commit 528a778e3864064bfccd8295abd1ec23da778843 Author: John Crispin Date: Thu Feb 18 14:16:15 2021 +0100 open-converged-wireless: Import 21.02 based uCentral tree Signed-off-by: John Crispin diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..29713bc84 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +openwrt/ diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..ac0d937f7 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +.PHONY: all purge + +all: + ./dock-run.sh ./build.sh $(TARGET) + +purge: + cd openwrt && rm -rf * && rm -rf .* + @echo Done diff --git a/backports/0001-build-build-kernel-image-before-building-modules-pac.patch b/backports/0001-build-build-kernel-image-before-building-modules-pac.patch new file mode 100644 index 000000000..a0beb0fdc --- /dev/null +++ b/backports/0001-build-build-kernel-image-before-building-modules-pac.patch @@ -0,0 +1,48 @@ +From 9a1f2adebe2245175462a6b2758d78b292072505 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Thu, 22 Oct 2020 10:29:34 +0200 +Subject: [PATCH 01/22] build: build kernel image before building + modules/packages + +This is needed for linux 5.10, where modules.builtin is generated from +vmlinux.o + +Signed-off-by: Felix Fietkau +--- + include/kernel-defaults.mk | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/include/kernel-defaults.mk b/include/kernel-defaults.mk +index e5a0ba367b..b069c1e671 100644 +--- a/include/kernel-defaults.mk ++++ b/include/kernel-defaults.mk +@@ -113,7 +113,7 @@ endef + + define Kernel/CompileModules/Default + rm -f $(LINUX_DIR)/vmlinux $(LINUX_DIR)/System.map +- +$(KERNEL_MAKE) modules ++ +$(KERNEL_MAKE) $(if $(KERNELNAME),$(KERNELNAME),all) modules + endef + + OBJCOPY_STRIP = -R .reginfo -R .notes -R .note -R .comment -R .mdebug -R .note.gnu.build-id +@@ -137,7 +137,7 @@ endef + + define Kernel/CompileImage/Default + rm -f $(TARGET_DIR)/init +- +$(KERNEL_MAKE) $(if $(KERNELNAME),$(KERNELNAME),all) modules ++ +$(KERNEL_MAKE) $(if $(KERNELNAME),$(KERNELNAME),all) + $(call Kernel/CopyImage) + endef + +@@ -147,7 +147,7 @@ define Kernel/CompileImage/Initramfs + $(CP) $(GENERIC_PLATFORM_DIR)/other-files/init $(TARGET_DIR)/init + $(if $(SOURCE_DATE_EPOCH),touch -hcd "@$(SOURCE_DATE_EPOCH)" $(TARGET_DIR)/init) + rm -rf $(KERNEL_BUILD_DIR)/linux-$(LINUX_VERSION)/usr/initramfs_data.cpio* +- +$(KERNEL_MAKE) $(if $(KERNELNAME),$(KERNELNAME),all) modules ++ +$(KERNEL_MAKE) $(if $(KERNELNAME),$(KERNELNAME),all) + $(call Kernel/CopyImage,-initramfs) + endef + else +-- +2.25.1 + diff --git a/backports/0002-kernel-add-linux-5.10-support.patch b/backports/0002-kernel-add-linux-5.10-support.patch new file mode 100644 index 000000000..cd2be305c --- /dev/null +++ b/backports/0002-kernel-add-linux-5.10-support.patch @@ -0,0 +1,33391 @@ +From d20b27e642d5e728142eb5180f20f185dcc42872 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Sat, 24 Oct 2020 21:14:16 +0200 +Subject: [PATCH 02/22] kernel: add linux 5.10 support + +Signed-off-by: Felix Fietkau +--- + include/kernel-version.mk | 2 + + package/kernel/linux/modules/block.mk | 16 +- + package/kernel/linux/modules/fs.mk | 6 +- + package/kernel/linux/modules/netdevices.mk | 2 +- + package/kernel/linux/modules/netfilter.mk | 4 +- + package/kernel/linux/modules/usb.mk | 2 +- + ...dcode-path-to-awk-in-scripts-ld-vers.patch | 30 + + .../011-kbuild-export-SUBARCH.patch | 21 + + ...ow_offload-handle-netdevice-events-f.patch | 106 + + target/linux/generic/config-5.10 | 6941 +++++++++++++++++ + target/linux/generic/config-filter | 6 +- + .../generic/files/drivers/net/phy/ar8216.c | 8 + + .../generic/hack-5.10/204-module_strip.patch | 196 + + .../210-darwin_scripts_include.patch | 3053 ++++++++ + .../211-darwin-uuid-typedef-clash.patch | 22 + + .../hack-5.10/212-tools_portability.patch | 110 + + .../hack-5.10/214-spidev_h_portability.patch | 24 + + .../generic/hack-5.10/220-gc_sections.patch | 120 + + .../hack-5.10/221-module_exports.patch | 102 + + .../hack-5.10/230-openwrt_lzma_options.patch | 34 + + .../hack-5.10/250-netfilter_depends.patch | 27 + + .../linux/generic/hack-5.10/251-kconfig.patch | 199 + + .../hack-5.10/259-regmap_dynamic.patch | 135 + + .../260-crypto_test_dependencies.patch | 52 + + .../hack-5.10/261-lib-arc4-unhide.patch | 15 + + .../generic/hack-5.10/280-rfkill-stubs.patch | 84 + + ...cache-use-more-efficient-cache-blast.patch | 64 + + .../301-mips_image_cmdline_hack.patch | 38 + + .../321-powerpc_crtsavres_prereq.patch | 38 + + .../generic/hack-5.10/531-debloat_lzma.patch | 1037 +++ + .../640-bridge-only-accept-EAP-locally.patch | 82 + + ...lter-connmark-introduce-set-dscpmark.patch | 212 + + .../650-netfilter-add-xt_OFFLOAD-target.patch | 822 ++ + .../hack-5.10/651-wireless_mesh_header.patch | 24 + + .../hack-5.10/660-fq_codel_defaults.patch | 27 + + .../661-use_fq_codel_by_default.patch | 100 + + .../700-swconfig_switch_drivers.patch | 129 + + .../hack-5.10/773-bgmac-add-srab-switch.patch | 98 + + .../hack-5.10/901-debloat_sock_diag.patch | 162 + + .../generic/hack-5.10/902-debloat_proc.patch | 408 + + .../hack-5.10/904-debloat_dma_buf.patch | 82 + + .../hack-5.10/910-kobject_uevent.patch | 32 + + .../911-kobject_add_broadcast_uevent.patch | 76 + + ...include-asm-rwonce.h-for-kernel-code.patch | 29 + + ...s-negative-stack-offsets-on-stack-tr.patch | 57 + + .../pending-5.10/110-ehci_hcd_ignore_oc.patch | 79 + + ...e_mem_map-with-ARCH_PFN_OFFSET-calcu.patch | 82 + + ...0-add-linux-spidev-compatible-si3210.patch | 18 + + ...ame2-and-add-RENAME_WHITEOUT-support.patch | 78 + + ...41-jffs2-add-RENAME_EXCHANGE-support.patch | 73 + + .../142-jffs2-add-splice-ops.patch | 20 + + ...ge_allow_receiption_on_disabled_port.patch | 45 + + ...-rs5c372-support_alarms_up_to_1_week.patch | 94 + + ...he_alarm_to_be_used_as_wakeup_source.patch | 70 + + .../pending-5.10/201-extra_optimization.patch | 31 + + .../203-kallsyms_uncompressed.patch | 119 + + .../205-backtrace_module_info.patch | 41 + + ...e-filenames-from-deps_initramfs-list.patch | 30 + + ...able_wilink_platform_without_drivers.patch | 20 + + .../270-platform-mikrotik-build-bits.patch | 31 + + .../300-mips_expose_boot_raw.patch | 40 + + .../302-mips_no_branch_likely.patch | 22 + + .../pending-5.10/305-mips_module_reloc.patch | 371 + + .../307-mips_highmem_offset.patch | 19 + + .../pending-5.10/308-mips32r2_tune.patch | 22 + + ...CPU-option-reporting-to-proc-cpuinfo.patch | 140 + + .../310-arm_module_unresolved_weak_sym.patch | 22 + + ...boot-put-appended-dtb-into-a-section.patch | 36 + + ...t-command-line-parameters-from-users.patch | 281 + + .../332-arc-add-OWRTDTB-section.patch | 84 + + ...able-unaligned-access-in-kernel-mode.patch | 24 + + ...ernel-XZ-compression-option-on-PPC_8.patch | 25 + + .../400-mtd-mtdsplit-support.patch | 313 + + ...t-add-of_match_table-with-DT-binding.patch | 22 + + .../pending-5.10/420-mtd-redboot_space.patch | 41 + + ...30-mtd-add-myloader-partition-parser.patch | 229 + + ...check-for-bad-blocks-when-calculatin.patch | 68 + + ...bcm47xxpart-detect-T_Meter-partition.patch | 37 + + ...mtd-add-routerbootpart-parser-config.patch | 38 + + ...mtd-cfi_cmdset_0002-no-erase_suspend.patch | 25 + + ...et_0002-add-buffer-write-cmd-timeout.patch | 17 + + ...25p80-mx-disable-software-protection.patch | 18 + + ...ort-limiting-4K-sectors-support-base.patch | 71 + + .../476-mtd-spi-nor-add-eon-en25q128.patch | 18 + + .../479-mtd-spi-nor-add-xtx-xt25f128b.patch | 79 + + .../480-mtd-set-rootfs-to-be-root-dev.patch | 38 + + ...or-rework-broken-flash-reset-support.patch | 180 + + ...r-add-support-for-Gigadevice-GD25D05.patch | 22 + + ...mtd-device-named-ubi-or-data-on-boot.patch | 97 + + ...to-create-ubiblock-device-for-rootfs.patch | 66 + + ...ting-ubi0-rootfs-in-init-do_mounts.c.patch | 51 + + ...ROOT_DEV-to-ubiblock-rootfs-if-unset.patch | 34 + + .../494-mtd-ubi-add-EOF-marker-support.patch | 60 + + ...-mtd-core-add-get_mtd_device_by_node.patch | 75 + + ...-add-bindings-for-mtd-concat-devices.patch | 52 + + ...cat-add-dt-driver-for-concat-devices.patch | 216 + + ...-mtdconcat-select-readwrite-function.patch | 24 + + .../500-fs_cdrom_dependencies.patch | 40 + + .../530-jffs2_make_lzma_available.patch | 5180 ++++++++++++ + .../pending-5.10/532-jffs2_eofdetect.patch | 65 + + .../600-netfilter_conntrack_flush.patch | 88 + + ...etfilter_match_bypass_default_checks.patch | 110 + + ...netfilter_match_bypass_default_table.patch | 106 + + ...netfilter_match_reduce_memory_access.patch | 22 + + ...-netfilter_optional_tcp_window_check.patch | 73 + + ...del-do-not-defer-queue-length-update.patch | 86 + + .../pending-5.10/630-packet_socket_type.patch | 138 + + ...table-add-hash-offset-field-to-tuple.patch | 52 + + ...filter-flowtable-add-xmit-path-types.patch | 188 + + ...arding-path-from-virtual-netdevice-a.patch | 170 + + ...lve-forwarding-path-for-vlan-devices.patch | 80 + + ...e-forwarding-path-for-bridge-devices.patch | 62 + + ...ble-use-dev_fill_forward_path-to-obt.patch | 191 + + ...ble-use-dev_fill_forward_path-to-obt.patch | 336 + + ...netfilter-flowtable-add-vlan-support.patch | 364 + + ...ter-flowtable-bridge-and-VLAN-suppor.patch | 107 + + ...ve-VLAN-tag-actions-in-forwarding-pa.patch | 207 + + ...-forwarding-path-for-dsa-slave-ports.patch | 62 + + ...ble-add-offload-support-for-xmit-pat.patch | 307 + + ...ter-nft_flow_offload-add-dsa-support.patch | 30 + + ...sa-slave-add-support-for-TC_SETUP_FT.patch | 53 + + ...ow_offload-add-bridge-vlan-filtering.patch | 31 + + ...ow_offload-use-direct-xmit-if-hardwa.patch | 51 + + ...ow_offload-fix-bridge-vlan-tag-handl.patch | 22 + + ...owtable-rework-ingress-vlan-matching.patch | 143 + + ...ble-handle-bridge-vlan-filter-offloa.patch | 106 + + .../pending-5.10/655-increase_skb_pad.patch | 20 + + ...Add-support-for-MAP-E-FMRs-mesh-mode.patch | 511 ++ + ...ng-with-source-address-failed-policy.patch | 263 + + ...nes-for-_POLICY_FAILED-until-all-cod.patch | 50 + + ...T-skip-GRO-for-foreign-MAC-addresses.patch | 149 + + .../681-NET-add-of_get_mac_address_mtd.patch | 135 + + ...dd-support-for-threaded-NAPI-polling.patch | 284 + + ...attribute-for-enabling-threaded-NAPI.patch | 74 + + ...detach-callback-to-struct-phy_driver.patch | 38 + + ...net-phy-at803x-fix-at8033-sgmii-mode.patch | 51 + + ...760-net-dsa-mv88e6xxx-fix-vlan-setup.patch | 27 + + ...-net-dsa-mt7530-Support-EEE-features.patch | 121 + + ...net-mtk_eth_soc-use-napi_consume_skb.patch | 72 + + ..._eth_soc-significantly-reduce-mdio-b.patch | 26 + + ...rnet-mtk_eth_soc-fix-rx-vlan-offload.patch | 31 + + ..._eth_soc-fix-unnecessary-tx-queue-st.patch | 50 + + ..._eth_soc-use-larger-burst-size-for-q.patch | 32 + + ...-mtk_eth_soc-increase-DMA-ring-sizes.patch | 21 + + ..._eth_soc-implement-dynamic-interrupt.patch | 281 + + ..._eth_soc-cache-hardware-pointer-of-l.patch | 67 + + ..._eth_soc-only-read-the-full-rx-descr.patch | 44 + + ..._eth_soc-unmap-rx-data-before-callin.patch | 44 + + ..._eth_soc-avoid-rearming-interrupt-if.patch | 35 + + ...k_eth_soc-fix-parsing-packets-in-GDM.patch | 67 + + ..._eth_soc-set-PPE-flow-hash-as-skb-ha.patch | 41 + + ..._eth_soc-add-support-for-initializin.patch | 1307 ++++ + ..._eth_soc-add-flow-offloading-support.patch | 561 ++ + ...ice-struct-copy-its-DMA-params-to-th.patch | 70 + + .../810-pci_disable_common_quirks.patch | 62 + + .../811-pci_disable_usb_common_quirks.patch | 115 + + ...problem-with-platfom-data-in-w1-gpio.patch | 26 + + .../pending-5.10/834-ledtrig-libata.patch | 149 + + .../pending-5.10/920-mangle_bootargs.patch | 71 + + 159 files changed, 31996 insertions(+), 11 deletions(-) + create mode 100644 target/linux/generic/backport-5.10/010-Kbuild-don-t-hardcode-path-to-awk-in-scripts-ld-vers.patch + create mode 100644 target/linux/generic/backport-5.10/011-kbuild-export-SUBARCH.patch + create mode 100644 target/linux/generic/backport-5.10/343-netfilter-nft_flow_offload-handle-netdevice-events-f.patch + create mode 100644 target/linux/generic/config-5.10 + create mode 100644 target/linux/generic/hack-5.10/204-module_strip.patch + create mode 100644 target/linux/generic/hack-5.10/210-darwin_scripts_include.patch + create mode 100644 target/linux/generic/hack-5.10/211-darwin-uuid-typedef-clash.patch + create mode 100644 target/linux/generic/hack-5.10/212-tools_portability.patch + create mode 100644 target/linux/generic/hack-5.10/214-spidev_h_portability.patch + create mode 100644 target/linux/generic/hack-5.10/220-gc_sections.patch + create mode 100644 target/linux/generic/hack-5.10/221-module_exports.patch + create mode 100644 target/linux/generic/hack-5.10/230-openwrt_lzma_options.patch + create mode 100644 target/linux/generic/hack-5.10/250-netfilter_depends.patch + create mode 100644 target/linux/generic/hack-5.10/251-kconfig.patch + create mode 100644 target/linux/generic/hack-5.10/259-regmap_dynamic.patch + create mode 100644 target/linux/generic/hack-5.10/260-crypto_test_dependencies.patch + create mode 100644 target/linux/generic/hack-5.10/261-lib-arc4-unhide.patch + create mode 100644 target/linux/generic/hack-5.10/280-rfkill-stubs.patch + create mode 100644 target/linux/generic/hack-5.10/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch + create mode 100644 target/linux/generic/hack-5.10/301-mips_image_cmdline_hack.patch + create mode 100644 target/linux/generic/hack-5.10/321-powerpc_crtsavres_prereq.patch + create mode 100644 target/linux/generic/hack-5.10/531-debloat_lzma.patch + create mode 100644 target/linux/generic/hack-5.10/640-bridge-only-accept-EAP-locally.patch + create mode 100644 target/linux/generic/hack-5.10/645-netfilter-connmark-introduce-set-dscpmark.patch + create mode 100644 target/linux/generic/hack-5.10/650-netfilter-add-xt_OFFLOAD-target.patch + create mode 100644 target/linux/generic/hack-5.10/651-wireless_mesh_header.patch + create mode 100644 target/linux/generic/hack-5.10/660-fq_codel_defaults.patch + create mode 100644 target/linux/generic/hack-5.10/661-use_fq_codel_by_default.patch + create mode 100644 target/linux/generic/hack-5.10/700-swconfig_switch_drivers.patch + create mode 100644 target/linux/generic/hack-5.10/773-bgmac-add-srab-switch.patch + create mode 100644 target/linux/generic/hack-5.10/901-debloat_sock_diag.patch + create mode 100644 target/linux/generic/hack-5.10/902-debloat_proc.patch + create mode 100644 target/linux/generic/hack-5.10/904-debloat_dma_buf.patch + create mode 100644 target/linux/generic/hack-5.10/910-kobject_uevent.patch + create mode 100644 target/linux/generic/hack-5.10/911-kobject_add_broadcast_uevent.patch + create mode 100644 target/linux/generic/pending-5.10/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch + create mode 100644 target/linux/generic/pending-5.10/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch + create mode 100644 target/linux/generic/pending-5.10/110-ehci_hcd_ignore_oc.patch + create mode 100644 target/linux/generic/pending-5.10/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch + create mode 100644 target/linux/generic/pending-5.10/130-add-linux-spidev-compatible-si3210.patch + create mode 100644 target/linux/generic/pending-5.10/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch + create mode 100644 target/linux/generic/pending-5.10/141-jffs2-add-RENAME_EXCHANGE-support.patch + create mode 100644 target/linux/generic/pending-5.10/142-jffs2-add-splice-ops.patch + create mode 100644 target/linux/generic/pending-5.10/150-bridge_allow_receiption_on_disabled_port.patch + create mode 100644 target/linux/generic/pending-5.10/190-rtc-rs5c372-support_alarms_up_to_1_week.patch + create mode 100644 target/linux/generic/pending-5.10/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch + create mode 100644 target/linux/generic/pending-5.10/201-extra_optimization.patch + create mode 100644 target/linux/generic/pending-5.10/203-kallsyms_uncompressed.patch + create mode 100644 target/linux/generic/pending-5.10/205-backtrace_module_info.patch + create mode 100644 target/linux/generic/pending-5.10/240-remove-unsane-filenames-from-deps_initramfs-list.patch + create mode 100644 target/linux/generic/pending-5.10/261-enable_wilink_platform_without_drivers.patch + create mode 100644 target/linux/generic/pending-5.10/270-platform-mikrotik-build-bits.patch + create mode 100644 target/linux/generic/pending-5.10/300-mips_expose_boot_raw.patch + create mode 100644 target/linux/generic/pending-5.10/302-mips_no_branch_likely.patch + create mode 100644 target/linux/generic/pending-5.10/305-mips_module_reloc.patch + create mode 100644 target/linux/generic/pending-5.10/307-mips_highmem_offset.patch + create mode 100644 target/linux/generic/pending-5.10/308-mips32r2_tune.patch + create mode 100644 target/linux/generic/pending-5.10/309-MIPS-Add-CPU-option-reporting-to-proc-cpuinfo.patch + create mode 100644 target/linux/generic/pending-5.10/310-arm_module_unresolved_weak_sym.patch + create mode 100644 target/linux/generic/pending-5.10/311-MIPS-zboot-put-appended-dtb-into-a-section.patch + create mode 100644 target/linux/generic/pending-5.10/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch + create mode 100644 target/linux/generic/pending-5.10/332-arc-add-OWRTDTB-section.patch + create mode 100644 target/linux/generic/pending-5.10/333-arc-enable-unaligned-access-in-kernel-mode.patch + create mode 100644 target/linux/generic/pending-5.10/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch + create mode 100644 target/linux/generic/pending-5.10/400-mtd-mtdsplit-support.patch + create mode 100644 target/linux/generic/pending-5.10/419-mtd-redboot-add-of_match_table-with-DT-binding.patch + create mode 100644 target/linux/generic/pending-5.10/420-mtd-redboot_space.patch + create mode 100644 target/linux/generic/pending-5.10/430-mtd-add-myloader-partition-parser.patch + create mode 100644 target/linux/generic/pending-5.10/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch + create mode 100644 target/linux/generic/pending-5.10/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch + create mode 100644 target/linux/generic/pending-5.10/435-mtd-add-routerbootpart-parser-config.patch + create mode 100644 target/linux/generic/pending-5.10/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch + create mode 100644 target/linux/generic/pending-5.10/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch + create mode 100644 target/linux/generic/pending-5.10/465-m25p80-mx-disable-software-protection.patch + create mode 100644 target/linux/generic/pending-5.10/470-mtd-spi-nor-support-limiting-4K-sectors-support-base.patch + create mode 100644 target/linux/generic/pending-5.10/476-mtd-spi-nor-add-eon-en25q128.patch + create mode 100644 target/linux/generic/pending-5.10/479-mtd-spi-nor-add-xtx-xt25f128b.patch + create mode 100644 target/linux/generic/pending-5.10/480-mtd-set-rootfs-to-be-root-dev.patch + create mode 100644 target/linux/generic/pending-5.10/481-mtd-spi-nor-rework-broken-flash-reset-support.patch + create mode 100644 target/linux/generic/pending-5.10/482-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch + create mode 100644 target/linux/generic/pending-5.10/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch + create mode 100644 target/linux/generic/pending-5.10/491-ubi-auto-create-ubiblock-device-for-rootfs.patch + create mode 100644 target/linux/generic/pending-5.10/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch + create mode 100644 target/linux/generic/pending-5.10/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch + create mode 100644 target/linux/generic/pending-5.10/494-mtd-ubi-add-EOF-marker-support.patch + create mode 100644 target/linux/generic/pending-5.10/495-mtd-core-add-get_mtd_device_by_node.patch + create mode 100644 target/linux/generic/pending-5.10/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch + create mode 100644 target/linux/generic/pending-5.10/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch + create mode 100644 target/linux/generic/pending-5.10/498-mtd-mtdconcat-select-readwrite-function.patch + create mode 100644 target/linux/generic/pending-5.10/500-fs_cdrom_dependencies.patch + create mode 100644 target/linux/generic/pending-5.10/530-jffs2_make_lzma_available.patch + create mode 100644 target/linux/generic/pending-5.10/532-jffs2_eofdetect.patch + create mode 100644 target/linux/generic/pending-5.10/600-netfilter_conntrack_flush.patch + create mode 100644 target/linux/generic/pending-5.10/610-netfilter_match_bypass_default_checks.patch + create mode 100644 target/linux/generic/pending-5.10/611-netfilter_match_bypass_default_table.patch + create mode 100644 target/linux/generic/pending-5.10/612-netfilter_match_reduce_memory_access.patch + create mode 100644 target/linux/generic/pending-5.10/613-netfilter_optional_tcp_window_check.patch + create mode 100644 target/linux/generic/pending-5.10/620-net_sched-codel-do-not-defer-queue-length-update.patch + create mode 100644 target/linux/generic/pending-5.10/630-packet_socket_type.patch + create mode 100644 target/linux/generic/pending-5.10/640-00-netfilter-flowtable-add-hash-offset-field-to-tuple.patch + create mode 100644 target/linux/generic/pending-5.10/640-01-netfilter-flowtable-add-xmit-path-types.patch + create mode 100644 target/linux/generic/pending-5.10/640-02-net-resolve-forwarding-path-from-virtual-netdevice-a.patch + create mode 100644 target/linux/generic/pending-5.10/640-03-net-8021q-resolve-forwarding-path-for-vlan-devices.patch + create mode 100644 target/linux/generic/pending-5.10/640-04-bridge-resolve-forwarding-path-for-bridge-devices.patch + create mode 100644 target/linux/generic/pending-5.10/640-05-netfilter-flowtable-use-dev_fill_forward_path-to-obt.patch + create mode 100644 target/linux/generic/pending-5.10/640-06-netfilter-flowtable-use-dev_fill_forward_path-to-obt.patch + create mode 100644 target/linux/generic/pending-5.10/640-07-netfilter-flowtable-add-vlan-support.patch + create mode 100644 target/linux/generic/pending-5.10/640-08-selftests-netfilter-flowtable-bridge-and-VLAN-suppor.patch + create mode 100644 target/linux/generic/pending-5.10/640-09-net-bridge-resolve-VLAN-tag-actions-in-forwarding-pa.patch + create mode 100644 target/linux/generic/pending-5.10/640-10-net-dsa-resolve-forwarding-path-for-dsa-slave-ports.patch + create mode 100644 target/linux/generic/pending-5.10/640-11-netfilter-flowtable-add-offload-support-for-xmit-pat.patch + create mode 100644 target/linux/generic/pending-5.10/640-12-netfilter-nft_flow_offload-add-dsa-support.patch + create mode 100644 target/linux/generic/pending-5.10/640-13-dsa-slave-add-support-for-TC_SETUP_FT.patch + create mode 100644 target/linux/generic/pending-5.10/640-14-netfilter-nft_flow_offload-add-bridge-vlan-filtering.patch + create mode 100644 target/linux/generic/pending-5.10/640-15-netfilter-nft_flow_offload-use-direct-xmit-if-hardwa.patch + create mode 100644 target/linux/generic/pending-5.10/640-16-netfilter-nft_flow_offload-fix-bridge-vlan-tag-handl.patch + create mode 100644 target/linux/generic/pending-5.10/640-17-netfilter-flowtable-rework-ingress-vlan-matching.patch + create mode 100644 target/linux/generic/pending-5.10/640-18-netfilter-flowtable-handle-bridge-vlan-filter-offloa.patch + create mode 100644 target/linux/generic/pending-5.10/655-increase_skb_pad.patch + create mode 100644 target/linux/generic/pending-5.10/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch + create mode 100644 target/linux/generic/pending-5.10/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch + create mode 100644 target/linux/generic/pending-5.10/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch + create mode 100644 target/linux/generic/pending-5.10/680-NET-skip-GRO-for-foreign-MAC-addresses.patch + create mode 100644 target/linux/generic/pending-5.10/681-NET-add-of_get_mac_address_mtd.patch + create mode 100644 target/linux/generic/pending-5.10/690-net-add-support-for-threaded-NAPI-polling.patch + create mode 100644 target/linux/generic/pending-5.10/691-net-add-sysfs-attribute-for-enabling-threaded-NAPI.patch + create mode 100644 target/linux/generic/pending-5.10/703-phy-add-detach-callback-to-struct-phy_driver.patch + create mode 100644 target/linux/generic/pending-5.10/735-net-phy-at803x-fix-at8033-sgmii-mode.patch + create mode 100644 target/linux/generic/pending-5.10/760-net-dsa-mv88e6xxx-fix-vlan-setup.patch + create mode 100644 target/linux/generic/pending-5.10/761-net-dsa-mt7530-Support-EEE-features.patch + create mode 100644 target/linux/generic/pending-5.10/770-00-net-ethernet-mtk_eth_soc-use-napi_consume_skb.patch + create mode 100644 target/linux/generic/pending-5.10/770-01-net-ethernet-mtk_eth_soc-significantly-reduce-mdio-b.patch + create mode 100644 target/linux/generic/pending-5.10/770-02-net-ethernet-mtk_eth_soc-fix-rx-vlan-offload.patch + create mode 100644 target/linux/generic/pending-5.10/770-03-net-ethernet-mtk_eth_soc-fix-unnecessary-tx-queue-st.patch + create mode 100644 target/linux/generic/pending-5.10/770-04-net-ethernet-mtk_eth_soc-use-larger-burst-size-for-q.patch + create mode 100644 target/linux/generic/pending-5.10/770-05-net-ethernet-mtk_eth_soc-increase-DMA-ring-sizes.patch + create mode 100644 target/linux/generic/pending-5.10/770-06-net-ethernet-mtk_eth_soc-implement-dynamic-interrupt.patch + create mode 100644 target/linux/generic/pending-5.10/770-08-net-ethernet-mtk_eth_soc-cache-hardware-pointer-of-l.patch + create mode 100644 target/linux/generic/pending-5.10/770-09-net-ethernet-mtk_eth_soc-only-read-the-full-rx-descr.patch + create mode 100644 target/linux/generic/pending-5.10/770-10-net-ethernet-mtk_eth_soc-unmap-rx-data-before-callin.patch + create mode 100644 target/linux/generic/pending-5.10/770-11-net-ethernet-mtk_eth_soc-avoid-rearming-interrupt-if.patch + create mode 100644 target/linux/generic/pending-5.10/770-13-net-ethernet-mtk_eth_soc-fix-parsing-packets-in-GDM.patch + create mode 100644 target/linux/generic/pending-5.10/770-14-net-ethernet-mtk_eth_soc-set-PPE-flow-hash-as-skb-ha.patch + create mode 100644 target/linux/generic/pending-5.10/770-15-net-ethernet-mtk_eth_soc-add-support-for-initializin.patch + create mode 100644 target/linux/generic/pending-5.10/770-16-net-ethernet-mtk_eth_soc-add-flow-offloading-support.patch + create mode 100644 target/linux/generic/pending-5.10/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch + create mode 100644 target/linux/generic/pending-5.10/810-pci_disable_common_quirks.patch + create mode 100644 target/linux/generic/pending-5.10/811-pci_disable_usb_common_quirks.patch + create mode 100644 target/linux/generic/pending-5.10/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch + create mode 100644 target/linux/generic/pending-5.10/834-ledtrig-libata.patch + create mode 100644 target/linux/generic/pending-5.10/920-mangle_bootargs.patch + +diff --git a/include/kernel-version.mk b/include/kernel-version.mk +index d65eb790d8..035692f3e3 100644 +--- a/include/kernel-version.mk ++++ b/include/kernel-version.mk +@@ -7,8 +7,10 @@ ifdef CONFIG_TESTING_KERNEL + endif + + LINUX_VERSION-5.4 = .105 ++LINUX_VERSION-5.10 = .14 + + LINUX_KERNEL_HASH-5.4.105 = 244e4cd16184285df55ec5a9501daba011aa8b85c5527ee05eab4592e70fb8b6 ++LINUX_KERNEL_HASH-5.10.14 = fa27b79f198b5be969e497ed5461860df48e0591c85e60699fc8be26837a1d2a + + remove_uri_prefix=$(subst git://,,$(subst http://,,$(subst https://,,$(1)))) + sanitize_uri=$(call qstrip,$(subst @,_,$(subst :,_,$(subst .,_,$(subst -,_,$(subst /,_,$(1))))))) +diff --git a/package/kernel/linux/modules/block.mk b/package/kernel/linux/modules/block.mk +index 373c9fbaab..b7767b3d16 100644 +--- a/package/kernel/linux/modules/block.mk ++++ b/package/kernel/linux/modules/block.mk +@@ -537,16 +537,24 @@ endef + $(eval $(call KernelPackage,scsi-generic)) + + ++define KernelPackage/cdrom ++ TITLE:=Kernel library module for CD / DVD drives ++ KCONFIG:=CONFIG_CDROM ++ HIDDEN:=1 ++ FILES:=$(LINUX_DIR)/drivers/cdrom/cdrom.ko ++endef ++ ++$(eval $(call KernelPackage,cdrom)) ++ ++ + define KernelPackage/scsi-cdrom + SUBMENU:=$(BLOCK_MENU) + TITLE:=Kernel support for CD / DVD drives +- DEPENDS:=+kmod-scsi-core ++ DEPENDS:=+kmod-scsi-core +kmod-cdrom + KCONFIG:= \ + CONFIG_BLK_DEV_SR \ + CONFIG_BLK_DEV_SR_VENDOR=n +- FILES:= \ +- $(LINUX_DIR)/drivers/cdrom/cdrom.ko \ +- $(LINUX_DIR)/drivers/scsi/sr_mod.ko ++ FILES:=$(LINUX_DIR)/drivers/scsi/sr_mod.ko + AUTOLOAD:=$(call AutoLoad,45,sr_mod) + endef + +diff --git a/package/kernel/linux/modules/fs.mk b/package/kernel/linux/modules/fs.mk +index d43542b17e..a0db14ecfe 100644 +--- a/package/kernel/linux/modules/fs.mk ++++ b/package/kernel/linux/modules/fs.mk +@@ -243,6 +243,7 @@ $(eval $(call KernelPackage,fs-fscache)) + define KernelPackage/fs-hfs + SUBMENU:=$(FS_MENU) + TITLE:=HFS filesystem support ++ DEPENDS:=+kmod-cdrom + KCONFIG:=CONFIG_HFS_FS + FILES:=$(LINUX_DIR)/fs/hfs/hfs.ko + AUTOLOAD:=$(call AutoLoad,30,hfs) +@@ -259,6 +260,7 @@ $(eval $(call KernelPackage,fs-hfs)) + define KernelPackage/fs-hfsplus + SUBMENU:=$(FS_MENU) + TITLE:=HFS+ filesystem support ++ DEPENDS:=+kmod-cdrom + KCONFIG:=CONFIG_HFSPLUS_FS + FILES:=$(LINUX_DIR)/fs/hfsplus/hfsplus.ko + AUTOLOAD:=$(call AutoLoad,30,hfsplus) +@@ -275,7 +277,7 @@ $(eval $(call KernelPackage,fs-hfsplus)) + define KernelPackage/fs-isofs + SUBMENU:=$(FS_MENU) + TITLE:=ISO9660 filesystem support +- DEPENDS:=+kmod-lib-zlib-inflate ++ DEPENDS:=+kmod-lib-zlib-inflate +kmod-cdrom + KCONFIG:=CONFIG_ISO9660_FS CONFIG_JOLIET=y CONFIG_ZISOFS=n + FILES:=$(LINUX_DIR)/fs/isofs/isofs.ko + AUTOLOAD:=$(call AutoLoad,30,isofs) +@@ -513,7 +515,7 @@ define KernelPackage/fs-udf + KCONFIG:=CONFIG_UDF_FS + FILES:=$(LINUX_DIR)/fs/udf/udf.ko + AUTOLOAD:=$(call AutoLoad,30,udf) +- DEPENDS:=+kmod-lib-crc-itu-t ++ DEPENDS:=+kmod-lib-crc-itu-t +kmod-cdrom + $(call AddDepends/nls) + endef + +diff --git a/package/kernel/linux/modules/netdevices.mk b/package/kernel/linux/modules/netdevices.mk +index 901bddddea..5f7a80bf22 100644 +--- a/package/kernel/linux/modules/netdevices.mk ++++ b/package/kernel/linux/modules/netdevices.mk +@@ -1178,7 +1178,7 @@ $(eval $(call KernelPackage,sfp)) + define KernelPackage/igc + SUBMENU:=$(NETWORK_DEVICES_MENU) + TITLE:=Intel(R) Ethernet Controller I225 Series support +- DEPENDS:=@PCI_SUPPORT ++ DEPENDS:=@PCI_SUPPORT +kmod-ptp + KCONFIG:=CONFIG_IGC + FILES:=$(LINUX_DIR)/drivers/net/ethernet/intel/igc/igc.ko + AUTOLOAD:=$(call AutoProbe,igc) +diff --git a/package/kernel/linux/modules/netfilter.mk b/package/kernel/linux/modules/netfilter.mk +index b46fcebc08..e2bb1d0681 100644 +--- a/package/kernel/linux/modules/netfilter.mk ++++ b/package/kernel/linux/modules/netfilter.mk +@@ -155,7 +155,7 @@ define KernelPackage/nf-flow + DEPENDS:=+kmod-nf-conntrack + FILES:= \ + $(LINUX_DIR)/net/netfilter/nf_flow_table.ko \ +- $(LINUX_DIR)/net/netfilter/nf_flow_table_hw.ko ++ $(if $(CONFIG_LINUX_5_4),$(LINUX_DIR)/net/netfilter/nf_flow_table_hw.ko) + AUTOLOAD:=$(call AutoProbe,nf_flow_table nf_flow_table_hw) + endef + +@@ -1052,7 +1052,7 @@ $(eval $(call KernelPackage,ipt-rpfilter)) + define KernelPackage/nft-core + SUBMENU:=$(NF_MENU) + TITLE:=Netfilter nf_tables support +- DEPENDS:=+kmod-nfnetlink +kmod-nf-reject +IPV6:kmod-nf-reject6 +IPV6:kmod-nf-conntrack6 +kmod-nf-nat ++ DEPENDS:=+kmod-nfnetlink +kmod-nf-reject +IPV6:kmod-nf-reject6 +IPV6:kmod-nf-conntrack6 +kmod-nf-nat +kmod-lib-crc32c + FILES:=$(foreach mod,$(NFT_CORE-m),$(LINUX_DIR)/net/$(mod).ko) + AUTOLOAD:=$(call AutoProbe,$(notdir $(NFT_CORE-m))) + KCONFIG:= \ +diff --git a/package/kernel/linux/modules/usb.mk b/package/kernel/linux/modules/usb.mk +index d050165df3..3dd20a0696 100644 +--- a/package/kernel/linux/modules/usb.mk ++++ b/package/kernel/linux/modules/usb.mk +@@ -1387,7 +1387,7 @@ define KernelPackage/usb-net-cdc-ncm + KCONFIG:=CONFIG_USB_NET_CDC_NCM + FILES:= $(LINUX_DIR)/drivers/$(USBNET_DIR)/cdc_ncm.ko + AUTOLOAD:=$(call AutoProbe,cdc_ncm) +- $(call AddDepends/usb-net) ++ $(call AddDepends/usb-net,+kmod-usb-net-cdc-ether) + endef + + define KernelPackage/usb-net-cdc-ncm/description +diff --git a/target/linux/generic/backport-5.10/010-Kbuild-don-t-hardcode-path-to-awk-in-scripts-ld-vers.patch b/target/linux/generic/backport-5.10/010-Kbuild-don-t-hardcode-path-to-awk-in-scripts-ld-vers.patch +new file mode 100644 +index 0000000000..7ac4f9d240 +--- /dev/null ++++ b/target/linux/generic/backport-5.10/010-Kbuild-don-t-hardcode-path-to-awk-in-scripts-ld-vers.patch +@@ -0,0 +1,30 @@ ++From 13b1ecc3401653a355798eb1dee10cc1608202f4 Mon Sep 17 00:00:00 2001 ++From: Felix Fietkau ++Date: Mon, 18 Jan 2016 12:27:49 +0100 ++Subject: [PATCH 33/34] Kbuild: don't hardcode path to awk in ++ scripts/ld-version.sh ++ ++On some systems /usr/bin/awk does not exist, or is broken. Find it via ++$PATH instead. ++ ++Signed-off-by: Felix Fietkau ++--- ++ scripts/ld-version.sh | 4 +++- ++ 1 file changed, 3 insertions(+), 1 deletion(-) ++ ++--- a/scripts/ld-version.sh +++++ b/scripts/ld-version.sh ++@@ -1,6 +1,7 @@ ++-#!/usr/bin/awk -f +++#!/bin/sh ++ # SPDX-License-Identifier: GPL-2.0 ++ # extract linker version number from stdin and turn into single number +++exec awk ' ++ { ++ gsub(".*\\)", ""); ++ gsub(".*version ", ""); ++@@ -9,3 +10,4 @@ ++ print a[1]*100000000 + a[2]*1000000 + a[3]*10000; ++ exit ++ } +++' +diff --git a/target/linux/generic/backport-5.10/011-kbuild-export-SUBARCH.patch b/target/linux/generic/backport-5.10/011-kbuild-export-SUBARCH.patch +new file mode 100644 +index 0000000000..a1f0d9aa96 +--- /dev/null ++++ b/target/linux/generic/backport-5.10/011-kbuild-export-SUBARCH.patch +@@ -0,0 +1,21 @@ ++From 173019b66dcc9d68ad9333aa744dad1e369b5aa8 Mon Sep 17 00:00:00 2001 ++From: Felix Fietkau ++Date: Sun, 9 Jul 2017 00:26:53 +0200 ++Subject: [PATCH 34/34] kernel: add compile fix for linux 4.9 on x86 ++ ++Signed-off-by: Felix Fietkau ++--- ++ Makefile | 4 ++-- ++ 1 file changed, 2 insertions(+), 2 deletions(-) ++ ++--- a/Makefile +++++ b/Makefile ++@@ -506,7 +506,7 @@ KBUILD_LDFLAGS_MODULE := ++ KBUILD_LDFLAGS := ++ CLANG_FLAGS := ++ ++-export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC +++export ARCH SRCARCH SUBARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC ++ export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL ++ export PERL PYTHON PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX ++ export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD +diff --git a/target/linux/generic/backport-5.10/343-netfilter-nft_flow_offload-handle-netdevice-events-f.patch b/target/linux/generic/backport-5.10/343-netfilter-nft_flow_offload-handle-netdevice-events-f.patch +new file mode 100644 +index 0000000000..137264cb9f +--- /dev/null ++++ b/target/linux/generic/backport-5.10/343-netfilter-nft_flow_offload-handle-netdevice-events-f.patch +@@ -0,0 +1,106 @@ ++From: Pablo Neira Ayuso ++Date: Thu, 25 Jan 2018 12:58:55 +0100 ++Subject: [PATCH] netfilter: nft_flow_offload: handle netdevice events from ++ nf_flow_table ++ ++Move the code that deals with device events to the core. ++ ++Signed-off-by: Pablo Neira Ayuso ++--- ++ ++--- a/net/netfilter/nf_flow_table_core.c +++++ b/net/netfilter/nf_flow_table_core.c ++@@ -577,13 +577,41 @@ void nf_flow_table_free(struct nf_flowta ++ } ++ EXPORT_SYMBOL_GPL(nf_flow_table_free); ++ +++static int nf_flow_table_netdev_event(struct notifier_block *this, +++ unsigned long event, void *ptr) +++{ +++ struct net_device *dev = netdev_notifier_info_to_dev(ptr); +++ +++ if (event != NETDEV_DOWN) +++ return NOTIFY_DONE; +++ +++ nf_flow_table_cleanup(dev); +++ +++ return NOTIFY_DONE; +++} +++ +++static struct notifier_block flow_offload_netdev_notifier = { +++ .notifier_call = nf_flow_table_netdev_event, +++}; +++ ++ static int __init nf_flow_table_module_init(void) ++ { ++- return nf_flow_table_offload_init(); +++ int ret; +++ +++ ret = nf_flow_table_offload_init(); +++ if (ret) +++ return ret; +++ +++ ret = register_netdevice_notifier(&flow_offload_netdev_notifier); +++ if (ret) +++ nf_flow_table_offload_exit(); +++ +++ return ret; ++ } ++ ++ static void __exit nf_flow_table_module_exit(void) ++ { +++ unregister_netdevice_notifier(&flow_offload_netdev_notifier); ++ nf_flow_table_offload_exit(); ++ } ++ ++--- a/net/netfilter/nft_flow_offload.c +++++ b/net/netfilter/nft_flow_offload.c ++@@ -237,47 +237,14 @@ static struct nft_expr_type nft_flow_off ++ .owner = THIS_MODULE, ++ }; ++ ++-static int flow_offload_netdev_event(struct notifier_block *this, ++- unsigned long event, void *ptr) ++-{ ++- struct net_device *dev = netdev_notifier_info_to_dev(ptr); ++- ++- if (event != NETDEV_DOWN) ++- return NOTIFY_DONE; ++- ++- nf_flow_table_cleanup(dev); ++- ++- return NOTIFY_DONE; ++-} ++- ++-static struct notifier_block flow_offload_netdev_notifier = { ++- .notifier_call = flow_offload_netdev_event, ++-}; ++- ++ static int __init nft_flow_offload_module_init(void) ++ { ++- int err; ++- ++- err = register_netdevice_notifier(&flow_offload_netdev_notifier); ++- if (err) ++- goto err; ++- ++- err = nft_register_expr(&nft_flow_offload_type); ++- if (err < 0) ++- goto register_expr; ++- ++- return 0; ++- ++-register_expr: ++- unregister_netdevice_notifier(&flow_offload_netdev_notifier); ++-err: ++- return err; +++ return nft_register_expr(&nft_flow_offload_type); ++ } ++ ++ static void __exit nft_flow_offload_module_exit(void) ++ { ++ nft_unregister_expr(&nft_flow_offload_type); ++- unregister_netdevice_notifier(&flow_offload_netdev_notifier); ++ } ++ ++ module_init(nft_flow_offload_module_init); +diff --git a/target/linux/generic/config-5.10 b/target/linux/generic/config-5.10 +new file mode 100644 +index 0000000000..f7cc6c8561 +--- /dev/null ++++ b/target/linux/generic/config-5.10 +@@ -0,0 +1,6941 @@ ++# CONFIG_104_QUAD_8 is not set ++CONFIG_32BIT=y ++CONFIG_64BIT_TIME=y ++# CONFIG_6LOWPAN is not set ++# CONFIG_6LOWPAN_DEBUGFS is not set ++# CONFIG_6PACK is not set ++# CONFIG_8139CP is not set ++# CONFIG_8139TOO is not set ++# CONFIG_9P_FS is not set ++# CONFIG_AB3100_CORE is not set ++# CONFIG_AB8500_CORE is not set ++# CONFIG_ABP060MG is not set ++# CONFIG_ABX500_CORE is not set ++# CONFIG_ACCESSIBILITY is not set ++# CONFIG_ACENIC is not set ++# CONFIG_ACERHDF is not set ++# CONFIG_ACER_WIRELESS is not set ++# CONFIG_ACORN_PARTITION is not set ++# CONFIG_ACPI_ALS is not set ++# CONFIG_ACPI_APEI is not set ++# CONFIG_ACPI_BUTTON is not set ++# CONFIG_ACPI_CONFIGFS is not set ++# CONFIG_ACPI_CUSTOM_METHOD is not set ++# CONFIG_ACPI_EXTLOG is not set ++# CONFIG_ACPI_HED is not set ++# CONFIG_ACPI_NFIT is not set ++# CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set ++# CONFIG_ACPI_TABLE_UPGRADE is not set ++# CONFIG_ACPI_VIDEO is not set ++# CONFIG_AD2S1200 is not set ++# CONFIG_AD2S1210 is not set ++# CONFIG_AD2S90 is not set ++# CONFIG_AD5064 is not set ++# CONFIG_AD525X_DPOT is not set ++# CONFIG_AD5272 is not set ++# CONFIG_AD5360 is not set ++# CONFIG_AD5380 is not set ++# CONFIG_AD5421 is not set ++# CONFIG_AD5446 is not set ++# CONFIG_AD5449 is not set ++# CONFIG_AD5504 is not set ++# CONFIG_AD5592R is not set ++# CONFIG_AD5593R is not set ++# CONFIG_AD5624R_SPI is not set ++# CONFIG_AD5686 is not set ++# CONFIG_AD5686_SPI is not set ++# CONFIG_AD5696_I2C is not set ++# CONFIG_AD5755 is not set ++# CONFIG_AD5758 is not set ++# CONFIG_AD5761 is not set ++# CONFIG_AD5764 is not set ++# CONFIG_AD5770R is not set ++# CONFIG_AD5791 is not set ++# CONFIG_AD5933 is not set ++# CONFIG_AD7091R5 is not set ++# CONFIG_AD7124 is not set ++# CONFIG_AD7150 is not set ++# CONFIG_AD7152 is not set ++# CONFIG_AD7192 is not set ++# CONFIG_AD7266 is not set ++# CONFIG_AD7280 is not set ++# CONFIG_AD7291 is not set ++# CONFIG_AD7292 is not set ++# CONFIG_AD7298 is not set ++# CONFIG_AD7303 is not set ++# CONFIG_AD7476 is not set ++# CONFIG_AD7606 is not set ++# CONFIG_AD7606_IFACE_PARALLEL is not set ++# CONFIG_AD7606_IFACE_SPI is not set ++# CONFIG_AD7746 is not set ++# CONFIG_AD7766 is not set ++# CONFIG_AD7768_1 is not set ++# CONFIG_AD7780 is not set ++# CONFIG_AD7791 is not set ++# CONFIG_AD7793 is not set ++# CONFIG_AD7816 is not set ++# CONFIG_AD7887 is not set ++# CONFIG_AD7923 is not set ++# CONFIG_AD7949 is not set ++# CONFIG_AD799X is not set ++# CONFIG_AD8366 is not set ++# CONFIG_AD8801 is not set ++# CONFIG_AD9467 is not set ++# CONFIG_AD9523 is not set ++# CONFIG_AD9832 is not set ++# CONFIG_AD9834 is not set ++# CONFIG_ADAPTEC_STARFIRE is not set ++# CONFIG_ADE7854 is not set ++# CONFIG_ADF4350 is not set ++# CONFIG_ADF4371 is not set ++# CONFIG_ADFS_FS is not set ++# CONFIG_ADIN_PHY is not set ++# CONFIG_ADIS16080 is not set ++# CONFIG_ADIS16130 is not set ++# CONFIG_ADIS16136 is not set ++# CONFIG_ADIS16201 is not set ++# CONFIG_ADIS16203 is not set ++# CONFIG_ADIS16209 is not set ++# CONFIG_ADIS16240 is not set ++# CONFIG_ADIS16260 is not set ++# CONFIG_ADIS16400 is not set ++# CONFIG_ADIS16460 is not set ++# CONFIG_ADIS16475 is not set ++# CONFIG_ADIS16480 is not set ++# CONFIG_ADI_AXI_ADC is not set ++# CONFIG_ADJD_S311 is not set ++# CONFIG_ADM6996_PHY is not set ++# CONFIG_ADM8211 is not set ++# CONFIG_ADT7316 is not set ++# CONFIG_ADUX1020 is not set ++CONFIG_ADVISE_SYSCALLS=y ++# CONFIG_ADXL345_I2C is not set ++# CONFIG_ADXL345_SPI is not set ++# CONFIG_ADXL372_I2C is not set ++# CONFIG_ADXL372_SPI is not set ++# CONFIG_ADXRS290 is not set ++# CONFIG_ADXRS450 is not set ++CONFIG_AEABI=y ++# CONFIG_AFE4403 is not set ++# CONFIG_AFE4404 is not set ++# CONFIG_AFFS_FS is not set ++# CONFIG_AFS_DEBUG_CURSOR is not set ++# CONFIG_AFS_FS is not set ++# CONFIG_AF_KCM is not set ++# CONFIG_AF_RXRPC is not set ++# CONFIG_AF_RXRPC_INJECT_LOSS is not set ++# CONFIG_AF_RXRPC_IPV6 is not set ++# CONFIG_AGP is not set ++# CONFIG_AHCI_CEVA is not set ++# CONFIG_AHCI_IMX is not set ++# CONFIG_AHCI_MVEBU is not set ++# CONFIG_AHCI_QORIQ is not set ++CONFIG_AIO=y ++# CONFIG_AIRO is not set ++# CONFIG_AIRO_CS is not set ++# CONFIG_AIX_PARTITION is not set ++# CONFIG_AK09911 is not set ++# CONFIG_AK8974 is not set ++# CONFIG_AK8975 is not set ++# CONFIG_AL3010 is not set ++# CONFIG_AL3320A is not set ++# CONFIG_ALIM7101_WDT is not set ++CONFIG_ALLOW_DEV_COREDUMP=y ++# CONFIG_ALTERA_MBOX is not set ++# CONFIG_ALTERA_MSGDMA is not set ++# CONFIG_ALTERA_STAPL is not set ++# CONFIG_ALTERA_TSE is not set ++# CONFIG_ALX is not set ++# CONFIG_AL_FIC is not set ++# CONFIG_AM2315 is not set ++# CONFIG_AM335X_PHY_USB is not set ++# CONFIG_AMBA_PL08X is not set ++# CONFIG_AMD8111_ETH is not set ++# CONFIG_AMD_MEM_ENCRYPT is not set ++# CONFIG_AMD_PHY is not set ++# CONFIG_AMD_XGBE is not set ++# CONFIG_AMD_XGBE_HAVE_ECC is not set ++# CONFIG_AMIGA_PARTITION is not set ++# CONFIG_AMILO_RFKILL is not set ++# CONFIG_ANDROID is not set ++CONFIG_ANON_INODES=y ++# CONFIG_APDS9300 is not set ++# CONFIG_APDS9802ALS is not set ++# CONFIG_APDS9960 is not set ++# CONFIG_APM8018X is not set ++# CONFIG_APM_EMULATION is not set ++# CONFIG_APPLE_GMUX is not set ++# CONFIG_APPLE_MFI_FASTCHARGE is not set ++# CONFIG_APPLE_PROPERTIES is not set ++# CONFIG_APPLICOM is not set ++# CONFIG_AQTION is not set ++# CONFIG_AQUANTIA_PHY is not set ++# CONFIG_AR5523 is not set ++# CONFIG_AR7 is not set ++# CONFIG_AR8216_PHY is not set ++# CONFIG_AR8216_PHY_LEDS is not set ++# CONFIG_ARCH_ACTIONS is not set ++# CONFIG_ARCH_AGILEX is not set ++# CONFIG_ARCH_ALPINE is not set ++# CONFIG_ARCH_ARTPEC is not set ++# CONFIG_ARCH_ASPEED is not set ++# CONFIG_ARCH_AT91 is not set ++# CONFIG_ARCH_AXXIA is not set ++# CONFIG_ARCH_BCM is not set ++# CONFIG_ARCH_BCM2835 is not set ++# CONFIG_ARCH_BCM_21664 is not set ++# CONFIG_ARCH_BCM_23550 is not set ++# CONFIG_ARCH_BCM_281XX is not set ++# CONFIG_ARCH_BCM_5301X is not set ++# CONFIG_ARCH_BCM_53573 is not set ++# CONFIG_ARCH_BCM_63XX is not set ++# CONFIG_ARCH_BCM_CYGNUS is not set ++# CONFIG_ARCH_BCM_IPROC is not set ++# CONFIG_ARCH_BCM_NSP is not set ++# CONFIG_ARCH_BERLIN is not set ++CONFIG_ARCH_BINFMT_ELF_STATE=y ++# CONFIG_ARCH_BITMAIN is not set ++# CONFIG_ARCH_BRCMSTB is not set ++# CONFIG_ARCH_CLPS711X is not set ++# CONFIG_ARCH_CNS3XXX is not set ++# CONFIG_ARCH_DAVINCI is not set ++# CONFIG_ARCH_DIGICOLOR is not set ++# CONFIG_ARCH_DMA_ADDR_T_64BIT is not set ++# CONFIG_ARCH_DOVE is not set ++# CONFIG_ARCH_EBSA110 is not set ++# CONFIG_ARCH_EP93XX is not set ++# CONFIG_ARCH_EXYNOS is not set ++CONFIG_ARCH_FLATMEM_ENABLE=y ++# CONFIG_ARCH_FOOTBRIDGE is not set ++# CONFIG_ARCH_GEMINI is not set ++# CONFIG_ARCH_HI3xxx is not set ++# CONFIG_ARCH_HIGHBANK is not set ++# CONFIG_ARCH_HISI is not set ++# CONFIG_ARCH_INTEGRATOR is not set ++# CONFIG_ARCH_IOP13XX is not set ++# CONFIG_ARCH_IOP32X is not set ++# CONFIG_ARCH_IOP33X is not set ++# CONFIG_ARCH_IXP4XX is not set ++# CONFIG_ARCH_K3 is not set ++# CONFIG_ARCH_KEEMBAY is not set ++# CONFIG_ARCH_KEYSTONE is not set ++# CONFIG_ARCH_KS8695 is not set ++# CONFIG_ARCH_LAYERSCAPE is not set ++# CONFIG_ARCH_LG1K is not set ++# CONFIG_ARCH_LPC32XX is not set ++# CONFIG_ARCH_MEDIATEK is not set ++# CONFIG_ARCH_MESON is not set ++# CONFIG_ARCH_MILBEAUT is not set ++CONFIG_ARCH_MMAP_RND_BITS=8 ++CONFIG_ARCH_MMAP_RND_BITS_MAX=16 ++CONFIG_ARCH_MMAP_RND_BITS_MIN=8 ++CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16 ++CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 ++# CONFIG_ARCH_MMP is not set ++# CONFIG_ARCH_MULTIPLATFORM is not set ++# CONFIG_ARCH_MULTI_V6 is not set ++# CONFIG_ARCH_MULTI_V7 is not set ++# CONFIG_ARCH_MV78XX0 is not set ++# CONFIG_ARCH_MVEBU is not set ++# CONFIG_ARCH_MXC is not set ++# CONFIG_ARCH_MXS is not set ++# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set ++# CONFIG_ARCH_NETX is not set ++# CONFIG_ARCH_NOMADIK is not set ++# CONFIG_ARCH_NPCM is not set ++# CONFIG_ARCH_NSPIRE is not set ++# CONFIG_ARCH_OMAP is not set ++# CONFIG_ARCH_OMAP1 is not set ++# CONFIG_ARCH_OMAP2 is not set ++# CONFIG_ARCH_OMAP2PLUS is not set ++# CONFIG_ARCH_OMAP3 is not set ++# CONFIG_ARCH_OMAP4 is not set ++# CONFIG_ARCH_ORION5X is not set ++# CONFIG_ARCH_OXNAS is not set ++# CONFIG_ARCH_PICOXCELL is not set ++# CONFIG_ARCH_PRIMA2 is not set ++# CONFIG_ARCH_PXA is not set ++# CONFIG_ARCH_QCOM is not set ++# CONFIG_ARCH_RANDOM is not set ++# CONFIG_ARCH_RDA is not set ++# CONFIG_ARCH_REALTEK is not set ++# CONFIG_ARCH_REALVIEW is not set ++# CONFIG_ARCH_RENESAS is not set ++# CONFIG_ARCH_ROCKCHIP is not set ++# CONFIG_ARCH_RPC is not set ++# CONFIG_ARCH_S32 is not set ++# CONFIG_ARCH_S3C24XX is not set ++# CONFIG_ARCH_S3C64XX is not set ++# CONFIG_ARCH_S5PV210 is not set ++# CONFIG_ARCH_SA1100 is not set ++# CONFIG_ARCH_SEATTLE is not set ++# CONFIG_ARCH_SHMOBILE is not set ++# CONFIG_ARCH_SIRF is not set ++# CONFIG_ARCH_SOCFPGA is not set ++# CONFIG_ARCH_SPARX5 is not set ++# CONFIG_ARCH_SPRD is not set ++# CONFIG_ARCH_STI is not set ++# CONFIG_ARCH_STM32 is not set ++# CONFIG_ARCH_STRATIX10 is not set ++# CONFIG_ARCH_SUNXI is not set ++# CONFIG_ARCH_SYNQUACER is not set ++# CONFIG_ARCH_TANGO is not set ++# CONFIG_ARCH_TEGRA is not set ++# CONFIG_ARCH_THUNDER is not set ++# CONFIG_ARCH_THUNDER2 is not set ++# CONFIG_ARCH_U300 is not set ++# CONFIG_ARCH_U8500 is not set ++# CONFIG_ARCH_UNIPHIER is not set ++# CONFIG_ARCH_VERSATILE is not set ++# CONFIG_ARCH_VEXPRESS is not set ++# CONFIG_ARCH_VIRT is not set ++# CONFIG_ARCH_VISCONTI is not set ++# CONFIG_ARCH_VT8500 is not set ++# CONFIG_ARCH_VULCAN is not set ++# CONFIG_ARCH_W90X900 is not set ++# CONFIG_ARCH_WANTS_THP_SWAP is not set ++# CONFIG_ARCH_WM8505 is not set ++# CONFIG_ARCH_WM8750 is not set ++# CONFIG_ARCH_WM8850 is not set ++# CONFIG_ARCH_XGENE is not set ++# CONFIG_ARCH_ZX is not set ++# CONFIG_ARCH_ZYNQ is not set ++# CONFIG_ARCH_ZYNQMP is not set ++# CONFIG_ARCNET is not set ++# CONFIG_ARC_EMAC is not set ++# CONFIG_ARC_IRQ_NO_AUTOSAVE is not set ++# CONFIG_ARM64_16K_PAGES is not set ++# CONFIG_ARM64_64K_PAGES is not set ++# CONFIG_ARM64_AMU_EXTN is not set ++# CONFIG_ARM64_BTI is not set ++# CONFIG_ARM64_CRYPTO is not set ++# CONFIG_ARM64_E0PD is not set ++# CONFIG_ARM64_ERRATUM_1024718 is not set ++# CONFIG_ARM64_ERRATUM_1319367 is not set ++# CONFIG_ARM64_ERRATUM_1463225 is not set ++# CONFIG_ARM64_ERRATUM_1508412 is not set ++# CONFIG_ARM64_ERRATUM_1530923 is not set ++# CONFIG_ARM64_ERRATUM_1542419 is not set ++# CONFIG_ARM64_ERRATUM_819472 is not set ++# CONFIG_ARM64_ERRATUM_824069 is not set ++# CONFIG_ARM64_ERRATUM_826319 is not set ++# CONFIG_ARM64_ERRATUM_827319 is not set ++# CONFIG_ARM64_ERRATUM_832075 is not set ++# CONFIG_ARM64_ERRATUM_834220 is not set ++# CONFIG_ARM64_ERRATUM_843419 is not set ++# CONFIG_ARM64_ERRATUM_845719 is not set ++# CONFIG_ARM64_ERRATUM_858921 is not set ++# CONFIG_ARM64_HW_AFDBM is not set ++# CONFIG_ARM64_LSE_ATOMICS is not set ++# CONFIG_ARM64_MODULE_PLTS is not set ++# CONFIG_ARM64_MTE is not set ++# CONFIG_ARM64_PAN is not set ++# CONFIG_ARM64_PMEM is not set ++# CONFIG_ARM64_PSEUDO_NMI is not set ++# CONFIG_ARM64_PTDUMP_DEBUGFS is not set ++# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set ++# CONFIG_ARM64_RAS_EXTN is not set ++# CONFIG_ARM64_RELOC_TEST is not set ++CONFIG_ARM64_SW_TTBR0_PAN=y ++# CONFIG_ARM64_TLB_RANGE is not set ++# CONFIG_ARM64_UAO is not set ++# CONFIG_ARM64_USE_LSE_ATOMICS is not set ++# CONFIG_ARM64_VA_BITS_48 is not set ++# CONFIG_ARM64_VHE is not set ++# CONFIG_ARM_APPENDED_DTB is not set ++# CONFIG_ARM_ARCH_TIMER is not set ++# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set ++# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set ++# CONFIG_ARM_CCI is not set ++# CONFIG_ARM_CCI400_PMU is not set ++# CONFIG_ARM_CCI5xx_PMU is not set ++# CONFIG_ARM_CCI_PMU is not set ++# CONFIG_ARM_CCN is not set ++# CONFIG_ARM_CMN is not set ++# CONFIG_ARM_CPUIDLE is not set ++CONFIG_ARM_CPU_TOPOLOGY=y ++# CONFIG_ARM_CRYPTO is not set ++CONFIG_ARM_DMA_MEM_BUFFERABLE=y ++# CONFIG_ARM_DSU_PMU is not set ++# CONFIG_ARM_ERRATA_326103 is not set ++# CONFIG_ARM_ERRATA_364296 is not set ++# CONFIG_ARM_ERRATA_411920 is not set ++# CONFIG_ARM_ERRATA_430973 is not set ++# CONFIG_ARM_ERRATA_458693 is not set ++# CONFIG_ARM_ERRATA_460075 is not set ++# CONFIG_ARM_ERRATA_643719 is not set ++# CONFIG_ARM_ERRATA_720789 is not set ++# CONFIG_ARM_ERRATA_742230 is not set ++# CONFIG_ARM_ERRATA_742231 is not set ++# CONFIG_ARM_ERRATA_743622 is not set ++# CONFIG_ARM_ERRATA_751472 is not set ++# CONFIG_ARM_ERRATA_754322 is not set ++# CONFIG_ARM_ERRATA_754327 is not set ++# CONFIG_ARM_ERRATA_764369 is not set ++# CONFIG_ARM_ERRATA_773022 is not set ++# CONFIG_ARM_ERRATA_775420 is not set ++# CONFIG_ARM_ERRATA_798181 is not set ++# CONFIG_ARM_ERRATA_814220 is not set ++# CONFIG_ARM_ERRATA_818325_852422 is not set ++# CONFIG_ARM_ERRATA_821420 is not set ++# CONFIG_ARM_ERRATA_825619 is not set ++# CONFIG_ARM_ERRATA_852421 is not set ++# CONFIG_ARM_ERRATA_852423 is not set ++# CONFIG_ARM_ERRATA_857271 is not set ++# CONFIG_ARM_ERRATA_857272 is not set ++CONFIG_ARM_GIC_MAX_NR=1 ++# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set ++# CONFIG_ARM_KPROBES_TEST is not set ++# CONFIG_ARM_LPAE is not set ++# CONFIG_ARM_MHU is not set ++# CONFIG_ARM_MODULE_PLTS is not set ++# CONFIG_ARM_PATCH_PHYS_VIRT is not set ++# CONFIG_ARM_PSCI is not set ++# CONFIG_ARM_PSCI_CHECKER is not set ++# CONFIG_ARM_PTDUMP_DEBUGFS is not set ++# CONFIG_ARM_SBSA_WATCHDOG is not set ++# CONFIG_ARM_SCPI_PROTOCOL is not set ++# CONFIG_ARM_SDE_INTERFACE is not set ++# CONFIG_ARM_SMCCC_SOC_ID is not set ++# CONFIG_ARM_SMC_WATCHDOG is not set ++# CONFIG_ARM_SP805_WATCHDOG is not set ++# CONFIG_ARM_SPE_PMU is not set ++# CONFIG_ARM_THUMBEE is not set ++# CONFIG_ARM_TIMER_SP804 is not set ++# CONFIG_ARM_UNWIND is not set ++# CONFIG_ARM_VIRT_EXT is not set ++# CONFIG_AS3935 is not set ++# CONFIG_ASM9260_TIMER is not set ++# CONFIG_ASUS_LAPTOP is not set ++# CONFIG_ASUS_WIRELESS is not set ++# CONFIG_ASYMMETRIC_KEY_TYPE is not set ++# CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE is not set ++# CONFIG_ASYNC_RAID6_TEST is not set ++# CONFIG_ASYNC_TX_DMA is not set ++# CONFIG_AT76C50X_USB is not set ++# CONFIG_AT803X_PHY is not set ++# CONFIG_AT91_SAMA5D2_ADC is not set ++# CONFIG_ATA is not set ++# CONFIG_ATAGS is not set ++CONFIG_ATAGS_PROC=y ++# CONFIG_ATALK is not set ++# CONFIG_ATARI_PARTITION is not set ++# CONFIG_ATA_ACPI is not set ++CONFIG_ATA_BMDMA=y ++# CONFIG_ATA_FORCE is not set ++# CONFIG_ATA_GENERIC is not set ++# CONFIG_ATA_LEDS is not set ++# CONFIG_ATA_NONSTANDARD is not set ++# CONFIG_ATA_OVER_ETH is not set ++# CONFIG_ATA_PIIX is not set ++CONFIG_ATA_SFF=y ++# CONFIG_ATA_VERBOSE_ERROR is not set ++# CONFIG_ATH10K is not set ++# CONFIG_ATH25 is not set ++# CONFIG_ATH5K is not set ++# CONFIG_ATH6KL is not set ++# CONFIG_ATH79 is not set ++# CONFIG_ATH9K is not set ++# CONFIG_ATH9K_HTC is not set ++# CONFIG_ATH_DEBUG is not set ++# CONFIG_ATL1 is not set ++# CONFIG_ATL1C is not set ++# CONFIG_ATL1E is not set ++# CONFIG_ATL2 is not set ++# CONFIG_ATLAS_EZO_SENSOR is not set ++# CONFIG_ATLAS_PH_SENSOR is not set ++# CONFIG_ATM is not set ++# CONFIG_ATMEL is not set ++# CONFIG_ATMEL_PIT is not set ++# CONFIG_ATMEL_SSC is not set ++# CONFIG_ATM_AMBASSADOR is not set ++# CONFIG_ATM_BR2684 is not set ++CONFIG_ATM_BR2684_IPFILTER=y ++# CONFIG_ATM_CLIP is not set ++CONFIG_ATM_CLIP_NO_ICMP=y ++# CONFIG_ATM_DRIVERS is not set ++# CONFIG_ATM_DUMMY is not set ++# CONFIG_ATM_ENI is not set ++# CONFIG_ATM_FIRESTREAM is not set ++# CONFIG_ATM_FORE200E is not set ++# CONFIG_ATM_HE is not set ++# CONFIG_ATM_HORIZON is not set ++# CONFIG_ATM_IA is not set ++# CONFIG_ATM_IDT77252 is not set ++# CONFIG_ATM_LANAI is not set ++# CONFIG_ATM_LANE is not set ++# CONFIG_ATM_MPOA is not set ++# CONFIG_ATM_NICSTAR is not set ++# CONFIG_ATM_SOLOS is not set ++# CONFIG_ATM_TCP is not set ++# CONFIG_ATM_ZATM is not set ++# CONFIG_ATOMIC64_SELFTEST is not set ++# CONFIG_ATP is not set ++# CONFIG_AUDIT is not set ++# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set ++# CONFIG_AURORA_NB8800 is not set ++# CONFIG_AUTOFS4_FS is not set ++# CONFIG_AUTOFS_FS is not set ++# CONFIG_AUTO_ZRELADDR is not set ++# CONFIG_AUXDISPLAY is not set ++# CONFIG_AX25 is not set ++# CONFIG_AX25_DAMA_SLAVE is not set ++# CONFIG_AX88796 is not set ++# CONFIG_AX88796B_PHY is not set ++# CONFIG_AXP20X_ADC is not set ++# CONFIG_AXP20X_POWER is not set ++# CONFIG_AXP288_ADC is not set ++# CONFIG_AXP288_FUEL_GAUGE is not set ++# CONFIG_B43 is not set ++# CONFIG_B43LEGACY is not set ++# CONFIG_B44 is not set ++# CONFIG_B53 is not set ++# CONFIG_BACKLIGHT_ADP8860 is not set ++# CONFIG_BACKLIGHT_ADP8870 is not set ++# CONFIG_BACKLIGHT_APPLE is not set ++# CONFIG_BACKLIGHT_ARCXCNN is not set ++# CONFIG_BACKLIGHT_BD6107 is not set ++# CONFIG_BACKLIGHT_CLASS_DEVICE is not set ++# CONFIG_BACKLIGHT_GENERIC is not set ++# CONFIG_BACKLIGHT_GPIO is not set ++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set ++# CONFIG_BACKLIGHT_LM3630A is not set ++# CONFIG_BACKLIGHT_LM3639 is not set ++# CONFIG_BACKLIGHT_LP855X is not set ++# CONFIG_BACKLIGHT_LV5207LP is not set ++# CONFIG_BACKLIGHT_PANDORA is not set ++# CONFIG_BACKLIGHT_PM8941_WLED is not set ++# CONFIG_BACKLIGHT_PWM is not set ++# CONFIG_BACKLIGHT_RPI is not set ++# CONFIG_BACKLIGHT_SAHARA is not set ++# CONFIG_BACKTRACE_SELF_TEST is not set ++# CONFIG_BAREUDP is not set ++CONFIG_BASE_FULL=y ++CONFIG_BASE_SMALL=0 ++# CONFIG_BATMAN_ADV is not set ++# CONFIG_BATTERY_BQ27XXX is not set ++# CONFIG_BATTERY_BQ27XXX_HDQ is not set ++# CONFIG_BATTERY_CW2015 is not set ++# CONFIG_BATTERY_DS2760 is not set ++# CONFIG_BATTERY_DS2780 is not set ++# CONFIG_BATTERY_DS2781 is not set ++# CONFIG_BATTERY_DS2782 is not set ++# CONFIG_BATTERY_GAUGE_LTC2941 is not set ++# CONFIG_BATTERY_GOLDFISH is not set ++# CONFIG_BATTERY_LEGO_EV3 is not set ++# CONFIG_BATTERY_MAX17040 is not set ++# CONFIG_BATTERY_MAX17042 is not set ++# CONFIG_BATTERY_MAX1721X is not set ++# CONFIG_BATTERY_SBS is not set ++# CONFIG_BAYCOM_EPP is not set ++# CONFIG_BAYCOM_PAR is not set ++# CONFIG_BAYCOM_SER_FDX is not set ++# CONFIG_BAYCOM_SER_HDX is not set ++# CONFIG_BCACHE is not set ++# CONFIG_BCM47XX is not set ++# CONFIG_BCM54140_PHY is not set ++# CONFIG_BCM63XX is not set ++# CONFIG_BCM63XX_PHY is not set ++# CONFIG_BCM7038_WDT is not set ++# CONFIG_BCM7XXX_PHY is not set ++# CONFIG_BCM84881_PHY is not set ++# CONFIG_BCM87XX_PHY is not set ++# CONFIG_BCMA is not set ++# CONFIG_BCMA_DRIVER_GPIO is not set ++CONFIG_BCMA_POSSIBLE=y ++# CONFIG_BCMGENET is not set ++# CONFIG_BCM_IPROC_ADC is not set ++# CONFIG_BCM_KONA_USB2_PHY is not set ++# CONFIG_BCM_SBA_RAID is not set ++# CONFIG_BDI_SWITCH is not set ++# CONFIG_BE2ISCSI is not set ++# CONFIG_BE2NET is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BFS_FS is not set ++# CONFIG_BGMAC is not set ++# CONFIG_BH1750 is not set ++# CONFIG_BH1780 is not set ++# CONFIG_BIG_KEYS is not set ++# CONFIG_BIG_LITTLE is not set ++# CONFIG_BINARY_PRINTF is not set ++# CONFIG_BINFMT_AOUT is not set ++CONFIG_BINFMT_ELF=y ++# CONFIG_BINFMT_ELF_FDPIC is not set ++# CONFIG_BINFMT_FLAT is not set ++# CONFIG_BINFMT_MISC is not set ++CONFIG_BINFMT_SCRIPT=y ++CONFIG_BITREVERSE=y ++# CONFIG_BLK_CGROUP_IOCOST is not set ++# CONFIG_BLK_CGROUP_IOLATENCY is not set ++# CONFIG_BLK_CMDLINE_PARSER is not set ++# CONFIG_BLK_DEBUG_FS is not set ++CONFIG_BLK_DEV=y ++# CONFIG_BLK_DEV_3W_XXXX_RAID is not set ++# CONFIG_BLK_DEV_4DRIVES is not set ++# CONFIG_BLK_DEV_AEC62XX is not set ++# CONFIG_BLK_DEV_ALI14XX is not set ++# CONFIG_BLK_DEV_ALI15X3 is not set ++# CONFIG_BLK_DEV_AMD74XX is not set ++# CONFIG_BLK_DEV_ATIIXP is not set ++# CONFIG_BLK_DEV_BSG is not set ++# CONFIG_BLK_DEV_BSGLIB is not set ++# CONFIG_BLK_DEV_CMD640 is not set ++# CONFIG_BLK_DEV_CMD64X is not set ++# CONFIG_BLK_DEV_COW_COMMON is not set ++# CONFIG_BLK_DEV_CRYPTOLOOP is not set ++# CONFIG_BLK_DEV_CS5520 is not set ++# CONFIG_BLK_DEV_CS5530 is not set ++# CONFIG_BLK_DEV_CS5535 is not set ++# CONFIG_BLK_DEV_CS5536 is not set ++# CONFIG_BLK_DEV_CY82C693 is not set ++# CONFIG_BLK_DEV_DAC960 is not set ++# CONFIG_BLK_DEV_DELKIN is not set ++# CONFIG_BLK_DEV_DRBD is not set ++# CONFIG_BLK_DEV_DTC2278 is not set ++# CONFIG_BLK_DEV_FD is not set ++# CONFIG_BLK_DEV_GENERIC is not set ++# CONFIG_BLK_DEV_HPT366 is not set ++# CONFIG_BLK_DEV_HT6560B is not set ++# CONFIG_BLK_DEV_IDEACPI is not set ++# CONFIG_BLK_DEV_IDECD is not set ++# CONFIG_BLK_DEV_IDECS is not set ++# CONFIG_BLK_DEV_IDEPCI is not set ++# CONFIG_BLK_DEV_IDEPNP is not set ++# CONFIG_BLK_DEV_IDETAPE is not set ++# CONFIG_BLK_DEV_IDE_AU1XXX is not set ++# CONFIG_BLK_DEV_IDE_SATA is not set ++CONFIG_BLK_DEV_INITRD=y ++# CONFIG_BLK_DEV_INTEGRITY is not set ++# CONFIG_BLK_DEV_IO_TRACE is not set ++# CONFIG_BLK_DEV_IT8172 is not set ++# CONFIG_BLK_DEV_IT8213 is not set ++# CONFIG_BLK_DEV_IT821X is not set ++# CONFIG_BLK_DEV_JMICRON is not set ++# CONFIG_BLK_DEV_LOOP is not set ++CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 ++# CONFIG_BLK_DEV_NBD is not set ++# CONFIG_BLK_DEV_NS87415 is not set ++# CONFIG_BLK_DEV_NULL_BLK is not set ++# CONFIG_BLK_DEV_NVME is not set ++# CONFIG_BLK_DEV_OFFBOARD is not set ++# CONFIG_BLK_DEV_OPTI621 is not set ++# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set ++# CONFIG_BLK_DEV_PDC202XX_NEW is not set ++# CONFIG_BLK_DEV_PDC202XX_OLD is not set ++# CONFIG_BLK_DEV_PIIX is not set ++# CONFIG_BLK_DEV_PLATFORM is not set ++# CONFIG_BLK_DEV_PMEM is not set ++# CONFIG_BLK_DEV_QD65XX is not set ++# CONFIG_BLK_DEV_RAM is not set ++# CONFIG_BLK_DEV_RBD is not set ++# CONFIG_BLK_DEV_RSXX is not set ++# CONFIG_BLK_DEV_RZ1000 is not set ++# CONFIG_BLK_DEV_SC1200 is not set ++# CONFIG_BLK_DEV_SD is not set ++# CONFIG_BLK_DEV_SIIMAGE is not set ++# CONFIG_BLK_DEV_SIS5513 is not set ++# CONFIG_BLK_DEV_SKD is not set ++# CONFIG_BLK_DEV_SL82C105 is not set ++# CONFIG_BLK_DEV_SLC90E66 is not set ++# CONFIG_BLK_DEV_SR is not set ++# CONFIG_BLK_DEV_SVWKS is not set ++# CONFIG_BLK_DEV_SX8 is not set ++# CONFIG_BLK_DEV_TC86C001 is not set ++# CONFIG_BLK_DEV_THROTTLING is not set ++# CONFIG_BLK_DEV_TRIFLEX is not set ++# CONFIG_BLK_DEV_TRM290 is not set ++# CONFIG_BLK_DEV_UMC8672 is not set ++# CONFIG_BLK_DEV_UMEM is not set ++# CONFIG_BLK_DEV_VIA82CXXX is not set ++# CONFIG_BLK_DEV_ZONED is not set ++# CONFIG_BLK_INLINE_ENCRYPTION is not set ++# CONFIG_BLK_SED_OPAL is not set ++# CONFIG_BLK_WBT is not set ++CONFIG_BLOCK=y ++# CONFIG_BMA180 is not set ++# CONFIG_BMA220 is not set ++# CONFIG_BMA400 is not set ++# CONFIG_BMC150_ACCEL is not set ++# CONFIG_BMC150_MAGN is not set ++# CONFIG_BMC150_MAGN_I2C is not set ++# CONFIG_BMC150_MAGN_SPI is not set ++# CONFIG_BME680 is not set ++# CONFIG_BMG160 is not set ++# CONFIG_BMI160_I2C is not set ++# CONFIG_BMI160_SPI is not set ++# CONFIG_BMIPS_GENERIC is not set ++# CONFIG_BMP280 is not set ++# CONFIG_BNA is not set ++# CONFIG_BNX2 is not set ++# CONFIG_BNX2X is not set ++# CONFIG_BNX2X_SRIOV is not set ++# CONFIG_BNXT is not set ++# CONFIG_BONDING is not set ++# CONFIG_BOOKE_WDT is not set ++CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT=3 ++# CONFIG_BOOT_CONFIG is not set ++# CONFIG_BOOT_PRINTK_DELAY is not set ++CONFIG_BOOT_RAW=y ++# CONFIG_BOUNCE is not set ++CONFIG_BPF=y ++# CONFIG_BPFILTER is not set ++CONFIG_BPF_JIT=y ++# CONFIG_BPF_JIT_ALWAYS_ON is not set ++CONFIG_BPF_JIT_DEFAULT_ON=y ++# CONFIG_BPF_PRELOAD is not set ++# CONFIG_BPF_STREAM_PARSER is not set ++CONFIG_BPF_SYSCALL=y ++# CONFIG_BPQETHER is not set ++CONFIG_BQL=y ++CONFIG_BRANCH_PROFILE_NONE=y ++# CONFIG_BRCMFMAC is not set ++# CONFIG_BRCMSMAC is not set ++# CONFIG_BRCMSTB_GISB_ARB is not set ++CONFIG_BRIDGE=y ++# CONFIG_BRIDGE_EBT_802_3 is not set ++# CONFIG_BRIDGE_EBT_AMONG is not set ++# CONFIG_BRIDGE_EBT_ARP is not set ++# CONFIG_BRIDGE_EBT_ARPREPLY is not set ++# CONFIG_BRIDGE_EBT_BROUTE is not set ++# CONFIG_BRIDGE_EBT_DNAT is not set ++# CONFIG_BRIDGE_EBT_IP is not set ++# CONFIG_BRIDGE_EBT_IP6 is not set ++# CONFIG_BRIDGE_EBT_LIMIT is not set ++# CONFIG_BRIDGE_EBT_LOG is not set ++# CONFIG_BRIDGE_EBT_MARK is not set ++# CONFIG_BRIDGE_EBT_MARK_T is not set ++# CONFIG_BRIDGE_EBT_NFLOG is not set ++# CONFIG_BRIDGE_EBT_PKTTYPE is not set ++# CONFIG_BRIDGE_EBT_REDIRECT is not set ++# CONFIG_BRIDGE_EBT_SNAT is not set ++# CONFIG_BRIDGE_EBT_STP is not set ++# CONFIG_BRIDGE_EBT_T_FILTER is not set ++# CONFIG_BRIDGE_EBT_T_NAT is not set ++# CONFIG_BRIDGE_EBT_VLAN is not set ++CONFIG_BRIDGE_IGMP_SNOOPING=y ++# CONFIG_BRIDGE_MRP is not set ++# CONFIG_BRIDGE_NETFILTER is not set ++# CONFIG_BRIDGE_NF_EBTABLES is not set ++CONFIG_BRIDGE_VLAN_FILTERING=y ++# CONFIG_BROADCOM_PHY is not set ++CONFIG_BROKEN_ON_SMP=y ++# CONFIG_BSD_DISKLABEL is not set ++# CONFIG_BSD_PROCESS_ACCT is not set ++# CONFIG_BSD_PROCESS_ACCT_V3 is not set ++# CONFIG_BT is not set ++# CONFIG_BTRFS_ASSERT is not set ++# CONFIG_BTRFS_DEBUG is not set ++# CONFIG_BTRFS_FS is not set ++# CONFIG_BTRFS_FS_POSIX_ACL is not set ++# CONFIG_BTRFS_FS_REF_VERIFY is not set ++# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set ++# CONFIG_BT_ATH3K is not set ++# CONFIG_BT_BNEP is not set ++CONFIG_BT_BNEP_MC_FILTER=y ++CONFIG_BT_BNEP_PROTO_FILTER=y ++# CONFIG_BT_BREDR is not set ++# CONFIG_BT_CMTP is not set ++# CONFIG_BT_FEATURE_DEBUG is not set ++# CONFIG_BT_HCIBCM203X is not set ++# CONFIG_BT_HCIBFUSB is not set ++# CONFIG_BT_HCIBLUECARD is not set ++# CONFIG_BT_HCIBPA10X is not set ++# CONFIG_BT_HCIBT3C is not set ++# CONFIG_BT_HCIBTSDIO is not set ++# CONFIG_BT_HCIBTUSB is not set ++# CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set ++# CONFIG_BT_HCIBTUSB_MTK is not set ++# CONFIG_BT_HCIBTUSB_RTL is not set ++# CONFIG_BT_HCIDTL1 is not set ++# CONFIG_BT_HCIUART is not set ++# CONFIG_BT_HCIUART_3WIRE is not set ++# CONFIG_BT_HCIUART_AG6XX is not set ++# CONFIG_BT_HCIUART_ATH3K is not set ++CONFIG_BT_HCIUART_BCSP=y ++CONFIG_BT_HCIUART_H4=y ++# CONFIG_BT_HCIUART_LL is not set ++# CONFIG_BT_HCIUART_MRVL is not set ++# CONFIG_BT_HCIUART_QCA is not set ++# CONFIG_BT_HCIUART_RTL is not set ++# CONFIG_BT_HCIVHCI is not set ++# CONFIG_BT_HIDP is not set ++# CONFIG_BT_HS is not set ++# CONFIG_BT_LE is not set ++# CONFIG_BT_LEDS is not set ++# CONFIG_BT_MRVL is not set ++# CONFIG_BT_MSFTEXT is not set ++# CONFIG_BT_MTKSDIO is not set ++# CONFIG_BT_MTKUART is not set ++# CONFIG_BT_RFCOMM is not set ++CONFIG_BT_RFCOMM_TTY=y ++# CONFIG_BT_SELFTEST is not set ++CONFIG_BUG=y ++# CONFIG_BUG_ON_DATA_CORRUPTION is not set ++CONFIG_BUILDTIME_EXTABLE_SORT=y ++CONFIG_BUILDTIME_TABLE_SORT=y ++# CONFIG_BUILD_BIN2C is not set ++CONFIG_BUILD_SALT="" ++# CONFIG_C2PORT is not set ++CONFIG_CACHE_L2X0_PMU=y ++# CONFIG_CADENCE_WATCHDOG is not set ++# CONFIG_CAIF is not set ++# CONFIG_CAN is not set ++# CONFIG_CAN_BCM is not set ++# CONFIG_CAN_DEBUG_DEVICES is not set ++# CONFIG_CAN_DEV is not set ++# CONFIG_CAN_GS_USB is not set ++# CONFIG_CAN_GW is not set ++# CONFIG_CAN_HI311X is not set ++# CONFIG_CAN_IFI_CANFD is not set ++# CONFIG_CAN_J1939 is not set ++# CONFIG_CAN_KVASER_PCIEFD is not set ++# CONFIG_CAN_MCBA_USB is not set ++# CONFIG_CAN_M_CAN is not set ++# CONFIG_CAN_PEAK_PCIEFD is not set ++# CONFIG_CAN_RAW is not set ++# CONFIG_CAN_RCAR is not set ++# CONFIG_CAN_RCAR_CANFD is not set ++# CONFIG_CAN_SLCAN is not set ++# CONFIG_CAN_SUN4I is not set ++# CONFIG_CAN_UCAN is not set ++# CONFIG_CAN_VCAN is not set ++# CONFIG_CAN_VXCAN is not set ++# CONFIG_CAPI_AVM is not set ++# CONFIG_CAPI_EICON is not set ++# CONFIG_CAPI_TRACE is not set ++CONFIG_CARDBUS=y ++# CONFIG_CARDMAN_4000 is not set ++# CONFIG_CARDMAN_4040 is not set ++# CONFIG_CARL9170 is not set ++# CONFIG_CASSINI is not set ++# CONFIG_CAVIUM_CPT is not set ++# CONFIG_CAVIUM_ERRATUM_22375 is not set ++# CONFIG_CAVIUM_ERRATUM_23144 is not set ++# CONFIG_CAVIUM_ERRATUM_23154 is not set ++# CONFIG_CAVIUM_ERRATUM_27456 is not set ++# CONFIG_CAVIUM_ERRATUM_30115 is not set ++# CONFIG_CAVIUM_OCTEON_SOC is not set ++# CONFIG_CAVIUM_PTP is not set ++# CONFIG_CB710_CORE is not set ++# CONFIG_CC10001_ADC is not set ++# CONFIG_CCS811 is not set ++CONFIG_CC_CAN_LINK=y ++CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y ++# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set ++# CONFIG_CDROM_PKTCDVD is not set ++# CONFIG_CEPH_FS is not set ++# CONFIG_CEPH_LIB is not set ++# CONFIG_CFG80211 is not set ++# CONFIG_CFG80211_CERTIFICATION_ONUS is not set ++# CONFIG_CGROUPS is not set ++# CONFIG_CHARGER_ADP5061 is not set ++# CONFIG_CHARGER_BD99954 is not set ++# CONFIG_CHARGER_BQ2415X is not set ++# CONFIG_CHARGER_BQ24190 is not set ++# CONFIG_CHARGER_BQ24257 is not set ++# CONFIG_CHARGER_BQ24735 is not set ++# CONFIG_CHARGER_BQ2515X is not set ++# CONFIG_CHARGER_BQ25890 is not set ++# CONFIG_CHARGER_DETECTOR_MAX14656 is not set ++# CONFIG_CHARGER_GPIO is not set ++# CONFIG_CHARGER_ISP1704 is not set ++# CONFIG_CHARGER_LP8727 is not set ++# CONFIG_CHARGER_LT3651 is not set ++# CONFIG_CHARGER_LTC3651 is not set ++# CONFIG_CHARGER_MANAGER is not set ++# CONFIG_CHARGER_MAX8903 is not set ++# CONFIG_CHARGER_RT9455 is not set ++# CONFIG_CHARGER_SBS is not set ++# CONFIG_CHARGER_SMB347 is not set ++# CONFIG_CHARGER_TWL4030 is not set ++# CONFIG_CHARGER_UCS1002 is not set ++# CONFIG_CHASH_SELFTEST is not set ++# CONFIG_CHASH_STATS is not set ++# CONFIG_CHECKPOINT_RESTORE is not set ++# CONFIG_CHELSIO_T1 is not set ++# CONFIG_CHELSIO_T3 is not set ++# CONFIG_CHELSIO_T4 is not set ++# CONFIG_CHELSIO_T4VF is not set ++# CONFIG_CHROME_PLATFORMS is not set ++# CONFIG_CHR_DEV_OSST is not set ++# CONFIG_CHR_DEV_SCH is not set ++# CONFIG_CHR_DEV_SG is not set ++# CONFIG_CHR_DEV_ST is not set ++# CONFIG_CICADA_PHY is not set ++# CONFIG_CIFS is not set ++# CONFIG_CIFS_ACL is not set ++CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y ++# CONFIG_CIFS_DEBUG is not set ++# CONFIG_CIFS_DEBUG2 is not set ++# CONFIG_CIFS_FSCACHE is not set ++# CONFIG_CIFS_NFSD_EXPORT is not set ++CONFIG_CIFS_POSIX=y ++# CONFIG_CIFS_SMB2 is not set ++# CONFIG_CIFS_STATS is not set ++# CONFIG_CIFS_STATS2 is not set ++# CONFIG_CIFS_WEAK_PW_HASH is not set ++CONFIG_CIFS_XATTR=y ++# CONFIG_CIO_DAC is not set ++CONFIG_CLANG_VERSION=0 ++# CONFIG_CLEANCACHE is not set ++# CONFIG_CLKSRC_VERSATILE is not set ++# CONFIG_CLK_HSDK is not set ++# CONFIG_CLK_QORIQ is not set ++# CONFIG_CLOCK_THERMAL is not set ++CONFIG_CLS_U32_MARK=y ++# CONFIG_CLS_U32_PERF is not set ++# CONFIG_CM32181 is not set ++# CONFIG_CM3232 is not set ++# CONFIG_CM3323 is not set ++# CONFIG_CM3605 is not set ++# CONFIG_CM36651 is not set ++# CONFIG_CMA is not set ++CONFIG_CMDLINE="" ++# CONFIG_CMDLINE_BOOL is not set ++# CONFIG_CMDLINE_EXTEND is not set ++# CONFIG_CMDLINE_FORCE is not set ++# CONFIG_CMDLINE_FROM_BOOTLOADER is not set ++# CONFIG_CMDLINE_PARTITION is not set ++# CONFIG_CNIC is not set ++# CONFIG_CODA_FS is not set ++# CONFIG_CODE_PATCHING_SELFTEST is not set ++# CONFIG_COMEDI is not set ++# CONFIG_COMMON_CLK_CDCE706 is not set ++# CONFIG_COMMON_CLK_CDCE925 is not set ++# CONFIG_COMMON_CLK_CS2000_CP is not set ++# CONFIG_COMMON_CLK_FIXED_MMIO is not set ++# CONFIG_COMMON_CLK_IPROC is not set ++# CONFIG_COMMON_CLK_MAX9485 is not set ++# CONFIG_COMMON_CLK_MT6765 is not set ++# CONFIG_COMMON_CLK_MT8167 is not set ++# CONFIG_COMMON_CLK_MT8167_AUDSYS is not set ++# CONFIG_COMMON_CLK_MT8167_IMGSYS is not set ++# CONFIG_COMMON_CLK_MT8167_MFGCFG is not set ++# CONFIG_COMMON_CLK_MT8167_MMSYS is not set ++# CONFIG_COMMON_CLK_MT8167_VDECSYS is not set ++# CONFIG_COMMON_CLK_NXP is not set ++# CONFIG_COMMON_CLK_PIC32 is not set ++# CONFIG_COMMON_CLK_PWM is not set ++# CONFIG_COMMON_CLK_PXA is not set ++# CONFIG_COMMON_CLK_QCOM is not set ++# CONFIG_COMMON_CLK_SI514 is not set ++# CONFIG_COMMON_CLK_SI5341 is not set ++# CONFIG_COMMON_CLK_SI5351 is not set ++# CONFIG_COMMON_CLK_SI544 is not set ++# CONFIG_COMMON_CLK_SI570 is not set ++# CONFIG_COMMON_CLK_VC5 is not set ++# CONFIG_COMMON_CLK_VERSATILE is not set ++# CONFIG_COMMON_CLK_XGENE is not set ++# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set ++CONFIG_COMPACTION=y ++# CONFIG_COMPAL_LAPTOP is not set ++# CONFIG_COMPAT is not set ++# CONFIG_COMPAT_BRK is not set ++# CONFIG_COMPILE_TEST is not set ++# CONFIG_CONFIGFS_FS is not set ++# CONFIG_CONFIG_KVM_AMD_SEV is not set ++# CONFIG_CONNECTOR is not set ++CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7 ++CONFIG_CONSOLE_LOGLEVEL_QUIET=4 ++CONFIG_CONSTRUCTORS=y ++# CONFIG_CONTEXT_SWITCH_TRACER is not set ++# CONFIG_COPS is not set ++# CONFIG_CORDIC is not set ++# CONFIG_COREDUMP is not set ++# CONFIG_CORESIGHT is not set ++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set ++# CONFIG_CORTINA_PHY is not set ++# CONFIG_COUNTER is not set ++# CONFIG_CPA_DEBUG is not set ++# CONFIG_CPU_BIG_ENDIAN is not set ++# CONFIG_CPU_BPREDICT_DISABLE is not set ++# CONFIG_CPU_DCACHE_DISABLE is not set ++# CONFIG_CPU_FREQ is not set ++# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set ++# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set ++# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set ++# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set ++# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set ++# CONFIG_CPU_FREQ_GOV_SCHEDUTIL is not set ++# CONFIG_CPU_FREQ_STAT_DETAILS is not set ++# CONFIG_CPU_FREQ_THERMAL is not set ++# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set ++# CONFIG_CPU_ICACHE_DISABLE is not set ++# CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND is not set ++# CONFIG_CPU_IDLE is not set ++# CONFIG_CPU_IDLE_GOV_MENU is not set ++# CONFIG_CPU_IDLE_GOV_TEO is not set ++# CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is not set ++# CONFIG_CPU_ISOLATION is not set ++CONFIG_CPU_LITTLE_ENDIAN=y ++# CONFIG_CPU_NO_EFFICIENT_FFS is not set ++CONFIG_CPU_SW_DOMAIN_PAN=y ++# CONFIG_CRAMFS is not set ++CONFIG_CRAMFS_BLOCKDEV=y ++# CONFIG_CRAMFS_MTD is not set ++CONFIG_CRASHLOG=y ++# CONFIG_CRASH_DUMP is not set ++# CONFIG_CRC16 is not set ++CONFIG_CRC32=y ++# CONFIG_CRC32_BIT is not set ++CONFIG_CRC32_SARWATE=y ++# CONFIG_CRC32_SELFTEST is not set ++# CONFIG_CRC32_SLICEBY4 is not set ++# CONFIG_CRC32_SLICEBY8 is not set ++# CONFIG_CRC4 is not set ++# CONFIG_CRC64 is not set ++# CONFIG_CRC7 is not set ++# CONFIG_CRC8 is not set ++# CONFIG_CRC_CCITT is not set ++# CONFIG_CRC_ITU_T is not set ++# CONFIG_CRC_T10DIF is not set ++CONFIG_CROSS_COMPILE="" ++# CONFIG_CROSS_MEMORY_ATTACH is not set ++CONFIG_CRYPTO=y ++# CONFIG_CRYPTO_842 is not set ++# CONFIG_CRYPTO_ADIANTUM is not set ++# CONFIG_CRYPTO_AEAD is not set ++# CONFIG_CRYPTO_AEGIS128 is not set ++# CONFIG_CRYPTO_AEGIS128L is not set ++# CONFIG_CRYPTO_AEGIS128L_AESNI_SSE2 is not set ++# CONFIG_CRYPTO_AEGIS128_AESNI_SSE2 is not set ++# CONFIG_CRYPTO_AEGIS256 is not set ++# CONFIG_CRYPTO_AEGIS256_AESNI_SSE2 is not set ++CONFIG_CRYPTO_AES=y ++# CONFIG_CRYPTO_AES_586 is not set ++# CONFIG_CRYPTO_AES_ARM is not set ++# CONFIG_CRYPTO_AES_ARM_BS is not set ++# CONFIG_CRYPTO_AES_ARM_CE is not set ++# CONFIG_CRYPTO_AES_NI_INTEL is not set ++# CONFIG_CRYPTO_AES_TI is not set ++CONFIG_CRYPTO_ALGAPI=y ++CONFIG_CRYPTO_ALGAPI2=y ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++# CONFIG_CRYPTO_ANUBIS is not set ++# CONFIG_CRYPTO_ARC4 is not set ++# CONFIG_CRYPTO_AUTHENC is not set ++# CONFIG_CRYPTO_BLAKE2B is not set ++# CONFIG_CRYPTO_BLAKE2S is not set ++# CONFIG_CRYPTO_BLOWFISH is not set ++# CONFIG_CRYPTO_CAMELLIA is not set ++# CONFIG_CRYPTO_CAST5 is not set ++# CONFIG_CRYPTO_CAST6 is not set ++# CONFIG_CRYPTO_CBC is not set ++# CONFIG_CRYPTO_CCM is not set ++# CONFIG_CRYPTO_CFB is not set ++# CONFIG_CRYPTO_CHACHA20 is not set ++# CONFIG_CRYPTO_CHACHA20POLY1305 is not set ++# CONFIG_CRYPTO_CHACHA20_NEON is not set ++# CONFIG_CRYPTO_CMAC is not set ++# CONFIG_CRYPTO_CRC32 is not set ++# CONFIG_CRYPTO_CRC32C is not set ++# CONFIG_CRYPTO_CRC32C_INTEL is not set ++# CONFIG_CRYPTO_CRC32_ARM_CE is not set ++# CONFIG_CRYPTO_CRCT10DIF is not set ++# CONFIG_CRYPTO_CRYPTD is not set ++# CONFIG_CRYPTO_CTR is not set ++# CONFIG_CRYPTO_CTS is not set ++# CONFIG_CRYPTO_CURVE25519 is not set ++# CONFIG_CRYPTO_DEFLATE is not set ++# CONFIG_CRYPTO_DES is not set ++# CONFIG_CRYPTO_DEV_AMLOGIC_GXL is not set ++# CONFIG_CRYPTO_DEV_ATMEL_AES is not set ++# CONFIG_CRYPTO_DEV_ATMEL_AUTHENC is not set ++# CONFIG_CRYPTO_DEV_ATMEL_ECC is not set ++# CONFIG_CRYPTO_DEV_ATMEL_SHA is not set ++# CONFIG_CRYPTO_DEV_ATMEL_SHA204A is not set ++# CONFIG_CRYPTO_DEV_ATMEL_TDES is not set ++# CONFIG_CRYPTO_DEV_CAVIUM_ZIP is not set ++# CONFIG_CRYPTO_DEV_CCP is not set ++# CONFIG_CRYPTO_DEV_CCP_DEBUGFS is not set ++# CONFIG_CRYPTO_DEV_CCREE is not set ++# CONFIG_CRYPTO_DEV_FSL_CAAM is not set ++# CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC is not set ++# CONFIG_CRYPTO_DEV_HIFN_795X is not set ++# CONFIG_CRYPTO_DEV_HISI_SEC is not set ++# CONFIG_CRYPTO_DEV_HISI_ZIP is not set ++# CONFIG_CRYPTO_DEV_IMGTEC_HASH is not set ++# CONFIG_CRYPTO_DEV_MARVELL_CESA is not set ++# CONFIG_CRYPTO_DEV_MV_CESA is not set ++# CONFIG_CRYPTO_DEV_MXC_SCC is not set ++# CONFIG_CRYPTO_DEV_MXS_DCP is not set ++# CONFIG_CRYPTO_DEV_NITROX_CNN55XX is not set ++# CONFIG_CRYPTO_DEV_QAT_C3XXX is not set ++# CONFIG_CRYPTO_DEV_QAT_C3XXXVF is not set ++# CONFIG_CRYPTO_DEV_QAT_C62X is not set ++# CONFIG_CRYPTO_DEV_QAT_C62XVF is not set ++# CONFIG_CRYPTO_DEV_QAT_DH895xCC is not set ++# CONFIG_CRYPTO_DEV_QAT_DH895xCCVF is not set ++# CONFIG_CRYPTO_DEV_QCE is not set ++# CONFIG_CRYPTO_DEV_S5P is not set ++# CONFIG_CRYPTO_DEV_SAFEXCEL is not set ++# CONFIG_CRYPTO_DEV_SAHARA is not set ++# CONFIG_CRYPTO_DEV_SP_PSP is not set ++# CONFIG_CRYPTO_DEV_TALITOS is not set ++# CONFIG_CRYPTO_DEV_VIRTIO is not set ++# CONFIG_CRYPTO_DH is not set ++# CONFIG_CRYPTO_DRBG_CTR is not set ++# CONFIG_CRYPTO_DRBG_HASH is not set ++# CONFIG_CRYPTO_DRBG_MENU is not set ++# CONFIG_CRYPTO_ECB is not set ++# CONFIG_CRYPTO_ECDH is not set ++# CONFIG_CRYPTO_ECHAINIV is not set ++# CONFIG_CRYPTO_ECRDSA is not set ++# CONFIG_CRYPTO_ESSIV is not set ++# CONFIG_CRYPTO_FCRYPT is not set ++# CONFIG_CRYPTO_FIPS is not set ++# CONFIG_CRYPTO_GCM is not set ++# CONFIG_CRYPTO_GF128MUL is not set ++# CONFIG_CRYPTO_GHASH is not set ++# CONFIG_CRYPTO_GHASH_ARM_CE is not set ++# CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL is not set ++# CONFIG_CRYPTO_HASH is not set ++# CONFIG_CRYPTO_HMAC is not set ++# CONFIG_CRYPTO_HW is not set ++# CONFIG_CRYPTO_JITTERENTROPY is not set ++# CONFIG_CRYPTO_KEYWRAP is not set ++# CONFIG_CRYPTO_KHAZAD is not set ++CONFIG_CRYPTO_LIB_AES=y ++CONFIG_CRYPTO_LIB_ARC4=y ++# CONFIG_CRYPTO_LIB_BLAKE2S is not set ++# CONFIG_CRYPTO_LIB_CHACHA is not set ++# CONFIG_CRYPTO_LIB_CHACHA20POLY1305 is not set ++# CONFIG_CRYPTO_LIB_CURVE25519 is not set ++# CONFIG_CRYPTO_LIB_POLY1305 is not set ++CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9 ++# CONFIG_CRYPTO_LRW is not set ++# CONFIG_CRYPTO_LZ4 is not set ++# CONFIG_CRYPTO_LZ4HC is not set ++# CONFIG_CRYPTO_LZO is not set ++# CONFIG_CRYPTO_MANAGER is not set ++# CONFIG_CRYPTO_MANAGER2 is not set ++CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y ++# CONFIG_CRYPTO_MCRYPTD is not set ++# CONFIG_CRYPTO_MD4 is not set ++# CONFIG_CRYPTO_MD5 is not set ++# CONFIG_CRYPTO_MICHAEL_MIC is not set ++# CONFIG_CRYPTO_MORUS1280 is not set ++# CONFIG_CRYPTO_MORUS1280_AVX2 is not set ++# CONFIG_CRYPTO_MORUS1280_SSE2 is not set ++# CONFIG_CRYPTO_MORUS640 is not set ++# CONFIG_CRYPTO_MORUS640_SSE2 is not set ++# CONFIG_CRYPTO_NHPOLY1305_NEON is not set ++# CONFIG_CRYPTO_NULL is not set ++# CONFIG_CRYPTO_OFB is not set ++# CONFIG_CRYPTO_PCBC is not set ++# CONFIG_CRYPTO_PCOMP is not set ++# CONFIG_CRYPTO_PCOMP2 is not set ++CONFIG_CRYPTO_PCRYPT=y ++# CONFIG_CRYPTO_POLY1305 is not set ++# CONFIG_CRYPTO_RMD128 is not set ++# CONFIG_CRYPTO_RMD160 is not set ++# CONFIG_CRYPTO_RMD256 is not set ++# CONFIG_CRYPTO_RMD320 is not set ++# CONFIG_CRYPTO_RNG is not set ++# CONFIG_CRYPTO_RSA is not set ++# CONFIG_CRYPTO_SALSA20 is not set ++# CONFIG_CRYPTO_SALSA20_586 is not set ++# CONFIG_CRYPTO_SEED is not set ++# CONFIG_CRYPTO_SEQIV is not set ++# CONFIG_CRYPTO_SERPENT is not set ++# CONFIG_CRYPTO_SHA1 is not set ++# CONFIG_CRYPTO_SHA1_ARM is not set ++# CONFIG_CRYPTO_SHA1_ARM_CE is not set ++# CONFIG_CRYPTO_SHA1_ARM_NEON is not set ++# CONFIG_CRYPTO_SHA256 is not set ++# CONFIG_CRYPTO_SHA256_ARM is not set ++# CONFIG_CRYPTO_SHA2_ARM_CE is not set ++# CONFIG_CRYPTO_SHA3 is not set ++# CONFIG_CRYPTO_SHA512 is not set ++# CONFIG_CRYPTO_SHA512_ARM is not set ++# CONFIG_CRYPTO_SIMD is not set ++CONFIG_CRYPTO_SKCIPHER=y ++CONFIG_CRYPTO_SKCIPHER2=y ++# CONFIG_CRYPTO_SM2 is not set ++# CONFIG_CRYPTO_SM3 is not set ++# CONFIG_CRYPTO_SM4 is not set ++# CONFIG_CRYPTO_SPECK is not set ++# CONFIG_CRYPTO_STATS is not set ++# CONFIG_CRYPTO_STREEBOG is not set ++# CONFIG_CRYPTO_TEA is not set ++# CONFIG_CRYPTO_TEST is not set ++# CONFIG_CRYPTO_TGR192 is not set ++# CONFIG_CRYPTO_TWOFISH is not set ++# CONFIG_CRYPTO_TWOFISH_586 is not set ++# CONFIG_CRYPTO_TWOFISH_COMMON is not set ++# CONFIG_CRYPTO_USER is not set ++# CONFIG_CRYPTO_USER_API_AEAD is not set ++# CONFIG_CRYPTO_USER_API_HASH is not set ++# CONFIG_CRYPTO_USER_API_RNG is not set ++# CONFIG_CRYPTO_USER_API_SKCIPHER is not set ++# CONFIG_CRYPTO_VMAC is not set ++# CONFIG_CRYPTO_WP512 is not set ++# CONFIG_CRYPTO_XCBC is not set ++# CONFIG_CRYPTO_XTS is not set ++# CONFIG_CRYPTO_XXHASH is not set ++# CONFIG_CRYPTO_ZLIB is not set ++# CONFIG_CRYPTO_ZSTD is not set ++# CONFIG_CS5535_MFGPT is not set ++# CONFIG_CS89x0 is not set ++# CONFIG_CSD_LOCK_WAIT_DEBUG is not set ++# CONFIG_CUSE is not set ++# CONFIG_CW1200 is not set ++# CONFIG_CXD2880_SPI_DRV is not set ++# CONFIG_CXL_AFU_DRIVER_OPS is not set ++# CONFIG_CXL_BASE is not set ++# CONFIG_CXL_EEH is not set ++# CONFIG_CXL_KERNEL_API is not set ++# CONFIG_CXL_LIB is not set ++# CONFIG_CYPRESS_FIRMWARE is not set ++# CONFIG_DA280 is not set ++# CONFIG_DA311 is not set ++# CONFIG_DAVICOM_PHY is not set ++# CONFIG_DAX is not set ++# CONFIG_DCB is not set ++# CONFIG_DDR is not set ++# CONFIG_DEBUG_ALIGN_RODATA is not set ++# CONFIG_DEBUG_ATOMIC_SLEEP is not set ++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set ++# CONFIG_DEBUG_BUGVERBOSE is not set ++# CONFIG_DEBUG_CREDENTIALS is not set ++# CONFIG_DEBUG_DEVRES is not set ++# CONFIG_DEBUG_DRIVER is not set ++# CONFIG_DEBUG_EFI is not set ++# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_32B is not set ++# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set ++CONFIG_DEBUG_FS=y ++CONFIG_DEBUG_FS_ALLOW_ALL=y ++# CONFIG_DEBUG_FS_ALLOW_NONE is not set ++# CONFIG_DEBUG_FS_DISALLOW_MOUNT is not set ++# CONFIG_DEBUG_GPIO is not set ++# CONFIG_DEBUG_HIGHMEM is not set ++# CONFIG_DEBUG_ICEDCC is not set ++# CONFIG_DEBUG_INFO is not set ++# CONFIG_DEBUG_INFO_BTF is not set ++# CONFIG_DEBUG_INFO_COMPRESSED is not set ++# CONFIG_DEBUG_INFO_DWARF4 is not set ++CONFIG_DEBUG_INFO_REDUCED=y ++# CONFIG_DEBUG_INFO_SPLIT is not set ++CONFIG_DEBUG_KERNEL=y ++# CONFIG_DEBUG_KMEMLEAK is not set ++# CONFIG_DEBUG_KOBJECT is not set ++# CONFIG_DEBUG_KOBJECT_RELEASE is not set ++# CONFIG_DEBUG_LIST is not set ++# CONFIG_DEBUG_LL is not set ++# CONFIG_DEBUG_LL_UART_8250 is not set ++# CONFIG_DEBUG_LL_UART_PL01X is not set ++# CONFIG_DEBUG_LOCKDEP is not set ++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set ++# CONFIG_DEBUG_LOCK_ALLOC is not set ++# CONFIG_DEBUG_MEMORY_INIT is not set ++# CONFIG_DEBUG_MISC is not set ++# CONFIG_DEBUG_MUTEXES is not set ++# CONFIG_DEBUG_NOTIFIERS is not set ++# CONFIG_DEBUG_NX_TEST is not set ++# CONFIG_DEBUG_OBJECTS is not set ++# CONFIG_DEBUG_PAGEALLOC is not set ++# CONFIG_DEBUG_PAGE_REF is not set ++# CONFIG_DEBUG_PERF_USE_VMALLOC is not set ++# CONFIG_DEBUG_PER_CPU_MAPS is not set ++# CONFIG_DEBUG_PINCTRL is not set ++# CONFIG_DEBUG_PI_LIST is not set ++# CONFIG_DEBUG_PLIST is not set ++# CONFIG_DEBUG_PREEMPT is not set ++# CONFIG_DEBUG_RODATA_TEST is not set ++# CONFIG_DEBUG_RSEQ is not set ++# CONFIG_DEBUG_RT_MUTEXES is not set ++# CONFIG_DEBUG_RWSEMS is not set ++# CONFIG_DEBUG_SECTION_MISMATCH is not set ++# CONFIG_DEBUG_SEMIHOSTING is not set ++# CONFIG_DEBUG_SG is not set ++# CONFIG_DEBUG_SHIRQ is not set ++# CONFIG_DEBUG_SLAB is not set ++# CONFIG_DEBUG_SPINLOCK is not set ++# CONFIG_DEBUG_STACKOVERFLOW is not set ++# CONFIG_DEBUG_STACK_USAGE is not set ++# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set ++# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set ++# CONFIG_DEBUG_TIMEKEEPING is not set ++# CONFIG_DEBUG_UART_8250_PALMCHIP is not set ++# CONFIG_DEBUG_UART_BCM63XX is not set ++# CONFIG_DEBUG_USER is not set ++# CONFIG_DEBUG_VIRTUAL is not set ++# CONFIG_DEBUG_VM is not set ++# CONFIG_DEBUG_VM_PGTABLE is not set ++# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set ++# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set ++# CONFIG_DEBUG_WX is not set ++# CONFIG_DEBUG_ZBOOT is not set ++# CONFIG_DECNET is not set ++CONFIG_DEFAULT_CUBIC=y ++CONFIG_DEFAULT_DEADLINE=y ++CONFIG_DEFAULT_HOSTNAME="(none)" ++CONFIG_DEFAULT_INIT="" ++CONFIG_DEFAULT_IOSCHED="deadline" ++CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 ++# CONFIG_DEFAULT_NOOP is not set ++# CONFIG_DEFAULT_RENO is not set ++CONFIG_DEFAULT_SECURITY="" ++CONFIG_DEFAULT_SECURITY_DAC=y ++# CONFIG_DEFAULT_SECURITY_SELINUX is not set ++CONFIG_DEFAULT_TCP_CONG="cubic" ++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" ++# CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set ++# CONFIG_DELL_LAPTOP is not set ++# CONFIG_DELL_RBTN is not set ++# CONFIG_DELL_SMBIOS is not set ++# CONFIG_DELL_SMO8800 is not set ++# CONFIG_DEPRECATED_PARAM_STRUCT is not set ++# CONFIG_DETECT_HUNG_TASK is not set ++# CONFIG_DEVKMEM is not set ++# CONFIG_DEVMEM is not set ++CONFIG_DEVPORT=y ++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set ++# CONFIG_DEVTMPFS is not set ++# CONFIG_DEVTMPFS_MOUNT is not set ++# CONFIG_DEV_DAX is not set ++# CONFIG_DGAP is not set ++# CONFIG_DGNC is not set ++# CONFIG_DHT11 is not set ++# CONFIG_DISCONTIGMEM_MANUAL is not set ++# CONFIG_DISPLAY_CONNECTOR_ANALOG_TV is not set ++# CONFIG_DISPLAY_CONNECTOR_DVI is not set ++# CONFIG_DISPLAY_CONNECTOR_HDMI is not set ++# CONFIG_DISPLAY_ENCODER_TFP410 is not set ++# CONFIG_DISPLAY_ENCODER_TPD12S015 is not set ++# CONFIG_DISPLAY_PANEL_DPI is not set ++# CONFIG_DISPLAY_PANEL_LGPHILIPS_LB035Q02 is not set ++# CONFIG_DISPLAY_PANEL_TPO_TD028TTEC1 is not set ++# CONFIG_DISPLAY_PANEL_TPO_TD043MTEA1 is not set ++# CONFIG_DL2K is not set ++# CONFIG_DLHL60D is not set ++# CONFIG_DLM is not set ++# CONFIG_DM9000 is not set ++# CONFIG_DMABUF_HEAPS is not set ++# CONFIG_DMABUF_MOVE_NOTIFY is not set ++# CONFIG_DMABUF_SELFTESTS is not set ++# CONFIG_DMADEVICES is not set ++# CONFIG_DMADEVICES_DEBUG is not set ++# CONFIG_DMARD06 is not set ++# CONFIG_DMARD09 is not set ++# CONFIG_DMARD10 is not set ++# CONFIG_DMASCC is not set ++# CONFIG_DMATEST is not set ++# CONFIG_DMA_API_DEBUG is not set ++CONFIG_DMA_COHERENT_POOL=y ++CONFIG_DMA_DECLARE_COHERENT=y ++# CONFIG_DMA_ENGINE is not set ++# CONFIG_DMA_FENCE_TRACE is not set ++# CONFIG_DMA_JZ4780 is not set ++CONFIG_DMA_NONCOHERENT_MMAP=y ++# CONFIG_DMA_NOOP_OPS is not set ++# CONFIG_DMA_SHARED_BUFFER is not set ++# CONFIG_DMA_VIRT_OPS is not set ++# CONFIG_DM_CACHE is not set ++# CONFIG_DM_CLONE is not set ++# CONFIG_DM_DEBUG is not set ++# CONFIG_DM_DELAY is not set ++# CONFIG_DM_DUST is not set ++# CONFIG_DM_EBS is not set ++# CONFIG_DM_ERA is not set ++# CONFIG_DM_FLAKEY is not set ++# CONFIG_DM_INTEGRITY is not set ++# CONFIG_DM_LOG_USERSPACE is not set ++# CONFIG_DM_LOG_WRITES is not set ++# CONFIG_DM_MQ_DEFAULT is not set ++# CONFIG_DM_MULTIPATH is not set ++# CONFIG_DM_RAID is not set ++# CONFIG_DM_SWITCH is not set ++# CONFIG_DM_THIN_PROVISIONING is not set ++# CONFIG_DM_UEVENT is not set ++# CONFIG_DM_UNSTRIPED is not set ++# CONFIG_DM_VERITY is not set ++# CONFIG_DM_WRITECACHE is not set ++# CONFIG_DM_ZERO is not set ++# CONFIG_DNET is not set ++# CONFIG_DNOTIFY is not set ++# CONFIG_DNS_RESOLVER is not set ++CONFIG_DOUBLEFAULT=y ++# CONFIG_DP83822_PHY is not set ++# CONFIG_DP83848_PHY is not set ++# CONFIG_DP83867_PHY is not set ++# CONFIG_DP83869_PHY is not set ++# CONFIG_DP83TC811_PHY is not set ++# CONFIG_DPOT_DAC is not set ++# CONFIG_DPS310 is not set ++CONFIG_DQL=y ++# CONFIG_DRAGONRISE_FF is not set ++# CONFIG_DRM is not set ++# CONFIG_DRM_AMDGPU is not set ++# CONFIG_DRM_AMDGPU_CIK is not set ++# CONFIG_DRM_AMDGPU_GART_DEBUGFS is not set ++# CONFIG_DRM_AMDGPU_SI is not set ++# CONFIG_DRM_AMDGPU_USERPTR is not set ++# CONFIG_DRM_AMD_ACP is not set ++# CONFIG_DRM_AMD_DC_DCN2_0 is not set ++# CONFIG_DRM_ANALOGIX_ANX78XX is not set ++# CONFIG_DRM_ARCPGU is not set ++# CONFIG_DRM_ARMADA is not set ++# CONFIG_DRM_AST is not set ++# CONFIG_DRM_BOCHS is not set ++# CONFIG_DRM_CDNS_DSI is not set ++# CONFIG_DRM_CIRRUS_QEMU is not set ++# CONFIG_DRM_DEBUG_MM is not set ++# CONFIG_DRM_DEBUG_SELFTEST is not set ++# CONFIG_DRM_DP_AUX_CHARDEV is not set ++# CONFIG_DRM_DP_CEC is not set ++# CONFIG_DRM_DUMB_VGA_DAC is not set ++# CONFIG_DRM_DW_HDMI_CEC is not set ++# CONFIG_DRM_ETNAVIV is not set ++# CONFIG_DRM_EXYNOS is not set ++# CONFIG_DRM_FBDEV_EMULATION is not set ++# CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set ++# CONFIG_DRM_FSL_DCU is not set ++# CONFIG_DRM_GM12U320 is not set ++# CONFIG_DRM_GMA500 is not set ++# CONFIG_DRM_HDLCD is not set ++# CONFIG_DRM_HISI_HIBMC is not set ++# CONFIG_DRM_HISI_KIRIN is not set ++# CONFIG_DRM_I2C_ADV7511 is not set ++# CONFIG_DRM_I2C_CH7006 is not set ++# CONFIG_DRM_I2C_NXP_TDA9950 is not set ++# CONFIG_DRM_I2C_NXP_TDA998X is not set ++# CONFIG_DRM_I2C_SIL164 is not set ++# CONFIG_DRM_I915 is not set ++# CONFIG_DRM_KOMEDA is not set ++# CONFIG_DRM_LEGACY is not set ++# CONFIG_DRM_LIB_RANDOM is not set ++# CONFIG_DRM_LIMA is not set ++# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set ++# CONFIG_DRM_LVDS_ENCODER is not set ++# CONFIG_DRM_MALI_DISPLAY is not set ++# CONFIG_DRM_MCDE is not set ++# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set ++# CONFIG_DRM_MGAG200 is not set ++# CONFIG_DRM_MXSFB is not set ++# CONFIG_DRM_NOUVEAU is not set ++# CONFIG_DRM_NXP_PTN3460 is not set ++# CONFIG_DRM_OMAP is not set ++# CONFIG_DRM_PANEL_ARM_VERSATILE is not set ++# CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D is not set ++# CONFIG_DRM_PANEL_ILITEK_IL9322 is not set ++# CONFIG_DRM_PANEL_ILITEK_ILI9881C is not set ++# CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set ++# CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set ++# CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04 is not set ++# CONFIG_DRM_PANEL_LG_LB035Q02 is not set ++# CONFIG_DRM_PANEL_LG_LG4573 is not set ++# CONFIG_DRM_PANEL_LVDS is not set ++# CONFIG_DRM_PANEL_NEC_NL8048HL11 is not set ++# CONFIG_DRM_PANEL_NOVATEK_NT39016 is not set ++# CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO is not set ++# CONFIG_DRM_PANEL_ORISETECH_OTM8009A is not set ++# CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS is not set ++# CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set ++# CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set ++# CONFIG_DRM_PANEL_RAYDIUM_RM67191 is not set ++# CONFIG_DRM_PANEL_RAYDIUM_RM68200 is not set ++# CONFIG_DRM_PANEL_ROCKTECH_JH057N00900 is not set ++# CONFIG_DRM_PANEL_RONBO_RB070D30 is not set ++# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set ++# CONFIG_DRM_PANEL_SAMSUNG_S6D16D0 is not set ++# CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set ++# CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03 is not set ++# CONFIG_DRM_PANEL_SAMSUNG_S6E63M0 is not set ++# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set ++# CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set ++# CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set ++# CONFIG_DRM_PANEL_SHARP_LS037V7DW01 is not set ++# CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set ++# CONFIG_DRM_PANEL_SITRONIX_ST7701 is not set ++# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set ++# CONFIG_DRM_PANEL_SONY_ACX565AKM is not set ++# CONFIG_DRM_PANEL_TPO_TD028TTEC1 is not set ++# CONFIG_DRM_PANEL_TPO_TD043MTEA1 is not set ++# CONFIG_DRM_PANEL_TPO_TPG110 is not set ++# CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA is not set ++# CONFIG_DRM_PANFROST is not set ++# CONFIG_DRM_PARADE_PS8622 is not set ++# CONFIG_DRM_PL111 is not set ++# CONFIG_DRM_QXL is not set ++# CONFIG_DRM_RADEON is not set ++# CONFIG_DRM_RADEON_USERPTR is not set ++# CONFIG_DRM_RCAR_DW_HDMI is not set ++# CONFIG_DRM_RCAR_LVDS is not set ++# CONFIG_DRM_SII902X is not set ++# CONFIG_DRM_SII9234 is not set ++# CONFIG_DRM_SIL_SII8620 is not set ++# CONFIG_DRM_STI is not set ++# CONFIG_DRM_STM is not set ++# CONFIG_DRM_SUN4I is not set ++# CONFIG_DRM_THINE_THC63LVD1024 is not set ++# CONFIG_DRM_TILCDC is not set ++# CONFIG_DRM_TINYDRM is not set ++# CONFIG_DRM_TI_SN65DSI86 is not set ++# CONFIG_DRM_TI_TFP410 is not set ++# CONFIG_DRM_TOSHIBA_TC358764 is not set ++# CONFIG_DRM_TOSHIBA_TC358767 is not set ++# CONFIG_DRM_UDL is not set ++# CONFIG_DRM_VBOXVIDEO is not set ++# CONFIG_DRM_VC4_HDMI_CEC is not set ++# CONFIG_DRM_VGEM is not set ++# CONFIG_DRM_VIRTIO_GPU is not set ++# CONFIG_DRM_VKMS is not set ++# CONFIG_DRM_VMWGFX is not set ++# CONFIG_DRM_XEN is not set ++# CONFIG_DS1682 is not set ++# CONFIG_DS1803 is not set ++# CONFIG_DS4424 is not set ++# CONFIG_DST_CACHE is not set ++# CONFIG_DTLK is not set ++# CONFIG_DUMMY is not set ++CONFIG_DUMMY_CONSOLE_COLUMNS=80 ++CONFIG_DUMMY_CONSOLE_ROWS=25 ++# CONFIG_DUMMY_IRQ is not set ++# CONFIG_DVB_A8293 is not set ++# CONFIG_DVB_AF9013 is not set ++# CONFIG_DVB_AF9033 is not set ++# CONFIG_DVB_AS102 is not set ++# CONFIG_DVB_ASCOT2E is not set ++# CONFIG_DVB_ATBM8830 is not set ++# CONFIG_DVB_AU8522_DTV is not set ++# CONFIG_DVB_AU8522_V4L is not set ++# CONFIG_DVB_B2C2_FLEXCOP_USB is not set ++# CONFIG_DVB_BCM3510 is not set ++# CONFIG_DVB_CORE is not set ++# CONFIG_DVB_CX22700 is not set ++# CONFIG_DVB_CX22702 is not set ++# CONFIG_DVB_CX24110 is not set ++# CONFIG_DVB_CX24116 is not set ++# CONFIG_DVB_CX24117 is not set ++# CONFIG_DVB_CX24120 is not set ++# CONFIG_DVB_CX24123 is not set ++# CONFIG_DVB_CXD2099 is not set ++# CONFIG_DVB_CXD2820R is not set ++# CONFIG_DVB_CXD2841ER is not set ++# CONFIG_DVB_CXD2880 is not set ++# CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set ++# CONFIG_DVB_DIB3000MB is not set ++# CONFIG_DVB_DIB3000MC is not set ++# CONFIG_DVB_DIB7000M is not set ++# CONFIG_DVB_DIB7000P is not set ++# CONFIG_DVB_DIB8000 is not set ++# CONFIG_DVB_DIB9000 is not set ++# CONFIG_DVB_DRX39XYJ is not set ++# CONFIG_DVB_DRXD is not set ++# CONFIG_DVB_DRXK is not set ++# CONFIG_DVB_DS3000 is not set ++# CONFIG_DVB_DUMMY_FE is not set ++# CONFIG_DVB_DYNAMIC_MINORS is not set ++# CONFIG_DVB_EC100 is not set ++# CONFIG_DVB_FIREDTV is not set ++# CONFIG_DVB_HELENE is not set ++# CONFIG_DVB_HORUS3A is not set ++# CONFIG_DVB_ISL6405 is not set ++# CONFIG_DVB_ISL6421 is not set ++# CONFIG_DVB_ISL6423 is not set ++# CONFIG_DVB_IX2505V is not set ++# CONFIG_DVB_L64781 is not set ++# CONFIG_DVB_LG2160 is not set ++# CONFIG_DVB_LGDT3305 is not set ++# CONFIG_DVB_LGDT3306A is not set ++# CONFIG_DVB_LGDT330X is not set ++# CONFIG_DVB_LGS8GL5 is not set ++# CONFIG_DVB_LGS8GXX is not set ++# CONFIG_DVB_LNBH25 is not set ++# CONFIG_DVB_LNBH29 is not set ++# CONFIG_DVB_LNBP21 is not set ++# CONFIG_DVB_LNBP22 is not set ++# CONFIG_DVB_M88DS3103 is not set ++# CONFIG_DVB_M88RS2000 is not set ++CONFIG_DVB_MAX_ADAPTERS=16 ++# CONFIG_DVB_MB86A16 is not set ++# CONFIG_DVB_MB86A20S is not set ++# CONFIG_DVB_MMAP is not set ++# CONFIG_DVB_MN88443X is not set ++# CONFIG_DVB_MN88472 is not set ++# CONFIG_DVB_MN88473 is not set ++# CONFIG_DVB_MT312 is not set ++# CONFIG_DVB_MT352 is not set ++# CONFIG_DVB_MXL5XX is not set ++# CONFIG_DVB_NET is not set ++# CONFIG_DVB_NXT200X is not set ++# CONFIG_DVB_NXT6000 is not set ++# CONFIG_DVB_OR51132 is not set ++# CONFIG_DVB_OR51211 is not set ++# CONFIG_DVB_PLATFORM_DRIVERS is not set ++# CONFIG_DVB_PLL is not set ++# CONFIG_DVB_RTL2830 is not set ++# CONFIG_DVB_RTL2832 is not set ++# CONFIG_DVB_RTL2832_SDR is not set ++# CONFIG_DVB_S5H1409 is not set ++# CONFIG_DVB_S5H1411 is not set ++# CONFIG_DVB_S5H1420 is not set ++# CONFIG_DVB_S5H1432 is not set ++# CONFIG_DVB_S921 is not set ++# CONFIG_DVB_SI2165 is not set ++# CONFIG_DVB_SI2168 is not set ++# CONFIG_DVB_SI21XX is not set ++# CONFIG_DVB_SP2 is not set ++# CONFIG_DVB_SP8870 is not set ++# CONFIG_DVB_SP887X is not set ++# CONFIG_DVB_STB0899 is not set ++# CONFIG_DVB_STB6000 is not set ++# CONFIG_DVB_STB6100 is not set ++# CONFIG_DVB_STV0288 is not set ++# CONFIG_DVB_STV0297 is not set ++# CONFIG_DVB_STV0299 is not set ++# CONFIG_DVB_STV0367 is not set ++# CONFIG_DVB_STV0900 is not set ++# CONFIG_DVB_STV090x is not set ++# CONFIG_DVB_STV0910 is not set ++# CONFIG_DVB_STV6110 is not set ++# CONFIG_DVB_STV6110x is not set ++# CONFIG_DVB_STV6111 is not set ++# CONFIG_DVB_TC90522 is not set ++# CONFIG_DVB_TDA10021 is not set ++# CONFIG_DVB_TDA10023 is not set ++# CONFIG_DVB_TDA10048 is not set ++# CONFIG_DVB_TDA1004X is not set ++# CONFIG_DVB_TDA10071 is not set ++# CONFIG_DVB_TDA10086 is not set ++# CONFIG_DVB_TDA18271C2DD is not set ++# CONFIG_DVB_TDA665x is not set ++# CONFIG_DVB_TDA8083 is not set ++# CONFIG_DVB_TDA8261 is not set ++# CONFIG_DVB_TDA826X is not set ++# CONFIG_DVB_TS2020 is not set ++# CONFIG_DVB_TTUSB_BUDGET is not set ++# CONFIG_DVB_TTUSB_DEC is not set ++# CONFIG_DVB_TUA6100 is not set ++# CONFIG_DVB_TUNER_CX24113 is not set ++# CONFIG_DVB_TUNER_DIB0070 is not set ++# CONFIG_DVB_TUNER_DIB0090 is not set ++# CONFIG_DVB_TUNER_ITD1000 is not set ++# CONFIG_DVB_ULE_DEBUG is not set ++# CONFIG_DVB_USB_V2 is not set ++# CONFIG_DVB_VES1820 is not set ++# CONFIG_DVB_VES1X93 is not set ++# CONFIG_DVB_ZD1301_DEMOD is not set ++# CONFIG_DVB_ZL10036 is not set ++# CONFIG_DVB_ZL10039 is not set ++# CONFIG_DVB_ZL10353 is not set ++# CONFIG_DWC_XLGMAC is not set ++# CONFIG_DWMAC_DWC_QOS_ETH is not set ++# CONFIG_DWMAC_IPQ806X is not set ++# CONFIG_DWMAC_LPC18XX is not set ++# CONFIG_DWMAC_MESON is not set ++# CONFIG_DWMAC_ROCKCHIP is not set ++# CONFIG_DWMAC_SOCFPGA is not set ++# CONFIG_DWMAC_STI is not set ++# CONFIG_DW_AXI_DMAC is not set ++# CONFIG_DW_DMAC is not set ++# CONFIG_DW_DMAC_PCI is not set ++# CONFIG_DW_EDMA is not set ++# CONFIG_DW_EDMA_PCIE is not set ++# CONFIG_DW_WATCHDOG is not set ++# CONFIG_DYNAMIC_DEBUG is not set ++CONFIG_DYNAMIC_DEBUG_CORE=y ++# CONFIG_E100 is not set ++# CONFIG_E1000 is not set ++# CONFIG_E1000E is not set ++# CONFIG_E1000E_HWTS is not set ++# CONFIG_EARLY_PRINTK_8250 is not set ++# CONFIG_EARLY_PRINTK_USB_XDBC is not set ++# CONFIG_EBC_C384_WDT is not set ++# CONFIG_ECHO is not set ++# CONFIG_ECRYPT_FS is not set ++# CONFIG_EDAC is not set ++# CONFIG_EEEPC_LAPTOP is not set ++# CONFIG_EEPROM_93CX6 is not set ++# CONFIG_EEPROM_93XX46 is not set ++# CONFIG_EEPROM_AT24 is not set ++# CONFIG_EEPROM_AT25 is not set ++# CONFIG_EEPROM_DIGSY_MTC_CFG is not set ++# CONFIG_EEPROM_EE1004 is not set ++# CONFIG_EEPROM_IDT_89HPESX is not set ++# CONFIG_EEPROM_LEGACY is not set ++# CONFIG_EEPROM_MAX6875 is not set ++# CONFIG_EFI is not set ++CONFIG_EFI_PARTITION=y ++# CONFIG_EFS_FS is not set ++CONFIG_ELFCORE=y ++# CONFIG_ELF_CORE is not set ++# CONFIG_EMAC_ROCKCHIP is not set ++CONFIG_EMBEDDED=y ++# CONFIG_EM_TIMER_STI is not set ++# CONFIG_ENABLE_MUST_CHECK is not set ++CONFIG_ENABLE_WARN_DEPRECATED=y ++# CONFIG_ENA_ETHERNET is not set ++# CONFIG_ENC28J60 is not set ++# CONFIG_ENCLOSURE_SERVICES is not set ++# CONFIG_ENCRYPTED_KEYS is not set ++# CONFIG_ENCX24J600 is not set ++# CONFIG_ENERGY_MODEL is not set ++# CONFIG_ENIC is not set ++# CONFIG_ENVELOPE_DETECTOR is not set ++# CONFIG_EPAPR_PARAVIRT is not set ++# CONFIG_EPIC100 is not set ++CONFIG_EPOLL=y ++# CONFIG_EQUALIZER is not set ++# CONFIG_EROFS_FS is not set ++# CONFIG_ET131X is not set ++CONFIG_ETHERNET=y ++# CONFIG_ETHOC is not set ++# CONFIG_ETHTOOL_NETLINK is not set ++CONFIG_EVENTFD=y ++# CONFIG_EVM is not set ++# CONFIG_EXFAT_FS is not set ++CONFIG_EXPERT=y ++CONFIG_EXPORTFS=y ++# CONFIG_EXPORTFS_BLOCK_OPS is not set ++# CONFIG_EXT2_FS is not set ++CONFIG_EXT2_FS_XATTR=y ++# CONFIG_EXT3_FS is not set ++# CONFIG_EXT4_DEBUG is not set ++# CONFIG_EXT4_ENCRYPTION is not set ++# CONFIG_EXT4_FS is not set ++# CONFIG_EXT4_FS_POSIX_ACL is not set ++# CONFIG_EXT4_FS_SECURITY is not set ++CONFIG_EXT4_USE_FOR_EXT2=y ++# CONFIG_EXTCON is not set ++# CONFIG_EXTCON_ADC_JACK is not set ++# CONFIG_EXTCON_ARIZONA is not set ++# CONFIG_EXTCON_AXP288 is not set ++# CONFIG_EXTCON_FSA9480 is not set ++# CONFIG_EXTCON_GPIO is not set ++# CONFIG_EXTCON_INTEL_INT3496 is not set ++# CONFIG_EXTCON_MAX3355 is not set ++# CONFIG_EXTCON_PTN5150 is not set ++# CONFIG_EXTCON_QCOM_SPMI_MISC is not set ++# CONFIG_EXTCON_RT8973A is not set ++# CONFIG_EXTCON_SM5502 is not set ++# CONFIG_EXTCON_USB_GPIO is not set ++CONFIG_EXTRA_FIRMWARE="" ++CONFIG_EXTRA_TARGETS="" ++# CONFIG_EXYNOS_ADC is not set ++# CONFIG_EXYNOS_VIDEO is not set ++# CONFIG_EZCHIP_NPS_MANAGEMENT_ENET is not set ++# CONFIG_EZX_PCAP is not set ++# CONFIG_F2FS_CHECK_FS is not set ++# CONFIG_F2FS_FAULT_INJECTION is not set ++# CONFIG_F2FS_FS is not set ++# CONFIG_F2FS_FS_COMPRESSION is not set ++# CONFIG_F2FS_FS_ENCRYPTION is not set ++# CONFIG_F2FS_FS_POSIX_ACL is not set ++# CONFIG_F2FS_FS_SECURITY is not set ++CONFIG_F2FS_FS_XATTR=y ++# CONFIG_F2FS_IO_TRACE is not set ++CONFIG_F2FS_STAT_FS=y ++# CONFIG_FAILOVER is not set ++# CONFIG_FAIR_GROUP_SCHED is not set ++# CONFIG_FANOTIFY is not set ++# CONFIG_FANOTIFY_ACCESS_PERMISSIONS is not set ++CONFIG_FAT_DEFAULT_CODEPAGE=437 ++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" ++# CONFIG_FAT_DEFAULT_UTF8 is not set ++# CONFIG_FAT_FS is not set ++# CONFIG_FAULT_INJECTION is not set ++# CONFIG_FB is not set ++# CONFIG_FB_3DFX is not set ++# CONFIG_FB_ARC is not set ++# CONFIG_FB_ARK is not set ++# CONFIG_FB_ARMCLCD is not set ++# CONFIG_FB_ASILIANT is not set ++# CONFIG_FB_ATY is not set ++# CONFIG_FB_ATY128 is not set ++# CONFIG_FB_AUO_K190X is not set ++# CONFIG_FB_BACKLIGHT is not set ++# CONFIG_FB_BIG_ENDIAN is not set ++# CONFIG_FB_BOOT_VESA_SUPPORT is not set ++# CONFIG_FB_BOTH_ENDIAN is not set ++# CONFIG_FB_BROADSHEET is not set ++# CONFIG_FB_CARMINE is not set ++# CONFIG_FB_CFB_COPYAREA is not set ++# CONFIG_FB_CFB_FILLRECT is not set ++# CONFIG_FB_CFB_IMAGEBLIT is not set ++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set ++# CONFIG_FB_CIRRUS is not set ++# CONFIG_FB_CYBER2000 is not set ++# CONFIG_FB_DA8XX is not set ++# CONFIG_FB_DDC is not set ++# CONFIG_FB_FLEX is not set ++# CONFIG_FB_FOREIGN_ENDIAN is not set ++# CONFIG_FB_GEODE is not set ++# CONFIG_FB_GOLDFISH is not set ++# CONFIG_FB_HGA is not set ++# CONFIG_FB_I740 is not set ++# CONFIG_FB_IBM_GXT4500 is not set ++# CONFIG_FB_IMSTT is not set ++# CONFIG_FB_IMX is not set ++# CONFIG_FB_KYRO is not set ++# CONFIG_FB_LE80578 is not set ++# CONFIG_FB_LITTLE_ENDIAN is not set ++# CONFIG_FB_MACMODES is not set ++# CONFIG_FB_MATROX is not set ++# CONFIG_FB_MB862XX is not set ++# CONFIG_FB_METRONOME is not set ++# CONFIG_FB_MODE_HELPERS is not set ++# CONFIG_FB_MXS is not set ++# CONFIG_FB_N411 is not set ++# CONFIG_FB_NEOMAGIC is not set ++CONFIG_FB_NOTIFY=y ++# CONFIG_FB_NVIDIA is not set ++# CONFIG_FB_OF is not set ++# CONFIG_FB_OMAP2 is not set ++# CONFIG_FB_OPENCORES is not set ++# CONFIG_FB_PM2 is not set ++# CONFIG_FB_PM3 is not set ++# CONFIG_FB_PS3 is not set ++# CONFIG_FB_PXA is not set ++# CONFIG_FB_RADEON is not set ++# CONFIG_FB_RIVA is not set ++# CONFIG_FB_S1D13XXX is not set ++# CONFIG_FB_S3 is not set ++# CONFIG_FB_SAVAGE is not set ++# CONFIG_FB_SIMPLE is not set ++# CONFIG_FB_SIS is not set ++# CONFIG_FB_SM712 is not set ++# CONFIG_FB_SM750 is not set ++# CONFIG_FB_SMSCUFX is not set ++# CONFIG_FB_SSD1307 is not set ++# CONFIG_FB_SVGALIB is not set ++# CONFIG_FB_SYS_COPYAREA is not set ++# CONFIG_FB_SYS_FILLRECT is not set ++# CONFIG_FB_SYS_FOPS is not set ++# CONFIG_FB_SYS_IMAGEBLIT is not set ++# CONFIG_FB_TFT is not set ++# CONFIG_FB_TFT_AGM1264K_FL is not set ++# CONFIG_FB_TFT_BD663474 is not set ++# CONFIG_FB_TFT_FBTFT_DEVICE is not set ++# CONFIG_FB_TFT_HX8340BN is not set ++# CONFIG_FB_TFT_HX8347D is not set ++# CONFIG_FB_TFT_HX8353D is not set ++# CONFIG_FB_TFT_HX8357D is not set ++# CONFIG_FB_TFT_ILI9163 is not set ++# CONFIG_FB_TFT_ILI9320 is not set ++# CONFIG_FB_TFT_ILI9325 is not set ++# CONFIG_FB_TFT_ILI9340 is not set ++# CONFIG_FB_TFT_ILI9341 is not set ++# CONFIG_FB_TFT_ILI9481 is not set ++# CONFIG_FB_TFT_ILI9486 is not set ++# CONFIG_FB_TFT_PCD8544 is not set ++# CONFIG_FB_TFT_RA8875 is not set ++# CONFIG_FB_TFT_S6D02A1 is not set ++# CONFIG_FB_TFT_S6D1121 is not set ++# CONFIG_FB_TFT_SH1106 is not set ++# CONFIG_FB_TFT_SSD1289 is not set ++# CONFIG_FB_TFT_SSD1305 is not set ++# CONFIG_FB_TFT_SSD1306 is not set ++# CONFIG_FB_TFT_SSD1325 is not set ++# CONFIG_FB_TFT_SSD1331 is not set ++# CONFIG_FB_TFT_SSD1351 is not set ++# CONFIG_FB_TFT_ST7735R is not set ++# CONFIG_FB_TFT_ST7789V is not set ++# CONFIG_FB_TFT_TINYLCD is not set ++# CONFIG_FB_TFT_TLS8204 is not set ++# CONFIG_FB_TFT_UC1611 is not set ++# CONFIG_FB_TFT_UC1701 is not set ++# CONFIG_FB_TFT_UPD161704 is not set ++# CONFIG_FB_TFT_WATTEROTT is not set ++# CONFIG_FB_TILEBLITTING is not set ++# CONFIG_FB_TMIO is not set ++# CONFIG_FB_TRIDENT is not set ++# CONFIG_FB_UDL is not set ++# CONFIG_FB_UVESA is not set ++# CONFIG_FB_VGA16 is not set ++# CONFIG_FB_VIA is not set ++# CONFIG_FB_VIRTUAL is not set ++# CONFIG_FB_VOODOO1 is not set ++# CONFIG_FB_VT8623 is not set ++# CONFIG_FB_XGI is not set ++# CONFIG_FCOE is not set ++# CONFIG_FCOE_FNIC is not set ++# CONFIG_FDDI is not set ++# CONFIG_FEALNX is not set ++# CONFIG_FENCE_TRACE is not set ++# CONFIG_FHANDLE is not set ++CONFIG_FIB_RULES=y ++# CONFIG_FIELDBUS_DEV is not set ++CONFIG_FILE_LOCKING=y ++# CONFIG_FIND_BIT_BENCHMARK is not set ++# CONFIG_FIREWIRE is not set ++# CONFIG_FIREWIRE_NOSY is not set ++# CONFIG_FIREWIRE_SERIAL is not set ++# CONFIG_FIRMWARE_EDID is not set ++# CONFIG_FIRMWARE_IN_KERNEL is not set ++# CONFIG_FIRMWARE_MEMMAP is not set ++# CONFIG_FIXED_PHY is not set ++CONFIG_FLATMEM=y ++CONFIG_FLATMEM_MANUAL=y ++CONFIG_FLAT_NODE_MEM_MAP=y ++# CONFIG_FM10K is not set ++# CONFIG_FMC is not set ++# CONFIG_FONTS is not set ++# CONFIG_FONT_TER16x32 is not set ++# CONFIG_FORCEDETH is not set ++CONFIG_FORCE_MAX_ZONEORDER=11 ++CONFIG_FORTIFY_SOURCE=y ++# CONFIG_FPGA is not set ++# CONFIG_FRAMEBUFFER_CONSOLE is not set ++# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set ++# CONFIG_FRAME_POINTER is not set ++CONFIG_FRAME_WARN=1024 ++# CONFIG_FREEZER is not set ++# CONFIG_FRONTSWAP is not set ++# CONFIG_FSCACHE is not set ++# CONFIG_FSI is not set ++# CONFIG_FSL_EDMA is not set ++# CONFIG_FSL_ERRATUM_A008585 is not set ++# CONFIG_FSL_MC_BUS is not set ++# CONFIG_FSL_PQ_MDIO is not set ++# CONFIG_FSL_QDMA is not set ++# CONFIG_FSL_XGMAC_MDIO is not set ++CONFIG_FSNOTIFY=y ++# CONFIG_FS_DAX is not set ++# CONFIG_FS_ENCRYPTION is not set ++# CONFIG_FS_POSIX_ACL is not set ++# CONFIG_FS_VERITY is not set ++# CONFIG_FTGMAC100 is not set ++# CONFIG_FTL is not set ++# CONFIG_FTMAC100 is not set ++# CONFIG_FTRACE is not set ++# CONFIG_FTRACE_STARTUP_TEST is not set ++# CONFIG_FTR_FIXUP_SELFTEST is not set ++# CONFIG_FTWDT010_WATCHDOG is not set ++# CONFIG_FUJITSU_ES is not set ++# CONFIG_FUJITSU_LAPTOP is not set ++# CONFIG_FUJITSU_TABLET is not set ++# CONFIG_FUNCTION_TRACER is not set ++# CONFIG_FUSE_FS is not set ++# CONFIG_FUSION is not set ++# CONFIG_FUSION_FC is not set ++# CONFIG_FUSION_SAS is not set ++# CONFIG_FUSION_SPI is not set ++CONFIG_FUTEX=y ++CONFIG_FUTEX_PI=y ++# CONFIG_FW_CFG_SYSFS is not set ++CONFIG_FW_LOADER=y ++# CONFIG_FW_LOADER_COMPRESS is not set ++CONFIG_FW_LOADER_USER_HELPER=y ++CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y ++# CONFIG_FXAS21002C is not set ++# CONFIG_FXOS8700_I2C is not set ++# CONFIG_FXOS8700_SPI is not set ++CONFIG_GACT_PROB=y ++# CONFIG_GADGET_UAC1 is not set ++# CONFIG_GAMEPORT is not set ++# CONFIG_GATEWORKS_GW16083 is not set ++# CONFIG_GCC_PLUGINS is not set ++# CONFIG_GCOV is not set ++# CONFIG_GCOV_KERNEL is not set ++# CONFIG_GDB_SCRIPTS is not set ++# CONFIG_GEMINI_ETHERNET is not set ++# CONFIG_GENERIC_ADC_BATTERY is not set ++# CONFIG_GENERIC_ADC_THERMAL is not set ++CONFIG_GENERIC_CALIBRATE_DELAY=y ++# CONFIG_GENERIC_CPU_DEVICES is not set ++CONFIG_GENERIC_HWEIGHT=y ++# CONFIG_GENERIC_IRQ_DEBUGFS is not set ++CONFIG_GENERIC_IRQ_IPI=y ++CONFIG_GENERIC_IRQ_PROBE=y ++CONFIG_GENERIC_NET_UTILS=y ++# CONFIG_GENERIC_PHY is not set ++CONFIG_GENERIC_PTDUMP=y ++CONFIG_GENERIC_VDSO_TIME_NS=y ++# CONFIG_GENEVE is not set ++# CONFIG_GENWQE is not set ++# CONFIG_GFS2_FS is not set ++# CONFIG_GIGASET_CAPI is not set ++# CONFIG_GIGASET_DEBUG is not set ++# CONFIG_GIGASET_DUMMYLL is not set ++# CONFIG_GLOB_SELFTEST is not set ++# CONFIG_GNSS is not set ++# CONFIG_GOLDFISH is not set ++# CONFIG_GOOGLE_FIRMWARE is not set ++# CONFIG_GP2AP002 is not set ++# CONFIG_GP2AP020A00F is not set ++# CONFIG_GPD_POCKET_FAN is not set ++# CONFIG_GPIOLIB is not set ++CONFIG_GPIOLIB_FASTPATH_LIMIT=512 ++# CONFIG_GPIO_104_DIO_48E is not set ++# CONFIG_GPIO_104_IDIO_16 is not set ++# CONFIG_GPIO_104_IDI_48 is not set ++# CONFIG_GPIO_74X164 is not set ++# CONFIG_GPIO_74XX_MMIO is not set ++# CONFIG_GPIO_ADNP is not set ++# CONFIG_GPIO_ADP5588 is not set ++# CONFIG_GPIO_AGGREGATOR is not set ++# CONFIG_GPIO_ALTERA is not set ++# CONFIG_GPIO_AMD8111 is not set ++# CONFIG_GPIO_AMDPT is not set ++# CONFIG_GPIO_AMD_FCH is not set ++# CONFIG_GPIO_BCM_KONA is not set ++# CONFIG_GPIO_BT8XX is not set ++# CONFIG_GPIO_CADENCE is not set ++# CONFIG_GPIO_CDEV is not set ++# CONFIG_GPIO_CS5535 is not set ++# CONFIG_GPIO_DWAPB is not set ++# CONFIG_GPIO_EM is not set ++# CONFIG_GPIO_EXAR is not set ++# CONFIG_GPIO_F7188X is not set ++# CONFIG_GPIO_FTGPIO010 is not set ++# CONFIG_GPIO_GENERIC_PLATFORM is not set ++# CONFIG_GPIO_GPIO_MM is not set ++# CONFIG_GPIO_GRGPIO is not set ++# CONFIG_GPIO_GW_PLD is not set ++# CONFIG_GPIO_HLWD is not set ++# CONFIG_GPIO_ICH is not set ++# CONFIG_GPIO_IT87 is not set ++# CONFIG_GPIO_LOGICVC is not set ++# CONFIG_GPIO_LYNXPOINT is not set ++# CONFIG_GPIO_MAX3191X is not set ++# CONFIG_GPIO_MAX7300 is not set ++# CONFIG_GPIO_MAX7301 is not set ++# CONFIG_GPIO_MAX732X is not set ++# CONFIG_GPIO_MB86S7X is not set ++# CONFIG_GPIO_MC33880 is not set ++# CONFIG_GPIO_MCP23S08 is not set ++# CONFIG_GPIO_ML_IOH is not set ++# CONFIG_GPIO_MOCKUP is not set ++# CONFIG_GPIO_MPC8XXX is not set ++# CONFIG_GPIO_PCA953X is not set ++# CONFIG_GPIO_PCA953X_IRQ is not set ++# CONFIG_GPIO_PCA9570 is not set ++# CONFIG_GPIO_PCF857X is not set ++# CONFIG_GPIO_PCH is not set ++# CONFIG_GPIO_PCIE_IDIO_24 is not set ++# CONFIG_GPIO_PCI_IDIO_16 is not set ++# CONFIG_GPIO_PISOSR is not set ++# CONFIG_GPIO_PL061 is not set ++# CONFIG_GPIO_RCAR is not set ++# CONFIG_GPIO_RDC321X is not set ++# CONFIG_GPIO_SAMA5D2_PIOBU is not set ++# CONFIG_GPIO_SCH is not set ++# CONFIG_GPIO_SCH311X is not set ++# CONFIG_GPIO_SIFIVE is not set ++# CONFIG_GPIO_SX150X is not set ++# CONFIG_GPIO_SYSCON is not set ++CONFIG_GPIO_SYSFS=y ++# CONFIG_GPIO_TPIC2810 is not set ++# CONFIG_GPIO_TS4900 is not set ++# CONFIG_GPIO_TS5500 is not set ++# CONFIG_GPIO_VX855 is not set ++# CONFIG_GPIO_WATCHDOG is not set ++# CONFIG_GPIO_WINBOND is not set ++# CONFIG_GPIO_WS16C48 is not set ++# CONFIG_GPIO_XGENE is not set ++# CONFIG_GPIO_XILINX is not set ++# CONFIG_GPIO_XRA1403 is not set ++# CONFIG_GPIO_ZEVIO is not set ++# CONFIG_GPIO_ZX is not set ++# CONFIG_GREENASIA_FF is not set ++# CONFIG_GREYBUS is not set ++# CONFIG_GS_FPGABOOT is not set ++# CONFIG_GTP is not set ++# CONFIG_GUP_BENCHMARK is not set ++# CONFIG_GVE is not set ++# CONFIG_HABANA_AI is not set ++# CONFIG_HAMACHI is not set ++# CONFIG_HAMRADIO is not set ++# CONFIG_HAPPYMEAL is not set ++CONFIG_HARDENED_USERCOPY=y ++# CONFIG_HARDENED_USERCOPY_FALLBACK is not set ++# CONFIG_HARDENED_USERCOPY_PAGESPAN is not set ++CONFIG_HARDEN_EL2_VECTORS=y ++# CONFIG_HARDLOCKUP_DETECTOR is not set ++# CONFIG_HCALL_STATS is not set ++# CONFIG_HDC100X is not set ++# CONFIG_HDLC is not set ++# CONFIG_HDLC_CISCO is not set ++# CONFIG_HDLC_FR is not set ++# CONFIG_HDLC_PPP is not set ++# CONFIG_HDLC_RAW is not set ++# CONFIG_HDLC_RAW_ETH is not set ++# CONFIG_HDMI_LPE_AUDIO is not set ++# CONFIG_HDQ_MASTER_OMAP is not set ++# CONFIG_HEADERS_CHECK is not set ++# CONFIG_HEADERS_INSTALL is not set ++# CONFIG_HEADER_TEST is not set ++# CONFIG_HERMES is not set ++# CONFIG_HFSPLUS_FS is not set ++# CONFIG_HFSPLUS_FS_POSIX_ACL is not set ++# CONFIG_HFS_FS is not set ++# CONFIG_HFS_FS_POSIX_ACL is not set ++# CONFIG_HI8435 is not set ++# CONFIG_HIBERNATION is not set ++# CONFIG_HID is not set ++# CONFIG_HIDRAW is not set ++# CONFIG_HID_A4TECH is not set ++# CONFIG_HID_ACCUTOUCH is not set ++# CONFIG_HID_ACRUX is not set ++# CONFIG_HID_ACRUX_FF is not set ++# CONFIG_HID_ALPS is not set ++# CONFIG_HID_APPLE is not set ++# CONFIG_HID_APPLEIR is not set ++# CONFIG_HID_ASUS is not set ++# CONFIG_HID_AUREAL is not set ++# CONFIG_HID_BATTERY_STRENGTH is not set ++# CONFIG_HID_BELKIN is not set ++# CONFIG_HID_BETOP_FF is not set ++# CONFIG_HID_BIGBEN_FF is not set ++# CONFIG_HID_CHERRY is not set ++# CONFIG_HID_CHICONY is not set ++# CONFIG_HID_CMEDIA is not set ++# CONFIG_HID_CORSAIR is not set ++# CONFIG_HID_COUGAR is not set ++# CONFIG_HID_CP2112 is not set ++# CONFIG_HID_CREATIVE_SB0540 is not set ++# CONFIG_HID_CYPRESS is not set ++# CONFIG_HID_DRAGONRISE is not set ++# CONFIG_HID_ELAN is not set ++# CONFIG_HID_ELECOM is not set ++# CONFIG_HID_ELO is not set ++# CONFIG_HID_EMS_FF is not set ++# CONFIG_HID_EZKEY is not set ++# CONFIG_HID_GEMBIRD is not set ++# CONFIG_HID_GENERIC is not set ++# CONFIG_HID_GFRM is not set ++# CONFIG_HID_GLORIOUS is not set ++# CONFIG_HID_GOOGLE_HAMMER is not set ++# CONFIG_HID_GREENASIA is not set ++# CONFIG_HID_GT683R is not set ++# CONFIG_HID_GYRATION is not set ++# CONFIG_HID_HOLTEK is not set ++# CONFIG_HID_ICADE is not set ++# CONFIG_HID_ITE is not set ++# CONFIG_HID_JABRA is not set ++# CONFIG_HID_KENSINGTON is not set ++# CONFIG_HID_KEYTOUCH is not set ++# CONFIG_HID_KYE is not set ++# CONFIG_HID_LCPOWER is not set ++# CONFIG_HID_LED is not set ++# CONFIG_HID_LENOVO is not set ++# CONFIG_HID_LOGITECH is not set ++# CONFIG_HID_LOGITECH_DJ is not set ++# CONFIG_HID_LOGITECH_HIDPP is not set ++# CONFIG_HID_MACALLY is not set ++# CONFIG_HID_MAGICMOUSE is not set ++# CONFIG_HID_MALTRON is not set ++# CONFIG_HID_MAYFLASH is not set ++# CONFIG_HID_MCP2221 is not set ++# CONFIG_HID_MICROSOFT is not set ++# CONFIG_HID_MONTEREY is not set ++# CONFIG_HID_MULTITOUCH is not set ++# CONFIG_HID_NTI is not set ++# CONFIG_HID_NTRIG is not set ++# CONFIG_HID_ORTEK is not set ++# CONFIG_HID_PANTHERLORD is not set ++# CONFIG_HID_PENMOUNT is not set ++# CONFIG_HID_PETALYNX is not set ++# CONFIG_HID_PICOLCD is not set ++# CONFIG_HID_PID is not set ++# CONFIG_HID_PLANTRONICS is not set ++# CONFIG_HID_PRIMAX is not set ++# CONFIG_HID_PRODIKEYS is not set ++# CONFIG_HID_REDRAGON is not set ++# CONFIG_HID_RETRODE is not set ++# CONFIG_HID_RMI is not set ++# CONFIG_HID_ROCCAT is not set ++# CONFIG_HID_SAITEK is not set ++# CONFIG_HID_SAMSUNG is not set ++# CONFIG_HID_SENSOR_HUB is not set ++# CONFIG_HID_SMARTJOYPLUS is not set ++# CONFIG_HID_SONY is not set ++# CONFIG_HID_SPEEDLINK is not set ++# CONFIG_HID_STEAM is not set ++# CONFIG_HID_STEELSERIES is not set ++# CONFIG_HID_SUNPLUS is not set ++# CONFIG_HID_THINGM is not set ++# CONFIG_HID_THRUSTMASTER is not set ++# CONFIG_HID_TIVO is not set ++# CONFIG_HID_TOPSEED is not set ++# CONFIG_HID_TWINHAN is not set ++# CONFIG_HID_U2FZERO is not set ++# CONFIG_HID_UCLOGIC is not set ++# CONFIG_HID_UDRAW_PS3 is not set ++# CONFIG_HID_VIEWSONIC is not set ++# CONFIG_HID_VIVALDI is not set ++# CONFIG_HID_WACOM is not set ++# CONFIG_HID_WALTOP is not set ++# CONFIG_HID_WIIMOTE is not set ++# CONFIG_HID_XINMO is not set ++# CONFIG_HID_ZEROPLUS is not set ++# CONFIG_HID_ZYDACRON is not set ++# CONFIG_HIGHMEM is not set ++CONFIG_HIGH_RES_TIMERS=y ++# CONFIG_HINIC is not set ++# CONFIG_HIP04_ETH is not set ++# CONFIG_HIPPI is not set ++# CONFIG_HISILICON_ERRATUM_161010101 is not set ++# CONFIG_HISILICON_ERRATUM_161600802 is not set ++# CONFIG_HISI_DMA is not set ++# CONFIG_HISI_FEMAC is not set ++# CONFIG_HIX5HD2_GMAC is not set ++# CONFIG_HMC425 is not set ++# CONFIG_HMC6352 is not set ++# CONFIG_HNS is not set ++# CONFIG_HNS3 is not set ++# CONFIG_HNS_DSAF is not set ++# CONFIG_HNS_ENET is not set ++# CONFIG_HOSTAP is not set ++# CONFIG_HOSTAP_CS is not set ++# CONFIG_HOSTAP_PCI is not set ++# CONFIG_HOSTAP_PLX is not set ++# CONFIG_HOTPLUG_CPU is not set ++# CONFIG_HOTPLUG_PCI is not set ++# CONFIG_HP03 is not set ++# CONFIG_HP100 is not set ++# CONFIG_HP206C is not set ++CONFIG_HPET_MMAP_DEFAULT=y ++# CONFIG_HPFS_FS is not set ++# CONFIG_HP_ILO is not set ++# CONFIG_HP_WIRELESS is not set ++# CONFIG_HSA_AMD is not set ++# CONFIG_HSI is not set ++# CONFIG_HSR is not set ++# CONFIG_HTC_EGPIO is not set ++# CONFIG_HTC_I2CPLD is not set ++# CONFIG_HTC_PASIC3 is not set ++# CONFIG_HTS221 is not set ++# CONFIG_HTU21 is not set ++# CONFIG_HUGETLBFS is not set ++# CONFIG_HUGETLB_PAGE is not set ++# CONFIG_HVC_DCC is not set ++# CONFIG_HVC_UDBG is not set ++# CONFIG_HWLAT_TRACER is not set ++# CONFIG_HWMON is not set ++# CONFIG_HWMON_DEBUG_CHIP is not set ++# CONFIG_HWMON_VID is not set ++# CONFIG_HWSPINLOCK is not set ++# CONFIG_HWSPINLOCK_OMAP is not set ++CONFIG_HW_PERF_EVENTS=y ++# CONFIG_HW_RANDOM is not set ++# CONFIG_HW_RANDOM_AMD is not set ++# CONFIG_HW_RANDOM_ATMEL is not set ++# CONFIG_HW_RANDOM_BA431 is not set ++# CONFIG_HW_RANDOM_CAVIUM is not set ++# CONFIG_HW_RANDOM_CCTRNG is not set ++# CONFIG_HW_RANDOM_EXYNOS is not set ++# CONFIG_HW_RANDOM_GEODE is not set ++# CONFIG_HW_RANDOM_INTEL is not set ++# CONFIG_HW_RANDOM_IPROC_RNG200 is not set ++# CONFIG_HW_RANDOM_MTK is not set ++# CONFIG_HW_RANDOM_OMAP is not set ++# CONFIG_HW_RANDOM_OMAP3_ROM is not set ++# CONFIG_HW_RANDOM_PPC4XX is not set ++# CONFIG_HW_RANDOM_TIMERIOMEM is not set ++CONFIG_HW_RANDOM_TPM=y ++# CONFIG_HW_RANDOM_VIA is not set ++# CONFIG_HW_RANDOM_VIRTIO is not set ++# CONFIG_HX711 is not set ++# CONFIG_HYPERV is not set ++# CONFIG_HYPERV_TSCPAGE is not set ++# CONFIG_HYSDN is not set ++# CONFIG_HZ is not set ++# CONFIG_HZ_100 is not set ++# CONFIG_HZ_1000 is not set ++# CONFIG_HZ_1024 is not set ++# CONFIG_HZ_128 is not set ++# CONFIG_HZ_200 is not set ++# CONFIG_HZ_24 is not set ++# CONFIG_HZ_250 is not set ++# CONFIG_HZ_256 is not set ++# CONFIG_HZ_300 is not set ++# CONFIG_HZ_48 is not set ++# CONFIG_HZ_500 is not set ++# CONFIG_HZ_PERIODIC is not set ++# CONFIG_I2C is not set ++# CONFIG_I2C_ALGOBIT is not set ++# CONFIG_I2C_ALGOPCA is not set ++# CONFIG_I2C_ALGOPCF is not set ++# CONFIG_I2C_ALI1535 is not set ++# CONFIG_I2C_ALI1563 is not set ++# CONFIG_I2C_ALI15X3 is not set ++# CONFIG_I2C_AMD756 is not set ++# CONFIG_I2C_AMD8111 is not set ++# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set ++# CONFIG_I2C_AU1550 is not set ++# CONFIG_I2C_BCM2835 is not set ++# CONFIG_I2C_BCM_IPROC is not set ++# CONFIG_I2C_CADENCE is not set ++# CONFIG_I2C_CBUS_GPIO is not set ++# CONFIG_I2C_CHARDEV is not set ++# CONFIG_I2C_COMPAT is not set ++# CONFIG_I2C_DEBUG_ALGO is not set ++# CONFIG_I2C_DEBUG_BUS is not set ++# CONFIG_I2C_DEBUG_CORE is not set ++# CONFIG_I2C_DEMUX_PINCTRL is not set ++# CONFIG_I2C_DESIGNWARE_PCI is not set ++# CONFIG_I2C_DESIGNWARE_PLATFORM is not set ++# CONFIG_I2C_DIOLAN_U2C is not set ++# CONFIG_I2C_EG20T is not set ++# CONFIG_I2C_ELEKTOR is not set ++# CONFIG_I2C_EMEV2 is not set ++# CONFIG_I2C_GPIO is not set ++# CONFIG_I2C_GPIO_FAULT_INJECTOR is not set ++# CONFIG_I2C_HELPER_AUTO is not set ++# CONFIG_I2C_HID is not set ++# CONFIG_I2C_I801 is not set ++# CONFIG_I2C_IBM_IIC is not set ++# CONFIG_I2C_IMG is not set ++# CONFIG_I2C_ISCH is not set ++# CONFIG_I2C_ISMT is not set ++# CONFIG_I2C_JZ4780 is not set ++# CONFIG_I2C_MLXCPLD is not set ++# CONFIG_I2C_MPC is not set ++# CONFIG_I2C_MT65XX is not set ++# CONFIG_I2C_MUX is not set ++# CONFIG_I2C_MUX_GPIO is not set ++# CONFIG_I2C_MUX_GPMUX is not set ++# CONFIG_I2C_MUX_LTC4306 is not set ++# CONFIG_I2C_MUX_MLXCPLD is not set ++# CONFIG_I2C_MUX_PCA9541 is not set ++# CONFIG_I2C_MUX_PCA954x is not set ++# CONFIG_I2C_MUX_PINCTRL is not set ++# CONFIG_I2C_MUX_REG is not set ++# CONFIG_I2C_MV64XXX is not set ++# CONFIG_I2C_NFORCE2 is not set ++# CONFIG_I2C_NOMADIK is not set ++# CONFIG_I2C_NVIDIA_GPU is not set ++# CONFIG_I2C_OCORES is not set ++# CONFIG_I2C_OCTEON is not set ++# CONFIG_I2C_PARPORT is not set ++# CONFIG_I2C_PARPORT_LIGHT is not set ++# CONFIG_I2C_PCA_ISA is not set ++# CONFIG_I2C_PCA_PLATFORM is not set ++# CONFIG_I2C_PIIX4 is not set ++# CONFIG_I2C_PXA_PCI is not set ++# CONFIG_I2C_RCAR is not set ++# CONFIG_I2C_RK3X is not set ++# CONFIG_I2C_ROBOTFUZZ_OSIF is not set ++# CONFIG_I2C_S3C2410 is not set ++# CONFIG_I2C_SCMI is not set ++# CONFIG_I2C_SH_MOBILE is not set ++# CONFIG_I2C_SIMTEC is not set ++# CONFIG_I2C_SIS5595 is not set ++# CONFIG_I2C_SIS630 is not set ++# CONFIG_I2C_SIS96X is not set ++# CONFIG_I2C_SLAVE is not set ++# CONFIG_I2C_SLAVE_EEPROM is not set ++# CONFIG_I2C_SMBUS is not set ++# CONFIG_I2C_STUB is not set ++# CONFIG_I2C_TAOS_EVM is not set ++# CONFIG_I2C_THUNDERX is not set ++# CONFIG_I2C_TINY_USB is not set ++# CONFIG_I2C_VERSATILE is not set ++# CONFIG_I2C_VIA is not set ++# CONFIG_I2C_VIAPRO is not set ++# CONFIG_I2C_XILINX is not set ++# CONFIG_I3C is not set ++# CONFIG_I40E is not set ++# CONFIG_I40EVF is not set ++# CONFIG_I6300ESB_WDT is not set ++# CONFIG_I82092 is not set ++# CONFIG_I82365 is not set ++# CONFIG_IAQCORE is not set ++# CONFIG_IBM_ASM is not set ++# CONFIG_IBM_EMAC_DEBUG is not set ++# CONFIG_IBM_EMAC_EMAC4 is not set ++# CONFIG_IBM_EMAC_MAL_CLR_ICINTSTAT is not set ++# CONFIG_IBM_EMAC_MAL_COMMON_ERR is not set ++# CONFIG_IBM_EMAC_NO_FLOW_CTRL is not set ++# CONFIG_IBM_EMAC_RGMII is not set ++# CONFIG_IBM_EMAC_TAH is not set ++# CONFIG_IBM_EMAC_ZMII is not set ++# CONFIG_ICE is not set ++# CONFIG_ICP10100 is not set ++# CONFIG_ICPLUS_PHY is not set ++# CONFIG_ICS932S401 is not set ++# CONFIG_IDE is not set ++# CONFIG_IDEAPAD_LAPTOP is not set ++# CONFIG_IDE_GD is not set ++# CONFIG_IDE_PROC_FS is not set ++# CONFIG_IDE_TASK_IOCTL is not set ++# CONFIG_IDLE_PAGE_TRACKING is not set ++# CONFIG_IEEE802154 is not set ++# CONFIG_IEEE802154_ADF7242 is not set ++# CONFIG_IEEE802154_ATUSB is not set ++# CONFIG_IEEE802154_CA8210 is not set ++# CONFIG_IEEE802154_HWSIM is not set ++# CONFIG_IEEE802154_MCR20A is not set ++# CONFIG_IFB is not set ++# CONFIG_IGB is not set ++# CONFIG_IGBVF is not set ++# CONFIG_IGC is not set ++# CONFIG_IIO is not set ++# CONFIG_IIO_BUFFER is not set ++# CONFIG_IIO_BUFFER_CB is not set ++# CONFIG_IIO_BUFFER_HW_CONSUMER is not set ++# CONFIG_IIO_CONFIGFS is not set ++CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 ++# CONFIG_IIO_CROS_EC_ACCEL_LEGACY is not set ++# CONFIG_IIO_INTERRUPT_TRIGGER is not set ++# CONFIG_IIO_MUX is not set ++# CONFIG_IIO_PERIODIC_RTC_TRIGGER is not set ++# CONFIG_IIO_RESCALE is not set ++# CONFIG_IIO_SIMPLE_DUMMY is not set ++# CONFIG_IIO_SSP_SENSORHUB is not set ++# CONFIG_IIO_ST_ACCEL_3AXIS is not set ++# CONFIG_IIO_ST_GYRO_3AXIS is not set ++# CONFIG_IIO_ST_LSM6DSX is not set ++# CONFIG_IIO_ST_MAGN_3AXIS is not set ++# CONFIG_IIO_ST_PRESS is not set ++# CONFIG_IIO_SW_DEVICE is not set ++# CONFIG_IIO_SW_TRIGGER is not set ++# CONFIG_IIO_SYSFS_TRIGGER is not set ++# CONFIG_IIO_TRIGGER is not set ++# CONFIG_IIO_TRIGGERED_EVENT is not set ++# CONFIG_IKCONFIG is not set ++# CONFIG_IKCONFIG_PROC is not set ++# CONFIG_IKHEADERS is not set ++# CONFIG_IMA is not set ++# CONFIG_IMAGE_CMDLINE_HACK is not set ++# CONFIG_IMGPDC_WDT is not set ++# CONFIG_IMG_MDC_DMA is not set ++# CONFIG_IMX7D_ADC is not set ++# CONFIG_IMX_IPUV3_CORE is not set ++# CONFIG_IMX_THERMAL is not set ++# CONFIG_INA2XX_ADC is not set ++# CONFIG_INDIRECT_PIO is not set ++CONFIG_INET=y ++# CONFIG_INET6_AH is not set ++# CONFIG_INET6_ESP is not set ++# CONFIG_INET6_ESPINTCP is not set ++# CONFIG_INET6_IPCOMP is not set ++# CONFIG_INET6_TUNNEL is not set ++# CONFIG_INET6_XFRM_MODE_BEET is not set ++# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set ++# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET6_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET6_XFRM_TUNNEL is not set ++# CONFIG_INET_AH is not set ++# CONFIG_INET_DIAG is not set ++# CONFIG_INET_ESP is not set ++# CONFIG_INET_ESPINTCP is not set ++# CONFIG_INET_IPCOMP is not set ++# CONFIG_INET_LRO is not set ++# CONFIG_INET_TCP_DIAG is not set ++# CONFIG_INET_TUNNEL is not set ++# CONFIG_INET_UDP_DIAG is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_TUNNEL is not set ++# CONFIG_INFINIBAND is not set ++# CONFIG_INFTL is not set ++# CONFIG_INGENIC_ADC is not set ++# CONFIG_INGENIC_CGU_JZ4725B is not set ++# CONFIG_INGENIC_CGU_JZ4740 is not set ++# CONFIG_INGENIC_CGU_JZ4770 is not set ++# CONFIG_INGENIC_CGU_JZ4780 is not set ++# CONFIG_INGENIC_TCU_CLK is not set ++# CONFIG_INGENIC_TCU_IRQ is not set ++# CONFIG_INGENIC_TIMER is not set ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set ++# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set ++CONFIG_INIT_STACK_NONE=y ++CONFIG_INOTIFY_USER=y ++# CONFIG_INPUT is not set ++# CONFIG_INPUT_AD714X is not set ++# CONFIG_INPUT_ADXL34X is not set ++# CONFIG_INPUT_APANEL is not set ++# CONFIG_INPUT_ATI_REMOTE2 is not set ++# CONFIG_INPUT_ATLAS_BTNS is not set ++# CONFIG_INPUT_ATMEL_CAPTOUCH is not set ++# CONFIG_INPUT_AXP20X_PEK is not set ++# CONFIG_INPUT_BMA150 is not set ++# CONFIG_INPUT_CM109 is not set ++# CONFIG_INPUT_CMA3000 is not set ++# CONFIG_INPUT_DRV260X_HAPTICS is not set ++# CONFIG_INPUT_DRV2665_HAPTICS is not set ++# CONFIG_INPUT_DRV2667_HAPTICS is not set ++# CONFIG_INPUT_E3X0_BUTTON is not set ++# CONFIG_INPUT_EVBUG is not set ++# CONFIG_INPUT_EVDEV is not set ++# CONFIG_INPUT_FF_MEMLESS is not set ++# CONFIG_INPUT_GP2A is not set ++# CONFIG_INPUT_GPIO_BEEPER is not set ++# CONFIG_INPUT_GPIO_DECODER is not set ++# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set ++# CONFIG_INPUT_GPIO_TILT_POLLED is not set ++# CONFIG_INPUT_GPIO_VIBRA is not set ++# CONFIG_INPUT_IDEAPAD_SLIDEBAR is not set ++# CONFIG_INPUT_IMS_PCU is not set ++# CONFIG_INPUT_IQS269A is not set ++# CONFIG_INPUT_JOYDEV is not set ++# CONFIG_INPUT_JOYSTICK is not set ++# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_INPUT_KEYSPAN_REMOTE is not set ++# CONFIG_INPUT_KXTJ9 is not set ++# CONFIG_INPUT_LEDS is not set ++# CONFIG_INPUT_MATRIXKMAP is not set ++# CONFIG_INPUT_MAX8997_HAPTIC is not set ++CONFIG_INPUT_MISC=y ++# CONFIG_INPUT_MMA8450 is not set ++# CONFIG_INPUT_MOUSE is not set ++# CONFIG_INPUT_MOUSEDEV is not set ++# CONFIG_INPUT_MPU3050 is not set ++# CONFIG_INPUT_MSM_VIBRATOR is not set ++# CONFIG_INPUT_PALMAS_PWRBUTTON is not set ++# CONFIG_INPUT_PCF8574 is not set ++# CONFIG_INPUT_PCSPKR is not set ++# CONFIG_INPUT_POLLDEV is not set ++# CONFIG_INPUT_POWERMATE is not set ++# CONFIG_INPUT_PWM_BEEPER is not set ++# CONFIG_INPUT_PWM_VIBRA is not set ++# CONFIG_INPUT_REGULATOR_HAPTIC is not set ++# CONFIG_INPUT_SOC_BUTTON_ARRAY is not set ++# CONFIG_INPUT_SPARSEKMAP is not set ++# CONFIG_INPUT_TABLET is not set ++# CONFIG_INPUT_TOUCHSCREEN is not set ++# CONFIG_INPUT_TPS65218_PWRBUTTON is not set ++# CONFIG_INPUT_TWL4030_PWRBUTTON is not set ++# CONFIG_INPUT_TWL4030_VIBRA is not set ++# CONFIG_INPUT_TWL6040_VIBRA is not set ++# CONFIG_INPUT_UINPUT is not set ++# CONFIG_INPUT_WISTRON_BTNS is not set ++# CONFIG_INPUT_YEALINK is not set ++# CONFIG_INT340X_THERMAL is not set ++# CONFIG_INTEGRITY is not set ++# CONFIG_INTEGRITY_AUDIT is not set ++# CONFIG_INTEGRITY_SIGNATURE is not set ++# CONFIG_INTEL_ATOMISP2_PM is not set ++# CONFIG_INTEL_CHT_INT33FE is not set ++# CONFIG_INTEL_HID_EVENT is not set ++# CONFIG_INTEL_IDLE is not set ++# CONFIG_INTEL_IDMA64 is not set ++# CONFIG_INTEL_IOATDMA is not set ++# CONFIG_INTEL_ISH_HID is not set ++# CONFIG_INTEL_MEI is not set ++# CONFIG_INTEL_MEI_ME is not set ++# CONFIG_INTEL_MEI_TXE is not set ++# CONFIG_INTEL_MIC_CARD is not set ++# CONFIG_INTEL_MIC_HOST is not set ++# CONFIG_INTEL_MID_PTI is not set ++# CONFIG_INTEL_OAKTRAIL is not set ++# CONFIG_INTEL_PMC_CORE is not set ++# CONFIG_INTEL_PUNIT_IPC is not set ++# CONFIG_INTEL_RST is not set ++# CONFIG_INTEL_SMARTCONNECT is not set ++# CONFIG_INTEL_SOC_PMIC is not set ++# CONFIG_INTEL_SOC_PMIC_CHTDC_TI is not set ++# CONFIG_INTEL_SOC_PMIC_CHTWC is not set ++# CONFIG_INTEL_TH is not set ++# CONFIG_INTEL_VBTN is not set ++# CONFIG_INTEL_XWAY_PHY is not set ++# CONFIG_INTERCONNECT is not set ++# CONFIG_INTERVAL_TREE_TEST is not set ++# CONFIG_INV_ICM42600_I2C is not set ++# CONFIG_INV_ICM42600_SPI is not set ++# CONFIG_INV_MPU6050_I2C is not set ++# CONFIG_INV_MPU6050_IIO is not set ++# CONFIG_INV_MPU6050_SPI is not set ++# CONFIG_IOMMU_SUPPORT is not set ++# CONFIG_IONIC is not set ++# CONFIG_IOSCHED_BFQ is not set ++# CONFIG_IOSCHED_CFQ is not set ++CONFIG_IOSCHED_DEADLINE=y ++CONFIG_IOSCHED_NOOP=y ++CONFIG_IO_STRICT_DEVMEM=y ++# CONFIG_IO_URING is not set ++CONFIG_IO_WQ=y ++# CONFIG_IP17XX_PHY is not set ++# CONFIG_IP6_NF_FILTER is not set ++# CONFIG_IP6_NF_IPTABLES is not set ++# CONFIG_IP6_NF_MANGLE is not set ++# CONFIG_IP6_NF_MATCH_AH is not set ++# CONFIG_IP6_NF_MATCH_EUI64 is not set ++# CONFIG_IP6_NF_MATCH_FRAG is not set ++# CONFIG_IP6_NF_MATCH_HL is not set ++# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set ++# CONFIG_IP6_NF_MATCH_MH is not set ++# CONFIG_IP6_NF_MATCH_OPTS is not set ++# CONFIG_IP6_NF_MATCH_RPFILTER is not set ++# CONFIG_IP6_NF_MATCH_RT is not set ++# CONFIG_IP6_NF_MATCH_SRH is not set ++# CONFIG_IP6_NF_NAT is not set ++# CONFIG_IP6_NF_RAW is not set ++# CONFIG_IP6_NF_SECURITY is not set ++# CONFIG_IP6_NF_TARGET_HL is not set ++# CONFIG_IP6_NF_TARGET_MASQUERADE is not set ++# CONFIG_IP6_NF_TARGET_REJECT is not set ++# CONFIG_IP6_NF_TARGET_SYNPROXY is not set ++# CONFIG_IPACK_BUS is not set ++# CONFIG_IPC_NS is not set ++# CONFIG_IPMB_DEVICE_INTERFACE is not set ++# CONFIG_IPMI_HANDLER is not set ++# CONFIG_IPV6 is not set ++# CONFIG_IPV6_FOU is not set ++# CONFIG_IPV6_FOU_TUNNEL is not set ++# CONFIG_IPV6_ILA is not set ++# CONFIG_IPV6_MIP6 is not set ++# CONFIG_IPV6_MROUTE is not set ++# CONFIG_IPV6_MROUTE_MULTIPLE_TABLES is not set ++# CONFIG_IPV6_MULTIPLE_TABLES is not set ++CONFIG_IPV6_NDISC_NODETYPE=y ++# CONFIG_IPV6_OPTIMISTIC_DAD is not set ++# CONFIG_IPV6_ROUTER_PREF is not set ++# CONFIG_IPV6_ROUTE_INFO is not set ++# CONFIG_IPV6_RPL_LWTUNNEL is not set ++# CONFIG_IPV6_SEG6_HMAC is not set ++# CONFIG_IPV6_SEG6_LWTUNNEL is not set ++# CONFIG_IPV6_SIT is not set ++# CONFIG_IPV6_SIT_6RD is not set ++# CONFIG_IPV6_TUNNEL is not set ++# CONFIG_IPV6_VTI is not set ++# CONFIG_IPVLAN is not set ++# CONFIG_IPW2100 is not set ++# CONFIG_IPW2100_DEBUG is not set ++CONFIG_IPW2100_MONITOR=y ++# CONFIG_IPW2200 is not set ++# CONFIG_IPW2200_DEBUG is not set ++CONFIG_IPW2200_MONITOR=y ++# CONFIG_IPW2200_PROMISCUOUS is not set ++# CONFIG_IPW2200_QOS is not set ++# CONFIG_IPW2200_RADIOTAP is not set ++# CONFIG_IPWIRELESS is not set ++# CONFIG_IPX is not set ++CONFIG_IP_ADVANCED_ROUTER=y ++# CONFIG_IP_DCCP is not set ++# CONFIG_IP_FIB_TRIE_STATS is not set ++# CONFIG_IP_MROUTE is not set ++CONFIG_IP_MROUTE_MULTIPLE_TABLES=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_MULTIPLE_TABLES=y ++# CONFIG_IP_NF_ARPFILTER is not set ++# CONFIG_IP_NF_ARPTABLES is not set ++# CONFIG_IP_NF_ARP_MANGLE is not set ++# CONFIG_IP_NF_FILTER is not set ++# CONFIG_IP_NF_IPTABLES is not set ++# CONFIG_IP_NF_MANGLE is not set ++# CONFIG_IP_NF_MATCH_AH is not set ++# CONFIG_IP_NF_MATCH_ECN is not set ++# CONFIG_IP_NF_MATCH_RPFILTER is not set ++# CONFIG_IP_NF_MATCH_TTL is not set ++# CONFIG_IP_NF_RAW is not set ++# CONFIG_IP_NF_SECURITY is not set ++# CONFIG_IP_NF_TARGET_CLUSTERIP is not set ++# CONFIG_IP_NF_TARGET_ECN is not set ++# CONFIG_IP_NF_TARGET_MASQUERADE is not set ++# CONFIG_IP_NF_TARGET_NETMAP is not set ++# CONFIG_IP_NF_TARGET_REDIRECT is not set ++# CONFIG_IP_NF_TARGET_REJECT is not set ++# CONFIG_IP_NF_TARGET_SYNPROXY is not set ++# CONFIG_IP_NF_TARGET_TTL is not set ++# CONFIG_IP_PIMSM_V1 is not set ++# CONFIG_IP_PIMSM_V2 is not set ++# CONFIG_IP_PNP is not set ++CONFIG_IP_ROUTE_MULTIPATH=y ++CONFIG_IP_ROUTE_VERBOSE=y ++# CONFIG_IP_SCTP is not set ++# CONFIG_IP_SET is not set ++# CONFIG_IP_SET_HASH_IPMAC is not set ++# CONFIG_IP_VS is not set ++# CONFIG_IP_VS_MH is not set ++CONFIG_IP_VS_MH_TAB_INDEX=10 ++# CONFIG_IRDA is not set ++# CONFIG_IRQSOFF_TRACER is not set ++# CONFIG_IRQ_ALL_CPUS is not set ++# CONFIG_IRQ_DOMAIN_DEBUG is not set ++# CONFIG_IRQ_POLL is not set ++# CONFIG_IRQ_TIME_ACCOUNTING is not set ++# CONFIG_IR_GPIO_CIR is not set ++# CONFIG_IR_HIX5HD2 is not set ++# CONFIG_IR_IGORPLUGUSB is not set ++# CONFIG_IR_IGUANA is not set ++# CONFIG_IR_IMG is not set ++# CONFIG_IR_IMON is not set ++# CONFIG_IR_JVC_DECODER is not set ++# CONFIG_IR_LIRC_CODEC is not set ++# CONFIG_IR_MCEUSB is not set ++# CONFIG_IR_NEC_DECODER is not set ++# CONFIG_IR_RC5_DECODER is not set ++# CONFIG_IR_RC6_DECODER is not set ++# CONFIG_IR_REDRAT3 is not set ++# CONFIG_IR_SONY_DECODER is not set ++# CONFIG_IR_STREAMZAP is not set ++# CONFIG_IR_TTUSBIR is not set ++# CONFIG_ISA_BUS is not set ++# CONFIG_ISA_BUS_API is not set ++# CONFIG_ISCSI_BOOT_SYSFS is not set ++# CONFIG_ISCSI_TCP is not set ++CONFIG_ISDN=y ++# CONFIG_ISDN_AUDIO is not set ++# CONFIG_ISDN_CAPI is not set ++# CONFIG_ISDN_CAPI_CAPIDRV is not set ++# CONFIG_ISDN_DIVERSION is not set ++# CONFIG_ISDN_DRV_ACT2000 is not set ++# CONFIG_ISDN_DRV_GIGASET is not set ++# CONFIG_ISDN_DRV_HISAX is not set ++# CONFIG_ISDN_DRV_ICN is not set ++# CONFIG_ISDN_DRV_LOOP is not set ++# CONFIG_ISDN_DRV_PCBIT is not set ++# CONFIG_ISDN_DRV_SC is not set ++# CONFIG_ISDN_I4L is not set ++# CONFIG_ISL29003 is not set ++# CONFIG_ISL29020 is not set ++# CONFIG_ISL29125 is not set ++# CONFIG_ISL29501 is not set ++# CONFIG_ISO9660_FS is not set ++# CONFIG_ISS4xx is not set ++# CONFIG_ITG3200 is not set ++# CONFIG_IWL3945 is not set ++# CONFIG_IWLWIFI is not set ++# CONFIG_IXGB is not set ++# CONFIG_IXGBE is not set ++# CONFIG_IXGBEVF is not set ++# CONFIG_JAILHOUSE_GUEST is not set ++# CONFIG_JBD2_DEBUG is not set ++# CONFIG_JFFS2_CMODE_FAVOURLZO is not set ++# CONFIG_JFFS2_CMODE_NONE is not set ++CONFIG_JFFS2_CMODE_PRIORITY=y ++# CONFIG_JFFS2_CMODE_SIZE is not set ++CONFIG_JFFS2_COMPRESSION_OPTIONS=y ++CONFIG_JFFS2_FS=y ++CONFIG_JFFS2_FS_DEBUG=0 ++# CONFIG_JFFS2_FS_POSIX_ACL is not set ++# CONFIG_JFFS2_FS_SECURITY is not set ++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set ++CONFIG_JFFS2_FS_WRITEBUFFER=y ++CONFIG_JFFS2_FS_XATTR=y ++CONFIG_JFFS2_LZMA=y ++# CONFIG_JFFS2_LZO is not set ++CONFIG_JFFS2_RTIME=y ++# CONFIG_JFFS2_RUBIN is not set ++CONFIG_JFFS2_SUMMARY=y ++# CONFIG_JFFS2_ZLIB is not set ++# CONFIG_JFS_DEBUG is not set ++# CONFIG_JFS_FS is not set ++# CONFIG_JFS_POSIX_ACL is not set ++# CONFIG_JFS_SECURITY is not set ++# CONFIG_JFS_STATISTICS is not set ++# CONFIG_JME is not set ++CONFIG_JOLIET=y ++# CONFIG_JSA1212 is not set ++# CONFIG_JUMP_LABEL is not set ++# CONFIG_KALLSYMS is not set ++# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set ++# CONFIG_KALLSYMS_ALL is not set ++CONFIG_KALLSYMS_BASE_RELATIVE=y ++# CONFIG_KALLSYMS_UNCOMPRESSED is not set ++# CONFIG_KARMA_PARTITION is not set ++# CONFIG_KASAN is not set ++CONFIG_KASAN_STACK=1 ++# CONFIG_KCOV is not set ++# CONFIG_KERNEL_BZIP2 is not set ++# CONFIG_KERNEL_CAT is not set ++# CONFIG_KERNEL_GZIP is not set ++# CONFIG_KERNEL_LZ4 is not set ++# CONFIG_KERNEL_LZMA is not set ++# CONFIG_KERNEL_LZO is not set ++CONFIG_KERNEL_MODE_NEON=y ++CONFIG_KERNEL_XZ=y ++CONFIG_KERNFS=y ++# CONFIG_KEXEC is not set ++# CONFIG_KEXEC_FILE is not set ++# CONFIG_KEYBOARD_ADC is not set ++# CONFIG_KEYBOARD_ADP5588 is not set ++# CONFIG_KEYBOARD_ADP5589 is not set ++# CONFIG_KEYBOARD_APPLESPI is not set ++# CONFIG_KEYBOARD_ATKBD is not set ++# CONFIG_KEYBOARD_BCM is not set ++# CONFIG_KEYBOARD_CAP11XX is not set ++# CONFIG_KEYBOARD_DLINK_DIR685 is not set ++# CONFIG_KEYBOARD_GPIO is not set ++# CONFIG_KEYBOARD_GPIO_POLLED is not set ++# CONFIG_KEYBOARD_LKKBD is not set ++# CONFIG_KEYBOARD_LM8323 is not set ++# CONFIG_KEYBOARD_LM8333 is not set ++# CONFIG_KEYBOARD_MATRIX is not set ++# CONFIG_KEYBOARD_MAX7359 is not set ++# CONFIG_KEYBOARD_MCS is not set ++# CONFIG_KEYBOARD_MPR121 is not set ++# CONFIG_KEYBOARD_NEWTON is not set ++# CONFIG_KEYBOARD_OMAP4 is not set ++# CONFIG_KEYBOARD_OPENCORES is not set ++# CONFIG_KEYBOARD_PXA27x is not set ++# CONFIG_KEYBOARD_QT1050 is not set ++# CONFIG_KEYBOARD_QT1070 is not set ++# CONFIG_KEYBOARD_QT2160 is not set ++# CONFIG_KEYBOARD_SAMSUNG is not set ++# CONFIG_KEYBOARD_SH_KEYSC is not set ++# CONFIG_KEYBOARD_SNVS_PWRKEY is not set ++# CONFIG_KEYBOARD_STMPE is not set ++# CONFIG_KEYBOARD_STOWAWAY is not set ++# CONFIG_KEYBOARD_SUNKBD is not set ++# CONFIG_KEYBOARD_TCA6416 is not set ++# CONFIG_KEYBOARD_TCA8418 is not set ++# CONFIG_KEYBOARD_TEGRA is not set ++# CONFIG_KEYBOARD_TM2_TOUCHKEY is not set ++# CONFIG_KEYBOARD_TWL4030 is not set ++# CONFIG_KEYBOARD_XTKBD is not set ++# CONFIG_KEYS is not set ++# CONFIG_KEYS_REQUEST_CACHE is not set ++# CONFIG_KEY_DH_OPERATIONS is not set ++# CONFIG_KGDB is not set ++# CONFIG_KMEMCHECK is not set ++# CONFIG_KMX61 is not set ++# CONFIG_KPROBES is not set ++# CONFIG_KPROBES_SANITY_TEST is not set ++# CONFIG_KS7010 is not set ++# CONFIG_KS8842 is not set ++# CONFIG_KS8851 is not set ++# CONFIG_KS8851_MLL is not set ++# CONFIG_KSM is not set ++# CONFIG_KSZ884X_PCI is not set ++# CONFIG_KUNIT is not set ++CONFIG_KUSER_HELPERS=y ++# CONFIG_KVM_AMD is not set ++# CONFIG_KVM_GUEST is not set ++# CONFIG_KVM_INTEL is not set ++# CONFIG_KXCJK1013 is not set ++# CONFIG_KXSD9 is not set ++# CONFIG_L2TP is not set ++# CONFIG_L2TP_ETH is not set ++# CONFIG_L2TP_IP is not set ++# CONFIG_L2TP_V3 is not set ++# CONFIG_LAN743X is not set ++# CONFIG_LANMEDIA is not set ++# CONFIG_LANTIQ is not set ++# CONFIG_LAPB is not set ++# CONFIG_LASAT is not set ++# CONFIG_LATENCYTOP is not set ++# CONFIG_LATTICE_ECP3_CONFIG is not set ++CONFIG_LBDAF=y ++# CONFIG_LCD_AMS369FG06 is not set ++# CONFIG_LCD_CLASS_DEVICE is not set ++# CONFIG_LCD_HX8357 is not set ++# CONFIG_LCD_ILI922X is not set ++# CONFIG_LCD_ILI9320 is not set ++# CONFIG_LCD_L4F00242T03 is not set ++# CONFIG_LCD_LD9040 is not set ++# CONFIG_LCD_LMS283GF05 is not set ++# CONFIG_LCD_LMS501KF03 is not set ++# CONFIG_LCD_LTV350QV is not set ++# CONFIG_LCD_OTM3225A is not set ++# CONFIG_LCD_S6E63M0 is not set ++# CONFIG_LCD_TDO24M is not set ++# CONFIG_LCD_VGG2432A4 is not set ++CONFIG_LDISC_AUTOLOAD=y ++# CONFIG_LDM_PARTITION is not set ++CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=y ++# CONFIG_LEDS_AN30259A is not set ++# CONFIG_LEDS_APU is not set ++# CONFIG_LEDS_AW2013 is not set ++# CONFIG_LEDS_BCM6328 is not set ++# CONFIG_LEDS_BCM6358 is not set ++# CONFIG_LEDS_BD2802 is not set ++# CONFIG_LEDS_BLINKM is not set ++CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y ++CONFIG_LEDS_CLASS=y ++# CONFIG_LEDS_CLASS_FLASH is not set ++CONFIG_LEDS_CLASS_MULTICOLOR=y ++# CONFIG_LEDS_CR0014114 is not set ++# CONFIG_LEDS_DAC124S085 is not set ++# CONFIG_LEDS_EL15203000 is not set ++# CONFIG_LEDS_GPIO is not set ++# CONFIG_LEDS_INTEL_SS4200 is not set ++# CONFIG_LEDS_IS31FL319X is not set ++# CONFIG_LEDS_IS31FL32XX is not set ++# CONFIG_LEDS_LM3530 is not set ++# CONFIG_LEDS_LM3532 is not set ++# CONFIG_LEDS_LM355x is not set ++# CONFIG_LEDS_LM3642 is not set ++# CONFIG_LEDS_LM3692X is not set ++# CONFIG_LEDS_LP3944 is not set ++# CONFIG_LEDS_LP3952 is not set ++# CONFIG_LEDS_LP5521 is not set ++# CONFIG_LEDS_LP5523 is not set ++# CONFIG_LEDS_LP5562 is not set ++# CONFIG_LEDS_LP55XX_COMMON is not set ++# CONFIG_LEDS_LP8501 is not set ++# CONFIG_LEDS_LP8860 is not set ++# CONFIG_LEDS_LT3593 is not set ++# CONFIG_LEDS_MLXCPLD is not set ++# CONFIG_LEDS_MLXREG is not set ++# CONFIG_LEDS_NIC78BX is not set ++# CONFIG_LEDS_NS2 is not set ++# CONFIG_LEDS_OT200 is not set ++# CONFIG_LEDS_PCA9532 is not set ++# CONFIG_LEDS_PCA955X is not set ++# CONFIG_LEDS_PCA963X is not set ++# CONFIG_LEDS_PWM is not set ++# CONFIG_LEDS_REGULATOR is not set ++# CONFIG_LEDS_SPI_BYTE is not set ++# CONFIG_LEDS_SYSCON is not set ++# CONFIG_LEDS_TCA6507 is not set ++# CONFIG_LEDS_TI_LMU_COMMON is not set ++# CONFIG_LEDS_TLC591XX is not set ++CONFIG_LEDS_TRIGGERS=y ++# CONFIG_LEDS_TRIGGER_ACTIVITY is not set ++# CONFIG_LEDS_TRIGGER_AUDIO is not set ++# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set ++# CONFIG_LEDS_TRIGGER_CAMERA is not set ++# CONFIG_LEDS_TRIGGER_CPU is not set ++CONFIG_LEDS_TRIGGER_DEFAULT_ON=y ++# CONFIG_LEDS_TRIGGER_DISK is not set ++# CONFIG_LEDS_TRIGGER_GPIO is not set ++CONFIG_LEDS_TRIGGER_HEARTBEAT=y ++# CONFIG_LEDS_TRIGGER_MTD is not set ++CONFIG_LEDS_TRIGGER_NETDEV=y ++# CONFIG_LEDS_TRIGGER_ONESHOT is not set ++# CONFIG_LEDS_TRIGGER_PANIC is not set ++# CONFIG_LEDS_TRIGGER_PATTERN is not set ++CONFIG_LEDS_TRIGGER_TIMER=y ++# CONFIG_LEDS_TRIGGER_TRANSIENT is not set ++# CONFIG_LEDS_USER is not set ++# CONFIG_LED_TRIGGER_PHY is not set ++# CONFIG_LEGACY_PTYS is not set ++# CONFIG_LGUEST is not set ++# CONFIG_LIB80211 is not set ++# CONFIG_LIB80211_CRYPT_CCMP is not set ++# CONFIG_LIB80211_CRYPT_TKIP is not set ++# CONFIG_LIB80211_CRYPT_WEP is not set ++# CONFIG_LIB80211_DEBUG is not set ++# CONFIG_LIBCRC32C is not set ++# CONFIG_LIBERTAS is not set ++# CONFIG_LIBERTAS_THINFIRM is not set ++# CONFIG_LIBERTAS_USB is not set ++# CONFIG_LIBFC is not set ++# CONFIG_LIBFCOE is not set ++# CONFIG_LIBIPW_DEBUG is not set ++# CONFIG_LIBNVDIMM is not set ++# CONFIG_LIDAR_LITE_V2 is not set ++CONFIG_LINEAR_RANGES=y ++# CONFIG_LIQUIDIO is not set ++# CONFIG_LIQUIDIO_VF is not set ++# CONFIG_LIS3L02DQ is not set ++# CONFIG_LKDTM is not set ++CONFIG_LLC=y ++# CONFIG_LLC2 is not set ++# CONFIG_LMP91000 is not set ++# CONFIG_LNET is not set ++CONFIG_LOCALVERSION="" ++# CONFIG_LOCALVERSION_AUTO is not set ++# CONFIG_LOCKD is not set ++CONFIG_LOCKDEP_SUPPORT=y ++CONFIG_LOCKD_V4=y ++# CONFIG_LOCKUP_DETECTOR is not set ++# CONFIG_LOCK_EVENT_COUNTS is not set ++# CONFIG_LOCK_STAT is not set ++# CONFIG_LOCK_TORTURE_TEST is not set ++# CONFIG_LOGFS is not set ++# CONFIG_LOGIG940_FF is not set ++# CONFIG_LOGIRUMBLEPAD2_FF is not set ++# CONFIG_LOGITECH_FF is not set ++# CONFIG_LOGIWHEELS_FF is not set ++# CONFIG_LOGO is not set ++CONFIG_LOG_BUF_SHIFT=17 ++CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 ++# CONFIG_LOONGSON_MC146818 is not set ++# CONFIG_LPC_ICH is not set ++# CONFIG_LPC_SCH is not set ++# CONFIG_LP_CONSOLE is not set ++# CONFIG_LSI_ET1011C_PHY is not set ++CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity" ++CONFIG_LSM_MMAP_MIN_ADDR=65536 ++# CONFIG_LTC1660 is not set ++# CONFIG_LTC2471 is not set ++# CONFIG_LTC2485 is not set ++# CONFIG_LTC2496 is not set ++# CONFIG_LTC2497 is not set ++# CONFIG_LTC2632 is not set ++# CONFIG_LTC2983 is not set ++# CONFIG_LTE_GDM724X is not set ++# CONFIG_LTPC is not set ++# CONFIG_LTR501 is not set ++# CONFIG_LUSTRE_FS is not set ++# CONFIG_LV0104CS is not set ++# CONFIG_LWTUNNEL is not set ++# CONFIG_LXT_PHY is not set ++# CONFIG_LZ4HC_COMPRESS is not set ++# CONFIG_LZ4_COMPRESS is not set ++# CONFIG_LZ4_DECOMPRESS is not set ++CONFIG_LZMA_COMPRESS=y ++CONFIG_LZMA_DECOMPRESS=y ++# CONFIG_LZO_COMPRESS is not set ++# CONFIG_LZO_DECOMPRESS is not set ++# CONFIG_M62332 is not set ++# CONFIG_MAC80211 is not set ++# CONFIG_MAC80211_MESSAGE_TRACING is not set ++CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 ++# CONFIG_MACB is not set ++# CONFIG_MACH_ASM9260 is not set ++# CONFIG_MACH_DECSTATION is not set ++# CONFIG_MACH_INGENIC is not set ++# CONFIG_MACH_JAZZ is not set ++# CONFIG_MACH_JZ4740 is not set ++# CONFIG_MACH_LOONGSON32 is not set ++# CONFIG_MACH_LOONGSON64 is not set ++# CONFIG_MACH_PIC32 is not set ++# CONFIG_MACH_PISTACHIO is not set ++# CONFIG_MACH_TX39XX is not set ++# CONFIG_MACH_TX49XX is not set ++# CONFIG_MACH_VR41XX is not set ++# CONFIG_MACH_XILFPGA is not set ++# CONFIG_MACINTOSH_DRIVERS is not set ++# CONFIG_MACSEC is not set ++# CONFIG_MACVLAN is not set ++# CONFIG_MACVTAP is not set ++# CONFIG_MAC_EMUMOUSEBTN is not set ++# CONFIG_MAC_PARTITION is not set ++# CONFIG_MAG3110 is not set ++# CONFIG_MAGIC_SYSRQ is not set ++CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1 ++# CONFIG_MAGIC_SYSRQ_SERIAL is not set ++CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE="" ++# CONFIG_MAILBOX is not set ++# CONFIG_MANAGER_SBS is not set ++# CONFIG_MANDATORY_FILE_LOCKING is not set ++# CONFIG_MANGLE_BOOTARGS is not set ++# CONFIG_MARVELL_10G_PHY is not set ++# CONFIG_MARVELL_PHY is not set ++# CONFIG_MAX1027 is not set ++# CONFIG_MAX11100 is not set ++# CONFIG_MAX1118 is not set ++# CONFIG_MAX1241 is not set ++# CONFIG_MAX1363 is not set ++# CONFIG_MAX30100 is not set ++# CONFIG_MAX30102 is not set ++# CONFIG_MAX31856 is not set ++# CONFIG_MAX44000 is not set ++# CONFIG_MAX44009 is not set ++# CONFIG_MAX517 is not set ++# CONFIG_MAX5432 is not set ++# CONFIG_MAX5481 is not set ++# CONFIG_MAX5487 is not set ++# CONFIG_MAX5821 is not set ++# CONFIG_MAX63XX_WATCHDOG is not set ++# CONFIG_MAX9611 is not set ++# CONFIG_MAXIM_THERMOCOUPLE is not set ++CONFIG_MAY_USE_DEVLINK=y ++# CONFIG_MB1232 is not set ++# CONFIG_MC3230 is not set ++# CONFIG_MCB is not set ++# CONFIG_MCP320X is not set ++# CONFIG_MCP3422 is not set ++# CONFIG_MCP3911 is not set ++# CONFIG_MCP4018 is not set ++# CONFIG_MCP41010 is not set ++# CONFIG_MCP4131 is not set ++# CONFIG_MCP4531 is not set ++# CONFIG_MCP4725 is not set ++# CONFIG_MCP4922 is not set ++# CONFIG_MCPM is not set ++# CONFIG_MD is not set ++# CONFIG_MDIO_BCM_UNIMAC is not set ++# CONFIG_MDIO_BITBANG is not set ++# CONFIG_MDIO_BUS_MUX_GPIO is not set ++# CONFIG_MDIO_BUS_MUX_MMIOREG is not set ++# CONFIG_MDIO_BUS_MUX_MULTIPLEXER is not set ++# CONFIG_MDIO_DEVICE is not set ++CONFIG_MDIO_DEVRES=y ++# CONFIG_MDIO_HISI_FEMAC is not set ++# CONFIG_MDIO_IPQ4019 is not set ++# CONFIG_MDIO_IPQ8064 is not set ++# CONFIG_MDIO_MSCC_MIIM is not set ++# CONFIG_MDIO_MVUSB is not set ++# CONFIG_MDIO_OCTEON is not set ++# CONFIG_MDIO_THUNDER is not set ++# CONFIG_MDIO_XPCS is not set ++# CONFIG_MD_FAULTY is not set ++# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set ++# CONFIG_MEDIA_ATTACH is not set ++# CONFIG_MEDIA_CAMERA_SUPPORT is not set ++# CONFIG_MEDIA_CEC_SUPPORT is not set ++# CONFIG_MEDIA_CONTROLLER is not set ++# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set ++# CONFIG_MEDIA_PCI_SUPPORT is not set ++# CONFIG_MEDIA_PLATFORM_SUPPORT is not set ++# CONFIG_MEDIA_RADIO_SUPPORT is not set ++# CONFIG_MEDIA_RC_SUPPORT is not set ++# CONFIG_MEDIA_SDR_SUPPORT is not set ++# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set ++# CONFIG_MEDIA_SUPPORT is not set ++# CONFIG_MEDIA_SUPPORT_FILTER is not set ++# CONFIG_MEDIA_TEST_SUPPORT is not set ++# CONFIG_MEDIA_TUNER_E4000 is not set ++# CONFIG_MEDIA_TUNER_FC0011 is not set ++# CONFIG_MEDIA_TUNER_FC0012 is not set ++# CONFIG_MEDIA_TUNER_FC0013 is not set ++# CONFIG_MEDIA_TUNER_FC2580 is not set ++# CONFIG_MEDIA_TUNER_IT913X is not set ++# CONFIG_MEDIA_TUNER_M88RS6000T is not set ++# CONFIG_MEDIA_TUNER_MAX2165 is not set ++# CONFIG_MEDIA_TUNER_MC44S803 is not set ++# CONFIG_MEDIA_TUNER_MSI001 is not set ++# CONFIG_MEDIA_TUNER_MT2060 is not set ++# CONFIG_MEDIA_TUNER_MT2063 is not set ++# CONFIG_MEDIA_TUNER_MT20XX is not set ++# CONFIG_MEDIA_TUNER_MT2131 is not set ++# CONFIG_MEDIA_TUNER_MT2266 is not set ++# CONFIG_MEDIA_TUNER_MXL301RF is not set ++# CONFIG_MEDIA_TUNER_MXL5005S is not set ++# CONFIG_MEDIA_TUNER_MXL5007T is not set ++# CONFIG_MEDIA_TUNER_QM1D1B0004 is not set ++# CONFIG_MEDIA_TUNER_QM1D1C0042 is not set ++# CONFIG_MEDIA_TUNER_QT1010 is not set ++# CONFIG_MEDIA_TUNER_R820T is not set ++# CONFIG_MEDIA_TUNER_SI2157 is not set ++# CONFIG_MEDIA_TUNER_SIMPLE is not set ++# CONFIG_MEDIA_TUNER_TDA18212 is not set ++# CONFIG_MEDIA_TUNER_TDA18218 is not set ++# CONFIG_MEDIA_TUNER_TDA18250 is not set ++# CONFIG_MEDIA_TUNER_TDA18271 is not set ++# CONFIG_MEDIA_TUNER_TDA827X is not set ++# CONFIG_MEDIA_TUNER_TDA8290 is not set ++# CONFIG_MEDIA_TUNER_TDA9887 is not set ++# CONFIG_MEDIA_TUNER_TEA5761 is not set ++# CONFIG_MEDIA_TUNER_TEA5767 is not set ++# CONFIG_MEDIA_TUNER_TUA9001 is not set ++# CONFIG_MEDIA_TUNER_XC2028 is not set ++# CONFIG_MEDIA_TUNER_XC4000 is not set ++# CONFIG_MEDIA_TUNER_XC5000 is not set ++# CONFIG_MEDIA_USB_SUPPORT is not set ++# CONFIG_MEGARAID_LEGACY is not set ++# CONFIG_MEGARAID_NEWGEN is not set ++# CONFIG_MEGARAID_SAS is not set ++# CONFIG_MELLANOX_PLATFORM is not set ++CONFIG_MEMBARRIER=y ++# CONFIG_MEMORY is not set ++# CONFIG_MEMORY_FAILURE is not set ++# CONFIG_MEMORY_HOTPLUG is not set ++# CONFIG_MEMSTICK is not set ++# CONFIG_MEMTEST is not set ++# CONFIG_MEN_A21_WDT is not set ++# CONFIG_MESON_SM is not set ++CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 ++# CONFIG_MFD_88PM800 is not set ++# CONFIG_MFD_88PM805 is not set ++# CONFIG_MFD_88PM860X is not set ++# CONFIG_MFD_AAT2870_CORE is not set ++# CONFIG_MFD_AC100 is not set ++# CONFIG_MFD_ACT8945A is not set ++# CONFIG_MFD_ARIZONA_I2C is not set ++# CONFIG_MFD_ARIZONA_SPI is not set ++# CONFIG_MFD_AS3711 is not set ++# CONFIG_MFD_AS3722 is not set ++# CONFIG_MFD_ASIC3 is not set ++# CONFIG_MFD_ATMEL_FLEXCOM is not set ++# CONFIG_MFD_ATMEL_HLCDC is not set ++# CONFIG_MFD_AXP20X is not set ++# CONFIG_MFD_AXP20X_I2C is not set ++# CONFIG_MFD_BCM590XX is not set ++# CONFIG_MFD_BD9571MWV is not set ++# CONFIG_MFD_CORE is not set ++# CONFIG_MFD_CPCAP is not set ++# CONFIG_MFD_CROS_EC is not set ++# CONFIG_MFD_CS5535 is not set ++# CONFIG_MFD_DA9052_I2C is not set ++# CONFIG_MFD_DA9052_SPI is not set ++# CONFIG_MFD_DA9055 is not set ++# CONFIG_MFD_DA9062 is not set ++# CONFIG_MFD_DA9063 is not set ++# CONFIG_MFD_DA9150 is not set ++# CONFIG_MFD_DLN2 is not set ++# CONFIG_MFD_EXYNOS_LPASS is not set ++# CONFIG_MFD_GATEWORKS_GSC is not set ++# CONFIG_MFD_HI6421_PMIC is not set ++# CONFIG_MFD_INTEL_M10_BMC is not set ++# CONFIG_MFD_INTEL_QUARK_I2C_GPIO is not set ++# CONFIG_MFD_IQS62X is not set ++# CONFIG_MFD_JANZ_CMODIO is not set ++# CONFIG_MFD_KEMPLD is not set ++# CONFIG_MFD_LM3533 is not set ++# CONFIG_MFD_LOCHNAGAR is not set ++# CONFIG_MFD_LP3943 is not set ++# CONFIG_MFD_LP8788 is not set ++# CONFIG_MFD_MADERA is not set ++# CONFIG_MFD_MAX14577 is not set ++# CONFIG_MFD_MAX77620 is not set ++# CONFIG_MFD_MAX77650 is not set ++# CONFIG_MFD_MAX77686 is not set ++# CONFIG_MFD_MAX77693 is not set ++# CONFIG_MFD_MAX77843 is not set ++# CONFIG_MFD_MAX8907 is not set ++# CONFIG_MFD_MAX8925 is not set ++# CONFIG_MFD_MAX8997 is not set ++# CONFIG_MFD_MAX8998 is not set ++# CONFIG_MFD_MC13XXX is not set ++# CONFIG_MFD_MC13XXX_I2C is not set ++# CONFIG_MFD_MC13XXX_SPI is not set ++# CONFIG_MFD_MENF21BMC is not set ++# CONFIG_MFD_MP2629 is not set ++# CONFIG_MFD_MT6360 is not set ++# CONFIG_MFD_MT6397 is not set ++# CONFIG_MFD_OMAP_USB_HOST is not set ++# CONFIG_MFD_PALMAS is not set ++# CONFIG_MFD_PCF50633 is not set ++# CONFIG_MFD_PM8921_CORE is not set ++# CONFIG_MFD_PM8XXX is not set ++# CONFIG_MFD_RC5T583 is not set ++# CONFIG_MFD_RDC321X is not set ++# CONFIG_MFD_RETU is not set ++# CONFIG_MFD_RK808 is not set ++# CONFIG_MFD_RN5T618 is not set ++# CONFIG_MFD_ROHM_BD70528 is not set ++# CONFIG_MFD_ROHM_BD718XX is not set ++# CONFIG_MFD_RT5033 is not set ++# CONFIG_MFD_RTSX_PCI is not set ++# CONFIG_MFD_RTSX_USB is not set ++# CONFIG_MFD_SEC_CORE is not set ++# CONFIG_MFD_SI476X_CORE is not set ++# CONFIG_MFD_SKY81452 is not set ++# CONFIG_MFD_SM501 is not set ++# CONFIG_MFD_SMSC is not set ++# CONFIG_MFD_STMFX is not set ++# CONFIG_MFD_STMPE is not set ++# CONFIG_MFD_STPMIC1 is not set ++# CONFIG_MFD_SYSCON is not set ++# CONFIG_MFD_T7L66XB is not set ++# CONFIG_MFD_TC3589X is not set ++# CONFIG_MFD_TC6387XB is not set ++# CONFIG_MFD_TC6393XB is not set ++# CONFIG_MFD_TIMBERDALE is not set ++# CONFIG_MFD_TI_AM335X_TSCADC is not set ++# CONFIG_MFD_TI_LMU is not set ++# CONFIG_MFD_TI_LP873X is not set ++# CONFIG_MFD_TI_LP87565 is not set ++# CONFIG_MFD_TMIO is not set ++# CONFIG_MFD_TPS65086 is not set ++# CONFIG_MFD_TPS65090 is not set ++# CONFIG_MFD_TPS65217 is not set ++# CONFIG_MFD_TPS65218 is not set ++# CONFIG_MFD_TPS6586X is not set ++# CONFIG_MFD_TPS65910 is not set ++# CONFIG_MFD_TPS65912 is not set ++# CONFIG_MFD_TPS65912_I2C is not set ++# CONFIG_MFD_TPS65912_SPI is not set ++# CONFIG_MFD_TPS68470 is not set ++# CONFIG_MFD_TPS80031 is not set ++# CONFIG_MFD_TQMX86 is not set ++# CONFIG_MFD_VIPERBOARD is not set ++# CONFIG_MFD_VX855 is not set ++# CONFIG_MFD_WL1273_CORE is not set ++# CONFIG_MFD_WM831X is not set ++# CONFIG_MFD_WM831X_I2C is not set ++# CONFIG_MFD_WM831X_SPI is not set ++# CONFIG_MFD_WM8350_I2C is not set ++# CONFIG_MFD_WM8400 is not set ++# CONFIG_MFD_WM8994 is not set ++# CONFIG_MG_DISK is not set ++# CONFIG_MHI_BUS is not set ++# CONFIG_MICREL_KS8995MA is not set ++# CONFIG_MICREL_PHY is not set ++# CONFIG_MICROCHIP_KSZ is not set ++# CONFIG_MICROCHIP_PHY is not set ++# CONFIG_MICROCHIP_PIT64B is not set ++# CONFIG_MICROCHIP_T1_PHY is not set ++# CONFIG_MICROSEMI_PHY is not set ++# CONFIG_MIGRATION is not set ++CONFIG_MII=y ++# CONFIG_MIKROTIK is not set ++# CONFIG_MIKROTIK_RB532 is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set ++# CONFIG_MINIX_SUBPARTITION is not set ++# CONFIG_MIPS_ALCHEMY is not set ++# CONFIG_MIPS_CDMM is not set ++# CONFIG_MIPS_COBALT is not set ++# CONFIG_MIPS_FPU_EMULATOR is not set ++# CONFIG_MIPS_FP_SUPPORT is not set ++# CONFIG_MIPS_GENERIC is not set ++# CONFIG_MIPS_MALTA is not set ++# CONFIG_MIPS_O32_FP64_SUPPORT is not set ++# CONFIG_MIPS_PARAVIRT is not set ++# CONFIG_MIPS_PLATFORM_DEVICES is not set ++# CONFIG_MIPS_SEAD3 is not set ++# CONFIG_MISC_ALCOR_PCI is not set ++CONFIG_MISC_FILESYSTEMS=y ++# CONFIG_MISC_RTSX_PCI is not set ++# CONFIG_MISC_RTSX_USB is not set ++# CONFIG_MISDN is not set ++# CONFIG_MISDN_AVMFRITZ is not set ++# CONFIG_MISDN_HFCPCI is not set ++# CONFIG_MISDN_HFCUSB is not set ++# CONFIG_MISDN_INFINEON is not set ++# CONFIG_MISDN_NETJET is not set ++# CONFIG_MISDN_SPEEDFAX is not set ++# CONFIG_MISDN_W6692 is not set ++# CONFIG_MKISS is not set ++# CONFIG_MLX4_CORE is not set ++# CONFIG_MLX4_EN is not set ++# CONFIG_MLX5_CORE is not set ++# CONFIG_MLX90614 is not set ++# CONFIG_MLX90632 is not set ++# CONFIG_MLXFW is not set ++# CONFIG_MLXSW_CORE is not set ++# CONFIG_MLX_CPLD_PLATFORM is not set ++# CONFIG_MLX_PLATFORM is not set ++# CONFIG_MMA7455_I2C is not set ++# CONFIG_MMA7455_SPI is not set ++# CONFIG_MMA7660 is not set ++# CONFIG_MMA8452 is not set ++# CONFIG_MMA9551 is not set ++# CONFIG_MMA9553 is not set ++# CONFIG_MMC is not set ++# CONFIG_MMC35240 is not set ++# CONFIG_MMC_ARMMMCI is not set ++# CONFIG_MMC_AU1X is not set ++# CONFIG_MMC_BLOCK is not set ++CONFIG_MMC_BLOCK_BOUNCE=y ++CONFIG_MMC_BLOCK_MINORS=8 ++# CONFIG_MMC_CAVIUM_THUNDERX is not set ++# CONFIG_MMC_CB710 is not set ++# CONFIG_MMC_CQHCI is not set ++# CONFIG_MMC_DEBUG is not set ++# CONFIG_MMC_DW is not set ++# CONFIG_MMC_HSQ is not set ++# CONFIG_MMC_JZ4740 is not set ++# CONFIG_MMC_MTK is not set ++# CONFIG_MMC_MVSDIO is not set ++# CONFIG_MMC_S3C is not set ++# CONFIG_MMC_SDHCI is not set ++# CONFIG_MMC_SDHCI_ACPI is not set ++# CONFIG_MMC_SDHCI_AM654 is not set ++# CONFIG_MMC_SDHCI_BCM_KONA is not set ++# CONFIG_MMC_SDHCI_CADENCE is not set ++# CONFIG_MMC_SDHCI_F_SDH30 is not set ++# CONFIG_MMC_SDHCI_IPROC is not set ++# CONFIG_MMC_SDHCI_MILBEAUT is not set ++# CONFIG_MMC_SDHCI_MSM is not set ++# CONFIG_MMC_SDHCI_OF_ARASAN is not set ++# CONFIG_MMC_SDHCI_OF_ASPEED is not set ++# CONFIG_MMC_SDHCI_OF_AT91 is not set ++# CONFIG_MMC_SDHCI_OF_DWCMSHC is not set ++# CONFIG_MMC_SDHCI_OF_ESDHC is not set ++# CONFIG_MMC_SDHCI_OF_HLWD is not set ++# CONFIG_MMC_SDHCI_OMAP is not set ++# CONFIG_MMC_SDHCI_PXAV2 is not set ++# CONFIG_MMC_SDHCI_PXAV3 is not set ++# CONFIG_MMC_SDHCI_S3C is not set ++# CONFIG_MMC_SDHCI_XENON is not set ++# CONFIG_MMC_SDRICOH_CS is not set ++# CONFIG_MMC_SPI is not set ++# CONFIG_MMC_STM32_SDMMC is not set ++# CONFIG_MMC_TEST is not set ++# CONFIG_MMC_TOSHIBA_PCI is not set ++# CONFIG_MMC_USDHI6ROL0 is not set ++# CONFIG_MMC_USHC is not set ++# CONFIG_MMC_VIA_SDMMC is not set ++# CONFIG_MMC_VUB300 is not set ++# CONFIG_MMIOTRACE is not set ++CONFIG_MMU=y ++CONFIG_MMU_GATHER_RCU_TABLE_FREE=y ++CONFIG_MMU_GATHER_TABLE_FREE=y ++CONFIG_MODULES=y ++# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set ++# CONFIG_MODULE_COMPRESS is not set ++# CONFIG_MODULE_FORCE_LOAD is not set ++# CONFIG_MODULE_FORCE_UNLOAD is not set ++# CONFIG_MODULE_SIG is not set ++# CONFIG_MODULE_SRCVERSION_ALL is not set ++CONFIG_MODULE_STRIPPED=y ++CONFIG_MODULE_UNLOAD=y ++# CONFIG_MODVERSIONS is not set ++# CONFIG_MOST is not set ++# CONFIG_MOUSE_APPLETOUCH is not set ++# CONFIG_MOUSE_ELAN_I2C is not set ++# CONFIG_MOUSE_GPIO is not set ++# CONFIG_MOUSE_INPORT is not set ++# CONFIG_MOUSE_LOGIBM is not set ++# CONFIG_MOUSE_PC110PAD is not set ++# CONFIG_MOUSE_PS2_FOCALTECH is not set ++# CONFIG_MOUSE_PS2_SENTELIC is not set ++# CONFIG_MOUSE_SYNAPTICS_I2C is not set ++# CONFIG_MOUSE_SYNAPTICS_USB is not set ++# CONFIG_MOXTET is not set ++# CONFIG_MPL115 is not set ++# CONFIG_MPL115_I2C is not set ++# CONFIG_MPL115_SPI is not set ++# CONFIG_MPL3115 is not set ++# CONFIG_MPLS is not set ++# CONFIG_MPTCP is not set ++# CONFIG_MPU3050_I2C is not set ++# CONFIG_MQ_IOSCHED_DEADLINE is not set ++# CONFIG_MQ_IOSCHED_KYBER is not set ++# CONFIG_MS5611 is not set ++# CONFIG_MS5637 is not set ++# CONFIG_MSCC_OCELOT_SWITCH is not set ++# CONFIG_MSDOS_FS is not set ++CONFIG_MSDOS_PARTITION=y ++# CONFIG_MSI_BITMAP_SELFTEST is not set ++# CONFIG_MSI_LAPTOP is not set ++# CONFIG_MST_IRQ is not set ++CONFIG_MTD=y ++# CONFIG_MTD_ABSENT is not set ++# CONFIG_MTD_AFS_PARTS is not set ++# CONFIG_MTD_AR7_PARTS is not set ++CONFIG_MTD_BLKDEVS=y ++CONFIG_MTD_BLOCK=y ++# CONFIG_MTD_BLOCK2MTD is not set ++CONFIG_MTD_CFI=y ++# CONFIG_MTD_CFI_ADV_OPTIONS is not set ++CONFIG_MTD_CFI_AMDSTD=y ++# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set ++CONFIG_MTD_CFI_I1=y ++CONFIG_MTD_CFI_I2=y ++# CONFIG_MTD_CFI_I4 is not set ++# CONFIG_MTD_CFI_I8 is not set ++CONFIG_MTD_CFI_INTELEXT=y ++# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set ++CONFIG_MTD_CFI_NOSWAP=y ++# CONFIG_MTD_CFI_STAA is not set ++CONFIG_MTD_CFI_UTIL=y ++# CONFIG_MTD_CMDLINE_PARTS is not set ++CONFIG_MTD_COMPLEX_MAPPINGS=y ++# CONFIG_MTD_DATAFLASH is not set ++# CONFIG_MTD_DOCG3 is not set ++CONFIG_MTD_GEN_PROBE=y ++# CONFIG_MTD_GPIO_ADDR is not set ++# CONFIG_MTD_HYPERBUS is not set ++# CONFIG_MTD_IMPA7 is not set ++# CONFIG_MTD_INTEL_VR_NOR is not set ++# CONFIG_MTD_JEDECPROBE is not set ++# CONFIG_MTD_LATCH_ADDR is not set ++# CONFIG_MTD_LPDDR is not set ++# CONFIG_MTD_LPDDR2_NVM is not set ++# CONFIG_MTD_M25P80 is not set ++CONFIG_MTD_MAP_BANK_WIDTH_1=y ++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set ++CONFIG_MTD_MAP_BANK_WIDTH_2=y ++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set ++CONFIG_MTD_MAP_BANK_WIDTH_4=y ++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set ++# CONFIG_MTD_MCHP23K256 is not set ++# CONFIG_MTD_MT81xx_NOR is not set ++# CONFIG_MTD_MTDRAM is not set ++# CONFIG_MTD_MYLOADER_PARTS is not set ++# CONFIG_MTD_NAND is not set ++# CONFIG_MTD_NAND_AMS_DELTA is not set ++# CONFIG_MTD_NAND_AR934X is not set ++# CONFIG_MTD_NAND_AR934X_HW_ECC is not set ++# CONFIG_MTD_NAND_ARASAN is not set ++# CONFIG_MTD_NAND_ATMEL is not set ++# CONFIG_MTD_NAND_AU1550 is not set ++# CONFIG_MTD_NAND_BCH is not set ++# CONFIG_MTD_NAND_BF5XX is not set ++# CONFIG_MTD_NAND_BRCMNAND is not set ++# CONFIG_MTD_NAND_CADENCE is not set ++# CONFIG_MTD_NAND_CAFE is not set ++# CONFIG_MTD_NAND_CM_X270 is not set ++# CONFIG_MTD_NAND_CS553X is not set ++# CONFIG_MTD_NAND_DAVINCI is not set ++# CONFIG_MTD_NAND_DENALI is not set ++# CONFIG_MTD_NAND_DENALI_DT is not set ++# CONFIG_MTD_NAND_DENALI_PCI is not set ++CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xff108018 ++# CONFIG_MTD_NAND_DISKONCHIP is not set ++# CONFIG_MTD_NAND_DOCG4 is not set ++# CONFIG_MTD_NAND_ECC is not set ++# CONFIG_MTD_NAND_ECC_BCH is not set ++# CONFIG_MTD_NAND_ECC_SMC is not set ++# CONFIG_MTD_NAND_ECC_SW_BCH is not set ++# CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC is not set ++# CONFIG_MTD_NAND_FSL_ELBC is not set ++# CONFIG_MTD_NAND_FSL_IFC is not set ++# CONFIG_MTD_NAND_FSL_UPM is not set ++# CONFIG_MTD_NAND_FSMC is not set ++# CONFIG_MTD_NAND_GPIO is not set ++# CONFIG_MTD_NAND_GPMI_NAND is not set ++# CONFIG_MTD_NAND_HISI504 is not set ++CONFIG_MTD_NAND_IDS=y ++# CONFIG_MTD_NAND_JZ4740 is not set ++# CONFIG_MTD_NAND_MPC5121_NFC is not set ++# CONFIG_MTD_NAND_MTK is not set ++# CONFIG_MTD_NAND_MXC is not set ++# CONFIG_MTD_NAND_MXIC is not set ++# CONFIG_MTD_NAND_NANDSIM is not set ++# CONFIG_MTD_NAND_NDFC is not set ++# CONFIG_MTD_NAND_NUC900 is not set ++# CONFIG_MTD_NAND_OMAP2 is not set ++# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set ++# CONFIG_MTD_NAND_ORION is not set ++# CONFIG_MTD_NAND_PASEMI is not set ++# CONFIG_MTD_NAND_PLATFORM is not set ++# CONFIG_MTD_NAND_PXA3xx is not set ++# CONFIG_MTD_NAND_RB4XX is not set ++# CONFIG_MTD_NAND_RB750 is not set ++# CONFIG_MTD_NAND_RICOH is not set ++# CONFIG_MTD_NAND_S3C2410 is not set ++# CONFIG_MTD_NAND_SHARPSL is not set ++# CONFIG_MTD_NAND_SH_FLCTL is not set ++# CONFIG_MTD_NAND_SOCRATES is not set ++# CONFIG_MTD_NAND_TMIO is not set ++# CONFIG_MTD_NAND_TXX9NDFMC is not set ++CONFIG_MTD_OF_PARTS=y ++# CONFIG_MTD_ONENAND is not set ++# CONFIG_MTD_OOPS is not set ++# CONFIG_MTD_OTP is not set ++# CONFIG_MTD_PARTITIONED_MASTER is not set ++# CONFIG_MTD_PCI is not set ++# CONFIG_MTD_PCMCIA is not set ++# CONFIG_MTD_PHRAM is not set ++# CONFIG_MTD_PHYSMAP is not set ++# CONFIG_MTD_PHYSMAP_COMPAT is not set ++# CONFIG_MTD_PHYSMAP_GEMINI is not set ++# CONFIG_MTD_PHYSMAP_GPIO_ADDR is not set ++CONFIG_MTD_PHYSMAP_OF=y ++# CONFIG_MTD_PHYSMAP_OF_GEMINI is not set ++# CONFIG_MTD_PHYSMAP_OF_VERSATILE is not set ++# CONFIG_MTD_PHYSMAP_VERSATILE is not set ++# CONFIG_MTD_PLATRAM is not set ++# CONFIG_MTD_PMC551 is not set ++# CONFIG_MTD_RAM is not set ++# CONFIG_MTD_RAW_NAND is not set ++CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 ++# CONFIG_MTD_REDBOOT_PARTS is not set ++# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set ++# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set ++# CONFIG_MTD_ROM is not set ++CONFIG_MTD_ROOTFS_ROOT_DEV=y ++# CONFIG_MTD_ROUTERBOOT_PARTS is not set ++# CONFIG_MTD_SLRAM is not set ++# CONFIG_MTD_SM_COMMON is not set ++# CONFIG_MTD_SPINAND_MT29F is not set ++# CONFIG_MTD_SPI_NAND is not set ++# CONFIG_MTD_SPI_NOR is not set ++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set ++CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=4096 ++CONFIG_MTD_SPLIT=y ++# CONFIG_MTD_SPLIT_BCM_WFI_FW is not set ++# CONFIG_MTD_SPLIT_BRNIMAGE_FW is not set ++# CONFIG_MTD_SPLIT_ELF_FW is not set ++# CONFIG_MTD_SPLIT_EVA_FW is not set ++# CONFIG_MTD_SPLIT_FIRMWARE is not set ++CONFIG_MTD_SPLIT_FIRMWARE_NAME="firmware" ++# CONFIG_MTD_SPLIT_FIT_FW is not set ++# CONFIG_MTD_SPLIT_JIMAGE_FW is not set ++# CONFIG_MTD_SPLIT_LZMA_FW is not set ++# CONFIG_MTD_SPLIT_MINOR_FW is not set ++# CONFIG_MTD_SPLIT_SEAMA_FW is not set ++CONFIG_MTD_SPLIT_SQUASHFS_ROOT=y ++CONFIG_MTD_SPLIT_SUPPORT=y ++# CONFIG_MTD_SPLIT_TPLINK_FW is not set ++# CONFIG_MTD_SPLIT_TRX_FW is not set ++# CONFIG_MTD_SPLIT_UIMAGE_FW is not set ++# CONFIG_MTD_SPLIT_WRGG_FW is not set ++# CONFIG_MTD_SST25L is not set ++# CONFIG_MTD_SWAP is not set ++# CONFIG_MTD_TESTS is not set ++# CONFIG_MTD_UBI is not set ++# CONFIG_MTD_UBI_FASTMAP is not set ++# CONFIG_MTD_UBI_GLUEBI is not set ++# CONFIG_MTD_UIMAGE_SPLIT is not set ++# CONFIG_MTD_VIRT_CONCAT is not set ++# CONFIG_MTK_MMC is not set ++# CONFIG_MTK_MMSYS is not set ++CONFIG_MULTIUSER=y ++# CONFIG_MUTEX_SPIN_ON_OWNER is not set ++# CONFIG_MV643XX_ETH is not set ++# CONFIG_MVMDIO is not set ++# CONFIG_MVNETA_BM is not set ++# CONFIG_MVSW61XX_PHY is not set ++# CONFIG_MVSWITCH_PHY is not set ++# CONFIG_MV_XOR_V2 is not set ++# CONFIG_MWAVE is not set ++# CONFIG_MWL8K is not set ++# CONFIG_MXC4005 is not set ++# CONFIG_MXC6255 is not set ++# CONFIG_MYRI10GE is not set ++# CONFIG_NAMESPACES is not set ++# CONFIG_NATIONAL_PHY is not set ++# CONFIG_NATSEMI is not set ++# CONFIG_NAU7802 is not set ++# CONFIG_NBPFAXI_DMA is not set ++# CONFIG_NCP_FS is not set ++# CONFIG_NE2000 is not set ++# CONFIG_NE2K_PCI is not set ++# CONFIG_NEC_MARKEINS is not set ++CONFIG_NET=y ++# CONFIG_NETCONSOLE is not set ++CONFIG_NETDEVICES=y ++# CONFIG_NETDEVSIM is not set ++# CONFIG_NETFILTER is not set ++# CONFIG_NETFILTER_ADVANCED is not set ++# CONFIG_NETFILTER_DEBUG is not set ++# CONFIG_NETFILTER_INGRESS is not set ++# CONFIG_NETFILTER_NETLINK is not set ++# CONFIG_NETFILTER_NETLINK_ACCT is not set ++# CONFIG_NETFILTER_NETLINK_GLUE_CT is not set ++# CONFIG_NETFILTER_NETLINK_LOG is not set ++# CONFIG_NETFILTER_NETLINK_OSF is not set ++# CONFIG_NETFILTER_NETLINK_QUEUE is not set ++# CONFIG_NETFILTER_XTABLES is not set ++# CONFIG_NETFILTER_XT_CONNMARK is not set ++# CONFIG_NETFILTER_XT_MARK is not set ++# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set ++# CONFIG_NETFILTER_XT_MATCH_BPF is not set ++# CONFIG_NETFILTER_XT_MATCH_CGROUP is not set ++# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set ++# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set ++# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set ++# CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set ++# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set ++# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set ++# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set ++# CONFIG_NETFILTER_XT_MATCH_CPU is not set ++# CONFIG_NETFILTER_XT_MATCH_DCCP is not set ++# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set ++# CONFIG_NETFILTER_XT_MATCH_DSCP is not set ++# CONFIG_NETFILTER_XT_MATCH_ECN is not set ++# CONFIG_NETFILTER_XT_MATCH_ESP is not set ++# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set ++# CONFIG_NETFILTER_XT_MATCH_HELPER is not set ++# CONFIG_NETFILTER_XT_MATCH_HL is not set ++# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set ++# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set ++# CONFIG_NETFILTER_XT_MATCH_L2TP is not set ++# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set ++# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set ++# CONFIG_NETFILTER_XT_MATCH_MAC is not set ++# CONFIG_NETFILTER_XT_MATCH_MARK is not set ++# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set ++# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set ++# CONFIG_NETFILTER_XT_MATCH_OSF is not set ++# CONFIG_NETFILTER_XT_MATCH_OWNER is not set ++# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set ++# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set ++# CONFIG_NETFILTER_XT_MATCH_POLICY is not set ++# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set ++# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set ++# CONFIG_NETFILTER_XT_MATCH_REALM is not set ++# CONFIG_NETFILTER_XT_MATCH_RECENT is not set ++# CONFIG_NETFILTER_XT_MATCH_SCTP is not set ++# CONFIG_NETFILTER_XT_MATCH_SOCKET is not set ++# CONFIG_NETFILTER_XT_MATCH_STATE is not set ++# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set ++# CONFIG_NETFILTER_XT_MATCH_STRING is not set ++# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set ++# CONFIG_NETFILTER_XT_MATCH_TIME is not set ++# CONFIG_NETFILTER_XT_MATCH_U32 is not set ++# CONFIG_NETFILTER_XT_TARGET_AUDIT is not set ++# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set ++# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set ++# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set ++# CONFIG_NETFILTER_XT_TARGET_CT is not set ++# CONFIG_NETFILTER_XT_TARGET_DSCP is not set ++# CONFIG_NETFILTER_XT_TARGET_HL is not set ++# CONFIG_NETFILTER_XT_TARGET_HMARK is not set ++# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set ++# CONFIG_NETFILTER_XT_TARGET_LED is not set ++# CONFIG_NETFILTER_XT_TARGET_LOG is not set ++# CONFIG_NETFILTER_XT_TARGET_MARK is not set ++# CONFIG_NETFILTER_XT_TARGET_NETMAP is not set ++# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set ++# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set ++# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set ++# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set ++# CONFIG_NETFILTER_XT_TARGET_REDIRECT is not set ++# CONFIG_NETFILTER_XT_TARGET_SECMARK is not set ++# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set ++# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set ++# CONFIG_NETFILTER_XT_TARGET_TEE is not set ++# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set ++# CONFIG_NETFILTER_XT_TARGET_TRACE is not set ++# CONFIG_NETLABEL is not set ++# CONFIG_NETLINK_DIAG is not set ++# CONFIG_NETLINK_MMAP is not set ++# CONFIG_NETPOLL is not set ++# CONFIG_NETROM is not set ++CONFIG_NETWORK_FILESYSTEMS=y ++# CONFIG_NETWORK_PHY_TIMESTAMPING is not set ++# CONFIG_NETWORK_SECMARK is not set ++# CONFIG_NETXEN_NIC is not set ++# CONFIG_NET_9P is not set ++# CONFIG_NET_ACT_BPF is not set ++# CONFIG_NET_ACT_CSUM is not set ++# CONFIG_NET_ACT_CT is not set ++# CONFIG_NET_ACT_GACT is not set ++# CONFIG_NET_ACT_GATE is not set ++# CONFIG_NET_ACT_IFE is not set ++# CONFIG_NET_ACT_IPT is not set ++# CONFIG_NET_ACT_MIRRED is not set ++# CONFIG_NET_ACT_MPLS is not set ++# CONFIG_NET_ACT_NAT is not set ++# CONFIG_NET_ACT_PEDIT is not set ++# CONFIG_NET_ACT_POLICE is not set ++# CONFIG_NET_ACT_SAMPLE is not set ++# CONFIG_NET_ACT_SIMP is not set ++# CONFIG_NET_ACT_SKBEDIT is not set ++# CONFIG_NET_ACT_SKBMOD is not set ++# CONFIG_NET_ACT_TUNNEL_KEY is not set ++# CONFIG_NET_ACT_VLAN is not set ++CONFIG_NET_CADENCE=y ++# CONFIG_NET_CALXEDA_XGMAC is not set ++CONFIG_NET_CLS=y ++# CONFIG_NET_CLS_ACT is not set ++# CONFIG_NET_CLS_BASIC is not set ++# CONFIG_NET_CLS_BPF is not set ++# CONFIG_NET_CLS_FLOW is not set ++# CONFIG_NET_CLS_FLOWER is not set ++# CONFIG_NET_CLS_FW is not set ++CONFIG_NET_CLS_IND=y ++# CONFIG_NET_CLS_MATCHALL is not set ++# CONFIG_NET_CLS_ROUTE4 is not set ++# CONFIG_NET_CLS_RSVP is not set ++# CONFIG_NET_CLS_RSVP6 is not set ++# CONFIG_NET_CLS_TCINDEX is not set ++# CONFIG_NET_CLS_U32 is not set ++CONFIG_NET_CORE=y ++# CONFIG_NET_DEVLINK is not set ++# CONFIG_NET_DROP_MONITOR is not set ++# CONFIG_NET_DSA is not set ++# CONFIG_NET_DSA_AR9331 is not set ++# CONFIG_NET_DSA_BCM_SF2 is not set ++# CONFIG_NET_DSA_LANTIQ_GSWIP is not set ++# CONFIG_NET_DSA_LEGACY is not set ++# CONFIG_NET_DSA_LOOP is not set ++# CONFIG_NET_DSA_MICROCHIP_KSZ8795 is not set ++# CONFIG_NET_DSA_MICROCHIP_KSZ9477 is not set ++# CONFIG_NET_DSA_MSCC_SEVILLE is not set ++# CONFIG_NET_DSA_MT7530 is not set ++# CONFIG_NET_DSA_MV88E6060 is not set ++# CONFIG_NET_DSA_MV88E6123_61_65 is not set ++# CONFIG_NET_DSA_MV88E6131 is not set ++# CONFIG_NET_DSA_MV88E6171 is not set ++# CONFIG_NET_DSA_MV88E6352 is not set ++# CONFIG_NET_DSA_MV88E6XXX is not set ++# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set ++# CONFIG_NET_DSA_QCA8K is not set ++# CONFIG_NET_DSA_REALTEK_SMI is not set ++# CONFIG_NET_DSA_SJA1105 is not set ++# CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set ++# CONFIG_NET_DSA_SMSC_LAN9303_MDIO is not set ++# CONFIG_NET_DSA_TAG_8021Q is not set ++# CONFIG_NET_DSA_TAG_AR9331 is not set ++# CONFIG_NET_DSA_TAG_BRCM is not set ++# CONFIG_NET_DSA_TAG_BRCM_PREPEND is not set ++# CONFIG_NET_DSA_TAG_DSA is not set ++# CONFIG_NET_DSA_TAG_EDSA is not set ++# CONFIG_NET_DSA_TAG_GSWIP is not set ++# CONFIG_NET_DSA_TAG_KSZ is not set ++# CONFIG_NET_DSA_TAG_LAN9303 is not set ++# CONFIG_NET_DSA_TAG_MTK is not set ++# CONFIG_NET_DSA_TAG_OCELOT is not set ++# CONFIG_NET_DSA_TAG_QCA is not set ++# CONFIG_NET_DSA_TAG_RTL4_A is not set ++# CONFIG_NET_DSA_TAG_SJA1105 is not set ++# CONFIG_NET_DSA_TAG_TRAILER is not set ++# CONFIG_NET_DSA_VITESSE_VSC73XX is not set ++# CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM is not set ++# CONFIG_NET_DSA_VITESSE_VSC73XX_SPI is not set ++# CONFIG_NET_EMATCH is not set ++# CONFIG_NET_EMATCH_CANID is not set ++# CONFIG_NET_EMATCH_CMP is not set ++# CONFIG_NET_EMATCH_IPT is not set ++# CONFIG_NET_EMATCH_META is not set ++# CONFIG_NET_EMATCH_NBYTE is not set ++CONFIG_NET_EMATCH_STACK=32 ++# CONFIG_NET_EMATCH_TEXT is not set ++# CONFIG_NET_EMATCH_U32 is not set ++# CONFIG_NET_FAILOVER is not set ++# CONFIG_NET_FC is not set ++# CONFIG_NET_FOU is not set ++# CONFIG_NET_FOU_IP_TUNNELS is not set ++# CONFIG_NET_IFE is not set ++# CONFIG_NET_IPGRE is not set ++CONFIG_NET_IPGRE_BROADCAST=y ++# CONFIG_NET_IPGRE_DEMUX is not set ++# CONFIG_NET_IPIP is not set ++# CONFIG_NET_IPVTI is not set ++# CONFIG_NET_IP_TUNNEL is not set ++# CONFIG_NET_KEY is not set ++# CONFIG_NET_KEY_MIGRATE is not set ++# CONFIG_NET_L3_MASTER_DEV is not set ++# CONFIG_NET_MEDIATEK_STAR_EMAC is not set ++# CONFIG_NET_MPLS_GSO is not set ++# CONFIG_NET_NCSI is not set ++# CONFIG_NET_NSH is not set ++# CONFIG_NET_PACKET_ENGINE is not set ++# CONFIG_NET_PKTGEN is not set ++# CONFIG_NET_POLL_CONTROLLER is not set ++# CONFIG_NET_PTP_CLASSIFY is not set ++CONFIG_NET_RX_BUSY_POLL=y ++# CONFIG_NET_SB1000 is not set ++CONFIG_NET_SCHED=y ++# CONFIG_NET_SCH_ATM is not set ++# CONFIG_NET_SCH_CAKE is not set ++# CONFIG_NET_SCH_CBQ is not set ++# CONFIG_NET_SCH_CBS is not set ++# CONFIG_NET_SCH_CHOKE is not set ++# CONFIG_NET_SCH_CODEL is not set ++# CONFIG_NET_SCH_DEFAULT is not set ++# CONFIG_NET_SCH_DRR is not set ++# CONFIG_NET_SCH_DSMARK is not set ++# CONFIG_NET_SCH_ETF is not set ++# CONFIG_NET_SCH_ETS is not set ++CONFIG_NET_SCH_FIFO=y ++# CONFIG_NET_SCH_FQ is not set ++CONFIG_NET_SCH_FQ_CODEL=y ++# CONFIG_NET_SCH_FQ_PIE is not set ++# CONFIG_NET_SCH_GRED is not set ++# CONFIG_NET_SCH_HFSC is not set ++# CONFIG_NET_SCH_HHF is not set ++# CONFIG_NET_SCH_HTB is not set ++# CONFIG_NET_SCH_INGRESS is not set ++# CONFIG_NET_SCH_MQPRIO is not set ++# CONFIG_NET_SCH_MULTIQ is not set ++# CONFIG_NET_SCH_NETEM is not set ++# CONFIG_NET_SCH_PIE is not set ++# CONFIG_NET_SCH_PLUG is not set ++# CONFIG_NET_SCH_PRIO is not set ++# CONFIG_NET_SCH_QFQ is not set ++# CONFIG_NET_SCH_RED is not set ++# CONFIG_NET_SCH_SFB is not set ++# CONFIG_NET_SCH_SFQ is not set ++# CONFIG_NET_SCH_SKBPRIO is not set ++# CONFIG_NET_SCH_TAPRIO is not set ++# CONFIG_NET_SCH_TBF is not set ++# CONFIG_NET_SCH_TEQL is not set ++# CONFIG_NET_SCTPPROBE is not set ++# CONFIG_NET_SWITCHDEV is not set ++# CONFIG_NET_TCPPROBE is not set ++# CONFIG_NET_TC_SKB_EXT is not set ++# CONFIG_NET_TEAM is not set ++# CONFIG_NET_TULIP is not set ++# CONFIG_NET_UDP_TUNNEL is not set ++CONFIG_NET_VENDOR_3COM=y ++CONFIG_NET_VENDOR_8390=y ++CONFIG_NET_VENDOR_ADAPTEC=y ++CONFIG_NET_VENDOR_AGERE=y ++CONFIG_NET_VENDOR_ALACRITECH=y ++CONFIG_NET_VENDOR_ALTEON=y ++CONFIG_NET_VENDOR_AMAZON=y ++CONFIG_NET_VENDOR_AMD=y ++CONFIG_NET_VENDOR_AQUANTIA=y ++CONFIG_NET_VENDOR_ARC=y ++CONFIG_NET_VENDOR_ATHEROS=y ++CONFIG_NET_VENDOR_AURORA=y ++CONFIG_NET_VENDOR_BROADCOM=y ++CONFIG_NET_VENDOR_BROCADE=y ++CONFIG_NET_VENDOR_CADENCE=y ++CONFIG_NET_VENDOR_CAVIUM=y ++CONFIG_NET_VENDOR_CHELSIO=y ++CONFIG_NET_VENDOR_CIRRUS=y ++CONFIG_NET_VENDOR_CISCO=y ++CONFIG_NET_VENDOR_CORTINA=y ++CONFIG_NET_VENDOR_DEC=y ++CONFIG_NET_VENDOR_DLINK=y ++CONFIG_NET_VENDOR_EMULEX=y ++CONFIG_NET_VENDOR_EXAR=y ++CONFIG_NET_VENDOR_EZCHIP=y ++CONFIG_NET_VENDOR_FARADAY=y ++CONFIG_NET_VENDOR_FREESCALE=y ++CONFIG_NET_VENDOR_FUJITSU=y ++CONFIG_NET_VENDOR_GOOGLE=y ++CONFIG_NET_VENDOR_HISILICON=y ++CONFIG_NET_VENDOR_HP=y ++CONFIG_NET_VENDOR_HUAWEI=y ++CONFIG_NET_VENDOR_I825XX=y ++CONFIG_NET_VENDOR_IBM=y ++CONFIG_NET_VENDOR_INTEL=y ++CONFIG_NET_VENDOR_MARVELL=y ++CONFIG_NET_VENDOR_MELLANOX=y ++CONFIG_NET_VENDOR_MICREL=y ++CONFIG_NET_VENDOR_MICROCHIP=y ++CONFIG_NET_VENDOR_MICROSEMI=y ++CONFIG_NET_VENDOR_MYRI=y ++CONFIG_NET_VENDOR_NATSEMI=y ++CONFIG_NET_VENDOR_NETERION=y ++CONFIG_NET_VENDOR_NETRONOME=y ++CONFIG_NET_VENDOR_NI=y ++CONFIG_NET_VENDOR_NVIDIA=y ++CONFIG_NET_VENDOR_OKI=y ++CONFIG_NET_VENDOR_PACKET_ENGINES=y ++CONFIG_NET_VENDOR_PENSANDO=y ++CONFIG_NET_VENDOR_QLOGIC=y ++CONFIG_NET_VENDOR_QUALCOMM=y ++CONFIG_NET_VENDOR_RDC=y ++CONFIG_NET_VENDOR_REALTEK=y ++CONFIG_NET_VENDOR_RENESAS=y ++CONFIG_NET_VENDOR_ROCKER=y ++CONFIG_NET_VENDOR_SAMSUNG=y ++CONFIG_NET_VENDOR_SEEQ=y ++CONFIG_NET_VENDOR_SILAN=y ++CONFIG_NET_VENDOR_SIS=y ++CONFIG_NET_VENDOR_SMSC=y ++CONFIG_NET_VENDOR_SOCIONEXT=y ++CONFIG_NET_VENDOR_SOLARFLARE=y ++CONFIG_NET_VENDOR_STMICRO=y ++CONFIG_NET_VENDOR_SUN=y ++CONFIG_NET_VENDOR_SYNOPSYS=y ++CONFIG_NET_VENDOR_TEHUTI=y ++CONFIG_NET_VENDOR_TI=y ++CONFIG_NET_VENDOR_TOSHIBA=y ++CONFIG_NET_VENDOR_VIA=y ++CONFIG_NET_VENDOR_WIZNET=y ++CONFIG_NET_VENDOR_XILINX=y ++CONFIG_NET_VENDOR_XIRCOM=y ++# CONFIG_NET_VRF is not set ++# CONFIG_NET_XGENE is not set ++CONFIG_NEW_LEDS=y ++# CONFIG_NFC is not set ++# CONFIG_NFP is not set ++# CONFIG_NFSD is not set ++# CONFIG_NFSD_V2_ACL is not set ++CONFIG_NFSD_V3=y ++# CONFIG_NFSD_V3_ACL is not set ++# CONFIG_NFSD_V4 is not set ++# CONFIG_NFS_ACL_SUPPORT is not set ++CONFIG_NFS_COMMON=y ++# CONFIG_NFS_DISABLE_UDP_SUPPORT is not set ++# CONFIG_NFS_FS is not set ++# CONFIG_NFS_FSCACHE is not set ++# CONFIG_NFS_SWAP is not set ++# CONFIG_NFS_V2 is not set ++CONFIG_NFS_V3=y ++# CONFIG_NFS_V3_ACL is not set ++# CONFIG_NFS_V4 is not set ++# CONFIG_NFS_V4_1 is not set ++# CONFIG_NFTL is not set ++# CONFIG_NFT_BRIDGE_META is not set ++# CONFIG_NFT_BRIDGE_REJECT is not set ++# CONFIG_NFT_CONNLIMIT is not set ++# CONFIG_NFT_DUP_IPV4 is not set ++# CONFIG_NFT_DUP_IPV6 is not set ++# CONFIG_NFT_FIB_IPV4 is not set ++# CONFIG_NFT_FIB_IPV6 is not set ++# CONFIG_NFT_FIB_NETDEV is not set ++# CONFIG_NFT_FLOW_OFFLOAD is not set ++# CONFIG_NFT_OBJREF is not set ++# CONFIG_NFT_OSF is not set ++# CONFIG_NFT_RT is not set ++# CONFIG_NFT_SET_BITMAP is not set ++# CONFIG_NFT_SOCKET is not set ++# CONFIG_NFT_SYNPROXY is not set ++# CONFIG_NFT_TPROXY is not set ++# CONFIG_NFT_TUNNEL is not set ++# CONFIG_NFT_XFRM is not set ++# CONFIG_NF_CONNTRACK is not set ++# CONFIG_NF_CONNTRACK_AMANDA is not set ++# CONFIG_NF_CONNTRACK_BRIDGE is not set ++# CONFIG_NF_CONNTRACK_EVENTS is not set ++# CONFIG_NF_CONNTRACK_FTP is not set ++# CONFIG_NF_CONNTRACK_H323 is not set ++# CONFIG_NF_CONNTRACK_IPV4 is not set ++# CONFIG_NF_CONNTRACK_IPV6 is not set ++# CONFIG_NF_CONNTRACK_IRC is not set ++# CONFIG_NF_CONNTRACK_LABELS is not set ++# CONFIG_NF_CONNTRACK_MARK is not set ++# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set ++# CONFIG_NF_CONNTRACK_PPTP is not set ++CONFIG_NF_CONNTRACK_PROCFS=y ++# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set ++# CONFIG_NF_CONNTRACK_SANE is not set ++# CONFIG_NF_CONNTRACK_SECMARK is not set ++# CONFIG_NF_CONNTRACK_SIP is not set ++# CONFIG_NF_CONNTRACK_SNMP is not set ++# CONFIG_NF_CONNTRACK_TFTP is not set ++# CONFIG_NF_CONNTRACK_TIMEOUT is not set ++# CONFIG_NF_CONNTRACK_TIMESTAMP is not set ++# CONFIG_NF_CONNTRACK_ZONES is not set ++# CONFIG_NF_CT_NETLINK is not set ++# CONFIG_NF_CT_NETLINK_TIMEOUT is not set ++# CONFIG_NF_CT_NETLINK_HELPER is not set ++# CONFIG_NF_CT_PROTO_DCCP is not set ++# CONFIG_NF_CT_PROTO_GRE is not set ++# CONFIG_NF_CT_PROTO_SCTP is not set ++# CONFIG_NF_CT_PROTO_UDPLITE is not set ++# CONFIG_NF_DEFRAG_IPV4 is not set ++# CONFIG_NF_DUP_IPV4 is not set ++# CONFIG_NF_DUP_IPV6 is not set ++# CONFIG_NF_FLOW_TABLE is not set ++# CONFIG_NF_LOG_ARP is not set ++# CONFIG_NF_LOG_BRIDGE is not set ++# CONFIG_NF_LOG_IPV4 is not set ++# CONFIG_NF_LOG_NETDEV is not set ++# CONFIG_NF_NAT is not set ++# CONFIG_NF_NAT_AMANDA is not set ++# CONFIG_NF_NAT_FTP is not set ++# CONFIG_NF_NAT_H323 is not set ++# CONFIG_NF_NAT_IPV6 is not set ++# CONFIG_NF_NAT_IRC is not set ++CONFIG_NF_NAT_MASQUERADE_IPV4=y ++CONFIG_NF_NAT_MASQUERADE_IPV6=y ++# CONFIG_NF_NAT_NEEDED is not set ++# CONFIG_NF_NAT_PPTP is not set ++# CONFIG_NF_NAT_PROTO_GRE is not set ++# CONFIG_NF_NAT_SIP is not set ++# CONFIG_NF_NAT_SNMP_BASIC is not set ++# CONFIG_NF_NAT_TFTP is not set ++# CONFIG_NF_REJECT_IPV4 is not set ++# CONFIG_NF_REJECT_IPV6 is not set ++# CONFIG_NF_SOCKET_IPV4 is not set ++# CONFIG_NF_SOCKET_IPV6 is not set ++# CONFIG_NF_TABLES is not set ++CONFIG_NF_TABLES_ARP=y ++CONFIG_NF_TABLES_BRIDGE=y ++CONFIG_NF_TABLES_INET=y ++CONFIG_NF_TABLES_IPV4=y ++CONFIG_NF_TABLES_IPV6=y ++CONFIG_NF_TABLES_NETDEV=y ++# CONFIG_NF_TABLES_SET is not set ++# CONFIG_NF_TPROXY_IPV4 is not set ++# CONFIG_NF_TPROXY_IPV6 is not set ++# CONFIG_NI65 is not set ++# CONFIG_NI903X_WDT is not set ++# CONFIG_NIC7018_WDT is not set ++# CONFIG_NILFS2_FS is not set ++# CONFIG_NIU is not set ++# CONFIG_NI_XGE_MANAGEMENT_ENET is not set ++CONFIG_NLATTR=y ++# CONFIG_NLMON is not set ++# CONFIG_NLM_XLP_BOARD is not set ++# CONFIG_NLM_XLR_BOARD is not set ++# CONFIG_NLS is not set ++# CONFIG_NLS_ASCII is not set ++# CONFIG_NLS_CODEPAGE_1250 is not set ++# CONFIG_NLS_CODEPAGE_1251 is not set ++# CONFIG_NLS_CODEPAGE_437 is not set ++# CONFIG_NLS_CODEPAGE_737 is not set ++# CONFIG_NLS_CODEPAGE_775 is not set ++# CONFIG_NLS_CODEPAGE_850 is not set ++# CONFIG_NLS_CODEPAGE_852 is not set ++# CONFIG_NLS_CODEPAGE_855 is not set ++# CONFIG_NLS_CODEPAGE_857 is not set ++# CONFIG_NLS_CODEPAGE_860 is not set ++# CONFIG_NLS_CODEPAGE_861 is not set ++# CONFIG_NLS_CODEPAGE_862 is not set ++# CONFIG_NLS_CODEPAGE_863 is not set ++# CONFIG_NLS_CODEPAGE_864 is not set ++# CONFIG_NLS_CODEPAGE_865 is not set ++# CONFIG_NLS_CODEPAGE_866 is not set ++# CONFIG_NLS_CODEPAGE_869 is not set ++# CONFIG_NLS_CODEPAGE_874 is not set ++# CONFIG_NLS_CODEPAGE_932 is not set ++# CONFIG_NLS_CODEPAGE_936 is not set ++# CONFIG_NLS_CODEPAGE_949 is not set ++# CONFIG_NLS_CODEPAGE_950 is not set ++CONFIG_NLS_DEFAULT="iso8859-1" ++# CONFIG_NLS_ISO8859_1 is not set ++# CONFIG_NLS_ISO8859_13 is not set ++# CONFIG_NLS_ISO8859_14 is not set ++# CONFIG_NLS_ISO8859_15 is not set ++# CONFIG_NLS_ISO8859_2 is not set ++# CONFIG_NLS_ISO8859_3 is not set ++# CONFIG_NLS_ISO8859_4 is not set ++# CONFIG_NLS_ISO8859_5 is not set ++# CONFIG_NLS_ISO8859_6 is not set ++# CONFIG_NLS_ISO8859_7 is not set ++# CONFIG_NLS_ISO8859_8 is not set ++# CONFIG_NLS_ISO8859_9 is not set ++# CONFIG_NLS_KOI8_R is not set ++# CONFIG_NLS_KOI8_U is not set ++# CONFIG_NLS_MAC_CELTIC is not set ++# CONFIG_NLS_MAC_CENTEURO is not set ++# CONFIG_NLS_MAC_CROATIAN is not set ++# CONFIG_NLS_MAC_CYRILLIC is not set ++# CONFIG_NLS_MAC_GAELIC is not set ++# CONFIG_NLS_MAC_GREEK is not set ++# CONFIG_NLS_MAC_ICELAND is not set ++# CONFIG_NLS_MAC_INUIT is not set ++# CONFIG_NLS_MAC_ROMAN is not set ++# CONFIG_NLS_MAC_ROMANIAN is not set ++# CONFIG_NLS_MAC_TURKISH is not set ++# CONFIG_NLS_UTF8 is not set ++CONFIG_NMI_LOG_BUF_SHIFT=13 ++# CONFIG_NOA1305 is not set ++# CONFIG_NOP_USB_XCEIV is not set ++# CONFIG_NORTEL_HERMES is not set ++# CONFIG_NOTIFIER_ERROR_INJECTION is not set ++# CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT is not set ++# CONFIG_NOZOMI is not set ++# CONFIG_NO_BOOTMEM is not set ++# CONFIG_NO_HZ is not set ++# CONFIG_NO_HZ_FULL is not set ++# CONFIG_NO_HZ_IDLE is not set ++# CONFIG_NS83820 is not set ++# CONFIG_NTB is not set ++# CONFIG_NTFS_DEBUG is not set ++# CONFIG_NTFS_FS is not set ++# CONFIG_NTFS_RW is not set ++# CONFIG_NTP_PPS is not set ++# CONFIG_NULL_TTY is not set ++# CONFIG_NUMA is not set ++# CONFIG_NVM is not set ++# CONFIG_NVMEM is not set ++# CONFIG_NVMEM_BCM_OCOTP is not set ++# CONFIG_NVMEM_IMX_OCOTP is not set ++# CONFIG_NVMEM_REBOOT_MODE is not set ++# CONFIG_NVMEM_SYSFS is not set ++# CONFIG_NVME_FC is not set ++# CONFIG_NVME_TARGET is not set ++# CONFIG_NVRAM is not set ++# CONFIG_NV_TCO is not set ++# CONFIG_NXP_STB220 is not set ++# CONFIG_NXP_STB225 is not set ++# CONFIG_NXP_TJA11XX_PHY is not set ++# CONFIG_N_GSM is not set ++# CONFIG_OABI_COMPAT is not set ++# CONFIG_OBS600 is not set ++# CONFIG_OCFS2_FS is not set ++# CONFIG_OCTEONTX2_PF is not set ++# CONFIG_OF_OVERLAY is not set ++CONFIG_OF_RESERVED_MEM=y ++# CONFIG_OF_UNITTEST is not set ++# CONFIG_OMAP2_DSS_DEBUG is not set ++# CONFIG_OMAP2_DSS_DEBUGFS is not set ++# CONFIG_OMAP2_DSS_SDI is not set ++# CONFIG_OMAP_OCP2SCP is not set ++# CONFIG_OMAP_USB2 is not set ++# CONFIG_OMFS_FS is not set ++# CONFIG_OPENVSWITCH is not set ++# CONFIG_OPROFILE is not set ++# CONFIG_OPROFILE_EVENT_MULTIPLEX is not set ++# CONFIG_OPT3001 is not set ++CONFIG_OPTIMIZE_INLINING=y ++# CONFIG_ORANGEFS_FS is not set ++# CONFIG_ORION_WATCHDOG is not set ++# CONFIG_OSF_PARTITION is not set ++CONFIG_OVERLAY_FS=y ++# CONFIG_OVERLAY_FS_INDEX is not set ++# CONFIG_OVERLAY_FS_METACOPY is not set ++CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y ++# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set ++CONFIG_OVERLAY_FS_XINO_AUTO=y ++# CONFIG_OWL_LOADER is not set ++# CONFIG_P54_COMMON is not set ++# CONFIG_PA12203001 is not set ++CONFIG_PACKET=y ++# CONFIG_PACKET_DIAG is not set ++# CONFIG_PACKING is not set ++# CONFIG_PAGE_EXTENSION is not set ++# CONFIG_PAGE_OWNER is not set ++# CONFIG_PAGE_POISONING is not set ++# CONFIG_PAGE_REPORTING is not set ++# CONFIG_PAGE_SIZE_16KB is not set ++# CONFIG_PAGE_SIZE_32KB is not set ++CONFIG_PAGE_SIZE_4KB=y ++# CONFIG_PAGE_SIZE_64KB is not set ++# CONFIG_PAGE_SIZE_8KB is not set ++# CONFIG_PALMAS_GPADC is not set ++# CONFIG_PANASONIC_LAPTOP is not set ++# CONFIG_PANEL is not set ++CONFIG_PANIC_ON_OOPS=y ++CONFIG_PANIC_ON_OOPS_VALUE=1 ++CONFIG_PANIC_TIMEOUT=1 ++# CONFIG_PANTHERLORD_FF is not set ++# CONFIG_PARAVIRT is not set ++# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set ++# CONFIG_PARPORT is not set ++# CONFIG_PARPORT_1284 is not set ++# CONFIG_PARPORT_AX88796 is not set ++# CONFIG_PARPORT_GSC is not set ++# CONFIG_PARPORT_PC is not set ++CONFIG_PARTITION_ADVANCED=y ++# CONFIG_PATA_ALI is not set ++# CONFIG_PATA_AMD is not set ++# CONFIG_PATA_ARASAN_CF is not set ++# CONFIG_PATA_ARTOP is not set ++# CONFIG_PATA_ATIIXP is not set ++# CONFIG_PATA_ATP867X is not set ++# CONFIG_PATA_CMD640_PCI is not set ++# CONFIG_PATA_CMD64X is not set ++# CONFIG_PATA_CS5520 is not set ++# CONFIG_PATA_CS5530 is not set ++# CONFIG_PATA_CS5535 is not set ++# CONFIG_PATA_CS5536 is not set ++# CONFIG_PATA_CYPRESS is not set ++# CONFIG_PATA_EFAR is not set ++# CONFIG_PATA_HPT366 is not set ++# CONFIG_PATA_HPT37X is not set ++# CONFIG_PATA_HPT3X2N is not set ++# CONFIG_PATA_HPT3X3 is not set ++# CONFIG_PATA_IMX is not set ++# CONFIG_PATA_ISAPNP is not set ++# CONFIG_PATA_IT8213 is not set ++# CONFIG_PATA_IT821X is not set ++# CONFIG_PATA_JMICRON is not set ++# CONFIG_PATA_LEGACY is not set ++# CONFIG_PATA_MARVELL is not set ++# CONFIG_PATA_MPIIX is not set ++# CONFIG_PATA_NETCELL is not set ++# CONFIG_PATA_NINJA32 is not set ++# CONFIG_PATA_NS87410 is not set ++# CONFIG_PATA_NS87415 is not set ++# CONFIG_PATA_OCTEON_CF is not set ++# CONFIG_PATA_OF_PLATFORM is not set ++# CONFIG_PATA_OLDPIIX is not set ++# CONFIG_PATA_OPTI is not set ++# CONFIG_PATA_OPTIDMA is not set ++# CONFIG_PATA_PCMCIA is not set ++# CONFIG_PATA_PDC2027X is not set ++# CONFIG_PATA_PDC_OLD is not set ++# CONFIG_PATA_PLATFORM is not set ++# CONFIG_PATA_QDI is not set ++# CONFIG_PATA_RADISYS is not set ++# CONFIG_PATA_RDC is not set ++# CONFIG_PATA_RZ1000 is not set ++# CONFIG_PATA_SC1200 is not set ++# CONFIG_PATA_SCH is not set ++# CONFIG_PATA_SERVERWORKS is not set ++# CONFIG_PATA_SIL680 is not set ++# CONFIG_PATA_SIS is not set ++# CONFIG_PATA_TOSHIBA is not set ++# CONFIG_PATA_TRIFLEX is not set ++# CONFIG_PATA_VIA is not set ++# CONFIG_PATA_WINBOND is not set ++# CONFIG_PATA_WINBOND_VLB is not set ++# CONFIG_PC104 is not set ++# CONFIG_PC300TOO is not set ++# CONFIG_PCCARD is not set ++# CONFIG_PCH_DMA is not set ++# CONFIG_PCH_GBE is not set ++# CONFIG_PCH_PHUB is not set ++# CONFIG_PCI is not set ++# CONFIG_PCI200SYN is not set ++# CONFIG_PCIEAER is not set ++# CONFIG_PCIEAER_INJECT is not set ++# CONFIG_PCIEASPM is not set ++# CONFIG_PCIEPORTBUS is not set ++# CONFIG_PCIE_ALTERA is not set ++# CONFIG_PCIE_ARMADA_8K is not set ++# CONFIG_PCIE_BUS_DEFAULT is not set ++# CONFIG_PCIE_BUS_PEER2PEER is not set ++CONFIG_PCIE_BUS_PERFORMANCE=y ++# CONFIG_PCIE_BUS_SAFE is not set ++# CONFIG_PCIE_BUS_TUNE_OFF is not set ++# CONFIG_PCIE_BW is not set ++# CONFIG_PCIE_CADENCE_HOST is not set ++# CONFIG_PCIE_CADENCE_PLAT_HOST is not set ++# CONFIG_PCIE_DPC is not set ++# CONFIG_PCIE_DW_PLAT is not set ++# CONFIG_PCIE_DW_PLAT_HOST is not set ++# CONFIG_PCIE_ECRC is not set ++# CONFIG_PCIE_IPROC is not set ++# CONFIG_PCIE_KIRIN is not set ++# CONFIG_PCIE_LAYERSCAPE_GEN4 is not set ++# CONFIG_PCIE_PTM is not set ++# CONFIG_PCIE_XILINX is not set ++# CONFIG_PCIPCWATCHDOG is not set ++# CONFIG_PCI_ATMEL is not set ++# CONFIG_PCI_CNB20LE_QUIRK is not set ++# CONFIG_PCI_DEBUG is not set ++# CONFIG_PCI_DISABLE_COMMON_QUIRKS is not set ++# CONFIG_PCI_ENDPOINT is not set ++# CONFIG_PCI_ENDPOINT_TEST is not set ++# CONFIG_PCI_FTPCI100 is not set ++# CONFIG_PCI_HERMES is not set ++# CONFIG_PCI_HISI is not set ++# CONFIG_PCI_HOST_GENERIC is not set ++# CONFIG_PCI_HOST_THUNDER_ECAM is not set ++# CONFIG_PCI_HOST_THUNDER_PEM is not set ++# CONFIG_PCI_IOV is not set ++# CONFIG_PCI_J721E_HOST is not set ++# CONFIG_PCI_LAYERSCAPE is not set ++# CONFIG_PCI_MESON is not set ++# CONFIG_PCI_MSI is not set ++# CONFIG_PCI_PASID is not set ++# CONFIG_PCI_PF_STUB is not set ++# CONFIG_PCI_PRI is not set ++CONFIG_PCI_QUIRKS=y ++# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set ++# CONFIG_PCI_STUB is not set ++# CONFIG_PCI_SW_SWITCHTEC is not set ++CONFIG_PCI_SYSCALL=y ++# CONFIG_PCI_V3_SEMI is not set ++# CONFIG_PCI_XGENE is not set ++# CONFIG_PCMCIA is not set ++# CONFIG_PCMCIA_3C574 is not set ++# CONFIG_PCMCIA_3C589 is not set ++# CONFIG_PCMCIA_AHA152X is not set ++# CONFIG_PCMCIA_ATMEL is not set ++# CONFIG_PCMCIA_AXNET is not set ++# CONFIG_PCMCIA_DEBUG is not set ++# CONFIG_PCMCIA_FDOMAIN is not set ++# CONFIG_PCMCIA_FMVJ18X is not set ++# CONFIG_PCMCIA_HERMES is not set ++# CONFIG_PCMCIA_LOAD_CIS is not set ++# CONFIG_PCMCIA_NINJA_SCSI is not set ++# CONFIG_PCMCIA_NMCLAN is not set ++# CONFIG_PCMCIA_PCNET is not set ++# CONFIG_PCMCIA_QLOGIC is not set ++# CONFIG_PCMCIA_RAYCS is not set ++# CONFIG_PCMCIA_SMC91C92 is not set ++# CONFIG_PCMCIA_SPECTRUM is not set ++# CONFIG_PCMCIA_SYM53C500 is not set ++# CONFIG_PCMCIA_WL3501 is not set ++# CONFIG_PCMCIA_XIRC2PS is not set ++# CONFIG_PCMCIA_XIRCOM is not set ++# CONFIG_PCNET32 is not set ++# CONFIG_PCSPKR_PLATFORM is not set ++# CONFIG_PCS_XPCS is not set ++# CONFIG_PD6729 is not set ++# CONFIG_PDA_POWER is not set ++# CONFIG_PDC_ADMA is not set ++# CONFIG_PERCPU_STATS is not set ++# CONFIG_PERCPU_TEST is not set ++# CONFIG_PERF_EVENTS is not set ++# CONFIG_PERF_EVENTS_AMD_POWER is not set ++# CONFIG_PERSISTENT_KEYRINGS is not set ++# CONFIG_PHANTOM is not set ++# CONFIG_PHONET is not set ++# CONFIG_PHYLIB is not set ++# CONFIG_PHYS_ADDR_T_64BIT is not set ++# CONFIG_PHY_CADENCE_DP is not set ++# CONFIG_PHY_CADENCE_DPHY is not set ++# CONFIG_PHY_CADENCE_SALVO is not set ++# CONFIG_PHY_CADENCE_SIERRA is not set ++# CONFIG_PHY_CADENCE_TORRENT is not set ++# CONFIG_PHY_CPCAP_USB is not set ++# CONFIG_PHY_EXYNOS_DP_VIDEO is not set ++# CONFIG_PHY_EXYNOS_MIPI_VIDEO is not set ++# CONFIG_PHY_FSL_IMX8MQ_USB is not set ++# CONFIG_PHY_INTEL_KEEMBAY_EMMC is not set ++# CONFIG_PHY_MAPPHONE_MDM6600 is not set ++# CONFIG_PHY_MIXEL_MIPI_DPHY is not set ++# CONFIG_PHY_MTK_HDMI is not set ++# CONFIG_PHY_OCELOT_SERDES is not set ++# CONFIG_PHY_PXA_28NM_HSIC is not set ++# CONFIG_PHY_PXA_28NM_USB2 is not set ++# CONFIG_PHY_QCOM_DWC3 is not set ++# CONFIG_PHY_QCOM_USB_HS is not set ++# CONFIG_PHY_QCOM_USB_HSIC is not set ++# CONFIG_PHY_SAMSUNG_USB2 is not set ++# CONFIG_PHY_TUSB1210 is not set ++# CONFIG_PHY_XGENE is not set ++# CONFIG_PI433 is not set ++# CONFIG_PID_IN_CONTEXTIDR is not set ++# CONFIG_PID_NS is not set ++CONFIG_PINCONF=y ++# CONFIG_PINCTRL is not set ++# CONFIG_PINCTRL_AMD is not set ++# CONFIG_PINCTRL_AXP209 is not set ++# CONFIG_PINCTRL_CEDARFORK is not set ++# CONFIG_PINCTRL_EXYNOS is not set ++# CONFIG_PINCTRL_EXYNOS5440 is not set ++# CONFIG_PINCTRL_ICELAKE is not set ++# CONFIG_PINCTRL_INGENIC is not set ++# CONFIG_PINCTRL_MCP23S08 is not set ++# CONFIG_PINCTRL_MSM8X74 is not set ++# CONFIG_PINCTRL_MT6779 is not set ++# CONFIG_PINCTRL_MT8167 is not set ++# CONFIG_PINCTRL_MT8192 is not set ++# CONFIG_PINCTRL_MTK_V2 is not set ++# CONFIG_PINCTRL_OCELOT is not set ++CONFIG_PINCTRL_SINGLE=y ++# CONFIG_PINCTRL_STMFX is not set ++# CONFIG_PINCTRL_SX150X is not set ++# CONFIG_PING is not set ++CONFIG_PINMUX=y ++# CONFIG_PKCS7_MESSAGE_PARSER is not set ++# CONFIG_PL310_ERRATA_588369 is not set ++# CONFIG_PL310_ERRATA_727915 is not set ++# CONFIG_PL310_ERRATA_753970 is not set ++# CONFIG_PL310_ERRATA_769419 is not set ++# CONFIG_PL320_MBOX is not set ++# CONFIG_PL330_DMA is not set ++# CONFIG_PLATFORM_MHU is not set ++# CONFIG_PLAT_SPEAR is not set ++# CONFIG_PLIP is not set ++CONFIG_PLUGIN_HOSTCC="" ++# CONFIG_PLX_DMA is not set ++# CONFIG_PLX_HERMES is not set ++# CONFIG_PM is not set ++# CONFIG_PMBUS is not set ++# CONFIG_PMC_MSP is not set ++# CONFIG_PMIC_ADP5520 is not set ++# CONFIG_PMIC_DA903X is not set ++# CONFIG_PMS7003 is not set ++# CONFIG_PM_AUTOSLEEP is not set ++# CONFIG_PM_DEBUG is not set ++# CONFIG_PM_DEVFREQ is not set ++# CONFIG_PM_WAKELOCKS is not set ++# CONFIG_POSIX_MQUEUE is not set ++CONFIG_POSIX_TIMERS=y ++# CONFIG_POWERCAP is not set ++# CONFIG_POWER_AVS is not set ++# CONFIG_POWER_RESET is not set ++# CONFIG_POWER_RESET_BRCMKONA is not set ++# CONFIG_POWER_RESET_BRCMSTB is not set ++# CONFIG_POWER_RESET_GPIO is not set ++# CONFIG_POWER_RESET_GPIO_RESTART is not set ++# CONFIG_POWER_RESET_LTC2952 is not set ++# CONFIG_POWER_RESET_PIIX4_POWEROFF is not set ++# CONFIG_POWER_RESET_RESTART is not set ++# CONFIG_POWER_RESET_SYSCON is not set ++# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set ++# CONFIG_POWER_RESET_VERSATILE is not set ++# CONFIG_POWER_RESET_XGENE is not set ++# CONFIG_POWER_SUPPLY is not set ++# CONFIG_POWER_SUPPLY_DEBUG is not set ++# CONFIG_POWER_SUPPLY_HWMON is not set ++# CONFIG_PPC4xx_GPIO is not set ++# CONFIG_PPC_16K_PAGES is not set ++# CONFIG_PPC_256K_PAGES is not set ++CONFIG_PPC_4K_PAGES=y ++# CONFIG_PPC_64K_PAGES is not set ++# CONFIG_PPC_DISABLE_WERROR is not set ++# CONFIG_PPC_EMULATED_STATS is not set ++# CONFIG_PPC_EPAPR_HV_BYTECHAN is not set ++# CONFIG_PPP is not set ++# CONFIG_PPPOATM is not set ++# CONFIG_PPPOE is not set ++# CONFIG_PPPOL2TP is not set ++# CONFIG_PPP_ASYNC is not set ++# CONFIG_PPP_BSDCOMP is not set ++# CONFIG_PPP_DEFLATE is not set ++CONFIG_PPP_FILTER=y ++# CONFIG_PPP_MPPE is not set ++CONFIG_PPP_MULTILINK=y ++# CONFIG_PPP_SYNC_TTY is not set ++# CONFIG_PPS is not set ++# CONFIG_PPS_CLIENT_GPIO is not set ++# CONFIG_PPS_CLIENT_KTIMER is not set ++# CONFIG_PPS_CLIENT_LDISC is not set ++# CONFIG_PPS_CLIENT_PARPORT is not set ++# CONFIG_PPS_DEBUG is not set ++# CONFIG_PPTP is not set ++# CONFIG_PREEMPT is not set ++# CONFIG_PREEMPTIRQ_DELAY_TEST is not set ++# CONFIG_PREEMPTIRQ_EVENTS is not set ++CONFIG_PREEMPT_NONE=y ++# CONFIG_PREEMPT_TRACER is not set ++# CONFIG_PREEMPT_VOLUNTARY is not set ++# CONFIG_PRESTERA is not set ++CONFIG_PREVENT_FIRMWARE_BUILD=y ++# CONFIG_PRIME_NUMBERS is not set ++CONFIG_PRINTK=y ++# CONFIG_PRINTK_CALLER is not set ++CONFIG_PRINTK_NMI=y ++CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13 ++# CONFIG_PRINTK_TIME is not set ++CONFIG_PRINT_STACK_DEPTH=64 ++# CONFIG_PRISM2_USB is not set ++# CONFIG_PRISM54 is not set ++# CONFIG_PROC_CHILDREN is not set ++CONFIG_PROC_FS=y ++# CONFIG_PROC_KCORE is not set ++# CONFIG_PROC_PAGE_MONITOR is not set ++# CONFIG_PROC_STRIPPED is not set ++CONFIG_PROC_SYSCTL=y ++# CONFIG_PROC_VMCORE_DEVICE_DUMP is not set ++# CONFIG_PROFILE_ALL_BRANCHES is not set ++# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set ++# CONFIG_PROFILING is not set ++# CONFIG_PROVE_LOCKING is not set ++# CONFIG_PROVE_RCU is not set ++# CONFIG_PROVE_RCU_LIST is not set ++# CONFIG_PROVE_RCU_REPEATEDLY is not set ++# CONFIG_PSAMPLE is not set ++# CONFIG_PSB6970_PHY is not set ++# CONFIG_PSI is not set ++# CONFIG_PSTORE is not set ++# CONFIG_PTDUMP_DEBUGFS is not set ++# CONFIG_PTP_1588_CLOCK is not set ++# CONFIG_PTP_1588_CLOCK_IDT82P33 is not set ++# CONFIG_PTP_1588_CLOCK_IDTCM is not set ++# CONFIG_PTP_1588_CLOCK_IXP46X is not set ++# CONFIG_PTP_1588_CLOCK_KVM is not set ++# CONFIG_PTP_1588_CLOCK_PCH is not set ++# CONFIG_PUBLIC_KEY_ALGO_RSA is not set ++# CONFIG_PVPANIC is not set ++# CONFIG_PWM is not set ++# CONFIG_PWM_DEBUG is not set ++# CONFIG_PWM_FSL_FTM is not set ++# CONFIG_PWM_PCA9685 is not set ++CONFIG_PWRSEQ_EMMC=y ++# CONFIG_PWRSEQ_SD8787 is not set ++CONFIG_PWRSEQ_SIMPLE=y ++# CONFIG_QCA7000 is not set ++# CONFIG_QCA7000_SPI is not set ++# CONFIG_QCA7000_UART is not set ++# CONFIG_QCOM_EMAC is not set ++# CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set ++# CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set ++# CONFIG_QCOM_FALKOR_ERRATUM_E1041 is not set ++# CONFIG_QCOM_HIDMA is not set ++# CONFIG_QCOM_HIDMA_MGMT is not set ++# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set ++# CONFIG_QCOM_SPMI_ADC5 is not set ++# CONFIG_QCOM_SPMI_IADC is not set ++# CONFIG_QCOM_SPMI_TEMP_ALARM is not set ++# CONFIG_QCOM_SPMI_VADC is not set ++# CONFIG_QED is not set ++# CONFIG_QLA3XXX is not set ++# CONFIG_QLCNIC is not set ++# CONFIG_QLGE is not set ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_QNX6FS_FS is not set ++# CONFIG_QORIQ_CPUFREQ is not set ++# CONFIG_QORIQ_THERMAL is not set ++# CONFIG_QRTR is not set ++# CONFIG_QSEMI_PHY is not set ++# CONFIG_QUEUED_LOCK_STAT is not set ++# CONFIG_QUICC_ENGINE is not set ++# CONFIG_QUOTA is not set ++# CONFIG_QUOTACTL is not set ++# CONFIG_QUOTA_DEBUG is not set ++# CONFIG_R3964 is not set ++# CONFIG_R6040 is not set ++# CONFIG_R8169 is not set ++# CONFIG_R8188EU is not set ++# CONFIG_R8712U is not set ++# CONFIG_R8723AU is not set ++# CONFIG_RADIO_ADAPTERS is not set ++# CONFIG_RADIO_AZTECH is not set ++# CONFIG_RADIO_CADET is not set ++# CONFIG_RADIO_GEMTEK is not set ++# CONFIG_RADIO_MAXIRADIO is not set ++# CONFIG_RADIO_RTRACK is not set ++# CONFIG_RADIO_RTRACK2 is not set ++# CONFIG_RADIO_SF16FMI is not set ++# CONFIG_RADIO_SF16FMR2 is not set ++# CONFIG_RADIO_TERRATEC is not set ++# CONFIG_RADIO_TRUST is not set ++# CONFIG_RADIO_TYPHOON is not set ++# CONFIG_RADIO_ZOLTRIX is not set ++# CONFIG_RAID6_PQ_BENCHMARK is not set ++# CONFIG_RAID_ATTRS is not set ++# CONFIG_RALINK is not set ++# CONFIG_RANDOM32_SELFTEST is not set ++# CONFIG_RANDOMIZE_BASE is not set ++# CONFIG_RANDOM_TRUST_BOOTLOADER is not set ++# CONFIG_RANDOM_TRUST_CPU is not set ++# CONFIG_RAPIDIO is not set ++# CONFIG_RAS is not set ++# CONFIG_RAW_DRIVER is not set ++# CONFIG_RBTREE_TEST is not set ++# CONFIG_RCU_BOOST is not set ++CONFIG_RCU_CPU_STALL_TIMEOUT=60 ++# CONFIG_RCU_EQS_DEBUG is not set ++# CONFIG_RCU_EXPEDITE_BOOT is not set ++CONFIG_RCU_EXPERT=y ++CONFIG_RCU_FANOUT=32 ++CONFIG_RCU_FANOUT_LEAF=16 ++# CONFIG_RCU_FAST_NO_HZ is not set ++CONFIG_RCU_KTHREAD_PRIO=0 ++# CONFIG_RCU_NOCB_CPU is not set ++# CONFIG_RCU_PERF_TEST is not set ++# CONFIG_RCU_REF_SCALE_TEST is not set ++# CONFIG_RCU_SCALE_TEST is not set ++# CONFIG_RCU_STRICT_GRACE_PERIOD is not set ++# CONFIG_RCU_TORTURE_TEST is not set ++CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY=3 ++# CONFIG_RCU_TRACE is not set ++# CONFIG_RC_ATI_REMOTE is not set ++# CONFIG_RC_CORE is not set ++# CONFIG_RC_DECODERS is not set ++# CONFIG_RC_LOOPBACK is not set ++# CONFIG_RC_MAP is not set ++# CONFIG_RDS is not set ++# CONFIG_RD_BZIP2 is not set ++# CONFIG_RD_GZIP is not set ++# CONFIG_RD_LZ4 is not set ++# CONFIG_RD_LZMA is not set ++# CONFIG_RD_LZO is not set ++# CONFIG_RD_XZ is not set ++# CONFIG_RD_ZSTD is not set ++# CONFIG_READABLE_ASM is not set ++# CONFIG_READ_ONLY_THP_FOR_FS is not set ++# CONFIG_REALTEK_PHY is not set ++# CONFIG_REDWOOD is not set ++# CONFIG_REED_SOLOMON_TEST is not set ++# CONFIG_REFCOUNT_FULL is not set ++# CONFIG_REGMAP is not set ++# CONFIG_REGMAP_I2C is not set ++# CONFIG_REGMAP_MMIO is not set ++# CONFIG_REGMAP_SPI is not set ++# CONFIG_REGULATOR is not set ++# CONFIG_REGULATOR_88PG86X is not set ++# CONFIG_REGULATOR_ACT8865 is not set ++# CONFIG_REGULATOR_AD5398 is not set ++# CONFIG_REGULATOR_ANATOP is not set ++# CONFIG_REGULATOR_DA9210 is not set ++# CONFIG_REGULATOR_DA9211 is not set ++# CONFIG_REGULATOR_DEBUG is not set ++# CONFIG_REGULATOR_FAN53555 is not set ++# CONFIG_REGULATOR_FAN53880 is not set ++# CONFIG_REGULATOR_FIXED_VOLTAGE is not set ++# CONFIG_REGULATOR_GPIO is not set ++# CONFIG_REGULATOR_ISL6271A is not set ++# CONFIG_REGULATOR_ISL9305 is not set ++# CONFIG_REGULATOR_LP3971 is not set ++# CONFIG_REGULATOR_LP3972 is not set ++# CONFIG_REGULATOR_LP872X is not set ++# CONFIG_REGULATOR_LP8755 is not set ++# CONFIG_REGULATOR_LTC3589 is not set ++# CONFIG_REGULATOR_LTC3676 is not set ++# CONFIG_REGULATOR_MAX1586 is not set ++# CONFIG_REGULATOR_MAX77826 is not set ++# CONFIG_REGULATOR_MAX8649 is not set ++# CONFIG_REGULATOR_MAX8660 is not set ++# CONFIG_REGULATOR_MAX8952 is not set ++# CONFIG_REGULATOR_MAX8973 is not set ++# CONFIG_REGULATOR_MCP16502 is not set ++# CONFIG_REGULATOR_MP5416 is not set ++# CONFIG_REGULATOR_MP8859 is not set ++# CONFIG_REGULATOR_MP886X is not set ++# CONFIG_REGULATOR_MPQ7920 is not set ++# CONFIG_REGULATOR_MT6311 is not set ++# CONFIG_REGULATOR_PCA9450 is not set ++# CONFIG_REGULATOR_PFUZE100 is not set ++# CONFIG_REGULATOR_PV88060 is not set ++# CONFIG_REGULATOR_PV88080 is not set ++# CONFIG_REGULATOR_PV88090 is not set ++# CONFIG_REGULATOR_PWM is not set ++# CONFIG_REGULATOR_SLG51000 is not set ++# CONFIG_REGULATOR_SY8106A is not set ++# CONFIG_REGULATOR_SY8824X is not set ++# CONFIG_REGULATOR_SY8827N is not set ++# CONFIG_REGULATOR_TI_ABB is not set ++# CONFIG_REGULATOR_TPS51632 is not set ++# CONFIG_REGULATOR_TPS62360 is not set ++# CONFIG_REGULATOR_TPS65023 is not set ++# CONFIG_REGULATOR_TPS6507X is not set ++# CONFIG_REGULATOR_TPS65132 is not set ++# CONFIG_REGULATOR_TPS6524X is not set ++# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set ++# CONFIG_REGULATOR_VCTRL is not set ++# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set ++# CONFIG_REISERFS_CHECK is not set ++# CONFIG_REISERFS_FS is not set ++# CONFIG_REISERFS_FS_POSIX_ACL is not set ++# CONFIG_REISERFS_FS_SECURITY is not set ++CONFIG_REISERFS_FS_XATTR=y ++# CONFIG_REISERFS_PROC_INFO is not set ++# CONFIG_RELAY is not set ++# CONFIG_RELOCATABLE is not set ++# CONFIG_REMOTEPROC is not set ++# CONFIG_RENESAS_PHY is not set ++# CONFIG_RESET_ATH79 is not set ++# CONFIG_RESET_BERLIN is not set ++# CONFIG_RESET_BRCMSTB_RESCAL is not set ++# CONFIG_RESET_CONTROLLER is not set ++# CONFIG_RESET_IMX7 is not set ++# CONFIG_RESET_INTEL_GW is not set ++# CONFIG_RESET_LANTIQ is not set ++# CONFIG_RESET_LPC18XX is not set ++# CONFIG_RESET_MESON is not set ++# CONFIG_RESET_PISTACHIO is not set ++# CONFIG_RESET_SOCFPGA is not set ++# CONFIG_RESET_STM32 is not set ++# CONFIG_RESET_SUNXI is not set ++# CONFIG_RESET_TEGRA_BPMP is not set ++# CONFIG_RESET_TI_SYSCON is not set ++# CONFIG_RESET_ZYNQ is not set ++# CONFIG_RFD77402 is not set ++# CONFIG_RFD_FTL is not set ++CONFIG_RFKILL=y ++# CONFIG_RFKILL_FULL is not set ++# CONFIG_RFKILL_GPIO is not set ++# CONFIG_RFKILL_INPUT is not set ++# CONFIG_RFKILL_LEDS is not set ++# CONFIG_RFKILL_REGULATOR is not set ++# CONFIG_RING_BUFFER_BENCHMARK is not set ++# CONFIG_RING_BUFFER_STARTUP_TEST is not set ++# CONFIG_RMI4_CORE is not set ++# CONFIG_RMNET is not set ++# CONFIG_ROCKCHIP_PHY is not set ++# CONFIG_ROCKER is not set ++# CONFIG_ROMFS_FS is not set ++# CONFIG_ROSE is not set ++# CONFIG_RPCSEC_GSS_KRB5 is not set ++# CONFIG_RPMSG_QCOM_GLINK_RPM is not set ++# CONFIG_RPMSG_VIRTIO is not set ++# CONFIG_RPR0521 is not set ++# CONFIG_RSEQ is not set ++# CONFIG_RT2X00 is not set ++# CONFIG_RTC_CLASS is not set ++# CONFIG_RTC_DEBUG is not set ++# CONFIG_RTC_DRV_ABB5ZES3 is not set ++# CONFIG_RTC_DRV_ABEOZ9 is not set ++# CONFIG_RTC_DRV_ABX80X is not set ++# CONFIG_RTC_DRV_ARMADA38X is not set ++# CONFIG_RTC_DRV_AU1XXX is not set ++# CONFIG_RTC_DRV_BQ32K is not set ++# CONFIG_RTC_DRV_BQ4802 is not set ++# CONFIG_RTC_DRV_CADENCE is not set ++CONFIG_RTC_DRV_CMOS=y ++# CONFIG_RTC_DRV_DS1286 is not set ++# CONFIG_RTC_DRV_DS1302 is not set ++# CONFIG_RTC_DRV_DS1305 is not set ++# CONFIG_RTC_DRV_DS1307 is not set ++# CONFIG_RTC_DRV_DS1307_CENTURY is not set ++# CONFIG_RTC_DRV_DS1307_HWMON is not set ++# CONFIG_RTC_DRV_DS1343 is not set ++# CONFIG_RTC_DRV_DS1347 is not set ++# CONFIG_RTC_DRV_DS1374 is not set ++# CONFIG_RTC_DRV_DS1390 is not set ++# CONFIG_RTC_DRV_DS1511 is not set ++# CONFIG_RTC_DRV_DS1553 is not set ++# CONFIG_RTC_DRV_DS1672 is not set ++# CONFIG_RTC_DRV_DS1685_FAMILY is not set ++# CONFIG_RTC_DRV_DS1742 is not set ++# CONFIG_RTC_DRV_DS2404 is not set ++# CONFIG_RTC_DRV_DS3232 is not set ++# CONFIG_RTC_DRV_DS3234 is not set ++# CONFIG_RTC_DRV_EM3027 is not set ++# CONFIG_RTC_DRV_EP93XX is not set ++# CONFIG_RTC_DRV_FM3130 is not set ++# CONFIG_RTC_DRV_FTRTC010 is not set ++# CONFIG_RTC_DRV_GENERIC is not set ++# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set ++# CONFIG_RTC_DRV_HYM8563 is not set ++# CONFIG_RTC_DRV_ISL12022 is not set ++# CONFIG_RTC_DRV_ISL12026 is not set ++# CONFIG_RTC_DRV_ISL12057 is not set ++# CONFIG_RTC_DRV_ISL1208 is not set ++# CONFIG_RTC_DRV_M41T80 is not set ++# CONFIG_RTC_DRV_M41T93 is not set ++# CONFIG_RTC_DRV_M41T94 is not set ++# CONFIG_RTC_DRV_M48T35 is not set ++# CONFIG_RTC_DRV_M48T59 is not set ++# CONFIG_RTC_DRV_M48T86 is not set ++# CONFIG_RTC_DRV_MAX6900 is not set ++# CONFIG_RTC_DRV_MAX6902 is not set ++# CONFIG_RTC_DRV_MAX6916 is not set ++# CONFIG_RTC_DRV_MCP795 is not set ++# CONFIG_RTC_DRV_MOXART is not set ++# CONFIG_RTC_DRV_MPC5121 is not set ++# CONFIG_RTC_DRV_MSM6242 is not set ++# CONFIG_RTC_DRV_MT2712 is not set ++# CONFIG_RTC_DRV_OMAP is not set ++# CONFIG_RTC_DRV_PCF2123 is not set ++# CONFIG_RTC_DRV_PCF2127 is not set ++# CONFIG_RTC_DRV_PCF85063 is not set ++# CONFIG_RTC_DRV_PCF8523 is not set ++# CONFIG_RTC_DRV_PCF85363 is not set ++# CONFIG_RTC_DRV_PCF8563 is not set ++# CONFIG_RTC_DRV_PCF8583 is not set ++# CONFIG_RTC_DRV_PL030 is not set ++# CONFIG_RTC_DRV_PL031 is not set ++# CONFIG_RTC_DRV_PS3 is not set ++# CONFIG_RTC_DRV_PT7C4338 is not set ++# CONFIG_RTC_DRV_R7301 is not set ++# CONFIG_RTC_DRV_R9701 is not set ++# CONFIG_RTC_DRV_RP5C01 is not set ++# CONFIG_RTC_DRV_RS5C348 is not set ++# CONFIG_RTC_DRV_RS5C372 is not set ++# CONFIG_RTC_DRV_RTC7301 is not set ++# CONFIG_RTC_DRV_RV3028 is not set ++# CONFIG_RTC_DRV_RV3029C2 is not set ++# CONFIG_RTC_DRV_RV8803 is not set ++# CONFIG_RTC_DRV_RX4581 is not set ++# CONFIG_RTC_DRV_RX6110 is not set ++# CONFIG_RTC_DRV_RX8010 is not set ++# CONFIG_RTC_DRV_RX8025 is not set ++# CONFIG_RTC_DRV_RX8581 is not set ++# CONFIG_RTC_DRV_S35390A is not set ++# CONFIG_RTC_DRV_SD3078 is not set ++# CONFIG_RTC_DRV_SNVS is not set ++# CONFIG_RTC_DRV_STK17TA8 is not set ++# CONFIG_RTC_DRV_SUN6I is not set ++# CONFIG_RTC_DRV_TEST is not set ++# CONFIG_RTC_DRV_V3020 is not set ++# CONFIG_RTC_DRV_X1205 is not set ++# CONFIG_RTC_DRV_XGENE is not set ++# CONFIG_RTC_DRV_ZYNQMP is not set ++CONFIG_RTC_HCTOSYS=y ++CONFIG_RTC_HCTOSYS_DEVICE="rtc0" ++CONFIG_RTC_INTF_DEV=y ++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set ++CONFIG_RTC_INTF_PROC=y ++CONFIG_RTC_INTF_SYSFS=y ++CONFIG_RTC_LIB=y ++# CONFIG_RTC_NVMEM is not set ++CONFIG_RTC_SYSTOHC=y ++CONFIG_RTC_SYSTOHC_DEVICE="rtc0" ++# CONFIG_RTL8180 is not set ++# CONFIG_RTL8187 is not set ++# CONFIG_RTL8192E is not set ++# CONFIG_RTL8192U is not set ++# CONFIG_RTL8306_PHY is not set ++# CONFIG_RTL8366RB_PHY is not set ++# CONFIG_RTL8366S_PHY is not set ++# CONFIG_RTL8366_SMI is not set ++# CONFIG_RTL8366_SMI_DEBUG_FS is not set ++# CONFIG_RTL8367B_PHY is not set ++# CONFIG_RTL8367_PHY is not set ++# CONFIG_RTLLIB is not set ++# CONFIG_RTL_CARDS is not set ++# CONFIG_RTS5208 is not set ++CONFIG_RT_MUTEXES=y ++# CONFIG_RUNTIME_DEBUG is not set ++CONFIG_RUNTIME_TESTING_MENU=y ++CONFIG_RWSEM_GENERIC_SPINLOCK=y ++CONFIG_RXKAD=y ++# CONFIG_S2IO is not set ++# CONFIG_SAMPLES is not set ++# CONFIG_SAMSUNG_LAPTOP is not set ++# CONFIG_SATA_ACARD_AHCI is not set ++# CONFIG_SATA_AHCI is not set ++# CONFIG_SATA_AHCI_PLATFORM is not set ++# CONFIG_SATA_DWC is not set ++# CONFIG_SATA_FSL is not set ++# CONFIG_SATA_HIGHBANK is not set ++# CONFIG_SATA_HOST is not set ++# CONFIG_SATA_INIC162X is not set ++CONFIG_SATA_MOBILE_LPM_POLICY=0 ++# CONFIG_SATA_MV is not set ++# CONFIG_SATA_NV is not set ++# CONFIG_SATA_PMP is not set ++# CONFIG_SATA_PROMISE is not set ++# CONFIG_SATA_QSTOR is not set ++# CONFIG_SATA_RCAR is not set ++# CONFIG_SATA_SIL is not set ++# CONFIG_SATA_SIL24 is not set ++# CONFIG_SATA_SIS is not set ++# CONFIG_SATA_SVW is not set ++# CONFIG_SATA_SX4 is not set ++# CONFIG_SATA_ULI is not set ++# CONFIG_SATA_VIA is not set ++# CONFIG_SATA_VITESSE is not set ++# CONFIG_SBC_FITPC2_WATCHDOG is not set ++CONFIG_SBITMAP=y ++# CONFIG_SC92031 is not set ++# CONFIG_SCA3000 is not set ++# CONFIG_SCACHE_DEBUGFS is not set ++# CONFIG_SCC is not set ++# CONFIG_SCD30_CORE is not set ++# CONFIG_SCF_TORTURE_TEST is not set ++# CONFIG_SCHEDSTATS is not set ++# CONFIG_SCHED_AUTOGROUP is not set ++# CONFIG_SCHED_DEBUG is not set ++CONFIG_SCHED_HRTICK=y ++# CONFIG_SCHED_MC is not set ++CONFIG_SCHED_OMIT_FRAME_POINTER=y ++# CONFIG_SCHED_SMT is not set ++# CONFIG_SCHED_STACK_END_CHECK is not set ++# CONFIG_SCHED_TRACER is not set ++# CONFIG_SCR24X is not set ++# CONFIG_SCSI is not set ++# CONFIG_SCSI_3W_9XXX is not set ++# CONFIG_SCSI_3W_SAS is not set ++# CONFIG_SCSI_7000FASST is not set ++# CONFIG_SCSI_AACRAID is not set ++# CONFIG_SCSI_ACARD is not set ++# CONFIG_SCSI_ADVANSYS is not set ++# CONFIG_SCSI_AHA152X is not set ++# CONFIG_SCSI_AHA1542 is not set ++# CONFIG_SCSI_AIC79XX is not set ++# CONFIG_SCSI_AIC7XXX is not set ++# CONFIG_SCSI_AIC94XX is not set ++# CONFIG_SCSI_AM53C974 is not set ++# CONFIG_SCSI_ARCMSR is not set ++# CONFIG_SCSI_BFA_FC is not set ++# CONFIG_SCSI_BNX2X_FCOE is not set ++# CONFIG_SCSI_BNX2_ISCSI is not set ++# CONFIG_SCSI_BUSLOGIC is not set ++# CONFIG_SCSI_CHELSIO_FCOE is not set ++# CONFIG_SCSI_CONSTANTS is not set ++# CONFIG_SCSI_CXGB3_ISCSI is not set ++# CONFIG_SCSI_CXGB4_ISCSI is not set ++# CONFIG_SCSI_DC395x is not set ++# CONFIG_SCSI_DEBUG is not set ++# CONFIG_SCSI_DH is not set ++CONFIG_SCSI_DMA=y ++# CONFIG_SCSI_DMX3191D is not set ++# CONFIG_SCSI_DPT_I2O is not set ++# CONFIG_SCSI_DTC3280 is not set ++# CONFIG_SCSI_EATA is not set ++# CONFIG_SCSI_ESAS2R is not set ++# CONFIG_SCSI_FC_ATTRS is not set ++# CONFIG_SCSI_FDOMAIN_PCI is not set ++# CONFIG_SCSI_FUTURE_DOMAIN is not set ++# CONFIG_SCSI_GDTH is not set ++# CONFIG_SCSI_GENERIC_NCR5380 is not set ++# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set ++# CONFIG_SCSI_HISI_SAS is not set ++# CONFIG_SCSI_HPSA is not set ++# CONFIG_SCSI_HPTIOP is not set ++# CONFIG_SCSI_IN2000 is not set ++# CONFIG_SCSI_INIA100 is not set ++# CONFIG_SCSI_INITIO is not set ++# CONFIG_SCSI_IPR is not set ++# CONFIG_SCSI_IPS is not set ++# CONFIG_SCSI_ISCI is not set ++# CONFIG_SCSI_ISCSI_ATTRS is not set ++# CONFIG_SCSI_LOGGING is not set ++CONFIG_SCSI_LOWLEVEL=y ++# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set ++# CONFIG_SCSI_LPFC is not set ++CONFIG_SCSI_MOD=y ++# CONFIG_SCSI_MPT2SAS is not set ++# CONFIG_SCSI_MPT3SAS is not set ++# CONFIG_SCSI_MQ_DEFAULT is not set ++# CONFIG_SCSI_MVSAS is not set ++# CONFIG_SCSI_MVSAS_DEBUG is not set ++# CONFIG_SCSI_MVUMI is not set ++# CONFIG_SCSI_MYRB is not set ++# CONFIG_SCSI_MYRS is not set ++# CONFIG_SCSI_NCR53C406A is not set ++# CONFIG_SCSI_NETLINK is not set ++# CONFIG_SCSI_NSP32 is not set ++# CONFIG_SCSI_OSD_INITIATOR is not set ++# CONFIG_SCSI_PAS16 is not set ++# CONFIG_SCSI_PM8001 is not set ++# CONFIG_SCSI_PMCRAID is not set ++CONFIG_SCSI_PROC_FS=y ++# CONFIG_SCSI_QLA_FC is not set ++# CONFIG_SCSI_QLA_ISCSI is not set ++# CONFIG_SCSI_QLOGIC_1280 is not set ++# CONFIG_SCSI_QLOGIC_FAS is not set ++# CONFIG_SCSI_SAS_ATTRS is not set ++# CONFIG_SCSI_SAS_LIBSAS is not set ++# CONFIG_SCSI_SCAN_ASYNC is not set ++# CONFIG_SCSI_SMARTPQI is not set ++# CONFIG_SCSI_SNIC is not set ++# CONFIG_SCSI_SPI_ATTRS is not set ++# CONFIG_SCSI_SRP_ATTRS is not set ++# CONFIG_SCSI_STEX is not set ++# CONFIG_SCSI_SYM53C416 is not set ++# CONFIG_SCSI_SYM53C8XX_2 is not set ++# CONFIG_SCSI_T128 is not set ++# CONFIG_SCSI_U14_34F is not set ++# CONFIG_SCSI_UFSHCD is not set ++# CONFIG_SCSI_ULTRASTOR is not set ++# CONFIG_SCSI_VIRTIO is not set ++# CONFIG_SCSI_WD719X is not set ++# CONFIG_SCx200_ACB is not set ++# CONFIG_SDIO_UART is not set ++# CONFIG_SDR_MAX2175 is not set ++# CONFIG_SDR_PLATFORM_DRIVERS is not set ++# CONFIG_SD_ADC_MODULATOR is not set ++# CONFIG_SECCOMP is not set ++CONFIG_SECTION_MISMATCH_WARN_ONLY=y ++# CONFIG_SECURITY is not set ++# CONFIG_SECURITYFS is not set ++# CONFIG_SECURITY_APPARMOR is not set ++CONFIG_SECURITY_DMESG_RESTRICT=y ++# CONFIG_SECURITY_LOADPIN is not set ++# CONFIG_SECURITY_LOCKDOWN_LSM is not set ++# CONFIG_SECURITY_PATH is not set ++# CONFIG_SECURITY_SAFESETID is not set ++# CONFIG_SECURITY_SELINUX_AVC_STATS is not set ++# CONFIG_SECURITY_SELINUX_BOOTPARAM is not set ++CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=0 ++# CONFIG_SECURITY_SELINUX_DEVELOP is not set ++# CONFIG_SECURITY_SELINUX_DISABLE is not set ++# CONFIG_SECURITY_SMACK is not set ++# CONFIG_SECURITY_TOMOYO is not set ++# CONFIG_SECURITY_YAMA is not set ++CONFIG_SELECT_MEMORY_MODEL=y ++# CONFIG_SENSIRION_SGP30 is not set ++# CONFIG_SENSORS_ABITUGURU is not set ++# CONFIG_SENSORS_ABITUGURU3 is not set ++# CONFIG_SENSORS_ACPI_POWER is not set ++# CONFIG_SENSORS_AD7314 is not set ++# CONFIG_SENSORS_AD7414 is not set ++# CONFIG_SENSORS_AD7418 is not set ++# CONFIG_SENSORS_ADC128D818 is not set ++# CONFIG_SENSORS_ADCXX is not set ++# CONFIG_SENSORS_ADM1021 is not set ++# CONFIG_SENSORS_ADM1025 is not set ++# CONFIG_SENSORS_ADM1026 is not set ++# CONFIG_SENSORS_ADM1029 is not set ++# CONFIG_SENSORS_ADM1031 is not set ++# CONFIG_SENSORS_ADM1177 is not set ++# CONFIG_SENSORS_ADM1275 is not set ++# CONFIG_SENSORS_ADM9240 is not set ++# CONFIG_SENSORS_ADS1015 is not set ++# CONFIG_SENSORS_ADS7828 is not set ++# CONFIG_SENSORS_ADS7871 is not set ++# CONFIG_SENSORS_ADT7310 is not set ++# CONFIG_SENSORS_ADT7410 is not set ++# CONFIG_SENSORS_ADT7411 is not set ++# CONFIG_SENSORS_ADT7462 is not set ++# CONFIG_SENSORS_ADT7470 is not set ++# CONFIG_SENSORS_ADT7475 is not set ++# CONFIG_SENSORS_AMC6821 is not set ++# CONFIG_SENSORS_APDS990X is not set ++# CONFIG_SENSORS_APPLESMC is not set ++# CONFIG_SENSORS_AS370 is not set ++# CONFIG_SENSORS_ASB100 is not set ++# CONFIG_SENSORS_ASC7621 is not set ++# CONFIG_SENSORS_ASPEED is not set ++# CONFIG_SENSORS_ATK0110 is not set ++# CONFIG_SENSORS_ATXP1 is not set ++# CONFIG_SENSORS_AXI_FAN_CONTROL is not set ++# CONFIG_SENSORS_BEL_PFE is not set ++# CONFIG_SENSORS_BH1770 is not set ++# CONFIG_SENSORS_BH1780 is not set ++# CONFIG_SENSORS_CORETEMP is not set ++# CONFIG_SENSORS_CORSAIR_CPRO is not set ++# CONFIG_SENSORS_DELL_SMM is not set ++# CONFIG_SENSORS_DME1737 is not set ++# CONFIG_SENSORS_DS1621 is not set ++# CONFIG_SENSORS_DS620 is not set ++# CONFIG_SENSORS_EMC1403 is not set ++# CONFIG_SENSORS_EMC2103 is not set ++# CONFIG_SENSORS_EMC6W201 is not set ++# CONFIG_SENSORS_F71805F is not set ++# CONFIG_SENSORS_F71882FG is not set ++# CONFIG_SENSORS_F75375S is not set ++# CONFIG_SENSORS_FAM15H_POWER is not set ++# CONFIG_SENSORS_FSCHMD is not set ++# CONFIG_SENSORS_FTSTEUTATES is not set ++# CONFIG_SENSORS_G760A is not set ++# CONFIG_SENSORS_G762 is not set ++# CONFIG_SENSORS_GL518SM is not set ++# CONFIG_SENSORS_GL520SM is not set ++# CONFIG_SENSORS_GPIO_FAN is not set ++# CONFIG_SENSORS_GSC is not set ++# CONFIG_SENSORS_HDAPS is not set ++# CONFIG_SENSORS_HIH6130 is not set ++# CONFIG_SENSORS_HMC5843 is not set ++# CONFIG_SENSORS_HMC5843_I2C is not set ++# CONFIG_SENSORS_HMC5843_SPI is not set ++# CONFIG_SENSORS_HTU21 is not set ++# CONFIG_SENSORS_I5500 is not set ++# CONFIG_SENSORS_I5K_AMB is not set ++# CONFIG_SENSORS_IBM_CFFPS is not set ++# CONFIG_SENSORS_IIO_HWMON is not set ++# CONFIG_SENSORS_INA209 is not set ++# CONFIG_SENSORS_INA2XX is not set ++# CONFIG_SENSORS_INA3221 is not set ++# CONFIG_SENSORS_INSPUR_IPSPS is not set ++# CONFIG_SENSORS_IR35221 is not set ++# CONFIG_SENSORS_IR38064 is not set ++# CONFIG_SENSORS_IRPS5401 is not set ++# CONFIG_SENSORS_ISL29018 is not set ++# CONFIG_SENSORS_ISL29028 is not set ++# CONFIG_SENSORS_ISL68137 is not set ++# CONFIG_SENSORS_IT87 is not set ++# CONFIG_SENSORS_JC42 is not set ++# CONFIG_SENSORS_K10TEMP is not set ++# CONFIG_SENSORS_K8TEMP is not set ++# CONFIG_SENSORS_LINEAGE is not set ++# CONFIG_SENSORS_LIS3LV02D is not set ++# CONFIG_SENSORS_LIS3_I2C is not set ++# CONFIG_SENSORS_LIS3_SPI is not set ++# CONFIG_SENSORS_LM25066 is not set ++# CONFIG_SENSORS_LM63 is not set ++# CONFIG_SENSORS_LM70 is not set ++# CONFIG_SENSORS_LM73 is not set ++# CONFIG_SENSORS_LM75 is not set ++# CONFIG_SENSORS_LM77 is not set ++# CONFIG_SENSORS_LM78 is not set ++# CONFIG_SENSORS_LM80 is not set ++# CONFIG_SENSORS_LM83 is not set ++# CONFIG_SENSORS_LM85 is not set ++# CONFIG_SENSORS_LM87 is not set ++# CONFIG_SENSORS_LM90 is not set ++# CONFIG_SENSORS_LM92 is not set ++# CONFIG_SENSORS_LM93 is not set ++# CONFIG_SENSORS_LM95234 is not set ++# CONFIG_SENSORS_LM95241 is not set ++# CONFIG_SENSORS_LM95245 is not set ++# CONFIG_SENSORS_LTC2945 is not set ++# CONFIG_SENSORS_LTC2947_I2C is not set ++# CONFIG_SENSORS_LTC2947_SPI is not set ++# CONFIG_SENSORS_LTC2978 is not set ++# CONFIG_SENSORS_LTC2990 is not set ++# CONFIG_SENSORS_LTC3815 is not set ++# CONFIG_SENSORS_LTC4151 is not set ++# CONFIG_SENSORS_LTC4215 is not set ++# CONFIG_SENSORS_LTC4222 is not set ++# CONFIG_SENSORS_LTC4245 is not set ++# CONFIG_SENSORS_LTC4260 is not set ++# CONFIG_SENSORS_LTC4261 is not set ++# CONFIG_SENSORS_LTQ_CPUTEMP is not set ++# CONFIG_SENSORS_MAX1111 is not set ++# CONFIG_SENSORS_MAX16064 is not set ++# CONFIG_SENSORS_MAX16065 is not set ++# CONFIG_SENSORS_MAX1619 is not set ++# CONFIG_SENSORS_MAX16601 is not set ++# CONFIG_SENSORS_MAX1668 is not set ++# CONFIG_SENSORS_MAX197 is not set ++# CONFIG_SENSORS_MAX20730 is not set ++# CONFIG_SENSORS_MAX20751 is not set ++# CONFIG_SENSORS_MAX31722 is not set ++# CONFIG_SENSORS_MAX31730 is not set ++# CONFIG_SENSORS_MAX31785 is not set ++# CONFIG_SENSORS_MAX31790 is not set ++# CONFIG_SENSORS_MAX34440 is not set ++# CONFIG_SENSORS_MAX6621 is not set ++# CONFIG_SENSORS_MAX6639 is not set ++# CONFIG_SENSORS_MAX6642 is not set ++# CONFIG_SENSORS_MAX6650 is not set ++# CONFIG_SENSORS_MAX6697 is not set ++# CONFIG_SENSORS_MAX8688 is not set ++# CONFIG_SENSORS_MCP3021 is not set ++# CONFIG_SENSORS_NCT6683 is not set ++# CONFIG_SENSORS_NCT6775 is not set ++# CONFIG_SENSORS_NCT7802 is not set ++# CONFIG_SENSORS_NCT7904 is not set ++# CONFIG_SENSORS_NPCM7XX is not set ++# CONFIG_SENSORS_NSA320 is not set ++# CONFIG_SENSORS_NTC_THERMISTOR is not set ++# CONFIG_SENSORS_OCC_P8_I2C is not set ++# CONFIG_SENSORS_PC87360 is not set ++# CONFIG_SENSORS_PC87427 is not set ++# CONFIG_SENSORS_PCF8591 is not set ++# CONFIG_SENSORS_PMBUS is not set ++# CONFIG_SENSORS_POWR1220 is not set ++# CONFIG_SENSORS_PWM_FAN is not set ++# CONFIG_SENSORS_PXE1610 is not set ++# CONFIG_SENSORS_RM3100_I2C is not set ++# CONFIG_SENSORS_RM3100_SPI is not set ++# CONFIG_SENSORS_SCH5627 is not set ++# CONFIG_SENSORS_SCH5636 is not set ++# CONFIG_SENSORS_SCH56XX_COMMON is not set ++# CONFIG_SENSORS_SHT15 is not set ++# CONFIG_SENSORS_SHT21 is not set ++# CONFIG_SENSORS_SHT3x is not set ++# CONFIG_SENSORS_SHTC1 is not set ++# CONFIG_SENSORS_SIS5595 is not set ++# CONFIG_SENSORS_SMM665 is not set ++# CONFIG_SENSORS_SMSC47B397 is not set ++# CONFIG_SENSORS_SMSC47M1 is not set ++# CONFIG_SENSORS_SMSC47M192 is not set ++# CONFIG_SENSORS_STTS751 is not set ++# CONFIG_SENSORS_TC654 is not set ++# CONFIG_SENSORS_TC74 is not set ++# CONFIG_SENSORS_THMC50 is not set ++# CONFIG_SENSORS_TMP102 is not set ++# CONFIG_SENSORS_TMP103 is not set ++# CONFIG_SENSORS_TMP108 is not set ++# CONFIG_SENSORS_TMP401 is not set ++# CONFIG_SENSORS_TMP421 is not set ++# CONFIG_SENSORS_TMP513 is not set ++# CONFIG_SENSORS_TPS40422 is not set ++# CONFIG_SENSORS_TPS53679 is not set ++# CONFIG_SENSORS_TSL2550 is not set ++# CONFIG_SENSORS_TSL2563 is not set ++# CONFIG_SENSORS_UCD9000 is not set ++# CONFIG_SENSORS_UCD9200 is not set ++# CONFIG_SENSORS_VEXPRESS is not set ++# CONFIG_SENSORS_VIA686A is not set ++# CONFIG_SENSORS_VIA_CPUTEMP is not set ++# CONFIG_SENSORS_VT1211 is not set ++# CONFIG_SENSORS_VT8231 is not set ++# CONFIG_SENSORS_W83627EHF is not set ++# CONFIG_SENSORS_W83627HF is not set ++# CONFIG_SENSORS_W83773G is not set ++# CONFIG_SENSORS_W83781D is not set ++# CONFIG_SENSORS_W83791D is not set ++# CONFIG_SENSORS_W83792D is not set ++# CONFIG_SENSORS_W83793 is not set ++# CONFIG_SENSORS_W83795 is not set ++# CONFIG_SENSORS_W83L785TS is not set ++# CONFIG_SENSORS_W83L786NG is not set ++# CONFIG_SENSORS_XDPE122 is not set ++# CONFIG_SENSORS_XGENE is not set ++# CONFIG_SENSORS_ZL6100 is not set ++CONFIG_SERIAL_8250=y ++# CONFIG_SERIAL_8250_16550A_VARIANTS is not set ++# CONFIG_SERIAL_8250_ACCENT is not set ++# CONFIG_SERIAL_8250_ASPEED_VUART is not set ++# CONFIG_SERIAL_8250_BOCA is not set ++CONFIG_SERIAL_8250_CONSOLE=y ++# CONFIG_SERIAL_8250_CS is not set ++# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set ++# CONFIG_SERIAL_8250_DETECT_IRQ is not set ++CONFIG_SERIAL_8250_DMA=y ++# CONFIG_SERIAL_8250_DW is not set ++# CONFIG_SERIAL_8250_EM is not set ++# CONFIG_SERIAL_8250_EXAR is not set ++# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set ++# CONFIG_SERIAL_8250_EXTENDED is not set ++# CONFIG_SERIAL_8250_FINTEK is not set ++# CONFIG_SERIAL_8250_FOURPORT is not set ++# CONFIG_SERIAL_8250_HUB6 is not set ++# CONFIG_SERIAL_8250_INGENIC is not set ++# CONFIG_SERIAL_8250_LPSS is not set ++# CONFIG_SERIAL_8250_MANY_PORTS is not set ++# CONFIG_SERIAL_8250_MID is not set ++# CONFIG_SERIAL_8250_MOXA is not set ++CONFIG_SERIAL_8250_NR_UARTS=2 ++# CONFIG_SERIAL_8250_PCI is not set ++# CONFIG_SERIAL_8250_RSA is not set ++# CONFIG_SERIAL_8250_RT288X is not set ++CONFIG_SERIAL_8250_RUNTIME_UARTS=2 ++# CONFIG_SERIAL_ALTERA_JTAGUART is not set ++# CONFIG_SERIAL_ALTERA_UART is not set ++# CONFIG_SERIAL_AMBA_PL010 is not set ++# CONFIG_SERIAL_AMBA_PL011 is not set ++# CONFIG_SERIAL_ARC is not set ++# CONFIG_SERIAL_BCM63XX is not set ++# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set ++CONFIG_SERIAL_CORE=y ++CONFIG_SERIAL_CORE_CONSOLE=y ++# CONFIG_SERIAL_DEV_BUS is not set ++CONFIG_SERIAL_EARLYCON=y ++# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set ++# CONFIG_SERIAL_FSL_LINFLEXUART is not set ++# CONFIG_SERIAL_FSL_LPUART is not set ++# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set ++# CONFIG_SERIAL_IFX6X60 is not set ++# CONFIG_SERIAL_JSM is not set ++# CONFIG_SERIAL_MAX3100 is not set ++# CONFIG_SERIAL_MAX310X is not set ++# CONFIG_SERIAL_NONSTANDARD is not set ++# CONFIG_SERIAL_OF_PLATFORM is not set ++# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set ++# CONFIG_SERIAL_PCH_UART is not set ++# CONFIG_SERIAL_RP2 is not set ++# CONFIG_SERIAL_SC16IS7XX is not set ++# CONFIG_SERIAL_SCCNXP is not set ++# CONFIG_SERIAL_SH_SCI is not set ++# CONFIG_SERIAL_SIFIVE is not set ++# CONFIG_SERIAL_SPRD is not set ++# CONFIG_SERIAL_STM32 is not set ++# CONFIG_SERIAL_ST_ASC is not set ++# CONFIG_SERIAL_TIMBERDALE is not set ++# CONFIG_SERIAL_UARTLITE is not set ++# CONFIG_SERIAL_XILINX_PS_UART is not set ++# CONFIG_SERIO is not set ++# CONFIG_SERIO_ALTERA_PS2 is not set ++# CONFIG_SERIO_AMBAKMI is not set ++# CONFIG_SERIO_APBPS2 is not set ++# CONFIG_SERIO_ARC_PS2 is not set ++# CONFIG_SERIO_CT82C710 is not set ++# CONFIG_SERIO_GPIO_PS2 is not set ++# CONFIG_SERIO_I8042 is not set ++# CONFIG_SERIO_LIBPS2 is not set ++# CONFIG_SERIO_PARKBD is not set ++# CONFIG_SERIO_PCIPS2 is not set ++# CONFIG_SERIO_PS2MULT is not set ++# CONFIG_SERIO_RAW is not set ++# CONFIG_SERIO_SERPORT is not set ++# CONFIG_SERIO_SUN4I_PS2 is not set ++# CONFIG_SFC is not set ++# CONFIG_SFC_FALCON is not set ++# CONFIG_SFI is not set ++# CONFIG_SFP is not set ++# CONFIG_SF_PDMA is not set ++# CONFIG_SGETMASK_SYSCALL is not set ++# CONFIG_SGI_IOC4 is not set ++# CONFIG_SGI_IP22 is not set ++# CONFIG_SGI_IP27 is not set ++# CONFIG_SGI_IP28 is not set ++# CONFIG_SGI_IP32 is not set ++# CONFIG_SGI_PARTITION is not set ++# CONFIG_SG_POOL is not set ++# CONFIG_SG_SPLIT is not set ++CONFIG_SHMEM=y ++# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set ++# CONFIG_SH_ETH is not set ++# CONFIG_SH_TIMER_CMT is not set ++# CONFIG_SH_TIMER_MTU2 is not set ++# CONFIG_SH_TIMER_TMU is not set ++# CONFIG_SI1133 is not set ++# CONFIG_SI1145 is not set ++# CONFIG_SI7005 is not set ++# CONFIG_SI7020 is not set ++# CONFIG_SIBYTE_BIGSUR is not set ++# CONFIG_SIBYTE_CARMEL is not set ++# CONFIG_SIBYTE_CRHINE is not set ++# CONFIG_SIBYTE_CRHONE is not set ++# CONFIG_SIBYTE_LITTLESUR is not set ++# CONFIG_SIBYTE_RHONE is not set ++# CONFIG_SIBYTE_SENTOSA is not set ++# CONFIG_SIBYTE_SWARM is not set ++CONFIG_SIGNALFD=y ++# CONFIG_SIGNED_PE_FILE_VERIFICATION is not set ++# CONFIG_SIMPLE_GPIO is not set ++# CONFIG_SIMPLE_PM_BUS is not set ++# CONFIG_SIOX is not set ++# CONFIG_SIS190 is not set ++# CONFIG_SIS900 is not set ++# CONFIG_SKGE is not set ++# CONFIG_SKY2 is not set ++# CONFIG_SKY2_DEBUG is not set ++# CONFIG_SLAB is not set ++CONFIG_SLABINFO=y ++# CONFIG_SLAB_FREELIST_HARDENED is not set ++# CONFIG_SLAB_FREELIST_RANDOM is not set ++CONFIG_SLAB_MERGE_DEFAULT=y ++# CONFIG_SLHC is not set ++# CONFIG_SLICOSS is not set ++# CONFIG_SLIMBUS is not set ++# CONFIG_SLIP is not set ++# CONFIG_SLOB is not set ++CONFIG_SLUB=y ++CONFIG_SLUB_CPU_PARTIAL=y ++# CONFIG_SLUB_DEBUG is not set ++# CONFIG_SLUB_DEBUG_ON is not set ++# CONFIG_SLUB_MEMCG_SYSFS_ON is not set ++# CONFIG_SLUB_STATS is not set ++# CONFIG_SMARTJOYPLUS_FF is not set ++# CONFIG_SMC911X is not set ++# CONFIG_SMC9194 is not set ++# CONFIG_SMC91X is not set ++# CONFIG_SMP is not set ++# CONFIG_SMSC911X is not set ++# CONFIG_SMSC9420 is not set ++# CONFIG_SMSC_PHY is not set ++# CONFIG_SMS_SDIO_DRV is not set ++# CONFIG_SMS_USB_DRV is not set ++# CONFIG_SM_FTL is not set ++# CONFIG_SND is not set ++# CONFIG_SND_AC97_POWER_SAVE is not set ++# CONFIG_SND_AD1816A is not set ++# CONFIG_SND_AD1848 is not set ++# CONFIG_SND_AD1889 is not set ++# CONFIG_SND_ADLIB is not set ++# CONFIG_SND_ALI5451 is not set ++# CONFIG_SND_ALOOP is not set ++# CONFIG_SND_ALS100 is not set ++# CONFIG_SND_ALS300 is not set ++# CONFIG_SND_ALS4000 is not set ++# CONFIG_SND_ARM is not set ++# CONFIG_SND_ASIHPI is not set ++# CONFIG_SND_ATIIXP is not set ++# CONFIG_SND_ATIIXP_MODEM is not set ++# CONFIG_SND_ATMEL_AC97C is not set ++# CONFIG_SND_ATMEL_SOC is not set ++# CONFIG_SND_AU8810 is not set ++# CONFIG_SND_AU8820 is not set ++# CONFIG_SND_AU8830 is not set ++# CONFIG_SND_AUDIO_GRAPH_CARD is not set ++# CONFIG_SND_AUDIO_GRAPH_SCU_CARD is not set ++# CONFIG_SND_AW2 is not set ++# CONFIG_SND_AZT2320 is not set ++# CONFIG_SND_AZT3328 is not set ++# CONFIG_SND_BCD2000 is not set ++# CONFIG_SND_BCM63XX_I2S_WHISTLER is not set ++# CONFIG_SND_BT87X is not set ++# CONFIG_SND_CA0106 is not set ++# CONFIG_SND_CMI8330 is not set ++# CONFIG_SND_CMIPCI is not set ++# CONFIG_SND_CS4231 is not set ++# CONFIG_SND_CS4236 is not set ++# CONFIG_SND_CS4281 is not set ++# CONFIG_SND_CS46XX is not set ++# CONFIG_SND_CS5530 is not set ++# CONFIG_SND_CS5535AUDIO is not set ++# CONFIG_SND_CTXFI is not set ++# CONFIG_SND_DARLA20 is not set ++# CONFIG_SND_DARLA24 is not set ++# CONFIG_SND_DEBUG is not set ++# CONFIG_SND_DESIGNWARE_I2S is not set ++CONFIG_SND_DRIVERS=y ++# CONFIG_SND_DUMMY is not set ++# CONFIG_SND_DYNAMIC_MINORS is not set ++# CONFIG_SND_ECHO3G is not set ++# CONFIG_SND_EDMA_SOC is not set ++# CONFIG_SND_EMU10K1 is not set ++# CONFIG_SND_EMU10K1X is not set ++# CONFIG_SND_EMU10K1_SEQ is not set ++# CONFIG_SND_ENS1370 is not set ++# CONFIG_SND_ENS1371 is not set ++# CONFIG_SND_ES1688 is not set ++# CONFIG_SND_ES18XX is not set ++# CONFIG_SND_ES1938 is not set ++# CONFIG_SND_ES1968 is not set ++# CONFIG_SND_FIREWIRE is not set ++# CONFIG_SND_FM801 is not set ++# CONFIG_SND_GINA20 is not set ++# CONFIG_SND_GINA24 is not set ++# CONFIG_SND_GUSCLASSIC is not set ++# CONFIG_SND_GUSEXTREME is not set ++# CONFIG_SND_GUSMAX is not set ++# CONFIG_SND_HDA_INTEL is not set ++# CONFIG_SND_HDA_INTEL_DETECT_DMIC is not set ++CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 ++CONFIG_SND_HDA_PREALLOC_SIZE=64 ++# CONFIG_SND_HDSP is not set ++# CONFIG_SND_HDSPM is not set ++# CONFIG_SND_HRTIMER is not set ++# CONFIG_SND_HWDEP is not set ++# CONFIG_SND_I2S_HI6210_I2S is not set ++# CONFIG_SND_ICE1712 is not set ++# CONFIG_SND_ICE1724 is not set ++# CONFIG_SND_INDIGO is not set ++# CONFIG_SND_INDIGODJ is not set ++# CONFIG_SND_INDIGODJX is not set ++# CONFIG_SND_INDIGOIO is not set ++# CONFIG_SND_INDIGOIOX is not set ++# CONFIG_SND_INTEL8X0 is not set ++# CONFIG_SND_INTEL8X0M is not set ++# CONFIG_SND_INTERWAVE is not set ++# CONFIG_SND_INTERWAVE_STB is not set ++# CONFIG_SND_ISA is not set ++# CONFIG_SND_JZ4740_SOC_I2S is not set ++# CONFIG_SND_KIRKWOOD_SOC is not set ++# CONFIG_SND_KORG1212 is not set ++# CONFIG_SND_LAYLA20 is not set ++# CONFIG_SND_LAYLA24 is not set ++# CONFIG_SND_LOLA is not set ++# CONFIG_SND_LX6464ES is not set ++# CONFIG_SND_MAESTRO3 is not set ++CONFIG_SND_MAX_CARDS=16 ++# CONFIG_SND_MIA is not set ++# CONFIG_SND_MIPS is not set ++# CONFIG_SND_MIRO is not set ++# CONFIG_SND_MIXART is not set ++# CONFIG_SND_MIXER_OSS is not set ++# CONFIG_SND_MONA is not set ++# CONFIG_SND_MPC52xx_SOC_EFIKA is not set ++# CONFIG_SND_MPU401 is not set ++# CONFIG_SND_MTPAV is not set ++# CONFIG_SND_MTS64 is not set ++# CONFIG_SND_MXS_SOC is not set ++# CONFIG_SND_NM256 is not set ++# CONFIG_SND_OPL3SA2 is not set ++# CONFIG_SND_OPL3_LIB_SEQ is not set ++# CONFIG_SND_OPL4_LIB_SEQ is not set ++# CONFIG_SND_OPTI92X_AD1848 is not set ++# CONFIG_SND_OPTI92X_CS4231 is not set ++# CONFIG_SND_OPTI93X is not set ++CONFIG_SND_OSSEMUL=y ++# CONFIG_SND_OXYGEN is not set ++CONFIG_SND_PCI=y ++# CONFIG_SND_PCM is not set ++# CONFIG_SND_PCMCIA is not set ++# CONFIG_SND_PCM_OSS is not set ++CONFIG_SND_PCM_OSS_PLUGINS=y ++# CONFIG_SND_PCM_TIMER is not set ++# CONFIG_SND_PCM_XRUN_DEBUG is not set ++# CONFIG_SND_PCXHR is not set ++# CONFIG_SND_PDAUDIOCF is not set ++# CONFIG_SND_PORTMAN2X4 is not set ++# CONFIG_SND_POWERPC_SOC is not set ++# CONFIG_SND_PPC is not set ++CONFIG_SND_PROC_FS=y ++# CONFIG_SND_RAWMIDI is not set ++# CONFIG_SND_RAWMIDI_SEQ is not set ++# CONFIG_SND_RIPTIDE is not set ++# CONFIG_SND_RME32 is not set ++# CONFIG_SND_RME96 is not set ++# CONFIG_SND_RME9652 is not set ++# CONFIG_SND_RTCTIMER is not set ++# CONFIG_SND_SB16 is not set ++# CONFIG_SND_SB8 is not set ++# CONFIG_SND_SBAWE is not set ++# CONFIG_SND_SBAWE_SEQ is not set ++# CONFIG_SND_SE6X is not set ++# CONFIG_SND_SEQUENCER is not set ++# CONFIG_SND_SERIAL_U16550 is not set ++# CONFIG_SND_SIMPLE_CARD is not set ++# CONFIG_SND_SIMPLE_SCU_CARD is not set ++# CONFIG_SND_SIS7019 is not set ++# CONFIG_SND_SOC is not set ++# CONFIG_SND_SOC_AC97_CODEC is not set ++# CONFIG_SND_SOC_ADAU1701 is not set ++# CONFIG_SND_SOC_ADAU1761_I2C is not set ++# CONFIG_SND_SOC_ADAU1761_SPI is not set ++# CONFIG_SND_SOC_ADAU7002 is not set ++# CONFIG_SND_SOC_ADAU7118_HW is not set ++# CONFIG_SND_SOC_ADAU7118_I2C is not set ++# CONFIG_SND_SOC_AK4104 is not set ++# CONFIG_SND_SOC_AK4118 is not set ++# CONFIG_SND_SOC_AK4458 is not set ++# CONFIG_SND_SOC_AK4554 is not set ++# CONFIG_SND_SOC_AK4613 is not set ++# CONFIG_SND_SOC_AK4642 is not set ++# CONFIG_SND_SOC_AK5386 is not set ++# CONFIG_SND_SOC_AK5558 is not set ++# CONFIG_SND_SOC_ALC5623 is not set ++# CONFIG_SND_SOC_AMD_ACP is not set ++# CONFIG_SND_SOC_AMD_ACP3x is not set ++# CONFIG_SND_SOC_AU1XAUDIO is not set ++# CONFIG_SND_SOC_AU1XPSC is not set ++# CONFIG_SND_SOC_BD28623 is not set ++# CONFIG_SND_SOC_BT_SCO is not set ++# CONFIG_SND_SOC_CS35L32 is not set ++# CONFIG_SND_SOC_CS35L33 is not set ++# CONFIG_SND_SOC_CS35L34 is not set ++# CONFIG_SND_SOC_CS35L35 is not set ++# CONFIG_SND_SOC_CS35L36 is not set ++# CONFIG_SND_SOC_CS4265 is not set ++# CONFIG_SND_SOC_CS4270 is not set ++# CONFIG_SND_SOC_CS4271 is not set ++# CONFIG_SND_SOC_CS4271_I2C is not set ++# CONFIG_SND_SOC_CS4271_SPI is not set ++# CONFIG_SND_SOC_CS42L42 is not set ++# CONFIG_SND_SOC_CS42L51_I2C is not set ++# CONFIG_SND_SOC_CS42L52 is not set ++# CONFIG_SND_SOC_CS42L56 is not set ++# CONFIG_SND_SOC_CS42L73 is not set ++# CONFIG_SND_SOC_CS42XX8_I2C is not set ++# CONFIG_SND_SOC_CS43130 is not set ++# CONFIG_SND_SOC_CS4341 is not set ++# CONFIG_SND_SOC_CS4349 is not set ++# CONFIG_SND_SOC_CS53L30 is not set ++# CONFIG_SND_SOC_CX2072X is not set ++# CONFIG_SND_SOC_DIO2125 is not set ++# CONFIG_SND_SOC_DMIC is not set ++# CONFIG_SND_SOC_ES7134 is not set ++# CONFIG_SND_SOC_ES7241 is not set ++# CONFIG_SND_SOC_ES8316 is not set ++# CONFIG_SND_SOC_ES8328 is not set ++# CONFIG_SND_SOC_ES8328_I2C is not set ++# CONFIG_SND_SOC_ES8328_SPI is not set ++# CONFIG_SND_SOC_EUKREA_TLV320 is not set ++# CONFIG_SND_SOC_FSL_ASOC_CARD is not set ++# CONFIG_SND_SOC_FSL_ASRC is not set ++# CONFIG_SND_SOC_FSL_AUDMIX is not set ++# CONFIG_SND_SOC_FSL_ESAI is not set ++# CONFIG_SND_SOC_FSL_MICFIL is not set ++# CONFIG_SND_SOC_FSL_SAI is not set ++# CONFIG_SND_SOC_FSL_SPDIF is not set ++# CONFIG_SND_SOC_FSL_SSI is not set ++# CONFIG_SND_SOC_GTM601 is not set ++# CONFIG_SND_SOC_ICS43432 is not set ++# CONFIG_SND_SOC_IMG is not set ++# CONFIG_SND_SOC_IMX_AUDMIX is not set ++# CONFIG_SND_SOC_IMX_AUDMUX is not set ++# CONFIG_SND_SOC_IMX_ES8328 is not set ++# CONFIG_SND_SOC_IMX_SPDIF is not set ++# CONFIG_SND_SOC_IMX_WM8962 is not set ++# CONFIG_SND_SOC_INNO_RK3036 is not set ++# CONFIG_SND_SOC_INTEL_APL is not set ++# CONFIG_SND_SOC_INTEL_BAYTRAIL is not set ++# CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH is not set ++# CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH is not set ++# CONFIG_SND_SOC_INTEL_BXT_RT298_MACH is not set ++# CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH is not set ++# CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH is not set ++# CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH is not set ++# CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH is not set ++# CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH is not set ++# CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH is not set ++# CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH is not set ++# CONFIG_SND_SOC_INTEL_CFL is not set ++# CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH is not set ++# CONFIG_SND_SOC_INTEL_CHT_BSW_NAU8824_MACH is not set ++# CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH is not set ++# CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH is not set ++# CONFIG_SND_SOC_INTEL_CML_H is not set ++# CONFIG_SND_SOC_INTEL_CML_LP is not set ++# CONFIG_SND_SOC_INTEL_CNL is not set ++# CONFIG_SND_SOC_INTEL_GLK is not set ++# CONFIG_SND_SOC_INTEL_HASWELL is not set ++# CONFIG_SND_SOC_INTEL_KBL is not set ++# CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH is not set ++# CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH is not set ++# CONFIG_SND_SOC_INTEL_KEEMBAY is not set ++# CONFIG_SND_SOC_INTEL_SKL is not set ++# CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH is not set ++# CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH is not set ++# CONFIG_SND_SOC_INTEL_SKL_RT286_MACH is not set ++# CONFIG_SND_SOC_INTEL_SKYLAKE is not set ++# CONFIG_SND_SOC_INTEL_SST is not set ++CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y ++# CONFIG_SND_SOC_JZ4725B_CODEC is not set ++# CONFIG_SND_SOC_JZ4740_CODEC is not set ++# CONFIG_SND_SOC_MA120X0P is not set ++# CONFIG_SND_SOC_MAX9759 is not set ++# CONFIG_SND_SOC_MAX98088 is not set ++# CONFIG_SND_SOC_MAX98357A is not set ++# CONFIG_SND_SOC_MAX98373 is not set ++# CONFIG_SND_SOC_MAX98373_I2C is not set ++# CONFIG_SND_SOC_MAX98390 is not set ++# CONFIG_SND_SOC_MAX98504 is not set ++# CONFIG_SND_SOC_MAX9860 is not set ++# CONFIG_SND_SOC_MAX9867 is not set ++# CONFIG_SND_SOC_MAX98927 is not set ++# CONFIG_SND_SOC_MEDIATEK is not set ++# CONFIG_SND_SOC_MPC5200_AC97 is not set ++# CONFIG_SND_SOC_MPC5200_I2S is not set ++# CONFIG_SND_SOC_MSM8916_WCD_ANALOG is not set ++# CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set ++# CONFIG_SND_SOC_MT2701 is not set ++# CONFIG_SND_SOC_MT6351 is not set ++# CONFIG_SND_SOC_MT6358 is not set ++# CONFIG_SND_SOC_MT6660 is not set ++# CONFIG_SND_SOC_MT6797 is not set ++# CONFIG_SND_SOC_MT8173 is not set ++# CONFIG_SND_SOC_MT8183 is not set ++# CONFIG_SND_SOC_MTK_BTCVSD is not set ++# CONFIG_SND_SOC_NAU8540 is not set ++# CONFIG_SND_SOC_NAU8810 is not set ++# CONFIG_SND_SOC_NAU8822 is not set ++# CONFIG_SND_SOC_NAU8824 is not set ++# CONFIG_SND_SOC_PCM1681 is not set ++# CONFIG_SND_SOC_PCM1789_I2C is not set ++# CONFIG_SND_SOC_PCM1792A is not set ++# CONFIG_SND_SOC_PCM179X_I2C is not set ++# CONFIG_SND_SOC_PCM179X_SPI is not set ++# CONFIG_SND_SOC_PCM186X_I2C is not set ++# CONFIG_SND_SOC_PCM186X_SPI is not set ++# CONFIG_SND_SOC_PCM3060_I2C is not set ++# CONFIG_SND_SOC_PCM3060_SPI is not set ++# CONFIG_SND_SOC_PCM3168A_I2C is not set ++# CONFIG_SND_SOC_PCM3168A_SPI is not set ++# CONFIG_SND_SOC_PCM512x_I2C is not set ++# CONFIG_SND_SOC_PCM512x_SPI is not set ++# CONFIG_SND_SOC_QCOM is not set ++# CONFIG_SND_SOC_RK3328 is not set ++# CONFIG_SND_SOC_RT5616 is not set ++# CONFIG_SND_SOC_RT5631 is not set ++# CONFIG_SND_SOC_RT5677_SPI is not set ++# CONFIG_SND_SOC_SGTL5000 is not set ++# CONFIG_SND_SOC_SIMPLE_AMPLIFIER is not set ++# CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set ++# CONFIG_SND_SOC_SOF_TOPLEVEL is not set ++# CONFIG_SND_SOC_SPDIF is not set ++# CONFIG_SND_SOC_SSM2305 is not set ++# CONFIG_SND_SOC_SSM2602_I2C is not set ++# CONFIG_SND_SOC_SSM2602_SPI is not set ++# CONFIG_SND_SOC_SSM4567 is not set ++# CONFIG_SND_SOC_STA32X is not set ++# CONFIG_SND_SOC_STA350 is not set ++# CONFIG_SND_SOC_STI_SAS is not set ++# CONFIG_SND_SOC_TAS2552 is not set ++# CONFIG_SND_SOC_TAS2562 is not set ++# CONFIG_SND_SOC_TAS2770 is not set ++# CONFIG_SND_SOC_TAS5086 is not set ++# CONFIG_SND_SOC_TAS571X is not set ++# CONFIG_SND_SOC_TAS5720 is not set ++# CONFIG_SND_SOC_TAS6424 is not set ++# CONFIG_SND_SOC_TDA7419 is not set ++# CONFIG_SND_SOC_TFA9879 is not set ++# CONFIG_SND_SOC_TLV320ADCX140 is not set ++# CONFIG_SND_SOC_TLV320AIC23_I2C is not set ++# CONFIG_SND_SOC_TLV320AIC23_SPI is not set ++# CONFIG_SND_SOC_TLV320AIC31XX is not set ++# CONFIG_SND_SOC_TLV320AIC32X4_I2C is not set ++# CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set ++# CONFIG_SND_SOC_TLV320AIC3X is not set ++# CONFIG_SND_SOC_TPA6130A2 is not set ++# CONFIG_SND_SOC_TS3A227E is not set ++# CONFIG_SND_SOC_TSCS42XX is not set ++# CONFIG_SND_SOC_TSCS454 is not set ++# CONFIG_SND_SOC_UDA1334 is not set ++# CONFIG_SND_SOC_WM8510 is not set ++# CONFIG_SND_SOC_WM8523 is not set ++# CONFIG_SND_SOC_WM8524 is not set ++# CONFIG_SND_SOC_WM8580 is not set ++# CONFIG_SND_SOC_WM8711 is not set ++# CONFIG_SND_SOC_WM8728 is not set ++# CONFIG_SND_SOC_WM8731 is not set ++# CONFIG_SND_SOC_WM8737 is not set ++# CONFIG_SND_SOC_WM8741 is not set ++# CONFIG_SND_SOC_WM8750 is not set ++# CONFIG_SND_SOC_WM8753 is not set ++# CONFIG_SND_SOC_WM8770 is not set ++# CONFIG_SND_SOC_WM8776 is not set ++# CONFIG_SND_SOC_WM8782 is not set ++# CONFIG_SND_SOC_WM8804_I2C is not set ++# CONFIG_SND_SOC_WM8804_SPI is not set ++# CONFIG_SND_SOC_WM8903 is not set ++# CONFIG_SND_SOC_WM8904 is not set ++# CONFIG_SND_SOC_WM8960 is not set ++# CONFIG_SND_SOC_WM8962 is not set ++# CONFIG_SND_SOC_WM8974 is not set ++# CONFIG_SND_SOC_WM8978 is not set ++# CONFIG_SND_SOC_WM8985 is not set ++# CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER is not set ++# CONFIG_SND_SOC_XILINX_I2S is not set ++# CONFIG_SND_SOC_XILINX_SPDIF is not set ++# CONFIG_SND_SOC_XTFPGA_I2S is not set ++# CONFIG_SND_SOC_ZL38060 is not set ++# CONFIG_SND_SOC_ZX_AUD96P22 is not set ++# CONFIG_SND_SONICVIBES is not set ++# CONFIG_SND_SPI is not set ++# CONFIG_SND_SSCAPE is not set ++# CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI is not set ++# CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_PCI is not set ++# CONFIG_SND_SUN4I_CODEC is not set ++# CONFIG_SND_SUPPORT_OLD_API is not set ++# CONFIG_SND_TIMER is not set ++# CONFIG_SND_TRIDENT is not set ++CONFIG_SND_USB=y ++# CONFIG_SND_USB_6FIRE is not set ++# CONFIG_SND_USB_AUDIO is not set ++# CONFIG_SND_USB_CAIAQ is not set ++# CONFIG_SND_USB_HIFACE is not set ++# CONFIG_SND_USB_POD is not set ++# CONFIG_SND_USB_PODHD is not set ++# CONFIG_SND_USB_TONEPORT is not set ++# CONFIG_SND_USB_UA101 is not set ++# CONFIG_SND_USB_US122L is not set ++# CONFIG_SND_USB_USX2Y is not set ++# CONFIG_SND_USB_VARIAX is not set ++# CONFIG_SND_VERBOSE_PRINTK is not set ++CONFIG_SND_VERBOSE_PROCFS=y ++# CONFIG_SND_VIA82XX is not set ++# CONFIG_SND_VIA82XX_MODEM is not set ++# CONFIG_SND_VIRTUOSO is not set ++# CONFIG_SND_VX222 is not set ++# CONFIG_SND_VXPOCKET is not set ++# CONFIG_SND_WAVEFRONT is not set ++CONFIG_SND_X86=y ++# CONFIG_SND_XEN_FRONTEND is not set ++# CONFIG_SND_YMFPCI is not set ++# CONFIG_SNI_RM is not set ++# CONFIG_SOCIONEXT_SYNQUACER_PREITS is not set ++# CONFIG_SOCK_CGROUP_DATA is not set ++# CONFIG_SOC_AM33XX is not set ++# CONFIG_SOC_AM43XX is not set ++# CONFIG_SOC_BRCMSTB is not set ++# CONFIG_SOC_CAMERA is not set ++# CONFIG_SOC_DRA7XX is not set ++# CONFIG_SOC_HAS_OMAP2_SDRC is not set ++# CONFIG_SOC_OMAP5 is not set ++# CONFIG_SOC_TI is not set ++# CONFIG_SOFTLOCKUP_DETECTOR is not set ++# CONFIG_SOFT_WATCHDOG is not set ++# CONFIG_SOLARIS_X86_PARTITION is not set ++# CONFIG_SONYPI is not set ++# CONFIG_SONY_LAPTOP is not set ++# CONFIG_SOUND is not set ++# CONFIG_SOUNDWIRE is not set ++# CONFIG_SOUND_OSS_CORE is not set ++# CONFIG_SOUND_OSS_CORE_PRECLAIM is not set ++# CONFIG_SOUND_PRIME is not set ++# CONFIG_SP5100_TCO is not set ++# CONFIG_SPARSEMEM_MANUAL is not set ++# CONFIG_SPARSEMEM_STATIC is not set ++# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set ++# CONFIG_SPARSE_IRQ is not set ++# CONFIG_SPARSE_RCU_POINTER is not set ++# CONFIG_SPEAKUP is not set ++# CONFIG_SPI is not set ++# CONFIG_SPINLOCK_TEST is not set ++# CONFIG_SPI_ALTERA is not set ++# CONFIG_SPI_AMD is not set ++# CONFIG_SPI_AU1550 is not set ++# CONFIG_SPI_AXI_SPI_ENGINE is not set ++# CONFIG_SPI_BCM2835 is not set ++# CONFIG_SPI_BCM_QSPI is not set ++# CONFIG_SPI_BITBANG is not set ++# CONFIG_SPI_BUTTERFLY is not set ++# CONFIG_SPI_CADENCE is not set ++# CONFIG_SPI_CADENCE_QUADSPI is not set ++# CONFIG_SPI_DEBUG is not set ++# CONFIG_SPI_DESIGNWARE is not set ++# CONFIG_SPI_FSL_DSPI is not set ++# CONFIG_SPI_FSL_ESPI is not set ++# CONFIG_SPI_FSL_SPI is not set ++# CONFIG_SPI_GPIO is not set ++# CONFIG_SPI_GPIO_OLD is not set ++# CONFIG_SPI_IMG_SPFI is not set ++# CONFIG_SPI_LM70_LLP is not set ++# CONFIG_SPI_LOOPBACK_TEST is not set ++# CONFIG_SPI_MASTER is not set ++# CONFIG_SPI_MEM is not set ++# CONFIG_SPI_MPC52xx is not set ++# CONFIG_SPI_MPC52xx_PSC is not set ++# CONFIG_SPI_MTK_QUADSPI is not set ++# CONFIG_SPI_MUX is not set ++# CONFIG_SPI_MXIC is not set ++# CONFIG_SPI_NXP_FLEXSPI is not set ++# CONFIG_SPI_OCTEON is not set ++# CONFIG_SPI_OC_TINY is not set ++# CONFIG_SPI_ORION is not set ++# CONFIG_SPI_PL022 is not set ++# CONFIG_SPI_PPC4xx is not set ++# CONFIG_SPI_PXA2XX is not set ++# CONFIG_SPI_PXA2XX_PCI is not set ++# CONFIG_SPI_QCOM_QSPI is not set ++# CONFIG_SPI_ROCKCHIP is not set ++# CONFIG_SPI_S3C64XX is not set ++# CONFIG_SPI_SC18IS602 is not set ++# CONFIG_SPI_SIFIVE is not set ++# CONFIG_SPI_SLAVE is not set ++# CONFIG_SPI_SPIDEV is not set ++# CONFIG_SPI_THUNDERX is not set ++# CONFIG_SPI_TI_QSPI is not set ++# CONFIG_SPI_TLE62X0 is not set ++# CONFIG_SPI_TOPCLIFF_PCH is not set ++# CONFIG_SPI_XCOMM is not set ++# CONFIG_SPI_XILINX is not set ++# CONFIG_SPI_XWAY is not set ++# CONFIG_SPI_ZYNQMP_GQSPI is not set ++CONFIG_SPLIT_PTLOCK_CPUS=4 ++# CONFIG_SPMI is not set ++# CONFIG_SPS30 is not set ++CONFIG_SQUASHFS=y ++# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set ++# CONFIG_SQUASHFS_DECOMP_MULTI is not set ++CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y ++# CONFIG_SQUASHFS_DECOMP_SINGLE is not set ++CONFIG_SQUASHFS_EMBEDDED=y ++# CONFIG_SQUASHFS_FILE_CACHE is not set ++CONFIG_SQUASHFS_FILE_DIRECT=y ++CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 ++# CONFIG_SQUASHFS_LZ4 is not set ++# CONFIG_SQUASHFS_LZO is not set ++# CONFIG_SQUASHFS_XATTR is not set ++CONFIG_SQUASHFS_XZ=y ++# CONFIG_SQUASHFS_ZLIB is not set ++# CONFIG_SQUASHFS_ZSTD is not set ++# CONFIG_SRAM is not set ++# CONFIG_SRF04 is not set ++# CONFIG_SRF08 is not set ++# CONFIG_SSB is not set ++# CONFIG_SSB_DEBUG is not set ++# CONFIG_SSB_DRIVER_GPIO is not set ++# CONFIG_SSB_HOST_SOC is not set ++# CONFIG_SSB_PCMCIAHOST is not set ++CONFIG_SSB_POSSIBLE=y ++# CONFIG_SSB_SDIOHOST is not set ++# CONFIG_SSB_SILENT is not set ++# CONFIG_SSFDC is not set ++# CONFIG_STACKPROTECTOR is not set ++# CONFIG_STACKPROTECTOR_STRONG is not set ++# CONFIG_STACKTRACE is not set ++CONFIG_STACKTRACE_SUPPORT=y ++# CONFIG_STACK_TRACER is not set ++# CONFIG_STACK_VALIDATION is not set ++CONFIG_STAGING=y ++# CONFIG_STAGING_BOARD is not set ++# CONFIG_STAGING_GASKET_FRAMEWORK is not set ++# CONFIG_STAGING_MEDIA is not set ++CONFIG_STANDALONE=y ++# CONFIG_STATIC_KEYS_SELFTEST is not set ++# CONFIG_STATIC_USERMODEHELPER is not set ++CONFIG_STDBINUTILS=y ++# CONFIG_STE10XP is not set ++# CONFIG_STE_MODEM_RPROC is not set ++# CONFIG_STK3310 is not set ++# CONFIG_STK8312 is not set ++# CONFIG_STK8BA50 is not set ++# CONFIG_STM is not set ++# CONFIG_STMMAC_ETH is not set ++# CONFIG_STMMAC_PCI is not set ++# CONFIG_STMMAC_PLATFORM is not set ++# CONFIG_STM_DUMMY is not set ++# CONFIG_STM_SOURCE_CONSOLE is not set ++CONFIG_STP=y ++# CONFIG_STREAM_PARSER is not set ++# CONFIG_STRICT_DEVMEM is not set ++CONFIG_STRICT_KERNEL_RWX=y ++CONFIG_STRICT_MODULE_RWX=y ++# CONFIG_STRING_SELFTEST is not set ++CONFIG_STRIP_ASM_SYMS=y ++# CONFIG_STX104 is not set ++# CONFIG_ST_UVIS25 is not set ++# CONFIG_SUN4I_GPADC is not set ++# CONFIG_SUN50I_DE2_BUS is not set ++# CONFIG_SUN50I_ERRATUM_UNKNOWN1 is not set ++# CONFIG_SUNDANCE is not set ++# CONFIG_SUNGEM is not set ++# CONFIG_SUNRPC is not set ++# CONFIG_SUNRPC_DEBUG is not set ++CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES=y ++# CONFIG_SUNRPC_GSS is not set ++# CONFIG_SUNXI_SRAM is not set ++# CONFIG_SUN_PARTITION is not set ++# CONFIG_SURFACE_3_BUTTON is not set ++# CONFIG_SUSPEND is not set ++# CONFIG_SUSPEND_SKIP_SYNC is not set ++CONFIG_SWAP=y ++# CONFIG_SWCONFIG is not set ++# CONFIG_SWCONFIG_B53 is not set ++# CONFIG_SWCONFIG_B53_MDIO_DRIVER is not set ++# CONFIG_SWCONFIG_B53_MMAP_DRIVER is not set ++# CONFIG_SWCONFIG_B53_SPI_DRIVER is not set ++# CONFIG_SWCONFIG_B53_SRAB_DRIVER is not set ++# CONFIG_SWCONFIG_LEDS is not set ++# CONFIG_SW_SYNC is not set ++# CONFIG_SX9310 is not set ++# CONFIG_SX9500 is not set ++# CONFIG_SXGBE_ETH is not set ++CONFIG_SYMBOLIC_ERRNAME=y ++# CONFIG_SYNCLINK_CS is not set ++# CONFIG_SYNC_FILE is not set ++# CONFIG_SYNOPSYS_DWC_ETH_QOS is not set ++CONFIG_SYN_COOKIES=y ++# CONFIG_SYSCON_REBOOT_MODE is not set ++CONFIG_SYSCTL=y ++# CONFIG_SYSCTL_SYSCALL is not set ++CONFIG_SYSFS=y ++# CONFIG_SYSFS_DEPRECATED is not set ++# CONFIG_SYSFS_DEPRECATED_V2 is not set ++# CONFIG_SYSFS_SYSCALL is not set ++# CONFIG_SYSTEMPORT is not set ++# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set ++# CONFIG_SYSTEM_DATA_VERIFICATION is not set ++# CONFIG_SYSTEM_TRUSTED_KEYRING is not set ++CONFIG_SYSTEM_TRUSTED_KEYS="" ++# CONFIG_SYSV68_PARTITION is not set ++CONFIG_SYSVIPC=y ++CONFIG_SYSVIPC_SYSCTL=y ++# CONFIG_SYSV_FS is not set ++# CONFIG_SYS_HYPERVISOR is not set ++# CONFIG_T5403 is not set ++# CONFIG_TARGET_CORE is not set ++# CONFIG_TASKSTATS is not set ++# CONFIG_TASKS_RCU is not set ++CONFIG_TASKS_TRACE_RCU_READ_MB=y ++# CONFIG_TASK_XACCT is not set ++# CONFIG_TC35815 is not set ++# CONFIG_TCG_ATMEL is not set ++# CONFIG_TCG_CRB is not set ++# CONFIG_TCG_FTPM_TEE is not set ++# CONFIG_TCG_INFINEON is not set ++# CONFIG_TCG_NSC is not set ++# CONFIG_TCG_ST33_I2C is not set ++# CONFIG_TCG_TIS is not set ++# CONFIG_TCG_TIS_I2C_ATMEL is not set ++# CONFIG_TCG_TIS_I2C_INFINEON is not set ++# CONFIG_TCG_TIS_I2C_NUVOTON is not set ++# CONFIG_TCG_TIS_SPI is not set ++# CONFIG_TCG_TIS_ST33ZP24_I2C is not set ++# CONFIG_TCG_TIS_ST33ZP24_SPI is not set ++# CONFIG_TCG_TPM is not set ++# CONFIG_TCG_VTPM_PROXY is not set ++# CONFIG_TCG_XEN is not set ++# CONFIG_TCIC is not set ++CONFIG_TCP_CONG_ADVANCED=y ++# CONFIG_TCP_CONG_BBR is not set ++# CONFIG_TCP_CONG_BIC is not set ++# CONFIG_TCP_CONG_CDG is not set ++CONFIG_TCP_CONG_CUBIC=y ++# CONFIG_TCP_CONG_DCTCP is not set ++# CONFIG_TCP_CONG_HSTCP is not set ++# CONFIG_TCP_CONG_HTCP is not set ++# CONFIG_TCP_CONG_HYBLA is not set ++# CONFIG_TCP_CONG_ILLINOIS is not set ++# CONFIG_TCP_CONG_LP is not set ++# CONFIG_TCP_CONG_NV is not set ++# CONFIG_TCP_CONG_SCALABLE is not set ++# CONFIG_TCP_CONG_VEGAS is not set ++# CONFIG_TCP_CONG_VENO is not set ++# CONFIG_TCP_CONG_WESTWOOD is not set ++# CONFIG_TCP_CONG_YEAH is not set ++# CONFIG_TCP_MD5SIG is not set ++# CONFIG_TCS3414 is not set ++# CONFIG_TCS3472 is not set ++# CONFIG_TEE is not set ++# CONFIG_TEGRA_AHB is not set ++# CONFIG_TEGRA_HOST1X is not set ++# CONFIG_TEHUTI is not set ++# CONFIG_TERANETICS_PHY is not set ++# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set ++# CONFIG_TEST_BITFIELD is not set ++# CONFIG_TEST_BITMAP is not set ++# CONFIG_TEST_BITOPS is not set ++# CONFIG_TEST_BLACKHOLE_DEV is not set ++# CONFIG_TEST_BPF is not set ++# CONFIG_TEST_FIRMWARE is not set ++# CONFIG_TEST_FREE_PAGES is not set ++# CONFIG_TEST_HASH is not set ++# CONFIG_TEST_HEXDUMP is not set ++# CONFIG_TEST_IDA is not set ++# CONFIG_TEST_KMOD is not set ++# CONFIG_TEST_KSTRTOX is not set ++# CONFIG_TEST_LIST_SORT is not set ++# CONFIG_TEST_LKM is not set ++# CONFIG_TEST_LOCKUP is not set ++# CONFIG_TEST_MEMCAT_P is not set ++# CONFIG_TEST_MEMINIT is not set ++# CONFIG_TEST_MIN_HEAP is not set ++# CONFIG_TEST_OVERFLOW is not set ++# CONFIG_TEST_POWER is not set ++# CONFIG_TEST_PRINTF is not set ++# CONFIG_TEST_RHASHTABLE is not set ++# CONFIG_TEST_SORT is not set ++# CONFIG_TEST_STACKINIT is not set ++# CONFIG_TEST_STATIC_KEYS is not set ++# CONFIG_TEST_STRING_HELPERS is not set ++# CONFIG_TEST_STRSCPY is not set ++# CONFIG_TEST_SYSCTL is not set ++# CONFIG_TEST_UDELAY is not set ++# CONFIG_TEST_USER_COPY is not set ++# CONFIG_TEST_UUID is not set ++# CONFIG_TEST_VMALLOC is not set ++# CONFIG_TEST_XARRAY is not set ++CONFIG_TEXTSEARCH=y ++# CONFIG_TEXTSEARCH_BM is not set ++# CONFIG_TEXTSEARCH_FSM is not set ++# CONFIG_TEXTSEARCH_KMP is not set ++# CONFIG_THERMAL is not set ++# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set ++# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set ++# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set ++# CONFIG_THERMAL_EMULATION is not set ++# CONFIG_THERMAL_GOV_BANG_BANG is not set ++# CONFIG_THERMAL_GOV_FAIR_SHARE is not set ++# CONFIG_THERMAL_GOV_POWER_ALLOCATOR is not set ++# CONFIG_THERMAL_GOV_USER_SPACE is not set ++# CONFIG_THERMAL_HWMON is not set ++# CONFIG_THERMAL_MMIO is not set ++# CONFIG_THERMAL_NETLINK is not set ++# CONFIG_THERMAL_STATISTICS is not set ++# CONFIG_THERMAL_WRITABLE_TRIPS is not set ++# CONFIG_THINKPAD_ACPI is not set ++CONFIG_THIN_ARCHIVES=y ++# CONFIG_THRUSTMASTER_FF is not set ++# CONFIG_THUMB2_KERNEL is not set ++# CONFIG_THUNDERBOLT is not set ++# CONFIG_THUNDER_NIC_BGX is not set ++# CONFIG_THUNDER_NIC_PF is not set ++# CONFIG_THUNDER_NIC_RGX is not set ++# CONFIG_THUNDER_NIC_VF is not set ++# CONFIG_TICK_CPU_ACCOUNTING is not set ++CONFIG_TICK_ONESHOT=y ++# CONFIG_TIFM_CORE is not set ++# CONFIG_TIGON3 is not set ++# CONFIG_TIMB_DMA is not set ++CONFIG_TIMERFD=y ++# CONFIG_TIMER_STATS is not set ++# CONFIG_TIME_NS is not set ++# CONFIG_TINYDRM_HX8357D is not set ++# CONFIG_TINYDRM_ILI9225 is not set ++# CONFIG_TINYDRM_ILI9341 is not set ++# CONFIG_TINYDRM_MI0283QT is not set ++# CONFIG_TINYDRM_REPAPER is not set ++# CONFIG_TINYDRM_ST7586 is not set ++# CONFIG_TINYDRM_ST7735R is not set ++CONFIG_TINY_RCU=y ++# CONFIG_TIPC is not set ++# CONFIG_TI_ADC081C is not set ++# CONFIG_TI_ADC0832 is not set ++# CONFIG_TI_ADC084S021 is not set ++# CONFIG_TI_ADC108S102 is not set ++# CONFIG_TI_ADC12138 is not set ++# CONFIG_TI_ADC128S052 is not set ++# CONFIG_TI_ADC161S626 is not set ++# CONFIG_TI_ADS1015 is not set ++# CONFIG_TI_ADS124S08 is not set ++# CONFIG_TI_ADS7950 is not set ++# CONFIG_TI_ADS8344 is not set ++# CONFIG_TI_ADS8688 is not set ++# CONFIG_TI_AM335X_ADC is not set ++# CONFIG_TI_CPSW is not set ++# CONFIG_TI_CPSW_ALE is not set ++# CONFIG_TI_CPSW_PHY_SEL is not set ++# CONFIG_TI_CPTS is not set ++# CONFIG_TI_DAC082S085 is not set ++# CONFIG_TI_DAC5571 is not set ++# CONFIG_TI_DAC7311 is not set ++# CONFIG_TI_DAC7512 is not set ++# CONFIG_TI_DAC7612 is not set ++# CONFIG_TI_DAVINCI_CPDMA is not set ++# CONFIG_TI_DAVINCI_MDIO is not set ++# CONFIG_TI_ST is not set ++# CONFIG_TI_SYSCON_RESET is not set ++# CONFIG_TI_TLC4541 is not set ++# CONFIG_TLAN is not set ++# CONFIG_TLS is not set ++# CONFIG_TMD_HERMES is not set ++# CONFIG_TMP006 is not set ++# CONFIG_TMP007 is not set ++CONFIG_TMPFS=y ++# CONFIG_TMPFS_INODE64 is not set ++# CONFIG_TMPFS_POSIX_ACL is not set ++CONFIG_TMPFS_XATTR=y ++# CONFIG_TOPSTAR_LAPTOP is not set ++# CONFIG_TORTURE_TEST is not set ++# CONFIG_TOSHIBA_HAPS is not set ++# CONFIG_TOUCHSCREEN_88PM860X is not set ++# CONFIG_TOUCHSCREEN_AD7877 is not set ++# CONFIG_TOUCHSCREEN_AD7879 is not set ++# CONFIG_TOUCHSCREEN_AD7879_I2C is not set ++# CONFIG_TOUCHSCREEN_AD7879_SPI is not set ++# CONFIG_TOUCHSCREEN_ADC is not set ++# CONFIG_TOUCHSCREEN_ADS7846 is not set ++# CONFIG_TOUCHSCREEN_AR1021_I2C is not set ++# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set ++# CONFIG_TOUCHSCREEN_ATMEL_MXT_T37 is not set ++# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set ++# CONFIG_TOUCHSCREEN_BU21013 is not set ++# CONFIG_TOUCHSCREEN_BU21029 is not set ++# CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set ++# CONFIG_TOUCHSCREEN_CHIPONE_ICN8505 is not set ++# CONFIG_TOUCHSCREEN_COLIBRI_VF50 is not set ++# CONFIG_TOUCHSCREEN_CY8CTMA140 is not set ++# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set ++# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set ++# CONFIG_TOUCHSCREEN_CYTTSP4_I2C is not set ++# CONFIG_TOUCHSCREEN_CYTTSP4_SPI is not set ++# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set ++# CONFIG_TOUCHSCREEN_CYTTSP_I2C is not set ++# CONFIG_TOUCHSCREEN_CYTTSP_SPI is not set ++# CONFIG_TOUCHSCREEN_DA9034 is not set ++# CONFIG_TOUCHSCREEN_DA9052 is not set ++# CONFIG_TOUCHSCREEN_DYNAPRO is not set ++# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set ++# CONFIG_TOUCHSCREEN_EETI is not set ++# CONFIG_TOUCHSCREEN_EGALAX is not set ++# CONFIG_TOUCHSCREEN_EGALAX_SERIAL is not set ++# CONFIG_TOUCHSCREEN_EKTF2127 is not set ++# CONFIG_TOUCHSCREEN_ELAN is not set ++# CONFIG_TOUCHSCREEN_ELO is not set ++# CONFIG_TOUCHSCREEN_EXC3000 is not set ++# CONFIG_TOUCHSCREEN_FUJITSU is not set ++# CONFIG_TOUCHSCREEN_GOODIX is not set ++# CONFIG_TOUCHSCREEN_GUNZE is not set ++# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set ++# CONFIG_TOUCHSCREEN_HIDEEP is not set ++# CONFIG_TOUCHSCREEN_HP600 is not set ++# CONFIG_TOUCHSCREEN_HP7XX is not set ++# CONFIG_TOUCHSCREEN_HTCPEN is not set ++# CONFIG_TOUCHSCREEN_ILI210X is not set ++# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set ++# CONFIG_TOUCHSCREEN_INEXIO is not set ++# CONFIG_TOUCHSCREEN_IPAQ_MICRO is not set ++# CONFIG_TOUCHSCREEN_IPROC is not set ++# CONFIG_TOUCHSCREEN_IQS5XX is not set ++# CONFIG_TOUCHSCREEN_LPC32XX is not set ++# CONFIG_TOUCHSCREEN_MAX11801 is not set ++# CONFIG_TOUCHSCREEN_MC13783 is not set ++# CONFIG_TOUCHSCREEN_MCS5000 is not set ++# CONFIG_TOUCHSCREEN_MELFAS_MIP4 is not set ++# CONFIG_TOUCHSCREEN_MIGOR is not set ++# CONFIG_TOUCHSCREEN_MK712 is not set ++# CONFIG_TOUCHSCREEN_MMS114 is not set ++# CONFIG_TOUCHSCREEN_MTOUCH is not set ++# CONFIG_TOUCHSCREEN_MX25 is not set ++# CONFIG_TOUCHSCREEN_MXS_LRADC is not set ++# CONFIG_TOUCHSCREEN_PCAP is not set ++# CONFIG_TOUCHSCREEN_PENMOUNT is not set ++# CONFIG_TOUCHSCREEN_PIXCIR is not set ++# CONFIG_TOUCHSCREEN_PROPERTIES is not set ++# CONFIG_TOUCHSCREEN_RASPBERRYPI_FW is not set ++# CONFIG_TOUCHSCREEN_RM_TS is not set ++# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set ++# CONFIG_TOUCHSCREEN_RPI_FT5406 is not set ++# CONFIG_TOUCHSCREEN_S3C2410 is not set ++# CONFIG_TOUCHSCREEN_S6SY761 is not set ++# CONFIG_TOUCHSCREEN_SILEAD is not set ++# CONFIG_TOUCHSCREEN_SIS_I2C is not set ++# CONFIG_TOUCHSCREEN_ST1232 is not set ++# CONFIG_TOUCHSCREEN_STMFTS is not set ++# CONFIG_TOUCHSCREEN_STMPE is not set ++# CONFIG_TOUCHSCREEN_SUN4I is not set ++# CONFIG_TOUCHSCREEN_SUR40 is not set ++# CONFIG_TOUCHSCREEN_SURFACE3_SPI is not set ++# CONFIG_TOUCHSCREEN_SX8654 is not set ++# CONFIG_TOUCHSCREEN_TI_AM335X_TSC is not set ++# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set ++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set ++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set ++# CONFIG_TOUCHSCREEN_TPS6507X is not set ++# CONFIG_TOUCHSCREEN_TS4800 is not set ++# CONFIG_TOUCHSCREEN_TSC2004 is not set ++# CONFIG_TOUCHSCREEN_TSC2005 is not set ++# CONFIG_TOUCHSCREEN_TSC2007 is not set ++# CONFIG_TOUCHSCREEN_TSC2007_IIO is not set ++# CONFIG_TOUCHSCREEN_TSC200X_CORE is not set ++# CONFIG_TOUCHSCREEN_TSC_SERIO is not set ++# CONFIG_TOUCHSCREEN_UCB1400 is not set ++# CONFIG_TOUCHSCREEN_USB_3M is not set ++# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set ++# CONFIG_TOUCHSCREEN_USB_DMC_TSC10 is not set ++# CONFIG_TOUCHSCREEN_USB_E2I is not set ++# CONFIG_TOUCHSCREEN_USB_EASYTOUCH is not set ++# CONFIG_TOUCHSCREEN_USB_EGALAX is not set ++# CONFIG_TOUCHSCREEN_USB_ELO is not set ++# CONFIG_TOUCHSCREEN_USB_ETT_TC45USB is not set ++# CONFIG_TOUCHSCREEN_USB_ETURBO is not set ++# CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH is not set ++# CONFIG_TOUCHSCREEN_USB_GOTOP is not set ++# CONFIG_TOUCHSCREEN_USB_GUNZE is not set ++# CONFIG_TOUCHSCREEN_USB_IDEALTEK is not set ++# CONFIG_TOUCHSCREEN_USB_IRTOUCH is not set ++# CONFIG_TOUCHSCREEN_USB_ITM is not set ++# CONFIG_TOUCHSCREEN_USB_JASTEC is not set ++# CONFIG_TOUCHSCREEN_USB_NEXIO is not set ++# CONFIG_TOUCHSCREEN_USB_PANJIT is not set ++# CONFIG_TOUCHSCREEN_USB_ZYTRONIC is not set ++# CONFIG_TOUCHSCREEN_W90X900 is not set ++# CONFIG_TOUCHSCREEN_WACOM_I2C is not set ++# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set ++# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set ++# CONFIG_TOUCHSCREEN_WM831X is not set ++# CONFIG_TOUCHSCREEN_WM9705 is not set ++# CONFIG_TOUCHSCREEN_WM9712 is not set ++# CONFIG_TOUCHSCREEN_WM9713 is not set ++# CONFIG_TOUCHSCREEN_WM97XX is not set ++# CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE is not set ++# CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE is not set ++# CONFIG_TOUCHSCREEN_ZET6223 is not set ++# CONFIG_TOUCHSCREEN_ZFORCE is not set ++# CONFIG_TPL0102 is not set ++# CONFIG_TPS6105X is not set ++# CONFIG_TPS65010 is not set ++# CONFIG_TPS6507X is not set ++# CONFIG_TRACEPOINT_BENCHMARK is not set ++# CONFIG_TRACER_SNAPSHOT is not set ++# CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP is not set ++# CONFIG_TRACE_BRANCH_PROFILING is not set ++# CONFIG_TRACE_EVAL_MAP_FILE is not set ++CONFIG_TRACE_IRQFLAGS_SUPPORT=y ++# CONFIG_TRACE_SINK is not set ++# CONFIG_TRACING_EVENTS_GPIO is not set ++CONFIG_TRACING_SUPPORT=y ++CONFIG_TRAD_SIGNALS=y ++# CONFIG_TRANSPARENT_HUGEPAGE is not set ++# CONFIG_TREE_RCU is not set ++# CONFIG_TREE_RCU_TRACE is not set ++# CONFIG_TRIM_UNUSED_KSYMS is not set ++# CONFIG_TRUSTED_FOUNDATIONS is not set ++# CONFIG_TRUSTED_KEYS is not set ++# CONFIG_TSL2583 is not set ++# CONFIG_TSL2772 is not set ++# CONFIG_TSL2x7x is not set ++# CONFIG_TSL4531 is not set ++# CONFIG_TSYS01 is not set ++# CONFIG_TSYS02D is not set ++# CONFIG_TTPCI_EEPROM is not set ++CONFIG_TTY=y ++# CONFIG_TTY_PRINTK is not set ++# CONFIG_TUN is not set ++# CONFIG_TUN_VNET_CROSS_LE is not set ++# CONFIG_TWL4030_CORE is not set ++# CONFIG_TWL4030_MADC is not set ++# CONFIG_TWL6030_GPADC is not set ++# CONFIG_TWL6040_CORE is not set ++# CONFIG_TYPEC is not set ++# CONFIG_TYPEC_TCPM is not set ++# CONFIG_TYPEC_UCSI is not set ++# CONFIG_TYPHOON is not set ++# CONFIG_UACCESS_WITH_MEMCPY is not set ++# CONFIG_UBIFS_ATIME_SUPPORT is not set ++# CONFIG_UBIFS_FS_AUTHENTICATION is not set ++# CONFIG_UBIFS_FS_ENCRYPTION is not set ++# CONFIG_UBIFS_FS_SECURITY is not set ++CONFIG_UBIFS_FS_XATTR=y ++# CONFIG_UBIFS_FS_ZLIB is not set ++# CONFIG_UBIFS_FS_ZSTD is not set ++# CONFIG_UBSAN is not set ++CONFIG_UBSAN_ALIGNMENT=y ++# CONFIG_UCB1400_CORE is not set ++# CONFIG_UCSI is not set ++# CONFIG_UDF_FS is not set ++# CONFIG_UDMABUF is not set ++CONFIG_UEVENT_HELPER=y ++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" ++# CONFIG_UFS_FS is not set ++# CONFIG_UHID is not set ++CONFIG_UID16=y ++# CONFIG_UIO is not set ++# CONFIG_ULTRA is not set ++# CONFIG_ULTRIX_PARTITION is not set ++# CONFIG_UNICODE is not set ++# CONFIG_UNISYSSPAR is not set ++# CONFIG_UNISYS_VISORBUS is not set ++CONFIG_UNIX=y ++CONFIG_UNIX98_PTYS=y ++# CONFIG_UNIXWARE_DISKLABEL is not set ++# CONFIG_UNIX_DIAG is not set ++CONFIG_UNIX_SCM=y ++# CONFIG_UNUSED_SYMBOLS is not set ++# CONFIG_UNWINDER_FRAME_POINTER is not set ++# CONFIG_UPROBES is not set ++# CONFIG_UPROBE_EVENTS is not set ++# CONFIG_US5182D is not set ++# CONFIG_USB is not set ++# CONFIG_USB4 is not set ++# CONFIG_USBIP_CORE is not set ++CONFIG_USBIP_VHCI_HC_PORTS=8 ++CONFIG_USBIP_VHCI_NR_HCS=1 ++# CONFIG_USBIP_VUDC is not set ++# CONFIG_USBPCWATCHDOG is not set ++# CONFIG_USB_ACM is not set ++# CONFIG_USB_ADUTUX is not set ++# CONFIG_USB_AIRSPY is not set ++CONFIG_USB_ALI_M5632=y ++# CONFIG_USB_AMD5536UDC is not set ++CONFIG_USB_AN2720=y ++# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set ++# CONFIG_USB_APPLEDISPLAY is not set ++CONFIG_USB_ARCH_HAS_HCD=y ++CONFIG_USB_ARMLINUX=y ++# CONFIG_USB_ATM is not set ++CONFIG_USB_AUTOSUSPEND_DELAY=2 ++# CONFIG_USB_BDC_UDC is not set ++CONFIG_USB_BELKIN=y ++# CONFIG_USB_C67X00_HCD is not set ++# CONFIG_USB_CATC is not set ++# CONFIG_USB_CDC_COMPOSITE is not set ++# CONFIG_USB_CDNS3 is not set ++# CONFIG_USB_CHAOSKEY is not set ++# CONFIG_USB_CHIPIDEA is not set ++# CONFIG_USB_CONFIGFS is not set ++# CONFIG_USB_CONN_GPIO is not set ++# CONFIG_USB_CXACRU is not set ++# CONFIG_USB_CYPRESS_CY7C63 is not set ++# CONFIG_USB_CYTHERM is not set ++CONFIG_USB_DEFAULT_PERSIST=y ++# CONFIG_USB_DSBR is not set ++# CONFIG_USB_DUMMY_HCD is not set ++# CONFIG_USB_DWC2 is not set ++# CONFIG_USB_DWC2_DEBUG is not set ++# CONFIG_USB_DWC2_DUAL_ROLE is not set ++# CONFIG_USB_DWC2_HOST is not set ++# CONFIG_USB_DWC2_PERIPHERAL is not set ++# CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set ++# CONFIG_USB_DWC3 is not set ++# CONFIG_USB_DWC3_EXYNOS is not set ++# CONFIG_USB_DWC3_HAPS is not set ++# CONFIG_USB_DWC3_KEYSTONE is not set ++# CONFIG_USB_DWC3_OF_SIMPLE is not set ++# CONFIG_USB_DWC3_PCI is not set ++# CONFIG_USB_DWC3_QCOM is not set ++# CONFIG_USB_DWC3_ULPI is not set ++# CONFIG_USB_DYNAMIC_MINORS is not set ++# CONFIG_USB_EG20T is not set ++# CONFIG_USB_EHCI_ATH79 is not set ++# CONFIG_USB_EHCI_FSL is not set ++# CONFIG_USB_EHCI_HCD is not set ++# CONFIG_USB_EHCI_HCD_AT91 is not set ++# CONFIG_USB_EHCI_HCD_OMAP is not set ++# CONFIG_USB_EHCI_HCD_PPC_OF is not set ++# CONFIG_USB_EHCI_MSM is not set ++# CONFIG_USB_EHCI_MV is not set ++CONFIG_USB_EHCI_ROOT_HUB_TT=y ++CONFIG_USB_EHCI_TT_NEWSCHED=y ++# CONFIG_USB_EHSET_TEST_FIXTURE is not set ++# CONFIG_USB_EMI26 is not set ++# CONFIG_USB_EMI62 is not set ++# CONFIG_USB_EPSON2888 is not set ++# CONFIG_USB_EZUSB_FX2 is not set ++# CONFIG_USB_FEW_INIT_RETRIES is not set ++# CONFIG_USB_FOTG210_HCD is not set ++# CONFIG_USB_FOTG210_UDC is not set ++# CONFIG_USB_FSL_USB2 is not set ++# CONFIG_USB_FTDI_ELAN is not set ++# CONFIG_USB_FUNCTIONFS is not set ++# CONFIG_USB_FUSB300 is not set ++# CONFIG_USB_GADGET is not set ++# CONFIG_USB_GADGETFS is not set ++# CONFIG_USB_GADGET_DEBUG is not set ++# CONFIG_USB_GADGET_DEBUG_FILES is not set ++# CONFIG_USB_GADGET_DEBUG_FS is not set ++CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 ++CONFIG_USB_GADGET_VBUS_DRAW=2 ++# CONFIG_USB_GADGET_XILINX is not set ++# CONFIG_USB_GL860 is not set ++# CONFIG_USB_GOKU is not set ++# CONFIG_USB_GPIO_VBUS is not set ++# CONFIG_USB_GR_UDC is not set ++# CONFIG_USB_GSPCA is not set ++# CONFIG_USB_GSPCA_BENQ is not set ++# CONFIG_USB_GSPCA_CONEX is not set ++# CONFIG_USB_GSPCA_CPIA1 is not set ++# CONFIG_USB_GSPCA_DTCS033 is not set ++# CONFIG_USB_GSPCA_ETOMS is not set ++# CONFIG_USB_GSPCA_FINEPIX is not set ++# CONFIG_USB_GSPCA_JEILINJ is not set ++# CONFIG_USB_GSPCA_JL2005BCD is not set ++# CONFIG_USB_GSPCA_KINECT is not set ++# CONFIG_USB_GSPCA_KONICA is not set ++# CONFIG_USB_GSPCA_MARS is not set ++# CONFIG_USB_GSPCA_MR97310A is not set ++# CONFIG_USB_GSPCA_NW80X is not set ++# CONFIG_USB_GSPCA_OV519 is not set ++# CONFIG_USB_GSPCA_OV534 is not set ++# CONFIG_USB_GSPCA_OV534_9 is not set ++# CONFIG_USB_GSPCA_PAC207 is not set ++# CONFIG_USB_GSPCA_PAC7302 is not set ++# CONFIG_USB_GSPCA_PAC7311 is not set ++# CONFIG_USB_GSPCA_SE401 is not set ++# CONFIG_USB_GSPCA_SN9C2028 is not set ++# CONFIG_USB_GSPCA_SN9C20X is not set ++# CONFIG_USB_GSPCA_SONIXB is not set ++# CONFIG_USB_GSPCA_SONIXJ is not set ++# CONFIG_USB_GSPCA_SPCA1528 is not set ++# CONFIG_USB_GSPCA_SPCA500 is not set ++# CONFIG_USB_GSPCA_SPCA501 is not set ++# CONFIG_USB_GSPCA_SPCA505 is not set ++# CONFIG_USB_GSPCA_SPCA506 is not set ++# CONFIG_USB_GSPCA_SPCA508 is not set ++# CONFIG_USB_GSPCA_SPCA561 is not set ++# CONFIG_USB_GSPCA_SQ905 is not set ++# CONFIG_USB_GSPCA_SQ905C is not set ++# CONFIG_USB_GSPCA_SQ930X is not set ++# CONFIG_USB_GSPCA_STK014 is not set ++# CONFIG_USB_GSPCA_STK1135 is not set ++# CONFIG_USB_GSPCA_STV0680 is not set ++# CONFIG_USB_GSPCA_SUNPLUS is not set ++# CONFIG_USB_GSPCA_T613 is not set ++# CONFIG_USB_GSPCA_TOPRO is not set ++# CONFIG_USB_GSPCA_TOUPTEK is not set ++# CONFIG_USB_GSPCA_TV8532 is not set ++# CONFIG_USB_GSPCA_VC032X is not set ++# CONFIG_USB_GSPCA_VICAM is not set ++# CONFIG_USB_GSPCA_XIRLINK_CIT is not set ++# CONFIG_USB_GSPCA_ZC3XX is not set ++# CONFIG_USB_G_ACM_MS is not set ++# CONFIG_USB_G_DBGP is not set ++# CONFIG_USB_G_HID is not set ++# CONFIG_USB_G_MULTI is not set ++# CONFIG_USB_G_NCM is not set ++# CONFIG_USB_G_NOKIA is not set ++# CONFIG_USB_G_PRINTER is not set ++# CONFIG_USB_G_SERIAL is not set ++# CONFIG_USB_G_WEBCAM is not set ++# CONFIG_USB_HACKRF is not set ++# CONFIG_USB_HCD_TEST_MODE is not set ++# CONFIG_USB_HID is not set ++# CONFIG_USB_HIDDEV is not set ++# CONFIG_USB_HSIC_USB3503 is not set ++# CONFIG_USB_HSIC_USB4604 is not set ++# CONFIG_USB_HSO is not set ++# CONFIG_USB_HUB_USB251XB is not set ++# CONFIG_USB_HWA_HCD is not set ++# CONFIG_USB_IDMOUSE is not set ++# CONFIG_USB_IMX21_HCD is not set ++# CONFIG_USB_IOWARRIOR is not set ++# CONFIG_USB_IPHETH is not set ++# CONFIG_USB_ISIGHTFW is not set ++# CONFIG_USB_ISP116X_HCD is not set ++# CONFIG_USB_ISP1301 is not set ++# CONFIG_USB_ISP1362_HCD is not set ++# CONFIG_USB_ISP1760 is not set ++# CONFIG_USB_ISP1760_HCD is not set ++# CONFIG_USB_KAWETH is not set ++# CONFIG_USB_KBD is not set ++# CONFIG_USB_KC2190 is not set ++# CONFIG_USB_LAN78XX is not set ++# CONFIG_USB_LCD is not set ++# CONFIG_USB_LD is not set ++# CONFIG_USB_LED is not set ++# CONFIG_USB_LEDS_TRIGGER_USBPORT is not set ++# CONFIG_USB_LED_TRIG is not set ++# CONFIG_USB_LEGOTOWER is not set ++# CONFIG_USB_LGM_PHY is not set ++# CONFIG_USB_LINK_LAYER_TEST is not set ++# CONFIG_USB_M5602 is not set ++# CONFIG_USB_M66592 is not set ++# CONFIG_USB_MASS_STORAGE is not set ++# CONFIG_USB_MAX3421_HCD is not set ++# CONFIG_USB_MDC800 is not set ++# CONFIG_USB_MICROTEK is not set ++# CONFIG_USB_MIDI_GADGET is not set ++# CONFIG_USB_MON is not set ++# CONFIG_USB_MOUSE is not set ++# CONFIG_USB_MSI2500 is not set ++# CONFIG_USB_MSM_OTG is not set ++# CONFIG_USB_MTU3 is not set ++# CONFIG_USB_MUSB_HDRC is not set ++# CONFIG_USB_MV_U3D is not set ++# CONFIG_USB_MV_UDC is not set ++# CONFIG_USB_MXS_PHY is not set ++# CONFIG_USB_NET2272 is not set ++# CONFIG_USB_NET2280 is not set ++# CONFIG_USB_NET_AQC111 is not set ++# CONFIG_USB_NET_AX88179_178A is not set ++# CONFIG_USB_NET_AX8817X is not set ++# CONFIG_USB_NET_CDCETHER is not set ++# CONFIG_USB_NET_CDC_EEM is not set ++# CONFIG_USB_NET_CDC_MBIM is not set ++# CONFIG_USB_NET_CDC_NCM is not set ++# CONFIG_USB_NET_CDC_SUBSET is not set ++# CONFIG_USB_NET_CH9200 is not set ++# CONFIG_USB_NET_CX82310_ETH is not set ++# CONFIG_USB_NET_DM9601 is not set ++# CONFIG_USB_NET_DRIVERS is not set ++# CONFIG_USB_NET_GL620A is not set ++# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set ++# CONFIG_USB_NET_INT51X1 is not set ++# CONFIG_USB_NET_KALMIA is not set ++# CONFIG_USB_NET_MCS7830 is not set ++# CONFIG_USB_NET_NET1080 is not set ++# CONFIG_USB_NET_PLUSB is not set ++# CONFIG_USB_NET_QMI_WWAN is not set ++# CONFIG_USB_NET_RNDIS_HOST is not set ++# CONFIG_USB_NET_RNDIS_WLAN is not set ++# CONFIG_USB_NET_SMSC75XX is not set ++# CONFIG_USB_NET_SMSC95XX is not set ++# CONFIG_USB_NET_SR9700 is not set ++# CONFIG_USB_NET_SR9800 is not set ++# CONFIG_USB_NET_ZAURUS is not set ++# CONFIG_USB_OHCI_HCD is not set ++# CONFIG_USB_OHCI_HCD_PCI is not set ++# CONFIG_USB_OHCI_HCD_PPC_OF is not set ++# CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set ++# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set ++# CONFIG_USB_OHCI_HCD_SSB is not set ++CONFIG_USB_OHCI_LITTLE_ENDIAN=y ++# CONFIG_USB_OTG is not set ++# CONFIG_USB_OTG_BLACKLIST_HUB is not set ++# CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB is not set ++# CONFIG_USB_OTG_FSM is not set ++# CONFIG_USB_OTG_PRODUCTLIST is not set ++# CONFIG_USB_OTG_WHITELIST is not set ++# CONFIG_USB_OXU210HP_HCD is not set ++# CONFIG_USB_PCI is not set ++# CONFIG_USB_PEGASUS is not set ++# CONFIG_USB_PHY is not set ++# CONFIG_USB_PRINTER is not set ++# CONFIG_USB_PWC_INPUT_EVDEV is not set ++# CONFIG_USB_PXA27X is not set ++# CONFIG_USB_R8A66597 is not set ++# CONFIG_USB_R8A66597_HCD is not set ++# CONFIG_USB_RCAR_PHY is not set ++# CONFIG_USB_RENESAS_USBHS is not set ++# CONFIG_USB_RIO500 is not set ++# CONFIG_USB_ROLE_SWITCH is not set ++# CONFIG_USB_RTL8150 is not set ++# CONFIG_USB_RTL8152 is not set ++# CONFIG_USB_S2255 is not set ++# CONFIG_USB_SERIAL is not set ++# CONFIG_USB_SERIAL_AIRCABLE is not set ++# CONFIG_USB_SERIAL_ARK3116 is not set ++# CONFIG_USB_SERIAL_BELKIN is not set ++# CONFIG_USB_SERIAL_CH341 is not set ++# CONFIG_USB_SERIAL_CP210X is not set ++# CONFIG_USB_SERIAL_CYBERJACK is not set ++# CONFIG_USB_SERIAL_CYPRESS_M8 is not set ++# CONFIG_USB_SERIAL_DEBUG is not set ++# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set ++# CONFIG_USB_SERIAL_EDGEPORT is not set ++# CONFIG_USB_SERIAL_EDGEPORT_TI is not set ++# CONFIG_USB_SERIAL_EMPEG is not set ++# CONFIG_USB_SERIAL_F81232 is not set ++# CONFIG_USB_SERIAL_F8153X is not set ++# CONFIG_USB_SERIAL_FTDI_SIO is not set ++# CONFIG_USB_SERIAL_GARMIN is not set ++CONFIG_USB_SERIAL_GENERIC=y ++# CONFIG_USB_SERIAL_IPAQ is not set ++# CONFIG_USB_SERIAL_IPW is not set ++# CONFIG_USB_SERIAL_IR is not set ++# CONFIG_USB_SERIAL_IUU is not set ++# CONFIG_USB_SERIAL_KEYSPAN is not set ++CONFIG_USB_SERIAL_KEYSPAN_MPR=y ++# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set ++CONFIG_USB_SERIAL_KEYSPAN_USA18X=y ++CONFIG_USB_SERIAL_KEYSPAN_USA19=y ++CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y ++CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y ++CONFIG_USB_SERIAL_KEYSPAN_USA19W=y ++CONFIG_USB_SERIAL_KEYSPAN_USA28=y ++CONFIG_USB_SERIAL_KEYSPAN_USA28X=y ++CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y ++CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y ++CONFIG_USB_SERIAL_KEYSPAN_USA49W=y ++CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y ++# CONFIG_USB_SERIAL_KLSI is not set ++# CONFIG_USB_SERIAL_KOBIL_SCT is not set ++# CONFIG_USB_SERIAL_MCT_U232 is not set ++# CONFIG_USB_SERIAL_METRO is not set ++# CONFIG_USB_SERIAL_MOS7715_PARPORT is not set ++# CONFIG_USB_SERIAL_MOS7720 is not set ++# CONFIG_USB_SERIAL_MOS7840 is not set ++# CONFIG_USB_SERIAL_MXUPORT is not set ++# CONFIG_USB_SERIAL_NAVMAN is not set ++# CONFIG_USB_SERIAL_OMNINET is not set ++# CONFIG_USB_SERIAL_OPTICON is not set ++# CONFIG_USB_SERIAL_OPTION is not set ++# CONFIG_USB_SERIAL_OTI6858 is not set ++# CONFIG_USB_SERIAL_PL2303 is not set ++# CONFIG_USB_SERIAL_QCAUX is not set ++# CONFIG_USB_SERIAL_QT2 is not set ++# CONFIG_USB_SERIAL_QUALCOMM is not set ++# CONFIG_USB_SERIAL_SAFE is not set ++CONFIG_USB_SERIAL_SAFE_PADDED=y ++# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set ++# CONFIG_USB_SERIAL_SIMPLE is not set ++# CONFIG_USB_SERIAL_SPCP8X5 is not set ++# CONFIG_USB_SERIAL_SSU100 is not set ++# CONFIG_USB_SERIAL_SYMBOL is not set ++# CONFIG_USB_SERIAL_TI is not set ++# CONFIG_USB_SERIAL_UPD78F0730 is not set ++# CONFIG_USB_SERIAL_VISOR is not set ++# CONFIG_USB_SERIAL_WHITEHEAT is not set ++# CONFIG_USB_SERIAL_WISHBONE is not set ++# CONFIG_USB_SERIAL_XIRCOM is not set ++# CONFIG_USB_SERIAL_XSENS_MT is not set ++# CONFIG_USB_SEVSEG is not set ++# CONFIG_USB_SIERRA_NET is not set ++# CONFIG_USB_SISUSBVGA is not set ++# CONFIG_USB_SL811_HCD is not set ++# CONFIG_USB_SNP_UDC_PLAT is not set ++# CONFIG_USB_SPEEDTOUCH is not set ++# CONFIG_USB_STKWEBCAM is not set ++# CONFIG_USB_STORAGE is not set ++# CONFIG_USB_STORAGE_ALAUDA is not set ++# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set ++# CONFIG_USB_STORAGE_DATAFAB is not set ++# CONFIG_USB_STORAGE_DEBUG is not set ++# CONFIG_USB_STORAGE_ENE_UB6250 is not set ++# CONFIG_USB_STORAGE_FREECOM is not set ++# CONFIG_USB_STORAGE_ISD200 is not set ++# CONFIG_USB_STORAGE_JUMPSHOT is not set ++# CONFIG_USB_STORAGE_KARMA is not set ++# CONFIG_USB_STORAGE_ONETOUCH is not set ++# CONFIG_USB_STORAGE_REALTEK is not set ++# CONFIG_USB_STORAGE_SDDR09 is not set ++# CONFIG_USB_STORAGE_SDDR55 is not set ++# CONFIG_USB_STORAGE_USBAT is not set ++# CONFIG_USB_STV06XX is not set ++# CONFIG_USB_SUPPORT is not set ++# CONFIG_USB_SWITCH_FSA9480 is not set ++# CONFIG_USB_TEST is not set ++# CONFIG_USB_TMC is not set ++# CONFIG_USB_TRANCEVIBRATOR is not set ++# CONFIG_USB_UAS is not set ++# CONFIG_USB_UEAGLEATM is not set ++# CONFIG_USB_ULPI is not set ++# CONFIG_USB_ULPI_BUS is not set ++# CONFIG_USB_USBNET is not set ++# CONFIG_USB_USS720 is not set ++# CONFIG_USB_VIDEO_CLASS is not set ++CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y ++# CONFIG_USB_VL600 is not set ++# CONFIG_USB_WDM is not set ++# CONFIG_USB_WHCI_HCD is not set ++# CONFIG_USB_WUSB is not set ++# CONFIG_USB_WUSB_CBAF is not set ++# CONFIG_USB_XHCI_DBGCAP is not set ++# CONFIG_USB_XHCI_HCD is not set ++# CONFIG_USB_XHCI_MVEBU is not set ++# CONFIG_USB_XHCI_PCI_RENESAS is not set ++# CONFIG_USB_XUSBATM is not set ++# CONFIG_USB_YUREX is not set ++# CONFIG_USB_ZD1201 is not set ++# CONFIG_USB_ZERO is not set ++# CONFIG_USB_ZR364XX is not set ++# CONFIG_USELIB is not set ++# CONFIG_USERFAULTFD is not set ++# CONFIG_USE_OF is not set ++# CONFIG_UTS_NS is not set ++# CONFIG_UWB is not set ++# CONFIG_U_SERIAL_CONSOLE is not set ++# CONFIG_V4L_MEM2MEM_DRIVERS is not set ++# CONFIG_V4L_PLATFORM_DRIVERS is not set ++# CONFIG_V4L_TEST_DRIVERS is not set ++# CONFIG_VALIDATE_FS_PARSER is not set ++# CONFIG_VBOXGUEST is not set ++# CONFIG_VCNL3020 is not set ++# CONFIG_VCNL4000 is not set ++# CONFIG_VCNL4035 is not set ++# CONFIG_VDPA is not set ++CONFIG_VDSO=y ++# CONFIG_VEML6030 is not set ++# CONFIG_VEML6070 is not set ++# CONFIG_VETH is not set ++# CONFIG_VEXPRESS_CONFIG is not set ++# CONFIG_VF610_ADC is not set ++# CONFIG_VF610_DAC is not set ++# CONFIG_VFAT_FS is not set ++# CONFIG_VGASTATE is not set ++# CONFIG_VGA_ARB is not set ++# CONFIG_VGA_SWITCHEROO is not set ++# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set ++CONFIG_VHOST_MENU=y ++# CONFIG_VHOST_NET is not set ++# CONFIG_VHOST_VSOCK is not set ++# CONFIG_VIA_RHINE is not set ++# CONFIG_VIA_VELOCITY is not set ++# CONFIG_VIDEO_AD5820 is not set ++# CONFIG_VIDEO_AD9389B is not set ++# CONFIG_VIDEO_ADP1653 is not set ++# CONFIG_VIDEO_ADV7170 is not set ++# CONFIG_VIDEO_ADV7175 is not set ++# CONFIG_VIDEO_ADV7180 is not set ++# CONFIG_VIDEO_ADV7183 is not set ++# CONFIG_VIDEO_ADV7343 is not set ++# CONFIG_VIDEO_ADV7393 is not set ++# CONFIG_VIDEO_ADV748X is not set ++# CONFIG_VIDEO_ADV7511 is not set ++# CONFIG_VIDEO_ADV7604 is not set ++# CONFIG_VIDEO_ADV7842 is not set ++# CONFIG_VIDEO_ADV_DEBUG is not set ++# CONFIG_VIDEO_AK7375 is not set ++# CONFIG_VIDEO_AK881X is not set ++# CONFIG_VIDEO_ASPEED is not set ++# CONFIG_VIDEO_AU0828 is not set ++# CONFIG_VIDEO_BT819 is not set ++# CONFIG_VIDEO_BT848 is not set ++# CONFIG_VIDEO_BT856 is not set ++# CONFIG_VIDEO_BT866 is not set ++# CONFIG_VIDEO_CADENCE is not set ++# CONFIG_VIDEO_CAFE_CCIC is not set ++# CONFIG_VIDEO_CS3308 is not set ++# CONFIG_VIDEO_CS5345 is not set ++# CONFIG_VIDEO_CS53L32A is not set ++# CONFIG_VIDEO_CX231XX is not set ++# CONFIG_VIDEO_CX2341X is not set ++# CONFIG_VIDEO_CX25840 is not set ++# CONFIG_VIDEO_CX88 is not set ++# CONFIG_VIDEO_DEV is not set ++# CONFIG_VIDEO_DM6446_CCDC is not set ++# CONFIG_VIDEO_DT3155 is not set ++# CONFIG_VIDEO_DW9714 is not set ++# CONFIG_VIDEO_DW9768 is not set ++# CONFIG_VIDEO_DW9807_VCM is not set ++# CONFIG_VIDEO_EM28XX is not set ++# CONFIG_VIDEO_ET8EK8 is not set ++# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set ++# CONFIG_VIDEO_GO7007 is not set ++# CONFIG_VIDEO_GS1662 is not set ++# CONFIG_VIDEO_HDPVR is not set ++# CONFIG_VIDEO_HEXIUM_GEMINI is not set ++# CONFIG_VIDEO_HEXIUM_ORION is not set ++# CONFIG_VIDEO_HI556 is not set ++# CONFIG_VIDEO_I2C is not set ++# CONFIG_VIDEO_IMX214 is not set ++# CONFIG_VIDEO_IMX219 is not set ++# CONFIG_VIDEO_IMX258 is not set ++# CONFIG_VIDEO_IMX274 is not set ++# CONFIG_VIDEO_IMX290 is not set ++# CONFIG_VIDEO_IMX319 is not set ++# CONFIG_VIDEO_IMX355 is not set ++# CONFIG_VIDEO_IR_I2C is not set ++# CONFIG_VIDEO_IVTV is not set ++# CONFIG_VIDEO_KS0127 is not set ++# CONFIG_VIDEO_LM3560 is not set ++# CONFIG_VIDEO_LM3646 is not set ++# CONFIG_VIDEO_M52790 is not set ++# CONFIG_VIDEO_M5MOLS is not set ++# CONFIG_VIDEO_MAX9286 is not set ++# CONFIG_VIDEO_ML86V7667 is not set ++# CONFIG_VIDEO_MSP3400 is not set ++# CONFIG_VIDEO_MT9M001 is not set ++# CONFIG_VIDEO_MT9M032 is not set ++# CONFIG_VIDEO_MT9M111 is not set ++# CONFIG_VIDEO_MT9P031 is not set ++# CONFIG_VIDEO_MT9T001 is not set ++# CONFIG_VIDEO_MT9T112 is not set ++# CONFIG_VIDEO_MT9V011 is not set ++# CONFIG_VIDEO_MT9V032 is not set ++# CONFIG_VIDEO_MT9V111 is not set ++# CONFIG_VIDEO_MUX is not set ++# CONFIG_VIDEO_MXB is not set ++# CONFIG_VIDEO_NOON010PC30 is not set ++# CONFIG_VIDEO_OMAP2_VOUT is not set ++# CONFIG_VIDEO_OV13858 is not set ++# CONFIG_VIDEO_OV2640 is not set ++# CONFIG_VIDEO_OV2659 is not set ++# CONFIG_VIDEO_OV2680 is not set ++# CONFIG_VIDEO_OV2685 is not set ++# CONFIG_VIDEO_OV5640 is not set ++# CONFIG_VIDEO_OV5645 is not set ++# CONFIG_VIDEO_OV5647 is not set ++# CONFIG_VIDEO_OV5670 is not set ++# CONFIG_VIDEO_OV5675 is not set ++# CONFIG_VIDEO_OV5695 is not set ++# CONFIG_VIDEO_OV6650 is not set ++# CONFIG_VIDEO_OV7251 is not set ++# CONFIG_VIDEO_OV7640 is not set ++# CONFIG_VIDEO_OV7670 is not set ++# CONFIG_VIDEO_OV772X is not set ++# CONFIG_VIDEO_OV7740 is not set ++# CONFIG_VIDEO_OV8856 is not set ++# CONFIG_VIDEO_OV9640 is not set ++# CONFIG_VIDEO_OV9650 is not set ++# CONFIG_VIDEO_PVRUSB2 is not set ++# CONFIG_VIDEO_RDACM20 is not set ++# CONFIG_VIDEO_RJ54N1 is not set ++# CONFIG_VIDEO_S5C73M3 is not set ++# CONFIG_VIDEO_S5K4ECGX is not set ++# CONFIG_VIDEO_S5K5BAF is not set ++# CONFIG_VIDEO_S5K6A3 is not set ++# CONFIG_VIDEO_S5K6AA is not set ++# CONFIG_VIDEO_SAA6588 is not set ++# CONFIG_VIDEO_SAA6752HS is not set ++# CONFIG_VIDEO_SAA7110 is not set ++# CONFIG_VIDEO_SAA711X is not set ++# CONFIG_VIDEO_SAA7127 is not set ++# CONFIG_VIDEO_SAA7134 is not set ++# CONFIG_VIDEO_SAA717X is not set ++# CONFIG_VIDEO_SAA7185 is not set ++# CONFIG_VIDEO_SH_MOBILE_CEU is not set ++# CONFIG_VIDEO_SMIAPP is not set ++# CONFIG_VIDEO_SONY_BTF_MPX is not set ++# CONFIG_VIDEO_SR030PC30 is not set ++# CONFIG_VIDEO_STK1160_COMMON is not set ++# CONFIG_VIDEO_ST_MIPID02 is not set ++# CONFIG_VIDEO_TC358743 is not set ++# CONFIG_VIDEO_TDA1997X is not set ++# CONFIG_VIDEO_TDA7432 is not set ++# CONFIG_VIDEO_TDA9840 is not set ++# CONFIG_VIDEO_TEA6415C is not set ++# CONFIG_VIDEO_TEA6420 is not set ++# CONFIG_VIDEO_THS7303 is not set ++# CONFIG_VIDEO_THS8200 is not set ++# CONFIG_VIDEO_TIMBERDALE is not set ++# CONFIG_VIDEO_TLV320AIC23B is not set ++# CONFIG_VIDEO_TM6000 is not set ++# CONFIG_VIDEO_TVAUDIO is not set ++# CONFIG_VIDEO_TVP514X is not set ++# CONFIG_VIDEO_TVP5150 is not set ++# CONFIG_VIDEO_TVP7002 is not set ++# CONFIG_VIDEO_TW2804 is not set ++# CONFIG_VIDEO_TW9903 is not set ++# CONFIG_VIDEO_TW9906 is not set ++# CONFIG_VIDEO_TW9910 is not set ++# CONFIG_VIDEO_UDA1342 is not set ++# CONFIG_VIDEO_UPD64031A is not set ++# CONFIG_VIDEO_UPD64083 is not set ++# CONFIG_VIDEO_USBTV is not set ++# CONFIG_VIDEO_USBVISION is not set ++# CONFIG_VIDEO_V4L2 is not set ++# CONFIG_VIDEO_VP27SMPX is not set ++# CONFIG_VIDEO_VPX3220 is not set ++# CONFIG_VIDEO_VS6624 is not set ++# CONFIG_VIDEO_WM8739 is not set ++# CONFIG_VIDEO_WM8775 is not set ++# CONFIG_VIDEO_XILINX is not set ++# CONFIG_VIDEO_ZORAN is not set ++# CONFIG_VIRTIO_BALLOON is not set ++# CONFIG_VIRTIO_BLK_SCSI is not set ++# CONFIG_VIRTIO_CONSOLE is not set ++# CONFIG_VIRTIO_FS is not set ++# CONFIG_VIRTIO_INPUT is not set ++CONFIG_VIRTIO_MENU=y ++# CONFIG_VIRTIO_MMIO is not set ++# CONFIG_VIRTIO_PCI is not set ++# CONFIG_VIRTUALIZATION is not set ++# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set ++# CONFIG_VIRT_DRIVERS is not set ++CONFIG_VIRT_TO_BUS=y ++# CONFIG_VITESSE_PHY is not set ++# CONFIG_VL53L0X_I2C is not set ++# CONFIG_VL6180 is not set ++CONFIG_VLAN_8021Q=y ++# CONFIG_VLAN_8021Q_GVRP is not set ++# CONFIG_VLAN_8021Q_MVRP is not set ++# CONFIG_VME_BUS is not set ++# CONFIG_VMSPLIT_1G is not set ++# CONFIG_VMSPLIT_2G is not set ++# CONFIG_VMSPLIT_2G_OPT is not set ++CONFIG_VMSPLIT_3G=y ++# CONFIG_VMSPLIT_3G_OPT is not set ++# CONFIG_VMWARE_PVSCSI is not set ++# CONFIG_VMXNET3 is not set ++# CONFIG_VM_EVENT_COUNTERS is not set ++# CONFIG_VOP_BUS is not set ++# CONFIG_VORTEX is not set ++# CONFIG_VSOCKETS is not set ++# CONFIG_VSOCKETS_DIAG is not set ++# CONFIG_VT is not set ++# CONFIG_VT6655 is not set ++# CONFIG_VT6656 is not set ++# CONFIG_VXFS_FS is not set ++# CONFIG_VXGE is not set ++# CONFIG_VXLAN is not set ++# CONFIG_VZ89X is not set ++# CONFIG_W1 is not set ++# CONFIG_W1_CON is not set ++# CONFIG_W1_MASTER_DS1WM is not set ++# CONFIG_W1_MASTER_DS2482 is not set ++# CONFIG_W1_MASTER_DS2490 is not set ++# CONFIG_W1_MASTER_GPIO is not set ++# CONFIG_W1_MASTER_MATROX is not set ++# CONFIG_W1_MASTER_SGI is not set ++# CONFIG_W1_SLAVE_DS2405 is not set ++# CONFIG_W1_SLAVE_DS2406 is not set ++# CONFIG_W1_SLAVE_DS2408 is not set ++# CONFIG_W1_SLAVE_DS2413 is not set ++# CONFIG_W1_SLAVE_DS2423 is not set ++# CONFIG_W1_SLAVE_DS2430 is not set ++# CONFIG_W1_SLAVE_DS2431 is not set ++# CONFIG_W1_SLAVE_DS2433 is not set ++# CONFIG_W1_SLAVE_DS2438 is not set ++# CONFIG_W1_SLAVE_DS250X is not set ++# CONFIG_W1_SLAVE_DS2780 is not set ++# CONFIG_W1_SLAVE_DS2781 is not set ++# CONFIG_W1_SLAVE_DS2805 is not set ++# CONFIG_W1_SLAVE_DS28E04 is not set ++# CONFIG_W1_SLAVE_DS28E17 is not set ++# CONFIG_W1_SLAVE_SMEM is not set ++# CONFIG_W1_SLAVE_THERM is not set ++# CONFIG_W83627HF_WDT is not set ++# CONFIG_W83877F_WDT is not set ++# CONFIG_W83977F_WDT is not set ++# CONFIG_WAN is not set ++# CONFIG_WANXL is not set ++# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set ++CONFIG_WATCHDOG=y ++# CONFIG_WATCHDOG_CORE is not set ++CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y ++# CONFIG_WATCHDOG_NOWAYOUT is not set ++CONFIG_WATCHDOG_OPEN_TIMEOUT=0 ++# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set ++# CONFIG_WATCHDOG_SYSFS is not set ++# CONFIG_WATCH_QUEUE is not set ++# CONFIG_WD80x3 is not set ++# CONFIG_WDAT_WDT is not set ++# CONFIG_WDTPCI is not set ++CONFIG_WEXT_CORE=y ++CONFIG_WEXT_PRIV=y ++CONFIG_WEXT_PROC=y ++CONFIG_WEXT_SPY=y ++CONFIG_WILINK_PLATFORM_DATA=y ++# CONFIG_WIMAX is not set ++# CONFIG_WIREGUARD is not set ++CONFIG_WIRELESS=y ++CONFIG_WIRELESS_EXT=y ++# CONFIG_WIRELESS_WDS is not set ++# CONFIG_WIZNET_W5100 is not set ++# CONFIG_WIZNET_W5300 is not set ++# CONFIG_WL1251 is not set ++# CONFIG_WL12XX is not set ++# CONFIG_WL18XX is not set ++CONFIG_WLAN=y ++# CONFIG_WLAN_VENDOR_ADMTEK is not set ++# CONFIG_WLAN_VENDOR_ATH is not set ++# CONFIG_WLAN_VENDOR_ATMEL is not set ++# CONFIG_WLAN_VENDOR_BROADCOM is not set ++# CONFIG_WLAN_VENDOR_CISCO is not set ++# CONFIG_WLAN_VENDOR_INTEL is not set ++# CONFIG_WLAN_VENDOR_INTERSIL is not set ++# CONFIG_WLAN_VENDOR_MARVELL is not set ++# CONFIG_WLAN_VENDOR_MEDIATEK is not set ++# CONFIG_WLAN_VENDOR_MICROCHIP is not set ++# CONFIG_WLAN_VENDOR_QUANTENNA is not set ++# CONFIG_WLAN_VENDOR_RALINK is not set ++# CONFIG_WLAN_VENDOR_REALTEK is not set ++# CONFIG_WLAN_VENDOR_RSI is not set ++# CONFIG_WLAN_VENDOR_ST is not set ++# CONFIG_WLAN_VENDOR_TI is not set ++# CONFIG_WLAN_VENDOR_ZYDAS is not set ++# CONFIG_WLCORE is not set ++CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y ++# CONFIG_WQ_WATCHDOG is not set ++# CONFIG_WW_MUTEX_SELFTEST is not set ++# CONFIG_X25 is not set ++# CONFIG_X509_CERTIFICATE_PARSER is not set ++# CONFIG_X86_PKG_TEMP_THERMAL is not set ++CONFIG_X86_SYSFB=y ++# CONFIG_XDP_SOCKETS is not set ++# CONFIG_XEN is not set ++# CONFIG_XEN_GRANT_DMA_ALLOC is not set ++# CONFIG_XEN_PVCALLS_FRONTEND is not set ++CONFIG_XEN_SCRUB_PAGES_DEFAULT=y ++CONFIG_XFRM=y ++# CONFIG_XFRM_INTERFACE is not set ++# CONFIG_XFRM_IPCOMP is not set ++# CONFIG_XFRM_MIGRATE is not set ++# CONFIG_XFRM_STATISTICS is not set ++# CONFIG_XFRM_SUB_POLICY is not set ++# CONFIG_XFRM_USER is not set ++# CONFIG_XFS_DEBUG is not set ++# CONFIG_XFS_FS is not set ++# CONFIG_XFS_ONLINE_SCRUB is not set ++# CONFIG_XFS_POSIX_ACL is not set ++# CONFIG_XFS_QUOTA is not set ++# CONFIG_XFS_RT is not set ++# CONFIG_XFS_WARN is not set ++# CONFIG_XILINX_AXI_EMAC is not set ++# CONFIG_XILINX_DMA is not set ++# CONFIG_XILINX_EMACLITE is not set ++# CONFIG_XILINX_GMII2RGMII is not set ++# CONFIG_XILINX_LL_TEMAC is not set ++# CONFIG_XILINX_SDFEC is not set ++# CONFIG_XILINX_VCU is not set ++# CONFIG_XILINX_WATCHDOG is not set ++# CONFIG_XILINX_XADC is not set ++# CONFIG_XILINX_ZYNQMP_DMA is not set ++# CONFIG_XILINX_ZYNQMP_DPDMA is not set ++# CONFIG_XILLYBUS is not set ++# CONFIG_XIL_AXIS_FIFO is not set ++# CONFIG_XIP_KERNEL is not set ++# CONFIG_XMON is not set ++CONFIG_XZ_DEC=y ++# CONFIG_XZ_DEC_ARM is not set ++# CONFIG_XZ_DEC_ARMTHUMB is not set ++# CONFIG_XZ_DEC_BCJ is not set ++# CONFIG_XZ_DEC_IA64 is not set ++# CONFIG_XZ_DEC_POWERPC is not set ++# CONFIG_XZ_DEC_SPARC is not set ++# CONFIG_XZ_DEC_TEST is not set ++# CONFIG_XZ_DEC_X86 is not set ++# CONFIG_YAM is not set ++# CONFIG_YELLOWFIN is not set ++# CONFIG_YENTA is not set ++# CONFIG_YENTA_O2 is not set ++# CONFIG_YENTA_RICOH is not set ++# CONFIG_YENTA_TI is not set ++# CONFIG_YENTA_TOSHIBA is not set ++# CONFIG_ZBUD is not set ++# CONFIG_ZD1211RW is not set ++# CONFIG_ZD1211RW_DEBUG is not set ++# CONFIG_ZEROPLUS_FF is not set ++# CONFIG_ZIIRAVE_WATCHDOG is not set ++# CONFIG_ZISOFS is not set ++# CONFIG_ZLIB_DEFLATE is not set ++# CONFIG_ZLIB_INFLATE is not set ++CONFIG_ZONE_DMA=y ++# CONFIG_ZOPT2201 is not set ++# CONFIG_ZPA2326 is not set ++# CONFIG_ZPOOL is not set ++# CONFIG_ZRAM is not set ++# CONFIG_ZRAM_MEMORY_TRACKING is not set ++# CONFIG_ZSMALLOC is not set ++# CONFIG_ZX_TDM is not set +diff --git a/target/linux/generic/config-filter b/target/linux/generic/config-filter +index 0d53ed9c3c..7d634b56cf 100644 +--- a/target/linux/generic/config-filter ++++ b/target/linux/generic/config-filter +@@ -1,7 +1,11 @@ +-# CONFIG_ARCH_(ENABLE|HAS|HAVE|INLINE|SUPPORTS|USE|WANT)_.* is not set ++# CONFIG_ARM64_AS_.* is not set ++# CONFIG_ARM64_CONT_.*_SHIFT is not set ++# CONFIG_ARCH_(ENABLE|HAS|HAVE|INLINE|SUPPORTS|USE|WANT|STACKWALK)_.* is not set + # CONFIG_AS_.* is not set + # CONFIG_CC_(CAN|HAS|IS|VERSION)_.* is not set + # CONFIG_LD_.* is not set + # CONFIG_GCC_VERSION is not set + # CONFIG_INLINE_.* is not set + # CONFIG_HAVE_(?!(ARCH_TIMER|TCM|SMP)).* is not set ++# CONFIG_SET_FS is not set ++# CONFIG_TASKS_.* is not set +diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c +index 0b0348bfdf..acfa0ebecd 100644 +--- a/target/linux/generic/files/drivers/net/phy/ar8216.c ++++ b/target/linux/generic/files/drivers/net/phy/ar8216.c +@@ -513,6 +513,8 @@ ar8216_read_port_link(struct ar8xxx_priv *priv, int port, + } + } + ++#ifdef CONFIG_ETHERNET_PACKET_MANGLE ++ + static struct sk_buff * + ar8216_mangle_tx(struct net_device *dev, struct sk_buff *skb) + { +@@ -579,6 +581,8 @@ ar8216_mangle_rx(struct net_device *dev, struct sk_buff *skb) + buf[15 + 2] = vlan & 0xff; + } + ++#endif ++ + int + ar8216_wait_bit(struct ar8xxx_priv *priv, int reg, u32 mask, u32 val) + { +@@ -2449,6 +2453,7 @@ ar8xxx_phy_config_init(struct phy_device *phydev) + if (ret) + return ret; + ++#ifdef CONFIG_ETHERNET_PACKET_MANGLE + /* VID fixup only needed on ar8216 */ + if (chip_is_ar8216(priv)) { + dev->phy_ptr = priv; +@@ -2456,6 +2461,7 @@ ar8xxx_phy_config_init(struct phy_device *phydev) + dev->eth_mangle_rx = ar8216_mangle_rx; + dev->eth_mangle_tx = ar8216_mangle_tx; + } ++#endif + + return 0; + } +@@ -2687,10 +2693,12 @@ ar8xxx_phy_detach(struct phy_device *phydev) + if (!dev) + return; + ++#ifdef CONFIG_ETHERNET_PACKET_MANGLE + dev->phy_ptr = NULL; + dev->priv_flags &= ~IFF_NO_IP_ALIGN; + dev->eth_mangle_rx = NULL; + dev->eth_mangle_tx = NULL; ++#endif + } + + static void +diff --git a/target/linux/generic/hack-5.10/204-module_strip.patch b/target/linux/generic/hack-5.10/204-module_strip.patch +new file mode 100644 +index 0000000000..79fc1057ab +--- /dev/null ++++ b/target/linux/generic/hack-5.10/204-module_strip.patch +@@ -0,0 +1,196 @@ ++From a779a482fb9b9f8fcdf8b2519c789b4b9bb5dd05 Mon Sep 17 00:00:00 2001 ++From: Felix Fietkau ++Date: Fri, 7 Jul 2017 16:56:48 +0200 ++Subject: build: add a hack for removing non-essential module info ++ ++Signed-off-by: Felix Fietkau ++--- ++ include/linux/module.h | 13 ++++++++----- ++ include/linux/moduleparam.h | 15 ++++++++++++--- ++ init/Kconfig | 7 +++++++ ++ kernel/module.c | 5 ++++- ++ scripts/mod/modpost.c | 12 ++++++++++++ ++ 5 files changed, 43 insertions(+), 9 deletions(-) ++ ++--- a/include/linux/module.h +++++ b/include/linux/module.h ++@@ -161,6 +161,7 @@ extern void cleanup_module(void); ++ ++ /* Generic info of form tag = "info" */ ++ #define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info) +++#define MODULE_INFO_STRIP(tag, info) __MODULE_INFO_STRIP(tag, tag, info) ++ ++ /* For userspace: you can also call me... */ ++ #define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias) ++@@ -230,12 +231,12 @@ extern void cleanup_module(void); ++ * Author(s), use "Name " or just "Name", for multiple ++ * authors use multiple MODULE_AUTHOR() statements/lines. ++ */ ++-#define MODULE_AUTHOR(_author) MODULE_INFO(author, _author) +++#define MODULE_AUTHOR(_author) MODULE_INFO_STRIP(author, _author) ++ ++ /* What your module does. */ ++-#define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description) +++#define MODULE_DESCRIPTION(_description) MODULE_INFO_STRIP(description, _description) ++ ++-#ifdef MODULE +++#if defined(MODULE) && !defined(CONFIG_MODULE_STRIPPED) ++ /* Creates an alias so file2alias.c can find device table. */ ++ #define MODULE_DEVICE_TABLE(type, name) \ ++ extern typeof(name) __mod_##type##__##name##_device_table \ ++@@ -262,7 +263,9 @@ extern typeof(name) __mod_##type##__##na ++ */ ++ ++ #if defined(MODULE) || !defined(CONFIG_SYSFS) ++-#define MODULE_VERSION(_version) MODULE_INFO(version, _version) +++#define MODULE_VERSION(_version) MODULE_INFO_STRIP(version, _version) +++#elif defined(CONFIG_MODULE_STRIPPED) +++#define MODULE_VERSION(_version) __MODULE_INFO_DISABLED(version) ++ #else ++ #define MODULE_VERSION(_version) \ ++ MODULE_INFO(version, _version); \ ++@@ -285,7 +288,7 @@ extern typeof(name) __mod_##type##__##na ++ /* Optional firmware file (or files) needed by the module ++ * format is simply firmware file name. Multiple firmware ++ * files require multiple MODULE_FIRMWARE() specifiers */ ++-#define MODULE_FIRMWARE(_firmware) MODULE_INFO(firmware, _firmware) +++#define MODULE_FIRMWARE(_firmware) MODULE_INFO_STRIP(firmware, _firmware) ++ ++ #define MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, #ns) ++ ++--- a/include/linux/moduleparam.h +++++ b/include/linux/moduleparam.h ++@@ -20,6 +20,16 @@ ++ /* Chosen so that structs with an unsigned long line up. */ ++ #define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long)) ++ +++/* This struct is here for syntactic coherency, it is not used */ +++#define __MODULE_INFO_DISABLED(name) \ +++ struct __UNIQUE_ID(name) {} +++ +++#ifdef CONFIG_MODULE_STRIPPED +++#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO_DISABLED(name) +++#else +++#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO(tag, name, info) +++#endif +++ ++ #define __MODULE_INFO(tag, name, info) \ ++ static const char __UNIQUE_ID(name)[] \ ++ __used __section(".modinfo") __attribute__((unused, aligned(1))) \ ++@@ -31,7 +41,7 @@ static const char __UNIQUE_ID(name)[] ++ /* One for each parameter, describing how to use it. Some files do ++ multiple of these per line, so can't just use MODULE_INFO. */ ++ #define MODULE_PARM_DESC(_parm, desc) \ ++- __MODULE_INFO(parm, _parm, #_parm ":" desc) +++ __MODULE_INFO_STRIP(parm, _parm, #_parm ":" desc) ++ ++ struct kernel_param; ++ ++--- a/init/Kconfig +++++ b/init/Kconfig ++@@ -2327,6 +2327,13 @@ config UNUSED_KSYMS_WHITELIST ++ one per line. The path can be absolute, or relative to the kernel ++ source tree. ++ +++config MODULE_STRIPPED +++ bool "Reduce module size" +++ depends on MODULES +++ help +++ Remove module parameter descriptions, author info, version, aliases, +++ device tables, etc. +++ ++ endif # MODULES ++ ++ config MODULES_TREE_LOOKUP ++--- a/kernel/module.c +++++ b/kernel/module.c ++@@ -3144,9 +3144,11 @@ static int setup_load_info(struct load_i ++ ++ static int check_modinfo(struct module *mod, struct load_info *info, int flags) ++ { ++- const char *modmagic = get_modinfo(info, "vermagic"); ++ int err; ++ +++#ifndef CONFIG_MODULE_STRIPPED +++ const char *modmagic = get_modinfo(info, "vermagic"); +++ ++ if (flags & MODULE_INIT_IGNORE_VERMAGIC) ++ modmagic = NULL; ++ ++@@ -3167,6 +3169,7 @@ static int check_modinfo(struct module * ++ mod->name); ++ add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK); ++ } +++#endif ++ ++ check_modinfo_retpoline(mod, info); ++ ++--- a/scripts/mod/modpost.c +++++ b/scripts/mod/modpost.c ++@@ -2037,7 +2037,9 @@ static void read_symbols(const char *mod ++ symname = remove_dot(info.strtab + sym->st_name); ++ ++ handle_symbol(mod, &info, sym, symname); +++#ifndef CONFIG_MODULE_STRIPPED ++ handle_moddevtable(mod, &info, sym, symname); +++#endif ++ } ++ ++ for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { ++@@ -2250,8 +2252,10 @@ static void add_header(struct buffer *b, ++ buf_printf(b, "\n"); ++ buf_printf(b, "BUILD_SALT;\n"); ++ buf_printf(b, "\n"); +++#ifndef CONFIG_MODULE_STRIPPED ++ buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n"); ++ buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n"); +++#endif ++ buf_printf(b, "\n"); ++ buf_printf(b, "__visible struct module __this_module\n"); ++ buf_printf(b, "__section(\".gnu.linkonce.this_module\") = {\n"); ++@@ -2268,8 +2272,10 @@ static void add_header(struct buffer *b, ++ ++ static void add_intree_flag(struct buffer *b, int is_intree) ++ { +++#ifndef CONFIG_MODULE_STRIPPED ++ if (is_intree) ++ buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n"); +++#endif ++ } ++ ++ /* Cannot check for assembler */ ++@@ -2282,8 +2288,10 @@ static void add_retpoline(struct buffer ++ ++ static void add_staging_flag(struct buffer *b, const char *name) ++ { +++#ifndef CONFIG_MODULE_STRIPPED ++ if (strstarts(name, "drivers/staging")) ++ buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n"); +++#endif ++ } ++ ++ /** ++@@ -2367,11 +2375,13 @@ static void add_depends(struct buffer *b ++ ++ static void add_srcversion(struct buffer *b, struct module *mod) ++ { +++#ifndef CONFIG_MODULE_STRIPPED ++ if (mod->srcversion[0]) { ++ buf_printf(b, "\n"); ++ buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n", ++ mod->srcversion); ++ } +++#endif ++ } ++ ++ static void write_buf(struct buffer *b, const char *fname) ++@@ -2643,7 +2653,9 @@ int main(int argc, char **argv) ++ add_staging_flag(&buf, mod->name); ++ err |= add_versions(&buf, mod); ++ add_depends(&buf, mod); +++#ifndef CONFIG_MODULE_STRIPPED ++ add_moddevtable(&buf, mod); +++#endif ++ add_srcversion(&buf, mod); ++ ++ sprintf(fname, "%s.mod.c", mod->name); +diff --git a/target/linux/generic/hack-5.10/210-darwin_scripts_include.patch b/target/linux/generic/hack-5.10/210-darwin_scripts_include.patch +new file mode 100644 +index 0000000000..be6adc0d11 +--- /dev/null ++++ b/target/linux/generic/hack-5.10/210-darwin_scripts_include.patch +@@ -0,0 +1,3053 @@ ++From db7c30dcd9a0391bf13b62c9f91e144d762ef43a Mon Sep 17 00:00:00 2001 ++From: Florian Fainelli ++Date: Fri, 7 Jul 2017 17:00:49 +0200 ++Subject: Add an OSX specific patch to make the kernel be compiled ++ ++lede-commit: 3fc2a24f0422b2f55f9ed43f116db3111f700526 ++Signed-off-by: Florian Fainelli ++--- ++ scripts/kconfig/Makefile | 3 + ++ scripts/mod/elf.h | 3007 ++++++++++++++++++++++++++++++++++++++++++++ ++ scripts/mod/mk_elfconfig.c | 4 + ++ scripts/mod/modpost.h | 4 + ++ 4 files changed, 3018 insertions(+) ++ create mode 100644 scripts/mod/elf.h ++ ++--- /dev/null +++++ b/scripts/mod/elf.h ++@@ -0,0 +1,3007 @@ +++/* This file defines standard ELF types, structures, and macros. +++ Copyright (C) 1995-2012 Free Software Foundation, Inc. +++ This file is part of the GNU C Library. +++ +++ The GNU C Library is free software; you can redistribute it and/or +++ modify it under the terms of the GNU Lesser General Public +++ License as published by the Free Software Foundation; either +++ version 2.1 of the License, or (at your option) any later version. +++ +++ The GNU C Library is distributed in the hope that it will be useful, +++ but WITHOUT ANY WARRANTY; without even the implied warranty of +++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +++ Lesser General Public License for more details. +++ +++ You should have received a copy of the GNU Lesser General Public +++ License along with the GNU C Library; if not, see +++ . */ +++ +++#ifndef _ELF_H +++#define _ELF_H 1 +++ +++/* Standard ELF types. */ +++ +++#include +++ +++/* Type for a 16-bit quantity. */ +++typedef uint16_t Elf32_Half; +++typedef uint16_t Elf64_Half; +++ +++/* Types for signed and unsigned 32-bit quantities. */ +++typedef uint32_t Elf32_Word; +++typedef int32_t Elf32_Sword; +++typedef uint32_t Elf64_Word; +++typedef int32_t Elf64_Sword; +++ +++/* Types for signed and unsigned 64-bit quantities. */ +++typedef uint64_t Elf32_Xword; +++typedef int64_t Elf32_Sxword; +++typedef uint64_t Elf64_Xword; +++typedef int64_t Elf64_Sxword; +++ +++/* Type of addresses. */ +++typedef uint32_t Elf32_Addr; +++typedef uint64_t Elf64_Addr; +++ +++/* Type of file offsets. */ +++typedef uint32_t Elf32_Off; +++typedef uint64_t Elf64_Off; +++ +++/* Type for section indices, which are 16-bit quantities. */ +++typedef uint16_t Elf32_Section; +++typedef uint16_t Elf64_Section; +++ +++/* Type for version symbol information. */ +++typedef Elf32_Half Elf32_Versym; +++typedef Elf64_Half Elf64_Versym; +++ +++ +++/* The ELF file header. This appears at the start of every ELF file. */ +++ +++#define EI_NIDENT (16) +++ +++typedef struct +++{ +++ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ +++ Elf32_Half e_type; /* Object file type */ +++ Elf32_Half e_machine; /* Architecture */ +++ Elf32_Word e_version; /* Object file version */ +++ Elf32_Addr e_entry; /* Entry point virtual address */ +++ Elf32_Off e_phoff; /* Program header table file offset */ +++ Elf32_Off e_shoff; /* Section header table file offset */ +++ Elf32_Word e_flags; /* Processor-specific flags */ +++ Elf32_Half e_ehsize; /* ELF header size in bytes */ +++ Elf32_Half e_phentsize; /* Program header table entry size */ +++ Elf32_Half e_phnum; /* Program header table entry count */ +++ Elf32_Half e_shentsize; /* Section header table entry size */ +++ Elf32_Half e_shnum; /* Section header table entry count */ +++ Elf32_Half e_shstrndx; /* Section header string table index */ +++} Elf32_Ehdr; +++ +++typedef struct +++{ +++ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ +++ Elf64_Half e_type; /* Object file type */ +++ Elf64_Half e_machine; /* Architecture */ +++ Elf64_Word e_version; /* Object file version */ +++ Elf64_Addr e_entry; /* Entry point virtual address */ +++ Elf64_Off e_phoff; /* Program header table file offset */ +++ Elf64_Off e_shoff; /* Section header table file offset */ +++ Elf64_Word e_flags; /* Processor-specific flags */ +++ Elf64_Half e_ehsize; /* ELF header size in bytes */ +++ Elf64_Half e_phentsize; /* Program header table entry size */ +++ Elf64_Half e_phnum; /* Program header table entry count */ +++ Elf64_Half e_shentsize; /* Section header table entry size */ +++ Elf64_Half e_shnum; /* Section header table entry count */ +++ Elf64_Half e_shstrndx; /* Section header string table index */ +++} Elf64_Ehdr; +++ +++/* Fields in the e_ident array. The EI_* macros are indices into the +++ array. The macros under each EI_* macro are the values the byte +++ may have. */ +++ +++#define EI_MAG0 0 /* File identification byte 0 index */ +++#define ELFMAG0 0x7f /* Magic number byte 0 */ +++ +++#define EI_MAG1 1 /* File identification byte 1 index */ +++#define ELFMAG1 'E' /* Magic number byte 1 */ +++ +++#define EI_MAG2 2 /* File identification byte 2 index */ +++#define ELFMAG2 'L' /* Magic number byte 2 */ +++ +++#define EI_MAG3 3 /* File identification byte 3 index */ +++#define ELFMAG3 'F' /* Magic number byte 3 */ +++ +++/* Conglomeration of the identification bytes, for easy testing as a word. */ +++#define ELFMAG "\177ELF" +++#define SELFMAG 4 +++ +++#define EI_CLASS 4 /* File class byte index */ +++#define ELFCLASSNONE 0 /* Invalid class */ +++#define ELFCLASS32 1 /* 32-bit objects */ +++#define ELFCLASS64 2 /* 64-bit objects */ +++#define ELFCLASSNUM 3 +++ +++#define EI_DATA 5 /* Data encoding byte index */ +++#define ELFDATANONE 0 /* Invalid data encoding */ +++#define ELFDATA2LSB 1 /* 2's complement, little endian */ +++#define ELFDATA2MSB 2 /* 2's complement, big endian */ +++#define ELFDATANUM 3 +++ +++#define EI_VERSION 6 /* File version byte index */ +++ /* Value must be EV_CURRENT */ +++ +++#define EI_OSABI 7 /* OS ABI identification */ +++#define ELFOSABI_NONE 0 /* UNIX System V ABI */ +++#define ELFOSABI_SYSV 0 /* Alias. */ +++#define ELFOSABI_HPUX 1 /* HP-UX */ +++#define ELFOSABI_NETBSD 2 /* NetBSD. */ +++#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */ +++#define ELFOSABI_LINUX ELFOSABI_GNU /* Compatibility alias. */ +++#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */ +++#define ELFOSABI_AIX 7 /* IBM AIX. */ +++#define ELFOSABI_IRIX 8 /* SGI Irix. */ +++#define ELFOSABI_FREEBSD 9 /* FreeBSD. */ +++#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */ +++#define ELFOSABI_MODESTO 11 /* Novell Modesto. */ +++#define ELFOSABI_OPENBSD 12 /* OpenBSD. */ +++#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */ +++#define ELFOSABI_ARM 97 /* ARM */ +++#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ +++ +++#define EI_ABIVERSION 8 /* ABI version */ +++ +++#define EI_PAD 9 /* Byte index of padding bytes */ +++ +++/* Legal values for e_type (object file type). */ +++ +++#define ET_NONE 0 /* No file type */ +++#define ET_REL 1 /* Relocatable file */ +++#define ET_EXEC 2 /* Executable file */ +++#define ET_DYN 3 /* Shared object file */ +++#define ET_CORE 4 /* Core file */ +++#define ET_NUM 5 /* Number of defined types */ +++#define ET_LOOS 0xfe00 /* OS-specific range start */ +++#define ET_HIOS 0xfeff /* OS-specific range end */ +++#define ET_LOPROC 0xff00 /* Processor-specific range start */ +++#define ET_HIPROC 0xffff /* Processor-specific range end */ +++ +++/* Legal values for e_machine (architecture). */ +++ +++#define EM_NONE 0 /* No machine */ +++#define EM_M32 1 /* AT&T WE 32100 */ +++#define EM_SPARC 2 /* SUN SPARC */ +++#define EM_386 3 /* Intel 80386 */ +++#define EM_68K 4 /* Motorola m68k family */ +++#define EM_88K 5 /* Motorola m88k family */ +++#define EM_860 7 /* Intel 80860 */ +++#define EM_MIPS 8 /* MIPS R3000 big-endian */ +++#define EM_S370 9 /* IBM System/370 */ +++#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ +++ +++#define EM_PARISC 15 /* HPPA */ +++#define EM_VPP500 17 /* Fujitsu VPP500 */ +++#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ +++#define EM_960 19 /* Intel 80960 */ +++#define EM_PPC 20 /* PowerPC */ +++#define EM_PPC64 21 /* PowerPC 64-bit */ +++#define EM_S390 22 /* IBM S390 */ +++ +++#define EM_V800 36 /* NEC V800 series */ +++#define EM_FR20 37 /* Fujitsu FR20 */ +++#define EM_RH32 38 /* TRW RH-32 */ +++#define EM_RCE 39 /* Motorola RCE */ +++#define EM_ARM 40 /* ARM */ +++#define EM_FAKE_ALPHA 41 /* Digital Alpha */ +++#define EM_SH 42 /* Hitachi SH */ +++#define EM_SPARCV9 43 /* SPARC v9 64-bit */ +++#define EM_TRICORE 44 /* Siemens Tricore */ +++#define EM_ARC 45 /* Argonaut RISC Core */ +++#define EM_H8_300 46 /* Hitachi H8/300 */ +++#define EM_H8_300H 47 /* Hitachi H8/300H */ +++#define EM_H8S 48 /* Hitachi H8S */ +++#define EM_H8_500 49 /* Hitachi H8/500 */ +++#define EM_IA_64 50 /* Intel Merced */ +++#define EM_MIPS_X 51 /* Stanford MIPS-X */ +++#define EM_COLDFIRE 52 /* Motorola Coldfire */ +++#define EM_68HC12 53 /* Motorola M68HC12 */ +++#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ +++#define EM_PCP 55 /* Siemens PCP */ +++#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ +++#define EM_NDR1 57 /* Denso NDR1 microprocessor */ +++#define EM_STARCORE 58 /* Motorola Start*Core processor */ +++#define EM_ME16 59 /* Toyota ME16 processor */ +++#define EM_ST100 60 /* STMicroelectronic ST100 processor */ +++#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ +++#define EM_X86_64 62 /* AMD x86-64 architecture */ +++#define EM_PDSP 63 /* Sony DSP Processor */ +++ +++#define EM_FX66 66 /* Siemens FX66 microcontroller */ +++#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ +++#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ +++#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ +++#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ +++#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ +++#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ +++#define EM_SVX 73 /* Silicon Graphics SVx */ +++#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ +++#define EM_VAX 75 /* Digital VAX */ +++#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ +++#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */ +++#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ +++#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ +++#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */ +++#define EM_HUANY 81 /* Harvard University machine-independent object files */ +++#define EM_PRISM 82 /* SiTera Prism */ +++#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ +++#define EM_FR30 84 /* Fujitsu FR30 */ +++#define EM_D10V 85 /* Mitsubishi D10V */ +++#define EM_D30V 86 /* Mitsubishi D30V */ +++#define EM_V850 87 /* NEC v850 */ +++#define EM_M32R 88 /* Mitsubishi M32R */ +++#define EM_MN10300 89 /* Matsushita MN10300 */ +++#define EM_MN10200 90 /* Matsushita MN10200 */ +++#define EM_PJ 91 /* picoJava */ +++#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ +++#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ +++#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ +++#define EM_TILEPRO 188 /* Tilera TILEPro */ +++#define EM_TILEGX 191 /* Tilera TILE-Gx */ +++#define EM_NUM 192 +++ +++/* If it is necessary to assign new unofficial EM_* values, please +++ pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the +++ chances of collision with official or non-GNU unofficial values. */ +++ +++#define EM_ALPHA 0x9026 +++ +++/* Legal values for e_version (version). */ +++ +++#define EV_NONE 0 /* Invalid ELF version */ +++#define EV_CURRENT 1 /* Current version */ +++#define EV_NUM 2 +++ +++/* Section header. */ +++ +++typedef struct +++{ +++ Elf32_Word sh_name; /* Section name (string tbl index) */ +++ Elf32_Word sh_type; /* Section type */ +++ Elf32_Word sh_flags; /* Section flags */ +++ Elf32_Addr sh_addr; /* Section virtual addr at execution */ +++ Elf32_Off sh_offset; /* Section file offset */ +++ Elf32_Word sh_size; /* Section size in bytes */ +++ Elf32_Word sh_link; /* Link to another section */ +++ Elf32_Word sh_info; /* Additional section information */ +++ Elf32_Word sh_addralign; /* Section alignment */ +++ Elf32_Word sh_entsize; /* Entry size if section holds table */ +++} Elf32_Shdr; +++ +++typedef struct +++{ +++ Elf64_Word sh_name; /* Section name (string tbl index) */ +++ Elf64_Word sh_type; /* Section type */ +++ Elf64_Xword sh_flags; /* Section flags */ +++ Elf64_Addr sh_addr; /* Section virtual addr at execution */ +++ Elf64_Off sh_offset; /* Section file offset */ +++ Elf64_Xword sh_size; /* Section size in bytes */ +++ Elf64_Word sh_link; /* Link to another section */ +++ Elf64_Word sh_info; /* Additional section information */ +++ Elf64_Xword sh_addralign; /* Section alignment */ +++ Elf64_Xword sh_entsize; /* Entry size if section holds table */ +++} Elf64_Shdr; +++ +++/* Special section indices. */ +++ +++#define SHN_UNDEF 0 /* Undefined section */ +++#define SHN_LORESERVE 0xff00 /* Start of reserved indices */ +++#define SHN_LOPROC 0xff00 /* Start of processor-specific */ +++#define SHN_BEFORE 0xff00 /* Order section before all others +++ (Solaris). */ +++#define SHN_AFTER 0xff01 /* Order section after all others +++ (Solaris). */ +++#define SHN_HIPROC 0xff1f /* End of processor-specific */ +++#define SHN_LOOS 0xff20 /* Start of OS-specific */ +++#define SHN_HIOS 0xff3f /* End of OS-specific */ +++#define SHN_ABS 0xfff1 /* Associated symbol is absolute */ +++#define SHN_COMMON 0xfff2 /* Associated symbol is common */ +++#define SHN_XINDEX 0xffff /* Index is in extra table. */ +++#define SHN_HIRESERVE 0xffff /* End of reserved indices */ +++ +++/* Legal values for sh_type (section type). */ +++ +++#define SHT_NULL 0 /* Section header table entry unused */ +++#define SHT_PROGBITS 1 /* Program data */ +++#define SHT_SYMTAB 2 /* Symbol table */ +++#define SHT_STRTAB 3 /* String table */ +++#define SHT_RELA 4 /* Relocation entries with addends */ +++#define SHT_HASH 5 /* Symbol hash table */ +++#define SHT_DYNAMIC 6 /* Dynamic linking information */ +++#define SHT_NOTE 7 /* Notes */ +++#define SHT_NOBITS 8 /* Program space with no data (bss) */ +++#define SHT_REL 9 /* Relocation entries, no addends */ +++#define SHT_SHLIB 10 /* Reserved */ +++#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ +++#define SHT_INIT_ARRAY 14 /* Array of constructors */ +++#define SHT_FINI_ARRAY 15 /* Array of destructors */ +++#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ +++#define SHT_GROUP 17 /* Section group */ +++#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ +++#define SHT_NUM 19 /* Number of defined types. */ +++#define SHT_LOOS 0x60000000 /* Start OS-specific. */ +++#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */ +++#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */ +++#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */ +++#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */ +++#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */ +++#define SHT_SUNW_move 0x6ffffffa +++#define SHT_SUNW_COMDAT 0x6ffffffb +++#define SHT_SUNW_syminfo 0x6ffffffc +++#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ +++#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ +++#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ +++#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ +++#define SHT_HIOS 0x6fffffff /* End OS-specific type */ +++#define SHT_LOPROC 0x70000000 /* Start of processor-specific */ +++#define SHT_HIPROC 0x7fffffff /* End of processor-specific */ +++#define SHT_LOUSER 0x80000000 /* Start of application-specific */ +++#define SHT_HIUSER 0x8fffffff /* End of application-specific */ +++ +++/* Legal values for sh_flags (section flags). */ +++ +++#define SHF_WRITE (1 << 0) /* Writable */ +++#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ +++#define SHF_EXECINSTR (1 << 2) /* Executable */ +++#define SHF_MERGE (1 << 4) /* Might be merged */ +++#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */ +++#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */ +++#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */ +++#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling +++ required */ +++#define SHF_GROUP (1 << 9) /* Section is member of a group. */ +++#define SHF_TLS (1 << 10) /* Section hold thread-local data. */ +++#define SHF_MASKOS 0x0ff00000 /* OS-specific. */ +++#define SHF_MASKPROC 0xf0000000 /* Processor-specific */ +++#define SHF_ORDERED (1 << 30) /* Special ordering requirement +++ (Solaris). */ +++#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless +++ referenced or allocated (Solaris).*/ +++ +++/* Section group handling. */ +++#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */ +++ +++/* Symbol table entry. */ +++ +++typedef struct +++{ +++ Elf32_Word st_name; /* Symbol name (string tbl index) */ +++ Elf32_Addr st_value; /* Symbol value */ +++ Elf32_Word st_size; /* Symbol size */ +++ unsigned char st_info; /* Symbol type and binding */ +++ unsigned char st_other; /* Symbol visibility */ +++ Elf32_Section st_shndx; /* Section index */ +++} Elf32_Sym; +++ +++typedef struct +++{ +++ Elf64_Word st_name; /* Symbol name (string tbl index) */ +++ unsigned char st_info; /* Symbol type and binding */ +++ unsigned char st_other; /* Symbol visibility */ +++ Elf64_Section st_shndx; /* Section index */ +++ Elf64_Addr st_value; /* Symbol value */ +++ Elf64_Xword st_size; /* Symbol size */ +++} Elf64_Sym; +++ +++/* The syminfo section if available contains additional information about +++ every dynamic symbol. */ +++ +++typedef struct +++{ +++ Elf32_Half si_boundto; /* Direct bindings, symbol bound to */ +++ Elf32_Half si_flags; /* Per symbol flags */ +++} Elf32_Syminfo; +++ +++typedef struct +++{ +++ Elf64_Half si_boundto; /* Direct bindings, symbol bound to */ +++ Elf64_Half si_flags; /* Per symbol flags */ +++} Elf64_Syminfo; +++ +++/* Possible values for si_boundto. */ +++#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */ +++#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */ +++#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */ +++ +++/* Possible bitmasks for si_flags. */ +++#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */ +++#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */ +++#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */ +++#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy +++ loaded */ +++/* Syminfo version values. */ +++#define SYMINFO_NONE 0 +++#define SYMINFO_CURRENT 1 +++#define SYMINFO_NUM 2 +++ +++ +++/* How to extract and insert information held in the st_info field. */ +++ +++#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) +++#define ELF32_ST_TYPE(val) ((val) & 0xf) +++#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) +++ +++/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */ +++#define ELF64_ST_BIND(val) ELF32_ST_BIND (val) +++#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val) +++#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) +++ +++/* Legal values for ST_BIND subfield of st_info (symbol binding). */ +++ +++#define STB_LOCAL 0 /* Local symbol */ +++#define STB_GLOBAL 1 /* Global symbol */ +++#define STB_WEAK 2 /* Weak symbol */ +++#define STB_NUM 3 /* Number of defined types. */ +++#define STB_LOOS 10 /* Start of OS-specific */ +++#define STB_GNU_UNIQUE 10 /* Unique symbol. */ +++#define STB_HIOS 12 /* End of OS-specific */ +++#define STB_LOPROC 13 /* Start of processor-specific */ +++#define STB_HIPROC 15 /* End of processor-specific */ +++ +++/* Legal values for ST_TYPE subfield of st_info (symbol type). */ +++ +++#define STT_NOTYPE 0 /* Symbol type is unspecified */ +++#define STT_OBJECT 1 /* Symbol is a data object */ +++#define STT_FUNC 2 /* Symbol is a code object */ +++#define STT_SECTION 3 /* Symbol associated with a section */ +++#define STT_FILE 4 /* Symbol's name is file name */ +++#define STT_COMMON 5 /* Symbol is a common data object */ +++#define STT_TLS 6 /* Symbol is thread-local data object*/ +++#define STT_NUM 7 /* Number of defined types. */ +++#define STT_LOOS 10 /* Start of OS-specific */ +++#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */ +++#define STT_HIOS 12 /* End of OS-specific */ +++#define STT_LOPROC 13 /* Start of processor-specific */ +++#define STT_HIPROC 15 /* End of processor-specific */ +++ +++ +++/* Symbol table indices are found in the hash buckets and chain table +++ of a symbol hash table section. This special index value indicates +++ the end of a chain, meaning no further symbols are found in that bucket. */ +++ +++#define STN_UNDEF 0 /* End of a chain. */ +++ +++ +++/* How to extract and insert information held in the st_other field. */ +++ +++#define ELF32_ST_VISIBILITY(o) ((o) & 0x03) +++ +++/* For ELF64 the definitions are the same. */ +++#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o) +++ +++/* Symbol visibility specification encoded in the st_other field. */ +++#define STV_DEFAULT 0 /* Default symbol visibility rules */ +++#define STV_INTERNAL 1 /* Processor specific hidden class */ +++#define STV_HIDDEN 2 /* Sym unavailable in other modules */ +++#define STV_PROTECTED 3 /* Not preemptible, not exported */ +++ +++ +++/* Relocation table entry without addend (in section of type SHT_REL). */ +++ +++typedef struct +++{ +++ Elf32_Addr r_offset; /* Address */ +++ Elf32_Word r_info; /* Relocation type and symbol index */ +++} Elf32_Rel; +++ +++/* I have seen two different definitions of the Elf64_Rel and +++ Elf64_Rela structures, so we'll leave them out until Novell (or +++ whoever) gets their act together. */ +++/* The following, at least, is used on Sparc v9, MIPS, and Alpha. */ +++ +++typedef struct +++{ +++ Elf64_Addr r_offset; /* Address */ +++ Elf64_Xword r_info; /* Relocation type and symbol index */ +++} Elf64_Rel; +++ +++/* Relocation table entry with addend (in section of type SHT_RELA). */ +++ +++typedef struct +++{ +++ Elf32_Addr r_offset; /* Address */ +++ Elf32_Word r_info; /* Relocation type and symbol index */ +++ Elf32_Sword r_addend; /* Addend */ +++} Elf32_Rela; +++ +++typedef struct +++{ +++ Elf64_Addr r_offset; /* Address */ +++ Elf64_Xword r_info; /* Relocation type and symbol index */ +++ Elf64_Sxword r_addend; /* Addend */ +++} Elf64_Rela; +++ +++/* How to extract and insert information held in the r_info field. */ +++ +++#define ELF32_R_SYM(val) ((val) >> 8) +++#define ELF32_R_TYPE(val) ((val) & 0xff) +++#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff)) +++ +++#define ELF64_R_SYM(i) ((i) >> 32) +++#define ELF64_R_TYPE(i) ((i) & 0xffffffff) +++#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type)) +++ +++/* Program segment header. */ +++ +++typedef struct +++{ +++ Elf32_Word p_type; /* Segment type */ +++ Elf32_Off p_offset; /* Segment file offset */ +++ Elf32_Addr p_vaddr; /* Segment virtual address */ +++ Elf32_Addr p_paddr; /* Segment physical address */ +++ Elf32_Word p_filesz; /* Segment size in file */ +++ Elf32_Word p_memsz; /* Segment size in memory */ +++ Elf32_Word p_flags; /* Segment flags */ +++ Elf32_Word p_align; /* Segment alignment */ +++} Elf32_Phdr; +++ +++typedef struct +++{ +++ Elf64_Word p_type; /* Segment type */ +++ Elf64_Word p_flags; /* Segment flags */ +++ Elf64_Off p_offset; /* Segment file offset */ +++ Elf64_Addr p_vaddr; /* Segment virtual address */ +++ Elf64_Addr p_paddr; /* Segment physical address */ +++ Elf64_Xword p_filesz; /* Segment size in file */ +++ Elf64_Xword p_memsz; /* Segment size in memory */ +++ Elf64_Xword p_align; /* Segment alignment */ +++} Elf64_Phdr; +++ +++/* Special value for e_phnum. This indicates that the real number of +++ program headers is too large to fit into e_phnum. Instead the real +++ value is in the field sh_info of section 0. */ +++ +++#define PN_XNUM 0xffff +++ +++/* Legal values for p_type (segment type). */ +++ +++#define PT_NULL 0 /* Program header table entry unused */ +++#define PT_LOAD 1 /* Loadable program segment */ +++#define PT_DYNAMIC 2 /* Dynamic linking information */ +++#define PT_INTERP 3 /* Program interpreter */ +++#define PT_NOTE 4 /* Auxiliary information */ +++#define PT_SHLIB 5 /* Reserved */ +++#define PT_PHDR 6 /* Entry for header table itself */ +++#define PT_TLS 7 /* Thread-local storage segment */ +++#define PT_NUM 8 /* Number of defined types */ +++#define PT_LOOS 0x60000000 /* Start of OS-specific */ +++#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ +++#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */ +++#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ +++#define PT_LOSUNW 0x6ffffffa +++#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ +++#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ +++#define PT_HISUNW 0x6fffffff +++#define PT_HIOS 0x6fffffff /* End of OS-specific */ +++#define PT_LOPROC 0x70000000 /* Start of processor-specific */ +++#define PT_HIPROC 0x7fffffff /* End of processor-specific */ +++ +++/* Legal values for p_flags (segment flags). */ +++ +++#define PF_X (1 << 0) /* Segment is executable */ +++#define PF_W (1 << 1) /* Segment is writable */ +++#define PF_R (1 << 2) /* Segment is readable */ +++#define PF_MASKOS 0x0ff00000 /* OS-specific */ +++#define PF_MASKPROC 0xf0000000 /* Processor-specific */ +++ +++/* Legal values for note segment descriptor types for core files. */ +++ +++#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */ +++#define NT_FPREGSET 2 /* Contains copy of fpregset struct */ +++#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */ +++#define NT_PRXREG 4 /* Contains copy of prxregset struct */ +++#define NT_TASKSTRUCT 4 /* Contains copy of task structure */ +++#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */ +++#define NT_AUXV 6 /* Contains copy of auxv array */ +++#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */ +++#define NT_ASRS 8 /* Contains copy of asrset struct */ +++#define NT_PSTATUS 10 /* Contains copy of pstatus struct */ +++#define NT_PSINFO 13 /* Contains copy of psinfo struct */ +++#define NT_PRCRED 14 /* Contains copy of prcred struct */ +++#define NT_UTSNAME 15 /* Contains copy of utsname struct */ +++#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */ +++#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */ +++#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */ +++#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_struct */ +++#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ +++#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ +++#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */ +++#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ +++#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ +++#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */ +++ +++/* Legal values for the note segment descriptor types for object files. */ +++ +++#define NT_VERSION 1 /* Contains a version string. */ +++ +++ +++/* Dynamic section entry. */ +++ +++typedef struct +++{ +++ Elf32_Sword d_tag; /* Dynamic entry type */ +++ union +++ { +++ Elf32_Word d_val; /* Integer value */ +++ Elf32_Addr d_ptr; /* Address value */ +++ } d_un; +++} Elf32_Dyn; +++ +++typedef struct +++{ +++ Elf64_Sxword d_tag; /* Dynamic entry type */ +++ union +++ { +++ Elf64_Xword d_val; /* Integer value */ +++ Elf64_Addr d_ptr; /* Address value */ +++ } d_un; +++} Elf64_Dyn; +++ +++/* Legal values for d_tag (dynamic entry type). */ +++ +++#define DT_NULL 0 /* Marks end of dynamic section */ +++#define DT_NEEDED 1 /* Name of needed library */ +++#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ +++#define DT_PLTGOT 3 /* Processor defined value */ +++#define DT_HASH 4 /* Address of symbol hash table */ +++#define DT_STRTAB 5 /* Address of string table */ +++#define DT_SYMTAB 6 /* Address of symbol table */ +++#define DT_RELA 7 /* Address of Rela relocs */ +++#define DT_RELASZ 8 /* Total size of Rela relocs */ +++#define DT_RELAENT 9 /* Size of one Rela reloc */ +++#define DT_STRSZ 10 /* Size of string table */ +++#define DT_SYMENT 11 /* Size of one symbol table entry */ +++#define DT_INIT 12 /* Address of init function */ +++#define DT_FINI 13 /* Address of termination function */ +++#define DT_SONAME 14 /* Name of shared object */ +++#define DT_RPATH 15 /* Library search path (deprecated) */ +++#define DT_SYMBOLIC 16 /* Start symbol search here */ +++#define DT_REL 17 /* Address of Rel relocs */ +++#define DT_RELSZ 18 /* Total size of Rel relocs */ +++#define DT_RELENT 19 /* Size of one Rel reloc */ +++#define DT_PLTREL 20 /* Type of reloc in PLT */ +++#define DT_DEBUG 21 /* For debugging; unspecified */ +++#define DT_TEXTREL 22 /* Reloc might modify .text */ +++#define DT_JMPREL 23 /* Address of PLT relocs */ +++#define DT_BIND_NOW 24 /* Process relocations of object */ +++#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ +++#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ +++#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ +++#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ +++#define DT_RUNPATH 29 /* Library search path */ +++#define DT_FLAGS 30 /* Flags for the object being loaded */ +++#define DT_ENCODING 32 /* Start of encoded range */ +++#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ +++#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ +++#define DT_NUM 34 /* Number used */ +++#define DT_LOOS 0x6000000d /* Start of OS-specific */ +++#define DT_HIOS 0x6ffff000 /* End of OS-specific */ +++#define DT_LOPROC 0x70000000 /* Start of processor-specific */ +++#define DT_HIPROC 0x7fffffff /* End of processor-specific */ +++#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */ +++ +++/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the +++ Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's +++ approach. */ +++#define DT_VALRNGLO 0x6ffffd00 +++#define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */ +++#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */ +++#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */ +++#define DT_CHECKSUM 0x6ffffdf8 +++#define DT_PLTPADSZ 0x6ffffdf9 +++#define DT_MOVEENT 0x6ffffdfa +++#define DT_MOVESZ 0x6ffffdfb +++#define DT_FEATURE_1 0x6ffffdfc /* Feature selection (DTF_*). */ +++#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting +++ the following DT_* entry. */ +++#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */ +++#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */ +++#define DT_VALRNGHI 0x6ffffdff +++#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */ +++#define DT_VALNUM 12 +++ +++/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the +++ Dyn.d_un.d_ptr field of the Elf*_Dyn structure. +++ +++ If any adjustment is made to the ELF object after it has been +++ built these entries will need to be adjusted. */ +++#define DT_ADDRRNGLO 0x6ffffe00 +++#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table. */ +++#define DT_TLSDESC_PLT 0x6ffffef6 +++#define DT_TLSDESC_GOT 0x6ffffef7 +++#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */ +++#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */ +++#define DT_CONFIG 0x6ffffefa /* Configuration information. */ +++#define DT_DEPAUDIT 0x6ffffefb /* Dependency auditing. */ +++#define DT_AUDIT 0x6ffffefc /* Object auditing. */ +++#define DT_PLTPAD 0x6ffffefd /* PLT padding. */ +++#define DT_MOVETAB 0x6ffffefe /* Move table. */ +++#define DT_SYMINFO 0x6ffffeff /* Syminfo table. */ +++#define DT_ADDRRNGHI 0x6ffffeff +++#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */ +++#define DT_ADDRNUM 11 +++ +++/* The versioning entry types. The next are defined as part of the +++ GNU extension. */ +++#define DT_VERSYM 0x6ffffff0 +++ +++#define DT_RELACOUNT 0x6ffffff9 +++#define DT_RELCOUNT 0x6ffffffa +++ +++/* These were chosen by Sun. */ +++#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */ +++#define DT_VERDEF 0x6ffffffc /* Address of version definition +++ table */ +++#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */ +++#define DT_VERNEED 0x6ffffffe /* Address of table with needed +++ versions */ +++#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */ +++#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ +++#define DT_VERSIONTAGNUM 16 +++ +++/* Sun added these machine-independent extensions in the "processor-specific" +++ range. Be compatible. */ +++#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */ +++#define DT_FILTER 0x7fffffff /* Shared object to get values from */ +++#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1) +++#define DT_EXTRANUM 3 +++ +++/* Values of `d_un.d_val' in the DT_FLAGS entry. */ +++#define DF_ORIGIN 0x00000001 /* Object may use DF_ORIGIN */ +++#define DF_SYMBOLIC 0x00000002 /* Symbol resolutions starts here */ +++#define DF_TEXTREL 0x00000004 /* Object contains text relocations */ +++#define DF_BIND_NOW 0x00000008 /* No lazy binding for this object */ +++#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */ +++ +++/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 +++ entry in the dynamic section. */ +++#define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */ +++#define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */ +++#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */ +++#define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/ +++#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/ +++#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/ +++#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */ +++#define DF_1_ORIGIN 0x00000080 /* $ORIGIN must be handled. */ +++#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */ +++#define DF_1_TRANS 0x00000200 +++#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */ +++#define DF_1_NODEFLIB 0x00000800 /* Ignore default lib search path. */ +++#define DF_1_NODUMP 0x00001000 /* Object can't be dldump'ed. */ +++#define DF_1_CONFALT 0x00002000 /* Configuration alternative created.*/ +++#define DF_1_ENDFILTEE 0x00004000 /* Filtee terminates filters search. */ +++#define DF_1_DISPRELDNE 0x00008000 /* Disp reloc applied at build time. */ +++#define DF_1_DISPRELPND 0x00010000 /* Disp reloc applied at run-time. */ +++ +++/* Flags for the feature selection in DT_FEATURE_1. */ +++#define DTF_1_PARINIT 0x00000001 +++#define DTF_1_CONFEXP 0x00000002 +++ +++/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */ +++#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */ +++#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not +++ generally available. */ +++ +++/* Version definition sections. */ +++ +++typedef struct +++{ +++ Elf32_Half vd_version; /* Version revision */ +++ Elf32_Half vd_flags; /* Version information */ +++ Elf32_Half vd_ndx; /* Version Index */ +++ Elf32_Half vd_cnt; /* Number of associated aux entries */ +++ Elf32_Word vd_hash; /* Version name hash value */ +++ Elf32_Word vd_aux; /* Offset in bytes to verdaux array */ +++ Elf32_Word vd_next; /* Offset in bytes to next verdef +++ entry */ +++} Elf32_Verdef; +++ +++typedef struct +++{ +++ Elf64_Half vd_version; /* Version revision */ +++ Elf64_Half vd_flags; /* Version information */ +++ Elf64_Half vd_ndx; /* Version Index */ +++ Elf64_Half vd_cnt; /* Number of associated aux entries */ +++ Elf64_Word vd_hash; /* Version name hash value */ +++ Elf64_Word vd_aux; /* Offset in bytes to verdaux array */ +++ Elf64_Word vd_next; /* Offset in bytes to next verdef +++ entry */ +++} Elf64_Verdef; +++ +++ +++/* Legal values for vd_version (version revision). */ +++#define VER_DEF_NONE 0 /* No version */ +++#define VER_DEF_CURRENT 1 /* Current version */ +++#define VER_DEF_NUM 2 /* Given version number */ +++ +++/* Legal values for vd_flags (version information flags). */ +++#define VER_FLG_BASE 0x1 /* Version definition of file itself */ +++#define VER_FLG_WEAK 0x2 /* Weak version identifier */ +++ +++/* Versym symbol index values. */ +++#define VER_NDX_LOCAL 0 /* Symbol is local. */ +++#define VER_NDX_GLOBAL 1 /* Symbol is global. */ +++#define VER_NDX_LORESERVE 0xff00 /* Beginning of reserved entries. */ +++#define VER_NDX_ELIMINATE 0xff01 /* Symbol is to be eliminated. */ +++ +++/* Auxialiary version information. */ +++ +++typedef struct +++{ +++ Elf32_Word vda_name; /* Version or dependency names */ +++ Elf32_Word vda_next; /* Offset in bytes to next verdaux +++ entry */ +++} Elf32_Verdaux; +++ +++typedef struct +++{ +++ Elf64_Word vda_name; /* Version or dependency names */ +++ Elf64_Word vda_next; /* Offset in bytes to next verdaux +++ entry */ +++} Elf64_Verdaux; +++ +++ +++/* Version dependency section. */ +++ +++typedef struct +++{ +++ Elf32_Half vn_version; /* Version of structure */ +++ Elf32_Half vn_cnt; /* Number of associated aux entries */ +++ Elf32_Word vn_file; /* Offset of filename for this +++ dependency */ +++ Elf32_Word vn_aux; /* Offset in bytes to vernaux array */ +++ Elf32_Word vn_next; /* Offset in bytes to next verneed +++ entry */ +++} Elf32_Verneed; +++ +++typedef struct +++{ +++ Elf64_Half vn_version; /* Version of structure */ +++ Elf64_Half vn_cnt; /* Number of associated aux entries */ +++ Elf64_Word vn_file; /* Offset of filename for this +++ dependency */ +++ Elf64_Word vn_aux; /* Offset in bytes to vernaux array */ +++ Elf64_Word vn_next; /* Offset in bytes to next verneed +++ entry */ +++} Elf64_Verneed; +++ +++ +++/* Legal values for vn_version (version revision). */ +++#define VER_NEED_NONE 0 /* No version */ +++#define VER_NEED_CURRENT 1 /* Current version */ +++#define VER_NEED_NUM 2 /* Given version number */ +++ +++/* Auxiliary needed version information. */ +++ +++typedef struct +++{ +++ Elf32_Word vna_hash; /* Hash value of dependency name */ +++ Elf32_Half vna_flags; /* Dependency specific information */ +++ Elf32_Half vna_other; /* Unused */ +++ Elf32_Word vna_name; /* Dependency name string offset */ +++ Elf32_Word vna_next; /* Offset in bytes to next vernaux +++ entry */ +++} Elf32_Vernaux; +++ +++typedef struct +++{ +++ Elf64_Word vna_hash; /* Hash value of dependency name */ +++ Elf64_Half vna_flags; /* Dependency specific information */ +++ Elf64_Half vna_other; /* Unused */ +++ Elf64_Word vna_name; /* Dependency name string offset */ +++ Elf64_Word vna_next; /* Offset in bytes to next vernaux +++ entry */ +++} Elf64_Vernaux; +++ +++ +++/* Legal values for vna_flags. */ +++#define VER_FLG_WEAK 0x2 /* Weak version identifier */ +++ +++ +++/* Auxiliary vector. */ +++ +++/* This vector is normally only used by the program interpreter. The +++ usual definition in an ABI supplement uses the name auxv_t. The +++ vector is not usually defined in a standard file, but it +++ can't hurt. We rename it to avoid conflicts. The sizes of these +++ types are an arrangement between the exec server and the program +++ interpreter, so we don't fully specify them here. */ +++ +++typedef struct +++{ +++ uint32_t a_type; /* Entry type */ +++ union +++ { +++ uint32_t a_val; /* Integer value */ +++ /* We use to have pointer elements added here. We cannot do that, +++ though, since it does not work when using 32-bit definitions +++ on 64-bit platforms and vice versa. */ +++ } a_un; +++} Elf32_auxv_t; +++ +++typedef struct +++{ +++ uint64_t a_type; /* Entry type */ +++ union +++ { +++ uint64_t a_val; /* Integer value */ +++ /* We use to have pointer elements added here. We cannot do that, +++ though, since it does not work when using 32-bit definitions +++ on 64-bit platforms and vice versa. */ +++ } a_un; +++} Elf64_auxv_t; +++ +++/* Legal values for a_type (entry type). */ +++ +++#define AT_NULL 0 /* End of vector */ +++#define AT_IGNORE 1 /* Entry should be ignored */ +++#define AT_EXECFD 2 /* File descriptor of program */ +++#define AT_PHDR 3 /* Program headers for program */ +++#define AT_PHENT 4 /* Size of program header entry */ +++#define AT_PHNUM 5 /* Number of program headers */ +++#define AT_PAGESZ 6 /* System page size */ +++#define AT_BASE 7 /* Base address of interpreter */ +++#define AT_FLAGS 8 /* Flags */ +++#define AT_ENTRY 9 /* Entry point of program */ +++#define AT_NOTELF 10 /* Program is not ELF */ +++#define AT_UID 11 /* Real uid */ +++#define AT_EUID 12 /* Effective uid */ +++#define AT_GID 13 /* Real gid */ +++#define AT_EGID 14 /* Effective gid */ +++#define AT_CLKTCK 17 /* Frequency of times() */ +++ +++/* Some more special a_type values describing the hardware. */ +++#define AT_PLATFORM 15 /* String identifying platform. */ +++#define AT_HWCAP 16 /* Machine dependent hints about +++ processor capabilities. */ +++ +++/* This entry gives some information about the FPU initialization +++ performed by the kernel. */ +++#define AT_FPUCW 18 /* Used FPU control word. */ +++ +++/* Cache block sizes. */ +++#define AT_DCACHEBSIZE 19 /* Data cache block size. */ +++#define AT_ICACHEBSIZE 20 /* Instruction cache block size. */ +++#define AT_UCACHEBSIZE 21 /* Unified cache block size. */ +++ +++/* A special ignored value for PPC, used by the kernel to control the +++ interpretation of the AUXV. Must be > 16. */ +++#define AT_IGNOREPPC 22 /* Entry should be ignored. */ +++ +++#define AT_SECURE 23 /* Boolean, was exec setuid-like? */ +++ +++#define AT_BASE_PLATFORM 24 /* String identifying real platforms.*/ +++ +++#define AT_RANDOM 25 /* Address of 16 random bytes. */ +++ +++#define AT_EXECFN 31 /* Filename of executable. */ +++ +++/* Pointer to the global system page used for system calls and other +++ nice things. */ +++#define AT_SYSINFO 32 +++#define AT_SYSINFO_EHDR 33 +++ +++/* Shapes of the caches. Bits 0-3 contains associativity; bits 4-7 contains +++ log2 of line size; mask those to get cache size. */ +++#define AT_L1I_CACHESHAPE 34 +++#define AT_L1D_CACHESHAPE 35 +++#define AT_L2_CACHESHAPE 36 +++#define AT_L3_CACHESHAPE 37 +++ +++/* Note section contents. Each entry in the note section begins with +++ a header of a fixed form. */ +++ +++typedef struct +++{ +++ Elf32_Word n_namesz; /* Length of the note's name. */ +++ Elf32_Word n_descsz; /* Length of the note's descriptor. */ +++ Elf32_Word n_type; /* Type of the note. */ +++} Elf32_Nhdr; +++ +++typedef struct +++{ +++ Elf64_Word n_namesz; /* Length of the note's name. */ +++ Elf64_Word n_descsz; /* Length of the note's descriptor. */ +++ Elf64_Word n_type; /* Type of the note. */ +++} Elf64_Nhdr; +++ +++/* Known names of notes. */ +++ +++/* Solaris entries in the note section have this name. */ +++#define ELF_NOTE_SOLARIS "SUNW Solaris" +++ +++/* Note entries for GNU systems have this name. */ +++#define ELF_NOTE_GNU "GNU" +++ +++ +++/* Defined types of notes for Solaris. */ +++ +++/* Value of descriptor (one word) is desired pagesize for the binary. */ +++#define ELF_NOTE_PAGESIZE_HINT 1 +++ +++ +++/* Defined note types for GNU systems. */ +++ +++/* ABI information. The descriptor consists of words: +++ word 0: OS descriptor +++ word 1: major version of the ABI +++ word 2: minor version of the ABI +++ word 3: subminor version of the ABI +++*/ +++#define NT_GNU_ABI_TAG 1 +++#define ELF_NOTE_ABI NT_GNU_ABI_TAG /* Old name. */ +++ +++/* Known OSes. These values can appear in word 0 of an +++ NT_GNU_ABI_TAG note section entry. */ +++#define ELF_NOTE_OS_LINUX 0 +++#define ELF_NOTE_OS_GNU 1 +++#define ELF_NOTE_OS_SOLARIS2 2 +++#define ELF_NOTE_OS_FREEBSD 3 +++ +++/* Synthetic hwcap information. The descriptor begins with two words: +++ word 0: number of entries +++ word 1: bitmask of enabled entries +++ Then follow variable-length entries, one byte followed by a +++ '\0'-terminated hwcap name string. The byte gives the bit +++ number to test if enabled, (1U << bit) & bitmask. */ +++#define NT_GNU_HWCAP 2 +++ +++/* Build ID bits as generated by ld --build-id. +++ The descriptor consists of any nonzero number of bytes. */ +++#define NT_GNU_BUILD_ID 3 +++ +++/* Version note generated by GNU gold containing a version string. */ +++#define NT_GNU_GOLD_VERSION 4 +++ +++ +++/* Move records. */ +++typedef struct +++{ +++ Elf32_Xword m_value; /* Symbol value. */ +++ Elf32_Word m_info; /* Size and index. */ +++ Elf32_Word m_poffset; /* Symbol offset. */ +++ Elf32_Half m_repeat; /* Repeat count. */ +++ Elf32_Half m_stride; /* Stride info. */ +++} Elf32_Move; +++ +++typedef struct +++{ +++ Elf64_Xword m_value; /* Symbol value. */ +++ Elf64_Xword m_info; /* Size and index. */ +++ Elf64_Xword m_poffset; /* Symbol offset. */ +++ Elf64_Half m_repeat; /* Repeat count. */ +++ Elf64_Half m_stride; /* Stride info. */ +++} Elf64_Move; +++ +++/* Macro to construct move records. */ +++#define ELF32_M_SYM(info) ((info) >> 8) +++#define ELF32_M_SIZE(info) ((unsigned char) (info)) +++#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size)) +++ +++#define ELF64_M_SYM(info) ELF32_M_SYM (info) +++#define ELF64_M_SIZE(info) ELF32_M_SIZE (info) +++#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size) +++ +++ +++/* Motorola 68k specific definitions. */ +++ +++/* Values for Elf32_Ehdr.e_flags. */ +++#define EF_CPU32 0x00810000 +++ +++/* m68k relocs. */ +++ +++#define R_68K_NONE 0 /* No reloc */ +++#define R_68K_32 1 /* Direct 32 bit */ +++#define R_68K_16 2 /* Direct 16 bit */ +++#define R_68K_8 3 /* Direct 8 bit */ +++#define R_68K_PC32 4 /* PC relative 32 bit */ +++#define R_68K_PC16 5 /* PC relative 16 bit */ +++#define R_68K_PC8 6 /* PC relative 8 bit */ +++#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */ +++#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */ +++#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */ +++#define R_68K_GOT32O 10 /* 32 bit GOT offset */ +++#define R_68K_GOT16O 11 /* 16 bit GOT offset */ +++#define R_68K_GOT8O 12 /* 8 bit GOT offset */ +++#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */ +++#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */ +++#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */ +++#define R_68K_PLT32O 16 /* 32 bit PLT offset */ +++#define R_68K_PLT16O 17 /* 16 bit PLT offset */ +++#define R_68K_PLT8O 18 /* 8 bit PLT offset */ +++#define R_68K_COPY 19 /* Copy symbol at runtime */ +++#define R_68K_GLOB_DAT 20 /* Create GOT entry */ +++#define R_68K_JMP_SLOT 21 /* Create PLT entry */ +++#define R_68K_RELATIVE 22 /* Adjust by program base */ +++#define R_68K_TLS_GD32 25 /* 32 bit GOT offset for GD */ +++#define R_68K_TLS_GD16 26 /* 16 bit GOT offset for GD */ +++#define R_68K_TLS_GD8 27 /* 8 bit GOT offset for GD */ +++#define R_68K_TLS_LDM32 28 /* 32 bit GOT offset for LDM */ +++#define R_68K_TLS_LDM16 29 /* 16 bit GOT offset for LDM */ +++#define R_68K_TLS_LDM8 30 /* 8 bit GOT offset for LDM */ +++#define R_68K_TLS_LDO32 31 /* 32 bit module-relative offset */ +++#define R_68K_TLS_LDO16 32 /* 16 bit module-relative offset */ +++#define R_68K_TLS_LDO8 33 /* 8 bit module-relative offset */ +++#define R_68K_TLS_IE32 34 /* 32 bit GOT offset for IE */ +++#define R_68K_TLS_IE16 35 /* 16 bit GOT offset for IE */ +++#define R_68K_TLS_IE8 36 /* 8 bit GOT offset for IE */ +++#define R_68K_TLS_LE32 37 /* 32 bit offset relative to +++ static TLS block */ +++#define R_68K_TLS_LE16 38 /* 16 bit offset relative to +++ static TLS block */ +++#define R_68K_TLS_LE8 39 /* 8 bit offset relative to +++ static TLS block */ +++#define R_68K_TLS_DTPMOD32 40 /* 32 bit module number */ +++#define R_68K_TLS_DTPREL32 41 /* 32 bit module-relative offset */ +++#define R_68K_TLS_TPREL32 42 /* 32 bit TP-relative offset */ +++/* Keep this the last entry. */ +++#define R_68K_NUM 43 +++ +++/* Intel 80386 specific definitions. */ +++ +++/* i386 relocs. */ +++ +++#define R_386_NONE 0 /* No reloc */ +++#define R_386_32 1 /* Direct 32 bit */ +++#define R_386_PC32 2 /* PC relative 32 bit */ +++#define R_386_GOT32 3 /* 32 bit GOT entry */ +++#define R_386_PLT32 4 /* 32 bit PLT address */ +++#define R_386_COPY 5 /* Copy symbol at runtime */ +++#define R_386_GLOB_DAT 6 /* Create GOT entry */ +++#define R_386_JMP_SLOT 7 /* Create PLT entry */ +++#define R_386_RELATIVE 8 /* Adjust by program base */ +++#define R_386_GOTOFF 9 /* 32 bit offset to GOT */ +++#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */ +++#define R_386_32PLT 11 +++#define R_386_TLS_TPOFF 14 /* Offset in static TLS block */ +++#define R_386_TLS_IE 15 /* Address of GOT entry for static TLS +++ block offset */ +++#define R_386_TLS_GOTIE 16 /* GOT entry for static TLS block +++ offset */ +++#define R_386_TLS_LE 17 /* Offset relative to static TLS +++ block */ +++#define R_386_TLS_GD 18 /* Direct 32 bit for GNU version of +++ general dynamic thread local data */ +++#define R_386_TLS_LDM 19 /* Direct 32 bit for GNU version of +++ local dynamic thread local data +++ in LE code */ +++#define R_386_16 20 +++#define R_386_PC16 21 +++#define R_386_8 22 +++#define R_386_PC8 23 +++#define R_386_TLS_GD_32 24 /* Direct 32 bit for general dynamic +++ thread local data */ +++#define R_386_TLS_GD_PUSH 25 /* Tag for pushl in GD TLS code */ +++#define R_386_TLS_GD_CALL 26 /* Relocation for call to +++ __tls_get_addr() */ +++#define R_386_TLS_GD_POP 27 /* Tag for popl in GD TLS code */ +++#define R_386_TLS_LDM_32 28 /* Direct 32 bit for local dynamic +++ thread local data in LE code */ +++#define R_386_TLS_LDM_PUSH 29 /* Tag for pushl in LDM TLS code */ +++#define R_386_TLS_LDM_CALL 30 /* Relocation for call to +++ __tls_get_addr() in LDM code */ +++#define R_386_TLS_LDM_POP 31 /* Tag for popl in LDM TLS code */ +++#define R_386_TLS_LDO_32 32 /* Offset relative to TLS block */ +++#define R_386_TLS_IE_32 33 /* GOT entry for negated static TLS +++ block offset */ +++#define R_386_TLS_LE_32 34 /* Negated offset relative to static +++ TLS block */ +++#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */ +++#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */ +++#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */ +++/* 38? */ +++#define R_386_TLS_GOTDESC 39 /* GOT offset for TLS descriptor. */ +++#define R_386_TLS_DESC_CALL 40 /* Marker of call through TLS +++ descriptor for +++ relaxation. */ +++#define R_386_TLS_DESC 41 /* TLS descriptor containing +++ pointer to code and to +++ argument, returning the TLS +++ offset for the symbol. */ +++#define R_386_IRELATIVE 42 /* Adjust indirectly by program base */ +++/* Keep this the last entry. */ +++#define R_386_NUM 43 +++ +++/* SUN SPARC specific definitions. */ +++ +++/* Legal values for ST_TYPE subfield of st_info (symbol type). */ +++ +++#define STT_SPARC_REGISTER 13 /* Global register reserved to app. */ +++ +++/* Values for Elf64_Ehdr.e_flags. */ +++ +++#define EF_SPARCV9_MM 3 +++#define EF_SPARCV9_TSO 0 +++#define EF_SPARCV9_PSO 1 +++#define EF_SPARCV9_RMO 2 +++#define EF_SPARC_LEDATA 0x800000 /* little endian data */ +++#define EF_SPARC_EXT_MASK 0xFFFF00 +++#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */ +++#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */ +++#define EF_SPARC_HAL_R1 0x000400 /* HAL R1 extensions */ +++#define EF_SPARC_SUN_US3 0x000800 /* Sun UltraSPARCIII extensions */ +++ +++/* SPARC relocs. */ +++ +++#define R_SPARC_NONE 0 /* No reloc */ +++#define R_SPARC_8 1 /* Direct 8 bit */ +++#define R_SPARC_16 2 /* Direct 16 bit */ +++#define R_SPARC_32 3 /* Direct 32 bit */ +++#define R_SPARC_DISP8 4 /* PC relative 8 bit */ +++#define R_SPARC_DISP16 5 /* PC relative 16 bit */ +++#define R_SPARC_DISP32 6 /* PC relative 32 bit */ +++#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */ +++#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */ +++#define R_SPARC_HI22 9 /* High 22 bit */ +++#define R_SPARC_22 10 /* Direct 22 bit */ +++#define R_SPARC_13 11 /* Direct 13 bit */ +++#define R_SPARC_LO10 12 /* Truncated 10 bit */ +++#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */ +++#define R_SPARC_GOT13 14 /* 13 bit GOT entry */ +++#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */ +++#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */ +++#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */ +++#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */ +++#define R_SPARC_COPY 19 /* Copy symbol at runtime */ +++#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */ +++#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */ +++#define R_SPARC_RELATIVE 22 /* Adjust by program base */ +++#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */ +++ +++/* Additional Sparc64 relocs. */ +++ +++#define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */ +++#define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */ +++#define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */ +++#define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */ +++#define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */ +++#define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */ +++#define R_SPARC_10 30 /* Direct 10 bit */ +++#define R_SPARC_11 31 /* Direct 11 bit */ +++#define R_SPARC_64 32 /* Direct 64 bit */ +++#define R_SPARC_OLO10 33 /* 10bit with secondary 13bit addend */ +++#define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */ +++#define R_SPARC_HM10 35 /* High middle 10 bits of ... */ +++#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */ +++#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */ +++#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */ +++#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */ +++#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */ +++#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */ +++#define R_SPARC_GLOB_JMP 42 /* was part of v9 ABI but was removed */ +++#define R_SPARC_7 43 /* Direct 7 bit */ +++#define R_SPARC_5 44 /* Direct 5 bit */ +++#define R_SPARC_6 45 /* Direct 6 bit */ +++#define R_SPARC_DISP64 46 /* PC relative 64 bit */ +++#define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */ +++#define R_SPARC_HIX22 48 /* High 22 bit complemented */ +++#define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */ +++#define R_SPARC_H44 50 /* Direct high 12 of 44 bit */ +++#define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */ +++#define R_SPARC_L44 52 /* Direct low 10 of 44 bit */ +++#define R_SPARC_REGISTER 53 /* Global register usage */ +++#define R_SPARC_UA64 54 /* Direct 64 bit unaligned */ +++#define R_SPARC_UA16 55 /* Direct 16 bit unaligned */ +++#define R_SPARC_TLS_GD_HI22 56 +++#define R_SPARC_TLS_GD_LO10 57 +++#define R_SPARC_TLS_GD_ADD 58 +++#define R_SPARC_TLS_GD_CALL 59 +++#define R_SPARC_TLS_LDM_HI22 60 +++#define R_SPARC_TLS_LDM_LO10 61 +++#define R_SPARC_TLS_LDM_ADD 62 +++#define R_SPARC_TLS_LDM_CALL 63 +++#define R_SPARC_TLS_LDO_HIX22 64 +++#define R_SPARC_TLS_LDO_LOX10 65 +++#define R_SPARC_TLS_LDO_ADD 66 +++#define R_SPARC_TLS_IE_HI22 67 +++#define R_SPARC_TLS_IE_LO10 68 +++#define R_SPARC_TLS_IE_LD 69 +++#define R_SPARC_TLS_IE_LDX 70 +++#define R_SPARC_TLS_IE_ADD 71 +++#define R_SPARC_TLS_LE_HIX22 72 +++#define R_SPARC_TLS_LE_LOX10 73 +++#define R_SPARC_TLS_DTPMOD32 74 +++#define R_SPARC_TLS_DTPMOD64 75 +++#define R_SPARC_TLS_DTPOFF32 76 +++#define R_SPARC_TLS_DTPOFF64 77 +++#define R_SPARC_TLS_TPOFF32 78 +++#define R_SPARC_TLS_TPOFF64 79 +++#define R_SPARC_GOTDATA_HIX22 80 +++#define R_SPARC_GOTDATA_LOX10 81 +++#define R_SPARC_GOTDATA_OP_HIX22 82 +++#define R_SPARC_GOTDATA_OP_LOX10 83 +++#define R_SPARC_GOTDATA_OP 84 +++#define R_SPARC_H34 85 +++#define R_SPARC_SIZE32 86 +++#define R_SPARC_SIZE64 87 +++#define R_SPARC_WDISP10 88 +++#define R_SPARC_JMP_IREL 248 +++#define R_SPARC_IRELATIVE 249 +++#define R_SPARC_GNU_VTINHERIT 250 +++#define R_SPARC_GNU_VTENTRY 251 +++#define R_SPARC_REV32 252 +++/* Keep this the last entry. */ +++#define R_SPARC_NUM 253 +++ +++/* For Sparc64, legal values for d_tag of Elf64_Dyn. */ +++ +++#define DT_SPARC_REGISTER 0x70000001 +++#define DT_SPARC_NUM 2 +++ +++/* MIPS R3000 specific definitions. */ +++ +++/* Legal values for e_flags field of Elf32_Ehdr. */ +++ +++#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used */ +++#define EF_MIPS_PIC 2 /* Contains PIC code */ +++#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence */ +++#define EF_MIPS_XGOT 8 +++#define EF_MIPS_64BIT_WHIRL 16 +++#define EF_MIPS_ABI2 32 +++#define EF_MIPS_ABI_ON32 64 +++#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */ +++ +++/* Legal values for MIPS architecture level. */ +++ +++#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ +++#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ +++#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ +++#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ +++#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ +++#define EF_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ +++#define EF_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ +++ +++/* The following are non-official names and should not be used. */ +++ +++#define E_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ +++#define E_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ +++#define E_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ +++#define E_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ +++#define E_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ +++#define E_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ +++#define E_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ +++ +++/* Special section indices. */ +++ +++#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols */ +++#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */ +++#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */ +++#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */ +++#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */ +++ +++/* Legal values for sh_type field of Elf32_Shdr. */ +++ +++#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link */ +++#define SHT_MIPS_MSYM 0x70000001 +++#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols */ +++#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes */ +++#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */ +++#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging information*/ +++#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information */ +++#define SHT_MIPS_PACKAGE 0x70000007 +++#define SHT_MIPS_PACKSYM 0x70000008 +++#define SHT_MIPS_RELD 0x70000009 +++#define SHT_MIPS_IFACE 0x7000000b +++#define SHT_MIPS_CONTENT 0x7000000c +++#define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */ +++#define SHT_MIPS_SHDR 0x70000010 +++#define SHT_MIPS_FDESC 0x70000011 +++#define SHT_MIPS_EXTSYM 0x70000012 +++#define SHT_MIPS_DENSE 0x70000013 +++#define SHT_MIPS_PDESC 0x70000014 +++#define SHT_MIPS_LOCSYM 0x70000015 +++#define SHT_MIPS_AUXSYM 0x70000016 +++#define SHT_MIPS_OPTSYM 0x70000017 +++#define SHT_MIPS_LOCSTR 0x70000018 +++#define SHT_MIPS_LINE 0x70000019 +++#define SHT_MIPS_RFDESC 0x7000001a +++#define SHT_MIPS_DELTASYM 0x7000001b +++#define SHT_MIPS_DELTAINST 0x7000001c +++#define SHT_MIPS_DELTACLASS 0x7000001d +++#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */ +++#define SHT_MIPS_DELTADECL 0x7000001f +++#define SHT_MIPS_SYMBOL_LIB 0x70000020 +++#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */ +++#define SHT_MIPS_TRANSLATE 0x70000022 +++#define SHT_MIPS_PIXIE 0x70000023 +++#define SHT_MIPS_XLATE 0x70000024 +++#define SHT_MIPS_XLATE_DEBUG 0x70000025 +++#define SHT_MIPS_WHIRL 0x70000026 +++#define SHT_MIPS_EH_REGION 0x70000027 +++#define SHT_MIPS_XLATE_OLD 0x70000028 +++#define SHT_MIPS_PDR_EXCEPTION 0x70000029 +++ +++/* Legal values for sh_flags field of Elf32_Shdr. */ +++ +++#define SHF_MIPS_GPREL 0x10000000 /* Must be part of global data area */ +++#define SHF_MIPS_MERGE 0x20000000 +++#define SHF_MIPS_ADDR 0x40000000 +++#define SHF_MIPS_STRINGS 0x80000000 +++#define SHF_MIPS_NOSTRIP 0x08000000 +++#define SHF_MIPS_LOCAL 0x04000000 +++#define SHF_MIPS_NAMES 0x02000000 +++#define SHF_MIPS_NODUPE 0x01000000 +++ +++ +++/* Symbol tables. */ +++ +++/* MIPS specific values for `st_other'. */ +++#define STO_MIPS_DEFAULT 0x0 +++#define STO_MIPS_INTERNAL 0x1 +++#define STO_MIPS_HIDDEN 0x2 +++#define STO_MIPS_PROTECTED 0x3 +++#define STO_MIPS_PLT 0x8 +++#define STO_MIPS_SC_ALIGN_UNUSED 0xff +++ +++/* MIPS specific values for `st_info'. */ +++#define STB_MIPS_SPLIT_COMMON 13 +++ +++/* Entries found in sections of type SHT_MIPS_GPTAB. */ +++ +++typedef union +++{ +++ struct +++ { +++ Elf32_Word gt_current_g_value; /* -G value used for compilation */ +++ Elf32_Word gt_unused; /* Not used */ +++ } gt_header; /* First entry in section */ +++ struct +++ { +++ Elf32_Word gt_g_value; /* If this value were used for -G */ +++ Elf32_Word gt_bytes; /* This many bytes would be used */ +++ } gt_entry; /* Subsequent entries in section */ +++} Elf32_gptab; +++ +++/* Entry found in sections of type SHT_MIPS_REGINFO. */ +++ +++typedef struct +++{ +++ Elf32_Word ri_gprmask; /* General registers used */ +++ Elf32_Word ri_cprmask[4]; /* Coprocessor registers used */ +++ Elf32_Sword ri_gp_value; /* $gp register value */ +++} Elf32_RegInfo; +++ +++/* Entries found in sections of type SHT_MIPS_OPTIONS. */ +++ +++typedef struct +++{ +++ unsigned char kind; /* Determines interpretation of the +++ variable part of descriptor. */ +++ unsigned char size; /* Size of descriptor, including header. */ +++ Elf32_Section section; /* Section header index of section affected, +++ 0 for global options. */ +++ Elf32_Word info; /* Kind-specific information. */ +++} Elf_Options; +++ +++/* Values for `kind' field in Elf_Options. */ +++ +++#define ODK_NULL 0 /* Undefined. */ +++#define ODK_REGINFO 1 /* Register usage information. */ +++#define ODK_EXCEPTIONS 2 /* Exception processing options. */ +++#define ODK_PAD 3 /* Section padding options. */ +++#define ODK_HWPATCH 4 /* Hardware workarounds performed */ +++#define ODK_FILL 5 /* record the fill value used by the linker. */ +++#define ODK_TAGS 6 /* reserve space for desktop tools to write. */ +++#define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */ +++#define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */ +++ +++/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries. */ +++ +++#define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */ +++#define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */ +++#define OEX_PAGE0 0x10000 /* page zero must be mapped. */ +++#define OEX_SMM 0x20000 /* Force sequential memory mode? */ +++#define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */ +++#define OEX_PRECISEFP OEX_FPDBUG +++#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */ +++ +++#define OEX_FPU_INVAL 0x10 +++#define OEX_FPU_DIV0 0x08 +++#define OEX_FPU_OFLO 0x04 +++#define OEX_FPU_UFLO 0x02 +++#define OEX_FPU_INEX 0x01 +++ +++/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry. */ +++ +++#define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */ +++#define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */ +++#define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */ +++#define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */ +++ +++#define OPAD_PREFIX 0x1 +++#define OPAD_POSTFIX 0x2 +++#define OPAD_SYMBOL 0x4 +++ +++/* Entry found in `.options' section. */ +++ +++typedef struct +++{ +++ Elf32_Word hwp_flags1; /* Extra flags. */ +++ Elf32_Word hwp_flags2; /* Extra flags. */ +++} Elf_Options_Hw; +++ +++/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries. */ +++ +++#define OHWA0_R4KEOP_CHECKED 0x00000001 +++#define OHWA1_R4KEOP_CLEAN 0x00000002 +++ +++/* MIPS relocs. */ +++ +++#define R_MIPS_NONE 0 /* No reloc */ +++#define R_MIPS_16 1 /* Direct 16 bit */ +++#define R_MIPS_32 2 /* Direct 32 bit */ +++#define R_MIPS_REL32 3 /* PC relative 32 bit */ +++#define R_MIPS_26 4 /* Direct 26 bit shifted */ +++#define R_MIPS_HI16 5 /* High 16 bit */ +++#define R_MIPS_LO16 6 /* Low 16 bit */ +++#define R_MIPS_GPREL16 7 /* GP relative 16 bit */ +++#define R_MIPS_LITERAL 8 /* 16 bit literal entry */ +++#define R_MIPS_GOT16 9 /* 16 bit GOT entry */ +++#define R_MIPS_PC16 10 /* PC relative 16 bit */ +++#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ +++#define R_MIPS_GPREL32 12 /* GP relative 32 bit */ +++ +++#define R_MIPS_SHIFT5 16 +++#define R_MIPS_SHIFT6 17 +++#define R_MIPS_64 18 +++#define R_MIPS_GOT_DISP 19 +++#define R_MIPS_GOT_PAGE 20 +++#define R_MIPS_GOT_OFST 21 +++#define R_MIPS_GOT_HI16 22 +++#define R_MIPS_GOT_LO16 23 +++#define R_MIPS_SUB 24 +++#define R_MIPS_INSERT_A 25 +++#define R_MIPS_INSERT_B 26 +++#define R_MIPS_DELETE 27 +++#define R_MIPS_HIGHER 28 +++#define R_MIPS_HIGHEST 29 +++#define R_MIPS_CALL_HI16 30 +++#define R_MIPS_CALL_LO16 31 +++#define R_MIPS_SCN_DISP 32 +++#define R_MIPS_REL16 33 +++#define R_MIPS_ADD_IMMEDIATE 34 +++#define R_MIPS_PJUMP 35 +++#define R_MIPS_RELGOT 36 +++#define R_MIPS_JALR 37 +++#define R_MIPS_TLS_DTPMOD32 38 /* Module number 32 bit */ +++#define R_MIPS_TLS_DTPREL32 39 /* Module-relative offset 32 bit */ +++#define R_MIPS_TLS_DTPMOD64 40 /* Module number 64 bit */ +++#define R_MIPS_TLS_DTPREL64 41 /* Module-relative offset 64 bit */ +++#define R_MIPS_TLS_GD 42 /* 16 bit GOT offset for GD */ +++#define R_MIPS_TLS_LDM 43 /* 16 bit GOT offset for LDM */ +++#define R_MIPS_TLS_DTPREL_HI16 44 /* Module-relative offset, high 16 bits */ +++#define R_MIPS_TLS_DTPREL_LO16 45 /* Module-relative offset, low 16 bits */ +++#define R_MIPS_TLS_GOTTPREL 46 /* 16 bit GOT offset for IE */ +++#define R_MIPS_TLS_TPREL32 47 /* TP-relative offset, 32 bit */ +++#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */ +++#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */ +++#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */ +++#define R_MIPS_GLOB_DAT 51 +++#define R_MIPS_COPY 126 +++#define R_MIPS_JUMP_SLOT 127 +++/* Keep this the last entry. */ +++#define R_MIPS_NUM 128 +++ +++/* Legal values for p_type field of Elf32_Phdr. */ +++ +++#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */ +++#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */ +++#define PT_MIPS_OPTIONS 0x70000002 +++ +++/* Special program header types. */ +++ +++#define PF_MIPS_LOCAL 0x10000000 +++ +++/* Legal values for d_tag field of Elf32_Dyn. */ +++ +++#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */ +++#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */ +++#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */ +++#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */ +++#define DT_MIPS_FLAGS 0x70000005 /* Flags */ +++#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */ +++#define DT_MIPS_MSYM 0x70000007 +++#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */ +++#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */ +++#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */ +++#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */ +++#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */ +++#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */ +++#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */ +++#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */ +++#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */ +++#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */ +++#define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */ +++#define DT_MIPS_DELTA_CLASS_NO 0x70000018 /* Number of entries in +++ DT_MIPS_DELTA_CLASS. */ +++#define DT_MIPS_DELTA_INSTANCE 0x70000019 /* Delta C++ class instances. */ +++#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in +++ DT_MIPS_DELTA_INSTANCE. */ +++#define DT_MIPS_DELTA_RELOC 0x7000001b /* Delta relocations. */ +++#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in +++ DT_MIPS_DELTA_RELOC. */ +++#define DT_MIPS_DELTA_SYM 0x7000001d /* Delta symbols that Delta +++ relocations refer to. */ +++#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in +++ DT_MIPS_DELTA_SYM. */ +++#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the +++ class declaration. */ +++#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in +++ DT_MIPS_DELTA_CLASSSYM. */ +++#define DT_MIPS_CXX_FLAGS 0x70000022 /* Flags indicating for C++ flavor. */ +++#define DT_MIPS_PIXIE_INIT 0x70000023 +++#define DT_MIPS_SYMBOL_LIB 0x70000024 +++#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025 +++#define DT_MIPS_LOCAL_GOTIDX 0x70000026 +++#define DT_MIPS_HIDDEN_GOTIDX 0x70000027 +++#define DT_MIPS_PROTECTED_GOTIDX 0x70000028 +++#define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */ +++#define DT_MIPS_INTERFACE 0x7000002a /* Address of .interface. */ +++#define DT_MIPS_DYNSTR_ALIGN 0x7000002b +++#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */ +++#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve +++ function stored in GOT. */ +++#define DT_MIPS_PERF_SUFFIX 0x7000002e /* Default suffix of dso to be added +++ by rld on dlopen() calls. */ +++#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */ +++#define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */ +++#define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */ +++/* The address of .got.plt in an executable using the new non-PIC ABI. */ +++#define DT_MIPS_PLTGOT 0x70000032 +++/* The base of the PLT in an executable using the new non-PIC ABI if that +++ PLT is writable. For a non-writable PLT, this is omitted or has a zero +++ value. */ +++#define DT_MIPS_RWPLT 0x70000034 +++#define DT_MIPS_NUM 0x35 +++ +++/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */ +++ +++#define RHF_NONE 0 /* No flags */ +++#define RHF_QUICKSTART (1 << 0) /* Use quickstart */ +++#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */ +++#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */ +++#define RHF_NO_MOVE (1 << 3) +++#define RHF_SGI_ONLY (1 << 4) +++#define RHF_GUARANTEE_INIT (1 << 5) +++#define RHF_DELTA_C_PLUS_PLUS (1 << 6) +++#define RHF_GUARANTEE_START_INIT (1 << 7) +++#define RHF_PIXIE (1 << 8) +++#define RHF_DEFAULT_DELAY_LOAD (1 << 9) +++#define RHF_REQUICKSTART (1 << 10) +++#define RHF_REQUICKSTARTED (1 << 11) +++#define RHF_CORD (1 << 12) +++#define RHF_NO_UNRES_UNDEF (1 << 13) +++#define RHF_RLD_ORDER_SAFE (1 << 14) +++ +++/* Entries found in sections of type SHT_MIPS_LIBLIST. */ +++ +++typedef struct +++{ +++ Elf32_Word l_name; /* Name (string table index) */ +++ Elf32_Word l_time_stamp; /* Timestamp */ +++ Elf32_Word l_checksum; /* Checksum */ +++ Elf32_Word l_version; /* Interface version */ +++ Elf32_Word l_flags; /* Flags */ +++} Elf32_Lib; +++ +++typedef struct +++{ +++ Elf64_Word l_name; /* Name (string table index) */ +++ Elf64_Word l_time_stamp; /* Timestamp */ +++ Elf64_Word l_checksum; /* Checksum */ +++ Elf64_Word l_version; /* Interface version */ +++ Elf64_Word l_flags; /* Flags */ +++} Elf64_Lib; +++ +++ +++/* Legal values for l_flags. */ +++ +++#define LL_NONE 0 +++#define LL_EXACT_MATCH (1 << 0) /* Require exact match */ +++#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */ +++#define LL_REQUIRE_MINOR (1 << 2) +++#define LL_EXPORTS (1 << 3) +++#define LL_DELAY_LOAD (1 << 4) +++#define LL_DELTA (1 << 5) +++ +++/* Entries found in sections of type SHT_MIPS_CONFLICT. */ +++ +++typedef Elf32_Addr Elf32_Conflict; +++ +++ +++/* HPPA specific definitions. */ +++ +++/* Legal values for e_flags field of Elf32_Ehdr. */ +++ +++#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */ +++#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */ +++#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */ +++#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */ +++#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch +++ prediction. */ +++#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */ +++#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */ +++ +++/* Defined values for `e_flags & EF_PARISC_ARCH' are: */ +++ +++#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */ +++#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */ +++#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */ +++ +++/* Additional section indeces. */ +++ +++#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared +++ symbols in ANSI C. */ +++#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */ +++ +++/* Legal values for sh_type field of Elf32_Shdr. */ +++ +++#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */ +++#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */ +++#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */ +++ +++/* Legal values for sh_flags field of Elf32_Shdr. */ +++ +++#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */ +++#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */ +++#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */ +++ +++/* Legal values for ST_TYPE subfield of st_info (symbol type). */ +++ +++#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */ +++ +++#define STT_HP_OPAQUE (STT_LOOS + 0x1) +++#define STT_HP_STUB (STT_LOOS + 0x2) +++ +++/* HPPA relocs. */ +++ +++#define R_PARISC_NONE 0 /* No reloc. */ +++#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */ +++#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */ +++#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */ +++#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */ +++#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */ +++#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */ +++#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */ +++#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */ +++#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */ +++#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */ +++#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */ +++#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */ +++#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */ +++#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */ +++#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */ +++#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */ +++#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */ +++#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */ +++#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */ +++#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */ +++#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */ +++#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */ +++#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */ +++#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */ +++#define R_PARISC_FPTR64 64 /* 64 bits function address. */ +++#define R_PARISC_PLABEL32 65 /* 32 bits function address. */ +++#define R_PARISC_PLABEL21L 66 /* Left 21 bits of fdesc address. */ +++#define R_PARISC_PLABEL14R 70 /* Right 14 bits of fdesc address. */ +++#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */ +++#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */ +++#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */ +++#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */ +++#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */ +++#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */ +++#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */ +++#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */ +++#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */ +++#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */ +++#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */ +++#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */ +++#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */ +++#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */ +++#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */ +++#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */ +++#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */ +++#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */ +++#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */ +++#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */ +++#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */ +++#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */ +++#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */ +++#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */ +++#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */ +++#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */ +++#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */ +++#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */ +++#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */ +++#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */ +++#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */ +++#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */ +++#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */ +++#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */ +++#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */ +++#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */ +++#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */ +++#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */ +++#define R_PARISC_LORESERVE 128 +++#define R_PARISC_COPY 128 /* Copy relocation. */ +++#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */ +++#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */ +++#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */ +++#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */ +++#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */ +++#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */ +++#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/ +++#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */ +++#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */ +++#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */ +++#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */ +++#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */ +++#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */ +++#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */ +++#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */ +++#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/ +++#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/ +++#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */ +++#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */ +++#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */ +++#define R_PARISC_GNU_VTENTRY 232 +++#define R_PARISC_GNU_VTINHERIT 233 +++#define R_PARISC_TLS_GD21L 234 /* GD 21-bit left. */ +++#define R_PARISC_TLS_GD14R 235 /* GD 14-bit right. */ +++#define R_PARISC_TLS_GDCALL 236 /* GD call to __t_g_a. */ +++#define R_PARISC_TLS_LDM21L 237 /* LD module 21-bit left. */ +++#define R_PARISC_TLS_LDM14R 238 /* LD module 14-bit right. */ +++#define R_PARISC_TLS_LDMCALL 239 /* LD module call to __t_g_a. */ +++#define R_PARISC_TLS_LDO21L 240 /* LD offset 21-bit left. */ +++#define R_PARISC_TLS_LDO14R 241 /* LD offset 14-bit right. */ +++#define R_PARISC_TLS_DTPMOD32 242 /* DTP module 32-bit. */ +++#define R_PARISC_TLS_DTPMOD64 243 /* DTP module 64-bit. */ +++#define R_PARISC_TLS_DTPOFF32 244 /* DTP offset 32-bit. */ +++#define R_PARISC_TLS_DTPOFF64 245 /* DTP offset 32-bit. */ +++#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L +++#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R +++#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L +++#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R +++#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32 +++#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64 +++#define R_PARISC_HIRESERVE 255 +++ +++/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */ +++ +++#define PT_HP_TLS (PT_LOOS + 0x0) +++#define PT_HP_CORE_NONE (PT_LOOS + 0x1) +++#define PT_HP_CORE_VERSION (PT_LOOS + 0x2) +++#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3) +++#define PT_HP_CORE_COMM (PT_LOOS + 0x4) +++#define PT_HP_CORE_PROC (PT_LOOS + 0x5) +++#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6) +++#define PT_HP_CORE_STACK (PT_LOOS + 0x7) +++#define PT_HP_CORE_SHM (PT_LOOS + 0x8) +++#define PT_HP_CORE_MMF (PT_LOOS + 0x9) +++#define PT_HP_PARALLEL (PT_LOOS + 0x10) +++#define PT_HP_FASTBIND (PT_LOOS + 0x11) +++#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12) +++#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13) +++#define PT_HP_STACK (PT_LOOS + 0x14) +++ +++#define PT_PARISC_ARCHEXT 0x70000000 +++#define PT_PARISC_UNWIND 0x70000001 +++ +++/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */ +++ +++#define PF_PARISC_SBP 0x08000000 +++ +++#define PF_HP_PAGE_SIZE 0x00100000 +++#define PF_HP_FAR_SHARED 0x00200000 +++#define PF_HP_NEAR_SHARED 0x00400000 +++#define PF_HP_CODE 0x01000000 +++#define PF_HP_MODIFY 0x02000000 +++#define PF_HP_LAZYSWAP 0x04000000 +++#define PF_HP_SBP 0x08000000 +++ +++ +++/* Alpha specific definitions. */ +++ +++/* Legal values for e_flags field of Elf64_Ehdr. */ +++ +++#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */ +++#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */ +++ +++/* Legal values for sh_type field of Elf64_Shdr. */ +++ +++/* These two are primerily concerned with ECOFF debugging info. */ +++#define SHT_ALPHA_DEBUG 0x70000001 +++#define SHT_ALPHA_REGINFO 0x70000002 +++ +++/* Legal values for sh_flags field of Elf64_Shdr. */ +++ +++#define SHF_ALPHA_GPREL 0x10000000 +++ +++/* Legal values for st_other field of Elf64_Sym. */ +++#define STO_ALPHA_NOPV 0x80 /* No PV required. */ +++#define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */ +++ +++/* Alpha relocs. */ +++ +++#define R_ALPHA_NONE 0 /* No reloc */ +++#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ +++#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ +++#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ +++#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ +++#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ +++#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ +++#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ +++#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ +++#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ +++#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ +++#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ +++#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */ +++#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */ +++#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */ +++#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ +++#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ +++#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ +++#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ +++#define R_ALPHA_TLS_GD_HI 28 +++#define R_ALPHA_TLSGD 29 +++#define R_ALPHA_TLS_LDM 30 +++#define R_ALPHA_DTPMOD64 31 +++#define R_ALPHA_GOTDTPREL 32 +++#define R_ALPHA_DTPREL64 33 +++#define R_ALPHA_DTPRELHI 34 +++#define R_ALPHA_DTPRELLO 35 +++#define R_ALPHA_DTPREL16 36 +++#define R_ALPHA_GOTTPREL 37 +++#define R_ALPHA_TPREL64 38 +++#define R_ALPHA_TPRELHI 39 +++#define R_ALPHA_TPRELLO 40 +++#define R_ALPHA_TPREL16 41 +++/* Keep this the last entry. */ +++#define R_ALPHA_NUM 46 +++ +++/* Magic values of the LITUSE relocation addend. */ +++#define LITUSE_ALPHA_ADDR 0 +++#define LITUSE_ALPHA_BASE 1 +++#define LITUSE_ALPHA_BYTOFF 2 +++#define LITUSE_ALPHA_JSR 3 +++#define LITUSE_ALPHA_TLS_GD 4 +++#define LITUSE_ALPHA_TLS_LDM 5 +++ +++/* Legal values for d_tag of Elf64_Dyn. */ +++#define DT_ALPHA_PLTRO (DT_LOPROC + 0) +++#define DT_ALPHA_NUM 1 +++ +++/* PowerPC specific declarations */ +++ +++/* Values for Elf32/64_Ehdr.e_flags. */ +++#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */ +++ +++/* Cygnus local bits below */ +++#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/ +++#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib +++ flag */ +++ +++/* PowerPC relocations defined by the ABIs */ +++#define R_PPC_NONE 0 +++#define R_PPC_ADDR32 1 /* 32bit absolute address */ +++#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ +++#define R_PPC_ADDR16 3 /* 16bit absolute address */ +++#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ +++#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ +++#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ +++#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ +++#define R_PPC_ADDR14_BRTAKEN 8 +++#define R_PPC_ADDR14_BRNTAKEN 9 +++#define R_PPC_REL24 10 /* PC relative 26 bit */ +++#define R_PPC_REL14 11 /* PC relative 16 bit */ +++#define R_PPC_REL14_BRTAKEN 12 +++#define R_PPC_REL14_BRNTAKEN 13 +++#define R_PPC_GOT16 14 +++#define R_PPC_GOT16_LO 15 +++#define R_PPC_GOT16_HI 16 +++#define R_PPC_GOT16_HA 17 +++#define R_PPC_PLTREL24 18 +++#define R_PPC_COPY 19 +++#define R_PPC_GLOB_DAT 20 +++#define R_PPC_JMP_SLOT 21 +++#define R_PPC_RELATIVE 22 +++#define R_PPC_LOCAL24PC 23 +++#define R_PPC_UADDR32 24 +++#define R_PPC_UADDR16 25 +++#define R_PPC_REL32 26 +++#define R_PPC_PLT32 27 +++#define R_PPC_PLTREL32 28 +++#define R_PPC_PLT16_LO 29 +++#define R_PPC_PLT16_HI 30 +++#define R_PPC_PLT16_HA 31 +++#define R_PPC_SDAREL16 32 +++#define R_PPC_SECTOFF 33 +++#define R_PPC_SECTOFF_LO 34 +++#define R_PPC_SECTOFF_HI 35 +++#define R_PPC_SECTOFF_HA 36 +++ +++/* PowerPC relocations defined for the TLS access ABI. */ +++#define R_PPC_TLS 67 /* none (sym+add)@tls */ +++#define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */ +++#define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */ +++#define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ +++#define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ +++#define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ +++#define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */ +++#define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */ +++#define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ +++#define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ +++#define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ +++#define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */ +++#define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ +++#define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ +++#define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ +++#define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ +++#define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ +++#define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ +++#define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ +++#define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ +++#define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */ +++#define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */ +++#define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ +++#define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ +++#define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */ +++#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */ +++#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */ +++#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */ +++ +++/* The remaining relocs are from the Embedded ELF ABI, and are not +++ in the SVR4 ELF ABI. */ +++#define R_PPC_EMB_NADDR32 101 +++#define R_PPC_EMB_NADDR16 102 +++#define R_PPC_EMB_NADDR16_LO 103 +++#define R_PPC_EMB_NADDR16_HI 104 +++#define R_PPC_EMB_NADDR16_HA 105 +++#define R_PPC_EMB_SDAI16 106 +++#define R_PPC_EMB_SDA2I16 107 +++#define R_PPC_EMB_SDA2REL 108 +++#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ +++#define R_PPC_EMB_MRKREF 110 +++#define R_PPC_EMB_RELSEC16 111 +++#define R_PPC_EMB_RELST_LO 112 +++#define R_PPC_EMB_RELST_HI 113 +++#define R_PPC_EMB_RELST_HA 114 +++#define R_PPC_EMB_BIT_FLD 115 +++#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ +++ +++/* Diab tool relocations. */ +++#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ +++#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ +++#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ +++#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ +++#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ +++#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ +++ +++/* GNU extension to support local ifunc. */ +++#define R_PPC_IRELATIVE 248 +++ +++/* GNU relocs used in PIC code sequences. */ +++#define R_PPC_REL16 249 /* half16 (sym+add-.) */ +++#define R_PPC_REL16_LO 250 /* half16 (sym+add-.)@l */ +++#define R_PPC_REL16_HI 251 /* half16 (sym+add-.)@h */ +++#define R_PPC_REL16_HA 252 /* half16 (sym+add-.)@ha */ +++ +++/* This is a phony reloc to handle any old fashioned TOC16 references +++ that may still be in object files. */ +++#define R_PPC_TOC16 255 +++ +++/* PowerPC specific values for the Dyn d_tag field. */ +++#define DT_PPC_GOT (DT_LOPROC + 0) +++#define DT_PPC_NUM 1 +++ +++/* PowerPC64 relocations defined by the ABIs */ +++#define R_PPC64_NONE R_PPC_NONE +++#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address */ +++#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned */ +++#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address */ +++#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of address */ +++#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of address. */ +++#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */ +++#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned */ +++#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN +++#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN +++#define R_PPC64_REL24 R_PPC_REL24 /* PC-rel. 26 bit, word aligned */ +++#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit */ +++#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN +++#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN +++#define R_PPC64_GOT16 R_PPC_GOT16 +++#define R_PPC64_GOT16_LO R_PPC_GOT16_LO +++#define R_PPC64_GOT16_HI R_PPC_GOT16_HI +++#define R_PPC64_GOT16_HA R_PPC_GOT16_HA +++ +++#define R_PPC64_COPY R_PPC_COPY +++#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT +++#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT +++#define R_PPC64_RELATIVE R_PPC_RELATIVE +++ +++#define R_PPC64_UADDR32 R_PPC_UADDR32 +++#define R_PPC64_UADDR16 R_PPC_UADDR16 +++#define R_PPC64_REL32 R_PPC_REL32 +++#define R_PPC64_PLT32 R_PPC_PLT32 +++#define R_PPC64_PLTREL32 R_PPC_PLTREL32 +++#define R_PPC64_PLT16_LO R_PPC_PLT16_LO +++#define R_PPC64_PLT16_HI R_PPC_PLT16_HI +++#define R_PPC64_PLT16_HA R_PPC_PLT16_HA +++ +++#define R_PPC64_SECTOFF R_PPC_SECTOFF +++#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO +++#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI +++#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA +++#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2 */ +++#define R_PPC64_ADDR64 38 /* doubleword64 S + A */ +++#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A) */ +++#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A) */ +++#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A) */ +++#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A) */ +++#define R_PPC64_UADDR64 43 /* doubleword64 S + A */ +++#define R_PPC64_REL64 44 /* doubleword64 S + A - P */ +++#define R_PPC64_PLT64 45 /* doubleword64 L + A */ +++#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P */ +++#define R_PPC64_TOC16 47 /* half16* S + A - .TOC */ +++#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.) */ +++#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.) */ +++#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.) */ +++#define R_PPC64_TOC 51 /* doubleword64 .TOC */ +++#define R_PPC64_PLTGOT16 52 /* half16* M + A */ +++#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A) */ +++#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A) */ +++#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A) */ +++ +++#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2 */ +++#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2 */ +++#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2 */ +++#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2 */ +++#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2 */ +++#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2 */ +++#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2 */ +++#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2 */ +++#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2 */ +++#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2 */ +++#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2 */ +++ +++/* PowerPC64 relocations defined for the TLS access ABI. */ +++#define R_PPC64_TLS 67 /* none (sym+add)@tls */ +++#define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */ +++#define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */ +++#define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ +++#define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ +++#define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ +++#define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */ +++#define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */ +++#define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ +++#define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ +++#define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ +++#define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */ +++#define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ +++#define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ +++#define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ +++#define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ +++#define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ +++#define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ +++#define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ +++#define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ +++#define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */ +++#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */ +++#define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ +++#define R_PPC64_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ +++#define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */ +++#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */ +++#define R_PPC64_GOT_DTPREL16_HI 93 /* half16 (sym+add)@got@dtprel@h */ +++#define R_PPC64_GOT_DTPREL16_HA 94 /* half16 (sym+add)@got@dtprel@ha */ +++#define R_PPC64_TPREL16_DS 95 /* half16ds* (sym+add)@tprel */ +++#define R_PPC64_TPREL16_LO_DS 96 /* half16ds (sym+add)@tprel@l */ +++#define R_PPC64_TPREL16_HIGHER 97 /* half16 (sym+add)@tprel@higher */ +++#define R_PPC64_TPREL16_HIGHERA 98 /* half16 (sym+add)@tprel@highera */ +++#define R_PPC64_TPREL16_HIGHEST 99 /* half16 (sym+add)@tprel@highest */ +++#define R_PPC64_TPREL16_HIGHESTA 100 /* half16 (sym+add)@tprel@highesta */ +++#define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */ +++#define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */ +++#define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@higher */ +++#define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */ +++#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */ +++#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */ +++ +++/* GNU extension to support local ifunc. */ +++#define R_PPC64_JMP_IREL 247 +++#define R_PPC64_IRELATIVE 248 +++#define R_PPC64_REL16 249 /* half16 (sym+add-.) */ +++#define R_PPC64_REL16_LO 250 /* half16 (sym+add-.)@l */ +++#define R_PPC64_REL16_HI 251 /* half16 (sym+add-.)@h */ +++#define R_PPC64_REL16_HA 252 /* half16 (sym+add-.)@ha */ +++ +++/* PowerPC64 specific values for the Dyn d_tag field. */ +++#define DT_PPC64_GLINK (DT_LOPROC + 0) +++#define DT_PPC64_OPD (DT_LOPROC + 1) +++#define DT_PPC64_OPDSZ (DT_LOPROC + 2) +++#define DT_PPC64_NUM 3 +++ +++ +++/* ARM specific declarations */ +++ +++/* Processor specific flags for the ELF header e_flags field. */ +++#define EF_ARM_RELEXEC 0x01 +++#define EF_ARM_HASENTRY 0x02 +++#define EF_ARM_INTERWORK 0x04 +++#define EF_ARM_APCS_26 0x08 +++#define EF_ARM_APCS_FLOAT 0x10 +++#define EF_ARM_PIC 0x20 +++#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */ +++#define EF_ARM_NEW_ABI 0x80 +++#define EF_ARM_OLD_ABI 0x100 +++#define EF_ARM_SOFT_FLOAT 0x200 +++#define EF_ARM_VFP_FLOAT 0x400 +++#define EF_ARM_MAVERICK_FLOAT 0x800 +++ +++ +++/* Other constants defined in the ARM ELF spec. version B-01. */ +++/* NB. These conflict with values defined above. */ +++#define EF_ARM_SYMSARESORTED 0x04 +++#define EF_ARM_DYNSYMSUSESEGIDX 0x08 +++#define EF_ARM_MAPSYMSFIRST 0x10 +++#define EF_ARM_EABIMASK 0XFF000000 +++ +++/* Constants defined in AAELF. */ +++#define EF_ARM_BE8 0x00800000 +++#define EF_ARM_LE8 0x00400000 +++ +++#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK) +++#define EF_ARM_EABI_UNKNOWN 0x00000000 +++#define EF_ARM_EABI_VER1 0x01000000 +++#define EF_ARM_EABI_VER2 0x02000000 +++#define EF_ARM_EABI_VER3 0x03000000 +++#define EF_ARM_EABI_VER4 0x04000000 +++#define EF_ARM_EABI_VER5 0x05000000 +++ +++/* Additional symbol types for Thumb. */ +++#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */ +++#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */ +++ +++/* ARM-specific values for sh_flags */ +++#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */ +++#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined +++ in the input to a link step. */ +++ +++/* ARM-specific program header flags */ +++#define PF_ARM_SB 0x10000000 /* Segment contains the location +++ addressed by the static base. */ +++#define PF_ARM_PI 0x20000000 /* Position-independent segment. */ +++#define PF_ARM_ABS 0x40000000 /* Absolute segment. */ +++ +++/* Processor specific values for the Phdr p_type field. */ +++#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */ +++ +++/* Processor specific values for the Shdr sh_type field. */ +++#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section. */ +++#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details. */ +++#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */ +++ +++ +++/* ARM relocs. */ +++ +++#define R_ARM_NONE 0 /* No reloc */ +++#define R_ARM_PC24 1 /* PC relative 26 bit branch */ +++#define R_ARM_ABS32 2 /* Direct 32 bit */ +++#define R_ARM_REL32 3 /* PC relative 32 bit */ +++#define R_ARM_PC13 4 +++#define R_ARM_ABS16 5 /* Direct 16 bit */ +++#define R_ARM_ABS12 6 /* Direct 12 bit */ +++#define R_ARM_THM_ABS5 7 +++#define R_ARM_ABS8 8 /* Direct 8 bit */ +++#define R_ARM_SBREL32 9 +++#define R_ARM_THM_PC22 10 +++#define R_ARM_THM_PC8 11 +++#define R_ARM_AMP_VCALL9 12 +++#define R_ARM_SWI24 13 /* Obsolete static relocation. */ +++#define R_ARM_TLS_DESC 13 /* Dynamic relocation. */ +++#define R_ARM_THM_SWI8 14 +++#define R_ARM_XPC25 15 +++#define R_ARM_THM_XPC22 16 +++#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */ +++#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */ +++#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */ +++#define R_ARM_COPY 20 /* Copy symbol at runtime */ +++#define R_ARM_GLOB_DAT 21 /* Create GOT entry */ +++#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ +++#define R_ARM_RELATIVE 23 /* Adjust by program base */ +++#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */ +++#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */ +++#define R_ARM_GOT32 26 /* 32 bit GOT entry */ +++#define R_ARM_PLT32 27 /* 32 bit PLT address */ +++#define R_ARM_ALU_PCREL_7_0 32 +++#define R_ARM_ALU_PCREL_15_8 33 +++#define R_ARM_ALU_PCREL_23_15 34 +++#define R_ARM_LDR_SBREL_11_0 35 +++#define R_ARM_ALU_SBREL_19_12 36 +++#define R_ARM_ALU_SBREL_27_20 37 +++#define R_ARM_TLS_GOTDESC 90 +++#define R_ARM_TLS_CALL 91 +++#define R_ARM_TLS_DESCSEQ 92 +++#define R_ARM_THM_TLS_CALL 93 +++#define R_ARM_GNU_VTENTRY 100 +++#define R_ARM_GNU_VTINHERIT 101 +++#define R_ARM_THM_PC11 102 /* thumb unconditional branch */ +++#define R_ARM_THM_PC9 103 /* thumb conditional branch */ +++#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic +++ thread local data */ +++#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic +++ thread local data */ +++#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS +++ block */ +++#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of +++ static TLS block offset */ +++#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static +++ TLS block */ +++#define R_ARM_THM_TLS_DESCSEQ 129 +++#define R_ARM_IRELATIVE 160 +++#define R_ARM_RXPC25 249 +++#define R_ARM_RSBREL32 250 +++#define R_ARM_THM_RPC22 251 +++#define R_ARM_RREL32 252 +++#define R_ARM_RABS22 253 +++#define R_ARM_RPC24 254 +++#define R_ARM_RBASE 255 +++/* Keep this the last entry. */ +++#define R_ARM_NUM 256 +++ +++/* IA-64 specific declarations. */ +++ +++/* Processor specific flags for the Ehdr e_flags field. */ +++#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */ +++#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */ +++#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */ +++ +++/* Processor specific values for the Phdr p_type field. */ +++#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */ +++#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */ +++#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12) +++#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13) +++#define PT_IA_64_HP_STACK (PT_LOOS + 0x14) +++ +++/* Processor specific flags for the Phdr p_flags field. */ +++#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */ +++ +++/* Processor specific values for the Shdr sh_type field. */ +++#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */ +++#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */ +++ +++/* Processor specific flags for the Shdr sh_flags field. */ +++#define SHF_IA_64_SHORT 0x10000000 /* section near gp */ +++#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */ +++ +++/* Processor specific values for the Dyn d_tag field. */ +++#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0) +++#define DT_IA_64_NUM 1 +++ +++/* IA-64 relocations. */ +++#define R_IA64_NONE 0x00 /* none */ +++#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */ +++#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */ +++#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */ +++#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */ +++#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */ +++#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */ +++#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */ +++#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */ +++#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */ +++#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym + add), data4 MSB */ +++#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym + add), data4 LSB */ +++#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */ +++#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */ +++#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */ +++#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */ +++#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */ +++#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */ +++#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */ +++#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */ +++#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */ +++#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */ +++#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */ +++#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */ +++#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */ +++#define R_IA64_PCREL60B 0x48 /* @pcrel(sym + add), brl */ +++#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */ +++#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */ +++#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */ +++#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */ +++#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */ +++#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */ +++#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */ +++#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */ +++#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */ +++#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), data4 MSB */ +++#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), data4 LSB */ +++#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), data8 MSB */ +++#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), data8 LSB */ +++#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */ +++#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */ +++#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */ +++#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */ +++#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */ +++#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */ +++#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */ +++#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */ +++#define R_IA64_REL32MSB 0x6c /* data 4 + REL */ +++#define R_IA64_REL32LSB 0x6d /* data 4 + REL */ +++#define R_IA64_REL64MSB 0x6e /* data 8 + REL */ +++#define R_IA64_REL64LSB 0x6f /* data 8 + REL */ +++#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */ +++#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */ +++#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */ +++#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */ +++#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym + add), 21bit inst */ +++#define R_IA64_PCREL22 0x7a /* @pcrel(sym + add), 22bit inst */ +++#define R_IA64_PCREL64I 0x7b /* @pcrel(sym + add), 64bit inst */ +++#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */ +++#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */ +++#define R_IA64_COPY 0x84 /* copy relocation */ +++#define R_IA64_SUB 0x85 /* Addend and symbol difference */ +++#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */ +++#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */ +++#define R_IA64_TPREL14 0x91 /* @tprel(sym + add), imm14 */ +++#define R_IA64_TPREL22 0x92 /* @tprel(sym + add), imm22 */ +++#define R_IA64_TPREL64I 0x93 /* @tprel(sym + add), imm64 */ +++#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym + add), data8 MSB */ +++#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym + add), data8 LSB */ +++#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), imm2 */ +++#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym + add), data8 MSB */ +++#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym + add), data8 LSB */ +++#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(sym + add)), imm22 */ +++#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym + add), imm14 */ +++#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym + add), imm22 */ +++#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym + add), imm64 */ +++#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym + add), data4 MSB */ +++#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym + add), data4 LSB */ +++#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym + add), data8 MSB */ +++#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */ +++#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */ +++ +++/* SH specific declarations */ +++ +++/* Processor specific flags for the ELF header e_flags field. */ +++#define EF_SH_MACH_MASK 0x1f +++#define EF_SH_UNKNOWN 0x0 +++#define EF_SH1 0x1 +++#define EF_SH2 0x2 +++#define EF_SH3 0x3 +++#define EF_SH_DSP 0x4 +++#define EF_SH3_DSP 0x5 +++#define EF_SH4AL_DSP 0x6 +++#define EF_SH3E 0x8 +++#define EF_SH4 0x9 +++#define EF_SH2E 0xb +++#define EF_SH4A 0xc +++#define EF_SH2A 0xd +++#define EF_SH4_NOFPU 0x10 +++#define EF_SH4A_NOFPU 0x11 +++#define EF_SH4_NOMMU_NOFPU 0x12 +++#define EF_SH2A_NOFPU 0x13 +++#define EF_SH3_NOMMU 0x14 +++#define EF_SH2A_SH4_NOFPU 0x15 +++#define EF_SH2A_SH3_NOFPU 0x16 +++#define EF_SH2A_SH4 0x17 +++#define EF_SH2A_SH3E 0x18 +++ +++/* SH relocs. */ +++#define R_SH_NONE 0 +++#define R_SH_DIR32 1 +++#define R_SH_REL32 2 +++#define R_SH_DIR8WPN 3 +++#define R_SH_IND12W 4 +++#define R_SH_DIR8WPL 5 +++#define R_SH_DIR8WPZ 6 +++#define R_SH_DIR8BP 7 +++#define R_SH_DIR8W 8 +++#define R_SH_DIR8L 9 +++#define R_SH_SWITCH16 25 +++#define R_SH_SWITCH32 26 +++#define R_SH_USES 27 +++#define R_SH_COUNT 28 +++#define R_SH_ALIGN 29 +++#define R_SH_CODE 30 +++#define R_SH_DATA 31 +++#define R_SH_LABEL 32 +++#define R_SH_SWITCH8 33 +++#define R_SH_GNU_VTINHERIT 34 +++#define R_SH_GNU_VTENTRY 35 +++#define R_SH_TLS_GD_32 144 +++#define R_SH_TLS_LD_32 145 +++#define R_SH_TLS_LDO_32 146 +++#define R_SH_TLS_IE_32 147 +++#define R_SH_TLS_LE_32 148 +++#define R_SH_TLS_DTPMOD32 149 +++#define R_SH_TLS_DTPOFF32 150 +++#define R_SH_TLS_TPOFF32 151 +++#define R_SH_GOT32 160 +++#define R_SH_PLT32 161 +++#define R_SH_COPY 162 +++#define R_SH_GLOB_DAT 163 +++#define R_SH_JMP_SLOT 164 +++#define R_SH_RELATIVE 165 +++#define R_SH_GOTOFF 166 +++#define R_SH_GOTPC 167 +++/* Keep this the last entry. */ +++#define R_SH_NUM 256 +++ +++/* S/390 specific definitions. */ +++ +++/* Valid values for the e_flags field. */ +++ +++#define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. */ +++ +++/* Additional s390 relocs */ +++ +++#define R_390_NONE 0 /* No reloc. */ +++#define R_390_8 1 /* Direct 8 bit. */ +++#define R_390_12 2 /* Direct 12 bit. */ +++#define R_390_16 3 /* Direct 16 bit. */ +++#define R_390_32 4 /* Direct 32 bit. */ +++#define R_390_PC32 5 /* PC relative 32 bit. */ +++#define R_390_GOT12 6 /* 12 bit GOT offset. */ +++#define R_390_GOT32 7 /* 32 bit GOT offset. */ +++#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */ +++#define R_390_COPY 9 /* Copy symbol at runtime. */ +++#define R_390_GLOB_DAT 10 /* Create GOT entry. */ +++#define R_390_JMP_SLOT 11 /* Create PLT entry. */ +++#define R_390_RELATIVE 12 /* Adjust by program base. */ +++#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */ +++#define R_390_GOTPC 14 /* 32 bit PC relative offset to GOT. */ +++#define R_390_GOT16 15 /* 16 bit GOT offset. */ +++#define R_390_PC16 16 /* PC relative 16 bit. */ +++#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */ +++#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */ +++#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */ +++#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */ +++#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */ +++#define R_390_64 22 /* Direct 64 bit. */ +++#define R_390_PC64 23 /* PC relative 64 bit. */ +++#define R_390_GOT64 24 /* 64 bit GOT offset. */ +++#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */ +++#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */ +++#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */ +++#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */ +++#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */ +++#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */ +++#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */ +++#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */ +++#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */ +++#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */ +++#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */ +++#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */ +++#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */ +++#define R_390_TLS_GDCALL 38 /* Tag for function call in general +++ dynamic TLS code. */ +++#define R_390_TLS_LDCALL 39 /* Tag for function call in local +++ dynamic TLS code. */ +++#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic +++ thread local data. */ +++#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic +++ thread local data. */ +++#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS +++ block offset. */ +++#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS +++ block offset. */ +++#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS +++ block offset. */ +++#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic +++ thread local data in LE code. */ +++#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic +++ thread local data in LE code. */ +++#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for +++ negated static TLS block offset. */ +++#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for +++ negated static TLS block offset. */ +++#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for +++ negated static TLS block offset. */ +++#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to +++ static TLS block. */ +++#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to +++ static TLS block. */ +++#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS +++ block. */ +++#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS +++ block. */ +++#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */ +++#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */ +++#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS +++ block. */ +++#define R_390_20 57 /* Direct 20 bit. */ +++#define R_390_GOT20 58 /* 20 bit GOT offset. */ +++#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */ +++#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS +++ block offset. */ +++#define R_390_IRELATIVE 61 /* STT_GNU_IFUNC relocation. */ +++/* Keep this the last entry. */ +++#define R_390_NUM 62 +++ +++ +++/* CRIS relocations. */ +++#define R_CRIS_NONE 0 +++#define R_CRIS_8 1 +++#define R_CRIS_16 2 +++#define R_CRIS_32 3 +++#define R_CRIS_8_PCREL 4 +++#define R_CRIS_16_PCREL 5 +++#define R_CRIS_32_PCREL 6 +++#define R_CRIS_GNU_VTINHERIT 7 +++#define R_CRIS_GNU_VTENTRY 8 +++#define R_CRIS_COPY 9 +++#define R_CRIS_GLOB_DAT 10 +++#define R_CRIS_JUMP_SLOT 11 +++#define R_CRIS_RELATIVE 12 +++#define R_CRIS_16_GOT 13 +++#define R_CRIS_32_GOT 14 +++#define R_CRIS_16_GOTPLT 15 +++#define R_CRIS_32_GOTPLT 16 +++#define R_CRIS_32_GOTREL 17 +++#define R_CRIS_32_PLT_GOTREL 18 +++#define R_CRIS_32_PLT_PCREL 19 +++ +++#define R_CRIS_NUM 20 +++ +++ +++/* AMD x86-64 relocations. */ +++#define R_X86_64_NONE 0 /* No reloc */ +++#define R_X86_64_64 1 /* Direct 64 bit */ +++#define R_X86_64_PC32 2 /* PC relative 32 bit signed */ +++#define R_X86_64_GOT32 3 /* 32 bit GOT entry */ +++#define R_X86_64_PLT32 4 /* 32 bit PLT address */ +++#define R_X86_64_COPY 5 /* Copy symbol at runtime */ +++#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ +++#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ +++#define R_X86_64_RELATIVE 8 /* Adjust by program base */ +++#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative +++ offset to GOT */ +++#define R_X86_64_32 10 /* Direct 32 bit zero extended */ +++#define R_X86_64_32S 11 /* Direct 32 bit sign extended */ +++#define R_X86_64_16 12 /* Direct 16 bit zero extended */ +++#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ +++#define R_X86_64_8 14 /* Direct 8 bit sign extended */ +++#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ +++#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ +++#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */ +++#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */ +++#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset +++ to two GOT entries for GD symbol */ +++#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset +++ to two GOT entries for LD symbol */ +++#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ +++#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset +++ to GOT entry for IE symbol */ +++#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */ +++#define R_X86_64_PC64 24 /* PC relative 64 bit */ +++#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */ +++#define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative +++ offset to GOT */ +++#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */ +++#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset +++ to GOT entry */ +++#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */ +++#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */ +++#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset +++ to PLT entry */ +++#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */ +++#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */ +++#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */ +++#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS +++ descriptor. */ +++#define R_X86_64_TLSDESC 36 /* TLS descriptor. */ +++#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */ +++#define R_X86_64_RELATIVE64 38 /* 64-bit adjust by program base */ +++ +++#define R_X86_64_NUM 39 +++ +++ +++/* AM33 relocations. */ +++#define R_MN10300_NONE 0 /* No reloc. */ +++#define R_MN10300_32 1 /* Direct 32 bit. */ +++#define R_MN10300_16 2 /* Direct 16 bit. */ +++#define R_MN10300_8 3 /* Direct 8 bit. */ +++#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */ +++#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */ +++#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */ +++#define R_MN10300_GNU_VTINHERIT 7 /* Ancient C++ vtable garbage... */ +++#define R_MN10300_GNU_VTENTRY 8 /* ... collection annotation. */ +++#define R_MN10300_24 9 /* Direct 24 bit. */ +++#define R_MN10300_GOTPC32 10 /* 32-bit PCrel offset to GOT. */ +++#define R_MN10300_GOTPC16 11 /* 16-bit PCrel offset to GOT. */ +++#define R_MN10300_GOTOFF32 12 /* 32-bit offset from GOT. */ +++#define R_MN10300_GOTOFF24 13 /* 24-bit offset from GOT. */ +++#define R_MN10300_GOTOFF16 14 /* 16-bit offset from GOT. */ +++#define R_MN10300_PLT32 15 /* 32-bit PCrel to PLT entry. */ +++#define R_MN10300_PLT16 16 /* 16-bit PCrel to PLT entry. */ +++#define R_MN10300_GOT32 17 /* 32-bit offset to GOT entry. */ +++#define R_MN10300_GOT24 18 /* 24-bit offset to GOT entry. */ +++#define R_MN10300_GOT16 19 /* 16-bit offset to GOT entry. */ +++#define R_MN10300_COPY 20 /* Copy symbol at runtime. */ +++#define R_MN10300_GLOB_DAT 21 /* Create GOT entry. */ +++#define R_MN10300_JMP_SLOT 22 /* Create PLT entry. */ +++#define R_MN10300_RELATIVE 23 /* Adjust by program base. */ +++ +++#define R_MN10300_NUM 24 +++ +++ +++/* M32R relocs. */ +++#define R_M32R_NONE 0 /* No reloc. */ +++#define R_M32R_16 1 /* Direct 16 bit. */ +++#define R_M32R_32 2 /* Direct 32 bit. */ +++#define R_M32R_24 3 /* Direct 24 bit. */ +++#define R_M32R_10_PCREL 4 /* PC relative 10 bit shifted. */ +++#define R_M32R_18_PCREL 5 /* PC relative 18 bit shifted. */ +++#define R_M32R_26_PCREL 6 /* PC relative 26 bit shifted. */ +++#define R_M32R_HI16_ULO 7 /* High 16 bit with unsigned low. */ +++#define R_M32R_HI16_SLO 8 /* High 16 bit with signed low. */ +++#define R_M32R_LO16 9 /* Low 16 bit. */ +++#define R_M32R_SDA16 10 /* 16 bit offset in SDA. */ +++#define R_M32R_GNU_VTINHERIT 11 +++#define R_M32R_GNU_VTENTRY 12 +++/* M32R relocs use SHT_RELA. */ +++#define R_M32R_16_RELA 33 /* Direct 16 bit. */ +++#define R_M32R_32_RELA 34 /* Direct 32 bit. */ +++#define R_M32R_24_RELA 35 /* Direct 24 bit. */ +++#define R_M32R_10_PCREL_RELA 36 /* PC relative 10 bit shifted. */ +++#define R_M32R_18_PCREL_RELA 37 /* PC relative 18 bit shifted. */ +++#define R_M32R_26_PCREL_RELA 38 /* PC relative 26 bit shifted. */ +++#define R_M32R_HI16_ULO_RELA 39 /* High 16 bit with unsigned low */ +++#define R_M32R_HI16_SLO_RELA 40 /* High 16 bit with signed low */ +++#define R_M32R_LO16_RELA 41 /* Low 16 bit */ +++#define R_M32R_SDA16_RELA 42 /* 16 bit offset in SDA */ +++#define R_M32R_RELA_GNU_VTINHERIT 43 +++#define R_M32R_RELA_GNU_VTENTRY 44 +++#define R_M32R_REL32 45 /* PC relative 32 bit. */ +++ +++#define R_M32R_GOT24 48 /* 24 bit GOT entry */ +++#define R_M32R_26_PLTREL 49 /* 26 bit PC relative to PLT shifted */ +++#define R_M32R_COPY 50 /* Copy symbol at runtime */ +++#define R_M32R_GLOB_DAT 51 /* Create GOT entry */ +++#define R_M32R_JMP_SLOT 52 /* Create PLT entry */ +++#define R_M32R_RELATIVE 53 /* Adjust by program base */ +++#define R_M32R_GOTOFF 54 /* 24 bit offset to GOT */ +++#define R_M32R_GOTPC24 55 /* 24 bit PC relative offset to GOT */ +++#define R_M32R_GOT16_HI_ULO 56 /* High 16 bit GOT entry with unsigned +++ low */ +++#define R_M32R_GOT16_HI_SLO 57 /* High 16 bit GOT entry with signed +++ low */ +++#define R_M32R_GOT16_LO 58 /* Low 16 bit GOT entry */ +++#define R_M32R_GOTPC_HI_ULO 59 /* High 16 bit PC relative offset to +++ GOT with unsigned low */ +++#define R_M32R_GOTPC_HI_SLO 60 /* High 16 bit PC relative offset to +++ GOT with signed low */ +++#define R_M32R_GOTPC_LO 61 /* Low 16 bit PC relative offset to +++ GOT */ +++#define R_M32R_GOTOFF_HI_ULO 62 /* High 16 bit offset to GOT +++ with unsigned low */ +++#define R_M32R_GOTOFF_HI_SLO 63 /* High 16 bit offset to GOT +++ with signed low */ +++#define R_M32R_GOTOFF_LO 64 /* Low 16 bit offset to GOT */ +++#define R_M32R_NUM 256 /* Keep this the last entry. */ +++ +++ +++/* TILEPro relocations. */ +++#define R_TILEPRO_NONE 0 /* No reloc */ +++#define R_TILEPRO_32 1 /* Direct 32 bit */ +++#define R_TILEPRO_16 2 /* Direct 16 bit */ +++#define R_TILEPRO_8 3 /* Direct 8 bit */ +++#define R_TILEPRO_32_PCREL 4 /* PC relative 32 bit */ +++#define R_TILEPRO_16_PCREL 5 /* PC relative 16 bit */ +++#define R_TILEPRO_8_PCREL 6 /* PC relative 8 bit */ +++#define R_TILEPRO_LO16 7 /* Low 16 bit */ +++#define R_TILEPRO_HI16 8 /* High 16 bit */ +++#define R_TILEPRO_HA16 9 /* High 16 bit, adjusted */ +++#define R_TILEPRO_COPY 10 /* Copy relocation */ +++#define R_TILEPRO_GLOB_DAT 11 /* Create GOT entry */ +++#define R_TILEPRO_JMP_SLOT 12 /* Create PLT entry */ +++#define R_TILEPRO_RELATIVE 13 /* Adjust by program base */ +++#define R_TILEPRO_BROFF_X1 14 /* X1 pipe branch offset */ +++#define R_TILEPRO_JOFFLONG_X1 15 /* X1 pipe jump offset */ +++#define R_TILEPRO_JOFFLONG_X1_PLT 16 /* X1 pipe jump offset to PLT */ +++#define R_TILEPRO_IMM8_X0 17 /* X0 pipe 8-bit */ +++#define R_TILEPRO_IMM8_Y0 18 /* Y0 pipe 8-bit */ +++#define R_TILEPRO_IMM8_X1 19 /* X1 pipe 8-bit */ +++#define R_TILEPRO_IMM8_Y1 20 /* Y1 pipe 8-bit */ +++#define R_TILEPRO_MT_IMM15_X1 21 /* X1 pipe mtspr */ +++#define R_TILEPRO_MF_IMM15_X1 22 /* X1 pipe mfspr */ +++#define R_TILEPRO_IMM16_X0 23 /* X0 pipe 16-bit */ +++#define R_TILEPRO_IMM16_X1 24 /* X1 pipe 16-bit */ +++#define R_TILEPRO_IMM16_X0_LO 25 /* X0 pipe low 16-bit */ +++#define R_TILEPRO_IMM16_X1_LO 26 /* X1 pipe low 16-bit */ +++#define R_TILEPRO_IMM16_X0_HI 27 /* X0 pipe high 16-bit */ +++#define R_TILEPRO_IMM16_X1_HI 28 /* X1 pipe high 16-bit */ +++#define R_TILEPRO_IMM16_X0_HA 29 /* X0 pipe high 16-bit, adjusted */ +++#define R_TILEPRO_IMM16_X1_HA 30 /* X1 pipe high 16-bit, adjusted */ +++#define R_TILEPRO_IMM16_X0_PCREL 31 /* X0 pipe PC relative 16 bit */ +++#define R_TILEPRO_IMM16_X1_PCREL 32 /* X1 pipe PC relative 16 bit */ +++#define R_TILEPRO_IMM16_X0_LO_PCREL 33 /* X0 pipe PC relative low 16 bit */ +++#define R_TILEPRO_IMM16_X1_LO_PCREL 34 /* X1 pipe PC relative low 16 bit */ +++#define R_TILEPRO_IMM16_X0_HI_PCREL 35 /* X0 pipe PC relative high 16 bit */ +++#define R_TILEPRO_IMM16_X1_HI_PCREL 36 /* X1 pipe PC relative high 16 bit */ +++#define R_TILEPRO_IMM16_X0_HA_PCREL 37 /* X0 pipe PC relative ha() 16 bit */ +++#define R_TILEPRO_IMM16_X1_HA_PCREL 38 /* X1 pipe PC relative ha() 16 bit */ +++#define R_TILEPRO_IMM16_X0_GOT 39 /* X0 pipe 16-bit GOT offset */ +++#define R_TILEPRO_IMM16_X1_GOT 40 /* X1 pipe 16-bit GOT offset */ +++#define R_TILEPRO_IMM16_X0_GOT_LO 41 /* X0 pipe low 16-bit GOT offset */ +++#define R_TILEPRO_IMM16_X1_GOT_LO 42 /* X1 pipe low 16-bit GOT offset */ +++#define R_TILEPRO_IMM16_X0_GOT_HI 43 /* X0 pipe high 16-bit GOT offset */ +++#define R_TILEPRO_IMM16_X1_GOT_HI 44 /* X1 pipe high 16-bit GOT offset */ +++#define R_TILEPRO_IMM16_X0_GOT_HA 45 /* X0 pipe ha() 16-bit GOT offset */ +++#define R_TILEPRO_IMM16_X1_GOT_HA 46 /* X1 pipe ha() 16-bit GOT offset */ +++#define R_TILEPRO_MMSTART_X0 47 /* X0 pipe mm "start" */ +++#define R_TILEPRO_MMEND_X0 48 /* X0 pipe mm "end" */ +++#define R_TILEPRO_MMSTART_X1 49 /* X1 pipe mm "start" */ +++#define R_TILEPRO_MMEND_X1 50 /* X1 pipe mm "end" */ +++#define R_TILEPRO_SHAMT_X0 51 /* X0 pipe shift amount */ +++#define R_TILEPRO_SHAMT_X1 52 /* X1 pipe shift amount */ +++#define R_TILEPRO_SHAMT_Y0 53 /* Y0 pipe shift amount */ +++#define R_TILEPRO_SHAMT_Y1 54 /* Y1 pipe shift amount */ +++#define R_TILEPRO_DEST_IMM8_X1 55 /* X1 pipe destination 8-bit */ +++/* Relocs 56-59 are currently not defined. */ +++#define R_TILEPRO_TLS_GD_CALL 60 /* "jal" for TLS GD */ +++#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61 /* X0 pipe "addi" for TLS GD */ +++#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62 /* X1 pipe "addi" for TLS GD */ +++#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63 /* Y0 pipe "addi" for TLS GD */ +++#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64 /* Y1 pipe "addi" for TLS GD */ +++#define R_TILEPRO_TLS_IE_LOAD 65 /* "lw_tls" for TLS IE */ +++#define R_TILEPRO_IMM16_X0_TLS_GD 66 /* X0 pipe 16-bit TLS GD offset */ +++#define R_TILEPRO_IMM16_X1_TLS_GD 67 /* X1 pipe 16-bit TLS GD offset */ +++#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68 /* X0 pipe low 16-bit TLS GD offset */ +++#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69 /* X1 pipe low 16-bit TLS GD offset */ +++#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70 /* X0 pipe high 16-bit TLS GD offset */ +++#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71 /* X1 pipe high 16-bit TLS GD offset */ +++#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72 /* X0 pipe ha() 16-bit TLS GD offset */ +++#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73 /* X1 pipe ha() 16-bit TLS GD offset */ +++#define R_TILEPRO_IMM16_X0_TLS_IE 74 /* X0 pipe 16-bit TLS IE offset */ +++#define R_TILEPRO_IMM16_X1_TLS_IE 75 /* X1 pipe 16-bit TLS IE offset */ +++#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76 /* X0 pipe low 16-bit TLS IE offset */ +++#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77 /* X1 pipe low 16-bit TLS IE offset */ +++#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78 /* X0 pipe high 16-bit TLS IE offset */ +++#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79 /* X1 pipe high 16-bit TLS IE offset */ +++#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80 /* X0 pipe ha() 16-bit TLS IE offset */ +++#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81 /* X1 pipe ha() 16-bit TLS IE offset */ +++#define R_TILEPRO_TLS_DTPMOD32 82 /* ID of module containing symbol */ +++#define R_TILEPRO_TLS_DTPOFF32 83 /* Offset in TLS block */ +++#define R_TILEPRO_TLS_TPOFF32 84 /* Offset in static TLS block */ +++#define R_TILEPRO_IMM16_X0_TLS_LE 85 /* X0 pipe 16-bit TLS LE offset */ +++#define R_TILEPRO_IMM16_X1_TLS_LE 86 /* X1 pipe 16-bit TLS LE offset */ +++#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87 /* X0 pipe low 16-bit TLS LE offset */ +++#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88 /* X1 pipe low 16-bit TLS LE offset */ +++#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89 /* X0 pipe high 16-bit TLS LE offset */ +++#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90 /* X1 pipe high 16-bit TLS LE offset */ +++#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91 /* X0 pipe ha() 16-bit TLS LE offset */ +++#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92 /* X1 pipe ha() 16-bit TLS LE offset */ +++ +++#define R_TILEPRO_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ +++#define R_TILEPRO_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ +++ +++#define R_TILEPRO_NUM 130 +++ +++ +++/* TILE-Gx relocations. */ +++#define R_TILEGX_NONE 0 /* No reloc */ +++#define R_TILEGX_64 1 /* Direct 64 bit */ +++#define R_TILEGX_32 2 /* Direct 32 bit */ +++#define R_TILEGX_16 3 /* Direct 16 bit */ +++#define R_TILEGX_8 4 /* Direct 8 bit */ +++#define R_TILEGX_64_PCREL 5 /* PC relative 64 bit */ +++#define R_TILEGX_32_PCREL 6 /* PC relative 32 bit */ +++#define R_TILEGX_16_PCREL 7 /* PC relative 16 bit */ +++#define R_TILEGX_8_PCREL 8 /* PC relative 8 bit */ +++#define R_TILEGX_HW0 9 /* hword 0 16-bit */ +++#define R_TILEGX_HW1 10 /* hword 1 16-bit */ +++#define R_TILEGX_HW2 11 /* hword 2 16-bit */ +++#define R_TILEGX_HW3 12 /* hword 3 16-bit */ +++#define R_TILEGX_HW0_LAST 13 /* last hword 0 16-bit */ +++#define R_TILEGX_HW1_LAST 14 /* last hword 1 16-bit */ +++#define R_TILEGX_HW2_LAST 15 /* last hword 2 16-bit */ +++#define R_TILEGX_COPY 16 /* Copy relocation */ +++#define R_TILEGX_GLOB_DAT 17 /* Create GOT entry */ +++#define R_TILEGX_JMP_SLOT 18 /* Create PLT entry */ +++#define R_TILEGX_RELATIVE 19 /* Adjust by program base */ +++#define R_TILEGX_BROFF_X1 20 /* X1 pipe branch offset */ +++#define R_TILEGX_JUMPOFF_X1 21 /* X1 pipe jump offset */ +++#define R_TILEGX_JUMPOFF_X1_PLT 22 /* X1 pipe jump offset to PLT */ +++#define R_TILEGX_IMM8_X0 23 /* X0 pipe 8-bit */ +++#define R_TILEGX_IMM8_Y0 24 /* Y0 pipe 8-bit */ +++#define R_TILEGX_IMM8_X1 25 /* X1 pipe 8-bit */ +++#define R_TILEGX_IMM8_Y1 26 /* Y1 pipe 8-bit */ +++#define R_TILEGX_DEST_IMM8_X1 27 /* X1 pipe destination 8-bit */ +++#define R_TILEGX_MT_IMM14_X1 28 /* X1 pipe mtspr */ +++#define R_TILEGX_MF_IMM14_X1 29 /* X1 pipe mfspr */ +++#define R_TILEGX_MMSTART_X0 30 /* X0 pipe mm "start" */ +++#define R_TILEGX_MMEND_X0 31 /* X0 pipe mm "end" */ +++#define R_TILEGX_SHAMT_X0 32 /* X0 pipe shift amount */ +++#define R_TILEGX_SHAMT_X1 33 /* X1 pipe shift amount */ +++#define R_TILEGX_SHAMT_Y0 34 /* Y0 pipe shift amount */ +++#define R_TILEGX_SHAMT_Y1 35 /* Y1 pipe shift amount */ +++#define R_TILEGX_IMM16_X0_HW0 36 /* X0 pipe hword 0 */ +++#define R_TILEGX_IMM16_X1_HW0 37 /* X1 pipe hword 0 */ +++#define R_TILEGX_IMM16_X0_HW1 38 /* X0 pipe hword 1 */ +++#define R_TILEGX_IMM16_X1_HW1 39 /* X1 pipe hword 1 */ +++#define R_TILEGX_IMM16_X0_HW2 40 /* X0 pipe hword 2 */ +++#define R_TILEGX_IMM16_X1_HW2 41 /* X1 pipe hword 2 */ +++#define R_TILEGX_IMM16_X0_HW3 42 /* X0 pipe hword 3 */ +++#define R_TILEGX_IMM16_X1_HW3 43 /* X1 pipe hword 3 */ +++#define R_TILEGX_IMM16_X0_HW0_LAST 44 /* X0 pipe last hword 0 */ +++#define R_TILEGX_IMM16_X1_HW0_LAST 45 /* X1 pipe last hword 0 */ +++#define R_TILEGX_IMM16_X0_HW1_LAST 46 /* X0 pipe last hword 1 */ +++#define R_TILEGX_IMM16_X1_HW1_LAST 47 /* X1 pipe last hword 1 */ +++#define R_TILEGX_IMM16_X0_HW2_LAST 48 /* X0 pipe last hword 2 */ +++#define R_TILEGX_IMM16_X1_HW2_LAST 49 /* X1 pipe last hword 2 */ +++#define R_TILEGX_IMM16_X0_HW0_PCREL 50 /* X0 pipe PC relative hword 0 */ +++#define R_TILEGX_IMM16_X1_HW0_PCREL 51 /* X1 pipe PC relative hword 0 */ +++#define R_TILEGX_IMM16_X0_HW1_PCREL 52 /* X0 pipe PC relative hword 1 */ +++#define R_TILEGX_IMM16_X1_HW1_PCREL 53 /* X1 pipe PC relative hword 1 */ +++#define R_TILEGX_IMM16_X0_HW2_PCREL 54 /* X0 pipe PC relative hword 2 */ +++#define R_TILEGX_IMM16_X1_HW2_PCREL 55 /* X1 pipe PC relative hword 2 */ +++#define R_TILEGX_IMM16_X0_HW3_PCREL 56 /* X0 pipe PC relative hword 3 */ +++#define R_TILEGX_IMM16_X1_HW3_PCREL 57 /* X1 pipe PC relative hword 3 */ +++#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */ +++#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */ +++#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */ +++#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */ +++#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */ +++#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */ +++#define R_TILEGX_IMM16_X0_HW0_GOT 64 /* X0 pipe hword 0 GOT offset */ +++#define R_TILEGX_IMM16_X1_HW0_GOT 65 /* X1 pipe hword 0 GOT offset */ +++/* Relocs 66-71 are currently not defined. */ +++#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */ +++#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */ +++#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */ +++#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */ +++/* Relocs 76-77 are currently not defined. */ +++#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78 /* X0 pipe hword 0 TLS GD offset */ +++#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79 /* X1 pipe hword 0 TLS GD offset */ +++#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80 /* X0 pipe hword 0 TLS LE offset */ +++#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81 /* X1 pipe hword 0 TLS LE offset */ +++#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */ +++#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */ +++#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */ +++#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */ +++#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */ +++#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */ +++#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */ +++#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */ +++/* Relocs 90-91 are currently not defined. */ +++#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92 /* X0 pipe hword 0 TLS IE offset */ +++#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93 /* X1 pipe hword 0 TLS IE offset */ +++/* Relocs 94-99 are currently not defined. */ +++#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */ +++#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */ +++#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */ +++#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */ +++/* Relocs 104-105 are currently not defined. */ +++#define R_TILEGX_TLS_DTPMOD64 106 /* 64-bit ID of symbol's module */ +++#define R_TILEGX_TLS_DTPOFF64 107 /* 64-bit offset in TLS block */ +++#define R_TILEGX_TLS_TPOFF64 108 /* 64-bit offset in static TLS block */ +++#define R_TILEGX_TLS_DTPMOD32 109 /* 32-bit ID of symbol's module */ +++#define R_TILEGX_TLS_DTPOFF32 110 /* 32-bit offset in TLS block */ +++#define R_TILEGX_TLS_TPOFF32 111 /* 32-bit offset in static TLS block */ +++#define R_TILEGX_TLS_GD_CALL 112 /* "jal" for TLS GD */ +++#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113 /* X0 pipe "addi" for TLS GD */ +++#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114 /* X1 pipe "addi" for TLS GD */ +++#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115 /* Y0 pipe "addi" for TLS GD */ +++#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116 /* Y1 pipe "addi" for TLS GD */ +++#define R_TILEGX_TLS_IE_LOAD 117 /* "ld_tls" for TLS IE */ +++#define R_TILEGX_IMM8_X0_TLS_ADD 118 /* X0 pipe "addi" for TLS GD/IE */ +++#define R_TILEGX_IMM8_X1_TLS_ADD 119 /* X1 pipe "addi" for TLS GD/IE */ +++#define R_TILEGX_IMM8_Y0_TLS_ADD 120 /* Y0 pipe "addi" for TLS GD/IE */ +++#define R_TILEGX_IMM8_Y1_TLS_ADD 121 /* Y1 pipe "addi" for TLS GD/IE */ +++ +++#define R_TILEGX_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */ +++#define R_TILEGX_GNU_VTENTRY 129 /* GNU C++ vtable member usage */ +++ +++#define R_TILEGX_NUM 130 +++ +++#endif /* elf.h */ ++--- a/scripts/mod/mk_elfconfig.c +++++ b/scripts/mod/mk_elfconfig.c ++@@ -2,7 +2,11 @@ ++ #include ++ #include ++ #include +++#ifndef __APPLE__ ++ #include +++#else +++#include "elf.h" +++#endif ++ ++ int ++ main(int argc, char **argv) ++--- a/scripts/mod/modpost.h +++++ b/scripts/mod/modpost.h ++@@ -8,7 +8,11 @@ ++ #include ++ #include ++ #include +++#if !(defined(__APPLE__) || defined(__CYGWIN__)) ++ #include +++#else +++#include "elf.h" +++#endif ++ ++ #include "elfconfig.h" ++ +diff --git a/target/linux/generic/hack-5.10/211-darwin-uuid-typedef-clash.patch b/target/linux/generic/hack-5.10/211-darwin-uuid-typedef-clash.patch +new file mode 100644 +index 0000000000..50a6227148 +--- /dev/null ++++ b/target/linux/generic/hack-5.10/211-darwin-uuid-typedef-clash.patch +@@ -0,0 +1,22 @@ ++From e44fc2af1ddc452b6659d08c16973d65c73b7d0a Mon Sep 17 00:00:00 2001 ++From: Kevin Darbyshire-Bryant ++Date: Wed, 5 Feb 2020 18:36:43 +0000 ++Subject: [PATCH] file2alias: build on macos ++ ++Signed-off-by: Kevin Darbyshire-Bryant ++--- ++ scripts/mod/file2alias.c | 3 +++ ++ 1 file changed, 3 insertions(+) ++ ++--- a/scripts/mod/file2alias.c +++++ b/scripts/mod/file2alias.c ++@@ -38,6 +38,9 @@ typedef struct { ++ __u8 b[16]; ++ } guid_t; ++ +++#ifdef __APPLE__ +++#define uuid_t compat_uuid_t +++#endif ++ /* backwards compatibility, don't use in new code */ ++ typedef struct { ++ __u8 b[16]; +diff --git a/target/linux/generic/hack-5.10/212-tools_portability.patch b/target/linux/generic/hack-5.10/212-tools_portability.patch +new file mode 100644 +index 0000000000..0d8eb6fb9d +--- /dev/null ++++ b/target/linux/generic/hack-5.10/212-tools_portability.patch +@@ -0,0 +1,110 @@ ++From 48232d3d931c95953ce2ddfe7da7bb164aef6a73 Mon Sep 17 00:00:00 2001 ++From: Felix Fietkau ++Date: Fri, 7 Jul 2017 17:03:16 +0200 ++Subject: fix portability of some includes files in tools/ used on the host ++ ++Signed-off-by: Felix Fietkau ++--- ++ tools/include/tools/be_byteshift.h | 4 ++++ ++ tools/include/tools/le_byteshift.h | 4 ++++ ++ tools/include/tools/linux_types.h | 22 ++++++++++++++++++++++ ++ 3 files changed, 30 insertions(+) ++ create mode 100644 tools/include/tools/linux_types.h ++ ++--- a/tools/include/tools/be_byteshift.h +++++ b/tools/include/tools/be_byteshift.h ++@@ -2,6 +2,10 @@ ++ #ifndef _TOOLS_BE_BYTESHIFT_H ++ #define _TOOLS_BE_BYTESHIFT_H ++ +++#ifndef __linux__ +++#include "linux_types.h" +++#endif +++ ++ #include ++ ++ static inline uint16_t __get_unaligned_be16(const uint8_t *p) ++--- a/tools/include/tools/le_byteshift.h +++++ b/tools/include/tools/le_byteshift.h ++@@ -2,6 +2,10 @@ ++ #ifndef _TOOLS_LE_BYTESHIFT_H ++ #define _TOOLS_LE_BYTESHIFT_H ++ +++#ifndef __linux__ +++#include "linux_types.h" +++#endif +++ ++ #include ++ ++ static inline uint16_t __get_unaligned_le16(const uint8_t *p) ++--- /dev/null +++++ b/tools/include/tools/linux_types.h ++@@ -0,0 +1,26 @@ +++#ifndef __LINUX_TYPES_H +++#define __LINUX_TYPES_H +++ +++#include +++ +++typedef int8_t __s8; +++typedef uint8_t __u8; +++typedef uint8_t __be8; +++typedef uint8_t __le8; +++ +++typedef int16_t __s16; +++typedef uint16_t __u16; +++typedef uint16_t __be16; +++typedef uint16_t __le16; +++ +++typedef int32_t __s32; +++typedef uint32_t __u32; +++typedef uint32_t __be32; +++typedef uint32_t __le32; +++ +++typedef int64_t __s64; +++typedef uint64_t __u64; +++typedef uint64_t __be64; +++typedef uint64_t __le64; +++ +++#endif ++--- a/tools/include/linux/types.h +++++ b/tools/include/linux/types.h ++@@ -7,8 +7,12 @@ ++ #include ++ ++ #define __SANE_USERSPACE_TYPES__ /* For PPC64, to get LL64 types */ +++#ifndef __linux__ +++#include +++#else ++ #include ++ #include +++#endif ++ ++ struct page; ++ struct kmem_cache; ++--- a/tools/perf/pmu-events/jevents.c +++++ b/tools/perf/pmu-events/jevents.c ++@@ -1,4 +1,6 @@ +++#ifdef __linux__ ++ #define _XOPEN_SOURCE 500 /* needed for nftw() */ +++#endif ++ #define _GNU_SOURCE /* needed for asprintf() */ ++ ++ /* Parse event JSON files */ ++@@ -35,6 +37,7 @@ ++ #include ++ #include ++ #include +++#include ++ #include ++ #include ++ #include ++--- a/tools/perf/pmu-events/json.c +++++ b/tools/perf/pmu-events/json.c ++@@ -38,7 +38,6 @@ ++ #include ++ #include "jsmn.h" ++ #include "json.h" ++-#include ++ ++ ++ static char *mapfile(const char *fn, size_t *size) +diff --git a/target/linux/generic/hack-5.10/214-spidev_h_portability.patch b/target/linux/generic/hack-5.10/214-spidev_h_portability.patch +new file mode 100644 +index 0000000000..506d50ad4d +--- /dev/null ++++ b/target/linux/generic/hack-5.10/214-spidev_h_portability.patch +@@ -0,0 +1,24 @@ ++From be9be95ff10e16a5b4ad36f903978d0cc5747024 Mon Sep 17 00:00:00 2001 ++From: Felix Fietkau ++Date: Fri, 7 Jul 2017 17:04:08 +0200 ++Subject: kernel: fix linux/spi/spidev.h portability issues with musl ++ ++Felix will try to get this define included into musl ++ ++lede-commit: 795e7cf60de19e7a076a46874fab7bb88b43bbff ++Signed-off-by: Felix Fietkau ++--- ++ include/uapi/linux/spi/spidev.h | 2 +- ++ 1 file changed, 1 insertion(+), 1 deletion(-) ++ ++--- a/include/uapi/linux/spi/spidev.h +++++ b/include/uapi/linux/spi/spidev.h ++@@ -121,7 +121,7 @@ struct spi_ioc_transfer { ++ ++ /* not all platforms use or _IOC_TYPECHECK() ... */ ++ #define SPI_MSGSIZE(N) \ ++- ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << _IOC_SIZEBITS)) \ +++ ((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << 13)) \ ++ ? ((N)*(sizeof (struct spi_ioc_transfer))) : 0) ++ #define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)]) ++ +diff --git a/target/linux/generic/hack-5.10/220-gc_sections.patch b/target/linux/generic/hack-5.10/220-gc_sections.patch +new file mode 100644 +index 0000000000..810c5aecf5 +--- /dev/null ++++ b/target/linux/generic/hack-5.10/220-gc_sections.patch +@@ -0,0 +1,120 @@ ++From e3d8676f5722b7622685581e06e8f53e6138e3ab Mon Sep 17 00:00:00 2001 ++From: Felix Fietkau ++Date: Sat, 15 Jul 2017 23:42:36 +0200 ++Subject: use -ffunction-sections, -fdata-sections and --gc-sections ++ ++In combination with kernel symbol export stripping this significantly reduces ++the kernel image size. Used on both ARM and MIPS architectures. ++ ++Signed-off-by: Felix Fietkau ++Signed-off-by: Jonas Gorski ++Signed-off-by: Gabor Juhos ++--- ++--- a/arch/arm/Kconfig +++++ b/arch/arm/Kconfig ++@@ -113,6 +113,7 @@ config ARM ++ select HAVE_UID16 ++ select HAVE_VIRT_CPU_ACCOUNTING_GEN ++ select IRQ_FORCED_THREADING +++ select HAVE_LD_DEAD_CODE_DATA_ELIMINATION ++ select MODULES_USE_ELF_REL ++ select NEED_DMA_MAP_STATE ++ select OF_EARLY_FLATTREE if OF ++--- a/arch/arm/boot/compressed/Makefile +++++ b/arch/arm/boot/compressed/Makefile ++@@ -98,6 +98,7 @@ $(foreach o, $(libfdt_objs) atags_to_fdt ++ ifdef building_out_of_srctree ++ $(shell rm -f $(addprefix $(obj)/, fdt_rw.c fdt_ro.c fdt_wip.c fdt.c)) ++ endif +++KBUILD_CFLAGS_KERNEL := $(patsubst -f%-sections,,$(KBUILD_CFLAGS_KERNEL)) ++ ++ targets := vmlinux vmlinux.lds piggy_data piggy.o \ ++ lib1funcs.o ashldi3.o bswapsdi2.o \ ++--- a/arch/arm/kernel/vmlinux.lds.S +++++ b/arch/arm/kernel/vmlinux.lds.S ++@@ -100,24 +100,24 @@ SECTIONS ++ } ++ .init.arch.info : { ++ __arch_info_begin = .; ++- *(.arch.info.init) +++ KEEP(*(.arch.info.init)) ++ __arch_info_end = .; ++ } ++ .init.tagtable : { ++ __tagtable_begin = .; ++- *(.taglist.init) +++ KEEP(*(.taglist.init)) ++ __tagtable_end = .; ++ } ++ #ifdef CONFIG_SMP_ON_UP ++ .init.smpalt : { ++ __smpalt_begin = .; ++- *(.alt.smp.init) +++ KEEP(*(.alt.smp.init)) ++ __smpalt_end = .; ++ } ++ #endif ++ .init.pv_table : { ++ __pv_table_begin = .; ++- *(.pv_table) +++ KEEP(*(.pv_table)) ++ __pv_table_end = .; ++ } ++ ++--- a/arch/arm/include/asm/vmlinux.lds.h +++++ b/arch/arm/include/asm/vmlinux.lds.h ++@@ -23,19 +23,19 @@ ++ #define ARM_MMU_DISCARD(x) ++ #else ++ #define ARM_MMU_KEEP(x) ++-#define ARM_MMU_DISCARD(x) x +++#define ARM_MMU_DISCARD(x) KEEP(x) ++ #endif ++ ++ #define PROC_INFO \ ++ . = ALIGN(4); \ ++ __proc_info_begin = .; \ ++- *(.proc.info.init) \ +++ KEEP(*(.proc.info.init)) \ ++ __proc_info_end = .; ++ ++ #define IDMAP_TEXT \ ++ ALIGN_FUNCTION(); \ ++ __idmap_text_start = .; \ ++- *(.idmap.text) \ +++ KEEP(*(.idmap.text)) \ ++ __idmap_text_end = .; \ ++ ++ #define ARM_DISCARD \ ++@@ -96,12 +96,12 @@ ++ . = ALIGN(8); \ ++ .ARM.unwind_idx : { \ ++ __start_unwind_idx = .; \ ++- *(.ARM.exidx*) \ +++ KEEP(*(.ARM.exidx*)) \ ++ __stop_unwind_idx = .; \ ++ } \ ++ .ARM.unwind_tab : { \ ++ __start_unwind_tab = .; \ ++- *(.ARM.extab*) \ +++ KEEP(*(.ARM.extab*)) \ ++ __stop_unwind_tab = .; \ ++ } ++ ++@@ -112,14 +112,14 @@ ++ #define ARM_VECTORS \ ++ __vectors_start = .; \ ++ .vectors 0xffff0000 : AT(__vectors_start) { \ ++- *(.vectors) \ +++ KEEP(*(.vectors)) \ ++ } \ ++ . = __vectors_start + SIZEOF(.vectors); \ ++ __vectors_end = .; \ ++ \ ++ __stubs_start = .; \ ++ .stubs ADDR(.vectors) + 0x1000 : AT(__stubs_start) { \ ++- *(.stubs) \ +++ KEEP(*(.stubs)) \ ++ } \ ++ . = __stubs_start + SIZEOF(.stubs); \ ++ __stubs_end = .; \ +diff --git a/target/linux/generic/hack-5.10/221-module_exports.patch b/target/linux/generic/hack-5.10/221-module_exports.patch +new file mode 100644 +index 0000000000..9dd57ba933 +--- /dev/null ++++ b/target/linux/generic/hack-5.10/221-module_exports.patch +@@ -0,0 +1,102 @@ ++From b14784e7883390c20ed3ff904892255404a5914b Mon Sep 17 00:00:00 2001 ++From: Felix Fietkau ++Date: Fri, 7 Jul 2017 17:05:53 +0200 ++Subject: add an optional config option for stripping all unnecessary symbol exports from the kernel image ++ ++lede-commit: bb5a40c64b7c4f4848509fa0a6625055fc9e66cc ++Signed-off-by: Felix Fietkau ++--- ++ include/asm-generic/vmlinux.lds.h | 18 +++++++++++++++--- ++ include/linux/export.h | 9 ++++++++- ++ scripts/Makefile.build | 2 +- ++ 3 files changed, 24 insertions(+), 5 deletions(-) ++ ++--- a/include/asm-generic/vmlinux.lds.h +++++ b/include/asm-generic/vmlinux.lds.h ++@@ -81,6 +81,16 @@ ++ #define RO_EXCEPTION_TABLE ++ #endif ++ +++#ifndef SYMTAB_KEEP +++#define SYMTAB_KEEP KEEP(*(SORT(___ksymtab+*))) +++#define SYMTAB_KEEP_GPL KEEP(*(SORT(___ksymtab_gpl+*))) +++#endif +++ +++#ifndef SYMTAB_DISCARD +++#define SYMTAB_DISCARD +++#define SYMTAB_DISCARD_GPL +++#endif +++ ++ /* Align . to a 8 byte boundary equals to maximum function alignment. */ ++ #define ALIGN_FUNCTION() . = ALIGN(8) ++ ++@@ -470,14 +480,14 @@ ++ /* Kernel symbol table: Normal symbols */ \ ++ __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \ ++ __start___ksymtab = .; \ ++- KEEP(*(SORT(___ksymtab+*))) \ +++ SYMTAB_KEEP \ ++ __stop___ksymtab = .; \ ++ } \ ++ \ ++ /* Kernel symbol table: GPL-only symbols */ \ ++ __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \ ++ __start___ksymtab_gpl = .; \ ++- KEEP(*(SORT(___ksymtab_gpl+*))) \ +++ SYMTAB_KEEP_GPL \ ++ __stop___ksymtab_gpl = .; \ ++ } \ ++ \ ++@@ -539,7 +549,7 @@ ++ \ ++ /* Kernel symbol table: strings */ \ ++ __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \ ++- *(__ksymtab_strings) \ +++ *(__ksymtab_strings+*) \ ++ } \ ++ \ ++ /* __*init sections */ \ ++@@ -1008,6 +1018,8 @@ ++ ++ #define COMMON_DISCARDS \ ++ SANITIZER_DISCARDS \ +++ SYMTAB_DISCARD \ +++ SYMTAB_DISCARD_GPL \ ++ *(.discard) \ ++ *(.discard.*) \ ++ *(.modinfo) \ ++--- a/include/linux/export.h +++++ b/include/linux/export.h ++@@ -82,6 +82,12 @@ struct kernel_symbol { ++ ++ #else ++ +++#ifdef MODULE +++#define __EXPORT_SUFFIX(sym) +++#else +++#define __EXPORT_SUFFIX(sym) "+" #sym +++#endif +++ ++ /* ++ * For every exported symbol, do the following: ++ * ++@@ -99,7 +105,7 @@ struct kernel_symbol { ++ extern const char __kstrtab_##sym[]; \ ++ extern const char __kstrtabns_##sym[]; \ ++ __CRC_SYMBOL(sym, sec); \ ++- asm(" .section \"__ksymtab_strings\",\"aMS\",%progbits,1 \n" \ +++ asm(" .section \"__ksymtab_strings" __EXPORT_SUFFIX(sym) "\",\"aMS\",%progbits,1 \n" \ ++ "__kstrtab_" #sym ": \n" \ ++ " .asciz \"" #sym "\" \n" \ ++ "__kstrtabns_" #sym ": \n" \ ++--- a/scripts/Makefile.build +++++ b/scripts/Makefile.build ++@@ -366,7 +366,7 @@ targets += $(lib-y) $(always-y) $(MAKECM ++ # Linker scripts preprocessor (.lds.S -> .lds) ++ # --------------------------------------------------------------------------- ++ quiet_cmd_cpp_lds_S = LDS $@ ++- cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -U$(ARCH) \ +++ cmd_cpp_lds_S = $(CPP) $(EXTRA_LDSFLAGS) $(cpp_flags) -P -U$(ARCH) \ ++ -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $< ++ ++ $(obj)/%.lds: $(src)/%.lds.S FORCE +diff --git a/target/linux/generic/hack-5.10/230-openwrt_lzma_options.patch b/target/linux/generic/hack-5.10/230-openwrt_lzma_options.patch +new file mode 100644 +index 0000000000..906527faf9 +--- /dev/null ++++ b/target/linux/generic/hack-5.10/230-openwrt_lzma_options.patch +@@ -0,0 +1,34 @@ ++From b3d00b452467f621317953d9e4c6f9ae8dcfd271 Mon Sep 17 00:00:00 2001 ++From: Imre Kaloz ++Date: Fri, 7 Jul 2017 17:06:55 +0200 ++Subject: use the openwrt lzma options for now ++ ++lede-commit: 548de949f392049420a6a1feeef118b30ab8ea8c ++Signed-off-by: Imre Kaloz ++--- ++ lib/decompress.c | 1 + ++ scripts/Makefile.lib | 2 +- ++ usr/gen_initramfs_list.sh | 10 +++++----- ++ 3 files changed, 7 insertions(+), 6 deletions(-) ++ ++--- a/lib/decompress.c +++++ b/lib/decompress.c ++@@ -53,6 +53,7 @@ static const struct compress_format comp ++ { {0x1f, 0x9e}, "gzip", gunzip }, ++ { {0x42, 0x5a}, "bzip2", bunzip2 }, ++ { {0x5d, 0x00}, "lzma", unlzma }, +++ { {0x6d, 0x00}, "lzma-openwrt", unlzma }, ++ { {0xfd, 0x37}, "xz", unxz }, ++ { {0x89, 0x4c}, "lzo", unlzo }, ++ { {0x02, 0x21}, "lz4", unlz4 }, ++--- a/scripts/Makefile.lib +++++ b/scripts/Makefile.lib ++@@ -370,7 +370,7 @@ quiet_cmd_bzip2 = BZIP2 $@ ++ # --------------------------------------------------------------------------- ++ ++ quiet_cmd_lzma = LZMA $@ ++- cmd_lzma = { cat $(real-prereqs) | $(LZMA) -9; $(size_append); } > $@ +++ cmd_lzma = { cat $(real-prereqs) | $(LZMA) e -d20 -lc1 -lp2 -pb2 -eos -si -so; $(size_append); } > $@ ++ ++ quiet_cmd_lzo = LZO $@ ++ cmd_lzo = { cat $(real-prereqs) | $(KLZOP) -9; $(size_append); } > $@ +diff --git a/target/linux/generic/hack-5.10/250-netfilter_depends.patch b/target/linux/generic/hack-5.10/250-netfilter_depends.patch +new file mode 100644 +index 0000000000..b27b440157 +--- /dev/null ++++ b/target/linux/generic/hack-5.10/250-netfilter_depends.patch +@@ -0,0 +1,27 @@ ++From: Felix Fietkau ++Subject: hack: net: remove bogus netfilter dependencies ++ ++lede-commit: 589d2a377dee27d206fc3725325309cf649e4df6 ++Signed-off-by: Felix Fietkau ++--- ++ net/netfilter/Kconfig | 2 -- ++ 1 file changed, 2 deletions(-) ++ ++--- a/net/netfilter/Kconfig +++++ b/net/netfilter/Kconfig ++@@ -228,7 +228,6 @@ config NF_CONNTRACK_FTP ++ ++ config NF_CONNTRACK_H323 ++ tristate "H.323 protocol support" ++- depends on IPV6 || IPV6=n ++ depends on NETFILTER_ADVANCED ++ help ++ H.323 is a VoIP signalling protocol from ITU-T. As one of the most ++@@ -1072,7 +1071,6 @@ config NETFILTER_XT_TARGET_SECMARK ++ ++ config NETFILTER_XT_TARGET_TCPMSS ++ tristate '"TCPMSS" target support' ++- depends on IPV6 || IPV6=n ++ default m if NETFILTER_ADVANCED=n ++ help ++ This option adds a `TCPMSS' target, which allows you to alter the +diff --git a/target/linux/generic/hack-5.10/251-kconfig.patch b/target/linux/generic/hack-5.10/251-kconfig.patch +new file mode 100644 +index 0000000000..f80561c8e6 +--- /dev/null ++++ b/target/linux/generic/hack-5.10/251-kconfig.patch +@@ -0,0 +1,199 @@ ++From da3c50704f14132f4adf80d48e9a4cd5d46e54c9 Mon Sep 17 00:00:00 2001 ++From: John Crispin ++Date: Fri, 7 Jul 2017 17:09:21 +0200 ++Subject: kconfig: owrt specifc dependencies ++ ++Signed-off-by: John Crispin ++--- ++ crypto/Kconfig | 10 +++++----- ++ drivers/bcma/Kconfig | 1 + ++ drivers/ssb/Kconfig | 3 ++- ++ lib/Kconfig | 8 ++++---- ++ net/netfilter/Kconfig | 2 +- ++ net/wireless/Kconfig | 17 ++++++++++------- ++ sound/core/Kconfig | 4 ++-- ++ 7 files changed, 25 insertions(+), 20 deletions(-) ++ ++--- a/crypto/Kconfig +++++ b/crypto/Kconfig ++@@ -33,7 +33,7 @@ config CRYPTO_FIPS ++ this is. ++ ++ config CRYPTO_ALGAPI ++- tristate +++ tristate "ALGAPI" ++ select CRYPTO_ALGAPI2 ++ help ++ This option provides the API for cryptographic algorithms. ++@@ -42,7 +42,7 @@ config CRYPTO_ALGAPI2 ++ tristate ++ ++ config CRYPTO_AEAD ++- tristate +++ tristate "AEAD" ++ select CRYPTO_AEAD2 ++ select CRYPTO_ALGAPI ++ ++@@ -53,7 +53,7 @@ config CRYPTO_AEAD2 ++ select CRYPTO_RNG2 ++ ++ config CRYPTO_SKCIPHER ++- tristate +++ tristate "SKCIPHER" ++ select CRYPTO_SKCIPHER2 ++ select CRYPTO_ALGAPI ++ ++@@ -63,7 +63,7 @@ config CRYPTO_SKCIPHER2 ++ select CRYPTO_RNG2 ++ ++ config CRYPTO_HASH ++- tristate +++ tristate "HASH" ++ select CRYPTO_HASH2 ++ select CRYPTO_ALGAPI ++ ++@@ -72,7 +72,7 @@ config CRYPTO_HASH2 ++ select CRYPTO_ALGAPI2 ++ ++ config CRYPTO_RNG ++- tristate +++ tristate "RNG" ++ select CRYPTO_RNG2 ++ select CRYPTO_ALGAPI ++ ++--- a/drivers/bcma/Kconfig +++++ b/drivers/bcma/Kconfig ++@@ -16,6 +16,7 @@ if BCMA ++ # Support for Block-I/O. SELECT this from the driver that needs it. ++ config BCMA_BLOCKIO ++ bool +++ default y ++ ++ config BCMA_HOST_PCI_POSSIBLE ++ bool ++--- a/drivers/ssb/Kconfig +++++ b/drivers/ssb/Kconfig ++@@ -29,6 +29,7 @@ config SSB_SPROM ++ config SSB_BLOCKIO ++ bool ++ depends on SSB +++ default y ++ ++ config SSB_PCIHOST_POSSIBLE ++ bool ++@@ -49,7 +50,7 @@ config SSB_PCIHOST ++ config SSB_B43_PCI_BRIDGE ++ bool ++ depends on SSB_PCIHOST ++- default n +++ default y ++ ++ config SSB_PCMCIAHOST_POSSIBLE ++ bool ++--- a/lib/Kconfig +++++ b/lib/Kconfig ++@@ -419,16 +419,16 @@ config BCH_CONST_T ++ # Textsearch support is select'ed if needed ++ # ++ config TEXTSEARCH ++- bool +++ bool "Textsearch support" ++ ++ config TEXTSEARCH_KMP ++- tristate +++ tristate "Textsearch KMP" ++ ++ config TEXTSEARCH_BM ++- tristate +++ tristate "Textsearch BM" ++ ++ config TEXTSEARCH_FSM ++- tristate +++ tristate "Textsearch FSM" ++ ++ config BTREE ++ bool ++--- a/net/netfilter/Kconfig +++++ b/net/netfilter/Kconfig ++@@ -11,7 +11,7 @@ config NETFILTER_INGRESS ++ infrastructure. ++ ++ config NETFILTER_NETLINK ++- tristate +++ tristate "Netfilter NFNETLINK interface" ++ ++ config NETFILTER_FAMILY_BRIDGE ++ bool ++--- a/net/wireless/Kconfig +++++ b/net/wireless/Kconfig ++@@ -1,6 +1,6 @@ ++ # SPDX-License-Identifier: GPL-2.0-only ++ config WIRELESS_EXT ++- bool +++ bool "Wireless extensions" ++ ++ config WEXT_CORE ++ def_bool y ++@@ -12,10 +12,10 @@ config WEXT_PROC ++ depends on WEXT_CORE ++ ++ config WEXT_SPY ++- bool +++ bool "WEXT_SPY" ++ ++ config WEXT_PRIV ++- bool +++ bool "WEXT_PRIV" ++ ++ config CFG80211 ++ tristate "cfg80211 - wireless configuration API" ++@@ -204,7 +204,7 @@ config CFG80211_WEXT_EXPORT ++ endif # CFG80211 ++ ++ config LIB80211 ++- tristate +++ tristate "LIB80211" ++ default n ++ help ++ This options enables a library of common routines used ++@@ -213,17 +213,17 @@ config LIB80211 ++ Drivers should select this themselves if needed. ++ ++ config LIB80211_CRYPT_WEP ++- tristate +++ tristate "LIB80211_CRYPT_WEP" ++ select CRYPTO_LIB_ARC4 ++ ++ config LIB80211_CRYPT_CCMP ++- tristate +++ tristate "LIB80211_CRYPT_CCMP" ++ select CRYPTO ++ select CRYPTO_AES ++ select CRYPTO_CCM ++ ++ config LIB80211_CRYPT_TKIP ++- tristate +++ tristate "LIB80211_CRYPT_TKIP" ++ select CRYPTO_LIB_ARC4 ++ ++ config LIB80211_DEBUG ++--- a/sound/core/Kconfig +++++ b/sound/core/Kconfig ++@@ -17,7 +17,7 @@ config SND_DMAENGINE_PCM ++ tristate ++ ++ config SND_HWDEP ++- tristate +++ tristate "Sound hardware support" ++ ++ config SND_SEQ_DEVICE ++ tristate ++@@ -27,7 +27,7 @@ config SND_RAWMIDI ++ select SND_SEQ_DEVICE if SND_SEQUENCER != n ++ ++ config SND_COMPRESS_OFFLOAD ++- tristate +++ tristate "Compression offloading support" ++ ++ config SND_JACK ++ bool +diff --git a/target/linux/generic/hack-5.10/259-regmap_dynamic.patch b/target/linux/generic/hack-5.10/259-regmap_dynamic.patch +new file mode 100644 +index 0000000000..e5159cb000 +--- /dev/null ++++ b/target/linux/generic/hack-5.10/259-regmap_dynamic.patch +@@ -0,0 +1,135 @@ ++From 811d9e2268a62b830cfe93cd8bc929afcb8b198b Mon Sep 17 00:00:00 2001 ++From: Felix Fietkau ++Date: Sat, 15 Jul 2017 21:12:38 +0200 ++Subject: kernel: move regmap bloat out of the kernel image if it is only being used in modules ++ ++lede-commit: 96f39119815028073583e4fca3a9c5fe9141e998 ++Signed-off-by: Felix Fietkau ++--- ++ drivers/base/regmap/Kconfig | 15 ++++++++++----- ++ drivers/base/regmap/Makefile | 12 ++++++++---- ++ drivers/base/regmap/regmap.c | 3 +++ ++ include/linux/regmap.h | 2 +- ++ 4 files changed, 22 insertions(+), 10 deletions(-) ++ ++--- a/drivers/base/regmap/Kconfig +++++ b/drivers/base/regmap/Kconfig ++@@ -4,9 +4,8 @@ ++ # subsystems should select the appropriate symbols. ++ ++ config REGMAP ++- default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SOUNDWIRE || REGMAP_SCCB || REGMAP_I3C || REGMAP_SPI_AVMM) ++ select IRQ_DOMAIN if REGMAP_IRQ ++- bool +++ tristate ++ ++ config REGCACHE_COMPRESSED ++ select LZO_COMPRESS ++@@ -14,46 +13,59 @@ config REGCACHE_COMPRESSED ++ bool ++ ++ config REGMAP_AC97 +++ select REGMAP ++ tristate ++ ++ config REGMAP_I2C ++ tristate +++ select REGMAP ++ depends on I2C ++ ++ config REGMAP_SLIMBUS ++ tristate +++ select REGMAP ++ depends on SLIMBUS ++ ++ config REGMAP_SPI ++ tristate +++ select REGMAP +++ depends on SPI_MASTER ++ depends on SPI ++ ++ config REGMAP_SPMI ++ tristate +++ select REGMAP ++ depends on SPMI ++ ++ config REGMAP_W1 ++ tristate +++ select REGMAP ++ depends on W1 ++ ++ config REGMAP_MMIO ++ tristate +++ select REGMAP ++ ++ config REGMAP_IRQ ++ bool +++ select REGMAP ++ ++ config REGMAP_SOUNDWIRE ++ tristate +++ select REGMAP ++ depends on SOUNDWIRE ++ ++ config REGMAP_SCCB ++ tristate +++ select REGMAP ++ depends on I2C ++ ++ config REGMAP_I3C ++ tristate +++ select REGMAP ++ depends on I3C ++ ++ config REGMAP_SPI_AVMM ++ tristate +++ select REGMAP ++ depends on SPI ++--- a/drivers/base/regmap/Makefile +++++ b/drivers/base/regmap/Makefile ++@@ -2,10 +2,14 @@ ++ # For include/trace/define_trace.h to include trace.h ++ CFLAGS_regmap.o := -I$(src) ++ ++-obj-$(CONFIG_REGMAP) += regmap.o regcache.o ++-obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-flat.o ++-obj-$(CONFIG_REGCACHE_COMPRESSED) += regcache-lzo.o ++-obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o +++regmap-core-objs = regmap.o regcache.o regcache-rbtree.o regcache-flat.o +++ifdef CONFIG_DEBUG_FS +++regmap-core-objs += regmap-debugfs.o +++endif +++ifdef CONFIG_REGCACHE_COMPRESSED +++regmap-core-objs += regcache-lzo.o +++endif +++obj-$(CONFIG_REGMAP) += regmap-core.o ++ obj-$(CONFIG_REGMAP_AC97) += regmap-ac97.o ++ obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o ++ obj-$(CONFIG_REGMAP_SLIMBUS) += regmap-slimbus.o ++--- a/drivers/base/regmap/regmap.c +++++ b/drivers/base/regmap/regmap.c ++@@ -9,6 +9,7 @@ ++ #include ++ #include ++ #include +++#include ++ #include ++ #include ++ #include ++@@ -3296,3 +3297,5 @@ static int __init regmap_initcall(void) ++ return 0; ++ } ++ postcore_initcall(regmap_initcall); +++ +++MODULE_LICENSE("GPL"); ++--- a/include/linux/regmap.h +++++ b/include/linux/regmap.h ++@@ -179,7 +179,7 @@ struct reg_sequence { ++ __ret ?: __tmp; \ ++ }) ++ ++-#ifdef CONFIG_REGMAP +++#if IS_REACHABLE(CONFIG_REGMAP) ++ ++ enum regmap_endian { ++ /* Unspecified -> 0 -> Backwards compatible default */ +diff --git a/target/linux/generic/hack-5.10/260-crypto_test_dependencies.patch b/target/linux/generic/hack-5.10/260-crypto_test_dependencies.patch +new file mode 100644 +index 0000000000..1eab709c46 +--- /dev/null ++++ b/target/linux/generic/hack-5.10/260-crypto_test_dependencies.patch +@@ -0,0 +1,52 @@ ++From fd1799b0bf5efa46dd3e6dfbbf3955564807e508 Mon Sep 17 00:00:00 2001 ++From: Felix Fietkau ++Date: Fri, 7 Jul 2017 17:12:51 +0200 ++Subject: kernel: prevent cryptomgr from pulling in useless extra dependencies for tests that are not run ++ ++Reduces kernel size after LZMA by about 5k on MIPS ++ ++lede-commit: 044c316167e076479a344c59905e5b435b84a77f ++Signed-off-by: Felix Fietkau ++--- ++ crypto/Kconfig | 13 ++++++------- ++ crypto/algboss.c | 4 ++++ ++ 2 files changed, 10 insertions(+), 7 deletions(-) ++ ++--- a/crypto/Kconfig +++++ b/crypto/Kconfig ++@@ -120,13 +120,13 @@ config CRYPTO_MANAGER ++ cbc(aes). ++ ++ config CRYPTO_MANAGER2 ++- def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y) ++- select CRYPTO_AEAD2 ++- select CRYPTO_HASH2 ++- select CRYPTO_SKCIPHER2 ++- select CRYPTO_AKCIPHER2 ++- select CRYPTO_KPP2 ++- select CRYPTO_ACOMP2 +++ def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y && !CRYPTO_MANAGER_DISABLE_TESTS) +++ select CRYPTO_AEAD2 if !CRYPTO_MANAGER_DISABLE_TESTS +++ select CRYPTO_HASH2 if !CRYPTO_MANAGER_DISABLE_TESTS +++ select CRYPTO_SKCIPHER2 if !CRYPTO_MANAGER_DISABLE_TESTS +++ select CRYPTO_AKCIPHER2 if !CRYPTO_MANAGER_DISABLE_TESTS +++ select CRYPTO_KPP2 if !CRYPTO_MANAGER_DISABLE_TESTS +++ select CRYPTO_ACOMP2 if !CRYPTO_MANAGER_DISABLE_TESTS ++ ++ config CRYPTO_USER ++ tristate "Userspace cryptographic algorithm configuration" ++--- a/crypto/algboss.c +++++ b/crypto/algboss.c ++@@ -230,8 +230,12 @@ static int cryptomgr_schedule_test(struc ++ type = alg->cra_flags; ++ ++ /* Do not test internal algorithms. */ +++#ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS +++ type |= CRYPTO_ALG_TESTED; +++#else ++ if (type & CRYPTO_ALG_INTERNAL) ++ type |= CRYPTO_ALG_TESTED; +++#endif ++ ++ param->type = type; ++ +diff --git a/target/linux/generic/hack-5.10/261-lib-arc4-unhide.patch b/target/linux/generic/hack-5.10/261-lib-arc4-unhide.patch +new file mode 100644 +index 0000000000..a7668acfad +--- /dev/null ++++ b/target/linux/generic/hack-5.10/261-lib-arc4-unhide.patch +@@ -0,0 +1,15 @@ ++This makes it possible to select CONFIG_CRYPTO_LIB_ARC4 directly. We ++need this to be able to compile this into the kernel and make use of it ++from backports. ++ ++--- a/lib/crypto/Kconfig +++++ b/lib/crypto/Kconfig ++@@ -6,7 +6,7 @@ config CRYPTO_LIB_AES ++ tristate ++ ++ config CRYPTO_LIB_ARC4 ++- tristate +++ tristate "ARC4 cipher library" ++ ++ config CRYPTO_ARCH_HAVE_LIB_BLAKE2S ++ tristate +diff --git a/target/linux/generic/hack-5.10/280-rfkill-stubs.patch b/target/linux/generic/hack-5.10/280-rfkill-stubs.patch +new file mode 100644 +index 0000000000..2e48aea1cf +--- /dev/null ++++ b/target/linux/generic/hack-5.10/280-rfkill-stubs.patch +@@ -0,0 +1,84 @@ ++From 236c1acdfef5958010ac9814a9872e0a46fd78ee Mon Sep 17 00:00:00 2001 ++From: John Crispin ++Date: Fri, 7 Jul 2017 17:13:44 +0200 ++Subject: rfkill: add fake rfkill support ++ ++allow building of modules depending on RFKILL even if RFKILL is not enabled. ++ ++Signed-off-by: John Crispin ++--- ++ include/linux/rfkill.h | 2 +- ++ net/Makefile | 2 +- ++ net/rfkill/Kconfig | 14 +++++++++----- ++ net/rfkill/Makefile | 2 +- ++ 4 files changed, 12 insertions(+), 8 deletions(-) ++ ++--- a/include/linux/rfkill.h +++++ b/include/linux/rfkill.h ++@@ -64,7 +64,7 @@ struct rfkill_ops { ++ int (*set_block)(void *data, bool blocked); ++ }; ++ ++-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) +++#if defined(CONFIG_RFKILL_FULL) || defined(CONFIG_RFKILL_FULL_MODULE) ++ /** ++ * rfkill_alloc - Allocate rfkill structure ++ * @name: name of the struct -- the string is not copied internally ++--- a/net/Makefile +++++ b/net/Makefile ++@@ -53,7 +53,7 @@ obj-$(CONFIG_TIPC) += tipc/ ++ obj-$(CONFIG_NETLABEL) += netlabel/ ++ obj-$(CONFIG_IUCV) += iucv/ ++ obj-$(CONFIG_SMC) += smc/ ++-obj-$(CONFIG_RFKILL) += rfkill/ +++obj-$(CONFIG_RFKILL_FULL) += rfkill/ ++ obj-$(CONFIG_NET_9P) += 9p/ ++ obj-$(CONFIG_CAIF) += caif/ ++ ifneq ($(CONFIG_DCB),) ++--- a/net/rfkill/Kconfig +++++ b/net/rfkill/Kconfig ++@@ -2,7 +2,11 @@ ++ # ++ # RF switch subsystem configuration ++ # ++-menuconfig RFKILL +++config RFKILL +++ bool +++ default y +++ +++menuconfig RFKILL_FULL ++ tristate "RF switch subsystem support" ++ help ++ Say Y here if you want to have control over RF switches ++@@ -14,19 +18,19 @@ menuconfig RFKILL ++ # LED trigger support ++ config RFKILL_LEDS ++ bool ++- depends on RFKILL +++ depends on RFKILL_FULL ++ depends on LEDS_TRIGGERS = y || RFKILL = LEDS_TRIGGERS ++ default y ++ ++ config RFKILL_INPUT ++ bool "RF switch input support" if EXPERT ++- depends on RFKILL +++ depends on RFKILL_FULL ++ depends on INPUT = y || RFKILL = INPUT ++ default y if !EXPERT ++ ++ config RFKILL_GPIO ++ tristate "GPIO RFKILL driver" ++- depends on RFKILL +++ depends on RFKILL_FULL ++ depends on GPIOLIB || COMPILE_TEST ++ default n ++ help ++--- a/net/rfkill/Makefile +++++ b/net/rfkill/Makefile ++@@ -5,5 +5,5 @@ ++ ++ rfkill-y += core.o ++ rfkill-$(CONFIG_RFKILL_INPUT) += input.o ++-obj-$(CONFIG_RFKILL) += rfkill.o +++obj-$(CONFIG_RFKILL_FULL) += rfkill.o ++ obj-$(CONFIG_RFKILL_GPIO) += rfkill-gpio.o +diff --git a/target/linux/generic/hack-5.10/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch b/target/linux/generic/hack-5.10/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch +new file mode 100644 +index 0000000000..fe89de7e08 +--- /dev/null ++++ b/target/linux/generic/hack-5.10/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch +@@ -0,0 +1,64 @@ ++From: Ben Menchaca ++Date: Fri, 7 Jun 2013 18:35:22 -0500 ++Subject: MIPS: r4k_cache: use more efficient cache blast ++ ++Optimize the compiler output for larger cache blast cases that are ++common for DMA-based networking. ++ ++Signed-off-by: Ben Menchaca ++Signed-off-by: Felix Fietkau ++--- ++--- a/arch/mips/include/asm/r4kcache.h +++++ b/arch/mips/include/asm/r4kcache.h ++@@ -296,14 +296,46 @@ static inline void prot##extra##blast_## ++ unsigned long end) \ ++ { \ ++ unsigned long lsize = cpu_##desc##_line_size(); \ +++ unsigned long lsize_2 = lsize * 2; \ +++ unsigned long lsize_3 = lsize * 3; \ +++ unsigned long lsize_4 = lsize * 4; \ +++ unsigned long lsize_5 = lsize * 5; \ +++ unsigned long lsize_6 = lsize * 6; \ +++ unsigned long lsize_7 = lsize * 7; \ +++ unsigned long lsize_8 = lsize * 8; \ ++ unsigned long addr = start & ~(lsize - 1); \ ++- unsigned long aend = (end - 1) & ~(lsize - 1); \ +++ unsigned long aend = (end + lsize - 1) & ~(lsize - 1); \ +++ int lines = (aend - addr) / lsize; \ ++ \ ++- while (1) { \ +++ while (lines >= 8) { \ +++ prot##cache_op(hitop, addr); \ +++ prot##cache_op(hitop, addr + lsize); \ +++ prot##cache_op(hitop, addr + lsize_2); \ +++ prot##cache_op(hitop, addr + lsize_3); \ +++ prot##cache_op(hitop, addr + lsize_4); \ +++ prot##cache_op(hitop, addr + lsize_5); \ +++ prot##cache_op(hitop, addr + lsize_6); \ +++ prot##cache_op(hitop, addr + lsize_7); \ +++ addr += lsize_8; \ +++ lines -= 8; \ +++ } \ +++ \ +++ if (lines & 0x4) { \ +++ prot##cache_op(hitop, addr); \ +++ prot##cache_op(hitop, addr + lsize); \ +++ prot##cache_op(hitop, addr + lsize_2); \ +++ prot##cache_op(hitop, addr + lsize_3); \ +++ addr += lsize_4; \ +++ } \ +++ \ +++ if (lines & 0x2) { \ +++ prot##cache_op(hitop, addr); \ +++ prot##cache_op(hitop, addr + lsize); \ +++ addr += lsize_2; \ +++ } \ +++ \ +++ if (lines & 0x1) { \ ++ prot##cache_op(hitop, addr); \ ++- if (addr == aend) \ ++- break; \ ++- addr += lsize; \ ++ } \ ++ } ++ +diff --git a/target/linux/generic/hack-5.10/301-mips_image_cmdline_hack.patch b/target/linux/generic/hack-5.10/301-mips_image_cmdline_hack.patch +new file mode 100644 +index 0000000000..6c0828fa8a +--- /dev/null ++++ b/target/linux/generic/hack-5.10/301-mips_image_cmdline_hack.patch +@@ -0,0 +1,38 @@ ++From: John Crispin ++Subject: hack: kernel: add generic image_cmdline hack to MIPS targets ++ ++lede-commit: d59f5b3a987a48508257a0ddbaeadc7909f9f976 ++Signed-off-by: Gabor Juhos ++--- ++ arch/mips/Kconfig | 4 ++++ ++ arch/mips/kernel/head.S | 6 ++++++ ++ 2 files changed, 10 insertions(+) ++ ++--- a/arch/mips/Kconfig +++++ b/arch/mips/Kconfig ++@@ -1162,6 +1162,10 @@ config MIPS_MSC ++ config SYNC_R4K ++ bool ++ +++config IMAGE_CMDLINE_HACK +++ bool "OpenWrt specific image command line hack" +++ default n +++ ++ config NO_IOPORT_MAP ++ def_bool n ++ ++--- a/arch/mips/kernel/head.S +++++ b/arch/mips/kernel/head.S ++@@ -79,6 +79,12 @@ FEXPORT(__kernel_entry) ++ j kernel_entry ++ #endif /* CONFIG_BOOT_RAW */ ++ +++#ifdef CONFIG_IMAGE_CMDLINE_HACK +++ .ascii "CMDLINE:" +++EXPORT(__image_cmdline) +++ .fill 0x400 +++#endif /* CONFIG_IMAGE_CMDLINE_HACK */ +++ ++ __REF ++ ++ NESTED(kernel_entry, 16, sp) # kernel entry point +diff --git a/target/linux/generic/hack-5.10/321-powerpc_crtsavres_prereq.patch b/target/linux/generic/hack-5.10/321-powerpc_crtsavres_prereq.patch +new file mode 100644 +index 0000000000..4bb438295d +--- /dev/null ++++ b/target/linux/generic/hack-5.10/321-powerpc_crtsavres_prereq.patch +@@ -0,0 +1,38 @@ ++From 107c0964cb8db7ca28ac5199426414fdab3c274d Mon Sep 17 00:00:00 2001 ++From: "Alexandros C. Couloumbis" ++Date: Fri, 7 Jul 2017 17:14:51 +0200 ++Subject: hack: arch: powerpc: drop register save/restore library from modules ++ ++Upstream GCC uses a libgcc function for saving/restoring registers. This ++makes the code bigger, and upstream kernels need to carry that function ++for every single kernel module. Our GCC is patched to avoid those ++references, so we can drop the extra bloat for modules. ++ ++lede-commit: e8e1084654f50904e6bf77b70b2de3f137d7b3ec ++Signed-off-by: Alexandros C. Couloumbis ++--- ++ arch/powerpc/Makefile | 1 - ++ 1 file changed, 1 deletion(-) ++ ++--- a/arch/powerpc/Makefile +++++ b/arch/powerpc/Makefile ++@@ -61,19 +61,6 @@ machine-$(CONFIG_PPC64) += 64 ++ machine-$(CONFIG_CPU_LITTLE_ENDIAN) += le ++ UTS_MACHINE := $(subst $(space),,$(machine-y)) ++ ++-# XXX This needs to be before we override LD below ++-ifdef CONFIG_PPC32 ++-KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o ++-else ++-ifeq ($(call ld-ifversion, -ge, 225000000, y),y) ++-# Have the linker provide sfpr if possible. ++-# There is a corresponding test in arch/powerpc/lib/Makefile ++-KBUILD_LDFLAGS_MODULE += --save-restore-funcs ++-else ++-KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o ++-endif ++-endif ++- ++ ifdef CONFIG_CPU_LITTLE_ENDIAN ++ KBUILD_CFLAGS += -mlittle-endian ++ KBUILD_LDFLAGS += -EL +diff --git a/target/linux/generic/hack-5.10/531-debloat_lzma.patch b/target/linux/generic/hack-5.10/531-debloat_lzma.patch +new file mode 100644 +index 0000000000..0854872ffa +--- /dev/null ++++ b/target/linux/generic/hack-5.10/531-debloat_lzma.patch +@@ -0,0 +1,1037 @@ ++From 3fd297761ac246c54d7723c57fca95c112b99465 Mon Sep 17 00:00:00 2001 ++From: Felix Fietkau ++Date: Sat, 15 Jul 2017 21:15:44 +0200 ++Subject: lzma: de-bloat the lzma library used by jffs2 ++ ++lede-commit: 3fd1dd08fbcbb78b34efefd32c3032e5c99108d6 ++Signed-off-by: Felix Fietkau ++--- ++ include/linux/lzma/LzFind.h | 17 --- ++ include/linux/lzma/LzmaDec.h | 101 --------------- ++ include/linux/lzma/LzmaEnc.h | 20 --- ++ lib/lzma/LzFind.c | 287 ++++--------------------------------------- ++ lib/lzma/LzmaDec.c | 86 +------------ ++ lib/lzma/LzmaEnc.c | 172 ++------------------------ ++ 6 files changed, 42 insertions(+), 641 deletions(-) ++ ++--- a/include/linux/lzma/LzFind.h +++++ b/include/linux/lzma/LzFind.h ++@@ -55,11 +55,6 @@ typedef struct _CMatchFinder ++ ++ #define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) ++ ++-int MatchFinder_NeedMove(CMatchFinder *p); ++-Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); ++-void MatchFinder_MoveBlock(CMatchFinder *p); ++-void MatchFinder_ReadIfRequired(CMatchFinder *p); ++- ++ void MatchFinder_Construct(CMatchFinder *p); ++ ++ /* Conditions: ++@@ -70,12 +65,6 @@ int MatchFinder_Create(CMatchFinder *p, ++ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ++ ISzAlloc *alloc); ++ void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); ++-void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems); ++-void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); ++- ++-UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, ++- UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, ++- UInt32 *distances, UInt32 maxLen); ++ ++ /* ++ Conditions: ++@@ -102,12 +91,6 @@ typedef struct _IMatchFinder ++ ++ void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); ++ ++-void MatchFinder_Init(CMatchFinder *p); ++-UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); ++-UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); ++-void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); ++-void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); ++- ++ #ifdef __cplusplus ++ } ++ #endif ++--- a/include/linux/lzma/LzmaDec.h +++++ b/include/linux/lzma/LzmaDec.h ++@@ -31,14 +31,6 @@ typedef struct _CLzmaProps ++ UInt32 dicSize; ++ } CLzmaProps; ++ ++-/* LzmaProps_Decode - decodes properties ++-Returns: ++- SZ_OK ++- SZ_ERROR_UNSUPPORTED - Unsupported properties ++-*/ ++- ++-SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); ++- ++ ++ /* ---------- LZMA Decoder state ---------- */ ++ ++@@ -70,8 +62,6 @@ typedef struct ++ ++ #define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } ++ ++-void LzmaDec_Init(CLzmaDec *p); ++- ++ /* There are two types of LZMA streams: ++ 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. ++ 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ ++@@ -108,97 +98,6 @@ typedef enum ++ ++ /* ELzmaStatus is used only as output value for function call */ ++ ++- ++-/* ---------- Interfaces ---------- */ ++- ++-/* There are 3 levels of interfaces: ++- 1) Dictionary Interface ++- 2) Buffer Interface ++- 3) One Call Interface ++- You can select any of these interfaces, but don't mix functions from different ++- groups for same object. */ ++- ++- ++-/* There are two variants to allocate state for Dictionary Interface: ++- 1) LzmaDec_Allocate / LzmaDec_Free ++- 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs ++- You can use variant 2, if you set dictionary buffer manually. ++- For Buffer Interface you must always use variant 1. ++- ++-LzmaDec_Allocate* can return: ++- SZ_OK ++- SZ_ERROR_MEM - Memory allocation error ++- SZ_ERROR_UNSUPPORTED - Unsupported properties ++-*/ ++- ++-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); ++-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); ++- ++-SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); ++-void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); ++- ++-/* ---------- Dictionary Interface ---------- */ ++- ++-/* You can use it, if you want to eliminate the overhead for data copying from ++- dictionary to some other external buffer. ++- You must work with CLzmaDec variables directly in this interface. ++- ++- STEPS: ++- LzmaDec_Constr() ++- LzmaDec_Allocate() ++- for (each new stream) ++- { ++- LzmaDec_Init() ++- while (it needs more decompression) ++- { ++- LzmaDec_DecodeToDic() ++- use data from CLzmaDec::dic and update CLzmaDec::dicPos ++- } ++- } ++- LzmaDec_Free() ++-*/ ++- ++-/* LzmaDec_DecodeToDic ++- ++- The decoding to internal dictionary buffer (CLzmaDec::dic). ++- You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! ++- ++-finishMode: ++- It has meaning only if the decoding reaches output limit (dicLimit). ++- LZMA_FINISH_ANY - Decode just dicLimit bytes. ++- LZMA_FINISH_END - Stream must be finished after dicLimit. ++- ++-Returns: ++- SZ_OK ++- status: ++- LZMA_STATUS_FINISHED_WITH_MARK ++- LZMA_STATUS_NOT_FINISHED ++- LZMA_STATUS_NEEDS_MORE_INPUT ++- LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK ++- SZ_ERROR_DATA - Data error ++-*/ ++- ++-SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, ++- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); ++- ++- ++-/* ---------- Buffer Interface ---------- */ ++- ++-/* It's zlib-like interface. ++- See LzmaDec_DecodeToDic description for information about STEPS and return results, ++- but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need ++- to work with CLzmaDec variables manually. ++- ++-finishMode: ++- It has meaning only if the decoding reaches output limit (*destLen). ++- LZMA_FINISH_ANY - Decode just destLen bytes. ++- LZMA_FINISH_END - Stream must be finished after (*destLen). ++-*/ ++- ++-SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, ++- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); ++- ++- ++ /* ---------- One Call Interface ---------- */ ++ ++ /* LzmaDecode ++--- a/include/linux/lzma/LzmaEnc.h +++++ b/include/linux/lzma/LzmaEnc.h ++@@ -31,9 +31,6 @@ typedef struct _CLzmaEncProps ++ } CLzmaEncProps; ++ ++ void LzmaEncProps_Init(CLzmaEncProps *p); ++-void LzmaEncProps_Normalize(CLzmaEncProps *p); ++-UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); ++- ++ ++ /* ---------- CLzmaEncHandle Interface ---------- */ ++ ++@@ -53,26 +50,9 @@ CLzmaEncHandle LzmaEnc_Create(ISzAlloc * ++ void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); ++ SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); ++ SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); ++-SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, ++- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); ++ SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, ++ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); ++ ++-/* ---------- One Call Interface ---------- */ ++- ++-/* LzmaEncode ++-Return code: ++- SZ_OK - OK ++- SZ_ERROR_MEM - Memory allocation error ++- SZ_ERROR_PARAM - Incorrect paramater ++- SZ_ERROR_OUTPUT_EOF - output buffer overflow ++- SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) ++-*/ ++- ++-SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, ++- const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, ++- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); ++- ++ #ifdef __cplusplus ++ } ++ #endif ++--- a/lib/lzma/LzFind.c +++++ b/lib/lzma/LzFind.c ++@@ -14,9 +14,15 @@ ++ ++ #define kStartMaxLen 3 ++ +++#if 0 +++#define DIRECT_INPUT p->directInput +++#else +++#define DIRECT_INPUT 1 +++#endif +++ ++ static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) ++ { ++- if (!p->directInput) +++ if (!DIRECT_INPUT) ++ { ++ alloc->Free(alloc, p->bufferBase); ++ p->bufferBase = 0; ++@@ -28,7 +34,7 @@ static void LzInWindow_Free(CMatchFinder ++ static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) ++ { ++ UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; ++- if (p->directInput) +++ if (DIRECT_INPUT) ++ { ++ p->blockSize = blockSize; ++ return 1; ++@@ -42,12 +48,12 @@ static int LzInWindow_Create(CMatchFinde ++ return (p->bufferBase != 0); ++ } ++ ++-Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } ++-Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } +++static Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } +++static Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } ++ ++-UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } +++static UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } ++ ++-void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) +++static void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) ++ { ++ p->posLimit -= subValue; ++ p->pos -= subValue; ++@@ -58,7 +64,7 @@ static void MatchFinder_ReadBlock(CMatch ++ { ++ if (p->streamEndWasReached || p->result != SZ_OK) ++ return; ++- if (p->directInput) +++ if (DIRECT_INPUT) ++ { ++ UInt32 curSize = 0xFFFFFFFF - p->streamPos; ++ if (curSize > p->directInputRem) ++@@ -89,7 +95,7 @@ static void MatchFinder_ReadBlock(CMatch ++ } ++ } ++ ++-void MatchFinder_MoveBlock(CMatchFinder *p) +++static void MatchFinder_MoveBlock(CMatchFinder *p) ++ { ++ memmove(p->bufferBase, ++ p->buffer - p->keepSizeBefore, ++@@ -97,22 +103,14 @@ void MatchFinder_MoveBlock(CMatchFinder ++ p->buffer = p->bufferBase + p->keepSizeBefore; ++ } ++ ++-int MatchFinder_NeedMove(CMatchFinder *p) +++static int MatchFinder_NeedMove(CMatchFinder *p) ++ { ++- if (p->directInput) +++ if (DIRECT_INPUT) ++ return 0; ++ /* if (p->streamEndWasReached) return 0; */ ++ return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); ++ } ++ ++-void MatchFinder_ReadIfRequired(CMatchFinder *p) ++-{ ++- if (p->streamEndWasReached) ++- return; ++- if (p->keepSizeAfter >= p->streamPos - p->pos) ++- MatchFinder_ReadBlock(p); ++-} ++- ++ static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) ++ { ++ if (MatchFinder_NeedMove(p)) ++@@ -268,7 +266,7 @@ static void MatchFinder_SetLimits(CMatch ++ p->posLimit = p->pos + limit; ++ } ++ ++-void MatchFinder_Init(CMatchFinder *p) +++static void MatchFinder_Init(CMatchFinder *p) ++ { ++ UInt32 i; ++ for (i = 0; i < p->hashSizeSum; i++) ++@@ -287,7 +285,7 @@ static UInt32 MatchFinder_GetSubValue(CM ++ return (p->pos - p->historySize - 1) & kNormalizeMask; ++ } ++ ++-void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) +++static void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) ++ { ++ UInt32 i; ++ for (i = 0; i < numItems; i++) ++@@ -319,38 +317,7 @@ static void MatchFinder_CheckLimits(CMat ++ MatchFinder_SetLimits(p); ++ } ++ ++-static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, ++- UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, ++- UInt32 *distances, UInt32 maxLen) ++-{ ++- son[_cyclicBufferPos] = curMatch; ++- for (;;) ++- { ++- UInt32 delta = pos - curMatch; ++- if (cutValue-- == 0 || delta >= _cyclicBufferSize) ++- return distances; ++- { ++- const Byte *pb = cur - delta; ++- curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; ++- if (pb[maxLen] == cur[maxLen] && *pb == *cur) ++- { ++- UInt32 len = 0; ++- while (++len != lenLimit) ++- if (pb[len] != cur[len]) ++- break; ++- if (maxLen < len) ++- { ++- *distances++ = maxLen = len; ++- *distances++ = delta - 1; ++- if (len == lenLimit) ++- return distances; ++- } ++- } ++- } ++- } ++-} ++- ++-UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, +++static UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, ++ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, ++ UInt32 *distances, UInt32 maxLen) ++ { ++@@ -460,10 +427,10 @@ static void SkipMatchesSpec(UInt32 lenLi ++ p->buffer++; \ ++ if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p); ++ ++-#define MOVE_POS_RET MOVE_POS return offset; ++- ++ static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } ++ +++#define MOVE_POS_RET MatchFinder_MovePos(p); return offset; +++ ++ #define GET_MATCHES_HEADER2(minLen, ret_op) \ ++ UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \ ++ lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ ++@@ -479,62 +446,7 @@ static void MatchFinder_MovePos(CMatchFi ++ distances + offset, maxLen) - distances); MOVE_POS_RET; ++ ++ #define SKIP_FOOTER \ ++- SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; ++- ++-static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) ++-{ ++- UInt32 offset; ++- GET_MATCHES_HEADER(2) ++- HASH2_CALC; ++- curMatch = p->hash[hashValue]; ++- p->hash[hashValue] = p->pos; ++- offset = 0; ++- GET_MATCHES_FOOTER(offset, 1) ++-} ++- ++-UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) ++-{ ++- UInt32 offset; ++- GET_MATCHES_HEADER(3) ++- HASH_ZIP_CALC; ++- curMatch = p->hash[hashValue]; ++- p->hash[hashValue] = p->pos; ++- offset = 0; ++- GET_MATCHES_FOOTER(offset, 2) ++-} ++- ++-static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) ++-{ ++- UInt32 hash2Value, delta2, maxLen, offset; ++- GET_MATCHES_HEADER(3) ++- ++- HASH3_CALC; ++- ++- delta2 = p->pos - p->hash[hash2Value]; ++- curMatch = p->hash[kFix3HashSize + hashValue]; ++- ++- p->hash[hash2Value] = ++- p->hash[kFix3HashSize + hashValue] = p->pos; ++- ++- ++- maxLen = 2; ++- offset = 0; ++- if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) ++- { ++- for (; maxLen != lenLimit; maxLen++) ++- if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) ++- break; ++- distances[0] = maxLen; ++- distances[1] = delta2 - 1; ++- offset = 2; ++- if (maxLen == lenLimit) ++- { ++- SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); ++- MOVE_POS_RET; ++- } ++- } ++- GET_MATCHES_FOOTER(offset, maxLen) ++-} +++ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MatchFinder_MovePos(p); ++ ++ static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) ++ { ++@@ -583,108 +495,6 @@ static UInt32 Bt4_MatchFinder_GetMatches ++ GET_MATCHES_FOOTER(offset, maxLen) ++ } ++ ++-static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) ++-{ ++- UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; ++- GET_MATCHES_HEADER(4) ++- ++- HASH4_CALC; ++- ++- delta2 = p->pos - p->hash[ hash2Value]; ++- delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; ++- curMatch = p->hash[kFix4HashSize + hashValue]; ++- ++- p->hash[ hash2Value] = ++- p->hash[kFix3HashSize + hash3Value] = ++- p->hash[kFix4HashSize + hashValue] = p->pos; ++- ++- maxLen = 1; ++- offset = 0; ++- if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) ++- { ++- distances[0] = maxLen = 2; ++- distances[1] = delta2 - 1; ++- offset = 2; ++- } ++- if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) ++- { ++- maxLen = 3; ++- distances[offset + 1] = delta3 - 1; ++- offset += 2; ++- delta2 = delta3; ++- } ++- if (offset != 0) ++- { ++- for (; maxLen != lenLimit; maxLen++) ++- if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) ++- break; ++- distances[offset - 2] = maxLen; ++- if (maxLen == lenLimit) ++- { ++- p->son[p->cyclicBufferPos] = curMatch; ++- MOVE_POS_RET; ++- } ++- } ++- if (maxLen < 3) ++- maxLen = 3; ++- offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), ++- distances + offset, maxLen) - (distances)); ++- MOVE_POS_RET ++-} ++- ++-UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) ++-{ ++- UInt32 offset; ++- GET_MATCHES_HEADER(3) ++- HASH_ZIP_CALC; ++- curMatch = p->hash[hashValue]; ++- p->hash[hashValue] = p->pos; ++- offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), ++- distances, 2) - (distances)); ++- MOVE_POS_RET ++-} ++- ++-static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) ++-{ ++- do ++- { ++- SKIP_HEADER(2) ++- HASH2_CALC; ++- curMatch = p->hash[hashValue]; ++- p->hash[hashValue] = p->pos; ++- SKIP_FOOTER ++- } ++- while (--num != 0); ++-} ++- ++-void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) ++-{ ++- do ++- { ++- SKIP_HEADER(3) ++- HASH_ZIP_CALC; ++- curMatch = p->hash[hashValue]; ++- p->hash[hashValue] = p->pos; ++- SKIP_FOOTER ++- } ++- while (--num != 0); ++-} ++- ++-static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) ++-{ ++- do ++- { ++- UInt32 hash2Value; ++- SKIP_HEADER(3) ++- HASH3_CALC; ++- curMatch = p->hash[kFix3HashSize + hashValue]; ++- p->hash[hash2Value] = ++- p->hash[kFix3HashSize + hashValue] = p->pos; ++- SKIP_FOOTER ++- } ++- while (--num != 0); ++-} ++- ++ static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) ++ { ++ do ++@@ -701,61 +511,12 @@ static void Bt4_MatchFinder_Skip(CMatchF ++ while (--num != 0); ++ } ++ ++-static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) ++-{ ++- do ++- { ++- UInt32 hash2Value, hash3Value; ++- SKIP_HEADER(4) ++- HASH4_CALC; ++- curMatch = p->hash[kFix4HashSize + hashValue]; ++- p->hash[ hash2Value] = ++- p->hash[kFix3HashSize + hash3Value] = ++- p->hash[kFix4HashSize + hashValue] = p->pos; ++- p->son[p->cyclicBufferPos] = curMatch; ++- MOVE_POS ++- } ++- while (--num != 0); ++-} ++- ++-void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) ++-{ ++- do ++- { ++- SKIP_HEADER(3) ++- HASH_ZIP_CALC; ++- curMatch = p->hash[hashValue]; ++- p->hash[hashValue] = p->pos; ++- p->son[p->cyclicBufferPos] = curMatch; ++- MOVE_POS ++- } ++- while (--num != 0); ++-} ++- ++ void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) ++ { ++ vTable->Init = (Mf_Init_Func)MatchFinder_Init; ++ vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte; ++ vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; ++ vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; ++- if (!p->btMode) ++- { ++- vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; ++- vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; ++- } ++- else if (p->numHashBytes == 2) ++- { ++- vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches; ++- vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip; ++- } ++- else if (p->numHashBytes == 3) ++- { ++- vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; ++- vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; ++- } ++- else ++- { ++- vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; ++- vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; ++- } +++ vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; +++ vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; ++ } ++--- a/lib/lzma/LzmaDec.c +++++ b/lib/lzma/LzmaDec.c ++@@ -682,7 +682,7 @@ static void LzmaDec_InitRc(CLzmaDec *p, ++ p->needFlush = 0; ++ } ++ ++-void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) +++static void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) ++ { ++ p->needFlush = 1; ++ p->remainLen = 0; ++@@ -698,7 +698,7 @@ void LzmaDec_InitDicAndState(CLzmaDec *p ++ p->needInitState = 1; ++ } ++ ++-void LzmaDec_Init(CLzmaDec *p) +++static void LzmaDec_Init(CLzmaDec *p) ++ { ++ p->dicPos = 0; ++ LzmaDec_InitDicAndState(p, True, True); ++@@ -716,7 +716,7 @@ static void LzmaDec_InitStateReal(CLzmaD ++ p->needInitState = 0; ++ } ++ ++-SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, +++static SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, ++ ELzmaFinishMode finishMode, ELzmaStatus *status) ++ { ++ SizeT inSize = *srcLen; ++@@ -837,65 +837,13 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, Si ++ return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; ++ } ++ ++-SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) ++-{ ++- SizeT outSize = *destLen; ++- SizeT inSize = *srcLen; ++- *srcLen = *destLen = 0; ++- for (;;) ++- { ++- SizeT inSizeCur = inSize, outSizeCur, dicPos; ++- ELzmaFinishMode curFinishMode; ++- SRes res; ++- if (p->dicPos == p->dicBufSize) ++- p->dicPos = 0; ++- dicPos = p->dicPos; ++- if (outSize > p->dicBufSize - dicPos) ++- { ++- outSizeCur = p->dicBufSize; ++- curFinishMode = LZMA_FINISH_ANY; ++- } ++- else ++- { ++- outSizeCur = dicPos + outSize; ++- curFinishMode = finishMode; ++- } ++- ++- res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); ++- src += inSizeCur; ++- inSize -= inSizeCur; ++- *srcLen += inSizeCur; ++- outSizeCur = p->dicPos - dicPos; ++- memcpy(dest, p->dic + dicPos, outSizeCur); ++- dest += outSizeCur; ++- outSize -= outSizeCur; ++- *destLen += outSizeCur; ++- if (res != 0) ++- return res; ++- if (outSizeCur == 0 || outSize == 0) ++- return SZ_OK; ++- } ++-} ++- ++-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) +++static void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) ++ { ++ alloc->Free(alloc, p->probs); ++ p->probs = 0; ++ } ++ ++-static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) ++-{ ++- alloc->Free(alloc, p->dic); ++- p->dic = 0; ++-} ++- ++-void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) ++-{ ++- LzmaDec_FreeProbs(p, alloc); ++- LzmaDec_FreeDict(p, alloc); ++-} ++- ++-SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) +++static SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) ++ { ++ UInt32 dicSize; ++ Byte d; ++@@ -935,33 +883,11 @@ static SRes LzmaDec_AllocateProbs2(CLzma ++ return SZ_OK; ++ } ++ ++-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) ++-{ ++- CLzmaProps propNew; ++- RINOK(LzmaProps_Decode(&propNew, props, propsSize)); ++- RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); ++- p->prop = propNew; ++- return SZ_OK; ++-} ++- ++-SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) +++static SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) ++ { ++ CLzmaProps propNew; ++- SizeT dicBufSize; ++ RINOK(LzmaProps_Decode(&propNew, props, propsSize)); ++ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); ++- dicBufSize = propNew.dicSize; ++- if (p->dic == 0 || dicBufSize != p->dicBufSize) ++- { ++- LzmaDec_FreeDict(p, alloc); ++- p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); ++- if (p->dic == 0) ++- { ++- LzmaDec_FreeProbs(p, alloc); ++- return SZ_ERROR_MEM; ++- } ++- } ++- p->dicBufSize = dicBufSize; ++ p->prop = propNew; ++ return SZ_OK; ++ } ++--- a/lib/lzma/LzmaEnc.c +++++ b/lib/lzma/LzmaEnc.c ++@@ -53,7 +53,7 @@ void LzmaEncProps_Init(CLzmaEncProps *p) ++ p->writeEndMark = 0; ++ } ++ ++-void LzmaEncProps_Normalize(CLzmaEncProps *p) +++static void LzmaEncProps_Normalize(CLzmaEncProps *p) ++ { ++ int level = p->level; ++ if (level < 0) level = 5; ++@@ -76,7 +76,7 @@ void LzmaEncProps_Normalize(CLzmaEncProp ++ #endif ++ } ++ ++-UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) +++static UInt32 __maybe_unused LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) ++ { ++ CLzmaEncProps props = *props2; ++ LzmaEncProps_Normalize(&props); ++@@ -93,7 +93,7 @@ UInt32 LzmaEncProps_GetDictSize(const CL ++ ++ #define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } ++ ++-UInt32 GetPosSlot1(UInt32 pos) +++static UInt32 GetPosSlot1(UInt32 pos) ++ { ++ UInt32 res; ++ BSR2_RET(pos, res); ++@@ -107,7 +107,7 @@ UInt32 GetPosSlot1(UInt32 pos) ++ #define kNumLogBits (9 + (int)sizeof(size_t) / 2) ++ #define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) ++ ++-void LzmaEnc_FastPosInit(Byte *g_FastPos) +++static void LzmaEnc_FastPosInit(Byte *g_FastPos) ++ { ++ int c = 2, slotFast; ++ g_FastPos[0] = 0; ++@@ -339,58 +339,6 @@ typedef struct ++ CSaveState saveState; ++ } CLzmaEnc; ++ ++-void LzmaEnc_SaveState(CLzmaEncHandle pp) ++-{ ++- CLzmaEnc *p = (CLzmaEnc *)pp; ++- CSaveState *dest = &p->saveState; ++- int i; ++- dest->lenEnc = p->lenEnc; ++- dest->repLenEnc = p->repLenEnc; ++- dest->state = p->state; ++- ++- for (i = 0; i < kNumStates; i++) ++- { ++- memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); ++- memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); ++- } ++- for (i = 0; i < kNumLenToPosStates; i++) ++- memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); ++- memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); ++- memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); ++- memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); ++- memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); ++- memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); ++- memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); ++- memcpy(dest->reps, p->reps, sizeof(p->reps)); ++- memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb)); ++-} ++- ++-void LzmaEnc_RestoreState(CLzmaEncHandle pp) ++-{ ++- CLzmaEnc *dest = (CLzmaEnc *)pp; ++- const CSaveState *p = &dest->saveState; ++- int i; ++- dest->lenEnc = p->lenEnc; ++- dest->repLenEnc = p->repLenEnc; ++- dest->state = p->state; ++- ++- for (i = 0; i < kNumStates; i++) ++- { ++- memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); ++- memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); ++- } ++- for (i = 0; i < kNumLenToPosStates; i++) ++- memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); ++- memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); ++- memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); ++- memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); ++- memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); ++- memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); ++- memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); ++- memcpy(dest->reps, p->reps, sizeof(p->reps)); ++- memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb)); ++-} ++- ++ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) ++ { ++ CLzmaEnc *p = (CLzmaEnc *)pp; ++@@ -600,7 +548,7 @@ static void LitEnc_EncodeMatched(CRangeE ++ while (symbol < 0x10000); ++ } ++ ++-void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) +++static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) ++ { ++ UInt32 i; ++ for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) ++@@ -1676,7 +1624,7 @@ static void FillDistancesPrices(CLzmaEnc ++ p->matchPriceCount = 0; ++ } ++ ++-void LzmaEnc_Construct(CLzmaEnc *p) +++static void LzmaEnc_Construct(CLzmaEnc *p) ++ { ++ RangeEnc_Construct(&p->rc); ++ MatchFinder_Construct(&p->matchFinderBase); ++@@ -1709,7 +1657,7 @@ CLzmaEncHandle LzmaEnc_Create(ISzAlloc * ++ return p; ++ } ++ ++-void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) +++static void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) ++ { ++ alloc->Free(alloc, p->litProbs); ++ alloc->Free(alloc, p->saveState.litProbs); ++@@ -1717,7 +1665,7 @@ void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAl ++ p->saveState.litProbs = 0; ++ } ++ ++-void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) +++static void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) ++ { ++ #ifndef _7ZIP_ST ++ MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); ++@@ -1947,7 +1895,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, U ++ return SZ_OK; ++ } ++ ++-void LzmaEnc_Init(CLzmaEnc *p) +++static void LzmaEnc_Init(CLzmaEnc *p) ++ { ++ UInt32 i; ++ p->state = 0; ++@@ -2005,7 +1953,7 @@ void LzmaEnc_Init(CLzmaEnc *p) ++ p->lpMask = (1 << p->lp) - 1; ++ } ++ ++-void LzmaEnc_InitPrices(CLzmaEnc *p) +++static void LzmaEnc_InitPrices(CLzmaEnc *p) ++ { ++ if (!p->fastMode) ++ { ++@@ -2037,26 +1985,6 @@ static SRes LzmaEnc_AllocAndInit(CLzmaEn ++ return SZ_OK; ++ } ++ ++-static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ++- ISzAlloc *alloc, ISzAlloc *allocBig) ++-{ ++- CLzmaEnc *p = (CLzmaEnc *)pp; ++- p->matchFinderBase.stream = inStream; ++- p->needInit = 1; ++- p->rc.outStream = outStream; ++- return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); ++-} ++- ++-SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, ++- ISeqInStream *inStream, UInt32 keepWindowSize, ++- ISzAlloc *alloc, ISzAlloc *allocBig) ++-{ ++- CLzmaEnc *p = (CLzmaEnc *)pp; ++- p->matchFinderBase.stream = inStream; ++- p->needInit = 1; ++- return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); ++-} ++- ++ static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) ++ { ++ p->matchFinderBase.directInput = 1; ++@@ -2064,7 +1992,7 @@ static void LzmaEnc_SetInputBuf(CLzmaEnc ++ p->matchFinderBase.directInputRem = srcLen; ++ } ++ ++-SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, +++static SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, ++ UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) ++ { ++ CLzmaEnc *p = (CLzmaEnc *)pp; ++@@ -2074,7 +2002,7 @@ SRes LzmaEnc_MemPrepare(CLzmaEncHandle p ++ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); ++ } ++ ++-void LzmaEnc_Finish(CLzmaEncHandle pp) +++static void LzmaEnc_Finish(CLzmaEncHandle pp) ++ { ++ #ifndef _7ZIP_ST ++ CLzmaEnc *p = (CLzmaEnc *)pp; ++@@ -2107,53 +2035,6 @@ static size_t MyWrite(void *pp, const vo ++ return size; ++ } ++ ++- ++-UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) ++-{ ++- const CLzmaEnc *p = (CLzmaEnc *)pp; ++- return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); ++-} ++- ++-const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) ++-{ ++- const CLzmaEnc *p = (CLzmaEnc *)pp; ++- return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; ++-} ++- ++-SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, ++- Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) ++-{ ++- CLzmaEnc *p = (CLzmaEnc *)pp; ++- UInt64 nowPos64; ++- SRes res; ++- CSeqOutStreamBuf outStream; ++- ++- outStream.funcTable.Write = MyWrite; ++- outStream.data = dest; ++- outStream.rem = *destLen; ++- outStream.overflow = False; ++- ++- p->writeEndMark = False; ++- p->finished = False; ++- p->result = SZ_OK; ++- ++- if (reInit) ++- LzmaEnc_Init(p); ++- LzmaEnc_InitPrices(p); ++- nowPos64 = p->nowPos64; ++- RangeEnc_Init(&p->rc); ++- p->rc.outStream = &outStream.funcTable; ++- ++- res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize); ++- ++- *unpackSize = (UInt32)(p->nowPos64 - nowPos64); ++- *destLen -= outStream.rem; ++- if (outStream.overflow) ++- return SZ_ERROR_OUTPUT_EOF; ++- ++- return res; ++-} ++- ++ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) ++ { ++ SRes res = SZ_OK; ++@@ -2184,13 +2065,6 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ++ return res; ++ } ++ ++-SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, ++- ISzAlloc *alloc, ISzAlloc *allocBig) ++-{ ++- RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig)); ++- return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); ++-} ++- ++ SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) ++ { ++ CLzmaEnc *p = (CLzmaEnc *)pp; ++@@ -2247,25 +2121,3 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp ++ return SZ_ERROR_OUTPUT_EOF; ++ return res; ++ } ++- ++-SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, ++- const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, ++- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) ++-{ ++- CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); ++- SRes res; ++- if (p == 0) ++- return SZ_ERROR_MEM; ++- ++- res = LzmaEnc_SetProps(p, props); ++- if (res == SZ_OK) ++- { ++- res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); ++- if (res == SZ_OK) ++- res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, ++- writeEndMark, progress, alloc, allocBig); ++- } ++- ++- LzmaEnc_Destroy(p, alloc, allocBig); ++- return res; ++-} +diff --git a/target/linux/generic/hack-5.10/640-bridge-only-accept-EAP-locally.patch b/target/linux/generic/hack-5.10/640-bridge-only-accept-EAP-locally.patch +new file mode 100644 +index 0000000000..d8e5f2fc9b +--- /dev/null ++++ b/target/linux/generic/hack-5.10/640-bridge-only-accept-EAP-locally.patch +@@ -0,0 +1,82 @@ ++From: Felix Fietkau ++Date: Fri, 7 Jul 2017 17:18:54 +0200 ++Subject: bridge: only accept EAP locally ++ ++When bridging, do not forward EAP frames to other ports, only deliver ++them locally, regardless of the state. ++ ++Signed-off-by: Felix Fietkau ++[add disable_eap_hack sysfs attribute] ++Signed-off-by: Etienne Champetier ++--- ++ ++--- a/net/bridge/br_input.c +++++ b/net/bridge/br_input.c ++@@ -107,10 +107,14 @@ int br_handle_frame_finish(struct net *n ++ } ++ } ++ +++ BR_INPUT_SKB_CB(skb)->brdev = br->dev; +++ +++ if (skb->protocol == htons(ETH_P_PAE) && !br->disable_eap_hack) +++ return br_pass_frame_up(skb); +++ ++ if (state == BR_STATE_LEARNING) ++ goto drop; ++ ++- BR_INPUT_SKB_CB(skb)->brdev = br->dev; ++ BR_INPUT_SKB_CB(skb)->src_port_isolated = !!(p->flags & BR_ISOLATED); ++ ++ if (IS_ENABLED(CONFIG_INET) && ++--- a/net/bridge/br_private.h +++++ b/net/bridge/br_private.h ++@@ -404,6 +404,8 @@ struct net_bridge { ++ u16 group_fwd_mask; ++ u16 group_fwd_mask_required; ++ +++ bool disable_eap_hack; +++ ++ /* STP */ ++ bridge_id designated_root; ++ bridge_id bridge_id; ++--- a/net/bridge/br_sysfs_br.c +++++ b/net/bridge/br_sysfs_br.c ++@@ -164,6 +164,30 @@ static ssize_t group_fwd_mask_store(stru ++ } ++ static DEVICE_ATTR_RW(group_fwd_mask); ++ +++static ssize_t disable_eap_hack_show(struct device *d, +++ struct device_attribute *attr, +++ char *buf) +++{ +++ struct net_bridge *br = to_bridge(d); +++ return sprintf(buf, "%u\n", br->disable_eap_hack); +++} +++ +++static int set_disable_eap_hack(struct net_bridge *br, unsigned long val) +++{ +++ br->disable_eap_hack = !!val; +++ +++ return 0; +++} +++ +++static ssize_t disable_eap_hack_store(struct device *d, +++ struct device_attribute *attr, +++ const char *buf, +++ size_t len) +++{ +++ return store_bridge_parm(d, buf, len, set_disable_eap_hack); +++} +++static DEVICE_ATTR_RW(disable_eap_hack); +++ ++ static ssize_t priority_show(struct device *d, struct device_attribute *attr, ++ char *buf) ++ { ++@@ -849,6 +873,7 @@ static struct attribute *bridge_attrs[] ++ &dev_attr_ageing_time.attr, ++ &dev_attr_stp_state.attr, ++ &dev_attr_group_fwd_mask.attr, +++ &dev_attr_disable_eap_hack.attr, ++ &dev_attr_priority.attr, ++ &dev_attr_bridge_id.attr, ++ &dev_attr_root_id.attr, +diff --git a/target/linux/generic/hack-5.10/645-netfilter-connmark-introduce-set-dscpmark.patch b/target/linux/generic/hack-5.10/645-netfilter-connmark-introduce-set-dscpmark.patch +new file mode 100644 +index 0000000000..2d3fe01a75 +--- /dev/null ++++ b/target/linux/generic/hack-5.10/645-netfilter-connmark-introduce-set-dscpmark.patch +@@ -0,0 +1,212 @@ ++From eda40b8c8c82e0f2789d6bc8bf63846dce2e8f32 Mon Sep 17 00:00:00 2001 ++From: Kevin Darbyshire-Bryant ++Date: Sat, 23 Mar 2019 09:29:49 +0000 ++Subject: [PATCH] netfilter: connmark: introduce set-dscpmark ++ ++set-dscpmark is a method of storing the DSCP of an ip packet into ++conntrack mark. In combination with a suitable tc filter action ++(act_ctinfo) DSCP values are able to be stored in the mark on egress and ++restored on ingress across links that otherwise alter or bleach DSCP. ++ ++This is useful for qdiscs such as CAKE which are able to shape according ++to policies based on DSCP. ++ ++Ingress classification is traditionally a challenging task since ++iptables rules haven't yet run and tc filter/eBPF programs are pre-NAT ++lookups, hence are unable to see internal IPv4 addresses as used on the ++typical home masquerading gateway. ++ ++x_tables CONNMARK set-dscpmark target solves the problem of storing the ++DSCP to the conntrack mark in a way suitable for the new act_ctinfo tc ++action to restore. ++ ++The set-dscpmark option accepts 2 parameters, a 32bit 'dscpmask' and a ++32bit 'statemask'. The dscp mask must be 6 contiguous bits and ++represents the area where the DSCP will be stored in the connmark. The ++state mask is a minimum 1 bit length mask that must not overlap with the ++dscpmask. It represents a flag which is set when the DSCP has been ++stored in the conntrack mark. This is useful to implement a 'one shot' ++iptables based classification where the 'complicated' iptables rules are ++only run once to classify the connection on initial (egress) packet and ++subsequent packets are all marked/restored with the same DSCP. A state ++mask of zero disables the setting of a status bit/s. ++ ++example syntax with a suitably modified iptables user space application: ++ ++iptables -A QOS_MARK_eth0 -t mangle -j CONNMARK --set-dscpmark 0xfc000000/0x01000000 ++ ++Would store the DSCP in the top 6 bits of the 32bit mark field, and use ++the LSB of the top byte as the 'DSCP has been stored' marker. ++ ++|----0xFC----conntrack mark----000000---| ++| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0| ++| DSCP | unused | flag |unused | ++|-----------------------0x01---000000---| ++ ^ ^ ++ | | ++ ---| Conditional flag ++ | set this when dscp ++|-ip diffserv-| stored in mark ++| 6 bits | ++|-------------| ++ ++an identically configured tc action to restore looks like: ++ ++tc filter show dev eth0 ingress ++filter parent ffff: protocol all pref 10 u32 chain 0 ++filter parent ffff: protocol all pref 10 u32 chain 0 fh 800: ht divisor 1 ++filter parent ffff: protocol all pref 10 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1: not_in_hw ++ match 00000000/00000000 at 0 ++ action order 1: ctinfo zone 0 pipe ++ index 2 ref 1 bind 1 dscp 0xfc000000/0x1000000 ++ ++ action order 2: mirred (Egress Redirect to device ifb4eth0) stolen ++ index 1 ref 1 bind 1 ++ ++|----0xFC----conntrack mark----000000---| ++| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0| ++| DSCP | unused | flag |unused | ++|-----------------------0x01---000000---| ++ | | ++ | | ++ ---| Conditional flag ++ v only restore if set ++|-ip diffserv-| ++| 6 bits | ++|-------------| ++ ++Signed-off-by: Kevin Darbyshire-Bryant ++--- ++ include/uapi/linux/netfilter/xt_connmark.h | 10 ++++ ++ net/netfilter/xt_connmark.c | 55 ++++++++++++++++++---- ++ 2 files changed, 57 insertions(+), 8 deletions(-) ++ ++--- a/include/uapi/linux/netfilter/xt_connmark.h +++++ b/include/uapi/linux/netfilter/xt_connmark.h ++@@ -20,6 +20,11 @@ enum { ++ }; ++ ++ enum { +++ XT_CONNMARK_VALUE = (1 << 0), +++ XT_CONNMARK_DSCP = (1 << 1) +++}; +++ +++enum { ++ D_SHIFT_LEFT = 0, ++ D_SHIFT_RIGHT, ++ }; ++@@ -34,6 +39,11 @@ struct xt_connmark_tginfo2 { ++ __u8 shift_dir, shift_bits, mode; ++ }; ++ +++struct xt_connmark_tginfo3 { +++ __u32 ctmark, ctmask, nfmask; +++ __u8 shift_dir, shift_bits, mode, func; +++}; +++ ++ struct xt_connmark_mtinfo1 { ++ __u32 mark, mask; ++ __u8 invert; ++--- a/net/netfilter/xt_connmark.c +++++ b/net/netfilter/xt_connmark.c ++@@ -24,12 +24,13 @@ MODULE_ALIAS("ipt_connmark"); ++ MODULE_ALIAS("ip6t_connmark"); ++ ++ static unsigned int ++-connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info) +++connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo3 *info) ++ { ++ enum ip_conntrack_info ctinfo; ++ u_int32_t new_targetmark; ++ struct nf_conn *ct; ++ u_int32_t newmark; +++ u_int8_t dscp; ++ ++ ct = nf_ct_get(skb, &ctinfo); ++ if (ct == NULL) ++@@ -37,12 +38,24 @@ connmark_tg_shift(struct sk_buff *skb, c ++ ++ switch (info->mode) { ++ case XT_CONNMARK_SET: ++- newmark = (ct->mark & ~info->ctmask) ^ info->ctmark; ++- if (info->shift_dir == D_SHIFT_RIGHT) ++- newmark >>= info->shift_bits; ++- else ++- newmark <<= info->shift_bits; +++ newmark = ct->mark; +++ if (info->func & XT_CONNMARK_VALUE) { +++ newmark = (newmark & ~info->ctmask) ^ info->ctmark; +++ if (info->shift_dir == D_SHIFT_RIGHT) +++ newmark >>= info->shift_bits; +++ else +++ newmark <<= info->shift_bits; +++ } else if (info->func & XT_CONNMARK_DSCP) { +++ if (skb->protocol == htons(ETH_P_IP)) +++ dscp = ipv4_get_dsfield(ip_hdr(skb)) >> 2; +++ else if (skb->protocol == htons(ETH_P_IPV6)) +++ dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> 2; +++ else /* protocol doesn't have diffserv */ +++ break; ++ +++ newmark = (newmark & ~info->ctmark) | +++ (info->ctmask | (dscp << info->shift_bits)); +++ } ++ if (ct->mark != newmark) { ++ ct->mark = newmark; ++ nf_conntrack_event_cache(IPCT_MARK, ct); ++@@ -81,20 +94,36 @@ static unsigned int ++ connmark_tg(struct sk_buff *skb, const struct xt_action_param *par) ++ { ++ const struct xt_connmark_tginfo1 *info = par->targinfo; ++- const struct xt_connmark_tginfo2 info2 = { +++ const struct xt_connmark_tginfo3 info3 = { ++ .ctmark = info->ctmark, ++ .ctmask = info->ctmask, ++ .nfmask = info->nfmask, ++ .mode = info->mode, +++ .func = XT_CONNMARK_VALUE ++ }; ++ ++- return connmark_tg_shift(skb, &info2); +++ return connmark_tg_shift(skb, &info3); ++ } ++ ++ static unsigned int ++ connmark_tg_v2(struct sk_buff *skb, const struct xt_action_param *par) ++ { ++ const struct xt_connmark_tginfo2 *info = par->targinfo; +++ const struct xt_connmark_tginfo3 info3 = { +++ .ctmark = info->ctmark, +++ .ctmask = info->ctmask, +++ .nfmask = info->nfmask, +++ .mode = info->mode, +++ .func = XT_CONNMARK_VALUE +++ }; +++ +++ return connmark_tg_shift(skb, &info3); +++} +++ +++static unsigned int +++connmark_tg_v3(struct sk_buff *skb, const struct xt_action_param *par) +++{ +++ const struct xt_connmark_tginfo3 *info = par->targinfo; ++ ++ return connmark_tg_shift(skb, info); ++ } ++@@ -165,6 +194,16 @@ static struct xt_target connmark_tg_reg[ ++ .targetsize = sizeof(struct xt_connmark_tginfo2), ++ .destroy = connmark_tg_destroy, ++ .me = THIS_MODULE, +++ }, +++ { +++ .name = "CONNMARK", +++ .revision = 3, +++ .family = NFPROTO_UNSPEC, +++ .checkentry = connmark_tg_check, +++ .target = connmark_tg_v3, +++ .targetsize = sizeof(struct xt_connmark_tginfo3), +++ .destroy = connmark_tg_destroy, +++ .me = THIS_MODULE, ++ } ++ }; ++ +diff --git a/target/linux/generic/hack-5.10/650-netfilter-add-xt_OFFLOAD-target.patch b/target/linux/generic/hack-5.10/650-netfilter-add-xt_OFFLOAD-target.patch +new file mode 100644 +index 0000000000..eb540acc85 +--- /dev/null ++++ b/target/linux/generic/hack-5.10/650-netfilter-add-xt_OFFLOAD-target.patch +@@ -0,0 +1,822 @@ ++From: Felix Fietkau ++Date: Tue, 20 Feb 2018 15:56:02 +0100 ++Subject: [PATCH] netfilter: add xt_OFFLOAD target ++ ++Signed-off-by: Felix Fietkau ++--- ++ create mode 100644 net/netfilter/xt_OFFLOAD.c ++ ++--- a/net/ipv4/netfilter/Kconfig +++++ b/net/ipv4/netfilter/Kconfig ++@@ -56,8 +56,6 @@ config NF_TABLES_ARP ++ help ++ This option enables the ARP support for nf_tables. ++ ++-endif # NF_TABLES ++- ++ config NF_FLOW_TABLE_IPV4 ++ tristate "Netfilter flow table IPv4 module" ++ depends on NF_FLOW_TABLE ++@@ -66,6 +64,8 @@ config NF_FLOW_TABLE_IPV4 ++ ++ To compile it as a module, choose M here. ++ +++endif # NF_TABLES +++ ++ config NF_DUP_IPV4 ++ tristate "Netfilter IPv4 packet duplication to alternate destination" ++ depends on !NF_CONNTRACK || NF_CONNTRACK ++--- a/net/ipv6/netfilter/Kconfig +++++ b/net/ipv6/netfilter/Kconfig ++@@ -45,7 +45,6 @@ config NFT_FIB_IPV6 ++ multicast or blackhole. ++ ++ endif # NF_TABLES_IPV6 ++-endif # NF_TABLES ++ ++ config NF_FLOW_TABLE_IPV6 ++ tristate "Netfilter flow table IPv6 module" ++@@ -55,6 +54,8 @@ config NF_FLOW_TABLE_IPV6 ++ ++ To compile it as a module, choose M here. ++ +++endif # NF_TABLES +++ ++ config NF_DUP_IPV6 ++ tristate "Netfilter IPv6 packet duplication to alternate destination" ++ depends on !NF_CONNTRACK || NF_CONNTRACK ++--- a/net/netfilter/Kconfig +++++ b/net/netfilter/Kconfig ++@@ -683,8 +683,6 @@ config NFT_FIB_NETDEV ++ ++ endif # NF_TABLES_NETDEV ++ ++-endif # NF_TABLES ++- ++ config NF_FLOW_TABLE_INET ++ tristate "Netfilter flow table mixed IPv4/IPv6 module" ++ depends on NF_FLOW_TABLE ++@@ -693,11 +691,12 @@ config NF_FLOW_TABLE_INET ++ ++ To compile it as a module, choose M here. ++ +++endif # NF_TABLES +++ ++ config NF_FLOW_TABLE ++ tristate "Netfilter flow table module" ++ depends on NETFILTER_INGRESS ++ depends on NF_CONNTRACK ++- depends on NF_TABLES ++ help ++ This option adds the flow table core infrastructure. ++ ++@@ -977,6 +976,15 @@ config NETFILTER_XT_TARGET_NOTRACK ++ depends on NETFILTER_ADVANCED ++ select NETFILTER_XT_TARGET_CT ++ +++config NETFILTER_XT_TARGET_FLOWOFFLOAD +++ tristate '"FLOWOFFLOAD" target support' +++ depends on NF_FLOW_TABLE +++ depends on NETFILTER_INGRESS +++ help +++ This option adds a `FLOWOFFLOAD' target, which uses the nf_flow_offload +++ module to speed up processing of packets by bypassing the usual +++ netfilter chains +++ ++ config NETFILTER_XT_TARGET_RATEEST ++ tristate '"RATEEST" target support' ++ depends on NETFILTER_ADVANCED ++--- a/net/netfilter/Makefile +++++ b/net/netfilter/Makefile ++@@ -145,6 +145,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIF ++ obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o ++ obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o ++ obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o +++obj-$(CONFIG_NETFILTER_XT_TARGET_FLOWOFFLOAD) += xt_FLOWOFFLOAD.o ++ obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o ++ obj-$(CONFIG_NETFILTER_XT_TARGET_HMARK) += xt_HMARK.o ++ obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o ++--- /dev/null +++++ b/net/netfilter/xt_FLOWOFFLOAD.c ++@@ -0,0 +1,660 @@ +++/* +++ * Copyright (C) 2018-2021 Felix Fietkau +++ * +++ * This program is free software; you can redistribute it and/or modify +++ * it under the terms of the GNU General Public License version 2 as +++ * published by the Free Software Foundation. +++ */ +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++ +++struct xt_flowoffload_hook { +++ struct hlist_node list; +++ struct nf_hook_ops ops; +++ struct net *net; +++ bool registered; +++ bool used; +++}; +++ +++struct xt_flowoffload_table { +++ struct nf_flowtable ft; +++ struct hlist_head hooks; +++ struct delayed_work work; +++}; +++ +++static DEFINE_SPINLOCK(hooks_lock); +++ +++struct xt_flowoffload_table flowtable[2]; +++ +++static unsigned int +++xt_flowoffload_net_hook(void *priv, struct sk_buff *skb, +++ const struct nf_hook_state *state) +++{ +++ struct nf_flowtable *ft = priv; +++ +++ if (!atomic_read(&ft->rhashtable.nelems)) +++ return NF_ACCEPT; +++ +++ switch (skb->protocol) { +++ case htons(ETH_P_IP): +++ return nf_flow_offload_ip_hook(priv, skb, state); +++ case htons(ETH_P_IPV6): +++ return nf_flow_offload_ipv6_hook(priv, skb, state); +++ } +++ +++ return NF_ACCEPT; +++} +++ +++static int +++xt_flowoffload_create_hook(struct xt_flowoffload_table *table, +++ struct net_device *dev) +++{ +++ struct xt_flowoffload_hook *hook; +++ struct nf_hook_ops *ops; +++ +++ hook = kzalloc(sizeof(*hook), GFP_ATOMIC); +++ if (!hook) +++ return -ENOMEM; +++ +++ ops = &hook->ops; +++ ops->pf = NFPROTO_NETDEV; +++ ops->hooknum = NF_NETDEV_INGRESS; +++ ops->priority = 10; +++ ops->priv = &table->ft; +++ ops->hook = xt_flowoffload_net_hook; +++ ops->dev = dev; +++ +++ hlist_add_head(&hook->list, &table->hooks); +++ mod_delayed_work(system_power_efficient_wq, &table->work, 0); +++ +++ return 0; +++} +++ +++static struct xt_flowoffload_hook * +++flow_offload_lookup_hook(struct xt_flowoffload_table *table, +++ struct net_device *dev) +++{ +++ struct xt_flowoffload_hook *hook; +++ +++ hlist_for_each_entry(hook, &table->hooks, list) { +++ if (hook->ops.dev == dev) +++ return hook; +++ } +++ +++ return NULL; +++} +++ +++static void +++xt_flowoffload_check_device(struct xt_flowoffload_table *table, +++ struct net_device *dev) +++{ +++ struct xt_flowoffload_hook *hook; +++ +++ if (!dev) +++ return; +++ +++ spin_lock_bh(&hooks_lock); +++ hook = flow_offload_lookup_hook(table, dev); +++ if (hook) +++ hook->used = true; +++ else +++ xt_flowoffload_create_hook(table, dev); +++ spin_unlock_bh(&hooks_lock); +++} +++ +++static void +++xt_flowoffload_register_hooks(struct xt_flowoffload_table *table) +++{ +++ struct xt_flowoffload_hook *hook; +++ +++restart: +++ hlist_for_each_entry(hook, &table->hooks, list) { +++ if (hook->registered) +++ continue; +++ +++ hook->registered = true; +++ hook->net = dev_net(hook->ops.dev); +++ spin_unlock_bh(&hooks_lock); +++ nf_register_net_hook(hook->net, &hook->ops); +++ if (table->ft.flags & NF_FLOWTABLE_HW_OFFLOAD) +++ table->ft.type->setup(&table->ft, hook->ops.dev, +++ FLOW_BLOCK_BIND); +++ spin_lock_bh(&hooks_lock); +++ goto restart; +++ } +++ +++} +++ +++static bool +++xt_flowoffload_cleanup_hooks(struct xt_flowoffload_table *table) +++{ +++ struct xt_flowoffload_hook *hook; +++ bool active = false; +++ +++restart: +++ spin_lock_bh(&hooks_lock); +++ hlist_for_each_entry(hook, &table->hooks, list) { +++ if (hook->used || !hook->registered) { +++ active = true; +++ continue; +++ } +++ +++ hlist_del(&hook->list); +++ spin_unlock_bh(&hooks_lock); +++ if (table->ft.flags & NF_FLOWTABLE_HW_OFFLOAD) +++ table->ft.type->setup(&table->ft, hook->ops.dev, +++ FLOW_BLOCK_UNBIND); +++ nf_unregister_net_hook(hook->net, &hook->ops); +++ kfree(hook); +++ goto restart; +++ } +++ spin_unlock_bh(&hooks_lock); +++ +++ return active; +++} +++ +++static void +++xt_flowoffload_check_hook(struct flow_offload *flow, void *data) +++{ +++ struct xt_flowoffload_table *table = data; +++ struct flow_offload_tuple *tuple = &flow->tuplehash[0].tuple; +++ struct xt_flowoffload_hook *hook; +++ +++ spin_lock_bh(&hooks_lock); +++ hlist_for_each_entry(hook, &table->hooks, list) { +++ int ifindex; +++ +++ if (tuple->xmit_type == FLOW_OFFLOAD_XMIT_DIRECT) +++ ifindex = tuple->out.ifidx; +++ else +++ ifindex = tuple->dst_cache->dev->ifindex; +++ +++ if (hook->ops.dev->ifindex != tuple->iifidx && +++ hook->ops.dev->ifindex != ifindex) +++ continue; +++ +++ hook->used = true; +++ } +++ spin_unlock_bh(&hooks_lock); +++ +++ cond_resched(); +++} +++ +++static void +++xt_flowoffload_hook_work(struct work_struct *work) +++{ +++ struct xt_flowoffload_table *table; +++ struct xt_flowoffload_hook *hook; +++ int err; +++ +++ table = container_of(work, struct xt_flowoffload_table, work.work); +++ +++ spin_lock_bh(&hooks_lock); +++ xt_flowoffload_register_hooks(table); +++ hlist_for_each_entry(hook, &table->hooks, list) +++ hook->used = false; +++ spin_unlock_bh(&hooks_lock); +++ +++ err = nf_flow_table_iterate(&table->ft, xt_flowoffload_check_hook, +++ table); +++ if (err && err != -EAGAIN) +++ goto out; +++ +++ if (!xt_flowoffload_cleanup_hooks(table)) +++ return; +++ +++out: +++ queue_delayed_work(system_power_efficient_wq, &table->work, HZ); +++} +++ +++static bool +++xt_flowoffload_skip(struct sk_buff *skb, int family) +++{ +++ if (skb_sec_path(skb)) +++ return true; +++ +++ if (family == NFPROTO_IPV4) { +++ const struct ip_options *opt = &(IPCB(skb)->opt); +++ +++ if (unlikely(opt->optlen)) +++ return true; +++ } +++ +++ return false; +++} +++ +++static bool flow_is_valid_ether_device(const struct net_device *dev) +++{ +++ if (!dev || (dev->flags & IFF_LOOPBACK) || dev->type != ARPHRD_ETHER || +++ dev->addr_len != ETH_ALEN || !is_valid_ether_addr(dev->dev_addr)) +++ return false; +++ +++ return true; +++} +++ +++static void +++xt_flowoffload_route_check_path(struct nf_flow_route *route, +++ const struct nf_conn *ct, +++ enum ip_conntrack_dir dir, +++ struct net_device **out_dev) +++{ +++ const struct dst_entry *dst = route->tuple[dir].dst; +++ const void *daddr = &ct->tuplehash[!dir].tuple.src.u3; +++ struct net_device_path_stack stack; +++ enum net_device_path_type prev_type; +++ struct net_device *dev = dst->dev; +++ struct neighbour *n; +++ bool last = false; +++ u8 nud_state; +++ int i; +++ +++ route->tuple[!dir].in.ifindex = dev->ifindex; +++ +++ if (route->tuple[dir].xmit_type == FLOW_OFFLOAD_XMIT_XFRM) +++ return; +++ +++ if ((dev->flags & IFF_LOOPBACK) || +++ dev->type != ARPHRD_ETHER || dev->addr_len != ETH_ALEN || +++ !is_valid_ether_addr(dev->dev_addr)) +++ return; +++ +++ n = dst_neigh_lookup(dst, daddr); +++ if (!n) +++ return; +++ +++ read_lock_bh(&n->lock); +++ nud_state = n->nud_state; +++ memcpy(route->tuple[dir].out.h_dest, n->ha, ETH_ALEN); +++ read_unlock_bh(&n->lock); +++ neigh_release(n); +++ +++ if (!(nud_state & NUD_VALID)) +++ return; +++ +++ if (dev_fill_forward_path(dev, route->tuple[dir].out.h_dest, &stack) || +++ !stack.num_paths) +++ return; +++ +++ prev_type = DEV_PATH_ETHERNET; +++ for (i = 0; i <= stack.num_paths; i++) { +++ const struct net_device_path *path = &stack.path[i]; +++ int n_vlans = route->tuple[!dir].in.num_vlans; +++ +++ dev = (struct net_device *)path->dev; +++ if (flow_is_valid_ether_device(dev)) { +++ if (route->tuple[dir].xmit_type != FLOW_OFFLOAD_XMIT_DIRECT) +++ memcpy(route->tuple[dir].out.h_source, +++ dev->dev_addr, ETH_ALEN); +++ route->tuple[dir].xmit_type = FLOW_OFFLOAD_XMIT_DIRECT; +++ route->tuple[dir].out.ifindex = dev->ifindex; +++ } +++ +++ switch (path->type) { +++ case DEV_PATH_VLAN: +++ if (n_vlans >= NF_FLOW_TABLE_VLAN_MAX || +++ i == stack.num_paths) { +++ last = true; +++ break; +++ } +++ +++ route->tuple[!dir].in.num_vlans++; +++ route->tuple[!dir].in.vid[n_vlans] = path->vlan.id; +++ route->tuple[!dir].in.vproto[n_vlans] = path->vlan.proto; +++ break; +++ case DEV_PATH_BRIDGE: +++ switch (path->bridge.vlan_mode) { +++ case DEV_PATH_BR_VLAN_TAG: +++ if (n_vlans >= NF_FLOW_TABLE_VLAN_MAX || +++ i == stack.num_paths) { +++ last = true; +++ break; +++ } +++ +++ route->tuple[!dir].in.num_vlans++; +++ route->tuple[!dir].in.vid[n_vlans] = +++ path->bridge.vlan_id; +++ route->tuple[!dir].in.vproto[n_vlans] = +++ path->bridge.vlan_proto; +++ break; +++ case DEV_PATH_BR_VLAN_UNTAG_HW: +++ route->tuple[!dir].in.pvid.id = +++ route->tuple[!dir].in.vid[n_vlans - 1]; +++ route->tuple[!dir].in.pvid.proto = +++ route->tuple[!dir].in.vproto[n_vlans - 1]; +++ fallthrough; +++ case DEV_PATH_BR_VLAN_UNTAG: +++ route->tuple[!dir].in.num_vlans--; +++ break; +++ case DEV_PATH_BR_VLAN_KEEP: +++ break; +++ } +++ break; +++ default: +++ last = true; +++ break; +++ } +++ +++ if (last) +++ break; +++ } +++ +++ *out_dev = dev; +++ route->tuple[!dir].in.ifindex = dev->ifindex; +++} +++ +++static int +++xt_flowoffload_route_dir(struct nf_flow_route *route, const struct nf_conn *ct, +++ enum ip_conntrack_dir dir, +++ const struct xt_action_param *par, int ifindex) +++{ +++ struct dst_entry *dst = NULL; +++ struct flowi fl; +++ +++ memset(&fl, 0, sizeof(fl)); +++ switch (xt_family(par)) { +++ case NFPROTO_IPV4: +++ fl.u.ip4.daddr = ct->tuplehash[!dir].tuple.src.u3.ip; +++ fl.u.ip4.flowi4_oif = ifindex; +++ break; +++ case NFPROTO_IPV6: +++ fl.u.ip6.saddr = ct->tuplehash[!dir].tuple.dst.u3.in6; +++ fl.u.ip6.daddr = ct->tuplehash[!dir].tuple.src.u3.in6; +++ fl.u.ip6.flowi6_oif = ifindex; +++ break; +++ } +++ +++ nf_route(xt_net(par), &dst, &fl, false, xt_family(par)); +++ if (!dst) +++ return -ENOENT; +++ +++ route->tuple[dir].dst = dst; +++ if (dst_xfrm(dst)) +++ route->tuple[dir].xmit_type = FLOW_OFFLOAD_XMIT_XFRM; +++ else +++ route->tuple[dir].xmit_type = FLOW_OFFLOAD_XMIT_NEIGH; +++ +++ return 0; +++} +++ +++static int +++xt_flowoffload_route(struct sk_buff *skb, const struct nf_conn *ct, +++ const struct xt_action_param *par, +++ struct nf_flow_route *route, enum ip_conntrack_dir dir, +++ struct net_device **dev) +++{ +++ int ret; +++ +++ ret = xt_flowoffload_route_dir(route, ct, dir, par, +++ dev[dir]->ifindex); +++ if (ret) +++ return ret; +++ +++ ret = xt_flowoffload_route_dir(route, ct, !dir, par, +++ dev[!dir]->ifindex); +++ if (ret) +++ return ret; +++ +++ xt_flowoffload_route_check_path(route, ct, dir, &dev[!dir]); +++ xt_flowoffload_route_check_path(route, ct, !dir, &dev[dir]); +++ +++ return 0; +++} +++ +++static unsigned int +++flowoffload_tg(struct sk_buff *skb, const struct xt_action_param *par) +++{ +++ struct xt_flowoffload_table *table; +++ const struct xt_flowoffload_target_info *info = par->targinfo; +++ struct tcphdr _tcph, *tcph = NULL; +++ enum ip_conntrack_info ctinfo; +++ enum ip_conntrack_dir dir; +++ struct nf_flow_route route = {}; +++ struct flow_offload *flow = NULL; +++ struct net_device *devs[2] = {}; +++ struct nf_conn *ct; +++ struct net *net; +++ +++ if (xt_flowoffload_skip(skb, xt_family(par))) +++ return XT_CONTINUE; +++ +++ ct = nf_ct_get(skb, &ctinfo); +++ if (ct == NULL) +++ return XT_CONTINUE; +++ +++ switch (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum) { +++ case IPPROTO_TCP: +++ if (ct->proto.tcp.state != TCP_CONNTRACK_ESTABLISHED) +++ return XT_CONTINUE; +++ +++ tcph = skb_header_pointer(skb, par->thoff, +++ sizeof(_tcph), &_tcph); +++ if (unlikely(!tcph || tcph->fin || tcph->rst)) +++ return XT_CONTINUE; +++ break; +++ case IPPROTO_UDP: +++ break; +++ default: +++ return XT_CONTINUE; +++ } +++ +++ if (nf_ct_ext_exist(ct, NF_CT_EXT_HELPER) || +++ ct->status & IPS_SEQ_ADJUST) +++ return XT_CONTINUE; +++ +++ if (!nf_ct_is_confirmed(ct)) +++ return XT_CONTINUE; +++ +++ devs[dir] = xt_out(par); +++ devs[!dir] = xt_in(par); +++ +++ if (!devs[dir] || !devs[!dir]) +++ return XT_CONTINUE; +++ +++ if (test_and_set_bit(IPS_OFFLOAD_BIT, &ct->status)) +++ return XT_CONTINUE; +++ +++ dir = CTINFO2DIR(ctinfo); +++ +++ if (xt_flowoffload_route(skb, ct, par, &route, dir, devs) < 0) +++ goto err_flow_route; +++ +++ flow = flow_offload_alloc(ct); +++ if (!flow) +++ goto err_flow_alloc; +++ +++ if (flow_offload_route_init(flow, &route) < 0) +++ goto err_flow_add; +++ +++ if (tcph) { +++ ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; +++ ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; +++ } +++ +++ table = &flowtable[!!(info->flags & XT_FLOWOFFLOAD_HW)]; +++ if (flow_offload_add(&table->ft, flow) < 0) +++ goto err_flow_add; +++ +++ xt_flowoffload_check_device(table, devs[0]); +++ xt_flowoffload_check_device(table, devs[1]); +++ +++ net = read_pnet(&table->ft.net); +++ if (!net) +++ write_pnet(&table->ft.net, xt_net(par)); +++ +++ dst_release(route.tuple[dir].dst); +++ dst_release(route.tuple[!dir].dst); +++ +++ return XT_CONTINUE; +++ +++err_flow_add: +++ flow_offload_free(flow); +++err_flow_alloc: +++ dst_release(route.tuple[dir].dst); +++ dst_release(route.tuple[!dir].dst); +++err_flow_route: +++ clear_bit(IPS_OFFLOAD_BIT, &ct->status); +++ +++ return XT_CONTINUE; +++} +++ +++static int flowoffload_chk(const struct xt_tgchk_param *par) +++{ +++ struct xt_flowoffload_target_info *info = par->targinfo; +++ +++ if (info->flags & ~XT_FLOWOFFLOAD_MASK) +++ return -EINVAL; +++ +++ return 0; +++} +++ +++static struct xt_target offload_tg_reg __read_mostly = { +++ .family = NFPROTO_UNSPEC, +++ .name = "FLOWOFFLOAD", +++ .revision = 0, +++ .targetsize = sizeof(struct xt_flowoffload_target_info), +++ .usersize = sizeof(struct xt_flowoffload_target_info), +++ .checkentry = flowoffload_chk, +++ .target = flowoffload_tg, +++ .me = THIS_MODULE, +++}; +++ +++static int flow_offload_netdev_event(struct notifier_block *this, +++ unsigned long event, void *ptr) +++{ +++ struct xt_flowoffload_hook *hook0, *hook1; +++ struct net_device *dev = netdev_notifier_info_to_dev(ptr); +++ +++ if (event != NETDEV_UNREGISTER) +++ return NOTIFY_DONE; +++ +++ spin_lock_bh(&hooks_lock); +++ hook0 = flow_offload_lookup_hook(&flowtable[0], dev); +++ if (hook0) +++ hlist_del(&hook0->list); +++ +++ hook1 = flow_offload_lookup_hook(&flowtable[1], dev); +++ if (hook1) +++ hlist_del(&hook1->list); +++ spin_unlock_bh(&hooks_lock); +++ +++ if (hook0) { +++ nf_unregister_net_hook(hook0->net, &hook0->ops); +++ kfree(hook0); +++ } +++ +++ if (hook1) { +++ nf_unregister_net_hook(hook1->net, &hook1->ops); +++ kfree(hook1); +++ } +++ +++ nf_flow_table_cleanup(dev); +++ +++ return NOTIFY_DONE; +++} +++ +++static struct notifier_block flow_offload_netdev_notifier = { +++ .notifier_call = flow_offload_netdev_event, +++}; +++ +++static unsigned int +++nf_flow_offload_inet_hook(void *priv, struct sk_buff *skb, +++ const struct nf_hook_state *state) +++{ +++ switch (skb->protocol) { +++ case htons(ETH_P_IP): +++ return nf_flow_offload_ip_hook(priv, skb, state); +++ case htons(ETH_P_IPV6): +++ return nf_flow_offload_ipv6_hook(priv, skb, state); +++ } +++ +++ return NF_ACCEPT; +++} +++ +++static int nf_flow_rule_route_inet(struct net *net, +++ const struct flow_offload *flow, +++ enum flow_offload_tuple_dir dir, +++ struct nf_flow_rule *flow_rule) +++{ +++ const struct flow_offload_tuple *flow_tuple = &flow->tuplehash[dir].tuple; +++ int err; +++ +++ switch (flow_tuple->l3proto) { +++ case NFPROTO_IPV4: +++ err = nf_flow_rule_route_ipv4(net, flow, dir, flow_rule); +++ break; +++ case NFPROTO_IPV6: +++ err = nf_flow_rule_route_ipv6(net, flow, dir, flow_rule); +++ break; +++ default: +++ err = -1; +++ break; +++ } +++ +++ return err; +++} +++ +++static struct nf_flowtable_type flowtable_inet = { +++ .family = NFPROTO_INET, +++ .init = nf_flow_table_init, +++ .setup = nf_flow_table_offload_setup, +++ .action = nf_flow_rule_route_inet, +++ .free = nf_flow_table_free, +++ .hook = nf_flow_offload_inet_hook, +++ .owner = THIS_MODULE, +++}; +++ +++static int init_flowtable(struct xt_flowoffload_table *tbl) +++{ +++ INIT_DELAYED_WORK(&tbl->work, xt_flowoffload_hook_work); +++ tbl->ft.type = &flowtable_inet; +++ +++ return nf_flow_table_init(&tbl->ft); +++} +++ +++static int __init xt_flowoffload_tg_init(void) +++{ +++ int ret; +++ +++ register_netdevice_notifier(&flow_offload_netdev_notifier); +++ +++ ret = init_flowtable(&flowtable[0]); +++ if (ret) +++ return ret; +++ +++ ret = init_flowtable(&flowtable[1]); +++ if (ret) +++ goto cleanup; +++ +++ flowtable[1].ft.flags = NF_FLOWTABLE_HW_OFFLOAD; +++ +++ ret = xt_register_target(&offload_tg_reg); +++ if (ret) +++ goto cleanup2; +++ +++ return 0; +++ +++cleanup2: +++ nf_flow_table_free(&flowtable[1].ft); +++cleanup: +++ nf_flow_table_free(&flowtable[0].ft); +++ return ret; +++} +++ +++static void __exit xt_flowoffload_tg_exit(void) +++{ +++ xt_unregister_target(&offload_tg_reg); +++ unregister_netdevice_notifier(&flow_offload_netdev_notifier); +++ nf_flow_table_free(&flowtable[0].ft); +++ nf_flow_table_free(&flowtable[1].ft); +++} +++ +++MODULE_LICENSE("GPL"); +++module_init(xt_flowoffload_tg_init); +++module_exit(xt_flowoffload_tg_exit); ++--- a/net/netfilter/nf_flow_table_core.c +++++ b/net/netfilter/nf_flow_table_core.c ++@@ -7,7 +7,6 @@ ++ #include ++ #include ++ #include ++-#include ++ #include ++ #include ++ #include ++@@ -355,8 +354,7 @@ flow_offload_lookup(struct nf_flowtable ++ } ++ EXPORT_SYMBOL_GPL(flow_offload_lookup); ++ ++-static int ++-nf_flow_table_iterate(struct nf_flowtable *flow_table, +++int nf_flow_table_iterate(struct nf_flowtable *flow_table, ++ void (*iter)(struct flow_offload *flow, void *data), ++ void *data) ++ { ++@@ -388,6 +386,7 @@ nf_flow_table_iterate(struct nf_flowtabl ++ ++ return err; ++ } +++EXPORT_SYMBOL_GPL(nf_flow_table_iterate); ++ ++ static void nf_flow_offload_gc_step(struct flow_offload *flow, void *data) ++ { ++--- /dev/null +++++ b/include/uapi/linux/netfilter/xt_FLOWOFFLOAD.h ++@@ -0,0 +1,17 @@ +++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +++#ifndef _XT_FLOWOFFLOAD_H +++#define _XT_FLOWOFFLOAD_H +++ +++#include +++ +++enum { +++ XT_FLOWOFFLOAD_HW = 1 << 0, +++ +++ XT_FLOWOFFLOAD_MASK = XT_FLOWOFFLOAD_HW +++}; +++ +++struct xt_flowoffload_target_info { +++ __u32 flags; +++}; +++ +++#endif /* _XT_FLOWOFFLOAD_H */ ++--- a/include/net/netfilter/nf_flow_table.h +++++ b/include/net/netfilter/nf_flow_table.h ++@@ -265,6 +265,10 @@ void nf_flow_table_free(struct nf_flowta ++ ++ void flow_offload_teardown(struct flow_offload *flow); ++ +++int nf_flow_table_iterate(struct nf_flowtable *flow_table, +++ void (*iter)(struct flow_offload *flow, void *data), +++ void *data); +++ ++ int nf_flow_snat_port(const struct flow_offload *flow, ++ struct sk_buff *skb, unsigned int thoff, ++ u8 protocol, enum flow_offload_tuple_dir dir); +diff --git a/target/linux/generic/hack-5.10/651-wireless_mesh_header.patch b/target/linux/generic/hack-5.10/651-wireless_mesh_header.patch +new file mode 100644 +index 0000000000..0639ad4e48 +--- /dev/null ++++ b/target/linux/generic/hack-5.10/651-wireless_mesh_header.patch +@@ -0,0 +1,24 @@ ++From 6d3bc769657b0ee7c7506dad9911111c4226a7ea Mon Sep 17 00:00:00 2001 ++From: Imre Kaloz ++Date: Fri, 7 Jul 2017 17:21:05 +0200 ++Subject: mac80211: increase wireless mesh header size ++ ++lede-commit 3d4466cfd8f75f717efdb1f96fdde3c70d865fc1 ++Signed-off-by: Imre Kaloz ++--- ++ include/linux/netdevice.h | 4 ++-- ++ 1 file changed, 2 insertions(+), 2 deletions(-) ++ ++--- a/include/linux/netdevice.h +++++ b/include/linux/netdevice.h ++@@ -144,8 +144,8 @@ static inline bool dev_xmit_complete(int ++ ++ #if defined(CONFIG_HYPERV_NET) ++ # define LL_MAX_HEADER 128 ++-#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25) ++-# if defined(CONFIG_MAC80211_MESH) +++#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25) || 1 +++# if defined(CONFIG_MAC80211_MESH) || 1 ++ # define LL_MAX_HEADER 128 ++ # else ++ # define LL_MAX_HEADER 96 +diff --git a/target/linux/generic/hack-5.10/660-fq_codel_defaults.patch b/target/linux/generic/hack-5.10/660-fq_codel_defaults.patch +new file mode 100644 +index 0000000000..6794349e26 +--- /dev/null ++++ b/target/linux/generic/hack-5.10/660-fq_codel_defaults.patch +@@ -0,0 +1,27 @@ ++From a6ccb238939b25851474a279b20367fd24a0e816 Mon Sep 17 00:00:00 2001 ++From: Felix Fietkau ++Date: Fri, 7 Jul 2017 17:21:53 +0200 ++Subject: hack: net: fq_codel: tune defaults for small devices ++ ++Assume that x86_64 devices always have a big memory and do not need this ++optimization compared to devices with only 32 MB or 64 MB RAM. ++ ++Signed-off-by: Felix Fietkau ++--- ++ net/sched/sch_fq_codel.c | 2 +- ++ 1 file changed, 1 insertion(+), 1 deletion(-) ++ ++--- a/net/sched/sch_fq_codel.c +++++ b/net/sched/sch_fq_codel.c ++@@ -461,7 +461,11 @@ static int fq_codel_init(struct Qdisc *s ++ ++ sch->limit = 10*1024; ++ q->flows_cnt = 1024; +++#ifdef CONFIG_X86_64 ++ q->memory_limit = 32 << 20; /* 32 MBytes */ +++#else +++ q->memory_limit = 4 << 20; /* 4 MBytes */ +++#endif ++ q->drop_batch_size = 64; ++ q->quantum = psched_mtu(qdisc_dev(sch)); ++ INIT_LIST_HEAD(&q->new_flows); +diff --git a/target/linux/generic/hack-5.10/661-use_fq_codel_by_default.patch b/target/linux/generic/hack-5.10/661-use_fq_codel_by_default.patch +new file mode 100644 +index 0000000000..ceabf81249 +--- /dev/null ++++ b/target/linux/generic/hack-5.10/661-use_fq_codel_by_default.patch +@@ -0,0 +1,100 @@ ++From 1d418f7e88035ed7a94073f6354246c66e9193e9 Mon Sep 17 00:00:00 2001 ++From: Felix Fietkau ++Date: Fri, 7 Jul 2017 17:22:58 +0200 ++Subject: fq_codel: switch default qdisc from pfifo_fast to fq_codel and remove pfifo_fast ++ ++Signed-off-by: Felix Fietkau ++--- ++ include/net/sch_generic.h | 3 ++- ++ net/sched/Kconfig | 3 ++- ++ net/sched/sch_api.c | 2 +- ++ net/sched/sch_fq_codel.c | 3 ++- ++ net/sched/sch_generic.c | 4 ++-- ++ 5 files changed, 9 insertions(+), 6 deletions(-) ++ ++--- a/include/net/sch_generic.h +++++ b/include/net/sch_generic.h ++@@ -578,12 +578,13 @@ extern struct Qdisc_ops noop_qdisc_ops; ++ extern struct Qdisc_ops pfifo_fast_ops; ++ extern struct Qdisc_ops mq_qdisc_ops; ++ extern struct Qdisc_ops noqueue_qdisc_ops; +++extern struct Qdisc_ops fq_codel_qdisc_ops; ++ extern const struct Qdisc_ops *default_qdisc_ops; ++ static inline const struct Qdisc_ops * ++ get_default_qdisc_ops(const struct net_device *dev, int ntx) ++ { ++ return ntx < dev->real_num_tx_queues ? ++- default_qdisc_ops : &pfifo_fast_ops; +++ default_qdisc_ops : &fq_codel_qdisc_ops; ++ } ++ ++ struct Qdisc_class_common { ++--- a/net/sched/Kconfig +++++ b/net/sched/Kconfig ++@@ -4,8 +4,9 @@ ++ # ++ ++ menuconfig NET_SCHED ++- bool "QoS and/or fair queueing" +++ def_bool y ++ select NET_SCH_FIFO +++ select NET_SCH_FQ_CODEL ++ help ++ When the kernel has several packets to send out over a network ++ device, it has to decide which ones to send first, which ones to ++--- a/net/sched/sch_api.c +++++ b/net/sched/sch_api.c ++@@ -2282,7 +2282,7 @@ static int __init pktsched_init(void) ++ return err; ++ } ++ ++- register_qdisc(&pfifo_fast_ops); +++ register_qdisc(&fq_codel_qdisc_ops); ++ register_qdisc(&pfifo_qdisc_ops); ++ register_qdisc(&bfifo_qdisc_ops); ++ register_qdisc(&pfifo_head_drop_qdisc_ops); ++--- a/net/sched/sch_fq_codel.c +++++ b/net/sched/sch_fq_codel.c ++@@ -701,7 +701,7 @@ static const struct Qdisc_class_ops fq_c ++ .walk = fq_codel_walk, ++ }; ++ ++-static struct Qdisc_ops fq_codel_qdisc_ops __read_mostly = { +++struct Qdisc_ops fq_codel_qdisc_ops __read_mostly = { ++ .cl_ops = &fq_codel_class_ops, ++ .id = "fq_codel", ++ .priv_size = sizeof(struct fq_codel_sched_data), ++@@ -716,6 +716,7 @@ static struct Qdisc_ops fq_codel_qdisc_o ++ .dump_stats = fq_codel_dump_stats, ++ .owner = THIS_MODULE, ++ }; +++EXPORT_SYMBOL(fq_codel_qdisc_ops); ++ ++ static int __init fq_codel_module_init(void) ++ { ++--- a/net/sched/sch_generic.c +++++ b/net/sched/sch_generic.c ++@@ -32,7 +32,7 @@ ++ #include ++ ++ /* Qdisc to use by default */ ++-const struct Qdisc_ops *default_qdisc_ops = &pfifo_fast_ops; +++const struct Qdisc_ops *default_qdisc_ops = &fq_codel_qdisc_ops; ++ EXPORT_SYMBOL(default_qdisc_ops); ++ ++ /* Main transmission queue. */ ++@@ -1018,12 +1018,12 @@ static void attach_one_default_qdisc(str ++ void *_unused) ++ { ++ struct Qdisc *qdisc; ++- const struct Qdisc_ops *ops = default_qdisc_ops; +++ const struct Qdisc_ops *ops = &fq_codel_qdisc_ops; ++ ++ if (dev->priv_flags & IFF_NO_QUEUE) ++ ops = &noqueue_qdisc_ops; ++ else if(dev->type == ARPHRD_CAN) ++- ops = &pfifo_fast_ops; +++ ops = &fq_codel_qdisc_ops; ++ ++ qdisc = qdisc_create_dflt(dev_queue, ops, TC_H_ROOT, NULL); ++ if (!qdisc) +diff --git a/target/linux/generic/hack-5.10/700-swconfig_switch_drivers.patch b/target/linux/generic/hack-5.10/700-swconfig_switch_drivers.patch +new file mode 100644 +index 0000000000..560937a7c1 +--- /dev/null ++++ b/target/linux/generic/hack-5.10/700-swconfig_switch_drivers.patch +@@ -0,0 +1,129 @@ ++From 36e516290611e613aa92996cb4339561452695b4 Mon Sep 17 00:00:00 2001 ++From: Felix Fietkau ++Date: Fri, 7 Jul 2017 17:24:23 +0200 ++Subject: net: swconfig: adds openwrt switch layer ++ ++Signed-off-by: Felix Fietkau ++--- ++ drivers/net/phy/Kconfig | 83 +++++++++++++++++++++++++++++++++++++++++++++++ ++ drivers/net/phy/Makefile | 15 +++++++++ ++ include/uapi/linux/Kbuild | 1 + ++ 3 files changed, 99 insertions(+) ++ ++--- a/drivers/net/phy/Kconfig +++++ b/drivers/net/phy/Kconfig ++@@ -61,6 +61,80 @@ config SFP ++ depends on HWMON || HWMON=n ++ select MDIO_I2C ++ +++comment "Switch configuration API + drivers" +++ +++config SWCONFIG +++ tristate "Switch configuration API" +++ help +++ Switch configuration API using netlink. This allows +++ you to configure the VLAN features of certain switches. +++ +++config SWCONFIG_LEDS +++ bool "Switch LED trigger support" +++ depends on (SWCONFIG && LEDS_TRIGGERS) +++ +++config ADM6996_PHY +++ tristate "Driver for ADM6996 switches" +++ select SWCONFIG +++ help +++ Currently supports the ADM6996FC and ADM6996M switches. +++ Support for FC is very limited. +++ +++config AR8216_PHY +++ tristate "Driver for Atheros AR8216 switches" +++ select SWCONFIG +++ +++config AR8216_PHY_LEDS +++ bool "Atheros AR8216 switch LED support" +++ depends on (AR8216_PHY && LEDS_CLASS) +++ +++source "drivers/net/phy/b53/Kconfig" +++ +++config IP17XX_PHY +++ tristate "Driver for IC+ IP17xx switches" +++ select SWCONFIG +++ +++config PSB6970_PHY +++ tristate "Lantiq XWAY Tantos (PSB6970) Ethernet switch" +++ select SWCONFIG +++ select ETHERNET_PACKET_MANGLE +++ +++config RTL8306_PHY +++ tristate "Driver for Realtek RTL8306S switches" +++ select SWCONFIG +++ +++config RTL8366_SMI +++ tristate "Driver for the RTL8366 SMI interface" +++ depends on GPIOLIB +++ help +++ This module implements the SMI interface protocol which is used +++ by some RTL8366 ethernet switch devices via the generic GPIO API. +++ +++if RTL8366_SMI +++ +++config RTL8366_SMI_DEBUG_FS +++ bool "RTL8366 SMI interface debugfs support" +++ depends on DEBUG_FS +++ default n +++ +++config RTL8366S_PHY +++ tristate "Driver for the Realtek RTL8366S switch" +++ select SWCONFIG +++ +++config RTL8366RB_PHY +++ tristate "Driver for the Realtek RTL8366RB switch" +++ select SWCONFIG +++ +++config RTL8367_PHY +++ tristate "Driver for the Realtek RTL8367R/M switches" +++ select SWCONFIG +++ +++config RTL8367B_PHY +++ tristate "Driver fot the Realtek RTL8367R-VB switch" +++ select SWCONFIG +++ +++endif # RTL8366_SMI +++ ++ comment "MII PHY device drivers" ++ ++ config AMD_PHY ++--- a/drivers/net/phy/Makefile +++++ b/drivers/net/phy/Makefile ++@@ -24,6 +24,19 @@ libphy-$(CONFIG_LED_TRIGGER_PHY) += phy_ ++ obj-$(CONFIG_PHYLINK) += phylink.o ++ obj-$(CONFIG_PHYLIB) += libphy.o ++ +++obj-$(CONFIG_SWCONFIG) += swconfig.o +++obj-$(CONFIG_ADM6996_PHY) += adm6996.o +++obj-$(CONFIG_AR8216_PHY) += ar8216.o ar8327.o +++obj-$(CONFIG_SWCONFIG_B53) += b53/ +++obj-$(CONFIG_IP17XX_PHY) += ip17xx.o +++obj-$(CONFIG_PSB6970_PHY) += psb6970.o +++obj-$(CONFIG_RTL8306_PHY) += rtl8306.o +++obj-$(CONFIG_RTL8366_SMI) += rtl8366_smi.o +++obj-$(CONFIG_RTL8366S_PHY) += rtl8366s.o +++obj-$(CONFIG_RTL8366RB_PHY) += rtl8366rb.o +++obj-$(CONFIG_RTL8367_PHY) += rtl8367.o +++obj-$(CONFIG_RTL8367B_PHY) += rtl8367b.o +++ ++ obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += mii_timestamper.o ++ ++ obj-$(CONFIG_SFP) += sfp.o ++--- a/include/linux/platform_data/b53.h +++++ b/include/linux/platform_data/b53.h ++@@ -29,6 +29,9 @@ struct b53_platform_data { ++ u32 chip_id; ++ u16 enabled_ports; ++ +++ /* allow to specify an ethX alias */ +++ const char *alias; +++ ++ /* only used by MMAP'd driver */ ++ unsigned big_endian:1; ++ void __iomem *regs; +diff --git a/target/linux/generic/hack-5.10/773-bgmac-add-srab-switch.patch b/target/linux/generic/hack-5.10/773-bgmac-add-srab-switch.patch +new file mode 100644 +index 0000000000..1c1b727ab7 +--- /dev/null ++++ b/target/linux/generic/hack-5.10/773-bgmac-add-srab-switch.patch +@@ -0,0 +1,98 @@ ++From 3cb240533ab787899dc7f17aa7d6c5b4810e2e58 Mon Sep 17 00:00:00 2001 ++From: Hauke Mehrtens ++Date: Fri, 7 Jul 2017 17:26:01 +0200 ++Subject: bcm53xx: bgmac: use srab switch driver ++ ++use the srab switch driver on these SoCs. ++ ++Signed-off-by: Hauke Mehrtens ++--- ++ drivers/net/ethernet/broadcom/bgmac-bcma.c | 1 + ++ drivers/net/ethernet/broadcom/bgmac.c | 24 ++++++++++++++++++++++++ ++ drivers/net/ethernet/broadcom/bgmac.h | 4 ++++ ++ 3 files changed, 29 insertions(+) ++ ++--- a/drivers/net/ethernet/broadcom/bgmac-bcma.c +++++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c ++@@ -268,6 +268,7 @@ static int bgmac_probe(struct bcma_devic ++ bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; ++ bgmac->feature_flags |= BGMAC_FEAT_NO_RESET; ++ bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500; +++ bgmac->feature_flags |= BGMAC_FEAT_SRAB; ++ break; ++ default: ++ bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; ++--- a/drivers/net/ethernet/broadcom/bgmac.c +++++ b/drivers/net/ethernet/broadcom/bgmac.c ++@@ -12,6 +12,7 @@ ++ #include ++ #include ++ #include +++#include ++ #include ++ #include ++ #include ++@@ -1408,6 +1409,17 @@ static const struct ethtool_ops bgmac_et ++ .set_link_ksettings = phy_ethtool_set_link_ksettings, ++ }; ++ +++static struct b53_platform_data bgmac_b53_pdata = { +++}; +++ +++static struct platform_device bgmac_b53_dev = { +++ .name = "b53-srab-switch", +++ .id = -1, +++ .dev = { +++ .platform_data = &bgmac_b53_pdata, +++ }, +++}; +++ ++ /************************************************** ++ * MII ++ **************************************************/ ++@@ -1542,6 +1554,14 @@ int bgmac_enet_probe(struct bgmac *bgmac ++ /* Omit FCS from max MTU size */ ++ net_dev->max_mtu = BGMAC_RX_MAX_FRAME_SIZE - ETH_FCS_LEN; ++ +++ if ((bgmac->feature_flags & BGMAC_FEAT_SRAB) && !bgmac_b53_pdata.regs) { +++ bgmac_b53_pdata.regs = ioremap_nocache(0x18007000, 0x1000); +++ +++ err = platform_device_register(&bgmac_b53_dev); +++ if (!err) +++ bgmac->b53_device = &bgmac_b53_dev; +++ } +++ ++ err = register_netdev(bgmac->net_dev); ++ if (err) { ++ dev_err(bgmac->dev, "Cannot register net device\n"); ++@@ -1564,6 +1584,10 @@ EXPORT_SYMBOL_GPL(bgmac_enet_probe); ++ ++ void bgmac_enet_remove(struct bgmac *bgmac) ++ { +++ if (bgmac->b53_device) +++ platform_device_unregister(&bgmac_b53_dev); +++ bgmac->b53_device = NULL; +++ ++ unregister_netdev(bgmac->net_dev); ++ phy_disconnect(bgmac->net_dev->phydev); ++ netif_napi_del(&bgmac->napi); ++--- a/drivers/net/ethernet/broadcom/bgmac.h +++++ b/drivers/net/ethernet/broadcom/bgmac.h ++@@ -428,6 +428,7 @@ ++ #define BGMAC_FEAT_CC4_IF_SW_TYPE_RGMII BIT(18) ++ #define BGMAC_FEAT_CC7_IF_TYPE_RGMII BIT(19) ++ #define BGMAC_FEAT_IDM_MASK BIT(20) +++#define BGMAC_FEAT_SRAB BIT(21) ++ ++ struct bgmac_slot_info { ++ union { ++@@ -533,6 +534,9 @@ struct bgmac { ++ void (*cmn_maskset32)(struct bgmac *bgmac, u16 offset, u32 mask, ++ u32 set); ++ int (*phy_connect)(struct bgmac *bgmac); +++ +++ /* platform device for associated switch */ +++ struct platform_device *b53_device; ++ }; ++ ++ struct bgmac *bgmac_alloc(struct device *dev); +diff --git a/target/linux/generic/hack-5.10/901-debloat_sock_diag.patch b/target/linux/generic/hack-5.10/901-debloat_sock_diag.patch +new file mode 100644 +index 0000000000..fc2a0a4862 +--- /dev/null ++++ b/target/linux/generic/hack-5.10/901-debloat_sock_diag.patch +@@ -0,0 +1,162 @@ ++From 3b6115d6b57a263bdc8c9b1df273bd4a7955eead Mon Sep 17 00:00:00 2001 ++From: Felix Fietkau ++Date: Sat, 8 Jul 2017 08:16:31 +0200 ++Subject: debloat: add some debloat patches, strip down procfs and make O_DIRECT support optional, saves ~15K after lzma on MIPS ++ ++Signed-off-by: Felix Fietkau ++--- ++ net/Kconfig | 3 +++ ++ net/core/Makefile | 3 ++- ++ net/core/sock.c | 2 ++ ++ net/ipv4/Kconfig | 1 + ++ net/netlink/Kconfig | 1 + ++ net/packet/Kconfig | 1 + ++ net/unix/Kconfig | 1 + ++ 7 files changed, 11 insertions(+), 1 deletion(-) ++ ++--- a/net/Kconfig +++++ b/net/Kconfig ++@@ -98,6 +98,9 @@ source "net/mptcp/Kconfig" ++ ++ endif # if INET ++ +++config SOCK_DIAG +++ bool +++ ++ config NETWORK_SECMARK ++ bool "Security Marking" ++ help ++--- a/net/core/Makefile +++++ b/net/core/Makefile ++@@ -10,9 +10,10 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_core. ++ ++ obj-y += dev.o dev_addr_lists.o dst.o netevent.o \ ++ neighbour.o rtnetlink.o utils.o link_watch.o filter.o \ ++- sock_diag.o dev_ioctl.o tso.o sock_reuseport.o \ +++ dev_ioctl.o tso.o sock_reuseport.o \ ++ fib_notifier.o xdp.o flow_offload.o ++ +++obj-$(CONFIG_SOCK_DIAG) += sock_diag.o ++ obj-y += net-sysfs.o ++ obj-$(CONFIG_PAGE_POOL) += page_pool.o ++ obj-$(CONFIG_PROC_FS) += net-procfs.o ++--- a/net/core/sock.c +++++ b/net/core/sock.c ++@@ -114,6 +114,7 @@ ++ #include ++ #include ++ #include +++#include ++ ++ #include ++ ++@@ -141,6 +142,7 @@ ++ ++ static DEFINE_MUTEX(proto_list_mutex); ++ static LIST_HEAD(proto_list); +++DEFINE_COOKIE(sock_cookie); ++ ++ static void sock_inuse_add(struct net *net, int val); ++ ++@@ -526,6 +528,18 @@ discard_and_relse: ++ } ++ EXPORT_SYMBOL(__sk_receive_skb); ++ +++u64 __sock_gen_cookie(struct sock *sk) +++{ +++ while (1) { +++ u64 res = atomic64_read(&sk->sk_cookie); +++ +++ if (res) +++ return res; +++ res = gen_cookie_next(&sock_cookie); +++ atomic64_cmpxchg(&sk->sk_cookie, 0, res); +++ } +++} +++ ++ struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie) ++ { ++ struct dst_entry *dst = __sk_dst_get(sk); ++@@ -1808,9 +1822,11 @@ static void __sk_free(struct sock *sk) ++ if (likely(sk->sk_net_refcnt)) ++ sock_inuse_add(sock_net(sk), -1); ++ +++#ifdef CONFIG_SOCK_DIAG ++ if (unlikely(sk->sk_net_refcnt && sock_diag_has_destroy_listeners(sk))) ++ sock_diag_broadcast_destroy(sk); ++ else +++#endif ++ sk_destruct(sk); ++ } ++ ++--- a/net/core/sock_diag.c +++++ b/net/core/sock_diag.c ++@@ -11,7 +11,6 @@ ++ #include ++ #include ++ #include ++-#include ++ #include ++ #include ++ ++@@ -20,20 +19,6 @@ static int (*inet_rcv_compat)(struct sk_ ++ static DEFINE_MUTEX(sock_diag_table_mutex); ++ static struct workqueue_struct *broadcast_wq; ++ ++-DEFINE_COOKIE(sock_cookie); ++- ++-u64 __sock_gen_cookie(struct sock *sk) ++-{ ++- while (1) { ++- u64 res = atomic64_read(&sk->sk_cookie); ++- ++- if (res) ++- return res; ++- res = gen_cookie_next(&sock_cookie); ++- atomic64_cmpxchg(&sk->sk_cookie, 0, res); ++- } ++-} ++- ++ int sock_diag_check_cookie(struct sock *sk, const __u32 *cookie) ++ { ++ u64 res; ++--- a/net/ipv4/Kconfig +++++ b/net/ipv4/Kconfig ++@@ -414,6 +414,7 @@ config INET_TUNNEL ++ ++ config INET_DIAG ++ tristate "INET: socket monitoring interface" +++ select SOCK_DIAG ++ default y ++ help ++ Support for INET (TCP, DCCP, etc) socket monitoring interface used by ++--- a/net/netlink/Kconfig +++++ b/net/netlink/Kconfig ++@@ -5,6 +5,7 @@ ++ ++ config NETLINK_DIAG ++ tristate "NETLINK: socket monitoring interface" +++ select SOCK_DIAG ++ default n ++ help ++ Support for NETLINK socket monitoring interface used by the ss tool. ++--- a/net/packet/Kconfig +++++ b/net/packet/Kconfig ++@@ -19,6 +19,7 @@ config PACKET ++ config PACKET_DIAG ++ tristate "Packet: sockets monitoring interface" ++ depends on PACKET +++ select SOCK_DIAG ++ default n ++ help ++ Support for PF_PACKET sockets monitoring interface used by the ss tool. ++--- a/net/unix/Kconfig +++++ b/net/unix/Kconfig ++@@ -28,6 +28,7 @@ config UNIX_SCM ++ config UNIX_DIAG ++ tristate "UNIX: socket monitoring interface" ++ depends on UNIX +++ select SOCK_DIAG ++ default n ++ help ++ Support for UNIX socket monitoring interface used by the ss tool. +diff --git a/target/linux/generic/hack-5.10/902-debloat_proc.patch b/target/linux/generic/hack-5.10/902-debloat_proc.patch +new file mode 100644 +index 0000000000..5a6d7d058e +--- /dev/null ++++ b/target/linux/generic/hack-5.10/902-debloat_proc.patch +@@ -0,0 +1,408 @@ ++From 9e3f1d0805b2d919904dd9a4ff0d956314cc3cba Mon Sep 17 00:00:00 2001 ++From: Felix Fietkau ++Date: Sat, 8 Jul 2017 08:20:09 +0200 ++Subject: debloat: procfs ++ ++Signed-off-by: Felix Fietkau ++--- ++ fs/locks.c | 2 ++ ++ fs/proc/Kconfig | 5 +++++ ++ fs/proc/consoles.c | 3 +++ ++ fs/proc/proc_tty.c | 11 ++++++++++- ++ include/net/snmp.h | 18 +++++++++++++++++- ++ ipc/msg.c | 3 +++ ++ ipc/sem.c | 2 ++ ++ ipc/shm.c | 2 ++ ++ ipc/util.c | 3 +++ ++ kernel/exec_domain.c | 2 ++ ++ kernel/irq/proc.c | 9 +++++++++ ++ kernel/time/timer_list.c | 2 ++ ++ mm/vmalloc.c | 2 ++ ++ mm/vmstat.c | 8 +++++--- ++ net/8021q/vlanproc.c | 6 ++++++ ++ net/core/net-procfs.c | 18 ++++++++++++------ ++ net/core/sock.c | 2 ++ ++ net/ipv4/fib_trie.c | 18 ++++++++++++------ ++ net/ipv4/proc.c | 3 +++ ++ net/ipv4/route.c | 3 +++ ++ 20 files changed, 105 insertions(+), 17 deletions(-) ++ ++--- a/fs/locks.c +++++ b/fs/locks.c ++@@ -2996,6 +2996,8 @@ static const struct seq_operations locks ++ ++ static int __init proc_locks_init(void) ++ { +++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) +++ return 0; ++ proc_create_seq_private("locks", 0, NULL, &locks_seq_operations, ++ sizeof(struct locks_iterator), NULL); ++ return 0; ++--- a/fs/proc/Kconfig +++++ b/fs/proc/Kconfig ++@@ -100,6 +100,11 @@ config PROC_CHILDREN ++ Say Y if you are running any user-space software which takes benefit from ++ this interface. For example, rkt is such a piece of software. ++ +++config PROC_STRIPPED +++ default n +++ depends on EXPERT +++ bool "Strip non-essential /proc functionality to reduce code size" +++ ++ config PROC_PID_ARCH_STATUS ++ def_bool n ++ depends on PROC_FS ++--- a/fs/proc/consoles.c +++++ b/fs/proc/consoles.c ++@@ -92,6 +92,9 @@ static const struct seq_operations conso ++ ++ static int __init proc_consoles_init(void) ++ { +++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) +++ return 0; +++ ++ proc_create_seq("consoles", 0, NULL, &consoles_op); ++ return 0; ++ } ++--- a/fs/proc/proc_tty.c +++++ b/fs/proc/proc_tty.c ++@@ -133,7 +133,10 @@ static const struct seq_operations tty_d ++ void proc_tty_register_driver(struct tty_driver *driver) ++ { ++ struct proc_dir_entry *ent; ++- +++ +++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) +++ return; +++ ++ if (!driver->driver_name || driver->proc_entry || ++ !driver->ops->proc_show) ++ return; ++@@ -150,6 +153,9 @@ void proc_tty_unregister_driver(struct t ++ { ++ struct proc_dir_entry *ent; ++ +++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) +++ return; +++ ++ ent = driver->proc_entry; ++ if (!ent) ++ return; ++@@ -164,6 +170,9 @@ void proc_tty_unregister_driver(struct t ++ */ ++ void __init proc_tty_init(void) ++ { +++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) +++ return; +++ ++ if (!proc_mkdir("tty", NULL)) ++ return; ++ proc_mkdir("tty/ldisc", NULL); /* Preserved: it's userspace visible */ ++--- a/include/net/snmp.h +++++ b/include/net/snmp.h ++@@ -124,6 +124,21 @@ struct linux_tls_mib { ++ #define DECLARE_SNMP_STAT(type, name) \ ++ extern __typeof__(type) __percpu *name ++ +++#ifdef CONFIG_PROC_STRIPPED +++#define __SNMP_STATS_DUMMY(mib) \ +++ do { (void) mib->mibs[0]; } while(0) +++ +++#define __SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib) +++#define SNMP_INC_STATS_ATOMIC_LONG(mib, field) __SNMP_STATS_DUMMY(mib) +++#define SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib) +++#define SNMP_DEC_STATS(mib, field) __SNMP_STATS_DUMMY(mib) +++#define __SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib) +++#define SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib) +++#define SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib) +++#define __SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib) +++ +++#else +++ ++ #define __SNMP_INC_STATS(mib, field) \ ++ __this_cpu_inc(mib->mibs[field]) ++ ++@@ -154,8 +169,9 @@ struct linux_tls_mib { ++ __this_cpu_add(ptr[basefield##OCTETS], addend); \ ++ } while (0) ++ +++#endif ++ ++-#if BITS_PER_LONG==32 +++#if (BITS_PER_LONG==32) && !defined(CONFIG_PROC_STRIPPED) ++ ++ #define __SNMP_ADD_STATS64(mib, field, addend) \ ++ do { \ ++--- a/ipc/msg.c +++++ b/ipc/msg.c ++@@ -1348,6 +1348,9 @@ void __init msg_init(void) ++ { ++ msg_init_ns(&init_ipc_ns); ++ +++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) +++ return; +++ ++ ipc_init_proc_interface("sysvipc/msg", ++ " key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n", ++ IPC_MSG_IDS, sysvipc_msg_proc_show); ++--- a/ipc/sem.c +++++ b/ipc/sem.c ++@@ -266,6 +266,8 @@ void sem_exit_ns(struct ipc_namespace *n ++ void __init sem_init(void) ++ { ++ sem_init_ns(&init_ipc_ns); +++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) +++ return; ++ ipc_init_proc_interface("sysvipc/sem", ++ " key semid perms nsems uid gid cuid cgid otime ctime\n", ++ IPC_SEM_IDS, sysvipc_sem_proc_show); ++--- a/ipc/shm.c +++++ b/ipc/shm.c ++@@ -144,6 +144,8 @@ pure_initcall(ipc_ns_init); ++ ++ void __init shm_init(void) ++ { +++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) +++ return; ++ ipc_init_proc_interface("sysvipc/shm", ++ #if BITS_PER_LONG <= 32 ++ " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap\n", ++--- a/ipc/util.c +++++ b/ipc/util.c ++@@ -140,6 +140,9 @@ void __init ipc_init_proc_interface(cons ++ struct proc_dir_entry *pde; ++ struct ipc_proc_iface *iface; ++ +++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) +++ return; +++ ++ iface = kmalloc(sizeof(*iface), GFP_KERNEL); ++ if (!iface) ++ return; ++--- a/kernel/exec_domain.c +++++ b/kernel/exec_domain.c ++@@ -29,6 +29,8 @@ static int execdomains_proc_show(struct ++ ++ static int __init proc_execdomains_init(void) ++ { +++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) +++ return 0; ++ proc_create_single("execdomains", 0, NULL, execdomains_proc_show); ++ return 0; ++ } ++--- a/kernel/irq/proc.c +++++ b/kernel/irq/proc.c ++@@ -341,6 +341,9 @@ void register_irq_proc(unsigned int irq, ++ void __maybe_unused *irqp = (void *)(unsigned long) irq; ++ char name [MAX_NAMELEN]; ++ +++ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP)) +++ return; +++ ++ if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip)) ++ return; ++ ++@@ -394,6 +397,9 @@ void unregister_irq_proc(unsigned int ir ++ { ++ char name [MAX_NAMELEN]; ++ +++ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP)) +++ return; +++ ++ if (!root_irq_dir || !desc->dir) ++ return; ++ #ifdef CONFIG_SMP ++@@ -432,6 +438,9 @@ void init_irq_proc(void) ++ unsigned int irq; ++ struct irq_desc *desc; ++ +++ if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP)) +++ return; +++ ++ /* create /proc/irq */ ++ root_irq_dir = proc_mkdir("irq", NULL); ++ if (!root_irq_dir) ++--- a/kernel/time/timer_list.c +++++ b/kernel/time/timer_list.c ++@@ -370,6 +370,8 @@ static int __init init_timer_list_procfs ++ { ++ struct proc_dir_entry *pe; ++ +++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) +++ return 0; ++ pe = proc_create_seq_private("timer_list", 0400, NULL, &timer_list_sops, ++ sizeof(struct timer_list_iter), NULL); ++ if (!pe) ++--- a/mm/vmalloc.c +++++ b/mm/vmalloc.c ++@@ -3572,6 +3572,8 @@ static const struct seq_operations vmall ++ ++ static int __init proc_vmalloc_init(void) ++ { +++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) +++ return 0; ++ if (IS_ENABLED(CONFIG_NUMA)) ++ proc_create_seq_private("vmallocinfo", 0400, NULL, ++ &vmalloc_op, ++--- a/mm/vmstat.c +++++ b/mm/vmstat.c ++@@ -2044,10 +2044,12 @@ void __init init_mm_internals(void) ++ start_shepherd_timer(); ++ #endif ++ #ifdef CONFIG_PROC_FS ++- proc_create_seq("buddyinfo", 0444, NULL, &fragmentation_op); ++- proc_create_seq("pagetypeinfo", 0400, NULL, &pagetypeinfo_op); +++ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) { +++ proc_create_seq("buddyinfo", 0444, NULL, &fragmentation_op); +++ proc_create_seq("pagetypeinfo", 0400, NULL, &pagetypeinfo_op); +++ proc_create_seq("zoneinfo", 0444, NULL, &zoneinfo_op); +++ } ++ proc_create_seq("vmstat", 0444, NULL, &vmstat_op); ++- proc_create_seq("zoneinfo", 0444, NULL, &zoneinfo_op); ++ #endif ++ } ++ ++--- a/net/8021q/vlanproc.c +++++ b/net/8021q/vlanproc.c ++@@ -93,6 +93,9 @@ void vlan_proc_cleanup(struct net *net) ++ { ++ struct vlan_net *vn = net_generic(net, vlan_net_id); ++ +++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) +++ return; +++ ++ if (vn->proc_vlan_conf) ++ remove_proc_entry(name_conf, vn->proc_vlan_dir); ++ ++@@ -112,6 +115,9 @@ int __net_init vlan_proc_init(struct net ++ { ++ struct vlan_net *vn = net_generic(net, vlan_net_id); ++ +++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) +++ return 0; +++ ++ vn->proc_vlan_dir = proc_net_mkdir(net, name_root, net->proc_net); ++ if (!vn->proc_vlan_dir) ++ goto err; ++--- a/net/core/net-procfs.c +++++ b/net/core/net-procfs.c ++@@ -290,10 +290,12 @@ static int __net_init dev_proc_net_init( ++ if (!proc_create_net("dev", 0444, net->proc_net, &dev_seq_ops, ++ sizeof(struct seq_net_private))) ++ goto out; ++- if (!proc_create_seq("softnet_stat", 0444, net->proc_net, +++ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && +++ !proc_create_seq("softnet_stat", 0444, net->proc_net, ++ &softnet_seq_ops)) ++ goto out_dev; ++- if (!proc_create_net("ptype", 0444, net->proc_net, &ptype_seq_ops, +++ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && +++ !proc_create_net("ptype", 0444, net->proc_net, &ptype_seq_ops, ++ sizeof(struct seq_net_private))) ++ goto out_softnet; ++ ++@@ -303,9 +305,11 @@ static int __net_init dev_proc_net_init( ++ out: ++ return rc; ++ out_ptype: ++- remove_proc_entry("ptype", net->proc_net); +++ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) +++ remove_proc_entry("ptype", net->proc_net); ++ out_softnet: ++- remove_proc_entry("softnet_stat", net->proc_net); +++ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) +++ remove_proc_entry("softnet_stat", net->proc_net); ++ out_dev: ++ remove_proc_entry("dev", net->proc_net); ++ goto out; ++@@ -315,8 +319,10 @@ static void __net_exit dev_proc_net_exit ++ { ++ wext_proc_exit(net); ++ ++- remove_proc_entry("ptype", net->proc_net); ++- remove_proc_entry("softnet_stat", net->proc_net); +++ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) { +++ remove_proc_entry("ptype", net->proc_net); +++ remove_proc_entry("softnet_stat", net->proc_net); +++ } ++ remove_proc_entry("dev", net->proc_net); ++ } ++ ++--- a/net/core/sock.c +++++ b/net/core/sock.c ++@@ -3680,6 +3680,8 @@ static __net_initdata struct pernet_oper ++ ++ static int __init proto_init(void) ++ { +++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) +++ return 0; ++ return register_pernet_subsys(&proto_net_ops); ++ } ++ ++--- a/net/ipv4/fib_trie.c +++++ b/net/ipv4/fib_trie.c ++@@ -2986,11 +2986,13 @@ static const struct seq_operations fib_r ++ ++ int __net_init fib_proc_init(struct net *net) ++ { ++- if (!proc_create_net("fib_trie", 0444, net->proc_net, &fib_trie_seq_ops, +++ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && +++ !proc_create_net("fib_trie", 0444, net->proc_net, &fib_trie_seq_ops, ++ sizeof(struct fib_trie_iter))) ++ goto out1; ++ ++- if (!proc_create_net_single("fib_triestat", 0444, net->proc_net, +++ if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && +++ !proc_create_net_single("fib_triestat", 0444, net->proc_net, ++ fib_triestat_seq_show, NULL)) ++ goto out2; ++ ++@@ -3001,17 +3003,21 @@ int __net_init fib_proc_init(struct net ++ return 0; ++ ++ out3: ++- remove_proc_entry("fib_triestat", net->proc_net); +++ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) +++ remove_proc_entry("fib_triestat", net->proc_net); ++ out2: ++- remove_proc_entry("fib_trie", net->proc_net); +++ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) +++ remove_proc_entry("fib_trie", net->proc_net); ++ out1: ++ return -ENOMEM; ++ } ++ ++ void __net_exit fib_proc_exit(struct net *net) ++ { ++- remove_proc_entry("fib_trie", net->proc_net); ++- remove_proc_entry("fib_triestat", net->proc_net); +++ if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) { +++ remove_proc_entry("fib_trie", net->proc_net); +++ remove_proc_entry("fib_triestat", net->proc_net); +++ } ++ remove_proc_entry("route", net->proc_net); ++ } ++ ++--- a/net/ipv4/proc.c +++++ b/net/ipv4/proc.c ++@@ -528,5 +528,8 @@ static __net_initdata struct pernet_oper ++ ++ int __init ip_misc_proc_init(void) ++ { +++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) +++ return 0; +++ ++ return register_pernet_subsys(&ip_proc_ops); ++ } ++--- a/net/ipv4/route.c +++++ b/net/ipv4/route.c ++@@ -409,6 +409,9 @@ static struct pernet_operations ip_rt_pr ++ ++ static int __init ip_rt_proc_init(void) ++ { +++ if (IS_ENABLED(CONFIG_PROC_STRIPPED)) +++ return 0; +++ ++ return register_pernet_subsys(&ip_rt_proc_ops); ++ } ++ +diff --git a/target/linux/generic/hack-5.10/904-debloat_dma_buf.patch b/target/linux/generic/hack-5.10/904-debloat_dma_buf.patch +new file mode 100644 +index 0000000000..3c5af9d666 +--- /dev/null ++++ b/target/linux/generic/hack-5.10/904-debloat_dma_buf.patch +@@ -0,0 +1,82 @@ ++From e3692cb2fcd5ba1244512a0f43b8118f65f1c375 Mon Sep 17 00:00:00 2001 ++From: Felix Fietkau ++Date: Sat, 8 Jul 2017 08:20:43 +0200 ++Subject: debloat: dmabuf ++ ++Signed-off-by: Felix Fietkau ++--- ++ drivers/base/Kconfig | 2 +- ++ drivers/dma-buf/Makefile | 10 +++++++--- ++ drivers/dma-buf/dma-buf.c | 4 +++- ++ kernel/sched/core.c | 1 + ++ 4 files changed, 12 insertions(+), 5 deletions(-) ++ ++--- a/drivers/base/Kconfig +++++ b/drivers/base/Kconfig ++@@ -184,7 +184,7 @@ config SOC_BUS ++ source "drivers/base/regmap/Kconfig" ++ ++ config DMA_SHARED_BUFFER ++- bool +++ tristate ++ default n ++ select IRQ_WORK ++ help ++--- a/drivers/dma-buf/Makefile +++++ b/drivers/dma-buf/Makefile ++@@ -1,15 +1,19 @@ ++ # SPDX-License-Identifier: GPL-2.0-only ++-obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \ +++obj-$(CONFIG_DMA_SHARED_BUFFER) := dma-shared-buffer.o +++ +++dma-buf-objs-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \ ++ dma-resv.o seqno-fence.o ++-obj-$(CONFIG_DMABUF_HEAPS) += dma-heap.o ++-obj-$(CONFIG_DMABUF_HEAPS) += heaps/ ++-obj-$(CONFIG_SYNC_FILE) += sync_file.o ++-obj-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o ++-obj-$(CONFIG_UDMABUF) += udmabuf.o +++dma-buf-objs-$(CONFIG_DMABUF_HEAPS) += dma-heap.o +++dma-buf-objs-$(CONFIG_DMABUF_HEAPS) += heaps/ +++dma-buf-objs-$(CONFIG_SYNC_FILE) += sync_file.o +++dma-buf-objs-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o +++dma-buf-objs-$(CONFIG_UDMABUF) += udmabuf.o ++ ++ dmabuf_selftests-y := \ ++ selftest.o \ ++ st-dma-fence.o \ ++ st-dma-fence-chain.o ++ ++-obj-$(CONFIG_DMABUF_SELFTESTS) += dmabuf_selftests.o +++dma-buf-objs-$(CONFIG_DMABUF_SELFTESTS) += dmabuf_selftests.o +++ +++dma-shared-buffer-objs := $(dma-buf-objs-y) ++--- a/drivers/dma-buf/dma-buf.c +++++ b/drivers/dma-buf/dma-buf.c ++@@ -1418,4 +1418,5 @@ static void __exit dma_buf_deinit(void) ++ dma_buf_uninit_debugfs(); ++ kern_unmount(dma_buf_mnt); ++ } ++-__exitcall(dma_buf_deinit); +++module_exit(dma_buf_deinit); +++MODULE_LICENSE("GPL"); ++--- a/kernel/sched/core.c +++++ b/kernel/sched/core.c ++@@ -3054,6 +3054,7 @@ int wake_up_state(struct task_struct *p, ++ { ++ return try_to_wake_up(p, state, 0); ++ } +++EXPORT_SYMBOL_GPL(wake_up_state); ++ ++ /* ++ * Perform scheduler related setup for a newly forked process p. ++--- a/fs/d_path.c +++++ b/fs/d_path.c ++@@ -311,6 +311,7 @@ char *dynamic_dname(struct dentry *dentr ++ buffer += buflen - sz; ++ return memcpy(buffer, temp, sz); ++ } +++EXPORT_SYMBOL_GPL(dynamic_dname); ++ ++ char *simple_dname(struct dentry *dentry, char *buffer, int buflen) ++ { +diff --git a/target/linux/generic/hack-5.10/910-kobject_uevent.patch b/target/linux/generic/hack-5.10/910-kobject_uevent.patch +new file mode 100644 +index 0000000000..c4c41ca400 +--- /dev/null ++++ b/target/linux/generic/hack-5.10/910-kobject_uevent.patch +@@ -0,0 +1,32 @@ ++From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001 ++From: Felix Fietkau ++Date: Sun, 16 Jul 2017 16:56:10 +0200 ++Subject: lib: add uevent_next_seqnum() ++ ++Signed-off-by: Felix Fietkau ++--- ++ include/linux/kobject.h | 5 +++++ ++ lib/kobject_uevent.c | 37 +++++++++++++++++++++++++++++++++++++ ++ 2 files changed, 42 insertions(+) ++ ++--- a/lib/kobject_uevent.c +++++ b/lib/kobject_uevent.c ++@@ -179,6 +179,18 @@ out: ++ return r; ++ } ++ +++u64 uevent_next_seqnum(void) +++{ +++ u64 seq; +++ +++ mutex_lock(&uevent_sock_mutex); +++ seq = ++uevent_seqnum; +++ mutex_unlock(&uevent_sock_mutex); +++ +++ return seq; +++} +++EXPORT_SYMBOL_GPL(uevent_next_seqnum); +++ ++ /** ++ * kobject_synth_uevent - send synthetic uevent with arguments ++ * +diff --git a/target/linux/generic/hack-5.10/911-kobject_add_broadcast_uevent.patch b/target/linux/generic/hack-5.10/911-kobject_add_broadcast_uevent.patch +new file mode 100644 +index 0000000000..1f3002da4c +--- /dev/null ++++ b/target/linux/generic/hack-5.10/911-kobject_add_broadcast_uevent.patch +@@ -0,0 +1,76 @@ ++From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001 ++From: Felix Fietkau ++Date: Sun, 16 Jul 2017 16:56:10 +0200 ++Subject: lib: add uevent_next_seqnum() ++ ++Signed-off-by: Felix Fietkau ++--- ++ include/linux/kobject.h | 5 +++++ ++ lib/kobject_uevent.c | 37 +++++++++++++++++++++++++++++++++++++ ++ 2 files changed, 42 insertions(+) ++ ++--- a/include/linux/kobject.h +++++ b/include/linux/kobject.h ++@@ -32,6 +32,8 @@ ++ #define UEVENT_NUM_ENVP 64 /* number of env pointers */ ++ #define UEVENT_BUFFER_SIZE 2048 /* buffer for the variables */ ++ +++struct sk_buff; +++ ++ #ifdef CONFIG_UEVENT_HELPER ++ /* path to the userspace helper executed on an event */ ++ extern char uevent_helper[]; ++@@ -244,4 +246,7 @@ int kobject_synth_uevent(struct kobject ++ __printf(2, 3) ++ int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...); ++ +++int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, +++ gfp_t allocation); +++ ++ #endif /* _KOBJECT_H_ */ ++--- a/lib/kobject_uevent.c +++++ b/lib/kobject_uevent.c ++@@ -690,6 +690,43 @@ int add_uevent_var(struct kobj_uevent_en ++ EXPORT_SYMBOL_GPL(add_uevent_var); ++ ++ #if defined(CONFIG_NET) +++int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, +++ gfp_t allocation) +++{ +++ struct uevent_sock *ue_sk; +++ int err = 0; +++ +++ /* send netlink message */ +++ mutex_lock(&uevent_sock_mutex); +++ list_for_each_entry(ue_sk, &uevent_sock_list, list) { +++ struct sock *uevent_sock = ue_sk->sk; +++ struct sk_buff *skb2; +++ +++ skb2 = skb_clone(skb, allocation); +++ if (!skb2) +++ break; +++ +++ err = netlink_broadcast(uevent_sock, skb2, pid, group, +++ allocation); +++ if (err) +++ break; +++ } +++ mutex_unlock(&uevent_sock_mutex); +++ +++ kfree_skb(skb); +++ return err; +++} +++#else +++int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, +++ gfp_t allocation) +++{ +++ kfree_skb(skb); +++ return 0; +++} +++#endif +++EXPORT_SYMBOL_GPL(broadcast_uevent); +++ +++#if defined(CONFIG_NET) ++ static int uevent_net_broadcast(struct sock *usk, struct sk_buff *skb, ++ struct netlink_ext_ack *extack) ++ { +diff --git a/target/linux/generic/pending-5.10/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch b/target/linux/generic/pending-5.10/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch +new file mode 100644 +index 0000000000..39b98eac1b +--- /dev/null ++++ b/target/linux/generic/pending-5.10/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch +@@ -0,0 +1,29 @@ ++From: Felix Fietkau ++Date: Thu, 22 Oct 2020 22:00:03 +0200 ++Subject: [PATCH] compiler.h: only include asm/rwonce.h for kernel code ++ ++This header file is not in uapi, which makes any user space code that includes ++linux/compiler.h to fail with the error 'asm/rwonce.h: No such file or directory' ++ ++Fixes: e506ea451254 ("compiler.h: Split {READ,WRITE}_ONCE definitions out into rwonce.h") ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/include/linux/compiler.h +++++ b/include/linux/compiler.h ++@@ -211,6 +211,8 @@ void ftrace_likely_update(struct ftrace_ ++ __v; \ ++ }) ++ +++#include +++ ++ #endif /* __KERNEL__ */ ++ ++ /* ++@@ -243,6 +245,4 @@ static inline void *offset_to_ptr(const ++ */ ++ #define prevent_tail_call_optimization() mb() ++ ++-#include ++- ++ #endif /* __LINUX_COMPILER_H */ +diff --git a/target/linux/generic/pending-5.10/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch b/target/linux/generic/pending-5.10/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch +new file mode 100644 +index 0000000000..cc9f99e8b0 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch +@@ -0,0 +1,57 @@ ++From: Felix Fietkau ++Date: Wed, 18 Apr 2018 10:50:05 +0200 ++Subject: [PATCH] MIPS: only process negative stack offsets on stack traces ++ ++Fixes endless back traces in cases where the compiler emits a stack ++pointer increase in a branch delay slot (probably for some form of ++function return). ++ ++[ 3.475442] BUG: MAX_STACK_TRACE_ENTRIES too low! ++[ 3.480070] turning off the locking correctness validator. ++[ 3.485521] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.14.34 #0 ++[ 3.491475] Stack : 00000000 00000000 00000000 00000000 80e0fce2 00000034 00000000 00000000 ++[ 3.499764] 87c3838c 80696377 8061047c 00000000 00000001 00000001 87c2d850 6534689f ++[ 3.508059] 00000000 00000000 80e10000 00000000 00000000 000000cf 0000000f 00000000 ++[ 3.516353] 00000000 806a0000 00076891 00000000 00000000 00000000 ffffffff 00000000 ++[ 3.524648] 806c0000 00000004 80e10000 806a0000 00000003 80690000 00000000 80700000 ++[ 3.532942] ... ++[ 3.535362] Call Trace: ++[ 3.537818] [<80010a48>] show_stack+0x58/0x100 ++[ 3.542207] [<804c2f78>] dump_stack+0xe8/0x170 ++[ 3.546613] [<80079f90>] save_trace+0xf0/0x110 ++[ 3.551010] [<8007b1ec>] mark_lock+0x33c/0x78c ++[ 3.555413] [<8007bf48>] __lock_acquire+0x2ac/0x1a08 ++[ 3.560337] [<8007de60>] lock_acquire+0x64/0x8c ++[ 3.564846] [<804e1570>] _raw_spin_lock_irqsave+0x54/0x78 ++[ 3.570186] [<801b618c>] kernfs_notify+0x94/0xac ++[ 3.574770] [<801b7b10>] sysfs_notify+0x74/0xa0 ++[ 3.579257] [<801b618c>] kernfs_notify+0x94/0xac ++[ 3.583839] [<801b7b10>] sysfs_notify+0x74/0xa0 ++[ 3.588329] [<801b618c>] kernfs_notify+0x94/0xac ++[ 3.592911] [<801b7b10>] sysfs_notify+0x74/0xa0 ++[ 3.597401] [<801b618c>] kernfs_notify+0x94/0xac ++[ 3.601983] [<801b7b10>] sysfs_notify+0x74/0xa0 ++[ 3.606473] [<801b618c>] kernfs_notify+0x94/0xac ++[ 3.611055] [<801b7b10>] sysfs_notify+0x74/0xa0 ++[ 3.615545] [<801b618c>] kernfs_notify+0x94/0xac ++[ 3.620125] [<801b7b10>] sysfs_notify+0x74/0xa0 ++[ 3.624619] [<801b618c>] kernfs_notify+0x94/0xac ++[ 3.629197] [<801b7b10>] sysfs_notify+0x74/0xa0 ++[ 3.633691] [<801b618c>] kernfs_notify+0x94/0xac ++[ 3.638269] [<801b7b10>] sysfs_notify+0x74/0xa0 ++[ 3.642763] [<801b618c>] kernfs_notify+0x94/0xac ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/arch/mips/kernel/process.c +++++ b/arch/mips/kernel/process.c ++@@ -380,6 +380,8 @@ static inline int is_sp_move_ins(union m ++ ++ if (ip->i_format.opcode == addiu_op || ++ ip->i_format.opcode == daddiu_op) { +++ if (ip->i_format.simmediate > 0) +++ return 0; ++ *frame_size = -ip->i_format.simmediate; ++ return 1; ++ } +diff --git a/target/linux/generic/pending-5.10/110-ehci_hcd_ignore_oc.patch b/target/linux/generic/pending-5.10/110-ehci_hcd_ignore_oc.patch +new file mode 100644 +index 0000000000..138d4fa1c5 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/110-ehci_hcd_ignore_oc.patch +@@ -0,0 +1,79 @@ ++From: Florian Fainelli ++Subject: USB: EHCI: add ignore_oc flag to disable overcurrent checking ++ ++This patch adds an ignore_oc flag which can be set by EHCI controller ++not supporting or wanting to disable overcurrent checking. The EHCI ++platform data in include/linux/usb/ehci_pdriver.h is also augmented to ++take advantage of this new flag. ++ ++Signed-off-by: Florian Fainelli ++--- ++ drivers/usb/host/ehci-hcd.c | 2 +- ++ drivers/usb/host/ehci-hub.c | 4 ++-- ++ drivers/usb/host/ehci-platform.c | 1 + ++ drivers/usb/host/ehci.h | 1 + ++ include/linux/usb/ehci_pdriver.h | 1 + ++ 5 files changed, 6 insertions(+), 3 deletions(-) ++ ++--- a/drivers/usb/host/ehci-hcd.c +++++ b/drivers/usb/host/ehci-hcd.c ++@@ -651,7 +651,7 @@ static int ehci_run (struct usb_hcd *hcd ++ "USB %x.%x started, EHCI %x.%02x%s\n", ++ ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), ++ temp >> 8, temp & 0xff, ++- ignore_oc ? ", overcurrent ignored" : ""); +++ (ignore_oc || ehci->ignore_oc) ? ", overcurrent ignored" : ""); ++ ++ ehci_writel(ehci, INTR_MASK, ++ &ehci->regs->intr_enable); /* Turn On Interrupts */ ++--- a/drivers/usb/host/ehci-hub.c +++++ b/drivers/usb/host/ehci-hub.c ++@@ -643,7 +643,7 @@ ehci_hub_status_data (struct usb_hcd *hc ++ * always set, seem to clear PORT_OCC and PORT_CSC when writing to ++ * PORT_POWER; that's surprising, but maybe within-spec. ++ */ ++- if (!ignore_oc) +++ if (!ignore_oc && !ehci->ignore_oc) ++ mask = PORT_CSC | PORT_PEC | PORT_OCC; ++ else ++ mask = PORT_CSC | PORT_PEC; ++@@ -1013,7 +1013,7 @@ int ehci_hub_control( ++ if (temp & PORT_PEC) ++ status |= USB_PORT_STAT_C_ENABLE << 16; ++ ++- if ((temp & PORT_OCC) && !ignore_oc){ +++ if ((temp & PORT_OCC) && (!ignore_oc && !ehci->ignore_oc)){ ++ status |= USB_PORT_STAT_C_OVERCURRENT << 16; ++ ++ /* ++--- a/drivers/usb/host/ehci-platform.c +++++ b/drivers/usb/host/ehci-platform.c ++@@ -327,6 +327,8 @@ static int ehci_platform_probe(struct pl ++ hcd->has_tt = 1; ++ if (pdata->reset_on_resume) ++ priv->reset_on_resume = true; +++ if (pdata->ignore_oc) +++ ehci->ignore_oc = 1; ++ ++ #ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO ++ if (ehci->big_endian_mmio) { ++--- a/drivers/usb/host/ehci.h +++++ b/drivers/usb/host/ehci.h ++@@ -218,6 +218,7 @@ struct ehci_hcd { /* one per controlle ++ unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */ ++ unsigned need_oc_pp_cycle:1; /* MPC834X port power */ ++ unsigned imx28_write_fix:1; /* For Freescale i.MX28 */ +++ unsigned ignore_oc:1; ++ ++ /* required for usb32 quirk */ ++ #define OHCI_CTRL_HCFS (3 << 6) ++--- a/include/linux/usb/ehci_pdriver.h +++++ b/include/linux/usb/ehci_pdriver.h ++@@ -50,6 +50,7 @@ struct usb_ehci_pdata { ++ unsigned no_io_watchdog:1; ++ unsigned reset_on_resume:1; ++ unsigned dma_mask_64:1; +++ unsigned ignore_oc:1; ++ ++ /* Turn on all power and clocks */ ++ int (*power_on)(struct platform_device *pdev); +diff --git a/target/linux/generic/pending-5.10/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch b/target/linux/generic/pending-5.10/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch +new file mode 100644 +index 0000000000..4e83b98724 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch +@@ -0,0 +1,82 @@ ++From: Tobias Wolf ++Subject: mm: Fix alloc_node_mem_map with ARCH_PFN_OFFSET calculation ++ ++An rt288x (ralink) based router (Belkin F5D8235 v1) does not boot with any ++kernel beyond version 4.3 resulting in: ++ ++BUG: Bad page state in process swapper pfn:086ac ++ ++bisect resulted in: ++ ++a1c34a3bf00af2cede839879502e12dc68491ad5 is the first bad commit ++commit a1c34a3bf00af2cede839879502e12dc68491ad5 ++Author: Laura Abbott ++Date: Thu Nov 5 18:48:46 2015 -0800 ++ ++ mm: Don't offset memmap for flatmem ++ ++ Srinivas Kandagatla reported bad page messages when trying to remove the ++ bottom 2MB on an ARM based IFC6410 board ++ ++ BUG: Bad page state in process swapper pfn:fffa8 ++ page:ef7fb500 count:0 mapcount:0 mapping: (null) index:0x0 ++ flags: 0x96640253(locked|error|dirty|active|arch_1|reclaim|mlocked) ++ page dumped because: PAGE_FLAGS_CHECK_AT_FREE flag(s) set ++ bad because of flags: ++ flags: 0x200041(locked|active|mlocked) ++ Modules linked in: ++ CPU: 0 PID: 0 Comm: swapper Not tainted 3.19.0-rc3-00007-g412f9ba-dirty ++#816 ++ Hardware name: Qualcomm (Flattened Device Tree) ++ unwind_backtrace ++ show_stack ++ dump_stack ++ bad_page ++ free_pages_prepare ++ free_hot_cold_page ++ __free_pages ++ free_highmem_page ++ mem_init ++ start_kernel ++ Disabling lock debugging due to kernel taint ++ [...] ++:040000 040000 2de013c372345fd471cd58f0553c9b38b0ef1cc4 ++0a8156f848733dfa21e16c196dfb6c0a76290709 M mm ++ ++This fix for ARM does not account ARCH_PFN_OFFSET for mem_map as later used by ++page_to_pfn anymore. ++ ++The following output was generated with two hacked in printk statements: ++ ++printk("before %p vs. %p or %p\n", mem_map, mem_map - offset, mem_map - ++(pgdat->node_start_pfn - ARCH_PFN_OFFSET)); ++ if (page_to_pfn(mem_map) != pgdat->node_start_pfn) ++ mem_map -= offset + (pgdat->node_start_pfn - ARCH_PFN_OFFSET); ++printk("after %p\n", mem_map); ++ ++Output: ++ ++[ 0.000000] before 8861b280 vs. 8861b280 or 8851b280 ++[ 0.000000] after 8851b280 ++ ++As seen in the first line mem_map with subtraction of offset does not equal the ++mem_map after subtraction of ARCH_PFN_OFFSET. ++ ++After adding the offset of ARCH_PFN_OFFSET as well to mem_map as the ++previously calculated offset is zero for the named platform it is able to boot ++4.4 and 4.9-rc7 again. ++ ++Signed-off-by: Tobias Wolf ++--- ++ ++--- a/mm/page_alloc.c +++++ b/mm/page_alloc.c ++@@ -6951,7 +6951,7 @@ static void __ref alloc_node_mem_map(str ++ if (pgdat == NODE_DATA(0)) { ++ mem_map = NODE_DATA(0)->node_mem_map; ++ if (page_to_pfn(mem_map) != pgdat->node_start_pfn) ++- mem_map -= offset; +++ mem_map -= offset + (pgdat->node_start_pfn - ARCH_PFN_OFFSET); ++ } ++ #endif ++ } +diff --git a/target/linux/generic/pending-5.10/130-add-linux-spidev-compatible-si3210.patch b/target/linux/generic/pending-5.10/130-add-linux-spidev-compatible-si3210.patch +new file mode 100644 +index 0000000000..355e900a3b +--- /dev/null ++++ b/target/linux/generic/pending-5.10/130-add-linux-spidev-compatible-si3210.patch +@@ -0,0 +1,18 @@ ++From: Giuseppe Lippolis ++Subject: Add the linux,spidev compatible in spidev Several device in ramips have this binding in the dts ++ ++Signed-off-by: Giuseppe Lippolis ++--- ++ drivers/spi/spidev.c | 1 + ++ 1 file changed, 1 insertion(+) ++ ++--- a/drivers/spi/spidev.c +++++ b/drivers/spi/spidev.c ++@@ -682,6 +682,7 @@ static const struct of_device_id spidev_ ++ { .compatible = "lwn,bk4" }, ++ { .compatible = "dh,dhcom-board" }, ++ { .compatible = "menlo,m53cpld" }, +++ { .compatible = "siliconlabs,si3210" }, ++ {}, ++ }; ++ MODULE_DEVICE_TABLE(of, spidev_dt_ids); +diff --git a/target/linux/generic/pending-5.10/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch b/target/linux/generic/pending-5.10/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch +new file mode 100644 +index 0000000000..e48da41fae +--- /dev/null ++++ b/target/linux/generic/pending-5.10/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch +@@ -0,0 +1,78 @@ ++From: Felix Fietkau ++Subject: jffs2: use .rename2 and add RENAME_WHITEOUT support ++ ++It is required for renames on overlayfs ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/fs/jffs2/dir.c +++++ b/fs/jffs2/dir.c ++@@ -609,7 +609,8 @@ static int jffs2_rmdir (struct inode *di ++ return ret; ++ } ++ ++-static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, umode_t mode, dev_t rdev) +++static int __jffs2_mknod (struct inode *dir_i, struct dentry *dentry, +++ umode_t mode, dev_t rdev, bool whiteout) ++ { ++ struct jffs2_inode_info *f, *dir_f; ++ struct jffs2_sb_info *c; ++@@ -748,7 +749,11 @@ static int jffs2_mknod (struct inode *di ++ mutex_unlock(&dir_f->sem); ++ jffs2_complete_reservation(c); ++ ++- d_instantiate_new(dentry, inode); +++ if (!whiteout) +++ d_instantiate_new(dentry, inode); +++ else +++ unlock_new_inode(inode); +++ ++ return 0; ++ ++ fail: ++@@ -756,6 +761,17 @@ static int jffs2_mknod (struct inode *di ++ return ret; ++ } ++ +++static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, umode_t mode, dev_t rdev) +++{ +++ return __jffs2_mknod(dir_i, dentry, mode, rdev, false); +++} +++ +++static int jffs2_whiteout (struct inode *old_dir, struct dentry *old_dentry) +++{ +++ return __jffs2_mknod(old_dir, old_dentry, S_IFCHR | WHITEOUT_MODE, +++ WHITEOUT_DEV, true); +++} +++ ++ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, ++ struct inode *new_dir_i, struct dentry *new_dentry, ++ unsigned int flags) ++@@ -766,7 +782,7 @@ static int jffs2_rename (struct inode *o ++ uint8_t type; ++ uint32_t now; ++ ++- if (flags & ~RENAME_NOREPLACE) +++ if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT)) ++ return -EINVAL; ++ ++ /* The VFS will check for us and prevent trying to rename a ++@@ -832,9 +848,14 @@ static int jffs2_rename (struct inode *o ++ if (d_is_dir(old_dentry) && !victim_f) ++ inc_nlink(new_dir_i); ++ ++- /* Unlink the original */ ++- ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), ++- old_dentry->d_name.name, old_dentry->d_name.len, NULL, now); +++ if (flags & RENAME_WHITEOUT) +++ /* Replace with whiteout */ +++ ret = jffs2_whiteout(old_dir_i, old_dentry); +++ else +++ /* Unlink the original */ +++ ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), +++ old_dentry->d_name.name, +++ old_dentry->d_name.len, NULL, now); ++ ++ /* We don't touch inode->i_nlink */ ++ +diff --git a/target/linux/generic/pending-5.10/141-jffs2-add-RENAME_EXCHANGE-support.patch b/target/linux/generic/pending-5.10/141-jffs2-add-RENAME_EXCHANGE-support.patch +new file mode 100644 +index 0000000000..dbc72339c6 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/141-jffs2-add-RENAME_EXCHANGE-support.patch +@@ -0,0 +1,73 @@ ++From: Felix Fietkau ++Subject: jffs2: add RENAME_EXCHANGE support ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/fs/jffs2/dir.c +++++ b/fs/jffs2/dir.c ++@@ -779,18 +779,31 @@ static int jffs2_rename (struct inode *o ++ int ret; ++ struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb); ++ struct jffs2_inode_info *victim_f = NULL; +++ struct inode *fst_inode = d_inode(old_dentry); +++ struct inode *snd_inode = d_inode(new_dentry); ++ uint8_t type; ++ uint32_t now; ++ ++- if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT)) +++ if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT|RENAME_EXCHANGE)) ++ return -EINVAL; ++ +++ if ((flags & RENAME_EXCHANGE) && (old_dir_i != new_dir_i)) { +++ if (S_ISDIR(fst_inode->i_mode) && !S_ISDIR(snd_inode->i_mode)) { +++ inc_nlink(new_dir_i); +++ drop_nlink(old_dir_i); +++ } +++ else if (!S_ISDIR(fst_inode->i_mode) && S_ISDIR(snd_inode->i_mode)) { +++ drop_nlink(new_dir_i); +++ inc_nlink(old_dir_i); +++ } +++ } +++ ++ /* The VFS will check for us and prevent trying to rename a ++ * file over a directory and vice versa, but if it's a directory, ++ * the VFS can't check whether the victim is empty. The filesystem ++ * needs to do that for itself. ++ */ ++- if (d_really_is_positive(new_dentry)) { +++ if (d_really_is_positive(new_dentry) && !(flags & RENAME_EXCHANGE)) { ++ victim_f = JFFS2_INODE_INFO(d_inode(new_dentry)); ++ if (d_is_dir(new_dentry)) { ++ struct jffs2_full_dirent *fd; ++@@ -825,7 +838,7 @@ static int jffs2_rename (struct inode *o ++ if (ret) ++ return ret; ++ ++- if (victim_f) { +++ if (victim_f && !(flags & RENAME_EXCHANGE)) { ++ /* There was a victim. Kill it off nicely */ ++ if (d_is_dir(new_dentry)) ++ clear_nlink(d_inode(new_dentry)); ++@@ -851,6 +864,12 @@ static int jffs2_rename (struct inode *o ++ if (flags & RENAME_WHITEOUT) ++ /* Replace with whiteout */ ++ ret = jffs2_whiteout(old_dir_i, old_dentry); +++ else if (flags & RENAME_EXCHANGE) +++ /* Replace the original */ +++ ret = jffs2_do_link(c, JFFS2_INODE_INFO(old_dir_i), +++ d_inode(new_dentry)->i_ino, type, +++ old_dentry->d_name.name, old_dentry->d_name.len, +++ now); ++ else ++ /* Unlink the original */ ++ ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), ++@@ -882,7 +901,7 @@ static int jffs2_rename (struct inode *o ++ return ret; ++ } ++ ++- if (d_is_dir(old_dentry)) +++ if (d_is_dir(old_dentry) && !(flags & RENAME_EXCHANGE)) ++ drop_nlink(old_dir_i); ++ ++ new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now); +diff --git a/target/linux/generic/pending-5.10/142-jffs2-add-splice-ops.patch b/target/linux/generic/pending-5.10/142-jffs2-add-splice-ops.patch +new file mode 100644 +index 0000000000..de847a1f5c +--- /dev/null ++++ b/target/linux/generic/pending-5.10/142-jffs2-add-splice-ops.patch +@@ -0,0 +1,20 @@ ++From: Felix Fietkau ++Subject: jffs2: add splice ops ++ ++Add splice_read using generic_file_splice_read. ++Add splice_write using iter_file_splice_write ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/fs/jffs2/file.c +++++ b/fs/jffs2/file.c ++@@ -53,6 +53,8 @@ const struct file_operations jffs2_file_ ++ .open = generic_file_open, ++ .read_iter = generic_file_read_iter, ++ .write_iter = generic_file_write_iter, +++ .splice_read = generic_file_splice_read, +++ .splice_write = iter_file_splice_write, ++ .unlocked_ioctl=jffs2_ioctl, ++ .mmap = generic_file_readonly_mmap, ++ .fsync = jffs2_fsync, +diff --git a/target/linux/generic/pending-5.10/150-bridge_allow_receiption_on_disabled_port.patch b/target/linux/generic/pending-5.10/150-bridge_allow_receiption_on_disabled_port.patch +new file mode 100644 +index 0000000000..6de22b1c7d +--- /dev/null ++++ b/target/linux/generic/pending-5.10/150-bridge_allow_receiption_on_disabled_port.patch +@@ -0,0 +1,45 @@ ++From: Stephen Hemminger ++Subject: bridge: allow receiption on disabled port ++ ++When an ethernet device is enslaved to a bridge, and the bridge STP ++detects loss of carrier (or operational state down), then normally ++packet receiption is blocked. ++ ++This breaks control applications like WPA which maybe expecting to ++receive packets to negotiate to bring link up. The bridge needs to ++block forwarding packets from these disabled ports, but there is no ++hard requirement to not allow local packet delivery. ++ ++Signed-off-by: Stephen Hemminger ++Signed-off-by: Felix Fietkau ++ ++--- a/net/bridge/br_input.c +++++ b/net/bridge/br_input.c ++@@ -195,6 +195,9 @@ static void __br_handle_local_finish(str ++ /* note: already called with rcu_read_lock */ ++ static int br_handle_local_finish(struct net *net, struct sock *sk, struct sk_buff *skb) ++ { +++ struct net_bridge_port *p = br_port_get_rcu(skb->dev); +++ +++ if (p->state != BR_STATE_DISABLED) ++ __br_handle_local_finish(skb); ++ ++ /* return 1 to signal the okfn() was called so it's ok to use the skb */ ++@@ -348,6 +351,17 @@ static rx_handler_result_t br_handle_fra ++ ++ forward: ++ switch (p->state) { +++ case BR_STATE_DISABLED: +++ if (ether_addr_equal(p->br->dev->dev_addr, dest)) +++ skb->pkt_type = PACKET_HOST; +++ +++ if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, +++ dev_net(skb->dev), NULL, skb, skb->dev, NULL, +++ br_handle_local_finish) == 1) { +++ return RX_HANDLER_PASS; +++ } +++ break; +++ ++ case BR_STATE_FORWARDING: ++ case BR_STATE_LEARNING: ++ if (ether_addr_equal(p->br->dev->dev_addr, dest)) +diff --git a/target/linux/generic/pending-5.10/190-rtc-rs5c372-support_alarms_up_to_1_week.patch b/target/linux/generic/pending-5.10/190-rtc-rs5c372-support_alarms_up_to_1_week.patch +new file mode 100644 +index 0000000000..13b79b5c09 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/190-rtc-rs5c372-support_alarms_up_to_1_week.patch +@@ -0,0 +1,94 @@ ++From: Daniel González Cabanelas ++Subject: [PATCH 1/2] rtc: rs5c372: support alarms up to 1 week ++ ++The Ricoh R2221x, R2223x, RS5C372, RV5C387A chips can handle 1 week ++alarms. ++ ++Read the "wday" alarm register and convert it to a date to support up 1 ++week in our driver. ++ ++Signed-off-by: Daniel González Cabanelas ++--- ++ drivers/rtc/rtc-rs5c372.c | 48 ++++++++++++++++++++++++++++++++++----- ++ 1 file changed, 42 insertions(+), 6 deletions(-) ++ ++--- a/drivers/rtc/rtc-rs5c372.c +++++ b/drivers/rtc/rtc-rs5c372.c ++@@ -393,7 +393,9 @@ static int rs5c_read_alarm(struct device ++ { ++ struct i2c_client *client = to_i2c_client(dev); ++ struct rs5c372 *rs5c = i2c_get_clientdata(client); ++- int status; +++ int status, wday_offs; +++ struct rtc_time rtc; +++ unsigned long alarm_secs; ++ ++ status = rs5c_get_regs(rs5c); ++ if (status < 0) ++@@ -403,6 +405,30 @@ static int rs5c_read_alarm(struct device ++ t->time.tm_sec = 0; ++ t->time.tm_min = bcd2bin(rs5c->regs[RS5C_REG_ALARM_A_MIN] & 0x7f); ++ t->time.tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C_REG_ALARM_A_HOURS]); +++ t->time.tm_wday = ffs(rs5c->regs[RS5C_REG_ALARM_A_WDAY] & 0x7f) - 1; +++ +++ /* determine the day, month and year based on alarm wday, taking as a +++ * reference the current time from the rtc +++ */ +++ status = rs5c372_rtc_read_time(dev, &rtc); +++ if (status < 0) +++ return status; +++ +++ wday_offs = t->time.tm_wday - rtc.tm_wday; +++ alarm_secs = mktime64(rtc.tm_year + 1900, +++ rtc.tm_mon + 1, +++ rtc.tm_mday + wday_offs, +++ t->time.tm_hour, +++ t->time.tm_min, +++ t->time.tm_sec); +++ +++ if (wday_offs < 0 || (wday_offs == 0 && +++ (t->time.tm_hour < rtc.tm_hour || +++ (t->time.tm_hour == rtc.tm_hour && +++ t->time.tm_min <= rtc.tm_min)))) +++ alarm_secs += 7 * 86400; +++ +++ rtc_time64_to_tm(alarm_secs, &t->time); ++ ++ /* ... and status */ ++ t->enabled = !!(rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE); ++@@ -417,12 +443,20 @@ static int rs5c_set_alarm(struct device ++ struct rs5c372 *rs5c = i2c_get_clientdata(client); ++ int status, addr, i; ++ unsigned char buf[3]; +++ struct rtc_time rtc_tm; +++ unsigned long rtc_secs, alarm_secs; ++ ++- /* only handle up to 24 hours in the future, like RTC_ALM_SET */ ++- if (t->time.tm_mday != -1 ++- || t->time.tm_mon != -1 ++- || t->time.tm_year != -1) +++ /* chip only can handle alarms up to one week in the future*/ +++ status = rs5c372_rtc_read_time(dev, &rtc_tm); +++ if (status) +++ return status; +++ rtc_secs = rtc_tm_to_time64(&rtc_tm); +++ alarm_secs = rtc_tm_to_time64(&t->time); +++ if (alarm_secs >= rtc_secs + 7 * 86400) { +++ dev_err(dev, "%s: alarm maximum is one week in the future (%d)\n", +++ __func__, status); ++ return -EINVAL; +++ } ++ ++ /* REVISIT: round up tm_sec */ ++ ++@@ -443,7 +477,9 @@ static int rs5c_set_alarm(struct device ++ /* set alarm */ ++ buf[0] = bin2bcd(t->time.tm_min); ++ buf[1] = rs5c_hr2reg(rs5c, t->time.tm_hour); ++- buf[2] = 0x7f; /* any/all days */ +++ /* each bit is the day of the week, 0x7f means all days */ +++ buf[2] = (t->time.tm_wday >= 0 && t->time.tm_wday < 7) ? +++ BIT(t->time.tm_wday) : 0x7f; ++ ++ for (i = 0; i < sizeof(buf); i++) { ++ addr = RS5C_ADDR(RS5C_REG_ALARM_A_MIN + i); +diff --git a/target/linux/generic/pending-5.10/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch b/target/linux/generic/pending-5.10/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch +new file mode 100644 +index 0000000000..7e9d0e66c0 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch +@@ -0,0 +1,70 @@ ++From: Daniel González Cabanelas ++Subject: [PATCH 2/2] rtc: rs5c372: let the alarm to be used as wakeup source ++ ++Currently there is no use for the interrupts on the rs5c372 RTC and the ++wakealarm isn't enabled. There are some devices like NASes which use this ++RTC to wake up from the power off state when the INTR pin is activated by ++the alarm clock. ++ ++Enable the alarm and let to be used as a wakeup source. ++ ++Tested on a Buffalo LS421DE NAS. ++ ++Signed-off-by: Daniel González Cabanelas ++--- ++ drivers/rtc/rtc-rs5c372.c | 16 ++++++++++++++++ ++ 1 file changed, 16 insertions(+) ++ ++--- a/drivers/rtc/rtc-rs5c372.c +++++ b/drivers/rtc/rtc-rs5c372.c ++@@ -654,6 +654,7 @@ static int rs5c372_probe(struct i2c_clie ++ int err = 0; ++ int smbus_mode = 0; ++ struct rs5c372 *rs5c372; +++ bool rs5c372_can_wakeup_device = false; ++ ++ dev_dbg(&client->dev, "%s\n", __func__); ++ ++@@ -689,6 +690,12 @@ static int rs5c372_probe(struct i2c_clie ++ else ++ rs5c372->type = id->driver_data; ++ +++#ifdef CONFIG_OF +++ if(of_property_read_bool(client->dev.of_node, +++ "wakeup-source")) +++ rs5c372_can_wakeup_device = true; +++#endif +++ ++ /* we read registers 0x0f then 0x00-0x0f; skip the first one */ ++ rs5c372->regs = &rs5c372->buf[1]; ++ rs5c372->smbus = smbus_mode; ++@@ -722,6 +729,8 @@ static int rs5c372_probe(struct i2c_clie ++ goto exit; ++ } ++ +++ rs5c372->has_irq = 1; +++ ++ /* if the oscillator lost power and no other software (like ++ * the bootloader) set it up, do it here. ++ * ++@@ -748,6 +757,10 @@ static int rs5c372_probe(struct i2c_clie ++ ); ++ ++ /* REVISIT use client->irq to register alarm irq ... */ +++ if (rs5c372_can_wakeup_device) { +++ device_init_wakeup(&client->dev, true); +++ } +++ ++ rs5c372->rtc = devm_rtc_device_register(&client->dev, ++ rs5c372_driver.driver.name, ++ &rs5c372_rtc_ops, THIS_MODULE); ++@@ -761,6 +774,9 @@ static int rs5c372_probe(struct i2c_clie ++ if (err) ++ goto exit; ++ +++ /* the rs5c372 alarm only supports a minute accuracy */ +++ rs5c372->rtc->uie_unsupported = 1; +++ ++ return 0; ++ ++ exit: +diff --git a/target/linux/generic/pending-5.10/201-extra_optimization.patch b/target/linux/generic/pending-5.10/201-extra_optimization.patch +new file mode 100644 +index 0000000000..53486680a2 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/201-extra_optimization.patch +@@ -0,0 +1,31 @@ ++From: Felix Fietkau ++Subject: Upgrade to Linux 2.6.19 ++ ++- Includes large parts of the patch from #1021 by dpalffy ++- Includes RB532 NAND driver changes by n0-1 ++ ++[john@phrozen.org: feix will add this to his upstream queue] ++ ++lede-commit: bff468813f78f81e36ebb2a3f4354de7365e640f ++Signed-off-by: Felix Fietkau ++--- ++ Makefile | 6 +++--- ++ 1 file changed, 3 insertions(+), 3 deletions(-) ++ ++--- a/Makefile +++++ b/Makefile ++@@ -733,11 +733,11 @@ KBUILD_CFLAGS += $(call cc-disable-warni ++ KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member) ++ ++ ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE ++-KBUILD_CFLAGS += -O2 +++KBUILD_CFLAGS += -O2 $(EXTRA_OPTIMIZATION) ++ else ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE_O3 ++-KBUILD_CFLAGS += -O3 +++KBUILD_CFLAGS += -O3 $(EXTRA_OPTIMIZATION) ++ else ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE ++-KBUILD_CFLAGS += -Os +++KBUILD_CFLAGS += -Os -fno-reorder-blocks -fno-tree-ch $(EXTRA_OPTIMIZATION) ++ endif ++ ++ # Tell gcc to never replace conditional load with a non-conditional one +diff --git a/target/linux/generic/pending-5.10/203-kallsyms_uncompressed.patch b/target/linux/generic/pending-5.10/203-kallsyms_uncompressed.patch +new file mode 100644 +index 0000000000..35d0333ad5 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/203-kallsyms_uncompressed.patch +@@ -0,0 +1,119 @@ ++From: Felix Fietkau ++Subject: kernel: add a config option for keeping the kallsyms table uncompressed, saving ~9kb kernel size after lzma on ar71xx ++ ++[john@phrozen.org: added to my upstream queue 30.12.2016] ++lede-commit: e0e3509b5ce2ccf93d4d67ea907613f5f7ec2eed ++Signed-off-by: Felix Fietkau ++--- ++ init/Kconfig | 11 +++++++++++ ++ kernel/kallsyms.c | 8 ++++++++ ++ scripts/kallsyms.c | 12 ++++++++++++ ++ scripts/link-vmlinux.sh | 4 ++++ ++ 4 files changed, 35 insertions(+) ++ ++--- a/init/Kconfig +++++ b/init/Kconfig ++@@ -1384,6 +1384,17 @@ config SYSCTL_ARCH_UNALIGN_ALLOW ++ the unaligned access emulation. ++ see arch/parisc/kernel/unaligned.c for reference ++ +++config KALLSYMS_UNCOMPRESSED +++ bool "Keep kallsyms uncompressed" +++ depends on KALLSYMS +++ help +++ Normally kallsyms contains compressed symbols (using a token table), +++ reducing the uncompressed kernel image size. Keeping the symbol table +++ uncompressed significantly improves the size of this part in compressed +++ kernel images. +++ +++ Say N unless you need compressed kernel images to be small. +++ ++ config HAVE_PCSPKR_PLATFORM ++ bool ++ ++--- a/kernel/kallsyms.c +++++ b/kernel/kallsyms.c ++@@ -77,6 +77,11 @@ static unsigned int kallsyms_expand_symb ++ * For every byte on the compressed symbol data, copy the table ++ * entry for that byte. ++ */ +++#ifdef CONFIG_KALLSYMS_UNCOMPRESSED +++ memcpy(result, data + 1, len - 1); +++ result += len - 1; +++ len = 0; +++#endif ++ while (len) { ++ tptr = &kallsyms_token_table[kallsyms_token_index[*data]]; ++ data++; ++@@ -109,6 +114,9 @@ tail: ++ */ ++ static char kallsyms_get_symbol_type(unsigned int off) ++ { +++#ifdef CONFIG_KALLSYMS_UNCOMPRESSED +++ return kallsyms_names[off + 1]; +++#endif ++ /* ++ * Get just the first code, look it up in the token table, ++ * and return the first char from this token. ++--- a/scripts/kallsyms.c +++++ b/scripts/kallsyms.c ++@@ -58,6 +58,7 @@ static struct addr_range percpu_range = ++ static struct sym_entry **table; ++ static unsigned int table_size, table_cnt; ++ static int all_symbols; +++static int uncompressed; ++ static int absolute_percpu; ++ static int base_relative; ++ ++@@ -480,6 +481,9 @@ static void write_src(void) ++ ++ free(markers); ++ +++ if (uncompressed) +++ return; +++ ++ output_label("kallsyms_token_table"); ++ off = 0; ++ for (i = 0; i < 256; i++) { ++@@ -531,6 +535,9 @@ static unsigned char *find_token(unsigne ++ { ++ int i; ++ +++ if (uncompressed) +++ return NULL; +++ ++ for (i = 0; i < len - 1; i++) { ++ if (str[i] == token[0] && str[i+1] == token[1]) ++ return &str[i]; ++@@ -603,6 +610,9 @@ static void optimize_result(void) ++ { ++ int i, best; ++ +++ if (uncompressed) +++ return; +++ ++ /* using the '\0' symbol last allows compress_symbols to use standard ++ * fast string functions */ ++ for (i = 255; i >= 0; i--) { ++@@ -767,6 +777,8 @@ int main(int argc, char **argv) ++ absolute_percpu = 1; ++ else if (strcmp(argv[i], "--base-relative") == 0) ++ base_relative = 1; +++ else if (strcmp(argv[i], "--uncompressed") == 0) +++ uncompressed = 1; ++ else ++ usage(); ++ } ++--- a/scripts/link-vmlinux.sh +++++ b/scripts/link-vmlinux.sh ++@@ -186,6 +186,10 @@ kallsyms() ++ kallsymopt="${kallsymopt} --base-relative" ++ fi ++ +++ if [ -n "${CONFIG_KALLSYMS_UNCOMPRESSED}" ]; then +++ kallsymopt="${kallsymopt} --uncompressed" +++ fi +++ ++ info KSYMS ${2} ++ ${NM} -n ${1} | scripts/kallsyms ${kallsymopt} > ${2} ++ } +diff --git a/target/linux/generic/pending-5.10/205-backtrace_module_info.patch b/target/linux/generic/pending-5.10/205-backtrace_module_info.patch +new file mode 100644 +index 0000000000..5953214757 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/205-backtrace_module_info.patch +@@ -0,0 +1,41 @@ ++From: Felix Fietkau ++Subject: kernel: when KALLSYMS is disabled, print module address + size for matching backtrace entries ++ ++[john@phrozen.org: felix will add this to his upstream queue] ++ ++lede-commit 53827cdc824556cda910b23ce5030c363b8f1461 ++Signed-off-by: Felix Fietkau ++--- ++ lib/vsprintf.c | 15 +++++++++++---- ++ 1 file changed, 11 insertions(+), 4 deletions(-) ++ ++--- a/lib/vsprintf.c +++++ b/lib/vsprintf.c ++@@ -957,8 +957,10 @@ char *symbol_string(char *buf, char *end ++ struct printf_spec spec, const char *fmt) ++ { ++ unsigned long value; ++-#ifdef CONFIG_KALLSYMS ++ char sym[KSYM_SYMBOL_LEN]; +++#ifndef CONFIG_KALLSYMS +++ struct module *mod; +++ int len; ++ #endif ++ ++ if (fmt[1] == 'R') ++@@ -975,8 +977,14 @@ char *symbol_string(char *buf, char *end ++ ++ return string_nocheck(buf, end, sym, spec); ++ #else ++- return special_hex_number(buf, end, value, sizeof(void *)); +++ len = snprintf(sym, sizeof(sym), "0x%lx", value); +++ mod = __module_address(value); +++ if (mod) +++ snprintf(sym + len, sizeof(sym) - len, " [%s@%p+0x%x]", +++ mod->name, mod->core_layout.base, +++ mod->core_layout.size); ++ #endif +++ return string(buf, end, sym, spec); ++ } ++ ++ static const struct printf_spec default_str_spec = { +diff --git a/target/linux/generic/pending-5.10/240-remove-unsane-filenames-from-deps_initramfs-list.patch b/target/linux/generic/pending-5.10/240-remove-unsane-filenames-from-deps_initramfs-list.patch +new file mode 100644 +index 0000000000..29cfade716 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/240-remove-unsane-filenames-from-deps_initramfs-list.patch +@@ -0,0 +1,30 @@ ++From: Gabor Juhos ++Subject: usr: sanitize deps_initramfs list ++ ++If any filename in the intramfs dependency ++list contains a colon, that causes a kernel ++build error like this: ++ ++/devel/openwrt/build_dir/linux-ar71xx_generic/linux-3.6.6/usr/Makefile:58: *** multiple target patterns. Stop. ++make[5]: *** [usr] Error 2 ++ ++Fix it by removing such filenames from the ++deps_initramfs list. ++ ++Signed-off-by: Gabor Juhos ++Signed-off-by: Felix Fietkau ++--- ++ usr/Makefile | 8 +++++--- ++ 1 file changed, 5 insertions(+), 3 deletions(-) ++ ++--- a/usr/Makefile +++++ b/usr/Makefile ++@@ -61,6 +61,8 @@ hostprogs := gen_init_cpio ++ # The dependency list is generated by gen_initramfs.sh -l ++ -include $(obj)/.initramfs_data.cpio.d ++ +++deps_initramfs := $(foreach v,$(deps_initramfs),$(if $(findstring :,$(v)),,$(v))) +++ ++ # do not try to update files included in initramfs ++ $(deps_initramfs): ; ++ +diff --git a/target/linux/generic/pending-5.10/261-enable_wilink_platform_without_drivers.patch b/target/linux/generic/pending-5.10/261-enable_wilink_platform_without_drivers.patch +new file mode 100644 +index 0000000000..cd31f9d934 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/261-enable_wilink_platform_without_drivers.patch +@@ -0,0 +1,20 @@ ++From: Imre Kaloz ++Subject: [PATCH] hack: net: wireless: make the wl12xx glue code available with ++ compat-wireless, too ++ ++Signed-off-by: Imre Kaloz ++--- ++ drivers/net/wireless/ti/Kconfig | 2 +- ++ 1 file changed, 1 insertion(+), 1 deletion(-) ++ ++--- a/drivers/net/wireless/ti/Kconfig +++++ b/drivers/net/wireless/ti/Kconfig ++@@ -20,7 +20,7 @@ source "drivers/net/wireless/ti/wlcore/K ++ ++ config WILINK_PLATFORM_DATA ++ bool "TI WiLink platform data" ++- depends on WLCORE_SDIO || WL1251_SDIO +++ depends on WLCORE_SDIO || WL1251_SDIO || ARCH_OMAP2PLUS ++ default y ++ help ++ Small platform data bit needed to pass data to the sdio modules. +diff --git a/target/linux/generic/pending-5.10/270-platform-mikrotik-build-bits.patch b/target/linux/generic/pending-5.10/270-platform-mikrotik-build-bits.patch +new file mode 100644 +index 0000000000..df738ef97b +--- /dev/null ++++ b/target/linux/generic/pending-5.10/270-platform-mikrotik-build-bits.patch +@@ -0,0 +1,31 @@ ++From c2deb5ef01a0ef09088832744cbace9e239a6ee0 Mon Sep 17 00:00:00 2001 ++From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= ++Date: Sat, 28 Mar 2020 12:11:50 +0100 ++Subject: [PATCH] generic: platform/mikrotik build bits (5.4) ++MIME-Version: 1.0 ++Content-Type: text/plain; charset=UTF-8 ++Content-Transfer-Encoding: 8bit ++ ++This patch adds platform/mikrotik kernel build bits ++ ++Signed-off-by: Thibaut VARÈNE ++--- ++ drivers/platform/Kconfig | 2 ++ ++ drivers/platform/Makefile | 1 + ++ 2 files changed, 3 insertions(+) ++ ++--- a/drivers/platform/Kconfig +++++ b/drivers/platform/Kconfig ++@@ -13,3 +13,5 @@ source "drivers/platform/chrome/Kconfig" ++ source "drivers/platform/mellanox/Kconfig" ++ ++ source "drivers/platform/olpc/Kconfig" +++ +++source "drivers/platform/mikrotik/Kconfig" ++--- a/drivers/platform/Makefile +++++ b/drivers/platform/Makefile ++@@ -9,3 +9,4 @@ obj-$(CONFIG_MIPS) += mips/ ++ obj-$(CONFIG_OLPC_EC) += olpc/ ++ obj-$(CONFIG_GOLDFISH) += goldfish/ ++ obj-$(CONFIG_CHROME_PLATFORMS) += chrome/ +++obj-$(CONFIG_MIKROTIK) += mikrotik/ +diff --git a/target/linux/generic/pending-5.10/300-mips_expose_boot_raw.patch b/target/linux/generic/pending-5.10/300-mips_expose_boot_raw.patch +new file mode 100644 +index 0000000000..a454733e66 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/300-mips_expose_boot_raw.patch +@@ -0,0 +1,40 @@ ++From: Mark Miller ++Subject: mips: expose CONFIG_BOOT_RAW ++ ++This exposes the CONFIG_BOOT_RAW symbol in Kconfig. This is needed on ++certain Broadcom chipsets running CFE in order to load the kernel. ++ ++Signed-off-by: Mark Miller ++Acked-by: Rob Landley ++--- ++--- a/arch/mips/Kconfig +++++ b/arch/mips/Kconfig ++@@ -1077,9 +1077,6 @@ config FW_ARC ++ config ARCH_MAY_HAVE_PC_FDC ++ bool ++ ++-config BOOT_RAW ++- bool ++- ++ config CEVT_BCM1480 ++ bool ++ ++@@ -3169,6 +3166,18 @@ choice ++ bool "Extend builtin kernel arguments with bootloader arguments" ++ endchoice ++ +++config BOOT_RAW +++ bool "Enable the kernel to be executed from the load address" +++ default n +++ help +++ Allow the kernel to be executed from the load address for +++ bootloaders which cannot read the ELF format. This places +++ a jump to start_kernel at the load address. +++ +++ If unsure, say N. +++ +++ +++ ++ endmenu ++ ++ config LOCKDEP_SUPPORT +diff --git a/target/linux/generic/pending-5.10/302-mips_no_branch_likely.patch b/target/linux/generic/pending-5.10/302-mips_no_branch_likely.patch +new file mode 100644 +index 0000000000..271923fca8 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/302-mips_no_branch_likely.patch +@@ -0,0 +1,22 @@ ++From: Felix Fietkau ++Subject: mips: use -mno-branch-likely for kernel and userspace ++ ++saves ~11k kernel size after lzma and ~12k squashfs size in the ++ ++lede-commit: 41a039f46450ffae9483d6216422098669da2900 ++Signed-off-by: Felix Fietkau ++--- ++ arch/mips/Makefile | 2 +- ++ 1 file changed, 1 insertion(+), 1 deletion(-) ++ ++--- a/arch/mips/Makefile +++++ b/arch/mips/Makefile ++@@ -95,7 +95,7 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin ++ # machines may also. Since BFD is incredibly buggy with respect to ++ # crossformat linking we rely on the elf2ecoff tool for format conversion. ++ # ++-cflags-y += -G 0 -mno-abicalls -fno-pic -pipe +++cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely ++ cflags-y += -msoft-float ++ LDFLAGS_vmlinux += -G 0 -static -n -nostdlib ++ KBUILD_AFLAGS_MODULE += -mlong-calls +diff --git a/target/linux/generic/pending-5.10/305-mips_module_reloc.patch b/target/linux/generic/pending-5.10/305-mips_module_reloc.patch +new file mode 100644 +index 0000000000..839ba24293 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/305-mips_module_reloc.patch +@@ -0,0 +1,371 @@ ++From: Felix Fietkau ++Subject: mips: replace -mlong-calls with -mno-long-calls to make function calls faster in kernel modules to achieve this, try to ++ ++lede-commit: 3b3d64743ba2a874df9d70cd19e242205b0a788c ++Signed-off-by: Felix Fietkau ++--- ++ arch/mips/Makefile | 5 + ++ arch/mips/include/asm/module.h | 5 + ++ arch/mips/kernel/module.c | 279 ++++++++++++++++++++++++++++++++++++++++- ++ 3 files changed, 284 insertions(+), 5 deletions(-) ++ ++--- a/arch/mips/Makefile +++++ b/arch/mips/Makefile ++@@ -98,8 +98,18 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin ++ cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely ++ cflags-y += -msoft-float ++ LDFLAGS_vmlinux += -G 0 -static -n -nostdlib +++ifdef CONFIG_64BIT ++ KBUILD_AFLAGS_MODULE += -mlong-calls ++ KBUILD_CFLAGS_MODULE += -mlong-calls +++else +++ ifdef CONFIG_DYNAMIC_FTRACE +++ KBUILD_AFLAGS_MODULE += -mlong-calls +++ KBUILD_CFLAGS_MODULE += -mlong-calls +++ else +++ KBUILD_AFLAGS_MODULE += -mno-long-calls +++ KBUILD_CFLAGS_MODULE += -mno-long-calls +++ endif +++endif ++ ++ ifeq ($(CONFIG_RELOCATABLE),y) ++ LDFLAGS_vmlinux += --emit-relocs ++--- a/arch/mips/include/asm/module.h +++++ b/arch/mips/include/asm/module.h ++@@ -12,6 +12,11 @@ struct mod_arch_specific { ++ const struct exception_table_entry *dbe_start; ++ const struct exception_table_entry *dbe_end; ++ struct mips_hi16 *r_mips_hi16_list; +++ +++ void *phys_plt_tbl; +++ void *virt_plt_tbl; +++ unsigned int phys_plt_offset; +++ unsigned int virt_plt_offset; ++ }; ++ ++ typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */ ++--- a/arch/mips/kernel/module.c +++++ b/arch/mips/kernel/module.c ++@@ -31,14 +31,221 @@ struct mips_hi16 { ++ static LIST_HEAD(dbe_list); ++ static DEFINE_SPINLOCK(dbe_lock); ++ ++-#ifdef MODULE_START +++/* +++ * Get the potential max trampolines size required of the init and +++ * non-init sections. Only used if we cannot find enough contiguous +++ * physically mapped memory to put the module into. +++ */ +++static unsigned int +++get_plt_size(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, +++ const char *secstrings, unsigned int symindex, bool is_init) +++{ +++ unsigned long ret = 0; +++ unsigned int i, j; +++ Elf_Sym *syms; +++ +++ /* Everything marked ALLOC (this includes the exported symbols) */ +++ for (i = 1; i < hdr->e_shnum; ++i) { +++ unsigned int info = sechdrs[i].sh_info; +++ +++ if (sechdrs[i].sh_type != SHT_REL +++ && sechdrs[i].sh_type != SHT_RELA) +++ continue; +++ +++ /* Not a valid relocation section? */ +++ if (info >= hdr->e_shnum) +++ continue; +++ +++ /* Don't bother with non-allocated sections */ +++ if (!(sechdrs[info].sh_flags & SHF_ALLOC)) +++ continue; +++ +++ /* If it's called *.init*, and we're not init, we're +++ not interested */ +++ if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0) +++ != is_init) +++ continue; +++ +++ syms = (Elf_Sym *) sechdrs[symindex].sh_addr; +++ if (sechdrs[i].sh_type == SHT_REL) { +++ Elf_Mips_Rel *rel = (void *) sechdrs[i].sh_addr; +++ unsigned int size = sechdrs[i].sh_size / sizeof(*rel); +++ +++ for (j = 0; j < size; ++j) { +++ Elf_Sym *sym; +++ +++ if (ELF_MIPS_R_TYPE(rel[j]) != R_MIPS_26) +++ continue; +++ +++ sym = syms + ELF_MIPS_R_SYM(rel[j]); +++ if (!is_init && sym->st_shndx != SHN_UNDEF) +++ continue; +++ +++ ret += 4 * sizeof(int); +++ } +++ } else { +++ Elf_Mips_Rela *rela = (void *) sechdrs[i].sh_addr; +++ unsigned int size = sechdrs[i].sh_size / sizeof(*rela); +++ +++ for (j = 0; j < size; ++j) { +++ Elf_Sym *sym; +++ +++ if (ELF_MIPS_R_TYPE(rela[j]) != R_MIPS_26) +++ continue; +++ +++ sym = syms + ELF_MIPS_R_SYM(rela[j]); +++ if (!is_init && sym->st_shndx != SHN_UNDEF) +++ continue; +++ +++ ret += 4 * sizeof(int); +++ } +++ } +++ } +++ +++ return ret; +++} +++ +++#ifndef MODULE_START +++static void *alloc_phys(unsigned long size) +++{ +++ unsigned order; +++ struct page *page; +++ struct page *p; +++ +++ size = PAGE_ALIGN(size); +++ order = get_order(size); +++ +++ page = alloc_pages(GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN | +++ __GFP_THISNODE, order); +++ if (!page) +++ return NULL; +++ +++ split_page(page, order); +++ +++ /* mark all pages except for the last one */ +++ for (p = page; p + 1 < page + (size >> PAGE_SHIFT); ++p) +++ set_bit(PG_owner_priv_1, &p->flags); +++ +++ for (p = page + (size >> PAGE_SHIFT); p < page + (1 << order); ++p) +++ __free_page(p); +++ +++ return page_address(page); +++} +++#endif +++ +++static void free_phys(void *ptr) +++{ +++ struct page *page; +++ bool free; +++ +++ page = virt_to_page(ptr); +++ do { +++ free = test_and_clear_bit(PG_owner_priv_1, &page->flags); +++ __free_page(page); +++ page++; +++ } while (free); +++} +++ +++ ++ void *module_alloc(unsigned long size) ++ { +++#ifdef MODULE_START ++ return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END, ++ GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE, ++ __builtin_return_address(0)); +++#else +++ void *ptr; +++ +++ if (size == 0) +++ return NULL; +++ +++ ptr = alloc_phys(size); +++ +++ /* If we failed to allocate physically contiguous memory, +++ * fall back to regular vmalloc. The module loader code will +++ * create jump tables to handle long jumps */ +++ if (!ptr) +++ return vmalloc(size); +++ +++ return ptr; +++#endif ++ } +++ +++static inline bool is_phys_addr(void *ptr) +++{ +++#ifdef CONFIG_64BIT +++ return (KSEGX((unsigned long)ptr) == CKSEG0); +++#else +++ return (KSEGX(ptr) == KSEG0); ++ #endif +++} +++ +++/* Free memory returned from module_alloc */ +++void module_memfree(void *module_region) +++{ +++ if (is_phys_addr(module_region)) +++ free_phys(module_region); +++ else +++ vfree(module_region); +++} +++ +++static void *__module_alloc(int size, bool phys) +++{ +++ void *ptr; +++ +++ if (phys) +++ ptr = kmalloc(size, GFP_KERNEL); +++ else +++ ptr = vmalloc(size); +++ return ptr; +++} +++ +++static void __module_free(void *ptr) +++{ +++ if (is_phys_addr(ptr)) +++ kfree(ptr); +++ else +++ vfree(ptr); +++} +++ +++int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, +++ char *secstrings, struct module *mod) +++{ +++ unsigned int symindex = 0; +++ unsigned int core_size, init_size; +++ int i; +++ +++ mod->arch.phys_plt_offset = 0; +++ mod->arch.virt_plt_offset = 0; +++ mod->arch.phys_plt_tbl = NULL; +++ mod->arch.virt_plt_tbl = NULL; +++ +++ if (IS_ENABLED(CONFIG_64BIT)) +++ return 0; +++ +++ for (i = 1; i < hdr->e_shnum; i++) +++ if (sechdrs[i].sh_type == SHT_SYMTAB) +++ symindex = i; +++ +++ core_size = get_plt_size(hdr, sechdrs, secstrings, symindex, false); +++ init_size = get_plt_size(hdr, sechdrs, secstrings, symindex, true); +++ +++ if ((core_size + init_size) == 0) +++ return 0; +++ +++ mod->arch.phys_plt_tbl = __module_alloc(core_size + init_size, 1); +++ if (!mod->arch.phys_plt_tbl) +++ return -ENOMEM; +++ +++ mod->arch.virt_plt_tbl = __module_alloc(core_size + init_size, 0); +++ if (!mod->arch.virt_plt_tbl) { +++ __module_free(mod->arch.phys_plt_tbl); +++ mod->arch.phys_plt_tbl = NULL; +++ return -ENOMEM; +++ } +++ +++ return 0; +++} ++ ++ static int apply_r_mips_none(struct module *me, u32 *location, ++ u32 base, Elf_Addr v, bool rela) ++@@ -54,9 +261,40 @@ static int apply_r_mips_32(struct module ++ return 0; ++ } ++ +++static Elf_Addr add_plt_entry_to(unsigned *plt_offset, +++ void *start, Elf_Addr v) +++{ +++ unsigned *tramp = start + *plt_offset; +++ *plt_offset += 4 * sizeof(int); +++ +++ /* adjust carry for addiu */ +++ if (v & 0x00008000) +++ v += 0x10000; +++ +++ tramp[0] = 0x3c190000 | (v >> 16); /* lui t9, hi16 */ +++ tramp[1] = 0x27390000 | (v & 0xffff); /* addiu t9, t9, lo16 */ +++ tramp[2] = 0x03200008; /* jr t9 */ +++ tramp[3] = 0x00000000; /* nop */ +++ +++ return (Elf_Addr) tramp; +++} +++ +++static Elf_Addr add_plt_entry(struct module *me, void *location, Elf_Addr v) +++{ +++ if (is_phys_addr(location)) +++ return add_plt_entry_to(&me->arch.phys_plt_offset, +++ me->arch.phys_plt_tbl, v); +++ else +++ return add_plt_entry_to(&me->arch.virt_plt_offset, +++ me->arch.virt_plt_tbl, v); +++ +++} +++ ++ static int apply_r_mips_26(struct module *me, u32 *location, ++ u32 base, Elf_Addr v, bool rela) ++ { +++ u32 ofs = base & 0x03ffffff; +++ ++ if (v % 4) { ++ pr_err("module %s: dangerous R_MIPS_26 relocation\n", ++ me->name); ++@@ -64,13 +302,17 @@ static int apply_r_mips_26(struct module ++ } ++ ++ if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { ++- pr_err("module %s: relocation overflow\n", ++- me->name); ++- return -ENOEXEC; +++ v = add_plt_entry(me, location, v + (ofs << 2)); +++ if (!v) { +++ pr_err("module %s: relocation overflow\n", +++ me->name); +++ return -ENOEXEC; +++ } +++ ofs = 0; ++ } ++ ++ *location = (*location & ~0x03ffffff) | ++- ((base + (v >> 2)) & 0x03ffffff); +++ ((ofs + (v >> 2)) & 0x03ffffff); ++ ++ return 0; ++ } ++@@ -446,9 +688,36 @@ int module_finalize(const Elf_Ehdr *hdr, ++ list_add(&me->arch.dbe_list, &dbe_list); ++ spin_unlock_irq(&dbe_lock); ++ } +++ +++ /* Get rid of the fixup trampoline if we're running the module +++ * from physically mapped address space */ +++ if (me->arch.phys_plt_offset == 0) { +++ __module_free(me->arch.phys_plt_tbl); +++ me->arch.phys_plt_tbl = NULL; +++ } +++ if (me->arch.virt_plt_offset == 0) { +++ __module_free(me->arch.virt_plt_tbl); +++ me->arch.virt_plt_tbl = NULL; +++ } +++ ++ return 0; ++ } ++ +++void module_arch_freeing_init(struct module *mod) +++{ +++ if (mod->state == MODULE_STATE_LIVE) +++ return; +++ +++ if (mod->arch.phys_plt_tbl) { +++ __module_free(mod->arch.phys_plt_tbl); +++ mod->arch.phys_plt_tbl = NULL; +++ } +++ if (mod->arch.virt_plt_tbl) { +++ __module_free(mod->arch.virt_plt_tbl); +++ mod->arch.virt_plt_tbl = NULL; +++ } +++} +++ ++ void module_arch_cleanup(struct module *mod) ++ { ++ spin_lock_irq(&dbe_lock); +diff --git a/target/linux/generic/pending-5.10/307-mips_highmem_offset.patch b/target/linux/generic/pending-5.10/307-mips_highmem_offset.patch +new file mode 100644 +index 0000000000..e1ada22f34 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/307-mips_highmem_offset.patch +@@ -0,0 +1,19 @@ ++From: Felix Fietkau ++Subject: kernel: adjust mips highmem offset to avoid the need for -mlong-calls on systems with >256M RAM ++ ++Signed-off-by: Felix Fietkau ++--- ++ arch/mips/include/asm/mach-generic/spaces.h | 2 +- ++ 1 file changed, 1 insertion(+), 1 deletion(-) ++ ++--- a/arch/mips/include/asm/mach-generic/spaces.h +++++ b/arch/mips/include/asm/mach-generic/spaces.h ++@@ -54,7 +54,7 @@ ++ * Memory above this physical address will be considered highmem. ++ */ ++ #ifndef HIGHMEM_START ++-#define HIGHMEM_START _AC(0x20000000, UL) +++#define HIGHMEM_START _AC(0x10000000, UL) ++ #endif ++ ++ #endif /* CONFIG_32BIT */ +diff --git a/target/linux/generic/pending-5.10/308-mips32r2_tune.patch b/target/linux/generic/pending-5.10/308-mips32r2_tune.patch +new file mode 100644 +index 0000000000..54c0e01023 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/308-mips32r2_tune.patch +@@ -0,0 +1,22 @@ ++From: Felix Fietkau ++Subject: kernel: add -mtune=34kc to MIPS CFLAGS when building for mips32r2 ++ ++This provides a good tradeoff across at least 24Kc-74Kc, while also ++producing smaller code. ++ ++Signed-off-by: Felix Fietkau ++--- ++ arch/mips/Makefile | 2 +- ++ 1 file changed, 1 insertion(+), 1 deletion(-) ++ ++--- a/arch/mips/Makefile +++++ b/arch/mips/Makefile ++@@ -155,7 +155,7 @@ cflags-$(CONFIG_CPU_VR41XX) += -march=r4 ++ cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap ++ cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap ++ cflags-$(CONFIG_CPU_MIPS32_R1) += -march=mips32 -Wa,--trap ++-cflags-$(CONFIG_CPU_MIPS32_R2) += -march=mips32r2 -Wa,--trap +++cflags-$(CONFIG_CPU_MIPS32_R2) += -march=mips32r2 -mtune=34kc -Wa,--trap ++ cflags-$(CONFIG_CPU_MIPS32_R5) += -march=mips32r5 -Wa,--trap -modd-spreg ++ cflags-$(CONFIG_CPU_MIPS32_R6) += -march=mips32r6 -Wa,--trap -modd-spreg ++ cflags-$(CONFIG_CPU_MIPS64_R1) += -march=mips64 -Wa,--trap +diff --git a/target/linux/generic/pending-5.10/309-MIPS-Add-CPU-option-reporting-to-proc-cpuinfo.patch b/target/linux/generic/pending-5.10/309-MIPS-Add-CPU-option-reporting-to-proc-cpuinfo.patch +new file mode 100644 +index 0000000000..794f027f18 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/309-MIPS-Add-CPU-option-reporting-to-proc-cpuinfo.patch +@@ -0,0 +1,140 @@ ++From 87ec87c2ad615c1a177cd08ef5fa29fc739f6e50 Mon Sep 17 00:00:00 2001 ++From: Hauke Mehrtens ++Date: Sun, 23 Dec 2018 18:06:53 +0100 ++Subject: [PATCH] MIPS: Add CPU option reporting to /proc/cpuinfo ++ ++Many MIPS CPUs have optional CPU features which are not activates for ++all CPU cores. Print the CPU options which are implemented in the core ++in /proc/cpuinfo. This makes it possible to see what features are ++supported and which are not supported. This should cover all standard ++MIPS extensions, before it only printed information about the main MIPS ++ASEs. ++ ++Signed-off-by: Hauke Mehrtens ++--- ++ arch/mips/kernel/proc.c | 116 ++++++++++++++++++++++++++++++++++++++++ ++ 1 file changed, 116 insertions(+) ++ ++--- a/arch/mips/kernel/proc.c +++++ b/arch/mips/kernel/proc.c ++@@ -138,6 +138,120 @@ static int show_cpuinfo(struct seq_file ++ seq_printf(m, "micromips kernel\t: %s\n", ++ (read_c0_config3() & MIPS_CONF3_ISA_OE) ? "yes" : "no"); ++ } +++ +++ seq_printf(m, "Options implemented\t:"); +++ if (cpu_has_tlb) +++ seq_printf(m, "%s", " tlb"); +++ if (cpu_has_ftlb) +++ seq_printf(m, "%s", " ftlb"); +++ if (cpu_has_tlbinv) +++ seq_printf(m, "%s", " tlbinv"); +++ if (cpu_has_segments) +++ seq_printf(m, "%s", " segments"); +++ if (cpu_has_rixiex) +++ seq_printf(m, "%s", " rixiex"); +++ if (cpu_has_ldpte) +++ seq_printf(m, "%s", " ldpte"); +++ if (cpu_has_maar) +++ seq_printf(m, "%s", " maar"); +++ if (cpu_has_rw_llb) +++ seq_printf(m, "%s", " rw_llb"); +++ if (cpu_has_4kex) +++ seq_printf(m, "%s", " 4kex"); +++ if (cpu_has_3k_cache) +++ seq_printf(m, "%s", " 3k_cache"); +++ if (cpu_has_4k_cache) +++ seq_printf(m, "%s", " 4k_cache"); +++ if (cpu_has_6k_cache) +++ seq_printf(m, "%s", " 6k_cache"); +++ if (cpu_has_8k_cache) +++ seq_printf(m, "%s", " 8k_cache"); +++ if (cpu_has_tx39_cache) +++ seq_printf(m, "%s", " tx39_cache"); +++ if (cpu_has_octeon_cache) +++ seq_printf(m, "%s", " octeon_cache"); +++ if (cpu_has_fpu) +++ seq_printf(m, "%s", " fpu"); +++ if (cpu_has_32fpr) +++ seq_printf(m, "%s", " 32fpr"); +++ if (cpu_has_cache_cdex_p) +++ seq_printf(m, "%s", " cache_cdex_p"); +++ if (cpu_has_cache_cdex_s) +++ seq_printf(m, "%s", " cache_cdex_s"); +++ if (cpu_has_prefetch) +++ seq_printf(m, "%s", " prefetch"); +++ if (cpu_has_mcheck) +++ seq_printf(m, "%s", " mcheck"); +++ if (cpu_has_ejtag) +++ seq_printf(m, "%s", " ejtag"); +++ if (cpu_has_llsc) +++ seq_printf(m, "%s", " llsc"); +++ if (cpu_has_guestctl0ext) +++ seq_printf(m, "%s", " guestctl0ext"); +++ if (cpu_has_guestctl1) +++ seq_printf(m, "%s", " guestctl1"); +++ if (cpu_has_guestctl2) +++ seq_printf(m, "%s", " guestctl2"); +++ if (cpu_has_guestid) +++ seq_printf(m, "%s", " guestid"); +++ if (cpu_has_drg) +++ seq_printf(m, "%s", " drg"); +++ if (cpu_has_rixi) +++ seq_printf(m, "%s", " rixi"); +++ if (cpu_has_lpa) +++ seq_printf(m, "%s", " lpa"); +++ if (cpu_has_mvh) +++ seq_printf(m, "%s", " mvh"); +++ if (cpu_has_vtag_icache) +++ seq_printf(m, "%s", " vtag_icache"); +++ if (cpu_has_dc_aliases) +++ seq_printf(m, "%s", " dc_aliases"); +++ if (cpu_has_ic_fills_f_dc) +++ seq_printf(m, "%s", " ic_fills_f_dc"); +++ if (cpu_has_pindexed_dcache) +++ seq_printf(m, "%s", " pindexed_dcache"); +++ if (cpu_has_userlocal) +++ seq_printf(m, "%s", " userlocal"); +++ if (cpu_has_nofpuex) +++ seq_printf(m, "%s", " nofpuex"); +++ if (cpu_has_vint) +++ seq_printf(m, "%s", " vint"); +++ if (cpu_has_veic) +++ seq_printf(m, "%s", " veic"); +++ if (cpu_has_inclusive_pcaches) +++ seq_printf(m, "%s", " inclusive_pcaches"); +++ if (cpu_has_perf_cntr_intr_bit) +++ seq_printf(m, "%s", " perf_cntr_intr_bit"); +++ if (cpu_has_ufr) +++ seq_printf(m, "%s", " ufr"); +++ if (cpu_has_fre) +++ seq_printf(m, "%s", " fre"); +++ if (cpu_has_cdmm) +++ seq_printf(m, "%s", " cdmm"); +++ if (cpu_has_small_pages) +++ seq_printf(m, "%s", " small_pages"); +++ if (cpu_has_nan_legacy) +++ seq_printf(m, "%s", " nan_legacy"); +++ if (cpu_has_nan_2008) +++ seq_printf(m, "%s", " nan_2008"); +++ if (cpu_has_ebase_wg) +++ seq_printf(m, "%s", " ebase_wg"); +++ if (cpu_has_badinstr) +++ seq_printf(m, "%s", " badinstr"); +++ if (cpu_has_badinstrp) +++ seq_printf(m, "%s", " badinstrp"); +++ if (cpu_has_contextconfig) +++ seq_printf(m, "%s", " contextconfig"); +++ if (cpu_has_perf) +++ seq_printf(m, "%s", " perf"); +++ if (cpu_has_shared_ftlb_ram) +++ seq_printf(m, "%s", " shared_ftlb_ram"); +++ if (cpu_has_shared_ftlb_entries) +++ seq_printf(m, "%s", " shared_ftlb_entries"); +++ if (cpu_has_mipsmt_pertccounters) +++ seq_printf(m, "%s", " mipsmt_pertccounters"); +++ seq_printf(m, "\n"); +++ ++ seq_printf(m, "shadow register sets\t: %d\n", ++ cpu_data[n].srsets); ++ seq_printf(m, "kscratch registers\t: %d\n", +diff --git a/target/linux/generic/pending-5.10/310-arm_module_unresolved_weak_sym.patch b/target/linux/generic/pending-5.10/310-arm_module_unresolved_weak_sym.patch +new file mode 100644 +index 0000000000..191dc6ac3c +--- /dev/null ++++ b/target/linux/generic/pending-5.10/310-arm_module_unresolved_weak_sym.patch +@@ -0,0 +1,22 @@ ++From: Felix Fietkau ++Subject: fix errors in unresolved weak symbols on arm ++ ++lede-commit: 570699d4838a907c3ef9f2819bf19eb72997b32f ++Signed-off-by: Felix Fietkau ++--- ++ arch/arm/kernel/module.c | 4 ++++ ++ 1 file changed, 4 insertions(+) ++ ++--- a/arch/arm/kernel/module.c +++++ b/arch/arm/kernel/module.c ++@@ -105,6 +105,10 @@ apply_relocate(Elf32_Shdr *sechdrs, cons ++ return -ENOEXEC; ++ } ++ +++ if ((IS_ERR_VALUE(sym->st_value) || !sym->st_value) && +++ ELF_ST_BIND(sym->st_info) == STB_WEAK) +++ continue; +++ ++ loc = dstsec->sh_addr + rel->r_offset; ++ ++ switch (ELF32_R_TYPE(rel->r_info)) { +diff --git a/target/linux/generic/pending-5.10/311-MIPS-zboot-put-appended-dtb-into-a-section.patch b/target/linux/generic/pending-5.10/311-MIPS-zboot-put-appended-dtb-into-a-section.patch +new file mode 100644 +index 0000000000..3f8808f702 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/311-MIPS-zboot-put-appended-dtb-into-a-section.patch +@@ -0,0 +1,36 @@ ++From 7d1531c81c0fb4c93bea8dc316043ad0e4d0c270 Mon Sep 17 00:00:00 2001 ++From: Chuanhong Guo ++Date: Sun, 25 Oct 2020 23:19:40 +0800 ++Subject: [PATCH] MIPS: zboot: put appended dtb into a section ++ ++This will make a separated section for dtb appear in ELF, and we can ++then use objcopy to patch a dtb into vmlinuz when RAW_APPENDED_DTB ++is set in kernel config. ++ ++command to patch a dtb: ++objcopy --set-section-flags=.appended_dtb=alloc,contents \ ++ --update-section=.appended_dtb=.dtb vmlinuz vmlinuz-dtb ++ ++Signed-off-by: Chuanhong Guo ++--- ++ arch/mips/boot/compressed/ld.script | 9 ++++++--- ++ 1 file changed, 6 insertions(+), 3 deletions(-) ++ ++--- a/arch/mips/boot/compressed/ld.script +++++ b/arch/mips/boot/compressed/ld.script ++@@ -31,9 +31,12 @@ SECTIONS ++ CONSTRUCTORS ++ . = ALIGN(16); ++ } ++- __appended_dtb = .; ++- /* leave space for appended DTB */ ++- . += 0x100000; +++ +++ .appended_dtb : { +++ __appended_dtb = .; +++ /* leave space for appended DTB */ +++ . += 0x100000; +++ } ++ ++ _edata = .; ++ /* End of data section */ +diff --git a/target/linux/generic/pending-5.10/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch b/target/linux/generic/pending-5.10/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch +new file mode 100644 +index 0000000000..5a0e44b76b +--- /dev/null ++++ b/target/linux/generic/pending-5.10/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch +@@ -0,0 +1,281 @@ ++From: Yousong Zhou ++Subject: MIPS: kexec: Accept command line parameters from userspace. ++ ++Signed-off-by: Yousong Zhou ++--- ++ arch/mips/kernel/machine_kexec.c | 153 +++++++++++++++++++++++++++++++----- ++ arch/mips/kernel/machine_kexec.h | 20 +++++ ++ arch/mips/kernel/relocate_kernel.S | 21 +++-- ++ 3 files changed, 167 insertions(+), 27 deletions(-) ++ create mode 100644 arch/mips/kernel/machine_kexec.h ++ ++--- a/arch/mips/kernel/machine_kexec.c +++++ b/arch/mips/kernel/machine_kexec.c ++@@ -9,14 +9,11 @@ ++ #include ++ #include ++ +++#include ++ #include ++ #include ++- ++-extern const unsigned char relocate_new_kernel[]; ++-extern const size_t relocate_new_kernel_size; ++- ++-extern unsigned long kexec_start_address; ++-extern unsigned long kexec_indirection_page; +++#include +++#include "machine_kexec.h" ++ ++ static unsigned long reboot_code_buffer; ++ ++@@ -30,6 +27,101 @@ void (*_crash_smp_send_stop)(void) = NUL ++ void (*_machine_kexec_shutdown)(void) = NULL; ++ void (*_machine_crash_shutdown)(struct pt_regs *regs) = NULL; ++ +++static void machine_kexec_print_args(void) +++{ +++ unsigned long argc = (int)kexec_args[0]; +++ int i; +++ +++ pr_info("kexec_args[0] (argc): %lu\n", argc); +++ pr_info("kexec_args[1] (argv): %p\n", (void *)kexec_args[1]); +++ pr_info("kexec_args[2] (env ): %p\n", (void *)kexec_args[2]); +++ pr_info("kexec_args[3] (desc): %p\n", (void *)kexec_args[3]); +++ +++ for (i = 0; i < argc; i++) { +++ pr_info("kexec_argv[%d] = %p, %s\n", +++ i, kexec_argv[i], kexec_argv[i]); +++ } +++} +++ +++static void machine_kexec_init_argv(struct kimage *image) +++{ +++ void __user *buf = NULL; +++ size_t bufsz; +++ size_t size; +++ int i; +++ +++ bufsz = 0; +++ for (i = 0; i < image->nr_segments; i++) { +++ struct kexec_segment *seg; +++ +++ seg = &image->segment[i]; +++ if (seg->bufsz < 6) +++ continue; +++ +++ if (strncmp((char *) seg->buf, "kexec ", 6)) +++ continue; +++ +++ buf = seg->buf; +++ bufsz = seg->bufsz; +++ break; +++ } +++ +++ if (!buf) +++ return; +++ +++ size = KEXEC_COMMAND_LINE_SIZE; +++ size = min(size, bufsz); +++ if (size < bufsz) +++ pr_warn("kexec command line truncated to %zd bytes\n", size); +++ +++ /* Copy to kernel space */ +++ if (copy_from_user(kexec_argv_buf, buf, size)) +++ pr_warn("kexec command line copy to kernel space failed\n"); +++ +++ kexec_argv_buf[size - 1] = 0; +++} +++ +++static void machine_kexec_parse_argv(struct kimage *image) +++{ +++ char *reboot_code_buffer; +++ int reloc_delta; +++ char *ptr; +++ int argc; +++ int i; +++ +++ ptr = kexec_argv_buf; +++ argc = 0; +++ +++ /* +++ * convert command line string to array of parameters +++ * (as bootloader does). +++ */ +++ while (ptr && *ptr && (KEXEC_MAX_ARGC > argc)) { +++ if (*ptr == ' ') { +++ *ptr++ = '\0'; +++ continue; +++ } +++ +++ kexec_argv[argc++] = ptr; +++ ptr = strchr(ptr, ' '); +++ } +++ +++ if (!argc) +++ return; +++ +++ kexec_args[0] = argc; +++ kexec_args[1] = (unsigned long)kexec_argv; +++ kexec_args[2] = 0; +++ kexec_args[3] = 0; +++ +++ reboot_code_buffer = page_address(image->control_code_page); +++ reloc_delta = reboot_code_buffer - (char *)kexec_relocate_new_kernel; +++ +++ kexec_args[1] += reloc_delta; +++ for (i = 0; i < argc; i++) +++ kexec_argv[i] += reloc_delta; +++} +++ ++ static void kexec_image_info(const struct kimage *kimage) ++ { ++ unsigned long i; ++@@ -99,6 +191,18 @@ machine_kexec_prepare(struct kimage *kim ++ #endif ++ ++ kexec_image_info(kimage); +++ /* +++ * Whenever arguments passed from kexec-tools, Init the arguments as +++ * the original ones to try avoiding booting failure. +++ */ +++ +++ kexec_args[0] = fw_arg0; +++ kexec_args[1] = fw_arg1; +++ kexec_args[2] = fw_arg2; +++ kexec_args[3] = fw_arg3; +++ +++ machine_kexec_init_argv(kimage); +++ machine_kexec_parse_argv(kimage); ++ ++ if (_machine_kexec_prepare) ++ return _machine_kexec_prepare(kimage); ++@@ -161,7 +265,7 @@ machine_crash_shutdown(struct pt_regs *r ++ void kexec_nonboot_cpu_jump(void) ++ { ++ local_flush_icache_range((unsigned long)relocated_kexec_smp_wait, ++- reboot_code_buffer + relocate_new_kernel_size); +++ reboot_code_buffer + KEXEC_RELOCATE_NEW_KERNEL_SIZE); ++ ++ relocated_kexec_smp_wait(NULL); ++ } ++@@ -199,7 +303,7 @@ void kexec_reboot(void) ++ * machine_kexec() CPU. ++ */ ++ local_flush_icache_range(reboot_code_buffer, ++- reboot_code_buffer + relocate_new_kernel_size); +++ reboot_code_buffer + KEXEC_RELOCATE_NEW_KERNEL_SIZE); ++ ++ do_kexec = (void *)reboot_code_buffer; ++ do_kexec(); ++@@ -212,10 +316,12 @@ machine_kexec(struct kimage *image) ++ unsigned long *ptr; ++ ++ reboot_code_buffer = ++- (unsigned long)page_address(image->control_code_page); +++ (unsigned long)page_address(image->control_code_page); +++ pr_info("reboot_code_buffer = %p\n", (void *)reboot_code_buffer); ++ ++ kexec_start_address = ++ (unsigned long) phys_to_virt(image->start); +++ pr_info("kexec_start_address = %p\n", (void *)kexec_start_address); ++ ++ if (image->type == KEXEC_TYPE_DEFAULT) { ++ kexec_indirection_page = ++@@ -223,9 +329,19 @@ machine_kexec(struct kimage *image) ++ } else { ++ kexec_indirection_page = (unsigned long)&image->head; ++ } +++ pr_info("kexec_indirection_page = %p\n", (void *)kexec_indirection_page); ++ ++- memcpy((void*)reboot_code_buffer, relocate_new_kernel, ++- relocate_new_kernel_size); +++ pr_info("Where is memcpy: %p\n", memcpy); +++ pr_info("kexec_relocate_new_kernel = %p, kexec_relocate_new_kernel_end = %p\n", +++ (void *)kexec_relocate_new_kernel, &kexec_relocate_new_kernel_end); +++ pr_info("Copy %lu bytes from %p to %p\n", KEXEC_RELOCATE_NEW_KERNEL_SIZE, +++ (void *)kexec_relocate_new_kernel, (void *)reboot_code_buffer); +++ memcpy((void*)reboot_code_buffer, kexec_relocate_new_kernel, +++ KEXEC_RELOCATE_NEW_KERNEL_SIZE); +++ +++ pr_info("Before _print_args().\n"); +++ machine_kexec_print_args(); +++ pr_info("Before eval loop.\n"); ++ ++ /* ++ * The generic kexec code builds a page list with physical ++@@ -256,7 +372,7 @@ machine_kexec(struct kimage *image) ++ #ifdef CONFIG_SMP ++ /* All secondary cpus now may jump to kexec_wait cycle */ ++ relocated_kexec_smp_wait = reboot_code_buffer + ++- (void *)(kexec_smp_wait - relocate_new_kernel); +++ (void *)(kexec_smp_wait - kexec_relocate_new_kernel); ++ smp_wmb(); ++ atomic_set(&kexec_ready_to_reboot, 1); ++ #endif ++--- /dev/null +++++ b/arch/mips/kernel/machine_kexec.h ++@@ -0,0 +1,20 @@ +++#ifndef _MACHINE_KEXEC_H +++#define _MACHINE_KEXEC_H +++ +++#ifndef __ASSEMBLY__ +++extern const unsigned char kexec_relocate_new_kernel[]; +++extern unsigned long kexec_relocate_new_kernel_end; +++extern unsigned long kexec_start_address; +++extern unsigned long kexec_indirection_page; +++ +++extern char kexec_argv_buf[]; +++extern char *kexec_argv[]; +++ +++#define KEXEC_RELOCATE_NEW_KERNEL_SIZE ((unsigned long)&kexec_relocate_new_kernel_end - (unsigned long)kexec_relocate_new_kernel) +++#endif /* !__ASSEMBLY__ */ +++ +++#define KEXEC_COMMAND_LINE_SIZE 256 +++#define KEXEC_ARGV_SIZE (KEXEC_COMMAND_LINE_SIZE / 16) +++#define KEXEC_MAX_ARGC (KEXEC_ARGV_SIZE / sizeof(long)) +++ +++#endif ++--- a/arch/mips/kernel/relocate_kernel.S +++++ b/arch/mips/kernel/relocate_kernel.S ++@@ -10,8 +10,9 @@ ++ #include ++ #include ++ #include +++#include "machine_kexec.h" ++ ++-LEAF(relocate_new_kernel) +++LEAF(kexec_relocate_new_kernel) ++ PTR_L a0, arg0 ++ PTR_L a1, arg1 ++ PTR_L a2, arg2 ++@@ -96,7 +97,7 @@ done: ++ #endif ++ /* jump to kexec_start_address */ ++ j s1 ++- END(relocate_new_kernel) +++ END(kexec_relocate_new_kernel) ++ ++ #ifdef CONFIG_SMP ++ /* ++@@ -182,9 +183,15 @@ kexec_indirection_page: ++ PTR 0 ++ .size kexec_indirection_page, PTRSIZE ++ ++-relocate_new_kernel_end: +++kexec_argv_buf: +++ EXPORT(kexec_argv_buf) +++ .skip KEXEC_COMMAND_LINE_SIZE +++ .size kexec_argv_buf, KEXEC_COMMAND_LINE_SIZE ++ ++-relocate_new_kernel_size: ++- EXPORT(relocate_new_kernel_size) ++- PTR relocate_new_kernel_end - relocate_new_kernel ++- .size relocate_new_kernel_size, PTRSIZE +++kexec_argv: +++ EXPORT(kexec_argv) +++ .skip KEXEC_ARGV_SIZE +++ .size kexec_argv, KEXEC_ARGV_SIZE +++ +++kexec_relocate_new_kernel_end: +++ EXPORT(kexec_relocate_new_kernel_end) +diff --git a/target/linux/generic/pending-5.10/332-arc-add-OWRTDTB-section.patch b/target/linux/generic/pending-5.10/332-arc-add-OWRTDTB-section.patch +new file mode 100644 +index 0000000000..30158cf399 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/332-arc-add-OWRTDTB-section.patch +@@ -0,0 +1,84 @@ ++From bb0c3b0175240bf152fd7c644821a0cf9f77c37c Mon Sep 17 00:00:00 2001 ++From: Evgeniy Didin ++Date: Fri, 15 Mar 2019 18:53:38 +0300 ++Subject: [PATCH] arc add OWRTDTB section ++ ++This change allows OpenWRT to patch resulting kernel binary with ++external .dtb. ++ ++That allows us to re-use exactky the same vmlinux on different boards ++given its ARC core configurations match (at least cache line sizes etc). ++ ++""patch-dtb" searches for ASCII "OWRTDTB:" strign and copies external ++.dtb right after it, keeping the string in place. ++ ++Signed-off-by: Eugeniy Paltsev ++Signed-off-by: Alexey Brodkin ++Signed-off-by: Evgeniy Didin ++--- ++ arch/arc/kernel/head.S | 10 ++++++++++ ++ arch/arc/kernel/setup.c | 4 +++- ++ arch/arc/kernel/vmlinux.lds.S | 13 +++++++++++++ ++ 3 files changed, 26 insertions(+), 1 deletion(-) ++ ++--- a/arch/arc/kernel/head.S +++++ b/arch/arc/kernel/head.S ++@@ -88,6 +88,16 @@ ++ DSP_EARLY_INIT ++ .endm ++ +++ ; Here "patch-dtb" will embed external .dtb +++ ; Note "patch-dtb" searches for ASCII "OWRTDTB:" string +++ ; and pastes .dtb right after it, hense the string precedes +++ ; __image_dtb symbol. +++ .section .owrt, "aw",@progbits +++ .ascii "OWRTDTB:" +++ENTRY(__image_dtb) +++ .fill 0x4000 +++END(__image_dtb) +++ ++ .section .init.text, "ax",@progbits ++ ++ ;---------------------------------------------------------------- ++--- a/arch/arc/kernel/setup.c +++++ b/arch/arc/kernel/setup.c ++@@ -495,6 +495,8 @@ static inline bool uboot_arg_invalid(uns ++ /* We always pass 0 as magic from U-boot */ ++ #define UBOOT_MAGIC_VALUE 0 ++ +++extern struct boot_param_header __image_dtb; +++ ++ void __init handle_uboot_args(void) ++ { ++ bool use_embedded_dtb = true; ++@@ -533,7 +535,7 @@ void __init handle_uboot_args(void) ++ ignore_uboot_args: ++ ++ if (use_embedded_dtb) { ++- machine_desc = setup_machine_fdt(__dtb_start); +++ machine_desc = setup_machine_fdt(&__image_dtb); ++ if (!machine_desc) ++ panic("Embedded DT invalid\n"); ++ } ++--- a/arch/arc/kernel/vmlinux.lds.S +++++ b/arch/arc/kernel/vmlinux.lds.S ++@@ -27,6 +27,19 @@ SECTIONS ++ ++ . = CONFIG_LINUX_LINK_BASE; ++ +++ /* +++ * In OpenWRT we want to patch built binary embedding .dtb of choice. +++ * This is implemented with "patch-dtb" utility which searches for +++ * "OWRTDTB:" string in first 16k of image and if it is found +++ * copies .dtb right after mentioned string. +++ * +++ * Note: "OWRTDTB:" won't be overwritten with .dtb, .dtb will follow it. +++ */ +++ .owrt : { +++ *(.owrt) +++ . = ALIGN(PAGE_SIZE); +++ } +++ ++ _int_vec_base_lds = .; ++ .vector : { ++ *(.vector) +diff --git a/target/linux/generic/pending-5.10/333-arc-enable-unaligned-access-in-kernel-mode.patch b/target/linux/generic/pending-5.10/333-arc-enable-unaligned-access-in-kernel-mode.patch +new file mode 100644 +index 0000000000..1848a84cc4 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/333-arc-enable-unaligned-access-in-kernel-mode.patch +@@ -0,0 +1,24 @@ ++From: Alexey Brodkin ++Subject: arc: enable unaligned access in kernel mode ++ ++This enables misaligned access handling even in kernel mode. ++Some wireless drivers (ath9k-htc and mt7601u) use misaligned accesses ++here and there and to cope with that without fixing stuff in the drivers ++we're just gracefully handling it on ARC. ++ ++Signed-off-by: Alexey Brodkin ++--- ++ arch/arc/kernel/unaligned.c | 2 +- ++ 1 file changed, 1 insertion(+), 1 deletion(-) ++ ++--- a/arch/arc/kernel/unaligned.c +++++ b/arch/arc/kernel/unaligned.c ++@@ -202,7 +202,7 @@ int misaligned_fixup(unsigned long addre ++ char buf[TASK_COMM_LEN]; ++ ++ /* handle user mode only and only if enabled by sysadmin */ ++- if (!user_mode(regs) || !unaligned_enabled) +++ if (!unaligned_enabled) ++ return 1; ++ ++ if (no_unaligned_warning) { +diff --git a/target/linux/generic/pending-5.10/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch b/target/linux/generic/pending-5.10/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch +new file mode 100644 +index 0000000000..6792a66f8a +--- /dev/null ++++ b/target/linux/generic/pending-5.10/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch +@@ -0,0 +1,25 @@ ++From 66770a004afe10df11d3902e16eaa0c2c39436bb Mon Sep 17 00:00:00 2001 ++From: Pawel Dembicki ++Date: Fri, 24 May 2019 17:56:19 +0200 ++Subject: [PATCH] powerpc: Enable kernel XZ compression option on PPC_85xx ++ ++Enable kernel XZ compression option on PPC_85xx. Tested with ++simpleImage on TP-Link TL-WDR4900 (Freescale P1014 processor). ++ ++Suggested-by: Christian Lamparter ++Signed-off-by: Pawel Dembicki ++--- ++ arch/powerpc/Kconfig | 2 +- ++ 1 file changed, 1 insertion(+), 1 deletion(-) ++ ++--- a/arch/powerpc/Kconfig +++++ b/arch/powerpc/Kconfig ++@@ -214,7 +214,7 @@ config PPC ++ select HAVE_KERNEL_GZIP ++ select HAVE_KERNEL_LZMA if DEFAULT_UIMAGE ++ select HAVE_KERNEL_LZO if DEFAULT_UIMAGE ++- select HAVE_KERNEL_XZ if PPC_BOOK3S || 44x +++ select HAVE_KERNEL_XZ if PPC_BOOK3S || 44x || PPC_85xx ++ select HAVE_KPROBES ++ select HAVE_KPROBES_ON_FTRACE ++ select HAVE_KRETPROBES +diff --git a/target/linux/generic/pending-5.10/400-mtd-mtdsplit-support.patch b/target/linux/generic/pending-5.10/400-mtd-mtdsplit-support.patch +new file mode 100644 +index 0000000000..6f816a6ad3 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/400-mtd-mtdsplit-support.patch +@@ -0,0 +1,313 @@ ++--- a/drivers/mtd/Kconfig +++++ b/drivers/mtd/Kconfig ++@@ -12,6 +12,25 @@ menuconfig MTD ++ ++ if MTD ++ +++menu "OpenWrt specific MTD options" +++ +++config MTD_ROOTFS_ROOT_DEV +++ bool "Automatically set 'rootfs' partition to be root filesystem" +++ default y +++ +++config MTD_SPLIT_FIRMWARE +++ bool "Automatically split firmware partition for kernel+rootfs" +++ default y +++ +++config MTD_SPLIT_FIRMWARE_NAME +++ string "Firmware partition name" +++ depends on MTD_SPLIT_FIRMWARE +++ default "firmware" +++ +++source "drivers/mtd/mtdsplit/Kconfig" +++ +++endmenu +++ ++ config MTD_TESTS ++ tristate "MTD tests support (DANGEROUS)" ++ depends on m ++--- a/drivers/mtd/mtdpart.c +++++ b/drivers/mtd/mtdpart.c ++@@ -15,10 +15,12 @@ ++ #include ++ #include ++ #include +++#include ++ #include ++ #include ++ ++ #include "mtdcore.h" +++#include "mtdsplit/mtdsplit.h" ++ ++ /* ++ * MTD methods which simply translate the effective address and pass through ++@@ -236,6 +238,146 @@ static int mtd_add_partition_attrs(struc ++ return ret; ++ } ++ +++static DEFINE_SPINLOCK(part_parser_lock); +++static LIST_HEAD(part_parsers); +++ +++static struct mtd_part_parser *mtd_part_parser_get(const char *name) +++{ +++ struct mtd_part_parser *p, *ret = NULL; +++ +++ spin_lock(&part_parser_lock); +++ +++ list_for_each_entry(p, &part_parsers, list) +++ if (!strcmp(p->name, name) && try_module_get(p->owner)) { +++ ret = p; +++ break; +++ } +++ +++ spin_unlock(&part_parser_lock); +++ +++ return ret; +++} +++ +++static inline void mtd_part_parser_put(const struct mtd_part_parser *p) +++{ +++ module_put(p->owner); +++} +++ +++static struct mtd_part_parser * +++get_partition_parser_by_type(enum mtd_parser_type type, +++ struct mtd_part_parser *start) +++{ +++ struct mtd_part_parser *p, *ret = NULL; +++ +++ spin_lock(&part_parser_lock); +++ +++ p = list_prepare_entry(start, &part_parsers, list); +++ if (start) +++ mtd_part_parser_put(start); +++ +++ list_for_each_entry_continue(p, &part_parsers, list) { +++ if (p->type == type && try_module_get(p->owner)) { +++ ret = p; +++ break; +++ } +++ } +++ +++ spin_unlock(&part_parser_lock); +++ +++ return ret; +++} +++ +++static int parse_mtd_partitions_by_type(struct mtd_info *master, +++ enum mtd_parser_type type, +++ const struct mtd_partition **pparts, +++ struct mtd_part_parser_data *data) +++{ +++ struct mtd_part_parser *prev = NULL; +++ int ret = 0; +++ +++ while (1) { +++ struct mtd_part_parser *parser; +++ +++ parser = get_partition_parser_by_type(type, prev); +++ if (!parser) +++ break; +++ +++ ret = (*parser->parse_fn)(master, pparts, data); +++ +++ if (ret > 0) { +++ mtd_part_parser_put(parser); +++ printk(KERN_NOTICE +++ "%d %s partitions found on MTD device %s\n", +++ ret, parser->name, master->name); +++ break; +++ } +++ +++ prev = parser; +++ } +++ +++ return ret; +++} +++ +++static int +++run_parsers_by_type(struct mtd_info *child, enum mtd_parser_type type) +++{ +++ struct mtd_partition *parts; +++ int nr_parts; +++ int i; +++ +++ nr_parts = parse_mtd_partitions_by_type(child, type, (const struct mtd_partition **)&parts, +++ NULL); +++ if (nr_parts <= 0) +++ return nr_parts; +++ +++ if (WARN_ON(!parts)) +++ return 0; +++ +++ for (i = 0; i < nr_parts; i++) { +++ /* adjust partition offsets */ +++ parts[i].offset += child->part.offset; +++ +++ mtd_add_partition(child->parent, +++ parts[i].name, +++ parts[i].offset, +++ parts[i].size); +++ } +++ +++ kfree(parts); +++ +++ return nr_parts; +++} +++ +++#ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME +++#define SPLIT_FIRMWARE_NAME CONFIG_MTD_SPLIT_FIRMWARE_NAME +++#else +++#define SPLIT_FIRMWARE_NAME "unused" +++#endif +++ +++static void split_firmware(struct mtd_info *master, struct mtd_info *part) +++{ +++ run_parsers_by_type(part, MTD_PARSER_TYPE_FIRMWARE); +++} +++ +++static void mtd_partition_split(struct mtd_info *master, struct mtd_info *part) +++{ +++ static int rootfs_found = 0; +++ +++ if (rootfs_found) +++ return; +++ +++ if (!strcmp(part->name, "rootfs")) { +++ run_parsers_by_type(part, MTD_PARSER_TYPE_ROOTFS); +++ +++ rootfs_found = 1; +++ } +++ +++ if (IS_ENABLED(CONFIG_MTD_SPLIT_FIRMWARE) && +++ !strcmp(part->name, SPLIT_FIRMWARE_NAME) && +++ !of_find_property(mtd_get_of_node(part), "compatible", NULL)) +++ split_firmware(master, part); +++} +++ ++ int mtd_add_partition(struct mtd_info *parent, const char *name, ++ long long offset, long long length) ++ { ++@@ -274,6 +416,7 @@ int mtd_add_partition(struct mtd_info *p ++ if (ret) ++ goto err_remove_part; ++ +++ mtd_partition_split(parent, child); ++ mtd_add_partition_attrs(child); ++ ++ return 0; ++@@ -422,6 +565,7 @@ int add_mtd_partitions(struct mtd_info * ++ goto err_del_partitions; ++ } ++ +++ mtd_partition_split(master, child); ++ mtd_add_partition_attrs(child); ++ ++ /* Look for subpartitions */ ++@@ -438,31 +582,6 @@ err_del_partitions: ++ return ret; ++ } ++ ++-static DEFINE_SPINLOCK(part_parser_lock); ++-static LIST_HEAD(part_parsers); ++- ++-static struct mtd_part_parser *mtd_part_parser_get(const char *name) ++-{ ++- struct mtd_part_parser *p, *ret = NULL; ++- ++- spin_lock(&part_parser_lock); ++- ++- list_for_each_entry(p, &part_parsers, list) ++- if (!strcmp(p->name, name) && try_module_get(p->owner)) { ++- ret = p; ++- break; ++- } ++- ++- spin_unlock(&part_parser_lock); ++- ++- return ret; ++-} ++- ++-static inline void mtd_part_parser_put(const struct mtd_part_parser *p) ++-{ ++- module_put(p->owner); ++-} ++- ++ /* ++ * Many partition parsers just expected the core to kfree() all their data in ++ * one chunk. Do that by default. ++--- a/include/linux/mtd/partitions.h +++++ b/include/linux/mtd/partitions.h ++@@ -75,6 +75,12 @@ struct mtd_part_parser_data { ++ * Functions dealing with the various ways of partitioning the space ++ */ ++ +++enum mtd_parser_type { +++ MTD_PARSER_TYPE_DEVICE = 0, +++ MTD_PARSER_TYPE_ROOTFS, +++ MTD_PARSER_TYPE_FIRMWARE, +++}; +++ ++ struct mtd_part_parser { ++ struct list_head list; ++ struct module *owner; ++@@ -83,6 +89,7 @@ struct mtd_part_parser { ++ int (*parse_fn)(struct mtd_info *, const struct mtd_partition **, ++ struct mtd_part_parser_data *); ++ void (*cleanup)(const struct mtd_partition *pparts, int nr_parts); +++ enum mtd_parser_type type; ++ }; ++ ++ /* Container for passing around a set of parsed partitions */ ++--- a/drivers/mtd/Makefile +++++ b/drivers/mtd/Makefile ++@@ -9,6 +9,8 @@ mtd-y := mtdcore.o mtdsuper.o mtdconc ++ ++ obj-y += parsers/ ++ +++obj-$(CONFIG_MTD_SPLIT) += mtdsplit/ +++ ++ # 'Users' - code which presents functionality to userspace. ++ obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o ++ obj-$(CONFIG_MTD_BLOCK) += mtdblock.o ++--- a/include/linux/mtd/mtd.h +++++ b/include/linux/mtd/mtd.h ++@@ -608,6 +608,24 @@ static inline void mtd_align_erase_req(s ++ req->len += mtd->erasesize - mod; ++ } ++ +++static inline uint64_t mtd_roundup_to_eb(uint64_t sz, struct mtd_info *mtd) +++{ +++ if (mtd_mod_by_eb(sz, mtd) == 0) +++ return sz; +++ +++ /* Round up to next erase block */ +++ return (mtd_div_by_eb(sz, mtd) + 1) * mtd->erasesize; +++} +++ +++static inline uint64_t mtd_rounddown_to_eb(uint64_t sz, struct mtd_info *mtd) +++{ +++ if (mtd_mod_by_eb(sz, mtd) == 0) +++ return sz; +++ +++ /* Round down to the start of the current erase block */ +++ return (mtd_div_by_eb(sz, mtd)) * mtd->erasesize; +++} +++ ++ static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd) ++ { ++ if (mtd->writesize_shift) ++@@ -680,6 +698,13 @@ extern void __put_mtd_device(struct mtd_ ++ extern struct mtd_info *get_mtd_device_nm(const char *name); ++ extern void put_mtd_device(struct mtd_info *mtd); ++ +++static inline uint64_t mtdpart_get_offset(const struct mtd_info *mtd) +++{ +++ if (!mtd_is_partition(mtd)) +++ return 0; +++ +++ return mtd->part.offset; +++} ++ ++ struct mtd_notifier { ++ void (*add)(struct mtd_info *mtd); +diff --git a/target/linux/generic/pending-5.10/419-mtd-redboot-add-of_match_table-with-DT-binding.patch b/target/linux/generic/pending-5.10/419-mtd-redboot-add-of_match_table-with-DT-binding.patch +new file mode 100644 +index 0000000000..8358a307cd +--- /dev/null ++++ b/target/linux/generic/pending-5.10/419-mtd-redboot-add-of_match_table-with-DT-binding.patch +@@ -0,0 +1,22 @@ ++From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= ++Subject: [PATCH] mtd: redboot: add of_match_table with DT binding ++MIME-Version: 1.0 ++Content-Type: text/plain; charset=UTF-8 ++Content-Transfer-Encoding: 8bit ++ ++This allows parsing RedBoot compatible partitions for properly described ++flash device in DT. ++ ++Signed-off-by: Rafał Miłecki ++--- ++ ++--- a/drivers/mtd/parsers/redboot.c +++++ b/drivers/mtd/parsers/redboot.c ++@@ -300,6 +300,7 @@ static int parse_redboot_partitions(stru ++ ++ static const struct of_device_id mtd_parser_redboot_of_match_table[] = { ++ { .compatible = "redboot-fis" }, +++ { .compatible = "ecoscentric,redboot-fis-partitions" }, ++ {}, ++ }; ++ MODULE_DEVICE_TABLE(of, mtd_parser_redboot_of_match_table); +diff --git a/target/linux/generic/pending-5.10/420-mtd-redboot_space.patch b/target/linux/generic/pending-5.10/420-mtd-redboot_space.patch +new file mode 100644 +index 0000000000..a2cf838989 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/420-mtd-redboot_space.patch +@@ -0,0 +1,41 @@ ++From: Felix Fietkau ++Subject: add patch for including unpartitioned space in the rootfs partition for redboot devices (if applicable) ++ ++[john@phrozen.org: used by ixp and others] ++ ++lede-commit: 394918851f84e4d00fa16eb900e7700e95091f00 ++Signed-off-by: Felix Fietkau ++--- ++ drivers/mtd/redboot.c | 19 +++++++++++++------ ++ 1 file changed, 13 insertions(+), 6 deletions(-) ++ ++--- a/drivers/mtd/parsers/redboot.c +++++ b/drivers/mtd/parsers/redboot.c ++@@ -274,14 +274,21 @@ static int parse_redboot_partitions(stru ++ #endif ++ names += strlen(names)+1; ++ ++-#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED ++ if(fl->next && fl->img->flash_base + fl->img->size + master->erasesize <= fl->next->img->flash_base) { ++- i++; ++- parts[i].offset = parts[i-1].size + parts[i-1].offset; ++- parts[i].size = fl->next->img->flash_base - parts[i].offset; ++- parts[i].name = nullname; ++- } +++ if (!strcmp(parts[i].name, "rootfs")) { +++ parts[i].size = fl->next->img->flash_base; +++ parts[i].size &= ~(master->erasesize - 1); +++ parts[i].size -= parts[i].offset; +++#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED +++ nrparts--; +++ } else { +++ i++; +++ parts[i].offset = parts[i-1].size + parts[i-1].offset; +++ parts[i].size = fl->next->img->flash_base - parts[i].offset; +++ parts[i].name = nullname; ++ #endif +++ } +++ } ++ tmp_fl = fl; ++ fl = fl->next; ++ kfree(tmp_fl); +diff --git a/target/linux/generic/pending-5.10/430-mtd-add-myloader-partition-parser.patch b/target/linux/generic/pending-5.10/430-mtd-add-myloader-partition-parser.patch +new file mode 100644 +index 0000000000..5c00612d03 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/430-mtd-add-myloader-partition-parser.patch +@@ -0,0 +1,229 @@ ++From: Florian Fainelli ++Subject: Add myloader partition table parser ++ ++[john@phozen.org: shoud be upstreamable] ++ ++lede-commit: d8bf22859b51faa09d22c056fe221a45d2f7a3b8 ++Signed-off-by: Florian Fainelli ++[adjust for kernel 5.4, add myloader.c to patch] ++Signed-off-by: Adrian Schmutzler ++ ++--- a/drivers/mtd/parsers/Kconfig +++++ b/drivers/mtd/parsers/Kconfig ++@@ -57,6 +57,22 @@ config MTD_CMDLINE_PARTS ++ ++ If unsure, say 'N'. ++ +++config MTD_MYLOADER_PARTS +++ tristate "MyLoader partition parsing" +++ depends on ADM5120 || ATH25 || ATH79 +++ help +++ MyLoader is a bootloader which allows the user to define partitions +++ in flash devices, by putting a table in the second erase block +++ on the device, similar to a partition table. This table gives the +++ offsets and lengths of the user defined partitions. +++ +++ If you need code which can detect and parse these tables, and +++ register MTD 'partitions' corresponding to each image detected, +++ enable this option. +++ +++ You will still need the parsing functions to be called by the driver +++ for your particular device. It won't happen automatically. +++ ++ config MTD_OF_PARTS ++ tristate "OpenFirmware (device tree) partitioning parser" ++ default y ++--- a/drivers/mtd/parsers/Makefile +++++ b/drivers/mtd/parsers/Makefile ++@@ -3,6 +3,7 @@ obj-$(CONFIG_MTD_AR7_PARTS) += ar7part. ++ obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o ++ obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o ++ obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o +++obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o ++ obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o ++ obj-$(CONFIG_MTD_PARSER_IMAGETAG) += parser_imagetag.o ++ obj-$(CONFIG_MTD_AFS_PARTS) += afs.o ++--- /dev/null +++++ b/drivers/mtd/parsers/myloader.c ++@@ -0,0 +1,181 @@ +++/* +++ * Parse MyLoader-style flash partition tables and produce a Linux partition +++ * array to match. +++ * +++ * Copyright (C) 2007-2009 Gabor Juhos +++ * +++ * This file was based on drivers/mtd/redboot.c +++ * Author: Red Hat, Inc. - David Woodhouse +++ * +++ * This program is free software; you can redistribute it and/or modify it +++ * under the terms of the GNU General Public License version 2 as published +++ * by the Free Software Foundation. +++ */ +++ +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++ +++#define BLOCK_LEN_MIN 0x10000 +++#define PART_NAME_LEN 32 +++ +++struct part_data { +++ struct mylo_partition_table tab; +++ char names[MYLO_MAX_PARTITIONS][PART_NAME_LEN]; +++}; +++ +++static int myloader_parse_partitions(struct mtd_info *master, +++ const struct mtd_partition **pparts, +++ struct mtd_part_parser_data *data) +++{ +++ struct part_data *buf; +++ struct mylo_partition_table *tab; +++ struct mylo_partition *part; +++ struct mtd_partition *mtd_parts; +++ struct mtd_partition *mtd_part; +++ int num_parts; +++ int ret, i; +++ size_t retlen; +++ char *names; +++ unsigned long offset; +++ unsigned long blocklen; +++ +++ buf = vmalloc(sizeof(*buf)); +++ if (!buf) { +++ return -ENOMEM; +++ goto out; +++ } +++ tab = &buf->tab; +++ +++ blocklen = master->erasesize; +++ if (blocklen < BLOCK_LEN_MIN) +++ blocklen = BLOCK_LEN_MIN; +++ +++ offset = blocklen; +++ +++ /* Find the partition table */ +++ for (i = 0; i < 4; i++, offset += blocklen) { +++ printk(KERN_DEBUG "%s: searching for MyLoader partition table" +++ " at offset 0x%lx\n", master->name, offset); +++ +++ ret = mtd_read(master, offset, sizeof(*buf), &retlen, +++ (void *)buf); +++ if (ret) +++ goto out_free_buf; +++ +++ if (retlen != sizeof(*buf)) { +++ ret = -EIO; +++ goto out_free_buf; +++ } +++ +++ /* Check for Partition Table magic number */ +++ if (tab->magic == le32_to_cpu(MYLO_MAGIC_PARTITIONS)) +++ break; +++ +++ } +++ +++ if (tab->magic != le32_to_cpu(MYLO_MAGIC_PARTITIONS)) { +++ printk(KERN_DEBUG "%s: no MyLoader partition table found\n", +++ master->name); +++ ret = 0; +++ goto out_free_buf; +++ } +++ +++ /* The MyLoader and the Partition Table is always present */ +++ num_parts = 2; +++ +++ /* Detect number of used partitions */ +++ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) { +++ part = &tab->partitions[i]; +++ +++ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE) +++ continue; +++ +++ num_parts++; +++ } +++ +++ mtd_parts = kzalloc((num_parts * sizeof(*mtd_part) + +++ num_parts * PART_NAME_LEN), GFP_KERNEL); +++ +++ if (!mtd_parts) { +++ ret = -ENOMEM; +++ goto out_free_buf; +++ } +++ +++ mtd_part = mtd_parts; +++ names = (char *)&mtd_parts[num_parts]; +++ +++ strncpy(names, "myloader", PART_NAME_LEN); +++ mtd_part->name = names; +++ mtd_part->offset = 0; +++ mtd_part->size = offset; +++ mtd_part->mask_flags = MTD_WRITEABLE; +++ mtd_part++; +++ names += PART_NAME_LEN; +++ +++ strncpy(names, "partition_table", PART_NAME_LEN); +++ mtd_part->name = names; +++ mtd_part->offset = offset; +++ mtd_part->size = blocklen; +++ mtd_part->mask_flags = MTD_WRITEABLE; +++ mtd_part++; +++ names += PART_NAME_LEN; +++ +++ for (i = 0; i < MYLO_MAX_PARTITIONS; i++) { +++ part = &tab->partitions[i]; +++ +++ if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE) +++ continue; +++ +++ if ((buf->names[i][0]) && (buf->names[i][0] != '\xff')) +++ strncpy(names, buf->names[i], PART_NAME_LEN); +++ else +++ snprintf(names, PART_NAME_LEN, "partition%d", i); +++ +++ mtd_part->offset = le32_to_cpu(part->addr); +++ mtd_part->size = le32_to_cpu(part->size); +++ mtd_part->name = names; +++ mtd_part++; +++ names += PART_NAME_LEN; +++ } +++ +++ *pparts = mtd_parts; +++ ret = num_parts; +++ +++ out_free_buf: +++ vfree(buf); +++ out: +++ return ret; +++} +++ +++static struct mtd_part_parser myloader_mtd_parser = { +++ .owner = THIS_MODULE, +++ .parse_fn = myloader_parse_partitions, +++ .name = "MyLoader", +++}; +++ +++static int __init myloader_mtd_parser_init(void) +++{ +++ register_mtd_parser(&myloader_mtd_parser); +++ +++ return 0; +++} +++ +++static void __exit myloader_mtd_parser_exit(void) +++{ +++ deregister_mtd_parser(&myloader_mtd_parser); +++} +++ +++module_init(myloader_mtd_parser_init); +++module_exit(myloader_mtd_parser_exit); +++ +++MODULE_AUTHOR("Gabor Juhos "); +++MODULE_DESCRIPTION("Parsing code for MyLoader partition tables"); +++MODULE_LICENSE("GPL v2"); +diff --git a/target/linux/generic/pending-5.10/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch b/target/linux/generic/pending-5.10/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch +new file mode 100644 +index 0000000000..2ea59cd872 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch +@@ -0,0 +1,68 @@ ++From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= ++Subject: [PATCH] mtd: bcm47xxpart: check for bad blocks when calculating offsets ++ ++Signed-off-by: Rafał Miłecki ++--- ++ ++--- a/drivers/mtd/parsers/parser_trx.c +++++ b/drivers/mtd/parsers/parser_trx.c ++@@ -25,6 +25,33 @@ struct trx_header { ++ uint32_t offset[3]; ++ } __packed; ++ +++/* +++ * Calculate real end offset (address) for a given amount of data. It checks +++ * all blocks skipping bad ones. +++ */ +++static size_t parser_trx_real_offset(struct mtd_info *mtd, size_t bytes) +++{ +++ size_t real_offset = 0; +++ +++ if (mtd_block_isbad(mtd, real_offset)) +++ pr_warn("Base offset shouldn't be at bad block"); +++ +++ while (bytes >= mtd->erasesize) { +++ bytes -= mtd->erasesize; +++ real_offset += mtd->erasesize; +++ while (mtd_block_isbad(mtd, real_offset)) { +++ real_offset += mtd->erasesize; +++ +++ if (real_offset >= mtd->size) +++ return real_offset - mtd->erasesize; +++ } +++ } +++ +++ real_offset += bytes; +++ +++ return real_offset; +++} +++ ++ static const char *parser_trx_data_part_name(struct mtd_info *master, ++ size_t offset) ++ { ++@@ -79,21 +106,21 @@ static int parser_trx_parse(struct mtd_i ++ if (trx.offset[2]) { ++ part = &parts[curr_part++]; ++ part->name = "loader"; ++- part->offset = trx.offset[i]; +++ part->offset = parser_trx_real_offset(mtd, trx.offset[i]); ++ i++; ++ } ++ ++ if (trx.offset[i]) { ++ part = &parts[curr_part++]; ++ part->name = "linux"; ++- part->offset = trx.offset[i]; +++ part->offset = parser_trx_real_offset(mtd, trx.offset[i]); ++ i++; ++ } ++ ++ if (trx.offset[i]) { ++ part = &parts[curr_part++]; ++- part->name = parser_trx_data_part_name(mtd, trx.offset[i]); ++- part->offset = trx.offset[i]; +++ part->offset = parser_trx_real_offset(mtd, trx.offset[i]); +++ part->name = parser_trx_data_part_name(mtd, part->offset); ++ i++; ++ } ++ +diff --git a/target/linux/generic/pending-5.10/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch b/target/linux/generic/pending-5.10/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch +new file mode 100644 +index 0000000000..852654d924 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch +@@ -0,0 +1,37 @@ ++From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= ++Subject: mtd: bcm47xxpart: detect T_Meter partition ++ ++It can be found on many Netgear devices. It consists of many 0x30 blocks ++starting with 4D 54. ++ ++Signed-off-by: Rafał Miłecki ++--- ++ drivers/mtd/bcm47xxpart.c | 10 ++++++++++ ++ 1 file changed, 10 insertions(+) ++ ++--- a/drivers/mtd/parsers/bcm47xxpart.c +++++ b/drivers/mtd/parsers/bcm47xxpart.c ++@@ -35,6 +35,7 @@ ++ #define NVRAM_HEADER 0x48534C46 /* FLSH */ ++ #define POT_MAGIC1 0x54544f50 /* POTT */ ++ #define POT_MAGIC2 0x504f /* OP */ +++#define T_METER_MAGIC 0x4D540000 /* MT */ ++ #define ML_MAGIC1 0x39685a42 ++ #define ML_MAGIC2 0x26594131 ++ #define TRX_MAGIC 0x30524448 ++@@ -178,6 +179,15 @@ static int bcm47xxpart_parse(struct mtd_ ++ MTD_WRITEABLE); ++ continue; ++ } +++ +++ /* T_Meter */ +++ if ((le32_to_cpu(buf[0x000 / 4]) & 0xFFFF0000) == T_METER_MAGIC && +++ (le32_to_cpu(buf[0x030 / 4]) & 0xFFFF0000) == T_METER_MAGIC && +++ (le32_to_cpu(buf[0x060 / 4]) & 0xFFFF0000) == T_METER_MAGIC) { +++ bcm47xxpart_add_part(&parts[curr_part++], "T_Meter", offset, +++ MTD_WRITEABLE); +++ continue; +++ } ++ ++ /* TRX */ ++ if (buf[0x000 / 4] == TRX_MAGIC) { +diff --git a/target/linux/generic/pending-5.10/435-mtd-add-routerbootpart-parser-config.patch b/target/linux/generic/pending-5.10/435-mtd-add-routerbootpart-parser-config.patch +new file mode 100644 +index 0000000000..1523e757c7 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/435-mtd-add-routerbootpart-parser-config.patch +@@ -0,0 +1,38 @@ ++From 4437e01fb6bca63fccdba5d6c44888b0935885c2 Mon Sep 17 00:00:00 2001 ++From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= ++Date: Tue, 24 Mar 2020 11:45:07 +0100 ++Subject: [PATCH] generic: routerboot partition build bits (5.4) ++MIME-Version: 1.0 ++Content-Type: text/plain; charset=UTF-8 ++Content-Transfer-Encoding: 8bit ++ ++This patch adds routerbootpart kernel build bits ++ ++Signed-off-by: Thibaut VARÈNE ++--- ++ drivers/mtd/parsers/Kconfig | 9 +++++++++ ++ drivers/mtd/parsers/Makefile | 1 + ++ 2 files changed, 10 insertions(+) ++ ++--- a/drivers/mtd/parsers/Kconfig +++++ b/drivers/mtd/parsers/Kconfig ++@@ -176,3 +176,12 @@ config MTD_REDBOOT_PARTS_READONLY ++ 'FIS directory' images, enable this option. ++ ++ endif # MTD_REDBOOT_PARTS +++ +++config MTD_ROUTERBOOT_PARTS +++ tristate "RouterBoot flash partition parser" +++ depends on MTD && OF +++ help +++ MikroTik RouterBoot is implemented as a multi segment system on the +++ flash, some of which are fixed and some of which are located at +++ variable offsets. This parser handles both cases via properly +++ formatted DTS. ++--- a/drivers/mtd/parsers/Makefile +++++ b/drivers/mtd/parsers/Makefile ++@@ -10,3 +10,4 @@ obj-$(CONFIG_MTD_AFS_PARTS) += afs.o ++ obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o ++ obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o ++ obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o +++obj-$(CONFIG_MTD_ROUTERBOOT_PARTS) += routerbootpart.o +diff --git a/target/linux/generic/pending-5.10/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch b/target/linux/generic/pending-5.10/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch +new file mode 100644 +index 0000000000..659a6386ae +--- /dev/null ++++ b/target/linux/generic/pending-5.10/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch +@@ -0,0 +1,25 @@ ++From: Felix Fietkau ++Subject: kernel: disable cfi cmdset 0002 erase suspend ++ ++on some platforms, erase suspend leads to data corruption and lockups when write ++ops collide with erase ops. this has been observed on the buffalo wzr-hp-g300nh. ++rather than play whack-a-mole with a hard to reproduce issue on a variety of devices, ++simply disable erase suspend, as it will usually not produce any useful gain on ++the small filesystems used on embedded hardware. ++ ++Signed-off-by: Felix Fietkau ++--- ++ drivers/mtd/chips/cfi_cmdset_0002.c | 2 +- ++ 1 file changed, 1 insertion(+), 1 deletion(-) ++ ++--- a/drivers/mtd/chips/cfi_cmdset_0002.c +++++ b/drivers/mtd/chips/cfi_cmdset_0002.c ++@@ -909,7 +909,7 @@ static int get_chip(struct map_info *map ++ return 0; ++ ++ case FL_ERASING: ++- if (!cfip || !(cfip->EraseSuspend & (0x1|0x2)) || +++ if (1 /* no suspend */ || !cfip || !(cfip->EraseSuspend & (0x1|0x2)) || ++ !(mode == FL_READY || mode == FL_POINT || ++ (mode == FL_WRITING && (cfip->EraseSuspend & 0x2)))) ++ goto sleep; +diff --git a/target/linux/generic/pending-5.10/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch b/target/linux/generic/pending-5.10/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch +new file mode 100644 +index 0000000000..79276b1b87 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch +@@ -0,0 +1,17 @@ ++From: George Kashperko ++Subject: Issue map read after Write Buffer Load command to ensure chip is ready to receive data. ++ ++Signed-off-by: George Kashperko ++--- ++ drivers/mtd/chips/cfi_cmdset_0002.c | 1 + ++ 1 file changed, 1 insertion(+) ++--- a/drivers/mtd/chips/cfi_cmdset_0002.c +++++ b/drivers/mtd/chips/cfi_cmdset_0002.c ++@@ -2053,6 +2053,7 @@ static int __xipram do_write_buffer(stru ++ ++ /* Write Buffer Load */ ++ map_write(map, CMD(0x25), cmd_adr); +++ (void) map_read(map, cmd_adr); ++ ++ chip->state = FL_WRITING_TO_BUFFER; ++ +diff --git a/target/linux/generic/pending-5.10/465-m25p80-mx-disable-software-protection.patch b/target/linux/generic/pending-5.10/465-m25p80-mx-disable-software-protection.patch +new file mode 100644 +index 0000000000..e9a9cad869 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/465-m25p80-mx-disable-software-protection.patch +@@ -0,0 +1,18 @@ ++From: Felix Fietkau ++Subject: Disable software protection bits for Macronix flashes. ++ ++Signed-off-by: Felix Fietkau ++--- ++ drivers/mtd/spi-nor/spi-nor.c | 1 + ++ 1 file changed, 1 insertion(+) ++ ++--- a/drivers/mtd/spi-nor/macronix.c +++++ b/drivers/mtd/spi-nor/macronix.c ++@@ -96,6 +96,7 @@ static void macronix_default_init(struct ++ { ++ nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable; ++ nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode; +++ nor->flags |= SNOR_F_HAS_LOCK; ++ } ++ ++ static const struct spi_nor_fixups macronix_fixups = { +diff --git a/target/linux/generic/pending-5.10/470-mtd-spi-nor-support-limiting-4K-sectors-support-base.patch b/target/linux/generic/pending-5.10/470-mtd-spi-nor-support-limiting-4K-sectors-support-base.patch +new file mode 100644 +index 0000000000..bbdab18102 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/470-mtd-spi-nor-support-limiting-4K-sectors-support-base.patch +@@ -0,0 +1,71 @@ ++From: Felix Fietkau ++Date: Sat, 4 Nov 2017 07:40:23 +0100 ++Subject: [PATCH] mtd: spi-nor: support limiting 4K sectors support based on ++ flash size ++ ++Some devices need 4K sectors to be able to deal with small flash chips. ++For instance, w25x05 is 64 KiB in size, and without 4K sectors, the ++entire chip is just one erase block. ++On bigger flash chip sizes, using 4K sectors can significantly slow down ++many operations, including using a writable filesystem. There are several ++platforms where it makes sense to use a single kernel on both kinds of ++devices. ++ ++To support this properly, allow configuring an upper flash chip size ++limit for 4K sectors support. ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/drivers/mtd/spi-nor/Kconfig +++++ b/drivers/mtd/spi-nor/Kconfig ++@@ -24,6 +24,17 @@ config MTD_SPI_NOR_USE_4K_SECTORS ++ Please note that some tools/drivers/filesystems may not work with ++ 4096 B erase size (e.g. UBIFS requires 15 KiB as a minimum). ++ +++config MTD_SPI_NOR_USE_4K_SECTORS_LIMIT +++ int "Maximum flash chip size to use 4K sectors on (in KiB)" +++ depends on MTD_SPI_NOR_USE_4K_SECTORS +++ default "4096" +++ help +++ There are many flash chips that support 4K sectors, but are so large +++ that using them significantly slows down writing large amounts of +++ data or using a writable filesystem. +++ Any flash chip larger than the size specified in this option will +++ not use 4K sectors. +++ ++ source "drivers/mtd/spi-nor/controllers/Kconfig" ++ ++ endif # MTD_SPI_NOR ++--- a/drivers/mtd/spi-nor/core.c +++++ b/drivers/mtd/spi-nor/core.c ++@@ -2784,6 +2784,21 @@ static void spi_nor_info_init_params(str ++ */ ++ erase_mask = 0; ++ i = 0; +++#ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS +++ if ((info->flags & SECT_4K_PMC) && (params->size <= +++ CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT * 1024)) { +++ erase_mask |= BIT(i); +++ spi_nor_set_erase_type(&map->erase_type[i], 4096u, +++ SPINOR_OP_BE_4K_PMC); +++ i++; +++ } else if ((info->flags & SECT_4K) && (params->size <= +++ CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT * 1024)) { +++ erase_mask |= BIT(i); +++ spi_nor_set_erase_type(&map->erase_type[i], 4096u, +++ SPINOR_OP_BE_4K); +++ i++; +++ } +++#else ++ if (info->flags & SECT_4K_PMC) { ++ erase_mask |= BIT(i); ++ spi_nor_set_erase_type(&map->erase_type[i], 4096u, ++@@ -2795,6 +2810,7 @@ static void spi_nor_info_init_params(str ++ SPINOR_OP_BE_4K); ++ i++; ++ } +++#endif ++ erase_mask |= BIT(i); ++ spi_nor_set_erase_type(&map->erase_type[i], info->sector_size, ++ SPINOR_OP_SE); +diff --git a/target/linux/generic/pending-5.10/476-mtd-spi-nor-add-eon-en25q128.patch b/target/linux/generic/pending-5.10/476-mtd-spi-nor-add-eon-en25q128.patch +new file mode 100644 +index 0000000000..325fca62f3 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/476-mtd-spi-nor-add-eon-en25q128.patch +@@ -0,0 +1,18 @@ ++From: Piotr Dymacz ++Subject: kernel/mtd: add support for EON EN25Q128 ++ ++Signed-off-by: Piotr Dymacz ++--- ++ drivers/mtd/spi-nor/spi-nor.c | 1 + ++ 1 file changed, 1 insertion(+) ++ ++--- a/drivers/mtd/spi-nor/eon.c +++++ b/drivers/mtd/spi-nor/eon.c ++@@ -15,6 +15,7 @@ static const struct flash_info eon_parts ++ { "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) }, ++ { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, ++ { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) }, +++ { "en25q128", INFO(0x1c3018, 0, 64 * 1024, 256, SECT_4K) }, ++ { "en25q80a", INFO(0x1c3014, 0, 64 * 1024, 16, ++ SECT_4K | SPI_NOR_DUAL_READ) }, ++ { "en25qh16", INFO(0x1c7015, 0, 64 * 1024, 32, +diff --git a/target/linux/generic/pending-5.10/479-mtd-spi-nor-add-xtx-xt25f128b.patch b/target/linux/generic/pending-5.10/479-mtd-spi-nor-add-xtx-xt25f128b.patch +new file mode 100644 +index 0000000000..3e7cd03679 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/479-mtd-spi-nor-add-xtx-xt25f128b.patch +@@ -0,0 +1,79 @@ ++From patchwork Thu Feb 6 17:19:41 2020 ++Content-Type: text/plain; charset="utf-8" ++MIME-Version: 1.0 ++Content-Transfer-Encoding: 7bit ++X-Patchwork-Submitter: Daniel Golle ++X-Patchwork-Id: 1234465 ++Date: Thu, 6 Feb 2020 19:19:41 +0200 ++From: Daniel Golle ++To: linux-mtd@lists.infradead.org ++Subject: [PATCH v2] mtd: spi-nor: Add support for xt25f128b chip ++Message-ID: <20200206171941.GA2398@makrotopia.org> ++MIME-Version: 1.0 ++Content-Disposition: inline ++List-Subscribe: , ++ ++Cc: Eitan Cohen , Piotr Dymacz , ++ Tudor Ambarus ++Sender: "linux-mtd" ++Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org ++ ++Add XT25F128B made by XTX Technology (Shenzhen) Limited. ++This chip supports dual and quad read and uniform 4K-byte erase. ++Verified on Teltonika RUT955 which comes with XT25F128B in recent ++versions of the device. ++ ++Signed-off-by: Daniel Golle ++Signed-off-by: Felix Fietkau ++--- ++ drivers/mtd/spi-nor/spi-nor.c | 4 ++++ ++ 1 file changed, 4 insertions(+) ++ ++--- a/drivers/mtd/spi-nor/Makefile +++++ b/drivers/mtd/spi-nor/Makefile ++@@ -17,6 +17,7 @@ spi-nor-objs += sst.o ++ spi-nor-objs += winbond.o ++ spi-nor-objs += xilinx.o ++ spi-nor-objs += xmc.o +++spi-nor-objs += xtx.o ++ obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o ++ ++ obj-$(CONFIG_MTD_SPI_NOR) += controllers/ ++--- /dev/null +++++ b/drivers/mtd/spi-nor/xtx.c ++@@ -0,0 +1,15 @@ +++// SPDX-License-Identifier: GPL-2.0 +++#include +++ +++#include "core.h" +++ +++static const struct flash_info xtx_parts[] = { +++ /* XTX Technology (Shenzhen) Limited */ +++ { "xt25f128b", INFO(0x0B4018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, +++}; +++ +++const struct spi_nor_manufacturer spi_nor_xtx = { +++ .name = "xtx", +++ .parts = xtx_parts, +++ .nparts = ARRAY_SIZE(xtx_parts), +++}; ++--- a/drivers/mtd/spi-nor/core.c +++++ b/drivers/mtd/spi-nor/core.c ++@@ -2024,6 +2024,7 @@ static const struct spi_nor_manufacturer ++ &spi_nor_winbond, ++ &spi_nor_xilinx, ++ &spi_nor_xmc, +++ &spi_nor_xtx, ++ }; ++ ++ static const struct flash_info * ++--- a/drivers/mtd/spi-nor/core.h +++++ b/drivers/mtd/spi-nor/core.h ++@@ -398,6 +398,7 @@ extern const struct spi_nor_manufacturer ++ extern const struct spi_nor_manufacturer spi_nor_winbond; ++ extern const struct spi_nor_manufacturer spi_nor_xilinx; ++ extern const struct spi_nor_manufacturer spi_nor_xmc; +++extern const struct spi_nor_manufacturer spi_nor_xtx; ++ ++ int spi_nor_write_enable(struct spi_nor *nor); ++ int spi_nor_write_disable(struct spi_nor *nor); +diff --git a/target/linux/generic/pending-5.10/480-mtd-set-rootfs-to-be-root-dev.patch b/target/linux/generic/pending-5.10/480-mtd-set-rootfs-to-be-root-dev.patch +new file mode 100644 +index 0000000000..11cdc179d2 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/480-mtd-set-rootfs-to-be-root-dev.patch +@@ -0,0 +1,38 @@ ++From: Gabor Juhos ++Subject: kernel/3.1[02]: move MTD root device setup code to mtdcore ++ ++The current code only allows to automatically set ++root device on MTD partitions. Move the code to MTD ++core to allow to use it with all MTD devices. ++ ++Signed-off-by: Gabor Juhos ++--- ++ drivers/mtd/mtdcore.c | 10 ++++++++++ ++ 1 file changed, 10 insertions(+) ++ ++--- a/drivers/mtd/mtdcore.c +++++ b/drivers/mtd/mtdcore.c ++@@ -27,6 +27,7 @@ ++ #include ++ #include ++ #include +++#include ++ #include ++ ++ #include ++@@ -692,6 +693,15 @@ int add_mtd_device(struct mtd_info *mtd) ++ of this try_ nonsense, and no bitching about it ++ either. :) */ ++ __module_get(THIS_MODULE); +++ +++ if (!strcmp(mtd->name, "rootfs") && +++ IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && +++ ROOT_DEV == 0) { +++ pr_notice("mtd: device %d (%s) set to be root filesystem\n", +++ mtd->index, mtd->name); +++ ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index); +++ } +++ ++ return 0; ++ ++ fail_nvmem_add: +diff --git a/target/linux/generic/pending-5.10/481-mtd-spi-nor-rework-broken-flash-reset-support.patch b/target/linux/generic/pending-5.10/481-mtd-spi-nor-rework-broken-flash-reset-support.patch +new file mode 100644 +index 0000000000..e8e737ffca +--- /dev/null ++++ b/target/linux/generic/pending-5.10/481-mtd-spi-nor-rework-broken-flash-reset-support.patch +@@ -0,0 +1,180 @@ ++From ea92cbb50a78404e29de2cc3999a240615ffb1c8 Mon Sep 17 00:00:00 2001 ++From: Chuanhong Guo ++Date: Mon, 6 Apr 2020 17:58:48 +0800 ++Subject: [PATCH] mtd: spi-nor: rework broken-flash-reset support ++ ++Instead of resetting flash to 3B address on remove hook, this ++implementation only enters 4B mode when needed, which prevents ++more unexpected reboot stuck. This implementation makes it only ++break when a kernel panic happens during flash operation on 16M+ ++areas. ++*OpenWrt only*: silent broken-flash-reset warning. We are not dealing ++with vendors and it's unpleasant for users to se that unnecessary ++and long WARN_ON print. ++ ++Signed-off-by: Chuanhong Guo ++--- ++ drivers/mtd/spi-nor/spi-nor.c | 52 +++++++++++++++++++++++++++++++++-- ++ 1 file changed, 49 insertions(+), 3 deletions(-) ++ ++--- a/drivers/mtd/spi-nor/core.c +++++ b/drivers/mtd/spi-nor/core.c ++@@ -1445,6 +1445,23 @@ destroy_erase_cmd_list: ++ return ret; ++ } ++ +++int spi_nor_check_set_addr_width(struct spi_nor *nor, loff_t addr) +++{ +++ u8 addr_width; +++ +++ if ((nor->flags & (SNOR_F_4B_OPCODES | SNOR_F_BROKEN_RESET)) != +++ SNOR_F_BROKEN_RESET) +++ return 0; +++ +++ addr_width = addr & 0xff000000 ? 4 : 3; +++ if (nor->addr_width == addr_width) +++ return 0; +++ +++ nor->addr_width = addr_width; +++ +++ return nor->params->set_4byte_addr_mode(nor, addr_width == 4); +++} +++ ++ /* ++ * Erase an address range on the nor chip. The address range may extend ++ * one or more erase sectors. Return an error is there is a problem erasing. ++@@ -1472,6 +1489,10 @@ static int spi_nor_erase(struct mtd_info ++ if (ret) ++ return ret; ++ +++ ret = spi_nor_check_set_addr_width(nor, instr->addr + instr->len); +++ if (ret < 0) +++ return ret; +++ ++ /* whole-chip erase? */ ++ if (len == mtd->size && !(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) { ++ unsigned long timeout; ++@@ -1531,6 +1552,7 @@ static int spi_nor_erase(struct mtd_info ++ ret = spi_nor_write_disable(nor); ++ ++ erase_err: +++ spi_nor_check_set_addr_width(nor, 0); ++ spi_nor_unlock_and_unprep(nor); ++ ++ return ret; ++@@ -1870,7 +1892,9 @@ static int spi_nor_lock(struct mtd_info ++ if (ret) ++ return ret; ++ +++ spi_nor_check_set_addr_width(nor, ofs + len); ++ ret = nor->params->locking_ops->lock(nor, ofs, len); +++ spi_nor_check_set_addr_width(nor, 0); ++ ++ spi_nor_unlock_and_unprep(nor); ++ return ret; ++@@ -1885,7 +1909,9 @@ static int spi_nor_unlock(struct mtd_inf ++ if (ret) ++ return ret; ++ +++ spi_nor_check_set_addr_width(nor, ofs + len); ++ ret = nor->params->locking_ops->unlock(nor, ofs, len); +++ spi_nor_check_set_addr_width(nor, 0); ++ ++ spi_nor_unlock_and_unprep(nor); ++ return ret; ++@@ -1900,7 +1926,9 @@ static int spi_nor_is_locked(struct mtd_ ++ if (ret) ++ return ret; ++ +++ spi_nor_check_set_addr_width(nor, ofs + len); ++ ret = nor->params->locking_ops->is_locked(nor, ofs, len); +++ spi_nor_check_set_addr_width(nor, 0); ++ ++ spi_nor_unlock_and_unprep(nor); ++ return ret; ++@@ -2093,6 +2121,10 @@ static int spi_nor_read(struct mtd_info ++ if (ret) ++ return ret; ++ +++ ret = spi_nor_check_set_addr_width(nor, from + len); +++ if (ret < 0) +++ return ret; +++ ++ while (len) { ++ loff_t addr = from; ++ ++@@ -2116,6 +2148,7 @@ static int spi_nor_read(struct mtd_info ++ ret = 0; ++ ++ read_err: +++ spi_nor_check_set_addr_width(nor, 0); ++ spi_nor_unlock_and_unprep(nor); ++ return ret; ++ } ++@@ -2138,6 +2171,10 @@ static int spi_nor_write(struct mtd_info ++ if (ret) ++ return ret; ++ +++ ret = spi_nor_check_set_addr_width(nor, to + len); +++ if (ret < 0) +++ return ret; +++ ++ for (i = 0; i < len; ) { ++ ssize_t written; ++ loff_t addr = to + i; ++@@ -2180,6 +2217,7 @@ static int spi_nor_write(struct mtd_info ++ } ++ ++ write_err: +++ spi_nor_check_set_addr_width(nor, 0); ++ spi_nor_unlock_and_unprep(nor); ++ return ret; ++ } ++@@ -2975,9 +3013,13 @@ static int spi_nor_init(struct spi_nor * ++ * reboots (e.g., crashes). Warn the user (or hopefully, system ++ * designer) that this is bad. ++ */ ++- WARN_ONCE(nor->flags & SNOR_F_BROKEN_RESET, ++- "enabling reset hack; may not recover from unexpected reboots\n"); ++- nor->params->set_4byte_addr_mode(nor, true); +++ if (nor->flags & SNOR_F_BROKEN_RESET) { +++ dev_warn(nor->dev, +++ "enabling reset hack; may not recover from unexpected reboots\n"); +++ nor->addr_width = 3; +++ } else { +++ nor->params->set_4byte_addr_mode(nor, true); +++ } ++ } ++ ++ return 0; ++--- a/drivers/mtd/spi-nor/core.h +++++ b/drivers/mtd/spi-nor/core.h ++@@ -400,6 +400,7 @@ extern const struct spi_nor_manufacturer ++ extern const struct spi_nor_manufacturer spi_nor_xmc; ++ extern const struct spi_nor_manufacturer spi_nor_xtx; ++ +++int spi_nor_check_set_addr_width(struct spi_nor *nor, loff_t addr); ++ int spi_nor_write_enable(struct spi_nor *nor); ++ int spi_nor_write_disable(struct spi_nor *nor); ++ int spi_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable); ++--- a/drivers/mtd/spi-nor/sst.c +++++ b/drivers/mtd/spi-nor/sst.c ++@@ -55,6 +55,10 @@ static int sst_write(struct mtd_info *mt ++ if (ret) ++ return ret; ++ +++ ret = spi_nor_check_set_addr_width(nor, to + len); +++ if (ret < 0) +++ return ret; +++ ++ ret = spi_nor_write_enable(nor); ++ if (ret) ++ goto out; ++@@ -124,6 +128,7 @@ static int sst_write(struct mtd_info *mt ++ } ++ out: ++ *retlen += actual; +++ spi_nor_check_set_addr_width(nor, 0); ++ spi_nor_unlock_and_unprep(nor); ++ return ret; ++ } +diff --git a/target/linux/generic/pending-5.10/482-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch b/target/linux/generic/pending-5.10/482-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch +new file mode 100644 +index 0000000000..c32cde559d +--- /dev/null ++++ b/target/linux/generic/pending-5.10/482-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch +@@ -0,0 +1,22 @@ ++From d68b4aa22e8c625685bfad642dd7337948dc0ad1 Mon Sep 17 00:00:00 2001 ++From: Koen Vandeputte ++Date: Mon, 6 Jan 2020 13:07:56 +0100 ++Subject: [PATCH] mtd: spi-nor: add support for Gigadevice GD25D05 ++ ++Signed-off-by: Koen Vandeputte ++--- ++ drivers/mtd/spi-nor/spi-nor.c | 5 +++++ ++ 1 file changed, 5 insertions(+) ++ ++--- a/drivers/mtd/spi-nor/gigadevice.c +++++ b/drivers/mtd/spi-nor/gigadevice.c ++@@ -24,6 +24,9 @@ static struct spi_nor_fixups gd25q256_fi ++ }; ++ ++ static const struct flash_info gigadevice_parts[] = { +++ { "gd25q05", INFO(0xc84010, 0, 64 * 1024, 1, +++ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | +++ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, ++ { "gd25q16", INFO(0xc84015, 0, 64 * 1024, 32, ++ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | ++ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, +diff --git a/target/linux/generic/pending-5.10/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch b/target/linux/generic/pending-5.10/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch +new file mode 100644 +index 0000000000..7c9766fa7b +--- /dev/null ++++ b/target/linux/generic/pending-5.10/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch +@@ -0,0 +1,97 @@ ++From: Daniel Golle ++Subject: ubi: auto-attach mtd device named "ubi" or "data" on boot ++ ++Signed-off-by: Daniel Golle ++--- ++ drivers/mtd/ubi/build.c | 36 ++++++++++++++++++++++++++++++++++++ ++ 1 file changed, 36 insertions(+) ++ ++--- a/drivers/mtd/ubi/build.c +++++ b/drivers/mtd/ubi/build.c ++@@ -1192,6 +1192,73 @@ static struct mtd_info * __init open_mtd ++ return mtd; ++ } ++ +++/* +++ * This function tries attaching mtd partitions named either "ubi" or "data" +++ * during boot. +++ */ +++static void __init ubi_auto_attach(void) +++{ +++ int err; +++ struct mtd_info *mtd; +++ loff_t offset = 0; +++ size_t len; +++ char magic[4]; +++ +++ /* try attaching mtd device named "ubi" or "data" */ +++ mtd = open_mtd_device("ubi"); +++ if (IS_ERR(mtd)) +++ mtd = open_mtd_device("data"); +++ +++ if (IS_ERR(mtd)) +++ return; +++ +++ /* get the first not bad block */ +++ if (mtd_can_have_bb(mtd)) +++ while (mtd_block_isbad(mtd, offset)) { +++ offset += mtd->erasesize; +++ +++ if (offset > mtd->size) { +++ pr_err("UBI error: Failed to find a non-bad " +++ "block on mtd%d\n", mtd->index); +++ goto cleanup; +++ } +++ } +++ +++ /* check if the read from flash was successful */ +++ err = mtd_read(mtd, offset, 4, &len, (void *) magic); +++ if ((err && !mtd_is_bitflip(err)) || len != 4) { +++ pr_err("UBI error: unable to read from mtd%d\n", mtd->index); +++ goto cleanup; +++ } +++ +++ /* check for a valid ubi magic */ +++ if (strncmp(magic, "UBI#", 4)) { +++ pr_err("UBI error: no valid UBI magic found inside mtd%d\n", mtd->index); +++ goto cleanup; +++ } +++ +++ /* don't auto-add media types where UBI doesn't makes sense */ +++ if (mtd->type != MTD_NANDFLASH && +++ mtd->type != MTD_NORFLASH && +++ mtd->type != MTD_DATAFLASH && +++ mtd->type != MTD_MLCNANDFLASH) +++ goto cleanup; +++ +++ mutex_lock(&ubi_devices_mutex); +++ pr_notice("UBI: auto-attach mtd%d\n", mtd->index); +++ err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0); +++ mutex_unlock(&ubi_devices_mutex); +++ if (err < 0) { +++ pr_err("UBI error: cannot attach mtd%d\n", mtd->index); +++ goto cleanup; +++ } +++ +++ return; +++ +++cleanup: +++ put_mtd_device(mtd); +++} +++ ++ static int __init ubi_init(void) ++ { ++ int err, i, k; ++@@ -1275,6 +1342,12 @@ static int __init ubi_init(void) ++ } ++ } ++ +++ /* auto-attach mtd devices only if built-in to the kernel and no ubi.mtd +++ * parameter was given */ +++ if (IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && +++ !ubi_is_module() && !mtd_devs) +++ ubi_auto_attach(); +++ ++ err = ubiblock_init(); ++ if (err) { ++ pr_err("UBI error: block: cannot initialize, error %d\n", err); +diff --git a/target/linux/generic/pending-5.10/491-ubi-auto-create-ubiblock-device-for-rootfs.patch b/target/linux/generic/pending-5.10/491-ubi-auto-create-ubiblock-device-for-rootfs.patch +new file mode 100644 +index 0000000000..61fcbac92e +--- /dev/null ++++ b/target/linux/generic/pending-5.10/491-ubi-auto-create-ubiblock-device-for-rootfs.patch +@@ -0,0 +1,66 @@ ++From: Daniel Golle ++Subject: ubi: auto-create ubiblock device for rootfs ++ ++Signed-off-by: Daniel Golle ++--- ++ drivers/mtd/ubi/block.c | 42 ++++++++++++++++++++++++++++++++++++++++++ ++ 1 file changed, 42 insertions(+) ++ ++--- a/drivers/mtd/ubi/block.c +++++ b/drivers/mtd/ubi/block.c ++@@ -652,6 +652,44 @@ static void __init ubiblock_create_from_ ++ } ++ } ++ +++#define UBIFS_NODE_MAGIC 0x06101831 +++static inline int ubi_vol_is_ubifs(struct ubi_volume_desc *desc) +++{ +++ int ret; +++ uint32_t magic_of, magic; +++ ret = ubi_read(desc, 0, (char *)&magic_of, 0, 4); +++ if (ret) +++ return 0; +++ magic = le32_to_cpu(magic_of); +++ return magic == UBIFS_NODE_MAGIC; +++} +++ +++static void __init ubiblock_create_auto_rootfs(void) +++{ +++ int ubi_num, ret, is_ubifs; +++ struct ubi_volume_desc *desc; +++ struct ubi_volume_info vi; +++ +++ for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++) { +++ desc = ubi_open_volume_nm(ubi_num, "rootfs", UBI_READONLY); +++ if (IS_ERR(desc)) +++ continue; +++ +++ ubi_get_volume_info(desc, &vi); +++ is_ubifs = ubi_vol_is_ubifs(desc); +++ ubi_close_volume(desc); +++ if (is_ubifs) +++ break; +++ +++ ret = ubiblock_create(&vi); +++ if (ret) +++ pr_err("UBI error: block: can't add '%s' volume, err=%d\n", +++ vi.name, ret); +++ /* always break if we get here */ +++ break; +++ } +++} +++ ++ static void ubiblock_remove_all(void) ++ { ++ struct ubiblock *next; ++@@ -684,6 +722,10 @@ int __init ubiblock_init(void) ++ */ ++ ubiblock_create_from_param(); ++ +++ /* auto-attach "rootfs" volume if existing and non-ubifs */ +++ if (IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV)) +++ ubiblock_create_auto_rootfs(); +++ ++ /* ++ * Block devices are only created upon user requests, so we ignore ++ * existing volumes. +diff --git a/target/linux/generic/pending-5.10/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch b/target/linux/generic/pending-5.10/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch +new file mode 100644 +index 0000000000..af65cbfa59 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch +@@ -0,0 +1,51 @@ ++From: Daniel Golle ++Subject: try auto-mounting ubi0:rootfs in init/do_mounts.c ++ ++Signed-off-by: Daniel Golle ++--- ++ init/do_mounts.c | 26 +++++++++++++++++++++++++- ++ 1 file changed, 25 insertions(+), 1 deletion(-) ++ ++--- a/init/do_mounts.c +++++ b/init/do_mounts.c ++@@ -474,7 +474,28 @@ retry: ++ out: ++ put_page(page); ++ } ++- +++ +++static int __init mount_ubi_rootfs(void) +++{ +++ int flags = MS_SILENT; +++ int err, tried = 0; +++ +++ while (tried < 2) { +++ err = do_mount_root("ubi0:rootfs", "ubifs", flags, \ +++ root_mount_data); +++ switch (err) { +++ case -EACCES: +++ flags |= MS_RDONLY; +++ tried++; +++ break; +++ default: +++ return err; +++ } +++ } +++ +++ return -EINVAL; +++} +++ ++ #ifdef CONFIG_ROOT_NFS ++ ++ #define NFSROOT_TIMEOUT_MIN 5 ++@@ -567,6 +588,10 @@ void __init mount_root(void) ++ return; ++ } ++ #endif +++#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV +++ if (!mount_ubi_rootfs()) +++ return; +++#endif ++ #ifdef CONFIG_BLOCK ++ { ++ int err = create_dev("/dev/root", ROOT_DEV); +diff --git a/target/linux/generic/pending-5.10/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch b/target/linux/generic/pending-5.10/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch +new file mode 100644 +index 0000000000..2dff46807e +--- /dev/null ++++ b/target/linux/generic/pending-5.10/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch +@@ -0,0 +1,34 @@ ++From: Daniel Golle ++Subject: ubi: set ROOT_DEV to ubiblock "rootfs" if unset ++ ++Signed-off-by: Daniel Golle ++--- ++ drivers/mtd/ubi/block.c | 10 ++++++++++ ++ 1 file changed, 10 insertions(+) ++ ++--- a/drivers/mtd/ubi/block.c +++++ b/drivers/mtd/ubi/block.c ++@@ -42,6 +42,7 @@ ++ #include ++ #include ++ #include +++#include ++ ++ #include "ubi-media.h" ++ #include "ubi.h" ++@@ -458,6 +459,15 @@ int ubiblock_create(struct ubi_volume_in ++ dev_info(disk_to_dev(dev->gd), "created from ubi%d:%d(%s)", ++ dev->ubi_num, dev->vol_id, vi->name); ++ mutex_unlock(&devices_mutex); +++ +++ if (!strcmp(vi->name, "rootfs") && +++ IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && +++ ROOT_DEV == 0) { +++ pr_notice("ubiblock: device ubiblock%d_%d (%s) set to be root filesystem\n", +++ dev->ubi_num, dev->vol_id, vi->name); +++ ROOT_DEV = MKDEV(gd->major, gd->first_minor); +++ } +++ ++ return 0; ++ ++ out_free_queue: +diff --git a/target/linux/generic/pending-5.10/494-mtd-ubi-add-EOF-marker-support.patch b/target/linux/generic/pending-5.10/494-mtd-ubi-add-EOF-marker-support.patch +new file mode 100644 +index 0000000000..81d32ca5a5 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/494-mtd-ubi-add-EOF-marker-support.patch +@@ -0,0 +1,60 @@ ++From: Gabor Juhos ++Subject: mtd: add EOF marker support to the UBI layer ++ ++Signed-off-by: Gabor Juhos ++--- ++ drivers/mtd/ubi/attach.c | 25 ++++++++++++++++++++++--- ++ drivers/mtd/ubi/ubi.h | 1 + ++ 2 files changed, 23 insertions(+), 3 deletions(-) ++ ++--- a/drivers/mtd/ubi/attach.c +++++ b/drivers/mtd/ubi/attach.c ++@@ -926,6 +926,13 @@ static bool vol_ignored(int vol_id) ++ #endif ++ } ++ +++static bool ec_hdr_has_eof(struct ubi_ec_hdr *ech) +++{ +++ return ech->padding1[0] == 'E' && +++ ech->padding1[1] == 'O' && +++ ech->padding1[2] == 'F'; +++} +++ ++ /** ++ * scan_peb - scan and process UBI headers of a PEB. ++ * @ubi: UBI device description object ++@@ -958,9 +965,21 @@ static int scan_peb(struct ubi_device *u ++ return 0; ++ } ++ ++- err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); ++- if (err < 0) ++- return err; +++ if (!ai->eof_found) { +++ err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); +++ if (err < 0) +++ return err; +++ +++ if (ec_hdr_has_eof(ech)) { +++ pr_notice("UBI: EOF marker found, PEBs from %d will be erased\n", +++ pnum); +++ ai->eof_found = true; +++ } +++ } +++ +++ if (ai->eof_found) +++ err = UBI_IO_FF_BITFLIPS; +++ ++ switch (err) { ++ case 0: ++ break; ++--- a/drivers/mtd/ubi/ubi.h +++++ b/drivers/mtd/ubi/ubi.h ++@@ -782,6 +782,7 @@ struct ubi_attach_info { ++ int mean_ec; ++ uint64_t ec_sum; ++ int ec_count; +++ bool eof_found; ++ struct kmem_cache *aeb_slab_cache; ++ struct ubi_ec_hdr *ech; ++ struct ubi_vid_io_buf *vidb; +diff --git a/target/linux/generic/pending-5.10/495-mtd-core-add-get_mtd_device_by_node.patch b/target/linux/generic/pending-5.10/495-mtd-core-add-get_mtd_device_by_node.patch +new file mode 100644 +index 0000000000..98c5c2ef19 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/495-mtd-core-add-get_mtd_device_by_node.patch +@@ -0,0 +1,75 @@ ++From 1bd1b740f208d1cf4071932cc51860d37266c402 Mon Sep 17 00:00:00 2001 ++From: Bernhard Frauendienst ++Date: Sat, 1 Sep 2018 00:30:11 +0200 ++Subject: [PATCH 495/497] mtd: core: add get_mtd_device_by_node ++ ++Add function to retrieve a mtd device by its OF node. Since drivers can ++assign arbitrary names to mtd devices in the absence of a label ++property, there is no other reliable way to retrieve a mtd device for a ++given OF node. ++ ++Signed-off-by: Bernhard Frauendienst ++Reviewed-by: Miquel Raynal ++--- ++ drivers/mtd/mtdcore.c | 38 ++++++++++++++++++++++++++++++++++++++ ++ include/linux/mtd/mtd.h | 2 ++ ++ 2 files changed, 40 insertions(+) ++ ++--- a/drivers/mtd/mtdcore.c +++++ b/drivers/mtd/mtdcore.c ++@@ -1052,6 +1052,44 @@ out_unlock: ++ } ++ EXPORT_SYMBOL_GPL(get_mtd_device_nm); ++ +++/** +++ * get_mtd_device_by_node - obtain a validated handle for an MTD device +++ * by of_node +++ * @of_node: OF node of MTD device to open +++ * +++ * This function returns MTD device description structure in case of +++ * success and an error code in case of failure. +++ */ +++struct mtd_info *get_mtd_device_by_node(const struct device_node *of_node) +++{ +++ int err = -ENODEV; +++ struct mtd_info *mtd = NULL, *other; +++ +++ mutex_lock(&mtd_table_mutex); +++ +++ mtd_for_each_device(other) { +++ if (of_node == other->dev.of_node) { +++ mtd = other; +++ break; +++ } +++ } +++ +++ if (!mtd) +++ goto out_unlock; +++ +++ err = __get_mtd_device(mtd); +++ if (err) +++ goto out_unlock; +++ +++ mutex_unlock(&mtd_table_mutex); +++ return mtd; +++ +++out_unlock: +++ mutex_unlock(&mtd_table_mutex); +++ return ERR_PTR(err); +++} +++EXPORT_SYMBOL_GPL(get_mtd_device_by_node); +++ ++ void put_mtd_device(struct mtd_info *mtd) ++ { ++ mutex_lock(&mtd_table_mutex); ++--- a/include/linux/mtd/mtd.h +++++ b/include/linux/mtd/mtd.h ++@@ -696,6 +696,8 @@ extern struct mtd_info *get_mtd_device(s ++ extern int __get_mtd_device(struct mtd_info *mtd); ++ extern void __put_mtd_device(struct mtd_info *mtd); ++ extern struct mtd_info *get_mtd_device_nm(const char *name); +++extern struct mtd_info *get_mtd_device_by_node( +++ const struct device_node *of_node); ++ extern void put_mtd_device(struct mtd_info *mtd); ++ ++ static inline uint64_t mtdpart_get_offset(const struct mtd_info *mtd) +diff --git a/target/linux/generic/pending-5.10/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch b/target/linux/generic/pending-5.10/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch +new file mode 100644 +index 0000000000..01f3b9ec2d +--- /dev/null ++++ b/target/linux/generic/pending-5.10/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch +@@ -0,0 +1,52 @@ ++From 5734c6669fba7ddb5ef491ccff7159d15dba0b59 Mon Sep 17 00:00:00 2001 ++From: Bernhard Frauendienst ++Date: Wed, 5 Sep 2018 01:32:51 +0200 ++Subject: [PATCH 496/497] dt-bindings: add bindings for mtd-concat devices ++ ++Document virtual mtd-concat device bindings. ++ ++Signed-off-by: Bernhard Frauendienst ++--- ++ .../devicetree/bindings/mtd/mtd-concat.txt | 36 +++++++++++++++++++ ++ 1 file changed, 36 insertions(+) ++ create mode 100644 Documentation/devicetree/bindings/mtd/mtd-concat.txt ++ ++--- /dev/null +++++ b/Documentation/devicetree/bindings/mtd/mtd-concat.txt ++@@ -0,0 +1,36 @@ +++Virtual MTD concat device +++ +++Requires properties: +++- devices: list of phandles to mtd nodes that should be concatenated +++ +++Example: +++ +++&spi { +++ flash0: flash@0 { +++ ... +++ }; +++ flash1: flash@1 { +++ ... +++ }; +++}; +++ +++flash { +++ compatible = "mtd-concat"; +++ +++ devices = <&flash0 &flash1>; +++ +++ partitions { +++ compatible = "fixed-partitions"; +++ +++ partition@0 { +++ label = "boot"; +++ reg = <0x0000000 0x0040000>; +++ read-only; +++ }; +++ +++ partition@40000 { +++ label = "firmware"; +++ reg = <0x0040000 0x1fc0000>; +++ }; +++ } +++} +diff --git a/target/linux/generic/pending-5.10/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch b/target/linux/generic/pending-5.10/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch +new file mode 100644 +index 0000000000..058cab09e5 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch +@@ -0,0 +1,216 @@ ++From e53f712d8eac71f54399b61038ccf87d2cee99d7 Mon Sep 17 00:00:00 2001 ++From: Bernhard Frauendienst ++Date: Sat, 25 Aug 2018 12:35:22 +0200 ++Subject: [PATCH 497/497] mtd: mtdconcat: add dt driver for concat devices ++ ++Some mtd drivers like physmap variants have support for concatenating ++multiple mtd devices, but there is no generic way to define such a ++concat device from within the device tree. ++ ++This is useful for some SoC boards that use multiple flash chips as ++memory banks of a single mtd device, with partitions spanning chip ++borders. ++ ++This commit adds a driver for creating virtual mtd-concat devices. They ++must have a compatible = "mtd-concat" line, and define a list of devices ++to concat in the 'devices' property, for example: ++ ++flash { ++ compatible = "mtd-concat"; ++ ++ devices = <&flash0 &flash1>; ++ ++ partitions { ++ ... ++ }; ++}; ++ ++The driver is added to the very end of the mtd Makefile to increase the ++likelyhood of all child devices already being loaded at the time of ++probing, preventing unnecessary deferred probes. ++ ++Signed-off-by: Bernhard Frauendienst ++--- ++ drivers/mtd/Kconfig | 2 + ++ drivers/mtd/Makefile | 3 + ++ drivers/mtd/composite/Kconfig | 12 +++ ++ drivers/mtd/composite/Makefile | 6 ++ ++ drivers/mtd/composite/virt_concat.c | 128 ++++++++++++++++++++++++++++ ++ 5 files changed, 151 insertions(+) ++ create mode 100644 drivers/mtd/composite/Kconfig ++ create mode 100644 drivers/mtd/composite/Makefile ++ create mode 100644 drivers/mtd/composite/virt_concat.c ++ ++--- a/drivers/mtd/Kconfig +++++ b/drivers/mtd/Kconfig ++@@ -238,4 +238,6 @@ source "drivers/mtd/ubi/Kconfig" ++ ++ source "drivers/mtd/hyperbus/Kconfig" ++ +++source "drivers/mtd/composite/Kconfig" +++ ++ endif # MTD ++--- a/drivers/mtd/Makefile +++++ b/drivers/mtd/Makefile ++@@ -33,3 +33,6 @@ obj-y += chips/ lpddr/ maps/ devices/ n ++ obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/ ++ obj-$(CONFIG_MTD_UBI) += ubi/ ++ obj-$(CONFIG_MTD_HYPERBUS) += hyperbus/ +++ +++# Composite drivers must be loaded last +++obj-y += composite/ ++--- /dev/null +++++ b/drivers/mtd/composite/Kconfig ++@@ -0,0 +1,12 @@ +++menu "Composite MTD device drivers" +++ depends on MTD!=n +++ +++config MTD_VIRT_CONCAT +++ tristate "Virtual concat MTD device" +++ help +++ This driver allows creation of a virtual MTD concat device, which +++ concatenates multiple underlying MTD devices to a single device. +++ This is required by some SoC boards where multiple memory banks are +++ used as one device with partitions spanning across device boundaries. +++ +++endmenu ++--- /dev/null +++++ b/drivers/mtd/composite/Makefile ++@@ -0,0 +1,6 @@ +++# SPDX-License-Identifier: GPL-2.0 +++# +++# linux/drivers/mtd/composite/Makefile +++# +++ +++obj-$(CONFIG_MTD_VIRT_CONCAT) += virt_concat.o ++--- /dev/null +++++ b/drivers/mtd/composite/virt_concat.c ++@@ -0,0 +1,128 @@ +++// SPDX-License-Identifier: GPL-2.0+ +++/* +++ * Virtual concat MTD device driver +++ * +++ * Copyright (C) 2018 Bernhard Frauendienst +++ * Author: Bernhard Frauendienst, kernel@nospam.obeliks.de +++ */ +++ +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++ +++/* +++ * struct of_virt_concat - platform device driver data. +++ * @cmtd the final mtd_concat device +++ * @num_devices the number of devices in @devices +++ * @devices points to an array of devices already loaded +++ */ +++struct of_virt_concat { +++ struct mtd_info *cmtd; +++ int num_devices; +++ struct mtd_info **devices; +++}; +++ +++static int virt_concat_remove(struct platform_device *pdev) +++{ +++ struct of_virt_concat *info; +++ int i; +++ +++ info = platform_get_drvdata(pdev); +++ if (!info) +++ return 0; +++ +++ // unset data for when this is called after a probe error +++ platform_set_drvdata(pdev, NULL); +++ +++ if (info->cmtd) { +++ mtd_device_unregister(info->cmtd); +++ mtd_concat_destroy(info->cmtd); +++ } +++ +++ if (info->devices) { +++ for (i = 0; i < info->num_devices; i++) +++ put_mtd_device(info->devices[i]); +++ } +++ +++ return 0; +++} +++ +++static int virt_concat_probe(struct platform_device *pdev) +++{ +++ struct device_node *node = pdev->dev.of_node; +++ struct of_phandle_iterator it; +++ struct of_virt_concat *info; +++ struct mtd_info *mtd; +++ int err = 0, count; +++ +++ count = of_count_phandle_with_args(node, "devices", NULL); +++ if (count <= 0) +++ return -EINVAL; +++ +++ info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); +++ if (!info) +++ return -ENOMEM; +++ info->devices = devm_kcalloc(&pdev->dev, count, +++ sizeof(*(info->devices)), GFP_KERNEL); +++ if (!info->devices) { +++ err = -ENOMEM; +++ goto err_remove; +++ } +++ +++ platform_set_drvdata(pdev, info); +++ +++ of_for_each_phandle(&it, err, node, "devices", NULL, 0) { +++ mtd = get_mtd_device_by_node(it.node); +++ if (IS_ERR(mtd)) { +++ of_node_put(it.node); +++ err = -EPROBE_DEFER; +++ goto err_remove; +++ } +++ +++ info->devices[info->num_devices++] = mtd; +++ } +++ +++ info->cmtd = mtd_concat_create(info->devices, info->num_devices, +++ dev_name(&pdev->dev)); +++ if (!info->cmtd) { +++ err = -ENXIO; +++ goto err_remove; +++ } +++ +++ info->cmtd->dev.parent = &pdev->dev; +++ mtd_set_of_node(info->cmtd, node); +++ mtd_device_register(info->cmtd, NULL, 0); +++ +++ return 0; +++ +++err_remove: +++ virt_concat_remove(pdev); +++ +++ return err; +++} +++ +++static const struct of_device_id virt_concat_of_match[] = { +++ { .compatible = "mtd-concat", }, +++ { /* sentinel */ } +++}; +++MODULE_DEVICE_TABLE(of, virt_concat_of_match); +++ +++static struct platform_driver virt_concat_driver = { +++ .probe = virt_concat_probe, +++ .remove = virt_concat_remove, +++ .driver = { +++ .name = "virt-mtdconcat", +++ .of_match_table = virt_concat_of_match, +++ }, +++}; +++ +++module_platform_driver(virt_concat_driver); +++ +++MODULE_LICENSE("GPL v2"); +++MODULE_AUTHOR("Bernhard Frauendienst "); +++MODULE_DESCRIPTION("Virtual concat MTD device driver"); +diff --git a/target/linux/generic/pending-5.10/498-mtd-mtdconcat-select-readwrite-function.patch b/target/linux/generic/pending-5.10/498-mtd-mtdconcat-select-readwrite-function.patch +new file mode 100644 +index 0000000000..9aad0f3e6c +--- /dev/null ++++ b/target/linux/generic/pending-5.10/498-mtd-mtdconcat-select-readwrite-function.patch +@@ -0,0 +1,24 @@ ++--- a/drivers/mtd/mtdconcat.c +++++ b/drivers/mtd/mtdconcat.c ++@@ -683,8 +683,12 @@ struct mtd_info *mtd_concat_create(struc ++ concat->mtd._writev = concat_writev; ++ if (subdev[0]->_read_oob) ++ concat->mtd._read_oob = concat_read_oob; +++ else +++ concat->mtd._read = concat_read; ++ if (subdev[0]->_write_oob) ++ concat->mtd._write_oob = concat_write_oob; +++ else +++ concat->mtd._write = concat_write; ++ if (subdev[0]->_block_isbad) ++ concat->mtd._block_isbad = concat_block_isbad; ++ if (subdev[0]->_block_markbad) ++@@ -744,8 +748,6 @@ struct mtd_info *mtd_concat_create(struc ++ concat->mtd.name = name; ++ ++ concat->mtd._erase = concat_erase; ++- concat->mtd._read = concat_read; ++- concat->mtd._write = concat_write; ++ concat->mtd._sync = concat_sync; ++ concat->mtd._lock = concat_lock; ++ concat->mtd._unlock = concat_unlock; +diff --git a/target/linux/generic/pending-5.10/500-fs_cdrom_dependencies.patch b/target/linux/generic/pending-5.10/500-fs_cdrom_dependencies.patch +new file mode 100644 +index 0000000000..0a5a3aae5d +--- /dev/null ++++ b/target/linux/generic/pending-5.10/500-fs_cdrom_dependencies.patch +@@ -0,0 +1,40 @@ ++--- a/fs/hfs/Kconfig +++++ b/fs/hfs/Kconfig ++@@ -2,6 +2,7 @@ ++ config HFS_FS ++ tristate "Apple Macintosh file system support" ++ depends on BLOCK +++ select CDROM ++ select NLS ++ help ++ If you say Y here, you will be able to mount Macintosh-formatted ++--- a/fs/hfsplus/Kconfig +++++ b/fs/hfsplus/Kconfig ++@@ -2,6 +2,7 @@ ++ config HFSPLUS_FS ++ tristate "Apple Extended HFS file system support" ++ depends on BLOCK +++ select CDROM ++ select NLS ++ select NLS_UTF8 ++ help ++--- a/fs/isofs/Kconfig +++++ b/fs/isofs/Kconfig ++@@ -1,6 +1,7 @@ ++ # SPDX-License-Identifier: GPL-2.0-only ++ config ISO9660_FS ++ tristate "ISO 9660 CDROM file system support" +++ select CDROM ++ help ++ This is the standard file system used on CD-ROMs. It was previously ++ known as "High Sierra File System" and is called "hsfs" on other ++--- a/fs/udf/Kconfig +++++ b/fs/udf/Kconfig ++@@ -1,6 +1,7 @@ ++ # SPDX-License-Identifier: GPL-2.0-only ++ config UDF_FS ++ tristate "UDF file system support" +++ select CDROM ++ select CRC_ITU_T ++ select NLS ++ help +diff --git a/target/linux/generic/pending-5.10/530-jffs2_make_lzma_available.patch b/target/linux/generic/pending-5.10/530-jffs2_make_lzma_available.patch +new file mode 100644 +index 0000000000..1bccb30a69 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/530-jffs2_make_lzma_available.patch +@@ -0,0 +1,5180 @@ ++From: Alexandros C. Couloumbis ++Subject: fs: add jffs2/lzma support (not activated by default yet) ++ ++lede-commit: c2c88d315fa0e881f8b19da07b62859b915b11b2 ++Signed-off-by: Alexandros C. Couloumbis ++--- ++ fs/jffs2/Kconfig | 9 + ++ fs/jffs2/Makefile | 3 + ++ fs/jffs2/compr.c | 6 + ++ fs/jffs2/compr.h | 10 +- ++ fs/jffs2/compr_lzma.c | 128 +++ ++ fs/jffs2/super.c | 33 +- ++ include/linux/lzma.h | 62 ++ ++ include/linux/lzma/LzFind.h | 115 +++ ++ include/linux/lzma/LzHash.h | 54 + ++ include/linux/lzma/LzmaDec.h | 231 +++++ ++ include/linux/lzma/LzmaEnc.h | 80 ++ ++ include/linux/lzma/Types.h | 226 +++++ ++ include/uapi/linux/jffs2.h | 1 + ++ lib/Kconfig | 6 + ++ lib/Makefile | 12 + ++ lib/lzma/LzFind.c | 761 ++++++++++++++ ++ lib/lzma/LzmaDec.c | 999 +++++++++++++++++++ ++ lib/lzma/LzmaEnc.c | 2271 ++++++++++++++++++++++++++++++++++++++++++ ++ lib/lzma/Makefile | 7 + ++ 19 files changed, 5008 insertions(+), 6 deletions(-) ++ create mode 100644 fs/jffs2/compr_lzma.c ++ create mode 100644 include/linux/lzma.h ++ create mode 100644 include/linux/lzma/LzFind.h ++ create mode 100644 include/linux/lzma/LzHash.h ++ create mode 100644 include/linux/lzma/LzmaDec.h ++ create mode 100644 include/linux/lzma/LzmaEnc.h ++ create mode 100644 include/linux/lzma/Types.h ++ create mode 100644 lib/lzma/LzFind.c ++ create mode 100644 lib/lzma/LzmaDec.c ++ create mode 100644 lib/lzma/LzmaEnc.c ++ create mode 100644 lib/lzma/Makefile ++ ++--- a/fs/jffs2/Kconfig +++++ b/fs/jffs2/Kconfig ++@@ -136,6 +136,15 @@ config JFFS2_LZO ++ This feature was added in July, 2007. Say 'N' if you need ++ compatibility with older bootloaders or kernels. ++ +++config JFFS2_LZMA +++ bool "JFFS2 LZMA compression support" if JFFS2_COMPRESSION_OPTIONS +++ select LZMA_COMPRESS +++ select LZMA_DECOMPRESS +++ depends on JFFS2_FS +++ default n +++ help +++ JFFS2 wrapper to the LZMA C SDK +++ ++ config JFFS2_RTIME ++ bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS ++ depends on JFFS2_FS ++--- a/fs/jffs2/Makefile +++++ b/fs/jffs2/Makefile ++@@ -19,4 +19,7 @@ jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rub ++ jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o ++ jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o ++ jffs2-$(CONFIG_JFFS2_LZO) += compr_lzo.o +++jffs2-$(CONFIG_JFFS2_LZMA) += compr_lzma.o ++ jffs2-$(CONFIG_JFFS2_SUMMARY) += summary.o +++ +++CFLAGS_compr_lzma.o += -Iinclude/linux -Ilib/lzma ++--- a/fs/jffs2/compr.c +++++ b/fs/jffs2/compr.c ++@@ -378,6 +378,9 @@ int __init jffs2_compressors_init(void) ++ #ifdef CONFIG_JFFS2_LZO ++ jffs2_lzo_init(); ++ #endif +++#ifdef CONFIG_JFFS2_LZMA +++ jffs2_lzma_init(); +++#endif ++ /* Setting default compression mode */ ++ #ifdef CONFIG_JFFS2_CMODE_NONE ++ jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; ++@@ -401,6 +404,9 @@ int __init jffs2_compressors_init(void) ++ int jffs2_compressors_exit(void) ++ { ++ /* Unregistering compressors */ +++#ifdef CONFIG_JFFS2_LZMA +++ jffs2_lzma_exit(); +++#endif ++ #ifdef CONFIG_JFFS2_LZO ++ jffs2_lzo_exit(); ++ #endif ++--- a/fs/jffs2/compr.h +++++ b/fs/jffs2/compr.h ++@@ -29,9 +29,9 @@ ++ #define JFFS2_DYNRUBIN_PRIORITY 20 ++ #define JFFS2_LZARI_PRIORITY 30 ++ #define JFFS2_RTIME_PRIORITY 50 ++-#define JFFS2_ZLIB_PRIORITY 60 ++-#define JFFS2_LZO_PRIORITY 80 ++- +++#define JFFS2_LZMA_PRIORITY 70 +++#define JFFS2_ZLIB_PRIORITY 80 +++#define JFFS2_LZO_PRIORITY 90 ++ ++ #define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */ ++ #define JFFS2_DYNRUBIN_DISABLED /* for decompression */ ++@@ -101,5 +101,9 @@ void jffs2_zlib_exit(void); ++ int jffs2_lzo_init(void); ++ void jffs2_lzo_exit(void); ++ #endif +++#ifdef CONFIG_JFFS2_LZMA +++int jffs2_lzma_init(void); +++void jffs2_lzma_exit(void); +++#endif ++ ++ #endif /* __JFFS2_COMPR_H__ */ ++--- /dev/null +++++ b/fs/jffs2/compr_lzma.c ++@@ -0,0 +1,128 @@ +++/* +++ * JFFS2 -- Journalling Flash File System, Version 2. +++ * +++ * For licensing information, see the file 'LICENCE' in this directory. +++ * +++ * JFFS2 wrapper to the LZMA C SDK +++ * +++ */ +++ +++#include +++#include "compr.h" +++ +++#ifdef __KERNEL__ +++ static DEFINE_MUTEX(deflate_mutex); +++#endif +++ +++CLzmaEncHandle *p; +++Byte propsEncoded[LZMA_PROPS_SIZE]; +++SizeT propsSize = sizeof(propsEncoded); +++ +++STATIC void lzma_free_workspace(void) +++{ +++ LzmaEnc_Destroy(p, &lzma_alloc, &lzma_alloc); +++} +++ +++STATIC int INIT lzma_alloc_workspace(CLzmaEncProps *props) +++{ +++ if ((p = (CLzmaEncHandle *)LzmaEnc_Create(&lzma_alloc)) == NULL) +++ { +++ PRINT_ERROR("Failed to allocate lzma deflate workspace\n"); +++ return -ENOMEM; +++ } +++ +++ if (LzmaEnc_SetProps(p, props) != SZ_OK) +++ { +++ lzma_free_workspace(); +++ return -1; +++ } +++ +++ if (LzmaEnc_WriteProperties(p, propsEncoded, &propsSize) != SZ_OK) +++ { +++ lzma_free_workspace(); +++ return -1; +++ } +++ +++ return 0; +++} +++ +++STATIC int jffs2_lzma_compress(unsigned char *data_in, unsigned char *cpage_out, +++ uint32_t *sourcelen, uint32_t *dstlen) +++{ +++ SizeT compress_size = (SizeT)(*dstlen); +++ int ret; +++ +++ #ifdef __KERNEL__ +++ mutex_lock(&deflate_mutex); +++ #endif +++ +++ ret = LzmaEnc_MemEncode(p, cpage_out, &compress_size, data_in, *sourcelen, +++ 0, NULL, &lzma_alloc, &lzma_alloc); +++ +++ #ifdef __KERNEL__ +++ mutex_unlock(&deflate_mutex); +++ #endif +++ +++ if (ret != SZ_OK) +++ return -1; +++ +++ *dstlen = (uint32_t)compress_size; +++ +++ return 0; +++} +++ +++STATIC int jffs2_lzma_decompress(unsigned char *data_in, unsigned char *cpage_out, +++ uint32_t srclen, uint32_t destlen) +++{ +++ int ret; +++ SizeT dl = (SizeT)destlen; +++ SizeT sl = (SizeT)srclen; +++ ELzmaStatus status; +++ +++ ret = LzmaDecode(cpage_out, &dl, data_in, &sl, propsEncoded, +++ propsSize, LZMA_FINISH_ANY, &status, &lzma_alloc); +++ +++ if (ret != SZ_OK || status == LZMA_STATUS_NOT_FINISHED || dl != (SizeT)destlen) +++ return -1; +++ +++ return 0; +++} +++ +++static struct jffs2_compressor jffs2_lzma_comp = { +++ .priority = JFFS2_LZMA_PRIORITY, +++ .name = "lzma", +++ .compr = JFFS2_COMPR_LZMA, +++ .compress = &jffs2_lzma_compress, +++ .decompress = &jffs2_lzma_decompress, +++ .disabled = 0, +++}; +++ +++int INIT jffs2_lzma_init(void) +++{ +++ int ret; +++ CLzmaEncProps props; +++ LzmaEncProps_Init(&props); +++ +++ props.dictSize = LZMA_BEST_DICT(0x2000); +++ props.level = LZMA_BEST_LEVEL; +++ props.lc = LZMA_BEST_LC; +++ props.lp = LZMA_BEST_LP; +++ props.pb = LZMA_BEST_PB; +++ props.fb = LZMA_BEST_FB; +++ +++ ret = lzma_alloc_workspace(&props); +++ if (ret < 0) +++ return ret; +++ +++ ret = jffs2_register_compressor(&jffs2_lzma_comp); +++ if (ret) +++ lzma_free_workspace(); +++ +++ return ret; +++} +++ +++void jffs2_lzma_exit(void) +++{ +++ jffs2_unregister_compressor(&jffs2_lzma_comp); +++ lzma_free_workspace(); +++} ++--- a/fs/jffs2/super.c +++++ b/fs/jffs2/super.c ++@@ -374,14 +374,41 @@ static int __init init_jffs2_fs(void) ++ BUILD_BUG_ON(sizeof(struct jffs2_raw_inode) != 68); ++ BUILD_BUG_ON(sizeof(struct jffs2_raw_summary) != 32); ++ ++- pr_info("version 2.2." +++ pr_info("version 2.2" ++ #ifdef CONFIG_JFFS2_FS_WRITEBUFFER ++ " (NAND)" ++ #endif ++ #ifdef CONFIG_JFFS2_SUMMARY ++- " (SUMMARY) " +++ " (SUMMARY)" ++ #endif ++- " © 2001-2006 Red Hat, Inc.\n"); +++#ifdef CONFIG_JFFS2_ZLIB +++ " (ZLIB)" +++#endif +++#ifdef CONFIG_JFFS2_LZO +++ " (LZO)" +++#endif +++#ifdef CONFIG_JFFS2_LZMA +++ " (LZMA)" +++#endif +++#ifdef CONFIG_JFFS2_RTIME +++ " (RTIME)" +++#endif +++#ifdef CONFIG_JFFS2_RUBIN +++ " (RUBIN)" +++#endif +++#ifdef CONFIG_JFFS2_CMODE_NONE +++ " (CMODE_NONE)" +++#endif +++#ifdef CONFIG_JFFS2_CMODE_PRIORITY +++ " (CMODE_PRIORITY)" +++#endif +++#ifdef CONFIG_JFFS2_CMODE_SIZE +++ " (CMODE_SIZE)" +++#endif +++#ifdef CONFIG_JFFS2_CMODE_FAVOURLZO +++ " (CMODE_FAVOURLZO)" +++#endif +++ " (c) 2001-2006 Red Hat, Inc.\n"); ++ ++ jffs2_inode_cachep = kmem_cache_create("jffs2_i", ++ sizeof(struct jffs2_inode_info), ++--- /dev/null +++++ b/include/linux/lzma.h ++@@ -0,0 +1,62 @@ +++#ifndef __LZMA_H__ +++#define __LZMA_H__ +++ +++#ifdef __KERNEL__ +++ #include +++ #include +++ #include +++ #include +++ #include +++ #define LZMA_MALLOC vmalloc +++ #define LZMA_FREE vfree +++ #define PRINT_ERROR(msg) printk(KERN_WARNING #msg) +++ #define INIT __init +++ #define STATIC static +++#else +++ #include +++ #include +++ #include +++ #include +++ #include +++ #include +++ #include +++ #include +++ #ifndef PAGE_SIZE +++ extern int page_size; +++ #define PAGE_SIZE page_size +++ #endif +++ #define LZMA_MALLOC malloc +++ #define LZMA_FREE free +++ #define PRINT_ERROR(msg) fprintf(stderr, msg) +++ #define INIT +++ #define STATIC +++#endif +++ +++#include "lzma/LzmaDec.h" +++#include "lzma/LzmaEnc.h" +++ +++#define LZMA_BEST_LEVEL (9) +++#define LZMA_BEST_LC (0) +++#define LZMA_BEST_LP (0) +++#define LZMA_BEST_PB (0) +++#define LZMA_BEST_FB (273) +++ +++#define LZMA_BEST_DICT(n) (((int)((n) / 2)) * 2) +++ +++static void *p_lzma_malloc(void *p, size_t size) +++{ +++ if (size == 0) +++ return NULL; +++ +++ return LZMA_MALLOC(size); +++} +++ +++static void p_lzma_free(void *p, void *address) +++{ +++ if (address != NULL) +++ LZMA_FREE(address); +++} +++ +++static ISzAlloc lzma_alloc = {p_lzma_malloc, p_lzma_free}; +++ +++#endif ++--- /dev/null +++++ b/include/linux/lzma/LzFind.h ++@@ -0,0 +1,115 @@ +++/* LzFind.h -- Match finder for LZ algorithms +++2009-04-22 : Igor Pavlov : Public domain */ +++ +++#ifndef __LZ_FIND_H +++#define __LZ_FIND_H +++ +++#include "Types.h" +++ +++#ifdef __cplusplus +++extern "C" { +++#endif +++ +++typedef UInt32 CLzRef; +++ +++typedef struct _CMatchFinder +++{ +++ Byte *buffer; +++ UInt32 pos; +++ UInt32 posLimit; +++ UInt32 streamPos; +++ UInt32 lenLimit; +++ +++ UInt32 cyclicBufferPos; +++ UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ +++ +++ UInt32 matchMaxLen; +++ CLzRef *hash; +++ CLzRef *son; +++ UInt32 hashMask; +++ UInt32 cutValue; +++ +++ Byte *bufferBase; +++ ISeqInStream *stream; +++ int streamEndWasReached; +++ +++ UInt32 blockSize; +++ UInt32 keepSizeBefore; +++ UInt32 keepSizeAfter; +++ +++ UInt32 numHashBytes; +++ int directInput; +++ size_t directInputRem; +++ int btMode; +++ int bigHash; +++ UInt32 historySize; +++ UInt32 fixedHashSize; +++ UInt32 hashSizeSum; +++ UInt32 numSons; +++ SRes result; +++ UInt32 crc[256]; +++} CMatchFinder; +++ +++#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) +++#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)]) +++ +++#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) +++ +++int MatchFinder_NeedMove(CMatchFinder *p); +++Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); +++void MatchFinder_MoveBlock(CMatchFinder *p); +++void MatchFinder_ReadIfRequired(CMatchFinder *p); +++ +++void MatchFinder_Construct(CMatchFinder *p); +++ +++/* Conditions: +++ historySize <= 3 GB +++ keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB +++*/ +++int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, +++ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, +++ ISzAlloc *alloc); +++void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); +++void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems); +++void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); +++ +++UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, +++ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, +++ UInt32 *distances, UInt32 maxLen); +++ +++/* +++Conditions: +++ Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func. +++ Mf_GetPointerToCurrentPos_Func's result must be used only before any other function +++*/ +++ +++typedef void (*Mf_Init_Func)(void *object); +++typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index); +++typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object); +++typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); +++typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances); +++typedef void (*Mf_Skip_Func)(void *object, UInt32); +++ +++typedef struct _IMatchFinder +++{ +++ Mf_Init_Func Init; +++ Mf_GetIndexByte_Func GetIndexByte; +++ Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; +++ Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos; +++ Mf_GetMatches_Func GetMatches; +++ Mf_Skip_Func Skip; +++} IMatchFinder; +++ +++void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); +++ +++void MatchFinder_Init(CMatchFinder *p); +++UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); +++UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); +++void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); +++void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); +++ +++#ifdef __cplusplus +++} +++#endif +++ +++#endif ++--- /dev/null +++++ b/include/linux/lzma/LzHash.h ++@@ -0,0 +1,54 @@ +++/* LzHash.h -- HASH functions for LZ algorithms +++2009-02-07 : Igor Pavlov : Public domain */ +++ +++#ifndef __LZ_HASH_H +++#define __LZ_HASH_H +++ +++#define kHash2Size (1 << 10) +++#define kHash3Size (1 << 16) +++#define kHash4Size (1 << 20) +++ +++#define kFix3HashSize (kHash2Size) +++#define kFix4HashSize (kHash2Size + kHash3Size) +++#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) +++ +++#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8); +++ +++#define HASH3_CALC { \ +++ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ +++ hash2Value = temp & (kHash2Size - 1); \ +++ hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } +++ +++#define HASH4_CALC { \ +++ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ +++ hash2Value = temp & (kHash2Size - 1); \ +++ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ +++ hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; } +++ +++#define HASH5_CALC { \ +++ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ +++ hash2Value = temp & (kHash2Size - 1); \ +++ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ +++ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \ +++ hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \ +++ hash4Value &= (kHash4Size - 1); } +++ +++/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ +++#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; +++ +++ +++#define MT_HASH2_CALC \ +++ hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); +++ +++#define MT_HASH3_CALC { \ +++ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ +++ hash2Value = temp & (kHash2Size - 1); \ +++ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } +++ +++#define MT_HASH4_CALC { \ +++ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ +++ hash2Value = temp & (kHash2Size - 1); \ +++ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ +++ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } +++ +++#endif ++--- /dev/null +++++ b/include/linux/lzma/LzmaDec.h ++@@ -0,0 +1,231 @@ +++/* LzmaDec.h -- LZMA Decoder +++2009-02-07 : Igor Pavlov : Public domain */ +++ +++#ifndef __LZMA_DEC_H +++#define __LZMA_DEC_H +++ +++#include "Types.h" +++ +++#ifdef __cplusplus +++extern "C" { +++#endif +++ +++/* #define _LZMA_PROB32 */ +++/* _LZMA_PROB32 can increase the speed on some CPUs, +++ but memory usage for CLzmaDec::probs will be doubled in that case */ +++ +++#ifdef _LZMA_PROB32 +++#define CLzmaProb UInt32 +++#else +++#define CLzmaProb UInt16 +++#endif +++ +++ +++/* ---------- LZMA Properties ---------- */ +++ +++#define LZMA_PROPS_SIZE 5 +++ +++typedef struct _CLzmaProps +++{ +++ unsigned lc, lp, pb; +++ UInt32 dicSize; +++} CLzmaProps; +++ +++/* LzmaProps_Decode - decodes properties +++Returns: +++ SZ_OK +++ SZ_ERROR_UNSUPPORTED - Unsupported properties +++*/ +++ +++SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); +++ +++ +++/* ---------- LZMA Decoder state ---------- */ +++ +++/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. +++ Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ +++ +++#define LZMA_REQUIRED_INPUT_MAX 20 +++ +++typedef struct +++{ +++ CLzmaProps prop; +++ CLzmaProb *probs; +++ Byte *dic; +++ const Byte *buf; +++ UInt32 range, code; +++ SizeT dicPos; +++ SizeT dicBufSize; +++ UInt32 processedPos; +++ UInt32 checkDicSize; +++ unsigned state; +++ UInt32 reps[4]; +++ unsigned remainLen; +++ int needFlush; +++ int needInitState; +++ UInt32 numProbs; +++ unsigned tempBufSize; +++ Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; +++} CLzmaDec; +++ +++#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } +++ +++void LzmaDec_Init(CLzmaDec *p); +++ +++/* There are two types of LZMA streams: +++ 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. +++ 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ +++ +++typedef enum +++{ +++ LZMA_FINISH_ANY, /* finish at any point */ +++ LZMA_FINISH_END /* block must be finished at the end */ +++} ELzmaFinishMode; +++ +++/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! +++ +++ You must use LZMA_FINISH_END, when you know that current output buffer +++ covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. +++ +++ If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, +++ and output value of destLen will be less than output buffer size limit. +++ You can check status result also. +++ +++ You can use multiple checks to test data integrity after full decompression: +++ 1) Check Result and "status" variable. +++ 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. +++ 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. +++ You must use correct finish mode in that case. */ +++ +++typedef enum +++{ +++ LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ +++ LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ +++ LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ +++ LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ +++ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ +++} ELzmaStatus; +++ +++/* ELzmaStatus is used only as output value for function call */ +++ +++ +++/* ---------- Interfaces ---------- */ +++ +++/* There are 3 levels of interfaces: +++ 1) Dictionary Interface +++ 2) Buffer Interface +++ 3) One Call Interface +++ You can select any of these interfaces, but don't mix functions from different +++ groups for same object. */ +++ +++ +++/* There are two variants to allocate state for Dictionary Interface: +++ 1) LzmaDec_Allocate / LzmaDec_Free +++ 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs +++ You can use variant 2, if you set dictionary buffer manually. +++ For Buffer Interface you must always use variant 1. +++ +++LzmaDec_Allocate* can return: +++ SZ_OK +++ SZ_ERROR_MEM - Memory allocation error +++ SZ_ERROR_UNSUPPORTED - Unsupported properties +++*/ +++ +++SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); +++void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); +++ +++SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); +++void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); +++ +++/* ---------- Dictionary Interface ---------- */ +++ +++/* You can use it, if you want to eliminate the overhead for data copying from +++ dictionary to some other external buffer. +++ You must work with CLzmaDec variables directly in this interface. +++ +++ STEPS: +++ LzmaDec_Constr() +++ LzmaDec_Allocate() +++ for (each new stream) +++ { +++ LzmaDec_Init() +++ while (it needs more decompression) +++ { +++ LzmaDec_DecodeToDic() +++ use data from CLzmaDec::dic and update CLzmaDec::dicPos +++ } +++ } +++ LzmaDec_Free() +++*/ +++ +++/* LzmaDec_DecodeToDic +++ +++ The decoding to internal dictionary buffer (CLzmaDec::dic). +++ You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! +++ +++finishMode: +++ It has meaning only if the decoding reaches output limit (dicLimit). +++ LZMA_FINISH_ANY - Decode just dicLimit bytes. +++ LZMA_FINISH_END - Stream must be finished after dicLimit. +++ +++Returns: +++ SZ_OK +++ status: +++ LZMA_STATUS_FINISHED_WITH_MARK +++ LZMA_STATUS_NOT_FINISHED +++ LZMA_STATUS_NEEDS_MORE_INPUT +++ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK +++ SZ_ERROR_DATA - Data error +++*/ +++ +++SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, +++ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); +++ +++ +++/* ---------- Buffer Interface ---------- */ +++ +++/* It's zlib-like interface. +++ See LzmaDec_DecodeToDic description for information about STEPS and return results, +++ but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need +++ to work with CLzmaDec variables manually. +++ +++finishMode: +++ It has meaning only if the decoding reaches output limit (*destLen). +++ LZMA_FINISH_ANY - Decode just destLen bytes. +++ LZMA_FINISH_END - Stream must be finished after (*destLen). +++*/ +++ +++SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, +++ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); +++ +++ +++/* ---------- One Call Interface ---------- */ +++ +++/* LzmaDecode +++ +++finishMode: +++ It has meaning only if the decoding reaches output limit (*destLen). +++ LZMA_FINISH_ANY - Decode just destLen bytes. +++ LZMA_FINISH_END - Stream must be finished after (*destLen). +++ +++Returns: +++ SZ_OK +++ status: +++ LZMA_STATUS_FINISHED_WITH_MARK +++ LZMA_STATUS_NOT_FINISHED +++ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK +++ SZ_ERROR_DATA - Data error +++ SZ_ERROR_MEM - Memory allocation error +++ SZ_ERROR_UNSUPPORTED - Unsupported properties +++ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). +++*/ +++ +++SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, +++ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, +++ ELzmaStatus *status, ISzAlloc *alloc); +++ +++#ifdef __cplusplus +++} +++#endif +++ +++#endif ++--- /dev/null +++++ b/include/linux/lzma/LzmaEnc.h ++@@ -0,0 +1,80 @@ +++/* LzmaEnc.h -- LZMA Encoder +++2009-02-07 : Igor Pavlov : Public domain */ +++ +++#ifndef __LZMA_ENC_H +++#define __LZMA_ENC_H +++ +++#include "Types.h" +++ +++#ifdef __cplusplus +++extern "C" { +++#endif +++ +++#define LZMA_PROPS_SIZE 5 +++ +++typedef struct _CLzmaEncProps +++{ +++ int level; /* 0 <= level <= 9 */ +++ UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version +++ (1 << 12) <= dictSize <= (1 << 30) for 64-bit version +++ default = (1 << 24) */ +++ int lc; /* 0 <= lc <= 8, default = 3 */ +++ int lp; /* 0 <= lp <= 4, default = 0 */ +++ int pb; /* 0 <= pb <= 4, default = 2 */ +++ int algo; /* 0 - fast, 1 - normal, default = 1 */ +++ int fb; /* 5 <= fb <= 273, default = 32 */ +++ int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ +++ int numHashBytes; /* 2, 3 or 4, default = 4 */ +++ UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ +++ unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ +++ int numThreads; /* 1 or 2, default = 2 */ +++} CLzmaEncProps; +++ +++void LzmaEncProps_Init(CLzmaEncProps *p); +++void LzmaEncProps_Normalize(CLzmaEncProps *p); +++UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); +++ +++ +++/* ---------- CLzmaEncHandle Interface ---------- */ +++ +++/* LzmaEnc_* functions can return the following exit codes: +++Returns: +++ SZ_OK - OK +++ SZ_ERROR_MEM - Memory allocation error +++ SZ_ERROR_PARAM - Incorrect paramater in props +++ SZ_ERROR_WRITE - Write callback error. +++ SZ_ERROR_PROGRESS - some break from progress callback +++ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) +++*/ +++ +++typedef void * CLzmaEncHandle; +++ +++CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc); +++void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); +++SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); +++SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); +++SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, +++ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); +++SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, +++ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); +++ +++/* ---------- One Call Interface ---------- */ +++ +++/* LzmaEncode +++Return code: +++ SZ_OK - OK +++ SZ_ERROR_MEM - Memory allocation error +++ SZ_ERROR_PARAM - Incorrect paramater +++ SZ_ERROR_OUTPUT_EOF - output buffer overflow +++ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) +++*/ +++ +++SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, +++ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, +++ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); +++ +++#ifdef __cplusplus +++} +++#endif +++ +++#endif ++--- /dev/null +++++ b/include/linux/lzma/Types.h ++@@ -0,0 +1,226 @@ +++/* Types.h -- Basic types +++2009-11-23 : Igor Pavlov : Public domain */ +++ +++#ifndef __7Z_TYPES_H +++#define __7Z_TYPES_H +++ +++#include +++ +++#ifdef _WIN32 +++#include +++#endif +++ +++#ifndef EXTERN_C_BEGIN +++#ifdef __cplusplus +++#define EXTERN_C_BEGIN extern "C" { +++#define EXTERN_C_END } +++#else +++#define EXTERN_C_BEGIN +++#define EXTERN_C_END +++#endif +++#endif +++ +++EXTERN_C_BEGIN +++ +++#define SZ_OK 0 +++ +++#define SZ_ERROR_DATA 1 +++#define SZ_ERROR_MEM 2 +++#define SZ_ERROR_CRC 3 +++#define SZ_ERROR_UNSUPPORTED 4 +++#define SZ_ERROR_PARAM 5 +++#define SZ_ERROR_INPUT_EOF 6 +++#define SZ_ERROR_OUTPUT_EOF 7 +++#define SZ_ERROR_READ 8 +++#define SZ_ERROR_WRITE 9 +++#define SZ_ERROR_PROGRESS 10 +++#define SZ_ERROR_FAIL 11 +++#define SZ_ERROR_THREAD 12 +++ +++#define SZ_ERROR_ARCHIVE 16 +++#define SZ_ERROR_NO_ARCHIVE 17 +++ +++typedef int SRes; +++ +++#ifdef _WIN32 +++typedef DWORD WRes; +++#else +++typedef int WRes; +++#endif +++ +++#ifndef RINOK +++#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } +++#endif +++ +++typedef unsigned char Byte; +++typedef short Int16; +++typedef unsigned short UInt16; +++ +++#ifdef _LZMA_UINT32_IS_ULONG +++typedef long Int32; +++typedef unsigned long UInt32; +++#else +++typedef int Int32; +++typedef unsigned int UInt32; +++#endif +++ +++#ifdef _SZ_NO_INT_64 +++ +++/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. +++ NOTES: Some code will work incorrectly in that case! */ +++ +++typedef long Int64; +++typedef unsigned long UInt64; +++ +++#else +++ +++#if defined(_MSC_VER) || defined(__BORLANDC__) +++typedef __int64 Int64; +++typedef unsigned __int64 UInt64; +++#else +++typedef long long int Int64; +++typedef unsigned long long int UInt64; +++#endif +++ +++#endif +++ +++#ifdef _LZMA_NO_SYSTEM_SIZE_T +++typedef UInt32 SizeT; +++#else +++typedef size_t SizeT; +++#endif +++ +++typedef int Bool; +++#define True 1 +++#define False 0 +++ +++ +++#ifdef _WIN32 +++#define MY_STD_CALL __stdcall +++#else +++#define MY_STD_CALL +++#endif +++ +++#ifdef _MSC_VER +++ +++#if _MSC_VER >= 1300 +++#define MY_NO_INLINE __declspec(noinline) +++#else +++#define MY_NO_INLINE +++#endif +++ +++#define MY_CDECL __cdecl +++#define MY_FAST_CALL __fastcall +++ +++#else +++ +++#define MY_CDECL +++#define MY_FAST_CALL +++ +++#endif +++ +++ +++/* The following interfaces use first parameter as pointer to structure */ +++ +++typedef struct +++{ +++ SRes (*Read)(void *p, void *buf, size_t *size); +++ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. +++ (output(*size) < input(*size)) is allowed */ +++} ISeqInStream; +++ +++/* it can return SZ_ERROR_INPUT_EOF */ +++SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); +++SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); +++SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); +++ +++typedef struct +++{ +++ size_t (*Write)(void *p, const void *buf, size_t size); +++ /* Returns: result - the number of actually written bytes. +++ (result < size) means error */ +++} ISeqOutStream; +++ +++typedef enum +++{ +++ SZ_SEEK_SET = 0, +++ SZ_SEEK_CUR = 1, +++ SZ_SEEK_END = 2 +++} ESzSeek; +++ +++typedef struct +++{ +++ SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ +++ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); +++} ISeekInStream; +++ +++typedef struct +++{ +++ SRes (*Look)(void *p, void **buf, size_t *size); +++ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. +++ (output(*size) > input(*size)) is not allowed +++ (output(*size) < input(*size)) is allowed */ +++ SRes (*Skip)(void *p, size_t offset); +++ /* offset must be <= output(*size) of Look */ +++ +++ SRes (*Read)(void *p, void *buf, size_t *size); +++ /* reads directly (without buffer). It's same as ISeqInStream::Read */ +++ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); +++} ILookInStream; +++ +++SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); +++SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); +++ +++/* reads via ILookInStream::Read */ +++SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); +++SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); +++ +++#define LookToRead_BUF_SIZE (1 << 14) +++ +++typedef struct +++{ +++ ILookInStream s; +++ ISeekInStream *realStream; +++ size_t pos; +++ size_t size; +++ Byte buf[LookToRead_BUF_SIZE]; +++} CLookToRead; +++ +++void LookToRead_CreateVTable(CLookToRead *p, int lookahead); +++void LookToRead_Init(CLookToRead *p); +++ +++typedef struct +++{ +++ ISeqInStream s; +++ ILookInStream *realStream; +++} CSecToLook; +++ +++void SecToLook_CreateVTable(CSecToLook *p); +++ +++typedef struct +++{ +++ ISeqInStream s; +++ ILookInStream *realStream; +++} CSecToRead; +++ +++void SecToRead_CreateVTable(CSecToRead *p); +++ +++typedef struct +++{ +++ SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); +++ /* Returns: result. (result != SZ_OK) means break. +++ Value (UInt64)(Int64)-1 for size means unknown value. */ +++} ICompressProgress; +++ +++typedef struct +++{ +++ void *(*Alloc)(void *p, size_t size); +++ void (*Free)(void *p, void *address); /* address can be 0 */ +++} ISzAlloc; +++ +++#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) +++#define IAlloc_Free(p, a) (p)->Free((p), a) +++ +++EXTERN_C_END +++ +++#endif ++--- a/include/uapi/linux/jffs2.h +++++ b/include/uapi/linux/jffs2.h ++@@ -46,6 +46,7 @@ ++ #define JFFS2_COMPR_DYNRUBIN 0x05 ++ #define JFFS2_COMPR_ZLIB 0x06 ++ #define JFFS2_COMPR_LZO 0x07 +++#define JFFS2_COMPR_LZMA 0x08 ++ /* Compatibility flags. */ ++ #define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */ ++ #define JFFS2_NODE_ACCURATE 0x2000 ++--- a/lib/Kconfig +++++ b/lib/Kconfig ++@@ -316,6 +316,12 @@ config ZSTD_DECOMPRESS ++ ++ source "lib/xz/Kconfig" ++ +++config LZMA_COMPRESS +++ tristate +++ +++config LZMA_DECOMPRESS +++ tristate +++ ++ # ++ # These all provide a common interface (hence the apparent duplication with ++ # ZLIB_INFLATE; DECOMPRESS_GZIP is just a wrapper.) ++--- a/lib/Makefile +++++ b/lib/Makefile ++@@ -136,6 +136,16 @@ CFLAGS_kobject.o += -DDEBUG ++ CFLAGS_kobject_uevent.o += -DDEBUG ++ endif ++ +++ifdef CONFIG_JFFS2_ZLIB +++ CONFIG_ZLIB_INFLATE:=y +++ CONFIG_ZLIB_DEFLATE:=y +++endif +++ +++ifdef CONFIG_JFFS2_LZMA +++ CONFIG_LZMA_DECOMPRESS:=y +++ CONFIG_LZMA_COMPRESS:=y +++endif +++ ++ obj-$(CONFIG_DEBUG_INFO_REDUCED) += debug_info.o ++ CFLAGS_debug_info.o += $(call cc-option, -femit-struct-debug-detailed=any) ++ ++@@ -191,6 +201,8 @@ obj-$(CONFIG_ZSTD_COMPRESS) += zstd/ ++ obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd/ ++ obj-$(CONFIG_XZ_DEC) += xz/ ++ obj-$(CONFIG_RAID6_PQ) += raid6/ +++obj-$(CONFIG_LZMA_COMPRESS) += lzma/ +++obj-$(CONFIG_LZMA_DECOMPRESS) += lzma/ ++ ++ lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o ++ lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o ++--- /dev/null +++++ b/lib/lzma/LzFind.c ++@@ -0,0 +1,761 @@ +++/* LzFind.c -- Match finder for LZ algorithms +++2009-04-22 : Igor Pavlov : Public domain */ +++ +++#include +++ +++#include "LzFind.h" +++#include "LzHash.h" +++ +++#define kEmptyHashValue 0 +++#define kMaxValForNormalize ((UInt32)0xFFFFFFFF) +++#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */ +++#define kNormalizeMask (~(kNormalizeStepMin - 1)) +++#define kMaxHistorySize ((UInt32)3 << 30) +++ +++#define kStartMaxLen 3 +++ +++static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) +++{ +++ if (!p->directInput) +++ { +++ alloc->Free(alloc, p->bufferBase); +++ p->bufferBase = 0; +++ } +++} +++ +++/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */ +++ +++static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) +++{ +++ UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; +++ if (p->directInput) +++ { +++ p->blockSize = blockSize; +++ return 1; +++ } +++ if (p->bufferBase == 0 || p->blockSize != blockSize) +++ { +++ LzInWindow_Free(p, alloc); +++ p->blockSize = blockSize; +++ p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); +++ } +++ return (p->bufferBase != 0); +++} +++ +++Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } +++Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } +++ +++UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } +++ +++void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) +++{ +++ p->posLimit -= subValue; +++ p->pos -= subValue; +++ p->streamPos -= subValue; +++} +++ +++static void MatchFinder_ReadBlock(CMatchFinder *p) +++{ +++ if (p->streamEndWasReached || p->result != SZ_OK) +++ return; +++ if (p->directInput) +++ { +++ UInt32 curSize = 0xFFFFFFFF - p->streamPos; +++ if (curSize > p->directInputRem) +++ curSize = (UInt32)p->directInputRem; +++ p->directInputRem -= curSize; +++ p->streamPos += curSize; +++ if (p->directInputRem == 0) +++ p->streamEndWasReached = 1; +++ return; +++ } +++ for (;;) +++ { +++ Byte *dest = p->buffer + (p->streamPos - p->pos); +++ size_t size = (p->bufferBase + p->blockSize - dest); +++ if (size == 0) +++ return; +++ p->result = p->stream->Read(p->stream, dest, &size); +++ if (p->result != SZ_OK) +++ return; +++ if (size == 0) +++ { +++ p->streamEndWasReached = 1; +++ return; +++ } +++ p->streamPos += (UInt32)size; +++ if (p->streamPos - p->pos > p->keepSizeAfter) +++ return; +++ } +++} +++ +++void MatchFinder_MoveBlock(CMatchFinder *p) +++{ +++ memmove(p->bufferBase, +++ p->buffer - p->keepSizeBefore, +++ (size_t)(p->streamPos - p->pos + p->keepSizeBefore)); +++ p->buffer = p->bufferBase + p->keepSizeBefore; +++} +++ +++int MatchFinder_NeedMove(CMatchFinder *p) +++{ +++ if (p->directInput) +++ return 0; +++ /* if (p->streamEndWasReached) return 0; */ +++ return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); +++} +++ +++void MatchFinder_ReadIfRequired(CMatchFinder *p) +++{ +++ if (p->streamEndWasReached) +++ return; +++ if (p->keepSizeAfter >= p->streamPos - p->pos) +++ MatchFinder_ReadBlock(p); +++} +++ +++static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) +++{ +++ if (MatchFinder_NeedMove(p)) +++ MatchFinder_MoveBlock(p); +++ MatchFinder_ReadBlock(p); +++} +++ +++static void MatchFinder_SetDefaultSettings(CMatchFinder *p) +++{ +++ p->cutValue = 32; +++ p->btMode = 1; +++ p->numHashBytes = 4; +++ p->bigHash = 0; +++} +++ +++#define kCrcPoly 0xEDB88320 +++ +++void MatchFinder_Construct(CMatchFinder *p) +++{ +++ UInt32 i; +++ p->bufferBase = 0; +++ p->directInput = 0; +++ p->hash = 0; +++ MatchFinder_SetDefaultSettings(p); +++ +++ for (i = 0; i < 256; i++) +++ { +++ UInt32 r = i; +++ int j; +++ for (j = 0; j < 8; j++) +++ r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); +++ p->crc[i] = r; +++ } +++} +++ +++static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) +++{ +++ alloc->Free(alloc, p->hash); +++ p->hash = 0; +++} +++ +++void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) +++{ +++ MatchFinder_FreeThisClassMemory(p, alloc); +++ LzInWindow_Free(p, alloc); +++} +++ +++static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc) +++{ +++ size_t sizeInBytes = (size_t)num * sizeof(CLzRef); +++ if (sizeInBytes / sizeof(CLzRef) != num) +++ return 0; +++ return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); +++} +++ +++int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, +++ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, +++ ISzAlloc *alloc) +++{ +++ UInt32 sizeReserv; +++ if (historySize > kMaxHistorySize) +++ { +++ MatchFinder_Free(p, alloc); +++ return 0; +++ } +++ sizeReserv = historySize >> 1; +++ if (historySize > ((UInt32)2 << 30)) +++ sizeReserv = historySize >> 2; +++ sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19); +++ +++ p->keepSizeBefore = historySize + keepAddBufferBefore + 1; +++ p->keepSizeAfter = matchMaxLen + keepAddBufferAfter; +++ /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ +++ if (LzInWindow_Create(p, sizeReserv, alloc)) +++ { +++ UInt32 newCyclicBufferSize = historySize + 1; +++ UInt32 hs; +++ p->matchMaxLen = matchMaxLen; +++ { +++ p->fixedHashSize = 0; +++ if (p->numHashBytes == 2) +++ hs = (1 << 16) - 1; +++ else +++ { +++ hs = historySize - 1; +++ hs |= (hs >> 1); +++ hs |= (hs >> 2); +++ hs |= (hs >> 4); +++ hs |= (hs >> 8); +++ hs >>= 1; +++ hs |= 0xFFFF; /* don't change it! It's required for Deflate */ +++ if (hs > (1 << 24)) +++ { +++ if (p->numHashBytes == 3) +++ hs = (1 << 24) - 1; +++ else +++ hs >>= 1; +++ } +++ } +++ p->hashMask = hs; +++ hs++; +++ if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size; +++ if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size; +++ if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size; +++ hs += p->fixedHashSize; +++ } +++ +++ { +++ UInt32 prevSize = p->hashSizeSum + p->numSons; +++ UInt32 newSize; +++ p->historySize = historySize; +++ p->hashSizeSum = hs; +++ p->cyclicBufferSize = newCyclicBufferSize; +++ p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize); +++ newSize = p->hashSizeSum + p->numSons; +++ if (p->hash != 0 && prevSize == newSize) +++ return 1; +++ MatchFinder_FreeThisClassMemory(p, alloc); +++ p->hash = AllocRefs(newSize, alloc); +++ if (p->hash != 0) +++ { +++ p->son = p->hash + p->hashSizeSum; +++ return 1; +++ } +++ } +++ } +++ MatchFinder_Free(p, alloc); +++ return 0; +++} +++ +++static void MatchFinder_SetLimits(CMatchFinder *p) +++{ +++ UInt32 limit = kMaxValForNormalize - p->pos; +++ UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos; +++ if (limit2 < limit) +++ limit = limit2; +++ limit2 = p->streamPos - p->pos; +++ if (limit2 <= p->keepSizeAfter) +++ { +++ if (limit2 > 0) +++ limit2 = 1; +++ } +++ else +++ limit2 -= p->keepSizeAfter; +++ if (limit2 < limit) +++ limit = limit2; +++ { +++ UInt32 lenLimit = p->streamPos - p->pos; +++ if (lenLimit > p->matchMaxLen) +++ lenLimit = p->matchMaxLen; +++ p->lenLimit = lenLimit; +++ } +++ p->posLimit = p->pos + limit; +++} +++ +++void MatchFinder_Init(CMatchFinder *p) +++{ +++ UInt32 i; +++ for (i = 0; i < p->hashSizeSum; i++) +++ p->hash[i] = kEmptyHashValue; +++ p->cyclicBufferPos = 0; +++ p->buffer = p->bufferBase; +++ p->pos = p->streamPos = p->cyclicBufferSize; +++ p->result = SZ_OK; +++ p->streamEndWasReached = 0; +++ MatchFinder_ReadBlock(p); +++ MatchFinder_SetLimits(p); +++} +++ +++static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) +++{ +++ return (p->pos - p->historySize - 1) & kNormalizeMask; +++} +++ +++void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) +++{ +++ UInt32 i; +++ for (i = 0; i < numItems; i++) +++ { +++ UInt32 value = items[i]; +++ if (value <= subValue) +++ value = kEmptyHashValue; +++ else +++ value -= subValue; +++ items[i] = value; +++ } +++} +++ +++static void MatchFinder_Normalize(CMatchFinder *p) +++{ +++ UInt32 subValue = MatchFinder_GetSubValue(p); +++ MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons); +++ MatchFinder_ReduceOffsets(p, subValue); +++} +++ +++static void MatchFinder_CheckLimits(CMatchFinder *p) +++{ +++ if (p->pos == kMaxValForNormalize) +++ MatchFinder_Normalize(p); +++ if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos) +++ MatchFinder_CheckAndMoveAndRead(p); +++ if (p->cyclicBufferPos == p->cyclicBufferSize) +++ p->cyclicBufferPos = 0; +++ MatchFinder_SetLimits(p); +++} +++ +++static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, +++ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, +++ UInt32 *distances, UInt32 maxLen) +++{ +++ son[_cyclicBufferPos] = curMatch; +++ for (;;) +++ { +++ UInt32 delta = pos - curMatch; +++ if (cutValue-- == 0 || delta >= _cyclicBufferSize) +++ return distances; +++ { +++ const Byte *pb = cur - delta; +++ curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; +++ if (pb[maxLen] == cur[maxLen] && *pb == *cur) +++ { +++ UInt32 len = 0; +++ while (++len != lenLimit) +++ if (pb[len] != cur[len]) +++ break; +++ if (maxLen < len) +++ { +++ *distances++ = maxLen = len; +++ *distances++ = delta - 1; +++ if (len == lenLimit) +++ return distances; +++ } +++ } +++ } +++ } +++} +++ +++UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, +++ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, +++ UInt32 *distances, UInt32 maxLen) +++{ +++ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; +++ CLzRef *ptr1 = son + (_cyclicBufferPos << 1); +++ UInt32 len0 = 0, len1 = 0; +++ for (;;) +++ { +++ UInt32 delta = pos - curMatch; +++ if (cutValue-- == 0 || delta >= _cyclicBufferSize) +++ { +++ *ptr0 = *ptr1 = kEmptyHashValue; +++ return distances; +++ } +++ { +++ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); +++ const Byte *pb = cur - delta; +++ UInt32 len = (len0 < len1 ? len0 : len1); +++ if (pb[len] == cur[len]) +++ { +++ if (++len != lenLimit && pb[len] == cur[len]) +++ while (++len != lenLimit) +++ if (pb[len] != cur[len]) +++ break; +++ if (maxLen < len) +++ { +++ *distances++ = maxLen = len; +++ *distances++ = delta - 1; +++ if (len == lenLimit) +++ { +++ *ptr1 = pair[0]; +++ *ptr0 = pair[1]; +++ return distances; +++ } +++ } +++ } +++ if (pb[len] < cur[len]) +++ { +++ *ptr1 = curMatch; +++ ptr1 = pair + 1; +++ curMatch = *ptr1; +++ len1 = len; +++ } +++ else +++ { +++ *ptr0 = curMatch; +++ ptr0 = pair; +++ curMatch = *ptr0; +++ len0 = len; +++ } +++ } +++ } +++} +++ +++static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, +++ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue) +++{ +++ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; +++ CLzRef *ptr1 = son + (_cyclicBufferPos << 1); +++ UInt32 len0 = 0, len1 = 0; +++ for (;;) +++ { +++ UInt32 delta = pos - curMatch; +++ if (cutValue-- == 0 || delta >= _cyclicBufferSize) +++ { +++ *ptr0 = *ptr1 = kEmptyHashValue; +++ return; +++ } +++ { +++ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); +++ const Byte *pb = cur - delta; +++ UInt32 len = (len0 < len1 ? len0 : len1); +++ if (pb[len] == cur[len]) +++ { +++ while (++len != lenLimit) +++ if (pb[len] != cur[len]) +++ break; +++ { +++ if (len == lenLimit) +++ { +++ *ptr1 = pair[0]; +++ *ptr0 = pair[1]; +++ return; +++ } +++ } +++ } +++ if (pb[len] < cur[len]) +++ { +++ *ptr1 = curMatch; +++ ptr1 = pair + 1; +++ curMatch = *ptr1; +++ len1 = len; +++ } +++ else +++ { +++ *ptr0 = curMatch; +++ ptr0 = pair; +++ curMatch = *ptr0; +++ len0 = len; +++ } +++ } +++ } +++} +++ +++#define MOVE_POS \ +++ ++p->cyclicBufferPos; \ +++ p->buffer++; \ +++ if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p); +++ +++#define MOVE_POS_RET MOVE_POS return offset; +++ +++static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } +++ +++#define GET_MATCHES_HEADER2(minLen, ret_op) \ +++ UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \ +++ lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ +++ cur = p->buffer; +++ +++#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0) +++#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue) +++ +++#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue +++ +++#define GET_MATCHES_FOOTER(offset, maxLen) \ +++ offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \ +++ distances + offset, maxLen) - distances); MOVE_POS_RET; +++ +++#define SKIP_FOOTER \ +++ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; +++ +++static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +++{ +++ UInt32 offset; +++ GET_MATCHES_HEADER(2) +++ HASH2_CALC; +++ curMatch = p->hash[hashValue]; +++ p->hash[hashValue] = p->pos; +++ offset = 0; +++ GET_MATCHES_FOOTER(offset, 1) +++} +++ +++UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +++{ +++ UInt32 offset; +++ GET_MATCHES_HEADER(3) +++ HASH_ZIP_CALC; +++ curMatch = p->hash[hashValue]; +++ p->hash[hashValue] = p->pos; +++ offset = 0; +++ GET_MATCHES_FOOTER(offset, 2) +++} +++ +++static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +++{ +++ UInt32 hash2Value, delta2, maxLen, offset; +++ GET_MATCHES_HEADER(3) +++ +++ HASH3_CALC; +++ +++ delta2 = p->pos - p->hash[hash2Value]; +++ curMatch = p->hash[kFix3HashSize + hashValue]; +++ +++ p->hash[hash2Value] = +++ p->hash[kFix3HashSize + hashValue] = p->pos; +++ +++ +++ maxLen = 2; +++ offset = 0; +++ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) +++ { +++ for (; maxLen != lenLimit; maxLen++) +++ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) +++ break; +++ distances[0] = maxLen; +++ distances[1] = delta2 - 1; +++ offset = 2; +++ if (maxLen == lenLimit) +++ { +++ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); +++ MOVE_POS_RET; +++ } +++ } +++ GET_MATCHES_FOOTER(offset, maxLen) +++} +++ +++static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +++{ +++ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; +++ GET_MATCHES_HEADER(4) +++ +++ HASH4_CALC; +++ +++ delta2 = p->pos - p->hash[ hash2Value]; +++ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; +++ curMatch = p->hash[kFix4HashSize + hashValue]; +++ +++ p->hash[ hash2Value] = +++ p->hash[kFix3HashSize + hash3Value] = +++ p->hash[kFix4HashSize + hashValue] = p->pos; +++ +++ maxLen = 1; +++ offset = 0; +++ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) +++ { +++ distances[0] = maxLen = 2; +++ distances[1] = delta2 - 1; +++ offset = 2; +++ } +++ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) +++ { +++ maxLen = 3; +++ distances[offset + 1] = delta3 - 1; +++ offset += 2; +++ delta2 = delta3; +++ } +++ if (offset != 0) +++ { +++ for (; maxLen != lenLimit; maxLen++) +++ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) +++ break; +++ distances[offset - 2] = maxLen; +++ if (maxLen == lenLimit) +++ { +++ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); +++ MOVE_POS_RET; +++ } +++ } +++ if (maxLen < 3) +++ maxLen = 3; +++ GET_MATCHES_FOOTER(offset, maxLen) +++} +++ +++static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +++{ +++ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; +++ GET_MATCHES_HEADER(4) +++ +++ HASH4_CALC; +++ +++ delta2 = p->pos - p->hash[ hash2Value]; +++ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; +++ curMatch = p->hash[kFix4HashSize + hashValue]; +++ +++ p->hash[ hash2Value] = +++ p->hash[kFix3HashSize + hash3Value] = +++ p->hash[kFix4HashSize + hashValue] = p->pos; +++ +++ maxLen = 1; +++ offset = 0; +++ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) +++ { +++ distances[0] = maxLen = 2; +++ distances[1] = delta2 - 1; +++ offset = 2; +++ } +++ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) +++ { +++ maxLen = 3; +++ distances[offset + 1] = delta3 - 1; +++ offset += 2; +++ delta2 = delta3; +++ } +++ if (offset != 0) +++ { +++ for (; maxLen != lenLimit; maxLen++) +++ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) +++ break; +++ distances[offset - 2] = maxLen; +++ if (maxLen == lenLimit) +++ { +++ p->son[p->cyclicBufferPos] = curMatch; +++ MOVE_POS_RET; +++ } +++ } +++ if (maxLen < 3) +++ maxLen = 3; +++ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), +++ distances + offset, maxLen) - (distances)); +++ MOVE_POS_RET +++} +++ +++UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +++{ +++ UInt32 offset; +++ GET_MATCHES_HEADER(3) +++ HASH_ZIP_CALC; +++ curMatch = p->hash[hashValue]; +++ p->hash[hashValue] = p->pos; +++ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), +++ distances, 2) - (distances)); +++ MOVE_POS_RET +++} +++ +++static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +++{ +++ do +++ { +++ SKIP_HEADER(2) +++ HASH2_CALC; +++ curMatch = p->hash[hashValue]; +++ p->hash[hashValue] = p->pos; +++ SKIP_FOOTER +++ } +++ while (--num != 0); +++} +++ +++void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +++{ +++ do +++ { +++ SKIP_HEADER(3) +++ HASH_ZIP_CALC; +++ curMatch = p->hash[hashValue]; +++ p->hash[hashValue] = p->pos; +++ SKIP_FOOTER +++ } +++ while (--num != 0); +++} +++ +++static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +++{ +++ do +++ { +++ UInt32 hash2Value; +++ SKIP_HEADER(3) +++ HASH3_CALC; +++ curMatch = p->hash[kFix3HashSize + hashValue]; +++ p->hash[hash2Value] = +++ p->hash[kFix3HashSize + hashValue] = p->pos; +++ SKIP_FOOTER +++ } +++ while (--num != 0); +++} +++ +++static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +++{ +++ do +++ { +++ UInt32 hash2Value, hash3Value; +++ SKIP_HEADER(4) +++ HASH4_CALC; +++ curMatch = p->hash[kFix4HashSize + hashValue]; +++ p->hash[ hash2Value] = +++ p->hash[kFix3HashSize + hash3Value] = p->pos; +++ p->hash[kFix4HashSize + hashValue] = p->pos; +++ SKIP_FOOTER +++ } +++ while (--num != 0); +++} +++ +++static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +++{ +++ do +++ { +++ UInt32 hash2Value, hash3Value; +++ SKIP_HEADER(4) +++ HASH4_CALC; +++ curMatch = p->hash[kFix4HashSize + hashValue]; +++ p->hash[ hash2Value] = +++ p->hash[kFix3HashSize + hash3Value] = +++ p->hash[kFix4HashSize + hashValue] = p->pos; +++ p->son[p->cyclicBufferPos] = curMatch; +++ MOVE_POS +++ } +++ while (--num != 0); +++} +++ +++void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +++{ +++ do +++ { +++ SKIP_HEADER(3) +++ HASH_ZIP_CALC; +++ curMatch = p->hash[hashValue]; +++ p->hash[hashValue] = p->pos; +++ p->son[p->cyclicBufferPos] = curMatch; +++ MOVE_POS +++ } +++ while (--num != 0); +++} +++ +++void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) +++{ +++ vTable->Init = (Mf_Init_Func)MatchFinder_Init; +++ vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte; +++ vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; +++ vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; +++ if (!p->btMode) +++ { +++ vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; +++ vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; +++ } +++ else if (p->numHashBytes == 2) +++ { +++ vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches; +++ vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip; +++ } +++ else if (p->numHashBytes == 3) +++ { +++ vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; +++ vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; +++ } +++ else +++ { +++ vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; +++ vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; +++ } +++} ++--- /dev/null +++++ b/lib/lzma/LzmaDec.c ++@@ -0,0 +1,999 @@ +++/* LzmaDec.c -- LZMA Decoder +++2009-09-20 : Igor Pavlov : Public domain */ +++ +++#include "LzmaDec.h" +++ +++#include +++ +++#define kNumTopBits 24 +++#define kTopValue ((UInt32)1 << kNumTopBits) +++ +++#define kNumBitModelTotalBits 11 +++#define kBitModelTotal (1 << kNumBitModelTotalBits) +++#define kNumMoveBits 5 +++ +++#define RC_INIT_SIZE 5 +++ +++#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } +++ +++#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) +++#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); +++#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); +++#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ +++ { UPDATE_0(p); i = (i + i); A0; } else \ +++ { UPDATE_1(p); i = (i + i) + 1; A1; } +++#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) +++ +++#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } +++#define TREE_DECODE(probs, limit, i) \ +++ { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } +++ +++/* #define _LZMA_SIZE_OPT */ +++ +++#ifdef _LZMA_SIZE_OPT +++#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) +++#else +++#define TREE_6_DECODE(probs, i) \ +++ { i = 1; \ +++ TREE_GET_BIT(probs, i); \ +++ TREE_GET_BIT(probs, i); \ +++ TREE_GET_BIT(probs, i); \ +++ TREE_GET_BIT(probs, i); \ +++ TREE_GET_BIT(probs, i); \ +++ TREE_GET_BIT(probs, i); \ +++ i -= 0x40; } +++#endif +++ +++#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } +++ +++#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) +++#define UPDATE_0_CHECK range = bound; +++#define UPDATE_1_CHECK range -= bound; code -= bound; +++#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ +++ { UPDATE_0_CHECK; i = (i + i); A0; } else \ +++ { UPDATE_1_CHECK; i = (i + i) + 1; A1; } +++#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) +++#define TREE_DECODE_CHECK(probs, limit, i) \ +++ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } +++ +++ +++#define kNumPosBitsMax 4 +++#define kNumPosStatesMax (1 << kNumPosBitsMax) +++ +++#define kLenNumLowBits 3 +++#define kLenNumLowSymbols (1 << kLenNumLowBits) +++#define kLenNumMidBits 3 +++#define kLenNumMidSymbols (1 << kLenNumMidBits) +++#define kLenNumHighBits 8 +++#define kLenNumHighSymbols (1 << kLenNumHighBits) +++ +++#define LenChoice 0 +++#define LenChoice2 (LenChoice + 1) +++#define LenLow (LenChoice2 + 1) +++#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) +++#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) +++#define kNumLenProbs (LenHigh + kLenNumHighSymbols) +++ +++ +++#define kNumStates 12 +++#define kNumLitStates 7 +++ +++#define kStartPosModelIndex 4 +++#define kEndPosModelIndex 14 +++#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) +++ +++#define kNumPosSlotBits 6 +++#define kNumLenToPosStates 4 +++ +++#define kNumAlignBits 4 +++#define kAlignTableSize (1 << kNumAlignBits) +++ +++#define kMatchMinLen 2 +++#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) +++ +++#define IsMatch 0 +++#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) +++#define IsRepG0 (IsRep + kNumStates) +++#define IsRepG1 (IsRepG0 + kNumStates) +++#define IsRepG2 (IsRepG1 + kNumStates) +++#define IsRep0Long (IsRepG2 + kNumStates) +++#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) +++#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +++#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) +++#define LenCoder (Align + kAlignTableSize) +++#define RepLenCoder (LenCoder + kNumLenProbs) +++#define Literal (RepLenCoder + kNumLenProbs) +++ +++#define LZMA_BASE_SIZE 1846 +++#define LZMA_LIT_SIZE 768 +++ +++#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) +++ +++#if Literal != LZMA_BASE_SIZE +++StopCompilingDueBUG +++#endif +++ +++#define LZMA_DIC_MIN (1 << 12) +++ +++/* First LZMA-symbol is always decoded. +++And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization +++Out: +++ Result: +++ SZ_OK - OK +++ SZ_ERROR_DATA - Error +++ p->remainLen: +++ < kMatchSpecLenStart : normal remain +++ = kMatchSpecLenStart : finished +++ = kMatchSpecLenStart + 1 : Flush marker +++ = kMatchSpecLenStart + 2 : State Init Marker +++*/ +++ +++static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +++{ +++ CLzmaProb *probs = p->probs; +++ +++ unsigned state = p->state; +++ UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; +++ unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; +++ unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; +++ unsigned lc = p->prop.lc; +++ +++ Byte *dic = p->dic; +++ SizeT dicBufSize = p->dicBufSize; +++ SizeT dicPos = p->dicPos; +++ +++ UInt32 processedPos = p->processedPos; +++ UInt32 checkDicSize = p->checkDicSize; +++ unsigned len = 0; +++ +++ const Byte *buf = p->buf; +++ UInt32 range = p->range; +++ UInt32 code = p->code; +++ +++ do +++ { +++ CLzmaProb *prob; +++ UInt32 bound; +++ unsigned ttt; +++ unsigned posState = processedPos & pbMask; +++ +++ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; +++ IF_BIT_0(prob) +++ { +++ unsigned symbol; +++ UPDATE_0(prob); +++ prob = probs + Literal; +++ if (checkDicSize != 0 || processedPos != 0) +++ prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + +++ (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); +++ +++ if (state < kNumLitStates) +++ { +++ state -= (state < 4) ? state : 3; +++ symbol = 1; +++ do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); +++ } +++ else +++ { +++ unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; +++ unsigned offs = 0x100; +++ state -= (state < 10) ? 3 : 6; +++ symbol = 1; +++ do +++ { +++ unsigned bit; +++ CLzmaProb *probLit; +++ matchByte <<= 1; +++ bit = (matchByte & offs); +++ probLit = prob + offs + bit + symbol; +++ GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) +++ } +++ while (symbol < 0x100); +++ } +++ dic[dicPos++] = (Byte)symbol; +++ processedPos++; +++ continue; +++ } +++ else +++ { +++ UPDATE_1(prob); +++ prob = probs + IsRep + state; +++ IF_BIT_0(prob) +++ { +++ UPDATE_0(prob); +++ state += kNumStates; +++ prob = probs + LenCoder; +++ } +++ else +++ { +++ UPDATE_1(prob); +++ if (checkDicSize == 0 && processedPos == 0) +++ return SZ_ERROR_DATA; +++ prob = probs + IsRepG0 + state; +++ IF_BIT_0(prob) +++ { +++ UPDATE_0(prob); +++ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; +++ IF_BIT_0(prob) +++ { +++ UPDATE_0(prob); +++ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; +++ dicPos++; +++ processedPos++; +++ state = state < kNumLitStates ? 9 : 11; +++ continue; +++ } +++ UPDATE_1(prob); +++ } +++ else +++ { +++ UInt32 distance; +++ UPDATE_1(prob); +++ prob = probs + IsRepG1 + state; +++ IF_BIT_0(prob) +++ { +++ UPDATE_0(prob); +++ distance = rep1; +++ } +++ else +++ { +++ UPDATE_1(prob); +++ prob = probs + IsRepG2 + state; +++ IF_BIT_0(prob) +++ { +++ UPDATE_0(prob); +++ distance = rep2; +++ } +++ else +++ { +++ UPDATE_1(prob); +++ distance = rep3; +++ rep3 = rep2; +++ } +++ rep2 = rep1; +++ } +++ rep1 = rep0; +++ rep0 = distance; +++ } +++ state = state < kNumLitStates ? 8 : 11; +++ prob = probs + RepLenCoder; +++ } +++ { +++ unsigned limit, offset; +++ CLzmaProb *probLen = prob + LenChoice; +++ IF_BIT_0(probLen) +++ { +++ UPDATE_0(probLen); +++ probLen = prob + LenLow + (posState << kLenNumLowBits); +++ offset = 0; +++ limit = (1 << kLenNumLowBits); +++ } +++ else +++ { +++ UPDATE_1(probLen); +++ probLen = prob + LenChoice2; +++ IF_BIT_0(probLen) +++ { +++ UPDATE_0(probLen); +++ probLen = prob + LenMid + (posState << kLenNumMidBits); +++ offset = kLenNumLowSymbols; +++ limit = (1 << kLenNumMidBits); +++ } +++ else +++ { +++ UPDATE_1(probLen); +++ probLen = prob + LenHigh; +++ offset = kLenNumLowSymbols + kLenNumMidSymbols; +++ limit = (1 << kLenNumHighBits); +++ } +++ } +++ TREE_DECODE(probLen, limit, len); +++ len += offset; +++ } +++ +++ if (state >= kNumStates) +++ { +++ UInt32 distance; +++ prob = probs + PosSlot + +++ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); +++ TREE_6_DECODE(prob, distance); +++ if (distance >= kStartPosModelIndex) +++ { +++ unsigned posSlot = (unsigned)distance; +++ int numDirectBits = (int)(((distance >> 1) - 1)); +++ distance = (2 | (distance & 1)); +++ if (posSlot < kEndPosModelIndex) +++ { +++ distance <<= numDirectBits; +++ prob = probs + SpecPos + distance - posSlot - 1; +++ { +++ UInt32 mask = 1; +++ unsigned i = 1; +++ do +++ { +++ GET_BIT2(prob + i, i, ; , distance |= mask); +++ mask <<= 1; +++ } +++ while (--numDirectBits != 0); +++ } +++ } +++ else +++ { +++ numDirectBits -= kNumAlignBits; +++ do +++ { +++ NORMALIZE +++ range >>= 1; +++ +++ { +++ UInt32 t; +++ code -= range; +++ t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ +++ distance = (distance << 1) + (t + 1); +++ code += range & t; +++ } +++ /* +++ distance <<= 1; +++ if (code >= range) +++ { +++ code -= range; +++ distance |= 1; +++ } +++ */ +++ } +++ while (--numDirectBits != 0); +++ prob = probs + Align; +++ distance <<= kNumAlignBits; +++ { +++ unsigned i = 1; +++ GET_BIT2(prob + i, i, ; , distance |= 1); +++ GET_BIT2(prob + i, i, ; , distance |= 2); +++ GET_BIT2(prob + i, i, ; , distance |= 4); +++ GET_BIT2(prob + i, i, ; , distance |= 8); +++ } +++ if (distance == (UInt32)0xFFFFFFFF) +++ { +++ len += kMatchSpecLenStart; +++ state -= kNumStates; +++ break; +++ } +++ } +++ } +++ rep3 = rep2; +++ rep2 = rep1; +++ rep1 = rep0; +++ rep0 = distance + 1; +++ if (checkDicSize == 0) +++ { +++ if (distance >= processedPos) +++ return SZ_ERROR_DATA; +++ } +++ else if (distance >= checkDicSize) +++ return SZ_ERROR_DATA; +++ state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; +++ } +++ +++ len += kMatchMinLen; +++ +++ if (limit == dicPos) +++ return SZ_ERROR_DATA; +++ { +++ SizeT rem = limit - dicPos; +++ unsigned curLen = ((rem < len) ? (unsigned)rem : len); +++ SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); +++ +++ processedPos += curLen; +++ +++ len -= curLen; +++ if (pos + curLen <= dicBufSize) +++ { +++ Byte *dest = dic + dicPos; +++ ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; +++ const Byte *lim = dest + curLen; +++ dicPos += curLen; +++ do +++ *(dest) = (Byte)*(dest + src); +++ while (++dest != lim); +++ } +++ else +++ { +++ do +++ { +++ dic[dicPos++] = dic[pos]; +++ if (++pos == dicBufSize) +++ pos = 0; +++ } +++ while (--curLen != 0); +++ } +++ } +++ } +++ } +++ while (dicPos < limit && buf < bufLimit); +++ NORMALIZE; +++ p->buf = buf; +++ p->range = range; +++ p->code = code; +++ p->remainLen = len; +++ p->dicPos = dicPos; +++ p->processedPos = processedPos; +++ p->reps[0] = rep0; +++ p->reps[1] = rep1; +++ p->reps[2] = rep2; +++ p->reps[3] = rep3; +++ p->state = state; +++ +++ return SZ_OK; +++} +++ +++static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) +++{ +++ if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) +++ { +++ Byte *dic = p->dic; +++ SizeT dicPos = p->dicPos; +++ SizeT dicBufSize = p->dicBufSize; +++ unsigned len = p->remainLen; +++ UInt32 rep0 = p->reps[0]; +++ if (limit - dicPos < len) +++ len = (unsigned)(limit - dicPos); +++ +++ if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) +++ p->checkDicSize = p->prop.dicSize; +++ +++ p->processedPos += len; +++ p->remainLen -= len; +++ while (len-- != 0) +++ { +++ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; +++ dicPos++; +++ } +++ p->dicPos = dicPos; +++ } +++} +++ +++static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +++{ +++ do +++ { +++ SizeT limit2 = limit; +++ if (p->checkDicSize == 0) +++ { +++ UInt32 rem = p->prop.dicSize - p->processedPos; +++ if (limit - p->dicPos > rem) +++ limit2 = p->dicPos + rem; +++ } +++ RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); +++ if (p->processedPos >= p->prop.dicSize) +++ p->checkDicSize = p->prop.dicSize; +++ LzmaDec_WriteRem(p, limit); +++ } +++ while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); +++ +++ if (p->remainLen > kMatchSpecLenStart) +++ { +++ p->remainLen = kMatchSpecLenStart; +++ } +++ return 0; +++} +++ +++typedef enum +++{ +++ DUMMY_ERROR, /* unexpected end of input stream */ +++ DUMMY_LIT, +++ DUMMY_MATCH, +++ DUMMY_REP +++} ELzmaDummy; +++ +++static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) +++{ +++ UInt32 range = p->range; +++ UInt32 code = p->code; +++ const Byte *bufLimit = buf + inSize; +++ CLzmaProb *probs = p->probs; +++ unsigned state = p->state; +++ ELzmaDummy res; +++ +++ { +++ CLzmaProb *prob; +++ UInt32 bound; +++ unsigned ttt; +++ unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); +++ +++ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; +++ IF_BIT_0_CHECK(prob) +++ { +++ UPDATE_0_CHECK +++ +++ /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ +++ +++ prob = probs + Literal; +++ if (p->checkDicSize != 0 || p->processedPos != 0) +++ prob += (LZMA_LIT_SIZE * +++ ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + +++ (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); +++ +++ if (state < kNumLitStates) +++ { +++ unsigned symbol = 1; +++ do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); +++ } +++ else +++ { +++ unsigned matchByte = p->dic[p->dicPos - p->reps[0] + +++ ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; +++ unsigned offs = 0x100; +++ unsigned symbol = 1; +++ do +++ { +++ unsigned bit; +++ CLzmaProb *probLit; +++ matchByte <<= 1; +++ bit = (matchByte & offs); +++ probLit = prob + offs + bit + symbol; +++ GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) +++ } +++ while (symbol < 0x100); +++ } +++ res = DUMMY_LIT; +++ } +++ else +++ { +++ unsigned len; +++ UPDATE_1_CHECK; +++ +++ prob = probs + IsRep + state; +++ IF_BIT_0_CHECK(prob) +++ { +++ UPDATE_0_CHECK; +++ state = 0; +++ prob = probs + LenCoder; +++ res = DUMMY_MATCH; +++ } +++ else +++ { +++ UPDATE_1_CHECK; +++ res = DUMMY_REP; +++ prob = probs + IsRepG0 + state; +++ IF_BIT_0_CHECK(prob) +++ { +++ UPDATE_0_CHECK; +++ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; +++ IF_BIT_0_CHECK(prob) +++ { +++ UPDATE_0_CHECK; +++ NORMALIZE_CHECK; +++ return DUMMY_REP; +++ } +++ else +++ { +++ UPDATE_1_CHECK; +++ } +++ } +++ else +++ { +++ UPDATE_1_CHECK; +++ prob = probs + IsRepG1 + state; +++ IF_BIT_0_CHECK(prob) +++ { +++ UPDATE_0_CHECK; +++ } +++ else +++ { +++ UPDATE_1_CHECK; +++ prob = probs + IsRepG2 + state; +++ IF_BIT_0_CHECK(prob) +++ { +++ UPDATE_0_CHECK; +++ } +++ else +++ { +++ UPDATE_1_CHECK; +++ } +++ } +++ } +++ state = kNumStates; +++ prob = probs + RepLenCoder; +++ } +++ { +++ unsigned limit, offset; +++ CLzmaProb *probLen = prob + LenChoice; +++ IF_BIT_0_CHECK(probLen) +++ { +++ UPDATE_0_CHECK; +++ probLen = prob + LenLow + (posState << kLenNumLowBits); +++ offset = 0; +++ limit = 1 << kLenNumLowBits; +++ } +++ else +++ { +++ UPDATE_1_CHECK; +++ probLen = prob + LenChoice2; +++ IF_BIT_0_CHECK(probLen) +++ { +++ UPDATE_0_CHECK; +++ probLen = prob + LenMid + (posState << kLenNumMidBits); +++ offset = kLenNumLowSymbols; +++ limit = 1 << kLenNumMidBits; +++ } +++ else +++ { +++ UPDATE_1_CHECK; +++ probLen = prob + LenHigh; +++ offset = kLenNumLowSymbols + kLenNumMidSymbols; +++ limit = 1 << kLenNumHighBits; +++ } +++ } +++ TREE_DECODE_CHECK(probLen, limit, len); +++ len += offset; +++ } +++ +++ if (state < 4) +++ { +++ unsigned posSlot; +++ prob = probs + PosSlot + +++ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << +++ kNumPosSlotBits); +++ TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); +++ if (posSlot >= kStartPosModelIndex) +++ { +++ int numDirectBits = ((posSlot >> 1) - 1); +++ +++ /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ +++ +++ if (posSlot < kEndPosModelIndex) +++ { +++ prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; +++ } +++ else +++ { +++ numDirectBits -= kNumAlignBits; +++ do +++ { +++ NORMALIZE_CHECK +++ range >>= 1; +++ code -= range & (((code - range) >> 31) - 1); +++ /* if (code >= range) code -= range; */ +++ } +++ while (--numDirectBits != 0); +++ prob = probs + Align; +++ numDirectBits = kNumAlignBits; +++ } +++ { +++ unsigned i = 1; +++ do +++ { +++ GET_BIT_CHECK(prob + i, i); +++ } +++ while (--numDirectBits != 0); +++ } +++ } +++ } +++ } +++ } +++ NORMALIZE_CHECK; +++ return res; +++} +++ +++ +++static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) +++{ +++ p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); +++ p->range = 0xFFFFFFFF; +++ p->needFlush = 0; +++} +++ +++void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) +++{ +++ p->needFlush = 1; +++ p->remainLen = 0; +++ p->tempBufSize = 0; +++ +++ if (initDic) +++ { +++ p->processedPos = 0; +++ p->checkDicSize = 0; +++ p->needInitState = 1; +++ } +++ if (initState) +++ p->needInitState = 1; +++} +++ +++void LzmaDec_Init(CLzmaDec *p) +++{ +++ p->dicPos = 0; +++ LzmaDec_InitDicAndState(p, True, True); +++} +++ +++static void LzmaDec_InitStateReal(CLzmaDec *p) +++{ +++ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); +++ UInt32 i; +++ CLzmaProb *probs = p->probs; +++ for (i = 0; i < numProbs; i++) +++ probs[i] = kBitModelTotal >> 1; +++ p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; +++ p->state = 0; +++ p->needInitState = 0; +++} +++ +++SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, +++ ELzmaFinishMode finishMode, ELzmaStatus *status) +++{ +++ SizeT inSize = *srcLen; +++ (*srcLen) = 0; +++ LzmaDec_WriteRem(p, dicLimit); +++ +++ *status = LZMA_STATUS_NOT_SPECIFIED; +++ +++ while (p->remainLen != kMatchSpecLenStart) +++ { +++ int checkEndMarkNow; +++ +++ if (p->needFlush != 0) +++ { +++ for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) +++ p->tempBuf[p->tempBufSize++] = *src++; +++ if (p->tempBufSize < RC_INIT_SIZE) +++ { +++ *status = LZMA_STATUS_NEEDS_MORE_INPUT; +++ return SZ_OK; +++ } +++ if (p->tempBuf[0] != 0) +++ return SZ_ERROR_DATA; +++ +++ LzmaDec_InitRc(p, p->tempBuf); +++ p->tempBufSize = 0; +++ } +++ +++ checkEndMarkNow = 0; +++ if (p->dicPos >= dicLimit) +++ { +++ if (p->remainLen == 0 && p->code == 0) +++ { +++ *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; +++ return SZ_OK; +++ } +++ if (finishMode == LZMA_FINISH_ANY) +++ { +++ *status = LZMA_STATUS_NOT_FINISHED; +++ return SZ_OK; +++ } +++ if (p->remainLen != 0) +++ { +++ *status = LZMA_STATUS_NOT_FINISHED; +++ return SZ_ERROR_DATA; +++ } +++ checkEndMarkNow = 1; +++ } +++ +++ if (p->needInitState) +++ LzmaDec_InitStateReal(p); +++ +++ if (p->tempBufSize == 0) +++ { +++ SizeT processed; +++ const Byte *bufLimit; +++ if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) +++ { +++ int dummyRes = LzmaDec_TryDummy(p, src, inSize); +++ if (dummyRes == DUMMY_ERROR) +++ { +++ memcpy(p->tempBuf, src, inSize); +++ p->tempBufSize = (unsigned)inSize; +++ (*srcLen) += inSize; +++ *status = LZMA_STATUS_NEEDS_MORE_INPUT; +++ return SZ_OK; +++ } +++ if (checkEndMarkNow && dummyRes != DUMMY_MATCH) +++ { +++ *status = LZMA_STATUS_NOT_FINISHED; +++ return SZ_ERROR_DATA; +++ } +++ bufLimit = src; +++ } +++ else +++ bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; +++ p->buf = src; +++ if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) +++ return SZ_ERROR_DATA; +++ processed = (SizeT)(p->buf - src); +++ (*srcLen) += processed; +++ src += processed; +++ inSize -= processed; +++ } +++ else +++ { +++ unsigned rem = p->tempBufSize, lookAhead = 0; +++ while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) +++ p->tempBuf[rem++] = src[lookAhead++]; +++ p->tempBufSize = rem; +++ if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) +++ { +++ int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); +++ if (dummyRes == DUMMY_ERROR) +++ { +++ (*srcLen) += lookAhead; +++ *status = LZMA_STATUS_NEEDS_MORE_INPUT; +++ return SZ_OK; +++ } +++ if (checkEndMarkNow && dummyRes != DUMMY_MATCH) +++ { +++ *status = LZMA_STATUS_NOT_FINISHED; +++ return SZ_ERROR_DATA; +++ } +++ } +++ p->buf = p->tempBuf; +++ if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) +++ return SZ_ERROR_DATA; +++ lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); +++ (*srcLen) += lookAhead; +++ src += lookAhead; +++ inSize -= lookAhead; +++ p->tempBufSize = 0; +++ } +++ } +++ if (p->code == 0) +++ *status = LZMA_STATUS_FINISHED_WITH_MARK; +++ return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; +++} +++ +++SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) +++{ +++ SizeT outSize = *destLen; +++ SizeT inSize = *srcLen; +++ *srcLen = *destLen = 0; +++ for (;;) +++ { +++ SizeT inSizeCur = inSize, outSizeCur, dicPos; +++ ELzmaFinishMode curFinishMode; +++ SRes res; +++ if (p->dicPos == p->dicBufSize) +++ p->dicPos = 0; +++ dicPos = p->dicPos; +++ if (outSize > p->dicBufSize - dicPos) +++ { +++ outSizeCur = p->dicBufSize; +++ curFinishMode = LZMA_FINISH_ANY; +++ } +++ else +++ { +++ outSizeCur = dicPos + outSize; +++ curFinishMode = finishMode; +++ } +++ +++ res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); +++ src += inSizeCur; +++ inSize -= inSizeCur; +++ *srcLen += inSizeCur; +++ outSizeCur = p->dicPos - dicPos; +++ memcpy(dest, p->dic + dicPos, outSizeCur); +++ dest += outSizeCur; +++ outSize -= outSizeCur; +++ *destLen += outSizeCur; +++ if (res != 0) +++ return res; +++ if (outSizeCur == 0 || outSize == 0) +++ return SZ_OK; +++ } +++} +++ +++void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) +++{ +++ alloc->Free(alloc, p->probs); +++ p->probs = 0; +++} +++ +++static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) +++{ +++ alloc->Free(alloc, p->dic); +++ p->dic = 0; +++} +++ +++void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) +++{ +++ LzmaDec_FreeProbs(p, alloc); +++ LzmaDec_FreeDict(p, alloc); +++} +++ +++SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) +++{ +++ UInt32 dicSize; +++ Byte d; +++ +++ if (size < LZMA_PROPS_SIZE) +++ return SZ_ERROR_UNSUPPORTED; +++ else +++ dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); +++ +++ if (dicSize < LZMA_DIC_MIN) +++ dicSize = LZMA_DIC_MIN; +++ p->dicSize = dicSize; +++ +++ d = data[0]; +++ if (d >= (9 * 5 * 5)) +++ return SZ_ERROR_UNSUPPORTED; +++ +++ p->lc = d % 9; +++ d /= 9; +++ p->pb = d / 5; +++ p->lp = d % 5; +++ +++ return SZ_OK; +++} +++ +++static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) +++{ +++ UInt32 numProbs = LzmaProps_GetNumProbs(propNew); +++ if (p->probs == 0 || numProbs != p->numProbs) +++ { +++ LzmaDec_FreeProbs(p, alloc); +++ p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); +++ p->numProbs = numProbs; +++ if (p->probs == 0) +++ return SZ_ERROR_MEM; +++ } +++ return SZ_OK; +++} +++ +++SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) +++{ +++ CLzmaProps propNew; +++ RINOK(LzmaProps_Decode(&propNew, props, propsSize)); +++ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); +++ p->prop = propNew; +++ return SZ_OK; +++} +++ +++SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) +++{ +++ CLzmaProps propNew; +++ SizeT dicBufSize; +++ RINOK(LzmaProps_Decode(&propNew, props, propsSize)); +++ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); +++ dicBufSize = propNew.dicSize; +++ if (p->dic == 0 || dicBufSize != p->dicBufSize) +++ { +++ LzmaDec_FreeDict(p, alloc); +++ p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); +++ if (p->dic == 0) +++ { +++ LzmaDec_FreeProbs(p, alloc); +++ return SZ_ERROR_MEM; +++ } +++ } +++ p->dicBufSize = dicBufSize; +++ p->prop = propNew; +++ return SZ_OK; +++} +++ +++SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, +++ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, +++ ELzmaStatus *status, ISzAlloc *alloc) +++{ +++ CLzmaDec p; +++ SRes res; +++ SizeT inSize = *srcLen; +++ SizeT outSize = *destLen; +++ *srcLen = *destLen = 0; +++ if (inSize < RC_INIT_SIZE) +++ return SZ_ERROR_INPUT_EOF; +++ +++ LzmaDec_Construct(&p); +++ res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); +++ if (res != 0) +++ return res; +++ p.dic = dest; +++ p.dicBufSize = outSize; +++ +++ LzmaDec_Init(&p); +++ +++ *srcLen = inSize; +++ res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); +++ +++ if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) +++ res = SZ_ERROR_INPUT_EOF; +++ +++ (*destLen) = p.dicPos; +++ LzmaDec_FreeProbs(&p, alloc); +++ return res; +++} ++--- /dev/null +++++ b/lib/lzma/LzmaEnc.c ++@@ -0,0 +1,2271 @@ +++/* LzmaEnc.c -- LZMA Encoder +++2009-11-24 : Igor Pavlov : Public domain */ +++ +++#include +++ +++/* #define SHOW_STAT */ +++/* #define SHOW_STAT2 */ +++ +++#if defined(SHOW_STAT) || defined(SHOW_STAT2) +++#include +++#endif +++ +++#include "LzmaEnc.h" +++ +++/* disable MT */ +++#define _7ZIP_ST +++ +++#include "LzFind.h" +++#ifndef _7ZIP_ST +++#include "LzFindMt.h" +++#endif +++ +++#ifdef SHOW_STAT +++static int ttt = 0; +++#endif +++ +++#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1) +++ +++#define kBlockSize (9 << 10) +++#define kUnpackBlockSize (1 << 18) +++#define kMatchArraySize (1 << 21) +++#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX) +++ +++#define kNumMaxDirectBits (31) +++ +++#define kNumTopBits 24 +++#define kTopValue ((UInt32)1 << kNumTopBits) +++ +++#define kNumBitModelTotalBits 11 +++#define kBitModelTotal (1 << kNumBitModelTotalBits) +++#define kNumMoveBits 5 +++#define kProbInitValue (kBitModelTotal >> 1) +++ +++#define kNumMoveReducingBits 4 +++#define kNumBitPriceShiftBits 4 +++#define kBitPrice (1 << kNumBitPriceShiftBits) +++ +++void LzmaEncProps_Init(CLzmaEncProps *p) +++{ +++ p->level = 5; +++ p->dictSize = p->mc = 0; +++ p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; +++ p->writeEndMark = 0; +++} +++ +++void LzmaEncProps_Normalize(CLzmaEncProps *p) +++{ +++ int level = p->level; +++ if (level < 0) level = 5; +++ p->level = level; +++ if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); +++ if (p->lc < 0) p->lc = 3; +++ if (p->lp < 0) p->lp = 0; +++ if (p->pb < 0) p->pb = 2; +++ if (p->algo < 0) p->algo = (level < 5 ? 0 : 1); +++ if (p->fb < 0) p->fb = (level < 7 ? 32 : 64); +++ if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); +++ if (p->numHashBytes < 0) p->numHashBytes = 4; +++ if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1); +++ if (p->numThreads < 0) +++ p->numThreads = +++ #ifndef _7ZIP_ST +++ ((p->btMode && p->algo) ? 2 : 1); +++ #else +++ 1; +++ #endif +++} +++ +++UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) +++{ +++ CLzmaEncProps props = *props2; +++ LzmaEncProps_Normalize(&props); +++ return props.dictSize; +++} +++ +++/* #define LZMA_LOG_BSR */ +++/* Define it for Intel's CPU */ +++ +++ +++#ifdef LZMA_LOG_BSR +++ +++#define kDicLogSizeMaxCompress 30 +++ +++#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } +++ +++UInt32 GetPosSlot1(UInt32 pos) +++{ +++ UInt32 res; +++ BSR2_RET(pos, res); +++ return res; +++} +++#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } +++#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); } +++ +++#else +++ +++#define kNumLogBits (9 + (int)sizeof(size_t) / 2) +++#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) +++ +++void LzmaEnc_FastPosInit(Byte *g_FastPos) +++{ +++ int c = 2, slotFast; +++ g_FastPos[0] = 0; +++ g_FastPos[1] = 1; +++ +++ for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++) +++ { +++ UInt32 k = (1 << ((slotFast >> 1) - 1)); +++ UInt32 j; +++ for (j = 0; j < k; j++, c++) +++ g_FastPos[c] = (Byte)slotFast; +++ } +++} +++ +++#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ +++ (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ +++ res = p->g_FastPos[pos >> i] + (i * 2); } +++/* +++#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ +++ p->g_FastPos[pos >> 6] + 12 : \ +++ p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; } +++*/ +++ +++#define GetPosSlot1(pos) p->g_FastPos[pos] +++#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } +++#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); } +++ +++#endif +++ +++ +++#define LZMA_NUM_REPS 4 +++ +++typedef unsigned CState; +++ +++typedef struct +++{ +++ UInt32 price; +++ +++ CState state; +++ int prev1IsChar; +++ int prev2; +++ +++ UInt32 posPrev2; +++ UInt32 backPrev2; +++ +++ UInt32 posPrev; +++ UInt32 backPrev; +++ UInt32 backs[LZMA_NUM_REPS]; +++} COptimal; +++ +++#define kNumOpts (1 << 12) +++ +++#define kNumLenToPosStates 4 +++#define kNumPosSlotBits 6 +++#define kDicLogSizeMin 0 +++#define kDicLogSizeMax 32 +++#define kDistTableSizeMax (kDicLogSizeMax * 2) +++ +++ +++#define kNumAlignBits 4 +++#define kAlignTableSize (1 << kNumAlignBits) +++#define kAlignMask (kAlignTableSize - 1) +++ +++#define kStartPosModelIndex 4 +++#define kEndPosModelIndex 14 +++#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex) +++ +++#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) +++ +++#ifdef _LZMA_PROB32 +++#define CLzmaProb UInt32 +++#else +++#define CLzmaProb UInt16 +++#endif +++ +++#define LZMA_PB_MAX 4 +++#define LZMA_LC_MAX 8 +++#define LZMA_LP_MAX 4 +++ +++#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX) +++ +++ +++#define kLenNumLowBits 3 +++#define kLenNumLowSymbols (1 << kLenNumLowBits) +++#define kLenNumMidBits 3 +++#define kLenNumMidSymbols (1 << kLenNumMidBits) +++#define kLenNumHighBits 8 +++#define kLenNumHighSymbols (1 << kLenNumHighBits) +++ +++#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) +++ +++#define LZMA_MATCH_LEN_MIN 2 +++#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1) +++ +++#define kNumStates 12 +++ +++typedef struct +++{ +++ CLzmaProb choice; +++ CLzmaProb choice2; +++ CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits]; +++ CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits]; +++ CLzmaProb high[kLenNumHighSymbols]; +++} CLenEnc; +++ +++typedef struct +++{ +++ CLenEnc p; +++ UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal]; +++ UInt32 tableSize; +++ UInt32 counters[LZMA_NUM_PB_STATES_MAX]; +++} CLenPriceEnc; +++ +++typedef struct +++{ +++ UInt32 range; +++ Byte cache; +++ UInt64 low; +++ UInt64 cacheSize; +++ Byte *buf; +++ Byte *bufLim; +++ Byte *bufBase; +++ ISeqOutStream *outStream; +++ UInt64 processed; +++ SRes res; +++} CRangeEnc; +++ +++typedef struct +++{ +++ CLzmaProb *litProbs; +++ +++ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; +++ CLzmaProb isRep[kNumStates]; +++ CLzmaProb isRepG0[kNumStates]; +++ CLzmaProb isRepG1[kNumStates]; +++ CLzmaProb isRepG2[kNumStates]; +++ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; +++ +++ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; +++ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; +++ CLzmaProb posAlignEncoder[1 << kNumAlignBits]; +++ +++ CLenPriceEnc lenEnc; +++ CLenPriceEnc repLenEnc; +++ +++ UInt32 reps[LZMA_NUM_REPS]; +++ UInt32 state; +++} CSaveState; +++ +++typedef struct +++{ +++ IMatchFinder matchFinder; +++ void *matchFinderObj; +++ +++ #ifndef _7ZIP_ST +++ Bool mtMode; +++ CMatchFinderMt matchFinderMt; +++ #endif +++ +++ CMatchFinder matchFinderBase; +++ +++ #ifndef _7ZIP_ST +++ Byte pad[128]; +++ #endif +++ +++ UInt32 optimumEndIndex; +++ UInt32 optimumCurrentIndex; +++ +++ UInt32 longestMatchLength; +++ UInt32 numPairs; +++ UInt32 numAvail; +++ COptimal opt[kNumOpts]; +++ +++ #ifndef LZMA_LOG_BSR +++ Byte g_FastPos[1 << kNumLogBits]; +++ #endif +++ +++ UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; +++ UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1]; +++ UInt32 numFastBytes; +++ UInt32 additionalOffset; +++ UInt32 reps[LZMA_NUM_REPS]; +++ UInt32 state; +++ +++ UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; +++ UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; +++ UInt32 alignPrices[kAlignTableSize]; +++ UInt32 alignPriceCount; +++ +++ UInt32 distTableSize; +++ +++ unsigned lc, lp, pb; +++ unsigned lpMask, pbMask; +++ +++ CLzmaProb *litProbs; +++ +++ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; +++ CLzmaProb isRep[kNumStates]; +++ CLzmaProb isRepG0[kNumStates]; +++ CLzmaProb isRepG1[kNumStates]; +++ CLzmaProb isRepG2[kNumStates]; +++ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; +++ +++ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; +++ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; +++ CLzmaProb posAlignEncoder[1 << kNumAlignBits]; +++ +++ CLenPriceEnc lenEnc; +++ CLenPriceEnc repLenEnc; +++ +++ unsigned lclp; +++ +++ Bool fastMode; +++ +++ CRangeEnc rc; +++ +++ Bool writeEndMark; +++ UInt64 nowPos64; +++ UInt32 matchPriceCount; +++ Bool finished; +++ Bool multiThread; +++ +++ SRes result; +++ UInt32 dictSize; +++ UInt32 matchFinderCycles; +++ +++ int needInit; +++ +++ CSaveState saveState; +++} CLzmaEnc; +++ +++void LzmaEnc_SaveState(CLzmaEncHandle pp) +++{ +++ CLzmaEnc *p = (CLzmaEnc *)pp; +++ CSaveState *dest = &p->saveState; +++ int i; +++ dest->lenEnc = p->lenEnc; +++ dest->repLenEnc = p->repLenEnc; +++ dest->state = p->state; +++ +++ for (i = 0; i < kNumStates; i++) +++ { +++ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); +++ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); +++ } +++ for (i = 0; i < kNumLenToPosStates; i++) +++ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); +++ memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); +++ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); +++ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); +++ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); +++ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); +++ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); +++ memcpy(dest->reps, p->reps, sizeof(p->reps)); +++ memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb)); +++} +++ +++void LzmaEnc_RestoreState(CLzmaEncHandle pp) +++{ +++ CLzmaEnc *dest = (CLzmaEnc *)pp; +++ const CSaveState *p = &dest->saveState; +++ int i; +++ dest->lenEnc = p->lenEnc; +++ dest->repLenEnc = p->repLenEnc; +++ dest->state = p->state; +++ +++ for (i = 0; i < kNumStates; i++) +++ { +++ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); +++ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); +++ } +++ for (i = 0; i < kNumLenToPosStates; i++) +++ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); +++ memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); +++ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); +++ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); +++ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); +++ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); +++ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); +++ memcpy(dest->reps, p->reps, sizeof(p->reps)); +++ memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb)); +++} +++ +++SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) +++{ +++ CLzmaEnc *p = (CLzmaEnc *)pp; +++ CLzmaEncProps props = *props2; +++ LzmaEncProps_Normalize(&props); +++ +++ if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX || +++ props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30)) +++ return SZ_ERROR_PARAM; +++ p->dictSize = props.dictSize; +++ p->matchFinderCycles = props.mc; +++ { +++ unsigned fb = props.fb; +++ if (fb < 5) +++ fb = 5; +++ if (fb > LZMA_MATCH_LEN_MAX) +++ fb = LZMA_MATCH_LEN_MAX; +++ p->numFastBytes = fb; +++ } +++ p->lc = props.lc; +++ p->lp = props.lp; +++ p->pb = props.pb; +++ p->fastMode = (props.algo == 0); +++ p->matchFinderBase.btMode = props.btMode; +++ { +++ UInt32 numHashBytes = 4; +++ if (props.btMode) +++ { +++ if (props.numHashBytes < 2) +++ numHashBytes = 2; +++ else if (props.numHashBytes < 4) +++ numHashBytes = props.numHashBytes; +++ } +++ p->matchFinderBase.numHashBytes = numHashBytes; +++ } +++ +++ p->matchFinderBase.cutValue = props.mc; +++ +++ p->writeEndMark = props.writeEndMark; +++ +++ #ifndef _7ZIP_ST +++ /* +++ if (newMultiThread != _multiThread) +++ { +++ ReleaseMatchFinder(); +++ _multiThread = newMultiThread; +++ } +++ */ +++ p->multiThread = (props.numThreads > 1); +++ #endif +++ +++ return SZ_OK; +++} +++ +++static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; +++static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; +++static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; +++static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; +++ +++#define IsCharState(s) ((s) < 7) +++ +++#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1) +++ +++#define kInfinityPrice (1 << 30) +++ +++static void RangeEnc_Construct(CRangeEnc *p) +++{ +++ p->outStream = 0; +++ p->bufBase = 0; +++} +++ +++#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize) +++ +++#define RC_BUF_SIZE (1 << 16) +++static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) +++{ +++ if (p->bufBase == 0) +++ { +++ p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE); +++ if (p->bufBase == 0) +++ return 0; +++ p->bufLim = p->bufBase + RC_BUF_SIZE; +++ } +++ return 1; +++} +++ +++static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc) +++{ +++ alloc->Free(alloc, p->bufBase); +++ p->bufBase = 0; +++} +++ +++static void RangeEnc_Init(CRangeEnc *p) +++{ +++ /* Stream.Init(); */ +++ p->low = 0; +++ p->range = 0xFFFFFFFF; +++ p->cacheSize = 1; +++ p->cache = 0; +++ +++ p->buf = p->bufBase; +++ +++ p->processed = 0; +++ p->res = SZ_OK; +++} +++ +++static void RangeEnc_FlushStream(CRangeEnc *p) +++{ +++ size_t num; +++ if (p->res != SZ_OK) +++ return; +++ num = p->buf - p->bufBase; +++ if (num != p->outStream->Write(p->outStream, p->bufBase, num)) +++ p->res = SZ_ERROR_WRITE; +++ p->processed += num; +++ p->buf = p->bufBase; +++} +++ +++static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) +++{ +++ if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0) +++ { +++ Byte temp = p->cache; +++ do +++ { +++ Byte *buf = p->buf; +++ *buf++ = (Byte)(temp + (Byte)(p->low >> 32)); +++ p->buf = buf; +++ if (buf == p->bufLim) +++ RangeEnc_FlushStream(p); +++ temp = 0xFF; +++ } +++ while (--p->cacheSize != 0); +++ p->cache = (Byte)((UInt32)p->low >> 24); +++ } +++ p->cacheSize++; +++ p->low = (UInt32)p->low << 8; +++} +++ +++static void RangeEnc_FlushData(CRangeEnc *p) +++{ +++ int i; +++ for (i = 0; i < 5; i++) +++ RangeEnc_ShiftLow(p); +++} +++ +++static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits) +++{ +++ do +++ { +++ p->range >>= 1; +++ p->low += p->range & (0 - ((value >> --numBits) & 1)); +++ if (p->range < kTopValue) +++ { +++ p->range <<= 8; +++ RangeEnc_ShiftLow(p); +++ } +++ } +++ while (numBits != 0); +++} +++ +++static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol) +++{ +++ UInt32 ttt = *prob; +++ UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt; +++ if (symbol == 0) +++ { +++ p->range = newBound; +++ ttt += (kBitModelTotal - ttt) >> kNumMoveBits; +++ } +++ else +++ { +++ p->low += newBound; +++ p->range -= newBound; +++ ttt -= ttt >> kNumMoveBits; +++ } +++ *prob = (CLzmaProb)ttt; +++ if (p->range < kTopValue) +++ { +++ p->range <<= 8; +++ RangeEnc_ShiftLow(p); +++ } +++} +++ +++static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol) +++{ +++ symbol |= 0x100; +++ do +++ { +++ RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1); +++ symbol <<= 1; +++ } +++ while (symbol < 0x10000); +++} +++ +++static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte) +++{ +++ UInt32 offs = 0x100; +++ symbol |= 0x100; +++ do +++ { +++ matchByte <<= 1; +++ RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1); +++ symbol <<= 1; +++ offs &= ~(matchByte ^ symbol); +++ } +++ while (symbol < 0x10000); +++} +++ +++void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) +++{ +++ UInt32 i; +++ for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) +++ { +++ const int kCyclesBits = kNumBitPriceShiftBits; +++ UInt32 w = i; +++ UInt32 bitCount = 0; +++ int j; +++ for (j = 0; j < kCyclesBits; j++) +++ { +++ w = w * w; +++ bitCount <<= 1; +++ while (w >= ((UInt32)1 << 16)) +++ { +++ w >>= 1; +++ bitCount++; +++ } +++ } +++ ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount); +++ } +++} +++ +++ +++#define GET_PRICE(prob, symbol) \ +++ p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; +++ +++#define GET_PRICEa(prob, symbol) \ +++ ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; +++ +++#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits] +++#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] +++ +++#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits] +++#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] +++ +++static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices) +++{ +++ UInt32 price = 0; +++ symbol |= 0x100; +++ do +++ { +++ price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1); +++ symbol <<= 1; +++ } +++ while (symbol < 0x10000); +++ return price; +++} +++ +++static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices) +++{ +++ UInt32 price = 0; +++ UInt32 offs = 0x100; +++ symbol |= 0x100; +++ do +++ { +++ matchByte <<= 1; +++ price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1); +++ symbol <<= 1; +++ offs &= ~(matchByte ^ symbol); +++ } +++ while (symbol < 0x10000); +++ return price; +++} +++ +++ +++static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) +++{ +++ UInt32 m = 1; +++ int i; +++ for (i = numBitLevels; i != 0;) +++ { +++ UInt32 bit; +++ i--; +++ bit = (symbol >> i) & 1; +++ RangeEnc_EncodeBit(rc, probs + m, bit); +++ m = (m << 1) | bit; +++ } +++} +++ +++static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) +++{ +++ UInt32 m = 1; +++ int i; +++ for (i = 0; i < numBitLevels; i++) +++ { +++ UInt32 bit = symbol & 1; +++ RangeEnc_EncodeBit(rc, probs + m, bit); +++ m = (m << 1) | bit; +++ symbol >>= 1; +++ } +++} +++ +++static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) +++{ +++ UInt32 price = 0; +++ symbol |= (1 << numBitLevels); +++ while (symbol != 1) +++ { +++ price += GET_PRICEa(probs[symbol >> 1], symbol & 1); +++ symbol >>= 1; +++ } +++ return price; +++} +++ +++static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) +++{ +++ UInt32 price = 0; +++ UInt32 m = 1; +++ int i; +++ for (i = numBitLevels; i != 0; i--) +++ { +++ UInt32 bit = symbol & 1; +++ symbol >>= 1; +++ price += GET_PRICEa(probs[m], bit); +++ m = (m << 1) | bit; +++ } +++ return price; +++} +++ +++ +++static void LenEnc_Init(CLenEnc *p) +++{ +++ unsigned i; +++ p->choice = p->choice2 = kProbInitValue; +++ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++) +++ p->low[i] = kProbInitValue; +++ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++) +++ p->mid[i] = kProbInitValue; +++ for (i = 0; i < kLenNumHighSymbols; i++) +++ p->high[i] = kProbInitValue; +++} +++ +++static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState) +++{ +++ if (symbol < kLenNumLowSymbols) +++ { +++ RangeEnc_EncodeBit(rc, &p->choice, 0); +++ RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol); +++ } +++ else +++ { +++ RangeEnc_EncodeBit(rc, &p->choice, 1); +++ if (symbol < kLenNumLowSymbols + kLenNumMidSymbols) +++ { +++ RangeEnc_EncodeBit(rc, &p->choice2, 0); +++ RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols); +++ } +++ else +++ { +++ RangeEnc_EncodeBit(rc, &p->choice2, 1); +++ RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols); +++ } +++ } +++} +++ +++static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices) +++{ +++ UInt32 a0 = GET_PRICE_0a(p->choice); +++ UInt32 a1 = GET_PRICE_1a(p->choice); +++ UInt32 b0 = a1 + GET_PRICE_0a(p->choice2); +++ UInt32 b1 = a1 + GET_PRICE_1a(p->choice2); +++ UInt32 i = 0; +++ for (i = 0; i < kLenNumLowSymbols; i++) +++ { +++ if (i >= numSymbols) +++ return; +++ prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices); +++ } +++ for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++) +++ { +++ if (i >= numSymbols) +++ return; +++ prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices); +++ } +++ for (; i < numSymbols; i++) +++ prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices); +++} +++ +++static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices) +++{ +++ LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices); +++ p->counters[posState] = p->tableSize; +++} +++ +++static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices) +++{ +++ UInt32 posState; +++ for (posState = 0; posState < numPosStates; posState++) +++ LenPriceEnc_UpdateTable(p, posState, ProbPrices); +++} +++ +++static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices) +++{ +++ LenEnc_Encode(&p->p, rc, symbol, posState); +++ if (updatePrice) +++ if (--p->counters[posState] == 0) +++ LenPriceEnc_UpdateTable(p, posState, ProbPrices); +++} +++ +++ +++ +++ +++static void MovePos(CLzmaEnc *p, UInt32 num) +++{ +++ #ifdef SHOW_STAT +++ ttt += num; +++ printf("\n MovePos %d", num); +++ #endif +++ if (num != 0) +++ { +++ p->additionalOffset += num; +++ p->matchFinder.Skip(p->matchFinderObj, num); +++ } +++} +++ +++static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes) +++{ +++ UInt32 lenRes = 0, numPairs; +++ p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); +++ numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); +++ #ifdef SHOW_STAT +++ printf("\n i = %d numPairs = %d ", ttt, numPairs / 2); +++ ttt++; +++ { +++ UInt32 i; +++ for (i = 0; i < numPairs; i += 2) +++ printf("%2d %6d | ", p->matches[i], p->matches[i + 1]); +++ } +++ #endif +++ if (numPairs > 0) +++ { +++ lenRes = p->matches[numPairs - 2]; +++ if (lenRes == p->numFastBytes) +++ { +++ const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; +++ UInt32 distance = p->matches[numPairs - 1] + 1; +++ UInt32 numAvail = p->numAvail; +++ if (numAvail > LZMA_MATCH_LEN_MAX) +++ numAvail = LZMA_MATCH_LEN_MAX; +++ { +++ const Byte *pby2 = pby - distance; +++ for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++); +++ } +++ } +++ } +++ p->additionalOffset++; +++ *numDistancePairsRes = numPairs; +++ return lenRes; +++} +++ +++ +++#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False; +++#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False; +++#define IsShortRep(p) ((p)->backPrev == 0) +++ +++static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState) +++{ +++ return +++ GET_PRICE_0(p->isRepG0[state]) + +++ GET_PRICE_0(p->isRep0Long[state][posState]); +++} +++ +++static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState) +++{ +++ UInt32 price; +++ if (repIndex == 0) +++ { +++ price = GET_PRICE_0(p->isRepG0[state]); +++ price += GET_PRICE_1(p->isRep0Long[state][posState]); +++ } +++ else +++ { +++ price = GET_PRICE_1(p->isRepG0[state]); +++ if (repIndex == 1) +++ price += GET_PRICE_0(p->isRepG1[state]); +++ else +++ { +++ price += GET_PRICE_1(p->isRepG1[state]); +++ price += GET_PRICE(p->isRepG2[state], repIndex - 2); +++ } +++ } +++ return price; +++} +++ +++static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState) +++{ +++ return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] + +++ GetPureRepPrice(p, repIndex, state, posState); +++} +++ +++static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur) +++{ +++ UInt32 posMem = p->opt[cur].posPrev; +++ UInt32 backMem = p->opt[cur].backPrev; +++ p->optimumEndIndex = cur; +++ do +++ { +++ if (p->opt[cur].prev1IsChar) +++ { +++ MakeAsChar(&p->opt[posMem]) +++ p->opt[posMem].posPrev = posMem - 1; +++ if (p->opt[cur].prev2) +++ { +++ p->opt[posMem - 1].prev1IsChar = False; +++ p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2; +++ p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2; +++ } +++ } +++ { +++ UInt32 posPrev = posMem; +++ UInt32 backCur = backMem; +++ +++ backMem = p->opt[posPrev].backPrev; +++ posMem = p->opt[posPrev].posPrev; +++ +++ p->opt[posPrev].backPrev = backCur; +++ p->opt[posPrev].posPrev = cur; +++ cur = posPrev; +++ } +++ } +++ while (cur != 0); +++ *backRes = p->opt[0].backPrev; +++ p->optimumCurrentIndex = p->opt[0].posPrev; +++ return p->optimumCurrentIndex; +++} +++ +++#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300) +++ +++static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) +++{ +++ UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur; +++ UInt32 matchPrice, repMatchPrice, normalMatchPrice; +++ UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS]; +++ UInt32 *matches; +++ const Byte *data; +++ Byte curByte, matchByte; +++ if (p->optimumEndIndex != p->optimumCurrentIndex) +++ { +++ const COptimal *opt = &p->opt[p->optimumCurrentIndex]; +++ UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex; +++ *backRes = opt->backPrev; +++ p->optimumCurrentIndex = opt->posPrev; +++ return lenRes; +++ } +++ p->optimumCurrentIndex = p->optimumEndIndex = 0; +++ +++ if (p->additionalOffset == 0) +++ mainLen = ReadMatchDistances(p, &numPairs); +++ else +++ { +++ mainLen = p->longestMatchLength; +++ numPairs = p->numPairs; +++ } +++ +++ numAvail = p->numAvail; +++ if (numAvail < 2) +++ { +++ *backRes = (UInt32)(-1); +++ return 1; +++ } +++ if (numAvail > LZMA_MATCH_LEN_MAX) +++ numAvail = LZMA_MATCH_LEN_MAX; +++ +++ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; +++ repMaxIndex = 0; +++ for (i = 0; i < LZMA_NUM_REPS; i++) +++ { +++ UInt32 lenTest; +++ const Byte *data2; +++ reps[i] = p->reps[i]; +++ data2 = data - (reps[i] + 1); +++ if (data[0] != data2[0] || data[1] != data2[1]) +++ { +++ repLens[i] = 0; +++ continue; +++ } +++ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); +++ repLens[i] = lenTest; +++ if (lenTest > repLens[repMaxIndex]) +++ repMaxIndex = i; +++ } +++ if (repLens[repMaxIndex] >= p->numFastBytes) +++ { +++ UInt32 lenRes; +++ *backRes = repMaxIndex; +++ lenRes = repLens[repMaxIndex]; +++ MovePos(p, lenRes - 1); +++ return lenRes; +++ } +++ +++ matches = p->matches; +++ if (mainLen >= p->numFastBytes) +++ { +++ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; +++ MovePos(p, mainLen - 1); +++ return mainLen; +++ } +++ curByte = *data; +++ matchByte = *(data - (reps[0] + 1)); +++ +++ if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2) +++ { +++ *backRes = (UInt32)-1; +++ return 1; +++ } +++ +++ p->opt[0].state = (CState)p->state; +++ +++ posState = (position & p->pbMask); +++ +++ { +++ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); +++ p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) + +++ (!IsCharState(p->state) ? +++ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : +++ LitEnc_GetPrice(probs, curByte, p->ProbPrices)); +++ } +++ +++ MakeAsChar(&p->opt[1]); +++ +++ matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]); +++ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]); +++ +++ if (matchByte == curByte) +++ { +++ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState); +++ if (shortRepPrice < p->opt[1].price) +++ { +++ p->opt[1].price = shortRepPrice; +++ MakeAsShortRep(&p->opt[1]); +++ } +++ } +++ lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]); +++ +++ if (lenEnd < 2) +++ { +++ *backRes = p->opt[1].backPrev; +++ return 1; +++ } +++ +++ p->opt[1].posPrev = 0; +++ for (i = 0; i < LZMA_NUM_REPS; i++) +++ p->opt[0].backs[i] = reps[i]; +++ +++ len = lenEnd; +++ do +++ p->opt[len--].price = kInfinityPrice; +++ while (len >= 2); +++ +++ for (i = 0; i < LZMA_NUM_REPS; i++) +++ { +++ UInt32 repLen = repLens[i]; +++ UInt32 price; +++ if (repLen < 2) +++ continue; +++ price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState); +++ do +++ { +++ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2]; +++ COptimal *opt = &p->opt[repLen]; +++ if (curAndLenPrice < opt->price) +++ { +++ opt->price = curAndLenPrice; +++ opt->posPrev = 0; +++ opt->backPrev = i; +++ opt->prev1IsChar = False; +++ } +++ } +++ while (--repLen >= 2); +++ } +++ +++ normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]); +++ +++ len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); +++ if (len <= mainLen) +++ { +++ UInt32 offs = 0; +++ while (len > matches[offs]) +++ offs += 2; +++ for (; ; len++) +++ { +++ COptimal *opt; +++ UInt32 distance = matches[offs + 1]; +++ +++ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN]; +++ UInt32 lenToPosState = GetLenToPosState(len); +++ if (distance < kNumFullDistances) +++ curAndLenPrice += p->distancesPrices[lenToPosState][distance]; +++ else +++ { +++ UInt32 slot; +++ GetPosSlot2(distance, slot); +++ curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot]; +++ } +++ opt = &p->opt[len]; +++ if (curAndLenPrice < opt->price) +++ { +++ opt->price = curAndLenPrice; +++ opt->posPrev = 0; +++ opt->backPrev = distance + LZMA_NUM_REPS; +++ opt->prev1IsChar = False; +++ } +++ if (len == matches[offs]) +++ { +++ offs += 2; +++ if (offs == numPairs) +++ break; +++ } +++ } +++ } +++ +++ cur = 0; +++ +++ #ifdef SHOW_STAT2 +++ if (position >= 0) +++ { +++ unsigned i; +++ printf("\n pos = %4X", position); +++ for (i = cur; i <= lenEnd; i++) +++ printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price); +++ } +++ #endif +++ +++ for (;;) +++ { +++ UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen; +++ UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice; +++ Bool nextIsChar; +++ Byte curByte, matchByte; +++ const Byte *data; +++ COptimal *curOpt; +++ COptimal *nextOpt; +++ +++ cur++; +++ if (cur == lenEnd) +++ return Backward(p, backRes, cur); +++ +++ newLen = ReadMatchDistances(p, &numPairs); +++ if (newLen >= p->numFastBytes) +++ { +++ p->numPairs = numPairs; +++ p->longestMatchLength = newLen; +++ return Backward(p, backRes, cur); +++ } +++ position++; +++ curOpt = &p->opt[cur]; +++ posPrev = curOpt->posPrev; +++ if (curOpt->prev1IsChar) +++ { +++ posPrev--; +++ if (curOpt->prev2) +++ { +++ state = p->opt[curOpt->posPrev2].state; +++ if (curOpt->backPrev2 < LZMA_NUM_REPS) +++ state = kRepNextStates[state]; +++ else +++ state = kMatchNextStates[state]; +++ } +++ else +++ state = p->opt[posPrev].state; +++ state = kLiteralNextStates[state]; +++ } +++ else +++ state = p->opt[posPrev].state; +++ if (posPrev == cur - 1) +++ { +++ if (IsShortRep(curOpt)) +++ state = kShortRepNextStates[state]; +++ else +++ state = kLiteralNextStates[state]; +++ } +++ else +++ { +++ UInt32 pos; +++ const COptimal *prevOpt; +++ if (curOpt->prev1IsChar && curOpt->prev2) +++ { +++ posPrev = curOpt->posPrev2; +++ pos = curOpt->backPrev2; +++ state = kRepNextStates[state]; +++ } +++ else +++ { +++ pos = curOpt->backPrev; +++ if (pos < LZMA_NUM_REPS) +++ state = kRepNextStates[state]; +++ else +++ state = kMatchNextStates[state]; +++ } +++ prevOpt = &p->opt[posPrev]; +++ if (pos < LZMA_NUM_REPS) +++ { +++ UInt32 i; +++ reps[0] = prevOpt->backs[pos]; +++ for (i = 1; i <= pos; i++) +++ reps[i] = prevOpt->backs[i - 1]; +++ for (; i < LZMA_NUM_REPS; i++) +++ reps[i] = prevOpt->backs[i]; +++ } +++ else +++ { +++ UInt32 i; +++ reps[0] = (pos - LZMA_NUM_REPS); +++ for (i = 1; i < LZMA_NUM_REPS; i++) +++ reps[i] = prevOpt->backs[i - 1]; +++ } +++ } +++ curOpt->state = (CState)state; +++ +++ curOpt->backs[0] = reps[0]; +++ curOpt->backs[1] = reps[1]; +++ curOpt->backs[2] = reps[2]; +++ curOpt->backs[3] = reps[3]; +++ +++ curPrice = curOpt->price; +++ nextIsChar = False; +++ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; +++ curByte = *data; +++ matchByte = *(data - (reps[0] + 1)); +++ +++ posState = (position & p->pbMask); +++ +++ curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]); +++ { +++ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); +++ curAnd1Price += +++ (!IsCharState(state) ? +++ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : +++ LitEnc_GetPrice(probs, curByte, p->ProbPrices)); +++ } +++ +++ nextOpt = &p->opt[cur + 1]; +++ +++ if (curAnd1Price < nextOpt->price) +++ { +++ nextOpt->price = curAnd1Price; +++ nextOpt->posPrev = cur; +++ MakeAsChar(nextOpt); +++ nextIsChar = True; +++ } +++ +++ matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]); +++ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); +++ +++ if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0)) +++ { +++ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState); +++ if (shortRepPrice <= nextOpt->price) +++ { +++ nextOpt->price = shortRepPrice; +++ nextOpt->posPrev = cur; +++ MakeAsShortRep(nextOpt); +++ nextIsChar = True; +++ } +++ } +++ numAvailFull = p->numAvail; +++ { +++ UInt32 temp = kNumOpts - 1 - cur; +++ if (temp < numAvailFull) +++ numAvailFull = temp; +++ } +++ +++ if (numAvailFull < 2) +++ continue; +++ numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes); +++ +++ if (!nextIsChar && matchByte != curByte) /* speed optimization */ +++ { +++ /* try Literal + rep0 */ +++ UInt32 temp; +++ UInt32 lenTest2; +++ const Byte *data2 = data - (reps[0] + 1); +++ UInt32 limit = p->numFastBytes + 1; +++ if (limit > numAvailFull) +++ limit = numAvailFull; +++ +++ for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++); +++ lenTest2 = temp - 1; +++ if (lenTest2 >= 2) +++ { +++ UInt32 state2 = kLiteralNextStates[state]; +++ UInt32 posStateNext = (position + 1) & p->pbMask; +++ UInt32 nextRepMatchPrice = curAnd1Price + +++ GET_PRICE_1(p->isMatch[state2][posStateNext]) + +++ GET_PRICE_1(p->isRep[state2]); +++ /* for (; lenTest2 >= 2; lenTest2--) */ +++ { +++ UInt32 curAndLenPrice; +++ COptimal *opt; +++ UInt32 offset = cur + 1 + lenTest2; +++ while (lenEnd < offset) +++ p->opt[++lenEnd].price = kInfinityPrice; +++ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); +++ opt = &p->opt[offset]; +++ if (curAndLenPrice < opt->price) +++ { +++ opt->price = curAndLenPrice; +++ opt->posPrev = cur + 1; +++ opt->backPrev = 0; +++ opt->prev1IsChar = True; +++ opt->prev2 = False; +++ } +++ } +++ } +++ } +++ +++ startLen = 2; /* speed optimization */ +++ { +++ UInt32 repIndex; +++ for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++) +++ { +++ UInt32 lenTest; +++ UInt32 lenTestTemp; +++ UInt32 price; +++ const Byte *data2 = data - (reps[repIndex] + 1); +++ if (data[0] != data2[0] || data[1] != data2[1]) +++ continue; +++ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); +++ while (lenEnd < cur + lenTest) +++ p->opt[++lenEnd].price = kInfinityPrice; +++ lenTestTemp = lenTest; +++ price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState); +++ do +++ { +++ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2]; +++ COptimal *opt = &p->opt[cur + lenTest]; +++ if (curAndLenPrice < opt->price) +++ { +++ opt->price = curAndLenPrice; +++ opt->posPrev = cur; +++ opt->backPrev = repIndex; +++ opt->prev1IsChar = False; +++ } +++ } +++ while (--lenTest >= 2); +++ lenTest = lenTestTemp; +++ +++ if (repIndex == 0) +++ startLen = lenTest + 1; +++ +++ /* if (_maxMode) */ +++ { +++ UInt32 lenTest2 = lenTest + 1; +++ UInt32 limit = lenTest2 + p->numFastBytes; +++ UInt32 nextRepMatchPrice; +++ if (limit > numAvailFull) +++ limit = numAvailFull; +++ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); +++ lenTest2 -= lenTest + 1; +++ if (lenTest2 >= 2) +++ { +++ UInt32 state2 = kRepNextStates[state]; +++ UInt32 posStateNext = (position + lenTest) & p->pbMask; +++ UInt32 curAndLenCharPrice = +++ price + p->repLenEnc.prices[posState][lenTest - 2] + +++ GET_PRICE_0(p->isMatch[state2][posStateNext]) + +++ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), +++ data[lenTest], data2[lenTest], p->ProbPrices); +++ state2 = kLiteralNextStates[state2]; +++ posStateNext = (position + lenTest + 1) & p->pbMask; +++ nextRepMatchPrice = curAndLenCharPrice + +++ GET_PRICE_1(p->isMatch[state2][posStateNext]) + +++ GET_PRICE_1(p->isRep[state2]); +++ +++ /* for (; lenTest2 >= 2; lenTest2--) */ +++ { +++ UInt32 curAndLenPrice; +++ COptimal *opt; +++ UInt32 offset = cur + lenTest + 1 + lenTest2; +++ while (lenEnd < offset) +++ p->opt[++lenEnd].price = kInfinityPrice; +++ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); +++ opt = &p->opt[offset]; +++ if (curAndLenPrice < opt->price) +++ { +++ opt->price = curAndLenPrice; +++ opt->posPrev = cur + lenTest + 1; +++ opt->backPrev = 0; +++ opt->prev1IsChar = True; +++ opt->prev2 = True; +++ opt->posPrev2 = cur; +++ opt->backPrev2 = repIndex; +++ } +++ } +++ } +++ } +++ } +++ } +++ /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */ +++ if (newLen > numAvail) +++ { +++ newLen = numAvail; +++ for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2); +++ matches[numPairs] = newLen; +++ numPairs += 2; +++ } +++ if (newLen >= startLen) +++ { +++ UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]); +++ UInt32 offs, curBack, posSlot; +++ UInt32 lenTest; +++ while (lenEnd < cur + newLen) +++ p->opt[++lenEnd].price = kInfinityPrice; +++ +++ offs = 0; +++ while (startLen > matches[offs]) +++ offs += 2; +++ curBack = matches[offs + 1]; +++ GetPosSlot2(curBack, posSlot); +++ for (lenTest = /*2*/ startLen; ; lenTest++) +++ { +++ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN]; +++ UInt32 lenToPosState = GetLenToPosState(lenTest); +++ COptimal *opt; +++ if (curBack < kNumFullDistances) +++ curAndLenPrice += p->distancesPrices[lenToPosState][curBack]; +++ else +++ curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask]; +++ +++ opt = &p->opt[cur + lenTest]; +++ if (curAndLenPrice < opt->price) +++ { +++ opt->price = curAndLenPrice; +++ opt->posPrev = cur; +++ opt->backPrev = curBack + LZMA_NUM_REPS; +++ opt->prev1IsChar = False; +++ } +++ +++ if (/*_maxMode && */lenTest == matches[offs]) +++ { +++ /* Try Match + Literal + Rep0 */ +++ const Byte *data2 = data - (curBack + 1); +++ UInt32 lenTest2 = lenTest + 1; +++ UInt32 limit = lenTest2 + p->numFastBytes; +++ UInt32 nextRepMatchPrice; +++ if (limit > numAvailFull) +++ limit = numAvailFull; +++ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); +++ lenTest2 -= lenTest + 1; +++ if (lenTest2 >= 2) +++ { +++ UInt32 state2 = kMatchNextStates[state]; +++ UInt32 posStateNext = (position + lenTest) & p->pbMask; +++ UInt32 curAndLenCharPrice = curAndLenPrice + +++ GET_PRICE_0(p->isMatch[state2][posStateNext]) + +++ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), +++ data[lenTest], data2[lenTest], p->ProbPrices); +++ state2 = kLiteralNextStates[state2]; +++ posStateNext = (posStateNext + 1) & p->pbMask; +++ nextRepMatchPrice = curAndLenCharPrice + +++ GET_PRICE_1(p->isMatch[state2][posStateNext]) + +++ GET_PRICE_1(p->isRep[state2]); +++ +++ /* for (; lenTest2 >= 2; lenTest2--) */ +++ { +++ UInt32 offset = cur + lenTest + 1 + lenTest2; +++ UInt32 curAndLenPrice; +++ COptimal *opt; +++ while (lenEnd < offset) +++ p->opt[++lenEnd].price = kInfinityPrice; +++ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); +++ opt = &p->opt[offset]; +++ if (curAndLenPrice < opt->price) +++ { +++ opt->price = curAndLenPrice; +++ opt->posPrev = cur + lenTest + 1; +++ opt->backPrev = 0; +++ opt->prev1IsChar = True; +++ opt->prev2 = True; +++ opt->posPrev2 = cur; +++ opt->backPrev2 = curBack + LZMA_NUM_REPS; +++ } +++ } +++ } +++ offs += 2; +++ if (offs == numPairs) +++ break; +++ curBack = matches[offs + 1]; +++ if (curBack >= kNumFullDistances) +++ GetPosSlot2(curBack, posSlot); +++ } +++ } +++ } +++ } +++} +++ +++#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist)) +++ +++static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) +++{ +++ UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i; +++ const Byte *data; +++ const UInt32 *matches; +++ +++ if (p->additionalOffset == 0) +++ mainLen = ReadMatchDistances(p, &numPairs); +++ else +++ { +++ mainLen = p->longestMatchLength; +++ numPairs = p->numPairs; +++ } +++ +++ numAvail = p->numAvail; +++ *backRes = (UInt32)-1; +++ if (numAvail < 2) +++ return 1; +++ if (numAvail > LZMA_MATCH_LEN_MAX) +++ numAvail = LZMA_MATCH_LEN_MAX; +++ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; +++ +++ repLen = repIndex = 0; +++ for (i = 0; i < LZMA_NUM_REPS; i++) +++ { +++ UInt32 len; +++ const Byte *data2 = data - (p->reps[i] + 1); +++ if (data[0] != data2[0] || data[1] != data2[1]) +++ continue; +++ for (len = 2; len < numAvail && data[len] == data2[len]; len++); +++ if (len >= p->numFastBytes) +++ { +++ *backRes = i; +++ MovePos(p, len - 1); +++ return len; +++ } +++ if (len > repLen) +++ { +++ repIndex = i; +++ repLen = len; +++ } +++ } +++ +++ matches = p->matches; +++ if (mainLen >= p->numFastBytes) +++ { +++ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; +++ MovePos(p, mainLen - 1); +++ return mainLen; +++ } +++ +++ mainDist = 0; /* for GCC */ +++ if (mainLen >= 2) +++ { +++ mainDist = matches[numPairs - 1]; +++ while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1) +++ { +++ if (!ChangePair(matches[numPairs - 3], mainDist)) +++ break; +++ numPairs -= 2; +++ mainLen = matches[numPairs - 2]; +++ mainDist = matches[numPairs - 1]; +++ } +++ if (mainLen == 2 && mainDist >= 0x80) +++ mainLen = 1; +++ } +++ +++ if (repLen >= 2 && ( +++ (repLen + 1 >= mainLen) || +++ (repLen + 2 >= mainLen && mainDist >= (1 << 9)) || +++ (repLen + 3 >= mainLen && mainDist >= (1 << 15)))) +++ { +++ *backRes = repIndex; +++ MovePos(p, repLen - 1); +++ return repLen; +++ } +++ +++ if (mainLen < 2 || numAvail <= 2) +++ return 1; +++ +++ p->longestMatchLength = ReadMatchDistances(p, &p->numPairs); +++ if (p->longestMatchLength >= 2) +++ { +++ UInt32 newDistance = matches[p->numPairs - 1]; +++ if ((p->longestMatchLength >= mainLen && newDistance < mainDist) || +++ (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) || +++ (p->longestMatchLength > mainLen + 1) || +++ (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist))) +++ return 1; +++ } +++ +++ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; +++ for (i = 0; i < LZMA_NUM_REPS; i++) +++ { +++ UInt32 len, limit; +++ const Byte *data2 = data - (p->reps[i] + 1); +++ if (data[0] != data2[0] || data[1] != data2[1]) +++ continue; +++ limit = mainLen - 1; +++ for (len = 2; len < limit && data[len] == data2[len]; len++); +++ if (len >= limit) +++ return 1; +++ } +++ *backRes = mainDist + LZMA_NUM_REPS; +++ MovePos(p, mainLen - 2); +++ return mainLen; +++} +++ +++static void WriteEndMarker(CLzmaEnc *p, UInt32 posState) +++{ +++ UInt32 len; +++ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); +++ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); +++ p->state = kMatchNextStates[p->state]; +++ len = LZMA_MATCH_LEN_MIN; +++ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); +++ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1); +++ RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits); +++ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask); +++} +++ +++static SRes CheckErrors(CLzmaEnc *p) +++{ +++ if (p->result != SZ_OK) +++ return p->result; +++ if (p->rc.res != SZ_OK) +++ p->result = SZ_ERROR_WRITE; +++ if (p->matchFinderBase.result != SZ_OK) +++ p->result = SZ_ERROR_READ; +++ if (p->result != SZ_OK) +++ p->finished = True; +++ return p->result; +++} +++ +++static SRes Flush(CLzmaEnc *p, UInt32 nowPos) +++{ +++ /* ReleaseMFStream(); */ +++ p->finished = True; +++ if (p->writeEndMark) +++ WriteEndMarker(p, nowPos & p->pbMask); +++ RangeEnc_FlushData(&p->rc); +++ RangeEnc_FlushStream(&p->rc); +++ return CheckErrors(p); +++} +++ +++static void FillAlignPrices(CLzmaEnc *p) +++{ +++ UInt32 i; +++ for (i = 0; i < kAlignTableSize; i++) +++ p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices); +++ p->alignPriceCount = 0; +++} +++ +++static void FillDistancesPrices(CLzmaEnc *p) +++{ +++ UInt32 tempPrices[kNumFullDistances]; +++ UInt32 i, lenToPosState; +++ for (i = kStartPosModelIndex; i < kNumFullDistances; i++) +++ { +++ UInt32 posSlot = GetPosSlot1(i); +++ UInt32 footerBits = ((posSlot >> 1) - 1); +++ UInt32 base = ((2 | (posSlot & 1)) << footerBits); +++ tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices); +++ } +++ +++ for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) +++ { +++ UInt32 posSlot; +++ const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState]; +++ UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState]; +++ for (posSlot = 0; posSlot < p->distTableSize; posSlot++) +++ posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices); +++ for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++) +++ posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits); +++ +++ { +++ UInt32 *distancesPrices = p->distancesPrices[lenToPosState]; +++ UInt32 i; +++ for (i = 0; i < kStartPosModelIndex; i++) +++ distancesPrices[i] = posSlotPrices[i]; +++ for (; i < kNumFullDistances; i++) +++ distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i]; +++ } +++ } +++ p->matchPriceCount = 0; +++} +++ +++void LzmaEnc_Construct(CLzmaEnc *p) +++{ +++ RangeEnc_Construct(&p->rc); +++ MatchFinder_Construct(&p->matchFinderBase); +++ #ifndef _7ZIP_ST +++ MatchFinderMt_Construct(&p->matchFinderMt); +++ p->matchFinderMt.MatchFinder = &p->matchFinderBase; +++ #endif +++ +++ { +++ CLzmaEncProps props; +++ LzmaEncProps_Init(&props); +++ LzmaEnc_SetProps(p, &props); +++ } +++ +++ #ifndef LZMA_LOG_BSR +++ LzmaEnc_FastPosInit(p->g_FastPos); +++ #endif +++ +++ LzmaEnc_InitPriceTables(p->ProbPrices); +++ p->litProbs = 0; +++ p->saveState.litProbs = 0; +++} +++ +++CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) +++{ +++ void *p; +++ p = alloc->Alloc(alloc, sizeof(CLzmaEnc)); +++ if (p != 0) +++ LzmaEnc_Construct((CLzmaEnc *)p); +++ return p; +++} +++ +++void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) +++{ +++ alloc->Free(alloc, p->litProbs); +++ alloc->Free(alloc, p->saveState.litProbs); +++ p->litProbs = 0; +++ p->saveState.litProbs = 0; +++} +++ +++void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) +++{ +++ #ifndef _7ZIP_ST +++ MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); +++ #endif +++ MatchFinder_Free(&p->matchFinderBase, allocBig); +++ LzmaEnc_FreeLits(p, alloc); +++ RangeEnc_Free(&p->rc, alloc); +++} +++ +++void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig) +++{ +++ LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig); +++ alloc->Free(alloc, p); +++} +++ +++static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize) +++{ +++ UInt32 nowPos32, startPos32; +++ if (p->needInit) +++ { +++ p->matchFinder.Init(p->matchFinderObj); +++ p->needInit = 0; +++ } +++ +++ if (p->finished) +++ return p->result; +++ RINOK(CheckErrors(p)); +++ +++ nowPos32 = (UInt32)p->nowPos64; +++ startPos32 = nowPos32; +++ +++ if (p->nowPos64 == 0) +++ { +++ UInt32 numPairs; +++ Byte curByte; +++ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) +++ return Flush(p, nowPos32); +++ ReadMatchDistances(p, &numPairs); +++ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0); +++ p->state = kLiteralNextStates[p->state]; +++ curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset); +++ LitEnc_Encode(&p->rc, p->litProbs, curByte); +++ p->additionalOffset--; +++ nowPos32++; +++ } +++ +++ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0) +++ for (;;) +++ { +++ UInt32 pos, len, posState; +++ +++ if (p->fastMode) +++ len = GetOptimumFast(p, &pos); +++ else +++ len = GetOptimum(p, nowPos32, &pos); +++ +++ #ifdef SHOW_STAT2 +++ printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos); +++ #endif +++ +++ posState = nowPos32 & p->pbMask; +++ if (len == 1 && pos == (UInt32)-1) +++ { +++ Byte curByte; +++ CLzmaProb *probs; +++ const Byte *data; +++ +++ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0); +++ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; +++ curByte = *data; +++ probs = LIT_PROBS(nowPos32, *(data - 1)); +++ if (IsCharState(p->state)) +++ LitEnc_Encode(&p->rc, probs, curByte); +++ else +++ LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1)); +++ p->state = kLiteralNextStates[p->state]; +++ } +++ else +++ { +++ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); +++ if (pos < LZMA_NUM_REPS) +++ { +++ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1); +++ if (pos == 0) +++ { +++ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0); +++ RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1)); +++ } +++ else +++ { +++ UInt32 distance = p->reps[pos]; +++ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1); +++ if (pos == 1) +++ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0); +++ else +++ { +++ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1); +++ RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2); +++ if (pos == 3) +++ p->reps[3] = p->reps[2]; +++ p->reps[2] = p->reps[1]; +++ } +++ p->reps[1] = p->reps[0]; +++ p->reps[0] = distance; +++ } +++ if (len == 1) +++ p->state = kShortRepNextStates[p->state]; +++ else +++ { +++ LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); +++ p->state = kRepNextStates[p->state]; +++ } +++ } +++ else +++ { +++ UInt32 posSlot; +++ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); +++ p->state = kMatchNextStates[p->state]; +++ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); +++ pos -= LZMA_NUM_REPS; +++ GetPosSlot(pos, posSlot); +++ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); +++ +++ if (posSlot >= kStartPosModelIndex) +++ { +++ UInt32 footerBits = ((posSlot >> 1) - 1); +++ UInt32 base = ((2 | (posSlot & 1)) << footerBits); +++ UInt32 posReduced = pos - base; +++ +++ if (posSlot < kEndPosModelIndex) +++ RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced); +++ else +++ { +++ RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits); +++ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask); +++ p->alignPriceCount++; +++ } +++ } +++ p->reps[3] = p->reps[2]; +++ p->reps[2] = p->reps[1]; +++ p->reps[1] = p->reps[0]; +++ p->reps[0] = pos; +++ p->matchPriceCount++; +++ } +++ } +++ p->additionalOffset -= len; +++ nowPos32 += len; +++ if (p->additionalOffset == 0) +++ { +++ UInt32 processed; +++ if (!p->fastMode) +++ { +++ if (p->matchPriceCount >= (1 << 7)) +++ FillDistancesPrices(p); +++ if (p->alignPriceCount >= kAlignTableSize) +++ FillAlignPrices(p); +++ } +++ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) +++ break; +++ processed = nowPos32 - startPos32; +++ if (useLimits) +++ { +++ if (processed + kNumOpts + 300 >= maxUnpackSize || +++ RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize) +++ break; +++ } +++ else if (processed >= (1 << 15)) +++ { +++ p->nowPos64 += nowPos32 - startPos32; +++ return CheckErrors(p); +++ } +++ } +++ } +++ p->nowPos64 += nowPos32 - startPos32; +++ return Flush(p, nowPos32); +++} +++ +++#define kBigHashDicLimit ((UInt32)1 << 24) +++ +++static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +++{ +++ UInt32 beforeSize = kNumOpts; +++ Bool btMode; +++ if (!RangeEnc_Alloc(&p->rc, alloc)) +++ return SZ_ERROR_MEM; +++ btMode = (p->matchFinderBase.btMode != 0); +++ #ifndef _7ZIP_ST +++ p->mtMode = (p->multiThread && !p->fastMode && btMode); +++ #endif +++ +++ { +++ unsigned lclp = p->lc + p->lp; +++ if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp) +++ { +++ LzmaEnc_FreeLits(p, alloc); +++ p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); +++ p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); +++ if (p->litProbs == 0 || p->saveState.litProbs == 0) +++ { +++ LzmaEnc_FreeLits(p, alloc); +++ return SZ_ERROR_MEM; +++ } +++ p->lclp = lclp; +++ } +++ } +++ +++ p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit); +++ +++ if (beforeSize + p->dictSize < keepWindowSize) +++ beforeSize = keepWindowSize - p->dictSize; +++ +++ #ifndef _7ZIP_ST +++ if (p->mtMode) +++ { +++ RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)); +++ p->matchFinderObj = &p->matchFinderMt; +++ MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); +++ } +++ else +++ #endif +++ { +++ if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)) +++ return SZ_ERROR_MEM; +++ p->matchFinderObj = &p->matchFinderBase; +++ MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); +++ } +++ return SZ_OK; +++} +++ +++void LzmaEnc_Init(CLzmaEnc *p) +++{ +++ UInt32 i; +++ p->state = 0; +++ for (i = 0 ; i < LZMA_NUM_REPS; i++) +++ p->reps[i] = 0; +++ +++ RangeEnc_Init(&p->rc); +++ +++ +++ for (i = 0; i < kNumStates; i++) +++ { +++ UInt32 j; +++ for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++) +++ { +++ p->isMatch[i][j] = kProbInitValue; +++ p->isRep0Long[i][j] = kProbInitValue; +++ } +++ p->isRep[i] = kProbInitValue; +++ p->isRepG0[i] = kProbInitValue; +++ p->isRepG1[i] = kProbInitValue; +++ p->isRepG2[i] = kProbInitValue; +++ } +++ +++ { +++ UInt32 num = 0x300 << (p->lp + p->lc); +++ for (i = 0; i < num; i++) +++ p->litProbs[i] = kProbInitValue; +++ } +++ +++ { +++ for (i = 0; i < kNumLenToPosStates; i++) +++ { +++ CLzmaProb *probs = p->posSlotEncoder[i]; +++ UInt32 j; +++ for (j = 0; j < (1 << kNumPosSlotBits); j++) +++ probs[j] = kProbInitValue; +++ } +++ } +++ { +++ for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) +++ p->posEncoders[i] = kProbInitValue; +++ } +++ +++ LenEnc_Init(&p->lenEnc.p); +++ LenEnc_Init(&p->repLenEnc.p); +++ +++ for (i = 0; i < (1 << kNumAlignBits); i++) +++ p->posAlignEncoder[i] = kProbInitValue; +++ +++ p->optimumEndIndex = 0; +++ p->optimumCurrentIndex = 0; +++ p->additionalOffset = 0; +++ +++ p->pbMask = (1 << p->pb) - 1; +++ p->lpMask = (1 << p->lp) - 1; +++} +++ +++void LzmaEnc_InitPrices(CLzmaEnc *p) +++{ +++ if (!p->fastMode) +++ { +++ FillDistancesPrices(p); +++ FillAlignPrices(p); +++ } +++ +++ p->lenEnc.tableSize = +++ p->repLenEnc.tableSize = +++ p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN; +++ LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices); +++ LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices); +++} +++ +++static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +++{ +++ UInt32 i; +++ for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++) +++ if (p->dictSize <= ((UInt32)1 << i)) +++ break; +++ p->distTableSize = i * 2; +++ +++ p->finished = False; +++ p->result = SZ_OK; +++ RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)); +++ LzmaEnc_Init(p); +++ LzmaEnc_InitPrices(p); +++ p->nowPos64 = 0; +++ return SZ_OK; +++} +++ +++static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, +++ ISzAlloc *alloc, ISzAlloc *allocBig) +++{ +++ CLzmaEnc *p = (CLzmaEnc *)pp; +++ p->matchFinderBase.stream = inStream; +++ p->needInit = 1; +++ p->rc.outStream = outStream; +++ return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); +++} +++ +++SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, +++ ISeqInStream *inStream, UInt32 keepWindowSize, +++ ISzAlloc *alloc, ISzAlloc *allocBig) +++{ +++ CLzmaEnc *p = (CLzmaEnc *)pp; +++ p->matchFinderBase.stream = inStream; +++ p->needInit = 1; +++ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); +++} +++ +++static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) +++{ +++ p->matchFinderBase.directInput = 1; +++ p->matchFinderBase.bufferBase = (Byte *)src; +++ p->matchFinderBase.directInputRem = srcLen; +++} +++ +++SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, +++ UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +++{ +++ CLzmaEnc *p = (CLzmaEnc *)pp; +++ LzmaEnc_SetInputBuf(p, src, srcLen); +++ p->needInit = 1; +++ +++ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); +++} +++ +++void LzmaEnc_Finish(CLzmaEncHandle pp) +++{ +++ #ifndef _7ZIP_ST +++ CLzmaEnc *p = (CLzmaEnc *)pp; +++ if (p->mtMode) +++ MatchFinderMt_ReleaseStream(&p->matchFinderMt); +++ #else +++ pp = pp; +++ #endif +++} +++ +++typedef struct +++{ +++ ISeqOutStream funcTable; +++ Byte *data; +++ SizeT rem; +++ Bool overflow; +++} CSeqOutStreamBuf; +++ +++static size_t MyWrite(void *pp, const void *data, size_t size) +++{ +++ CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp; +++ if (p->rem < size) +++ { +++ size = p->rem; +++ p->overflow = True; +++ } +++ memcpy(p->data, data, size); +++ p->rem -= size; +++ p->data += size; +++ return size; +++} +++ +++ +++UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) +++{ +++ const CLzmaEnc *p = (CLzmaEnc *)pp; +++ return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); +++} +++ +++const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) +++{ +++ const CLzmaEnc *p = (CLzmaEnc *)pp; +++ return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; +++} +++ +++SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, +++ Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) +++{ +++ CLzmaEnc *p = (CLzmaEnc *)pp; +++ UInt64 nowPos64; +++ SRes res; +++ CSeqOutStreamBuf outStream; +++ +++ outStream.funcTable.Write = MyWrite; +++ outStream.data = dest; +++ outStream.rem = *destLen; +++ outStream.overflow = False; +++ +++ p->writeEndMark = False; +++ p->finished = False; +++ p->result = SZ_OK; +++ +++ if (reInit) +++ LzmaEnc_Init(p); +++ LzmaEnc_InitPrices(p); +++ nowPos64 = p->nowPos64; +++ RangeEnc_Init(&p->rc); +++ p->rc.outStream = &outStream.funcTable; +++ +++ res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize); +++ +++ *unpackSize = (UInt32)(p->nowPos64 - nowPos64); +++ *destLen -= outStream.rem; +++ if (outStream.overflow) +++ return SZ_ERROR_OUTPUT_EOF; +++ +++ return res; +++} +++ +++static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) +++{ +++ SRes res = SZ_OK; +++ +++ #ifndef _7ZIP_ST +++ Byte allocaDummy[0x300]; +++ int i = 0; +++ for (i = 0; i < 16; i++) +++ allocaDummy[i] = (Byte)i; +++ #endif +++ +++ for (;;) +++ { +++ res = LzmaEnc_CodeOneBlock(p, False, 0, 0); +++ if (res != SZ_OK || p->finished != 0) +++ break; +++ if (progress != 0) +++ { +++ res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); +++ if (res != SZ_OK) +++ { +++ res = SZ_ERROR_PROGRESS; +++ break; +++ } +++ } +++ } +++ LzmaEnc_Finish(p); +++ return res; +++} +++ +++SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, +++ ISzAlloc *alloc, ISzAlloc *allocBig) +++{ +++ RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig)); +++ return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); +++} +++ +++SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) +++{ +++ CLzmaEnc *p = (CLzmaEnc *)pp; +++ int i; +++ UInt32 dictSize = p->dictSize; +++ if (*size < LZMA_PROPS_SIZE) +++ return SZ_ERROR_PARAM; +++ *size = LZMA_PROPS_SIZE; +++ props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); +++ +++ for (i = 11; i <= 30; i++) +++ { +++ if (dictSize <= ((UInt32)2 << i)) +++ { +++ dictSize = (2 << i); +++ break; +++ } +++ if (dictSize <= ((UInt32)3 << i)) +++ { +++ dictSize = (3 << i); +++ break; +++ } +++ } +++ +++ for (i = 0; i < 4; i++) +++ props[1 + i] = (Byte)(dictSize >> (8 * i)); +++ return SZ_OK; +++} +++ +++SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, +++ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) +++{ +++ SRes res; +++ CLzmaEnc *p = (CLzmaEnc *)pp; +++ +++ CSeqOutStreamBuf outStream; +++ +++ LzmaEnc_SetInputBuf(p, src, srcLen); +++ +++ outStream.funcTable.Write = MyWrite; +++ outStream.data = dest; +++ outStream.rem = *destLen; +++ outStream.overflow = False; +++ +++ p->writeEndMark = writeEndMark; +++ +++ p->rc.outStream = &outStream.funcTable; +++ res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); +++ if (res == SZ_OK) +++ res = LzmaEnc_Encode2(p, progress); +++ +++ *destLen -= outStream.rem; +++ if (outStream.overflow) +++ return SZ_ERROR_OUTPUT_EOF; +++ return res; +++} +++ +++SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, +++ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, +++ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) +++{ +++ CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); +++ SRes res; +++ if (p == 0) +++ return SZ_ERROR_MEM; +++ +++ res = LzmaEnc_SetProps(p, props); +++ if (res == SZ_OK) +++ { +++ res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); +++ if (res == SZ_OK) +++ res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, +++ writeEndMark, progress, alloc, allocBig); +++ } +++ +++ LzmaEnc_Destroy(p, alloc, allocBig); +++ return res; +++} ++--- /dev/null +++++ b/lib/lzma/Makefile ++@@ -0,0 +1,7 @@ +++lzma_compress-objs := LzFind.o LzmaEnc.o +++lzma_decompress-objs := LzmaDec.o +++ +++obj-$(CONFIG_LZMA_COMPRESS) += lzma_compress.o +++obj-$(CONFIG_LZMA_DECOMPRESS) += lzma_decompress.o +++ +++EXTRA_CFLAGS += -Iinclude/linux -Iinclude/linux/lzma -include types.h +diff --git a/target/linux/generic/pending-5.10/532-jffs2_eofdetect.patch b/target/linux/generic/pending-5.10/532-jffs2_eofdetect.patch +new file mode 100644 +index 0000000000..a1d7dc1a69 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/532-jffs2_eofdetect.patch +@@ -0,0 +1,65 @@ ++From: Felix Fietkau ++Subject: fs: jffs2: EOF marker ++ ++Signed-off-by: Felix Fietkau ++--- ++ fs/jffs2/build.c | 10 ++++++++++ ++ fs/jffs2/scan.c | 21 +++++++++++++++++++-- ++ 2 files changed, 29 insertions(+), 2 deletions(-) ++ ++--- a/fs/jffs2/build.c +++++ b/fs/jffs2/build.c ++@@ -117,6 +117,16 @@ static int jffs2_build_filesystem(struct ++ dbg_fsbuild("scanned flash completely\n"); ++ jffs2_dbg_dump_block_lists_nolock(c); ++ +++ if (c->flags & (1 << 7)) { +++ printk("%s(): unlocking the mtd device... ", __func__); +++ mtd_unlock(c->mtd, 0, c->mtd->size); +++ printk("done.\n"); +++ +++ printk("%s(): erasing all blocks after the end marker... ", __func__); +++ jffs2_erase_pending_blocks(c, -1); +++ printk("done.\n"); +++ } +++ ++ dbg_fsbuild("pass 1 starting\n"); ++ c->flags |= JFFS2_SB_FLAG_BUILDING; ++ /* Now scan the directory tree, increasing nlink according to every dirent found. */ ++--- a/fs/jffs2/scan.c +++++ b/fs/jffs2/scan.c ++@@ -148,8 +148,14 @@ int jffs2_scan_medium(struct jffs2_sb_in ++ /* reset summary info for next eraseblock scan */ ++ jffs2_sum_reset_collected(s); ++ ++- ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), ++- buf_size, s); +++ if (c->flags & (1 << 7)) { +++ if (mtd_block_isbad(c->mtd, jeb->offset)) +++ ret = BLK_STATE_BADBLOCK; +++ else +++ ret = BLK_STATE_ALLFF; +++ } else +++ ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), +++ buf_size, s); ++ ++ if (ret < 0) ++ goto out; ++@@ -565,6 +571,17 @@ full_scan: ++ return err; ++ } ++ +++ if ((buf[0] == 0xde) && +++ (buf[1] == 0xad) && +++ (buf[2] == 0xc0) && +++ (buf[3] == 0xde)) { +++ /* end of filesystem. erase everything after this point */ +++ printk("%s(): End of filesystem marker found at 0x%x\n", __func__, jeb->offset); +++ c->flags |= (1 << 7); +++ +++ return BLK_STATE_ALLFF; +++ } +++ ++ /* We temporarily use 'ofs' as a pointer into the buffer/jeb */ ++ ofs = 0; ++ max_ofs = EMPTY_SCAN_SIZE(c->sector_size); +diff --git a/target/linux/generic/pending-5.10/600-netfilter_conntrack_flush.patch b/target/linux/generic/pending-5.10/600-netfilter_conntrack_flush.patch +new file mode 100644 +index 0000000000..f82849c356 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/600-netfilter_conntrack_flush.patch +@@ -0,0 +1,88 @@ ++From: Felix Fietkau ++Subject: netfilter: add support for flushing conntrack via /proc ++ ++lede-commit 8193bbe59a74d34d6a26d4a8cb857b1952905314 ++Signed-off-by: Felix Fietkau ++--- ++ net/netfilter/nf_conntrack_standalone.c | 59 ++++++++++++++++++++++++++++++++- ++ 1 file changed, 58 insertions(+), 1 deletion(-) ++ ++--- a/net/netfilter/nf_conntrack_standalone.c +++++ b/net/netfilter/nf_conntrack_standalone.c ++@@ -9,6 +9,7 @@ ++ #include ++ #include ++ #include +++#include ++ #include ++ #ifdef CONFIG_SYSCTL ++ #include ++@@ -456,6 +457,56 @@ static int ct_cpu_seq_show(struct seq_fi ++ return 0; ++ } ++ +++struct kill_request { +++ u16 family; +++ union nf_inet_addr addr; +++}; +++ +++static int kill_matching(struct nf_conn *i, void *data) +++{ +++ struct kill_request *kr = data; +++ struct nf_conntrack_tuple *t1 = &i->tuplehash[IP_CT_DIR_ORIGINAL].tuple; +++ struct nf_conntrack_tuple *t2 = &i->tuplehash[IP_CT_DIR_REPLY].tuple; +++ +++ if (!kr->family) +++ return 1; +++ +++ if (t1->src.l3num != kr->family) +++ return 0; +++ +++ return (nf_inet_addr_cmp(&kr->addr, &t1->src.u3) || +++ nf_inet_addr_cmp(&kr->addr, &t1->dst.u3) || +++ nf_inet_addr_cmp(&kr->addr, &t2->src.u3) || +++ nf_inet_addr_cmp(&kr->addr, &t2->dst.u3)); +++} +++ +++static int ct_file_write(struct file *file, char *buf, size_t count) +++{ +++ struct seq_file *seq = file->private_data; +++ struct net *net = seq_file_net(seq); +++ struct kill_request kr = { }; +++ +++ if (count == 0) +++ return 0; +++ +++ if (count >= INET6_ADDRSTRLEN) +++ count = INET6_ADDRSTRLEN - 1; +++ +++ if (strnchr(buf, count, ':')) { +++ kr.family = AF_INET6; +++ if (!in6_pton(buf, count, (void *)&kr.addr, '\n', NULL)) +++ return -EINVAL; +++ } else if (strnchr(buf, count, '.')) { +++ kr.family = AF_INET; +++ if (!in4_pton(buf, count, (void *)&kr.addr, '\n', NULL)) +++ return -EINVAL; +++ } +++ +++ nf_ct_iterate_cleanup_net(net, kill_matching, &kr, 0, 0); +++ +++ return 0; +++} +++ ++ static const struct seq_operations ct_cpu_seq_ops = { ++ .start = ct_cpu_seq_start, ++ .next = ct_cpu_seq_next, ++@@ -469,8 +520,9 @@ static int nf_conntrack_standalone_init_ ++ kuid_t root_uid; ++ kgid_t root_gid; ++ ++- pde = proc_create_net("nf_conntrack", 0440, net->proc_net, &ct_seq_ops, ++- sizeof(struct ct_iter_state)); +++ pde = proc_create_net_data_write("nf_conntrack", 0440, net->proc_net, +++ &ct_seq_ops, &ct_file_write, +++ sizeof(struct ct_iter_state), NULL); ++ if (!pde) ++ goto out_nf_conntrack; ++ +diff --git a/target/linux/generic/pending-5.10/610-netfilter_match_bypass_default_checks.patch b/target/linux/generic/pending-5.10/610-netfilter_match_bypass_default_checks.patch +new file mode 100644 +index 0000000000..04f9ba2f08 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/610-netfilter_match_bypass_default_checks.patch +@@ -0,0 +1,110 @@ ++From: Felix Fietkau ++Subject: kernel: add a new version of my netfilter speedup patches for linux 2.6.39 and 3.0 ++ ++Signed-off-by: Felix Fietkau ++--- ++ include/uapi/linux/netfilter_ipv4/ip_tables.h | 1 + ++ net/ipv4/netfilter/ip_tables.c | 37 +++++++++++++++++++++++++++ ++ 2 files changed, 38 insertions(+) ++ ++--- a/include/uapi/linux/netfilter_ipv4/ip_tables.h +++++ b/include/uapi/linux/netfilter_ipv4/ip_tables.h ++@@ -89,6 +89,7 @@ struct ipt_ip { ++ #define IPT_F_FRAG 0x01 /* Set if rule is a fragment rule */ ++ #define IPT_F_GOTO 0x02 /* Set if jump is a goto */ ++ #define IPT_F_MASK 0x03 /* All possible flag bits mask. */ +++#define IPT_F_NO_DEF_MATCH 0x80 /* Internal: no default match rules present */ ++ ++ /* Values for "inv" field in struct ipt_ip. */ ++ #define IPT_INV_VIA_IN 0x01 /* Invert the sense of IN IFACE. */ ++--- a/net/ipv4/netfilter/ip_tables.c +++++ b/net/ipv4/netfilter/ip_tables.c ++@@ -50,6 +50,9 @@ ip_packet_match(const struct iphdr *ip, ++ { ++ unsigned long ret; ++ +++ if (ipinfo->flags & IPT_F_NO_DEF_MATCH) +++ return true; +++ ++ if (NF_INVF(ipinfo, IPT_INV_SRCIP, ++ (ip->saddr & ipinfo->smsk.s_addr) != ipinfo->src.s_addr) || ++ NF_INVF(ipinfo, IPT_INV_DSTIP, ++@@ -80,6 +83,29 @@ ip_packet_match(const struct iphdr *ip, ++ return true; ++ } ++ +++static void +++ip_checkdefault(struct ipt_ip *ip) +++{ +++ static const char iface_mask[IFNAMSIZ] = {}; +++ +++ if (ip->invflags || ip->flags & IPT_F_FRAG) +++ return; +++ +++ if (memcmp(ip->iniface_mask, iface_mask, IFNAMSIZ) != 0) +++ return; +++ +++ if (memcmp(ip->outiface_mask, iface_mask, IFNAMSIZ) != 0) +++ return; +++ +++ if (ip->smsk.s_addr || ip->dmsk.s_addr) +++ return; +++ +++ if (ip->proto) +++ return; +++ +++ ip->flags |= IPT_F_NO_DEF_MATCH; +++} +++ ++ static bool ++ ip_checkentry(const struct ipt_ip *ip) ++ { ++@@ -524,6 +550,8 @@ find_check_entry(struct ipt_entry *e, st ++ struct xt_mtchk_param mtpar; ++ struct xt_entry_match *ematch; ++ +++ ip_checkdefault(&e->ip); +++ ++ if (!xt_percpu_counter_alloc(alloc_state, &e->counters)) ++ return -ENOMEM; ++ ++@@ -818,6 +846,7 @@ copy_entries_to_user(unsigned int total_ ++ const struct xt_table_info *private = xt_table_get_private_protected(table); ++ int ret = 0; ++ const void *loc_cpu_entry; +++ u8 flags; ++ ++ counters = alloc_counters(table); ++ if (IS_ERR(counters)) ++@@ -845,6 +874,14 @@ copy_entries_to_user(unsigned int total_ ++ goto free_counters; ++ } ++ +++ flags = e->ip.flags & IPT_F_MASK; +++ if (copy_to_user(userptr + off +++ + offsetof(struct ipt_entry, ip.flags), +++ &flags, sizeof(flags)) != 0) { +++ ret = -EFAULT; +++ goto free_counters; +++ } +++ ++ for (i = sizeof(struct ipt_entry); ++ i < e->target_offset; ++ i += m->u.match_size) { ++@@ -1223,12 +1260,15 @@ compat_copy_entry_to_user(struct ipt_ent ++ compat_uint_t origsize; ++ const struct xt_entry_match *ematch; ++ int ret = 0; +++ u8 flags = e->ip.flags & IPT_F_MASK; ++ ++ origsize = *size; ++ ce = *dstptr; ++ if (copy_to_user(ce, e, sizeof(struct ipt_entry)) != 0 || ++ copy_to_user(&ce->counters, &counters[i], ++- sizeof(counters[i])) != 0) +++ sizeof(counters[i])) != 0 || +++ copy_to_user(&ce->ip.flags, &flags, +++ sizeof(flags)) != 0) ++ return -EFAULT; ++ ++ *dstptr += sizeof(struct compat_ipt_entry); +diff --git a/target/linux/generic/pending-5.10/611-netfilter_match_bypass_default_table.patch b/target/linux/generic/pending-5.10/611-netfilter_match_bypass_default_table.patch +new file mode 100644 +index 0000000000..1792534835 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/611-netfilter_match_bypass_default_table.patch +@@ -0,0 +1,106 @@ ++From: Felix Fietkau ++Subject: netfilter: match bypass default table ++ ++Signed-off-by: Felix Fietkau ++--- ++ net/ipv4/netfilter/ip_tables.c | 79 +++++++++++++++++++++++++++++++----------- ++ 1 file changed, 58 insertions(+), 21 deletions(-) ++ ++--- a/net/ipv4/netfilter/ip_tables.c +++++ b/net/ipv4/netfilter/ip_tables.c ++@@ -246,6 +246,33 @@ struct ipt_entry *ipt_next_entry(const s ++ return (void *)entry + entry->next_offset; ++ } ++ +++static bool +++ipt_handle_default_rule(struct ipt_entry *e, unsigned int *verdict) +++{ +++ struct xt_entry_target *t; +++ struct xt_standard_target *st; +++ +++ if (e->target_offset != sizeof(struct ipt_entry)) +++ return false; +++ +++ if (!(e->ip.flags & IPT_F_NO_DEF_MATCH)) +++ return false; +++ +++ t = ipt_get_target(e); +++ if (t->u.kernel.target->target) +++ return false; +++ +++ st = (struct xt_standard_target *) t; +++ if (st->verdict == XT_RETURN) +++ return false; +++ +++ if (st->verdict >= 0) +++ return false; +++ +++ *verdict = (unsigned)(-st->verdict) - 1; +++ return true; +++} +++ ++ /* Returns one of the generic firewall policies, like NF_ACCEPT. */ ++ unsigned int ++ ipt_do_table(struct sk_buff *skb, ++@@ -266,27 +293,28 @@ ipt_do_table(struct sk_buff *skb, ++ unsigned int addend; ++ ++ /* Initialization */ +++ WARN_ON(!(table->valid_hooks & (1 << hook))); +++ local_bh_disable(); +++ private = rcu_access_pointer(table->private); +++ cpu = smp_processor_id(); +++ table_base = private->entries; +++ +++ e = get_entry(table_base, private->hook_entry[hook]); +++ if (ipt_handle_default_rule(e, &verdict)) { +++ struct xt_counters *counter; +++ +++ counter = xt_get_this_cpu_counter(&e->counters); +++ ADD_COUNTER(*counter, skb->len, 1); +++ local_bh_enable(); +++ return verdict; +++ } +++ ++ stackidx = 0; ++ ip = ip_hdr(skb); ++ indev = state->in ? state->in->name : nulldevname; ++ outdev = state->out ? state->out->name : nulldevname; ++- /* We handle fragments by dealing with the first fragment as ++- * if it was a normal packet. All other fragments are treated ++- * normally, except that they will NEVER match rules that ask ++- * things we don't know, ie. tcp syn flag or ports). If the ++- * rule is also a fragment-specific rule, non-fragments won't ++- * match it. */ ++- acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET; ++- acpar.thoff = ip_hdrlen(skb); ++- acpar.hotdrop = false; ++- acpar.state = state; ++ ++- WARN_ON(!(table->valid_hooks & (1 << hook))); ++- local_bh_disable(); ++ addend = xt_write_recseq_begin(); ++- private = rcu_access_pointer(table->private); ++- cpu = smp_processor_id(); ++- table_base = private->entries; ++ jumpstack = (struct ipt_entry **)private->jumpstack[cpu]; ++ ++ /* Switch to alternate jumpstack if we're being invoked via TEE. ++@@ -299,7 +327,16 @@ ipt_do_table(struct sk_buff *skb, ++ if (static_key_false(&xt_tee_enabled)) ++ jumpstack += private->stacksize * __this_cpu_read(nf_skb_duplicated); ++ ++- e = get_entry(table_base, private->hook_entry[hook]); +++ /* We handle fragments by dealing with the first fragment as +++ * if it was a normal packet. All other fragments are treated +++ * normally, except that they will NEVER match rules that ask +++ * things we don't know, ie. tcp syn flag or ports). If the +++ * rule is also a fragment-specific rule, non-fragments won't +++ * match it. */ +++ acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET; +++ acpar.thoff = ip_hdrlen(skb); +++ acpar.hotdrop = false; +++ acpar.state = state; ++ ++ do { ++ const struct xt_entry_target *t; +diff --git a/target/linux/generic/pending-5.10/612-netfilter_match_reduce_memory_access.patch b/target/linux/generic/pending-5.10/612-netfilter_match_reduce_memory_access.patch +new file mode 100644 +index 0000000000..79da6778b6 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/612-netfilter_match_reduce_memory_access.patch +@@ -0,0 +1,22 @@ ++From: Felix Fietkau ++Subject: netfilter: reduce match memory access ++ ++Signed-off-by: Felix Fietkau ++--- ++ net/ipv4/netfilter/ip_tables.c | 4 ++-- ++ 1 file changed, 2 insertions(+), 2 deletions(-) ++ ++--- a/net/ipv4/netfilter/ip_tables.c +++++ b/net/ipv4/netfilter/ip_tables.c ++@@ -53,9 +53,9 @@ ip_packet_match(const struct iphdr *ip, ++ if (ipinfo->flags & IPT_F_NO_DEF_MATCH) ++ return true; ++ ++- if (NF_INVF(ipinfo, IPT_INV_SRCIP, +++ if (NF_INVF(ipinfo, IPT_INV_SRCIP, ipinfo->smsk.s_addr && ++ (ip->saddr & ipinfo->smsk.s_addr) != ipinfo->src.s_addr) || ++- NF_INVF(ipinfo, IPT_INV_DSTIP, +++ NF_INVF(ipinfo, IPT_INV_DSTIP, ipinfo->dmsk.s_addr && ++ (ip->daddr & ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr)) ++ return false; ++ +diff --git a/target/linux/generic/pending-5.10/613-netfilter_optional_tcp_window_check.patch b/target/linux/generic/pending-5.10/613-netfilter_optional_tcp_window_check.patch +new file mode 100644 +index 0000000000..61776921c6 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/613-netfilter_optional_tcp_window_check.patch +@@ -0,0 +1,73 @@ ++From: Felix Fietkau ++Subject: netfilter: optional tcp window check ++ ++Signed-off-by: Felix Fietkau ++--- ++ net/netfilter/nf_conntrack_proto_tcp.c | 13 +++++++++++++ ++ 1 file changed, 13 insertions(+) ++ ++--- a/net/netfilter/nf_conntrack_proto_tcp.c +++++ b/net/netfilter/nf_conntrack_proto_tcp.c ++@@ -31,6 +31,9 @@ ++ #include ++ #include ++ +++/* Do not check the TCP window for incoming packets */ +++static int nf_ct_tcp_no_window_check __read_mostly = 1; +++ ++ /* "Be conservative in what you do, ++ be liberal in what you accept from others." ++ If it's non-zero, we mark only out of window RST segments as INVALID. */ ++@@ -476,6 +479,9 @@ static bool tcp_in_window(const struct n ++ s32 receiver_offset; ++ bool res, in_recv_win; ++ +++ if (nf_ct_tcp_no_window_check) +++ return true; +++ ++ /* ++ * Get the required data from the packet. ++ */ ++@@ -1130,7 +1136,7 @@ int nf_conntrack_tcp_packet(struct nf_co ++ IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED && ++ timeouts[new_state] > timeouts[TCP_CONNTRACK_UNACK]) ++ timeout = timeouts[TCP_CONNTRACK_UNACK]; ++- else if (ct->proto.tcp.last_win == 0 && +++ else if (!nf_ct_tcp_no_window_check && ct->proto.tcp.last_win == 0 && ++ timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS]) ++ timeout = timeouts[TCP_CONNTRACK_RETRANS]; ++ else ++--- a/net/netfilter/nf_conntrack_standalone.c +++++ b/net/netfilter/nf_conntrack_standalone.c ++@@ -25,6 +25,9 @@ ++ #include ++ #include ++ +++/* Do not check the TCP window for incoming packets */ +++static int nf_ct_tcp_no_window_check __read_mostly = 1; +++ ++ static bool enable_hooks __read_mostly; ++ MODULE_PARM_DESC(enable_hooks, "Always enable conntrack hooks"); ++ module_param(enable_hooks, bool, 0000); ++@@ -651,6 +654,7 @@ enum nf_ct_sysctl_index { ++ NF_SYSCTL_CT_PROTO_TIMEOUT_GRE_STREAM, ++ #endif ++ +++ NF_SYSCTL_CT_PROTO_TCP_NO_WINDOW_CHECK, ++ __NF_SYSCTL_CT_LAST_SYSCTL, ++ }; ++ ++@@ -977,6 +981,13 @@ static struct ctl_table nf_ct_sysctl_tab ++ .proc_handler = proc_dointvec_jiffies, ++ }, ++ #endif +++ [NF_SYSCTL_CT_PROTO_TCP_NO_WINDOW_CHECK] = { +++ .procname = "nf_conntrack_tcp_no_window_check", +++ .data = &nf_ct_tcp_no_window_check, +++ .maxlen = sizeof(unsigned int), +++ .mode = 0644, +++ .proc_handler = proc_dointvec, +++ }, ++ {} ++ }; ++ +diff --git a/target/linux/generic/pending-5.10/620-net_sched-codel-do-not-defer-queue-length-update.patch b/target/linux/generic/pending-5.10/620-net_sched-codel-do-not-defer-queue-length-update.patch +new file mode 100644 +index 0000000000..4b4825ae3b +--- /dev/null ++++ b/target/linux/generic/pending-5.10/620-net_sched-codel-do-not-defer-queue-length-update.patch +@@ -0,0 +1,86 @@ ++From: Konstantin Khlebnikov ++Date: Mon, 21 Aug 2017 11:14:14 +0300 ++Subject: [PATCH] net_sched/codel: do not defer queue length update ++ ++When codel wants to drop last packet in ->dequeue() it cannot call ++qdisc_tree_reduce_backlog() right away - it will notify parent qdisc ++about zero qlen and HTB/HFSC will deactivate class. The same class will ++be deactivated second time by caller of ->dequeue(). Currently codel and ++fq_codel defer update. This triggers warning in HFSC when it's qlen != 0 ++but there is no active classes. ++ ++This patch update parent queue length immediately: just temporary increase ++qlen around qdisc_tree_reduce_backlog() to prevent first class deactivation ++if we have skb to return. ++ ++This might open another problem in HFSC - now operation peek could fail and ++deactivate parent class. ++ ++Signed-off-by: Konstantin Khlebnikov ++Link: https://bugzilla.kernel.org/show_bug.cgi?id=109581 ++--- ++ ++--- a/net/sched/sch_codel.c +++++ b/net/sched/sch_codel.c ++@@ -95,11 +95,17 @@ static struct sk_buff *codel_qdisc_deque ++ &q->stats, qdisc_pkt_len, codel_get_enqueue_time, ++ drop_func, dequeue_func); ++ ++- /* We cant call qdisc_tree_reduce_backlog() if our qlen is 0, ++- * or HTB crashes. Defer it for next round. +++ /* If our qlen is 0 qdisc_tree_reduce_backlog() will deactivate +++ * parent class, dequeue in parent qdisc will do the same if we +++ * return skb. Temporary increment qlen if we have skb. ++ */ ++- if (q->stats.drop_count && sch->q.qlen) { ++- qdisc_tree_reduce_backlog(sch, q->stats.drop_count, q->stats.drop_len); +++ if (q->stats.drop_count) { +++ if (skb) +++ sch->q.qlen++; +++ qdisc_tree_reduce_backlog(sch, q->stats.drop_count, +++ q->stats.drop_len); +++ if (skb) +++ sch->q.qlen--; ++ q->stats.drop_count = 0; ++ q->stats.drop_len = 0; ++ } ++--- a/net/sched/sch_fq_codel.c +++++ b/net/sched/sch_fq_codel.c ++@@ -304,6 +304,21 @@ begin: ++ &flow->cvars, &q->cstats, qdisc_pkt_len, ++ codel_get_enqueue_time, drop_func, dequeue_func); ++ +++ /* If our qlen is 0 qdisc_tree_reduce_backlog() will deactivate +++ * parent class, dequeue in parent qdisc will do the same if we +++ * return skb. Temporary increment qlen if we have skb. +++ */ +++ if (q->cstats.drop_count) { +++ if (skb) +++ sch->q.qlen++; +++ qdisc_tree_reduce_backlog(sch, q->cstats.drop_count, +++ q->cstats.drop_len); +++ if (skb) +++ sch->q.qlen--; +++ q->cstats.drop_count = 0; +++ q->cstats.drop_len = 0; +++ } +++ ++ if (!skb) { ++ /* force a pass through old_flows to prevent starvation */ ++ if ((head == &q->new_flows) && !list_empty(&q->old_flows)) ++@@ -314,15 +329,6 @@ begin: ++ } ++ qdisc_bstats_update(sch, skb); ++ flow->deficit -= qdisc_pkt_len(skb); ++- /* We cant call qdisc_tree_reduce_backlog() if our qlen is 0, ++- * or HTB crashes. Defer it for next round. ++- */ ++- if (q->cstats.drop_count && sch->q.qlen) { ++- qdisc_tree_reduce_backlog(sch, q->cstats.drop_count, ++- q->cstats.drop_len); ++- q->cstats.drop_count = 0; ++- q->cstats.drop_len = 0; ++- } ++ return skb; ++ } ++ +diff --git a/target/linux/generic/pending-5.10/630-packet_socket_type.patch b/target/linux/generic/pending-5.10/630-packet_socket_type.patch +new file mode 100644 +index 0000000000..104bcbe5a5 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/630-packet_socket_type.patch +@@ -0,0 +1,138 @@ ++From: Felix Fietkau ++Subject: net: add an optimization for dealing with raw sockets ++ ++lede-commit: 4898039703d7315f0f3431c860123338ec3be0f6 ++Signed-off-by: Felix Fietkau ++--- ++ include/uapi/linux/if_packet.h | 3 +++ ++ net/packet/af_packet.c | 34 +++++++++++++++++++++++++++------- ++ net/packet/internal.h | 1 + ++ 3 files changed, 31 insertions(+), 7 deletions(-) ++ ++--- a/include/uapi/linux/if_packet.h +++++ b/include/uapi/linux/if_packet.h ++@@ -32,6 +32,8 @@ struct sockaddr_ll { ++ #define PACKET_KERNEL 7 /* To kernel space */ ++ /* Unused, PACKET_FASTROUTE and PACKET_LOOPBACK are invisible to user space */ ++ #define PACKET_FASTROUTE 6 /* Fastrouted frame */ +++#define PACKET_MASK_ANY 0xffffffff /* mask for packet type bits */ +++ ++ ++ /* Packet socket options */ ++ ++@@ -58,6 +60,7 @@ struct sockaddr_ll { ++ #define PACKET_ROLLOVER_STATS 21 ++ #define PACKET_FANOUT_DATA 22 ++ #define PACKET_IGNORE_OUTGOING 23 +++#define PACKET_RECV_TYPE 24 ++ ++ #define PACKET_FANOUT_HASH 0 ++ #define PACKET_FANOUT_LB 1 ++--- a/net/packet/af_packet.c +++++ b/net/packet/af_packet.c ++@@ -1801,6 +1801,7 @@ static int packet_rcv_spkt(struct sk_buf ++ { ++ struct sock *sk; ++ struct sockaddr_pkt *spkt; +++ struct packet_sock *po; ++ ++ /* ++ * When we registered the protocol we saved the socket in the data ++@@ -1808,6 +1809,7 @@ static int packet_rcv_spkt(struct sk_buf ++ */ ++ ++ sk = pt->af_packet_priv; +++ po = pkt_sk(sk); ++ ++ /* ++ * Yank back the headers [hope the device set this ++@@ -1820,7 +1822,7 @@ static int packet_rcv_spkt(struct sk_buf ++ * so that this procedure is noop. ++ */ ++ ++- if (skb->pkt_type == PACKET_LOOPBACK) +++ if (!(po->pkt_type & (1 << skb->pkt_type))) ++ goto out; ++ ++ if (!net_eq(dev_net(dev), sock_net(sk))) ++@@ -2058,12 +2060,12 @@ static int packet_rcv(struct sk_buff *sk ++ unsigned int snaplen, res; ++ bool is_drop_n_account = false; ++ ++- if (skb->pkt_type == PACKET_LOOPBACK) ++- goto drop; ++- ++ sk = pt->af_packet_priv; ++ po = pkt_sk(sk); ++ +++ if (!(po->pkt_type & (1 << skb->pkt_type))) +++ goto drop; +++ ++ if (!net_eq(dev_net(dev), sock_net(sk))) ++ goto drop; ++ ++@@ -2189,12 +2191,12 @@ static int tpacket_rcv(struct sk_buff *s ++ BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h2)) != 32); ++ BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h3)) != 48); ++ ++- if (skb->pkt_type == PACKET_LOOPBACK) ++- goto drop; ++- ++ sk = pt->af_packet_priv; ++ po = pkt_sk(sk); ++ +++ if (!(po->pkt_type & (1 << skb->pkt_type))) +++ goto drop; +++ ++ if (!net_eq(dev_net(dev), sock_net(sk))) ++ goto drop; ++ ++@@ -3293,6 +3295,7 @@ static int packet_create(struct net *net ++ mutex_init(&po->pg_vec_lock); ++ po->rollover = NULL; ++ po->prot_hook.func = packet_rcv; +++ po->pkt_type = PACKET_MASK_ANY & ~(1 << PACKET_LOOPBACK); ++ ++ if (sock->type == SOCK_PACKET) ++ po->prot_hook.func = packet_rcv_spkt; ++@@ -3927,6 +3930,16 @@ packet_setsockopt(struct socket *sock, i ++ po->xmit = val ? packet_direct_xmit : dev_queue_xmit; ++ return 0; ++ } +++ case PACKET_RECV_TYPE: +++ { +++ unsigned int val; +++ if (optlen != sizeof(val)) +++ return -EINVAL; +++ if (copy_from_sockptr(&val, optval, sizeof(val))) +++ return -EFAULT; +++ po->pkt_type = val & ~BIT(PACKET_LOOPBACK); +++ return 0; +++ } ++ default: ++ return -ENOPROTOOPT; ++ } ++@@ -3983,6 +3996,13 @@ static int packet_getsockopt(struct sock ++ case PACKET_VNET_HDR: ++ val = po->has_vnet_hdr; ++ break; +++ case PACKET_RECV_TYPE: +++ if (len > sizeof(unsigned int)) +++ len = sizeof(unsigned int); +++ val = po->pkt_type; +++ +++ data = &val; +++ break; ++ case PACKET_VERSION: ++ val = po->tp_version; ++ break; ++--- a/net/packet/internal.h +++++ b/net/packet/internal.h ++@@ -136,6 +136,7 @@ struct packet_sock { ++ int (*xmit)(struct sk_buff *skb); ++ struct packet_type prot_hook ____cacheline_aligned_in_smp; ++ atomic_t tp_drops ____cacheline_aligned_in_smp; +++ unsigned int pkt_type; ++ }; ++ ++ static struct packet_sock *pkt_sk(struct sock *sk) +diff --git a/target/linux/generic/pending-5.10/640-00-netfilter-flowtable-add-hash-offset-field-to-tuple.patch b/target/linux/generic/pending-5.10/640-00-netfilter-flowtable-add-hash-offset-field-to-tuple.patch +new file mode 100644 +index 0000000000..c881ccfcb0 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/640-00-netfilter-flowtable-add-hash-offset-field-to-tuple.patch +@@ -0,0 +1,52 @@ ++From: Pablo Neira Ayuso ++Date: Fri, 20 Nov 2020 13:49:13 +0100 ++Subject: [PATCH] netfilter: flowtable: add hash offset field to tuple ++ ++Add a placeholder field to calculate hash tuple offset. Similar to ++2c407aca6497 ("netfilter: conntrack: avoid gcc-10 zero-length-bounds ++warning"). ++ ++Signed-off-by: Pablo Neira Ayuso ++--- ++ ++--- a/include/net/netfilter/nf_flow_table.h +++++ b/include/net/netfilter/nf_flow_table.h ++@@ -107,6 +107,10 @@ struct flow_offload_tuple { ++ ++ u8 l3proto; ++ u8 l4proto; +++ +++ /* All members above are keys for lookups, see flow_offload_hash(). */ +++ struct { } __hash; +++ ++ u8 dir; ++ ++ u16 mtu; ++--- a/net/netfilter/nf_flow_table_core.c +++++ b/net/netfilter/nf_flow_table_core.c ++@@ -191,14 +191,14 @@ static u32 flow_offload_hash(const void ++ { ++ const struct flow_offload_tuple *tuple = data; ++ ++- return jhash(tuple, offsetof(struct flow_offload_tuple, dir), seed); +++ return jhash(tuple, offsetof(struct flow_offload_tuple, __hash), seed); ++ } ++ ++ static u32 flow_offload_hash_obj(const void *data, u32 len, u32 seed) ++ { ++ const struct flow_offload_tuple_rhash *tuplehash = data; ++ ++- return jhash(&tuplehash->tuple, offsetof(struct flow_offload_tuple, dir), seed); +++ return jhash(&tuplehash->tuple, offsetof(struct flow_offload_tuple, __hash), seed); ++ } ++ ++ static int flow_offload_hash_cmp(struct rhashtable_compare_arg *arg, ++@@ -207,7 +207,7 @@ static int flow_offload_hash_cmp(struct ++ const struct flow_offload_tuple *tuple = arg->key; ++ const struct flow_offload_tuple_rhash *x = ptr; ++ ++- if (memcmp(&x->tuple, tuple, offsetof(struct flow_offload_tuple, dir))) +++ if (memcmp(&x->tuple, tuple, offsetof(struct flow_offload_tuple, __hash))) ++ return 1; ++ ++ return 0; +diff --git a/target/linux/generic/pending-5.10/640-01-netfilter-flowtable-add-xmit-path-types.patch b/target/linux/generic/pending-5.10/640-01-netfilter-flowtable-add-xmit-path-types.patch +new file mode 100644 +index 0000000000..e47d03e48d +--- /dev/null ++++ b/target/linux/generic/pending-5.10/640-01-netfilter-flowtable-add-xmit-path-types.patch +@@ -0,0 +1,188 @@ ++From: Pablo Neira Ayuso ++Date: Fri, 20 Nov 2020 13:49:14 +0100 ++Subject: [PATCH] netfilter: flowtable: add xmit path types ++ ++Add the xmit_type field that defines the two supported xmit paths in the ++flowtable data plane, which are the neighbour and the xfrm xmit paths. ++This patch prepares for new flowtable xmit path types to come. ++ ++Signed-off-by: Pablo Neira Ayuso ++--- ++ ++--- a/include/net/netfilter/nf_flow_table.h +++++ b/include/net/netfilter/nf_flow_table.h ++@@ -89,6 +89,11 @@ enum flow_offload_tuple_dir { ++ FLOW_OFFLOAD_DIR_MAX = IP_CT_DIR_MAX ++ }; ++ +++enum flow_offload_xmit_type { +++ FLOW_OFFLOAD_XMIT_NEIGH = 0, +++ FLOW_OFFLOAD_XMIT_XFRM, +++}; +++ ++ struct flow_offload_tuple { ++ union { ++ struct in_addr src_v4; ++@@ -111,7 +116,8 @@ struct flow_offload_tuple { ++ /* All members above are keys for lookups, see flow_offload_hash(). */ ++ struct { } __hash; ++ ++- u8 dir; +++ u8 dir:6, +++ xmit_type:2; ++ ++ u16 mtu; ++ ++@@ -158,7 +164,8 @@ static inline __s32 nf_flow_timeout_delt ++ ++ struct nf_flow_route { ++ struct { ++- struct dst_entry *dst; +++ struct dst_entry *dst; +++ enum flow_offload_xmit_type xmit_type; ++ } tuple[FLOW_OFFLOAD_DIR_MAX]; ++ }; ++ ++--- a/net/netfilter/nf_flow_table_core.c +++++ b/net/netfilter/nf_flow_table_core.c ++@@ -95,6 +95,7 @@ static int flow_offload_fill_route(struc ++ } ++ ++ flow_tuple->iifidx = other_dst->dev->ifindex; +++ flow_tuple->xmit_type = route->tuple[dir].xmit_type; ++ flow_tuple->dst_cache = dst; ++ ++ return 0; ++--- a/net/netfilter/nf_flow_table_ip.c +++++ b/net/netfilter/nf_flow_table_ip.c ++@@ -220,10 +220,20 @@ static bool nf_flow_exceeds_mtu(const st ++ return true; ++ } ++ ++-static int nf_flow_offload_dst_check(struct dst_entry *dst) +++static inline struct dst_entry * +++nft_flow_dst(struct flow_offload_tuple_rhash *tuplehash) ++ { ++- if (unlikely(dst_xfrm(dst))) +++ return tuplehash->tuple.dst_cache; +++} +++ +++static int nf_flow_offload_dst_check(struct flow_offload_tuple_rhash *tuplehash) +++{ +++ struct dst_entry *dst; +++ +++ if (unlikely(tuplehash->tuple.xmit_type == FLOW_OFFLOAD_XMIT_XFRM)) { +++ dst = nft_flow_dst(tuplehash); ++ return dst_check(dst, 0) ? 0 : -1; +++ } ++ ++ return 0; ++ } ++@@ -265,8 +275,6 @@ nf_flow_offload_ip_hook(void *priv, stru ++ ++ dir = tuplehash->tuple.dir; ++ flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); ++- rt = (struct rtable *)flow->tuplehash[dir].tuple.dst_cache; ++- outdev = rt->dst.dev; ++ ++ if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu))) ++ return NF_ACCEPT; ++@@ -280,7 +288,7 @@ nf_flow_offload_ip_hook(void *priv, stru ++ ++ flow_offload_refresh(flow_table, flow); ++ ++- if (nf_flow_offload_dst_check(&rt->dst)) { +++ if (nf_flow_offload_dst_check(tuplehash)) { ++ flow_offload_teardown(flow); ++ return NF_ACCEPT; ++ } ++@@ -295,13 +303,16 @@ nf_flow_offload_ip_hook(void *priv, stru ++ if (flow_table->flags & NF_FLOWTABLE_COUNTER) ++ nf_ct_acct_update(flow->ct, tuplehash->tuple.dir, skb->len); ++ ++- if (unlikely(dst_xfrm(&rt->dst))) { +++ rt = (struct rtable *)tuplehash->tuple.dst_cache; +++ +++ if (unlikely(tuplehash->tuple.xmit_type == FLOW_OFFLOAD_XMIT_XFRM)) { ++ memset(skb->cb, 0, sizeof(struct inet_skb_parm)); ++ IPCB(skb)->iif = skb->dev->ifindex; ++ IPCB(skb)->flags = IPSKB_FORWARDED; ++ return nf_flow_xmit_xfrm(skb, state, &rt->dst); ++ } ++ +++ outdev = rt->dst.dev; ++ skb->dev = outdev; ++ nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr); ++ skb_dst_set_noref(skb, &rt->dst); ++@@ -506,8 +517,6 @@ nf_flow_offload_ipv6_hook(void *priv, st ++ ++ dir = tuplehash->tuple.dir; ++ flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); ++- rt = (struct rt6_info *)flow->tuplehash[dir].tuple.dst_cache; ++- outdev = rt->dst.dev; ++ ++ if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu))) ++ return NF_ACCEPT; ++@@ -518,7 +527,7 @@ nf_flow_offload_ipv6_hook(void *priv, st ++ ++ flow_offload_refresh(flow_table, flow); ++ ++- if (nf_flow_offload_dst_check(&rt->dst)) { +++ if (nf_flow_offload_dst_check(tuplehash)) { ++ flow_offload_teardown(flow); ++ return NF_ACCEPT; ++ } ++@@ -536,13 +545,16 @@ nf_flow_offload_ipv6_hook(void *priv, st ++ if (flow_table->flags & NF_FLOWTABLE_COUNTER) ++ nf_ct_acct_update(flow->ct, tuplehash->tuple.dir, skb->len); ++ ++- if (unlikely(dst_xfrm(&rt->dst))) { +++ rt = (struct rt6_info *)tuplehash->tuple.dst_cache; +++ +++ if (unlikely(tuplehash->tuple.xmit_type == FLOW_OFFLOAD_XMIT_XFRM)) { ++ memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); ++ IP6CB(skb)->iif = skb->dev->ifindex; ++ IP6CB(skb)->flags = IP6SKB_FORWARDED; ++ return nf_flow_xmit_xfrm(skb, state, &rt->dst); ++ } ++ +++ outdev = rt->dst.dev; ++ skb->dev = outdev; ++ nexthop = rt6_nexthop(rt, &flow->tuplehash[!dir].tuple.src_v6); ++ skb_dst_set_noref(skb, &rt->dst); ++--- a/net/netfilter/nft_flow_offload.c +++++ b/net/netfilter/nft_flow_offload.c ++@@ -19,6 +19,22 @@ struct nft_flow_offload { ++ struct nft_flowtable *flowtable; ++ }; ++ +++static enum flow_offload_xmit_type nft_xmit_type(struct dst_entry *dst) +++{ +++ if (dst_xfrm(dst)) +++ return FLOW_OFFLOAD_XMIT_XFRM; +++ +++ return FLOW_OFFLOAD_XMIT_NEIGH; +++} +++ +++static void nft_default_forward_path(struct nf_flow_route *route, +++ struct dst_entry *dst_cache, +++ enum ip_conntrack_dir dir) +++{ +++ route->tuple[dir].dst = dst_cache; +++ route->tuple[dir].xmit_type = nft_xmit_type(dst_cache); +++} +++ ++ static int nft_flow_route(const struct nft_pktinfo *pkt, ++ const struct nf_conn *ct, ++ struct nf_flow_route *route, ++@@ -44,8 +60,8 @@ static int nft_flow_route(const struct n ++ if (!other_dst) ++ return -ENOENT; ++ ++- route->tuple[dir].dst = this_dst; ++- route->tuple[!dir].dst = other_dst; +++ nft_default_forward_path(route, this_dst, dir); +++ nft_default_forward_path(route, other_dst, !dir); ++ ++ return 0; ++ } +diff --git a/target/linux/generic/pending-5.10/640-02-net-resolve-forwarding-path-from-virtual-netdevice-a.patch b/target/linux/generic/pending-5.10/640-02-net-resolve-forwarding-path-from-virtual-netdevice-a.patch +new file mode 100644 +index 0000000000..953446baab +--- /dev/null ++++ b/target/linux/generic/pending-5.10/640-02-net-resolve-forwarding-path-from-virtual-netdevice-a.patch +@@ -0,0 +1,170 @@ ++From: Pablo Neira Ayuso ++Date: Sun, 10 Jan 2021 15:53:58 +0100 ++Subject: [PATCH] net: resolve forwarding path from virtual netdevice and ++ HW destination address ++ ++This patch adds dev_fill_forward_path() which resolves the path to reach ++the real netdevice from the IP forwarding side. This function takes as ++input the netdevice and the destination hardware address and it walks ++down the devices calling .ndo_fill_forward_path() for each device until ++the real device is found. ++ ++For instance, assuming the following topology: ++ ++ IP forwarding ++ / \ ++ br0 eth0 ++ / \ ++ eth1 eth2 ++ . ++ . ++ . ++ ethX ++ ab:cd:ef:ab:cd:ef ++ ++where eth1 and eth2 are bridge ports and eth0 provides WAN connectivity. ++ethX is the interface in another box which is connected to the eth1 ++bridge port. ++ ++For packets going through IP forwarding to br0 whose destination MAC ++address is ab:cd:ef:ab:cd:ef, dev_fill_forward_path() provides the ++following path: ++ ++ br0 -> eth1 ++ ++.ndo_fill_forward_path for br0 looks up at the FDB for the bridge port ++from the destination MAC address to get the bridge port eth1. ++ ++This information allows to create a fast path that bypasses the classic ++bridge and IP forwarding paths, so packets go directly from the bridge ++port eth1 to eth0 (wan interface) and vice versa. ++ ++ fast path ++ .------------------------. ++ / \ ++ | IP forwarding | ++ | / \ \/ ++ | br0 eth0 ++ . / \ ++ -> eth1 eth2 ++ . ++ . ++ . ++ ethX ++ ab:cd:ef:ab:cd:ef ++ ++Signed-off-by: Pablo Neira Ayuso ++--- ++ ++--- a/include/linux/netdevice.h +++++ b/include/linux/netdevice.h ++@@ -833,6 +833,27 @@ typedef u16 (*select_queue_fallback_t)(s ++ struct sk_buff *skb, ++ struct net_device *sb_dev); ++ +++enum net_device_path_type { +++ DEV_PATH_ETHERNET = 0, +++}; +++ +++struct net_device_path { +++ enum net_device_path_type type; +++ const struct net_device *dev; +++}; +++ +++#define NET_DEVICE_PATH_STACK_MAX 5 +++ +++struct net_device_path_stack { +++ int num_paths; +++ struct net_device_path path[NET_DEVICE_PATH_STACK_MAX]; +++}; +++ +++struct net_device_path_ctx { +++ const struct net_device *dev; +++ const u8 *daddr; +++}; +++ ++ enum tc_setup_type { ++ TC_SETUP_QDISC_MQPRIO, ++ TC_SETUP_CLSU32, ++@@ -1279,6 +1300,8 @@ struct netdev_net_notifier { ++ * struct net_device *(*ndo_get_peer_dev)(struct net_device *dev); ++ * If a device is paired with a peer device, return the peer instance. ++ * The caller must be under RCU read context. +++ * int (*ndo_fill_forward_path)(struct net_device_path_ctx *ctx, struct net_device_path *path); +++ * Get the forwarding path to reach the real device from the HW destination address ++ */ ++ struct net_device_ops { ++ int (*ndo_init)(struct net_device *dev); ++@@ -1487,6 +1510,8 @@ struct net_device_ops { ++ int (*ndo_tunnel_ctl)(struct net_device *dev, ++ struct ip_tunnel_parm *p, int cmd); ++ struct net_device * (*ndo_get_peer_dev)(struct net_device *dev); +++ int (*ndo_fill_forward_path)(struct net_device_path_ctx *ctx, +++ struct net_device_path *path); ++ }; ++ ++ /** ++@@ -2798,6 +2823,8 @@ void dev_remove_offload(struct packet_of ++ ++ int dev_get_iflink(const struct net_device *dev); ++ int dev_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb); +++int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr, +++ struct net_device_path_stack *stack); ++ struct net_device *__dev_get_by_flags(struct net *net, unsigned short flags, ++ unsigned short mask); ++ struct net_device *dev_get_by_name(struct net *net, const char *name); ++--- a/net/core/dev.c +++++ b/net/core/dev.c ++@@ -846,6 +846,52 @@ int dev_fill_metadata_dst(struct net_dev ++ } ++ EXPORT_SYMBOL_GPL(dev_fill_metadata_dst); ++ +++static struct net_device_path *dev_fwd_path(struct net_device_path_stack *stack) +++{ +++ int k = stack->num_paths++; +++ +++ if (WARN_ON_ONCE(k >= NET_DEVICE_PATH_STACK_MAX)) +++ return NULL; +++ +++ return &stack->path[k]; +++} +++ +++int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr, +++ struct net_device_path_stack *stack) +++{ +++ const struct net_device *last_dev; +++ struct net_device_path_ctx ctx = { +++ .dev = dev, +++ .daddr = daddr, +++ }; +++ struct net_device_path *path; +++ int ret = 0; +++ +++ stack->num_paths = 0; +++ while (ctx.dev && ctx.dev->netdev_ops->ndo_fill_forward_path) { +++ last_dev = ctx.dev; +++ path = dev_fwd_path(stack); +++ if (!path) +++ return -1; +++ +++ memset(path, 0, sizeof(struct net_device_path)); +++ ret = ctx.dev->netdev_ops->ndo_fill_forward_path(&ctx, path); +++ if (ret < 0) +++ return -1; +++ +++ if (WARN_ON_ONCE(last_dev == ctx.dev)) +++ return -1; +++ } +++ path = dev_fwd_path(stack); +++ if (!path) +++ return -1; +++ path->type = DEV_PATH_ETHERNET; +++ path->dev = ctx.dev; +++ +++ return ret; +++} +++EXPORT_SYMBOL_GPL(dev_fill_forward_path); +++ ++ /** ++ * __dev_get_by_name - find a device by its name ++ * @net: the applicable net namespace +diff --git a/target/linux/generic/pending-5.10/640-03-net-8021q-resolve-forwarding-path-for-vlan-devices.patch b/target/linux/generic/pending-5.10/640-03-net-8021q-resolve-forwarding-path-for-vlan-devices.patch +new file mode 100644 +index 0000000000..ddc0de0d3b +--- /dev/null ++++ b/target/linux/generic/pending-5.10/640-03-net-8021q-resolve-forwarding-path-for-vlan-devices.patch +@@ -0,0 +1,80 @@ ++From: Pablo Neira Ayuso ++Date: Fri, 20 Nov 2020 13:49:16 +0100 ++Subject: [PATCH] net: 8021q: resolve forwarding path for vlan devices ++ ++Add .ndo_fill_forward_path for vlan devices. ++ ++For instance, assuming the following topology: ++ ++ IP forwarding ++ / \ ++ eth0.100 eth0 ++ | ++ eth0 ++ . ++ . ++ . ++ ethX ++ ab:cd:ef:ab:cd:ef ++ ++For packets going through IP forwarding to eth0.100 whose destination ++MAC address is ab:cd:ef:ab:cd:ef, dev_fill_forward_path() provides the ++following path: ++ ++ eth0.100 -> eth0 ++ ++Signed-off-by: Pablo Neira Ayuso ++--- ++ ++--- a/include/linux/netdevice.h +++++ b/include/linux/netdevice.h ++@@ -835,11 +835,18 @@ typedef u16 (*select_queue_fallback_t)(s ++ ++ enum net_device_path_type { ++ DEV_PATH_ETHERNET = 0, +++ DEV_PATH_VLAN, ++ }; ++ ++ struct net_device_path { ++ enum net_device_path_type type; ++ const struct net_device *dev; +++ union { +++ struct { +++ u16 id; +++ __be16 proto; +++ } vlan; +++ }; ++ }; ++ ++ #define NET_DEVICE_PATH_STACK_MAX 5 ++--- a/net/8021q/vlan_dev.c +++++ b/net/8021q/vlan_dev.c ++@@ -767,6 +767,20 @@ static int vlan_dev_get_iflink(const str ++ return real_dev->ifindex; ++ } ++ +++static int vlan_dev_fill_forward_path(struct net_device_path_ctx *ctx, +++ struct net_device_path *path) +++{ +++ struct vlan_dev_priv *vlan = vlan_dev_priv(ctx->dev); +++ +++ path->type = DEV_PATH_VLAN; +++ path->vlan.id = vlan->vlan_id; +++ path->vlan.proto = vlan->vlan_proto; +++ path->dev = ctx->dev; +++ ctx->dev = vlan->real_dev; +++ +++ return 0; +++} +++ ++ static const struct ethtool_ops vlan_ethtool_ops = { ++ .get_link_ksettings = vlan_ethtool_get_link_ksettings, ++ .get_drvinfo = vlan_ethtool_get_drvinfo, ++@@ -805,6 +819,7 @@ static const struct net_device_ops vlan_ ++ #endif ++ .ndo_fix_features = vlan_dev_fix_features, ++ .ndo_get_iflink = vlan_dev_get_iflink, +++ .ndo_fill_forward_path = vlan_dev_fill_forward_path, ++ }; ++ ++ static void vlan_dev_free(struct net_device *dev) +diff --git a/target/linux/generic/pending-5.10/640-04-bridge-resolve-forwarding-path-for-bridge-devices.patch b/target/linux/generic/pending-5.10/640-04-bridge-resolve-forwarding-path-for-bridge-devices.patch +new file mode 100644 +index 0000000000..d9093b3da4 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/640-04-bridge-resolve-forwarding-path-for-bridge-devices.patch +@@ -0,0 +1,62 @@ ++From: Pablo Neira Ayuso ++Date: Fri, 20 Nov 2020 13:49:17 +0100 ++Subject: [PATCH] bridge: resolve forwarding path for bridge devices ++ ++Add .ndo_fill_forward_path for bridge devices. ++ ++Signed-off-by: Pablo Neira Ayuso ++--- ++ ++--- a/include/linux/netdevice.h +++++ b/include/linux/netdevice.h ++@@ -836,6 +836,7 @@ typedef u16 (*select_queue_fallback_t)(s ++ enum net_device_path_type { ++ DEV_PATH_ETHERNET = 0, ++ DEV_PATH_VLAN, +++ DEV_PATH_BRIDGE, ++ }; ++ ++ struct net_device_path { ++--- a/net/bridge/br_device.c +++++ b/net/bridge/br_device.c ++@@ -398,6 +398,32 @@ static int br_del_slave(struct net_devic ++ return br_del_if(br, slave_dev); ++ } ++ +++static int br_fill_forward_path(struct net_device_path_ctx *ctx, +++ struct net_device_path *path) +++{ +++ struct net_bridge_fdb_entry *f; +++ struct net_bridge_port *dst; +++ struct net_bridge *br; +++ +++ if (netif_is_bridge_port(ctx->dev)) +++ return -1; +++ +++ br = netdev_priv(ctx->dev); +++ f = br_fdb_find_rcu(br, ctx->daddr, 0); +++ if (!f || !f->dst) +++ return -1; +++ +++ dst = READ_ONCE(f->dst); +++ if (!dst) +++ return -1; +++ +++ path->type = DEV_PATH_BRIDGE; +++ path->dev = dst->br->dev; +++ ctx->dev = dst->dev; +++ +++ return 0; +++} +++ ++ static const struct ethtool_ops br_ethtool_ops = { ++ .get_drvinfo = br_getinfo, ++ .get_link = ethtool_op_get_link, ++@@ -432,6 +458,7 @@ static const struct net_device_ops br_ne ++ .ndo_bridge_setlink = br_setlink, ++ .ndo_bridge_dellink = br_dellink, ++ .ndo_features_check = passthru_features_check, +++ .ndo_fill_forward_path = br_fill_forward_path, ++ }; ++ ++ static struct device_type br_type = { +diff --git a/target/linux/generic/pending-5.10/640-05-netfilter-flowtable-use-dev_fill_forward_path-to-obt.patch b/target/linux/generic/pending-5.10/640-05-netfilter-flowtable-use-dev_fill_forward_path-to-obt.patch +new file mode 100644 +index 0000000000..34724a5696 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/640-05-netfilter-flowtable-use-dev_fill_forward_path-to-obt.patch +@@ -0,0 +1,191 @@ ++From: Pablo Neira Ayuso ++Date: Fri, 20 Nov 2020 13:49:18 +0100 ++Subject: [PATCH] netfilter: flowtable: use dev_fill_forward_path() to ++ obtain ingress device ++ ++Obtain the ingress device in the tuple from the route in the reply ++direction. Use dev_fill_forward_path() instead to get the real ingress ++device for this flow. ++ ++Fall back to use the ingress device that the IP forwarding route ++provides if: ++ ++- dev_fill_forward_path() finds no real ingress device. ++- the ingress device that is obtained is not part of the flowtable ++ devices. ++- this route has a xfrm policy. ++ ++Signed-off-by: Pablo Neira Ayuso ++--- ++ ++--- a/include/net/netfilter/nf_flow_table.h +++++ b/include/net/netfilter/nf_flow_table.h ++@@ -165,6 +165,9 @@ static inline __s32 nf_flow_timeout_delt ++ struct nf_flow_route { ++ struct { ++ struct dst_entry *dst; +++ struct { +++ u32 ifindex; +++ } in; ++ enum flow_offload_xmit_type xmit_type; ++ } tuple[FLOW_OFFLOAD_DIR_MAX]; ++ }; ++--- a/net/netfilter/nf_flow_table_core.c +++++ b/net/netfilter/nf_flow_table_core.c ++@@ -79,7 +79,6 @@ static int flow_offload_fill_route(struc ++ enum flow_offload_tuple_dir dir) ++ { ++ struct flow_offload_tuple *flow_tuple = &flow->tuplehash[dir].tuple; ++- struct dst_entry *other_dst = route->tuple[!dir].dst; ++ struct dst_entry *dst = route->tuple[dir].dst; ++ ++ if (!dst_hold_safe(route->tuple[dir].dst)) ++@@ -94,7 +93,7 @@ static int flow_offload_fill_route(struc ++ break; ++ } ++ ++- flow_tuple->iifidx = other_dst->dev->ifindex; +++ flow_tuple->iifidx = route->tuple[dir].in.ifindex; ++ flow_tuple->xmit_type = route->tuple[dir].xmit_type; ++ flow_tuple->dst_cache = dst; ++ ++--- a/net/netfilter/nft_flow_offload.c +++++ b/net/netfilter/nft_flow_offload.c ++@@ -31,14 +31,104 @@ static void nft_default_forward_path(str ++ struct dst_entry *dst_cache, ++ enum ip_conntrack_dir dir) ++ { +++ route->tuple[!dir].in.ifindex = dst_cache->dev->ifindex; ++ route->tuple[dir].dst = dst_cache; ++ route->tuple[dir].xmit_type = nft_xmit_type(dst_cache); ++ } ++ +++static int nft_dev_fill_forward_path(const struct nf_flow_route *route, +++ const struct dst_entry *dst_cache, +++ const struct nf_conn *ct, +++ enum ip_conntrack_dir dir, +++ struct net_device_path_stack *stack) +++{ +++ const void *daddr = &ct->tuplehash[!dir].tuple.src.u3; +++ struct net_device *dev = dst_cache->dev; +++ unsigned char ha[ETH_ALEN]; +++ struct neighbour *n; +++ u8 nud_state; +++ +++ n = dst_neigh_lookup(dst_cache, daddr); +++ if (!n) +++ return -1; +++ +++ read_lock_bh(&n->lock); +++ nud_state = n->nud_state; +++ ether_addr_copy(ha, n->ha); +++ read_unlock_bh(&n->lock); +++ neigh_release(n); +++ +++ if (!(nud_state & NUD_VALID)) +++ return -1; +++ +++ return dev_fill_forward_path(dev, ha, stack); +++} +++ +++struct nft_forward_info { +++ const struct net_device *dev; +++}; +++ +++static void nft_dev_path_info(const struct net_device_path_stack *stack, +++ struct nft_forward_info *info) +++{ +++ const struct net_device_path *path; +++ int i; +++ +++ for (i = 0; i < stack->num_paths; i++) { +++ path = &stack->path[i]; +++ switch (path->type) { +++ case DEV_PATH_ETHERNET: +++ info->dev = path->dev; +++ break; +++ case DEV_PATH_VLAN: +++ case DEV_PATH_BRIDGE: +++ default: +++ info->dev = NULL; +++ break; +++ } +++ } +++} +++ +++static bool nft_flowtable_find_dev(const struct net_device *dev, +++ struct nft_flowtable *ft) +++{ +++ struct nft_hook *hook; +++ bool found = false; +++ +++ list_for_each_entry_rcu(hook, &ft->hook_list, list) { +++ if (hook->ops.dev != dev) +++ continue; +++ +++ found = true; +++ break; +++ } +++ +++ return found; +++} +++ +++static void nft_dev_forward_path(struct nf_flow_route *route, +++ const struct nf_conn *ct, +++ enum ip_conntrack_dir dir, +++ struct nft_flowtable *ft) +++{ +++ const struct dst_entry *dst = route->tuple[dir].dst; +++ struct net_device_path_stack stack; +++ struct nft_forward_info info = {}; +++ +++ if (nft_dev_fill_forward_path(route, dst, ct, dir, &stack) >= 0) +++ nft_dev_path_info(&stack, &info); +++ +++ if (!info.dev || !nft_flowtable_find_dev(info.dev, ft)) +++ return; +++ +++ route->tuple[!dir].in.ifindex = info.dev->ifindex; +++} +++ ++ static int nft_flow_route(const struct nft_pktinfo *pkt, ++ const struct nf_conn *ct, ++ struct nf_flow_route *route, ++- enum ip_conntrack_dir dir) +++ enum ip_conntrack_dir dir, +++ struct nft_flowtable *ft) ++ { ++ struct dst_entry *this_dst = skb_dst(pkt->skb); ++ struct dst_entry *other_dst = NULL; ++@@ -63,6 +153,12 @@ static int nft_flow_route(const struct n ++ nft_default_forward_path(route, this_dst, dir); ++ nft_default_forward_path(route, other_dst, !dir); ++ +++ if (route->tuple[dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH && +++ route->tuple[!dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH) { +++ nft_dev_forward_path(route, ct, dir, ft); +++ nft_dev_forward_path(route, ct, !dir, ft); +++ } +++ ++ return 0; ++ } ++ ++@@ -90,8 +186,8 @@ static void nft_flow_offload_eval(const ++ struct nft_flow_offload *priv = nft_expr_priv(expr); ++ struct nf_flowtable *flowtable = &priv->flowtable->data; ++ struct tcphdr _tcph, *tcph = NULL; +++ struct nf_flow_route route = {}; ++ enum ip_conntrack_info ctinfo; ++- struct nf_flow_route route; ++ struct flow_offload *flow; ++ enum ip_conntrack_dir dir; ++ struct nf_conn *ct; ++@@ -128,7 +224,7 @@ static void nft_flow_offload_eval(const ++ goto out; ++ ++ dir = CTINFO2DIR(ctinfo); ++- if (nft_flow_route(pkt, ct, &route, dir) < 0) +++ if (nft_flow_route(pkt, ct, &route, dir, priv->flowtable) < 0) ++ goto err_flow_route; ++ ++ flow = flow_offload_alloc(ct); +diff --git a/target/linux/generic/pending-5.10/640-06-netfilter-flowtable-use-dev_fill_forward_path-to-obt.patch b/target/linux/generic/pending-5.10/640-06-netfilter-flowtable-use-dev_fill_forward_path-to-obt.patch +new file mode 100644 +index 0000000000..d4bf68a690 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/640-06-netfilter-flowtable-use-dev_fill_forward_path-to-obt.patch +@@ -0,0 +1,336 @@ ++From: Pablo Neira Ayuso ++Date: Fri, 20 Nov 2020 13:49:19 +0100 ++Subject: [PATCH] netfilter: flowtable: use dev_fill_forward_path() to ++ obtain egress device ++ ++The egress device in the tuple is obtained from route. Use ++dev_fill_forward_path() instead to provide the real egress device for ++this flow whenever this is available. ++ ++The new FLOW_OFFLOAD_XMIT_DIRECT type uses dev_queue_xmit() to transmit ++ethernet frames. Cache the source and destination hardware address to ++use dev_queue_xmit() to transfer packets. ++ ++The FLOW_OFFLOAD_XMIT_DIRECT replaces FLOW_OFFLOAD_XMIT_NEIGH if ++dev_fill_forward_path() finds a direct transmit path. ++ ++In case of topology updates, if peer is moved to different bridge port, ++the connection will time out, reconnect will result in a new entry with ++the correct path. Snooping fdb updates would allow for cleaning up stale ++flowtable entries. ++ ++Signed-off-by: Pablo Neira Ayuso ++--- ++ ++--- a/include/net/netfilter/nf_flow_table.h +++++ b/include/net/netfilter/nf_flow_table.h ++@@ -92,6 +92,7 @@ enum flow_offload_tuple_dir { ++ enum flow_offload_xmit_type { ++ FLOW_OFFLOAD_XMIT_NEIGH = 0, ++ FLOW_OFFLOAD_XMIT_XFRM, +++ FLOW_OFFLOAD_XMIT_DIRECT, ++ }; ++ ++ struct flow_offload_tuple { ++@@ -120,8 +121,14 @@ struct flow_offload_tuple { ++ xmit_type:2; ++ ++ u16 mtu; ++- ++- struct dst_entry *dst_cache; +++ union { +++ struct dst_entry *dst_cache; +++ struct { +++ u32 ifidx; +++ u8 h_source[ETH_ALEN]; +++ u8 h_dest[ETH_ALEN]; +++ } out; +++ }; ++ }; ++ ++ struct flow_offload_tuple_rhash { ++@@ -168,6 +175,11 @@ struct nf_flow_route { ++ struct { ++ u32 ifindex; ++ } in; +++ struct { +++ u32 ifindex; +++ u8 h_source[ETH_ALEN]; +++ u8 h_dest[ETH_ALEN]; +++ } out; ++ enum flow_offload_xmit_type xmit_type; ++ } tuple[FLOW_OFFLOAD_DIR_MAX]; ++ }; ++--- a/net/netfilter/nf_flow_table_core.c +++++ b/net/netfilter/nf_flow_table_core.c ++@@ -81,9 +81,6 @@ static int flow_offload_fill_route(struc ++ struct flow_offload_tuple *flow_tuple = &flow->tuplehash[dir].tuple; ++ struct dst_entry *dst = route->tuple[dir].dst; ++ ++- if (!dst_hold_safe(route->tuple[dir].dst)) ++- return -1; ++- ++ switch (flow_tuple->l3proto) { ++ case NFPROTO_IPV4: ++ flow_tuple->mtu = ip_dst_mtu_maybe_forward(dst, true); ++@@ -94,12 +91,36 @@ static int flow_offload_fill_route(struc ++ } ++ ++ flow_tuple->iifidx = route->tuple[dir].in.ifindex; +++ +++ switch (route->tuple[dir].xmit_type) { +++ case FLOW_OFFLOAD_XMIT_DIRECT: +++ memcpy(flow_tuple->out.h_dest, route->tuple[dir].out.h_dest, +++ ETH_ALEN); +++ memcpy(flow_tuple->out.h_source, route->tuple[dir].out.h_source, +++ ETH_ALEN); +++ flow_tuple->out.ifidx = route->tuple[dir].out.ifindex; +++ break; +++ case FLOW_OFFLOAD_XMIT_XFRM: +++ case FLOW_OFFLOAD_XMIT_NEIGH: +++ if (!dst_hold_safe(route->tuple[dir].dst)) +++ return -1; +++ +++ flow_tuple->dst_cache = dst; +++ break; +++ } ++ flow_tuple->xmit_type = route->tuple[dir].xmit_type; ++- flow_tuple->dst_cache = dst; ++ ++ return 0; ++ } ++ +++static void nft_flow_dst_release(struct flow_offload *flow, +++ enum flow_offload_tuple_dir dir) +++{ +++ if (flow->tuplehash[dir].tuple.xmit_type == FLOW_OFFLOAD_XMIT_NEIGH || +++ flow->tuplehash[dir].tuple.xmit_type == FLOW_OFFLOAD_XMIT_XFRM) +++ dst_release(flow->tuplehash[dir].tuple.dst_cache); +++} +++ ++ int flow_offload_route_init(struct flow_offload *flow, ++ const struct nf_flow_route *route) ++ { ++@@ -118,7 +139,7 @@ int flow_offload_route_init(struct flow_ ++ return 0; ++ ++ err_route_reply: ++- dst_release(route->tuple[FLOW_OFFLOAD_DIR_ORIGINAL].dst); +++ nft_flow_dst_release(flow, FLOW_OFFLOAD_DIR_ORIGINAL); ++ ++ return err; ++ } ++@@ -169,8 +190,8 @@ static void flow_offload_fixup_ct(struct ++ ++ static void flow_offload_route_release(struct flow_offload *flow) ++ { ++- dst_release(flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_cache); ++- dst_release(flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_cache); +++ nft_flow_dst_release(flow, FLOW_OFFLOAD_DIR_ORIGINAL); +++ nft_flow_dst_release(flow, FLOW_OFFLOAD_DIR_REPLY); ++ } ++ ++ void flow_offload_free(struct flow_offload *flow) ++--- a/net/netfilter/nf_flow_table_ip.c +++++ b/net/netfilter/nf_flow_table_ip.c ++@@ -248,6 +248,24 @@ static unsigned int nf_flow_xmit_xfrm(st ++ return NF_STOLEN; ++ } ++ +++static unsigned int nf_flow_queue_xmit(struct net *net, struct sk_buff *skb, +++ const struct flow_offload_tuple_rhash *tuplehash, +++ unsigned short type) +++{ +++ struct net_device *outdev; +++ +++ outdev = dev_get_by_index_rcu(net, tuplehash->tuple.out.ifidx); +++ if (!outdev) +++ return NF_DROP; +++ +++ skb->dev = outdev; +++ dev_hard_header(skb, skb->dev, type, tuplehash->tuple.out.h_dest, +++ tuplehash->tuple.out.h_source, skb->len); +++ dev_queue_xmit(skb); +++ +++ return NF_STOLEN; +++} +++ ++ unsigned int ++ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb, ++ const struct nf_hook_state *state) ++@@ -262,6 +280,7 @@ nf_flow_offload_ip_hook(void *priv, stru ++ unsigned int thoff; ++ struct iphdr *iph; ++ __be32 nexthop; +++ int ret; ++ ++ if (skb->protocol != htons(ETH_P_IP)) ++ return NF_ACCEPT; ++@@ -303,22 +322,32 @@ nf_flow_offload_ip_hook(void *priv, stru ++ if (flow_table->flags & NF_FLOWTABLE_COUNTER) ++ nf_ct_acct_update(flow->ct, tuplehash->tuple.dir, skb->len); ++ ++- rt = (struct rtable *)tuplehash->tuple.dst_cache; ++- ++ if (unlikely(tuplehash->tuple.xmit_type == FLOW_OFFLOAD_XMIT_XFRM)) { +++ rt = (struct rtable *)tuplehash->tuple.dst_cache; ++ memset(skb->cb, 0, sizeof(struct inet_skb_parm)); ++ IPCB(skb)->iif = skb->dev->ifindex; ++ IPCB(skb)->flags = IPSKB_FORWARDED; ++ return nf_flow_xmit_xfrm(skb, state, &rt->dst); ++ } ++ ++- outdev = rt->dst.dev; ++- skb->dev = outdev; ++- nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr); ++- skb_dst_set_noref(skb, &rt->dst); ++- neigh_xmit(NEIGH_ARP_TABLE, outdev, &nexthop, skb); +++ switch (tuplehash->tuple.xmit_type) { +++ case FLOW_OFFLOAD_XMIT_NEIGH: +++ rt = (struct rtable *)tuplehash->tuple.dst_cache; +++ outdev = rt->dst.dev; +++ skb->dev = outdev; +++ nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr); +++ skb_dst_set_noref(skb, &rt->dst); +++ neigh_xmit(NEIGH_ARP_TABLE, outdev, &nexthop, skb); +++ ret = NF_STOLEN; +++ break; +++ case FLOW_OFFLOAD_XMIT_DIRECT: +++ ret = nf_flow_queue_xmit(state->net, skb, tuplehash, ETH_P_IP); +++ if (ret == NF_DROP) +++ flow_offload_teardown(flow); +++ break; +++ } ++ ++- return NF_STOLEN; +++ return ret; ++ } ++ EXPORT_SYMBOL_GPL(nf_flow_offload_ip_hook); ++ ++@@ -504,6 +533,7 @@ nf_flow_offload_ipv6_hook(void *priv, st ++ struct net_device *outdev; ++ struct ipv6hdr *ip6h; ++ struct rt6_info *rt; +++ int ret; ++ ++ if (skb->protocol != htons(ETH_P_IPV6)) ++ return NF_ACCEPT; ++@@ -545,21 +575,31 @@ nf_flow_offload_ipv6_hook(void *priv, st ++ if (flow_table->flags & NF_FLOWTABLE_COUNTER) ++ nf_ct_acct_update(flow->ct, tuplehash->tuple.dir, skb->len); ++ ++- rt = (struct rt6_info *)tuplehash->tuple.dst_cache; ++- ++ if (unlikely(tuplehash->tuple.xmit_type == FLOW_OFFLOAD_XMIT_XFRM)) { +++ rt = (struct rt6_info *)tuplehash->tuple.dst_cache; ++ memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); ++ IP6CB(skb)->iif = skb->dev->ifindex; ++ IP6CB(skb)->flags = IP6SKB_FORWARDED; ++ return nf_flow_xmit_xfrm(skb, state, &rt->dst); ++ } ++ ++- outdev = rt->dst.dev; ++- skb->dev = outdev; ++- nexthop = rt6_nexthop(rt, &flow->tuplehash[!dir].tuple.src_v6); ++- skb_dst_set_noref(skb, &rt->dst); ++- neigh_xmit(NEIGH_ND_TABLE, outdev, nexthop, skb); +++ switch (tuplehash->tuple.xmit_type) { +++ case FLOW_OFFLOAD_XMIT_NEIGH: +++ rt = (struct rt6_info *)tuplehash->tuple.dst_cache; +++ outdev = rt->dst.dev; +++ skb->dev = outdev; +++ nexthop = rt6_nexthop(rt, &flow->tuplehash[!dir].tuple.src_v6); +++ skb_dst_set_noref(skb, &rt->dst); +++ neigh_xmit(NEIGH_ND_TABLE, outdev, nexthop, skb); +++ ret = NF_STOLEN; +++ break; +++ case FLOW_OFFLOAD_XMIT_DIRECT: +++ ret = nf_flow_queue_xmit(state->net, skb, tuplehash, ETH_P_IPV6); +++ if (ret == NF_DROP) +++ flow_offload_teardown(flow); +++ break; +++ } ++ ++- return NF_STOLEN; +++ return ret; ++ } ++ EXPORT_SYMBOL_GPL(nf_flow_offload_ipv6_hook); ++--- a/net/netfilter/nft_flow_offload.c +++++ b/net/netfilter/nft_flow_offload.c ++@@ -39,12 +39,11 @@ static void nft_default_forward_path(str ++ static int nft_dev_fill_forward_path(const struct nf_flow_route *route, ++ const struct dst_entry *dst_cache, ++ const struct nf_conn *ct, ++- enum ip_conntrack_dir dir, +++ enum ip_conntrack_dir dir, u8 *ha, ++ struct net_device_path_stack *stack) ++ { ++ const void *daddr = &ct->tuplehash[!dir].tuple.src.u3; ++ struct net_device *dev = dst_cache->dev; ++- unsigned char ha[ETH_ALEN]; ++ struct neighbour *n; ++ u8 nud_state; ++ ++@@ -66,22 +65,35 @@ static int nft_dev_fill_forward_path(con ++ ++ struct nft_forward_info { ++ const struct net_device *dev; +++ u8 h_source[ETH_ALEN]; +++ u8 h_dest[ETH_ALEN]; +++ enum flow_offload_xmit_type xmit_type; ++ }; ++ ++ static void nft_dev_path_info(const struct net_device_path_stack *stack, ++- struct nft_forward_info *info) +++ struct nft_forward_info *info, +++ unsigned char *ha) ++ { ++ const struct net_device_path *path; ++ int i; ++ +++ memcpy(info->h_dest, ha, ETH_ALEN); +++ ++ for (i = 0; i < stack->num_paths; i++) { ++ path = &stack->path[i]; ++ switch (path->type) { ++ case DEV_PATH_ETHERNET: ++ info->dev = path->dev; +++ if (is_zero_ether_addr(info->h_source)) +++ memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN); ++ break; ++- case DEV_PATH_VLAN: ++ case DEV_PATH_BRIDGE: +++ if (is_zero_ether_addr(info->h_source)) +++ memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN); +++ +++ info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT; +++ break; +++ case DEV_PATH_VLAN: ++ default: ++ info->dev = NULL; ++ break; ++@@ -114,14 +126,22 @@ static void nft_dev_forward_path(struct ++ const struct dst_entry *dst = route->tuple[dir].dst; ++ struct net_device_path_stack stack; ++ struct nft_forward_info info = {}; +++ unsigned char ha[ETH_ALEN]; ++ ++- if (nft_dev_fill_forward_path(route, dst, ct, dir, &stack) >= 0) ++- nft_dev_path_info(&stack, &info); +++ if (nft_dev_fill_forward_path(route, dst, ct, dir, ha, &stack) >= 0) +++ nft_dev_path_info(&stack, &info, ha); ++ ++ if (!info.dev || !nft_flowtable_find_dev(info.dev, ft)) ++ return; ++ ++ route->tuple[!dir].in.ifindex = info.dev->ifindex; +++ +++ if (info.xmit_type == FLOW_OFFLOAD_XMIT_DIRECT) { +++ memcpy(route->tuple[dir].out.h_source, info.h_source, ETH_ALEN); +++ memcpy(route->tuple[dir].out.h_dest, info.h_dest, ETH_ALEN); +++ route->tuple[dir].out.ifindex = info.dev->ifindex; +++ route->tuple[dir].xmit_type = info.xmit_type; +++ } ++ } ++ ++ static int nft_flow_route(const struct nft_pktinfo *pkt, +diff --git a/target/linux/generic/pending-5.10/640-07-netfilter-flowtable-add-vlan-support.patch b/target/linux/generic/pending-5.10/640-07-netfilter-flowtable-add-vlan-support.patch +new file mode 100644 +index 0000000000..77aeaccbce +--- /dev/null ++++ b/target/linux/generic/pending-5.10/640-07-netfilter-flowtable-add-vlan-support.patch +@@ -0,0 +1,364 @@ ++From: Pablo Neira Ayuso ++Date: Fri, 20 Nov 2020 13:49:20 +0100 ++Subject: [PATCH] netfilter: flowtable: add vlan support ++ ++Add the vlan id and protocol to the flow tuple to uniquely identify ++flows from the receive path. For the transmit path, dev_hard_header() on ++the vlan device push the headers. This patch includes support for two ++VLAN headers (QinQ) from the ingress path. ++ ++Signed-off-by: Pablo Neira Ayuso ++--- ++ ++--- a/include/net/netfilter/nf_flow_table.h +++++ b/include/net/netfilter/nf_flow_table.h ++@@ -95,6 +95,8 @@ enum flow_offload_xmit_type { ++ FLOW_OFFLOAD_XMIT_DIRECT, ++ }; ++ +++#define NF_FLOW_TABLE_VLAN_MAX 2 +++ ++ struct flow_offload_tuple { ++ union { ++ struct in_addr src_v4; ++@@ -113,13 +115,17 @@ struct flow_offload_tuple { ++ ++ u8 l3proto; ++ u8 l4proto; +++ struct { +++ u16 id; +++ __be16 proto; +++ } in_vlan[NF_FLOW_TABLE_VLAN_MAX]; ++ ++ /* All members above are keys for lookups, see flow_offload_hash(). */ ++ struct { } __hash; ++ ++- u8 dir:6, ++- xmit_type:2; ++- +++ u8 dir:4, +++ xmit_type:2, +++ in_vlan_num:2; ++ u16 mtu; ++ union { ++ struct dst_entry *dst_cache; ++@@ -174,6 +180,9 @@ struct nf_flow_route { ++ struct dst_entry *dst; ++ struct { ++ u32 ifindex; +++ u16 vid[NF_FLOW_TABLE_VLAN_MAX]; +++ __be16 vproto[NF_FLOW_TABLE_VLAN_MAX]; +++ u8 num_vlans; ++ } in; ++ struct { ++ u32 ifindex; ++--- a/net/netfilter/nf_flow_table_core.c +++++ b/net/netfilter/nf_flow_table_core.c ++@@ -80,6 +80,7 @@ static int flow_offload_fill_route(struc ++ { ++ struct flow_offload_tuple *flow_tuple = &flow->tuplehash[dir].tuple; ++ struct dst_entry *dst = route->tuple[dir].dst; +++ int i, j = 0; ++ ++ switch (flow_tuple->l3proto) { ++ case NFPROTO_IPV4: ++@@ -91,6 +92,12 @@ static int flow_offload_fill_route(struc ++ } ++ ++ flow_tuple->iifidx = route->tuple[dir].in.ifindex; +++ for (i = route->tuple[dir].in.num_vlans - 1; i >= 0; i--) { +++ flow_tuple->in_vlan[j].id = route->tuple[dir].in.vid[i]; +++ flow_tuple->in_vlan[j].proto = route->tuple[dir].in.vproto[i]; +++ j++; +++ } +++ flow_tuple->in_vlan_num = route->tuple[dir].in.num_vlans; ++ ++ switch (route->tuple[dir].xmit_type) { ++ case FLOW_OFFLOAD_XMIT_DIRECT: ++--- a/net/netfilter/nf_flow_table_ip.c +++++ b/net/netfilter/nf_flow_table_ip.c ++@@ -159,17 +159,35 @@ static bool ip_has_options(unsigned int ++ return thoff != sizeof(struct iphdr); ++ } ++ +++static void nf_flow_tuple_vlan(struct sk_buff *skb, +++ struct flow_offload_tuple *tuple) +++{ +++ if (skb_vlan_tag_present(skb)) { +++ tuple->in_vlan[0].id = skb_vlan_tag_get(skb); +++ tuple->in_vlan[0].proto = skb->vlan_proto; +++ } +++ if (skb->protocol == htons(ETH_P_8021Q)) { +++ struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb_mac_header(skb); +++ +++ tuple->in_vlan[1].id = ntohs(veth->h_vlan_TCI); +++ tuple->in_vlan[1].proto = skb->protocol; +++ } +++} +++ ++ static int nf_flow_tuple_ip(struct sk_buff *skb, const struct net_device *dev, ++ struct flow_offload_tuple *tuple) ++ { ++- unsigned int thoff, hdrsize; +++ unsigned int thoff, hdrsize, offset = 0; ++ struct flow_ports *ports; ++ struct iphdr *iph; ++ ++- if (!pskb_may_pull(skb, sizeof(*iph))) +++ if (skb->protocol == htons(ETH_P_8021Q)) +++ offset += VLAN_HLEN; +++ +++ if (!pskb_may_pull(skb, sizeof(*iph) + offset)) ++ return -1; ++ ++- iph = ip_hdr(skb); +++ iph = (struct iphdr *)(skb_network_header(skb) + offset); ++ thoff = iph->ihl * 4; ++ ++ if (ip_is_fragment(iph) || ++@@ -191,11 +209,11 @@ static int nf_flow_tuple_ip(struct sk_bu ++ return -1; ++ ++ thoff = iph->ihl * 4; ++- if (!pskb_may_pull(skb, thoff + hdrsize)) +++ if (!pskb_may_pull(skb, thoff + hdrsize + offset)) ++ return -1; ++ ++- iph = ip_hdr(skb); ++- ports = (struct flow_ports *)(skb_network_header(skb) + thoff); +++ iph = (struct iphdr *)(skb_network_header(skb) + offset); +++ ports = (struct flow_ports *)(skb_network_header(skb) + thoff + offset); ++ ++ tuple->src_v4.s_addr = iph->saddr; ++ tuple->dst_v4.s_addr = iph->daddr; ++@@ -204,6 +222,7 @@ static int nf_flow_tuple_ip(struct sk_bu ++ tuple->l3proto = AF_INET; ++ tuple->l4proto = iph->protocol; ++ tuple->iifidx = dev->ifindex; +++ nf_flow_tuple_vlan(skb, tuple); ++ ++ return 0; ++ } ++@@ -248,6 +267,37 @@ static unsigned int nf_flow_xmit_xfrm(st ++ return NF_STOLEN; ++ } ++ +++static bool nf_flow_skb_vlan_protocol(const struct sk_buff *skb, __be16 proto) +++{ +++ if (skb->protocol == htons(ETH_P_8021Q)) { +++ struct vlan_ethhdr *veth; +++ +++ veth = (struct vlan_ethhdr *)skb_mac_header(skb); +++ if (veth->h_vlan_encapsulated_proto == proto) +++ return true; +++ } +++ +++ return false; +++} +++ +++static void nf_flow_vlan_pop(struct sk_buff *skb, +++ struct flow_offload_tuple_rhash *tuplehash) +++{ +++ struct vlan_hdr *vlan_hdr; +++ int i; +++ +++ for (i = 0; i < tuplehash->tuple.in_vlan_num; i++) { +++ if (skb_vlan_tag_present(skb)) { +++ __vlan_hwaccel_clear_tag(skb); +++ continue; +++ } +++ vlan_hdr = (struct vlan_hdr *)skb->data; +++ __skb_pull(skb, VLAN_HLEN); +++ vlan_set_encap_proto(skb, vlan_hdr); +++ skb_reset_network_header(skb); +++ } +++} +++ ++ static unsigned int nf_flow_queue_xmit(struct net *net, struct sk_buff *skb, ++ const struct flow_offload_tuple_rhash *tuplehash, ++ unsigned short type) ++@@ -280,9 +330,11 @@ nf_flow_offload_ip_hook(void *priv, stru ++ unsigned int thoff; ++ struct iphdr *iph; ++ __be32 nexthop; +++ u32 offset = 0; ++ int ret; ++ ++- if (skb->protocol != htons(ETH_P_IP)) +++ if (skb->protocol != htons(ETH_P_IP) && +++ !nf_flow_skb_vlan_protocol(skb, htons(ETH_P_IP))) ++ return NF_ACCEPT; ++ ++ if (nf_flow_tuple_ip(skb, state->in, &tuple) < 0) ++@@ -298,11 +350,15 @@ nf_flow_offload_ip_hook(void *priv, stru ++ if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu))) ++ return NF_ACCEPT; ++ ++- if (skb_try_make_writable(skb, sizeof(*iph))) +++ if (skb->protocol == htons(ETH_P_8021Q)) +++ offset += VLAN_HLEN; +++ +++ if (skb_try_make_writable(skb, sizeof(*iph) + offset)) ++ return NF_DROP; ++ ++- thoff = ip_hdr(skb)->ihl * 4; ++- if (nf_flow_state_check(flow, ip_hdr(skb)->protocol, skb, thoff)) +++ iph = (struct iphdr *)(skb_network_header(skb) + offset); +++ thoff = (iph->ihl * 4) + offset; +++ if (nf_flow_state_check(flow, iph->protocol, skb, thoff)) ++ return NF_ACCEPT; ++ ++ flow_offload_refresh(flow_table, flow); ++@@ -312,6 +368,9 @@ nf_flow_offload_ip_hook(void *priv, stru ++ return NF_ACCEPT; ++ } ++ +++ nf_flow_vlan_pop(skb, tuplehash); +++ thoff -= offset; +++ ++ if (nf_flow_nat_ip(flow, skb, thoff, dir) < 0) ++ return NF_DROP; ++ ++@@ -479,14 +538,17 @@ static int nf_flow_nat_ipv6(const struct ++ static int nf_flow_tuple_ipv6(struct sk_buff *skb, const struct net_device *dev, ++ struct flow_offload_tuple *tuple) ++ { ++- unsigned int thoff, hdrsize; +++ unsigned int thoff, hdrsize, offset = 0; ++ struct flow_ports *ports; ++ struct ipv6hdr *ip6h; ++ ++- if (!pskb_may_pull(skb, sizeof(*ip6h))) +++ if (skb->protocol == htons(ETH_P_8021Q)) +++ offset += VLAN_HLEN; +++ +++ if (!pskb_may_pull(skb, sizeof(*ip6h) + offset)) ++ return -1; ++ ++- ip6h = ipv6_hdr(skb); +++ ip6h = (struct ipv6hdr *)(skb_network_header(skb) + offset); ++ ++ switch (ip6h->nexthdr) { ++ case IPPROTO_TCP: ++@@ -503,11 +565,11 @@ static int nf_flow_tuple_ipv6(struct sk_ ++ return -1; ++ ++ thoff = sizeof(*ip6h); ++- if (!pskb_may_pull(skb, thoff + hdrsize)) +++ if (!pskb_may_pull(skb, thoff + hdrsize + offset)) ++ return -1; ++ ++- ip6h = ipv6_hdr(skb); ++- ports = (struct flow_ports *)(skb_network_header(skb) + thoff); +++ ip6h = (struct ipv6hdr *)(skb_network_header(skb) + offset); +++ ports = (struct flow_ports *)(skb_network_header(skb) + thoff + offset); ++ ++ tuple->src_v6 = ip6h->saddr; ++ tuple->dst_v6 = ip6h->daddr; ++@@ -516,6 +578,7 @@ static int nf_flow_tuple_ipv6(struct sk_ ++ tuple->l3proto = AF_INET6; ++ tuple->l4proto = ip6h->nexthdr; ++ tuple->iifidx = dev->ifindex; +++ nf_flow_tuple_vlan(skb, tuple); ++ ++ return 0; ++ } ++@@ -533,9 +596,11 @@ nf_flow_offload_ipv6_hook(void *priv, st ++ struct net_device *outdev; ++ struct ipv6hdr *ip6h; ++ struct rt6_info *rt; +++ u32 offset = 0; ++ int ret; ++ ++- if (skb->protocol != htons(ETH_P_IPV6)) +++ if (skb->protocol != htons(ETH_P_IPV6) && +++ !nf_flow_skb_vlan_protocol(skb, htons(ETH_P_IPV6))) ++ return NF_ACCEPT; ++ ++ if (nf_flow_tuple_ipv6(skb, state->in, &tuple) < 0) ++@@ -551,8 +616,11 @@ nf_flow_offload_ipv6_hook(void *priv, st ++ if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu))) ++ return NF_ACCEPT; ++ ++- if (nf_flow_state_check(flow, ipv6_hdr(skb)->nexthdr, skb, ++- sizeof(*ip6h))) +++ if (skb->protocol == htons(ETH_P_8021Q)) +++ offset += VLAN_HLEN; +++ +++ ip6h = (struct ipv6hdr *)(skb_network_header(skb) + offset); +++ if (nf_flow_state_check(flow, ip6h->nexthdr, skb, sizeof(*ip6h))) ++ return NF_ACCEPT; ++ ++ flow_offload_refresh(flow_table, flow); ++@@ -562,6 +630,8 @@ nf_flow_offload_ipv6_hook(void *priv, st ++ return NF_ACCEPT; ++ } ++ +++ nf_flow_vlan_pop(skb, tuplehash); +++ ++ if (skb_try_make_writable(skb, sizeof(*ip6h))) ++ return NF_DROP; ++ ++--- a/net/netfilter/nft_flow_offload.c +++++ b/net/netfilter/nft_flow_offload.c ++@@ -65,6 +65,9 @@ static int nft_dev_fill_forward_path(con ++ ++ struct nft_forward_info { ++ const struct net_device *dev; +++ __u16 vid[NF_FLOW_TABLE_VLAN_MAX]; +++ __be16 vproto[NF_FLOW_TABLE_VLAN_MAX]; +++ u8 num_vlans; ++ u8 h_source[ETH_ALEN]; ++ u8 h_dest[ETH_ALEN]; ++ enum flow_offload_xmit_type xmit_type; ++@@ -83,9 +86,22 @@ static void nft_dev_path_info(const stru ++ path = &stack->path[i]; ++ switch (path->type) { ++ case DEV_PATH_ETHERNET: +++ case DEV_PATH_VLAN: ++ info->dev = path->dev; ++ if (is_zero_ether_addr(info->h_source)) ++ memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN); +++ +++ if (path->type == DEV_PATH_ETHERNET) +++ break; +++ +++ /* DEV_PATH_VLAN */ +++ if (info->num_vlans >= NF_FLOW_TABLE_VLAN_MAX) { +++ info->dev = NULL; +++ break; +++ } +++ info->vid[info->num_vlans] = path->vlan.id; +++ info->vproto[info->num_vlans] = path->vlan.proto; +++ info->num_vlans++; ++ break; ++ case DEV_PATH_BRIDGE: ++ if (is_zero_ether_addr(info->h_source)) ++@@ -93,7 +109,6 @@ static void nft_dev_path_info(const stru ++ ++ info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT; ++ break; ++- case DEV_PATH_VLAN: ++ default: ++ info->dev = NULL; ++ break; ++@@ -127,6 +142,7 @@ static void nft_dev_forward_path(struct ++ struct net_device_path_stack stack; ++ struct nft_forward_info info = {}; ++ unsigned char ha[ETH_ALEN]; +++ int i; ++ ++ if (nft_dev_fill_forward_path(route, dst, ct, dir, ha, &stack) >= 0) ++ nft_dev_path_info(&stack, &info, ha); ++@@ -135,6 +151,11 @@ static void nft_dev_forward_path(struct ++ return; ++ ++ route->tuple[!dir].in.ifindex = info.dev->ifindex; +++ for (i = 0; i < info.num_vlans; i++) { +++ route->tuple[!dir].in.vid[i] = info.vid[i]; +++ route->tuple[!dir].in.vproto[i] = info.vproto[i]; +++ } +++ route->tuple[!dir].in.num_vlans = info.num_vlans; ++ ++ if (info.xmit_type == FLOW_OFFLOAD_XMIT_DIRECT) { ++ memcpy(route->tuple[dir].out.h_source, info.h_source, ETH_ALEN); +diff --git a/target/linux/generic/pending-5.10/640-08-selftests-netfilter-flowtable-bridge-and-VLAN-suppor.patch b/target/linux/generic/pending-5.10/640-08-selftests-netfilter-flowtable-bridge-and-VLAN-suppor.patch +new file mode 100644 +index 0000000000..1ee015c6aa +--- /dev/null ++++ b/target/linux/generic/pending-5.10/640-08-selftests-netfilter-flowtable-bridge-and-VLAN-suppor.patch +@@ -0,0 +1,107 @@ ++From: Pablo Neira Ayuso ++Date: Fri, 20 Nov 2020 13:49:21 +0100 ++Subject: [PATCH] selftests: netfilter: flowtable bridge and VLAN support ++ ++This patch adds two new tests to cover bridge and VLAN support: ++ ++- Add a bridge device to the Router1 (nsr1) container and attach the ++ veth0 device to the bridge. Set the IP address to the bridge device ++ to exercise the bridge forwarding path. ++ ++- Add VLAN encapsulation between to the bridge device in the Router1 and ++ one of the sender containers (ns1). ++ ++Signed-off-by: Pablo Neira Ayuso ++--- ++ ++--- a/tools/testing/selftests/netfilter/nft_flowtable.sh +++++ b/tools/testing/selftests/netfilter/nft_flowtable.sh ++@@ -371,6 +371,88 @@ else ++ ip netns exec nsr1 nft list ruleset ++ fi ++ +++# Another test: +++# Add bridge interface br0 to Router1, with NAT enabled. +++ip -net nsr1 link add name br0 type bridge +++ip -net nsr1 addr flush dev veth0 +++ip -net nsr1 link set up dev veth0 +++ip -net nsr1 link set veth0 master br0 +++ip -net nsr1 addr add 10.0.1.1/24 dev br0 +++ip -net nsr1 addr add dead:1::1/64 dev br0 +++ip -net nsr1 link set up dev br0 +++ +++ip netns exec nsr1 sysctl net.ipv4.conf.br0.forwarding=1 > /dev/null +++ +++# br0 with NAT enabled. +++ip netns exec nsr1 nft -f - <&2 +++ ip netns exec nsr1 nft list ruleset +++ ret=1 +++fi +++ +++# Another test: +++# Add bridge interface br0 to Router1, with NAT and VLAN. +++ip -net nsr1 link set veth0 nomaster +++ip -net nsr1 link set down dev veth0 +++ip -net nsr1 link add link veth0 name veth0.10 type vlan id 10 +++ip -net nsr1 link set up dev veth0 +++ip -net nsr1 link set up dev veth0.10 +++ip -net nsr1 link set veth0.10 master br0 +++ +++ip -net ns1 addr flush dev eth0 +++ip -net ns1 link add link eth0 name eth0.10 type vlan id 10 +++ip -net ns1 link set eth0 up +++ip -net ns1 link set eth0.10 up +++ip -net ns1 addr add 10.0.1.99/24 dev eth0.10 +++ip -net ns1 route add default via 10.0.1.1 +++ip -net ns1 addr add dead:1::99/64 dev eth0.10 +++ +++if test_tcp_forwarding_nat ns1 ns2; then +++ echo "PASS: flow offloaded for ns1/ns2 with bridge NAT and VLAN" +++else +++ echo "FAIL: flow offload for ns1/ns2 with bridge NAT and VLAN" 1>&2 +++ ip netns exec nsr1 nft list ruleset +++ ret=1 +++fi +++ +++# restore test topology (remove bridge and VLAN) +++ip -net nsr1 link set veth0 nomaster +++ip -net nsr1 link set veth0 down +++ip -net nsr1 link set veth0.10 down +++ip -net nsr1 link delete veth0.10 type vlan +++ip -net nsr1 link delete br0 type bridge +++ip -net ns1 addr flush dev eth0.10 +++ip -net ns1 link set eth0.10 down +++ip -net ns1 link set eth0 down +++ip -net ns1 link delete eth0.10 type vlan +++ +++# restore address in ns1 and nsr1 +++ip -net ns1 link set eth0 up +++ip -net ns1 addr add 10.0.1.99/24 dev eth0 +++ip -net ns1 route add default via 10.0.1.1 +++ip -net ns1 addr add dead:1::99/64 dev eth0 +++ip -net ns1 route add default via dead:1::1 +++ip -net nsr1 addr add 10.0.1.1/24 dev veth0 +++ip -net nsr1 addr add dead:1::1/64 dev veth0 +++ip -net nsr1 link set up dev veth0 +++ ++ KEY_SHA="0x"$(ps -xaf | sha1sum | cut -d " " -f 1) ++ KEY_AES="0x"$(ps -xaf | md5sum | cut -d " " -f 1) ++ SPI1=$RANDOM +diff --git a/target/linux/generic/pending-5.10/640-09-net-bridge-resolve-VLAN-tag-actions-in-forwarding-pa.patch b/target/linux/generic/pending-5.10/640-09-net-bridge-resolve-VLAN-tag-actions-in-forwarding-pa.patch +new file mode 100644 +index 0000000000..fb5f736648 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/640-09-net-bridge-resolve-VLAN-tag-actions-in-forwarding-pa.patch +@@ -0,0 +1,207 @@ ++From: Felix Fietkau ++Date: Mon, 7 Dec 2020 20:31:45 +0100 ++Subject: [PATCH] net: bridge: resolve VLAN tag actions in forwarding ++ path for bridge devices ++ ++Depending on the VLAN settings of the bridge and the port, the bridge can ++either add or remove a tag. When vlan filtering is enabled, the fdb lookup ++also needs to know the VLAN tag/proto for the destination address ++To provide this, keep track of the stack of VLAN tags for the path in the ++lookup context ++ ++Signed-off-by: Felix Fietkau ++Signed-off-by: Pablo Neira Ayuso ++--- ++ ++--- a/include/linux/netdevice.h +++++ b/include/linux/netdevice.h ++@@ -847,10 +847,20 @@ struct net_device_path { ++ u16 id; ++ __be16 proto; ++ } vlan; +++ struct { +++ enum { +++ DEV_PATH_BR_VLAN_KEEP, +++ DEV_PATH_BR_VLAN_TAG, +++ DEV_PATH_BR_VLAN_UNTAG, +++ } vlan_mode; +++ u16 vlan_id; +++ __be16 vlan_proto; +++ } bridge; ++ }; ++ }; ++ ++ #define NET_DEVICE_PATH_STACK_MAX 5 +++#define NET_DEVICE_PATH_VLAN_MAX 2 ++ ++ struct net_device_path_stack { ++ int num_paths; ++@@ -860,6 +870,12 @@ struct net_device_path_stack { ++ struct net_device_path_ctx { ++ const struct net_device *dev; ++ const u8 *daddr; +++ +++ int num_vlans; +++ struct { +++ u16 id; +++ __be16 proto; +++ } vlan[NET_DEVICE_PATH_VLAN_MAX]; ++ }; ++ ++ enum tc_setup_type { ++--- a/net/8021q/vlan_dev.c +++++ b/net/8021q/vlan_dev.c ++@@ -777,6 +777,12 @@ static int vlan_dev_fill_forward_path(st ++ path->vlan.proto = vlan->vlan_proto; ++ path->dev = ctx->dev; ++ ctx->dev = vlan->real_dev; +++ if (ctx->num_vlans >= ARRAY_SIZE(ctx->vlan)) +++ return -ENOSPC; +++ +++ ctx->vlan[ctx->num_vlans].id = vlan->vlan_id; +++ ctx->vlan[ctx->num_vlans].proto = vlan->vlan_proto; +++ ctx->num_vlans++; ++ ++ return 0; ++ } ++--- a/net/bridge/br_device.c +++++ b/net/bridge/br_device.c ++@@ -409,7 +409,10 @@ static int br_fill_forward_path(struct n ++ return -1; ++ ++ br = netdev_priv(ctx->dev); ++- f = br_fdb_find_rcu(br, ctx->daddr, 0); +++ +++ br_vlan_fill_forward_path_pvid(br, ctx, path); +++ +++ f = br_fdb_find_rcu(br, ctx->daddr, path->bridge.vlan_id); ++ if (!f || !f->dst) ++ return -1; ++ ++@@ -417,10 +420,28 @@ static int br_fill_forward_path(struct n ++ if (!dst) ++ return -1; ++ +++ if (br_vlan_fill_forward_path_mode(br, dst, path)) +++ return -1; +++ ++ path->type = DEV_PATH_BRIDGE; ++ path->dev = dst->br->dev; ++ ctx->dev = dst->dev; ++ +++ switch (path->bridge.vlan_mode) { +++ case DEV_PATH_BR_VLAN_TAG: +++ if (ctx->num_vlans >= ARRAY_SIZE(ctx->vlan)) +++ return -ENOSPC; +++ ctx->vlan[ctx->num_vlans].id = path->bridge.vlan_id; +++ ctx->vlan[ctx->num_vlans].proto = path->bridge.vlan_proto; +++ ctx->num_vlans++; +++ break; +++ case DEV_PATH_BR_VLAN_UNTAG: +++ ctx->num_vlans--; +++ break; +++ case DEV_PATH_BR_VLAN_KEEP: +++ break; +++ } +++ ++ return 0; ++ } ++ ++--- a/net/bridge/br_private.h +++++ b/net/bridge/br_private.h ++@@ -1095,6 +1095,13 @@ void br_vlan_notify(const struct net_bri ++ bool br_vlan_can_enter_range(const struct net_bridge_vlan *v_curr, ++ const struct net_bridge_vlan *range_end); ++ +++void br_vlan_fill_forward_path_pvid(struct net_bridge *br, +++ struct net_device_path_ctx *ctx, +++ struct net_device_path *path); +++int br_vlan_fill_forward_path_mode(struct net_bridge *br, +++ struct net_bridge_port *dst, +++ struct net_device_path *path); +++ ++ static inline struct net_bridge_vlan_group *br_vlan_group( ++ const struct net_bridge *br) ++ { ++@@ -1252,6 +1259,19 @@ static inline int nbp_get_num_vlan_infos ++ { ++ return 0; ++ } +++ +++static inline void br_vlan_fill_forward_path_pvid(struct net_bridge *br, +++ struct net_device_path_ctx *ctx, +++ struct net_device_path *path) +++{ +++} +++ +++static inline int br_vlan_fill_forward_path_mode(struct net_bridge *br, +++ struct net_bridge_port *dst, +++ struct net_device_path *path) +++{ +++ return 0; +++} ++ ++ static inline struct net_bridge_vlan_group *br_vlan_group( ++ const struct net_bridge *br) ++--- a/net/bridge/br_vlan.c +++++ b/net/bridge/br_vlan.c ++@@ -1327,6 +1327,59 @@ int br_vlan_get_pvid_rcu(const struct ne ++ } ++ EXPORT_SYMBOL_GPL(br_vlan_get_pvid_rcu); ++ +++void br_vlan_fill_forward_path_pvid(struct net_bridge *br, +++ struct net_device_path_ctx *ctx, +++ struct net_device_path *path) +++{ +++ struct net_bridge_vlan_group *vg; +++ int idx = ctx->num_vlans - 1; +++ u16 vid; +++ +++ path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP; +++ +++ if (!br_opt_get(br, BROPT_VLAN_ENABLED)) +++ return; +++ +++ vg = br_vlan_group(br); +++ +++ if (idx >= 0 && +++ ctx->vlan[idx].proto == br->vlan_proto) { +++ vid = ctx->vlan[idx].id; +++ } else { +++ path->bridge.vlan_mode = DEV_PATH_BR_VLAN_TAG; +++ vid = br_get_pvid(vg); +++ } +++ +++ path->bridge.vlan_id = vid; +++ path->bridge.vlan_proto = br->vlan_proto; +++} +++ +++int br_vlan_fill_forward_path_mode(struct net_bridge *br, +++ struct net_bridge_port *dst, +++ struct net_device_path *path) +++{ +++ struct net_bridge_vlan_group *vg; +++ struct net_bridge_vlan *v; +++ +++ if (!br_opt_get(br, BROPT_VLAN_ENABLED)) +++ return 0; +++ +++ vg = nbp_vlan_group_rcu(dst); +++ v = br_vlan_find(vg, path->bridge.vlan_id); +++ if (!v || !br_vlan_should_use(v)) +++ return -EINVAL; +++ +++ if (!(v->flags & BRIDGE_VLAN_INFO_UNTAGGED)) +++ return 0; +++ +++ if (path->bridge.vlan_mode == DEV_PATH_BR_VLAN_TAG) +++ path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP; +++ else +++ path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG; +++ +++ return 0; +++} +++ ++ int br_vlan_get_info(const struct net_device *dev, u16 vid, ++ struct bridge_vlan_info *p_vinfo) ++ { +diff --git a/target/linux/generic/pending-5.10/640-10-net-dsa-resolve-forwarding-path-for-dsa-slave-ports.patch b/target/linux/generic/pending-5.10/640-10-net-dsa-resolve-forwarding-path-for-dsa-slave-ports.patch +new file mode 100644 +index 0000000000..64a2b14af5 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/640-10-net-dsa-resolve-forwarding-path-for-dsa-slave-ports.patch +@@ -0,0 +1,62 @@ ++From: Felix Fietkau ++Date: Mon, 7 Dec 2020 20:31:48 +0100 ++Subject: [PATCH] net: dsa: resolve forwarding path for dsa slave ports ++ ++Add .ndo_fill_forward_path for dsa slave port devices ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/include/linux/netdevice.h +++++ b/include/linux/netdevice.h ++@@ -837,6 +837,7 @@ enum net_device_path_type { ++ DEV_PATH_ETHERNET = 0, ++ DEV_PATH_VLAN, ++ DEV_PATH_BRIDGE, +++ DEV_PATH_DSA, ++ }; ++ ++ struct net_device_path { ++@@ -856,6 +857,10 @@ struct net_device_path { ++ u16 vlan_id; ++ __be16 vlan_proto; ++ } bridge; +++ struct { +++ int port; +++ u16 proto; +++ } dsa; ++ }; ++ }; ++ ++--- a/net/dsa/slave.c +++++ b/net/dsa/slave.c ++@@ -1582,6 +1582,21 @@ static struct devlink_port *dsa_slave_ge ++ return dp->ds->devlink ? &dp->devlink_port : NULL; ++ } ++ +++static int dsa_slave_fill_forward_path(struct net_device_path_ctx *ctx, +++ struct net_device_path *path) +++{ +++ struct dsa_port *dp = dsa_slave_to_port(ctx->dev); +++ struct dsa_port *cpu_dp = dp->cpu_dp; +++ +++ path->dev = ctx->dev; +++ path->type = DEV_PATH_DSA; +++ path->dsa.proto = cpu_dp->tag_ops->proto; +++ path->dsa.port = dp->index; +++ ctx->dev = cpu_dp->master; +++ +++ return 0; +++} +++ ++ static const struct net_device_ops dsa_slave_netdev_ops = { ++ .ndo_open = dsa_slave_open, ++ .ndo_stop = dsa_slave_close, ++@@ -1607,6 +1622,7 @@ static const struct net_device_ops dsa_s ++ .ndo_vlan_rx_kill_vid = dsa_slave_vlan_rx_kill_vid, ++ .ndo_get_devlink_port = dsa_slave_get_devlink_port, ++ .ndo_change_mtu = dsa_slave_change_mtu, +++ .ndo_fill_forward_path = dsa_slave_fill_forward_path, ++ }; ++ ++ static struct device_type dsa_type = { +diff --git a/target/linux/generic/pending-5.10/640-11-netfilter-flowtable-add-offload-support-for-xmit-pat.patch b/target/linux/generic/pending-5.10/640-11-netfilter-flowtable-add-offload-support-for-xmit-pat.patch +new file mode 100644 +index 0000000000..5e3c7e031a +--- /dev/null ++++ b/target/linux/generic/pending-5.10/640-11-netfilter-flowtable-add-offload-support-for-xmit-pat.patch +@@ -0,0 +1,307 @@ ++From: Pablo Neira Ayuso ++Date: Mon, 7 Dec 2020 20:31:44 +0100 ++Subject: [PATCH] netfilter: flowtable: add offload support for xmit path ++ types ++ ++When the flow tuple xmit_type is set to FLOW_OFFLOAD_XMIT_DIRECT, the ++dst_cache pointer is not valid, and the h_source/h_dest/ifidx out fields ++need to be used. ++ ++This patch also adds the FLOW_ACTION_VLAN_PUSH action to pass the VLAN ++tag to the driver. ++--- ++ ++--- a/net/netfilter/nf_flow_table_offload.c +++++ b/net/netfilter/nf_flow_table_offload.c ++@@ -175,28 +175,45 @@ static int flow_offload_eth_src(struct n ++ enum flow_offload_tuple_dir dir, ++ struct nf_flow_rule *flow_rule) ++ { ++- const struct flow_offload_tuple *tuple = &flow->tuplehash[!dir].tuple; ++ struct flow_action_entry *entry0 = flow_action_entry_next(flow_rule); ++ struct flow_action_entry *entry1 = flow_action_entry_next(flow_rule); ++- struct net_device *dev; +++ const struct flow_offload_tuple *other_tuple, *this_tuple; +++ struct net_device *dev = NULL; +++ const unsigned char *addr; ++ u32 mask, val; ++ u16 val16; ++ ++- dev = dev_get_by_index(net, tuple->iifidx); ++- if (!dev) ++- return -ENOENT; +++ this_tuple = &flow->tuplehash[dir].tuple; +++ +++ switch (this_tuple->xmit_type) { +++ case FLOW_OFFLOAD_XMIT_DIRECT: +++ addr = this_tuple->out.h_source; +++ break; +++ case FLOW_OFFLOAD_XMIT_NEIGH: +++ other_tuple = &flow->tuplehash[!dir].tuple; +++ dev = dev_get_by_index(net, other_tuple->iifidx); +++ if (!dev) +++ return -ENOENT; +++ +++ addr = dev->dev_addr; +++ break; +++ default: +++ return -EOPNOTSUPP; +++ } ++ ++ mask = ~0xffff0000; ++- memcpy(&val16, dev->dev_addr, 2); +++ memcpy(&val16, addr, 2); ++ val = val16 << 16; ++ flow_offload_mangle(entry0, FLOW_ACT_MANGLE_HDR_TYPE_ETH, 4, ++ &val, &mask); ++ ++ mask = ~0xffffffff; ++- memcpy(&val, dev->dev_addr + 2, 4); +++ memcpy(&val, addr + 2, 4); ++ flow_offload_mangle(entry1, FLOW_ACT_MANGLE_HDR_TYPE_ETH, 8, ++ &val, &mask); ++- dev_put(dev); +++ +++ if (dev) +++ dev_put(dev); ++ ++ return 0; ++ } ++@@ -208,27 +225,40 @@ static int flow_offload_eth_dst(struct n ++ { ++ struct flow_action_entry *entry0 = flow_action_entry_next(flow_rule); ++ struct flow_action_entry *entry1 = flow_action_entry_next(flow_rule); ++- const void *daddr = &flow->tuplehash[!dir].tuple.src_v4; +++ const struct flow_offload_tuple *other_tuple, *this_tuple; ++ const struct dst_entry *dst_cache; ++ unsigned char ha[ETH_ALEN]; ++ struct neighbour *n; +++ const void *daddr; ++ u32 mask, val; ++ u8 nud_state; ++ u16 val16; ++ ++- dst_cache = flow->tuplehash[dir].tuple.dst_cache; ++- n = dst_neigh_lookup(dst_cache, daddr); ++- if (!n) ++- return -ENOENT; +++ this_tuple = &flow->tuplehash[dir].tuple; ++ ++- read_lock_bh(&n->lock); ++- nud_state = n->nud_state; ++- ether_addr_copy(ha, n->ha); ++- read_unlock_bh(&n->lock); +++ switch (this_tuple->xmit_type) { +++ case FLOW_OFFLOAD_XMIT_DIRECT: +++ ether_addr_copy(ha, this_tuple->out.h_dest); +++ break; +++ case FLOW_OFFLOAD_XMIT_NEIGH: +++ other_tuple = &flow->tuplehash[!dir].tuple; +++ daddr = &other_tuple->src_v4; +++ dst_cache = this_tuple->dst_cache; +++ n = dst_neigh_lookup(dst_cache, daddr); +++ if (!n) +++ return -ENOENT; ++ ++- if (!(nud_state & NUD_VALID)) { +++ read_lock_bh(&n->lock); +++ nud_state = n->nud_state; +++ ether_addr_copy(ha, n->ha); +++ read_unlock_bh(&n->lock); ++ neigh_release(n); ++- return -ENOENT; +++ +++ if (!(nud_state & NUD_VALID)) +++ return -ENOENT; +++ break; +++ default: +++ return -EOPNOTSUPP; ++ } ++ ++ mask = ~0xffffffff; ++@@ -241,7 +271,6 @@ static int flow_offload_eth_dst(struct n ++ val = val16; ++ flow_offload_mangle(entry1, FLOW_ACT_MANGLE_HDR_TYPE_ETH, 4, ++ &val, &mask); ++- neigh_release(n); ++ ++ return 0; ++ } ++@@ -463,27 +492,52 @@ static void flow_offload_ipv4_checksum(s ++ } ++ } ++ ++-static void flow_offload_redirect(const struct flow_offload *flow, +++static void flow_offload_redirect(struct net *net, +++ const struct flow_offload *flow, ++ enum flow_offload_tuple_dir dir, ++ struct nf_flow_rule *flow_rule) ++ { ++- struct flow_action_entry *entry = flow_action_entry_next(flow_rule); ++- struct rtable *rt; +++ const struct flow_offload_tuple *this_tuple, *other_tuple; +++ struct flow_action_entry *entry; +++ struct net_device *dev; +++ int ifindex; ++ ++- rt = (struct rtable *)flow->tuplehash[dir].tuple.dst_cache; +++ this_tuple = &flow->tuplehash[dir].tuple; +++ switch (this_tuple->xmit_type) { +++ case FLOW_OFFLOAD_XMIT_DIRECT: +++ this_tuple = &flow->tuplehash[dir].tuple; +++ ifindex = this_tuple->out.ifidx; +++ break; +++ case FLOW_OFFLOAD_XMIT_NEIGH: +++ other_tuple = &flow->tuplehash[!dir].tuple; +++ ifindex = other_tuple->iifidx; +++ break; +++ default: +++ return; +++ } +++ +++ dev = dev_get_by_index(net, ifindex); +++ if (!dev) +++ return; +++ +++ entry = flow_action_entry_next(flow_rule); ++ entry->id = FLOW_ACTION_REDIRECT; ++- entry->dev = rt->dst.dev; ++- dev_hold(rt->dst.dev); +++ entry->dev = dev; ++ } ++ ++ static void flow_offload_encap_tunnel(const struct flow_offload *flow, ++ enum flow_offload_tuple_dir dir, ++ struct nf_flow_rule *flow_rule) ++ { +++ const struct flow_offload_tuple *this_tuple; ++ struct flow_action_entry *entry; ++ struct dst_entry *dst; ++ ++- dst = flow->tuplehash[dir].tuple.dst_cache; +++ this_tuple = &flow->tuplehash[dir].tuple; +++ if (this_tuple->xmit_type == FLOW_OFFLOAD_XMIT_DIRECT) +++ return; +++ +++ dst = this_tuple->dst_cache; ++ if (dst && dst->lwtstate) { ++ struct ip_tunnel_info *tun_info; ++ ++@@ -500,10 +554,15 @@ static void flow_offload_decap_tunnel(co ++ enum flow_offload_tuple_dir dir, ++ struct nf_flow_rule *flow_rule) ++ { +++ const struct flow_offload_tuple *other_tuple; ++ struct flow_action_entry *entry; ++ struct dst_entry *dst; ++ ++- dst = flow->tuplehash[!dir].tuple.dst_cache; +++ other_tuple = &flow->tuplehash[!dir].tuple; +++ if (other_tuple->xmit_type == FLOW_OFFLOAD_XMIT_DIRECT) +++ return; +++ +++ dst = other_tuple->dst_cache; ++ if (dst && dst->lwtstate) { ++ struct ip_tunnel_info *tun_info; ++ ++@@ -515,10 +574,14 @@ static void flow_offload_decap_tunnel(co ++ } ++ } ++ ++-int nf_flow_rule_route_ipv4(struct net *net, const struct flow_offload *flow, ++- enum flow_offload_tuple_dir dir, ++- struct nf_flow_rule *flow_rule) +++static int +++nf_flow_rule_route_common(struct net *net, const struct flow_offload *flow, +++ enum flow_offload_tuple_dir dir, +++ struct nf_flow_rule *flow_rule) ++ { +++ const struct flow_offload_tuple *other_tuple; +++ int i; +++ ++ flow_offload_decap_tunnel(flow, dir, flow_rule); ++ flow_offload_encap_tunnel(flow, dir, flow_rule); ++ ++@@ -526,6 +589,26 @@ int nf_flow_rule_route_ipv4(struct net * ++ flow_offload_eth_dst(net, flow, dir, flow_rule) < 0) ++ return -1; ++ +++ other_tuple = &flow->tuplehash[!dir].tuple; +++ +++ for (i = 0; i < other_tuple->in_vlan_num; i++) { +++ struct flow_action_entry *entry = flow_action_entry_next(flow_rule); +++ +++ entry->id = FLOW_ACTION_VLAN_PUSH; +++ entry->vlan.vid = other_tuple->in_vlan[i].id; +++ entry->vlan.proto = other_tuple->in_vlan[i].proto; +++ } +++ +++ return 0; +++} +++ +++int nf_flow_rule_route_ipv4(struct net *net, const struct flow_offload *flow, +++ enum flow_offload_tuple_dir dir, +++ struct nf_flow_rule *flow_rule) +++{ +++ if (nf_flow_rule_route_common(net, flow, dir, flow_rule) < 0) +++ return -1; +++ ++ if (test_bit(NF_FLOW_SNAT, &flow->flags)) { ++ flow_offload_ipv4_snat(net, flow, dir, flow_rule); ++ flow_offload_port_snat(net, flow, dir, flow_rule); ++@@ -538,7 +621,7 @@ int nf_flow_rule_route_ipv4(struct net * ++ test_bit(NF_FLOW_DNAT, &flow->flags)) ++ flow_offload_ipv4_checksum(net, flow, flow_rule); ++ ++- flow_offload_redirect(flow, dir, flow_rule); +++ flow_offload_redirect(net, flow, dir, flow_rule); ++ ++ return 0; ++ } ++@@ -548,11 +631,7 @@ int nf_flow_rule_route_ipv6(struct net * ++ enum flow_offload_tuple_dir dir, ++ struct nf_flow_rule *flow_rule) ++ { ++- flow_offload_decap_tunnel(flow, dir, flow_rule); ++- flow_offload_encap_tunnel(flow, dir, flow_rule); ++- ++- if (flow_offload_eth_src(net, flow, dir, flow_rule) < 0 || ++- flow_offload_eth_dst(net, flow, dir, flow_rule) < 0) +++ if (nf_flow_rule_route_common(net, flow, dir, flow_rule) < 0) ++ return -1; ++ ++ if (test_bit(NF_FLOW_SNAT, &flow->flags)) { ++@@ -564,7 +643,7 @@ int nf_flow_rule_route_ipv6(struct net * ++ flow_offload_port_dnat(net, flow, dir, flow_rule); ++ } ++ ++- flow_offload_redirect(flow, dir, flow_rule); +++ flow_offload_redirect(net, flow, dir, flow_rule); ++ ++ return 0; ++ } ++@@ -578,10 +657,10 @@ nf_flow_offload_rule_alloc(struct net *n ++ enum flow_offload_tuple_dir dir) ++ { ++ const struct nf_flowtable *flowtable = offload->flowtable; +++ const struct flow_offload_tuple *tuple, *other_tuple; ++ const struct flow_offload *flow = offload->flow; ++- const struct flow_offload_tuple *tuple; +++ struct dst_entry *other_dst = NULL; ++ struct nf_flow_rule *flow_rule; ++- struct dst_entry *other_dst; ++ int err = -ENOMEM; ++ ++ flow_rule = kzalloc(sizeof(*flow_rule), GFP_KERNEL); ++@@ -597,7 +676,10 @@ nf_flow_offload_rule_alloc(struct net *n ++ flow_rule->rule->match.key = &flow_rule->match.key; ++ ++ tuple = &flow->tuplehash[dir].tuple; ++- other_dst = flow->tuplehash[!dir].tuple.dst_cache; +++ other_tuple = &flow->tuplehash[!dir].tuple; +++ if (other_tuple->xmit_type == FLOW_OFFLOAD_XMIT_NEIGH) +++ other_dst = other_tuple->dst_cache; +++ ++ err = nf_flow_rule_match(&flow_rule->match, tuple, other_dst); ++ if (err < 0) ++ goto err_flow_match; +diff --git a/target/linux/generic/pending-5.10/640-12-netfilter-nft_flow_offload-add-dsa-support.patch b/target/linux/generic/pending-5.10/640-12-netfilter-nft_flow_offload-add-dsa-support.patch +new file mode 100644 +index 0000000000..3689a476b3 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/640-12-netfilter-nft_flow_offload-add-dsa-support.patch +@@ -0,0 +1,30 @@ ++From: Pablo Neira Ayuso ++Date: Mon, 18 Jan 2021 22:27:45 +0100 ++Subject: [PATCH] netfilter: nft_flow_offload: add dsa support ++ ++Replace the master ethernet device by the dsa slave port. ++ ++Signed-off-by: Pablo Neira Ayuso ++--- ++ ++--- a/net/netfilter/nft_flow_offload.c +++++ b/net/netfilter/nft_flow_offload.c ++@@ -86,6 +86,7 @@ static void nft_dev_path_info(const stru ++ path = &stack->path[i]; ++ switch (path->type) { ++ case DEV_PATH_ETHERNET: +++ case DEV_PATH_DSA: ++ case DEV_PATH_VLAN: ++ info->dev = path->dev; ++ if (is_zero_ether_addr(info->h_source)) ++@@ -93,6 +94,10 @@ static void nft_dev_path_info(const stru ++ ++ if (path->type == DEV_PATH_ETHERNET) ++ break; +++ if (path->type == DEV_PATH_DSA) { +++ i = stack->num_paths; +++ break; +++ } ++ ++ /* DEV_PATH_VLAN */ ++ if (info->num_vlans >= NF_FLOW_TABLE_VLAN_MAX) { +diff --git a/target/linux/generic/pending-5.10/640-13-dsa-slave-add-support-for-TC_SETUP_FT.patch b/target/linux/generic/pending-5.10/640-13-dsa-slave-add-support-for-TC_SETUP_FT.patch +new file mode 100644 +index 0000000000..58a2064c03 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/640-13-dsa-slave-add-support-for-TC_SETUP_FT.patch +@@ -0,0 +1,53 @@ ++From: Pablo Neira Ayuso ++Date: Mon, 18 Jan 2021 22:39:17 +0100 ++Subject: [PATCH] dsa: slave: add support for TC_SETUP_FT ++ ++The dsa infrastructure provides a well-defined hierarchy of devices, ++pass up the call to set up the flow block to the master device. From the ++software dataplane, the netfilter infrastructure uses the dsa slave ++devices to refer to the input and output device for the given skbuff. ++Similarly, the flowtable definition in the ruleset refers to the dsa ++slave port devices. ++ ++This patch adds the glue code to call ndo_setup_tc with TC_SETUP_FT ++with the master device via the dsa slave devices. ++ ++Signed-off-by: Pablo Neira Ayuso ++--- ++ ++--- a/net/dsa/slave.c +++++ b/net/dsa/slave.c ++@@ -1202,14 +1202,32 @@ static int dsa_slave_setup_tc_block(stru ++ } ++ } ++ +++static int dsa_slave_setup_ft_block(struct dsa_switch *ds, int port, +++ void *type_data) +++{ +++ struct dsa_port *cpu_dp = dsa_to_port(ds, port)->cpu_dp; +++ struct net_device *master = cpu_dp->master; +++ +++ if (!master->netdev_ops->ndo_setup_tc) +++ return -EOPNOTSUPP; +++ +++ return master->netdev_ops->ndo_setup_tc(master, TC_SETUP_FT, type_data); +++} +++ ++ static int dsa_slave_setup_tc(struct net_device *dev, enum tc_setup_type type, ++ void *type_data) ++ { ++ struct dsa_port *dp = dsa_slave_to_port(dev); ++ struct dsa_switch *ds = dp->ds; ++ ++- if (type == TC_SETUP_BLOCK) +++ switch (type) { +++ case TC_SETUP_BLOCK: ++ return dsa_slave_setup_tc_block(dev, type_data); +++ case TC_SETUP_FT: +++ return dsa_slave_setup_ft_block(ds, dp->index, type_data); +++ default: +++ break; +++ } ++ ++ if (!ds->ops->port_setup_tc) ++ return -EOPNOTSUPP; +diff --git a/target/linux/generic/pending-5.10/640-14-netfilter-nft_flow_offload-add-bridge-vlan-filtering.patch b/target/linux/generic/pending-5.10/640-14-netfilter-nft_flow_offload-add-bridge-vlan-filtering.patch +new file mode 100644 +index 0000000000..2e833117db +--- /dev/null ++++ b/target/linux/generic/pending-5.10/640-14-netfilter-nft_flow_offload-add-bridge-vlan-filtering.patch +@@ -0,0 +1,31 @@ ++From: Pablo Neira Ayuso ++Date: Sun, 24 Jan 2021 18:01:34 +0100 ++Subject: [PATCH] netfilter: nft_flow_offload: add bridge vlan filtering ++ support ++ ++Add the vlan tag based when PVID is set on. ++ ++Signed-off-by: Pablo Neira Ayuso ++--- ++ ++--- a/net/netfilter/nft_flow_offload.c +++++ b/net/netfilter/nft_flow_offload.c ++@@ -112,6 +112,18 @@ static void nft_dev_path_info(const stru ++ if (is_zero_ether_addr(info->h_source)) ++ memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN); ++ +++ switch (path->bridge.vlan_mode) { +++ case DEV_PATH_BR_VLAN_TAG: +++ info->vid[info->num_vlans] = path->vlan.id; +++ info->vproto[info->num_vlans] = path->vlan.proto; +++ info->num_vlans++; +++ break; +++ case DEV_PATH_BR_VLAN_UNTAG: +++ info->num_vlans--; +++ break; +++ case DEV_PATH_BR_VLAN_KEEP: +++ break; +++ } ++ info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT; ++ break; ++ default: +diff --git a/target/linux/generic/pending-5.10/640-15-netfilter-nft_flow_offload-use-direct-xmit-if-hardwa.patch b/target/linux/generic/pending-5.10/640-15-netfilter-nft_flow_offload-use-direct-xmit-if-hardwa.patch +new file mode 100644 +index 0000000000..1c65a5e218 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/640-15-netfilter-nft_flow_offload-use-direct-xmit-if-hardwa.patch +@@ -0,0 +1,51 @@ ++From: Pablo Neira Ayuso ++Date: Tue, 2 Feb 2021 17:10:07 +0100 ++Subject: [PATCH] netfilter: nft_flow_offload: use direct xmit if ++ hardware offload is enabled ++ ++If there is a forward path to reach an ethernet device and hardware ++offload is enabled, then use the direct xmit path. ++--- ++ ++--- a/net/netfilter/nft_flow_offload.c +++++ b/net/netfilter/nft_flow_offload.c ++@@ -73,9 +73,18 @@ struct nft_forward_info { ++ enum flow_offload_xmit_type xmit_type; ++ }; ++ +++static bool nft_is_valid_ether_device(const struct net_device *dev) +++{ +++ if (!dev || (dev->flags & IFF_LOOPBACK) || dev->type != ARPHRD_ETHER || +++ dev->addr_len != ETH_ALEN || !is_valid_ether_addr(dev->dev_addr)) +++ return false; +++ +++ return true; +++} +++ ++ static void nft_dev_path_info(const struct net_device_path_stack *stack, ++ struct nft_forward_info *info, ++- unsigned char *ha) +++ unsigned char *ha, struct nf_flowtable *flowtable) ++ { ++ const struct net_device_path *path; ++ int i; ++@@ -131,6 +140,10 @@ static void nft_dev_path_info(const stru ++ break; ++ } ++ } +++ +++ if (nf_flowtable_hw_offload(flowtable) && +++ nft_is_valid_ether_device(info->dev)) +++ info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT; ++ } ++ ++ static bool nft_flowtable_find_dev(const struct net_device *dev, ++@@ -162,7 +175,7 @@ static void nft_dev_forward_path(struct ++ int i; ++ ++ if (nft_dev_fill_forward_path(route, dst, ct, dir, ha, &stack) >= 0) ++- nft_dev_path_info(&stack, &info, ha); +++ nft_dev_path_info(&stack, &info, ha, &ft->data); ++ ++ if (!info.dev || !nft_flowtable_find_dev(info.dev, ft)) ++ return; +diff --git a/target/linux/generic/pending-5.10/640-16-netfilter-nft_flow_offload-fix-bridge-vlan-tag-handl.patch b/target/linux/generic/pending-5.10/640-16-netfilter-nft_flow_offload-fix-bridge-vlan-tag-handl.patch +new file mode 100644 +index 0000000000..5877e91e78 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/640-16-netfilter-nft_flow_offload-fix-bridge-vlan-tag-handl.patch +@@ -0,0 +1,22 @@ ++From: Felix Fietkau ++Date: Wed, 10 Feb 2021 10:23:38 +0100 ++Subject: [PATCH] netfilter: nft_flow_offload: fix bridge vlan tag handling ++ ++the brigde type uses the path->bridge.vlan_* fields ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/net/netfilter/nft_flow_offload.c +++++ b/net/netfilter/nft_flow_offload.c ++@@ -123,8 +123,8 @@ static void nft_dev_path_info(const stru ++ ++ switch (path->bridge.vlan_mode) { ++ case DEV_PATH_BR_VLAN_TAG: ++- info->vid[info->num_vlans] = path->vlan.id; ++- info->vproto[info->num_vlans] = path->vlan.proto; +++ info->vid[info->num_vlans] = path->bridge.vlan_id; +++ info->vproto[info->num_vlans] = path->bridge.vlan_proto; ++ info->num_vlans++; ++ break; ++ case DEV_PATH_BR_VLAN_UNTAG: +diff --git a/target/linux/generic/pending-5.10/640-17-netfilter-flowtable-rework-ingress-vlan-matching.patch b/target/linux/generic/pending-5.10/640-17-netfilter-flowtable-rework-ingress-vlan-matching.patch +new file mode 100644 +index 0000000000..67ec263f51 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/640-17-netfilter-flowtable-rework-ingress-vlan-matching.patch +@@ -0,0 +1,143 @@ ++From: Felix Fietkau ++Date: Wed, 10 Feb 2021 19:39:23 +0100 ++Subject: [PATCH] netfilter: flowtable: rework ingress vlan matching ++ ++When dealing with bridges with VLAN filtering and DSA/switchdev offload, ++the hardware could offload adding a VLAN tag configured in the bridge. ++Since there doesn't seem to be an easy way to detect that, this patch ++reworks the code to optionally match the last VLAN tag that would otherwise ++be inserted by the bridge. ++This matters when bypassing the bridge and attaching an ingress hook on ++a DSA port below it. ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/include/net/netfilter/nf_flow_table.h +++++ b/include/net/netfilter/nf_flow_table.h ++@@ -115,14 +115,15 @@ struct flow_offload_tuple { ++ ++ u8 l3proto; ++ u8 l4proto; ++- struct { ++- u16 id; ++- __be16 proto; ++- } in_vlan[NF_FLOW_TABLE_VLAN_MAX]; ++ ++ /* All members above are keys for lookups, see flow_offload_hash(). */ ++ struct { } __hash; ++ +++ struct { +++ u16 id; +++ __be16 proto; +++ } in_vlan[NF_FLOW_TABLE_VLAN_MAX], in_pvid; +++ ++ u8 dir:4, ++ xmit_type:2, ++ in_vlan_num:2; ++--- a/net/netfilter/nf_flow_table_ip.c +++++ b/net/netfilter/nf_flow_table_ip.c ++@@ -281,12 +281,13 @@ static bool nf_flow_skb_vlan_protocol(co ++ } ++ ++ static void nf_flow_vlan_pop(struct sk_buff *skb, ++- struct flow_offload_tuple_rhash *tuplehash) +++ struct flow_offload_tuple_rhash *tuplehash, +++ bool strip_pvid) ++ { ++ struct vlan_hdr *vlan_hdr; ++ int i; ++ ++- for (i = 0; i < tuplehash->tuple.in_vlan_num; i++) { +++ for (i = 0; i < tuplehash->tuple.in_vlan_num + strip_pvid; i++) { ++ if (skb_vlan_tag_present(skb)) { ++ __vlan_hwaccel_clear_tag(skb); ++ continue; ++@@ -316,6 +317,31 @@ static unsigned int nf_flow_queue_xmit(s ++ return NF_STOLEN; ++ } ++ +++static bool +++nf_flow_offload_check_vlan(struct flow_offload_tuple *tuple, +++ struct flow_offload_tuple *flow_tuple, +++ bool *strip_pvid) +++{ +++ int i, cur = 0; +++ +++ if (flow_tuple->in_pvid.proto && +++ !memcmp(&tuple->in_vlan[0], &flow_tuple->in_pvid, +++ sizeof(tuple->in_vlan[0]))) +++ cur++; +++ +++ *strip_pvid = cur; +++ +++ for (i = 0; i < flow_tuple->in_vlan_num; i++, cur++) { +++ if (!memcmp(&tuple->in_vlan[cur], &flow_tuple->in_vlan[i], +++ sizeof(tuple->in_vlan[0]))) +++ continue; +++ +++ return false; +++ } +++ +++ return true; +++} +++ ++ unsigned int ++ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb, ++ const struct nf_hook_state *state) ++@@ -329,6 +355,7 @@ nf_flow_offload_ip_hook(void *priv, stru ++ struct rtable *rt; ++ unsigned int thoff; ++ struct iphdr *iph; +++ bool strip_pvid; ++ __be32 nexthop; ++ u32 offset = 0; ++ int ret; ++@@ -344,6 +371,10 @@ nf_flow_offload_ip_hook(void *priv, stru ++ if (tuplehash == NULL) ++ return NF_ACCEPT; ++ +++ if (!nf_flow_offload_check_vlan(&tuple, &tuplehash->tuple, +++ &strip_pvid)) +++ return NF_ACCEPT; +++ ++ dir = tuplehash->tuple.dir; ++ flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); ++ ++@@ -368,7 +399,7 @@ nf_flow_offload_ip_hook(void *priv, stru ++ return NF_ACCEPT; ++ } ++ ++- nf_flow_vlan_pop(skb, tuplehash); +++ nf_flow_vlan_pop(skb, tuplehash, strip_pvid); ++ thoff -= offset; ++ ++ if (nf_flow_nat_ip(flow, skb, thoff, dir) < 0) ++@@ -596,6 +627,7 @@ nf_flow_offload_ipv6_hook(void *priv, st ++ struct net_device *outdev; ++ struct ipv6hdr *ip6h; ++ struct rt6_info *rt; +++ bool strip_pvid; ++ u32 offset = 0; ++ int ret; ++ ++@@ -610,6 +642,10 @@ nf_flow_offload_ipv6_hook(void *priv, st ++ if (tuplehash == NULL) ++ return NF_ACCEPT; ++ +++ if (!nf_flow_offload_check_vlan(&tuple, &tuplehash->tuple, +++ &strip_pvid)) +++ return NF_ACCEPT; +++ ++ dir = tuplehash->tuple.dir; ++ flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); ++ ++@@ -630,7 +666,7 @@ nf_flow_offload_ipv6_hook(void *priv, st ++ return NF_ACCEPT; ++ } ++ ++- nf_flow_vlan_pop(skb, tuplehash); +++ nf_flow_vlan_pop(skb, tuplehash, strip_pvid); ++ ++ if (skb_try_make_writable(skb, sizeof(*ip6h))) ++ return NF_DROP; +diff --git a/target/linux/generic/pending-5.10/640-18-netfilter-flowtable-handle-bridge-vlan-filter-offloa.patch b/target/linux/generic/pending-5.10/640-18-netfilter-flowtable-handle-bridge-vlan-filter-offloa.patch +new file mode 100644 +index 0000000000..ba480f3520 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/640-18-netfilter-flowtable-handle-bridge-vlan-filter-offloa.patch +@@ -0,0 +1,106 @@ ++From: Felix Fietkau ++Date: Wed, 10 Feb 2021 19:44:33 +0100 ++Subject: [PATCH] netfilter: flowtable: handle bridge vlan filter offload ++ tags from DSA/switchdev ++ ++When a switchdev/DSA port is an untagged member of a bridge vlan, ingress ++packets could potentially be tagged with the id of the VLAN. ++When the VLAN port group has been uploaded to switchdev, report the bridge ++tag mode as DEV_PATH_BR_VLAN_UNTAG_HW instead of DEV_PATH_BR_VLAN_UNTAG ++and handle it in netfilter flow offloading by storing the tag in the tuple ++in_pvid field. ++This allows the ingress hook to detect the optional tag and remove it for ++software offload. This tag processing is for ingress only, egress needs to be ++fully untagged ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/include/linux/netdevice.h +++++ b/include/linux/netdevice.h ++@@ -853,6 +853,7 @@ struct net_device_path { ++ DEV_PATH_BR_VLAN_KEEP, ++ DEV_PATH_BR_VLAN_TAG, ++ DEV_PATH_BR_VLAN_UNTAG, +++ DEV_PATH_BR_VLAN_UNTAG_HW, ++ } vlan_mode; ++ u16 vlan_id; ++ __be16 vlan_proto; ++--- a/include/net/netfilter/nf_flow_table.h +++++ b/include/net/netfilter/nf_flow_table.h ++@@ -183,6 +183,10 @@ struct nf_flow_route { ++ u32 ifindex; ++ u16 vid[NF_FLOW_TABLE_VLAN_MAX]; ++ __be16 vproto[NF_FLOW_TABLE_VLAN_MAX]; +++ struct { +++ u16 id; +++ __be16 proto; +++ } pvid; ++ u8 num_vlans; ++ } in; ++ struct { ++--- a/net/bridge/br_device.c +++++ b/net/bridge/br_device.c ++@@ -435,6 +435,7 @@ static int br_fill_forward_path(struct n ++ ctx->vlan[ctx->num_vlans].proto = path->bridge.vlan_proto; ++ ctx->num_vlans++; ++ break; +++ case DEV_PATH_BR_VLAN_UNTAG_HW: ++ case DEV_PATH_BR_VLAN_UNTAG: ++ ctx->num_vlans--; ++ break; ++--- a/net/bridge/br_vlan.c +++++ b/net/bridge/br_vlan.c ++@@ -1374,6 +1374,8 @@ int br_vlan_fill_forward_path_mode(struc ++ ++ if (path->bridge.vlan_mode == DEV_PATH_BR_VLAN_TAG) ++ path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP; +++ else if (v->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV) +++ path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG_HW; ++ else ++ path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG; ++ ++--- a/net/netfilter/nf_flow_table_core.c +++++ b/net/netfilter/nf_flow_table_core.c ++@@ -98,6 +98,8 @@ static int flow_offload_fill_route(struc ++ j++; ++ } ++ flow_tuple->in_vlan_num = route->tuple[dir].in.num_vlans; +++ flow_tuple->in_pvid.id = route->tuple[dir].in.pvid.id; +++ flow_tuple->in_pvid.proto = route->tuple[dir].in.pvid.proto; ++ ++ switch (route->tuple[dir].xmit_type) { ++ case FLOW_OFFLOAD_XMIT_DIRECT: ++--- a/net/netfilter/nft_flow_offload.c +++++ b/net/netfilter/nft_flow_offload.c ++@@ -67,6 +67,10 @@ struct nft_forward_info { ++ const struct net_device *dev; ++ __u16 vid[NF_FLOW_TABLE_VLAN_MAX]; ++ __be16 vproto[NF_FLOW_TABLE_VLAN_MAX]; +++ struct { +++ __u16 id; +++ __be16 proto; +++ } pvid; ++ u8 num_vlans; ++ u8 h_source[ETH_ALEN]; ++ u8 h_dest[ETH_ALEN]; ++@@ -127,6 +131,10 @@ static void nft_dev_path_info(const stru ++ info->vproto[info->num_vlans] = path->bridge.vlan_proto; ++ info->num_vlans++; ++ break; +++ case DEV_PATH_BR_VLAN_UNTAG_HW: +++ info->pvid.id = info->vid[info->num_vlans - 1]; +++ info->pvid.proto = info->vproto[info->num_vlans - 1]; +++ fallthrough; ++ case DEV_PATH_BR_VLAN_UNTAG: ++ info->num_vlans--; ++ break; ++@@ -185,6 +193,8 @@ static void nft_dev_forward_path(struct ++ route->tuple[!dir].in.vid[i] = info.vid[i]; ++ route->tuple[!dir].in.vproto[i] = info.vproto[i]; ++ } +++ route->tuple[!dir].in.pvid.id = info.pvid.id; +++ route->tuple[!dir].in.pvid.proto = info.pvid.proto; ++ route->tuple[!dir].in.num_vlans = info.num_vlans; ++ ++ if (info.xmit_type == FLOW_OFFLOAD_XMIT_DIRECT) { +diff --git a/target/linux/generic/pending-5.10/655-increase_skb_pad.patch b/target/linux/generic/pending-5.10/655-increase_skb_pad.patch +new file mode 100644 +index 0000000000..ff39ddb8b3 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/655-increase_skb_pad.patch +@@ -0,0 +1,20 @@ ++From: Felix Fietkau ++Subject: kernel: add a few patches for avoiding unnecessary skb reallocations - significantly improves ethernet<->wireless performance ++ ++lede-commit: 6f89cffc9add6939d44a6b54cf9a5e77849aa7fd ++Signed-off-by: Felix Fietkau ++--- ++ include/linux/skbuff.h | 2 +- ++ 1 file changed, 1 insertion(+), 1 deletion(-) ++ ++--- a/include/linux/skbuff.h +++++ b/include/linux/skbuff.h ++@@ -2676,7 +2676,7 @@ static inline int pskb_network_may_pull( ++ * NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8) ++ */ ++ #ifndef NET_SKB_PAD ++-#define NET_SKB_PAD max(32, L1_CACHE_BYTES) +++#define NET_SKB_PAD max(64, L1_CACHE_BYTES) ++ #endif ++ ++ int ___pskb_trim(struct sk_buff *skb, unsigned int len); +diff --git a/target/linux/generic/pending-5.10/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch b/target/linux/generic/pending-5.10/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch +new file mode 100644 +index 0000000000..924baa0607 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch +@@ -0,0 +1,511 @@ ++From: Steven Barth ++Subject: Add support for MAP-E FMRs (mesh mode) ++ ++MAP-E FMRs (draft-ietf-softwire-map-10) are rules for IPv4-communication ++between MAP CEs (mesh mode) without the need to forward such data to a ++border relay. This is similar to how 6rd works but for IPv4 over IPv6. ++ ++Signed-off-by: Steven Barth ++--- ++ include/net/ip6_tunnel.h | 13 ++ ++ include/uapi/linux/if_tunnel.h | 13 ++ ++ net/ipv6/ip6_tunnel.c | 276 +++++++++++++++++++++++++++++++++++++++-- ++ 3 files changed, 291 insertions(+), 11 deletions(-) ++ ++--- a/include/net/ip6_tunnel.h +++++ b/include/net/ip6_tunnel.h ++@@ -18,6 +18,18 @@ ++ /* determine capability on a per-packet basis */ ++ #define IP6_TNL_F_CAP_PER_PACKET 0x40000 ++ +++/* IPv6 tunnel FMR */ +++struct __ip6_tnl_fmr { +++ struct __ip6_tnl_fmr *next; /* next fmr in list */ +++ struct in6_addr ip6_prefix; +++ struct in_addr ip4_prefix; +++ +++ __u8 ip6_prefix_len; +++ __u8 ip4_prefix_len; +++ __u8 ea_len; +++ __u8 offset; +++}; +++ ++ struct __ip6_tnl_parm { ++ char name[IFNAMSIZ]; /* name of tunnel device */ ++ int link; /* ifindex of underlying L2 interface */ ++@@ -29,6 +41,7 @@ struct __ip6_tnl_parm { ++ __u32 flags; /* tunnel flags */ ++ struct in6_addr laddr; /* local tunnel end-point address */ ++ struct in6_addr raddr; /* remote tunnel end-point address */ +++ struct __ip6_tnl_fmr *fmrs; /* FMRs */ ++ ++ __be16 i_flags; ++ __be16 o_flags; ++--- a/include/uapi/linux/if_tunnel.h +++++ b/include/uapi/linux/if_tunnel.h ++@@ -77,10 +77,23 @@ enum { ++ IFLA_IPTUN_ENCAP_DPORT, ++ IFLA_IPTUN_COLLECT_METADATA, ++ IFLA_IPTUN_FWMARK, +++ IFLA_IPTUN_FMRS, ++ __IFLA_IPTUN_MAX, ++ }; ++ #define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1) ++ +++enum { +++ IFLA_IPTUN_FMR_UNSPEC, +++ IFLA_IPTUN_FMR_IP6_PREFIX, +++ IFLA_IPTUN_FMR_IP4_PREFIX, +++ IFLA_IPTUN_FMR_IP6_PREFIX_LEN, +++ IFLA_IPTUN_FMR_IP4_PREFIX_LEN, +++ IFLA_IPTUN_FMR_EA_LEN, +++ IFLA_IPTUN_FMR_OFFSET, +++ __IFLA_IPTUN_FMR_MAX, +++}; +++#define IFLA_IPTUN_FMR_MAX (__IFLA_IPTUN_FMR_MAX - 1) +++ ++ enum tunnel_encap_types { ++ TUNNEL_ENCAP_NONE, ++ TUNNEL_ENCAP_FOU, ++--- a/net/ipv6/ip6_tunnel.c +++++ b/net/ipv6/ip6_tunnel.c ++@@ -11,6 +11,9 @@ ++ * linux/net/ipv6/sit.c and linux/net/ipv4/ipip.c ++ * ++ * RFC 2473 +++ * +++ * Changes: +++ * Steven Barth : MAP-E FMR support ++ */ ++ ++ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ++@@ -67,9 +70,9 @@ static bool log_ecn_error = true; ++ module_param(log_ecn_error, bool, 0644); ++ MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN"); ++ ++-static u32 HASH(const struct in6_addr *addr1, const struct in6_addr *addr2) +++static u32 HASH(const struct in6_addr *addr) ++ { ++- u32 hash = ipv6_addr_hash(addr1) ^ ipv6_addr_hash(addr2); +++ u32 hash = ipv6_addr_hash(addr); ++ ++ return hash_32(hash, IP6_TUNNEL_HASH_SIZE_SHIFT); ++ } ++@@ -144,17 +147,33 @@ static struct ip6_tnl * ++ ip6_tnl_lookup(struct net *net, int link, ++ const struct in6_addr *remote, const struct in6_addr *local) ++ { ++- unsigned int hash = HASH(remote, local); +++ unsigned int hash = HASH(local); ++ struct ip6_tnl *t, *cand = NULL; ++ struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); ++ struct in6_addr any; ++ ++ for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) { ++ if (!ipv6_addr_equal(local, &t->parms.laddr) || ++- !ipv6_addr_equal(remote, &t->parms.raddr) || ++ !(t->dev->flags & IFF_UP)) ++ continue; ++ +++ if (!ipv6_addr_equal(remote, &t->parms.raddr)) { +++ struct __ip6_tnl_fmr *fmr; +++ bool found = false; +++ +++ for (fmr = t->parms.fmrs; fmr; fmr = fmr->next) { +++ if (!ipv6_prefix_equal(remote, &fmr->ip6_prefix, +++ fmr->ip6_prefix_len)) +++ continue; +++ +++ found = true; +++ break; +++ } +++ +++ if (!found) +++ continue; +++ } +++ ++ if (link == t->parms.link) ++ return t; ++ else ++@@ -162,7 +181,7 @@ ip6_tnl_lookup(struct net *net, int link ++ } ++ ++ memset(&any, 0, sizeof(any)); ++- hash = HASH(&any, local); +++ hash = HASH(local); ++ for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) { ++ if (!ipv6_addr_equal(local, &t->parms.laddr) || ++ !ipv6_addr_any(&t->parms.raddr) || ++@@ -175,7 +194,7 @@ ip6_tnl_lookup(struct net *net, int link ++ cand = t; ++ } ++ ++- hash = HASH(remote, &any); +++ hash = HASH(&any); ++ for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) { ++ if (!ipv6_addr_equal(remote, &t->parms.raddr) || ++ !ipv6_addr_any(&t->parms.laddr) || ++@@ -223,7 +242,7 @@ ip6_tnl_bucket(struct ip6_tnl_net *ip6n, ++ ++ if (!ipv6_addr_any(remote) || !ipv6_addr_any(local)) { ++ prio = 1; ++- h = HASH(remote, local); +++ h = HASH(local); ++ } ++ return &ip6n->tnls[prio][h]; ++ } ++@@ -406,6 +425,12 @@ ip6_tnl_dev_uninit(struct net_device *de ++ struct net *net = t->net; ++ struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); ++ +++ while (t->parms.fmrs) { +++ struct __ip6_tnl_fmr *next = t->parms.fmrs->next; +++ kfree(t->parms.fmrs); +++ t->parms.fmrs = next; +++ } +++ ++ if (dev == ip6n->fb_tnl_dev) ++ RCU_INIT_POINTER(ip6n->tnls_wc[0], NULL); ++ else ++@@ -822,6 +847,107 @@ int ip6_tnl_rcv_ctl(struct ip6_tnl *t, ++ } ++ EXPORT_SYMBOL_GPL(ip6_tnl_rcv_ctl); ++ +++/** +++ * ip4ip6_fmr_calc - calculate target / source IPv6-address based on FMR +++ * @dest: destination IPv6 address buffer +++ * @skb: received socket buffer +++ * @fmr: MAP FMR +++ * @xmit: Calculate for xmit or rcv +++ **/ +++static void ip4ip6_fmr_calc(struct in6_addr *dest, +++ const struct iphdr *iph, const uint8_t *end, +++ const struct __ip6_tnl_fmr *fmr, bool xmit) +++{ +++ int psidlen = fmr->ea_len - (32 - fmr->ip4_prefix_len); +++ u8 *portp = NULL; +++ bool use_dest_addr; +++ const struct iphdr *dsth = iph; +++ +++ if ((u8*)dsth >= end) +++ return; +++ +++ /* find significant IP header */ +++ if (iph->protocol == IPPROTO_ICMP) { +++ struct icmphdr *ih = (struct icmphdr*)(((u8*)dsth) + dsth->ihl * 4); +++ if (ih && ((u8*)&ih[1]) <= end && ( +++ ih->type == ICMP_DEST_UNREACH || +++ ih->type == ICMP_SOURCE_QUENCH || +++ ih->type == ICMP_TIME_EXCEEDED || +++ ih->type == ICMP_PARAMETERPROB || +++ ih->type == ICMP_REDIRECT)) +++ dsth = (const struct iphdr*)&ih[1]; +++ } +++ +++ /* in xmit-path use dest port by default and source port only if +++ this is an ICMP reply to something else; vice versa in rcv-path */ +++ use_dest_addr = (xmit && dsth == iph) || (!xmit && dsth != iph); +++ +++ /* get dst port */ +++ if (((u8*)&dsth[1]) <= end && ( +++ dsth->protocol == IPPROTO_UDP || +++ dsth->protocol == IPPROTO_TCP || +++ dsth->protocol == IPPROTO_SCTP || +++ dsth->protocol == IPPROTO_DCCP)) { +++ /* for UDP, TCP, SCTP and DCCP source and dest port +++ follow IPv4 header directly */ +++ portp = ((u8*)dsth) + dsth->ihl * 4; +++ +++ if (use_dest_addr) +++ portp += sizeof(u16); +++ } else if (iph->protocol == IPPROTO_ICMP) { +++ struct icmphdr *ih = (struct icmphdr*)(((u8*)dsth) + dsth->ihl * 4); +++ +++ /* use icmp identifier as port */ +++ if (((u8*)&ih) <= end && ( +++ (use_dest_addr && ( +++ ih->type == ICMP_ECHOREPLY || +++ ih->type == ICMP_TIMESTAMPREPLY || +++ ih->type == ICMP_INFO_REPLY || +++ ih->type == ICMP_ADDRESSREPLY)) || +++ (!use_dest_addr && ( +++ ih->type == ICMP_ECHO || +++ ih->type == ICMP_TIMESTAMP || +++ ih->type == ICMP_INFO_REQUEST || +++ ih->type == ICMP_ADDRESS) +++ ))) +++ portp = (u8*)&ih->un.echo.id; +++ } +++ +++ if ((portp && &portp[2] <= end) || psidlen == 0) { +++ int frombyte = fmr->ip6_prefix_len / 8; +++ int fromrem = fmr->ip6_prefix_len % 8; +++ int bytes = sizeof(struct in6_addr) - frombyte; +++ const u32 *addr = (use_dest_addr) ? &iph->daddr : &iph->saddr; +++ u64 eabits = ((u64)ntohl(*addr)) << (32 + fmr->ip4_prefix_len); +++ u64 t = 0; +++ +++ /* extract PSID from port and add it to eabits */ +++ u16 psidbits = 0; +++ if (psidlen > 0) { +++ psidbits = ((u16)portp[0]) << 8 | ((u16)portp[1]); +++ psidbits >>= 16 - psidlen - fmr->offset; +++ psidbits = (u16)(psidbits << (16 - psidlen)); +++ eabits |= ((u64)psidbits) << (48 - (fmr->ea_len - psidlen)); +++ } +++ +++ /* rewrite destination address */ +++ *dest = fmr->ip6_prefix; +++ memcpy(&dest->s6_addr[10], addr, sizeof(*addr)); +++ dest->s6_addr16[7] = htons(psidbits >> (16 - psidlen)); +++ +++ if (bytes > sizeof(u64)) +++ bytes = sizeof(u64); +++ +++ /* insert eabits */ +++ memcpy(&t, &dest->s6_addr[frombyte], bytes); +++ t = be64_to_cpu(t) & ~(((((u64)1) << fmr->ea_len) - 1) +++ << (64 - fmr->ea_len - fromrem)); +++ t = cpu_to_be64(t | (eabits >> fromrem)); +++ memcpy(&dest->s6_addr[frombyte], &t, bytes); +++ } +++} +++ +++ ++ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb, ++ const struct tnl_ptk_info *tpi, ++ struct metadata_dst *tun_dst, ++@@ -874,6 +1000,27 @@ static int __ip6_tnl_rcv(struct ip6_tnl ++ skb_reset_network_header(skb); ++ memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); ++ +++ if (tpi->proto == htons(ETH_P_IP) && tunnel->parms.fmrs && +++ !ipv6_addr_equal(&ipv6h->saddr, &tunnel->parms.raddr)) { +++ /* Packet didn't come from BR, so lookup FMR */ +++ struct __ip6_tnl_fmr *fmr; +++ struct in6_addr expected = tunnel->parms.raddr; +++ for (fmr = tunnel->parms.fmrs; fmr; fmr = fmr->next) +++ if (ipv6_prefix_equal(&ipv6h->saddr, +++ &fmr->ip6_prefix, fmr->ip6_prefix_len)) +++ break; +++ +++ /* Check that IPv6 matches IPv4 source to prevent spoofing */ +++ if (fmr) +++ ip4ip6_fmr_calc(&expected, ip_hdr(skb), +++ skb_tail_pointer(skb), fmr, false); +++ +++ if (!ipv6_addr_equal(&ipv6h->saddr, &expected)) { +++ rcu_read_unlock(); +++ goto drop; +++ } +++ } +++ ++ __skb_tunnel_rx(skb, tunnel->dev, tunnel->net); ++ ++ err = dscp_ecn_decapsulate(tunnel, ipv6h, skb); ++@@ -1025,6 +1172,7 @@ static void init_tel_txopt(struct ipv6_t ++ opt->ops.opt_nflen = 8; ++ } ++ +++ ++ /** ++ * ip6_tnl_addr_conflict - compare packet addresses to tunnel's own ++ * @t: the outgoing tunnel device ++@@ -1307,6 +1455,7 @@ ipxip6_tnl_xmit(struct sk_buff *skb, str ++ u8 protocol) ++ { ++ struct ip6_tnl *t = netdev_priv(dev); +++ struct __ip6_tnl_fmr *fmr; ++ struct ipv6hdr *ipv6h; ++ const struct iphdr *iph; ++ int encap_limit = -1; ++@@ -1406,6 +1555,18 @@ ipxip6_tnl_xmit(struct sk_buff *skb, str ++ fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL); ++ dsfield = INET_ECN_encapsulate(dsfield, orig_dsfield); ++ +++ /* try to find matching FMR */ +++ for (fmr = t->parms.fmrs; fmr; fmr = fmr->next) { +++ unsigned mshift = 32 - fmr->ip4_prefix_len; +++ if (ntohl(fmr->ip4_prefix.s_addr) >> mshift == +++ ntohl(ip_hdr(skb)->daddr) >> mshift) +++ break; +++ } +++ +++ /* change dstaddr according to FMR */ +++ if (fmr) +++ ip4ip6_fmr_calc(&fl6.daddr, ip_hdr(skb), skb_tail_pointer(skb), fmr, true); +++ ++ if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6)) ++ return -1; ++ ++@@ -1556,6 +1717,14 @@ ip6_tnl_change(struct ip6_tnl *t, const ++ t->parms.link = p->link; ++ t->parms.proto = p->proto; ++ t->parms.fwmark = p->fwmark; +++ +++ while (t->parms.fmrs) { +++ struct __ip6_tnl_fmr *next = t->parms.fmrs->next; +++ kfree(t->parms.fmrs); +++ t->parms.fmrs = next; +++ } +++ t->parms.fmrs = p->fmrs; +++ ++ dst_cache_reset(&t->dst_cache); ++ ip6_tnl_link_config(t); ++ return 0; ++@@ -1594,6 +1763,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_ ++ p->flowinfo = u->flowinfo; ++ p->link = u->link; ++ p->proto = u->proto; +++ p->fmrs = NULL; ++ memcpy(p->name, u->name, sizeof(u->name)); ++ } ++ ++@@ -1979,6 +2149,15 @@ static int ip6_tnl_validate(struct nlatt ++ return 0; ++ } ++ +++static const struct nla_policy ip6_tnl_fmr_policy[IFLA_IPTUN_FMR_MAX + 1] = { +++ [IFLA_IPTUN_FMR_IP6_PREFIX] = { .len = sizeof(struct in6_addr) }, +++ [IFLA_IPTUN_FMR_IP4_PREFIX] = { .len = sizeof(struct in_addr) }, +++ [IFLA_IPTUN_FMR_IP6_PREFIX_LEN] = { .type = NLA_U8 }, +++ [IFLA_IPTUN_FMR_IP4_PREFIX_LEN] = { .type = NLA_U8 }, +++ [IFLA_IPTUN_FMR_EA_LEN] = { .type = NLA_U8 }, +++ [IFLA_IPTUN_FMR_OFFSET] = { .type = NLA_U8 } +++}; +++ ++ static void ip6_tnl_netlink_parms(struct nlattr *data[], ++ struct __ip6_tnl_parm *parms) ++ { ++@@ -2016,6 +2195,46 @@ static void ip6_tnl_netlink_parms(struct ++ ++ if (data[IFLA_IPTUN_FWMARK]) ++ parms->fwmark = nla_get_u32(data[IFLA_IPTUN_FWMARK]); +++ +++ if (data[IFLA_IPTUN_FMRS]) { +++ unsigned rem; +++ struct nlattr *fmr; +++ nla_for_each_nested(fmr, data[IFLA_IPTUN_FMRS], rem) { +++ struct nlattr *fmrd[IFLA_IPTUN_FMR_MAX + 1], *c; +++ struct __ip6_tnl_fmr *nfmr; +++ +++ nla_parse_nested(fmrd, IFLA_IPTUN_FMR_MAX, +++ fmr, ip6_tnl_fmr_policy, NULL); +++ +++ if (!(nfmr = kzalloc(sizeof(*nfmr), GFP_KERNEL))) +++ continue; +++ +++ nfmr->offset = 6; +++ +++ if ((c = fmrd[IFLA_IPTUN_FMR_IP6_PREFIX])) +++ nla_memcpy(&nfmr->ip6_prefix, fmrd[IFLA_IPTUN_FMR_IP6_PREFIX], +++ sizeof(nfmr->ip6_prefix)); +++ +++ if ((c = fmrd[IFLA_IPTUN_FMR_IP4_PREFIX])) +++ nla_memcpy(&nfmr->ip4_prefix, fmrd[IFLA_IPTUN_FMR_IP4_PREFIX], +++ sizeof(nfmr->ip4_prefix)); +++ +++ if ((c = fmrd[IFLA_IPTUN_FMR_IP6_PREFIX_LEN])) +++ nfmr->ip6_prefix_len = nla_get_u8(c); +++ +++ if ((c = fmrd[IFLA_IPTUN_FMR_IP4_PREFIX_LEN])) +++ nfmr->ip4_prefix_len = nla_get_u8(c); +++ +++ if ((c = fmrd[IFLA_IPTUN_FMR_EA_LEN])) +++ nfmr->ea_len = nla_get_u8(c); +++ +++ if ((c = fmrd[IFLA_IPTUN_FMR_OFFSET])) +++ nfmr->offset = nla_get_u8(c); +++ +++ nfmr->next = parms->fmrs; +++ parms->fmrs = nfmr; +++ } +++ } ++ } ++ ++ static bool ip6_tnl_netlink_encap_parms(struct nlattr *data[], ++@@ -2131,6 +2350,12 @@ static void ip6_tnl_dellink(struct net_d ++ ++ static size_t ip6_tnl_get_size(const struct net_device *dev) ++ { +++ const struct ip6_tnl *t = netdev_priv(dev); +++ struct __ip6_tnl_fmr *c; +++ int fmrs = 0; +++ for (c = t->parms.fmrs; c; c = c->next) +++ ++fmrs; +++ ++ return ++ /* IFLA_IPTUN_LINK */ ++ nla_total_size(4) + ++@@ -2160,6 +2385,24 @@ static size_t ip6_tnl_get_size(const str ++ nla_total_size(0) + ++ /* IFLA_IPTUN_FWMARK */ ++ nla_total_size(4) + +++ /* IFLA_IPTUN_FMRS */ +++ nla_total_size(0) + +++ ( +++ /* nest */ +++ nla_total_size(0) + +++ /* IFLA_IPTUN_FMR_IP6_PREFIX */ +++ nla_total_size(sizeof(struct in6_addr)) + +++ /* IFLA_IPTUN_FMR_IP4_PREFIX */ +++ nla_total_size(sizeof(struct in_addr)) + +++ /* IFLA_IPTUN_FMR_EA_LEN */ +++ nla_total_size(1) + +++ /* IFLA_IPTUN_FMR_IP6_PREFIX_LEN */ +++ nla_total_size(1) + +++ /* IFLA_IPTUN_FMR_IP4_PREFIX_LEN */ +++ nla_total_size(1) + +++ /* IFLA_IPTUN_FMR_OFFSET */ +++ nla_total_size(1) +++ ) * fmrs + ++ 0; ++ } ++ ++@@ -2167,6 +2410,9 @@ static int ip6_tnl_fill_info(struct sk_b ++ { ++ struct ip6_tnl *tunnel = netdev_priv(dev); ++ struct __ip6_tnl_parm *parm = &tunnel->parms; +++ struct __ip6_tnl_fmr *c; +++ int fmrcnt = 0; +++ struct nlattr *fmrs; ++ ++ if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) || ++ nla_put_in6_addr(skb, IFLA_IPTUN_LOCAL, &parm->laddr) || ++@@ -2176,9 +2422,27 @@ static int ip6_tnl_fill_info(struct sk_b ++ nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) || ++ nla_put_u32(skb, IFLA_IPTUN_FLAGS, parm->flags) || ++ nla_put_u8(skb, IFLA_IPTUN_PROTO, parm->proto) || ++- nla_put_u32(skb, IFLA_IPTUN_FWMARK, parm->fwmark)) +++ nla_put_u32(skb, IFLA_IPTUN_FWMARK, parm->fwmark) || +++ !(fmrs = nla_nest_start(skb, IFLA_IPTUN_FMRS))) ++ goto nla_put_failure; ++ +++ for (c = parm->fmrs; c; c = c->next) { +++ struct nlattr *fmr = nla_nest_start(skb, ++fmrcnt); +++ if (!fmr || +++ nla_put(skb, IFLA_IPTUN_FMR_IP6_PREFIX, +++ sizeof(c->ip6_prefix), &c->ip6_prefix) || +++ nla_put(skb, IFLA_IPTUN_FMR_IP4_PREFIX, +++ sizeof(c->ip4_prefix), &c->ip4_prefix) || +++ nla_put_u8(skb, IFLA_IPTUN_FMR_IP6_PREFIX_LEN, c->ip6_prefix_len) || +++ nla_put_u8(skb, IFLA_IPTUN_FMR_IP4_PREFIX_LEN, c->ip4_prefix_len) || +++ nla_put_u8(skb, IFLA_IPTUN_FMR_EA_LEN, c->ea_len) || +++ nla_put_u8(skb, IFLA_IPTUN_FMR_OFFSET, c->offset)) +++ goto nla_put_failure; +++ +++ nla_nest_end(skb, fmr); +++ } +++ nla_nest_end(skb, fmrs); +++ ++ if (nla_put_u16(skb, IFLA_IPTUN_ENCAP_TYPE, tunnel->encap.type) || ++ nla_put_be16(skb, IFLA_IPTUN_ENCAP_SPORT, tunnel->encap.sport) || ++ nla_put_be16(skb, IFLA_IPTUN_ENCAP_DPORT, tunnel->encap.dport) || ++@@ -2218,6 +2482,7 @@ static const struct nla_policy ip6_tnl_p ++ [IFLA_IPTUN_ENCAP_DPORT] = { .type = NLA_U16 }, ++ [IFLA_IPTUN_COLLECT_METADATA] = { .type = NLA_FLAG }, ++ [IFLA_IPTUN_FWMARK] = { .type = NLA_U32 }, +++ [IFLA_IPTUN_FMRS] = { .type = NLA_NESTED }, ++ }; ++ ++ static struct rtnl_link_ops ip6_link_ops __read_mostly = { +diff --git a/target/linux/generic/pending-5.10/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch b/target/linux/generic/pending-5.10/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch +new file mode 100644 +index 0000000000..fda982fce9 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch +@@ -0,0 +1,263 @@ ++From: Jonas Gorski ++Subject: ipv6: allow rejecting with "source address failed policy" ++ ++RFC6204 L-14 requires rejecting traffic from invalid addresses with ++ICMPv6 Destination Unreachable, Code 5 (Source address failed ingress/ ++egress policy) on the LAN side, so add an appropriate rule for that. ++ ++Signed-off-by: Jonas Gorski ++--- ++ include/net/netns/ipv6.h | 1 + ++ include/uapi/linux/fib_rules.h | 4 +++ ++ include/uapi/linux/rtnetlink.h | 1 + ++ net/ipv4/fib_semantics.c | 4 +++ ++ net/ipv4/fib_trie.c | 1 + ++ net/ipv4/ipmr.c | 1 + ++ net/ipv6/fib6_rules.c | 4 +++ ++ net/ipv6/ip6mr.c | 2 ++ ++ net/ipv6/route.c | 58 +++++++++++++++++++++++++++++++++++++++++- ++ 9 files changed, 75 insertions(+), 1 deletion(-) ++ ++--- a/include/net/netns/ipv6.h +++++ b/include/net/netns/ipv6.h ++@@ -87,6 +87,7 @@ struct netns_ipv6 { ++ unsigned int fib6_routes_require_src; ++ #endif ++ struct rt6_info *ip6_prohibit_entry; +++ struct rt6_info *ip6_policy_failed_entry; ++ struct rt6_info *ip6_blk_hole_entry; ++ struct fib6_table *fib6_local_tbl; ++ struct fib_rules_ops *fib6_rules_ops; ++--- a/include/uapi/linux/fib_rules.h +++++ b/include/uapi/linux/fib_rules.h ++@@ -82,6 +82,10 @@ enum { ++ FR_ACT_BLACKHOLE, /* Drop without notification */ ++ FR_ACT_UNREACHABLE, /* Drop with ENETUNREACH */ ++ FR_ACT_PROHIBIT, /* Drop with EACCES */ +++ FR_ACT_RES9, +++ FR_ACT_RES10, +++ FR_ACT_RES11, +++ FR_ACT_POLICY_FAILED, /* Drop with EACCES */ ++ __FR_ACT_MAX, ++ }; ++ ++--- a/include/uapi/linux/rtnetlink.h +++++ b/include/uapi/linux/rtnetlink.h ++@@ -249,6 +249,7 @@ enum { ++ RTN_THROW, /* Not in this table */ ++ RTN_NAT, /* Translate this address */ ++ RTN_XRESOLVE, /* Use external resolver */ +++ RTN_POLICY_FAILED, /* Failed ingress/egress policy */ ++ __RTN_MAX ++ }; ++ ++--- a/net/ipv4/fib_semantics.c +++++ b/net/ipv4/fib_semantics.c ++@@ -141,6 +141,10 @@ const struct fib_prop fib_props[RTN_MAX ++ .error = -EINVAL, ++ .scope = RT_SCOPE_NOWHERE, ++ }, +++ [RTN_POLICY_FAILED] = { +++ .error = -EACCES, +++ .scope = RT_SCOPE_UNIVERSE, +++ }, ++ }; ++ ++ static void rt_fibinfo_free(struct rtable __rcu **rtp) ++--- a/net/ipv4/fib_trie.c +++++ b/net/ipv4/fib_trie.c ++@@ -2734,6 +2734,7 @@ static const char *const rtn_type_names[ ++ [RTN_THROW] = "THROW", ++ [RTN_NAT] = "NAT", ++ [RTN_XRESOLVE] = "XRESOLVE", +++ [RTN_POLICY_FAILED] = "POLICY_FAILED", ++ }; ++ ++ static inline const char *rtn_type(char *buf, size_t len, unsigned int t) ++--- a/net/ipv4/ipmr.c +++++ b/net/ipv4/ipmr.c ++@@ -175,6 +175,7 @@ static int ipmr_rule_action(struct fib_r ++ case FR_ACT_UNREACHABLE: ++ return -ENETUNREACH; ++ case FR_ACT_PROHIBIT: +++ case FR_ACT_POLICY_FAILED: ++ return -EACCES; ++ case FR_ACT_BLACKHOLE: ++ default: ++--- a/net/ipv6/fib6_rules.c +++++ b/net/ipv6/fib6_rules.c ++@@ -220,6 +220,10 @@ static int __fib6_rule_action(struct fib ++ err = -EACCES; ++ rt = net->ipv6.ip6_prohibit_entry; ++ goto discard_pkt; +++ case FR_ACT_POLICY_FAILED: +++ err = -EACCES; +++ rt = net->ipv6.ip6_policy_failed_entry; +++ goto discard_pkt; ++ } ++ ++ tb_id = fib_rule_get_table(rule, arg); ++--- a/net/ipv6/ip6mr.c +++++ b/net/ipv6/ip6mr.c ++@@ -163,6 +163,8 @@ static int ip6mr_rule_action(struct fib_ ++ return -ENETUNREACH; ++ case FR_ACT_PROHIBIT: ++ return -EACCES; +++ case FR_ACT_POLICY_FAILED: +++ return -EACCES; ++ case FR_ACT_BLACKHOLE: ++ default: ++ return -EINVAL; ++--- a/net/ipv6/route.c +++++ b/net/ipv6/route.c ++@@ -94,6 +94,8 @@ static int ip6_pkt_discard(struct sk_bu ++ static int ip6_pkt_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb); ++ static int ip6_pkt_prohibit(struct sk_buff *skb); ++ static int ip6_pkt_prohibit_out(struct net *net, struct sock *sk, struct sk_buff *skb); +++static int ip6_pkt_policy_failed(struct sk_buff *skb); +++static int ip6_pkt_policy_failed_out(struct net *net, struct sock *sk, struct sk_buff *skb); ++ static void ip6_link_failure(struct sk_buff *skb); ++ static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, ++ struct sk_buff *skb, u32 mtu, ++@@ -327,6 +329,18 @@ static const struct rt6_info ip6_prohibi ++ .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), ++ }; ++ +++static const struct rt6_info ip6_policy_failed_entry_template = { +++ .dst = { +++ .__refcnt = ATOMIC_INIT(1), +++ .__use = 1, +++ .obsolete = DST_OBSOLETE_FORCE_CHK, +++ .error = -EACCES, +++ .input = ip6_pkt_policy_failed, +++ .output = ip6_pkt_policy_failed_out, +++ }, +++ .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), +++}; +++ ++ static const struct rt6_info ip6_blk_hole_entry_template = { ++ .dst = { ++ .__refcnt = ATOMIC_INIT(1), ++@@ -1048,6 +1062,7 @@ static const int fib6_prop[RTN_MAX + 1] ++ [RTN_BLACKHOLE] = -EINVAL, ++ [RTN_UNREACHABLE] = -EHOSTUNREACH, ++ [RTN_PROHIBIT] = -EACCES, +++ [RTN_POLICY_FAILED] = -EACCES, ++ [RTN_THROW] = -EAGAIN, ++ [RTN_NAT] = -EINVAL, ++ [RTN_XRESOLVE] = -EINVAL, ++@@ -1083,6 +1098,10 @@ static void ip6_rt_init_dst_reject(struc ++ rt->dst.output = ip6_pkt_prohibit_out; ++ rt->dst.input = ip6_pkt_prohibit; ++ break; +++ case RTN_POLICY_FAILED: +++ rt->dst.output = ip6_pkt_policy_failed_out; +++ rt->dst.input = ip6_pkt_policy_failed; +++ break; ++ case RTN_THROW: ++ case RTN_UNREACHABLE: ++ default: ++@@ -4432,6 +4451,17 @@ static int ip6_pkt_prohibit_out(struct n ++ return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); ++ } ++ +++static int ip6_pkt_policy_failed(struct sk_buff *skb) +++{ +++ return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_INNOROUTES); +++} +++ +++static int ip6_pkt_policy_failed_out(struct net *net, struct sock *sk, struct sk_buff *skb) +++{ +++ skb->dev = skb_dst(skb)->dev; +++ return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_OUTNOROUTES); +++} +++ ++ /* ++ * Allocate a dst for local (unicast / anycast) address. ++ */ ++@@ -4912,7 +4942,8 @@ static int rtm_to_fib6_config(struct sk_ ++ if (rtm->rtm_type == RTN_UNREACHABLE || ++ rtm->rtm_type == RTN_BLACKHOLE || ++ rtm->rtm_type == RTN_PROHIBIT || ++- rtm->rtm_type == RTN_THROW) +++ rtm->rtm_type == RTN_THROW || +++ rtm->rtm_type == RTN_POLICY_FAILED) ++ cfg->fc_flags |= RTF_REJECT; ++ ++ if (rtm->rtm_type == RTN_LOCAL) ++@@ -6080,6 +6111,8 @@ static int ip6_route_dev_notify(struct n ++ #ifdef CONFIG_IPV6_MULTIPLE_TABLES ++ net->ipv6.ip6_prohibit_entry->dst.dev = dev; ++ net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev); +++ net->ipv6.ip6_policy_failed_entry->dst.dev = dev; +++ net->ipv6.ip6_policy_failed_entry->rt6i_idev = in6_dev_get(dev); ++ net->ipv6.ip6_blk_hole_entry->dst.dev = dev; ++ net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev); ++ #endif ++@@ -6091,6 +6124,7 @@ static int ip6_route_dev_notify(struct n ++ in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev); ++ #ifdef CONFIG_IPV6_MULTIPLE_TABLES ++ in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev); +++ in6_dev_put_clear(&net->ipv6.ip6_policy_failed_entry->rt6i_idev); ++ in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev); ++ #endif ++ } ++@@ -6282,6 +6316,8 @@ static int __net_init ip6_route_net_init ++ ++ #ifdef CONFIG_IPV6_MULTIPLE_TABLES ++ net->ipv6.fib6_has_custom_rules = false; +++ +++ ++ net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template, ++ sizeof(*net->ipv6.ip6_prohibit_entry), ++ GFP_KERNEL); ++@@ -6292,11 +6328,21 @@ static int __net_init ip6_route_net_init ++ ip6_template_metrics, true); ++ INIT_LIST_HEAD(&net->ipv6.ip6_prohibit_entry->rt6i_uncached); ++ +++ net->ipv6.ip6_policy_failed_entry = +++ kmemdup(&ip6_policy_failed_entry_template, +++ sizeof(*net->ipv6.ip6_policy_failed_entry), GFP_KERNEL); +++ if (!net->ipv6.ip6_policy_failed_entry) +++ goto out_ip6_prohibit_entry; +++ net->ipv6.ip6_policy_failed_entry->dst.ops = &net->ipv6.ip6_dst_ops; +++ dst_init_metrics(&net->ipv6.ip6_policy_failed_entry->dst, +++ ip6_template_metrics, true); +++ INIT_LIST_HEAD(&net->ipv6.ip6_policy_failed_entry->rt6i_uncached); +++ ++ net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template, ++ sizeof(*net->ipv6.ip6_blk_hole_entry), ++ GFP_KERNEL); ++ if (!net->ipv6.ip6_blk_hole_entry) ++- goto out_ip6_prohibit_entry; +++ goto out_ip6_policy_failed_entry; ++ net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops; ++ dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst, ++ ip6_template_metrics, true); ++@@ -6323,6 +6369,8 @@ out: ++ return ret; ++ ++ #ifdef CONFIG_IPV6_MULTIPLE_TABLES +++out_ip6_policy_failed_entry: +++ kfree(net->ipv6.ip6_policy_failed_entry); ++ out_ip6_prohibit_entry: ++ kfree(net->ipv6.ip6_prohibit_entry); ++ out_ip6_null_entry: ++@@ -6342,6 +6390,7 @@ static void __net_exit ip6_route_net_exi ++ kfree(net->ipv6.ip6_null_entry); ++ #ifdef CONFIG_IPV6_MULTIPLE_TABLES ++ kfree(net->ipv6.ip6_prohibit_entry); +++ kfree(net->ipv6.ip6_policy_failed_entry); ++ kfree(net->ipv6.ip6_blk_hole_entry); ++ #endif ++ dst_entries_destroy(&net->ipv6.ip6_dst_ops); ++@@ -6419,6 +6468,9 @@ void __init ip6_route_init_special_entri ++ init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); ++ init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev; ++ init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev); +++ init_net.ipv6.ip6_policy_failed_entry->dst.dev = init_net.loopback_dev; +++ init_net.ipv6.ip6_policy_failed_entry->rt6i_idev = +++ in6_dev_get(init_net.loopback_dev); ++ #endif ++ } ++ +diff --git a/target/linux/generic/pending-5.10/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch b/target/linux/generic/pending-5.10/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch +new file mode 100644 +index 0000000000..0e7f35db89 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch +@@ -0,0 +1,50 @@ ++From: Jonas Gorski ++Subject: net: provide defines for _POLICY_FAILED until all code is updated ++ ++Upstream introduced ICMPV6_POLICY_FAIL for code 5 of destination ++unreachable, conflicting with our name. ++ ++Add appropriate defines to allow our code to build with the new ++name until we have updated our local patches for older kernels ++and userspace packages. ++ ++Signed-off-by: Jonas Gorski ++--- ++ include/uapi/linux/fib_rules.h | 2 ++ ++ include/uapi/linux/icmpv6.h | 2 ++ ++ include/uapi/linux/rtnetlink.h | 2 ++ ++ 3 files changed, 6 insertions(+) ++ ++--- a/include/uapi/linux/fib_rules.h +++++ b/include/uapi/linux/fib_rules.h ++@@ -89,6 +89,8 @@ enum { ++ __FR_ACT_MAX, ++ }; ++ +++#define FR_ACT_FAILED_POLICY FR_ACT_POLICY_FAILED +++ ++ #define FR_ACT_MAX (__FR_ACT_MAX - 1) ++ ++ #endif ++--- a/include/uapi/linux/icmpv6.h +++++ b/include/uapi/linux/icmpv6.h ++@@ -126,6 +126,8 @@ struct icmp6hdr { ++ #define ICMPV6_POLICY_FAIL 5 ++ #define ICMPV6_REJECT_ROUTE 6 ++ +++#define ICMPV6_FAILED_POLICY ICMPV6_POLICY_FAIL +++ ++ /* ++ * Codes for Time Exceeded ++ */ ++--- a/include/uapi/linux/rtnetlink.h +++++ b/include/uapi/linux/rtnetlink.h ++@@ -253,6 +253,8 @@ enum { ++ __RTN_MAX ++ }; ++ +++#define RTN_FAILED_POLICY RTN_POLICY_FAILED +++ ++ #define RTN_MAX (__RTN_MAX - 1) ++ ++ +diff --git a/target/linux/generic/pending-5.10/680-NET-skip-GRO-for-foreign-MAC-addresses.patch b/target/linux/generic/pending-5.10/680-NET-skip-GRO-for-foreign-MAC-addresses.patch +new file mode 100644 +index 0000000000..cd1b30b4af +--- /dev/null ++++ b/target/linux/generic/pending-5.10/680-NET-skip-GRO-for-foreign-MAC-addresses.patch +@@ -0,0 +1,149 @@ ++From: Felix Fietkau ++Subject: net: replace GRO optimization patch with a new one that supports VLANs/bridges with different MAC addresses ++ ++Signed-off-by: Felix Fietkau ++--- ++ include/linux/netdevice.h | 2 ++ ++ include/linux/skbuff.h | 3 ++- ++ net/core/dev.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++ ++ net/ethernet/eth.c | 18 +++++++++++++++++- ++ 4 files changed, 69 insertions(+), 2 deletions(-) ++ ++--- a/include/linux/netdevice.h +++++ b/include/linux/netdevice.h ++@@ -2031,6 +2031,8 @@ struct net_device { ++ struct netdev_hw_addr_list mc; ++ struct netdev_hw_addr_list dev_addrs; ++ +++ unsigned char local_addr_mask[MAX_ADDR_LEN]; +++ ++ #ifdef CONFIG_SYSFS ++ struct kset *queues_kset; ++ #endif ++--- a/include/linux/skbuff.h +++++ b/include/linux/skbuff.h ++@@ -858,6 +858,7 @@ struct sk_buff { ++ #ifdef CONFIG_TLS_DEVICE ++ __u8 decrypted:1; ++ #endif +++ __u8 gro_skip:1; ++ ++ #ifdef CONFIG_NET_SCHED ++ __u16 tc_index; /* traffic control index */ ++--- a/net/core/dev.c +++++ b/net/core/dev.c ++@@ -5962,6 +5962,9 @@ static enum gro_result dev_gro_receive(s ++ int same_flow; ++ int grow; ++ +++ if (skb->gro_skip) +++ goto normal; +++ ++ if (netif_elide_gro(skb->dev)) ++ goto normal; ++ ++@@ -7790,6 +7793,48 @@ static void __netdev_adjacent_dev_unlink ++ &upper_dev->adj_list.lower); ++ } ++ +++static void __netdev_addr_mask(unsigned char *mask, const unsigned char *addr, +++ struct net_device *dev) +++{ +++ int i; +++ +++ for (i = 0; i < dev->addr_len; i++) +++ mask[i] |= addr[i] ^ dev->dev_addr[i]; +++} +++ +++static void __netdev_upper_mask(unsigned char *mask, struct net_device *dev, +++ struct net_device *lower) +++{ +++ struct net_device *cur; +++ struct list_head *iter; +++ +++ netdev_for_each_upper_dev_rcu(dev, cur, iter) { +++ __netdev_addr_mask(mask, cur->dev_addr, lower); +++ __netdev_upper_mask(mask, cur, lower); +++ } +++} +++ +++static void __netdev_update_addr_mask(struct net_device *dev) +++{ +++ unsigned char mask[MAX_ADDR_LEN]; +++ struct net_device *cur; +++ struct list_head *iter; +++ +++ memset(mask, 0, sizeof(mask)); +++ __netdev_upper_mask(mask, dev, dev); +++ memcpy(dev->local_addr_mask, mask, dev->addr_len); +++ +++ netdev_for_each_lower_dev(dev, cur, iter) +++ __netdev_update_addr_mask(cur); +++} +++ +++static void netdev_update_addr_mask(struct net_device *dev) +++{ +++ rcu_read_lock(); +++ __netdev_update_addr_mask(dev); +++ rcu_read_unlock(); +++} +++ ++ static int __netdev_upper_dev_link(struct net_device *dev, ++ struct net_device *upper_dev, bool master, ++ void *upper_priv, void *upper_info, ++@@ -7841,6 +7886,7 @@ static int __netdev_upper_dev_link(struc ++ if (ret) ++ return ret; ++ +++ netdev_update_addr_mask(dev); ++ ret = call_netdevice_notifiers_info(NETDEV_CHANGEUPPER, ++ &changeupper_info.info); ++ ret = notifier_to_errno(ret); ++@@ -7937,6 +7983,7 @@ static void __netdev_upper_dev_unlink(st ++ ++ __netdev_adjacent_dev_unlink_neighbour(dev, upper_dev); ++ +++ netdev_update_addr_mask(dev); ++ call_netdevice_notifiers_info(NETDEV_CHANGEUPPER, ++ &changeupper_info.info); ++ ++@@ -8723,6 +8770,7 @@ int dev_set_mac_address(struct net_devic ++ if (err) ++ return err; ++ dev->addr_assign_type = NET_ADDR_SET; +++ netdev_update_addr_mask(dev); ++ call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); ++ add_device_randomness(dev->dev_addr, dev->addr_len); ++ return 0; ++--- a/net/ethernet/eth.c +++++ b/net/ethernet/eth.c ++@@ -143,6 +143,18 @@ u32 eth_get_headlen(const struct net_dev ++ } ++ EXPORT_SYMBOL(eth_get_headlen); ++ +++static inline bool +++eth_check_local_mask(const void *addr1, const void *addr2, const void *mask) +++{ +++ const u16 *a1 = addr1; +++ const u16 *a2 = addr2; +++ const u16 *m = mask; +++ +++ return (((a1[0] ^ a2[0]) & ~m[0]) | +++ ((a1[1] ^ a2[1]) & ~m[1]) | +++ ((a1[2] ^ a2[2]) & ~m[2])); +++} +++ ++ /** ++ * eth_type_trans - determine the packet's protocol ID. ++ * @skb: received socket data ++@@ -174,6 +186,10 @@ __be16 eth_type_trans(struct sk_buff *sk ++ } else { ++ skb->pkt_type = PACKET_OTHERHOST; ++ } +++ +++ if (eth_check_local_mask(eth->h_dest, dev->dev_addr, +++ dev->local_addr_mask)) +++ skb->gro_skip = 1; ++ } ++ ++ /* +diff --git a/target/linux/generic/pending-5.10/681-NET-add-of_get_mac_address_mtd.patch b/target/linux/generic/pending-5.10/681-NET-add-of_get_mac_address_mtd.patch +new file mode 100644 +index 0000000000..71fbfe9978 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/681-NET-add-of_get_mac_address_mtd.patch +@@ -0,0 +1,135 @@ ++From: John Crispin ++Subject: NET: add mtd-mac-address support to of_get_mac_address() ++ ++Many embedded devices have information such as mac addresses stored inside mtd ++devices. This patch allows us to add a property inside a node describing a ++network interface. The new property points at a mtd partition with an offset ++where the mac address can be found. ++ ++Signed-off-by: John Crispin ++Signed-off-by: Felix Fietkau ++--- ++ drivers/of/of_net.c | 37 +++++++++++++++++++++++++++++++++++++ ++ include/linux/of_net.h | 1 + ++ 2 files changed, 38 insertions(+) ++ ++--- a/drivers/of/of_net.c +++++ b/drivers/of/of_net.c ++@@ -11,6 +11,7 @@ ++ #include ++ #include ++ #include +++#include ++ ++ /** ++ * of_get_phy_mode - Get phy mode for given device_node ++@@ -45,7 +46,7 @@ int of_get_phy_mode(struct device_node * ++ } ++ EXPORT_SYMBOL_GPL(of_get_phy_mode); ++ ++-static const void *of_get_mac_addr(struct device_node *np, const char *name) +++static void *of_get_mac_addr(struct device_node *np, const char *name) ++ { ++ struct property *pp = of_find_property(np, name, NULL); ++ ++@@ -78,6 +79,79 @@ static const void *of_get_mac_addr_nvmem ++ return mac; ++ } ++ +++static const void *of_get_mac_address_mtd(struct device_node *np) +++{ +++#ifdef CONFIG_MTD +++ struct device_node *mtd_np = NULL; +++ struct property *prop; +++ size_t retlen; +++ int size, ret; +++ struct mtd_info *mtd; +++ const char *part; +++ const __be32 *list; +++ phandle phandle; +++ u32 mac_inc = 0; +++ u8 mac[ETH_ALEN]; +++ void *addr; +++ u32 inc_idx; +++ +++ list = of_get_property(np, "mtd-mac-address", &size); +++ if (!list || (size != (2 * sizeof(*list)))) +++ return NULL; +++ +++ phandle = be32_to_cpup(list++); +++ if (phandle) +++ mtd_np = of_find_node_by_phandle(phandle); +++ +++ if (!mtd_np) +++ return NULL; +++ +++ part = of_get_property(mtd_np, "label", NULL); +++ if (!part) +++ part = mtd_np->name; +++ +++ mtd = get_mtd_device_nm(part); +++ if (IS_ERR(mtd)) +++ return NULL; +++ +++ ret = mtd_read(mtd, be32_to_cpup(list), 6, &retlen, mac); +++ put_mtd_device(mtd); +++ +++ if (of_property_read_u32(np, "mtd-mac-address-increment-byte", &inc_idx)) +++ inc_idx = 5; +++ if (inc_idx > 5) +++ return NULL; +++ +++ if (!of_property_read_u32(np, "mtd-mac-address-increment", &mac_inc)) +++ mac[inc_idx] += mac_inc; +++ +++ if (!is_valid_ether_addr(mac)) +++ return NULL; +++ +++ addr = of_get_mac_addr(np, "mac-address"); +++ if (addr) { +++ memcpy(addr, mac, ETH_ALEN); +++ return addr; +++ } +++ +++ prop = kzalloc(sizeof(*prop), GFP_KERNEL); +++ if (!prop) +++ return NULL; +++ +++ prop->name = "mac-address"; +++ prop->length = ETH_ALEN; +++ prop->value = kmemdup(mac, ETH_ALEN, GFP_KERNEL); +++ if (!prop->value || of_add_property(np, prop)) +++ goto free; +++ +++ return prop->value; +++free: +++ kfree(prop->value); +++ kfree(prop); +++#endif +++ return NULL; +++} +++ ++ /** ++ * Search the device tree for the best MAC address to use. 'mac-address' is ++ * checked first, because that is supposed to contain to "most recent" MAC ++@@ -98,12 +172,20 @@ static const void *of_get_mac_addr_nvmem ++ * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists ++ * but is all zeros. ++ * +++ * +++ * If a mtd-mac-address property exists, try to fetch the MAC address from the +++ * specified mtd device, and store it as a 'mac-address' property +++ * ++ * Return: Will be a valid pointer on success and ERR_PTR in case of error. ++ */ ++ const void *of_get_mac_address(struct device_node *np) ++ { ++ const void *addr; ++ +++ addr = of_get_mac_address_mtd(np); +++ if (addr) +++ return addr; +++ ++ addr = of_get_mac_addr(np, "mac-address"); ++ if (addr) ++ return addr; +diff --git a/target/linux/generic/pending-5.10/690-net-add-support-for-threaded-NAPI-polling.patch b/target/linux/generic/pending-5.10/690-net-add-support-for-threaded-NAPI-polling.patch +new file mode 100644 +index 0000000000..79b7832f2a +--- /dev/null ++++ b/target/linux/generic/pending-5.10/690-net-add-support-for-threaded-NAPI-polling.patch +@@ -0,0 +1,284 @@ ++From: Felix Fietkau ++Date: Sun, 26 Jul 2020 14:03:21 +0200 ++Subject: [PATCH] net: add support for threaded NAPI polling ++ ++For some drivers (especially 802.11 drivers), doing a lot of work in the NAPI ++poll function does not perform well. Since NAPI poll is bound to the CPU it ++was scheduled from, we can easily end up with a few very busy CPUs spending ++most of their time in softirq/ksoftirqd and some idle ones. ++ ++Introduce threaded NAPI for such drivers based on a workqueue. The API is the ++same except for using netif_threaded_napi_add instead of netif_napi_add. ++ ++In my tests with mt76 on MT7621 using threaded NAPI + a thread for tx scheduling ++improves LAN->WLAN bridging throughput by 10-50%. Throughput without threaded ++NAPI is wildly inconsistent, depending on the CPU that runs the tx scheduling ++thread. ++ ++With threaded NAPI, throughput seems stable and consistent (and higher than ++the best results I got without it). ++ ++Based on a patch by Hillf Danton ++ ++Cc: Hillf Danton ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/include/linux/netdevice.h +++++ b/include/linux/netdevice.h ++@@ -347,6 +347,7 @@ struct napi_struct { ++ struct list_head dev_list; ++ struct hlist_node napi_hash_node; ++ unsigned int napi_id; +++ struct work_struct work; ++ }; ++ ++ enum { ++@@ -357,6 +358,7 @@ enum { ++ NAPI_STATE_LISTED, /* NAPI added to system lists */ ++ NAPI_STATE_NO_BUSY_POLL,/* Do not add in napi_hash, no busy polling */ ++ NAPI_STATE_IN_BUSY_POLL,/* sk_busy_loop() owns this NAPI */ +++ NAPI_STATE_THREADED, /* Use threaded NAPI */ ++ }; ++ ++ enum { ++@@ -367,6 +369,7 @@ enum { ++ NAPIF_STATE_LISTED = BIT(NAPI_STATE_LISTED), ++ NAPIF_STATE_NO_BUSY_POLL = BIT(NAPI_STATE_NO_BUSY_POLL), ++ NAPIF_STATE_IN_BUSY_POLL = BIT(NAPI_STATE_IN_BUSY_POLL), +++ NAPIF_STATE_THREADED = BIT(NAPI_STATE_THREADED), ++ }; ++ ++ enum gro_result { ++@@ -2411,6 +2414,26 @@ void netif_napi_add(struct net_device *d ++ int (*poll)(struct napi_struct *, int), int weight); ++ ++ /** +++ * netif_threaded_napi_add - initialize a NAPI context +++ * @dev: network device +++ * @napi: NAPI context +++ * @poll: polling function +++ * @weight: default weight +++ * +++ * This variant of netif_napi_add() should be used from drivers using NAPI +++ * with CPU intensive poll functions. +++ * This will schedule polling from a high priority workqueue +++ */ +++static inline void netif_threaded_napi_add(struct net_device *dev, +++ struct napi_struct *napi, +++ int (*poll)(struct napi_struct *, int), +++ int weight) +++{ +++ set_bit(NAPI_STATE_THREADED, &napi->state); +++ netif_napi_add(dev, napi, poll, weight); +++} +++ +++/** ++ * netif_tx_napi_add - initialize a NAPI context ++ * @dev: network device ++ * @napi: NAPI context ++--- a/net/core/dev.c +++++ b/net/core/dev.c ++@@ -159,6 +159,7 @@ static DEFINE_SPINLOCK(offload_lock); ++ struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly; ++ struct list_head ptype_all __read_mostly; /* Taps */ ++ static struct list_head offload_base __read_mostly; +++static struct workqueue_struct *napi_workq __read_mostly; ++ ++ static int netif_rx_internal(struct sk_buff *skb); ++ static int call_netdevice_notifiers_info(unsigned long val, ++@@ -6404,6 +6405,11 @@ void __napi_schedule(struct napi_struct ++ { ++ unsigned long flags; ++ +++ if (test_bit(NAPI_STATE_THREADED, &n->state)) { +++ queue_work(napi_workq, &n->work); +++ return; +++ } +++ ++ local_irq_save(flags); ++ ____napi_schedule(this_cpu_ptr(&softnet_data), n); ++ local_irq_restore(flags); ++@@ -6451,6 +6457,11 @@ EXPORT_SYMBOL(napi_schedule_prep); ++ */ ++ void __napi_schedule_irqoff(struct napi_struct *n) ++ { +++ if (test_bit(NAPI_STATE_THREADED, &n->state)) { +++ queue_work(napi_workq, &n->work); +++ return; +++ } +++ ++ ____napi_schedule(this_cpu_ptr(&softnet_data), n); ++ } ++ EXPORT_SYMBOL(__napi_schedule_irqoff); ++@@ -6712,6 +6723,86 @@ static void init_gro_hash(struct napi_st ++ napi->gro_bitmask = 0; ++ } ++ +++static int __napi_poll(struct napi_struct *n, bool *repoll) +++{ +++ int work, weight; +++ +++ weight = n->weight; +++ +++ /* This NAPI_STATE_SCHED test is for avoiding a race +++ * with netpoll's poll_napi(). Only the entity which +++ * obtains the lock and sees NAPI_STATE_SCHED set will +++ * actually make the ->poll() call. Therefore we avoid +++ * accidentally calling ->poll() when NAPI is not scheduled. +++ */ +++ work = 0; +++ if (test_bit(NAPI_STATE_SCHED, &n->state)) { +++ work = n->poll(n, weight); +++ trace_napi_poll(n, work, weight); +++ } +++ +++ if (unlikely(work > weight)) +++ pr_err_once("NAPI poll function %pS returned %d, exceeding its budget of %d.\n", +++ n->poll, work, weight); +++ +++ if (likely(work < weight)) +++ return work; +++ +++ /* Drivers must not modify the NAPI state if they +++ * consume the entire weight. In such cases this code +++ * still "owns" the NAPI instance and therefore can +++ * move the instance around on the list at-will. +++ */ +++ if (unlikely(napi_disable_pending(n))) { +++ napi_complete(n); +++ return work; +++ } +++ +++ if (n->gro_bitmask) { +++ /* flush too old packets +++ * If HZ < 1000, flush all packets. +++ */ +++ napi_gro_flush(n, HZ >= 1000); +++ } +++ +++ gro_normal_list(n); +++ +++ *repoll = true; +++ +++ return work; +++} +++ +++static void napi_workfn(struct work_struct *work) +++{ +++ struct napi_struct *n = container_of(work, struct napi_struct, work); +++ void *have; +++ +++ for (;;) { +++ bool repoll = false; +++ +++ local_bh_disable(); +++ +++ have = netpoll_poll_lock(n); +++ __napi_poll(n, &repoll); +++ netpoll_poll_unlock(have); +++ +++ local_bh_enable(); +++ +++ if (!repoll) +++ return; +++ +++ if (!need_resched()) +++ continue; +++ +++ /* +++ * have to pay for the latency of task switch even if +++ * napi is scheduled +++ */ +++ queue_work(napi_workq, work); +++ return; +++ } +++} +++ ++ void netif_napi_add(struct net_device *dev, struct napi_struct *napi, ++ int (*poll)(struct napi_struct *, int), int weight) ++ { ++@@ -6735,6 +6826,7 @@ void netif_napi_add(struct net_device *d ++ #ifdef CONFIG_NETPOLL ++ napi->poll_owner = -1; ++ #endif +++ INIT_WORK(&napi->work, napi_workfn); ++ set_bit(NAPI_STATE_SCHED, &napi->state); ++ set_bit(NAPI_STATE_NPSVC, &napi->state); ++ list_add_rcu(&napi->dev_list, &dev->napi_list); ++@@ -6777,6 +6869,7 @@ void __netif_napi_del(struct napi_struct ++ if (!test_and_clear_bit(NAPI_STATE_LISTED, &napi->state)) ++ return; ++ +++ cancel_work_sync(&napi->work); ++ napi_hash_del(napi); ++ list_del_rcu(&napi->dev_list); ++ napi_free_frags(napi); ++@@ -6788,52 +6881,18 @@ EXPORT_SYMBOL(__netif_napi_del); ++ ++ static int napi_poll(struct napi_struct *n, struct list_head *repoll) ++ { +++ bool do_repoll = false; ++ void *have; ++- int work, weight; +++ int work; ++ ++ list_del_init(&n->poll_list); ++ ++ have = netpoll_poll_lock(n); ++ ++- weight = n->weight; ++- ++- /* This NAPI_STATE_SCHED test is for avoiding a race ++- * with netpoll's poll_napi(). Only the entity which ++- * obtains the lock and sees NAPI_STATE_SCHED set will ++- * actually make the ->poll() call. Therefore we avoid ++- * accidentally calling ->poll() when NAPI is not scheduled. ++- */ ++- work = 0; ++- if (test_bit(NAPI_STATE_SCHED, &n->state)) { ++- work = n->poll(n, weight); ++- trace_napi_poll(n, work, weight); ++- } ++- ++- if (unlikely(work > weight)) ++- pr_err_once("NAPI poll function %pS returned %d, exceeding its budget of %d.\n", ++- n->poll, work, weight); ++- ++- if (likely(work < weight)) ++- goto out_unlock; +++ work = __napi_poll(n, &do_repoll); ++ ++- /* Drivers must not modify the NAPI state if they ++- * consume the entire weight. In such cases this code ++- * still "owns" the NAPI instance and therefore can ++- * move the instance around on the list at-will. ++- */ ++- if (unlikely(napi_disable_pending(n))) { ++- napi_complete(n); +++ if (!do_repoll) ++ goto out_unlock; ++- } ++- ++- if (n->gro_bitmask) { ++- /* flush too old packets ++- * If HZ < 1000, flush all packets. ++- */ ++- napi_gro_flush(n, HZ >= 1000); ++- } ++- ++- gro_normal_list(n); ++ ++ /* Some drivers may have called napi_schedule ++ * prior to exhausting their budget. ++@@ -11288,6 +11347,10 @@ static int __init net_dev_init(void) ++ sd->backlog.weight = weight_p; ++ } ++ +++ napi_workq = alloc_workqueue("napi_workq", WQ_UNBOUND | WQ_HIGHPRI, +++ WQ_UNBOUND_MAX_ACTIVE | WQ_SYSFS); +++ BUG_ON(!napi_workq); +++ ++ dev_boot_phase = 0; ++ ++ /* The loopback device is special if any other network devices +diff --git a/target/linux/generic/pending-5.10/691-net-add-sysfs-attribute-for-enabling-threaded-NAPI.patch b/target/linux/generic/pending-5.10/691-net-add-sysfs-attribute-for-enabling-threaded-NAPI.patch +new file mode 100644 +index 0000000000..279ae2c25a +--- /dev/null ++++ b/target/linux/generic/pending-5.10/691-net-add-sysfs-attribute-for-enabling-threaded-NAPI.patch +@@ -0,0 +1,74 @@ ++From: Felix Fietkau ++Date: Fri, 21 Aug 2020 15:07:54 +0200 ++Subject: [PATCH] net: add sysfs attribute for enabling threaded NAPI ++ ++This can be used to enable threaded NAPI on drivers that did not explicitly ++request it. ++ ++Suggested-by: Eric Dumazet ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/net/core/net-sysfs.c +++++ b/net/core/net-sysfs.c ++@@ -472,6 +472,52 @@ static ssize_t proto_down_store(struct d ++ } ++ NETDEVICE_SHOW_RW(proto_down, fmt_dec); ++ +++static int change_napi_threaded(struct net_device *dev, unsigned long val) +++{ +++ struct napi_struct *napi; +++ +++ if (list_empty(&dev->napi_list)) +++ return -EOPNOTSUPP; +++ +++ list_for_each_entry(napi, &dev->napi_list, dev_list) { +++ if (val) +++ set_bit(NAPI_STATE_THREADED, &napi->state); +++ else +++ clear_bit(NAPI_STATE_THREADED, &napi->state); +++ } +++ +++ return 0; +++} +++ +++static ssize_t napi_threaded_store(struct device *dev, +++ struct device_attribute *attr, +++ const char *buf, size_t len) +++{ +++ return netdev_store(dev, attr, buf, len, change_napi_threaded); +++} +++ +++static ssize_t napi_threaded_show(struct device *dev, +++ struct device_attribute *attr, +++ char *buf) +++{ +++ struct net_device *netdev = to_net_dev(dev); +++ struct napi_struct *napi; +++ bool enabled = false; +++ +++ if (!rtnl_trylock()) +++ return restart_syscall(); +++ +++ list_for_each_entry(napi, &netdev->napi_list, dev_list) { +++ if (test_bit(NAPI_STATE_THREADED, &napi->state)) +++ enabled = true; +++ } +++ +++ rtnl_unlock(); +++ +++ return sprintf(buf, fmt_dec, enabled); +++} +++static DEVICE_ATTR_RW(napi_threaded); +++ ++ static ssize_t phys_port_id_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++ { ++@@ -564,6 +610,7 @@ static struct attribute *net_class_attrs ++ &dev_attr_tx_queue_len.attr, ++ &dev_attr_gro_flush_timeout.attr, ++ &dev_attr_napi_defer_hard_irqs.attr, +++ &dev_attr_napi_threaded.attr, ++ &dev_attr_phys_port_id.attr, ++ &dev_attr_phys_port_name.attr, ++ &dev_attr_phys_switch_id.attr, +diff --git a/target/linux/generic/pending-5.10/703-phy-add-detach-callback-to-struct-phy_driver.patch b/target/linux/generic/pending-5.10/703-phy-add-detach-callback-to-struct-phy_driver.patch +new file mode 100644 +index 0000000000..371cffc58b +--- /dev/null ++++ b/target/linux/generic/pending-5.10/703-phy-add-detach-callback-to-struct-phy_driver.patch +@@ -0,0 +1,38 @@ ++From: Gabor Juhos ++Subject: generic: add detach callback to struct phy_driver ++ ++lede-commit: fe61fc2d7d0b3fb348b502f68f98243b3ddf5867 ++ ++Signed-off-by: Gabor Juhos ++--- ++ drivers/net/phy/phy_device.c | 3 +++ ++ include/linux/phy.h | 6 ++++++ ++ 2 files changed, 9 insertions(+) ++ ++--- a/drivers/net/phy/phy_device.c +++++ b/drivers/net/phy/phy_device.c ++@@ -1663,6 +1663,9 @@ void phy_detach(struct phy_device *phyde ++ struct module *ndev_owner = NULL; ++ struct mii_bus *bus; ++ +++ if (phydev->drv && phydev->drv->detach) +++ phydev->drv->detach(phydev); +++ ++ if (phydev->sysfs_links) { ++ if (dev) ++ sysfs_remove_link(&dev->dev.kobj, "phydev"); ++--- a/include/linux/phy.h +++++ b/include/linux/phy.h ++@@ -759,6 +759,12 @@ struct phy_driver { ++ /** @handle_interrupt: Override default interrupt handling */ ++ irqreturn_t (*handle_interrupt)(struct phy_device *phydev); ++ +++ /* +++ * Called before an ethernet device is detached +++ * from the PHY. +++ */ +++ void (*detach)(struct phy_device *phydev); +++ ++ /** @remove: Clears up any memory if needed */ ++ void (*remove)(struct phy_device *phydev); ++ +diff --git a/target/linux/generic/pending-5.10/735-net-phy-at803x-fix-at8033-sgmii-mode.patch b/target/linux/generic/pending-5.10/735-net-phy-at803x-fix-at8033-sgmii-mode.patch +new file mode 100644 +index 0000000000..b063b10251 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/735-net-phy-at803x-fix-at8033-sgmii-mode.patch +@@ -0,0 +1,51 @@ ++From: Roman Yeryomin ++Subject: kernel: add at803x fix for sgmii mode ++ ++Some (possibly broken) bootloaders incorreclty initialize at8033 ++phy. This patch enables sgmii autonegotiation mode. ++ ++[john@phrozen.org: felix added this to his upstream queue] ++ ++Signed-off-by: Roman Yeryomin ++--- ++ drivers/net/phy/at803x.c | 25 +++++++++++++++++++++++++ ++ 1 file changed, 25 insertions(+) ++ ++--- a/drivers/net/phy/at803x.c +++++ b/drivers/net/phy/at803x.c ++@@ -76,6 +76,7 @@ ++ #define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A ++ #define AT803X_REG_CHIP_CONFIG 0x1f ++ #define AT803X_BT_BX_REG_SEL 0x8000 +++#define AT803X_SGMII_ANEG_EN 0x1000 ++ ++ #define AT803X_DEBUG_ADDR 0x1D ++ #define AT803X_DEBUG_DATA 0x1E ++@@ -562,6 +563,27 @@ static int at8031_pll_config(struct phy_ ++ static int at803x_config_init(struct phy_device *phydev) ++ { ++ int ret; +++ u32 v; +++ +++ if (phydev->drv->phy_id == ATH8031_PHY_ID && +++ phydev->interface == PHY_INTERFACE_MODE_SGMII) +++ { +++ v = phy_read(phydev, AT803X_REG_CHIP_CONFIG); +++ /* select SGMII/fiber page */ +++ ret = phy_write(phydev, AT803X_REG_CHIP_CONFIG, +++ v & ~AT803X_BT_BX_REG_SEL); +++ if (ret) +++ return ret; +++ /* enable SGMII autonegotiation */ +++ ret = phy_write(phydev, MII_BMCR, AT803X_SGMII_ANEG_EN); +++ if (ret) +++ return ret; +++ /* select copper page */ +++ ret = phy_write(phydev, AT803X_REG_CHIP_CONFIG, +++ v | AT803X_BT_BX_REG_SEL); +++ if (ret) +++ return ret; +++ } ++ ++ /* The RX and TX delay default is: ++ * after HW reset: RX delay enabled and TX delay disabled +diff --git a/target/linux/generic/pending-5.10/760-net-dsa-mv88e6xxx-fix-vlan-setup.patch b/target/linux/generic/pending-5.10/760-net-dsa-mv88e6xxx-fix-vlan-setup.patch +new file mode 100644 +index 0000000000..e6a3d15b79 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/760-net-dsa-mv88e6xxx-fix-vlan-setup.patch +@@ -0,0 +1,27 @@ ++From a1b291f3f6c80a6c5ccad7283fc472d77a2a4763 Mon Sep 17 00:00:00 2001 ++From: Russell King ++Date: Sun, 22 Dec 2019 12:40:11 +0000 ++Subject: [PATCH] net: dsa: mv88e6xxx: fix vlan setup ++ ++Provide an option that drivers can set to indicate they want to receive ++vlan configuration even when vlan filtering is disabled. This is safe ++for Marvell DSA bridges, which do not look up ingress traffic in the ++VTU if the port is in 8021Q disabled state. Whether this change is ++suitable for all DSA bridges is not known. ++ ++Signed-off-by: Russell King ++Signed-off-by: DENG Qingfang ++--- ++ drivers/net/dsa/mv88e6xxx/chip.c | 1 + ++ 1 file changed, 1 insertion(+) ++ ++--- a/drivers/net/dsa/mv88e6xxx/chip.c +++++ b/drivers/net/dsa/mv88e6xxx/chip.c ++@@ -2853,6 +2853,7 @@ static int mv88e6xxx_setup(struct dsa_sw ++ ++ chip->ds = ds; ++ ds->slave_mii_bus = mv88e6xxx_default_mdio_bus(chip); +++ ds->configure_vlan_while_not_filtering = true; ++ ++ mv88e6xxx_reg_lock(chip); ++ +diff --git a/target/linux/generic/pending-5.10/761-net-dsa-mt7530-Support-EEE-features.patch b/target/linux/generic/pending-5.10/761-net-dsa-mt7530-Support-EEE-features.patch +new file mode 100644 +index 0000000000..3e4413db02 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/761-net-dsa-mt7530-Support-EEE-features.patch +@@ -0,0 +1,121 @@ ++From 9cfb2d426c38272f245e9e6f62b3552d1ed5852b Mon Sep 17 00:00:00 2001 ++From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= ++Date: Tue, 21 Apr 2020 00:18:08 +0200 ++Subject: [PATCH] net: dsa: mt7530: Support EEE features ++MIME-Version: 1.0 ++Content-Type: text/plain; charset=UTF-8 ++Content-Transfer-Encoding: 8bit ++ ++Signed-off-by: René van Dorst ++--- a/drivers/net/dsa/mt7530.c +++++ b/drivers/net/dsa/mt7530.c ++@@ -2266,9 +2266,13 @@ static void mt753x_phylink_mac_link_up(s ++ switch (speed) { ++ case SPEED_1000: ++ mcr |= PMCR_FORCE_SPEED_1000; +++ if (priv->eee_enable & BIT(port)) +++ mcr |= PMCR_FORCE_EEE1G; ++ break; ++ case SPEED_100: ++ mcr |= PMCR_FORCE_SPEED_100; +++ if (priv->eee_enable & BIT(port)) +++ mcr |= PMCR_FORCE_EEE100; ++ break; ++ } ++ if (duplex == DUPLEX_FULL) { ++@@ -2509,6 +2513,54 @@ mt753x_phy_write(struct dsa_switch *ds, ++ return priv->info->phy_write(ds, port, regnum, val); ++ } ++ +++static int mt7530_get_mac_eee(struct dsa_switch *ds, int port, +++ struct ethtool_eee *e) +++{ +++ struct mt7530_priv *priv = ds->priv; +++ u32 eeecr, pmsr; +++ +++ e->eee_enabled = !!(priv->eee_enable & BIT(port)); +++ +++ if (e->eee_enabled) { +++ eeecr = mt7530_read(priv, MT7530_PMEEECR_P(port)); +++ e->tx_lpi_enabled = !(eeecr & LPI_MODE_EN); +++ e->tx_lpi_timer = (eeecr >> 4) & 0xFFF; +++ pmsr = mt7530_read(priv, MT7530_PMSR_P(port)); +++ e->eee_active = e->eee_enabled && !!(pmsr & PMSR_EEE1G); +++ } else { +++ e->tx_lpi_enabled = 0; +++ e->tx_lpi_timer = 0; +++ e->eee_active = 0; +++ } +++ +++ return 0; +++} +++ +++static int mt7530_set_mac_eee(struct dsa_switch *ds, int port, +++ struct ethtool_eee *e) +++{ +++ struct mt7530_priv *priv = ds->priv; +++ u32 eeecr; +++ +++ if (e->tx_lpi_enabled && e->tx_lpi_timer > 0xFFF) +++ return -EINVAL; +++ +++ if (e->eee_enabled) { +++ priv->eee_enable |= BIT(port); +++ //MT7530_PMEEECR_P +++ eeecr = mt7530_read(priv, MT7530_PMEEECR_P(port)); +++ eeecr &= 0xFFFF0000; +++ if (!e->tx_lpi_enabled) +++ eeecr |= LPI_MODE_EN; +++ eeecr = LPI_THRESH(e->tx_lpi_timer); +++ mt7530_write(priv, MT7530_PMEEECR_P(port), eeecr); +++ } else { +++ priv->eee_enable &= ~(BIT(port)); +++ } +++ +++ return 0; +++} +++ ++ static const struct dsa_switch_ops mt7530_switch_ops = { ++ .get_tag_protocol = mtk_get_tag_protocol, ++ .setup = mt753x_setup, ++@@ -2537,6 +2589,8 @@ static const struct dsa_switch_ops mt753 ++ .phylink_mac_an_restart = mt753x_phylink_mac_an_restart, ++ .phylink_mac_link_down = mt753x_phylink_mac_link_down, ++ .phylink_mac_link_up = mt753x_phylink_mac_link_up, +++ .get_mac_eee = mt7530_get_mac_eee, +++ .set_mac_eee = mt7530_set_mac_eee, ++ }; ++ ++ static const struct mt753x_info mt753x_table[] = { ++--- a/drivers/net/dsa/mt7530.h +++++ b/drivers/net/dsa/mt7530.h ++@@ -240,6 +240,8 @@ enum mt7530_vlan_port_attr { ++ #define PMCR_RX_EN BIT(13) ++ #define PMCR_BACKOFF_EN BIT(9) ++ #define PMCR_BACKPR_EN BIT(8) +++#define PMCR_FORCE_EEE1G BIT(7) +++#define PMCR_FORCE_EEE100 BIT(6) ++ #define PMCR_TX_FC_EN BIT(5) ++ #define PMCR_RX_FC_EN BIT(4) ++ #define PMCR_FORCE_SPEED_1000 BIT(3) ++@@ -289,6 +291,12 @@ enum mt7530_vlan_port_attr { ++ #define MT7531_DBG_CNT(x) (0x3018 + (x) * 0x100) ++ #define MT7531_DIS_CLR BIT(31) ++ +++#define MT7530_PMEEECR_P(x) (0x3004 + (x) * 0x100) +++#define WAKEUP_TIME_1000(x) ((x & 0xFF) << 24) +++#define WAKEUP_TIME_100(x) ((x & 0xFF) << 16) +++#define LPI_THRESH(x) ((x & 0xFFF) << 4) +++#define LPI_MODE_EN BIT(0) +++ ++ /* Register for MIB */ ++ #define MT7530_PORT_MIB_COUNTER(x) (0x4000 + (x) * 0x100) ++ #define MT7530_MIB_CCR 0x4fe0 ++@@ -732,6 +740,7 @@ struct mt7530_priv { ++ unsigned int p5_intf_sel; ++ u8 mirror_rx; ++ u8 mirror_tx; +++ u8 eee_enable; ++ ++ struct mt7530_port ports[MT7530_NUM_PORTS]; ++ /* protect among processes for registers access*/ +diff --git a/target/linux/generic/pending-5.10/770-00-net-ethernet-mtk_eth_soc-use-napi_consume_skb.patch b/target/linux/generic/pending-5.10/770-00-net-ethernet-mtk_eth_soc-use-napi_consume_skb.patch +new file mode 100644 +index 0000000000..85c859b388 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/770-00-net-ethernet-mtk_eth_soc-use-napi_consume_skb.patch +@@ -0,0 +1,72 @@ ++From: Felix Fietkau ++Date: Mon, 8 Jun 2020 17:01:12 +0200 ++Subject: [PATCH] net: ethernet: mtk_eth_soc: use napi_consume_skb ++ ++Should improve performance, since it can use bulk free ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++@@ -857,7 +857,8 @@ static int txd_to_idx(struct mtk_tx_ring ++ return ((void *)dma - (void *)ring->dma) / sizeof(*dma); ++ } ++ ++-static void mtk_tx_unmap(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf) +++static void mtk_tx_unmap(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf, +++ bool napi) ++ { ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) { ++ if (tx_buf->flags & MTK_TX_FLAGS_SINGLE0) { ++@@ -889,8 +890,12 @@ static void mtk_tx_unmap(struct mtk_eth ++ ++ tx_buf->flags = 0; ++ if (tx_buf->skb && ++- (tx_buf->skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC)) ++- dev_kfree_skb_any(tx_buf->skb); +++ (tx_buf->skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC)) { +++ if (napi) +++ napi_consume_skb(tx_buf->skb, napi); +++ else +++ dev_kfree_skb_any(tx_buf->skb); +++ } ++ tx_buf->skb = NULL; ++ } ++ ++@@ -1068,7 +1073,7 @@ err_dma: ++ tx_buf = mtk_desc_to_tx_buf(ring, itxd); ++ ++ /* unmap dma */ ++- mtk_tx_unmap(eth, tx_buf); +++ mtk_tx_unmap(eth, tx_buf, false); ++ ++ itxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU; ++ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) ++@@ -1386,7 +1391,7 @@ static int mtk_poll_tx_qdma(struct mtk_e ++ done[mac]++; ++ budget--; ++ } ++- mtk_tx_unmap(eth, tx_buf); +++ mtk_tx_unmap(eth, tx_buf, true); ++ ++ ring->last_free = desc; ++ atomic_inc(&ring->free_count); ++@@ -1423,7 +1428,7 @@ static int mtk_poll_tx_pdma(struct mtk_e ++ budget--; ++ } ++ ++- mtk_tx_unmap(eth, tx_buf); +++ mtk_tx_unmap(eth, tx_buf, true); ++ ++ desc = &ring->dma[cpu]; ++ ring->last_free = desc; ++@@ -1625,7 +1630,7 @@ static void mtk_tx_clean(struct mtk_eth ++ ++ if (ring->buf) { ++ for (i = 0; i < MTK_DMA_SIZE; i++) ++- mtk_tx_unmap(eth, &ring->buf[i]); +++ mtk_tx_unmap(eth, &ring->buf[i], false); ++ kfree(ring->buf); ++ ring->buf = NULL; ++ } +diff --git a/target/linux/generic/pending-5.10/770-01-net-ethernet-mtk_eth_soc-significantly-reduce-mdio-b.patch b/target/linux/generic/pending-5.10/770-01-net-ethernet-mtk_eth_soc-significantly-reduce-mdio-b.patch +new file mode 100644 +index 0000000000..922c35a3e4 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/770-01-net-ethernet-mtk_eth_soc-significantly-reduce-mdio-b.patch +@@ -0,0 +1,26 @@ ++From: Felix Fietkau ++Date: Mon, 8 Jun 2020 17:02:39 +0200 ++Subject: [PATCH] net: ethernet: mtk_eth_soc: significantly reduce mdio bus ++ access latency ++ ++usleep_range often ends up sleeping much longer than the 10-20us provided ++as a range here. This causes significant latency in mdio bus acceses, ++which easily adds multiple seconds to the boot time on MT7621 when polling ++DSA slave ports. ++Use cond_resched instead of usleep_range, since the MDIO access does not ++take much time ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++@@ -85,7 +85,7 @@ static int mtk_mdio_busy_wait(struct mtk ++ return 0; ++ if (time_after(jiffies, t_start + PHY_IAC_TIMEOUT)) ++ break; ++- usleep_range(10, 20); +++ cond_resched(); ++ } ++ ++ dev_err(eth->dev, "mdio: MDIO timeout\n"); +diff --git a/target/linux/generic/pending-5.10/770-02-net-ethernet-mtk_eth_soc-fix-rx-vlan-offload.patch b/target/linux/generic/pending-5.10/770-02-net-ethernet-mtk_eth_soc-fix-rx-vlan-offload.patch +new file mode 100644 +index 0000000000..cebfe32d95 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/770-02-net-ethernet-mtk_eth_soc-fix-rx-vlan-offload.patch +@@ -0,0 +1,31 @@ ++From: Felix Fietkau ++Date: Wed, 26 Aug 2020 16:52:12 +0200 ++Subject: [PATCH] net: ethernet: mtk_eth_soc: fix rx vlan offload ++ ++The VLAN ID in the rx descriptor is only valid if the RX_DMA_VID bit is set ++Fixes frames wrongly marked with VLAN tags ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++@@ -1324,7 +1324,7 @@ static int mtk_poll_rx(struct napi_struc ++ skb->protocol = eth_type_trans(skb, netdev); ++ ++ if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX && ++- RX_DMA_VID(trxd.rxd3)) +++ (trxd.rxd2 & RX_DMA_VTAG)) ++ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), ++ RX_DMA_VID(trxd.rxd3)); ++ skb_record_rx_queue(skb, 0); ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++@@ -295,6 +295,7 @@ ++ #define RX_DMA_LSO BIT(30) ++ #define RX_DMA_PLEN0(_x) (((_x) & 0x3fff) << 16) ++ #define RX_DMA_GET_PLEN0(_x) (((_x) >> 16) & 0x3fff) +++#define RX_DMA_VTAG BIT(15) ++ ++ /* QDMA descriptor rxd3 */ ++ #define RX_DMA_VID(_x) ((_x) & 0xfff) +diff --git a/target/linux/generic/pending-5.10/770-03-net-ethernet-mtk_eth_soc-fix-unnecessary-tx-queue-st.patch b/target/linux/generic/pending-5.10/770-03-net-ethernet-mtk_eth_soc-fix-unnecessary-tx-queue-st.patch +new file mode 100644 +index 0000000000..82bdb10eba +--- /dev/null ++++ b/target/linux/generic/pending-5.10/770-03-net-ethernet-mtk_eth_soc-fix-unnecessary-tx-queue-st.patch +@@ -0,0 +1,50 @@ ++From: Felix Fietkau ++Date: Wed, 26 Aug 2020 16:55:54 +0200 ++Subject: [PATCH] net: ethernet: mtk_eth_soc: fix unnecessary tx queue ++ stops ++ ++When running short on descriptors, only stop the queue for the netdev that tx ++was attempted for. By the time the something tries to send on the other netdev, ++the ring might have some more room already ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++@@ -1130,17 +1130,6 @@ static void mtk_wake_queue(struct mtk_et ++ } ++ } ++ ++-static void mtk_stop_queue(struct mtk_eth *eth) ++-{ ++- int i; ++- ++- for (i = 0; i < MTK_MAC_COUNT; i++) { ++- if (!eth->netdev[i]) ++- continue; ++- netif_stop_queue(eth->netdev[i]); ++- } ++-} ++- ++ static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev) ++ { ++ struct mtk_mac *mac = netdev_priv(dev); ++@@ -1161,7 +1150,7 @@ static netdev_tx_t mtk_start_xmit(struct ++ ++ tx_num = mtk_cal_txd_req(skb); ++ if (unlikely(atomic_read(&ring->free_count) <= tx_num)) { ++- mtk_stop_queue(eth); +++ netif_stop_queue(dev); ++ netif_err(eth, tx_queued, dev, ++ "Tx Ring full when queue awake!\n"); ++ spin_unlock(ð->page_lock); ++@@ -1187,7 +1176,7 @@ static netdev_tx_t mtk_start_xmit(struct ++ goto drop; ++ ++ if (unlikely(atomic_read(&ring->free_count) <= ring->thresh)) ++- mtk_stop_queue(eth); +++ netif_stop_queue(dev); ++ ++ spin_unlock(ð->page_lock); ++ +diff --git a/target/linux/generic/pending-5.10/770-04-net-ethernet-mtk_eth_soc-use-larger-burst-size-for-q.patch b/target/linux/generic/pending-5.10/770-04-net-ethernet-mtk_eth_soc-use-larger-burst-size-for-q.patch +new file mode 100644 +index 0000000000..94c0510257 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/770-04-net-ethernet-mtk_eth_soc-use-larger-burst-size-for-q.patch +@@ -0,0 +1,32 @@ ++From: Felix Fietkau ++Date: Wed, 26 Aug 2020 16:58:55 +0200 ++Subject: [PATCH] net: ethernet: mtk_eth_soc: use larger burst size for ++ qdma tx ++ ++Improves tx performance ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++@@ -2191,7 +2191,7 @@ static int mtk_start_dma(struct mtk_eth ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) { ++ mtk_w32(eth, ++ MTK_TX_WB_DDONE | MTK_TX_DMA_EN | ++- MTK_DMA_SIZE_16DWORDS | MTK_NDP_CO_PRO | +++ MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO | ++ MTK_RX_DMA_EN | MTK_RX_2B_OFFSET | ++ MTK_RX_BT_32DWORDS, ++ MTK_QDMA_GLO_CFG); ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++@@ -197,7 +197,7 @@ ++ #define MTK_RX_BT_32DWORDS (3 << 11) ++ #define MTK_NDP_CO_PRO BIT(10) ++ #define MTK_TX_WB_DDONE BIT(6) ++-#define MTK_DMA_SIZE_16DWORDS (2 << 4) +++#define MTK_TX_BT_32DWORDS (3 << 4) ++ #define MTK_RX_DMA_BUSY BIT(3) ++ #define MTK_TX_DMA_BUSY BIT(1) ++ #define MTK_RX_DMA_EN BIT(2) +diff --git a/target/linux/generic/pending-5.10/770-05-net-ethernet-mtk_eth_soc-increase-DMA-ring-sizes.patch b/target/linux/generic/pending-5.10/770-05-net-ethernet-mtk_eth_soc-increase-DMA-ring-sizes.patch +new file mode 100644 +index 0000000000..f68cbc333c +--- /dev/null ++++ b/target/linux/generic/pending-5.10/770-05-net-ethernet-mtk_eth_soc-increase-DMA-ring-sizes.patch +@@ -0,0 +1,21 @@ ++From: Felix Fietkau ++Date: Wed, 26 Aug 2020 16:59:41 +0200 ++Subject: [PATCH] net: ethernet: mtk_eth_soc: increase DMA ring sizes ++ ++256 descriptors is not enough for multi-gigabit traffic under load on MT7622. ++Bump it to 512 to improve performance ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++@@ -19,7 +19,7 @@ ++ #define MTK_QDMA_PAGE_SIZE 2048 ++ #define MTK_MAX_RX_LENGTH 1536 ++ #define MTK_TX_DMA_BUF_LEN 0x3fff ++-#define MTK_DMA_SIZE 256 +++#define MTK_DMA_SIZE 512 ++ #define MTK_NAPI_WEIGHT 64 ++ #define MTK_MAC_COUNT 2 ++ #define MTK_RX_ETH_HLEN (VLAN_ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN) +diff --git a/target/linux/generic/pending-5.10/770-06-net-ethernet-mtk_eth_soc-implement-dynamic-interrupt.patch b/target/linux/generic/pending-5.10/770-06-net-ethernet-mtk_eth_soc-implement-dynamic-interrupt.patch +new file mode 100644 +index 0000000000..61a51ba33b +--- /dev/null ++++ b/target/linux/generic/pending-5.10/770-06-net-ethernet-mtk_eth_soc-implement-dynamic-interrupt.patch +@@ -0,0 +1,281 @@ ++From: Felix Fietkau ++Date: Wed, 26 Aug 2020 17:02:30 +0200 ++Subject: [PATCH] net: ethernet: mtk_eth_soc: implement dynamic interrupt ++ moderation ++ ++Reduces the number of interrupts under load ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/drivers/net/ethernet/mediatek/Kconfig +++++ b/drivers/net/ethernet/mediatek/Kconfig ++@@ -10,6 +10,7 @@ if NET_VENDOR_MEDIATEK ++ config NET_MEDIATEK_SOC ++ tristate "MediaTek SoC Gigabit Ethernet support" ++ select PHYLINK +++ select DIMLIB ++ help ++ This driver supports the gigabit ethernet MACs in the ++ MediaTek SoC family. ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++@@ -1232,12 +1232,13 @@ static void mtk_update_rx_cpu_idx(struct ++ static int mtk_poll_rx(struct napi_struct *napi, int budget, ++ struct mtk_eth *eth) ++ { +++ struct dim_sample dim_sample = {}; ++ struct mtk_rx_ring *ring; ++ int idx; ++ struct sk_buff *skb; ++ u8 *data, *new_data; ++ struct mtk_rx_dma *rxd, trxd; ++- int done = 0; +++ int done = 0, bytes = 0; ++ ++ while (done < budget) { ++ struct net_device *netdev; ++@@ -1311,6 +1312,7 @@ static int mtk_poll_rx(struct napi_struc ++ else ++ skb_checksum_none_assert(skb); ++ skb->protocol = eth_type_trans(skb, netdev); +++ bytes += pktlen; ++ ++ if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX && ++ (trxd.rxd2 & RX_DMA_VTAG)) ++@@ -1342,6 +1344,12 @@ rx_done: ++ mtk_update_rx_cpu_idx(eth); ++ } ++ +++ eth->rx_packets += done; +++ eth->rx_bytes += bytes; +++ dim_update_sample(eth->rx_events, eth->rx_packets, eth->rx_bytes, +++ &dim_sample); +++ net_dim(ð->rx_dim, dim_sample); +++ ++ return done; ++ } ++ ++@@ -1434,6 +1442,7 @@ static int mtk_poll_tx_pdma(struct mtk_e ++ static int mtk_poll_tx(struct mtk_eth *eth, int budget) ++ { ++ struct mtk_tx_ring *ring = ð->tx_ring; +++ struct dim_sample dim_sample = {}; ++ unsigned int done[MTK_MAX_DEVS]; ++ unsigned int bytes[MTK_MAX_DEVS]; ++ int total = 0, i; ++@@ -1451,8 +1460,14 @@ static int mtk_poll_tx(struct mtk_eth *e ++ continue; ++ netdev_completed_queue(eth->netdev[i], done[i], bytes[i]); ++ total += done[i]; +++ eth->tx_packets += done[i]; +++ eth->tx_bytes += bytes[i]; ++ } ++ +++ dim_update_sample(eth->tx_events, eth->tx_packets, eth->tx_bytes, +++ &dim_sample); +++ net_dim(ð->tx_dim, dim_sample); +++ ++ if (mtk_queue_stopped(eth) && ++ (atomic_read(&ring->free_count) > ring->thresh)) ++ mtk_wake_queue(eth); ++@@ -2127,6 +2142,7 @@ static irqreturn_t mtk_handle_irq_rx(int ++ { ++ struct mtk_eth *eth = _eth; ++ +++ eth->rx_events++; ++ if (likely(napi_schedule_prep(ð->rx_napi))) { ++ __napi_schedule(ð->rx_napi); ++ mtk_rx_irq_disable(eth, MTK_RX_DONE_INT); ++@@ -2139,6 +2155,7 @@ static irqreturn_t mtk_handle_irq_tx(int ++ { ++ struct mtk_eth *eth = _eth; ++ +++ eth->tx_events++; ++ if (likely(napi_schedule_prep(ð->tx_napi))) { ++ __napi_schedule(ð->tx_napi); ++ mtk_tx_irq_disable(eth, MTK_TX_DONE_INT); ++@@ -2315,6 +2332,9 @@ static int mtk_stop(struct net_device *d ++ napi_disable(ð->tx_napi); ++ napi_disable(ð->rx_napi); ++ +++ cancel_work_sync(ð->rx_dim.work); +++ cancel_work_sync(ð->tx_dim.work); +++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) ++ mtk_stop_dma(eth, MTK_QDMA_GLO_CFG); ++ mtk_stop_dma(eth, MTK_PDMA_GLO_CFG); ++@@ -2364,6 +2384,64 @@ err_disable_clks: ++ return ret; ++ } ++ +++static void mtk_dim_rx(struct work_struct *work) +++{ +++ struct dim *dim = container_of(work, struct dim, work); +++ struct mtk_eth *eth = container_of(dim, struct mtk_eth, rx_dim); +++ struct dim_cq_moder cur_profile; +++ u32 val, cur; +++ +++ cur_profile = net_dim_get_rx_moderation(eth->rx_dim.mode, +++ dim->profile_ix); +++ spin_lock_bh(ð->dim_lock); +++ +++ val = mtk_r32(eth, MTK_PDMA_DELAY_INT); +++ val &= MTK_PDMA_DELAY_TX_MASK; +++ val |= MTK_PDMA_DELAY_RX_EN; +++ +++ cur = min_t(u32, DIV_ROUND_UP(cur_profile.usec, 20), MTK_PDMA_DELAY_PTIME_MASK); +++ val |= cur << MTK_PDMA_DELAY_RX_PTIME_SHIFT; +++ +++ cur = min_t(u32, cur_profile.pkts, MTK_PDMA_DELAY_PINT_MASK); +++ val |= cur << MTK_PDMA_DELAY_RX_PINT_SHIFT; +++ +++ mtk_w32(eth, val, MTK_PDMA_DELAY_INT); +++ mtk_w32(eth, val, MTK_QDMA_DELAY_INT); +++ +++ spin_unlock_bh(ð->dim_lock); +++ +++ dim->state = DIM_START_MEASURE; +++} +++ +++static void mtk_dim_tx(struct work_struct *work) +++{ +++ struct dim *dim = container_of(work, struct dim, work); +++ struct mtk_eth *eth = container_of(dim, struct mtk_eth, tx_dim); +++ struct dim_cq_moder cur_profile; +++ u32 val, cur; +++ +++ cur_profile = net_dim_get_tx_moderation(eth->tx_dim.mode, +++ dim->profile_ix); +++ spin_lock_bh(ð->dim_lock); +++ +++ val = mtk_r32(eth, MTK_PDMA_DELAY_INT); +++ val &= MTK_PDMA_DELAY_RX_MASK; +++ val |= MTK_PDMA_DELAY_TX_EN; +++ +++ cur = min_t(u32, DIV_ROUND_UP(cur_profile.usec, 20), MTK_PDMA_DELAY_PTIME_MASK); +++ val |= cur << MTK_PDMA_DELAY_TX_PTIME_SHIFT; +++ +++ cur = min_t(u32, cur_profile.pkts, MTK_PDMA_DELAY_PINT_MASK); +++ val |= cur << MTK_PDMA_DELAY_TX_PINT_SHIFT; +++ +++ mtk_w32(eth, val, MTK_PDMA_DELAY_INT); +++ mtk_w32(eth, val, MTK_QDMA_DELAY_INT); +++ +++ spin_unlock_bh(ð->dim_lock); +++ +++ dim->state = DIM_START_MEASURE; +++} +++ ++ static int mtk_hw_init(struct mtk_eth *eth) ++ { ++ int i, val, ret; ++@@ -2385,9 +2463,6 @@ static int mtk_hw_init(struct mtk_eth *e ++ goto err_disable_pm; ++ } ++ ++- /* enable interrupt delay for RX */ ++- mtk_w32(eth, MTK_PDMA_DELAY_RX_DELAY, MTK_PDMA_DELAY_INT); ++- ++ /* disable delay and normal interrupt */ ++ mtk_tx_irq_disable(eth, ~0); ++ mtk_rx_irq_disable(eth, ~0); ++@@ -2426,11 +2501,10 @@ static int mtk_hw_init(struct mtk_eth *e ++ /* Enable RX VLan Offloading */ ++ mtk_w32(eth, 1, MTK_CDMP_EG_CTRL); ++ ++- /* enable interrupt delay for RX */ ++- mtk_w32(eth, MTK_PDMA_DELAY_RX_DELAY, MTK_PDMA_DELAY_INT); +++ mtk_dim_rx(ð->rx_dim.work); +++ mtk_dim_tx(ð->tx_dim.work); ++ ++ /* disable delay and normal interrupt */ ++- mtk_w32(eth, 0, MTK_QDMA_DELAY_INT); ++ mtk_tx_irq_disable(eth, ~0); ++ mtk_rx_irq_disable(eth, ~0); ++ ++@@ -2934,6 +3008,13 @@ static int mtk_probe(struct platform_dev ++ spin_lock_init(ð->page_lock); ++ spin_lock_init(ð->tx_irq_lock); ++ spin_lock_init(ð->rx_irq_lock); +++ spin_lock_init(ð->dim_lock); +++ +++ eth->rx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE; +++ INIT_WORK(ð->rx_dim.work, mtk_dim_rx); +++ +++ eth->tx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE; +++ INIT_WORK(ð->tx_dim.work, mtk_dim_tx); ++ ++ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) { ++ eth->ethsys = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++@@ -15,6 +15,7 @@ ++ #include ++ #include ++ #include +++#include ++ ++ #define MTK_QDMA_PAGE_SIZE 2048 ++ #define MTK_MAX_RX_LENGTH 1536 ++@@ -131,13 +132,18 @@ ++ ++ /* PDMA Delay Interrupt Register */ ++ #define MTK_PDMA_DELAY_INT 0xa0c +++#define MTK_PDMA_DELAY_RX_MASK GENMASK(15, 0) ++ #define MTK_PDMA_DELAY_RX_EN BIT(15) ++-#define MTK_PDMA_DELAY_RX_PINT 4 ++ #define MTK_PDMA_DELAY_RX_PINT_SHIFT 8 ++-#define MTK_PDMA_DELAY_RX_PTIME 4 ++-#define MTK_PDMA_DELAY_RX_DELAY \ ++- (MTK_PDMA_DELAY_RX_EN | MTK_PDMA_DELAY_RX_PTIME | \ ++- (MTK_PDMA_DELAY_RX_PINT << MTK_PDMA_DELAY_RX_PINT_SHIFT)) +++#define MTK_PDMA_DELAY_RX_PTIME_SHIFT 0 +++ +++#define MTK_PDMA_DELAY_TX_MASK GENMASK(31, 16) +++#define MTK_PDMA_DELAY_TX_EN BIT(31) +++#define MTK_PDMA_DELAY_TX_PINT_SHIFT 24 +++#define MTK_PDMA_DELAY_TX_PTIME_SHIFT 16 +++ +++#define MTK_PDMA_DELAY_PINT_MASK 0x7f +++#define MTK_PDMA_DELAY_PTIME_MASK 0xff ++ ++ /* PDMA Interrupt Status Register */ ++ #define MTK_PDMA_INT_STATUS 0xa20 ++@@ -219,6 +225,7 @@ ++ /* QDMA Interrupt Status Register */ ++ #define MTK_QDMA_INT_STATUS 0x1A18 ++ #define MTK_RX_DONE_DLY BIT(30) +++#define MTK_TX_DONE_DLY BIT(28) ++ #define MTK_RX_DONE_INT3 BIT(19) ++ #define MTK_RX_DONE_INT2 BIT(18) ++ #define MTK_RX_DONE_INT1 BIT(17) ++@@ -228,8 +235,7 @@ ++ #define MTK_TX_DONE_INT1 BIT(1) ++ #define MTK_TX_DONE_INT0 BIT(0) ++ #define MTK_RX_DONE_INT MTK_RX_DONE_DLY ++-#define MTK_TX_DONE_INT (MTK_TX_DONE_INT0 | MTK_TX_DONE_INT1 | \ ++- MTK_TX_DONE_INT2 | MTK_TX_DONE_INT3) +++#define MTK_TX_DONE_INT MTK_TX_DONE_DLY ++ ++ /* QDMA Interrupt grouping registers */ ++ #define MTK_QDMA_INT_GRP1 0x1a20 ++@@ -892,6 +898,18 @@ struct mtk_eth { ++ ++ const struct mtk_soc_data *soc; ++ +++ spinlock_t dim_lock; +++ +++ u32 rx_events; +++ u32 rx_packets; +++ u32 rx_bytes; +++ struct dim rx_dim; +++ +++ u32 tx_events; +++ u32 tx_packets; +++ u32 tx_bytes; +++ struct dim tx_dim; +++ ++ u32 tx_int_mask_reg; ++ u32 tx_int_status_reg; ++ u32 rx_dma_l4_valid; +diff --git a/target/linux/generic/pending-5.10/770-08-net-ethernet-mtk_eth_soc-cache-hardware-pointer-of-l.patch b/target/linux/generic/pending-5.10/770-08-net-ethernet-mtk_eth_soc-cache-hardware-pointer-of-l.patch +new file mode 100644 +index 0000000000..20181b8d12 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/770-08-net-ethernet-mtk_eth_soc-cache-hardware-pointer-of-l.patch +@@ -0,0 +1,67 @@ ++From: Felix Fietkau ++Date: Thu, 27 Aug 2020 06:32:03 +0200 ++Subject: [PATCH] net: ethernet: mtk_eth_soc: cache hardware pointer of last ++ freed tx descriptor ++ ++The value is only updated by the CPU, so it is cheaper to access from the ring ++data structure than from a hardware register ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++@@ -1362,7 +1362,7 @@ static int mtk_poll_tx_qdma(struct mtk_e ++ struct mtk_tx_buf *tx_buf; ++ u32 cpu, dma; ++ ++- cpu = mtk_r32(eth, MTK_QTX_CRX_PTR); +++ cpu = ring->last_free_ptr; ++ dma = mtk_r32(eth, MTK_QTX_DRX_PTR); ++ ++ desc = mtk_qdma_phys_to_virt(ring, cpu); ++@@ -1396,6 +1396,7 @@ static int mtk_poll_tx_qdma(struct mtk_e ++ cpu = next_cpu; ++ } ++ +++ ring->last_free_ptr = cpu; ++ mtk_w32(eth, cpu, MTK_QTX_CRX_PTR); ++ ++ return budget; ++@@ -1596,6 +1597,7 @@ static int mtk_tx_alloc(struct mtk_eth * ++ atomic_set(&ring->free_count, MTK_DMA_SIZE - 2); ++ ring->next_free = &ring->dma[0]; ++ ring->last_free = &ring->dma[MTK_DMA_SIZE - 1]; +++ ring->last_free_ptr = (u32)(ring->phys + ((MTK_DMA_SIZE - 1) * sz)); ++ ring->thresh = MAX_SKB_FRAGS; ++ ++ /* make sure that all changes to the dma ring are flushed before we ++@@ -1609,9 +1611,7 @@ static int mtk_tx_alloc(struct mtk_eth * ++ mtk_w32(eth, ++ ring->phys + ((MTK_DMA_SIZE - 1) * sz), ++ MTK_QTX_CRX_PTR); ++- mtk_w32(eth, ++- ring->phys + ((MTK_DMA_SIZE - 1) * sz), ++- MTK_QTX_DRX_PTR); +++ mtk_w32(eth, ring->last_free_ptr, MTK_QTX_DRX_PTR); ++ mtk_w32(eth, (QDMA_RES_THRES << 8) | QDMA_RES_THRES, ++ MTK_QTX_CFG(0)); ++ } else { ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++@@ -624,6 +624,7 @@ struct mtk_tx_buf { ++ * @phys: The physical addr of tx_buf ++ * @next_free: Pointer to the next free descriptor ++ * @last_free: Pointer to the last free descriptor +++ * @last_free_ptr: Hardware pointer value of the last free descriptor ++ * @thresh: The threshold of minimum amount of free descriptors ++ * @free_count: QDMA uses a linked list. Track how many free descriptors ++ * are present ++@@ -634,6 +635,7 @@ struct mtk_tx_ring { ++ dma_addr_t phys; ++ struct mtk_tx_dma *next_free; ++ struct mtk_tx_dma *last_free; +++ u32 last_free_ptr; ++ u16 thresh; ++ atomic_t free_count; ++ int dma_size; +diff --git a/target/linux/generic/pending-5.10/770-09-net-ethernet-mtk_eth_soc-only-read-the-full-rx-descr.patch b/target/linux/generic/pending-5.10/770-09-net-ethernet-mtk_eth_soc-only-read-the-full-rx-descr.patch +new file mode 100644 +index 0000000000..bbd8ae7be4 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/770-09-net-ethernet-mtk_eth_soc-only-read-the-full-rx-descr.patch +@@ -0,0 +1,44 @@ ++From: Felix Fietkau ++Date: Thu, 27 Aug 2020 09:24:25 +0200 ++Subject: [PATCH] net: ethernet: mtk_eth_soc: only read the full rx ++ descriptor if DMA is done ++ ++Uncached memory access is expensive, and there is no need to access all ++descriptor words if we can't process them anyway ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++@@ -776,13 +776,18 @@ static inline int mtk_max_buf_size(int f ++ return buf_size; ++ } ++ ++-static inline void mtk_rx_get_desc(struct mtk_rx_dma *rxd, +++static inline bool mtk_rx_get_desc(struct mtk_rx_dma *rxd, ++ struct mtk_rx_dma *dma_rxd) ++ { ++- rxd->rxd1 = READ_ONCE(dma_rxd->rxd1); ++ rxd->rxd2 = READ_ONCE(dma_rxd->rxd2); +++ if (!(rxd->rxd2 & RX_DMA_DONE)) +++ return false; +++ +++ rxd->rxd1 = READ_ONCE(dma_rxd->rxd1); ++ rxd->rxd3 = READ_ONCE(dma_rxd->rxd3); ++ rxd->rxd4 = READ_ONCE(dma_rxd->rxd4); +++ +++ return true; ++ } ++ ++ /* the qdma core needs scratch memory to be setup */ ++@@ -1254,8 +1259,7 @@ static int mtk_poll_rx(struct napi_struc ++ rxd = &ring->dma[idx]; ++ data = ring->data[idx]; ++ ++- mtk_rx_get_desc(&trxd, rxd); ++- if (!(trxd.rxd2 & RX_DMA_DONE)) +++ if (!mtk_rx_get_desc(&trxd, rxd)) ++ break; ++ ++ /* find out which mac the packet come from. values start at 1 */ +diff --git a/target/linux/generic/pending-5.10/770-10-net-ethernet-mtk_eth_soc-unmap-rx-data-before-callin.patch b/target/linux/generic/pending-5.10/770-10-net-ethernet-mtk_eth_soc-unmap-rx-data-before-callin.patch +new file mode 100644 +index 0000000000..4a19fa1164 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/770-10-net-ethernet-mtk_eth_soc-unmap-rx-data-before-callin.patch +@@ -0,0 +1,44 @@ ++From: Felix Fietkau ++Date: Thu, 27 Aug 2020 09:44:43 +0200 ++Subject: [PATCH] net: ethernet: mtk_eth_soc: unmap rx data before calling ++ build_skb ++ ++Since build_skb accesses the data area (for initializing shinfo), dma unmap ++needs to happen before that call ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++@@ -1297,17 +1297,18 @@ static int mtk_poll_rx(struct napi_struc ++ goto release_desc; ++ } ++ +++ dma_unmap_single(eth->dev, trxd.rxd1, +++ ring->buf_size, DMA_FROM_DEVICE); +++ ++ /* receive data */ ++ skb = build_skb(data, ring->frag_size); ++ if (unlikely(!skb)) { ++- skb_free_frag(new_data); +++ skb_free_frag(data); ++ netdev->stats.rx_dropped++; ++- goto release_desc; +++ goto skip_rx; ++ } ++ skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN); ++ ++- dma_unmap_single(eth->dev, trxd.rxd1, ++- ring->buf_size, DMA_FROM_DEVICE); ++ pktlen = RX_DMA_GET_PLEN0(trxd.rxd2); ++ skb->dev = netdev; ++ skb_put(skb, pktlen); ++@@ -1325,6 +1326,7 @@ static int mtk_poll_rx(struct napi_struc ++ skb_record_rx_queue(skb, 0); ++ napi_gro_receive(napi, skb); ++ +++skip_rx: ++ ring->data[idx] = new_data; ++ rxd->rxd1 = (unsigned int)dma_addr; ++ +diff --git a/target/linux/generic/pending-5.10/770-11-net-ethernet-mtk_eth_soc-avoid-rearming-interrupt-if.patch b/target/linux/generic/pending-5.10/770-11-net-ethernet-mtk_eth_soc-avoid-rearming-interrupt-if.patch +new file mode 100644 +index 0000000000..4c61951d77 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/770-11-net-ethernet-mtk_eth_soc-avoid-rearming-interrupt-if.patch +@@ -0,0 +1,35 @@ ++From: Felix Fietkau ++Date: Fri, 4 Sep 2020 18:14:05 +0200 ++Subject: [PATCH] net: ethernet: mtk_eth_soc: avoid rearming interrupt if ++ napi_complete returns false ++ ++Reduces unnecessary interrupts ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++@@ -1519,8 +1519,8 @@ static int mtk_napi_tx(struct napi_struc ++ if (status & MTK_TX_DONE_INT) ++ return budget; ++ ++- napi_complete(napi); ++- mtk_tx_irq_enable(eth, MTK_TX_DONE_INT); +++ if (napi_complete(napi)) +++ mtk_tx_irq_enable(eth, MTK_TX_DONE_INT); ++ ++ return tx_done; ++ } ++@@ -1553,8 +1553,9 @@ poll_again: ++ remain_budget -= rx_done; ++ goto poll_again; ++ } ++- napi_complete(napi); ++- mtk_rx_irq_enable(eth, MTK_RX_DONE_INT); +++ +++ if (napi_complete(napi)) +++ mtk_rx_irq_enable(eth, MTK_RX_DONE_INT); ++ ++ return rx_done + budget - remain_budget; ++ } +diff --git a/target/linux/generic/pending-5.10/770-13-net-ethernet-mtk_eth_soc-fix-parsing-packets-in-GDM.patch b/target/linux/generic/pending-5.10/770-13-net-ethernet-mtk_eth_soc-fix-parsing-packets-in-GDM.patch +new file mode 100644 +index 0000000000..d81d4bf5f4 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/770-13-net-ethernet-mtk_eth_soc-fix-parsing-packets-in-GDM.patch +@@ -0,0 +1,67 @@ ++From: Felix Fietkau ++Date: Sun, 13 Sep 2020 08:17:02 +0200 ++Subject: [PATCH] net: ethernet: mtk_eth_soc: fix parsing packets in GDM ++ ++When using DSA, set the special tag in GDM ingress control to allow the MAC ++to parse packets properly earlier. This affects rx DMA source port reporting. ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++@@ -19,6 +19,7 @@ ++ #include ++ #include ++ #include +++#include ++ ++ #include "mtk_eth_soc.h" ++ ++@@ -1263,13 +1264,12 @@ static int mtk_poll_rx(struct napi_struc ++ break; ++ ++ /* find out which mac the packet come from. values start at 1 */ ++- if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) { +++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) || +++ (trxd.rxd4 & RX_DMA_SPECIAL_TAG)) ++ mac = 0; ++- } else { ++- mac = (trxd.rxd4 >> RX_DMA_FPORT_SHIFT) & ++- RX_DMA_FPORT_MASK; ++- mac--; ++- } +++ else +++ mac = ((trxd.rxd4 >> RX_DMA_FPORT_SHIFT) & +++ RX_DMA_FPORT_MASK) - 1; ++ ++ if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT || ++ !eth->netdev[mac])) ++@@ -2251,6 +2251,9 @@ static void mtk_gdm_config(struct mtk_et ++ ++ val |= config; ++ +++ if (!i && eth->netdev[0] && netdev_uses_dsa(eth->netdev[0])) +++ val |= MTK_GDMA_SPECIAL_TAG; +++ ++ mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i)); ++ } ++ /* Reset and enable PSE */ ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++@@ -82,6 +82,7 @@ ++ ++ /* GDM Exgress Control Register */ ++ #define MTK_GDMA_FWD_CFG(x) (0x500 + (x * 0x1000)) +++#define MTK_GDMA_SPECIAL_TAG BIT(24) ++ #define MTK_GDMA_ICS_EN BIT(22) ++ #define MTK_GDMA_TCS_EN BIT(21) ++ #define MTK_GDMA_UCS_EN BIT(20) ++@@ -311,6 +312,7 @@ ++ #define RX_DMA_L4_VALID_PDMA BIT(30) /* when PDMA is used */ ++ #define RX_DMA_FPORT_SHIFT 19 ++ #define RX_DMA_FPORT_MASK 0x7 +++#define RX_DMA_SPECIAL_TAG BIT(22) ++ ++ /* PHY Indirect Access Control registers */ ++ #define MTK_PHY_IAC 0x10004 +diff --git a/target/linux/generic/pending-5.10/770-14-net-ethernet-mtk_eth_soc-set-PPE-flow-hash-as-skb-ha.patch b/target/linux/generic/pending-5.10/770-14-net-ethernet-mtk_eth_soc-set-PPE-flow-hash-as-skb-ha.patch +new file mode 100644 +index 0000000000..e94b352b9c +--- /dev/null ++++ b/target/linux/generic/pending-5.10/770-14-net-ethernet-mtk_eth_soc-set-PPE-flow-hash-as-skb-ha.patch +@@ -0,0 +1,41 @@ ++From: Felix Fietkau ++Date: Sun, 13 Sep 2020 08:27:24 +0200 ++Subject: [PATCH] net: ethernet: mtk_eth_soc: set PPE flow hash as skb hash ++ if present ++ ++This improves GRO performance ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++@@ -19,6 +19,7 @@ ++ #include ++ #include ++ #include +++#include ++ #include ++ ++ #include "mtk_eth_soc.h" ++@@ -1250,6 +1251,7 @@ static int mtk_poll_rx(struct napi_struc ++ struct net_device *netdev; ++ unsigned int pktlen; ++ dma_addr_t dma_addr; +++ u32 hash; ++ int mac; ++ ++ ring = mtk_get_rx_ring(eth); ++@@ -1319,6 +1321,12 @@ static int mtk_poll_rx(struct napi_struc ++ skb->protocol = eth_type_trans(skb, netdev); ++ bytes += pktlen; ++ +++ hash = trxd.rxd4 & GENMASK(13, 0); +++ if (hash != GENMASK(13, 0)) { +++ hash = jhash_1word(hash, 0); +++ skb_set_hash(skb, hash, PKT_HASH_TYPE_L4); +++ } +++ ++ if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX && ++ (trxd.rxd2 & RX_DMA_VTAG)) ++ __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), +diff --git a/target/linux/generic/pending-5.10/770-15-net-ethernet-mtk_eth_soc-add-support-for-initializin.patch b/target/linux/generic/pending-5.10/770-15-net-ethernet-mtk_eth_soc-add-support-for-initializin.patch +new file mode 100644 +index 0000000000..fa4803211a +--- /dev/null ++++ b/target/linux/generic/pending-5.10/770-15-net-ethernet-mtk_eth_soc-add-support-for-initializin.patch +@@ -0,0 +1,1307 @@ ++From: Felix Fietkau ++Date: Sun, 11 Oct 2020 22:23:08 +0200 ++Subject: [PATCH] ethernet: mediatek: mtk_eth_soc: add support for ++ initializing the PPE ++ ++The PPE (packet processing engine) is used to offload NAT/routed or even ++bridged flows. This patch brings up the PPE and uses it to get a packet ++hash. It also contains some functionality that will be used to bring up ++flow offloading. ++ ++Signed-off-by: Felix Fietkau ++--- ++ create mode 100644 drivers/net/ethernet/mediatek/mtk_ppe.c ++ create mode 100644 drivers/net/ethernet/mediatek/mtk_ppe.h ++ create mode 100644 drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c ++ create mode 100644 drivers/net/ethernet/mediatek/mtk_ppe_regs.h ++ ++--- a/drivers/net/ethernet/mediatek/Makefile +++++ b/drivers/net/ethernet/mediatek/Makefile ++@@ -4,5 +4,5 @@ ++ # ++ ++ obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o ++-mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.o +++mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o ++ obj-$(CONFIG_NET_MEDIATEK_STAR_EMAC) += mtk_star_emac.o ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++@@ -2284,12 +2284,17 @@ static int mtk_open(struct net_device *d ++ ++ /* we run 2 netdevs on the same dma ring so we only bring it up once */ ++ if (!refcount_read(ð->dma_refcnt)) { ++- int err = mtk_start_dma(eth); +++ u32 gdm_config = MTK_GDMA_TO_PDMA; +++ int err; ++ +++ err = mtk_start_dma(eth); ++ if (err) ++ return err; ++ ++- mtk_gdm_config(eth, MTK_GDMA_TO_PDMA); +++ if (eth->soc->offload_version && mtk_ppe_start(ð->ppe) == 0) +++ gdm_config = MTK_GDMA_TO_PPE; +++ +++ mtk_gdm_config(eth, gdm_config); ++ ++ napi_enable(ð->tx_napi); ++ napi_enable(ð->rx_napi); ++@@ -2359,6 +2364,9 @@ static int mtk_stop(struct net_device *d ++ ++ mtk_dma_free(eth); ++ +++ if (eth->soc->offload_version) +++ mtk_ppe_stop(ð->ppe); +++ ++ return 0; ++ } ++ ++@@ -3148,6 +3156,13 @@ static int mtk_probe(struct platform_dev ++ goto err_free_dev; ++ } ++ +++ if (eth->soc->offload_version) { +++ err = mtk_ppe_init(ð->ppe, eth->dev, +++ eth->base + MTK_ETH_PPE_BASE, 2); +++ if (err) +++ goto err_free_dev; +++ } +++ ++ for (i = 0; i < MTK_MAX_DEVS; i++) { ++ if (!eth->netdev[i]) ++ continue; ++@@ -3222,6 +3237,7 @@ static const struct mtk_soc_data mt7621_ ++ .hw_features = MTK_HW_FEATURES, ++ .required_clks = MT7621_CLKS_BITMAP, ++ .required_pctl = false, +++ .offload_version = 2, ++ }; ++ ++ static const struct mtk_soc_data mt7622_data = { ++@@ -3230,6 +3246,7 @@ static const struct mtk_soc_data mt7622_ ++ .hw_features = MTK_HW_FEATURES, ++ .required_clks = MT7622_CLKS_BITMAP, ++ .required_pctl = false, +++ .offload_version = 2, ++ }; ++ ++ static const struct mtk_soc_data mt7623_data = { ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++@@ -16,6 +16,7 @@ ++ #include ++ #include ++ #include +++#include "mtk_ppe.h" ++ ++ #define MTK_QDMA_PAGE_SIZE 2048 ++ #define MTK_MAX_RX_LENGTH 1536 ++@@ -87,6 +88,7 @@ ++ #define MTK_GDMA_TCS_EN BIT(21) ++ #define MTK_GDMA_UCS_EN BIT(20) ++ #define MTK_GDMA_TO_PDMA 0x0 +++#define MTK_GDMA_TO_PPE 0x4444 ++ #define MTK_GDMA_DROP_ALL 0x7777 ++ ++ /* Unicast Filter MAC Address Register - Low */ ++@@ -308,6 +310,12 @@ ++ #define RX_DMA_VID(_x) ((_x) & 0xfff) ++ ++ /* QDMA descriptor rxd4 */ +++#define MTK_RXD4_FOE_ENTRY GENMASK(13, 0) +++#define MTK_RXD4_PPE_CPU_REASON GENMASK(18, 14) +++#define MTK_RXD4_SRC_PORT GENMASK(21, 19) +++#define MTK_RXD4_ALG GENMASK(31, 22) +++ +++/* QDMA descriptor rxd4 */ ++ #define RX_DMA_L4_VALID BIT(24) ++ #define RX_DMA_L4_VALID_PDMA BIT(30) /* when PDMA is used */ ++ #define RX_DMA_FPORT_SHIFT 19 ++@@ -807,6 +815,7 @@ struct mtk_soc_data { ++ u32 caps; ++ u32 required_clks; ++ bool required_pctl; +++ u8 offload_version; ++ netdev_features_t hw_features; ++ }; ++ ++@@ -918,6 +927,8 @@ struct mtk_eth { ++ u32 tx_int_status_reg; ++ u32 rx_dma_l4_valid; ++ int ip_align; +++ +++ struct mtk_ppe ppe; ++ }; ++ ++ /* struct mtk_mac - the structure that holds the info about the MACs of the ++--- /dev/null +++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c ++@@ -0,0 +1,511 @@ +++// SPDX-License-Identifier: GPL-2.0-only +++/* Copyright (C) 2020 Felix Fietkau */ +++ +++#include +++#include +++#include +++#include +++#include +++#include +++#include "mtk_ppe.h" +++#include "mtk_ppe_regs.h" +++ +++static void ppe_w32(struct mtk_ppe *ppe, u32 reg, u32 val) +++{ +++ writel(val, ppe->base + reg); +++} +++ +++static u32 ppe_r32(struct mtk_ppe *ppe, u32 reg) +++{ +++ return readl(ppe->base + reg); +++} +++ +++static u32 ppe_m32(struct mtk_ppe *ppe, u32 reg, u32 mask, u32 set) +++{ +++ u32 val; +++ +++ val = ppe_r32(ppe, reg); +++ val &= ~mask; +++ val |= set; +++ ppe_w32(ppe, reg, val); +++ +++ return val; +++} +++ +++static u32 ppe_set(struct mtk_ppe *ppe, u32 reg, u32 val) +++{ +++ return ppe_m32(ppe, reg, 0, val); +++} +++ +++static u32 ppe_clear(struct mtk_ppe *ppe, u32 reg, u32 val) +++{ +++ return ppe_m32(ppe, reg, val, 0); +++} +++ +++static int mtk_ppe_wait_busy(struct mtk_ppe *ppe) +++{ +++ unsigned long timeout = jiffies + HZ; +++ +++ while (time_is_before_jiffies(timeout)) { +++ if (!(ppe_r32(ppe, MTK_PPE_GLO_CFG) & MTK_PPE_GLO_CFG_BUSY)) +++ return 0; +++ +++ usleep_range(10, 20); +++ } +++ +++ dev_err(ppe->dev, "PPE table busy"); +++ +++ return -ETIMEDOUT; +++} +++ +++static void mtk_ppe_cache_clear(struct mtk_ppe *ppe) +++{ +++ ppe_set(ppe, MTK_PPE_CACHE_CTL, MTK_PPE_CACHE_CTL_CLEAR); +++ ppe_clear(ppe, MTK_PPE_CACHE_CTL, MTK_PPE_CACHE_CTL_CLEAR); +++} +++ +++static void mtk_ppe_cache_enable(struct mtk_ppe *ppe, bool enable) +++{ +++ mtk_ppe_cache_clear(ppe); +++ +++ ppe_m32(ppe, MTK_PPE_CACHE_CTL, MTK_PPE_CACHE_CTL_EN, +++ enable * MTK_PPE_CACHE_CTL_EN); +++} +++ +++static u32 mtk_ppe_hash_entry(struct mtk_foe_entry *e) +++{ +++ u32 hv1, hv2, hv3; +++ u32 hash; +++ +++ switch (FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, e->ib1)) { +++ case MTK_PPE_PKT_TYPE_BRIDGE: +++ hv1 = e->bridge.src_mac_lo; +++ hv1 ^= ((e->bridge.src_mac_hi & 0xffff) << 16); +++ hv2 = e->bridge.src_mac_hi >> 16; +++ hv2 ^= e->bridge.dest_mac_lo; +++ hv3 = e->bridge.dest_mac_hi; +++ break; +++ case MTK_PPE_PKT_TYPE_IPV4_ROUTE: +++ case MTK_PPE_PKT_TYPE_IPV4_HNAPT: +++ hv1 = e->ipv4.orig.ports; +++ hv2 = e->ipv4.orig.dest_ip; +++ hv3 = e->ipv4.orig.src_ip; +++ break; +++ case MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T: +++ case MTK_PPE_PKT_TYPE_IPV6_ROUTE_5T: +++ hv1 = e->ipv6.src_ip[3] ^ e->ipv6.dest_ip[3]; +++ hv1 ^= e->ipv6.ports; +++ +++ hv2 = e->ipv6.src_ip[2] ^ e->ipv6.dest_ip[2]; +++ hv2 ^= e->ipv6.dest_ip[0]; +++ +++ hv3 = e->ipv6.src_ip[1] ^ e->ipv6.dest_ip[1]; +++ hv3 ^= e->ipv6.src_ip[0]; +++ break; +++ case MTK_PPE_PKT_TYPE_IPV4_DSLITE: +++ case MTK_PPE_PKT_TYPE_IPV6_6RD: +++ default: +++ WARN_ON_ONCE(1); +++ return MTK_PPE_HASH_MASK; +++ } +++ +++ hash = (hv1 & hv2) | ((~hv1) & hv3); +++ hash = (hash >> 24) | ((hash & 0xffffff) << 8); +++ hash ^= hv1 ^ hv2 ^ hv3; +++ hash ^= hash >> 16; +++ hash <<= 1; +++ hash &= MTK_PPE_ENTRIES - 1; +++ +++ return hash; +++} +++ +++static inline struct mtk_foe_mac_info * +++mtk_foe_entry_l2(struct mtk_foe_entry *entry) +++{ +++ int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); +++ +++ if (type >= MTK_PPE_PKT_TYPE_IPV4_DSLITE) +++ return &entry->ipv6.l2; +++ +++ return &entry->ipv4.l2; +++} +++ +++static inline u32 * +++mtk_foe_entry_ib2(struct mtk_foe_entry *entry) +++{ +++ int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); +++ +++ if (type >= MTK_PPE_PKT_TYPE_IPV4_DSLITE) +++ return &entry->ipv6.ib2; +++ +++ return &entry->ipv4.ib2; +++} +++ +++int mtk_foe_entry_prepare(struct mtk_foe_entry *entry, int type, int l4proto, +++ u8 pse_port, u8 *src_mac, u8 *dest_mac) +++{ +++ struct mtk_foe_mac_info *l2; +++ u32 ports_pad, val; +++ +++ memset(entry, 0, sizeof(*entry)); +++ +++ val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) | +++ FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE, type) | +++ FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) | +++ MTK_FOE_IB1_BIND_TTL | +++ MTK_FOE_IB1_BIND_CACHE; +++ entry->ib1 = val; +++ +++ val = FIELD_PREP(MTK_FOE_IB2_PORT_MG, 0x3f) | +++ FIELD_PREP(MTK_FOE_IB2_PORT_AG, 0x1f) | +++ FIELD_PREP(MTK_FOE_IB2_DEST_PORT, pse_port); +++ +++ if (is_multicast_ether_addr(dest_mac)) +++ val |= MTK_FOE_IB2_MULTICAST; +++ +++ ports_pad = 0xa5a5a500 | (l4proto & 0xff); +++ if (type == MTK_PPE_PKT_TYPE_IPV4_ROUTE) +++ entry->ipv4.orig.ports = ports_pad; +++ if (type == MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T) +++ entry->ipv6.ports = ports_pad; +++ +++ if (type >= MTK_PPE_PKT_TYPE_IPV4_DSLITE) { +++ entry->ipv6.ib2 = val; +++ l2 = &entry->ipv6.l2; +++ } else { +++ entry->ipv4.ib2 = val; +++ l2 = &entry->ipv4.l2; +++ } +++ +++ l2->dest_mac_hi = get_unaligned_be32(dest_mac); +++ l2->dest_mac_lo = get_unaligned_be16(dest_mac + 4); +++ l2->src_mac_hi = get_unaligned_be32(src_mac); +++ l2->src_mac_lo = get_unaligned_be16(src_mac + 4); +++ +++ if (type >= MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T) +++ l2->etype = ETH_P_IPV6; +++ else +++ l2->etype = ETH_P_IP; +++ +++ return 0; +++} +++ +++int mtk_foe_entry_set_pse_port(struct mtk_foe_entry *entry, u8 port) +++{ +++ u32 *ib2 = mtk_foe_entry_ib2(entry); +++ u32 val; +++ +++ val = *ib2; +++ val &= ~MTK_FOE_IB2_DEST_PORT; +++ val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT, port); +++ *ib2 = val; +++ +++ return 0; +++} +++ +++int mtk_foe_entry_set_ipv4_tuple(struct mtk_foe_entry *entry, bool egress, +++ __be32 src_addr, __be16 src_port, +++ __be32 dest_addr, __be16 dest_port) +++{ +++ int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); +++ struct mtk_ipv4_tuple *t; +++ +++ switch (type) { +++ case MTK_PPE_PKT_TYPE_IPV4_HNAPT: +++ if (egress) { +++ t = &entry->ipv4.new; +++ break; +++ } +++ fallthrough; +++ case MTK_PPE_PKT_TYPE_IPV4_DSLITE: +++ case MTK_PPE_PKT_TYPE_IPV4_ROUTE: +++ t = &entry->ipv4.orig; +++ break; +++ case MTK_PPE_PKT_TYPE_IPV6_6RD: +++ entry->ipv6_6rd.tunnel_src_ip = be32_to_cpu(src_addr); +++ entry->ipv6_6rd.tunnel_dest_ip = be32_to_cpu(dest_addr); +++ return 0; +++ default: +++ WARN_ON_ONCE(1); +++ return -EINVAL; +++ } +++ +++ t->src_ip = be32_to_cpu(src_addr); +++ t->dest_ip = be32_to_cpu(dest_addr); +++ +++ if (type == MTK_PPE_PKT_TYPE_IPV4_ROUTE) +++ return 0; +++ +++ t->src_port = be16_to_cpu(src_port); +++ t->dest_port = be16_to_cpu(dest_port); +++ +++ return 0; +++} +++ +++int mtk_foe_entry_set_ipv6_tuple(struct mtk_foe_entry *entry, +++ __be32 *src_addr, __be16 src_port, +++ __be32 *dest_addr, __be16 dest_port) +++{ +++ int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); +++ u32 *src, *dest; +++ int i; +++ +++ switch (type) { +++ case MTK_PPE_PKT_TYPE_IPV4_DSLITE: +++ src = entry->dslite.tunnel_src_ip; +++ dest = entry->dslite.tunnel_dest_ip; +++ break; +++ case MTK_PPE_PKT_TYPE_IPV6_ROUTE_5T: +++ case MTK_PPE_PKT_TYPE_IPV6_6RD: +++ entry->ipv6.src_port = be16_to_cpu(src_port); +++ entry->ipv6.dest_port = be16_to_cpu(dest_port); +++ fallthrough; +++ case MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T: +++ src = entry->ipv6.src_ip; +++ dest = entry->ipv6.dest_ip; +++ break; +++ default: +++ WARN_ON_ONCE(1); +++ return -EINVAL; +++ }; +++ +++ for (i = 0; i < 4; i++) +++ src[i] = be32_to_cpu(src_addr[i]); +++ for (i = 0; i < 4; i++) +++ dest[i] = be32_to_cpu(dest_addr[i]); +++ +++ return 0; +++} +++ +++int mtk_foe_entry_set_dsa(struct mtk_foe_entry *entry, int port) +++{ +++ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry); +++ +++ l2->etype = BIT(port); +++ +++ if (!(entry->ib1 & MTK_FOE_IB1_BIND_VLAN_LAYER)) +++ entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, 1); +++ else +++ l2->etype |= BIT(8); +++ +++ entry->ib1 &= ~MTK_FOE_IB1_BIND_VLAN_TAG; +++ +++ return 0; +++} +++ +++int mtk_foe_entry_set_vlan(struct mtk_foe_entry *entry, int vid) +++{ +++ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry); +++ +++ switch (FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER, entry->ib1)) { +++ case 0: +++ entry->ib1 |= MTK_FOE_IB1_BIND_VLAN_TAG | +++ FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, 1); +++ l2->vlan1 = vid; +++ return 0; +++ case 1: +++ if (!(entry->ib1 & MTK_FOE_IB1_BIND_VLAN_TAG)) { +++ l2->vlan1 = vid; +++ l2->etype |= BIT(8); +++ } else { +++ l2->vlan2 = vid; +++ entry->ib1 += FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, 1); +++ } +++ return 0; +++ default: +++ return -ENOSPC; +++ } +++} +++ +++int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid) +++{ +++ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry); +++ +++ if (!(entry->ib1 & MTK_FOE_IB1_BIND_VLAN_LAYER) || +++ (entry->ib1 & MTK_FOE_IB1_BIND_VLAN_TAG)) +++ l2->etype = ETH_P_PPP_SES; +++ +++ entry->ib1 |= MTK_FOE_IB1_BIND_PPPOE; +++ l2->pppoe_id = sid; +++ +++ return 0; +++} +++ +++static inline bool mtk_foe_entry_usable(struct mtk_foe_entry *entry) +++{ +++ return !(entry->ib1 & MTK_FOE_IB1_STATIC) && +++ FIELD_GET(MTK_FOE_IB1_STATE, entry->ib1) != MTK_FOE_STATE_BIND; +++} +++ +++int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry, +++ u16 timestamp) +++{ +++ struct mtk_foe_entry *hwe; +++ u32 hash; +++ +++ timestamp &= MTK_FOE_IB1_BIND_TIMESTAMP; +++ entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP; +++ entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP, timestamp); +++ +++ hash = mtk_ppe_hash_entry(entry); +++ hwe = &ppe->foe_table[hash]; +++ if (!mtk_foe_entry_usable(hwe)) { +++ hwe++; +++ hash++; +++ +++ if (!mtk_foe_entry_usable(hwe)) +++ return -ENOSPC; +++ } +++ +++ memcpy(&hwe->data, &entry->data, sizeof(hwe->data)); +++ wmb(); +++ hwe->ib1 = entry->ib1; +++ +++ dma_wmb(); +++ +++ mtk_ppe_cache_clear(ppe); +++ +++ return hash; +++} +++ +++int mtk_ppe_init(struct mtk_ppe *ppe, struct device *dev, void __iomem *base, +++ int version) +++{ +++ struct mtk_foe_entry *foe; +++ +++ /* need to allocate a separate device, since it PPE DMA access is +++ * not coherent. +++ */ +++ ppe->base = base; +++ ppe->dev = dev; +++ ppe->version = version; +++ +++ foe = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*foe), +++ &ppe->foe_phys, GFP_KERNEL); +++ if (!foe) +++ return -ENOMEM; +++ +++ ppe->foe_table = foe; +++ +++ mtk_ppe_debugfs_init(ppe); +++ +++ return 0; +++} +++ +++static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe) +++{ +++ static const u8 skip[] = { 12, 25, 38, 51, 76, 89, 102 }; +++ int i, k; +++ +++ memset(ppe->foe_table, 0, MTK_PPE_ENTRIES * sizeof(ppe->foe_table)); +++ +++ if (!IS_ENABLED(CONFIG_SOC_MT7621)) +++ return; +++ +++ /* skip all entries that cross the 1024 byte boundary */ +++ for (i = 0; i < MTK_PPE_ENTRIES; i += 128) +++ for (k = 0; k < ARRAY_SIZE(skip); k++) +++ ppe->foe_table[i + skip[k]].ib1 |= MTK_FOE_IB1_STATIC; +++} +++ +++int mtk_ppe_start(struct mtk_ppe *ppe) +++{ +++ u32 val; +++ +++ mtk_ppe_init_foe_table(ppe); +++ ppe_w32(ppe, MTK_PPE_TB_BASE, ppe->foe_phys); +++ +++ val = MTK_PPE_TB_CFG_ENTRY_80B | +++ MTK_PPE_TB_CFG_AGE_NON_L4 | +++ MTK_PPE_TB_CFG_AGE_UNBIND | +++ MTK_PPE_TB_CFG_AGE_TCP | +++ MTK_PPE_TB_CFG_AGE_UDP | +++ MTK_PPE_TB_CFG_AGE_TCP_FIN | +++ FIELD_PREP(MTK_PPE_TB_CFG_SEARCH_MISS, +++ MTK_PPE_SEARCH_MISS_ACTION_FORWARD_BUILD) | +++ FIELD_PREP(MTK_PPE_TB_CFG_KEEPALIVE, +++ MTK_PPE_KEEPALIVE_DISABLE) | +++ FIELD_PREP(MTK_PPE_TB_CFG_HASH_MODE, 1) | +++ FIELD_PREP(MTK_PPE_TB_CFG_SCAN_MODE, +++ MTK_PPE_SCAN_MODE_KEEPALIVE_AGE) | +++ FIELD_PREP(MTK_PPE_TB_CFG_ENTRY_NUM, +++ MTK_PPE_ENTRIES_SHIFT); +++ ppe_w32(ppe, MTK_PPE_TB_CFG, val); +++ +++ ppe_w32(ppe, MTK_PPE_IP_PROTO_CHK, +++ MTK_PPE_IP_PROTO_CHK_IPV4 | MTK_PPE_IP_PROTO_CHK_IPV6); +++ +++ mtk_ppe_cache_enable(ppe, true); +++ +++ val = MTK_PPE_FLOW_CFG_IP4_TCP_FRAG | +++ MTK_PPE_FLOW_CFG_IP4_UDP_FRAG | +++ MTK_PPE_FLOW_CFG_IP6_3T_ROUTE | +++ MTK_PPE_FLOW_CFG_IP6_5T_ROUTE | +++ MTK_PPE_FLOW_CFG_IP6_6RD | +++ MTK_PPE_FLOW_CFG_IP4_NAT | +++ MTK_PPE_FLOW_CFG_IP4_NAPT | +++ MTK_PPE_FLOW_CFG_IP4_DSLITE | +++ MTK_PPE_FLOW_CFG_L2_BRIDGE | +++ MTK_PPE_FLOW_CFG_IP4_NAT_FRAG; +++ ppe_w32(ppe, MTK_PPE_FLOW_CFG, val); +++ +++ val = FIELD_PREP(MTK_PPE_UNBIND_AGE_MIN_PACKETS, 1000) | +++ FIELD_PREP(MTK_PPE_UNBIND_AGE_DELTA, 3); +++ ppe_w32(ppe, MTK_PPE_UNBIND_AGE, val); +++ +++ val = FIELD_PREP(MTK_PPE_BIND_AGE0_DELTA_UDP, 12) | +++ FIELD_PREP(MTK_PPE_BIND_AGE0_DELTA_NON_L4, 1); +++ ppe_w32(ppe, MTK_PPE_BIND_AGE0, val); +++ +++ val = FIELD_PREP(MTK_PPE_BIND_AGE1_DELTA_TCP_FIN, 1) | +++ FIELD_PREP(MTK_PPE_BIND_AGE1_DELTA_TCP, 7); +++ ppe_w32(ppe, MTK_PPE_BIND_AGE1, val); +++ +++ val = MTK_PPE_BIND_LIMIT0_QUARTER | MTK_PPE_BIND_LIMIT0_HALF; +++ ppe_w32(ppe, MTK_PPE_BIND_LIMIT0, val); +++ +++ val = MTK_PPE_BIND_LIMIT1_FULL | +++ FIELD_PREP(MTK_PPE_BIND_LIMIT1_NON_L4, 1); +++ ppe_w32(ppe, MTK_PPE_BIND_LIMIT1, val); +++ +++ val = FIELD_PREP(MTK_PPE_BIND_RATE_BIND, 30) | +++ FIELD_PREP(MTK_PPE_BIND_RATE_PREBIND, 1); +++ ppe_w32(ppe, MTK_PPE_BIND_RATE, val); +++ +++ /* enable PPE */ +++ val = MTK_PPE_GLO_CFG_EN | +++ MTK_PPE_GLO_CFG_IP4_L4_CS_DROP | +++ MTK_PPE_GLO_CFG_IP4_CS_DROP | +++ MTK_PPE_GLO_CFG_FLOW_DROP_UPDATE; +++ ppe_w32(ppe, MTK_PPE_GLO_CFG, val); +++ +++ ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0); +++ +++ return 0; +++} +++ +++int mtk_ppe_stop(struct mtk_ppe *ppe) +++{ +++ u32 val; +++ int i; +++ +++ for (i = 0; i < MTK_PPE_ENTRIES; i++) +++ ppe->foe_table[i].ib1 = FIELD_PREP(MTK_FOE_IB1_STATE, +++ MTK_FOE_STATE_INVALID); +++ +++ mtk_ppe_cache_enable(ppe, false); +++ +++ /* disable offload engine */ +++ ppe_clear(ppe, MTK_PPE_GLO_CFG, MTK_PPE_GLO_CFG_EN); +++ ppe_w32(ppe, MTK_PPE_FLOW_CFG, 0); +++ +++ /* disable aging */ +++ val = MTK_PPE_TB_CFG_AGE_NON_L4 | +++ MTK_PPE_TB_CFG_AGE_UNBIND | +++ MTK_PPE_TB_CFG_AGE_TCP | +++ MTK_PPE_TB_CFG_AGE_UDP | +++ MTK_PPE_TB_CFG_AGE_TCP_FIN; +++ ppe_clear(ppe, MTK_PPE_TB_CFG, val); +++ +++ return mtk_ppe_wait_busy(ppe); +++} ++--- /dev/null +++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h ++@@ -0,0 +1,287 @@ +++// SPDX-License-Identifier: GPL-2.0-only +++/* Copyright (C) 2020 Felix Fietkau */ +++ +++#ifndef __MTK_PPE_H +++#define __MTK_PPE_H +++ +++#include +++#include +++ +++#define MTK_ETH_PPE_BASE 0xc00 +++ +++#define MTK_PPE_ENTRIES_SHIFT 3 +++#define MTK_PPE_ENTRIES (1024 << MTK_PPE_ENTRIES_SHIFT) +++#define MTK_PPE_HASH_MASK (MTK_PPE_ENTRIES - 1) +++ +++#define MTK_FOE_IB1_UNBIND_TIMESTAMP GENMASK(7, 0) +++#define MTK_FOE_IB1_UNBIND_PACKETS GENMASK(23, 8) +++#define MTK_FOE_IB1_UNBIND_PREBIND BIT(24) +++ +++#define MTK_FOE_IB1_BIND_TIMESTAMP GENMASK(14, 0) +++#define MTK_FOE_IB1_BIND_KEEPALIVE BIT(15) +++#define MTK_FOE_IB1_BIND_VLAN_LAYER GENMASK(18, 16) +++#define MTK_FOE_IB1_BIND_PPPOE BIT(19) +++#define MTK_FOE_IB1_BIND_VLAN_TAG BIT(20) +++#define MTK_FOE_IB1_BIND_PKT_SAMPLE BIT(21) +++#define MTK_FOE_IB1_BIND_CACHE BIT(22) +++#define MTK_FOE_IB1_BIND_TUNNEL_DECAP BIT(23) +++#define MTK_FOE_IB1_BIND_TTL BIT(24) +++ +++#define MTK_FOE_IB1_PACKET_TYPE GENMASK(27, 25) +++#define MTK_FOE_IB1_STATE GENMASK(29, 28) +++#define MTK_FOE_IB1_UDP BIT(30) +++#define MTK_FOE_IB1_STATIC BIT(31) +++ +++enum { +++ MTK_PPE_PKT_TYPE_IPV4_HNAPT = 0, +++ MTK_PPE_PKT_TYPE_IPV4_ROUTE = 1, +++ MTK_PPE_PKT_TYPE_BRIDGE = 2, +++ MTK_PPE_PKT_TYPE_IPV4_DSLITE = 3, +++ MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T = 4, +++ MTK_PPE_PKT_TYPE_IPV6_ROUTE_5T = 5, +++ MTK_PPE_PKT_TYPE_IPV6_6RD = 7, +++}; +++ +++#define MTK_FOE_IB2_QID GENMASK(3, 0) +++#define MTK_FOE_IB2_PSE_QOS BIT(4) +++#define MTK_FOE_IB2_DEST_PORT GENMASK(7, 5) +++#define MTK_FOE_IB2_MULTICAST BIT(8) +++ +++#define MTK_FOE_IB2_WHNAT_QID2 GENMASK(13, 12) +++#define MTK_FOE_IB2_WHNAT_DEVIDX BIT(16) +++#define MTK_FOE_IB2_WHNAT_NAT BIT(17) +++ +++#define MTK_FOE_IB2_PORT_MG GENMASK(17, 12) +++ +++#define MTK_FOE_IB2_PORT_AG GENMASK(23, 18) +++ +++#define MTK_FOE_IB2_DSCP GENMASK(31, 24) +++ +++#define MTK_FOE_VLAN2_WHNAT_BSS GEMMASK(5, 0) +++#define MTK_FOE_VLAN2_WHNAT_WCID GENMASK(13, 6) +++#define MTK_FOE_VLAN2_WHNAT_RING GENMASK(15, 14) +++ +++enum { +++ MTK_FOE_STATE_INVALID, +++ MTK_FOE_STATE_UNBIND, +++ MTK_FOE_STATE_BIND, +++ MTK_FOE_STATE_FIN +++}; +++ +++struct mtk_foe_mac_info { +++ u16 vlan1; +++ u16 etype; +++ +++ u32 dest_mac_hi; +++ +++ u16 vlan2; +++ u16 dest_mac_lo; +++ +++ u32 src_mac_hi; +++ +++ u16 pppoe_id; +++ u16 src_mac_lo; +++}; +++ +++struct mtk_foe_bridge { +++ u32 dest_mac_hi; +++ +++ u16 src_mac_lo; +++ u16 dest_mac_lo; +++ +++ u32 src_mac_hi; +++ +++ u32 ib2; +++ +++ u32 _rsv[5]; +++ +++ u32 udf_tsid; +++ struct mtk_foe_mac_info l2; +++}; +++ +++struct mtk_ipv4_tuple { +++ u32 src_ip; +++ u32 dest_ip; +++ union { +++ struct { +++ u16 dest_port; +++ u16 src_port; +++ }; +++ struct { +++ u8 protocol; +++ u8 _pad[3]; /* fill with 0xa5a5a5 */ +++ }; +++ u32 ports; +++ }; +++}; +++ +++struct mtk_foe_ipv4 { +++ struct mtk_ipv4_tuple orig; +++ +++ u32 ib2; +++ +++ struct mtk_ipv4_tuple new; +++ +++ u16 timestamp; +++ u16 _rsv0[3]; +++ +++ u32 udf_tsid; +++ +++ struct mtk_foe_mac_info l2; +++}; +++ +++struct mtk_foe_ipv4_dslite { +++ struct mtk_ipv4_tuple ip4; +++ +++ u32 tunnel_src_ip[4]; +++ u32 tunnel_dest_ip[4]; +++ +++ u8 flow_label[3]; +++ u8 priority; +++ +++ u32 udf_tsid; +++ +++ u32 ib2; +++ +++ struct mtk_foe_mac_info l2; +++}; +++ +++struct mtk_foe_ipv6 { +++ u32 src_ip[4]; +++ u32 dest_ip[4]; +++ +++ union { +++ struct { +++ u8 protocol; +++ u8 _pad[3]; /* fill with 0xa5a5a5 */ +++ }; /* 3-tuple */ +++ struct { +++ u16 dest_port; +++ u16 src_port; +++ }; /* 5-tuple */ +++ u32 ports; +++ }; +++ +++ u32 _rsv[3]; +++ +++ u32 udf; +++ +++ u32 ib2; +++ struct mtk_foe_mac_info l2; +++}; +++ +++struct mtk_foe_ipv6_6rd { +++ u32 src_ip[4]; +++ u32 dest_ip[4]; +++ u16 dest_port; +++ u16 src_port; +++ +++ u32 tunnel_src_ip; +++ u32 tunnel_dest_ip; +++ +++ u16 hdr_csum; +++ u8 dscp; +++ u8 ttl; +++ +++ u8 flag; +++ u8 pad; +++ u8 per_flow_6rd_id; +++ u8 pad2; +++ +++ u32 ib2; +++ struct mtk_foe_mac_info l2; +++}; +++ +++struct mtk_foe_entry { +++ u32 ib1; +++ +++ union { +++ struct mtk_foe_bridge bridge; +++ struct mtk_foe_ipv4 ipv4; +++ struct mtk_foe_ipv4_dslite dslite; +++ struct mtk_foe_ipv6 ipv6; +++ struct mtk_foe_ipv6_6rd ipv6_6rd; +++ u32 data[19]; +++ }; +++}; +++ +++enum { +++ MTK_PPE_CPU_REASON_TTL_EXCEEDED = 0x02, +++ MTK_PPE_CPU_REASON_OPTION_HEADER = 0x03, +++ MTK_PPE_CPU_REASON_NO_FLOW = 0x07, +++ MTK_PPE_CPU_REASON_IPV4_FRAG = 0x08, +++ MTK_PPE_CPU_REASON_IPV4_DSLITE_FRAG = 0x09, +++ MTK_PPE_CPU_REASON_IPV4_DSLITE_NO_TCP_UDP = 0x0a, +++ MTK_PPE_CPU_REASON_IPV6_6RD_NO_TCP_UDP = 0x0b, +++ MTK_PPE_CPU_REASON_TCP_FIN_SYN_RST = 0x0c, +++ MTK_PPE_CPU_REASON_UN_HIT = 0x0d, +++ MTK_PPE_CPU_REASON_HIT_UNBIND = 0x0e, +++ MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED = 0x0f, +++ MTK_PPE_CPU_REASON_HIT_BIND_TCP_FIN = 0x10, +++ MTK_PPE_CPU_REASON_HIT_TTL_1 = 0x11, +++ MTK_PPE_CPU_REASON_HIT_BIND_VLAN_VIOLATION = 0x12, +++ MTK_PPE_CPU_REASON_KEEPALIVE_UC_OLD_HDR = 0x13, +++ MTK_PPE_CPU_REASON_KEEPALIVE_MC_NEW_HDR = 0x14, +++ MTK_PPE_CPU_REASON_KEEPALIVE_DUP_OLD_HDR = 0x15, +++ MTK_PPE_CPU_REASON_HIT_BIND_FORCE_CPU = 0x16, +++ MTK_PPE_CPU_REASON_TUNNEL_OPTION_HEADER = 0x17, +++ MTK_PPE_CPU_REASON_MULTICAST_TO_CPU = 0x18, +++ MTK_PPE_CPU_REASON_MULTICAST_TO_GMAC1_CPU = 0x19, +++ MTK_PPE_CPU_REASON_HIT_PRE_BIND = 0x1a, +++ MTK_PPE_CPU_REASON_PACKET_SAMPLING = 0x1b, +++ MTK_PPE_CPU_REASON_EXCEED_MTU = 0x1c, +++ MTK_PPE_CPU_REASON_PPE_BYPASS = 0x1e, +++ MTK_PPE_CPU_REASON_INVALID = 0x1f, +++}; +++ +++struct mtk_ppe { +++ struct device *dev; +++ void __iomem *base; +++ int version; +++ +++ struct mtk_foe_entry *foe_table; +++ dma_addr_t foe_phys; +++ +++ void *acct_table; +++}; +++ +++int mtk_ppe_init(struct mtk_ppe *ppe, struct device *dev, void __iomem *base, +++ int version); +++int mtk_ppe_start(struct mtk_ppe *ppe); +++int mtk_ppe_stop(struct mtk_ppe *ppe); +++ +++static inline void +++mtk_foe_entry_clear(struct mtk_ppe *ppe, u16 hash) +++{ +++ ppe->foe_table[hash].ib1 = 0; +++ dma_wmb(); +++} +++ +++static inline int +++mtk_foe_entry_timestamp(struct mtk_ppe *ppe, u16 hash) +++{ +++ u32 ib1 = READ_ONCE(ppe->foe_table[hash].ib1); +++ +++ if (FIELD_GET(MTK_FOE_IB1_STATE, ib1) != MTK_FOE_STATE_BIND) +++ return -1; +++ +++ return FIELD_GET(MTK_FOE_IB1_BIND_TIMESTAMP, ib1); +++} +++ +++int mtk_foe_entry_prepare(struct mtk_foe_entry *entry, int type, int l4proto, +++ u8 pse_port, u8 *src_mac, u8 *dest_mac); +++int mtk_foe_entry_set_pse_port(struct mtk_foe_entry *entry, u8 port); +++int mtk_foe_entry_set_ipv4_tuple(struct mtk_foe_entry *entry, bool orig, +++ __be32 src_addr, __be16 src_port, +++ __be32 dest_addr, __be16 dest_port); +++int mtk_foe_entry_set_ipv6_tuple(struct mtk_foe_entry *entry, +++ __be32 *src_addr, __be16 src_port, +++ __be32 *dest_addr, __be16 dest_port); +++int mtk_foe_entry_set_dsa(struct mtk_foe_entry *entry, int port); +++int mtk_foe_entry_set_vlan(struct mtk_foe_entry *entry, int vid); +++int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid); +++int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry, +++ u16 timestamp); +++int mtk_ppe_debugfs_init(struct mtk_ppe *ppe); +++ +++#endif ++--- /dev/null +++++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c ++@@ -0,0 +1,217 @@ +++// SPDX-License-Identifier: GPL-2.0-only +++/* Copyright (C) 2020 Felix Fietkau */ +++ +++#include +++#include +++#include "mtk_eth_soc.h" +++ +++struct mtk_flow_addr_info +++{ +++ void *src, *dest; +++ u16 *src_port, *dest_port; +++ bool ipv6; +++}; +++ +++static const char *mtk_foe_entry_state_str(int state) +++{ +++ static const char * const state_str[] = { +++ [MTK_FOE_STATE_INVALID] = "INV", +++ [MTK_FOE_STATE_UNBIND] = "UNB", +++ [MTK_FOE_STATE_BIND] = "BND", +++ [MTK_FOE_STATE_FIN] = "FIN", +++ }; +++ +++ if (state >= ARRAY_SIZE(state_str) || !state_str[state]) +++ return "UNK"; +++ +++ return state_str[state]; +++} +++ +++static const char *mtk_foe_pkt_type_str(int type) +++{ +++ static const char * const type_str[] = { +++ [MTK_PPE_PKT_TYPE_IPV4_HNAPT] = "IPv4 5T", +++ [MTK_PPE_PKT_TYPE_IPV4_ROUTE] = "IPv4 3T", +++ [MTK_PPE_PKT_TYPE_BRIDGE] = "L2", +++ [MTK_PPE_PKT_TYPE_IPV4_DSLITE] = "DS-LITE", +++ [MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T] = "IPv6 3T", +++ [MTK_PPE_PKT_TYPE_IPV6_ROUTE_5T] = "IPv6 5T", +++ [MTK_PPE_PKT_TYPE_IPV6_6RD] = "6RD", +++ }; +++ +++ if (type >= ARRAY_SIZE(type_str) || !type_str[type]) +++ return "UNKNOWN"; +++ +++ return type_str[type]; +++} +++ +++static void +++mtk_print_addr(struct seq_file *m, u32 *addr, bool ipv6) +++{ +++ u32 n_addr[4]; +++ int i; +++ +++ if (!ipv6) { +++ seq_printf(m, "%pI4h", addr); +++ return; +++ } +++ +++ for (i = 0; i < ARRAY_SIZE(n_addr); i++) +++ n_addr[i] = htonl(addr[i]); +++ seq_printf(m, "%pI6", n_addr); +++} +++ +++static void +++mtk_print_addr_info(struct seq_file *m, struct mtk_flow_addr_info *ai) +++{ +++ mtk_print_addr(m, ai->src, ai->ipv6); +++ if (ai->src_port) +++ seq_printf(m, ":%d", *ai->src_port); +++ seq_printf(m, "->"); +++ mtk_print_addr(m, ai->dest, ai->ipv6); +++ if (ai->dest_port) +++ seq_printf(m, ":%d", *ai->dest_port); +++} +++ +++static int +++mtk_ppe_debugfs_foe_show(struct seq_file *m, void *private, bool bind) +++{ +++ struct mtk_ppe *ppe = m->private; +++ int i, count; +++ +++ for (i = 0, count = 0; i < MTK_PPE_ENTRIES; i++) { +++ struct mtk_foe_entry *entry = &ppe->foe_table[i]; +++ struct mtk_foe_mac_info *l2; +++ struct mtk_flow_addr_info ai = {}; +++ unsigned char h_source[ETH_ALEN]; +++ unsigned char h_dest[ETH_ALEN]; +++ int type, state; +++ u32 ib2; +++ +++ +++ state = FIELD_GET(MTK_FOE_IB1_STATE, entry->ib1); +++ if (!state) +++ continue; +++ +++ if (bind && state != MTK_FOE_STATE_BIND) +++ continue; +++ +++ type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1); +++ seq_printf(m, "%05x %s %7s", i, +++ mtk_foe_entry_state_str(state), +++ mtk_foe_pkt_type_str(type)); +++ +++ switch (type) { +++ case MTK_PPE_PKT_TYPE_IPV4_HNAPT: +++ case MTK_PPE_PKT_TYPE_IPV4_DSLITE: +++ ai.src_port = &entry->ipv4.orig.src_port; +++ ai.dest_port = &entry->ipv4.orig.dest_port; +++ fallthrough; +++ case MTK_PPE_PKT_TYPE_IPV4_ROUTE: +++ ai.src = &entry->ipv4.orig.src_ip; +++ ai.dest = &entry->ipv4.orig.dest_ip; +++ break; +++ case MTK_PPE_PKT_TYPE_IPV6_ROUTE_5T: +++ ai.src_port = &entry->ipv6.src_port; +++ ai.dest_port = &entry->ipv6.dest_port; +++ fallthrough; +++ case MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T: +++ case MTK_PPE_PKT_TYPE_IPV6_6RD: +++ ai.src = &entry->ipv6.src_ip; +++ ai.dest = &entry->ipv6.dest_ip; +++ ai.ipv6 = true; +++ break; +++ } +++ +++ seq_printf(m, " orig="); +++ mtk_print_addr_info(m, &ai); +++ +++ switch (type) { +++ case MTK_PPE_PKT_TYPE_IPV4_HNAPT: +++ case MTK_PPE_PKT_TYPE_IPV4_DSLITE: +++ ai.src_port = &entry->ipv4.new.src_port; +++ ai.dest_port = &entry->ipv4.new.dest_port; +++ fallthrough; +++ case MTK_PPE_PKT_TYPE_IPV4_ROUTE: +++ ai.src = &entry->ipv4.new.src_ip; +++ ai.dest = &entry->ipv4.new.dest_ip; +++ seq_printf(m, " new="); +++ mtk_print_addr_info(m, &ai); +++ break; +++ } +++ +++ if (type >= MTK_PPE_PKT_TYPE_IPV4_DSLITE) { +++ l2 = &entry->ipv6.l2; +++ ib2 = entry->ipv6.ib2; +++ } else { +++ l2 = &entry->ipv4.l2; +++ ib2 = entry->ipv4.ib2; +++ } +++ +++ *((__be32 *)h_source) = htonl(l2->src_mac_hi); +++ *((__be16 *)&h_source[4]) = htons(l2->src_mac_lo); +++ *((__be32 *)h_dest) = htonl(l2->dest_mac_hi); +++ *((__be16 *)&h_dest[4]) = htons(l2->dest_mac_lo); +++ +++ seq_printf(m, " eth=%pM->%pM etype=%04x" +++ " vlan=%d,%d ib1=%08x ib2=%08x\n", +++ h_source, h_dest, ntohs(l2->etype), +++ l2->vlan1, l2->vlan2, entry->ib1, ib2); +++ } +++ +++ return 0; +++} +++ +++static int +++mtk_ppe_debugfs_foe_show_all(struct seq_file *m, void *private) +++{ +++ return mtk_ppe_debugfs_foe_show(m, private, false); +++} +++ +++static int +++mtk_ppe_debugfs_foe_show_bind(struct seq_file *m, void *private) +++{ +++ return mtk_ppe_debugfs_foe_show(m, private, true); +++} +++ +++static int +++mtk_ppe_debugfs_foe_open_all(struct inode *inode, struct file *file) +++{ +++ return single_open(file, mtk_ppe_debugfs_foe_show_all, +++ inode->i_private); +++} +++ +++static int +++mtk_ppe_debugfs_foe_open_bind(struct inode *inode, struct file *file) +++{ +++ return single_open(file, mtk_ppe_debugfs_foe_show_bind, +++ inode->i_private); +++} +++ +++int mtk_ppe_debugfs_init(struct mtk_ppe *ppe) +++{ +++ static const struct file_operations fops_all = { +++ .open = mtk_ppe_debugfs_foe_open_all, +++ .read = seq_read, +++ .llseek = seq_lseek, +++ .release = single_release, +++ }; +++ +++ static const struct file_operations fops_bind = { +++ .open = mtk_ppe_debugfs_foe_open_bind, +++ .read = seq_read, +++ .llseek = seq_lseek, +++ .release = single_release, +++ }; +++ +++ struct dentry *root; +++ +++ root = debugfs_create_dir("mtk_ppe", NULL); +++ if (!root) +++ return -ENOMEM; +++ +++ debugfs_create_file("entries", S_IRUGO, root, ppe, &fops_all); +++ debugfs_create_file("bind", S_IRUGO, root, ppe, &fops_bind); +++ +++ return 0; +++} ++--- /dev/null +++++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h ++@@ -0,0 +1,144 @@ +++// SPDX-License-Identifier: GPL-2.0-only +++/* Copyright (C) 2020 Felix Fietkau */ +++ +++#ifndef __MTK_PPE_REGS_H +++#define __MTK_PPE_REGS_H +++ +++#define MTK_PPE_GLO_CFG 0x200 +++#define MTK_PPE_GLO_CFG_EN BIT(0) +++#define MTK_PPE_GLO_CFG_TSID_EN BIT(1) +++#define MTK_PPE_GLO_CFG_IP4_L4_CS_DROP BIT(2) +++#define MTK_PPE_GLO_CFG_IP4_CS_DROP BIT(3) +++#define MTK_PPE_GLO_CFG_TTL0_DROP BIT(4) +++#define MTK_PPE_GLO_CFG_PPE_BSWAP BIT(5) +++#define MTK_PPE_GLO_CFG_PSE_HASH_OFS BIT(6) +++#define MTK_PPE_GLO_CFG_MCAST_TB_EN BIT(7) +++#define MTK_PPE_GLO_CFG_FLOW_DROP_KA BIT(8) +++#define MTK_PPE_GLO_CFG_FLOW_DROP_UPDATE BIT(9) +++#define MTK_PPE_GLO_CFG_UDP_LITE_EN BIT(10) +++#define MTK_PPE_GLO_CFG_UDP_LEN_DROP BIT(11) +++#define MTK_PPE_GLO_CFG_MCAST_ENTRIES GNEMASK(13, 12) +++#define MTK_PPE_GLO_CFG_BUSY BIT(31) +++ +++#define MTK_PPE_FLOW_CFG 0x204 +++#define MTK_PPE_FLOW_CFG_IP4_TCP_FRAG BIT(6) +++#define MTK_PPE_FLOW_CFG_IP4_UDP_FRAG BIT(7) +++#define MTK_PPE_FLOW_CFG_IP6_3T_ROUTE BIT(8) +++#define MTK_PPE_FLOW_CFG_IP6_5T_ROUTE BIT(9) +++#define MTK_PPE_FLOW_CFG_IP6_6RD BIT(10) +++#define MTK_PPE_FLOW_CFG_IP4_NAT BIT(12) +++#define MTK_PPE_FLOW_CFG_IP4_NAPT BIT(13) +++#define MTK_PPE_FLOW_CFG_IP4_DSLITE BIT(14) +++#define MTK_PPE_FLOW_CFG_L2_BRIDGE BIT(15) +++#define MTK_PPE_FLOW_CFG_IP_PROTO_BLACKLIST BIT(16) +++#define MTK_PPE_FLOW_CFG_IP4_NAT_FRAG BIT(17) +++#define MTK_PPE_FLOW_CFG_IP4_HASH_FLOW_LABEL BIT(18) +++#define MTK_PPE_FLOW_CFG_IP4_HASH_GRE_KEY BIT(19) +++#define MTK_PPE_FLOW_CFG_IP6_HASH_GRE_KEY BIT(20) +++ +++#define MTK_PPE_IP_PROTO_CHK 0x208 +++#define MTK_PPE_IP_PROTO_CHK_IPV4 GENMASK(15, 0) +++#define MTK_PPE_IP_PROTO_CHK_IPV6 GENMASK(31, 16) +++ +++#define MTK_PPE_TB_CFG 0x21c +++#define MTK_PPE_TB_CFG_ENTRY_NUM GENMASK(2, 0) +++#define MTK_PPE_TB_CFG_ENTRY_80B BIT(3) +++#define MTK_PPE_TB_CFG_SEARCH_MISS GENMASK(5, 4) +++#define MTK_PPE_TB_CFG_AGE_PREBIND BIT(6) +++#define MTK_PPE_TB_CFG_AGE_NON_L4 BIT(7) +++#define MTK_PPE_TB_CFG_AGE_UNBIND BIT(8) +++#define MTK_PPE_TB_CFG_AGE_TCP BIT(9) +++#define MTK_PPE_TB_CFG_AGE_UDP BIT(10) +++#define MTK_PPE_TB_CFG_AGE_TCP_FIN BIT(11) +++#define MTK_PPE_TB_CFG_KEEPALIVE GENMASK(13, 12) +++#define MTK_PPE_TB_CFG_HASH_MODE GENMASK(15, 14) +++#define MTK_PPE_TB_CFG_SCAN_MODE GENMASK(17, 16) +++#define MTK_PPE_TB_CFG_HASH_DEBUG GENMASK(19, 18) +++ +++enum { +++ MTK_PPE_SCAN_MODE_DISABLED, +++ MTK_PPE_SCAN_MODE_CHECK_AGE, +++ MTK_PPE_SCAN_MODE_KEEPALIVE_AGE, +++}; +++ +++enum { +++ MTK_PPE_KEEPALIVE_DISABLE, +++ MTK_PPE_KEEPALIVE_UNICAST_CPU, +++ MTK_PPE_KEEPALIVE_DUP_CPU = 3, +++}; +++ +++enum { +++ MTK_PPE_SEARCH_MISS_ACTION_DROP, +++ MTK_PPE_SEARCH_MISS_ACTION_FORWARD = 2, +++ MTK_PPE_SEARCH_MISS_ACTION_FORWARD_BUILD = 3, +++}; +++ +++#define MTK_PPE_TB_BASE 0x220 +++ +++#define MTK_PPE_TB_USED 0x224 +++#define MTK_PPE_TB_USED_NUM GENMASK(13, 0) +++ +++#define MTK_PPE_BIND_RATE 0x228 +++#define MTK_PPE_BIND_RATE_BIND GENMASK(15, 0) +++#define MTK_PPE_BIND_RATE_PREBIND GENMASK(31, 16) +++ +++#define MTK_PPE_BIND_LIMIT0 0x22c +++#define MTK_PPE_BIND_LIMIT0_QUARTER GENMASK(13, 0) +++#define MTK_PPE_BIND_LIMIT0_HALF GENMASK(29, 16) +++ +++#define MTK_PPE_BIND_LIMIT1 0x230 +++#define MTK_PPE_BIND_LIMIT1_FULL GENMASK(13, 0) +++#define MTK_PPE_BIND_LIMIT1_NON_L4 GENMASK(23, 16) +++ +++#define MTK_PPE_KEEPALIVE 0x234 +++#define MTK_PPE_KEEPALIVE_TIME GENMASK(15, 0) +++#define MTK_PPE_KEEPALIVE_TIME_TCP GENMASK(23, 16) +++#define MTK_PPE_KEEPALIVE_TIME_UDP GENMASK(31, 24) +++ +++#define MTK_PPE_UNBIND_AGE 0x238 +++#define MTK_PPE_UNBIND_AGE_MIN_PACKETS GENMASK(31, 16) +++#define MTK_PPE_UNBIND_AGE_DELTA GENMASK(7, 0) +++ +++#define MTK_PPE_BIND_AGE0 0x23c +++#define MTK_PPE_BIND_AGE0_DELTA_NON_L4 GENMASK(30, 16) +++#define MTK_PPE_BIND_AGE0_DELTA_UDP GENMASK(14, 0) +++ +++#define MTK_PPE_BIND_AGE1 0x240 +++#define MTK_PPE_BIND_AGE1_DELTA_TCP_FIN GENMASK(30, 16) +++#define MTK_PPE_BIND_AGE1_DELTA_TCP GENMASK(14, 0) +++ +++#define MTK_PPE_HASH_SEED 0x244 +++ +++#define MTK_PPE_DEFAULT_CPU_PORT 0x248 +++#define MTK_PPE_DEFAULT_CPU_PORT_MASK(_n) (GENMASK(2, 0) << ((_n) * 4)) +++ +++#define MTK_PPE_MTU_DROP 0x308 +++ +++#define MTK_PPE_VLAN_MTU0 0x30c +++#define MTK_PPE_VLAN_MTU0_NONE GENMASK(13, 0) +++#define MTK_PPE_VLAN_MTU0_1TAG GENMASK(29, 16) +++ +++#define MTK_PPE_VLAN_MTU1 0x310 +++#define MTK_PPE_VLAN_MTU1_2TAG GENMASK(13, 0) +++#define MTK_PPE_VLAN_MTU1_3TAG GENMASK(29, 16) +++ +++#define MTK_PPE_VPM_TPID 0x318 +++ +++#define MTK_PPE_CACHE_CTL 0x320 +++#define MTK_PPE_CACHE_CTL_EN BIT(0) +++#define MTK_PPE_CACHE_CTL_LOCK_CLR BIT(4) +++#define MTK_PPE_CACHE_CTL_REQ BIT(8) +++#define MTK_PPE_CACHE_CTL_CLEAR BIT(9) +++#define MTK_PPE_CACHE_CTL_CMD GENMASK(13, 12) +++ +++#define MTK_PPE_MIB_CFG 0x334 +++#define MTK_PPE_MIB_CFG_EN BIT(0) +++#define MTK_PPE_MIB_CFG_RD_CLR BIT(1) +++ +++#define MTK_PPE_MIB_TB_BASE 0x338 +++ +++#define MTK_PPE_MIB_CACHE_CTL 0x350 +++#define MTK_PPE_MIB_CACHE_CTL_EN BIT(0) +++#define MTK_PPE_MIB_CACHE_CTL_FLUSH BIT(2) +++ +++#endif +diff --git a/target/linux/generic/pending-5.10/770-16-net-ethernet-mtk_eth_soc-add-flow-offloading-support.patch b/target/linux/generic/pending-5.10/770-16-net-ethernet-mtk_eth_soc-add-flow-offloading-support.patch +new file mode 100644 +index 0000000000..fa9cbcafc8 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/770-16-net-ethernet-mtk_eth_soc-add-flow-offloading-support.patch +@@ -0,0 +1,561 @@ ++From: Felix Fietkau ++Date: Thu, 10 Dec 2020 12:19:18 +0100 ++Subject: [PATCH] net: ethernet: mtk_eth_soc: add flow offloading support ++ ++This adds support for offloading IPv4 routed flows, including SNAT/DNAT, ++one VLAN, and DSA. ++ ++Signed-off-by: Felix Fietkau ++Signed-off-by: Pablo Neira Ayuso ++--- ++ create mode 100644 drivers/net/ethernet/mediatek/mtk_ppe_offload.c ++ ++--- a/drivers/net/ethernet/mediatek/Makefile +++++ b/drivers/net/ethernet/mediatek/Makefile ++@@ -4,5 +4,5 @@ ++ # ++ ++ obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o ++-mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o +++mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o ++ obj-$(CONFIG_NET_MEDIATEK_STAR_EMAC) += mtk_star_emac.o ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++@@ -2896,6 +2896,7 @@ static const struct net_device_ops mtk_n ++ #ifdef CONFIG_NET_POLL_CONTROLLER ++ .ndo_poll_controller = mtk_poll_controller, ++ #endif +++ .ndo_setup_tc = mtk_eth_setup_tc, ++ }; ++ ++ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np) ++@@ -3161,6 +3162,10 @@ static int mtk_probe(struct platform_dev ++ eth->base + MTK_ETH_PPE_BASE, 2); ++ if (err) ++ goto err_free_dev; +++ +++ err = mtk_eth_offload_init(eth); +++ if (err) +++ goto err_free_dev; ++ } ++ ++ for (i = 0; i < MTK_MAX_DEVS; i++) { ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++@@ -16,6 +16,7 @@ ++ #include ++ #include ++ #include +++#include ++ #include "mtk_ppe.h" ++ ++ #define MTK_QDMA_PAGE_SIZE 2048 ++@@ -41,7 +42,8 @@ ++ NETIF_F_HW_VLAN_CTAG_RX | \ ++ NETIF_F_SG | NETIF_F_TSO | \ ++ NETIF_F_TSO6 | \ ++- NETIF_F_IPV6_CSUM) +++ NETIF_F_IPV6_CSUM |\ +++ NETIF_F_HW_TC) ++ #define MTK_HW_FEATURES_MT7628 (NETIF_F_SG | NETIF_F_RXCSUM) ++ #define NEXT_DESP_IDX(X, Y) (((X) + 1) & ((Y) - 1)) ++ ++@@ -929,6 +931,7 @@ struct mtk_eth { ++ int ip_align; ++ ++ struct mtk_ppe ppe; +++ struct rhashtable flow_table; ++ }; ++ ++ /* struct mtk_mac - the structure that holds the info about the MACs of the ++@@ -973,4 +976,9 @@ int mtk_gmac_sgmii_path_setup(struct mtk ++ int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id); ++ int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id); ++ +++int mtk_eth_offload_init(struct mtk_eth *eth); +++int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type, +++ void *type_data); +++ +++ ++ #endif /* MTK_ETH_H */ ++--- /dev/null +++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c ++@@ -0,0 +1,478 @@ +++// SPDX-License-Identifier: GPL-2.0-only +++/* +++ * Copyright (C) 2020 Felix Fietkau +++ */ +++ +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include "mtk_eth_soc.h" +++ +++struct mtk_flow_data { +++ struct ethhdr eth; +++ +++ union { +++ struct { +++ __be32 src_addr; +++ __be32 dst_addr; +++ } v4; +++ }; +++ +++ __be16 src_port; +++ __be16 dst_port; +++ +++ struct { +++ u16 id; +++ __be16 proto; +++ u8 num; +++ } vlan; +++}; +++ +++struct mtk_flow_entry { +++ struct rhash_head node; +++ unsigned long cookie; +++ u16 hash; +++}; +++ +++static const struct rhashtable_params mtk_flow_ht_params = { +++ .head_offset = offsetof(struct mtk_flow_entry, node), +++ .head_offset = offsetof(struct mtk_flow_entry, cookie), +++ .key_len = sizeof(unsigned long), +++ .automatic_shrinking = true, +++}; +++ +++static u32 +++mtk_eth_timestamp(struct mtk_eth *eth) +++{ +++ return mtk_r32(eth, 0x0010) & MTK_FOE_IB1_BIND_TIMESTAMP; +++} +++ +++static int +++mtk_flow_set_ipv4_addr(struct mtk_foe_entry *foe, struct mtk_flow_data *data, +++ bool egress) +++{ +++ return mtk_foe_entry_set_ipv4_tuple(foe, egress, +++ data->v4.src_addr, data->src_port, +++ data->v4.dst_addr, data->dst_port); +++} +++ +++static void +++mtk_flow_offload_mangle_eth(const struct flow_action_entry *act, void *eth) +++{ +++ void *dest = eth + act->mangle.offset; +++ const void *src = &act->mangle.val; +++ +++ if (act->mangle.offset > 8) +++ return; +++ +++ if (act->mangle.mask == 0xffff) { +++ src += 2; +++ dest += 2; +++ } +++ +++ memcpy(dest, src, act->mangle.mask ? 2 : 4); +++} +++ +++ +++static int +++mtk_flow_mangle_ports(const struct flow_action_entry *act, +++ struct mtk_flow_data *data) +++{ +++ u32 val = ntohl(act->mangle.val); +++ +++ switch (act->mangle.offset) { +++ case 0: +++ if (act->mangle.mask == ~htonl(0xffff)) +++ data->dst_port = cpu_to_be16(val); +++ else +++ data->src_port = cpu_to_be16(val >> 16); +++ break; +++ case 2: +++ data->dst_port = cpu_to_be16(val); +++ break; +++ default: +++ return -EINVAL; +++ } +++ +++ return 0; +++} +++ +++static int +++mtk_flow_mangle_ipv4(const struct flow_action_entry *act, +++ struct mtk_flow_data *data) +++{ +++ __be32 *dest; +++ +++ switch (act->mangle.offset) { +++ case offsetof(struct iphdr, saddr): +++ dest = &data->v4.src_addr; +++ break; +++ case offsetof(struct iphdr, daddr): +++ dest = &data->v4.dst_addr; +++ break; +++ default: +++ return -EINVAL; +++ } +++ +++ memcpy(dest, &act->mangle.val, sizeof(u32)); +++ +++ return 0; +++} +++ +++static int +++mtk_flow_get_dsa_port(struct net_device **dev) +++{ +++#if IS_ENABLED(CONFIG_NET_DSA) +++ struct dsa_port *dp; +++ +++ dp = dsa_port_from_netdev(*dev); +++ if (IS_ERR(dp)) +++ return -ENODEV; +++ +++ if (!dp->cpu_dp) +++ return -ENODEV; +++ +++ if (!dp->cpu_dp->tag_ops) +++ return -ENODEV; +++ +++ if (dp->cpu_dp->tag_ops->proto != DSA_TAG_PROTO_MTK) +++ return -ENODEV; +++ +++ *dev = dp->cpu_dp->master; +++ +++ return dp->index; +++#else +++ return -ENODEV; +++#endif +++} +++ +++static int +++mtk_flow_set_output_device(struct mtk_eth *eth, struct mtk_foe_entry *foe, +++ struct net_device *dev) +++{ +++ int pse_port, dsa_port; +++ +++ dsa_port = mtk_flow_get_dsa_port(&dev); +++ if (dsa_port >= 0) +++ mtk_foe_entry_set_dsa(foe, dsa_port); +++ +++ if (dev == eth->netdev[0]) +++ pse_port = 1; +++ else if (dev == eth->netdev[1]) +++ pse_port = 2; +++ else +++ return -EOPNOTSUPP; +++ +++ mtk_foe_entry_set_pse_port(foe, pse_port); +++ +++ return 0; +++} +++ +++static int +++mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f) +++{ +++ struct flow_rule *rule = flow_cls_offload_flow_rule(f); +++ struct flow_action_entry *act; +++ struct mtk_flow_data data = {}; +++ struct mtk_foe_entry foe; +++ struct net_device *odev = NULL; +++ struct mtk_flow_entry *entry; +++ int offload_type = 0; +++ u16 addr_type = 0; +++ u32 timestamp; +++ u8 l4proto = 0; +++ int err = 0; +++ int hash; +++ int i; +++ +++ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_META)) { +++ struct flow_match_meta match; +++ +++ flow_rule_match_meta(rule, &match); +++ } else { +++ return -EOPNOTSUPP; +++ } +++ +++ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) { +++ struct flow_match_control match; +++ +++ flow_rule_match_control(rule, &match); +++ addr_type = match.key->addr_type; +++ } else { +++ return -EOPNOTSUPP; +++ } +++ +++ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) { +++ struct flow_match_basic match; +++ +++ flow_rule_match_basic(rule, &match); +++ l4proto = match.key->ip_proto; +++ } else { +++ return -EOPNOTSUPP; +++ } +++ +++ flow_action_for_each(i, act, &rule->action) { +++ switch (act->id) { +++ case FLOW_ACTION_MANGLE: +++ if (act->mangle.htype == FLOW_ACT_MANGLE_HDR_TYPE_ETH) +++ mtk_flow_offload_mangle_eth(act, &data.eth); +++ break; +++ case FLOW_ACTION_REDIRECT: +++ odev = act->dev; +++ break; +++ case FLOW_ACTION_CSUM: +++ break; +++ case FLOW_ACTION_VLAN_PUSH: +++ if (data.vlan.num == 1 || +++ data.vlan.proto != ETH_P_8021Q) +++ return -EOPNOTSUPP; +++ +++ data.vlan.id = act->vlan.vid; +++ data.vlan.proto = act->vlan.proto; +++ data.vlan.num++; +++ break; +++ default: +++ return -EOPNOTSUPP; +++ } +++ } +++ +++ switch (addr_type) { +++ case FLOW_DISSECTOR_KEY_IPV4_ADDRS: +++ offload_type = MTK_PPE_PKT_TYPE_IPV4_HNAPT; +++ break; +++ default: +++ return -EOPNOTSUPP; +++ } +++ +++ if (!is_valid_ether_addr(data.eth.h_source) || +++ !is_valid_ether_addr(data.eth.h_dest)) +++ return -EINVAL; +++ +++ err = mtk_foe_entry_prepare(&foe, offload_type, l4proto, 0, +++ data.eth.h_source, +++ data.eth.h_dest); +++ if (err) +++ return err; +++ +++ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) { +++ struct flow_match_ports ports; +++ +++ flow_rule_match_ports(rule, &ports); +++ data.src_port = ports.key->src; +++ data.dst_port = ports.key->dst; +++ } else { +++ return -EOPNOTSUPP; +++ } +++ +++ if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) { +++ struct flow_match_ipv4_addrs addrs; +++ +++ flow_rule_match_ipv4_addrs(rule, &addrs); +++ +++ data.v4.src_addr = addrs.key->src; +++ data.v4.dst_addr = addrs.key->dst; +++ +++ mtk_flow_set_ipv4_addr(&foe, &data, false); +++ } +++ +++ flow_action_for_each(i, act, &rule->action) { +++ if (act->id != FLOW_ACTION_MANGLE) +++ continue; +++ +++ switch (act->mangle.htype) { +++ case FLOW_ACT_MANGLE_HDR_TYPE_TCP: +++ case FLOW_ACT_MANGLE_HDR_TYPE_UDP: +++ err = mtk_flow_mangle_ports(act, &data); +++ break; +++ case FLOW_ACT_MANGLE_HDR_TYPE_IP4: +++ err = mtk_flow_mangle_ipv4(act, &data); +++ break; +++ case FLOW_ACT_MANGLE_HDR_TYPE_ETH: +++ /* handled earlier */ +++ break; +++ default: +++ return -EOPNOTSUPP; +++ } +++ +++ if (err) +++ return err; +++ } +++ +++ if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) { +++ err = mtk_flow_set_ipv4_addr(&foe, &data, true); +++ if (err) +++ return err; +++ } +++ +++ if (data.vlan.num == 1) { +++ if (data.vlan.proto != ETH_P_8021Q) +++ return -EOPNOTSUPP; +++ +++ mtk_foe_entry_set_vlan(&foe, data.vlan.id); +++ } +++ +++ err = mtk_flow_set_output_device(eth, &foe, odev); +++ if (err) +++ return err; +++ +++ entry = kzalloc(sizeof(*entry), GFP_KERNEL); +++ if (!entry) +++ return -ENOMEM; +++ +++ entry->cookie = f->cookie; +++ timestamp = mtk_eth_timestamp(eth); +++ hash = mtk_foe_entry_commit(ð->ppe, &foe, timestamp); +++ if (hash < 0) { +++ err = hash; +++ goto free; +++ } +++ +++ entry->hash = hash; +++ err = rhashtable_insert_fast(ð->flow_table, &entry->node, +++ mtk_flow_ht_params); +++ if (err < 0) +++ goto clear_flow; +++ +++ return 0; +++clear_flow: +++ mtk_foe_entry_clear(ð->ppe, hash); +++free: +++ kfree(entry); +++ return err; +++} +++ +++static int +++mtk_flow_offload_destroy(struct mtk_eth *eth, struct flow_cls_offload *f) +++{ +++ struct mtk_flow_entry *entry; +++ +++ entry = rhashtable_lookup(ð->flow_table, &f->cookie, +++ mtk_flow_ht_params); +++ if (!entry) +++ return -ENOENT; +++ +++ mtk_foe_entry_clear(ð->ppe, entry->hash); +++ rhashtable_remove_fast(ð->flow_table, &entry->node, +++ mtk_flow_ht_params); +++ kfree(entry); +++ +++ return 0; +++} +++ +++static int +++mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f) +++{ +++ struct mtk_flow_entry *entry; +++ int timestamp; +++ u32 idle; +++ +++ entry = rhashtable_lookup(ð->flow_table, &f->cookie, +++ mtk_flow_ht_params); +++ if (!entry) +++ return -ENOENT; +++ +++ timestamp = mtk_foe_entry_timestamp(ð->ppe, entry->hash); +++ if (timestamp < 0) +++ return -ETIMEDOUT; +++ +++ idle = mtk_eth_timestamp(eth) - timestamp; +++ f->stats.lastused = jiffies - idle * HZ; +++ +++ return 0; +++} +++ +++static int +++mtk_eth_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv) +++{ +++ struct flow_cls_offload *cls = type_data; +++ struct net_device *dev = cb_priv; +++ struct mtk_mac *mac = netdev_priv(dev); +++ struct mtk_eth *eth = mac->hw; +++ +++ if (!tc_can_offload(dev)) +++ return -EOPNOTSUPP; +++ +++ if (type != TC_SETUP_CLSFLOWER) +++ return -EOPNOTSUPP; +++ +++ switch (cls->command) { +++ case FLOW_CLS_REPLACE: +++ return mtk_flow_offload_replace(eth, cls); +++ case FLOW_CLS_DESTROY: +++ return mtk_flow_offload_destroy(eth, cls); +++ case FLOW_CLS_STATS: +++ return mtk_flow_offload_stats(eth, cls); +++ default: +++ return -EOPNOTSUPP; +++ } +++ +++ return 0; +++} +++ +++static int +++mtk_eth_setup_tc_block(struct net_device *dev, struct flow_block_offload *f) +++{ +++ struct mtk_mac *mac = netdev_priv(dev); +++ struct mtk_eth *eth = mac->hw; +++ static LIST_HEAD(block_cb_list); +++ struct flow_block_cb *block_cb; +++ flow_setup_cb_t *cb; +++ +++ if (!eth->ppe.foe_table) +++ return -EOPNOTSUPP; +++ +++ if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) +++ return -EOPNOTSUPP; +++ +++ cb = mtk_eth_setup_tc_block_cb; +++ f->driver_block_list = &block_cb_list; +++ +++ switch (f->command) { +++ case FLOW_BLOCK_BIND: +++ block_cb = flow_block_cb_lookup(f->block, cb, dev); +++ if (block_cb) { +++ flow_block_cb_incref(block_cb); +++ return 0; +++ } +++ block_cb = flow_block_cb_alloc(cb, dev, dev, NULL); +++ if (IS_ERR(block_cb)) +++ return PTR_ERR(block_cb); +++ +++ flow_block_cb_add(block_cb, f); +++ list_add_tail(&block_cb->driver_list, &block_cb_list); +++ return 0; +++ case FLOW_BLOCK_UNBIND: +++ block_cb = flow_block_cb_lookup(f->block, cb, dev); +++ if (!block_cb) +++ return -ENOENT; +++ +++ if (flow_block_cb_decref(block_cb)) { +++ flow_block_cb_remove(block_cb, f); +++ list_del(&block_cb->driver_list); +++ } +++ return 0; +++ default: +++ return -EOPNOTSUPP; +++ } +++} +++ +++int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type, +++ void *type_data) +++{ +++ if (type == TC_SETUP_FT) +++ return mtk_eth_setup_tc_block(dev, type_data); +++ +++ return -EOPNOTSUPP; +++} +++ +++int mtk_eth_offload_init(struct mtk_eth *eth) +++{ +++ if (!eth->ppe.foe_table) +++ return 0; +++ +++ return rhashtable_init(ð->flow_table, &mtk_flow_ht_params); +++} +diff --git a/target/linux/generic/pending-5.10/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch b/target/linux/generic/pending-5.10/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch +new file mode 100644 +index 0000000000..cb02c71829 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch +@@ -0,0 +1,70 @@ ++From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= ++Subject: [PATCH] bcma: get SoC device struct & copy its DMA params to the ++ subdevices ++MIME-Version: 1.0 ++Content-Type: text/plain; charset=UTF-8 ++Content-Transfer-Encoding: 8bit ++ ++For bus devices to be fully usable it's required to set their DMA ++parameters. ++ ++For years it has been missing and remained unnoticed because of ++mips_dma_alloc_coherent() silently handling the empty coherent_dma_mask. ++Kernel 4.19 came with a lot of DMA changes and caused a regression on ++the bcm47xx. Starting with the commit f8c55dc6e828 ("MIPS: use generic ++dma noncoherent ops for simple noncoherent platforms") DMA coherent ++allocations just fail. Example: ++[ 1.114914] bgmac_bcma bcma0:2: Allocation of TX ring 0x200 failed ++[ 1.121215] bgmac_bcma bcma0:2: Unable to alloc memory for DMA ++[ 1.127626] bgmac_bcma: probe of bcma0:2 failed with error -12 ++[ 1.133838] bgmac_bcma: Broadcom 47xx GBit MAC driver loaded ++ ++This change fixes above regression in addition to the MIPS bcm47xx ++commit 321c46b91550 ("MIPS: BCM47XX: Setup struct device for the SoC"). ++ ++It also fixes another *old* GPIO regression caused by a parent pointing ++to the NULL: ++[ 0.157054] missing gpiochip .dev parent pointer ++[ 0.157287] bcma: bus0: Error registering GPIO driver: -22 ++introduced by the commit 74f4e0cc6108 ("bcma: switch GPIO portions to ++use GPIOLIB_IRQCHIP"). ++ ++Fixes: f8c55dc6e828 ("MIPS: use generic dma noncoherent ops for simple noncoherent platforms") ++Fixes: 74f4e0cc6108 ("bcma: switch GPIO portions to use GPIOLIB_IRQCHIP") ++Cc: linux-mips@linux-mips.org ++Cc: Christoph Hellwig ++Cc: Linus Walleij ++Signed-off-by: RafaÅ‚ MiÅ‚ecki ++--- ++ ++--- a/drivers/bcma/host_soc.c +++++ b/drivers/bcma/host_soc.c ++@@ -191,6 +191,8 @@ int __init bcma_host_soc_init(struct bcm ++ struct bcma_bus *bus = &soc->bus; ++ int err; ++ +++ bus->dev = soc->dev; +++ ++ /* Scan bus and initialize it */ ++ err = bcma_bus_early_register(bus); ++ if (err) ++--- a/drivers/bcma/main.c +++++ b/drivers/bcma/main.c ++@@ -236,12 +236,16 @@ EXPORT_SYMBOL(bcma_core_irq); ++ ++ void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core) ++ { +++ struct device *dev = &core->dev; +++ ++ core->dev.release = bcma_release_core_dev; ++ core->dev.bus = &bcma_bus_type; ++ dev_set_name(&core->dev, "bcma%d:%d", bus->num, core->core_index); ++ core->dev.parent = bus->dev; ++- if (bus->dev) +++ if (bus->dev) { ++ bcma_of_fill_device(bus->dev, core); +++ dma_coerce_mask_and_coherent(dev, bus->dev->coherent_dma_mask); +++ } ++ ++ switch (bus->hosttype) { ++ case BCMA_HOSTTYPE_PCI: +diff --git a/target/linux/generic/pending-5.10/810-pci_disable_common_quirks.patch b/target/linux/generic/pending-5.10/810-pci_disable_common_quirks.patch +new file mode 100644 +index 0000000000..7e7866add8 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/810-pci_disable_common_quirks.patch +@@ -0,0 +1,62 @@ ++From: Gabor Juhos ++Subject: debloat: add kernel config option to disabling common PCI quirks ++ ++Signed-off-by: Gabor Juhos ++--- ++ drivers/pci/Kconfig | 6 ++++++ ++ drivers/pci/quirks.c | 6 ++++++ ++ 2 files changed, 12 insertions(+) ++ ++--- a/drivers/pci/Kconfig +++++ b/drivers/pci/Kconfig ++@@ -118,6 +118,13 @@ config XEN_PCIDEV_FRONTEND ++ The PCI device frontend driver allows the kernel to import arbitrary ++ PCI devices from a PCI backend to support PCI driver domains. ++ +++config PCI_DISABLE_COMMON_QUIRKS +++ bool "PCI disable common quirks" +++ depends on PCI +++ help +++ If you don't know what to do here, say N. +++ +++ ++ config PCI_ATS ++ bool ++ ++--- a/drivers/pci/quirks.c +++++ b/drivers/pci/quirks.c ++@@ -205,6 +205,7 @@ static void quirk_mmio_always_on(struct ++ DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_ANY_ID, PCI_ANY_ID, ++ PCI_CLASS_BRIDGE_HOST, 8, quirk_mmio_always_on); ++ +++#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS ++ /* ++ * The Mellanox Tavor device gives false positive parity errors. Mark this ++ * device with a broken_parity_status to allow PCI scanning code to "skip" ++@@ -3320,6 +3321,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I ++ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f9, quirk_intel_mc_errata); ++ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata); ++ +++#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */ +++ ++ /* ++ * Ivytown NTB BAR sizes are misreported by the hardware due to an erratum. ++ * To work around this, query the size it should be configured to by the ++@@ -3345,6 +3348,8 @@ static void quirk_intel_ntb(struct pci_d ++ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e08, quirk_intel_ntb); ++ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e0d, quirk_intel_ntb); ++ +++#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS +++ ++ /* ++ * Some BIOS implementations leave the Intel GPU interrupts enabled, even ++ * though no one is handling them (e.g., if the i915 driver is never ++@@ -3383,6 +3388,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IN ++ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq); ++ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0152, disable_igfx_irq); ++ +++#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */ +++ ++ /* ++ * PCI devices which are on Intel chips can skip the 10ms delay ++ * before entering D3 mode. +diff --git a/target/linux/generic/pending-5.10/811-pci_disable_usb_common_quirks.patch b/target/linux/generic/pending-5.10/811-pci_disable_usb_common_quirks.patch +new file mode 100644 +index 0000000000..42a8397839 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/811-pci_disable_usb_common_quirks.patch +@@ -0,0 +1,115 @@ ++From: Felix Fietkau ++Subject: debloat: disable common USB quirks ++ ++Signed-off-by: Felix Fietkau ++--- ++ drivers/usb/host/pci-quirks.c | 16 ++++++++++++++++ ++ drivers/usb/host/pci-quirks.h | 18 +++++++++++++++++- ++ include/linux/usb/hcd.h | 7 +++++++ ++ 3 files changed, 40 insertions(+), 1 deletion(-) ++ ++--- a/drivers/usb/host/pci-quirks.c +++++ b/drivers/usb/host/pci-quirks.c ++@@ -128,6 +128,8 @@ struct amd_chipset_type { ++ u8 rev; ++ }; ++ +++#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS +++ ++ static struct amd_chipset_info { ++ struct pci_dev *nb_dev; ++ struct pci_dev *smbus_dev; ++@@ -633,6 +635,10 @@ bool usb_amd_pt_check_port(struct device ++ } ++ EXPORT_SYMBOL_GPL(usb_amd_pt_check_port); ++ +++#endif /* CONFIG_PCI_DISABLE_COMMON_QUIRKS */ +++ +++#if IS_ENABLED(CONFIG_USB_UHCI_HCD) +++ ++ /* ++ * Make sure the controller is completely inactive, unable to ++ * generate interrupts or do DMA. ++@@ -712,8 +718,17 @@ reset_needed: ++ uhci_reset_hc(pdev, base); ++ return 1; ++ } +++#else +++int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base) +++{ +++ return 0; +++} +++ +++#endif ++ EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc); ++ +++#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS +++ ++ static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask) ++ { ++ u16 cmd; ++@@ -1285,3 +1300,4 @@ static void quirk_usb_early_handoff(stru ++ } ++ DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, ++ PCI_CLASS_SERIAL_USB, 8, quirk_usb_early_handoff); +++#endif ++--- a/drivers/usb/host/pci-quirks.h +++++ b/drivers/usb/host/pci-quirks.h ++@@ -5,6 +5,9 @@ ++ #ifdef CONFIG_USB_PCI ++ void uhci_reset_hc(struct pci_dev *pdev, unsigned long base); ++ int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base); +++#endif /* CONFIG_USB_PCI */ +++ +++#if defined(CONFIG_USB_PCI) && !defined(CONFIG_PCI_DISABLE_COMMON_QUIRKS) ++ int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev); ++ bool usb_amd_hang_symptom_quirk(void); ++ bool usb_amd_prefetch_quirk(void); ++@@ -19,6 +22,18 @@ void sb800_prefetch(struct device *dev, ++ bool usb_amd_pt_check_port(struct device *device, int port); ++ #else ++ struct pci_dev; +++static inline int usb_amd_quirk_pll_check(void) +++{ +++ return 0; +++} +++static inline bool usb_amd_hang_symptom_quirk(void) +++{ +++ return false; +++} +++static inline bool usb_amd_prefetch_quirk(void) +++{ +++ return false; +++} ++ static inline void usb_amd_quirk_pll_disable(void) {} ++ static inline void usb_amd_quirk_pll_enable(void) {} ++ static inline void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) {} ++@@ -29,6 +44,11 @@ static inline bool usb_amd_pt_check_port ++ { ++ return false; ++ } +++static inline void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev) {} +++static inline bool usb_xhci_needs_pci_reset(struct pci_dev *pdev) +++{ +++ return false; +++} ++ #endif /* CONFIG_USB_PCI */ ++ ++ #endif /* __LINUX_USB_PCI_QUIRKS_H */ ++--- a/include/linux/usb/hcd.h +++++ b/include/linux/usb/hcd.h ++@@ -484,7 +484,14 @@ extern int usb_hcd_pci_probe(struct pci_ ++ extern void usb_hcd_pci_remove(struct pci_dev *dev); ++ extern void usb_hcd_pci_shutdown(struct pci_dev *dev); ++ +++#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS ++ extern int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev); +++#else +++static inline int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev) +++{ +++ return 0; +++} +++#endif ++ ++ #ifdef CONFIG_PM ++ extern const struct dev_pm_ops usb_hcd_pci_pm_ops; +diff --git a/target/linux/generic/pending-5.10/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch b/target/linux/generic/pending-5.10/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch +new file mode 100644 +index 0000000000..33eb34c913 +--- /dev/null ++++ b/target/linux/generic/pending-5.10/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch +@@ -0,0 +1,26 @@ ++From d9c8bc8c1408f3e8529db6e4e04017b4c579c342 Mon Sep 17 00:00:00 2001 ++From: Pawel Dembicki ++Date: Sun, 18 Feb 2018 17:08:04 +0100 ++Subject: [PATCH] w1: gpio: fix problem with platfom data in w1-gpio ++ ++In devices, where fdt is used, is impossible to apply platform data ++without proper fdt node. ++ ++This patch allow to use platform data in devices with fdt. ++ ++Signed-off-by: Pawel Dembicki ++--- ++ drivers/w1/masters/w1-gpio.c | 7 +++---- ++ 1 file changed, 3 insertions(+), 4 deletions(-) ++ ++--- a/drivers/w1/masters/w1-gpio.c +++++ b/drivers/w1/masters/w1-gpio.c ++@@ -76,7 +76,7 @@ static int w1_gpio_probe(struct platform ++ enum gpiod_flags gflags = GPIOD_OUT_LOW_OPEN_DRAIN; ++ int err; ++ ++- if (of_have_populated_dt()) { +++ if (of_have_populated_dt() && !dev_get_platdata(&pdev->dev)) { ++ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); ++ if (!pdata) ++ return -ENOMEM; +diff --git a/target/linux/generic/pending-5.10/834-ledtrig-libata.patch b/target/linux/generic/pending-5.10/834-ledtrig-libata.patch +new file mode 100644 +index 0000000000..623e48085d +--- /dev/null ++++ b/target/linux/generic/pending-5.10/834-ledtrig-libata.patch +@@ -0,0 +1,149 @@ ++From: Daniel Golle ++Subject: libata: add ledtrig support ++ ++This adds a LED trigger for each ATA port indicating disk activity. ++ ++As this is needed only on specific platforms (NAS SoCs and such), ++these platforms should define ARCH_WANTS_LIBATA_LEDS if there ++are boards with LED(s) intended to indicate ATA disk activity and ++need the OS to take care of that. ++In that way, if not selected, LED trigger support not will be ++included in libata-core and both, codepaths and structures remain ++untouched. ++ ++Signed-off-by: Daniel Golle ++--- ++ drivers/ata/Kconfig | 16 ++++++++++++++++ ++ drivers/ata/libata-core.c | 41 +++++++++++++++++++++++++++++++++++++++++ ++ include/linux/libata.h | 9 +++++++++ ++ 3 files changed, 66 insertions(+) ++ ++--- a/drivers/ata/Kconfig +++++ b/drivers/ata/Kconfig ++@@ -67,6 +67,22 @@ config ATA_FORCE ++ ++ If unsure, say Y. ++ +++config ARCH_WANT_LIBATA_LEDS +++ bool +++ +++config ATA_LEDS +++ bool "support ATA port LED triggers" +++ depends on ARCH_WANT_LIBATA_LEDS +++ select NEW_LEDS +++ select LEDS_CLASS +++ select LEDS_TRIGGERS +++ default y +++ help +++ This option adds a LED trigger for each registered ATA port. +++ It is used to drive disk activity leds connected via GPIO. +++ +++ If unsure, say N. +++ ++ config ATA_ACPI ++ bool "ATA ACPI Support" ++ depends on ACPI ++--- a/drivers/ata/libata-core.c +++++ b/drivers/ata/libata-core.c ++@@ -650,6 +650,19 @@ u64 ata_tf_read_block(const struct ata_t ++ return block; ++ } ++ +++#ifdef CONFIG_ATA_LEDS +++#define LIBATA_BLINK_DELAY 20 /* ms */ +++static inline void ata_led_act(struct ata_port *ap) +++{ +++ unsigned long led_delay = LIBATA_BLINK_DELAY; +++ +++ if (unlikely(!ap->ledtrig)) +++ return; +++ +++ led_trigger_blink_oneshot(ap->ledtrig, &led_delay, &led_delay, 0); +++} +++#endif +++ ++ /** ++ * ata_build_rw_tf - Build ATA taskfile for given read/write request ++ * @tf: Target ATA taskfile ++@@ -4513,6 +4526,9 @@ struct ata_queued_cmd *ata_qc_new_init(s ++ if (tag < 0) ++ return NULL; ++ } +++#ifdef CONFIG_ATA_LEDS +++ ata_led_act(ap); +++#endif ++ ++ qc = __ata_qc_from_tag(ap, tag); ++ qc->tag = qc->hw_tag = tag; ++@@ -5291,6 +5307,9 @@ struct ata_port *ata_port_alloc(struct a ++ ap->stats.unhandled_irq = 1; ++ ap->stats.idle_irq = 1; ++ #endif +++#ifdef CONFIG_ATA_LEDS +++ ap->ledtrig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); +++#endif ++ ata_sff_port_init(ap); ++ ++ return ap; ++@@ -5326,6 +5345,12 @@ static void ata_host_release(struct kref ++ ++ kfree(ap->pmp_link); ++ kfree(ap->slave_link); +++#ifdef CONFIG_ATA_LEDS +++ if (ap->ledtrig) { +++ led_trigger_unregister(ap->ledtrig); +++ kfree(ap->ledtrig); +++ }; +++#endif ++ kfree(ap); ++ host->ports[i] = NULL; ++ } ++@@ -5732,7 +5757,23 @@ int ata_host_register(struct ata_host *h ++ host->ports[i]->print_id = atomic_inc_return(&ata_print_id); ++ host->ports[i]->local_port_no = i + 1; ++ } +++#ifdef CONFIG_ATA_LEDS +++ for (i = 0; i < host->n_ports; i++) { +++ if (unlikely(!host->ports[i]->ledtrig)) +++ continue; +++ +++ snprintf(host->ports[i]->ledtrig_name, +++ sizeof(host->ports[i]->ledtrig_name), "ata%u", +++ host->ports[i]->print_id); ++ +++ host->ports[i]->ledtrig->name = host->ports[i]->ledtrig_name; +++ +++ if (led_trigger_register(host->ports[i]->ledtrig)) { +++ kfree(host->ports[i]->ledtrig); +++ host->ports[i]->ledtrig = NULL; +++ } +++ } +++#endif ++ /* Create associated sysfs transport objects */ ++ for (i = 0; i < host->n_ports; i++) { ++ rc = ata_tport_add(host->dev,host->ports[i]); ++--- a/include/linux/libata.h +++++ b/include/linux/libata.h ++@@ -23,6 +23,9 @@ ++ #include ++ #include ++ #include +++#ifdef CONFIG_ATA_LEDS +++#include +++#endif ++ ++ /* ++ * Define if arch has non-standard setup. This is a _PCI_ standard ++@@ -882,6 +885,12 @@ struct ata_port { ++ #ifdef CONFIG_ATA_ACPI ++ struct ata_acpi_gtm __acpi_init_gtm; /* use ata_acpi_init_gtm() */ ++ #endif +++ +++#ifdef CONFIG_ATA_LEDS +++ struct led_trigger *ledtrig; +++ char ledtrig_name[8]; +++#endif +++ ++ /* owned by EH */ ++ u8 sector_buf[ATA_SECT_SIZE] ____cacheline_aligned; ++ }; +diff --git a/target/linux/generic/pending-5.10/920-mangle_bootargs.patch b/target/linux/generic/pending-5.10/920-mangle_bootargs.patch +new file mode 100644 +index 0000000000..14fdef31fd +--- /dev/null ++++ b/target/linux/generic/pending-5.10/920-mangle_bootargs.patch +@@ -0,0 +1,71 @@ ++From: Imre Kaloz ++Subject: init: add CONFIG_MANGLE_BOOTARGS and disable it by default ++ ++Enabling this option renames the bootloader supplied root= ++and rootfstype= variables, which might have to be know but ++would break the automatisms OpenWrt uses. ++ ++Signed-off-by: Imre Kaloz ++--- ++ init/Kconfig | 9 +++++++++ ++ init/main.c | 24 ++++++++++++++++++++++++ ++ 2 files changed, 33 insertions(+) ++ ++--- a/init/Kconfig +++++ b/init/Kconfig ++@@ -1780,6 +1780,15 @@ config EMBEDDED ++ an embedded system so certain expert options are available ++ for configuration. ++ +++config MANGLE_BOOTARGS +++ bool "Rename offending bootargs" +++ depends on EXPERT +++ help +++ Sometimes the bootloader passed bogus root= and rootfstype= +++ parameters to the kernel, and while you want to ignore them, +++ you need to know the values f.e. to support dual firmware +++ layouts on the flash. +++ ++ config HAVE_PERF_EVENTS ++ bool ++ help ++--- a/init/main.c +++++ b/init/main.c ++@@ -607,6 +607,29 @@ static inline void setup_nr_cpu_ids(void ++ static inline void smp_prepare_cpus(unsigned int maxcpus) { } ++ #endif ++ +++#ifdef CONFIG_MANGLE_BOOTARGS +++static void __init mangle_bootargs(char *command_line) +++{ +++ char *rootdev; +++ char *rootfs; +++ +++ rootdev = strstr(command_line, "root=/dev/mtdblock"); +++ +++ if (rootdev) +++ strncpy(rootdev, "mangled_rootblock=", 18); +++ +++ rootfs = strstr(command_line, "rootfstype"); +++ +++ if (rootfs) +++ strncpy(rootfs, "mangled_fs", 10); +++ +++} +++#else +++static void __init mangle_bootargs(char *command_line) +++{ +++} +++#endif +++ ++ /* ++ * We need to store the untouched command line for future reference. ++ * We also need to store the touched command line since the parameter ++@@ -868,6 +891,7 @@ asmlinkage __visible void __init __no_sa ++ pr_notice("%s", linux_banner); ++ early_security_init(); ++ setup_arch(&command_line); +++ mangle_bootargs(command_line); ++ setup_boot_config(command_line); ++ setup_command_line(command_line); ++ setup_nr_cpu_ids(); +-- +2.25.1 + diff --git a/backports/0003-generic-ar8216-fix-kernel-5.10-compile-error.patch b/backports/0003-generic-ar8216-fix-kernel-5.10-compile-error.patch new file mode 100644 index 000000000..f9f94bad5 --- /dev/null +++ b/backports/0003-generic-ar8216-fix-kernel-5.10-compile-error.patch @@ -0,0 +1,41 @@ +From cc135eeb1b77fc084e4154d25e13e42b7a2d9150 Mon Sep 17 00:00:00 2001 +From: David Bauer +Date: Tue, 16 Feb 2021 22:51:18 +0100 +Subject: [PATCH 03/22] generic: ar8216: fix kernel 5.10 compile error + +Signed-off-by: David Bauer +--- + target/linux/generic/files/drivers/net/phy/ar8216.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c +index acfa0ebecd..d48a415d50 100644 +--- a/target/linux/generic/files/drivers/net/phy/ar8216.c ++++ b/target/linux/generic/files/drivers/net/phy/ar8216.c +@@ -891,7 +891,11 @@ ar8216_phy_write(struct ar8xxx_priv *priv, int addr, int regnum, u16 val) + static int + ar8229_hw_init(struct ar8xxx_priv *priv) + { ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) ++ phy_interface_t phy_if_mode; ++#else + int phy_if_mode; ++#endif + + if (priv->initialized) + return 0; +@@ -899,7 +903,11 @@ ar8229_hw_init(struct ar8xxx_priv *priv) + ar8xxx_write(priv, AR8216_REG_CTRL, AR8216_CTRL_RESET); + ar8xxx_reg_wait(priv, AR8216_REG_CTRL, AR8216_CTRL_RESET, 0, 1000); + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) ++ of_get_phy_mode(priv->pdev->of_node, &phy_if_mode); ++#else + phy_if_mode = of_get_phy_mode(priv->pdev->of_node); ++#endif + + if (phy_if_mode == PHY_INTERFACE_MODE_GMII) { + ar8xxx_write(priv, AR8229_REG_OPER_MODE0, +-- +2.25.1 + diff --git a/backports/0004-generic-ar8216-update-version-switch-for-of_get_phy_.patch b/backports/0004-generic-ar8216-update-version-switch-for-of_get_phy_.patch new file mode 100644 index 000000000..26e1c37f2 --- /dev/null +++ b/backports/0004-generic-ar8216-update-version-switch-for-of_get_phy_.patch @@ -0,0 +1,45 @@ +From e1053344ae44ac022e1e8262169d7194442d78a6 Mon Sep 17 00:00:00 2001 +From: Adrian Schmutzler +Date: Tue, 16 Feb 2021 22:56:06 +0100 +Subject: [PATCH 04/22] generic: ar8216: update version switch for + of_get_phy_mode fix + +Kernel has changed the of_get_phy_mode API in commit 0c65b2b90d13 +("net: of_get_phy_mode: Change API to solve int/unit warnings"). + +This is already included in kernel 5.5, so fix the version switch +(though this will not actually matter for the versions we support). + +Similar driver adjustments to account for the API change will +probably be necessary to various other local drivers. + +Signed-off-by: Adrian Schmutzler +--- + target/linux/generic/files/drivers/net/phy/ar8216.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c +index d48a415d50..ef0fc54949 100644 +--- a/target/linux/generic/files/drivers/net/phy/ar8216.c ++++ b/target/linux/generic/files/drivers/net/phy/ar8216.c +@@ -891,7 +891,7 @@ ar8216_phy_write(struct ar8xxx_priv *priv, int addr, int regnum, u16 val) + static int + ar8229_hw_init(struct ar8xxx_priv *priv) + { +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0) + phy_interface_t phy_if_mode; + #else + int phy_if_mode; +@@ -903,7 +903,7 @@ ar8229_hw_init(struct ar8xxx_priv *priv) + ar8xxx_write(priv, AR8216_REG_CTRL, AR8216_CTRL_RESET); + ar8xxx_reg_wait(priv, AR8216_REG_CTRL, AR8216_CTRL_RESET, 0, 1000); + +-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0) + of_get_phy_mode(priv->pdev->of_node, &phy_if_mode); + #else + phy_if_mode = of_get_phy_mode(priv->pdev->of_node); +-- +2.25.1 + diff --git a/backports/0005-kernel-5.10-fix-busy-wait-loop-in-mediatek-PPE-code.patch b/backports/0005-kernel-5.10-fix-busy-wait-loop-in-mediatek-PPE-code.patch new file mode 100644 index 000000000..f3e1cfac9 --- /dev/null +++ b/backports/0005-kernel-5.10-fix-busy-wait-loop-in-mediatek-PPE-code.patch @@ -0,0 +1,36 @@ +From c3a5b35f6971a4c6daed3674badb6718058f5ebe Mon Sep 17 00:00:00 2001 +From: Adrian Schmutzler +Date: Tue, 16 Feb 2021 23:16:00 +0100 +Subject: [PATCH 05/22] kernel: 5.10: fix busy wait loop in mediatek PPE code + +Reapply changes added to 5.4 but not copied to 5.10: +3da4acaa7bba ("kernel: fix busy wait loop in mediatek PPE code") + +The intention is for the loop to timeout if the body does not succeed. +The current logic calls time_is_before_jiffies(timeout) which is false +until after the timeout, so the loop body never executes. + +time_is_after_jiffies(timeout) will return true until timeout is less +than jiffies, which is the intended behavior here. + +Signed-off-by: Adrian Schmutzler +--- + ...5-net-ethernet-mtk_eth_soc-add-support-for-initializin.patch | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/target/linux/generic/pending-5.10/770-15-net-ethernet-mtk_eth_soc-add-support-for-initializin.patch b/target/linux/generic/pending-5.10/770-15-net-ethernet-mtk_eth_soc-add-support-for-initializin.patch +index fa4803211a..09282175b0 100644 +--- a/target/linux/generic/pending-5.10/770-15-net-ethernet-mtk_eth_soc-add-support-for-initializin.patch ++++ b/target/linux/generic/pending-5.10/770-15-net-ethernet-mtk_eth_soc-add-support-for-initializin.patch +@@ -185,7 +185,7 @@ Signed-off-by: Felix Fietkau + +{ + + unsigned long timeout = jiffies + HZ; + + +-+ while (time_is_before_jiffies(timeout)) { +++ while (time_is_after_jiffies(timeout)) { + + if (!(ppe_r32(ppe, MTK_PPE_GLO_CFG) & MTK_PPE_GLO_CFG_BUSY)) + + return 0; + + +-- +2.25.1 + diff --git a/backports/0006-kernel-hack-5.10-make-UDP-tunneling-user-selectable.patch b/backports/0006-kernel-hack-5.10-make-UDP-tunneling-user-selectable.patch new file mode 100644 index 000000000..36fd9c5f9 --- /dev/null +++ b/backports/0006-kernel-hack-5.10-make-UDP-tunneling-user-selectable.patch @@ -0,0 +1,43 @@ +From c7c270cedef77aa077f1f0dcc31964b43d573597 Mon Sep 17 00:00:00 2001 +From: Adrian Schmutzler +Date: Tue, 16 Feb 2021 23:25:00 +0100 +Subject: [PATCH 06/22] kernel: hack-5.10: make UDP tunneling user-selectable + +This applies another patch from 5.4 to 5.10 as well: +de09355f74c3 ("kernel/hack-5.4: make UDP tunneling user-selectable") + +UDP tunneling support isn't user-selectable, but it's required by WireGuard +which is, for the time being, an out-of-tree module. We currently work around +this issue by selecting an unrelated module which depends on UDP tunnelling +(VXLAN). This is inconvenient, as it implies this unrelated module needs to be +built-in when doing a monolithic build. + +Fix this inconvenience by making UDP tunneling user-selectable in the kernel +configuration. + +Signed-off-by: Adrian Schmutzler +--- + .../generic/hack-5.10/249-udp-tunnel-selection.patch | 11 +++++++++++ + 1 file changed, 11 insertions(+) + create mode 100644 target/linux/generic/hack-5.10/249-udp-tunnel-selection.patch + +diff --git a/target/linux/generic/hack-5.10/249-udp-tunnel-selection.patch b/target/linux/generic/hack-5.10/249-udp-tunnel-selection.patch +new file mode 100644 +index 0000000000..2c74298dfe +--- /dev/null ++++ b/target/linux/generic/hack-5.10/249-udp-tunnel-selection.patch +@@ -0,0 +1,11 @@ ++--- a/net/ipv4/Kconfig +++++ b/net/ipv4/Kconfig ++@@ -315,7 +315,7 @@ config NET_IPVTI ++ on top. ++ ++ config NET_UDP_TUNNEL ++- tristate +++ tristate "IP: UDP tunneling support" ++ select NET_IP_TUNNEL ++ default n ++ +-- +2.25.1 + diff --git a/backports/0007-kernel-5.10-add-missing-partitions-doc-syntax-commit.patch b/backports/0007-kernel-5.10-add-missing-partitions-doc-syntax-commit.patch new file mode 100644 index 000000000..4ea84201f --- /dev/null +++ b/backports/0007-kernel-5.10-add-missing-partitions-doc-syntax-commit.patch @@ -0,0 +1,347 @@ +From 56c65b4ffa04a202b777e8119aaa8069264d7789 Mon Sep 17 00:00:00 2001 +From: Adrian Schmutzler +Date: Tue, 16 Feb 2021 23:31:40 +0100 +Subject: [PATCH 07/22] kernel: 5.10: add missing partitions doc syntax commit + +This patch has been added to 5.4, but not been copied to 5.10: +7495acb55573 ("kernel: backport mtd commit converting partitions doc syntax") + +Signed-off-by: Adrian Schmutzler +--- + ...convert-fixed-partitions-to-the-json.patch | 324 ++++++++++++++++++ + 1 file changed, 324 insertions(+) + create mode 100644 target/linux/generic/backport-5.10/401-v5.11-dt-bindings-mtd-convert-fixed-partitions-to-the-json.patch + +diff --git a/target/linux/generic/backport-5.10/401-v5.11-dt-bindings-mtd-convert-fixed-partitions-to-the-json.patch b/target/linux/generic/backport-5.10/401-v5.11-dt-bindings-mtd-convert-fixed-partitions-to-the-json.patch +new file mode 100644 +index 0000000000..8aded43526 +--- /dev/null ++++ b/target/linux/generic/backport-5.10/401-v5.11-dt-bindings-mtd-convert-fixed-partitions-to-the-json.patch +@@ -0,0 +1,324 @@ ++From 04e9ab75267489224364fa510a88ada83e11c325 Mon Sep 17 00:00:00 2001 ++From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= ++Date: Thu, 10 Dec 2020 18:23:52 +0100 ++Subject: [PATCH] dt-bindings: mtd: convert "fixed-partitions" to the ++ json-schema ++MIME-Version: 1.0 ++Content-Type: text/plain; charset=UTF-8 ++Content-Transfer-Encoding: 8bit ++ ++This standardizes its documentation, allows validating with Makefile ++checks and helps writing DTS files. ++ ++Noticeable changes: ++1. Dropped "Partitions can be represented by sub-nodes of a flash ++ device." as we also support subpartitions (don't have to be part of ++ flash device node) ++2. Dropped "to Linux" as bindings are meant to be os agnostic. ++ ++Signed-off-by: RafaÅ‚ MiÅ‚ecki ++Link: https://lore.kernel.org/r/20201210172352.31632-1-zajec5@gmail.com ++Signed-off-by: Rob Herring ++--- ++ .../devicetree/bindings/mtd/partition.txt | 131 +-------------- ++ .../mtd/partitions/fixed-partitions.yaml | 152 ++++++++++++++++++ ++ 2 files changed, 154 insertions(+), 129 deletions(-) ++ create mode 100644 Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml ++ ++--- a/Documentation/devicetree/bindings/mtd/partition.txt +++++ b/Documentation/devicetree/bindings/mtd/partition.txt ++@@ -24,137 +24,10 @@ another partitioning method. ++ Available bindings are listed in the "partitions" subdirectory. ++ ++ ++-Fixed Partitions ++-================ ++- ++-Partitions can be represented by sub-nodes of a flash device. This can be used ++-on platforms which have strong conventions about which portions of a flash are ++-used for what purposes, but which don't use an on-flash partition table such ++-as RedBoot. ++- ++-The partition table should be a subnode of the flash node and should be named ++-'partitions'. This node should have the following property: ++-- compatible : (required) must be "fixed-partitions" ++-Partitions are then defined in subnodes of the partitions node. +++Deprecated: partitions defined in flash node +++============================================ ++ ++ For backwards compatibility partitions as direct subnodes of the flash device are ++ supported. This use is discouraged. ++ NOTE: also for backwards compatibility, direct subnodes that have a compatible ++ string are not considered partitions, as they may be used for other bindings. ++- ++-#address-cells & #size-cells must both be present in the partitions subnode of the ++-flash device. There are two valid values for both: ++-<1>: for partitions that require a single 32-bit cell to represent their ++- size/address (aka the value is below 4 GiB) ++-<2>: for partitions that require two 32-bit cells to represent their ++- size/address (aka the value is 4 GiB or greater). ++- ++-Required properties: ++-- reg : The partition's offset and size within the flash ++- ++-Optional properties: ++-- label : The label / name for this partition. If omitted, the label is taken ++- from the node name (excluding the unit address). ++-- read-only : This parameter, if present, is a hint to Linux that this ++- partition should only be mounted read-only. This is usually used for flash ++- partitions containing early-boot firmware images or data which should not be ++- clobbered. ++-- lock : Do not unlock the partition at initialization time (not supported on ++- all devices) ++-- slc-mode: This parameter, if present, allows one to emulate SLC mode on a ++- partition attached to an MLC NAND thus making this partition immune to ++- paired-pages corruptions ++- ++-Examples: ++- ++- ++-flash@0 { ++- partitions { ++- compatible = "fixed-partitions"; ++- #address-cells = <1>; ++- #size-cells = <1>; ++- ++- partition@0 { ++- label = "u-boot"; ++- reg = <0x0000000 0x100000>; ++- read-only; ++- }; ++- ++- uimage@100000 { ++- reg = <0x0100000 0x200000>; ++- }; ++- }; ++-}; ++- ++-flash@1 { ++- partitions { ++- compatible = "fixed-partitions"; ++- #address-cells = <1>; ++- #size-cells = <2>; ++- ++- /* a 4 GiB partition */ ++- partition@0 { ++- label = "filesystem"; ++- reg = <0x00000000 0x1 0x00000000>; ++- }; ++- }; ++-}; ++- ++-flash@2 { ++- partitions { ++- compatible = "fixed-partitions"; ++- #address-cells = <2>; ++- #size-cells = <2>; ++- ++- /* an 8 GiB partition */ ++- partition@0 { ++- label = "filesystem #1"; ++- reg = <0x0 0x00000000 0x2 0x00000000>; ++- }; ++- ++- /* a 4 GiB partition */ ++- partition@200000000 { ++- label = "filesystem #2"; ++- reg = <0x2 0x00000000 0x1 0x00000000>; ++- }; ++- }; ++-}; ++- ++-flash@3 { ++- partitions { ++- compatible = "fixed-partitions"; ++- #address-cells = <1>; ++- #size-cells = <1>; ++- ++- partition@0 { ++- label = "bootloader"; ++- reg = <0x000000 0x100000>; ++- read-only; ++- }; ++- ++- firmware@100000 { ++- label = "firmware"; ++- reg = <0x100000 0xe00000>; ++- compatible = "brcm,trx"; ++- }; ++- ++- calibration@f00000 { ++- label = "calibration"; ++- reg = <0xf00000 0x100000>; ++- compatible = "fixed-partitions"; ++- ranges = <0 0xf00000 0x100000>; ++- #address-cells = <1>; ++- #size-cells = <1>; ++- ++- partition@0 { ++- label = "wifi0"; ++- reg = <0x000000 0x080000>; ++- }; ++- ++- partition@80000 { ++- label = "wifi1"; ++- reg = <0x080000 0x080000>; ++- }; ++- }; ++- }; ++-}; ++--- /dev/null +++++ b/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml ++@@ -0,0 +1,152 @@ +++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +++%YAML 1.2 +++--- +++$id: http://devicetree.org/schemas/mtd/partitions/fixed-partitions.yaml# +++$schema: http://devicetree.org/meta-schemas/core.yaml# +++ +++title: Fixed partitions +++ +++description: | +++ This binding can be used on platforms which have strong conventions about +++ which portions of a flash are used for what purposes, but which don't use an +++ on-flash partition table such as RedBoot. +++ +++ The partition table should be a node named "partitions". Partitions are then +++ defined as subnodes. +++ +++maintainers: +++ - RafaÅ‚ MiÅ‚ecki +++ +++properties: +++ compatible: +++ const: fixed-partitions +++ +++ "#address-cells": true +++ +++ "#size-cells": true +++ +++patternProperties: +++ "@[0-9a-f]+$": +++ description: node describing a single flash partition +++ type: object +++ +++ properties: +++ reg: +++ description: partition's offset and size within the flash +++ maxItems: 1 +++ +++ label: +++ description: The label / name for this partition. If omitted, the label +++ is taken from the node name (excluding the unit address). +++ +++ read-only: +++ description: This parameter, if present, is a hint that this partition +++ should only be mounted read-only. This is usually used for flash +++ partitions containing early-boot firmware images or data which should +++ not be clobbered. +++ type: boolean +++ +++ lock: +++ description: Do not unlock the partition at initialization time (not +++ supported on all devices) +++ type: boolean +++ +++ slc-mode: +++ description: This parameter, if present, allows one to emulate SLC mode +++ on a partition attached to an MLC NAND thus making this partition +++ immune to paired-pages corruptions +++ type: boolean +++ +++ required: +++ - reg +++ +++required: +++ - "#address-cells" +++ - "#size-cells" +++ +++additionalProperties: true +++ +++examples: +++ - | +++ partitions { +++ compatible = "fixed-partitions"; +++ #address-cells = <1>; +++ #size-cells = <1>; +++ +++ partition@0 { +++ label = "u-boot"; +++ reg = <0x0000000 0x100000>; +++ read-only; +++ }; +++ +++ uimage@100000 { +++ reg = <0x0100000 0x200000>; +++ }; +++ }; +++ - | +++ partitions { +++ compatible = "fixed-partitions"; +++ #address-cells = <1>; +++ #size-cells = <2>; +++ +++ /* a 4 GiB partition */ +++ partition@0 { +++ label = "filesystem"; +++ reg = <0x00000000 0x1 0x00000000>; +++ }; +++ }; +++ - | +++ partitions { +++ compatible = "fixed-partitions"; +++ #address-cells = <2>; +++ #size-cells = <2>; +++ +++ /* an 8 GiB partition */ +++ partition@0 { +++ label = "filesystem #1"; +++ reg = <0x0 0x00000000 0x2 0x00000000>; +++ }; +++ +++ /* a 4 GiB partition */ +++ partition@200000000 { +++ label = "filesystem #2"; +++ reg = <0x2 0x00000000 0x1 0x00000000>; +++ }; +++ }; +++ - | +++ partitions { +++ compatible = "fixed-partitions"; +++ #address-cells = <1>; +++ #size-cells = <1>; +++ +++ partition@0 { +++ label = "bootloader"; +++ reg = <0x000000 0x100000>; +++ read-only; +++ }; +++ +++ firmware@100000 { +++ compatible = "brcm,trx"; +++ label = "firmware"; +++ reg = <0x100000 0xe00000>; +++ }; +++ +++ calibration@f00000 { +++ compatible = "fixed-partitions"; +++ label = "calibration"; +++ reg = <0xf00000 0x100000>; +++ ranges = <0 0xf00000 0x100000>; +++ #address-cells = <1>; +++ #size-cells = <1>; +++ +++ partition@0 { +++ label = "wifi0"; +++ reg = <0x000000 0x080000>; +++ }; +++ +++ partition@80000 { +++ label = "wifi1"; +++ reg = <0x080000 0x080000>; +++ }; +++ }; +++ }; +-- +2.25.1 + diff --git a/backports/0008-kernel-5.10-refresh-patches.patch b/backports/0008-kernel-5.10-refresh-patches.patch new file mode 100644 index 000000000..f1bc16074 --- /dev/null +++ b/backports/0008-kernel-5.10-refresh-patches.patch @@ -0,0 +1,226 @@ +From cebbb0ffa366e356268afe15fb243682313e02fc Mon Sep 17 00:00:00 2001 +From: Adrian Schmutzler +Date: Tue, 16 Feb 2021 23:39:32 +0100 +Subject: [PATCH 08/22] kernel: 5.10: refresh patches + +Signed-off-by: Adrian Schmutzler +--- + .../generic/hack-5.10/531-debloat_lzma.patch | 33 ++++++++++--------- + ...t-command-line-parameters-from-users.patch | 10 +++--- + ...ble-add-offload-support-for-xmit-pat.patch | 15 +++++---- + ...dd-support-for-threaded-NAPI-polling.patch | 15 +++++---- + .../pending-5.10/834-ledtrig-libata.patch | 4 +-- + 5 files changed, 41 insertions(+), 36 deletions(-) + +diff --git a/target/linux/generic/hack-5.10/531-debloat_lzma.patch b/target/linux/generic/hack-5.10/531-debloat_lzma.patch +index 0854872ffa..2f70eee3e9 100644 +--- a/target/linux/generic/hack-5.10/531-debloat_lzma.patch ++++ b/target/linux/generic/hack-5.10/531-debloat_lzma.patch +@@ -710,26 +710,26 @@ Signed-off-by: Felix Fietkau + { + UInt32 dicSize; + Byte d; +-@@ -935,33 +883,11 @@ static SRes LzmaDec_AllocateProbs2(CLzma ++@@ -935,7 +883,7 @@ static SRes LzmaDec_AllocateProbs2(CLzma + return SZ_OK; + } + + -SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) +--{ +-- CLzmaProps propNew; +-- RINOK(LzmaProps_Decode(&propNew, props, propsSize)); +-- RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); +-- p->prop = propNew; +-- return SZ_OK; +--} +-- +--SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) + +static SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) + { + CLzmaProps propNew; +-- SizeT dicBufSize; + RINOK(LzmaProps_Decode(&propNew, props, propsSize)); +- RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); ++@@ -943,28 +891,6 @@ SRes LzmaDec_AllocateProbs(CLzmaDec *p, ++ p->prop = propNew; ++ return SZ_OK; ++ } ++- ++-SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) ++-{ ++- CLzmaProps propNew; ++- SizeT dicBufSize; ++- RINOK(LzmaProps_Decode(&propNew, props, propsSize)); ++- RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); + - dicBufSize = propNew.dicSize; + - if (p->dic == 0 || dicBufSize != p->dicBufSize) + - { +@@ -742,9 +742,12 @@ Signed-off-by: Felix Fietkau + - } + - } + - p->dicBufSize = dicBufSize; +- p->prop = propNew; +- return SZ_OK; +- } ++- p->prop = propNew; ++- return SZ_OK; ++-} ++ ++ SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ++ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, + --- a/lib/lzma/LzmaEnc.c + +++ b/lib/lzma/LzmaEnc.c + @@ -53,7 +53,7 @@ void LzmaEncProps_Init(CLzmaEncProps *p) +diff --git a/target/linux/generic/pending-5.10/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch b/target/linux/generic/pending-5.10/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch +index 5a0e44b76b..2808c95322 100644 +--- a/target/linux/generic/pending-5.10/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch ++++ b/target/linux/generic/pending-5.10/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch +@@ -267,15 +267,15 @@ Signed-off-by: Yousong Zhou + + EXPORT(kexec_argv_buf) + + .skip KEXEC_COMMAND_LINE_SIZE + + .size kexec_argv_buf, KEXEC_COMMAND_LINE_SIZE +++ +++kexec_argv: +++ EXPORT(kexec_argv) +++ .skip KEXEC_ARGV_SIZE +++ .size kexec_argv, KEXEC_ARGV_SIZE + + -relocate_new_kernel_size: + - EXPORT(relocate_new_kernel_size) + - PTR relocate_new_kernel_end - relocate_new_kernel + - .size relocate_new_kernel_size, PTRSIZE +-+kexec_argv: +-+ EXPORT(kexec_argv) +-+ .skip KEXEC_ARGV_SIZE +-+ .size kexec_argv, KEXEC_ARGV_SIZE +-+ + +kexec_relocate_new_kernel_end: + + EXPORT(kexec_relocate_new_kernel_end) +diff --git a/target/linux/generic/pending-5.10/640-11-netfilter-flowtable-add-offload-support-for-xmit-pat.patch b/target/linux/generic/pending-5.10/640-11-netfilter-flowtable-add-offload-support-for-xmit-pat.patch +index 5e3c7e031a..508dc90e14 100644 +--- a/target/linux/generic/pending-5.10/640-11-netfilter-flowtable-add-offload-support-for-xmit-pat.patch ++++ b/target/linux/generic/pending-5.10/640-11-netfilter-flowtable-add-offload-support-for-xmit-pat.patch +@@ -85,12 +85,14 @@ tag to the driver. + - n = dst_neigh_lookup(dst_cache, daddr); + - if (!n) + - return -ENOENT; +-+ this_tuple = &flow->tuplehash[dir].tuple; +- ++- + - read_lock_bh(&n->lock); + - nud_state = n->nud_state; + - ether_addr_copy(ha, n->ha); + - read_unlock_bh(&n->lock); +++ this_tuple = &flow->tuplehash[dir].tuple; ++ ++- if (!(nud_state & NUD_VALID)) { + + switch (this_tuple->xmit_type) { + + case FLOW_OFFLOAD_XMIT_DIRECT: + + ether_addr_copy(ha, this_tuple->out.h_dest); +@@ -102,8 +104,7 @@ tag to the driver. + + n = dst_neigh_lookup(dst_cache, daddr); + + if (!n) + + return -ENOENT; +- +-- if (!(nud_state & NUD_VALID)) { +++ + + read_lock_bh(&n->lock); + + nud_state = n->nud_state; + + ether_addr_copy(ha, n->ha); +@@ -143,8 +144,7 @@ tag to the driver. + + struct flow_action_entry *entry; + + struct net_device *dev; + + int ifindex; +- +-- rt = (struct rtable *)flow->tuplehash[dir].tuple.dst_cache; +++ + + this_tuple = &flow->tuplehash[dir].tuple; + + switch (this_tuple->xmit_type) { + + case FLOW_OFFLOAD_XMIT_DIRECT: +@@ -158,7 +158,8 @@ tag to the driver. + + default: + + return; + + } +-+ ++ ++- rt = (struct rtable *)flow->tuplehash[dir].tuple.dst_cache; + + dev = dev_get_by_index(net, ifindex); + + if (!dev) + + return; +diff --git a/target/linux/generic/pending-5.10/690-net-add-support-for-threaded-NAPI-polling.patch b/target/linux/generic/pending-5.10/690-net-add-support-for-threaded-NAPI-polling.patch +index 79b7832f2a..2979934926 100644 +--- a/target/linux/generic/pending-5.10/690-net-add-support-for-threaded-NAPI-polling.patch ++++ b/target/linux/generic/pending-5.10/690-net-add-support-for-threaded-NAPI-polling.patch +@@ -214,7 +214,7 @@ Signed-off-by: Felix Fietkau + napi_hash_del(napi); + list_del_rcu(&napi->dev_list); + napi_free_frags(napi); +-@@ -6788,52 +6881,18 @@ EXPORT_SYMBOL(__netif_napi_del); ++@@ -6788,53 +6881,19 @@ EXPORT_SYMBOL(__netif_napi_del); + + static int napi_poll(struct napi_struct *n, struct list_head *repoll) + { +@@ -228,7 +228,8 @@ Signed-off-by: Felix Fietkau + have = netpoll_poll_lock(n); + + - weight = n->weight; +-- +++ work = __napi_poll(n, &do_repoll); ++ + - /* This NAPI_STATE_SCHED test is for avoiding a race + - * with netpoll's poll_napi(). Only the entity which + - * obtains the lock and sees NAPI_STATE_SCHED set will +@@ -246,8 +247,8 @@ Signed-off-by: Felix Fietkau + - n->poll, work, weight); + - + - if (likely(work < weight)) +-- goto out_unlock; +-+ work = __napi_poll(n, &do_repoll); +++ if (!do_repoll) ++ goto out_unlock; + + - /* Drivers must not modify the NAPI state if they + - * consume the entire weight. In such cases this code +@@ -256,8 +257,7 @@ Signed-off-by: Felix Fietkau + - */ + - if (unlikely(napi_disable_pending(n))) { + - napi_complete(n); +-+ if (!do_repoll) +- goto out_unlock; ++- goto out_unlock; + - } + - + - if (n->gro_bitmask) { +@@ -268,9 +268,10 @@ Signed-off-by: Felix Fietkau + - } + - + - gro_normal_list(n); +- ++- + /* Some drivers may have called napi_schedule + * prior to exhausting their budget. ++ */ + @@ -11288,6 +11347,10 @@ static int __init net_dev_init(void) + sd->backlog.weight = weight_p; + } +diff --git a/target/linux/generic/pending-5.10/834-ledtrig-libata.patch b/target/linux/generic/pending-5.10/834-ledtrig-libata.patch +index 623e48085d..a52e712d8c 100644 +--- a/target/linux/generic/pending-5.10/834-ledtrig-libata.patch ++++ b/target/linux/generic/pending-5.10/834-ledtrig-libata.patch +@@ -106,11 +106,11 @@ Signed-off-by: Daniel Golle + + for (i = 0; i < host->n_ports; i++) { + + if (unlikely(!host->ports[i]->ledtrig)) + + continue; +-+ ++ + + snprintf(host->ports[i]->ledtrig_name, + + sizeof(host->ports[i]->ledtrig_name), "ata%u", + + host->ports[i]->print_id); +- +++ + + host->ports[i]->ledtrig->name = host->ports[i]->ledtrig_name; + + + + if (led_trigger_register(host->ports[i]->ledtrig)) { +-- +2.25.1 + diff --git a/backports/0009-build-fix-build-with-CONFIG_STRIP_KERNEL_EXPORTS.patch b/backports/0009-build-fix-build-with-CONFIG_STRIP_KERNEL_EXPORTS.patch new file mode 100644 index 000000000..1de1ec9ba --- /dev/null +++ b/backports/0009-build-fix-build-with-CONFIG_STRIP_KERNEL_EXPORTS.patch @@ -0,0 +1,46 @@ +From 6923e03f687b00c0394d34194364b56d04a79d8f Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Wed, 17 Feb 2021 13:49:14 +0100 +Subject: [PATCH 09/22] build: fix build with CONFIG_STRIP_KERNEL_EXPORTS + +Only use symtab.h on the final kernel link + +Signed-off-by: Felix Fietkau +--- + include/kernel-defaults.mk | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/include/kernel-defaults.mk b/include/kernel-defaults.mk +index b069c1e671..93eed54ae1 100644 +--- a/include/kernel-defaults.mk ++++ b/include/kernel-defaults.mk +@@ -3,7 +3,7 @@ + # Copyright (C) 2006-2020 OpenWrt.org + + ifdef CONFIG_STRIP_KERNEL_EXPORTS +- KERNEL_MAKEOPTS += \ ++ KERNEL_MAKEOPTS_IMAGE += \ + EXTRA_LDSFLAGS="-I$(KERNEL_BUILD_DIR) -include symtab.h" + endif + +@@ -137,7 +137,7 @@ endef + + define Kernel/CompileImage/Default + rm -f $(TARGET_DIR)/init +- +$(KERNEL_MAKE) $(if $(KERNELNAME),$(KERNELNAME),all) ++ +$(KERNEL_MAKE) $(KERNEL_MAKEOPTS_IMAGE) $(if $(KERNELNAME),$(KERNELNAME),all) + $(call Kernel/CopyImage) + endef + +@@ -147,7 +147,7 @@ define Kernel/CompileImage/Initramfs + $(CP) $(GENERIC_PLATFORM_DIR)/other-files/init $(TARGET_DIR)/init + $(if $(SOURCE_DATE_EPOCH),touch -hcd "@$(SOURCE_DATE_EPOCH)" $(TARGET_DIR)/init) + rm -rf $(KERNEL_BUILD_DIR)/linux-$(LINUX_VERSION)/usr/initramfs_data.cpio* +- +$(KERNEL_MAKE) $(if $(KERNELNAME),$(KERNELNAME),all) ++ +$(KERNEL_MAKE) $(KERNEL_MAKEOPTS_IMAGE) $(if $(KERNELNAME),$(KERNELNAME),all) + $(call Kernel/CopyImage,-initramfs) + endef + else +-- +2.25.1 + diff --git a/backports/0010-kernel-update-kernel-5.10-to-5.10.16.patch b/backports/0010-kernel-update-kernel-5.10-to-5.10.16.patch new file mode 100644 index 000000000..3bbf02762 --- /dev/null +++ b/backports/0010-kernel-update-kernel-5.10-to-5.10.16.patch @@ -0,0 +1,60 @@ +From c0484713ff059736b169496d396f722af5db31c0 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Sun, 14 Feb 2021 20:17:31 +0000 +Subject: [PATCH 10/22] kernel: update kernel 5.10 to 5.10.16 + +Compile and runtime-tested on mediatek/mt7622 + +Signed-off-by: Daniel Golle +--- + include/kernel-version.mk | 4 ++-- + .../491-ubi-auto-create-ubiblock-device-for-rootfs.patch | 2 +- + .../pending-5.10/760-net-dsa-mv88e6xxx-fix-vlan-setup.patch | 2 +- + 3 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/include/kernel-version.mk b/include/kernel-version.mk +index 035692f3e3..26f24bae42 100644 +--- a/include/kernel-version.mk ++++ b/include/kernel-version.mk +@@ -7,10 +7,10 @@ ifdef CONFIG_TESTING_KERNEL + endif + + LINUX_VERSION-5.4 = .105 +-LINUX_VERSION-5.10 = .14 ++LINUX_VERSION-5.10 = .16 + + LINUX_KERNEL_HASH-5.4.105 = 244e4cd16184285df55ec5a9501daba011aa8b85c5527ee05eab4592e70fb8b6 +-LINUX_KERNEL_HASH-5.10.14 = fa27b79f198b5be969e497ed5461860df48e0591c85e60699fc8be26837a1d2a ++LINUX_KERNEL_HASH-5.10.16 = 536fe3ea273bfcc72b3571d3b3a7ff0a5bcdc16068efd22e42c4f9d03c200a37 + + remove_uri_prefix=$(subst git://,,$(subst http://,,$(subst https://,,$(1)))) + sanitize_uri=$(call qstrip,$(subst @,_,$(subst :,_,$(subst .,_,$(subst -,_,$(subst /,_,$(1))))))) +diff --git a/target/linux/generic/pending-5.10/491-ubi-auto-create-ubiblock-device-for-rootfs.patch b/target/linux/generic/pending-5.10/491-ubi-auto-create-ubiblock-device-for-rootfs.patch +index 61fcbac92e..e5ee2c8656 100644 +--- a/target/linux/generic/pending-5.10/491-ubi-auto-create-ubiblock-device-for-rootfs.patch ++++ b/target/linux/generic/pending-5.10/491-ubi-auto-create-ubiblock-device-for-rootfs.patch +@@ -53,7 +53,7 @@ Signed-off-by: Daniel Golle + static void ubiblock_remove_all(void) + { + struct ubiblock *next; +-@@ -684,6 +722,10 @@ int __init ubiblock_init(void) ++@@ -684,6 +725,10 @@ int __init ubiblock_init(void) + */ + ubiblock_create_from_param(); + +diff --git a/target/linux/generic/pending-5.10/760-net-dsa-mv88e6xxx-fix-vlan-setup.patch b/target/linux/generic/pending-5.10/760-net-dsa-mv88e6xxx-fix-vlan-setup.patch +index e6a3d15b79..42b91fe4c3 100644 +--- a/target/linux/generic/pending-5.10/760-net-dsa-mv88e6xxx-fix-vlan-setup.patch ++++ b/target/linux/generic/pending-5.10/760-net-dsa-mv88e6xxx-fix-vlan-setup.patch +@@ -17,7 +17,7 @@ Signed-off-by: DENG Qingfang + + --- a/drivers/net/dsa/mv88e6xxx/chip.c + +++ b/drivers/net/dsa/mv88e6xxx/chip.c +-@@ -2853,6 +2853,7 @@ static int mv88e6xxx_setup(struct dsa_sw ++@@ -2857,6 +2857,7 @@ static int mv88e6xxx_setup(struct dsa_sw + + chip->ds = ds; + ds->slave_mii_bus = mv88e6xxx_default_mdio_bus(chip); +-- +2.25.1 + diff --git a/backports/0011-mediatek-implement-bad-block-management-table-suppor.patch b/backports/0011-mediatek-implement-bad-block-management-table-suppor.patch new file mode 100644 index 000000000..aef95cd69 --- /dev/null +++ b/backports/0011-mediatek-implement-bad-block-management-table-suppor.patch @@ -0,0 +1,910 @@ +From 4ff7b77727cc6c4ed02fa89ced3aaa3d9437bf22 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Thu, 9 Apr 2020 09:53:24 +0200 +Subject: [PATCH 11/22] mediatek: implement bad-block management table support + +Signed-off-by: Felix Fietkau +--- + .../mediatek/mt7622-elecom-wrc-2533gent.dts | 2 + + target/linux/mediatek/mt7622/config-5.4 | 1 + + target/linux/mediatek/mt7623/config-5.4 | 1 + + target/linux/mediatek/mt7629/config-5.4 | 1 + + .../patches-5.4/0310-mtk-bmt-support.patch | 837 ++++++++++++++++++ + 5 files changed, 842 insertions(+) + create mode 100644 target/linux/mediatek/patches-5.4/0310-mtk-bmt-support.patch + +diff --git a/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7622-elecom-wrc-2533gent.dts b/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7622-elecom-wrc-2533gent.dts +index 2ac1c6a671..3971ce0389 100644 +--- a/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7622-elecom-wrc-2533gent.dts ++++ b/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7622-elecom-wrc-2533gent.dts +@@ -514,6 +514,8 @@ + spi-max-frequency = <104000000>; + reg = <0>; + ++ mediatek,bmt-v2; ++ + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; +diff --git a/target/linux/mediatek/mt7622/config-5.4 b/target/linux/mediatek/mt7622/config-5.4 +index 1b0b1e36a6..cdb73bd7bc 100644 +--- a/target/linux/mediatek/mt7622/config-5.4 ++++ b/target/linux/mediatek/mt7622/config-5.4 +@@ -396,6 +396,7 @@ CONFIG_MT753X_GSW=y + CONFIG_MTD_NAND_CORE=y + CONFIG_MTD_NAND_ECC_SW_HAMMING=y + CONFIG_MTD_NAND_MTK=y ++CONFIG_MTD_NAND_MTK_BMT=y + CONFIG_MTD_RAW_NAND=y + CONFIG_MTD_SPI_NAND=y + CONFIG_MTD_SPI_NOR=y +diff --git a/target/linux/mediatek/mt7623/config-5.4 b/target/linux/mediatek/mt7623/config-5.4 +index dbd3055d3b..839eb71008 100644 +--- a/target/linux/mediatek/mt7623/config-5.4 ++++ b/target/linux/mediatek/mt7623/config-5.4 +@@ -332,6 +332,7 @@ CONFIG_MODULES_USE_ELF_REL=y + # CONFIG_MT753X_GSW is not set + CONFIG_MTD_BLOCK2MTD=y + CONFIG_MTD_CMDLINE_PARTS=y ++# CONFIG_MTD_NAND_MTK_BMT is not set + CONFIG_MTD_SPI_NOR=y + CONFIG_MTD_SPLIT_FIRMWARE=y + CONFIG_MTD_SPLIT_UIMAGE_FW=y +diff --git a/target/linux/mediatek/mt7629/config-5.4 b/target/linux/mediatek/mt7629/config-5.4 +index 7fe01d1748..6ecde5ced6 100644 +--- a/target/linux/mediatek/mt7629/config-5.4 ++++ b/target/linux/mediatek/mt7629/config-5.4 +@@ -240,6 +240,7 @@ CONFIG_MT753X_GSW=y + CONFIG_MTD_NAND_CORE=y + CONFIG_MTD_NAND_ECC_SW_HAMMING=y + CONFIG_MTD_NAND_MTK=y ++# CONFIG_MTD_NAND_MTK_BMT is not set + CONFIG_MTD_RAW_NAND=y + CONFIG_MTD_SPI_NAND=y + CONFIG_MTD_SPI_NOR=y +diff --git a/target/linux/mediatek/patches-5.4/0310-mtk-bmt-support.patch b/target/linux/mediatek/patches-5.4/0310-mtk-bmt-support.patch +new file mode 100644 +index 0000000000..2a23f8c3dc +--- /dev/null ++++ b/target/linux/mediatek/patches-5.4/0310-mtk-bmt-support.patch +@@ -0,0 +1,837 @@ ++--- a/drivers/mtd/nand/Kconfig +++++ b/drivers/mtd/nand/Kconfig ++@@ -5,3 +5,7 @@ config MTD_NAND_CORE ++ source "drivers/mtd/nand/onenand/Kconfig" ++ source "drivers/mtd/nand/raw/Kconfig" ++ source "drivers/mtd/nand/spi/Kconfig" +++ +++config MTD_NAND_MTK_BMT +++ bool "Support MediaTek NAND Bad-block Management Table" +++ default n ++--- a/drivers/mtd/nand/Makefile +++++ b/drivers/mtd/nand/Makefile ++@@ -2,6 +2,7 @@ ++ ++ nandcore-objs := core.o bbt.o ++ obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o +++obj-$(CONFIG_MTD_NAND_MTK_BMT) += mtk_bmt.o ++ ++ obj-y += onenand/ ++ obj-y += raw/ ++--- /dev/null +++++ b/drivers/mtd/nand/mtk_bmt.c ++@@ -0,0 +1,766 @@ +++/* +++ * Copyright (c) 2017 MediaTek Inc. +++ * Author: Xiangsheng Hou +++ * Copyright (c) 2020 Felix Fietkau +++ * +++ * This program is free software; you can redistribute it and/or modify +++ * it under the terms of the GNU General Public License version 2 as +++ * published by the Free Software Foundation. +++ * +++ * This program is distributed in the hope that it will be useful, +++ * but WITHOUT ANY WARRANTY; without even the implied warranty of +++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +++ * GNU General Public License for more details. +++ */ +++ +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++ +++#define MAIN_SIGNATURE_OFFSET 0 +++#define OOB_SIGNATURE_OFFSET 1 +++#define BBPOOL_RATIO 2 +++ +++#define BBT_LOG(fmt, ...) pr_debug("[BBT][%s|%d] "fmt"\n", __func__, __LINE__, ##__VA_ARGS__) +++ +++/* Maximum 8k blocks */ +++#define BB_TABLE_MAX 0x2000U +++#define BMT_TABLE_MAX (BB_TABLE_MAX * BBPOOL_RATIO / 100) +++#define BMT_TBL_DEF_VAL 0x0 +++ +++/* +++ * Burner Bad Block Table +++ * --------- Only support SLC Nand Chips!!!!!!!!!!! ---------- +++ */ +++ +++struct bbbt { +++ char signature[3]; +++ /* This version is used to distinguish the legacy and new algorithm */ +++#define BBMT_VERSION 2 +++ unsigned char version; +++ /* Below 2 tables will be written in SLC */ +++ u16 bb_tbl[BB_TABLE_MAX]; +++ struct bbmt { +++ u16 block; +++#define NO_MAPPED 0 +++#define NORMAL_MAPPED 1 +++#define BMT_MAPPED 2 +++ u16 mapped; +++ } bmt_tbl[BMT_TABLE_MAX]; +++}; +++ +++static struct bmt_desc { +++ struct mtd_info *mtd; +++ +++ int (*_read_oob) (struct mtd_info *mtd, loff_t from, +++ struct mtd_oob_ops *ops); +++ int (*_write_oob) (struct mtd_info *mtd, loff_t to, +++ struct mtd_oob_ops *ops); +++ const struct nand_ops *nand_ops; +++ +++ struct bbbt *bbt; +++ +++ struct dentry *debugfs_dir; +++ +++ u32 pg_size; +++ u32 blk_size; +++ u16 pg_shift; +++ u16 blk_shift; +++ /* bbt logical address */ +++ u16 pool_lba; +++ /* bbt physical address */ +++ u16 pool_pba; +++ /* Maximum count of bad blocks that the vendor guaranteed */ +++ u16 bb_max; +++ /* Total blocks of the Nand Chip */ +++ u16 total_blks; +++ /* The block(n) BMT is located at (bmt_tbl[n]) */ +++ u16 bmt_blk_idx; +++ /* How many pages needs to store 'struct bbbt' */ +++ u32 bmt_pgs; +++ +++ /* to compensate for driver level remapping */ +++ u8 oob_offset; +++} bmtd = {0}; +++ +++static unsigned char *nand_bbt_buf; +++static unsigned char *nand_data_buf; +++ +++/* -------- Unit conversions -------- */ +++static inline u32 blk_pg(u16 block) +++{ +++ return (u32)(block << (bmtd.blk_shift - bmtd.pg_shift)); +++} +++ +++/* -------- Nand operations wrapper -------- */ +++static inline int +++bbt_nand_read(u32 page, unsigned char *dat, int dat_len, +++ unsigned char *fdm, int fdm_len) +++{ +++ struct mtd_oob_ops ops = { +++ .mode = MTD_OPS_PLACE_OOB, +++ .ooboffs = bmtd.oob_offset, +++ .oobbuf = fdm, +++ .ooblen = fdm_len, +++ .datbuf = dat, +++ .len = dat_len, +++ }; +++ +++ return bmtd._read_oob(bmtd.mtd, page << bmtd.pg_shift, &ops); +++} +++ +++static inline int bbt_nand_erase(u16 block) +++{ +++ struct nand_device *nand = mtd_to_nanddev(bmtd.mtd); +++ loff_t addr = (loff_t)block << bmtd.blk_shift; +++ struct nand_pos pos; +++ +++ nanddev_offs_to_pos(nand, addr, &pos); +++ return bmtd.nand_ops->erase(nand, &pos); +++} +++ +++/* -------- Bad Blocks Management -------- */ +++static int +++read_bmt(u16 block, unsigned char *dat, unsigned char *fdm, int fdm_len) +++{ +++ u32 len = bmtd.bmt_pgs << bmtd.pg_shift; +++ +++ return bbt_nand_read(blk_pg(block), dat, len, fdm, fdm_len); +++} +++ +++static int write_bmt(u16 block, unsigned char *dat) +++{ +++ struct mtd_oob_ops ops = { +++ .mode = MTD_OPS_PLACE_OOB, +++ .ooboffs = OOB_SIGNATURE_OFFSET + bmtd.oob_offset, +++ .oobbuf = "bmt", +++ .ooblen = 3, +++ .datbuf = dat, +++ .len = bmtd.bmt_pgs << bmtd.pg_shift, +++ }; +++ loff_t addr = (loff_t)block << bmtd.blk_shift; +++ +++ return bmtd._write_oob(bmtd.mtd, addr, &ops); +++} +++ +++static u16 find_valid_block(u16 block) +++{ +++ u8 fdm[4]; +++ int ret; +++ int loop = 0; +++ +++retry: +++ if (block >= bmtd.total_blks) +++ return 0; +++ +++ ret = bbt_nand_read(blk_pg(block), nand_data_buf, bmtd.pg_size, +++ fdm, sizeof(fdm)); +++ /* Read the 1st byte of FDM to judge whether it's a bad +++ * or not +++ */ +++ if (ret || fdm[0] != 0xff) { +++ pr_info("nand: found bad block 0x%x\n", block); +++ if (loop >= bmtd.bb_max) { +++ pr_info("nand: FATAL ERR: too many bad blocks!!\n"); +++ return 0; +++ } +++ +++ loop++; +++ block++; +++ goto retry; +++ } +++ +++ return block; +++} +++ +++/* Find out all bad blocks, and fill in the mapping table */ +++static int scan_bad_blocks(struct bbbt *bbt) +++{ +++ int i; +++ u16 block = 0; +++ +++ /* First time download, the block0 MUST NOT be a bad block, +++ * this is guaranteed by vendor +++ */ +++ bbt->bb_tbl[0] = 0; +++ +++ /* +++ * Construct the mapping table of Normal data area(non-PMT/BMTPOOL) +++ * G - Good block; B - Bad block +++ * --------------------------- +++ * physical |G|G|B|G|B|B|G|G|G|G|B|G|B| +++ * --------------------------- +++ * What bb_tbl[i] looks like: +++ * physical block(i): +++ * 0 1 2 3 4 5 6 7 8 9 a b c +++ * mapped block(bb_tbl[i]): +++ * 0 1 3 6 7 8 9 b ...... +++ * ATTENTION: +++ * If new bad block ocurred(n), search bmt_tbl to find +++ * a available block(x), and fill in the bb_tbl[n] = x; +++ */ +++ for (i = 1; i < bmtd.pool_lba; i++) { +++ bbt->bb_tbl[i] = find_valid_block(bbt->bb_tbl[i - 1] + 1); +++ BBT_LOG("bb_tbl[0x%x] = 0x%x", i, bbt->bb_tbl[i]); +++ if (bbt->bb_tbl[i] == 0) +++ return -1; +++ } +++ +++ /* Physical Block start Address of BMT pool */ +++ bmtd.pool_pba = bbt->bb_tbl[i - 1] + 1; +++ if (bmtd.pool_pba >= bmtd.total_blks - 2) { +++ pr_info("nand: FATAL ERR: Too many bad blocks!!\n"); +++ return -1; +++ } +++ +++ BBT_LOG("pool_pba=0x%x", bmtd.pool_pba); +++ i = 0; +++ block = bmtd.pool_pba; +++ /* +++ * The bmt table is used for runtime bad block mapping +++ * G - Good block; B - Bad block +++ * --------------------------- +++ * physical |G|G|B|G|B|B|G|G|G|G|B|G|B| +++ * --------------------------- +++ * block: 0 1 2 3 4 5 6 7 8 9 a b c +++ * What bmt_tbl[i] looks like in initial state: +++ * i: +++ * 0 1 2 3 4 5 6 7 +++ * bmt_tbl[i].block: +++ * 0 1 3 6 7 8 9 b +++ * bmt_tbl[i].mapped: +++ * N N N N N N N B +++ * N - Not mapped(Available) +++ * M - Mapped +++ * B - BMT +++ * ATTENTION: +++ * BMT always in the last valid block in pool +++ */ +++ while ((block = find_valid_block(block)) != 0) { +++ bbt->bmt_tbl[i].block = block; +++ bbt->bmt_tbl[i].mapped = NO_MAPPED; +++ BBT_LOG("bmt_tbl[%d].block = 0x%x", i, block); +++ block++; +++ i++; +++ } +++ +++ /* i - How many available blocks in pool, which is the length of bmt_tbl[] +++ * bmtd.bmt_blk_idx - bmt_tbl[bmtd.bmt_blk_idx].block => the BMT block +++ */ +++ bmtd.bmt_blk_idx = i - 1; +++ bbt->bmt_tbl[bmtd.bmt_blk_idx].mapped = BMT_MAPPED; +++ +++ if (i < 1) { +++ pr_info("nand: FATAL ERR: no space to store BMT!!\n"); +++ return -1; +++ } +++ +++ pr_info("[BBT] %d available blocks in BMT pool\n", i); +++ +++ return 0; +++} +++ +++static bool is_valid_bmt(unsigned char *buf, unsigned char *fdm) +++{ +++ struct bbbt *bbt = (struct bbbt *)buf; +++ u8 *sig = (u8*)bbt->signature + MAIN_SIGNATURE_OFFSET; +++ +++ +++ if (memcmp(bbt->signature + MAIN_SIGNATURE_OFFSET, "BMT", 3) == 0 && +++ memcmp(fdm + OOB_SIGNATURE_OFFSET, "bmt", 3) == 0) { +++ if (bbt->version == BBMT_VERSION) +++ return true; +++ } +++ BBT_LOG("[BBT] BMT Version not match,upgrage preloader and uboot please! sig=%02x%02x%02x, fdm=%02x%02x%02x", +++ sig[0], sig[1], sig[2], +++ fdm[1], fdm[2], fdm[3]); +++ return false; +++} +++ +++static u16 get_bmt_index(struct bbmt *bmt) +++{ +++ int i = 0; +++ +++ while (bmt[i].block != BMT_TBL_DEF_VAL) { +++ if (bmt[i].mapped == BMT_MAPPED) +++ return i; +++ i++; +++ } +++ return 0; +++} +++ +++static struct bbbt *scan_bmt(u16 block) +++{ +++ u8 fdm[4]; +++ +++ if (block < bmtd.pool_lba) +++ return NULL; +++ +++ if (read_bmt(block, nand_bbt_buf, fdm, sizeof(fdm))) +++ return scan_bmt(block - 1); +++ +++ if (is_valid_bmt(nand_bbt_buf, fdm)) { +++ bmtd.bmt_blk_idx = get_bmt_index(((struct bbbt *)nand_bbt_buf)->bmt_tbl); +++ if (bmtd.bmt_blk_idx == 0) { +++ pr_info("[BBT] FATAL ERR: bmt block index is wrong!\n"); +++ return NULL; +++ } +++ pr_info("[BBT] BMT.v2 is found at 0x%x\n", block); +++ return (struct bbbt *)nand_bbt_buf; +++ } else +++ return scan_bmt(block - 1); +++} +++ +++/* Write the Burner Bad Block Table to Nand Flash +++ * n - write BMT to bmt_tbl[n] +++ */ +++static u16 upload_bmt(struct bbbt *bbt, int n) +++{ +++ u16 block; +++ +++retry: +++ if (n < 0 || bbt->bmt_tbl[n].mapped == NORMAL_MAPPED) { +++ pr_info("nand: FATAL ERR: no space to store BMT!\n"); +++ return (u16)-1; +++ } +++ +++ block = bbt->bmt_tbl[n].block; +++ BBT_LOG("n = 0x%x, block = 0x%x", n, block); +++ if (bbt_nand_erase(block)) { +++ bbt->bmt_tbl[n].block = 0; +++ /* erase failed, try the previous block: bmt_tbl[n - 1].block */ +++ n--; +++ goto retry; +++ } +++ +++ /* The signature offset is fixed set to 0, +++ * oob signature offset is fixed set to 1 +++ */ +++ memcpy(bbt->signature + MAIN_SIGNATURE_OFFSET, "BMT", 3); +++ bbt->version = BBMT_VERSION; +++ +++ if (write_bmt(block, (unsigned char *)bbt)) { +++ bbt->bmt_tbl[n].block = 0; +++ +++ /* write failed, try the previous block in bmt_tbl[n - 1] */ +++ n--; +++ goto retry; +++ } +++ +++ /* Return the current index(n) of BMT pool (bmt_tbl[n]) */ +++ return n; +++} +++ +++static u16 find_valid_block_in_pool(struct bbbt *bbt) +++{ +++ int i; +++ +++ if (bmtd.bmt_blk_idx == 0) +++ goto error; +++ +++ for (i = 0; i < bmtd.bmt_blk_idx; i++) { +++ if (bbt->bmt_tbl[i].block != 0 && bbt->bmt_tbl[i].mapped == NO_MAPPED) { +++ bbt->bmt_tbl[i].mapped = NORMAL_MAPPED; +++ return bbt->bmt_tbl[i].block; +++ } +++ } +++ +++error: +++ pr_info("nand: FATAL ERR: BMT pool is run out!\n"); +++ return 0; +++} +++ +++/* We met a bad block, mark it as bad and map it to a valid block in pool, +++ * if it's a write failure, we need to write the data to mapped block +++ */ +++static bool update_bmt(u16 block) +++{ +++ u16 mapped_blk; +++ struct bbbt *bbt; +++ +++ bbt = bmtd.bbt; +++ mapped_blk = find_valid_block_in_pool(bbt); +++ if (mapped_blk == 0) +++ return false; +++ +++ /* Map new bad block to available block in pool */ +++ bbt->bb_tbl[block] = mapped_blk; +++ bmtd.bmt_blk_idx = upload_bmt(bbt, bmtd.bmt_blk_idx); +++ +++ return true; +++} +++ +++u16 get_mapping_block_index(int block) +++{ +++ int mapping_block; +++ +++ if (block < bmtd.pool_lba) +++ mapping_block = bmtd.bbt->bb_tbl[block]; +++ else +++ mapping_block = block; +++ BBT_LOG("0x%x mapped to 0x%x", block, mapping_block); +++ +++ return mapping_block; +++} +++ +++static int +++mtk_bmt_read(struct mtd_info *mtd, loff_t from, +++ struct mtd_oob_ops *ops) +++{ +++ struct mtd_oob_ops cur_ops = *ops; +++ int retry_count = 0; +++ loff_t cur_from; +++ int ret; +++ +++ ops->retlen = 0; +++ ops->oobretlen = 0; +++ +++ while (ops->retlen < ops->len || ops->oobretlen < ops->ooblen) { +++ u32 offset = from & (bmtd.blk_size - 1); +++ u32 block = from >> bmtd.blk_shift; +++ u32 cur_block; +++ +++ cur_block = get_mapping_block_index(block); +++ cur_from = ((loff_t)cur_block << bmtd.blk_shift) + offset; +++ +++ cur_ops.oobretlen = 0; +++ cur_ops.retlen = 0; +++ cur_ops.len = min_t(u32, mtd->erasesize - offset, +++ ops->len - ops->retlen); +++ ret = bmtd._read_oob(mtd, cur_from, &cur_ops); +++ if (ret < 0) { +++ update_bmt(block); +++ if (retry_count++ < 10) +++ continue; +++ +++ return ret; +++ } +++ +++ ops->retlen += cur_ops.retlen; +++ ops->oobretlen += cur_ops.oobretlen; +++ +++ cur_ops.datbuf += cur_ops.retlen; +++ cur_ops.oobbuf += cur_ops.oobretlen; +++ cur_ops.ooblen -= cur_ops.oobretlen; +++ +++ if (!cur_ops.len) +++ cur_ops.len = mtd->erasesize - offset; +++ +++ from += cur_ops.len; +++ retry_count = 0; +++ } +++ +++ return 0; +++} +++ +++static int +++mtk_bmt_write(struct mtd_info *mtd, loff_t to, +++ struct mtd_oob_ops *ops) +++{ +++ struct mtd_oob_ops cur_ops = *ops; +++ int retry_count = 0; +++ loff_t cur_to; +++ int ret; +++ +++ ops->retlen = 0; +++ ops->oobretlen = 0; +++ +++ while (ops->retlen < ops->len || ops->oobretlen < ops->ooblen) { +++ u32 offset = to & (bmtd.blk_size - 1); +++ u32 block = to >> bmtd.blk_shift; +++ u32 cur_block; +++ +++ cur_block = get_mapping_block_index(block); +++ cur_to = ((loff_t)cur_block << bmtd.blk_shift) + offset; +++ +++ cur_ops.oobretlen = 0; +++ cur_ops.retlen = 0; +++ cur_ops.len = min_t(u32, bmtd.blk_size - offset, +++ ops->len - ops->retlen); +++ ret = bmtd._write_oob(mtd, cur_to, &cur_ops); +++ if (ret < 0) { +++ update_bmt(block); +++ if (retry_count++ < 10) +++ continue; +++ +++ return ret; +++ } +++ +++ ops->retlen += cur_ops.retlen; +++ ops->oobretlen += cur_ops.oobretlen; +++ +++ cur_ops.datbuf += cur_ops.retlen; +++ cur_ops.oobbuf += cur_ops.oobretlen; +++ cur_ops.ooblen -= cur_ops.oobretlen; +++ +++ if (!cur_ops.len) +++ cur_ops.len = mtd->erasesize - offset; +++ +++ to += cur_ops.len; +++ retry_count = 0; +++ } +++ +++ return 0; +++} +++ +++ +++ +++static int +++mtk_bmt_erase(struct nand_device *nand, const struct nand_pos *pos) +++{ +++ struct nand_pos new_pos = *pos; +++ int retry_count = 0; +++ int ret; +++ +++retry: +++ new_pos.eraseblock = get_mapping_block_index(pos->eraseblock); +++ +++ ret = bmtd.nand_ops->erase(nand, &new_pos); +++ if (ret) { +++ update_bmt(pos->eraseblock); +++ if (retry_count++ < 10) +++ goto retry; +++ } +++ +++ return ret; +++} +++ +++static bool +++mtk_bmt_isbad(struct nand_device *nand, const struct nand_pos *pos) +++{ +++ struct nand_pos new_pos = *pos; +++ int retry_count = 0; +++ bool ret; +++ +++retry: +++ new_pos.eraseblock = get_mapping_block_index(pos->eraseblock); +++ +++ ret = bmtd.nand_ops->isbad(nand, &new_pos); +++ if (ret) { +++ update_bmt(pos->eraseblock); +++ if (retry_count++ < 10) +++ goto retry; +++ } +++ +++ return ret; +++} +++ +++static int +++mtk_bmt_markbad(struct nand_device *nand, const struct nand_pos *pos) +++{ +++ struct nand_pos new_pos = *pos; +++ +++ new_pos.eraseblock = get_mapping_block_index(new_pos.eraseblock); +++ update_bmt(pos->eraseblock); +++ +++ return bmtd.nand_ops->markbad(nand, &new_pos); +++} +++ +++static void +++mtk_bmt_replace_ops(struct mtd_info *mtd) +++{ +++ static const struct nand_ops mtk_bmt_nand_ops = { +++ .erase = mtk_bmt_erase, +++ .isbad = mtk_bmt_isbad, +++ .markbad = mtk_bmt_markbad, +++ }; +++ struct nand_device *nand = mtd_to_nanddev(mtd); +++ +++ bmtd.nand_ops = nand->ops; +++ bmtd._read_oob = mtd->_read_oob; +++ bmtd._write_oob = mtd->_write_oob; +++ +++ mtd->_read_oob = mtk_bmt_read; +++ mtd->_write_oob = mtk_bmt_write; +++ nand->ops = &mtk_bmt_nand_ops; +++} +++ +++static int mtk_bmt_debug_mark_good(void *data, u64 val) +++{ +++ u32 block = val >> bmtd.blk_shift; +++ +++ bmtd.bbt->bb_tbl[block] = block; +++ bmtd.bmt_blk_idx = upload_bmt(bmtd.bbt, bmtd.bmt_blk_idx); +++ +++ return 0; +++} +++ +++static int mtk_bmt_debug_mark_bad(void *data, u64 val) +++{ +++ u32 block = val >> bmtd.blk_shift; +++ +++ update_bmt(block); +++ +++ return 0; +++} +++ +++DEFINE_DEBUGFS_ATTRIBUTE(fops_mark_good, NULL, mtk_bmt_debug_mark_good, "%llu\n"); +++DEFINE_DEBUGFS_ATTRIBUTE(fops_mark_bad, NULL, mtk_bmt_debug_mark_bad, "%llu\n"); +++ +++static void +++mtk_bmt_add_debugfs(void) +++{ +++ struct dentry *dir; +++ +++ dir = bmtd.debugfs_dir = debugfs_create_dir("mtk-bmt", NULL); +++ if (!dir) +++ return; +++ +++ debugfs_create_file_unsafe("mark_good", S_IWUSR, dir, NULL, &fops_mark_good); +++ debugfs_create_file_unsafe("mark_bad", S_IWUSR, dir, NULL, &fops_mark_bad); +++} +++ +++void mtk_bmt_detach(struct mtd_info *mtd) +++{ +++ struct nand_device *nand = mtd_to_nanddev(mtd); +++ +++ if (bmtd.mtd != mtd) +++ return; +++ +++ if (bmtd.debugfs_dir) +++ debugfs_remove_recursive(bmtd.debugfs_dir); +++ bmtd.debugfs_dir = NULL; +++ +++ kfree(nand_bbt_buf); +++ kfree(nand_data_buf); +++ +++ mtd->_read_oob = bmtd._read_oob; +++ mtd->_write_oob = bmtd._write_oob; +++ mtd->size = bmtd.total_blks << bmtd.blk_shift; +++ nand->ops = bmtd.nand_ops; +++ +++ memset(&bmtd, 0, sizeof(bmtd)); +++} +++ +++/* total_blocks - The total count of blocks that the Nand Chip has */ +++int mtk_bmt_attach(struct mtd_info *mtd) +++{ +++ struct device_node *np; +++ struct bbbt *bbt; +++ u32 bufsz; +++ u32 block; +++ u16 total_blocks, pmt_block; +++ int ret = 0; +++ u32 bmt_pool_size; +++ +++ if (bmtd.mtd) +++ return -ENOSPC; +++ +++ np = mtd_get_of_node(mtd); +++ if (!np) +++ return 0; +++ +++ if (!of_property_read_bool(np, "mediatek,bmt-v2")) +++ return 0; +++ +++ if (of_property_read_u32(np, "mediatek,bmt-pool-size", +++ &bmt_pool_size) != 0) +++ bmt_pool_size = 80; +++ +++ if (of_property_read_u8(np, "mediatek,bmt-oob-offset", +++ &bmtd.oob_offset) != 0) +++ bmtd.oob_offset = 8; +++ +++ bmtd.mtd = mtd; +++ mtk_bmt_replace_ops(mtd); +++ +++ bmtd.blk_size = mtd->erasesize; +++ bmtd.blk_shift = ffs(bmtd.blk_size) - 1; +++ bmtd.pg_size = mtd->writesize; +++ bmtd.pg_shift = ffs(bmtd.pg_size) - 1; +++ total_blocks = mtd->size >> bmtd.blk_shift; +++ pmt_block = total_blocks - bmt_pool_size - 2; +++ +++ mtd->size = pmt_block << bmtd.blk_shift; +++ +++ /* +++ * --------------------------------------- +++ * | PMT(2blks) | BMT POOL(totalblks * 2%) | +++ * --------------------------------------- +++ * ^ ^ +++ * | | +++ * pmt_block pmt_block + 2blocks(pool_lba) +++ * +++ * ATTETION!!!!!! +++ * The blocks ahead of the boundary block are stored in bb_tbl +++ * and blocks behind are stored in bmt_tbl +++ */ +++ +++ bmtd.pool_lba = (u16)(pmt_block + 2); +++ bmtd.total_blks = total_blocks; +++ bmtd.bb_max = bmtd.total_blks * BBPOOL_RATIO / 100; +++ +++ /* 3 buffers we need */ +++ bufsz = round_up(sizeof(struct bbbt), bmtd.pg_size); +++ bmtd.bmt_pgs = bufsz >> bmtd.pg_shift; +++ +++ nand_bbt_buf = kzalloc(bufsz, GFP_KERNEL); +++ nand_data_buf = kzalloc(bmtd.pg_size, GFP_KERNEL); +++ +++ if (!nand_bbt_buf || !nand_data_buf) { +++ pr_info("nand: FATAL ERR: allocate buffer failed!\n"); +++ ret = -1; +++ goto error; +++ } +++ +++ memset(nand_bbt_buf, 0xff, bufsz); +++ memset(nand_data_buf, 0xff, bmtd.pg_size); +++ +++ BBT_LOG("bbtbuf=0x%p(0x%x) dat=0x%p(0x%x)", +++ nand_bbt_buf, bufsz, nand_data_buf, bmtd.pg_size); +++ BBT_LOG("pool_lba=0x%x total_blks=0x%x bb_max=0x%x", +++ bmtd.pool_lba, bmtd.total_blks, bmtd.bb_max); +++ +++ /* Scanning start from the first page of the last block +++ * of whole flash +++ */ +++ bbt = scan_bmt(bmtd.total_blks - 1); +++ if (!bbt) { +++ /* BMT not found */ +++ if (bmtd.total_blks > BB_TABLE_MAX + BMT_TABLE_MAX) { +++ pr_info("nand: FATAL: Too many blocks, can not support!\n"); +++ ret = -1; +++ goto error; +++ } +++ +++ bbt = (struct bbbt *)nand_bbt_buf; +++ memset(bbt->bmt_tbl, BMT_TBL_DEF_VAL, sizeof(bbt->bmt_tbl)); +++ +++ if (scan_bad_blocks(bbt)) { +++ ret = -1; +++ goto error; +++ } +++ +++ /* BMT always in the last valid block in pool */ +++ bmtd.bmt_blk_idx = upload_bmt(bbt, bmtd.bmt_blk_idx); +++ block = bbt->bmt_tbl[bmtd.bmt_blk_idx].block; +++ pr_notice("[BBT] BMT.v2 is written into PBA:0x%x\n", block); +++ +++ if (bmtd.bmt_blk_idx == 0) +++ pr_info("nand: Warning: no available block in BMT pool!\n"); +++ else if (bmtd.bmt_blk_idx == (u16)-1) { +++ ret = -1; +++ goto error; +++ } +++ } +++ mtk_bmt_add_debugfs(); +++ +++ bmtd.bbt = bbt; +++ return 0; +++ +++error: +++ mtk_bmt_detach(mtd); +++ return ret; +++} +++ +++ +++MODULE_LICENSE("GPL"); +++MODULE_AUTHOR("Xiangsheng Hou , Felix Fietkau "); +++MODULE_DESCRIPTION("Bad Block mapping management v2 for MediaTek NAND Flash Driver"); +++ ++--- a/drivers/mtd/nand/spi/core.c +++++ b/drivers/mtd/nand/spi/core.c ++@@ -18,6 +18,7 @@ ++ #include ++ #include ++ #include +++#include ++ ++ static int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val) ++ { ++@@ -1099,6 +1100,8 @@ static int spinand_probe(struct spi_mem ++ if (ret) ++ return ret; ++ +++ mtk_bmt_attach(mtd); +++ ++ ret = mtd_device_register(mtd, NULL, 0); ++ if (ret) ++ goto err_spinand_cleanup; ++@@ -1124,6 +1127,7 @@ static int spinand_remove(struct spi_mem ++ if (ret) ++ return ret; ++ +++ mtk_bmt_detach(mtd); ++ spinand_cleanup(spinand); ++ ++ return 0; ++--- /dev/null +++++ b/include/linux/mtd/mtk_bmt.h ++@@ -0,0 +1,18 @@ +++#ifndef __MTK_BMT_H +++#define __MTK_BMT_H +++ +++#ifdef CONFIG_MTD_NAND_MTK_BMT +++int mtk_bmt_attach(struct mtd_info *mtd); +++void mtk_bmt_detach(struct mtd_info *mtd); +++#else +++static inline int mtk_bmt_attach(struct mtd_info *mtd) +++{ +++ return 0; +++} +++ +++static inline void mtk_bmt_detach(struct mtd_info *mtd) +++{ +++} +++#endif +++ +++#endif +-- +2.25.1 + diff --git a/backports/0012-mediatek-add-work-in-progress-linux-5.10-support.patch b/backports/0012-mediatek-add-work-in-progress-linux-5.10-support.patch new file mode 100644 index 000000000..352209137 --- /dev/null +++ b/backports/0012-mediatek-add-work-in-progress-linux-5.10-support.patch @@ -0,0 +1,106266 @@ +From 216db427fb2688b59099410fb5853795aa6c0b4a Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Sat, 24 Oct 2020 21:15:20 +0200 +Subject: [PATCH 12/22] mediatek: add work-in-progress linux 5.10 support + +Signed-off-by: Felix Fietkau +--- + target/linux/mediatek/Makefile | 2 +- + .../mt7622-bananapi-bpi-r64-rootdisk.dts | 593 + + .../mediatek/mt7622-elecom-wrc-2533gent.dts | 608 + + .../boot/dts/mediatek/mt7622-rfb1-ubi.dts | 646 + + .../drivers/net/phy/mtk/mt753x/Kconfig | 3 + + .../drivers/net/phy/mtk/mt753x/Makefile | 11 + + .../drivers/net/phy/mtk/mt753x/mt7530.c | 631 + + .../drivers/net/phy/mtk/mt753x/mt7530.h | 13 + + .../drivers/net/phy/mtk/mt753x/mt7531.c | 918 + + .../drivers/net/phy/mtk/mt753x/mt7531.h | 13 + + .../drivers/net/phy/mtk/mt753x/mt753x.h | 213 + + .../net/phy/mtk/mt753x/mt753x_common.c | 90 + + .../drivers/net/phy/mtk/mt753x/mt753x_mdio.c | 597 + + .../drivers/net/phy/mtk/mt753x/mt753x_nl.c | 382 + + .../drivers/net/phy/mtk/mt753x/mt753x_nl.h | 43 + + .../drivers/net/phy/mtk/mt753x/mt753x_regs.h | 294 + + .../net/phy/mtk/mt753x/mt753x_swconfig.c | 510 + + .../net/phy/mtk/mt753x/mt753x_swconfig.h | 29 + + .../drivers/net/phy/mtk/mt753x/mt753x_vlan.c | 183 + + .../drivers/net/phy/mtk/mt753x/mt753x_vlan.h | 40 + + .../files-5.10/drivers/net/phy/rtk/Makefile | 66 + + .../drivers/net/phy/rtk/modules.builtin | 1 + + .../drivers/net/phy/rtk/rtl8367c/acl.c | 2061 ++ + .../drivers/net/phy/rtk/rtl8367c/cpu.c | 537 + + .../drivers/net/phy/rtk/rtl8367c/dot1x.c | 843 + + .../drivers/net/phy/rtk/rtl8367c/eee.c | 162 + + .../drivers/net/phy/rtk/rtl8367c/i2c.c | 436 + + .../drivers/net/phy/rtk/rtl8367c/igmp.c | 1555 ++ + .../net/phy/rtk/rtl8367c/include/acl.h | 990 + + .../net/phy/rtk/rtl8367c/include/cpu.h | 327 + + .../net/phy/rtk/rtl8367c/include/dot1x.h | 470 + + .../net/phy/rtk/rtl8367c/include/eee.h | 82 + + .../net/phy/rtk/rtl8367c/include/i2c.h | 168 + + .../net/phy/rtk/rtl8367c/include/igmp.h | 769 + + .../net/phy/rtk/rtl8367c/include/interrupt.h | 254 + + .../drivers/net/phy/rtk/rtl8367c/include/l2.h | 1181 + + .../net/phy/rtk/rtl8367c/include/leaky.h | 371 + + .../net/phy/rtk/rtl8367c/include/led.h | 481 + + .../net/phy/rtk/rtl8367c/include/mirror.h | 272 + + .../net/phy/rtk/rtl8367c/include/oam.h | 188 + + .../net/phy/rtk/rtl8367c/include/port.h | 959 + + .../net/phy/rtk/rtl8367c/include/ptp.h | 511 + + .../net/phy/rtk/rtl8367c/include/qos.h | 781 + + .../net/phy/rtk/rtl8367c/include/rate.h | 305 + + .../net/phy/rtk/rtl8367c/include/rldp.h | 264 + + .../net/phy/rtk/rtl8367c/include/rtk_error.h | 229 + + .../net/phy/rtk/rtl8367c/include/rtk_hal.h | 44 + + .../net/phy/rtk/rtl8367c/include/rtk_switch.h | 737 + + .../net/phy/rtk/rtl8367c/include/rtk_types.h | 155 + + .../rtk/rtl8367c/include/rtl8367c_asicdrv.h | 129 + + .../rtl8367c/include/rtl8367c_asicdrv_acl.h | 231 + + .../include/rtl8367c_asicdrv_cputag.h | 49 + + .../rtl8367c/include/rtl8367c_asicdrv_dot1x.h | 52 + + .../rtl8367c/include/rtl8367c_asicdrv_eav.h | 109 + + .../rtl8367c/include/rtl8367c_asicdrv_eee.h | 31 + + .../rtl8367c/include/rtl8367c_asicdrv_fc.h | 99 + + .../rtl8367c/include/rtl8367c_asicdrv_green.h | 36 + + .../rtl8367c/include/rtl8367c_asicdrv_hsb.h | 43 + + .../rtl8367c/include/rtl8367c_asicdrv_i2c.h | 47 + + .../rtl8367c/include/rtl8367c_asicdrv_igmp.h | 169 + + .../include/rtl8367c_asicdrv_inbwctrl.h | 30 + + .../include/rtl8367c_asicdrv_interrupt.h | 66 + + .../rtl8367c/include/rtl8367c_asicdrv_led.h | 138 + + .../rtl8367c/include/rtl8367c_asicdrv_lut.h | 159 + + .../rtl8367c/include/rtl8367c_asicdrv_meter.h | 34 + + .../rtl8367c/include/rtl8367c_asicdrv_mib.h | 133 + + .../include/rtl8367c_asicdrv_mirror.h | 49 + + .../rtl8367c/include/rtl8367c_asicdrv_misc.h | 34 + + .../rtl8367c/include/rtl8367c_asicdrv_oam.h | 47 + + .../rtl8367c/include/rtl8367c_asicdrv_phy.h | 43 + + .../rtl8367c/include/rtl8367c_asicdrv_port.h | 237 + + .../include/rtl8367c_asicdrv_portIsolation.h | 28 + + .../rtl8367c/include/rtl8367c_asicdrv_qos.h | 96 + + .../rtl8367c/include/rtl8367c_asicdrv_rldp.h | 60 + + .../rtl8367c/include/rtl8367c_asicdrv_rma.h | 57 + + .../include/rtl8367c_asicdrv_scheduling.h | 58 + + .../rtl8367c/include/rtl8367c_asicdrv_storm.h | 61 + + .../rtl8367c/include/rtl8367c_asicdrv_svlan.h | 132 + + .../include/rtl8367c_asicdrv_trunking.h | 48 + + .../rtl8367c_asicdrv_unknownMulticast.h | 59 + + .../rtl8367c/include/rtl8367c_asicdrv_vlan.h | 157 + + .../phy/rtk/rtl8367c/include/rtl8367c_base.h | 596 + + .../phy/rtk/rtl8367c/include/rtl8367c_reg.h | 22819 ++++++++++++++++ + .../net/phy/rtk/rtl8367c/include/smi.h | 54 + + .../net/phy/rtk/rtl8367c/include/stat.h | 433 + + .../net/phy/rtk/rtl8367c/include/storm.h | 422 + + .../net/phy/rtk/rtl8367c/include/svlan.h | 896 + + .../net/phy/rtk/rtl8367c/include/trap.h | 757 + + .../net/phy/rtk/rtl8367c/include/trunk.h | 328 + + .../net/phy/rtk/rtl8367c/include/vlan.h | 892 + + .../drivers/net/phy/rtk/rtl8367c/interrupt.c | 434 + + .../drivers/net/phy/rtk/rtl8367c/l2.c | 2911 ++ + .../drivers/net/phy/rtk/rtl8367c/leaky.c | 590 + + .../drivers/net/phy/rtk/rtl8367c/led.c | 792 + + .../drivers/net/phy/rtk/rtl8367c/mirror.c | 548 + + .../drivers/net/phy/rtk/rtl8367c/oam.c | 245 + + .../drivers/net/phy/rtk/rtl8367c/port.c | 2467 ++ + .../drivers/net/phy/rtk/rtl8367c/ptp.c | 759 + + .../drivers/net/phy/rtk/rtl8367c/qos.c | 1452 + + .../drivers/net/phy/rtk/rtl8367c/rate.c | 607 + + .../drivers/net/phy/rtk/rtl8367c/rldp.c | 468 + + .../drivers/net/phy/rtk/rtl8367c/rtk_hal.c | 839 + + .../drivers/net/phy/rtk/rtl8367c/rtk_switch.c | 1796 ++ + .../net/phy/rtk/rtl8367c/rtl8367c_asicdrv.c | 639 + + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_acl.c | 1173 + + .../rtk/rtl8367c/rtl8367c_asicdrv_cputag.c | 369 + + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_dot1x.c | 415 + + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_eav.c | 877 + + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_eee.c | 141 + + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_fc.c | 1354 + + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_green.c | 445 + + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_hsb.c | 81 + + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_i2c.c | 474 + + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_igmp.c | 2109 ++ + .../rtk/rtl8367c/rtl8367c_asicdrv_inbwctrl.c | 164 + + .../rtk/rtl8367c/rtl8367c_asicdrv_interrupt.c | 205 + + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_led.c | 727 + + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_lut.c | 1549 ++ + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_meter.c | 305 + + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_mib.c | 570 + + .../rtk/rtl8367c/rtl8367c_asicdrv_mirror.c | 472 + + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_misc.c | 268 + + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_oam.c | 194 + + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c | 394 + + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_port.c | 5752 ++++ + .../rtl8367c/rtl8367c_asicdrv_portIsolation.c | 119 + + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_qos.c | 778 + + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_rldp.c | 674 + + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_rma.c | 362 + + .../rtl8367c/rtl8367c_asicdrv_scheduling.c | 525 + + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_storm.c | 851 + + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_svlan.c | 1003 + + .../rtk/rtl8367c/rtl8367c_asicdrv_trunking.c | 356 + + .../rtl8367c_asicdrv_unknownMulticast.c | 238 + + .../phy/rtk/rtl8367c/rtl8367c_asicdrv_vlan.c | 1505 + + .../drivers/net/phy/rtk/rtl8367c/smi.c | 444 + + .../drivers/net/phy/rtk/rtl8367c/stat.c | 626 + + .../drivers/net/phy/rtk/rtl8367c/storm.c | 816 + + .../drivers/net/phy/rtk/rtl8367c/svlan.c | 2415 ++ + .../drivers/net/phy/rtk/rtl8367c/trap.c | 1229 + + .../drivers/net/phy/rtk/rtl8367c/trunk.c | 605 + + .../drivers/net/phy/rtk/rtl8367c/vlan.c | 2124 ++ + .../files-5.10/drivers/net/phy/rtk/rtl8367s.c | 580 + + .../drivers/net/phy/rtk/rtl8367s_dbg.c | 648 + + .../drivers/net/phy/rtk/rtl8367s_mdio.c | 312 + + target/linux/mediatek/image/mt7622.mk | 6 +- + target/linux/mediatek/mt7622/config-5.10 | 433 + + .../100-dts-update-mt7622-rfb1.patch | 119 + + .../101-dts-update-mt7629-rfb.patch | 37 + + .../110-dts-fix-bpi2-console.patch | 10 + + .../111-dts-fix-bpi64-console.patch | 11 + + .../120-arm-dts-Add-Unielec-U7623-DTS.patch | 390 + + .../130-dts-mt7629-add-snand-support.patch | 97 + + .../131-dts-mt7622-add-snand-support.patch | 96 + + ...dts-fix-wmac-support-for-mt7622-rfb1.patch | 18 + + ...s-mt7623-eip97-inside-secure-support.patch | 23 + + ...-phy-phy-mtk-tphy-Add-hifsys-support.patch | 66 + + ...e-mtk-ecc-header-file-to-include-mtd.patch | 139 + + .../310-mtd-spinand-disable-on-die-ECC.patch | 31 + + ...aTek-Add-SPI-NAND-Flash-interface-dr.patch | 1246 + + .../patches-5.10/330-mtk-bmt-support.patch | 840 + + ...ypto-add-eip97-inside-secure-support.patch | 27 + + ...01-crypto-fix-eip97-cache-incoherent.patch | 26 + + .../patches-5.10/410-bt-mtk-serial-fix.patch | 33 + + .../500-gsw-rtl8367s-mt7622-support.patch | 25 + + ...ngs-PCI-Mediatek-Update-PCIe-binding.patch | 415 + + ...e-regmap-to-get-shared-pcie-cfg-base.patch | 217 + + ...ek-Split-PCIe-node-for-MT2712-MT7622.patch | 417 + + ...dts-mediatek-Update-mt7629-PCIe-node.patch | 203 + + ...diatek-fix-clearing-interrupt-status.patch | 24 + + ..._eth_soc-add-support-for-coherent-DM.patch | 85 + + ...ediatek-add-support-for-coherent-DMA.patch | 108 + + 172 files changed, 104871 insertions(+), 2 deletions(-) + create mode 100644 target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64-rootdisk.dts + create mode 100644 target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-elecom-wrc-2533gent.dts + create mode 100644 target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-rfb1-ubi.dts + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/Kconfig + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/Makefile + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt7530.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt7530.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt7531.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt7531.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_common.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_mdio.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_nl.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_nl.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_regs.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_swconfig.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_swconfig.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_vlan.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_vlan.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/Makefile + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/modules.builtin + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/acl.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/cpu.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/dot1x.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/eee.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/i2c.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/igmp.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/acl.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/cpu.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/dot1x.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/eee.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/i2c.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/igmp.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/interrupt.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/l2.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/leaky.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/led.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/mirror.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/oam.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/port.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/ptp.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/qos.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rate.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rldp.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtk_error.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtk_hal.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtk_switch.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtk_types.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_acl.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_cputag.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_dot1x.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eav.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eee.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_fc.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_green.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_hsb.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_i2c.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_igmp.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_inbwctrl.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_interrupt.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_led.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_lut.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_meter.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mib.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mirror.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_misc.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_oam.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_phy.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_port.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_portIsolation.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_qos.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rldp.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rma.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_scheduling.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_storm.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_svlan.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_trunking.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_unknownMulticast.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_vlan.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_base.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_reg.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/smi.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/stat.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/storm.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/svlan.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/trap.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/trunk.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/vlan.h + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/interrupt.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/l2.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/leaky.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/led.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/mirror.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/oam.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/port.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/ptp.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/qos.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rate.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rldp.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtk_hal.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtk_switch.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_acl.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_cputag.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_dot1x.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eav.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eee.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_fc.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_green.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_hsb.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_i2c.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_igmp.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_inbwctrl.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_interrupt.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_led.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_lut.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_meter.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_mib.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_mirror.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_misc.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_oam.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_port.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_portIsolation.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_qos.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rldp.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rma.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_scheduling.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_storm.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_svlan.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_trunking.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_unknownMulticast.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_vlan.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/smi.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/stat.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/storm.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/svlan.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/trap.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/trunk.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/vlan.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367s.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367s_dbg.c + create mode 100644 target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367s_mdio.c + create mode 100755 target/linux/mediatek/mt7622/config-5.10 + create mode 100644 target/linux/mediatek/patches-5.10/100-dts-update-mt7622-rfb1.patch + create mode 100644 target/linux/mediatek/patches-5.10/101-dts-update-mt7629-rfb.patch + create mode 100644 target/linux/mediatek/patches-5.10/110-dts-fix-bpi2-console.patch + create mode 100644 target/linux/mediatek/patches-5.10/111-dts-fix-bpi64-console.patch + create mode 100644 target/linux/mediatek/patches-5.10/120-arm-dts-Add-Unielec-U7623-DTS.patch + create mode 100644 target/linux/mediatek/patches-5.10/130-dts-mt7629-add-snand-support.patch + create mode 100644 target/linux/mediatek/patches-5.10/131-dts-mt7622-add-snand-support.patch + create mode 100644 target/linux/mediatek/patches-5.10/140-dts-fix-wmac-support-for-mt7622-rfb1.patch + create mode 100644 target/linux/mediatek/patches-5.10/150-dts-mt7623-eip97-inside-secure-support.patch + create mode 100644 target/linux/mediatek/patches-5.10/200-phy-phy-mtk-tphy-Add-hifsys-support.patch + create mode 100644 target/linux/mediatek/patches-5.10/300-mtd-mtk-ecc-move-mtk-ecc-header-file-to-include-mtd.patch + create mode 100644 target/linux/mediatek/patches-5.10/310-mtd-spinand-disable-on-die-ECC.patch + create mode 100644 target/linux/mediatek/patches-5.10/320-spi-spi-mem-MediaTek-Add-SPI-NAND-Flash-interface-dr.patch + create mode 100644 target/linux/mediatek/patches-5.10/330-mtk-bmt-support.patch + create mode 100644 target/linux/mediatek/patches-5.10/400-crypto-add-eip97-inside-secure-support.patch + create mode 100644 target/linux/mediatek/patches-5.10/401-crypto-fix-eip97-cache-incoherent.patch + create mode 100644 target/linux/mediatek/patches-5.10/410-bt-mtk-serial-fix.patch + create mode 100644 target/linux/mediatek/patches-5.10/500-gsw-rtl8367s-mt7622-support.patch + create mode 100644 target/linux/mediatek/patches-5.10/600-dt-bindings-PCI-Mediatek-Update-PCIe-binding.patch + create mode 100644 target/linux/mediatek/patches-5.10/601-PCI-mediatek-Use-regmap-to-get-shared-pcie-cfg-base.patch + create mode 100644 target/linux/mediatek/patches-5.10/602-arm64-dts-mediatek-Split-PCIe-node-for-MT2712-MT7622.patch + create mode 100644 target/linux/mediatek/patches-5.10/603-ARM-dts-mediatek-Update-mt7629-PCIe-node.patch + create mode 100644 target/linux/mediatek/patches-5.10/610-pcie-mediatek-fix-clearing-interrupt-status.patch + create mode 100644 target/linux/mediatek/patches-5.10/700-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch + create mode 100644 target/linux/mediatek/patches-5.10/710-pci-pcie-mediatek-add-support-for-coherent-DMA.patch + +diff --git a/target/linux/mediatek/Makefile b/target/linux/mediatek/Makefile +index c8ab5e01e6..a088210321 100644 +--- a/target/linux/mediatek/Makefile ++++ b/target/linux/mediatek/Makefile +@@ -9,7 +9,7 @@ SUBTARGETS:=mt7622 mt7623 mt7629 + FEATURES:=squashfs nand ramdisk fpu + + KERNEL_PATCHVER:=5.4 +-KERNEL_TESTING_PATCHVER:=5.4 ++KERNEL_TESTING_PATCHVER:=5.10 + + include $(INCLUDE_DIR)/target.mk + DEFAULT_PACKAGES += \ +diff --git a/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64-rootdisk.dts b/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64-rootdisk.dts +new file mode 100644 +index 0000000000..2235306b2b +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64-rootdisk.dts +@@ -0,0 +1,593 @@ ++/* ++ * Copyright (c) 2018 MediaTek Inc. ++ * Author: Ryder Lee ++ * ++ * SPDX-License-Identifier: (GPL-2.0-only OR MIT) ++ */ ++ ++/dts-v1/; ++#include ++#include ++ ++#include "mt7622.dtsi" ++#include "mt6380.dtsi" ++ ++/ { ++ model = "Bananapi BPI-R64"; ++ compatible = "bananapi,bpi-r64-rootdisk", "mediatek,mt7622"; ++ ++ aliases { ++ serial0 = &uart0; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512 root=/dev/mmcblk0p7 rootfstype=squashfs,f2fs"; ++ }; ++ ++ cpus { ++ cpu@0 { ++ proc-supply = <&mt6380_vcpu_reg>; ++ sram-supply = <&mt6380_vm_reg>; ++ }; ++ ++ cpu@1 { ++ proc-supply = <&mt6380_vcpu_reg>; ++ sram-supply = <&mt6380_vm_reg>; ++ }; ++ }; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ ++ factory { ++ label = "factory"; ++ linux,code = ; ++ gpios = <&pio 0 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ wps { ++ label = "wps"; ++ linux,code = ; ++ gpios = <&pio 102 GPIO_ACTIVE_HIGH>; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ green { ++ label = "bpi-r64:pio:green"; ++ gpios = <&pio 89 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ }; ++ ++ red { ++ label = "bpi-r64:pio:red"; ++ gpios = <&pio 88 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ }; ++ }; ++ ++ memory { ++ reg = <0 0x40000000 0 0x40000000>; ++ }; ++ ++ reg_1p8v: regulator-1p8v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-1.8V"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ }; ++ ++ reg_3p3v: regulator-3p3v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-3.3V"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ reg_5v: regulator-5v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-5V"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++}; ++ ++&bch { ++ status = "disabled"; ++}; ++ ++&btif { ++ status = "okay"; ++}; ++ ++&cir { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&irrx_pins>; ++ status = "okay"; ++}; ++ ++ð { ++ status = "okay"; ++ gmac0: mac@0 { ++ compatible = "mediatek,eth-mac"; ++ reg = <0>; ++ phy-mode = "2500base-x"; ++ ++ fixed-link { ++ speed = <2500>; ++ full-duplex; ++ pause; ++ }; ++ }; ++ ++ gmac1: mac@1 { ++ compatible = "mediatek,eth-mac"; ++ reg = <1>; ++ phy-mode = "rgmii"; ++ ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ pause; ++ }; ++ }; ++ ++ mdio: mdio-bus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ switch@1f { ++ compatible = "mediatek,mt7531"; ++ reg = <0x1f>; ++ reset-gpios = <&pio 54 0>; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ wan: port@0 { ++ reg = <0>; ++ label = "wan"; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ label = "lan0"; ++ }; ++ ++ port@2 { ++ reg = <2>; ++ label = "lan1"; ++ }; ++ ++ port@3 { ++ reg = <3>; ++ label = "lan2"; ++ }; ++ ++ port@4 { ++ reg = <4>; ++ label = "lan3"; ++ }; ++ ++ port@6 { ++ reg = <6>; ++ label = "cpu"; ++ ethernet = <&gmac0>; ++ phy-mode = "2500base-x"; ++ ++ fixed-link { ++ speed = <2500>; ++ full-duplex; ++ pause; ++ }; ++ }; ++ }; ++ }; ++ ++ }; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ status = "okay"; ++}; ++ ++&i2c2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c2_pins>; ++ status = "okay"; ++}; ++ ++&mmc0 { ++ pinctrl-names = "default", "state_uhs"; ++ pinctrl-0 = <&emmc_pins_default>; ++ pinctrl-1 = <&emmc_pins_uhs>; ++ status = "okay"; ++ bus-width = <8>; ++ max-frequency = <50000000>; ++ cap-mmc-highspeed; ++ mmc-hs200-1_8v; ++ vmmc-supply = <®_3p3v>; ++ vqmmc-supply = <®_1p8v>; ++ assigned-clocks = <&topckgen CLK_TOP_MSDC30_0_SEL>; ++ assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>; ++ non-removable; ++}; ++ ++&mmc1 { ++ pinctrl-names = "default", "state_uhs"; ++ pinctrl-0 = <&sd0_pins_default>; ++ pinctrl-1 = <&sd0_pins_uhs>; ++ status = "okay"; ++ bus-width = <4>; ++ max-frequency = <50000000>; ++ cap-sd-highspeed; ++ r_smpl = <1>; ++ cd-gpios = <&pio 81 GPIO_ACTIVE_LOW>; ++ vmmc-supply = <®_3p3v>; ++ vqmmc-supply = <®_3p3v>; ++ assigned-clocks = <&topckgen CLK_TOP_MSDC30_1_SEL>; ++ assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>; ++}; ++ ++&nandc { ++ pinctrl-names = "default"; ++ pinctrl-0 = <¶llel_nand_pins>; ++ status = "disabled"; ++}; ++ ++&nor_flash { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi_nor_pins>; ++ status = "disabled"; ++ ++ flash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ }; ++}; ++ ++&pcie0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie0_pins>; ++ status = "okay"; ++}; ++ ++&pcie1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie1_pins>; ++ status = "okay"; ++}; ++ ++&pio { ++ /* Attention: GPIO 90 is used to switch between PCIe@1,0 and ++ * SATA functions. i.e. output-high: PCIe, output-low: SATA ++ */ ++ asm_sel { ++ gpio-hog; ++ gpios = <90 GPIO_ACTIVE_HIGH>; ++ output-high; ++ }; ++ ++ /* eMMC is shared pin with parallel NAND */ ++ emmc_pins_default: emmc-pins-default { ++ mux { ++ function = "emmc", "emmc_rst"; ++ groups = "emmc"; ++ }; ++ ++ /* "NDL0","NDL1","NDL2","NDL3","NDL4","NDL5","NDL6","NDL7", ++ * "NRB","NCLE" pins are used as DAT0,DAT1,DAT2,DAT3,DAT4, ++ * DAT5,DAT6,DAT7,CMD,CLK for eMMC respectively ++ */ ++ conf-cmd-dat { ++ pins = "NDL0", "NDL1", "NDL2", ++ "NDL3", "NDL4", "NDL5", ++ "NDL6", "NDL7", "NRB"; ++ input-enable; ++ bias-pull-up; ++ }; ++ ++ conf-clk { ++ pins = "NCLE"; ++ bias-pull-down; ++ }; ++ }; ++ ++ emmc_pins_uhs: emmc-pins-uhs { ++ mux { ++ function = "emmc"; ++ groups = "emmc"; ++ }; ++ ++ conf-cmd-dat { ++ pins = "NDL0", "NDL1", "NDL2", ++ "NDL3", "NDL4", "NDL5", ++ "NDL6", "NDL7", "NRB"; ++ input-enable; ++ drive-strength = <4>; ++ bias-pull-up; ++ }; ++ ++ conf-clk { ++ pins = "NCLE"; ++ drive-strength = <4>; ++ bias-pull-down; ++ }; ++ }; ++ ++ eth_pins: eth-pins { ++ mux { ++ function = "eth"; ++ groups = "mdc_mdio", "rgmii_via_gmac2"; ++ }; ++ }; ++ ++ i2c1_pins: i2c1-pins { ++ mux { ++ function = "i2c"; ++ groups = "i2c1_0"; ++ }; ++ }; ++ ++ i2c2_pins: i2c2-pins { ++ mux { ++ function = "i2c"; ++ groups = "i2c2_0"; ++ }; ++ }; ++ ++ i2s1_pins: i2s1-pins { ++ mux { ++ function = "i2s"; ++ groups = "i2s_out_mclk_bclk_ws", ++ "i2s1_in_data", ++ "i2s1_out_data"; ++ }; ++ ++ conf { ++ pins = "I2S1_IN", "I2S1_OUT", "I2S_BCLK", ++ "I2S_WS", "I2S_MCLK"; ++ drive-strength = <12>; ++ bias-pull-down; ++ }; ++ }; ++ ++ irrx_pins: irrx-pins { ++ mux { ++ function = "ir"; ++ groups = "ir_1_rx"; ++ }; ++ }; ++ ++ irtx_pins: irtx-pins { ++ mux { ++ function = "ir"; ++ groups = "ir_1_tx"; ++ }; ++ }; ++ ++ /* Parallel nand is shared pin with eMMC */ ++ parallel_nand_pins: parallel-nand-pins { ++ mux { ++ function = "flash"; ++ groups = "par_nand"; ++ }; ++ }; ++ ++ pcie0_pins: pcie0-pins { ++ mux { ++ function = "pcie"; ++ groups = "pcie0_pad_perst", ++ "pcie0_1_waken", ++ "pcie0_1_clkreq"; ++ }; ++ }; ++ ++ pcie1_pins: pcie1-pins { ++ mux { ++ function = "pcie"; ++ groups = "pcie1_pad_perst", ++ "pcie1_0_waken", ++ "pcie1_0_clkreq"; ++ }; ++ }; ++ ++ pmic_bus_pins: pmic-bus-pins { ++ mux { ++ function = "pmic"; ++ groups = "pmic_bus"; ++ }; ++ }; ++ ++ pwm7_pins: pwm1-2-pins { ++ mux { ++ function = "pwm"; ++ groups = "pwm_ch7_2"; ++ }; ++ }; ++ ++ wled_pins: wled-pins { ++ mux { ++ function = "led"; ++ groups = "wled"; ++ }; ++ }; ++ ++ sd0_pins_default: sd0-pins-default { ++ mux { ++ function = "sd"; ++ groups = "sd_0"; ++ }; ++ ++ /* "I2S2_OUT, "I2S4_IN"", "I2S3_IN", "I2S2_IN", ++ * "I2S4_OUT", "I2S3_OUT" are used as DAT0, DAT1, ++ * DAT2, DAT3, CMD, CLK for SD respectively. ++ */ ++ conf-cmd-data { ++ pins = "I2S2_OUT", "I2S4_IN", "I2S3_IN", ++ "I2S2_IN","I2S4_OUT"; ++ input-enable; ++ drive-strength = <8>; ++ bias-pull-up; ++ }; ++ conf-clk { ++ pins = "I2S3_OUT"; ++ drive-strength = <12>; ++ bias-pull-down; ++ }; ++ conf-cd { ++ pins = "TXD3"; ++ bias-pull-up; ++ }; ++ }; ++ ++ sd0_pins_uhs: sd0-pins-uhs { ++ mux { ++ function = "sd"; ++ groups = "sd_0"; ++ }; ++ ++ conf-cmd-data { ++ pins = "I2S2_OUT", "I2S4_IN", "I2S3_IN", ++ "I2S2_IN","I2S4_OUT"; ++ input-enable; ++ bias-pull-up; ++ }; ++ ++ conf-clk { ++ pins = "I2S3_OUT"; ++ bias-pull-down; ++ }; ++ }; ++ ++ /* Serial NAND is shared pin with SPI-NOR */ ++ serial_nand_pins: serial-nand-pins { ++ mux { ++ function = "flash"; ++ groups = "snfi"; ++ }; ++ }; ++ ++ spic0_pins: spic0-pins { ++ mux { ++ function = "spi"; ++ groups = "spic0_0"; ++ }; ++ }; ++ ++ spic1_pins: spic1-pins { ++ mux { ++ function = "spi"; ++ groups = "spic1_0"; ++ }; ++ }; ++ ++ /* SPI-NOR is shared pin with serial NAND */ ++ spi_nor_pins: spi-nor-pins { ++ mux { ++ function = "flash"; ++ groups = "spi_nor"; ++ }; ++ }; ++ ++ /* serial NAND is shared pin with SPI-NOR */ ++ serial_nand_pins: serial-nand-pins { ++ mux { ++ function = "flash"; ++ groups = "snfi"; ++ }; ++ }; ++ ++ uart0_pins: uart0-pins { ++ mux { ++ function = "uart"; ++ groups = "uart0_0_tx_rx" ; ++ }; ++ }; ++ ++ uart2_pins: uart2-pins { ++ mux { ++ function = "uart"; ++ groups = "uart2_1_tx_rx" ; ++ }; ++ }; ++ ++ watchdog_pins: watchdog-pins { ++ mux { ++ function = "watchdog"; ++ groups = "watchdog"; ++ }; ++ }; ++}; ++ ++&pwm { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm7_pins>; ++ status = "okay"; ++}; ++ ++&pwrap { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_bus_pins>; ++ ++ status = "okay"; ++}; ++ ++&sata { ++ status = "disable"; ++}; ++ ++&sata_phy { ++ status = "disable"; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spic0_pins>; ++ status = "okay"; ++}; ++ ++&spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spic1_pins>; ++ status = "okay"; ++}; ++ ++&ssusb { ++ vusb33-supply = <®_3p3v>; ++ vbus-supply = <®_5v>; ++ status = "okay"; ++}; ++ ++&u3phy { ++ status = "okay"; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pins>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2_pins>; ++ status = "okay"; ++}; ++ ++&watchdog { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&watchdog_pins>; ++ status = "okay"; ++}; +diff --git a/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-elecom-wrc-2533gent.dts b/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-elecom-wrc-2533gent.dts +new file mode 100644 +index 0000000000..48865ada40 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-elecom-wrc-2533gent.dts +@@ -0,0 +1,608 @@ ++/* ++ * Copyright (c) 2017 MediaTek Inc. ++ * Author: Ming Huang ++ * Sean Wang ++ * ++ * SPDX-License-Identifier: (GPL-2.0-only OR MIT) ++ */ ++ ++/dts-v1/; ++#include ++#include ++ ++#include "mt7622.dtsi" ++#include "mt6380.dtsi" ++ ++/ { ++ model = "Elecom WRC-2533"; ++ compatible = "elecom,wrc-2533gent", "mediatek,mt7622"; ++ ++ aliases { ++ led-boot = &led_power; ++ led-failsafe = &led_power; ++ led-running = &led_power; ++ led-upgrade = &led_power; ++ serial0 = &uart0; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512 console=ttyS0,115200n8"; ++ }; ++ ++ cpus { ++ cpu@0 { ++ proc-supply = <&mt6380_vcpu_reg>; ++ sram-supply = <&mt6380_vm_reg>; ++ }; ++ ++ cpu@1 { ++ proc-supply = <&mt6380_vcpu_reg>; ++ sram-supply = <&mt6380_vm_reg>; ++ }; ++ }; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ poll-interval = <100>; ++ ++ wps { ++ label = "wps"; ++ linux,code = ; ++ gpios = <&pio 0 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ factory { ++ label = "factory"; ++ linux,code = ; ++ gpios = <&pio 102 GPIO_ACTIVE_LOW>; ++ }; ++ ++ switch0 { ++ label = "switch0"; ++ gpios = <&pio 1 GPIO_ACTIVE_LOW>; ++ linux,code = ; ++ linux,input-type = ; ++ }; ++ ++ switch1 { ++ label = "switch1"; ++ gpios = <&pio 16 GPIO_ACTIVE_LOW>; ++ linux,code = ; ++ linux,input-type = ; ++ }; ++ ++ switch2 { ++ label = "switch2"; ++ gpios = <&pio 17 GPIO_ACTIVE_LOW>; ++ linux,code = ; ++ linux,input-type = ; ++ }; ++ ++ switch3 { ++ label = "switch3"; ++ gpios = <&pio 18 GPIO_ACTIVE_LOW>; ++ linux,code = ; ++ linux,input-type = ; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led_power: power_g { ++ label = "wrc-2533:green:power"; ++ gpios = <&pio 2 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ power_b { ++ label = "wrc-2533:blue:power"; ++ gpios = <&pio 19 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ power_r { ++ label = "wrc-2533:red:power"; ++ gpios = <&pio 73 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ usb { ++ label = "wrc-2533:blue:usb"; ++ gpios = <&pio 74 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ wps { ++ label = "wrc-2533:red:wps"; ++ gpios = <&pio 76 GPIO_ACTIVE_LOW>; ++ }; ++ ++ wifi2 { ++ label = "wrc-2533:blue:wifi2g"; ++ gpios = <&pio 85 GPIO_ACTIVE_LOW>; ++ }; ++ ++ wifi5 { ++ label = "wrc-2533:blue:wifi5g"; ++ gpios = <&pio 91 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ reg_usb_vbus: regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "usb_vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ gpio = <&pio 22 GPIO_ACTIVE_LOW>; ++ enable-active-high; ++ }; ++ ++ memory { ++ reg = <0 0x40000000 0 0x3F000000>; ++ }; ++ ++ reg_1p8v: regulator-1p8v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-1.8V"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ }; ++ ++ reg_3p3v: regulator-3p3v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-3.3V"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ rtkgsw: rtkgsw@0 { ++ compatible = "mediatek,rtk-gsw"; ++ mediatek,ethsys = <ðsys>; ++ mediatek,mdio = <&mdio>; ++ mediatek,reset-pin = <&pio 54 0>; ++ status = "okay"; ++ }; ++}; ++ ++&pcie0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie0_pins>; ++ status = "okay"; ++}; ++ ++&slot0 { ++ mt7615@0,0 { ++ reg = <0x0000 0 0 0 0>; ++ mediatek,mtd-eeprom = <&factory 0x05000>; ++ }; ++}; ++ ++&pio { ++ /* eMMC is shared pin with parallel NAND */ ++ emmc_pins_default: emmc-pins-default { ++ mux { ++ function = "emmc", "emmc_rst"; ++ groups = "emmc"; ++ }; ++ ++ /* "NDL0","NDL1","NDL2","NDL3","NDL4","NDL5","NDL6","NDL7", ++ * "NRB","NCLE" pins are used as DAT0,DAT1,DAT2,DAT3,DAT4, ++ * DAT5,DAT6,DAT7,CMD,CLK for eMMC respectively ++ */ ++ conf-cmd-dat { ++ pins = "NDL0", "NDL1", "NDL2", ++ "NDL3", "NDL4", "NDL5", ++ "NDL6", "NDL7", "NRB"; ++ input-enable; ++ bias-pull-up; ++ }; ++ ++ conf-clk { ++ pins = "NCLE"; ++ bias-pull-down; ++ }; ++ }; ++ ++ emmc_pins_uhs: emmc-pins-uhs { ++ mux { ++ function = "emmc"; ++ groups = "emmc"; ++ }; ++ ++ conf-cmd-dat { ++ pins = "NDL0", "NDL1", "NDL2", ++ "NDL3", "NDL4", "NDL5", ++ "NDL6", "NDL7", "NRB"; ++ input-enable; ++ drive-strength = <4>; ++ bias-pull-up; ++ }; ++ ++ conf-clk { ++ pins = "NCLE"; ++ drive-strength = <4>; ++ bias-pull-down; ++ }; ++ }; ++ ++ eth_pins: eth-pins { ++ mux { ++ function = "eth"; ++ groups = "mdc_mdio", "rgmii_via_gmac2"; ++ }; ++ }; ++ ++ i2c1_pins: i2c1-pins { ++ mux { ++ function = "i2c"; ++ groups = "i2c1_0"; ++ }; ++ }; ++ ++ i2c2_pins: i2c2-pins { ++ mux { ++ function = "i2c"; ++ groups = "i2c2_0"; ++ }; ++ }; ++ ++ i2s1_pins: i2s1-pins { ++ mux { ++ function = "i2s"; ++ groups = "i2s_out_mclk_bclk_ws", ++ "i2s1_in_data", ++ "i2s1_out_data"; ++ }; ++ ++ conf { ++ pins = "I2S1_IN", "I2S1_OUT", "I2S_BCLK", ++ "I2S_WS", "I2S_MCLK"; ++ drive-strength = <12>; ++ bias-pull-down; ++ }; ++ }; ++ ++ irrx_pins: irrx-pins { ++ mux { ++ function = "ir"; ++ groups = "ir_1_rx"; ++ }; ++ }; ++ ++ irtx_pins: irtx-pins { ++ mux { ++ function = "ir"; ++ groups = "ir_1_tx"; ++ }; ++ }; ++ ++ /* Parallel nand is shared pin with eMMC */ ++ parallel_nand_pins: parallel-nand-pins { ++ mux { ++ function = "flash"; ++ groups = "par_nand"; ++ }; ++ }; ++ ++ pcie0_pins: pcie0-pins { ++ mux { ++ function = "pcie"; ++ groups = "pcie0_pad_perst", ++ "pcie0_1_waken", ++ "pcie0_1_clkreq"; ++ }; ++ }; ++ ++ pcie1_pins: pcie1-pins { ++ mux { ++ function = "pcie"; ++ groups = "pcie1_pad_perst", ++ "pcie1_0_waken", ++ "pcie1_0_clkreq"; ++ }; ++ }; ++ ++ pmic_bus_pins: pmic-bus-pins { ++ mux { ++ function = "pmic"; ++ groups = "pmic_bus"; ++ }; ++ }; ++ ++ pwm7_pins: pwm1-2-pins { ++ mux { ++ function = "pwm"; ++ groups = "pwm_ch7_2"; ++ }; ++ }; ++ ++ wled_pins: wled-pins { ++ mux { ++ function = "led"; ++ groups = "wled"; ++ }; ++ }; ++ ++ sd0_pins_default: sd0-pins-default { ++ mux { ++ function = "sd"; ++ groups = "sd_0"; ++ }; ++ ++ /* "I2S2_OUT, "I2S4_IN"", "I2S3_IN", "I2S2_IN", ++ * "I2S4_OUT", "I2S3_OUT" are used as DAT0, DAT1, ++ * DAT2, DAT3, CMD, CLK for SD respectively. ++ */ ++ conf-cmd-data { ++ pins = "I2S2_OUT", "I2S4_IN", "I2S3_IN", ++ "I2S2_IN","I2S4_OUT"; ++ input-enable; ++ drive-strength = <8>; ++ bias-pull-up; ++ }; ++ conf-clk { ++ pins = "I2S3_OUT"; ++ drive-strength = <12>; ++ bias-pull-down; ++ }; ++ conf-cd { ++ pins = "TXD3"; ++ bias-pull-up; ++ }; ++ }; ++ ++ sd0_pins_uhs: sd0-pins-uhs { ++ mux { ++ function = "sd"; ++ groups = "sd_0"; ++ }; ++ ++ conf-cmd-data { ++ pins = "I2S2_OUT", "I2S4_IN", "I2S3_IN", ++ "I2S2_IN","I2S4_OUT"; ++ input-enable; ++ bias-pull-up; ++ }; ++ ++ conf-clk { ++ pins = "I2S3_OUT"; ++ bias-pull-down; ++ }; ++ }; ++ ++ /* Serial NAND is shared pin with SPI-NOR */ ++ serial_nand_pins: serial-nand-pins { ++ mux { ++ function = "flash"; ++ groups = "snfi"; ++ }; ++ }; ++ ++ spic0_pins: spic0-pins { ++ mux { ++ function = "spi"; ++ groups = "spic0_0"; ++ }; ++ }; ++ ++ spic1_pins: spic1-pins { ++ mux { ++ function = "spi"; ++ groups = "spic1_0"; ++ }; ++ }; ++ ++ /* SPI-NOR is shared pin with serial NAND */ ++ spi_nor_pins: spi-nor-pins { ++ mux { ++ function = "flash"; ++ groups = "spi_nor"; ++ }; ++ }; ++ ++ /* serial NAND is shared pin with SPI-NOR */ ++ serial_nand_pins: serial-nand-pins { ++ mux { ++ function = "flash"; ++ groups = "snfi"; ++ }; ++ }; ++ ++ uart0_pins: uart0-pins { ++ mux { ++ function = "uart"; ++ groups = "uart0_0_tx_rx" ; ++ }; ++ }; ++ ++ uart2_pins: uart2-pins { ++ mux { ++ function = "uart"; ++ groups = "uart2_1_tx_rx" ; ++ }; ++ }; ++ ++ watchdog_pins: watchdog-pins { ++ mux { ++ function = "watchdog"; ++ groups = "watchdog"; ++ }; ++ }; ++}; ++ ++&bch { ++ status = "okay"; ++}; ++ ++&btif { ++ status = "disabled"; ++}; ++ ++&cir { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&irrx_pins>; ++ status = "okay"; ++}; ++ ++ð { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <ð_pins>; ++ gmac0: mac@0 { ++ compatible = "mediatek,eth-mac"; ++ reg = <0>; ++ phy-mode = "sgmii"; ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ pause; ++ }; ++ }; ++ gmac1: mac@1 { ++ compatible = "mediatek,eth-mac"; ++ reg = <1>; ++ phy-mode = "rgmii"; ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ pause; ++ }; ++ }; ++ mdio: mdio-bus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ status = "okay"; ++}; ++ ++&i2c2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c2_pins>; ++ status = "okay"; ++}; ++ ++&pwm { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm7_pins>; ++ status = "okay"; ++}; ++ ++&pwrap { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_bus_pins>; ++ ++ status = "okay"; ++}; ++ ++&snfi { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&serial_nand_pins>; ++ status = "okay"; ++ ++ spi_nand@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "spi-nand"; ++ spi-max-frequency = <104000000>; ++ reg = <0>; ++ ++ mediatek,bmt-v2; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "Preloader"; ++ reg = <0x00000 0x0080000>; ++ read-only; ++ }; ++ ++ partition@80000 { ++ label = "ATF"; ++ reg = <0x80000 0x0040000>; ++ read-only; ++ }; ++ ++ partition@c0000 { ++ label = "uboot"; ++ reg = <0xc0000 0x0080000>; ++ read-only; ++ }; ++ ++ partition@140000 { ++ label = "uboot-env"; ++ reg = <0x140000 0x0080000>; ++ read-only; ++ }; ++ ++ factory: partition@1c0000 { ++ label = "factory"; ++ reg = <0x1c0000 0x0040000>; ++ read-only; ++ }; ++ ++ partition@200000 { ++ label = "firmware"; ++ reg = <0x200000 0x2000000>; ++ }; ++ ++ partition@2200000 { ++ label = "reserved"; ++ reg = <0x2200000 0x4000000>; ++ }; ++ }; ++ }; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spic0_pins>; ++ status = "okay"; ++}; ++ ++&spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spic1_pins>; ++ status = "okay"; ++}; ++ ++&ssusb { ++ vusb33-supply = <®_3p3v>; ++ vbus-supply = <®_usb_vbus>; ++ status = "okay"; ++}; ++ ++&u3phy { ++ status = "okay"; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pins>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2_pins>; ++ status = "okay"; ++}; ++ ++&watchdog { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&watchdog_pins>; ++ status = "okay"; ++}; ++ ++&wmac { ++ mediatek,mtd-eeprom = <&factory 0x0000>; ++ status = "okay"; ++}; +diff --git a/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-rfb1-ubi.dts b/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-rfb1-ubi.dts +new file mode 100644 +index 0000000000..2589a349ad +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-rfb1-ubi.dts +@@ -0,0 +1,646 @@ ++/* ++ * Copyright (c) 2018 MediaTek Inc. ++ * Author: Ryder Lee ++ * ++ * SPDX-License-Identifier: (GPL-2.0-only OR MIT) ++ */ ++ ++/dts-v1/; ++#include ++#include ++ ++#include "mt7622.dtsi" ++#include "mt6380.dtsi" ++ ++/ { ++ model = "MT7622_MT7531 RFB"; ++ compatible = "mediatek,mt7622,ubi"; ++ ++ aliases { ++ serial0 = &uart0; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512"; ++ }; ++ ++ cpus { ++ cpu@0 { ++ proc-supply = <&mt6380_vcpu_reg>; ++ sram-supply = <&mt6380_vm_reg>; ++ }; ++ ++ cpu@1 { ++ proc-supply = <&mt6380_vcpu_reg>; ++ sram-supply = <&mt6380_vm_reg>; ++ }; ++ }; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ ++ factory { ++ label = "factory"; ++ linux,code = ; ++ gpios = <&pio 0 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ wps { ++ label = "wps"; ++ linux,code = ; ++ gpios = <&pio 102 GPIO_ACTIVE_HIGH>; ++ }; ++ }; ++ ++ gsw: gsw@0 { ++ compatible = "mediatek,mt753x"; ++ mediatek,ethsys = <ðsys>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ green { ++ label = "bpi-r64:pio:green"; ++ gpios = <&pio 89 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ }; ++ ++ red { ++ label = "bpi-r64:pio:red"; ++ gpios = <&pio 88 GPIO_ACTIVE_HIGH>; ++ default-state = "off"; ++ }; ++ }; ++ ++ memory { ++ reg = <0 0x40000000 0 0x40000000>; ++ }; ++ ++ reg_1p8v: regulator-1p8v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-1.8V"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ }; ++ ++ reg_3p3v: regulator-3p3v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-3.3V"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ reg_5v: regulator-5v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-5V"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++}; ++ ++&bch { ++ status = "okay"; ++}; ++ ++&btif { ++ status = "okay"; ++}; ++ ++&cir { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&irrx_pins>; ++ status = "okay"; ++}; ++ ++ð { ++ status = "okay"; ++ gmac0: mac@0 { ++ compatible = "mediatek,eth-mac"; ++ reg = <0>; ++ phy-mode = "2500base-x"; ++ ++ fixed-link { ++ speed = <2500>; ++ full-duplex; ++ pause; ++ }; ++ }; ++ ++ gmac1: mac@1 { ++ compatible = "mediatek,eth-mac"; ++ reg = <1>; ++ phy-mode = "rgmii"; ++ ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ pause; ++ }; ++ }; ++ ++ mdio: mdio-bus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++}; ++ ++&gsw { ++ mediatek,mdio = <&mdio>; ++ mediatek,portmap = "llllw"; ++ mediatek,mdio_master_pinmux = <0>; ++ reset-gpios = <&pio 54 0>; ++ interrupt-parent = <&pio>; ++ interrupts = <53 IRQ_TYPE_LEVEL_HIGH>; ++ status = "okay"; ++ ++ port5: port@5 { ++ compatible = "mediatek,mt753x-port"; ++ reg = <5>; ++ phy-mode = "rgmii"; ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ }; ++ }; ++ ++ port6: port@6 { ++ compatible = "mediatek,mt753x-port"; ++ reg = <6>; ++ phy-mode = "sgmii"; ++ fixed-link { ++ speed = <2500>; ++ full-duplex; ++ }; ++ }; ++}; ++ ++&i2c1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c1_pins>; ++ status = "okay"; ++}; ++ ++&i2c2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c2_pins>; ++ status = "okay"; ++}; ++ ++&mmc0 { ++ pinctrl-names = "default", "state_uhs"; ++ pinctrl-0 = <&emmc_pins_default>; ++ pinctrl-1 = <&emmc_pins_uhs>; ++ status = "okay"; ++ bus-width = <8>; ++ max-frequency = <50000000>; ++ cap-mmc-highspeed; ++ mmc-hs200-1_8v; ++ vmmc-supply = <®_3p3v>; ++ vqmmc-supply = <®_1p8v>; ++ assigned-clocks = <&topckgen CLK_TOP_MSDC30_0_SEL>; ++ assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>; ++ non-removable; ++}; ++ ++&mmc1 { ++ pinctrl-names = "default", "state_uhs"; ++ pinctrl-0 = <&sd0_pins_default>; ++ pinctrl-1 = <&sd0_pins_uhs>; ++ status = "okay"; ++ bus-width = <4>; ++ max-frequency = <50000000>; ++ cap-sd-highspeed; ++ r_smpl = <1>; ++ cd-gpios = <&pio 81 GPIO_ACTIVE_LOW>; ++ vmmc-supply = <®_3p3v>; ++ vqmmc-supply = <®_3p3v>; ++ assigned-clocks = <&topckgen CLK_TOP_MSDC30_1_SEL>; ++ assigned-clock-parents = <&topckgen CLK_TOP_UNIV48M>; ++}; ++ ++&nandc { ++ pinctrl-names = "default"; ++ pinctrl-0 = <¶llel_nand_pins>; ++ status = "disabled"; ++}; ++ ++&nor_flash { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi_nor_pins>; ++ status = "disabled"; ++ ++ flash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ }; ++}; ++ ++&pcie0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie0_pins>; ++ status = "okay"; ++}; ++ ++&pcie1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie1_pins>; ++ status = "okay"; ++}; ++ ++&pio { ++ /* Attention: GPIO 90 is used to switch between PCIe@1,0 and ++ * SATA functions. i.e. output-high: PCIe, output-low: SATA ++ */ ++ asm_sel { ++ gpio-hog; ++ gpios = <90 GPIO_ACTIVE_HIGH>; ++ output-high; ++ }; ++ ++ /* eMMC is shared pin with parallel NAND */ ++ emmc_pins_default: emmc-pins-default { ++ mux { ++ function = "emmc", "emmc_rst"; ++ groups = "emmc"; ++ }; ++ ++ /* "NDL0","NDL1","NDL2","NDL3","NDL4","NDL5","NDL6","NDL7", ++ * "NRB","NCLE" pins are used as DAT0,DAT1,DAT2,DAT3,DAT4, ++ * DAT5,DAT6,DAT7,CMD,CLK for eMMC respectively ++ */ ++ conf-cmd-dat { ++ pins = "NDL0", "NDL1", "NDL2", ++ "NDL3", "NDL4", "NDL5", ++ "NDL6", "NDL7", "NRB"; ++ input-enable; ++ bias-pull-up; ++ }; ++ ++ conf-clk { ++ pins = "NCLE"; ++ bias-pull-down; ++ }; ++ }; ++ ++ emmc_pins_uhs: emmc-pins-uhs { ++ mux { ++ function = "emmc"; ++ groups = "emmc"; ++ }; ++ ++ conf-cmd-dat { ++ pins = "NDL0", "NDL1", "NDL2", ++ "NDL3", "NDL4", "NDL5", ++ "NDL6", "NDL7", "NRB"; ++ input-enable; ++ drive-strength = <4>; ++ bias-pull-up; ++ }; ++ ++ conf-clk { ++ pins = "NCLE"; ++ drive-strength = <4>; ++ bias-pull-down; ++ }; ++ }; ++ ++ eth_pins: eth-pins { ++ mux { ++ function = "eth"; ++ groups = "mdc_mdio", "rgmii_via_gmac2"; ++ }; ++ }; ++ ++ i2c1_pins: i2c1-pins { ++ mux { ++ function = "i2c"; ++ groups = "i2c1_0"; ++ }; ++ }; ++ ++ i2c2_pins: i2c2-pins { ++ mux { ++ function = "i2c"; ++ groups = "i2c2_0"; ++ }; ++ }; ++ ++ i2s1_pins: i2s1-pins { ++ mux { ++ function = "i2s"; ++ groups = "i2s_out_mclk_bclk_ws", ++ "i2s1_in_data", ++ "i2s1_out_data"; ++ }; ++ ++ conf { ++ pins = "I2S1_IN", "I2S1_OUT", "I2S_BCLK", ++ "I2S_WS", "I2S_MCLK"; ++ drive-strength = <12>; ++ bias-pull-down; ++ }; ++ }; ++ ++ irrx_pins: irrx-pins { ++ mux { ++ function = "ir"; ++ groups = "ir_1_rx"; ++ }; ++ }; ++ ++ irtx_pins: irtx-pins { ++ mux { ++ function = "ir"; ++ groups = "ir_1_tx"; ++ }; ++ }; ++ ++ /* Parallel nand is shared pin with eMMC */ ++ parallel_nand_pins: parallel-nand-pins { ++ mux { ++ function = "flash"; ++ groups = "par_nand"; ++ }; ++ }; ++ ++ pcie0_pins: pcie0-pins { ++ mux { ++ function = "pcie"; ++ groups = "pcie0_pad_perst", ++ "pcie0_1_waken", ++ "pcie0_1_clkreq"; ++ }; ++ }; ++ ++ pcie1_pins: pcie1-pins { ++ mux { ++ function = "pcie"; ++ groups = "pcie1_pad_perst", ++ "pcie1_0_waken", ++ "pcie1_0_clkreq"; ++ }; ++ }; ++ ++ pmic_bus_pins: pmic-bus-pins { ++ mux { ++ function = "pmic"; ++ groups = "pmic_bus"; ++ }; ++ }; ++ ++ pwm7_pins: pwm1-2-pins { ++ mux { ++ function = "pwm"; ++ groups = "pwm_ch7_2"; ++ }; ++ }; ++ ++ wled_pins: wled-pins { ++ mux { ++ function = "led"; ++ groups = "wled"; ++ }; ++ }; ++ ++ sd0_pins_default: sd0-pins-default { ++ mux { ++ function = "sd"; ++ groups = "sd_0"; ++ }; ++ ++ /* "I2S2_OUT, "I2S4_IN"", "I2S3_IN", "I2S2_IN", ++ * "I2S4_OUT", "I2S3_OUT" are used as DAT0, DAT1, ++ * DAT2, DAT3, CMD, CLK for SD respectively. ++ */ ++ conf-cmd-data { ++ pins = "I2S2_OUT", "I2S4_IN", "I2S3_IN", ++ "I2S2_IN","I2S4_OUT"; ++ input-enable; ++ drive-strength = <8>; ++ bias-pull-up; ++ }; ++ conf-clk { ++ pins = "I2S3_OUT"; ++ drive-strength = <12>; ++ bias-pull-down; ++ }; ++ conf-cd { ++ pins = "TXD3"; ++ bias-pull-up; ++ }; ++ }; ++ ++ sd0_pins_uhs: sd0-pins-uhs { ++ mux { ++ function = "sd"; ++ groups = "sd_0"; ++ }; ++ ++ conf-cmd-data { ++ pins = "I2S2_OUT", "I2S4_IN", "I2S3_IN", ++ "I2S2_IN","I2S4_OUT"; ++ input-enable; ++ bias-pull-up; ++ }; ++ ++ conf-clk { ++ pins = "I2S3_OUT"; ++ bias-pull-down; ++ }; ++ }; ++ ++ /* Serial NAND is shared pin with SPI-NOR */ ++ serial_nand_pins: serial-nand-pins { ++ mux { ++ function = "flash"; ++ groups = "snfi"; ++ }; ++ }; ++ ++ spic0_pins: spic0-pins { ++ mux { ++ function = "spi"; ++ groups = "spic0_0"; ++ }; ++ }; ++ ++ spic1_pins: spic1-pins { ++ mux { ++ function = "spi"; ++ groups = "spic1_0"; ++ }; ++ }; ++ ++ /* SPI-NOR is shared pin with serial NAND */ ++ spi_nor_pins: spi-nor-pins { ++ mux { ++ function = "flash"; ++ groups = "spi_nor"; ++ }; ++ }; ++ ++ /* serial NAND is shared pin with SPI-NOR */ ++ serial_nand_pins: serial-nand-pins { ++ mux { ++ function = "flash"; ++ groups = "snfi"; ++ }; ++ }; ++ ++ uart0_pins: uart0-pins { ++ mux { ++ function = "uart"; ++ groups = "uart0_0_tx_rx" ; ++ }; ++ }; ++ ++ uart2_pins: uart2-pins { ++ mux { ++ function = "uart"; ++ groups = "uart2_1_tx_rx" ; ++ }; ++ }; ++ ++ watchdog_pins: watchdog-pins { ++ mux { ++ function = "watchdog"; ++ groups = "watchdog"; ++ }; ++ }; ++}; ++ ++&pwm { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm7_pins>; ++ status = "okay"; ++}; ++ ++&pwrap { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_bus_pins>; ++ ++ status = "okay"; ++}; ++ ++&sata { ++ status = "disable"; ++}; ++ ++&sata_phy { ++ status = "disable"; ++}; ++ ++&snfi { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&serial_nand_pins>; ++ status = "okay"; ++ ++ spi_nand@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "spi-nand"; ++ spi-max-frequency = <104000000>; ++ reg = <0>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "Preloader"; ++ reg = <0x00000 0x0080000>; ++ read-only; ++ }; ++ ++ partition@80000 { ++ label = "ATF"; ++ reg = <0x80000 0x0040000>; ++ }; ++ ++ partition@c0000 { ++ label = "Bootloader"; ++ reg = <0xc0000 0x0080000>; ++ }; ++ ++ partition@140000 { ++ label = "Config"; ++ reg = <0x140000 0x0080000>; ++ }; ++ ++ factory: partition@1c0000 { ++ label = "Factory"; ++ reg = <0x1c0000 0x0040000>; ++ }; ++ ++ partition@200000 { ++ label = "kernel"; ++ reg = <0x200000 0x400000>; ++ }; ++ ++ partition@600000 { ++ label = "ubi"; ++ reg = <0x600000 0x1C00000>; ++ }; ++ ++ partition@2200000 { ++ label = "User_data"; ++ reg = <0x2200000 0x4000000>; ++ }; ++ }; ++ }; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spic0_pins>; ++ status = "okay"; ++}; ++ ++&spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spic1_pins>; ++ status = "okay"; ++}; ++ ++&ssusb { ++ vusb33-supply = <®_3p3v>; ++ vbus-supply = <®_5v>; ++ status = "okay"; ++}; ++ ++&u3phy { ++ status = "okay"; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pins>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2_pins>; ++ status = "okay"; ++}; ++ ++&watchdog { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&watchdog_pins>; ++ status = "okay"; ++}; ++ ++&wmac { ++ mediatek,mtd-eeprom = <&factory 0x0000>; ++ status = "okay"; ++}; +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/Kconfig b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/Kconfig +new file mode 100644 +index 0000000000..d9e0230cf0 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/Kconfig +@@ -0,0 +1,3 @@ ++ ++config MT753X_GSW ++ tristate "Driver for the MediaTek MT753x switch" +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/Makefile b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/Makefile +new file mode 100644 +index 0000000000..7aae451cd1 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/Makefile +@@ -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 +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt7530.c b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt7530.c +new file mode 100644 +index 0000000000..6a94d0d2f4 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt7530.c +@@ -0,0 +1,631 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (c) 2018 MediaTek Inc. ++ * Author: Weijie Gao ++ */ ++ ++#include ++#include ++ ++#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 ++}; +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt7530.h b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt7530.h +new file mode 100644 +index 0000000000..40243d4e5a +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt7530.h +@@ -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_ */ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt7531.c b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt7531.c +new file mode 100644 +index 0000000000..7ebf09c102 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt7531.c +@@ -0,0 +1,918 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (c) 2018 MediaTek Inc. ++ * Author: Zhanguo Ju ++ */ ++ ++#include ++#include ++#include ++ ++#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 "); ++MODULE_DESCRIPTION("Driver for MediaTek MT753x Gigabit Switch"); +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt7531.h b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt7531.h +new file mode 100644 +index 0000000000..52c8a49fd3 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt7531.h +@@ -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_ */ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x.h b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x.h +new file mode 100644 +index 0000000000..27cd6f4f1e +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x.h +@@ -0,0 +1,213 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Copyright (c) 2018 MediaTek Inc. ++ * Author: Weijie Gao ++ */ ++ ++#ifndef _MT753X_H_ ++#define _MT753X_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef CONFIG_SWCONFIG ++#include ++#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_ */ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_common.c b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_common.c +new file mode 100644 +index 0000000000..4015ddf125 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_common.c +@@ -0,0 +1,90 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (c) 2018 MediaTek Inc. ++ * Author: Weijie Gao ++ */ ++ ++#include ++#include ++ ++#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); ++} +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_mdio.c b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_mdio.c +new file mode 100644 +index 0000000000..3e2e6d68ae +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_mdio.c +@@ -0,0 +1,597 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (c) 2018 MediaTek Inc. ++ * Author: Weijie Gao ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 "); ++MODULE_DESCRIPTION("Driver for MediaTek MT753x Gigabit Switch"); +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_nl.c b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_nl.c +new file mode 100644 +index 0000000000..ccde2c9209 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_nl.c +@@ -0,0 +1,382 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (c) 2018 MediaTek Inc. ++ * Author: Sirui Zhao ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#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); ++} +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_nl.h b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_nl.h +new file mode 100644 +index 0000000000..85dc9e791a +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_nl.h +@@ -0,0 +1,43 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Copyright (c) 2018 MediaTek Inc. ++ * Author: Sirui Zhao ++ */ ++ ++#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_ */ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_regs.h b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_regs.h +new file mode 100644 +index 0000000000..3f23ae200e +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_regs.h +@@ -0,0 +1,294 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Copyright (c) 2018 MediaTek Inc. ++ * Author: Weijie Gao ++ */ ++ ++#ifndef _MT753X_REGS_H_ ++#define _MT753X_REGS_H_ ++ ++#include ++ ++/* 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_ */ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_swconfig.c b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_swconfig.c +new file mode 100644 +index 0000000000..342ad576b2 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_swconfig.c +@@ -0,0 +1,510 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Copyright (c) 2018 MediaTek Inc. ++ * Author: Weijie Gao ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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); ++} +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_swconfig.h b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_swconfig.h +new file mode 100644 +index 0000000000..f000364ee8 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_swconfig.h +@@ -0,0 +1,29 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Copyright (c) 2018 MediaTek Inc. ++ * Author: Weijie Gao ++ */ ++ ++#ifndef _MT753X_SWCONFIG_H_ ++#define _MT753X_SWCONFIG_H_ ++ ++#ifdef CONFIG_SWCONFIG ++#include ++#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_ */ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_vlan.c b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_vlan.c +new file mode 100644 +index 0000000000..4d88eee8de +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_vlan.c +@@ -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]; ++ } ++} +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_vlan.h b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_vlan.h +new file mode 100644 +index 0000000000..c726b8eacd +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/mtk/mt753x/mt753x_vlan.h +@@ -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_ */ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/Makefile b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/Makefile +new file mode 100644 +index 0000000000..0f2891ead4 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/Makefile +@@ -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/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/modules.builtin b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/modules.builtin +new file mode 100644 +index 0000000000..961a70a150 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/modules.builtin +@@ -0,0 +1 @@ ++kernel/drivers/net/phy/rtk/rtl8367s_gsw.ko +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/acl.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/acl.c +new file mode 100644 +index 0000000000..75e5a5e740 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/acl.c +@@ -0,0 +1,2061 @@ ++/* ++ * 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 ACL module. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++CONST_T rtk_uint8 filter_templateField[RTL8367C_ACLTEMPLATENO][RTL8367C_ACLRULEFIELDNO] = { ++ {ACL_DMAC0, ACL_DMAC1, ACL_DMAC2, ACL_SMAC0, ACL_SMAC1, ACL_SMAC2, ACL_ETHERTYPE, ACL_FIELD_SELECT15}, ++ {ACL_IP4SIP0, ACL_IP4SIP1, ACL_IP4DIP0, ACL_IP4DIP1, ACL_FIELD_SELECT13, ACL_FIELD_SELECT14, ACL_FIELD_SELECT02, ACL_FIELD_SELECT15}, ++ {ACL_IP6SIP0WITHIPV4, ACL_IP6SIP1WITHIPV4,ACL_FIELD_SELECT03, ACL_FIELD_SELECT04, ACL_FIELD_SELECT05, ACL_FIELD_SELECT06, ACL_FIELD_SELECT07, ACL_FIELD_SELECT08}, ++ {ACL_IP6DIP0WITHIPV4, ACL_IP6DIP1WITHIPV4,ACL_FIELD_SELECT09, ACL_FIELD_SELECT10, ACL_FIELD_SELECT11, ACL_FIELD_SELECT12, ACL_FIELD_SELECT13, ACL_FIELD_SELECT14}, ++ {ACL_VIDRANGE, ACL_IPRANGE, ACL_PORTRANGE, ACL_CTAG, ACL_STAG, ACL_FIELD_SELECT13, ACL_FIELD_SELECT14, ACL_FIELD_SELECT15} ++}; ++ ++CONST_T rtk_uint8 filter_advanceCaretagField[RTL8367C_ACLTEMPLATENO][2] = { ++ {TRUE, 7}, ++ {TRUE, 7}, ++ {FALSE, 0}, ++ {FALSE, 0}, ++ {TRUE, 7}, ++}; ++ ++ ++CONST_T rtk_uint8 filter_fieldTemplateIndex[FILTER_FIELD_END][RTK_FILTER_FIELD_USED_MAX] = { ++ {0x00, 0x01,0x02}, ++ {0x03, 0x04,0x05}, ++ {0x06}, ++ {0x43}, ++ {0x44}, ++ {0x10, 0x11}, ++ {0x12, 0x13}, ++ {0x24}, ++ {0x25}, ++ {0x35}, ++ {0x35}, ++ {0x20, 0x21,0x22,0x23}, ++ {0x30, 0x31,0x32,0x33}, ++ {0x26}, ++ {0x27}, ++ {0x14}, ++ {0x15}, ++ {0x16}, ++ {0x14}, ++ {0x15}, ++ {0x14}, ++ {0x14}, ++ {0x14}, ++ ++ {0x40}, ++ {0x41}, ++ {0x42}, ++ ++ {0x14}, ++ {0x15}, ++ {0x16}, ++ {0x22}, ++ {0x23}, ++ {0x24}, ++ {0x25}, ++ {0x26}, ++ {0x27}, ++ {0x32}, ++ {0x33}, ++ {0x34}, ++ {0x35}, ++ {0x36}, ++ {0x37}, ++ {0x47}, ++ ++ {0xFF} /* Pattern Match */ ++}; ++ ++CONST_T rtk_uint8 filter_fieldSize[FILTER_FIELD_END] = { ++ 3, 3, 1, 1, 1, ++ 2, 2, 1, 1, 1, 1, 4, 4, 1, 1, ++ 1, 1, 1, 1, 1, 1, 1, 1, ++ 1, 1, 1, ++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ++ 8 ++}; ++ ++CONST_T rtk_uint16 field_selector[RTL8367C_FIELDSEL_FORMAT_NUMBER][2] = ++{ ++ {FIELDSEL_FORMAT_DEFAULT, 0}, /* Field Selector 0 */ ++ {FIELDSEL_FORMAT_DEFAULT, 0}, /* Field Selector 1 */ ++ {FIELDSEL_FORMAT_IPPAYLOAD, 12}, /* Field Selector 2 */ ++ {FIELDSEL_FORMAT_IPV6, 10}, /* Field Selector 3 */ ++ {FIELDSEL_FORMAT_IPV6, 8}, /* Field Selector 4 */ ++ {FIELDSEL_FORMAT_IPV4, 0}, /* Field Selector 5 */ ++ {FIELDSEL_FORMAT_IPV4, 8}, /* Field Selector 6 */ ++ {FIELDSEL_FORMAT_IPV6, 0}, /* Field Selector 7 */ ++ {FIELDSEL_FORMAT_IPV6, 6}, /* Field Selector 8 */ ++ {FIELDSEL_FORMAT_IPV6, 26}, /* Field Selector 9 */ ++ {FIELDSEL_FORMAT_IPV6, 24}, /* Field Selector 10 */ ++ {FIELDSEL_FORMAT_DEFAULT, 0}, /* Field Selector 11 */ ++ {FIELDSEL_FORMAT_IPV4, 6}, /* Field Selector 12 */ ++ {FIELDSEL_FORMAT_IPPAYLOAD, 0}, /* Field Selector 13 */ ++ {FIELDSEL_FORMAT_IPPAYLOAD, 2}, /* Field Selector 14 */ ++ {FIELDSEL_FORMAT_DEFAULT, 0} /* Field Selector 15 */ ++}; ++ ++ ++static rtk_api_ret_t _rtk_filter_igrAcl_writeDataField(rtl8367c_aclrule *aclRule, rtk_filter_field_t *fieldPtr); ++ ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_filter_igrAcl_init(void) ++{ ++ rtl8367c_acltemplate_t aclTemp; ++ rtk_uint32 i, j; ++ rtk_api_ret_t ret; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ((ret = rtk_filter_igrAcl_cfg_delAll()) != RT_ERR_OK) ++ return ret; ++ ++ for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) ++ { ++ for(j = 0; j < RTL8367C_ACLRULEFIELDNO;j++) ++ aclTemp.field[j] = filter_templateField[i][j]; ++ ++ if ((ret = rtl8367c_setAsicAclTemplate(i, &aclTemp)) != RT_ERR_OK) ++ return ret; ++ } ++ ++ for(i = 0; i < RTL8367C_FIELDSEL_FORMAT_NUMBER; i++) ++ { ++ if ((ret = rtl8367c_setAsicFieldSelector(i, field_selector[i][0], field_selector[i][1])) != RT_ERR_OK) ++ return ret; ++ } ++ ++ RTK_SCAN_ALL_PHY_PORTMASK(i) ++ { ++ if ((ret = rtl8367c_setAsicAcl(i, TRUE)) != RT_ERR_OK) ++ return ret; ++ ++ if ((ret = rtl8367c_setAsicAclUnmatchedPermit(i, TRUE)) != RT_ERR_OK) ++ return ret; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_filter_igrAcl_field_add(rtk_filter_cfg_t* pFilter_cfg, rtk_filter_field_t* pFilter_field) ++{ ++ rtk_uint32 i; ++ rtk_filter_field_t *tailPtr; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pFilter_cfg || NULL == pFilter_field) ++ return RT_ERR_NULL_POINTER; ++ ++ if(pFilter_field->fieldType >= FILTER_FIELD_END) ++ return RT_ERR_ENTRY_INDEX; ++ ++ ++ if(0 == pFilter_field->fieldTemplateNo) ++ { ++ pFilter_field->fieldTemplateNo = filter_fieldSize[pFilter_field->fieldType]; ++ ++ for(i = 0; i < pFilter_field->fieldTemplateNo; i++) ++ { ++ pFilter_field->fieldTemplateIdx[i] = filter_fieldTemplateIndex[pFilter_field->fieldType][i]; ++ } ++ } ++ ++ if(NULL == pFilter_cfg->fieldHead) ++ { ++ pFilter_cfg->fieldHead = pFilter_field; ++ } ++ else ++ { ++ if (pFilter_cfg->fieldHead->next == NULL) ++ { ++ pFilter_cfg->fieldHead->next = pFilter_field; ++ } ++ else ++ { ++ tailPtr = pFilter_cfg->fieldHead->next; ++ while( tailPtr->next != NULL) ++ { ++ tailPtr = tailPtr->next; ++ } ++ tailPtr->next = pFilter_field; ++ } ++ } ++ ++ return RT_ERR_OK; ++} ++ ++static rtk_api_ret_t _rtk_filter_igrAcl_writeDataField(rtl8367c_aclrule *aclRule, rtk_filter_field_t *fieldPtr) ++{ ++ rtk_uint32 i, tempIdx,fieldIdx, ipValue, ipMask; ++ rtk_uint32 ip6addr[RTK_IPV6_ADDR_WORD_LENGTH]; ++ rtk_uint32 ip6mask[RTK_IPV6_ADDR_WORD_LENGTH]; ++ ++ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) ++ { ++ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; ++ ++ aclRule[tempIdx].valid = TRUE; ++ } ++ ++ switch (fieldPtr->fieldType) ++ { ++ /* use DMAC structure as representative for mac structure */ ++ case FILTER_FIELD_DMAC: ++ case FILTER_FIELD_SMAC: ++ ++ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) ++ { ++ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; ++ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; ++ ++ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.mac.value.octet[5 - i*2] | (fieldPtr->filter_pattern_union.mac.value.octet[5 - (i*2 + 1)] << 8); ++ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.mac.mask.octet[5 - i*2] | (fieldPtr->filter_pattern_union.mac.mask.octet[5 - (i*2 + 1)] << 8); ++ } ++ break; ++ case FILTER_FIELD_ETHERTYPE: ++ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) ++ { ++ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; ++ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; ++ ++ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.etherType.value; ++ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.etherType.mask; ++ } ++ break; ++ case FILTER_FIELD_IPV4_SIP: ++ case FILTER_FIELD_IPV4_DIP: ++ ++ ipValue = fieldPtr->filter_pattern_union.sip.value; ++ ipMask = fieldPtr->filter_pattern_union.sip.mask; ++ ++ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) ++ { ++ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; ++ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; ++ ++ aclRule[tempIdx].data_bits.field[fieldIdx] = (0xFFFF & (ipValue >> (i*16))); ++ aclRule[tempIdx].care_bits.field[fieldIdx] = (0xFFFF & (ipMask >> (i*16))); ++ } ++ break; ++ case FILTER_FIELD_IPV4_TOS: ++ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) ++ { ++ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; ++ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; ++ ++ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.ipTos.value & 0xFF; ++ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.ipTos.mask & 0xFF; ++ } ++ break; ++ case FILTER_FIELD_IPV4_PROTOCOL: ++ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) ++ { ++ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; ++ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; ++ ++ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.protocol.value & 0xFF; ++ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.protocol.mask & 0xFF; ++ } ++ break; ++ case FILTER_FIELD_IPV6_SIPV6: ++ case FILTER_FIELD_IPV6_DIPV6: ++ for(i = 0; i < RTK_IPV6_ADDR_WORD_LENGTH; i++) ++ { ++ ip6addr[i] = fieldPtr->filter_pattern_union.sipv6.value.addr[i]; ++ ip6mask[i] = fieldPtr->filter_pattern_union.sipv6.mask.addr[i]; ++ } ++ ++ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) ++ { ++ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; ++ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; ++ ++ if(i < 2) ++ { ++ aclRule[tempIdx].data_bits.field[fieldIdx] = ((ip6addr[0] & (0xFFFF << (i * 16))) >> (i * 16)); ++ aclRule[tempIdx].care_bits.field[fieldIdx] = ((ip6mask[0] & (0xFFFF << (i * 16))) >> (i * 16)); ++ } ++ else ++ { ++ /*default acl template for ipv6 address supports MSB 32-bits and LSB 32-bits only*/ ++ aclRule[tempIdx].data_bits.field[fieldIdx] = ((ip6addr[3] & (0xFFFF << ((i&1) * 16))) >> ((i&1) * 16)); ++ aclRule[tempIdx].care_bits.field[fieldIdx] = ((ip6mask[3] & (0xFFFF << ((i&1) * 16))) >> ((i&1) * 16)); ++ } ++ } ++ ++ break; ++ case FILTER_FIELD_CTAG: ++ case FILTER_FIELD_STAG: ++ ++ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) ++ { ++ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; ++ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; ++ ++ aclRule[tempIdx].data_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.l2tag.pri.value << 13) | (fieldPtr->filter_pattern_union.l2tag.cfi.value << 12) | fieldPtr->filter_pattern_union.l2tag.vid.value; ++ aclRule[tempIdx].care_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.l2tag.pri.mask << 13) | (fieldPtr->filter_pattern_union.l2tag.cfi.mask << 12) | fieldPtr->filter_pattern_union.l2tag.vid.mask; ++ } ++ break; ++ case FILTER_FIELD_IPV4_FLAG: ++ ++ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) ++ { ++ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; ++ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; ++ ++ aclRule[tempIdx].data_bits.field[fieldIdx] &= 0x1FFF; ++ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.xf.value << 15); ++ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.df.value << 14); ++ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.mf.value << 13); ++ ++ aclRule[tempIdx].care_bits.field[fieldIdx] &= 0x1FFF; ++ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.xf.mask << 15); ++ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.df.mask << 14); ++ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.ipFlag.mf.mask << 13); ++ } ++ ++ break; ++ case FILTER_FIELD_IPV4_OFFSET: ++ ++ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) ++ { ++ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; ++ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; ++ ++ aclRule[tempIdx].data_bits.field[fieldIdx] &= 0xE000; ++ aclRule[tempIdx].data_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.inData.value; ++ ++ aclRule[tempIdx].care_bits.field[fieldIdx] &= 0xE000; ++ aclRule[tempIdx].care_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.inData.mask; ++ } ++ ++ break; ++ ++ case FILTER_FIELD_IPV6_TRAFFIC_CLASS: ++ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) ++ { ++ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; ++ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; ++ ++ ++ aclRule[tempIdx].data_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.inData.value << 4)&0x0FF0; ++ aclRule[tempIdx].care_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.inData.mask << 4)&0x0FF0; ++ } ++ break; ++ case FILTER_FIELD_IPV6_NEXT_HEADER: ++ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) ++ { ++ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; ++ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; ++ ++ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.value << 8; ++ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.mask << 8; ++ } ++ break; ++ case FILTER_FIELD_TCP_SPORT: ++ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) ++ { ++ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; ++ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; ++ ++ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpSrcPort.value; ++ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpSrcPort.mask; ++ } ++ break; ++ case FILTER_FIELD_TCP_DPORT: ++ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) ++ { ++ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; ++ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; ++ ++ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpDstPort.value; ++ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.tcpDstPort.mask; ++ } ++ break; ++ case FILTER_FIELD_TCP_FLAG: ++ ++ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) ++ { ++ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; ++ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; ++ ++ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.cwr.value << 7); ++ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ece.value << 6); ++ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.urg.value << 5); ++ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ack.value << 4); ++ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.psh.value << 3); ++ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.rst.value << 2); ++ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.syn.value << 1); ++ aclRule[tempIdx].data_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.tcpFlag.fin.value; ++ ++ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.cwr.mask << 7); ++ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ece.mask << 6); ++ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.urg.mask << 5); ++ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.ack.mask << 4); ++ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.psh.mask << 3); ++ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.rst.mask << 2); ++ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.tcpFlag.syn.mask << 1); ++ aclRule[tempIdx].care_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.tcpFlag.fin.mask; ++ } ++ break; ++ case FILTER_FIELD_UDP_SPORT: ++ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) ++ { ++ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; ++ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; ++ ++ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpSrcPort.value; ++ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpSrcPort.mask; ++ } ++ break; ++ case FILTER_FIELD_UDP_DPORT: ++ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) ++ { ++ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; ++ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; ++ ++ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpDstPort.value; ++ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.udpDstPort.mask; ++ } ++ break; ++ case FILTER_FIELD_ICMP_CODE: ++ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) ++ { ++ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; ++ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; ++ ++ aclRule[tempIdx].data_bits.field[fieldIdx] &= 0xFF00; ++ aclRule[tempIdx].data_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.icmpCode.value; ++ aclRule[tempIdx].care_bits.field[fieldIdx] &= 0xFF00; ++ aclRule[tempIdx].care_bits.field[fieldIdx] |= fieldPtr->filter_pattern_union.icmpCode.mask; ++ } ++ break; ++ case FILTER_FIELD_ICMP_TYPE: ++ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) ++ { ++ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; ++ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; ++ ++ aclRule[tempIdx].data_bits.field[fieldIdx] &= 0x00FF; ++ aclRule[tempIdx].data_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.icmpType.value << 8); ++ aclRule[tempIdx].care_bits.field[fieldIdx] &= 0x00FF; ++ aclRule[tempIdx].care_bits.field[fieldIdx] |= (fieldPtr->filter_pattern_union.icmpType.mask << 8); ++ } ++ break; ++ case FILTER_FIELD_IGMP_TYPE: ++ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) ++ { ++ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; ++ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; ++ ++ aclRule[tempIdx].data_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.igmpType.value << 8); ++ aclRule[tempIdx].care_bits.field[fieldIdx] = (fieldPtr->filter_pattern_union.igmpType.mask << 8); ++ } ++ break; ++ case FILTER_FIELD_PATTERN_MATCH: ++ for(i = 0; i < fieldPtr->fieldTemplateNo; i++) ++ { ++ tempIdx = (fieldPtr->fieldTemplateIdx[i] & 0xF0) >> 4; ++ fieldIdx = fieldPtr->fieldTemplateIdx[i] & 0x0F; ++ ++ aclRule[tempIdx].data_bits.field[fieldIdx] = ((fieldPtr->filter_pattern_union.pattern.value[i/2] >> (16 * (i%2))) & 0x0000FFFF ); ++ aclRule[tempIdx].care_bits.field[fieldIdx] = ((fieldPtr->filter_pattern_union.pattern.mask[i/2] >> (16 * (i%2))) & 0x0000FFFF ); ++ } ++ break; ++ case FILTER_FIELD_VID_RANGE: ++ case FILTER_FIELD_IP_RANGE: ++ case FILTER_FIELD_PORT_RANGE: ++ default: ++ tempIdx = (fieldPtr->fieldTemplateIdx[0] & 0xF0) >> 4; ++ fieldIdx = fieldPtr->fieldTemplateIdx[0] & 0x0F; ++ ++ aclRule[tempIdx].data_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.value; ++ aclRule[tempIdx].care_bits.field[fieldIdx] = fieldPtr->filter_pattern_union.inData.mask; ++ break; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++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* pFilter_action, rtk_filter_number_t *ruleNum) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 careTagData, careTagMask; ++ rtk_uint32 i,vidx, svidx, actType, ruleId; ++ rtk_uint32 aclActCtrl; ++ rtk_uint32 cpuPort; ++ rtk_filter_field_t* fieldPtr; ++ rtl8367c_aclrule aclRule[RTL8367C_ACLTEMPLATENO]; ++ rtl8367c_aclrule tempRule; ++ rtl8367c_acl_act_t aclAct; ++ rtk_uint32 noRulesAdd; ++ rtk_uint32 portmask; ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(filter_id > RTL8367C_ACLRULEMAX ) ++ return RT_ERR_ENTRY_INDEX; ++ ++ if((NULL == pFilter_cfg) || (NULL == pFilter_action) || (NULL == ruleNum)) ++ return RT_ERR_NULL_POINTER; ++ ++ fieldPtr = pFilter_cfg->fieldHead; ++ ++ /* init RULE */ ++ for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) ++ { ++ memset(&aclRule[i], 0, sizeof(rtl8367c_aclrule)); ++ ++ aclRule[i].data_bits.type= i; ++ aclRule[i].care_bits.type= 0x7; ++ } ++ ++ while(NULL != fieldPtr) ++ { ++ _rtk_filter_igrAcl_writeDataField(aclRule, fieldPtr); ++ ++ fieldPtr = fieldPtr->next; ++ } ++ ++ /*set care tag mask in User Defined Field 15*/ ++ /*Follow care tag should not be used while ACL template and User defined fields are fully control by system designer*/ ++ /*those advanced packet type care tag is used in default template design structure only*/ ++ careTagData = 0; ++ careTagMask = 0; ++ ++ for(i = CARE_TAG_TCP; i < CARE_TAG_END; i++) ++ { ++ if(pFilter_cfg->careTag.tagType[i].mask) ++ careTagMask = careTagMask | (1 << (i-CARE_TAG_TCP)); ++ ++ if(pFilter_cfg->careTag.tagType[i].value) ++ careTagData = careTagData | (1 << (i-CARE_TAG_TCP)); ++ } ++ ++ if(careTagData || careTagMask) ++ { ++ i = 0; ++ while(i < RTL8367C_ACLTEMPLATENO) ++ { ++ if(aclRule[i].valid == 1 && filter_advanceCaretagField[i][0] == TRUE) ++ { ++ ++ aclRule[i].data_bits.field[filter_advanceCaretagField[i][1]] = careTagData & 0xFFFF; ++ aclRule[i].care_bits.field[filter_advanceCaretagField[i][1]] = careTagMask & 0xFFFF; ++ break; ++ } ++ i++; ++ } ++ /*none of previous used template containing field 15*/ ++ if(i == RTL8367C_ACLTEMPLATENO) ++ { ++ i = 0; ++ while(i < RTL8367C_ACLTEMPLATENO) ++ { ++ if(filter_advanceCaretagField[i][0] == TRUE) ++ { ++ aclRule[i].data_bits.field[filter_advanceCaretagField[i][1]] = careTagData & 0xFFFF; ++ aclRule[i].care_bits.field[filter_advanceCaretagField[i][1]] = careTagMask & 0xFFFF; ++ aclRule[i].valid = 1; ++ break; ++ } ++ i++; ++ } ++ } ++ } ++ ++ /*Check rule number*/ ++ noRulesAdd = 0; ++ for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) ++ { ++ if(1 == aclRule[i].valid) ++ { ++ noRulesAdd ++; ++ } ++ } ++ ++ *ruleNum = noRulesAdd; ++ ++ if((filter_id + noRulesAdd - 1) > RTL8367C_ACLRULEMAX) ++ { ++ return RT_ERR_ENTRY_INDEX; ++ } ++ ++ /*set care tag mask in TAG Indicator*/ ++ careTagData = 0; ++ careTagMask = 0; ++ ++ for(i = 0; i <= CARE_TAG_IPV6;i++) ++ { ++ if(0 == pFilter_cfg->careTag.tagType[i].mask ) ++ { ++ careTagMask &= ~(1 << i); ++ } ++ else ++ { ++ careTagMask |= (1 << i); ++ if(0 == pFilter_cfg->careTag.tagType[i].value ) ++ careTagData &= ~(1 << i); ++ else ++ careTagData |= (1 << i); ++ } ++ } ++ ++ for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) ++ { ++ aclRule[i].data_bits.tag_exist = (careTagData) & ACL_RULE_CARETAG_MASK; ++ aclRule[i].care_bits.tag_exist = (careTagMask) & ACL_RULE_CARETAG_MASK; ++ } ++ ++ RTK_CHK_PORTMASK_VALID(&pFilter_cfg->activeport.value); ++ RTK_CHK_PORTMASK_VALID(&pFilter_cfg->activeport.mask); ++ ++ for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) ++ { ++ if(TRUE == aclRule[i].valid) ++ { ++ if(rtk_switch_portmask_L2P_get(&pFilter_cfg->activeport.value, &portmask) != RT_ERR_OK) ++ return RT_ERR_PORT_MASK; ++ ++ aclRule[i].data_bits.active_portmsk = portmask; ++ ++ if(rtk_switch_portmask_L2P_get(&pFilter_cfg->activeport.mask, &portmask) != RT_ERR_OK) ++ return RT_ERR_PORT_MASK; ++ ++ aclRule[i].care_bits.active_portmsk = portmask; ++ } ++ } ++ ++ if(pFilter_cfg->invert >= FILTER_INVERT_END ) ++ return RT_ERR_INPUT; ++ ++ ++ /*Last action gets high priority if actions are the same*/ ++ memset(&aclAct, 0, sizeof(rtl8367c_acl_act_t)); ++ aclActCtrl = 0; ++ for(actType = 0; actType < FILTER_ENACT_END; actType ++) ++ { ++ if(pFilter_action->actEnable[actType]) ++ { ++ switch (actType) ++ { ++ case FILTER_ENACT_CVLAN_INGRESS: ++ if(pFilter_action->filterCvlanVid > RTL8367C_EVIDMAX) ++ return RT_ERR_INPUT; ++ ++ if((retVal = rtk_vlan_checkAndCreateMbr(pFilter_action->filterCvlanVid, &vidx)) != RT_ERR_OK) ++ { ++ return retVal; ++ } ++ aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType); ++ aclAct.cvidx_cact = vidx; ++ ++ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) ++ { ++ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY) ++ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; ++ } ++ else ++ { ++ aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY; ++ } ++ ++ aclActCtrl |= FILTER_ENACT_CVLAN_MASK; ++ break; ++ case FILTER_ENACT_CVLAN_EGRESS: ++ if(pFilter_action->filterCvlanVid > RTL8367C_EVIDMAX) ++ return RT_ERR_INPUT; ++ ++ if((retVal = rtk_vlan_checkAndCreateMbr(pFilter_action->filterCvlanVid, &vidx)) != RT_ERR_OK) ++ return retVal; ++ ++ aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType); ++ aclAct.cvidx_cact = vidx; ++ ++ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) ++ { ++ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY) ++ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; ++ } ++ else ++ { ++ aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY; ++ } ++ ++ aclActCtrl |= FILTER_ENACT_CVLAN_MASK; ++ break; ++ case FILTER_ENACT_CVLAN_SVID: ++ ++ aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType); ++ ++ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) ++ { ++ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY) ++ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; ++ } ++ else ++ { ++ aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY; ++ } ++ ++ aclActCtrl |= FILTER_ENACT_CVLAN_MASK; ++ break; ++ case FILTER_ENACT_POLICING_1: ++ if(pFilter_action->filterPolicingIdx[1] >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM)) ++ return RT_ERR_INPUT; ++ ++ aclAct.cact = FILTER_ENACT_CVLAN_TYPE(actType); ++ aclAct.cvidx_cact = pFilter_action->filterPolicingIdx[1]; ++ ++ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) ++ { ++ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_TAGONLY) ++ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; ++ } ++ else ++ { ++ aclAct.cact_ext = FILTER_ENACT_CACTEXT_VLANONLY; ++ } ++ ++ aclActCtrl |= FILTER_ENACT_CVLAN_MASK; ++ break; ++ ++ case FILTER_ENACT_SVLAN_INGRESS: ++ case FILTER_ENACT_SVLAN_EGRESS: ++ ++ if((retVal = rtk_svlan_checkAndCreateMbr(pFilter_action->filterSvlanVid, &svidx)) != RT_ERR_OK) ++ return retVal; ++ ++ aclAct.sact = FILTER_ENACT_SVLAN_TYPE(actType); ++ aclAct.svidx_sact = svidx; ++ aclActCtrl |= FILTER_ENACT_SVLAN_MASK; ++ break; ++ case FILTER_ENACT_SVLAN_CVID: ++ ++ aclAct.sact = FILTER_ENACT_SVLAN_TYPE(actType); ++ aclActCtrl |= FILTER_ENACT_SVLAN_MASK; ++ break; ++ case FILTER_ENACT_POLICING_2: ++ if(pFilter_action->filterPolicingIdx[2] >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM)) ++ return RT_ERR_INPUT; ++ ++ aclAct.sact = FILTER_ENACT_SVLAN_TYPE(actType); ++ aclAct.svidx_sact = pFilter_action->filterPolicingIdx[2]; ++ aclActCtrl |= FILTER_ENACT_SVLAN_MASK; ++ break; ++ case FILTER_ENACT_POLICING_0: ++ if(pFilter_action->filterPolicingIdx[0] >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM)) ++ return RT_ERR_INPUT; ++ ++ aclAct.aclmeteridx = pFilter_action->filterPolicingIdx[0]; ++ aclActCtrl |= FILTER_ENACT_POLICING_MASK; ++ break; ++ case FILTER_ENACT_PRIORITY: ++ case FILTER_ENACT_1P_REMARK: ++ if(pFilter_action->filterPriority > RTL8367C_PRIMAX) ++ return RT_ERR_INPUT; ++ ++ aclAct.priact = FILTER_ENACT_PRI_TYPE(actType); ++ aclAct.pridx = pFilter_action->filterPriority; ++ aclActCtrl |= FILTER_ENACT_PRIORITY_MASK; ++ break; ++ case FILTER_ENACT_DSCP_REMARK: ++ if(pFilter_action->filterPriority > RTL8367C_DSCPMAX) ++ return RT_ERR_INPUT; ++ ++ aclAct.priact = FILTER_ENACT_PRI_TYPE(actType); ++ aclAct.pridx = pFilter_action->filterPriority; ++ aclActCtrl |= FILTER_ENACT_PRIORITY_MASK; ++ break; ++ case FILTER_ENACT_POLICING_3: ++ if(pFilter_action->filterPriority >= (RTK_METER_NUM + RTL8367C_MAX_LOG_CNT_NUM)) ++ return RT_ERR_INPUT; ++ ++ aclAct.priact = FILTER_ENACT_PRI_TYPE(actType); ++ aclAct.pridx = pFilter_action->filterPolicingIdx[3]; ++ aclActCtrl |= FILTER_ENACT_PRIORITY_MASK; ++ break; ++ case FILTER_ENACT_DROP: ++ ++ aclAct.fwdact = FILTER_ENACT_FWD_TYPE(FILTER_ENACT_REDIRECT); ++ aclAct.fwdact_ext = FALSE; ++ ++ aclAct.fwdpmask = 0; ++ aclActCtrl |= FILTER_ENACT_FWD_MASK; ++ break; ++ case FILTER_ENACT_REDIRECT: ++ RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask); ++ ++ aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType); ++ aclAct.fwdact_ext = FALSE; ++ ++ if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK) ++ return RT_ERR_PORT_MASK; ++ aclAct.fwdpmask = portmask; ++ ++ aclActCtrl |= FILTER_ENACT_FWD_MASK; ++ break; ++ ++ case FILTER_ENACT_ADD_DSTPORT: ++ RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask); ++ ++ aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType); ++ aclAct.fwdact_ext = FALSE; ++ ++ if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK) ++ return RT_ERR_PORT_MASK; ++ aclAct.fwdpmask = portmask; ++ ++ aclActCtrl |= FILTER_ENACT_FWD_MASK; ++ break; ++ case FILTER_ENACT_MIRROR: ++ RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask); ++ ++ aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType); ++ aclAct.cact_ext = FALSE; ++ ++ if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK) ++ return RT_ERR_PORT_MASK; ++ aclAct.fwdpmask = portmask; ++ ++ aclActCtrl |= FILTER_ENACT_FWD_MASK; ++ break; ++ case FILTER_ENACT_TRAP_CPU: ++ ++ aclAct.fwdact = FILTER_ENACT_FWD_TYPE(actType); ++ aclAct.fwdact_ext = FALSE; ++ ++ aclActCtrl |= FILTER_ENACT_FWD_MASK; ++ break; ++ case FILTER_ENACT_COPY_CPU: ++ if((retVal = rtl8367c_getAsicCputagTrapPort(&cpuPort)) != RT_ERR_OK) ++ return retVal; ++ ++ aclAct.fwdact = FILTER_ENACT_FWD_TYPE(FILTER_ENACT_MIRROR); ++ aclAct.fwdact_ext = FALSE; ++ ++ aclAct.fwdpmask = 1 << cpuPort; ++ aclActCtrl |= FILTER_ENACT_FWD_MASK; ++ break; ++ case FILTER_ENACT_ISOLATION: ++ RTK_CHK_PORTMASK_VALID(&pFilter_action->filterPortmask); ++ ++ aclAct.fwdact_ext = TRUE; ++ ++ if(rtk_switch_portmask_L2P_get(&pFilter_action->filterPortmask, &portmask) != RT_ERR_OK) ++ return RT_ERR_PORT_MASK; ++ aclAct.fwdpmask = portmask; ++ ++ aclActCtrl |= FILTER_ENACT_FWD_MASK; ++ break; ++ ++ case FILTER_ENACT_INTERRUPT: ++ ++ aclAct.aclint = TRUE; ++ aclActCtrl |= FILTER_ENACT_INTGPIO_MASK; ++ break; ++ case FILTER_ENACT_GPO: ++ ++ aclAct.gpio_en = TRUE; ++ aclAct.gpio_pin = pFilter_action->filterPin; ++ aclActCtrl |= FILTER_ENACT_INTGPIO_MASK; ++ break; ++ case FILTER_ENACT_EGRESSCTAG_TAG: ++ ++ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) ++ { ++ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY) ++ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; ++ } ++ else ++ { ++ aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY; ++ } ++ aclAct.tag_fmt = FILTER_CTAGFMT_TAG; ++ aclActCtrl |= FILTER_ENACT_CVLAN_MASK; ++ break; ++ case FILTER_ENACT_EGRESSCTAG_UNTAG: ++ ++ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) ++ { ++ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY) ++ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; ++ } ++ else ++ { ++ aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY; ++ } ++ aclAct.tag_fmt = FILTER_CTAGFMT_UNTAG; ++ aclActCtrl |= FILTER_ENACT_CVLAN_MASK; ++ break; ++ case FILTER_ENACT_EGRESSCTAG_KEEP: ++ ++ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) ++ { ++ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY) ++ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; ++ } ++ else ++ { ++ aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY; ++ } ++ aclAct.tag_fmt = FILTER_CTAGFMT_KEEP; ++ aclActCtrl |= FILTER_ENACT_CVLAN_MASK; ++ break; ++ case FILTER_ENACT_EGRESSCTAG_KEEPAND1PRMK: ++ ++ if(aclActCtrl &(FILTER_ENACT_CVLAN_MASK)) ++ { ++ if(aclAct.cact_ext == FILTER_ENACT_CACTEXT_VLANONLY) ++ aclAct.cact_ext = FILTER_ENACT_CACTEXT_BOTHVLANTAG; ++ } ++ else ++ { ++ aclAct.cact_ext = FILTER_ENACT_CACTEXT_TAGONLY; ++ } ++ aclAct.tag_fmt = FILTER_CTAGFMT_KEEP1PRMK; ++ aclActCtrl |= FILTER_ENACT_CVLAN_MASK; ++ break; ++ default: ++ return RT_ERR_FILTER_INACL_ACT_NOT_SUPPORT; ++ } ++ } ++ } ++ ++ ++ /*check if free ACL rules are enough*/ ++ for(i = filter_id; i < (filter_id + noRulesAdd); i++) ++ { ++ if((retVal = rtl8367c_getAsicAclRule(i, &tempRule)) != RT_ERR_OK ) ++ return retVal; ++ ++ if(tempRule.valid == TRUE) ++ { ++ return RT_ERR_TBL_FULL; ++ } ++ } ++ ++ ruleId = 0; ++ for(i = 0; i < RTL8367C_ACLTEMPLATENO; i++) ++ { ++ if(aclRule[i].valid == TRUE) ++ { ++ /* write ACL action control */ ++ if((retVal = rtl8367c_setAsicAclActCtrl(filter_id + ruleId, aclActCtrl)) != RT_ERR_OK ) ++ return retVal; ++ /* write ACL action */ ++ if((retVal = rtl8367c_setAsicAclAct(filter_id + ruleId, &aclAct)) != RT_ERR_OK ) ++ return retVal; ++ ++ /* write ACL not */ ++ if((retVal = rtl8367c_setAsicAclNot(filter_id + ruleId, pFilter_cfg->invert)) != RT_ERR_OK ) ++ return retVal; ++ /* write ACL rule */ ++ if((retVal = rtl8367c_setAsicAclRule(filter_id + ruleId, &aclRule[i])) != RT_ERR_OK ) ++ return retVal; ++ ++ /* only the first rule will be written with input action control, aclActCtrl of other rules will be zero */ ++ aclActCtrl = 0; ++ memset(&aclAct, 0, sizeof(rtl8367c_acl_act_t)); ++ ++ ruleId ++; ++ } ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_filter_igrAcl_cfg_del(rtk_filter_id_t filter_id) ++{ ++ rtl8367c_aclrule initRule; ++ rtl8367c_acl_act_t initAct; ++ rtk_api_ret_t ret; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(filter_id > RTL8367C_ACLRULEMAX ) ++ return RT_ERR_FILTER_ENTRYIDX; ++ ++ memset(&initRule, 0, sizeof(rtl8367c_aclrule)); ++ memset(&initAct, 0, sizeof(rtl8367c_acl_act_t)); ++ ++ if((ret = rtl8367c_setAsicAclRule(filter_id, &initRule)) != RT_ERR_OK) ++ return ret; ++ if((ret = rtl8367c_setAsicAclActCtrl(filter_id, FILTER_ENACT_INIT_MASK))!= RT_ERR_OK) ++ return ret; ++ if((ret = rtl8367c_setAsicAclAct(filter_id, &initAct)) != RT_ERR_OK) ++ return ret; ++ if((ret = rtl8367c_setAsicAclNot(filter_id, DISABLED)) != RT_ERR_OK ) ++ return ret; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_filter_igrAcl_cfg_delAll(void) ++{ ++ rtk_uint32 i; ++ rtk_api_ret_t ret; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ for(i = 0; i < RTL8367C_ACLRULENO; i++) ++ { ++ if((ret = rtl8367c_setAsicAclActCtrl(i, FILTER_ENACT_INIT_MASK))!= RT_ERR_OK) ++ return ret; ++ if((ret = rtl8367c_setAsicAclNot(i, DISABLED)) != RT_ERR_OK ) ++ return ret; ++ } ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_ACL_RESET_CFG, RTL8367C_ACL_RESET_CFG_OFFSET, TRUE);; ++} ++ ++/* 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 get configuration from ASIC. ++ */ ++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) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 i, tmp; ++ rtl8367c_aclrule aclRule; ++ rtl8367c_acl_act_t aclAct; ++ rtk_uint32 cpuPort; ++ rtl8367c_acltemplate_t type; ++ rtl8367c_svlan_memconf_t svlan_cfg; ++ rtl8367c_vlanconfiguser vlanMC; ++ rtk_uint32 phyPmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pFilter_cfg || NULL == pAction) ++ return RT_ERR_NULL_POINTER; ++ ++ if(filter_id > RTL8367C_ACLRULEMAX) ++ return RT_ERR_ENTRY_INDEX; ++ ++ if ((retVal = rtl8367c_getAsicAclRule(filter_id, &aclRule)) != RT_ERR_OK) ++ return retVal; ++ ++ /* Check valid */ ++ if(aclRule.valid == 0) ++ { ++ pFilter_cfg->valid = DISABLED; ++ return RT_ERR_OK; ++ } ++ ++ phyPmask = aclRule.data_bits.active_portmsk; ++ if(rtk_switch_portmask_P2L_get(phyPmask,&(pFilter_cfg->activeport.value)) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ ++ phyPmask = aclRule.care_bits.active_portmsk; ++ if(rtk_switch_portmask_P2L_get(phyPmask,&(pFilter_cfg->activeport.mask)) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ ++ for(i = 0; i <= CARE_TAG_IPV6; i++) ++ { ++ if(aclRule.data_bits.tag_exist & (1 << i)) ++ pFilter_cfg->careTag.tagType[i].value = 1; ++ else ++ pFilter_cfg->careTag.tagType[i].value = 0; ++ ++ if (aclRule.care_bits.tag_exist & (1 << i)) ++ pFilter_cfg->careTag.tagType[i].mask = 1; ++ else ++ pFilter_cfg->careTag.tagType[i].mask = 0; ++ } ++ ++ if(filter_advanceCaretagField[aclRule.data_bits.type][0] == TRUE) ++ { ++ /* Advanced Care tag setting */ ++ for(i = CARE_TAG_TCP; i < CARE_TAG_END; i++) ++ { ++ if(aclRule.data_bits.field[filter_advanceCaretagField[aclRule.data_bits.type][1]] & (0x0001 << (i-CARE_TAG_TCP)) ) ++ pFilter_cfg->careTag.tagType[i].value = 1; ++ else ++ pFilter_cfg->careTag.tagType[i].value = 0; ++ ++ if(aclRule.care_bits.field[filter_advanceCaretagField[aclRule.care_bits.type][1]] & (0x0001 << (i-CARE_TAG_TCP)) ) ++ pFilter_cfg->careTag.tagType[i].mask = 1; ++ else ++ pFilter_cfg->careTag.tagType[i].mask = 0; ++ } ++ } ++ ++ for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++) ++ { ++ pFilter_cfg->careFieldRaw[i] = aclRule.care_bits.field[i]; ++ pFilter_cfg->dataFieldRaw[i] = aclRule.data_bits.field[i]; ++ } ++ ++ if ((retVal = rtl8367c_getAsicAclNot(filter_id, &tmp))!= RT_ERR_OK) ++ return retVal; ++ ++ pFilter_cfg->invert = tmp; ++ ++ pFilter_cfg->valid = aclRule.valid; ++ ++ memset(pAction, 0, sizeof(rtk_filter_action_t)); ++ ++ if ((retVal = rtl8367c_getAsicAclActCtrl(filter_id, &tmp))!= RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicAclAct(filter_id, &aclAct)) != RT_ERR_OK) ++ return retVal; ++ ++ if(tmp & FILTER_ENACT_FWD_MASK) ++ { ++ if(TRUE == aclAct.fwdact_ext) ++ { ++ pAction->actEnable[FILTER_ENACT_ISOLATION] = TRUE; ++ ++ phyPmask = aclAct.fwdpmask; ++ if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ } ++ else if(aclAct.fwdact == RTL8367C_ACL_FWD_TRAP) ++ { ++ pAction->actEnable[FILTER_ENACT_TRAP_CPU] = TRUE; ++ } ++ else if (aclAct.fwdact == RTL8367C_ACL_FWD_MIRRORFUNTION ) ++ { ++ pAction->actEnable[FILTER_ENACT_MIRROR] = TRUE; ++ ++ phyPmask = aclAct.fwdpmask; ++ if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ } ++ else if (aclAct.fwdact == RTL8367C_ACL_FWD_REDIRECT) ++ { ++ if(aclAct.fwdpmask == 0 ) ++ pAction->actEnable[FILTER_ENACT_DROP] = TRUE; ++ else ++ { ++ pAction->actEnable[FILTER_ENACT_REDIRECT] = TRUE; ++ ++ phyPmask = aclAct.fwdpmask; ++ if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ } ++ } ++ else if (aclAct.fwdact == RTL8367C_ACL_FWD_MIRROR) ++ { ++ if((retVal = rtl8367c_getAsicCputagTrapPort(&cpuPort)) != RT_ERR_OK) ++ return retVal; ++ if (aclAct.fwdpmask == (1 << cpuPort)) ++ { ++ pAction->actEnable[FILTER_ENACT_COPY_CPU] = TRUE; ++ } ++ else ++ { ++ pAction->actEnable[FILTER_ENACT_ADD_DSTPORT] = TRUE; ++ ++ phyPmask = aclAct.fwdpmask; ++ if(rtk_switch_portmask_P2L_get(phyPmask,&(pAction->filterPortmask)) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ } ++ } ++ else ++ { ++ return RT_ERR_FAILED; ++ } ++ } ++ ++ if(tmp & FILTER_ENACT_POLICING_MASK) ++ { ++ pAction->actEnable[FILTER_ENACT_POLICING_0] = TRUE; ++ pAction->filterPolicingIdx[0] = aclAct.aclmeteridx; ++ } ++ ++ if(tmp & FILTER_ENACT_PRIORITY_MASK) ++ { ++ if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_PRIORITY)) ++ { ++ pAction->actEnable[FILTER_ENACT_PRIORITY] = TRUE; ++ pAction->filterPriority = aclAct.pridx; ++ } ++ else if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_1P_REMARK)) ++ { ++ pAction->actEnable[FILTER_ENACT_1P_REMARK] = TRUE; ++ pAction->filterPriority = aclAct.pridx; ++ } ++ else if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_DSCP_REMARK)) ++ { ++ pAction->actEnable[FILTER_ENACT_DSCP_REMARK] = TRUE; ++ pAction->filterPriority = aclAct.pridx; ++ } ++ else if(aclAct.priact == FILTER_ENACT_PRI_TYPE(FILTER_ENACT_POLICING_3)) ++ { ++ pAction->actEnable[FILTER_ENACT_POLICING_3] = TRUE; ++ pAction->filterPolicingIdx[3] = aclAct.pridx; ++ } ++ } ++ ++ if(tmp & FILTER_ENACT_SVLAN_MASK) ++ { ++ if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_SVLAN_INGRESS)) ++ { ++ if((retVal = rtl8367c_getAsicSvlanMemberConfiguration(aclAct.svidx_sact, &svlan_cfg)) != RT_ERR_OK) ++ return retVal; ++ ++ pAction->actEnable[FILTER_ENACT_SVLAN_INGRESS] = TRUE; ++ pAction->filterSvlanIdx = aclAct.svidx_sact; ++ pAction->filterSvlanVid = svlan_cfg.vs_svid; ++ } ++ else if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_SVLAN_EGRESS)) ++ { ++ if((retVal = rtl8367c_getAsicSvlanMemberConfiguration(aclAct.svidx_sact, &svlan_cfg)) != RT_ERR_OK) ++ return retVal; ++ ++ pAction->actEnable[FILTER_ENACT_SVLAN_EGRESS] = TRUE; ++ pAction->filterSvlanIdx = aclAct.svidx_sact; ++ pAction->filterSvlanVid = svlan_cfg.vs_svid; ++ } ++ else if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_SVLAN_CVID)) ++ pAction->actEnable[FILTER_ENACT_SVLAN_CVID] = TRUE; ++ else if(aclAct.sact == FILTER_ENACT_SVLAN_TYPE(FILTER_ENACT_POLICING_2)) ++ { ++ pAction->actEnable[FILTER_ENACT_POLICING_2] = TRUE; ++ pAction->filterPolicingIdx[2] = aclAct.svidx_sact; ++ } ++ } ++ ++ ++ if(tmp & FILTER_ENACT_CVLAN_MASK) ++ { ++ if(FILTER_ENACT_CACTEXT_TAGONLY == aclAct.cact_ext || ++ FILTER_ENACT_CACTEXT_BOTHVLANTAG == aclAct.cact_ext ) ++ { ++ if(FILTER_CTAGFMT_UNTAG == aclAct.tag_fmt) ++ { ++ pAction->actEnable[FILTER_ENACT_EGRESSCTAG_UNTAG] = TRUE; ++ } ++ else if(FILTER_CTAGFMT_TAG == aclAct.tag_fmt) ++ { ++ pAction->actEnable[FILTER_ENACT_EGRESSCTAG_TAG] = TRUE; ++ } ++ else if(FILTER_CTAGFMT_KEEP == aclAct.tag_fmt) ++ { ++ pAction->actEnable[FILTER_ENACT_EGRESSCTAG_KEEP] = TRUE; ++ } ++ else if(FILTER_CTAGFMT_KEEP1PRMK== aclAct.tag_fmt) ++ { ++ pAction->actEnable[FILTER_ENACT_EGRESSCTAG_KEEPAND1PRMK] = TRUE; ++ } ++ ++ } ++ ++ if(FILTER_ENACT_CACTEXT_VLANONLY == aclAct.cact_ext || ++ FILTER_ENACT_CACTEXT_BOTHVLANTAG == aclAct.cact_ext ) ++ { ++ if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_CVLAN_INGRESS)) ++ { ++ if((retVal = rtl8367c_getAsicVlanMemberConfig(aclAct.cvidx_cact, &vlanMC)) != RT_ERR_OK) ++ return retVal; ++ ++ pAction->actEnable[FILTER_ENACT_CVLAN_INGRESS] = TRUE; ++ pAction->filterCvlanIdx = aclAct.cvidx_cact; ++ pAction->filterCvlanVid = vlanMC.evid; ++ } ++ else if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_CVLAN_EGRESS)) ++ { ++ if((retVal = rtl8367c_getAsicVlanMemberConfig(aclAct.cvidx_cact, &vlanMC)) != RT_ERR_OK) ++ return retVal; ++ ++ pAction->actEnable[FILTER_ENACT_CVLAN_EGRESS] = TRUE; ++ pAction->filterCvlanIdx = aclAct.cvidx_cact; ++ pAction->filterCvlanVid = vlanMC.evid; ++ } ++ else if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_CVLAN_SVID)) ++ { ++ pAction->actEnable[FILTER_ENACT_CVLAN_SVID] = TRUE; ++ } ++ else if(aclAct.cact == FILTER_ENACT_CVLAN_TYPE(FILTER_ENACT_POLICING_1)) ++ { ++ pAction->actEnable[FILTER_ENACT_POLICING_1] = TRUE; ++ pAction->filterPolicingIdx[1] = aclAct.cvidx_cact; ++ } ++ } ++ } ++ ++ if(tmp & FILTER_ENACT_INTGPIO_MASK) ++ { ++ if(TRUE == aclAct.aclint) ++ { ++ pAction->actEnable[FILTER_ENACT_INTERRUPT] = TRUE; ++ } ++ ++ if(TRUE == aclAct.gpio_en) ++ { ++ pAction->actEnable[FILTER_ENACT_GPO] = TRUE; ++ pAction->filterPin = aclAct.gpio_pin; ++ } ++ } ++ ++ /* Get field type of RAW data */ ++ if ((retVal = rtl8367c_getAsicAclTemplate(aclRule.data_bits.type, &type))!= RT_ERR_OK) ++ return retVal; ++ ++ for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++) ++ { ++ pFilter_cfg->fieldRawType[i] = type.field[i]; ++ }/* end of for(i...) */ ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_filter_igrAcl_unmatchAction_set(rtk_port_t port, rtk_filter_unmatch_action_t action) ++{ ++ rtk_api_ret_t ret; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check port valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(action >= FILTER_UNMATCH_END) ++ return RT_ERR_INPUT; ++ ++ if((ret = rtl8367c_setAsicAclUnmatchedPermit(rtk_switch_port_L2P_get(port), action)) != RT_ERR_OK) ++ return ret; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_filter_igrAcl_unmatchAction_get(rtk_port_t port, rtk_filter_unmatch_action_t* pAction) ++{ ++ rtk_api_ret_t ret; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pAction) ++ return RT_ERR_NULL_POINTER; ++ ++ /* Check port valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if((ret = rtl8367c_getAsicAclUnmatchedPermit(rtk_switch_port_L2P_get(port), pAction)) != RT_ERR_OK) ++ return ret; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_filter_igrAcl_state_set(rtk_port_t port, rtk_filter_state_t state) ++{ ++ rtk_api_ret_t ret; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check port valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(state >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if((ret = rtl8367c_setAsicAcl(rtk_switch_port_L2P_get(port), state)) != RT_ERR_OK) ++ return ret; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_filter_igrAcl_state_get(rtk_port_t port, rtk_filter_state_t* pState) ++{ ++ rtk_api_ret_t ret; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pState) ++ return RT_ERR_NULL_POINTER; ++ ++ /* Check port valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if((ret = rtl8367c_getAsicAcl(rtk_switch_port_L2P_get(port), pState)) != RT_ERR_OK) ++ return ret; ++ ++ return RT_ERR_OK; ++} ++/* 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. ++ */ ++rtk_api_ret_t rtk_filter_igrAcl_template_set(rtk_filter_template_t *aclTemplate) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 idxField; ++ rtl8367c_acltemplate_t aclType; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(aclTemplate->index >= RTK_MAX_NUM_OF_FILTER_TYPE) ++ return RT_ERR_INPUT; ++ ++ for(idxField = 0; idxField < RTK_MAX_NUM_OF_FILTER_FIELD; idxField++) ++ { ++ if(aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_DMAC_15_0 || ++ (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_CTAG && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_IPV4_SIP_15_0 ) || ++ (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_IPV4_DIP_31_16 && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_IPV6_SIP_15_0 ) || ++ (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_IPV6_DIP_31_16 && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_VIDRANGE ) || ++ (aclTemplate->fieldType[idxField] > FILTER_FIELD_RAW_FIELD_VALID && aclTemplate->fieldType[idxField] < FILTER_FIELD_RAW_FIELD_SELECT00 ) || ++ aclTemplate->fieldType[idxField] >= FILTER_FIELD_RAW_END) ++ { ++ return RT_ERR_INPUT; ++ } ++ } ++ ++ for(idxField = 0; idxField < RTK_MAX_NUM_OF_FILTER_FIELD; idxField++) ++ { ++ aclType.field[idxField] = aclTemplate->fieldType[idxField]; ++ } ++ ++ if((retVal = rtl8367c_setAsicAclTemplate(aclTemplate->index, &aclType)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_filter_igrAcl_template_get(rtk_filter_template_t *aclTemplate) ++{ ++ rtk_api_ret_t ret; ++ rtk_uint32 idxField; ++ rtl8367c_acltemplate_t aclType; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == aclTemplate) ++ return RT_ERR_NULL_POINTER; ++ ++ if(aclTemplate->index >= RTK_MAX_NUM_OF_FILTER_TYPE) ++ return RT_ERR_INPUT; ++ ++ if((ret = rtl8367c_getAsicAclTemplate(aclTemplate->index, &aclType)) != RT_ERR_OK) ++ return ret; ++ ++ for(idxField = 0; idxField < RTK_MAX_NUM_OF_FILTER_FIELD; idxField ++) ++ { ++ aclTemplate->fieldType[idxField] = aclType.field[idxField]; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_filter_igrAcl_field_sel_set(rtk_uint32 index, rtk_field_sel_t format, rtk_uint32 offset) ++{ ++ rtk_api_ret_t ret; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(index >= RTL8367C_FIELDSEL_FORMAT_NUMBER) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(format >= FORMAT_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(offset > RTL8367C_FIELDSEL_MAX_OFFSET) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if((ret = rtl8367c_setAsicFieldSelector(index, (rtk_uint32)format, offset)) != RT_ERR_OK) ++ return ret; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_filter_igrAcl_field_sel_get(rtk_uint32 index, rtk_field_sel_t *pFormat, rtk_uint32 *pOffset) ++{ ++ rtk_api_ret_t ret; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pFormat || NULL == pOffset) ++ return RT_ERR_NULL_POINTER; ++ ++ if(index >= RTL8367C_FIELDSEL_FORMAT_NUMBER) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if((ret = rtl8367c_getAsicFieldSelector(index, pFormat, pOffset)) != RT_ERR_OK) ++ return ret; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_filter_iprange_set(rtk_uint32 index, rtk_filter_iprange_t type, ipaddr_t upperIp, ipaddr_t lowerIp) ++{ ++ rtk_api_ret_t ret; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(index > RTL8367C_ACLRANGEMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(type >= IPRANGE_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(lowerIp > upperIp) ++ return RT_ERR_INPUT; ++ ++ if((ret = rtl8367c_setAsicAclIpRange(index, type, upperIp, lowerIp)) != RT_ERR_OK) ++ return ret; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ * None. ++ */ ++rtk_api_ret_t rtk_filter_iprange_get(rtk_uint32 index, rtk_filter_iprange_t *pType, ipaddr_t *pUpperIp, ipaddr_t *pLowerIp) ++{ ++ rtk_api_ret_t ret; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if((NULL == pType) || (NULL == pUpperIp) || (NULL == pLowerIp)) ++ return RT_ERR_NULL_POINTER; ++ ++ if(index > RTL8367C_ACLRANGEMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if((ret = rtl8367c_getAsicAclIpRange(index, pType, pUpperIp, pLowerIp)) != RT_ERR_OK) ++ return ret; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_filter_vidrange_set(rtk_uint32 index, rtk_filter_vidrange_t type, rtk_uint32 upperVid, rtk_uint32 lowerVid) ++{ ++ rtk_api_ret_t ret; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(index > RTL8367C_ACLRANGEMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(type >= VIDRANGE_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(lowerVid > upperVid) ++ return RT_ERR_INPUT; ++ ++ if( (upperVid > RTL8367C_VIDMAX) || (lowerVid > RTL8367C_VIDMAX)) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if((ret = rtl8367c_setAsicAclVidRange(index, type, upperVid, lowerVid)) != RT_ERR_OK) ++ return ret; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_filter_vidrange_get(rtk_uint32 index, rtk_filter_vidrange_t *pType, rtk_uint32 *pUpperVid, rtk_uint32 *pLowerVid) ++{ ++ rtk_api_ret_t ret; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if((NULL == pType) || (NULL == pUpperVid) || (NULL == pLowerVid)) ++ return RT_ERR_NULL_POINTER; ++ ++ if(index > RTL8367C_ACLRANGEMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if((ret = rtl8367c_getAsicAclVidRange(index, pType, pUpperVid, pLowerVid)) != RT_ERR_OK) ++ return ret; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_filter_portrange_set(rtk_uint32 index, rtk_filter_portrange_t type, rtk_uint32 upperPort, rtk_uint32 lowerPort) ++{ ++ rtk_api_ret_t ret; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(index > RTL8367C_ACLRANGEMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(type >= PORTRANGE_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(lowerPort > upperPort) ++ return RT_ERR_INPUT; ++ ++ if(upperPort > RTL8367C_ACL_PORTRANGEMAX) ++ return RT_ERR_INPUT; ++ ++ if(lowerPort > RTL8367C_ACL_PORTRANGEMAX) ++ return RT_ERR_INPUT; ++ ++ if((ret = rtl8367c_setAsicAclPortRange(index, type, upperPort, lowerPort)) != RT_ERR_OK) ++ return ret; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_filter_portrange_get(rtk_uint32 index, rtk_filter_portrange_t *pType, rtk_uint32 *pUpperPort, rtk_uint32 *pLowerPort) ++{ ++ rtk_api_ret_t ret; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if((NULL == pType) || (NULL == pUpperPort) || (NULL == pLowerPort)) ++ return RT_ERR_NULL_POINTER; ++ ++ if(index > RTL8367C_ACLRANGEMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if((ret = rtl8367c_getAsicAclPortRange(index, pType, pUpperPort, pLowerPort)) != RT_ERR_OK) ++ return ret; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_filter_igrAclPolarity_set(rtk_uint32 polarity) ++{ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(polarity > 1) ++ return RT_ERR_OUT_OF_RANGE; ++ return rtl8367c_setAsicAclGpioPolarity(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 ++ */ ++rtk_api_ret_t rtk_filter_igrAclPolarity_get(rtk_uint32* pPolarity) ++{ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pPolarity) ++ return RT_ERR_NULL_POINTER; ++ ++ return rtl8367c_getAsicAclGpioPolarity(pPolarity); ++} ++ ++ ++ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/cpu.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/cpu.c +new file mode 100644 +index 0000000000..d1cd95b37a +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/cpu.c +@@ -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 ++#include ++#include ++#include ++ ++#include ++#include ++ ++/* 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<= 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; ++} ++ ++ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/dot1x.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/dot1x.c +new file mode 100644 +index 0000000000..c9b146a6d8 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/dot1x.c +@@ -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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* 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; ++} ++ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/eee.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/eee.c +new file mode 100644 +index 0000000000..cd14c2ce13 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/eee.c +@@ -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 ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++/* 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, ®Data))!=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,®Data1))!=RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_getAsicEeeGiga(phy_port,®Data2))!=RT_ERR_OK) ++ return retVal; ++ ++ if (regData1==1&®Data2==1) ++ *pEnable = ENABLED; ++ else ++ *pEnable = DISABLED; ++ ++ return RT_ERR_OK; ++} ++ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/i2c.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/i2c.c +new file mode 100644 +index 0000000000..17a5f3785b +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/i2c.c +@@ -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 ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++ ++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( ®Data_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( ®Data_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; ++} ++ ++ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/igmp.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/igmp.c +new file mode 100644 +index 0000000000..170cbdaaf0 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/igmp.c +@@ -0,0 +1,1555 @@ ++/* ++ * 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 IGMP module. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_igmp_init(void) ++{ ++ rtk_api_ret_t retVal; ++ rtk_port_t port; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ((retVal = rtl8367c_setAsicLutIpMulticastLookup(ENABLED))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicLutIpLookupMethod(1))!=RT_ERR_OK) ++ return retVal; ++ ++ RTK_SCAN_ALL_PHY_PORTMASK(port) ++ { ++ if ((retVal = rtl8367c_setAsicIGMPv1Opeartion(port, PROTOCOL_OP_ASIC))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicIGMPv2Opeartion(port, PROTOCOL_OP_ASIC))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicIGMPv3Opeartion(port, PROTOCOL_OP_FLOOD))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicMLDv1Opeartion(port, PROTOCOL_OP_ASIC))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicMLDv2Opeartion(port, PROTOCOL_OP_FLOOD))!=RT_ERR_OK) ++ return retVal; ++ } ++ ++ if ((retVal = rtl8367c_setAsicIGMPAllowDynamicRouterPort(rtk_switch_phyPortMask_get()))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicIGMPFastLeaveEn(ENABLED))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicIGMPReportLeaveFlood(1))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicIgmp(ENABLED))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_igmp_state_set(rtk_enable_t enabled) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (enabled >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicIgmp(enabled))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_igmp_state_get(rtk_enable_t *pEnabled) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(pEnabled == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicIgmp(pEnabled))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_igmp_static_router_port_set(rtk_portmask_t *pPortmask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Valid port mask */ ++ if(pPortmask == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ RTK_CHK_PORTMASK_VALID(pPortmask); ++ ++ if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicIGMPStaticRouterPort(pmask))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_igmp_static_router_port_get(rtk_portmask_t *pPortmask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(pPortmask == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicIGMPStaticRouterPort(&pmask))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_igmp_protocol_set(rtk_port_t port, rtk_igmp_protocol_t protocol, rtk_igmp_action_t action) ++{ ++ rtk_uint32 operation; ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check port valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(protocol >= PROTOCOL_END) ++ return RT_ERR_INPUT; ++ ++ if(action >= IGMP_ACTION_END) ++ return RT_ERR_INPUT; ++ ++ switch(action) ++ { ++ case IGMP_ACTION_FORWARD: ++ operation = PROTOCOL_OP_FLOOD; ++ break; ++ case IGMP_ACTION_TRAP2CPU: ++ operation = PROTOCOL_OP_TRAP; ++ break; ++ case IGMP_ACTION_DROP: ++ operation = PROTOCOL_OP_DROP; ++ break; ++ case IGMP_ACTION_ASIC: ++ operation = PROTOCOL_OP_ASIC; ++ break; ++ default: ++ return RT_ERR_INPUT; ++ } ++ ++ switch(protocol) ++ { ++ case PROTOCOL_IGMPv1: ++ if ((retVal = rtl8367c_setAsicIGMPv1Opeartion(rtk_switch_port_L2P_get(port), operation))!=RT_ERR_OK) ++ return retVal; ++ ++ break; ++ case PROTOCOL_IGMPv2: ++ if ((retVal = rtl8367c_setAsicIGMPv2Opeartion(rtk_switch_port_L2P_get(port), operation))!=RT_ERR_OK) ++ return retVal; ++ ++ break; ++ case PROTOCOL_IGMPv3: ++ if ((retVal = rtl8367c_setAsicIGMPv3Opeartion(rtk_switch_port_L2P_get(port), operation))!=RT_ERR_OK) ++ return retVal; ++ ++ break; ++ case PROTOCOL_MLDv1: ++ if ((retVal = rtl8367c_setAsicMLDv1Opeartion(rtk_switch_port_L2P_get(port), operation))!=RT_ERR_OK) ++ return retVal; ++ ++ break; ++ case PROTOCOL_MLDv2: ++ if ((retVal = rtl8367c_setAsicMLDv2Opeartion(rtk_switch_port_L2P_get(port), operation))!=RT_ERR_OK) ++ return retVal; ++ ++ break; ++ default: ++ return RT_ERR_INPUT; ++ ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_igmp_protocol_get(rtk_port_t port, rtk_igmp_protocol_t protocol, rtk_igmp_action_t *pAction) ++{ ++ rtk_uint32 operation; ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check port valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(protocol >= PROTOCOL_END) ++ return RT_ERR_INPUT; ++ ++ if(pAction == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ switch(protocol) ++ { ++ case PROTOCOL_IGMPv1: ++ if ((retVal = rtl8367c_getAsicIGMPv1Opeartion(rtk_switch_port_L2P_get(port), &operation))!=RT_ERR_OK) ++ return retVal; ++ ++ break; ++ case PROTOCOL_IGMPv2: ++ if ((retVal = rtl8367c_getAsicIGMPv2Opeartion(rtk_switch_port_L2P_get(port), &operation))!=RT_ERR_OK) ++ return retVal; ++ ++ break; ++ case PROTOCOL_IGMPv3: ++ if ((retVal = rtl8367c_getAsicIGMPv3Opeartion(rtk_switch_port_L2P_get(port), &operation))!=RT_ERR_OK) ++ return retVal; ++ ++ break; ++ case PROTOCOL_MLDv1: ++ if ((retVal = rtl8367c_getAsicMLDv1Opeartion(rtk_switch_port_L2P_get(port), &operation))!=RT_ERR_OK) ++ return retVal; ++ ++ break; ++ case PROTOCOL_MLDv2: ++ if ((retVal = rtl8367c_getAsicMLDv2Opeartion(rtk_switch_port_L2P_get(port), &operation))!=RT_ERR_OK) ++ return retVal; ++ ++ break; ++ default: ++ return RT_ERR_INPUT; ++ ++ } ++ ++ switch(operation) ++ { ++ case PROTOCOL_OP_FLOOD: ++ *pAction = IGMP_ACTION_FORWARD; ++ break; ++ case PROTOCOL_OP_TRAP: ++ *pAction = IGMP_ACTION_TRAP2CPU; ++ break; ++ case PROTOCOL_OP_DROP: ++ *pAction = IGMP_ACTION_DROP; ++ break; ++ case PROTOCOL_OP_ASIC: ++ *pAction = IGMP_ACTION_ASIC; ++ break; ++ default: ++ return RT_ERR_FAILED; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_igmp_fastLeave_set(rtk_enable_t state) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(state >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicIGMPFastLeaveEn((rtk_uint32)state))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_igmp_fastLeave_get(rtk_enable_t *pState) ++{ ++ rtk_uint32 fast_leave; ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(pState == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicIGMPFastLeaveEn(&fast_leave))!=RT_ERR_OK) ++ return retVal; ++ ++ *pState = ((fast_leave == 1) ? ENABLED : DISABLED); ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_igmp_maxGroup_set(rtk_port_t port, rtk_uint32 group) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check port valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(group > RTL8367C_IGMP_MAX_GOUP) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if ((retVal = rtl8367c_setAsicIGMPPortMAXGroup(rtk_switch_port_L2P_get(port), group))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_igmp_maxGroup_get(rtk_port_t port, rtk_uint32 *pGroup) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check port valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(pGroup == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicIGMPPortMAXGroup(rtk_switch_port_L2P_get(port), pGroup))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_igmp_currentGroup_get(rtk_port_t port, rtk_uint32 *pGroup) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check port valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(pGroup == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicIGMPPortCurrentGroup(rtk_switch_port_L2P_get(port), pGroup))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ */ ++rtk_api_ret_t rtk_igmp_tableFullAction_set(rtk_igmp_tableFullAction_t action) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(action >= IGMP_TABLE_FULL_OP_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicIGMPTableFullOP((rtk_uint32)action))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ */ ++rtk_api_ret_t rtk_igmp_tableFullAction_get(rtk_igmp_tableFullAction_t *pAction) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pAction) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicIGMPTableFullOP((rtk_uint32 *)pAction))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ */ ++rtk_api_ret_t rtk_igmp_checksumErrorAction_set(rtk_igmp_checksumErrorAction_t action) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(action >= IGMP_CRC_ERR_OP_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicIGMPCRCErrOP((rtk_uint32)action))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++ ++/* 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: ++ */ ++rtk_api_ret_t rtk_igmp_checksumErrorAction_get(rtk_igmp_checksumErrorAction_t *pAction) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pAction) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicIGMPCRCErrOP((rtk_uint32 *)pAction))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ */ ++rtk_api_ret_t rtk_igmp_leaveTimer_set(rtk_uint32 timer) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(timer > RTL8367C_MAX_LEAVE_TIMER) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicIGMPLeaveTimer(timer))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ */ ++rtk_api_ret_t rtk_igmp_leaveTimer_get(rtk_uint32 *pTimer) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pTimer) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicIGMPLeaveTimer(pTimer))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ */ ++rtk_api_ret_t rtk_igmp_queryInterval_set(rtk_uint32 interval) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(interval > RTL8367C_MAX_QUERY_INT) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicIGMPQueryInterval(interval))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ */ ++rtk_api_ret_t rtk_igmp_queryInterval_get(rtk_uint32 *pInterval) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pInterval) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicIGMPQueryInterval(pInterval))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ */ ++rtk_api_ret_t rtk_igmp_robustness_set(rtk_uint32 robustness) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(robustness > RTL8367C_MAX_ROB_VAR) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicIGMPRobVar(robustness))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ */ ++rtk_api_ret_t rtk_igmp_robustness_get(rtk_uint32 *pRobustness) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pRobustness) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicIGMPRobVar(pRobustness))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_igmp_dynamicRouterPortAllow_set(rtk_portmask_t *pPortmask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pPortmask) ++ return RT_ERR_NULL_POINTER; ++ ++ RTK_CHK_PORTMASK_VALID(pPortmask); ++ ++ if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicIGMPAllowDynamicRouterPort(pmask))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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_NULL_POINTER - Null pointer ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_MASK - Error parameter ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_igmp_dynamicRouterPortAllow_get(rtk_portmask_t *pPortmask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pPortmask) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicIGMPAllowDynamicRouterPort(&pmask))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_igmp_dynamicRouterPort_get(rtk_igmp_dynamicRouterPort_t *pDynamicRouterPort) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 port; ++ rtk_uint32 timer; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pDynamicRouterPort) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicIGMPdynamicRouterPort1(&port, &timer))!= RT_ERR_OK) ++ return retVal; ++ ++ if (port == RTL8367C_ROUTER_PORT_INVALID) ++ { ++ pDynamicRouterPort->dynamicRouterPort0Valid = DISABLED; ++ pDynamicRouterPort->dynamicRouterPort0 = 0; ++ pDynamicRouterPort->dynamicRouterPort0Timer = 0; ++ } ++ else ++ { ++ pDynamicRouterPort->dynamicRouterPort0Valid = ENABLED; ++ pDynamicRouterPort->dynamicRouterPort0 = rtk_switch_port_P2L_get(port); ++ pDynamicRouterPort->dynamicRouterPort0Timer = timer; ++ } ++ ++ if ((retVal = rtl8367c_getAsicIGMPdynamicRouterPort2(&port, &timer))!= RT_ERR_OK) ++ return retVal; ++ ++ if (port == RTL8367C_ROUTER_PORT_INVALID) ++ { ++ pDynamicRouterPort->dynamicRouterPort1Valid = DISABLED; ++ pDynamicRouterPort->dynamicRouterPort1 = 0; ++ pDynamicRouterPort->dynamicRouterPort1Timer = 0; ++ } ++ else ++ { ++ pDynamicRouterPort->dynamicRouterPort1Valid = ENABLED; ++ pDynamicRouterPort->dynamicRouterPort1 = rtk_switch_port_P2L_get(port); ++ pDynamicRouterPort->dynamicRouterPort1Timer = timer; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_igmp_suppressionEnable_set(rtk_enable_t reportSuppression, rtk_enable_t leaveSuppression) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(reportSuppression >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if(leaveSuppression >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicIGMPSuppression((rtk_uint32)reportSuppression, (rtk_uint32)leaveSuppression))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_igmp_suppressionEnable_get(rtk_enable_t *pReportSuppression, rtk_enable_t *pLeaveSuppression) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pReportSuppression) ++ return RT_ERR_NULL_POINTER; ++ ++ if(NULL == pLeaveSuppression) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicIGMPSuppression((rtk_uint32 *)pReportSuppression, (rtk_uint32 *)pLeaveSuppression))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_igmp_portRxPktEnable_set(rtk_port_t port, rtk_igmp_rxPktEnable_t *pRxCfg) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check port valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(NULL == pRxCfg) ++ return RT_ERR_NULL_POINTER; ++ ++ if(pRxCfg->rxQuery >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if(pRxCfg->rxReport >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if(pRxCfg->rxLeave >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if(pRxCfg->rxMRP >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if(pRxCfg->rxMcast >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicIGMPQueryRX(rtk_switch_port_L2P_get(port), (rtk_uint32)pRxCfg->rxQuery))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicIGMPReportRX(rtk_switch_port_L2P_get(port), (rtk_uint32)pRxCfg->rxReport))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicIGMPLeaveRX(rtk_switch_port_L2P_get(port), (rtk_uint32)pRxCfg->rxLeave))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicIGMPMRPRX(rtk_switch_port_L2P_get(port), (rtk_uint32)pRxCfg->rxMRP))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicIGMPMcDataRX(rtk_switch_port_L2P_get(port), (rtk_uint32)pRxCfg->rxMcast))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_igmp_portRxPktEnable_get(rtk_port_t port, rtk_igmp_rxPktEnable_t *pRxCfg) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check port valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(NULL == pRxCfg) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicIGMPQueryRX(rtk_switch_port_L2P_get(port), (rtk_uint32 *)&(pRxCfg->rxQuery)))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicIGMPReportRX(rtk_switch_port_L2P_get(port), (rtk_uint32 *)&(pRxCfg->rxReport)))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicIGMPLeaveRX(rtk_switch_port_L2P_get(port), (rtk_uint32 *)&(pRxCfg->rxLeave)))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicIGMPMRPRX(rtk_switch_port_L2P_get(port), (rtk_uint32 *)&(pRxCfg->rxMRP)))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicIGMPMcDataRX(rtk_switch_port_L2P_get(port), (rtk_uint32 *)&(pRxCfg->rxMcast)))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_igmp_groupInfo_get(rtk_uint32 index, rtk_igmp_groupInfo_t *pGroup) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 valid; ++ rtl8367c_igmpgroup grp; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check index */ ++ if(index > RTL8367C_IGMP_MAX_GOUP) ++ return RT_ERR_INPUT; ++ ++ if(NULL == pGroup) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicIGMPGroup(index, &valid, &grp))!=RT_ERR_OK) ++ return retVal; ++ ++ memset(pGroup, 0x00, sizeof(rtk_igmp_groupInfo_t)); ++ pGroup->valid = valid; ++ pGroup->reportSuppFlag = grp.report_supp_flag; ++ ++ if(grp.p0_timer != 0) ++ { ++ RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(0)); ++ pGroup->timer[rtk_switch_port_P2L_get(0)] = grp.p0_timer; ++ } ++ ++ if(grp.p1_timer != 0) ++ { ++ RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(1)); ++ pGroup->timer[rtk_switch_port_P2L_get(1)] = grp.p1_timer; ++ } ++ ++ if(grp.p2_timer != 0) ++ { ++ RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(2)); ++ pGroup->timer[rtk_switch_port_P2L_get(2)] = grp.p2_timer; ++ } ++ ++ if(grp.p3_timer != 0) ++ { ++ RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(3)); ++ pGroup->timer[rtk_switch_port_P2L_get(3)] = grp.p3_timer; ++ } ++ ++ if(grp.p4_timer != 0) ++ { ++ RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(4)); ++ pGroup->timer[rtk_switch_port_P2L_get(4)] = grp.p4_timer; ++ } ++ ++ if(grp.p5_timer != 0) ++ { ++ RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(5)); ++ pGroup->timer[rtk_switch_port_P2L_get(5)] = grp.p5_timer; ++ } ++ ++ if(grp.p6_timer != 0) ++ { ++ RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(6)); ++ pGroup->timer[rtk_switch_port_P2L_get(6)] = grp.p6_timer; ++ } ++ ++ if(grp.p7_timer != 0) ++ { ++ RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(7)); ++ pGroup->timer[rtk_switch_port_P2L_get(7)] = grp.p7_timer; ++ } ++ ++ if(grp.p8_timer != 0) ++ { ++ RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(8)); ++ pGroup->timer[rtk_switch_port_P2L_get(8)] = grp.p8_timer; ++ } ++ ++ if(grp.p9_timer != 0) ++ { ++ RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(9)); ++ pGroup->timer[rtk_switch_port_P2L_get(9)] = grp.p9_timer; ++ } ++ ++ if(grp.p10_timer != 0) ++ { ++ RTK_PORTMASK_PORT_SET((pGroup->member), rtk_switch_port_P2L_get(10)); ++ pGroup->timer[rtk_switch_port_P2L_get(10)] = grp.p10_timer; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_igmp_ReportLeaveFwdAction_set(rtk_igmp_ReportLeaveFwdAct_t action) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 regData; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ switch(action) ++ { ++ case IGMP_REPORT_LEAVE_TO_ROUTER: ++ regData = 1; ++ break; ++ case IGMP_REPORT_LEAVE_TO_ALLPORT: ++ regData = 2; ++ break; ++ case IGMP_REPORT_LEAVE_TO_ROUTER_PORT_ADV: ++ regData = 3; ++ break; ++ default: ++ return RT_ERR_INPUT; ++ } ++ ++ if ((retVal = rtl8367c_setAsicIGMPReportLeaveFlood(regData))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_igmp_ReportLeaveFwdAction_get(rtk_igmp_ReportLeaveFwdAct_t *pAction) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 regData; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pAction) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicIGMPReportLeaveFlood(®Data))!=RT_ERR_OK) ++ return retVal; ++ ++ switch(regData) ++ { ++ case 1: ++ *pAction = IGMP_REPORT_LEAVE_TO_ROUTER; ++ break; ++ case 2: ++ *pAction = IGMP_REPORT_LEAVE_TO_ALLPORT; ++ break; ++ case 3: ++ *pAction = IGMP_REPORT_LEAVE_TO_ROUTER_PORT_ADV; ++ break; ++ default: ++ return RT_ERR_FAILED; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_igmp_dropLeaveZeroEnable_set(rtk_enable_t enabled) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(enabled >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicIGMPDropLeaveZero(enabled))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++ ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_igmp_dropLeaveZeroEnable_get(rtk_enable_t *pEnabled) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pEnabled) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicIGMPDropLeaveZero((rtk_uint32 *)pEnabled))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++ ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_igmp_bypassGroupRange_set(rtk_igmp_bypassGroup_t group, rtk_enable_t enabled) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(group >= IGMP_BYPASS_GROUP_END) ++ return RT_ERR_INPUT; ++ ++ if(enabled >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicIGMPBypassGroup(group, enabled))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_igmp_bypassGroupRange_get(rtk_igmp_bypassGroup_t group, rtk_enable_t *pEnable) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(group >= IGMP_BYPASS_GROUP_END) ++ return RT_ERR_INPUT; ++ ++ if(NULL == pEnable) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicIGMPBypassGroup(group, pEnable))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/acl.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/acl.h +new file mode 100644 +index 0000000000..6308da8d42 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/acl.h +@@ -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__ */ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/cpu.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/cpu.h +new file mode 100644 +index 0000000000..5544aca7b2 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/cpu.h +@@ -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__ */ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/dot1x.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/dot1x.h +new file mode 100644 +index 0000000000..ef0a05a04b +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/dot1x.h +@@ -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__ */ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/eee.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/eee.h +new file mode 100644 +index 0000000000..b670998c8c +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/eee.h +@@ -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__ */ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/i2c.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/i2c.h +new file mode 100644 +index 0000000000..2c7f0756ae +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/i2c.h +@@ -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 ++ ++#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 ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/igmp.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/igmp.h +new file mode 100644 +index 0000000000..f088b0ccdd +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/igmp.h +@@ -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__ */ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/interrupt.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/interrupt.h +new file mode 100644 +index 0000000000..f2689ebc70 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/interrupt.h +@@ -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__ */ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/l2.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/l2.h +new file mode 100644 +index 0000000000..e0ccdbe3d7 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/l2.h +@@ -0,0 +1,1181 @@ ++/* ++ * 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 L2 module high-layer API defination ++ * ++ */ ++ ++#ifndef __RTK_API_L2_H__ ++#define __RTK_API_L2_H__ ++ ++ ++/* ++ * Data Type Declaration ++ */ ++#define RTK_MAX_NUM_OF_LEARN_LIMIT (rtk_switch_maxLutAddrNumber_get()) ++ ++#define RTK_MAC_ADDR_LEN 6 ++#define RTK_MAX_LUT_ADDRESS (RTK_MAX_NUM_OF_LEARN_LIMIT) ++#define RTK_MAX_LUT_ADDR_ID (RTK_MAX_LUT_ADDRESS - 1) ++ ++typedef rtk_uint32 rtk_l2_age_time_t; ++ ++typedef enum rtk_l2_flood_type_e ++{ ++ FLOOD_UNKNOWNDA = 0, ++ FLOOD_UNKNOWNMC, ++ FLOOD_BC, ++ FLOOD_END ++} rtk_l2_flood_type_t; ++ ++typedef rtk_uint32 rtk_l2_flushItem_t; ++ ++typedef enum rtk_l2_flushType_e ++{ ++ FLUSH_TYPE_BY_PORT = 0, /* physical port */ ++ FLUSH_TYPE_BY_PORT_VID, /* physical port + VID */ ++ FLUSH_TYPE_BY_PORT_FID, /* physical port + FID */ ++ FLUSH_TYPE_END ++} rtk_l2_flushType_t; ++ ++typedef struct rtk_l2_flushCfg_s ++{ ++ rtk_enable_t flushByVid; ++ rtk_vlan_t vid; ++ rtk_enable_t flushByFid; ++ rtk_uint32 fid; ++ rtk_enable_t flushByPort; ++ rtk_port_t port; ++ rtk_enable_t flushByMac; ++ rtk_mac_t ucastAddr; ++ rtk_enable_t flushStaticAddr; ++ rtk_enable_t flushAddrOnAllPorts; /* this is used when flushByVid */ ++} rtk_l2_flushCfg_t; ++ ++typedef enum rtk_l2_read_method_e{ ++ ++ READMETHOD_MAC = 0, ++ READMETHOD_ADDRESS, ++ READMETHOD_NEXT_ADDRESS, ++ READMETHOD_NEXT_L2UC, ++ READMETHOD_NEXT_L2MC, ++ READMETHOD_NEXT_L3MC, ++ READMETHOD_NEXT_L2L3MC, ++ READMETHOD_NEXT_L2UCSPA, ++ READMETHOD_END ++}rtk_l2_read_method_t; ++ ++/* l2 limit learning count action */ ++typedef enum rtk_l2_limitLearnCntAction_e ++{ ++ LIMIT_LEARN_CNT_ACTION_DROP = 0, ++ LIMIT_LEARN_CNT_ACTION_FORWARD, ++ LIMIT_LEARN_CNT_ACTION_TO_CPU, ++ LIMIT_LEARN_CNT_ACTION_END ++} rtk_l2_limitLearnCntAction_t; ++ ++typedef enum rtk_l2_ipmc_lookup_type_e ++{ ++ LOOKUP_MAC = 0, ++ LOOKUP_IP, ++ LOOKUP_IP_VID, ++ LOOKUP_END ++} rtk_l2_ipmc_lookup_type_t; ++ ++/* l2 address table - unicast data structure */ ++typedef struct rtk_l2_ucastAddr_s ++{ ++ rtk_mac_t mac; ++ rtk_uint32 ivl; ++ rtk_uint32 cvid; ++ rtk_uint32 fid; ++ rtk_uint32 efid; ++ rtk_uint32 port; ++ rtk_uint32 sa_block; ++ rtk_uint32 da_block; ++ rtk_uint32 auth; ++ rtk_uint32 is_static; ++ rtk_uint32 priority; ++ rtk_uint32 sa_pri_en; ++ rtk_uint32 fwd_pri_en; ++ rtk_uint32 address; ++}rtk_l2_ucastAddr_t; ++ ++/* l2 address table - multicast data structure */ ++typedef struct rtk_l2_mcastAddr_s ++{ ++ rtk_uint32 vid; ++ rtk_mac_t mac; ++ rtk_uint32 fid; ++ rtk_portmask_t portmask; ++ rtk_uint32 ivl; ++ rtk_uint32 priority; ++ rtk_uint32 fwd_pri_en; ++ rtk_uint32 igmp_asic; ++ rtk_uint32 igmp_index; ++ rtk_uint32 address; ++}rtk_l2_mcastAddr_t; ++ ++/* l2 address table - ip multicast data structure */ ++typedef struct rtk_l2_ipMcastAddr_s ++{ ++ ipaddr_t dip; ++ ipaddr_t sip; ++ rtk_portmask_t portmask; ++ rtk_uint32 priority; ++ rtk_uint32 fwd_pri_en; ++ rtk_uint32 igmp_asic; ++ rtk_uint32 igmp_index; ++ rtk_uint32 address; ++}rtk_l2_ipMcastAddr_t; ++ ++/* l2 address table - ip VID multicast data structure */ ++typedef struct rtk_l2_ipVidMcastAddr_s ++{ ++ ipaddr_t dip; ++ ipaddr_t sip; ++ rtk_uint32 vid; ++ rtk_portmask_t portmask; ++ rtk_uint32 address; ++}rtk_l2_ipVidMcastAddr_t; ++ ++typedef struct rtk_l2_addr_table_s ++{ ++ rtk_uint32 index; ++ ipaddr_t sip; ++ ipaddr_t dip; ++ rtk_mac_t mac; ++ rtk_uint32 sa_block; ++ rtk_uint32 auth; ++ rtk_portmask_t portmask; ++ rtk_uint32 age; ++ rtk_uint32 ivl; ++ rtk_uint32 cvid; ++ rtk_uint32 fid; ++ rtk_uint32 is_ipmul; ++ rtk_uint32 is_static; ++ rtk_uint32 is_ipvidmul; ++ rtk_uint32 l3_vid; ++}rtk_l2_addr_table_t; ++ ++typedef enum rtk_l2_clearStatus_e ++{ ++ L2_CLEAR_STATE_FINISH = 0, ++ L2_CLEAR_STATE_BUSY, ++ L2_CLEAR_STATE_END ++}rtk_l2_clearStatus_t; ++ ++/* Function Name: ++ * rtk_l2_init ++ * Description: ++ * Initialize l2 module of the specified device. ++ * Input: ++ * None ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * Initialize l2 module before calling any l2 APIs. ++ */ ++extern rtk_api_ret_t rtk_l2_init(void); ++ ++/* Function Name: ++ * rtk_l2_addr_add ++ * Description: ++ * Add LUT unicast entry. ++ * Input: ++ * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. ++ * pL2_data - Unicast entry parameter ++ * 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_MAC - Invalid MAC address. ++ * RT_ERR_L2_FID - Invalid FID . ++ * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * If the unicast mac address already existed in LUT, it will udpate the status of the entry. ++ * Otherwise, it will find an empty or asic auto learned entry to write. If all the entries ++ * with the same hash value can't be replaced, ASIC will return a RT_ERR_L2_INDEXTBL_FULL error. ++ */ ++extern rtk_api_ret_t rtk_l2_addr_add(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data); ++ ++/* Function Name: ++ * rtk_l2_addr_get ++ * Description: ++ * Get LUT unicast entry. ++ * Input: ++ * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. ++ * Output: ++ * pL2_data - Unicast entry parameter ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number. ++ * RT_ERR_MAC - Invalid MAC address. ++ * RT_ERR_L2_FID - Invalid FID . ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * If the unicast mac address existed in LUT, it will return the port and fid where ++ * the mac is learned. Otherwise, it will return a RT_ERR_L2_ENTRY_NOTFOUND error. ++ */ ++extern rtk_api_ret_t rtk_l2_addr_get(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data); ++ ++/* Function Name: ++ * rtk_l2_addr_next_get ++ * Description: ++ * Get Next LUT unicast entry. ++ * Input: ++ * read_method - The reading method. ++ * port - The port number if the read_metohd is READMETHOD_NEXT_L2UCSPA ++ * pAddress - The Address ID ++ * Output: ++ * pL2_data - Unicast entry parameter ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number. ++ * RT_ERR_MAC - Invalid MAC address. ++ * RT_ERR_L2_FID - Invalid FID . ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * Get the next unicast entry after the current entry pointed by pAddress. ++ * The address of next entry is returned by pAddress. User can use (address + 1) ++ * as pAddress to call this API again for dumping all entries is LUT. ++ */ ++extern rtk_api_ret_t rtk_l2_addr_next_get(rtk_l2_read_method_t read_method, rtk_port_t port, rtk_uint32 *pAddress, rtk_l2_ucastAddr_t *pL2_data); ++ ++/* Function Name: ++ * rtk_l2_addr_del ++ * Description: ++ * Delete LUT unicast entry. ++ * Input: ++ * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. ++ * 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_MAC - Invalid MAC address. ++ * RT_ERR_L2_FID - Invalid FID . ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * If the mac has existed in the LUT, it will be deleted. Otherwise, it will return RT_ERR_L2_ENTRY_NOTFOUND. ++ */ ++extern rtk_api_ret_t rtk_l2_addr_del(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data); ++ ++/* Function Name: ++ * rtk_l2_mcastAddr_add ++ * Description: ++ * Add LUT multicast entry. ++ * Input: ++ * pMcastAddr - L2 multicast entry 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_MAC - Invalid MAC address. ++ * RT_ERR_L2_FID - Invalid FID . ++ * RT_ERR_L2_VID - Invalid VID . ++ * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. ++ * RT_ERR_PORT_MASK - Invalid portmask. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * If the multicast mac address already existed in the LUT, it will udpate the ++ * port mask of the entry. Otherwise, it will find an empty or asic auto learned ++ * entry to write. If all the entries with the same hash value can't be replaced, ++ * ASIC will return a RT_ERR_L2_INDEXTBL_FULL error. ++ */ ++extern rtk_api_ret_t rtk_l2_mcastAddr_add(rtk_l2_mcastAddr_t *pMcastAddr); ++ ++/* Function Name: ++ * rtk_l2_mcastAddr_get ++ * Description: ++ * Get LUT multicast entry. ++ * Input: ++ * pMcastAddr - L2 multicast entry structure ++ * Output: ++ * pMcastAddr - L2 multicast entry structure ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_MAC - Invalid MAC address. ++ * RT_ERR_L2_FID - Invalid FID . ++ * RT_ERR_L2_VID - Invalid VID . ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * If the multicast mac address existed in the LUT, it will return the port where ++ * the mac is learned. Otherwise, it will return a RT_ERR_L2_ENTRY_NOTFOUND error. ++ */ ++extern rtk_api_ret_t rtk_l2_mcastAddr_get(rtk_l2_mcastAddr_t *pMcastAddr); ++ ++/* Function Name: ++ * rtk_l2_mcastAddr_next_get ++ * Description: ++ * Get Next L2 Multicast entry. ++ * Input: ++ * pAddress - The Address ID ++ * Output: ++ * pMcastAddr - L2 multicast entry structure ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * Get the next L2 multicast entry after the current entry pointed by pAddress. ++ * The address of next entry is returned by pAddress. User can use (address + 1) ++ * as pAddress to call this API again for dumping all multicast entries is LUT. ++ */ ++extern rtk_api_ret_t rtk_l2_mcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_mcastAddr_t *pMcastAddr); ++ ++/* Function Name: ++ * rtk_l2_mcastAddr_del ++ * Description: ++ * Delete LUT multicast entry. ++ * Input: ++ * pMcastAddr - L2 multicast entry structure ++ * 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_L2_FID - Invalid FID . ++ * RT_ERR_L2_VID - Invalid VID . ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * If the mac has existed in the LUT, it will be deleted. Otherwise, it will return RT_ERR_L2_ENTRY_NOTFOUND. ++ */ ++extern rtk_api_ret_t rtk_l2_mcastAddr_del(rtk_l2_mcastAddr_t *pMcastAddr); ++ ++/* Function Name: ++ * rtk_l2_ipMcastAddr_add ++ * Description: ++ * Add Lut IP multicast entry ++ * Input: ++ * pIpMcastAddr - IP Multicast entry ++ * 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_L2_INDEXTBL_FULL - hashed index is full of entries. ++ * RT_ERR_PORT_MASK - Invalid portmask. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * System supports L2 entry with IP multicast DIP/SIP to forward IP multicasting frame as user ++ * desired. If this function is enabled, then system will be looked up L2 IP multicast entry to ++ * forward IP multicast frame directly without flooding. ++ */ ++extern rtk_api_ret_t rtk_l2_ipMcastAddr_add(rtk_l2_ipMcastAddr_t *pIpMcastAddr); ++ ++/* Function Name: ++ * rtk_l2_ipMcastAddr_get ++ * Description: ++ * Get LUT IP multicast entry. ++ * Input: ++ * pIpMcastAddr - IP Multicast entry ++ * Output: ++ * pIpMcastAddr - IP Multicast entry ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can get Lut table of IP multicast entry. ++ */ ++extern rtk_api_ret_t rtk_l2_ipMcastAddr_get(rtk_l2_ipMcastAddr_t *pIpMcastAddr); ++ ++/* Function Name: ++ * rtk_l2_ipMcastAddr_next_get ++ * Description: ++ * Get Next IP Multicast entry. ++ * Input: ++ * pAddress - The Address ID ++ * Output: ++ * pIpMcastAddr - IP Multicast entry ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * Get the next IP multicast entry after the current entry pointed by pAddress. ++ * The address of next entry is returned by pAddress. User can use (address + 1) ++ * as pAddress to call this API again for dumping all IP multicast entries is LUT. ++ */ ++extern rtk_api_ret_t rtk_l2_ipMcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_ipMcastAddr_t *pIpMcastAddr); ++ ++/* Function Name: ++ * rtk_l2_ipMcastAddr_del ++ * Description: ++ * Delete a ip multicast address entry from the specified device. ++ * Input: ++ * pIpMcastAddr - IP Multicast entry ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can delete a IP multicast address entry from the specified device. ++ */ ++extern rtk_api_ret_t rtk_l2_ipMcastAddr_del(rtk_l2_ipMcastAddr_t *pIpMcastAddr); ++ ++/* Function Name: ++ * rtk_l2_ipVidMcastAddr_add ++ * Description: ++ * Add Lut IP multicast+VID entry ++ * Input: ++ * pIpVidMcastAddr - IP & VID multicast Entry ++ * 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_L2_INDEXTBL_FULL - hashed index is full of entries. ++ * RT_ERR_PORT_MASK - Invalid portmask. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * ++ */ ++extern rtk_api_ret_t rtk_l2_ipVidMcastAddr_add(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr); ++ ++/* Function Name: ++ * rtk_l2_ipVidMcastAddr_get ++ * Description: ++ * Get LUT IP multicast+VID entry. ++ * Input: ++ * pIpVidMcastAddr - IP & VID multicast Entry ++ * Output: ++ * pIpVidMcastAddr - IP & VID multicast Entry ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * ++ */ ++extern rtk_api_ret_t rtk_l2_ipVidMcastAddr_get(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr); ++ ++/* Function Name: ++ * rtk_l2_ipVidMcastAddr_next_get ++ * Description: ++ * Get Next IP Multicast+VID entry. ++ * Input: ++ * pAddress - The Address ID ++ * Output: ++ * pIpVidMcastAddr - IP & VID multicast Entry ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * Get the next IP multicast entry after the current entry pointed by pAddress. ++ * The address of next entry is returned by pAddress. User can use (address + 1) ++ * as pAddress to call this API again for dumping all IP multicast entries is LUT. ++ */ ++extern rtk_api_ret_t rtk_l2_ipVidMcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr); ++ ++/* Function Name: ++ * rtk_l2_ipVidMcastAddr_del ++ * Description: ++ * Delete a ip multicast+VID address entry from the specified device. ++ * Input: ++ * pIpVidMcastAddr - IP & VID multicast Entry ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * ++ */ ++extern rtk_api_ret_t rtk_l2_ipVidMcastAddr_del(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr); ++ ++/* Function Name: ++ * rtk_l2_ucastAddr_flush ++ * Description: ++ * Flush L2 mac address by type in the specified device (both dynamic and static). ++ * Input: ++ * pConfig - flush 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. ++ * RT_ERR_VLAN_VID - Invalid VID parameter. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * flushByVid - 1: Flush by VID, 0: Don't flush by VID ++ * vid - VID (0 ~ 4095) ++ * flushByFid - 1: Flush by FID, 0: Don't flush by FID ++ * fid - FID (0 ~ 15) ++ * flushByPort - 1: Flush by Port, 0: Don't flush by Port ++ * port - Port ID ++ * flushByMac - Not Supported ++ * ucastAddr - Not Supported ++ * flushStaticAddr - 1: Flush both Static and Dynamic entries, 0: Flush only Dynamic entries ++ * flushAddrOnAllPorts - 1: Flush VID-matched entries at all ports, 0: Flush VID-matched entries per port. ++ */ ++extern rtk_api_ret_t rtk_l2_ucastAddr_flush(rtk_l2_flushCfg_t *pConfig); ++ ++/* Function Name: ++ * rtk_l2_table_clear ++ * Description: ++ * Flush all static & dynamic entries in LUT. ++ * Input: ++ * None ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * ++ */ ++extern rtk_api_ret_t rtk_l2_table_clear(void); ++ ++/* Function Name: ++ * rtk_l2_table_clearStatus_get ++ * Description: ++ * Get table clear status ++ * Input: ++ * None ++ * Output: ++ * pStatus - Clear status, 1:Busy, 0:finish ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * ++ */ ++extern rtk_api_ret_t rtk_l2_table_clearStatus_get(rtk_l2_clearStatus_t *pStatus); ++ ++/* Function Name: ++ * rtk_l2_flushLinkDownPortAddrEnable_set ++ * Description: ++ * Set HW flush linkdown port mac configuration of the specified device. ++ * Input: ++ * port - Port id. ++ * enable - link down flush 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: ++ * The status of flush linkdown port address is as following: ++ * - DISABLED ++ * - ENABLED ++ */ ++extern rtk_api_ret_t rtk_l2_flushLinkDownPortAddrEnable_set(rtk_port_t port, rtk_enable_t enable); ++ ++/* Function Name: ++ * rtk_l2_flushLinkDownPortAddrEnable_get ++ * Description: ++ * Get HW flush linkdown port mac configuration of the specified device. ++ * Input: ++ * port - Port id. ++ * Output: ++ * pEnable - link down flush status ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number. ++ * Note: ++ * The status of flush linkdown port address is as following: ++ * - DISABLED ++ * - ENABLED ++ */ ++extern rtk_api_ret_t rtk_l2_flushLinkDownPortAddrEnable_get(rtk_port_t port, rtk_enable_t *pEnable); ++ ++/* Function Name: ++ * rtk_l2_agingEnable_set ++ * Description: ++ * Set L2 LUT aging status per port setting. ++ * Input: ++ * port - Port id. ++ * enable - Aging 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 be used to set L2 LUT aging status per port. ++ */ ++extern rtk_api_ret_t rtk_l2_agingEnable_set(rtk_port_t port, rtk_enable_t enable); ++ ++/* Function Name: ++ * rtk_l2_agingEnable_get ++ * Description: ++ * Get L2 LUT aging status per port setting. ++ * Input: ++ * port - Port id. ++ * Output: ++ * pEnable - Aging 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 be used to get L2 LUT aging function per port. ++ */ ++extern rtk_api_ret_t rtk_l2_agingEnable_get(rtk_port_t port, rtk_enable_t *pEnable); ++ ++/* Function Name: ++ * rtk_l2_limitLearningCnt_set ++ * Description: ++ * Set per-Port auto learning limit number ++ * Input: ++ * port - Port id. ++ * mac_cnt - Auto learning entries limit number ++ * 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_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number ++ * Note: ++ * The API can set per-port ASIC auto learning limit number from 0(disable learning) ++ * to 8k. ++ */ ++extern rtk_api_ret_t rtk_l2_limitLearningCnt_set(rtk_port_t port, rtk_mac_cnt_t mac_cnt); ++ ++/* Function Name: ++ * rtk_l2_limitLearningCnt_get ++ * Description: ++ * Get per-Port auto learning limit number ++ * Input: ++ * port - Port id. ++ * Output: ++ * pMac_cnt - Auto learning entries limit 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 can get per-port ASIC auto learning limit number. ++ */ ++extern rtk_api_ret_t rtk_l2_limitLearningCnt_get(rtk_port_t port, rtk_mac_cnt_t *pMac_cnt); ++ ++/* Function Name: ++ * rtk_l2_limitSystemLearningCnt_set ++ * Description: ++ * Set System auto learning limit number ++ * Input: ++ * mac_cnt - Auto learning entries limit number ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number ++ * Note: ++ * The API can set system ASIC auto learning limit number from 0(disable learning) ++ * to 2112. ++ */ ++extern rtk_api_ret_t rtk_l2_limitSystemLearningCnt_set(rtk_mac_cnt_t mac_cnt); ++ ++/* Function Name: ++ * rtk_l2_limitSystemLearningCnt_get ++ * Description: ++ * Get System auto learning limit number ++ * Input: ++ * None ++ * Output: ++ * pMac_cnt - Auto learning entries limit 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 can get system ASIC auto learning limit number. ++ */ ++extern rtk_api_ret_t rtk_l2_limitSystemLearningCnt_get(rtk_mac_cnt_t *pMac_cnt); ++ ++/* Function Name: ++ * rtk_l2_limitLearningCntAction_set ++ * Description: ++ * Configure auto learn over limit number action. ++ * Input: ++ * port - Port id. ++ * action - Auto learning entries limit number ++ * 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_NOT_ALLOWED - Invalid learn over action ++ * Note: ++ * The API can set SA unknown packet action while auto learn limit number is over ++ * The action symbol as following: ++ * - LIMIT_LEARN_CNT_ACTION_DROP, ++ * - LIMIT_LEARN_CNT_ACTION_FORWARD, ++ * - LIMIT_LEARN_CNT_ACTION_TO_CPU, ++ */ ++extern rtk_api_ret_t rtk_l2_limitLearningCntAction_set(rtk_port_t port, rtk_l2_limitLearnCntAction_t action); ++ ++/* Function Name: ++ * rtk_l2_limitLearningCntAction_get ++ * Description: ++ * Get auto learn over limit number action. ++ * Input: ++ * port - Port id. ++ * Output: ++ * pAction - Learn over action ++ * 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 SA unknown packet action while auto learn limit number is over ++ * The action symbol as following: ++ * - LIMIT_LEARN_CNT_ACTION_DROP, ++ * - LIMIT_LEARN_CNT_ACTION_FORWARD, ++ * - LIMIT_LEARN_CNT_ACTION_TO_CPU, ++ */ ++extern rtk_api_ret_t rtk_l2_limitLearningCntAction_get(rtk_port_t port, rtk_l2_limitLearnCntAction_t *pAction); ++ ++/* Function Name: ++ * rtk_l2_limitSystemLearningCntAction_set ++ * Description: ++ * Configure system auto learn over limit number action. ++ * Input: ++ * port - Port id. ++ * action - Auto learning entries limit number ++ * 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_NOT_ALLOWED - Invalid learn over action ++ * Note: ++ * The API can set SA unknown packet action while auto learn limit number is over ++ * The action symbol as following: ++ * - LIMIT_LEARN_CNT_ACTION_DROP, ++ * - LIMIT_LEARN_CNT_ACTION_FORWARD, ++ * - LIMIT_LEARN_CNT_ACTION_TO_CPU, ++ */ ++extern rtk_api_ret_t rtk_l2_limitSystemLearningCntAction_set(rtk_l2_limitLearnCntAction_t action); ++ ++/* Function Name: ++ * rtk_l2_limitSystemLearningCntAction_get ++ * Description: ++ * Get system auto learn over limit number action. ++ * Input: ++ * None. ++ * Output: ++ * pAction - Learn over action ++ * 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 SA unknown packet action while auto learn limit number is over ++ * The action symbol as following: ++ * - LIMIT_LEARN_CNT_ACTION_DROP, ++ * - LIMIT_LEARN_CNT_ACTION_FORWARD, ++ * - LIMIT_LEARN_CNT_ACTION_TO_CPU, ++ */ ++extern rtk_api_ret_t rtk_l2_limitSystemLearningCntAction_get(rtk_l2_limitLearnCntAction_t *pAction); ++ ++/* Function Name: ++ * rtk_l2_limitSystemLearningCntPortMask_set ++ * Description: ++ * Configure system auto learn portmask ++ * Input: ++ * pPortmask - 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: ++ * ++ */ ++extern rtk_api_ret_t rtk_l2_limitSystemLearningCntPortMask_set(rtk_portmask_t *pPortmask); ++ ++/* Function Name: ++ * rtk_l2_limitSystemLearningCntPortMask_get ++ * Description: ++ * get system auto learn portmask ++ * Input: ++ * None ++ * Output: ++ * pPortmask - Port Mask ++ * 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_l2_limitSystemLearningCntPortMask_get(rtk_portmask_t *pPortmask); ++ ++/* Function Name: ++ * rtk_l2_learningCnt_get ++ * Description: ++ * Get per-Port current auto learning number ++ * Input: ++ * port - Port id. ++ * Output: ++ * pMac_cnt - ASIC auto learning entries 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 can get per-port ASIC auto learning number ++ */ ++extern rtk_api_ret_t rtk_l2_learningCnt_get(rtk_port_t port, rtk_mac_cnt_t *pMac_cnt); ++ ++/* Function Name: ++ * rtk_l2_floodPortMask_set ++ * Description: ++ * Set flooding portmask ++ * Input: ++ * type - flooding type. ++ * pFlood_portmask - flooding porkmask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_MASK - Invalid portmask. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * This API can set the flooding mask. ++ * The flooding type is as following: ++ * - FLOOD_UNKNOWNDA ++ * - FLOOD_UNKNOWNMC ++ * - FLOOD_BC ++ */ ++extern rtk_api_ret_t rtk_l2_floodPortMask_set(rtk_l2_flood_type_t floood_type, rtk_portmask_t *pFlood_portmask); ++ ++/* Function Name: ++ * rtk_l2_floodPortMask_get ++ * Description: ++ * Get flooding portmask ++ * Input: ++ * type - flooding type. ++ * Output: ++ * pFlood_portmask - flooding porkmask ++ * 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 flooding mask. ++ * The flooding type is as following: ++ * - FLOOD_UNKNOWNDA ++ * - FLOOD_UNKNOWNMC ++ * - FLOOD_BC ++ */ ++extern rtk_api_ret_t rtk_l2_floodPortMask_get(rtk_l2_flood_type_t floood_type, rtk_portmask_t *pFlood_portmask); ++ ++/* Function Name: ++ * rtk_l2_localPktPermit_set ++ * Description: ++ * Set permittion of frames if source port and destination port are the same. ++ * Input: ++ * port - Port id. ++ * permit - permittion 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 permit value. ++ * Note: ++ * This API is setted to permit frame if its source port is equal to destination port. ++ */ ++extern rtk_api_ret_t rtk_l2_localPktPermit_set(rtk_port_t port, rtk_enable_t permit); ++ ++/* Function Name: ++ * rtk_l2_localPktPermit_get ++ * Description: ++ * Get permittion of frames if source port and destination port are the same. ++ * Input: ++ * port - Port id. ++ * Output: ++ * pPermit - permittion 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 is to get permittion status for frames if its source port is equal to destination port. ++ */ ++extern rtk_api_ret_t rtk_l2_localPktPermit_get(rtk_port_t port, rtk_enable_t *pPermit); ++ ++/* Function Name: ++ * rtk_l2_aging_set ++ * Description: ++ * Set LUT agging out speed ++ * Input: ++ * aging_time - Agging out time. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * Note: ++ * The API can set LUT agging out period for each entry and the range is from 14s to 800s. ++ */ ++extern rtk_api_ret_t rtk_l2_aging_set(rtk_l2_age_time_t aging_time); ++ ++/* Function Name: ++ * rtk_l2_aging_get ++ * Description: ++ * Get LUT agging out time ++ * Input: ++ * None ++ * Output: ++ * pEnable - Aging status ++ * 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 LUT agging out period for each entry. ++ */ ++extern rtk_api_ret_t rtk_l2_aging_get(rtk_l2_age_time_t *pAging_time); ++ ++/* Function Name: ++ * rtk_l2_ipMcastAddrLookup_set ++ * Description: ++ * Set Lut IP multicast lookup function ++ * Input: ++ * type - Lookup type for IPMC packet. ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * This API can work with rtk_l2_ipMcastAddrLookupException_add. ++ * If users set the lookup type to DIP, the group in exception table ++ * will be lookup by DIP+SIP ++ * If users set the lookup type to DIP+SIP, the group in exception table ++ * will be lookup by only DIP ++ */ ++extern rtk_api_ret_t rtk_l2_ipMcastAddrLookup_set(rtk_l2_ipmc_lookup_type_t type); ++ ++/* Function Name: ++ * rtk_l2_ipMcastAddrLookup_get ++ * Description: ++ * Get Lut IP multicast lookup function ++ * Input: ++ * None. ++ * Output: ++ * pType - Lookup type for IPMC packet. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None. ++ */ ++extern rtk_api_ret_t rtk_l2_ipMcastAddrLookup_get(rtk_l2_ipmc_lookup_type_t *pType); ++ ++/* Function Name: ++ * rtk_l2_ipMcastForwardRouterPort_set ++ * Description: ++ * Set IPMC packet forward to rounter port also or not ++ * Input: ++ * enabled - 1: Inlcude router port, 0, exclude router port ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * ++ */ ++extern rtk_api_ret_t rtk_l2_ipMcastForwardRouterPort_set(rtk_enable_t enabled); ++ ++/* Function Name: ++ * rtk_l2_ipMcastForwardRouterPort_get ++ * Description: ++ * Get IPMC packet forward to rounter port also or not ++ * Input: ++ * None. ++ * Output: ++ * pEnabled - 1: Inlcude router port, 0, exclude router port ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_NULL_POINTER - Null pointer ++ * Note: ++ * ++ */ ++extern rtk_api_ret_t rtk_l2_ipMcastForwardRouterPort_get(rtk_enable_t *pEnabled); ++ ++/* Function Name: ++ * rtk_l2_ipMcastGroupEntry_add ++ * Description: ++ * Add an IP Multicast entry to group table ++ * Input: ++ * ip_addr - IP address ++ * vid - VLAN ID ++ * pPortmask - portmask ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_TBL_FULL - Table Full ++ * Note: ++ * Add an entry to IP Multicast Group table. ++ */ ++extern rtk_api_ret_t rtk_l2_ipMcastGroupEntry_add(ipaddr_t ip_addr, rtk_uint32 vid, rtk_portmask_t *pPortmask); ++ ++/* Function Name: ++ * rtk_l2_ipMcastGroupEntry_del ++ * Description: ++ * Delete an entry from IP Multicast group table ++ * Input: ++ * ip_addr - IP address ++ * vid - VLAN ID ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_TBL_FULL - Table Full ++ * Note: ++ * Delete an entry from IP Multicast group table. ++ */ ++extern rtk_api_ret_t rtk_l2_ipMcastGroupEntry_del(ipaddr_t ip_addr, rtk_uint32 vid); ++ ++/* Function Name: ++ * rtk_l2_ipMcastGroupEntry_get ++ * Description: ++ * get an entry from IP Multicast group table ++ * Input: ++ * ip_addr - IP address ++ * vid - VLAN ID ++ * Output: ++ * pPortmask - member port mask ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_TBL_FULL - Table Full ++ * Note: ++ * Delete an entry from IP Multicast group table. ++ */ ++extern rtk_api_ret_t rtk_l2_ipMcastGroupEntry_get(ipaddr_t ip_addr, rtk_uint32 vid, rtk_portmask_t *pPortmask); ++ ++/* Function Name: ++ * rtk_l2_entry_get ++ * Description: ++ * Get LUT unicast entry. ++ * Input: ++ * pL2_entry - Index field in the structure. ++ * Output: ++ * pL2_entry - other fields such as MAC, port, age... ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_L2_EMPTY_ENTRY - Empty LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * This API is used to get address by index from 0~2111. ++ */ ++extern rtk_api_ret_t rtk_l2_entry_get(rtk_l2_addr_table_t *pL2_entry); ++ ++ ++#endif /* __RTK_API_L2_H__ */ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/leaky.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/leaky.h +new file mode 100644 +index 0000000000..13ef60df83 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/leaky.h +@@ -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__ */ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/led.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/led.h +new file mode 100644 +index 0000000000..71acc7c92c +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/led.h +@@ -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__ */ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/mirror.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/mirror.h +new file mode 100644 +index 0000000000..1e984b7d80 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/mirror.h +@@ -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__ */ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/oam.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/oam.h +new file mode 100644 +index 0000000000..1fc14bd62f +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/oam.h +@@ -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__ */ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/port.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/port.h +new file mode 100644 +index 0000000000..fcac1bcb84 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/port.h +@@ -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__ */ ++ ++ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/ptp.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/ptp.h +new file mode 100644 +index 0000000000..6c4aca5a58 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/ptp.h +@@ -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__ */ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/qos.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/qos.h +new file mode 100644 +index 0000000000..4be417486f +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/qos.h +@@ -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__ */ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rate.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rate.h +new file mode 100644 +index 0000000000..231ed01bb0 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rate.h +@@ -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 ++ ++/* ++ * 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__ */ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rldp.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rldp.h +new file mode 100644 +index 0000000000..111de0c093 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rldp.h +@@ -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__ */ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtk_error.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtk_error.h +new file mode 100644 +index 0000000000..dc9c0bed35 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtk_error.h +@@ -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__ */ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtk_hal.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtk_hal.h +new file mode 100644 +index 0000000000..6ddb23f2ed +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtk_hal.h +@@ -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 +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtk_switch.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtk_switch.h +new file mode 100644 +index 0000000000..b0ca13682c +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtk_switch.h +@@ -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 ++ ++#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 +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtk_types.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtk_types.h +new file mode 100644 +index 0000000000..589ecb7811 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtk_types.h +@@ -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 ++ ++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_ */ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv.h +new file mode 100644 +index 0000000000..55cb41b067 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv.h +@@ -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 ++#include ++#include ++#include ++ ++#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_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_acl.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_acl.h +new file mode 100644 +index 0000000000..8ae69ac332 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_acl.h +@@ -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 ++ ++#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_*/ ++ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_cputag.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_cputag.h +new file mode 100644 +index 0000000000..f7a460145e +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_cputag.h +@@ -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 ++ ++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_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_dot1x.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_dot1x.h +new file mode 100644 +index 0000000000..7639ae782b +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_dot1x.h +@@ -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 ++ ++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_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eav.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eav.h +new file mode 100644 +index 0000000000..b633f66fb0 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eav.h +@@ -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 ++ ++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_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eee.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eee.h +new file mode 100644 +index 0000000000..6bedce62b0 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_eee.h +@@ -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 ++ ++#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_*/ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_fc.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_fc.h +new file mode 100644 +index 0000000000..ce67cdebac +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_fc.h +@@ -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 ++ ++#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_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_green.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_green.h +new file mode 100644 +index 0000000000..38fd085d06 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_green.h +@@ -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 ++#include ++ ++#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_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_hsb.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_hsb.h +new file mode 100644 +index 0000000000..f4f9bb377b +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_hsb.h +@@ -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 ++ ++#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_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_i2c.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_i2c.h +new file mode 100644 +index 0000000000..d5b095a0e5 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_i2c.h +@@ -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 ++#include ++ ++ ++#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_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_igmp.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_igmp.h +new file mode 100644 +index 0000000000..b879b6b520 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_igmp.h +@@ -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 ++ ++#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 ++ ++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_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_inbwctrl.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_inbwctrl.h +new file mode 100644 +index 0000000000..10f3545322 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_inbwctrl.h +@@ -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 ++ ++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_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_interrupt.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_interrupt.h +new file mode 100644 +index 0000000000..8b78014ab0 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_interrupt.h +@@ -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 ++ ++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_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_led.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_led.h +new file mode 100644 +index 0000000000..a7f8e20643 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_led.h +@@ -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 ++ ++#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_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_lut.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_lut.h +new file mode 100644 +index 0000000000..c94ea07601 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_lut.h +@@ -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 ++ ++#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_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_meter.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_meter.h +new file mode 100644 +index 0000000000..ba761a94f8 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_meter.h +@@ -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 ++ ++ ++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_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mib.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mib.h +new file mode 100644 +index 0000000000..ca46e0f470 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mib.h +@@ -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 ++ ++#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_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mirror.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mirror.h +new file mode 100644 +index 0000000000..23b788d7a6 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_mirror.h +@@ -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 : Port mirror related functions ++ * ++ */ ++ ++#ifndef _RTL8367C_ASICDRV_MIRROR_H_ ++#define _RTL8367C_ASICDRV_MIRROR_H_ ++ ++#include ++ ++extern ret_t rtl8367c_setAsicPortMirror(rtk_uint32 source, rtk_uint32 monitor); ++extern ret_t rtl8367c_getAsicPortMirror(rtk_uint32 *pSource, rtk_uint32 *pMonitor); ++extern ret_t rtl8367c_setAsicPortMirrorRxFunction(rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicPortMirrorRxFunction(rtk_uint32* pEnabled); ++extern ret_t rtl8367c_setAsicPortMirrorTxFunction(rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicPortMirrorTxFunction(rtk_uint32* pEnabled); ++extern ret_t rtl8367c_setAsicPortMirrorIsolation(rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicPortMirrorIsolation(rtk_uint32* pEnabled); ++extern ret_t rtl8367c_setAsicPortMirrorPriority(rtk_uint32 priority); ++extern ret_t rtl8367c_getAsicPortMirrorPriority(rtk_uint32* pPriority); ++extern ret_t rtl8367c_setAsicPortMirrorMask(rtk_uint32 SourcePortmask); ++extern ret_t rtl8367c_getAsicPortMirrorMask(rtk_uint32 *pSourcePortmask); ++extern ret_t rtl8367c_setAsicPortMirrorVlanRxLeaky(rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicPortMirrorVlanRxLeaky(rtk_uint32* pEnabled); ++extern ret_t rtl8367c_setAsicPortMirrorVlanTxLeaky(rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicPortMirrorVlanTxLeaky(rtk_uint32* pEnabled); ++extern ret_t rtl8367c_setAsicPortMirrorIsolationRxLeaky(rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicPortMirrorIsolationRxLeaky(rtk_uint32* pEnabled); ++extern ret_t rtl8367c_setAsicPortMirrorIsolationTxLeaky(rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicPortMirrorIsolationTxLeaky(rtk_uint32* pEnabled); ++extern ret_t rtl8367c_setAsicPortMirrorRealKeep(rtk_uint32 mode); ++extern ret_t rtl8367c_getAsicPortMirrorRealKeep(rtk_uint32* pMode); ++extern ret_t rtl8367c_setAsicPortMirrorOverride(rtk_uint32 rxMirror, rtk_uint32 txMirror, rtk_uint32 aclMirror); ++extern ret_t rtl8367c_getAsicPortMirrorOverride(rtk_uint32 *pRxMirror, rtk_uint32 *pTxMirror, rtk_uint32 *pAclMirror); ++ ++#endif /*#ifndef _RTL8367C_ASICDRV_MIRROR_H_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_misc.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_misc.h +new file mode 100644 +index 0000000000..c666a7b58b +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_misc.h +@@ -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 : Miscellaneous functions ++ * ++ */ ++ ++#ifndef _RTL8367C_ASICDRV_MISC_H_ ++#define _RTL8367C_ASICDRV_MISC_H_ ++ ++#include ++ ++extern ret_t rtl8367c_setAsicMacAddress(ether_addr_t mac); ++extern ret_t rtl8367c_getAsicMacAddress(ether_addr_t *pMac); ++extern ret_t rtl8367c_getAsicDebugInfo(rtk_uint32 port, rtk_uint32 *pDebugifo); ++extern ret_t rtl8367c_setAsicPortJamMode(rtk_uint32 mode); ++extern ret_t rtl8367c_getAsicPortJamMode(rtk_uint32* pMode); ++extern ret_t rtl8367c_setAsicMaxLengthCfg(rtk_uint32 cfgId, rtk_uint32 maxLength); ++extern ret_t rtl8367c_getAsicMaxLengthCfg(rtk_uint32 cfgId, rtk_uint32 *pMaxLength); ++extern ret_t rtl8367c_setAsicMaxLength(rtk_uint32 port, rtk_uint32 type, rtk_uint32 cfgId); ++extern ret_t rtl8367c_getAsicMaxLength(rtk_uint32 port, rtk_uint32 type, rtk_uint32 *pCfgId); ++ ++#endif /*_RTL8367C_ASICDRV_MISC_H_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_oam.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_oam.h +new file mode 100644 +index 0000000000..c09dc76988 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_oam.h +@@ -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: 42321 $ ++ * $Date: 2013-08-26 13:51:29 +0800 (¶g¤@, 26 ¤K¤ë 2013) $ ++ * ++ * Purpose : RTL8367C switch high-level API for RTL8367C ++ * Feature : OAM related functions ++ * ++ */ ++ ++#ifndef _RTL8367C_ASICDRV_OAM_H_ ++#define _RTL8367C_ASICDRV_OAM_H_ ++ ++#include ++ ++enum OAMPARACT ++{ ++ OAM_PARFWD = 0, ++ OAM_PARLB, ++ OAM_PARDISCARD, ++ OAM_PARFWDCPU ++}; ++ ++enum OAMMULACT ++{ ++ OAM_MULFWD = 0, ++ OAM_MULDISCARD, ++ OAM_MULCPU ++}; ++ ++extern ret_t rtl8367c_setAsicOamParser(rtk_uint32 port, rtk_uint32 parser); ++extern ret_t rtl8367c_getAsicOamParser(rtk_uint32 port, rtk_uint32* pParser); ++extern ret_t rtl8367c_setAsicOamMultiplexer(rtk_uint32 port, rtk_uint32 multiplexer); ++extern ret_t rtl8367c_getAsicOamMultiplexer(rtk_uint32 port, rtk_uint32* pMultiplexer); ++extern ret_t rtl8367c_setAsicOamCpuPri(rtk_uint32 priority); ++extern ret_t rtl8367c_getAsicOamCpuPri(rtk_uint32 *pPriority); ++extern ret_t rtl8367c_setAsicOamEnable(rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicOamEnable(rtk_uint32 *pEnabled); ++#endif /*_RTL8367C_ASICDRV_OAM_H_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_phy.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_phy.h +new file mode 100644 +index 0000000000..e993d6edf7 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_phy.h +@@ -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 : PHY related functions ++ * ++ */ ++ ++#ifndef _RTL8367C_ASICDRV_PHY_H_ ++#define _RTL8367C_ASICDRV_PHY_H_ ++ ++#include ++ ++#define RTL8367C_PHY_REGNOMAX 0x1F ++#define RTL8367C_PHY_EXTERNALMAX 0x7 ++ ++#define RTL8367C_PHY_BASE 0x2000 ++#define RTL8367C_PHY_EXT_BASE 0xA000 ++ ++#define RTL8367C_PHY_OFFSET 5 ++#define RTL8367C_PHY_EXT_OFFSET 9 ++ ++#define RTL8367C_PHY_PAGE_ADDRESS 31 ++ ++ ++extern ret_t rtl8367c_setAsicPHYReg(rtk_uint32 phyNo, rtk_uint32 phyAddr, rtk_uint32 regData ); ++extern ret_t rtl8367c_getAsicPHYReg(rtk_uint32 phyNo, rtk_uint32 phyAddr, rtk_uint32* pRegData ); ++extern ret_t rtl8367c_setAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 ocpData ); ++extern ret_t rtl8367c_getAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 *pRegData ); ++extern ret_t rtl8367c_setAsicSdsReg(rtk_uint32 sdsId, rtk_uint32 sdsReg, rtk_uint32 sdsPage, rtk_uint32 value); ++extern ret_t rtl8367c_getAsicSdsReg(rtk_uint32 sdsId, rtk_uint32 sdsReg, rtk_uint32 sdsPage, rtk_uint32 *value); ++ ++#endif /*#ifndef _RTL8367C_ASICDRV_PHY_H_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_port.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_port.h +new file mode 100644 +index 0000000000..ad99d8560b +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_port.h +@@ -0,0 +1,237 @@ ++/* ++ * 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: 76333 $ ++ * $Date: 2017-03-09 09:33:15 +0800 (¶g¥|, 09 ¤T¤ë 2017) $ ++ * ++ * Purpose : RTL8367C switch high-level API for RTL8367C ++ * Feature : Port security related functions ++ * ++ */ ++ ++#ifndef _RTL8367C_ASICDRV_PORTSECURITY_H_ ++#define _RTL8367C_ASICDRV_PORTSECURITY_H_ ++ ++#include ++#include ++#include ++ ++/****************************************************************/ ++/* Type Definition */ ++/****************************************************************/ ++ ++#define RTL8367C_MAC7 7 ++#define RTL8367C_EXTNO 3 ++ ++#define RTL8367C_RTCT_PAGE (11) ++#define RTL8367C_RTCT_RESULT_A_REG (27) ++#define RTL8367C_RTCT_RESULT_B_REG (28) ++#define RTL8367C_RTCT_RESULT_C_REG (29) ++#define RTL8367C_RTCT_RESULT_D_REG (30) ++#define RTL8367C_RTCT_STATUS_REG (26) ++ ++enum L2_SECURITY_BEHAVE ++{ ++ L2_BEHAVE_FLOODING = 0, ++ L2_BEHAVE_DROP, ++ L2_BEHAVE_TRAP, ++ L2_BEHAVE_END ++}; ++ ++enum L2_UNDA_BEHAVE ++{ ++ L2_UNDA_BEHAVE_FLOODING_PMASK = 0, ++ L2_UNDA_BEHAVE_DROP, ++ L2_UNDA_BEHAVE_TRAP, ++ L2_UNDA_BEHAVE_FLOODING, ++ L2_UNDA_BEHAVE_END ++}; ++ ++enum L2_SECURITY_SA_BEHAVE ++{ ++ L2_BEHAVE_SA_FLOODING = 0, ++ L2_BEHAVE_SA_DROP, ++ L2_BEHAVE_SA_TRAP, ++ L2_BEHAVE_SA_COPY28051, ++ L2_BEHAVE_SA_END ++}; ++ ++/* enum for port current link speed */ ++enum SPEEDMODE ++{ ++ SPD_10M = 0, ++ SPD_100M, ++ SPD_1000M, ++ SPD_2500M ++}; ++ ++/* enum for mac link mode */ ++enum LINKMODE ++{ ++ MAC_NORMAL = 0, ++ MAC_FORCE, ++}; ++ ++/* enum for port current link duplex mode */ ++enum DUPLEXMODE ++{ ++ HALF_DUPLEX = 0, ++ FULL_DUPLEX ++}; ++ ++/* enum for port current MST mode */ ++enum MSTMODE ++{ ++ SLAVE_MODE= 0, ++ MASTER_MODE ++}; ++ ++ ++enum EXTMODE ++{ ++ EXT_DISABLE = 0, ++ EXT_RGMII, ++ EXT_MII_MAC, ++ EXT_MII_PHY, ++ EXT_TMII_MAC, ++ EXT_TMII_PHY, ++ EXT_GMII, ++ EXT_RMII_MAC, ++ EXT_RMII_PHY, ++ EXT_SGMII, ++ EXT_HSGMII, ++ EXT_1000X_100FX, ++ EXT_1000X, ++ EXT_100FX, ++ EXT_RGMII_2, ++ EXT_MII_MAC_2, ++ EXT_MII_PHY_2, ++ EXT_TMII_MAC_2, ++ EXT_TMII_PHY_2, ++ EXT_RMII_MAC_2, ++ EXT_RMII_PHY_2, ++ EXT_END ++}; ++ ++enum DOSTYPE ++{ ++ DOS_DAEQSA = 0, ++ DOS_LANDATTACKS, ++ DOS_BLATATTACKS, ++ DOS_SYNFINSCAN, ++ DOS_XMASCAN, ++ DOS_NULLSCAN, ++ DOS_SYN1024, ++ DOS_TCPSHORTHDR, ++ DOS_TCPFRAGERROR, ++ DOS_ICMPFRAGMENT, ++ DOS_END, ++ ++}; ++ ++typedef struct rtl8367c_port_ability_s{ ++ rtk_uint16 forcemode; ++ rtk_uint16 mstfault; ++ rtk_uint16 mstmode; ++ rtk_uint16 nway; ++ rtk_uint16 txpause; ++ rtk_uint16 rxpause; ++ rtk_uint16 link; ++ rtk_uint16 duplex; ++ rtk_uint16 speed; ++}rtl8367c_port_ability_t; ++ ++typedef struct rtl8367c_port_status_s{ ++ ++ rtk_uint16 lpi1000; ++ rtk_uint16 lpi100; ++ rtk_uint16 mstfault; ++ rtk_uint16 mstmode; ++ rtk_uint16 nway; ++ rtk_uint16 txpause; ++ rtk_uint16 rxpause; ++ rtk_uint16 link; ++ rtk_uint16 duplex; ++ rtk_uint16 speed; ++ ++}rtl8367c_port_status_t; ++ ++typedef struct rtct_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; ++} rtl8367c_port_rtct_result_t; ++ ++ ++/****************************************************************/ ++/* Driver Proto Type Definition */ ++/****************************************************************/ ++extern ret_t rtl8367c_setAsicPortUnknownDaBehavior(rtk_uint32 port, rtk_uint32 behavior); ++extern ret_t rtl8367c_getAsicPortUnknownDaBehavior(rtk_uint32 port, rtk_uint32 *pBehavior); ++extern ret_t rtl8367c_setAsicPortUnknownSaBehavior(rtk_uint32 behavior); ++extern ret_t rtl8367c_getAsicPortUnknownSaBehavior(rtk_uint32 *pBehavior); ++extern ret_t rtl8367c_setAsicPortUnmatchedSaBehavior(rtk_uint32 behavior); ++extern ret_t rtl8367c_getAsicPortUnmatchedSaBehavior(rtk_uint32 *pBehavior); ++extern ret_t rtl8367c_setAsicPortUnmatchedSaMoving(rtk_uint32 port, rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicPortUnmatchedSaMoving(rtk_uint32 port, rtk_uint32 *pEnabled); ++extern ret_t rtl8367c_setAsicPortUnknownDaFloodingPortmask(rtk_uint32 portmask); ++extern ret_t rtl8367c_getAsicPortUnknownDaFloodingPortmask(rtk_uint32 *pPortmask); ++extern ret_t rtl8367c_setAsicPortUnknownMulticastFloodingPortmask(rtk_uint32 portmask); ++extern ret_t rtl8367c_getAsicPortUnknownMulticastFloodingPortmask(rtk_uint32 *pPortmask); ++extern ret_t rtl8367c_setAsicPortBcastFloodingPortmask(rtk_uint32 portmask); ++extern ret_t rtl8367c_getAsicPortBcastFloodingPortmask(rtk_uint32 *pPortmask); ++extern ret_t rtl8367c_setAsicPortBlockSpa(rtk_uint32 port, rtk_uint32 block); ++extern ret_t rtl8367c_getAsicPortBlockSpa(rtk_uint32 port, rtk_uint32 *pBlock); ++extern ret_t rtl8367c_setAsicPortForceLink(rtk_uint32 port, rtl8367c_port_ability_t *pPortAbility); ++extern ret_t rtl8367c_getAsicPortForceLink(rtk_uint32 port, rtl8367c_port_ability_t *pPortAbility); ++extern ret_t rtl8367c_getAsicPortStatus(rtk_uint32 port, rtl8367c_port_status_t *pPortStatus); ++extern ret_t rtl8367c_setAsicPortForceLinkExt(rtk_uint32 id, rtl8367c_port_ability_t *pPortAbility); ++extern ret_t rtl8367c_getAsicPortForceLinkExt(rtk_uint32 id, rtl8367c_port_ability_t *pPortAbility); ++extern ret_t rtl8367c_setAsicPortExtMode(rtk_uint32 id, rtk_uint32 mode); ++extern ret_t rtl8367c_getAsicPortExtMode(rtk_uint32 id, rtk_uint32 *pMode); ++extern ret_t rtl8367c_setAsicPortDos(rtk_uint32 type, rtk_uint32 drop); ++extern ret_t rtl8367c_getAsicPortDos(rtk_uint32 type, rtk_uint32* pDrop); ++extern ret_t rtl8367c_setAsicPortEnableAll(rtk_uint32 enable); ++extern ret_t rtl8367c_getAsicPortEnableAll(rtk_uint32 *pEnable); ++extern ret_t rtl8367c_setAsicPortSmallIpg(rtk_uint32 port, rtk_uint32 enable); ++extern ret_t rtl8367c_getAsicPortSmallIpg(rtk_uint32 port, rtk_uint32* pEnable); ++extern ret_t rtl8367c_setAsicPortLoopback(rtk_uint32 port, rtk_uint32 enable); ++extern ret_t rtl8367c_getAsicPortLoopback(rtk_uint32 port, rtk_uint32 *pEnable); ++extern ret_t rtl8367c_setAsicPortRTCTEnable(rtk_uint32 portmask); ++extern ret_t rtl8367c_setAsicPortRTCTDisable(rtk_uint32 portmask); ++extern ret_t rtl8367c_getAsicPortRTCTResult(rtk_uint32 port, rtl8367c_port_rtct_result_t *pResult); ++extern ret_t rtl8367c_sdsReset(rtk_uint32 id); ++extern ret_t rtl8367c_getSdsLinkStatus(rtk_uint32 ext_id, rtk_uint32 *pSignalDetect, rtk_uint32 *pSync, rtk_uint32 *pLink); ++extern ret_t rtl8367c_setSgmiiNway(rtk_uint32 ext_id, rtk_uint32 state); ++extern ret_t rtl8367c_getSgmiiNway(rtk_uint32 ext_id, rtk_uint32 *pState); ++ ++#endif /*_RTL8367C_ASICDRV_PORTSECURITY_H_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_portIsolation.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_portIsolation.h +new file mode 100644 +index 0000000000..e23d88e81f +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_portIsolation.h +@@ -0,0 +1,28 @@ ++/* ++ * 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 : Port isolation related functions ++ * ++ */ ++ ++#ifndef _RTL8367C_ASICDRV_PORTISOLATION_H_ ++#define _RTL8367C_ASICDRV_PORTISOLATION_H_ ++ ++#include ++ ++extern ret_t rtl8367c_setAsicPortIsolationPermittedPortmask(rtk_uint32 port, rtk_uint32 permitPortmask); ++extern ret_t rtl8367c_getAsicPortIsolationPermittedPortmask(rtk_uint32 port, rtk_uint32 *pPermitPortmask); ++extern ret_t rtl8367c_setAsicPortIsolationEfid(rtk_uint32 port, rtk_uint32 efid); ++extern ret_t rtl8367c_getAsicPortIsolationEfid(rtk_uint32 port, rtk_uint32 *pEfid); ++ ++#endif /*_RTL8367C_ASICDRV_PORTISOLATION_H_*/ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_qos.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_qos.h +new file mode 100644 +index 0000000000..26042bfa13 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_qos.h +@@ -0,0 +1,96 @@ ++/* ++ * 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 : Qos related functions ++ * ++ */ ++ ++#ifndef _RTL8367C_ASICDRV_QOS_H_ ++#define _RTL8367C_ASICDRV_QOS_H_ ++ ++#include ++ ++#define RTL8367C_DECISIONPRIMAX 0xFF ++ ++/* enum Priority Selection Types */ ++enum PRIDECISION ++{ ++ PRIDEC_PORT = 0, ++ PRIDEC_ACL, ++ PRIDEC_DSCP, ++ PRIDEC_1Q, ++ PRIDEC_1AD, ++ PRIDEC_CVLAN, ++ PRIDEC_DA, ++ PRIDEC_SA, ++ PRIDEC_END, ++}; ++ ++/* enum Priority Selection Index */ ++enum RTL8367C_PRIDEC_TABLE ++{ ++ PRIDEC_IDX0 = 0, ++ PRIDEC_IDX1, ++ PRIDEC_IDX_END, ++}; ++ ++enum RTL8367C_DOT1P_PRISEL ++{ ++ DOT1P_PRISEL_USER = 0, ++ DOT1P_PRISEL_TAG, ++ DOT1P_PRISEL_END ++}; ++ ++enum RTL8367C_DSCP_PRISEL ++{ ++ DSCP_PRISEL_INTERNAL = 0, ++ DSCP_PRISEL_DSCP, ++ DSCP_PRISEL_USER , ++ DSCP_PRISEL_END ++}; ++ ++ ++extern ret_t rtl8367c_setAsicRemarkingDot1pAbility(rtk_uint32 port, rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicRemarkingDot1pAbility(rtk_uint32 port, rtk_uint32* pEnabled); ++extern ret_t rtl8367c_setAsicRemarkingDot1pParameter(rtk_uint32 priority, rtk_uint32 newPriority ); ++extern ret_t rtl8367c_getAsicRemarkingDot1pParameter(rtk_uint32 priority, rtk_uint32 *pNewPriority ); ++extern ret_t rtl8367c_setAsicRemarkingDot1pSrc(rtk_uint32 type); ++extern ret_t rtl8367c_getAsicRemarkingDot1pSrc(rtk_uint32 *pType); ++extern ret_t rtl8367c_setAsicRemarkingDscpAbility(rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicRemarkingDscpAbility(rtk_uint32* pEnabled); ++extern ret_t rtl8367c_setAsicRemarkingDscpParameter(rtk_uint32 priority, rtk_uint32 newDscp ); ++extern ret_t rtl8367c_getAsicRemarkingDscpParameter(rtk_uint32 priority, rtk_uint32* pNewDscp ); ++ ++extern ret_t rtl8367c_setAsicPriorityDot1qRemapping(rtk_uint32 srcpriority, rtk_uint32 priority ); ++extern ret_t rtl8367c_getAsicPriorityDot1qRemapping(rtk_uint32 srcpriority, rtk_uint32 *pPriority ); ++extern ret_t rtl8367c_setAsicPriorityDscpBased(rtk_uint32 dscp, rtk_uint32 priority ); ++extern ret_t rtl8367c_getAsicPriorityDscpBased(rtk_uint32 dscp, rtk_uint32 *pPriority ); ++extern ret_t rtl8367c_setAsicPriorityPortBased(rtk_uint32 port, rtk_uint32 priority ); ++extern ret_t rtl8367c_getAsicPriorityPortBased(rtk_uint32 port, rtk_uint32 *pPriority ); ++extern ret_t rtl8367c_setAsicPriorityDecision(rtk_uint32 index, rtk_uint32 prisrc, rtk_uint32 decisionPri); ++extern ret_t rtl8367c_getAsicPriorityDecision(rtk_uint32 index, rtk_uint32 prisrc, rtk_uint32* pDecisionPri); ++extern ret_t rtl8367c_setAsicPriorityToQIDMappingTable(rtk_uint32 qnum, rtk_uint32 priority, rtk_uint32 qid ); ++extern ret_t rtl8367c_getAsicPriorityToQIDMappingTable(rtk_uint32 qnum, rtk_uint32 priority, rtk_uint32* pQid); ++extern ret_t rtl8367c_setAsicOutputQueueMappingIndex(rtk_uint32 port, rtk_uint32 qnum ); ++extern ret_t rtl8367c_getAsicOutputQueueMappingIndex(rtk_uint32 port, rtk_uint32 *pQnum ); ++ ++extern ret_t rtl8367c_setAsicRemarkingDscpSrc(rtk_uint32 type); ++extern ret_t rtl8367c_getAsicRemarkingDscpSrc(rtk_uint32 *pType); ++extern ret_t rtl8367c_setAsicRemarkingDscp2Dscp(rtk_uint32 dscp, rtk_uint32 rmkDscp); ++extern ret_t rtl8367c_getAsicRemarkingDscp2Dscp(rtk_uint32 dscp, rtk_uint32 *pRmkDscp); ++ ++extern ret_t rtl8367c_setAsicPortPriorityDecisionIndex(rtk_uint32 port, rtk_uint32 index ); ++extern ret_t rtl8367c_getAsicPortPriorityDecisionIndex(rtk_uint32 port, rtk_uint32 *pIndex ); ++ ++#endif /*#ifndef _RTL8367C_ASICDRV_QOS_H_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rldp.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rldp.h +new file mode 100644 +index 0000000000..cde970b638 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rldp.h +@@ -0,0 +1,60 @@ ++/* ++ * 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: 42321 $ ++ * $Date: 2013-08-26 13:51:29 +0800 (¶g¤@, 26 ¤K¤ë 2013) $ ++ * ++ * Purpose : RTL8367C switch high-level API for RTL8367C ++ * Feature : RLDP related functions ++ * ++ */ ++ ++#ifndef _RTL8367C_ASICDRV_RLDP_H_ ++#define _RTL8367C_ASICDRV_RLDP_H_ ++ ++#include ++#include ++ ++extern ret_t rtl8367c_setAsicRldp(rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicRldp(rtk_uint32 *pEnabled); ++extern ret_t rtl8367c_setAsicRldpEnable8051(rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicRldpEnable8051(rtk_uint32 *pEnabled); ++extern ret_t rtl8367c_setAsicRldpCompareRandomNumber(rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicRldpCompareRandomNumber(rtk_uint32 *pEnabled); ++extern ret_t rtl8367c_setAsicRldpIndicatorSource(rtk_uint32 src); ++extern ret_t rtl8367c_getAsicRldpIndicatorSource(rtk_uint32 *pSrc); ++extern ret_t rtl8367c_setAsicRldpCheckingStatePara(rtk_uint32 retryCount, rtk_uint32 retryPeriod); ++extern ret_t rtl8367c_getAsicRldpCheckingStatePara(rtk_uint32 *pRetryCount, rtk_uint32 *pRetryPeriod); ++extern ret_t rtl8367c_setAsicRldpLoopStatePara(rtk_uint32 retryCount, rtk_uint32 retryPeriod); ++extern ret_t rtl8367c_getAsicRldpLoopStatePara(rtk_uint32 *pRetryCount, rtk_uint32 *pRetryPeriod); ++extern ret_t rtl8367c_setAsicRldpTxPortmask(rtk_uint32 portmask); ++extern ret_t rtl8367c_getAsicRldpTxPortmask(rtk_uint32 *pPortmask); ++extern ret_t rtl8367c_setAsicRldpMagicNum(ether_addr_t seed); ++extern ret_t rtl8367c_getAsicRldpMagicNum(ether_addr_t *pSeed); ++extern ret_t rtl8367c_getAsicRldpLoopedPortmask(rtk_uint32 *pPortmask); ++extern ret_t rtl8367c_setAsicRldp8051Portmask(rtk_uint32 portmask); ++extern ret_t rtl8367c_getAsicRldp8051Portmask(rtk_uint32 *pPortmask); ++ ++ ++extern ret_t rtl8367c_getAsicRldpRandomNumber(ether_addr_t *pRandNumber); ++extern ret_t rtl8367c_getAsicRldpLoopedPortPair(rtk_uint32 port, rtk_uint32 *pLoopedPair); ++extern ret_t rtl8367c_setAsicRlppTrap8051(rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicRlppTrap8051(rtk_uint32 *pEnabled); ++ ++extern ret_t rtl8367c_setAsicRldpLeaveLoopedPortmask(rtk_uint32 portmask); ++extern ret_t rtl8367c_getAsicRldpLeaveLoopedPortmask(rtk_uint32 *pPortmask); ++ ++extern ret_t rtl8367c_setAsicRldpEnterLoopedPortmask(rtk_uint32 portmask); ++extern ret_t rtl8367c_getAsicRldpEnterLoopedPortmask(rtk_uint32 *pPortmask); ++ ++extern ret_t rtl8367c_setAsicRldpTriggerMode(rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicRldpTriggerMode(rtk_uint32 *pEnabled); ++ ++#endif /*_RTL8367C_ASICDRV_RLDP_H_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rma.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rma.h +new file mode 100644 +index 0000000000..10c707544f +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_rma.h +@@ -0,0 +1,57 @@ ++/* ++ * 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: 64716 $ ++ * $Date: 2015-12-31 16:31:55 +0800 (¶g¥|, 31 ¤Q¤G¤ë 2015) $ ++ * ++ * Purpose : RTL8367C switch high-level API for RTL8367C ++ * Feature : RMA related functions ++ * ++ */ ++ ++#ifndef _RTL8367C_ASICDRV_RMA_H_ ++#define _RTL8367C_ASICDRV_RMA_H_ ++ ++#include ++ ++#define RTL8367C_RMAMAX 0x2F ++ ++enum RTL8367C_RMAOP ++{ ++ RMAOP_FORWARD = 0, ++ RMAOP_TRAP_TO_CPU, ++ RMAOP_DROP, ++ RMAOP_FORWARD_EXCLUDE_CPU, ++ RMAOP_END ++}; ++ ++ ++typedef struct rtl8367c_rma_s{ ++ ++ rtk_uint16 operation; ++ rtk_uint16 discard_storm_filter; ++ rtk_uint16 trap_priority; ++ rtk_uint16 keep_format; ++ rtk_uint16 vlan_leaky; ++ rtk_uint16 portiso_leaky; ++ ++}rtl8367c_rma_t; ++ ++ ++extern ret_t rtl8367c_setAsicRma(rtk_uint32 index, rtl8367c_rma_t* pRmacfg); ++extern ret_t rtl8367c_getAsicRma(rtk_uint32 index, rtl8367c_rma_t* pRmacfg); ++extern ret_t rtl8367c_setAsicRmaCdp(rtl8367c_rma_t* pRmacfg); ++extern ret_t rtl8367c_getAsicRmaCdp(rtl8367c_rma_t* pRmacfg); ++extern ret_t rtl8367c_setAsicRmaCsstp(rtl8367c_rma_t* pRmacfg); ++extern ret_t rtl8367c_getAsicRmaCsstp(rtl8367c_rma_t* pRmacfg); ++extern ret_t rtl8367c_setAsicRmaLldp(rtk_uint32 enabled, rtl8367c_rma_t* pRmacfg); ++extern ret_t rtl8367c_getAsicRmaLldp(rtk_uint32 *pEnabled, rtl8367c_rma_t* pRmacfg); ++ ++#endif /*#ifndef _RTL8367C_ASICDRV_RMA_H_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_scheduling.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_scheduling.h +new file mode 100644 +index 0000000000..919a4ca692 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_scheduling.h +@@ -0,0 +1,58 @@ ++/* ++ * 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 : Packet Scheduling related functions ++ * ++ */ ++ ++#ifndef _RTL8367C_ASICDRV_SCHEDULING_H_ ++#define _RTL8367C_ASICDRV_SCHEDULING_H_ ++ ++#include ++ ++#define RTL8367C_QWEIGHTMAX 0x7F ++#define RTL8367C_PORT_QUEUE_METER_INDEX_MAX 7 ++ ++/* enum for queue type */ ++enum QUEUETYPE ++{ ++ QTYPE_STRICT = 0, ++ QTYPE_WFQ, ++}; ++extern ret_t rtl8367c_setAsicLeakyBucketParameter(rtk_uint32 tick, rtk_uint32 token); ++extern ret_t rtl8367c_getAsicLeakyBucketParameter(rtk_uint32 *tick, rtk_uint32 *token); ++extern ret_t rtl8367c_setAsicAprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 apridx); ++extern ret_t rtl8367c_getAsicAprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *apridx); ++extern ret_t rtl8367c_setAsicPprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 ppridx); ++extern ret_t rtl8367c_getAsicPprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *ppridx); ++extern ret_t rtl8367c_setAsicAprEnable(rtk_uint32 port, rtk_uint32 aprEnable); ++extern ret_t rtl8367c_getAsicAprEnable(rtk_uint32 port, rtk_uint32 *aprEnable); ++extern ret_t rtl8367c_setAsicPprEnable(rtk_uint32 port, rtk_uint32 pprEnable); ++extern ret_t rtl8367c_getAsicPprEnable(rtk_uint32 port, rtk_uint32 *pprEnable); ++ ++extern ret_t rtl8367c_setAsicWFQWeight(rtk_uint32, rtk_uint32 queueid, rtk_uint32 weight ); ++extern ret_t rtl8367c_getAsicWFQWeight(rtk_uint32, rtk_uint32 queueid, rtk_uint32 *weight ); ++extern ret_t rtl8367c_setAsicWFQBurstSize(rtk_uint32 burstsize); ++extern ret_t rtl8367c_getAsicWFQBurstSize(rtk_uint32 *burstsize); ++ ++extern ret_t rtl8367c_setAsicQueueType(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 queueType); ++extern ret_t rtl8367c_getAsicQueueType(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *queueType); ++extern ret_t rtl8367c_setAsicQueueRate(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 ppridx, rtk_uint32 apridx ); ++extern ret_t rtl8367c_getAsicQueueRate(rtk_uint32 port, rtk_uint32 qid, rtk_uint32* ppridx, rtk_uint32* apridx ); ++extern ret_t rtl8367c_setAsicPortEgressRate(rtk_uint32 port, rtk_uint32 rate); ++extern ret_t rtl8367c_getAsicPortEgressRate(rtk_uint32 port, rtk_uint32 *rate); ++extern ret_t rtl8367c_setAsicPortEgressRateIfg(rtk_uint32 ifg); ++extern ret_t rtl8367c_getAsicPortEgressRateIfg(rtk_uint32 *ifg); ++ ++#endif /*_RTL8367C_ASICDRV_SCHEDULING_H_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_storm.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_storm.h +new file mode 100644 +index 0000000000..3865b5225a +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_storm.h +@@ -0,0 +1,61 @@ ++/* ++ * 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 : Storm control filtering related functions ++ * ++ */ ++ ++#ifndef _RTL8367C_ASICDRV_STORM_H_ ++#define _RTL8367C_ASICDRV_STORM_H_ ++ ++#include ++ ++extern ret_t rtl8367c_setAsicStormFilterBroadcastEnable(rtk_uint32 port, rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicStormFilterBroadcastEnable(rtk_uint32 port, rtk_uint32 *pEnabled); ++extern ret_t rtl8367c_setAsicStormFilterBroadcastMeter(rtk_uint32 port, rtk_uint32 meter); ++extern ret_t rtl8367c_getAsicStormFilterBroadcastMeter(rtk_uint32 port, rtk_uint32 *pMeter); ++extern ret_t rtl8367c_setAsicStormFilterMulticastEnable(rtk_uint32 port, rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicStormFilterMulticastEnable(rtk_uint32 port, rtk_uint32 *pEnabled); ++extern ret_t rtl8367c_setAsicStormFilterMulticastMeter(rtk_uint32 port, rtk_uint32 meter); ++extern ret_t rtl8367c_getAsicStormFilterMulticastMeter(rtk_uint32 port, rtk_uint32 *pMeter); ++extern ret_t rtl8367c_setAsicStormFilterUnknownMulticastEnable(rtk_uint32 port, rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicStormFilterUnknownMulticastEnable(rtk_uint32 port, rtk_uint32 *pEnabled); ++extern ret_t rtl8367c_setAsicStormFilterUnknownMulticastMeter(rtk_uint32 port, rtk_uint32 meter); ++extern ret_t rtl8367c_getAsicStormFilterUnknownMulticastMeter(rtk_uint32 port, rtk_uint32 *pMeter); ++extern ret_t rtl8367c_setAsicStormFilterUnknownUnicastEnable(rtk_uint32 port, rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicStormFilterUnknownUnicastEnable(rtk_uint32 port, rtk_uint32 *pEnabled); ++extern ret_t rtl8367c_setAsicStormFilterUnknownUnicastMeter(rtk_uint32 port, rtk_uint32 meter); ++extern ret_t rtl8367c_getAsicStormFilterUnknownUnicastMeter(rtk_uint32 port, rtk_uint32 *pMeter); ++extern ret_t rtl8367c_setAsicStormFilterExtBroadcastMeter(rtk_uint32 meter); ++extern ret_t rtl8367c_getAsicStormFilterExtBroadcastMeter(rtk_uint32 *pMeter); ++extern ret_t rtl8367c_setAsicStormFilterExtMulticastMeter(rtk_uint32 meter); ++extern ret_t rtl8367c_getAsicStormFilterExtMulticastMeter(rtk_uint32 *pMeter); ++extern ret_t rtl8367c_setAsicStormFilterExtUnknownMulticastMeter(rtk_uint32 meter); ++extern ret_t rtl8367c_getAsicStormFilterExtUnknownMulticastMeter(rtk_uint32 *pMeter); ++extern ret_t rtl8367c_setAsicStormFilterExtUnknownUnicastMeter(rtk_uint32 meter); ++extern ret_t rtl8367c_getAsicStormFilterExtUnknownUnicastMeter(rtk_uint32 *pMeter); ++extern ret_t rtl8367c_setAsicStormFilterExtBroadcastEnable(rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicStormFilterExtBroadcastEnable(rtk_uint32 *pEnabled); ++extern ret_t rtl8367c_setAsicStormFilterExtMulticastEnable(rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicStormFilterExtMulticastEnable(rtk_uint32 *pEnabled); ++extern ret_t rtl8367c_setAsicStormFilterExtUnknownMulticastEnable(rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicStormFilterExtUnknownMulticastEnable(rtk_uint32 *pEnabled); ++extern ret_t rtl8367c_setAsicStormFilterExtUnknownUnicastEnable(rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicStormFilterExtUnknownUnicastEnable(rtk_uint32 *pEnabled); ++extern ret_t rtl8367c_setAsicStormFilterExtEnablePortMask(rtk_uint32 portmask); ++extern ret_t rtl8367c_getAsicStormFilterExtEnablePortMask(rtk_uint32 *pPortmask); ++ ++ ++#endif /*_RTL8367C_ASICDRV_STORM_H_*/ ++ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_svlan.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_svlan.h +new file mode 100644 +index 0000000000..5a6a4a8329 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_svlan.h +@@ -0,0 +1,132 @@ ++/* ++ * 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 : SVLAN related functions ++ * ++ */ ++ ++#ifndef _RTL8367C_ASICDRV_SVLAN_H_ ++#define _RTL8367C_ASICDRV_SVLAN_H_ ++ ++#include ++ ++#define RTL8367C_C2SIDXNO 128 ++#define RTL8367C_C2SIDXMAX (RTL8367C_C2SIDXNO-1) ++#define RTL8367C_MC2SIDXNO 32 ++#define RTL8367C_MC2SIDXMAX (RTL8367C_MC2SIDXNO-1) ++#define RTL8367C_SP2CIDXNO 128 ++#define RTL8367C_SP2CMAX (RTL8367C_SP2CIDXNO-1) ++ ++#define RTL8367C_SVLAN_MEMCONF_LEN 4 ++#define RTL8367C_SVLAN_MC2S_LEN 5 ++#define RTL8367C_SVLAN_SP2C_LEN 2 ++ ++enum RTL8367C_SPRISEL ++{ ++ SPRISEL_INTERNALPRI = 0, ++ SPRISEL_CTAGPRI, ++ SPRISEL_VSPRI, ++ SPRISEL_PBPRI, ++ SPRISEL_END ++}; ++ ++enum RTL8367C_SUNACCEPT ++{ ++ SUNACCEPT_DROP = 0, ++ SUNACCEPT_TRAP, ++ SUNACCEPT_SVLAN, ++ SUNACCEPT_END ++}; ++ ++enum RTL8367C_SVLAN_MC2S_MODE ++{ ++ SVLAN_MC2S_MODE_MAC = 0, ++ SVLAN_MC2S_MODE_IP, ++ SVLAN_MC2S_MODE_END ++}; ++ ++ ++typedef struct rtl8367c_svlan_memconf_s{ ++ ++ rtk_uint16 vs_member:11; ++ rtk_uint16 vs_untag:11; ++ ++ rtk_uint16 vs_fid_msti:4; ++ rtk_uint16 vs_priority:3; ++ rtk_uint16 vs_force_fid:1; ++ rtk_uint16 reserved:8; ++ ++ rtk_uint16 vs_svid:12; ++ rtk_uint16 vs_efiden:1; ++ rtk_uint16 vs_efid:3; ++ ++ ++}rtl8367c_svlan_memconf_t; ++ ++ ++typedef struct rtl8367c_svlan_mc2s_s{ ++ ++ rtk_uint16 valid:1; ++ rtk_uint16 format:1; ++ rtk_uint16 svidx:6; ++ rtk_uint32 sdata; ++ rtk_uint32 smask; ++}rtl8367c_svlan_mc2s_t; ++ ++ ++typedef struct rtl8367c_svlan_s2c_s{ ++ ++ rtk_uint16 valid:1; ++ rtk_uint16 svidx:6; ++ rtk_uint16 dstport:4; ++ rtk_uint32 vid:12; ++}rtl8367c_svlan_s2c_t; ++ ++extern ret_t rtl8367c_setAsicSvlanIngressUntag(rtk_uint32 mode); ++extern ret_t rtl8367c_getAsicSvlanIngressUntag(rtk_uint32* pMode); ++extern ret_t rtl8367c_setAsicSvlanIngressUnmatch(rtk_uint32 mode); ++extern ret_t rtl8367c_getAsicSvlanIngressUnmatch(rtk_uint32* pMode); ++extern ret_t rtl8367c_setAsicSvlanTrapPriority(rtk_uint32 priority); ++extern ret_t rtl8367c_getAsicSvlanTrapPriority(rtk_uint32* pPriority); ++extern ret_t rtl8367c_setAsicSvlanDefaultVlan(rtk_uint32 port, rtk_uint32 index); ++extern ret_t rtl8367c_getAsicSvlanDefaultVlan(rtk_uint32 port, rtk_uint32* pIndex); ++ ++extern ret_t rtl8367c_setAsicSvlanMemberConfiguration(rtk_uint32 index,rtl8367c_svlan_memconf_t* pSvlanMemCfg); ++extern ret_t rtl8367c_getAsicSvlanMemberConfiguration(rtk_uint32 index,rtl8367c_svlan_memconf_t* pSvlanMemCfg); ++ ++extern ret_t rtl8367c_setAsicSvlanPrioritySel(rtk_uint32 priSel); ++extern ret_t rtl8367c_getAsicSvlanPrioritySel(rtk_uint32* pPriSel); ++extern ret_t rtl8367c_setAsicSvlanTpid(rtk_uint32 protocolType); ++extern ret_t rtl8367c_getAsicSvlanTpid(rtk_uint32* pProtocolType); ++extern ret_t rtl8367c_setAsicSvlanUplinkPortMask(rtk_uint32 portMask); ++extern ret_t rtl8367c_getAsicSvlanUplinkPortMask(rtk_uint32* pPortmask); ++extern ret_t rtl8367c_setAsicSvlanEgressUnassign(rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicSvlanEgressUnassign(rtk_uint32* pEnabled); ++extern ret_t rtl8367c_setAsicSvlanC2SConf(rtk_uint32 index, rtk_uint32 evid, rtk_uint32 portmask, rtk_uint32 svidx); ++extern ret_t rtl8367c_getAsicSvlanC2SConf(rtk_uint32 index, rtk_uint32* pEvid, rtk_uint32* pPortmask, rtk_uint32* pSvidx); ++extern ret_t rtl8367c_setAsicSvlanMC2SConf(rtk_uint32 index,rtl8367c_svlan_mc2s_t* pSvlanMc2sCfg); ++extern ret_t rtl8367c_getAsicSvlanMC2SConf(rtk_uint32 index,rtl8367c_svlan_mc2s_t* pSvlanMc2sCfg); ++extern ret_t rtl8367c_setAsicSvlanSP2CConf(rtk_uint32 index,rtl8367c_svlan_s2c_t* pSvlanSp2cCfg); ++extern ret_t rtl8367c_getAsicSvlanSP2CConf(rtk_uint32 index,rtl8367c_svlan_s2c_t* pSvlanSp2cCfg); ++extern ret_t rtl8367c_setAsicSvlanDmacCvidSel(rtk_uint32 port, rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicSvlanDmacCvidSel(rtk_uint32 port, rtk_uint32* pEnabled); ++extern ret_t rtl8367c_setAsicSvlanUntagVlan(rtk_uint32 index); ++extern ret_t rtl8367c_getAsicSvlanUntagVlan(rtk_uint32* pIndex); ++extern ret_t rtl8367c_setAsicSvlanUnmatchVlan(rtk_uint32 index); ++extern ret_t rtl8367c_getAsicSvlanUnmatchVlan(rtk_uint32* pIndex); ++extern ret_t rtl8367c_setAsicSvlanLookupType(rtk_uint32 type); ++extern ret_t rtl8367c_getAsicSvlanLookupType(rtk_uint32* pType); ++ ++ ++#endif /*#ifndef _RTL8367C_ASICDRV_SVLAN_H_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_trunking.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_trunking.h +new file mode 100644 +index 0000000000..2e3a682819 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_trunking.h +@@ -0,0 +1,48 @@ ++/* ++ * 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 : Port trunking related functions ++ * ++ */ ++ ++ ++#ifndef _RTL8367C_ASICDRV_TRUNKING_H_ ++#define _RTL8367C_ASICDRV_TRUNKING_H_ ++ ++#include ++ ++#define RTL8367C_MAX_TRUNK_GID (2) ++#define RTL8367C_TRUNKING_PORTNO (4) ++#define RTL8367C_TRUNKING1_PORTN0 (2) ++#define RTL8367C_TRUNKING_HASHVALUE_MAX (15) ++ ++extern ret_t rtl8367c_setAsicTrunkingGroup(rtk_uint32 group, rtk_uint32 portmask); ++extern ret_t rtl8367c_getAsicTrunkingGroup(rtk_uint32 group, rtk_uint32* pPortmask); ++extern ret_t rtl8367c_setAsicTrunkingFlood(rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicTrunkingFlood(rtk_uint32* pEnabled); ++extern ret_t rtl8367c_setAsicTrunkingHashSelect(rtk_uint32 hashsel); ++extern ret_t rtl8367c_getAsicTrunkingHashSelect(rtk_uint32* pHashsel); ++ ++extern ret_t rtl8367c_getAsicQeueuEmptyStatus(rtk_uint32* pPortmask); ++ ++extern ret_t rtl8367c_setAsicTrunkingMode(rtk_uint32 mode); ++extern ret_t rtl8367c_getAsicTrunkingMode(rtk_uint32* pMode); ++extern ret_t rtl8367c_setAsicTrunkingFc(rtk_uint32 group, rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicTrunkingFc(rtk_uint32 group, rtk_uint32* pEnabled); ++extern ret_t rtl8367c_setAsicTrunkingHashTable(rtk_uint32 hashval, rtk_uint32 portId); ++extern ret_t rtl8367c_getAsicTrunkingHashTable(rtk_uint32 hashval, rtk_uint32* pPortId); ++extern ret_t rtl8367c_setAsicTrunkingHashTable1(rtk_uint32 hashval, rtk_uint32 portId); ++extern ret_t rtl8367c_getAsicTrunkingHashTable1(rtk_uint32 hashval, rtk_uint32* pPortId); ++ ++#endif /*_RTL8367C_ASICDRV_TRUNKING_H_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_unknownMulticast.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_unknownMulticast.h +new file mode 100644 +index 0000000000..d142d25cff +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_unknownMulticast.h +@@ -0,0 +1,59 @@ ++/* ++ * 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 : Unkown multicast related functions ++ * ++ */ ++ ++#ifndef _RTL8367C_ASICDRV_UNKNOWNMULTICAST_H_ ++#define _RTL8367C_ASICDRV_UNKNOWNMULTICAST_H_ ++ ++#include ++ ++enum L2_UNKOWN_MULTICAST_BEHAVE ++{ ++ L2_UNKOWN_MULTICAST_FLOODING = 0, ++ L2_UNKOWN_MULTICAST_DROP, ++ L2_UNKOWN_MULTICAST_TRAP, ++ L2_UNKOWN_MULTICAST_DROP_EXCLUDE_RMA, ++ L2_UNKOWN_MULTICAST_END ++}; ++ ++enum L3_UNKOWN_MULTICAST_BEHAVE ++{ ++ L3_UNKOWN_MULTICAST_FLOODING = 0, ++ L3_UNKOWN_MULTICAST_DROP, ++ L3_UNKOWN_MULTICAST_TRAP, ++ L3_UNKOWN_MULTICAST_ROUTER, ++ L3_UNKOWN_MULTICAST_END ++}; ++ ++enum MULTICASTTYPE{ ++ MULTICAST_TYPE_IPV4 = 0, ++ MULTICAST_TYPE_IPV6, ++ MULTICAST_TYPE_L2, ++ MULTICAST_TYPE_END ++}; ++ ++extern ret_t rtl8367c_setAsicUnknownL2MulticastBehavior(rtk_uint32 port, rtk_uint32 behave); ++extern ret_t rtl8367c_getAsicUnknownL2MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave); ++extern ret_t rtl8367c_setAsicUnknownIPv4MulticastBehavior(rtk_uint32 port, rtk_uint32 behave); ++extern ret_t rtl8367c_getAsicUnknownIPv4MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave); ++extern ret_t rtl8367c_setAsicUnknownIPv6MulticastBehavior(rtk_uint32 port, rtk_uint32 behave); ++extern ret_t rtl8367c_getAsicUnknownIPv6MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave); ++extern ret_t rtl8367c_setAsicUnknownMulticastTrapPriority(rtk_uint32 priority); ++extern ret_t rtl8367c_getAsicUnknownMulticastTrapPriority(rtk_uint32 *pPriority); ++ ++#endif /*_RTL8367C_ASICDRV_UNKNOWNMULTICAST_H_*/ ++ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_vlan.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_vlan.h +new file mode 100644 +index 0000000000..61848650b5 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_asicdrv_vlan.h +@@ -0,0 +1,157 @@ ++/* ++ * 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 : VLAN related functions ++ * ++ */ ++ ++ ++#ifndef _RTL8367C_ASICDRV_VLAN_H_ ++#define _RTL8367C_ASICDRV_VLAN_H_ ++ ++/****************************************************************/ ++/* Header File inclusion */ ++/****************************************************************/ ++#include ++ ++/****************************************************************/ ++/* Constant Definition */ ++/****************************************************************/ ++#define RTL8367C_PROTOVLAN_GIDX_MAX 3 ++#define RTL8367C_PROTOVLAN_GROUPNO 4 ++ ++#define RTL8367C_VLAN_BUSY_CHECK_NO (10) ++ ++#define RTL8367C_VLAN_MBRCFG_LEN (4) ++#define RTL8367C_VLAN_4KTABLE_LEN (3) ++ ++/****************************************************************/ ++/* Type Definition */ ++/****************************************************************/ ++typedef struct VLANCONFIGUSER ++{ ++ rtk_uint16 evid; ++ rtk_uint16 mbr; ++ rtk_uint16 fid_msti; ++ rtk_uint16 envlanpol; ++ rtk_uint16 meteridx; ++ rtk_uint16 vbpen; ++ rtk_uint16 vbpri; ++}rtl8367c_vlanconfiguser; ++ ++typedef struct USER_VLANTABLE{ ++ ++ rtk_uint16 vid; ++ rtk_uint16 mbr; ++ rtk_uint16 untag; ++ rtk_uint16 fid_msti; ++ rtk_uint16 envlanpol; ++ rtk_uint16 meteridx; ++ rtk_uint16 vbpen; ++ rtk_uint16 vbpri; ++ rtk_uint16 ivl_svl; ++ ++}rtl8367c_user_vlan4kentry; ++ ++typedef enum ++{ ++ FRAME_TYPE_BOTH = 0, ++ FRAME_TYPE_TAGGED_ONLY, ++ FRAME_TYPE_UNTAGGED_ONLY, ++ FRAME_TYPE_MAX_BOUND ++} rtl8367c_accframetype; ++ ++typedef enum ++{ ++ EG_TAG_MODE_ORI = 0, ++ EG_TAG_MODE_KEEP, ++ EG_TAG_MODE_PRI_TAG, ++ EG_TAG_MODE_REAL_KEEP, ++ EG_TAG_MODE_END ++} rtl8367c_egtagmode; ++ ++typedef enum ++{ ++ PPVLAN_FRAME_TYPE_ETHERNET = 0, ++ PPVLAN_FRAME_TYPE_LLC, ++ PPVLAN_FRAME_TYPE_RFC1042, ++ PPVLAN_FRAME_TYPE_END ++} rtl8367c_provlan_frametype; ++ ++enum RTL8367C_STPST ++{ ++ STPST_DISABLED = 0, ++ STPST_BLOCKING, ++ STPST_LEARNING, ++ STPST_FORWARDING ++}; ++ ++enum RTL8367C_RESVIDACT ++{ ++ RES_VID_ACT_UNTAG = 0, ++ RES_VID_ACT_TAG, ++ RES_VID_ACT_END ++}; ++ ++typedef struct ++{ ++ rtl8367c_provlan_frametype frameType; ++ rtk_uint32 etherType; ++} rtl8367c_protocolgdatacfg; ++ ++typedef struct ++{ ++ rtk_uint32 valid; ++ rtk_uint32 vlan_idx; ++ rtk_uint32 priority; ++} rtl8367c_protocolvlancfg; ++ ++extern ret_t rtl8367c_setAsicVlanMemberConfig(rtk_uint32 index, rtl8367c_vlanconfiguser *pVlanCg); ++extern ret_t rtl8367c_getAsicVlanMemberConfig(rtk_uint32 index, rtl8367c_vlanconfiguser *pVlanCg); ++extern ret_t rtl8367c_setAsicVlan4kEntry(rtl8367c_user_vlan4kentry *pVlan4kEntry ); ++extern ret_t rtl8367c_getAsicVlan4kEntry(rtl8367c_user_vlan4kentry *pVlan4kEntry ); ++extern ret_t rtl8367c_setAsicVlanAccpetFrameType(rtk_uint32 port, rtl8367c_accframetype frameType); ++extern ret_t rtl8367c_getAsicVlanAccpetFrameType(rtk_uint32 port, rtl8367c_accframetype *pFrameType); ++extern ret_t rtl8367c_setAsicVlanIngressFilter(rtk_uint32 port, rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicVlanIngressFilter(rtk_uint32 port, rtk_uint32 *pEnable); ++extern ret_t rtl8367c_setAsicVlanEgressTagMode(rtk_uint32 port, rtl8367c_egtagmode tagMode); ++extern ret_t rtl8367c_getAsicVlanEgressTagMode(rtk_uint32 port, rtl8367c_egtagmode *pTagMode); ++extern ret_t rtl8367c_setAsicVlanPortBasedVID(rtk_uint32 port, rtk_uint32 index, rtk_uint32 pri); ++extern ret_t rtl8367c_getAsicVlanPortBasedVID(rtk_uint32 port, rtk_uint32 *pIndex, rtk_uint32 *pPri); ++extern ret_t rtl8367c_setAsicVlanProtocolBasedGroupData(rtk_uint32 index, rtl8367c_protocolgdatacfg *pPbCfg); ++extern ret_t rtl8367c_getAsicVlanProtocolBasedGroupData(rtk_uint32 index, rtl8367c_protocolgdatacfg *pPbCfg); ++extern ret_t rtl8367c_setAsicVlanPortAndProtocolBased(rtk_uint32 port, rtk_uint32 index, rtl8367c_protocolvlancfg *pPpbCfg); ++extern ret_t rtl8367c_getAsicVlanPortAndProtocolBased(rtk_uint32 port, rtk_uint32 index, rtl8367c_protocolvlancfg *pPpbCfg); ++extern ret_t rtl8367c_setAsicVlanFilter(rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicVlanFilter(rtk_uint32* pEnabled); ++ ++extern ret_t rtl8367c_setAsicPortBasedFid(rtk_uint32 port, rtk_uint32 fid); ++extern ret_t rtl8367c_getAsicPortBasedFid(rtk_uint32 port, rtk_uint32* pFid); ++extern ret_t rtl8367c_setAsicPortBasedFidEn(rtk_uint32 port, rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicPortBasedFidEn(rtk_uint32 port, rtk_uint32* pEnabled); ++extern ret_t rtl8367c_setAsicSpanningTreeStatus(rtk_uint32 port, rtk_uint32 msti, rtk_uint32 state); ++extern ret_t rtl8367c_getAsicSpanningTreeStatus(rtk_uint32 port, rtk_uint32 msti, rtk_uint32* pState); ++extern ret_t rtl8367c_setAsicVlanUntagDscpPriorityEn(rtk_uint32 enabled); ++extern ret_t rtl8367c_getAsicVlanUntagDscpPriorityEn(rtk_uint32* enabled); ++extern ret_t rtl8367c_setAsicVlanTransparent(rtk_uint32 port, rtk_uint32 portmask); ++extern ret_t rtl8367c_getAsicVlanTransparent(rtk_uint32 port, rtk_uint32 *pPortmask); ++extern ret_t rtl8367c_setAsicVlanEgressKeep(rtk_uint32 port, rtk_uint32 portmask); ++extern ret_t rtl8367c_getAsicVlanEgressKeep(rtk_uint32 port, rtk_uint32* pPortmask); ++extern ret_t rtl8367c_setReservedVidAction(rtk_uint32 vid0Action, rtk_uint32 vid4095Action); ++extern ret_t rtl8367c_getReservedVidAction(rtk_uint32 *pVid0Action, rtk_uint32 *pVid4095Action); ++extern ret_t rtl8367c_setRealKeepRemarkEn(rtk_uint32 enabled); ++extern ret_t rtl8367c_getRealKeepRemarkEn(rtk_uint32 *pEnabled); ++extern ret_t rtl8367c_resetVlan(void); ++ ++#endif /*#ifndef _RTL8367C_ASICDRV_VLAN_H_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_base.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_base.h +new file mode 100644 +index 0000000000..676ca8ed74 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_base.h +@@ -0,0 +1,596 @@ ++/* ++ * 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 : Regsiter MACRO related definition ++ * ++ */ ++ ++#ifndef _RTL8367C_BASE_H_ ++#define _RTL8367C_BASE_H_ ++ ++#include ++ ++/* (16'h0000) port_reg */ ++ ++#define RTL8367C_PORT_SPECIAL_CONGEST_MODE_TIMER_BASE RTL8367C_REG_PKTGEN_PORT0_TIMER ++#define RTL8367C_PORT_SPECIAL_CONGEST_MODE_TIMER_REG(port) (RTL8367C_PORT_SPECIAL_CONGEST_MODE_TIMER_BASE + (port << 5)) ++ ++#define RTL8367C_PORT_MISC_CFG_BASE RTL8367C_REG_PORT0_MISC_CFG ++#define RTL8367C_PORT_MISC_CFG_REG(port) (RTL8367C_PORT_MISC_CFG_BASE + (port << 5)) ++#define RTL8367C_1QREMARK_ENABLE_OFFSET RTL8367C_PORT0_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET ++#define RTL8367C_1QREMARK_ENABLE_MASK RTL8367C_PORT0_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK ++ ++#define RTL8367C_INGRESSBW_PORT_IFG_MASK RTL8367C_PORT0_MISC_CFG_INGRESSBW_IFG_MASK ++#define RTL8367C_VLAN_EGRESS_MDOE_MASK RTL8367C_PORT0_MISC_CFG_VLAN_EGRESS_MODE_MASK ++#define RTL8367C_SPECIALCONGEST_SUSTAIN_TIMER_MASK RTL8367C_PORT0_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK ++ ++#define RTL8367C_INGRESSBW_PORT_RATE_LSB_BASE RTL8367C_REG_INGRESSBW_PORT0_RATE_CTRL0 ++#define RTL8367C_INGRESSBW_PORT_RATE_LSB_REG(port) (RTL8367C_INGRESSBW_PORT_RATE_LSB_BASE + (port << 5)) ++ ++#define RTL8367C_PORT_SMALL_IPG_REG(port) (RTL8367C_REG_PORT0_MISC_CFG + (port*0x20)) ++ ++#define RTL8367C_PORT_EEE_CFG_BASE RTL8367C_REG_PORT0_EEECFG ++#define RTL8367C_PORT_EEE_CFG_REG(port) (RTL8367C_REG_PORT0_EEECFG + (port << 5)) ++#define RTL8367C_PORT_EEE_100M_OFFSET RTL8367C_PORT0_EEECFG_EEE_100M_OFFSET ++#define RTL8367C_PORT_EEE_100M_MASK RTL8367C_PORT0_EEECFG_EEE_100M_MASK ++#define RTL8367C_PORT_EEE_GIGA_OFFSET RTL8367C_PORT0_EEECFG_EEE_GIGA_500M_OFFSET ++#define RTL8367C_PORT_EEE_GIGA_MASK RTL8367C_PORT0_EEECFG_EEE_GIGA_500M_MASK ++ ++ ++/* (16'h0200) outq_reg */ ++ ++#define RTL8367C_FLOWCTRL_QUEUE_DROP_ON_BASE RTL8367C_REG_FLOWCTRL_QUEUE0_DROP_ON ++#define RTL8367C_FLOWCTRL_QUEUE_DROP_ON_REG(queue) (RTL8367C_FLOWCTRL_QUEUE_DROP_ON_BASE + queue) ++#define RTL8367C_FLOWCTRL_QUEUE_DROP_ON_MASK RTL8367C_FLOWCTRL_QUEUE0_DROP_ON_MASK ++ ++#define RTL8367C_FLOWCTRL_PORT_DROP_ON_BASE RTL8367C_REG_FLOWCTRL_PORT0_DROP_ON ++#define RTL8367C_FLOWCTRL_PORT_DROP_ON_REG(PORT) (RTL8367C_FLOWCTRL_PORT_DROP_ON_BASE + PORT) ++#define RTL8367C_FLOWCTRL_PORT_DROP_ON_MASK RTL8367C_FLOWCTRL_PORT0_DROP_ON_MASK ++ ++#define RTL8367C_FLOWCTRL_PORT_GAP_REG RTL8367C_REG_FLOWCTRL_PORT_GAP ++#define RTL8367C_FLOWCTRL_QUEUE_GAP_REG RTL8367C_REG_FLOWCTRL_QUEUE_GAP ++#define RTL8367C_FLOWCTRL_PORT_QEMPTY_REG RTL8367C_REG_PORT_QEMPTY ++ ++/* (16'h0300) sch_reg */ ++ ++#define RTL8367C_SCHEDULE_WFQ_BURST_SIZE_REG RTL8367C_REG_SCHEDULE_WFQ_BURST_SIZE ++ ++#define RTL8367C_SCHEDULE_QUEUE_TYPE_BASE RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL0 ++#define RTL8367C_SCHEDULE_QUEUE_TYPE_REG(port) (RTL8367C_SCHEDULE_QUEUE_TYPE_BASE + (port >> 1)) ++#define RTL8367C_SCHEDULE_QUEUE_TYPE_OFFSET(port, queue) (((port & 0x1) << 3) + queue) ++#define RTL8367C_SCHEDULE_QUEUE_TYPE_MASK(port, queue) RTL8367C_SCHEDULE_QUEUE_TYPE_OFFSET(port, queue) ++ ++#define RTL8367C_SCHEDULE_PORT_QUEUE_WFQ_WEIGHT_BASE RTL8367C_REG_SCHEDULE_PORT0_QUEUE0_WFQ_WEIGHT ++#define RTL8367C_SCHEDULE_PORT_QUEUE_WFQ_WEIGHT_REG(port, queue) (RTL8367C_SCHEDULE_PORT_QUEUE_WFQ_WEIGHT_BASE + (port << 3) + queue) ++ ++#define RTL8367C_SCHEDULE_APR_CTRL_REG RTL8367C_REG_SCHEDULE_APR_CTRL0 ++#define RTL8367C_SCHEDULE_APR_CTRL_OFFSET(port) (port) ++#define RTL8367C_SCHEDULE_APR_CTRL_MASK(port) (1 << RTL8367C_SCHEDULE_APR_CTRL_OFFSET(port)) ++ ++#define RTL8367C_SCHEDULE_PORT_APR_METER_BASE RTL8367C_REG_SCHEDULE_PORT0_APR_METER_CTRL0 ++#define RTL8367C_SCHEDULE_PORT_APR_METER_REG(port, queue) (RTL8367C_SCHEDULE_PORT_APR_METER_BASE + (port << 2) + (queue / 5)) ++#define RTL8367C_SCHEDULE_PORT_APR_METER_OFFSET(queue) (3 * (queue % 5)) ++#define RTL8367C_SCHEDULE_PORT_APR_METER_MASK(queue) (RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE0_APR_METER_MASK << RTL8367C_SCHEDULE_PORT_APR_METER_OFFSET(queue)) ++ ++#define RTL8367C_PORT_EGRESSBW_LSB_BASE RTL8367C_REG_PORT0_EGRESSBW_CTRL0 ++#define RTL8367C_PORT_EGRESSBW_LSB_REG(port) (RTL8367C_PORT_EGRESSBW_LSB_BASE + (port << 1)) ++ ++#define RTL8367C_PORT_EGRESSBW_MSB_BASE RTL8367C_REG_PORT0_EGRESSBW_CTRL1 ++#define RTL8367C_PORT_EGRESSBW_MSB_REG(port) (RTL8367C_PORT_EGRESSBW_MSB_BASE + (port << 1)) ++ ++/* (16'h0500) table_reg */ ++ ++#define RTL8367C_TABLE_ACCESS_CTRL_REG RTL8367C_REG_TABLE_ACCESS_CTRL ++ ++#define RTL8367C_TABLE_ACCESS_ADDR_REG RTL8367C_REG_TABLE_ACCESS_ADDR ++ ++#define RTL8367C_TABLE_ACCESS_STATUS_REG RTL8367C_REG_TABLE_LUT_ADDR ++ ++#define RTL8367C_TABLE_ACCESS_WRDATA_BASE RTL8367C_REG_TABLE_WRITE_DATA0 ++#define RTL8367C_TABLE_ACCESS_WRDATA_REG(index) (RTL8367C_TABLE_ACCESS_WRDATA_BASE + index) ++ ++#define RTL8367C_TABLE_ACCESS_RDDATA_BASE RTL8367C_REG_TABLE_READ_DATA0 ++#define RTL8367C_TABLE_ACCESS_RDDATA_REG(index) (RTL8367C_TABLE_ACCESS_RDDATA_BASE + index) ++ ++ ++ ++/* (16'h0600) acl_reg */ ++ ++#define RTL8367C_ACL_RULE_TEMPLATE_CTRL_BASE RTL8367C_REG_ACL_RULE_TEMPLATE0_CTRL0 ++#define RTL8367C_ACL_RULE_TEMPLATE_CTRL_REG(template) (RTL8367C_ACL_RULE_TEMPLATE_CTRL_BASE + template * 0x4) ++#define RTL8367C_ACL_TEMPLATE_FIELD_OFFSET(field) ((field & 0x01) <<3) ++#define RTL8367C_ACL_TEMPLATE_FIELD_MASK(field) (0x3F << RTL8367C_ACL_TEMPLATE_FIELD_OFFSET(field)) ++ ++#define RTL8367C_ACL_ACTION_CTRL_BASE RTL8367C_REG_ACL_ACTION_CTRL0 ++#define RTL8367C_ACL_ACTION_CTRL_REG(rule) (RTL8367C_ACL_ACTION_CTRL_BASE + (rule >> 1)) ++#define RTL8367C_ACL_ACTION_CTRL2_BASE RTL8367C_REG_ACL_ACTION_CTRL32 ++#define RTL8367C_ACL_ACTION_CTRL2_REG(rule) (RTL8367C_ACL_ACTION_CTRL2_BASE + ((rule-64) >> 1)) ++ ++#define RTL8367C_ACL_OP_NOT_OFFSET(rule) (6 + ((rule & 0x1) << 3)) ++#define RTL8367C_ACL_OP_NOT_MASK(rule) (1 << RTL8367C_ACL_OP_NOT_OFFSET(rule)) ++#define RTL8367C_ACL_OP_ACTION_OFFSET(rule) ((rule & 0x1) << 3) ++#define RTL8367C_ACL_OP_ACTION_MASK(rule) (0x3F << RTL8367C_ACL_OP_ACTION_OFFSET(rule)) ++ ++#define RTL8367C_ACL_ENABLE_REG RTL8367C_REG_ACL_ENABLE ++#define RTL8367C_ACL_UNMATCH_PERMIT_REG RTL8367C_REG_ACL_UNMATCH_PERMIT ++ ++/* (16'h0700) cvlan_reg */ ++ ++#define RTL8367C_VLAN_PVID_CTRL_BASE RTL8367C_REG_VLAN_PVID_CTRL0 ++#define RTL8367C_VLAN_PVID_CTRL_REG(port) (RTL8367C_VLAN_PVID_CTRL_BASE + (port >> 1)) ++#define RTL8367C_PORT_VIDX_OFFSET(port) ((port &1)<<3) ++#define RTL8367C_PORT_VIDX_MASK(port) (RTL8367C_PORT0_VIDX_MASK << RTL8367C_PORT_VIDX_OFFSET(port)) ++ ++#define RTL8367C_VLAN_PPB_VALID_BASE RTL8367C_REG_VLAN_PPB0_VALID ++#define RTL8367C_VLAN_PPB_VALID_REG(item) (RTL8367C_VLAN_PPB_VALID_BASE + (item << 3)) ++ ++#define RTL8367C_VLAN_PPB_CTRL_BASE RTL8367C_REG_VLAN_PPB0_CTRL0 ++#define RTL8367C_VLAN_PPB_CTRL_REG(item, port) (RTL8367C_VLAN_PPB_CTRL_BASE + (item << 3) + (port / 3) ) ++#define RTL8367C_VLAN_PPB_CTRL_OFFSET(port) ((port % 3) * 5) ++#define RTL8367C_VLAN_PPB_CTRL_MASK(port) (RTL8367C_VLAN_PPB0_CTRL0_PORT0_INDEX_MASK << RTL8367C_VLAN_PPB_CTRL_OFFSET(port)) ++ ++#define RTL8367C_VLAN_PPB_FRAMETYPE_BASE RTL8367C_REG_VLAN_PPB0_CTRL2 ++#define RTL8367C_VLAN_PPB_FRAMETYPE_REG(item) (RTL8367C_VLAN_PPB_FRAMETYPE_BASE + (item << 3)) ++#define RTL8367C_VLAN_PPB_FRAMETYPE_MASK RTL8367C_VLAN_PPB0_CTRL2_FRAME_TYPE_MASK ++ ++#define RTL8367C_VLAN_PPB_ETHERTYPR_BASE RTL8367C_REG_VLAN_PPB0_CTRL3 ++#define RTL8367C_VLAN_PPB_ETHERTYPR_REG(item) (RTL8367C_VLAN_PPB_ETHERTYPR_BASE + (item << 3)) ++ ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION_BASE RTL8367C_REG_VLAN_MEMBER_CONFIGURATION0_CTRL0 ++ ++ ++#define RTL8367C_VLAN_CTRL_REG RTL8367C_REG_VLAN_CTRL ++ ++#define RTL8367C_VLAN_INGRESS_REG RTL8367C_REG_VLAN_INGRESS ++ ++#define RTL8367C_VLAN_ACCEPT_FRAME_TYPE_BASE RTL8367C_REG_VLAN_ACCEPT_FRAME_TYPE_CTRL0 ++#define RTL8367C_VLAN_ACCEPT_FRAME_TYPE_REG(port) (RTL8367C_VLAN_ACCEPT_FRAME_TYPE_BASE + (port >> 3)) ++#define RTL8367C_VLAN_ACCEPT_FRAME_TYPE_MASK(port) (RTL8367C_PORT0_FRAME_TYPE_MASK << ((port & 0x7) << 1)) ++ ++#define RTL8367C_PORT_EFID_BASE RTL8367C_REG_PORT_EFID_CTRL0 ++#define RTL8367C_PORT_EFID_REG(port) (RTL8367C_PORT_EFID_BASE + (port >> 2)) ++#define RTL8367C_PORT_EFID_OFFSET(port) ((port & 0x3) << 2) ++#define RTL8367C_PORT_EFID_MASK(port) (RTL8367C_PORT0_EFID_MASK << RTL8367C_PORT_EFID_OFFSET(port)) ++ ++#define RTL8367C_PORT_PBFIDEN_REG RTL8367C_REG_PORT_PBFIDEN ++ ++#define RTL8367C_PORT_PBFID_BASE RTL8367C_REG_PORT0_PBFID ++#define RTL8367C_PORT_PBFID_REG(port) (RTL8367C_PORT_PBFID_BASE + port) ++ ++/* (16'h0800) dpm_reg */ ++ ++#define RTL8367C_RMA_CTRL_BASE RTL8367C_REG_RMA_CTRL00 ++ ++ ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_BASE RTL8367C_REG_VLAN_PORTBASED_PRIORITY_CTRL0 ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_REG(port) (RTL8367C_VLAN_PORTBASED_PRIORITY_BASE + (port >> 2)) ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_OFFSET(port) ((port & 0x3) << 2) ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_MASK(port) (0x7 << RTL8367C_VLAN_PORTBASED_PRIORITY_OFFSET(port)) ++ ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM_BASE RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM0_CTRL0 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM_REG(port, item) (RTL8367C_VLAN_PPB_PRIORITY_ITEM_BASE + (item << 2)+ (port>>2)) ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM_OFFSET(port) ((port & 0x3) <<2) ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM_MASK(port) (RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT0_PRIORITY_MASK << RTL8367C_VLAN_PPB_PRIORITY_ITEM_OFFSET(port)) ++ ++#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_BASE RTL8367C_REG_QOS_1Q_PRIORITY_REMAPPING_CTRL0 ++#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_REG(pri) (RTL8367C_QOS_1Q_PRIORITY_REMAPPING_BASE + (pri >> 2)) ++#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_OFFSET(pri) ((pri & 0x3) << 2) ++#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_MASK(pri) (0x7 << RTL8367C_QOS_1Q_PRIORITY_REMAPPING_OFFSET(pri)) ++ ++#define RTL8367C_QOS_DSCP_TO_PRIORITY_BASE RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL0 ++#define RTL8367C_QOS_DSCP_TO_PRIORITY_REG(dscp) (RTL8367C_QOS_DSCP_TO_PRIORITY_BASE + (dscp >> 2)) ++#define RTL8367C_QOS_DSCP_TO_PRIORITY_OFFSET(dscp) ((dscp & 0x3) << 2) ++#define RTL8367C_QOS_DSCP_TO_PRIORITY_MASK(dscp) (0x7 << RTL8367C_QOS_DSCP_TO_PRIORITY_OFFSET(dscp)) ++ ++#define RTL8367C_QOS_PORTBASED_PRIORITY_BASE RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL0 ++#define RTL8367C_QOS_PORTBASED_PRIORITY_REG(port) (RTL8367C_QOS_PORTBASED_PRIORITY_BASE + (port >> 2)) ++#define RTL8367C_QOS_PORTBASED_PRIORITY_OFFSET(port) ((port & 0x3) << 2) ++#define RTL8367C_QOS_PORTBASED_PRIORITY_MASK(port) (0x7 << RTL8367C_QOS_PORTBASED_PRIORITY_OFFSET(port)) ++ ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_BASE RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_CTRL0 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_REG(src) (RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_BASE + (src >> 1)) ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_OFFSET(src) ((src & 1) << 3) ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_MASK(src) (RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL0_QOS_PORT_WEIGHT_MASK << RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_OFFSET(src)) ++ ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_BASE RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_REG(src) (RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_BASE + (src >> 1)) ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_OFFSET(src) ((src & 1) << 3) ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_MASK(src) (RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0_QOS_PORT_WEIGHT_MASK << RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_OFFSET(src)) ++ ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX_CTRL RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_IDX ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX(port) (1 << port) ++ ++#define RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_BASE RTL8367C_REG_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0 ++#define RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_REG(pri) (RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_BASE + (pri >> 2)) ++#define RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_OFFSET(pri) ((pri & 0x3) << 2) ++#define RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_MASK(pri) (RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY0_MASK << RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_OFFSET(pri)) ++ ++#define RTL8367C_QOS_TRAP_PRIORITY_CTRL0_REG RTL8367C_REG_QOS_TRAP_PRIORITY0 ++ ++#define RTL8367C_QOS_TRAP_PRIORITY_CTRL1_REG RTL8367C_REG_QOS_TRAP_PRIORITY1 ++ ++#define RTL8367C_QOS_DSCP_TO_DSCP_BASE RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL0 ++#define RTL8367C_QOS_DSCP_TO_DSCP_REG(dscp) (RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL0 + (dscp >> 1)) ++#define RTL8367C_QOS_DSCP_TO_DSCP_OFFSET(dscp) ((dscp & 0x1) << 8) ++#define RTL8367C_QOS_DSCP_TO_DSCP_MASK(dscp) (0x3F << RTL8367C_QOS_DSCP_TO_DSCP_OFFSET(dscp)) ++ ++#define RTL8367C_UNUCAST_FLOADING_PMSK_REG RTL8367C_REG_UNDA_FLOODING_PMSK ++ ++#define RTL8367C_UNMCAST_FLOADING_PMSK_REG RTL8367C_REG_UNMCAST_FLOADING_PMSK ++ ++#define RTL8367C_BCAST_FLOADING_PMSK_REG RTL8367C_REG_BCAST_FLOADING_PMSK ++ ++#define RTL8367C_PORT_ISOLATION_PORT_MASK_BASE RTL8367C_REG_PORT_ISOLATION_PORT0_MASK ++#define RTL8367C_PORT_ISOLATION_PORT_MASK_REG(port) (RTL8367C_PORT_ISOLATION_PORT_MASK_BASE + port) ++ ++#define RTL8367C_FORCE_CTRL_REG RTL8367C_REG_FORCE_CTRL ++ ++#define RTL8367C_SOURCE_PORT_BLOCK_REG RTL8367C_REG_SOURCE_PORT_PERMIT ++ ++#define RTL8367C_IPMCAST_VLAN_LEAKY_REG RTL8367C_REG_IPMCAST_VLAN_LEAKY ++ ++#define RTL8367C_IPMCAST_PORTISO_LEAKY_REG RTL8367C_REG_IPMCAST_PORTISO_LEAKY ++ ++#define RTL8367C_PORT_SECURIT_CTRL_REG RTL8367C_REG_PORT_SECURITY_CTRL ++ ++#define RTL8367C_UNKNOWN_IPV4_MULTICAST_BASE RTL8367C_REG_UNKNOWN_IPV4_MULTICAST_CTRL0 ++#define RTL8367C_UNKNOWN_IPV4_MULTICAST_REG(port) (RTL8367C_UNKNOWN_IPV4_MULTICAST_BASE + (port >> 3)) ++#define RTL8367C_UNKNOWN_IPV4_MULTICAST_OFFSET(port) ((port & 0x7) << 1) ++#define RTL8367C_UNKNOWN_IPV4_MULTICAST_MASK(port) (RTL8367C_PORT0_UNKNOWN_IP4_MCAST_MASK << RTL8367C_UNKNOWN_IPV4_MULTICAST_OFFSET(port)) ++ ++#define RTL8367C_UNKNOWN_IPV6_MULTICAST_BASE RTL8367C_REG_UNKNOWN_IPV6_MULTICAST_CTRL0 ++#define RTL8367C_UNKNOWN_IPV6_MULTICAST_REG(port) (RTL8367C_UNKNOWN_IPV6_MULTICAST_BASE + (port >> 3)) ++#define RTL8367C_UNKNOWN_IPV6_MULTICAST_OFFSET(port) ((port & 0x7) << 1) ++#define RTL8367C_UNKNOWN_IPV6_MULTICAST_MASK(port) (RTL8367C_PORT0_UNKNOWN_IP4_MCAST_MASK << RTL8367C_UNKNOWN_IPV6_MULTICAST_OFFSET(port)) ++ ++#define RTL8367C_UNKNOWN_L2_MULTICAST_BASE RTL8367C_REG_UNKNOWN_L2_MULTICAST_CTRL0 ++#define RTL8367C_UNKNOWN_L2_MULTICAST_REG(port) (RTL8367C_UNKNOWN_L2_MULTICAST_BASE + (port >> 3)) ++#define RTL8367C_UNKNOWN_L2_MULTICAST_OFFSET(port) ((port & 0x7) << 1) ++#define RTL8367C_UNKNOWN_L2_MULTICAST_MASK(port) (RTL8367C_PORT0_UNKNOWN_L2_MCAST_MASK << RTL8367C_UNKNOWN_L2_MULTICAST_OFFSET(port)) ++ ++#define RTL8367C_PORT_TRUNK_CTRL_REG RTL8367C_REG_PORT_TRUNK_CTRL ++#define RTL8367C_PORT_TRUNK_HASH_MASK 0x007F ++ ++#define RTL8367C_PORT_TRUNK_GROUP_MASK_REG RTL8367C_REG_PORT_TRUNK_GROUP_MASK ++#define RTL8367C_PORT_TRUNK_GROUP_MASK_OFFSET(group) (group << 2) ++#define RTL8367C_PORT_TRUNK_GROUP_MASK_MASK(group) (RTL8367C_PORT_TRUNK_GROUP0_MASK_MASK << RTL8367C_PORT_TRUNK_GROUP_MASK_OFFSET(group)) ++ ++#define RTL8367C_PORT_TRUNK_FLOWCTRL_REG RTL8367C_REG_PORT_TRUNK_FLOWCTRL ++ ++#define RTL8367C_QOS_PORT_QUEUE_NUMBER_BASE RTL8367C_REG_QOS_PORT_QUEUE_NUMBER_CTRL0 ++#define RTL8367C_QOS_PORT_QUEUE_NUMBER_REG(port) (RTL8367C_QOS_PORT_QUEUE_NUMBER_BASE + (port >> 2)) ++#define RTL8367C_QOS_PORT_QUEUE_NUMBER_OFFSET(port) ((port & 0x3) << 2) ++#define RTL8367C_QOS_PORT_QUEUE_NUMBER_MASK(port) (0x7 << RTL8367C_QOS_PORT_QUEUE_NUMBER_OFFSET(port)) ++ ++#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_BASE RTL8367C_REG_QOS_1Q_PRIORITY_TO_QID_CTRL0 ++#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_REG(index, pri) (RTL8367C_QOS_1Q_PRIORITY_TO_QID_BASE + (index << 1) + (pri >> 2)) ++#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_OFFSET(pri) ((pri & 0x3) << 2) ++#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_MASK(pri) (RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK << RTL8367C_QOS_1Q_PRIORITY_TO_QID_OFFSET(pri)) ++ ++#define RTL8367C_DEBUG_INFO_BASE RTL8367C_REG_PORT_DEBUG_INFO_CTRL0 ++#define RTL8367C_DEBUG_INFO_REG(port) (RTL8367C_DEBUG_INFO_BASE + (port >>1)) ++#define RTL8367C_DEBUG_INFO_OFFSET(port) ((port&1)<<3) ++#define RTL8367C_DEBUG_INFO_MASK(port) (RTL8367C_PORT0_DEBUG_INFO_MASK << RTL8367C_DEBUG_INFO_OFFSET(port)) ++ ++/* (16'h0a00) l2_reg */ ++ ++#define RTL8367C_VLAN_MSTI_BASE RTL8367C_REG_VLAN_MSTI0_CTRL0 ++#define RTL8367C_VLAN_MSTI_REG(tree, port) (RTL8367C_VLAN_MSTI_BASE + (tree << 1) + (port >> 3)) ++#define RTL8367C_VLAN_MSTI_OFFSET(port) ((port & 0x7) << 1) ++#define RTL8367C_VLAN_MSTI_MASK(port) (RTL8367C_VLAN_MSTI0_CTRL0_PORT0_STATE_MASK << RTL8367C_VLAN_MSTI_OFFSET(port)) ++ ++#define RTL8367C_LUT_PORT_LEARN_LIMITNO_BASE RTL8367C_REG_LUT_PORT0_LEARN_LIMITNO ++#define RTL8367C_LUT_PORT_LEARN_LIMITNO_REG(port) (RTL8367C_LUT_PORT_LEARN_LIMITNO_BASE + port) ++ ++#define RTL8367C_LUT_CFG_REG RTL8367C_REG_LUT_CFG ++ ++#define RTL8367C_LUT_AGEOUT_CTRL_REG RTL8367C_REG_LUT_AGEOUT_CTRL ++ ++#define RTL8367C_FORCE_FLUSH_REG RTL8367C_REG_FORCE_FLUSH ++ ++#define RTL8367C_STORM_BCAST_REG RTL8367C_REG_STORM_BCAST ++ ++#define RTL8367C_STORM_MCAST_REG RTL8367C_REG_STORM_MCAST ++ ++#define RTL8367C_STORM_UNKNOWN_UCAST_REG RTL8367C_REG_STORM_UNKOWN_UCAST ++ ++#define RTL8367C_STORM_UNKNOWN_MCAST_REG RTL8367C_REG_STORM_UNKOWN_MCAST ++ ++#define RTL8367C_STORM_BCAST_METER_CTRL_BASE RTL8367C_REG_STORM_BCAST_METER_CTRL0 ++#define RTL8367C_STORM_BCAST_METER_CTRL_REG(port) (RTL8367C_STORM_BCAST_METER_CTRL_BASE + (port >> 1)) ++#define RTL8367C_STORM_BCAST_METER_CTRL_OFFSET(port) ((port & 0x1) << 3) ++#define RTL8367C_STORM_BCAST_METER_CTRL_MASK(port) (0xFF << RTL8367C_STORM_BCAST_METER_CTRL_OFFSET(port)) ++ ++#define RTL8367C_STORM_MCAST_METER_CTRL_BASE RTL8367C_REG_STORM_MCAST_METER_CTRL0 ++#define RTL8367C_STORM_MCAST_METER_CTRL_REG(port) (RTL8367C_STORM_MCAST_METER_CTRL_BASE + (port >> 1)) ++#define RTL8367C_STORM_MCAST_METER_CTRL_OFFSET(port) ((port & 0x1) << 3) ++#define RTL8367C_STORM_MCAST_METER_CTRL_MASK(port) (0xFF << RTL8367C_STORM_MCAST_METER_CTRL_OFFSET(port)) ++ ++#define RTL8367C_STORM_UNDA_METER_CTRL_BASE RTL8367C_REG_STORM_UNDA_METER_CTRL0 ++#define RTL8367C_STORM_UNDA_METER_CTRL_REG(port) (RTL8367C_STORM_UNDA_METER_CTRL_BASE + (port >> 1)) ++#define RTL8367C_STORM_UNDA_METER_CTRL_OFFSET(port) ((port & 0x1) << 3) ++#define RTL8367C_STORM_UNDA_METER_CTRL_MASK(port) (0xFF << RTL8367C_STORM_UNDA_METER_CTRL_OFFSET(port)) ++ ++#define RTL8367C_STORM_UNMC_METER_CTRL_BASE RTL8367C_REG_STORM_UNMC_METER_CTRL0 ++#define RTL8367C_STORM_UNMC_METER_CTRL_REG(port) (RTL8367C_STORM_UNMC_METER_CTRL_BASE + (port >> 1)) ++#define RTL8367C_STORM_UNMC_METER_CTRL_OFFSET(port) ((port & 0x1) << 3) ++#define RTL8367C_STORM_UNMC_METER_CTRL_MASK(port) (0xFF << RTL8367C_STORM_UNMC_METER_CTRL_OFFSET(port)) ++ ++#define RTL8367C_OAM_PARSER_OFFSET(port) (port*2) ++#define RTL8367C_OAM_PARSER_MASK(port) (RTL8367C_PORT0_PARACT_MASK << RTL8367C_OAM_PARSER_OFFSET(port)) ++ ++#define RTL8367C_OAM_MULTIPLEXER_OFFSET(port) (port*2) ++#define RTL8367C_OAM_MULTIPLEXER_MASK(port) (RTL8367C_PORT0_PARACT_MASK << RTL8367C_OAM_MULTIPLEXER_OFFSET(port)) ++ ++#define RTL8367C_OAM_CTRL_REG RTL8367C_REG_OAM_CTRL ++ ++#define RTL8367C_DOT1X_PORT_ENABLE_REG RTL8367C_REG_DOT1X_PORT_ENABLE ++ ++#define RTL8367C_DOT1X_MAC_ENABLE_REG RTL8367C_REG_DOT1X_MAC_ENABLE ++ ++#define RTL8367C_DOT1X_PORT_AUTH_REG RTL8367C_REG_DOT1X_PORT_AUTH ++ ++#define RTL8367C_DOT1X_PORT_OPDIR_REG RTL8367C_REG_DOT1X_PORT_OPDIR ++ ++#define RTL8367C_DOT1X_UNAUTH_ACT_BASE RTL8367C_REG_DOT1X_UNAUTH_ACT_W0 ++#define RTL8367C_DOT1X_UNAUTH_ACT_OFFSET(port) ((port & 0x7) << 1) ++#define RTL8367C_DOT1X_UNAUTH_ACT_MASK(port) (RTL8367C_DOT1X_PORT0_UNAUTHBH_MASK << RTL8367C_DOT1X_UNAUTH_ACT_OFFSET(port)) ++ ++#define RTL8367C_DOT1X_CFG_REG RTL8367C_REG_DOT1X_CFG ++ ++#define RTL8367C_REG_L2_LRN_CNT_BASE RTL8367C_REG_L2_LRN_CNT_CTRL0 ++#define RTL8367C_REG_L2_LRN_CNT_REG(port) (RTL8367C_REG_L2_LRN_CNT_BASE + port) ++ ++/* (16'h0b00) mltvlan_reg */ ++ ++#define RTL8367C_SVLAN_MCAST2S_ENTRY_BASE_REG(index) (RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL0 + index*5) ++ ++/* (16'h0c00) svlan_reg */ ++ ++#define RTL8367C_SVLAN_MEMBERCFG_BASE_REG(index) (RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL1 + index*3) ++#define RTL8367C_SVLAN_C2SCFG_BASE_REG(index) (RTL8367C_REG_SVLAN_C2SCFG0_CTRL0+ index*3) ++#define RTL8367C_SVLAN_CFG_REG RTL8367C_REG_SVLAN_CFG ++ ++/* (16'h0f00) hsactrl_reg */ ++ ++#define RTL8367C_SVLAN_S2C_ENTRY_BASE_REG(index) (RTL8367C_REG_SVLAN_SP2C_ENTRY0_CTRL0 + index*2) ++ ++/* (16'h1000) mib_reg */ ++ ++#define RTL8367C_MIB_COUNTER_BASE_REG RTL8367C_REG_MIB_COUNTER0 ++ ++#define RTL8367C_MIB_ADDRESS_REG RTL8367C_REG_MIB_ADDRESS ++ ++#define RTL8367C_MIB_CTRL_REG RTL8367C_REG_MIB_CTRL0 ++#define RTL8367C_MIB_PORT07_MASK (0xFF<> 4)) ++#define RTL8367C_REG_METER_EXCEED_INDICATOR_OFFSET(meter) (meter & 0xF) ++ ++/* (16'h1200) swcore_reg */ ++ ++#define RTL8367C_VS_TPID_REG RTL8367C_REG_VS_TPID ++ ++#define RTL8367C_SWITCH_MAC_BASE RTL8367C_REG_SWITCH_MAC0 ++ ++#define RTL8367C_REMARKING_CTRL_REG RTL8367C_REG_SWITCH_CTRL0 ++ ++#define RTL8367C_QOS_DSCP_REMARK_BASE RTL8367C_REG_QOS_DSCP_REMARK_CTRL0 ++#define RTL8367C_QOS_DSCP_REMARK_REG(pri) (RTL8367C_QOS_DSCP_REMARK_BASE + (pri >> 1)) ++#define RTL8367C_QOS_DSCP_REMARK_OFFSET(pri) (((pri) & 0x1) << 3) ++#define RTL8367C_QOS_DSCP_REMARK_MASK(pri) (0x3F << RTL8367C_QOS_DSCP_REMARK_OFFSET(pri)) ++ ++#define RTL8367C_QOS_1Q_REMARK_BASE RTL8367C_REG_QOS_1Q_REMARK_CTRL0 ++#define RTL8367C_QOS_1Q_REMARK_REG(pri) (RTL8367C_QOS_1Q_REMARK_BASE + (pri >> 2)) ++#define RTL8367C_QOS_1Q_REMARK_OFFSET(pri) ((pri & 0x3) << 2) ++#define RTL8367C_QOS_1Q_REMARK_MASK(pri) (0x7 << RTL8367C_QOS_1Q_REMARK_OFFSET(pri)) ++ ++#define RTL8367C_PTKGEN_PAYLOAD_CTRL0_REG RTL8367C_REG_PTKGEN_PAYLOAD_CTRL0 ++ ++#define RTL8367C_PTKGEN_PAYLOAD_CTRL1_REG RTL8367C_REG_PTKGEN_PAYLOAD_CTRL1 ++ ++#define RTL8367C_SVLAN_UPLINK_PORTMASK_REG RTL8367C_REG_SVLAN_UPLINK_PORTMASK ++ ++#define RTL8367C_CPU_PORT_MASK_REG RTL8367C_REG_CPU_PORT_MASK ++ ++#define RTL8367C_CPU_CTRL_REG RTL8367C_REG_CPU_CTRL ++ ++#define RTL8367C_MIRROR_CTRL_REG RTL8367C_REG_MIRROR_CTRL ++ ++ ++#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_BASE RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL0 ++#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG(port) (RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_BASE + (port >> 1)) ++#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG_OFFSET(port) ((port & 0x1) << 3) ++#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG_MASK(port) (RTL8367C_PORT0_QUEUE_MASK_MASK << RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG_OFFSET(port)) ++ ++ ++#define RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_BASE RTL8367C_REG_FLOWCTRL_PORT0_PAGE_COUNTER ++#define RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_REG(port) (RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_BASE + port) ++#define RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_MASK RTL8367C_FLOWCTRL_PORT0_PAGE_COUNTER_MASK ++ ++#define RTL8367C_FLOWCTRL_PORT_PAGE_MAX_BASE RTL8367C_REG_FLOWCTRL_PORT0_PAGE_MAX ++#define RTL8367C_FLOWCTRL_PORT_PAGE_MAX_REG(port) (RTL8367C_FLOWCTRL_PORT_PAGE_MAX_BASE + port) ++#define RTL8367C_FLOWCTRL_PORT_PAGE_MAX_MASK RTL8367C_FLOWCTRL_PORT0_PAGE_MAX_MASK ++ ++#define RTL8367C_FIELD_SELECTOR_REG(index) (RTL8367C_REG_FIELD_SELECTOR0 + index) ++#define RTL8367C_FIELD_SELECTOR_ENABLE_OFFSET RTL8367C_FIELD_SELECTOR0_ENABLE_OFFSET ++#define RTL8367C_FIELD_SELECTOR_ENABLE_MASK RTL8367C_FIELD_SELECTOR0_ENABLE_MASK ++#define RTL8367C_FIELD_SELECTOR_FORMAT_OFFSET RTL8367C_FIELD_SELECTOR0_FORMAT_OFFSET ++#define RTL8367C_FIELD_SELECTOR_FORMAT_MASK RTL8367C_FIELD_SELECTOR0_FORMAT_MASK ++#define RTL8367C_FIELD_SELECTOR_OFFSET_OFFSET RTL8367C_FIELD_SELECTOR0_OFFSET_OFFSET ++#define RTL8367C_FIELD_SELECTOR_OFFSET_MASK RTL8367C_FIELD_SELECTOR0_OFFSET_MASK ++ ++/* (16'h1300) chip_reg*/ ++ ++/* (16'h1400) mtrpool_reg */ ++#define RTL8367C_METER_RATE_BASE RTL8367C_REG_METER0_RATE_CTRL0 ++#define RTL8367C_METER_RATE_REG(meter) ((meter << 1) + RTL8367C_METER_RATE_BASE) ++ ++#define RTL8367C_METER_BUCKET_SIZE_BASE RTL8367C_REG_METER0_BUCKET_SIZE ++#define RTL8367C_METER_BUCKET_SIZE_REG(meter) (RTL8367C_METER_BUCKET_SIZE_BASE + meter) ++ ++#define RTL8367C_LEAKY_BUCKET_TICK_REG RTL8367C_REG_METER_CTRL0 ++#define RTL8367C_LEAKY_BUCKET_TICK_OFFSET RTL8367C_METER_TICK_OFFSET ++#define RTL8367C_LEAKY_BUCKET_TICK_MASK RTL8367C_METER_TICK_MASK ++ ++#define RTL8367C_LEAKY_BUCKET_TOKEN_REG RTL8367C_REG_METER_CTRL1 ++#define RTL8367C_LEAKY_BUCKET_TOKEN_OFFSET RTL8367C_METER_CTRL1_OFFSET ++#define RTL8367C_LEAKY_BUCKET_TOKEN_MASK RTL8367C_METER_CTRL1_MASK ++ ++#define RTL8367C_METER_OVERRATE_INDICATOR_BASE RTL8367C_REG_METER_OVERRATE_INDICATOR0 ++#define RTL8367C_METER_OVERRATE_INDICATOR_REG(meter) (RTL8367C_METER_OVERRATE_INDICATOR_BASE + (meter >> 4)) ++#define RTL8367C_METER_EXCEED_OFFSET(meter) (meter & 0xF) ++#define RTL8367C_METER_EXCEED_MASK(meter) (1 << RTL8367C_METER_EXCEED_OFFSET(meter)) ++ ++#define RTL8367C_METER_IFG_CTRL_BASE RTL8367C_REG_METER_IFG_CTRL0 ++#define RTL8367C_METER_IFG_CTRL_REG(meter) (RTL8367C_METER_IFG_CTRL_BASE + (meter >> 4)) ++#define RTL8367C_METER_IFG_OFFSET(meter) (meter & 0xF) ++#define RTL8367C_METER_IFG_MASK(meter) (1 << RTL8367C_METER_IFG_OFFSET(meter)) ++ ++#define RTL8367C_FLOWCTRL_CTRL_REG RTL8367C_REG_FLOWCTRL_CTRL0 ++ ++/* (16'h1800)8051_RLDP_EEE_reg */ ++#define RTL8367C_EEELLDP_CTRL0_REG RTL8367C_REG_EEELLDP_CTRL0 ++ ++#define RTL8367C_EEELLDP_CTRL1_REG RTL8367C_REG_EEELLDP_CTRL1 ++ ++#define RTL8367C_EEELLDP_PMSK_REG RTL8367C_REG_EEELLDP_PMSK ++ ++#define RTL8367C_EEELLDP_TX_FRAMEU_REG_BASE RTL8367C_REG_EEELLDP_FRAMEU00 ++ ++#define RTL8367C_EEELLDP_TX_CAP_FRAMEL_REG_BASE RTL8367C_REG_EEELLDP_CAP_FRAMEL00 ++ ++#define RTL8367C_EEELLDP_RX_VALUE_PORT_BASE RTL8367C_REG_EEELLDP_RX_VALUE_P00_00 ++#define RTL8367C_EEELLDP_RX_VALUE_PORT_REG(port) (RTL8367C_EEELLDP_RX_VALUE_PORT_BASE + (port * 9)) ++ ++#define RTL8367C_RLDP_CTRL0_REG RTL8367C_REG_RLDP_CTRL0 ++#define RTL8367C_RLDP_MODE_OFFSET 14 ++ ++#define RTL8367C_RLDP_RETRY_COUNT_REG RTL8367C_REG_RLDP_CTRL1 ++ ++#define RTL8367C_RLDP_RETRY_PERIOD_LOOPSTATE_REG RTL8367C_REG_RLDP_CTRL2 ++ ++#define RTL8367C_RLDP_RETRY_PERIOD_CHKSTATE_REG RTL8367C_REG_RLDP_CTRL3 ++ ++#define RTL8367C_RLDP_TX_PMSK_REG RTL8367C_REG_RLDP_CTRL4 ++ ++#define RTL8367C_RLDP_RAND_NUM_REG_BASE RTL8367C_REG_RLDP_RAND_NUM0 ++ ++#define RTL8367C_RLDP_MAGIC_NUM_REG_BASE RTL8367C_REG_RLDP_MAGIC_NUM0 ++ ++#define RTL8367C_RLDP_LOOP_PMSK_REG RTL8367C_REG_RLDP_LOOPSTATUS_INDICATOR ++ ++#define RTL8367C_RLDP_LOOP_PORT_BASE RTL8367C_REG_RLDP_LOOP_PORT_REG0 ++#define RTL8367C_RLDP_LOOP_PORT_REG(port) (RTL8367C_RLDP_LOOP_PORT_BASE + (port >> 1)) ++#define RTL8367C_RLDP_LOOP_PORT_OFFSET(port) ((port & 0x1) << 3) ++#define RTL8367C_RLDP_LOOP_PORT_MASK(port) (RTL8367C_RLDP_LOOP_PORT_00_MASK << RTL8367C_RLDP_LOOP_PORT_OFFSET(port)) ++ ++#define RTL8367C_PAGEMETER_PORT_BASE RTL8367C_REG_PAGEMETER_PORT0_CTRL0 ++#define RTL8367C_PAGEMETER_PORT_REG(port) (RTL8367C_PAGEMETER_PORT_BASE + 0x20*port) ++ ++#define RTL8367C_HIGHPRI_INDICATOR_REG RTL8367C_REG_HIGHPRI_INDICATOR ++#define RTL8367C_PORT_INDICATOR_OFFSET(port) (port) ++#define RTL8367C_PORT_INDICATOR_MASK(port) (RTL8367C_PORT0_INDICATOR_MASK << RTL8367C_PORT_INDICATOR_OFFSET(port)) ++ ++#define RTL8367C_HIGHPRI_CFG_REG RTL8367C_REG_HIGHPRI_CFG ++ ++#define RTL8367C_EAV_PRIORITY_REMAPPING_BASE RTL8367C_REG_EAV_CTRL1 ++#define RTL8367C_EAV_PRIORITY_REMAPPING_REG(pri) (RTL8367C_EAV_PRIORITY_REMAPPING_BASE + (pri >> 2)) ++#define RTL8367C_EAV_PRIORITY_REMAPPING_OFFSET(pri) ((pri & 0x3) * RTL8367C_REMAP_EAV_PRI1_REGEN_OFFSET) ++#define RTL8367C_EAV_PRIORITY_REMAPPING_MASK(pri) (RTL8367C_REMAP_EAV_PRI0_REGEN_MASK << RTL8367C_EAV_PRIORITY_REMAPPING_OFFSET(pri)) ++ ++#define RTL8367C_EEEP_CFG_BASE RTL8367C_REG_PORT0_EEECFG ++#define RTL8367C_EEEP_CFG_REG(port) (RTL8367C_EEEP_CFG_BASE + (port*0x20)) ++ ++#define RTL8367C_PKG_CFG_BASE RTL8367C_REG_PKTGEN_PORT0_CTRL ++#define RTL8367C_PKG_CFG_REG(port) (RTL8367C_PKG_CFG_BASE + (port*0x20)) ++ ++#define RTL8367C_PKG_DA_BASE RTL8367C_REG_PKTGEN_PORT0_DA0 ++#define RTL8367C_PKG_DA_REG(port) (RTL8367C_PKG_DA_BASE + (port*0x20)) ++ ++#define RTL8367C_PKG_SA_BASE RTL8367C_REG_PKTGEN_PORT0_SA0 ++#define RTL8367C_PKG_SA_REG(port) (RTL8367C_PKG_SA_BASE + (port*0x20)) ++ ++#define RTL8367C_PKG_NUM_BASE RTL8367C_REG_PKTGEN_PORT0_COUNTER0 ++#define RTL8367C_PKG_NUM_REG(port) (RTL8367C_PKG_NUM_BASE + (port*0x20)) ++ ++#define RTL8367C_PKG_LENGTH_BASE RTL8367C_REG_PKTGEN_PORT0_TX_LENGTH ++#define RTL8367C_PKG_LENGTH_REG(port) (RTL8367C_PKG_LENGTH_BASE + (port*0x20)) ++ ++/* (16'h1c00)IGMP_MLD_reg */ ++#define RTL8367C_IGMP_GROUP_USAGE_BASE RTL8367C_REG_IGMP_GROUP_USAGE_LIST0 ++#define RTL8367C_IGMP_GROUP_USAGE_REG(idx) (RTL8367C_IGMP_GROUP_USAGE_BASE + (idx / 16)) ++ ++#define RTL8367C_FALLBACK_BASE RTL8367C_REG_FALLBACK_PORT0_CFG0 ++#define RTL8367C_FALLBACK_PORT_CFG_REG(port) (RTL8367C_FALLBACK_BASE + (port * 4)) ++#define RTL8367C_FALLBACK_PORT_MON_CNT_REG(port) (RTL8367C_FALLBACK_BASE + 1 + (port * 4)) ++#define RTL8367C_FALLBACK_PORT_ERR_CNT_REG(port) (RTL8367C_FALLBACK_BASE + 3 + (port * 4)) ++ ++ ++/* (16'h6400)timer_1588 */ ++#define RTL8367C_EAV_CFG_BASE RTL8367C_REG_P0_EAV_CFG ++#define RTL8367C_EAV_PORT_CFG_REG(port) (RTL8367C_EAV_CFG_BASE + (port *0x10)) ++#define RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET RTL8367C_P0_EAV_CFG_PTP_PHY_EN_EN_OFFSET ++#define RTL8367C_EAV_CFG_RX_PDELAY_RESP_OFFSET RTL8367C_P0_EAV_CFG_RX_PDELAY_RESP_OFFSET ++#define RTL8367C_EAV_CFG_RX_PDELAY_REQ_OFFSET RTL8367C_P0_EAV_CFG_RX_PDELAY_REQ_OFFSET ++#define RTL8367C_EAV_CFG_RX_DELAY_REQ_OFFSET RTL8367C_P0_EAV_CFG_RX_DELAY_REQ_OFFSET ++#define RTL8367C_EAV_CFG_RX_SYNC_OFFSET RTL8367C_P0_EAV_CFG_RX_SYNC_OFFSET ++#define RTL8367C_EAV_CFG_TX_PDELAY_RESP_OFFSET RTL8367C_P0_EAV_CFG_TX_PDELAY_RESP_OFFSET ++#define RTL8367C_EAV_CFG_TX_PDELAY_REQ_OFFSET RTL8367C_P0_EAV_CFG_TX_PDELAY_REQ_OFFSET ++#define RTL8367C_EAV_CFG_TX_DELAY_REQ_OFFSET RTL8367C_P0_EAV_CFG_TX_DELAY_REQ_OFFSET ++#define RTL8367C_EAV_CFG_TX_SYNC_OFFSET RTL8367C_P0_EAV_CFG_TX_SYNC_OFFSET ++ ++#define RTL8367C_REG_TX_SYNC_SEQ_ID_BASE RTL8367C_REG_P0_TX_SYNC_SEQ_ID ++#define RTL8367C_REG_TX_SYNC_SEQ_ID(port) (RTL8367C_REG_TX_SYNC_SEQ_ID_BASE + (port *0x10)) ++#define RTL8367C_REG_SEQ_ID(port, type) (RTL8367C_REG_TX_SYNC_SEQ_ID_BASE + type + (port *0x10)) ++ ++#define RTL8367C_REG_TX_DELAY_REQ_SEQ_ID_BASE RTL8367C_REG_P0_TX_DELAY_REQ_SEQ_ID ++#define RTL8367C_REG_TX_PDELAY_REQ_SEQ_ID_BASE RTL8367C_REG_P0_TX_PDELAY_REQ_SEQ_ID ++#define RTL8367C_REG_TX_PDELAY_RESP_SEQ_ID_BASE RTL8367C_REG_P0_TX_PDELAY_RESP_SEQ_ID ++#define RTL8367C_REG_RX_SYNC_SEQ_ID_BASE RTL8367C_REG_P0_RX_SYNC_SEQ_ID ++#define RTL8367C_REG_RX_DELAY_REQ_SEQ_ID_BASE RTL8367C_REG_P0_RX_DELAY_REQ_SEQ_ID ++#define RTL8367C_REG_RX_PDELAY_REQ_SEQ_ID_BASE RTL8367C_REG_P0_RX_PDELAY_REQ_SEQ_ID ++#define RTL8367C_REG_RX_PDELAY_RESP_SEQ_ID_BASE RTL8367C_REG_P0_RX_PDELAY_RESP_SEQ_ID ++ ++#define RTL8367C_REG_PORT_NSEC_L_BASE RTL8367C_REG_P0_PORT_NSEC_15_0 ++#define RTL8367C_REG_PORT_NSEC_L(port) (RTL8367C_REG_PORT_NSEC_L_BASE + (port *0x10)) ++#define RTL8367C_REG_PORT_NSEC_H_BASE RTL8367C_REG_P0_PORT_NSEC_26_16 ++#define RTL8367C_REG_PORT_NSEC_H(port) (RTL8367C_REG_PORT_NSEC_H_BASE + (port *0x10)) ++#define RTL8367C_PORT_NSEC_H_OFFSET RTL8367C_P0_PORT_NSEC_26_16_OFFSET ++#define RTL8367C_PORT_NSEC_H_MASK RTL8367C_P0_PORT_NSEC_26_16_MASK ++ ++#define RTL8367C_REG_PORT_SEC_L_BASE RTL8367C_REG_P0_PORT_SEC_15_0 ++#define RTL8367C_REG_PORT_SEC_L(port) (RTL8367C_REG_PORT_SEC_L_BASE + (port *0x10)) ++#define RTL8367C_REG_PORT_SEC_H_BASE RTL8367C_REG_P0_PORT_SEC_31_16 ++#define RTL8367C_REG_PORT_SEC_H(port) (RTL8367C_REG_PORT_SEC_H_BASE + (port *0x10)) ++ ++#endif /*#ifndef _RTL8367C_BASE_H_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_reg.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_reg.h +new file mode 100644 +index 0000000000..eb4f48b83e +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/rtl8367c_reg.h +@@ -0,0 +1,22819 @@ ++#ifndef _RTL8367C_REG_H_ ++#define _RTL8367C_REG_H_ ++ ++/************************************************************ ++auto-generated register address and field data ++*************************************************************/ ++ ++/* (16'h0000)port_reg */ ++ ++#define RTL8367C_REG_PORT0_CGST_HALF_CFG 0x0000 ++#define RTL8367C_PORT0_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 ++#define RTL8367C_PORT0_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 ++#define RTL8367C_PORT0_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 ++#define RTL8367C_PORT0_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF ++ ++#define RTL8367C_REG_PKTGEN_PORT0_CTRL 0x0001 ++#define RTL8367C_PKTGEN_PORT0_CTRL_STATUS_OFFSET 15 ++#define RTL8367C_PKTGEN_PORT0_CTRL_STATUS_MASK 0x8000 ++#define RTL8367C_PKTGEN_PORT0_CTRL_PKTGEN_STS_OFFSET 13 ++#define RTL8367C_PKTGEN_PORT0_CTRL_PKTGEN_STS_MASK 0x2000 ++#define RTL8367C_PKTGEN_PORT0_CTRL_CRC_NO_ERROR_OFFSET 4 ++#define RTL8367C_PKTGEN_PORT0_CTRL_CRC_NO_ERROR_MASK 0x10 ++#define RTL8367C_PKTGEN_PORT0_CTRL_CMD_START_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT0_CTRL_CMD_START_MASK 0x1 ++ ++#define RTL8367C_REG_TX_ERR_CNT_PORT0 0x0002 ++#define RTL8367C_TX_ERR_CNT_PORT0_OFFSET 0 ++#define RTL8367C_TX_ERR_CNT_PORT0_MASK 0x7 ++ ++#define RTL8367C_REG_PKTGEN_PORT0_DA0 0x0003 ++ ++#define RTL8367C_REG_PKTGEN_PORT0_DA1 0x0004 ++ ++#define RTL8367C_REG_PKTGEN_PORT0_DA2 0x0005 ++ ++#define RTL8367C_REG_PKTGEN_PORT0_SA0 0x0006 ++ ++#define RTL8367C_REG_PKTGEN_PORT0_SA1 0x0007 ++ ++#define RTL8367C_REG_PKTGEN_PORT0_SA2 0x0008 ++ ++#define RTL8367C_REG_PKTGEN_PORT0_COUNTER0 0x0009 ++ ++#define RTL8367C_REG_PKTGEN_PORT0_COUNTER1 0x000a ++#define RTL8367C_PKTGEN_PORT0_COUNTER1_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT0_COUNTER1_MASK 0xFF ++ ++#define RTL8367C_REG_PKTGEN_PORT0_TX_LENGTH 0x000b ++#define RTL8367C_PKTGEN_PORT0_TX_LENGTH_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT0_TX_LENGTH_MASK 0x3FFF ++ ++#define RTL8367C_REG_PKTGEN_PORT0_TIMER 0x000d ++#define RTL8367C_PKTGEN_PORT0_TIMER_TIMER_OFFSET 4 ++#define RTL8367C_PKTGEN_PORT0_TIMER_TIMER_MASK 0xF0 ++#define RTL8367C_PKTGEN_PORT0_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 ++#define RTL8367C_PKTGEN_PORT0_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 ++ ++#define RTL8367C_REG_PORT0_MISC_CFG 0x000e ++#define RTL8367C_PORT0_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 ++#define RTL8367C_PORT0_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 ++#define RTL8367C_PORT0_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 ++#define RTL8367C_PORT0_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 ++#define RTL8367C_PORT0_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 ++#define RTL8367C_PORT0_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 ++#define RTL8367C_PORT0_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 ++#define RTL8367C_PORT0_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 ++#define RTL8367C_PORT0_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 ++#define RTL8367C_PORT0_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 ++#define RTL8367C_PORT0_MISC_CFG_INGRESSBW_IFG_OFFSET 10 ++#define RTL8367C_PORT0_MISC_CFG_INGRESSBW_IFG_MASK 0x400 ++#define RTL8367C_PORT0_MISC_CFG_RX_SPC_OFFSET 9 ++#define RTL8367C_PORT0_MISC_CFG_RX_SPC_MASK 0x200 ++#define RTL8367C_PORT0_MISC_CFG_CRC_SKIP_OFFSET 8 ++#define RTL8367C_PORT0_MISC_CFG_CRC_SKIP_MASK 0x100 ++#define RTL8367C_PORT0_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 ++#define RTL8367C_PORT0_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 ++#define RTL8367C_PORT0_MISC_CFG_MAC_LOOPBACK_OFFSET 6 ++#define RTL8367C_PORT0_MISC_CFG_MAC_LOOPBACK_MASK 0x40 ++#define RTL8367C_PORT0_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 ++#define RTL8367C_PORT0_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 ++#define RTL8367C_PORT0_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 ++#define RTL8367C_PORT0_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF ++ ++#define RTL8367C_REG_INGRESSBW_PORT0_RATE_CTRL0 0x000f ++ ++#define RTL8367C_REG_INGRESSBW_PORT0_RATE_CTRL1 0x0010 ++#define RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_DUMMY_OFFSET 3 ++#define RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_DUMMY_MASK 0xFFF8 ++#define RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 ++#define RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 ++ ++#define RTL8367C_REG_PORT0_FORCE_RATE0 0x0011 ++ ++#define RTL8367C_REG_PORT0_FORCE_RATE1 0x0012 ++ ++#define RTL8367C_REG_PORT0_CURENT_RATE0 0x0013 ++ ++#define RTL8367C_REG_PORT0_CURENT_RATE1 0x0014 ++ ++#define RTL8367C_REG_PORT0_PAGE_COUNTER 0x0015 ++#define RTL8367C_PORT0_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_PORT0_PAGE_COUNTER_MASK 0x7F ++ ++#define RTL8367C_REG_PAGEMETER_PORT0_CTRL0 0x0016 ++ ++#define RTL8367C_REG_PAGEMETER_PORT0_CTRL1 0x0017 ++ ++#define RTL8367C_REG_PORT0_EEECFG 0x0018 ++#define RTL8367C_PORT0_EEECFG_EEEP_ENABLE_TX_OFFSET 14 ++#define RTL8367C_PORT0_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 ++#define RTL8367C_PORT0_EEECFG_EEEP_ENABLE_RX_OFFSET 13 ++#define RTL8367C_PORT0_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 ++#define RTL8367C_PORT0_EEECFG_EEE_FORCE_OFFSET 12 ++#define RTL8367C_PORT0_EEECFG_EEE_FORCE_MASK 0x1000 ++#define RTL8367C_PORT0_EEECFG_EEE_100M_OFFSET 11 ++#define RTL8367C_PORT0_EEECFG_EEE_100M_MASK 0x800 ++#define RTL8367C_PORT0_EEECFG_EEE_GIGA_500M_OFFSET 10 ++#define RTL8367C_PORT0_EEECFG_EEE_GIGA_500M_MASK 0x400 ++#define RTL8367C_PORT0_EEECFG_EEE_TX_OFFSET 9 ++#define RTL8367C_PORT0_EEECFG_EEE_TX_MASK 0x200 ++#define RTL8367C_PORT0_EEECFG_EEE_RX_OFFSET 8 ++#define RTL8367C_PORT0_EEECFG_EEE_RX_MASK 0x100 ++#define RTL8367C_PORT0_EEECFG_EEE_DSP_RX_OFFSET 6 ++#define RTL8367C_PORT0_EEECFG_EEE_DSP_RX_MASK 0x40 ++#define RTL8367C_PORT0_EEECFG_EEE_LPI_OFFSET 5 ++#define RTL8367C_PORT0_EEECFG_EEE_LPI_MASK 0x20 ++#define RTL8367C_PORT0_EEECFG_EEE_TX_LPI_OFFSET 4 ++#define RTL8367C_PORT0_EEECFG_EEE_TX_LPI_MASK 0x10 ++#define RTL8367C_PORT0_EEECFG_EEE_RX_LPI_OFFSET 3 ++#define RTL8367C_PORT0_EEECFG_EEE_RX_LPI_MASK 0x8 ++#define RTL8367C_PORT0_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 ++#define RTL8367C_PORT0_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 ++#define RTL8367C_PORT0_EEECFG_EEE_WAKE_REQ_OFFSET 1 ++#define RTL8367C_PORT0_EEECFG_EEE_WAKE_REQ_MASK 0x2 ++#define RTL8367C_PORT0_EEECFG_EEE_SLEEP_REQ_OFFSET 0 ++#define RTL8367C_PORT0_EEECFG_EEE_SLEEP_REQ_MASK 0x1 ++ ++#define RTL8367C_REG_PORT0_EEETXMTR 0x0019 ++ ++#define RTL8367C_REG_PORT0_EEERXMTR 0x001a ++ ++#define RTL8367C_REG_PORT0_EEEPTXMTR 0x001b ++ ++#define RTL8367C_REG_PORT0_EEEPRXMTR 0x001c ++ ++#define RTL8367C_REG_PTP_PORT0_CFG1 0x001e ++#define RTL8367C_PTP_PORT0_CFG1_OFFSET 7 ++#define RTL8367C_PTP_PORT0_CFG1_MASK 0xFF ++ ++#define RTL8367C_REG_P0_MSIC1 0x001f ++#define RTL8367C_P0_MSIC1_OFFSET 0 ++#define RTL8367C_P0_MSIC1_MASK 0x1 ++ ++#define RTL8367C_REG_PORT1_CGST_HALF_CFG 0x0020 ++#define RTL8367C_PORT1_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 ++#define RTL8367C_PORT1_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 ++#define RTL8367C_PORT1_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 ++#define RTL8367C_PORT1_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF ++ ++#define RTL8367C_REG_PKTGEN_PORT1_CTRL 0x0021 ++#define RTL8367C_PKTGEN_PORT1_CTRL_STATUS_OFFSET 15 ++#define RTL8367C_PKTGEN_PORT1_CTRL_STATUS_MASK 0x8000 ++#define RTL8367C_PKTGEN_PORT1_CTRL_PKTGEN_STS_OFFSET 13 ++#define RTL8367C_PKTGEN_PORT1_CTRL_PKTGEN_STS_MASK 0x2000 ++#define RTL8367C_PKTGEN_PORT1_CTRL_CRC_NO_ERROR_OFFSET 4 ++#define RTL8367C_PKTGEN_PORT1_CTRL_CRC_NO_ERROR_MASK 0x10 ++#define RTL8367C_PKTGEN_PORT1_CTRL_CMD_START_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT1_CTRL_CMD_START_MASK 0x1 ++ ++#define RTL8367C_REG_TX_ERR_CNT_PORT1 0x0022 ++#define RTL8367C_TX_ERR_CNT_PORT1_OFFSET 0 ++#define RTL8367C_TX_ERR_CNT_PORT1_MASK 0x7 ++ ++#define RTL8367C_REG_PKTGEN_PORT1_DA0 0x0023 ++ ++#define RTL8367C_REG_PKTGEN_PORT1_DA1 0x0024 ++ ++#define RTL8367C_REG_PKTGEN_PORT1_DA2 0x0025 ++ ++#define RTL8367C_REG_PKTGEN_PORT1_SA0 0x0026 ++ ++#define RTL8367C_REG_PKTGEN_PORT1_SA1 0x0027 ++ ++#define RTL8367C_REG_PKTGEN_PORT1_SA2 0x0028 ++ ++#define RTL8367C_REG_PKTGEN_PORT1_COUNTER0 0x0029 ++ ++#define RTL8367C_REG_PKTGEN_PORT1_COUNTER1 0x002a ++#define RTL8367C_PKTGEN_PORT1_COUNTER1_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT1_COUNTER1_MASK 0xFF ++ ++#define RTL8367C_REG_PKTGEN_PORT1_TX_LENGTH 0x002b ++#define RTL8367C_PKTGEN_PORT1_TX_LENGTH_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT1_TX_LENGTH_MASK 0x3FFF ++ ++#define RTL8367C_REG_PKTGEN_PORT1_TIMER 0x002d ++#define RTL8367C_PKTGEN_PORT1_TIMER_TIMER_OFFSET 4 ++#define RTL8367C_PKTGEN_PORT1_TIMER_TIMER_MASK 0xF0 ++#define RTL8367C_PKTGEN_PORT1_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 ++#define RTL8367C_PKTGEN_PORT1_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 ++ ++#define RTL8367C_REG_PORT1_MISC_CFG 0x002e ++#define RTL8367C_PORT1_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 ++#define RTL8367C_PORT1_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 ++#define RTL8367C_PORT1_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 ++#define RTL8367C_PORT1_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 ++#define RTL8367C_PORT1_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 ++#define RTL8367C_PORT1_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 ++#define RTL8367C_PORT1_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 ++#define RTL8367C_PORT1_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 ++#define RTL8367C_PORT1_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 ++#define RTL8367C_PORT1_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 ++#define RTL8367C_PORT1_MISC_CFG_INGRESSBW_IFG_OFFSET 10 ++#define RTL8367C_PORT1_MISC_CFG_INGRESSBW_IFG_MASK 0x400 ++#define RTL8367C_PORT1_MISC_CFG_RX_SPC_OFFSET 9 ++#define RTL8367C_PORT1_MISC_CFG_RX_SPC_MASK 0x200 ++#define RTL8367C_PORT1_MISC_CFG_CRC_SKIP_OFFSET 8 ++#define RTL8367C_PORT1_MISC_CFG_CRC_SKIP_MASK 0x100 ++#define RTL8367C_PORT1_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 ++#define RTL8367C_PORT1_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 ++#define RTL8367C_PORT1_MISC_CFG_MAC_LOOPBACK_OFFSET 6 ++#define RTL8367C_PORT1_MISC_CFG_MAC_LOOPBACK_MASK 0x40 ++#define RTL8367C_PORT1_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 ++#define RTL8367C_PORT1_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 ++#define RTL8367C_PORT1_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 ++#define RTL8367C_PORT1_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF ++ ++#define RTL8367C_REG_INGRESSBW_PORT1_RATE_CTRL0 0x002f ++ ++#define RTL8367C_REG_INGRESSBW_PORT1_RATE_CTRL1 0x0030 ++#define RTL8367C_INGRESSBW_PORT1_RATE_CTRL1_DUMMY_OFFSET 3 ++#define RTL8367C_INGRESSBW_PORT1_RATE_CTRL1_DUMMY_MASK 0xFFF8 ++#define RTL8367C_INGRESSBW_PORT1_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 ++#define RTL8367C_INGRESSBW_PORT1_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 ++ ++#define RTL8367C_REG_PORT1_FORCE_RATE0 0x0031 ++ ++#define RTL8367C_REG_PORT1_FORCE_RATE1 0x0032 ++ ++#define RTL8367C_REG_PORT1_CURENT_RATE0 0x0033 ++ ++#define RTL8367C_REG_PORT1_CURENT_RATE1 0x0034 ++ ++#define RTL8367C_REG_PORT1_PAGE_COUNTER 0x0035 ++#define RTL8367C_PORT1_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_PORT1_PAGE_COUNTER_MASK 0x7F ++ ++#define RTL8367C_REG_PAGEMETER_PORT1_CTRL0 0x0036 ++ ++#define RTL8367C_REG_PAGEMETER_PORT1_CTRL1 0x0037 ++ ++#define RTL8367C_REG_PORT1_EEECFG 0x0038 ++#define RTL8367C_PORT1_EEECFG_EEEP_ENABLE_TX_OFFSET 14 ++#define RTL8367C_PORT1_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 ++#define RTL8367C_PORT1_EEECFG_EEEP_ENABLE_RX_OFFSET 13 ++#define RTL8367C_PORT1_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 ++#define RTL8367C_PORT1_EEECFG_EEE_FORCE_OFFSET 12 ++#define RTL8367C_PORT1_EEECFG_EEE_FORCE_MASK 0x1000 ++#define RTL8367C_PORT1_EEECFG_EEE_100M_OFFSET 11 ++#define RTL8367C_PORT1_EEECFG_EEE_100M_MASK 0x800 ++#define RTL8367C_PORT1_EEECFG_EEE_GIGA_500M_OFFSET 10 ++#define RTL8367C_PORT1_EEECFG_EEE_GIGA_500M_MASK 0x400 ++#define RTL8367C_PORT1_EEECFG_EEE_TX_OFFSET 9 ++#define RTL8367C_PORT1_EEECFG_EEE_TX_MASK 0x200 ++#define RTL8367C_PORT1_EEECFG_EEE_RX_OFFSET 8 ++#define RTL8367C_PORT1_EEECFG_EEE_RX_MASK 0x100 ++#define RTL8367C_PORT1_EEECFG_EEE_DSP_RX_OFFSET 6 ++#define RTL8367C_PORT1_EEECFG_EEE_DSP_RX_MASK 0x40 ++#define RTL8367C_PORT1_EEECFG_EEE_LPI_OFFSET 5 ++#define RTL8367C_PORT1_EEECFG_EEE_LPI_MASK 0x20 ++#define RTL8367C_PORT1_EEECFG_EEE_TX_LPI_OFFSET 4 ++#define RTL8367C_PORT1_EEECFG_EEE_TX_LPI_MASK 0x10 ++#define RTL8367C_PORT1_EEECFG_EEE_RX_LPI_OFFSET 3 ++#define RTL8367C_PORT1_EEECFG_EEE_RX_LPI_MASK 0x8 ++#define RTL8367C_PORT1_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 ++#define RTL8367C_PORT1_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 ++#define RTL8367C_PORT1_EEECFG_EEE_WAKE_REQ_OFFSET 1 ++#define RTL8367C_PORT1_EEECFG_EEE_WAKE_REQ_MASK 0x2 ++#define RTL8367C_PORT1_EEECFG_EEE_SLEEP_REQ_OFFSET 0 ++#define RTL8367C_PORT1_EEECFG_EEE_SLEEP_REQ_MASK 0x1 ++ ++#define RTL8367C_REG_PORT1_EEETXMTR 0x0039 ++ ++#define RTL8367C_REG_PORT1_EEERXMTR 0x003a ++ ++#define RTL8367C_REG_PORT1_EEEPTXMTR 0x003b ++ ++#define RTL8367C_REG_PORT1_EEEPRXMTR 0x003c ++ ++#define RTL8367C_REG_PTP_PORT1_CFG1 0x003e ++#define RTL8367C_PTP_PORT1_CFG1_OFFSET 7 ++#define RTL8367C_PTP_PORT1_CFG1_MASK 0xFF ++ ++#define RTL8367C_REG_P1_MSIC1 0x003f ++#define RTL8367C_P1_MSIC1_OFFSET 0 ++#define RTL8367C_P1_MSIC1_MASK 0x1 ++ ++#define RTL8367C_REG_PORT2_CGST_HALF_CFG 0x0040 ++#define RTL8367C_PORT2_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 ++#define RTL8367C_PORT2_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 ++#define RTL8367C_PORT2_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 ++#define RTL8367C_PORT2_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF ++ ++#define RTL8367C_REG_PKTGEN_PORT2_CTRL 0x0041 ++#define RTL8367C_PKTGEN_PORT2_CTRL_STATUS_OFFSET 15 ++#define RTL8367C_PKTGEN_PORT2_CTRL_STATUS_MASK 0x8000 ++#define RTL8367C_PKTGEN_PORT2_CTRL_PKTGEN_STS_OFFSET 13 ++#define RTL8367C_PKTGEN_PORT2_CTRL_PKTGEN_STS_MASK 0x2000 ++#define RTL8367C_PKTGEN_PORT2_CTRL_CRC_NO_ERROR_OFFSET 4 ++#define RTL8367C_PKTGEN_PORT2_CTRL_CRC_NO_ERROR_MASK 0x10 ++#define RTL8367C_PKTGEN_PORT2_CTRL_CMD_START_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT2_CTRL_CMD_START_MASK 0x1 ++ ++#define RTL8367C_REG_TX_ERR_CNT_PORT2 0x0042 ++#define RTL8367C_TX_ERR_CNT_PORT2_OFFSET 0 ++#define RTL8367C_TX_ERR_CNT_PORT2_MASK 0x7 ++ ++#define RTL8367C_REG_PKTGEN_PORT2_DA0 0x0043 ++ ++#define RTL8367C_REG_PKTGEN_PORT2_DA1 0x0044 ++ ++#define RTL8367C_REG_PKTGEN_PORT2_DA2 0x0045 ++ ++#define RTL8367C_REG_PKTGEN_PORT2_SA0 0x0046 ++ ++#define RTL8367C_REG_PKTGEN_PORT2_SA1 0x0047 ++ ++#define RTL8367C_REG_PKTGEN_PORT2_SA2 0x0048 ++ ++#define RTL8367C_REG_PKTGEN_PORT2_COUNTER0 0x0049 ++ ++#define RTL8367C_REG_PKTGEN_PORT2_COUNTER1 0x004a ++#define RTL8367C_PKTGEN_PORT2_COUNTER1_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT2_COUNTER1_MASK 0xFF ++ ++#define RTL8367C_REG_PKTGEN_PORT2_TX_LENGTH 0x004b ++#define RTL8367C_PKTGEN_PORT2_TX_LENGTH_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT2_TX_LENGTH_MASK 0x3FFF ++ ++#define RTL8367C_REG_PKTGEN_PORT2_TIMER 0x004d ++#define RTL8367C_PKTGEN_PORT2_TIMER_TIMER_OFFSET 4 ++#define RTL8367C_PKTGEN_PORT2_TIMER_TIMER_MASK 0xF0 ++#define RTL8367C_PKTGEN_PORT2_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 ++#define RTL8367C_PKTGEN_PORT2_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 ++ ++#define RTL8367C_REG_PORT2_MISC_CFG 0x004e ++#define RTL8367C_PORT2_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 ++#define RTL8367C_PORT2_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 ++#define RTL8367C_PORT2_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 ++#define RTL8367C_PORT2_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 ++#define RTL8367C_PORT2_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 ++#define RTL8367C_PORT2_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 ++#define RTL8367C_PORT2_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 ++#define RTL8367C_PORT2_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 ++#define RTL8367C_PORT2_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 ++#define RTL8367C_PORT2_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 ++#define RTL8367C_PORT2_MISC_CFG_INGRESSBW_IFG_OFFSET 10 ++#define RTL8367C_PORT2_MISC_CFG_INGRESSBW_IFG_MASK 0x400 ++#define RTL8367C_PORT2_MISC_CFG_RX_SPC_OFFSET 9 ++#define RTL8367C_PORT2_MISC_CFG_RX_SPC_MASK 0x200 ++#define RTL8367C_PORT2_MISC_CFG_CRC_SKIP_OFFSET 8 ++#define RTL8367C_PORT2_MISC_CFG_CRC_SKIP_MASK 0x100 ++#define RTL8367C_PORT2_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 ++#define RTL8367C_PORT2_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 ++#define RTL8367C_PORT2_MISC_CFG_MAC_LOOPBACK_OFFSET 6 ++#define RTL8367C_PORT2_MISC_CFG_MAC_LOOPBACK_MASK 0x40 ++#define RTL8367C_PORT2_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 ++#define RTL8367C_PORT2_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 ++#define RTL8367C_PORT2_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 ++#define RTL8367C_PORT2_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF ++ ++#define RTL8367C_REG_INGRESSBW_PORT2_RATE_CTRL0 0x004f ++ ++#define RTL8367C_REG_INGRESSBW_PORT2_RATE_CTRL1 0x0050 ++#define RTL8367C_INGRESSBW_PORT2_RATE_CTRL1_DUMMY_OFFSET 3 ++#define RTL8367C_INGRESSBW_PORT2_RATE_CTRL1_DUMMY_MASK 0xFFF8 ++#define RTL8367C_INGRESSBW_PORT2_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 ++#define RTL8367C_INGRESSBW_PORT2_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 ++ ++#define RTL8367C_REG_PORT2_FORCE_RATE0 0x0051 ++ ++#define RTL8367C_REG_PORT2_FORCE_RATE1 0x0052 ++ ++#define RTL8367C_REG_PORT2_CURENT_RATE0 0x0053 ++ ++#define RTL8367C_REG_PORT2_CURENT_RATE1 0x0054 ++ ++#define RTL8367C_REG_PORT2_PAGE_COUNTER 0x0055 ++#define RTL8367C_PORT2_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_PORT2_PAGE_COUNTER_MASK 0x7F ++ ++#define RTL8367C_REG_PAGEMETER_PORT2_CTRL0 0x0056 ++ ++#define RTL8367C_REG_PAGEMETER_PORT2_CTRL1 0x0057 ++ ++#define RTL8367C_REG_PORT2_EEECFG 0x0058 ++#define RTL8367C_PORT2_EEECFG_EEEP_ENABLE_TX_OFFSET 14 ++#define RTL8367C_PORT2_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 ++#define RTL8367C_PORT2_EEECFG_EEEP_ENABLE_RX_OFFSET 13 ++#define RTL8367C_PORT2_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 ++#define RTL8367C_PORT2_EEECFG_EEE_FORCE_OFFSET 12 ++#define RTL8367C_PORT2_EEECFG_EEE_FORCE_MASK 0x1000 ++#define RTL8367C_PORT2_EEECFG_EEE_100M_OFFSET 11 ++#define RTL8367C_PORT2_EEECFG_EEE_100M_MASK 0x800 ++#define RTL8367C_PORT2_EEECFG_EEE_GIGA_500M_OFFSET 10 ++#define RTL8367C_PORT2_EEECFG_EEE_GIGA_500M_MASK 0x400 ++#define RTL8367C_PORT2_EEECFG_EEE_TX_OFFSET 9 ++#define RTL8367C_PORT2_EEECFG_EEE_TX_MASK 0x200 ++#define RTL8367C_PORT2_EEECFG_EEE_RX_OFFSET 8 ++#define RTL8367C_PORT2_EEECFG_EEE_RX_MASK 0x100 ++#define RTL8367C_PORT2_EEECFG_EEE_DSP_RX_OFFSET 6 ++#define RTL8367C_PORT2_EEECFG_EEE_DSP_RX_MASK 0x40 ++#define RTL8367C_PORT2_EEECFG_EEE_LPI_OFFSET 5 ++#define RTL8367C_PORT2_EEECFG_EEE_LPI_MASK 0x20 ++#define RTL8367C_PORT2_EEECFG_EEE_TX_LPI_OFFSET 4 ++#define RTL8367C_PORT2_EEECFG_EEE_TX_LPI_MASK 0x10 ++#define RTL8367C_PORT2_EEECFG_EEE_RX_LPI_OFFSET 3 ++#define RTL8367C_PORT2_EEECFG_EEE_RX_LPI_MASK 0x8 ++#define RTL8367C_PORT2_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 ++#define RTL8367C_PORT2_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 ++#define RTL8367C_PORT2_EEECFG_EEE_WAKE_REQ_OFFSET 1 ++#define RTL8367C_PORT2_EEECFG_EEE_WAKE_REQ_MASK 0x2 ++#define RTL8367C_PORT2_EEECFG_EEE_SLEEP_REQ_OFFSET 0 ++#define RTL8367C_PORT2_EEECFG_EEE_SLEEP_REQ_MASK 0x1 ++ ++#define RTL8367C_REG_PORT2_EEETXMTR 0x0059 ++ ++#define RTL8367C_REG_PORT2_EEERXMTR 0x005a ++ ++#define RTL8367C_REG_PORT2_EEEPTXMTR 0x005b ++ ++#define RTL8367C_REG_PORT2_EEEPRXMTR 0x005c ++ ++#define RTL8367C_REG_PTP_PORT2_CFG1 0x005e ++#define RTL8367C_PTP_PORT2_CFG1_OFFSET 7 ++#define RTL8367C_PTP_PORT2_CFG1_MASK 0xFF ++ ++#define RTL8367C_REG_P2_MSIC1 0x005f ++#define RTL8367C_P2_MSIC1_OFFSET 0 ++#define RTL8367C_P2_MSIC1_MASK 0x1 ++ ++#define RTL8367C_REG_PORT3_CGST_HALF_CFG 0x0060 ++#define RTL8367C_PORT3_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 ++#define RTL8367C_PORT3_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 ++#define RTL8367C_PORT3_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 ++#define RTL8367C_PORT3_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF ++ ++#define RTL8367C_REG_PKTGEN_PORT3_CTRL 0x0061 ++#define RTL8367C_PKTGEN_PORT3_CTRL_STATUS_OFFSET 15 ++#define RTL8367C_PKTGEN_PORT3_CTRL_STATUS_MASK 0x8000 ++#define RTL8367C_PKTGEN_PORT3_CTRL_PKTGEN_STS_OFFSET 13 ++#define RTL8367C_PKTGEN_PORT3_CTRL_PKTGEN_STS_MASK 0x2000 ++#define RTL8367C_PKTGEN_PORT3_CTRL_CRC_NO_ERROR_OFFSET 4 ++#define RTL8367C_PKTGEN_PORT3_CTRL_CRC_NO_ERROR_MASK 0x10 ++#define RTL8367C_PKTGEN_PORT3_CTRL_CMD_START_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT3_CTRL_CMD_START_MASK 0x1 ++ ++#define RTL8367C_REG_TX_ERR_CNT_PORT3 0x0062 ++#define RTL8367C_TX_ERR_CNT_PORT3_OFFSET 0 ++#define RTL8367C_TX_ERR_CNT_PORT3_MASK 0x7 ++ ++#define RTL8367C_REG_PKTGEN_PORT3_DA0 0x0063 ++ ++#define RTL8367C_REG_PKTGEN_PORT3_DA1 0x0064 ++ ++#define RTL8367C_REG_PKTGEN_PORT3_DA2 0x0065 ++ ++#define RTL8367C_REG_PKTGEN_PORT3_SA0 0x0066 ++ ++#define RTL8367C_REG_PKTGEN_PORT3_SA1 0x0067 ++ ++#define RTL8367C_REG_PKTGEN_PORT3_SA2 0x0068 ++ ++#define RTL8367C_REG_PKTGEN_PORT3_COUNTER0 0x0069 ++ ++#define RTL8367C_REG_PKTGEN_PORT3_COUNTER1 0x006a ++#define RTL8367C_PKTGEN_PORT3_COUNTER1_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT3_COUNTER1_MASK 0xFF ++ ++#define RTL8367C_REG_PKTGEN_PORT3_TX_LENGTH 0x006b ++#define RTL8367C_PKTGEN_PORT3_TX_LENGTH_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT3_TX_LENGTH_MASK 0x3FFF ++ ++#define RTL8367C_REG_PKTGEN_PORT3_TIMER 0x006d ++#define RTL8367C_PKTGEN_PORT3_TIMER_TIMER_OFFSET 4 ++#define RTL8367C_PKTGEN_PORT3_TIMER_TIMER_MASK 0xF0 ++#define RTL8367C_PKTGEN_PORT3_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 ++#define RTL8367C_PKTGEN_PORT3_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 ++ ++#define RTL8367C_REG_PORT3_MISC_CFG 0x006e ++#define RTL8367C_PORT3_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 ++#define RTL8367C_PORT3_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 ++#define RTL8367C_PORT3_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 ++#define RTL8367C_PORT3_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 ++#define RTL8367C_PORT3_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 ++#define RTL8367C_PORT3_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 ++#define RTL8367C_PORT3_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 ++#define RTL8367C_PORT3_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 ++#define RTL8367C_PORT3_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 ++#define RTL8367C_PORT3_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 ++#define RTL8367C_PORT3_MISC_CFG_INGRESSBW_IFG_OFFSET 10 ++#define RTL8367C_PORT3_MISC_CFG_INGRESSBW_IFG_MASK 0x400 ++#define RTL8367C_PORT3_MISC_CFG_RX_SPC_OFFSET 9 ++#define RTL8367C_PORT3_MISC_CFG_RX_SPC_MASK 0x200 ++#define RTL8367C_PORT3_MISC_CFG_CRC_SKIP_OFFSET 8 ++#define RTL8367C_PORT3_MISC_CFG_CRC_SKIP_MASK 0x100 ++#define RTL8367C_PORT3_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 ++#define RTL8367C_PORT3_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 ++#define RTL8367C_PORT3_MISC_CFG_MAC_LOOPBACK_OFFSET 6 ++#define RTL8367C_PORT3_MISC_CFG_MAC_LOOPBACK_MASK 0x40 ++#define RTL8367C_PORT3_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 ++#define RTL8367C_PORT3_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 ++#define RTL8367C_PORT3_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 ++#define RTL8367C_PORT3_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF ++ ++#define RTL8367C_REG_INGRESSBW_PORT3_RATE_CTRL0 0x006f ++ ++#define RTL8367C_REG_INGRESSBW_PORT3_RATE_CTRL1 0x0070 ++#define RTL8367C_INGRESSBW_PORT3_RATE_CTRL1_DUMMY_OFFSET 3 ++#define RTL8367C_INGRESSBW_PORT3_RATE_CTRL1_DUMMY_MASK 0xFFF8 ++#define RTL8367C_INGRESSBW_PORT3_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 ++#define RTL8367C_INGRESSBW_PORT3_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 ++ ++#define RTL8367C_REG_PORT3_FORCE_RATE0 0x0071 ++ ++#define RTL8367C_REG_PORT3_FORCE_RATE1 0x0072 ++ ++#define RTL8367C_REG_PORT3_CURENT_RATE0 0x0073 ++ ++#define RTL8367C_REG_PORT3_CURENT_RATE1 0x0074 ++ ++#define RTL8367C_REG_PORT3_PAGE_COUNTER 0x0075 ++#define RTL8367C_PORT3_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_PORT3_PAGE_COUNTER_MASK 0x7F ++ ++#define RTL8367C_REG_PAGEMETER_PORT3_CTRL0 0x0076 ++ ++#define RTL8367C_REG_PAGEMETER_PORT3_CTRL1 0x0077 ++ ++#define RTL8367C_REG_PORT3_EEECFG 0x0078 ++#define RTL8367C_PORT3_EEECFG_EEEP_ENABLE_TX_OFFSET 14 ++#define RTL8367C_PORT3_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 ++#define RTL8367C_PORT3_EEECFG_EEEP_ENABLE_RX_OFFSET 13 ++#define RTL8367C_PORT3_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 ++#define RTL8367C_PORT3_EEECFG_EEE_FORCE_OFFSET 12 ++#define RTL8367C_PORT3_EEECFG_EEE_FORCE_MASK 0x1000 ++#define RTL8367C_PORT3_EEECFG_EEE_100M_OFFSET 11 ++#define RTL8367C_PORT3_EEECFG_EEE_100M_MASK 0x800 ++#define RTL8367C_PORT3_EEECFG_EEE_GIGA_500M_OFFSET 10 ++#define RTL8367C_PORT3_EEECFG_EEE_GIGA_500M_MASK 0x400 ++#define RTL8367C_PORT3_EEECFG_EEE_TX_OFFSET 9 ++#define RTL8367C_PORT3_EEECFG_EEE_TX_MASK 0x200 ++#define RTL8367C_PORT3_EEECFG_EEE_RX_OFFSET 8 ++#define RTL8367C_PORT3_EEECFG_EEE_RX_MASK 0x100 ++#define RTL8367C_PORT3_EEECFG_EEE_DSP_RX_OFFSET 6 ++#define RTL8367C_PORT3_EEECFG_EEE_DSP_RX_MASK 0x40 ++#define RTL8367C_PORT3_EEECFG_EEE_LPI_OFFSET 5 ++#define RTL8367C_PORT3_EEECFG_EEE_LPI_MASK 0x20 ++#define RTL8367C_PORT3_EEECFG_EEE_TX_LPI_OFFSET 4 ++#define RTL8367C_PORT3_EEECFG_EEE_TX_LPI_MASK 0x10 ++#define RTL8367C_PORT3_EEECFG_EEE_RX_LPI_OFFSET 3 ++#define RTL8367C_PORT3_EEECFG_EEE_RX_LPI_MASK 0x8 ++#define RTL8367C_PORT3_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 ++#define RTL8367C_PORT3_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 ++#define RTL8367C_PORT3_EEECFG_EEE_WAKE_REQ_OFFSET 1 ++#define RTL8367C_PORT3_EEECFG_EEE_WAKE_REQ_MASK 0x2 ++#define RTL8367C_PORT3_EEECFG_EEE_SLEEP_REQ_OFFSET 0 ++#define RTL8367C_PORT3_EEECFG_EEE_SLEEP_REQ_MASK 0x1 ++ ++#define RTL8367C_REG_PORT3_EEETXMTR 0x0079 ++ ++#define RTL8367C_REG_PORT3_EEERXMTR 0x007a ++ ++#define RTL8367C_REG_PORT3_EEEPTXMTR 0x007b ++ ++#define RTL8367C_REG_PORT3_EEEPRXMTR 0x007c ++ ++#define RTL8367C_REG_PTP_PORT3_CFG1 0x007e ++#define RTL8367C_PTP_PORT3_CFG1_OFFSET 7 ++#define RTL8367C_PTP_PORT3_CFG1_MASK 0xFF ++ ++#define RTL8367C_REG_P3_MSIC1 0x007f ++#define RTL8367C_P3_MSIC1_OFFSET 0 ++#define RTL8367C_P3_MSIC1_MASK 0x1 ++ ++#define RTL8367C_REG_PORT4_CGST_HALF_CFG 0x0080 ++#define RTL8367C_PORT4_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 ++#define RTL8367C_PORT4_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 ++#define RTL8367C_PORT4_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 ++#define RTL8367C_PORT4_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF ++ ++#define RTL8367C_REG_PKTGEN_PORT4_CTRL 0x0081 ++#define RTL8367C_PKTGEN_PORT4_CTRL_STATUS_OFFSET 15 ++#define RTL8367C_PKTGEN_PORT4_CTRL_STATUS_MASK 0x8000 ++#define RTL8367C_PKTGEN_PORT4_CTRL_PKTGEN_STS_OFFSET 13 ++#define RTL8367C_PKTGEN_PORT4_CTRL_PKTGEN_STS_MASK 0x2000 ++#define RTL8367C_PKTGEN_PORT4_CTRL_CRC_NO_ERROR_OFFSET 4 ++#define RTL8367C_PKTGEN_PORT4_CTRL_CRC_NO_ERROR_MASK 0x10 ++#define RTL8367C_PKTGEN_PORT4_CTRL_CMD_START_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT4_CTRL_CMD_START_MASK 0x1 ++ ++#define RTL8367C_REG_TX_ERR_CNT_PORT4 0x0082 ++#define RTL8367C_TX_ERR_CNT_PORT4_OFFSET 0 ++#define RTL8367C_TX_ERR_CNT_PORT4_MASK 0x7 ++ ++#define RTL8367C_REG_PKTGEN_PORT4_DA0 0x0083 ++ ++#define RTL8367C_REG_PKTGEN_PORT4_DA1 0x0084 ++ ++#define RTL8367C_REG_PKTGEN_PORT4_DA2 0x0085 ++ ++#define RTL8367C_REG_PKTGEN_PORT4_SA0 0x0086 ++ ++#define RTL8367C_REG_PKTGEN_PORT4_SA1 0x0087 ++ ++#define RTL8367C_REG_PKTGEN_PORT4_SA2 0x0088 ++ ++#define RTL8367C_REG_PKTGEN_PORT4_COUNTER0 0x0089 ++ ++#define RTL8367C_REG_PKTGEN_PORT4_COUNTER1 0x008a ++#define RTL8367C_PKTGEN_PORT4_COUNTER1_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT4_COUNTER1_MASK 0xFF ++ ++#define RTL8367C_REG_PKTGEN_PORT4_TX_LENGTH 0x008b ++#define RTL8367C_PKTGEN_PORT4_TX_LENGTH_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT4_TX_LENGTH_MASK 0x3FFF ++ ++#define RTL8367C_REG_PKTGEN_PORT4_TIMER 0x008d ++#define RTL8367C_PKTGEN_PORT4_TIMER_TIMER_OFFSET 4 ++#define RTL8367C_PKTGEN_PORT4_TIMER_TIMER_MASK 0xF0 ++#define RTL8367C_PKTGEN_PORT4_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 ++#define RTL8367C_PKTGEN_PORT4_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 ++ ++#define RTL8367C_REG_PORT4_MISC_CFG 0x008e ++#define RTL8367C_PORT4_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 ++#define RTL8367C_PORT4_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 ++#define RTL8367C_PORT4_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 ++#define RTL8367C_PORT4_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 ++#define RTL8367C_PORT4_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 ++#define RTL8367C_PORT4_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 ++#define RTL8367C_PORT4_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 ++#define RTL8367C_PORT4_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 ++#define RTL8367C_PORT4_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 ++#define RTL8367C_PORT4_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 ++#define RTL8367C_PORT4_MISC_CFG_INGRESSBW_IFG_OFFSET 10 ++#define RTL8367C_PORT4_MISC_CFG_INGRESSBW_IFG_MASK 0x400 ++#define RTL8367C_PORT4_MISC_CFG_RX_SPC_OFFSET 9 ++#define RTL8367C_PORT4_MISC_CFG_RX_SPC_MASK 0x200 ++#define RTL8367C_PORT4_MISC_CFG_CRC_SKIP_OFFSET 8 ++#define RTL8367C_PORT4_MISC_CFG_CRC_SKIP_MASK 0x100 ++#define RTL8367C_PORT4_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 ++#define RTL8367C_PORT4_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 ++#define RTL8367C_PORT4_MISC_CFG_MAC_LOOPBACK_OFFSET 6 ++#define RTL8367C_PORT4_MISC_CFG_MAC_LOOPBACK_MASK 0x40 ++#define RTL8367C_PORT4_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 ++#define RTL8367C_PORT4_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 ++#define RTL8367C_PORT4_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 ++#define RTL8367C_PORT4_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF ++ ++#define RTL8367C_REG_INGRESSBW_PORT4_RATE_CTRL0 0x008f ++ ++#define RTL8367C_REG_INGRESSBW_PORT4_RATE_CTRL1 0x0090 ++#define RTL8367C_INGRESSBW_PORT4_RATE_CTRL1_DUMMY_OFFSET 3 ++#define RTL8367C_INGRESSBW_PORT4_RATE_CTRL1_DUMMY_MASK 0xFFF8 ++#define RTL8367C_INGRESSBW_PORT4_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 ++#define RTL8367C_INGRESSBW_PORT4_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 ++ ++#define RTL8367C_REG_PORT4_FORCE_RATE0 0x0091 ++ ++#define RTL8367C_REG_PORT4_FORCE_RATE1 0x0092 ++ ++#define RTL8367C_REG_PORT4_CURENT_RATE0 0x0093 ++ ++#define RTL8367C_REG_PORT4_CURENT_RATE1 0x0094 ++ ++#define RTL8367C_REG_PORT4_PAGE_COUNTER 0x0095 ++#define RTL8367C_PORT4_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_PORT4_PAGE_COUNTER_MASK 0x7F ++ ++#define RTL8367C_REG_PAGEMETER_PORT4_CTRL0 0x0096 ++ ++#define RTL8367C_REG_PAGEMETER_PORT4_CTRL1 0x0097 ++ ++#define RTL8367C_REG_PORT4_EEECFG 0x0098 ++#define RTL8367C_PORT4_EEECFG_EEEP_ENABLE_TX_OFFSET 14 ++#define RTL8367C_PORT4_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 ++#define RTL8367C_PORT4_EEECFG_EEEP_ENABLE_RX_OFFSET 13 ++#define RTL8367C_PORT4_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 ++#define RTL8367C_PORT4_EEECFG_EEE_FORCE_OFFSET 12 ++#define RTL8367C_PORT4_EEECFG_EEE_FORCE_MASK 0x1000 ++#define RTL8367C_PORT4_EEECFG_EEE_100M_OFFSET 11 ++#define RTL8367C_PORT4_EEECFG_EEE_100M_MASK 0x800 ++#define RTL8367C_PORT4_EEECFG_EEE_GIGA_500M_OFFSET 10 ++#define RTL8367C_PORT4_EEECFG_EEE_GIGA_500M_MASK 0x400 ++#define RTL8367C_PORT4_EEECFG_EEE_TX_OFFSET 9 ++#define RTL8367C_PORT4_EEECFG_EEE_TX_MASK 0x200 ++#define RTL8367C_PORT4_EEECFG_EEE_RX_OFFSET 8 ++#define RTL8367C_PORT4_EEECFG_EEE_RX_MASK 0x100 ++#define RTL8367C_PORT4_EEECFG_EEE_DSP_RX_OFFSET 6 ++#define RTL8367C_PORT4_EEECFG_EEE_DSP_RX_MASK 0x40 ++#define RTL8367C_PORT4_EEECFG_EEE_LPI_OFFSET 5 ++#define RTL8367C_PORT4_EEECFG_EEE_LPI_MASK 0x20 ++#define RTL8367C_PORT4_EEECFG_EEE_TX_LPI_OFFSET 4 ++#define RTL8367C_PORT4_EEECFG_EEE_TX_LPI_MASK 0x10 ++#define RTL8367C_PORT4_EEECFG_EEE_RX_LPI_OFFSET 3 ++#define RTL8367C_PORT4_EEECFG_EEE_RX_LPI_MASK 0x8 ++#define RTL8367C_PORT4_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 ++#define RTL8367C_PORT4_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 ++#define RTL8367C_PORT4_EEECFG_EEE_WAKE_REQ_OFFSET 1 ++#define RTL8367C_PORT4_EEECFG_EEE_WAKE_REQ_MASK 0x2 ++#define RTL8367C_PORT4_EEECFG_EEE_SLEEP_REQ_OFFSET 0 ++#define RTL8367C_PORT4_EEECFG_EEE_SLEEP_REQ_MASK 0x1 ++ ++#define RTL8367C_REG_PORT4_EEETXMTR 0x0099 ++ ++#define RTL8367C_REG_PORT4_EEERXMTR 0x009a ++ ++#define RTL8367C_REG_PORT4_EEEPTXMTR 0x009b ++ ++#define RTL8367C_REG_PORT4_EEEPRXMTR 0x009c ++ ++#define RTL8367C_REG_PTP_PORT4_CFG1 0x009e ++#define RTL8367C_PTP_PORT4_CFG1_OFFSET 7 ++#define RTL8367C_PTP_PORT4_CFG1_MASK 0xFF ++ ++#define RTL8367C_REG_P4_MSIC1 0x009f ++#define RTL8367C_P4_MSIC1_OFFSET 0 ++#define RTL8367C_P4_MSIC1_MASK 0x1 ++ ++#define RTL8367C_REG_PORT5_CGST_HALF_CFG 0x00a0 ++#define RTL8367C_PORT5_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 ++#define RTL8367C_PORT5_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 ++#define RTL8367C_PORT5_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 ++#define RTL8367C_PORT5_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF ++ ++#define RTL8367C_REG_PKTGEN_PORT5_CTRL 0x00a1 ++#define RTL8367C_PKTGEN_PORT5_CTRL_STATUS_OFFSET 15 ++#define RTL8367C_PKTGEN_PORT5_CTRL_STATUS_MASK 0x8000 ++#define RTL8367C_PKTGEN_PORT5_CTRL_PKTGEN_STS_OFFSET 13 ++#define RTL8367C_PKTGEN_PORT5_CTRL_PKTGEN_STS_MASK 0x2000 ++#define RTL8367C_PKTGEN_PORT5_CTRL_CRC_NO_ERROR_OFFSET 4 ++#define RTL8367C_PKTGEN_PORT5_CTRL_CRC_NO_ERROR_MASK 0x10 ++#define RTL8367C_PKTGEN_PORT5_CTRL_CMD_START_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT5_CTRL_CMD_START_MASK 0x1 ++ ++#define RTL8367C_REG_TX_ERR_CNT_PORT5 0x00a2 ++#define RTL8367C_TX_ERR_CNT_PORT5_OFFSET 0 ++#define RTL8367C_TX_ERR_CNT_PORT5_MASK 0x7 ++ ++#define RTL8367C_REG_PKTGEN_PORT5_DA0 0x00a3 ++ ++#define RTL8367C_REG_PKTGEN_PORT5_DA1 0x00a4 ++ ++#define RTL8367C_REG_PKTGEN_PORT5_DA2 0x00a5 ++ ++#define RTL8367C_REG_PKTGEN_PORT5_SA0 0x00a6 ++ ++#define RTL8367C_REG_PKTGEN_PORT5_SA1 0x00a7 ++ ++#define RTL8367C_REG_PKTGEN_PORT5_SA2 0x00a8 ++ ++#define RTL8367C_REG_PKTGEN_PORT5_COUNTER0 0x00a9 ++ ++#define RTL8367C_REG_PKTGEN_PORT5_COUNTER1 0x00aa ++#define RTL8367C_PKTGEN_PORT5_COUNTER1_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT5_COUNTER1_MASK 0xFF ++ ++#define RTL8367C_REG_PKTGEN_PORT5_TX_LENGTH 0x00ab ++#define RTL8367C_PKTGEN_PORT5_TX_LENGTH_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT5_TX_LENGTH_MASK 0x3FFF ++ ++#define RTL8367C_REG_PKTGEN_PORT5_TIMER 0x00ad ++#define RTL8367C_PKTGEN_PORT5_TIMER_TIMER_OFFSET 4 ++#define RTL8367C_PKTGEN_PORT5_TIMER_TIMER_MASK 0xF0 ++#define RTL8367C_PKTGEN_PORT5_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 ++#define RTL8367C_PKTGEN_PORT5_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 ++ ++#define RTL8367C_REG_PORT5_MISC_CFG 0x00ae ++#define RTL8367C_PORT5_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 ++#define RTL8367C_PORT5_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 ++#define RTL8367C_PORT5_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 ++#define RTL8367C_PORT5_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 ++#define RTL8367C_PORT5_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 ++#define RTL8367C_PORT5_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 ++#define RTL8367C_PORT5_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 ++#define RTL8367C_PORT5_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 ++#define RTL8367C_PORT5_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 ++#define RTL8367C_PORT5_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 ++#define RTL8367C_PORT5_MISC_CFG_INGRESSBW_IFG_OFFSET 10 ++#define RTL8367C_PORT5_MISC_CFG_INGRESSBW_IFG_MASK 0x400 ++#define RTL8367C_PORT5_MISC_CFG_RX_SPC_OFFSET 9 ++#define RTL8367C_PORT5_MISC_CFG_RX_SPC_MASK 0x200 ++#define RTL8367C_PORT5_MISC_CFG_CRC_SKIP_OFFSET 8 ++#define RTL8367C_PORT5_MISC_CFG_CRC_SKIP_MASK 0x100 ++#define RTL8367C_PORT5_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 ++#define RTL8367C_PORT5_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 ++#define RTL8367C_PORT5_MISC_CFG_MAC_LOOPBACK_OFFSET 6 ++#define RTL8367C_PORT5_MISC_CFG_MAC_LOOPBACK_MASK 0x40 ++#define RTL8367C_PORT5_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 ++#define RTL8367C_PORT5_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 ++#define RTL8367C_PORT5_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 ++#define RTL8367C_PORT5_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF ++ ++#define RTL8367C_REG_INGRESSBW_PORT5_RATE_CTRL0 0x00af ++ ++#define RTL8367C_REG_INGRESSBW_PORT5_RATE_CTRL1 0x00b0 ++#define RTL8367C_INGRESSBW_PORT5_RATE_CTRL1_DUMMY_OFFSET 3 ++#define RTL8367C_INGRESSBW_PORT5_RATE_CTRL1_DUMMY_MASK 0xFFF8 ++#define RTL8367C_INGRESSBW_PORT5_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 ++#define RTL8367C_INGRESSBW_PORT5_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 ++ ++#define RTL8367C_REG_PORT5_FORCE_RATE0 0x00b1 ++ ++#define RTL8367C_REG_PORT5_FORCE_RATE1 0x00b2 ++ ++#define RTL8367C_REG_PORT5_CURENT_RATE0 0x00b3 ++ ++#define RTL8367C_REG_PORT5_CURENT_RATE1 0x00b4 ++ ++#define RTL8367C_REG_PORT5_PAGE_COUNTER 0x00b5 ++#define RTL8367C_PORT5_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_PORT5_PAGE_COUNTER_MASK 0x7F ++ ++#define RTL8367C_REG_PAGEMETER_PORT5_CTRL0 0x00b6 ++ ++#define RTL8367C_REG_PAGEMETER_PORT5_CTRL1 0x00b7 ++ ++#define RTL8367C_REG_PORT5_EEECFG 0x00b8 ++#define RTL8367C_PORT5_EEECFG_EEEP_ENABLE_TX_OFFSET 14 ++#define RTL8367C_PORT5_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 ++#define RTL8367C_PORT5_EEECFG_EEEP_ENABLE_RX_OFFSET 13 ++#define RTL8367C_PORT5_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 ++#define RTL8367C_PORT5_EEECFG_EEE_FORCE_OFFSET 12 ++#define RTL8367C_PORT5_EEECFG_EEE_FORCE_MASK 0x1000 ++#define RTL8367C_PORT5_EEECFG_EEE_100M_OFFSET 11 ++#define RTL8367C_PORT5_EEECFG_EEE_100M_MASK 0x800 ++#define RTL8367C_PORT5_EEECFG_EEE_GIGA_500M_OFFSET 10 ++#define RTL8367C_PORT5_EEECFG_EEE_GIGA_500M_MASK 0x400 ++#define RTL8367C_PORT5_EEECFG_EEE_TX_OFFSET 9 ++#define RTL8367C_PORT5_EEECFG_EEE_TX_MASK 0x200 ++#define RTL8367C_PORT5_EEECFG_EEE_RX_OFFSET 8 ++#define RTL8367C_PORT5_EEECFG_EEE_RX_MASK 0x100 ++#define RTL8367C_PORT5_EEECFG_EEE_DSP_RX_OFFSET 6 ++#define RTL8367C_PORT5_EEECFG_EEE_DSP_RX_MASK 0x40 ++#define RTL8367C_PORT5_EEECFG_EEE_LPI_OFFSET 5 ++#define RTL8367C_PORT5_EEECFG_EEE_LPI_MASK 0x20 ++#define RTL8367C_PORT5_EEECFG_EEE_TX_LPI_OFFSET 4 ++#define RTL8367C_PORT5_EEECFG_EEE_TX_LPI_MASK 0x10 ++#define RTL8367C_PORT5_EEECFG_EEE_RX_LPI_OFFSET 3 ++#define RTL8367C_PORT5_EEECFG_EEE_RX_LPI_MASK 0x8 ++#define RTL8367C_PORT5_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 ++#define RTL8367C_PORT5_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 ++#define RTL8367C_PORT5_EEECFG_EEE_WAKE_REQ_OFFSET 1 ++#define RTL8367C_PORT5_EEECFG_EEE_WAKE_REQ_MASK 0x2 ++#define RTL8367C_PORT5_EEECFG_EEE_SLEEP_REQ_OFFSET 0 ++#define RTL8367C_PORT5_EEECFG_EEE_SLEEP_REQ_MASK 0x1 ++ ++#define RTL8367C_REG_PORT5_EEETXMTR 0x00b9 ++ ++#define RTL8367C_REG_PORT5_EEERXMTR 0x00ba ++ ++#define RTL8367C_REG_PORT5_EEEPTXMTR 0x00bb ++ ++#define RTL8367C_REG_PORT5_EEEPRXMTR 0x00bc ++ ++#define RTL8367C_REG_PTP_PORT5_CFG1 0x00be ++#define RTL8367C_PTP_PORT5_CFG1_OFFSET 7 ++#define RTL8367C_PTP_PORT5_CFG1_MASK 0xFF ++ ++#define RTL8367C_REG_P5_MSIC1 0x00bf ++#define RTL8367C_P5_MSIC1_OFFSET 0 ++#define RTL8367C_P5_MSIC1_MASK 0x1 ++ ++#define RTL8367C_REG_PORT6_CGST_HALF_CFG 0x00c0 ++#define RTL8367C_PORT6_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 ++#define RTL8367C_PORT6_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 ++#define RTL8367C_PORT6_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 ++#define RTL8367C_PORT6_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF ++ ++#define RTL8367C_REG_PKTGEN_PORT6_CTRL 0x00c1 ++#define RTL8367C_PKTGEN_PORT6_CTRL_STATUS_OFFSET 15 ++#define RTL8367C_PKTGEN_PORT6_CTRL_STATUS_MASK 0x8000 ++#define RTL8367C_PKTGEN_PORT6_CTRL_PKTGEN_STS_OFFSET 13 ++#define RTL8367C_PKTGEN_PORT6_CTRL_PKTGEN_STS_MASK 0x2000 ++#define RTL8367C_PKTGEN_PORT6_CTRL_CRC_NO_ERROR_OFFSET 4 ++#define RTL8367C_PKTGEN_PORT6_CTRL_CRC_NO_ERROR_MASK 0x10 ++#define RTL8367C_PKTGEN_PORT6_CTRL_CMD_START_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT6_CTRL_CMD_START_MASK 0x1 ++ ++#define RTL8367C_REG_TX_ERR_CNT_PORT6 0x00c2 ++#define RTL8367C_TX_ERR_CNT_PORT6_OFFSET 0 ++#define RTL8367C_TX_ERR_CNT_PORT6_MASK 0x7 ++ ++#define RTL8367C_REG_PKTGEN_PORT6_DA0 0x00c3 ++ ++#define RTL8367C_REG_PKTGEN_PORT6_DA1 0x00c4 ++ ++#define RTL8367C_REG_PKTGEN_PORT6_DA2 0x00c5 ++ ++#define RTL8367C_REG_PKTGEN_PORT6_SA0 0x00c6 ++ ++#define RTL8367C_REG_PKTGEN_PORT6_SA1 0x00c7 ++ ++#define RTL8367C_REG_PKTGEN_PORT6_SA2 0x00c8 ++ ++#define RTL8367C_REG_PKTGEN_PORT6_COUNTER0 0x00c9 ++ ++#define RTL8367C_REG_PKTGEN_PORT6_COUNTER1 0x00ca ++#define RTL8367C_PKTGEN_PORT6_COUNTER1_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT6_COUNTER1_MASK 0xFF ++ ++#define RTL8367C_REG_PKTGEN_PORT6_TX_LENGTH 0x00cb ++#define RTL8367C_PKTGEN_PORT6_TX_LENGTH_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT6_TX_LENGTH_MASK 0x3FFF ++ ++#define RTL8367C_REG_PKTGEN_PORT6_TIMER 0x00cd ++#define RTL8367C_PKTGEN_PORT6_TIMER_TIMER_OFFSET 4 ++#define RTL8367C_PKTGEN_PORT6_TIMER_TIMER_MASK 0xF0 ++#define RTL8367C_PKTGEN_PORT6_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 ++#define RTL8367C_PKTGEN_PORT6_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 ++ ++#define RTL8367C_REG_PORT6_MISC_CFG 0x00ce ++#define RTL8367C_PORT6_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 ++#define RTL8367C_PORT6_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 ++#define RTL8367C_PORT6_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 ++#define RTL8367C_PORT6_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 ++#define RTL8367C_PORT6_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 ++#define RTL8367C_PORT6_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 ++#define RTL8367C_PORT6_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 ++#define RTL8367C_PORT6_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 ++#define RTL8367C_PORT6_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 ++#define RTL8367C_PORT6_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 ++#define RTL8367C_PORT6_MISC_CFG_INGRESSBW_IFG_OFFSET 10 ++#define RTL8367C_PORT6_MISC_CFG_INGRESSBW_IFG_MASK 0x400 ++#define RTL8367C_PORT6_MISC_CFG_RX_SPC_OFFSET 9 ++#define RTL8367C_PORT6_MISC_CFG_RX_SPC_MASK 0x200 ++#define RTL8367C_PORT6_MISC_CFG_CRC_SKIP_OFFSET 8 ++#define RTL8367C_PORT6_MISC_CFG_CRC_SKIP_MASK 0x100 ++#define RTL8367C_PORT6_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 ++#define RTL8367C_PORT6_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 ++#define RTL8367C_PORT6_MISC_CFG_MAC_LOOPBACK_OFFSET 6 ++#define RTL8367C_PORT6_MISC_CFG_MAC_LOOPBACK_MASK 0x40 ++#define RTL8367C_PORT6_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 ++#define RTL8367C_PORT6_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 ++#define RTL8367C_PORT6_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 ++#define RTL8367C_PORT6_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF ++ ++#define RTL8367C_REG_INGRESSBW_PORT6_RATE_CTRL0 0x00cf ++ ++#define RTL8367C_REG_INGRESSBW_PORT6_RATE_CTRL1 0x00d0 ++#define RTL8367C_INGRESSBW_PORT6_RATE_CTRL1_DUMMY_OFFSET 3 ++#define RTL8367C_INGRESSBW_PORT6_RATE_CTRL1_DUMMY_MASK 0xFFF8 ++#define RTL8367C_INGRESSBW_PORT6_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 ++#define RTL8367C_INGRESSBW_PORT6_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 ++ ++#define RTL8367C_REG_PORT6_FORCE_RATE0 0x00d1 ++ ++#define RTL8367C_REG_PORT6_FORCE_RATE1 0x00d2 ++ ++#define RTL8367C_REG_PORT6_CURENT_RATE0 0x00d3 ++ ++#define RTL8367C_REG_PORT6_CURENT_RATE1 0x00d4 ++ ++#define RTL8367C_REG_PORT6_PAGE_COUNTER 0x00d5 ++#define RTL8367C_PORT6_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_PORT6_PAGE_COUNTER_MASK 0x7F ++ ++#define RTL8367C_REG_PAGEMETER_PORT6_CTRL0 0x00d6 ++ ++#define RTL8367C_REG_PAGEMETER_PORT6_CTRL1 0x00d7 ++ ++#define RTL8367C_REG_PORT6_EEECFG 0x00d8 ++#define RTL8367C_PORT6_EEECFG_EEEP_ENABLE_TX_OFFSET 14 ++#define RTL8367C_PORT6_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 ++#define RTL8367C_PORT6_EEECFG_EEEP_ENABLE_RX_OFFSET 13 ++#define RTL8367C_PORT6_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 ++#define RTL8367C_PORT6_EEECFG_EEE_FORCE_OFFSET 12 ++#define RTL8367C_PORT6_EEECFG_EEE_FORCE_MASK 0x1000 ++#define RTL8367C_PORT6_EEECFG_EEE_100M_OFFSET 11 ++#define RTL8367C_PORT6_EEECFG_EEE_100M_MASK 0x800 ++#define RTL8367C_PORT6_EEECFG_EEE_GIGA_500M_OFFSET 10 ++#define RTL8367C_PORT6_EEECFG_EEE_GIGA_500M_MASK 0x400 ++#define RTL8367C_PORT6_EEECFG_EEE_TX_OFFSET 9 ++#define RTL8367C_PORT6_EEECFG_EEE_TX_MASK 0x200 ++#define RTL8367C_PORT6_EEECFG_EEE_RX_OFFSET 8 ++#define RTL8367C_PORT6_EEECFG_EEE_RX_MASK 0x100 ++#define RTL8367C_PORT6_EEECFG_EEE_DSP_RX_OFFSET 6 ++#define RTL8367C_PORT6_EEECFG_EEE_DSP_RX_MASK 0x40 ++#define RTL8367C_PORT6_EEECFG_EEE_LPI_OFFSET 5 ++#define RTL8367C_PORT6_EEECFG_EEE_LPI_MASK 0x20 ++#define RTL8367C_PORT6_EEECFG_EEE_TX_LPI_OFFSET 4 ++#define RTL8367C_PORT6_EEECFG_EEE_TX_LPI_MASK 0x10 ++#define RTL8367C_PORT6_EEECFG_EEE_RX_LPI_OFFSET 3 ++#define RTL8367C_PORT6_EEECFG_EEE_RX_LPI_MASK 0x8 ++#define RTL8367C_PORT6_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 ++#define RTL8367C_PORT6_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 ++#define RTL8367C_PORT6_EEECFG_EEE_WAKE_REQ_OFFSET 1 ++#define RTL8367C_PORT6_EEECFG_EEE_WAKE_REQ_MASK 0x2 ++#define RTL8367C_PORT6_EEECFG_EEE_SLEEP_REQ_OFFSET 0 ++#define RTL8367C_PORT6_EEECFG_EEE_SLEEP_REQ_MASK 0x1 ++ ++#define RTL8367C_REG_PORT6_EEETXMTR 0x00d9 ++ ++#define RTL8367C_REG_PORT6_EEERXMTR 0x00da ++ ++#define RTL8367C_REG_PORT6_EEEPTXMTR 0x00db ++ ++#define RTL8367C_REG_PORT6_EEEPRXMTR 0x00dc ++ ++#define RTL8367C_REG_PTP_PORT6_CFG1 0x00de ++#define RTL8367C_PTP_PORT6_CFG1_OFFSET 7 ++#define RTL8367C_PTP_PORT6_CFG1_MASK 0xFF ++ ++#define RTL8367C_REG_P6_MSIC1 0x00df ++#define RTL8367C_P6_MSIC1_OFFSET 0 ++#define RTL8367C_P6_MSIC1_MASK 0x1 ++ ++#define RTL8367C_REG_PORT7_CGST_HALF_CFG 0x00e0 ++#define RTL8367C_PORT7_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 ++#define RTL8367C_PORT7_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 ++#define RTL8367C_PORT7_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 ++#define RTL8367C_PORT7_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF ++ ++#define RTL8367C_REG_PKTGEN_PORT7_CTRL 0x00e1 ++#define RTL8367C_PKTGEN_PORT7_CTRL_STATUS_OFFSET 15 ++#define RTL8367C_PKTGEN_PORT7_CTRL_STATUS_MASK 0x8000 ++#define RTL8367C_PKTGEN_PORT7_CTRL_PKTGEN_STS_OFFSET 13 ++#define RTL8367C_PKTGEN_PORT7_CTRL_PKTGEN_STS_MASK 0x2000 ++#define RTL8367C_PKTGEN_PORT7_CTRL_CRC_NO_ERROR_OFFSET 4 ++#define RTL8367C_PKTGEN_PORT7_CTRL_CRC_NO_ERROR_MASK 0x10 ++#define RTL8367C_PKTGEN_PORT7_CTRL_CMD_START_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT7_CTRL_CMD_START_MASK 0x1 ++ ++#define RTL8367C_REG_TX_ERR_CNT_PORT7 0x00e2 ++#define RTL8367C_TX_ERR_CNT_PORT7_OFFSET 0 ++#define RTL8367C_TX_ERR_CNT_PORT7_MASK 0x7 ++ ++#define RTL8367C_REG_PKTGEN_PORT7_DA0 0x00e3 ++ ++#define RTL8367C_REG_PKTGEN_PORT7_DA1 0x00e4 ++ ++#define RTL8367C_REG_PKTGEN_PORT7_DA2 0x00e5 ++ ++#define RTL8367C_REG_PKTGEN_PORT7_SA0 0x00e6 ++ ++#define RTL8367C_REG_PKTGEN_PORT7_SA1 0x00e7 ++ ++#define RTL8367C_REG_PKTGEN_PORT7_SA2 0x00e8 ++ ++#define RTL8367C_REG_PKTGEN_PORT7_COUNTER0 0x00e9 ++ ++#define RTL8367C_REG_PKTGEN_PORT7_COUNTER1 0x00ea ++#define RTL8367C_PKTGEN_PORT7_COUNTER1_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT7_COUNTER1_MASK 0xFF ++ ++#define RTL8367C_REG_PKTGEN_PORT7_TX_LENGTH 0x00eb ++#define RTL8367C_PKTGEN_PORT7_TX_LENGTH_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT7_TX_LENGTH_MASK 0x3FFF ++ ++#define RTL8367C_REG_PKTGEN_PORT7_TIMER 0x00ed ++#define RTL8367C_PKTGEN_PORT7_TIMER_TIMER_OFFSET 4 ++#define RTL8367C_PKTGEN_PORT7_TIMER_TIMER_MASK 0xF0 ++#define RTL8367C_PKTGEN_PORT7_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 ++#define RTL8367C_PKTGEN_PORT7_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 ++ ++#define RTL8367C_REG_PORT7_MISC_CFG 0x00ee ++#define RTL8367C_PORT7_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 ++#define RTL8367C_PORT7_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 ++#define RTL8367C_PORT7_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 ++#define RTL8367C_PORT7_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 ++#define RTL8367C_PORT7_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 ++#define RTL8367C_PORT7_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 ++#define RTL8367C_PORT7_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 ++#define RTL8367C_PORT7_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 ++#define RTL8367C_PORT7_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 ++#define RTL8367C_PORT7_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 ++#define RTL8367C_PORT7_MISC_CFG_INGRESSBW_IFG_OFFSET 10 ++#define RTL8367C_PORT7_MISC_CFG_INGRESSBW_IFG_MASK 0x400 ++#define RTL8367C_PORT7_MISC_CFG_RX_SPC_OFFSET 9 ++#define RTL8367C_PORT7_MISC_CFG_RX_SPC_MASK 0x200 ++#define RTL8367C_PORT7_MISC_CFG_CRC_SKIP_OFFSET 8 ++#define RTL8367C_PORT7_MISC_CFG_CRC_SKIP_MASK 0x100 ++#define RTL8367C_PORT7_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 ++#define RTL8367C_PORT7_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 ++#define RTL8367C_PORT7_MISC_CFG_MAC_LOOPBACK_OFFSET 6 ++#define RTL8367C_PORT7_MISC_CFG_MAC_LOOPBACK_MASK 0x40 ++#define RTL8367C_PORT7_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 ++#define RTL8367C_PORT7_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 ++#define RTL8367C_PORT7_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 ++#define RTL8367C_PORT7_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF ++ ++#define RTL8367C_REG_INGRESSBW_PORT7_RATE_CTRL0 0x00ef ++ ++#define RTL8367C_REG_INGRESSBW_PORT7_RATE_CTRL1 0x00f0 ++#define RTL8367C_INGRESSBW_PORT7_RATE_CTRL1_DUMMY_OFFSET 3 ++#define RTL8367C_INGRESSBW_PORT7_RATE_CTRL1_DUMMY_MASK 0xFFF8 ++#define RTL8367C_INGRESSBW_PORT7_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 ++#define RTL8367C_INGRESSBW_PORT7_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 ++ ++#define RTL8367C_REG_PORT7_FORCE_RATE0 0x00f1 ++ ++#define RTL8367C_REG_PORT7_FORCE_RATE1 0x00f2 ++ ++#define RTL8367C_REG_PORT7_CURENT_RATE0 0x00f3 ++ ++#define RTL8367C_REG_PORT7_CURENT_RATE1 0x00f4 ++ ++#define RTL8367C_REG_PORT7_PAGE_COUNTER 0x00f5 ++#define RTL8367C_PORT7_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_PORT7_PAGE_COUNTER_MASK 0x7F ++ ++#define RTL8367C_REG_PAGEMETER_PORT7_CTRL0 0x00f6 ++ ++#define RTL8367C_REG_PAGEMETER_PORT7_CTRL1 0x00f7 ++ ++#define RTL8367C_REG_PORT7_EEECFG 0x00f8 ++#define RTL8367C_PORT7_EEECFG_EEEP_ENABLE_TX_OFFSET 14 ++#define RTL8367C_PORT7_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 ++#define RTL8367C_PORT7_EEECFG_EEEP_ENABLE_RX_OFFSET 13 ++#define RTL8367C_PORT7_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 ++#define RTL8367C_PORT7_EEECFG_EEE_FORCE_OFFSET 12 ++#define RTL8367C_PORT7_EEECFG_EEE_FORCE_MASK 0x1000 ++#define RTL8367C_PORT7_EEECFG_EEE_100M_OFFSET 11 ++#define RTL8367C_PORT7_EEECFG_EEE_100M_MASK 0x800 ++#define RTL8367C_PORT7_EEECFG_EEE_GIGA_500M_OFFSET 10 ++#define RTL8367C_PORT7_EEECFG_EEE_GIGA_500M_MASK 0x400 ++#define RTL8367C_PORT7_EEECFG_EEE_TX_OFFSET 9 ++#define RTL8367C_PORT7_EEECFG_EEE_TX_MASK 0x200 ++#define RTL8367C_PORT7_EEECFG_EEE_RX_OFFSET 8 ++#define RTL8367C_PORT7_EEECFG_EEE_RX_MASK 0x100 ++#define RTL8367C_PORT7_EEECFG_EEE_DSP_RX_OFFSET 6 ++#define RTL8367C_PORT7_EEECFG_EEE_DSP_RX_MASK 0x40 ++#define RTL8367C_PORT7_EEECFG_EEE_LPI_OFFSET 5 ++#define RTL8367C_PORT7_EEECFG_EEE_LPI_MASK 0x20 ++#define RTL8367C_PORT7_EEECFG_EEE_TX_LPI_OFFSET 4 ++#define RTL8367C_PORT7_EEECFG_EEE_TX_LPI_MASK 0x10 ++#define RTL8367C_PORT7_EEECFG_EEE_RX_LPI_OFFSET 3 ++#define RTL8367C_PORT7_EEECFG_EEE_RX_LPI_MASK 0x8 ++#define RTL8367C_PORT7_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 ++#define RTL8367C_PORT7_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 ++#define RTL8367C_PORT7_EEECFG_EEE_WAKE_REQ_OFFSET 1 ++#define RTL8367C_PORT7_EEECFG_EEE_WAKE_REQ_MASK 0x2 ++#define RTL8367C_PORT7_EEECFG_EEE_SLEEP_REQ_OFFSET 0 ++#define RTL8367C_PORT7_EEECFG_EEE_SLEEP_REQ_MASK 0x1 ++ ++#define RTL8367C_REG_PORT7_EEETXMTR 0x00f9 ++ ++#define RTL8367C_REG_PORT7_EEERXMTR 0x00fa ++ ++#define RTL8367C_REG_PORT7_EEEPTXMTR 0x00fb ++ ++#define RTL8367C_REG_PORT7_EEEPRXMTR 0x00fc ++ ++#define RTL8367C_REG_PTP_PORT7_CFG1 0x00fe ++#define RTL8367C_PTP_PORT7_CFG1_OFFSET 7 ++#define RTL8367C_PTP_PORT7_CFG1_MASK 0xFF ++ ++#define RTL8367C_REG_P7_MSIC1 0x00ff ++#define RTL8367C_P7_MSIC1_OFFSET 0 ++#define RTL8367C_P7_MSIC1_MASK 0x1 ++ ++#define RTL8367C_REG_PORT8_CGST_HALF_CFG 0x0100 ++#define RTL8367C_PORT8_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 ++#define RTL8367C_PORT8_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 ++#define RTL8367C_PORT8_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 ++#define RTL8367C_PORT8_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF ++ ++#define RTL8367C_REG_PKTGEN_PORT8_CTRL 0x0101 ++#define RTL8367C_PKTGEN_PORT8_CTRL_STATUS_OFFSET 15 ++#define RTL8367C_PKTGEN_PORT8_CTRL_STATUS_MASK 0x8000 ++#define RTL8367C_PKTGEN_PORT8_CTRL_PKTGEN_STS_OFFSET 13 ++#define RTL8367C_PKTGEN_PORT8_CTRL_PKTGEN_STS_MASK 0x2000 ++#define RTL8367C_PKTGEN_PORT8_CTRL_CRC_NO_ERROR_OFFSET 4 ++#define RTL8367C_PKTGEN_PORT8_CTRL_CRC_NO_ERROR_MASK 0x10 ++#define RTL8367C_PKTGEN_PORT8_CTRL_CMD_START_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT8_CTRL_CMD_START_MASK 0x1 ++ ++#define RTL8367C_REG_TX_ERR_CNT_PORT8 0x0102 ++#define RTL8367C_TX_ERR_CNT_PORT8_OFFSET 0 ++#define RTL8367C_TX_ERR_CNT_PORT8_MASK 0x7 ++ ++#define RTL8367C_REG_PKTGEN_PORT8_DA0 0x0103 ++ ++#define RTL8367C_REG_PKTGEN_PORT8_DA1 0x0104 ++ ++#define RTL8367C_REG_PKTGEN_PORT8_DA2 0x0105 ++ ++#define RTL8367C_REG_PKTGEN_PORT8_SA0 0x0106 ++ ++#define RTL8367C_REG_PKTGEN_PORT8_SA1 0x0107 ++ ++#define RTL8367C_REG_PKTGEN_PORT8_SA2 0x0108 ++ ++#define RTL8367C_REG_PKTGEN_PORT8_COUNTER0 0x0109 ++ ++#define RTL8367C_REG_PKTGEN_PORT8_COUNTER1 0x010a ++#define RTL8367C_PKTGEN_PORT8_COUNTER1_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT8_COUNTER1_MASK 0xFF ++ ++#define RTL8367C_REG_PKTGEN_PORT8_TX_LENGTH 0x010b ++#define RTL8367C_PKTGEN_PORT8_TX_LENGTH_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT8_TX_LENGTH_MASK 0x3FFF ++ ++#define RTL8367C_REG_PKTGEN_PORT8_TIMER 0x010d ++#define RTL8367C_PKTGEN_PORT8_TIMER_TIMER_OFFSET 4 ++#define RTL8367C_PKTGEN_PORT8_TIMER_TIMER_MASK 0xF0 ++#define RTL8367C_PKTGEN_PORT8_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 ++#define RTL8367C_PKTGEN_PORT8_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 ++ ++#define RTL8367C_REG_PORT8_MISC_CFG 0x010e ++#define RTL8367C_PORT8_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 ++#define RTL8367C_PORT8_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 ++#define RTL8367C_PORT8_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 ++#define RTL8367C_PORT8_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 ++#define RTL8367C_PORT8_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 ++#define RTL8367C_PORT8_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 ++#define RTL8367C_PORT8_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 ++#define RTL8367C_PORT8_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 ++#define RTL8367C_PORT8_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 ++#define RTL8367C_PORT8_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 ++#define RTL8367C_PORT8_MISC_CFG_INGRESSBW_IFG_OFFSET 10 ++#define RTL8367C_PORT8_MISC_CFG_INGRESSBW_IFG_MASK 0x400 ++#define RTL8367C_PORT8_MISC_CFG_RX_SPC_OFFSET 9 ++#define RTL8367C_PORT8_MISC_CFG_RX_SPC_MASK 0x200 ++#define RTL8367C_PORT8_MISC_CFG_CRC_SKIP_OFFSET 8 ++#define RTL8367C_PORT8_MISC_CFG_CRC_SKIP_MASK 0x100 ++#define RTL8367C_PORT8_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 ++#define RTL8367C_PORT8_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 ++#define RTL8367C_PORT8_MISC_CFG_MAC_LOOPBACK_OFFSET 6 ++#define RTL8367C_PORT8_MISC_CFG_MAC_LOOPBACK_MASK 0x40 ++#define RTL8367C_PORT8_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 ++#define RTL8367C_PORT8_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 ++#define RTL8367C_PORT8_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 ++#define RTL8367C_PORT8_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF ++ ++#define RTL8367C_REG_INGRESSBW_PORT8_RATE_CTRL0 0x010f ++ ++#define RTL8367C_REG_INGRESSBW_PORT8_RATE_CTRL1 0x0110 ++#define RTL8367C_INGRESSBW_PORT8_RATE_CTRL1_DUMMY_OFFSET 3 ++#define RTL8367C_INGRESSBW_PORT8_RATE_CTRL1_DUMMY_MASK 0xFFF8 ++#define RTL8367C_INGRESSBW_PORT8_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 ++#define RTL8367C_INGRESSBW_PORT8_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 ++ ++#define RTL8367C_REG_PORT8_FORCE_RATE0 0x0111 ++ ++#define RTL8367C_REG_PORT8_FORCE_RATE1 0x0112 ++ ++#define RTL8367C_REG_PORT8_CURENT_RATE0 0x0113 ++ ++#define RTL8367C_REG_PORT8_CURENT_RATE1 0x0114 ++ ++#define RTL8367C_REG_PORT8_PAGE_COUNTER 0x0115 ++#define RTL8367C_PORT8_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_PORT8_PAGE_COUNTER_MASK 0x7F ++ ++#define RTL8367C_REG_PAGEMETER_PORT8_CTRL0 0x0116 ++ ++#define RTL8367C_REG_PAGEMETER_PORT8_CTRL1 0x0117 ++ ++#define RTL8367C_REG_PORT8_EEECFG 0x0118 ++#define RTL8367C_PORT8_EEECFG_EEEP_ENABLE_TX_OFFSET 14 ++#define RTL8367C_PORT8_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 ++#define RTL8367C_PORT8_EEECFG_EEEP_ENABLE_RX_OFFSET 13 ++#define RTL8367C_PORT8_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 ++#define RTL8367C_PORT8_EEECFG_EEE_FORCE_OFFSET 12 ++#define RTL8367C_PORT8_EEECFG_EEE_FORCE_MASK 0x1000 ++#define RTL8367C_PORT8_EEECFG_EEE_100M_OFFSET 11 ++#define RTL8367C_PORT8_EEECFG_EEE_100M_MASK 0x800 ++#define RTL8367C_PORT8_EEECFG_EEE_GIGA_500M_OFFSET 10 ++#define RTL8367C_PORT8_EEECFG_EEE_GIGA_500M_MASK 0x400 ++#define RTL8367C_PORT8_EEECFG_EEE_TX_OFFSET 9 ++#define RTL8367C_PORT8_EEECFG_EEE_TX_MASK 0x200 ++#define RTL8367C_PORT8_EEECFG_EEE_RX_OFFSET 8 ++#define RTL8367C_PORT8_EEECFG_EEE_RX_MASK 0x100 ++#define RTL8367C_PORT8_EEECFG_EEE_DSP_RX_OFFSET 6 ++#define RTL8367C_PORT8_EEECFG_EEE_DSP_RX_MASK 0x40 ++#define RTL8367C_PORT8_EEECFG_EEE_LPI_OFFSET 5 ++#define RTL8367C_PORT8_EEECFG_EEE_LPI_MASK 0x20 ++#define RTL8367C_PORT8_EEECFG_EEE_TX_LPI_OFFSET 4 ++#define RTL8367C_PORT8_EEECFG_EEE_TX_LPI_MASK 0x10 ++#define RTL8367C_PORT8_EEECFG_EEE_RX_LPI_OFFSET 3 ++#define RTL8367C_PORT8_EEECFG_EEE_RX_LPI_MASK 0x8 ++#define RTL8367C_PORT8_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 ++#define RTL8367C_PORT8_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 ++#define RTL8367C_PORT8_EEECFG_EEE_WAKE_REQ_OFFSET 1 ++#define RTL8367C_PORT8_EEECFG_EEE_WAKE_REQ_MASK 0x2 ++#define RTL8367C_PORT8_EEECFG_EEE_SLEEP_REQ_OFFSET 0 ++#define RTL8367C_PORT8_EEECFG_EEE_SLEEP_REQ_MASK 0x1 ++ ++#define RTL8367C_REG_PORT8_EEETXMTR 0x0119 ++ ++#define RTL8367C_REG_PORT8_EEERXMTR 0x011a ++ ++#define RTL8367C_REG_PORT8_EEEPTXMTR 0x011b ++ ++#define RTL8367C_REG_PORT8_EEEPRXMTR 0x011c ++ ++#define RTL8367C_REG_PTP_PORT8_CFG1 0x011e ++#define RTL8367C_PTP_PORT8_CFG1_OFFSET 7 ++#define RTL8367C_PTP_PORT8_CFG1_MASK 0xFF ++ ++#define RTL8367C_REG_P8_MSIC1 0x011f ++#define RTL8367C_P8_MSIC1_OFFSET 0 ++#define RTL8367C_P8_MSIC1_MASK 0x1 ++ ++#define RTL8367C_REG_PORT9_CGST_HALF_CFG 0x0120 ++#define RTL8367C_PORT9_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 ++#define RTL8367C_PORT9_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 ++#define RTL8367C_PORT9_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 ++#define RTL8367C_PORT9_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF ++ ++#define RTL8367C_REG_PKTGEN_PORT9_CTRL 0x0121 ++#define RTL8367C_PKTGEN_PORT9_CTRL_STATUS_OFFSET 15 ++#define RTL8367C_PKTGEN_PORT9_CTRL_STATUS_MASK 0x8000 ++#define RTL8367C_PKTGEN_PORT9_CTRL_PKTGEN_STS_OFFSET 13 ++#define RTL8367C_PKTGEN_PORT9_CTRL_PKTGEN_STS_MASK 0x2000 ++#define RTL8367C_PKTGEN_PORT9_CTRL_CRC_NO_ERROR_OFFSET 4 ++#define RTL8367C_PKTGEN_PORT9_CTRL_CRC_NO_ERROR_MASK 0x10 ++#define RTL8367C_PKTGEN_PORT9_CTRL_CMD_START_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT9_CTRL_CMD_START_MASK 0x1 ++ ++#define RTL8367C_REG_TX_ERR_CNT_PORT9 0x0122 ++#define RTL8367C_TX_ERR_CNT_PORT9_OFFSET 0 ++#define RTL8367C_TX_ERR_CNT_PORT9_MASK 0x7 ++ ++#define RTL8367C_REG_PKTGEN_PORT9_DA0 0x0123 ++ ++#define RTL8367C_REG_PKTGEN_PORT9_DA1 0x0124 ++ ++#define RTL8367C_REG_PKTGEN_PORT9_DA2 0x0125 ++ ++#define RTL8367C_REG_PKTGEN_PORT9_SA0 0x0126 ++ ++#define RTL8367C_REG_PKTGEN_PORT9_SA1 0x0127 ++ ++#define RTL8367C_REG_PKTGEN_PORT9_SA2 0x0128 ++ ++#define RTL8367C_REG_PKTGEN_PORT9_COUNTER0 0x0129 ++ ++#define RTL8367C_REG_PKTGEN_PORT9_COUNTER1 0x012a ++#define RTL8367C_PKTGEN_PORT9_COUNTER1_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT9_COUNTER1_MASK 0xFF ++ ++#define RTL8367C_REG_PKTGEN_PORT9_TX_LENGTH 0x012b ++#define RTL8367C_PKTGEN_PORT9_TX_LENGTH_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT9_TX_LENGTH_MASK 0x3FFF ++ ++#define RTL8367C_REG_PKTGEN_PORT9_TIMER 0x012d ++#define RTL8367C_PKTGEN_PORT9_TIMER_TIMER_OFFSET 4 ++#define RTL8367C_PKTGEN_PORT9_TIMER_TIMER_MASK 0xF0 ++#define RTL8367C_PKTGEN_PORT9_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 ++#define RTL8367C_PKTGEN_PORT9_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 ++ ++#define RTL8367C_REG_PORT9_MISC_CFG 0x012e ++#define RTL8367C_PORT9_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 ++#define RTL8367C_PORT9_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 ++#define RTL8367C_PORT9_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 ++#define RTL8367C_PORT9_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 ++#define RTL8367C_PORT9_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 ++#define RTL8367C_PORT9_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 ++#define RTL8367C_PORT9_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 ++#define RTL8367C_PORT9_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 ++#define RTL8367C_PORT9_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 ++#define RTL8367C_PORT9_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 ++#define RTL8367C_PORT9_MISC_CFG_INGRESSBW_IFG_OFFSET 10 ++#define RTL8367C_PORT9_MISC_CFG_INGRESSBW_IFG_MASK 0x400 ++#define RTL8367C_PORT9_MISC_CFG_RX_SPC_OFFSET 9 ++#define RTL8367C_PORT9_MISC_CFG_RX_SPC_MASK 0x200 ++#define RTL8367C_PORT9_MISC_CFG_CRC_SKIP_OFFSET 8 ++#define RTL8367C_PORT9_MISC_CFG_CRC_SKIP_MASK 0x100 ++#define RTL8367C_PORT9_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 ++#define RTL8367C_PORT9_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 ++#define RTL8367C_PORT9_MISC_CFG_MAC_LOOPBACK_OFFSET 6 ++#define RTL8367C_PORT9_MISC_CFG_MAC_LOOPBACK_MASK 0x40 ++#define RTL8367C_PORT9_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 ++#define RTL8367C_PORT9_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 ++#define RTL8367C_PORT9_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 ++#define RTL8367C_PORT9_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF ++ ++#define RTL8367C_REG_INGRESSBW_PORT9_RATE_CTRL0 0x012f ++ ++#define RTL8367C_REG_INGRESSBW_PORT9_RATE_CTRL1 0x0130 ++#define RTL8367C_INGRESSBW_PORT9_RATE_CTRL1_DUMMY_OFFSET 3 ++#define RTL8367C_INGRESSBW_PORT9_RATE_CTRL1_DUMMY_MASK 0xFFF8 ++#define RTL8367C_INGRESSBW_PORT9_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 ++#define RTL8367C_INGRESSBW_PORT9_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 ++ ++#define RTL8367C_REG_PORT9_FORCE_RATE0 0x0131 ++ ++#define RTL8367C_REG_PORT9_FORCE_RATE1 0x0132 ++ ++#define RTL8367C_REG_PORT9_CURENT_RATE0 0x0133 ++ ++#define RTL8367C_REG_PORT9_CURENT_RATE1 0x0134 ++ ++#define RTL8367C_REG_PORT9_PAGE_COUNTER 0x0135 ++#define RTL8367C_PORT9_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_PORT9_PAGE_COUNTER_MASK 0x7F ++ ++#define RTL8367C_REG_PAGEMETER_PORT9_CTRL0 0x0136 ++ ++#define RTL8367C_REG_PAGEMETER_PORT9_CTRL1 0x0137 ++ ++#define RTL8367C_REG_PORT9_EEECFG 0x0138 ++#define RTL8367C_PORT9_EEECFG_EEEP_ENABLE_TX_OFFSET 14 ++#define RTL8367C_PORT9_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 ++#define RTL8367C_PORT9_EEECFG_EEEP_ENABLE_RX_OFFSET 13 ++#define RTL8367C_PORT9_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 ++#define RTL8367C_PORT9_EEECFG_EEE_FORCE_OFFSET 12 ++#define RTL8367C_PORT9_EEECFG_EEE_FORCE_MASK 0x1000 ++#define RTL8367C_PORT9_EEECFG_EEE_100M_OFFSET 11 ++#define RTL8367C_PORT9_EEECFG_EEE_100M_MASK 0x800 ++#define RTL8367C_PORT9_EEECFG_EEE_GIGA_500M_OFFSET 10 ++#define RTL8367C_PORT9_EEECFG_EEE_GIGA_500M_MASK 0x400 ++#define RTL8367C_PORT9_EEECFG_EEE_TX_OFFSET 9 ++#define RTL8367C_PORT9_EEECFG_EEE_TX_MASK 0x200 ++#define RTL8367C_PORT9_EEECFG_EEE_RX_OFFSET 8 ++#define RTL8367C_PORT9_EEECFG_EEE_RX_MASK 0x100 ++#define RTL8367C_PORT9_EEECFG_EEE_DSP_RX_OFFSET 6 ++#define RTL8367C_PORT9_EEECFG_EEE_DSP_RX_MASK 0x40 ++#define RTL8367C_PORT9_EEECFG_EEE_LPI_OFFSET 5 ++#define RTL8367C_PORT9_EEECFG_EEE_LPI_MASK 0x20 ++#define RTL8367C_PORT9_EEECFG_EEE_TX_LPI_OFFSET 4 ++#define RTL8367C_PORT9_EEECFG_EEE_TX_LPI_MASK 0x10 ++#define RTL8367C_PORT9_EEECFG_EEE_RX_LPI_OFFSET 3 ++#define RTL8367C_PORT9_EEECFG_EEE_RX_LPI_MASK 0x8 ++#define RTL8367C_PORT9_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 ++#define RTL8367C_PORT9_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 ++#define RTL8367C_PORT9_EEECFG_EEE_WAKE_REQ_OFFSET 1 ++#define RTL8367C_PORT9_EEECFG_EEE_WAKE_REQ_MASK 0x2 ++#define RTL8367C_PORT9_EEECFG_EEE_SLEEP_REQ_OFFSET 0 ++#define RTL8367C_PORT9_EEECFG_EEE_SLEEP_REQ_MASK 0x1 ++ ++#define RTL8367C_REG_PORT9_EEETXMTR 0x0139 ++ ++#define RTL8367C_REG_PORT9_EEERXMTR 0x013a ++ ++#define RTL8367C_REG_PORT9_EEEPTXMTR 0x013b ++ ++#define RTL8367C_REG_PORT9_EEEPRXMTR 0x013c ++ ++#define RTL8367C_REG_PTP_PORT9_CFG1 0x013e ++#define RTL8367C_PTP_PORT9_CFG1_OFFSET 7 ++#define RTL8367C_PTP_PORT9_CFG1_MASK 0xFF ++ ++#define RTL8367C_REG_P9_MSIC1 0x013f ++#define RTL8367C_P9_MSIC1_OFFSET 0 ++#define RTL8367C_P9_MSIC1_MASK 0x1 ++ ++#define RTL8367C_REG_PORT10_CGST_HALF_CFG 0x0140 ++#define RTL8367C_PORT10_CGST_HALF_CFG_CONGESTION_TIME_OFFSET 4 ++#define RTL8367C_PORT10_CGST_HALF_CFG_CONGESTION_TIME_MASK 0xF0 ++#define RTL8367C_PORT10_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 ++#define RTL8367C_PORT10_CGST_HALF_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF ++ ++#define RTL8367C_REG_PKTGEN_PORT10_CTRL 0x0141 ++#define RTL8367C_PKTGEN_PORT10_CTRL_STATUS_OFFSET 15 ++#define RTL8367C_PKTGEN_PORT10_CTRL_STATUS_MASK 0x8000 ++#define RTL8367C_PKTGEN_PORT10_CTRL_PKTGEN_STS_OFFSET 13 ++#define RTL8367C_PKTGEN_PORT10_CTRL_PKTGEN_STS_MASK 0x2000 ++#define RTL8367C_PKTGEN_PORT10_CTRL_CRC_NO_ERROR_OFFSET 4 ++#define RTL8367C_PKTGEN_PORT10_CTRL_CRC_NO_ERROR_MASK 0x10 ++#define RTL8367C_PKTGEN_PORT10_CTRL_CMD_START_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT10_CTRL_CMD_START_MASK 0x1 ++ ++#define RTL8367C_REG_TX_ERR_CNT_PORT10 0x0142 ++#define RTL8367C_TX_ERR_CNT_PORT10_OFFSET 0 ++#define RTL8367C_TX_ERR_CNT_PORT10_MASK 0x7 ++ ++#define RTL8367C_REG_PKTGEN_PORT10_DA0 0x0143 ++ ++#define RTL8367C_REG_PKTGEN_PORT10_DA1 0x0144 ++ ++#define RTL8367C_REG_PKTGEN_PORT10_DA2 0x0145 ++ ++#define RTL8367C_REG_PKTGEN_PORT10_SA0 0x0146 ++ ++#define RTL8367C_REG_PKTGEN_PORT10_SA1 0x0147 ++ ++#define RTL8367C_REG_PKTGEN_PORT10_SA2 0x0148 ++ ++#define RTL8367C_REG_PKTGEN_PORT10_COUNTER0 0x0149 ++ ++#define RTL8367C_REG_PKTGEN_PORT10_COUNTER1 0x014a ++#define RTL8367C_PKTGEN_PORT10_COUNTER1_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT10_COUNTER1_MASK 0xFF ++ ++#define RTL8367C_REG_PKTGEN_PORT10_TX_LENGTH 0x014b ++#define RTL8367C_PKTGEN_PORT10_TX_LENGTH_OFFSET 0 ++#define RTL8367C_PKTGEN_PORT10_TX_LENGTH_MASK 0x3FFF ++ ++#define RTL8367C_REG_PKTGEN_PORT10_TIMER 0x014d ++#define RTL8367C_PKTGEN_PORT10_TIMER_TIMER_OFFSET 4 ++#define RTL8367C_PKTGEN_PORT10_TIMER_TIMER_MASK 0xF0 ++#define RTL8367C_PKTGEN_PORT10_TIMER_RX_DMA_ERR_FLAG_OFFSET 3 ++#define RTL8367C_PKTGEN_PORT10_TIMER_RX_DMA_ERR_FLAG_MASK 0x8 ++ ++#define RTL8367C_REG_PORT10_MISC_CFG 0x014e ++#define RTL8367C_PORT10_MISC_CFG_SMALL_TAG_IPG_OFFSET 15 ++#define RTL8367C_PORT10_MISC_CFG_SMALL_TAG_IPG_MASK 0x8000 ++#define RTL8367C_PORT10_MISC_CFG_TX_ITFSP_MODE_OFFSET 14 ++#define RTL8367C_PORT10_MISC_CFG_TX_ITFSP_MODE_MASK 0x4000 ++#define RTL8367C_PORT10_MISC_CFG_FLOWCTRL_INDEP_OFFSET 13 ++#define RTL8367C_PORT10_MISC_CFG_FLOWCTRL_INDEP_MASK 0x2000 ++#define RTL8367C_PORT10_MISC_CFG_DOT1Q_REMARK_ENABLE_OFFSET 12 ++#define RTL8367C_PORT10_MISC_CFG_DOT1Q_REMARK_ENABLE_MASK 0x1000 ++#define RTL8367C_PORT10_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET 11 ++#define RTL8367C_PORT10_MISC_CFG_INGRESSBW_FLOWCTRL_MASK 0x800 ++#define RTL8367C_PORT10_MISC_CFG_INGRESSBW_IFG_OFFSET 10 ++#define RTL8367C_PORT10_MISC_CFG_INGRESSBW_IFG_MASK 0x400 ++#define RTL8367C_PORT10_MISC_CFG_RX_SPC_OFFSET 9 ++#define RTL8367C_PORT10_MISC_CFG_RX_SPC_MASK 0x200 ++#define RTL8367C_PORT10_MISC_CFG_CRC_SKIP_OFFSET 8 ++#define RTL8367C_PORT10_MISC_CFG_CRC_SKIP_MASK 0x100 ++#define RTL8367C_PORT10_MISC_CFG_PKTGEN_TX_FIRST_OFFSET 7 ++#define RTL8367C_PORT10_MISC_CFG_PKTGEN_TX_FIRST_MASK 0x80 ++#define RTL8367C_PORT10_MISC_CFG_MAC_LOOPBACK_OFFSET 6 ++#define RTL8367C_PORT10_MISC_CFG_MAC_LOOPBACK_MASK 0x40 ++#define RTL8367C_PORT10_MISC_CFG_VLAN_EGRESS_MODE_OFFSET 4 ++#define RTL8367C_PORT10_MISC_CFG_VLAN_EGRESS_MODE_MASK 0x30 ++#define RTL8367C_PORT10_MISC_CFG_CONGESTION_SUSTAIN_TIME_OFFSET 0 ++#define RTL8367C_PORT10_MISC_CFG_CONGESTION_SUSTAIN_TIME_MASK 0xF ++ ++#define RTL8367C_REG_INGRESSBW_PORT10_RATE_CTRL0 0x014f ++ ++#define RTL8367C_REG_INGRESSBW_PORT10_RATE_CTRL1 0x0150 ++#define RTL8367C_INGRESSBW_PORT10_RATE_CTRL1_DUMMY_OFFSET 3 ++#define RTL8367C_INGRESSBW_PORT10_RATE_CTRL1_DUMMY_MASK 0xFFF8 ++#define RTL8367C_INGRESSBW_PORT10_RATE_CTRL1_INGRESSBW_RATE16_OFFSET 0 ++#define RTL8367C_INGRESSBW_PORT10_RATE_CTRL1_INGRESSBW_RATE16_MASK 0x7 ++ ++#define RTL8367C_REG_PORT10_FORCE_RATE0 0x0151 ++ ++#define RTL8367C_REG_PORT10_FORCE_RATE1 0x0152 ++ ++#define RTL8367C_REG_PORT10_CURENT_RATE0 0x0153 ++ ++#define RTL8367C_REG_PORT10_CURENT_RATE1 0x0154 ++ ++#define RTL8367C_REG_PORT10_PAGE_COUNTER 0x0155 ++#define RTL8367C_PORT10_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_PORT10_PAGE_COUNTER_MASK 0x7F ++ ++#define RTL8367C_REG_PAGEMETER_PORT10_CTRL0 0x0156 ++ ++#define RTL8367C_REG_PAGEMETER_PORT10_CTRL1 0x0157 ++ ++#define RTL8367C_REG_PORT10_EEECFG 0x0158 ++#define RTL8367C_PORT10_EEECFG_EEEP_ENABLE_TX_OFFSET 14 ++#define RTL8367C_PORT10_EEECFG_EEEP_ENABLE_TX_MASK 0x4000 ++#define RTL8367C_PORT10_EEECFG_EEEP_ENABLE_RX_OFFSET 13 ++#define RTL8367C_PORT10_EEECFG_EEEP_ENABLE_RX_MASK 0x2000 ++#define RTL8367C_PORT10_EEECFG_EEE_FORCE_OFFSET 12 ++#define RTL8367C_PORT10_EEECFG_EEE_FORCE_MASK 0x1000 ++#define RTL8367C_PORT10_EEECFG_EEE_100M_OFFSET 11 ++#define RTL8367C_PORT10_EEECFG_EEE_100M_MASK 0x800 ++#define RTL8367C_PORT10_EEECFG_EEE_GIGA_500M_OFFSET 10 ++#define RTL8367C_PORT10_EEECFG_EEE_GIGA_500M_MASK 0x400 ++#define RTL8367C_PORT10_EEECFG_EEE_TX_OFFSET 9 ++#define RTL8367C_PORT10_EEECFG_EEE_TX_MASK 0x200 ++#define RTL8367C_PORT10_EEECFG_EEE_RX_OFFSET 8 ++#define RTL8367C_PORT10_EEECFG_EEE_RX_MASK 0x100 ++#define RTL8367C_PORT10_EEECFG_EEE_DSP_RX_OFFSET 6 ++#define RTL8367C_PORT10_EEECFG_EEE_DSP_RX_MASK 0x40 ++#define RTL8367C_PORT10_EEECFG_EEE_LPI_OFFSET 5 ++#define RTL8367C_PORT10_EEECFG_EEE_LPI_MASK 0x20 ++#define RTL8367C_PORT10_EEECFG_EEE_TX_LPI_OFFSET 4 ++#define RTL8367C_PORT10_EEECFG_EEE_TX_LPI_MASK 0x10 ++#define RTL8367C_PORT10_EEECFG_EEE_RX_LPI_OFFSET 3 ++#define RTL8367C_PORT10_EEECFG_EEE_RX_LPI_MASK 0x8 ++#define RTL8367C_PORT10_EEECFG_EEE_PAUSE_INDICATOR_OFFSET 2 ++#define RTL8367C_PORT10_EEECFG_EEE_PAUSE_INDICATOR_MASK 0x4 ++#define RTL8367C_PORT10_EEECFG_EEE_WAKE_REQ_OFFSET 1 ++#define RTL8367C_PORT10_EEECFG_EEE_WAKE_REQ_MASK 0x2 ++#define RTL8367C_PORT10_EEECFG_EEE_SLEEP_REQ_OFFSET 0 ++#define RTL8367C_PORT10_EEECFG_EEE_SLEEP_REQ_MASK 0x1 ++ ++#define RTL8367C_REG_PORT10_EEETXMTR 0x0159 ++ ++#define RTL8367C_REG_PORT10_EEERXMTR 0x015a ++ ++#define RTL8367C_REG_PORT10_EEEPTXMTR 0x015b ++ ++#define RTL8367C_REG_PORT10_EEEPRXMTR 0x015c ++ ++#define RTL8367C_REG_PTP_PORT10_CFG1 0x015e ++#define RTL8367C_PTP_PORT10_CFG1_OFFSET 7 ++#define RTL8367C_PTP_PORT10_CFG1_MASK 0xFF ++ ++#define RTL8367C_REG_P10_MSIC1 0x015f ++#define RTL8367C_P10_MSIC1_OFFSET 0 ++#define RTL8367C_P10_MSIC1_MASK 0x1 ++ ++/* (16'h0200)outq_reg */ ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE0_DROP_ON 0x0200 ++#define RTL8367C_FLOWCTRL_QUEUE0_DROP_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE0_DROP_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE1_DROP_ON 0x0201 ++#define RTL8367C_FLOWCTRL_QUEUE1_DROP_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE1_DROP_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE2_DROP_ON 0x0202 ++#define RTL8367C_FLOWCTRL_QUEUE2_DROP_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE2_DROP_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE3_DROP_ON 0x0203 ++#define RTL8367C_FLOWCTRL_QUEUE3_DROP_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE3_DROP_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE4_DROP_ON 0x0204 ++#define RTL8367C_FLOWCTRL_QUEUE4_DROP_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE4_DROP_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE5_DROP_ON 0x0205 ++#define RTL8367C_FLOWCTRL_QUEUE5_DROP_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE5_DROP_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE6_DROP_ON 0x0206 ++#define RTL8367C_FLOWCTRL_QUEUE6_DROP_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE6_DROP_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE7_DROP_ON 0x0207 ++#define RTL8367C_FLOWCTRL_QUEUE7_DROP_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE7_DROP_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT0_DROP_ON 0x0208 ++#define RTL8367C_FLOWCTRL_PORT0_DROP_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT0_DROP_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT1_DROP_ON 0x0209 ++#define RTL8367C_FLOWCTRL_PORT1_DROP_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT1_DROP_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT2_DROP_ON 0x020a ++#define RTL8367C_FLOWCTRL_PORT2_DROP_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT2_DROP_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT3_DROP_ON 0x020b ++#define RTL8367C_FLOWCTRL_PORT3_DROP_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT3_DROP_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT4_DROP_ON 0x020c ++#define RTL8367C_FLOWCTRL_PORT4_DROP_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT4_DROP_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT5_DROP_ON 0x020d ++#define RTL8367C_FLOWCTRL_PORT5_DROP_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT5_DROP_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT6_DROP_ON 0x020e ++#define RTL8367C_FLOWCTRL_PORT6_DROP_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT6_DROP_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT7_DROP_ON 0x020f ++#define RTL8367C_FLOWCTRL_PORT7_DROP_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT7_DROP_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT8_DROP_ON 0x0210 ++#define RTL8367C_FLOWCTRL_PORT8_DROP_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT8_DROP_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT9_DROP_ON 0x0211 ++#define RTL8367C_FLOWCTRL_PORT9_DROP_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT9_DROP_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT10_DROP_ON 0x0212 ++#define RTL8367C_FLOWCTRL_PORT10_DROP_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT10_DROP_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT_GAP 0x0218 ++#define RTL8367C_FLOWCTRL_PORT_GAP_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT_GAP_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE_GAP 0x0219 ++#define RTL8367C_FLOWCTRL_QUEUE_GAP_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE_GAP_MASK 0x7FF ++ ++#define RTL8367C_REG_PORT_QEMPTY 0x022d ++#define RTL8367C_PORT_QEMPTY_OFFSET 0 ++#define RTL8367C_PORT_QEMPTY_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_DEBUG_CTRL0 0x022e ++#define RTL8367C_FLOWCTRL_DEBUG_CTRL0_OFFSET 0 ++#define RTL8367C_FLOWCTRL_DEBUG_CTRL0_MASK 0xF ++ ++#define RTL8367C_REG_FLOWCTRL_DEBUG_CTRL1 0x022f ++#define RTL8367C_TOTAL_OFFSET 9 ++#define RTL8367C_TOTAL_MASK 0x200 ++#define RTL8367C_PORT_MAX_OFFSET 8 ++#define RTL8367C_PORT_MAX_MASK 0x100 ++#define RTL8367C_QMAX_MASK_OFFSET 0 ++#define RTL8367C_QMAX_MASK_MASK 0xFF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE0_PAGE_COUNT 0x0230 ++#define RTL8367C_FLOWCTRL_QUEUE0_PAGE_COUNT_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE0_PAGE_COUNT_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE1_PAGE_COUNT 0x0231 ++#define RTL8367C_FLOWCTRL_QUEUE1_PAGE_COUNT_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE1_PAGE_COUNT_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE2_PAGE_COUNT 0x0232 ++#define RTL8367C_FLOWCTRL_QUEUE2_PAGE_COUNT_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE2_PAGE_COUNT_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE3_PAGE_COUNT 0x0233 ++#define RTL8367C_FLOWCTRL_QUEUE3_PAGE_COUNT_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE3_PAGE_COUNT_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE4_PAGE_COUNT 0x0234 ++#define RTL8367C_FLOWCTRL_QUEUE4_PAGE_COUNT_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE4_PAGE_COUNT_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE5_PAGE_COUNT 0x0235 ++#define RTL8367C_FLOWCTRL_QUEUE5_PAGE_COUNT_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE5_PAGE_COUNT_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE6_PAGE_COUNT 0x0236 ++#define RTL8367C_FLOWCTRL_QUEUE6_PAGE_COUNT_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE6_PAGE_COUNT_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE7_PAGE_COUNT 0x0237 ++#define RTL8367C_FLOWCTRL_QUEUE7_PAGE_COUNT_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE7_PAGE_COUNT_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT_PAGE_COUNT 0x0238 ++#define RTL8367C_FLOWCTRL_PORT_PAGE_COUNT_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT_PAGE_COUNT_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE0_MAX_PAGE_COUNT 0x0239 ++#define RTL8367C_FLOWCTRL_QUEUE0_MAX_PAGE_COUNT_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE0_MAX_PAGE_COUNT_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE1_MAX_PAGE_COUNT 0x023a ++#define RTL8367C_FLOWCTRL_QUEUE1_MAX_PAGE_COUNT_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE1_MAX_PAGE_COUNT_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE2_MAX_PAGE_COUNT 0x023b ++#define RTL8367C_FLOWCTRL_QUEUE2_MAX_PAGE_COUNT_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE2_MAX_PAGE_COUNT_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE3_MAX_PAGE_COUNT 0x023c ++#define RTL8367C_FLOWCTRL_QUEUE3_MAX_PAGE_COUNT_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE3_MAX_PAGE_COUNT_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE4_MAX_PAGE_COUNT 0x023d ++#define RTL8367C_FLOWCTRL_QUEUE4_MAX_PAGE_COUNT_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE4_MAX_PAGE_COUNT_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE5_MAX_PAGE_COUNT 0x023e ++#define RTL8367C_FLOWCTRL_QUEUE5_MAX_PAGE_COUNT_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE5_MAX_PAGE_COUNT_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE6_MAX_PAGE_COUNT 0x023f ++#define RTL8367C_FLOWCTRL_QUEUE6_MAX_PAGE_COUNT_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE6_MAX_PAGE_COUNT_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_QUEUE7_MAX_PAGE_COUNT 0x0240 ++#define RTL8367C_FLOWCTRL_QUEUE7_MAX_PAGE_COUNT_OFFSET 0 ++#define RTL8367C_FLOWCTRL_QUEUE7_MAX_PAGE_COUNT_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT_MAX_PAGE_COUNT 0x0241 ++#define RTL8367C_FLOWCTRL_PORT_MAX_PAGE_COUNT_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT_MAX_PAGE_COUNT_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_TOTAL_PACKET_COUNT 0x0243 ++ ++#define RTL8367C_REG_HIGH_QUEUE_MASK0 0x0244 ++#define RTL8367C_PORT1_HIGH_QUEUE_MASK_OFFSET 8 ++#define RTL8367C_PORT1_HIGH_QUEUE_MASK_MASK 0xFF00 ++#define RTL8367C_PORT0_HIGH_QUEUE_MASK_OFFSET 0 ++#define RTL8367C_PORT0_HIGH_QUEUE_MASK_MASK 0xFF ++ ++#define RTL8367C_REG_HIGH_QUEUE_MASK1 0x0245 ++#define RTL8367C_PORT3_HIGH_QUEUE_MASK_OFFSET 8 ++#define RTL8367C_PORT3_HIGH_QUEUE_MASK_MASK 0xFF00 ++#define RTL8367C_PORT2_HIGH_QUEUE_MASK_OFFSET 0 ++#define RTL8367C_PORT2_HIGH_QUEUE_MASK_MASK 0xFF ++ ++#define RTL8367C_REG_HIGH_QUEUE_MASK2 0x0246 ++#define RTL8367C_PORT5_HIGH_QUEUE_MASK_OFFSET 8 ++#define RTL8367C_PORT5_HIGH_QUEUE_MASK_MASK 0xFF00 ++#define RTL8367C_PORT4_HIGH_QUEUE_MASK_OFFSET 0 ++#define RTL8367C_PORT4_HIGH_QUEUE_MASK_MASK 0xFF ++ ++#define RTL8367C_REG_HIGH_QUEUE_MASK3 0x0247 ++#define RTL8367C_PORT7_HIGH_QUEUE_MASK_OFFSET 8 ++#define RTL8367C_PORT7_HIGH_QUEUE_MASK_MASK 0xFF00 ++#define RTL8367C_PORT6_HIGH_QUEUE_MASK_OFFSET 0 ++#define RTL8367C_PORT6_HIGH_QUEUE_MASK_MASK 0xFF ++ ++#define RTL8367C_REG_HIGH_QUEUE_MASK4 0x0248 ++#define RTL8367C_PORT9_HIGH_QUEUE_MASK_OFFSET 8 ++#define RTL8367C_PORT9_HIGH_QUEUE_MASK_MASK 0xFF00 ++#define RTL8367C_PORT8_HIGH_QUEUE_MASK_OFFSET 0 ++#define RTL8367C_PORT8_HIGH_QUEUE_MASK_MASK 0xFF ++ ++#define RTL8367C_REG_HIGH_QUEUE_MASK5 0x0249 ++#define RTL8367C_HIGH_QUEUE_MASK5_OFFSET 0 ++#define RTL8367C_HIGH_QUEUE_MASK5_MASK 0xFF ++ ++#define RTL8367C_REG_LOW_QUEUE_TH 0x024c ++#define RTL8367C_LOW_QUEUE_TH_OFFSET 0 ++#define RTL8367C_LOW_QUEUE_TH_MASK 0x7FF ++ ++#define RTL8367C_REG_TH_TX_PREFET 0x0250 ++#define RTL8367C_TH_TX_PREFET_OFFSET 0 ++#define RTL8367C_TH_TX_PREFET_MASK 0xFF ++ ++#define RTL8367C_REG_DUMMY_0251 0x0251 ++ ++#define RTL8367C_REG_DUMMY_0252 0x0252 ++ ++#define RTL8367C_REG_DUMMY_0253 0x0253 ++ ++#define RTL8367C_REG_DUMMY_0254 0x0254 ++ ++#define RTL8367C_REG_DUMMY_0255 0x0255 ++ ++#define RTL8367C_REG_DUMMY_0256 0x0256 ++ ++#define RTL8367C_REG_DUMMY_0257 0x0257 ++ ++#define RTL8367C_REG_DUMMY_0258 0x0258 ++ ++#define RTL8367C_REG_DUMMY_0259 0x0259 ++ ++#define RTL8367C_REG_DUMMY_025A 0x025A ++ ++#define RTL8367C_REG_DUMMY_025B 0x025B ++ ++#define RTL8367C_REG_DUMMY_025C 0x025C ++ ++#define RTL8367C_REG_Q_TXPKT_CNT_CTL 0x025d ++#define RTL8367C_QUEUE_PKT_CNT_CLR_OFFSET 4 ++#define RTL8367C_QUEUE_PKT_CNT_CLR_MASK 0x10 ++#define RTL8367C_PORT_ID_QUEUE_PKT_CNT_OFFSET 0 ++#define RTL8367C_PORT_ID_QUEUE_PKT_CNT_MASK 0xF ++ ++#define RTL8367C_REG_Q0_TXPKT_CNT_L 0x025e ++ ++#define RTL8367C_REG_Q0_TXPKT_CNT_H 0x025f ++ ++#define RTL8367C_REG_Q1_TXPKT_CNT_L 0x0260 ++ ++#define RTL8367C_REG_Q1_TXPKT_CNT_H 0x0261 ++ ++#define RTL8367C_REG_Q2_TXPKT_CNT_L 0x0262 ++ ++#define RTL8367C_REG_Q2_TXPKT_CNT_H 0x0263 ++ ++#define RTL8367C_REG_Q3_TXPKT_CNT_L 0x0264 ++ ++#define RTL8367C_REG_Q3_TXPKT_CNT_H 0x0265 ++ ++#define RTL8367C_REG_Q4_TXPKT_CNT_L 0x0266 ++ ++#define RTL8367C_REG_Q4_TXPKT_CNT_H 0x0267 ++ ++#define RTL8367C_REG_Q5_TXPKT_CNT_L 0x0268 ++ ++#define RTL8367C_REG_Q5_TXPKT_CNT_H 0x0269 ++ ++#define RTL8367C_REG_Q6_TXPKT_CNT_L 0x026a ++ ++#define RTL8367C_REG_Q6_TXPKT_CNT_H 0x026b ++ ++#define RTL8367C_REG_Q7_TXPKT_CNT_L 0x026c ++ ++#define RTL8367C_REG_Q7_TXPKT_CNT_H 0x026d ++ ++/* (16'h0300)sch_reg */ ++ ++#define RTL8367C_REG_SCHEDULE_WFQ_CTRL 0x0300 ++#define RTL8367C_SCHEDULE_WFQ_CTRL_OFFSET 0 ++#define RTL8367C_SCHEDULE_WFQ_CTRL_MASK 0x1 ++ ++#define RTL8367C_REG_SCHEDULE_WFQ_BURST_SIZE 0x0301 ++ ++#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL0 0x0302 ++#define RTL8367C_PORT1_QUEUE7_TYPE_OFFSET 15 ++#define RTL8367C_PORT1_QUEUE7_TYPE_MASK 0x8000 ++#define RTL8367C_PORT1_QUEUE6_TYPE_OFFSET 14 ++#define RTL8367C_PORT1_QUEUE6_TYPE_MASK 0x4000 ++#define RTL8367C_PORT1_QUEUE5_TYPE_OFFSET 13 ++#define RTL8367C_PORT1_QUEUE5_TYPE_MASK 0x2000 ++#define RTL8367C_PORT1_QUEUE4_TYPE_OFFSET 12 ++#define RTL8367C_PORT1_QUEUE4_TYPE_MASK 0x1000 ++#define RTL8367C_PORT1_QUEUE3_TYPE_OFFSET 11 ++#define RTL8367C_PORT1_QUEUE3_TYPE_MASK 0x800 ++#define RTL8367C_PORT1_QUEUE2_TYPE_OFFSET 10 ++#define RTL8367C_PORT1_QUEUE2_TYPE_MASK 0x400 ++#define RTL8367C_PORT1_QUEUE1_TYPE_OFFSET 9 ++#define RTL8367C_PORT1_QUEUE1_TYPE_MASK 0x200 ++#define RTL8367C_PORT1_QUEUE0_TYPE_OFFSET 8 ++#define RTL8367C_PORT1_QUEUE0_TYPE_MASK 0x100 ++#define RTL8367C_PORT0_QUEUE7_TYPE_OFFSET 7 ++#define RTL8367C_PORT0_QUEUE7_TYPE_MASK 0x80 ++#define RTL8367C_PORT0_QUEUE6_TYPE_OFFSET 6 ++#define RTL8367C_PORT0_QUEUE6_TYPE_MASK 0x40 ++#define RTL8367C_PORT0_QUEUE5_TYPE_OFFSET 5 ++#define RTL8367C_PORT0_QUEUE5_TYPE_MASK 0x20 ++#define RTL8367C_PORT0_QUEUE4_TYPE_OFFSET 4 ++#define RTL8367C_PORT0_QUEUE4_TYPE_MASK 0x10 ++#define RTL8367C_PORT0_QUEUE3_TYPE_OFFSET 3 ++#define RTL8367C_PORT0_QUEUE3_TYPE_MASK 0x8 ++#define RTL8367C_PORT0_QUEUE2_TYPE_OFFSET 2 ++#define RTL8367C_PORT0_QUEUE2_TYPE_MASK 0x4 ++#define RTL8367C_PORT0_QUEUE1_TYPE_OFFSET 1 ++#define RTL8367C_PORT0_QUEUE1_TYPE_MASK 0x2 ++#define RTL8367C_PORT0_QUEUE0_TYPE_OFFSET 0 ++#define RTL8367C_PORT0_QUEUE0_TYPE_MASK 0x1 ++ ++#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL1 0x0303 ++#define RTL8367C_PORT3_QUEUE7_TYPE_OFFSET 15 ++#define RTL8367C_PORT3_QUEUE7_TYPE_MASK 0x8000 ++#define RTL8367C_PORT3_QUEUE6_TYPE_OFFSET 14 ++#define RTL8367C_PORT3_QUEUE6_TYPE_MASK 0x4000 ++#define RTL8367C_PORT3_QUEUE5_TYPE_OFFSET 13 ++#define RTL8367C_PORT3_QUEUE5_TYPE_MASK 0x2000 ++#define RTL8367C_PORT3_QUEUE4_TYPE_OFFSET 12 ++#define RTL8367C_PORT3_QUEUE4_TYPE_MASK 0x1000 ++#define RTL8367C_PORT3_QUEUE3_TYPE_OFFSET 11 ++#define RTL8367C_PORT3_QUEUE3_TYPE_MASK 0x800 ++#define RTL8367C_PORT3_QUEUE2_TYPE_OFFSET 10 ++#define RTL8367C_PORT3_QUEUE2_TYPE_MASK 0x400 ++#define RTL8367C_PORT3_QUEUE1_TYPE_OFFSET 9 ++#define RTL8367C_PORT3_QUEUE1_TYPE_MASK 0x200 ++#define RTL8367C_PORT3_QUEUE0_TYPE_OFFSET 8 ++#define RTL8367C_PORT3_QUEUE0_TYPE_MASK 0x100 ++#define RTL8367C_PORT2_QUEUE7_TYPE_OFFSET 7 ++#define RTL8367C_PORT2_QUEUE7_TYPE_MASK 0x80 ++#define RTL8367C_PORT2_QUEUE6_TYPE_OFFSET 6 ++#define RTL8367C_PORT2_QUEUE6_TYPE_MASK 0x40 ++#define RTL8367C_PORT2_QUEUE5_TYPE_OFFSET 5 ++#define RTL8367C_PORT2_QUEUE5_TYPE_MASK 0x20 ++#define RTL8367C_PORT2_QUEUE4_TYPE_OFFSET 4 ++#define RTL8367C_PORT2_QUEUE4_TYPE_MASK 0x10 ++#define RTL8367C_PORT2_QUEUE3_TYPE_OFFSET 3 ++#define RTL8367C_PORT2_QUEUE3_TYPE_MASK 0x8 ++#define RTL8367C_PORT2_QUEUE2_TYPE_OFFSET 2 ++#define RTL8367C_PORT2_QUEUE2_TYPE_MASK 0x4 ++#define RTL8367C_PORT2_QUEUE1_TYPE_OFFSET 1 ++#define RTL8367C_PORT2_QUEUE1_TYPE_MASK 0x2 ++#define RTL8367C_PORT2_QUEUE0_TYPE_OFFSET 0 ++#define RTL8367C_PORT2_QUEUE0_TYPE_MASK 0x1 ++ ++#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL2 0x0304 ++#define RTL8367C_PORT5_QUEUE7_TYPE_OFFSET 15 ++#define RTL8367C_PORT5_QUEUE7_TYPE_MASK 0x8000 ++#define RTL8367C_PORT5_QUEUE6_TYPE_OFFSET 14 ++#define RTL8367C_PORT5_QUEUE6_TYPE_MASK 0x4000 ++#define RTL8367C_PORT5_QUEUE5_TYPE_OFFSET 13 ++#define RTL8367C_PORT5_QUEUE5_TYPE_MASK 0x2000 ++#define RTL8367C_PORT5_QUEUE4_TYPE_OFFSET 12 ++#define RTL8367C_PORT5_QUEUE4_TYPE_MASK 0x1000 ++#define RTL8367C_PORT5_QUEUE3_TYPE_OFFSET 11 ++#define RTL8367C_PORT5_QUEUE3_TYPE_MASK 0x800 ++#define RTL8367C_PORT5_QUEUE2_TYPE_OFFSET 10 ++#define RTL8367C_PORT5_QUEUE2_TYPE_MASK 0x400 ++#define RTL8367C_PORT5_QUEUE1_TYPE_OFFSET 9 ++#define RTL8367C_PORT5_QUEUE1_TYPE_MASK 0x200 ++#define RTL8367C_PORT5_QUEUE0_TYPE_OFFSET 8 ++#define RTL8367C_PORT5_QUEUE0_TYPE_MASK 0x100 ++#define RTL8367C_PORT4_QUEUE7_TYPE_OFFSET 7 ++#define RTL8367C_PORT4_QUEUE7_TYPE_MASK 0x80 ++#define RTL8367C_PORT4_QUEUE6_TYPE_OFFSET 6 ++#define RTL8367C_PORT4_QUEUE6_TYPE_MASK 0x40 ++#define RTL8367C_PORT4_QUEUE5_TYPE_OFFSET 5 ++#define RTL8367C_PORT4_QUEUE5_TYPE_MASK 0x20 ++#define RTL8367C_PORT4_QUEUE4_TYPE_OFFSET 4 ++#define RTL8367C_PORT4_QUEUE4_TYPE_MASK 0x10 ++#define RTL8367C_PORT4_QUEUE3_TYPE_OFFSET 3 ++#define RTL8367C_PORT4_QUEUE3_TYPE_MASK 0x8 ++#define RTL8367C_PORT4_QUEUE2_TYPE_OFFSET 2 ++#define RTL8367C_PORT4_QUEUE2_TYPE_MASK 0x4 ++#define RTL8367C_PORT4_QUEUE1_TYPE_OFFSET 1 ++#define RTL8367C_PORT4_QUEUE1_TYPE_MASK 0x2 ++#define RTL8367C_PORT4_QUEUE0_TYPE_OFFSET 0 ++#define RTL8367C_PORT4_QUEUE0_TYPE_MASK 0x1 ++ ++#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL3 0x0305 ++#define RTL8367C_PORT7_QUEUE7_TYPE_OFFSET 15 ++#define RTL8367C_PORT7_QUEUE7_TYPE_MASK 0x8000 ++#define RTL8367C_PORT7_QUEUE6_TYPE_OFFSET 14 ++#define RTL8367C_PORT7_QUEUE6_TYPE_MASK 0x4000 ++#define RTL8367C_PORT7_QUEUE5_TYPE_OFFSET 13 ++#define RTL8367C_PORT7_QUEUE5_TYPE_MASK 0x2000 ++#define RTL8367C_PORT7_QUEUE4_TYPE_OFFSET 12 ++#define RTL8367C_PORT7_QUEUE4_TYPE_MASK 0x1000 ++#define RTL8367C_PORT7_QUEUE3_TYPE_OFFSET 11 ++#define RTL8367C_PORT7_QUEUE3_TYPE_MASK 0x800 ++#define RTL8367C_PORT7_QUEUE2_TYPE_OFFSET 10 ++#define RTL8367C_PORT7_QUEUE2_TYPE_MASK 0x400 ++#define RTL8367C_PORT7_QUEUE1_TYPE_OFFSET 9 ++#define RTL8367C_PORT7_QUEUE1_TYPE_MASK 0x200 ++#define RTL8367C_PORT7_QUEUE0_TYPE_OFFSET 8 ++#define RTL8367C_PORT7_QUEUE0_TYPE_MASK 0x100 ++#define RTL8367C_PORT6_QUEUE7_TYPE_OFFSET 7 ++#define RTL8367C_PORT6_QUEUE7_TYPE_MASK 0x80 ++#define RTL8367C_PORT6_QUEUE6_TYPE_OFFSET 6 ++#define RTL8367C_PORT6_QUEUE6_TYPE_MASK 0x40 ++#define RTL8367C_PORT6_QUEUE5_TYPE_OFFSET 5 ++#define RTL8367C_PORT6_QUEUE5_TYPE_MASK 0x20 ++#define RTL8367C_PORT6_QUEUE4_TYPE_OFFSET 4 ++#define RTL8367C_PORT6_QUEUE4_TYPE_MASK 0x10 ++#define RTL8367C_PORT6_QUEUE3_TYPE_OFFSET 3 ++#define RTL8367C_PORT6_QUEUE3_TYPE_MASK 0x8 ++#define RTL8367C_PORT6_QUEUE2_TYPE_OFFSET 2 ++#define RTL8367C_PORT6_QUEUE2_TYPE_MASK 0x4 ++#define RTL8367C_PORT6_QUEUE1_TYPE_OFFSET 1 ++#define RTL8367C_PORT6_QUEUE1_TYPE_MASK 0x2 ++#define RTL8367C_SCHEDULE_QUEUE_TYPE_CTRL3_PORT6_QUEUE0_TYPE_OFFSET 0 ++#define RTL8367C_SCHEDULE_QUEUE_TYPE_CTRL3_PORT6_QUEUE0_TYPE_MASK 0x1 ++ ++#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL4 0x0306 ++#define RTL8367C_PORT9_QUEUE7_TYPE_OFFSET 15 ++#define RTL8367C_PORT9_QUEUE7_TYPE_MASK 0x8000 ++#define RTL8367C_PORT9_QUEUE6_TYPE_OFFSET 14 ++#define RTL8367C_PORT9_QUEUE6_TYPE_MASK 0x4000 ++#define RTL8367C_PORT9_QUEUE5_TYPE_OFFSET 13 ++#define RTL8367C_PORT9_QUEUE5_TYPE_MASK 0x2000 ++#define RTL8367C_PORT9_QUEUE4_TYPE_OFFSET 12 ++#define RTL8367C_PORT9_QUEUE4_TYPE_MASK 0x1000 ++#define RTL8367C_PORT9_QUEUE3_TYPE_OFFSET 11 ++#define RTL8367C_PORT9_QUEUE3_TYPE_MASK 0x800 ++#define RTL8367C_PORT9_QUEUE2_TYPE_OFFSET 10 ++#define RTL8367C_PORT9_QUEUE2_TYPE_MASK 0x400 ++#define RTL8367C_PORT9_QUEUE1_TYPE_OFFSET 9 ++#define RTL8367C_PORT9_QUEUE1_TYPE_MASK 0x200 ++#define RTL8367C_PORT9_QUEUE0_TYPE_OFFSET 8 ++#define RTL8367C_PORT9_QUEUE0_TYPE_MASK 0x100 ++#define RTL8367C_PORT8_QUEUE7_TYPE_OFFSET 7 ++#define RTL8367C_PORT8_QUEUE7_TYPE_MASK 0x80 ++#define RTL8367C_PORT8_QUEUE6_TYPE_OFFSET 6 ++#define RTL8367C_PORT8_QUEUE6_TYPE_MASK 0x40 ++#define RTL8367C_PORT8_QUEUE5_TYPE_OFFSET 5 ++#define RTL8367C_PORT8_QUEUE5_TYPE_MASK 0x20 ++#define RTL8367C_PORT8_QUEUE4_TYPE_OFFSET 4 ++#define RTL8367C_PORT8_QUEUE4_TYPE_MASK 0x10 ++#define RTL8367C_PORT8_QUEUE3_TYPE_OFFSET 3 ++#define RTL8367C_PORT8_QUEUE3_TYPE_MASK 0x8 ++#define RTL8367C_PORT8_QUEUE2_TYPE_OFFSET 2 ++#define RTL8367C_PORT8_QUEUE2_TYPE_MASK 0x4 ++#define RTL8367C_PORT8_QUEUE1_TYPE_OFFSET 1 ++#define RTL8367C_PORT8_QUEUE1_TYPE_MASK 0x2 ++#define RTL8367C_SCHEDULE_QUEUE_TYPE_CTRL4_PORT6_QUEUE0_TYPE_OFFSET 0 ++#define RTL8367C_SCHEDULE_QUEUE_TYPE_CTRL4_PORT6_QUEUE0_TYPE_MASK 0x1 ++ ++#define RTL8367C_REG_SCHEDULE_QUEUE_TYPE_CTRL5 0x0307 ++#define RTL8367C_PORT10_QUEUE7_TYPE_OFFSET 7 ++#define RTL8367C_PORT10_QUEUE7_TYPE_MASK 0x80 ++#define RTL8367C_PORT10_QUEUE6_TYPE_OFFSET 6 ++#define RTL8367C_PORT10_QUEUE6_TYPE_MASK 0x40 ++#define RTL8367C_PORT10_QUEUE5_TYPE_OFFSET 5 ++#define RTL8367C_PORT10_QUEUE5_TYPE_MASK 0x20 ++#define RTL8367C_PORT10_QUEUE4_TYPE_OFFSET 4 ++#define RTL8367C_PORT10_QUEUE4_TYPE_MASK 0x10 ++#define RTL8367C_PORT10_QUEUE3_TYPE_OFFSET 3 ++#define RTL8367C_PORT10_QUEUE3_TYPE_MASK 0x8 ++#define RTL8367C_PORT10_QUEUE2_TYPE_OFFSET 2 ++#define RTL8367C_PORT10_QUEUE2_TYPE_MASK 0x4 ++#define RTL8367C_PORT10_QUEUE1_TYPE_OFFSET 1 ++#define RTL8367C_PORT10_QUEUE1_TYPE_MASK 0x2 ++#define RTL8367C_PORT10_QUEUE0_TYPE_OFFSET 0 ++#define RTL8367C_PORT10_QUEUE0_TYPE_MASK 0x1 ++ ++#define RTL8367C_REG_SCHEDULE_APR_CTRL0 0x030a ++#define RTL8367C_PORT10_APR_ENABLE_OFFSET 10 ++#define RTL8367C_PORT10_APR_ENABLE_MASK 0x400 ++#define RTL8367C_PORT9_APR_ENABLE_OFFSET 9 ++#define RTL8367C_PORT9_APR_ENABLE_MASK 0x200 ++#define RTL8367C_PORT8_APR_ENABLE_OFFSET 8 ++#define RTL8367C_PORT8_APR_ENABLE_MASK 0x100 ++#define RTL8367C_PORT7_APR_ENABLE_OFFSET 7 ++#define RTL8367C_PORT7_APR_ENABLE_MASK 0x80 ++#define RTL8367C_PORT6_APR_ENABLE_OFFSET 6 ++#define RTL8367C_PORT6_APR_ENABLE_MASK 0x40 ++#define RTL8367C_PORT5_APR_ENABLE_OFFSET 5 ++#define RTL8367C_PORT5_APR_ENABLE_MASK 0x20 ++#define RTL8367C_PORT4_APR_ENABLE_OFFSET 4 ++#define RTL8367C_PORT4_APR_ENABLE_MASK 0x10 ++#define RTL8367C_PORT3_APR_ENABLE_OFFSET 3 ++#define RTL8367C_PORT3_APR_ENABLE_MASK 0x8 ++#define RTL8367C_PORT2_APR_ENABLE_OFFSET 2 ++#define RTL8367C_PORT2_APR_ENABLE_MASK 0x4 ++#define RTL8367C_PORT1_APR_ENABLE_OFFSET 1 ++#define RTL8367C_PORT1_APR_ENABLE_MASK 0x2 ++#define RTL8367C_PORT0_APR_ENABLE_OFFSET 0 ++#define RTL8367C_PORT0_APR_ENABLE_MASK 0x1 ++ ++#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE0_WFQ_WEIGHT 0x030c ++ ++#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE1_WFQ_WEIGHT 0x030d ++#define RTL8367C_SCHEDULE_PORT0_QUEUE1_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT0_QUEUE1_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE2_WFQ_WEIGHT 0x030e ++#define RTL8367C_SCHEDULE_PORT0_QUEUE2_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT0_QUEUE2_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE3_WFQ_WEIGHT 0x030f ++#define RTL8367C_SCHEDULE_PORT0_QUEUE3_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT0_QUEUE3_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE4_WFQ_WEIGHT 0x0310 ++#define RTL8367C_SCHEDULE_PORT0_QUEUE4_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT0_QUEUE4_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE5_WFQ_WEIGHT 0x0311 ++#define RTL8367C_SCHEDULE_PORT0_QUEUE5_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT0_QUEUE5_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE6_WFQ_WEIGHT 0x0312 ++#define RTL8367C_SCHEDULE_PORT0_QUEUE6_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT0_QUEUE6_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT0_QUEUE7_WFQ_WEIGHT 0x0313 ++#define RTL8367C_SCHEDULE_PORT0_QUEUE7_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT0_QUEUE7_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE0_WFQ_WEIGHT 0x0314 ++ ++#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE1_WFQ_WEIGHT 0x0315 ++#define RTL8367C_SCHEDULE_PORT1_QUEUE1_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT1_QUEUE1_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE2_WFQ_WEIGHT 0x0316 ++#define RTL8367C_SCHEDULE_PORT1_QUEUE2_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT1_QUEUE2_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE3_WFQ_WEIGHT 0x0317 ++#define RTL8367C_SCHEDULE_PORT1_QUEUE3_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT1_QUEUE3_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE4_WFQ_WEIGHT 0x0318 ++#define RTL8367C_SCHEDULE_PORT1_QUEUE4_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT1_QUEUE4_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE5_WFQ_WEIGHT 0x0319 ++#define RTL8367C_SCHEDULE_PORT1_QUEUE5_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT1_QUEUE5_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE6_WFQ_WEIGHT 0x031a ++#define RTL8367C_SCHEDULE_PORT1_QUEUE6_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT1_QUEUE6_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT1_QUEUE7_WFQ_WEIGHT 0x031b ++#define RTL8367C_SCHEDULE_PORT1_QUEUE7_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT1_QUEUE7_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE0_WFQ_WEIGHT 0x031c ++ ++#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE1_WFQ_WEIGHT 0x031d ++#define RTL8367C_SCHEDULE_PORT2_QUEUE1_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT2_QUEUE1_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE2_WFQ_WEIGHT 0x031e ++#define RTL8367C_SCHEDULE_PORT2_QUEUE2_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT2_QUEUE2_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE3_WFQ_WEIGHT 0x031f ++#define RTL8367C_SCHEDULE_PORT2_QUEUE3_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT2_QUEUE3_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE4_WFQ_WEIGHT 0x0320 ++#define RTL8367C_SCHEDULE_PORT2_QUEUE4_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT2_QUEUE4_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE5_WFQ_WEIGHT 0x0321 ++#define RTL8367C_SCHEDULE_PORT2_QUEUE5_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT2_QUEUE5_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE6_WFQ_WEIGHT 0x0322 ++#define RTL8367C_SCHEDULE_PORT2_QUEUE6_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT2_QUEUE6_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT2_QUEUE7_WFQ_WEIGHT 0x0323 ++#define RTL8367C_SCHEDULE_PORT2_QUEUE7_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT2_QUEUE7_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE0_WFQ_WEIGHT 0x0324 ++ ++#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE1_WFQ_WEIGHT 0x0325 ++#define RTL8367C_SCHEDULE_PORT3_QUEUE1_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT3_QUEUE1_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE2_WFQ_WEIGHT 0x0326 ++#define RTL8367C_SCHEDULE_PORT3_QUEUE2_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT3_QUEUE2_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE3_WFQ_WEIGHT 0x0327 ++#define RTL8367C_SCHEDULE_PORT3_QUEUE3_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT3_QUEUE3_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE4_WFQ_WEIGHT 0x0328 ++#define RTL8367C_SCHEDULE_PORT3_QUEUE4_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT3_QUEUE4_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE5_WFQ_WEIGHT 0x0329 ++#define RTL8367C_SCHEDULE_PORT3_QUEUE5_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT3_QUEUE5_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE6_WFQ_WEIGHT 0x032a ++#define RTL8367C_SCHEDULE_PORT3_QUEUE6_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT3_QUEUE6_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT3_QUEUE7_WFQ_WEIGHT 0x032b ++#define RTL8367C_SCHEDULE_PORT3_QUEUE7_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT3_QUEUE7_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE0_WFQ_WEIGHT 0x032c ++ ++#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE1_WFQ_WEIGHT 0x032d ++#define RTL8367C_SCHEDULE_PORT4_QUEUE1_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT4_QUEUE1_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE2_WFQ_WEIGHT 0x032e ++#define RTL8367C_SCHEDULE_PORT4_QUEUE2_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT4_QUEUE2_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE3_WFQ_WEIGHT 0x032f ++#define RTL8367C_SCHEDULE_PORT4_QUEUE3_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT4_QUEUE3_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE4_WFQ_WEIGHT 0x0330 ++#define RTL8367C_SCHEDULE_PORT4_QUEUE4_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT4_QUEUE4_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE5_WFQ_WEIGHT 0x0331 ++#define RTL8367C_SCHEDULE_PORT4_QUEUE5_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT4_QUEUE5_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE6_WFQ_WEIGHT 0x0332 ++#define RTL8367C_SCHEDULE_PORT4_QUEUE6_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT4_QUEUE6_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT4_QUEUE7_WFQ_WEIGHT 0x0333 ++#define RTL8367C_SCHEDULE_PORT4_QUEUE7_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT4_QUEUE7_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE0_WFQ_WEIGHT 0x0334 ++ ++#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE1_WFQ_WEIGHT 0x0335 ++#define RTL8367C_SCHEDULE_PORT5_QUEUE1_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT5_QUEUE1_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE2_WFQ_WEIGHT 0x0336 ++#define RTL8367C_SCHEDULE_PORT5_QUEUE2_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT5_QUEUE2_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE3_WFQ_WEIGHT 0x0337 ++#define RTL8367C_SCHEDULE_PORT5_QUEUE3_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT5_QUEUE3_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE4_WFQ_WEIGHT 0x0338 ++#define RTL8367C_SCHEDULE_PORT5_QUEUE4_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT5_QUEUE4_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE5_WFQ_WEIGHT 0x0339 ++#define RTL8367C_SCHEDULE_PORT5_QUEUE5_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT5_QUEUE5_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE6_WFQ_WEIGHT 0x033a ++#define RTL8367C_SCHEDULE_PORT5_QUEUE6_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT5_QUEUE6_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT5_QUEUE7_WFQ_WEIGHT 0x033b ++#define RTL8367C_SCHEDULE_PORT5_QUEUE7_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT5_QUEUE7_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE0_WFQ_WEIGHT 0x033c ++ ++#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE1_WFQ_WEIGHT 0x033d ++#define RTL8367C_SCHEDULE_PORT6_QUEUE1_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT6_QUEUE1_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE2_WFQ_WEIGHT 0x033e ++#define RTL8367C_SCHEDULE_PORT6_QUEUE2_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT6_QUEUE2_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE3_WFQ_WEIGHT 0x033f ++#define RTL8367C_SCHEDULE_PORT6_QUEUE3_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT6_QUEUE3_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE4_WFQ_WEIGHT 0x0340 ++#define RTL8367C_SCHEDULE_PORT6_QUEUE4_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT6_QUEUE4_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE5_WFQ_WEIGHT 0x0341 ++#define RTL8367C_SCHEDULE_PORT6_QUEUE5_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT6_QUEUE5_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE6_WFQ_WEIGHT 0x0342 ++#define RTL8367C_SCHEDULE_PORT6_QUEUE6_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT6_QUEUE6_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT6_QUEUE7_WFQ_WEIGHT 0x0343 ++#define RTL8367C_SCHEDULE_PORT6_QUEUE7_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT6_QUEUE7_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE0_WFQ_WEIGHT 0x0344 ++ ++#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE1_WFQ_WEIGHT 0x0345 ++#define RTL8367C_SCHEDULE_PORT7_QUEUE1_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT7_QUEUE1_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE2_WFQ_WEIGHT 0x0346 ++#define RTL8367C_SCHEDULE_PORT7_QUEUE2_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT7_QUEUE2_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE3_WFQ_WEIGHT 0x0347 ++#define RTL8367C_SCHEDULE_PORT7_QUEUE3_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT7_QUEUE3_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE4_WFQ_WEIGHT 0x0348 ++#define RTL8367C_SCHEDULE_PORT7_QUEUE4_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT7_QUEUE4_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE5_WFQ_WEIGHT 0x0349 ++#define RTL8367C_SCHEDULE_PORT7_QUEUE5_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT7_QUEUE5_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE6_WFQ_WEIGHT 0x034a ++#define RTL8367C_SCHEDULE_PORT7_QUEUE6_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT7_QUEUE6_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT7_QUEUE7_WFQ_WEIGHT 0x034b ++#define RTL8367C_SCHEDULE_PORT7_QUEUE7_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT7_QUEUE7_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE0_WFQ_WEIGHT 0x034c ++ ++#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE1_WFQ_WEIGHT 0x034d ++#define RTL8367C_SCHEDULE_PORT8_QUEUE1_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT8_QUEUE1_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE2_WFQ_WEIGHT 0x034e ++#define RTL8367C_SCHEDULE_PORT8_QUEUE2_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT8_QUEUE2_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE3_WFQ_WEIGHT 0x034f ++#define RTL8367C_SCHEDULE_PORT8_QUEUE3_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT8_QUEUE3_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE4_WFQ_WEIGHT 0x0350 ++#define RTL8367C_SCHEDULE_PORT8_QUEUE4_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT8_QUEUE4_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE5_WFQ_WEIGHT 0x0351 ++#define RTL8367C_SCHEDULE_PORT8_QUEUE5_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT8_QUEUE5_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE6_WFQ_WEIGHT 0x0352 ++#define RTL8367C_SCHEDULE_PORT8_QUEUE6_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT8_QUEUE6_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT8_QUEUE7_WFQ_WEIGHT 0x0353 ++#define RTL8367C_SCHEDULE_PORT8_QUEUE7_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT8_QUEUE7_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE0_WFQ_WEIGHT 0x0354 ++ ++#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE1_WFQ_WEIGHT 0x0355 ++#define RTL8367C_SCHEDULE_PORT9_QUEUE1_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT9_QUEUE1_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE2_WFQ_WEIGHT 0x0356 ++#define RTL8367C_SCHEDULE_PORT9_QUEUE2_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT9_QUEUE2_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE3_WFQ_WEIGHT 0x0357 ++#define RTL8367C_SCHEDULE_PORT9_QUEUE3_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT9_QUEUE3_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE4_WFQ_WEIGHT 0x0358 ++#define RTL8367C_SCHEDULE_PORT9_QUEUE4_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT9_QUEUE4_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE5_WFQ_WEIGHT 0x0359 ++#define RTL8367C_SCHEDULE_PORT9_QUEUE5_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT9_QUEUE5_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE6_WFQ_WEIGHT 0x035a ++#define RTL8367C_SCHEDULE_PORT9_QUEUE6_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT9_QUEUE6_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT9_QUEUE7_WFQ_WEIGHT 0x035b ++#define RTL8367C_SCHEDULE_PORT9_QUEUE7_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT9_QUEUE7_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE0_WFQ_WEIGHT 0x035c ++ ++#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE1_WFQ_WEIGHT 0x035d ++#define RTL8367C_SCHEDULE_PORT10_QUEUE1_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT10_QUEUE1_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE2_WFQ_WEIGHT 0x035e ++#define RTL8367C_SCHEDULE_PORT10_QUEUE2_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT10_QUEUE2_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE3_WFQ_WEIGHT 0x035f ++#define RTL8367C_SCHEDULE_PORT10_QUEUE3_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT10_QUEUE3_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE4_WFQ_WEIGHT 0x0360 ++#define RTL8367C_SCHEDULE_PORT10_QUEUE4_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT10_QUEUE4_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE5_WFQ_WEIGHT 0x0361 ++#define RTL8367C_SCHEDULE_PORT10_QUEUE5_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT10_QUEUE5_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE6_WFQ_WEIGHT 0x0362 ++#define RTL8367C_SCHEDULE_PORT10_QUEUE6_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT10_QUEUE6_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_SCHEDULE_PORT10_QUEUE7_WFQ_WEIGHT 0x0363 ++#define RTL8367C_SCHEDULE_PORT10_QUEUE7_WFQ_WEIGHT_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT10_QUEUE7_WFQ_WEIGHT_MASK 0x7F ++ ++#define RTL8367C_REG_PORT0_EGRESSBW_CTRL0 0x038c ++ ++#define RTL8367C_REG_PORT0_EGRESSBW_CTRL1 0x038d ++#define RTL8367C_PORT0_EGRESSBW_CTRL1_OFFSET 0 ++#define RTL8367C_PORT0_EGRESSBW_CTRL1_MASK 0x1 ++ ++#define RTL8367C_REG_PORT1_EGRESSBW_CTRL0 0x038e ++ ++#define RTL8367C_REG_PORT1_EGRESSBW_CTRL1 0x038f ++#define RTL8367C_PORT1_EGRESSBW_CTRL1_OFFSET 0 ++#define RTL8367C_PORT1_EGRESSBW_CTRL1_MASK 0x1 ++ ++#define RTL8367C_REG_PORT2_EGRESSBW_CTRL0 0x0390 ++ ++#define RTL8367C_REG_PORT2_EGRESSBW_CTRL1 0x0391 ++#define RTL8367C_PORT2_EGRESSBW_CTRL1_OFFSET 0 ++#define RTL8367C_PORT2_EGRESSBW_CTRL1_MASK 0x1 ++ ++#define RTL8367C_REG_PORT3_EGRESSBW_CTRL0 0x0392 ++ ++#define RTL8367C_REG_PORT3_EGRESSBW_CTRL1 0x0393 ++#define RTL8367C_PORT3_EGRESSBW_CTRL1_OFFSET 0 ++#define RTL8367C_PORT3_EGRESSBW_CTRL1_MASK 0x1 ++ ++#define RTL8367C_REG_PORT4_EGRESSBW_CTRL0 0x0394 ++ ++#define RTL8367C_REG_PORT4_EGRESSBW_CTRL1 0x0395 ++#define RTL8367C_PORT4_EGRESSBW_CTRL1_OFFSET 0 ++#define RTL8367C_PORT4_EGRESSBW_CTRL1_MASK 0x1 ++ ++#define RTL8367C_REG_PORT5_EGRESSBW_CTRL0 0x0396 ++ ++#define RTL8367C_REG_PORT5_EGRESSBW_CTRL1 0x0397 ++#define RTL8367C_PORT5_EGRESSBW_CTRL1_OFFSET 0 ++#define RTL8367C_PORT5_EGRESSBW_CTRL1_MASK 0x1 ++ ++#define RTL8367C_REG_PORT6_EGRESSBW_CTRL0 0x0398 ++ ++#define RTL8367C_REG_PORT6_EGRESSBW_CTRL1 0x0399 ++#define RTL8367C_PORT6_EGRESSBW_CTRL1_OFFSET 0 ++#define RTL8367C_PORT6_EGRESSBW_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_PORT7_EGRESSBW_CTRL0 0x039a ++ ++#define RTL8367C_REG_PORT7_EGRESSBW_CTRL1 0x039b ++#define RTL8367C_PORT7_EGRESSBW_CTRL1_OFFSET 0 ++#define RTL8367C_PORT7_EGRESSBW_CTRL1_MASK 0x1 ++ ++#define RTL8367C_REG_PORT8_EGRESSBW_CTRL0 0x039c ++ ++#define RTL8367C_REG_PORT8_EGRESSBW_CTRL1 0x039d ++#define RTL8367C_PORT8_EGRESSBW_CTRL1_OFFSET 0 ++#define RTL8367C_PORT8_EGRESSBW_CTRL1_MASK 0x1 ++ ++#define RTL8367C_REG_PORT9_EGRESSBW_CTRL0 0x039e ++ ++#define RTL8367C_REG_PORT9_EGRESSBW_CTRL1 0x039f ++#define RTL8367C_PORT9_EGRESSBW_CTRL1_OFFSET 0 ++#define RTL8367C_PORT9_EGRESSBW_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_PORT10_EGRESSBW_CTRL0 0x03a0 ++ ++#define RTL8367C_REG_PORT10_EGRESSBW_CTRL1 0x03a1 ++#define RTL8367C_PORT10_EGRESSBW_CTRL1_OFFSET 0 ++#define RTL8367C_PORT10_EGRESSBW_CTRL1_MASK 0x1 ++ ++#define RTL8367C_REG_SCHEDULE_PORT0_APR_METER_CTRL0 0x03ac ++#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 ++#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 ++#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 ++#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 ++#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 ++#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 ++#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 ++#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 ++#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 ++ ++#define RTL8367C_REG_SCHEDULE_PORT0_APR_METER_CTRL1 0x03ad ++#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 ++#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 ++#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 ++#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 ++#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT0_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 ++ ++#define RTL8367C_REG_SCHEDULE_PORT1_APR_METER_CTRL0 0x03b0 ++#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 ++#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 ++#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 ++#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 ++#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 ++#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 ++#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 ++#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 ++#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 ++ ++#define RTL8367C_REG_SCHEDULE_PORT1_APR_METER_CTRL1 0x03b1 ++#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 ++#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 ++#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 ++#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 ++#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT1_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 ++ ++#define RTL8367C_REG_SCHEDULE_PORT2_APR_METER_CTRL0 0x03b4 ++#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 ++#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 ++#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 ++#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 ++#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 ++#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 ++#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 ++#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 ++#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 ++ ++#define RTL8367C_REG_SCHEDULE_PORT2_APR_METER_CTRL1 0x03b5 ++#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 ++#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 ++#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 ++#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 ++#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT2_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 ++ ++#define RTL8367C_REG_SCHEDULE_PORT3_APR_METER_CTRL0 0x03b8 ++#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 ++#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 ++#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 ++#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 ++#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 ++#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 ++#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 ++#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 ++#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 ++ ++#define RTL8367C_REG_SCHEDULE_PORT3_APR_METER_CTRL1 0x03b9 ++#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 ++#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 ++#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 ++#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 ++#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT3_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 ++ ++#define RTL8367C_REG_SCHEDULE_PORT4_APR_METER_CTRL0 0x03bc ++#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 ++#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 ++#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 ++#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 ++#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 ++#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 ++#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 ++#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 ++#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 ++ ++#define RTL8367C_REG_SCHEDULE_PORT4_APR_METER_CTRL1 0x03bd ++#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 ++#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 ++#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 ++#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 ++#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT4_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 ++ ++#define RTL8367C_REG_SCHEDULE_PORT5_APR_METER_CTRL0 0x03c0 ++#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 ++#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 ++#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 ++#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 ++#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 ++#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 ++#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 ++#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 ++#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 ++ ++#define RTL8367C_REG_SCHEDULE_PORT5_APR_METER_CTRL1 0x03c1 ++#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 ++#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 ++#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 ++#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 ++#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT5_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 ++ ++#define RTL8367C_REG_SCHEDULE_PORT6_APR_METER_CTRL0 0x03c4 ++#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 ++#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 ++#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 ++#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 ++#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 ++#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 ++#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 ++#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 ++#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 ++ ++#define RTL8367C_REG_SCHEDULE_PORT6_APR_METER_CTRL1 0x03c5 ++#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 ++#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 ++#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 ++#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 ++#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT6_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 ++ ++#define RTL8367C_REG_SCHEDULE_PORT7_APR_METER_CTRL0 0x03c8 ++#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 ++#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 ++#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 ++#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 ++#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 ++#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 ++#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 ++#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 ++#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 ++ ++#define RTL8367C_REG_SCHEDULE_PORT7_APR_METER_CTRL1 0x03c9 ++#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 ++#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 ++#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 ++#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 ++#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT7_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 ++ ++#define RTL8367C_REG_SCHEDULE_PORT8_APR_METER_CTRL0 0x03ca ++#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 ++#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 ++#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 ++#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 ++#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 ++#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 ++#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 ++#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 ++#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 ++ ++#define RTL8367C_REG_SCHEDULE_PORT8_APR_METER_CTRL1 0x03cb ++#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 ++#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 ++#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 ++#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 ++#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT8_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 ++ ++#define RTL8367C_REG_SCHEDULE_PORT9_APR_METER_CTRL0 0x03cc ++#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 ++#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 ++#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 ++#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 ++#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 ++#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 ++#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 ++#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 ++#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 ++ ++#define RTL8367C_REG_SCHEDULE_PORT9_APR_METER_CTRL1 0x03cd ++#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 ++#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 ++#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 ++#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 ++#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT9_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 ++ ++#define RTL8367C_REG_SCHEDULE_PORT10_APR_METER_CTRL0 0x03ce ++#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE4_APR_METER_OFFSET 12 ++#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE4_APR_METER_MASK 0x7000 ++#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE3_APR_METER_OFFSET 9 ++#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE3_APR_METER_MASK 0xE00 ++#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE2_APR_METER_OFFSET 6 ++#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE2_APR_METER_MASK 0x1C0 ++#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE1_APR_METER_OFFSET 3 ++#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE1_APR_METER_MASK 0x38 ++#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE0_APR_METER_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL0_QUEUE0_APR_METER_MASK 0x7 ++ ++#define RTL8367C_REG_SCHEDULE_PORT10_APR_METER_CTRL1 0x03cf ++#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE7_APR_METER_OFFSET 6 ++#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE7_APR_METER_MASK 0x1C0 ++#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE6_APR_METER_OFFSET 3 ++#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE6_APR_METER_MASK 0x38 ++#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE5_APR_METER_OFFSET 0 ++#define RTL8367C_SCHEDULE_PORT10_APR_METER_CTRL1_QUEUE5_APR_METER_MASK 0x7 ++ ++#define RTL8367C_REG_LINE_RATE_1G_L 0x03ec ++ ++#define RTL8367C_REG_LINE_RATE_1G_H 0x03ed ++#define RTL8367C_LINE_RATE_1G_H_OFFSET 0 ++#define RTL8367C_LINE_RATE_1G_H_MASK 0x1 ++ ++#define RTL8367C_REG_LINE_RATE_100_L 0x03ee ++ ++#define RTL8367C_REG_LINE_RATE_100_H 0x03ef ++#define RTL8367C_LINE_RATE_100_H_OFFSET 0 ++#define RTL8367C_LINE_RATE_100_H_MASK 0x1 ++ ++#define RTL8367C_REG_LINE_RATE_10_L 0x03f0 ++ ++#define RTL8367C_REG_LINE_RATE_10_H 0x03f1 ++#define RTL8367C_LINE_RATE_10_H_OFFSET 0 ++#define RTL8367C_LINE_RATE_10_H_MASK 0x1 ++ ++#define RTL8367C_REG_DUMMY_03f2 0x03f2 ++ ++#define RTL8367C_REG_DUMMY_03f3 0x03f3 ++ ++#define RTL8367C_REG_DUMMY_03f4 0x03f4 ++ ++#define RTL8367C_REG_DUMMY_03f5 0x03f5 ++ ++#define RTL8367C_REG_DUMMY_03f6 0x03f6 ++ ++#define RTL8367C_REG_BYPASS_LINE_RATE 0x03f7 ++#define RTL8367C_BYPASS_PORT10_CONSTRAINT_OFFSET 5 ++#define RTL8367C_BYPASS_PORT10_CONSTRAINT_MASK 0x20 ++#define RTL8367C_BYPASS_PORT9_CONSTRAINT_OFFSET 4 ++#define RTL8367C_BYPASS_PORT9_CONSTRAINT_MASK 0x10 ++#define RTL8367C_BYPASS_PORT8_CONSTRAINT_OFFSET 3 ++#define RTL8367C_BYPASS_PORT8_CONSTRAINT_MASK 0x8 ++#define RTL8367C_BYPASS_PORT7_CONSTRAINT_OFFSET 2 ++#define RTL8367C_BYPASS_PORT7_CONSTRAINT_MASK 0x4 ++#define RTL8367C_BYPASS_PORT6_CONSTRAINT_OFFSET 1 ++#define RTL8367C_BYPASS_PORT6_CONSTRAINT_MASK 0x2 ++#define RTL8367C_BYPASS_PORT5_CONSTRAINT_OFFSET 0 ++#define RTL8367C_BYPASS_PORT5_CONSTRAINT_MASK 0x1 ++ ++#define RTL8367C_REG_LINE_RATE_500_H 0x03f8 ++#define RTL8367C_LINE_RATE_500_H_OFFSET 0 ++#define RTL8367C_LINE_RATE_500_H_MASK 0x7 ++ ++#define RTL8367C_REG_LINE_RATE_500_L 0x03f9 ++ ++#define RTL8367C_REG_LINE_RATE_HSG_H 0x03fa ++#define RTL8367C_LINE_RATE_HSG_H_OFFSET 0 ++#define RTL8367C_LINE_RATE_HSG_H_MASK 0x7 ++ ++#define RTL8367C_REG_LINE_RATE_HSG_L 0x03fb ++ ++/* (16'h0500)table_reg */ ++ ++#define RTL8367C_REG_TABLE_ACCESS_CTRL 0x0500 ++#define RTL8367C_TABLE_ACCESS_CTRL_SPA_OFFSET 8 ++#define RTL8367C_TABLE_ACCESS_CTRL_SPA_MASK 0xF00 ++#define RTL8367C_ACCESS_METHOD_OFFSET 4 ++#define RTL8367C_ACCESS_METHOD_MASK 0x70 ++#define RTL8367C_COMMAND_TYPE_OFFSET 3 ++#define RTL8367C_COMMAND_TYPE_MASK 0x8 ++#define RTL8367C_TABLE_TYPE_OFFSET 0 ++#define RTL8367C_TABLE_TYPE_MASK 0x7 ++ ++#define RTL8367C_REG_TABLE_ACCESS_ADDR 0x0501 ++#define RTL8367C_TABLE_ACCESS_ADDR_OFFSET 0 ++#define RTL8367C_TABLE_ACCESS_ADDR_MASK 0x1FFF ++ ++#define RTL8367C_REG_TABLE_LUT_ADDR 0x0502 ++#define RTL8367C_ADDRESS2_OFFSET 14 ++#define RTL8367C_ADDRESS2_MASK 0x4000 ++#define RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET 13 ++#define RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_MASK 0x2000 ++#define RTL8367C_HIT_STATUS_OFFSET 12 ++#define RTL8367C_HIT_STATUS_MASK 0x1000 ++#define RTL8367C_TABLE_LUT_ADDR_TYPE_OFFSET 11 ++#define RTL8367C_TABLE_LUT_ADDR_TYPE_MASK 0x800 ++#define RTL8367C_TABLE_LUT_ADDR_ADDRESS_OFFSET 0 ++#define RTL8367C_TABLE_LUT_ADDR_ADDRESS_MASK 0x7FF ++ ++#define RTL8367C_REG_HSA_HSB_LATCH 0x0503 ++#define RTL8367C_LATCH_ALWAYS_OFFSET 15 ++#define RTL8367C_LATCH_ALWAYS_MASK 0x8000 ++#define RTL8367C_LATCH_FIRST_OFFSET 14 ++#define RTL8367C_LATCH_FIRST_MASK 0x4000 ++#define RTL8367C_SPA_EN_OFFSET 13 ++#define RTL8367C_SPA_EN_MASK 0x2000 ++#define RTL8367C_FORWARD_EN_OFFSET 12 ++#define RTL8367C_FORWARD_EN_MASK 0x1000 ++#define RTL8367C_REASON_EN_OFFSET 11 ++#define RTL8367C_REASON_EN_MASK 0x800 ++#define RTL8367C_HSA_HSB_LATCH_SPA_OFFSET 8 ++#define RTL8367C_HSA_HSB_LATCH_SPA_MASK 0x700 ++#define RTL8367C_FORWARD_OFFSET 6 ++#define RTL8367C_FORWARD_MASK 0xC0 ++#define RTL8367C_REASON_OFFSET 0 ++#define RTL8367C_REASON_MASK 0x3F ++ ++#define RTL8367C_REG_HSA_HSB_LATCH2 0x0504 ++#define RTL8367C_HSA_HSB_LATCH2_Reserved_OFFSET 1 ++#define RTL8367C_HSA_HSB_LATCH2_Reserved_MASK 0xFFFE ++#define RTL8367C_SPA2_OFFSET 0 ++#define RTL8367C_SPA2_MASK 0x1 ++ ++#define RTL8367C_REG_TABLE_WRITE_DATA0 0x0510 ++ ++#define RTL8367C_REG_TABLE_WRITE_DATA1 0x0511 ++ ++#define RTL8367C_REG_TABLE_WRITE_DATA2 0x0512 ++ ++#define RTL8367C_REG_TABLE_WRITE_DATA3 0x0513 ++ ++#define RTL8367C_REG_TABLE_WRITE_DATA4 0x0514 ++ ++#define RTL8367C_REG_TABLE_WRITE_DATA5 0x0515 ++ ++#define RTL8367C_REG_TABLE_WRITE_DATA6 0x0516 ++ ++#define RTL8367C_REG_TABLE_WRITE_DATA7 0x0517 ++ ++#define RTL8367C_REG_TABLE_WRITE_DATA8 0x0518 ++ ++#define RTL8367C_REG_TABLE_WRITE_DATA9 0x0519 ++#define RTL8367C_TABLE_WRITE_DATA9_OFFSET 0 ++#define RTL8367C_TABLE_WRITE_DATA9_MASK 0xF ++ ++#define RTL8367C_REG_TABLE_READ_DATA0 0x0520 ++ ++#define RTL8367C_REG_TABLE_READ_DATA1 0x0521 ++ ++#define RTL8367C_REG_TABLE_READ_DATA2 0x0522 ++ ++#define RTL8367C_REG_TABLE_READ_DATA3 0x0523 ++ ++#define RTL8367C_REG_TABLE_READ_DATA4 0x0524 ++ ++#define RTL8367C_REG_TABLE_READ_DATA5 0x0525 ++ ++#define RTL8367C_REG_TABLE_READ_DATA6 0x0526 ++ ++#define RTL8367C_REG_TABLE_READ_DATA7 0x0527 ++ ++#define RTL8367C_REG_TABLE_READ_DATA8 0x0528 ++ ++#define RTL8367C_REG_TABLE_READ_DATA9 0x0529 ++#define RTL8367C_TABLE_READ_DATA9_OFFSET 0 ++#define RTL8367C_TABLE_READ_DATA9_MASK 0xF ++ ++#define RTL8367C_REG_TBL_DUMMY00 0x0550 ++ ++#define RTL8367C_REG_TBL_DUMMY01 0x0551 ++ ++/* (16'h0600)acl_reg */ ++ ++#define RTL8367C_REG_ACL_RULE_TEMPLATE0_CTRL0 0x0600 ++#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL0_FIELD1_OFFSET 8 ++#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL0_FIELD1_MASK 0x7F00 ++#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL0_FIELD0_OFFSET 0 ++#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL0_FIELD0_MASK 0x7F ++ ++#define RTL8367C_REG_ACL_RULE_TEMPLATE0_CTRL1 0x0601 ++#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL1_FIELD3_OFFSET 8 ++#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL1_FIELD3_MASK 0x7F00 ++#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL1_FIELD2_OFFSET 0 ++#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL1_FIELD2_MASK 0x7F ++ ++#define RTL8367C_REG_ACL_RULE_TEMPLATE0_CTRL2 0x0602 ++#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL2_FIELD5_OFFSET 8 ++#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL2_FIELD5_MASK 0x7F00 ++#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL2_FIELD4_OFFSET 0 ++#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL2_FIELD4_MASK 0x7F ++ ++#define RTL8367C_REG_ACL_RULE_TEMPLATE0_CTRL3 0x0603 ++#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL3_FIELD7_OFFSET 8 ++#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL3_FIELD7_MASK 0x7F00 ++#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL3_FIELD6_OFFSET 0 ++#define RTL8367C_ACL_RULE_TEMPLATE0_CTRL3_FIELD6_MASK 0x7F ++ ++#define RTL8367C_REG_ACL_RULE_TEMPLATE1_CTRL0 0x0604 ++#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL0_FIELD1_OFFSET 8 ++#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL0_FIELD1_MASK 0x7F00 ++#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL0_FIELD0_OFFSET 0 ++#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL0_FIELD0_MASK 0x7F ++ ++#define RTL8367C_REG_ACL_RULE_TEMPLATE1_CTRL1 0x0605 ++#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL1_FIELD3_OFFSET 8 ++#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL1_FIELD3_MASK 0x7F00 ++#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL1_FIELD2_OFFSET 0 ++#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL1_FIELD2_MASK 0x7F ++ ++#define RTL8367C_REG_ACL_RULE_TEMPLATE1_CTRL2 0x0606 ++#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL2_FIELD5_OFFSET 8 ++#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL2_FIELD5_MASK 0x7F00 ++#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL2_FIELD4_OFFSET 0 ++#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL2_FIELD4_MASK 0x7F ++ ++#define RTL8367C_REG_ACL_RULE_TEMPLATE1_CTRL3 0x0607 ++#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL3_FIELD7_OFFSET 8 ++#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL3_FIELD7_MASK 0x7F00 ++#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL3_FIELD6_OFFSET 0 ++#define RTL8367C_ACL_RULE_TEMPLATE1_CTRL3_FIELD6_MASK 0x7F ++ ++#define RTL8367C_REG_ACL_RULE_TEMPLATE2_CTRL0 0x0608 ++#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL0_FIELD1_OFFSET 8 ++#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL0_FIELD1_MASK 0x7F00 ++#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL0_FIELD0_OFFSET 0 ++#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL0_FIELD0_MASK 0x7F ++ ++#define RTL8367C_REG_ACL_RULE_TEMPLATE2_CTRL1 0x0609 ++#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL1_FIELD3_OFFSET 8 ++#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL1_FIELD3_MASK 0x7F00 ++#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL1_FIELD2_OFFSET 0 ++#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL1_FIELD2_MASK 0x7F ++ ++#define RTL8367C_REG_ACL_RULE_TEMPLATE2_CTRL2 0x060a ++#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL2_FIELD5_OFFSET 8 ++#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL2_FIELD5_MASK 0x7F00 ++#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL2_FIELD4_OFFSET 0 ++#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL2_FIELD4_MASK 0x7F ++ ++#define RTL8367C_REG_ACL_RULE_TEMPLATE2_CTRL3 0x060b ++#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL3_FIELD7_OFFSET 8 ++#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL3_FIELD7_MASK 0x7F00 ++#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL3_FIELD6_OFFSET 0 ++#define RTL8367C_ACL_RULE_TEMPLATE2_CTRL3_FIELD6_MASK 0x7F ++ ++#define RTL8367C_REG_ACL_RULE_TEMPLATE3_CTRL0 0x060c ++#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL0_FIELD1_OFFSET 8 ++#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL0_FIELD1_MASK 0x7F00 ++#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL0_FIELD0_OFFSET 0 ++#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL0_FIELD0_MASK 0x7F ++ ++#define RTL8367C_REG_ACL_RULE_TEMPLATE3_CTRL1 0x060d ++#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL1_FIELD3_OFFSET 8 ++#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL1_FIELD3_MASK 0x7F00 ++#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL1_FIELD2_OFFSET 0 ++#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL1_FIELD2_MASK 0x7F ++ ++#define RTL8367C_REG_ACL_RULE_TEMPLATE3_CTRL2 0x060e ++#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL2_FIELD5_OFFSET 8 ++#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL2_FIELD5_MASK 0x7F00 ++#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL2_FIELD4_OFFSET 0 ++#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL2_FIELD4_MASK 0x7F ++ ++#define RTL8367C_REG_ACL_RULE_TEMPLATE3_CTRL3 0x060f ++#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL3_FIELD7_OFFSET 8 ++#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL3_FIELD7_MASK 0x7F00 ++#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL3_FIELD6_OFFSET 0 ++#define RTL8367C_ACL_RULE_TEMPLATE3_CTRL3_FIELD6_MASK 0x7F ++ ++#define RTL8367C_REG_ACL_RULE_TEMPLATE4_CTRL0 0x0610 ++#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL0_FIELD1_OFFSET 8 ++#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL0_FIELD1_MASK 0x7F00 ++#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL0_FIELD0_OFFSET 0 ++#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL0_FIELD0_MASK 0x7F ++ ++#define RTL8367C_REG_ACL_RULE_TEMPLATE4_CTRL1 0x0611 ++#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL1_FIELD3_OFFSET 8 ++#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL1_FIELD3_MASK 0x7F00 ++#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL1_FIELD2_OFFSET 0 ++#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL1_FIELD2_MASK 0x7F ++ ++#define RTL8367C_REG_ACL_RULE_TEMPLATE4_CTRL2 0x0612 ++#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL2_FIELD5_OFFSET 8 ++#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL2_FIELD5_MASK 0x7F00 ++#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL2_FIELD4_OFFSET 0 ++#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL2_FIELD4_MASK 0x7F ++ ++#define RTL8367C_REG_ACL_RULE_TEMPLATE4_CTRL3 0x0613 ++#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL3_FIELD7_OFFSET 8 ++#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL3_FIELD7_MASK 0x7F00 ++#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL3_FIELD6_OFFSET 0 ++#define RTL8367C_ACL_RULE_TEMPLATE4_CTRL3_FIELD6_MASK 0x7F ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL0 0x0614 ++#define RTL8367C_OP1_NOT_OFFSET 14 ++#define RTL8367C_OP1_NOT_MASK 0x4000 ++#define RTL8367C_ACT1_GPIO_OFFSET 13 ++#define RTL8367C_ACT1_GPIO_MASK 0x2000 ++#define RTL8367C_ACT1_FORWARD_OFFSET 12 ++#define RTL8367C_ACT1_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT1_POLICING_OFFSET 11 ++#define RTL8367C_ACT1_POLICING_MASK 0x800 ++#define RTL8367C_ACT1_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT1_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT1_SVID_OFFSET 9 ++#define RTL8367C_ACT1_SVID_MASK 0x200 ++#define RTL8367C_ACT1_CVID_OFFSET 8 ++#define RTL8367C_ACT1_CVID_MASK 0x100 ++#define RTL8367C_OP0_NOT_OFFSET 6 ++#define RTL8367C_OP0_NOT_MASK 0x40 ++#define RTL8367C_ACT0_GPIO_OFFSET 5 ++#define RTL8367C_ACT0_GPIO_MASK 0x20 ++#define RTL8367C_ACT0_FORWARD_OFFSET 4 ++#define RTL8367C_ACT0_FORWARD_MASK 0x10 ++#define RTL8367C_ACT0_POLICING_OFFSET 3 ++#define RTL8367C_ACT0_POLICING_MASK 0x8 ++#define RTL8367C_ACT0_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT0_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT0_SVID_OFFSET 1 ++#define RTL8367C_ACT0_SVID_MASK 0x2 ++#define RTL8367C_ACT0_CVID_OFFSET 0 ++#define RTL8367C_ACT0_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL1 0x0615 ++#define RTL8367C_OP3_NOT_OFFSET 14 ++#define RTL8367C_OP3_NOT_MASK 0x4000 ++#define RTL8367C_ACT3_GPIO_OFFSET 13 ++#define RTL8367C_ACT3_GPIO_MASK 0x2000 ++#define RTL8367C_ACT3_FORWARD_OFFSET 12 ++#define RTL8367C_ACT3_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT3_POLICING_OFFSET 11 ++#define RTL8367C_ACT3_POLICING_MASK 0x800 ++#define RTL8367C_ACT3_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT3_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT3_SVID_OFFSET 9 ++#define RTL8367C_ACT3_SVID_MASK 0x200 ++#define RTL8367C_ACT3_CVID_OFFSET 8 ++#define RTL8367C_ACT3_CVID_MASK 0x100 ++#define RTL8367C_OP2_NOT_OFFSET 6 ++#define RTL8367C_OP2_NOT_MASK 0x40 ++#define RTL8367C_ACT2_GPIO_OFFSET 5 ++#define RTL8367C_ACT2_GPIO_MASK 0x20 ++#define RTL8367C_ACT2_FORWARD_OFFSET 4 ++#define RTL8367C_ACT2_FORWARD_MASK 0x10 ++#define RTL8367C_ACT2_POLICING_OFFSET 3 ++#define RTL8367C_ACT2_POLICING_MASK 0x8 ++#define RTL8367C_ACT2_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT2_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT2_SVID_OFFSET 1 ++#define RTL8367C_ACT2_SVID_MASK 0x2 ++#define RTL8367C_ACT2_CVID_OFFSET 0 ++#define RTL8367C_ACT2_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL2 0x0616 ++#define RTL8367C_OP5_NOT_OFFSET 14 ++#define RTL8367C_OP5_NOT_MASK 0x4000 ++#define RTL8367C_ACT5_GPIO_OFFSET 13 ++#define RTL8367C_ACT5_GPIO_MASK 0x2000 ++#define RTL8367C_ACT5_FORWARD_OFFSET 12 ++#define RTL8367C_ACT5_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT5_POLICING_OFFSET 11 ++#define RTL8367C_ACT5_POLICING_MASK 0x800 ++#define RTL8367C_ACT5_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT5_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT5_SVID_OFFSET 9 ++#define RTL8367C_ACT5_SVID_MASK 0x200 ++#define RTL8367C_ACT5_CVID_OFFSET 8 ++#define RTL8367C_ACT5_CVID_MASK 0x100 ++#define RTL8367C_OP4_NOT_OFFSET 6 ++#define RTL8367C_OP4_NOT_MASK 0x40 ++#define RTL8367C_ACT4_GPIO_OFFSET 5 ++#define RTL8367C_ACT4_GPIO_MASK 0x20 ++#define RTL8367C_ACT4_FORWARD_OFFSET 4 ++#define RTL8367C_ACT4_FORWARD_MASK 0x10 ++#define RTL8367C_ACT4_POLICING_OFFSET 3 ++#define RTL8367C_ACT4_POLICING_MASK 0x8 ++#define RTL8367C_ACT4_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT4_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT4_SVID_OFFSET 1 ++#define RTL8367C_ACT4_SVID_MASK 0x2 ++#define RTL8367C_ACT4_CVID_OFFSET 0 ++#define RTL8367C_ACT4_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL3 0x0617 ++#define RTL8367C_OP7_NOT_OFFSET 14 ++#define RTL8367C_OP7_NOT_MASK 0x4000 ++#define RTL8367C_ACT7_GPIO_OFFSET 13 ++#define RTL8367C_ACT7_GPIO_MASK 0x2000 ++#define RTL8367C_ACT7_FORWARD_OFFSET 12 ++#define RTL8367C_ACT7_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT7_POLICING_OFFSET 11 ++#define RTL8367C_ACT7_POLICING_MASK 0x800 ++#define RTL8367C_ACT7_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT7_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT7_SVID_OFFSET 9 ++#define RTL8367C_ACT7_SVID_MASK 0x200 ++#define RTL8367C_ACT7_CVID_OFFSET 8 ++#define RTL8367C_ACT7_CVID_MASK 0x100 ++#define RTL8367C_OP6_NOT_OFFSET 6 ++#define RTL8367C_OP6_NOT_MASK 0x40 ++#define RTL8367C_ACT6_GPIO_OFFSET 5 ++#define RTL8367C_ACT6_GPIO_MASK 0x20 ++#define RTL8367C_ACT6_FORWARD_OFFSET 4 ++#define RTL8367C_ACT6_FORWARD_MASK 0x10 ++#define RTL8367C_ACT6_POLICING_OFFSET 3 ++#define RTL8367C_ACT6_POLICING_MASK 0x8 ++#define RTL8367C_ACT6_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT6_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT6_SVID_OFFSET 1 ++#define RTL8367C_ACT6_SVID_MASK 0x2 ++#define RTL8367C_ACT6_CVID_OFFSET 0 ++#define RTL8367C_ACT6_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL4 0x0618 ++#define RTL8367C_OP9_NOT_OFFSET 14 ++#define RTL8367C_OP9_NOT_MASK 0x4000 ++#define RTL8367C_ACT9_GPIO_OFFSET 13 ++#define RTL8367C_ACT9_GPIO_MASK 0x2000 ++#define RTL8367C_ACT9_FORWARD_OFFSET 12 ++#define RTL8367C_ACT9_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT9_POLICING_OFFSET 11 ++#define RTL8367C_ACT9_POLICING_MASK 0x800 ++#define RTL8367C_ACT9_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT9_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT9_SVID_OFFSET 9 ++#define RTL8367C_ACT9_SVID_MASK 0x200 ++#define RTL8367C_ACT9_CVID_OFFSET 8 ++#define RTL8367C_ACT9_CVID_MASK 0x100 ++#define RTL8367C_OP8_NOT_OFFSET 6 ++#define RTL8367C_OP8_NOT_MASK 0x40 ++#define RTL8367C_ACT8_GPIO_OFFSET 5 ++#define RTL8367C_ACT8_GPIO_MASK 0x20 ++#define RTL8367C_ACT8_FORWARD_OFFSET 4 ++#define RTL8367C_ACT8_FORWARD_MASK 0x10 ++#define RTL8367C_ACT8_POLICING_OFFSET 3 ++#define RTL8367C_ACT8_POLICING_MASK 0x8 ++#define RTL8367C_ACT8_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT8_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT8_SVID_OFFSET 1 ++#define RTL8367C_ACT8_SVID_MASK 0x2 ++#define RTL8367C_ACT8_CVID_OFFSET 0 ++#define RTL8367C_ACT8_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL5 0x0619 ++#define RTL8367C_OP11_NOT_OFFSET 14 ++#define RTL8367C_OP11_NOT_MASK 0x4000 ++#define RTL8367C_ACT11_GPIO_OFFSET 13 ++#define RTL8367C_ACT11_GPIO_MASK 0x2000 ++#define RTL8367C_ACT11_FORWARD_OFFSET 12 ++#define RTL8367C_ACT11_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT11_POLICING_OFFSET 11 ++#define RTL8367C_ACT11_POLICING_MASK 0x800 ++#define RTL8367C_ACT11_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT11_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT11_SVID_OFFSET 9 ++#define RTL8367C_ACT11_SVID_MASK 0x200 ++#define RTL8367C_ACT11_CVID_OFFSET 8 ++#define RTL8367C_ACT11_CVID_MASK 0x100 ++#define RTL8367C_OP10_NOT_OFFSET 6 ++#define RTL8367C_OP10_NOT_MASK 0x40 ++#define RTL8367C_ACT10_GPIO_OFFSET 5 ++#define RTL8367C_ACT10_GPIO_MASK 0x20 ++#define RTL8367C_ACT10_FORWARD_OFFSET 4 ++#define RTL8367C_ACT10_FORWARD_MASK 0x10 ++#define RTL8367C_ACT10_POLICING_OFFSET 3 ++#define RTL8367C_ACT10_POLICING_MASK 0x8 ++#define RTL8367C_ACT10_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT10_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT10_SVID_OFFSET 1 ++#define RTL8367C_ACT10_SVID_MASK 0x2 ++#define RTL8367C_ACT10_CVID_OFFSET 0 ++#define RTL8367C_ACT10_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL6 0x061a ++#define RTL8367C_OP13_NOT_OFFSET 14 ++#define RTL8367C_OP13_NOT_MASK 0x4000 ++#define RTL8367C_ACT13_GPIO_OFFSET 13 ++#define RTL8367C_ACT13_GPIO_MASK 0x2000 ++#define RTL8367C_ACT13_FORWARD_OFFSET 12 ++#define RTL8367C_ACT13_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT13_POLICING_OFFSET 11 ++#define RTL8367C_ACT13_POLICING_MASK 0x800 ++#define RTL8367C_ACT13_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT13_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT13_SVID_OFFSET 9 ++#define RTL8367C_ACT13_SVID_MASK 0x200 ++#define RTL8367C_ACT13_CVID_OFFSET 8 ++#define RTL8367C_ACT13_CVID_MASK 0x100 ++#define RTL8367C_OP12_NOT_OFFSET 6 ++#define RTL8367C_OP12_NOT_MASK 0x40 ++#define RTL8367C_ACT12_GPIO_OFFSET 5 ++#define RTL8367C_ACT12_GPIO_MASK 0x20 ++#define RTL8367C_ACT12_FORWARD_OFFSET 4 ++#define RTL8367C_ACT12_FORWARD_MASK 0x10 ++#define RTL8367C_ACT12_POLICING_OFFSET 3 ++#define RTL8367C_ACT12_POLICING_MASK 0x8 ++#define RTL8367C_ACT12_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT12_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT12_SVID_OFFSET 1 ++#define RTL8367C_ACT12_SVID_MASK 0x2 ++#define RTL8367C_ACT12_CVID_OFFSET 0 ++#define RTL8367C_ACT12_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL7 0x061b ++#define RTL8367C_OP15_NOT_OFFSET 14 ++#define RTL8367C_OP15_NOT_MASK 0x4000 ++#define RTL8367C_ACT15_GPIO_OFFSET 13 ++#define RTL8367C_ACT15_GPIO_MASK 0x2000 ++#define RTL8367C_ACT15_FORWARD_OFFSET 12 ++#define RTL8367C_ACT15_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT15_POLICING_OFFSET 11 ++#define RTL8367C_ACT15_POLICING_MASK 0x800 ++#define RTL8367C_ACT15_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT15_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT15_SVID_OFFSET 9 ++#define RTL8367C_ACT15_SVID_MASK 0x200 ++#define RTL8367C_ACT15_CVID_OFFSET 8 ++#define RTL8367C_ACT15_CVID_MASK 0x100 ++#define RTL8367C_OP14_NOT_OFFSET 6 ++#define RTL8367C_OP14_NOT_MASK 0x40 ++#define RTL8367C_ACT14_GPIO_OFFSET 5 ++#define RTL8367C_ACT14_GPIO_MASK 0x20 ++#define RTL8367C_ACT14_FORWARD_OFFSET 4 ++#define RTL8367C_ACT14_FORWARD_MASK 0x10 ++#define RTL8367C_ACT14_POLICING_OFFSET 3 ++#define RTL8367C_ACT14_POLICING_MASK 0x8 ++#define RTL8367C_ACT14_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT14_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT14_SVID_OFFSET 1 ++#define RTL8367C_ACT14_SVID_MASK 0x2 ++#define RTL8367C_ACT14_CVID_OFFSET 0 ++#define RTL8367C_ACT14_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL8 0x061c ++#define RTL8367C_OP17_NOT_OFFSET 14 ++#define RTL8367C_OP17_NOT_MASK 0x4000 ++#define RTL8367C_ACT17_GPIO_OFFSET 13 ++#define RTL8367C_ACT17_GPIO_MASK 0x2000 ++#define RTL8367C_ACT17_FORWARD_OFFSET 12 ++#define RTL8367C_ACT17_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT17_POLICING_OFFSET 11 ++#define RTL8367C_ACT17_POLICING_MASK 0x800 ++#define RTL8367C_ACT17_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT17_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT17_SVID_OFFSET 9 ++#define RTL8367C_ACT17_SVID_MASK 0x200 ++#define RTL8367C_ACT17_CVID_OFFSET 8 ++#define RTL8367C_ACT17_CVID_MASK 0x100 ++#define RTL8367C_OP16_NOT_OFFSET 6 ++#define RTL8367C_OP16_NOT_MASK 0x40 ++#define RTL8367C_ACT16_GPIO_OFFSET 5 ++#define RTL8367C_ACT16_GPIO_MASK 0x20 ++#define RTL8367C_ACT16_FORWARD_OFFSET 4 ++#define RTL8367C_ACT16_FORWARD_MASK 0x10 ++#define RTL8367C_ACT16_POLICING_OFFSET 3 ++#define RTL8367C_ACT16_POLICING_MASK 0x8 ++#define RTL8367C_ACT16_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT16_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT16_SVID_OFFSET 1 ++#define RTL8367C_ACT16_SVID_MASK 0x2 ++#define RTL8367C_ACT16_CVID_OFFSET 0 ++#define RTL8367C_ACT16_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL9 0x061d ++#define RTL8367C_OP19_NOT_OFFSET 14 ++#define RTL8367C_OP19_NOT_MASK 0x4000 ++#define RTL8367C_ACT19_GPIO_OFFSET 13 ++#define RTL8367C_ACT19_GPIO_MASK 0x2000 ++#define RTL8367C_ACT19_FORWARD_OFFSET 12 ++#define RTL8367C_ACT19_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT19_POLICING_OFFSET 11 ++#define RTL8367C_ACT19_POLICING_MASK 0x800 ++#define RTL8367C_ACT19_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT19_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT19_SVID_OFFSET 9 ++#define RTL8367C_ACT19_SVID_MASK 0x200 ++#define RTL8367C_ACT19_CVID_OFFSET 8 ++#define RTL8367C_ACT19_CVID_MASK 0x100 ++#define RTL8367C_OP18_NOT_OFFSET 6 ++#define RTL8367C_OP18_NOT_MASK 0x40 ++#define RTL8367C_ACT18_GPIO_OFFSET 5 ++#define RTL8367C_ACT18_GPIO_MASK 0x20 ++#define RTL8367C_ACT18_FORWARD_OFFSET 4 ++#define RTL8367C_ACT18_FORWARD_MASK 0x10 ++#define RTL8367C_ACT18_POLICING_OFFSET 3 ++#define RTL8367C_ACT18_POLICING_MASK 0x8 ++#define RTL8367C_ACT18_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT18_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT18_SVID_OFFSET 1 ++#define RTL8367C_ACT18_SVID_MASK 0x2 ++#define RTL8367C_ACT18_CVID_OFFSET 0 ++#define RTL8367C_ACT18_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL10 0x061e ++#define RTL8367C_OP21_NOT_OFFSET 14 ++#define RTL8367C_OP21_NOT_MASK 0x4000 ++#define RTL8367C_ACT21_GPIO_OFFSET 13 ++#define RTL8367C_ACT21_GPIO_MASK 0x2000 ++#define RTL8367C_ACT21_FORWARD_OFFSET 12 ++#define RTL8367C_ACT21_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT21_POLICING_OFFSET 11 ++#define RTL8367C_ACT21_POLICING_MASK 0x800 ++#define RTL8367C_ACT21_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT21_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT21_SVID_OFFSET 9 ++#define RTL8367C_ACT21_SVID_MASK 0x200 ++#define RTL8367C_ACT21_CVID_OFFSET 8 ++#define RTL8367C_ACT21_CVID_MASK 0x100 ++#define RTL8367C_OP20_NOT_OFFSET 6 ++#define RTL8367C_OP20_NOT_MASK 0x40 ++#define RTL8367C_ACT20_GPIO_OFFSET 5 ++#define RTL8367C_ACT20_GPIO_MASK 0x20 ++#define RTL8367C_ACT20_FORWARD_OFFSET 4 ++#define RTL8367C_ACT20_FORWARD_MASK 0x10 ++#define RTL8367C_ACT20_POLICING_OFFSET 3 ++#define RTL8367C_ACT20_POLICING_MASK 0x8 ++#define RTL8367C_ACT20_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT20_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT20_SVID_OFFSET 1 ++#define RTL8367C_ACT20_SVID_MASK 0x2 ++#define RTL8367C_ACT20_CVID_OFFSET 0 ++#define RTL8367C_ACT20_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL11 0x061f ++#define RTL8367C_OP23_NOT_OFFSET 14 ++#define RTL8367C_OP23_NOT_MASK 0x4000 ++#define RTL8367C_ACT23_GPIO_OFFSET 13 ++#define RTL8367C_ACT23_GPIO_MASK 0x2000 ++#define RTL8367C_ACT23_FORWARD_OFFSET 12 ++#define RTL8367C_ACT23_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT23_POLICING_OFFSET 11 ++#define RTL8367C_ACT23_POLICING_MASK 0x800 ++#define RTL8367C_ACT23_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT23_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT23_SVID_OFFSET 9 ++#define RTL8367C_ACT23_SVID_MASK 0x200 ++#define RTL8367C_ACT23_CVID_OFFSET 8 ++#define RTL8367C_ACT23_CVID_MASK 0x100 ++#define RTL8367C_OP22_NOT_OFFSET 6 ++#define RTL8367C_OP22_NOT_MASK 0x40 ++#define RTL8367C_ACT22_GPIO_OFFSET 5 ++#define RTL8367C_ACT22_GPIO_MASK 0x20 ++#define RTL8367C_ACT22_FORWARD_OFFSET 4 ++#define RTL8367C_ACT22_FORWARD_MASK 0x10 ++#define RTL8367C_ACT22_POLICING_OFFSET 3 ++#define RTL8367C_ACT22_POLICING_MASK 0x8 ++#define RTL8367C_ACT22_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT22_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT22_SVID_OFFSET 1 ++#define RTL8367C_ACT22_SVID_MASK 0x2 ++#define RTL8367C_ACT22_CVID_OFFSET 0 ++#define RTL8367C_ACT22_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL12 0x0620 ++#define RTL8367C_OP25_NOT_OFFSET 14 ++#define RTL8367C_OP25_NOT_MASK 0x4000 ++#define RTL8367C_ACT25_GPIO_OFFSET 13 ++#define RTL8367C_ACT25_GPIO_MASK 0x2000 ++#define RTL8367C_ACT25_FORWARD_OFFSET 12 ++#define RTL8367C_ACT25_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT25_POLICING_OFFSET 11 ++#define RTL8367C_ACT25_POLICING_MASK 0x800 ++#define RTL8367C_ACT25_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT25_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT25_SVID_OFFSET 9 ++#define RTL8367C_ACT25_SVID_MASK 0x200 ++#define RTL8367C_ACT25_CVID_OFFSET 8 ++#define RTL8367C_ACT25_CVID_MASK 0x100 ++#define RTL8367C_OP24_NOT_OFFSET 6 ++#define RTL8367C_OP24_NOT_MASK 0x40 ++#define RTL8367C_ACT24_GPIO_OFFSET 5 ++#define RTL8367C_ACT24_GPIO_MASK 0x20 ++#define RTL8367C_ACT24_FORWARD_OFFSET 4 ++#define RTL8367C_ACT24_FORWARD_MASK 0x10 ++#define RTL8367C_ACT24_POLICING_OFFSET 3 ++#define RTL8367C_ACT24_POLICING_MASK 0x8 ++#define RTL8367C_ACT24_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT24_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT24_SVID_OFFSET 1 ++#define RTL8367C_ACT24_SVID_MASK 0x2 ++#define RTL8367C_ACT24_CVID_OFFSET 0 ++#define RTL8367C_ACT24_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL13 0x0621 ++#define RTL8367C_OP27_NOT_OFFSET 14 ++#define RTL8367C_OP27_NOT_MASK 0x4000 ++#define RTL8367C_ACT27_GPIO_OFFSET 13 ++#define RTL8367C_ACT27_GPIO_MASK 0x2000 ++#define RTL8367C_ACT27_FORWARD_OFFSET 12 ++#define RTL8367C_ACT27_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT27_POLICING_OFFSET 11 ++#define RTL8367C_ACT27_POLICING_MASK 0x800 ++#define RTL8367C_ACT27_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT27_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT27_SVID_OFFSET 9 ++#define RTL8367C_ACT27_SVID_MASK 0x200 ++#define RTL8367C_ACT27_CVID_OFFSET 8 ++#define RTL8367C_ACT27_CVID_MASK 0x100 ++#define RTL8367C_OP26_NOT_OFFSET 6 ++#define RTL8367C_OP26_NOT_MASK 0x40 ++#define RTL8367C_ACT26_GPIO_OFFSET 5 ++#define RTL8367C_ACT26_GPIO_MASK 0x20 ++#define RTL8367C_ACT26_FORWARD_OFFSET 4 ++#define RTL8367C_ACT26_FORWARD_MASK 0x10 ++#define RTL8367C_ACT26_POLICING_OFFSET 3 ++#define RTL8367C_ACT26_POLICING_MASK 0x8 ++#define RTL8367C_ACT26_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT26_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT26_SVID_OFFSET 1 ++#define RTL8367C_ACT26_SVID_MASK 0x2 ++#define RTL8367C_ACT26_CVID_OFFSET 0 ++#define RTL8367C_ACT26_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL14 0x0622 ++#define RTL8367C_OP29_NOT_OFFSET 14 ++#define RTL8367C_OP29_NOT_MASK 0x4000 ++#define RTL8367C_ACT29_GPIO_OFFSET 13 ++#define RTL8367C_ACT29_GPIO_MASK 0x2000 ++#define RTL8367C_ACT29_FORWARD_OFFSET 12 ++#define RTL8367C_ACT29_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT29_POLICING_OFFSET 11 ++#define RTL8367C_ACT29_POLICING_MASK 0x800 ++#define RTL8367C_ACT29_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT29_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT29_SVID_OFFSET 9 ++#define RTL8367C_ACT29_SVID_MASK 0x200 ++#define RTL8367C_ACT29_CVID_OFFSET 8 ++#define RTL8367C_ACT29_CVID_MASK 0x100 ++#define RTL8367C_OP28_NOT_OFFSET 6 ++#define RTL8367C_OP28_NOT_MASK 0x40 ++#define RTL8367C_ACT28_GPIO_OFFSET 5 ++#define RTL8367C_ACT28_GPIO_MASK 0x20 ++#define RTL8367C_ACT28_FORWARD_OFFSET 4 ++#define RTL8367C_ACT28_FORWARD_MASK 0x10 ++#define RTL8367C_ACT28_POLICING_OFFSET 3 ++#define RTL8367C_ACT28_POLICING_MASK 0x8 ++#define RTL8367C_ACT28_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT28_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT28_SVID_OFFSET 1 ++#define RTL8367C_ACT28_SVID_MASK 0x2 ++#define RTL8367C_ACT28_CVID_OFFSET 0 ++#define RTL8367C_ACT28_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL15 0x0623 ++#define RTL8367C_OP31_NOT_OFFSET 14 ++#define RTL8367C_OP31_NOT_MASK 0x4000 ++#define RTL8367C_ACT31_GPIO_OFFSET 13 ++#define RTL8367C_ACT31_GPIO_MASK 0x2000 ++#define RTL8367C_ACT31_FORWARD_OFFSET 12 ++#define RTL8367C_ACT31_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT31_POLICING_OFFSET 11 ++#define RTL8367C_ACT31_POLICING_MASK 0x800 ++#define RTL8367C_ACT31_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT31_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT31_SVID_OFFSET 9 ++#define RTL8367C_ACT31_SVID_MASK 0x200 ++#define RTL8367C_ACT31_CVID_OFFSET 8 ++#define RTL8367C_ACT31_CVID_MASK 0x100 ++#define RTL8367C_OP30_NOT_OFFSET 6 ++#define RTL8367C_OP30_NOT_MASK 0x40 ++#define RTL8367C_ACT30_GPIO_OFFSET 5 ++#define RTL8367C_ACT30_GPIO_MASK 0x20 ++#define RTL8367C_ACT30_FORWARD_OFFSET 4 ++#define RTL8367C_ACT30_FORWARD_MASK 0x10 ++#define RTL8367C_ACT30_POLICING_OFFSET 3 ++#define RTL8367C_ACT30_POLICING_MASK 0x8 ++#define RTL8367C_ACT30_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT30_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT30_SVID_OFFSET 1 ++#define RTL8367C_ACT30_SVID_MASK 0x2 ++#define RTL8367C_ACT30_CVID_OFFSET 0 ++#define RTL8367C_ACT30_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL16 0x0624 ++#define RTL8367C_OP33_NOT_OFFSET 14 ++#define RTL8367C_OP33_NOT_MASK 0x4000 ++#define RTL8367C_ACT33_GPIO_OFFSET 13 ++#define RTL8367C_ACT33_GPIO_MASK 0x2000 ++#define RTL8367C_ACT33_FORWARD_OFFSET 12 ++#define RTL8367C_ACT33_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT33_POLICING_OFFSET 11 ++#define RTL8367C_ACT33_POLICING_MASK 0x800 ++#define RTL8367C_ACT33_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT33_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT33_SVID_OFFSET 9 ++#define RTL8367C_ACT33_SVID_MASK 0x200 ++#define RTL8367C_ACT33_CVID_OFFSET 8 ++#define RTL8367C_ACT33_CVID_MASK 0x100 ++#define RTL8367C_OP32_NOT_OFFSET 6 ++#define RTL8367C_OP32_NOT_MASK 0x40 ++#define RTL8367C_ACT32_GPIO_OFFSET 5 ++#define RTL8367C_ACT32_GPIO_MASK 0x20 ++#define RTL8367C_ACT32_FORWARD_OFFSET 4 ++#define RTL8367C_ACT32_FORWARD_MASK 0x10 ++#define RTL8367C_ACT32_POLICING_OFFSET 3 ++#define RTL8367C_ACT32_POLICING_MASK 0x8 ++#define RTL8367C_ACT32_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT32_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT32_SVID_OFFSET 1 ++#define RTL8367C_ACT32_SVID_MASK 0x2 ++#define RTL8367C_ACT32_CVID_OFFSET 0 ++#define RTL8367C_ACT32_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL17 0x0625 ++#define RTL8367C_OP35_NOT_OFFSET 14 ++#define RTL8367C_OP35_NOT_MASK 0x4000 ++#define RTL8367C_ACT35_GPIO_OFFSET 13 ++#define RTL8367C_ACT35_GPIO_MASK 0x2000 ++#define RTL8367C_ACT35_FORWARD_OFFSET 12 ++#define RTL8367C_ACT35_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT35_POLICING_OFFSET 11 ++#define RTL8367C_ACT35_POLICING_MASK 0x800 ++#define RTL8367C_ACT35_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT35_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT35_SVID_OFFSET 9 ++#define RTL8367C_ACT35_SVID_MASK 0x200 ++#define RTL8367C_ACT35_CVID_OFFSET 8 ++#define RTL8367C_ACT35_CVID_MASK 0x100 ++#define RTL8367C_OP34_NOT_OFFSET 6 ++#define RTL8367C_OP34_NOT_MASK 0x40 ++#define RTL8367C_ACT34_GPIO_OFFSET 5 ++#define RTL8367C_ACT34_GPIO_MASK 0x20 ++#define RTL8367C_ACT34_FORWARD_OFFSET 4 ++#define RTL8367C_ACT34_FORWARD_MASK 0x10 ++#define RTL8367C_ACT34_POLICING_OFFSET 3 ++#define RTL8367C_ACT34_POLICING_MASK 0x8 ++#define RTL8367C_ACT34_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT34_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT34_SVID_OFFSET 1 ++#define RTL8367C_ACT34_SVID_MASK 0x2 ++#define RTL8367C_ACT34_CVID_OFFSET 0 ++#define RTL8367C_ACT34_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL18 0x0626 ++#define RTL8367C_OP37_NOT_OFFSET 14 ++#define RTL8367C_OP37_NOT_MASK 0x4000 ++#define RTL8367C_ACT37_GPIO_OFFSET 13 ++#define RTL8367C_ACT37_GPIO_MASK 0x2000 ++#define RTL8367C_ACT37_FORWARD_OFFSET 12 ++#define RTL8367C_ACT37_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT37_POLICING_OFFSET 11 ++#define RTL8367C_ACT37_POLICING_MASK 0x800 ++#define RTL8367C_ACT37_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT37_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT37_SVID_OFFSET 9 ++#define RTL8367C_ACT37_SVID_MASK 0x200 ++#define RTL8367C_ACT37_CVID_OFFSET 8 ++#define RTL8367C_ACT37_CVID_MASK 0x100 ++#define RTL8367C_OP36_NOT_OFFSET 6 ++#define RTL8367C_OP36_NOT_MASK 0x40 ++#define RTL8367C_ACT36_GPIO_OFFSET 5 ++#define RTL8367C_ACT36_GPIO_MASK 0x20 ++#define RTL8367C_ACT36_FORWARD_OFFSET 4 ++#define RTL8367C_ACT36_FORWARD_MASK 0x10 ++#define RTL8367C_ACT36_POLICING_OFFSET 3 ++#define RTL8367C_ACT36_POLICING_MASK 0x8 ++#define RTL8367C_ACT36_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT36_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT36_SVID_OFFSET 1 ++#define RTL8367C_ACT36_SVID_MASK 0x2 ++#define RTL8367C_ACT36_CVID_OFFSET 0 ++#define RTL8367C_ACT36_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL19 0x0627 ++#define RTL8367C_OP39_NOT_OFFSET 14 ++#define RTL8367C_OP39_NOT_MASK 0x4000 ++#define RTL8367C_ACT39_GPIO_OFFSET 13 ++#define RTL8367C_ACT39_GPIO_MASK 0x2000 ++#define RTL8367C_ACT39_FORWARD_OFFSET 12 ++#define RTL8367C_ACT39_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT39_POLICING_OFFSET 11 ++#define RTL8367C_ACT39_POLICING_MASK 0x800 ++#define RTL8367C_ACT39_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT39_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT39_SVID_OFFSET 9 ++#define RTL8367C_ACT39_SVID_MASK 0x200 ++#define RTL8367C_ACT39_CVID_OFFSET 8 ++#define RTL8367C_ACT39_CVID_MASK 0x100 ++#define RTL8367C_OP38_NOT_OFFSET 6 ++#define RTL8367C_OP38_NOT_MASK 0x40 ++#define RTL8367C_ACT38_GPIO_OFFSET 5 ++#define RTL8367C_ACT38_GPIO_MASK 0x20 ++#define RTL8367C_ACT38_FORWARD_OFFSET 4 ++#define RTL8367C_ACT38_FORWARD_MASK 0x10 ++#define RTL8367C_ACT38_POLICING_OFFSET 3 ++#define RTL8367C_ACT38_POLICING_MASK 0x8 ++#define RTL8367C_ACT38_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT38_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT38_SVID_OFFSET 1 ++#define RTL8367C_ACT38_SVID_MASK 0x2 ++#define RTL8367C_ACT38_CVID_OFFSET 0 ++#define RTL8367C_ACT38_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL20 0x0628 ++#define RTL8367C_OP41_NOT_OFFSET 14 ++#define RTL8367C_OP41_NOT_MASK 0x4000 ++#define RTL8367C_ACT41_GPIO_OFFSET 13 ++#define RTL8367C_ACT41_GPIO_MASK 0x2000 ++#define RTL8367C_ACT41_FORWARD_OFFSET 12 ++#define RTL8367C_ACT41_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT41_POLICING_OFFSET 11 ++#define RTL8367C_ACT41_POLICING_MASK 0x800 ++#define RTL8367C_ACT41_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT41_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT41_SVID_OFFSET 9 ++#define RTL8367C_ACT41_SVID_MASK 0x200 ++#define RTL8367C_ACT41_CVID_OFFSET 8 ++#define RTL8367C_ACT41_CVID_MASK 0x100 ++#define RTL8367C_OP40_NOT_OFFSET 6 ++#define RTL8367C_OP40_NOT_MASK 0x40 ++#define RTL8367C_ACT40_GPIO_OFFSET 5 ++#define RTL8367C_ACT40_GPIO_MASK 0x20 ++#define RTL8367C_ACT40_FORWARD_OFFSET 4 ++#define RTL8367C_ACT40_FORWARD_MASK 0x10 ++#define RTL8367C_ACT40_POLICING_OFFSET 3 ++#define RTL8367C_ACT40_POLICING_MASK 0x8 ++#define RTL8367C_ACT40_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT40_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT40_SVID_OFFSET 1 ++#define RTL8367C_ACT40_SVID_MASK 0x2 ++#define RTL8367C_ACT40_CVID_OFFSET 0 ++#define RTL8367C_ACT40_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL21 0x0629 ++#define RTL8367C_OP43_NOT_OFFSET 14 ++#define RTL8367C_OP43_NOT_MASK 0x4000 ++#define RTL8367C_ACT43_GPIO_OFFSET 13 ++#define RTL8367C_ACT43_GPIO_MASK 0x2000 ++#define RTL8367C_ACT43_FORWARD_OFFSET 12 ++#define RTL8367C_ACT43_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT43_POLICING_OFFSET 11 ++#define RTL8367C_ACT43_POLICING_MASK 0x800 ++#define RTL8367C_ACT43_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT43_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT43_SVID_OFFSET 9 ++#define RTL8367C_ACT43_SVID_MASK 0x200 ++#define RTL8367C_ACT43_CVID_OFFSET 8 ++#define RTL8367C_ACT43_CVID_MASK 0x100 ++#define RTL8367C_OP42_NOT_OFFSET 6 ++#define RTL8367C_OP42_NOT_MASK 0x40 ++#define RTL8367C_ACT42_GPIO_OFFSET 5 ++#define RTL8367C_ACT42_GPIO_MASK 0x20 ++#define RTL8367C_ACT42_FORWARD_OFFSET 4 ++#define RTL8367C_ACT42_FORWARD_MASK 0x10 ++#define RTL8367C_ACT42_POLICING_OFFSET 3 ++#define RTL8367C_ACT42_POLICING_MASK 0x8 ++#define RTL8367C_ACT42_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT42_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT42_SVID_OFFSET 1 ++#define RTL8367C_ACT42_SVID_MASK 0x2 ++#define RTL8367C_ACT42_CVID_OFFSET 0 ++#define RTL8367C_ACT42_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL22 0x062a ++#define RTL8367C_OP45_NOT_OFFSET 14 ++#define RTL8367C_OP45_NOT_MASK 0x4000 ++#define RTL8367C_ACT45_GPIO_OFFSET 13 ++#define RTL8367C_ACT45_GPIO_MASK 0x2000 ++#define RTL8367C_ACT45_FORWARD_OFFSET 12 ++#define RTL8367C_ACT45_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT45_POLICING_OFFSET 11 ++#define RTL8367C_ACT45_POLICING_MASK 0x800 ++#define RTL8367C_ACT45_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT45_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT45_SVID_OFFSET 9 ++#define RTL8367C_ACT45_SVID_MASK 0x200 ++#define RTL8367C_ACT45_CVID_OFFSET 8 ++#define RTL8367C_ACT45_CVID_MASK 0x100 ++#define RTL8367C_OP44_NOT_OFFSET 6 ++#define RTL8367C_OP44_NOT_MASK 0x40 ++#define RTL8367C_ACT44_GPIO_OFFSET 5 ++#define RTL8367C_ACT44_GPIO_MASK 0x20 ++#define RTL8367C_ACT44_FORWARD_OFFSET 4 ++#define RTL8367C_ACT44_FORWARD_MASK 0x10 ++#define RTL8367C_ACT44_POLICING_OFFSET 3 ++#define RTL8367C_ACT44_POLICING_MASK 0x8 ++#define RTL8367C_ACT44_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT44_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT44_SVID_OFFSET 1 ++#define RTL8367C_ACT44_SVID_MASK 0x2 ++#define RTL8367C_ACT44_CVID_OFFSET 0 ++#define RTL8367C_ACT44_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL23 0x062b ++#define RTL8367C_OP47_NOT_OFFSET 14 ++#define RTL8367C_OP47_NOT_MASK 0x4000 ++#define RTL8367C_ACT47_GPIO_OFFSET 13 ++#define RTL8367C_ACT47_GPIO_MASK 0x2000 ++#define RTL8367C_ACT47_FORWARD_OFFSET 12 ++#define RTL8367C_ACT47_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT47_POLICING_OFFSET 11 ++#define RTL8367C_ACT47_POLICING_MASK 0x800 ++#define RTL8367C_ACT47_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT47_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT47_SVID_OFFSET 9 ++#define RTL8367C_ACT47_SVID_MASK 0x200 ++#define RTL8367C_ACT47_CVID_OFFSET 8 ++#define RTL8367C_ACT47_CVID_MASK 0x100 ++#define RTL8367C_OP46_NOT_OFFSET 6 ++#define RTL8367C_OP46_NOT_MASK 0x40 ++#define RTL8367C_ACT46_GPIO_OFFSET 5 ++#define RTL8367C_ACT46_GPIO_MASK 0x20 ++#define RTL8367C_ACT46_FORWARD_OFFSET 4 ++#define RTL8367C_ACT46_FORWARD_MASK 0x10 ++#define RTL8367C_ACT46_POLICING_OFFSET 3 ++#define RTL8367C_ACT46_POLICING_MASK 0x8 ++#define RTL8367C_ACT46_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT46_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT46_SVID_OFFSET 1 ++#define RTL8367C_ACT46_SVID_MASK 0x2 ++#define RTL8367C_ACT46_CVID_OFFSET 0 ++#define RTL8367C_ACT46_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL24 0x062c ++#define RTL8367C_OP49_NOT_OFFSET 14 ++#define RTL8367C_OP49_NOT_MASK 0x4000 ++#define RTL8367C_ACT49_GPIO_OFFSET 13 ++#define RTL8367C_ACT49_GPIO_MASK 0x2000 ++#define RTL8367C_ACT49_FORWARD_OFFSET 12 ++#define RTL8367C_ACT49_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT49_POLICING_OFFSET 11 ++#define RTL8367C_ACT49_POLICING_MASK 0x800 ++#define RTL8367C_ACT49_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT49_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT49_SVID_OFFSET 9 ++#define RTL8367C_ACT49_SVID_MASK 0x200 ++#define RTL8367C_ACT49_CVID_OFFSET 8 ++#define RTL8367C_ACT49_CVID_MASK 0x100 ++#define RTL8367C_OP48_NOT_OFFSET 6 ++#define RTL8367C_OP48_NOT_MASK 0x40 ++#define RTL8367C_ACT48_GPIO_OFFSET 5 ++#define RTL8367C_ACT48_GPIO_MASK 0x20 ++#define RTL8367C_ACT48_FORWARD_OFFSET 4 ++#define RTL8367C_ACT48_FORWARD_MASK 0x10 ++#define RTL8367C_ACT48_POLICING_OFFSET 3 ++#define RTL8367C_ACT48_POLICING_MASK 0x8 ++#define RTL8367C_ACT48_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT48_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT48_SVID_OFFSET 1 ++#define RTL8367C_ACT48_SVID_MASK 0x2 ++#define RTL8367C_ACT48_CVID_OFFSET 0 ++#define RTL8367C_ACT48_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL25 0x062d ++#define RTL8367C_OP51_NOT_OFFSET 14 ++#define RTL8367C_OP51_NOT_MASK 0x4000 ++#define RTL8367C_ACT51_GPIO_OFFSET 13 ++#define RTL8367C_ACT51_GPIO_MASK 0x2000 ++#define RTL8367C_ACT51_FORWARD_OFFSET 12 ++#define RTL8367C_ACT51_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT51_POLICING_OFFSET 11 ++#define RTL8367C_ACT51_POLICING_MASK 0x800 ++#define RTL8367C_ACT51_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT51_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT51_SVID_OFFSET 9 ++#define RTL8367C_ACT51_SVID_MASK 0x200 ++#define RTL8367C_ACT51_CVID_OFFSET 8 ++#define RTL8367C_ACT51_CVID_MASK 0x100 ++#define RTL8367C_OP50_NOT_OFFSET 6 ++#define RTL8367C_OP50_NOT_MASK 0x40 ++#define RTL8367C_ACT50_GPIO_OFFSET 5 ++#define RTL8367C_ACT50_GPIO_MASK 0x20 ++#define RTL8367C_ACT50_FORWARD_OFFSET 4 ++#define RTL8367C_ACT50_FORWARD_MASK 0x10 ++#define RTL8367C_ACT50_POLICING_OFFSET 3 ++#define RTL8367C_ACT50_POLICING_MASK 0x8 ++#define RTL8367C_ACT50_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT50_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT50_SVID_OFFSET 1 ++#define RTL8367C_ACT50_SVID_MASK 0x2 ++#define RTL8367C_ACT50_CVID_OFFSET 0 ++#define RTL8367C_ACT50_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL26 0x062e ++#define RTL8367C_OP53_NOT_OFFSET 14 ++#define RTL8367C_OP53_NOT_MASK 0x4000 ++#define RTL8367C_ACT53_GPIO_OFFSET 13 ++#define RTL8367C_ACT53_GPIO_MASK 0x2000 ++#define RTL8367C_ACT53_FORWARD_OFFSET 12 ++#define RTL8367C_ACT53_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT53_POLICING_OFFSET 11 ++#define RTL8367C_ACT53_POLICING_MASK 0x800 ++#define RTL8367C_ACT53_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT53_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT53_SVID_OFFSET 9 ++#define RTL8367C_ACT53_SVID_MASK 0x200 ++#define RTL8367C_ACT53_CVID_OFFSET 8 ++#define RTL8367C_ACT53_CVID_MASK 0x100 ++#define RTL8367C_OP52_NOT_OFFSET 6 ++#define RTL8367C_OP52_NOT_MASK 0x40 ++#define RTL8367C_ACT52_GPIO_OFFSET 5 ++#define RTL8367C_ACT52_GPIO_MASK 0x20 ++#define RTL8367C_ACT52_FORWARD_OFFSET 4 ++#define RTL8367C_ACT52_FORWARD_MASK 0x10 ++#define RTL8367C_ACT52_POLICING_OFFSET 3 ++#define RTL8367C_ACT52_POLICING_MASK 0x8 ++#define RTL8367C_ACT52_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT52_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT52_SVID_OFFSET 1 ++#define RTL8367C_ACT52_SVID_MASK 0x2 ++#define RTL8367C_ACT52_CVID_OFFSET 0 ++#define RTL8367C_ACT52_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL27 0x062f ++#define RTL8367C_OP55_NOT_OFFSET 14 ++#define RTL8367C_OP55_NOT_MASK 0x4000 ++#define RTL8367C_ACT55_GPIO_OFFSET 13 ++#define RTL8367C_ACT55_GPIO_MASK 0x2000 ++#define RTL8367C_ACT55_FORWARD_OFFSET 12 ++#define RTL8367C_ACT55_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT55_POLICING_OFFSET 11 ++#define RTL8367C_ACT55_POLICING_MASK 0x800 ++#define RTL8367C_ACT55_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT55_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT55_SVID_OFFSET 9 ++#define RTL8367C_ACT55_SVID_MASK 0x200 ++#define RTL8367C_ACT55_CVID_OFFSET 8 ++#define RTL8367C_ACT55_CVID_MASK 0x100 ++#define RTL8367C_OP54_NOT_OFFSET 6 ++#define RTL8367C_OP54_NOT_MASK 0x40 ++#define RTL8367C_ACT54_GPIO_OFFSET 5 ++#define RTL8367C_ACT54_GPIO_MASK 0x20 ++#define RTL8367C_ACT54_FORWARD_OFFSET 4 ++#define RTL8367C_ACT54_FORWARD_MASK 0x10 ++#define RTL8367C_ACT54_POLICING_OFFSET 3 ++#define RTL8367C_ACT54_POLICING_MASK 0x8 ++#define RTL8367C_ACT54_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT54_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT54_SVID_OFFSET 1 ++#define RTL8367C_ACT54_SVID_MASK 0x2 ++#define RTL8367C_ACT54_CVID_OFFSET 0 ++#define RTL8367C_ACT54_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL28 0x0630 ++#define RTL8367C_OP57_NOT_OFFSET 14 ++#define RTL8367C_OP57_NOT_MASK 0x4000 ++#define RTL8367C_ACT57_GPIO_OFFSET 13 ++#define RTL8367C_ACT57_GPIO_MASK 0x2000 ++#define RTL8367C_ACT57_FORWARD_OFFSET 12 ++#define RTL8367C_ACT57_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT57_POLICING_OFFSET 11 ++#define RTL8367C_ACT57_POLICING_MASK 0x800 ++#define RTL8367C_ACT57_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT57_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT57_SVID_OFFSET 9 ++#define RTL8367C_ACT57_SVID_MASK 0x200 ++#define RTL8367C_ACT57_CVID_OFFSET 8 ++#define RTL8367C_ACT57_CVID_MASK 0x100 ++#define RTL8367C_OP56_NOT_OFFSET 6 ++#define RTL8367C_OP56_NOT_MASK 0x40 ++#define RTL8367C_ACT56_GPIO_OFFSET 5 ++#define RTL8367C_ACT56_GPIO_MASK 0x20 ++#define RTL8367C_ACT56_FORWARD_OFFSET 4 ++#define RTL8367C_ACT56_FORWARD_MASK 0x10 ++#define RTL8367C_ACT56_POLICING_OFFSET 3 ++#define RTL8367C_ACT56_POLICING_MASK 0x8 ++#define RTL8367C_ACT56_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT56_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT56_SVID_OFFSET 1 ++#define RTL8367C_ACT56_SVID_MASK 0x2 ++#define RTL8367C_ACT56_CVID_OFFSET 0 ++#define RTL8367C_ACT56_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL29 0x0631 ++#define RTL8367C_OP59_NOT_OFFSET 14 ++#define RTL8367C_OP59_NOT_MASK 0x4000 ++#define RTL8367C_ACT59_GPIO_OFFSET 13 ++#define RTL8367C_ACT59_GPIO_MASK 0x2000 ++#define RTL8367C_ACT59_FORWARD_OFFSET 12 ++#define RTL8367C_ACT59_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT59_POLICING_OFFSET 11 ++#define RTL8367C_ACT59_POLICING_MASK 0x800 ++#define RTL8367C_ACT59_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT59_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT59_SVID_OFFSET 9 ++#define RTL8367C_ACT59_SVID_MASK 0x200 ++#define RTL8367C_ACT59_CVID_OFFSET 8 ++#define RTL8367C_ACT59_CVID_MASK 0x100 ++#define RTL8367C_OP58_NOT_OFFSET 6 ++#define RTL8367C_OP58_NOT_MASK 0x40 ++#define RTL8367C_ACT58_GPIO_OFFSET 5 ++#define RTL8367C_ACT58_GPIO_MASK 0x20 ++#define RTL8367C_ACT58_FORWARD_OFFSET 4 ++#define RTL8367C_ACT58_FORWARD_MASK 0x10 ++#define RTL8367C_ACT58_POLICING_OFFSET 3 ++#define RTL8367C_ACT58_POLICING_MASK 0x8 ++#define RTL8367C_ACT58_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT58_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT58_SVID_OFFSET 1 ++#define RTL8367C_ACT58_SVID_MASK 0x2 ++#define RTL8367C_ACT58_CVID_OFFSET 0 ++#define RTL8367C_ACT58_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL30 0x0632 ++#define RTL8367C_OP61_NOT_OFFSET 14 ++#define RTL8367C_OP61_NOT_MASK 0x4000 ++#define RTL8367C_ACT61_GPIO_OFFSET 13 ++#define RTL8367C_ACT61_GPIO_MASK 0x2000 ++#define RTL8367C_ACT61_FORWARD_OFFSET 12 ++#define RTL8367C_ACT61_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT61_POLICING_OFFSET 11 ++#define RTL8367C_ACT61_POLICING_MASK 0x800 ++#define RTL8367C_ACT61_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT61_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT61_SVID_OFFSET 9 ++#define RTL8367C_ACT61_SVID_MASK 0x200 ++#define RTL8367C_ACT61_CVID_OFFSET 8 ++#define RTL8367C_ACT61_CVID_MASK 0x100 ++#define RTL8367C_OP60_NOT_OFFSET 6 ++#define RTL8367C_OP60_NOT_MASK 0x40 ++#define RTL8367C_ACT60_GPIO_OFFSET 5 ++#define RTL8367C_ACT60_GPIO_MASK 0x20 ++#define RTL8367C_ACT60_FORWARD_OFFSET 4 ++#define RTL8367C_ACT60_FORWARD_MASK 0x10 ++#define RTL8367C_ACT60_POLICING_OFFSET 3 ++#define RTL8367C_ACT60_POLICING_MASK 0x8 ++#define RTL8367C_ACT60_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT60_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT60_SVID_OFFSET 1 ++#define RTL8367C_ACT60_SVID_MASK 0x2 ++#define RTL8367C_ACT60_CVID_OFFSET 0 ++#define RTL8367C_ACT60_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL31 0x0633 ++#define RTL8367C_OP63_NOT_OFFSET 14 ++#define RTL8367C_OP63_NOT_MASK 0x4000 ++#define RTL8367C_ACT63_GPIO_OFFSET 13 ++#define RTL8367C_ACT63_GPIO_MASK 0x2000 ++#define RTL8367C_ACT63_FORWARD_OFFSET 12 ++#define RTL8367C_ACT63_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT63_POLICING_OFFSET 11 ++#define RTL8367C_ACT63_POLICING_MASK 0x800 ++#define RTL8367C_ACT63_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT63_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT63_SVID_OFFSET 9 ++#define RTL8367C_ACT63_SVID_MASK 0x200 ++#define RTL8367C_ACT63_CVID_OFFSET 8 ++#define RTL8367C_ACT63_CVID_MASK 0x100 ++#define RTL8367C_OP62_NOT_OFFSET 6 ++#define RTL8367C_OP62_NOT_MASK 0x40 ++#define RTL8367C_ACT62_GPIO_OFFSET 5 ++#define RTL8367C_ACT62_GPIO_MASK 0x20 ++#define RTL8367C_ACT62_FORWARD_OFFSET 4 ++#define RTL8367C_ACT62_FORWARD_MASK 0x10 ++#define RTL8367C_ACT62_POLICING_OFFSET 3 ++#define RTL8367C_ACT62_POLICING_MASK 0x8 ++#define RTL8367C_ACT62_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT62_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT62_SVID_OFFSET 1 ++#define RTL8367C_ACT62_SVID_MASK 0x2 ++#define RTL8367C_ACT62_CVID_OFFSET 0 ++#define RTL8367C_ACT62_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL0 0x0635 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL1 0x0636 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL2 0x0637 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY0_CTRL2_OFFSET 0 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY0_CTRL2_MASK 0x3 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY1_CTRL0 0x0638 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY1_CTRL1 0x0639 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY1_CTRL2 0x063a ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY1_CTRL2_OFFSET 0 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY1_CTRL2_MASK 0x3 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY2_CTRL0 0x063b ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY2_CTRL1 0x063c ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY2_CTRL2 0x063d ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY2_CTRL2_OFFSET 0 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY2_CTRL2_MASK 0x3 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY3_CTRL0 0x063e ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY3_CTRL1 0x063f ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY3_CTRL2 0x0640 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY3_CTRL2_OFFSET 0 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY3_CTRL2_MASK 0x3 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY4_CTRL0 0x0641 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY4_CTRL1 0x0642 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY4_CTRL2 0x0643 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY4_CTRL2_OFFSET 0 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY4_CTRL2_MASK 0x3 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY5_CTRL0 0x0644 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY5_CTRL1 0x0645 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY5_CTRL2 0x0646 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY5_CTRL2_OFFSET 0 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY5_CTRL2_MASK 0x3 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY6_CTRL0 0x0647 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY6_CTRL1 0x0648 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY6_CTRL2 0x0649 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY6_CTRL2_OFFSET 0 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY6_CTRL2_MASK 0x3 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY7_CTRL0 0x064a ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY7_CTRL1 0x064b ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY7_CTRL2 0x064c ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY7_CTRL2_OFFSET 0 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY7_CTRL2_MASK 0x3 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY8_CTRL0 0x064d ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY8_CTRL1 0x064e ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY8_CTRL2 0x064f ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY8_CTRL2_OFFSET 0 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY8_CTRL2_MASK 0x3 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY9_CTRL0 0x0650 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY9_CTRL1 0x0651 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY9_CTRL2 0x0652 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY9_CTRL2_OFFSET 0 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY9_CTRL2_MASK 0x3 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY10_CTRL0 0x0653 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY10_CTRL1 0x0654 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY10_CTRL2 0x0655 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY10_CTRL2_OFFSET 0 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY10_CTRL2_MASK 0x3 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY11_CTRL0 0x0656 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY11_CTRL1 0x0657 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY11_CTRL2 0x0658 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY11_CTRL2_OFFSET 0 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY11_CTRL2_MASK 0x3 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY12_CTRL0 0x0659 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY12_CTRL1 0x065a ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY12_CTRL2 0x065b ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY12_CTRL2_OFFSET 0 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY12_CTRL2_MASK 0x3 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY13_CTRL0 0x065c ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY13_CTRL1 0x065d ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY13_CTRL2 0x065e ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY13_CTRL2_OFFSET 0 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY13_CTRL2_MASK 0x3 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY14_CTRL0 0x065f ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY14_CTRL1 0x0660 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY14_CTRL2 0x0661 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY14_CTRL2_OFFSET 0 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY14_CTRL2_MASK 0x3 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY15_CTRL0 0x0662 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY15_CTRL1 0x0663 ++ ++#define RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY15_CTRL2 0x0664 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY15_CTRL2_OFFSET 0 ++#define RTL8367C_ACL_SDPORT_RANGE_ENTRY15_CTRL2_MASK 0x3 ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL0 0x0665 ++#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL0_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL0_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL1 0x0666 ++#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_OFFSET 12 ++#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_MASK 0x3000 ++#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_HIGH_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_HIGH_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY1_CTRL0 0x0667 ++#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL0_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL0_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY1_CTRL1 0x0668 ++#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL1_CHECK1_TYPE_OFFSET 12 ++#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL1_CHECK1_TYPE_MASK 0x3000 ++#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL1_CHECK1_HIGH_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY1_CTRL1_CHECK1_HIGH_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY2_CTRL0 0x0669 ++#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL0_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL0_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY2_CTRL1 0x066a ++#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL1_CHECK2_TYPE_OFFSET 12 ++#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL1_CHECK2_TYPE_MASK 0x3000 ++#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL1_CHECK2_HIGH_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY2_CTRL1_CHECK2_HIGH_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY3_CTRL0 0x066b ++#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL0_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL0_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY3_CTRL1 0x066c ++#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL1_CHECK3_TYPE_OFFSET 12 ++#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL1_CHECK3_TYPE_MASK 0x3000 ++#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL1_CHECK3_HIGH_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY3_CTRL1_CHECK3_HIGH_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY4_CTRL0 0x066d ++#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL0_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL0_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY4_CTRL1 0x066e ++#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL1_CHECK4_TYPE_OFFSET 12 ++#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL1_CHECK4_TYPE_MASK 0x3000 ++#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL1_CHECK4_HIGH_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY4_CTRL1_CHECK4_HIGH_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY5_CTRL0 0x066f ++#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL0_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL0_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY5_CTRL1 0x0670 ++#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL1_CHECK5_TYPE_OFFSET 12 ++#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL1_CHECK5_TYPE_MASK 0x3000 ++#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL1_CHECK5_HIGH_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY5_CTRL1_CHECK5_HIGH_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY6_CTRL0 0x0671 ++#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL0_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL0_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY6_CTRL1 0x0672 ++#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL1_CHECK6_TYPE_OFFSET 12 ++#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL1_CHECK6_TYPE_MASK 0x3000 ++#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL1_CHECK6_HIGH_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY6_CTRL1_CHECK6_HIGH_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY7_CTRL0 0x0673 ++#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL0_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL0_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY7_CTRL1 0x0674 ++#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL1_CHECK7_TYPE_OFFSET 12 ++#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL1_CHECK7_TYPE_MASK 0x3000 ++#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL1_CHECK7_HIGH_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY7_CTRL1_CHECK7_HIGH_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY8_CTRL0 0x0675 ++#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL0_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL0_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY8_CTRL1 0x0676 ++#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL1_CHECK8_TYPE_OFFSET 12 ++#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL1_CHECK8_TYPE_MASK 0x3000 ++#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL1_CHECK8_HIGH_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY8_CTRL1_CHECK8_HIGH_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY9_CTRL0 0x0677 ++#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL0_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL0_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY9_CTRL1 0x0678 ++#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL1_CHECK9_TYPE_OFFSET 12 ++#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL1_CHECK9_TYPE_MASK 0x3000 ++#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL1_CHECK9_HIGH_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY9_CTRL1_CHECK9_HIGH_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY10_CTRL0 0x0679 ++#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL0_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL0_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY10_CTRL1 0x067a ++#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL1_CHECK10_TYPE_OFFSET 12 ++#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL1_CHECK10_TYPE_MASK 0x3000 ++#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL1_CHECK10_HIGH_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY10_CTRL1_CHECK10_HIGH_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY11_CTRL0 0x067b ++#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL0_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL0_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY11_CTRL1 0x067c ++#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL1_CHECK11_TYPE_OFFSET 12 ++#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL1_CHECK11_TYPE_MASK 0x3000 ++#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL1_CHECK11_HIGH_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY11_CTRL1_CHECK11_HIGH_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY12_CTRL0 0x067d ++#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL0_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL0_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY12_CTRL1 0x067e ++#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL1_CHECK12_TYPE_OFFSET 12 ++#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL1_CHECK12_TYPE_MASK 0x3000 ++#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL1_CHECK12_HIGH_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY12_CTRL1_CHECK12_HIGH_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY13_CTRL0 0x067f ++#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL0_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL0_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY13_CTRL1 0x0680 ++#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL1_CHECK13_TYPE_OFFSET 12 ++#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL1_CHECK13_TYPE_MASK 0x3000 ++#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL1_CHECK13_HIGH_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY13_CTRL1_CHECK13_HIGH_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY14_CTRL0 0x0681 ++#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL0_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL0_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY14_CTRL1 0x0682 ++#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL1_CHECK14_TYPE_OFFSET 12 ++#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL1_CHECK14_TYPE_MASK 0x3000 ++#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL1_CHECK14_HIGH_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY14_CTRL1_CHECK14_HIGH_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY15_CTRL0 0x0683 ++#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL0_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL0_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_VID_RANGE_ENTRY15_CTRL1 0x0684 ++#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL1_CHECK15_TYPE_OFFSET 12 ++#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL1_CHECK15_TYPE_MASK 0x3000 ++#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL1_CHECK15_HIGH_OFFSET 0 ++#define RTL8367C_ACL_VID_RANGE_ENTRY15_CTRL1_CHECK15_HIGH_MASK 0xFFF ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL0 0x0685 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL1 0x0686 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL2 0x0687 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL3 0x0688 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL4 0x0689 ++#define RTL8367C_ACL_IP_RANGE_ENTRY0_CTRL4_OFFSET 0 ++#define RTL8367C_ACL_IP_RANGE_ENTRY0_CTRL4_MASK 0x7 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY1_CTRL0 0x068a ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY1_CTRL1 0x068b ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY1_CTRL2 0x068c ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY1_CTRL3 0x068d ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY1_CTRL4 0x068e ++#define RTL8367C_ACL_IP_RANGE_ENTRY1_CTRL4_OFFSET 0 ++#define RTL8367C_ACL_IP_RANGE_ENTRY1_CTRL4_MASK 0x7 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY2_CTRL0 0x068f ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY2_CTRL1 0x0690 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY2_CTRL2 0x0691 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY2_CTRL3 0x0692 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY2_CTRL4 0x0693 ++#define RTL8367C_ACL_IP_RANGE_ENTRY2_CTRL4_OFFSET 0 ++#define RTL8367C_ACL_IP_RANGE_ENTRY2_CTRL4_MASK 0x7 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY3_CTRL0 0x0694 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY3_CTRL1 0x0695 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY3_CTRL2 0x0696 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY3_CTRL3 0x0697 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY3_CTRL4 0x0698 ++#define RTL8367C_ACL_IP_RANGE_ENTRY3_CTRL4_OFFSET 0 ++#define RTL8367C_ACL_IP_RANGE_ENTRY3_CTRL4_MASK 0x7 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY4_CTRL0 0x0699 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY4_CTRL1 0x069a ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY4_CTRL2 0x069b ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY4_CTRL3 0x069c ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY4_CTRL4 0x069d ++#define RTL8367C_ACL_IP_RANGE_ENTRY4_CTRL4_OFFSET 0 ++#define RTL8367C_ACL_IP_RANGE_ENTRY4_CTRL4_MASK 0x7 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY5_CTRL0 0x069e ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY5_CTRL1 0x069f ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY5_CTRL2 0x06a0 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY5_CTRL3 0x06a1 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY5_CTRL4 0x06a2 ++#define RTL8367C_ACL_IP_RANGE_ENTRY5_CTRL4_OFFSET 0 ++#define RTL8367C_ACL_IP_RANGE_ENTRY5_CTRL4_MASK 0x7 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY6_CTRL0 0x06a3 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY6_CTRL1 0x06a4 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY6_CTRL2 0x06a5 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY6_CTRL3 0x06a6 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY6_CTRL4 0x06a7 ++#define RTL8367C_ACL_IP_RANGE_ENTRY6_CTRL4_OFFSET 0 ++#define RTL8367C_ACL_IP_RANGE_ENTRY6_CTRL4_MASK 0x7 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY7_CTRL0 0x06a8 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY7_CTRL1 0x06a9 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY7_CTRL2 0x06aa ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY7_CTRL3 0x06ab ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY7_CTRL4 0x06ac ++#define RTL8367C_ACL_IP_RANGE_ENTRY7_CTRL4_OFFSET 0 ++#define RTL8367C_ACL_IP_RANGE_ENTRY7_CTRL4_MASK 0x7 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY8_CTRL0 0x06ad ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY8_CTRL1 0x06ae ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY8_CTRL2 0x06af ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY8_CTRL3 0x06b0 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY8_CTRL4 0x06b1 ++#define RTL8367C_ACL_IP_RANGE_ENTRY8_CTRL4_OFFSET 0 ++#define RTL8367C_ACL_IP_RANGE_ENTRY8_CTRL4_MASK 0x7 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY9_CTRL0 0x06b2 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY9_CTRL1 0x06b3 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY9_CTRL2 0x06b4 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY9_CTRL3 0x06b5 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY9_CTRL4 0x06b6 ++#define RTL8367C_ACL_IP_RANGE_ENTRY9_CTRL4_OFFSET 0 ++#define RTL8367C_ACL_IP_RANGE_ENTRY9_CTRL4_MASK 0x7 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY10_CTRL0 0x06b7 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY10_CTRL1 0x06b8 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY10_CTRL2 0x06b9 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY10_CTRL3 0x06ba ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY10_CTRL4 0x06bb ++#define RTL8367C_ACL_IP_RANGE_ENTRY10_CTRL4_OFFSET 0 ++#define RTL8367C_ACL_IP_RANGE_ENTRY10_CTRL4_MASK 0x7 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY11_CTRL0 0x06bc ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY11_CTRL1 0x06bd ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY11_CTRL2 0x06be ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY11_CTRL3 0x06bf ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY11_CTRL4 0x06c0 ++#define RTL8367C_ACL_IP_RANGE_ENTRY11_CTRL4_OFFSET 0 ++#define RTL8367C_ACL_IP_RANGE_ENTRY11_CTRL4_MASK 0x7 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY12_CTRL0 0x06c1 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY12_CTRL1 0x06c2 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY12_CTRL2 0x06c3 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY12_CTRL3 0x06c4 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY12_CTRL4 0x06c5 ++#define RTL8367C_ACL_IP_RANGE_ENTRY12_CTRL4_OFFSET 0 ++#define RTL8367C_ACL_IP_RANGE_ENTRY12_CTRL4_MASK 0x7 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY13_CTRL0 0x06c6 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY13_CTRL1 0x06c7 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY13_CTRL2 0x06c8 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY13_CTRL3 0x06c9 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY13_CTRL4 0x06ca ++#define RTL8367C_ACL_IP_RANGE_ENTRY13_CTRL4_OFFSET 0 ++#define RTL8367C_ACL_IP_RANGE_ENTRY13_CTRL4_MASK 0x7 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY14_CTRL0 0x06cb ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY14_CTRL1 0x06cc ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY14_CTRL2 0x06cd ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY14_CTRL3 0x06ce ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY14_CTRL4 0x06cf ++#define RTL8367C_ACL_IP_RANGE_ENTRY14_CTRL4_OFFSET 0 ++#define RTL8367C_ACL_IP_RANGE_ENTRY14_CTRL4_MASK 0x7 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY15_CTRL0 0x06d0 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY15_CTRL1 0x06d1 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY15_CTRL2 0x06d2 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY15_CTRL3 0x06d3 ++ ++#define RTL8367C_REG_ACL_IP_RANGE_ENTRY15_CTRL4 0x06d4 ++#define RTL8367C_ACL_IP_RANGE_ENTRY15_CTRL4_OFFSET 0 ++#define RTL8367C_ACL_IP_RANGE_ENTRY15_CTRL4_MASK 0x7 ++ ++#define RTL8367C_REG_ACL_ENABLE 0x06d5 ++#define RTL8367C_PORT10_ENABLE_OFFSET 10 ++#define RTL8367C_PORT10_ENABLE_MASK 0x400 ++#define RTL8367C_PORT9_ENABLE_OFFSET 9 ++#define RTL8367C_PORT9_ENABLE_MASK 0x200 ++#define RTL8367C_PORT8_ENABLE_OFFSET 8 ++#define RTL8367C_PORT8_ENABLE_MASK 0x100 ++#define RTL8367C_PORT7_ENABLE_OFFSET 7 ++#define RTL8367C_PORT7_ENABLE_MASK 0x80 ++#define RTL8367C_PORT6_ENABLE_OFFSET 6 ++#define RTL8367C_PORT6_ENABLE_MASK 0x40 ++#define RTL8367C_PORT5_ENABLE_OFFSET 5 ++#define RTL8367C_PORT5_ENABLE_MASK 0x20 ++#define RTL8367C_PORT4_ENABLE_OFFSET 4 ++#define RTL8367C_PORT4_ENABLE_MASK 0x10 ++#define RTL8367C_PORT3_ENABLE_OFFSET 3 ++#define RTL8367C_PORT3_ENABLE_MASK 0x8 ++#define RTL8367C_PORT2_ENABLE_OFFSET 2 ++#define RTL8367C_PORT2_ENABLE_MASK 0x4 ++#define RTL8367C_PORT1_ENABLE_OFFSET 1 ++#define RTL8367C_PORT1_ENABLE_MASK 0x2 ++#define RTL8367C_PORT0_ENABLE_OFFSET 0 ++#define RTL8367C_PORT0_ENABLE_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_UNMATCH_PERMIT 0x06d6 ++#define RTL8367C_PORT10_PERMIT_OFFSET 10 ++#define RTL8367C_PORT10_PERMIT_MASK 0x400 ++#define RTL8367C_PORT9_PERMIT_OFFSET 9 ++#define RTL8367C_PORT9_PERMIT_MASK 0x200 ++#define RTL8367C_PORT8_PERMIT_OFFSET 8 ++#define RTL8367C_PORT8_PERMIT_MASK 0x100 ++#define RTL8367C_PORT7_PERMIT_OFFSET 7 ++#define RTL8367C_PORT7_PERMIT_MASK 0x80 ++#define RTL8367C_PORT6_PERMIT_OFFSET 6 ++#define RTL8367C_PORT6_PERMIT_MASK 0x40 ++#define RTL8367C_PORT5_PERMIT_OFFSET 5 ++#define RTL8367C_PORT5_PERMIT_MASK 0x20 ++#define RTL8367C_PORT4_PERMIT_OFFSET 4 ++#define RTL8367C_PORT4_PERMIT_MASK 0x10 ++#define RTL8367C_PORT3_PERMIT_OFFSET 3 ++#define RTL8367C_PORT3_PERMIT_MASK 0x8 ++#define RTL8367C_PORT2_PERMIT_OFFSET 2 ++#define RTL8367C_PORT2_PERMIT_MASK 0x4 ++#define RTL8367C_PORT1_PERMIT_OFFSET 1 ++#define RTL8367C_PORT1_PERMIT_MASK 0x2 ++#define RTL8367C_PORT0_PERMIT_OFFSET 0 ++#define RTL8367C_PORT0_PERMIT_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_GPIO_POLARITY 0x06d7 ++#define RTL8367C_ACL_GPIO_POLARITY_OFFSET 0 ++#define RTL8367C_ACL_GPIO_POLARITY_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_LOG_CNT_TYPE 0x06d8 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER15_TYPE_OFFSET 15 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER15_TYPE_MASK 0x8000 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER14_TYPE_OFFSET 14 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER14_TYPE_MASK 0x4000 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER13_TYPE_OFFSET 13 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER13_TYPE_MASK 0x2000 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER12_TYPE_OFFSET 12 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER12_TYPE_MASK 0x1000 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER11_TYPE_OFFSET 11 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER11_TYPE_MASK 0x800 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER10_TYPE_OFFSET 10 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER10_TYPE_MASK 0x400 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER9_TYPE_OFFSET 9 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER9_TYPE_MASK 0x200 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER8_TYPE_OFFSET 8 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER8_TYPE_MASK 0x100 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER7_TYPE_OFFSET 7 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER7_TYPE_MASK 0x80 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER6_TYPE_OFFSET 6 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER6_TYPE_MASK 0x40 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER5_TYPE_OFFSET 5 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER5_TYPE_MASK 0x20 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER4_TYPE_OFFSET 4 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER4_TYPE_MASK 0x10 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER3_TYPE_OFFSET 3 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER3_TYPE_MASK 0x8 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER2_TYPE_OFFSET 2 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER2_TYPE_MASK 0x4 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER1_TYPE_OFFSET 1 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER1_TYPE_MASK 0x2 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER0_TYPE_OFFSET 0 ++#define RTL8367C_ACL_LOG_CNT_TYPE_COUNTER0_TYPE_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_RESET_CFG 0x06d9 ++#define RTL8367C_ACL_RESET_CFG_OFFSET 0 ++#define RTL8367C_ACL_RESET_CFG_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_DUMMY00 0x06E0 ++ ++#define RTL8367C_REG_ACL_DUMMY01 0x06E1 ++ ++#define RTL8367C_REG_ACL_DUMMY02 0x06E2 ++ ++#define RTL8367C_REG_ACL_DUMMY03 0x06E3 ++ ++#define RTL8367C_REG_ACL_DUMMY04 0x06E4 ++ ++#define RTL8367C_REG_ACL_DUMMY05 0x06E5 ++ ++#define RTL8367C_REG_ACL_DUMMY06 0x06E6 ++ ++#define RTL8367C_REG_ACL_DUMMY07 0x06E7 ++ ++#define RTL8367C_REG_ACL_REASON_01 0x06E8 ++#define RTL8367C_ACL_ACT_1_OFFSET 8 ++#define RTL8367C_ACL_ACT_1_MASK 0xFF00 ++#define RTL8367C_ACL_ACT_0_OFFSET 0 ++#define RTL8367C_ACL_ACT_0_MASK 0xFF ++ ++#define RTL8367C_REG_ACL_REASON_23 0x06E9 ++#define RTL8367C_ACL_ACT_3_OFFSET 8 ++#define RTL8367C_ACL_ACT_3_MASK 0xFF00 ++#define RTL8367C_ACL_ACT_2_OFFSET 0 ++#define RTL8367C_ACL_ACT_2_MASK 0xFF ++ ++#define RTL8367C_REG_ACL_REASON_45 0x06EA ++#define RTL8367C_ACL_ACT_5_OFFSET 8 ++#define RTL8367C_ACL_ACT_5_MASK 0xFF00 ++#define RTL8367C_ACL_ACT_4_OFFSET 0 ++#define RTL8367C_ACL_ACT_4_MASK 0xFF ++ ++#define RTL8367C_REG_ACL_ACCESS_MODE 0x06EB ++#define RTL8367C_ACL_ACCESS_MODE_OFFSET 0 ++#define RTL8367C_ACL_ACCESS_MODE_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL32 0x06F0 ++#define RTL8367C_OP65_NOT_OFFSET 14 ++#define RTL8367C_OP65_NOT_MASK 0x4000 ++#define RTL8367C_ACT65_GPIO_OFFSET 13 ++#define RTL8367C_ACT65_GPIO_MASK 0x2000 ++#define RTL8367C_ACT65_FORWARD_OFFSET 12 ++#define RTL8367C_ACT65_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT65_POLICING_OFFSET 11 ++#define RTL8367C_ACT65_POLICING_MASK 0x800 ++#define RTL8367C_ACT65_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT65_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT65_SVID_OFFSET 9 ++#define RTL8367C_ACT65_SVID_MASK 0x200 ++#define RTL8367C_ACT65_CVID_OFFSET 8 ++#define RTL8367C_ACT65_CVID_MASK 0x100 ++#define RTL8367C_OP64_NOT_OFFSET 6 ++#define RTL8367C_OP64_NOT_MASK 0x40 ++#define RTL8367C_ACT64_GPIO_OFFSET 5 ++#define RTL8367C_ACT64_GPIO_MASK 0x20 ++#define RTL8367C_ACT64_FORWARD_OFFSET 4 ++#define RTL8367C_ACT64_FORWARD_MASK 0x10 ++#define RTL8367C_ACT64_POLICING_OFFSET 3 ++#define RTL8367C_ACT64_POLICING_MASK 0x8 ++#define RTL8367C_ACT64_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT64_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT64_SVID_OFFSET 1 ++#define RTL8367C_ACT64_SVID_MASK 0x2 ++#define RTL8367C_ACT64_CVID_OFFSET 0 ++#define RTL8367C_ACT64_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL33 0x06F1 ++#define RTL8367C_OP67_NOT_OFFSET 14 ++#define RTL8367C_OP67_NOT_MASK 0x4000 ++#define RTL8367C_ACT67_GPIO_OFFSET 13 ++#define RTL8367C_ACT67_GPIO_MASK 0x2000 ++#define RTL8367C_ACT67_FORWARD_OFFSET 12 ++#define RTL8367C_ACT67_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT67_POLICING_OFFSET 11 ++#define RTL8367C_ACT67_POLICING_MASK 0x800 ++#define RTL8367C_ACT67_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT67_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT67_SVID_OFFSET 9 ++#define RTL8367C_ACT67_SVID_MASK 0x200 ++#define RTL8367C_ACT67_CVID_OFFSET 8 ++#define RTL8367C_ACT67_CVID_MASK 0x100 ++#define RTL8367C_OP66_NOT_OFFSET 6 ++#define RTL8367C_OP66_NOT_MASK 0x40 ++#define RTL8367C_ACT66_GPIO_OFFSET 5 ++#define RTL8367C_ACT66_GPIO_MASK 0x20 ++#define RTL8367C_ACT66_FORWARD_OFFSET 4 ++#define RTL8367C_ACT66_FORWARD_MASK 0x10 ++#define RTL8367C_ACT66_POLICING_OFFSET 3 ++#define RTL8367C_ACT66_POLICING_MASK 0x8 ++#define RTL8367C_ACT66_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT66_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT66_SVID_OFFSET 1 ++#define RTL8367C_ACT66_SVID_MASK 0x2 ++#define RTL8367C_ACT66_CVID_OFFSET 0 ++#define RTL8367C_ACT66_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL34 0x06F2 ++#define RTL8367C_OP69_NOT_OFFSET 14 ++#define RTL8367C_OP69_NOT_MASK 0x4000 ++#define RTL8367C_ACT69_GPIO_OFFSET 13 ++#define RTL8367C_ACT69_GPIO_MASK 0x2000 ++#define RTL8367C_ACT69_FORWARD_OFFSET 12 ++#define RTL8367C_ACT69_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT69_POLICING_OFFSET 11 ++#define RTL8367C_ACT69_POLICING_MASK 0x800 ++#define RTL8367C_ACT69_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT69_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT69_SVID_OFFSET 9 ++#define RTL8367C_ACT69_SVID_MASK 0x200 ++#define RTL8367C_ACT69_CVID_OFFSET 8 ++#define RTL8367C_ACT69_CVID_MASK 0x100 ++#define RTL8367C_OP68_NOT_OFFSET 6 ++#define RTL8367C_OP68_NOT_MASK 0x40 ++#define RTL8367C_ACT68_GPIO_OFFSET 5 ++#define RTL8367C_ACT68_GPIO_MASK 0x20 ++#define RTL8367C_ACT68_FORWARD_OFFSET 4 ++#define RTL8367C_ACT68_FORWARD_MASK 0x10 ++#define RTL8367C_ACT68_POLICING_OFFSET 3 ++#define RTL8367C_ACT68_POLICING_MASK 0x8 ++#define RTL8367C_ACT68_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT68_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT68_SVID_OFFSET 1 ++#define RTL8367C_ACT68_SVID_MASK 0x2 ++#define RTL8367C_ACT68_CVID_OFFSET 0 ++#define RTL8367C_ACT68_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL35 0x06F3 ++#define RTL8367C_OP71_NOT_OFFSET 14 ++#define RTL8367C_OP71_NOT_MASK 0x4000 ++#define RTL8367C_ACT71_GPIO_OFFSET 13 ++#define RTL8367C_ACT71_GPIO_MASK 0x2000 ++#define RTL8367C_ACT71_FORWARD_OFFSET 12 ++#define RTL8367C_ACT71_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT71_POLICING_OFFSET 11 ++#define RTL8367C_ACT71_POLICING_MASK 0x800 ++#define RTL8367C_ACT71_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT71_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT71_SVID_OFFSET 9 ++#define RTL8367C_ACT71_SVID_MASK 0x200 ++#define RTL8367C_ACT71_CVID_OFFSET 8 ++#define RTL8367C_ACT71_CVID_MASK 0x100 ++#define RTL8367C_OP70_NOT_OFFSET 6 ++#define RTL8367C_OP70_NOT_MASK 0x40 ++#define RTL8367C_ACT70_GPIO_OFFSET 5 ++#define RTL8367C_ACT70_GPIO_MASK 0x20 ++#define RTL8367C_ACT70_FORWARD_OFFSET 4 ++#define RTL8367C_ACT70_FORWARD_MASK 0x10 ++#define RTL8367C_ACT70_POLICING_OFFSET 3 ++#define RTL8367C_ACT70_POLICING_MASK 0x8 ++#define RTL8367C_ACT70_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT70_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT70_SVID_OFFSET 1 ++#define RTL8367C_ACT70_SVID_MASK 0x2 ++#define RTL8367C_ACT70_CVID_OFFSET 0 ++#define RTL8367C_ACT70_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL36 0x06F4 ++#define RTL8367C_OP73_NOT_OFFSET 14 ++#define RTL8367C_OP73_NOT_MASK 0x4000 ++#define RTL8367C_ACT73_GPIO_OFFSET 13 ++#define RTL8367C_ACT73_GPIO_MASK 0x2000 ++#define RTL8367C_ACT73_FORWARD_OFFSET 12 ++#define RTL8367C_ACT73_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT73_POLICING_OFFSET 11 ++#define RTL8367C_ACT73_POLICING_MASK 0x800 ++#define RTL8367C_ACT73_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT73_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT73_SVID_OFFSET 9 ++#define RTL8367C_ACT73_SVID_MASK 0x200 ++#define RTL8367C_ACT73_CVID_OFFSET 8 ++#define RTL8367C_ACT73_CVID_MASK 0x100 ++#define RTL8367C_OP72_NOT_OFFSET 6 ++#define RTL8367C_OP72_NOT_MASK 0x40 ++#define RTL8367C_ACT72_GPIO_OFFSET 5 ++#define RTL8367C_ACT72_GPIO_MASK 0x20 ++#define RTL8367C_ACT72_FORWARD_OFFSET 4 ++#define RTL8367C_ACT72_FORWARD_MASK 0x10 ++#define RTL8367C_ACT72_POLICING_OFFSET 3 ++#define RTL8367C_ACT72_POLICING_MASK 0x8 ++#define RTL8367C_ACT72_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT72_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT72_SVID_OFFSET 1 ++#define RTL8367C_ACT72_SVID_MASK 0x2 ++#define RTL8367C_ACT72_CVID_OFFSET 0 ++#define RTL8367C_ACT72_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL37 0x06F5 ++#define RTL8367C_OP75_NOT_OFFSET 14 ++#define RTL8367C_OP75_NOT_MASK 0x4000 ++#define RTL8367C_ACT75_GPIO_OFFSET 13 ++#define RTL8367C_ACT75_GPIO_MASK 0x2000 ++#define RTL8367C_ACT75_FORWARD_OFFSET 12 ++#define RTL8367C_ACT75_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT75_POLICING_OFFSET 11 ++#define RTL8367C_ACT75_POLICING_MASK 0x800 ++#define RTL8367C_ACT75_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT75_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT75_SVID_OFFSET 9 ++#define RTL8367C_ACT75_SVID_MASK 0x200 ++#define RTL8367C_ACT75_CVID_OFFSET 8 ++#define RTL8367C_ACT75_CVID_MASK 0x100 ++#define RTL8367C_OP74_NOT_OFFSET 6 ++#define RTL8367C_OP74_NOT_MASK 0x40 ++#define RTL8367C_ACT74_GPIO_OFFSET 5 ++#define RTL8367C_ACT74_GPIO_MASK 0x20 ++#define RTL8367C_ACT74_FORWARD_OFFSET 4 ++#define RTL8367C_ACT74_FORWARD_MASK 0x10 ++#define RTL8367C_ACT74_POLICING_OFFSET 3 ++#define RTL8367C_ACT74_POLICING_MASK 0x8 ++#define RTL8367C_ACT74_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT74_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT74_SVID_OFFSET 1 ++#define RTL8367C_ACT74_SVID_MASK 0x2 ++#define RTL8367C_ACT74_CVID_OFFSET 0 ++#define RTL8367C_ACT74_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL38 0x06F6 ++#define RTL8367C_OP77_NOT_OFFSET 14 ++#define RTL8367C_OP77_NOT_MASK 0x4000 ++#define RTL8367C_ACT77_GPIO_OFFSET 13 ++#define RTL8367C_ACT77_GPIO_MASK 0x2000 ++#define RTL8367C_ACT77_FORWARD_OFFSET 12 ++#define RTL8367C_ACT77_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT77_POLICING_OFFSET 11 ++#define RTL8367C_ACT77_POLICING_MASK 0x800 ++#define RTL8367C_ACT77_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT77_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT77_SVID_OFFSET 9 ++#define RTL8367C_ACT77_SVID_MASK 0x200 ++#define RTL8367C_ACT77_CVID_OFFSET 8 ++#define RTL8367C_ACT77_CVID_MASK 0x100 ++#define RTL8367C_OP76_NOT_OFFSET 6 ++#define RTL8367C_OP76_NOT_MASK 0x40 ++#define RTL8367C_ACT76_GPIO_OFFSET 5 ++#define RTL8367C_ACT76_GPIO_MASK 0x20 ++#define RTL8367C_ACT76_FORWARD_OFFSET 4 ++#define RTL8367C_ACT76_FORWARD_MASK 0x10 ++#define RTL8367C_ACT76_POLICING_OFFSET 3 ++#define RTL8367C_ACT76_POLICING_MASK 0x8 ++#define RTL8367C_ACT76_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT76_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT76_SVID_OFFSET 1 ++#define RTL8367C_ACT76_SVID_MASK 0x2 ++#define RTL8367C_ACT76_CVID_OFFSET 0 ++#define RTL8367C_ACT76_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL39 0x06F7 ++#define RTL8367C_OP79_NOT_OFFSET 14 ++#define RTL8367C_OP79_NOT_MASK 0x4000 ++#define RTL8367C_ACT79_GPIO_OFFSET 13 ++#define RTL8367C_ACT79_GPIO_MASK 0x2000 ++#define RTL8367C_ACT79_FORWARD_OFFSET 12 ++#define RTL8367C_ACT79_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT79_POLICING_OFFSET 11 ++#define RTL8367C_ACT79_POLICING_MASK 0x800 ++#define RTL8367C_ACT79_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT79_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT79_SVID_OFFSET 9 ++#define RTL8367C_ACT79_SVID_MASK 0x200 ++#define RTL8367C_ACT79_CVID_OFFSET 8 ++#define RTL8367C_ACT79_CVID_MASK 0x100 ++#define RTL8367C_OP78_NOT_OFFSET 6 ++#define RTL8367C_OP78_NOT_MASK 0x40 ++#define RTL8367C_ACT78_GPIO_OFFSET 5 ++#define RTL8367C_ACT78_GPIO_MASK 0x20 ++#define RTL8367C_ACT78_FORWARD_OFFSET 4 ++#define RTL8367C_ACT78_FORWARD_MASK 0x10 ++#define RTL8367C_ACT78_POLICING_OFFSET 3 ++#define RTL8367C_ACT78_POLICING_MASK 0x8 ++#define RTL8367C_ACT78_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT78_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT78_SVID_OFFSET 1 ++#define RTL8367C_ACT78_SVID_MASK 0x2 ++#define RTL8367C_ACT78_CVID_OFFSET 0 ++#define RTL8367C_ACT78_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL40 0x06F8 ++#define RTL8367C_OP81_NOT_OFFSET 14 ++#define RTL8367C_OP81_NOT_MASK 0x4000 ++#define RTL8367C_ACT81_GPIO_OFFSET 13 ++#define RTL8367C_ACT81_GPIO_MASK 0x2000 ++#define RTL8367C_ACT81_FORWARD_OFFSET 12 ++#define RTL8367C_ACT81_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT81_POLICING_OFFSET 11 ++#define RTL8367C_ACT81_POLICING_MASK 0x800 ++#define RTL8367C_ACT81_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT81_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT81_SVID_OFFSET 9 ++#define RTL8367C_ACT81_SVID_MASK 0x200 ++#define RTL8367C_ACT81_CVID_OFFSET 8 ++#define RTL8367C_ACT81_CVID_MASK 0x100 ++#define RTL8367C_OP80_NOT_OFFSET 6 ++#define RTL8367C_OP80_NOT_MASK 0x40 ++#define RTL8367C_ACT80_GPIO_OFFSET 5 ++#define RTL8367C_ACT80_GPIO_MASK 0x20 ++#define RTL8367C_ACT80_FORWARD_OFFSET 4 ++#define RTL8367C_ACT80_FORWARD_MASK 0x10 ++#define RTL8367C_ACT80_POLICING_OFFSET 3 ++#define RTL8367C_ACT80_POLICING_MASK 0x8 ++#define RTL8367C_ACT80_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT80_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT80_SVID_OFFSET 1 ++#define RTL8367C_ACT80_SVID_MASK 0x2 ++#define RTL8367C_ACT80_CVID_OFFSET 0 ++#define RTL8367C_ACT80_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL41 0x06F9 ++#define RTL8367C_OP83_NOT_OFFSET 14 ++#define RTL8367C_OP83_NOT_MASK 0x4000 ++#define RTL8367C_ACT83_GPIO_OFFSET 13 ++#define RTL8367C_ACT83_GPIO_MASK 0x2000 ++#define RTL8367C_ACT83_FORWARD_OFFSET 12 ++#define RTL8367C_ACT83_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT83_POLICING_OFFSET 11 ++#define RTL8367C_ACT83_POLICING_MASK 0x800 ++#define RTL8367C_ACT83_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT83_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT83_SVID_OFFSET 9 ++#define RTL8367C_ACT83_SVID_MASK 0x200 ++#define RTL8367C_ACT83_CVID_OFFSET 8 ++#define RTL8367C_ACT83_CVID_MASK 0x100 ++#define RTL8367C_OP82_NOT_OFFSET 6 ++#define RTL8367C_OP82_NOT_MASK 0x40 ++#define RTL8367C_ACT82_GPIO_OFFSET 5 ++#define RTL8367C_ACT82_GPIO_MASK 0x20 ++#define RTL8367C_ACT82_FORWARD_OFFSET 4 ++#define RTL8367C_ACT82_FORWARD_MASK 0x10 ++#define RTL8367C_ACT82_POLICING_OFFSET 3 ++#define RTL8367C_ACT82_POLICING_MASK 0x8 ++#define RTL8367C_ACT82_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT82_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT82_SVID_OFFSET 1 ++#define RTL8367C_ACT82_SVID_MASK 0x2 ++#define RTL8367C_ACT82_CVID_OFFSET 0 ++#define RTL8367C_ACT82_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL42 0x06FA ++#define RTL8367C_OP85_NOT_OFFSET 14 ++#define RTL8367C_OP85_NOT_MASK 0x4000 ++#define RTL8367C_ACT85_GPIO_OFFSET 13 ++#define RTL8367C_ACT85_GPIO_MASK 0x2000 ++#define RTL8367C_ACT85_FORWARD_OFFSET 12 ++#define RTL8367C_ACT85_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT85_POLICING_OFFSET 11 ++#define RTL8367C_ACT85_POLICING_MASK 0x800 ++#define RTL8367C_ACT85_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT85_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT85_SVID_OFFSET 9 ++#define RTL8367C_ACT85_SVID_MASK 0x200 ++#define RTL8367C_ACT85_CVID_OFFSET 8 ++#define RTL8367C_ACT85_CVID_MASK 0x100 ++#define RTL8367C_OP84_NOT_OFFSET 6 ++#define RTL8367C_OP84_NOT_MASK 0x40 ++#define RTL8367C_ACT84_GPIO_OFFSET 5 ++#define RTL8367C_ACT84_GPIO_MASK 0x20 ++#define RTL8367C_ACT84_FORWARD_OFFSET 4 ++#define RTL8367C_ACT84_FORWARD_MASK 0x10 ++#define RTL8367C_ACT84_POLICING_OFFSET 3 ++#define RTL8367C_ACT84_POLICING_MASK 0x8 ++#define RTL8367C_ACT84_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT84_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT84_SVID_OFFSET 1 ++#define RTL8367C_ACT84_SVID_MASK 0x2 ++#define RTL8367C_ACT84_CVID_OFFSET 0 ++#define RTL8367C_ACT84_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL43 0x06FB ++#define RTL8367C_OP87_NOT_OFFSET 14 ++#define RTL8367C_OP87_NOT_MASK 0x4000 ++#define RTL8367C_ACT87_GPIO_OFFSET 13 ++#define RTL8367C_ACT87_GPIO_MASK 0x2000 ++#define RTL8367C_ACT87_FORWARD_OFFSET 12 ++#define RTL8367C_ACT87_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT87_POLICING_OFFSET 11 ++#define RTL8367C_ACT87_POLICING_MASK 0x800 ++#define RTL8367C_ACT87_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT87_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT87_SVID_OFFSET 9 ++#define RTL8367C_ACT87_SVID_MASK 0x200 ++#define RTL8367C_ACT87_CVID_OFFSET 8 ++#define RTL8367C_ACT87_CVID_MASK 0x100 ++#define RTL8367C_OP86_NOT_OFFSET 6 ++#define RTL8367C_OP86_NOT_MASK 0x40 ++#define RTL8367C_ACT86_GPIO_OFFSET 5 ++#define RTL8367C_ACT86_GPIO_MASK 0x20 ++#define RTL8367C_ACT86_FORWARD_OFFSET 4 ++#define RTL8367C_ACT86_FORWARD_MASK 0x10 ++#define RTL8367C_ACT86_POLICING_OFFSET 3 ++#define RTL8367C_ACT86_POLICING_MASK 0x8 ++#define RTL8367C_ACT86_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT86_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT86_SVID_OFFSET 1 ++#define RTL8367C_ACT86_SVID_MASK 0x2 ++#define RTL8367C_ACT86_CVID_OFFSET 0 ++#define RTL8367C_ACT86_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL44 0x06FC ++#define RTL8367C_OP89_NOT_OFFSET 14 ++#define RTL8367C_OP89_NOT_MASK 0x4000 ++#define RTL8367C_ACT89_GPIO_OFFSET 13 ++#define RTL8367C_ACT89_GPIO_MASK 0x2000 ++#define RTL8367C_ACT89_FORWARD_OFFSET 12 ++#define RTL8367C_ACT89_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT89_POLICING_OFFSET 11 ++#define RTL8367C_ACT89_POLICING_MASK 0x800 ++#define RTL8367C_ACT89_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT89_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT89_SVID_OFFSET 9 ++#define RTL8367C_ACT89_SVID_MASK 0x200 ++#define RTL8367C_ACT89_CVID_OFFSET 8 ++#define RTL8367C_ACT89_CVID_MASK 0x100 ++#define RTL8367C_OP88_NOT_OFFSET 6 ++#define RTL8367C_OP88_NOT_MASK 0x40 ++#define RTL8367C_ACT88_GPIO_OFFSET 5 ++#define RTL8367C_ACT88_GPIO_MASK 0x20 ++#define RTL8367C_ACT88_FORWARD_OFFSET 4 ++#define RTL8367C_ACT88_FORWARD_MASK 0x10 ++#define RTL8367C_ACT88_POLICING_OFFSET 3 ++#define RTL8367C_ACT88_POLICING_MASK 0x8 ++#define RTL8367C_ACT88_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT88_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT88_SVID_OFFSET 1 ++#define RTL8367C_ACT88_SVID_MASK 0x2 ++#define RTL8367C_ACT88_CVID_OFFSET 0 ++#define RTL8367C_ACT88_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL45 0x06FD ++#define RTL8367C_OP91_NOT_OFFSET 14 ++#define RTL8367C_OP91_NOT_MASK 0x4000 ++#define RTL8367C_ACT91_GPIO_OFFSET 13 ++#define RTL8367C_ACT91_GPIO_MASK 0x2000 ++#define RTL8367C_ACT91_FORWARD_OFFSET 12 ++#define RTL8367C_ACT91_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT91_POLICING_OFFSET 11 ++#define RTL8367C_ACT91_POLICING_MASK 0x800 ++#define RTL8367C_ACT91_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT91_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT91_SVID_OFFSET 9 ++#define RTL8367C_ACT91_SVID_MASK 0x200 ++#define RTL8367C_ACT91_CVID_OFFSET 8 ++#define RTL8367C_ACT91_CVID_MASK 0x100 ++#define RTL8367C_OP90_NOT_OFFSET 6 ++#define RTL8367C_OP90_NOT_MASK 0x40 ++#define RTL8367C_ACT90_GPIO_OFFSET 5 ++#define RTL8367C_ACT90_GPIO_MASK 0x20 ++#define RTL8367C_ACT90_FORWARD_OFFSET 4 ++#define RTL8367C_ACT90_FORWARD_MASK 0x10 ++#define RTL8367C_ACT90_POLICING_OFFSET 3 ++#define RTL8367C_ACT90_POLICING_MASK 0x8 ++#define RTL8367C_ACT90_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT90_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT90_SVID_OFFSET 1 ++#define RTL8367C_ACT90_SVID_MASK 0x2 ++#define RTL8367C_ACT90_CVID_OFFSET 0 ++#define RTL8367C_ACT90_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL46 0x06FE ++#define RTL8367C_OP93_NOT_OFFSET 14 ++#define RTL8367C_OP93_NOT_MASK 0x4000 ++#define RTL8367C_ACT93_GPIO_OFFSET 13 ++#define RTL8367C_ACT93_GPIO_MASK 0x2000 ++#define RTL8367C_ACT93_FORWARD_OFFSET 12 ++#define RTL8367C_ACT93_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT93_POLICING_OFFSET 11 ++#define RTL8367C_ACT93_POLICING_MASK 0x800 ++#define RTL8367C_ACT93_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT93_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT93_SVID_OFFSET 9 ++#define RTL8367C_ACT93_SVID_MASK 0x200 ++#define RTL8367C_ACT93_CVID_OFFSET 8 ++#define RTL8367C_ACT93_CVID_MASK 0x100 ++#define RTL8367C_OP92_NOT_OFFSET 6 ++#define RTL8367C_OP92_NOT_MASK 0x40 ++#define RTL8367C_ACT92_GPIO_OFFSET 5 ++#define RTL8367C_ACT92_GPIO_MASK 0x20 ++#define RTL8367C_ACT92_FORWARD_OFFSET 4 ++#define RTL8367C_ACT92_FORWARD_MASK 0x10 ++#define RTL8367C_ACT92_POLICING_OFFSET 3 ++#define RTL8367C_ACT92_POLICING_MASK 0x8 ++#define RTL8367C_ACT92_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT92_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT92_SVID_OFFSET 1 ++#define RTL8367C_ACT92_SVID_MASK 0x2 ++#define RTL8367C_ACT92_CVID_OFFSET 0 ++#define RTL8367C_ACT92_CVID_MASK 0x1 ++ ++#define RTL8367C_REG_ACL_ACTION_CTRL47 0x06FF ++#define RTL8367C_OP95_NOT_OFFSET 14 ++#define RTL8367C_OP95_NOT_MASK 0x4000 ++#define RTL8367C_ACT95_GPIO_OFFSET 13 ++#define RTL8367C_ACT95_GPIO_MASK 0x2000 ++#define RTL8367C_ACT95_FORWARD_OFFSET 12 ++#define RTL8367C_ACT95_FORWARD_MASK 0x1000 ++#define RTL8367C_ACT95_POLICING_OFFSET 11 ++#define RTL8367C_ACT95_POLICING_MASK 0x800 ++#define RTL8367C_ACT95_PRIORITY_OFFSET 10 ++#define RTL8367C_ACT95_PRIORITY_MASK 0x400 ++#define RTL8367C_ACT95_SVID_OFFSET 9 ++#define RTL8367C_ACT95_SVID_MASK 0x200 ++#define RTL8367C_ACT95_CVID_OFFSET 8 ++#define RTL8367C_ACT95_CVID_MASK 0x100 ++#define RTL8367C_OP94_NOT_OFFSET 6 ++#define RTL8367C_OP94_NOT_MASK 0x40 ++#define RTL8367C_ACT94_GPIO_OFFSET 5 ++#define RTL8367C_ACT94_GPIO_MASK 0x20 ++#define RTL8367C_ACT94_FORWARD_OFFSET 4 ++#define RTL8367C_ACT94_FORWARD_MASK 0x10 ++#define RTL8367C_ACT94_POLICING_OFFSET 3 ++#define RTL8367C_ACT94_POLICING_MASK 0x8 ++#define RTL8367C_ACT94_PRIORITY_OFFSET 2 ++#define RTL8367C_ACT94_PRIORITY_MASK 0x4 ++#define RTL8367C_ACT94_SVID_OFFSET 1 ++#define RTL8367C_ACT94_SVID_MASK 0x2 ++#define RTL8367C_ACT94_CVID_OFFSET 0 ++#define RTL8367C_ACT94_CVID_MASK 0x1 ++ ++/* (16'h0700)cvlan_reg */ ++ ++#define RTL8367C_REG_VLAN_PVID_CTRL0 0x0700 ++#define RTL8367C_PORT1_VIDX_OFFSET 8 ++#define RTL8367C_PORT1_VIDX_MASK 0x1F00 ++#define RTL8367C_PORT0_VIDX_OFFSET 0 ++#define RTL8367C_PORT0_VIDX_MASK 0x1F ++ ++#define RTL8367C_REG_VLAN_PVID_CTRL1 0x0701 ++#define RTL8367C_PORT3_VIDX_OFFSET 8 ++#define RTL8367C_PORT3_VIDX_MASK 0x1F00 ++#define RTL8367C_PORT2_VIDX_OFFSET 0 ++#define RTL8367C_PORT2_VIDX_MASK 0x1F ++ ++#define RTL8367C_REG_VLAN_PVID_CTRL2 0x0702 ++#define RTL8367C_PORT5_VIDX_OFFSET 8 ++#define RTL8367C_PORT5_VIDX_MASK 0x1F00 ++#define RTL8367C_PORT4_VIDX_OFFSET 0 ++#define RTL8367C_PORT4_VIDX_MASK 0x1F ++ ++#define RTL8367C_REG_VLAN_PVID_CTRL3 0x0703 ++#define RTL8367C_PORT7_VIDX_OFFSET 8 ++#define RTL8367C_PORT7_VIDX_MASK 0x1F00 ++#define RTL8367C_PORT6_VIDX_OFFSET 0 ++#define RTL8367C_PORT6_VIDX_MASK 0x1F ++ ++#define RTL8367C_REG_VLAN_PVID_CTRL4 0x0704 ++#define RTL8367C_PORT9_VIDX_OFFSET 8 ++#define RTL8367C_PORT9_VIDX_MASK 0x1F00 ++#define RTL8367C_PORT8_VIDX_OFFSET 0 ++#define RTL8367C_PORT8_VIDX_MASK 0x1F ++ ++#define RTL8367C_REG_VLAN_PVID_CTRL5 0x0705 ++#define RTL8367C_VLAN_PVID_CTRL5_OFFSET 0 ++#define RTL8367C_VLAN_PVID_CTRL5_MASK 0x1F ++ ++#define RTL8367C_REG_VLAN_PPB0_VALID 0x0708 ++#define RTL8367C_VLAN_PPB0_VALID_VALID_EXT_OFFSET 8 ++#define RTL8367C_VLAN_PPB0_VALID_VALID_EXT_MASK 0x700 ++#define RTL8367C_VLAN_PPB0_VALID_VALID_OFFSET 0 ++#define RTL8367C_VLAN_PPB0_VALID_VALID_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_PPB0_CTRL0 0x0709 ++#define RTL8367C_VLAN_PPB0_CTRL0_PORT2_INDEX_OFFSET 10 ++#define RTL8367C_VLAN_PPB0_CTRL0_PORT2_INDEX_MASK 0x7C00 ++#define RTL8367C_VLAN_PPB0_CTRL0_PORT1_INDEX_OFFSET 5 ++#define RTL8367C_VLAN_PPB0_CTRL0_PORT1_INDEX_MASK 0x3E0 ++#define RTL8367C_VLAN_PPB0_CTRL0_PORT0_INDEX_OFFSET 0 ++#define RTL8367C_VLAN_PPB0_CTRL0_PORT0_INDEX_MASK 0x1F ++ ++#define RTL8367C_REG_VLAN_PPB0_CTRL1 0x070a ++#define RTL8367C_VLAN_PPB0_CTRL1_PORT5_INDEX_OFFSET 10 ++#define RTL8367C_VLAN_PPB0_CTRL1_PORT5_INDEX_MASK 0x7C00 ++#define RTL8367C_VLAN_PPB0_CTRL1_PORT4_INDEX_OFFSET 5 ++#define RTL8367C_VLAN_PPB0_CTRL1_PORT4_INDEX_MASK 0x3E0 ++#define RTL8367C_VLAN_PPB0_CTRL1_PORT3_INDEX_OFFSET 0 ++#define RTL8367C_VLAN_PPB0_CTRL1_PORT3_INDEX_MASK 0x1F ++ ++#define RTL8367C_REG_VLAN_PPB0_CTRL2 0x070b ++#define RTL8367C_VLAN_PPB0_CTRL2_FRAME_TYPE_OFFSET 10 ++#define RTL8367C_VLAN_PPB0_CTRL2_FRAME_TYPE_MASK 0xC00 ++#define RTL8367C_VLAN_PPB0_CTRL2_PORT7_INDEX_OFFSET 5 ++#define RTL8367C_VLAN_PPB0_CTRL2_PORT7_INDEX_MASK 0x3E0 ++#define RTL8367C_VLAN_PPB0_CTRL2_PORT6_INDEX_OFFSET 0 ++#define RTL8367C_VLAN_PPB0_CTRL2_PORT6_INDEX_MASK 0x1F ++ ++#define RTL8367C_REG_VLAN_PPB0_CTRL4 0x070c ++#define RTL8367C_VLAN_PPB0_CTRL4_PORT10_INDEX_OFFSET 10 ++#define RTL8367C_VLAN_PPB0_CTRL4_PORT10_INDEX_MASK 0x7C00 ++#define RTL8367C_VLAN_PPB0_CTRL4_PORT9_INDEX_OFFSET 5 ++#define RTL8367C_VLAN_PPB0_CTRL4_PORT9_INDEX_MASK 0x3E0 ++#define RTL8367C_VLAN_PPB0_CTRL4_PORT8_INDEX_OFFSET 0 ++#define RTL8367C_VLAN_PPB0_CTRL4_PORT8_INDEX_MASK 0x1F ++ ++#define RTL8367C_REG_VLAN_PPB0_CTRL3 0x070f ++ ++#define RTL8367C_REG_VLAN_PPB1_VALID 0x0710 ++#define RTL8367C_VLAN_PPB1_VALID_VALID_EXT_OFFSET 8 ++#define RTL8367C_VLAN_PPB1_VALID_VALID_EXT_MASK 0x700 ++#define RTL8367C_VLAN_PPB1_VALID_VALID_OFFSET 0 ++#define RTL8367C_VLAN_PPB1_VALID_VALID_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_PPB1_CTRL0 0x0711 ++#define RTL8367C_VLAN_PPB1_CTRL0_PORT2_INDEX_OFFSET 10 ++#define RTL8367C_VLAN_PPB1_CTRL0_PORT2_INDEX_MASK 0x7C00 ++#define RTL8367C_VLAN_PPB1_CTRL0_PORT1_INDEX_OFFSET 5 ++#define RTL8367C_VLAN_PPB1_CTRL0_PORT1_INDEX_MASK 0x3E0 ++#define RTL8367C_VLAN_PPB1_CTRL0_PORT0_INDEX_OFFSET 0 ++#define RTL8367C_VLAN_PPB1_CTRL0_PORT0_INDEX_MASK 0x1F ++ ++#define RTL8367C_REG_VLAN_PPB1_CTRL1 0x0712 ++#define RTL8367C_VLAN_PPB1_CTRL1_PORT5_INDEX_OFFSET 10 ++#define RTL8367C_VLAN_PPB1_CTRL1_PORT5_INDEX_MASK 0x7C00 ++#define RTL8367C_VLAN_PPB1_CTRL1_PORT4_INDEX_OFFSET 5 ++#define RTL8367C_VLAN_PPB1_CTRL1_PORT4_INDEX_MASK 0x3E0 ++#define RTL8367C_VLAN_PPB1_CTRL1_PORT3_INDEX_OFFSET 0 ++#define RTL8367C_VLAN_PPB1_CTRL1_PORT3_INDEX_MASK 0x1F ++ ++#define RTL8367C_REG_VLAN_PPB1_CTRL2 0x0713 ++#define RTL8367C_VLAN_PPB1_CTRL2_FRAME_TYPE_OFFSET 10 ++#define RTL8367C_VLAN_PPB1_CTRL2_FRAME_TYPE_MASK 0xC00 ++#define RTL8367C_VLAN_PPB1_CTRL2_PORT7_INDEX_OFFSET 5 ++#define RTL8367C_VLAN_PPB1_CTRL2_PORT7_INDEX_MASK 0x3E0 ++#define RTL8367C_VLAN_PPB1_CTRL2_PORT6_INDEX_OFFSET 0 ++#define RTL8367C_VLAN_PPB1_CTRL2_PORT6_INDEX_MASK 0x1F ++ ++#define RTL8367C_REG_VLAN_PPB1_CTRL4 0x0714 ++#define RTL8367C_VLAN_PPB1_CTRL4_PORT10_INDEX_OFFSET 10 ++#define RTL8367C_VLAN_PPB1_CTRL4_PORT10_INDEX_MASK 0x7C00 ++#define RTL8367C_VLAN_PPB1_CTRL4_PORT9_INDEX_OFFSET 5 ++#define RTL8367C_VLAN_PPB1_CTRL4_PORT9_INDEX_MASK 0x3E0 ++#define RTL8367C_VLAN_PPB1_CTRL4_PORT8_INDEX_OFFSET 0 ++#define RTL8367C_VLAN_PPB1_CTRL4_PORT8_INDEX_MASK 0x1F ++ ++#define RTL8367C_REG_VLAN_PPB1_CTRL3 0x0717 ++ ++#define RTL8367C_REG_VLAN_PPB2_VALID 0x0718 ++#define RTL8367C_VLAN_PPB2_VALID_VALID_EXT_OFFSET 8 ++#define RTL8367C_VLAN_PPB2_VALID_VALID_EXT_MASK 0x700 ++#define RTL8367C_VLAN_PPB2_VALID_VALID_OFFSET 0 ++#define RTL8367C_VLAN_PPB2_VALID_VALID_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_PPB2_CTRL0 0x0719 ++#define RTL8367C_VLAN_PPB2_CTRL0_PORT2_INDEX_OFFSET 10 ++#define RTL8367C_VLAN_PPB2_CTRL0_PORT2_INDEX_MASK 0x7C00 ++#define RTL8367C_VLAN_PPB2_CTRL0_PORT1_INDEX_OFFSET 5 ++#define RTL8367C_VLAN_PPB2_CTRL0_PORT1_INDEX_MASK 0x3E0 ++#define RTL8367C_VLAN_PPB2_CTRL0_PORT0_INDEX_OFFSET 0 ++#define RTL8367C_VLAN_PPB2_CTRL0_PORT0_INDEX_MASK 0x1F ++ ++#define RTL8367C_REG_VLAN_PPB2_CTRL1 0x071a ++#define RTL8367C_VLAN_PPB2_CTRL1_PORT5_INDEX_OFFSET 10 ++#define RTL8367C_VLAN_PPB2_CTRL1_PORT5_INDEX_MASK 0x7C00 ++#define RTL8367C_VLAN_PPB2_CTRL1_PORT4_INDEX_OFFSET 5 ++#define RTL8367C_VLAN_PPB2_CTRL1_PORT4_INDEX_MASK 0x3E0 ++#define RTL8367C_VLAN_PPB2_CTRL1_PORT3_INDEX_OFFSET 0 ++#define RTL8367C_VLAN_PPB2_CTRL1_PORT3_INDEX_MASK 0x1F ++ ++#define RTL8367C_REG_VLAN_PPB2_CTRL2 0x071b ++#define RTL8367C_VLAN_PPB2_CTRL2_FRAME_TYPE_OFFSET 10 ++#define RTL8367C_VLAN_PPB2_CTRL2_FRAME_TYPE_MASK 0xC00 ++#define RTL8367C_VLAN_PPB2_CTRL2_PORT7_INDEX_OFFSET 5 ++#define RTL8367C_VLAN_PPB2_CTRL2_PORT7_INDEX_MASK 0x3E0 ++#define RTL8367C_VLAN_PPB2_CTRL2_PORT6_INDEX_OFFSET 0 ++#define RTL8367C_VLAN_PPB2_CTRL2_PORT6_INDEX_MASK 0x1F ++ ++#define RTL8367C_REG_VLAN_PPB2_CTRL4 0x071c ++#define RTL8367C_VLAN_PPB2_CTRL4_PORT10_INDEX_OFFSET 10 ++#define RTL8367C_VLAN_PPB2_CTRL4_PORT10_INDEX_MASK 0x7C00 ++#define RTL8367C_VLAN_PPB2_CTRL4_PORT9_INDEX_OFFSET 5 ++#define RTL8367C_VLAN_PPB2_CTRL4_PORT9_INDEX_MASK 0x3E0 ++#define RTL8367C_VLAN_PPB2_CTRL4_PORT8_INDEX_OFFSET 0 ++#define RTL8367C_VLAN_PPB2_CTRL4_PORT8_INDEX_MASK 0x1F ++ ++#define RTL8367C_REG_VLAN_PPB2_CTRL3 0x071f ++ ++#define RTL8367C_REG_VLAN_PPB3_VALID 0x0720 ++#define RTL8367C_VLAN_PPB3_VALID_VALID_EXT_OFFSET 8 ++#define RTL8367C_VLAN_PPB3_VALID_VALID_EXT_MASK 0x700 ++#define RTL8367C_VLAN_PPB3_VALID_VALID_OFFSET 0 ++#define RTL8367C_VLAN_PPB3_VALID_VALID_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_PPB3_CTRL0 0x0721 ++#define RTL8367C_VLAN_PPB3_CTRL0_PORT2_INDEX_OFFSET 10 ++#define RTL8367C_VLAN_PPB3_CTRL0_PORT2_INDEX_MASK 0x7C00 ++#define RTL8367C_VLAN_PPB3_CTRL0_PORT1_INDEX_OFFSET 5 ++#define RTL8367C_VLAN_PPB3_CTRL0_PORT1_INDEX_MASK 0x3E0 ++#define RTL8367C_VLAN_PPB3_CTRL0_PORT0_INDEX_OFFSET 0 ++#define RTL8367C_VLAN_PPB3_CTRL0_PORT0_INDEX_MASK 0x1F ++ ++#define RTL8367C_REG_VLAN_PPB3_CTRL1 0x0722 ++#define RTL8367C_VLAN_PPB3_CTRL1_PORT5_INDEX_OFFSET 10 ++#define RTL8367C_VLAN_PPB3_CTRL1_PORT5_INDEX_MASK 0x7C00 ++#define RTL8367C_VLAN_PPB3_CTRL1_PORT4_INDEX_OFFSET 5 ++#define RTL8367C_VLAN_PPB3_CTRL1_PORT4_INDEX_MASK 0x3E0 ++#define RTL8367C_VLAN_PPB3_CTRL1_PORT3_INDEX_OFFSET 0 ++#define RTL8367C_VLAN_PPB3_CTRL1_PORT3_INDEX_MASK 0x1F ++ ++#define RTL8367C_REG_VLAN_PPB3_CTRL2 0x0723 ++#define RTL8367C_VLAN_PPB3_CTRL2_FRAME_TYPE_OFFSET 10 ++#define RTL8367C_VLAN_PPB3_CTRL2_FRAME_TYPE_MASK 0xC00 ++#define RTL8367C_VLAN_PPB3_CTRL2_PORT7_INDEX_OFFSET 5 ++#define RTL8367C_VLAN_PPB3_CTRL2_PORT7_INDEX_MASK 0x3E0 ++#define RTL8367C_VLAN_PPB3_CTRL2_PORT6_INDEX_OFFSET 0 ++#define RTL8367C_VLAN_PPB3_CTRL2_PORT6_INDEX_MASK 0x1F ++ ++#define RTL8367C_REG_VLAN_PPB3_CTRL4 0x0724 ++#define RTL8367C_VLAN_PPB3_CTRL4_PORT10_INDEX_OFFSET 10 ++#define RTL8367C_VLAN_PPB3_CTRL4_PORT10_INDEX_MASK 0x7C00 ++#define RTL8367C_VLAN_PPB3_CTRL4_PORT9_INDEX_OFFSET 5 ++#define RTL8367C_VLAN_PPB3_CTRL4_PORT9_INDEX_MASK 0x3E0 ++#define RTL8367C_VLAN_PPB3_CTRL4_PORT8_INDEX_OFFSET 0 ++#define RTL8367C_VLAN_PPB3_CTRL4_PORT8_INDEX_MASK 0x1F ++ ++#define RTL8367C_REG_VLAN_PPB3_CTRL3 0x0727 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION0_CTRL0 0x0728 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION0_CTRL1 0x0729 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION0_CTRL2 0x072a ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION0_CTRL3 0x072b ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION0_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION1_CTRL0 0x072c ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION1_CTRL1 0x072d ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION1_CTRL2 0x072e ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION1_CTRL3 0x072f ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION1_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION2_CTRL0 0x0730 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION2_CTRL1 0x0731 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION2_CTRL2 0x0732 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION2_CTRL3 0x0733 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION2_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION3_CTRL0 0x0734 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION3_CTRL1 0x0735 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION3_CTRL2 0x0736 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION3_CTRL3 0x0737 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION3_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION4_CTRL0 0x0738 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION4_CTRL1 0x0739 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION4_CTRL2 0x073a ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION4_CTRL3 0x073b ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION4_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION5_CTRL0 0x073c ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION5_CTRL1 0x073d ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION5_CTRL2 0x073e ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION5_CTRL3 0x073f ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION5_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION6_CTRL0 0x0740 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION6_CTRL1 0x0741 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION6_CTRL2 0x0742 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION6_CTRL3 0x0743 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION6_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION7_CTRL0 0x0744 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION7_CTRL1 0x0745 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION7_CTRL2 0x0746 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION7_CTRL3 0x0747 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION7_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION8_CTRL0 0x0748 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION8_CTRL1 0x0749 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION8_CTRL2 0x074a ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION8_CTRL3 0x074b ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION8_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION9_CTRL0 0x074c ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION9_CTRL1 0x074d ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION9_CTRL2 0x074e ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION9_CTRL3 0x074f ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION9_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION10_CTRL0 0x0750 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION10_CTRL1 0x0751 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION10_CTRL2 0x0752 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION10_CTRL3 0x0753 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION10_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION11_CTRL0 0x0754 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION11_CTRL1 0x0755 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION11_CTRL2 0x0756 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION11_CTRL3 0x0757 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION11_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION12_CTRL0 0x0758 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION12_CTRL1 0x0759 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION12_CTRL2 0x075a ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION12_CTRL3 0x075b ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION12_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION13_CTRL0 0x075c ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION13_CTRL1 0x075d ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION13_CTRL2 0x075e ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION13_CTRL3 0x075f ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION13_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION14_CTRL0 0x0760 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION14_CTRL1 0x0761 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION14_CTRL2 0x0762 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION14_CTRL3 0x0763 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION14_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION15_CTRL0 0x0764 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION15_CTRL1 0x0765 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION15_CTRL2 0x0766 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION15_CTRL3 0x0767 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION15_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION16_CTRL0 0x0768 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION16_CTRL1 0x0769 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION16_CTRL2 0x076a ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION16_CTRL3 0x076b ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION16_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION17_CTRL0 0x076c ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION17_CTRL1 0x076d ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION17_CTRL2 0x076e ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION17_CTRL3 0x076f ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION17_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION18_CTRL0 0x0770 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION18_CTRL1 0x0771 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION18_CTRL2 0x0772 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION18_CTRL3 0x0773 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION18_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION19_CTRL0 0x0774 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION19_CTRL1 0x0775 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION19_CTRL2 0x0776 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION19_CTRL3 0x0777 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION19_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION20_CTRL0 0x0778 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION20_CTRL1 0x0779 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION20_CTRL2 0x077a ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION20_CTRL3 0x077b ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION20_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION21_CTRL0 0x077c ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION21_CTRL1 0x077d ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION21_CTRL2 0x077e ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION21_CTRL3 0x077f ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION21_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION22_CTRL0 0x0780 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION22_CTRL1 0x0781 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION22_CTRL2 0x0782 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION22_CTRL3 0x0783 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION22_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION23_CTRL0 0x0784 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION23_CTRL1 0x0785 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION23_CTRL2 0x0786 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION23_CTRL3 0x0787 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION23_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION24_CTRL0 0x0788 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION24_CTRL1 0x0789 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION24_CTRL2 0x078a ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION24_CTRL3 0x078b ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION24_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION25_CTRL0 0x078c ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION25_CTRL1 0x078d ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION25_CTRL2 0x078e ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION25_CTRL3 0x078f ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION25_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION26_CTRL0 0x0790 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION26_CTRL1 0x0791 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION26_CTRL2 0x0792 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION26_CTRL3 0x0793 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION26_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION27_CTRL0 0x0794 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION27_CTRL1 0x0795 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION27_CTRL2 0x0796 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION27_CTRL3 0x0797 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION27_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION28_CTRL0 0x0798 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION28_CTRL1 0x0799 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION28_CTRL2 0x079a ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION28_CTRL3 0x079b ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION28_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION29_CTRL0 0x079c ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION29_CTRL1 0x079d ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION29_CTRL2 0x079e ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION29_CTRL3 0x079f ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION29_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION30_CTRL0 0x07a0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION30_CTRL1 0x07a1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION30_CTRL2 0x07a2 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION30_CTRL3 0x07a3 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION30_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION31_CTRL0 0x07a4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL0_MBR_EXT_OFFSET 8 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL0_MBR_EXT_MASK 0x700 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL0_MBR_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL0_MBR_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION31_CTRL1 0x07a5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL1_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION31_CTRL2 0x07a6 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_METERIDX_EXT_OFFSET 10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_METERIDX_EXT_MASK 0x400 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_METERIDX_OFFSET 5 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_METERIDX_MASK 0x3E0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_ENVLANPOL_OFFSET 4 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_ENVLANPOL_MASK 0x10 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_VBPRI_OFFSET 1 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_VBPRI_MASK 0xE ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_VBPEN_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL2_VBPEN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_MEMBER_CONFIGURATION31_CTRL3 0x07a7 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_MEMBER_CONFIGURATION31_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_VLAN_CTRL 0x07a8 ++#define RTL8367C_VLAN_CTRL_OFFSET 0 ++#define RTL8367C_VLAN_CTRL_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_INGRESS 0x07a9 ++#define RTL8367C_VLAN_INGRESS_OFFSET 0 ++#define RTL8367C_VLAN_INGRESS_MASK 0x7FF ++ ++#define RTL8367C_REG_VLAN_ACCEPT_FRAME_TYPE_CTRL0 0x07aa ++#define RTL8367C_PORT7_FRAME_TYPE_OFFSET 14 ++#define RTL8367C_PORT7_FRAME_TYPE_MASK 0xC000 ++#define RTL8367C_PORT6_FRAME_TYPE_OFFSET 12 ++#define RTL8367C_PORT6_FRAME_TYPE_MASK 0x3000 ++#define RTL8367C_PORT5_FRAME_TYPE_OFFSET 10 ++#define RTL8367C_PORT5_FRAME_TYPE_MASK 0xC00 ++#define RTL8367C_PORT4_FRAME_TYPE_OFFSET 8 ++#define RTL8367C_PORT4_FRAME_TYPE_MASK 0x300 ++#define RTL8367C_PORT3_FRAME_TYPE_OFFSET 6 ++#define RTL8367C_PORT3_FRAME_TYPE_MASK 0xC0 ++#define RTL8367C_PORT2_FRAME_TYPE_OFFSET 4 ++#define RTL8367C_PORT2_FRAME_TYPE_MASK 0x30 ++#define RTL8367C_PORT1_FRAME_TYPE_OFFSET 2 ++#define RTL8367C_PORT1_FRAME_TYPE_MASK 0xC ++#define RTL8367C_PORT0_FRAME_TYPE_OFFSET 0 ++#define RTL8367C_PORT0_FRAME_TYPE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_ACCEPT_FRAME_TYPE_CTRL1 0x07ab ++#define RTL8367C_PORT10_FRAME_TYPE_OFFSET 4 ++#define RTL8367C_PORT10_FRAME_TYPE_MASK 0x30 ++#define RTL8367C_PORT9_FRAME_TYPE_OFFSET 2 ++#define RTL8367C_PORT9_FRAME_TYPE_MASK 0xC ++#define RTL8367C_PORT8_FRAME_TYPE_OFFSET 0 ++#define RTL8367C_PORT8_FRAME_TYPE_MASK 0x3 ++ ++#define RTL8367C_REG_PORT_PBFIDEN 0x07ac ++#define RTL8367C_PORT_PBFIDEN_OFFSET 0 ++#define RTL8367C_PORT_PBFIDEN_MASK 0x7FF ++ ++#define RTL8367C_REG_PORT0_PBFID 0x07ad ++#define RTL8367C_PORT0_PBFID_OFFSET 0 ++#define RTL8367C_PORT0_PBFID_MASK 0xF ++ ++#define RTL8367C_REG_PORT1_PBFID 0x07ae ++#define RTL8367C_PORT1_PBFID_OFFSET 0 ++#define RTL8367C_PORT1_PBFID_MASK 0xF ++ ++#define RTL8367C_REG_PORT2_PBFID 0x07af ++#define RTL8367C_PORT2_PBFID_OFFSET 0 ++#define RTL8367C_PORT2_PBFID_MASK 0xF ++ ++#define RTL8367C_REG_PORT3_PBFID 0x07b0 ++#define RTL8367C_PORT3_PBFID_OFFSET 0 ++#define RTL8367C_PORT3_PBFID_MASK 0xF ++ ++#define RTL8367C_REG_PORT4_PBFID 0x07b1 ++#define RTL8367C_PORT4_PBFID_OFFSET 0 ++#define RTL8367C_PORT4_PBFID_MASK 0xF ++ ++#define RTL8367C_REG_PORT5_PBFID 0x07b2 ++#define RTL8367C_PORT5_PBFID_OFFSET 0 ++#define RTL8367C_PORT5_PBFID_MASK 0xF ++ ++#define RTL8367C_REG_PORT6_PBFID 0x07b3 ++#define RTL8367C_PORT6_PBFID_OFFSET 0 ++#define RTL8367C_PORT6_PBFID_MASK 0xF ++ ++#define RTL8367C_REG_PORT7_PBFID 0x07b4 ++#define RTL8367C_PORT7_PBFID_OFFSET 0 ++#define RTL8367C_PORT7_PBFID_MASK 0xF ++ ++#define RTL8367C_REG_VLAN_EXT_CTRL 0x07b5 ++#define RTL8367C_VLAN_1P_REMARK_BYPASS_REALKEEP_OFFSET 2 ++#define RTL8367C_VLAN_1P_REMARK_BYPASS_REALKEEP_MASK 0x4 ++#define RTL8367C_VLAN_VID4095_TYPE_OFFSET 1 ++#define RTL8367C_VLAN_VID4095_TYPE_MASK 0x2 ++#define RTL8367C_VLAN_VID0_TYPE_OFFSET 0 ++#define RTL8367C_VLAN_VID0_TYPE_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_EXT_CTRL2 0x07b6 ++#define RTL8367C_VLAN_EXT_CTRL2_OFFSET 0 ++#define RTL8367C_VLAN_EXT_CTRL2_MASK 0x1 ++ ++#define RTL8367C_REG_PORT8_PBFID 0x07b7 ++#define RTL8367C_PORT8_PBFID_OFFSET 0 ++#define RTL8367C_PORT8_PBFID_MASK 0xF ++ ++#define RTL8367C_REG_PORT9_PBFID 0x07b8 ++#define RTL8367C_PORT9_PBFID_OFFSET 0 ++#define RTL8367C_PORT9_PBFID_MASK 0xF ++ ++#define RTL8367C_REG_PORT10_PBFID 0x07b9 ++#define RTL8367C_PORT10_PBFID_OFFSET 0 ++#define RTL8367C_PORT10_PBFID_MASK 0xF ++ ++#define RTL8367C_REG_CVLAN_DUMMY00 0x07E0 ++ ++#define RTL8367C_REG_CVLAN_DUMMY01 0x07E1 ++ ++#define RTL8367C_REG_CVLAN_DUMMY02 0x07E2 ++ ++#define RTL8367C_REG_CVLAN_DUMMY03 0x07E3 ++ ++#define RTL8367C_REG_CVLAN_DUMMY04 0x07E4 ++ ++#define RTL8367C_REG_CVLAN_DUMMY05 0x07E5 ++ ++#define RTL8367C_REG_CVLAN_DUMMY06 0x07E6 ++ ++#define RTL8367C_REG_CVLAN_DUMMY07 0x07E7 ++ ++#define RTL8367C_REG_CVLAN_DUMMY08 0x07E8 ++ ++#define RTL8367C_REG_CVLAN_DUMMY09 0x07E9 ++ ++#define RTL8367C_REG_CVLAN_DUMMY10 0x07EA ++ ++#define RTL8367C_REG_CVLAN_DUMMY11 0x07EB ++ ++#define RTL8367C_REG_CVLAN_DUMMY12 0x07EC ++ ++#define RTL8367C_REG_CVLAN_DUMMY13 0x07ED ++ ++#define RTL8367C_REG_CVLAN_DUMMY14 0x07EE ++ ++#define RTL8367C_REG_CVLAN_DUMMY15 0x07EF ++ ++/* (16'h0800)dpm_reg */ ++ ++#define RTL8367C_REG_RMA_CTRL00 0x0800 ++#define RTL8367C_RMA_CTRL00_OPERATION_OFFSET 7 ++#define RTL8367C_RMA_CTRL00_OPERATION_MASK 0x180 ++#define RTL8367C_RMA_CTRL00_DISCARD_STORM_FILTER_OFFSET 6 ++#define RTL8367C_RMA_CTRL00_DISCARD_STORM_FILTER_MASK 0x40 ++#define RTL8367C_TRAP_PRIORITY_OFFSET 3 ++#define RTL8367C_TRAP_PRIORITY_MASK 0x38 ++#define RTL8367C_RMA_CTRL00_KEEP_FORMAT_OFFSET 2 ++#define RTL8367C_RMA_CTRL00_KEEP_FORMAT_MASK 0x4 ++#define RTL8367C_RMA_CTRL00_VLAN_LEAKY_OFFSET 1 ++#define RTL8367C_RMA_CTRL00_VLAN_LEAKY_MASK 0x2 ++#define RTL8367C_RMA_CTRL00_PORTISO_LEAKY_OFFSET 0 ++#define RTL8367C_RMA_CTRL00_PORTISO_LEAKY_MASK 0x1 ++ ++#define RTL8367C_REG_RMA_CTRL01 0x0801 ++#define RTL8367C_RMA_CTRL01_OPERATION_OFFSET 7 ++#define RTL8367C_RMA_CTRL01_OPERATION_MASK 0x180 ++#define RTL8367C_RMA_CTRL01_DISCARD_STORM_FILTER_OFFSET 6 ++#define RTL8367C_RMA_CTRL01_DISCARD_STORM_FILTER_MASK 0x40 ++#define RTL8367C_RMA_CTRL01_KEEP_FORMAT_OFFSET 2 ++#define RTL8367C_RMA_CTRL01_KEEP_FORMAT_MASK 0x4 ++#define RTL8367C_RMA_CTRL01_VLAN_LEAKY_OFFSET 1 ++#define RTL8367C_RMA_CTRL01_VLAN_LEAKY_MASK 0x2 ++#define RTL8367C_RMA_CTRL01_PORTISO_LEAKY_OFFSET 0 ++#define RTL8367C_RMA_CTRL01_PORTISO_LEAKY_MASK 0x1 ++ ++#define RTL8367C_REG_RMA_CTRL02 0x0802 ++#define RTL8367C_RMA_CTRL02_OPERATION_OFFSET 7 ++#define RTL8367C_RMA_CTRL02_OPERATION_MASK 0x180 ++#define RTL8367C_RMA_CTRL02_DISCARD_STORM_FILTER_OFFSET 6 ++#define RTL8367C_RMA_CTRL02_DISCARD_STORM_FILTER_MASK 0x40 ++#define RTL8367C_RMA_CTRL02_KEEP_FORMAT_OFFSET 2 ++#define RTL8367C_RMA_CTRL02_KEEP_FORMAT_MASK 0x4 ++#define RTL8367C_RMA_CTRL02_VLAN_LEAKY_OFFSET 1 ++#define RTL8367C_RMA_CTRL02_VLAN_LEAKY_MASK 0x2 ++#define RTL8367C_RMA_CTRL02_PORTISO_LEAKY_OFFSET 0 ++#define RTL8367C_RMA_CTRL02_PORTISO_LEAKY_MASK 0x1 ++ ++#define RTL8367C_REG_RMA_CTRL03 0x0803 ++#define RTL8367C_RMA_CTRL03_OPERATION_OFFSET 7 ++#define RTL8367C_RMA_CTRL03_OPERATION_MASK 0x180 ++#define RTL8367C_RMA_CTRL03_DISCARD_STORM_FILTER_OFFSET 6 ++#define RTL8367C_RMA_CTRL03_DISCARD_STORM_FILTER_MASK 0x40 ++#define RTL8367C_RMA_CTRL03_KEEP_FORMAT_OFFSET 2 ++#define RTL8367C_RMA_CTRL03_KEEP_FORMAT_MASK 0x4 ++#define RTL8367C_RMA_CTRL03_VLAN_LEAKY_OFFSET 1 ++#define RTL8367C_RMA_CTRL03_VLAN_LEAKY_MASK 0x2 ++#define RTL8367C_RMA_CTRL03_PORTISO_LEAKY_OFFSET 0 ++#define RTL8367C_RMA_CTRL03_PORTISO_LEAKY_MASK 0x1 ++ ++#define RTL8367C_REG_RMA_CTRL04 0x0804 ++#define RTL8367C_RMA_CTRL04_OPERATION_OFFSET 7 ++#define RTL8367C_RMA_CTRL04_OPERATION_MASK 0x180 ++#define RTL8367C_RMA_CTRL04_DISCARD_STORM_FILTER_OFFSET 6 ++#define RTL8367C_RMA_CTRL04_DISCARD_STORM_FILTER_MASK 0x40 ++#define RTL8367C_RMA_CTRL04_KEEP_FORMAT_OFFSET 2 ++#define RTL8367C_RMA_CTRL04_KEEP_FORMAT_MASK 0x4 ++#define RTL8367C_RMA_CTRL04_VLAN_LEAKY_OFFSET 1 ++#define RTL8367C_RMA_CTRL04_VLAN_LEAKY_MASK 0x2 ++#define RTL8367C_RMA_CTRL04_PORTISO_LEAKY_OFFSET 0 ++#define RTL8367C_RMA_CTRL04_PORTISO_LEAKY_MASK 0x1 ++ ++#define RTL8367C_REG_RMA_CTRL08 0x0808 ++#define RTL8367C_RMA_CTRL08_OPERATION_OFFSET 7 ++#define RTL8367C_RMA_CTRL08_OPERATION_MASK 0x180 ++#define RTL8367C_RMA_CTRL08_DISCARD_STORM_FILTER_OFFSET 6 ++#define RTL8367C_RMA_CTRL08_DISCARD_STORM_FILTER_MASK 0x40 ++#define RTL8367C_RMA_CTRL08_KEEP_FORMAT_OFFSET 2 ++#define RTL8367C_RMA_CTRL08_KEEP_FORMAT_MASK 0x4 ++#define RTL8367C_RMA_CTRL08_VLAN_LEAKY_OFFSET 1 ++#define RTL8367C_RMA_CTRL08_VLAN_LEAKY_MASK 0x2 ++#define RTL8367C_RMA_CTRL08_PORTISO_LEAKY_OFFSET 0 ++#define RTL8367C_RMA_CTRL08_PORTISO_LEAKY_MASK 0x1 ++ ++#define RTL8367C_REG_RMA_CTRL0D 0x080d ++#define RTL8367C_RMA_CTRL0D_OPERATION_OFFSET 7 ++#define RTL8367C_RMA_CTRL0D_OPERATION_MASK 0x180 ++#define RTL8367C_RMA_CTRL0D_DISCARD_STORM_FILTER_OFFSET 6 ++#define RTL8367C_RMA_CTRL0D_DISCARD_STORM_FILTER_MASK 0x40 ++#define RTL8367C_RMA_CTRL0D_KEEP_FORMAT_OFFSET 2 ++#define RTL8367C_RMA_CTRL0D_KEEP_FORMAT_MASK 0x4 ++#define RTL8367C_RMA_CTRL0D_VLAN_LEAKY_OFFSET 1 ++#define RTL8367C_RMA_CTRL0D_VLAN_LEAKY_MASK 0x2 ++#define RTL8367C_RMA_CTRL0D_PORTISO_LEAKY_OFFSET 0 ++#define RTL8367C_RMA_CTRL0D_PORTISO_LEAKY_MASK 0x1 ++ ++#define RTL8367C_REG_RMA_CTRL0E 0x080e ++#define RTL8367C_RMA_CTRL0E_OPERATION_OFFSET 7 ++#define RTL8367C_RMA_CTRL0E_OPERATION_MASK 0x180 ++#define RTL8367C_RMA_CTRL0E_DISCARD_STORM_FILTER_OFFSET 6 ++#define RTL8367C_RMA_CTRL0E_DISCARD_STORM_FILTER_MASK 0x40 ++#define RTL8367C_RMA_CTRL0E_KEEP_FORMAT_OFFSET 2 ++#define RTL8367C_RMA_CTRL0E_KEEP_FORMAT_MASK 0x4 ++#define RTL8367C_RMA_CTRL0E_VLAN_LEAKY_OFFSET 1 ++#define RTL8367C_RMA_CTRL0E_VLAN_LEAKY_MASK 0x2 ++#define RTL8367C_RMA_CTRL0E_PORTISO_LEAKY_OFFSET 0 ++#define RTL8367C_RMA_CTRL0E_PORTISO_LEAKY_MASK 0x1 ++ ++#define RTL8367C_REG_RMA_CTRL10 0x0810 ++#define RTL8367C_RMA_CTRL10_OPERATION_OFFSET 7 ++#define RTL8367C_RMA_CTRL10_OPERATION_MASK 0x180 ++#define RTL8367C_RMA_CTRL10_DISCARD_STORM_FILTER_OFFSET 6 ++#define RTL8367C_RMA_CTRL10_DISCARD_STORM_FILTER_MASK 0x40 ++#define RTL8367C_RMA_CTRL10_KEEP_FORMAT_OFFSET 2 ++#define RTL8367C_RMA_CTRL10_KEEP_FORMAT_MASK 0x4 ++#define RTL8367C_RMA_CTRL10_VLAN_LEAKY_OFFSET 1 ++#define RTL8367C_RMA_CTRL10_VLAN_LEAKY_MASK 0x2 ++#define RTL8367C_RMA_CTRL10_PORTISO_LEAKY_OFFSET 0 ++#define RTL8367C_RMA_CTRL10_PORTISO_LEAKY_MASK 0x1 ++ ++#define RTL8367C_REG_RMA_CTRL11 0x0811 ++#define RTL8367C_RMA_CTRL11_OPERATION_OFFSET 7 ++#define RTL8367C_RMA_CTRL11_OPERATION_MASK 0x180 ++#define RTL8367C_RMA_CTRL11_DISCARD_STORM_FILTER_OFFSET 6 ++#define RTL8367C_RMA_CTRL11_DISCARD_STORM_FILTER_MASK 0x40 ++#define RTL8367C_RMA_CTRL11_KEEP_FORMAT_OFFSET 2 ++#define RTL8367C_RMA_CTRL11_KEEP_FORMAT_MASK 0x4 ++#define RTL8367C_RMA_CTRL11_VLAN_LEAKY_OFFSET 1 ++#define RTL8367C_RMA_CTRL11_VLAN_LEAKY_MASK 0x2 ++#define RTL8367C_RMA_CTRL11_PORTISO_LEAKY_OFFSET 0 ++#define RTL8367C_RMA_CTRL11_PORTISO_LEAKY_MASK 0x1 ++ ++#define RTL8367C_REG_RMA_CTRL12 0x0812 ++#define RTL8367C_RMA_CTRL12_OPERATION_OFFSET 7 ++#define RTL8367C_RMA_CTRL12_OPERATION_MASK 0x180 ++#define RTL8367C_RMA_CTRL12_DISCARD_STORM_FILTER_OFFSET 6 ++#define RTL8367C_RMA_CTRL12_DISCARD_STORM_FILTER_MASK 0x40 ++#define RTL8367C_RMA_CTRL12_KEEP_FORMAT_OFFSET 2 ++#define RTL8367C_RMA_CTRL12_KEEP_FORMAT_MASK 0x4 ++#define RTL8367C_RMA_CTRL12_VLAN_LEAKY_OFFSET 1 ++#define RTL8367C_RMA_CTRL12_VLAN_LEAKY_MASK 0x2 ++#define RTL8367C_RMA_CTRL12_PORTISO_LEAKY_OFFSET 0 ++#define RTL8367C_RMA_CTRL12_PORTISO_LEAKY_MASK 0x1 ++ ++#define RTL8367C_REG_RMA_CTRL13 0x0813 ++#define RTL8367C_RMA_CTRL13_OPERATION_OFFSET 7 ++#define RTL8367C_RMA_CTRL13_OPERATION_MASK 0x180 ++#define RTL8367C_RMA_CTRL13_DISCARD_STORM_FILTER_OFFSET 6 ++#define RTL8367C_RMA_CTRL13_DISCARD_STORM_FILTER_MASK 0x40 ++#define RTL8367C_RMA_CTRL13_KEEP_FORMAT_OFFSET 2 ++#define RTL8367C_RMA_CTRL13_KEEP_FORMAT_MASK 0x4 ++#define RTL8367C_RMA_CTRL13_VLAN_LEAKY_OFFSET 1 ++#define RTL8367C_RMA_CTRL13_VLAN_LEAKY_MASK 0x2 ++#define RTL8367C_RMA_CTRL13_PORTISO_LEAKY_OFFSET 0 ++#define RTL8367C_RMA_CTRL13_PORTISO_LEAKY_MASK 0x1 ++ ++#define RTL8367C_REG_RMA_CTRL18 0x0818 ++#define RTL8367C_RMA_CTRL18_OPERATION_OFFSET 7 ++#define RTL8367C_RMA_CTRL18_OPERATION_MASK 0x180 ++#define RTL8367C_RMA_CTRL18_DISCARD_STORM_FILTER_OFFSET 6 ++#define RTL8367C_RMA_CTRL18_DISCARD_STORM_FILTER_MASK 0x40 ++#define RTL8367C_RMA_CTRL18_KEEP_FORMAT_OFFSET 2 ++#define RTL8367C_RMA_CTRL18_KEEP_FORMAT_MASK 0x4 ++#define RTL8367C_RMA_CTRL18_VLAN_LEAKY_OFFSET 1 ++#define RTL8367C_RMA_CTRL18_VLAN_LEAKY_MASK 0x2 ++#define RTL8367C_RMA_CTRL18_PORTISO_LEAKY_OFFSET 0 ++#define RTL8367C_RMA_CTRL18_PORTISO_LEAKY_MASK 0x1 ++ ++#define RTL8367C_REG_RMA_CTRL1A 0x081a ++#define RTL8367C_RMA_CTRL1A_OPERATION_OFFSET 7 ++#define RTL8367C_RMA_CTRL1A_OPERATION_MASK 0x180 ++#define RTL8367C_RMA_CTRL1A_DISCARD_STORM_FILTER_OFFSET 6 ++#define RTL8367C_RMA_CTRL1A_DISCARD_STORM_FILTER_MASK 0x40 ++#define RTL8367C_RMA_CTRL1A_KEEP_FORMAT_OFFSET 2 ++#define RTL8367C_RMA_CTRL1A_KEEP_FORMAT_MASK 0x4 ++#define RTL8367C_RMA_CTRL1A_VLAN_LEAKY_OFFSET 1 ++#define RTL8367C_RMA_CTRL1A_VLAN_LEAKY_MASK 0x2 ++#define RTL8367C_RMA_CTRL1A_PORTISO_LEAKY_OFFSET 0 ++#define RTL8367C_RMA_CTRL1A_PORTISO_LEAKY_MASK 0x1 ++ ++#define RTL8367C_REG_RMA_CTRL20 0x0820 ++#define RTL8367C_RMA_CTRL20_OPERATION_OFFSET 7 ++#define RTL8367C_RMA_CTRL20_OPERATION_MASK 0x180 ++#define RTL8367C_RMA_CTRL20_DISCARD_STORM_FILTER_OFFSET 6 ++#define RTL8367C_RMA_CTRL20_DISCARD_STORM_FILTER_MASK 0x40 ++#define RTL8367C_RMA_CTRL20_KEEP_FORMAT_OFFSET 2 ++#define RTL8367C_RMA_CTRL20_KEEP_FORMAT_MASK 0x4 ++#define RTL8367C_RMA_CTRL20_VLAN_LEAKY_OFFSET 1 ++#define RTL8367C_RMA_CTRL20_VLAN_LEAKY_MASK 0x2 ++#define RTL8367C_RMA_CTRL20_PORTISO_LEAKY_OFFSET 0 ++#define RTL8367C_RMA_CTRL20_PORTISO_LEAKY_MASK 0x1 ++ ++#define RTL8367C_REG_RMA_CTRL21 0x0821 ++#define RTL8367C_RMA_CTRL21_OPERATION_OFFSET 7 ++#define RTL8367C_RMA_CTRL21_OPERATION_MASK 0x180 ++#define RTL8367C_RMA_CTRL21_DISCARD_STORM_FILTER_OFFSET 6 ++#define RTL8367C_RMA_CTRL21_DISCARD_STORM_FILTER_MASK 0x40 ++#define RTL8367C_RMA_CTRL21_KEEP_FORMAT_OFFSET 2 ++#define RTL8367C_RMA_CTRL21_KEEP_FORMAT_MASK 0x4 ++#define RTL8367C_RMA_CTRL21_VLAN_LEAKY_OFFSET 1 ++#define RTL8367C_RMA_CTRL21_VLAN_LEAKY_MASK 0x2 ++#define RTL8367C_RMA_CTRL21_PORTISO_LEAKY_OFFSET 0 ++#define RTL8367C_RMA_CTRL21_PORTISO_LEAKY_MASK 0x1 ++ ++#define RTL8367C_REG_RMA_CTRL22 0x0822 ++#define RTL8367C_RMA_CTRL22_OPERATION_OFFSET 7 ++#define RTL8367C_RMA_CTRL22_OPERATION_MASK 0x180 ++#define RTL8367C_RMA_CTRL22_DISCARD_STORM_FILTER_OFFSET 6 ++#define RTL8367C_RMA_CTRL22_DISCARD_STORM_FILTER_MASK 0x40 ++#define RTL8367C_RMA_CTRL22_KEEP_FORMAT_OFFSET 2 ++#define RTL8367C_RMA_CTRL22_KEEP_FORMAT_MASK 0x4 ++#define RTL8367C_RMA_CTRL22_VLAN_LEAKY_OFFSET 1 ++#define RTL8367C_RMA_CTRL22_VLAN_LEAKY_MASK 0x2 ++#define RTL8367C_RMA_CTRL22_PORTISO_LEAKY_OFFSET 0 ++#define RTL8367C_RMA_CTRL22_PORTISO_LEAKY_MASK 0x1 ++ ++#define RTL8367C_REG_RMA_CTRL_CDP 0x0830 ++#define RTL8367C_RMA_CTRL_CDP_OPERATION_OFFSET 7 ++#define RTL8367C_RMA_CTRL_CDP_OPERATION_MASK 0x180 ++#define RTL8367C_RMA_CTRL_CDP_DISCARD_STORM_FILTER_OFFSET 6 ++#define RTL8367C_RMA_CTRL_CDP_DISCARD_STORM_FILTER_MASK 0x40 ++#define RTL8367C_RMA_CTRL_CDP_KEEP_FORMAT_OFFSET 2 ++#define RTL8367C_RMA_CTRL_CDP_KEEP_FORMAT_MASK 0x4 ++#define RTL8367C_RMA_CTRL_CDP_VLAN_LEAKY_OFFSET 1 ++#define RTL8367C_RMA_CTRL_CDP_VLAN_LEAKY_MASK 0x2 ++#define RTL8367C_RMA_CTRL_CDP_PORTISO_LEAKY_OFFSET 0 ++#define RTL8367C_RMA_CTRL_CDP_PORTISO_LEAKY_MASK 0x1 ++ ++#define RTL8367C_REG_RMA_CTRL_CSSTP 0x0831 ++#define RTL8367C_RMA_CTRL_CSSTP_OPERATION_OFFSET 7 ++#define RTL8367C_RMA_CTRL_CSSTP_OPERATION_MASK 0x180 ++#define RTL8367C_RMA_CTRL_CSSTP_DISCARD_STORM_FILTER_OFFSET 6 ++#define RTL8367C_RMA_CTRL_CSSTP_DISCARD_STORM_FILTER_MASK 0x40 ++#define RTL8367C_RMA_CTRL_CSSTP_KEEP_FORMAT_OFFSET 2 ++#define RTL8367C_RMA_CTRL_CSSTP_KEEP_FORMAT_MASK 0x4 ++#define RTL8367C_RMA_CTRL_CSSTP_VLAN_LEAKY_OFFSET 1 ++#define RTL8367C_RMA_CTRL_CSSTP_VLAN_LEAKY_MASK 0x2 ++#define RTL8367C_RMA_CTRL_CSSTP_PORTISO_LEAKY_OFFSET 0 ++#define RTL8367C_RMA_CTRL_CSSTP_PORTISO_LEAKY_MASK 0x1 ++ ++#define RTL8367C_REG_RMA_CTRL_LLDP 0x0832 ++#define RTL8367C_RMA_CTRL_LLDP_OPERATION_OFFSET 7 ++#define RTL8367C_RMA_CTRL_LLDP_OPERATION_MASK 0x180 ++#define RTL8367C_RMA_CTRL_LLDP_DISCARD_STORM_FILTER_OFFSET 6 ++#define RTL8367C_RMA_CTRL_LLDP_DISCARD_STORM_FILTER_MASK 0x40 ++#define RTL8367C_RMA_CTRL_LLDP_KEEP_FORMAT_OFFSET 2 ++#define RTL8367C_RMA_CTRL_LLDP_KEEP_FORMAT_MASK 0x4 ++#define RTL8367C_RMA_CTRL_LLDP_VLAN_LEAKY_OFFSET 1 ++#define RTL8367C_RMA_CTRL_LLDP_VLAN_LEAKY_MASK 0x2 ++#define RTL8367C_RMA_CTRL_LLDP_PORTISO_LEAKY_OFFSET 0 ++#define RTL8367C_RMA_CTRL_LLDP_PORTISO_LEAKY_MASK 0x1 ++ ++#define RTL8367C_REG_RMA_LLDP_EN 0x0833 ++#define RTL8367C_RMA_LLDP_EN_OFFSET 0 ++#define RTL8367C_RMA_LLDP_EN_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_PORTBASED_PRIORITY_CTRL0 0x0851 ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT3_PRIORITY_OFFSET 12 ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT3_PRIORITY_MASK 0x7000 ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT2_PRIORITY_OFFSET 8 ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT2_PRIORITY_MASK 0x700 ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT1_PRIORITY_OFFSET 4 ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT1_PRIORITY_MASK 0x70 ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT0_PRIORITY_OFFSET 0 ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL0_PORT0_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_VLAN_PORTBASED_PRIORITY_CTRL1 0x0852 ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT7_PRIORITY_OFFSET 12 ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT7_PRIORITY_MASK 0x7000 ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT6_PRIORITY_OFFSET 8 ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT6_PRIORITY_MASK 0x700 ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT5_PRIORITY_OFFSET 4 ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT5_PRIORITY_MASK 0x70 ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT4_PRIORITY_OFFSET 0 ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL1_PORT4_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_VLAN_PORTBASED_PRIORITY_CTRL2 0x0853 ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT10_PRIORITY_OFFSET 8 ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT10_PRIORITY_MASK 0x700 ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT9_PRIORITY_OFFSET 4 ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT9_PRIORITY_MASK 0x70 ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT8_PRIORITY_OFFSET 0 ++#define RTL8367C_VLAN_PORTBASED_PRIORITY_CTRL2_PORT8_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM0_CTRL0 0x0855 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT3_PRIORITY_OFFSET 12 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT3_PRIORITY_MASK 0x7000 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT2_PRIORITY_OFFSET 8 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT2_PRIORITY_MASK 0x700 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT1_PRIORITY_OFFSET 4 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT1_PRIORITY_MASK 0x70 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT0_PRIORITY_OFFSET 0 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL0_PORT0_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM0_CTRL1 0x0856 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT7_PRIORITY_OFFSET 12 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT7_PRIORITY_MASK 0x7000 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT6_PRIORITY_OFFSET 8 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT6_PRIORITY_MASK 0x700 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT5_PRIORITY_OFFSET 4 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT5_PRIORITY_MASK 0x70 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT4_PRIORITY_OFFSET 0 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL1_PORT4_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM0_CTRL2 0x0857 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT10_PRIORITY_OFFSET 8 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT10_PRIORITY_MASK 0x700 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT9_PRIORITY_OFFSET 4 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT9_PRIORITY_MASK 0x70 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT8_PRIORITY_OFFSET 0 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM0_CTRL2_PORT8_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM1_CTRL0 0x0859 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT3_PRIORITY_OFFSET 12 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT3_PRIORITY_MASK 0x7000 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT2_PRIORITY_OFFSET 8 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT2_PRIORITY_MASK 0x700 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT1_PRIORITY_OFFSET 4 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT1_PRIORITY_MASK 0x70 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT0_PRIORITY_OFFSET 0 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL0_PORT0_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM1_CTRL1 0x085a ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT7_PRIORITY_OFFSET 12 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT7_PRIORITY_MASK 0x7000 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT6_PRIORITY_OFFSET 8 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT6_PRIORITY_MASK 0x700 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT5_PRIORITY_OFFSET 4 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT5_PRIORITY_MASK 0x70 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT4_PRIORITY_OFFSET 0 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL1_PORT4_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM1_CTRL2 0x085b ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT10_PRIORITY_OFFSET 8 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT10_PRIORITY_MASK 0x700 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT9_PRIORITY_OFFSET 4 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT9_PRIORITY_MASK 0x70 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT8_PRIORITY_OFFSET 0 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM1_CTRL2_PORT8_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM2_CTRL0 0x085d ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT3_PRIORITY_OFFSET 12 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT3_PRIORITY_MASK 0x7000 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT2_PRIORITY_OFFSET 8 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT2_PRIORITY_MASK 0x700 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT1_PRIORITY_OFFSET 4 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT1_PRIORITY_MASK 0x70 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT0_PRIORITY_OFFSET 0 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL0_PORT0_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM2_CTRL1 0x085e ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT7_PRIORITY_OFFSET 12 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT7_PRIORITY_MASK 0x7000 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT6_PRIORITY_OFFSET 8 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT6_PRIORITY_MASK 0x700 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT5_PRIORITY_OFFSET 4 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT5_PRIORITY_MASK 0x70 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT4_PRIORITY_OFFSET 0 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL1_PORT4_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM2_CTRL2 0x085f ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT10_PRIORITY_OFFSET 8 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT10_PRIORITY_MASK 0x700 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT9_PRIORITY_OFFSET 4 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT9_PRIORITY_MASK 0x70 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT8_PRIORITY_OFFSET 0 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM2_CTRL2_PORT8_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM3_CTRL0 0x0861 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT3_PRIORITY_OFFSET 12 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT3_PRIORITY_MASK 0x7000 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT2_PRIORITY_OFFSET 8 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT2_PRIORITY_MASK 0x700 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT1_PRIORITY_OFFSET 4 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT1_PRIORITY_MASK 0x70 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT0_PRIORITY_OFFSET 0 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL0_PORT0_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM3_CTRL1 0x0862 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT7_PRIORITY_OFFSET 12 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT7_PRIORITY_MASK 0x7000 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT6_PRIORITY_OFFSET 8 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT6_PRIORITY_MASK 0x700 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT5_PRIORITY_OFFSET 4 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT5_PRIORITY_MASK 0x70 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT4_PRIORITY_OFFSET 0 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL1_PORT4_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_VLAN_PPB_PRIORITY_ITEM3_CTRL2 0x0863 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT10_PRIORITY_OFFSET 8 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT10_PRIORITY_MASK 0x700 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT9_PRIORITY_OFFSET 4 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT9_PRIORITY_MASK 0x70 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT8_PRIORITY_OFFSET 0 ++#define RTL8367C_VLAN_PPB_PRIORITY_ITEM3_CTRL2_PORT8_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_1Q_PRIORITY_REMAPPING_CTRL0 0x0865 ++#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY3_OFFSET 12 ++#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY3_MASK 0x7000 ++#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY2_OFFSET 8 ++#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY2_MASK 0x700 ++#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY1_OFFSET 4 ++#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY1_MASK 0x70 ++#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY0_OFFSET 0 ++#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL0_PRIORITY0_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_1Q_PRIORITY_REMAPPING_CTRL1 0x0866 ++#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY7_OFFSET 12 ++#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY7_MASK 0x7000 ++#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY6_OFFSET 8 ++#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY6_MASK 0x700 ++#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY5_OFFSET 4 ++#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY5_MASK 0x70 ++#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY4_OFFSET 0 ++#define RTL8367C_QOS_1Q_PRIORITY_REMAPPING_CTRL1_PRIORITY4_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL0 0x0867 ++#define RTL8367C_DSCP3_PRIORITY_OFFSET 12 ++#define RTL8367C_DSCP3_PRIORITY_MASK 0x7000 ++#define RTL8367C_DSCP2_PRIORITY_OFFSET 8 ++#define RTL8367C_DSCP2_PRIORITY_MASK 0x700 ++#define RTL8367C_DSCP1_PRIORITY_OFFSET 4 ++#define RTL8367C_DSCP1_PRIORITY_MASK 0x70 ++#define RTL8367C_DSCP0_PRIORITY_OFFSET 0 ++#define RTL8367C_DSCP0_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL1 0x0868 ++#define RTL8367C_DSCP7_PRIORITY_OFFSET 12 ++#define RTL8367C_DSCP7_PRIORITY_MASK 0x7000 ++#define RTL8367C_DSCP6_PRIORITY_OFFSET 8 ++#define RTL8367C_DSCP6_PRIORITY_MASK 0x700 ++#define RTL8367C_DSCP5_PRIORITY_OFFSET 4 ++#define RTL8367C_DSCP5_PRIORITY_MASK 0x70 ++#define RTL8367C_DSCP4_PRIORITY_OFFSET 0 ++#define RTL8367C_DSCP4_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL2 0x0869 ++#define RTL8367C_DSCP11_PRIORITY_OFFSET 12 ++#define RTL8367C_DSCP11_PRIORITY_MASK 0x7000 ++#define RTL8367C_DSCP10_PRIORITY_OFFSET 8 ++#define RTL8367C_DSCP10_PRIORITY_MASK 0x700 ++#define RTL8367C_DSCP9_PRIORITY_OFFSET 4 ++#define RTL8367C_DSCP9_PRIORITY_MASK 0x70 ++#define RTL8367C_DSCP8_PRIORITY_OFFSET 0 ++#define RTL8367C_DSCP8_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL3 0x086a ++#define RTL8367C_DSCP15_PRIORITY_OFFSET 12 ++#define RTL8367C_DSCP15_PRIORITY_MASK 0x7000 ++#define RTL8367C_DSCP14_PRIORITY_OFFSET 8 ++#define RTL8367C_DSCP14_PRIORITY_MASK 0x700 ++#define RTL8367C_DSCP13_PRIORITY_OFFSET 4 ++#define RTL8367C_DSCP13_PRIORITY_MASK 0x70 ++#define RTL8367C_DSCP12_PRIORITY_OFFSET 0 ++#define RTL8367C_DSCP12_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL4 0x086b ++#define RTL8367C_DSCP19_PRIORITY_OFFSET 12 ++#define RTL8367C_DSCP19_PRIORITY_MASK 0x7000 ++#define RTL8367C_DSCP18_PRIORITY_OFFSET 8 ++#define RTL8367C_DSCP18_PRIORITY_MASK 0x700 ++#define RTL8367C_DSCP17_PRIORITY_OFFSET 4 ++#define RTL8367C_DSCP17_PRIORITY_MASK 0x70 ++#define RTL8367C_DSCP16_PRIORITY_OFFSET 0 ++#define RTL8367C_DSCP16_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL5 0x086c ++#define RTL8367C_DSCP23_PRIORITY_OFFSET 12 ++#define RTL8367C_DSCP23_PRIORITY_MASK 0x7000 ++#define RTL8367C_DSCP22_PRIORITY_OFFSET 8 ++#define RTL8367C_DSCP22_PRIORITY_MASK 0x700 ++#define RTL8367C_DSCP21_PRIORITY_OFFSET 4 ++#define RTL8367C_DSCP21_PRIORITY_MASK 0x70 ++#define RTL8367C_DSCP20_PRIORITY_OFFSET 0 ++#define RTL8367C_DSCP20_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL6 0x086d ++#define RTL8367C_DSCP27_PRIORITY_OFFSET 12 ++#define RTL8367C_DSCP27_PRIORITY_MASK 0x7000 ++#define RTL8367C_DSCP26_PRIORITY_OFFSET 8 ++#define RTL8367C_DSCP26_PRIORITY_MASK 0x700 ++#define RTL8367C_DSCP25_PRIORITY_OFFSET 4 ++#define RTL8367C_DSCP25_PRIORITY_MASK 0x70 ++#define RTL8367C_DSCP24_PRIORITY_OFFSET 0 ++#define RTL8367C_DSCP24_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL7 0x086e ++#define RTL8367C_DSCP31_PRIORITY_OFFSET 12 ++#define RTL8367C_DSCP31_PRIORITY_MASK 0x7000 ++#define RTL8367C_DSCP30_PRIORITY_OFFSET 8 ++#define RTL8367C_DSCP30_PRIORITY_MASK 0x700 ++#define RTL8367C_DSCP29_PRIORITY_OFFSET 4 ++#define RTL8367C_DSCP29_PRIORITY_MASK 0x70 ++#define RTL8367C_DSCP28_PRIORITY_OFFSET 0 ++#define RTL8367C_DSCP28_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL8 0x086f ++#define RTL8367C_DSCP35_PRIORITY_OFFSET 12 ++#define RTL8367C_DSCP35_PRIORITY_MASK 0x7000 ++#define RTL8367C_DSCP34_PRIORITY_OFFSET 8 ++#define RTL8367C_DSCP34_PRIORITY_MASK 0x700 ++#define RTL8367C_DSCP33_PRIORITY_OFFSET 4 ++#define RTL8367C_DSCP33_PRIORITY_MASK 0x70 ++#define RTL8367C_DSCP32_PRIORITY_OFFSET 0 ++#define RTL8367C_DSCP32_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL9 0x0870 ++#define RTL8367C_DSCP39_PRIORITY_OFFSET 12 ++#define RTL8367C_DSCP39_PRIORITY_MASK 0x7000 ++#define RTL8367C_DSCP38_PRIORITY_OFFSET 8 ++#define RTL8367C_DSCP38_PRIORITY_MASK 0x700 ++#define RTL8367C_DSCP37_PRIORITY_OFFSET 4 ++#define RTL8367C_DSCP37_PRIORITY_MASK 0x70 ++#define RTL8367C_DSCP36_PRIORITY_OFFSET 0 ++#define RTL8367C_DSCP36_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL10 0x0871 ++#define RTL8367C_DSCP43_PRIORITY_OFFSET 12 ++#define RTL8367C_DSCP43_PRIORITY_MASK 0x7000 ++#define RTL8367C_DSCP42_PRIORITY_OFFSET 8 ++#define RTL8367C_DSCP42_PRIORITY_MASK 0x700 ++#define RTL8367C_DSCP41_PRIORITY_OFFSET 4 ++#define RTL8367C_DSCP41_PRIORITY_MASK 0x70 ++#define RTL8367C_DSCP40_PRIORITY_OFFSET 0 ++#define RTL8367C_DSCP40_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL11 0x0872 ++#define RTL8367C_DSCP47_PRIORITY_OFFSET 12 ++#define RTL8367C_DSCP47_PRIORITY_MASK 0x7000 ++#define RTL8367C_DSCP46_PRIORITY_OFFSET 8 ++#define RTL8367C_DSCP46_PRIORITY_MASK 0x700 ++#define RTL8367C_DSCP45_PRIORITY_OFFSET 4 ++#define RTL8367C_DSCP45_PRIORITY_MASK 0x70 ++#define RTL8367C_DSCP44_PRIORITY_OFFSET 0 ++#define RTL8367C_DSCP44_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL12 0x0873 ++#define RTL8367C_DSCP51_PRIORITY_OFFSET 12 ++#define RTL8367C_DSCP51_PRIORITY_MASK 0x7000 ++#define RTL8367C_DSCP50_PRIORITY_OFFSET 8 ++#define RTL8367C_DSCP50_PRIORITY_MASK 0x700 ++#define RTL8367C_DSCP49_PRIORITY_OFFSET 4 ++#define RTL8367C_DSCP49_PRIORITY_MASK 0x70 ++#define RTL8367C_DSCP48_PRIORITY_OFFSET 0 ++#define RTL8367C_DSCP48_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL13 0x0874 ++#define RTL8367C_DSCP55_PRIORITY_OFFSET 12 ++#define RTL8367C_DSCP55_PRIORITY_MASK 0x7000 ++#define RTL8367C_DSCP54_PRIORITY_OFFSET 8 ++#define RTL8367C_DSCP54_PRIORITY_MASK 0x700 ++#define RTL8367C_DSCP53_PRIORITY_OFFSET 4 ++#define RTL8367C_DSCP53_PRIORITY_MASK 0x70 ++#define RTL8367C_DSCP52_PRIORITY_OFFSET 0 ++#define RTL8367C_DSCP52_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL14 0x0875 ++#define RTL8367C_DSCP59_PRIORITY_OFFSET 12 ++#define RTL8367C_DSCP59_PRIORITY_MASK 0x7000 ++#define RTL8367C_DSCP58_PRIORITY_OFFSET 8 ++#define RTL8367C_DSCP58_PRIORITY_MASK 0x700 ++#define RTL8367C_DSCP57_PRIORITY_OFFSET 4 ++#define RTL8367C_DSCP57_PRIORITY_MASK 0x70 ++#define RTL8367C_DSCP56_PRIORITY_OFFSET 0 ++#define RTL8367C_DSCP56_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_DSCP_TO_PRIORITY_CTRL15 0x0876 ++#define RTL8367C_DSCP63_PRIORITY_OFFSET 12 ++#define RTL8367C_DSCP63_PRIORITY_MASK 0x7000 ++#define RTL8367C_DSCP62_PRIORITY_OFFSET 8 ++#define RTL8367C_DSCP62_PRIORITY_MASK 0x700 ++#define RTL8367C_DSCP61_PRIORITY_OFFSET 4 ++#define RTL8367C_DSCP61_PRIORITY_MASK 0x70 ++#define RTL8367C_DSCP60_PRIORITY_OFFSET 0 ++#define RTL8367C_DSCP60_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL0 0x0877 ++#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT3_PRIORITY_OFFSET 12 ++#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT3_PRIORITY_MASK 0x7000 ++#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT2_PRIORITY_OFFSET 8 ++#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT2_PRIORITY_MASK 0x700 ++#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT1_PRIORITY_OFFSET 4 ++#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT1_PRIORITY_MASK 0x70 ++#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT0_PRIORITY_OFFSET 0 ++#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL0_PORT0_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL1 0x0878 ++#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT7_PRIORITY_OFFSET 12 ++#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT7_PRIORITY_MASK 0x7000 ++#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT6_PRIORITY_OFFSET 8 ++#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT6_PRIORITY_MASK 0x700 ++#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT5_PRIORITY_OFFSET 4 ++#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT5_PRIORITY_MASK 0x70 ++#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT4_PRIORITY_OFFSET 0 ++#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL1_PORT4_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_DUMMY0879 0x0879 ++#define RTL8367C_DUMMY0879_OFFSET 0 ++#define RTL8367C_DUMMY0879_MASK 0x1 ++ ++#define RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL2 0x087a ++#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT10_PRIORITY_OFFSET 8 ++#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT10_PRIORITY_MASK 0x700 ++#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT9_PRIORITY_OFFSET 4 ++#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT9_PRIORITY_MASK 0x70 ++#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT8_PRIORITY_OFFSET 0 ++#define RTL8367C_QOS_PORTBASED_PRIORITY_CTRL2_PORT8_PRIORITY_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_CTRL0 0x087b ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL0_QOS_ACL_WEIGHT_OFFSET 8 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL0_QOS_ACL_WEIGHT_MASK 0xFF00 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL0_QOS_PORT_WEIGHT_OFFSET 0 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL0_QOS_PORT_WEIGHT_MASK 0xFF ++ ++#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_CTRL1 0x087c ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL1_QOS_DOT1Q_WEIGHT_OFFSET 8 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL1_QOS_DOT1Q_WEIGHT_MASK 0xFF00 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL1_QOS_DSCP_WEIGHT_OFFSET 0 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL1_QOS_DSCP_WEIGHT_MASK 0xFF ++ ++#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_CTRL2 0x087d ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL2_QOS_CVLAN_WEIGHT_OFFSET 8 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL2_QOS_CVLAN_WEIGHT_MASK 0xFF00 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL2_QOS_SVLAN_WEIGHT_OFFSET 0 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL2_QOS_SVLAN_WEIGHT_MASK 0xFF ++ ++#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_CTRL3 0x087e ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL3_QOS_SA_WEIGHT_OFFSET 8 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL3_QOS_SA_WEIGHT_MASK 0xFF00 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL3_QOS_LUTFWD_WEIGHT_OFFSET 0 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_CTRL3_QOS_LUTFWD_WEIGHT_MASK 0xFF ++ ++#define RTL8367C_REG_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0 0x087f ++#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY3_OFFSET 12 ++#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY3_MASK 0x7000 ++#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY2_OFFSET 8 ++#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY2_MASK 0x700 ++#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY1_OFFSET 4 ++#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY1_MASK 0x70 ++#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY0_OFFSET 0 ++#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL0_PRIORITY0_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1 0x0880 ++#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY7_OFFSET 12 ++#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY7_MASK 0x7000 ++#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY6_OFFSET 8 ++#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY6_MASK 0x700 ++#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY5_OFFSET 4 ++#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY5_MASK 0x70 ++#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY4_OFFSET 0 ++#define RTL8367C_QOS_PRIORITY_REMAPPING_IN_CPU_CTRL1_PRIORITY4_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_TRAP_PRIORITY0 0x0881 ++#define RTL8367C_UNKNOWN_MC_PRIORTY_OFFSET 12 ++#define RTL8367C_UNKNOWN_MC_PRIORTY_MASK 0x7000 ++#define RTL8367C_SVLAN_PRIOIRTY_OFFSET 8 ++#define RTL8367C_SVLAN_PRIOIRTY_MASK 0x700 ++#define RTL8367C_OAM_PRIOIRTY_OFFSET 4 ++#define RTL8367C_OAM_PRIOIRTY_MASK 0x70 ++#define RTL8367C_DOT1X_PRIORTY_OFFSET 0 ++#define RTL8367C_DOT1X_PRIORTY_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_TRAP_PRIORITY1 0x0882 ++#define RTL8367C_DW8051_TRAP_PRI_OFFSET 4 ++#define RTL8367C_DW8051_TRAP_PRI_MASK 0x70 ++#define RTL8367C_EEELLDP_TRAP_PRI_OFFSET 0 ++#define RTL8367C_EEELLDP_TRAP_PRI_MASK 0x7 ++ ++#define RTL8367C_REG_MAX_LENGTH_CFG 0x0883 ++#define RTL8367C_MAX_LENGTH_GIGA_OFFSET 8 ++#define RTL8367C_MAX_LENGTH_GIGA_MASK 0xFF00 ++#define RTL8367C_MAX_LENGTH_10_100M_OFFSET 0 ++#define RTL8367C_MAX_LENGTH_10_100M_MASK 0xFF ++ ++#define RTL8367C_REG_MAX_LEN_RX_TX 0x0884 ++#define RTL8367C_MAX_LEN_RX_TX_OFFSET 0 ++#define RTL8367C_MAX_LEN_RX_TX_MASK 0x3 ++ ++#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0 0x0885 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0_QOS_ACL_WEIGHT_OFFSET 8 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0_QOS_ACL_WEIGHT_MASK 0xFF00 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0_QOS_PORT_WEIGHT_OFFSET 0 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL0_QOS_PORT_WEIGHT_MASK 0xFF ++ ++#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION2_CTRL1 0x0886 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL1_QOS_DOT1Q_WEIGHT_OFFSET 8 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL1_QOS_DOT1Q_WEIGHT_MASK 0xFF00 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL1_QOS_DSCP_WEIGHT_OFFSET 0 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL1_QOS_DSCP_WEIGHT_MASK 0xFF ++ ++#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION2_CTRL2 0x0887 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL2_QOS_CVLAN_WEIGHT_OFFSET 8 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL2_QOS_CVLAN_WEIGHT_MASK 0xFF00 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL2_QOS_SVLAN_WEIGHT_OFFSET 0 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL2_QOS_SVLAN_WEIGHT_MASK 0xFF ++ ++#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION2_CTRL3 0x0888 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL3_QOS_SA_WEIGHT_OFFSET 8 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL3_QOS_SA_WEIGHT_MASK 0xFF00 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL3_QOS_LUTFWD_WEIGHT_OFFSET 0 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_CTRL3_QOS_LUTFWD_WEIGHT_MASK 0xFF ++ ++#define RTL8367C_REG_QOS_INTERNAL_PRIORITY_DECISION_IDX 0x0889 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX_OFFSET 0 ++#define RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX_MASK 0x7FF ++ ++#define RTL8367C_REG_MAX_LENGTH_CFG_EXT 0x088a ++#define RTL8367C_MAX_LENGTH_GIGA_EXT_OFFSET 3 ++#define RTL8367C_MAX_LENGTH_GIGA_EXT_MASK 0x38 ++#define RTL8367C_MAX_LENGTH_10_100M_EXT_OFFSET 0 ++#define RTL8367C_MAX_LENGTH_10_100M_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_MAX_LEN_RX_TX_CFG0 0x088c ++#define RTL8367C_MAX_LEN_RX_TX_CFG0_OFFSET 0 ++#define RTL8367C_MAX_LEN_RX_TX_CFG0_MASK 0x3FFF ++ ++#define RTL8367C_REG_MAX_LEN_RX_TX_CFG1 0x088d ++#define RTL8367C_MAX_LEN_RX_TX_CFG1_OFFSET 0 ++#define RTL8367C_MAX_LEN_RX_TX_CFG1_MASK 0x3FFF ++ ++#define RTL8367C_REG_UNDA_FLOODING_PMSK 0x0890 ++#define RTL8367C_UNDA_FLOODING_PMSK_OFFSET 0 ++#define RTL8367C_UNDA_FLOODING_PMSK_MASK 0x7FF ++ ++#define RTL8367C_REG_UNMCAST_FLOADING_PMSK 0x0891 ++#define RTL8367C_UNMCAST_FLOADING_PMSK_OFFSET 0 ++#define RTL8367C_UNMCAST_FLOADING_PMSK_MASK 0x7FF ++ ++#define RTL8367C_REG_BCAST_FLOADING_PMSK 0x0892 ++#define RTL8367C_BCAST_FLOADING_PMSK_OFFSET 0 ++#define RTL8367C_BCAST_FLOADING_PMSK_MASK 0x7FF ++ ++#define RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL2 0x08a0 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH7_OFFSET 14 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH7_MASK 0xC000 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH6_OFFSET 12 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH6_MASK 0x3000 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH5_OFFSET 10 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH5_MASK 0xC00 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH4_OFFSET 8 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH4_MASK 0x300 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH3_OFFSET 6 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH3_MASK 0xC0 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH2_OFFSET 4 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH2_MASK 0x30 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH1_OFFSET 2 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH1_MASK 0xC ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH0_OFFSET 0 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH0_MASK 0x3 ++ ++#define RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL3 0x08a1 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH15_OFFSET 14 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH15_MASK 0xC000 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH14_OFFSET 12 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH14_MASK 0x3000 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH13_OFFSET 10 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH13_MASK 0xC00 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH12_OFFSET 8 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH12_MASK 0x300 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH11_OFFSET 6 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH11_MASK 0xC0 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH10_OFFSET 4 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH10_MASK 0x30 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH9_OFFSET 2 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH9_MASK 0xC ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH8_OFFSET 0 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH8_MASK 0x3 ++ ++#define RTL8367C_REG_PORT_ISOLATION_PORT0_MASK 0x08a2 ++#define RTL8367C_PORT_ISOLATION_PORT0_MASK_OFFSET 0 ++#define RTL8367C_PORT_ISOLATION_PORT0_MASK_MASK 0x7FF ++ ++#define RTL8367C_REG_PORT_ISOLATION_PORT1_MASK 0x08a3 ++#define RTL8367C_PORT_ISOLATION_PORT1_MASK_OFFSET 0 ++#define RTL8367C_PORT_ISOLATION_PORT1_MASK_MASK 0x7FF ++ ++#define RTL8367C_REG_PORT_ISOLATION_PORT2_MASK 0x08a4 ++#define RTL8367C_PORT_ISOLATION_PORT2_MASK_OFFSET 0 ++#define RTL8367C_PORT_ISOLATION_PORT2_MASK_MASK 0x7FF ++ ++#define RTL8367C_REG_PORT_ISOLATION_PORT3_MASK 0x08a5 ++#define RTL8367C_PORT_ISOLATION_PORT3_MASK_OFFSET 0 ++#define RTL8367C_PORT_ISOLATION_PORT3_MASK_MASK 0x7FF ++ ++#define RTL8367C_REG_PORT_ISOLATION_PORT4_MASK 0x08a6 ++#define RTL8367C_PORT_ISOLATION_PORT4_MASK_OFFSET 0 ++#define RTL8367C_PORT_ISOLATION_PORT4_MASK_MASK 0x7FF ++ ++#define RTL8367C_REG_PORT_ISOLATION_PORT5_MASK 0x08a7 ++#define RTL8367C_PORT_ISOLATION_PORT5_MASK_OFFSET 0 ++#define RTL8367C_PORT_ISOLATION_PORT5_MASK_MASK 0x7FF ++ ++#define RTL8367C_REG_PORT_ISOLATION_PORT6_MASK 0x08a8 ++#define RTL8367C_PORT_ISOLATION_PORT6_MASK_OFFSET 0 ++#define RTL8367C_PORT_ISOLATION_PORT6_MASK_MASK 0x7FF ++ ++#define RTL8367C_REG_PORT_ISOLATION_PORT7_MASK 0x08a9 ++#define RTL8367C_PORT_ISOLATION_PORT7_MASK_OFFSET 0 ++#define RTL8367C_PORT_ISOLATION_PORT7_MASK_MASK 0x7FF ++ ++#define RTL8367C_REG_PORT_ISOLATION_PORT8_MASK 0x08aa ++#define RTL8367C_PORT_ISOLATION_PORT8_MASK_OFFSET 0 ++#define RTL8367C_PORT_ISOLATION_PORT8_MASK_MASK 0x7FF ++ ++#define RTL8367C_REG_PORT_ISOLATION_PORT9_MASK 0x08ab ++#define RTL8367C_PORT_ISOLATION_PORT9_MASK_OFFSET 0 ++#define RTL8367C_PORT_ISOLATION_PORT9_MASK_MASK 0x7FF ++ ++#define RTL8367C_REG_PORT_ISOLATION_PORT10_MASK 0x08ac ++#define RTL8367C_PORT_ISOLATION_PORT10_MASK_OFFSET 0 ++#define RTL8367C_PORT_ISOLATION_PORT10_MASK_MASK 0x7FF ++ ++#define RTL8367C_REG_FORCE_CTRL 0x08b4 ++#define RTL8367C_FORCE_CTRL_OFFSET 0 ++#define RTL8367C_FORCE_CTRL_MASK 0x7FF ++ ++#define RTL8367C_REG_FORCE_PORT0_MASK 0x08b5 ++#define RTL8367C_FORCE_PORT0_MASK_OFFSET 0 ++#define RTL8367C_FORCE_PORT0_MASK_MASK 0x7FF ++ ++#define RTL8367C_REG_FORCE_PORT1_MASK 0x08b6 ++#define RTL8367C_FORCE_PORT1_MASK_OFFSET 0 ++#define RTL8367C_FORCE_PORT1_MASK_MASK 0x7FF ++ ++#define RTL8367C_REG_FORCE_PORT2_MASK 0x08b7 ++#define RTL8367C_FORCE_PORT2_MASK_OFFSET 0 ++#define RTL8367C_FORCE_PORT2_MASK_MASK 0x7FF ++ ++#define RTL8367C_REG_FORCE_PORT3_MASK 0x08b8 ++#define RTL8367C_FORCE_PORT3_MASK_OFFSET 0 ++#define RTL8367C_FORCE_PORT3_MASK_MASK 0x7FF ++ ++#define RTL8367C_REG_FORCE_PORT4_MASK 0x08b9 ++#define RTL8367C_FORCE_PORT4_MASK_OFFSET 0 ++#define RTL8367C_FORCE_PORT4_MASK_MASK 0x7FF ++ ++#define RTL8367C_REG_FORCE_PORT5_MASK 0x08ba ++#define RTL8367C_FORCE_PORT5_MASK_OFFSET 0 ++#define RTL8367C_FORCE_PORT5_MASK_MASK 0x7FF ++ ++#define RTL8367C_REG_FORCE_PORT6_MASK 0x08bb ++#define RTL8367C_FORCE_PORT6_MASK_OFFSET 0 ++#define RTL8367C_FORCE_PORT6_MASK_MASK 0x7FF ++ ++#define RTL8367C_REG_FORCE_PORT7_MASK 0x08bc ++#define RTL8367C_FORCE_PORT7_MASK_OFFSET 0 ++#define RTL8367C_FORCE_PORT7_MASK_MASK 0x7FF ++ ++#define RTL8367C_REG_FORCE_PORT8_MASK 0x08bd ++#define RTL8367C_FORCE_PORT8_MASK_OFFSET 0 ++#define RTL8367C_FORCE_PORT8_MASK_MASK 0x7FF ++ ++#define RTL8367C_REG_FORCE_PORT9_MASK 0x08be ++#define RTL8367C_FORCE_PORT9_MASK_OFFSET 0 ++#define RTL8367C_FORCE_PORT9_MASK_MASK 0x7FF ++ ++#define RTL8367C_REG_FORCE_PORT10_MASK 0x08bf ++#define RTL8367C_FORCE_PORT10_MASK_OFFSET 0 ++#define RTL8367C_FORCE_PORT10_MASK_MASK 0x7FF ++ ++#define RTL8367C_REG_SOURCE_PORT_PERMIT 0x08c5 ++#define RTL8367C_SOURCE_PORT_PERMIT_OFFSET 0 ++#define RTL8367C_SOURCE_PORT_PERMIT_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMCAST_VLAN_LEAKY 0x08c6 ++#define RTL8367C_IPMCAST_VLAN_LEAKY_OFFSET 0 ++#define RTL8367C_IPMCAST_VLAN_LEAKY_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMCAST_PORTISO_LEAKY 0x08c7 ++#define RTL8367C_IPMCAST_PORTISO_LEAKY_OFFSET 0 ++#define RTL8367C_IPMCAST_PORTISO_LEAKY_MASK 0x7FF ++ ++#define RTL8367C_REG_PORT_SECURITY_CTRL 0x08c8 ++#define RTL8367C_UNKNOWN_UNICAST_DA_BEHAVE_OFFSET 6 ++#define RTL8367C_UNKNOWN_UNICAST_DA_BEHAVE_MASK 0xC0 ++#define RTL8367C_LUT_LEARN_OVER_ACT_OFFSET 4 ++#define RTL8367C_LUT_LEARN_OVER_ACT_MASK 0x30 ++#define RTL8367C_UNMATCHED_SA_BEHAVE_OFFSET 2 ++#define RTL8367C_UNMATCHED_SA_BEHAVE_MASK 0xC ++#define RTL8367C_UNKNOWN_SA_BEHAVE_OFFSET 0 ++#define RTL8367C_UNKNOWN_SA_BEHAVE_MASK 0x3 ++ ++#define RTL8367C_REG_UNKNOWN_IPV4_MULTICAST_CTRL0 0x08c9 ++#define RTL8367C_PORT7_UNKNOWN_IP4_MCAST_OFFSET 14 ++#define RTL8367C_PORT7_UNKNOWN_IP4_MCAST_MASK 0xC000 ++#define RTL8367C_PORT6_UNKNOWN_IP4_MCAST_OFFSET 12 ++#define RTL8367C_PORT6_UNKNOWN_IP4_MCAST_MASK 0x3000 ++#define RTL8367C_PORT5_UNKNOWN_IP4_MCAST_OFFSET 10 ++#define RTL8367C_PORT5_UNKNOWN_IP4_MCAST_MASK 0xC00 ++#define RTL8367C_PORT4_UNKNOWN_IP4_MCAST_OFFSET 8 ++#define RTL8367C_PORT4_UNKNOWN_IP4_MCAST_MASK 0x300 ++#define RTL8367C_PORT3_UNKNOWN_IP4_MCAST_OFFSET 6 ++#define RTL8367C_PORT3_UNKNOWN_IP4_MCAST_MASK 0xC0 ++#define RTL8367C_PORT2_UNKNOWN_IP4_MCAST_OFFSET 4 ++#define RTL8367C_PORT2_UNKNOWN_IP4_MCAST_MASK 0x30 ++#define RTL8367C_PORT1_UNKNOWN_IP4_MCAST_OFFSET 2 ++#define RTL8367C_PORT1_UNKNOWN_IP4_MCAST_MASK 0xC ++#define RTL8367C_PORT0_UNKNOWN_IP4_MCAST_OFFSET 0 ++#define RTL8367C_PORT0_UNKNOWN_IP4_MCAST_MASK 0x3 ++ ++#define RTL8367C_REG_UNKNOWN_IPV4_MULTICAST_CTRL1 0x08ca ++#define RTL8367C_PORT10_UNKNOWN_IP4_MCAST_OFFSET 4 ++#define RTL8367C_PORT10_UNKNOWN_IP4_MCAST_MASK 0x30 ++#define RTL8367C_PORT9_UNKNOWN_IP4_MCAST_OFFSET 2 ++#define RTL8367C_PORT9_UNKNOWN_IP4_MCAST_MASK 0xC ++#define RTL8367C_PORT8_UNKNOWN_IP4_MCAST_OFFSET 0 ++#define RTL8367C_PORT8_UNKNOWN_IP4_MCAST_MASK 0x3 ++ ++#define RTL8367C_REG_UNKNOWN_IPV6_MULTICAST_CTRL0 0x08cb ++#define RTL8367C_PORT7_UNKNOWN_IP6_MCAST_OFFSET 14 ++#define RTL8367C_PORT7_UNKNOWN_IP6_MCAST_MASK 0xC000 ++#define RTL8367C_PORT6_UNKNOWN_IP6_MCAST_OFFSET 12 ++#define RTL8367C_PORT6_UNKNOWN_IP6_MCAST_MASK 0x3000 ++#define RTL8367C_PORT5_UNKNOWN_IP6_MCAST_OFFSET 10 ++#define RTL8367C_PORT5_UNKNOWN_IP6_MCAST_MASK 0xC00 ++#define RTL8367C_PORT4_UNKNOWN_IP6_MCAST_OFFSET 8 ++#define RTL8367C_PORT4_UNKNOWN_IP6_MCAST_MASK 0x300 ++#define RTL8367C_PORT3_UNKNOWN_IP6_MCAST_OFFSET 6 ++#define RTL8367C_PORT3_UNKNOWN_IP6_MCAST_MASK 0xC0 ++#define RTL8367C_PORT2_UNKNOWN_IP6_MCAST_OFFSET 4 ++#define RTL8367C_PORT2_UNKNOWN_IP6_MCAST_MASK 0x30 ++#define RTL8367C_PORT1_UNKNOWN_IP6_MCAST_OFFSET 2 ++#define RTL8367C_PORT1_UNKNOWN_IP6_MCAST_MASK 0xC ++#define RTL8367C_PORT0_UNKNOWN_IP6_MCAST_OFFSET 0 ++#define RTL8367C_PORT0_UNKNOWN_IP6_MCAST_MASK 0x3 ++ ++#define RTL8367C_REG_UNKNOWN_IPV6_MULTICAST_CTRL1 0x08cc ++#define RTL8367C_PORT10_UNKNOWN_IP6_MCAST_OFFSET 4 ++#define RTL8367C_PORT10_UNKNOWN_IP6_MCAST_MASK 0x30 ++#define RTL8367C_PORT9_UNKNOWN_IP6_MCAST_OFFSET 2 ++#define RTL8367C_PORT9_UNKNOWN_IP6_MCAST_MASK 0xC ++#define RTL8367C_PORT8_UNKNOWN_IP6_MCAST_OFFSET 0 ++#define RTL8367C_PORT8_UNKNOWN_IP6_MCAST_MASK 0x3 ++ ++#define RTL8367C_REG_UNKNOWN_L2_MULTICAST_CTRL0 0x08cd ++#define RTL8367C_PORT7_UNKNOWN_L2_MCAST_OFFSET 14 ++#define RTL8367C_PORT7_UNKNOWN_L2_MCAST_MASK 0xC000 ++#define RTL8367C_PORT6_UNKNOWN_L2_MCAST_OFFSET 12 ++#define RTL8367C_PORT6_UNKNOWN_L2_MCAST_MASK 0x3000 ++#define RTL8367C_PORT5_UNKNOWN_L2_MCAST_OFFSET 10 ++#define RTL8367C_PORT5_UNKNOWN_L2_MCAST_MASK 0xC00 ++#define RTL8367C_PORT4_UNKNOWN_L2_MCAST_OFFSET 8 ++#define RTL8367C_PORT4_UNKNOWN_L2_MCAST_MASK 0x300 ++#define RTL8367C_PORT3_UNKNOWN_L2_MCAST_OFFSET 6 ++#define RTL8367C_PORT3_UNKNOWN_L2_MCAST_MASK 0xC0 ++#define RTL8367C_PORT2_UNKNOWN_L2_MCAST_OFFSET 4 ++#define RTL8367C_PORT2_UNKNOWN_L2_MCAST_MASK 0x30 ++#define RTL8367C_PORT1_UNKNOWN_L2_MCAST_OFFSET 2 ++#define RTL8367C_PORT1_UNKNOWN_L2_MCAST_MASK 0xC ++#define RTL8367C_PORT0_UNKNOWN_L2_MCAST_OFFSET 0 ++#define RTL8367C_PORT0_UNKNOWN_L2_MCAST_MASK 0x3 ++ ++#define RTL8367C_REG_PORT_TRUNK_DROP_CTRL 0x08ce ++#define RTL8367C_PORT_TRUNK_DROP_CTRL_OFFSET 0 ++#define RTL8367C_PORT_TRUNK_DROP_CTRL_MASK 0x1 ++ ++#define RTL8367C_REG_PORT_TRUNK_CTRL 0x08cf ++#define RTL8367C_PORT_TRUNK_DUMB_OFFSET 8 ++#define RTL8367C_PORT_TRUNK_DUMB_MASK 0x100 ++#define RTL8367C_PORT_TRUNK_FLOOD_OFFSET 7 ++#define RTL8367C_PORT_TRUNK_FLOOD_MASK 0x80 ++#define RTL8367C_DPORT_HASH_OFFSET 6 ++#define RTL8367C_DPORT_HASH_MASK 0x40 ++#define RTL8367C_SPORT_HASH_OFFSET 5 ++#define RTL8367C_SPORT_HASH_MASK 0x20 ++#define RTL8367C_DIP_HASH_OFFSET 4 ++#define RTL8367C_DIP_HASH_MASK 0x10 ++#define RTL8367C_SIP_HASH_OFFSET 3 ++#define RTL8367C_SIP_HASH_MASK 0x8 ++#define RTL8367C_DMAC_HASH_OFFSET 2 ++#define RTL8367C_DMAC_HASH_MASK 0x4 ++#define RTL8367C_SMAC_HASH_OFFSET 1 ++#define RTL8367C_SMAC_HASH_MASK 0x2 ++#define RTL8367C_SPA_HASH_OFFSET 0 ++#define RTL8367C_SPA_HASH_MASK 0x1 ++ ++#define RTL8367C_REG_PORT_TRUNK_GROUP_MASK 0x08d0 ++#define RTL8367C_PORT_TRUNK_GROUP2_MASK_OFFSET 8 ++#define RTL8367C_PORT_TRUNK_GROUP2_MASK_MASK 0x300 ++#define RTL8367C_PORT_TRUNK_GROUP1_MASK_OFFSET 4 ++#define RTL8367C_PORT_TRUNK_GROUP1_MASK_MASK 0xF0 ++#define RTL8367C_PORT_TRUNK_GROUP0_MASK_OFFSET 0 ++#define RTL8367C_PORT_TRUNK_GROUP0_MASK_MASK 0xF ++ ++#define RTL8367C_REG_PORT_TRUNK_FLOWCTRL 0x08d1 ++#define RTL8367C_EN_FLOWCTRL_TG2_OFFSET 2 ++#define RTL8367C_EN_FLOWCTRL_TG2_MASK 0x4 ++#define RTL8367C_EN_FLOWCTRL_TG1_OFFSET 1 ++#define RTL8367C_EN_FLOWCTRL_TG1_MASK 0x2 ++#define RTL8367C_EN_FLOWCTRL_TG0_OFFSET 0 ++#define RTL8367C_EN_FLOWCTRL_TG0_MASK 0x1 ++ ++#define RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL0 0x08d2 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH7_OFFSET 14 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH7_MASK 0xC000 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH6_OFFSET 12 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH6_MASK 0x3000 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH5_OFFSET 10 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH5_MASK 0xC00 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH4_OFFSET 8 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH4_MASK 0x300 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH3_OFFSET 6 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH3_MASK 0xC0 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH2_OFFSET 4 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH2_MASK 0x30 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH1_OFFSET 2 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH1_MASK 0xC ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH0_OFFSET 0 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH0_MASK 0x3 ++ ++#define RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL1 0x08d3 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH15_OFFSET 14 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH15_MASK 0xC000 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH14_OFFSET 12 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH14_MASK 0x3000 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH13_OFFSET 10 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH13_MASK 0xC00 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH12_OFFSET 8 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH12_MASK 0x300 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH11_OFFSET 6 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH11_MASK 0xC0 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH10_OFFSET 4 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH10_MASK 0x30 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH9_OFFSET 2 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH9_MASK 0xC ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH8_OFFSET 0 ++#define RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH8_MASK 0x3 ++ ++#define RTL8367C_REG_DOS_CFG 0x08d4 ++#define RTL8367C_DROP_ICMPFRAGMENT_OFFSET 9 ++#define RTL8367C_DROP_ICMPFRAGMENT_MASK 0x200 ++#define RTL8367C_DROP_TCPFRAGERROR_OFFSET 8 ++#define RTL8367C_DROP_TCPFRAGERROR_MASK 0x100 ++#define RTL8367C_DROP_TCPSHORTHDR_OFFSET 7 ++#define RTL8367C_DROP_TCPSHORTHDR_MASK 0x80 ++#define RTL8367C_DROP_SYN1024_OFFSET 6 ++#define RTL8367C_DROP_SYN1024_MASK 0x40 ++#define RTL8367C_DROP_NULLSCAN_OFFSET 5 ++#define RTL8367C_DROP_NULLSCAN_MASK 0x20 ++#define RTL8367C_DROP_XMASCAN_OFFSET 4 ++#define RTL8367C_DROP_XMASCAN_MASK 0x10 ++#define RTL8367C_DROP_SYNFINSCAN_OFFSET 3 ++#define RTL8367C_DROP_SYNFINSCAN_MASK 0x8 ++#define RTL8367C_DROP_BLATATTACKS_OFFSET 2 ++#define RTL8367C_DROP_BLATATTACKS_MASK 0x4 ++#define RTL8367C_DROP_LANDATTACKS_OFFSET 1 ++#define RTL8367C_DROP_LANDATTACKS_MASK 0x2 ++#define RTL8367C_DROP_DAEQSA_OFFSET 0 ++#define RTL8367C_DROP_DAEQSA_MASK 0x1 ++ ++#define RTL8367C_REG_UNKNOWN_L2_MULTICAST_CTRL1 0x08d5 ++#define RTL8367C_PORT10_UNKNOWN_L2_MCAST_OFFSET 4 ++#define RTL8367C_PORT10_UNKNOWN_L2_MCAST_MASK 0x30 ++#define RTL8367C_PORT9_UNKNOWN_L2_MCAST_OFFSET 2 ++#define RTL8367C_PORT9_UNKNOWN_L2_MCAST_MASK 0xC ++#define RTL8367C_PORT8_UNKNOWN_L2_MCAST_OFFSET 0 ++#define RTL8367C_PORT8_UNKNOWN_L2_MCAST_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4 0x08d6 ++#define RTL8367C_PORT9_VLAN_KEEP_MASK_OFFSET 8 ++#define RTL8367C_PORT9_VLAN_KEEP_MASK_MASK 0xFF00 ++#define RTL8367C_PORT8_VLAN_KEEP_MASK_OFFSET 0 ++#define RTL8367C_PORT8_VLAN_KEEP_MASK_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5 0x08d7 ++#define RTL8367C_VLAN_EGRESS_KEEP_CTRL5_OFFSET 0 ++#define RTL8367C_VLAN_EGRESS_KEEP_CTRL5_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0_EXT 0x08d8 ++#define RTL8367C_PORT1_VLAN_KEEP_MASK_EXT_OFFSET 3 ++#define RTL8367C_PORT1_VLAN_KEEP_MASK_EXT_MASK 0x38 ++#define RTL8367C_PORT0_VLAN_KEEP_MASK_EXT_OFFSET 0 ++#define RTL8367C_PORT0_VLAN_KEEP_MASK_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL1_EXT 0x08d9 ++#define RTL8367C_PORT3_VLAN_KEEP_MASK_EXT_OFFSET 3 ++#define RTL8367C_PORT3_VLAN_KEEP_MASK_EXT_MASK 0x38 ++#define RTL8367C_PORT2_VLAN_KEEP_MASK_EXT_OFFSET 0 ++#define RTL8367C_PORT2_VLAN_KEEP_MASK_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL2_EXT 0x08da ++#define RTL8367C_PORT5_VLAN_KEEP_MASK_EXT_OFFSET 3 ++#define RTL8367C_PORT5_VLAN_KEEP_MASK_EXT_MASK 0x38 ++#define RTL8367C_PORT4_VLAN_KEEP_MASK_EXT_OFFSET 0 ++#define RTL8367C_PORT4_VLAN_KEEP_MASK_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL3_EXT 0x08db ++#define RTL8367C_PORT7_VLAN_KEEP_MASK_EXT_OFFSET 3 ++#define RTL8367C_PORT7_VLAN_KEEP_MASK_EXT_MASK 0x38 ++#define RTL8367C_PORT6_VLAN_KEEP_MASK_EXT_OFFSET 0 ++#define RTL8367C_PORT6_VLAN_KEEP_MASK_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4_EXT 0x08dc ++#define RTL8367C_PORT9_VLAN_KEEP_MASK_EXT_OFFSET 3 ++#define RTL8367C_PORT9_VLAN_KEEP_MASK_EXT_MASK 0x38 ++#define RTL8367C_PORT8_VLAN_KEEP_MASK_EXT_OFFSET 0 ++#define RTL8367C_PORT8_VLAN_KEEP_MASK_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5_EXT 0x08dd ++#define RTL8367C_VLAN_EGRESS_KEEP_CTRL5_EXT_OFFSET 0 ++#define RTL8367C_VLAN_EGRESS_KEEP_CTRL5_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL10 0x08de ++#define RTL8367C_VLAN_EGRESS_TRANS_CTRL10_OFFSET 0 ++#define RTL8367C_VLAN_EGRESS_TRANS_CTRL10_MASK 0x7FF ++ ++#define RTL8367C_REG_FPGA_VER_CEN 0x08e0 ++ ++#define RTL8367C_REG_FPGA_TIME_CEN 0x08e1 ++ ++#define RTL8367C_REG_FPGA_DATE_CEN 0x08e2 ++ ++#define RTL8367C_REG_QOS_PORT_QUEUE_NUMBER_CTRL0 0x0900 ++#define RTL8367C_PORT3_NUMBER_OFFSET 12 ++#define RTL8367C_PORT3_NUMBER_MASK 0x7000 ++#define RTL8367C_PORT2_NUMBER_OFFSET 8 ++#define RTL8367C_PORT2_NUMBER_MASK 0x700 ++#define RTL8367C_PORT1_NUMBER_OFFSET 4 ++#define RTL8367C_PORT1_NUMBER_MASK 0x70 ++#define RTL8367C_PORT0_NUMBER_OFFSET 0 ++#define RTL8367C_PORT0_NUMBER_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_PORT_QUEUE_NUMBER_CTRL1 0x0901 ++#define RTL8367C_PORT7_NUMBER_OFFSET 12 ++#define RTL8367C_PORT7_NUMBER_MASK 0x7000 ++#define RTL8367C_PORT6_NUMBER_OFFSET 8 ++#define RTL8367C_PORT6_NUMBER_MASK 0x700 ++#define RTL8367C_PORT5_NUMBER_OFFSET 4 ++#define RTL8367C_PORT5_NUMBER_MASK 0x70 ++#define RTL8367C_PORT4_NUMBER_OFFSET 0 ++#define RTL8367C_PORT4_NUMBER_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_PORT_QUEUE_NUMBER_CTRL2 0x0902 ++#define RTL8367C_PORT10_NUMBER_OFFSET 8 ++#define RTL8367C_PORT10_NUMBER_MASK 0x700 ++#define RTL8367C_PORT9_NUMBER_OFFSET 4 ++#define RTL8367C_PORT9_NUMBER_MASK 0x70 ++#define RTL8367C_PORT8_NUMBER_OFFSET 0 ++#define RTL8367C_PORT8_NUMBER_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_1Q_PRIORITY_TO_QID_CTRL0 0x0904 ++#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 ++#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 ++#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 ++#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 ++#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 ++#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 ++#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 ++#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_1Q_PRIORITY_TO_QID_CTRL1 0x0905 ++#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 ++#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 ++#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 ++#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 ++#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 ++#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 ++#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 ++#define RTL8367C_QOS_1Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_2Q_PRIORITY_TO_QID_CTRL0 0x0906 ++#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 ++#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 ++#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 ++#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 ++#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 ++#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 ++#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 ++#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_2Q_PRIORITY_TO_QID_CTRL1 0x0907 ++#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 ++#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 ++#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 ++#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 ++#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 ++#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 ++#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 ++#define RTL8367C_QOS_2Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_3Q_PRIORITY_TO_QID_CTRL0 0x0908 ++#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 ++#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 ++#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 ++#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 ++#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 ++#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 ++#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 ++#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_3Q_PRIORITY_TO_QID_CTRL1 0x0909 ++#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 ++#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 ++#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 ++#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 ++#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 ++#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 ++#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 ++#define RTL8367C_QOS_3Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_4Q_PRIORITY_TO_QID_CTRL0 0x090a ++#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 ++#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 ++#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 ++#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 ++#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 ++#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 ++#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 ++#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_4Q_PRIORITY_TO_QID_CTRL1 0x090b ++#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 ++#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 ++#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 ++#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 ++#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 ++#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 ++#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 ++#define RTL8367C_QOS_4Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_5Q_PRIORITY_TO_QID_CTRL0 0x090c ++#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 ++#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 ++#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 ++#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 ++#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 ++#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 ++#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 ++#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_5Q_PRIORITY_TO_QID_CTRL1 0x090d ++#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 ++#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 ++#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 ++#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 ++#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 ++#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 ++#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 ++#define RTL8367C_QOS_5Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_6Q_PRIORITY_TO_QID_CTRL0 0x090e ++#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 ++#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 ++#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 ++#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 ++#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 ++#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 ++#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 ++#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_6Q_PRIORITY_TO_QID_CTRL1 0x090f ++#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 ++#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 ++#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 ++#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 ++#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 ++#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 ++#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 ++#define RTL8367C_QOS_6Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_7Q_PRIORITY_TO_QID_CTRL0 0x0910 ++#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 ++#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 ++#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 ++#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 ++#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 ++#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 ++#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 ++#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_7Q_PRIORITY_TO_QID_CTRL1 0x0911 ++#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 ++#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 ++#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 ++#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 ++#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 ++#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 ++#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 ++#define RTL8367C_QOS_7Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_8Q_PRIORITY_TO_QID_CTRL0 0x0912 ++#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_OFFSET 12 ++#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY3_TO_QID_MASK 0x7000 ++#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_OFFSET 8 ++#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY2_TO_QID_MASK 0x700 ++#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_OFFSET 4 ++#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY1_TO_QID_MASK 0x70 ++#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_OFFSET 0 ++#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL0_PRIORITY0_TO_QID_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_8Q_PRIORITY_TO_QID_CTRL1 0x0913 ++#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_OFFSET 12 ++#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY7_TO_QID_MASK 0x7000 ++#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_OFFSET 8 ++#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY6_TO_QID_MASK 0x700 ++#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_OFFSET 4 ++#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY5_TO_QID_MASK 0x70 ++#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_OFFSET 0 ++#define RTL8367C_QOS_8Q_PRIORITY_TO_QID_CTRL1_PRIORITY4_TO_QID_MASK 0x7 ++ ++#define RTL8367C_REG_HIGHPRI_INDICATOR 0x0915 ++#define RTL8367C_PORT10_INDICATOR_OFFSET 10 ++#define RTL8367C_PORT10_INDICATOR_MASK 0x400 ++#define RTL8367C_PORT9_INDICATOR_OFFSET 9 ++#define RTL8367C_PORT9_INDICATOR_MASK 0x200 ++#define RTL8367C_PORT8_INDICATOR_OFFSET 8 ++#define RTL8367C_PORT8_INDICATOR_MASK 0x100 ++#define RTL8367C_PORT7_INDICATOR_OFFSET 7 ++#define RTL8367C_PORT7_INDICATOR_MASK 0x80 ++#define RTL8367C_PORT6_INDICATOR_OFFSET 6 ++#define RTL8367C_PORT6_INDICATOR_MASK 0x40 ++#define RTL8367C_PORT5_INDICATOR_OFFSET 5 ++#define RTL8367C_PORT5_INDICATOR_MASK 0x20 ++#define RTL8367C_PORT4_INDICATOR_OFFSET 4 ++#define RTL8367C_PORT4_INDICATOR_MASK 0x10 ++#define RTL8367C_PORT3_INDICATOR_OFFSET 3 ++#define RTL8367C_PORT3_INDICATOR_MASK 0x8 ++#define RTL8367C_PORT2_INDICATOR_OFFSET 2 ++#define RTL8367C_PORT2_INDICATOR_MASK 0x4 ++#define RTL8367C_PORT1_INDICATOR_OFFSET 1 ++#define RTL8367C_PORT1_INDICATOR_MASK 0x2 ++#define RTL8367C_PORT0_INDICATOR_OFFSET 0 ++#define RTL8367C_PORT0_INDICATOR_MASK 0x1 ++ ++#define RTL8367C_REG_HIGHPRI_CFG 0x0916 ++#define RTL8367C_HIGHPRI_CFG_OFFSET 0 ++#define RTL8367C_HIGHPRI_CFG_MASK 0xFF ++ ++#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL0 0x0917 ++#define RTL8367C_PORT1_DEBUG_INFO_OFFSET 8 ++#define RTL8367C_PORT1_DEBUG_INFO_MASK 0xFF00 ++#define RTL8367C_PORT0_DEBUG_INFO_OFFSET 0 ++#define RTL8367C_PORT0_DEBUG_INFO_MASK 0xFF ++ ++#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL1 0x0918 ++#define RTL8367C_PORT3_DEBUG_INFO_OFFSET 8 ++#define RTL8367C_PORT3_DEBUG_INFO_MASK 0xFF00 ++#define RTL8367C_PORT2_DEBUG_INFO_OFFSET 0 ++#define RTL8367C_PORT2_DEBUG_INFO_MASK 0xFF ++ ++#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL2 0x0919 ++#define RTL8367C_PORT5_DEBUG_INFO_OFFSET 8 ++#define RTL8367C_PORT5_DEBUG_INFO_MASK 0xFF00 ++#define RTL8367C_PORT4_DEBUG_INFO_OFFSET 0 ++#define RTL8367C_PORT4_DEBUG_INFO_MASK 0xFF ++ ++#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL3 0x091a ++#define RTL8367C_PORT7_DEBUG_INFO_OFFSET 8 ++#define RTL8367C_PORT7_DEBUG_INFO_MASK 0xFF00 ++#define RTL8367C_PORT6_DEBUG_INFO_OFFSET 0 ++#define RTL8367C_PORT6_DEBUG_INFO_MASK 0xFF ++ ++#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL4 0x091b ++#define RTL8367C_PORT9_DEBUG_INFO_OFFSET 8 ++#define RTL8367C_PORT9_DEBUG_INFO_MASK 0xFF00 ++#define RTL8367C_PORT8_DEBUG_INFO_OFFSET 0 ++#define RTL8367C_PORT8_DEBUG_INFO_MASK 0xFF ++ ++#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL5 0x091c ++#define RTL8367C_PORT10_DEBUG_INFO_OFFSET 0 ++#define RTL8367C_PORT10_DEBUG_INFO_MASK 0xFF ++ ++#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL6 0x091d ++#define RTL8367C_PORT7_DEBUG_INDICATOR_OFFSET 14 ++#define RTL8367C_PORT7_DEBUG_INDICATOR_MASK 0xC000 ++#define RTL8367C_PORT6_DEBUG_INDICATOR_OFFSET 12 ++#define RTL8367C_PORT6_DEBUG_INDICATOR_MASK 0x3000 ++#define RTL8367C_PORT5_DEBUG_INDICATOR_OFFSET 10 ++#define RTL8367C_PORT5_DEBUG_INDICATOR_MASK 0xC00 ++#define RTL8367C_PORT4_DEBUG_INDICATOR_OFFSET 8 ++#define RTL8367C_PORT4_DEBUG_INDICATOR_MASK 0x300 ++#define RTL8367C_PORT3_DEBUG_INDICATOR_OFFSET 6 ++#define RTL8367C_PORT3_DEBUG_INDICATOR_MASK 0xC0 ++#define RTL8367C_PORT2_DEBUG_INDICATOR_OFFSET 4 ++#define RTL8367C_PORT2_DEBUG_INDICATOR_MASK 0x30 ++#define RTL8367C_PORT1_DEBUG_INDICATOR_OFFSET 2 ++#define RTL8367C_PORT1_DEBUG_INDICATOR_MASK 0xC ++#define RTL8367C_PORT0_DEBUG_INDICATOR_OFFSET 0 ++#define RTL8367C_PORT0_DEBUG_INDICATOR_MASK 0x3 ++ ++#define RTL8367C_REG_PORT_DEBUG_INFO_CTRL7 0x091e ++#define RTL8367C_PORT10_DEBUG_INDICATOR_OFFSET 4 ++#define RTL8367C_PORT10_DEBUG_INDICATOR_MASK 0x30 ++#define RTL8367C_PORT9_DEBUG_INDICATOR_OFFSET 2 ++#define RTL8367C_PORT9_DEBUG_INDICATOR_MASK 0xC ++#define RTL8367C_PORT8_DEBUG_INDICATOR_OFFSET 0 ++#define RTL8367C_PORT8_DEBUG_INDICATOR_MASK 0x3 ++ ++#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL0 0x0930 ++#define RTL8367C_PORT1_QUEUE_MASK_OFFSET 8 ++#define RTL8367C_PORT1_QUEUE_MASK_MASK 0xFF00 ++#define RTL8367C_PORT0_QUEUE_MASK_OFFSET 0 ++#define RTL8367C_PORT0_QUEUE_MASK_MASK 0xFF ++ ++#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL1 0x0931 ++#define RTL8367C_PORT3_QUEUE_MASK_OFFSET 8 ++#define RTL8367C_PORT3_QUEUE_MASK_MASK 0xFF00 ++#define RTL8367C_PORT2_QUEUE_MASK_OFFSET 0 ++#define RTL8367C_PORT2_QUEUE_MASK_MASK 0xFF ++ ++#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL2 0x0932 ++#define RTL8367C_PORT5_QUEUE_MASK_OFFSET 8 ++#define RTL8367C_PORT5_QUEUE_MASK_MASK 0xFF00 ++#define RTL8367C_PORT4_QUEUE_MASK_OFFSET 0 ++#define RTL8367C_PORT4_QUEUE_MASK_MASK 0xFF ++ ++#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL3 0x0933 ++#define RTL8367C_PORT7_QUEUE_MASK_OFFSET 8 ++#define RTL8367C_PORT7_QUEUE_MASK_MASK 0xFF00 ++#define RTL8367C_PORT6_QUEUE_MASK_OFFSET 0 ++#define RTL8367C_PORT6_QUEUE_MASK_MASK 0xFF ++ ++#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL4 0x0934 ++#define RTL8367C_PORT9_QUEUE_MASK_OFFSET 8 ++#define RTL8367C_PORT9_QUEUE_MASK_MASK 0xFF00 ++#define RTL8367C_PORT8_QUEUE_MASK_OFFSET 0 ++#define RTL8367C_PORT8_QUEUE_MASK_MASK 0xFF ++ ++#define RTL8367C_REG_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL5 0x0935 ++#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL5_OFFSET 0 ++#define RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_CTRL5_MASK 0xFF ++ ++#define RTL8367C_REG_FLOWCRTL_EGRESS_PORT_ENABLE 0x0938 ++#define RTL8367C_FLOWCRTL_EGRESS_PORT_ENABLE_OFFSET 0 ++#define RTL8367C_FLOWCRTL_EGRESS_PORT_ENABLE_MASK 0xFF ++ ++#define RTL8367C_REG_EAV_CTRL 0x0939 ++#define RTL8367C_EAV_TRAP_CPU_OFFSET 1 ++#define RTL8367C_EAV_TRAP_CPU_MASK 0x2 ++#define RTL8367C_EAV_TRAP_8051_OFFSET 0 ++#define RTL8367C_EAV_TRAP_8051_MASK 0x1 ++ ++#define RTL8367C_REG_UNTAG_DSCP_PRI_CFG 0x093a ++#define RTL8367C_UNTAG_DSCP_PRI_CFG_OFFSET 0 ++#define RTL8367C_UNTAG_DSCP_PRI_CFG_MASK 0x1 ++ ++#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0 0x093b ++#define RTL8367C_PORT1_VLAN_KEEP_MASK_OFFSET 8 ++#define RTL8367C_PORT1_VLAN_KEEP_MASK_MASK 0xFF00 ++#define RTL8367C_PORT0_VLAN_KEEP_MASK_OFFSET 0 ++#define RTL8367C_PORT0_VLAN_KEEP_MASK_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL1 0x093c ++#define RTL8367C_PORT3_VLAN_KEEP_MASK_OFFSET 8 ++#define RTL8367C_PORT3_VLAN_KEEP_MASK_MASK 0xFF00 ++#define RTL8367C_PORT2_VLAN_KEEP_MASK_OFFSET 0 ++#define RTL8367C_PORT2_VLAN_KEEP_MASK_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL2 0x093d ++#define RTL8367C_PORT5_VLAN_KEEP_MASK_OFFSET 8 ++#define RTL8367C_PORT5_VLAN_KEEP_MASK_MASK 0xFF00 ++#define RTL8367C_PORT4_VLAN_KEEP_MASK_OFFSET 0 ++#define RTL8367C_PORT4_VLAN_KEEP_MASK_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL3 0x093e ++#define RTL8367C_PORT7_VLAN_KEEP_MASK_OFFSET 8 ++#define RTL8367C_PORT7_VLAN_KEEP_MASK_MASK 0xFF00 ++#define RTL8367C_PORT6_VLAN_KEEP_MASK_OFFSET 0 ++#define RTL8367C_PORT6_VLAN_KEEP_MASK_MASK 0xFF ++ ++#define RTL8367C_REG_VLAN_TRANSPARENT_EN_CFG 0x093f ++#define RTL8367C_VLAN_TRANSPARENT_EN_CFG_OFFSET 0 ++#define RTL8367C_VLAN_TRANSPARENT_EN_CFG_MASK 0x1 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY0_H 0x0940 ++#define RTL8367C_IPMC_GROUP_ENTRY0_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY0_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY0_L 0x0941 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY1_H 0x0942 ++#define RTL8367C_IPMC_GROUP_ENTRY1_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY1_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY1_L 0x0943 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY2_H 0x0944 ++#define RTL8367C_IPMC_GROUP_ENTRY2_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY2_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY2_L 0x0945 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY3_H 0x0946 ++#define RTL8367C_IPMC_GROUP_ENTRY3_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY3_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY3_L 0x0947 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY4_H 0x0948 ++#define RTL8367C_IPMC_GROUP_ENTRY4_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY4_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY4_L 0x0949 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY5_H 0x094a ++#define RTL8367C_IPMC_GROUP_ENTRY5_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY5_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY5_L 0x094b ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY6_H 0x094c ++#define RTL8367C_IPMC_GROUP_ENTRY6_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY6_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY6_L 0x094d ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY7_H 0x094e ++#define RTL8367C_IPMC_GROUP_ENTRY7_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY7_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY7_L 0x094f ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY8_H 0x0950 ++#define RTL8367C_IPMC_GROUP_ENTRY8_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY8_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY8_L 0x0951 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY9_H 0x0952 ++#define RTL8367C_IPMC_GROUP_ENTRY9_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY9_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY9_L 0x0953 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY10_H 0x0954 ++#define RTL8367C_IPMC_GROUP_ENTRY10_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY10_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY10_L 0x0955 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY11_H 0x0956 ++#define RTL8367C_IPMC_GROUP_ENTRY11_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY11_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY11_L 0x0957 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY12_H 0x0958 ++#define RTL8367C_IPMC_GROUP_ENTRY12_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY12_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY12_L 0x0959 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY13_H 0x095a ++#define RTL8367C_IPMC_GROUP_ENTRY13_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY13_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY13_L 0x095b ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY14_H 0x095c ++#define RTL8367C_IPMC_GROUP_ENTRY14_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY14_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY14_L 0x095d ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY15_H 0x095e ++#define RTL8367C_IPMC_GROUP_ENTRY15_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY15_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY15_L 0x095f ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY16_H 0x0960 ++#define RTL8367C_IPMC_GROUP_ENTRY16_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY16_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY16_L 0x0961 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY17_H 0x0962 ++#define RTL8367C_IPMC_GROUP_ENTRY17_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY17_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY17_L 0x0963 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY18_H 0x0964 ++#define RTL8367C_IPMC_GROUP_ENTRY18_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY18_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY18_L 0x0965 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY19_H 0x0966 ++#define RTL8367C_IPMC_GROUP_ENTRY19_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY19_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY19_L 0x0967 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY20_H 0x0968 ++#define RTL8367C_IPMC_GROUP_ENTRY20_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY20_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY20_L 0x0969 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY21_H 0x096a ++#define RTL8367C_IPMC_GROUP_ENTRY21_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY21_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY21_L 0x096b ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY22_H 0x096c ++#define RTL8367C_IPMC_GROUP_ENTRY22_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY22_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY22_L 0x096d ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY23_H 0x096e ++#define RTL8367C_IPMC_GROUP_ENTRY23_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY23_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY23_L 0x096f ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY24_H 0x0970 ++#define RTL8367C_IPMC_GROUP_ENTRY24_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY24_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY24_L 0x0971 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY25_H 0x0972 ++#define RTL8367C_IPMC_GROUP_ENTRY25_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY25_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY25_L 0x0973 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY26_H 0x0974 ++#define RTL8367C_IPMC_GROUP_ENTRY26_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY26_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY26_L 0x0975 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY27_H 0x0976 ++#define RTL8367C_IPMC_GROUP_ENTRY27_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY27_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY27_L 0x0977 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY28_H 0x0978 ++#define RTL8367C_IPMC_GROUP_ENTRY28_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY28_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY28_L 0x0979 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY29_H 0x097a ++#define RTL8367C_IPMC_GROUP_ENTRY29_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY29_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY29_L 0x097b ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY30_H 0x097c ++#define RTL8367C_IPMC_GROUP_ENTRY30_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY30_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY30_L 0x097d ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY31_H 0x097e ++#define RTL8367C_IPMC_GROUP_ENTRY31_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY31_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY31_L 0x097f ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY32_H 0x0980 ++#define RTL8367C_IPMC_GROUP_ENTRY32_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY32_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY32_L 0x0981 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY33_H 0x0982 ++#define RTL8367C_IPMC_GROUP_ENTRY33_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY33_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY33_L 0x0983 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY34_H 0x0984 ++#define RTL8367C_IPMC_GROUP_ENTRY34_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY34_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY34_L 0x0985 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY35_H 0x0986 ++#define RTL8367C_IPMC_GROUP_ENTRY35_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY35_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY35_L 0x0987 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY36_H 0x0988 ++#define RTL8367C_IPMC_GROUP_ENTRY36_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY36_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY36_L 0x0989 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY37_H 0x098a ++#define RTL8367C_IPMC_GROUP_ENTRY37_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY37_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY37_L 0x098b ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY38_H 0x098c ++#define RTL8367C_IPMC_GROUP_ENTRY38_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY38_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY38_L 0x098d ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY39_H 0x098e ++#define RTL8367C_IPMC_GROUP_ENTRY39_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY39_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY39_L 0x098f ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY40_H 0x0990 ++#define RTL8367C_IPMC_GROUP_ENTRY40_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY40_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY40_L 0x0991 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY41_H 0x0992 ++#define RTL8367C_IPMC_GROUP_ENTRY41_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY41_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY41_L 0x0993 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY42_H 0x0994 ++#define RTL8367C_IPMC_GROUP_ENTRY42_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY42_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY42_L 0x0995 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY43_H 0x0996 ++#define RTL8367C_IPMC_GROUP_ENTRY43_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY43_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY43_L 0x0997 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY44_H 0x0998 ++#define RTL8367C_IPMC_GROUP_ENTRY44_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY44_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY44_L 0x0999 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY45_H 0x099a ++#define RTL8367C_IPMC_GROUP_ENTRY45_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY45_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY45_L 0x099b ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY46_H 0x099c ++#define RTL8367C_IPMC_GROUP_ENTRY46_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY46_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY46_L 0x099d ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY47_H 0x099e ++#define RTL8367C_IPMC_GROUP_ENTRY47_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY47_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY47_L 0x099f ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY48_H 0x09a0 ++#define RTL8367C_IPMC_GROUP_ENTRY48_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY48_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY48_L 0x09a1 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY49_H 0x09a2 ++#define RTL8367C_IPMC_GROUP_ENTRY49_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY49_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY49_L 0x09a3 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY50_H 0x09a4 ++#define RTL8367C_IPMC_GROUP_ENTRY50_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY50_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY50_L 0x09a5 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY51_H 0x09a6 ++#define RTL8367C_IPMC_GROUP_ENTRY51_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY51_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY51_L 0x09a7 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY52_H 0x09a8 ++#define RTL8367C_IPMC_GROUP_ENTRY52_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY52_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY52_L 0x09a9 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY53_H 0x09aa ++#define RTL8367C_IPMC_GROUP_ENTRY53_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY53_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY53_L 0x09ab ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY54_H 0x09ac ++#define RTL8367C_IPMC_GROUP_ENTRY54_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY54_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY54_L 0x09ad ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY55_H 0x09ae ++#define RTL8367C_IPMC_GROUP_ENTRY55_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY55_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY55_L 0x09af ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY56_H 0x09b0 ++#define RTL8367C_IPMC_GROUP_ENTRY56_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY56_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY56_L 0x09b1 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY57_H 0x09b2 ++#define RTL8367C_IPMC_GROUP_ENTRY57_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY57_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY57_L 0x09b3 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY58_H 0x09b4 ++#define RTL8367C_IPMC_GROUP_ENTRY58_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY58_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY58_L 0x09b5 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY59_H 0x09b6 ++#define RTL8367C_IPMC_GROUP_ENTRY59_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY59_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY59_L 0x09b7 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY60_H 0x09b8 ++#define RTL8367C_IPMC_GROUP_ENTRY60_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY60_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY60_L 0x09b9 ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY61_H 0x09ba ++#define RTL8367C_IPMC_GROUP_ENTRY61_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY61_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY61_L 0x09bb ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY62_H 0x09bc ++#define RTL8367C_IPMC_GROUP_ENTRY62_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY62_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY62_L 0x09bd ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY63_H 0x09be ++#define RTL8367C_IPMC_GROUP_ENTRY63_H_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_ENTRY63_H_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_ENTRY63_L 0x09bf ++ ++#define RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE 0x09C0 ++#define RTL8367C_Port7_ACTION_OFFSET 14 ++#define RTL8367C_Port7_ACTION_MASK 0xC000 ++#define RTL8367C_Port6_ACTION_OFFSET 12 ++#define RTL8367C_Port6_ACTION_MASK 0x3000 ++#define RTL8367C_Port5_ACTION_OFFSET 10 ++#define RTL8367C_Port5_ACTION_MASK 0xC00 ++#define RTL8367C_Port4_ACTION_OFFSET 8 ++#define RTL8367C_Port4_ACTION_MASK 0x300 ++#define RTL8367C_Port3_ACTION_OFFSET 6 ++#define RTL8367C_Port3_ACTION_MASK 0xC0 ++#define RTL8367C_Port2_ACTION_OFFSET 4 ++#define RTL8367C_Port2_ACTION_MASK 0x30 ++#define RTL8367C_Port1_ACTION_OFFSET 2 ++#define RTL8367C_Port1_ACTION_MASK 0xC ++#define RTL8367C_Port0_ACTION_OFFSET 0 ++#define RTL8367C_Port0_ACTION_MASK 0x3 ++ ++#define RTL8367C_REG_MIRROR_CTRL3 0x09C1 ++#define RTL8367C_MIRROR_ACL_OVERRIDE_EN_OFFSET 2 ++#define RTL8367C_MIRROR_ACL_OVERRIDE_EN_MASK 0x4 ++#define RTL8367C_MIRROR_TX_OVERRIDE_EN_OFFSET 1 ++#define RTL8367C_MIRROR_TX_OVERRIDE_EN_MASK 0x2 ++#define RTL8367C_MIRROR_RX_OVERRIDE_EN_OFFSET 0 ++#define RTL8367C_MIRROR_RX_OVERRIDE_EN_MASK 0x1 ++ ++#define RTL8367C_REG_DPM_DUMMY02 0x09C2 ++ ++#define RTL8367C_REG_DPM_DUMMY03 0x09C3 ++ ++#define RTL8367C_REG_DPM_DUMMY04 0x09C4 ++ ++#define RTL8367C_REG_DPM_DUMMY05 0x09C5 ++ ++#define RTL8367C_REG_DPM_DUMMY06 0x09C6 ++ ++#define RTL8367C_REG_DPM_DUMMY07 0x09C7 ++ ++#define RTL8367C_REG_DPM_DUMMY08 0x09C8 ++ ++#define RTL8367C_REG_DPM_DUMMY09 0x09C9 ++ ++#define RTL8367C_REG_DPM_DUMMY10 0x09CA ++ ++#define RTL8367C_REG_DPM_DUMMY11 0x09CB ++ ++#define RTL8367C_REG_DPM_DUMMY12 0x09CC ++ ++#define RTL8367C_REG_DPM_DUMMY13 0x09CD ++ ++#define RTL8367C_REG_DPM_DUMMY14 0x09CE ++ ++#define RTL8367C_REG_DPM_DUMMY15 0x09CF ++ ++#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL0 0x09D0 ++#define RTL8367C_VLAN_EGRESS_TRANS_CTRL0_OFFSET 0 ++#define RTL8367C_VLAN_EGRESS_TRANS_CTRL0_MASK 0x7FF ++ ++#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL1 0x09D1 ++#define RTL8367C_VLAN_EGRESS_TRANS_CTRL1_OFFSET 0 ++#define RTL8367C_VLAN_EGRESS_TRANS_CTRL1_MASK 0x7FF ++ ++#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL2 0x09D2 ++#define RTL8367C_VLAN_EGRESS_TRANS_CTRL2_OFFSET 0 ++#define RTL8367C_VLAN_EGRESS_TRANS_CTRL2_MASK 0x7FF ++ ++#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL3 0x09D3 ++#define RTL8367C_VLAN_EGRESS_TRANS_CTRL3_OFFSET 0 ++#define RTL8367C_VLAN_EGRESS_TRANS_CTRL3_MASK 0x7FF ++ ++#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL4 0x09D4 ++#define RTL8367C_VLAN_EGRESS_TRANS_CTRL4_OFFSET 0 ++#define RTL8367C_VLAN_EGRESS_TRANS_CTRL4_MASK 0x7FF ++ ++#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL5 0x09D5 ++#define RTL8367C_VLAN_EGRESS_TRANS_CTRL5_OFFSET 0 ++#define RTL8367C_VLAN_EGRESS_TRANS_CTRL5_MASK 0x7FF ++ ++#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL6 0x09D6 ++#define RTL8367C_VLAN_EGRESS_TRANS_CTRL6_OFFSET 0 ++#define RTL8367C_VLAN_EGRESS_TRANS_CTRL6_MASK 0x7FF ++ ++#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL7 0x09D7 ++#define RTL8367C_VLAN_EGRESS_TRANS_CTRL7_OFFSET 0 ++#define RTL8367C_VLAN_EGRESS_TRANS_CTRL7_MASK 0x7FF ++ ++#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL8 0x09D8 ++#define RTL8367C_VLAN_EGRESS_TRANS_CTRL8_OFFSET 0 ++#define RTL8367C_VLAN_EGRESS_TRANS_CTRL8_MASK 0x7FF ++ ++#define RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL9 0x09D9 ++#define RTL8367C_VLAN_EGRESS_TRANS_CTRL9_OFFSET 0 ++#define RTL8367C_VLAN_EGRESS_TRANS_CTRL9_MASK 0x7FF ++ ++#define RTL8367C_REG_MIRROR_CTRL2 0x09DA ++#define RTL8367C_MIRROR_REALKEEP_EN_OFFSET 4 ++#define RTL8367C_MIRROR_REALKEEP_EN_MASK 0x10 ++#define RTL8367C_MIRROR_RX_ISOLATION_LEAKY_OFFSET 3 ++#define RTL8367C_MIRROR_RX_ISOLATION_LEAKY_MASK 0x8 ++#define RTL8367C_MIRROR_TX_ISOLATION_LEAKY_OFFSET 2 ++#define RTL8367C_MIRROR_TX_ISOLATION_LEAKY_MASK 0x4 ++#define RTL8367C_MIRROR_RX_VLAN_LEAKY_OFFSET 1 ++#define RTL8367C_MIRROR_RX_VLAN_LEAKY_MASK 0x2 ++#define RTL8367C_MIRROR_TX_VLAN_LEAKY_OFFSET 0 ++#define RTL8367C_MIRROR_TX_VLAN_LEAKY_MASK 0x1 ++ ++#define RTL8367C_REG_OUTPUT_DROP_CFG 0x09DB ++#define RTL8367C_ENABLE_PMASK_EXT_OFFSET 13 ++#define RTL8367C_ENABLE_PMASK_EXT_MASK 0xE000 ++#define RTL8367C_ENABLE_BC_OFFSET 12 ++#define RTL8367C_ENABLE_BC_MASK 0x1000 ++#define RTL8367C_ENABLE_MC_OFFSET 11 ++#define RTL8367C_ENABLE_MC_MASK 0x800 ++#define RTL8367C_ENABLE_UC_OFFSET 10 ++#define RTL8367C_ENABLE_UC_MASK 0x400 ++#define RTL8367C_ENABLE_PMASK_OFFSET 0 ++#define RTL8367C_ENABLE_PMASK_MASK 0xFF ++ ++#define RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE_EXT 0x09DC ++#define RTL8367C_PORT10_ACTION_OFFSET 4 ++#define RTL8367C_PORT10_ACTION_MASK 0x30 ++#define RTL8367C_PORT9_ACTION_OFFSET 2 ++#define RTL8367C_PORT9_ACTION_MASK 0xC ++#define RTL8367C_PORT8_ACTION_OFFSET 0 ++#define RTL8367C_PORT8_ACTION_MASK 0x3 ++ ++#define RTL8367C_REG_RMK_CFG_SEL_CTRL 0x09DF ++#define RTL8367C_RMK_1Q_CFG_SEL_OFFSET 2 ++#define RTL8367C_RMK_1Q_CFG_SEL_MASK 0x4 ++#define RTL8367C_RMK_DSCP_CFG_SEL_OFFSET 0 ++#define RTL8367C_RMK_DSCP_CFG_SEL_MASK 0x3 ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL0 0x09E0 ++#define RTL8367C_DSCP1_DSCP_OFFSET 8 ++#define RTL8367C_DSCP1_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP0_DSCP_OFFSET 0 ++#define RTL8367C_DSCP0_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL1 0x09E1 ++#define RTL8367C_DSCP3_DSCP_OFFSET 8 ++#define RTL8367C_DSCP3_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP2_DSCP_OFFSET 0 ++#define RTL8367C_DSCP2_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL2 0x09E2 ++#define RTL8367C_DSCP5_DSCP_OFFSET 8 ++#define RTL8367C_DSCP5_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP4_DSCP_OFFSET 0 ++#define RTL8367C_DSCP4_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL3 0x09E3 ++#define RTL8367C_DSCP7_DSCP_OFFSET 8 ++#define RTL8367C_DSCP7_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP6_DSCP_OFFSET 0 ++#define RTL8367C_DSCP6_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL4 0x09E4 ++#define RTL8367C_DSCP9_DSCP_OFFSET 8 ++#define RTL8367C_DSCP9_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP8_DSCP_OFFSET 0 ++#define RTL8367C_DSCP8_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL5 0x09E5 ++#define RTL8367C_DSCP11_DSCP_OFFSET 8 ++#define RTL8367C_DSCP11_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP10_DSCP_OFFSET 0 ++#define RTL8367C_DSCP10_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL6 0x09E6 ++#define RTL8367C_DSCP13_DSCP_OFFSET 8 ++#define RTL8367C_DSCP13_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP12_DSCP_OFFSET 0 ++#define RTL8367C_DSCP12_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL7 0x09E7 ++#define RTL8367C_DSCP15_DSCP_OFFSET 8 ++#define RTL8367C_DSCP15_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP14_DSCP_OFFSET 0 ++#define RTL8367C_DSCP14_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL8 0x09E8 ++#define RTL8367C_DSCP17_DSCP_OFFSET 8 ++#define RTL8367C_DSCP17_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP16_DSCP_OFFSET 0 ++#define RTL8367C_DSCP16_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL9 0x09E9 ++#define RTL8367C_DSCP19_DSCP_OFFSET 8 ++#define RTL8367C_DSCP19_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP18_DSCP_OFFSET 0 ++#define RTL8367C_DSCP18_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL10 0x09EA ++#define RTL8367C_DSCP21_DSCP_OFFSET 8 ++#define RTL8367C_DSCP21_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP20_DSCP_OFFSET 0 ++#define RTL8367C_DSCP20_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL11 0x09EB ++#define RTL8367C_DSCP23_DSCP_OFFSET 8 ++#define RTL8367C_DSCP23_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP22_DSCP_OFFSET 0 ++#define RTL8367C_DSCP22_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL12 0x09EC ++#define RTL8367C_DSCP25_DSCP_OFFSET 8 ++#define RTL8367C_DSCP25_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP24_DSCP_OFFSET 0 ++#define RTL8367C_DSCP24_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL13 0x09ED ++#define RTL8367C_DSCP27_DSCP_OFFSET 8 ++#define RTL8367C_DSCP27_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP26_DSCP_OFFSET 0 ++#define RTL8367C_DSCP26_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL14 0x09EE ++#define RTL8367C_DSCP29_DSCP_OFFSET 8 ++#define RTL8367C_DSCP29_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP28_DSCP_OFFSET 0 ++#define RTL8367C_DSCP28_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL15 0x09EF ++#define RTL8367C_DSCP31_DSCP_OFFSET 8 ++#define RTL8367C_DSCP31_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP30_DSCP_OFFSET 0 ++#define RTL8367C_DSCP30_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL16 0x09F0 ++#define RTL8367C_DSCP33_DSCP_OFFSET 8 ++#define RTL8367C_DSCP33_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP32_DSCP_OFFSET 0 ++#define RTL8367C_DSCP32_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL17 0x09F1 ++#define RTL8367C_DSCP35_DSCP_OFFSET 8 ++#define RTL8367C_DSCP35_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP34_DSCP_OFFSET 0 ++#define RTL8367C_DSCP34_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL18 0x09F2 ++#define RTL8367C_DSCP37_DSCP_OFFSET 8 ++#define RTL8367C_DSCP37_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP36_DSCP_OFFSET 0 ++#define RTL8367C_DSCP36_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL19 0x09F3 ++#define RTL8367C_DSCP39_DSCP_OFFSET 8 ++#define RTL8367C_DSCP39_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP38_DSCP_OFFSET 0 ++#define RTL8367C_DSCP38_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL20 0x09F4 ++#define RTL8367C_DSCP41_DSCP_OFFSET 8 ++#define RTL8367C_DSCP41_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP40_DSCP_OFFSET 0 ++#define RTL8367C_DSCP40_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL21 0x09F5 ++#define RTL8367C_DSCP43_DSCP_OFFSET 8 ++#define RTL8367C_DSCP43_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP42_DSCP_OFFSET 0 ++#define RTL8367C_DSCP42_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL22 0x09F6 ++#define RTL8367C_DSCP45_DSCP_OFFSET 8 ++#define RTL8367C_DSCP45_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP44_DSCP_OFFSET 0 ++#define RTL8367C_DSCP44_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL23 0x09F7 ++#define RTL8367C_DSCP47_DSCP_OFFSET 8 ++#define RTL8367C_DSCP47_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP46_DSCP_OFFSET 0 ++#define RTL8367C_DSCP46_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL24 0x09F8 ++#define RTL8367C_DSCP49_DSCP_OFFSET 8 ++#define RTL8367C_DSCP49_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP48_DSCP_OFFSET 0 ++#define RTL8367C_DSCP48_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL25 0x09F9 ++#define RTL8367C_DSCP51_DSCP_OFFSET 8 ++#define RTL8367C_DSCP51_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP50_DSCP_OFFSET 0 ++#define RTL8367C_DSCP50_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL26 0x09FA ++#define RTL8367C_DSCP53_DSCP_OFFSET 8 ++#define RTL8367C_DSCP53_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP52_DSCP_OFFSET 0 ++#define RTL8367C_DSCP52_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL27 0x09FB ++#define RTL8367C_DSCP55_DSCP_OFFSET 8 ++#define RTL8367C_DSCP55_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP54_DSCP_OFFSET 0 ++#define RTL8367C_DSCP54_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL28 0x09FC ++#define RTL8367C_DSCP57_DSCP_OFFSET 8 ++#define RTL8367C_DSCP57_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP56_DSCP_OFFSET 0 ++#define RTL8367C_DSCP56_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL29 0x09FD ++#define RTL8367C_DSCP59_DSCP_OFFSET 8 ++#define RTL8367C_DSCP59_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP58_DSCP_OFFSET 0 ++#define RTL8367C_DSCP58_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL30 0x09FE ++#define RTL8367C_DSCP61_DSCP_OFFSET 8 ++#define RTL8367C_DSCP61_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP60_DSCP_OFFSET 0 ++#define RTL8367C_DSCP60_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_DSCP_CTRL31 0x09FF ++#define RTL8367C_DSCP63_DSCP_OFFSET 8 ++#define RTL8367C_DSCP63_DSCP_MASK 0x3F00 ++#define RTL8367C_DSCP62_DSCP_OFFSET 0 ++#define RTL8367C_DSCP62_DSCP_MASK 0x3F ++ ++/* (16'h0a00)l2_reg */ ++ ++#define RTL8367C_REG_VLAN_MSTI0_CTRL0 0x0a00 ++#define RTL8367C_VLAN_MSTI0_CTRL0_PORT7_STATE_OFFSET 14 ++#define RTL8367C_VLAN_MSTI0_CTRL0_PORT7_STATE_MASK 0xC000 ++#define RTL8367C_VLAN_MSTI0_CTRL0_PORT6_STATE_OFFSET 12 ++#define RTL8367C_VLAN_MSTI0_CTRL0_PORT6_STATE_MASK 0x3000 ++#define RTL8367C_VLAN_MSTI0_CTRL0_PORT5_STATE_OFFSET 10 ++#define RTL8367C_VLAN_MSTI0_CTRL0_PORT5_STATE_MASK 0xC00 ++#define RTL8367C_VLAN_MSTI0_CTRL0_PORT4_STATE_OFFSET 8 ++#define RTL8367C_VLAN_MSTI0_CTRL0_PORT4_STATE_MASK 0x300 ++#define RTL8367C_VLAN_MSTI0_CTRL0_PORT3_STATE_OFFSET 6 ++#define RTL8367C_VLAN_MSTI0_CTRL0_PORT3_STATE_MASK 0xC0 ++#define RTL8367C_VLAN_MSTI0_CTRL0_PORT2_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI0_CTRL0_PORT2_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI0_CTRL0_PORT1_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI0_CTRL0_PORT1_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI0_CTRL0_PORT0_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI0_CTRL0_PORT0_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI0_CTRL1 0x0a01 ++#define RTL8367C_VLAN_MSTI0_CTRL1_PORT10_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI0_CTRL1_PORT10_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI0_CTRL1_PORT9_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI0_CTRL1_PORT9_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI0_CTRL1_PORT8_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI0_CTRL1_PORT8_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI1_CTRL0 0x0a02 ++#define RTL8367C_VLAN_MSTI1_CTRL0_PORT7_STATE_OFFSET 14 ++#define RTL8367C_VLAN_MSTI1_CTRL0_PORT7_STATE_MASK 0xC000 ++#define RTL8367C_VLAN_MSTI1_CTRL0_PORT6_STATE_OFFSET 12 ++#define RTL8367C_VLAN_MSTI1_CTRL0_PORT6_STATE_MASK 0x3000 ++#define RTL8367C_VLAN_MSTI1_CTRL0_PORT5_STATE_OFFSET 10 ++#define RTL8367C_VLAN_MSTI1_CTRL0_PORT5_STATE_MASK 0xC00 ++#define RTL8367C_VLAN_MSTI1_CTRL0_PORT4_STATE_OFFSET 8 ++#define RTL8367C_VLAN_MSTI1_CTRL0_PORT4_STATE_MASK 0x300 ++#define RTL8367C_VLAN_MSTI1_CTRL0_PORT3_STATE_OFFSET 6 ++#define RTL8367C_VLAN_MSTI1_CTRL0_PORT3_STATE_MASK 0xC0 ++#define RTL8367C_VLAN_MSTI1_CTRL0_PORT2_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI1_CTRL0_PORT2_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI1_CTRL0_PORT1_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI1_CTRL0_PORT1_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI1_CTRL0_PORT0_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI1_CTRL0_PORT0_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI1_CTRL1 0x0a03 ++#define RTL8367C_VLAN_MSTI1_CTRL1_PORT10_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI1_CTRL1_PORT10_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI1_CTRL1_PORT9_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI1_CTRL1_PORT9_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI1_CTRL1_PORT8_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI1_CTRL1_PORT8_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI2_CTRL0 0x0a04 ++#define RTL8367C_VLAN_MSTI2_CTRL0_PORT7_STATE_OFFSET 14 ++#define RTL8367C_VLAN_MSTI2_CTRL0_PORT7_STATE_MASK 0xC000 ++#define RTL8367C_VLAN_MSTI2_CTRL0_PORT6_STATE_OFFSET 12 ++#define RTL8367C_VLAN_MSTI2_CTRL0_PORT6_STATE_MASK 0x3000 ++#define RTL8367C_VLAN_MSTI2_CTRL0_PORT5_STATE_OFFSET 10 ++#define RTL8367C_VLAN_MSTI2_CTRL0_PORT5_STATE_MASK 0xC00 ++#define RTL8367C_VLAN_MSTI2_CTRL0_PORT4_STATE_OFFSET 8 ++#define RTL8367C_VLAN_MSTI2_CTRL0_PORT4_STATE_MASK 0x300 ++#define RTL8367C_VLAN_MSTI2_CTRL0_PORT3_STATE_OFFSET 6 ++#define RTL8367C_VLAN_MSTI2_CTRL0_PORT3_STATE_MASK 0xC0 ++#define RTL8367C_VLAN_MSTI2_CTRL0_PORT2_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI2_CTRL0_PORT2_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI2_CTRL0_PORT1_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI2_CTRL0_PORT1_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI2_CTRL0_PORT0_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI2_CTRL0_PORT0_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI2_CTRL1 0x0a05 ++#define RTL8367C_VLAN_MSTI2_CTRL1_PORT10_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI2_CTRL1_PORT10_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI2_CTRL1_PORT9_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI2_CTRL1_PORT9_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI2_CTRL1_PORT8_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI2_CTRL1_PORT8_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI3_CTRL0 0x0a06 ++#define RTL8367C_VLAN_MSTI3_CTRL0_PORT7_STATE_OFFSET 14 ++#define RTL8367C_VLAN_MSTI3_CTRL0_PORT7_STATE_MASK 0xC000 ++#define RTL8367C_VLAN_MSTI3_CTRL0_PORT6_STATE_OFFSET 12 ++#define RTL8367C_VLAN_MSTI3_CTRL0_PORT6_STATE_MASK 0x3000 ++#define RTL8367C_VLAN_MSTI3_CTRL0_PORT5_STATE_OFFSET 10 ++#define RTL8367C_VLAN_MSTI3_CTRL0_PORT5_STATE_MASK 0xC00 ++#define RTL8367C_VLAN_MSTI3_CTRL0_PORT4_STATE_OFFSET 8 ++#define RTL8367C_VLAN_MSTI3_CTRL0_PORT4_STATE_MASK 0x300 ++#define RTL8367C_VLAN_MSTI3_CTRL0_PORT3_STATE_OFFSET 6 ++#define RTL8367C_VLAN_MSTI3_CTRL0_PORT3_STATE_MASK 0xC0 ++#define RTL8367C_VLAN_MSTI3_CTRL0_PORT2_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI3_CTRL0_PORT2_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI3_CTRL0_PORT1_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI3_CTRL0_PORT1_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI3_CTRL0_PORT0_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI3_CTRL0_PORT0_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI3_CTRL1 0x0a07 ++#define RTL8367C_VLAN_MSTI3_CTRL1_PORT10_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI3_CTRL1_PORT10_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI3_CTRL1_PORT9_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI3_CTRL1_PORT9_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI3_CTRL1_PORT8_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI3_CTRL1_PORT8_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI4_CTRL0 0x0a08 ++#define RTL8367C_VLAN_MSTI4_CTRL0_PORT7_STATE_OFFSET 14 ++#define RTL8367C_VLAN_MSTI4_CTRL0_PORT7_STATE_MASK 0xC000 ++#define RTL8367C_VLAN_MSTI4_CTRL0_PORT6_STATE_OFFSET 12 ++#define RTL8367C_VLAN_MSTI4_CTRL0_PORT6_STATE_MASK 0x3000 ++#define RTL8367C_VLAN_MSTI4_CTRL0_PORT5_STATE_OFFSET 10 ++#define RTL8367C_VLAN_MSTI4_CTRL0_PORT5_STATE_MASK 0xC00 ++#define RTL8367C_VLAN_MSTI4_CTRL0_PORT4_STATE_OFFSET 8 ++#define RTL8367C_VLAN_MSTI4_CTRL0_PORT4_STATE_MASK 0x300 ++#define RTL8367C_VLAN_MSTI4_CTRL0_PORT3_STATE_OFFSET 6 ++#define RTL8367C_VLAN_MSTI4_CTRL0_PORT3_STATE_MASK 0xC0 ++#define RTL8367C_VLAN_MSTI4_CTRL0_PORT2_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI4_CTRL0_PORT2_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI4_CTRL0_PORT1_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI4_CTRL0_PORT1_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI4_CTRL0_PORT0_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI4_CTRL0_PORT0_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI4_CTRL1 0x0a09 ++#define RTL8367C_VLAN_MSTI4_CTRL1_PORT10_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI4_CTRL1_PORT10_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI4_CTRL1_PORT9_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI4_CTRL1_PORT9_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI4_CTRL1_PORT8_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI4_CTRL1_PORT8_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI5_CTRL0 0x0a0a ++#define RTL8367C_VLAN_MSTI5_CTRL0_PORT7_STATE_OFFSET 14 ++#define RTL8367C_VLAN_MSTI5_CTRL0_PORT7_STATE_MASK 0xC000 ++#define RTL8367C_VLAN_MSTI5_CTRL0_PORT6_STATE_OFFSET 12 ++#define RTL8367C_VLAN_MSTI5_CTRL0_PORT6_STATE_MASK 0x3000 ++#define RTL8367C_VLAN_MSTI5_CTRL0_PORT5_STATE_OFFSET 10 ++#define RTL8367C_VLAN_MSTI5_CTRL0_PORT5_STATE_MASK 0xC00 ++#define RTL8367C_VLAN_MSTI5_CTRL0_PORT4_STATE_OFFSET 8 ++#define RTL8367C_VLAN_MSTI5_CTRL0_PORT4_STATE_MASK 0x300 ++#define RTL8367C_VLAN_MSTI5_CTRL0_PORT3_STATE_OFFSET 6 ++#define RTL8367C_VLAN_MSTI5_CTRL0_PORT3_STATE_MASK 0xC0 ++#define RTL8367C_VLAN_MSTI5_CTRL0_PORT2_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI5_CTRL0_PORT2_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI5_CTRL0_PORT1_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI5_CTRL0_PORT1_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI5_CTRL0_PORT0_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI5_CTRL0_PORT0_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI5_CTRL1 0x0a0b ++#define RTL8367C_VLAN_MSTI5_CTRL1_PORT10_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI5_CTRL1_PORT10_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI5_CTRL1_PORT9_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI5_CTRL1_PORT9_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI5_CTRL1_PORT8_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI5_CTRL1_PORT8_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI6_CTRL0 0x0a0c ++#define RTL8367C_VLAN_MSTI6_CTRL0_PORT7_STATE_OFFSET 14 ++#define RTL8367C_VLAN_MSTI6_CTRL0_PORT7_STATE_MASK 0xC000 ++#define RTL8367C_VLAN_MSTI6_CTRL0_PORT6_STATE_OFFSET 12 ++#define RTL8367C_VLAN_MSTI6_CTRL0_PORT6_STATE_MASK 0x3000 ++#define RTL8367C_VLAN_MSTI6_CTRL0_PORT5_STATE_OFFSET 10 ++#define RTL8367C_VLAN_MSTI6_CTRL0_PORT5_STATE_MASK 0xC00 ++#define RTL8367C_VLAN_MSTI6_CTRL0_PORT4_STATE_OFFSET 8 ++#define RTL8367C_VLAN_MSTI6_CTRL0_PORT4_STATE_MASK 0x300 ++#define RTL8367C_VLAN_MSTI6_CTRL0_PORT3_STATE_OFFSET 6 ++#define RTL8367C_VLAN_MSTI6_CTRL0_PORT3_STATE_MASK 0xC0 ++#define RTL8367C_VLAN_MSTI6_CTRL0_PORT2_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI6_CTRL0_PORT2_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI6_CTRL0_PORT1_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI6_CTRL0_PORT1_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI6_CTRL0_PORT0_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI6_CTRL0_PORT0_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI6_CTRL1 0x0a0d ++#define RTL8367C_VLAN_MSTI6_CTRL1_PORT10_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI6_CTRL1_PORT10_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI6_CTRL1_PORT9_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI6_CTRL1_PORT9_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI6_CTRL1_PORT8_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI6_CTRL1_PORT8_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI7_CTRL0 0x0a0e ++#define RTL8367C_VLAN_MSTI7_CTRL0_PORT7_STATE_OFFSET 14 ++#define RTL8367C_VLAN_MSTI7_CTRL0_PORT7_STATE_MASK 0xC000 ++#define RTL8367C_VLAN_MSTI7_CTRL0_PORT6_STATE_OFFSET 12 ++#define RTL8367C_VLAN_MSTI7_CTRL0_PORT6_STATE_MASK 0x3000 ++#define RTL8367C_VLAN_MSTI7_CTRL0_PORT5_STATE_OFFSET 10 ++#define RTL8367C_VLAN_MSTI7_CTRL0_PORT5_STATE_MASK 0xC00 ++#define RTL8367C_VLAN_MSTI7_CTRL0_PORT4_STATE_OFFSET 8 ++#define RTL8367C_VLAN_MSTI7_CTRL0_PORT4_STATE_MASK 0x300 ++#define RTL8367C_VLAN_MSTI7_CTRL0_PORT3_STATE_OFFSET 6 ++#define RTL8367C_VLAN_MSTI7_CTRL0_PORT3_STATE_MASK 0xC0 ++#define RTL8367C_VLAN_MSTI7_CTRL0_PORT2_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI7_CTRL0_PORT2_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI7_CTRL0_PORT1_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI7_CTRL0_PORT1_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI7_CTRL0_PORT0_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI7_CTRL0_PORT0_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI7_CTRL1 0x0a0f ++#define RTL8367C_VLAN_MSTI7_CTRL1_PORT10_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI7_CTRL1_PORT10_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI7_CTRL1_PORT9_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI7_CTRL1_PORT9_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI7_CTRL1_PORT8_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI7_CTRL1_PORT8_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI8_CTRL0 0x0a10 ++#define RTL8367C_VLAN_MSTI8_CTRL0_PORT7_STATE_OFFSET 14 ++#define RTL8367C_VLAN_MSTI8_CTRL0_PORT7_STATE_MASK 0xC000 ++#define RTL8367C_VLAN_MSTI8_CTRL0_PORT6_STATE_OFFSET 12 ++#define RTL8367C_VLAN_MSTI8_CTRL0_PORT6_STATE_MASK 0x3000 ++#define RTL8367C_VLAN_MSTI8_CTRL0_PORT5_STATE_OFFSET 10 ++#define RTL8367C_VLAN_MSTI8_CTRL0_PORT5_STATE_MASK 0xC00 ++#define RTL8367C_VLAN_MSTI8_CTRL0_PORT4_STATE_OFFSET 8 ++#define RTL8367C_VLAN_MSTI8_CTRL0_PORT4_STATE_MASK 0x300 ++#define RTL8367C_VLAN_MSTI8_CTRL0_PORT3_STATE_OFFSET 6 ++#define RTL8367C_VLAN_MSTI8_CTRL0_PORT3_STATE_MASK 0xC0 ++#define RTL8367C_VLAN_MSTI8_CTRL0_PORT2_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI8_CTRL0_PORT2_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI8_CTRL0_PORT1_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI8_CTRL0_PORT1_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI8_CTRL0_PORT0_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI8_CTRL0_PORT0_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI8_CTRL1 0x0a11 ++#define RTL8367C_VLAN_MSTI8_CTRL1_PORT10_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI8_CTRL1_PORT10_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI8_CTRL1_PORT9_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI8_CTRL1_PORT9_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI8_CTRL1_PORT8_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI8_CTRL1_PORT8_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI9_CTRL0 0x0a12 ++#define RTL8367C_VLAN_MSTI9_CTRL0_PORT7_STATE_OFFSET 14 ++#define RTL8367C_VLAN_MSTI9_CTRL0_PORT7_STATE_MASK 0xC000 ++#define RTL8367C_VLAN_MSTI9_CTRL0_PORT6_STATE_OFFSET 12 ++#define RTL8367C_VLAN_MSTI9_CTRL0_PORT6_STATE_MASK 0x3000 ++#define RTL8367C_VLAN_MSTI9_CTRL0_PORT5_STATE_OFFSET 10 ++#define RTL8367C_VLAN_MSTI9_CTRL0_PORT5_STATE_MASK 0xC00 ++#define RTL8367C_VLAN_MSTI9_CTRL0_PORT4_STATE_OFFSET 8 ++#define RTL8367C_VLAN_MSTI9_CTRL0_PORT4_STATE_MASK 0x300 ++#define RTL8367C_VLAN_MSTI9_CTRL0_PORT3_STATE_OFFSET 6 ++#define RTL8367C_VLAN_MSTI9_CTRL0_PORT3_STATE_MASK 0xC0 ++#define RTL8367C_VLAN_MSTI9_CTRL0_PORT2_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI9_CTRL0_PORT2_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI9_CTRL0_PORT1_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI9_CTRL0_PORT1_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI9_CTRL0_PORT0_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI9_CTRL0_PORT0_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI9_CTRL1 0x0a13 ++#define RTL8367C_VLAN_MSTI9_CTRL1_PORT10_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI9_CTRL1_PORT10_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI9_CTRL1_PORT9_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI9_CTRL1_PORT9_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI9_CTRL1_PORT8_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI9_CTRL1_PORT8_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI10_CTRL0 0x0a14 ++#define RTL8367C_VLAN_MSTI10_CTRL0_PORT7_STATE_OFFSET 14 ++#define RTL8367C_VLAN_MSTI10_CTRL0_PORT7_STATE_MASK 0xC000 ++#define RTL8367C_VLAN_MSTI10_CTRL0_PORT6_STATE_OFFSET 12 ++#define RTL8367C_VLAN_MSTI10_CTRL0_PORT6_STATE_MASK 0x3000 ++#define RTL8367C_VLAN_MSTI10_CTRL0_PORT5_STATE_OFFSET 10 ++#define RTL8367C_VLAN_MSTI10_CTRL0_PORT5_STATE_MASK 0xC00 ++#define RTL8367C_VLAN_MSTI10_CTRL0_PORT4_STATE_OFFSET 8 ++#define RTL8367C_VLAN_MSTI10_CTRL0_PORT4_STATE_MASK 0x300 ++#define RTL8367C_VLAN_MSTI10_CTRL0_PORT3_STATE_OFFSET 6 ++#define RTL8367C_VLAN_MSTI10_CTRL0_PORT3_STATE_MASK 0xC0 ++#define RTL8367C_VLAN_MSTI10_CTRL0_PORT2_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI10_CTRL0_PORT2_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI10_CTRL0_PORT1_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI10_CTRL0_PORT1_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI10_CTRL0_PORT0_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI10_CTRL0_PORT0_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI10_CTRL1 0x0a15 ++#define RTL8367C_VLAN_MSTI10_CTRL1_PORT10_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI10_CTRL1_PORT10_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI10_CTRL1_PORT9_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI10_CTRL1_PORT9_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI10_CTRL1_PORT8_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI10_CTRL1_PORT8_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI11_CTRL0 0x0a16 ++#define RTL8367C_VLAN_MSTI11_CTRL0_PORT7_STATE_OFFSET 14 ++#define RTL8367C_VLAN_MSTI11_CTRL0_PORT7_STATE_MASK 0xC000 ++#define RTL8367C_VLAN_MSTI11_CTRL0_PORT6_STATE_OFFSET 12 ++#define RTL8367C_VLAN_MSTI11_CTRL0_PORT6_STATE_MASK 0x3000 ++#define RTL8367C_VLAN_MSTI11_CTRL0_PORT5_STATE_OFFSET 10 ++#define RTL8367C_VLAN_MSTI11_CTRL0_PORT5_STATE_MASK 0xC00 ++#define RTL8367C_VLAN_MSTI11_CTRL0_PORT4_STATE_OFFSET 8 ++#define RTL8367C_VLAN_MSTI11_CTRL0_PORT4_STATE_MASK 0x300 ++#define RTL8367C_VLAN_MSTI11_CTRL0_PORT3_STATE_OFFSET 6 ++#define RTL8367C_VLAN_MSTI11_CTRL0_PORT3_STATE_MASK 0xC0 ++#define RTL8367C_VLAN_MSTI11_CTRL0_PORT2_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI11_CTRL0_PORT2_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI11_CTRL0_PORT1_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI11_CTRL0_PORT1_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI11_CTRL0_PORT0_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI11_CTRL0_PORT0_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI11_CTRL1 0x0a17 ++#define RTL8367C_VLAN_MSTI11_CTRL1_PORT10_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI11_CTRL1_PORT10_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI11_CTRL1_PORT9_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI11_CTRL1_PORT9_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI11_CTRL1_PORT8_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI11_CTRL1_PORT8_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI12_CTRL0 0x0a18 ++#define RTL8367C_VLAN_MSTI12_CTRL0_PORT7_STATE_OFFSET 14 ++#define RTL8367C_VLAN_MSTI12_CTRL0_PORT7_STATE_MASK 0xC000 ++#define RTL8367C_VLAN_MSTI12_CTRL0_PORT6_STATE_OFFSET 12 ++#define RTL8367C_VLAN_MSTI12_CTRL0_PORT6_STATE_MASK 0x3000 ++#define RTL8367C_VLAN_MSTI12_CTRL0_PORT5_STATE_OFFSET 10 ++#define RTL8367C_VLAN_MSTI12_CTRL0_PORT5_STATE_MASK 0xC00 ++#define RTL8367C_VLAN_MSTI12_CTRL0_PORT4_STATE_OFFSET 8 ++#define RTL8367C_VLAN_MSTI12_CTRL0_PORT4_STATE_MASK 0x300 ++#define RTL8367C_VLAN_MSTI12_CTRL0_PORT3_STATE_OFFSET 6 ++#define RTL8367C_VLAN_MSTI12_CTRL0_PORT3_STATE_MASK 0xC0 ++#define RTL8367C_VLAN_MSTI12_CTRL0_PORT2_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI12_CTRL0_PORT2_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI12_CTRL0_PORT1_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI12_CTRL0_PORT1_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI12_CTRL0_PORT0_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI12_CTRL0_PORT0_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI12_CTRL1 0x0a19 ++#define RTL8367C_VLAN_MSTI12_CTRL1_PORT10_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI12_CTRL1_PORT10_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI12_CTRL1_PORT9_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI12_CTRL1_PORT9_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI12_CTRL1_PORT8_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI12_CTRL1_PORT8_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI13_CTRL0 0x0a1a ++#define RTL8367C_VLAN_MSTI13_CTRL0_PORT7_STATE_OFFSET 14 ++#define RTL8367C_VLAN_MSTI13_CTRL0_PORT7_STATE_MASK 0xC000 ++#define RTL8367C_VLAN_MSTI13_CTRL0_PORT6_STATE_OFFSET 12 ++#define RTL8367C_VLAN_MSTI13_CTRL0_PORT6_STATE_MASK 0x3000 ++#define RTL8367C_VLAN_MSTI13_CTRL0_PORT5_STATE_OFFSET 10 ++#define RTL8367C_VLAN_MSTI13_CTRL0_PORT5_STATE_MASK 0xC00 ++#define RTL8367C_VLAN_MSTI13_CTRL0_PORT4_STATE_OFFSET 8 ++#define RTL8367C_VLAN_MSTI13_CTRL0_PORT4_STATE_MASK 0x300 ++#define RTL8367C_VLAN_MSTI13_CTRL0_PORT3_STATE_OFFSET 6 ++#define RTL8367C_VLAN_MSTI13_CTRL0_PORT3_STATE_MASK 0xC0 ++#define RTL8367C_VLAN_MSTI13_CTRL0_PORT2_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI13_CTRL0_PORT2_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI13_CTRL0_PORT1_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI13_CTRL0_PORT1_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI13_CTRL0_PORT0_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI13_CTRL0_PORT0_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI13_CTRL1 0x0a1b ++#define RTL8367C_VLAN_MSTI13_CTRL1_PORT10_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI13_CTRL1_PORT10_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI13_CTRL1_PORT9_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI13_CTRL1_PORT9_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI13_CTRL1_PORT8_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI13_CTRL1_PORT8_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI14_CTRL0 0x0a1c ++#define RTL8367C_VLAN_MSTI14_CTRL0_PORT7_STATE_OFFSET 14 ++#define RTL8367C_VLAN_MSTI14_CTRL0_PORT7_STATE_MASK 0xC000 ++#define RTL8367C_VLAN_MSTI14_CTRL0_PORT6_STATE_OFFSET 12 ++#define RTL8367C_VLAN_MSTI14_CTRL0_PORT6_STATE_MASK 0x3000 ++#define RTL8367C_VLAN_MSTI14_CTRL0_PORT5_STATE_OFFSET 10 ++#define RTL8367C_VLAN_MSTI14_CTRL0_PORT5_STATE_MASK 0xC00 ++#define RTL8367C_VLAN_MSTI14_CTRL0_PORT4_STATE_OFFSET 8 ++#define RTL8367C_VLAN_MSTI14_CTRL0_PORT4_STATE_MASK 0x300 ++#define RTL8367C_VLAN_MSTI14_CTRL0_PORT3_STATE_OFFSET 6 ++#define RTL8367C_VLAN_MSTI14_CTRL0_PORT3_STATE_MASK 0xC0 ++#define RTL8367C_VLAN_MSTI14_CTRL0_PORT2_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI14_CTRL0_PORT2_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI14_CTRL0_PORT1_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI14_CTRL0_PORT1_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI14_CTRL0_PORT0_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI14_CTRL0_PORT0_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI14_CTRL1 0x0a1d ++#define RTL8367C_VLAN_MSTI14_CTRL1_PORT10_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI14_CTRL1_PORT10_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI14_CTRL1_PORT9_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI14_CTRL1_PORT9_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI14_CTRL1_PORT8_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI14_CTRL1_PORT8_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI15_CTRL0 0x0a1e ++#define RTL8367C_VLAN_MSTI15_CTRL0_PORT7_STATE_OFFSET 14 ++#define RTL8367C_VLAN_MSTI15_CTRL0_PORT7_STATE_MASK 0xC000 ++#define RTL8367C_VLAN_MSTI15_CTRL0_PORT6_STATE_OFFSET 12 ++#define RTL8367C_VLAN_MSTI15_CTRL0_PORT6_STATE_MASK 0x3000 ++#define RTL8367C_VLAN_MSTI15_CTRL0_PORT5_STATE_OFFSET 10 ++#define RTL8367C_VLAN_MSTI15_CTRL0_PORT5_STATE_MASK 0xC00 ++#define RTL8367C_VLAN_MSTI15_CTRL0_PORT4_STATE_OFFSET 8 ++#define RTL8367C_VLAN_MSTI15_CTRL0_PORT4_STATE_MASK 0x300 ++#define RTL8367C_VLAN_MSTI15_CTRL0_PORT3_STATE_OFFSET 6 ++#define RTL8367C_VLAN_MSTI15_CTRL0_PORT3_STATE_MASK 0xC0 ++#define RTL8367C_VLAN_MSTI15_CTRL0_PORT2_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI15_CTRL0_PORT2_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI15_CTRL0_PORT1_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI15_CTRL0_PORT1_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI15_CTRL0_PORT0_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI15_CTRL0_PORT0_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_VLAN_MSTI15_CTRL1 0x0a1f ++#define RTL8367C_VLAN_MSTI15_CTRL1_PORT10_STATE_OFFSET 4 ++#define RTL8367C_VLAN_MSTI15_CTRL1_PORT10_STATE_MASK 0x30 ++#define RTL8367C_VLAN_MSTI15_CTRL1_PORT9_STATE_OFFSET 2 ++#define RTL8367C_VLAN_MSTI15_CTRL1_PORT9_STATE_MASK 0xC ++#define RTL8367C_VLAN_MSTI15_CTRL1_PORT8_STATE_OFFSET 0 ++#define RTL8367C_VLAN_MSTI15_CTRL1_PORT8_STATE_MASK 0x3 ++ ++#define RTL8367C_REG_LUT_PORT0_LEARN_LIMITNO 0x0a20 ++#define RTL8367C_LUT_PORT0_LEARN_LIMITNO_OFFSET 0 ++#define RTL8367C_LUT_PORT0_LEARN_LIMITNO_MASK 0x1FFF ++ ++#define RTL8367C_REG_LUT_PORT1_LEARN_LIMITNO 0x0a21 ++#define RTL8367C_LUT_PORT1_LEARN_LIMITNO_OFFSET 0 ++#define RTL8367C_LUT_PORT1_LEARN_LIMITNO_MASK 0x1FFF ++ ++#define RTL8367C_REG_LUT_PORT2_LEARN_LIMITNO 0x0a22 ++#define RTL8367C_LUT_PORT2_LEARN_LIMITNO_OFFSET 0 ++#define RTL8367C_LUT_PORT2_LEARN_LIMITNO_MASK 0x1FFF ++ ++#define RTL8367C_REG_LUT_PORT3_LEARN_LIMITNO 0x0a23 ++#define RTL8367C_LUT_PORT3_LEARN_LIMITNO_OFFSET 0 ++#define RTL8367C_LUT_PORT3_LEARN_LIMITNO_MASK 0x1FFF ++ ++#define RTL8367C_REG_LUT_PORT4_LEARN_LIMITNO 0x0a24 ++#define RTL8367C_LUT_PORT4_LEARN_LIMITNO_OFFSET 0 ++#define RTL8367C_LUT_PORT4_LEARN_LIMITNO_MASK 0x1FFF ++ ++#define RTL8367C_REG_LUT_PORT5_LEARN_LIMITNO 0x0a25 ++#define RTL8367C_LUT_PORT5_LEARN_LIMITNO_OFFSET 0 ++#define RTL8367C_LUT_PORT5_LEARN_LIMITNO_MASK 0x1FFF ++ ++#define RTL8367C_REG_LUT_PORT6_LEARN_LIMITNO 0x0a26 ++#define RTL8367C_LUT_PORT6_LEARN_LIMITNO_OFFSET 0 ++#define RTL8367C_LUT_PORT6_LEARN_LIMITNO_MASK 0x1FFF ++ ++#define RTL8367C_REG_LUT_PORT7_LEARN_LIMITNO 0x0a27 ++#define RTL8367C_LUT_PORT7_LEARN_LIMITNO_OFFSET 0 ++#define RTL8367C_LUT_PORT7_LEARN_LIMITNO_MASK 0x1FFF ++ ++#define RTL8367C_REG_LUT_SYS_LEARN_LIMITNO 0x0a28 ++#define RTL8367C_LUT_SYS_LEARN_LIMITNO_OFFSET 0 ++#define RTL8367C_LUT_SYS_LEARN_LIMITNO_MASK 0x1FFF ++ ++#define RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL 0x0a29 ++#define RTL8367C_LUT_SYSTEM_LEARN_PMASK1_OFFSET 12 ++#define RTL8367C_LUT_SYSTEM_LEARN_PMASK1_MASK 0x7000 ++#define RTL8367C_LUT_SYSTEM_LEARN_OVER_ACT_OFFSET 10 ++#define RTL8367C_LUT_SYSTEM_LEARN_OVER_ACT_MASK 0xC00 ++#define RTL8367C_LUT_SYSTEM_LEARN_PMASK_OFFSET 0 ++#define RTL8367C_LUT_SYSTEM_LEARN_PMASK_MASK 0xFF ++ ++#define RTL8367C_REG_LUT_PORT8_LEARN_LIMITNO 0x0a2a ++#define RTL8367C_LUT_PORT8_LEARN_LIMITNO_OFFSET 0 ++#define RTL8367C_LUT_PORT8_LEARN_LIMITNO_MASK 0x1FFF ++ ++#define RTL8367C_REG_LUT_PORT9_LEARN_LIMITNO 0x0a2b ++#define RTL8367C_LUT_PORT9_LEARN_LIMITNO_OFFSET 0 ++#define RTL8367C_LUT_PORT9_LEARN_LIMITNO_MASK 0x1FFF ++ ++#define RTL8367C_REG_LUT_PORT10_LEARN_LIMITNO 0x0a2c ++#define RTL8367C_LUT_PORT10_LEARN_LIMITNO_OFFSET 0 ++#define RTL8367C_LUT_PORT10_LEARN_LIMITNO_MASK 0x1FFF ++ ++#define RTL8367C_REG_LUT_CFG 0x0a30 ++#define RTL8367C_AGE_SPEED_OFFSET 8 ++#define RTL8367C_AGE_SPEED_MASK 0x300 ++#define RTL8367C_BCAM_DISABLE_OFFSET 6 ++#define RTL8367C_BCAM_DISABLE_MASK 0x40 ++#define RTL8367C_LINKDOWN_AGEOUT_OFFSET 5 ++#define RTL8367C_LINKDOWN_AGEOUT_MASK 0x20 ++#define RTL8367C_LUT_IPMC_HASH_OFFSET 4 ++#define RTL8367C_LUT_IPMC_HASH_MASK 0x10 ++#define RTL8367C_LUT_IPMC_LOOKUP_OP_OFFSET 3 ++#define RTL8367C_LUT_IPMC_LOOKUP_OP_MASK 0x8 ++#define RTL8367C_AGE_TIMER_OFFSET 0 ++#define RTL8367C_AGE_TIMER_MASK 0x7 ++ ++#define RTL8367C_REG_LUT_AGEOUT_CTRL 0x0a31 ++#define RTL8367C_LUT_AGEOUT_CTRL_OFFSET 0 ++#define RTL8367C_LUT_AGEOUT_CTRL_MASK 0x7FF ++ ++#define RTL8367C_REG_PORT_EFID_CTRL0 0x0a32 ++#define RTL8367C_PORT3_EFID_OFFSET 12 ++#define RTL8367C_PORT3_EFID_MASK 0x7000 ++#define RTL8367C_PORT2_EFID_OFFSET 8 ++#define RTL8367C_PORT2_EFID_MASK 0x700 ++#define RTL8367C_PORT1_EFID_OFFSET 4 ++#define RTL8367C_PORT1_EFID_MASK 0x70 ++#define RTL8367C_PORT0_EFID_OFFSET 0 ++#define RTL8367C_PORT0_EFID_MASK 0x7 ++ ++#define RTL8367C_REG_PORT_EFID_CTRL1 0x0a33 ++#define RTL8367C_PORT7_EFID_OFFSET 12 ++#define RTL8367C_PORT7_EFID_MASK 0x7000 ++#define RTL8367C_PORT6_EFID_OFFSET 8 ++#define RTL8367C_PORT6_EFID_MASK 0x700 ++#define RTL8367C_PORT5_EFID_OFFSET 4 ++#define RTL8367C_PORT5_EFID_MASK 0x70 ++#define RTL8367C_PORT4_EFID_OFFSET 0 ++#define RTL8367C_PORT4_EFID_MASK 0x7 ++ ++#define RTL8367C_REG_PORT_EFID_CTRL2 0x0a34 ++#define RTL8367C_PORT10_EFID_OFFSET 8 ++#define RTL8367C_PORT10_EFID_MASK 0x700 ++#define RTL8367C_PORT9_EFID_OFFSET 4 ++#define RTL8367C_PORT9_EFID_MASK 0x70 ++#define RTL8367C_PORT8_EFID_OFFSET 0 ++#define RTL8367C_PORT8_EFID_MASK 0x7 ++ ++#define RTL8367C_REG_FORCE_FLUSH1 0x0a35 ++#define RTL8367C_BUSY_STATUS1_OFFSET 3 ++#define RTL8367C_BUSY_STATUS1_MASK 0x38 ++#define RTL8367C_PORTMASK1_OFFSET 0 ++#define RTL8367C_PORTMASK1_MASK 0x7 ++ ++#define RTL8367C_REG_FORCE_FLUSH 0x0a36 ++#define RTL8367C_BUSY_STATUS_OFFSET 8 ++#define RTL8367C_BUSY_STATUS_MASK 0xFF00 ++#define RTL8367C_FORCE_FLUSH_PORTMASK_OFFSET 0 ++#define RTL8367C_FORCE_FLUSH_PORTMASK_MASK 0xFF ++ ++#define RTL8367C_REG_L2_FLUSH_CTRL1 0x0a37 ++#define RTL8367C_LUT_FLUSH_FID_OFFSET 12 ++#define RTL8367C_LUT_FLUSH_FID_MASK 0xF000 ++#define RTL8367C_LUT_FLUSH_VID_OFFSET 0 ++#define RTL8367C_LUT_FLUSH_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_L2_FLUSH_CTRL2 0x0a38 ++#define RTL8367C_LUT_FLUSH_TYPE_OFFSET 2 ++#define RTL8367C_LUT_FLUSH_TYPE_MASK 0x4 ++#define RTL8367C_LUT_FLUSH_MODE_OFFSET 0 ++#define RTL8367C_LUT_FLUSH_MODE_MASK 0x3 ++ ++#define RTL8367C_REG_L2_FLUSH_CTRL3 0x0a39 ++#define RTL8367C_L2_FLUSH_CTRL3_OFFSET 0 ++#define RTL8367C_L2_FLUSH_CTRL3_MASK 0x1 ++ ++#define RTL8367C_REG_LUT_CFG2 0x0a3a ++#define RTL8367C_LUT_IPMC_FWD_RPORT_OFFSET 1 ++#define RTL8367C_LUT_IPMC_FWD_RPORT_MASK 0x2 ++#define RTL8367C_LUT_IPMC_VID_HASH_OFFSET 0 ++#define RTL8367C_LUT_IPMC_VID_HASH_MASK 0x1 ++ ++#define RTL8367C_REG_FLUSH_STATUS 0x0a3f ++#define RTL8367C_FLUSH_STATUS_OFFSET 0 ++#define RTL8367C_FLUSH_STATUS_MASK 0x1 ++ ++#define RTL8367C_REG_STORM_BCAST 0x0a40 ++#define RTL8367C_STORM_BCAST_OFFSET 0 ++#define RTL8367C_STORM_BCAST_MASK 0x7FF ++ ++#define RTL8367C_REG_STORM_MCAST 0x0a41 ++#define RTL8367C_STORM_MCAST_OFFSET 0 ++#define RTL8367C_STORM_MCAST_MASK 0x7FF ++ ++#define RTL8367C_REG_STORM_UNKOWN_UCAST 0x0a42 ++#define RTL8367C_STORM_UNKOWN_UCAST_OFFSET 0 ++#define RTL8367C_STORM_UNKOWN_UCAST_MASK 0x7FF ++ ++#define RTL8367C_REG_STORM_UNKOWN_MCAST 0x0a43 ++#define RTL8367C_STORM_UNKOWN_MCAST_OFFSET 0 ++#define RTL8367C_STORM_UNKOWN_MCAST_MASK 0x7FF ++ ++#define RTL8367C_REG_STORM_BCAST_METER_CTRL0 0x0a44 ++#define RTL8367C_STORM_BCAST_METER_CTRL0_PORT1_METERIDX_OFFSET 8 ++#define RTL8367C_STORM_BCAST_METER_CTRL0_PORT1_METERIDX_MASK 0x3F00 ++#define RTL8367C_STORM_BCAST_METER_CTRL0_PORT0_METERIDX_OFFSET 0 ++#define RTL8367C_STORM_BCAST_METER_CTRL0_PORT0_METERIDX_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_BCAST_METER_CTRL1 0x0a45 ++#define RTL8367C_STORM_BCAST_METER_CTRL1_PORT3_METERIDX_OFFSET 8 ++#define RTL8367C_STORM_BCAST_METER_CTRL1_PORT3_METERIDX_MASK 0x3F00 ++#define RTL8367C_STORM_BCAST_METER_CTRL1_PORT2_METERIDX_OFFSET 0 ++#define RTL8367C_STORM_BCAST_METER_CTRL1_PORT2_METERIDX_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_BCAST_METER_CTRL2 0x0a46 ++#define RTL8367C_STORM_BCAST_METER_CTRL2_PORT5_METERIDX_OFFSET 8 ++#define RTL8367C_STORM_BCAST_METER_CTRL2_PORT5_METERIDX_MASK 0x3F00 ++#define RTL8367C_STORM_BCAST_METER_CTRL2_PORT4_METERIDX_OFFSET 0 ++#define RTL8367C_STORM_BCAST_METER_CTRL2_PORT4_METERIDX_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_BCAST_METER_CTRL3 0x0a47 ++#define RTL8367C_STORM_BCAST_METER_CTRL3_PORT7_METERIDX_OFFSET 8 ++#define RTL8367C_STORM_BCAST_METER_CTRL3_PORT7_METERIDX_MASK 0x3F00 ++#define RTL8367C_STORM_BCAST_METER_CTRL3_PORT6_METERIDX_OFFSET 0 ++#define RTL8367C_STORM_BCAST_METER_CTRL3_PORT6_METERIDX_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_BCAST_METER_CTRL4 0x0a48 ++#define RTL8367C_STORM_BCAST_METER_CTRL4_PORT9_METERIDX_OFFSET 8 ++#define RTL8367C_STORM_BCAST_METER_CTRL4_PORT9_METERIDX_MASK 0x3F00 ++#define RTL8367C_STORM_BCAST_METER_CTRL4_PORT8_METERIDX_OFFSET 0 ++#define RTL8367C_STORM_BCAST_METER_CTRL4_PORT8_METERIDX_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_BCAST_METER_CTRL5 0x0a49 ++#define RTL8367C_STORM_BCAST_METER_CTRL5_OFFSET 0 ++#define RTL8367C_STORM_BCAST_METER_CTRL5_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_MCAST_METER_CTRL0 0x0a4c ++#define RTL8367C_STORM_MCAST_METER_CTRL0_PORT1_METERIDX_OFFSET 8 ++#define RTL8367C_STORM_MCAST_METER_CTRL0_PORT1_METERIDX_MASK 0x3F00 ++#define RTL8367C_STORM_MCAST_METER_CTRL0_PORT0_METERIDX_OFFSET 0 ++#define RTL8367C_STORM_MCAST_METER_CTRL0_PORT0_METERIDX_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_MCAST_METER_CTRL1 0x0a4d ++#define RTL8367C_STORM_MCAST_METER_CTRL1_PORT3_METERIDX_OFFSET 8 ++#define RTL8367C_STORM_MCAST_METER_CTRL1_PORT3_METERIDX_MASK 0x3F00 ++#define RTL8367C_STORM_MCAST_METER_CTRL1_PORT2_METERIDX_OFFSET 0 ++#define RTL8367C_STORM_MCAST_METER_CTRL1_PORT2_METERIDX_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_MCAST_METER_CTRL2 0x0a4e ++#define RTL8367C_STORM_MCAST_METER_CTRL2_PORT5_METERIDX_OFFSET 8 ++#define RTL8367C_STORM_MCAST_METER_CTRL2_PORT5_METERIDX_MASK 0x3F00 ++#define RTL8367C_STORM_MCAST_METER_CTRL2_PORT4_METERIDX_OFFSET 0 ++#define RTL8367C_STORM_MCAST_METER_CTRL2_PORT4_METERIDX_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_MCAST_METER_CTRL3 0x0a4f ++#define RTL8367C_STORM_MCAST_METER_CTRL3_PORT7_METERIDX_OFFSET 8 ++#define RTL8367C_STORM_MCAST_METER_CTRL3_PORT7_METERIDX_MASK 0x3F00 ++#define RTL8367C_STORM_MCAST_METER_CTRL3_PORT6_METERIDX_OFFSET 0 ++#define RTL8367C_STORM_MCAST_METER_CTRL3_PORT6_METERIDX_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_MCAST_METER_CTRL4 0x0a50 ++#define RTL8367C_STORM_MCAST_METER_CTRL4_PORT9_METERIDX_OFFSET 8 ++#define RTL8367C_STORM_MCAST_METER_CTRL4_PORT9_METERIDX_MASK 0x3F00 ++#define RTL8367C_STORM_MCAST_METER_CTRL4_PORT8_METERIDX_OFFSET 0 ++#define RTL8367C_STORM_MCAST_METER_CTRL4_PORT8_METERIDX_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_MCAST_METER_CTRL5 0x0a51 ++#define RTL8367C_STORM_MCAST_METER_CTRL5_OFFSET 0 ++#define RTL8367C_STORM_MCAST_METER_CTRL5_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_UNDA_METER_CTRL0 0x0a54 ++#define RTL8367C_STORM_UNDA_METER_CTRL0_PORT1_METERIDX_OFFSET 8 ++#define RTL8367C_STORM_UNDA_METER_CTRL0_PORT1_METERIDX_MASK 0x3F00 ++#define RTL8367C_STORM_UNDA_METER_CTRL0_PORT0_METERIDX_OFFSET 0 ++#define RTL8367C_STORM_UNDA_METER_CTRL0_PORT0_METERIDX_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_UNDA_METER_CTRL1 0x0a55 ++#define RTL8367C_STORM_UNDA_METER_CTRL1_PORT3_METERIDX_OFFSET 8 ++#define RTL8367C_STORM_UNDA_METER_CTRL1_PORT3_METERIDX_MASK 0x3F00 ++#define RTL8367C_STORM_UNDA_METER_CTRL1_PORT2_METERIDX_OFFSET 0 ++#define RTL8367C_STORM_UNDA_METER_CTRL1_PORT2_METERIDX_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_UNDA_METER_CTRL2 0x0a56 ++#define RTL8367C_STORM_UNDA_METER_CTRL2_PORT5_METERIDX_OFFSET 8 ++#define RTL8367C_STORM_UNDA_METER_CTRL2_PORT5_METERIDX_MASK 0x3F00 ++#define RTL8367C_STORM_UNDA_METER_CTRL2_PORT4_METERIDX_OFFSET 0 ++#define RTL8367C_STORM_UNDA_METER_CTRL2_PORT4_METERIDX_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_UNDA_METER_CTRL3 0x0a57 ++#define RTL8367C_STORM_UNDA_METER_CTRL3_PORT7_METERIDX_OFFSET 8 ++#define RTL8367C_STORM_UNDA_METER_CTRL3_PORT7_METERIDX_MASK 0x3F00 ++#define RTL8367C_STORM_UNDA_METER_CTRL3_PORT6_METERIDX_OFFSET 0 ++#define RTL8367C_STORM_UNDA_METER_CTRL3_PORT6_METERIDX_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_UNDA_METER_CTRL4 0x0a58 ++#define RTL8367C_STORM_UNDA_METER_CTRL4_PORT9_METERIDX_OFFSET 8 ++#define RTL8367C_STORM_UNDA_METER_CTRL4_PORT9_METERIDX_MASK 0x3F00 ++#define RTL8367C_STORM_UNDA_METER_CTRL4_PORT8_METERIDX_OFFSET 0 ++#define RTL8367C_STORM_UNDA_METER_CTRL4_PORT8_METERIDX_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_UNDA_METER_CTRL5 0x0a59 ++#define RTL8367C_STORM_UNDA_METER_CTRL5_OFFSET 0 ++#define RTL8367C_STORM_UNDA_METER_CTRL5_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_UNMC_METER_CTRL0 0x0a5c ++#define RTL8367C_STORM_UNMC_METER_CTRL0_PORT1_METERIDX_OFFSET 8 ++#define RTL8367C_STORM_UNMC_METER_CTRL0_PORT1_METERIDX_MASK 0x3F00 ++#define RTL8367C_STORM_UNMC_METER_CTRL0_PORT0_METERIDX_OFFSET 0 ++#define RTL8367C_STORM_UNMC_METER_CTRL0_PORT0_METERIDX_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_UNMC_METER_CTRL1 0x0a5d ++#define RTL8367C_STORM_UNMC_METER_CTRL1_PORT3_METERIDX_OFFSET 8 ++#define RTL8367C_STORM_UNMC_METER_CTRL1_PORT3_METERIDX_MASK 0x3F00 ++#define RTL8367C_STORM_UNMC_METER_CTRL1_PORT2_METERIDX_OFFSET 0 ++#define RTL8367C_STORM_UNMC_METER_CTRL1_PORT2_METERIDX_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_UNMC_METER_CTRL2 0x0a5e ++#define RTL8367C_STORM_UNMC_METER_CTRL2_PORT5_METERIDX_OFFSET 8 ++#define RTL8367C_STORM_UNMC_METER_CTRL2_PORT5_METERIDX_MASK 0x3F00 ++#define RTL8367C_STORM_UNMC_METER_CTRL2_PORT4_METERIDX_OFFSET 0 ++#define RTL8367C_STORM_UNMC_METER_CTRL2_PORT4_METERIDX_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_UNMC_METER_CTRL3 0x0a5f ++#define RTL8367C_STORM_UNMC_METER_CTRL3_PORT7_METERIDX_OFFSET 8 ++#define RTL8367C_STORM_UNMC_METER_CTRL3_PORT7_METERIDX_MASK 0x3F00 ++#define RTL8367C_STORM_UNMC_METER_CTRL3_PORT6_METERIDX_OFFSET 0 ++#define RTL8367C_STORM_UNMC_METER_CTRL3_PORT6_METERIDX_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_EXT_CFG 0x0a60 ++#define RTL8367C_STORM_EXT_EN_PORTMASK_EXT_OFFSET 14 ++#define RTL8367C_STORM_EXT_EN_PORTMASK_EXT_MASK 0x4000 ++#define RTL8367C_STORM_UNKNOWN_MCAST_EXT_EN_OFFSET 13 ++#define RTL8367C_STORM_UNKNOWN_MCAST_EXT_EN_MASK 0x2000 ++#define RTL8367C_STORM_UNKNOWN_UCAST_EXT_EN_OFFSET 12 ++#define RTL8367C_STORM_UNKNOWN_UCAST_EXT_EN_MASK 0x1000 ++#define RTL8367C_STORM_MCAST_EXT_EN_OFFSET 11 ++#define RTL8367C_STORM_MCAST_EXT_EN_MASK 0x800 ++#define RTL8367C_STORM_BCAST_EXT_EN_OFFSET 10 ++#define RTL8367C_STORM_BCAST_EXT_EN_MASK 0x400 ++#define RTL8367C_STORM_EXT_EN_PORTMASK_OFFSET 0 ++#define RTL8367C_STORM_EXT_EN_PORTMASK_MASK 0x3FF ++ ++#define RTL8367C_REG_STORM_EXT_MTRIDX_CFG0 0x0a61 ++#define RTL8367C_MC_STORM_EXT_METERIDX_OFFSET 8 ++#define RTL8367C_MC_STORM_EXT_METERIDX_MASK 0x3F00 ++#define RTL8367C_BC_STORM_EXT_METERIDX_OFFSET 0 ++#define RTL8367C_BC_STORM_EXT_METERIDX_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_EXT_MTRIDX_CFG1 0x0a62 ++#define RTL8367C_UNMC_STORM_EXT_METERIDX_OFFSET 8 ++#define RTL8367C_UNMC_STORM_EXT_METERIDX_MASK 0x3F00 ++#define RTL8367C_UNUC_STORM_EXT_METERIDX_OFFSET 0 ++#define RTL8367C_UNUC_STORM_EXT_METERIDX_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_UNMC_METER_CTRL4 0x0a63 ++#define RTL8367C_STORM_UNMC_METER_CTRL4_PORT9_METERIDX_OFFSET 8 ++#define RTL8367C_STORM_UNMC_METER_CTRL4_PORT9_METERIDX_MASK 0x3F00 ++#define RTL8367C_STORM_UNMC_METER_CTRL4_PORT8_METERIDX_OFFSET 0 ++#define RTL8367C_STORM_UNMC_METER_CTRL4_PORT8_METERIDX_MASK 0x3F ++ ++#define RTL8367C_REG_STORM_UNMC_METER_CTRL5 0x0a64 ++#define RTL8367C_STORM_UNMC_METER_CTRL5_OFFSET 0 ++#define RTL8367C_STORM_UNMC_METER_CTRL5_MASK 0x3F ++ ++#define RTL8367C_REG_OAM_PARSER_CTRL0 0x0a70 ++#define RTL8367C_PORT7_PARACT_OFFSET 14 ++#define RTL8367C_PORT7_PARACT_MASK 0xC000 ++#define RTL8367C_PORT6_PARACT_OFFSET 12 ++#define RTL8367C_PORT6_PARACT_MASK 0x3000 ++#define RTL8367C_PORT5_PARACT_OFFSET 10 ++#define RTL8367C_PORT5_PARACT_MASK 0xC00 ++#define RTL8367C_PORT4_PARACT_OFFSET 8 ++#define RTL8367C_PORT4_PARACT_MASK 0x300 ++#define RTL8367C_PORT3_PARACT_OFFSET 6 ++#define RTL8367C_PORT3_PARACT_MASK 0xC0 ++#define RTL8367C_PORT2_PARACT_OFFSET 4 ++#define RTL8367C_PORT2_PARACT_MASK 0x30 ++#define RTL8367C_PORT1_PARACT_OFFSET 2 ++#define RTL8367C_PORT1_PARACT_MASK 0xC ++#define RTL8367C_PORT0_PARACT_OFFSET 0 ++#define RTL8367C_PORT0_PARACT_MASK 0x3 ++ ++#define RTL8367C_REG_OAM_PARSER_CTRL1 0x0a71 ++#define RTL8367C_PORT10_PARACT_OFFSET 4 ++#define RTL8367C_PORT10_PARACT_MASK 0x30 ++#define RTL8367C_PORT9_PARACT_OFFSET 2 ++#define RTL8367C_PORT9_PARACT_MASK 0xC ++#define RTL8367C_PORT8_PARACT_OFFSET 0 ++#define RTL8367C_PORT8_PARACT_MASK 0x3 ++ ++#define RTL8367C_REG_OAM_MULTIPLEXER_CTRL0 0x0a72 ++#define RTL8367C_PORT7_MULACT_OFFSET 14 ++#define RTL8367C_PORT7_MULACT_MASK 0xC000 ++#define RTL8367C_PORT6_MULACT_OFFSET 12 ++#define RTL8367C_PORT6_MULACT_MASK 0x3000 ++#define RTL8367C_PORT5_MULACT_OFFSET 10 ++#define RTL8367C_PORT5_MULACT_MASK 0xC00 ++#define RTL8367C_PORT4_MULACT_OFFSET 8 ++#define RTL8367C_PORT4_MULACT_MASK 0x300 ++#define RTL8367C_PORT3_MULACT_OFFSET 6 ++#define RTL8367C_PORT3_MULACT_MASK 0xC0 ++#define RTL8367C_PORT2_MULACT_OFFSET 4 ++#define RTL8367C_PORT2_MULACT_MASK 0x30 ++#define RTL8367C_PORT1_MULACT_OFFSET 2 ++#define RTL8367C_PORT1_MULACT_MASK 0xC ++#define RTL8367C_PORT0_MULACT_OFFSET 0 ++#define RTL8367C_PORT0_MULACT_MASK 0x3 ++ ++#define RTL8367C_REG_OAM_MULTIPLEXER_CTRL1 0x0a73 ++#define RTL8367C_PORT10_MULACT_OFFSET 4 ++#define RTL8367C_PORT10_MULACT_MASK 0x30 ++#define RTL8367C_PORT9_MULACT_OFFSET 2 ++#define RTL8367C_PORT9_MULACT_MASK 0xC ++#define RTL8367C_PORT8_MULACT_OFFSET 0 ++#define RTL8367C_PORT8_MULACT_MASK 0x3 ++ ++#define RTL8367C_REG_OAM_CTRL 0x0a74 ++#define RTL8367C_OAM_CTRL_OFFSET 0 ++#define RTL8367C_OAM_CTRL_MASK 0x1 ++ ++#define RTL8367C_REG_DOT1X_PORT_ENABLE 0x0a80 ++#define RTL8367C_DOT1X_PORT_ENABLE_OFFSET 0 ++#define RTL8367C_DOT1X_PORT_ENABLE_MASK 0x7FF ++ ++#define RTL8367C_REG_DOT1X_MAC_ENABLE 0x0a81 ++#define RTL8367C_DOT1X_MAC_ENABLE_OFFSET 0 ++#define RTL8367C_DOT1X_MAC_ENABLE_MASK 0x7FF ++ ++#define RTL8367C_REG_DOT1X_PORT_AUTH 0x0a82 ++#define RTL8367C_DOT1X_PORT_AUTH_OFFSET 0 ++#define RTL8367C_DOT1X_PORT_AUTH_MASK 0x7FF ++ ++#define RTL8367C_REG_DOT1X_PORT_OPDIR 0x0a83 ++#define RTL8367C_DOT1X_PORT_OPDIR_OFFSET 0 ++#define RTL8367C_DOT1X_PORT_OPDIR_MASK 0x7FF ++ ++#define RTL8367C_REG_DOT1X_UNAUTH_ACT_W0 0x0a84 ++#define RTL8367C_DOT1X_PORT7_UNAUTHBH_OFFSET 14 ++#define RTL8367C_DOT1X_PORT7_UNAUTHBH_MASK 0xC000 ++#define RTL8367C_DOT1X_PORT6_UNAUTHBH_OFFSET 12 ++#define RTL8367C_DOT1X_PORT6_UNAUTHBH_MASK 0x3000 ++#define RTL8367C_DOT1X_PORT5_UNAUTHBH_OFFSET 10 ++#define RTL8367C_DOT1X_PORT5_UNAUTHBH_MASK 0xC00 ++#define RTL8367C_DOT1X_PORT4_UNAUTHBH_OFFSET 8 ++#define RTL8367C_DOT1X_PORT4_UNAUTHBH_MASK 0x300 ++#define RTL8367C_DOT1X_PORT3_UNAUTHBH_OFFSET 6 ++#define RTL8367C_DOT1X_PORT3_UNAUTHBH_MASK 0xC0 ++#define RTL8367C_DOT1X_PORT2_UNAUTHBH_OFFSET 4 ++#define RTL8367C_DOT1X_PORT2_UNAUTHBH_MASK 0x30 ++#define RTL8367C_DOT1X_PORT1_UNAUTHBH_OFFSET 2 ++#define RTL8367C_DOT1X_PORT1_UNAUTHBH_MASK 0xC ++#define RTL8367C_DOT1X_PORT0_UNAUTHBH_OFFSET 0 ++#define RTL8367C_DOT1X_PORT0_UNAUTHBH_MASK 0x3 ++ ++#define RTL8367C_REG_DOT1X_UNAUTH_ACT_W1 0x0a85 ++#define RTL8367C_DOT1X_PORT10_UNAUTHBH_OFFSET 4 ++#define RTL8367C_DOT1X_PORT10_UNAUTHBH_MASK 0x30 ++#define RTL8367C_DOT1X_PORT9_UNAUTHBH_OFFSET 2 ++#define RTL8367C_DOT1X_PORT9_UNAUTHBH_MASK 0xC ++#define RTL8367C_DOT1X_PORT8_UNAUTHBH_OFFSET 0 ++#define RTL8367C_DOT1X_PORT8_UNAUTHBH_MASK 0x3 ++ ++#define RTL8367C_REG_DOT1X_CFG 0x0a86 ++#define RTL8367C_DOT1X_GVOPDIR_OFFSET 6 ++#define RTL8367C_DOT1X_GVOPDIR_MASK 0x40 ++#define RTL8367C_DOT1X_MAC_OPDIR_OFFSET 5 ++#define RTL8367C_DOT1X_MAC_OPDIR_MASK 0x20 ++#define RTL8367C_DOT1X_GVIDX_OFFSET 0 ++#define RTL8367C_DOT1X_GVIDX_MASK 0x1F ++ ++#define RTL8367C_REG_L2_LRN_CNT_CTRL0 0x0a87 ++#define RTL8367C_L2_LRN_CNT_CTRL0_OFFSET 0 ++#define RTL8367C_L2_LRN_CNT_CTRL0_MASK 0x1FFF ++ ++#define RTL8367C_REG_L2_LRN_CNT_CTRL1 0x0a88 ++#define RTL8367C_L2_LRN_CNT_CTRL1_OFFSET 0 ++#define RTL8367C_L2_LRN_CNT_CTRL1_MASK 0x1FFF ++ ++#define RTL8367C_REG_L2_LRN_CNT_CTRL2 0x0a89 ++#define RTL8367C_L2_LRN_CNT_CTRL2_OFFSET 0 ++#define RTL8367C_L2_LRN_CNT_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_L2_LRN_CNT_CTRL3 0x0a8a ++#define RTL8367C_L2_LRN_CNT_CTRL3_OFFSET 0 ++#define RTL8367C_L2_LRN_CNT_CTRL3_MASK 0x1FFF ++ ++#define RTL8367C_REG_L2_LRN_CNT_CTRL4 0x0a8b ++#define RTL8367C_L2_LRN_CNT_CTRL4_OFFSET 0 ++#define RTL8367C_L2_LRN_CNT_CTRL4_MASK 0x1FFF ++ ++#define RTL8367C_REG_L2_LRN_CNT_CTRL5 0x0a8c ++#define RTL8367C_L2_LRN_CNT_CTRL5_OFFSET 0 ++#define RTL8367C_L2_LRN_CNT_CTRL5_MASK 0x1FFF ++ ++#define RTL8367C_REG_L2_LRN_CNT_CTRL6 0x0a8d ++#define RTL8367C_L2_LRN_CNT_CTRL6_OFFSET 0 ++#define RTL8367C_L2_LRN_CNT_CTRL6_MASK 0x1FFF ++ ++#define RTL8367C_REG_L2_LRN_CNT_CTRL7 0x0a8e ++#define RTL8367C_L2_LRN_CNT_CTRL7_OFFSET 0 ++#define RTL8367C_L2_LRN_CNT_CTRL7_MASK 0x1FFF ++ ++#define RTL8367C_REG_L2_LRN_CNT_CTRL8 0x0a8f ++#define RTL8367C_L2_LRN_CNT_CTRL8_OFFSET 0 ++#define RTL8367C_L2_LRN_CNT_CTRL8_MASK 0x1FFF ++ ++#define RTL8367C_REG_L2_LRN_CNT_CTRL9 0x0a90 ++#define RTL8367C_L2_LRN_CNT_CTRL9_OFFSET 0 ++#define RTL8367C_L2_LRN_CNT_CTRL9_MASK 0x1FFF ++ ++#define RTL8367C_REG_L2_LRN_CNT_CTRL10 0x0a92 ++#define RTL8367C_L2_LRN_CNT_CTRL10_OFFSET 0 ++#define RTL8367C_L2_LRN_CNT_CTRL10_MASK 0x1FFF ++ ++#define RTL8367C_REG_LUT_LRN_UNDER_STATUS 0x0a91 ++#define RTL8367C_LUT_LRN_UNDER_STATUS_OFFSET 0 ++#define RTL8367C_LUT_LRN_UNDER_STATUS_MASK 0x7FF ++ ++#define RTL8367C_REG_L2_SA_MOVING_FORBID 0x0aa0 ++#define RTL8367C_L2_SA_MOVING_FORBID_OFFSET 0 ++#define RTL8367C_L2_SA_MOVING_FORBID_MASK 0x7FF ++ ++#define RTL8367C_REG_DRPORT_LEARN_CTRL 0x0aa1 ++#define RTL8367C_FORBID1_OFFSET 1 ++#define RTL8367C_FORBID1_MASK 0x2 ++#define RTL8367C_FORBID0_OFFSET 0 ++#define RTL8367C_FORBID0_MASK 0x1 ++ ++#define RTL8367C_REG_L2_DUMMY02 0x0aa2 ++ ++#define RTL8367C_REG_L2_DUMMY03 0x0aa3 ++ ++#define RTL8367C_REG_L2_DUMMY04 0x0aa4 ++ ++#define RTL8367C_REG_L2_DUMMY05 0x0aa5 ++ ++#define RTL8367C_REG_L2_DUMMY06 0x0aa6 ++ ++#define RTL8367C_REG_L2_DUMMY07 0x0aa7 ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_00 0x0AC0 ++#define RTL8367C_IPMC_GROUP_PMSK_00_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_00_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_01 0x0AC1 ++#define RTL8367C_IPMC_GROUP_PMSK_01_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_01_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_02 0x0AC2 ++#define RTL8367C_IPMC_GROUP_PMSK_02_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_02_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_03 0x0AC3 ++#define RTL8367C_IPMC_GROUP_PMSK_03_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_03_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_04 0x0AC4 ++#define RTL8367C_IPMC_GROUP_PMSK_04_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_04_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_05 0x0AC5 ++#define RTL8367C_IPMC_GROUP_PMSK_05_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_05_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_06 0x0AC6 ++#define RTL8367C_IPMC_GROUP_PMSK_06_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_06_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_07 0x0AC7 ++#define RTL8367C_IPMC_GROUP_PMSK_07_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_07_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_08 0x0AC8 ++#define RTL8367C_IPMC_GROUP_PMSK_08_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_08_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_09 0x0AC9 ++#define RTL8367C_IPMC_GROUP_PMSK_09_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_09_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_10 0x0ACA ++#define RTL8367C_IPMC_GROUP_PMSK_10_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_10_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_11 0x0ACB ++#define RTL8367C_IPMC_GROUP_PMSK_11_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_11_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_12 0x0ACC ++#define RTL8367C_IPMC_GROUP_PMSK_12_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_12_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_13 0x0ACD ++#define RTL8367C_IPMC_GROUP_PMSK_13_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_13_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_14 0x0ACE ++#define RTL8367C_IPMC_GROUP_PMSK_14_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_14_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_15 0x0ACF ++#define RTL8367C_IPMC_GROUP_PMSK_15_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_15_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_16 0x0AD0 ++#define RTL8367C_IPMC_GROUP_PMSK_16_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_16_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_17 0x0AD1 ++#define RTL8367C_IPMC_GROUP_PMSK_17_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_17_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_18 0x0AD2 ++#define RTL8367C_IPMC_GROUP_PMSK_18_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_18_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_19 0x0AD3 ++#define RTL8367C_IPMC_GROUP_PMSK_19_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_19_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_20 0x0AD4 ++#define RTL8367C_IPMC_GROUP_PMSK_20_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_20_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_21 0x0AD5 ++#define RTL8367C_IPMC_GROUP_PMSK_21_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_21_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_22 0x0AD6 ++#define RTL8367C_IPMC_GROUP_PMSK_22_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_22_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_23 0x0AD7 ++#define RTL8367C_IPMC_GROUP_PMSK_23_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_23_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_24 0x0AD8 ++#define RTL8367C_IPMC_GROUP_PMSK_24_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_24_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_25 0x0AD9 ++#define RTL8367C_IPMC_GROUP_PMSK_25_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_25_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_26 0x0ADA ++#define RTL8367C_IPMC_GROUP_PMSK_26_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_26_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_27 0x0ADB ++#define RTL8367C_IPMC_GROUP_PMSK_27_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_27_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_28 0x0ADC ++#define RTL8367C_IPMC_GROUP_PMSK_28_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_28_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_29 0x0ADD ++#define RTL8367C_IPMC_GROUP_PMSK_29_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_29_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_30 0x0ADE ++#define RTL8367C_IPMC_GROUP_PMSK_30_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_30_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_31 0x0ADF ++#define RTL8367C_IPMC_GROUP_PMSK_31_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_31_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_32 0x0AE0 ++#define RTL8367C_IPMC_GROUP_PMSK_32_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_32_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_33 0x0AE1 ++#define RTL8367C_IPMC_GROUP_PMSK_33_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_33_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_34 0x0AE2 ++#define RTL8367C_IPMC_GROUP_PMSK_34_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_34_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_35 0x0AE3 ++#define RTL8367C_IPMC_GROUP_PMSK_35_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_35_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_36 0x0AE4 ++#define RTL8367C_IPMC_GROUP_PMSK_36_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_36_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_37 0x0AE5 ++#define RTL8367C_IPMC_GROUP_PMSK_37_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_37_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_38 0x0AE6 ++#define RTL8367C_IPMC_GROUP_PMSK_38_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_38_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_39 0x0AE7 ++#define RTL8367C_IPMC_GROUP_PMSK_39_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_39_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_40 0x0AE8 ++#define RTL8367C_IPMC_GROUP_PMSK_40_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_40_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_41 0x0AE9 ++#define RTL8367C_IPMC_GROUP_PMSK_41_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_41_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_42 0x0AEA ++#define RTL8367C_IPMC_GROUP_PMSK_42_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_42_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_43 0x0AEB ++#define RTL8367C_IPMC_GROUP_PMSK_43_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_43_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_44 0x0AEC ++#define RTL8367C_IPMC_GROUP_PMSK_44_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_44_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_45 0x0AED ++#define RTL8367C_IPMC_GROUP_PMSK_45_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_45_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_46 0x0AEE ++#define RTL8367C_IPMC_GROUP_PMSK_46_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_46_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_47 0x0AEF ++#define RTL8367C_IPMC_GROUP_PMSK_47_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_47_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_48 0x0AF0 ++#define RTL8367C_IPMC_GROUP_PMSK_48_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_48_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_49 0x0AF1 ++#define RTL8367C_IPMC_GROUP_PMSK_49_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_49_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_50 0x0AF2 ++#define RTL8367C_IPMC_GROUP_PMSK_50_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_50_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_51 0x0AF3 ++#define RTL8367C_IPMC_GROUP_PMSK_51_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_51_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_52 0x0AF4 ++#define RTL8367C_IPMC_GROUP_PMSK_52_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_52_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_53 0x0AF5 ++#define RTL8367C_IPMC_GROUP_PMSK_53_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_53_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_54 0x0AF6 ++#define RTL8367C_IPMC_GROUP_PMSK_54_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_54_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_55 0x0AF7 ++#define RTL8367C_IPMC_GROUP_PMSK_55_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_55_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_56 0x0AF8 ++#define RTL8367C_IPMC_GROUP_PMSK_56_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_56_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_57 0x0AF9 ++#define RTL8367C_IPMC_GROUP_PMSK_57_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_57_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_58 0x0AFA ++#define RTL8367C_IPMC_GROUP_PMSK_58_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_58_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_59 0x0AFB ++#define RTL8367C_IPMC_GROUP_PMSK_59_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_59_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_60 0x0AFC ++#define RTL8367C_IPMC_GROUP_PMSK_60_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_60_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_61 0x0AFD ++#define RTL8367C_IPMC_GROUP_PMSK_61_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_61_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_62 0x0AFE ++#define RTL8367C_IPMC_GROUP_PMSK_62_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_62_MASK 0x7FF ++ ++#define RTL8367C_REG_IPMC_GROUP_PMSK_63 0x0AFF ++#define RTL8367C_IPMC_GROUP_PMSK_63_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_PMSK_63_MASK 0x7FF ++ ++/* (16'h0b00)mltvlan_reg */ ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL0 0x0b00 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY0_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL1 0x0b01 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL2 0x0b02 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL3 0x0b03 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY0_CTRL4 0x0b04 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY1_CTRL0 0x0b05 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY1_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY1_CTRL1 0x0b06 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY1_CTRL2 0x0b07 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY1_CTRL3 0x0b08 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY1_CTRL4 0x0b09 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY2_CTRL0 0x0b0a ++#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY2_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY2_CTRL1 0x0b0b ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY2_CTRL2 0x0b0c ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY2_CTRL3 0x0b0d ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY2_CTRL4 0x0b0e ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY3_CTRL0 0x0b0f ++#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY3_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY3_CTRL1 0x0b10 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY3_CTRL2 0x0b11 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY3_CTRL3 0x0b12 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY3_CTRL4 0x0b13 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY4_CTRL0 0x0b14 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY4_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY4_CTRL1 0x0b15 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY4_CTRL2 0x0b16 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY4_CTRL3 0x0b17 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY4_CTRL4 0x0b18 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY5_CTRL0 0x0b19 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY5_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY5_CTRL1 0x0b1a ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY5_CTRL2 0x0b1b ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY5_CTRL3 0x0b1c ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY5_CTRL4 0x0b1d ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY6_CTRL0 0x0b1e ++#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY6_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY6_CTRL1 0x0b1f ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY6_CTRL2 0x0b20 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY6_CTRL3 0x0b21 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY6_CTRL4 0x0b22 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY7_CTRL0 0x0b23 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY7_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY7_CTRL1 0x0b24 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY7_CTRL2 0x0b25 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY7_CTRL3 0x0b26 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY7_CTRL4 0x0b27 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY8_CTRL0 0x0b28 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY8_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY8_CTRL1 0x0b29 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY8_CTRL2 0x0b2a ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY8_CTRL3 0x0b2b ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY8_CTRL4 0x0b2c ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY9_CTRL0 0x0b2d ++#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY9_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY9_CTRL1 0x0b2e ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY9_CTRL2 0x0b2f ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY9_CTRL3 0x0b30 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY9_CTRL4 0x0b31 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY10_CTRL0 0x0b32 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY10_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY10_CTRL1 0x0b33 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY10_CTRL2 0x0b34 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY10_CTRL3 0x0b35 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY10_CTRL4 0x0b36 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY11_CTRL0 0x0b37 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY11_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY11_CTRL1 0x0b38 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY11_CTRL2 0x0b39 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY11_CTRL3 0x0b3a ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY11_CTRL4 0x0b3b ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY12_CTRL0 0x0b3c ++#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY12_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY12_CTRL1 0x0b3d ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY12_CTRL2 0x0b3e ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY12_CTRL3 0x0b3f ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY12_CTRL4 0x0b40 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY13_CTRL0 0x0b41 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY13_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY13_CTRL1 0x0b42 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY13_CTRL2 0x0b43 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY13_CTRL3 0x0b44 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY13_CTRL4 0x0b45 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY14_CTRL0 0x0b46 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY14_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY14_CTRL1 0x0b47 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY14_CTRL2 0x0b48 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY14_CTRL3 0x0b49 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY14_CTRL4 0x0b4a ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY15_CTRL0 0x0b4b ++#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY15_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY15_CTRL1 0x0b4c ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY15_CTRL2 0x0b4d ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY15_CTRL3 0x0b4e ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY15_CTRL4 0x0b4f ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY16_CTRL0 0x0b50 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY16_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY16_CTRL1 0x0b51 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY16_CTRL2 0x0b52 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY16_CTRL3 0x0b53 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY16_CTRL4 0x0b54 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY17_CTRL0 0x0b55 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY17_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY17_CTRL1 0x0b56 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY17_CTRL2 0x0b57 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY17_CTRL3 0x0b58 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY17_CTRL4 0x0b59 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY18_CTRL0 0x0b5a ++#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY18_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY18_CTRL1 0x0b5b ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY18_CTRL2 0x0b5c ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY18_CTRL3 0x0b5d ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY18_CTRL4 0x0b5e ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY19_CTRL0 0x0b5f ++#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY19_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY19_CTRL1 0x0b60 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY19_CTRL2 0x0b61 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY19_CTRL3 0x0b62 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY19_CTRL4 0x0b63 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY20_CTRL0 0x0b64 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY20_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY20_CTRL1 0x0b65 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY20_CTRL2 0x0b66 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY20_CTRL3 0x0b67 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY20_CTRL4 0x0b68 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY21_CTRL0 0x0b69 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY21_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY21_CTRL1 0x0b6a ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY21_CTRL2 0x0b6b ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY21_CTRL3 0x0b6c ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY21_CTRL4 0x0b6d ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY22_CTRL0 0x0b6e ++#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY22_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY22_CTRL1 0x0b6f ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY22_CTRL2 0x0b70 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY22_CTRL3 0x0b71 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY22_CTRL4 0x0b72 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY23_CTRL0 0x0b73 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY23_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY23_CTRL1 0x0b74 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY23_CTRL2 0x0b75 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY23_CTRL3 0x0b76 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY23_CTRL4 0x0b77 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY24_CTRL0 0x0b78 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY24_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY24_CTRL1 0x0b79 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY24_CTRL2 0x0b7a ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY24_CTRL3 0x0b7b ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY24_CTRL4 0x0b7c ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY25_CTRL0 0x0b7d ++#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY25_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY25_CTRL1 0x0b7e ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY25_CTRL2 0x0b7f ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY25_CTRL3 0x0b80 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY25_CTRL4 0x0b81 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY26_CTRL0 0x0b82 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY26_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY26_CTRL1 0x0b83 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY26_CTRL2 0x0b84 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY26_CTRL3 0x0b85 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY26_CTRL4 0x0b86 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY27_CTRL0 0x0b87 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY27_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY27_CTRL1 0x0b88 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY27_CTRL2 0x0b89 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY27_CTRL3 0x0b8a ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY27_CTRL4 0x0b8b ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY28_CTRL0 0x0b8c ++#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY28_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY28_CTRL1 0x0b8d ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY28_CTRL2 0x0b8e ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY28_CTRL3 0x0b8f ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY28_CTRL4 0x0b90 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY29_CTRL0 0x0b91 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY29_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY29_CTRL1 0x0b92 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY29_CTRL2 0x0b93 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY29_CTRL3 0x0b94 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY29_CTRL4 0x0b95 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY30_CTRL0 0x0b96 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY30_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY30_CTRL1 0x0b97 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY30_CTRL2 0x0b98 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY30_CTRL3 0x0b99 ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY30_CTRL4 0x0b9a ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY31_CTRL0 0x0b9b ++#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_VALID_OFFSET 7 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_VALID_MASK 0x80 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_FORMAT_OFFSET 6 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_FORMAT_MASK 0x40 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_SVIDX_OFFSET 0 ++#define RTL8367C_SVLAN_MCAST2S_ENTRY31_CTRL0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY31_CTRL1 0x0b9c ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY31_CTRL2 0x0b9d ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY31_CTRL3 0x0b9e ++ ++#define RTL8367C_REG_SVLAN_MCAST2S_ENTRY31_CTRL4 0x0b9f ++ ++#define RTL8367C_REG_MLTVLAN_DUMMY_0 0x0ba0 ++ ++#define RTL8367C_REG_MLTVLAN_DUMMY_1 0x0ba1 ++ ++#define RTL8367C_REG_MLTVLAN_DUMMY_2 0x0ba2 ++ ++#define RTL8367C_REG_MLTVLAN_DUMMY_3 0x0ba3 ++ ++#define RTL8367C_REG_MLTVLAN_DUMMY_4 0x0ba4 ++ ++#define RTL8367C_REG_MLTVLAN_DUMMY_5 0x0ba5 ++ ++#define RTL8367C_REG_MLTVLAN_DUMMY_6 0x0ba6 ++ ++#define RTL8367C_REG_MLTVLAN_DUMMY_7 0x0ba7 ++ ++/* (16'h0c00)svlan_reg */ ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL1 0x0c01 ++#define RTL8367C_SVLAN_MEMBERCFG0_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG0_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG0_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG0_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL2 0x0c02 ++#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG0_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL3 0x0c03 ++#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG0_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG1_CTRL1 0x0c04 ++#define RTL8367C_SVLAN_MEMBERCFG1_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG1_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG1_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG1_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG1_CTRL2 0x0c05 ++#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG1_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG1_CTRL3 0x0c06 ++#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG1_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG2_CTRL1 0x0c07 ++#define RTL8367C_SVLAN_MEMBERCFG2_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG2_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG2_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG2_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG2_CTRL2 0x0c08 ++#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG2_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG2_CTRL3 0x0c09 ++#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG2_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG3_CTRL1 0x0c0a ++#define RTL8367C_SVLAN_MEMBERCFG3_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG3_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG3_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG3_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG3_CTRL2 0x0c0b ++#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG3_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG3_CTRL3 0x0c0c ++#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG3_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG4_CTRL1 0x0c0d ++#define RTL8367C_SVLAN_MEMBERCFG4_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG4_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG4_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG4_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG4_CTRL2 0x0c0e ++#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG4_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG4_CTRL3 0x0c0f ++#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG4_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG5_CTRL1 0x0c10 ++#define RTL8367C_SVLAN_MEMBERCFG5_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG5_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG5_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG5_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG5_CTRL2 0x0c11 ++#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG5_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG5_CTRL3 0x0c12 ++#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG5_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG6_CTRL1 0x0c13 ++#define RTL8367C_SVLAN_MEMBERCFG6_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG6_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG6_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG6_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG6_CTRL2 0x0c14 ++#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG6_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG6_CTRL3 0x0c15 ++#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG6_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG7_CTRL1 0x0c16 ++#define RTL8367C_SVLAN_MEMBERCFG7_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG7_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG7_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG7_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG7_CTRL2 0x0c17 ++#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG7_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG7_CTRL3 0x0c18 ++#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG7_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG8_CTRL1 0x0c19 ++#define RTL8367C_SVLAN_MEMBERCFG8_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG8_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG8_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG8_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG8_CTRL2 0x0c1a ++#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG8_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG8_CTRL3 0x0c1b ++#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG8_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG9_CTRL1 0x0c1c ++#define RTL8367C_SVLAN_MEMBERCFG9_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG9_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG9_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG9_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG9_CTRL2 0x0c1d ++#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG9_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG9_CTRL3 0x0c1e ++#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG9_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG10_CTRL1 0x0c1f ++#define RTL8367C_SVLAN_MEMBERCFG10_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG10_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG10_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG10_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG10_CTRL2 0x0c20 ++#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG10_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG10_CTRL3 0x0c21 ++#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG10_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG11_CTRL1 0x0c22 ++#define RTL8367C_SVLAN_MEMBERCFG11_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG11_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG11_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG11_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG11_CTRL2 0x0c23 ++#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG11_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG11_CTRL3 0x0c24 ++#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG11_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG12_CTRL1 0x0c25 ++#define RTL8367C_SVLAN_MEMBERCFG12_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG12_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG12_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG12_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG12_CTRL2 0x0c26 ++#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG12_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG12_CTRL3 0x0c27 ++#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG12_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG13_CTRL1 0x0c28 ++#define RTL8367C_SVLAN_MEMBERCFG13_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG13_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG13_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG13_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG13_CTRL2 0x0c29 ++#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG13_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG13_CTRL3 0x0c2a ++#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG13_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG14_CTRL1 0x0c2b ++#define RTL8367C_SVLAN_MEMBERCFG14_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG14_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG14_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG14_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG14_CTRL2 0x0c2c ++#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG14_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG14_CTRL3 0x0c2d ++#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG14_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG15_CTRL1 0x0c2e ++#define RTL8367C_SVLAN_MEMBERCFG15_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG15_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG15_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG15_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG15_CTRL2 0x0c2f ++#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG15_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG15_CTRL3 0x0c30 ++#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG15_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG16_CTRL1 0x0c31 ++#define RTL8367C_SVLAN_MEMBERCFG16_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG16_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG16_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG16_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG16_CTRL2 0x0c32 ++#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG16_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG16_CTRL3 0x0c33 ++#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG16_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG17_CTRL1 0x0c34 ++#define RTL8367C_SVLAN_MEMBERCFG17_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG17_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG17_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG17_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG17_CTRL2 0x0c35 ++#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG17_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG17_CTRL3 0x0c36 ++#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG17_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG18_CTRL1 0x0c37 ++#define RTL8367C_SVLAN_MEMBERCFG18_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG18_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG18_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG18_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG18_CTRL2 0x0c38 ++#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG18_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG18_CTRL3 0x0c39 ++#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG18_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG19_CTRL1 0x0c3a ++#define RTL8367C_SVLAN_MEMBERCFG19_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG19_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG19_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG19_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG19_CTRL2 0x0c3b ++#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG19_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG19_CTRL3 0x0c3c ++#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG19_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG20_CTRL1 0x0c3d ++#define RTL8367C_SVLAN_MEMBERCFG20_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG20_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG20_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG20_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG20_CTRL2 0x0c3e ++#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG20_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG20_CTRL3 0x0c3f ++#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG20_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG21_CTRL1 0x0c40 ++#define RTL8367C_SVLAN_MEMBERCFG21_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG21_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG21_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG21_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG21_CTRL2 0x0c41 ++#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG21_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG21_CTRL3 0x0c42 ++#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG21_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG22_CTRL1 0x0c43 ++#define RTL8367C_SVLAN_MEMBERCFG22_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG22_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG22_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG22_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG22_CTRL2 0x0c44 ++#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG22_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG22_CTRL3 0x0c45 ++#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG22_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG23_CTRL1 0x0c46 ++#define RTL8367C_SVLAN_MEMBERCFG23_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG23_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG23_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG23_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG23_CTRL2 0x0c47 ++#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG23_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG23_CTRL3 0x0c48 ++#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG23_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG24_CTRL1 0x0c49 ++#define RTL8367C_SVLAN_MEMBERCFG24_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG24_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG24_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG24_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG24_CTRL2 0x0c4a ++#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG24_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG24_CTRL3 0x0c4b ++#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG24_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG25_CTRL1 0x0c4c ++#define RTL8367C_SVLAN_MEMBERCFG25_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG25_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG25_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG25_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG25_CTRL2 0x0c4d ++#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG25_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG25_CTRL3 0x0c4e ++#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG25_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG26_CTRL1 0x0c4f ++#define RTL8367C_SVLAN_MEMBERCFG26_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG26_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG26_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG26_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG26_CTRL2 0x0c50 ++#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG26_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG26_CTRL3 0x0c51 ++#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG26_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG27_CTRL1 0x0c52 ++#define RTL8367C_SVLAN_MEMBERCFG27_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG27_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG27_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG27_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG27_CTRL2 0x0c53 ++#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG27_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG27_CTRL3 0x0c54 ++#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG27_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG28_CTRL1 0x0c55 ++#define RTL8367C_SVLAN_MEMBERCFG28_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG28_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG28_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG28_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG28_CTRL2 0x0c56 ++#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG28_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG28_CTRL3 0x0c57 ++#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG28_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG29_CTRL1 0x0c58 ++#define RTL8367C_SVLAN_MEMBERCFG29_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG29_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG29_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG29_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG29_CTRL2 0x0c59 ++#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG29_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG29_CTRL3 0x0c5a ++#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG29_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG30_CTRL1 0x0c5b ++#define RTL8367C_SVLAN_MEMBERCFG30_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG30_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG30_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG30_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG30_CTRL2 0x0c5c ++#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG30_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG30_CTRL3 0x0c5d ++#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG30_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG31_CTRL1 0x0c5e ++#define RTL8367C_SVLAN_MEMBERCFG31_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG31_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG31_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG31_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG31_CTRL2 0x0c5f ++#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG31_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG31_CTRL3 0x0c60 ++#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG31_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG32_CTRL1 0x0c61 ++#define RTL8367C_SVLAN_MEMBERCFG32_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG32_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG32_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG32_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG32_CTRL2 0x0c62 ++#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG32_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG32_CTRL3 0x0c63 ++#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG32_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG33_CTRL1 0x0c64 ++#define RTL8367C_SVLAN_MEMBERCFG33_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG33_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG33_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG33_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG33_CTRL2 0x0c65 ++#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG33_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG33_CTRL3 0x0c66 ++#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG33_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG34_CTRL1 0x0c67 ++#define RTL8367C_SVLAN_MEMBERCFG34_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG34_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG34_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG34_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG34_CTRL2 0x0c68 ++#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG34_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG34_CTRL3 0x0c69 ++#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG34_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG35_CTRL1 0x0c6a ++#define RTL8367C_SVLAN_MEMBERCFG35_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG35_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG35_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG35_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG35_CTRL2 0x0c6b ++#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG35_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG35_CTRL3 0x0c6c ++#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG35_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG36_CTRL1 0x0c6d ++#define RTL8367C_SVLAN_MEMBERCFG36_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG36_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG36_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG36_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG36_CTRL2 0x0c6e ++#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG36_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG36_CTRL3 0x0c6f ++#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG36_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG37_CTRL1 0x0c70 ++#define RTL8367C_SVLAN_MEMBERCFG37_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG37_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG37_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG37_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG37_CTRL2 0x0c71 ++#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG37_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG37_CTRL3 0x0c72 ++#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG37_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG38_CTRL1 0x0c73 ++#define RTL8367C_SVLAN_MEMBERCFG38_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG38_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG38_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG38_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG38_CTRL2 0x0c74 ++#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG38_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG38_CTRL3 0x0c75 ++#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG38_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG39_CTRL1 0x0c76 ++#define RTL8367C_SVLAN_MEMBERCFG39_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG39_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG39_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG39_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG39_CTRL2 0x0c77 ++#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG39_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG39_CTRL3 0x0c78 ++#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG39_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG40_CTRL1 0x0c79 ++#define RTL8367C_SVLAN_MEMBERCFG40_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG40_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG40_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG40_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG40_CTRL2 0x0c7a ++#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG40_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG40_CTRL3 0x0c7b ++#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG40_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG41_CTRL1 0x0c7c ++#define RTL8367C_SVLAN_MEMBERCFG41_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG41_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG41_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG41_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG41_CTRL2 0x0c7d ++#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG41_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG41_CTRL3 0x0c7e ++#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG41_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG42_CTRL1 0x0c7f ++#define RTL8367C_SVLAN_MEMBERCFG42_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG42_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG42_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG42_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG42_CTRL2 0x0c80 ++#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG42_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG42_CTRL3 0x0c81 ++#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG42_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG43_CTRL1 0x0c82 ++#define RTL8367C_SVLAN_MEMBERCFG43_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG43_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG43_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG43_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG43_CTRL2 0x0c83 ++#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG43_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG43_CTRL3 0x0c84 ++#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG43_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG44_CTRL1 0x0c85 ++#define RTL8367C_SVLAN_MEMBERCFG44_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG44_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG44_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG44_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG44_CTRL2 0x0c86 ++#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG44_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG44_CTRL3 0x0c87 ++#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG44_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG45_CTRL1 0x0c88 ++#define RTL8367C_SVLAN_MEMBERCFG45_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG45_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG45_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG45_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG45_CTRL2 0x0c89 ++#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG45_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG45_CTRL3 0x0c8a ++#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG45_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG46_CTRL1 0x0c8b ++#define RTL8367C_SVLAN_MEMBERCFG46_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG46_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG46_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG46_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG46_CTRL2 0x0c8c ++#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG46_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG46_CTRL3 0x0c8d ++#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG46_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG47_CTRL1 0x0c8e ++#define RTL8367C_SVLAN_MEMBERCFG47_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG47_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG47_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG47_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG47_CTRL2 0x0c8f ++#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG47_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG47_CTRL3 0x0c90 ++#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG47_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG48_CTRL1 0x0c91 ++#define RTL8367C_SVLAN_MEMBERCFG48_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG48_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG48_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG48_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG48_CTRL2 0x0c92 ++#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG48_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG48_CTRL3 0x0c93 ++#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG48_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG49_CTRL1 0x0c94 ++#define RTL8367C_SVLAN_MEMBERCFG49_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG49_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG49_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG49_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG49_CTRL2 0x0c95 ++#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG49_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG49_CTRL3 0x0c96 ++#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG49_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG50_CTRL1 0x0c97 ++#define RTL8367C_SVLAN_MEMBERCFG50_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG50_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG50_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG50_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG50_CTRL2 0x0c98 ++#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG50_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG50_CTRL3 0x0c99 ++#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG50_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG51_CTRL1 0x0c9a ++#define RTL8367C_SVLAN_MEMBERCFG51_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG51_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG51_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG51_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG51_CTRL2 0x0c9b ++#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG51_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG51_CTRL3 0x0c9c ++#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG51_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG52_CTRL1 0x0c9d ++#define RTL8367C_SVLAN_MEMBERCFG52_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG52_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG52_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG52_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG52_CTRL2 0x0c9e ++#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG52_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG52_CTRL3 0x0c9f ++#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG52_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG53_CTRL1 0x0ca0 ++#define RTL8367C_SVLAN_MEMBERCFG53_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG53_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG53_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG53_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG53_CTRL2 0x0ca1 ++#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG53_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG53_CTRL3 0x0ca2 ++#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG53_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG54_CTRL1 0x0ca3 ++#define RTL8367C_SVLAN_MEMBERCFG54_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG54_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG54_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG54_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG54_CTRL2 0x0ca4 ++#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG54_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG54_CTRL3 0x0ca5 ++#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG54_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG55_CTRL1 0x0ca6 ++#define RTL8367C_SVLAN_MEMBERCFG55_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG55_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG55_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG55_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG55_CTRL2 0x0ca7 ++#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG55_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG55_CTRL3 0x0ca8 ++#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG55_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG56_CTRL1 0x0ca9 ++#define RTL8367C_SVLAN_MEMBERCFG56_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG56_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG56_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG56_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG56_CTRL2 0x0caa ++#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG56_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG56_CTRL3 0x0cab ++#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG56_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG57_CTRL1 0x0cac ++#define RTL8367C_SVLAN_MEMBERCFG57_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG57_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG57_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG57_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG57_CTRL2 0x0cad ++#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG57_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG57_CTRL3 0x0cae ++#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG57_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG58_CTRL1 0x0caf ++#define RTL8367C_SVLAN_MEMBERCFG58_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG58_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG58_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG58_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG58_CTRL2 0x0cb0 ++#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG58_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG58_CTRL3 0x0cb1 ++#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG58_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG59_CTRL1 0x0cb2 ++#define RTL8367C_SVLAN_MEMBERCFG59_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG59_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG59_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG59_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG59_CTRL2 0x0cb3 ++#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG59_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG59_CTRL3 0x0cb4 ++#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG59_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG60_CTRL1 0x0cb5 ++#define RTL8367C_SVLAN_MEMBERCFG60_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG60_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG60_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG60_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG60_CTRL2 0x0cb6 ++#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG60_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG60_CTRL3 0x0cb7 ++#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG60_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG61_CTRL1 0x0cb8 ++#define RTL8367C_SVLAN_MEMBERCFG61_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG61_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG61_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG61_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG61_CTRL2 0x0cb9 ++#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG61_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG61_CTRL3 0x0cba ++#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG61_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG62_CTRL1 0x0cbb ++#define RTL8367C_SVLAN_MEMBERCFG62_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG62_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG62_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG62_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG62_CTRL2 0x0cbc ++#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG62_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG62_CTRL3 0x0cbd ++#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG62_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL1 0x0cbe ++#define RTL8367C_SVLAN_MEMBERCFG63_CTRL1_VS_UNTAGSET_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG63_CTRL1_VS_UNTAGSET_MASK 0xFF00 ++#define RTL8367C_SVLAN_MEMBERCFG63_CTRL1_VS_SMBR_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG63_CTRL1_VS_SMBR_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL2 0x0cbf ++#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_FIDEN_OFFSET 7 ++#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_FIDEN_MASK 0x80 ++#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_SPRI_OFFSET 4 ++#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_SPRI_MASK 0x70 ++#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_FID_MSTI_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG63_CTRL2_VS_FID_MSTI_MASK 0xF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL3 0x0cc0 ++#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_EFID_OFFSET 13 ++#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_EFID_MASK 0xE000 ++#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_EFIDEN_OFFSET 12 ++#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_EFIDEN_MASK 0x1000 ++#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_SVID_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG63_CTRL3_VS_SVID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL4 0x0cc1 ++#define RTL8367C_SVLAN_MEMBERCFG0_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG0_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG0_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG0_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG1_CTRL4 0x0cc2 ++#define RTL8367C_SVLAN_MEMBERCFG1_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG1_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG1_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG1_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG2_CTRL4 0x0cc3 ++#define RTL8367C_SVLAN_MEMBERCFG2_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG2_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG2_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG2_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG3_CTRL4 0x0cc4 ++#define RTL8367C_SVLAN_MEMBERCFG3_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG3_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG3_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG3_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG4_CTRL4 0x0cc5 ++#define RTL8367C_SVLAN_MEMBERCFG4_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG4_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG4_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG4_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG5_CTRL4 0x0cc6 ++#define RTL8367C_SVLAN_MEMBERCFG5_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG5_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG5_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG5_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG6_CTRL4 0x0cc7 ++#define RTL8367C_SVLAN_MEMBERCFG6_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG6_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG6_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG6_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG7_CTRL4 0x0cc8 ++#define RTL8367C_SVLAN_MEMBERCFG7_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG7_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG7_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG7_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG8_CTRL4 0x0cc9 ++#define RTL8367C_SVLAN_MEMBERCFG8_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG8_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG8_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG8_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG9_CTRL4 0x0cca ++#define RTL8367C_SVLAN_MEMBERCFG9_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG9_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG9_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG9_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG10_CTRL4 0x0ccb ++#define RTL8367C_SVLAN_MEMBERCFG10_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG10_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG10_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG10_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG11_CTRL4 0x0ccc ++#define RTL8367C_SVLAN_MEMBERCFG11_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG11_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG11_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG11_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG12_CTRL4 0x0ccd ++#define RTL8367C_SVLAN_MEMBERCFG12_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG12_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG12_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG12_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG13_CTRL4 0x0cce ++#define RTL8367C_SVLAN_MEMBERCFG13_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG13_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG13_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG13_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG14_CTRL4 0x0ccf ++#define RTL8367C_SVLAN_MEMBERCFG14_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG14_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG14_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG14_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG15_CTRL4 0x0cd0 ++#define RTL8367C_SVLAN_MEMBERCFG15_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG15_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG15_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG15_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG16_CTRL4 0x0cd1 ++#define RTL8367C_SVLAN_MEMBERCFG16_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG16_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG16_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG16_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG17_CTRL4 0x0cd2 ++#define RTL8367C_SVLAN_MEMBERCFG17_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG17_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG17_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG17_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG18_CTRL4 0x0cd3 ++#define RTL8367C_SVLAN_MEMBERCFG18_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG18_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG18_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG18_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG19_CTRL4 0x0cd4 ++#define RTL8367C_SVLAN_MEMBERCFG19_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG19_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG19_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG19_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG20_CTRL4 0x0cd5 ++#define RTL8367C_SVLAN_MEMBERCFG20_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG20_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG20_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG20_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG21_CTRL4 0x0cd6 ++#define RTL8367C_SVLAN_MEMBERCFG21_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG21_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG21_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG21_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG22_CTRL4 0x0cd7 ++#define RTL8367C_SVLAN_MEMBERCFG22_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG22_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG22_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG22_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG23_CTRL4 0x0cd8 ++#define RTL8367C_SVLAN_MEMBERCFG23_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG23_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG23_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG23_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG24_CTRL4 0x0cd9 ++#define RTL8367C_SVLAN_MEMBERCFG24_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG24_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG24_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG24_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG25_CTRL4 0x0cda ++#define RTL8367C_SVLAN_MEMBERCFG25_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG25_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG25_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG25_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG26_CTRL4 0x0cdb ++#define RTL8367C_SVLAN_MEMBERCFG26_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG26_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG26_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG26_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG27_CTRL4 0x0cdc ++#define RTL8367C_SVLAN_MEMBERCFG27_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG27_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG27_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG27_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG28_CTRL4 0x0cdd ++#define RTL8367C_SVLAN_MEMBERCFG28_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG28_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG28_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG28_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG29_CTRL4 0x0cde ++#define RTL8367C_SVLAN_MEMBERCFG29_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG29_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG29_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG29_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG30_CTRL4 0x0cdf ++#define RTL8367C_SVLAN_MEMBERCFG30_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG30_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG30_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG30_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG31_CTRL4 0x0ce0 ++#define RTL8367C_SVLAN_MEMBERCFG31_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG31_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG31_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG31_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG32_CTRL4 0x0ce1 ++#define RTL8367C_SVLAN_MEMBERCFG32_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG32_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG32_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG32_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG33_CTRL4 0x0ce2 ++#define RTL8367C_SVLAN_MEMBERCFG33_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG33_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG33_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG33_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG34_CTRL4 0x0ce3 ++#define RTL8367C_SVLAN_MEMBERCFG34_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG34_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG34_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG34_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG35_CTRL4 0x0ce4 ++#define RTL8367C_SVLAN_MEMBERCFG35_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG35_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG35_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG35_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG36_CTRL4 0x0ce5 ++#define RTL8367C_SVLAN_MEMBERCFG36_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG36_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG36_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG36_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG37_CTRL4 0x0ce6 ++#define RTL8367C_SVLAN_MEMBERCFG37_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG37_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG37_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG37_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG38_CTRL4 0x0ce7 ++#define RTL8367C_SVLAN_MEMBERCFG38_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG38_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG38_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG38_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG39_CTRL4 0x0ce8 ++#define RTL8367C_SVLAN_MEMBERCFG39_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG39_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG39_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG39_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG40_CTRL4 0x0ce9 ++#define RTL8367C_SVLAN_MEMBERCFG40_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG40_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG40_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG40_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG41_CTRL4 0x0cea ++#define RTL8367C_SVLAN_MEMBERCFG41_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG41_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG41_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG41_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG42_CTRL4 0x0ceb ++#define RTL8367C_SVLAN_MEMBERCFG42_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG42_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG42_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG42_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG43_CTRL4 0x0cec ++#define RTL8367C_SVLAN_MEMBERCFG43_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG43_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG43_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG43_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG44_CTRL4 0x0ced ++#define RTL8367C_SVLAN_MEMBERCFG44_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG44_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG44_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG44_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG45_CTRL4 0x0cee ++#define RTL8367C_SVLAN_MEMBERCFG45_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG45_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG45_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG45_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG46_CTRL4 0x0cef ++#define RTL8367C_SVLAN_MEMBERCFG46_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG46_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG46_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG46_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG47_CTRL4 0x0cf0 ++#define RTL8367C_SVLAN_MEMBERCFG47_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG47_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG47_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG47_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG48_CTRL4 0x0cf1 ++#define RTL8367C_SVLAN_MEMBERCFG48_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG48_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG48_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG48_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG49_CTRL4 0x0cf2 ++#define RTL8367C_SVLAN_MEMBERCFG49_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG49_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG49_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG49_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG50_CTRL4 0x0cf3 ++#define RTL8367C_SVLAN_MEMBERCFG50_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG50_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG50_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG50_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG51_CTRL4 0x0cf4 ++#define RTL8367C_SVLAN_MEMBERCFG51_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG51_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG51_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG51_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG52_CTRL4 0x0cf5 ++#define RTL8367C_SVLAN_MEMBERCFG52_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG52_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG52_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG52_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG53_CTRL4 0x0cf6 ++#define RTL8367C_SVLAN_MEMBERCFG53_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG53_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG53_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG53_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG54_CTRL4 0x0cf7 ++#define RTL8367C_SVLAN_MEMBERCFG54_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG54_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG54_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG54_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG55_CTRL4 0x0cf8 ++#define RTL8367C_SVLAN_MEMBERCFG55_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG55_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG55_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG55_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG56_CTRL4 0x0cf9 ++#define RTL8367C_SVLAN_MEMBERCFG56_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG56_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG56_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG56_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG57_CTRL4 0x0cfa ++#define RTL8367C_SVLAN_MEMBERCFG57_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG57_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG57_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG57_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG58_CTRL4 0x0cfb ++#define RTL8367C_SVLAN_MEMBERCFG58_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG58_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG58_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG58_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG59_CTRL4 0x0cfc ++#define RTL8367C_SVLAN_MEMBERCFG59_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG59_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG59_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG59_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG60_CTRL4 0x0cfd ++#define RTL8367C_SVLAN_MEMBERCFG60_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG60_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG60_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG60_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG61_CTRL4 0x0cfe ++#define RTL8367C_SVLAN_MEMBERCFG61_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG61_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG61_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG61_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG62_CTRL4 0x0cff ++#define RTL8367C_SVLAN_MEMBERCFG62_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG62_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG62_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG62_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_C2SCFG0_CTRL0 0x0d00 ++#define RTL8367C_SVLAN_C2SCFG0_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG0_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG0_CTRL1 0x0d01 ++#define RTL8367C_SVLAN_C2SCFG0_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG0_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG0_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG0_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG0_CTRL2 0x0d02 ++#define RTL8367C_SVLAN_C2SCFG0_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG0_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG1_CTRL0 0x0d03 ++#define RTL8367C_SVLAN_C2SCFG1_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG1_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG1_CTRL1 0x0d04 ++#define RTL8367C_SVLAN_C2SCFG1_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG1_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG1_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG1_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG1_CTRL2 0x0d05 ++#define RTL8367C_SVLAN_C2SCFG1_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG1_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG2_CTRL0 0x0d06 ++#define RTL8367C_SVLAN_C2SCFG2_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG2_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG2_CTRL1 0x0d07 ++#define RTL8367C_SVLAN_C2SCFG2_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG2_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG2_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG2_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG2_CTRL2 0x0d08 ++#define RTL8367C_SVLAN_C2SCFG2_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG2_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG3_CTRL0 0x0d09 ++#define RTL8367C_SVLAN_C2SCFG3_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG3_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG3_CTRL1 0x0d0a ++#define RTL8367C_SVLAN_C2SCFG3_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG3_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG3_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG3_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG3_CTRL2 0x0d0b ++#define RTL8367C_SVLAN_C2SCFG3_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG3_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG4_CTRL0 0x0d0c ++#define RTL8367C_SVLAN_C2SCFG4_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG4_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG4_CTRL1 0x0d0d ++#define RTL8367C_SVLAN_C2SCFG4_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG4_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG4_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG4_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG4_CTRL2 0x0d0e ++#define RTL8367C_SVLAN_C2SCFG4_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG4_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG5_CTRL0 0x0d0f ++#define RTL8367C_SVLAN_C2SCFG5_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG5_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG5_CTRL1 0x0d10 ++#define RTL8367C_SVLAN_C2SCFG5_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG5_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG5_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG5_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG5_CTRL2 0x0d11 ++#define RTL8367C_SVLAN_C2SCFG5_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG5_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG6_CTRL0 0x0d12 ++#define RTL8367C_SVLAN_C2SCFG6_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG6_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG6_CTRL1 0x0d13 ++#define RTL8367C_SVLAN_C2SCFG6_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG6_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG6_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG6_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG6_CTRL2 0x0d14 ++#define RTL8367C_SVLAN_C2SCFG6_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG6_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG7_CTRL0 0x0d15 ++#define RTL8367C_SVLAN_C2SCFG7_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG7_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG7_CTRL1 0x0d16 ++#define RTL8367C_SVLAN_C2SCFG7_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG7_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG7_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG7_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG7_CTRL2 0x0d17 ++#define RTL8367C_SVLAN_C2SCFG7_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG7_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG8_CTRL0 0x0d18 ++#define RTL8367C_SVLAN_C2SCFG8_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG8_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG8_CTRL1 0x0d19 ++#define RTL8367C_SVLAN_C2SCFG8_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG8_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG8_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG8_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG8_CTRL2 0x0d1a ++#define RTL8367C_SVLAN_C2SCFG8_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG8_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG9_CTRL0 0x0d1b ++#define RTL8367C_SVLAN_C2SCFG9_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG9_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG9_CTRL1 0x0d1c ++#define RTL8367C_SVLAN_C2SCFG9_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG9_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG9_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG9_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG9_CTRL2 0x0d1d ++#define RTL8367C_SVLAN_C2SCFG9_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG9_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG10_CTRL0 0x0d1e ++#define RTL8367C_SVLAN_C2SCFG10_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG10_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG10_CTRL1 0x0d1f ++#define RTL8367C_SVLAN_C2SCFG10_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG10_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG10_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG10_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG10_CTRL2 0x0d20 ++#define RTL8367C_SVLAN_C2SCFG10_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG10_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG11_CTRL0 0x0d21 ++#define RTL8367C_SVLAN_C2SCFG11_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG11_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG11_CTRL1 0x0d22 ++#define RTL8367C_SVLAN_C2SCFG11_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG11_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG11_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG11_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG11_CTRL2 0x0d23 ++#define RTL8367C_SVLAN_C2SCFG11_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG11_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG12_CTRL0 0x0d24 ++#define RTL8367C_SVLAN_C2SCFG12_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG12_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG12_CTRL1 0x0d25 ++#define RTL8367C_SVLAN_C2SCFG12_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG12_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG12_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG12_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG12_CTRL2 0x0d26 ++#define RTL8367C_SVLAN_C2SCFG12_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG12_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG13_CTRL0 0x0d27 ++#define RTL8367C_SVLAN_C2SCFG13_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG13_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG13_CTRL1 0x0d28 ++#define RTL8367C_SVLAN_C2SCFG13_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG13_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG13_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG13_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG13_CTRL2 0x0d29 ++#define RTL8367C_SVLAN_C2SCFG13_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG13_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG14_CTRL0 0x0d2a ++#define RTL8367C_SVLAN_C2SCFG14_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG14_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG14_CTRL1 0x0d2b ++#define RTL8367C_SVLAN_C2SCFG14_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG14_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG14_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG14_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG14_CTRL2 0x0d2c ++#define RTL8367C_SVLAN_C2SCFG14_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG14_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG15_CTRL0 0x0d2d ++#define RTL8367C_SVLAN_C2SCFG15_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG15_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG15_CTRL1 0x0d2e ++#define RTL8367C_SVLAN_C2SCFG15_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG15_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG15_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG15_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG15_CTRL2 0x0d2f ++#define RTL8367C_SVLAN_C2SCFG15_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG15_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG16_CTRL0 0x0d30 ++#define RTL8367C_SVLAN_C2SCFG16_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG16_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG16_CTRL1 0x0d31 ++#define RTL8367C_SVLAN_C2SCFG16_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG16_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG16_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG16_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG16_CTRL2 0x0d32 ++#define RTL8367C_SVLAN_C2SCFG16_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG16_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG17_CTRL0 0x0d33 ++#define RTL8367C_SVLAN_C2SCFG17_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG17_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG17_CTRL1 0x0d34 ++#define RTL8367C_SVLAN_C2SCFG17_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG17_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG17_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG17_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG17_CTRL2 0x0d35 ++#define RTL8367C_SVLAN_C2SCFG17_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG17_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG18_CTRL0 0x0d36 ++#define RTL8367C_SVLAN_C2SCFG18_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG18_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG18_CTRL1 0x0d37 ++#define RTL8367C_SVLAN_C2SCFG18_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG18_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG18_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG18_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG18_CTRL2 0x0d38 ++#define RTL8367C_SVLAN_C2SCFG18_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG18_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG19_CTRL0 0x0d39 ++#define RTL8367C_SVLAN_C2SCFG19_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG19_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG19_CTRL1 0x0d3a ++#define RTL8367C_SVLAN_C2SCFG19_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG19_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG19_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG19_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG19_CTRL2 0x0d3b ++#define RTL8367C_SVLAN_C2SCFG19_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG19_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG20_CTRL0 0x0d3c ++#define RTL8367C_SVLAN_C2SCFG20_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG20_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG20_CTRL1 0x0d3d ++#define RTL8367C_SVLAN_C2SCFG20_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG20_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG20_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG20_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG20_CTRL2 0x0d3e ++#define RTL8367C_SVLAN_C2SCFG20_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG20_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG21_CTRL0 0x0d3f ++#define RTL8367C_SVLAN_C2SCFG21_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG21_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG21_CTRL1 0x0d40 ++#define RTL8367C_SVLAN_C2SCFG21_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG21_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG21_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG21_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG21_CTRL2 0x0d41 ++#define RTL8367C_SVLAN_C2SCFG21_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG21_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG22_CTRL0 0x0d42 ++#define RTL8367C_SVLAN_C2SCFG22_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG22_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG22_CTRL1 0x0d43 ++#define RTL8367C_SVLAN_C2SCFG22_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG22_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG22_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG22_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG22_CTRL2 0x0d44 ++#define RTL8367C_SVLAN_C2SCFG22_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG22_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG23_CTRL0 0x0d45 ++#define RTL8367C_SVLAN_C2SCFG23_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG23_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG23_CTRL1 0x0d46 ++#define RTL8367C_SVLAN_C2SCFG23_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG23_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG23_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG23_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG23_CTRL2 0x0d47 ++#define RTL8367C_SVLAN_C2SCFG23_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG23_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG24_CTRL0 0x0d48 ++#define RTL8367C_SVLAN_C2SCFG24_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG24_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG24_CTRL1 0x0d49 ++#define RTL8367C_SVLAN_C2SCFG24_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG24_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG24_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG24_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG24_CTRL2 0x0d4a ++#define RTL8367C_SVLAN_C2SCFG24_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG24_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG25_CTRL0 0x0d4b ++#define RTL8367C_SVLAN_C2SCFG25_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG25_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG25_CTRL1 0x0d4c ++#define RTL8367C_SVLAN_C2SCFG25_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG25_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG25_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG25_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG25_CTRL2 0x0d4d ++#define RTL8367C_SVLAN_C2SCFG25_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG25_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG26_CTRL0 0x0d4e ++#define RTL8367C_SVLAN_C2SCFG26_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG26_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG26_CTRL1 0x0d4f ++#define RTL8367C_SVLAN_C2SCFG26_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG26_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG26_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG26_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG26_CTRL2 0x0d50 ++#define RTL8367C_SVLAN_C2SCFG26_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG26_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG27_CTRL0 0x0d51 ++#define RTL8367C_SVLAN_C2SCFG27_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG27_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG27_CTRL1 0x0d52 ++#define RTL8367C_SVLAN_C2SCFG27_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG27_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG27_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG27_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG27_CTRL2 0x0d53 ++#define RTL8367C_SVLAN_C2SCFG27_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG27_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG28_CTRL0 0x0d54 ++#define RTL8367C_SVLAN_C2SCFG28_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG28_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG28_CTRL1 0x0d55 ++#define RTL8367C_SVLAN_C2SCFG28_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG28_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG28_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG28_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG28_CTRL2 0x0d56 ++#define RTL8367C_SVLAN_C2SCFG28_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG28_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG29_CTRL0 0x0d57 ++#define RTL8367C_SVLAN_C2SCFG29_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG29_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG29_CTRL1 0x0d58 ++#define RTL8367C_SVLAN_C2SCFG29_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG29_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG29_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG29_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG29_CTRL2 0x0d59 ++#define RTL8367C_SVLAN_C2SCFG29_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG29_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG30_CTRL0 0x0d5a ++#define RTL8367C_SVLAN_C2SCFG30_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG30_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG30_CTRL1 0x0d5b ++#define RTL8367C_SVLAN_C2SCFG30_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG30_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG30_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG30_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG30_CTRL2 0x0d5c ++#define RTL8367C_SVLAN_C2SCFG30_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG30_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG31_CTRL0 0x0d5d ++#define RTL8367C_SVLAN_C2SCFG31_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG31_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG31_CTRL1 0x0d5e ++#define RTL8367C_SVLAN_C2SCFG31_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG31_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG31_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG31_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG31_CTRL2 0x0d5f ++#define RTL8367C_SVLAN_C2SCFG31_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG31_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG32_CTRL0 0x0d60 ++#define RTL8367C_SVLAN_C2SCFG32_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG32_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG32_CTRL1 0x0d61 ++#define RTL8367C_SVLAN_C2SCFG32_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG32_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG32_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG32_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG32_CTRL2 0x0d62 ++#define RTL8367C_SVLAN_C2SCFG32_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG32_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG33_CTRL0 0x0d63 ++#define RTL8367C_SVLAN_C2SCFG33_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG33_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG33_CTRL1 0x0d64 ++#define RTL8367C_SVLAN_C2SCFG33_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG33_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG33_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG33_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG33_CTRL2 0x0d65 ++#define RTL8367C_SVLAN_C2SCFG33_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG33_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG34_CTRL0 0x0d66 ++#define RTL8367C_SVLAN_C2SCFG34_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG34_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG34_CTRL1 0x0d67 ++#define RTL8367C_SVLAN_C2SCFG34_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG34_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG34_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG34_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG34_CTRL2 0x0d68 ++#define RTL8367C_SVLAN_C2SCFG34_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG34_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG35_CTRL0 0x0d69 ++#define RTL8367C_SVLAN_C2SCFG35_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG35_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG35_CTRL1 0x0d6a ++#define RTL8367C_SVLAN_C2SCFG35_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG35_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG35_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG35_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG35_CTRL2 0x0d6b ++#define RTL8367C_SVLAN_C2SCFG35_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG35_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG36_CTRL0 0x0d6c ++#define RTL8367C_SVLAN_C2SCFG36_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG36_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG36_CTRL1 0x0d6d ++#define RTL8367C_SVLAN_C2SCFG36_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG36_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG36_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG36_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG36_CTRL2 0x0d6e ++#define RTL8367C_SVLAN_C2SCFG36_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG36_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG37_CTRL0 0x0d6f ++#define RTL8367C_SVLAN_C2SCFG37_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG37_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG37_CTRL1 0x0d70 ++#define RTL8367C_SVLAN_C2SCFG37_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG37_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG37_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG37_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG37_CTRL2 0x0d71 ++#define RTL8367C_SVLAN_C2SCFG37_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG37_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG38_CTRL0 0x0d72 ++#define RTL8367C_SVLAN_C2SCFG38_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG38_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG38_CTRL1 0x0d73 ++#define RTL8367C_SVLAN_C2SCFG38_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG38_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG38_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG38_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG38_CTRL2 0x0d74 ++#define RTL8367C_SVLAN_C2SCFG38_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG38_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG39_CTRL0 0x0d75 ++#define RTL8367C_SVLAN_C2SCFG39_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG39_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG39_CTRL1 0x0d76 ++#define RTL8367C_SVLAN_C2SCFG39_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG39_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG39_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG39_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG39_CTRL2 0x0d77 ++#define RTL8367C_SVLAN_C2SCFG39_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG39_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG40_CTRL0 0x0d78 ++#define RTL8367C_SVLAN_C2SCFG40_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG40_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG40_CTRL1 0x0d79 ++#define RTL8367C_SVLAN_C2SCFG40_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG40_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG40_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG40_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG40_CTRL2 0x0d7a ++#define RTL8367C_SVLAN_C2SCFG40_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG40_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG41_CTRL0 0x0d7b ++#define RTL8367C_SVLAN_C2SCFG41_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG41_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG41_CTRL1 0x0d7c ++#define RTL8367C_SVLAN_C2SCFG41_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG41_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG41_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG41_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG41_CTRL2 0x0d7d ++#define RTL8367C_SVLAN_C2SCFG41_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG41_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG42_CTRL0 0x0d7e ++#define RTL8367C_SVLAN_C2SCFG42_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG42_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG42_CTRL1 0x0d7f ++#define RTL8367C_SVLAN_C2SCFG42_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG42_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG42_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG42_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG42_CTRL2 0x0d80 ++#define RTL8367C_SVLAN_C2SCFG42_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG42_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG43_CTRL0 0x0d81 ++#define RTL8367C_SVLAN_C2SCFG43_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG43_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG43_CTRL1 0x0d82 ++#define RTL8367C_SVLAN_C2SCFG43_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG43_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG43_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG43_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG43_CTRL2 0x0d83 ++#define RTL8367C_SVLAN_C2SCFG43_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG43_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG44_CTRL0 0x0d84 ++#define RTL8367C_SVLAN_C2SCFG44_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG44_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG44_CTRL1 0x0d85 ++#define RTL8367C_SVLAN_C2SCFG44_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG44_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG44_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG44_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG44_CTRL2 0x0d86 ++#define RTL8367C_SVLAN_C2SCFG44_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG44_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG45_CTRL0 0x0d87 ++#define RTL8367C_SVLAN_C2SCFG45_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG45_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG45_CTRL1 0x0d88 ++#define RTL8367C_SVLAN_C2SCFG45_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG45_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG45_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG45_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG45_CTRL2 0x0d89 ++#define RTL8367C_SVLAN_C2SCFG45_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG45_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG46_CTRL0 0x0d8a ++#define RTL8367C_SVLAN_C2SCFG46_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG46_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG46_CTRL1 0x0d8b ++#define RTL8367C_SVLAN_C2SCFG46_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG46_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG46_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG46_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG46_CTRL2 0x0d8c ++#define RTL8367C_SVLAN_C2SCFG46_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG46_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG47_CTRL0 0x0d8d ++#define RTL8367C_SVLAN_C2SCFG47_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG47_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG47_CTRL1 0x0d8e ++#define RTL8367C_SVLAN_C2SCFG47_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG47_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG47_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG47_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG47_CTRL2 0x0d8f ++#define RTL8367C_SVLAN_C2SCFG47_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG47_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG48_CTRL0 0x0d90 ++#define RTL8367C_SVLAN_C2SCFG48_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG48_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG48_CTRL1 0x0d91 ++#define RTL8367C_SVLAN_C2SCFG48_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG48_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG48_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG48_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG48_CTRL2 0x0d92 ++#define RTL8367C_SVLAN_C2SCFG48_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG48_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG49_CTRL0 0x0d93 ++#define RTL8367C_SVLAN_C2SCFG49_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG49_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG49_CTRL1 0x0d94 ++#define RTL8367C_SVLAN_C2SCFG49_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG49_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG49_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG49_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG49_CTRL2 0x0d95 ++#define RTL8367C_SVLAN_C2SCFG49_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG49_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG50_CTRL0 0x0d96 ++#define RTL8367C_SVLAN_C2SCFG50_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG50_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG50_CTRL1 0x0d97 ++#define RTL8367C_SVLAN_C2SCFG50_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG50_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG50_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG50_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG50_CTRL2 0x0d98 ++#define RTL8367C_SVLAN_C2SCFG50_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG50_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG51_CTRL0 0x0d99 ++#define RTL8367C_SVLAN_C2SCFG51_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG51_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG51_CTRL1 0x0d9a ++#define RTL8367C_SVLAN_C2SCFG51_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG51_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG51_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG51_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG51_CTRL2 0x0d9b ++#define RTL8367C_SVLAN_C2SCFG51_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG51_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG52_CTRL0 0x0d9c ++#define RTL8367C_SVLAN_C2SCFG52_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG52_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG52_CTRL1 0x0d9d ++#define RTL8367C_SVLAN_C2SCFG52_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG52_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG52_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG52_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG52_CTRL2 0x0d9e ++#define RTL8367C_SVLAN_C2SCFG52_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG52_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG53_CTRL0 0x0d9f ++#define RTL8367C_SVLAN_C2SCFG53_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG53_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG53_CTRL1 0x0da0 ++#define RTL8367C_SVLAN_C2SCFG53_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG53_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG53_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG53_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG53_CTRL2 0x0da1 ++#define RTL8367C_SVLAN_C2SCFG53_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG53_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG54_CTRL0 0x0da2 ++#define RTL8367C_SVLAN_C2SCFG54_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG54_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG54_CTRL1 0x0da3 ++#define RTL8367C_SVLAN_C2SCFG54_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG54_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG54_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG54_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG54_CTRL2 0x0da4 ++#define RTL8367C_SVLAN_C2SCFG54_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG54_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG55_CTRL0 0x0da5 ++#define RTL8367C_SVLAN_C2SCFG55_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG55_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG55_CTRL1 0x0da6 ++#define RTL8367C_SVLAN_C2SCFG55_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG55_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG55_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG55_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG55_CTRL2 0x0da7 ++#define RTL8367C_SVLAN_C2SCFG55_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG55_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG56_CTRL0 0x0da8 ++#define RTL8367C_SVLAN_C2SCFG56_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG56_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG56_CTRL1 0x0da9 ++#define RTL8367C_SVLAN_C2SCFG56_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG56_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG56_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG56_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG56_CTRL2 0x0daa ++#define RTL8367C_SVLAN_C2SCFG56_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG56_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG57_CTRL0 0x0dab ++#define RTL8367C_SVLAN_C2SCFG57_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG57_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG57_CTRL1 0x0dac ++#define RTL8367C_SVLAN_C2SCFG57_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG57_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG57_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG57_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG57_CTRL2 0x0dad ++#define RTL8367C_SVLAN_C2SCFG57_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG57_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG58_CTRL0 0x0dae ++#define RTL8367C_SVLAN_C2SCFG58_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG58_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG58_CTRL1 0x0daf ++#define RTL8367C_SVLAN_C2SCFG58_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG58_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG58_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG58_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG58_CTRL2 0x0db0 ++#define RTL8367C_SVLAN_C2SCFG58_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG58_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG59_CTRL0 0x0db1 ++#define RTL8367C_SVLAN_C2SCFG59_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG59_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG59_CTRL1 0x0db2 ++#define RTL8367C_SVLAN_C2SCFG59_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG59_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG59_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG59_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG59_CTRL2 0x0db3 ++#define RTL8367C_SVLAN_C2SCFG59_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG59_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG60_CTRL0 0x0db4 ++#define RTL8367C_SVLAN_C2SCFG60_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG60_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG60_CTRL1 0x0db5 ++#define RTL8367C_SVLAN_C2SCFG60_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG60_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG60_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG60_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG60_CTRL2 0x0db6 ++#define RTL8367C_SVLAN_C2SCFG60_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG60_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG61_CTRL0 0x0db7 ++#define RTL8367C_SVLAN_C2SCFG61_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG61_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG61_CTRL1 0x0db8 ++#define RTL8367C_SVLAN_C2SCFG61_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG61_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG61_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG61_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG61_CTRL2 0x0db9 ++#define RTL8367C_SVLAN_C2SCFG61_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG61_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG62_CTRL0 0x0dba ++#define RTL8367C_SVLAN_C2SCFG62_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG62_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG62_CTRL1 0x0dbb ++#define RTL8367C_SVLAN_C2SCFG62_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG62_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG62_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG62_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG62_CTRL2 0x0dbc ++#define RTL8367C_SVLAN_C2SCFG62_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG62_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG63_CTRL0 0x0dbd ++#define RTL8367C_SVLAN_C2SCFG63_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG63_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG63_CTRL1 0x0dbe ++#define RTL8367C_SVLAN_C2SCFG63_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG63_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG63_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG63_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG63_CTRL2 0x0dbf ++#define RTL8367C_SVLAN_C2SCFG63_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG63_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG64_CTRL0 0x0dc0 ++#define RTL8367C_SVLAN_C2SCFG64_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG64_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG64_CTRL1 0x0dc1 ++#define RTL8367C_SVLAN_C2SCFG64_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG64_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG64_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG64_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG64_CTRL2 0x0dc2 ++#define RTL8367C_SVLAN_C2SCFG64_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG64_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG65_CTRL0 0x0dc3 ++#define RTL8367C_SVLAN_C2SCFG65_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG65_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG65_CTRL1 0x0dc4 ++#define RTL8367C_SVLAN_C2SCFG65_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG65_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG65_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG65_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG65_CTRL2 0x0dc5 ++#define RTL8367C_SVLAN_C2SCFG65_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG65_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG66_CTRL0 0x0dc6 ++#define RTL8367C_SVLAN_C2SCFG66_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG66_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG66_CTRL1 0x0dc7 ++#define RTL8367C_SVLAN_C2SCFG66_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG66_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG66_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG66_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG66_CTRL2 0x0dc8 ++#define RTL8367C_SVLAN_C2SCFG66_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG66_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG67_CTRL0 0x0dc9 ++#define RTL8367C_SVLAN_C2SCFG67_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG67_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG67_CTRL1 0x0dca ++#define RTL8367C_SVLAN_C2SCFG67_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG67_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG67_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG67_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG67_CTRL2 0x0dcb ++#define RTL8367C_SVLAN_C2SCFG67_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG67_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG68_CTRL0 0x0dcc ++#define RTL8367C_SVLAN_C2SCFG68_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG68_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG68_CTRL1 0x0dcd ++#define RTL8367C_SVLAN_C2SCFG68_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG68_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG68_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG68_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG68_CTRL2 0x0dce ++#define RTL8367C_SVLAN_C2SCFG68_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG68_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG69_CTRL0 0x0dcf ++#define RTL8367C_SVLAN_C2SCFG69_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG69_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG69_CTRL1 0x0dd0 ++#define RTL8367C_SVLAN_C2SCFG69_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG69_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG69_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG69_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG69_CTRL2 0x0dd1 ++#define RTL8367C_SVLAN_C2SCFG69_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG69_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG70_CTRL0 0x0dd2 ++#define RTL8367C_SVLAN_C2SCFG70_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG70_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG70_CTRL1 0x0dd3 ++#define RTL8367C_SVLAN_C2SCFG70_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG70_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG70_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG70_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG70_CTRL2 0x0dd4 ++#define RTL8367C_SVLAN_C2SCFG70_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG70_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG71_CTRL0 0x0dd5 ++#define RTL8367C_SVLAN_C2SCFG71_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG71_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG71_CTRL1 0x0dd6 ++#define RTL8367C_SVLAN_C2SCFG71_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG71_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG71_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG71_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG71_CTRL2 0x0dd7 ++#define RTL8367C_SVLAN_C2SCFG71_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG71_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG72_CTRL0 0x0dd8 ++#define RTL8367C_SVLAN_C2SCFG72_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG72_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG72_CTRL1 0x0dd9 ++#define RTL8367C_SVLAN_C2SCFG72_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG72_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG72_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG72_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG72_CTRL2 0x0dda ++#define RTL8367C_SVLAN_C2SCFG72_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG72_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG73_CTRL0 0x0ddb ++#define RTL8367C_SVLAN_C2SCFG73_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG73_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG73_CTRL1 0x0ddc ++#define RTL8367C_SVLAN_C2SCFG73_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG73_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG73_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG73_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG73_CTRL2 0x0ddd ++#define RTL8367C_SVLAN_C2SCFG73_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG73_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG74_CTRL0 0x0dde ++#define RTL8367C_SVLAN_C2SCFG74_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG74_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG74_CTRL1 0x0ddf ++#define RTL8367C_SVLAN_C2SCFG74_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG74_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG74_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG74_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG74_CTRL2 0x0de0 ++#define RTL8367C_SVLAN_C2SCFG74_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG74_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG75_CTRL0 0x0de1 ++#define RTL8367C_SVLAN_C2SCFG75_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG75_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG75_CTRL1 0x0de2 ++#define RTL8367C_SVLAN_C2SCFG75_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG75_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG75_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG75_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG75_CTRL2 0x0de3 ++#define RTL8367C_SVLAN_C2SCFG75_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG75_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG76_CTRL0 0x0de4 ++#define RTL8367C_SVLAN_C2SCFG76_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG76_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG76_CTRL1 0x0de5 ++#define RTL8367C_SVLAN_C2SCFG76_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG76_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG76_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG76_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG76_CTRL2 0x0de6 ++#define RTL8367C_SVLAN_C2SCFG76_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG76_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG77_CTRL0 0x0de7 ++#define RTL8367C_SVLAN_C2SCFG77_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG77_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG77_CTRL1 0x0de8 ++#define RTL8367C_SVLAN_C2SCFG77_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG77_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG77_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG77_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG77_CTRL2 0x0de9 ++#define RTL8367C_SVLAN_C2SCFG77_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG77_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG78_CTRL0 0x0dea ++#define RTL8367C_SVLAN_C2SCFG78_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG78_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG78_CTRL1 0x0deb ++#define RTL8367C_SVLAN_C2SCFG78_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG78_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG78_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG78_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG78_CTRL2 0x0dec ++#define RTL8367C_SVLAN_C2SCFG78_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG78_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG79_CTRL0 0x0ded ++#define RTL8367C_SVLAN_C2SCFG79_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG79_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG79_CTRL1 0x0dee ++#define RTL8367C_SVLAN_C2SCFG79_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG79_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG79_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG79_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG79_CTRL2 0x0def ++#define RTL8367C_SVLAN_C2SCFG79_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG79_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG80_CTRL0 0x0df0 ++#define RTL8367C_SVLAN_C2SCFG80_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG80_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG80_CTRL1 0x0df1 ++#define RTL8367C_SVLAN_C2SCFG80_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG80_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG80_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG80_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG80_CTRL2 0x0df2 ++#define RTL8367C_SVLAN_C2SCFG80_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG80_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG81_CTRL0 0x0df3 ++#define RTL8367C_SVLAN_C2SCFG81_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG81_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG81_CTRL1 0x0df4 ++#define RTL8367C_SVLAN_C2SCFG81_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG81_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG81_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG81_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG81_CTRL2 0x0df5 ++#define RTL8367C_SVLAN_C2SCFG81_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG81_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG82_CTRL0 0x0df6 ++#define RTL8367C_SVLAN_C2SCFG82_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG82_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG82_CTRL1 0x0df7 ++#define RTL8367C_SVLAN_C2SCFG82_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG82_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG82_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG82_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG82_CTRL2 0x0df8 ++#define RTL8367C_SVLAN_C2SCFG82_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG82_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG83_CTRL0 0x0df9 ++#define RTL8367C_SVLAN_C2SCFG83_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG83_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG83_CTRL1 0x0dfa ++#define RTL8367C_SVLAN_C2SCFG83_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG83_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG83_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG83_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG83_CTRL2 0x0dfb ++#define RTL8367C_SVLAN_C2SCFG83_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG83_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG84_CTRL0 0x0dfc ++#define RTL8367C_SVLAN_C2SCFG84_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG84_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG84_CTRL1 0x0dfd ++#define RTL8367C_SVLAN_C2SCFG84_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG84_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG84_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG84_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG84_CTRL2 0x0dfe ++#define RTL8367C_SVLAN_C2SCFG84_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG84_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG85_CTRL0 0x0dff ++#define RTL8367C_SVLAN_C2SCFG85_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG85_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG85_CTRL1 0x0e00 ++#define RTL8367C_SVLAN_C2SCFG85_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG85_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG85_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG85_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG85_CTRL2 0x0e01 ++#define RTL8367C_SVLAN_C2SCFG85_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG85_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG86_CTRL0 0x0e02 ++#define RTL8367C_SVLAN_C2SCFG86_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG86_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG86_CTRL1 0x0e03 ++#define RTL8367C_SVLAN_C2SCFG86_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG86_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG86_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG86_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG86_CTRL2 0x0e04 ++#define RTL8367C_SVLAN_C2SCFG86_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG86_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG87_CTRL0 0x0e05 ++#define RTL8367C_SVLAN_C2SCFG87_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG87_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG87_CTRL1 0x0e06 ++#define RTL8367C_SVLAN_C2SCFG87_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG87_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG87_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG87_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG87_CTRL2 0x0e07 ++#define RTL8367C_SVLAN_C2SCFG87_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG87_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG88_CTRL0 0x0e08 ++#define RTL8367C_SVLAN_C2SCFG88_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG88_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG88_CTRL1 0x0e09 ++#define RTL8367C_SVLAN_C2SCFG88_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG88_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG88_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG88_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG88_CTRL2 0x0e0a ++#define RTL8367C_SVLAN_C2SCFG88_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG88_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG89_CTRL0 0x0e0b ++#define RTL8367C_SVLAN_C2SCFG89_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG89_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG89_CTRL1 0x0e0c ++#define RTL8367C_SVLAN_C2SCFG89_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG89_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG89_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG89_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG89_CTRL2 0x0e0d ++#define RTL8367C_SVLAN_C2SCFG89_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG89_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG90_CTRL0 0x0e0e ++#define RTL8367C_SVLAN_C2SCFG90_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG90_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG90_CTRL1 0x0e0f ++#define RTL8367C_SVLAN_C2SCFG90_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG90_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG90_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG90_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG90_CTRL2 0x0e10 ++#define RTL8367C_SVLAN_C2SCFG90_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG90_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG91_CTRL0 0x0e11 ++#define RTL8367C_SVLAN_C2SCFG91_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG91_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG91_CTRL1 0x0e12 ++#define RTL8367C_SVLAN_C2SCFG91_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG91_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG91_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG91_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG91_CTRL2 0x0e13 ++#define RTL8367C_SVLAN_C2SCFG91_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG91_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG92_CTRL0 0x0e14 ++#define RTL8367C_SVLAN_C2SCFG92_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG92_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG92_CTRL1 0x0e15 ++#define RTL8367C_SVLAN_C2SCFG92_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG92_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG92_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG92_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG92_CTRL2 0x0e16 ++#define RTL8367C_SVLAN_C2SCFG92_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG92_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG93_CTRL0 0x0e17 ++#define RTL8367C_SVLAN_C2SCFG93_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG93_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG93_CTRL1 0x0e18 ++#define RTL8367C_SVLAN_C2SCFG93_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG93_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG93_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG93_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG93_CTRL2 0x0e19 ++#define RTL8367C_SVLAN_C2SCFG93_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG93_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG94_CTRL0 0x0e1a ++#define RTL8367C_SVLAN_C2SCFG94_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG94_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG94_CTRL1 0x0e1b ++#define RTL8367C_SVLAN_C2SCFG94_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG94_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG94_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG94_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG94_CTRL2 0x0e1c ++#define RTL8367C_SVLAN_C2SCFG94_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG94_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG95_CTRL0 0x0e1d ++#define RTL8367C_SVLAN_C2SCFG95_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG95_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG95_CTRL1 0x0e1e ++#define RTL8367C_SVLAN_C2SCFG95_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG95_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG95_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG95_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG95_CTRL2 0x0e1f ++#define RTL8367C_SVLAN_C2SCFG95_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG95_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG96_CTRL0 0x0e20 ++#define RTL8367C_SVLAN_C2SCFG96_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG96_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG96_CTRL1 0x0e21 ++#define RTL8367C_SVLAN_C2SCFG96_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG96_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG96_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG96_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG96_CTRL2 0x0e22 ++#define RTL8367C_SVLAN_C2SCFG96_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG96_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG97_CTRL0 0x0e23 ++#define RTL8367C_SVLAN_C2SCFG97_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG97_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG97_CTRL1 0x0e24 ++#define RTL8367C_SVLAN_C2SCFG97_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG97_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG97_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG97_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG97_CTRL2 0x0e25 ++#define RTL8367C_SVLAN_C2SCFG97_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG97_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG98_CTRL0 0x0e26 ++#define RTL8367C_SVLAN_C2SCFG98_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG98_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG98_CTRL1 0x0e27 ++#define RTL8367C_SVLAN_C2SCFG98_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG98_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG98_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG98_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG98_CTRL2 0x0e28 ++#define RTL8367C_SVLAN_C2SCFG98_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG98_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG99_CTRL0 0x0e29 ++#define RTL8367C_SVLAN_C2SCFG99_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG99_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG99_CTRL1 0x0e2a ++#define RTL8367C_SVLAN_C2SCFG99_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG99_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG99_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG99_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG99_CTRL2 0x0e2b ++#define RTL8367C_SVLAN_C2SCFG99_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG99_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG100_CTRL0 0x0e2c ++#define RTL8367C_SVLAN_C2SCFG100_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG100_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG100_CTRL1 0x0e2d ++#define RTL8367C_SVLAN_C2SCFG100_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG100_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG100_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG100_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG100_CTRL2 0x0e2e ++#define RTL8367C_SVLAN_C2SCFG100_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG100_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG101_CTRL0 0x0e2f ++#define RTL8367C_SVLAN_C2SCFG101_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG101_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG101_CTRL1 0x0e30 ++#define RTL8367C_SVLAN_C2SCFG101_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG101_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG101_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG101_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG101_CTRL2 0x0e31 ++#define RTL8367C_SVLAN_C2SCFG101_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG101_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG102_CTRL0 0x0e32 ++#define RTL8367C_SVLAN_C2SCFG102_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG102_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG102_CTRL1 0x0e33 ++#define RTL8367C_SVLAN_C2SCFG102_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG102_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG102_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG102_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG102_CTRL2 0x0e34 ++#define RTL8367C_SVLAN_C2SCFG102_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG102_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG103_CTRL0 0x0e35 ++#define RTL8367C_SVLAN_C2SCFG103_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG103_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG103_CTRL1 0x0e36 ++#define RTL8367C_SVLAN_C2SCFG103_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG103_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG103_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG103_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG103_CTRL2 0x0e37 ++#define RTL8367C_SVLAN_C2SCFG103_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG103_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG104_CTRL0 0x0e38 ++#define RTL8367C_SVLAN_C2SCFG104_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG104_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG104_CTRL1 0x0e39 ++#define RTL8367C_SVLAN_C2SCFG104_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG104_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG104_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG104_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG104_CTRL2 0x0e3a ++#define RTL8367C_SVLAN_C2SCFG104_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG104_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG105_CTRL0 0x0e3b ++#define RTL8367C_SVLAN_C2SCFG105_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG105_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG105_CTRL1 0x0e3c ++#define RTL8367C_SVLAN_C2SCFG105_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG105_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG105_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG105_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG105_CTRL2 0x0e3d ++#define RTL8367C_SVLAN_C2SCFG105_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG105_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG106_CTRL0 0x0e3e ++#define RTL8367C_SVLAN_C2SCFG106_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG106_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG106_CTRL1 0x0e3f ++#define RTL8367C_SVLAN_C2SCFG106_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG106_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG106_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG106_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG106_CTRL2 0x0e40 ++#define RTL8367C_SVLAN_C2SCFG106_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG106_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG107_CTRL0 0x0e41 ++#define RTL8367C_SVLAN_C2SCFG107_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG107_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG107_CTRL1 0x0e42 ++#define RTL8367C_SVLAN_C2SCFG107_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG107_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG107_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG107_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG107_CTRL2 0x0e43 ++#define RTL8367C_SVLAN_C2SCFG107_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG107_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG108_CTRL0 0x0e44 ++#define RTL8367C_SVLAN_C2SCFG108_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG108_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG108_CTRL1 0x0e45 ++#define RTL8367C_SVLAN_C2SCFG108_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG108_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG108_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG108_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG108_CTRL2 0x0e46 ++#define RTL8367C_SVLAN_C2SCFG108_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG108_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG109_CTRL0 0x0e47 ++#define RTL8367C_SVLAN_C2SCFG109_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG109_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG109_CTRL1 0x0e48 ++#define RTL8367C_SVLAN_C2SCFG109_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG109_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG109_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG109_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG109_CTRL2 0x0e49 ++#define RTL8367C_SVLAN_C2SCFG109_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG109_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG110_CTRL0 0x0e4a ++#define RTL8367C_SVLAN_C2SCFG110_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG110_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG110_CTRL1 0x0e4b ++#define RTL8367C_SVLAN_C2SCFG110_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG110_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG110_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG110_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG110_CTRL2 0x0e4c ++#define RTL8367C_SVLAN_C2SCFG110_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG110_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG111_CTRL0 0x0e4d ++#define RTL8367C_SVLAN_C2SCFG111_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG111_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG111_CTRL1 0x0e4e ++#define RTL8367C_SVLAN_C2SCFG111_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG111_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG111_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG111_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG111_CTRL2 0x0e4f ++#define RTL8367C_SVLAN_C2SCFG111_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG111_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG112_CTRL0 0x0e50 ++#define RTL8367C_SVLAN_C2SCFG112_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG112_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG112_CTRL1 0x0e51 ++#define RTL8367C_SVLAN_C2SCFG112_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG112_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG112_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG112_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG112_CTRL2 0x0e52 ++#define RTL8367C_SVLAN_C2SCFG112_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG112_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG113_CTRL0 0x0e53 ++#define RTL8367C_SVLAN_C2SCFG113_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG113_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG113_CTRL1 0x0e54 ++#define RTL8367C_SVLAN_C2SCFG113_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG113_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG113_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG113_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG113_CTRL2 0x0e55 ++#define RTL8367C_SVLAN_C2SCFG113_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG113_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG114_CTRL0 0x0e56 ++#define RTL8367C_SVLAN_C2SCFG114_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG114_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG114_CTRL1 0x0e57 ++#define RTL8367C_SVLAN_C2SCFG114_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG114_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG114_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG114_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG114_CTRL2 0x0e58 ++#define RTL8367C_SVLAN_C2SCFG114_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG114_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG115_CTRL0 0x0e59 ++#define RTL8367C_SVLAN_C2SCFG115_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG115_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG115_CTRL1 0x0e5a ++#define RTL8367C_SVLAN_C2SCFG115_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG115_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG115_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG115_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG115_CTRL2 0x0e5b ++#define RTL8367C_SVLAN_C2SCFG115_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG115_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG116_CTRL0 0x0e5c ++#define RTL8367C_SVLAN_C2SCFG116_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG116_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG116_CTRL1 0x0e5d ++#define RTL8367C_SVLAN_C2SCFG116_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG116_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG116_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG116_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG116_CTRL2 0x0e5e ++#define RTL8367C_SVLAN_C2SCFG116_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG116_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG117_CTRL0 0x0e5f ++#define RTL8367C_SVLAN_C2SCFG117_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG117_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG117_CTRL1 0x0e60 ++#define RTL8367C_SVLAN_C2SCFG117_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG117_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG117_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG117_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG117_CTRL2 0x0e61 ++#define RTL8367C_SVLAN_C2SCFG117_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG117_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG118_CTRL0 0x0e62 ++#define RTL8367C_SVLAN_C2SCFG118_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG118_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG118_CTRL1 0x0e63 ++#define RTL8367C_SVLAN_C2SCFG118_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG118_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG118_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG118_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG118_CTRL2 0x0e64 ++#define RTL8367C_SVLAN_C2SCFG118_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG118_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG119_CTRL0 0x0e65 ++#define RTL8367C_SVLAN_C2SCFG119_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG119_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG119_CTRL1 0x0e66 ++#define RTL8367C_SVLAN_C2SCFG119_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG119_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG119_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG119_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG119_CTRL2 0x0e67 ++#define RTL8367C_SVLAN_C2SCFG119_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG119_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG120_CTRL0 0x0e68 ++#define RTL8367C_SVLAN_C2SCFG120_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG120_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG120_CTRL1 0x0e69 ++#define RTL8367C_SVLAN_C2SCFG120_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG120_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG120_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG120_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG120_CTRL2 0x0e6a ++#define RTL8367C_SVLAN_C2SCFG120_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG120_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG121_CTRL0 0x0e6b ++#define RTL8367C_SVLAN_C2SCFG121_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG121_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG121_CTRL1 0x0e6c ++#define RTL8367C_SVLAN_C2SCFG121_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG121_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG121_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG121_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG121_CTRL2 0x0e6d ++#define RTL8367C_SVLAN_C2SCFG121_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG121_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG122_CTRL0 0x0e6e ++#define RTL8367C_SVLAN_C2SCFG122_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG122_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG122_CTRL1 0x0e6f ++#define RTL8367C_SVLAN_C2SCFG122_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG122_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG122_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG122_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG122_CTRL2 0x0e70 ++#define RTL8367C_SVLAN_C2SCFG122_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG122_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG123_CTRL0 0x0e71 ++#define RTL8367C_SVLAN_C2SCFG123_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG123_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG123_CTRL1 0x0e72 ++#define RTL8367C_SVLAN_C2SCFG123_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG123_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG123_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG123_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG123_CTRL2 0x0e73 ++#define RTL8367C_SVLAN_C2SCFG123_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG123_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG124_CTRL0 0x0e74 ++#define RTL8367C_SVLAN_C2SCFG124_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG124_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG124_CTRL1 0x0e75 ++#define RTL8367C_SVLAN_C2SCFG124_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG124_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG124_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG124_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG124_CTRL2 0x0e76 ++#define RTL8367C_SVLAN_C2SCFG124_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG124_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG125_CTRL0 0x0e77 ++#define RTL8367C_SVLAN_C2SCFG125_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG125_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG125_CTRL1 0x0e78 ++#define RTL8367C_SVLAN_C2SCFG125_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG125_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG125_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG125_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG125_CTRL2 0x0e79 ++#define RTL8367C_SVLAN_C2SCFG125_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG125_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG126_CTRL0 0x0e7a ++#define RTL8367C_SVLAN_C2SCFG126_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG126_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG126_CTRL1 0x0e7b ++#define RTL8367C_SVLAN_C2SCFG126_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG126_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG126_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG126_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG126_CTRL2 0x0e7c ++#define RTL8367C_SVLAN_C2SCFG126_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG126_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG127_CTRL0 0x0e7d ++#define RTL8367C_SVLAN_C2SCFG127_CTRL0_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG127_CTRL0_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_C2SCFG127_CTRL1 0x0e7e ++#define RTL8367C_SVLAN_C2SCFG127_CTRL1_C2SENPMSK_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_C2SCFG127_CTRL1_C2SENPMSK_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_C2SCFG127_CTRL1_C2SENPMSK_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG127_CTRL1_C2SENPMSK_MASK 0xFF ++ ++#define RTL8367C_REG_SVLAN_C2SCFG127_CTRL2 0x0e7f ++#define RTL8367C_SVLAN_C2SCFG127_CTRL2_OFFSET 0 ++#define RTL8367C_SVLAN_C2SCFG127_CTRL2_MASK 0x1FFF ++ ++#define RTL8367C_REG_SVLAN_CFG 0x0e80 ++#define RTL8367C_VS_PORT7_DMACVIDSEL_OFFSET 14 ++#define RTL8367C_VS_PORT7_DMACVIDSEL_MASK 0x4000 ++#define RTL8367C_VS_PORT6_DMACVIDSEL_OFFSET 13 ++#define RTL8367C_VS_PORT6_DMACVIDSEL_MASK 0x2000 ++#define RTL8367C_VS_PORT5_DMACVIDSEL_OFFSET 12 ++#define RTL8367C_VS_PORT5_DMACVIDSEL_MASK 0x1000 ++#define RTL8367C_VS_PORT4_DMACVIDSEL_OFFSET 11 ++#define RTL8367C_VS_PORT4_DMACVIDSEL_MASK 0x800 ++#define RTL8367C_VS_PORT3_DMACVIDSEL_OFFSET 10 ++#define RTL8367C_VS_PORT3_DMACVIDSEL_MASK 0x400 ++#define RTL8367C_VS_PORT2_DMACVIDSEL_OFFSET 9 ++#define RTL8367C_VS_PORT2_DMACVIDSEL_MASK 0x200 ++#define RTL8367C_VS_PORT1_DMACVIDSEL_OFFSET 8 ++#define RTL8367C_VS_PORT1_DMACVIDSEL_MASK 0x100 ++#define RTL8367C_VS_PORT0_DMACVIDSEL_OFFSET 7 ++#define RTL8367C_VS_PORT0_DMACVIDSEL_MASK 0x80 ++#define RTL8367C_VS_UIFSEG_OFFSET 6 ++#define RTL8367C_VS_UIFSEG_MASK 0x40 ++#define RTL8367C_VS_UNMAT_OFFSET 4 ++#define RTL8367C_VS_UNMAT_MASK 0x30 ++#define RTL8367C_VS_UNTAG_OFFSET 2 ++#define RTL8367C_VS_UNTAG_MASK 0xC ++#define RTL8367C_VS_SPRISEL_OFFSET 0 ++#define RTL8367C_VS_SPRISEL_MASK 0x3 ++ ++#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL0 0x0e81 ++#define RTL8367C_VS_PORT1_SVIDX_OFFSET 8 ++#define RTL8367C_VS_PORT1_SVIDX_MASK 0x3F00 ++#define RTL8367C_VS_PORT0_SVIDX_OFFSET 0 ++#define RTL8367C_VS_PORT0_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL1 0x0e82 ++#define RTL8367C_VS_PORT3_SVIDX_OFFSET 8 ++#define RTL8367C_VS_PORT3_SVIDX_MASK 0x3F00 ++#define RTL8367C_VS_PORT2_SVIDX_OFFSET 0 ++#define RTL8367C_VS_PORT2_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL2 0x0e83 ++#define RTL8367C_VS_PORT5_SVIDX_OFFSET 8 ++#define RTL8367C_VS_PORT5_SVIDX_MASK 0x3F00 ++#define RTL8367C_VS_PORT4_SVIDX_OFFSET 0 ++#define RTL8367C_VS_PORT4_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL3 0x0e84 ++#define RTL8367C_VS_PORT7_SVIDX_OFFSET 8 ++#define RTL8367C_VS_PORT7_SVIDX_MASK 0x3F00 ++#define RTL8367C_VS_PORT6_SVIDX_OFFSET 0 ++#define RTL8367C_VS_PORT6_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_UNTAG_UNMAT_CFG 0x0e85 ++#define RTL8367C_VS_UNTAG_SVIDX_OFFSET 8 ++#define RTL8367C_VS_UNTAG_SVIDX_MASK 0x3F00 ++#define RTL8367C_VS_UNMAT_SVIDX_OFFSET 0 ++#define RTL8367C_VS_UNMAT_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_LOOKUP_TYPE 0x0e86 ++#define RTL8367C_SVLAN_LOOKUP_TYPE_OFFSET 0 ++#define RTL8367C_SVLAN_LOOKUP_TYPE_MASK 0x1 ++ ++#define RTL8367C_REG_IPMC_GROUP_VALID_15_0 0x0e87 ++ ++#define RTL8367C_REG_IPMC_GROUP_VALID_31_16 0x0e88 ++ ++#define RTL8367C_REG_IPMC_GROUP_VALID_47_32 0x0e89 ++ ++#define RTL8367C_REG_IPMC_GROUP_VALID_63_48 0x0e8a ++ ++#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL4 0x0e8b ++#define RTL8367C_VS_PORT9_SVIDX_OFFSET 8 ++#define RTL8367C_VS_PORT9_SVIDX_MASK 0x3F00 ++#define RTL8367C_VS_PORT8_SVIDX_OFFSET 0 ++#define RTL8367C_VS_PORT8_SVIDX_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL5 0x0e8c ++#define RTL8367C_SVLAN_PORTBASED_SVIDX_CTRL5_OFFSET 0 ++#define RTL8367C_SVLAN_PORTBASED_SVIDX_CTRL5_MASK 0x3F ++ ++#define RTL8367C_REG_SVLAN_CFG_EXT 0x0e8d ++#define RTL8367C_VS_PORT10_DMACVIDSEL_OFFSET 2 ++#define RTL8367C_VS_PORT10_DMACVIDSEL_MASK 0x4 ++#define RTL8367C_VS_PORT9_DMACVIDSEL_OFFSET 1 ++#define RTL8367C_VS_PORT9_DMACVIDSEL_MASK 0x2 ++#define RTL8367C_VS_PORT8_DMACVIDSEL_OFFSET 0 ++#define RTL8367C_VS_PORT8_DMACVIDSEL_MASK 0x1 ++ ++#define RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL4 0x0e8e ++#define RTL8367C_SVLAN_MEMBERCFG63_CTRL4_VS_UNTAGSET_EXT_OFFSET 8 ++#define RTL8367C_SVLAN_MEMBERCFG63_CTRL4_VS_UNTAGSET_EXT_MASK 0x700 ++#define RTL8367C_SVLAN_MEMBERCFG63_CTRL4_VS_SMBR_EXT_OFFSET 0 ++#define RTL8367C_SVLAN_MEMBERCFG63_CTRL4_VS_SMBR_EXT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_DUMMY_0 0x0e90 ++ ++#define RTL8367C_REG_SVLAN_DUMMY_1 0x0e91 ++ ++#define RTL8367C_REG_SVLAN_DUMMY_2 0x0e92 ++ ++#define RTL8367C_REG_SVLAN_DUMMY_3 0x0e93 ++ ++#define RTL8367C_REG_SVLAN_DUMMY_4 0x0e94 ++ ++#define RTL8367C_REG_SVLAN_DUMMY_5 0x0e95 ++ ++#define RTL8367C_REG_SVLAN_DUMMY_6 0x0e96 ++ ++#define RTL8367C_REG_SVLAN_DUMMY_7 0x0e97 ++ ++#define RTL8367C_REG_SVLAN_DUMMY_8 0x0e98 ++ ++#define RTL8367C_REG_SVLAN_DUMMY_9 0x0e99 ++ ++#define RTL8367C_REG_SVLAN_DUMMY_10 0x0e9a ++ ++#define RTL8367C_REG_SVLAN_DUMMY_11 0x0e9b ++ ++#define RTL8367C_REG_SVLAN_DUMMY_12 0x0e9c ++ ++#define RTL8367C_REG_SVLAN_DUMMY_13 0x0e9d ++ ++#define RTL8367C_REG_SVLAN_DUMMY_14 0x0e9e ++ ++#define RTL8367C_REG_SVLAN_DUMMY_15 0x0e9f ++ ++#define RTL8367C_REG_SVLAN_DUMMY_16 0x0ea0 ++ ++#define RTL8367C_REG_SVLAN_DUMMY_17 0x0ea1 ++ ++#define RTL8367C_REG_SVLAN_DUMMY_18 0x0ea2 ++ ++#define RTL8367C_REG_SVLAN_DUMMY_19 0x0ea3 ++ ++#define RTL8367C_REG_SVLAN_DUMMY_20 0x0ea4 ++ ++#define RTL8367C_REG_SVLAN_DUMMY_21 0x0ea5 ++ ++#define RTL8367C_REG_SVLAN_DUMMY_22 0x0ea6 ++ ++#define RTL8367C_REG_SVLAN_DUMMY_23 0x0ea7 ++ ++#define RTL8367C_REG_SVLAN_DUMMY_24 0x0ea8 ++ ++#define RTL8367C_REG_SVLAN_DUMMY_25 0x0ea9 ++ ++#define RTL8367C_REG_SVLAN_DUMMY_26 0x0eaa ++ ++#define RTL8367C_REG_SVLAN_DUMMY_27 0x0eab ++ ++#define RTL8367C_REG_SVLAN_DUMMY_28 0x0eac ++ ++#define RTL8367C_REG_SVLAN_DUMMY_29 0x0ead ++ ++#define RTL8367C_REG_SVLAN_DUMMY_30 0x0eae ++ ++#define RTL8367C_REG_SVLAN_DUMMY_31 0x0eaf ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_00 0x0eb0 ++#define RTL8367C_IPMC_GROUP_VID_00_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_00_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_01 0x0eb1 ++#define RTL8367C_IPMC_GROUP_VID_01_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_01_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_02 0x0eb2 ++#define RTL8367C_IPMC_GROUP_VID_02_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_02_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_03 0x0eb3 ++#define RTL8367C_IPMC_GROUP_VID_03_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_03_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_04 0x0eb4 ++#define RTL8367C_IPMC_GROUP_VID_04_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_04_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_05 0x0eb5 ++#define RTL8367C_IPMC_GROUP_VID_05_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_05_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_06 0x0eb6 ++#define RTL8367C_IPMC_GROUP_VID_06_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_06_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_07 0x0eb7 ++#define RTL8367C_IPMC_GROUP_VID_07_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_07_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_08 0x0eb8 ++#define RTL8367C_IPMC_GROUP_VID_08_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_08_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_09 0x0eb9 ++#define RTL8367C_IPMC_GROUP_VID_09_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_09_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_10 0x0eba ++#define RTL8367C_IPMC_GROUP_VID_10_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_10_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_11 0x0ebb ++#define RTL8367C_IPMC_GROUP_VID_11_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_11_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_12 0x0ebc ++#define RTL8367C_IPMC_GROUP_VID_12_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_12_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_13 0x0ebd ++#define RTL8367C_IPMC_GROUP_VID_13_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_13_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_14 0x0ebe ++#define RTL8367C_IPMC_GROUP_VID_14_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_14_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_15 0x0ebf ++#define RTL8367C_IPMC_GROUP_VID_15_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_15_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_16 0x0ec0 ++#define RTL8367C_IPMC_GROUP_VID_16_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_16_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_17 0x0ec1 ++#define RTL8367C_IPMC_GROUP_VID_17_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_17_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_18 0x0ec2 ++#define RTL8367C_IPMC_GROUP_VID_18_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_18_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_19 0x0ec3 ++#define RTL8367C_IPMC_GROUP_VID_19_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_19_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_20 0x0ec4 ++#define RTL8367C_IPMC_GROUP_VID_20_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_20_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_21 0x0ec5 ++#define RTL8367C_IPMC_GROUP_VID_21_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_21_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_22 0x0ec6 ++#define RTL8367C_IPMC_GROUP_VID_22_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_22_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_23 0x0ec7 ++#define RTL8367C_IPMC_GROUP_VID_23_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_23_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_24 0x0ec8 ++#define RTL8367C_IPMC_GROUP_VID_24_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_24_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_25 0x0ec9 ++#define RTL8367C_IPMC_GROUP_VID_25_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_25_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_26 0x0eca ++#define RTL8367C_IPMC_GROUP_VID_26_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_26_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_27 0x0ecb ++#define RTL8367C_IPMC_GROUP_VID_27_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_27_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_28 0x0ecc ++#define RTL8367C_IPMC_GROUP_VID_28_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_28_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_29 0x0ecd ++#define RTL8367C_IPMC_GROUP_VID_29_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_29_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_30 0x0ece ++#define RTL8367C_IPMC_GROUP_VID_30_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_30_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_31 0x0ecf ++#define RTL8367C_IPMC_GROUP_VID_31_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_31_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_32 0x0ed0 ++#define RTL8367C_IPMC_GROUP_VID_32_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_32_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_33 0x0ed1 ++#define RTL8367C_IPMC_GROUP_VID_33_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_33_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_34 0x0ed2 ++#define RTL8367C_IPMC_GROUP_VID_34_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_34_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_35 0x0ed3 ++#define RTL8367C_IPMC_GROUP_VID_35_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_35_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_36 0x0ed4 ++#define RTL8367C_IPMC_GROUP_VID_36_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_36_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_37 0x0ed5 ++#define RTL8367C_IPMC_GROUP_VID_37_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_37_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_38 0x0ed6 ++#define RTL8367C_IPMC_GROUP_VID_38_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_38_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_39 0x0ed7 ++#define RTL8367C_IPMC_GROUP_VID_39_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_39_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_40 0x0ed8 ++#define RTL8367C_IPMC_GROUP_VID_40_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_40_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_41 0x0ed9 ++#define RTL8367C_IPMC_GROUP_VID_41_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_41_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_42 0x0eda ++#define RTL8367C_IPMC_GROUP_VID_42_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_42_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_43 0x0edb ++#define RTL8367C_IPMC_GROUP_VID_43_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_43_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_44 0x0edc ++#define RTL8367C_IPMC_GROUP_VID_44_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_44_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_45 0x0edd ++#define RTL8367C_IPMC_GROUP_VID_45_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_45_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_46 0x0ede ++#define RTL8367C_IPMC_GROUP_VID_46_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_46_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_47 0x0edf ++#define RTL8367C_IPMC_GROUP_VID_47_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_47_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_48 0x0ef0 ++#define RTL8367C_IPMC_GROUP_VID_48_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_48_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_49 0x0ef1 ++#define RTL8367C_IPMC_GROUP_VID_49_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_49_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_50 0x0ef2 ++#define RTL8367C_IPMC_GROUP_VID_50_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_50_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_51 0x0ef3 ++#define RTL8367C_IPMC_GROUP_VID_51_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_51_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_52 0x0ef4 ++#define RTL8367C_IPMC_GROUP_VID_52_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_52_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_53 0x0ef5 ++#define RTL8367C_IPMC_GROUP_VID_53_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_53_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_54 0x0ef6 ++#define RTL8367C_IPMC_GROUP_VID_54_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_54_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_55 0x0ef7 ++#define RTL8367C_IPMC_GROUP_VID_55_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_55_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_56 0x0ef8 ++#define RTL8367C_IPMC_GROUP_VID_56_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_56_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_57 0x0ef9 ++#define RTL8367C_IPMC_GROUP_VID_57_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_57_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_58 0x0efa ++#define RTL8367C_IPMC_GROUP_VID_58_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_58_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_59 0x0efb ++#define RTL8367C_IPMC_GROUP_VID_59_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_59_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_60 0x0efc ++#define RTL8367C_IPMC_GROUP_VID_60_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_60_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_61 0x0efd ++#define RTL8367C_IPMC_GROUP_VID_61_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_61_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_62 0x0efe ++#define RTL8367C_IPMC_GROUP_VID_62_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_62_MASK 0xFFF ++ ++#define RTL8367C_REG_IPMC_GROUP_VID_63 0x0eff ++#define RTL8367C_IPMC_GROUP_VID_63_OFFSET 0 ++#define RTL8367C_IPMC_GROUP_VID_63_MASK 0xFFF ++ ++/* (16'h0f00)hsactrl_reg */ ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY0_CTRL0 0x0f00 ++#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY0_CTRL1 0x0f01 ++#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY0_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY1_CTRL0 0x0f02 ++#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY1_CTRL1 0x0f03 ++#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY1_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY2_CTRL0 0x0f04 ++#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY2_CTRL1 0x0f05 ++#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY2_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY3_CTRL0 0x0f06 ++#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY3_CTRL1 0x0f07 ++#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY3_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY4_CTRL0 0x0f08 ++#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY4_CTRL1 0x0f09 ++#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY4_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY5_CTRL0 0x0f0a ++#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY5_CTRL1 0x0f0b ++#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY5_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY6_CTRL0 0x0f0c ++#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY6_CTRL1 0x0f0d ++#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY6_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY7_CTRL0 0x0f0e ++#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY7_CTRL1 0x0f0f ++#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY7_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY8_CTRL0 0x0f10 ++#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY8_CTRL1 0x0f11 ++#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY8_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY9_CTRL0 0x0f12 ++#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY9_CTRL1 0x0f13 ++#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY9_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY10_CTRL0 0x0f14 ++#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY10_CTRL1 0x0f15 ++#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY10_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY11_CTRL0 0x0f16 ++#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY11_CTRL1 0x0f17 ++#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY11_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY12_CTRL0 0x0f18 ++#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY12_CTRL1 0x0f19 ++#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY12_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY13_CTRL0 0x0f1a ++#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY13_CTRL1 0x0f1b ++#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY13_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY14_CTRL0 0x0f1c ++#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY14_CTRL1 0x0f1d ++#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY14_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY15_CTRL0 0x0f1e ++#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY15_CTRL1 0x0f1f ++#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY15_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY16_CTRL0 0x0f20 ++#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY16_CTRL1 0x0f21 ++#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY16_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY17_CTRL0 0x0f22 ++#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY17_CTRL1 0x0f23 ++#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY17_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY18_CTRL0 0x0f24 ++#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY18_CTRL1 0x0f25 ++#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY18_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY19_CTRL0 0x0f26 ++#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY19_CTRL1 0x0f27 ++#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY19_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY20_CTRL0 0x0f28 ++#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY20_CTRL1 0x0f29 ++#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY20_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY21_CTRL0 0x0f2a ++#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY21_CTRL1 0x0f2b ++#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY21_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY22_CTRL0 0x0f2c ++#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY22_CTRL1 0x0f2d ++#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY22_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY23_CTRL0 0x0f2e ++#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY23_CTRL1 0x0f2f ++#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY23_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY24_CTRL0 0x0f30 ++#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY24_CTRL1 0x0f31 ++#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY24_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY25_CTRL0 0x0f32 ++#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY25_CTRL1 0x0f33 ++#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY25_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY26_CTRL0 0x0f34 ++#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY26_CTRL1 0x0f35 ++#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY26_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY27_CTRL0 0x0f36 ++#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY27_CTRL1 0x0f37 ++#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY27_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY28_CTRL0 0x0f38 ++#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY28_CTRL1 0x0f39 ++#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY28_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY29_CTRL0 0x0f3a ++#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY29_CTRL1 0x0f3b ++#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY29_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY30_CTRL0 0x0f3c ++#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY30_CTRL1 0x0f3d ++#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY30_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY31_CTRL0 0x0f3e ++#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY31_CTRL1 0x0f3f ++#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY31_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY32_CTRL0 0x0f40 ++#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY32_CTRL1 0x0f41 ++#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY32_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY33_CTRL0 0x0f42 ++#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY33_CTRL1 0x0f43 ++#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY33_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY34_CTRL0 0x0f44 ++#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY34_CTRL1 0x0f45 ++#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY34_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY35_CTRL0 0x0f46 ++#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY35_CTRL1 0x0f47 ++#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY35_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY36_CTRL0 0x0f48 ++#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY36_CTRL1 0x0f49 ++#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY36_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY37_CTRL0 0x0f4a ++#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY37_CTRL1 0x0f4b ++#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY37_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY38_CTRL0 0x0f4c ++#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY38_CTRL1 0x0f4d ++#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY38_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY39_CTRL0 0x0f4e ++#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY39_CTRL1 0x0f4f ++#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY39_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY40_CTRL0 0x0f50 ++#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY40_CTRL1 0x0f51 ++#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY40_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY41_CTRL0 0x0f52 ++#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY41_CTRL1 0x0f53 ++#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY41_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY42_CTRL0 0x0f54 ++#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY42_CTRL1 0x0f55 ++#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY42_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY43_CTRL0 0x0f56 ++#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY43_CTRL1 0x0f57 ++#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY43_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY44_CTRL0 0x0f58 ++#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY44_CTRL1 0x0f59 ++#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY44_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY45_CTRL0 0x0f5a ++#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY45_CTRL1 0x0f5b ++#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY45_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY46_CTRL0 0x0f5c ++#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY46_CTRL1 0x0f5d ++#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY46_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY47_CTRL0 0x0f5e ++#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY47_CTRL1 0x0f5f ++#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY47_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY48_CTRL0 0x0f60 ++#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY48_CTRL1 0x0f61 ++#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY48_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY49_CTRL0 0x0f62 ++#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY49_CTRL1 0x0f63 ++#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY49_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY50_CTRL0 0x0f64 ++#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY50_CTRL1 0x0f65 ++#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY50_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY51_CTRL0 0x0f66 ++#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY51_CTRL1 0x0f67 ++#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY51_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY52_CTRL0 0x0f68 ++#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY52_CTRL1 0x0f69 ++#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY52_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY53_CTRL0 0x0f6a ++#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY53_CTRL1 0x0f6b ++#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY53_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY54_CTRL0 0x0f6c ++#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY54_CTRL1 0x0f6d ++#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY54_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY55_CTRL0 0x0f6e ++#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY55_CTRL1 0x0f6f ++#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY55_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY56_CTRL0 0x0f70 ++#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY56_CTRL1 0x0f71 ++#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY56_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY57_CTRL0 0x0f72 ++#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY57_CTRL1 0x0f73 ++#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY57_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY58_CTRL0 0x0f74 ++#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY58_CTRL1 0x0f75 ++#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY58_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY59_CTRL0 0x0f76 ++#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY59_CTRL1 0x0f77 ++#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY59_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY60_CTRL0 0x0f78 ++#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY60_CTRL1 0x0f79 ++#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY60_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY61_CTRL0 0x0f7a ++#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY61_CTRL1 0x0f7b ++#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY61_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY62_CTRL0 0x0f7c ++#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY62_CTRL1 0x0f7d ++#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY62_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY63_CTRL0 0x0f7e ++#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY63_CTRL1 0x0f7f ++#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY63_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY64_CTRL0 0x0f80 ++#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY64_CTRL1 0x0f81 ++#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY64_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY65_CTRL0 0x0f82 ++#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY65_CTRL1 0x0f83 ++#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY65_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY66_CTRL0 0x0f84 ++#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY66_CTRL1 0x0f85 ++#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY66_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY67_CTRL0 0x0f86 ++#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY67_CTRL1 0x0f87 ++#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY67_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY68_CTRL0 0x0f88 ++#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY68_CTRL1 0x0f89 ++#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY68_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY69_CTRL0 0x0f8a ++#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY69_CTRL1 0x0f8b ++#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY69_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY70_CTRL0 0x0f8c ++#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY70_CTRL1 0x0f8d ++#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY70_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY71_CTRL0 0x0f8e ++#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY71_CTRL1 0x0f8f ++#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY71_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY72_CTRL0 0x0f90 ++#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY72_CTRL1 0x0f91 ++#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY72_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY73_CTRL0 0x0f92 ++#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY73_CTRL1 0x0f93 ++#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY73_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY74_CTRL0 0x0f94 ++#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY74_CTRL1 0x0f95 ++#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY74_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY75_CTRL0 0x0f96 ++#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY75_CTRL1 0x0f97 ++#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY75_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY76_CTRL0 0x0f98 ++#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY76_CTRL1 0x0f99 ++#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY76_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY77_CTRL0 0x0f9a ++#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY77_CTRL1 0x0f9b ++#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY77_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY78_CTRL0 0x0f9c ++#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY78_CTRL1 0x0f9d ++#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY78_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY79_CTRL0 0x0f9e ++#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY79_CTRL1 0x0f9f ++#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY79_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY80_CTRL0 0x0fa0 ++#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY80_CTRL1 0x0fa1 ++#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY80_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY81_CTRL0 0x0fa2 ++#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY81_CTRL1 0x0fa3 ++#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY81_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY82_CTRL0 0x0fa4 ++#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY82_CTRL1 0x0fa5 ++#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY82_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY83_CTRL0 0x0fa6 ++#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY83_CTRL1 0x0fa7 ++#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY83_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY84_CTRL0 0x0fa8 ++#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY84_CTRL1 0x0fa9 ++#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY84_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY85_CTRL0 0x0faa ++#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY85_CTRL1 0x0fab ++#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY85_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY86_CTRL0 0x0fac ++#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY86_CTRL1 0x0fad ++#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY86_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY87_CTRL0 0x0fae ++#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY87_CTRL1 0x0faf ++#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY87_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY88_CTRL0 0x0fb0 ++#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY88_CTRL1 0x0fb1 ++#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY88_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY89_CTRL0 0x0fb2 ++#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY89_CTRL1 0x0fb3 ++#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY89_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY90_CTRL0 0x0fb4 ++#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY90_CTRL1 0x0fb5 ++#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY90_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY91_CTRL0 0x0fb6 ++#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY91_CTRL1 0x0fb7 ++#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY91_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY92_CTRL0 0x0fb8 ++#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY92_CTRL1 0x0fb9 ++#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY92_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY93_CTRL0 0x0fba ++#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY93_CTRL1 0x0fbb ++#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY93_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY94_CTRL0 0x0fbc ++#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY94_CTRL1 0x0fbd ++#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY94_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY95_CTRL0 0x0fbe ++#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY95_CTRL1 0x0fbf ++#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY95_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY96_CTRL0 0x0fc0 ++#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY96_CTRL1 0x0fc1 ++#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY96_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY97_CTRL0 0x0fc2 ++#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY97_CTRL1 0x0fc3 ++#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY97_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY98_CTRL0 0x0fc4 ++#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY98_CTRL1 0x0fc5 ++#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY98_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY99_CTRL0 0x0fc6 ++#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY99_CTRL1 0x0fc7 ++#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY99_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY100_CTRL0 0x0fc8 ++#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY100_CTRL1 0x0fc9 ++#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY100_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY101_CTRL0 0x0fca ++#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY101_CTRL1 0x0fcb ++#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY101_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY102_CTRL0 0x0fcc ++#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY102_CTRL1 0x0fcd ++#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY102_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY103_CTRL0 0x0fce ++#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY103_CTRL1 0x0fcf ++#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY103_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY104_CTRL0 0x0fd0 ++#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY104_CTRL1 0x0fd1 ++#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY104_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY105_CTRL0 0x0fd2 ++#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY105_CTRL1 0x0fd3 ++#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY105_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY106_CTRL0 0x0fd4 ++#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY106_CTRL1 0x0fd5 ++#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY106_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY107_CTRL0 0x0fd6 ++#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY107_CTRL1 0x0fd7 ++#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY107_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY108_CTRL0 0x0fd8 ++#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY108_CTRL1 0x0fd9 ++#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY108_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY109_CTRL0 0x0fda ++#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY109_CTRL1 0x0fdb ++#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY109_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY110_CTRL0 0x0fdc ++#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY110_CTRL1 0x0fdd ++#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY110_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY111_CTRL0 0x0fde ++#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY111_CTRL1 0x0fdf ++#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY111_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY112_CTRL0 0x0fe0 ++#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY112_CTRL1 0x0fe1 ++#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY112_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY113_CTRL0 0x0fe2 ++#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY113_CTRL1 0x0fe3 ++#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY113_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY114_CTRL0 0x0fe4 ++#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY114_CTRL1 0x0fe5 ++#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY114_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY115_CTRL0 0x0fe6 ++#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY115_CTRL1 0x0fe7 ++#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY115_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY116_CTRL0 0x0fe8 ++#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY116_CTRL1 0x0fe9 ++#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY116_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY117_CTRL0 0x0fea ++#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY117_CTRL1 0x0feb ++#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY117_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY118_CTRL0 0x0fec ++#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY118_CTRL1 0x0fed ++#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY118_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY119_CTRL0 0x0fee ++#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY119_CTRL1 0x0fef ++#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY119_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY120_CTRL0 0x0ff0 ++#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY120_CTRL1 0x0ff1 ++#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY120_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY121_CTRL0 0x0ff2 ++#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY121_CTRL1 0x0ff3 ++#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY121_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY122_CTRL0 0x0ff4 ++#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY122_CTRL1 0x0ff5 ++#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY122_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY123_CTRL0 0x0ff6 ++#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY123_CTRL1 0x0ff7 ++#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY123_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY124_CTRL0 0x0ff8 ++#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY124_CTRL1 0x0ff9 ++#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY124_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY125_CTRL0 0x0ffa ++#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY125_CTRL1 0x0ffb ++#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY125_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY126_CTRL0 0x0ffc ++#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY126_CTRL1 0x0ffd ++#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY126_CTRL1_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY127_CTRL0 0x0ffe ++#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_DST_PORT1_OFFSET 9 ++#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_DST_PORT1_MASK 0x200 ++#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_SVIDX_OFFSET 3 ++#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_SVIDX_MASK 0x1F8 ++#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_DST_PORT_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL0_DST_PORT_MASK 0x7 ++ ++#define RTL8367C_REG_SVLAN_SP2C_ENTRY127_CTRL1 0x0fff ++#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL1_VALID_OFFSET 12 ++#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL1_VALID_MASK 0x1000 ++#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL1_VID_OFFSET 0 ++#define RTL8367C_SVLAN_SP2C_ENTRY127_CTRL1_VID_MASK 0xFFF ++ ++/* (16'h1000)mib_reg */ ++ ++#define RTL8367C_REG_MIB_COUNTER0 0x1000 ++ ++#define RTL8367C_REG_MIB_COUNTER1 0x1001 ++ ++#define RTL8367C_REG_MIB_COUNTER2 0x1002 ++ ++#define RTL8367C_REG_MIB_COUNTER3 0x1003 ++ ++#define RTL8367C_REG_MIB_ADDRESS 0x1004 ++#define RTL8367C_MIB_ADDRESS_OFFSET 0 ++#define RTL8367C_MIB_ADDRESS_MASK 0x1FF ++ ++#define RTL8367C_REG_MIB_CTRL0 0x1005 ++#define RTL8367C_PORT10_RESET_OFFSET 15 ++#define RTL8367C_PORT10_RESET_MASK 0x8000 ++#define RTL8367C_PORT9_RESET_OFFSET 14 ++#define RTL8367C_PORT9_RESET_MASK 0x4000 ++#define RTL8367C_PORT8_RESET_OFFSET 13 ++#define RTL8367C_PORT8_RESET_MASK 0x2000 ++#define RTL8367C_RESET_VALUE_OFFSET 12 ++#define RTL8367C_RESET_VALUE_MASK 0x1000 ++#define RTL8367C_GLOBAL_RESET_OFFSET 11 ++#define RTL8367C_GLOBAL_RESET_MASK 0x800 ++#define RTL8367C_QM_RESET_OFFSET 10 ++#define RTL8367C_QM_RESET_MASK 0x400 ++#define RTL8367C_PORT7_RESET_OFFSET 9 ++#define RTL8367C_PORT7_RESET_MASK 0x200 ++#define RTL8367C_PORT6_RESET_OFFSET 8 ++#define RTL8367C_PORT6_RESET_MASK 0x100 ++#define RTL8367C_PORT5_RESET_OFFSET 7 ++#define RTL8367C_PORT5_RESET_MASK 0x80 ++#define RTL8367C_PORT4_RESET_OFFSET 6 ++#define RTL8367C_PORT4_RESET_MASK 0x40 ++#define RTL8367C_PORT3_RESET_OFFSET 5 ++#define RTL8367C_PORT3_RESET_MASK 0x20 ++#define RTL8367C_PORT2_RESET_OFFSET 4 ++#define RTL8367C_PORT2_RESET_MASK 0x10 ++#define RTL8367C_PORT1_RESET_OFFSET 3 ++#define RTL8367C_PORT1_RESET_MASK 0x8 ++#define RTL8367C_PORT0_RESET_OFFSET 2 ++#define RTL8367C_PORT0_RESET_MASK 0x4 ++#define RTL8367C_RESET_FLAG_OFFSET 1 ++#define RTL8367C_RESET_FLAG_MASK 0x2 ++#define RTL8367C_MIB_CTRL0_BUSY_FLAG_OFFSET 0 ++#define RTL8367C_MIB_CTRL0_BUSY_FLAG_MASK 0x1 ++ ++#define RTL8367C_REG_MIB_CTRL1 0x1007 ++#define RTL8367C_COUNTER15_RESET_OFFSET 15 ++#define RTL8367C_COUNTER15_RESET_MASK 0x8000 ++#define RTL8367C_COUNTER14_RESET_OFFSET 14 ++#define RTL8367C_COUNTER14_RESET_MASK 0x4000 ++#define RTL8367C_COUNTER13_RESET_OFFSET 13 ++#define RTL8367C_COUNTER13_RESET_MASK 0x2000 ++#define RTL8367C_COUNTER12_RESET_OFFSET 12 ++#define RTL8367C_COUNTER12_RESET_MASK 0x1000 ++#define RTL8367C_COUNTER11_RESET_OFFSET 11 ++#define RTL8367C_COUNTER11_RESET_MASK 0x800 ++#define RTL8367C_COUNTER10_RESET_OFFSET 10 ++#define RTL8367C_COUNTER10_RESET_MASK 0x400 ++#define RTL8367C_COUNTER9_RESET_OFFSET 9 ++#define RTL8367C_COUNTER9_RESET_MASK 0x200 ++#define RTL8367C_COUNTER8_RESET_OFFSET 8 ++#define RTL8367C_COUNTER8_RESET_MASK 0x100 ++#define RTL8367C_COUNTER7_RESET_OFFSET 7 ++#define RTL8367C_COUNTER7_RESET_MASK 0x80 ++#define RTL8367C_COUNTER6_RESET_OFFSET 6 ++#define RTL8367C_COUNTER6_RESET_MASK 0x40 ++#define RTL8367C_COUNTER5_RESET_OFFSET 5 ++#define RTL8367C_COUNTER5_RESET_MASK 0x20 ++#define RTL8367C_COUNTER4_RESET_OFFSET 4 ++#define RTL8367C_COUNTER4_RESET_MASK 0x10 ++#define RTL8367C_COUNTER3_RESET_OFFSET 3 ++#define RTL8367C_COUNTER3_RESET_MASK 0x8 ++#define RTL8367C_COUNTER2_RESET_OFFSET 2 ++#define RTL8367C_COUNTER2_RESET_MASK 0x4 ++#define RTL8367C_COUNTER1_RESET_OFFSET 1 ++#define RTL8367C_COUNTER1_RESET_MASK 0x2 ++#define RTL8367C_COUNTER0_RESET_OFFSET 0 ++#define RTL8367C_COUNTER0_RESET_MASK 0x1 ++ ++#define RTL8367C_REG_MIB_CTRL2 0x1008 ++#define RTL8367C_COUNTER31_RESET_OFFSET 15 ++#define RTL8367C_COUNTER31_RESET_MASK 0x8000 ++#define RTL8367C_COUNTER30_RESET_OFFSET 14 ++#define RTL8367C_COUNTER30_RESET_MASK 0x4000 ++#define RTL8367C_COUNTER29_RESET_OFFSET 13 ++#define RTL8367C_COUNTER29_RESET_MASK 0x2000 ++#define RTL8367C_COUNTER28_RESET_OFFSET 12 ++#define RTL8367C_COUNTER28_RESET_MASK 0x1000 ++#define RTL8367C_COUNTER27_RESET_OFFSET 11 ++#define RTL8367C_COUNTER27_RESET_MASK 0x800 ++#define RTL8367C_COUNTER26_RESET_OFFSET 10 ++#define RTL8367C_COUNTER26_RESET_MASK 0x400 ++#define RTL8367C_COUNTER25_RESET_OFFSET 9 ++#define RTL8367C_COUNTER25_RESET_MASK 0x200 ++#define RTL8367C_COUNTER24_RESET_OFFSET 8 ++#define RTL8367C_COUNTER24_RESET_MASK 0x100 ++#define RTL8367C_COUNTER23_RESET_OFFSET 7 ++#define RTL8367C_COUNTER23_RESET_MASK 0x80 ++#define RTL8367C_COUNTER22_RESET_OFFSET 6 ++#define RTL8367C_COUNTER22_RESET_MASK 0x40 ++#define RTL8367C_COUNTER21_RESET_OFFSET 5 ++#define RTL8367C_COUNTER21_RESET_MASK 0x20 ++#define RTL8367C_COUNTER20_RESET_OFFSET 4 ++#define RTL8367C_COUNTER20_RESET_MASK 0x10 ++#define RTL8367C_COUNTER19_RESET_OFFSET 3 ++#define RTL8367C_COUNTER19_RESET_MASK 0x8 ++#define RTL8367C_COUNTER18_RESET_OFFSET 2 ++#define RTL8367C_COUNTER18_RESET_MASK 0x4 ++#define RTL8367C_COUNTER17_RESET_OFFSET 1 ++#define RTL8367C_COUNTER17_RESET_MASK 0x2 ++#define RTL8367C_COUNTER16_RESET_OFFSET 0 ++#define RTL8367C_COUNTER16_RESET_MASK 0x1 ++ ++#define RTL8367C_REG_MIB_CTRL3 0x1009 ++#define RTL8367C_COUNTER15_MODE_OFFSET 15 ++#define RTL8367C_COUNTER15_MODE_MASK 0x8000 ++#define RTL8367C_COUNTER14_MODE_OFFSET 14 ++#define RTL8367C_COUNTER14_MODE_MASK 0x4000 ++#define RTL8367C_COUNTER13_MODE_OFFSET 13 ++#define RTL8367C_COUNTER13_MODE_MASK 0x2000 ++#define RTL8367C_COUNTER12_MODE_OFFSET 12 ++#define RTL8367C_COUNTER12_MODE_MASK 0x1000 ++#define RTL8367C_COUNTER11_MODE_OFFSET 11 ++#define RTL8367C_COUNTER11_MODE_MASK 0x800 ++#define RTL8367C_COUNTER10_MODE_OFFSET 10 ++#define RTL8367C_COUNTER10_MODE_MASK 0x400 ++#define RTL8367C_COUNTER9_MODE_OFFSET 9 ++#define RTL8367C_COUNTER9_MODE_MASK 0x200 ++#define RTL8367C_COUNTER8_MODE_OFFSET 8 ++#define RTL8367C_COUNTER8_MODE_MASK 0x100 ++#define RTL8367C_COUNTER7_MODE_OFFSET 7 ++#define RTL8367C_COUNTER7_MODE_MASK 0x80 ++#define RTL8367C_COUNTER6_MODE_OFFSET 6 ++#define RTL8367C_COUNTER6_MODE_MASK 0x40 ++#define RTL8367C_COUNTER5_MODE_OFFSET 5 ++#define RTL8367C_COUNTER5_MODE_MASK 0x20 ++#define RTL8367C_COUNTER4_MODE_OFFSET 4 ++#define RTL8367C_COUNTER4_MODE_MASK 0x10 ++#define RTL8367C_COUNTER3_MODE_OFFSET 3 ++#define RTL8367C_COUNTER3_MODE_MASK 0x8 ++#define RTL8367C_COUNTER2_MODE_OFFSET 2 ++#define RTL8367C_COUNTER2_MODE_MASK 0x4 ++#define RTL8367C_COUNTER1_MODE_OFFSET 1 ++#define RTL8367C_COUNTER1_MODE_MASK 0x2 ++#define RTL8367C_COUNTER0_MODE_OFFSET 0 ++#define RTL8367C_COUNTER0_MODE_MASK 0x1 ++ ++#define RTL8367C_REG_MIB_CTRL4 0x100a ++#define RTL8367C_MIB_USAGE_MODE_OFFSET 8 ++#define RTL8367C_MIB_USAGE_MODE_MASK 0x100 ++#define RTL8367C_MIB_TIMER_OFFSET 0 ++#define RTL8367C_MIB_TIMER_MASK 0xFF ++ ++#define RTL8367C_REG_MIB_CTRL5 0x100b ++#define RTL8367C_MIB_CTRL5_COUNTER15_TYPE_OFFSET 15 ++#define RTL8367C_MIB_CTRL5_COUNTER15_TYPE_MASK 0x8000 ++#define RTL8367C_MIB_CTRL5_COUNTER14_TYPE_OFFSET 14 ++#define RTL8367C_MIB_CTRL5_COUNTER14_TYPE_MASK 0x4000 ++#define RTL8367C_MIB_CTRL5_COUNTER13_TYPE_OFFSET 13 ++#define RTL8367C_MIB_CTRL5_COUNTER13_TYPE_MASK 0x2000 ++#define RTL8367C_MIB_CTRL5_COUNTER12_TYPE_OFFSET 12 ++#define RTL8367C_MIB_CTRL5_COUNTER12_TYPE_MASK 0x1000 ++#define RTL8367C_MIB_CTRL5_COUNTER11_TYPE_OFFSET 11 ++#define RTL8367C_MIB_CTRL5_COUNTER11_TYPE_MASK 0x800 ++#define RTL8367C_MIB_CTRL5_COUNTER10_TYPE_OFFSET 10 ++#define RTL8367C_MIB_CTRL5_COUNTER10_TYPE_MASK 0x400 ++#define RTL8367C_MIB_CTRL5_COUNTER9_TYPE_OFFSET 9 ++#define RTL8367C_MIB_CTRL5_COUNTER9_TYPE_MASK 0x200 ++#define RTL8367C_MIB_CTRL5_COUNTER8_TYPE_OFFSET 8 ++#define RTL8367C_MIB_CTRL5_COUNTER8_TYPE_MASK 0x100 ++#define RTL8367C_MIB_CTRL5_COUNTER7_TYPE_OFFSET 7 ++#define RTL8367C_MIB_CTRL5_COUNTER7_TYPE_MASK 0x80 ++#define RTL8367C_MIB_CTRL5_COUNTER6_TYPE_OFFSET 6 ++#define RTL8367C_MIB_CTRL5_COUNTER6_TYPE_MASK 0x40 ++#define RTL8367C_MIB_CTRL5_COUNTER5_TYPE_OFFSET 5 ++#define RTL8367C_MIB_CTRL5_COUNTER5_TYPE_MASK 0x20 ++#define RTL8367C_MIB_CTRL5_COUNTER4_TYPE_OFFSET 4 ++#define RTL8367C_MIB_CTRL5_COUNTER4_TYPE_MASK 0x10 ++#define RTL8367C_MIB_CTRL5_COUNTER3_TYPE_OFFSET 3 ++#define RTL8367C_MIB_CTRL5_COUNTER3_TYPE_MASK 0x8 ++#define RTL8367C_MIB_CTRL5_COUNTER2_TYPE_OFFSET 2 ++#define RTL8367C_MIB_CTRL5_COUNTER2_TYPE_MASK 0x4 ++#define RTL8367C_MIB_CTRL5_COUNTER1_TYPE_OFFSET 1 ++#define RTL8367C_MIB_CTRL5_COUNTER1_TYPE_MASK 0x2 ++#define RTL8367C_MIB_CTRL5_COUNTER0_TYPE_OFFSET 0 ++#define RTL8367C_MIB_CTRL5_COUNTER0_TYPE_MASK 0x1 ++ ++/* (16'h1100)intrpt_reg */ ++ ++#define RTL8367C_REG_INTR_CTRL 0x1100 ++#define RTL8367C_INTR_CTRL_OFFSET 0 ++#define RTL8367C_INTR_CTRL_MASK 0x1 ++ ++#define RTL8367C_REG_INTR_IMR 0x1101 ++#define RTL8367C_INTR_IMR_SLIENT_START_2_OFFSET 12 ++#define RTL8367C_INTR_IMR_SLIENT_START_2_MASK 0x1000 ++#define RTL8367C_INTR_IMR_SLIENT_START_OFFSET 11 ++#define RTL8367C_INTR_IMR_SLIENT_START_MASK 0x800 ++#define RTL8367C_INTR_IMR_ACL_ACTION_OFFSET 9 ++#define RTL8367C_INTR_IMR_ACL_ACTION_MASK 0x200 ++#define RTL8367C_INTR_IMR_CABLE_DIAG_FIN_OFFSET 8 ++#define RTL8367C_INTR_IMR_CABLE_DIAG_FIN_MASK 0x100 ++#define RTL8367C_INTR_IMR_INTERRUPT_8051_OFFSET 7 ++#define RTL8367C_INTR_IMR_INTERRUPT_8051_MASK 0x80 ++#define RTL8367C_INTR_IMR_LOOP_DETECTION_OFFSET 6 ++#define RTL8367C_INTR_IMR_LOOP_DETECTION_MASK 0x40 ++#define RTL8367C_INTR_IMR_GREEN_TIMER_OFFSET 5 ++#define RTL8367C_INTR_IMR_GREEN_TIMER_MASK 0x20 ++#define RTL8367C_INTR_IMR_SPECIAL_CONGEST_OFFSET 4 ++#define RTL8367C_INTR_IMR_SPECIAL_CONGEST_MASK 0x10 ++#define RTL8367C_INTR_IMR_SPEED_CHANGE_OFFSET 3 ++#define RTL8367C_INTR_IMR_SPEED_CHANGE_MASK 0x8 ++#define RTL8367C_INTR_IMR_LEARN_OVER_OFFSET 2 ++#define RTL8367C_INTR_IMR_LEARN_OVER_MASK 0x4 ++#define RTL8367C_INTR_IMR_METER_EXCEEDED_OFFSET 1 ++#define RTL8367C_INTR_IMR_METER_EXCEEDED_MASK 0x2 ++#define RTL8367C_INTR_IMR_LINK_CHANGE_OFFSET 0 ++#define RTL8367C_INTR_IMR_LINK_CHANGE_MASK 0x1 ++ ++#define RTL8367C_REG_INTR_IMS 0x1102 ++#define RTL8367C_INTR_IMS_SLIENT_START_2_OFFSET 12 ++#define RTL8367C_INTR_IMS_SLIENT_START_2_MASK 0x1000 ++#define RTL8367C_INTR_IMS_SLIENT_START_OFFSET 11 ++#define RTL8367C_INTR_IMS_SLIENT_START_MASK 0x800 ++#define RTL8367C_INTR_IMS_ACL_ACTION_OFFSET 9 ++#define RTL8367C_INTR_IMS_ACL_ACTION_MASK 0x200 ++#define RTL8367C_INTR_IMS_CABLE_DIAG_FIN_OFFSET 8 ++#define RTL8367C_INTR_IMS_CABLE_DIAG_FIN_MASK 0x100 ++#define RTL8367C_INTR_IMS_INTERRUPT_8051_OFFSET 7 ++#define RTL8367C_INTR_IMS_INTERRUPT_8051_MASK 0x80 ++#define RTL8367C_INTR_IMS_LOOP_DETECTION_OFFSET 6 ++#define RTL8367C_INTR_IMS_LOOP_DETECTION_MASK 0x40 ++#define RTL8367C_INTR_IMS_GREEN_TIMER_OFFSET 5 ++#define RTL8367C_INTR_IMS_GREEN_TIMER_MASK 0x20 ++#define RTL8367C_INTR_IMS_SPECIAL_CONGEST_OFFSET 4 ++#define RTL8367C_INTR_IMS_SPECIAL_CONGEST_MASK 0x10 ++#define RTL8367C_INTR_IMS_SPEED_CHANGE_OFFSET 3 ++#define RTL8367C_INTR_IMS_SPEED_CHANGE_MASK 0x8 ++#define RTL8367C_INTR_IMS_LEARN_OVER_OFFSET 2 ++#define RTL8367C_INTR_IMS_LEARN_OVER_MASK 0x4 ++#define RTL8367C_INTR_IMS_METER_EXCEEDED_OFFSET 1 ++#define RTL8367C_INTR_IMS_METER_EXCEEDED_MASK 0x2 ++#define RTL8367C_INTR_IMS_LINK_CHANGE_OFFSET 0 ++#define RTL8367C_INTR_IMS_LINK_CHANGE_MASK 0x1 ++ ++#define RTL8367C_REG_LEARN_OVER_INDICATOR 0x1103 ++#define RTL8367C_LEARN_OVER_INDICATOR_OFFSET 0 ++#define RTL8367C_LEARN_OVER_INDICATOR_MASK 0x7FF ++ ++#define RTL8367C_REG_SPEED_CHANGE_INDICATOR 0x1104 ++#define RTL8367C_SPEED_CHANGE_INDICATOR_OFFSET 0 ++#define RTL8367C_SPEED_CHANGE_INDICATOR_MASK 0x7FF ++ ++#define RTL8367C_REG_SPECIAL_CONGEST_INDICATOR 0x1105 ++#define RTL8367C_SPECIAL_CONGEST_INDICATOR_OFFSET 0 ++#define RTL8367C_SPECIAL_CONGEST_INDICATOR_MASK 0x7FF ++ ++#define RTL8367C_REG_PORT_LINKDOWN_INDICATOR 0x1106 ++#define RTL8367C_PORT_LINKDOWN_INDICATOR_OFFSET 0 ++#define RTL8367C_PORT_LINKDOWN_INDICATOR_MASK 0x7FF ++ ++#define RTL8367C_REG_PORT_LINKUP_INDICATOR 0x1107 ++#define RTL8367C_PORT_LINKUP_INDICATOR_OFFSET 0 ++#define RTL8367C_PORT_LINKUP_INDICATOR_MASK 0x7FF ++ ++#define RTL8367C_REG_SYSTEM_LEARN_OVER_INDICATOR 0x1108 ++#define RTL8367C_SYSTEM_LEARN_OVER_INDICATOR_OFFSET 0 ++#define RTL8367C_SYSTEM_LEARN_OVER_INDICATOR_MASK 0x1 ++ ++#define RTL8367C_REG_INTR_IMR_8051 0x1118 ++#define RTL8367C_INTR_IMR_8051_SLIENT_START_2_OFFSET 13 ++#define RTL8367C_INTR_IMR_8051_SLIENT_START_2_MASK 0x2000 ++#define RTL8367C_INTR_IMR_8051_SLIENT_START_OFFSET 12 ++#define RTL8367C_INTR_IMR_8051_SLIENT_START_MASK 0x1000 ++#define RTL8367C_INTR_IMR_8051_ACL_ACTION_OFFSET 10 ++#define RTL8367C_INTR_IMR_8051_ACL_ACTION_MASK 0x400 ++#define RTL8367C_INTR_IMR_8051_SAMOVING_8051_OFFSET 9 ++#define RTL8367C_INTR_IMR_8051_SAMOVING_8051_MASK 0x200 ++#define RTL8367C_INTR_IMR_8051_CABLE_DIAG_FIN_8051_OFFSET 8 ++#define RTL8367C_INTR_IMR_8051_CABLE_DIAG_FIN_8051_MASK 0x100 ++#define RTL8367C_INTR_IMR_8051_EEELLDP_8051_OFFSET 7 ++#define RTL8367C_INTR_IMR_8051_EEELLDP_8051_MASK 0x80 ++#define RTL8367C_INTR_IMR_8051_LOOP_DETECTION_8051_OFFSET 6 ++#define RTL8367C_INTR_IMR_8051_LOOP_DETECTION_8051_MASK 0x40 ++#define RTL8367C_INTR_IMR_8051_GREEN_TIMER_8051_OFFSET 5 ++#define RTL8367C_INTR_IMR_8051_GREEN_TIMER_8051_MASK 0x20 ++#define RTL8367C_INTR_IMR_8051_SPECIAL_CONGEST_8051_OFFSET 4 ++#define RTL8367C_INTR_IMR_8051_SPECIAL_CONGEST_8051_MASK 0x10 ++#define RTL8367C_INTR_IMR_8051_SPEED_CHANGE_8051_OFFSET 3 ++#define RTL8367C_INTR_IMR_8051_SPEED_CHANGE_8051_MASK 0x8 ++#define RTL8367C_INTR_IMR_8051_LEARN_OVER_8051_OFFSET 2 ++#define RTL8367C_INTR_IMR_8051_LEARN_OVER_8051_MASK 0x4 ++#define RTL8367C_INTR_IMR_8051_METER_EXCEEDED_8051_OFFSET 1 ++#define RTL8367C_INTR_IMR_8051_METER_EXCEEDED_8051_MASK 0x2 ++#define RTL8367C_INTR_IMR_8051_LINK_CHANGE_8051_OFFSET 0 ++#define RTL8367C_INTR_IMR_8051_LINK_CHANGE_8051_MASK 0x1 ++ ++#define RTL8367C_REG_INTR_IMS_8051 0x1119 ++#define RTL8367C_INTR_IMS_8051_SLIENT_START_2_OFFSET 13 ++#define RTL8367C_INTR_IMS_8051_SLIENT_START_2_MASK 0x2000 ++#define RTL8367C_INTR_IMS_8051_SLIENT_START_OFFSET 12 ++#define RTL8367C_INTR_IMS_8051_SLIENT_START_MASK 0x1000 ++#define RTL8367C_INTR_IMS_8051_ACL_ACTION_OFFSET 10 ++#define RTL8367C_INTR_IMS_8051_ACL_ACTION_MASK 0x400 ++#define RTL8367C_INTR_IMS_8051_SAMOVING_8051_OFFSET 9 ++#define RTL8367C_INTR_IMS_8051_SAMOVING_8051_MASK 0x200 ++#define RTL8367C_INTR_IMS_8051_CABLE_DIAG_FIN_8051_OFFSET 8 ++#define RTL8367C_INTR_IMS_8051_CABLE_DIAG_FIN_8051_MASK 0x100 ++#define RTL8367C_INTR_IMS_8051_EEELLDP_8051_OFFSET 7 ++#define RTL8367C_INTR_IMS_8051_EEELLDP_8051_MASK 0x80 ++#define RTL8367C_INTR_IMS_8051_LOOP_DETECTION_8051_OFFSET 6 ++#define RTL8367C_INTR_IMS_8051_LOOP_DETECTION_8051_MASK 0x40 ++#define RTL8367C_INTR_IMS_8051_GREEN_TIMER_8051_OFFSET 5 ++#define RTL8367C_INTR_IMS_8051_GREEN_TIMER_8051_MASK 0x20 ++#define RTL8367C_INTR_IMS_8051_SPECIAL_CONGEST_8051_OFFSET 4 ++#define RTL8367C_INTR_IMS_8051_SPECIAL_CONGEST_8051_MASK 0x10 ++#define RTL8367C_INTR_IMS_8051_SPEED_CHANGE_8051_OFFSET 3 ++#define RTL8367C_INTR_IMS_8051_SPEED_CHANGE_8051_MASK 0x8 ++#define RTL8367C_INTR_IMS_8051_LEARN_OVER_8051_OFFSET 2 ++#define RTL8367C_INTR_IMS_8051_LEARN_OVER_8051_MASK 0x4 ++#define RTL8367C_INTR_IMS_8051_METER_EXCEEDED_8051_OFFSET 1 ++#define RTL8367C_INTR_IMS_8051_METER_EXCEEDED_8051_MASK 0x2 ++#define RTL8367C_INTR_IMS_8051_LINK_CHANGE_8051_OFFSET 0 ++#define RTL8367C_INTR_IMS_8051_LINK_CHANGE_8051_MASK 0x1 ++ ++#define RTL8367C_REG_DW8051_INT_CPU 0x111a ++#define RTL8367C_DW8051_INT_CPU_OFFSET 0 ++#define RTL8367C_DW8051_INT_CPU_MASK 0x1 ++ ++#define RTL8367C_REG_LEARN_OVER_INDICATOR_8051 0x1120 ++#define RTL8367C_LEARN_OVER_INDICATOR_8051_OFFSET 0 ++#define RTL8367C_LEARN_OVER_INDICATOR_8051_MASK 0x7FF ++ ++#define RTL8367C_REG_SPEED_CHANGE_INDICATOR_8051 0x1121 ++#define RTL8367C_SPEED_CHANGE_INDICATOR_8051_OFFSET 0 ++#define RTL8367C_SPEED_CHANGE_INDICATOR_8051_MASK 0x7FF ++ ++#define RTL8367C_REG_SPECIAL_CONGEST_INDICATOR_8051 0x1122 ++#define RTL8367C_SPECIAL_CONGEST_INDICATOR_8051_OFFSET 0 ++#define RTL8367C_SPECIAL_CONGEST_INDICATOR_8051_MASK 0x7FF ++ ++#define RTL8367C_REG_PORT_LINKDOWN_INDICATOR_8051 0x1123 ++#define RTL8367C_PORT_LINKDOWN_INDICATOR_8051_OFFSET 0 ++#define RTL8367C_PORT_LINKDOWN_INDICATOR_8051_MASK 0x7FF ++ ++#define RTL8367C_REG_PORT_LINKUP_INDICATOR_8051 0x1124 ++#define RTL8367C_PORT_LINKUP_INDICATOR_8051_OFFSET 0 ++#define RTL8367C_PORT_LINKUP_INDICATOR_8051_MASK 0x7FF ++ ++#define RTL8367C_REG_DUMMY_1125 0x1125 ++ ++#define RTL8367C_REG_DUMMY_1126 0x1126 ++ ++#define RTL8367C_REG_DUMMY_1127 0x1127 ++ ++#define RTL8367C_REG_DUMMY_1128 0x1128 ++ ++#define RTL8367C_REG_DUMMY_1129 0x1129 ++ ++#define RTL8367C_REG_INTR_IMS_BUFFER_RESET 0x112a ++#define RTL8367C_INTR_IMS_BUFFER_RESET_IMR_BUFF_RESET_OFFSET 1 ++#define RTL8367C_INTR_IMS_BUFFER_RESET_IMR_BUFF_RESET_MASK 0x2 ++#define RTL8367C_INTR_IMS_BUFFER_RESET_BUFFER_RESET_OFFSET 0 ++#define RTL8367C_INTR_IMS_BUFFER_RESET_BUFFER_RESET_MASK 0x1 ++ ++#define RTL8367C_REG_INTR_IMS_8051_BUFFER_RESET 0x112b ++#define RTL8367C_INTR_IMS_8051_BUFFER_RESET_IMR_BUFF_RESET_OFFSET 1 ++#define RTL8367C_INTR_IMS_8051_BUFFER_RESET_IMR_BUFF_RESET_MASK 0x2 ++#define RTL8367C_INTR_IMS_8051_BUFFER_RESET_BUFFER_RESET_OFFSET 0 ++#define RTL8367C_INTR_IMS_8051_BUFFER_RESET_BUFFER_RESET_MASK 0x1 ++ ++#define RTL8367C_REG_GPHY_INTRPT_8051 0x112c ++#define RTL8367C_IMS_GPHY_8051_H_OFFSET 13 ++#define RTL8367C_IMS_GPHY_8051_H_MASK 0xE000 ++#define RTL8367C_IMR_GPHY_8051_H_OFFSET 10 ++#define RTL8367C_IMR_GPHY_8051_H_MASK 0x1C00 ++#define RTL8367C_IMS_GPHY_8051_OFFSET 5 ++#define RTL8367C_IMS_GPHY_8051_MASK 0x3E0 ++#define RTL8367C_IMR_GPHY_8051_OFFSET 0 ++#define RTL8367C_IMR_GPHY_8051_MASK 0x1F ++ ++#define RTL8367C_REG_GPHY_INTRPT 0x112d ++#define RTL8367C_IMS_GPHY_H_OFFSET 13 ++#define RTL8367C_IMS_GPHY_H_MASK 0xE000 ++#define RTL8367C_IMR_GPHY_H_OFFSET 10 ++#define RTL8367C_IMR_GPHY_H_MASK 0x1C00 ++#define RTL8367C_IMS_GPHY_OFFSET 5 ++#define RTL8367C_IMS_GPHY_MASK 0x3E0 ++#define RTL8367C_IMR_GPHY_OFFSET 0 ++#define RTL8367C_IMR_GPHY_MASK 0x1F ++ ++#define RTL8367C_REG_THERMAL_INTRPT 0x112e ++#define RTL8367C_IMS_TM_HIGH_OFFSET 3 ++#define RTL8367C_IMS_TM_HIGH_MASK 0x8 ++#define RTL8367C_IMR_TM_HIGH_OFFSET 2 ++#define RTL8367C_IMR_TM_HIGH_MASK 0x4 ++#define RTL8367C_IMS_TM_LOW_OFFSET 1 ++#define RTL8367C_IMS_TM_LOW_MASK 0x2 ++#define RTL8367C_IMR_TM_LOW_OFFSET 0 ++#define RTL8367C_IMR_TM_LOW_MASK 0x1 ++ ++#define RTL8367C_REG_THERMAL_INTRPT_8051 0x112f ++#define RTL8367C_IMS_TM_HIGH_8051_OFFSET 3 ++#define RTL8367C_IMS_TM_HIGH_8051_MASK 0x8 ++#define RTL8367C_IMR_TM_HIGH_8051_OFFSET 2 ++#define RTL8367C_IMR_TM_HIGH_8051_MASK 0x4 ++#define RTL8367C_IMS_TM_LOW_8051_OFFSET 1 ++#define RTL8367C_IMS_TM_LOW_8051_MASK 0x2 ++#define RTL8367C_IMR_TM_LOW_8051_OFFSET 0 ++#define RTL8367C_IMR_TM_LOW_8051_MASK 0x1 ++ ++#define RTL8367C_REG_SDS_LINK_CHG_INT 0x1130 ++#define RTL8367C_IMS_SDS_LINK_STS_C7_OFFSET 15 ++#define RTL8367C_IMS_SDS_LINK_STS_C7_MASK 0x8000 ++#define RTL8367C_IMS_SDS_LINK_STS_C6_OFFSET 14 ++#define RTL8367C_IMS_SDS_LINK_STS_C6_MASK 0x4000 ++#define RTL8367C_IMS_SDS_LINK_STS_C5_OFFSET 13 ++#define RTL8367C_IMS_SDS_LINK_STS_C5_MASK 0x2000 ++#define RTL8367C_IMS_SDS_LINK_STS_C4_OFFSET 12 ++#define RTL8367C_IMS_SDS_LINK_STS_C4_MASK 0x1000 ++#define RTL8367C_IMS_SDS_LINK_STS_C3_OFFSET 11 ++#define RTL8367C_IMS_SDS_LINK_STS_C3_MASK 0x800 ++#define RTL8367C_IMS_SDS_LINK_STS_C2_OFFSET 10 ++#define RTL8367C_IMS_SDS_LINK_STS_C2_MASK 0x400 ++#define RTL8367C_IMS_SDS_LINK_STS_C1_OFFSET 9 ++#define RTL8367C_IMS_SDS_LINK_STS_C1_MASK 0x200 ++#define RTL8367C_IMS_SDS_LINK_STS_C0_OFFSET 8 ++#define RTL8367C_IMS_SDS_LINK_STS_C0_MASK 0x100 ++#define RTL8367C_IMR_SDS_LINK_STS_C7_OFFSET 7 ++#define RTL8367C_IMR_SDS_LINK_STS_C7_MASK 0x80 ++#define RTL8367C_IMR_SDS_LINK_STS_C6_OFFSET 6 ++#define RTL8367C_IMR_SDS_LINK_STS_C6_MASK 0x40 ++#define RTL8367C_IMR_SDS_LINK_STS_C5_OFFSET 5 ++#define RTL8367C_IMR_SDS_LINK_STS_C5_MASK 0x20 ++#define RTL8367C_IMR_SDS_LINK_STS_C4_OFFSET 4 ++#define RTL8367C_IMR_SDS_LINK_STS_C4_MASK 0x10 ++#define RTL8367C_IMR_SDS_LINK_STS_C3_OFFSET 3 ++#define RTL8367C_IMR_SDS_LINK_STS_C3_MASK 0x8 ++#define RTL8367C_IMR_SDS_LINK_STS_C2_OFFSET 2 ++#define RTL8367C_IMR_SDS_LINK_STS_C2_MASK 0x4 ++#define RTL8367C_IMR_SDS_LINK_STS_C1_OFFSET 1 ++#define RTL8367C_IMR_SDS_LINK_STS_C1_MASK 0x2 ++#define RTL8367C_IMR_SDS_LINK_STS_C0_OFFSET 0 ++#define RTL8367C_IMR_SDS_LINK_STS_C0_MASK 0x1 ++ ++#define RTL8367C_REG_SDS_LINK_CHG_INT_8051 0x1131 ++#define RTL8367C_IMS_SDS_LINK_STS_C7_8051_OFFSET 15 ++#define RTL8367C_IMS_SDS_LINK_STS_C7_8051_MASK 0x8000 ++#define RTL8367C_IMS_SDS_LINK_STS_C6_8051_OFFSET 14 ++#define RTL8367C_IMS_SDS_LINK_STS_C6_8051_MASK 0x4000 ++#define RTL8367C_IMS_SDS_LINK_STS_C5_8051_OFFSET 13 ++#define RTL8367C_IMS_SDS_LINK_STS_C5_8051_MASK 0x2000 ++#define RTL8367C_IMS_SDS_LINK_STS_C4_8051_OFFSET 12 ++#define RTL8367C_IMS_SDS_LINK_STS_C4_8051_MASK 0x1000 ++#define RTL8367C_IMS_SDS_LINK_STS_C3_8051_OFFSET 11 ++#define RTL8367C_IMS_SDS_LINK_STS_C3_8051_MASK 0x800 ++#define RTL8367C_IMS_SDS_LINK_STS_C2_8051_OFFSET 10 ++#define RTL8367C_IMS_SDS_LINK_STS_C2_8051_MASK 0x400 ++#define RTL8367C_IMS_SDS_LINK_STS_C1_8051_OFFSET 9 ++#define RTL8367C_IMS_SDS_LINK_STS_C1_8051_MASK 0x200 ++#define RTL8367C_IMS_SDS_LINK_STS_C0_8051_OFFSET 8 ++#define RTL8367C_IMS_SDS_LINK_STS_C0_8051_MASK 0x100 ++#define RTL8367C_IMR_SDS_LINK_STS_C7_8051_OFFSET 7 ++#define RTL8367C_IMR_SDS_LINK_STS_C7_8051_MASK 0x80 ++#define RTL8367C_IMR_SDS_LINK_STS_C6_8051_OFFSET 6 ++#define RTL8367C_IMR_SDS_LINK_STS_C6_8051_MASK 0x40 ++#define RTL8367C_IMR_SDS_LINK_STS_C5_8051_OFFSET 5 ++#define RTL8367C_IMR_SDS_LINK_STS_C5_8051_MASK 0x20 ++#define RTL8367C_IMR_SDS_LINK_STS_C4_8051_OFFSET 4 ++#define RTL8367C_IMR_SDS_LINK_STS_C4_8051_MASK 0x10 ++#define RTL8367C_IMR_SDS_LINK_STS_C3_8051_OFFSET 3 ++#define RTL8367C_IMR_SDS_LINK_STS_C3_8051_MASK 0x8 ++#define RTL8367C_IMR_SDS_LINK_STS_C2_8051_OFFSET 2 ++#define RTL8367C_IMR_SDS_LINK_STS_C2_8051_MASK 0x4 ++#define RTL8367C_IMR_SDS_LINK_STS_C1_8051_OFFSET 1 ++#define RTL8367C_IMR_SDS_LINK_STS_C1_8051_MASK 0x2 ++#define RTL8367C_IMR_SDS_LINK_STS_C0_8051_OFFSET 0 ++#define RTL8367C_IMR_SDS_LINK_STS_C0_8051_MASK 0x1 ++ ++/* (16'h1200)swcore_reg */ ++ ++#define RTL8367C_REG_MAX_LENGTH_LIMINT_IPG 0x1200 ++#define RTL8367C_MAX_LENTH_CTRL_OFFSET 13 ++#define RTL8367C_MAX_LENTH_CTRL_MASK 0x6000 ++#define RTL8367C_PAGES_BEFORE_FCDROP_OFFSET 6 ++#define RTL8367C_PAGES_BEFORE_FCDROP_MASK 0x1FC0 ++#define RTL8367C_CHECK_MIN_IPG_RXDV_OFFSET 5 ++#define RTL8367C_CHECK_MIN_IPG_RXDV_MASK 0x20 ++#define RTL8367C_LIMIT_IPG_CFG_OFFSET 0 ++#define RTL8367C_LIMIT_IPG_CFG_MASK 0x1F ++ ++#define RTL8367C_REG_IOL_RXDROP_CFG 0x1201 ++#define RTL8367C_RX_IOL_MAX_LENGTH_CFG_OFFSET 13 ++#define RTL8367C_RX_IOL_MAX_LENGTH_CFG_MASK 0x2000 ++#define RTL8367C_RX_IOL_ERROR_LENGTH_CFG_OFFSET 12 ++#define RTL8367C_RX_IOL_ERROR_LENGTH_CFG_MASK 0x1000 ++#define RTL8367C_RX_NODROP_PAUSE_CFG_OFFSET 8 ++#define RTL8367C_RX_NODROP_PAUSE_CFG_MASK 0x100 ++#define RTL8367C_RX_DV_CNT_CFG_OFFSET 0 ++#define RTL8367C_RX_DV_CNT_CFG_MASK 0x3F ++ ++#define RTL8367C_REG_VS_TPID 0x1202 ++ ++#define RTL8367C_REG_INBW_BOUND 0x1203 ++#define RTL8367C_LBOUND_OFFSET 4 ++#define RTL8367C_LBOUND_MASK 0xF0 ++#define RTL8367C_HBOUND_OFFSET 0 ++#define RTL8367C_HBOUND_MASK 0xF ++ ++#define RTL8367C_REG_CFG_TX_ITFSP_OP 0x1204 ++#define RTL8367C_MASK_OFFSET 1 ++#define RTL8367C_MASK_MASK 0x2 ++#define RTL8367C_OP_OFFSET 0 ++#define RTL8367C_OP_MASK 0x1 ++ ++#define RTL8367C_REG_INBW_BOUND2 0x1205 ++#define RTL8367C_LBOUND2_H_OFFSET 9 ++#define RTL8367C_LBOUND2_H_MASK 0x200 ++#define RTL8367C_HBOUND2_H_OFFSET 8 ++#define RTL8367C_HBOUND2_H_MASK 0x100 ++#define RTL8367C_LBOUND2_OFFSET 4 ++#define RTL8367C_LBOUND2_MASK 0xF0 ++#define RTL8367C_HBOUND2_OFFSET 0 ++#define RTL8367C_HBOUND2_MASK 0xF ++ ++#define RTL8367C_REG_CFG_48PASS1_DROP 0x1206 ++#define RTL8367C_CFG_48PASS1_DROP_OFFSET 0 ++#define RTL8367C_CFG_48PASS1_DROP_MASK 0x1 ++ ++#define RTL8367C_REG_CFG_BACKPRESSURE 0x1207 ++#define RTL8367C_LONGTXE_OFFSET 12 ++#define RTL8367C_LONGTXE_MASK 0x1000 ++#define RTL8367C_EN_BYPASS_ERROR_OFFSET 8 ++#define RTL8367C_EN_BYPASS_ERROR_MASK 0x100 ++#define RTL8367C_EN_BACKPRESSURE_OFFSET 4 ++#define RTL8367C_EN_BACKPRESSURE_MASK 0x10 ++#define RTL8367C_EN_48_PASS_1_OFFSET 0 ++#define RTL8367C_EN_48_PASS_1_MASK 0x1 ++ ++#define RTL8367C_REG_CFG_UNHIOL 0x1208 ++#define RTL8367C_IOL_BACKOFF_OFFSET 12 ++#define RTL8367C_IOL_BACKOFF_MASK 0x1000 ++#define RTL8367C_BACKOFF_RANDOM_TIME_OFFSET 8 ++#define RTL8367C_BACKOFF_RANDOM_TIME_MASK 0x100 ++#define RTL8367C_DISABLE_BACK_OFF_OFFSET 4 ++#define RTL8367C_DISABLE_BACK_OFF_MASK 0x10 ++#define RTL8367C_IPG_COMPENSATION_OFFSET 0 ++#define RTL8367C_IPG_COMPENSATION_MASK 0x1 ++ ++#define RTL8367C_REG_SWITCH_MAC0 0x1209 ++ ++#define RTL8367C_REG_SWITCH_MAC1 0x120a ++ ++#define RTL8367C_REG_SWITCH_MAC2 0x120b ++ ++#define RTL8367C_REG_SWITCH_CTRL0 0x120c ++#define RTL8367C_REMARKING_DSCP_ENABLE_OFFSET 8 ++#define RTL8367C_REMARKING_DSCP_ENABLE_MASK 0x100 ++#define RTL8367C_SHORT_IPG_OFFSET 4 ++#define RTL8367C_SHORT_IPG_MASK 0x10 ++#define RTL8367C_PAUSE_MAX128_OFFSET 0 ++#define RTL8367C_PAUSE_MAX128_MASK 0x1 ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_CTRL0 0x120d ++#define RTL8367C_INTPRI1_DSCP_OFFSET 8 ++#define RTL8367C_INTPRI1_DSCP_MASK 0x3F00 ++#define RTL8367C_INTPRI0_DSCP_OFFSET 0 ++#define RTL8367C_INTPRI0_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_CTRL1 0x120e ++#define RTL8367C_INTPRI3_DSCP_OFFSET 8 ++#define RTL8367C_INTPRI3_DSCP_MASK 0x3F00 ++#define RTL8367C_INTPRI2_DSCP_OFFSET 0 ++#define RTL8367C_INTPRI2_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_CTRL2 0x120f ++#define RTL8367C_INTPRI5_DSCP_OFFSET 8 ++#define RTL8367C_INTPRI5_DSCP_MASK 0x3F00 ++#define RTL8367C_INTPRI4_DSCP_OFFSET 0 ++#define RTL8367C_INTPRI4_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_DSCP_REMARK_CTRL3 0x1210 ++#define RTL8367C_INTPRI7_DSCP_OFFSET 8 ++#define RTL8367C_INTPRI7_DSCP_MASK 0x3F00 ++#define RTL8367C_INTPRI6_DSCP_OFFSET 0 ++#define RTL8367C_INTPRI6_DSCP_MASK 0x3F ++ ++#define RTL8367C_REG_QOS_1Q_REMARK_CTRL0 0x1211 ++#define RTL8367C_INTPRI3_PRI_OFFSET 12 ++#define RTL8367C_INTPRI3_PRI_MASK 0x7000 ++#define RTL8367C_INTPRI2_PRI_OFFSET 8 ++#define RTL8367C_INTPRI2_PRI_MASK 0x700 ++#define RTL8367C_INTPRI1_PRI_OFFSET 4 ++#define RTL8367C_INTPRI1_PRI_MASK 0x70 ++#define RTL8367C_INTPRI0_PRI_OFFSET 0 ++#define RTL8367C_INTPRI0_PRI_MASK 0x7 ++ ++#define RTL8367C_REG_QOS_1Q_REMARK_CTRL1 0x1212 ++#define RTL8367C_INTPRI7_PRI_OFFSET 12 ++#define RTL8367C_INTPRI7_PRI_MASK 0x7000 ++#define RTL8367C_INTPRI6_PRI_OFFSET 8 ++#define RTL8367C_INTPRI6_PRI_MASK 0x700 ++#define RTL8367C_INTPRI5_PRI_OFFSET 4 ++#define RTL8367C_INTPRI5_PRI_MASK 0x70 ++#define RTL8367C_INTPRI4_PRI_OFFSET 0 ++#define RTL8367C_INTPRI4_PRI_MASK 0x7 ++ ++#define RTL8367C_REG_PKTGEN_COMMAND 0x1213 ++#define RTL8367C_PKTGEN_STOP_OFFSET 8 ++#define RTL8367C_PKTGEN_STOP_MASK 0x100 ++#define RTL8367C_PKTGEN_START_OFFSET 4 ++#define RTL8367C_PKTGEN_START_MASK 0x10 ++#define RTL8367C_PKTGEN_BYPASS_FLOWCONTROL_OFFSET 0 ++#define RTL8367C_PKTGEN_BYPASS_FLOWCONTROL_MASK 0x1 ++ ++#define RTL8367C_REG_SW_DUMMY0 0x1214 ++#define RTL8367C_SW_DUMMY0_DUMMY_OFFSET 4 ++#define RTL8367C_SW_DUMMY0_DUMMY_MASK 0xFFF0 ++#define RTL8367C_EEE_DEFER_TXLPI_OFFSET 3 ++#define RTL8367C_EEE_DEFER_TXLPI_MASK 0x8 ++#define RTL8367C_INGRESSBW_BYPASS_EN_OFFSET 2 ++#define RTL8367C_INGRESSBW_BYPASS_EN_MASK 0x4 ++#define RTL8367C_CFG_RX_MIN_OFFSET 0 ++#define RTL8367C_CFG_RX_MIN_MASK 0x3 ++ ++#define RTL8367C_REG_SW_DUMMY1 0x1215 ++ ++#define RTL8367C_REG_PKTGEN_PAUSE_TIME 0x1216 ++ ++#define RTL8367C_REG_SVLAN_UPLINK_PORTMASK 0x1218 ++#define RTL8367C_SVLAN_UPLINK_PORTMASK_OFFSET 0 ++#define RTL8367C_SVLAN_UPLINK_PORTMASK_MASK 0x7FF ++ ++#define RTL8367C_REG_CPU_PORT_MASK 0x1219 ++#define RTL8367C_CPU_PORT_MASK_OFFSET 0 ++#define RTL8367C_CPU_PORT_MASK_MASK 0x7FF ++ ++#define RTL8367C_REG_CPU_CTRL 0x121a ++#define RTL8367C_CPU_TRAP_PORT_EXT_OFFSET 10 ++#define RTL8367C_CPU_TRAP_PORT_EXT_MASK 0x400 ++#define RTL8367C_CPU_TAG_FORMAT_OFFSET 9 ++#define RTL8367C_CPU_TAG_FORMAT_MASK 0x200 ++#define RTL8367C_IOL_16DROP_OFFSET 8 ++#define RTL8367C_IOL_16DROP_MASK 0x100 ++#define RTL8367C_CPU_TAG_RXBYTECOUNT_OFFSET 7 ++#define RTL8367C_CPU_TAG_RXBYTECOUNT_MASK 0x80 ++#define RTL8367C_CPU_TAG_POSITION_OFFSET 6 ++#define RTL8367C_CPU_TAG_POSITION_MASK 0x40 ++#define RTL8367C_CPU_TRAP_PORT_OFFSET 3 ++#define RTL8367C_CPU_TRAP_PORT_MASK 0x38 ++#define RTL8367C_CPU_INSERTMODE_OFFSET 1 ++#define RTL8367C_CPU_INSERTMODE_MASK 0x6 ++#define RTL8367C_CPU_EN_OFFSET 0 ++#define RTL8367C_CPU_EN_MASK 0x1 ++ ++#define RTL8367C_REG_MIRROR_CTRL 0x121c ++#define RTL8367C_MIRROR_CTRL_DUMMY_OFFSET 12 ++#define RTL8367C_MIRROR_CTRL_DUMMY_MASK 0xF000 ++#define RTL8367C_MIRROR_ISO_OFFSET 11 ++#define RTL8367C_MIRROR_ISO_MASK 0x800 ++#define RTL8367C_MIRROR_TX_OFFSET 10 ++#define RTL8367C_MIRROR_TX_MASK 0x400 ++#define RTL8367C_MIRROR_RX_OFFSET 9 ++#define RTL8367C_MIRROR_RX_MASK 0x200 ++#define RTL8367C_MIRROR_MONITOR_PORT_OFFSET 4 ++#define RTL8367C_MIRROR_MONITOR_PORT_MASK 0xF0 ++#define RTL8367C_MIRROR_SOURCE_PORT_OFFSET 0 ++#define RTL8367C_MIRROR_SOURCE_PORT_MASK 0xF ++ ++#define RTL8367C_REG_FLOWCTRL_CTRL0 0x121d ++#define RTL8367C_FLOWCTRL_TYPE_OFFSET 15 ++#define RTL8367C_FLOWCTRL_TYPE_MASK 0x8000 ++#define RTL8367C_DROP_ALL_THRESHOLD_OFFSET 5 ++#define RTL8367C_DROP_ALL_THRESHOLD_MASK 0x7FE0 ++#define RTL8367C_DROP_ALL_THRESHOLD_MSB_OFFSET 4 ++#define RTL8367C_DROP_ALL_THRESHOLD_MSB_MASK 0x10 ++#define RTL8367C_ITFSP_REG_OFFSET 0 ++#define RTL8367C_ITFSP_REG_MASK 0x7 ++ ++#define RTL8367C_REG_FLOWCTRL_ALL_ON 0x121e ++#define RTL8367C_CFG_RLDPACT_OFFSET 12 ++#define RTL8367C_CFG_RLDPACT_MASK 0x1000 ++#define RTL8367C_FLOWCTRL_ALL_ON_THRESHOLD_OFFSET 0 ++#define RTL8367C_FLOWCTRL_ALL_ON_THRESHOLD_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_SYS_ON 0x121f ++#define RTL8367C_FLOWCTRL_SYS_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_SYS_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_SYS_OFF 0x1220 ++#define RTL8367C_FLOWCTRL_SYS_OFF_OFFSET 0 ++#define RTL8367C_FLOWCTRL_SYS_OFF_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_SHARE_ON 0x1221 ++#define RTL8367C_FLOWCTRL_SHARE_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_SHARE_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_SHARE_OFF 0x1222 ++#define RTL8367C_FLOWCTRL_SHARE_OFF_OFFSET 0 ++#define RTL8367C_FLOWCTRL_SHARE_OFF_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_FCOFF_SYS_ON 0x1223 ++#define RTL8367C_FLOWCTRL_FCOFF_SYS_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_FCOFF_SYS_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_FCOFF_SYS_OFF 0x1224 ++#define RTL8367C_FLOWCTRL_FCOFF_SYS_OFF_OFFSET 0 ++#define RTL8367C_FLOWCTRL_FCOFF_SYS_OFF_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_ON 0x1225 ++#define RTL8367C_FLOWCTRL_FCOFF_SHARE_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_FCOFF_SHARE_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_OFF 0x1226 ++#define RTL8367C_FLOWCTRL_FCOFF_SHARE_OFF_OFFSET 0 ++#define RTL8367C_FLOWCTRL_FCOFF_SHARE_OFF_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT_ON 0x1227 ++#define RTL8367C_FLOWCTRL_PORT_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT_OFF 0x1228 ++#define RTL8367C_FLOWCTRL_PORT_OFF_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT_OFF_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_ON 0x1229 ++#define RTL8367C_FLOWCTRL_PORT_PRIVATE_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT_PRIVATE_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_OFF 0x122a ++#define RTL8367C_FLOWCTRL_PORT_PRIVATE_OFF_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT_PRIVATE_OFF_MASK 0x7FF ++ ++#define RTL8367C_REG_RRCP_CTRL0 0x122b ++#define RTL8367C_COL_SEL_OFFSET 14 ++#define RTL8367C_COL_SEL_MASK 0x4000 ++#define RTL8367C_CRS_SEL_OFFSET 13 ++#define RTL8367C_CRS_SEL_MASK 0x2000 ++#define RTL8367C_RRCP_PBVLAN_EN_OFFSET 11 ++#define RTL8367C_RRCP_PBVLAN_EN_MASK 0x800 ++#define RTL8367C_RRCPV3_SECURITY_CRC_OFFSET 10 ++#define RTL8367C_RRCPV3_SECURITY_CRC_MASK 0x400 ++#define RTL8367C_RRCPV3_HANDLE_OFFSET 8 ++#define RTL8367C_RRCPV3_HANDLE_MASK 0x300 ++#define RTL8367C_RRCPV1_MALFORMED_ACT_OFFSET 5 ++#define RTL8367C_RRCPV1_MALFORMED_ACT_MASK 0x60 ++#define RTL8367C_RRCP_VLANLEAKY_OFFSET 4 ++#define RTL8367C_RRCP_VLANLEAKY_MASK 0x10 ++#define RTL8367C_RRCPV1_SECURITY_CRC_GET_OFFSET 3 ++#define RTL8367C_RRCPV1_SECURITY_CRC_GET_MASK 0x8 ++#define RTL8367C_RRCPV1_SECURITY_CRC_SET_OFFSET 2 ++#define RTL8367C_RRCPV1_SECURITY_CRC_SET_MASK 0x4 ++#define RTL8367C_RRCPV1_HANDLE_OFFSET 1 ++#define RTL8367C_RRCPV1_HANDLE_MASK 0x2 ++#define RTL8367C_RRCP_ENABLE_OFFSET 0 ++#define RTL8367C_RRCP_ENABLE_MASK 0x1 ++ ++#define RTL8367C_REG_RRCP_CTRL1 0x122c ++#define RTL8367C_RRCP_ADMIN_PMSK_OFFSET 8 ++#define RTL8367C_RRCP_ADMIN_PMSK_MASK 0xFF00 ++#define RTL8367C_RRCP_AUTH_PMSK_OFFSET 0 ++#define RTL8367C_RRCP_AUTH_PMSK_MASK 0xFF ++ ++#define RTL8367C_REG_RRCP_CTRL2 0x122d ++#define RTL8367C_RRCPV1_HELLOFWD_TAG_OFFSET 9 ++#define RTL8367C_RRCPV1_HELLOFWD_TAG_MASK 0x600 ++#define RTL8367C_RRCP_FWD_TAG_OFFSET 7 ++#define RTL8367C_RRCP_FWD_TAG_MASK 0x180 ++#define RTL8367C_RRCPV1_REPLY_TAG_OFFSET 6 ++#define RTL8367C_RRCPV1_REPLY_TAG_MASK 0x40 ++#define RTL8367C_RRCPV1_HELLO_COUNT_OFFSET 3 ++#define RTL8367C_RRCPV1_HELLO_COUNT_MASK 0x38 ++#define RTL8367C_RRCPV1_HELLO_PEDIOD_OFFSET 0 ++#define RTL8367C_RRCPV1_HELLO_PEDIOD_MASK 0x3 ++ ++#define RTL8367C_REG_RRCP_CTRL3 0x122e ++#define RTL8367C_RRCP_TAG_PRIORITY_OFFSET 13 ++#define RTL8367C_RRCP_TAG_PRIORITY_MASK 0xE000 ++#define RTL8367C_RRCP_TAG_VID_OFFSET 0 ++#define RTL8367C_RRCP_TAG_VID_MASK 0xFFF ++ ++#define RTL8367C_REG_FLOWCTRL_FCOFF_PORT_ON 0x122f ++#define RTL8367C_FLOWCTRL_FCOFF_PORT_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_FCOFF_PORT_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_FCOFF_PORT_OFF 0x1230 ++#define RTL8367C_FLOWCTRL_FCOFF_PORT_OFF_OFFSET 0 ++#define RTL8367C_FLOWCTRL_FCOFF_PORT_OFF_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_ON 0x1231 ++#define RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF 0x1232 ++#define RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF_OFFSET 0 ++#define RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_JUMBO_SYS_ON 0x1233 ++#define RTL8367C_FLOWCTRL_JUMBO_SYS_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_JUMBO_SYS_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_JUMBO_SYS_OFF 0x1234 ++#define RTL8367C_FLOWCTRL_JUMBO_SYS_OFF_OFFSET 0 ++#define RTL8367C_FLOWCTRL_JUMBO_SYS_OFF_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_ON 0x1235 ++#define RTL8367C_FLOWCTRL_JUMBO_SHARE_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_JUMBO_SHARE_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_OFF 0x1236 ++#define RTL8367C_FLOWCTRL_JUMBO_SHARE_OFF_OFFSET 0 ++#define RTL8367C_FLOWCTRL_JUMBO_SHARE_OFF_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_JUMBO_PORT_ON 0x1237 ++#define RTL8367C_FLOWCTRL_JUMBO_PORT_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_JUMBO_PORT_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_JUMBO_PORT_OFF 0x1238 ++#define RTL8367C_FLOWCTRL_JUMBO_PORT_OFF_OFFSET 0 ++#define RTL8367C_FLOWCTRL_JUMBO_PORT_OFF_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_ON 0x1239 ++#define RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_ON_OFFSET 0 ++#define RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_ON_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF 0x123a ++#define RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF_OFFSET 0 ++#define RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_JUMBO_SIZE 0x123b ++#define RTL8367C_JUMBO_MODE_OFFSET 2 ++#define RTL8367C_JUMBO_MODE_MASK 0x4 ++#define RTL8367C_JUMBO_SIZE_OFFSET 0 ++#define RTL8367C_JUMBO_SIZE_MASK 0x3 ++ ++#define RTL8367C_REG_FLOWCTRL_TOTAL_PAGE_COUNTER 0x124c ++#define RTL8367C_FLOWCTRL_TOTAL_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_FLOWCTRL_TOTAL_PAGE_COUNTER_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PUBLIC_PAGE_COUNTER 0x124d ++#define RTL8367C_FLOWCTRL_PUBLIC_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PUBLIC_PAGE_COUNTER_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_TOTAL_PAGE_MAX 0x124e ++#define RTL8367C_FLOWCTRL_TOTAL_PAGE_MAX_OFFSET 0 ++#define RTL8367C_FLOWCTRL_TOTAL_PAGE_MAX_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PUBLIC_PAGE_MAX 0x124f ++#define RTL8367C_FLOWCTRL_PUBLIC_PAGE_MAX_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PUBLIC_PAGE_MAX_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT0_PAGE_COUNTER 0x1250 ++#define RTL8367C_FLOWCTRL_PORT0_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT0_PAGE_COUNTER_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT1_PAGE_COUNTER 0x1251 ++#define RTL8367C_FLOWCTRL_PORT1_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT1_PAGE_COUNTER_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT2_PAGE_COUNTER 0x1252 ++#define RTL8367C_FLOWCTRL_PORT2_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT2_PAGE_COUNTER_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT3_PAGE_COUNTER 0x1253 ++#define RTL8367C_FLOWCTRL_PORT3_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT3_PAGE_COUNTER_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT4_PAGE_COUNTER 0x1254 ++#define RTL8367C_FLOWCTRL_PORT4_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT4_PAGE_COUNTER_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT5_PAGE_COUNTER 0x1255 ++#define RTL8367C_FLOWCTRL_PORT5_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT5_PAGE_COUNTER_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT6_PAGE_COUNTER 0x1256 ++#define RTL8367C_FLOWCTRL_PORT6_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT6_PAGE_COUNTER_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT7_PAGE_COUNTER 0x1257 ++#define RTL8367C_FLOWCTRL_PORT7_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT7_PAGE_COUNTER_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PUBLIC_FCOFF_PAGE_COUNTER 0x1258 ++#define RTL8367C_FLOWCTRL_PUBLIC_FCOFF_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PUBLIC_FCOFF_PAGE_COUNTER_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PUBLIC_JUMBO_PAGE_COUNTER 0x1259 ++#define RTL8367C_FLOWCTRL_PUBLIC_JUMBO_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PUBLIC_JUMBO_PAGE_COUNTER_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_MAX_PUBLIC_FCOFF_PAGE_COUNTER 0x125a ++#define RTL8367C_FLOWCTRL_MAX_PUBLIC_FCOFF_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_FLOWCTRL_MAX_PUBLIC_FCOFF_PAGE_COUNTER_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_MAX_PUBLIC_JUMBO_PAGE_COUNTER 0x125b ++#define RTL8367C_FLOWCTRL_MAX_PUBLIC_JUMBO_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_FLOWCTRL_MAX_PUBLIC_JUMBO_PAGE_COUNTER_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT0_PAGE_MAX 0x1260 ++#define RTL8367C_FLOWCTRL_PORT0_PAGE_MAX_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT0_PAGE_MAX_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT1_PAGE_MAX 0x1261 ++#define RTL8367C_FLOWCTRL_PORT1_PAGE_MAX_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT1_PAGE_MAX_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT2_PAGE_MAX 0x1262 ++#define RTL8367C_FLOWCTRL_PORT2_PAGE_MAX_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT2_PAGE_MAX_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT3_PAGE_MAX 0x1263 ++#define RTL8367C_FLOWCTRL_PORT3_PAGE_MAX_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT3_PAGE_MAX_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT4_PAGE_MAX 0x1264 ++#define RTL8367C_FLOWCTRL_PORT4_PAGE_MAX_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT4_PAGE_MAX_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT5_PAGE_MAX 0x1265 ++#define RTL8367C_FLOWCTRL_PORT5_PAGE_MAX_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT5_PAGE_MAX_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT6_PAGE_MAX 0x1266 ++#define RTL8367C_FLOWCTRL_PORT6_PAGE_MAX_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT6_PAGE_MAX_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT7_PAGE_MAX 0x1267 ++#define RTL8367C_FLOWCTRL_PORT7_PAGE_MAX_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT7_PAGE_MAX_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PAGE_COUNT_CLEAR 0x1268 ++#define RTL8367C_DIS_SKIP_FP_OFFSET 1 ++#define RTL8367C_DIS_SKIP_FP_MASK 0x2 ++#define RTL8367C_PAGE_COUNT_CLEAR_OFFSET 0 ++#define RTL8367C_PAGE_COUNT_CLEAR_MASK 0x1 ++ ++#define RTL8367C_REG_FLOWCTRL_PORT8_PAGE_MAX 0x1269 ++#define RTL8367C_FLOWCTRL_PORT8_PAGE_MAX_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT8_PAGE_MAX_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT9_PAGE_MAX 0x126a ++#define RTL8367C_FLOWCTRL_PORT9_PAGE_MAX_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT9_PAGE_MAX_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT10_PAGE_MAX 0x126b ++#define RTL8367C_FLOWCTRL_PORT10_PAGE_MAX_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT10_PAGE_MAX_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT8_PAGE_COUNTER 0x126c ++#define RTL8367C_FLOWCTRL_PORT8_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT8_PAGE_COUNTER_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT9_PAGE_COUNTER 0x126d ++#define RTL8367C_FLOWCTRL_PORT9_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT9_PAGE_COUNTER_MASK 0x7FF ++ ++#define RTL8367C_REG_FLOWCTRL_PORT10_PAGE_COUNTER 0x126e ++#define RTL8367C_FLOWCTRL_PORT10_PAGE_COUNTER_OFFSET 0 ++#define RTL8367C_FLOWCTRL_PORT10_PAGE_COUNTER_MASK 0x7FF ++ ++#define RTL8367C_REG_RRCP_CTRL1_H 0x126f ++#define RTL8367C_RRCP_ADMIN_PMSK_P10_8_OFFSET 3 ++#define RTL8367C_RRCP_ADMIN_PMSK_P10_8_MASK 0x38 ++#define RTL8367C_RRCP_AUTH_PMSK_P10_8_OFFSET 0 ++#define RTL8367C_RRCP_AUTH_PMSK_P10_8_MASK 0x7 ++ ++#define RTL8367C_REG_EMA_CTRL0 0x1270 ++#define RTL8367C_CFG_DVSE_VIAROM_OFFSET 13 ++#define RTL8367C_CFG_DVSE_VIAROM_MASK 0x2000 ++#define RTL8367C_CFG_DVSE_MIBRAM_OFFSET 12 ++#define RTL8367C_CFG_DVSE_MIBRAM_MASK 0x1000 ++#define RTL8367C_CFG_DVSE_IROM_OFFSET 11 ++#define RTL8367C_CFG_DVSE_IROM_MASK 0x800 ++#define RTL8367C_CFG_DVSE_ERAM_OFFSET 10 ++#define RTL8367C_CFG_DVSE_ERAM_MASK 0x400 ++#define RTL8367C_CFG_DVSE_IRAM_OFFSET 9 ++#define RTL8367C_CFG_DVSE_IRAM_MASK 0x200 ++#define RTL8367C_CFG_DVSE_NICRAM_OFFSET 8 ++#define RTL8367C_CFG_DVSE_NICRAM_MASK 0x100 ++#define RTL8367C_CFG_DVSE_CVLANRAM_OFFSET 7 ++#define RTL8367C_CFG_DVSE_CVLANRAM_MASK 0x80 ++#define RTL8367C_CFG_DVSE_ACTRAM_OFFSET 6 ++#define RTL8367C_CFG_DVSE_ACTRAM_MASK 0x40 ++#define RTL8367C_CFG_DVSE_INQRAM_OFFSET 5 ++#define RTL8367C_CFG_DVSE_INQRAM_MASK 0x20 ++#define RTL8367C_CFG_DVSE_HSARAM_OFFSET 4 ++#define RTL8367C_CFG_DVSE_HSARAM_MASK 0x10 ++#define RTL8367C_CFG_DVSE_OUTQRAM_OFFSET 3 ++#define RTL8367C_CFG_DVSE_OUTQRAM_MASK 0x8 ++#define RTL8367C_CFG_DVSE_HTRAM_OFFSET 2 ++#define RTL8367C_CFG_DVSE_HTRAM_MASK 0x4 ++#define RTL8367C_CFG_DVSE_PBRAM_OFFSET 1 ++#define RTL8367C_CFG_DVSE_PBRAM_MASK 0x2 ++#define RTL8367C_CFG_DVSE_L2RAM_OFFSET 0 ++#define RTL8367C_CFG_DVSE_L2RAM_MASK 0x1 ++ ++#define RTL8367C_REG_EMA_CTRL1 0x1271 ++#define RTL8367C_CFG_DVS_OUTQRAM_OFFSET 12 ++#define RTL8367C_CFG_DVS_OUTQRAM_MASK 0xF000 ++#define RTL8367C_CFG_DVS_HTRAM_OFFSET 8 ++#define RTL8367C_CFG_DVS_HTRAM_MASK 0x700 ++#define RTL8367C_CFG_DVS_PBRAM_OFFSET 4 ++#define RTL8367C_CFG_DVS_PBRAM_MASK 0xF0 ++#define RTL8367C_CFG_DVS_L2RAM_OFFSET 0 ++#define RTL8367C_CFG_DVS_L2RAM_MASK 0xF ++ ++#define RTL8367C_REG_EMA_CTRL2 0x1272 ++#define RTL8367C_CFG_DVS_CVLANRAM_OFFSET 12 ++#define RTL8367C_CFG_DVS_CVLANRAM_MASK 0xF000 ++#define RTL8367C_CFG_DVS_ACTRAM_OFFSET 8 ++#define RTL8367C_CFG_DVS_ACTRAM_MASK 0xF00 ++#define RTL8367C_CFG_DVS_INQRAM_OFFSET 4 ++#define RTL8367C_CFG_DVS_INQRAM_MASK 0xF0 ++#define RTL8367C_CFG_DVS_HSARAM_OFFSET 0 ++#define RTL8367C_CFG_DVS_HSARAM_MASK 0xF ++ ++#define RTL8367C_REG_EMA_CTRL3 0x1273 ++#define RTL8367C_CFG_DVS_IROM_OFFSET 12 ++#define RTL8367C_CFG_DVS_IROM_MASK 0xF000 ++#define RTL8367C_CFG_DVS_ERAM_OFFSET 8 ++#define RTL8367C_CFG_DVS_ERAM_MASK 0xF00 ++#define RTL8367C_CFG_DVS_IRAM_OFFSET 4 ++#define RTL8367C_CFG_DVS_IRAM_MASK 0xF0 ++#define RTL8367C_CFG_DVS_NICRAM_OFFSET 0 ++#define RTL8367C_CFG_DVS_NICRAM_MASK 0xF ++ ++#define RTL8367C_REG_EMA_CTRL4 0x1274 ++#define RTL8367C_CFG_DVS_VIAROM_OFFSET 4 ++#define RTL8367C_CFG_DVS_VIAROM_MASK 0xF0 ++#define RTL8367C_CFG_DVS_MIBRAM_OFFSET 0 ++#define RTL8367C_CFG_DVS_MIBRAM_MASK 0xF ++ ++#define RTL8367C_REG_DIAG_MODE 0x1275 ++#define RTL8367C_DIAG_MODE_OFFSET 0 ++#define RTL8367C_DIAG_MODE_MASK 0x1F ++ ++#define RTL8367C_REG_BIST_MODE 0x1276 ++ ++#define RTL8367C_REG_STS_BIST_DONE 0x1277 ++ ++#define RTL8367C_REG_STS_BIST_RLT0 0x1278 ++#define RTL8367C_STS_BIST_RLT0_OFFSET 0 ++#define RTL8367C_STS_BIST_RLT0_MASK 0x1 ++ ++#define RTL8367C_REG_STS_BIST_RLT1 0x1279 ++ ++#define RTL8367C_REG_STS_BIST_RLT2 0x127a ++ ++#define RTL8367C_REG_STS_BIST_RLT3 0x127b ++#define RTL8367C_STS_BIST_RLT3_OFFSET 0 ++#define RTL8367C_STS_BIST_RLT3_MASK 0x3FF ++ ++#define RTL8367C_REG_STS_BIST_RLT4 0x127c ++#define RTL8367C_STS_BIST_RLT4_OFFSET 0 ++#define RTL8367C_STS_BIST_RLT4_MASK 0x7 ++ ++#define RTL8367C_REG_VIAROM_MISR 0x127d ++ ++#define RTL8367C_REG_DRF_BIST_MODE 0x1280 ++#define RTL8367C_DRF_TCAMDEL_OFFSET 15 ++#define RTL8367C_DRF_TCAMDEL_MASK 0x8000 ++#define RTL8367C_CFG_DRF_BIST_MODE_OFFSET 0 ++#define RTL8367C_CFG_DRF_BIST_MODE_MASK 0x7FFF ++ ++#define RTL8367C_REG_STS_DRF_BIST 0x1281 ++#define RTL8367C_STS_DRF_BIST_OFFSET 0 ++#define RTL8367C_STS_DRF_BIST_MASK 0x7FFF ++ ++#define RTL8367C_REG_STS_DRF_BIST_RLT0 0x1282 ++#define RTL8367C_STS_DRF_BIST_RLT0_OFFSET 0 ++#define RTL8367C_STS_DRF_BIST_RLT0_MASK 0x1 ++ ++#define RTL8367C_REG_STS_DRF_BIST_RLT1 0x1283 ++ ++#define RTL8367C_REG_STS_DRF_BIST_RLT2 0x1284 ++ ++#define RTL8367C_REG_STS_DRF_BIST_RLT3 0x1285 ++#define RTL8367C_STS_DRF_BIST_RLT3_OFFSET 0 ++#define RTL8367C_STS_DRF_BIST_RLT3_MASK 0x3FF ++ ++#define RTL8367C_REG_STS_DRF_BIST_RLT4 0x1286 ++#define RTL8367C_STS_DRF_BIST_RLT4_OFFSET 0 ++#define RTL8367C_STS_DRF_BIST_RLT4_MASK 0x7FFF ++ ++#define RTL8367C_REG_RAM_DRF_CTRL 0x1289 ++#define RTL8367C_RAM_DRF_CTRL_OFFSET 0 ++#define RTL8367C_RAM_DRF_CTRL_MASK 0x1 ++ ++#define RTL8367C_REG_MIB_RMON_LEN_CTRL 0x128a ++#define RTL8367C_RX_LENGTH_CTRL_OFFSET 1 ++#define RTL8367C_RX_LENGTH_CTRL_MASK 0x2 ++#define RTL8367C_TX_LENGTH_CTRL_OFFSET 0 ++#define RTL8367C_TX_LENGTH_CTRL_MASK 0x1 ++ ++#define RTL8367C_REG_COND0_BISR_OUT0 0x1290 ++ ++#define RTL8367C_REG_COND0_BISR_OUT1 0x1291 ++ ++#define RTL8367C_REG_COND0_BISR_OUT2 0x1292 ++ ++#define RTL8367C_REG_COND0_BISR_OUT3 0x1293 ++ ++#define RTL8367C_REG_COND0_BISR_OUT4 0x1294 ++#define RTL8367C_COND0_BISR_OUT4_OFFSET 0 ++#define RTL8367C_COND0_BISR_OUT4_MASK 0x3F ++ ++#define RTL8367C_REG_COND0_BISR_OUT5 0x1295 ++#define RTL8367C_COND0_BISR_OUT5_OFFSET 0 ++#define RTL8367C_COND0_BISR_OUT5_MASK 0x7 ++ ++#define RTL8367C_REG_CHG_DUPLEX_CFG 0x1296 ++#define RTL8367C_CHG_COL_CNT_PORT_OFFSET 13 ++#define RTL8367C_CHG_COL_CNT_PORT_MASK 0xE000 ++#define RTL8367C_CHG_COL_CNT_OFFSET 8 ++#define RTL8367C_CHG_COL_CNT_MASK 0x1F00 ++#define RTL8367C_CFG_CHG_DUP_EN_OFFSET 7 ++#define RTL8367C_CFG_CHG_DUP_EN_MASK 0x80 ++#define RTL8367C_CFG_CHG_DUP_THR_OFFSET 2 ++#define RTL8367C_CFG_CHG_DUP_THR_MASK 0x7C ++#define RTL8367C_CFG_CHG_DUP_CONGEST_OFFSET 1 ++#define RTL8367C_CFG_CHG_DUP_CONGEST_MASK 0x2 ++#define RTL8367C_CFG_CHG_DUP_REF_OFFSET 0 ++#define RTL8367C_CFG_CHG_DUP_REF_MASK 0x1 ++ ++#define RTL8367C_REG_COND0_BIST_PASS 0x1297 ++#define RTL8367C_COND0_DRF_BIST_NOFAIL_OFFSET 1 ++#define RTL8367C_COND0_DRF_BIST_NOFAIL_MASK 0x2 ++#define RTL8367C_COND0_BIST_NOFAIL_OFFSET 0 ++#define RTL8367C_COND0_BIST_NOFAIL_MASK 0x1 ++ ++#define RTL8367C_REG_COND1_BISR_OUT0 0x1298 ++ ++#define RTL8367C_REG_COND1_BISR_OUT1 0x1299 ++ ++#define RTL8367C_REG_COND1_BISR_OUT2 0x129a ++ ++#define RTL8367C_REG_COND1_BISR_OUT3 0x129b ++ ++#define RTL8367C_REG_COND1_BISR_OUT4 0x129c ++#define RTL8367C_COND1_BISR_OUT4_OFFSET 0 ++#define RTL8367C_COND1_BISR_OUT4_MASK 0x3F ++ ++#define RTL8367C_REG_COND1_BISR_OUT5 0x129d ++#define RTL8367C_COND1_BISR_OUT5_OFFSET 0 ++#define RTL8367C_COND1_BISR_OUT5_MASK 0x7 ++ ++#define RTL8367C_REG_COND1_BIST_PASS 0x129f ++#define RTL8367C_COND1_DRF_BIST_NOFAIL_OFFSET 1 ++#define RTL8367C_COND1_DRF_BIST_NOFAIL_MASK 0x2 ++#define RTL8367C_COND1_BIST_NOFAIL_OFFSET 0 ++#define RTL8367C_COND1_BIST_NOFAIL_MASK 0x1 ++ ++#define RTL8367C_REG_EEE_TX_THR_Giga_500M 0x12a0 ++ ++#define RTL8367C_REG_EEE_TX_THR_FE 0x12a1 ++ ++#define RTL8367C_REG_EEE_MISC 0x12a3 ++#define RTL8367C_EEE_REQ_SET1_OFFSET 13 ++#define RTL8367C_EEE_REQ_SET1_MASK 0x2000 ++#define RTL8367C_EEE_REQ_SET0_OFFSET 12 ++#define RTL8367C_EEE_REQ_SET0_MASK 0x1000 ++#define RTL8367C_EEE_WAKE_SET1_OFFSET 9 ++#define RTL8367C_EEE_WAKE_SET1_MASK 0x200 ++#define RTL8367C_EEE_Wake_SET0_OFFSET 8 ++#define RTL8367C_EEE_Wake_SET0_MASK 0x100 ++#define RTL8367C_EEE_TU_GIGA_500M_OFFSET 4 ++#define RTL8367C_EEE_TU_GIGA_500M_MASK 0x30 ++#define RTL8367C_EEE_TU_100M_OFFSET 2 ++#define RTL8367C_EEE_TU_100M_MASK 0xC ++ ++#define RTL8367C_REG_EEE_GIGA_CTRL0 0x12a4 ++#define RTL8367C_EEE_TW_GIGA_OFFSET 8 ++#define RTL8367C_EEE_TW_GIGA_MASK 0xFF00 ++#define RTL8367C_EEE_TR_GIGA_500M_OFFSET 0 ++#define RTL8367C_EEE_TR_GIGA_500M_MASK 0xFF ++ ++#define RTL8367C_REG_EEE_GIGA_CTRL1 0x12a5 ++#define RTL8367C_EEE_TD_GIGA_500M_OFFSET 8 ++#define RTL8367C_EEE_TD_GIGA_500M_MASK 0xFF00 ++#define RTL8367C_EEE_TP_GIGA_OFFSET 0 ++#define RTL8367C_EEE_TP_GIGA_MASK 0xFF ++ ++#define RTL8367C_REG_EEE_100M_CTRL0 0x12a6 ++#define RTL8367C_EEE_TW_100M_OFFSET 8 ++#define RTL8367C_EEE_TW_100M_MASK 0xFF00 ++#define RTL8367C_EEE_TR_100M_OFFSET 0 ++#define RTL8367C_EEE_TR_100M_MASK 0xFF ++ ++#define RTL8367C_REG_EEE_100M_CTRL1 0x12a7 ++#define RTL8367C_EEE_TD_100M_OFFSET 8 ++#define RTL8367C_EEE_TD_100M_MASK 0xFF00 ++#define RTL8367C_EEE_TP_100M_OFFSET 0 ++#define RTL8367C_EEE_TP_100M_MASK 0xFF ++ ++#define RTL8367C_REG_RX_FC_REG 0x12aa ++#define RTL8367C_EN_EEE_HALF_DUP_OFFSET 8 ++#define RTL8367C_EN_EEE_HALF_DUP_MASK 0x100 ++#define RTL8367C_RX_PGCNT_OFFSET 0 ++#define RTL8367C_RX_PGCNT_MASK 0xFF ++ ++#define RTL8367C_REG_MAX_FIFO_SIZE 0x12af ++#define RTL8367C_MAX_FIFO_SIZE_OFFSET 0 ++#define RTL8367C_MAX_FIFO_SIZE_MASK 0xF ++ ++#define RTL8367C_REG_EEEP_RX_RATE_GIGA 0x12b0 ++ ++#define RTL8367C_REG_EEEP_RX_RATE_100M 0x12b1 ++ ++#define RTL8367C_REG_DUMMY_REG_12_2 0x12b2 ++ ++#define RTL8367C_REG_EEEP_TX_RATE_GIGA 0x12b3 ++ ++#define RTL8367C_REG_EEEP_TX_RATE_100M 0x12b4 ++ ++#define RTL8367C_REG_DUMMY_REG_12_3 0x12b5 ++ ++#define RTL8367C_REG_EEEP_GIGA_CTRL0 0x12b6 ++#define RTL8367C_EEEP_TR_GIGA_OFFSET 8 ++#define RTL8367C_EEEP_TR_GIGA_MASK 0xFF00 ++#define RTL8367C_EEEP_RW_GIGA_MST_OFFSET 0 ++#define RTL8367C_EEEP_RW_GIGA_MST_MASK 0xFF ++ ++#define RTL8367C_REG_EEEP_GIGA_CTRL1 0x12b7 ++#define RTL8367C_EEEP_TW_GIGA_OFFSET 8 ++#define RTL8367C_EEEP_TW_GIGA_MASK 0xFF00 ++#define RTL8367C_EEEP_TP_GIGA_OFFSET 0 ++#define RTL8367C_EEEP_TP_GIGA_MASK 0xFF ++ ++#define RTL8367C_REG_EEEP_GIGA_CTRL2 0x12b8 ++#define RTL8367C_EEEP_TXEN_GIGA_OFFSET 12 ++#define RTL8367C_EEEP_TXEN_GIGA_MASK 0x1000 ++#define RTL8367C_EEEP_TU_GIGA_OFFSET 8 ++#define RTL8367C_EEEP_TU_GIGA_MASK 0x300 ++#define RTL8367C_EEEP_TS_GIGA_OFFSET 0 ++#define RTL8367C_EEEP_TS_GIGA_MASK 0xFF ++ ++#define RTL8367C_REG_EEEP_100M_CTRL0 0x12b9 ++#define RTL8367C_EEEP_TR_100M_OFFSET 8 ++#define RTL8367C_EEEP_TR_100M_MASK 0xFF00 ++#define RTL8367C_EEEP_RW_100M_OFFSET 0 ++#define RTL8367C_EEEP_RW_100M_MASK 0xFF ++ ++#define RTL8367C_REG_EEEP_100M_CTRL1 0x12ba ++#define RTL8367C_EEEP_TW_100M_OFFSET 8 ++#define RTL8367C_EEEP_TW_100M_MASK 0xFF00 ++#define RTL8367C_EEEP_TP_100M_OFFSET 0 ++#define RTL8367C_EEEP_TP_100M_MASK 0xFF ++ ++#define RTL8367C_REG_EEEP_100M_CTRL2 0x12bb ++#define RTL8367C_EEEP_TXEN_100M_OFFSET 12 ++#define RTL8367C_EEEP_TXEN_100M_MASK 0x1000 ++#define RTL8367C_EEEP_TU_100M_OFFSET 8 ++#define RTL8367C_EEEP_TU_100M_MASK 0x300 ++#define RTL8367C_EEEP_TS_100M_OFFSET 0 ++#define RTL8367C_EEEP_TS_100M_MASK 0xFF ++ ++#define RTL8367C_REG_EEEP_CTRL0 0x12bc ++#define RTL8367C_EEEP_CTRL0_DUMMY_OFFSET 8 ++#define RTL8367C_EEEP_CTRL0_DUMMY_MASK 0xFF00 ++#define RTL8367C_EEEP_SLEEP_STEP_OFFSET 0 ++#define RTL8367C_EEEP_SLEEP_STEP_MASK 0xFF ++ ++#define RTL8367C_REG_EEEP_CTRL1 0x12bd ++#define RTL8367C_EEEP_TXR_GIGA_OFFSET 8 ++#define RTL8367C_EEEP_TXR_GIGA_MASK 0xFF00 ++#define RTL8367C_EEEP_TXR_100M_OFFSET 0 ++#define RTL8367C_EEEP_TXR_100M_MASK 0xFF ++ ++#define RTL8367C_REG_BACK_PRESSURE_IPG 0x12be ++#define RTL8367C_BACK_PRESSURE_IPG_OFFSET 0 ++#define RTL8367C_BACK_PRESSURE_IPG_MASK 0x3 ++ ++#define RTL8367C_REG_TX_ESD_LEVEL 0x12bf ++#define RTL8367C_TX_ESD_LEVEL_MODE_OFFSET 8 ++#define RTL8367C_TX_ESD_LEVEL_MODE_MASK 0x100 ++#define RTL8367C_LEVEL_OFFSET 0 ++#define RTL8367C_LEVEL_MASK 0xFF ++ ++#define RTL8367C_REG_RRCP_CTRL4 0x12e0 ++ ++#define RTL8367C_REG_RRCP_CTRL5 0x12e1 ++ ++#define RTL8367C_REG_RRCP_CTRL6 0x12e2 ++ ++#define RTL8367C_REG_RRCP_CTRL7 0x12e3 ++ ++#define RTL8367C_REG_RRCP_CTRL8 0x12e4 ++ ++#define RTL8367C_REG_RRCP_CTRL9 0x12e5 ++ ++#define RTL8367C_REG_RRCP_CTRL10 0x12e6 ++ ++#define RTL8367C_REG_FIELD_SELECTOR0 0x12e7 ++#define RTL8367C_FIELD_SELECTOR0_FORMAT_OFFSET 8 ++#define RTL8367C_FIELD_SELECTOR0_FORMAT_MASK 0x700 ++#define RTL8367C_FIELD_SELECTOR0_OFFSET_OFFSET 0 ++#define RTL8367C_FIELD_SELECTOR0_OFFSET_MASK 0xFF ++ ++#define RTL8367C_REG_FIELD_SELECTOR1 0x12e8 ++#define RTL8367C_FIELD_SELECTOR1_FORMAT_OFFSET 8 ++#define RTL8367C_FIELD_SELECTOR1_FORMAT_MASK 0x700 ++#define RTL8367C_FIELD_SELECTOR1_OFFSET_OFFSET 0 ++#define RTL8367C_FIELD_SELECTOR1_OFFSET_MASK 0xFF ++ ++#define RTL8367C_REG_FIELD_SELECTOR2 0x12e9 ++#define RTL8367C_FIELD_SELECTOR2_FORMAT_OFFSET 8 ++#define RTL8367C_FIELD_SELECTOR2_FORMAT_MASK 0x700 ++#define RTL8367C_FIELD_SELECTOR2_OFFSET_OFFSET 0 ++#define RTL8367C_FIELD_SELECTOR2_OFFSET_MASK 0xFF ++ ++#define RTL8367C_REG_FIELD_SELECTOR3 0x12ea ++#define RTL8367C_FIELD_SELECTOR3_FORMAT_OFFSET 8 ++#define RTL8367C_FIELD_SELECTOR3_FORMAT_MASK 0x700 ++#define RTL8367C_FIELD_SELECTOR3_OFFSET_OFFSET 0 ++#define RTL8367C_FIELD_SELECTOR3_OFFSET_MASK 0xFF ++ ++#define RTL8367C_REG_FIELD_SELECTOR4 0x12eb ++#define RTL8367C_FIELD_SELECTOR4_FORMAT_OFFSET 8 ++#define RTL8367C_FIELD_SELECTOR4_FORMAT_MASK 0x700 ++#define RTL8367C_FIELD_SELECTOR4_OFFSET_OFFSET 0 ++#define RTL8367C_FIELD_SELECTOR4_OFFSET_MASK 0xFF ++ ++#define RTL8367C_REG_FIELD_SELECTOR5 0x12ec ++#define RTL8367C_FIELD_SELECTOR5_FORMAT_OFFSET 8 ++#define RTL8367C_FIELD_SELECTOR5_FORMAT_MASK 0x700 ++#define RTL8367C_FIELD_SELECTOR5_OFFSET_OFFSET 0 ++#define RTL8367C_FIELD_SELECTOR5_OFFSET_MASK 0xFF ++ ++#define RTL8367C_REG_FIELD_SELECTOR6 0x12ed ++#define RTL8367C_FIELD_SELECTOR6_FORMAT_OFFSET 8 ++#define RTL8367C_FIELD_SELECTOR6_FORMAT_MASK 0x700 ++#define RTL8367C_FIELD_SELECTOR6_OFFSET_OFFSET 0 ++#define RTL8367C_FIELD_SELECTOR6_OFFSET_MASK 0xFF ++ ++#define RTL8367C_REG_FIELD_SELECTOR7 0x12ee ++#define RTL8367C_FIELD_SELECTOR7_FORMAT_OFFSET 8 ++#define RTL8367C_FIELD_SELECTOR7_FORMAT_MASK 0x700 ++#define RTL8367C_FIELD_SELECTOR7_OFFSET_OFFSET 0 ++#define RTL8367C_FIELD_SELECTOR7_OFFSET_MASK 0xFF ++ ++#define RTL8367C_REG_FIELD_SELECTOR8 0x12ef ++#define RTL8367C_FIELD_SELECTOR8_FORMAT_OFFSET 8 ++#define RTL8367C_FIELD_SELECTOR8_FORMAT_MASK 0x700 ++#define RTL8367C_FIELD_SELECTOR8_OFFSET_OFFSET 0 ++#define RTL8367C_FIELD_SELECTOR8_OFFSET_MASK 0xFF ++ ++#define RTL8367C_REG_FIELD_SELECTOR9 0x12f0 ++#define RTL8367C_FIELD_SELECTOR9_FORMAT_OFFSET 8 ++#define RTL8367C_FIELD_SELECTOR9_FORMAT_MASK 0x700 ++#define RTL8367C_FIELD_SELECTOR9_OFFSET_OFFSET 0 ++#define RTL8367C_FIELD_SELECTOR9_OFFSET_MASK 0xFF ++ ++#define RTL8367C_REG_FIELD_SELECTOR10 0x12f1 ++#define RTL8367C_FIELD_SELECTOR10_FORMAT_OFFSET 8 ++#define RTL8367C_FIELD_SELECTOR10_FORMAT_MASK 0x700 ++#define RTL8367C_FIELD_SELECTOR10_OFFSET_OFFSET 0 ++#define RTL8367C_FIELD_SELECTOR10_OFFSET_MASK 0xFF ++ ++#define RTL8367C_REG_FIELD_SELECTOR11 0x12f2 ++#define RTL8367C_FIELD_SELECTOR11_FORMAT_OFFSET 8 ++#define RTL8367C_FIELD_SELECTOR11_FORMAT_MASK 0x700 ++#define RTL8367C_FIELD_SELECTOR11_OFFSET_OFFSET 0 ++#define RTL8367C_FIELD_SELECTOR11_OFFSET_MASK 0xFF ++ ++#define RTL8367C_REG_FIELD_SELECTOR12 0x12f3 ++#define RTL8367C_FIELD_SELECTOR12_FORMAT_OFFSET 8 ++#define RTL8367C_FIELD_SELECTOR12_FORMAT_MASK 0x700 ++#define RTL8367C_FIELD_SELECTOR12_OFFSET_OFFSET 0 ++#define RTL8367C_FIELD_SELECTOR12_OFFSET_MASK 0xFF ++ ++#define RTL8367C_REG_FIELD_SELECTOR13 0x12f4 ++#define RTL8367C_FIELD_SELECTOR13_FORMAT_OFFSET 8 ++#define RTL8367C_FIELD_SELECTOR13_FORMAT_MASK 0x700 ++#define RTL8367C_FIELD_SELECTOR13_OFFSET_OFFSET 0 ++#define RTL8367C_FIELD_SELECTOR13_OFFSET_MASK 0xFF ++ ++#define RTL8367C_REG_FIELD_SELECTOR14 0x12f5 ++#define RTL8367C_FIELD_SELECTOR14_FORMAT_OFFSET 8 ++#define RTL8367C_FIELD_SELECTOR14_FORMAT_MASK 0x700 ++#define RTL8367C_FIELD_SELECTOR14_OFFSET_OFFSET 0 ++#define RTL8367C_FIELD_SELECTOR14_OFFSET_MASK 0xFF ++ ++#define RTL8367C_REG_FIELD_SELECTOR15 0x12f6 ++#define RTL8367C_FIELD_SELECTOR15_FORMAT_OFFSET 8 ++#define RTL8367C_FIELD_SELECTOR15_FORMAT_MASK 0x700 ++#define RTL8367C_FIELD_SELECTOR15_OFFSET_OFFSET 0 ++#define RTL8367C_FIELD_SELECTOR15_OFFSET_MASK 0xFF ++ ++#define RTL8367C_REG_HWPKT_GEN_MISC_H 0x12f7 ++#define RTL8367C_PKT_GEN_SUSPEND_P10_8_OFFSET 3 ++#define RTL8367C_PKT_GEN_SUSPEND_P10_8_MASK 0x38 ++#define RTL8367C_PKT_GEN_STATUS_P10_8_OFFSET 0 ++#define RTL8367C_PKT_GEN_STATUS_P10_8_MASK 0x7 ++ ++#define RTL8367C_REG_MIRROR_SRC_PMSK 0x12fb ++#define RTL8367C_MIRROR_SRC_PMSK_OFFSET 0 ++#define RTL8367C_MIRROR_SRC_PMSK_MASK 0x7FF ++ ++#define RTL8367C_REG_EEE_BURSTSIZE 0x12fc ++ ++#define RTL8367C_REG_EEE_IFG_CFG 0x12fd ++#define RTL8367C_EEE_IFG_CFG_OFFSET 0 ++#define RTL8367C_EEE_IFG_CFG_MASK 0x1 ++ ++#define RTL8367C_REG_FPGA_VER_MAC 0x12fe ++ ++#define RTL8367C_REG_HWPKT_GEN_MISC 0x12ff ++#define RTL8367C_PKT_GEN_SUSPEND_OFFSET 8 ++#define RTL8367C_PKT_GEN_SUSPEND_MASK 0xFF00 ++#define RTL8367C_PKT_GEN_STATUS_OFFSET 0 ++#define RTL8367C_PKT_GEN_STATUS_MASK 0xFF ++ ++/* (16'h1300)chip_reg */ ++ ++#define RTL8367C_REG_CHIP_NUMBER 0x1300 ++ ++#define RTL8367C_REG_CHIP_VER 0x1301 ++#define RTL8367C_VERID_OFFSET 12 ++#define RTL8367C_VERID_MASK 0xF000 ++#define RTL8367C_MCID_OFFSET 8 ++#define RTL8367C_MCID_MASK 0xF00 ++#define RTL8367C_MODEL_ID_OFFSET 4 ++#define RTL8367C_MODEL_ID_MASK 0xF0 ++#define RTL8367C_AFE_VERSION_OFFSET 0 ++#define RTL8367C_AFE_VERSION_MASK 0x1 ++ ++#define RTL8367C_REG_CHIP_DEBUG0 0x1303 ++#define RTL8367C_SEL33_EXT2_OFFSET 10 ++#define RTL8367C_SEL33_EXT2_MASK 0x400 ++#define RTL8367C_SEL33_EXT1_OFFSET 9 ++#define RTL8367C_SEL33_EXT1_MASK 0x200 ++#define RTL8367C_SEL33_EXT0_OFFSET 8 ++#define RTL8367C_SEL33_EXT0_MASK 0x100 ++#define RTL8367C_DRI_OTHER_OFFSET 7 ++#define RTL8367C_DRI_OTHER_MASK 0x80 ++#define RTL8367C_DRI_EXT1_RG_OFFSET 6 ++#define RTL8367C_DRI_EXT1_RG_MASK 0x40 ++#define RTL8367C_DRI_EXT0_RG_OFFSET 5 ++#define RTL8367C_DRI_EXT0_RG_MASK 0x20 ++#define RTL8367C_DRI_EXT1_OFFSET 4 ++#define RTL8367C_DRI_EXT1_MASK 0x10 ++#define RTL8367C_DRI_EXT0_OFFSET 3 ++#define RTL8367C_DRI_EXT0_MASK 0x8 ++#define RTL8367C_SLR_OTHER_OFFSET 2 ++#define RTL8367C_SLR_OTHER_MASK 0x4 ++#define RTL8367C_SLR_EXT1_OFFSET 1 ++#define RTL8367C_SLR_EXT1_MASK 0x2 ++#define RTL8367C_SLR_EXT0_OFFSET 0 ++#define RTL8367C_SLR_EXT0_MASK 0x1 ++ ++#define RTL8367C_REG_CHIP_DEBUG1 0x1304 ++#define RTL8367C_RG1_DN_OFFSET 12 ++#define RTL8367C_RG1_DN_MASK 0x7000 ++#define RTL8367C_RG1_DP_OFFSET 8 ++#define RTL8367C_RG1_DP_MASK 0x700 ++#define RTL8367C_RG0_DN_OFFSET 4 ++#define RTL8367C_RG0_DN_MASK 0x70 ++#define RTL8367C_RG0_DP_OFFSET 0 ++#define RTL8367C_RG0_DP_MASK 0x7 ++ ++#define RTL8367C_REG_DIGITAL_INTERFACE_SELECT 0x1305 ++#define RTL8367C_ORG_COL_OFFSET 15 ++#define RTL8367C_ORG_COL_MASK 0x8000 ++#define RTL8367C_ORG_CRS_OFFSET 14 ++#define RTL8367C_ORG_CRS_MASK 0x4000 ++#define RTL8367C_SKIP_MII_1_RXER_OFFSET 13 ++#define RTL8367C_SKIP_MII_1_RXER_MASK 0x2000 ++#define RTL8367C_SKIP_MII_0_RXER_OFFSET 12 ++#define RTL8367C_SKIP_MII_0_RXER_MASK 0x1000 ++#define RTL8367C_SELECT_GMII_1_OFFSET 4 ++#define RTL8367C_SELECT_GMII_1_MASK 0xF0 ++#define RTL8367C_SELECT_GMII_0_OFFSET 0 ++#define RTL8367C_SELECT_GMII_0_MASK 0xF ++ ++#define RTL8367C_REG_EXT0_RGMXF 0x1306 ++#define RTL8367C_EXT0_RGTX_INV_OFFSET 6 ++#define RTL8367C_EXT0_RGTX_INV_MASK 0x40 ++#define RTL8367C_EXT0_RGRX_INV_OFFSET 5 ++#define RTL8367C_EXT0_RGRX_INV_MASK 0x20 ++#define RTL8367C_EXT0_RGMXF_OFFSET 0 ++#define RTL8367C_EXT0_RGMXF_MASK 0x1F ++ ++#define RTL8367C_REG_EXT1_RGMXF 0x1307 ++#define RTL8367C_EXT1_RGTX_INV_OFFSET 6 ++#define RTL8367C_EXT1_RGTX_INV_MASK 0x40 ++#define RTL8367C_EXT1_RGRX_INV_OFFSET 5 ++#define RTL8367C_EXT1_RGRX_INV_MASK 0x20 ++#define RTL8367C_EXT1_RGMXF_OFFSET 0 ++#define RTL8367C_EXT1_RGMXF_MASK 0x1F ++ ++#define RTL8367C_REG_BISR_CTRL 0x1308 ++#define RTL8367C_BISR_CTRL_OFFSET 0 ++#define RTL8367C_BISR_CTRL_MASK 0x7 ++ ++#define RTL8367C_REG_SLF_IF 0x1309 ++#define RTL8367C_LINK_DOWN_CLR_FIFO_OFFSET 7 ++#define RTL8367C_LINK_DOWN_CLR_FIFO_MASK 0x80 ++#define RTL8367C_LOOPBACK_OFFSET 6 ++#define RTL8367C_LOOPBACK_MASK 0x40 ++#define RTL8367C_WATER_LEVEL_OFFSET 4 ++#define RTL8367C_WATER_LEVEL_MASK 0x30 ++#define RTL8367C_SLF_IF_OFFSET 0 ++#define RTL8367C_SLF_IF_MASK 0x3 ++ ++#define RTL8367C_REG_I2C_CLOCK_DIV 0x130a ++#define RTL8367C_I2C_CLOCK_DIV_OFFSET 0 ++#define RTL8367C_I2C_CLOCK_DIV_MASK 0x3FF ++ ++#define RTL8367C_REG_MDX_MDC_DIV 0x130b ++#define RTL8367C_MDX_MDC_DIV_OFFSET 0 ++#define RTL8367C_MDX_MDC_DIV_MASK 0x3FF ++ ++#define RTL8367C_REG_MISCELLANEOUS_CONFIGURE0 0x130c ++#define RTL8367C_ADCCKI_FROM_PAD_OFFSET 14 ++#define RTL8367C_ADCCKI_FROM_PAD_MASK 0x4000 ++#define RTL8367C_ADCCKI_EN_OFFSET 13 ++#define RTL8367C_ADCCKI_EN_MASK 0x2000 ++#define RTL8367C_FLASH_ENABLE_OFFSET 12 ++#define RTL8367C_FLASH_ENABLE_MASK 0x1000 ++#define RTL8367C_EEE_ENABLE_OFFSET 11 ++#define RTL8367C_EEE_ENABLE_MASK 0x800 ++#define RTL8367C_NIC_ENABLE_OFFSET 10 ++#define RTL8367C_NIC_ENABLE_MASK 0x400 ++#define RTL8367C_FT_ENABLE_OFFSET 9 ++#define RTL8367C_FT_ENABLE_MASK 0x200 ++#define RTL8367C_OLT_ENABLE_OFFSET 8 ++#define RTL8367C_OLT_ENABLE_MASK 0x100 ++#define RTL8367C_RTCT_EN_OFFSET 7 ++#define RTL8367C_RTCT_EN_MASK 0x80 ++#define RTL8367C_PON_LIGHT_EN_OFFSET 6 ++#define RTL8367C_PON_LIGHT_EN_MASK 0x40 ++#define RTL8367C_DW8051_EN_OFFSET 5 ++#define RTL8367C_DW8051_EN_MASK 0x20 ++#define RTL8367C_AUTOLOAD_EN_OFFSET 4 ++#define RTL8367C_AUTOLOAD_EN_MASK 0x10 ++#define RTL8367C_NRESTORE_EN_OFFSET 3 ++#define RTL8367C_NRESTORE_EN_MASK 0x8 ++#define RTL8367C_DIS_PON_TABLE_INIT_OFFSET 2 ++#define RTL8367C_DIS_PON_TABLE_INIT_MASK 0x4 ++#define RTL8367C_DIS_PON_BIST_OFFSET 1 ++#define RTL8367C_DIS_PON_BIST_MASK 0x2 ++#define RTL8367C_EFUSE_EN_OFFSET 0 ++#define RTL8367C_EFUSE_EN_MASK 0x1 ++ ++#define RTL8367C_REG_MISCELLANEOUS_CONFIGURE1 0x130d ++#define RTL8367C_EEPROM_DEV_ADR_OFFSET 8 ++#define RTL8367C_EEPROM_DEV_ADR_MASK 0x7F00 ++#define RTL8367C_EEPROM_MSB_OFFSET 7 ++#define RTL8367C_EEPROM_MSB_MASK 0x80 ++#define RTL8367C_EEPROM_ADDRESS_16B_OFFSET 6 ++#define RTL8367C_EEPROM_ADDRESS_16B_MASK 0x40 ++#define RTL8367C_EEPROM_DWONLOAD_COMPLETE_OFFSET 3 ++#define RTL8367C_EEPROM_DWONLOAD_COMPLETE_MASK 0x8 ++#define RTL8367C_SPI_SLAVE_EN_OFFSET 2 ++#define RTL8367C_SPI_SLAVE_EN_MASK 0x4 ++#define RTL8367C_SMI_SEL_OFFSET 0 ++#define RTL8367C_SMI_SEL_MASK 0x3 ++ ++#define RTL8367C_REG_PHY_AD 0x130f ++#define RTL8367C_EN_PHY_MAX_POWER_OFFSET 14 ++#define RTL8367C_EN_PHY_MAX_POWER_MASK 0x4000 ++#define RTL8367C_EN_PHY_SEL_DEG_OFFSET 13 ++#define RTL8367C_EN_PHY_SEL_DEG_MASK 0x2000 ++#define RTL8367C_EXTPHY_AD_OFFSET 8 ++#define RTL8367C_EXTPHY_AD_MASK 0x1F00 ++#define RTL8367C_EN_PHY_LOW_POWER_MODE_OFFSET 7 ++#define RTL8367C_EN_PHY_LOW_POWER_MODE_MASK 0x80 ++#define RTL8367C_EN_PHY_GREEN_OFFSET 6 ++#define RTL8367C_EN_PHY_GREEN_MASK 0x40 ++#define RTL8367C_PDNPHY_OFFSET 5 ++#define RTL8367C_PDNPHY_MASK 0x20 ++#define RTL8367C_INTPHY_AD_OFFSET 0 ++#define RTL8367C_INTPHY_AD_MASK 0x1F ++ ++#define RTL8367C_REG_DIGITAL_INTERFACE0_FORCE 0x1310 ++#define RTL8367C_GMII_0_FORCE_OFFSET 12 ++#define RTL8367C_GMII_0_FORCE_MASK 0x1000 ++#define RTL8367C_RGMII_0_FORCE_OFFSET 0 ++#define RTL8367C_RGMII_0_FORCE_MASK 0xFFF ++ ++#define RTL8367C_REG_DIGITAL_INTERFACE1_FORCE 0x1311 ++#define RTL8367C_GMII_1_FORCE_OFFSET 12 ++#define RTL8367C_GMII_1_FORCE_MASK 0x1000 ++#define RTL8367C_RGMII_1_FORCE_OFFSET 0 ++#define RTL8367C_RGMII_1_FORCE_MASK 0xFFF ++ ++#define RTL8367C_REG_MAC0_FORCE_SELECT 0x1312 ++#define RTL8367C_EN_MAC0_FORCE_OFFSET 12 ++#define RTL8367C_EN_MAC0_FORCE_MASK 0x1000 ++#define RTL8367C_MAC0_FORCE_ABLTY_OFFSET 0 ++#define RTL8367C_MAC0_FORCE_ABLTY_MASK 0xFFF ++ ++#define RTL8367C_REG_MAC1_FORCE_SELECT 0x1313 ++#define RTL8367C_EN_MAC1_FORCE_OFFSET 12 ++#define RTL8367C_EN_MAC1_FORCE_MASK 0x1000 ++#define RTL8367C_MAC1_FORCE_ABLTY_OFFSET 0 ++#define RTL8367C_MAC1_FORCE_ABLTY_MASK 0xFFF ++ ++#define RTL8367C_REG_MAC2_FORCE_SELECT 0x1314 ++#define RTL8367C_EN_MAC2_FORCE_OFFSET 12 ++#define RTL8367C_EN_MAC2_FORCE_MASK 0x1000 ++#define RTL8367C_MAC2_FORCE_ABLTY_OFFSET 0 ++#define RTL8367C_MAC2_FORCE_ABLTY_MASK 0xFFF ++ ++#define RTL8367C_REG_MAC3_FORCE_SELECT 0x1315 ++#define RTL8367C_EN_MAC3_FORCE_OFFSET 12 ++#define RTL8367C_EN_MAC3_FORCE_MASK 0x1000 ++#define RTL8367C_MAC3_FORCE_ABLTY_OFFSET 0 ++#define RTL8367C_MAC3_FORCE_ABLTY_MASK 0xFFF ++ ++#define RTL8367C_REG_MAC4_FORCE_SELECT 0x1316 ++#define RTL8367C_EN_MAC4_FORCE_OFFSET 12 ++#define RTL8367C_EN_MAC4_FORCE_MASK 0x1000 ++#define RTL8367C_MAC4_FORCE_ABLTY_OFFSET 0 ++#define RTL8367C_MAC4_FORCE_ABLTY_MASK 0xFFF ++ ++#define RTL8367C_REG_MAC5_FORCE_SELECT 0x1317 ++#define RTL8367C_EN_MAC5_FORCE_OFFSET 12 ++#define RTL8367C_EN_MAC5_FORCE_MASK 0x1000 ++#define RTL8367C_MAC5_FORCE_ABLTY_OFFSET 0 ++#define RTL8367C_MAC5_FORCE_ABLTY_MASK 0xFFF ++ ++#define RTL8367C_REG_MAC6_FORCE_SELECT 0x1318 ++#define RTL8367C_EN_MAC6_FORCE_OFFSET 12 ++#define RTL8367C_EN_MAC6_FORCE_MASK 0x1000 ++#define RTL8367C_MAC6_FORCE_ABLTY_OFFSET 0 ++#define RTL8367C_MAC6_FORCE_ABLTY_MASK 0xFFF ++ ++#define RTL8367C_REG_MAC7_FORCE_SELECT 0x1319 ++#define RTL8367C_EN_MAC7_FORCE_OFFSET 12 ++#define RTL8367C_EN_MAC7_FORCE_MASK 0x1000 ++#define RTL8367C_MAC7_FORCE_ABLTY_OFFSET 0 ++#define RTL8367C_MAC7_FORCE_ABLTY_MASK 0xFFF ++ ++#define RTL8367C_REG_M10_FORCE_SELECT 0x131c ++#define RTL8367C_EN_M10_FORCE_OFFSET 12 ++#define RTL8367C_EN_M10_FORCE_MASK 0x1000 ++#define RTL8367C_M10_FORCE_ABLTY_OFFSET 0 ++#define RTL8367C_M10_FORCE_ABLTY_MASK 0xFFF ++ ++#define RTL8367C_REG_CHIP_RESET 0x1322 ++#define RTL8367C_GPHY_RESET_OFFSET 6 ++#define RTL8367C_GPHY_RESET_MASK 0x40 ++#define RTL8367C_NIC_RST_OFFSET 5 ++#define RTL8367C_NIC_RST_MASK 0x20 ++#define RTL8367C_DW8051_RST_OFFSET 4 ++#define RTL8367C_DW8051_RST_MASK 0x10 ++#define RTL8367C_SDS_RST_OFFSET 3 ++#define RTL8367C_SDS_RST_MASK 0x8 ++#define RTL8367C_CONFIG_RST_OFFSET 2 ++#define RTL8367C_CONFIG_RST_MASK 0x4 ++#define RTL8367C_SW_RST_OFFSET 1 ++#define RTL8367C_SW_RST_MASK 0x2 ++#define RTL8367C_CHIP_RST_OFFSET 0 ++#define RTL8367C_CHIP_RST_MASK 0x1 ++ ++#define RTL8367C_REG_DIGITAL_DEBUG_0 0x1323 ++ ++#define RTL8367C_REG_DIGITAL_DEBUG_1 0x1324 ++ ++#define RTL8367C_REG_INTERNAL_PHY_MDC_DRIVER 0x1325 ++#define RTL8367C_INTERNAL_PHY_MDC_DRIVER_OFFSET 0 ++#define RTL8367C_INTERNAL_PHY_MDC_DRIVER_MASK 0x3FF ++ ++#define RTL8367C_REG_LINKDOWN_TIME_CTRL 0x1326 ++#define RTL8367C_LINKDOWN_TIME_CFG_OFFSET 9 ++#define RTL8367C_LINKDOWN_TIME_CFG_MASK 0x7E00 ++#define RTL8367C_LINKDOWN_TIME_ENABLE_OFFSET 8 ++#define RTL8367C_LINKDOWN_TIME_ENABLE_MASK 0x100 ++#define RTL8367C_LINKDOWN_TIME_OFFSET 0 ++#define RTL8367C_LINKDOWN_TIME_MASK 0xFF ++ ++#define RTL8367C_REG_PHYACK_TIMEOUT 0x1331 ++ ++#define RTL8367C_REG_MDXACK_TIMEOUT 0x1333 ++ ++#define RTL8367C_REG_DW8051_RDY 0x1336 ++#define RTL8367C_VIAROM_WRITE_EN_OFFSET 9 ++#define RTL8367C_VIAROM_WRITE_EN_MASK 0x200 ++#define RTL8367C_SPIF_CK2_OFFSET 8 ++#define RTL8367C_SPIF_CK2_MASK 0x100 ++#define RTL8367C_RRCP_MDOE_OFFSET 7 ++#define RTL8367C_RRCP_MDOE_MASK 0x80 ++#define RTL8367C_DW8051_RATE_OFFSET 4 ++#define RTL8367C_DW8051_RATE_MASK 0x70 ++#define RTL8367C_IROM_MSB_OFFSET 2 ++#define RTL8367C_IROM_MSB_MASK 0xC ++#define RTL8367C_ACS_IROM_ENABLE_OFFSET 1 ++#define RTL8367C_ACS_IROM_ENABLE_MASK 0x2 ++#define RTL8367C_DW8051_READY_OFFSET 0 ++#define RTL8367C_DW8051_READY_MASK 0x1 ++ ++#define RTL8367C_REG_BIST_CTRL 0x133c ++#define RTL8367C_DRF_BIST_DONE_ALL_OFFSET 5 ++#define RTL8367C_DRF_BIST_DONE_ALL_MASK 0x20 ++#define RTL8367C_DRF_BIST_PAUSE_ALL_OFFSET 4 ++#define RTL8367C_DRF_BIST_PAUSE_ALL_MASK 0x10 ++#define RTL8367C_BIST_DOAN_ALL_OFFSET 3 ++#define RTL8367C_BIST_DOAN_ALL_MASK 0x8 ++#define RTL8367C_BIST_PASS_OFFSET 0 ++#define RTL8367C_BIST_PASS_MASK 0x7 ++ ++#define RTL8367C_REG_DIAG_MODE2 0x133d ++#define RTL8367C_DIAG_MODE2_ACTRAM_OFFSET 1 ++#define RTL8367C_DIAG_MODE2_ACTRAM_MASK 0x2 ++#define RTL8367C_DIAG_MODE2_BCAM_ACTION_OFFSET 0 ++#define RTL8367C_DIAG_MODE2_BCAM_ACTION_MASK 0x1 ++ ++#define RTL8367C_REG_MDX_PHY_REG0 0x133e ++#define RTL8367C_PHY_BRD_MASK_OFFSET 4 ++#define RTL8367C_PHY_BRD_MASK_MASK 0x1F0 ++#define RTL8367C_MDX_INDACC_PAGE_OFFSET 0 ++#define RTL8367C_MDX_INDACC_PAGE_MASK 0xF ++ ++#define RTL8367C_REG_MDX_PHY_REG1 0x133f ++#define RTL8367C_PHY_BRD_MODE_OFFSET 5 ++#define RTL8367C_PHY_BRD_MODE_MASK 0x20 ++#define RTL8367C_BRD_PHYAD_OFFSET 0 ++#define RTL8367C_BRD_PHYAD_MASK 0x1F ++ ++#define RTL8367C_REG_DEBUG_SIGNAL_SELECT_SW 0x1340 ++ ++#define RTL8367C_REG_DEBUG_SIGNAL_SELECT_B 0x1341 ++#define RTL8367C_DEBUG_MX_OFFSET 9 ++#define RTL8367C_DEBUG_MX_MASK 0xE00 ++#define RTL8367C_DEBUG_SHIFT_MISC_OFFSET 6 ++#define RTL8367C_DEBUG_SHIFT_MISC_MASK 0x1C0 ++#define RTL8367C_DEBUG_SHIFT_SW_OFFSET 3 ++#define RTL8367C_DEBUG_SHIFT_SW_MASK 0x38 ++#define RTL8367C_DEBUG_SHIFT_GPHY_OFFSET 0 ++#define RTL8367C_DEBUG_SHIFT_GPHY_MASK 0x7 ++ ++#define RTL8367C_REG_DEBUG_SIGNAL_I 0x1343 ++ ++#define RTL8367C_REG_DEBUG_SIGNAL_H 0x1344 ++ ++#define RTL8367C_REG_DBGO_SEL_GPHY 0x1345 ++ ++#define RTL8367C_REG_DBGO_SEL_MISC 0x1346 ++ ++#define RTL8367C_REG_BYPASS_ABLTY_LOCK 0x1349 ++#define RTL8367C_BYPASS_ABLTY_LOCK_OFFSET 0 ++#define RTL8367C_BYPASS_ABLTY_LOCK_MASK 0xFF ++ ++#define RTL8367C_REG_BYPASS_ABLTY_LOCK_EXT 0x134a ++#define RTL8367C_BYPASS_P10_ABILIITY_LOCK_OFFSET 3 ++#define RTL8367C_BYPASS_P10_ABILIITY_LOCK_MASK 0x8 ++#define RTL8367C_BYPASS_EXT_ABILITY_LOCK_OFFSET 0 ++#define RTL8367C_BYPASS_EXT_ABILITY_LOCK_MASK 0x7 ++ ++#define RTL8367C_REG_ACL_GPIO 0x134f ++#define RTL8367C_ACL_GPIO_13_OFFSET 13 ++#define RTL8367C_ACL_GPIO_13_MASK 0x2000 ++#define RTL8367C_ACL_GPIO_12_OFFSET 12 ++#define RTL8367C_ACL_GPIO_12_MASK 0x1000 ++#define RTL8367C_ACL_GPIO_11_OFFSET 11 ++#define RTL8367C_ACL_GPIO_11_MASK 0x800 ++#define RTL8367C_ACL_GPIO_10_OFFSET 10 ++#define RTL8367C_ACL_GPIO_10_MASK 0x400 ++#define RTL8367C_ACL_GPIO_9_OFFSET 9 ++#define RTL8367C_ACL_GPIO_9_MASK 0x200 ++#define RTL8367C_ACL_GPIO_8_OFFSET 8 ++#define RTL8367C_ACL_GPIO_8_MASK 0x100 ++#define RTL8367C_ACL_GPIO_7_OFFSET 7 ++#define RTL8367C_ACL_GPIO_7_MASK 0x80 ++#define RTL8367C_ACL_GPIO_6_OFFSET 6 ++#define RTL8367C_ACL_GPIO_6_MASK 0x40 ++#define RTL8367C_ACL_GPIO_5_OFFSET 5 ++#define RTL8367C_ACL_GPIO_5_MASK 0x20 ++#define RTL8367C_ACL_GPIO_4_OFFSET 4 ++#define RTL8367C_ACL_GPIO_4_MASK 0x10 ++#define RTL8367C_ACL_GPIO_3_OFFSET 3 ++#define RTL8367C_ACL_GPIO_3_MASK 0x8 ++#define RTL8367C_ACL_GPIO_2_OFFSET 2 ++#define RTL8367C_ACL_GPIO_2_MASK 0x4 ++#define RTL8367C_ACL_GPIO_1_OFFSET 1 ++#define RTL8367C_ACL_GPIO_1_MASK 0x2 ++#define RTL8367C_ACL_GPIO_0_OFFSET 0 ++#define RTL8367C_ACL_GPIO_0_MASK 0x1 ++ ++#define RTL8367C_REG_EN_GPIO 0x1350 ++#define RTL8367C_EN_GPIO_13_OFFSET 13 ++#define RTL8367C_EN_GPIO_13_MASK 0x2000 ++#define RTL8367C_EN_GPIO_12_OFFSET 12 ++#define RTL8367C_EN_GPIO_12_MASK 0x1000 ++#define RTL8367C_EN_GPIO_11_OFFSET 11 ++#define RTL8367C_EN_GPIO_11_MASK 0x800 ++#define RTL8367C_EN_GPIO_10_OFFSET 10 ++#define RTL8367C_EN_GPIO_10_MASK 0x400 ++#define RTL8367C_EN_GPIO_9_OFFSET 9 ++#define RTL8367C_EN_GPIO_9_MASK 0x200 ++#define RTL8367C_EN_GPIO_8_OFFSET 8 ++#define RTL8367C_EN_GPIO_8_MASK 0x100 ++#define RTL8367C_EN_GPIO_7_OFFSET 7 ++#define RTL8367C_EN_GPIO_7_MASK 0x80 ++#define RTL8367C_EN_GPIO_6_OFFSET 6 ++#define RTL8367C_EN_GPIO_6_MASK 0x40 ++#define RTL8367C_EN_GPIO_5_OFFSET 5 ++#define RTL8367C_EN_GPIO_5_MASK 0x20 ++#define RTL8367C_EN_GPIO_4_OFFSET 4 ++#define RTL8367C_EN_GPIO_4_MASK 0x10 ++#define RTL8367C_EN_GPIO_3_OFFSET 3 ++#define RTL8367C_EN_GPIO_3_MASK 0x8 ++#define RTL8367C_EN_GPIO_2_OFFSET 2 ++#define RTL8367C_EN_GPIO_2_MASK 0x4 ++#define RTL8367C_EN_GPIO_1_OFFSET 1 ++#define RTL8367C_EN_GPIO_1_MASK 0x2 ++#define RTL8367C_EN_GPIO_0_OFFSET 0 ++#define RTL8367C_EN_GPIO_0_MASK 0x1 ++ ++#define RTL8367C_REG_CFG_MULTI_PIN 0x1351 ++#define RTL8367C_CFG_MULTI_PIN_OFFSET 0 ++#define RTL8367C_CFG_MULTI_PIN_MASK 0x3 ++ ++#define RTL8367C_REG_PORT0_STATUS 0x1352 ++#define RTL8367C_PORT0_STATUS_EN_1000_LPI_OFFSET 11 ++#define RTL8367C_PORT0_STATUS_EN_1000_LPI_MASK 0x800 ++#define RTL8367C_PORT0_STATUS_EN_100_LPI_OFFSET 10 ++#define RTL8367C_PORT0_STATUS_EN_100_LPI_MASK 0x400 ++#define RTL8367C_PORT0_STATUS_NWAY_FAULT_OFFSET 9 ++#define RTL8367C_PORT0_STATUS_NWAY_FAULT_MASK 0x200 ++#define RTL8367C_PORT0_STATUS_LINK_ON_MASTER_OFFSET 8 ++#define RTL8367C_PORT0_STATUS_LINK_ON_MASTER_MASK 0x100 ++#define RTL8367C_PORT0_STATUS_NWAY_CAP_OFFSET 7 ++#define RTL8367C_PORT0_STATUS_NWAY_CAP_MASK 0x80 ++#define RTL8367C_PORT0_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 ++#define RTL8367C_PORT0_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 ++#define RTL8367C_PORT0_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 ++#define RTL8367C_PORT0_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 ++#define RTL8367C_PORT0_STATUS_LINK_STATE_OFFSET 4 ++#define RTL8367C_PORT0_STATUS_LINK_STATE_MASK 0x10 ++#define RTL8367C_PORT0_STATUS_FULL_DUPLUX_CAP_OFFSET 2 ++#define RTL8367C_PORT0_STATUS_FULL_DUPLUX_CAP_MASK 0x4 ++#define RTL8367C_PORT0_STATUS_LINK_SPEED_OFFSET 0 ++#define RTL8367C_PORT0_STATUS_LINK_SPEED_MASK 0x3 ++ ++#define RTL8367C_REG_PORT1_STATUS 0x1353 ++#define RTL8367C_PORT1_STATUS_EN_1000_LPI_OFFSET 11 ++#define RTL8367C_PORT1_STATUS_EN_1000_LPI_MASK 0x800 ++#define RTL8367C_PORT1_STATUS_EN_100_LPI_OFFSET 10 ++#define RTL8367C_PORT1_STATUS_EN_100_LPI_MASK 0x400 ++#define RTL8367C_PORT1_STATUS_NWAY_FAULT_OFFSET 9 ++#define RTL8367C_PORT1_STATUS_NWAY_FAULT_MASK 0x200 ++#define RTL8367C_PORT1_STATUS_LINK_ON_MASTER_OFFSET 8 ++#define RTL8367C_PORT1_STATUS_LINK_ON_MASTER_MASK 0x100 ++#define RTL8367C_PORT1_STATUS_NWAY_CAP_OFFSET 7 ++#define RTL8367C_PORT1_STATUS_NWAY_CAP_MASK 0x80 ++#define RTL8367C_PORT1_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 ++#define RTL8367C_PORT1_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 ++#define RTL8367C_PORT1_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 ++#define RTL8367C_PORT1_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 ++#define RTL8367C_PORT1_STATUS_LINK_STATE_OFFSET 4 ++#define RTL8367C_PORT1_STATUS_LINK_STATE_MASK 0x10 ++#define RTL8367C_PORT1_STATUS_FULL_DUPLUX_CAP_OFFSET 2 ++#define RTL8367C_PORT1_STATUS_FULL_DUPLUX_CAP_MASK 0x4 ++#define RTL8367C_PORT1_STATUS_LINK_SPEED_OFFSET 0 ++#define RTL8367C_PORT1_STATUS_LINK_SPEED_MASK 0x3 ++ ++#define RTL8367C_REG_PORT2_STATUS 0x1354 ++#define RTL8367C_PORT2_STATUS_EN_1000_LPI_OFFSET 11 ++#define RTL8367C_PORT2_STATUS_EN_1000_LPI_MASK 0x800 ++#define RTL8367C_PORT2_STATUS_EN_100_LPI_OFFSET 10 ++#define RTL8367C_PORT2_STATUS_EN_100_LPI_MASK 0x400 ++#define RTL8367C_PORT2_STATUS_NWAY_FAULT_OFFSET 9 ++#define RTL8367C_PORT2_STATUS_NWAY_FAULT_MASK 0x200 ++#define RTL8367C_PORT2_STATUS_LINK_ON_MASTER_OFFSET 8 ++#define RTL8367C_PORT2_STATUS_LINK_ON_MASTER_MASK 0x100 ++#define RTL8367C_PORT2_STATUS_NWAY_CAP_OFFSET 7 ++#define RTL8367C_PORT2_STATUS_NWAY_CAP_MASK 0x80 ++#define RTL8367C_PORT2_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 ++#define RTL8367C_PORT2_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 ++#define RTL8367C_PORT2_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 ++#define RTL8367C_PORT2_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 ++#define RTL8367C_PORT2_STATUS_LINK_STATE_OFFSET 4 ++#define RTL8367C_PORT2_STATUS_LINK_STATE_MASK 0x10 ++#define RTL8367C_PORT2_STATUS_FULL_DUPLUX_CAP_OFFSET 2 ++#define RTL8367C_PORT2_STATUS_FULL_DUPLUX_CAP_MASK 0x4 ++#define RTL8367C_PORT2_STATUS_LINK_SPEED_OFFSET 0 ++#define RTL8367C_PORT2_STATUS_LINK_SPEED_MASK 0x3 ++ ++#define RTL8367C_REG_PORT3_STATUS 0x1355 ++#define RTL8367C_PORT3_STATUS_EN_1000_LPI_OFFSET 11 ++#define RTL8367C_PORT3_STATUS_EN_1000_LPI_MASK 0x800 ++#define RTL8367C_PORT3_STATUS_EN_100_LPI_OFFSET 10 ++#define RTL8367C_PORT3_STATUS_EN_100_LPI_MASK 0x400 ++#define RTL8367C_PORT3_STATUS_NWAY_FAULT_OFFSET 9 ++#define RTL8367C_PORT3_STATUS_NWAY_FAULT_MASK 0x200 ++#define RTL8367C_PORT3_STATUS_LINK_ON_MASTER_OFFSET 8 ++#define RTL8367C_PORT3_STATUS_LINK_ON_MASTER_MASK 0x100 ++#define RTL8367C_PORT3_STATUS_NWAY_CAP_OFFSET 7 ++#define RTL8367C_PORT3_STATUS_NWAY_CAP_MASK 0x80 ++#define RTL8367C_PORT3_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 ++#define RTL8367C_PORT3_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 ++#define RTL8367C_PORT3_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 ++#define RTL8367C_PORT3_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 ++#define RTL8367C_PORT3_STATUS_LINK_STATE_OFFSET 4 ++#define RTL8367C_PORT3_STATUS_LINK_STATE_MASK 0x10 ++#define RTL8367C_PORT3_STATUS_FULL_DUPLUX_CAP_OFFSET 2 ++#define RTL8367C_PORT3_STATUS_FULL_DUPLUX_CAP_MASK 0x4 ++#define RTL8367C_PORT3_STATUS_LINK_SPEED_OFFSET 0 ++#define RTL8367C_PORT3_STATUS_LINK_SPEED_MASK 0x3 ++ ++#define RTL8367C_REG_PORT4_STATUS 0x1356 ++#define RTL8367C_PORT4_STATUS_EN_1000_LPI_OFFSET 11 ++#define RTL8367C_PORT4_STATUS_EN_1000_LPI_MASK 0x800 ++#define RTL8367C_PORT4_STATUS_EN_100_LPI_OFFSET 10 ++#define RTL8367C_PORT4_STATUS_EN_100_LPI_MASK 0x400 ++#define RTL8367C_PORT4_STATUS_NWAY_FAULT_OFFSET 9 ++#define RTL8367C_PORT4_STATUS_NWAY_FAULT_MASK 0x200 ++#define RTL8367C_PORT4_STATUS_LINK_ON_MASTER_OFFSET 8 ++#define RTL8367C_PORT4_STATUS_LINK_ON_MASTER_MASK 0x100 ++#define RTL8367C_PORT4_STATUS_NWAY_CAP_OFFSET 7 ++#define RTL8367C_PORT4_STATUS_NWAY_CAP_MASK 0x80 ++#define RTL8367C_PORT4_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 ++#define RTL8367C_PORT4_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 ++#define RTL8367C_PORT4_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 ++#define RTL8367C_PORT4_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 ++#define RTL8367C_PORT4_STATUS_LINK_STATE_OFFSET 4 ++#define RTL8367C_PORT4_STATUS_LINK_STATE_MASK 0x10 ++#define RTL8367C_PORT4_STATUS_FULL_DUPLUX_CAP_OFFSET 2 ++#define RTL8367C_PORT4_STATUS_FULL_DUPLUX_CAP_MASK 0x4 ++#define RTL8367C_PORT4_STATUS_LINK_SPEED_OFFSET 0 ++#define RTL8367C_PORT4_STATUS_LINK_SPEED_MASK 0x3 ++ ++#define RTL8367C_REG_PORT5_STATUS 0x1357 ++#define RTL8367C_PORT5_STATUS_EN_1000_LPI_OFFSET 11 ++#define RTL8367C_PORT5_STATUS_EN_1000_LPI_MASK 0x800 ++#define RTL8367C_PORT5_STATUS_EN_100_LPI_OFFSET 10 ++#define RTL8367C_PORT5_STATUS_EN_100_LPI_MASK 0x400 ++#define RTL8367C_PORT5_STATUS_NWAY_FAULT_OFFSET 9 ++#define RTL8367C_PORT5_STATUS_NWAY_FAULT_MASK 0x200 ++#define RTL8367C_PORT5_STATUS_LINK_ON_MASTER_OFFSET 8 ++#define RTL8367C_PORT5_STATUS_LINK_ON_MASTER_MASK 0x100 ++#define RTL8367C_PORT5_STATUS_NWAY_CAP_OFFSET 7 ++#define RTL8367C_PORT5_STATUS_NWAY_CAP_MASK 0x80 ++#define RTL8367C_PORT5_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 ++#define RTL8367C_PORT5_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 ++#define RTL8367C_PORT5_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 ++#define RTL8367C_PORT5_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 ++#define RTL8367C_PORT5_STATUS_LINK_STATE_OFFSET 4 ++#define RTL8367C_PORT5_STATUS_LINK_STATE_MASK 0x10 ++#define RTL8367C_PORT5_STATUS_FULL_DUPLUX_CAP_OFFSET 2 ++#define RTL8367C_PORT5_STATUS_FULL_DUPLUX_CAP_MASK 0x4 ++#define RTL8367C_PORT5_STATUS_LINK_SPEED_OFFSET 0 ++#define RTL8367C_PORT5_STATUS_LINK_SPEED_MASK 0x3 ++ ++#define RTL8367C_REG_PORT6_STATUS 0x1358 ++#define RTL8367C_PORT6_STATUS_EN_1000_LPI_OFFSET 11 ++#define RTL8367C_PORT6_STATUS_EN_1000_LPI_MASK 0x800 ++#define RTL8367C_PORT6_STATUS_EN_100_LPI_OFFSET 10 ++#define RTL8367C_PORT6_STATUS_EN_100_LPI_MASK 0x400 ++#define RTL8367C_PORT6_STATUS_NWAY_FAULT_OFFSET 9 ++#define RTL8367C_PORT6_STATUS_NWAY_FAULT_MASK 0x200 ++#define RTL8367C_PORT6_STATUS_LINK_ON_MASTER_OFFSET 8 ++#define RTL8367C_PORT6_STATUS_LINK_ON_MASTER_MASK 0x100 ++#define RTL8367C_PORT6_STATUS_NWAY_CAP_OFFSET 7 ++#define RTL8367C_PORT6_STATUS_NWAY_CAP_MASK 0x80 ++#define RTL8367C_PORT6_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 ++#define RTL8367C_PORT6_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 ++#define RTL8367C_PORT6_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 ++#define RTL8367C_PORT6_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 ++#define RTL8367C_PORT6_STATUS_LINK_STATE_OFFSET 4 ++#define RTL8367C_PORT6_STATUS_LINK_STATE_MASK 0x10 ++#define RTL8367C_PORT6_STATUS_FULL_DUPLUX_CAP_OFFSET 2 ++#define RTL8367C_PORT6_STATUS_FULL_DUPLUX_CAP_MASK 0x4 ++#define RTL8367C_PORT6_STATUS_LINK_SPEED_OFFSET 0 ++#define RTL8367C_PORT6_STATUS_LINK_SPEED_MASK 0x3 ++ ++#define RTL8367C_REG_PORT7_STATUS 0x1359 ++#define RTL8367C_PORT7_STATUS_EN_1000_LPI_OFFSET 11 ++#define RTL8367C_PORT7_STATUS_EN_1000_LPI_MASK 0x800 ++#define RTL8367C_PORT7_STATUS_EN_100_LPI_OFFSET 10 ++#define RTL8367C_PORT7_STATUS_EN_100_LPI_MASK 0x400 ++#define RTL8367C_PORT7_STATUS_NWAY_FAULT_OFFSET 9 ++#define RTL8367C_PORT7_STATUS_NWAY_FAULT_MASK 0x200 ++#define RTL8367C_PORT7_STATUS_LINK_ON_MASTER_OFFSET 8 ++#define RTL8367C_PORT7_STATUS_LINK_ON_MASTER_MASK 0x100 ++#define RTL8367C_PORT7_STATUS_NWAY_CAP_OFFSET 7 ++#define RTL8367C_PORT7_STATUS_NWAY_CAP_MASK 0x80 ++#define RTL8367C_PORT7_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 ++#define RTL8367C_PORT7_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 ++#define RTL8367C_PORT7_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 ++#define RTL8367C_PORT7_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 ++#define RTL8367C_PORT7_STATUS_LINK_STATE_OFFSET 4 ++#define RTL8367C_PORT7_STATUS_LINK_STATE_MASK 0x10 ++#define RTL8367C_PORT7_STATUS_FULL_DUPLUX_CAP_OFFSET 2 ++#define RTL8367C_PORT7_STATUS_FULL_DUPLUX_CAP_MASK 0x4 ++#define RTL8367C_PORT7_STATUS_LINK_SPEED_OFFSET 0 ++#define RTL8367C_PORT7_STATUS_LINK_SPEED_MASK 0x3 ++ ++#define RTL8367C_REG_PORT8_STATUS 0x135a ++#define RTL8367C_PORT8_STATUS_EN_1000_LPI_OFFSET 11 ++#define RTL8367C_PORT8_STATUS_EN_1000_LPI_MASK 0x800 ++#define RTL8367C_PORT8_STATUS_EN_100_LPI_OFFSET 10 ++#define RTL8367C_PORT8_STATUS_EN_100_LPI_MASK 0x400 ++#define RTL8367C_PORT8_STATUS_NWAY_FAULT_OFFSET 9 ++#define RTL8367C_PORT8_STATUS_NWAY_FAULT_MASK 0x200 ++#define RTL8367C_PORT8_STATUS_LINK_ON_MASTER_OFFSET 8 ++#define RTL8367C_PORT8_STATUS_LINK_ON_MASTER_MASK 0x100 ++#define RTL8367C_PORT8_STATUS_NWAY_CAP_OFFSET 7 ++#define RTL8367C_PORT8_STATUS_NWAY_CAP_MASK 0x80 ++#define RTL8367C_PORT8_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 ++#define RTL8367C_PORT8_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 ++#define RTL8367C_PORT8_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 ++#define RTL8367C_PORT8_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 ++#define RTL8367C_PORT8_STATUS_LINK_STATE_OFFSET 4 ++#define RTL8367C_PORT8_STATUS_LINK_STATE_MASK 0x10 ++#define RTL8367C_PORT8_STATUS_FULL_DUPLUX_CAP_OFFSET 2 ++#define RTL8367C_PORT8_STATUS_FULL_DUPLUX_CAP_MASK 0x4 ++#define RTL8367C_PORT8_STATUS_LINK_SPEED_OFFSET 0 ++#define RTL8367C_PORT8_STATUS_LINK_SPEED_MASK 0x3 ++ ++#define RTL8367C_REG_PORT9_STATUS 0x135b ++#define RTL8367C_PORT9_STATUS_EN_1000_LPI_OFFSET 11 ++#define RTL8367C_PORT9_STATUS_EN_1000_LPI_MASK 0x800 ++#define RTL8367C_PORT9_STATUS_EN_100_LPI_OFFSET 10 ++#define RTL8367C_PORT9_STATUS_EN_100_LPI_MASK 0x400 ++#define RTL8367C_PORT9_STATUS_NWAY_FAULT_OFFSET 9 ++#define RTL8367C_PORT9_STATUS_NWAY_FAULT_MASK 0x200 ++#define RTL8367C_PORT9_STATUS_LINK_ON_MASTER_OFFSET 8 ++#define RTL8367C_PORT9_STATUS_LINK_ON_MASTER_MASK 0x100 ++#define RTL8367C_PORT9_STATUS_NWAY_CAP_OFFSET 7 ++#define RTL8367C_PORT9_STATUS_NWAY_CAP_MASK 0x80 ++#define RTL8367C_PORT9_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 ++#define RTL8367C_PORT9_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 ++#define RTL8367C_PORT9_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 ++#define RTL8367C_PORT9_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 ++#define RTL8367C_PORT9_STATUS_LINK_STATE_OFFSET 4 ++#define RTL8367C_PORT9_STATUS_LINK_STATE_MASK 0x10 ++#define RTL8367C_PORT9_STATUS_FULL_DUPLUX_CAP_OFFSET 2 ++#define RTL8367C_PORT9_STATUS_FULL_DUPLUX_CAP_MASK 0x4 ++#define RTL8367C_PORT9_STATUS_LINK_SPEED_OFFSET 0 ++#define RTL8367C_PORT9_STATUS_LINK_SPEED_MASK 0x3 ++ ++#define RTL8367C_REG_PORT10_STATUS 0x135c ++#define RTL8367C_PORT10_STATUS_EN_1000_LPI_OFFSET 11 ++#define RTL8367C_PORT10_STATUS_EN_1000_LPI_MASK 0x800 ++#define RTL8367C_PORT10_STATUS_EN_100_LPI_OFFSET 10 ++#define RTL8367C_PORT10_STATUS_EN_100_LPI_MASK 0x400 ++#define RTL8367C_PORT10_STATUS_NWAY_FAULT_OFFSET 9 ++#define RTL8367C_PORT10_STATUS_NWAY_FAULT_MASK 0x200 ++#define RTL8367C_PORT10_STATUS_LINK_ON_MASTER_OFFSET 8 ++#define RTL8367C_PORT10_STATUS_LINK_ON_MASTER_MASK 0x100 ++#define RTL8367C_PORT10_STATUS_NWAY_CAP_OFFSET 7 ++#define RTL8367C_PORT10_STATUS_NWAY_CAP_MASK 0x80 ++#define RTL8367C_PORT10_STATUS_TX_FLOWCTRL_CAP_OFFSET 6 ++#define RTL8367C_PORT10_STATUS_TX_FLOWCTRL_CAP_MASK 0x40 ++#define RTL8367C_PORT10_STATUS_RX_FLOWCTRL_CAP_OFFSET 5 ++#define RTL8367C_PORT10_STATUS_RX_FLOWCTRL_CAP_MASK 0x20 ++#define RTL8367C_PORT10_STATUS_LINK_STATE_OFFSET 4 ++#define RTL8367C_PORT10_STATUS_LINK_STATE_MASK 0x10 ++#define RTL8367C_PORT10_STATUS_FULL_DUPLUX_CAP_OFFSET 2 ++#define RTL8367C_PORT10_STATUS_FULL_DUPLUX_CAP_MASK 0x4 ++#define RTL8367C_PORT10_STATUS_LINK_SPEED_OFFSET 0 ++#define RTL8367C_PORT10_STATUS_LINK_SPEED_MASK 0x3 ++ ++#define RTL8367C_REG_UPS_CTRL0 0x1362 ++#define RTL8367C_P3_REF_SD_BIT0_OFFSET 8 ++#define RTL8367C_P3_REF_SD_BIT0_MASK 0xFF00 ++#define RTL8367C_P2_REF_SD_OFFSET 0 ++#define RTL8367C_P2_REF_SD_MASK 0xFF ++ ++#define RTL8367C_REG_UPS_CTRL1 0x1363 ++#define RTL8367C_UPS_OUT_OFFSET 8 ++#define RTL8367C_UPS_OUT_MASK 0xFF00 ++#define RTL8367C_UPS_WRITE_PULSE_OFFSET 1 ++#define RTL8367C_UPS_WRITE_PULSE_MASK 0x2 ++#define RTL8367C_UPS_EN_OFFSET 0 ++#define RTL8367C_UPS_EN_MASK 0x1 ++ ++#define RTL8367C_REG_UPS_CTRL2 0x1364 ++#define RTL8367C_IGNOE_MAC8_LINK_OFFSET 15 ++#define RTL8367C_IGNOE_MAC8_LINK_MASK 0x8000 ++#define RTL8367C_AGREE_SLEEP_OFFSET 14 ++#define RTL8367C_AGREE_SLEEP_MASK 0x4000 ++#define RTL8367C_WAIT_FOR_AGREEMENT_OFFSET 13 ++#define RTL8367C_WAIT_FOR_AGREEMENT_MASK 0x2000 ++#define RTL8367C_WAKE_UP_BY_LINK_OFFSET 12 ++#define RTL8367C_WAKE_UP_BY_LINK_MASK 0x1000 ++#define RTL8367C_WAKE_UP_BY_PHY_OFFSET 11 ++#define RTL8367C_WAKE_UP_BY_PHY_MASK 0x800 ++#define RTL8367C_SLOW_CLK_TGL_RATE_OFFSET 7 ++#define RTL8367C_SLOW_CLK_TGL_RATE_MASK 0x780 ++#define RTL8367C_PLL_G1_CTRL_EN_OFFSET 6 ++#define RTL8367C_PLL_G1_CTRL_EN_MASK 0x40 ++#define RTL8367C_PLL_G0_CTRL_EN_OFFSET 5 ++#define RTL8367C_PLL_G0_CTRL_EN_MASK 0x20 ++#define RTL8367C_SLOW_DOWN_PLL_EN_OFFSET 4 ++#define RTL8367C_SLOW_DOWN_PLL_EN_MASK 0x10 ++#define RTL8367C_SLOW_DOWN_CLK_EN_OFFSET 3 ++#define RTL8367C_SLOW_DOWN_CLK_EN_MASK 0x8 ++#define RTL8367C_GATING_CLK_SDS_EN_OFFSET 2 ++#define RTL8367C_GATING_CLK_SDS_EN_MASK 0x4 ++#define RTL8367C_GATING_CLK_CHIP_EN_OFFSET 1 ++#define RTL8367C_GATING_CLK_CHIP_EN_MASK 0x2 ++#define RTL8367C_GATING_SW_EN_OFFSET 0 ++#define RTL8367C_GATING_SW_EN_MASK 0x1 ++ ++#define RTL8367C_REG_GATING_CLK_1 0x1365 ++#define RTL8367C_ALDPS_MODE_4_OFFSET 15 ++#define RTL8367C_ALDPS_MODE_4_MASK 0x8000 ++#define RTL8367C_ALDPS_MODE_3_OFFSET 14 ++#define RTL8367C_ALDPS_MODE_3_MASK 0x4000 ++#define RTL8367C_ALDPS_MODE_2_OFFSET 13 ++#define RTL8367C_ALDPS_MODE_2_MASK 0x2000 ++#define RTL8367C_ALDPS_MODE_1_OFFSET 12 ++#define RTL8367C_ALDPS_MODE_1_MASK 0x1000 ++#define RTL8367C_ALDPS_MODE_0_OFFSET 11 ++#define RTL8367C_ALDPS_MODE_0_MASK 0x800 ++#define RTL8367C_UPS_DBGO_OFFSET 10 ++#define RTL8367C_UPS_DBGO_MASK 0x400 ++#define RTL8367C_IFMX_AFF_NOT_FF_OUT_OFFSET 9 ++#define RTL8367C_IFMX_AFF_NOT_FF_OUT_MASK 0x200 ++#define RTL8367C_WATER_LEVEL_FD_OFFSET 6 ++#define RTL8367C_WATER_LEVEL_FD_MASK 0x1C0 ++#define RTL8367C_WATER_LEVEL_Y2X_OFFSET 3 ++#define RTL8367C_WATER_LEVEL_Y2X_MASK 0x38 ++#define RTL8367C_WATER_LEVEL_X2Y_2_OFFSET 2 ++#define RTL8367C_WATER_LEVEL_X2Y_2_MASK 0x4 ++#define RTL8367C_IGNOE_MAC10_LINK_OFFSET 1 ++#define RTL8367C_IGNOE_MAC10_LINK_MASK 0x2 ++#define RTL8367C_IGNOE_MAC9_LINK_OFFSET 0 ++#define RTL8367C_IGNOE_MAC9_LINK_MASK 0x1 ++ ++#define RTL8367C_REG_UPS_CTRL4 0x1366 ++#define RTL8367C_PROB_EN_OFFSET 6 ++#define RTL8367C_PROB_EN_MASK 0x40 ++#define RTL8367C_PLL_DOWN_OFFSET 1 ++#define RTL8367C_PLL_DOWN_MASK 0x2 ++#define RTL8367C_XTAL_DOWN_OFFSET 0 ++#define RTL8367C_XTAL_DOWN_MASK 0x1 ++ ++#define RTL8367C_REG_UPS_CTRL5 0x1367 ++#define RTL8367C_FRC_CPU_ACPT_OFFSET 3 ++#define RTL8367C_FRC_CPU_ACPT_MASK 0x8 ++#define RTL8367C_UPS_CPU_ACPT_OFFSET 2 ++#define RTL8367C_UPS_CPU_ACPT_MASK 0x4 ++#define RTL8367C_UPS_DBG_4_OFFSET 0 ++#define RTL8367C_UPS_DBG_4_MASK 0x3 ++ ++#define RTL8367C_REG_UPS_CTRL6 0x1368 ++#define RTL8367C_UPS_CTRL6_OFFSET 0 ++#define RTL8367C_UPS_CTRL6_MASK 0xF ++ ++#define RTL8367C_REG_EFUSE_CMD_70B 0x1369 ++ ++#define RTL8367C_REG_EFUSE_CMD 0x1370 ++#define RTL8367C_EFUSE_TIME_OUT_FLAG_OFFSET 3 ++#define RTL8367C_EFUSE_TIME_OUT_FLAG_MASK 0x8 ++#define RTL8367C_EFUSE_ACCESS_BUSY_OFFSET 2 ++#define RTL8367C_EFUSE_ACCESS_BUSY_MASK 0x4 ++#define RTL8367C_EFUSE_COMMAND_EN_OFFSET 1 ++#define RTL8367C_EFUSE_COMMAND_EN_MASK 0x2 ++#define RTL8367C_EFUSE_WR_OFFSET 0 ++#define RTL8367C_EFUSE_WR_MASK 0x1 ++ ++#define RTL8367C_REG_EFUSE_ADR 0x1371 ++#define RTL8367C_DUMMY_15_10_OFFSET 8 ++#define RTL8367C_DUMMY_15_10_MASK 0xFF00 ++#define RTL8367C_EFUSE_ADDRESS_OFFSET 0 ++#define RTL8367C_EFUSE_ADDRESS_MASK 0xFF ++ ++#define RTL8367C_REG_EFUSE_WDAT 0x1372 ++ ++#define RTL8367C_REG_EFUSE_RDAT 0x1373 ++ ++#define RTL8367C_REG_I2C_CTRL 0x1374 ++#define RTL8367C_MDX_MST_FAIL_LAT_OFFSET 1 ++#define RTL8367C_MDX_MST_FAIL_LAT_MASK 0x2 ++#define RTL8367C_MDX_MST_FAIL_CLRPS_OFFSET 0 ++#define RTL8367C_MDX_MST_FAIL_CLRPS_MASK 0x1 ++ ++#define RTL8367C_REG_EEE_CFG 0x1375 ++#define RTL8367C_CFG_BYPASS_GATELPTD_OFFSET 11 ++#define RTL8367C_CFG_BYPASS_GATELPTD_MASK 0x800 ++#define RTL8367C_EEE_ABT_ADDR2_OFFSET 6 ++#define RTL8367C_EEE_ABT_ADDR2_MASK 0x7C0 ++#define RTL8367C_EEE_ABT_ADDR1_OFFSET 1 ++#define RTL8367C_EEE_ABT_ADDR1_MASK 0x3E ++#define RTL8367C_EEE_POLL_EN_OFFSET 0 ++#define RTL8367C_EEE_POLL_EN_MASK 0x1 ++ ++#define RTL8367C_REG_EEE_PAGE 0x1376 ++ ++#define RTL8367C_REG_EEE_EXT_PAGE 0x1377 ++ ++#define RTL8367C_REG_EEE_EN_SPD1000 0x1378 ++ ++#define RTL8367C_REG_EEE_EN_SPD100 0x1379 ++ ++#define RTL8367C_REG_EEE_LP_SPD1000 0x137a ++ ++#define RTL8367C_REG_EEE_LP_SPD100 0x137b ++ ++#define RTL8367C_REG_DW8051_PRO_REG0 0x13a0 ++ ++#define RTL8367C_REG_DW8051_PRO_REG1 0x13a1 ++ ++#define RTL8367C_REG_DW8051_PRO_REG2 0x13a2 ++ ++#define RTL8367C_REG_DW8051_PRO_REG3 0x13a3 ++ ++#define RTL8367C_REG_DW8051_PRO_REG4 0x13a4 ++ ++#define RTL8367C_REG_DW8051_PRO_REG5 0x13a5 ++ ++#define RTL8367C_REG_DW8051_PRO_REG6 0x13a6 ++ ++#define RTL8367C_REG_DW8051_PRO_REG7 0x13a7 ++ ++#define RTL8367C_REG_PROTECT_ID 0x13c0 ++ ++#define RTL8367C_REG_CHIP_VER_INTL 0x13c1 ++#define RTL8367C_CHIP_VER_INTL_OFFSET 0 ++#define RTL8367C_CHIP_VER_INTL_MASK 0xF ++ ++#define RTL8367C_REG_MAGIC_ID 0x13c2 ++ ++#define RTL8367C_REG_DIGITAL_INTERFACE_SELECT_1 0x13c3 ++#define RTL8367C_SKIP_MII_2_RXER_OFFSET 4 ++#define RTL8367C_SKIP_MII_2_RXER_MASK 0x10 ++#define RTL8367C_SELECT_GMII_2_OFFSET 0 ++#define RTL8367C_SELECT_GMII_2_MASK 0xF ++ ++#define RTL8367C_REG_DIGITAL_INTERFACE2_FORCE 0x13c4 ++#define RTL8367C_GMII_2_FORCE_OFFSET 12 ++#define RTL8367C_GMII_2_FORCE_MASK 0x1000 ++#define RTL8367C_RGMII_2_FORCE_OFFSET 0 ++#define RTL8367C_RGMII_2_FORCE_MASK 0xFFF ++ ++#define RTL8367C_REG_EXT2_RGMXF 0x13c5 ++#define RTL8367C_EXT2_RGTX_INV_OFFSET 6 ++#define RTL8367C_EXT2_RGTX_INV_MASK 0x40 ++#define RTL8367C_EXT2_RGRX_INV_OFFSET 5 ++#define RTL8367C_EXT2_RGRX_INV_MASK 0x20 ++#define RTL8367C_EXT2_RGMXF_OFFSET 0 ++#define RTL8367C_EXT2_RGMXF_MASK 0x1F ++ ++#define RTL8367C_REG_ROUTER_UPS_CFG 0x13c6 ++#define RTL8367C_UPS_Status_OFFSET 1 ++#define RTL8367C_UPS_Status_MASK 0x2 ++#define RTL8367C_SoftStart_OFFSET 0 ++#define RTL8367C_SoftStart_MASK 0x1 ++ ++#define RTL8367C_REG_CTRL_GPIO 0x13c7 ++#define RTL8367C_CTRL_GPIO_13_OFFSET 13 ++#define RTL8367C_CTRL_GPIO_13_MASK 0x2000 ++#define RTL8367C_CTRL_GPIO_12_OFFSET 12 ++#define RTL8367C_CTRL_GPIO_12_MASK 0x1000 ++#define RTL8367C_CTRL_GPIO_11_OFFSET 11 ++#define RTL8367C_CTRL_GPIO_11_MASK 0x800 ++#define RTL8367C_CTRL_GPIO_10_OFFSET 10 ++#define RTL8367C_CTRL_GPIO_10_MASK 0x400 ++#define RTL8367C_CTRL_GPIO_9_OFFSET 9 ++#define RTL8367C_CTRL_GPIO_9_MASK 0x200 ++#define RTL8367C_CTRL_GPIO_8_OFFSET 8 ++#define RTL8367C_CTRL_GPIO_8_MASK 0x100 ++#define RTL8367C_CTRL_GPIO_7_OFFSET 7 ++#define RTL8367C_CTRL_GPIO_7_MASK 0x80 ++#define RTL8367C_CTRL_GPIO_6_OFFSET 6 ++#define RTL8367C_CTRL_GPIO_6_MASK 0x40 ++#define RTL8367C_CTRL_GPIO_5_OFFSET 5 ++#define RTL8367C_CTRL_GPIO_5_MASK 0x20 ++#define RTL8367C_CTRL_GPIO_4_OFFSET 4 ++#define RTL8367C_CTRL_GPIO_4_MASK 0x10 ++#define RTL8367C_CTRL_GPIO_3_OFFSET 3 ++#define RTL8367C_CTRL_GPIO_3_MASK 0x8 ++#define RTL8367C_CTRL_GPIO_2_OFFSET 2 ++#define RTL8367C_CTRL_GPIO_2_MASK 0x4 ++#define RTL8367C_CTRL_GPIO_1_OFFSET 1 ++#define RTL8367C_CTRL_GPIO_1_MASK 0x2 ++#define RTL8367C_CTRL_GPIO_0_OFFSET 0 ++#define RTL8367C_CTRL_GPIO_0_MASK 0x1 ++ ++#define RTL8367C_REG_SEL_GPIO 0x13c8 ++#define RTL8367C_SEL_GPIO_13_OFFSET 13 ++#define RTL8367C_SEL_GPIO_13_MASK 0x2000 ++#define RTL8367C_SEL_GPIO_12_OFFSET 12 ++#define RTL8367C_SEL_GPIO_12_MASK 0x1000 ++#define RTL8367C_SEL_GPIO_11_OFFSET 11 ++#define RTL8367C_SEL_GPIO_11_MASK 0x800 ++#define RTL8367C_SEL_GPIO_10_OFFSET 10 ++#define RTL8367C_SEL_GPIO_10_MASK 0x400 ++#define RTL8367C_SEL_GPIO_9_OFFSET 9 ++#define RTL8367C_SEL_GPIO_9_MASK 0x200 ++#define RTL8367C_SEL_GPIO_8_OFFSET 8 ++#define RTL8367C_SEL_GPIO_8_MASK 0x100 ++#define RTL8367C_SEL_GPIO_7_OFFSET 7 ++#define RTL8367C_SEL_GPIO_7_MASK 0x80 ++#define RTL8367C_SEL_GPIO_6_OFFSET 6 ++#define RTL8367C_SEL_GPIO_6_MASK 0x40 ++#define RTL8367C_SEL_GPIO_5_OFFSET 5 ++#define RTL8367C_SEL_GPIO_5_MASK 0x20 ++#define RTL8367C_SEL_GPIO_4_OFFSET 4 ++#define RTL8367C_SEL_GPIO_4_MASK 0x10 ++#define RTL8367C_SEL_GPIO_3_OFFSET 3 ++#define RTL8367C_SEL_GPIO_3_MASK 0x8 ++#define RTL8367C_SEL_GPIO_2_OFFSET 2 ++#define RTL8367C_SEL_GPIO_2_MASK 0x4 ++#define RTL8367C_SEL_GPIO_1_OFFSET 1 ++#define RTL8367C_SEL_GPIO_1_MASK 0x2 ++#define RTL8367C_SEL_GPIO_0_OFFSET 0 ++#define RTL8367C_SEL_GPIO_0_MASK 0x1 ++ ++#define RTL8367C_REG_STATUS_GPIO 0x13c9 ++#define RTL8367C_STATUS_GPIO_OFFSET 0 ++#define RTL8367C_STATUS_GPIO_MASK 0x3FFF ++ ++#define RTL8367C_REG_SYNC_ETH_CFG 0x13e0 ++#define RTL8367C_DUMMY2_OFFSET 9 ++#define RTL8367C_DUMMY2_MASK 0xFE00 ++#define RTL8367C_RFC2819_TYPE_OFFSET 8 ++#define RTL8367C_RFC2819_TYPE_MASK 0x100 ++#define RTL8367C_DUMMY1_OFFSET 7 ++#define RTL8367C_DUMMY1_MASK 0x80 ++#define RTL8367C_FIBER_SYNCE125_L_SEL_OFFSET 6 ++#define RTL8367C_FIBER_SYNCE125_L_SEL_MASK 0x40 ++#define RTL8367C_SYNC_ETH_EN_RTT2_OFFSET 5 ++#define RTL8367C_SYNC_ETH_EN_RTT2_MASK 0x20 ++#define RTL8367C_SYNC_ETH_EN_RTT1_OFFSET 4 ++#define RTL8367C_SYNC_ETH_EN_RTT1_MASK 0x10 ++#define RTL8367C_SYNC_ETH_SEL_DPLL_OFFSET 3 ++#define RTL8367C_SYNC_ETH_SEL_DPLL_MASK 0x8 ++#define RTL8367C_SYNC_ETH_SEL_PHYREF_OFFSET 2 ++#define RTL8367C_SYNC_ETH_SEL_PHYREF_MASK 0x4 ++#define RTL8367C_SYNC_ETH_SEL_XTAL_OFFSET 1 ++#define RTL8367C_SYNC_ETH_SEL_XTAL_MASK 0x2 ++#define RTL8367C_DUMMY0_OFFSET 0 ++#define RTL8367C_DUMMY0_MASK 0x1 ++ ++#define RTL8367C_REG_LED_DRI_CFG 0x13e1 ++#define RTL8367C_LED_DRI_CFG_DUMMY_OFFSET 1 ++#define RTL8367C_LED_DRI_CFG_DUMMY_MASK 0xFFFE ++#define RTL8367C_LED_DRIVING_OFFSET 0 ++#define RTL8367C_LED_DRIVING_MASK 0x1 ++ ++#define RTL8367C_REG_CHIP_DEBUG2 0x13e2 ++#define RTL8367C_RG2_DN_OFFSET 6 ++#define RTL8367C_RG2_DN_MASK 0x1C0 ++#define RTL8367C_RG2_DP_OFFSET 3 ++#define RTL8367C_RG2_DP_MASK 0x38 ++#define RTL8367C_DRI_EXT2_RG_OFFSET 2 ++#define RTL8367C_DRI_EXT2_RG_MASK 0x4 ++#define RTL8367C_DRI_EXT2_OFFSET 1 ++#define RTL8367C_DRI_EXT2_MASK 0x2 ++#define RTL8367C_SLR_EXT2_OFFSET 0 ++#define RTL8367C_SLR_EXT2_MASK 0x1 ++ ++#define RTL8367C_REG_DIGITAL_DEBUG_2 0x13e3 ++ ++#define RTL8367C_REG_FIBER_RTL_OUI_CFG0 0x13e4 ++#define RTL8367C_FIBER_RTL_OUI_CFG0_OFFSET 0 ++#define RTL8367C_FIBER_RTL_OUI_CFG0_MASK 0xFF ++ ++#define RTL8367C_REG_FIBER_RTL_OUI_CFG1 0x13e5 ++ ++#define RTL8367C_REG_FIBER_CFG_0 0x13e6 ++#define RTL8367C_REV_NUM_OFFSET 8 ++#define RTL8367C_REV_NUM_MASK 0xF00 ++#define RTL8367C_MODEL_NUM_OFFSET 0 ++#define RTL8367C_MODEL_NUM_MASK 0x3F ++ ++#define RTL8367C_REG_FIBER_CFG_1 0x13e7 ++#define RTL8367C_SDS_FRC_REG4_OFFSET 12 ++#define RTL8367C_SDS_FRC_REG4_MASK 0x1000 ++#define RTL8367C_SDS_FRC_REG4_FIB100_OFFSET 11 ++#define RTL8367C_SDS_FRC_REG4_FIB100_MASK 0x800 ++#define RTL8367C_SEL_MASK_ONL_OFFSET 5 ++#define RTL8367C_SEL_MASK_ONL_MASK 0x20 ++#define RTL8367C_DIS_QUALITY_IN_MASK_OFFSET 4 ++#define RTL8367C_DIS_QUALITY_IN_MASK_MASK 0x10 ++#define RTL8367C_SDS_FRC_MODE_OFFSET 3 ++#define RTL8367C_SDS_FRC_MODE_MASK 0x8 ++#define RTL8367C_SDS_MODE_OFFSET 0 ++#define RTL8367C_SDS_MODE_MASK 0x7 ++ ++#define RTL8367C_REG_FIBER_CFG_2 0x13e8 ++#define RTL8367C_SEL_SDET_PS_OFFSET 12 ++#define RTL8367C_SEL_SDET_PS_MASK 0xF000 ++#define RTL8367C_UTP_DIS_RX_OFFSET 10 ++#define RTL8367C_UTP_DIS_RX_MASK 0xC00 ++#define RTL8367C_UTP_FRC_LD_OFFSET 8 ++#define RTL8367C_UTP_FRC_LD_MASK 0x300 ++#define RTL8367C_SDS_RX_DISABLE_OFFSET 6 ++#define RTL8367C_SDS_RX_DISABLE_MASK 0xC0 ++#define RTL8367C_SDS_TX_DISABLE_OFFSET 4 ++#define RTL8367C_SDS_TX_DISABLE_MASK 0x30 ++#define RTL8367C_FIBER_CFG_2_SDS_PWR_ISO_OFFSET 2 ++#define RTL8367C_FIBER_CFG_2_SDS_PWR_ISO_MASK 0xC ++#define RTL8367C_SDS_FRC_LD_OFFSET 0 ++#define RTL8367C_SDS_FRC_LD_MASK 0x3 ++ ++#define RTL8367C_REG_FIBER_CFG_3 0x13e9 ++#define RTL8367C_FIBER_CFG_3_OFFSET 0 ++#define RTL8367C_FIBER_CFG_3_MASK 0xFFF ++ ++#define RTL8367C_REG_FIBER_CFG_4 0x13ea ++ ++#define RTL8367C_REG_UTP_FIB_DET 0x13eb ++#define RTL8367C_FORCE_SEL_FIBER_OFFSET 14 ++#define RTL8367C_FORCE_SEL_FIBER_MASK 0xC000 ++#define RTL8367C_FIB_FINAL_TIMER_OFFSET 12 ++#define RTL8367C_FIB_FINAL_TIMER_MASK 0x3000 ++#define RTL8367C_FIB_LINK_TIMER_OFFSET 10 ++#define RTL8367C_FIB_LINK_TIMER_MASK 0xC00 ++#define RTL8367C_FIB_SDET_TIMER_OFFSET 8 ++#define RTL8367C_FIB_SDET_TIMER_MASK 0x300 ++#define RTL8367C_UTP_LINK_TIMER_OFFSET 6 ++#define RTL8367C_UTP_LINK_TIMER_MASK 0xC0 ++#define RTL8367C_UTP_SDET_TIMER_OFFSET 4 ++#define RTL8367C_UTP_SDET_TIMER_MASK 0x30 ++#define RTL8367C_FORCE_AUTODET_OFFSET 3 ++#define RTL8367C_FORCE_AUTODET_MASK 0x8 ++#define RTL8367C_AUTODET_FSM_CLR_OFFSET 2 ++#define RTL8367C_AUTODET_FSM_CLR_MASK 0x4 ++#define RTL8367C_UTP_FIRST_OFFSET 1 ++#define RTL8367C_UTP_FIRST_MASK 0x2 ++#define RTL8367C_UTP_FIB_DISAUTODET_OFFSET 0 ++#define RTL8367C_UTP_FIB_DISAUTODET_MASK 0x1 ++ ++#define RTL8367C_REG_NRESTORE_MAGIC_NUM 0x13ec ++#define RTL8367C_NRESTORE_MAGIC_NUM_MASK 0xFFFF ++#define RTL8367C_EEPROM_PROGRAM_CYCLE_OFFSET 0 ++#define RTL8367C_EEPROM_PROGRAM_CYCLE_MASK 0x3 ++ ++#define RTL8367C_REG_MAC_ACTIVE 0x13ee ++#define RTL8367C_MAC_ACTIVE_H_OFFSET 9 ++#define RTL8367C_MAC_ACTIVE_H_MASK 0xE00 ++#define RTL8367C_FORCE_MAC_ACTIVE_OFFSET 8 ++#define RTL8367C_FORCE_MAC_ACTIVE_MASK 0x100 ++#define RTL8367C_MAC_ACTIVE_OFFSET 0 ++#define RTL8367C_MAC_ACTIVE_MASK 0xFF ++ ++#define RTL8367C_REG_SERDES_RESULT 0x13ef ++#define RTL8367C_FIB100_DET_1_OFFSET 12 ++#define RTL8367C_FIB100_DET_1_MASK 0x1000 ++#define RTL8367C_FIB_ISO_1_OFFSET 11 ++#define RTL8367C_FIB_ISO_1_MASK 0x800 ++#define RTL8367C_SDS_ANFAULT_1_OFFSET 10 ++#define RTL8367C_SDS_ANFAULT_1_MASK 0x400 ++#define RTL8367C_SDS_INTB_1_OFFSET 9 ++#define RTL8367C_SDS_INTB_1_MASK 0x200 ++#define RTL8367C_SDS_LINK_OK_1_OFFSET 8 ++#define RTL8367C_SDS_LINK_OK_1_MASK 0x100 ++#define RTL8367C_FIB100_DET_OFFSET 4 ++#define RTL8367C_FIB100_DET_MASK 0x10 ++#define RTL8367C_FIB_ISO_OFFSET 3 ++#define RTL8367C_FIB_ISO_MASK 0x8 ++#define RTL8367C_SDS_ANFAULT_OFFSET 2 ++#define RTL8367C_SDS_ANFAULT_MASK 0x4 ++#define RTL8367C_SDS_INTB_OFFSET 1 ++#define RTL8367C_SDS_INTB_MASK 0x2 ++#define RTL8367C_SDS_LINK_OK_OFFSET 0 ++#define RTL8367C_SDS_LINK_OK_MASK 0x1 ++ ++#define RTL8367C_REG_CHIP_ECO 0x13f0 ++#define RTL8367C_CFG_CHIP_ECO_OFFSET 1 ++#define RTL8367C_CFG_CHIP_ECO_MASK 0xFFFE ++#define RTL8367C_CFG_CKOUTEN_OFFSET 0 ++#define RTL8367C_CFG_CKOUTEN_MASK 0x1 ++ ++#define RTL8367C_REG_WAKELPI_SLOT_PRD 0x13f1 ++#define RTL8367C_WAKELPI_SLOT_PRD_OFFSET 0 ++#define RTL8367C_WAKELPI_SLOT_PRD_MASK 0x1F ++ ++#define RTL8367C_REG_WAKELPI_SLOT_PG0 0x13f2 ++#define RTL8367C_WAKELPI_SLOT_P1_OFFSET 8 ++#define RTL8367C_WAKELPI_SLOT_P1_MASK 0x1F00 ++#define RTL8367C_WAKELPI_SLOT_P0_OFFSET 0 ++#define RTL8367C_WAKELPI_SLOT_P0_MASK 0x1F ++ ++#define RTL8367C_REG_WAKELPI_SLOT_PG1 0x13f3 ++#define RTL8367C_WAKELPI_SLOT_P3_OFFSET 8 ++#define RTL8367C_WAKELPI_SLOT_P3_MASK 0x1F00 ++#define RTL8367C_WAKELPI_SLOT_P2_OFFSET 0 ++#define RTL8367C_WAKELPI_SLOT_P2_MASK 0x1F ++ ++#define RTL8367C_REG_WAKELPI_SLOT_PG2 0x13f4 ++#define RTL8367C_WAKELPI_SLOT_P5_OFFSET 8 ++#define RTL8367C_WAKELPI_SLOT_P5_MASK 0x1F00 ++#define RTL8367C_WAKELPI_SLOT_P4_OFFSET 0 ++#define RTL8367C_WAKELPI_SLOT_P4_MASK 0x1F ++ ++#define RTL8367C_REG_WAKELPI_SLOT_PG3 0x13f5 ++#define RTL8367C_WAKELPI_SLOT_P7_OFFSET 8 ++#define RTL8367C_WAKELPI_SLOT_P7_MASK 0x1F00 ++#define RTL8367C_WAKELPI_SLOT_P6_OFFSET 0 ++#define RTL8367C_WAKELPI_SLOT_P6_MASK 0x1F ++ ++#define RTL8367C_REG_SYNC_FIFO_0 0x13f6 ++#define RTL8367C_SYNC_FIFO_TX_OFFSET 8 ++#define RTL8367C_SYNC_FIFO_TX_MASK 0x700 ++#define RTL8367C_SYNC_FIFO_RX_OFFSET 0 ++#define RTL8367C_SYNC_FIFO_RX_MASK 0xFF ++ ++#define RTL8367C_REG_SYNC_FIFO_1 0x13f7 ++#define RTL8367C_SYNC_FIFO_RX_ERR_P10_8_OFFSET 11 ++#define RTL8367C_SYNC_FIFO_RX_ERR_P10_8_MASK 0x3800 ++#define RTL8367C_SYNC_FIFO_TX_ERR_OFFSET 8 ++#define RTL8367C_SYNC_FIFO_TX_ERR_MASK 0x700 ++#define RTL8367C_SYNC_FIFO_RX_ERR_OFFSET 0 ++#define RTL8367C_SYNC_FIFO_RX_ERR_MASK 0xFF ++ ++#define RTL8367C_REG_RGM_EEE 0x13f8 ++#define RTL8367C_EXT2_PAD_STOP_EN_OFFSET 14 ++#define RTL8367C_EXT2_PAD_STOP_EN_MASK 0x4000 ++#define RTL8367C_EXT1_PAD_STOP_EN_OFFSET 13 ++#define RTL8367C_EXT1_PAD_STOP_EN_MASK 0x2000 ++#define RTL8367C_EXT0_PAD_STOP_EN_OFFSET 12 ++#define RTL8367C_EXT0_PAD_STOP_EN_MASK 0x1000 ++#define RTL8367C_EXT2_CYCLE_PAD_OFFSET 8 ++#define RTL8367C_EXT2_CYCLE_PAD_MASK 0xF00 ++#define RTL8367C_EXT1_CYCLE_PAD_OFFSET 4 ++#define RTL8367C_EXT1_CYCLE_PAD_MASK 0xF0 ++#define RTL8367C_EXT0_CYCLE_PAD_OFFSET 0 ++#define RTL8367C_EXT0_CYCLE_PAD_MASK 0xF ++ ++#define RTL8367C_REG_EXT_TXC_DLY 0x13f9 ++#define RTL8367C_EXT1_GMII_TX_DELAY_OFFSET 12 ++#define RTL8367C_EXT1_GMII_TX_DELAY_MASK 0x7000 ++#define RTL8367C_EXT0_GMII_TX_DELAY_OFFSET 9 ++#define RTL8367C_EXT0_GMII_TX_DELAY_MASK 0xE00 ++#define RTL8367C_EXT2_RGMII_TX_DELAY_OFFSET 6 ++#define RTL8367C_EXT2_RGMII_TX_DELAY_MASK 0x1C0 ++#define RTL8367C_EXT1_RGMII_TX_DELAY_OFFSET 3 ++#define RTL8367C_EXT1_RGMII_TX_DELAY_MASK 0x38 ++#define RTL8367C_EXT0_RGMII_TX_DELAY_OFFSET 0 ++#define RTL8367C_EXT0_RGMII_TX_DELAY_MASK 0x7 ++ ++#define RTL8367C_REG_IO_MISC_CTRL 0x13fa ++#define RTL8367C_IO_BUZZER_EN_OFFSET 3 ++#define RTL8367C_IO_BUZZER_EN_MASK 0x8 ++#define RTL8367C_IO_INTRPT_EN_OFFSET 2 ++#define RTL8367C_IO_INTRPT_EN_MASK 0x4 ++#define RTL8367C_IO_NRESTORE_EN_OFFSET 1 ++#define RTL8367C_IO_NRESTORE_EN_MASK 0x2 ++#define RTL8367C_IO_UART_EN_OFFSET 0 ++#define RTL8367C_IO_UART_EN_MASK 0x1 ++ ++#define RTL8367C_REG_CHIP_DUMMY_NO 0x13fb ++#define RTL8367C_CHIP_DUMMY_NO_OFFSET 0 ++#define RTL8367C_CHIP_DUMMY_NO_MASK 0xF ++ ++#define RTL8367C_REG_RC_CALIB_CFG 0x13fc ++#define RTL8367C_TRIG_BURN_EFUSE_OFFSET 9 ++#define RTL8367C_TRIG_BURN_EFUSE_MASK 0x200 ++#define RTL8367C_AMP_CALIB_FAIL_OFFSET 8 ++#define RTL8367C_AMP_CALIB_FAIL_MASK 0x100 ++#define RTL8367C_R_CALIB_FAIL_OFFSET 7 ++#define RTL8367C_R_CALIB_FAIL_MASK 0x80 ++#define RTL8367C_CFG_CALIB_MODE_OFFSET 6 ++#define RTL8367C_CFG_CALIB_MODE_MASK 0x40 ++#define RTL8367C_CENTER_PORT_SEL_OFFSET 3 ++#define RTL8367C_CENTER_PORT_SEL_MASK 0x38 ++#define RTL8367C_CALIB_FINISH_OFFSET 2 ++#define RTL8367C_CALIB_FINISH_MASK 0x4 ++#define RTL8367C_CFG_CALIB_OPTION_OFFSET 1 ++#define RTL8367C_CFG_CALIB_OPTION_MASK 0x2 ++#define RTL8367C_CFG_CALIB_EN_OFFSET 0 ++#define RTL8367C_CFG_CALIB_EN_MASK 0x1 ++ ++#define RTL8367C_REG_WAKELPI_SLOT_PG4 0x13fd ++#define RTL8367C_WAKELPI_SLOT_P9_OFFSET 8 ++#define RTL8367C_WAKELPI_SLOT_P9_MASK 0x1F00 ++#define RTL8367C_WAKELPI_SLOT_P8_OFFSET 0 ++#define RTL8367C_WAKELPI_SLOT_P8_MASK 0x1F ++ ++#define RTL8367C_REG_WAKELPI_SLOT_PG5 0x13fe ++#define RTL8367C_WAKELPI_SLOT_PG5_OFFSET 0 ++#define RTL8367C_WAKELPI_SLOT_PG5_MASK 0x1F ++ ++/* (16'h1400)mtrpool_reg */ ++ ++#define RTL8367C_REG_METER0_RATE_CTRL0 0x1400 ++ ++#define RTL8367C_REG_METER0_RATE_CTRL1 0x1401 ++#define RTL8367C_METER0_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER0_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER1_RATE_CTRL0 0x1402 ++ ++#define RTL8367C_REG_METER1_RATE_CTRL1 0x1403 ++#define RTL8367C_METER1_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER1_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER2_RATE_CTRL0 0x1404 ++ ++#define RTL8367C_REG_METER2_RATE_CTRL1 0x1405 ++#define RTL8367C_METER2_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER2_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER3_RATE_CTRL0 0x1406 ++ ++#define RTL8367C_REG_METER3_RATE_CTRL1 0x1407 ++#define RTL8367C_METER3_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER3_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER4_RATE_CTRL0 0x1408 ++ ++#define RTL8367C_REG_METER4_RATE_CTRL1 0x1409 ++#define RTL8367C_METER4_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER4_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER5_RATE_CTRL0 0x140a ++ ++#define RTL8367C_REG_METER5_RATE_CTRL1 0x140b ++#define RTL8367C_METER5_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER5_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER6_RATE_CTRL0 0x140c ++ ++#define RTL8367C_REG_METER6_RATE_CTRL1 0x140d ++#define RTL8367C_METER6_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER6_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER7_RATE_CTRL0 0x140e ++ ++#define RTL8367C_REG_METER7_RATE_CTRL1 0x140f ++#define RTL8367C_METER7_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER7_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER8_RATE_CTRL0 0x1410 ++ ++#define RTL8367C_REG_METER8_RATE_CTRL1 0x1411 ++#define RTL8367C_METER8_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER8_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER9_RATE_CTRL0 0x1412 ++ ++#define RTL8367C_REG_METER9_RATE_CTRL1 0x1413 ++#define RTL8367C_METER9_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER9_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER10_RATE_CTRL0 0x1414 ++ ++#define RTL8367C_REG_METER10_RATE_CTRL1 0x1415 ++#define RTL8367C_METER10_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER10_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER11_RATE_CTRL0 0x1416 ++ ++#define RTL8367C_REG_METER11_RATE_CTRL1 0x1417 ++#define RTL8367C_METER11_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER11_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER12_RATE_CTRL0 0x1418 ++ ++#define RTL8367C_REG_METER12_RATE_CTRL1 0x1419 ++#define RTL8367C_METER12_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER12_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER13_RATE_CTRL0 0x141a ++ ++#define RTL8367C_REG_METER13_RATE_CTRL1 0x141b ++#define RTL8367C_METER13_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER13_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER14_RATE_CTRL0 0x141c ++ ++#define RTL8367C_REG_METER14_RATE_CTRL1 0x141d ++#define RTL8367C_METER14_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER14_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER15_RATE_CTRL0 0x141e ++ ++#define RTL8367C_REG_METER15_RATE_CTRL1 0x141f ++#define RTL8367C_METER15_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER15_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER16_RATE_CTRL0 0x1420 ++ ++#define RTL8367C_REG_METER16_RATE_CTRL1 0x1421 ++#define RTL8367C_METER16_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER16_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER17_RATE_CTRL0 0x1422 ++ ++#define RTL8367C_REG_METER17_RATE_CTRL1 0x1423 ++#define RTL8367C_METER17_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER17_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER18_RATE_CTRL0 0x1424 ++ ++#define RTL8367C_REG_METER18_RATE_CTRL1 0x1425 ++#define RTL8367C_METER18_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER18_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER19_RATE_CTRL0 0x1426 ++ ++#define RTL8367C_REG_METER19_RATE_CTRL1 0x1427 ++#define RTL8367C_METER19_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER19_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER20_RATE_CTRL0 0x1428 ++ ++#define RTL8367C_REG_METER20_RATE_CTRL1 0x1429 ++#define RTL8367C_METER20_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER20_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER21_RATE_CTRL0 0x142a ++ ++#define RTL8367C_REG_METER21_RATE_CTRL1 0x142b ++#define RTL8367C_METER21_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER21_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER22_RATE_CTRL0 0x142c ++ ++#define RTL8367C_REG_METER22_RATE_CTRL1 0x142d ++#define RTL8367C_METER22_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER22_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER23_RATE_CTRL0 0x142e ++ ++#define RTL8367C_REG_METER23_RATE_CTRL1 0x142f ++#define RTL8367C_METER23_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER23_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER24_RATE_CTRL0 0x1430 ++ ++#define RTL8367C_REG_METER24_RATE_CTRL1 0x1431 ++#define RTL8367C_METER24_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER24_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER25_RATE_CTRL0 0x1432 ++ ++#define RTL8367C_REG_METER25_RATE_CTRL1 0x1433 ++#define RTL8367C_METER25_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER25_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER26_RATE_CTRL0 0x1434 ++ ++#define RTL8367C_REG_METER26_RATE_CTRL1 0x1435 ++#define RTL8367C_METER26_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER26_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER27_RATE_CTRL0 0x1436 ++ ++#define RTL8367C_REG_METER27_RATE_CTRL1 0x1437 ++#define RTL8367C_METER27_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER27_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER28_RATE_CTRL0 0x1438 ++ ++#define RTL8367C_REG_METER28_RATE_CTRL1 0x1439 ++#define RTL8367C_METER28_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER28_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER29_RATE_CTRL0 0x143a ++ ++#define RTL8367C_REG_METER29_RATE_CTRL1 0x143b ++#define RTL8367C_METER29_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER29_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER30_RATE_CTRL0 0x143c ++ ++#define RTL8367C_REG_METER30_RATE_CTRL1 0x143d ++#define RTL8367C_METER30_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER30_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER31_RATE_CTRL0 0x143e ++ ++#define RTL8367C_REG_METER31_RATE_CTRL1 0x143f ++#define RTL8367C_METER31_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER31_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER_MODE_SETTING0 0x1440 ++ ++#define RTL8367C_REG_METER_MODE_SETTING1 0x1441 ++ ++#define RTL8367C_REG_METER_MODE_TOKEN_CFG 0x1442 ++#define RTL8367C_METER_MODE_TOKEN_CFG_OFFSET 0 ++#define RTL8367C_METER_MODE_TOKEN_CFG_MASK 0x7FF ++ ++#define RTL8367C_REG_METER0_BUCKET_SIZE 0x1600 ++ ++#define RTL8367C_REG_METER1_BUCKET_SIZE 0x1601 ++ ++#define RTL8367C_REG_METER2_BUCKET_SIZE 0x1602 ++ ++#define RTL8367C_REG_METER3_BUCKET_SIZE 0x1603 ++ ++#define RTL8367C_REG_METER4_BUCKET_SIZE 0x1604 ++ ++#define RTL8367C_REG_METER5_BUCKET_SIZE 0x1605 ++ ++#define RTL8367C_REG_METER6_BUCKET_SIZE 0x1606 ++ ++#define RTL8367C_REG_METER7_BUCKET_SIZE 0x1607 ++ ++#define RTL8367C_REG_METER8_BUCKET_SIZE 0x1608 ++ ++#define RTL8367C_REG_METER9_BUCKET_SIZE 0x1609 ++ ++#define RTL8367C_REG_METER10_BUCKET_SIZE 0x160a ++ ++#define RTL8367C_REG_METER11_BUCKET_SIZE 0x160b ++ ++#define RTL8367C_REG_METER12_BUCKET_SIZE 0x160c ++ ++#define RTL8367C_REG_METER13_BUCKET_SIZE 0x160d ++ ++#define RTL8367C_REG_METER14_BUCKET_SIZE 0x160e ++ ++#define RTL8367C_REG_METER15_BUCKET_SIZE 0x160f ++ ++#define RTL8367C_REG_METER16_BUCKET_SIZE 0x1610 ++ ++#define RTL8367C_REG_METER17_BUCKET_SIZE 0x1611 ++ ++#define RTL8367C_REG_METER18_BUCKET_SIZE 0x1612 ++ ++#define RTL8367C_REG_METER19_BUCKET_SIZE 0x1613 ++ ++#define RTL8367C_REG_METER20_BUCKET_SIZE 0x1614 ++ ++#define RTL8367C_REG_METER21_BUCKET_SIZE 0x1615 ++ ++#define RTL8367C_REG_METER22_BUCKET_SIZE 0x1616 ++ ++#define RTL8367C_REG_METER23_BUCKET_SIZE 0x1617 ++ ++#define RTL8367C_REG_METER24_BUCKET_SIZE 0x1618 ++ ++#define RTL8367C_REG_METER25_BUCKET_SIZE 0x1619 ++ ++#define RTL8367C_REG_METER26_BUCKET_SIZE 0x161a ++ ++#define RTL8367C_REG_METER27_BUCKET_SIZE 0x161b ++ ++#define RTL8367C_REG_METER28_BUCKET_SIZE 0x161c ++ ++#define RTL8367C_REG_METER29_BUCKET_SIZE 0x161d ++ ++#define RTL8367C_REG_METER30_BUCKET_SIZE 0x161e ++ ++#define RTL8367C_REG_METER31_BUCKET_SIZE 0x161f ++ ++#define RTL8367C_REG_METER_CTRL0 0x1700 ++#define RTL8367C_METER_OP_OFFSET 8 ++#define RTL8367C_METER_OP_MASK 0x100 ++#define RTL8367C_METER_TICK_OFFSET 0 ++#define RTL8367C_METER_TICK_MASK 0xFF ++ ++#define RTL8367C_REG_METER_CTRL1 0x1701 ++#define RTL8367C_METER_CTRL1_OFFSET 0 ++#define RTL8367C_METER_CTRL1_MASK 0xFF ++ ++#define RTL8367C_REG_METER_OVERRATE_INDICATOR0 0x1702 ++ ++#define RTL8367C_REG_METER_OVERRATE_INDICATOR1 0x1703 ++ ++#define RTL8367C_REG_METER_OVERRATE_INDICATOR0_8051 0x1704 ++ ++#define RTL8367C_REG_METER_OVERRATE_INDICATOR1_8051 0x1705 ++ ++#define RTL8367C_REG_METER_IFG_CTRL0 0x1712 ++#define RTL8367C_METER15_IFG_OFFSET 15 ++#define RTL8367C_METER15_IFG_MASK 0x8000 ++#define RTL8367C_METER14_IFG_OFFSET 14 ++#define RTL8367C_METER14_IFG_MASK 0x4000 ++#define RTL8367C_METER13_IFG_OFFSET 13 ++#define RTL8367C_METER13_IFG_MASK 0x2000 ++#define RTL8367C_METER12_IFG_OFFSET 12 ++#define RTL8367C_METER12_IFG_MASK 0x1000 ++#define RTL8367C_METER11_IFG_OFFSET 11 ++#define RTL8367C_METER11_IFG_MASK 0x800 ++#define RTL8367C_METER10_IFG_OFFSET 10 ++#define RTL8367C_METER10_IFG_MASK 0x400 ++#define RTL8367C_METER9_IFG_OFFSET 9 ++#define RTL8367C_METER9_IFG_MASK 0x200 ++#define RTL8367C_METER8_IFG_OFFSET 8 ++#define RTL8367C_METER8_IFG_MASK 0x100 ++#define RTL8367C_METER7_IFG_OFFSET 7 ++#define RTL8367C_METER7_IFG_MASK 0x80 ++#define RTL8367C_METER6_IFG_OFFSET 6 ++#define RTL8367C_METER6_IFG_MASK 0x40 ++#define RTL8367C_METER5_IFG_OFFSET 5 ++#define RTL8367C_METER5_IFG_MASK 0x20 ++#define RTL8367C_METER4_IFG_OFFSET 4 ++#define RTL8367C_METER4_IFG_MASK 0x10 ++#define RTL8367C_METER3_IFG_OFFSET 3 ++#define RTL8367C_METER3_IFG_MASK 0x8 ++#define RTL8367C_METER2_IFG_OFFSET 2 ++#define RTL8367C_METER2_IFG_MASK 0x4 ++#define RTL8367C_METER1_IFG_OFFSET 1 ++#define RTL8367C_METER1_IFG_MASK 0x2 ++#define RTL8367C_METER0_IFG_OFFSET 0 ++#define RTL8367C_METER0_IFG_MASK 0x1 ++ ++#define RTL8367C_REG_METER_IFG_CTRL1 0x1713 ++#define RTL8367C_METER31_IFG_OFFSET 15 ++#define RTL8367C_METER31_IFG_MASK 0x8000 ++#define RTL8367C_METER30_IFG_OFFSET 14 ++#define RTL8367C_METER30_IFG_MASK 0x4000 ++#define RTL8367C_METER29_IFG_OFFSET 13 ++#define RTL8367C_METER29_IFG_MASK 0x2000 ++#define RTL8367C_METER28_IFG_OFFSET 12 ++#define RTL8367C_METER28_IFG_MASK 0x1000 ++#define RTL8367C_METER27_IFG_OFFSET 11 ++#define RTL8367C_METER27_IFG_MASK 0x800 ++#define RTL8367C_METER26_IFG_OFFSET 10 ++#define RTL8367C_METER26_IFG_MASK 0x400 ++#define RTL8367C_METER25_IFG_OFFSET 9 ++#define RTL8367C_METER25_IFG_MASK 0x200 ++#define RTL8367C_METER24_IFG_OFFSET 8 ++#define RTL8367C_METER24_IFG_MASK 0x100 ++#define RTL8367C_METER23_IFG_OFFSET 7 ++#define RTL8367C_METER23_IFG_MASK 0x80 ++#define RTL8367C_METER22_IFG_OFFSET 6 ++#define RTL8367C_METER22_IFG_MASK 0x40 ++#define RTL8367C_METER21_IFG_OFFSET 5 ++#define RTL8367C_METER21_IFG_MASK 0x20 ++#define RTL8367C_METER20_IFG_OFFSET 4 ++#define RTL8367C_METER20_IFG_MASK 0x10 ++#define RTL8367C_METER19_IFG_OFFSET 3 ++#define RTL8367C_METER19_IFG_MASK 0x8 ++#define RTL8367C_METER18_IFG_OFFSET 2 ++#define RTL8367C_METER18_IFG_MASK 0x4 ++#define RTL8367C_METER17_IFG_OFFSET 1 ++#define RTL8367C_METER17_IFG_MASK 0x2 ++#define RTL8367C_METER16_IFG_OFFSET 0 ++#define RTL8367C_METER16_IFG_MASK 0x1 ++ ++#define RTL8367C_REG_METER_CTRL2 0x1722 ++#define RTL8367C_cfg_mtr_tick_8g_OFFSET 8 ++#define RTL8367C_cfg_mtr_tick_8g_MASK 0xFF00 ++#define RTL8367C_cfg_mtr_dec_cnt_8g_OFFSET 0 ++#define RTL8367C_cfg_mtr_dec_cnt_8g_MASK 0xFF ++ ++#define RTL8367C_REG_DUMMY_1723 0x1723 ++ ++#define RTL8367C_REG_DUMMY_1724 0x1724 ++ ++#define RTL8367C_REG_DUMMY_1725 0x1725 ++ ++#define RTL8367C_REG_DUMMY_1726 0x1726 ++ ++#define RTL8367C_REG_DUMMY_1727 0x1727 ++ ++#define RTL8367C_REG_DUMMY_1728 0x1728 ++ ++#define RTL8367C_REG_DUMMY_1729 0x1729 ++ ++#define RTL8367C_REG_DUMMY_172A 0x172a ++ ++#define RTL8367C_REG_DUMMY_172B 0x172b ++ ++#define RTL8367C_REG_DUMMY_172C 0x172c ++ ++#define RTL8367C_REG_DUMMY_172D 0x172d ++ ++#define RTL8367C_REG_DUMMY_172E 0x172e ++ ++#define RTL8367C_REG_DUMMY_172F 0x172f ++ ++#define RTL8367C_REG_DUMMY_1730 0x1730 ++ ++#define RTL8367C_REG_DUMMY_1731 0x1731 ++ ++#define RTL8367C_REG_METER32_RATE_CTRL0 0x1740 ++ ++#define RTL8367C_REG_METER32_RATE_CTRL1 0x1741 ++#define RTL8367C_METER32_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER32_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER33_RATE_CTRL0 0x1742 ++ ++#define RTL8367C_REG_METER33_RATE_CTRL1 0x1743 ++#define RTL8367C_METER33_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER33_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER34_RATE_CTRL0 0x1744 ++ ++#define RTL8367C_REG_METER34_RATE_CTRL1 0x1745 ++#define RTL8367C_METER34_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER34_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER35_RATE_CTRL0 0x1746 ++ ++#define RTL8367C_REG_METER35_RATE_CTRL1 0x1747 ++#define RTL8367C_METER35_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER35_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER36_RATE_CTRL0 0x1748 ++ ++#define RTL8367C_REG_METER36_RATE_CTRL1 0x1749 ++#define RTL8367C_METER36_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER36_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER37_RATE_CTRL0 0x174a ++ ++#define RTL8367C_REG_METER37_RATE_CTRL1 0x174b ++#define RTL8367C_METER37_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER37_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER38_RATE_CTRL0 0x174c ++ ++#define RTL8367C_REG_METER38_RATE_CTRL1 0x174d ++#define RTL8367C_METER38_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER38_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER39_RATE_CTRL0 0x174e ++ ++#define RTL8367C_REG_METER39_RATE_CTRL1 0x174f ++#define RTL8367C_METER39_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER39_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER40_RATE_CTRL0 0x1750 ++ ++#define RTL8367C_REG_METER40_RATE_CTRL1 0x1751 ++#define RTL8367C_METER40_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER40_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER41_RATE_CTRL0 0x1752 ++ ++#define RTL8367C_REG_METER41_RATE_CTRL1 0x1753 ++#define RTL8367C_METER41_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER41_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER42_RATE_CTRL0 0x1754 ++ ++#define RTL8367C_REG_METER42_RATE_CTRL1 0x1755 ++#define RTL8367C_METER42_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER42_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER43_RATE_CTRL0 0x1756 ++ ++#define RTL8367C_REG_METER43_RATE_CTRL1 0x1757 ++#define RTL8367C_METER43_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER43_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER44_RATE_CTRL0 0x1758 ++ ++#define RTL8367C_REG_METER44_RATE_CTRL1 0x1759 ++#define RTL8367C_METER44_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER44_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER45_RATE_CTRL0 0x175a ++ ++#define RTL8367C_REG_METER45_RATE_CTRL1 0x175b ++#define RTL8367C_METER45_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER45_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER46_RATE_CTRL0 0x175c ++ ++#define RTL8367C_REG_METER46_RATE_CTRL1 0x175d ++#define RTL8367C_METER46_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER46_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER47_RATE_CTRL0 0x175e ++ ++#define RTL8367C_REG_METER47_RATE_CTRL1 0x175f ++#define RTL8367C_METER47_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER47_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER48_RATE_CTRL0 0x1760 ++ ++#define RTL8367C_REG_METER48_RATE_CTRL1 0x1761 ++#define RTL8367C_METER48_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER48_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER49_RATE_CTRL0 0x1762 ++ ++#define RTL8367C_REG_METER49_RATE_CTRL1 0x1763 ++#define RTL8367C_METER49_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER49_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER50_RATE_CTRL0 0x1764 ++ ++#define RTL8367C_REG_METER50_RATE_CTRL1 0x1765 ++#define RTL8367C_METER50_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER50_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER51_RATE_CTRL0 0x1766 ++ ++#define RTL8367C_REG_METER51_RATE_CTRL1 0x1767 ++#define RTL8367C_METER51_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER51_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER52_RATE_CTRL0 0x1768 ++ ++#define RTL8367C_REG_METER52_RATE_CTRL1 0x1769 ++#define RTL8367C_METER52_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER52_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER53_RATE_CTRL0 0x176a ++ ++#define RTL8367C_REG_METER53_RATE_CTRL1 0x176b ++#define RTL8367C_METER53_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER53_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER54_RATE_CTRL0 0x176c ++ ++#define RTL8367C_REG_METER54_RATE_CTRL1 0x176d ++#define RTL8367C_METER54_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER54_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER55_RATE_CTRL0 0x176e ++ ++#define RTL8367C_REG_METER55_RATE_CTRL1 0x176f ++#define RTL8367C_METER55_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER55_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER56_RATE_CTRL0 0x1770 ++ ++#define RTL8367C_REG_METER56_RATE_CTRL1 0x1771 ++#define RTL8367C_METER56_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER56_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER57_RATE_CTRL0 0x1772 ++ ++#define RTL8367C_REG_METER57_RATE_CTRL1 0x1773 ++#define RTL8367C_METER57_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER57_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER58_RATE_CTRL0 0x1774 ++ ++#define RTL8367C_REG_METER58_RATE_CTRL1 0x1775 ++#define RTL8367C_METER58_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER58_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER59_RATE_CTRL0 0x1776 ++ ++#define RTL8367C_REG_METER59_RATE_CTRL1 0x1777 ++#define RTL8367C_METER59_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER59_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER60_RATE_CTRL0 0x1778 ++ ++#define RTL8367C_REG_METER60_RATE_CTRL1 0x1779 ++#define RTL8367C_METER60_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER60_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER61_RATE_CTRL0 0x177a ++ ++#define RTL8367C_REG_METER61_RATE_CTRL1 0x177b ++#define RTL8367C_METER61_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER61_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER62_RATE_CTRL0 0x177c ++ ++#define RTL8367C_REG_METER62_RATE_CTRL1 0x177d ++#define RTL8367C_METER62_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER62_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER63_RATE_CTRL0 0x177e ++ ++#define RTL8367C_REG_METER63_RATE_CTRL1 0x177f ++#define RTL8367C_METER63_RATE_CTRL1_OFFSET 0 ++#define RTL8367C_METER63_RATE_CTRL1_MASK 0x7 ++ ++#define RTL8367C_REG_METER_MODE_SETTING2 0x1780 ++ ++#define RTL8367C_REG_METER_MODE_SETTING3 0x1781 ++ ++#define RTL8367C_REG_METER32_BUCKET_SIZE 0x1790 ++ ++#define RTL8367C_REG_METER33_BUCKET_SIZE 0x1791 ++ ++#define RTL8367C_REG_METER34_BUCKET_SIZE 0x1792 ++ ++#define RTL8367C_REG_METER35_BUCKET_SIZE 0x1793 ++ ++#define RTL8367C_REG_METER36_BUCKET_SIZE 0x1794 ++ ++#define RTL8367C_REG_METER37_BUCKET_SIZE 0x1795 ++ ++#define RTL8367C_REG_METER38_BUCKET_SIZE 0x1796 ++ ++#define RTL8367C_REG_METER39_BUCKET_SIZE 0x1797 ++ ++#define RTL8367C_REG_METER40_BUCKET_SIZE 0x1798 ++ ++#define RTL8367C_REG_METER41_BUCKET_SIZE 0x1799 ++ ++#define RTL8367C_REG_METER42_BUCKET_SIZE 0x179a ++ ++#define RTL8367C_REG_METER43_BUCKET_SIZE 0x179b ++ ++#define RTL8367C_REG_METER44_BUCKET_SIZE 0x179c ++ ++#define RTL8367C_REG_METER45_BUCKET_SIZE 0x179d ++ ++#define RTL8367C_REG_METER46_BUCKET_SIZE 0x179e ++ ++#define RTL8367C_REG_METER47_BUCKET_SIZE 0x179f ++ ++#define RTL8367C_REG_METER48_BUCKET_SIZE 0x17a0 ++ ++#define RTL8367C_REG_METER49_BUCKET_SIZE 0x17a1 ++ ++#define RTL8367C_REG_METER50_BUCKET_SIZE 0x17a2 ++ ++#define RTL8367C_REG_METER51_BUCKET_SIZE 0x17a3 ++ ++#define RTL8367C_REG_METER52_BUCKET_SIZE 0x17a4 ++ ++#define RTL8367C_REG_METER53_BUCKET_SIZE 0x17a5 ++ ++#define RTL8367C_REG_METER54_BUCKET_SIZE 0x17a6 ++ ++#define RTL8367C_REG_METER55_BUCKET_SIZE 0x17a7 ++ ++#define RTL8367C_REG_METER56_BUCKET_SIZE 0x17a8 ++ ++#define RTL8367C_REG_METER57_BUCKET_SIZE 0x17a9 ++ ++#define RTL8367C_REG_METER58_BUCKET_SIZE 0x17aa ++ ++#define RTL8367C_REG_METER59_BUCKET_SIZE 0x17ab ++ ++#define RTL8367C_REG_METER60_BUCKET_SIZE 0x17ac ++ ++#define RTL8367C_REG_METER61_BUCKET_SIZE 0x17ad ++ ++#define RTL8367C_REG_METER62_BUCKET_SIZE 0x17ae ++ ++#define RTL8367C_REG_METER63_BUCKET_SIZE 0x17af ++ ++#define RTL8367C_REG_METER_OVERRATE_INDICATOR2 0x17b0 ++ ++#define RTL8367C_REG_METER_OVERRATE_INDICATOR3 0x17b1 ++ ++#define RTL8367C_REG_METER_OVERRATE_INDICATOR2_8051 0x17b2 ++ ++#define RTL8367C_REG_METER_OVERRATE_INDICATOR3_8051 0x17b3 ++ ++#define RTL8367C_REG_METER_IFG_CTRL2 0x17b4 ++#define RTL8367C_METER47_IFG_OFFSET 15 ++#define RTL8367C_METER47_IFG_MASK 0x8000 ++#define RTL8367C_METER46_IFG_OFFSET 14 ++#define RTL8367C_METER46_IFG_MASK 0x4000 ++#define RTL8367C_METER45_IFG_OFFSET 13 ++#define RTL8367C_METER45_IFG_MASK 0x2000 ++#define RTL8367C_METER44_IFG_OFFSET 12 ++#define RTL8367C_METER44_IFG_MASK 0x1000 ++#define RTL8367C_METER43_IFG_OFFSET 11 ++#define RTL8367C_METER43_IFG_MASK 0x800 ++#define RTL8367C_METER42_IFG_OFFSET 10 ++#define RTL8367C_METER42_IFG_MASK 0x400 ++#define RTL8367C_METER41_IFG_OFFSET 9 ++#define RTL8367C_METER41_IFG_MASK 0x200 ++#define RTL8367C_METER40_IFG_OFFSET 8 ++#define RTL8367C_METER40_IFG_MASK 0x100 ++#define RTL8367C_METER39_IFG_OFFSET 7 ++#define RTL8367C_METER39_IFG_MASK 0x80 ++#define RTL8367C_METER38_IFG_OFFSET 6 ++#define RTL8367C_METER38_IFG_MASK 0x40 ++#define RTL8367C_METER37_IFG_OFFSET 5 ++#define RTL8367C_METER37_IFG_MASK 0x20 ++#define RTL8367C_METER36_IFG_OFFSET 4 ++#define RTL8367C_METER36_IFG_MASK 0x10 ++#define RTL8367C_METER35_IFG_OFFSET 3 ++#define RTL8367C_METER35_IFG_MASK 0x8 ++#define RTL8367C_METER34_IFG_OFFSET 2 ++#define RTL8367C_METER34_IFG_MASK 0x4 ++#define RTL8367C_METER33_IFG_OFFSET 1 ++#define RTL8367C_METER33_IFG_MASK 0x2 ++#define RTL8367C_METER32_IFG_OFFSET 0 ++#define RTL8367C_METER32_IFG_MASK 0x1 ++ ++#define RTL8367C_REG_METER_IFG_CTRL3 0x17b5 ++#define RTL8367C_METER63_IFG_OFFSET 15 ++#define RTL8367C_METER63_IFG_MASK 0x8000 ++#define RTL8367C_METER62_IFG_OFFSET 14 ++#define RTL8367C_METER62_IFG_MASK 0x4000 ++#define RTL8367C_METER61_IFG_OFFSET 13 ++#define RTL8367C_METER61_IFG_MASK 0x2000 ++#define RTL8367C_METER60_IFG_OFFSET 12 ++#define RTL8367C_METER60_IFG_MASK 0x1000 ++#define RTL8367C_METER59_IFG_OFFSET 11 ++#define RTL8367C_METER59_IFG_MASK 0x800 ++#define RTL8367C_METER58_IFG_OFFSET 10 ++#define RTL8367C_METER58_IFG_MASK 0x400 ++#define RTL8367C_METER57_IFG_OFFSET 9 ++#define RTL8367C_METER57_IFG_MASK 0x200 ++#define RTL8367C_METER56_IFG_OFFSET 8 ++#define RTL8367C_METER56_IFG_MASK 0x100 ++#define RTL8367C_METER55_IFG_OFFSET 7 ++#define RTL8367C_METER55_IFG_MASK 0x80 ++#define RTL8367C_METER54_IFG_OFFSET 6 ++#define RTL8367C_METER54_IFG_MASK 0x40 ++#define RTL8367C_METER53_IFG_OFFSET 5 ++#define RTL8367C_METER53_IFG_MASK 0x20 ++#define RTL8367C_METER52_IFG_OFFSET 4 ++#define RTL8367C_METER52_IFG_MASK 0x10 ++#define RTL8367C_METER51_IFG_OFFSET 3 ++#define RTL8367C_METER51_IFG_MASK 0x8 ++#define RTL8367C_METER50_IFG_OFFSET 2 ++#define RTL8367C_METER50_IFG_MASK 0x4 ++#define RTL8367C_METER49_IFG_OFFSET 1 ++#define RTL8367C_METER49_IFG_MASK 0x2 ++#define RTL8367C_METER48_IFG_OFFSET 0 ++#define RTL8367C_METER48_IFG_MASK 0x1 ++ ++#define RTL8367C_REG_METER_MISC 0x17b6 ++#define RTL8367C_METER_MISC_OFFSET 0 ++#define RTL8367C_METER_MISC_MASK 0x1 ++ ++/* (16'h1800)8051_RLDP_EEE_reg */ ++ ++#define RTL8367C_REG_EEELLDP_CTRL0 0x1820 ++#define RTL8367C_EEELLDP_SUBTYPE_OFFSET 6 ++#define RTL8367C_EEELLDP_SUBTYPE_MASK 0x3FC0 ++#define RTL8367C_EEELLDP_TRAP_8051_OFFSET 2 ++#define RTL8367C_EEELLDP_TRAP_8051_MASK 0x4 ++#define RTL8367C_EEELLDP_TRAP_CPU_OFFSET 1 ++#define RTL8367C_EEELLDP_TRAP_CPU_MASK 0x2 ++#define RTL8367C_EEELLDP_ENABLE_OFFSET 0 ++#define RTL8367C_EEELLDP_ENABLE_MASK 0x1 ++ ++#define RTL8367C_REG_EEELLDP_PMSK 0x1822 ++#define RTL8367C_EEELLDP_PMSK_OFFSET 0 ++#define RTL8367C_EEELLDP_PMSK_MASK 0x7FF ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_08 0x1843 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_07 0x1844 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_06 0x1845 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_05 0x1846 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_04 0x1847 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_03 0x1848 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_02 0x1849 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_01 0x184a ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P00_00 0x184b ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_08 0x184c ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_07 0x184d ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_06 0x184e ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_05 0x184f ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_04 0x1850 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_03 0x1851 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_02 0x1852 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_01 0x1853 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P01_00 0x1854 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_08 0x1855 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_07 0x1856 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_06 0x1857 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_05 0x1858 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_04 0x1859 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_03 0x185a ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_02 0x185b ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_01 0x185c ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P02_00 0x185d ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_08 0x185e ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_07 0x185f ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_06 0x1860 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_05 0x1861 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_04 0x1862 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_03 0x1863 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_02 0x1864 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_01 0x1865 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P03_00 0x1866 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_08 0x1867 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_07 0x1868 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_06 0x1869 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_05 0x186a ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_04 0x186b ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_03 0x186c ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_02 0x186d ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_01 0x186e ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P04_00 0x186f ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_08 0x1870 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_07 0x1871 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_06 0x1872 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_05 0x1873 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_04 0x1874 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_03 0x1875 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_02 0x1876 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_01 0x1877 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P05_00 0x1878 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_08 0x1879 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_07 0x187a ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_06 0x187b ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_05 0x187c ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_04 0x187d ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_03 0x187e ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_02 0x187f ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_01 0x1880 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P06_00 0x1881 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_08 0x1882 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_07 0x1883 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_06 0x1884 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_05 0x1885 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_04 0x1886 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_03 0x1887 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_02 0x1888 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_01 0x1889 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P07_00 0x188a ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_08 0x188b ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_07 0x188c ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_06 0x188d ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_05 0x188e ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_04 0x188f ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_03 0x1890 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_02 0x1891 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_01 0x1892 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P08_00 0x1893 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_08 0x1894 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_07 0x1895 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_06 0x1896 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_05 0x1897 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_04 0x1898 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_03 0x1899 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_02 0x189a ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_01 0x189b ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P09_00 0x189c ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_08 0x189d ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_07 0x189e ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_06 0x189f ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_05 0x18a0 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_04 0x18a1 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_03 0x18a2 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_02 0x18a3 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_01 0x18a4 ++ ++#define RTL8367C_REG_EEELLDP_RX_VALUE_P10_00 0x18a5 ++ ++#define RTL8367C_REG_RLDP_CTRL0 0x18e0 ++#define RTL8367C_RLDP_TRIGGER_MODE_OFFSET 14 ++#define RTL8367C_RLDP_TRIGGER_MODE_MASK 0x4000 ++#define RTL8367C_RLDP_8051_LOOP_PORTMSK_OFFSET 6 ++#define RTL8367C_RLDP_8051_LOOP_PORTMSK_MASK 0x3FC0 ++#define RTL8367C_RLPP_8051_TRAP_OFFSET 5 ++#define RTL8367C_RLPP_8051_TRAP_MASK 0x20 ++#define RTL8367C_RLDP_INDICATOR_SOURCE_OFFSET 4 ++#define RTL8367C_RLDP_INDICATOR_SOURCE_MASK 0x10 ++#define RTL8367C_RLDP_GEN_RANDOM_OFFSET 3 ++#define RTL8367C_RLDP_GEN_RANDOM_MASK 0x8 ++#define RTL8367C_RLDP_COMP_ID_OFFSET 2 ++#define RTL8367C_RLDP_COMP_ID_MASK 0x4 ++#define RTL8367C_RLDP_8051_ENABLE_OFFSET 1 ++#define RTL8367C_RLDP_8051_ENABLE_MASK 0x2 ++#define RTL8367C_RLDP_ENABLE_OFFSET 0 ++#define RTL8367C_RLDP_ENABLE_MASK 0x1 ++ ++#define RTL8367C_REG_RLDP_CTRL1 0x18e1 ++#define RTL8367C_RLDP_RETRY_COUNT_LOOPSTATE_OFFSET 8 ++#define RTL8367C_RLDP_RETRY_COUNT_LOOPSTATE_MASK 0xFF00 ++#define RTL8367C_RLDP_RETRY_COUNT_CHKSTATE_OFFSET 0 ++#define RTL8367C_RLDP_RETRY_COUNT_CHKSTATE_MASK 0xFF ++ ++#define RTL8367C_REG_RLDP_CTRL2 0x18e2 ++ ++#define RTL8367C_REG_RLDP_CTRL3 0x18e3 ++ ++#define RTL8367C_REG_RLDP_CTRL4 0x18e4 ++#define RTL8367C_RLDP_CTRL4_OFFSET 0 ++#define RTL8367C_RLDP_CTRL4_MASK 0x7FF ++ ++#define RTL8367C_REG_RLDP_RAND_NUM0 0x18e5 ++ ++#define RTL8367C_REG_RLDP_RAND_NUM1 0x18e6 ++ ++#define RTL8367C_REG_RLDP_RAND_NUM2 0x18e7 ++ ++#define RTL8367C_REG_RLDP_MAGIC_NUM0 0x18e8 ++ ++#define RTL8367C_REG_RLDP_MAGIC_NUM1 0x18e9 ++ ++#define RTL8367C_REG_RLDP_MAGIC_NUM2 0x18ea ++ ++#define RTL8367C_REG_RLDP_LOOPED_INDICATOR 0x18eb ++#define RTL8367C_RLDP_LOOPED_INDICATOR_OFFSET 0 ++#define RTL8367C_RLDP_LOOPED_INDICATOR_MASK 0x7FF ++ ++#define RTL8367C_REG_RLDP_LOOP_PORT_REG0 0x18ec ++#define RTL8367C_RLDP_LOOP_PORT_01_OFFSET 8 ++#define RTL8367C_RLDP_LOOP_PORT_01_MASK 0xF00 ++#define RTL8367C_RLDP_LOOP_PORT_00_OFFSET 0 ++#define RTL8367C_RLDP_LOOP_PORT_00_MASK 0xF ++ ++#define RTL8367C_REG_RLDP_LOOP_PORT_REG1 0x18ed ++#define RTL8367C_RLDP_LOOP_PORT_03_OFFSET 8 ++#define RTL8367C_RLDP_LOOP_PORT_03_MASK 0xF00 ++#define RTL8367C_RLDP_LOOP_PORT_02_OFFSET 0 ++#define RTL8367C_RLDP_LOOP_PORT_02_MASK 0xF ++ ++#define RTL8367C_REG_RLDP_LOOP_PORT_REG2 0x18ee ++#define RTL8367C_RLDP_LOOP_PORT_05_OFFSET 8 ++#define RTL8367C_RLDP_LOOP_PORT_05_MASK 0xF00 ++#define RTL8367C_RLDP_LOOP_PORT_04_OFFSET 0 ++#define RTL8367C_RLDP_LOOP_PORT_04_MASK 0xF ++ ++#define RTL8367C_REG_RLDP_LOOP_PORT_REG3 0x18ef ++#define RTL8367C_RLDP_LOOP_PORT_07_OFFSET 8 ++#define RTL8367C_RLDP_LOOP_PORT_07_MASK 0xF00 ++#define RTL8367C_RLDP_LOOP_PORT_06_OFFSET 0 ++#define RTL8367C_RLDP_LOOP_PORT_06_MASK 0xF ++ ++#define RTL8367C_REG_RLDP_RELEASED_INDICATOR 0x18f0 ++#define RTL8367C_RLDP_RELEASED_INDICATOR_OFFSET 0 ++#define RTL8367C_RLDP_RELEASED_INDICATOR_MASK 0x7FF ++ ++#define RTL8367C_REG_RLDP_LOOPSTATUS_INDICATOR 0x18f1 ++#define RTL8367C_RLDP_LOOPSTATUS_INDICATOR_OFFSET 0 ++#define RTL8367C_RLDP_LOOPSTATUS_INDICATOR_MASK 0x7FF ++ ++#define RTL8367C_REG_RLDP_LOOP_PORT_REG4 0x18f2 ++#define RTL8367C_RLDP_LOOP_PORT_9_OFFSET 8 ++#define RTL8367C_RLDP_LOOP_PORT_9_MASK 0xF00 ++#define RTL8367C_RLDP_LOOP_PORT_8_OFFSET 0 ++#define RTL8367C_RLDP_LOOP_PORT_8_MASK 0xF ++ ++#define RTL8367C_REG_RLDP_LOOP_PORT_REG5 0x18f3 ++#define RTL8367C_RLDP_LOOP_PORT_REG5_OFFSET 0 ++#define RTL8367C_RLDP_LOOP_PORT_REG5_MASK 0xF ++ ++#define RTL8367C_REG_RLDP_CTRL5 0x18f4 ++#define RTL8367C_RLDP_CTRL5_OFFSET 0 ++#define RTL8367C_RLDP_CTRL5_MASK 0x7 ++ ++/* (16'h1900)EEE_EEEP_reg */ ++ ++#define RTL8367C_REG_EEE_500M_CTRL0 0x1900 ++#define RTL8367C_EEE_500M_CTRL0_OFFSET 0 ++#define RTL8367C_EEE_500M_CTRL0_MASK 0xFF ++ ++#define RTL8367C_REG_EEE_RXIDLE_GIGA_CTRL 0x1901 ++#define RTL8367C_EEE_RXIDLE_GIGA_EN_OFFSET 8 ++#define RTL8367C_EEE_RXIDLE_GIGA_EN_MASK 0x100 ++#define RTL8367C_EEE_RXIDLE_GIGA_OFFSET 0 ++#define RTL8367C_EEE_RXIDLE_GIGA_MASK 0xFF ++ ++#define RTL8367C_REG_EEE_RXIDLE_500M_CTRL 0x1902 ++#define RTL8367C_EEE_RXIDLE_500M_EN_OFFSET 8 ++#define RTL8367C_EEE_RXIDLE_500M_EN_MASK 0x100 ++#define RTL8367C_EEE_RXIDLE_500M_OFFSET 0 ++#define RTL8367C_EEE_RXIDLE_500M_MASK 0xFF ++ ++#define RTL8367C_REG_EEE_DECISION_GIGA_500M 0x1903 ++#define RTL8367C_EEE_DECISION_GIGA_OFFSET 8 ++#define RTL8367C_EEE_DECISION_GIGA_MASK 0xFF00 ++#define RTL8367C_EEE_DECISION_500M_OFFSET 0 ++#define RTL8367C_EEE_DECISION_500M_MASK 0xFF ++ ++#define RTL8367C_REG_EEE_DECISION_100M 0x1904 ++#define RTL8367C_EEE_DECISION_100M_OFFSET 0 ++#define RTL8367C_EEE_DECISION_100M_MASK 0xFF ++ ++#define RTL8367C_REG_EEEP_DEFER_TXLPI 0x1905 ++#define RTL8367C_EEEP_DEFER_TXLPI_OFFSET 0 ++#define RTL8367C_EEEP_DEFER_TXLPI_MASK 0x1 ++ ++#define RTL8367C_REG_EEEP_EN 0x1906 ++#define RTL8367C_EEEP_SLAVE_EN_OFFSET 3 ++#define RTL8367C_EEEP_SLAVE_EN_MASK 0x8 ++#define RTL8367C_EEEP_100M_OFFSET 2 ++#define RTL8367C_EEEP_100M_MASK 0x4 ++#define RTL8367C_EEEP_500M_OFFSET 1 ++#define RTL8367C_EEEP_500M_MASK 0x2 ++#define RTL8367C_EEEP_GIGA_OFFSET 0 ++#define RTL8367C_EEEP_GIGA_MASK 0x1 ++ ++#define RTL8367C_REG_EEEP_TI_GIGA_500M 0x1907 ++#define RTL8367C_EEEP_TI_GIGA_OFFSET 8 ++#define RTL8367C_EEEP_TI_GIGA_MASK 0xFF00 ++#define RTL8367C_EEEP_TI_500M_OFFSET 0 ++#define RTL8367C_EEEP_TI_500M_MASK 0xFF ++ ++#define RTL8367C_REG_EEEP_TI_100M 0x1908 ++#define RTL8367C_EEEP_TI_100M_OFFSET 0 ++#define RTL8367C_EEEP_TI_100M_MASK 0xFF ++ ++#define RTL8367C_REG_EEEP_CTRL2 0x1909 ++#define RTL8367C_EEEP_CTRL2_OFFSET 0 ++#define RTL8367C_EEEP_CTRL2_MASK 0xFF ++ ++#define RTL8367C_REG_EEEP_RX_RATE_500M 0x190b ++ ++#define RTL8367C_REG_EEEP_RW_GIGA_SLV 0x190c ++#define RTL8367C_EEEP_RW_GIGA_SLV_OFFSET 0 ++#define RTL8367C_EEEP_RW_GIGA_SLV_MASK 0xFF ++ ++#define RTL8367C_REG_EEEP_TMR_GIGA 0x190d ++#define RTL8367C_RX_IDLE_EEEP_GIGA_OFFSET 8 ++#define RTL8367C_RX_IDLE_EEEP_GIGA_MASK 0xFF00 ++#define RTL8367C_RX_MIN_SLP_TMR_GIGA_OFFSET 0 ++#define RTL8367C_RX_MIN_SLP_TMR_GIGA_MASK 0xFF ++ ++#define RTL8367C_REG_EEEP_TMR_500M 0x190e ++#define RTL8367C_RX_IDLE_EEEP_500M_OFFSET 8 ++#define RTL8367C_RX_IDLE_EEEP_500M_MASK 0xFF00 ++#define RTL8367C_RX_MIN_SLP_TMR_500M_OFFSET 0 ++#define RTL8367C_RX_MIN_SLP_TMR_500M_MASK 0xFF ++ ++#define RTL8367C_REG_EEEP_TMR_100M 0x190f ++#define RTL8367C_RX_IDLE_EEEP_100M_OFFSET 8 ++#define RTL8367C_RX_IDLE_EEEP_100M_MASK 0xFF00 ++#define RTL8367C_RX_MIN_SLP_TMR_100M_OFFSET 0 ++#define RTL8367C_RX_MIN_SLP_TMR_100M_MASK 0xFF ++ ++#define RTL8367C_REG_EEEP_RW_500M_MST_SLV 0x1910 ++#define RTL8367C_EEEP_RW_500M_MST_OFFSET 8 ++#define RTL8367C_EEEP_RW_500M_MST_MASK 0xFF00 ++#define RTL8367C_EEEP_RW_500M_SLV_OFFSET 0 ++#define RTL8367C_EEEP_RW_500M_SLV_MASK 0xFF ++ ++#define RTL8367C_REG_EEEP_500M_CTRL0 0x1911 ++#define RTL8367C_EEEP_500M_CTRL0_OFFSET 0 ++#define RTL8367C_EEEP_500M_CTRL0_MASK 0xFF ++ ++#define RTL8367C_REG_EEEP_500M_CTRL1 0x1912 ++#define RTL8367C_EEEP_TW_500M_OFFSET 8 ++#define RTL8367C_EEEP_TW_500M_MASK 0xFF00 ++#define RTL8367C_EEEP_TP_500M_OFFSET 0 ++#define RTL8367C_EEEP_TP_500M_MASK 0xFF ++ ++#define RTL8367C_REG_EEEP_500M_CTRL2 0x1913 ++#define RTL8367C_EEEP_TXEN_500M_OFFSET 12 ++#define RTL8367C_EEEP_TXEN_500M_MASK 0x1000 ++#define RTL8367C_EEEP_TU_500M_OFFSET 8 ++#define RTL8367C_EEEP_TU_500M_MASK 0x300 ++#define RTL8367C_EEEP_TS_500M_OFFSET 0 ++#define RTL8367C_EEEP_TS_500M_MASK 0xFF ++ ++#define RTL8367C_REG_EEE_NEW_CTRL0 0x1914 ++#define RTL8367C_LINK_UP_DELAY_OFFSET 3 ++#define RTL8367C_LINK_UP_DELAY_MASK 0x18 ++#define RTL8367C_EEE_TXLPI_ORI_OFFSET 2 ++#define RTL8367C_EEE_TXLPI_ORI_MASK 0x4 ++#define RTL8367C_REALTX_SEL_OFFSET 1 ++#define RTL8367C_REALTX_SEL_MASK 0x2 ++#define RTL8367C_EN_FC_EFCT_OFFSET 0 ++#define RTL8367C_EN_FC_EFCT_MASK 0x1 ++ ++#define RTL8367C_REG_EEE_LONGIDLE_100M 0x1915 ++#define RTL8367C_EEE_LONGIDLE_100M_OFFSET 0 ++#define RTL8367C_EEE_LONGIDLE_100M_MASK 0x3FF ++ ++#define RTL8367C_REG_EEE_LONGIDLE_500M 0x1916 ++#define RTL8367C_EEE_LONGIDLE_500M_OFFSET 0 ++#define RTL8367C_EEE_LONGIDLE_500M_MASK 0x3FF ++ ++#define RTL8367C_REG_EEE_LONGIDLE_GIGA 0x1917 ++#define RTL8367C_EEE_LONGIDLE_GIGA_OFFSET 0 ++#define RTL8367C_EEE_LONGIDLE_GIGA_MASK 0x3FF ++ ++#define RTL8367C_REG_EEE_MINIPG_100M 0x1918 ++ ++#define RTL8367C_REG_EEE_MINIPG_500M 0x1919 ++ ++#define RTL8367C_REG_EEE_MINIPG_GIGA 0x191A ++ ++#define RTL8367C_REG_EEE_LONGIDLE_CTRL0 0x191B ++#define RTL8367C_TX_IDLEN_REQ_100M_OFFSET 10 ++#define RTL8367C_TX_IDLEN_REQ_100M_MASK 0x400 ++#define RTL8367C_TX_IDLEN_REQ_500M_OFFSET 9 ++#define RTL8367C_TX_IDLEN_REQ_500M_MASK 0x200 ++#define RTL8367C_TX_IDLEN_REQ_GIGA_OFFSET 8 ++#define RTL8367C_TX_IDLEN_REQ_GIGA_MASK 0x100 ++#define RTL8367C_EEE_LONGIDLE_CTRL0_TX_LPI_MINIPG_100M_OFFSET 0 ++#define RTL8367C_EEE_LONGIDLE_CTRL0_TX_LPI_MINIPG_100M_MASK 0xFF ++ ++#define RTL8367C_REG_EEE_LONGIDLE_CTRL1 0x191C ++#define RTL8367C_EEE_LONGIDLE_CTRL1_TX_LPI_MINIPG_GELITE_OFFSET 8 ++#define RTL8367C_EEE_LONGIDLE_CTRL1_TX_LPI_MINIPG_GELITE_MASK 0xFF00 ++#define RTL8367C_EEE_LONGIDLE_CTRL1_TX_LPI_MINIPG_GIGA_OFFSET 0 ++#define RTL8367C_EEE_LONGIDLE_CTRL1_TX_LPI_MINIPG_GIGA_MASK 0xFF ++ ++#define RTL8367C_REG_EEE_TD_CTRL_H 0x191d ++#define RTL8367C_REF_RXLPI_OFFSET 8 ++#define RTL8367C_REF_RXLPI_MASK 0x100 ++#define RTL8367C_LOW_Q_TX_DELAY_GE_500M_H_OFFSET 4 ++#define RTL8367C_LOW_Q_TX_DELAY_GE_500M_H_MASK 0xF0 ++#define RTL8367C_LOW_Q_TX_DELAY_FE_H_OFFSET 0 ++#define RTL8367C_LOW_Q_TX_DELAY_FE_H_MASK 0xF ++ ++/* (16'h1a00)nic_reg */ ++ ++#define RTL8367C_REG_NIC_RXRDRL 0x1a04 ++#define RTL8367C_NIC_RXRDRL_OFFSET 0 ++#define RTL8367C_NIC_RXRDRL_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_RXRDRH 0x1a05 ++#define RTL8367C_NIC_RXRDRH_OFFSET 0 ++#define RTL8367C_NIC_RXRDRH_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_TXASRL 0x1a08 ++#define RTL8367C_NIC_TXASRL_OFFSET 0 ++#define RTL8367C_NIC_TXASRL_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_TXASRH 0x1a09 ++#define RTL8367C_NIC_TXASRH_OFFSET 0 ++#define RTL8367C_NIC_TXASRH_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_RXCMDR 0x1a0c ++#define RTL8367C_NIC_RXCMDR_OFFSET 0 ++#define RTL8367C_NIC_RXCMDR_MASK 0x1 ++ ++#define RTL8367C_REG_NIC_TXCMDR 0x1a0d ++#define RTL8367C_NIC_TXCMDR_OFFSET 0 ++#define RTL8367C_NIC_TXCMDR_MASK 0x1 ++ ++#define RTL8367C_REG_NIC_IMS 0x1a0e ++#define RTL8367C_NIC_RXIS_OFFSET 7 ++#define RTL8367C_NIC_RXIS_MASK 0x80 ++#define RTL8367C_NIC_TXIS_OFFSET 6 ++#define RTL8367C_NIC_TXIS_MASK 0x40 ++#define RTL8367C_NIC_TXES_OFFSET 5 ++#define RTL8367C_NIC_TXES_MASK 0x20 ++#define RTL8367C_NIC_IMS_DMY_OFFSET 4 ++#define RTL8367C_NIC_IMS_DMY_MASK 0x10 ++#define RTL8367C_NIC_RXBUS_OFFSET 3 ++#define RTL8367C_NIC_RXBUS_MASK 0x8 ++#define RTL8367C_NIC_TXBOS_OFFSET 2 ++#define RTL8367C_NIC_TXBOS_MASK 0x4 ++#define RTL8367C_NIC_RXMIS_OFFSET 1 ++#define RTL8367C_NIC_RXMIS_MASK 0x2 ++#define RTL8367C_NIC_TXNLS_OFFSET 0 ++#define RTL8367C_NIC_TXNLS_MASK 0x1 ++ ++#define RTL8367C_REG_NIC_IMR 0x1a0f ++#define RTL8367C_NIC_RXIE_OFFSET 7 ++#define RTL8367C_NIC_RXIE_MASK 0x80 ++#define RTL8367C_NIC_TXIE_OFFSET 6 ++#define RTL8367C_NIC_TXIE_MASK 0x40 ++#define RTL8367C_NIC_TXEE_OFFSET 5 ++#define RTL8367C_NIC_TXEE_MASK 0x20 ++#define RTL8367C_NIC_IMR_DMY_OFFSET 4 ++#define RTL8367C_NIC_IMR_DMY_MASK 0x10 ++#define RTL8367C_NIC_RXBUE_OFFSET 3 ++#define RTL8367C_NIC_RXBUE_MASK 0x8 ++#define RTL8367C_NIC_TXBOE_OFFSET 2 ++#define RTL8367C_NIC_TXBOE_MASK 0x4 ++#define RTL8367C_NIC_RXMIE_OFFSET 1 ++#define RTL8367C_NIC_RXMIE_MASK 0x2 ++#define RTL8367C_NIC_TXNLE_OFFSET 0 ++#define RTL8367C_NIC_TXNLE_MASK 0x1 ++ ++#define RTL8367C_REG_NIC_RXCR0 0x1a14 ++#define RTL8367C_NIC_HFPPE_OFFSET 7 ++#define RTL8367C_NIC_HFPPE_MASK 0x80 ++#define RTL8367C_NIC_HFMPE_OFFSET 6 ++#define RTL8367C_NIC_HFMPE_MASK 0x40 ++#define RTL8367C_NIC_RXBPE_OFFSET 5 ++#define RTL8367C_NIC_RXBPE_MASK 0x20 ++#define RTL8367C_NIC_RXMPE_OFFSET 4 ++#define RTL8367C_NIC_RXMPE_MASK 0x10 ++#define RTL8367C_NIC_RXPPS_OFFSET 2 ++#define RTL8367C_NIC_RXPPS_MASK 0xC ++#define RTL8367C_NIC_RXAPE_OFFSET 1 ++#define RTL8367C_NIC_RXAPE_MASK 0x2 ++#define RTL8367C_NIC_ARPPE_OFFSET 0 ++#define RTL8367C_NIC_ARPPE_MASK 0x1 ++ ++#define RTL8367C_REG_NIC_RXCR1 0x1a15 ++#define RTL8367C_NIC_RL4CEPE_OFFSET 4 ++#define RTL8367C_NIC_RL4CEPE_MASK 0x10 ++#define RTL8367C_NIC_RL3CEPE_OFFSET 3 ++#define RTL8367C_NIC_RL3CEPE_MASK 0x8 ++#define RTL8367C_NIC_RCRCEPE_OFFSET 2 ++#define RTL8367C_NIC_RCRCEPE_MASK 0x4 ++#define RTL8367C_NIC_RMCRC_OFFSET 1 ++#define RTL8367C_NIC_RMCRC_MASK 0x2 ++#define RTL8367C_NIC_RXENABLE_OFFSET 0 ++#define RTL8367C_NIC_RXENABLE_MASK 0x1 ++ ++#define RTL8367C_REG_NIC_TXCR 0x1a16 ++#define RTL8367C_NIC_LBE_OFFSET 2 ++#define RTL8367C_NIC_LBE_MASK 0x4 ++#define RTL8367C_NIC_TXMFM_OFFSET 1 ++#define RTL8367C_NIC_TXMFM_MASK 0x2 ++#define RTL8367C_NIC_TXENABLE_OFFSET 0 ++#define RTL8367C_NIC_TXENABLE_MASK 0x1 ++ ++#define RTL8367C_REG_NIC_GCR 0x1a17 ++#define RTL8367C_DUMMY_7_6_OFFSET 6 ++#define RTL8367C_DUMMY_7_6_MASK 0xC0 ++#define RTL8367C_NIC_RXMTU_OFFSET 4 ++#define RTL8367C_NIC_RXMTU_MASK 0x30 ++#define RTL8367C_NIC_GCR_DUMMY_0_OFFSET 0 ++#define RTL8367C_NIC_GCR_DUMMY_0_MASK 0x1 ++ ++#define RTL8367C_REG_NIC_MHR0 0x1a24 ++#define RTL8367C_NIC_MHR0_OFFSET 0 ++#define RTL8367C_NIC_MHR0_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_MHR1 0x1a25 ++#define RTL8367C_NIC_MHR1_OFFSET 0 ++#define RTL8367C_NIC_MHR1_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_MHR2 0x1a26 ++#define RTL8367C_NIC_MHR2_OFFSET 0 ++#define RTL8367C_NIC_MHR2_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_MHR3 0x1a27 ++#define RTL8367C_NIC_MHR3_OFFSET 0 ++#define RTL8367C_NIC_MHR3_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_MHR4 0x1a28 ++#define RTL8367C_NIC_MHR4_OFFSET 0 ++#define RTL8367C_NIC_MHR4_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_MHR5 0x1a29 ++#define RTL8367C_NIC_MHR5_OFFSET 0 ++#define RTL8367C_NIC_MHR5_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_MHR6 0x1a2a ++#define RTL8367C_NIC_MHR6_OFFSET 0 ++#define RTL8367C_NIC_MHR6_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_MHR7 0x1a2b ++#define RTL8367C_NIC_MHR7_OFFSET 0 ++#define RTL8367C_NIC_MHR7_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_PAHR0 0x1a2c ++#define RTL8367C_NIC_PAHR0_OFFSET 0 ++#define RTL8367C_NIC_PAHR0_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_PAHR1 0x1a2d ++#define RTL8367C_NIC_PAHR1_OFFSET 0 ++#define RTL8367C_NIC_PAHR1_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_PAHR2 0x1a2e ++#define RTL8367C_NIC_PAHR2_OFFSET 0 ++#define RTL8367C_NIC_PAHR2_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_PAHR3 0x1a2f ++#define RTL8367C_NIC_PAHR3_OFFSET 0 ++#define RTL8367C_NIC_PAHR3_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_PAHR4 0x1a30 ++#define RTL8367C_NIC_PAHR4_OFFSET 0 ++#define RTL8367C_NIC_PAHR4_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_PAHR5 0x1a31 ++#define RTL8367C_NIC_PAHR5_OFFSET 0 ++#define RTL8367C_NIC_PAHR5_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_PAHR6 0x1a32 ++#define RTL8367C_NIC_PAHR6_OFFSET 0 ++#define RTL8367C_NIC_PAHR6_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_PAHR7 0x1a33 ++#define RTL8367C_NIC_PAHR7_OFFSET 0 ++#define RTL8367C_NIC_PAHR7_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_TXSTOPRL 0x1a44 ++#define RTL8367C_NIC_TXSTOPRL_OFFSET 0 ++#define RTL8367C_NIC_TXSTOPRL_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_TXSTOPRH 0x1a45 ++#define RTL8367C_NIC_TXSTOPRH_OFFSET 0 ++#define RTL8367C_NIC_TXSTOPRH_MASK 0x3 ++ ++#define RTL8367C_REG_NIC_RXSTOPRL 0x1a46 ++#define RTL8367C_NIC_RXSTOPRL_OFFSET 0 ++#define RTL8367C_NIC_RXSTOPRL_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_RXSTOPRH 0x1a47 ++#define RTL8367C_NIC_RXSTOPRH_OFFSET 0 ++#define RTL8367C_NIC_RXSTOPRH_MASK 0x3 ++ ++#define RTL8367C_REG_NIC_RXFSTR 0x1a48 ++#define RTL8367C_NIC_RXFSTR_OFFSET 0 ++#define RTL8367C_NIC_RXFSTR_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_RXMBTRL 0x1a4c ++#define RTL8367C_NIC_RXMBTRL_OFFSET 0 ++#define RTL8367C_NIC_RXMBTRL_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_RXMBTRH 0x1a4d ++#define RTL8367C_NIC_RXMBTRH_OFFSET 0 ++#define RTL8367C_NIC_RXMBTRH_MASK 0x7F ++ ++#define RTL8367C_REG_NIC_RXMPTR 0x1a4e ++#define RTL8367C_NIC_RXMPTR_OFFSET 0 ++#define RTL8367C_NIC_RXMPTR_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_T0TR 0x1a4f ++#define RTL8367C_NIC_T0TR_OFFSET 0 ++#define RTL8367C_NIC_T0TR_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_CRXCPRL 0x1a50 ++#define RTL8367C_NIC_CRXCPRL_OFFSET 0 ++#define RTL8367C_NIC_CRXCPRL_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_CRXCPRH 0x1a51 ++#define RTL8367C_NIC_CRXCPRH_OFFSET 0 ++#define RTL8367C_NIC_CRXCPRH_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_CTXCPRL 0x1a52 ++#define RTL8367C_NIC_CTXCPRL_OFFSET 0 ++#define RTL8367C_NIC_CTXCPRL_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_CTXPCRH 0x1a53 ++#define RTL8367C_NIC_CTXPCRH_OFFSET 0 ++#define RTL8367C_NIC_CTXPCRH_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_SRXCURPKTRL 0x1a54 ++#define RTL8367C_NIC_SRXCURPKTRL_OFFSET 0 ++#define RTL8367C_NIC_SRXCURPKTRL_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_SRXCURPKTRH 0x1a55 ++#define RTL8367C_NIC_SRXCURPKTRH_OFFSET 0 ++#define RTL8367C_NIC_SRXCURPKTRH_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_STXCURPKTRL 0x1a56 ++#define RTL8367C_NIC_STXCURPKTRL_OFFSET 0 ++#define RTL8367C_NIC_STXCURPKTRL_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_STXCURPKTRH 0x1a57 ++#define RTL8367C_NIC_STXCURPKTRH_OFFSET 0 ++#define RTL8367C_NIC_STXCURPKTRH_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_STXPKTLENRL 0x1a58 ++#define RTL8367C_NIC_STXPKTLENRL_OFFSET 0 ++#define RTL8367C_NIC_STXPKTLENRL_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_STXPKTLENRH 0x1a59 ++#define RTL8367C_NIC_STXPKTLENRH_OFFSET 0 ++#define RTL8367C_NIC_STXPKTLENRH_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_STXCURUNITRL 0x1a5a ++#define RTL8367C_NIC_STXCURUNITRL_OFFSET 0 ++#define RTL8367C_NIC_STXCURUNITRL_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_STXCURUNITRH 0x1a5b ++#define RTL8367C_NIC_STXCURUNITRH_OFFSET 0 ++#define RTL8367C_NIC_STXCURUNITRH_MASK 0xFF ++ ++#define RTL8367C_REG_NIC_DROP_MODE 0x1a5c ++#define RTL8367C_NIC_RXDV_MODE_OFFSET 1 ++#define RTL8367C_NIC_RXDV_MODE_MASK 0x2 ++#define RTL8367C_NIC_DROP_MODE_OFFSET 0 ++#define RTL8367C_NIC_DROP_MODE_MASK 0x1 ++ ++/* (16'h1b00)LED */ ++ ++#define RTL8367C_REG_LED_SYS_CONFIG 0x1b00 ++#define RTL8367C_LED_SYS_CONFIG_DUMMY_15_OFFSET 15 ++#define RTL8367C_LED_SYS_CONFIG_DUMMY_15_MASK 0x8000 ++#define RTL8367C_LED_SERIAL_OUT_MODE_OFFSET 14 ++#define RTL8367C_LED_SERIAL_OUT_MODE_MASK 0x4000 ++#define RTL8367C_LED_EEE_LPI_MODE_OFFSET 13 ++#define RTL8367C_LED_EEE_LPI_MODE_MASK 0x2000 ++#define RTL8367C_LED_EEE_LPI_EN_OFFSET 12 ++#define RTL8367C_LED_EEE_LPI_EN_MASK 0x1000 ++#define RTL8367C_LED_EEE_LPI_10_OFFSET 11 ++#define RTL8367C_LED_EEE_LPI_10_MASK 0x800 ++#define RTL8367C_LED_EEE_CAP_10_OFFSET 10 ++#define RTL8367C_LED_EEE_CAP_10_MASK 0x400 ++#define RTL8367C_LED_LPI_SEL_OFFSET 8 ++#define RTL8367C_LED_LPI_SEL_MASK 0x300 ++#define RTL8367C_SERI_LED_ACT_LOW_OFFSET 7 ++#define RTL8367C_SERI_LED_ACT_LOW_MASK 0x80 ++#define RTL8367C_LED_POWERON_2_OFFSET 6 ++#define RTL8367C_LED_POWERON_2_MASK 0x40 ++#define RTL8367C_LED_POWERON_1_OFFSET 5 ++#define RTL8367C_LED_POWERON_1_MASK 0x20 ++#define RTL8367C_LED_POWERON_0_OFFSET 4 ++#define RTL8367C_LED_POWERON_0_MASK 0x10 ++#define RTL8367C_LED_IO_DISABLE_OFFSET 3 ++#define RTL8367C_LED_IO_DISABLE_MASK 0x8 ++#define RTL8367C_DUMMY_2_2_OFFSET 2 ++#define RTL8367C_DUMMY_2_2_MASK 0x4 ++#define RTL8367C_LED_SELECT_OFFSET 0 ++#define RTL8367C_LED_SELECT_MASK 0x3 ++ ++#define RTL8367C_REG_LED_SYS_CONFIG2 0x1b01 ++#define RTL8367C_LED_SYS_CONFIG2_DUMMY_OFFSET 2 ++#define RTL8367C_LED_SYS_CONFIG2_DUMMY_MASK 0xFFFC ++#define RTL8367C_GATE_LPTD_BYPASS_OFFSET 1 ++#define RTL8367C_GATE_LPTD_BYPASS_MASK 0x2 ++#define RTL8367C_LED_SPD_MODE_OFFSET 0 ++#define RTL8367C_LED_SPD_MODE_MASK 0x1 ++ ++#define RTL8367C_REG_LED_MODE 0x1b02 ++#define RTL8367C_DLINK_TIME_OFFSET 15 ++#define RTL8367C_DLINK_TIME_MASK 0x8000 ++#define RTL8367C_LED_BUZZ_DUTY_OFFSET 14 ++#define RTL8367C_LED_BUZZ_DUTY_MASK 0x4000 ++#define RTL8367C_BUZZER_RATE_OFFSET 12 ++#define RTL8367C_BUZZER_RATE_MASK 0x3000 ++#define RTL8367C_LOOP_DETECT_MODE_OFFSET 11 ++#define RTL8367C_LOOP_DETECT_MODE_MASK 0x800 ++#define RTL8367C_SEL_PWRON_TIME_OFFSET 9 ++#define RTL8367C_SEL_PWRON_TIME_MASK 0x600 ++#define RTL8367C_EN_DLINK_LED_OFFSET 8 ++#define RTL8367C_EN_DLINK_LED_MASK 0x100 ++#define RTL8367C_LOOP_DETECT_RATE_OFFSET 6 ++#define RTL8367C_LOOP_DETECT_RATE_MASK 0xC0 ++#define RTL8367C_FORCE_RATE_OFFSET 4 ++#define RTL8367C_FORCE_RATE_MASK 0x30 ++#define RTL8367C_SEL_LEDRATE_OFFSET 1 ++#define RTL8367C_SEL_LEDRATE_MASK 0xE ++#define RTL8367C_SPEED_UP_OFFSET 0 ++#define RTL8367C_SPEED_UP_MASK 0x1 ++ ++#define RTL8367C_REG_LED_CONFIGURATION 0x1b03 ++#define RTL8367C_LED_CONFIGURATION_DUMMY_OFFSET 15 ++#define RTL8367C_LED_CONFIGURATION_DUMMY_MASK 0x8000 ++#define RTL8367C_LED_CONFIG_SEL_OFFSET 14 ++#define RTL8367C_LED_CONFIG_SEL_MASK 0x4000 ++#define RTL8367C_DATA_LED_OFFSET 12 ++#define RTL8367C_DATA_LED_MASK 0x3000 ++#define RTL8367C_LED2_CFG_OFFSET 8 ++#define RTL8367C_LED2_CFG_MASK 0xF00 ++#define RTL8367C_LED1_CFG_OFFSET 4 ++#define RTL8367C_LED1_CFG_MASK 0xF0 ++#define RTL8367C_LED0_CFG_OFFSET 0 ++#define RTL8367C_LED0_CFG_MASK 0xF ++ ++#define RTL8367C_REG_RTCT_RESULTS_CFG 0x1b04 ++#define RTL8367C_RTCT_2PAIR_FTT_OFFSET 15 ++#define RTL8367C_RTCT_2PAIR_FTT_MASK 0x8000 ++#define RTL8367C_RTCT_2PAIR_MODE_OFFSET 14 ++#define RTL8367C_RTCT_2PAIR_MODE_MASK 0x4000 ++#define RTL8367C_BLINK_EN_OFFSET 13 ++#define RTL8367C_BLINK_EN_MASK 0x2000 ++#define RTL8367C_TIMEOUT_OFFSET 12 ++#define RTL8367C_TIMEOUT_MASK 0x1000 ++#define RTL8367C_EN_CD_SAME_SHORT_OFFSET 11 ++#define RTL8367C_EN_CD_SAME_SHORT_MASK 0x800 ++#define RTL8367C_EN_CD_SAME_OPEN_OFFSET 10 ++#define RTL8367C_EN_CD_SAME_OPEN_MASK 0x400 ++#define RTL8367C_EN_CD_SAME_LINEDRIVER_OFFSET 9 ++#define RTL8367C_EN_CD_SAME_LINEDRIVER_MASK 0x200 ++#define RTL8367C_EN_CD_SAME_MISMATCH_OFFSET 8 ++#define RTL8367C_EN_CD_SAME_MISMATCH_MASK 0x100 ++#define RTL8367C_EN_CD_SHORT_OFFSET 7 ++#define RTL8367C_EN_CD_SHORT_MASK 0x80 ++#define RTL8367C_EN_AB_SHORT_OFFSET 6 ++#define RTL8367C_EN_AB_SHORT_MASK 0x40 ++#define RTL8367C_EN_CD_OPEN_OFFSET 5 ++#define RTL8367C_EN_CD_OPEN_MASK 0x20 ++#define RTL8367C_EN_AB_OPEN_OFFSET 4 ++#define RTL8367C_EN_AB_OPEN_MASK 0x10 ++#define RTL8367C_EN_CD_MISMATCH_OFFSET 3 ++#define RTL8367C_EN_CD_MISMATCH_MASK 0x8 ++#define RTL8367C_EN_AB_MISMATCH_OFFSET 2 ++#define RTL8367C_EN_AB_MISMATCH_MASK 0x4 ++#define RTL8367C_EN_CD_LINEDRIVER_OFFSET 1 ++#define RTL8367C_EN_CD_LINEDRIVER_MASK 0x2 ++#define RTL8367C_EN_AB_LINEDRIVER_OFFSET 0 ++#define RTL8367C_EN_AB_LINEDRIVER_MASK 0x1 ++ ++#define RTL8367C_REG_RTCT_LED 0x1b05 ++#define RTL8367C_DUMMY_1b05a_OFFSET 12 ++#define RTL8367C_DUMMY_1b05a_MASK 0xF000 ++#define RTL8367C_RTCT_LED2_OFFSET 8 ++#define RTL8367C_RTCT_LED2_MASK 0xF00 ++#define RTL8367C_RTCT_LED1_OFFSET 4 ++#define RTL8367C_RTCT_LED1_MASK 0xF0 ++#define RTL8367C_RTCT_LED0_OFFSET 0 ++#define RTL8367C_RTCT_LED0_MASK 0xF ++ ++#define RTL8367C_REG_CPU_FORCE_LED_CFG 0x1b07 ++#define RTL8367C_DUMMY_1b07a_OFFSET 8 ++#define RTL8367C_DUMMY_1b07a_MASK 0xFF00 ++#define RTL8367C_LED_FORCE_MODE_OFFSET 2 ++#define RTL8367C_LED_FORCE_MODE_MASK 0xFC ++#define RTL8367C_FORCE_MODE_OFFSET 0 ++#define RTL8367C_FORCE_MODE_MASK 0x3 ++ ++#define RTL8367C_REG_CPU_FORCE_LED0_CFG0 0x1b08 ++#define RTL8367C_PORT7_LED0_MODE_OFFSET 14 ++#define RTL8367C_PORT7_LED0_MODE_MASK 0xC000 ++#define RTL8367C_PORT6_LED0_MODE_OFFSET 12 ++#define RTL8367C_PORT6_LED0_MODE_MASK 0x3000 ++#define RTL8367C_PORT5_LED0_MODE_OFFSET 10 ++#define RTL8367C_PORT5_LED0_MODE_MASK 0xC00 ++#define RTL8367C_PORT4_LED0_MODE_OFFSET 8 ++#define RTL8367C_PORT4_LED0_MODE_MASK 0x300 ++#define RTL8367C_PORT3_LED0_MODE_OFFSET 6 ++#define RTL8367C_PORT3_LED0_MODE_MASK 0xC0 ++#define RTL8367C_PORT2_LED0_MODE_OFFSET 4 ++#define RTL8367C_PORT2_LED0_MODE_MASK 0x30 ++#define RTL8367C_PORT1_LED0_MODE_OFFSET 2 ++#define RTL8367C_PORT1_LED0_MODE_MASK 0xC ++#define RTL8367C_PORT0_LED0_MODE_OFFSET 0 ++#define RTL8367C_PORT0_LED0_MODE_MASK 0x3 ++ ++#define RTL8367C_REG_CPU_FORCE_LED0_CFG1 0x1b09 ++#define RTL8367C_DUMMY_1b09a_OFFSET 4 ++#define RTL8367C_DUMMY_1b09a_MASK 0xFFF0 ++#define RTL8367C_PORT9_LED0_MODE_OFFSET 2 ++#define RTL8367C_PORT9_LED0_MODE_MASK 0xC ++#define RTL8367C_PORT8_LED0_MODE_OFFSET 0 ++#define RTL8367C_PORT8_LED0_MODE_MASK 0x3 ++ ++#define RTL8367C_REG_CPU_FORCE_LED1_CFG0 0x1b0a ++#define RTL8367C_PORT7_LED1_MODE_OFFSET 14 ++#define RTL8367C_PORT7_LED1_MODE_MASK 0xC000 ++#define RTL8367C_PORT6_LED1_MODE_OFFSET 12 ++#define RTL8367C_PORT6_LED1_MODE_MASK 0x3000 ++#define RTL8367C_PORT5_LED1_MODE_OFFSET 10 ++#define RTL8367C_PORT5_LED1_MODE_MASK 0xC00 ++#define RTL8367C_PORT4_LED1_MODE_OFFSET 8 ++#define RTL8367C_PORT4_LED1_MODE_MASK 0x300 ++#define RTL8367C_PORT3_LED1_MODE_OFFSET 6 ++#define RTL8367C_PORT3_LED1_MODE_MASK 0xC0 ++#define RTL8367C_PORT2_LED1_MODE_OFFSET 4 ++#define RTL8367C_PORT2_LED1_MODE_MASK 0x30 ++#define RTL8367C_PORT1_LED1_MODE_OFFSET 2 ++#define RTL8367C_PORT1_LED1_MODE_MASK 0xC ++#define RTL8367C_PORT0_LED1_MODE_OFFSET 0 ++#define RTL8367C_PORT0_LED1_MODE_MASK 0x3 ++ ++#define RTL8367C_REG_CPU_FORCE_LED1_CFG1 0x1b0b ++#define RTL8367C_DUMMY_1b0ba_OFFSET 4 ++#define RTL8367C_DUMMY_1b0ba_MASK 0xFFF0 ++#define RTL8367C_PORT9_LED1_MODE_OFFSET 2 ++#define RTL8367C_PORT9_LED1_MODE_MASK 0xC ++#define RTL8367C_PORT8_LED1_MODE_OFFSET 0 ++#define RTL8367C_PORT8_LED1_MODE_MASK 0x3 ++ ++#define RTL8367C_REG_CPU_FORCE_LED2_CFG0 0x1b0c ++#define RTL8367C_PORT7_LED2_MODE_OFFSET 14 ++#define RTL8367C_PORT7_LED2_MODE_MASK 0xC000 ++#define RTL8367C_PORT6_LED2_MODE_OFFSET 12 ++#define RTL8367C_PORT6_LED2_MODE_MASK 0x3000 ++#define RTL8367C_PORT5_LED2_MODE_OFFSET 10 ++#define RTL8367C_PORT5_LED2_MODE_MASK 0xC00 ++#define RTL8367C_PORT4_LED2_MODE_OFFSET 8 ++#define RTL8367C_PORT4_LED2_MODE_MASK 0x300 ++#define RTL8367C_PORT3_LED2_MODE_OFFSET 6 ++#define RTL8367C_PORT3_LED2_MODE_MASK 0xC0 ++#define RTL8367C_PORT2_LED2_MODE_OFFSET 4 ++#define RTL8367C_PORT2_LED2_MODE_MASK 0x30 ++#define RTL8367C_PORT1_LED2_MODE_OFFSET 2 ++#define RTL8367C_PORT1_LED2_MODE_MASK 0xC ++#define RTL8367C_PORT0_LED2_MODE_OFFSET 0 ++#define RTL8367C_PORT0_LED2_MODE_MASK 0x3 ++ ++#define RTL8367C_REG_CPU_FORCE_LED2_CFG1 0x1b0d ++#define RTL8367C_DUMMY_1b0da_OFFSET 4 ++#define RTL8367C_DUMMY_1b0da_MASK 0xFFF0 ++#define RTL8367C_PORT9_LED2_MODE_OFFSET 2 ++#define RTL8367C_PORT9_LED2_MODE_MASK 0xC ++#define RTL8367C_PORT8_LED2_MODE_OFFSET 0 ++#define RTL8367C_PORT8_LED2_MODE_MASK 0x3 ++ ++#define RTL8367C_REG_LED_ACTIVE_LOW_CFG0 0x1b0e ++#define RTL8367C_LED_ACTIVE_LOW_CFG0_DUMMY_15_OFFSET 15 ++#define RTL8367C_LED_ACTIVE_LOW_CFG0_DUMMY_15_MASK 0x8000 ++#define RTL8367C_PORT3_LED_ACTIVE_LOW_OFFSET 12 ++#define RTL8367C_PORT3_LED_ACTIVE_LOW_MASK 0x7000 ++#define RTL8367C_LED_ACTIVE_LOW_CFG0_DUMMY_11_OFFSET 11 ++#define RTL8367C_LED_ACTIVE_LOW_CFG0_DUMMY_11_MASK 0x800 ++#define RTL8367C_PORT2_LED_ACTIVE_LOW_OFFSET 8 ++#define RTL8367C_PORT2_LED_ACTIVE_LOW_MASK 0x700 ++#define RTL8367C_DUMMY_7_OFFSET 7 ++#define RTL8367C_DUMMY_7_MASK 0x80 ++#define RTL8367C_PORT1_LED_ACTIVE_LOW_OFFSET 4 ++#define RTL8367C_PORT1_LED_ACTIVE_LOW_MASK 0x70 ++#define RTL8367C_DUMMY_3_OFFSET 3 ++#define RTL8367C_DUMMY_3_MASK 0x8 ++#define RTL8367C_PORT0_LED_ACTIVE_LOW_OFFSET 0 ++#define RTL8367C_PORT0_LED_ACTIVE_LOW_MASK 0x7 ++ ++#define RTL8367C_REG_LED_ACTIVE_LOW_CFG1 0x1b0f ++#define RTL8367C_LED_ACTIVE_LOW_CFG1_DUMMY_15_OFFSET 15 ++#define RTL8367C_LED_ACTIVE_LOW_CFG1_DUMMY_15_MASK 0x8000 ++#define RTL8367C_PORT7_LED_ACTIVE_LOW_OFFSET 12 ++#define RTL8367C_PORT7_LED_ACTIVE_LOW_MASK 0x7000 ++#define RTL8367C_LED_ACTIVE_LOW_CFG1_DUMMY_11_OFFSET 11 ++#define RTL8367C_LED_ACTIVE_LOW_CFG1_DUMMY_11_MASK 0x800 ++#define RTL8367C_PORT6_LED_ACTIVE_LOW_OFFSET 8 ++#define RTL8367C_PORT6_LED_ACTIVE_LOW_MASK 0x700 ++#define RTL8367C_DUMMY_1b0f_b_OFFSET 7 ++#define RTL8367C_DUMMY_1b0f_b_MASK 0x80 ++#define RTL8367C_PORT5_LED_ACTIVE_LOW_OFFSET 4 ++#define RTL8367C_PORT5_LED_ACTIVE_LOW_MASK 0x70 ++#define RTL8367C_DUMMY_1b0f_a_OFFSET 3 ++#define RTL8367C_DUMMY_1b0f_a_MASK 0x8 ++#define RTL8367C_PORT4_LED_ACTIVE_LOW_OFFSET 0 ++#define RTL8367C_PORT4_LED_ACTIVE_LOW_MASK 0x7 ++ ++#define RTL8367C_REG_LED_ACTIVE_LOW_CFG2 0x1b10 ++#define RTL8367C_DUMMY_1b10_b_OFFSET 7 ++#define RTL8367C_DUMMY_1b10_b_MASK 0xFF80 ++#define RTL8367C_PORT9_LED_ACTIVE_LOW_OFFSET 4 ++#define RTL8367C_PORT9_LED_ACTIVE_LOW_MASK 0x70 ++#define RTL8367C_DUMMY_1b10_a_OFFSET 3 ++#define RTL8367C_DUMMY_1b10_a_MASK 0x8 ++#define RTL8367C_PORT8_LED_ACTIVE_LOW_OFFSET 0 ++#define RTL8367C_PORT8_LED_ACTIVE_LOW_MASK 0x7 ++ ++#define RTL8367C_REG_SEL_RTCT_PARA 0x1b21 ++#define RTL8367C_DO_RTCT_COMMAND_OFFSET 15 ++#define RTL8367C_DO_RTCT_COMMAND_MASK 0x8000 ++#define RTL8367C_SEL_RTCT_PARA_DUMMY_OFFSET 12 ++#define RTL8367C_SEL_RTCT_PARA_DUMMY_MASK 0x7000 ++#define RTL8367C_SEL_RTCT_RLSTLED_TIME_OFFSET 10 ++#define RTL8367C_SEL_RTCT_RLSTLED_TIME_MASK 0xC00 ++#define RTL8367C_SEL_RTCT_TEST_LED_TIME_OFFSET 8 ++#define RTL8367C_SEL_RTCT_TEST_LED_TIME_MASK 0x300 ++#define RTL8367C_EN_SCAN_RTCT_OFFSET 7 ++#define RTL8367C_EN_SCAN_RTCT_MASK 0x80 ++#define RTL8367C_EN_RTCT_TIMOUT_OFFSET 6 ++#define RTL8367C_EN_RTCT_TIMOUT_MASK 0x40 ++#define RTL8367C_EN_ALL_RTCT_OFFSET 5 ++#define RTL8367C_EN_ALL_RTCT_MASK 0x20 ++#define RTL8367C_SEL_RTCT_PLE_WID_OFFSET 0 ++#define RTL8367C_SEL_RTCT_PLE_WID_MASK 0x1F ++ ++#define RTL8367C_REG_RTCT_ENABLE 0x1b22 ++#define RTL8367C_RTCT_ENABLE_DUMMY_OFFSET 8 ++#define RTL8367C_RTCT_ENABLE_DUMMY_MASK 0xFF00 ++#define RTL8367C_RTCT_ENABLE_PORT_MASK_OFFSET 0 ++#define RTL8367C_RTCT_ENABLE_PORT_MASK_MASK 0xFF ++ ++#define RTL8367C_REG_RTCT_TIMEOUT 0x1b23 ++ ++#define RTL8367C_REG_PARA_LED_IO_EN1 0x1b24 ++#define RTL8367C_LED1_PARA_P07_00_OFFSET 8 ++#define RTL8367C_LED1_PARA_P07_00_MASK 0xFF00 ++#define RTL8367C_LED0_PARA_P07_00_OFFSET 0 ++#define RTL8367C_LED0_PARA_P07_00_MASK 0xFF ++ ++#define RTL8367C_REG_PARA_LED_IO_EN2 0x1b25 ++#define RTL8367C_DUMMY_15_8_OFFSET 8 ++#define RTL8367C_DUMMY_15_8_MASK 0xFF00 ++#define RTL8367C_LED2_PARA_P07_00_OFFSET 0 ++#define RTL8367C_LED2_PARA_P07_00_MASK 0xFF ++ ++#define RTL8367C_REG_SCAN0_LED_IO_EN1 0x1b26 ++#define RTL8367C_SCAN0_LED_IO_EN1_DUMMY_OFFSET 3 ++#define RTL8367C_SCAN0_LED_IO_EN1_DUMMY_MASK 0xFFF8 ++#define RTL8367C_LED_LOOP_DET_BUZZER_EN_OFFSET 2 ++#define RTL8367C_LED_LOOP_DET_BUZZER_EN_MASK 0x4 ++#define RTL8367C_LED_SERI_DATA_EN_OFFSET 1 ++#define RTL8367C_LED_SERI_DATA_EN_MASK 0x2 ++#define RTL8367C_LED_SERI_CLK_EN_OFFSET 0 ++#define RTL8367C_LED_SERI_CLK_EN_MASK 0x1 ++ ++#define RTL8367C_REG_SCAN1_LED_IO_EN2 0x1b27 ++#define RTL8367C_LED_SCAN1_BI_PORT_EN_OFFSET 8 ++#define RTL8367C_LED_SCAN1_BI_PORT_EN_MASK 0xFF00 ++#define RTL8367C_LED_SCAN1_BI_STA_EN_OFFSET 7 ++#define RTL8367C_LED_SCAN1_BI_STA_EN_MASK 0x80 ++#define RTL8367C_SCAN1_LED_IO_EN2_DUMMY_0_OFFSET 6 ++#define RTL8367C_SCAN1_LED_IO_EN2_DUMMY_0_MASK 0x40 ++#define RTL8367C_LED_SCAN1_SI_PORT_EN_OFFSET 2 ++#define RTL8367C_LED_SCAN1_SI_PORT_EN_MASK 0x3C ++#define RTL8367C_LED_SCAN1_SI_STA_EN_OFFSET 0 ++#define RTL8367C_LED_SCAN1_SI_STA_EN_MASK 0x3 ++ ++#define RTL8367C_REG_LPI_LED_OPT1 0x1b28 ++#define RTL8367C_LPI_TAG4_OFFSET 12 ++#define RTL8367C_LPI_TAG4_MASK 0xF000 ++#define RTL8367C_LPI_TAG3_OFFSET 8 ++#define RTL8367C_LPI_TAG3_MASK 0xF00 ++#define RTL8367C_LPI_TAG2_OFFSET 4 ++#define RTL8367C_LPI_TAG2_MASK 0xF0 ++#define RTL8367C_LPI_TAG1_OFFSET 0 ++#define RTL8367C_LPI_TAG1_MASK 0xF ++ ++#define RTL8367C_REG_LPI_LED_OPT2 0x1b29 ++#define RTL8367C_LPI_LED_OPT2_DUMMY_OFFSET 15 ++#define RTL8367C_LPI_LED_OPT2_DUMMY_MASK 0x8000 ++#define RTL8367C_LPI_LED2_WEAK_OFFSET 14 ++#define RTL8367C_LPI_LED2_WEAK_MASK 0x4000 ++#define RTL8367C_LPI_LED1_WEAK_OFFSET 13 ++#define RTL8367C_LPI_LED1_WEAK_MASK 0x2000 ++#define RTL8367C_LPI_LED0_WEAK_OFFSET 12 ++#define RTL8367C_LPI_LED0_WEAK_MASK 0x1000 ++#define RTL8367C_LPI_LED2_OFFSET 11 ++#define RTL8367C_LPI_LED2_MASK 0x800 ++#define RTL8367C_LPI_LED1_OFFSET 10 ++#define RTL8367C_LPI_LED1_MASK 0x400 ++#define RTL8367C_LPI_LED0_OFFSET 9 ++#define RTL8367C_LPI_LED0_MASK 0x200 ++#define RTL8367C_LPI_TAG8_OFFSET 8 ++#define RTL8367C_LPI_TAG8_MASK 0x100 ++#define RTL8367C_LPI_TAG7_OFFSET 6 ++#define RTL8367C_LPI_TAG7_MASK 0xC0 ++#define RTL8367C_LPI_TAG6_OFFSET 4 ++#define RTL8367C_LPI_TAG6_MASK 0x30 ++#define RTL8367C_LPI_TAG5_OFFSET 0 ++#define RTL8367C_LPI_TAG5_MASK 0xF ++ ++#define RTL8367C_REG_LPI_LED_OPT3 0x1b2a ++#define RTL8367C_LPI_LED_OPT3_DUMMY_OFFSET 3 ++#define RTL8367C_LPI_LED_OPT3_DUMMY_MASK 0xFFF8 ++#define RTL8367C_RESTORE_LED_RATE_SEL_OFFSET 1 ++#define RTL8367C_RESTORE_LED_RATE_SEL_MASK 0x6 ++#define RTL8367C_RESTORE_LED_SEL_OFFSET 0 ++#define RTL8367C_RESTORE_LED_SEL_MASK 0x1 ++ ++#define RTL8367C_REG_P0_LED_MUX 0x1b2b ++#define RTL8367C_CFG_P0_LED2_MUX_OFFSET 10 ++#define RTL8367C_CFG_P0_LED2_MUX_MASK 0x7C00 ++#define RTL8367C_CFG_P0_LED1_MUX_OFFSET 5 ++#define RTL8367C_CFG_P0_LED1_MUX_MASK 0x3E0 ++#define RTL8367C_CFG_P0_LED0_MUX_OFFSET 0 ++#define RTL8367C_CFG_P0_LED0_MUX_MASK 0x1F ++ ++#define RTL8367C_REG_P1_LED_MUX 0x1b2c ++#define RTL8367C_CFG_P1_LED2_MUX_OFFSET 10 ++#define RTL8367C_CFG_P1_LED2_MUX_MASK 0x7C00 ++#define RTL8367C_CFG_P1_LED1_MUX_OFFSET 5 ++#define RTL8367C_CFG_P1_LED1_MUX_MASK 0x3E0 ++#define RTL8367C_CFG_P1_LED0_MUX_OFFSET 0 ++#define RTL8367C_CFG_P1_LED0_MUX_MASK 0x1F ++ ++#define RTL8367C_REG_P2_LED_MUX 0x1b2d ++#define RTL8367C_CFG_P2_LED2_MUX_OFFSET 10 ++#define RTL8367C_CFG_P2_LED2_MUX_MASK 0x7C00 ++#define RTL8367C_CFG_P2_LED1_MUX_OFFSET 5 ++#define RTL8367C_CFG_P2_LED1_MUX_MASK 0x3E0 ++#define RTL8367C_CFG_P2_LED0_MUX_OFFSET 0 ++#define RTL8367C_CFG_P2_LED0_MUX_MASK 0x1F ++ ++#define RTL8367C_REG_P3_LED_MUX 0x1b2e ++#define RTL8367C_CFG_P3_LED2_MUX_OFFSET 10 ++#define RTL8367C_CFG_P3_LED2_MUX_MASK 0x7C00 ++#define RTL8367C_CFG_P3_LED1_MUX_OFFSET 5 ++#define RTL8367C_CFG_P3_LED1_MUX_MASK 0x3E0 ++#define RTL8367C_CFG_P3_LED0_MUX_OFFSET 0 ++#define RTL8367C_CFG_P3_LED0_MUX_MASK 0x1F ++ ++#define RTL8367C_REG_P4_LED_MUX 0x1b2f ++#define RTL8367C_CFG_P4_LED2_MUX_OFFSET 10 ++#define RTL8367C_CFG_P4_LED2_MUX_MASK 0x7C00 ++#define RTL8367C_CFG_P4_LED1_MUX_OFFSET 5 ++#define RTL8367C_CFG_P4_LED1_MUX_MASK 0x3E0 ++#define RTL8367C_CFG_P4_LED0_MUX_OFFSET 0 ++#define RTL8367C_CFG_P4_LED0_MUX_MASK 0x1F ++ ++#define RTL8367C_REG_LED0_DATA_CTRL 0x1b30 ++#define RTL8367C_CFG_DATA_LED0_SEL_OFFSET 6 ++#define RTL8367C_CFG_DATA_LED0_SEL_MASK 0x40 ++#define RTL8367C_CFG_DATA_LED0_ACT_OFFSET 4 ++#define RTL8367C_CFG_DATA_LED0_ACT_MASK 0x30 ++#define RTL8367C_CFG_DATA_LED0_SPD_OFFSET 0 ++#define RTL8367C_CFG_DATA_LED0_SPD_MASK 0xF ++ ++#define RTL8367C_REG_LED1_DATA_CTRL 0x1b31 ++#define RTL8367C_CFG_DATA_LED1_SEL_OFFSET 6 ++#define RTL8367C_CFG_DATA_LED1_SEL_MASK 0x40 ++#define RTL8367C_CFG_DATA_LED1_ACT_OFFSET 4 ++#define RTL8367C_CFG_DATA_LED1_ACT_MASK 0x30 ++#define RTL8367C_CFG_DATA_LED1_SPD_OFFSET 0 ++#define RTL8367C_CFG_DATA_LED1_SPD_MASK 0xF ++ ++#define RTL8367C_REG_LED2_DATA_CTRL 0x1b32 ++#define RTL8367C_CFG_DATA_LED2_SEL_OFFSET 6 ++#define RTL8367C_CFG_DATA_LED2_SEL_MASK 0x40 ++#define RTL8367C_CFG_DATA_LED2_ACT_OFFSET 4 ++#define RTL8367C_CFG_DATA_LED2_ACT_MASK 0x30 ++#define RTL8367C_CFG_DATA_LED2_SPD_OFFSET 0 ++#define RTL8367C_CFG_DATA_LED2_SPD_MASK 0xF ++ ++#define RTL8367C_REG_PARA_LED_IO_EN3 0x1b33 ++#define RTL8367C_dummy_1b33a_OFFSET 6 ++#define RTL8367C_dummy_1b33a_MASK 0xFFC0 ++#define RTL8367C_LED2_PARA_P09_08_OFFSET 4 ++#define RTL8367C_LED2_PARA_P09_08_MASK 0x30 ++#define RTL8367C_LED1_PARA_P09_08_OFFSET 2 ++#define RTL8367C_LED1_PARA_P09_08_MASK 0xC ++#define RTL8367C_LED0_PARA_P09_08_OFFSET 0 ++#define RTL8367C_LED0_PARA_P09_08_MASK 0x3 ++ ++#define RTL8367C_REG_SCAN1_LED_IO_EN3 0x1b34 ++#define RTL8367C_dummy_1b34a_OFFSET 3 ++#define RTL8367C_dummy_1b34a_MASK 0xFFF8 ++#define RTL8367C_LED_SCAN1_BI_PORT9_8_EN_OFFSET 1 ++#define RTL8367C_LED_SCAN1_BI_PORT9_8_EN_MASK 0x6 ++#define RTL8367C_LED_SCAN1_SI_PORT9_8_EN_OFFSET 0 ++#define RTL8367C_LED_SCAN1_SI_PORT9_8_EN_MASK 0x1 ++ ++#define RTL8367C_REG_P5_LED_MUX 0x1b35 ++#define RTL8367C_CFG_P5_LED2_MUX_OFFSET 10 ++#define RTL8367C_CFG_P5_LED2_MUX_MASK 0x7C00 ++#define RTL8367C_CFG_P5_LED1_MUX_OFFSET 5 ++#define RTL8367C_CFG_P5_LED1_MUX_MASK 0x3E0 ++#define RTL8367C_CFG_P5_LED0_MUX_OFFSET 0 ++#define RTL8367C_CFG_P5_LED0_MUX_MASK 0x1F ++ ++#define RTL8367C_REG_P6_LED_MUX 0x1b36 ++#define RTL8367C_CFG_P6_LED2_MUX_OFFSET 10 ++#define RTL8367C_CFG_P6_LED2_MUX_MASK 0x7C00 ++#define RTL8367C_CFG_P6_LED1_MUX_OFFSET 5 ++#define RTL8367C_CFG_P6_LED1_MUX_MASK 0x3E0 ++#define RTL8367C_CFG_P6_LED0_MUX_OFFSET 0 ++#define RTL8367C_CFG_P6_LED0_MUX_MASK 0x1F ++ ++#define RTL8367C_REG_P7_LED_MUX 0x1b37 ++#define RTL8367C_CFG_P7_LED2_MUX_OFFSET 10 ++#define RTL8367C_CFG_P7_LED2_MUX_MASK 0x7C00 ++#define RTL8367C_CFG_P7_LED1_MUX_OFFSET 5 ++#define RTL8367C_CFG_P7_LED1_MUX_MASK 0x3E0 ++#define RTL8367C_CFG_P7_LED0_MUX_OFFSET 0 ++#define RTL8367C_CFG_P7_LED0_MUX_MASK 0x1F ++ ++#define RTL8367C_REG_P8_LED_MUX 0x1b38 ++#define RTL8367C_CFG_P8_LED2_MUX_OFFSET 10 ++#define RTL8367C_CFG_P8_LED2_MUX_MASK 0x7C00 ++#define RTL8367C_CFG_P8_LED1_MUX_OFFSET 5 ++#define RTL8367C_CFG_P8_LED1_MUX_MASK 0x3E0 ++#define RTL8367C_CFG_P8_LED0_MUX_OFFSET 0 ++#define RTL8367C_CFG_P8_LED0_MUX_MASK 0x1F ++ ++#define RTL8367C_REG_P9_LED_MUX 0x1b39 ++#define RTL8367C_CFG_P9_LED2_MUX_OFFSET 10 ++#define RTL8367C_CFG_P9_LED2_MUX_MASK 0x7C00 ++#define RTL8367C_CFG_P9_LED1_MUX_OFFSET 5 ++#define RTL8367C_CFG_P9_LED1_MUX_MASK 0x3E0 ++#define RTL8367C_CFG_P9_LED0_MUX_OFFSET 0 ++#define RTL8367C_CFG_P9_LED0_MUX_MASK 0x1F ++ ++#define RTL8367C_REG_SERIAL_LED_CTRL 0x1b3a ++#define RTL8367C_SERIAL_LED_SHIFT_SEQUENCE_OFFSET 13 ++#define RTL8367C_SERIAL_LED_SHIFT_SEQUENCE_MASK 0x6000 ++#define RTL8367C_SERIAL_LED_SHIFT_SEQUENCE_EN_OFFSET 12 ++#define RTL8367C_SERIAL_LED_SHIFT_SEQUENCE_EN_MASK 0x1000 ++#define RTL8367C_SERIAL_LED_GROUP_NUM_OFFSET 10 ++#define RTL8367C_SERIAL_LED_GROUP_NUM_MASK 0xC00 ++#define RTL8367C_SERIAL_LED_PORT_EN_OFFSET 0 ++#define RTL8367C_SERIAL_LED_PORT_EN_MASK 0x3FF ++ ++/* (16'h1c00)IGMP_EAV */ ++ ++#define RTL8367C_REG_IGMP_MLD_CFG0 0x1c00 ++#define RTL8367C_IGMP_MLD_PORTISO_LEAKY_OFFSET 15 ++#define RTL8367C_IGMP_MLD_PORTISO_LEAKY_MASK 0x8000 ++#define RTL8367C_IGMP_MLD_VLAN_LEAKY_OFFSET 14 ++#define RTL8367C_IGMP_MLD_VLAN_LEAKY_MASK 0x4000 ++#define RTL8367C_IGMP_MLD_DISCARD_STORM_FILTER_OFFSET 13 ++#define RTL8367C_IGMP_MLD_DISCARD_STORM_FILTER_MASK 0x2000 ++#define RTL8367C_REPORT_FORWARD_OFFSET 12 ++#define RTL8367C_REPORT_FORWARD_MASK 0x1000 ++#define RTL8367C_ROBURSTNESS_VAR_OFFSET 9 ++#define RTL8367C_ROBURSTNESS_VAR_MASK 0xE00 ++#define RTL8367C_LEAVE_SUPPRESSION_OFFSET 8 ++#define RTL8367C_LEAVE_SUPPRESSION_MASK 0x100 ++#define RTL8367C_REPORT_SUPPRESSION_OFFSET 7 ++#define RTL8367C_REPORT_SUPPRESSION_MASK 0x80 ++#define RTL8367C_LEAVE_TIMER_OFFSET 4 ++#define RTL8367C_LEAVE_TIMER_MASK 0x70 ++#define RTL8367C_FAST_LEAVE_EN_OFFSET 3 ++#define RTL8367C_FAST_LEAVE_EN_MASK 0x8 ++#define RTL8367C_CKS_ERR_OP_OFFSET 1 ++#define RTL8367C_CKS_ERR_OP_MASK 0x6 ++#define RTL8367C_IGMP_MLD_EN_OFFSET 0 ++#define RTL8367C_IGMP_MLD_EN_MASK 0x1 ++ ++#define RTL8367C_REG_IGMP_MLD_CFG1 0x1c01 ++#define RTL8367C_DROP_LEAVE_ZERO_OFFSET 2 ++#define RTL8367C_DROP_LEAVE_ZERO_MASK 0x4 ++#define RTL8367C_TABLE_FULL_OP_OFFSET 0 ++#define RTL8367C_TABLE_FULL_OP_MASK 0x3 ++ ++#define RTL8367C_REG_IGMP_MLD_CFG2 0x1c02 ++ ++#define RTL8367C_REG_IGMP_DYNAMIC_ROUTER_PORT 0x1c03 ++#define RTL8367C_D_ROUTER_PORT_2_OFFSET 11 ++#define RTL8367C_D_ROUTER_PORT_2_MASK 0x7800 ++#define RTL8367C_D_ROUTER_PORT_TMR_2_OFFSET 8 ++#define RTL8367C_D_ROUTER_PORT_TMR_2_MASK 0x700 ++#define RTL8367C_D_ROUTER_PORT_1_OFFSET 3 ++#define RTL8367C_D_ROUTER_PORT_1_MASK 0x78 ++#define RTL8367C_D_ROUTER_PORT_TMR_1_OFFSET 0 ++#define RTL8367C_D_ROUTER_PORT_TMR_1_MASK 0x7 ++ ++#define RTL8367C_REG_IGMP_STATIC_ROUTER_PORT 0x1c04 ++#define RTL8367C_IGMP_STATIC_ROUTER_PORT_OFFSET 0 ++#define RTL8367C_IGMP_STATIC_ROUTER_PORT_MASK 0x7FF ++ ++#define RTL8367C_REG_IGMP_PORT0_CONTROL 0x1c05 ++#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_OFFSET 14 ++#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_MASK 0x4000 ++#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_OFFSET 13 ++#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_MASK 0x2000 ++#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_OFFSET 12 ++#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_MASK 0x1000 ++#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_OFFSET 11 ++#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_MASK 0x800 ++#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_OFFSET 10 ++#define RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_MASK 0x400 ++#define RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_OFFSET 8 ++#define RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_MASK 0x300 ++#define RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_OFFSET 6 ++#define RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_MASK 0xC0 ++#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_OFFSET 4 ++#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_MASK 0x30 ++#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_OFFSET 2 ++#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_MASK 0xC ++#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_OFFSET 0 ++#define RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_MASK 0x3 ++ ++#define RTL8367C_REG_IGMP_PORT1_CONTROL 0x1c06 ++#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_QUERY_OFFSET 14 ++#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_QUERY_MASK 0x4000 ++#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_REPORT_OFFSET 13 ++#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_REPORT_MASK 0x2000 ++#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_LEAVE_OFFSET 12 ++#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_LEAVE_MASK 0x1000 ++#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_MRP_OFFSET 11 ++#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_MRP_MASK 0x800 ++#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_MC_DATA_OFFSET 10 ++#define RTL8367C_IGMP_PORT1_CONTROL_ALLOW_MC_DATA_MASK 0x400 ++#define RTL8367C_IGMP_PORT1_CONTROL_MLDv2_OP_OFFSET 8 ++#define RTL8367C_IGMP_PORT1_CONTROL_MLDv2_OP_MASK 0x300 ++#define RTL8367C_IGMP_PORT1_CONTROL_MLDv1_OP_OFFSET 6 ++#define RTL8367C_IGMP_PORT1_CONTROL_MLDv1_OP_MASK 0xC0 ++#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV3_OP_OFFSET 4 ++#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV3_OP_MASK 0x30 ++#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV2_OP_OFFSET 2 ++#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV2_OP_MASK 0xC ++#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV1_OP_OFFSET 0 ++#define RTL8367C_IGMP_PORT1_CONTROL_IGMPV1_OP_MASK 0x3 ++ ++#define RTL8367C_REG_IGMP_PORT2_CONTROL 0x1c07 ++#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_QUERY_OFFSET 14 ++#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_QUERY_MASK 0x4000 ++#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_REPORT_OFFSET 13 ++#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_REPORT_MASK 0x2000 ++#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_LEAVE_OFFSET 12 ++#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_LEAVE_MASK 0x1000 ++#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_MRP_OFFSET 11 ++#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_MRP_MASK 0x800 ++#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_MC_DATA_OFFSET 10 ++#define RTL8367C_IGMP_PORT2_CONTROL_ALLOW_MC_DATA_MASK 0x400 ++#define RTL8367C_IGMP_PORT2_CONTROL_MLDv2_OP_OFFSET 8 ++#define RTL8367C_IGMP_PORT2_CONTROL_MLDv2_OP_MASK 0x300 ++#define RTL8367C_IGMP_PORT2_CONTROL_MLDv1_OP_OFFSET 6 ++#define RTL8367C_IGMP_PORT2_CONTROL_MLDv1_OP_MASK 0xC0 ++#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV3_OP_OFFSET 4 ++#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV3_OP_MASK 0x30 ++#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV2_OP_OFFSET 2 ++#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV2_OP_MASK 0xC ++#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV1_OP_OFFSET 0 ++#define RTL8367C_IGMP_PORT2_CONTROL_IGMPV1_OP_MASK 0x3 ++ ++#define RTL8367C_REG_IGMP_PORT3_CONTROL 0x1c08 ++#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_QUERY_OFFSET 14 ++#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_QUERY_MASK 0x4000 ++#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_REPORT_OFFSET 13 ++#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_REPORT_MASK 0x2000 ++#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_LEAVE_OFFSET 12 ++#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_LEAVE_MASK 0x1000 ++#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_MRP_OFFSET 11 ++#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_MRP_MASK 0x800 ++#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_MC_DATA_OFFSET 10 ++#define RTL8367C_IGMP_PORT3_CONTROL_ALLOW_MC_DATA_MASK 0x400 ++#define RTL8367C_IGMP_PORT3_CONTROL_MLDv2_OP_OFFSET 8 ++#define RTL8367C_IGMP_PORT3_CONTROL_MLDv2_OP_MASK 0x300 ++#define RTL8367C_IGMP_PORT3_CONTROL_MLDv1_OP_OFFSET 6 ++#define RTL8367C_IGMP_PORT3_CONTROL_MLDv1_OP_MASK 0xC0 ++#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV3_OP_OFFSET 4 ++#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV3_OP_MASK 0x30 ++#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV2_OP_OFFSET 2 ++#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV2_OP_MASK 0xC ++#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV1_OP_OFFSET 0 ++#define RTL8367C_IGMP_PORT3_CONTROL_IGMPV1_OP_MASK 0x3 ++ ++#define RTL8367C_REG_IGMP_PORT4_CONTROL 0x1c09 ++#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_QUERY_OFFSET 14 ++#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_QUERY_MASK 0x4000 ++#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_REPORT_OFFSET 13 ++#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_REPORT_MASK 0x2000 ++#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_LEAVE_OFFSET 12 ++#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_LEAVE_MASK 0x1000 ++#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_MRP_OFFSET 11 ++#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_MRP_MASK 0x800 ++#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_MC_DATA_OFFSET 10 ++#define RTL8367C_IGMP_PORT4_CONTROL_ALLOW_MC_DATA_MASK 0x400 ++#define RTL8367C_IGMP_PORT4_CONTROL_MLDv2_OP_OFFSET 8 ++#define RTL8367C_IGMP_PORT4_CONTROL_MLDv2_OP_MASK 0x300 ++#define RTL8367C_IGMP_PORT4_CONTROL_MLDv1_OP_OFFSET 6 ++#define RTL8367C_IGMP_PORT4_CONTROL_MLDv1_OP_MASK 0xC0 ++#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV3_OP_OFFSET 4 ++#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV3_OP_MASK 0x30 ++#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV2_OP_OFFSET 2 ++#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV2_OP_MASK 0xC ++#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV1_OP_OFFSET 0 ++#define RTL8367C_IGMP_PORT4_CONTROL_IGMPV1_OP_MASK 0x3 ++ ++#define RTL8367C_REG_IGMP_PORT5_CONTROL 0x1c0a ++#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_QUERY_OFFSET 14 ++#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_QUERY_MASK 0x4000 ++#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_REPORT_OFFSET 13 ++#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_REPORT_MASK 0x2000 ++#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_LEAVE_OFFSET 12 ++#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_LEAVE_MASK 0x1000 ++#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_MRP_OFFSET 11 ++#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_MRP_MASK 0x800 ++#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_MC_DATA_OFFSET 10 ++#define RTL8367C_IGMP_PORT5_CONTROL_ALLOW_MC_DATA_MASK 0x400 ++#define RTL8367C_IGMP_PORT5_CONTROL_MLDv2_OP_OFFSET 8 ++#define RTL8367C_IGMP_PORT5_CONTROL_MLDv2_OP_MASK 0x300 ++#define RTL8367C_IGMP_PORT5_CONTROL_MLDv1_OP_OFFSET 6 ++#define RTL8367C_IGMP_PORT5_CONTROL_MLDv1_OP_MASK 0xC0 ++#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV3_OP_OFFSET 4 ++#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV3_OP_MASK 0x30 ++#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV2_OP_OFFSET 2 ++#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV2_OP_MASK 0xC ++#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV1_OP_OFFSET 0 ++#define RTL8367C_IGMP_PORT5_CONTROL_IGMPV1_OP_MASK 0x3 ++ ++#define RTL8367C_REG_IGMP_PORT6_CONTROL 0x1c0b ++#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_QUERY_OFFSET 14 ++#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_QUERY_MASK 0x4000 ++#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_REPORT_OFFSET 13 ++#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_REPORT_MASK 0x2000 ++#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_LEAVE_OFFSET 12 ++#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_LEAVE_MASK 0x1000 ++#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_MRP_OFFSET 11 ++#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_MRP_MASK 0x800 ++#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_MC_DATA_OFFSET 10 ++#define RTL8367C_IGMP_PORT6_CONTROL_ALLOW_MC_DATA_MASK 0x400 ++#define RTL8367C_IGMP_PORT6_CONTROL_MLDv2_OP_OFFSET 8 ++#define RTL8367C_IGMP_PORT6_CONTROL_MLDv2_OP_MASK 0x300 ++#define RTL8367C_IGMP_PORT6_CONTROL_MLDv1_OP_OFFSET 6 ++#define RTL8367C_IGMP_PORT6_CONTROL_MLDv1_OP_MASK 0xC0 ++#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV3_OP_OFFSET 4 ++#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV3_OP_MASK 0x30 ++#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV2_OP_OFFSET 2 ++#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV2_OP_MASK 0xC ++#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV1_OP_OFFSET 0 ++#define RTL8367C_IGMP_PORT6_CONTROL_IGMPV1_OP_MASK 0x3 ++ ++#define RTL8367C_REG_IGMP_PORT7_CONTROL 0x1c0c ++#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_QUERY_OFFSET 14 ++#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_QUERY_MASK 0x4000 ++#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_REPORT_OFFSET 13 ++#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_REPORT_MASK 0x2000 ++#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_LEAVE_OFFSET 12 ++#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_LEAVE_MASK 0x1000 ++#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_MRP_OFFSET 11 ++#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_MRP_MASK 0x800 ++#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_MC_DATA_OFFSET 10 ++#define RTL8367C_IGMP_PORT7_CONTROL_ALLOW_MC_DATA_MASK 0x400 ++#define RTL8367C_IGMP_PORT7_CONTROL_MLDv2_OP_OFFSET 8 ++#define RTL8367C_IGMP_PORT7_CONTROL_MLDv2_OP_MASK 0x300 ++#define RTL8367C_IGMP_PORT7_CONTROL_MLDv1_OP_OFFSET 6 ++#define RTL8367C_IGMP_PORT7_CONTROL_MLDv1_OP_MASK 0xC0 ++#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV3_OP_OFFSET 4 ++#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV3_OP_MASK 0x30 ++#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV2_OP_OFFSET 2 ++#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV2_OP_MASK 0xC ++#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV1_OP_OFFSET 0 ++#define RTL8367C_IGMP_PORT7_CONTROL_IGMPV1_OP_MASK 0x3 ++ ++#define RTL8367C_REG_IGMP_PORT01_MAX_GROUP 0x1c0d ++#define RTL8367C_PORT1_MAX_GROUP_OFFSET 8 ++#define RTL8367C_PORT1_MAX_GROUP_MASK 0xFF00 ++#define RTL8367C_PORT0_MAX_GROUP_OFFSET 0 ++#define RTL8367C_PORT0_MAX_GROUP_MASK 0xFF ++ ++#define RTL8367C_REG_IGMP_PORT23_MAX_GROUP 0x1c0e ++#define RTL8367C_PORT3_MAX_GROUP_OFFSET 8 ++#define RTL8367C_PORT3_MAX_GROUP_MASK 0xFF00 ++#define RTL8367C_PORT2_MAX_GROUP_OFFSET 0 ++#define RTL8367C_PORT2_MAX_GROUP_MASK 0xFF ++ ++#define RTL8367C_REG_IGMP_PORT45_MAX_GROUP 0x1c0f ++#define RTL8367C_PORT5_MAX_GROUP_OFFSET 8 ++#define RTL8367C_PORT5_MAX_GROUP_MASK 0xFF00 ++#define RTL8367C_PORT4_MAX_GROUP_OFFSET 0 ++#define RTL8367C_PORT4_MAX_GROUP_MASK 0xFF ++ ++#define RTL8367C_REG_IGMP_PORT67_MAX_GROUP 0x1c10 ++#define RTL8367C_PORT7_MAX_GROUP_OFFSET 8 ++#define RTL8367C_PORT7_MAX_GROUP_MASK 0xFF00 ++#define RTL8367C_PORT6_MAX_GROUP_OFFSET 0 ++#define RTL8367C_PORT6_MAX_GROUP_MASK 0xFF ++ ++#define RTL8367C_REG_IGMP_PORT01_CURRENT_GROUP 0x1c11 ++#define RTL8367C_PORT1_CURRENT_GROUP_OFFSET 8 ++#define RTL8367C_PORT1_CURRENT_GROUP_MASK 0xFF00 ++#define RTL8367C_PORT0_CURRENT_GROUP_OFFSET 0 ++#define RTL8367C_PORT0_CURRENT_GROUP_MASK 0xFF ++ ++#define RTL8367C_REG_IGMP_PORT23_CURRENT_GROUP 0x1c12 ++#define RTL8367C_PORT3_CURRENT_GROUP_OFFSET 8 ++#define RTL8367C_PORT3_CURRENT_GROUP_MASK 0xFF00 ++#define RTL8367C_PORT2_CURRENT_GROUP_OFFSET 0 ++#define RTL8367C_PORT2_CURRENT_GROUP_MASK 0xFF ++ ++#define RTL8367C_REG_IGMP_PORT45_CURRENT_GROUP 0x1c13 ++#define RTL8367C_PORT5_CURRENT_GROUP_OFFSET 8 ++#define RTL8367C_PORT5_CURRENT_GROUP_MASK 0xFF00 ++#define RTL8367C_PORT4_CURRENT_GROUP_OFFSET 0 ++#define RTL8367C_PORT4_CURRENT_GROUP_MASK 0xFF ++ ++#define RTL8367C_REG_IGMP_PORT67_CURRENT_GROUP 0x1c14 ++#define RTL8367C_PORT7_CURRENT_GROUP_OFFSET 8 ++#define RTL8367C_PORT7_CURRENT_GROUP_MASK 0xFF00 ++#define RTL8367C_PORT6_CURRENT_GROUP_OFFSET 0 ++#define RTL8367C_PORT6_CURRENT_GROUP_MASK 0xFF ++ ++#define RTL8367C_REG_IGMP_MLD_CFG3 0x1c15 ++#define RTL8367C_IGMP_MLD_IP6_BYPASS_OFFSET 5 ++#define RTL8367C_IGMP_MLD_IP6_BYPASS_MASK 0x20 ++#define RTL8367C_IGMP_MLD_IP4_BYPASS_239_255_255_OFFSET 4 ++#define RTL8367C_IGMP_MLD_IP4_BYPASS_239_255_255_MASK 0x10 ++#define RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_1_OFFSET 3 ++#define RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_1_MASK 0x8 ++#define RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_0_OFFSET 2 ++#define RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_0_MASK 0x4 ++#define RTL8367C_REPORT_LEAVE_FORWARD_OFFSET 0 ++#define RTL8367C_REPORT_LEAVE_FORWARD_MASK 0x3 ++ ++#define RTL8367C_REG_IGMP_MLD_CFG4 0x1c16 ++#define RTL8367C_IGMP_MLD_CFG4_OFFSET 0 ++#define RTL8367C_IGMP_MLD_CFG4_MASK 0x7FF ++ ++#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST0 0x1c20 ++ ++#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST1 0x1c21 ++ ++#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST2 0x1c22 ++ ++#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST3 0x1c23 ++ ++#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST4 0x1c24 ++ ++#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST5 0x1c25 ++ ++#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST6 0x1c26 ++ ++#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST7 0x1c27 ++ ++#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST8 0x1c28 ++ ++#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST9 0x1c29 ++ ++#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST10 0x1c2a ++ ++#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST11 0x1c2b ++ ++#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST12 0x1c2c ++ ++#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST13 0x1c2d ++ ++#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST14 0x1c2e ++ ++#define RTL8367C_REG_IGMP_GROUP_USAGE_LIST15 0x1c2f ++ ++#define RTL8367C_REG_EAV_CTRL0 0x1c30 ++#define RTL8367C_EAV_CTRL0_OFFSET 0 ++#define RTL8367C_EAV_CTRL0_MASK 0xFF ++ ++#define RTL8367C_REG_EAV_CTRL1 0x1c31 ++#define RTL8367C_REMAP_EAV_PRI3_REGEN_OFFSET 9 ++#define RTL8367C_REMAP_EAV_PRI3_REGEN_MASK 0xE00 ++#define RTL8367C_REMAP_EAV_PRI2_REGEN_OFFSET 6 ++#define RTL8367C_REMAP_EAV_PRI2_REGEN_MASK 0x1C0 ++#define RTL8367C_REMAP_EAV_PRI1_REGEN_OFFSET 3 ++#define RTL8367C_REMAP_EAV_PRI1_REGEN_MASK 0x38 ++#define RTL8367C_REMAP_EAV_PRI0_REGEN_OFFSET 0 ++#define RTL8367C_REMAP_EAV_PRI0_REGEN_MASK 0x7 ++ ++#define RTL8367C_REG_EAV_CTRL2 0x1c32 ++#define RTL8367C_REMAP_EAV_PRI7_REGEN_OFFSET 9 ++#define RTL8367C_REMAP_EAV_PRI7_REGEN_MASK 0xE00 ++#define RTL8367C_REMAP_EAV_PRI6_REGEN_OFFSET 6 ++#define RTL8367C_REMAP_EAV_PRI6_REGEN_MASK 0x1C0 ++#define RTL8367C_REMAP_EAV_PRI5_REGEN_OFFSET 3 ++#define RTL8367C_REMAP_EAV_PRI5_REGEN_MASK 0x38 ++#define RTL8367C_REMAP_EAV_PRI4_REGEN_OFFSET 0 ++#define RTL8367C_REMAP_EAV_PRI4_REGEN_MASK 0x7 ++ ++#define RTL8367C_REG_SYS_TIME_FREQ 0x1c43 ++ ++#define RTL8367C_REG_SYS_TIME_OFFSET_L 0x1c44 ++ ++#define RTL8367C_REG_SYS_TIME_OFFSET_H 0x1c45 ++ ++#define RTL8367C_REG_SYS_TIME_OFFSET_512NS_L 0x1c46 ++ ++#define RTL8367C_REG_SYS_TIME_OFFSET_512NS_H 0x1c47 ++#define RTL8367C_SYS_TIME_OFFSET_TUNE_OFFSET 5 ++#define RTL8367C_SYS_TIME_OFFSET_TUNE_MASK 0x20 ++#define RTL8367C_SYS_TIME_OFFSET_512NS_H_SYS_TIME_OFFSET_512NS_OFFSET 0 ++#define RTL8367C_SYS_TIME_OFFSET_512NS_H_SYS_TIME_OFFSET_512NS_MASK 0x1F ++ ++#define RTL8367C_REG_SYS_TIME_SEC_TRANSIT 0x1c48 ++#define RTL8367C_SYS_TIME_SEC_TRANSIT_OFFSET 0 ++#define RTL8367C_SYS_TIME_SEC_TRANSIT_MASK 0x1 ++ ++#define RTL8367C_REG_SYS_TIME_SEC_HIGH_L 0x1c49 ++ ++#define RTL8367C_REG_SYS_TIME_SEC_HIGH_H 0x1c4a ++ ++#define RTL8367C_REG_SYS_TIME_512NS_L 0x1c4b ++ ++#define RTL8367C_REG_SYS_TIME_512NS_H 0x1c4c ++#define RTL8367C_SYS_TIME_512NS_H_OFFSET 0 ++#define RTL8367C_SYS_TIME_512NS_H_MASK 0x1F ++ ++#define RTL8367C_REG_FALLBACK_CTRL 0x1c70 ++#define RTL8367C_FALLBACK_PL_DEC_EN_OFFSET 15 ++#define RTL8367C_FALLBACK_PL_DEC_EN_MASK 0x8000 ++#define RTL8367C_FALLBACK_MONITOR_TIMEOUT_IGNORE_OFFSET 14 ++#define RTL8367C_FALLBACK_MONITOR_TIMEOUT_IGNORE_MASK 0x4000 ++#define RTL8367C_FALLBACK_ERROR_RATIO_THRESHOLD_OFFSET 11 ++#define RTL8367C_FALLBACK_ERROR_RATIO_THRESHOLD_MASK 0x3800 ++#define RTL8367C_FALLBACK_MONITORMAX_OFFSET 8 ++#define RTL8367C_FALLBACK_MONITORMAX_MASK 0x700 ++#define RTL8367C_FALLBACK_MONITOR_TIMEOUT_OFFSET 0 ++#define RTL8367C_FALLBACK_MONITOR_TIMEOUT_MASK 0xFF ++ ++#define RTL8367C_REG_FALLBACK_PORT0_CFG0 0x1c71 ++#define RTL8367C_FALLBACK_PORT0_CFG0_RESET_POWER_LEVEL_OFFSET 15 ++#define RTL8367C_FALLBACK_PORT0_CFG0_RESET_POWER_LEVEL_MASK 0x8000 ++#define RTL8367C_FALLBACK_PORT0_CFG0_ENABLE_OFFSET 14 ++#define RTL8367C_FALLBACK_PORT0_CFG0_ENABLE_MASK 0x4000 ++ ++#define RTL8367C_REG_FALLBACK_PORT0_CFG1 0x1c72 ++ ++#define RTL8367C_REG_FALLBACK_PORT0_CFG2 0x1c73 ++#define RTL8367C_FALLBACK_PORT0_CFG2_OFFSET 0 ++#define RTL8367C_FALLBACK_PORT0_CFG2_MASK 0xFFF ++ ++#define RTL8367C_REG_FALLBACK_PORT0_CFG3 0x1c74 ++#define RTL8367C_FALLBACK_PORT0_CFG3_OFFSET 0 ++#define RTL8367C_FALLBACK_PORT0_CFG3_MASK 0xFF ++ ++#define RTL8367C_REG_FALLBACK_PORT1_CFG0 0x1c75 ++#define RTL8367C_FALLBACK_PORT1_CFG0_RESET_POWER_LEVEL_OFFSET 15 ++#define RTL8367C_FALLBACK_PORT1_CFG0_RESET_POWER_LEVEL_MASK 0x8000 ++#define RTL8367C_FALLBACK_PORT1_CFG0_ENABLE_OFFSET 14 ++#define RTL8367C_FALLBACK_PORT1_CFG0_ENABLE_MASK 0x4000 ++ ++#define RTL8367C_REG_FALLBACK_PORT1_CFG1 0x1c76 ++ ++#define RTL8367C_REG_FALLBACK_PORT1_CFG2 0x1c77 ++#define RTL8367C_FALLBACK_PORT1_CFG2_OFFSET 0 ++#define RTL8367C_FALLBACK_PORT1_CFG2_MASK 0xFFF ++ ++#define RTL8367C_REG_FALLBACK_PORT1_CFG3 0x1c78 ++#define RTL8367C_FALLBACK_PORT1_CFG3_OFFSET 0 ++#define RTL8367C_FALLBACK_PORT1_CFG3_MASK 0xFF ++ ++#define RTL8367C_REG_FALLBACK_PORT2_CFG0 0x1c79 ++#define RTL8367C_FALLBACK_PORT2_CFG0_RESET_POWER_LEVEL_OFFSET 15 ++#define RTL8367C_FALLBACK_PORT2_CFG0_RESET_POWER_LEVEL_MASK 0x8000 ++#define RTL8367C_FALLBACK_PORT2_CFG0_ENABLE_OFFSET 14 ++#define RTL8367C_FALLBACK_PORT2_CFG0_ENABLE_MASK 0x4000 ++ ++#define RTL8367C_REG_FALLBACK_PORT2_CFG1 0x1c7a ++ ++#define RTL8367C_REG_FALLBACK_PORT2_CFG2 0x1c7b ++#define RTL8367C_FALLBACK_PORT2_CFG2_OFFSET 0 ++#define RTL8367C_FALLBACK_PORT2_CFG2_MASK 0xFFF ++ ++#define RTL8367C_REG_FALLBACK_PORT2_CFG3 0x1c7c ++#define RTL8367C_FALLBACK_PORT2_CFG3_OFFSET 0 ++#define RTL8367C_FALLBACK_PORT2_CFG3_MASK 0xFF ++ ++#define RTL8367C_REG_FALLBACK_PORT3_CFG0 0x1c7d ++#define RTL8367C_FALLBACK_PORT3_CFG0_RESET_POWER_LEVEL_OFFSET 15 ++#define RTL8367C_FALLBACK_PORT3_CFG0_RESET_POWER_LEVEL_MASK 0x8000 ++#define RTL8367C_FALLBACK_PORT3_CFG0_ENABLE_OFFSET 14 ++#define RTL8367C_FALLBACK_PORT3_CFG0_ENABLE_MASK 0x4000 ++ ++#define RTL8367C_REG_FALLBACK_PORT3_CFG1 0x1c7e ++ ++#define RTL8367C_REG_FALLBACK_PORT3_CFG2 0x1c7f ++#define RTL8367C_FALLBACK_PORT3_CFG2_OFFSET 0 ++#define RTL8367C_FALLBACK_PORT3_CFG2_MASK 0xFFF ++ ++#define RTL8367C_REG_FALLBACK_PORT3_CFG3 0x1c80 ++#define RTL8367C_FALLBACK_PORT3_CFG3_OFFSET 0 ++#define RTL8367C_FALLBACK_PORT3_CFG3_MASK 0xFF ++ ++#define RTL8367C_REG_FALLBACK_PORT4_CFG0 0x1c81 ++#define RTL8367C_FALLBACK_PORT4_CFG0_RESET_POWER_LEVEL_OFFSET 15 ++#define RTL8367C_FALLBACK_PORT4_CFG0_RESET_POWER_LEVEL_MASK 0x8000 ++#define RTL8367C_FALLBACK_PORT4_CFG0_ENABLE_OFFSET 14 ++#define RTL8367C_FALLBACK_PORT4_CFG0_ENABLE_MASK 0x4000 ++ ++#define RTL8367C_REG_FALLBACK_PORT4_CFG1 0x1c82 ++ ++#define RTL8367C_REG_FALLBACK_PORT4_CFG2 0x1c83 ++#define RTL8367C_FALLBACK_PORT4_CFG2_OFFSET 0 ++#define RTL8367C_FALLBACK_PORT4_CFG2_MASK 0xFFF ++ ++#define RTL8367C_REG_FALLBACK_PORT4_CFG3 0x1c84 ++#define RTL8367C_FALLBACK_PORT4_CFG3_OFFSET 0 ++#define RTL8367C_FALLBACK_PORT4_CFG3_MASK 0xFF ++ ++#define RTL8367C_REG_FALLBACK_CTRL1 0x1c85 ++#define RTL8367C_FALLBACK_VALIDFLOW_OFFSET 8 ++#define RTL8367C_FALLBACK_VALIDFLOW_MASK 0xFF00 ++#define RTL8367C_FALLBACK_STOP_TMR_OFFSET 0 ++#define RTL8367C_FALLBACK_STOP_TMR_MASK 0x1 ++ ++#define RTL8367C_REG_FALLBACK_CPL 0x1c86 ++#define RTL8367C_PORT4_CPL_OFFSET 4 ++#define RTL8367C_PORT4_CPL_MASK 0x10 ++#define RTL8367C_PORT3_CPL_OFFSET 3 ++#define RTL8367C_PORT3_CPL_MASK 0x8 ++#define RTL8367C_PORT2_CPL_OFFSET 2 ++#define RTL8367C_PORT2_CPL_MASK 0x4 ++#define RTL8367C_PORT1_CPL_OFFSET 1 ++#define RTL8367C_PORT1_CPL_MASK 0x2 ++#define RTL8367C_PORT0_CPL_OFFSET 0 ++#define RTL8367C_PORT0_CPL_MASK 0x1 ++ ++#define RTL8367C_REG_FALLBACK_PHY_PAGE 0x1c87 ++#define RTL8367C_FALLBACK_PHY_PAGE_OFFSET 0 ++#define RTL8367C_FALLBACK_PHY_PAGE_MASK 0xFFF ++ ++#define RTL8367C_REG_FALLBACK_PHY_REG 0x1c88 ++#define RTL8367C_FALLBACK_PHY_REG_OFFSET 0 ++#define RTL8367C_FALLBACK_PHY_REG_MASK 0x1F ++ ++#define RTL8367C_REG_AFBK_INFO_X0 0x1c89 ++ ++#define RTL8367C_REG_AFBK_INFO_X1 0x1c8a ++ ++#define RTL8367C_REG_AFBK_INFO_X2 0x1c8b ++ ++#define RTL8367C_REG_AFBK_INFO_X3 0x1c8c ++ ++#define RTL8367C_REG_AFBK_INFO_X4 0x1c8d ++ ++#define RTL8367C_REG_AFBK_INFO_X5 0x1c8e ++ ++#define RTL8367C_REG_AFBK_INFO_X6 0x1c8f ++ ++#define RTL8367C_REG_AFBK_INFO_X7 0x1c90 ++ ++#define RTL8367C_REG_AFBK_INFO_X8 0x1c91 ++ ++#define RTL8367C_REG_AFBK_INFO_X9 0x1c92 ++ ++#define RTL8367C_REG_AFBK_INFO_X10 0x1c93 ++ ++#define RTL8367C_REG_AFBK_INFO_X11 0x1c94 ++ ++#define RTL8367C_REG_FALLBACK_PORT5_CFG0 0x1ca0 ++#define RTL8367C_FALLBACK_PORT5_CFG0_RESET_POWER_LEVEL_OFFSET 15 ++#define RTL8367C_FALLBACK_PORT5_CFG0_RESET_POWER_LEVEL_MASK 0x8000 ++#define RTL8367C_FALLBACK_PORT5_CFG0_ENABLE_OFFSET 14 ++#define RTL8367C_FALLBACK_PORT5_CFG0_ENABLE_MASK 0x4000 ++ ++#define RTL8367C_REG_FALLBACK_PORT5_CFG1 0x1ca1 ++ ++#define RTL8367C_REG_FALLBACK_PORT5_CFG2 0x1ca2 ++#define RTL8367C_FALLBACK_PORT5_CFG2_OFFSET 0 ++#define RTL8367C_FALLBACK_PORT5_CFG2_MASK 0xFFF ++ ++#define RTL8367C_REG_FALLBACK_PORT5_CFG3 0x1ca3 ++#define RTL8367C_FALLBACK_PORT5_CFG3_OFFSET 0 ++#define RTL8367C_FALLBACK_PORT5_CFG3_MASK 0xFF ++ ++#define RTL8367C_REG_FALLBACK_PORT6_CFG0 0x1ca4 ++#define RTL8367C_FALLBACK_PORT6_CFG0_RESET_POWER_LEVEL_OFFSET 15 ++#define RTL8367C_FALLBACK_PORT6_CFG0_RESET_POWER_LEVEL_MASK 0x8000 ++#define RTL8367C_FALLBACK_PORT6_CFG0_ENABLE_OFFSET 14 ++#define RTL8367C_FALLBACK_PORT6_CFG0_ENABLE_MASK 0x4000 ++ ++#define RTL8367C_REG_FALLBACK_PORT6_CFG1 0x1ca5 ++ ++#define RTL8367C_REG_FALLBACK_PORT6_CFG2 0x1ca6 ++#define RTL8367C_FALLBACK_PORT6_CFG2_OFFSET 0 ++#define RTL8367C_FALLBACK_PORT6_CFG2_MASK 0xFFF ++ ++#define RTL8367C_REG_FALLBACK_PORT6_CFG3 0x1ca7 ++#define RTL8367C_FALLBACK_PORT6_CFG3_OFFSET 0 ++#define RTL8367C_FALLBACK_PORT6_CFG3_MASK 0xFF ++ ++#define RTL8367C_REG_FALLBACK_PORT7_CFG0 0x1ca8 ++#define RTL8367C_FALLBACK_PORT7_CFG0_RESET_POWER_LEVEL_OFFSET 15 ++#define RTL8367C_FALLBACK_PORT7_CFG0_RESET_POWER_LEVEL_MASK 0x8000 ++#define RTL8367C_FALLBACK_PORT7_CFG0_ENABLE_OFFSET 14 ++#define RTL8367C_FALLBACK_PORT7_CFG0_ENABLE_MASK 0x4000 ++ ++#define RTL8367C_REG_FALLBACK_PORT7_CFG1 0x1ca9 ++ ++#define RTL8367C_REG_FALLBACK_PORT7_CFG2 0x1caa ++#define RTL8367C_FALLBACK_PORT7_CFG2_OFFSET 0 ++#define RTL8367C_FALLBACK_PORT7_CFG2_MASK 0xFFF ++ ++#define RTL8367C_REG_FALLBACK_PORT7_CFG3 0x1cab ++#define RTL8367C_FALLBACK_PORT7_CFG3_OFFSET 0 ++#define RTL8367C_FALLBACK_PORT7_CFG3_MASK 0xFF ++ ++#define RTL8367C_REG_IGMP_PORT8_CONTROL 0x1cb0 ++#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_QUERY_OFFSET 14 ++#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_QUERY_MASK 0x4000 ++#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_REPORT_OFFSET 13 ++#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_REPORT_MASK 0x2000 ++#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_LEAVE_OFFSET 12 ++#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_LEAVE_MASK 0x1000 ++#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_MRP_OFFSET 11 ++#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_MRP_MASK 0x800 ++#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_MC_DATA_OFFSET 10 ++#define RTL8367C_IGMP_PORT8_CONTROL_ALLOW_MC_DATA_MASK 0x400 ++#define RTL8367C_IGMP_PORT8_CONTROL_MLDv2_OP_OFFSET 8 ++#define RTL8367C_IGMP_PORT8_CONTROL_MLDv2_OP_MASK 0x300 ++#define RTL8367C_IGMP_PORT8_CONTROL_MLDv1_OP_OFFSET 6 ++#define RTL8367C_IGMP_PORT8_CONTROL_MLDv1_OP_MASK 0xC0 ++#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV3_OP_OFFSET 4 ++#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV3_OP_MASK 0x30 ++#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV2_OP_OFFSET 2 ++#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV2_OP_MASK 0xC ++#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV1_OP_OFFSET 0 ++#define RTL8367C_IGMP_PORT8_CONTROL_IGMPV1_OP_MASK 0x3 ++ ++#define RTL8367C_REG_IGMP_PORT9_CONTROL 0x1cb1 ++#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_QUERY_OFFSET 14 ++#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_QUERY_MASK 0x4000 ++#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_REPORT_OFFSET 13 ++#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_REPORT_MASK 0x2000 ++#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_LEAVE_OFFSET 12 ++#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_LEAVE_MASK 0x1000 ++#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_MRP_OFFSET 11 ++#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_MRP_MASK 0x800 ++#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_MC_DATA_OFFSET 10 ++#define RTL8367C_IGMP_PORT9_CONTROL_ALLOW_MC_DATA_MASK 0x400 ++#define RTL8367C_IGMP_PORT9_CONTROL_MLDv2_OP_OFFSET 8 ++#define RTL8367C_IGMP_PORT9_CONTROL_MLDv2_OP_MASK 0x300 ++#define RTL8367C_IGMP_PORT9_CONTROL_MLDv1_OP_OFFSET 6 ++#define RTL8367C_IGMP_PORT9_CONTROL_MLDv1_OP_MASK 0xC0 ++#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV3_OP_OFFSET 4 ++#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV3_OP_MASK 0x30 ++#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV2_OP_OFFSET 2 ++#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV2_OP_MASK 0xC ++#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV1_OP_OFFSET 0 ++#define RTL8367C_IGMP_PORT9_CONTROL_IGMPV1_OP_MASK 0x3 ++ ++#define RTL8367C_REG_IGMP_PORT10_CONTROL 0x1cb2 ++#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_QUERY_OFFSET 14 ++#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_QUERY_MASK 0x4000 ++#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_REPORT_OFFSET 13 ++#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_REPORT_MASK 0x2000 ++#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_LEAVE_OFFSET 12 ++#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_LEAVE_MASK 0x1000 ++#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_MRP_OFFSET 11 ++#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_MRP_MASK 0x800 ++#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_MC_DATA_OFFSET 10 ++#define RTL8367C_IGMP_PORT10_CONTROL_ALLOW_MC_DATA_MASK 0x400 ++#define RTL8367C_IGMP_PORT10_CONTROL_MLDv2_OP_OFFSET 8 ++#define RTL8367C_IGMP_PORT10_CONTROL_MLDv2_OP_MASK 0x300 ++#define RTL8367C_IGMP_PORT10_CONTROL_MLDv1_OP_OFFSET 6 ++#define RTL8367C_IGMP_PORT10_CONTROL_MLDv1_OP_MASK 0xC0 ++#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV3_OP_OFFSET 4 ++#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV3_OP_MASK 0x30 ++#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV2_OP_OFFSET 2 ++#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV2_OP_MASK 0xC ++#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV1_OP_OFFSET 0 ++#define RTL8367C_IGMP_PORT10_CONTROL_IGMPV1_OP_MASK 0x3 ++ ++#define RTL8367C_REG_IGMP_PORT89_MAX_GROUP 0x1cb3 ++#define RTL8367C_PORT9_MAX_GROUP_OFFSET 8 ++#define RTL8367C_PORT9_MAX_GROUP_MASK 0xFF00 ++#define RTL8367C_PORT8_MAX_GROUP_OFFSET 0 ++#define RTL8367C_PORT8_MAX_GROUP_MASK 0xFF ++ ++#define RTL8367C_REG_IGMP_PORT10_MAX_GROUP 0x1cb4 ++#define RTL8367C_IGMP_PORT10_MAX_GROUP_OFFSET 0 ++#define RTL8367C_IGMP_PORT10_MAX_GROUP_MASK 0xFF ++ ++#define RTL8367C_REG_IGMP_PORT89_CURRENT_GROUP 0x1cb5 ++#define RTL8367C_PORT9_CURRENT_GROUP_OFFSET 8 ++#define RTL8367C_PORT9_CURRENT_GROUP_MASK 0xFF00 ++#define RTL8367C_PORT8_CURRENT_GROUP_OFFSET 0 ++#define RTL8367C_PORT8_CURRENT_GROUP_MASK 0xFF ++ ++#define RTL8367C_REG_IGMP_PORT10_CURRENT_GROUP 0x1cb6 ++#define RTL8367C_IGMP_PORT10_CURRENT_GROUP_OFFSET 0 ++#define RTL8367C_IGMP_PORT10_CURRENT_GROUP_MASK 0xFF ++ ++#define RTL8367C_REG_IGMP_L3_CHECKSUM_CHECK 0x1cb7 ++#define RTL8367C_IGMP_L3_CHECKSUM_CHECK_OFFSET 0 ++#define RTL8367C_IGMP_L3_CHECKSUM_CHECK_MASK 0x1 ++ ++/* (16'h1d00)chip_70b_reg */ ++ ++#define RTL8367C_REG_PCSXF_CFG 0x1d00 ++#define RTL8367C_PCSXF_CFG_Reserved_OFFSET 15 ++#define RTL8367C_PCSXF_CFG_Reserved_MASK 0x8000 ++#define RTL8367C_CFG_RST_RXFIFO_P7_5_OFFSET 12 ++#define RTL8367C_CFG_RST_RXFIFO_P7_5_MASK 0x7000 ++#define RTL8367C_CFG_PCSXF_OFFSET 8 ++#define RTL8367C_CFG_PCSXF_MASK 0xF00 ++#define RTL8367C_CFG_RST_RXFIFO_OFFSET 3 ++#define RTL8367C_CFG_RST_RXFIFO_MASK 0xF8 ++#define RTL8367C_CFG_COL2RXDV_OFFSET 2 ++#define RTL8367C_CFG_COL2RXDV_MASK 0x4 ++#define RTL8367C_CFG_PHY_SDET_OFFSET 0 ++#define RTL8367C_CFG_PHY_SDET_MASK 0x3 ++ ++#define RTL8367C_REG_PHYID_CFG0 0x1d01 ++#define RTL8367C_CFG_PHY_BRD_MODE_P7_5_OFFSET 11 ++#define RTL8367C_CFG_PHY_BRD_MODE_P7_5_MASK 0x3800 ++#define RTL8367C_CFG_PHYAD_14C_OFFSET 10 ++#define RTL8367C_CFG_PHYAD_14C_MASK 0x400 ++#define RTL8367C_CFG_PHY_BRD_MODE_OFFSET 5 ++#define RTL8367C_CFG_PHY_BRD_MODE_MASK 0x3E0 ++#define RTL8367C_CFG_BRD_PHYAD_OFFSET 0 ++#define RTL8367C_CFG_BRD_PHYAD_MASK 0x1F ++ ++#define RTL8367C_REG_PHYID_CFG1 0x1d02 ++#define RTL8367C_CFG_MSK_MDI_OFFSET 5 ++#define RTL8367C_CFG_MSK_MDI_MASK 0x1FE0 ++#define RTL8367C_CFG_BASE_PHYAD_OFFSET 0 ++#define RTL8367C_CFG_BASE_PHYAD_MASK 0x1F ++ ++#define RTL8367C_REG_PHY_POLL_CFG0 0x1d03 ++#define RTL8367C_CFG_HOTCMD_PRD_EN_OFFSET 15 ++#define RTL8367C_CFG_HOTCMD_PRD_EN_MASK 0x8000 ++#define RTL8367C_CFG_HOTCMD_EN_OFFSET 12 ++#define RTL8367C_CFG_HOTCMD_EN_MASK 0x7000 ++#define RTL8367C_CFG_POLL_PERIOD_OFFSET 8 ++#define RTL8367C_CFG_POLL_PERIOD_MASK 0xF00 ++#define RTL8367C_CFG_PERI_CMDS_RD_OFFSET 4 ++#define RTL8367C_CFG_PERI_CMDS_RD_MASK 0xF0 ++#define RTL8367C_CFG_PERI_CMDS_WR_OFFSET 0 ++#define RTL8367C_CFG_PERI_CMDS_WR_MASK 0xF ++ ++#define RTL8367C_REG_PHY_POLL_CFG1 0x1d04 ++ ++#define RTL8367C_REG_PHY_POLL_CFG2 0x1d05 ++ ++#define RTL8367C_REG_PHY_POLL_CFG3 0x1d06 ++ ++#define RTL8367C_REG_PHY_POLL_CFG4 0x1d07 ++ ++#define RTL8367C_REG_PHY_POLL_CFG5 0x1d08 ++ ++#define RTL8367C_REG_PHY_POLL_CFG6 0x1d09 ++ ++#define RTL8367C_REG_PHY_POLL_CFG7 0x1d0a ++ ++#define RTL8367C_REG_PHY_POLL_CFG8 0x1d0b ++ ++#define RTL8367C_REG_PHY_POLL_CFG9 0x1d0c ++ ++#define RTL8367C_REG_PHY_POLL_CFG10 0x1d0d ++ ++#define RTL8367C_REG_PHY_POLL_CFG11 0x1d0e ++ ++#define RTL8367C_REG_PHY_POLL_CFG12 0x1d0f ++ ++#define RTL8367C_REG_EFUSE_MISC 0x1d10 ++#define RTL8367C_CFG_SA_SEL_OFFSET 5 ++#define RTL8367C_CFG_SA_SEL_MASK 0x20 ++#define RTL8367C_CFG_PHYAD00_OFFSET 0 ++#define RTL8367C_CFG_PHYAD00_MASK 0x1F ++ ++#define RTL8367C_REG_SDS_MISC 0x1d11 ++#define RTL8367C_CFG_SGMII_RXFC_OFFSET 14 ++#define RTL8367C_CFG_SGMII_RXFC_MASK 0x4000 ++#define RTL8367C_CFG_SGMII_TXFC_OFFSET 13 ++#define RTL8367C_CFG_SGMII_TXFC_MASK 0x2000 ++#define RTL8367C_INB_ARB_OFFSET 12 ++#define RTL8367C_INB_ARB_MASK 0x1000 ++#define RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET 11 ++#define RTL8367C_CFG_MAC8_SEL_HSGMII_MASK 0x800 ++#define RTL8367C_CFG_SGMII_FDUP_OFFSET 10 ++#define RTL8367C_CFG_SGMII_FDUP_MASK 0x400 ++#define RTL8367C_CFG_SGMII_LINK_OFFSET 9 ++#define RTL8367C_CFG_SGMII_LINK_MASK 0x200 ++#define RTL8367C_CFG_SGMII_SPD_OFFSET 7 ++#define RTL8367C_CFG_SGMII_SPD_MASK 0x180 ++#define RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET 6 ++#define RTL8367C_CFG_MAC8_SEL_SGMII_MASK 0x40 ++#define RTL8367C_CFG_INB_SEL_OFFSET 3 ++#define RTL8367C_CFG_INB_SEL_MASK 0x38 ++#define RTL8367C_CFG_SDS_MODE_18C_OFFSET 0 ++#define RTL8367C_CFG_SDS_MODE_18C_MASK 0x7 ++ ++#define RTL8367C_REG_FIFO_CTRL 0x1d12 ++#define RTL8367C_CFG_LINK_DOWN_CLR_FIFO_OFFSET 11 ++#define RTL8367C_CFG_LINK_DOWN_CLR_FIFO_MASK 0x800 ++#define RTL8367C_CFG_LPBK_OFFSET 10 ++#define RTL8367C_CFG_LPBK_MASK 0x400 ++#define RTL8367C_CFG_NOT_FF_OUT_OFFSET 9 ++#define RTL8367C_CFG_NOT_FF_OUT_MASK 0x200 ++#define RTL8367C_CFG_WATER_LEVEL_FD_OFFSET 6 ++#define RTL8367C_CFG_WATER_LEVEL_FD_MASK 0x1C0 ++#define RTL8367C_CFG_WATER_LEVEL_Y2X_OFFSET 3 ++#define RTL8367C_CFG_WATER_LEVEL_Y2X_MASK 0x38 ++#define RTL8367C_CFG_WATER_LEVEL_X2Y_OFFSET 0 ++#define RTL8367C_CFG_WATER_LEVEL_X2Y_MASK 0x7 ++ ++#define RTL8367C_REG_BCAM_SETTING 0x1d13 ++#define RTL8367C_CFG_BCAM_MDS_OFFSET 3 ++#define RTL8367C_CFG_BCAM_MDS_MASK 0x18 ++#define RTL8367C_CFG_BCAM_RDS_OFFSET 0 ++#define RTL8367C_CFG_BCAM_RDS_MASK 0x7 ++ ++#define RTL8367C_REG_GPHY_ACS_MISC 0x1d14 ++#define RTL8367C_CFG_SEL_GPHY_SMI_OFFSET 3 ++#define RTL8367C_CFG_SEL_GPHY_SMI_MASK 0x8 ++#define RTL8367C_CFG_BRD_PHYIDX_OFFSET 0 ++#define RTL8367C_CFG_BRD_PHYIDX_MASK 0x7 ++ ++#define RTL8367C_REG_GPHY_OCP_MSB_0 0x1d15 ++#define RTL8367C_CFG_CPU_OCPADR_MSB_OFFSET 6 ++#define RTL8367C_CFG_CPU_OCPADR_MSB_MASK 0xFC0 ++#define RTL8367C_CFG_DW8051_OCPADR_MSB_OFFSET 0 ++#define RTL8367C_CFG_DW8051_OCPADR_MSB_MASK 0x3F ++ ++#define RTL8367C_REG_GPHY_OCP_MSB_1 0x1d16 ++#define RTL8367C_CFG_PATCH_OCPADR_MSB_OFFSET 6 ++#define RTL8367C_CFG_PATCH_OCPADR_MSB_MASK 0xFC0 ++#define RTL8367C_CFG_PHYSTS_OCPADR_MSB_OFFSET 0 ++#define RTL8367C_CFG_PHYSTS_OCPADR_MSB_MASK 0x3F ++ ++#define RTL8367C_REG_GPHY_OCP_MSB_2 0x1d17 ++#define RTL8367C_CFG_RRCP_OCPADR_MSB_OFFSET 6 ++#define RTL8367C_CFG_RRCP_OCPADR_MSB_MASK 0xFC0 ++#define RTL8367C_CFG_RTCT_OCPADR_MSB_OFFSET 0 ++#define RTL8367C_CFG_RTCT_OCPADR_MSB_MASK 0x3F ++ ++#define RTL8367C_REG_GPHY_OCP_MSB_3 0x1d18 ++#define RTL8367C_GPHY_OCP_MSB_3_OFFSET 0 ++#define RTL8367C_GPHY_OCP_MSB_3_MASK 0x3F ++ ++#define RTL8367C_REG_GPIO_67C_I_X0 0x1d19 ++ ++#define RTL8367C_REG_GPIO_67C_I_X1 0x1d1a ++ ++#define RTL8367C_REG_GPIO_67C_I_X2 0x1d1b ++ ++#define RTL8367C_REG_GPIO_67C_I_X3 0x1d1c ++#define RTL8367C_GPIO_67C_I_X3_OFFSET 0 ++#define RTL8367C_GPIO_67C_I_X3_MASK 0x3FFF ++ ++#define RTL8367C_REG_GPIO_67C_O_X0 0x1d1d ++ ++#define RTL8367C_REG_GPIO_67C_O_X1 0x1d1e ++ ++#define RTL8367C_REG_GPIO_67C_O_X2 0x1d1f ++ ++#define RTL8367C_REG_GPIO_67C_O_X3 0x1d20 ++#define RTL8367C_GPIO_67C_O_X3_OFFSET 0 ++#define RTL8367C_GPIO_67C_O_X3_MASK 0x3FFF ++ ++#define RTL8367C_REG_GPIO_67C_OE_X0 0x1d21 ++ ++#define RTL8367C_REG_GPIO_67C_OE_X1 0x1d22 ++ ++#define RTL8367C_REG_GPIO_67C_OE_X2 0x1d23 ++ ++#define RTL8367C_REG_GPIO_67C_OE_X3 0x1d24 ++#define RTL8367C_GPIO_67C_OE_X3_OFFSET 0 ++#define RTL8367C_GPIO_67C_OE_X3_MASK 0x3FFF ++ ++#define RTL8367C_REG_GPIO_MODE_67C_X0 0x1d25 ++ ++#define RTL8367C_REG_GPIO_MODE_67C_X1 0x1d26 ++ ++#define RTL8367C_REG_GPIO_MODE_67C_X2 0x1d27 ++ ++#define RTL8367C_REG_GPIO_MODE_67C_X3 0x1d28 ++#define RTL8367C_GPIO_MODE_67C_X3_OFFSET 0 ++#define RTL8367C_GPIO_MODE_67C_X3_MASK 0x3FFF ++ ++#define RTL8367C_REG_WGPHY_MISC_0 0x1d29 ++#define RTL8367C_CFG_INIPHY_DISGIGA_P7_5_OFFSET 13 ++#define RTL8367C_CFG_INIPHY_DISGIGA_P7_5_MASK 0xE000 ++#define RTL8367C_CFG_INIPHY_PWRUP_OFFSET 5 ++#define RTL8367C_CFG_INIPHY_PWRUP_MASK 0x1FE0 ++#define RTL8367C_CFG_INIPHY_DISGIGA_OFFSET 0 ++#define RTL8367C_CFG_INIPHY_DISGIGA_MASK 0x1F ++ ++#define RTL8367C_REG_WGPHY_MISC_1 0x1d2a ++#define RTL8367C_WGPHY_MISC_1_OFFSET 0 ++#define RTL8367C_WGPHY_MISC_1_MASK 0xFF ++ ++#define RTL8367C_REG_WGPHY_MISC_2 0x1d2b ++#define RTL8367C_WGPHY_MISC_2_OFFSET 0 ++#define RTL8367C_WGPHY_MISC_2_MASK 0x3FF ++ ++#define RTL8367C_REG_CFG_AFBK_GPHY_0 0x1d2c ++#define RTL8367C_CFG_AFBK_GPHY_0_OFFSET 0 ++#define RTL8367C_CFG_AFBK_GPHY_0_MASK 0x1F ++ ++#define RTL8367C_REG_CFG_AFBK_GPHY_1 0x1d2d ++#define RTL8367C_CFG_AFBK_GPHY_1_OFFSET 0 ++#define RTL8367C_CFG_AFBK_GPHY_1_MASK 0xFFF ++ ++#define RTL8367C_REG_EF_SLV_CTRL_0 0x1d2e ++#define RTL8367C_EF_SLV_BUSY_OFFSET 11 ++#define RTL8367C_EF_SLV_BUSY_MASK 0x800 ++#define RTL8367C_EF_SLV_ACK_OFFSET 10 ++#define RTL8367C_EF_SLV_ACK_MASK 0x400 ++#define RTL8367C_EF_SLV_A_OFFSET 2 ++#define RTL8367C_EF_SLV_A_MASK 0x3FC ++#define RTL8367C_EF_SLV_WE_OFFSET 1 ++#define RTL8367C_EF_SLV_WE_MASK 0x2 ++#define RTL8367C_EF_SLV_CE_OFFSET 0 ++#define RTL8367C_EF_SLV_CE_MASK 0x1 ++ ++#define RTL8367C_REG_EF_SLV_CTRL_1 0x1d2f ++ ++#define RTL8367C_REG_EF_SLV_CTRL_2 0x1d30 ++ ++#define RTL8367C_REG_EFUSE_MISC_1 0x1d31 ++#define RTL8367C_EF_EN_EFUSE_OFFSET 10 ++#define RTL8367C_EF_EN_EFUSE_MASK 0x400 ++#define RTL8367C_EF_MODEL_ID_OFFSET 6 ++#define RTL8367C_EF_MODEL_ID_MASK 0x3C0 ++#define RTL8367C_EF_RSVD_OFFSET 2 ++#define RTL8367C_EF_RSVD_MASK 0x3C ++#define RTL8367C_EF_SYS_CLK_OFFSET 0 ++#define RTL8367C_EF_SYS_CLK_MASK 0x3 ++ ++#define RTL8367C_REG_IO_MISC_FUNC 0x1d32 ++#define RTL8367C_TST_MODE_OFFSET 3 ++#define RTL8367C_TST_MODE_MASK 0x8 ++#define RTL8367C_UART_EN_OFFSET 2 ++#define RTL8367C_UART_EN_MASK 0x4 ++#define RTL8367C_INT_EN_OFFSET 1 ++#define RTL8367C_INT_EN_MASK 0x2 ++#define RTL8367C_BUZ_EN_OFFSET 0 ++#define RTL8367C_BUZ_EN_MASK 0x1 ++ ++#define RTL8367C_REG_HTRAM_DVS 0x1d33 ++#define RTL8367C_HTRAM_DVS_OFFSET 0 ++#define RTL8367C_HTRAM_DVS_MASK 0x1 ++ ++#define RTL8367C_REG_EF_SLV_CTRL_3 0x1d34 ++#define RTL8367C_EF_SLV_CTRL_3_OFFSET 0 ++#define RTL8367C_EF_SLV_CTRL_3_MASK 0x1 ++ ++#define RTL8367C_REG_INBAND_EN14C 0x1d35 ++#define RTL8367C_INBAND_EN14C_OFFSET 0 ++#define RTL8367C_INBAND_EN14C_MASK 0x1 ++ ++#define RTL8367C_REG_CFG_SWR_L 0x1d36 ++#define RTL8367C_ANARG_RDY_SWR_L_OFFSET 14 ++#define RTL8367C_ANARG_RDY_SWR_L_MASK 0x4000 ++#define RTL8367C_ANARG_VALID_SWR_L_OFFSET 13 ++#define RTL8367C_ANARG_VALID_SWR_L_MASK 0x2000 ++#define RTL8367C_SAW_SWR_L_OFFSET 9 ++#define RTL8367C_SAW_SWR_L_MASK 0x1E00 ++#define RTL8367C_SAW_VALID_SWR_L_OFFSET 8 ++#define RTL8367C_SAW_VALID_SWR_L_MASK 0x100 ++#define RTL8367C_UPS_DBGO_L_OFFSET 0 ++#define RTL8367C_UPS_DBGO_L_MASK 0xFF ++ ++#define RTL8367C_REG_BTCAM_CTRL 0x1d37 ++#define RTL8367C_TCAM_RDS_OFFSET 2 ++#define RTL8367C_TCAM_RDS_MASK 0x1C ++#define RTL8367C_TCAM_MDS_OFFSET 0 ++#define RTL8367C_TCAM_MDS_MASK 0x3 ++ ++#define RTL8367C_REG_PBRAM_BISR_CTRL 0x1d38 ++#define RTL8367C_HAS_HLDRMP_MD_OFFSET 9 ++#define RTL8367C_HAS_HLDRMP_MD_MASK 0x200 ++#define RTL8367C_PB_HLDRMP_MD_OFFSET 8 ++#define RTL8367C_PB_HLDRMP_MD_MASK 0x100 ++#define RTL8367C_HAS_BISR_BIRSTN_OFFSET 7 ++#define RTL8367C_HAS_BISR_BIRSTN_MASK 0x80 ++#define RTL8367C_SEC_RUN_HSA_OFFSET 6 ++#define RTL8367C_SEC_RUN_HSA_MASK 0x40 ++#define RTL8367C_HAS_HLDRMP_VAL_OFFSET 5 ++#define RTL8367C_HAS_HLDRMP_VAL_MASK 0x20 ++#define RTL8367C_HAS_BISR_PWRSTN_OFFSET 4 ++#define RTL8367C_HAS_BISR_PWRSTN_MASK 0x10 ++#define RTL8367C_SEC_RUN_PB_OFFSET 3 ++#define RTL8367C_SEC_RUN_PB_MASK 0x8 ++#define RTL8367C_PB_HLDRMP_VAL_OFFSET 2 ++#define RTL8367C_PB_HLDRMP_VAL_MASK 0x4 ++#define RTL8367C_PB_BISR_BIRSTN_OFFSET 1 ++#define RTL8367C_PB_BISR_BIRSTN_MASK 0x2 ++#define RTL8367C_PB_BISR_PWRSTN_OFFSET 0 ++#define RTL8367C_PB_BISR_PWRSTN_MASK 0x1 ++ ++#define RTL8367C_REG_CVLANRAM_BISR_CTRL 0x1d39 ++#define RTL8367C_SEC_RUN_CVLAN_OFFSET 4 ++#define RTL8367C_SEC_RUN_CVLAN_MASK 0x10 ++#define RTL8367C_CVALN_HLDRMP_MD_OFFSET 3 ++#define RTL8367C_CVALN_HLDRMP_MD_MASK 0x8 ++#define RTL8367C_CVALN_HLDRMP_VAL_OFFSET 2 ++#define RTL8367C_CVALN_HLDRMP_VAL_MASK 0x4 ++#define RTL8367C_CVLAN_BISR_BIRSTN_OFFSET 1 ++#define RTL8367C_CVLAN_BISR_BIRSTN_MASK 0x2 ++#define RTL8367C_CVLAN_BISR_PWRSTN_OFFSET 0 ++#define RTL8367C_CVLAN_BISR_PWRSTN_MASK 0x1 ++ ++#define RTL8367C_REG_CFG_1588_TIMER_EN_GPI 0x1d3a ++#define RTL8367C_CFG_1588_TIMER_EN_GPI_OFFSET 0 ++#define RTL8367C_CFG_1588_TIMER_EN_GPI_MASK 0x1 ++ ++#define RTL8367C_REG_MDIO_PRMB_SUPP 0x1d3b ++#define RTL8367C_FIB_HIPRI_OFFSET 14 ++#define RTL8367C_FIB_HIPRI_MASK 0x4000 ++#define RTL8367C_SMT_EN_OFFSET 13 ++#define RTL8367C_SMT_EN_MASK 0x2000 ++#define RTL8367C_P4_FB_CPL_OFFSET 12 ++#define RTL8367C_P4_FB_CPL_MASK 0x1000 ++#define RTL8367C_P3_FB_CPL_OFFSET 11 ++#define RTL8367C_P3_FB_CPL_MASK 0x800 ++#define RTL8367C_P2_FB_CPL_OFFSET 10 ++#define RTL8367C_P2_FB_CPL_MASK 0x400 ++#define RTL8367C_P1_FB_CPL_OFFSET 9 ++#define RTL8367C_P1_FB_CPL_MASK 0x200 ++#define RTL8367C_P0_FB_CPL_OFFSET 8 ++#define RTL8367C_P0_FB_CPL_MASK 0x100 ++#define RTL8367C_DBG_PKG_8367N_OFFSET 7 ++#define RTL8367C_DBG_PKG_8367N_MASK 0x80 ++#define RTL8367C_DBG_PKG_8367VB_OFFSET 6 ++#define RTL8367C_DBG_PKG_8367VB_MASK 0x40 ++#define RTL8367C_CFG_DEBUG_EN_OFFSET 5 ++#define RTL8367C_CFG_DEBUG_EN_MASK 0x20 ++#define RTL8367C_CFG_TMR_ACK_OFFSET 1 ++#define RTL8367C_CFG_TMR_ACK_MASK 0x1E ++#define RTL8367C_CFG_PRMB_SUPP_OFFSET 0 ++#define RTL8367C_CFG_PRMB_SUPP_MASK 0x1 ++ ++#define RTL8367C_REG_BOND4READ 0x1d3c ++#define RTL8367C_BOND_BOID0_OFFSET 8 ++#define RTL8367C_BOND_BOID0_MASK 0x100 ++#define RTL8367C_BOND_SYSCLK_OFFSET 7 ++#define RTL8367C_BOND_SYSCLK_MASK 0x80 ++#define RTL8367C_BOND_PHYMODE_OFFSET 6 ++#define RTL8367C_BOND_PHYMODE_MASK 0x40 ++#define RTL8367C_BOND_DIS_PON_BIST_OFFSET 5 ++#define RTL8367C_BOND_DIS_PON_BIST_MASK 0x20 ++#define RTL8367C_BOND_DIS_TABLE_INIT_OFFSET 4 ++#define RTL8367C_BOND_DIS_TABLE_INIT_MASK 0x10 ++#define RTL8367C_BOND_BYP_AFE_PLL_OFFSET 3 ++#define RTL8367C_BOND_BYP_AFE_PLL_MASK 0x8 ++#define RTL8367C_BOND_BYP_AFE_POR_OFFSET 2 ++#define RTL8367C_BOND_BYP_AFE_POR_MASK 0x4 ++#define RTL8367C_BOND_BISR_COND_OFFSET 1 ++#define RTL8367C_BOND_BISR_COND_MASK 0x2 ++#define RTL8367C_BOND_EF_EN_OFFSET 0 ++#define RTL8367C_BOND_EF_EN_MASK 0x1 ++ ++#define RTL8367C_REG_REG_TO_ECO0 0x1d3d ++ ++#define RTL8367C_REG_REG_TO_ECO1 0x1d3e ++ ++#define RTL8367C_REG_REG_TO_ECO2 0x1d3f ++ ++#define RTL8367C_REG_REG_TO_ECO3 0x1d40 ++ ++#define RTL8367C_REG_REG_TO_ECO4 0x1d41 ++ ++#define RTL8367C_REG_PHYSTS_CTRL0 0x1d42 ++#define RTL8367C_MACRX_DUPDET_EN_OFFSET 5 ++#define RTL8367C_MACRX_DUPDET_EN_MASK 0x20 ++#define RTL8367C_LNKUP_DLY_EN_OFFSET 4 ++#define RTL8367C_LNKUP_DLY_EN_MASK 0x10 ++#define RTL8367C_GE_100M_LNKUP_DLY_OFFSET 2 ++#define RTL8367C_GE_100M_LNKUP_DLY_MASK 0xC ++#define RTL8367C_PHYSTS_10M_LNKUP_DLY_OFFSET 0 ++#define RTL8367C_PHYSTS_10M_LNKUP_DLY_MASK 0x3 ++ ++#define RTL8367C_REG_SSC_CTRL0_0 0x1d44 ++#define RTL8367C_SSC_CTRL0_0_SSC_TYPE_OFFSET 13 ++#define RTL8367C_SSC_CTRL0_0_SSC_TYPE_MASK 0x2000 ++#define RTL8367C_SSC_CTRL0_0_PHASE_LIM_SEL_OFFSET 5 ++#define RTL8367C_SSC_CTRL0_0_PHASE_LIM_SEL_MASK 0x1FE0 ++#define RTL8367C_SSC_CTRL0_0_PHASE_LIM_EN_OFFSET 4 ++#define RTL8367C_SSC_CTRL0_0_PHASE_LIM_EN_MASK 0x10 ++#define RTL8367C_SSC_CTRL0_0_DLL_MODE_OFFSET 2 ++#define RTL8367C_SSC_CTRL0_0_DLL_MODE_MASK 0xC ++#define RTL8367C_SSC_CTRL0_0_SSC_EN_OFFSET 1 ++#define RTL8367C_SSC_CTRL0_0_SSC_EN_MASK 0x2 ++#define RTL8367C_SSC_CTRL0_0_SSC_MODE_OFFSET 0 ++#define RTL8367C_SSC_CTRL0_0_SSC_MODE_MASK 0x1 ++ ++#define RTL8367C_REG_SSC_RDM_SEED 0x1d45 ++ ++#define RTL8367C_REG_SSC_PN_POLY_SEL 0x1d46 ++ ++#define RTL8367C_REG_SSC_CTRL0_3 0x1d47 ++#define RTL8367C_SSC_CTRL0_3_PHSFT_CNT_OFFSET 8 ++#define RTL8367C_SSC_CTRL0_3_PHSFT_CNT_MASK 0x7F00 ++#define RTL8367C_SSC_CTRL0_3_PHSFT_A_OFFSET 7 ++#define RTL8367C_SSC_CTRL0_3_PHSFT_A_MASK 0x80 ++#define RTL8367C_SSC_CTRL0_3_PHSFT_B_OFFSET 6 ++#define RTL8367C_SSC_CTRL0_3_PHSFT_B_MASK 0x40 ++#define RTL8367C_SSC_CTRL0_3_PHSFT_UPDN_OFFSET 5 ++#define RTL8367C_SSC_CTRL0_3_PHSFT_UPDN_MASK 0x20 ++#define RTL8367C_SSC_CTRL0_3_PHSFT_PRD_OFFSET 4 ++#define RTL8367C_SSC_CTRL0_3_PHSFT_PRD_MASK 0x10 ++#define RTL8367C_SSC_CTRL0_3_PN_POLY_DEG_OFFSET 0 ++#define RTL8367C_SSC_CTRL0_3_PN_POLY_DEG_MASK 0xF ++ ++#define RTL8367C_REG_SSC_CTRL0_4 0x1d48 ++#define RTL8367C_SSC_CTRL0_4_SSC_UP1DN0_OFFSET 15 ++#define RTL8367C_SSC_CTRL0_4_SSC_UP1DN0_MASK 0x8000 ++#define RTL8367C_SSC_CTRL0_4_SSC_PERIOD_OFFSET 8 ++#define RTL8367C_SSC_CTRL0_4_SSC_PERIOD_MASK 0x7F00 ++#define RTL8367C_SSC_CTRL0_4_SSC_OFFSET_OFFSET 0 ++#define RTL8367C_SSC_CTRL0_4_SSC_OFFSET_MASK 0xFF ++ ++#define RTL8367C_REG_SSC_CTRL0_5 0x1d49 ++#define RTL8367C_SSC_CTRL0_5_PH_OFS_TOG_OFFSET 15 ++#define RTL8367C_SSC_CTRL0_5_PH_OFS_TOG_MASK 0x8000 ++#define RTL8367C_SSC_CTRL0_5_PH_OFS_OFFSET 10 ++#define RTL8367C_SSC_CTRL0_5_PH_OFS_MASK 0x7C00 ++#define RTL8367C_SSC_CTRL0_5_SSC_STEP_OFFSET 4 ++#define RTL8367C_SSC_CTRL0_5_SSC_STEP_MASK 0x3F0 ++#define RTL8367C_SSC_CTRL0_5_SSC_TEST_MODE_OFFSET 2 ++#define RTL8367C_SSC_CTRL0_5_SSC_TEST_MODE_MASK 0xC ++#define RTL8367C_SSC_CTRL0_5_SSC_PH_CFG_OFFSET 0 ++#define RTL8367C_SSC_CTRL0_5_SSC_PH_CFG_MASK 0x3 ++ ++#define RTL8367C_REG_SSC_STS0 0x1d4a ++#define RTL8367C_SSC_STS0_OFS_BUSY_OFFSET 13 ++#define RTL8367C_SSC_STS0_OFS_BUSY_MASK 0x2000 ++#define RTL8367C_SSC_STS0_OFS_TOTAL_R_OFFSET 8 ++#define RTL8367C_SSC_STS0_OFS_TOTAL_R_MASK 0x1F00 ++#define RTL8367C_SSC_STS0_CNT_GRY0_OFFSET 4 ++#define RTL8367C_SSC_STS0_CNT_GRY0_MASK 0xF0 ++#define RTL8367C_SSC_STS0_OFS_GRY0_OFFSET 0 ++#define RTL8367C_SSC_STS0_OFS_GRY0_MASK 0xF ++ ++#define RTL8367C_REG_SSC_CTRL1_0 0x1d4b ++#define RTL8367C_SSC_CTRL1_0_SSC_TYPE_OFFSET 13 ++#define RTL8367C_SSC_CTRL1_0_SSC_TYPE_MASK 0x2000 ++#define RTL8367C_SSC_CTRL1_0_PHASE_LIM_SEL_OFFSET 5 ++#define RTL8367C_SSC_CTRL1_0_PHASE_LIM_SEL_MASK 0x1FE0 ++#define RTL8367C_SSC_CTRL1_0_PHASE_LIM_EN_OFFSET 4 ++#define RTL8367C_SSC_CTRL1_0_PHASE_LIM_EN_MASK 0x10 ++#define RTL8367C_SSC_CTRL1_0_DLL_MODE_OFFSET 2 ++#define RTL8367C_SSC_CTRL1_0_DLL_MODE_MASK 0xC ++#define RTL8367C_SSC_CTRL1_0_SSC_EN_OFFSET 1 ++#define RTL8367C_SSC_CTRL1_0_SSC_EN_MASK 0x2 ++#define RTL8367C_SSC_CTRL1_0_SSC_MODE_OFFSET 0 ++#define RTL8367C_SSC_CTRL1_0_SSC_MODE_MASK 0x1 ++ ++#define RTL8367C_REG_SSC_RDM_SEED1 0x1d4c ++ ++#define RTL8367C_REG_SSC_PN_POLY_SEL1 0x1d4d ++ ++#define RTL8367C_REG_SSC_CTRL1_3 0x1d4e ++#define RTL8367C_SSC_CTRL1_3_PHSFT_CNT_OFFSET 8 ++#define RTL8367C_SSC_CTRL1_3_PHSFT_CNT_MASK 0x7F00 ++#define RTL8367C_SSC_CTRL1_3_PHSFT_A_OFFSET 7 ++#define RTL8367C_SSC_CTRL1_3_PHSFT_A_MASK 0x80 ++#define RTL8367C_SSC_CTRL1_3_PHSFT_B_OFFSET 6 ++#define RTL8367C_SSC_CTRL1_3_PHSFT_B_MASK 0x40 ++#define RTL8367C_SSC_CTRL1_3_PHSFT_UPDN_OFFSET 5 ++#define RTL8367C_SSC_CTRL1_3_PHSFT_UPDN_MASK 0x20 ++#define RTL8367C_SSC_CTRL1_3_PHSFT_PRD_OFFSET 4 ++#define RTL8367C_SSC_CTRL1_3_PHSFT_PRD_MASK 0x10 ++#define RTL8367C_SSC_CTRL1_3_PN_POLY_DEG_OFFSET 0 ++#define RTL8367C_SSC_CTRL1_3_PN_POLY_DEG_MASK 0xF ++ ++#define RTL8367C_REG_SSC_CTRL1_4 0x1d4f ++#define RTL8367C_SSC_CTRL1_4_SSC_UP1DN0_OFFSET 15 ++#define RTL8367C_SSC_CTRL1_4_SSC_UP1DN0_MASK 0x8000 ++#define RTL8367C_SSC_CTRL1_4_SSC_PERIOD_OFFSET 8 ++#define RTL8367C_SSC_CTRL1_4_SSC_PERIOD_MASK 0x7F00 ++#define RTL8367C_SSC_CTRL1_4_SSC_OFFSET_OFFSET 0 ++#define RTL8367C_SSC_CTRL1_4_SSC_OFFSET_MASK 0xFF ++ ++#define RTL8367C_REG_SSC_CTRL1_5 0x1d50 ++#define RTL8367C_SSC_CTRL1_5_PH_OFS_TOG_OFFSET 15 ++#define RTL8367C_SSC_CTRL1_5_PH_OFS_TOG_MASK 0x8000 ++#define RTL8367C_SSC_CTRL1_5_PH_OFS_OFFSET 10 ++#define RTL8367C_SSC_CTRL1_5_PH_OFS_MASK 0x7C00 ++#define RTL8367C_SSC_CTRL1_5_SSC_STEP_OFFSET 4 ++#define RTL8367C_SSC_CTRL1_5_SSC_STEP_MASK 0x3F0 ++#define RTL8367C_SSC_CTRL1_5_SSC_TEST_MODE_OFFSET 2 ++#define RTL8367C_SSC_CTRL1_5_SSC_TEST_MODE_MASK 0xC ++#define RTL8367C_SSC_CTRL1_5_SSC_PH_CFG_OFFSET 0 ++#define RTL8367C_SSC_CTRL1_5_SSC_PH_CFG_MASK 0x3 ++ ++#define RTL8367C_REG_SSC_STS1 0x1d51 ++#define RTL8367C_SSC_STS1_OFS_BUSY_OFFSET 13 ++#define RTL8367C_SSC_STS1_OFS_BUSY_MASK 0x2000 ++#define RTL8367C_SSC_STS1_OFS_TOTAL_R_OFFSET 8 ++#define RTL8367C_SSC_STS1_OFS_TOTAL_R_MASK 0x1F00 ++#define RTL8367C_SSC_STS1_CNT_GRY0_OFFSET 4 ++#define RTL8367C_SSC_STS1_CNT_GRY0_MASK 0xF0 ++#define RTL8367C_SSC_STS1_OFS_GRY0_OFFSET 0 ++#define RTL8367C_SSC_STS1_OFS_GRY0_MASK 0xF ++ ++#define RTL8367C_REG_SSC_CTRL2_0 0x1d52 ++#define RTL8367C_SSC_CTRL2_0_SSC_TYPE_OFFSET 13 ++#define RTL8367C_SSC_CTRL2_0_SSC_TYPE_MASK 0x2000 ++#define RTL8367C_SSC_CTRL2_0_PHASE_LIM_SEL_OFFSET 5 ++#define RTL8367C_SSC_CTRL2_0_PHASE_LIM_SEL_MASK 0x1FE0 ++#define RTL8367C_SSC_CTRL2_0_PHASE_LIM_EN_OFFSET 4 ++#define RTL8367C_SSC_CTRL2_0_PHASE_LIM_EN_MASK 0x10 ++#define RTL8367C_SSC_CTRL2_0_DLL_MODE_OFFSET 2 ++#define RTL8367C_SSC_CTRL2_0_DLL_MODE_MASK 0xC ++#define RTL8367C_SSC_CTRL2_0_SSC_EN_OFFSET 1 ++#define RTL8367C_SSC_CTRL2_0_SSC_EN_MASK 0x2 ++#define RTL8367C_SSC_CTRL2_0_SSC_MODE_OFFSET 0 ++#define RTL8367C_SSC_CTRL2_0_SSC_MODE_MASK 0x1 ++ ++#define RTL8367C_REG_SSC_RDM_SEED2 0x1d53 ++ ++#define RTL8367C_REG_SSC_PN_POLY_SEL2 0x1d54 ++ ++#define RTL8367C_REG_SSC_CTRL2_3 0x1d55 ++#define RTL8367C_SSC_CTRL2_3_PHSFT_CNT_OFFSET 8 ++#define RTL8367C_SSC_CTRL2_3_PHSFT_CNT_MASK 0x7F00 ++#define RTL8367C_SSC_CTRL2_3_PHSFT_A_OFFSET 7 ++#define RTL8367C_SSC_CTRL2_3_PHSFT_A_MASK 0x80 ++#define RTL8367C_SSC_CTRL2_3_PHSFT_B_OFFSET 6 ++#define RTL8367C_SSC_CTRL2_3_PHSFT_B_MASK 0x40 ++#define RTL8367C_SSC_CTRL2_3_PHSFT_UPDN_OFFSET 5 ++#define RTL8367C_SSC_CTRL2_3_PHSFT_UPDN_MASK 0x20 ++#define RTL8367C_SSC_CTRL2_3_PHSFT_PRD_OFFSET 4 ++#define RTL8367C_SSC_CTRL2_3_PHSFT_PRD_MASK 0x10 ++#define RTL8367C_SSC_CTRL2_3_PN_POLY_DEG_OFFSET 0 ++#define RTL8367C_SSC_CTRL2_3_PN_POLY_DEG_MASK 0xF ++ ++#define RTL8367C_REG_SSC_CTRL2_4 0x1d56 ++#define RTL8367C_SSC_CTRL2_4_SSC_UP1DN0_OFFSET 15 ++#define RTL8367C_SSC_CTRL2_4_SSC_UP1DN0_MASK 0x8000 ++#define RTL8367C_SSC_CTRL2_4_SSC_PERIOD_OFFSET 8 ++#define RTL8367C_SSC_CTRL2_4_SSC_PERIOD_MASK 0x7F00 ++#define RTL8367C_SSC_CTRL2_4_SSC_OFFSET_OFFSET 0 ++#define RTL8367C_SSC_CTRL2_4_SSC_OFFSET_MASK 0xFF ++ ++#define RTL8367C_REG_SSC_CTRL2_5 0x1d57 ++#define RTL8367C_SSC_CTRL2_5_PH_OFS_TOG_OFFSET 15 ++#define RTL8367C_SSC_CTRL2_5_PH_OFS_TOG_MASK 0x8000 ++#define RTL8367C_SSC_CTRL2_5_PH_OFS_OFFSET 10 ++#define RTL8367C_SSC_CTRL2_5_PH_OFS_MASK 0x7C00 ++#define RTL8367C_SSC_CTRL2_5_SSC_STEP_OFFSET 4 ++#define RTL8367C_SSC_CTRL2_5_SSC_STEP_MASK 0x3F0 ++#define RTL8367C_SSC_CTRL2_5_SSC_TEST_MODE_OFFSET 2 ++#define RTL8367C_SSC_CTRL2_5_SSC_TEST_MODE_MASK 0xC ++#define RTL8367C_SSC_CTRL2_5_SSC_PH_CFG_OFFSET 0 ++#define RTL8367C_SSC_CTRL2_5_SSC_PH_CFG_MASK 0x3 ++ ++#define RTL8367C_REG_SSC_STS2 0x1d58 ++#define RTL8367C_SSC_STS2_OFS_BUSY_OFFSET 13 ++#define RTL8367C_SSC_STS2_OFS_BUSY_MASK 0x2000 ++#define RTL8367C_SSC_STS2_OFS_TOTAL_R_OFFSET 8 ++#define RTL8367C_SSC_STS2_OFS_TOTAL_R_MASK 0x1F00 ++#define RTL8367C_SSC_STS2_CNT_GRY0_OFFSET 4 ++#define RTL8367C_SSC_STS2_CNT_GRY0_MASK 0xF0 ++#define RTL8367C_SSC_STS2_OFS_GRY0_OFFSET 0 ++#define RTL8367C_SSC_STS2_OFS_GRY0_MASK 0xF ++ ++#define RTL8367C_REG_SSC_CTRL3_0 0x1d59 ++#define RTL8367C_SSC_CTRL3_0_SSC_TYPE_OFFSET 13 ++#define RTL8367C_SSC_CTRL3_0_SSC_TYPE_MASK 0x2000 ++#define RTL8367C_SSC_CTRL3_0_PHASE_LIM_SEL_OFFSET 5 ++#define RTL8367C_SSC_CTRL3_0_PHASE_LIM_SEL_MASK 0x1FE0 ++#define RTL8367C_SSC_CTRL3_0_PHASE_LIM_EN_OFFSET 4 ++#define RTL8367C_SSC_CTRL3_0_PHASE_LIM_EN_MASK 0x10 ++#define RTL8367C_SSC_CTRL3_0_DLL_MODE_OFFSET 2 ++#define RTL8367C_SSC_CTRL3_0_DLL_MODE_MASK 0xC ++#define RTL8367C_SSC_CTRL3_0_SSC_EN_OFFSET 1 ++#define RTL8367C_SSC_CTRL3_0_SSC_EN_MASK 0x2 ++#define RTL8367C_SSC_CTRL3_0_SSC_MODE_OFFSET 0 ++#define RTL8367C_SSC_CTRL3_0_SSC_MODE_MASK 0x1 ++ ++#define RTL8367C_REG_SSC_RDM_SEED3 0x1d5a ++ ++#define RTL8367C_REG_SSC_PN_POLY_SEL3 0x1d5b ++ ++#define RTL8367C_REG_SSC_CTRL3_3 0x1d5c ++#define RTL8367C_SSC_CTRL3_3_PHSFT_CNT_OFFSET 8 ++#define RTL8367C_SSC_CTRL3_3_PHSFT_CNT_MASK 0x7F00 ++#define RTL8367C_SSC_CTRL3_3_PHSFT_A_OFFSET 7 ++#define RTL8367C_SSC_CTRL3_3_PHSFT_A_MASK 0x80 ++#define RTL8367C_SSC_CTRL3_3_PHSFT_B_OFFSET 6 ++#define RTL8367C_SSC_CTRL3_3_PHSFT_B_MASK 0x40 ++#define RTL8367C_SSC_CTRL3_3_PHSFT_UPDN_OFFSET 5 ++#define RTL8367C_SSC_CTRL3_3_PHSFT_UPDN_MASK 0x20 ++#define RTL8367C_SSC_CTRL3_3_PHSFT_PRD_OFFSET 4 ++#define RTL8367C_SSC_CTRL3_3_PHSFT_PRD_MASK 0x10 ++#define RTL8367C_SSC_CTRL3_3_PN_POLY_DEG_OFFSET 0 ++#define RTL8367C_SSC_CTRL3_3_PN_POLY_DEG_MASK 0xF ++ ++#define RTL8367C_REG_SSC_CTRL3_4 0x1d5d ++#define RTL8367C_SSC_CTRL3_4_SSC_UP1DN0_OFFSET 15 ++#define RTL8367C_SSC_CTRL3_4_SSC_UP1DN0_MASK 0x8000 ++#define RTL8367C_SSC_CTRL3_4_SSC_PERIOD_OFFSET 8 ++#define RTL8367C_SSC_CTRL3_4_SSC_PERIOD_MASK 0x7F00 ++#define RTL8367C_SSC_CTRL3_4_SSC_OFFSET_OFFSET 0 ++#define RTL8367C_SSC_CTRL3_4_SSC_OFFSET_MASK 0xFF ++ ++#define RTL8367C_REG_SSC_CTRL3_5 0x1d5e ++#define RTL8367C_SSC_CTRL3_5_PH_OFS_TOG_OFFSET 15 ++#define RTL8367C_SSC_CTRL3_5_PH_OFS_TOG_MASK 0x8000 ++#define RTL8367C_SSC_CTRL3_5_PH_OFS_OFFSET 10 ++#define RTL8367C_SSC_CTRL3_5_PH_OFS_MASK 0x7C00 ++#define RTL8367C_SSC_CTRL3_5_SSC_STEP_OFFSET 4 ++#define RTL8367C_SSC_CTRL3_5_SSC_STEP_MASK 0x3F0 ++#define RTL8367C_SSC_CTRL3_5_SSC_TEST_MODE_OFFSET 2 ++#define RTL8367C_SSC_CTRL3_5_SSC_TEST_MODE_MASK 0xC ++#define RTL8367C_SSC_CTRL3_5_SSC_PH_CFG_OFFSET 0 ++#define RTL8367C_SSC_CTRL3_5_SSC_PH_CFG_MASK 0x3 ++ ++#define RTL8367C_REG_SSC_STS3 0x1d5f ++#define RTL8367C_SSC_STS3_OFS_BUSY_OFFSET 13 ++#define RTL8367C_SSC_STS3_OFS_BUSY_MASK 0x2000 ++#define RTL8367C_SSC_STS3_OFS_TOTAL_R_OFFSET 8 ++#define RTL8367C_SSC_STS3_OFS_TOTAL_R_MASK 0x1F00 ++#define RTL8367C_SSC_STS3_CNT_GRY0_OFFSET 4 ++#define RTL8367C_SSC_STS3_CNT_GRY0_MASK 0xF0 ++#define RTL8367C_SSC_STS3_OFS_GRY0_OFFSET 0 ++#define RTL8367C_SSC_STS3_OFS_GRY0_MASK 0xF ++ ++#define RTL8367C_REG_PHY_POLL_CFG13 0x1d60 ++ ++#define RTL8367C_REG_PHY_POLL_CFG14 0x1d61 ++ ++#define RTL8367C_REG_FRC_SYS_CLK 0x1d62 ++#define RTL8367C_SYSCLK_FRC_MD_OFFSET 1 ++#define RTL8367C_SYSCLK_FRC_MD_MASK 0x2 ++#define RTL8367C_SYSCLK_FRC_VAL_OFFSET 0 ++#define RTL8367C_SYSCLK_FRC_VAL_MASK 0x1 ++ ++#define RTL8367C_REG_AFE_SSC_CTRL 0x1d63 ++#define RTL8367C_PH_RSTB_TXD1_OFFSET 9 ++#define RTL8367C_PH_RSTB_TXD1_MASK 0x200 ++#define RTL8367C_PH_RSTB_TXC1_OFFSET 8 ++#define RTL8367C_PH_RSTB_TXC1_MASK 0x100 ++#define RTL8367C_PH_RSTB_TXD0_OFFSET 7 ++#define RTL8367C_PH_RSTB_TXD0_MASK 0x80 ++#define RTL8367C_PH_RSTB_TXC0_OFFSET 6 ++#define RTL8367C_PH_RSTB_TXC0_MASK 0x40 ++#define RTL8367C_PH_RSTBSYS_OFFSET 5 ++#define RTL8367C_PH_RSTBSYS_MASK 0x20 ++#define RTL8367C_PH_RSTB8051_OFFSET 4 ++#define RTL8367C_PH_RSTB8051_MASK 0x10 ++#define RTL8367C_OREG_SSC_OFFSET 0 ++#define RTL8367C_OREG_SSC_MASK 0xF ++ ++#define RTL8367C_REG_BUFF_RST_CTRL0 0x1d64 ++#define RTL8367C_BUFFRST_TXESD_EN_OFFSET 13 ++#define RTL8367C_BUFFRST_TXESD_EN_MASK 0x2000 ++#define RTL8367C_BUFF_RST_TIME_LONG_OFFSET 8 ++#define RTL8367C_BUFF_RST_TIME_LONG_MASK 0x1F00 ++#define RTL8367C_BUFF_RST_TIME_SHORT_OFFSET 3 ++#define RTL8367C_BUFF_RST_TIME_SHORT_MASK 0xF8 ++#define RTL8367C_SW_BUFF_RST_OFFSET 2 ++#define RTL8367C_SW_BUFF_RST_MASK 0x4 ++#define RTL8367C_IMS_BUFF_RST_OFFSET 1 ++#define RTL8367C_IMS_BUFF_RST_MASK 0x2 ++#define RTL8367C_IMR_BUFF_RST_OFFSET 0 ++#define RTL8367C_IMR_BUFF_RST_MASK 0x1 ++ ++#define RTL8367C_REG_BUFF_RST_CTRL1 0x1d65 ++#define RTL8367C_BUFFRST_SYSOVER_EN_OFFSET 10 ++#define RTL8367C_BUFFRST_SYSOVER_EN_MASK 0x400 ++#define RTL8367C_BUFFRST_SYSOVER_THR_OFFSET 0 ++#define RTL8367C_BUFFRST_SYSOVER_THR_MASK 0x3FF ++ ++#define RTL8367C_REG_BUFF_RST_CTRL2 0x1d66 ++#define RTL8367C_BUFFRST_QOVER_EN_OFFSET 10 ++#define RTL8367C_BUFFRST_QOVER_EN_MASK 0x400 ++#define RTL8367C_BUFFRST_QOVER_THR_OFFSET 0 ++#define RTL8367C_BUFFRST_QOVER_THR_MASK 0x3FF ++ ++#define RTL8367C_REG_BUFF_RST_CTRL3 0x1d67 ++#define RTL8367C_DSC_TIMER_OFFSET 11 ++#define RTL8367C_DSC_TIMER_MASK 0x7800 ++#define RTL8367C_BUFFRST_DSCOVER_THR_OFFSET 1 ++#define RTL8367C_BUFFRST_DSCOVER_THR_MASK 0x7FE ++#define RTL8367C_BUFFRST_DSCOVER_EN_OFFSET 0 ++#define RTL8367C_BUFFRST_DSCOVER_EN_MASK 0x1 ++ ++#define RTL8367C_REG_BUFF_RST_CTRL4 0x1d68 ++#define RTL8367C_INDSC_TIMER_OFFSET 11 ++#define RTL8367C_INDSC_TIMER_MASK 0x7800 ++#define RTL8367C_BUFFRST_INDSCOVER_THR_OFFSET 1 ++#define RTL8367C_BUFFRST_INDSCOVER_THR_MASK 0x7FE ++#define RTL8367C_BUFFRST_INDSCOVER_EN_OFFSET 0 ++#define RTL8367C_BUFFRST_INDSCOVER_EN_MASK 0x1 ++ ++#define RTL8367C_REG_BUFF_RST_CTRL5 0x1d69 ++#define RTL8367C_TX_ESD_MODE_OFFSET 8 ++#define RTL8367C_TX_ESD_MODE_MASK 0x100 ++#define RTL8367C_TX_ESD_LVL_OFFSET 0 ++#define RTL8367C_TX_ESD_LVL_MASK 0xFF ++ ++#define RTL8367C_REG_TOP_CON0 0x1d70 ++#define RTL8367C_TOP_CON0_SDS_PWR_ISO_1_OFFSET 15 ++#define RTL8367C_TOP_CON0_SDS_PWR_ISO_1_MASK 0x8000 ++#define RTL8367C_OCP_TIMEOUT_P7_5_OFFSET 12 ++#define RTL8367C_OCP_TIMEOUT_P7_5_MASK 0x7000 ++#define RTL8367C_FIB_EEE_AB_OFFSET 11 ++#define RTL8367C_FIB_EEE_AB_MASK 0x800 ++#define RTL8367C_ADCCKIEN_OFFSET 10 ++#define RTL8367C_ADCCKIEN_MASK 0x400 ++#define RTL8367C_OCP_TIMEOUT_OFFSET 5 ++#define RTL8367C_OCP_TIMEOUT_MASK 0x3E0 ++#define RTL8367C_TOP_CON0_SDS_PWR_ISO_OFFSET 4 ++#define RTL8367C_TOP_CON0_SDS_PWR_ISO_MASK 0x10 ++#define RTL8367C_RG2_TXC_SEL_OFFSET 3 ++#define RTL8367C_RG2_TXC_SEL_MASK 0x8 ++#define RTL8367C_RG1TXC_SEL_OFFSET 2 ++#define RTL8367C_RG1TXC_SEL_MASK 0x4 ++#define RTL8367C_SYNC_1588_EN_OFFSET 1 ++#define RTL8367C_SYNC_1588_EN_MASK 0x2 ++#define RTL8367C_LS_MODE_OFFSET 0 ++#define RTL8367C_LS_MODE_MASK 0x1 ++ ++#define RTL8367C_REG_TOP_CON1 0x1d71 ++#define RTL8367C_TA_CHK_EN_OFFSET 2 ++#define RTL8367C_TA_CHK_EN_MASK 0x4 ++#define RTL8367C_SLV_EG_SEL_OFFSET 1 ++#define RTL8367C_SLV_EG_SEL_MASK 0x2 ++#define RTL8367C_IIC_OP_DRAIN_OFFSET 0 ++#define RTL8367C_IIC_OP_DRAIN_MASK 0x1 ++ ++#define RTL8367C_REG_SWR_FPWM 0x1d72 ++#define RTL8367C_SWR_FPWM_OFFSET 0 ++#define RTL8367C_SWR_FPWM_MASK 0x1 ++ ++#define RTL8367C_REG_EEEP_CTRL_500M 0x1d73 ++ ++#define RTL8367C_REG_SHORT_PRMB 0x1d74 ++#define RTL8367C_SHORT_PRMB_OFFSET 0 ++#define RTL8367C_SHORT_PRMB_MASK 0x1 ++ ++#define RTL8367C_REG_INDSC_THR_CTRL 0x1d75 ++#define RTL8367C_INDSC_THR_CTRL_OFFSET 0 ++#define RTL8367C_INDSC_THR_CTRL_MASK 0x7FF ++ ++#define RTL8367C_REG_SET_PAD_CTRL_NEW 0x1d80 ++#define RTL8367C_SET_PAD_CTRL_NEW_OFFSET 0 ++#define RTL8367C_SET_PAD_CTRL_NEW_MASK 0x1 ++ ++#define RTL8367C_REG_SET_PAD_DRI_0 0x1d81 ++ ++#define RTL8367C_REG_SET_PAD_DRI_1 0x1d82 ++ ++#define RTL8367C_REG_SET_PAD_DRI_2 0x1d83 ++ ++#define RTL8367C_REG_SET_PAD_SLEW_0 0x1d84 ++ ++#define RTL8367C_REG_SET_PAD_SLEW_1 0x1d85 ++ ++#define RTL8367C_REG_SET_PAD_SLEW_2 0x1d86 ++ ++#define RTL8367C_REG_SET_PAD_SMT_0 0x1d87 ++ ++#define RTL8367C_REG_SET_PAD_SMT_1 0x1d88 ++ ++#define RTL8367C_REG_SET_PAD_SMT_2 0x1d89 ++ ++#define RTL8367C_REG_M_I2C_CTL_STA_REG 0x1d8a ++#define RTL8367C_TX_RX_DATA_OFFSET 8 ++#define RTL8367C_TX_RX_DATA_MASK 0xFF00 ++#define RTL8367C_DUMB_RW_ERR_OFFSET 7 ++#define RTL8367C_DUMB_RW_ERR_MASK 0x80 ++#define RTL8367C_SLV_ACK_FLAG_OFFSET 6 ++#define RTL8367C_SLV_ACK_FLAG_MASK 0x40 ++#define RTL8367C_M_I2C_BUS_IDLE_OFFSET 5 ++#define RTL8367C_M_I2C_BUS_IDLE_MASK 0x20 ++#define RTL8367C_I2C_CMD_TYPE_OFFSET 1 ++#define RTL8367C_I2C_CMD_TYPE_MASK 0x1E ++#define RTL8367C_I2C_CMD_EXEC_OFFSET 0 ++#define RTL8367C_I2C_CMD_EXEC_MASK 0x1 ++ ++#define RTL8367C_REG_M_I2C_DUMB_RW_ADDR_0 0x1d8b ++ ++#define RTL8367C_REG_M_I2C_DUMB_RW_ADDR_1 0x1d8c ++ ++#define RTL8367C_REG_M_I2C_DUMB_RW_DATA_0 0x1d8d ++ ++#define RTL8367C_REG_M_I2C_DUMB_RW_DATA_1 0x1d8e ++ ++#define RTL8367C_REG_M_I2C_DUMB_RW_CTL 0x1d8f ++#define RTL8367C_DUMB_I2C_CTL_CODE_OFFSET 8 ++#define RTL8367C_DUMB_I2C_CTL_CODE_MASK 0x7F00 ++#define RTL8367C_DUMB_RW_I2C_FORMAT_OFFSET 4 ++#define RTL8367C_DUMB_RW_I2C_FORMAT_MASK 0x10 ++#define RTL8367C_DUMB_RW_DATA_MODE_OFFSET 2 ++#define RTL8367C_DUMB_RW_DATA_MODE_MASK 0xC ++#define RTL8367C_DUMB_RW_ADDR_MODE_OFFSET 0 ++#define RTL8367C_DUMB_RW_ADDR_MODE_MASK 0x3 ++ ++#define RTL8367C_REG_M_I2C_SYS_CTL 0x1d90 ++#define RTL8367C_M_I2C_SCL_IO_MUX_OFFSET 12 ++#define RTL8367C_M_I2C_SCL_IO_MUX_MASK 0x3000 ++#define RTL8367C_M_I2C_SDA_IO_MUX_OFFSET 10 ++#define RTL8367C_M_I2C_SDA_IO_MUX_MASK 0xC00 ++#define RTL8367C_M_I2C_SDA_OD_EN_OFFSET 9 ++#define RTL8367C_M_I2C_SDA_OD_EN_MASK 0x200 ++#define RTL8367C_M_I2C_SCL_OD_EN_OFFSET 8 ++#define RTL8367C_M_I2C_SCL_OD_EN_MASK 0x100 ++#define RTL8367C_M_I2C_SCL_F_DIV_OFFSET 0 ++#define RTL8367C_M_I2C_SCL_F_DIV_MASK 0xFF ++ ++#define RTL8367C_REG_HT_PB_SRAM_CTRL 0x1da0 ++#define RTL8367C_HTPB_RW_OFFSET 2 ++#define RTL8367C_HTPB_RW_MASK 0x4 ++#define RTL8367C_HTPB_SEL_OFFSET 1 ++#define RTL8367C_HTPB_SEL_MASK 0x2 ++#define RTL8367C_HTPB_CE_OFFSET 0 ++#define RTL8367C_HTPB_CE_MASK 0x1 ++ ++#define RTL8367C_REG_HT_PB_SRAM_ADDR 0x1da1 ++ ++#define RTL8367C_REG_HT_PB_SRAM_DIN0 0x1da2 ++ ++#define RTL8367C_REG_HT_PB_SRAM_DIN1 0x1da3 ++ ++#define RTL8367C_REG_HT_PB_SRAM_DOUT0 0x1da4 ++ ++#define RTL8367C_REG_HT_PB_SRAM_DOUT1 0x1da5 ++ ++#define RTL8367C_REG_PHY_STAT_0 0x1db0 ++ ++#define RTL8367C_REG_PHY_STAT_1 0x1db1 ++ ++#define RTL8367C_REG_PHY_STAT_2 0x1db2 ++ ++#define RTL8367C_REG_PHY_STAT_3 0x1db3 ++ ++#define RTL8367C_REG_PHY_STAT_4 0x1db4 ++ ++#define RTL8367C_REG_PHY_STAT_5 0x1db5 ++ ++#define RTL8367C_REG_PHY_STAT_6 0x1db6 ++ ++#define RTL8367C_REG_PHY_STAT_7 0x1db7 ++ ++#define RTL8367C_REG_SDS_STAT_0 0x1db8 ++ ++#define RTL8367C_REG_SDS_STAT_1 0x1db9 ++ ++#define RTL8367C_REG_MAC_LINK_STAT_0 0x1dba ++#define RTL8367C_MAC_LINK_STAT_CUR_0_OFFSET 8 ++#define RTL8367C_MAC_LINK_STAT_CUR_0_MASK 0xFF00 ++#define RTL8367C_MAC_LINK_STAT_LATCH_0_OFFSET 0 ++#define RTL8367C_MAC_LINK_STAT_LATCH_0_MASK 0xFF ++ ++#define RTL8367C_REG_MAC_LINK_STAT_1 0x1dbb ++#define RTL8367C_MAC_LINK_STAT_1_Reserved_OFFSET 6 ++#define RTL8367C_MAC_LINK_STAT_1_Reserved_MASK 0xFFC0 ++#define RTL8367C_MAC_LINK_STAT_CUR_1_OFFSET 3 ++#define RTL8367C_MAC_LINK_STAT_CUR_1_MASK 0x38 ++#define RTL8367C_MAC_LINK_STAT_LATCH_1_OFFSET 0 ++#define RTL8367C_MAC_LINK_STAT_LATCH_1_MASK 0x7 ++ ++#define RTL8367C_REG_MISC_CONTROL_1 0x1dc0 ++#define RTL8367C_P7_FB_CPL_OFFSET 2 ++#define RTL8367C_P7_FB_CPL_MASK 0x4 ++#define RTL8367C_P6_FB_CPL_OFFSET 1 ++#define RTL8367C_P6_FB_CPL_MASK 0x2 ++#define RTL8367C_P5_FB_CPL_OFFSET 0 ++#define RTL8367C_P5_FB_CPL_MASK 0x1 ++ ++#define RTL8367C_REG_SDS_MISC_1 0x1dc1 ++#define RTL8367C_CFG_SGMII_RXFC_1_OFFSET 14 ++#define RTL8367C_CFG_SGMII_RXFC_1_MASK 0x4000 ++#define RTL8367C_CFG_SGMII_TXFC_1_OFFSET 13 ++#define RTL8367C_CFG_SGMII_TXFC_1_MASK 0x2000 ++#define RTL8367C_CFG_MAC9_SEL_HSGMII_OFFSET 11 ++#define RTL8367C_CFG_MAC9_SEL_HSGMII_MASK 0x800 ++#define RTL8367C_CFG_SGMII_FDUP_1_OFFSET 10 ++#define RTL8367C_CFG_SGMII_FDUP_1_MASK 0x400 ++#define RTL8367C_CFG_SGMII_LINK_1_OFFSET 9 ++#define RTL8367C_CFG_SGMII_LINK_1_MASK 0x200 ++#define RTL8367C_CFG_SGMII_SPD_1_OFFSET 7 ++#define RTL8367C_CFG_SGMII_SPD_1_MASK 0x180 ++#define RTL8367C_CFG_MAC9_SEL_SGMII_OFFSET 6 ++#define RTL8367C_CFG_MAC9_SEL_SGMII_MASK 0x40 ++#define RTL8367C_CFG_SDS_MODE_14C_1_OFFSET 0 ++#define RTL8367C_CFG_SDS_MODE_14C_1_MASK 0x7 ++ ++#define RTL8367C_REG_FIBER_CFG_2_1 0x1dc2 ++#define RTL8367C_SDS_RX_DISABLE_1_OFFSET 6 ++#define RTL8367C_SDS_RX_DISABLE_1_MASK 0xC0 ++#define RTL8367C_SDS_TX_DISABLE_1_OFFSET 4 ++#define RTL8367C_SDS_TX_DISABLE_1_MASK 0x30 ++#define RTL8367C_FIBER_CFG_2_1_SDS_PWR_ISO_1_OFFSET 2 ++#define RTL8367C_FIBER_CFG_2_1_SDS_PWR_ISO_1_MASK 0xC ++#define RTL8367C_SDS_FRC_LD_1_OFFSET 0 ++#define RTL8367C_SDS_FRC_LD_1_MASK 0x3 ++ ++#define RTL8367C_REG_FIBER_CFG_1_1 0x1dc3 ++#define RTL8367C_SDS_FRC_REG4_1_OFFSET 12 ++#define RTL8367C_SDS_FRC_REG4_1_MASK 0x1000 ++#define RTL8367C_SDS_FRC_REG4_FIB100_1_OFFSET 11 ++#define RTL8367C_SDS_FRC_REG4_FIB100_1_MASK 0x800 ++#define RTL8367C_SDS_FRC_MODE_1_OFFSET 3 ++#define RTL8367C_SDS_FRC_MODE_1_MASK 0x8 ++#define RTL8367C_SDS_MODE_1_OFFSET 0 ++#define RTL8367C_SDS_MODE_1_MASK 0x7 ++ ++#define RTL8367C_REG_PHYSTS_CTRL0_1 0x1dc4 ++#define RTL8367C_LNKUP_DLY_EN_EXT2_OFFSET 9 ++#define RTL8367C_LNKUP_DLY_EN_EXT2_MASK 0x200 ++#define RTL8367C_GE_100M_LNKUP_DLY_EXT2_OFFSET 7 ++#define RTL8367C_GE_100M_LNKUP_DLY_EXT2_MASK 0x180 ++#define RTL8367C_PHYSTS_10M_LNKUP_DLY_EXT2_OFFSET 5 ++#define RTL8367C_PHYSTS_10M_LNKUP_DLY_EXT2_MASK 0x60 ++#define RTL8367C_LNKUP_DLY_EN_EXT1_OFFSET 4 ++#define RTL8367C_LNKUP_DLY_EN_EXT1_MASK 0x10 ++#define RTL8367C_GE_100M_LNKUP_DLY_EXT1_OFFSET 2 ++#define RTL8367C_GE_100M_LNKUP_DLY_EXT1_MASK 0xC ++#define RTL8367C_PHYSTS_10M_LNKUP_DLY_EXT1_OFFSET 0 ++#define RTL8367C_PHYSTS_10M_LNKUP_DLY_EXT1_MASK 0x3 ++ ++#define RTL8367C_REG_FIBER_CFG_3_1 0x1dc5 ++#define RTL8367C_FIBER_CFG_3_1_OFFSET 0 ++#define RTL8367C_FIBER_CFG_3_1_MASK 0xFFF ++ ++#define RTL8367C_REG_FIBER_CFG_4_1 0x1dc6 ++ ++#define RTL8367C_REG_BUFF_RST_CTRL2_2 0x1dc7 ++#define RTL8367C_Cfg_buffrst_sysover_thr_1_OFFSET 3 ++#define RTL8367C_Cfg_buffrst_sysover_thr_1_MASK 0x8 ++#define RTL8367C_Cfg_buffrst_qover_thr_OFFSET 2 ++#define RTL8367C_Cfg_buffrst_qover_thr_MASK 0x4 ++#define RTL8367C_Cfg_buffrst_indscover_thr_1_OFFSET 1 ++#define RTL8367C_Cfg_buffrst_indscover_thr_1_MASK 0x2 ++#define RTL8367C_Cfg_buffrst_dscover_thr_1_OFFSET 0 ++#define RTL8367C_Cfg_buffrst_dscover_thr_1_MASK 0x1 ++ ++#define RTL8367C_REG_PHY_DEBUG_CNT_CTRL 0x1dc8 ++#define RTL8367C_PHY_MIB_RST_7_OFFSET 15 ++#define RTL8367C_PHY_MIB_RST_7_MASK 0x8000 ++#define RTL8367C_PHY_MIB_RST_6_OFFSET 14 ++#define RTL8367C_PHY_MIB_RST_6_MASK 0x4000 ++#define RTL8367C_PHY_MIB_RST_5_OFFSET 13 ++#define RTL8367C_PHY_MIB_RST_5_MASK 0x2000 ++#define RTL8367C_PHY_MIB_RST_4_OFFSET 12 ++#define RTL8367C_PHY_MIB_RST_4_MASK 0x1000 ++#define RTL8367C_PHY_MIB_RST_3_OFFSET 11 ++#define RTL8367C_PHY_MIB_RST_3_MASK 0x800 ++#define RTL8367C_PHY_MIB_RST_2_OFFSET 10 ++#define RTL8367C_PHY_MIB_RST_2_MASK 0x400 ++#define RTL8367C_PHY_MIB_RST_1_OFFSET 9 ++#define RTL8367C_PHY_MIB_RST_1_MASK 0x200 ++#define RTL8367C_PHY_MIB_RST_0_OFFSET 8 ++#define RTL8367C_PHY_MIB_RST_0_MASK 0x100 ++#define RTL8367C_PHY_MIB_EN_7_OFFSET 7 ++#define RTL8367C_PHY_MIB_EN_7_MASK 0x80 ++#define RTL8367C_PHY_MIB_EN_6_OFFSET 6 ++#define RTL8367C_PHY_MIB_EN_6_MASK 0x40 ++#define RTL8367C_PHY_MIB_EN_5_OFFSET 5 ++#define RTL8367C_PHY_MIB_EN_5_MASK 0x20 ++#define RTL8367C_PHY_MIB_EN_4_OFFSET 4 ++#define RTL8367C_PHY_MIB_EN_4_MASK 0x10 ++#define RTL8367C_PHY_MIB_EN_3_OFFSET 3 ++#define RTL8367C_PHY_MIB_EN_3_MASK 0x8 ++#define RTL8367C_PHY_MIB_EN_2_OFFSET 2 ++#define RTL8367C_PHY_MIB_EN_2_MASK 0x4 ++#define RTL8367C_PHY_MIB_EN_1_OFFSET 1 ++#define RTL8367C_PHY_MIB_EN_1_MASK 0x2 ++#define RTL8367C_PHY_MIB_EN_0_OFFSET 0 ++#define RTL8367C_PHY_MIB_EN_0_MASK 0x1 ++ ++#define RTL8367C_REG_TXPKT_CNT_L_0 0x1dc9 ++ ++#define RTL8367C_REG_TXPKT_CNT_H_0 0x1dca ++ ++#define RTL8367C_REG_RXPKT_CNT_L_0 0x1dcb ++ ++#define RTL8367C_REG_RXPKT_CNT_H_0 0x1dcc ++ ++#define RTL8367C_REG_TX_CRC_0 0x1dcd ++ ++#define RTL8367C_REG_RX_CRC_0 0x1dce ++ ++#define RTL8367C_REG_TXPKT_CNT_L_1 0x1dcf ++ ++#define RTL8367C_REG_TXPKT_CNT_H_1 0x1dd0 ++ ++#define RTL8367C_REG_RXPKT_CNT_L_1 0x1dd1 ++ ++#define RTL8367C_REG_RXPKT_CNT_H_1 0x1dd2 ++ ++#define RTL8367C_REG_TX_CRC_1 0x1dd3 ++ ++#define RTL8367C_REG_RX_CRC_1 0x1dd4 ++ ++#define RTL8367C_REG_TXPKT_CNT_L_2 0x1dd5 ++ ++#define RTL8367C_REG_TXPKT_CNT_H_2 0x1dd6 ++ ++#define RTL8367C_REG_RXPKT_CNT_L_2 0x1dd7 ++ ++#define RTL8367C_REG_RXPKT_CNT_H_2 0x1dd8 ++ ++#define RTL8367C_REG_TX_CRC_2 0x1dd9 ++ ++#define RTL8367C_REG_RX_CRC_2 0x1dda ++ ++#define RTL8367C_REG_TXPKT_CNT_L_3 0x1ddb ++ ++#define RTL8367C_REG_TXPKT_CNT_H_3 0x1ddc ++ ++#define RTL8367C_REG_RXPKT_CNT_L_3 0x1ddd ++ ++#define RTL8367C_REG_RXPKT_CNT_H_3 0x1dde ++ ++#define RTL8367C_REG_TX_CRC_3 0x1ddf ++ ++#define RTL8367C_REG_RX_CRC_3 0x1de0 ++ ++#define RTL8367C_REG_TXPKT_CNT_L_4 0x1de1 ++ ++#define RTL8367C_REG_TXPKT_CNT_H_4 0x1de2 ++ ++#define RTL8367C_REG_RXPKT_CNT_L_4 0x1de3 ++ ++#define RTL8367C_REG_RXPKT_CNT_H_4 0x1de4 ++ ++#define RTL8367C_REG_TX_CRC_4 0x1de5 ++ ++#define RTL8367C_REG_RX_CRC_4 0x1de6 ++ ++#define RTL8367C_REG_TXPKT_CNT_L_5 0x1de7 ++ ++#define RTL8367C_REG_TXPKT_CNT_H_5 0x1de8 ++ ++#define RTL8367C_REG_RXPKT_CNT_L_5 0x1de9 ++ ++#define RTL8367C_REG_RXPKT_CNT_H_5 0x1dea ++ ++#define RTL8367C_REG_TX_CRC_5 0x1deb ++ ++#define RTL8367C_REG_RX_CRC_5 0x1dec ++ ++#define RTL8367C_REG_TXPKT_CNT_L_6 0x1ded ++ ++#define RTL8367C_REG_TXPKT_CNT_H_6 0x1dee ++ ++#define RTL8367C_REG_RXPKT_CNT_L_6 0x1def ++ ++#define RTL8367C_REG_RXPKT_CNT_H_6 0x1df0 ++ ++#define RTL8367C_REG_TX_CRC_6 0x1df1 ++ ++#define RTL8367C_REG_RX_CRC_6 0x1df2 ++ ++#define RTL8367C_REG_TXPKT_CNT_L_7 0x1df3 ++ ++#define RTL8367C_REG_TXPKT_CNT_H_7 0x1df4 ++ ++#define RTL8367C_REG_RXPKT_CNT_L_7 0x1df5 ++ ++#define RTL8367C_REG_RXPKT_CNT_H_7 0x1df6 ++ ++#define RTL8367C_REG_TX_CRC_7 0x1df7 ++ ++#define RTL8367C_REG_RX_CRC_7 0x1df8 ++ ++#define RTL8367C_REG_BOND_DBG_0 0x1df9 ++ ++#define RTL8367C_REG_BOND_DBG_1 0x1dfa ++ ++#define RTL8367C_REG_STRP_DBG_0 0x1dfb ++ ++#define RTL8367C_REG_STRP_DBG_1 0x1dfc ++ ++#define RTL8367C_REG_STRP_DBG_2 0x1dfd ++ ++/* (16'h1f00)patch_reg */ ++ ++#define RTL8367C_REG_INDRECT_ACCESS_CTRL 0x1f00 ++#define RTL8367C_RW_OFFSET 1 ++#define RTL8367C_RW_MASK 0x2 ++#define RTL8367C_CMD_OFFSET 0 ++#define RTL8367C_CMD_MASK 0x1 ++ ++#define RTL8367C_REG_INDRECT_ACCESS_STATUS 0x1f01 ++#define RTL8367C_INDRECT_ACCESS_STATUS_OFFSET 2 ++#define RTL8367C_INDRECT_ACCESS_STATUS_MASK 0x7 ++ ++#define RTL8367C_REG_INDRECT_ACCESS_ADDRESS 0x1f02 ++ ++#define RTL8367C_REG_INDRECT_ACCESS_WRITE_DATA 0x1f03 ++ ++#define RTL8367C_REG_INDRECT_ACCESS_READ_DATA 0x1f04 ++ ++/* (16'h6200)fib_page */ ++ ++#define RTL8367C_REG_FIB0_CFG00 0x6200 ++#define RTL8367C_FIB0_CFG00_CFG_FIB_RST_OFFSET 15 ++#define RTL8367C_FIB0_CFG00_CFG_FIB_RST_MASK 0x8000 ++#define RTL8367C_FIB0_CFG00_CFG_FIB_LPK_OFFSET 14 ++#define RTL8367C_FIB0_CFG00_CFG_FIB_LPK_MASK 0x4000 ++#define RTL8367C_FIB0_CFG00_CFG_FIB_SPD_RD_0_OFFSET 13 ++#define RTL8367C_FIB0_CFG00_CFG_FIB_SPD_RD_0_MASK 0x2000 ++#define RTL8367C_FIB0_CFG00_CFG_FIB_ANEN_OFFSET 12 ++#define RTL8367C_FIB0_CFG00_CFG_FIB_ANEN_MASK 0x1000 ++#define RTL8367C_FIB0_CFG00_CFG_FIB_PDOWN_OFFSET 11 ++#define RTL8367C_FIB0_CFG00_CFG_FIB_PDOWN_MASK 0x800 ++#define RTL8367C_FIB0_CFG00_CFG_FIB_ISO_OFFSET 10 ++#define RTL8367C_FIB0_CFG00_CFG_FIB_ISO_MASK 0x400 ++#define RTL8367C_FIB0_CFG00_CFG_FIB_RESTART_OFFSET 9 ++#define RTL8367C_FIB0_CFG00_CFG_FIB_RESTART_MASK 0x200 ++#define RTL8367C_FIB0_CFG00_CFG_FIB_FULLDUP_OFFSET 8 ++#define RTL8367C_FIB0_CFG00_CFG_FIB_FULLDUP_MASK 0x100 ++#define RTL8367C_FIB0_CFG00_CFG_FIB_SPD_RD_1_OFFSET 6 ++#define RTL8367C_FIB0_CFG00_CFG_FIB_SPD_RD_1_MASK 0x40 ++#define RTL8367C_FIB0_CFG00_CFG_FIB_FRCTX_OFFSET 5 ++#define RTL8367C_FIB0_CFG00_CFG_FIB_FRCTX_MASK 0x20 ++ ++#define RTL8367C_REG_FIB0_CFG01 0x6201 ++#define RTL8367C_FIB0_CFG01_CAPBILITY_OFFSET 6 ++#define RTL8367C_FIB0_CFG01_CAPBILITY_MASK 0xFFC0 ++#define RTL8367C_FIB0_CFG01_AN_COMPLETE_OFFSET 5 ++#define RTL8367C_FIB0_CFG01_AN_COMPLETE_MASK 0x20 ++#define RTL8367C_FIB0_CFG01_R_FAULT_OFFSET 4 ++#define RTL8367C_FIB0_CFG01_R_FAULT_MASK 0x10 ++#define RTL8367C_FIB0_CFG01_NWAY_ABILITY_OFFSET 3 ++#define RTL8367C_FIB0_CFG01_NWAY_ABILITY_MASK 0x8 ++#define RTL8367C_FIB0_CFG01_LINK_STATUS_OFFSET 2 ++#define RTL8367C_FIB0_CFG01_LINK_STATUS_MASK 0x4 ++#define RTL8367C_FIB0_CFG01_JABBER_DETECT_OFFSET 1 ++#define RTL8367C_FIB0_CFG01_JABBER_DETECT_MASK 0x2 ++#define RTL8367C_FIB0_CFG01_EXTENDED_CAPBILITY_OFFSET 0 ++#define RTL8367C_FIB0_CFG01_EXTENDED_CAPBILITY_MASK 0x1 ++ ++#define RTL8367C_REG_FIB0_CFG02 0x6202 ++ ++#define RTL8367C_REG_FIB0_CFG03 0x6203 ++#define RTL8367C_FIB0_CFG03_REALTEK_OUI5_0_OFFSET 10 ++#define RTL8367C_FIB0_CFG03_REALTEK_OUI5_0_MASK 0xFC00 ++#define RTL8367C_FIB0_CFG03_MODEL_NO_OFFSET 4 ++#define RTL8367C_FIB0_CFG03_MODEL_NO_MASK 0x3F0 ++#define RTL8367C_FIB0_CFG03_REVISION_NO_OFFSET 0 ++#define RTL8367C_FIB0_CFG03_REVISION_NO_MASK 0xF ++ ++#define RTL8367C_REG_FIB0_CFG04 0x6204 ++ ++#define RTL8367C_REG_FIB0_CFG05 0x6205 ++ ++#define RTL8367C_REG_FIB0_CFG06 0x6206 ++#define RTL8367C_FIB0_CFG06_FIB_NP_EN_OFFSET 2 ++#define RTL8367C_FIB0_CFG06_FIB_NP_EN_MASK 0x4 ++#define RTL8367C_FIB0_CFG06_RXPAGE_OFFSET 1 ++#define RTL8367C_FIB0_CFG06_RXPAGE_MASK 0x2 ++ ++#define RTL8367C_REG_FIB0_CFG07 0x6207 ++ ++#define RTL8367C_REG_FIB0_CFG08 0x6208 ++ ++#define RTL8367C_REG_FIB0_CFG09 0x6209 ++ ++#define RTL8367C_REG_FIB0_CFG10 0x620a ++ ++#define RTL8367C_REG_FIB0_CFG11 0x620b ++ ++#define RTL8367C_REG_FIB0_CFG12 0x620c ++ ++#define RTL8367C_REG_FIB0_CFG13 0x620d ++#define RTL8367C_FIB0_CFG13_INDR_FUNC_OFFSET 14 ++#define RTL8367C_FIB0_CFG13_INDR_FUNC_MASK 0xC000 ++#define RTL8367C_FIB0_CFG13_DUMMY_OFFSET 5 ++#define RTL8367C_FIB0_CFG13_DUMMY_MASK 0x3FE0 ++#define RTL8367C_FIB0_CFG13_INDR_DEVAD_OFFSET 0 ++#define RTL8367C_FIB0_CFG13_INDR_DEVAD_MASK 0x1F ++ ++#define RTL8367C_REG_FIB0_CFG14 0x620e ++ ++#define RTL8367C_REG_FIB0_CFG15 0x620f ++ ++#define RTL8367C_REG_FIB1_CFG00 0x6210 ++#define RTL8367C_FIB1_CFG00_CFG_FIB_RST_OFFSET 15 ++#define RTL8367C_FIB1_CFG00_CFG_FIB_RST_MASK 0x8000 ++#define RTL8367C_FIB1_CFG00_CFG_FIB_LPK_OFFSET 14 ++#define RTL8367C_FIB1_CFG00_CFG_FIB_LPK_MASK 0x4000 ++#define RTL8367C_FIB1_CFG00_CFG_FIB_SPD_RD_0_OFFSET 13 ++#define RTL8367C_FIB1_CFG00_CFG_FIB_SPD_RD_0_MASK 0x2000 ++#define RTL8367C_FIB1_CFG00_CFG_FIB_ANEN_OFFSET 12 ++#define RTL8367C_FIB1_CFG00_CFG_FIB_ANEN_MASK 0x1000 ++#define RTL8367C_FIB1_CFG00_CFG_FIB_PDOWN_OFFSET 11 ++#define RTL8367C_FIB1_CFG00_CFG_FIB_PDOWN_MASK 0x800 ++#define RTL8367C_FIB1_CFG00_CFG_FIB_ISO_OFFSET 10 ++#define RTL8367C_FIB1_CFG00_CFG_FIB_ISO_MASK 0x400 ++#define RTL8367C_FIB1_CFG00_CFG_FIB_RESTART_OFFSET 9 ++#define RTL8367C_FIB1_CFG00_CFG_FIB_RESTART_MASK 0x200 ++#define RTL8367C_FIB1_CFG00_CFG_FIB_FULLDUP_OFFSET 8 ++#define RTL8367C_FIB1_CFG00_CFG_FIB_FULLDUP_MASK 0x100 ++#define RTL8367C_FIB1_CFG00_CFG_FIB_SPD_RD_1_OFFSET 6 ++#define RTL8367C_FIB1_CFG00_CFG_FIB_SPD_RD_1_MASK 0x40 ++#define RTL8367C_FIB1_CFG00_CFG_FIB_FRCTX_OFFSET 5 ++#define RTL8367C_FIB1_CFG00_CFG_FIB_FRCTX_MASK 0x20 ++ ++#define RTL8367C_REG_FIB1_CFG01 0x6211 ++#define RTL8367C_FIB1_CFG01_CAPBILITY_OFFSET 6 ++#define RTL8367C_FIB1_CFG01_CAPBILITY_MASK 0xFFC0 ++#define RTL8367C_FIB1_CFG01_AN_COMPLETE_OFFSET 5 ++#define RTL8367C_FIB1_CFG01_AN_COMPLETE_MASK 0x20 ++#define RTL8367C_FIB1_CFG01_R_FAULT_OFFSET 4 ++#define RTL8367C_FIB1_CFG01_R_FAULT_MASK 0x10 ++#define RTL8367C_FIB1_CFG01_NWAY_ABILITY_OFFSET 3 ++#define RTL8367C_FIB1_CFG01_NWAY_ABILITY_MASK 0x8 ++#define RTL8367C_FIB1_CFG01_LINK_STATUS_OFFSET 2 ++#define RTL8367C_FIB1_CFG01_LINK_STATUS_MASK 0x4 ++#define RTL8367C_FIB1_CFG01_JABBER_DETECT_OFFSET 1 ++#define RTL8367C_FIB1_CFG01_JABBER_DETECT_MASK 0x2 ++#define RTL8367C_FIB1_CFG01_EXTENDED_CAPBILITY_OFFSET 0 ++#define RTL8367C_FIB1_CFG01_EXTENDED_CAPBILITY_MASK 0x1 ++ ++#define RTL8367C_REG_FIB1_CFG02 0x6212 ++ ++#define RTL8367C_REG_FIB1_CFG03 0x6213 ++#define RTL8367C_FIB1_CFG03_REALTEK_OUI5_0_OFFSET 10 ++#define RTL8367C_FIB1_CFG03_REALTEK_OUI5_0_MASK 0xFC00 ++#define RTL8367C_FIB1_CFG03_MODEL_NO_OFFSET 4 ++#define RTL8367C_FIB1_CFG03_MODEL_NO_MASK 0x3F0 ++#define RTL8367C_FIB1_CFG03_REVISION_NO_OFFSET 0 ++#define RTL8367C_FIB1_CFG03_REVISION_NO_MASK 0xF ++ ++#define RTL8367C_REG_FIB1_CFG04 0x6214 ++ ++#define RTL8367C_REG_FIB1_CFG05 0x6215 ++ ++#define RTL8367C_REG_FIB1_CFG06 0x6216 ++#define RTL8367C_FIB1_CFG06_FIB_NP_EN_OFFSET 2 ++#define RTL8367C_FIB1_CFG06_FIB_NP_EN_MASK 0x4 ++#define RTL8367C_FIB1_CFG06_RXPAGE_OFFSET 1 ++#define RTL8367C_FIB1_CFG06_RXPAGE_MASK 0x2 ++ ++#define RTL8367C_REG_FIB1_CFG07 0x6217 ++ ++#define RTL8367C_REG_FIB1_CFG08 0x6218 ++ ++#define RTL8367C_REG_FIB1_CFG09 0x6219 ++ ++#define RTL8367C_REG_FIB1_CFG10 0x621a ++ ++#define RTL8367C_REG_FIB1_CFG11 0x621b ++ ++#define RTL8367C_REG_FIB1_CFG12 0x621c ++ ++#define RTL8367C_REG_FIB1_CFG13 0x621d ++#define RTL8367C_FIB1_CFG13_INDR_FUNC_OFFSET 14 ++#define RTL8367C_FIB1_CFG13_INDR_FUNC_MASK 0xC000 ++#define RTL8367C_FIB1_CFG13_DUMMY_OFFSET 5 ++#define RTL8367C_FIB1_CFG13_DUMMY_MASK 0x3FE0 ++#define RTL8367C_FIB1_CFG13_INDR_DEVAD_OFFSET 0 ++#define RTL8367C_FIB1_CFG13_INDR_DEVAD_MASK 0x1F ++ ++#define RTL8367C_REG_FIB1_CFG14 0x621e ++ ++#define RTL8367C_REG_FIB1_CFG15 0x621f ++ ++/* (16'h6400)timer_1588 */ ++ ++#define RTL8367C_REG_PTP_TIME_NSEC_L_NSEC 0x6400 ++ ++#define RTL8367C_REG_PTP_TIME_NSEC_H_NSEC 0x6401 ++#define RTL8367C_PTP_TIME_NSEC_H_EXEC_OFFSET 15 ++#define RTL8367C_PTP_TIME_NSEC_H_EXEC_MASK 0x8000 ++#define RTL8367C_PTP_TIME_NSEC_H_CMD_OFFSET 12 ++#define RTL8367C_PTP_TIME_NSEC_H_CMD_MASK 0x3000 ++#define RTL8367C_PTP_TIME_NSEC_H_NSEC_OFFSET 0 ++#define RTL8367C_PTP_TIME_NSEC_H_NSEC_MASK 0x7FF ++ ++#define RTL8367C_REG_PTP_TIME_SEC_L_SEC 0x6402 ++ ++#define RTL8367C_REG_PTP_TIME_SEC_H_SEC 0x6403 ++ ++#define RTL8367C_REG_PTP_TIME_CFG 0x6404 ++#define RTL8367C_CFG_TIMER_EN_FRC_OFFSET 2 ++#define RTL8367C_CFG_TIMER_EN_FRC_MASK 0x4 ++#define RTL8367C_CFG_TIMER_1588_EN_OFFSET 1 ++#define RTL8367C_CFG_TIMER_1588_EN_MASK 0x2 ++#define RTL8367C_CFG_CLK_SRC_OFFSET 0 ++#define RTL8367C_CFG_CLK_SRC_MASK 0x1 ++ ++#define RTL8367C_REG_OTAG_TPID 0x6405 ++ ++#define RTL8367C_REG_ITAG_TPID 0x6406 ++ ++#define RTL8367C_REG_MAC_ADDR_L 0x6407 ++ ++#define RTL8367C_REG_MAC_ADDR_M 0x6408 ++ ++#define RTL8367C_REG_MAC_ADDR_H 0x6409 ++ ++#define RTL8367C_REG_PTP_TIME_NSEC_L_NSEC_RD 0x640a ++ ++#define RTL8367C_REG_PTP_TIME_NSEC_H_NSEC_RD 0x640b ++#define RTL8367C_PTP_TIME_NSEC_H_NSEC_RD_OFFSET 0 ++#define RTL8367C_PTP_TIME_NSEC_H_NSEC_RD_MASK 0x7FF ++ ++#define RTL8367C_REG_PTP_TIME_SEC_L_SEC_RD 0x640c ++ ++#define RTL8367C_REG_PTP_TIME_SEC_H_SEC_RD 0x640d ++ ++#define RTL8367C_REG_PTP_TIME_CFG2 0x640e ++#define RTL8367C_CFG_EN_OFFLOAD_OFFSET 9 ++#define RTL8367C_CFG_EN_OFFLOAD_MASK 0x200 ++#define RTL8367C_CFG_SAVE_OFF_TS_OFFSET 8 ++#define RTL8367C_CFG_SAVE_OFF_TS_MASK 0x100 ++#define RTL8367C_CFG_IMR_OFFSET 0 ++#define RTL8367C_CFG_IMR_MASK 0xFF ++ ++#define RTL8367C_REG_PTP_INTERRUPT_CFG 0x640f ++#define RTL8367C_P9_INTERRUPT_OFFSET 9 ++#define RTL8367C_P9_INTERRUPT_MASK 0x200 ++#define RTL8367C_P8_INTERRUPT_OFFSET 8 ++#define RTL8367C_P8_INTERRUPT_MASK 0x100 ++#define RTL8367C_P7_INTERRUPT_OFFSET 7 ++#define RTL8367C_P7_INTERRUPT_MASK 0x80 ++#define RTL8367C_P6_INTERRUPT_OFFSET 6 ++#define RTL8367C_P6_INTERRUPT_MASK 0x40 ++#define RTL8367C_P5_INTERRUPT_OFFSET 5 ++#define RTL8367C_P5_INTERRUPT_MASK 0x20 ++#define RTL8367C_P4_INTERRUPT_OFFSET 4 ++#define RTL8367C_P4_INTERRUPT_MASK 0x10 ++#define RTL8367C_P3_INTERRUPT_OFFSET 3 ++#define RTL8367C_P3_INTERRUPT_MASK 0x8 ++#define RTL8367C_P2_INTERRUPT_OFFSET 2 ++#define RTL8367C_P2_INTERRUPT_MASK 0x4 ++#define RTL8367C_P1_INTERRUPT_OFFSET 1 ++#define RTL8367C_P1_INTERRUPT_MASK 0x2 ++#define RTL8367C_P0_INTERRUPT_OFFSET 0 ++#define RTL8367C_P0_INTERRUPT_MASK 0x1 ++ ++#define RTL8367C_REG_P0_TX_SYNC_SEQ_ID 0x6410 ++ ++#define RTL8367C_REG_P0_TX_DELAY_REQ_SEQ_ID 0x6411 ++ ++#define RTL8367C_REG_P0_TX_PDELAY_REQ_SEQ_ID 0x6412 ++ ++#define RTL8367C_REG_P0_TX_PDELAY_RESP_SEQ_ID 0x6413 ++ ++#define RTL8367C_REG_P0_RX_SYNC_SEQ_ID 0x6414 ++ ++#define RTL8367C_REG_P0_RX_DELAY_REQ_SEQ_ID 0x6415 ++ ++#define RTL8367C_REG_P0_RX_PDELAY_REQ_SEQ_ID 0x6416 ++ ++#define RTL8367C_REG_P0_RX_PDELAY_RESP_SEQ_ID 0x6417 ++ ++#define RTL8367C_REG_P0_PORT_NSEC_15_0 0x6418 ++ ++#define RTL8367C_REG_P0_PORT_NSEC_26_16 0x6419 ++#define RTL8367C_P0_PORT_NSEC_26_16_OFFSET 0 ++#define RTL8367C_P0_PORT_NSEC_26_16_MASK 0x7FF ++ ++#define RTL8367C_REG_P0_PORT_SEC_15_0 0x641a ++ ++#define RTL8367C_REG_P0_PORT_SEC_31_16 0x641b ++ ++#define RTL8367C_REG_P0_EAV_CFG 0x641c ++#define RTL8367C_P0_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 ++#define RTL8367C_P0_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 ++#define RTL8367C_P0_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 ++#define RTL8367C_P0_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 ++#define RTL8367C_P0_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 ++#define RTL8367C_P0_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 ++#define RTL8367C_P0_EAV_CFG_RX_DELAY_REQ_OFFSET 5 ++#define RTL8367C_P0_EAV_CFG_RX_DELAY_REQ_MASK 0x20 ++#define RTL8367C_P0_EAV_CFG_RX_SYNC_OFFSET 4 ++#define RTL8367C_P0_EAV_CFG_RX_SYNC_MASK 0x10 ++#define RTL8367C_P0_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 ++#define RTL8367C_P0_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 ++#define RTL8367C_P0_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 ++#define RTL8367C_P0_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 ++#define RTL8367C_P0_EAV_CFG_TX_DELAY_REQ_OFFSET 1 ++#define RTL8367C_P0_EAV_CFG_TX_DELAY_REQ_MASK 0x2 ++#define RTL8367C_P0_EAV_CFG_TX_SYNC_OFFSET 0 ++#define RTL8367C_P0_EAV_CFG_TX_SYNC_MASK 0x1 ++ ++#define RTL8367C_REG_P1_TX_SYNC_SEQ_ID 0x6420 ++ ++#define RTL8367C_REG_P1_TX_DELAY_REQ_SEQ_ID 0x6421 ++ ++#define RTL8367C_REG_P1_TX_PDELAY_REQ_SEQ_ID 0x6422 ++ ++#define RTL8367C_REG_P1_TX_PDELAY_RESP_SEQ_ID 0x6423 ++ ++#define RTL8367C_REG_P1_RX_SYNC_SEQ_ID 0x6424 ++ ++#define RTL8367C_REG_P1_RX_DELAY_REQ_SEQ_ID 0x6425 ++ ++#define RTL8367C_REG_P1_RX_PDELAY_REQ_SEQ_ID 0x6426 ++ ++#define RTL8367C_REG_P1_RX_PDELAY_RESP_SEQ_ID 0x6427 ++ ++#define RTL8367C_REG_P1_PORT_NSEC_15_0 0x6428 ++ ++#define RTL8367C_REG_P1_PORT_NSEC_26_16 0x6429 ++#define RTL8367C_P1_PORT_NSEC_26_16_OFFSET 0 ++#define RTL8367C_P1_PORT_NSEC_26_16_MASK 0x7FF ++ ++#define RTL8367C_REG_P1_PORT_SEC_15_0 0x642a ++ ++#define RTL8367C_REG_P1_PORT_SEC_31_16 0x642b ++ ++#define RTL8367C_REG_P1_EAV_CFG 0x642c ++#define RTL8367C_P1_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 ++#define RTL8367C_P1_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 ++#define RTL8367C_P1_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 ++#define RTL8367C_P1_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 ++#define RTL8367C_P1_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 ++#define RTL8367C_P1_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 ++#define RTL8367C_P1_EAV_CFG_RX_DELAY_REQ_OFFSET 5 ++#define RTL8367C_P1_EAV_CFG_RX_DELAY_REQ_MASK 0x20 ++#define RTL8367C_P1_EAV_CFG_RX_SYNC_OFFSET 4 ++#define RTL8367C_P1_EAV_CFG_RX_SYNC_MASK 0x10 ++#define RTL8367C_P1_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 ++#define RTL8367C_P1_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 ++#define RTL8367C_P1_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 ++#define RTL8367C_P1_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 ++#define RTL8367C_P1_EAV_CFG_TX_DELAY_REQ_OFFSET 1 ++#define RTL8367C_P1_EAV_CFG_TX_DELAY_REQ_MASK 0x2 ++#define RTL8367C_P1_EAV_CFG_TX_SYNC_OFFSET 0 ++#define RTL8367C_P1_EAV_CFG_TX_SYNC_MASK 0x1 ++ ++#define RTL8367C_REG_P2_TX_SYNC_SEQ_ID 0x6430 ++ ++#define RTL8367C_REG_P2_TX_DELAY_REQ_SEQ_ID 0x6431 ++ ++#define RTL8367C_REG_P2_TX_PDELAY_REQ_SEQ_ID 0x6432 ++ ++#define RTL8367C_REG_P2_TX_PDELAY_RESP_SEQ_ID 0x6433 ++ ++#define RTL8367C_REG_P2_RX_SYNC_SEQ_ID 0x6434 ++ ++#define RTL8367C_REG_P2_RX_DELAY_REQ_SEQ_ID 0x6435 ++ ++#define RTL8367C_REG_P2_RX_PDELAY_REQ_SEQ_ID 0x6436 ++ ++#define RTL8367C_REG_P2_RX_PDELAY_RESP_SEQ_ID 0x6437 ++ ++#define RTL8367C_REG_P2_PORT_NSEC_15_0 0x6438 ++ ++#define RTL8367C_REG_P2_PORT_NSEC_26_16 0x6439 ++#define RTL8367C_P2_PORT_NSEC_26_16_OFFSET 0 ++#define RTL8367C_P2_PORT_NSEC_26_16_MASK 0x7FF ++ ++#define RTL8367C_REG_P2_PORT_SEC_15_0 0x643a ++ ++#define RTL8367C_REG_P2_PORT_SEC_31_16 0x643b ++ ++#define RTL8367C_REG_P2_EAV_CFG 0x643c ++#define RTL8367C_P2_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 ++#define RTL8367C_P2_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 ++#define RTL8367C_P2_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 ++#define RTL8367C_P2_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 ++#define RTL8367C_P2_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 ++#define RTL8367C_P2_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 ++#define RTL8367C_P2_EAV_CFG_RX_DELAY_REQ_OFFSET 5 ++#define RTL8367C_P2_EAV_CFG_RX_DELAY_REQ_MASK 0x20 ++#define RTL8367C_P2_EAV_CFG_RX_SYNC_OFFSET 4 ++#define RTL8367C_P2_EAV_CFG_RX_SYNC_MASK 0x10 ++#define RTL8367C_P2_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 ++#define RTL8367C_P2_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 ++#define RTL8367C_P2_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 ++#define RTL8367C_P2_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 ++#define RTL8367C_P2_EAV_CFG_TX_DELAY_REQ_OFFSET 1 ++#define RTL8367C_P2_EAV_CFG_TX_DELAY_REQ_MASK 0x2 ++#define RTL8367C_P2_EAV_CFG_TX_SYNC_OFFSET 0 ++#define RTL8367C_P2_EAV_CFG_TX_SYNC_MASK 0x1 ++ ++#define RTL8367C_REG_P3_TX_SYNC_SEQ_ID 0x6440 ++ ++#define RTL8367C_REG_P3_TX_DELAY_REQ_SEQ_ID 0x6441 ++ ++#define RTL8367C_REG_P3_TX_PDELAY_REQ_SEQ_ID 0x6442 ++ ++#define RTL8367C_REG_P3_TX_PDELAY_RESP_SEQ_ID 0x6443 ++ ++#define RTL8367C_REG_P3_RX_SYNC_SEQ_ID 0x6444 ++ ++#define RTL8367C_REG_P3_RX_DELAY_REQ_SEQ_ID 0x6445 ++ ++#define RTL8367C_REG_P3_RX_PDELAY_REQ_SEQ_ID 0x6446 ++ ++#define RTL8367C_REG_P3_RX_PDELAY_RESP_SEQ_ID 0x6447 ++ ++#define RTL8367C_REG_P3_PORT_NSEC_15_0 0x6448 ++ ++#define RTL8367C_REG_P3_PORT_NSEC_26_16 0x6449 ++#define RTL8367C_P3_PORT_NSEC_26_16_OFFSET 0 ++#define RTL8367C_P3_PORT_NSEC_26_16_MASK 0x7FF ++ ++#define RTL8367C_REG_P3_PORT_SEC_15_0 0x644a ++ ++#define RTL8367C_REG_P3_PORT_SEC_31_16 0x644b ++ ++#define RTL8367C_REG_P3_EAV_CFG 0x644c ++#define RTL8367C_P3_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 ++#define RTL8367C_P3_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 ++#define RTL8367C_P3_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 ++#define RTL8367C_P3_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 ++#define RTL8367C_P3_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 ++#define RTL8367C_P3_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 ++#define RTL8367C_P3_EAV_CFG_RX_DELAY_REQ_OFFSET 5 ++#define RTL8367C_P3_EAV_CFG_RX_DELAY_REQ_MASK 0x20 ++#define RTL8367C_P3_EAV_CFG_RX_SYNC_OFFSET 4 ++#define RTL8367C_P3_EAV_CFG_RX_SYNC_MASK 0x10 ++#define RTL8367C_P3_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 ++#define RTL8367C_P3_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 ++#define RTL8367C_P3_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 ++#define RTL8367C_P3_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 ++#define RTL8367C_P3_EAV_CFG_TX_DELAY_REQ_OFFSET 1 ++#define RTL8367C_P3_EAV_CFG_TX_DELAY_REQ_MASK 0x2 ++#define RTL8367C_P3_EAV_CFG_TX_SYNC_OFFSET 0 ++#define RTL8367C_P3_EAV_CFG_TX_SYNC_MASK 0x1 ++ ++#define RTL8367C_REG_P4_TX_SYNC_SEQ_ID 0x6450 ++ ++#define RTL8367C_REG_P4_TX_DELAY_REQ_SEQ_ID 0x6451 ++ ++#define RTL8367C_REG_P4_TX_PDELAY_REQ_SEQ_ID 0x6452 ++ ++#define RTL8367C_REG_P4_TX_PDELAY_RESP_SEQ_ID 0x6453 ++ ++#define RTL8367C_REG_P4_RX_SYNC_SEQ_ID 0x6454 ++ ++#define RTL8367C_REG_P4_RX_DELAY_REQ_SEQ_ID 0x6455 ++ ++#define RTL8367C_REG_P4_RX_PDELAY_REQ_SEQ_ID 0x6456 ++ ++#define RTL8367C_REG_P4_RX_PDELAY_RESP_SEQ_ID 0x6457 ++ ++#define RTL8367C_REG_P4_PORT_NSEC_15_0 0x6458 ++ ++#define RTL8367C_REG_P4_PORT_NSEC_26_16 0x6459 ++#define RTL8367C_P4_PORT_NSEC_26_16_OFFSET 0 ++#define RTL8367C_P4_PORT_NSEC_26_16_MASK 0x7FF ++ ++#define RTL8367C_REG_P4_PORT_SEC_15_0 0x645a ++ ++#define RTL8367C_REG_P4_PORT_SEC_31_16 0x645b ++ ++#define RTL8367C_REG_P4_EAV_CFG 0x645c ++#define RTL8367C_P4_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 ++#define RTL8367C_P4_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 ++#define RTL8367C_P4_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 ++#define RTL8367C_P4_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 ++#define RTL8367C_P4_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 ++#define RTL8367C_P4_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 ++#define RTL8367C_P4_EAV_CFG_RX_DELAY_REQ_OFFSET 5 ++#define RTL8367C_P4_EAV_CFG_RX_DELAY_REQ_MASK 0x20 ++#define RTL8367C_P4_EAV_CFG_RX_SYNC_OFFSET 4 ++#define RTL8367C_P4_EAV_CFG_RX_SYNC_MASK 0x10 ++#define RTL8367C_P4_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 ++#define RTL8367C_P4_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 ++#define RTL8367C_P4_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 ++#define RTL8367C_P4_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 ++#define RTL8367C_P4_EAV_CFG_TX_DELAY_REQ_OFFSET 1 ++#define RTL8367C_P4_EAV_CFG_TX_DELAY_REQ_MASK 0x2 ++#define RTL8367C_P4_EAV_CFG_TX_SYNC_OFFSET 0 ++#define RTL8367C_P4_EAV_CFG_TX_SYNC_MASK 0x1 ++ ++#define RTL8367C_REG_P6_TX_SYNC_SEQ_ID 0x6460 ++ ++#define RTL8367C_REG_P6_TX_DELAY_REQ_SEQ_ID 0x6461 ++ ++#define RTL8367C_REG_P6_TX_PDELAY_REQ_SEQ_ID 0x6462 ++ ++#define RTL8367C_REG_P6_TX_PDELAY_RESP_SEQ_ID 0x6463 ++ ++#define RTL8367C_REG_P6_RX_SYNC_SEQ_ID 0x6464 ++ ++#define RTL8367C_REG_P6_RX_DELAY_REQ_SEQ_ID 0x6465 ++ ++#define RTL8367C_REG_P6_RX_PDELAY_REQ_SEQ_ID 0x6466 ++ ++#define RTL8367C_REG_P6_RX_PDELAY_RESP_SEQ_ID 0x6467 ++ ++#define RTL8367C_REG_P6_PORT_NSEC_15_0 0x6468 ++ ++#define RTL8367C_REG_P6_PORT_NSEC_26_16 0x6469 ++#define RTL8367C_P6_PORT_NSEC_26_16_OFFSET 0 ++#define RTL8367C_P6_PORT_NSEC_26_16_MASK 0x7FF ++ ++#define RTL8367C_REG_P6_PORT_SEC_15_0 0x646a ++ ++#define RTL8367C_REG_P6_PORT_SEC_31_16 0x646b ++ ++#define RTL8367C_REG_P6_EAV_CFG 0x646c ++#define RTL8367C_P6_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 ++#define RTL8367C_P6_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 ++#define RTL8367C_P6_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 ++#define RTL8367C_P6_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 ++#define RTL8367C_P6_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 ++#define RTL8367C_P6_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 ++#define RTL8367C_P6_EAV_CFG_RX_DELAY_REQ_OFFSET 5 ++#define RTL8367C_P6_EAV_CFG_RX_DELAY_REQ_MASK 0x20 ++#define RTL8367C_P6_EAV_CFG_RX_SYNC_OFFSET 4 ++#define RTL8367C_P6_EAV_CFG_RX_SYNC_MASK 0x10 ++#define RTL8367C_P6_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 ++#define RTL8367C_P6_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 ++#define RTL8367C_P6_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 ++#define RTL8367C_P6_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 ++#define RTL8367C_P6_EAV_CFG_TX_DELAY_REQ_OFFSET 1 ++#define RTL8367C_P6_EAV_CFG_TX_DELAY_REQ_MASK 0x2 ++#define RTL8367C_P6_EAV_CFG_TX_SYNC_OFFSET 0 ++#define RTL8367C_P6_EAV_CFG_TX_SYNC_MASK 0x1 ++ ++#define RTL8367C_REG_P7_TX_SYNC_SEQ_ID 0x6470 ++ ++#define RTL8367C_REG_P7_TX_DELAY_REQ_SEQ_ID 0x6471 ++ ++#define RTL8367C_REG_P7_TX_PDELAY_REQ_SEQ_ID 0x6472 ++ ++#define RTL8367C_REG_P7_TX_PDELAY_RESP_SEQ_ID 0x6473 ++ ++#define RTL8367C_REG_P7_RX_SYNC_SEQ_ID 0x6474 ++ ++#define RTL8367C_REG_P7_RX_DELAY_REQ_SEQ_ID 0x6475 ++ ++#define RTL8367C_REG_P7_RX_PDELAY_REQ_SEQ_ID 0x6476 ++ ++#define RTL8367C_REG_P7_RX_PDELAY_RESP_SEQ_ID 0x6477 ++ ++#define RTL8367C_REG_P7_PORT_NSEC_15_0 0x6478 ++ ++#define RTL8367C_REG_P7_PORT_NSEC_26_16 0x6479 ++#define RTL8367C_P7_PORT_NSEC_26_16_OFFSET 0 ++#define RTL8367C_P7_PORT_NSEC_26_16_MASK 0x7FF ++ ++#define RTL8367C_REG_P7_PORT_SEC_15_0 0x647a ++ ++#define RTL8367C_REG_P7_PORT_SEC_31_16 0x647b ++ ++#define RTL8367C_REG_P7_EAV_CFG 0x647c ++#define RTL8367C_P7_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 ++#define RTL8367C_P7_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 ++#define RTL8367C_P7_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 ++#define RTL8367C_P7_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 ++#define RTL8367C_P7_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 ++#define RTL8367C_P7_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 ++#define RTL8367C_P7_EAV_CFG_RX_DELAY_REQ_OFFSET 5 ++#define RTL8367C_P7_EAV_CFG_RX_DELAY_REQ_MASK 0x20 ++#define RTL8367C_P7_EAV_CFG_RX_SYNC_OFFSET 4 ++#define RTL8367C_P7_EAV_CFG_RX_SYNC_MASK 0x10 ++#define RTL8367C_P7_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 ++#define RTL8367C_P7_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 ++#define RTL8367C_P7_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 ++#define RTL8367C_P7_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 ++#define RTL8367C_P7_EAV_CFG_TX_DELAY_REQ_OFFSET 1 ++#define RTL8367C_P7_EAV_CFG_TX_DELAY_REQ_MASK 0x2 ++#define RTL8367C_P7_EAV_CFG_TX_SYNC_OFFSET 0 ++#define RTL8367C_P7_EAV_CFG_TX_SYNC_MASK 0x1 ++ ++#define RTL8367C_REG_P5_TX_SYNC_SEQ_ID 0x6480 ++ ++#define RTL8367C_REG_P5_TX_DELAY_REQ_SEQ_ID 0x6481 ++ ++#define RTL8367C_REG_P5_TX_PDELAY_REQ_SEQ_ID 0x6482 ++ ++#define RTL8367C_REG_P5_TX_PDELAY_RESP_SEQ_ID 0x6483 ++ ++#define RTL8367C_REG_P5_RX_SYNC_SEQ_ID 0x6484 ++ ++#define RTL8367C_REG_P5_RX_DELAY_REQ_SEQ_ID 0x6485 ++ ++#define RTL8367C_REG_P5_RX_PDELAY_REQ_SEQ_ID 0x6486 ++ ++#define RTL8367C_REG_P5_RX_PDELAY_RESP_SEQ_ID 0x6487 ++ ++#define RTL8367C_REG_P5_PORT_NSEC_15_0 0x6488 ++ ++#define RTL8367C_REG_P5_PORT_NSEC_26_16 0x6489 ++#define RTL8367C_P5_PORT_NSEC_26_16_OFFSET 0 ++#define RTL8367C_P5_PORT_NSEC_26_16_MASK 0x7FF ++ ++#define RTL8367C_REG_P5_PORT_SEC_15_0 0x648a ++ ++#define RTL8367C_REG_P5_PORT_SEC_31_16 0x648b ++ ++#define RTL8367C_REG_P5_EAV_CFG 0x648c ++#define RTL8367C_P5_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 ++#define RTL8367C_P5_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 ++#define RTL8367C_P5_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 ++#define RTL8367C_P5_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 ++#define RTL8367C_P5_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 ++#define RTL8367C_P5_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 ++#define RTL8367C_P5_EAV_CFG_RX_DELAY_REQ_OFFSET 5 ++#define RTL8367C_P5_EAV_CFG_RX_DELAY_REQ_MASK 0x20 ++#define RTL8367C_P5_EAV_CFG_RX_SYNC_OFFSET 4 ++#define RTL8367C_P5_EAV_CFG_RX_SYNC_MASK 0x10 ++#define RTL8367C_P5_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 ++#define RTL8367C_P5_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 ++#define RTL8367C_P5_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 ++#define RTL8367C_P5_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 ++#define RTL8367C_P5_EAV_CFG_TX_DELAY_REQ_OFFSET 1 ++#define RTL8367C_P5_EAV_CFG_TX_DELAY_REQ_MASK 0x2 ++#define RTL8367C_P5_EAV_CFG_TX_SYNC_OFFSET 0 ++#define RTL8367C_P5_EAV_CFG_TX_SYNC_MASK 0x1 ++ ++#define RTL8367C_REG_P8_TX_SYNC_SEQ_ID 0x6490 ++ ++#define RTL8367C_REG_P8_TX_DELAY_REQ_SEQ_ID 0x6491 ++ ++#define RTL8367C_REG_P8_TX_PDELAY_REQ_SEQ_ID 0x6492 ++ ++#define RTL8367C_REG_P8_TX_PDELAY_RESP_SEQ_ID 0x6493 ++ ++#define RTL8367C_REG_P8_RX_SYNC_SEQ_ID 0x6494 ++ ++#define RTL8367C_REG_P8_RX_DELAY_REQ_SEQ_ID 0x6495 ++ ++#define RTL8367C_REG_P8_RX_PDELAY_REQ_SEQ_ID 0x6496 ++ ++#define RTL8367C_REG_P8_RX_PDELAY_RESP_SEQ_ID 0x6497 ++ ++#define RTL8367C_REG_P8_PORT_NSEC_15_0 0x6498 ++ ++#define RTL8367C_REG_P8_PORT_NSEC_26_16 0x6499 ++#define RTL8367C_P8_PORT_NSEC_26_16_OFFSET 0 ++#define RTL8367C_P8_PORT_NSEC_26_16_MASK 0x7FF ++ ++#define RTL8367C_REG_P8_PORT_SEC_15_0 0x649a ++ ++#define RTL8367C_REG_P8_PORT_SEC_31_16 0x649b ++ ++#define RTL8367C_REG_P8_EAV_CFG 0x649c ++#define RTL8367C_P8_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 ++#define RTL8367C_P8_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 ++#define RTL8367C_P8_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 ++#define RTL8367C_P8_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 ++#define RTL8367C_P8_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 ++#define RTL8367C_P8_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 ++#define RTL8367C_P8_EAV_CFG_RX_DELAY_REQ_OFFSET 5 ++#define RTL8367C_P8_EAV_CFG_RX_DELAY_REQ_MASK 0x20 ++#define RTL8367C_P8_EAV_CFG_RX_SYNC_OFFSET 4 ++#define RTL8367C_P8_EAV_CFG_RX_SYNC_MASK 0x10 ++#define RTL8367C_P8_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 ++#define RTL8367C_P8_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 ++#define RTL8367C_P8_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 ++#define RTL8367C_P8_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 ++#define RTL8367C_P8_EAV_CFG_TX_DELAY_REQ_OFFSET 1 ++#define RTL8367C_P8_EAV_CFG_TX_DELAY_REQ_MASK 0x2 ++#define RTL8367C_P8_EAV_CFG_TX_SYNC_OFFSET 0 ++#define RTL8367C_P8_EAV_CFG_TX_SYNC_MASK 0x1 ++ ++#define RTL8367C_REG_P9_TX_SYNC_SEQ_ID 0x64a0 ++ ++#define RTL8367C_REG_P9_TX_DELAY_REQ_SEQ_ID 0x64a1 ++ ++#define RTL8367C_REG_P9_TX_PDELAY_REQ_SEQ_ID 0x64a2 ++ ++#define RTL8367C_REG_P9_TX_PDELAY_RESP_SEQ_ID 0x64a3 ++ ++#define RTL8367C_REG_P9_RX_SYNC_SEQ_ID 0x64a4 ++ ++#define RTL8367C_REG_P9_RX_DELAY_REQ_SEQ_ID 0x64a5 ++ ++#define RTL8367C_REG_P9_RX_PDELAY_REQ_SEQ_ID 0x64a6 ++ ++#define RTL8367C_REG_P9_RX_PDELAY_RESP_SEQ_ID 0x64a7 ++ ++#define RTL8367C_REG_P9_PORT_NSEC_15_0 0x64a8 ++ ++#define RTL8367C_REG_P9_PORT_NSEC_26_16 0x64a9 ++#define RTL8367C_P9_PORT_NSEC_26_16_OFFSET 0 ++#define RTL8367C_P9_PORT_NSEC_26_16_MASK 0x7FF ++ ++#define RTL8367C_REG_P9_PORT_SEC_15_0 0x64aa ++ ++#define RTL8367C_REG_P9_PORT_SEC_31_16 0x64ab ++ ++#define RTL8367C_REG_P9_EAV_CFG 0x64ac ++#define RTL8367C_P9_EAV_CFG_PTP_PHY_EN_EN_OFFSET 8 ++#define RTL8367C_P9_EAV_CFG_PTP_PHY_EN_EN_MASK 0x100 ++#define RTL8367C_P9_EAV_CFG_RX_PDELAY_RESP_OFFSET 7 ++#define RTL8367C_P9_EAV_CFG_RX_PDELAY_RESP_MASK 0x80 ++#define RTL8367C_P9_EAV_CFG_RX_PDELAY_REQ_OFFSET 6 ++#define RTL8367C_P9_EAV_CFG_RX_PDELAY_REQ_MASK 0x40 ++#define RTL8367C_P9_EAV_CFG_RX_DELAY_REQ_OFFSET 5 ++#define RTL8367C_P9_EAV_CFG_RX_DELAY_REQ_MASK 0x20 ++#define RTL8367C_P9_EAV_CFG_RX_SYNC_OFFSET 4 ++#define RTL8367C_P9_EAV_CFG_RX_SYNC_MASK 0x10 ++#define RTL8367C_P9_EAV_CFG_TX_PDELAY_RESP_OFFSET 3 ++#define RTL8367C_P9_EAV_CFG_TX_PDELAY_RESP_MASK 0x8 ++#define RTL8367C_P9_EAV_CFG_TX_PDELAY_REQ_OFFSET 2 ++#define RTL8367C_P9_EAV_CFG_TX_PDELAY_REQ_MASK 0x4 ++#define RTL8367C_P9_EAV_CFG_TX_DELAY_REQ_OFFSET 1 ++#define RTL8367C_P9_EAV_CFG_TX_DELAY_REQ_MASK 0x2 ++#define RTL8367C_P9_EAV_CFG_TX_SYNC_OFFSET 0 ++#define RTL8367C_P9_EAV_CFG_TX_SYNC_MASK 0x1 ++ ++/* (16'h6600)sds_indacs_reg */ ++ ++#define RTL8367C_REG_SDS_INDACS_CMD 0x6600 ++#define RTL8367C_SDS_CMD_BUSY_OFFSET 8 ++#define RTL8367C_SDS_CMD_BUSY_MASK 0x100 ++#define RTL8367C_SDS_CMD_OFFSET 7 ++#define RTL8367C_SDS_CMD_MASK 0x80 ++#define RTL8367C_SDS_RWOP_OFFSET 6 ++#define RTL8367C_SDS_RWOP_MASK 0x40 ++#define RTL8367C_SDS_INDEX_OFFSET 0 ++#define RTL8367C_SDS_INDEX_MASK 0x3F ++ ++#define RTL8367C_REG_SDS_INDACS_ADR 0x6601 ++#define RTL8367C_SDS_PAGE_OFFSET 5 ++#define RTL8367C_SDS_PAGE_MASK 0x7E0 ++#define RTL8367C_SDS_REGAD_OFFSET 0 ++#define RTL8367C_SDS_REGAD_MASK 0x1F ++ ++#define RTL8367C_REG_SDS_INDACS_DATA 0x6602 ++ ++ ++#endif /*#ifndef _RTL8367C_REG_H_*/ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/smi.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/smi.h +new file mode 100644 +index 0000000000..b77d760711 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/smi.h +@@ -0,0 +1,54 @@ ++/* ++ * 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 : RTL8367C switch low-level function for access register ++ * Feature : SMI related functions ++ * ++ */ ++ ++#ifndef __SMI_H__ ++#define __SMI_H__ ++ ++#include ++#include "rtk_error.h" ++ ++#define MDC_MDIO_CTRL0_REG 31 ++#define MDC_MDIO_START_REG 29 ++#define MDC_MDIO_CTRL1_REG 21 ++#define MDC_MDIO_ADDRESS_REG 23 ++#define MDC_MDIO_DATA_WRITE_REG 24 ++#define MDC_MDIO_DATA_READ_REG 25 ++#define MDC_MDIO_PREAMBLE_LEN 32 ++ ++#define MDC_MDIO_START_OP 0xFFFF ++#define MDC_MDIO_ADDR_OP 0x000E ++#define MDC_MDIO_READ_OP 0x0001 ++#define MDC_MDIO_WRITE_OP 0x0003 ++ ++#define SPI_READ_OP 0x3 ++#define SPI_WRITE_OP 0x2 ++#define SPI_READ_OP_LEN 0x8 ++#define SPI_WRITE_OP_LEN 0x8 ++#define SPI_REG_LEN 16 ++#define SPI_DATA_LEN 16 ++ ++#define GPIO_DIR_IN 1 ++#define GPIO_DIR_OUT 0 ++ ++#define ack_timer 5 ++ ++#define DELAY 10000 ++#define CLK_DURATION(clk) { int i; for(i=0; isvid is SVID of SVLAN member configuration. ++ * - rtk_svlan_memberCfg_t->memberport is member port mask of SVLAN member configuration. ++ * - rtk_svlan_memberCfg_t->fid is filtering database of SVLAN member configuration. ++ * - rtk_svlan_memberCfg_t->priority is priority of SVLAN member configuration. ++ */ ++extern rtk_api_ret_t rtk_svlan_memberPortEntry_set(rtk_uint32 svid_idx, rtk_svlan_memberCfg_t *psvlan_cfg); ++ ++/* Function Name: ++ * rtk_svlan_memberPortEntry_get ++ * Description: ++ * Get SVLAN member Configure. ++ * Input: ++ * svid - SVLAN id ++ * Output: ++ * pSvlan_cfg - SVLAN member configuration ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can get system 64 accepted s-tag frame format. Only 64 SVID S-tag frame will be accpeted ++ * to receiving from uplink ports. Other SVID S-tag frame or S-untagged frame will be droped. ++ */ ++extern rtk_api_ret_t rtk_svlan_memberPortEntry_get(rtk_uint32 svid_idx, rtk_svlan_memberCfg_t *pSvlan_cfg); ++ ++/* Function Name: ++ * rtk_svlan_memberPortEntry_adv_set ++ * Description: ++ * Configure system SVLAN member by index ++ * Input: ++ * idx - Index (0 ~ 63) ++ * psvlan_cfg - SVLAN member configuration ++ * 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_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_PORT_MASK - Invalid portmask. ++ * RT_ERR_SVLAN_TABLE_FULL - SVLAN configuration is full. ++ * Note: ++ * The API can set system 64 accepted s-tag frame format by index. ++ * - rtk_svlan_memberCfg_t->svid is SVID of SVLAN member configuration. ++ * - rtk_svlan_memberCfg_t->memberport is member port mask of SVLAN member configuration. ++ * - rtk_svlan_memberCfg_t->fid is filtering database of SVLAN member configuration. ++ * - rtk_svlan_memberCfg_t->priority is priority of SVLAN member configuration. ++ */ ++extern rtk_api_ret_t rtk_svlan_memberPortEntry_adv_set(rtk_uint32 idx, rtk_svlan_memberCfg_t *pSvlan_cfg); ++ ++/* Function Name: ++ * rtk_svlan_memberPortEntry_adv_get ++ * Description: ++ * Get SVLAN member Configure by index. ++ * Input: ++ * idx - Index (0 ~ 63) ++ * Output: ++ * pSvlan_cfg - SVLAN member configuration ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can get system 64 accepted s-tag frame format. Only 64 SVID S-tag frame will be accpeted ++ * to receiving from uplink ports. Other SVID S-tag frame or S-untagged frame will be droped. ++ */ ++extern rtk_api_ret_t rtk_svlan_memberPortEntry_adv_get(rtk_uint32 idx, rtk_svlan_memberCfg_t *pSvlan_cfg); ++ ++/* Function Name: ++ * rtk_svlan_defaultSvlan_set ++ * Description: ++ * Configure default egress SVLAN. ++ * Input: ++ * port - Source port ++ * svid - SVLAN id ++ * 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_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. ++ * Note: ++ * The API can set port n S-tag format index while receiving frame from port n ++ * is transmit through uplink port with s-tag field ++ */ ++extern rtk_api_ret_t rtk_svlan_defaultSvlan_set(rtk_port_t port, rtk_vlan_t svid); ++ ++/* Function Name: ++ * rtk_svlan_defaultSvlan_get ++ * Description: ++ * Get the configure default egress SVLAN. ++ * Input: ++ * port - Source port ++ * Output: ++ * pSvid - SVLAN VID ++ * 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 port n S-tag format index while receiving frame from port n ++ * is transmit through uplink port with s-tag field ++ */ ++extern rtk_api_ret_t rtk_svlan_defaultSvlan_get(rtk_port_t port, rtk_vlan_t *pSvid); ++ ++/* Function Name: ++ * rtk_svlan_c2s_add ++ * Description: ++ * Configure SVLAN C2S table ++ * Input: ++ * vid - VLAN ID ++ * src_port - Ingress Port ++ * svid - SVLAN VID ++ * 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_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_VLAN_VID - Invalid VID parameter. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can set system C2S configuration. ASIC will check upstream's VID and assign related ++ * SVID to mathed packet. There are 128 SVLAN C2S configurations. ++ */ ++extern rtk_api_ret_t rtk_svlan_c2s_add(rtk_vlan_t vid, rtk_port_t src_port, rtk_vlan_t svid); ++ ++/* Function Name: ++ * rtk_svlan_c2s_del ++ * Description: ++ * Delete one C2S entry ++ * Input: ++ * vid - VLAN ID ++ * src_port - Ingress Port ++ * svid - SVLAN VID ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_VLAN_VID - Invalid VID parameter. ++ * RT_ERR_PORT_ID - Invalid port ID. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * Note: ++ * The API can delete system C2S configuration. There are 128 SVLAN C2S configurations. ++ */ ++extern rtk_api_ret_t rtk_svlan_c2s_del(rtk_vlan_t vid, rtk_port_t src_port); ++ ++/* Function Name: ++ * rtk_svlan_c2s_get ++ * Description: ++ * Get configure SVLAN C2S table ++ * Input: ++ * vid - VLAN ID ++ * src_port - Ingress Port ++ * Output: ++ * pSvid - SVLAN ID ++ * 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. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * Note: ++ * The API can get system C2S configuration. There are 128 SVLAN C2S configurations. ++ */ ++extern rtk_api_ret_t rtk_svlan_c2s_get(rtk_vlan_t vid, rtk_port_t src_port, rtk_vlan_t *pSvid); ++ ++/* Function Name: ++ * rtk_svlan_untag_action_set ++ * Description: ++ * Configure Action of downstream Un-Stag packet ++ * Input: ++ * action - Action for UnStag ++ * svid - The SVID assigned to UnStag packet ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can configure action of downstream Un-Stag packet. A SVID assigned ++ * to the un-stag is also supported by this API. The parameter of svid is ++ * only referenced when the action is set to UNTAG_ASSIGN ++ */ ++extern rtk_api_ret_t rtk_svlan_untag_action_set(rtk_svlan_untag_action_t action, rtk_vlan_t svid); ++ ++/* Function Name: ++ * rtk_svlan_untag_action_get ++ * Description: ++ * Get Action of downstream Un-Stag packet ++ * Input: ++ * None ++ * Output: ++ * pAction - Action for UnStag ++ * pSvid - The SVID assigned to UnStag packet ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can Get action of downstream Un-Stag packet. A SVID assigned ++ * to the un-stag is also retrieved by this API. The parameter pSvid is ++ * only refernced when the action is UNTAG_ASSIGN ++ */ ++extern rtk_api_ret_t rtk_svlan_untag_action_get(rtk_svlan_untag_action_t *pAction, rtk_vlan_t *pSvid); ++ ++/* Function Name: ++ * rtk_svlan_unmatch_action_set ++ * Description: ++ * Configure Action of downstream Unmatch packet ++ * Input: ++ * action - Action for Unmatch ++ * svid - The SVID assigned to Unmatch packet ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can configure action of downstream Un-match packet. A SVID assigned ++ * to the un-match is also supported by this API. The parameter od svid is ++ * only refernced when the action is set to UNMATCH_ASSIGN ++ */ ++extern rtk_api_ret_t rtk_svlan_unmatch_action_set(rtk_svlan_unmatch_action_t action, rtk_vlan_t svid); ++ ++/* Function Name: ++ * rtk_svlan_unmatch_action_get ++ * Description: ++ * Get Action of downstream Unmatch packet ++ * Input: ++ * None ++ * Output: ++ * pAction - Action for Unmatch ++ * pSvid - The SVID assigned to Unmatch packet ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can Get action of downstream Un-match packet. A SVID assigned ++ * to the un-match is also retrieved by this API. The parameter pSvid is ++ * only refernced when the action is UNMATCH_ASSIGN ++ */ ++extern rtk_api_ret_t rtk_svlan_unmatch_action_get(rtk_svlan_unmatch_action_t *pAction, rtk_vlan_t *pSvid); ++ ++/* Function Name: ++ * rtk_svlan_dmac_vidsel_set ++ * Description: ++ * Set DMAC CVID selection ++ * Input: ++ * port - Port ++ * enable - state of DMAC CVID Selection ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * This API can set DMAC CVID Selection state ++ */ ++extern rtk_api_ret_t rtk_svlan_dmac_vidsel_set(rtk_port_t port, rtk_enable_t enable); ++ ++/* Function Name: ++ * rtk_svlan_dmac_vidsel_get ++ * Description: ++ * Get DMAC CVID selection ++ * Input: ++ * port - Port ++ * Output: ++ * pEnable - state of DMAC CVID Selection ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * This API can get DMAC CVID Selection state ++ */ ++extern rtk_api_ret_t rtk_svlan_dmac_vidsel_get(rtk_port_t port, rtk_enable_t *pEnable); ++ ++/* Function Name: ++ * rtk_svlan_ipmc2s_add ++ * Description: ++ * add ip multicast address to SVLAN ++ * Input: ++ * svid - SVLAN VID ++ * ipmc - ip multicast address ++ * ipmcMsk - ip multicast mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can set IP mutlicast to SVID configuration. If upstream packet is IPv4 multicast ++ * packet and DIP is matched MC2S configuration, ASIC will assign egress SVID to the packet. ++ * There are 32 SVLAN multicast configurations for IP and L2 multicast. ++ */ ++extern rtk_api_ret_t rtk_svlan_ipmc2s_add(ipaddr_t ipmc, ipaddr_t ipmcMsk, rtk_vlan_t svid); ++ ++/* Function Name: ++ * rtk_svlan_ipmc2s_del ++ * Description: ++ * delete ip multicast address to SVLAN ++ * Input: ++ * ipmc - ip multicast address ++ * ipmcMsk - ip multicast mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * Note: ++ * The API can delete IP mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. ++ */ ++extern rtk_api_ret_t rtk_svlan_ipmc2s_del(ipaddr_t ipmc, ipaddr_t ipmcMsk); ++ ++/* Function Name: ++ * rtk_svlan_ipmc2s_get ++ * Description: ++ * Get ip multicast address to SVLAN ++ * Input: ++ * ipmc - ip multicast address ++ * ipmcMsk - ip multicast mask ++ * Output: ++ * pSvid - SVLAN VID ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * Note: ++ * The API can get IP mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. ++ */ ++extern rtk_api_ret_t rtk_svlan_ipmc2s_get(ipaddr_t ipmc, ipaddr_t ipmcMsk, rtk_vlan_t *pSvid); ++ ++/* Function Name: ++ * rtk_svlan_l2mc2s_add ++ * Description: ++ * Add L2 multicast address to SVLAN ++ * Input: ++ * mac - L2 multicast address ++ * macMsk - L2 multicast address mask ++ * svid - SVLAN VID ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can set L2 Mutlicast to SVID configuration. If upstream packet is L2 multicast ++ * packet and DMAC is matched, ASIC will assign egress SVID to the packet. There are 32 ++ * SVLAN multicast configurations for IP and L2 multicast. ++ */ ++extern rtk_api_ret_t rtk_svlan_l2mc2s_add(rtk_mac_t mac, rtk_mac_t macMsk, rtk_vlan_t svid); ++ ++/* Function Name: ++ * rtk_svlan_l2mc2s_del ++ * Description: ++ * delete L2 multicast address to SVLAN ++ * Input: ++ * mac - L2 multicast address ++ * macMsk - L2 multicast address mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * Note: ++ * The API can delete Mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. ++ */ ++extern rtk_api_ret_t rtk_svlan_l2mc2s_del(rtk_mac_t mac, rtk_mac_t macMsk); ++ ++/* Function Name: ++ * rtk_svlan_l2mc2s_get ++ * Description: ++ * Get L2 multicast address to SVLAN ++ * Input: ++ * mac - L2 multicast address ++ * macMsk - L2 multicast address mask ++ * Output: ++ * pSvid - SVLAN VID ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * Note: ++ * The API can get L2 mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. ++ */ ++extern rtk_api_ret_t rtk_svlan_l2mc2s_get(rtk_mac_t mac, rtk_mac_t macMsk, rtk_vlan_t *pSvid); ++ ++/* Function Name: ++ * rtk_svlan_sp2c_add ++ * Description: ++ * Add system SP2C configuration ++ * Input: ++ * cvid - VLAN ID ++ * dst_port - Destination port of SVLAN to CVLAN configuration ++ * svid - SVLAN VID ++ * ++ * 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_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_VLAN_VID - Invalid VID parameter. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can add SVID & Destination Port to CVLAN configuration. The downstream frames with assigned ++ * SVID will be add C-tag with assigned CVID if the output port is the assigned destination port. ++ * There are 128 SP2C configurations. ++ */ ++extern rtk_api_ret_t rtk_svlan_sp2c_add(rtk_vlan_t svid, rtk_port_t dst_port, rtk_vlan_t cvid); ++ ++/* Function Name: ++ * rtk_svlan_sp2c_get ++ * Description: ++ * Get configure system SP2C content ++ * Input: ++ * svid - SVLAN VID ++ * dst_port - Destination port of SVLAN to CVLAN configuration ++ * Output: ++ * pCvid - VLAN ID ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_PORT_ID - Invalid port number. ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * Note: ++ * The API can get SVID & Destination Port to CVLAN configuration. There are 128 SP2C configurations. ++ */ ++extern rtk_api_ret_t rtk_svlan_sp2c_get(rtk_vlan_t svid, rtk_port_t dst_port, rtk_vlan_t *pCvid); ++ ++/* Function Name: ++ * rtk_svlan_sp2c_del ++ * Description: ++ * Delete system SP2C configuration ++ * Input: ++ * svid - SVLAN VID ++ * dst_port - Destination port of SVLAN to CVLAN 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. ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * Note: ++ * The API can delete SVID & Destination Port to CVLAN configuration. There are 128 SP2C configurations. ++ */ ++extern rtk_api_ret_t rtk_svlan_sp2c_del(rtk_vlan_t svid, rtk_port_t dst_port); ++ ++ ++/* Function Name: ++ * rtk_svlan_lookupType_set ++ * Description: ++ * Set lookup type of SVLAN ++ * Input: ++ * type - lookup type ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * Note: ++ * none ++ */ ++extern rtk_api_ret_t rtk_svlan_lookupType_set(rtk_svlan_lookupType_t type); ++ ++/* Function Name: ++ * rtk_svlan_lookupType_get ++ * Description: ++ * Get lookup type of SVLAN ++ * Input: ++ * pType - lookup type ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * Note: ++ * none ++ */ ++extern rtk_api_ret_t rtk_svlan_lookupType_get(rtk_svlan_lookupType_t *pType); ++ ++/* Function Name: ++ * rtk_svlan_trapPri_set ++ * Description: ++ * Set svlan trap priority ++ * Input: ++ * priority - priority for trap packets ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_QOS_INT_PRIORITY ++ * Note: ++ * None ++ */ ++extern rtk_api_ret_t rtk_svlan_trapPri_set(rtk_pri_t priority); ++ ++/* Function Name: ++ * rtk_svlan_trapPri_get ++ * Description: ++ * Get svlan trap priority ++ * Input: ++ * None ++ * Output: ++ * pPriority - priority for trap packets ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_NULL_POINTER - input parameter may be null pointer ++ * Note: ++ * None ++ */ ++extern rtk_api_ret_t rtk_svlan_trapPri_get(rtk_pri_t *pPriority); ++ ++/* Function Name: ++ * rtk_svlan_unassign_action_set ++ * Description: ++ * Configure Action of upstream without svid assign action ++ * Input: ++ * action - Action for Un-assign ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can configure action of upstream Un-assign svid packet. If action is not ++ * trap to CPU, the port-based SVID sure be assign as system need ++ */ ++extern rtk_api_ret_t rtk_svlan_unassign_action_set(rtk_svlan_unassign_action_t action); ++ ++/* Function Name: ++ * rtk_svlan_unassign_action_get ++ * Description: ++ * Get action of upstream without svid assignment ++ * Input: ++ * None ++ * Output: ++ * pAction - Action for Un-assign ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * Note: ++ * None ++ */ ++extern rtk_api_ret_t rtk_svlan_unassign_action_get(rtk_svlan_unassign_action_t *pAction); ++ ++ ++/* Function Name: ++ * rtk_svlan_checkAndCreateMbr ++ * Description: ++ * Check and create Member configuration and return index ++ * Input: ++ * vid - VLAN id. ++ * Output: ++ * pIndex - Member configuration index ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_VLAN_VID - Invalid VLAN ID. ++ * RT_ERR_TBL_FULL - Member Configuration table full ++ * Note: ++ * ++ */ ++extern rtk_api_ret_t rtk_svlan_checkAndCreateMbr(rtk_vlan_t vid, rtk_uint32 *pIndex); ++ ++ ++#endif /* __RTK_API_SVLAN_H__ */ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/trap.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/trap.h +new file mode 100644 +index 0000000000..0cdb64a77b +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/trap.h +@@ -0,0 +1,757 @@ ++/* ++ * 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 Trap module high-layer API defination ++ * ++ */ ++ ++#ifndef __RTK_API_TRAP_H__ ++#define __RTK_API_TRAP_H__ ++ ++ ++typedef enum rtk_trap_type_e ++{ ++ TRAP_BRG_GROUP = 0, ++ TRAP_FD_PAUSE, ++ TRAP_SP_MCAST, ++ TRAP_1X_PAE, ++ TRAP_UNDEF_BRG_04, ++ TRAP_UNDEF_BRG_05, ++ TRAP_UNDEF_BRG_06, ++ TRAP_UNDEF_BRG_07, ++ TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, ++ TRAP_UNDEF_BRG_09, ++ TRAP_UNDEF_BRG_0A, ++ TRAP_UNDEF_BRG_0B, ++ TRAP_UNDEF_BRG_0C, ++ TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, ++ TRAP_8021AB, ++ TRAP_UNDEF_BRG_0F, ++ TRAP_BRG_MNGEMENT, ++ TRAP_UNDEFINED_11, ++ TRAP_UNDEFINED_12, ++ TRAP_UNDEFINED_13, ++ TRAP_UNDEFINED_14, ++ TRAP_UNDEFINED_15, ++ TRAP_UNDEFINED_16, ++ TRAP_UNDEFINED_17, ++ TRAP_UNDEFINED_18, ++ TRAP_UNDEFINED_19, ++ TRAP_UNDEFINED_1A, ++ TRAP_UNDEFINED_1B, ++ TRAP_UNDEFINED_1C, ++ TRAP_UNDEFINED_1D, ++ TRAP_UNDEFINED_1E, ++ TRAP_UNDEFINED_1F, ++ TRAP_GMRP, ++ TRAP_GVRP, ++ TRAP_UNDEF_GARP_22, ++ TRAP_UNDEF_GARP_23, ++ TRAP_UNDEF_GARP_24, ++ TRAP_UNDEF_GARP_25, ++ TRAP_UNDEF_GARP_26, ++ TRAP_UNDEF_GARP_27, ++ TRAP_UNDEF_GARP_28, ++ TRAP_UNDEF_GARP_29, ++ TRAP_UNDEF_GARP_2A, ++ TRAP_UNDEF_GARP_2B, ++ TRAP_UNDEF_GARP_2C, ++ TRAP_UNDEF_GARP_2D, ++ TRAP_UNDEF_GARP_2E, ++ TRAP_UNDEF_GARP_2F, ++ TRAP_CDP, ++ TRAP_CSSTP, ++ TRAP_LLDP, ++ TRAP_END, ++}rtk_trap_type_t; ++ ++ ++typedef enum rtk_mcast_type_e ++{ ++ MCAST_L2 = 0, ++ MCAST_IPV4, ++ MCAST_IPV6, ++ MCAST_END ++} rtk_mcast_type_t; ++ ++typedef enum rtk_trap_mcast_action_e ++{ ++ MCAST_ACTION_FORWARD = 0, ++ MCAST_ACTION_DROP, ++ MCAST_ACTION_TRAP2CPU, ++ MCAST_ACTION_ROUTER_PORT, ++ MCAST_ACTION_DROP_EX_RMA, ++ MCAST_ACTION_END ++} rtk_trap_mcast_action_t; ++ ++typedef enum rtk_trap_rma_action_e ++{ ++ RMA_ACTION_FORWARD = 0, ++ RMA_ACTION_TRAP2CPU, ++ RMA_ACTION_DROP, ++ RMA_ACTION_FORWARD_EXCLUDE_CPU, ++ RMA_ACTION_END ++} rtk_trap_rma_action_t; ++ ++typedef enum rtk_trap_ucast_action_e ++{ ++ UCAST_ACTION_FORWARD_PMASK = 0, ++ UCAST_ACTION_DROP, ++ UCAST_ACTION_TRAP2CPU, ++ UCAST_ACTION_FLOODING, ++ UCAST_ACTION_END ++} rtk_trap_ucast_action_t; ++ ++typedef enum rtk_trap_ucast_type_e ++{ ++ UCAST_UNKNOWNDA = 0, ++ UCAST_UNKNOWNSA, ++ UCAST_UNMATCHSA, ++ UCAST_END ++} rtk_trap_ucast_type_t; ++ ++typedef enum rtk_trap_reason_type_e ++{ ++ TRAP_REASON_RMA = 0, ++ TRAP_REASON_OAM, ++ TRAP_REASON_1XUNAUTH, ++ TRAP_REASON_VLANSTACK, ++ TRAP_REASON_UNKNOWNMC, ++ TRAP_REASON_END, ++} rtk_trap_reason_type_t; ++ ++ ++/* Function Name: ++ * rtk_trap_unknownUnicastPktAction_set ++ * Description: ++ * Set unknown unicast packet action configuration. ++ * Input: ++ * port - ingress port ID for unknown unicast packet ++ * ucast_action - Unknown unicast action. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NOT_ALLOWED - Invalid action. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * This API can set unknown unicast packet action configuration. ++ * The unknown unicast action is as following: ++ * - UCAST_ACTION_FORWARD_PMASK ++ * - UCAST_ACTION_DROP ++ * - UCAST_ACTION_TRAP2CPU ++ * - UCAST_ACTION_FLOODING ++ */ ++rtk_api_ret_t rtk_trap_unknownUnicastPktAction_set(rtk_port_t port, rtk_trap_ucast_action_t ucast_action); ++ ++/* Function Name: ++ * rtk_trap_unknownUnicastPktAction_get ++ * Description: ++ * Get unknown unicast packet action configuration. ++ * Input: ++ * port - ingress port ID for unknown unicast packet ++ * Output: ++ * pUcast_action - Unknown unicast action. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NOT_ALLOWED - Invalid action. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * RT_ERR_NULL_POINTER - Null pointer ++ * Note: ++ * This API can get unknown unicast packet action configuration. ++ * The unknown unicast action is as following: ++ * - UCAST_ACTION_FORWARD_PMASK ++ * - UCAST_ACTION_DROP ++ * - UCAST_ACTION_TRAP2CPU ++ * - UCAST_ACTION_FLOODING ++ */ ++rtk_api_ret_t rtk_trap_unknownUnicastPktAction_get(rtk_port_t port, rtk_trap_ucast_action_t *pUcast_action); ++ ++/* Function Name: ++ * rtk_trap_unknownMacPktAction_set ++ * Description: ++ * Set unknown source MAC packet action configuration. ++ * Input: ++ * ucast_action - Unknown source MAC action. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NOT_ALLOWED - Invalid action. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * This API can set unknown unicast packet action configuration. ++ * The unknown unicast action is as following: ++ * - UCAST_ACTION_FORWARD_PMASK ++ * - UCAST_ACTION_DROP ++ * - UCAST_ACTION_TRAP2CPU ++ */ ++extern rtk_api_ret_t rtk_trap_unknownMacPktAction_set(rtk_trap_ucast_action_t ucast_action); ++ ++/* Function Name: ++ * rtk_trap_unknownMacPktAction_get ++ * Description: ++ * Get unknown source MAC packet action configuration. ++ * Input: ++ * None. ++ * Output: ++ * pUcast_action - Unknown source MAC action. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NULL_POINTER - Null Pointer. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * ++ */ ++extern rtk_api_ret_t rtk_trap_unknownMacPktAction_get(rtk_trap_ucast_action_t *pUcast_action); ++ ++/* Function Name: ++ * rtk_trap_unmatchMacPktAction_set ++ * Description: ++ * Set unmatch source MAC packet action configuration. ++ * Input: ++ * ucast_action - Unknown source MAC action. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NOT_ALLOWED - Invalid action. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * This API can set unknown unicast packet action configuration. ++ * The unknown unicast action is as following: ++ * - UCAST_ACTION_FORWARD_PMASK ++ * - UCAST_ACTION_DROP ++ * - UCAST_ACTION_TRAP2CPU ++ */ ++extern rtk_api_ret_t rtk_trap_unmatchMacPktAction_set(rtk_trap_ucast_action_t ucast_action); ++ ++/* Function Name: ++ * rtk_trap_unmatchMacPktAction_get ++ * Description: ++ * Get unmatch source MAC packet action configuration. ++ * Input: ++ * None. ++ * Output: ++ * pUcast_action - Unknown source MAC action. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NOT_ALLOWED - Invalid action. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * This API can set unknown unicast packet action configuration. ++ * The unknown unicast action is as following: ++ * - UCAST_ACTION_FORWARD_PMASK ++ * - UCAST_ACTION_DROP ++ * - UCAST_ACTION_TRAP2CPU ++ */ ++extern rtk_api_ret_t rtk_trap_unmatchMacPktAction_get(rtk_trap_ucast_action_t *pUcast_action); ++ ++/* Function Name: ++ * rtk_trap_unmatchMacMoving_set ++ * Description: ++ * Set unmatch source MAC packet moving state. ++ * Input: ++ * port - Port ID. ++ * enable - ENABLED: allow SA moving, DISABLE: don't allow SA moving. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NOT_ALLOWED - Invalid action. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ */ ++extern rtk_api_ret_t rtk_trap_unmatchMacMoving_set(rtk_port_t port, rtk_enable_t enable); ++ ++/* Function Name: ++ * rtk_trap_unmatchMacMoving_get ++ * Description: ++ * Set unmatch source MAC packet moving state. ++ * Input: ++ * port - Port ID. ++ * Output: ++ * pEnable - ENABLED: allow SA moving, DISABLE: don't allow SA moving. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NOT_ALLOWED - Invalid action. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ */ ++extern rtk_api_ret_t rtk_trap_unmatchMacMoving_get(rtk_port_t port, rtk_enable_t *pEnable); ++ ++/* Function Name: ++ * rtk_trap_unknownMcastPktAction_set ++ * Description: ++ * Set behavior of unknown multicast ++ * Input: ++ * port - Port id. ++ * type - unknown multicast packet type. ++ * mcast_action - unknown multicast 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_NOT_ALLOWED - Invalid action. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * When receives an unknown multicast packet, switch may trap, drop or flood this packet ++ * (1) The unknown multicast packet type is as following: ++ * - MCAST_L2 ++ * - MCAST_IPV4 ++ * - MCAST_IPV6 ++ * (2) The unknown multicast action is as following: ++ * - MCAST_ACTION_FORWARD ++ * - MCAST_ACTION_DROP ++ * - MCAST_ACTION_TRAP2CPU ++ */ ++extern rtk_api_ret_t rtk_trap_unknownMcastPktAction_set(rtk_port_t port, rtk_mcast_type_t type, rtk_trap_mcast_action_t mcast_action); ++ ++/* Function Name: ++ * rtk_trap_unknownMcastPktAction_get ++ * Description: ++ * Get behavior of unknown multicast ++ * Input: ++ * type - unknown multicast packet type. ++ * Output: ++ * pMcast_action - unknown multicast action. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number. ++ * RT_ERR_NOT_ALLOWED - Invalid operation. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * When receives an unknown multicast packet, switch may trap, drop or flood this packet ++ * (1) The unknown multicast packet type is as following: ++ * - MCAST_L2 ++ * - MCAST_IPV4 ++ * - MCAST_IPV6 ++ * (2) The unknown multicast action is as following: ++ * - MCAST_ACTION_FORWARD ++ * - MCAST_ACTION_DROP ++ * - MCAST_ACTION_TRAP2CPU ++ */ ++extern rtk_api_ret_t rtk_trap_unknownMcastPktAction_get(rtk_port_t port, rtk_mcast_type_t type, rtk_trap_mcast_action_t *pMcast_action); ++ ++/* Function Name: ++ * rtk_trap_lldpEnable_set ++ * Description: ++ * Set LLDP enable. ++ * Input: ++ * enabled - LLDP enable, 0: follow RMA, 1: use LLDP action. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NOT_ALLOWED - Invalid action. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * - DMAC Assignment ++ * - 01:80:c2:00:00:0e ethertype = 0x88CC LLDP ++ * - 01:80:c2:00:00:03 ethertype = 0x88CC ++ * - 01:80:c2:00:00:00 ethertype = 0x88CC ++ ++ */ ++extern rtk_api_ret_t rtk_trap_lldpEnable_set(rtk_enable_t enabled); ++ ++/* Function Name: ++ * rtk_trap_lldpEnable_get ++ * Description: ++ * Get LLDP status. ++ * Input: ++ * None ++ * Output: ++ * pEnabled - LLDP enable, 0: follow RMA, 1: use LLDP action. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * LLDP is as following definition. ++ * - DMAC Assignment ++ * - 01:80:c2:00:00:0e ethertype = 0x88CC LLDP ++ * - 01:80:c2:00:00:03 ethertype = 0x88CC ++ * - 01:80:c2:00:00:00 ethertype = 0x88CC ++ */ ++extern rtk_api_ret_t rtk_trap_lldpEnable_get(rtk_enable_t *pEnabled); ++ ++/* Function Name: ++ * rtk_trap_reasonTrapToCpuPriority_set ++ * Description: ++ * Set priority value of a packet that trapped to CPU port according to specific reason. ++ * Input: ++ * type - reason that trap to CPU port. ++ * priority - internal priority that is going to be set for specific trap reason. ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_NOT_INIT - The module is not initial ++ * RT_ERR_INPUT - Invalid input parameter ++ * Note: ++ * Currently the trap reason that supported are listed as follows: ++ * - TRAP_REASON_RMA ++ * - TRAP_REASON_OAM ++ * - TRAP_REASON_1XUNAUTH ++ * - TRAP_REASON_VLANSTACK ++ * - TRAP_REASON_UNKNOWNMC ++ */ ++extern rtk_api_ret_t rtk_trap_reasonTrapToCpuPriority_set(rtk_trap_reason_type_t type, rtk_pri_t priority); ++ ++/* Function Name: ++ * rtk_trap_reasonTrapToCpuPriority_get ++ * Description: ++ * Get priority value of a packet that trapped to CPU port according to specific reason. ++ * Input: ++ * type - reason that trap to CPU port. ++ * Output: ++ * pPriority - configured internal priority for such reason. ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_NOT_INIT - The module is not initial ++ * RT_ERR_INPUT - Invalid input parameter ++ * RT_ERR_NULL_POINTER - NULL pointer ++ * Note: ++ * Currently the trap reason that supported are listed as follows: ++ * - TRAP_REASON_RMA ++ * - TRAP_REASON_OAM ++ * - TRAP_REASON_1XUNAUTH ++ * - TRAP_REASON_VLANSTACK ++ * - TRAP_REASON_UNKNOWNMC ++ */ ++extern rtk_api_ret_t rtk_trap_reasonTrapToCpuPriority_get(rtk_trap_reason_type_t type, rtk_pri_t *pPriority); ++ ++/* Function Name: ++ * rtk_trap_rmaAction_set ++ * Description: ++ * Set Reserved multicast address action configuration. ++ * Input: ++ * type - rma type. ++ * rma_action - RMA action. ++ * 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 IFG parameter ++ * Note: ++ * ++ * There are 48 types of Reserved Multicast Address frame for application usage. ++ * (1)They are as following definition. ++ * - TRAP_BRG_GROUP, ++ * - TRAP_FD_PAUSE, ++ * - TRAP_SP_MCAST, ++ * - TRAP_1X_PAE, ++ * - TRAP_UNDEF_BRG_04, ++ * - TRAP_UNDEF_BRG_05, ++ * - TRAP_UNDEF_BRG_06, ++ * - TRAP_UNDEF_BRG_07, ++ * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, ++ * - TRAP_UNDEF_BRG_09, ++ * - TRAP_UNDEF_BRG_0A, ++ * - TRAP_UNDEF_BRG_0B, ++ * - TRAP_UNDEF_BRG_0C, ++ * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, ++ * - TRAP_8021AB, ++ * - TRAP_UNDEF_BRG_0F, ++ * - TRAP_BRG_MNGEMENT, ++ * - TRAP_UNDEFINED_11, ++ * - TRAP_UNDEFINED_12, ++ * - TRAP_UNDEFINED_13, ++ * - TRAP_UNDEFINED_14, ++ * - TRAP_UNDEFINED_15, ++ * - TRAP_UNDEFINED_16, ++ * - TRAP_UNDEFINED_17, ++ * - TRAP_UNDEFINED_18, ++ * - TRAP_UNDEFINED_19, ++ * - TRAP_UNDEFINED_1A, ++ * - TRAP_UNDEFINED_1B, ++ * - TRAP_UNDEFINED_1C, ++ * - TRAP_UNDEFINED_1D, ++ * - TRAP_UNDEFINED_1E, ++ * - TRAP_UNDEFINED_1F, ++ * - TRAP_GMRP, ++ * - TRAP_GVRP, ++ * - TRAP_UNDEF_GARP_22, ++ * - TRAP_UNDEF_GARP_23, ++ * - TRAP_UNDEF_GARP_24, ++ * - TRAP_UNDEF_GARP_25, ++ * - TRAP_UNDEF_GARP_26, ++ * - TRAP_UNDEF_GARP_27, ++ * - TRAP_UNDEF_GARP_28, ++ * - TRAP_UNDEF_GARP_29, ++ * - TRAP_UNDEF_GARP_2A, ++ * - TRAP_UNDEF_GARP_2B, ++ * - TRAP_UNDEF_GARP_2C, ++ * - TRAP_UNDEF_GARP_2D, ++ * - TRAP_UNDEF_GARP_2E, ++ * - TRAP_UNDEF_GARP_2F, ++ * - TRAP_CDP. ++ * - TRAP_CSSTP. ++ * - TRAP_LLDP. ++ * (2) The RMA action is as following: ++ * - RMA_ACTION_FORWARD ++ * - RMA_ACTION_TRAP2CPU ++ * - RMA_ACTION_DROP ++ * - RMA_ACTION_FORWARD_EXCLUDE_CPU ++ */ ++extern rtk_api_ret_t rtk_trap_rmaAction_set(rtk_trap_type_t type, rtk_trap_rma_action_t rma_action); ++ ++/* Function Name: ++ * rtk_trap_rmaAction_get ++ * Description: ++ * Get Reserved multicast address action configuration. ++ * Input: ++ * type - rma type. ++ * Output: ++ * pRma_action - RMA action. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * There are 48 types of Reserved Multicast Address frame for application usage. ++ * (1)They are as following definition. ++ * - TRAP_BRG_GROUP, ++ * - TRAP_FD_PAUSE, ++ * - TRAP_SP_MCAST, ++ * - TRAP_1X_PAE, ++ * - TRAP_UNDEF_BRG_04, ++ * - TRAP_UNDEF_BRG_05, ++ * - TRAP_UNDEF_BRG_06, ++ * - TRAP_UNDEF_BRG_07, ++ * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, ++ * - TRAP_UNDEF_BRG_09, ++ * - TRAP_UNDEF_BRG_0A, ++ * - TRAP_UNDEF_BRG_0B, ++ * - TRAP_UNDEF_BRG_0C, ++ * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, ++ * - TRAP_8021AB, ++ * - TRAP_UNDEF_BRG_0F, ++ * - TRAP_BRG_MNGEMENT, ++ * - TRAP_UNDEFINED_11, ++ * - TRAP_UNDEFINED_12, ++ * - TRAP_UNDEFINED_13, ++ * - TRAP_UNDEFINED_14, ++ * - TRAP_UNDEFINED_15, ++ * - TRAP_UNDEFINED_16, ++ * - TRAP_UNDEFINED_17, ++ * - TRAP_UNDEFINED_18, ++ * - TRAP_UNDEFINED_19, ++ * - TRAP_UNDEFINED_1A, ++ * - TRAP_UNDEFINED_1B, ++ * - TRAP_UNDEFINED_1C, ++ * - TRAP_UNDEFINED_1D, ++ * - TRAP_UNDEFINED_1E, ++ * - TRAP_UNDEFINED_1F, ++ * - TRAP_GMRP, ++ * - TRAP_GVRP, ++ * - TRAP_UNDEF_GARP_22, ++ * - TRAP_UNDEF_GARP_23, ++ * - TRAP_UNDEF_GARP_24, ++ * - TRAP_UNDEF_GARP_25, ++ * - TRAP_UNDEF_GARP_26, ++ * - TRAP_UNDEF_GARP_27, ++ * - TRAP_UNDEF_GARP_28, ++ * - TRAP_UNDEF_GARP_29, ++ * - TRAP_UNDEF_GARP_2A, ++ * - TRAP_UNDEF_GARP_2B, ++ * - TRAP_UNDEF_GARP_2C, ++ * - TRAP_UNDEF_GARP_2D, ++ * - TRAP_UNDEF_GARP_2E, ++ * - TRAP_UNDEF_GARP_2F, ++ * - TRAP_CDP. ++ * - TRAP_CSSTP. ++ * - TRAP_LLDP. ++ * (2) The RMA action is as following: ++ * - RMA_ACTION_FORWARD ++ * - RMA_ACTION_TRAP2CPU ++ * - RMA_ACTION_DROP ++ * - RMA_ACTION_FORWARD_EXCLUDE_CPU ++ */ ++extern rtk_api_ret_t rtk_trap_rmaAction_get(rtk_trap_type_t type, rtk_trap_rma_action_t *pRma_action); ++ ++/* Function Name: ++ * rtk_trap_rmaKeepFormat_set ++ * Description: ++ * Set Reserved multicast address keep format configuration. ++ * Input: ++ * type - rma type. ++ * enable - enable keep format. ++ * 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 IFG parameter ++ * Note: ++ * ++ * There are 48 types of Reserved Multicast Address frame for application usage. ++ * They are as following definition. ++ * - TRAP_BRG_GROUP, ++ * - TRAP_FD_PAUSE, ++ * - TRAP_SP_MCAST, ++ * - TRAP_1X_PAE, ++ * - TRAP_UNDEF_BRG_04, ++ * - TRAP_UNDEF_BRG_05, ++ * - TRAP_UNDEF_BRG_06, ++ * - TRAP_UNDEF_BRG_07, ++ * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, ++ * - TRAP_UNDEF_BRG_09, ++ * - TRAP_UNDEF_BRG_0A, ++ * - TRAP_UNDEF_BRG_0B, ++ * - TRAP_UNDEF_BRG_0C, ++ * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, ++ * - TRAP_8021AB, ++ * - TRAP_UNDEF_BRG_0F, ++ * - TRAP_BRG_MNGEMENT, ++ * - TRAP_UNDEFINED_11, ++ * - TRAP_UNDEFINED_12, ++ * - TRAP_UNDEFINED_13, ++ * - TRAP_UNDEFINED_14, ++ * - TRAP_UNDEFINED_15, ++ * - TRAP_UNDEFINED_16, ++ * - TRAP_UNDEFINED_17, ++ * - TRAP_UNDEFINED_18, ++ * - TRAP_UNDEFINED_19, ++ * - TRAP_UNDEFINED_1A, ++ * - TRAP_UNDEFINED_1B, ++ * - TRAP_UNDEFINED_1C, ++ * - TRAP_UNDEFINED_1D, ++ * - TRAP_UNDEFINED_1E, ++ * - TRAP_UNDEFINED_1F, ++ * - TRAP_GMRP, ++ * - TRAP_GVRP, ++ * - TRAP_UNDEF_GARP_22, ++ * - TRAP_UNDEF_GARP_23, ++ * - TRAP_UNDEF_GARP_24, ++ * - TRAP_UNDEF_GARP_25, ++ * - TRAP_UNDEF_GARP_26, ++ * - TRAP_UNDEF_GARP_27, ++ * - TRAP_UNDEF_GARP_28, ++ * - TRAP_UNDEF_GARP_29, ++ * - TRAP_UNDEF_GARP_2A, ++ * - TRAP_UNDEF_GARP_2B, ++ * - TRAP_UNDEF_GARP_2C, ++ * - TRAP_UNDEF_GARP_2D, ++ * - TRAP_UNDEF_GARP_2E, ++ * - TRAP_UNDEF_GARP_2F, ++ * - TRAP_CDP. ++ * - TRAP_CSSTP. ++ * - TRAP_LLDP. ++ */ ++extern rtk_api_ret_t rtk_trap_rmaKeepFormat_set(rtk_trap_type_t type, rtk_enable_t enable); ++ ++/* Function Name: ++ * rtk_trap_rmaKeepFormat_get ++ * Description: ++ * Get Reserved multicast address action configuration. ++ * Input: ++ * type - rma type. ++ * Output: ++ * pEnable - keep format status. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * There are 48 types of Reserved Multicast Address frame for application usage. ++ * They are as following definition. ++ * - TRAP_BRG_GROUP, ++ * - TRAP_FD_PAUSE, ++ * - TRAP_SP_MCAST, ++ * - TRAP_1X_PAE, ++ * - TRAP_UNDEF_BRG_04, ++ * - TRAP_UNDEF_BRG_05, ++ * - TRAP_UNDEF_BRG_06, ++ * - TRAP_UNDEF_BRG_07, ++ * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, ++ * - TRAP_UNDEF_BRG_09, ++ * - TRAP_UNDEF_BRG_0A, ++ * - TRAP_UNDEF_BRG_0B, ++ * - TRAP_UNDEF_BRG_0C, ++ * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, ++ * - TRAP_8021AB, ++ * - TRAP_UNDEF_BRG_0F, ++ * - TRAP_BRG_MNGEMENT, ++ * - TRAP_UNDEFINED_11, ++ * - TRAP_UNDEFINED_12, ++ * - TRAP_UNDEFINED_13, ++ * - TRAP_UNDEFINED_14, ++ * - TRAP_UNDEFINED_15, ++ * - TRAP_UNDEFINED_16, ++ * - TRAP_UNDEFINED_17, ++ * - TRAP_UNDEFINED_18, ++ * - TRAP_UNDEFINED_19, ++ * - TRAP_UNDEFINED_1A, ++ * - TRAP_UNDEFINED_1B, ++ * - TRAP_UNDEFINED_1C, ++ * - TRAP_UNDEFINED_1D, ++ * - TRAP_UNDEFINED_1E, ++ * - TRAP_UNDEFINED_1F, ++ * - TRAP_GMRP, ++ * - TRAP_GVRP, ++ * - TRAP_UNDEF_GARP_22, ++ * - TRAP_UNDEF_GARP_23, ++ * - TRAP_UNDEF_GARP_24, ++ * - TRAP_UNDEF_GARP_25, ++ * - TRAP_UNDEF_GARP_26, ++ * - TRAP_UNDEF_GARP_27, ++ * - TRAP_UNDEF_GARP_28, ++ * - TRAP_UNDEF_GARP_29, ++ * - TRAP_UNDEF_GARP_2A, ++ * - TRAP_UNDEF_GARP_2B, ++ * - TRAP_UNDEF_GARP_2C, ++ * - TRAP_UNDEF_GARP_2D, ++ * - TRAP_UNDEF_GARP_2E, ++ * - TRAP_UNDEF_GARP_2F, ++ * - TRAP_CDP. ++ * - TRAP_CSSTP. ++ * - TRAP_LLDP. ++ */ ++extern rtk_api_ret_t rtk_trap_rmaKeepFormat_get(rtk_trap_type_t type, rtk_enable_t *pEnable); ++ ++ ++#endif /* __RTK_API_TRAP_H__ */ ++ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/trunk.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/trunk.h +new file mode 100644 +index 0000000000..dff61769df +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/trunk.h +@@ -0,0 +1,328 @@ ++/* ++ * 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 Trunk module high-layer TRUNK defination ++ * ++ */ ++ ++#ifndef __RTK_API_TRUNK_H__ ++#define __RTK_API_TRUNK_H__ ++ ++/* ++ * Data Type Declaration ++ */ ++#define RTK_TRUNK_DPORT_HASH_MASK 0x40 ++#define RTK_TRUNK_SPORT_HASH_MASK 0x20 ++#define RTK_TRUNK_DIP_HASH_MASK 0x10 ++#define RTK_TRUNK_SIP_HASH_MASK 0x8 ++#define RTK_TRUNK_DMAC_HASH_MASK 0x4 ++#define RTK_TRUNK_SMAC_HASH_MASK 0x2 ++#define RTK_TRUNK_SPA_HASH_MASK 0x1 ++ ++ ++#define RTK_MAX_NUM_OF_TRUNK_HASH_VAL 16 ++ ++typedef struct rtk_trunk_hashVal2Port_s ++{ ++ rtk_uint8 value[RTK_MAX_NUM_OF_TRUNK_HASH_VAL]; ++} rtk_trunk_hashVal2Port_t; ++ ++typedef enum rtk_trunk_group_e ++{ ++ TRUNK_GROUP0 = 0, ++ TRUNK_GROUP1, ++ TRUNK_GROUP2, ++ TRUNK_GROUP3, ++ TRUNK_GROUP_END ++} rtk_trunk_group_t; ++ ++typedef enum rtk_trunk_separateType_e ++{ ++ SEPARATE_NONE = 0, ++ SEPARATE_FLOOD, ++ SEPARATE_END ++ ++} rtk_trunk_separateType_t; ++ ++typedef enum rtk_trunk_mode_e ++{ ++ TRUNK_MODE_NORMAL = 0, ++ TRUNK_MODE_DUMB, ++ TRUNK_MODE_END ++} rtk_trunk_mode_t; ++ ++/* Function Name: ++ * rtk_trunk_port_set ++ * Description: ++ * Set trunking group available port mask ++ * Input: ++ * trk_gid - trunk group id ++ * pTrunk_member_portmask - Logic trunking member port mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_LA_TRUNK_ID - Invalid trunking group ++ * RT_ERR_PORT_MASK - Invalid portmask. ++ * Note: ++ * The API can set port trunking group port mask. Each port trunking group has max 4 ports. ++ * If enabled port mask has less than 2 ports available setting, then this trunking group function is disabled. ++ */ ++extern rtk_api_ret_t rtk_trunk_port_set(rtk_trunk_group_t trk_gid, rtk_portmask_t *pTrunk_member_portmask); ++ ++/* Function Name: ++ * rtk_trunk_port_get ++ * Description: ++ * Get trunking group available port mask ++ * Input: ++ * trk_gid - trunk group id ++ * Output: ++ * pTrunk_member_portmask - Logic trunking member port mask ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_LA_TRUNK_ID - Invalid trunking group ++ * Note: ++ * The API can get 2 port trunking group. ++ */ ++extern rtk_api_ret_t rtk_trunk_port_get(rtk_trunk_group_t trk_gid, rtk_portmask_t *pTrunk_member_portmask); ++ ++/* Function Name: ++ * rtk_trunk_distributionAlgorithm_set ++ * Description: ++ * Set port trunking hash select sources ++ * Input: ++ * trk_gid - trunk group id ++ * algo_bitmask - Bitmask of the distribution algorithm ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_LA_TRUNK_ID - Invalid trunking group ++ * RT_ERR_LA_HASHMASK - Hash algorithm selection error. ++ * RT_ERR_PORT_MASK - Invalid portmask. ++ * Note: ++ * The API can set port trunking hash algorithm sources. ++ * 7 bits mask for link aggregation group0 hash parameter selection {DIP, SIP, DMAC, SMAC, SPA} ++ * - 0b0000001: SPA ++ * - 0b0000010: SMAC ++ * - 0b0000100: DMAC ++ * - 0b0001000: SIP ++ * - 0b0010000: DIP ++ * - 0b0100000: TCP/UDP Source Port ++ * - 0b1000000: TCP/UDP Destination Port ++ * Example: ++ * - 0b0000011: SMAC & SPA ++ * - Note that it could be an arbitrary combination or independent set ++ */ ++extern rtk_api_ret_t rtk_trunk_distributionAlgorithm_set(rtk_trunk_group_t trk_gid, rtk_uint32 algo_bitmask); ++ ++/* Function Name: ++ * rtk_trunk_distributionAlgorithm_get ++ * Description: ++ * Get port trunking hash select sources ++ * Input: ++ * trk_gid - trunk group id ++ * Output: ++ * pAlgo_bitmask - Bitmask of the distribution algorithm ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_LA_TRUNK_ID - Invalid trunking group ++ * Note: ++ * The API can get port trunking hash algorithm sources. ++ */ ++extern rtk_api_ret_t rtk_trunk_distributionAlgorithm_get(rtk_trunk_group_t trk_gid, rtk_uint32 *pAlgo_bitmask); ++ ++/* Function Name: ++ * rtk_trunk_trafficSeparate_set ++ * Description: ++ * Set the traffic separation setting of a trunk group from the specified device. ++ * Input: ++ * trk_gid - trunk group id ++ * separateType - traffic separation setting ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_UNIT_ID - invalid unit id ++ * RT_ERR_LA_TRUNK_ID - invalid trunk ID ++ * RT_ERR_LA_HASHMASK - invalid hash mask ++ * Note: ++ * SEPARATE_NONE: disable traffic separation ++ * SEPARATE_FLOOD: trunk MSB link up port is dedicated to TX flooding (L2 lookup miss) traffic ++ */ ++extern rtk_api_ret_t rtk_trunk_trafficSeparate_set(rtk_trunk_group_t trk_gid, rtk_trunk_separateType_t separateType); ++ ++/* Function Name: ++ * rtk_trunk_trafficSeparate_get ++ * Description: ++ * Get the traffic separation setting of a trunk group from the specified device. ++ * Input: ++ * trk_gid - trunk group id ++ * Output: ++ * pSeparateType - pointer separated traffic type ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_UNIT_ID - invalid unit id ++ * RT_ERR_LA_TRUNK_ID - invalid trunk ID ++ * RT_ERR_NULL_POINTER - input parameter may be null pointer ++ * Note: ++ * SEPARATE_NONE: disable traffic separation ++ * SEPARATE_FLOOD: trunk MSB link up port is dedicated to TX flooding (L2 lookup miss) traffic ++ */ ++extern rtk_api_ret_t rtk_trunk_trafficSeparate_get(rtk_trunk_group_t trk_gid, rtk_trunk_separateType_t *pSeparateType); ++ ++ ++/* Function Name: ++ * rtk_trunk_mode_set ++ * Description: ++ * Set the trunk mode to the specified device. ++ * Input: ++ * mode - trunk mode ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_INPUT - invalid input parameter ++ * Note: ++ * The enum of the trunk mode as following ++ * - TRUNK_MODE_NORMAL ++ * - TRUNK_MODE_DUMB ++ */ ++extern rtk_api_ret_t rtk_trunk_mode_set(rtk_trunk_mode_t mode); ++ ++/* Function Name: ++ * rtk_trunk_mode_get ++ * Description: ++ * Get the trunk mode from the specified device. ++ * Input: ++ * None ++ * Output: ++ * pMode - pointer buffer of trunk mode ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_NULL_POINTER - input parameter may be null pointer ++ * Note: ++ * The enum of the trunk mode as following ++ * - TRUNK_MODE_NORMAL ++ * - TRUNK_MODE_DUMB ++ */ ++extern rtk_api_ret_t rtk_trunk_mode_get(rtk_trunk_mode_t *pMode); ++ ++/* Function Name: ++ * rtk_trunk_trafficPause_set ++ * Description: ++ * Set the traffic pause setting of a trunk group. ++ * Input: ++ * trk_gid - trunk group id ++ * enable - traffic pause state ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_LA_TRUNK_ID - invalid trunk ID ++ * Note: ++ * None. ++ */ ++extern rtk_api_ret_t rtk_trunk_trafficPause_set(rtk_trunk_group_t trk_gid, rtk_enable_t enable); ++ ++/* Function Name: ++ * rtk_trunk_trafficPause_get ++ * Description: ++ * Get the traffic pause setting of a trunk group. ++ * Input: ++ * trk_gid - trunk group id ++ * Output: ++ * pEnable - pointer of traffic pause state. ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_LA_TRUNK_ID - invalid trunk ID ++ * RT_ERR_NULL_POINTER - input parameter may be null pointer ++ * Note: ++ * None. ++ */ ++extern rtk_api_ret_t rtk_trunk_trafficPause_get(rtk_trunk_group_t trk_gid, rtk_enable_t *pEnable); ++ ++/* Function Name: ++ * rtk_trunk_hashMappingTable_set ++ * Description: ++ * Set hash value to port array in the trunk group id from the specified device. ++ * Input: ++ * trk_gid - trunk group id ++ * pHash2Port_array - ports associate with the hash value ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_UNIT_ID - invalid unit id ++ * RT_ERR_LA_TRUNK_ID - invalid trunk ID ++ * RT_ERR_NULL_POINTER - input parameter may be null pointer ++ * RT_ERR_LA_TRUNK_NOT_EXIST - the trunk doesn't exist ++ * RT_ERR_LA_NOT_MEMBER_PORT - the port is not a member port of the trunk ++ * RT_ERR_LA_CPUPORT - CPU port can not be aggregated port ++ * Note: ++ * Trunk group 0 & 1 shares the same hash mapping table. ++ * Trunk group 2 uses a independent table. ++ */ ++extern rtk_api_ret_t rtk_trunk_hashMappingTable_set(rtk_trunk_group_t trk_gid, rtk_trunk_hashVal2Port_t *pHash2Port_array); ++ ++/* Function Name: ++ * rtk_trunk_hashMappingTable_get ++ * Description: ++ * Get hash value to port array in the trunk group id from the specified device. ++ * Input: ++ * trk_gid - trunk group id ++ * Output: ++ * pHash2Port_array - pointer buffer of ports associate with the hash value ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_UNIT_ID - invalid unit id ++ * RT_ERR_LA_TRUNK_ID - invalid trunk ID ++ * RT_ERR_NULL_POINTER - input parameter may be null pointer ++ * Note: ++ * Trunk group 0 & 1 shares the same hash mapping table. ++ * Trunk group 2 uses a independent table. ++ */ ++extern rtk_api_ret_t rtk_trunk_hashMappingTable_get(rtk_trunk_group_t trk_gid, rtk_trunk_hashVal2Port_t *pHash2Port_array); ++ ++/* Function Name: ++ * rtk_trunk_portQueueEmpty_get ++ * Description: ++ * Get the port mask which all queues are empty. ++ * Input: ++ * None. ++ * Output: ++ * pEmpty_portmask - pointer empty port mask ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_NULL_POINTER - input parameter may be null pointer ++ * Note: ++ * None. ++ */ ++extern rtk_api_ret_t rtk_trunk_portQueueEmpty_get(rtk_portmask_t *pEmpty_portmask); ++ ++#endif /* __RTK_API_TRUNK_H__ */ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/vlan.h b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/vlan.h +new file mode 100644 +index 0000000000..8569fc0d40 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/include/vlan.h +@@ -0,0 +1,892 @@ ++/* ++ * 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 Trap module high-layer VLAN defination ++ * ++ */ ++ ++#ifndef __RTK_API_VLAN_H__ ++#define __RTK_API_VLAN_H__ ++ ++ ++/* ++ * Data Type Declaration ++ */ ++#define RTK_MAX_NUM_OF_PROTO_TYPE 0xFFFF ++#define RTK_MAX_NUM_OF_MSTI 0xF ++#define RTK_FID_MAX 0xF ++ ++typedef struct rtk_vlan_cfg_s ++{ ++ rtk_portmask_t mbr; ++ rtk_portmask_t untag; ++ rtk_uint16 ivl_en; ++ rtk_uint16 fid_msti; ++ rtk_uint16 envlanpol; ++ rtk_uint16 meteridx; ++ rtk_uint16 vbpen; ++ rtk_uint16 vbpri; ++}rtk_vlan_cfg_t; ++ ++typedef struct rtk_vlan_mbrcfg_s ++{ ++ rtk_uint16 evid; ++ rtk_portmask_t mbr; ++ rtk_uint16 fid_msti; ++ rtk_uint16 envlanpol; ++ rtk_uint16 meteridx; ++ rtk_uint16 vbpen; ++ rtk_uint16 vbpri; ++}rtk_vlan_mbrcfg_t; ++ ++typedef rtk_uint32 rtk_stp_msti_id_t; /* MSTI ID */ ++ ++typedef enum rtk_stp_state_e ++{ ++ STP_STATE_DISABLED = 0, ++ STP_STATE_BLOCKING, ++ STP_STATE_LEARNING, ++ STP_STATE_FORWARDING, ++ STP_STATE_END ++} rtk_stp_state_t; ++ ++typedef rtk_uint32 rtk_vlan_proto_type_t; /* protocol and port based VLAN protocol type */ ++ ++ ++typedef enum rtk_vlan_acceptFrameType_e ++{ ++ ACCEPT_FRAME_TYPE_ALL = 0, /* untagged, priority-tagged and tagged */ ++ ACCEPT_FRAME_TYPE_TAG_ONLY, /* tagged */ ++ ACCEPT_FRAME_TYPE_UNTAG_ONLY, /* untagged and priority-tagged */ ++ ACCEPT_FRAME_TYPE_END ++} rtk_vlan_acceptFrameType_t; ++ ++ ++/* frame type of protocol vlan - reference 802.1v standard */ ++typedef enum rtk_vlan_protoVlan_frameType_e ++{ ++ FRAME_TYPE_ETHERNET = 0, ++ FRAME_TYPE_LLCOTHER, ++ FRAME_TYPE_RFC1042, ++ FRAME_TYPE_END ++} rtk_vlan_protoVlan_frameType_t; ++ ++/* Protocol-and-port-based Vlan structure */ ++typedef struct rtk_vlan_protoAndPortInfo_s ++{ ++ rtk_uint32 proto_type; ++ rtk_vlan_protoVlan_frameType_t frame_type; ++ rtk_vlan_t cvid; ++ rtk_pri_t cpri; ++}rtk_vlan_protoAndPortInfo_t; ++ ++/* tagged mode of VLAN - reference realtek private specification */ ++typedef enum rtk_vlan_tagMode_e ++{ ++ VLAN_TAG_MODE_ORIGINAL = 0, ++ VLAN_TAG_MODE_KEEP_FORMAT, ++ VLAN_TAG_MODE_PRI, ++ VLAN_TAG_MODE_REAL_KEEP_FORMAT, ++ VLAN_TAG_MODE_END ++} rtk_vlan_tagMode_t; ++ ++typedef enum rtk_vlan_resVidAction_e ++{ ++ RESVID_ACTION_UNTAG = 0, ++ RESVID_ACTION_TAG, ++ RESVID_ACTION_END ++} ++rtk_vlan_resVidAction_t; ++ ++/* Function Name: ++ * rtk_vlan_init ++ * Description: ++ * Initialize VLAN. ++ * Input: ++ * None ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * VLAN is disabled by default. User has to call this API to enable VLAN before ++ * using it. And It will set a default VLAN(vid 1) including all ports and set ++ * all ports PVID to the default VLAN. ++ */ ++extern rtk_api_ret_t rtk_vlan_init(void); ++ ++/* Function Name: ++ * rtk_vlan_set ++ * Description: ++ * Set a VLAN entry. ++ * Input: ++ * vid - VLAN ID to configure. ++ * pVlanCfg - VLAN Configuration ++ * 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_L2_FID - Invalid FID. ++ * RT_ERR_VLAN_PORT_MBR_EXIST - Invalid member port mask. ++ * RT_ERR_VLAN_VID - Invalid VID parameter. ++ * Note: ++ * ++ */ ++extern rtk_api_ret_t rtk_vlan_set(rtk_vlan_t vid, rtk_vlan_cfg_t *pVlanCfg); ++ ++/* Function Name: ++ * rtk_vlan_get ++ * Description: ++ * Get a VLAN entry. ++ * Input: ++ * vid - VLAN ID to configure. ++ * Output: ++ * pVlanCfg - VLAN Configuration ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters. ++ * RT_ERR_VLAN_VID - Invalid VID parameter. ++ * Note: ++ * ++ */ ++extern rtk_api_ret_t rtk_vlan_get(rtk_vlan_t vid, rtk_vlan_cfg_t *pVlanCfg); ++ ++/* Function Name: ++ * rtk_vlan_egrFilterEnable_set ++ * Description: ++ * Set VLAN egress filter. ++ * Input: ++ * egrFilter - Egress filtering ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_ENABLE - Invalid input parameters. ++ * Note: ++ * ++ */ ++extern rtk_api_ret_t rtk_vlan_egrFilterEnable_set(rtk_enable_t egrFilter); ++ ++/* Function Name: ++ * rtk_vlan_egrFilterEnable_get ++ * Description: ++ * Get VLAN egress filter. ++ * Input: ++ * pEgrFilter - Egress filtering ++ * Output: ++ * None. ++ * 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_vlan_egrFilterEnable_get(rtk_enable_t *pEgrFilter); ++ ++/* Function Name: ++ * rtk_vlan_mbrCfg_set ++ * Description: ++ * Set a VLAN Member Configuration entry by index. ++ * Input: ++ * idx - Index of VLAN Member Configuration. ++ * pMbrcfg - VLAN member Configuration. ++ * 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_VID - Invalid VID parameter. ++ * Note: ++ * Set a VLAN Member Configuration entry by index. ++ */ ++extern rtk_api_ret_t rtk_vlan_mbrCfg_set(rtk_uint32 idx, rtk_vlan_mbrcfg_t *pMbrcfg); ++ ++/* Function Name: ++ * rtk_vlan_mbrCfg_get ++ * Description: ++ * Get a VLAN Member Configuration entry by index. ++ * Input: ++ * idx - Index of VLAN Member Configuration. ++ * Output: ++ * pMbrcfg - VLAN member Configuration. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters. ++ * RT_ERR_VLAN_VID - Invalid VID parameter. ++ * Note: ++ * Get a VLAN Member Configuration entry by index. ++ */ ++extern rtk_api_ret_t rtk_vlan_mbrCfg_get(rtk_uint32 idx, rtk_vlan_mbrcfg_t *pMbrcfg); ++ ++/* Function Name: ++ * rtk_vlan_portPvid_set ++ * Description: ++ * Set port to specified VLAN ID(PVID). ++ * Input: ++ * port - Port id. ++ * pvid - Specified VLAN ID. ++ * priority - 802.1p priority for the PVID. ++ * 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_VLAN_PRIORITY - Invalid priority. ++ * RT_ERR_VLAN_ENTRY_NOT_FOUND - VLAN entry not found. ++ * RT_ERR_VLAN_VID - Invalid VID parameter. ++ * Note: ++ * The API is used for Port-based VLAN. The untagged frame received from the ++ * port will be classified to the specified VLAN and assigned to the specified priority. ++ */ ++extern rtk_api_ret_t rtk_vlan_portPvid_set(rtk_port_t port, rtk_vlan_t pvid, rtk_pri_t priority); ++ ++/* Function Name: ++ * rtk_vlan_portPvid_get ++ * Description: ++ * Get VLAN ID(PVID) on specified port. ++ * Input: ++ * port - Port id. ++ * Output: ++ * pPvid - Specified VLAN ID. ++ * pPriority - 802.1p priority for the PVID. ++ * 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 PVID and 802.1p priority for the PVID of Port-based VLAN. ++ */ ++extern rtk_api_ret_t rtk_vlan_portPvid_get(rtk_port_t port, rtk_vlan_t *pPvid, rtk_pri_t *pPriority); ++ ++/* Function Name: ++ * rtk_vlan_portIgrFilterEnable_set ++ * Description: ++ * Set VLAN ingress for each port. ++ * Input: ++ * port - Port id. ++ * igr_filter - VLAN ingress function enable 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: ++ * The status of vlan ingress filter is as following: ++ * - DISABLED ++ * - ENABLED ++ * While VLAN function is enabled, ASIC will decide VLAN ID for each received frame and get belonged member ++ * ports from VLAN table. If received port is not belonged to VLAN member ports, ASIC will drop received frame if VLAN ingress function is enabled. ++ */ ++extern rtk_api_ret_t rtk_vlan_portIgrFilterEnable_set(rtk_port_t port, rtk_enable_t igr_filter); ++ ++/* Function Name: ++ * rtk_vlan_portIgrFilterEnable_get ++ * Description: ++ * Get VLAN Ingress Filter ++ * Input: ++ * port - Port id. ++ * Output: ++ * pIgr_filter - VLAN ingress function enable status. ++ * 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 VLAN ingress filter status. ++ * The status of vlan ingress filter is as following: ++ * - DISABLED ++ * - ENABLED ++ */ ++extern rtk_api_ret_t rtk_vlan_portIgrFilterEnable_get(rtk_port_t port, rtk_enable_t *pIgr_filter); ++ ++/* Function Name: ++ * rtk_vlan_portAcceptFrameType_set ++ * Description: ++ * Set VLAN accept_frame_type ++ * Input: ++ * port - Port id. ++ * accept_frame_type - accept frame type ++ * 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_VLAN_ACCEPT_FRAME_TYPE - Invalid frame type. ++ * Note: ++ * The API is used for checking 802.1Q tagged frames. ++ * The accept frame type as following: ++ * - ACCEPT_FRAME_TYPE_ALL ++ * - ACCEPT_FRAME_TYPE_TAG_ONLY ++ * - ACCEPT_FRAME_TYPE_UNTAG_ONLY ++ */ ++extern rtk_api_ret_t rtk_vlan_portAcceptFrameType_set(rtk_port_t port, rtk_vlan_acceptFrameType_t accept_frame_type); ++ ++/* Function Name: ++ * rtk_vlan_portAcceptFrameType_get ++ * Description: ++ * Get VLAN accept_frame_type ++ * Input: ++ * port - Port id. ++ * Output: ++ * pAccept_frame_type - accept frame type ++ * 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 VLAN ingress filter. ++ * The accept frame type as following: ++ * - ACCEPT_FRAME_TYPE_ALL ++ * - ACCEPT_FRAME_TYPE_TAG_ONLY ++ * - ACCEPT_FRAME_TYPE_UNTAG_ONLY ++ */ ++extern rtk_api_ret_t rtk_vlan_portAcceptFrameType_get(rtk_port_t port, rtk_vlan_acceptFrameType_t *pAccept_frame_type); ++ ++/* Function Name: ++ * rtk_vlan_tagMode_set ++ * Description: ++ * Set CVLAN egress tag mode ++ * Input: ++ * port - Port id. ++ * tag_mode - The egress tag mode. ++ * 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. ++ * RT_ERR_ENABLE - Invalid enable input. ++ * Note: ++ * The API can set Egress tag mode. There are 4 mode for egress tag: ++ * - VLAN_TAG_MODE_ORIGINAL, ++ * - VLAN_TAG_MODE_KEEP_FORMAT, ++ * - VLAN_TAG_MODE_PRI. ++ * - VLAN_TAG_MODE_REAL_KEEP_FORMAT, ++ */ ++extern rtk_api_ret_t rtk_vlan_tagMode_set(rtk_port_t port, rtk_vlan_tagMode_t tag_mode); ++ ++/* Function Name: ++ * rtk_vlan_tagMode_get ++ * Description: ++ * Get CVLAN egress tag mode ++ * Input: ++ * port - Port id. ++ * Output: ++ * pTag_mode - The egress tag mode. ++ * 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 Egress tag mode. There are 4 mode for egress tag: ++ * - VLAN_TAG_MODE_ORIGINAL, ++ * - VLAN_TAG_MODE_KEEP_FORMAT, ++ * - VLAN_TAG_MODE_PRI. ++ * - VLAN_TAG_MODE_REAL_KEEP_FORMAT, ++ */ ++extern rtk_api_ret_t rtk_vlan_tagMode_get(rtk_port_t port, rtk_vlan_tagMode_t *pTag_mode); ++ ++/* Function Name: ++ * rtk_vlan_transparent_set ++ * Description: ++ * Set VLAN transparent mode ++ * Input: ++ * egr_port - Egress Port id. ++ * pIgr_pmask - Ingress 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. ++ * RT_ERR_PORT_ID - Invalid port number. ++ * Note: ++ * None. ++ */ ++extern rtk_api_ret_t rtk_vlan_transparent_set(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask); ++ ++/* Function Name: ++ * rtk_vlan_transparent_get ++ * Description: ++ * Get VLAN transparent mode ++ * Input: ++ * egr_port - Egress Port id. ++ * Output: ++ * pIgr_pmask - Ingress Port Mask ++ * 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: ++ * None. ++ */ ++extern rtk_api_ret_t rtk_vlan_transparent_get(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask); ++ ++/* Function Name: ++ * rtk_vlan_keep_set ++ * Description: ++ * Set VLAN egress keep mode ++ * Input: ++ * egr_port - Egress Port id. ++ * pIgr_pmask - Ingress 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. ++ * RT_ERR_PORT_ID - Invalid port number. ++ * Note: ++ * None. ++ */ ++extern rtk_api_ret_t rtk_vlan_keep_set(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask); ++ ++/* Function Name: ++ * rtk_vlan_keep_get ++ * Description: ++ * Get VLAN egress keep mode ++ * Input: ++ * egr_port - Egress Port id. ++ * Output: ++ * pIgr_pmask - Ingress Port Mask ++ * 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: ++ * None. ++ */ ++extern rtk_api_ret_t rtk_vlan_keep_get(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask); ++ ++/* Function Name: ++ * rtk_vlan_stg_set ++ * Description: ++ * Set spanning tree group instance of the vlan to the specified device ++ * Input: ++ * vid - Specified VLAN ID. ++ * stg - spanning tree group instance. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_MSTI - Invalid msti parameter ++ * RT_ERR_INPUT - Invalid input parameter. ++ * RT_ERR_VLAN_VID - Invalid VID parameter. ++ * Note: ++ * The API can set spanning tree group instance of the vlan to the specified device. ++ */ ++extern rtk_api_ret_t rtk_vlan_stg_set(rtk_vlan_t vid, rtk_stp_msti_id_t stg); ++ ++/* Function Name: ++ * rtk_vlan_stg_get ++ * Description: ++ * Get spanning tree group instance of the vlan to the specified device ++ * Input: ++ * vid - Specified VLAN ID. ++ * Output: ++ * pStg - spanning tree group instance. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters. ++ * RT_ERR_VLAN_VID - Invalid VID parameter. ++ * Note: ++ * The API can get spanning tree group instance of the vlan to the specified device. ++ */ ++extern rtk_api_ret_t rtk_vlan_stg_get(rtk_vlan_t vid, rtk_stp_msti_id_t *pStg); ++ ++/* Function Name: ++ * rtk_vlan_protoAndPortBasedVlan_add ++ * Description: ++ * Add the protocol-and-port-based vlan to the specified port of device. ++ * Input: ++ * port - Port id. ++ * pInfo - Protocol and port based VLAN configuration information. ++ * 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_VLAN_VID - Invalid VID parameter. ++ * RT_ERR_VLAN_PRIORITY - Invalid priority. ++ * RT_ERR_TBL_FULL - Table is full. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * Note: ++ * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline ++ * The frame type is shown in the following: ++ * - FRAME_TYPE_ETHERNET ++ * - FRAME_TYPE_RFC1042 ++ * - FRAME_TYPE_LLCOTHER ++ */ ++extern rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_add(rtk_port_t port, rtk_vlan_protoAndPortInfo_t *pInfo); ++ ++/* Function Name: ++ * rtk_vlan_protoAndPortBasedVlan_get ++ * Description: ++ * Get the protocol-and-port-based vlan to the specified port of device. ++ * Input: ++ * port - Port id. ++ * proto_type - protocol-and-port-based vlan protocol type. ++ * frame_type - protocol-and-port-based vlan frame type. ++ * Output: ++ * pInfo - Protocol and port based VLAN configuration information. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_TBL_FULL - Table is full. ++ * Note: ++ * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline ++ * The frame type is shown in the following: ++ * - FRAME_TYPE_ETHERNET ++ * - FRAME_TYPE_RFC1042 ++ * - FRAME_TYPE_LLCOTHER ++ */ ++extern rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_get(rtk_port_t port, rtk_vlan_proto_type_t proto_type, rtk_vlan_protoVlan_frameType_t frame_type, rtk_vlan_protoAndPortInfo_t *pInfo); ++ ++/* Function Name: ++ * rtk_vlan_protoAndPortBasedVlan_del ++ * Description: ++ * Delete the protocol-and-port-based vlan from the specified port of device. ++ * Input: ++ * port - Port id. ++ * proto_type - protocol-and-port-based vlan protocol type. ++ * frame_type - protocol-and-port-based vlan frame type. ++ * 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_OUT_OF_RANGE - input out of range. ++ * RT_ERR_TBL_FULL - Table is full. ++ * Note: ++ * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline ++ * The frame type is shown in the following: ++ * - FRAME_TYPE_ETHERNET ++ * - FRAME_TYPE_RFC1042 ++ * - FRAME_TYPE_LLCOTHER ++ */ ++extern rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_del(rtk_port_t port, rtk_vlan_proto_type_t proto_type, rtk_vlan_protoVlan_frameType_t frame_type); ++ ++/* Function Name: ++ * rtk_vlan_protoAndPortBasedVlan_delAll ++ * Description: ++ * Delete all protocol-and-port-based vlans from the specified port of device. ++ * 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 number. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * Note: ++ * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline ++ * Delete all flow table protocol-and-port-based vlan entries. ++ */ ++extern rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_delAll(rtk_port_t port); ++ ++/* Function Name: ++ * rtk_vlan_portFid_set ++ * Description: ++ * Set port-based filtering database ++ * Input: ++ * port - Port id. ++ * enable - ebable port-based FID ++ * fid - Specified 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 filtering database. If the function is enabled, all input ++ * packets will be assigned to the port-based fid regardless vlan tag. ++ */ ++extern rtk_api_ret_t rtk_vlan_portFid_set(rtk_port_t port, rtk_enable_t enable, rtk_fid_t fid); ++ ++/* Function Name: ++ * rtk_vlan_portFid_get ++ * Description: ++ * Get port-based filtering database ++ * Input: ++ * port - Port id. ++ * Output: ++ * pEnable - ebable port-based FID ++ * pFid - Specified 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 filtering database status. If the function is enabled, all input ++ * packets will be assigned to the port-based fid regardless vlan tag. ++ */ ++extern rtk_api_ret_t rtk_vlan_portFid_get(rtk_port_t port, rtk_enable_t *pEnable, rtk_fid_t *pFid); ++ ++/* Function Name: ++ * rtk_vlan_UntagDscpPriorityEnable_set ++ * Description: ++ * Set Untag DSCP priority assign ++ * Input: ++ * enable - state of Untag DSCP priority assign ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_ENABLE - Invalid input parameters. ++ * Note: ++ * ++ */ ++extern rtk_api_ret_t rtk_vlan_UntagDscpPriorityEnable_set(rtk_enable_t enable); ++ ++/* Function Name: ++ * rtk_vlan_UntagDscpPriorityEnable_get ++ * Description: ++ * Get Untag DSCP priority assign ++ * Input: ++ * None ++ * Output: ++ * pEnable - state of Untag DSCP priority assign ++ * 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_vlan_UntagDscpPriorityEnable_get(rtk_enable_t *pEnable); ++ ++ ++/*Spanning Tree*/ ++/* Function Name: ++ * rtk_stp_mstpState_set ++ * Description: ++ * Configure spanning tree state per each port. ++ * Input: ++ * port - Port id ++ * msti - Multiple spanning tree instance. ++ * stp_state - Spanning tree state for msti ++ * 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_MSTI - Invalid msti parameter. ++ * RT_ERR_MSTP_STATE - Invalid STP state. ++ * Note: ++ * System supports per-port multiple spanning tree state for each msti. ++ * There are four states supported by ASIC. ++ * - STP_STATE_DISABLED ++ * - STP_STATE_BLOCKING ++ * - STP_STATE_LEARNING ++ * - STP_STATE_FORWARDING ++ */ ++extern rtk_api_ret_t rtk_stp_mstpState_set(rtk_stp_msti_id_t msti, rtk_port_t port, rtk_stp_state_t stp_state); ++ ++/* Function Name: ++ * rtk_stp_mstpState_get ++ * Description: ++ * Get spanning tree state per each port. ++ * Input: ++ * port - Port id. ++ * msti - Multiple spanning tree instance. ++ * Output: ++ * pStp_state - Spanning tree state for msti ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number. ++ * RT_ERR_MSTI - Invalid msti parameter. ++ * Note: ++ * System supports per-port multiple spanning tree state for each msti. ++ * There are four states supported by ASIC. ++ * - STP_STATE_DISABLED ++ * - STP_STATE_BLOCKING ++ * - STP_STATE_LEARNING ++ * - STP_STATE_FORWARDING ++ */ ++extern rtk_api_ret_t rtk_stp_mstpState_get(rtk_stp_msti_id_t msti, rtk_port_t port, rtk_stp_state_t *pStp_state); ++ ++/* Function Name: ++ * rtk_vlan_checkAndCreateMbr ++ * Description: ++ * Check and create Member configuration and return index ++ * Input: ++ * vid - VLAN id. ++ * Output: ++ * pIndex - Member configuration index ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_VLAN_VID - Invalid VLAN ID. ++ * RT_ERR_VLAN_ENTRY_NOT_FOUND - VLAN not found ++ * RT_ERR_TBL_FULL - Member Configuration table full ++ * Note: ++ * ++ */ ++extern rtk_api_ret_t rtk_vlan_checkAndCreateMbr(rtk_vlan_t vid, rtk_uint32 *pIndex); ++ ++/* Function Name: ++ * rtk_vlan_reservedVidAction_set ++ * Description: ++ * Set Action of VLAN ID = 0 & 4095 tagged packet ++ * Input: ++ * action_vid0 - Action for VID 0. ++ * action_vid4095 - Action for VID 4095. ++ * 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_vlan_reservedVidAction_set(rtk_vlan_resVidAction_t action_vid0, rtk_vlan_resVidAction_t action_vid4095); ++ ++/* Function Name: ++ * rtk_vlan_reservedVidAction_get ++ * Description: ++ * Get Action of VLAN ID = 0 & 4095 tagged packet ++ * Input: ++ * pAction_vid0 - Action for VID 0. ++ * pAction_vid4095 - Action for VID 4095. ++ * Output: ++ * None. ++ * 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_vlan_reservedVidAction_get(rtk_vlan_resVidAction_t *pAction_vid0, rtk_vlan_resVidAction_t *pAction_vid4095); ++ ++/* Function Name: ++ * rtk_vlan_realKeepRemarkEnable_set ++ * Description: ++ * Set Real keep 1p remarking feature ++ * Input: ++ * enabled - State of 1p remarking at real keep packet ++ * 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_vlan_realKeepRemarkEnable_set(rtk_enable_t enabled); ++ ++/* Function Name: ++ * rtk_vlan_realKeepRemarkEnable_get ++ * Description: ++ * Get Real keep 1p remarking feature ++ * Input: ++ * None. ++ * Output: ++ * pEnabled - State of 1p remarking at real keep packet ++ * 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_vlan_realKeepRemarkEnable_get(rtk_enable_t *pEnabled); ++ ++/* Function Name: ++ * rtk_vlan_reset ++ * Description: ++ * Reset VLAN ++ * Input: ++ * None. ++ * Output: ++ * pEnabled - State of 1p remarking at real keep packet ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Error Input ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_vlan_reset(void); ++ ++#endif /* __RTK_API_VLAN_H__ */ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/interrupt.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/interrupt.c +new file mode 100644 +index 0000000000..165ee41721 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/interrupt.c +@@ -0,0 +1,434 @@ ++/* ++ * 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 Interrupt module. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_int_polarity_set(rtk_int_polarity_t type) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(type >= INT_POLAR_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicInterruptPolarity(type)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_int_polarity_get(rtk_int_polarity_t *pType) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pType) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicInterruptPolarity(pType)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_int_control_set(rtk_int_type_t type, rtk_enable_t enable) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 mask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (type >= INT_TYPE_END) ++ return RT_ERR_INPUT; ++ ++ if (type == INT_TYPE_RESERVED) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_getAsicInterruptMask(&mask)) != RT_ERR_OK) ++ return retVal; ++ ++ if (ENABLED == enable) ++ mask = mask | (1<value[0] & (0x0001 << INT_TYPE_RESERVED)) ++ return RT_ERR_INPUT; ++ ++ if(pStatusMask->value[0] >= (0x0001 << INT_TYPE_END)) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicInterruptStatus((rtk_uint32)pStatusMask->value[0]))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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)) ++ * ++ */ ++rtk_api_ret_t rtk_int_status_get(rtk_int_status_t* pStatusMask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 ims_mask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pStatusMask) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicInterruptStatus(&ims_mask)) != RT_ERR_OK) ++ return retVal; ++ ++ pStatusMask->value[0] = (ims_mask & 0x00000FFF); ++ return RT_ERR_OK; ++} ++ ++#define ADV_NOT_SUPPORT (0xFFFF) ++static rtk_api_ret_t _rtk_int_Advidx_get(rtk_int_advType_t adv_type, rtk_uint32 *pAsic_idx) ++{ ++ rtk_uint32 asic_idx[ADV_END] = ++ { ++ INTRST_L2_LEARN, ++ INTRST_SPEED_CHANGE, ++ INTRST_SPECIAL_CONGESTION, ++ INTRST_PORT_LINKDOWN, ++ INTRST_PORT_LINKUP, ++ ADV_NOT_SUPPORT, ++ INTRST_RLDP_LOOPED, ++ INTRST_RLDP_RELEASED, ++ }; ++ ++ if(adv_type >= ADV_END) ++ return RT_ERR_INPUT; ++ ++ if(asic_idx[adv_type] == ADV_NOT_SUPPORT) ++ return RT_ERR_CHIP_NOT_SUPPORTED; ++ ++ *pAsic_idx = asic_idx[adv_type]; ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_int_advanceInfo_get(rtk_int_advType_t adv_type, rtk_int_info_t *pInfo) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 data; ++ rtk_uint32 intAdvType; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(adv_type >= ADV_END) ++ return RT_ERR_INPUT; ++ ++ if(NULL == pInfo) ++ return RT_ERR_NULL_POINTER; ++ ++ if(adv_type != ADV_METER_EXCEED_MASK) ++ { ++ if((retVal = _rtk_int_Advidx_get(adv_type, &intAdvType)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ switch(adv_type) ++ { ++ case ADV_L2_LEARN_PORT_MASK: ++ /* Get physical portmask */ ++ if((retVal = rtl8367c_getAsicInterruptRelatedStatus(intAdvType, &data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* Clear Advanced Info */ ++ if((retVal = rtl8367c_setAsicInterruptRelatedStatus(intAdvType, 0xFFFF)) != RT_ERR_OK) ++ return retVal; ++ ++ /* Translate to logical portmask */ ++ if((retVal = rtk_switch_portmask_P2L_get(data, &(pInfo->portMask))) != RT_ERR_OK) ++ return retVal; ++ ++ /* Get system learn */ ++ if((retVal = rtl8367c_getAsicInterruptRelatedStatus(INTRST_SYS_LEARN, &data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* Clear system learn */ ++ if((retVal = rtl8367c_setAsicInterruptRelatedStatus(INTRST_SYS_LEARN, 0x0001)) != RT_ERR_OK) ++ return retVal; ++ ++ pInfo->systemLearnOver = data; ++ break; ++ case ADV_SPEED_CHANGE_PORT_MASK: ++ case ADV_SPECIAL_CONGESTION_PORT_MASK: ++ case ADV_PORT_LINKDOWN_PORT_MASK: ++ case ADV_PORT_LINKUP_PORT_MASK: ++ case ADV_RLDP_LOOPED: ++ case ADV_RLDP_RELEASED: ++ /* Get physical portmask */ ++ if((retVal = rtl8367c_getAsicInterruptRelatedStatus(intAdvType, &data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* Clear Advanced Info */ ++ if((retVal = rtl8367c_setAsicInterruptRelatedStatus(intAdvType, 0xFFFF)) != RT_ERR_OK) ++ return retVal; ++ ++ /* Translate to logical portmask */ ++ if((retVal = rtk_switch_portmask_P2L_get(data, &(pInfo->portMask))) != RT_ERR_OK) ++ return retVal; ++ ++ break; ++ case ADV_METER_EXCEED_MASK: ++ /* Get Meter Mask */ ++ if((retVal = rtl8367c_getAsicInterruptRelatedStatus(INTRST_METER0_15, &data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* Clear Advanced Info */ ++ if((retVal = rtl8367c_setAsicInterruptRelatedStatus(INTRST_METER0_15, 0xFFFF)) != RT_ERR_OK) ++ return retVal; ++ ++ pInfo->meterMask = data & 0xFFFF; ++ ++ /* Get Meter Mask */ ++ if((retVal = rtl8367c_getAsicInterruptRelatedStatus(INTRST_METER16_31, &data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* Clear Advanced Info */ ++ if((retVal = rtl8367c_setAsicInterruptRelatedStatus(INTRST_METER16_31, 0xFFFF)) != RT_ERR_OK) ++ return retVal; ++ ++ pInfo->meterMask = pInfo->meterMask | ((data << 16) & 0xFFFF0000); ++ ++ break; ++ default: ++ return RT_ERR_INPUT; ++ } ++ ++ return RT_ERR_OK; ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/l2.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/l2.c +new file mode 100644 +index 0000000000..feff0b240b +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/l2.c +@@ -0,0 +1,2911 @@ ++/* ++ * 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 L2 module. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++/* Function Name: ++ * rtk_l2_init ++ * Description: ++ * Initialize l2 module of the specified device. ++ * Input: ++ * None ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * Initialize l2 module before calling any l2 APIs. ++ */ ++rtk_api_ret_t rtk_l2_init(void) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 port; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ((retVal = rtl8367c_setAsicLutIpMulticastLookup(DISABLED)) != RT_ERR_OK) ++ return retVal; ++ ++ /*Enable CAM Usage*/ ++ if ((retVal = rtl8367c_setAsicLutCamTbUsage(ENABLED)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicLutAgeTimerSpeed(6,2)) != RT_ERR_OK) ++ return retVal; ++ ++ RTK_SCAN_ALL_LOG_PORT(port) ++ { ++ if ((retVal = rtl8367c_setAsicLutLearnLimitNo(rtk_switch_port_L2P_get(port), rtk_switch_maxLutAddrNumber_get())) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++ ++/* Function Name: ++ * rtk_l2_addr_add ++ * Description: ++ * Add LUT unicast entry. ++ * Input: ++ * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. ++ * pL2_data - Unicast entry parameter ++ * 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_MAC - Invalid MAC address. ++ * RT_ERR_L2_FID - Invalid FID . ++ * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * If the unicast mac address already existed in LUT, it will udpate the status of the entry. ++ * Otherwise, it will find an empty or asic auto learned entry to write. If all the entries ++ * with the same hash value can't be replaced, ASIC will return a RT_ERR_L2_INDEXTBL_FULL error. ++ */ ++rtk_api_ret_t rtk_l2_addr_add(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 method; ++ rtl8367c_luttb l2Table; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* must be unicast address */ ++ if ((pMac == NULL) || (pMac->octet[0] & 0x1)) ++ return RT_ERR_MAC; ++ ++ if(pL2_data == NULL) ++ return RT_ERR_MAC; ++ ++ RTK_CHK_PORT_VALID(pL2_data->port); ++ ++ if (pL2_data->ivl >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if (pL2_data->cvid > RTL8367C_VIDMAX) ++ return RT_ERR_L2_VID; ++ ++ if (pL2_data->fid > RTL8367C_FIDMAX) ++ return RT_ERR_L2_FID; ++ ++ if (pL2_data->is_static>= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if (pL2_data->sa_block>= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if (pL2_data->da_block>= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if (pL2_data->auth>= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if (pL2_data->efid> RTL8367C_EFIDMAX) ++ return RT_ERR_INPUT; ++ ++ if (pL2_data->priority > RTL8367C_PRIMAX) ++ return RT_ERR_INPUT; ++ ++ if (pL2_data->sa_pri_en >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if (pL2_data->fwd_pri_en >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); ++ ++ /* fill key (MAC,FID) to get L2 entry */ ++ memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); ++ l2Table.ivl_svl = pL2_data->ivl; ++ l2Table.fid = pL2_data->fid; ++ l2Table.cvid_fid = pL2_data->cvid; ++ l2Table.efid = pL2_data->efid; ++ method = LUTREADMETHOD_MAC; ++ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); ++ if (RT_ERR_OK == retVal ) ++ { ++ memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); ++ l2Table.ivl_svl = pL2_data->ivl; ++ l2Table.cvid_fid = pL2_data->cvid; ++ l2Table.fid = pL2_data->fid; ++ l2Table.efid = pL2_data->efid; ++ l2Table.spa = rtk_switch_port_L2P_get(pL2_data->port); ++ l2Table.nosalearn = pL2_data->is_static; ++ l2Table.sa_block = pL2_data->sa_block; ++ l2Table.da_block = pL2_data->da_block; ++ l2Table.l3lookup = 0; ++ l2Table.auth = pL2_data->auth; ++ l2Table.age = 6; ++ l2Table.lut_pri = pL2_data->priority; ++ l2Table.sa_en = pL2_data->sa_pri_en; ++ l2Table.fwd_en = pL2_data->fwd_pri_en; ++ if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) ++ return retVal; ++ ++ pL2_data->address = l2Table.address; ++ return RT_ERR_OK; ++ } ++ else if (RT_ERR_L2_ENTRY_NOTFOUND == retVal ) ++ { ++ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); ++ memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); ++ l2Table.ivl_svl = pL2_data->ivl; ++ l2Table.cvid_fid = pL2_data->cvid; ++ l2Table.fid = pL2_data->fid; ++ l2Table.efid = pL2_data->efid; ++ l2Table.spa = rtk_switch_port_L2P_get(pL2_data->port); ++ l2Table.nosalearn = pL2_data->is_static; ++ l2Table.sa_block = pL2_data->sa_block; ++ l2Table.da_block = pL2_data->da_block; ++ l2Table.l3lookup = 0; ++ l2Table.auth = pL2_data->auth; ++ l2Table.age = 6; ++ l2Table.lut_pri = pL2_data->priority; ++ l2Table.sa_en = pL2_data->sa_pri_en; ++ l2Table.fwd_en = pL2_data->fwd_pri_en; ++ ++ if ((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) ++ return retVal; ++ ++ pL2_data->address = l2Table.address; ++ ++ method = LUTREADMETHOD_MAC; ++ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); ++ if (RT_ERR_L2_ENTRY_NOTFOUND == retVal ) ++ return RT_ERR_L2_INDEXTBL_FULL; ++ else ++ return retVal; ++ } ++ else ++ return retVal; ++ ++} ++ ++/* Function Name: ++ * rtk_l2_addr_get ++ * Description: ++ * Get LUT unicast entry. ++ * Input: ++ * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. ++ * Output: ++ * pL2_data - Unicast entry parameter ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number. ++ * RT_ERR_MAC - Invalid MAC address. ++ * RT_ERR_L2_FID - Invalid FID . ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * If the unicast mac address existed in LUT, it will return the port and fid where ++ * the mac is learned. Otherwise, it will return a RT_ERR_L2_ENTRY_NOTFOUND error. ++ */ ++rtk_api_ret_t rtk_l2_addr_get(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 method; ++ rtl8367c_luttb l2Table; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* must be unicast address */ ++ if ((pMac == NULL) || (pMac->octet[0] & 0x1)) ++ return RT_ERR_MAC; ++ ++ if (pL2_data->fid > RTL8367C_FIDMAX || pL2_data->efid > RTL8367C_EFIDMAX) ++ return RT_ERR_L2_FID; ++ ++ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); ++ ++ memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); ++ l2Table.ivl_svl = pL2_data->ivl; ++ l2Table.cvid_fid = pL2_data->cvid; ++ l2Table.fid = pL2_data->fid; ++ l2Table.efid = pL2_data->efid; ++ method = LUTREADMETHOD_MAC; ++ ++ if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) ++ return retVal; ++ ++ memcpy(pL2_data->mac.octet, pMac->octet,ETHER_ADDR_LEN); ++ pL2_data->port = rtk_switch_port_P2L_get(l2Table.spa); ++ pL2_data->fid = l2Table.fid; ++ pL2_data->efid = l2Table.efid; ++ pL2_data->ivl = l2Table.ivl_svl; ++ pL2_data->cvid = l2Table.cvid_fid; ++ pL2_data->is_static = l2Table.nosalearn; ++ pL2_data->auth = l2Table.auth; ++ pL2_data->sa_block = l2Table.sa_block; ++ pL2_data->da_block = l2Table.da_block; ++ pL2_data->priority = l2Table.lut_pri; ++ pL2_data->sa_pri_en = l2Table.sa_en; ++ pL2_data->fwd_pri_en= l2Table.fwd_en; ++ pL2_data->address = l2Table.address; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_addr_next_get ++ * Description: ++ * Get Next LUT unicast entry. ++ * Input: ++ * read_method - The reading method. ++ * port - The port number if the read_metohd is READMETHOD_NEXT_L2UCSPA ++ * pAddress - The Address ID ++ * Output: ++ * pL2_data - Unicast entry parameter ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number. ++ * RT_ERR_MAC - Invalid MAC address. ++ * RT_ERR_L2_FID - Invalid FID . ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * Get the next unicast entry after the current entry pointed by pAddress. ++ * The address of next entry is returned by pAddress. User can use (address + 1) ++ * as pAddress to call this API again for dumping all entries is LUT. ++ */ ++rtk_api_ret_t rtk_l2_addr_next_get(rtk_l2_read_method_t read_method, rtk_port_t port, rtk_uint32 *pAddress, rtk_l2_ucastAddr_t *pL2_data) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 method; ++ rtl8367c_luttb l2Table; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Error Checking */ ++ if ((pL2_data == NULL) || (pAddress == NULL)) ++ return RT_ERR_MAC; ++ ++ if(read_method == READMETHOD_NEXT_L2UC) ++ method = LUTREADMETHOD_NEXT_L2UC; ++ else if(read_method == READMETHOD_NEXT_L2UCSPA) ++ method = LUTREADMETHOD_NEXT_L2UCSPA; ++ else ++ return RT_ERR_INPUT; ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(*pAddress > RTK_MAX_LUT_ADDR_ID ) ++ return RT_ERR_L2_L2UNI_PARAM; ++ ++ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); ++ l2Table.address = *pAddress; ++ ++ if(read_method == READMETHOD_NEXT_L2UCSPA) ++ l2Table.spa = rtk_switch_port_L2P_get(port); ++ ++ if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) ++ return retVal; ++ ++ if(l2Table.address < *pAddress) ++ return RT_ERR_L2_ENTRY_NOTFOUND; ++ ++ memcpy(pL2_data->mac.octet, l2Table.mac.octet, ETHER_ADDR_LEN); ++ pL2_data->port = rtk_switch_port_P2L_get(l2Table.spa); ++ pL2_data->fid = l2Table.fid; ++ pL2_data->efid = l2Table.efid; ++ pL2_data->ivl = l2Table.ivl_svl; ++ pL2_data->cvid = l2Table.cvid_fid; ++ pL2_data->is_static = l2Table.nosalearn; ++ pL2_data->auth = l2Table.auth; ++ pL2_data->sa_block = l2Table.sa_block; ++ pL2_data->da_block = l2Table.da_block; ++ pL2_data->priority = l2Table.lut_pri; ++ pL2_data->sa_pri_en = l2Table.sa_en; ++ pL2_data->fwd_pri_en= l2Table.fwd_en; ++ pL2_data->address = l2Table.address; ++ ++ *pAddress = l2Table.address; ++ ++ return RT_ERR_OK; ++ ++} ++ ++/* Function Name: ++ * rtk_l2_addr_del ++ * Description: ++ * Delete LUT unicast entry. ++ * Input: ++ * pMac - 6 bytes unicast(I/G bit is 0) mac address to be written into LUT. ++ * 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_MAC - Invalid MAC address. ++ * RT_ERR_L2_FID - Invalid FID . ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * If the mac has existed in the LUT, it will be deleted. Otherwise, it will return RT_ERR_L2_ENTRY_NOTFOUND. ++ */ ++rtk_api_ret_t rtk_l2_addr_del(rtk_mac_t *pMac, rtk_l2_ucastAddr_t *pL2_data) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 method; ++ rtl8367c_luttb l2Table; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* must be unicast address */ ++ if ((pMac == NULL) || (pMac->octet[0] & 0x1)) ++ return RT_ERR_MAC; ++ ++ if (pL2_data->fid > RTL8367C_FIDMAX || pL2_data->efid > RTL8367C_EFIDMAX) ++ return RT_ERR_L2_FID; ++ ++ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); ++ ++ /* fill key (MAC,FID) to get L2 entry */ ++ memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); ++ l2Table.ivl_svl = pL2_data->ivl; ++ l2Table.cvid_fid = pL2_data->cvid; ++ l2Table.fid = pL2_data->fid; ++ l2Table.efid = pL2_data->efid; ++ method = LUTREADMETHOD_MAC; ++ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); ++ if (RT_ERR_OK == retVal) ++ { ++ memcpy(l2Table.mac.octet, pMac->octet, ETHER_ADDR_LEN); ++ l2Table.ivl_svl = pL2_data->ivl; ++ l2Table.cvid_fid = pL2_data->cvid; ++ l2Table.fid = pL2_data->fid; ++ l2Table.efid = pL2_data->efid; ++ l2Table.spa = 0; ++ l2Table.nosalearn = 0; ++ l2Table.sa_block = 0; ++ l2Table.da_block = 0; ++ l2Table.auth = 0; ++ l2Table.age = 0; ++ l2Table.lut_pri = 0; ++ l2Table.sa_en = 0; ++ l2Table.fwd_en = 0; ++ if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) ++ return retVal; ++ ++ pL2_data->address = l2Table.address; ++ return RT_ERR_OK; ++ } ++ else ++ return retVal; ++} ++ ++/* Function Name: ++ * rtk_l2_mcastAddr_add ++ * Description: ++ * Add LUT multicast entry. ++ * Input: ++ * pMcastAddr - L2 multicast entry 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_MAC - Invalid MAC address. ++ * RT_ERR_L2_FID - Invalid FID . ++ * RT_ERR_L2_VID - Invalid VID . ++ * RT_ERR_L2_INDEXTBL_FULL - hashed index is full of entries. ++ * RT_ERR_PORT_MASK - Invalid portmask. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * If the multicast mac address already existed in the LUT, it will udpate the ++ * port mask of the entry. Otherwise, it will find an empty or asic auto learned ++ * entry to write. If all the entries with the same hash value can't be replaced, ++ * ASIC will return a RT_ERR_L2_INDEXTBL_FULL error. ++ */ ++rtk_api_ret_t rtk_l2_mcastAddr_add(rtk_l2_mcastAddr_t *pMcastAddr) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 method; ++ rtl8367c_luttb l2Table; ++ rtk_uint32 pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pMcastAddr) ++ return RT_ERR_NULL_POINTER; ++ ++ /* must be L2 multicast address */ ++ if( (pMcastAddr->mac.octet[0] & 0x01) != 0x01) ++ return RT_ERR_MAC; ++ ++ RTK_CHK_PORTMASK_VALID(&pMcastAddr->portmask); ++ ++ if(pMcastAddr->ivl == 1) ++ { ++ if (pMcastAddr->vid > RTL8367C_VIDMAX) ++ return RT_ERR_L2_VID; ++ } ++ else if(pMcastAddr->ivl == 0) ++ { ++ if (pMcastAddr->fid > RTL8367C_FIDMAX) ++ return RT_ERR_L2_FID; ++ } ++ else ++ return RT_ERR_INPUT; ++ ++ if(pMcastAddr->fwd_pri_en >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if(pMcastAddr->priority > RTL8367C_PRIMAX) ++ return RT_ERR_INPUT; ++ ++ /* Get physical port mask */ ++ if ((retVal = rtk_switch_portmask_L2P_get(&pMcastAddr->portmask, &pmask)) != RT_ERR_OK) ++ return retVal; ++ ++ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); ++ ++ /* fill key (MAC,FID) to get L2 entry */ ++ memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); ++ l2Table.ivl_svl = pMcastAddr->ivl; ++ ++ if(pMcastAddr->ivl) ++ l2Table.cvid_fid = pMcastAddr->vid; ++ else ++ l2Table.cvid_fid = pMcastAddr->fid; ++ ++ method = LUTREADMETHOD_MAC; ++ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); ++ if (RT_ERR_OK == retVal) ++ { ++ memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); ++ l2Table.ivl_svl = pMcastAddr->ivl; ++ ++ if(pMcastAddr->ivl) ++ l2Table.cvid_fid = pMcastAddr->vid; ++ else ++ l2Table.cvid_fid = pMcastAddr->fid; ++ ++ l2Table.mbr = pmask; ++ l2Table.nosalearn = 1; ++ l2Table.l3lookup = 0; ++ l2Table.lut_pri = pMcastAddr->priority; ++ l2Table.fwd_en = pMcastAddr->fwd_pri_en; ++ if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) ++ return retVal; ++ ++ pMcastAddr->address = l2Table.address; ++ return RT_ERR_OK; ++ } ++ else if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) ++ { ++ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); ++ memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); ++ l2Table.ivl_svl = pMcastAddr->ivl; ++ if(pMcastAddr->ivl) ++ l2Table.cvid_fid = pMcastAddr->vid; ++ else ++ l2Table.cvid_fid = pMcastAddr->fid; ++ ++ l2Table.mbr = pmask; ++ l2Table.nosalearn = 1; ++ l2Table.l3lookup = 0; ++ l2Table.lut_pri = pMcastAddr->priority; ++ l2Table.fwd_en = pMcastAddr->fwd_pri_en; ++ if ((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) ++ return retVal; ++ ++ pMcastAddr->address = l2Table.address; ++ ++ method = LUTREADMETHOD_MAC; ++ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); ++ if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) ++ return RT_ERR_L2_INDEXTBL_FULL; ++ else ++ return retVal; ++ } ++ else ++ return retVal; ++ ++} ++ ++/* Function Name: ++ * rtk_l2_mcastAddr_get ++ * Description: ++ * Get LUT multicast entry. ++ * Input: ++ * pMcastAddr - L2 multicast entry structure ++ * Output: ++ * pMcastAddr - L2 multicast entry structure ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_MAC - Invalid MAC address. ++ * RT_ERR_L2_FID - Invalid FID . ++ * RT_ERR_L2_VID - Invalid VID . ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * If the multicast mac address existed in the LUT, it will return the port where ++ * the mac is learned. Otherwise, it will return a RT_ERR_L2_ENTRY_NOTFOUND error. ++ */ ++rtk_api_ret_t rtk_l2_mcastAddr_get(rtk_l2_mcastAddr_t *pMcastAddr) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 method; ++ rtl8367c_luttb l2Table; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pMcastAddr) ++ return RT_ERR_NULL_POINTER; ++ ++ /* must be L2 multicast address */ ++ if( (pMcastAddr->mac.octet[0] & 0x01) != 0x01) ++ return RT_ERR_MAC; ++ ++ if(pMcastAddr->ivl == 1) ++ { ++ if (pMcastAddr->vid > RTL8367C_VIDMAX) ++ return RT_ERR_L2_VID; ++ } ++ else if(pMcastAddr->ivl == 0) ++ { ++ if (pMcastAddr->fid > RTL8367C_FIDMAX) ++ return RT_ERR_L2_FID; ++ } ++ else ++ return RT_ERR_INPUT; ++ ++ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); ++ memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); ++ l2Table.ivl_svl = pMcastAddr->ivl; ++ ++ if(pMcastAddr->ivl) ++ l2Table.cvid_fid = pMcastAddr->vid; ++ else ++ l2Table.cvid_fid = pMcastAddr->fid; ++ ++ method = LUTREADMETHOD_MAC; ++ ++ if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) ++ return retVal; ++ ++ pMcastAddr->priority = l2Table.lut_pri; ++ pMcastAddr->fwd_pri_en = l2Table.fwd_en; ++ pMcastAddr->igmp_asic = l2Table.igmp_asic; ++ pMcastAddr->igmp_index = l2Table.igmpidx; ++ pMcastAddr->address = l2Table.address; ++ ++ /* Get Logical port mask */ ++ if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pMcastAddr->portmask)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_mcastAddr_next_get ++ * Description: ++ * Get Next L2 Multicast entry. ++ * Input: ++ * pAddress - The Address ID ++ * Output: ++ * pMcastAddr - L2 multicast entry structure ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * Get the next L2 multicast entry after the current entry pointed by pAddress. ++ * The address of next entry is returned by pAddress. User can use (address + 1) ++ * as pAddress to call this API again for dumping all multicast entries is LUT. ++ */ ++rtk_api_ret_t rtk_l2_mcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_mcastAddr_t *pMcastAddr) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_luttb l2Table; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Error Checking */ ++ if ((pAddress == NULL) || (pMcastAddr == NULL)) ++ return RT_ERR_INPUT; ++ ++ if(*pAddress > RTK_MAX_LUT_ADDR_ID ) ++ return RT_ERR_L2_L2UNI_PARAM; ++ ++ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); ++ l2Table.address = *pAddress; ++ ++ if ((retVal = rtl8367c_getAsicL2LookupTb(LUTREADMETHOD_NEXT_L2MC, &l2Table)) != RT_ERR_OK) ++ return retVal; ++ ++ if(l2Table.address < *pAddress) ++ return RT_ERR_L2_ENTRY_NOTFOUND; ++ ++ memcpy(pMcastAddr->mac.octet, l2Table.mac.octet, ETHER_ADDR_LEN); ++ pMcastAddr->ivl = l2Table.ivl_svl; ++ ++ if(pMcastAddr->ivl) ++ pMcastAddr->vid = l2Table.cvid_fid; ++ else ++ pMcastAddr->fid = l2Table.cvid_fid; ++ ++ pMcastAddr->priority = l2Table.lut_pri; ++ pMcastAddr->fwd_pri_en = l2Table.fwd_en; ++ pMcastAddr->igmp_asic = l2Table.igmp_asic; ++ pMcastAddr->igmp_index = l2Table.igmpidx; ++ pMcastAddr->address = l2Table.address; ++ ++ /* Get Logical port mask */ ++ if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pMcastAddr->portmask)) != RT_ERR_OK) ++ return retVal; ++ ++ *pAddress = l2Table.address; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_mcastAddr_del ++ * Description: ++ * Delete LUT multicast entry. ++ * Input: ++ * pMcastAddr - L2 multicast entry structure ++ * 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_L2_FID - Invalid FID . ++ * RT_ERR_L2_VID - Invalid VID . ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * If the mac has existed in the LUT, it will be deleted. Otherwise, it will return RT_ERR_L2_ENTRY_NOTFOUND. ++ */ ++rtk_api_ret_t rtk_l2_mcastAddr_del(rtk_l2_mcastAddr_t *pMcastAddr) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 method; ++ rtl8367c_luttb l2Table; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pMcastAddr) ++ return RT_ERR_NULL_POINTER; ++ ++ /* must be L2 multicast address */ ++ if( (pMcastAddr->mac.octet[0] & 0x01) != 0x01) ++ return RT_ERR_MAC; ++ ++ if(pMcastAddr->ivl == 1) ++ { ++ if (pMcastAddr->vid > RTL8367C_VIDMAX) ++ return RT_ERR_L2_VID; ++ } ++ else if(pMcastAddr->ivl == 0) ++ { ++ if (pMcastAddr->fid > RTL8367C_FIDMAX) ++ return RT_ERR_L2_FID; ++ } ++ else ++ return RT_ERR_INPUT; ++ ++ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); ++ ++ /* fill key (MAC,FID) to get L2 entry */ ++ memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); ++ l2Table.ivl_svl = pMcastAddr->ivl; ++ ++ if(pMcastAddr->ivl) ++ l2Table.cvid_fid = pMcastAddr->vid; ++ else ++ l2Table.cvid_fid = pMcastAddr->fid; ++ ++ method = LUTREADMETHOD_MAC; ++ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); ++ if (RT_ERR_OK == retVal) ++ { ++ memcpy(l2Table.mac.octet, pMcastAddr->mac.octet, ETHER_ADDR_LEN); ++ l2Table.ivl_svl = pMcastAddr->ivl; ++ ++ if(pMcastAddr->ivl) ++ l2Table.cvid_fid = pMcastAddr->vid; ++ else ++ l2Table.cvid_fid = pMcastAddr->fid; ++ ++ l2Table.mbr = 0; ++ l2Table.nosalearn = 0; ++ l2Table.sa_block = 0; ++ l2Table.l3lookup = 0; ++ l2Table.lut_pri = 0; ++ l2Table.fwd_en = 0; ++ if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) ++ return retVal; ++ ++ pMcastAddr->address = l2Table.address; ++ return RT_ERR_OK; ++ } ++ else ++ return retVal; ++} ++ ++/* Function Name: ++ * rtk_l2_ipMcastAddr_add ++ * Description: ++ * Add Lut IP multicast entry ++ * Input: ++ * pIpMcastAddr - IP Multicast entry ++ * 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_L2_INDEXTBL_FULL - hashed index is full of entries. ++ * RT_ERR_PORT_MASK - Invalid portmask. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * System supports L2 entry with IP multicast DIP/SIP to forward IP multicasting frame as user ++ * desired. If this function is enabled, then system will be looked up L2 IP multicast entry to ++ * forward IP multicast frame directly without flooding. ++ */ ++rtk_api_ret_t rtk_l2_ipMcastAddr_add(rtk_l2_ipMcastAddr_t *pIpMcastAddr) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 method; ++ rtl8367c_luttb l2Table; ++ rtk_uint32 pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pIpMcastAddr) ++ return RT_ERR_NULL_POINTER; ++ ++ /* check port mask */ ++ RTK_CHK_PORTMASK_VALID(&pIpMcastAddr->portmask); ++ ++ if( (pIpMcastAddr->dip & 0xF0000000) != 0xE0000000) ++ return RT_ERR_INPUT; ++ ++ if(pIpMcastAddr->fwd_pri_en >= RTK_ENABLE_END) ++ return RT_ERR_ENABLE; ++ ++ if(pIpMcastAddr->priority > RTL8367C_PRIMAX) ++ return RT_ERR_INPUT; ++ ++ /* Get Physical port mask */ ++ if ((retVal = rtk_switch_portmask_L2P_get(&pIpMcastAddr->portmask, &pmask)) != RT_ERR_OK) ++ return retVal; ++ ++ memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); ++ l2Table.sip = pIpMcastAddr->sip; ++ l2Table.dip = pIpMcastAddr->dip; ++ l2Table.l3lookup = 1; ++ l2Table.l3vidlookup = 0; ++ method = LUTREADMETHOD_MAC; ++ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); ++ if (RT_ERR_OK == retVal) ++ { ++ l2Table.sip = pIpMcastAddr->sip; ++ l2Table.dip = pIpMcastAddr->dip; ++ l2Table.mbr = pmask; ++ l2Table.nosalearn = 1; ++ l2Table.l3lookup = 1; ++ l2Table.l3vidlookup = 0; ++ l2Table.lut_pri = pIpMcastAddr->priority; ++ l2Table.fwd_en = pIpMcastAddr->fwd_pri_en; ++ if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) ++ return retVal; ++ ++ pIpMcastAddr->address = l2Table.address; ++ return RT_ERR_OK; ++ } ++ else if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) ++ { ++ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); ++ l2Table.sip = pIpMcastAddr->sip; ++ l2Table.dip = pIpMcastAddr->dip; ++ l2Table.mbr = pmask; ++ l2Table.nosalearn = 1; ++ l2Table.l3lookup = 1; ++ l2Table.l3vidlookup = 0; ++ l2Table.lut_pri = pIpMcastAddr->priority; ++ l2Table.fwd_en = pIpMcastAddr->fwd_pri_en; ++ if ((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) ++ return retVal; ++ ++ pIpMcastAddr->address = l2Table.address; ++ ++ method = LUTREADMETHOD_MAC; ++ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); ++ if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) ++ return RT_ERR_L2_INDEXTBL_FULL; ++ else ++ return retVal; ++ ++ } ++ else ++ return retVal; ++ ++} ++ ++/* Function Name: ++ * rtk_l2_ipMcastAddr_get ++ * Description: ++ * Get LUT IP multicast entry. ++ * Input: ++ * pIpMcastAddr - IP Multicast entry ++ * Output: ++ * pIpMcastAddr - IP Multicast entry ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can get Lut table of IP multicast entry. ++ */ ++rtk_api_ret_t rtk_l2_ipMcastAddr_get(rtk_l2_ipMcastAddr_t *pIpMcastAddr) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 method; ++ rtl8367c_luttb l2Table; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pIpMcastAddr) ++ return RT_ERR_NULL_POINTER; ++ ++ if( (pIpMcastAddr->dip & 0xF0000000) != 0xE0000000) ++ return RT_ERR_INPUT; ++ ++ memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); ++ l2Table.sip = pIpMcastAddr->sip; ++ l2Table.dip = pIpMcastAddr->dip; ++ l2Table.l3lookup = 1; ++ l2Table.l3vidlookup = 0; ++ method = LUTREADMETHOD_MAC; ++ if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) ++ return retVal; ++ ++ /* Get Logical port mask */ ++ if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pIpMcastAddr->portmask)) != RT_ERR_OK) ++ return retVal; ++ ++ pIpMcastAddr->priority = l2Table.lut_pri; ++ pIpMcastAddr->fwd_pri_en = l2Table.fwd_en; ++ pIpMcastAddr->igmp_asic = l2Table.igmp_asic; ++ pIpMcastAddr->igmp_index = l2Table.igmpidx; ++ pIpMcastAddr->address = l2Table.address; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_ipMcastAddr_next_get ++ * Description: ++ * Get Next IP Multicast entry. ++ * Input: ++ * pAddress - The Address ID ++ * Output: ++ * pIpMcastAddr - IP Multicast entry ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * Get the next IP multicast entry after the current entry pointed by pAddress. ++ * The address of next entry is returned by pAddress. User can use (address + 1) ++ * as pAddress to call this API again for dumping all IP multicast entries is LUT. ++ */ ++rtk_api_ret_t rtk_l2_ipMcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_ipMcastAddr_t *pIpMcastAddr) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_luttb l2Table; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Error Checking */ ++ if ((pAddress == NULL) || (pIpMcastAddr == NULL) ) ++ return RT_ERR_INPUT; ++ ++ if(*pAddress > RTK_MAX_LUT_ADDR_ID ) ++ return RT_ERR_L2_L2UNI_PARAM; ++ ++ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); ++ l2Table.address = *pAddress; ++ ++ do ++ { ++ if ((retVal = rtl8367c_getAsicL2LookupTb(LUTREADMETHOD_NEXT_L3MC, &l2Table)) != RT_ERR_OK) ++ return retVal; ++ ++ if(l2Table.address < *pAddress) ++ return RT_ERR_L2_ENTRY_NOTFOUND; ++ ++ }while(l2Table.l3vidlookup == 1); ++ ++ pIpMcastAddr->sip = l2Table.sip; ++ pIpMcastAddr->dip = l2Table.dip; ++ ++ /* Get Logical port mask */ ++ if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pIpMcastAddr->portmask)) != RT_ERR_OK) ++ return retVal; ++ ++ pIpMcastAddr->priority = l2Table.lut_pri; ++ pIpMcastAddr->fwd_pri_en = l2Table.fwd_en; ++ pIpMcastAddr->igmp_asic = l2Table.igmp_asic; ++ pIpMcastAddr->igmp_index = l2Table.igmpidx; ++ pIpMcastAddr->address = l2Table.address; ++ *pAddress = l2Table.address; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_ipMcastAddr_del ++ * Description: ++ * Delete a ip multicast address entry from the specified device. ++ * Input: ++ * pIpMcastAddr - IP Multicast entry ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can delete a IP multicast address entry from the specified device. ++ */ ++rtk_api_ret_t rtk_l2_ipMcastAddr_del(rtk_l2_ipMcastAddr_t *pIpMcastAddr) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 method; ++ rtl8367c_luttb l2Table; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Error Checking */ ++ if (pIpMcastAddr == NULL) ++ return RT_ERR_INPUT; ++ ++ if( (pIpMcastAddr->dip & 0xF0000000) != 0xE0000000) ++ return RT_ERR_INPUT; ++ ++ memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); ++ l2Table.sip = pIpMcastAddr->sip; ++ l2Table.dip = pIpMcastAddr->dip; ++ l2Table.l3lookup = 1; ++ l2Table.l3vidlookup = 0; ++ method = LUTREADMETHOD_MAC; ++ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); ++ if (RT_ERR_OK == retVal) ++ { ++ l2Table.sip = pIpMcastAddr->sip; ++ l2Table.dip = pIpMcastAddr->dip; ++ l2Table.mbr = 0; ++ l2Table.nosalearn = 0; ++ l2Table.l3lookup = 1; ++ l2Table.l3vidlookup = 0; ++ l2Table.lut_pri = 0; ++ l2Table.fwd_en = 0; ++ if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) ++ return retVal; ++ ++ pIpMcastAddr->address = l2Table.address; ++ return RT_ERR_OK; ++ } ++ else ++ return retVal; ++} ++ ++/* Function Name: ++ * rtk_l2_ipVidMcastAddr_add ++ * Description: ++ * Add Lut IP multicast+VID entry ++ * Input: ++ * pIpVidMcastAddr - IP & VID multicast Entry ++ * 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_L2_INDEXTBL_FULL - hashed index is full of entries. ++ * RT_ERR_PORT_MASK - Invalid portmask. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_l2_ipVidMcastAddr_add(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 method; ++ rtl8367c_luttb l2Table; ++ rtk_uint32 pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pIpVidMcastAddr) ++ return RT_ERR_NULL_POINTER; ++ ++ /* check port mask */ ++ RTK_CHK_PORTMASK_VALID(&pIpVidMcastAddr->portmask); ++ ++ if (pIpVidMcastAddr->vid > RTL8367C_VIDMAX) ++ return RT_ERR_L2_VID; ++ ++ if( (pIpVidMcastAddr->dip & 0xF0000000) != 0xE0000000) ++ return RT_ERR_INPUT; ++ ++ /* Get Physical port mask */ ++ if ((retVal = rtk_switch_portmask_L2P_get(&pIpVidMcastAddr->portmask, &pmask)) != RT_ERR_OK) ++ return retVal; ++ ++ memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); ++ l2Table.sip = pIpVidMcastAddr->sip; ++ l2Table.dip = pIpVidMcastAddr->dip; ++ l2Table.l3lookup = 1; ++ l2Table.l3vidlookup = 1; ++ l2Table.l3_vid = pIpVidMcastAddr->vid; ++ method = LUTREADMETHOD_MAC; ++ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); ++ if (RT_ERR_OK == retVal) ++ { ++ l2Table.sip = pIpVidMcastAddr->sip; ++ l2Table.dip = pIpVidMcastAddr->dip; ++ l2Table.mbr = pmask; ++ l2Table.nosalearn = 1; ++ l2Table.l3lookup = 1; ++ l2Table.l3vidlookup = 1; ++ l2Table.l3_vid = pIpVidMcastAddr->vid; ++ if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) ++ return retVal; ++ ++ pIpVidMcastAddr->address = l2Table.address; ++ return RT_ERR_OK; ++ } ++ else if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) ++ { ++ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); ++ l2Table.sip = pIpVidMcastAddr->sip; ++ l2Table.dip = pIpVidMcastAddr->dip; ++ l2Table.mbr = pmask; ++ l2Table.nosalearn = 1; ++ l2Table.l3lookup = 1; ++ l2Table.l3vidlookup = 1; ++ l2Table.l3_vid = pIpVidMcastAddr->vid; ++ if ((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) ++ return retVal; ++ ++ pIpVidMcastAddr->address = l2Table.address; ++ ++ method = LUTREADMETHOD_MAC; ++ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); ++ if (RT_ERR_L2_ENTRY_NOTFOUND == retVal) ++ return RT_ERR_L2_INDEXTBL_FULL; ++ else ++ return retVal; ++ ++ } ++ else ++ return retVal; ++} ++ ++/* Function Name: ++ * rtk_l2_ipVidMcastAddr_get ++ * Description: ++ * Get LUT IP multicast+VID entry. ++ * Input: ++ * pIpVidMcastAddr - IP & VID multicast Entry ++ * Output: ++ * pIpVidMcastAddr - IP & VID multicast Entry ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_l2_ipVidMcastAddr_get(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 method; ++ rtl8367c_luttb l2Table; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pIpVidMcastAddr) ++ return RT_ERR_NULL_POINTER; ++ ++ if (pIpVidMcastAddr->vid > RTL8367C_VIDMAX) ++ return RT_ERR_L2_VID; ++ ++ if( (pIpVidMcastAddr->dip & 0xF0000000) != 0xE0000000) ++ return RT_ERR_INPUT; ++ ++ memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); ++ l2Table.sip = pIpVidMcastAddr->sip; ++ l2Table.dip = pIpVidMcastAddr->dip; ++ l2Table.l3lookup = 1; ++ l2Table.l3vidlookup = 1; ++ l2Table.l3_vid = pIpVidMcastAddr->vid; ++ method = LUTREADMETHOD_MAC; ++ if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) ++ return retVal; ++ ++ pIpVidMcastAddr->address = l2Table.address; ++ ++ /* Get Logical port mask */ ++ if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pIpVidMcastAddr->portmask)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_ipVidMcastAddr_next_get ++ * Description: ++ * Get Next IP Multicast+VID entry. ++ * Input: ++ * pAddress - The Address ID ++ * Output: ++ * pIpVidMcastAddr - IP & VID multicast Entry ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * Get the next IP multicast entry after the current entry pointed by pAddress. ++ * The address of next entry is returned by pAddress. User can use (address + 1) ++ * as pAddress to call this API again for dumping all IP multicast entries is LUT. ++ */ ++rtk_api_ret_t rtk_l2_ipVidMcastAddr_next_get(rtk_uint32 *pAddress, rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_luttb l2Table; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Error Checking */ ++ if ((pAddress == NULL) || (pIpVidMcastAddr == NULL)) ++ return RT_ERR_INPUT; ++ ++ if(*pAddress > RTK_MAX_LUT_ADDR_ID ) ++ return RT_ERR_L2_L2UNI_PARAM; ++ ++ memset(&l2Table, 0, sizeof(rtl8367c_luttb)); ++ l2Table.address = *pAddress; ++ ++ do ++ { ++ if ((retVal = rtl8367c_getAsicL2LookupTb(LUTREADMETHOD_NEXT_L3MC, &l2Table)) != RT_ERR_OK) ++ return retVal; ++ ++ if(l2Table.address < *pAddress) ++ return RT_ERR_L2_ENTRY_NOTFOUND; ++ ++ }while(l2Table.l3vidlookup == 0); ++ ++ pIpVidMcastAddr->sip = l2Table.sip; ++ pIpVidMcastAddr->dip = l2Table.dip; ++ pIpVidMcastAddr->vid = l2Table.l3_vid; ++ pIpVidMcastAddr->address = l2Table.address; ++ ++ /* Get Logical port mask */ ++ if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &pIpVidMcastAddr->portmask)) != RT_ERR_OK) ++ return retVal; ++ ++ *pAddress = l2Table.address; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_ipVidMcastAddr_del ++ * Description: ++ * Delete a ip multicast+VID address entry from the specified device. ++ * Input: ++ * pIpVidMcastAddr - IP & VID multicast Entry ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_L2_ENTRY_NOTFOUND - No such LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_l2_ipVidMcastAddr_del(rtk_l2_ipVidMcastAddr_t *pIpVidMcastAddr) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 method; ++ rtl8367c_luttb l2Table; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pIpVidMcastAddr) ++ return RT_ERR_NULL_POINTER; ++ ++ if (pIpVidMcastAddr->vid > RTL8367C_VIDMAX) ++ return RT_ERR_L2_VID; ++ ++ if( (pIpVidMcastAddr->dip & 0xF0000000) != 0xE0000000) ++ return RT_ERR_INPUT; ++ ++ memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); ++ l2Table.sip = pIpVidMcastAddr->sip; ++ l2Table.dip = pIpVidMcastAddr->dip; ++ l2Table.l3lookup = 1; ++ l2Table.l3vidlookup = 1; ++ l2Table.l3_vid = pIpVidMcastAddr->vid; ++ method = LUTREADMETHOD_MAC; ++ retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table); ++ if (RT_ERR_OK == retVal) ++ { ++ l2Table.sip = pIpVidMcastAddr->sip; ++ l2Table.dip = pIpVidMcastAddr->dip; ++ l2Table.mbr= 0; ++ l2Table.nosalearn = 0; ++ l2Table.l3lookup = 1; ++ l2Table.l3vidlookup = 1; ++ l2Table.l3_vid = pIpVidMcastAddr->vid; ++ if((retVal = rtl8367c_setAsicL2LookupTb(&l2Table)) != RT_ERR_OK) ++ return retVal; ++ ++ pIpVidMcastAddr->address = l2Table.address; ++ return RT_ERR_OK; ++ } ++ else ++ return retVal; ++} ++ ++/* Function Name: ++ * rtk_l2_ucastAddr_flush ++ * Description: ++ * Flush L2 mac address by type in the specified device (both dynamic and static). ++ * Input: ++ * pConfig - flush 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. ++ * RT_ERR_VLAN_VID - Invalid VID parameter. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * flushByVid - 1: Flush by VID, 0: Don't flush by VID ++ * vid - VID (0 ~ 4095) ++ * flushByFid - 1: Flush by FID, 0: Don't flush by FID ++ * fid - FID (0 ~ 15) ++ * flushByPort - 1: Flush by Port, 0: Don't flush by Port ++ * port - Port ID ++ * flushByMac - Not Supported ++ * ucastAddr - Not Supported ++ * flushStaticAddr - 1: Flush both Static and Dynamic entries, 0: Flush only Dynamic entries ++ * flushAddrOnAllPorts - 1: Flush VID-matched entries at all ports, 0: Flush VID-matched entries per port. ++ */ ++rtk_api_ret_t rtk_l2_ucastAddr_flush(rtk_l2_flushCfg_t *pConfig) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(pConfig == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ if(pConfig->flushByVid >= RTK_ENABLE_END) ++ return RT_ERR_ENABLE; ++ ++ if(pConfig->flushByFid >= RTK_ENABLE_END) ++ return RT_ERR_ENABLE; ++ ++ if(pConfig->flushByPort >= RTK_ENABLE_END) ++ return RT_ERR_ENABLE; ++ ++ if(pConfig->flushByMac >= RTK_ENABLE_END) ++ return RT_ERR_ENABLE; ++ ++ if(pConfig->flushStaticAddr >= RTK_ENABLE_END) ++ return RT_ERR_ENABLE; ++ ++ if(pConfig->flushAddrOnAllPorts >= RTK_ENABLE_END) ++ return RT_ERR_ENABLE; ++ ++ if(pConfig->vid > RTL8367C_VIDMAX) ++ return RT_ERR_VLAN_VID; ++ ++ if(pConfig->fid > RTL8367C_FIDMAX) ++ return RT_ERR_INPUT; ++ ++ /* check port valid */ ++ RTK_CHK_PORT_VALID(pConfig->port); ++ ++ if(pConfig->flushByVid == ENABLED) ++ { ++ if ((retVal = rtl8367c_setAsicLutFlushMode(FLUSHMDOE_VID)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicLutFlushVid(pConfig->vid)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicLutFlushType((pConfig->flushStaticAddr == ENABLED) ? FLUSHTYPE_BOTH : FLUSHTYPE_DYNAMIC)) != RT_ERR_OK) ++ return retVal; ++ ++ if(pConfig->flushAddrOnAllPorts == ENABLED) ++ { ++ if ((retVal = rtl8367c_setAsicLutForceFlush(RTL8367C_PORTMASK)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if(pConfig->flushByPort == ENABLED) ++ { ++ if ((retVal = rtl8367c_setAsicLutForceFlush(1 << rtk_switch_port_L2P_get(pConfig->port))) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ return RT_ERR_INPUT; ++ } ++ else if(pConfig->flushByFid == ENABLED) ++ { ++ if ((retVal = rtl8367c_setAsicLutFlushMode(FLUSHMDOE_FID)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicLutFlushFid(pConfig->fid)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicLutFlushType((pConfig->flushStaticAddr == ENABLED) ? FLUSHTYPE_BOTH : FLUSHTYPE_DYNAMIC)) != RT_ERR_OK) ++ return retVal; ++ ++ if(pConfig->flushAddrOnAllPorts == ENABLED) ++ { ++ if ((retVal = rtl8367c_setAsicLutForceFlush(RTL8367C_PORTMASK)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if(pConfig->flushByPort == ENABLED) ++ { ++ if ((retVal = rtl8367c_setAsicLutForceFlush(1 << rtk_switch_port_L2P_get(pConfig->port))) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ return RT_ERR_INPUT; ++ } ++ else if(pConfig->flushByPort == ENABLED) ++ { ++ if ((retVal = rtl8367c_setAsicLutFlushType((pConfig->flushStaticAddr == ENABLED) ? FLUSHTYPE_BOTH : FLUSHTYPE_DYNAMIC)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicLutFlushMode(FLUSHMDOE_PORT)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicLutForceFlush(1 << rtk_switch_port_L2P_get(pConfig->port))) != RT_ERR_OK) ++ return retVal; ++ } ++ else if(pConfig->flushByMac == ENABLED) ++ { ++ /* Should use API "rtk_l2_addr_del" to remove a specified entry*/ ++ return RT_ERR_CHIP_NOT_SUPPORTED; ++ } ++ else ++ return RT_ERR_INPUT; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_table_clear ++ * Description: ++ * Flush all static & dynamic entries in LUT. ++ * Input: ++ * None ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_l2_table_clear(void) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ((retVal = rtl8367c_setAsicLutFlushAll()) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_table_clearStatus_get ++ * Description: ++ * Get table clear status ++ * Input: ++ * None ++ * Output: ++ * pStatus - Clear status, 1:Busy, 0:finish ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_l2_table_clearStatus_get(rtk_l2_clearStatus_t *pStatus) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pStatus) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicLutFlushAllStatus((rtk_uint32 *)pStatus)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_flushLinkDownPortAddrEnable_set ++ * Description: ++ * Set HW flush linkdown port mac configuration of the specified device. ++ * Input: ++ * port - Port id. ++ * enable - link down flush 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: ++ * The status of flush linkdown port address is as following: ++ * - DISABLED ++ * - ENABLED ++ */ ++rtk_api_ret_t rtk_l2_flushLinkDownPortAddrEnable_set(rtk_port_t port, rtk_enable_t enable) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (port != RTK_WHOLE_SYSTEM) ++ return RT_ERR_PORT_ID; ++ ++ if (enable >= RTK_ENABLE_END) ++ return RT_ERR_ENABLE; ++ ++ if ((retVal = rtl8367c_setAsicLutLinkDownForceAging(enable)) != RT_ERR_OK) ++ return retVal; ++ ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_flushLinkDownPortAddrEnable_get ++ * Description: ++ * Get HW flush linkdown port mac configuration of the specified device. ++ * Input: ++ * port - Port id. ++ * Output: ++ * pEnable - link down flush status ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number. ++ * Note: ++ * The status of flush linkdown port address is as following: ++ * - DISABLED ++ * - ENABLED ++ */ ++rtk_api_ret_t rtk_l2_flushLinkDownPortAddrEnable_get(rtk_port_t port, rtk_enable_t *pEnable) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (port != RTK_WHOLE_SYSTEM) ++ return RT_ERR_PORT_ID; ++ ++ if(NULL == pEnable) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicLutLinkDownForceAging(pEnable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_agingEnable_set ++ * Description: ++ * Set L2 LUT aging status per port setting. ++ * Input: ++ * port - Port id. ++ * enable - Aging 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 be used to set L2 LUT aging status per port. ++ */ ++rtk_api_ret_t rtk_l2_agingEnable_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(enable == 1) ++ enable = 0; ++ else ++ enable = 1; ++ ++ if ((retVal = rtl8367c_setAsicLutDisableAging(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_agingEnable_get ++ * Description: ++ * Get L2 LUT aging status per port setting. ++ * Input: ++ * port - Port id. ++ * Output: ++ * pEnable - Aging 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 be used to get L2 LUT aging function per port. ++ */ ++rtk_api_ret_t rtk_l2_agingEnable_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_getAsicLutDisableAging(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) ++ return retVal; ++ ++ if(*pEnable == 1) ++ *pEnable = 0; ++ else ++ *pEnable = 1; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_limitLearningCnt_set ++ * Description: ++ * Set per-Port auto learning limit number ++ * Input: ++ * port - Port id. ++ * mac_cnt - Auto learning entries limit number ++ * 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_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number ++ * Note: ++ * The API can set per-port ASIC auto learning limit number from 0(disable learning) ++ * to 2112. ++ */ ++rtk_api_ret_t rtk_l2_limitLearningCnt_set(rtk_port_t port, rtk_mac_cnt_t mac_cnt) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* check port valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if (mac_cnt > rtk_switch_maxLutAddrNumber_get()) ++ return RT_ERR_LIMITED_L2ENTRY_NUM; ++ ++ if ((retVal = rtl8367c_setAsicLutLearnLimitNo(rtk_switch_port_L2P_get(port), mac_cnt)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_limitLearningCnt_get ++ * Description: ++ * Get per-Port auto learning limit number ++ * Input: ++ * port - Port id. ++ * Output: ++ * pMac_cnt - Auto learning entries limit 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 can get per-port ASIC auto learning limit number. ++ */ ++rtk_api_ret_t rtk_l2_limitLearningCnt_get(rtk_port_t port, rtk_mac_cnt_t *pMac_cnt) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* check port valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(NULL == pMac_cnt) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicLutLearnLimitNo(rtk_switch_port_L2P_get(port), pMac_cnt)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_limitSystemLearningCnt_set ++ * Description: ++ * Set System auto learning limit number ++ * Input: ++ * mac_cnt - Auto learning entries limit number ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number ++ * Note: ++ * The API can set system ASIC auto learning limit number from 0(disable learning) ++ * to 2112. ++ */ ++rtk_api_ret_t rtk_l2_limitSystemLearningCnt_set(rtk_mac_cnt_t mac_cnt) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (mac_cnt > rtk_switch_maxLutAddrNumber_get()) ++ return RT_ERR_LIMITED_L2ENTRY_NUM; ++ ++ if ((retVal = rtl8367c_setAsicSystemLutLearnLimitNo(mac_cnt)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_limitSystemLearningCnt_get ++ * Description: ++ * Get System auto learning limit number ++ * Input: ++ * None ++ * Output: ++ * pMac_cnt - Auto learning entries limit 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 can get system ASIC auto learning limit number. ++ */ ++rtk_api_ret_t rtk_l2_limitSystemLearningCnt_get(rtk_mac_cnt_t *pMac_cnt) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pMac_cnt) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicSystemLutLearnLimitNo(pMac_cnt)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_limitLearningCntAction_set ++ * Description: ++ * Configure auto learn over limit number action. ++ * Input: ++ * port - Port id. ++ * action - Auto learning entries limit number ++ * 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_NOT_ALLOWED - Invalid learn over action ++ * Note: ++ * The API can set SA unknown packet action while auto learn limit number is over ++ * The action symbol as following: ++ * - LIMIT_LEARN_CNT_ACTION_DROP, ++ * - LIMIT_LEARN_CNT_ACTION_FORWARD, ++ * - LIMIT_LEARN_CNT_ACTION_TO_CPU, ++ */ ++rtk_api_ret_t rtk_l2_limitLearningCntAction_set(rtk_port_t port, rtk_l2_limitLearnCntAction_t action) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 data; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (port != RTK_WHOLE_SYSTEM) ++ return RT_ERR_PORT_ID; ++ ++ if ( LIMIT_LEARN_CNT_ACTION_DROP == action ) ++ data = 1; ++ else if ( LIMIT_LEARN_CNT_ACTION_FORWARD == action ) ++ data = 0; ++ else if ( LIMIT_LEARN_CNT_ACTION_TO_CPU == action ) ++ data = 2; ++ else ++ return RT_ERR_NOT_ALLOWED; ++ ++ if ((retVal = rtl8367c_setAsicLutLearnOverAct(data)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_limitLearningCntAction_get ++ * Description: ++ * Get auto learn over limit number action. ++ * Input: ++ * port - Port id. ++ * Output: ++ * pAction - Learn over action ++ * 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 SA unknown packet action while auto learn limit number is over ++ * The action symbol as following: ++ * - LIMIT_LEARN_CNT_ACTION_DROP, ++ * - LIMIT_LEARN_CNT_ACTION_FORWARD, ++ * - LIMIT_LEARN_CNT_ACTION_TO_CPU, ++ */ ++rtk_api_ret_t rtk_l2_limitLearningCntAction_get(rtk_port_t port, rtk_l2_limitLearnCntAction_t *pAction) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 action; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (port != RTK_WHOLE_SYSTEM) ++ return RT_ERR_PORT_ID; ++ ++ if(NULL == pAction) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicLutLearnOverAct(&action)) != RT_ERR_OK) ++ return retVal; ++ ++ if ( 1 == action ) ++ *pAction = LIMIT_LEARN_CNT_ACTION_DROP; ++ else if ( 0 == action ) ++ *pAction = LIMIT_LEARN_CNT_ACTION_FORWARD; ++ else if ( 2 == action ) ++ *pAction = LIMIT_LEARN_CNT_ACTION_TO_CPU; ++ else ++ *pAction = action; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_limitSystemLearningCntAction_set ++ * Description: ++ * Configure system auto learn over limit number action. ++ * Input: ++ * port - Port id. ++ * action - Auto learning entries limit number ++ * 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_NOT_ALLOWED - Invalid learn over action ++ * Note: ++ * The API can set SA unknown packet action while auto learn limit number is over ++ * The action symbol as following: ++ * - LIMIT_LEARN_CNT_ACTION_DROP, ++ * - LIMIT_LEARN_CNT_ACTION_FORWARD, ++ * - LIMIT_LEARN_CNT_ACTION_TO_CPU, ++ */ ++rtk_api_ret_t rtk_l2_limitSystemLearningCntAction_set(rtk_l2_limitLearnCntAction_t action) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 data; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ( LIMIT_LEARN_CNT_ACTION_DROP == action ) ++ data = 1; ++ else if ( LIMIT_LEARN_CNT_ACTION_FORWARD == action ) ++ data = 0; ++ else if ( LIMIT_LEARN_CNT_ACTION_TO_CPU == action ) ++ data = 2; ++ else ++ return RT_ERR_NOT_ALLOWED; ++ ++ if ((retVal = rtl8367c_setAsicSystemLutLearnOverAct(data)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_limitSystemLearningCntAction_get ++ * Description: ++ * Get system auto learn over limit number action. ++ * Input: ++ * None. ++ * Output: ++ * pAction - Learn over action ++ * 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 SA unknown packet action while auto learn limit number is over ++ * The action symbol as following: ++ * - LIMIT_LEARN_CNT_ACTION_DROP, ++ * - LIMIT_LEARN_CNT_ACTION_FORWARD, ++ * - LIMIT_LEARN_CNT_ACTION_TO_CPU, ++ */ ++rtk_api_ret_t rtk_l2_limitSystemLearningCntAction_get(rtk_l2_limitLearnCntAction_t *pAction) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 action; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pAction) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicSystemLutLearnOverAct(&action)) != RT_ERR_OK) ++ return retVal; ++ ++ if ( 1 == action ) ++ *pAction = LIMIT_LEARN_CNT_ACTION_DROP; ++ else if ( 0 == action ) ++ *pAction = LIMIT_LEARN_CNT_ACTION_FORWARD; ++ else if ( 2 == action ) ++ *pAction = LIMIT_LEARN_CNT_ACTION_TO_CPU; ++ else ++ *pAction = action; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_limitSystemLearningCntPortMask_set ++ * Description: ++ * Configure system auto learn portmask ++ * Input: ++ * pPortmask - 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: ++ * ++ */ ++rtk_api_ret_t rtk_l2_limitSystemLearningCntPortMask_set(rtk_portmask_t *pPortmask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pPortmask) ++ return RT_ERR_NULL_POINTER; ++ ++ /* Check port mask */ ++ RTK_CHK_PORTMASK_VALID(pPortmask); ++ ++ if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicSystemLutLearnPortMask(pmask)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_limitSystemLearningCntPortMask_get ++ * Description: ++ * get system auto learn portmask ++ * Input: ++ * None ++ * Output: ++ * pPortmask - Port Mask ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NULL_POINTER - Null pointer. ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_l2_limitSystemLearningCntPortMask_get(rtk_portmask_t *pPortmask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pPortmask) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicSystemLutLearnPortMask(&pmask)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_learningCnt_get ++ * Description: ++ * Get per-Port current auto learning number ++ * Input: ++ * port - Port id. ++ * Output: ++ * pMac_cnt - ASIC auto learning entries 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 can get per-port ASIC auto learning number ++ */ ++rtk_api_ret_t rtk_l2_learningCnt_get(rtk_port_t port, rtk_mac_cnt_t *pMac_cnt) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* check port valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(NULL == pMac_cnt) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicLutLearnNo(rtk_switch_port_L2P_get(port), pMac_cnt)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_floodPortMask_set ++ * Description: ++ * Set flooding portmask ++ * Input: ++ * type - flooding type. ++ * pFlood_portmask - flooding porkmask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_MASK - Invalid portmask. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * This API can set the flooding mask. ++ * The flooding type is as following: ++ * - FLOOD_UNKNOWNDA ++ * - FLOOD_UNKNOWNMC ++ * - FLOOD_BC ++ */ ++rtk_api_ret_t rtk_l2_floodPortMask_set(rtk_l2_flood_type_t floood_type, rtk_portmask_t *pFlood_portmask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (floood_type >= FLOOD_END) ++ return RT_ERR_INPUT; ++ ++ /* check port valid */ ++ RTK_CHK_PORTMASK_VALID(pFlood_portmask); ++ ++ /* Get Physical port mask */ ++ if ((retVal = rtk_switch_portmask_L2P_get(pFlood_portmask, &pmask))!=RT_ERR_OK) ++ return retVal; ++ ++ switch (floood_type) ++ { ++ case FLOOD_UNKNOWNDA: ++ if ((retVal = rtl8367c_setAsicPortUnknownDaFloodingPortmask(pmask)) != RT_ERR_OK) ++ return retVal; ++ break; ++ case FLOOD_UNKNOWNMC: ++ if ((retVal = rtl8367c_setAsicPortUnknownMulticastFloodingPortmask(pmask)) != RT_ERR_OK) ++ return retVal; ++ break; ++ case FLOOD_BC: ++ if ((retVal = rtl8367c_setAsicPortBcastFloodingPortmask(pmask)) != RT_ERR_OK) ++ return retVal; ++ break; ++ default: ++ break; ++ } ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtk_l2_floodPortMask_get ++ * Description: ++ * Get flooding portmask ++ * Input: ++ * type - flooding type. ++ * Output: ++ * pFlood_portmask - flooding porkmask ++ * 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 flooding mask. ++ * The flooding type is as following: ++ * - FLOOD_UNKNOWNDA ++ * - FLOOD_UNKNOWNMC ++ * - FLOOD_BC ++ */ ++rtk_api_ret_t rtk_l2_floodPortMask_get(rtk_l2_flood_type_t floood_type, rtk_portmask_t *pFlood_portmask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (floood_type >= FLOOD_END) ++ return RT_ERR_INPUT; ++ ++ if(NULL == pFlood_portmask) ++ return RT_ERR_NULL_POINTER; ++ ++ switch (floood_type) ++ { ++ case FLOOD_UNKNOWNDA: ++ if ((retVal = rtl8367c_getAsicPortUnknownDaFloodingPortmask(&pmask)) != RT_ERR_OK) ++ return retVal; ++ break; ++ case FLOOD_UNKNOWNMC: ++ if ((retVal = rtl8367c_getAsicPortUnknownMulticastFloodingPortmask(&pmask)) != RT_ERR_OK) ++ return retVal; ++ break; ++ case FLOOD_BC: ++ if ((retVal = rtl8367c_getAsicPortBcastFloodingPortmask(&pmask)) != RT_ERR_OK) ++ return retVal; ++ break; ++ default: ++ break; ++ } ++ ++ /* Get Logical port mask */ ++ if ((retVal = rtk_switch_portmask_P2L_get(pmask, pFlood_portmask))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_localPktPermit_set ++ * Description: ++ * Set permittion of frames if source port and destination port are the same. ++ * Input: ++ * port - Port id. ++ * permit - permittion 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 permit value. ++ * Note: ++ * This API is setted to permit frame if its source port is equal to destination port. ++ */ ++rtk_api_ret_t rtk_l2_localPktPermit_set(rtk_port_t port, rtk_enable_t permit) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* check port valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if (permit >= RTK_ENABLE_END) ++ return RT_ERR_ENABLE; ++ ++ if ((retVal = rtl8367c_setAsicPortBlockSpa(rtk_switch_port_L2P_get(port), permit)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_localPktPermit_get ++ * Description: ++ * Get permittion of frames if source port and destination port are the same. ++ * Input: ++ * port - Port id. ++ * Output: ++ * pPermit - permittion 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 is to get permittion status for frames if its source port is equal to destination port. ++ */ ++rtk_api_ret_t rtk_l2_localPktPermit_get(rtk_port_t port, rtk_enable_t *pPermit) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* check port valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(NULL == pPermit) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicPortBlockSpa(rtk_switch_port_L2P_get(port), pPermit)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_aging_set ++ * Description: ++ * Set LUT agging out speed ++ * Input: ++ * aging_time - Agging out time. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * Note: ++ * The API can set LUT agging out period for each entry and the range is from 45s to 458s. ++ */ ++rtk_api_ret_t rtk_l2_aging_set(rtk_l2_age_time_t aging_time) ++{ ++ rtk_uint32 i; ++ CONST_T rtk_uint32 agePara[10][3] = { ++ {45, 0, 1}, {88, 0, 2}, {133, 0, 3}, {177, 0, 4}, {221, 0, 5}, {266, 0, 6}, {310, 0, 7}, ++ {354, 2, 6}, {413, 2, 7}, {458, 3, 7}}; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (aging_time>agePara[9][0]) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ for (i = 0; i<10; i++) ++ { ++ if (aging_time<=agePara[i][0]) ++ { ++ return rtl8367c_setAsicLutAgeTimerSpeed(agePara[i][2], agePara[i][1]); ++ } ++ } ++ ++ return RT_ERR_FAILED; ++} ++ ++/* Function Name: ++ * rtk_l2_aging_get ++ * Description: ++ * Get LUT agging out time ++ * Input: ++ * None ++ * Output: ++ * pEnable - Aging status ++ * 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 LUT agging out period for each entry. ++ */ ++rtk_api_ret_t rtk_l2_aging_get(rtk_l2_age_time_t *pAging_time) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 i,time, speed; ++ CONST_T rtk_uint32 agePara[10][3] = { ++ {45, 0, 1}, {88, 0, 2}, {133, 0, 3}, {177, 0, 4}, {221, 0, 5}, {266, 0, 6}, {310, 0, 7}, ++ {354, 2, 6}, {413, 2, 7}, {458, 3, 7}}; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pAging_time) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicLutAgeTimerSpeed(&time, &speed)) != RT_ERR_OK) ++ return retVal; ++ ++ for (i = 0; i<10; i++) ++ { ++ if (time==agePara[i][2]&&speed==agePara[i][1]) ++ { ++ *pAging_time = agePara[i][0]; ++ return RT_ERR_OK; ++ } ++ } ++ ++ return RT_ERR_FAILED; ++} ++ ++/* Function Name: ++ * rtk_l2_ipMcastAddrLookup_set ++ * Description: ++ * Set Lut IP multicast lookup function ++ * Input: ++ * type - Lookup type for IPMC packet. ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * LOOKUP_MAC - Lookup by MAC address ++ * LOOKUP_IP - Lookup by IP address ++ * LOOKUP_IP_VID - Lookup by IP address & VLAN ID ++ */ ++rtk_api_ret_t rtk_l2_ipMcastAddrLookup_set(rtk_l2_ipmc_lookup_type_t type) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(type == LOOKUP_MAC) ++ { ++ if((retVal = rtl8367c_setAsicLutIpMulticastLookup(DISABLED)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if(type == LOOKUP_IP) ++ { ++ if((retVal = rtl8367c_setAsicLutIpMulticastLookup(ENABLED)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicLutIpMulticastVidLookup(DISABLED))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicLutIpLookupMethod(1))!=RT_ERR_OK) ++ return retVal; ++ } ++ else if(type == LOOKUP_IP_VID) ++ { ++ if((retVal = rtl8367c_setAsicLutIpMulticastLookup(ENABLED)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicLutIpMulticastVidLookup(ENABLED))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicLutIpLookupMethod(1))!=RT_ERR_OK) ++ return retVal; ++ } ++ else ++ return RT_ERR_INPUT; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_ipMcastAddrLookup_get ++ * Description: ++ * Get Lut IP multicast lookup function ++ * Input: ++ * None. ++ * Output: ++ * pType - Lookup type for IPMC packet. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None. ++ */ ++rtk_api_ret_t rtk_l2_ipMcastAddrLookup_get(rtk_l2_ipmc_lookup_type_t *pType) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 enabled, vid_lookup; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pType) ++ return RT_ERR_NULL_POINTER; ++ ++ if((retVal = rtl8367c_getAsicLutIpMulticastLookup(&enabled)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicLutIpMulticastVidLookup(&vid_lookup))!=RT_ERR_OK) ++ return retVal; ++ ++ if(enabled == ENABLED) ++ { ++ if(vid_lookup == ENABLED) ++ *pType = LOOKUP_IP_VID; ++ else ++ *pType = LOOKUP_IP; ++ } ++ else ++ *pType = LOOKUP_MAC; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_ipMcastForwardRouterPort_set ++ * Description: ++ * Set IPMC packet forward to rounter port also or not ++ * Input: ++ * enabled - 1: Inlcude router port, 0, exclude router port ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_l2_ipMcastForwardRouterPort_set(rtk_enable_t enabled) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (enabled >= RTK_ENABLE_END) ++ return RT_ERR_ENABLE; ++ ++ if((retVal = rtl8367c_setAsicLutIpmcFwdRouterPort(enabled)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_ipMcastForwardRouterPort_get ++ * Description: ++ * Get IPMC packet forward to rounter port also or not ++ * Input: ++ * None. ++ * Output: ++ * pEnabled - 1: Inlcude router port, 0, exclude router port ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_NULL_POINTER - Null pointer ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_l2_ipMcastForwardRouterPort_get(rtk_enable_t *pEnabled) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (NULL == pEnabled) ++ return RT_ERR_NULL_POINTER; ++ ++ if((retVal = rtl8367c_getAsicLutIpmcFwdRouterPort(pEnabled)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_ipMcastGroupEntry_add ++ * Description: ++ * Add an IP Multicast entry to group table ++ * Input: ++ * ip_addr - IP address ++ * vid - VLAN ID ++ * pPortmask - portmask ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_TBL_FULL - Table Full ++ * Note: ++ * Add an entry to IP Multicast Group table. ++ */ ++rtk_api_ret_t rtk_l2_ipMcastGroupEntry_add(ipaddr_t ip_addr, rtk_uint32 vid, rtk_portmask_t *pPortmask) ++{ ++ rtk_uint32 empty_idx = 0xFFFF; ++ rtk_int32 index; ++ ipaddr_t group_addr; ++ rtk_uint32 group_vid; ++ rtk_uint32 pmask; ++ rtk_uint32 valid; ++ rtk_uint32 physicalPortmask; ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (vid > RTL8367C_VIDMAX) ++ return RT_ERR_L2_VID; ++ ++ if(NULL == pPortmask) ++ return RT_ERR_NULL_POINTER; ++ ++ if((ip_addr & 0xF0000000) != 0xE0000000) ++ return RT_ERR_INPUT; ++ ++ /* Get Physical port mask */ ++ if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &physicalPortmask))!=RT_ERR_OK) ++ return retVal; ++ ++ for(index = 0; index <= RTL8367C_LUT_IPMCGRP_TABLE_MAX; index++) ++ { ++ if ((retVal = rtl8367c_getAsicLutIPMCGroup((rtk_uint32)index, &group_addr, &group_vid, &pmask, &valid))!=RT_ERR_OK) ++ return retVal; ++ ++ if( (valid == ENABLED) && (group_addr == ip_addr) && (group_vid == vid) ) ++ { ++ if(pmask != physicalPortmask) ++ { ++ pmask = physicalPortmask; ++ if ((retVal = rtl8367c_setAsicLutIPMCGroup(index, ip_addr, vid, pmask, valid))!=RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++ } ++ ++ if( (valid == DISABLED) && (empty_idx == 0xFFFF) ) /* Unused */ ++ empty_idx = (rtk_uint32)index; ++ } ++ ++ if(empty_idx == 0xFFFF) ++ return RT_ERR_TBL_FULL; ++ ++ pmask = physicalPortmask; ++ if ((retVal = rtl8367c_setAsicLutIPMCGroup(empty_idx, ip_addr, vid, pmask, ENABLED))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_l2_ipMcastGroupEntry_del ++ * Description: ++ * Delete an entry from IP Multicast group table ++ * Input: ++ * ip_addr - IP address ++ * vid - VLAN ID ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_TBL_FULL - Table Full ++ * Note: ++ * Delete an entry from IP Multicast group table. ++ */ ++rtk_api_ret_t rtk_l2_ipMcastGroupEntry_del(ipaddr_t ip_addr, rtk_uint32 vid) ++{ ++ rtk_int32 index; ++ ipaddr_t group_addr; ++ rtk_uint32 group_vid; ++ rtk_uint32 pmask; ++ rtk_uint32 valid; ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (vid > RTL8367C_VIDMAX) ++ return RT_ERR_L2_VID; ++ ++ if((ip_addr & 0xF0000000) != 0xE0000000) ++ return RT_ERR_INPUT; ++ ++ for(index = 0; index <= RTL8367C_LUT_IPMCGRP_TABLE_MAX; index++) ++ { ++ if ((retVal = rtl8367c_getAsicLutIPMCGroup((rtk_uint32)index, &group_addr, &group_vid, &pmask, &valid))!=RT_ERR_OK) ++ return retVal; ++ ++ if( (valid == ENABLED) && (group_addr == ip_addr) && (group_vid == vid) ) ++ { ++ group_addr = 0xE0000000; ++ group_vid = 0; ++ pmask = 0; ++ if ((retVal = rtl8367c_setAsicLutIPMCGroup(index, group_addr, group_vid, pmask, DISABLED))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++ } ++ } ++ ++ return RT_ERR_FAILED; ++} ++ ++/* Function Name: ++ * rtk_l2_ipMcastGroupEntry_get ++ * Description: ++ * get an entry from IP Multicast group table ++ * Input: ++ * ip_addr - IP address ++ * vid - VLAN ID ++ * Output: ++ * pPortmask - member port mask ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_TBL_FULL - Table Full ++ * Note: ++ * Delete an entry from IP Multicast group table. ++ */ ++rtk_api_ret_t rtk_l2_ipMcastGroupEntry_get(ipaddr_t ip_addr, rtk_uint32 vid, rtk_portmask_t *pPortmask) ++{ ++ rtk_int32 index; ++ ipaddr_t group_addr; ++ rtk_uint32 group_vid; ++ rtk_uint32 valid; ++ rtk_uint32 pmask; ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if((ip_addr & 0xF0000000) != 0xE0000000) ++ return RT_ERR_INPUT; ++ ++ if (vid > RTL8367C_VIDMAX) ++ return RT_ERR_L2_VID; ++ ++ if(NULL == pPortmask) ++ return RT_ERR_NULL_POINTER; ++ ++ for(index = 0; index <= RTL8367C_LUT_IPMCGRP_TABLE_MAX; index++) ++ { ++ if ((retVal = rtl8367c_getAsicLutIPMCGroup((rtk_uint32)index, &group_addr, &group_vid, &pmask, &valid))!=RT_ERR_OK) ++ return retVal; ++ ++ if( (valid == ENABLED) && (group_addr == ip_addr) && (group_vid == vid) ) ++ { ++ if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++ } ++ } ++ ++ return RT_ERR_FAILED; ++} ++ ++/* Function Name: ++ * rtk_l2_entry_get ++ * Description: ++ * Get LUT unicast entry. ++ * Input: ++ * pL2_entry - Index field in the structure. ++ * Output: ++ * pL2_entry - other fields such as MAC, port, age... ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_L2_EMPTY_ENTRY - Empty LUT entry. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * This API is used to get address by index from 0~2111. ++ */ ++rtk_api_ret_t rtk_l2_entry_get(rtk_l2_addr_table_t *pL2_entry) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 method; ++ rtl8367c_luttb l2Table; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (pL2_entry->index >= rtk_switch_maxLutAddrNumber_get()) ++ return RT_ERR_INPUT; ++ ++ memset(&l2Table, 0x00, sizeof(rtl8367c_luttb)); ++ l2Table.address= pL2_entry->index; ++ method = LUTREADMETHOD_ADDRESS; ++ if ((retVal = rtl8367c_getAsicL2LookupTb(method, &l2Table)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((pL2_entry->index>0x800)&&(l2Table.lookup_hit==0)) ++ return RT_ERR_L2_EMPTY_ENTRY; ++ ++ if(l2Table.l3lookup) ++ { ++ if(l2Table.l3vidlookup) ++ { ++ memset(&pL2_entry->mac, 0, sizeof(rtk_mac_t)); ++ pL2_entry->is_ipmul = l2Table.l3lookup; ++ pL2_entry->sip = l2Table.sip; ++ pL2_entry->dip = l2Table.dip; ++ pL2_entry->is_static = l2Table.nosalearn; ++ ++ /* Get Logical port mask */ ++ if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &(pL2_entry->portmask)))!=RT_ERR_OK) ++ return retVal; ++ ++ pL2_entry->fid = 0; ++ pL2_entry->age = 0; ++ pL2_entry->auth = 0; ++ pL2_entry->sa_block = 0; ++ pL2_entry->is_ipvidmul = 1; ++ pL2_entry->l3_vid = l2Table.l3_vid; ++ } ++ else ++ { ++ memset(&pL2_entry->mac, 0, sizeof(rtk_mac_t)); ++ pL2_entry->is_ipmul = l2Table.l3lookup; ++ pL2_entry->sip = l2Table.sip; ++ pL2_entry->dip = l2Table.dip; ++ pL2_entry->is_static = l2Table.nosalearn; ++ ++ /* Get Logical port mask */ ++ if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &(pL2_entry->portmask)))!=RT_ERR_OK) ++ return retVal; ++ ++ pL2_entry->fid = 0; ++ pL2_entry->age = 0; ++ pL2_entry->auth = 0; ++ pL2_entry->sa_block = 0; ++ pL2_entry->is_ipvidmul = 0; ++ pL2_entry->l3_vid = 0; ++ } ++ } ++ else if(l2Table.mac.octet[0]&0x01) ++ { ++ memset(&pL2_entry->sip, 0, sizeof(ipaddr_t)); ++ memset(&pL2_entry->dip, 0, sizeof(ipaddr_t)); ++ pL2_entry->mac.octet[0] = l2Table.mac.octet[0]; ++ pL2_entry->mac.octet[1] = l2Table.mac.octet[1]; ++ pL2_entry->mac.octet[2] = l2Table.mac.octet[2]; ++ pL2_entry->mac.octet[3] = l2Table.mac.octet[3]; ++ pL2_entry->mac.octet[4] = l2Table.mac.octet[4]; ++ pL2_entry->mac.octet[5] = l2Table.mac.octet[5]; ++ pL2_entry->is_ipmul = l2Table.l3lookup; ++ pL2_entry->is_static = l2Table.nosalearn; ++ ++ /* Get Logical port mask */ ++ if ((retVal = rtk_switch_portmask_P2L_get(l2Table.mbr, &(pL2_entry->portmask)))!=RT_ERR_OK) ++ return retVal; ++ ++ pL2_entry->ivl = l2Table.ivl_svl; ++ if(l2Table.ivl_svl == 1) /* IVL */ ++ { ++ pL2_entry->cvid = l2Table.cvid_fid; ++ pL2_entry->fid = 0; ++ } ++ else /* SVL*/ ++ { ++ pL2_entry->cvid = 0; ++ pL2_entry->fid = l2Table.cvid_fid; ++ } ++ pL2_entry->auth = l2Table.auth; ++ pL2_entry->sa_block = l2Table.sa_block; ++ pL2_entry->age = 0; ++ pL2_entry->is_ipvidmul = 0; ++ pL2_entry->l3_vid = 0; ++ } ++ else if((l2Table.age != 0)||(l2Table.nosalearn == 1)) ++ { ++ memset(&pL2_entry->sip, 0, sizeof(ipaddr_t)); ++ memset(&pL2_entry->dip, 0, sizeof(ipaddr_t)); ++ pL2_entry->mac.octet[0] = l2Table.mac.octet[0]; ++ pL2_entry->mac.octet[1] = l2Table.mac.octet[1]; ++ pL2_entry->mac.octet[2] = l2Table.mac.octet[2]; ++ pL2_entry->mac.octet[3] = l2Table.mac.octet[3]; ++ pL2_entry->mac.octet[4] = l2Table.mac.octet[4]; ++ pL2_entry->mac.octet[5] = l2Table.mac.octet[5]; ++ pL2_entry->is_ipmul = l2Table.l3lookup; ++ pL2_entry->is_static = l2Table.nosalearn; ++ ++ /* Get Logical port mask */ ++ if ((retVal = rtk_switch_portmask_P2L_get(1<<(l2Table.spa), &(pL2_entry->portmask)))!=RT_ERR_OK) ++ return retVal; ++ ++ pL2_entry->ivl = l2Table.ivl_svl; ++ pL2_entry->cvid = l2Table.cvid_fid; ++ pL2_entry->fid = l2Table.fid; ++ pL2_entry->auth = l2Table.auth; ++ pL2_entry->sa_block = l2Table.sa_block; ++ pL2_entry->age = l2Table.age; ++ pL2_entry->is_ipvidmul = 0; ++ pL2_entry->l3_vid = 0; ++ } ++ else ++ return RT_ERR_L2_EMPTY_ENTRY; ++ ++ return RT_ERR_OK; ++} ++ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/leaky.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/leaky.c +new file mode 100644 +index 0000000000..1b7d50a9e5 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/leaky.c +@@ -0,0 +1,590 @@ ++/* ++ * 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 Leaky module. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_leaky_vlan_set(rtk_leaky_type_t type, rtk_enable_t enable) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 port; ++ rtl8367c_rma_t rmacfg; ++ rtk_uint32 tmp; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (type >= LEAKY_END) ++ return RT_ERR_INPUT; ++ ++ if (enable >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if (type >= 0 && type <= LEAKY_UNDEF_GARP_2F) ++ { ++ if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ rmacfg.vlan_leaky = enable; ++ ++ if ((retVal = rtl8367c_setAsicRma(type, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (LEAKY_IPMULTICAST == type) ++ { ++ for (port = 0; port <= RTK_PORT_ID_MAX; port++) ++ { ++ if ((retVal = rtl8367c_setAsicIpMulticastVlanLeaky(port,enable)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ else if (LEAKY_IGMP == type) ++ { ++ if ((retVal = rtl8367c_setAsicIGMPVLANLeaky(enable)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (LEAKY_CDP == type) ++ { ++ if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ rmacfg.vlan_leaky = enable; ++ ++ if ((retVal = rtl8367c_setAsicRmaCdp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (LEAKY_CSSTP == type) ++ { ++ if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ rmacfg.vlan_leaky = enable; ++ ++ if ((retVal = rtl8367c_setAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (LEAKY_LLDP == type) ++ { ++ if ((retVal = rtl8367c_getAsicRmaLldp(&tmp,&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ rmacfg.vlan_leaky = enable; ++ ++ if ((retVal = rtl8367c_setAsicRmaLldp(tmp, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_leaky_vlan_get(rtk_leaky_type_t type, rtk_enable_t *pEnable) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 port,tmp; ++ rtl8367c_rma_t rmacfg; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (type >= LEAKY_END) ++ return RT_ERR_INPUT; ++ ++ if(NULL == pEnable) ++ return RT_ERR_NULL_POINTER; ++ ++ if (type >= 0 && type <= LEAKY_UNDEF_GARP_2F) ++ { ++ if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEnable = rmacfg.vlan_leaky; ++ ++ } ++ else if (LEAKY_IPMULTICAST == type) ++ { ++ for (port = 0; port <= RTK_PORT_ID_MAX; port++) ++ { ++ if ((retVal = rtl8367c_getAsicIpMulticastVlanLeaky(port, &tmp)) != RT_ERR_OK) ++ return retVal; ++ if (port>0&&(tmp!=*pEnable)) ++ return RT_ERR_FAILED; ++ *pEnable = tmp; ++ } ++ } ++ else if (LEAKY_IGMP == type) ++ { ++ if ((retVal = rtl8367c_getAsicIGMPVLANLeaky(&tmp)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEnable = tmp; ++ } ++ else if (LEAKY_CDP == type) ++ { ++ if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEnable = rmacfg.vlan_leaky; ++ } ++ else if (LEAKY_CSSTP == type) ++ { ++ if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEnable = rmacfg.vlan_leaky; ++ } ++ else if (LEAKY_LLDP == type) ++ { ++ if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEnable = rmacfg.vlan_leaky; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_leaky_portIsolation_set(rtk_leaky_type_t type, rtk_enable_t enable) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 port; ++ rtl8367c_rma_t rmacfg; ++ rtk_uint32 tmp; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (type >= LEAKY_END) ++ return RT_ERR_INPUT; ++ ++ if (enable >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if (type >= 0 && type <= LEAKY_UNDEF_GARP_2F) ++ { ++ if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ rmacfg.portiso_leaky = enable; ++ ++ if ((retVal = rtl8367c_setAsicRma(type, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (LEAKY_IPMULTICAST == type) ++ { ++ for (port = 0; port < RTK_MAX_NUM_OF_PORT; port++) ++ { ++ if ((retVal = rtl8367c_setAsicIpMulticastPortIsoLeaky(port,enable)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ else if (LEAKY_IGMP == type) ++ { ++ if ((retVal = rtl8367c_setAsicIGMPIsoLeaky(enable)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (LEAKY_CDP == type) ++ { ++ if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ rmacfg.portiso_leaky = enable; ++ ++ if ((retVal = rtl8367c_setAsicRmaCdp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (LEAKY_CSSTP == type) ++ { ++ if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ rmacfg.portiso_leaky = enable; ++ ++ if ((retVal = rtl8367c_setAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (LEAKY_LLDP == type) ++ { ++ if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ rmacfg.portiso_leaky = enable; ++ ++ if ((retVal = rtl8367c_setAsicRmaLldp(tmp, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_leaky_portIsolation_get(rtk_leaky_type_t type, rtk_enable_t *pEnable) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 port, tmp; ++ rtl8367c_rma_t rmacfg; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (type >= LEAKY_END) ++ return RT_ERR_INPUT; ++ ++ if(NULL == pEnable) ++ return RT_ERR_NULL_POINTER; ++ ++ if (type >= 0 && type <= LEAKY_UNDEF_GARP_2F) ++ { ++ if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEnable = rmacfg.portiso_leaky; ++ ++ } ++ else if (LEAKY_IPMULTICAST == type) ++ { ++ for (port = 0; port < RTK_MAX_NUM_OF_PORT; port++) ++ { ++ if ((retVal = rtl8367c_getAsicIpMulticastPortIsoLeaky(port, &tmp)) != RT_ERR_OK) ++ return retVal; ++ if (port > 0 &&(tmp != *pEnable)) ++ return RT_ERR_FAILED; ++ *pEnable = tmp; ++ } ++ } ++ else if (LEAKY_IGMP == type) ++ { ++ if ((retVal = rtl8367c_getAsicIGMPIsoLeaky(&tmp)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEnable = tmp; ++ } ++ else if (LEAKY_CDP == type) ++ { ++ if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEnable = rmacfg.portiso_leaky; ++ } ++ else if (LEAKY_CSSTP == type) ++ { ++ if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEnable = rmacfg.portiso_leaky; ++ } ++ else if (LEAKY_LLDP == type) ++ { ++ if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEnable = rmacfg.portiso_leaky; ++ } ++ ++ ++ return RT_ERR_OK; ++} +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/led.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/led.c +new file mode 100644 +index 0000000000..c00c331d8a +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/led.c +@@ -0,0 +1,792 @@ ++/* ++ * 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 LED module. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++ ++/* 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. ++ * RT_ERR_PORT_MASK - Error portmask ++ * Note: ++ * The API can be used to enable LED per port per group. ++ */ ++rtk_api_ret_t rtk_led_enable_set(rtk_led_group_t group, rtk_portmask_t *pPortmask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmask; ++ rtk_port_t port; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (group >= LED_GROUP_END) ++ return RT_ERR_INPUT; ++ ++ RTK_CHK_PORTMASK_VALID(pPortmask); ++ ++ RTK_PORTMASK_SCAN((*pPortmask), port) ++ { ++ if(rtk_switch_isCPUPort(port) == RT_ERR_OK) ++ return RT_ERR_PORT_MASK; ++ } ++ ++ if((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicLedGroupEnable(group, pmask)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_led_enable_get(rtk_led_group_t group, rtk_portmask_t *pPortmask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (group >= LED_GROUP_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_getAsicLedGroupEnable(group, &pmask)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++ ++} ++ ++/* 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, ++ */ ++rtk_api_ret_t rtk_led_operation_set(rtk_led_operation_t mode) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 regData; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ( mode >= LED_OP_END) ++ return RT_ERR_INPUT; ++ ++ switch (mode) ++ { ++ case LED_OP_PARALLEL: ++ regData = LEDOP_PARALLEL; ++ break; ++ case LED_OP_SERIAL: ++ regData = LEDOP_SERIAL; ++ break; ++ default: ++ return RT_ERR_CHIP_NOT_SUPPORTED; ++ break; ++ } ++ ++ if ((retVal = rtl8367c_setAsicLedOperationMode(regData)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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, ++ */ ++rtk_api_ret_t rtk_led_operation_get(rtk_led_operation_t *pMode) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 regData; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pMode) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicLedOperationMode(®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ if (regData == LEDOP_SERIAL) ++ *pMode = LED_OP_SERIAL; ++ else if (regData ==LEDOP_PARALLEL) ++ *pMode = LED_OP_PARALLEL; ++ else ++ return RT_ERR_FAILED; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_led_modeForce_set(rtk_port_t port, rtk_led_group_t group, rtk_led_force_mode_t mode) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ /* No LED for CPU port */ ++ if(rtk_switch_isCPUPort(port) == RT_ERR_OK) ++ return RT_ERR_PORT_ID; ++ ++ if (group >= LED_GROUP_END) ++ return RT_ERR_INPUT; ++ ++ if (mode >= LED_FORCE_END) ++ return RT_ERR_NOT_ALLOWED; ++ ++ if ((retVal = rtl8367c_setAsicForceLed(rtk_switch_port_L2P_get(port), group, mode)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_led_modeForce_get(rtk_port_t port, rtk_led_group_t group, rtk_led_force_mode_t *pMode) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ /* No LED for CPU port */ ++ if(rtk_switch_isCPUPort(port) == RT_ERR_OK) ++ return RT_ERR_PORT_ID; ++ ++ if (group >= LED_GROUP_END) ++ return RT_ERR_INPUT; ++ ++ if (NULL == pMode) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicForceLed(rtk_switch_port_L2P_get(port), group, pMode)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_led_blinkRate_set(rtk_led_blink_rate_t blinkRate) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (blinkRate >= LED_BLINKRATE_END) ++ return RT_ERR_FAILED; ++ ++ if ((retVal = rtl8367c_setAsicLedBlinkRate(blinkRate)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_led_blinkRate_get(rtk_led_blink_rate_t *pBlinkRate) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pBlinkRate) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicLedBlinkRate(pBlinkRate)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_led_groupConfig_set(rtk_led_group_t group, rtk_led_congig_t config) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (LED_GROUP_END <= group) ++ return RT_ERR_FAILED; ++ ++ if (LED_CONFIG_END <= config) ++ return RT_ERR_FAILED; ++ ++ if ((retVal = rtl8367c_setAsicLedIndicateInfoConfig(group, config)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_led_groupConfig_get(rtk_led_group_t group, rtk_led_congig_t *pConfig) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (LED_GROUP_END <= group) ++ return RT_ERR_FAILED; ++ ++ if(NULL == pConfig) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicLedIndicateInfoConfig(group, pConfig)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++ ++rtk_api_ret_t rtk_led_groupAbility_set(rtk_led_group_t group, rtk_led_ability_t *pAbility) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 regData; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (LED_GROUP_END <= group) ++ return RT_ERR_FAILED; ++ ++ if(pAbility == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ if( (pAbility->link_10m >= RTK_ENABLE_END) || (pAbility->link_100m >= RTK_ENABLE_END)|| ++ (pAbility->link_500m >= RTK_ENABLE_END) || (pAbility->link_1000m >= RTK_ENABLE_END)|| ++ (pAbility->act_rx >= RTK_ENABLE_END) || (pAbility->act_tx >= RTK_ENABLE_END) ) ++ { ++ return RT_ERR_INPUT; ++ } ++ ++ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_LED0_DATA_CTRL + (rtk_uint32)group, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ if(pAbility->link_10m == ENABLED) ++ regData |= 0x0001; ++ else ++ regData &= ~0x0001; ++ ++ if(pAbility->link_100m == ENABLED) ++ regData |= 0x0002; ++ else ++ regData &= ~0x0002; ++ ++ if(pAbility->link_500m == ENABLED) ++ regData |= 0x0004; ++ else ++ regData &= ~0x0004; ++ ++ if(pAbility->link_1000m == ENABLED) ++ regData |= 0x0008; ++ else ++ regData &= ~0x0008; ++ ++ if(pAbility->act_rx == ENABLED) ++ regData |= 0x0010; ++ else ++ regData &= ~0x0010; ++ ++ if(pAbility->act_tx == ENABLED) ++ regData |= 0x0020; ++ else ++ regData &= ~0x0020; ++ ++ regData |= (0x0001 << 6); ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_LED0_DATA_CTRL + (rtk_uint32)group, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++ ++rtk_api_ret_t rtk_led_groupAbility_get(rtk_led_group_t group, rtk_led_ability_t *pAbility) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 regData; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (LED_GROUP_END <= group) ++ return RT_ERR_FAILED; ++ ++ if(pAbility == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_LED0_DATA_CTRL + (rtk_uint32)group, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pAbility->link_10m = (regData & 0x0001) ? ENABLED : DISABLED; ++ pAbility->link_100m = (regData & 0x0002) ? ENABLED : DISABLED; ++ pAbility->link_500m = (regData & 0x0004) ? ENABLED : DISABLED; ++ pAbility->link_1000m = (regData & 0x0008) ? ENABLED : DISABLED; ++ pAbility->act_rx = (regData & 0x0010) ? ENABLED : DISABLED; ++ pAbility->act_tx = (regData & 0x0020) ? ENABLED : DISABLED; ++ ++ return RT_ERR_OK; ++} ++ ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_led_serialMode_set(rtk_led_active_t active) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ( active >= LED_ACTIVE_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicLedSerialModeConfig(active,1))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_led_serialMode_get(rtk_led_active_t *pActive) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 regData; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pActive) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicLedSerialModeConfig(pActive,®Data))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_led_OutputEnable_set(rtk_enable_t state) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (state >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicLedOutputEnable(state))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_led_OutputEnable_get(rtk_enable_t *pState) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(pState == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicLedOutputEnable(pState))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++ ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_led_serialModePortmask_set(rtk_led_serialOutput_t output, rtk_portmask_t *pPortmask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(output >= SERIAL_LED_END) ++ return RT_ERR_INPUT; ++ ++ if(pPortmask == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicLedSerialOutput((rtk_uint32)output, pmask))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_led_serialModePortmask_get(rtk_led_serialOutput_t *pOutput, rtk_portmask_t *pPortmask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(pOutput == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ if(pPortmask == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicLedSerialOutput((rtk_uint32 *)pOutput, &pmask))!=RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/mirror.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/mirror.c +new file mode 100644 +index 0000000000..1921d1a5af +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/mirror.c +@@ -0,0 +1,548 @@ ++/* ++ * 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 Mirror module. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* 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. ++ */ ++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) ++{ ++ rtk_api_ret_t retVal; ++ rtk_enable_t mirRx, mirTx; ++ rtk_uint32 i, pmask; ++ rtk_port_t source_port; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check port valid */ ++ RTK_CHK_PORT_VALID(mirroring_port); ++ ++ if(NULL == pMirrored_rx_portmask) ++ return RT_ERR_NULL_POINTER; ++ ++ if(NULL == pMirrored_tx_portmask) ++ return RT_ERR_NULL_POINTER; ++ ++ RTK_CHK_PORTMASK_VALID(pMirrored_rx_portmask); ++ ++ RTK_CHK_PORTMASK_VALID(pMirrored_tx_portmask); ++ ++ /*Mirror Sorce Port Mask Check*/ ++ if (pMirrored_tx_portmask->bits[0]!=pMirrored_rx_portmask->bits[0]&&pMirrored_tx_portmask->bits[0]!=0&&pMirrored_rx_portmask->bits[0]!=0) ++ return RT_ERR_PORT_MASK; ++ ++ /*mirror port != source port*/ ++ if(RTK_PORTMASK_IS_PORT_SET((*pMirrored_tx_portmask), mirroring_port) || RTK_PORTMASK_IS_PORT_SET((*pMirrored_rx_portmask), mirroring_port)) ++ return RT_ERR_PORT_MASK; ++ ++ source_port = rtk_switch_maxLogicalPort_get(); ++ ++ RTK_SCAN_ALL_LOG_PORT(i) ++ { ++ if (pMirrored_tx_portmask->bits[0]&(1<bits[0]&(1<bits[0] != 0) ++ { ++ if ((retVal = rtk_switch_portmask_L2P_get(pMirrored_rx_portmask, &pmask)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicPortMirrorMask(pmask)) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ if ((retVal = rtk_switch_portmask_L2P_get(pMirrored_tx_portmask, &pmask)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicPortMirrorMask(pmask)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ ++ if (pMirrored_rx_portmask->bits[0]) ++ mirRx = ENABLED; ++ else ++ mirRx = DISABLED; ++ ++ if ((retVal = rtl8367c_setAsicPortMirrorRxFunction(mirRx)) != RT_ERR_OK) ++ return retVal; ++ ++ if (pMirrored_tx_portmask->bits[0]) ++ mirTx = ENABLED; ++ else ++ mirTx = DISABLED; ++ ++ if ((retVal = rtl8367c_setAsicPortMirrorTxFunction(mirTx)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++ ++} ++ ++/* 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. ++ */ ++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) ++{ ++ rtk_api_ret_t retVal; ++ rtk_port_t source_port; ++ rtk_enable_t mirRx, mirTx; ++ rtk_uint32 sport, mport, pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pMirrored_rx_portmask) ++ return RT_ERR_NULL_POINTER; ++ ++ if(NULL == pMirrored_tx_portmask) ++ return RT_ERR_NULL_POINTER; ++ ++ if(NULL == pMirroring_port) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicPortMirror(&sport, &mport)) != RT_ERR_OK) ++ return retVal; ++ source_port = rtk_switch_port_P2L_get(sport); ++ *pMirroring_port = rtk_switch_port_P2L_get(mport); ++ ++ if ((retVal = rtl8367c_getAsicPortMirrorRxFunction((rtk_uint32*)&mirRx)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicPortMirrorTxFunction((rtk_uint32*)&mirTx)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicPortMirrorMask(&pmask)) != RT_ERR_OK) ++ return retVal; ++ ++ if (DISABLED == mirRx) ++ pMirrored_rx_portmask->bits[0]=0; ++ else ++ { ++ if ((retVal = rtk_switch_portmask_P2L_get(pmask, pMirrored_rx_portmask)) != RT_ERR_OK) ++ return retVal; ++ pMirrored_rx_portmask->bits[0] |= 1<bits[0]=0; ++ else ++ { ++ if ((retVal = rtk_switch_portmask_P2L_get(pmask, pMirrored_tx_portmask)) != RT_ERR_OK) ++ return retVal; ++ pMirrored_tx_portmask->bits[0] |= 1<= RTK_ENABLE_END) ++ return RT_ERR_ENABLE; ++ ++ if ((retVal = rtl8367c_setAsicPortMirrorIsolation(enable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_mirror_portIso_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_getAsicPortMirrorIsolation(pEnable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_mirror_vlanLeaky_set(rtk_enable_t txenable, rtk_enable_t rxenable) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ((txenable >= RTK_ENABLE_END) ||(rxenable >= RTK_ENABLE_END)) ++ return RT_ERR_ENABLE; ++ ++ if ((retVal = rtl8367c_setAsicPortMirrorVlanTxLeaky(txenable)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicPortMirrorVlanRxLeaky(rxenable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_mirror_vlanLeaky_get(rtk_enable_t *pTxenable, rtk_enable_t *pRxenable) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if( (NULL == pTxenable) || (NULL == pRxenable) ) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicPortMirrorVlanTxLeaky(pTxenable)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicPortMirrorVlanRxLeaky(pRxenable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_mirror_isolationLeaky_set(rtk_enable_t txenable, rtk_enable_t rxenable) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ((txenable >= RTK_ENABLE_END) ||(rxenable >= RTK_ENABLE_END)) ++ return RT_ERR_ENABLE; ++ ++ if ((retVal = rtl8367c_setAsicPortMirrorIsolationTxLeaky(txenable)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicPortMirrorIsolationRxLeaky(rxenable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_mirror_isolationLeaky_get(rtk_enable_t *pTxenable, rtk_enable_t *pRxenable) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if( (NULL == pTxenable) || (NULL == pRxenable) ) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicPortMirrorIsolationTxLeaky(pTxenable)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicPortMirrorIsolationRxLeaky(pRxenable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_mirror_keep_set(rtk_mirror_keep_t mode) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (mode >= MIRROR_KEEP_END) ++ return RT_ERR_ENABLE; ++ ++ if ((retVal = rtl8367c_setAsicPortMirrorRealKeep(mode)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_mirror_keep_get(rtk_mirror_keep_t *pMode) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pMode) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicPortMirrorRealKeep(pMode)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_mirror_override_set(rtk_enable_t rxMirror, rtk_enable_t txMirror, rtk_enable_t aclMirror) ++{ ++ rtk_api_ret_t retVal; ++ ++ if( (rxMirror >= RTK_ENABLE_END) || (txMirror >= RTK_ENABLE_END) || (aclMirror >= RTK_ENABLE_END)) ++ return RT_ERR_ENABLE; ++ ++ if ((retVal = rtl8367c_setAsicPortMirrorOverride((rtk_uint32)rxMirror, (rtk_uint32)txMirror, (rtk_uint32)aclMirror)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_mirror_override_get(rtk_enable_t *pRxMirror, rtk_enable_t *pTxMirror, rtk_enable_t *pAclMirror) ++{ ++ rtk_api_ret_t retVal; ++ ++ if( (pRxMirror == NULL) || (pTxMirror == NULL) || (pAclMirror == NULL)) ++ return RT_ERR_ENABLE; ++ ++ if ((retVal = rtl8367c_getAsicPortMirrorOverride((rtk_uint32 *)pRxMirror, (rtk_uint32 *)pTxMirror, (rtk_uint32 *)pAclMirror)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/oam.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/oam.c +new file mode 100644 +index 0000000000..dc1559ae3e +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/oam.c +@@ -0,0 +1,245 @@ ++/* ++ * 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 OAM(802.3ah) module. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++ ++/* Module Name : OAM */ ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_oam_init(void) ++{ ++ return RT_ERR_OK; ++} /* end of rtk_oam_init */ ++ ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_oam_state_set(rtk_enable_t enabled) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (enabled >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicOamEnable(enabled))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_oam_state_get(rtk_enable_t *pEnabled) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ((retVal = rtl8367c_getAsicOamEnable(pEnabled))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++ ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_oam_parserAction_set(rtk_port_t port, rtk_oam_parser_act_t action) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if (action >= OAM_PARSER_ACTION_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicOamParser(rtk_switch_port_L2P_get(port), action))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_oam_parserAction_get(rtk_port_t port, rtk_oam_parser_act_t *pAction) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if ((retVal = rtl8367c_getAsicOamParser(rtk_switch_port_L2P_get(port), pAction))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_oam_multiplexerAction_set(rtk_port_t port, rtk_oam_multiplexer_act_t action) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if (action >= OAM_MULTIPLEXER_ACTION_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicOamMultiplexer(rtk_switch_port_L2P_get(port), action))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_oam_parserAction_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 ++ */ ++rtk_api_ret_t rtk_oam_multiplexerAction_get(rtk_port_t port, rtk_oam_multiplexer_act_t *pAction) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if ((retVal = rtl8367c_getAsicOamMultiplexer(rtk_switch_port_L2P_get(port), pAction))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/port.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/port.c +new file mode 100644 +index 0000000000..9f99d1b3dc +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/port.c +@@ -0,0 +1,2467 @@ ++/* ++ * 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 Port module. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#define FIBER_INIT_SIZE 1507 ++CONST_T rtk_uint8 Fiber[FIBER_INIT_SIZE] = { ++0x02,0x04,0x41,0xE4,0xF5,0xA8,0xD2,0xAF, ++0x22,0x00,0x00,0x02,0x05,0x2D,0xE4,0x90, ++0x06,0x2A,0xF0,0xFD,0x7C,0x01,0x7F,0x3F, ++0x7E,0x1D,0x12,0x05,0xAF,0x7D,0x40,0x12, ++0x02,0x5F,0xE4,0xFF,0xFE,0xFD,0x80,0x08, ++0x12,0x05,0x9E,0x50,0x0C,0x12,0x05,0x8B, ++0xFC,0x90,0x06,0x24,0x12,0x03,0x76,0x80, ++0xEF,0xE4,0xF5,0xA8,0xD2,0xAF,0x7D,0x1F, ++0xFC,0x7F,0x49,0x7E,0x13,0x12,0x05,0xAF, ++0x12,0x05,0xD6,0x7D,0xD7,0x12,0x02,0x1E, ++0x7D,0x80,0x12,0x01,0xCA,0x7D,0x94,0x7C, ++0xF9,0x12,0x02,0x3B,0x7D,0x81,0x12,0x01, ++0xCA,0x7D,0xA2,0x7C,0x31,0x12,0x02,0x3B, ++0x7D,0x82,0x12,0x01,0xDF,0x7D,0x60,0x7C, ++0x69,0x12,0x02,0x43,0x7D,0x83,0x12,0x01, ++0xDF,0x7D,0x28,0x7C,0x97,0x12,0x02,0x43, ++0x7D,0x84,0x12,0x01,0xF4,0x7D,0x85,0x7C, ++0x9D,0x12,0x02,0x57,0x7D,0x23,0x12,0x01, ++0xF4,0x7D,0x10,0x7C,0xD8,0x12,0x02,0x57, ++0x7D,0x24,0x7C,0x04,0x12,0x02,0x28,0x7D, ++0x00,0x12,0x02,0x1E,0x7D,0x2F,0x12,0x02, ++0x09,0x7D,0x20,0x7C,0x0F,0x7F,0x02,0x7E, ++0x66,0x12,0x05,0xAF,0x7D,0x01,0x12,0x02, ++0x09,0x7D,0x04,0x7C,0x00,0x7F,0x01,0x7E, ++0x66,0x12,0x05,0xAF,0x7D,0x80,0x7C,0x00, ++0x7F,0x00,0x7E,0x66,0x12,0x05,0xAF,0x7F, ++0x02,0x7E,0x66,0x12,0x02,0x4B,0x44,0x02, ++0xFF,0x90,0x06,0x28,0xEE,0xF0,0xA3,0xEF, ++0xF0,0x44,0x04,0xFF,0x90,0x06,0x28,0xEE, ++0xF0,0xFC,0xA3,0xEF,0xF0,0xFD,0x7F,0x02, ++0x7E,0x66,0x12,0x05,0xAF,0x7D,0x04,0x7C, ++0x00,0x12,0x02,0x28,0x7D,0xB9,0x7C,0x15, ++0x7F,0xEB,0x7E,0x13,0x12,0x05,0xAF,0x7D, ++0x07,0x7C,0x00,0x7F,0xE7,0x7E,0x13,0x12, ++0x05,0xAF,0x7D,0x40,0x7C,0x11,0x7F,0x00, ++0x7E,0x62,0x12,0x05,0xAF,0x12,0x03,0x82, ++0x7D,0x41,0x12,0x02,0x5F,0xE4,0xFF,0xFE, ++0xFD,0x80,0x08,0x12,0x05,0x9E,0x50,0x0C, ++0x12,0x05,0x8B,0xFC,0x90,0x06,0x24,0x12, ++0x03,0x76,0x80,0xEF,0xC2,0x00,0xC2,0x01, ++0xD2,0xA9,0xD2,0x8C,0x7F,0x01,0x7E,0x62, ++0x12,0x02,0x4B,0x30,0xE2,0x05,0xE4,0xA3, ++0xF0,0x80,0xF1,0x90,0x06,0x2A,0xE0,0x70, ++0x12,0x12,0x01,0x89,0x90,0x06,0x2A,0x74, ++0x01,0xF0,0xE4,0x90,0x06,0x2D,0xF0,0xA3, ++0xF0,0x80,0xD9,0xC3,0x90,0x06,0x2E,0xE0, ++0x94,0x64,0x90,0x06,0x2D,0xE0,0x94,0x00, ++0x40,0xCA,0xE4,0xF0,0xA3,0xF0,0x12,0x01, ++0x89,0x90,0x06,0x2A,0x74,0x01,0xF0,0x80, ++0xBB,0x7D,0x04,0xFC,0x7F,0x02,0x7E,0x66, ++0x12,0x05,0xAF,0x7D,0x00,0x7C,0x04,0x7F, ++0x01,0x7E,0x66,0x12,0x05,0xAF,0x7D,0xC0, ++0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,0x05, ++0xAF,0xE4,0xFD,0xFC,0x7F,0x02,0x7E,0x66, ++0x12,0x05,0xAF,0x7D,0x00,0x7C,0x04,0x7F, ++0x01,0x7E,0x66,0x12,0x05,0xAF,0x7D,0xC0, ++0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,0x05, ++0xAF,0x22,0x7C,0x04,0x7F,0x01,0x7E,0x66, ++0x12,0x05,0xAF,0x7D,0xC0,0x7C,0x00,0x7F, ++0x00,0x7E,0x66,0x12,0x05,0xAF,0x22,0x7C, ++0x04,0x7F,0x01,0x7E,0x66,0x12,0x05,0xAF, ++0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66, ++0x12,0x05,0xAF,0x22,0x7C,0x04,0x7F,0x01, ++0x7E,0x66,0x12,0x05,0xAF,0x7D,0xC0,0x7C, ++0x00,0x7F,0x00,0x7E,0x66,0x12,0x05,0xAF, ++0x22,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, ++0x05,0xAF,0x7D,0xC0,0x7C,0x00,0x7F,0x00, ++0x7E,0x66,0x12,0x05,0xAF,0x22,0x7C,0x04, ++0x7F,0x02,0x7E,0x66,0x12,0x05,0xAF,0x22, ++0x7F,0x01,0x7E,0x66,0x12,0x05,0xAF,0x7D, ++0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, ++0x05,0xAF,0x22,0x7F,0x02,0x7E,0x66,0x12, ++0x05,0xAF,0x22,0x7F,0x02,0x7E,0x66,0x12, ++0x05,0xAF,0x22,0x12,0x05,0x67,0x90,0x06, ++0x28,0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0x7F, ++0x02,0x7E,0x66,0x12,0x05,0xAF,0x22,0x7C, ++0x00,0x7F,0x36,0x7E,0x13,0x12,0x05,0xAF, ++0x22,0xC5,0xF0,0xF8,0xA3,0xE0,0x28,0xF0, ++0xC5,0xF0,0xF8,0xE5,0x82,0x15,0x82,0x70, ++0x02,0x15,0x83,0xE0,0x38,0xF0,0x22,0x75, ++0xF0,0x08,0x75,0x82,0x00,0xEF,0x2F,0xFF, ++0xEE,0x33,0xFE,0xCD,0x33,0xCD,0xCC,0x33, ++0xCC,0xC5,0x82,0x33,0xC5,0x82,0x9B,0xED, ++0x9A,0xEC,0x99,0xE5,0x82,0x98,0x40,0x0C, ++0xF5,0x82,0xEE,0x9B,0xFE,0xED,0x9A,0xFD, ++0xEC,0x99,0xFC,0x0F,0xD5,0xF0,0xD6,0xE4, ++0xCE,0xFB,0xE4,0xCD,0xFA,0xE4,0xCC,0xF9, ++0xA8,0x82,0x22,0xB8,0x00,0xC1,0xB9,0x00, ++0x59,0xBA,0x00,0x2D,0xEC,0x8B,0xF0,0x84, ++0xCF,0xCE,0xCD,0xFC,0xE5,0xF0,0xCB,0xF9, ++0x78,0x18,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, ++0xED,0x33,0xFD,0xEC,0x33,0xFC,0xEB,0x33, ++0xFB,0x10,0xD7,0x03,0x99,0x40,0x04,0xEB, ++0x99,0xFB,0x0F,0xD8,0xE5,0xE4,0xF9,0xFA, ++0x22,0x78,0x18,0xEF,0x2F,0xFF,0xEE,0x33, ++0xFE,0xED,0x33,0xFD,0xEC,0x33,0xFC,0xC9, ++0x33,0xC9,0x10,0xD7,0x05,0x9B,0xE9,0x9A, ++0x40,0x07,0xEC,0x9B,0xFC,0xE9,0x9A,0xF9, ++0x0F,0xD8,0xE0,0xE4,0xC9,0xFA,0xE4,0xCC, ++0xFB,0x22,0x75,0xF0,0x10,0xEF,0x2F,0xFF, ++0xEE,0x33,0xFE,0xED,0x33,0xFD,0xCC,0x33, ++0xCC,0xC8,0x33,0xC8,0x10,0xD7,0x07,0x9B, ++0xEC,0x9A,0xE8,0x99,0x40,0x0A,0xED,0x9B, ++0xFD,0xEC,0x9A,0xFC,0xE8,0x99,0xF8,0x0F, ++0xD5,0xF0,0xDA,0xE4,0xCD,0xFB,0xE4,0xCC, ++0xFA,0xE4,0xC8,0xF9,0x22,0xEB,0x9F,0xF5, ++0xF0,0xEA,0x9E,0x42,0xF0,0xE9,0x9D,0x42, ++0xF0,0xE8,0x9C,0x45,0xF0,0x22,0xE0,0xFC, ++0xA3,0xE0,0xFD,0xA3,0xE0,0xFE,0xA3,0xE0, ++0xFF,0x22,0xE0,0xF8,0xA3,0xE0,0xF9,0xA3, ++0xE0,0xFA,0xA3,0xE0,0xFB,0x22,0xEC,0xF0, ++0xA3,0xED,0xF0,0xA3,0xEE,0xF0,0xA3,0xEF, ++0xF0,0x22,0x12,0x03,0xF8,0x12,0x04,0x1A, ++0x44,0x40,0x12,0x04,0x0F,0x7D,0x03,0x7C, ++0x00,0x12,0x04,0x23,0x12,0x05,0xAF,0x12, ++0x03,0xF8,0x12,0x04,0x1A,0x54,0xBF,0x12, ++0x04,0x0F,0x7D,0x03,0x7C,0x00,0x12,0x03, ++0xD0,0x7F,0x02,0x7E,0x66,0x12,0x05,0x67, ++0xEF,0x54,0xFD,0x54,0xFE,0x12,0x04,0x33, ++0x12,0x03,0xD0,0x7F,0x02,0x7E,0x66,0x12, ++0x05,0x67,0xEF,0x44,0x02,0x44,0x01,0x12, ++0x04,0x33,0x12,0x04,0x23,0x02,0x05,0xAF, ++0x7F,0x01,0x7E,0x66,0x12,0x05,0xAF,0x7D, ++0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, ++0x05,0xAF,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, ++0x66,0x12,0x05,0xAF,0x7D,0x80,0x7C,0x00, ++0x7F,0x00,0x7E,0x66,0x12,0x05,0xAF,0x22, ++0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66, ++0x12,0x05,0xAF,0x7D,0x80,0x7C,0x00,0x7F, ++0x00,0x7E,0x66,0x12,0x05,0xAF,0x22,0xFD, ++0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x05, ++0xAF,0x22,0x7F,0x02,0x7E,0x66,0x12,0x05, ++0x67,0xEF,0x22,0x7F,0x01,0x7E,0x66,0x12, ++0x05,0xAF,0x7D,0xC0,0x7C,0x00,0x7F,0x00, ++0x7E,0x66,0x22,0xFD,0xAC,0x06,0x7F,0x02, ++0x7E,0x66,0x12,0x05,0xAF,0xE4,0xFD,0xFC, ++0x22,0x78,0x7F,0xE4,0xF6,0xD8,0xFD,0x75, ++0x81,0x3C,0x02,0x04,0x88,0x02,0x00,0x0E, ++0xE4,0x93,0xA3,0xF8,0xE4,0x93,0xA3,0x40, ++0x03,0xF6,0x80,0x01,0xF2,0x08,0xDF,0xF4, ++0x80,0x29,0xE4,0x93,0xA3,0xF8,0x54,0x07, ++0x24,0x0C,0xC8,0xC3,0x33,0xC4,0x54,0x0F, ++0x44,0x20,0xC8,0x83,0x40,0x04,0xF4,0x56, ++0x80,0x01,0x46,0xF6,0xDF,0xE4,0x80,0x0B, ++0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80, ++0x90,0x05,0xCB,0xE4,0x7E,0x01,0x93,0x60, ++0xBC,0xA3,0xFF,0x54,0x3F,0x30,0xE5,0x09, ++0x54,0x1F,0xFE,0xE4,0x93,0xA3,0x60,0x01, ++0x0E,0xCF,0x54,0xC0,0x25,0xE0,0x60,0xA8, ++0x40,0xB8,0xE4,0x93,0xA3,0xFA,0xE4,0x93, ++0xA3,0xF8,0xE4,0x93,0xA3,0xC8,0xC5,0x82, ++0xC8,0xCA,0xC5,0x83,0xCA,0xF0,0xA3,0xC8, ++0xC5,0x82,0xC8,0xCA,0xC5,0x83,0xCA,0xDF, ++0xE9,0xDE,0xE7,0x80,0xBE,0x75,0x0F,0x80, ++0x75,0x0E,0x7E,0x75,0x0D,0xAA,0x75,0x0C, ++0x83,0xE4,0xF5,0x10,0x75,0x0B,0xA0,0x75, ++0x0A,0xAC,0x75,0x09,0xB9,0x75,0x08,0x03, ++0x75,0x89,0x11,0x7B,0x60,0x7A,0x09,0xF9, ++0xF8,0xAF,0x0B,0xAE,0x0A,0xAD,0x09,0xAC, ++0x08,0x12,0x02,0xBB,0xAD,0x07,0xAC,0x06, ++0xC3,0xE4,0x9D,0xFD,0xE4,0x9C,0xFC,0x78, ++0x17,0xF6,0xAF,0x05,0xEF,0x08,0xF6,0x18, ++0xE6,0xF5,0x8C,0x08,0xE6,0xF5,0x8A,0x74, ++0x0D,0x2D,0xFD,0xE4,0x3C,0x18,0xF6,0xAF, ++0x05,0xEF,0x08,0xF6,0x75,0x88,0x10,0x53, ++0x8E,0xC7,0xD2,0xA9,0x22,0xC0,0xE0,0xC0, ++0xF0,0xC0,0x83,0xC0,0x82,0xC0,0xD0,0x75, ++0xD0,0x00,0xC0,0x00,0x78,0x17,0xE6,0xF5, ++0x8C,0x78,0x18,0xE6,0xF5,0x8A,0x90,0x06, ++0x2B,0xE4,0x75,0xF0,0x01,0x12,0x02,0x69, ++0x90,0x06,0x2D,0xE4,0x75,0xF0,0x01,0x12, ++0x02,0x69,0xD0,0x00,0xD0,0xD0,0xD0,0x82, ++0xD0,0x83,0xD0,0xF0,0xD0,0xE0,0x32,0xC2, ++0xAF,0xAD,0x07,0xAC,0x06,0x8C,0xA2,0x8D, ++0xA3,0x75,0xA0,0x01,0x00,0x00,0x00,0x00, ++0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAE, ++0xA1,0xBE,0x00,0xF0,0xAE,0xA6,0xAF,0xA7, ++0xD2,0xAF,0x22,0x90,0x06,0x24,0x12,0x03, ++0x5E,0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE, ++0xE4,0x3D,0xFD,0xE4,0x3C,0x22,0xE4,0x7F, ++0x20,0x7E,0x4E,0xFD,0xFC,0x90,0x06,0x24, ++0x12,0x03,0x6A,0xC3,0x02,0x03,0x4D,0xC2, ++0xAF,0xAB,0x07,0xAA,0x06,0x8A,0xA2,0x8B, ++0xA3,0x8C,0xA4,0x8D,0xA5,0x75,0xA0,0x03, ++0x00,0x00,0x00,0xAA,0xA1,0xBA,0x00,0xF8, ++0xD2,0xAF,0x22,0x42,0x06,0x2D,0x00,0x00, ++0x42,0x06,0x2B,0x00,0x00,0x00,0x12,0x05, ++0xDF,0x12,0x04,0xCD,0x02,0x00,0x03,0xE4, ++0xF5,0x8E,0x22}; ++ ++static rtk_api_ret_t _rtk_port_FiberModeAbility_set(rtk_port_t port, rtk_port_phy_ability_t *pAbility) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 regData; ++ ++ /* Check Combo port or not */ ++ RTK_CHK_PORT_IS_COMBO(port); ++ ++ /* Flow Control */ ++ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_FIB0_CFG04, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ if (pAbility->AsyFC == 1) ++ regData |= (0x0001 << 8); ++ else ++ regData &= ~(0x0001 << 8); ++ ++ if (pAbility->FC == 1) ++ regData |= (0x0001 << 7); ++ else ++ regData &= ~(0x0001 << 7); ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG04, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ /* Speed ability */ ++ if( (pAbility->Full_1000 == 1) && (pAbility->Full_100 == 1) && (pAbility->AutoNegotiation == 1) ) ++ { ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_MODE_OFFSET, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_MODE_MASK, 7)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG00, 0x1140)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if(pAbility->Full_1000 == 1) ++ { ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_MODE_OFFSET, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_MODE_MASK, 4)) != RT_ERR_OK) ++ return retVal; ++ ++ if(pAbility->AutoNegotiation == 1) ++ { ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG00, 0x1140)) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG00, 0x0140)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ else if(pAbility->Full_100 == 1) ++ { ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_MODE_OFFSET, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_MODE_MASK, 5)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_FIB0_CFG00, 0x2100)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ /* Digital software reset */ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0003)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x0080)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SDS_INDACS_DATA, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ regData |= (0x0001 << 6); ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0003)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) ++ return retVal; ++ ++ regData &= ~(0x0001 << 6); ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0003)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) ++ return retVal; ++ ++ /* CDR reset */ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x1401))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0000))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x1403))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0000))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++static rtk_api_ret_t _rtk_port_FiberModeAbility_get(rtk_port_t port, rtk_port_phy_ability_t *pAbility) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 data, regData; ++ ++ /* Check Combo port or not */ ++ RTK_CHK_PORT_IS_COMBO(port); ++ ++ memset(pAbility, 0x00, sizeof(rtk_port_phy_ability_t)); ++ ++ /* Flow Control */ ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_REG4_OFFSET, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_REG4_FIB100_OFFSET, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0044)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x0080)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SDS_INDACS_DATA, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ if(regData & (0x0001 << 8)) ++ pAbility->AsyFC = 1; ++ ++ if(regData & (0x0001 << 7)) ++ pAbility->FC = 1; ++ ++ /* Speed ability */ ++ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_FRC_MODE_OFFSET, &data)) != RT_ERR_OK) ++ return retVal; ++ ++ if(data == 0) ++ { ++ pAbility->AutoNegotiation = 1; ++ pAbility->Full_1000 = 1; ++ pAbility->Full_100 = 1; ++ } ++ else ++ { ++ if ((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FIBER_CFG_1, RTL8367C_SDS_MODE_MASK, &data)) != RT_ERR_OK) ++ return retVal; ++ ++ if(data == 4) ++ { ++ pAbility->Full_1000 = 1; ++ ++ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_FIB0_CFG00, &data)) != RT_ERR_OK) ++ return retVal; ++ ++ if(data & 0x1000) ++ pAbility->AutoNegotiation = 1; ++ else ++ pAbility->AutoNegotiation = 0; ++ } ++ else if(data == 5) ++ pAbility->Full_100 = 1; ++ else ++ return RT_ERR_FAILED; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_port_phyAutoNegoAbility_set(rtk_port_t port, rtk_port_phy_ability_t *pAbility) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 phyData; ++ rtk_uint32 phyEnMsk0; ++ rtk_uint32 phyEnMsk4; ++ rtk_uint32 phyEnMsk9; ++ rtk_port_media_t media_type; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_IS_UTP(port); ++ ++ if(NULL == pAbility) ++ return RT_ERR_NULL_POINTER; ++ ++ if (pAbility->Half_10 >= RTK_ENABLE_END || pAbility->Full_10 >= RTK_ENABLE_END || ++ pAbility->Half_100 >= RTK_ENABLE_END || pAbility->Full_100 >= RTK_ENABLE_END || ++ pAbility->Full_1000 >= RTK_ENABLE_END || pAbility->AutoNegotiation >= RTK_ENABLE_END || ++ pAbility->AsyFC >= RTK_ENABLE_END || pAbility->FC >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if (rtk_switch_isComboPort(port) == RT_ERR_OK) ++ { ++ if ((retVal = rtk_port_phyComboPortMedia_get(port, &media_type)) != RT_ERR_OK) ++ return retVal; ++ ++ if(media_type == PORT_MEDIA_FIBER) ++ { ++ return _rtk_port_FiberModeAbility_set(port, pAbility); ++ } ++ } ++ ++ /*for PHY auto mode setup*/ ++ pAbility->AutoNegotiation = 1; ++ ++ phyEnMsk0 = 0; ++ phyEnMsk4 = 0; ++ phyEnMsk9 = 0; ++ ++ if (1 == pAbility->Half_10) ++ { ++ /*10BASE-TX half duplex capable in reg 4.5*/ ++ phyEnMsk4 = phyEnMsk4 | (1 << 5); ++ ++ /*Speed selection [1:0] */ ++ /* 11=Reserved*/ ++ /* 10= 1000Mpbs*/ ++ /* 01= 100Mpbs*/ ++ /* 00= 10Mpbs*/ ++ phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); ++ phyEnMsk0 = phyEnMsk0 & (~(1 << 13)); ++ } ++ ++ if (1 == pAbility->Full_10) ++ { ++ /*10BASE-TX full duplex capable in reg 4.6*/ ++ phyEnMsk4 = phyEnMsk4 | (1 << 6); ++ /*Speed selection [1:0] */ ++ /* 11=Reserved*/ ++ /* 10= 1000Mpbs*/ ++ /* 01= 100Mpbs*/ ++ /* 00= 10Mpbs*/ ++ phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); ++ phyEnMsk0 = phyEnMsk0 & (~(1 << 13)); ++ ++ /*Full duplex mode in reg 0.8*/ ++ phyEnMsk0 = phyEnMsk0 | (1 << 8); ++ ++ } ++ ++ if (1 == pAbility->Half_100) ++ { ++ /*100BASE-TX half duplex capable in reg 4.7*/ ++ phyEnMsk4 = phyEnMsk4 | (1 << 7); ++ /*Speed selection [1:0] */ ++ /* 11=Reserved*/ ++ /* 10= 1000Mpbs*/ ++ /* 01= 100Mpbs*/ ++ /* 00= 10Mpbs*/ ++ phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); ++ phyEnMsk0 = phyEnMsk0 | (1 << 13); ++ } ++ ++ ++ if (1 == pAbility->Full_100) ++ { ++ /*100BASE-TX full duplex capable in reg 4.8*/ ++ phyEnMsk4 = phyEnMsk4 | (1 << 8); ++ /*Speed selection [1:0] */ ++ /* 11=Reserved*/ ++ /* 10= 1000Mpbs*/ ++ /* 01= 100Mpbs*/ ++ /* 00= 10Mpbs*/ ++ phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); ++ phyEnMsk0 = phyEnMsk0 | (1 << 13); ++ /*Full duplex mode in reg 0.8*/ ++ phyEnMsk0 = phyEnMsk0 | (1 << 8); ++ } ++ ++ ++ if (1 == pAbility->Full_1000) ++ { ++ /*1000 BASE-T FULL duplex capable setting in reg 9.9*/ ++ phyEnMsk9 = phyEnMsk9 | (1 << 9); ++ ++ /*Speed selection [1:0] */ ++ /* 11=Reserved*/ ++ /* 10= 1000Mpbs*/ ++ /* 01= 100Mpbs*/ ++ /* 00= 10Mpbs*/ ++ phyEnMsk0 = phyEnMsk0 | (1 << 6); ++ phyEnMsk0 = phyEnMsk0 & (~(1 << 13)); ++ ++ ++ /*Auto-Negotiation setting in reg 0.12*/ ++ phyEnMsk0 = phyEnMsk0 | (1 << 12); ++ ++ } ++ ++ if (1 == pAbility->AutoNegotiation) ++ { ++ /*Auto-Negotiation setting in reg 0.12*/ ++ phyEnMsk0 = phyEnMsk0 | (1 << 12); ++ } ++ ++ if (1 == pAbility->AsyFC) ++ { ++ /*Asymetric flow control in reg 4.11*/ ++ phyEnMsk4 = phyEnMsk4 | (1 << 11); ++ } ++ if (1 == pAbility->FC) ++ { ++ /*Flow control in reg 4.10*/ ++ phyEnMsk4 = phyEnMsk4 | (1 << 10); ++ } ++ ++ /*1000 BASE-T control register setting*/ ++ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, &phyData)) != RT_ERR_OK) ++ return retVal; ++ ++ phyData = (phyData & (~0x0200)) | phyEnMsk9 ; ++ ++ if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, phyData)) != RT_ERR_OK) ++ return retVal; ++ ++ /*Auto-Negotiation control register setting*/ ++ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, &phyData)) != RT_ERR_OK) ++ return retVal; ++ ++ phyData = (phyData & (~0x0DE0)) | phyEnMsk4; ++ if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, phyData)) != RT_ERR_OK) ++ return retVal; ++ ++ /*Control register setting and restart auto*/ ++ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, &phyData)) != RT_ERR_OK) ++ return retVal; ++ ++ phyData = (phyData & (~0x3140)) | phyEnMsk0; ++ /*If have auto-negotiation capable, then restart auto negotiation*/ ++ if (1 == pAbility->AutoNegotiation) ++ { ++ phyData = phyData | (1 << 9); ++ } ++ ++ if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, phyData)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_port_phyAutoNegoAbility_get(rtk_port_t port, rtk_port_phy_ability_t *pAbility) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 phyData0; ++ rtk_uint32 phyData4; ++ rtk_uint32 phyData9; ++ rtk_port_media_t media_type; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_IS_UTP(port); ++ ++ if(NULL == pAbility) ++ return RT_ERR_NULL_POINTER; ++ ++ if (rtk_switch_isComboPort(port) == RT_ERR_OK) ++ { ++ if ((retVal = rtk_port_phyComboPortMedia_get(port, &media_type)) != RT_ERR_OK) ++ return retVal; ++ ++ if(media_type == PORT_MEDIA_FIBER) ++ { ++ return _rtk_port_FiberModeAbility_get(port, pAbility); ++ } ++ } ++ ++ /*Control register setting and restart auto*/ ++ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, &phyData0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*Auto-Negotiation control register setting*/ ++ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, &phyData4)) != RT_ERR_OK) ++ return retVal; ++ ++ /*1000 BASE-T control register setting*/ ++ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, &phyData9)) != RT_ERR_OK) ++ return retVal; ++ ++ if (phyData9 & (1 << 9)) ++ pAbility->Full_1000 = 1; ++ else ++ pAbility->Full_1000 = 0; ++ ++ if (phyData4 & (1 << 11)) ++ pAbility->AsyFC = 1; ++ else ++ pAbility->AsyFC = 0; ++ ++ if (phyData4 & (1 << 10)) ++ pAbility->FC = 1; ++ else ++ pAbility->FC = 0; ++ ++ ++ if (phyData4 & (1 << 8)) ++ pAbility->Full_100 = 1; ++ else ++ pAbility->Full_100 = 0; ++ ++ if (phyData4 & (1 << 7)) ++ pAbility->Half_100 = 1; ++ else ++ pAbility->Half_100 = 0; ++ ++ if (phyData4 & (1 << 6)) ++ pAbility->Full_10 = 1; ++ else ++ pAbility->Full_10 = 0; ++ ++ if (phyData4 & (1 << 5)) ++ pAbility->Half_10 = 1; ++ else ++ pAbility->Half_10 = 0; ++ ++ ++ if (phyData0 & (1 << 12)) ++ pAbility->AutoNegotiation = 1; ++ else ++ pAbility->AutoNegotiation = 0; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ * This API can be used to configure combo port in fiber mode. ++ * The possible parameters in fiber mode are Full_1000 and Full 100. ++ * All the other fields in rtk_port_phy_ability_t will be ignored in fiber port. ++ */ ++rtk_api_ret_t rtk_port_phyForceModeAbility_set(rtk_port_t port, rtk_port_phy_ability_t *pAbility) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 phyData; ++ rtk_uint32 phyEnMsk0; ++ rtk_uint32 phyEnMsk4; ++ rtk_uint32 phyEnMsk9; ++ rtk_port_media_t media_type; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_IS_UTP(port); ++ ++ if(NULL == pAbility) ++ return RT_ERR_NULL_POINTER; ++ ++ if (pAbility->Half_10 >= RTK_ENABLE_END || pAbility->Full_10 >= RTK_ENABLE_END || ++ pAbility->Half_100 >= RTK_ENABLE_END || pAbility->Full_100 >= RTK_ENABLE_END || ++ pAbility->Full_1000 >= RTK_ENABLE_END || pAbility->AutoNegotiation >= RTK_ENABLE_END || ++ pAbility->AsyFC >= RTK_ENABLE_END || pAbility->FC >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if (rtk_switch_isComboPort(port) == RT_ERR_OK) ++ { ++ if ((retVal = rtk_port_phyComboPortMedia_get(port, &media_type)) != RT_ERR_OK) ++ return retVal; ++ ++ if(media_type == PORT_MEDIA_FIBER) ++ { ++ return _rtk_port_FiberModeAbility_set(port, pAbility); ++ } ++ } ++ ++ if (1 == pAbility->Full_1000) ++ return RT_ERR_INPUT; ++ ++ /*for PHY force mode setup*/ ++ pAbility->AutoNegotiation = 0; ++ ++ phyEnMsk0 = 0; ++ phyEnMsk4 = 0; ++ phyEnMsk9 = 0; ++ ++ if (1 == pAbility->Half_10) ++ { ++ /*10BASE-TX half duplex capable in reg 4.5*/ ++ phyEnMsk4 = phyEnMsk4 | (1 << 5); ++ ++ /*Speed selection [1:0] */ ++ /* 11=Reserved*/ ++ /* 10= 1000Mpbs*/ ++ /* 01= 100Mpbs*/ ++ /* 00= 10Mpbs*/ ++ phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); ++ phyEnMsk0 = phyEnMsk0 & (~(1 << 13)); ++ } ++ ++ if (1 == pAbility->Full_10) ++ { ++ /*10BASE-TX full duplex capable in reg 4.6*/ ++ phyEnMsk4 = phyEnMsk4 | (1 << 6); ++ /*Speed selection [1:0] */ ++ /* 11=Reserved*/ ++ /* 10= 1000Mpbs*/ ++ /* 01= 100Mpbs*/ ++ /* 00= 10Mpbs*/ ++ phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); ++ phyEnMsk0 = phyEnMsk0 & (~(1 << 13)); ++ ++ /*Full duplex mode in reg 0.8*/ ++ phyEnMsk0 = phyEnMsk0 | (1 << 8); ++ ++ } ++ ++ if (1 == pAbility->Half_100) ++ { ++ /*100BASE-TX half duplex capable in reg 4.7*/ ++ phyEnMsk4 = phyEnMsk4 | (1 << 7); ++ /*Speed selection [1:0] */ ++ /* 11=Reserved*/ ++ /* 10= 1000Mpbs*/ ++ /* 01= 100Mpbs*/ ++ /* 00= 10Mpbs*/ ++ phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); ++ phyEnMsk0 = phyEnMsk0 | (1 << 13); ++ } ++ ++ ++ if (1 == pAbility->Full_100) ++ { ++ /*100BASE-TX full duplex capable in reg 4.8*/ ++ phyEnMsk4 = phyEnMsk4 | (1 << 8); ++ /*Speed selection [1:0] */ ++ /* 11=Reserved*/ ++ /* 10= 1000Mpbs*/ ++ /* 01= 100Mpbs*/ ++ /* 00= 10Mpbs*/ ++ phyEnMsk0 = phyEnMsk0 & (~(1 << 6)); ++ phyEnMsk0 = phyEnMsk0 | (1 << 13); ++ /*Full duplex mode in reg 0.8*/ ++ phyEnMsk0 = phyEnMsk0 | (1 << 8); ++ } ++ ++ if (1 == pAbility->AsyFC) ++ { ++ /*Asymetric flow control in reg 4.11*/ ++ phyEnMsk4 = phyEnMsk4 | (1 << 11); ++ } ++ if (1 == pAbility->FC) ++ { ++ /*Flow control in reg 4.10*/ ++ phyEnMsk4 = phyEnMsk4 | ((1 << 10)); ++ } ++ ++ /*1000 BASE-T control register setting*/ ++ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, &phyData)) != RT_ERR_OK) ++ return retVal; ++ ++ phyData = (phyData & (~0x0200)) | phyEnMsk9 ; ++ ++ if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, phyData)) != RT_ERR_OK) ++ return retVal; ++ ++ /*Auto-Negotiation control register setting*/ ++ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, &phyData)) != RT_ERR_OK) ++ return retVal; ++ ++ phyData = (phyData & (~0x0DE0)) | phyEnMsk4; ++ if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, phyData)) != RT_ERR_OK) ++ return retVal; ++ ++ /*Control register setting and power off/on*/ ++ phyData = phyEnMsk0 & (~(1 << 12)); ++ phyData |= (1 << 11); /* power down PHY, bit 11 should be set to 1 */ ++ if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, phyData)) != RT_ERR_OK) ++ return retVal; ++ ++ phyData = phyData & (~(1 << 11)); /* power on PHY, bit 11 should be set to 0*/ ++ if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, phyData)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_port_phyForceModeAbility_get(rtk_port_t port, rtk_port_phy_ability_t *pAbility) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 phyData0; ++ rtk_uint32 phyData4; ++ rtk_uint32 phyData9; ++ rtk_port_media_t media_type; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_IS_UTP(port); ++ ++ if(NULL == pAbility) ++ return RT_ERR_NULL_POINTER; ++ ++ if (rtk_switch_isComboPort(port) == RT_ERR_OK) ++ { ++ if ((retVal = rtk_port_phyComboPortMedia_get(port, &media_type)) != RT_ERR_OK) ++ return retVal; ++ ++ if(media_type == PORT_MEDIA_FIBER) ++ { ++ return _rtk_port_FiberModeAbility_get(port, pAbility); ++ } ++ } ++ ++ /*Control register setting and restart auto*/ ++ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, &phyData0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*Auto-Negotiation control register setting*/ ++ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_AN_ADVERTISEMENT_REG, &phyData4)) != RT_ERR_OK) ++ return retVal; ++ ++ /*1000 BASE-T control register setting*/ ++ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_1000_BASET_CONTROL_REG, &phyData9)) != RT_ERR_OK) ++ return retVal; ++ ++ if (phyData9 & (1 << 9)) ++ pAbility->Full_1000 = 1; ++ else ++ pAbility->Full_1000 = 0; ++ ++ if (phyData4 & (1 << 11)) ++ pAbility->AsyFC = 1; ++ else ++ pAbility->AsyFC = 0; ++ ++ if (phyData4 & ((1 << 10))) ++ pAbility->FC = 1; ++ else ++ pAbility->FC = 0; ++ ++ ++ if (phyData4 & (1 << 8)) ++ pAbility->Full_100 = 1; ++ else ++ pAbility->Full_100 = 0; ++ ++ if (phyData4 & (1 << 7)) ++ pAbility->Half_100 = 1; ++ else ++ pAbility->Half_100 = 0; ++ ++ if (phyData4 & (1 << 6)) ++ pAbility->Full_10 = 1; ++ else ++ pAbility->Full_10 = 0; ++ ++ if (phyData4 & (1 << 5)) ++ pAbility->Half_10 = 1; ++ else ++ pAbility->Half_10 = 0; ++ ++ ++ if (phyData0 & (1 << 12)) ++ pAbility->AutoNegotiation = 1; ++ else ++ pAbility->AutoNegotiation = 0; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++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) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 phyData; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_IS_UTP(port); ++ ++ if( (NULL == pLinkStatus) || (NULL == pSpeed) || (NULL == pDuplex) ) ++ return RT_ERR_NULL_POINTER; ++ ++ /*Get PHY resolved register*/ ++ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_RESOLVED_REG, &phyData)) != RT_ERR_OK) ++ return retVal; ++ ++ /*check link status*/ ++ if (phyData & (1<<2)) ++ { ++ *pLinkStatus = 1; ++ ++ /*check link speed*/ ++ *pSpeed = (phyData&0x0030) >> 4; ++ ++ /*check link duplex*/ ++ *pDuplex = (phyData&0x0008) >> 3; ++ } ++ else ++ { ++ *pLinkStatus = 0; ++ *pSpeed = 0; ++ *pDuplex = 0; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_port_macForceLink_set(rtk_port_t port, rtk_port_mac_ability_t *pPortability) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_port_ability_t ability; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_IS_UTP(port); ++ ++ if(NULL == pPortability) ++ return RT_ERR_NULL_POINTER; ++ ++ if (pPortability->forcemode >1|| pPortability->speed > 2 || pPortability->duplex > 1 || ++ pPortability->link > 1 || pPortability->nway > 1 || pPortability->txpause > 1 || pPortability->rxpause > 1) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_getAsicPortForceLink(rtk_switch_port_L2P_get(port), &ability)) != RT_ERR_OK) ++ return retVal; ++ ++ ability.forcemode = pPortability->forcemode; ++ ability.speed = pPortability->speed; ++ ability.duplex = pPortability->duplex; ++ ability.link = pPortability->link; ++ ability.nway = pPortability->nway; ++ ability.txpause = pPortability->txpause; ++ ability.rxpause = pPortability->rxpause; ++ ++ if ((retVal = rtl8367c_setAsicPortForceLink(rtk_switch_port_L2P_get(port), &ability)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_port_macForceLink_get(rtk_port_t port, rtk_port_mac_ability_t *pPortability) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_port_ability_t ability; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_IS_UTP(port); ++ ++ if(NULL == pPortability) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicPortForceLink(rtk_switch_port_L2P_get(port), &ability)) != RT_ERR_OK) ++ return retVal; ++ ++ pPortability->forcemode = ability.forcemode; ++ pPortability->speed = ability.speed; ++ pPortability->duplex = ability.duplex; ++ pPortability->link = ability.link; ++ pPortability->nway = ability.nway; ++ pPortability->txpause = ability.txpause; ++ pPortability->rxpause = ability.rxpause; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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, ++ */ ++rtk_api_ret_t rtk_port_macForceLinkExt_set(rtk_port_t port, rtk_mode_ext_t mode, rtk_port_mac_ability_t *pPortability) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_port_ability_t ability; ++ rtk_uint32 ext_id; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_IS_EXT(port); ++ ++ if(NULL == pPortability) ++ return RT_ERR_NULL_POINTER; ++ ++ if (mode >=MODE_EXT_END) ++ return RT_ERR_INPUT; ++ ++ if(mode == MODE_EXT_HSGMII) ++ { ++ if (pPortability->forcemode > 1 || pPortability->speed != PORT_SPEED_2500M || pPortability->duplex != PORT_FULL_DUPLEX || ++ pPortability->link >= PORT_LINKSTATUS_END || pPortability->nway > 1 || pPortability->txpause > 1 || pPortability->rxpause > 1) ++ return RT_ERR_INPUT; ++ ++ if(rtk_switch_isHsgPort(port) != RT_ERR_OK) ++ return RT_ERR_PORT_ID; ++ } ++ else ++ { ++ if (pPortability->forcemode > 1 || pPortability->speed > PORT_SPEED_1000M || pPortability->duplex >= PORT_DUPLEX_END || ++ pPortability->link >= PORT_LINKSTATUS_END || pPortability->nway > 1 || pPortability->txpause > 1 || pPortability->rxpause > 1) ++ return RT_ERR_INPUT; ++ } ++ ++ ext_id = port - 15; ++ ++ if(mode == MODE_EXT_DISABLE) ++ { ++ memset(&ability, 0x00, sizeof(rtl8367c_port_ability_t)); ++ if ((retVal = rtl8367c_setAsicPortForceLinkExt(ext_id, &ability)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicPortExtMode(ext_id, mode)) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ if ((retVal = rtl8367c_setAsicPortExtMode(ext_id, mode)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicPortForceLinkExt(ext_id, &ability)) != RT_ERR_OK) ++ return retVal; ++ ++ ability.forcemode = pPortability->forcemode; ++ ability.speed = (mode == MODE_EXT_HSGMII) ? PORT_SPEED_1000M : pPortability->speed; ++ ability.duplex = pPortability->duplex; ++ ability.link = pPortability->link; ++ ability.nway = pPortability->nway; ++ ability.txpause = pPortability->txpause; ++ ability.rxpause = pPortability->rxpause; ++ ++ if ((retVal = rtl8367c_setAsicPortForceLinkExt(ext_id, &ability)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_port_macForceLinkExt_get(rtk_port_t port, rtk_mode_ext_t *pMode, rtk_port_mac_ability_t *pPortability) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_port_ability_t ability; ++ rtk_uint32 ext_id; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_IS_EXT(port); ++ ++ if(NULL == pMode) ++ return RT_ERR_NULL_POINTER; ++ ++ if(NULL == pPortability) ++ return RT_ERR_NULL_POINTER; ++ ++ ext_id = port - 15; ++ ++ if ((retVal = rtl8367c_getAsicPortExtMode(ext_id, (rtk_uint32 *)pMode)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicPortForceLinkExt(ext_id, &ability)) != RT_ERR_OK) ++ return retVal; ++ ++ pPortability->forcemode = ability.forcemode; ++ pPortability->speed = (*pMode == MODE_EXT_HSGMII) ? PORT_SPEED_2500M : ability.speed; ++ pPortability->duplex = ability.duplex; ++ pPortability->link = ability.link; ++ pPortability->nway = ability.nway; ++ pPortability->txpause = ability.txpause; ++ pPortability->rxpause = ability.rxpause; ++ ++ return RT_ERR_OK; ++ ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_port_macStatus_get(rtk_port_t port, rtk_port_mac_ability_t *pPortstatus) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_port_status_t status; ++ rtk_uint32 hsgsel; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(NULL == pPortstatus) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicPortStatus(rtk_switch_port_L2P_get(port), &status)) != RT_ERR_OK) ++ return retVal; ++ ++ ++ pPortstatus->duplex = status.duplex; ++ pPortstatus->link = status.link; ++ pPortstatus->nway = status.nway; ++ pPortstatus->txpause = status.txpause; ++ pPortstatus->rxpause = status.rxpause; ++ ++ if( (retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, &hsgsel)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (rtk_switch_isHsgPort(port) == RT_ERR_OK) && (hsgsel == 1) ) ++ pPortstatus->speed = PORT_SPEED_2500M; ++ else ++ pPortstatus->speed = status.speed; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_port_macLocalLoopbackEnable_set(rtk_port_t port, rtk_enable_t enable) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 data; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(enable >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicPortLoopback(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) ++ return retVal; ++ ++ if(rtk_switch_isUtpPort(port) == RT_ERR_OK) ++ { ++ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, &data)) != RT_ERR_OK) ++ return retVal; ++ ++ if(enable == ENABLED) ++ data |= (0x0001 << 14); ++ else ++ data &= ~(0x0001 << 14); ++ ++ if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), PHY_CONTROL_REG, data)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_port_macLocalLoopbackEnable_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_getAsicPortLoopback(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_port_phyReg_set(rtk_port_t port, rtk_port_phy_reg_t reg, rtk_port_phy_data_t regData) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_IS_UTP(port); ++ ++ if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), reg, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_port_phyReg_get(rtk_port_t port, rtk_port_phy_reg_t reg, rtk_port_phy_data_t *pData) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_IS_UTP(port); ++ ++ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), reg, pData)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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(Defer) ++ * - ENABLE (Backpressure) ++ */ ++rtk_api_ret_t rtk_port_backpressureEnable_set(rtk_port_t port, rtk_enable_t enable) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (port != RTK_WHOLE_SYSTEM) ++ return RT_ERR_PORT_ID; ++ ++ if (enable >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicPortJamMode(!enable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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(Defer) ++ * - ENABLE (Backpressure) ++ */ ++rtk_api_ret_t rtk_port_backpressureEnable_get(rtk_port_t port, rtk_enable_t *pEnable) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 regData; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (port != RTK_WHOLE_SYSTEM) ++ return RT_ERR_PORT_ID; ++ ++ if(NULL == pEnable) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicPortJamMode(®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEnable = !regData; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_port_adminEnable_set(rtk_port_t port, rtk_enable_t enable) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 data; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_IS_UTP(port); ++ ++ if (enable >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtk_port_phyReg_get(port, PHY_CONTROL_REG, &data)) != RT_ERR_OK) ++ return retVal; ++ ++ if (ENABLED == enable) ++ { ++ data &= 0xF7FF; ++ data |= 0x0200; ++ } ++ else if (DISABLED == enable) ++ { ++ data |= 0x0800; ++ } ++ ++ if ((retVal = rtk_port_phyReg_set(port, PHY_CONTROL_REG, data)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_port_adminEnable_get(rtk_port_t port, rtk_enable_t *pEnable) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 data; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_IS_UTP(port); ++ ++ if(NULL == pEnable) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtk_port_phyReg_get(port, PHY_CONTROL_REG, &data)) != RT_ERR_OK) ++ return retVal; ++ ++ if ( (data & 0x0800) == 0x0800) ++ { ++ *pEnable = DISABLED; ++ } ++ else ++ { ++ *pEnable = ENABLED; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_port_isolation_set(rtk_port_t port, rtk_portmask_t *pPortmask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(NULL == pPortmask) ++ return RT_ERR_NULL_POINTER; ++ ++ /* check port mask */ ++ RTK_CHK_PORTMASK_VALID(pPortmask); ++ ++ if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicPortIsolationPermittedPortmask(rtk_switch_port_L2P_get(port), pmask)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_port_isolation_get(rtk_port_t port, rtk_portmask_t *pPortmask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(NULL == pPortmask) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicPortIsolationPermittedPortmask(rtk_switch_port_L2P_get(port), &pmask)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_port_rgmiiDelayExt_set(rtk_port_t port, rtk_data_t txDelay, rtk_data_t rxDelay) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 regAddr, regData; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_IS_EXT(port); ++ ++ if ((txDelay > 1) || (rxDelay > 7)) ++ return RT_ERR_INPUT; ++ ++ if(port == EXT_PORT0) ++ regAddr = RTL8367C_REG_EXT1_RGMXF; ++ else if(port == EXT_PORT1) ++ regAddr = RTL8367C_REG_EXT2_RGMXF; ++ else ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ regData = (regData & 0xFFF0) | ((txDelay << 3) & 0x0008) | (rxDelay & 0x0007); ++ ++ if ((retVal = rtl8367c_setAsicReg(regAddr, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_port_rgmiiDelayExt_get(rtk_port_t port, rtk_data_t *pTxDelay, rtk_data_t *pRxDelay) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 regAddr, regData; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_IS_EXT(port); ++ ++ if( (NULL == pTxDelay) || (NULL == pRxDelay) ) ++ return RT_ERR_NULL_POINTER; ++ ++ if(port == EXT_PORT0) ++ regAddr = RTL8367C_REG_EXT1_RGMXF; ++ else if(port == EXT_PORT1) ++ regAddr = RTL8367C_REG_EXT2_RGMXF; ++ else ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ *pTxDelay = (regData & 0x0008) >> 3; ++ *pRxDelay = regData & 0x0007; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_port_phyEnableAll_set(rtk_enable_t enable) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 data; ++ rtk_uint32 port; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (enable >= RTK_ENABLE_END) ++ return RT_ERR_ENABLE; ++ ++ if ((retVal = rtl8367c_setAsicPortEnableAll(enable)) != RT_ERR_OK) ++ return retVal; ++ ++ RTK_SCAN_ALL_LOG_PORT(port) ++ { ++ if(rtk_switch_isUtpPort(port) == RT_ERR_OK) ++ { ++ if ((retVal = rtk_port_phyReg_get(port, PHY_CONTROL_REG, &data)) != RT_ERR_OK) ++ return retVal; ++ ++ if (ENABLED == enable) ++ { ++ data &= 0xF7FF; ++ data |= 0x0200; ++ } ++ else ++ { ++ data |= 0x0800; ++ } ++ ++ if ((retVal = rtk_port_phyReg_set(port, PHY_CONTROL_REG, data)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ ++ return RT_ERR_OK; ++ ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_port_phyEnableAll_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_getAsicPortEnableAll(pEnable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_port_efid_set(rtk_port_t port, rtk_data_t efid) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ /* efid must be 0~7 */ ++ if (efid > RTK_EFID_MAX) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicPortIsolationEfid(rtk_switch_port_L2P_get(port), efid))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_port_efid_get(rtk_port_t port, rtk_data_t *pEfid) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(NULL == pEfid) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicPortIsolationEfid(rtk_switch_port_L2P_get(port), pEfid))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_port_phyComboPortMedia_set ++ * Description: ++ * Set Combo port media type ++ * Input: ++ * port - Port id. ++ * 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. ++ */ ++rtk_api_ret_t rtk_port_phyComboPortMedia_set(rtk_port_t port, rtk_port_media_t media) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint32 idx; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_IS_UTP(port); ++ ++ /* Check Combo Port ID */ ++ RTK_CHK_PORT_IS_COMBO(port); ++ ++ if (media >= PORT_MEDIA_END) ++ return RT_ERR_INPUT; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) ++ return retVal; ++ ++ if(regData != 0x6367) ++ return RT_ERR_CHIP_NOT_SUPPORTED; ++ ++ if(media == PORT_MEDIA_FIBER) ++ { ++ /* software init */ ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MISCELLANEOUS_CONFIGURE0, RTL8367C_DW8051_EN_OFFSET, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ for(idx = 0; idx < FIBER_INIT_SIZE; idx++) ++ { ++ if ((retVal = rtl8367c_setAsicReg(0xE000 + idx, (rtk_uint32)Fiber[idx])) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_UTP_FIB_DET, RTL8367C_UTP_FIRST_OFFSET, 1))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_DW8051_READY_OFFSET, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_port_phyComboPortMedia_get ++ * Description: ++ * Get Combo port media type ++ * Input: ++ * port - Port id. ++ * 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. ++ */ ++rtk_api_ret_t rtk_port_phyComboPortMedia_get(rtk_port_t port, rtk_port_media_t *pMedia) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint32 data; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_IS_UTP(port); ++ ++ /* Check Combo Port ID */ ++ RTK_CHK_PORT_IS_COMBO(port); ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) ++ return retVal; ++ ++ if(regData != 0x6367) ++ { ++ *pMedia = PORT_MEDIA_COPPER; ++ } ++ else ++ { ++ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_UTP_FIB_DET, RTL8367C_UTP_FIRST_OFFSET, &data))!=RT_ERR_OK) ++ return retVal; ++ ++ if(data == 1) ++ *pMedia = PORT_MEDIA_COPPER; ++ else ++ *pMedia = PORT_MEDIA_FIBER; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_port_rtctEnable_set(rtk_portmask_t *pPortmask) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Mask Valid */ ++ RTK_CHK_PORTMASK_VALID_ONLY_UTP(pPortmask); ++ ++ if ((retVal = rtl8367c_setAsicPortRTCTEnable(pPortmask->bits[0]))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Mask Valid */ ++ RTK_CHK_PORTMASK_VALID_ONLY_UTP(pPortmask); ++ ++ if ((retVal = rtl8367c_setAsicPortRTCTDisable(pPortmask->bits[0]))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_port_rtctResult_get(rtk_port_t port, rtk_rtctResult_t *pRtctResult) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_port_rtct_result_t result; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_IS_UTP(port); ++ ++ memset(pRtctResult, 0x00, sizeof(rtk_rtctResult_t)); ++ if ((retVal = rtl8367c_getAsicPortRTCTResult(port, &result))!=RT_ERR_OK) ++ return retVal; ++ ++ pRtctResult->result.ge_result.channelALen = result.channelALen; ++ pRtctResult->result.ge_result.channelBLen = result.channelBLen; ++ pRtctResult->result.ge_result.channelCLen = result.channelCLen; ++ pRtctResult->result.ge_result.channelDLen = result.channelDLen; ++ ++ pRtctResult->result.ge_result.channelALinedriver = result.channelALinedriver; ++ pRtctResult->result.ge_result.channelBLinedriver = result.channelBLinedriver; ++ pRtctResult->result.ge_result.channelCLinedriver = result.channelCLinedriver; ++ pRtctResult->result.ge_result.channelDLinedriver = result.channelDLinedriver; ++ ++ pRtctResult->result.ge_result.channelAMismatch = result.channelAMismatch; ++ pRtctResult->result.ge_result.channelBMismatch = result.channelBMismatch; ++ pRtctResult->result.ge_result.channelCMismatch = result.channelCMismatch; ++ pRtctResult->result.ge_result.channelDMismatch = result.channelDMismatch; ++ ++ pRtctResult->result.ge_result.channelAOpen = result.channelAOpen; ++ pRtctResult->result.ge_result.channelBOpen = result.channelBOpen; ++ pRtctResult->result.ge_result.channelCOpen = result.channelCOpen; ++ pRtctResult->result.ge_result.channelDOpen = result.channelDOpen; ++ ++ pRtctResult->result.ge_result.channelAShort = result.channelAShort; ++ pRtctResult->result.ge_result.channelBShort = result.channelBShort; ++ pRtctResult->result.ge_result.channelCShort = result.channelCShort; ++ pRtctResult->result.ge_result.channelDShort = result.channelDShort; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_port_sds_reset(rtk_port_t port) ++{ ++ rtk_uint32 ext_id; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ if(rtk_switch_isSgmiiPort(port) != RT_ERR_OK) ++ return RT_ERR_PORT_ID; ++ ++ ext_id = port - 15; ++ return rtl8367c_sdsReset(ext_id); ++} ++ ++/* 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 ++ */ ++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) ++{ ++ rtk_uint32 ext_id; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ if(rtk_switch_isSgmiiPort(port) != RT_ERR_OK) ++ return RT_ERR_PORT_ID; ++ ++ if(NULL == pSignalDetect) ++ return RT_ERR_NULL_POINTER; ++ ++ if(NULL == pSync) ++ return RT_ERR_NULL_POINTER; ++ ++ if(NULL == pLink) ++ return RT_ERR_NULL_POINTER; ++ ++ ext_id = port - 15; ++ return rtl8367c_getSdsLinkStatus(ext_id, (rtk_uint32 *)pSignalDetect, (rtk_uint32 *)pSync, (rtk_uint32 *)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 ++ */ ++rtk_api_ret_t rtk_port_sgmiiNway_set(rtk_port_t port, rtk_enable_t state) ++{ ++ rtk_uint32 ext_id; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ if(rtk_switch_isSgmiiPort(port) != RT_ERR_OK) ++ return RT_ERR_PORT_ID; ++ ++ if(state >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ ext_id = port - 15; ++ return rtl8367c_setSgmiiNway(ext_id, (rtk_uint32)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 ++ */ ++rtk_api_ret_t rtk_port_sgmiiNway_get(rtk_port_t port, rtk_enable_t *pState) ++{ ++ rtk_uint32 ext_id; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ if(rtk_switch_isSgmiiPort(port) != RT_ERR_OK) ++ return RT_ERR_PORT_ID; ++ ++ if(NULL == pState) ++ return RT_ERR_NULL_POINTER; ++ ++ ext_id = port - 15; ++ return rtl8367c_getSgmiiNway(ext_id, (rtk_uint32 *)pState); ++} +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/ptp.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/ptp.c +new file mode 100644 +index 0000000000..40962a0e69 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/ptp.c +@@ -0,0 +1,759 @@ ++/* ++ * 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: 39583 $ ++ * $Date: 2013-05-20 16:59:23 +0800 (星期一, 20 五月 2013) $ ++ * ++ * Purpose : RTK switch high-level API for RTL8367/RTL8367C ++ * Feature : Here is a list of all functions and variables in time module. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++/* Function Name: ++ * rtk_ptp_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 PTP status. ++ */ ++rtk_api_ret_t rtk_ptp_init(void) ++{ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_ptp_mac_set(rtk_mac_t mac) ++{ ++ rtk_api_ret_t retVal; ++ ether_addr_t sw_mac; ++ ++ memcpy(sw_mac.octet, mac.octet, ETHER_ADDR_LEN); ++ ++ if((retVal=rtl8367c_setAsicEavMacAddress(sw_mac))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_ptp_mac_get(rtk_mac_t *pMac) ++{ ++ rtk_api_ret_t retVal; ++ ether_addr_t sw_mac; ++ ++ if((retVal=rtl8367c_getAsicEavMacAddress(&sw_mac))!=RT_ERR_OK) ++ return retVal; ++ ++ memcpy(pMac->octet, sw_mac.octet, ETHER_ADDR_LEN); ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_ptp_tpid_set(rtk_ptp_tpid_t outerId, rtk_ptp_tpid_t innerId) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ((outerId>RTK_MAX_NUM_OF_TPID) ||(innerId>RTK_MAX_NUM_OF_TPID)) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicEavTpid(outerId, innerId)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_ptp_tpid_get(rtk_ptp_tpid_t *pOuterId, rtk_ptp_tpid_t *pInnerId) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ((retVal = rtl8367c_getAsicEavTpid(pOuterId, pInnerId)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_ptp_refTime_set(rtk_ptp_timeStamp_t timeStamp) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (timeStamp.nsec > RTK_MAX_NUM_OF_NANO_SECOND) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicEavSysTime(timeStamp.sec, timeStamp.nsec))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_ptp_refTime_get(rtk_ptp_timeStamp_t *pTimeStamp) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ((retVal = rtl8367c_getAsicEavSysTime(&pTimeStamp->sec, &pTimeStamp->nsec))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_ptp_refTimeAdjust_set(rtk_ptp_sys_adjust_t sign, rtk_ptp_timeStamp_t timeStamp) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (timeStamp.nsec > RTK_MAX_NUM_OF_NANO_SECOND) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicEavSysTimeAdjust(sign, timeStamp.sec, timeStamp.nsec))!=RT_ERR_OK) ++ return retVal; ++ ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_ptp_refTimeEnable_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_setAsicEavSysTimeCtrl(enable))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_ptp_refTimeEnable_get(rtk_enable_t *pEnable) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ((retVal = rtl8367c_getAsicEavSysTimeCtrl(pEnable))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_ptp_portEnable_set(rtk_port_t port, rtk_enable_t enable) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check port is PTP port */ ++ RTK_CHK_PORT_IS_PTP(port); ++ ++ if (enable>=RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicEavPortEnable(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_ptp_portEnable_get(rtk_port_t port, rtk_enable_t *pEnable) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check port is PTP port */ ++ RTK_CHK_PORT_IS_PTP(port); ++ ++ if ((retVal = rtl8367c_getAsicEavPortEnable(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_ptp_portTimestamp_get( rtk_port_t port, rtk_ptp_msgType_t type, rtk_ptp_info_t *pInfo) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_ptp_time_stamp_t time; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check port is PTP port */ ++ RTK_CHK_PORT_IS_PTP(port); ++ ++ if ((retVal = rtl8367c_getAsicEavPortTimeStamp(rtk_switch_port_L2P_get(port), type, &time)) != RT_ERR_OK) ++ return retVal; ++ ++ pInfo->sequenceId = time.sequence_id; ++ pInfo->timeStamp.sec = time.second; ++ pInfo->timeStamp.nsec = time.nano_second; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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, ++ */ ++rtk_api_ret_t rtk_ptp_intControl_set(rtk_ptp_intType_t type, rtk_enable_t enable) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 mask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (type>=PTP_INT_TYPE_END) ++ return RT_ERR_INPUT; ++ ++ if (PTP_INT_TYPE_ALL!=type) ++ { ++ if ((retVal = rtl8367c_getAsicEavInterruptMask(&mask)) != RT_ERR_OK) ++ return retVal; ++ ++ if (ENABLED == enable) ++ mask = mask | (1<=PTP_INT_TYPE_ALL) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_getAsicEavInterruptMask(&mask)) != RT_ERR_OK) ++ return retVal; ++ ++ if (0 == (mask&(1<=RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicEavTrap(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_ptp_portTrap_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 ((retVal = rtl8367c_getAsicEavTrap(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/qos.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/qos.c +new file mode 100644 +index 0000000000..70067a3016 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/qos.c +@@ -0,0 +1,1452 @@ ++/* ++ * 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 QoS module. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_qos_init(rtk_queue_num_t queueNum) ++{ ++ CONST_T rtk_uint16 g_prioritytToQid[8][8]= { ++ {0, 0,0,0,0,0,0,0}, ++ {0, 0,0,0,7,7,7,7}, ++ {0, 0,0,0,1,1,7,7}, ++ {0, 0,1,1,2,2,7,7}, ++ {0, 0,1,1,2,3,7,7}, ++ {0, 0,1,2,3,4,7,7}, ++ {0, 0,1,2,3,4,5,7}, ++ {0,1,2,3,4,5,6,7} ++ }; ++ ++ CONST_T rtk_uint32 g_priorityDecision[8] = {0x01, 0x80,0x04,0x02,0x20,0x40,0x10,0x08}; ++ CONST_T rtk_uint32 g_prioritytRemap[8] = {0,1,2,3,4,5,6,7}; ++ ++ rtk_api_ret_t retVal; ++ rtk_uint32 qmapidx; ++ rtk_uint32 priority; ++ rtk_uint32 priDec; ++ rtk_uint32 port; ++ rtk_uint32 dscp; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (queueNum <= 0 || queueNum > RTK_MAX_NUM_OF_QUEUE) ++ return RT_ERR_QUEUE_NUM; ++ ++ /*Set Output Queue Number*/ ++ if (RTK_MAX_NUM_OF_QUEUE == queueNum) ++ qmapidx = 0; ++ else ++ qmapidx = queueNum; ++ ++ RTK_SCAN_ALL_PHY_PORTMASK(port) ++ { ++ if ((retVal = rtl8367c_setAsicOutputQueueMappingIndex(port, qmapidx)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ /*Set Priority to Qid*/ ++ for (priority = 0; priority <= RTK_PRIMAX; priority++) ++ { ++ if ((retVal = rtl8367c_setAsicPriorityToQIDMappingTable(queueNum - 1, priority, g_prioritytToQid[queueNum - 1][priority])) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ /*Set Flow Control Type to Ingress Flow Control*/ ++ if ((retVal = rtl8367c_setAsicFlowControlSelect(FC_INGRESS)) != RT_ERR_OK) ++ return retVal; ++ ++ ++ /*Priority Decision Order*/ ++ for (priDec = 0;priDec < PRIDEC_END;priDec++) ++ { ++ if ((retVal = rtl8367c_setAsicPriorityDecision(PRIDECTBL_IDX0, priDec, g_priorityDecision[priDec])) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicPriorityDecision(PRIDECTBL_IDX1, priDec, g_priorityDecision[priDec])) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ /*Set Port-based Priority to 0*/ ++ RTK_SCAN_ALL_PHY_PORTMASK(port) ++ { ++ if ((retVal = rtl8367c_setAsicPriorityPortBased(port, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ /*Disable 1p Remarking*/ ++ RTK_SCAN_ALL_PHY_PORTMASK(port) ++ { ++ if ((retVal = rtl8367c_setAsicRemarkingDot1pAbility(port, DISABLED)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ /*Disable DSCP Remarking*/ ++ if ((retVal = rtl8367c_setAsicRemarkingDscpAbility(DISABLED)) != RT_ERR_OK) ++ return retVal; ++ ++ /*Set 1p & DSCP Priority Remapping & Remarking*/ ++ for (priority = 0; priority <= RTL8367C_PRIMAX; priority++) ++ { ++ if ((retVal = rtl8367c_setAsicPriorityDot1qRemapping(priority, g_prioritytRemap[priority])) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRemarkingDot1pParameter(priority, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRemarkingDscpParameter(priority, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ /*Set DSCP Priority*/ ++ for (dscp = 0; dscp <= 63; dscp++) ++ { ++ if ((retVal = rtl8367c_setAsicPriorityDscpBased(dscp, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ /* Finetune B/T value */ ++ if((retVal = rtl8367c_setAsicReg(0x1722, 0x1158)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_qos_priSel_set(rtk_qos_priDecTbl_t index, rtk_priority_select_t *pPriDec) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 port_pow; ++ rtk_uint32 dot1q_pow; ++ rtk_uint32 dscp_pow; ++ rtk_uint32 acl_pow; ++ rtk_uint32 svlan_pow; ++ rtk_uint32 cvlan_pow; ++ rtk_uint32 smac_pow; ++ rtk_uint32 dmac_pow; ++ rtk_uint32 i; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (index < 0 || index >= PRIDECTBL_END) ++ return RT_ERR_ENTRY_INDEX; ++ ++ if (pPriDec->port_pri >= 8 || pPriDec->dot1q_pri >= 8 || pPriDec->acl_pri >= 8 || pPriDec->dscp_pri >= 8 || ++ pPriDec->cvlan_pri >= 8 || pPriDec->svlan_pri >= 8 || pPriDec->dmac_pri >= 8 || pPriDec->smac_pri >= 8) ++ return RT_ERR_QOS_SEL_PRI_SOURCE; ++ ++ port_pow = 1; ++ for (i = pPriDec->port_pri; i > 0; i--) ++ port_pow = (port_pow)*2; ++ ++ dot1q_pow = 1; ++ for (i = pPriDec->dot1q_pri; i > 0; i--) ++ dot1q_pow = (dot1q_pow)*2; ++ ++ acl_pow = 1; ++ for (i = pPriDec->acl_pri; i > 0; i--) ++ acl_pow = (acl_pow)*2; ++ ++ dscp_pow = 1; ++ for (i = pPriDec->dscp_pri; i > 0; i--) ++ dscp_pow = (dscp_pow)*2; ++ ++ svlan_pow = 1; ++ for (i = pPriDec->svlan_pri; i > 0; i--) ++ svlan_pow = (svlan_pow)*2; ++ ++ cvlan_pow = 1; ++ for (i = pPriDec->cvlan_pri; i > 0; i--) ++ cvlan_pow = (cvlan_pow)*2; ++ ++ dmac_pow = 1; ++ for (i = pPriDec->dmac_pri; i > 0; i--) ++ dmac_pow = (dmac_pow)*2; ++ ++ smac_pow = 1; ++ for (i = pPriDec->smac_pri; i > 0; i--) ++ smac_pow = (smac_pow)*2; ++ ++ if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_PORT, port_pow)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_ACL, acl_pow)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_DSCP, dscp_pow)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_1Q, dot1q_pow)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_1AD, svlan_pow)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_CVLAN, cvlan_pow)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_DA, dmac_pow)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicPriorityDecision(index, PRIDEC_SA, smac_pow)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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, ++ */ ++rtk_api_ret_t rtk_qos_priSel_get(rtk_qos_priDecTbl_t index, rtk_priority_select_t *pPriDec) ++{ ++ ++ rtk_api_ret_t retVal; ++ rtk_int32 i; ++ rtk_uint32 port_pow; ++ rtk_uint32 dot1q_pow; ++ rtk_uint32 dscp_pow; ++ rtk_uint32 acl_pow; ++ rtk_uint32 svlan_pow; ++ rtk_uint32 cvlan_pow; ++ rtk_uint32 smac_pow; ++ rtk_uint32 dmac_pow; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (index < 0 || index >= PRIDECTBL_END) ++ return RT_ERR_ENTRY_INDEX; ++ ++ if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_PORT, &port_pow)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_ACL, &acl_pow)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_DSCP, &dscp_pow)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_1Q, &dot1q_pow)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_1AD, &svlan_pow)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_CVLAN, &cvlan_pow)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_DA, &dmac_pow)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicPriorityDecision(index, PRIDEC_SA, &smac_pow)) != RT_ERR_OK) ++ return retVal; ++ ++ for (i = 31; i >= 0; i--) ++ { ++ if (port_pow & (1 << i)) ++ { ++ pPriDec->port_pri = i; ++ break; ++ } ++ } ++ ++ for (i = 31; i >= 0; i--) ++ { ++ if (dot1q_pow & (1 << i)) ++ { ++ pPriDec->dot1q_pri = i; ++ break; ++ } ++ } ++ ++ for (i = 31; i >= 0; i--) ++ { ++ if (acl_pow & (1 << i)) ++ { ++ pPriDec->acl_pri = i; ++ break; ++ } ++ } ++ ++ for (i = 31; i >= 0; i--) ++ { ++ if (dscp_pow & (1 << i)) ++ { ++ pPriDec->dscp_pri = i; ++ break; ++ } ++ } ++ ++ for (i = 31; i >= 0; i--) ++ { ++ if (svlan_pow & (1 << i)) ++ { ++ pPriDec->svlan_pri = i; ++ break; ++ } ++ } ++ ++ for (i = 31;i >= 0; i--) ++ { ++ if (cvlan_pow & (1 << i)) ++ { ++ pPriDec->cvlan_pri = i; ++ break; ++ } ++ } ++ ++ for (i = 31; i >= 0; i--) ++ { ++ if (dmac_pow&(1<dmac_pri = i; ++ break; ++ } ++ } ++ ++ for (i = 31; i >= 0; i--) ++ { ++ if (smac_pow & (1 << i)) ++ { ++ pPriDec->smac_pri = i; ++ break; ++ } ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_qos_1pPriRemap_set(rtk_pri_t dot1p_pri, rtk_pri_t int_pri) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (dot1p_pri > RTL8367C_PRIMAX || int_pri > RTL8367C_PRIMAX) ++ return RT_ERR_VLAN_PRIORITY; ++ ++ if ((retVal = rtl8367c_setAsicPriorityDot1qRemapping(dot1p_pri, int_pri)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_qos_1pPriRemap_get(rtk_pri_t dot1p_pri, rtk_pri_t *pInt_pri) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (dot1p_pri > RTL8367C_PRIMAX) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ if ((retVal = rtl8367c_getAsicPriorityDot1qRemapping(dot1p_pri, pInt_pri)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_qos_dscpPriRemap_set(rtk_dscp_t dscp, rtk_pri_t int_pri) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (int_pri > RTL8367C_PRIMAX ) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ if (dscp > RTL8367C_DSCPMAX) ++ return RT_ERR_QOS_DSCP_VALUE; ++ ++ if ((retVal = rtl8367c_setAsicPriorityDscpBased(dscp, int_pri)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_qos_dscpPriRemap_get(rtk_dscp_t dscp, rtk_pri_t *pInt_pri) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (dscp > RTL8367C_DSCPMAX) ++ return RT_ERR_QOS_DSCP_VALUE; ++ ++ if ((retVal = rtl8367c_getAsicPriorityDscpBased(dscp, pInt_pri)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_qos_portPri_set(rtk_port_t port, rtk_pri_t int_pri) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if (int_pri > RTL8367C_PRIMAX ) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ if ((retVal = rtl8367c_setAsicPriorityPortBased(rtk_switch_port_L2P_get(port), int_pri)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_qos_portPri_get(rtk_port_t port, rtk_pri_t *pInt_pri) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if ((retVal = rtl8367c_getAsicPriorityPortBased(rtk_switch_port_L2P_get(port), pInt_pri)) != RT_ERR_OK) ++ return retVal; ++ ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_qos_queueNum_set(rtk_port_t port, rtk_queue_num_t queue_num) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if ((0 == queue_num) || (queue_num > RTK_MAX_NUM_OF_QUEUE)) ++ return RT_ERR_FAILED; ++ ++ if (RTK_MAX_NUM_OF_QUEUE == queue_num) ++ queue_num = 0; ++ ++ if ((retVal = rtl8367c_setAsicOutputQueueMappingIndex(rtk_switch_port_L2P_get(port), queue_num)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_qos_queueNum_get(rtk_port_t port, rtk_queue_num_t *pQueue_num) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 qidx; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if ((retVal = rtl8367c_getAsicOutputQueueMappingIndex(rtk_switch_port_L2P_get(port), &qidx)) != RT_ERR_OK) ++ return retVal; ++ ++ if (0 == qidx) ++ *pQueue_num = 8; ++ else ++ *pQueue_num = qidx; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_qos_priMap_set(rtk_queue_num_t queue_num, rtk_qos_pri2queue_t *pPri2qid) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pri; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ((0 == queue_num) || (queue_num > RTK_MAX_NUM_OF_QUEUE)) ++ return RT_ERR_QUEUE_NUM; ++ ++ for (pri = 0; pri <= RTK_PRIMAX; pri++) ++ { ++ if (pPri2qid->pri2queue[pri] > RTK_QIDMAX) ++ return RT_ERR_QUEUE_ID; ++ ++ if ((retVal = rtl8367c_setAsicPriorityToQIDMappingTable(queue_num - 1, pri, pPri2qid->pri2queue[pri])) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_qos_priMap_get(rtk_queue_num_t queue_num, rtk_qos_pri2queue_t *pPri2qid) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pri; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ((0 == queue_num) || (queue_num > RTK_MAX_NUM_OF_QUEUE)) ++ return RT_ERR_QUEUE_NUM; ++ ++ for (pri = 0; pri <= RTK_PRIMAX; pri++) ++ { ++ if ((retVal = rtl8367c_getAsicPriorityToQIDMappingTable(queue_num-1, pri, &pPri2qid->pri2queue[pri])) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 127, and weight 0 is ++ * for strict priority queue type. ++ */ ++rtk_api_ret_t rtk_qos_schedulingQueue_set(rtk_port_t port, rtk_qos_queue_weights_t *pQweights) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 qid; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ for (qid = 0; qid < RTL8367C_QUEUENO; qid ++) ++ { ++ ++ if (pQweights->weights[qid] > QOS_WEIGHT_MAX) ++ return RT_ERR_QOS_QUEUE_WEIGHT; ++ ++ if (0 == pQweights->weights[qid]) ++ { ++ if ((retVal = rtl8367c_setAsicQueueType(rtk_switch_port_L2P_get(port), qid, QTYPE_STRICT)) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ if ((retVal = rtl8367c_setAsicQueueType(rtk_switch_port_L2P_get(port), qid, QTYPE_WFQ)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicWFQWeight(rtk_switch_port_L2P_get(port),qid, pQweights->weights[qid])) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 127, and weight 0 is for strict priority queue type. ++ */ ++rtk_api_ret_t rtk_qos_schedulingQueue_get(rtk_port_t port, rtk_qos_queue_weights_t *pQweights) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 qid,qtype,qweight; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ for (qid = 0; qid < RTL8367C_QUEUENO; qid++) ++ { ++ if ((retVal = rtl8367c_getAsicQueueType(rtk_switch_port_L2P_get(port), qid, &qtype)) != RT_ERR_OK) ++ return retVal; ++ ++ if (QTYPE_STRICT == qtype) ++ { ++ pQweights->weights[qid] = 0; ++ } ++ else if (QTYPE_WFQ == qtype) ++ { ++ if ((retVal = rtl8367c_getAsicWFQWeight(rtk_switch_port_L2P_get(port), qid, &qweight)) != RT_ERR_OK) ++ return retVal; ++ pQweights->weights[qid] = qweight; ++ } ++ } ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_qos_1pRemarkEnable_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_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicRemarkingDot1pAbility(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_qos_1pRemarkEnable_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 ((retVal = rtl8367c_getAsicRemarkingDot1pAbility(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_qos_1pRemark_set(rtk_pri_t int_pri, rtk_pri_t dot1p_pri) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (int_pri > RTL8367C_PRIMAX ) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ if (dot1p_pri > RTL8367C_PRIMAX) ++ return RT_ERR_VLAN_PRIORITY; ++ ++ if ((retVal = rtl8367c_setAsicRemarkingDot1pParameter(int_pri, dot1p_pri)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_qos_1pRemark_get(rtk_pri_t int_pri, rtk_pri_t *pDot1p_pri) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (int_pri > RTL8367C_PRIMAX ) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ if ((retVal = rtl8367c_getAsicRemarkingDot1pParameter(int_pri, pDot1p_pri)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_qos_1pRemarkSrcSel_set(rtk_qos_1pRmkSrc_t type) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (type >= DOT1P_RMK_SRC_END ) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ if ((retVal = rtl8367c_setAsicRemarkingDot1pSrc(type)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_qos_1pRemarkSrcSel_get(rtk_qos_1pRmkSrc_t *pType) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ((retVal = rtl8367c_getAsicRemarkingDot1pSrc(pType)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_qos_dscpRemarkEnable_set(rtk_port_t port, rtk_enable_t enable) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /*for whole system function, the port value should be 0xFF*/ ++ if (port != RTK_WHOLE_SYSTEM) ++ return RT_ERR_PORT_ID; ++ ++ if (enable >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicRemarkingDscpAbility(enable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_qos_dscpRemarkEnable_get(rtk_port_t port, rtk_enable_t *pEnable) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /*for whole system function, the port value should be 0xFF*/ ++ if (port != RTK_WHOLE_SYSTEM) ++ return RT_ERR_PORT_ID; ++ ++ if ((retVal = rtl8367c_getAsicRemarkingDscpAbility(pEnable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_qos_dscpRemark_set(rtk_pri_t int_pri, rtk_dscp_t dscp) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (int_pri > RTK_PRIMAX ) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ if (dscp > RTK_DSCPMAX) ++ return RT_ERR_QOS_DSCP_VALUE; ++ ++ if ((retVal = rtl8367c_setAsicRemarkingDscpParameter(int_pri, dscp)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_qos_dscpRemark_get(rtk_pri_t int_pri, rtk_dscp_t *pDscp) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (int_pri > RTK_PRIMAX ) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ if ((retVal = rtl8367c_getAsicRemarkingDscpParameter(int_pri, pDscp)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_qos_dscpRemarkSrcSel_set(rtk_qos_dscpRmkSrc_t type) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (type >= DSCP_RMK_SRC_END ) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ if ((retVal = rtl8367c_setAsicRemarkingDscpSrc(type)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_qos_dscpRemarkSrcSel_get(rtk_qos_dscpRmkSrc_t *pType) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ((retVal = rtl8367c_getAsicRemarkingDscpSrc(pType)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_qos_dscpRemark2Dscp_set(rtk_dscp_t dscp, rtk_dscp_t rmkDscp) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ((dscp > RTK_DSCPMAX) || (rmkDscp > RTK_DSCPMAX)) ++ return RT_ERR_QOS_DSCP_VALUE; ++ ++ if ((retVal = rtl8367c_setAsicRemarkingDscp2Dscp(dscp, rmkDscp)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_qos_dscpRemark2Dscp_get(rtk_dscp_t dscp, rtk_dscp_t *pDscp) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (dscp > RTK_DSCPMAX) ++ return RT_ERR_QOS_DSCP_VALUE; ++ ++ if ((retVal = rtl8367c_getAsicRemarkingDscp2Dscp(dscp, pDscp)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_qos_portPriSelIndex_set(rtk_port_t port, rtk_qos_priDecTbl_t index) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if (index >= PRIDECTBL_END ) ++ return RT_ERR_ENTRY_INDEX; ++ ++ if ((retVal = rtl8367c_setAsicPortPriorityDecisionIndex(rtk_switch_port_L2P_get(port), index)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_qos_portPriSelIndex_get(rtk_port_t port, rtk_qos_priDecTbl_t *pIndex) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if ((retVal = rtl8367c_getAsicPortPriorityDecisionIndex(rtk_switch_port_L2P_get(port), pIndex)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rate.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rate.c +new file mode 100644 +index 0000000000..a077e0c5cc +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rate.c +@@ -0,0 +1,607 @@ ++/* ++ * 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 rate module. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++/* 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) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (index > RTK_MAX_METER_ID) ++ return RT_ERR_FILTER_METER_ID; ++ ++ if (type >= METER_TYPE_END) ++ return RT_ERR_INPUT; ++ ++ if (ifg_include >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ switch (type) ++ { ++ case METER_TYPE_KBPS: ++ if (rate > RTL8367C_QOS_RATE_INPUT_MAX_HSG || rate < RTL8367C_QOS_RATE_INPUT_MIN) ++ return RT_ERR_RATE ; ++ ++ if ((retVal = rtl8367c_setAsicShareMeter(index, rate >> 3, ifg_include)) != RT_ERR_OK) ++ return retVal; ++ ++ break; ++ case METER_TYPE_PPS: ++ if (rate > RTL8367C_QOS_PPS_INPUT_MAX || rate < RTL8367C_QOS_PPS_INPUT_MIN) ++ return RT_ERR_RATE ; ++ ++ if ((retVal = rtl8367c_setAsicShareMeter(index, rate, ifg_include)) != RT_ERR_OK) ++ return retVal; ++ ++ break; ++ default: ++ return RT_ERR_INPUT; ++ } ++ ++ /* Set Type */ ++ if ((retVal = rtl8367c_setAsicShareMeterType(index, (rtk_uint32)type)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 regData; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (index > RTK_MAX_METER_ID) ++ return RT_ERR_FILTER_METER_ID; ++ ++ if(NULL == pType) ++ return RT_ERR_NULL_POINTER; ++ ++ if(NULL == pRate) ++ return RT_ERR_NULL_POINTER; ++ ++ if(NULL == pIfg_include) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicShareMeter(index, ®Data, pIfg_include)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicShareMeterType(index, (rtk_uint32 *)pType)) != RT_ERR_OK) ++ return retVal; ++ ++ if(*pType == METER_TYPE_KBPS) ++ *pRate = regData<<3; ++ else ++ *pRate = regData; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_rate_shareMeterBucket_set(rtk_meter_id_t index, rtk_uint32 bucket_size) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (index > RTK_MAX_METER_ID) ++ return RT_ERR_FILTER_METER_ID; ++ ++ if(bucket_size > RTL8367C_METERBUCKETSIZEMAX) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicShareMeterBucketSize(index, bucket_size)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_rate_shareMeterBucket_get(rtk_meter_id_t index, rtk_uint32 *pBucket_size) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (index > RTK_MAX_METER_ID) ++ return RT_ERR_FILTER_METER_ID; ++ ++ if(NULL == pBucket_size) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicShareMeterBucketSize(index, pBucket_size)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++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) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(ifg_include >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if(fc_enable >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if(rtk_switch_isHsgPort(port) == RT_ERR_OK) ++ { ++ if ((rate > RTL8367C_QOS_RATE_INPUT_MAX_HSG) || (rate < RTL8367C_QOS_RATE_INPUT_MIN)) ++ return RT_ERR_QOS_EBW_RATE ; ++ } ++ else ++ { ++ if ((rate > RTL8367C_QOS_RATE_INPUT_MAX) || (rate < RTL8367C_QOS_RATE_INPUT_MIN)) ++ return RT_ERR_QOS_EBW_RATE ; ++ } ++ ++ if ((retVal = rtl8367c_setAsicPortIngressBandwidth(rtk_switch_port_L2P_get(port), rate>>3, ifg_include,fc_enable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++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) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 regData; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(NULL == pIfg_include) ++ return RT_ERR_NULL_POINTER; ++ ++ if(NULL == pFc_enable) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicPortIngressBandwidth(rtk_switch_port_L2P_get(port), ®Data, pIfg_include, pFc_enable)) != RT_ERR_OK) ++ return retVal; ++ ++ *pRate = regData<<3; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_rate_egrBandwidthCtrlRate_set( rtk_port_t port, rtk_rate_t rate, rtk_enable_t ifg_include) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(rtk_switch_isHsgPort(port) == RT_ERR_OK) ++ { ++ if ((rate > RTL8367C_QOS_RATE_INPUT_MAX_HSG) || (rate < RTL8367C_QOS_RATE_INPUT_MIN)) ++ return RT_ERR_QOS_EBW_RATE ; ++ } ++ else ++ { ++ if ((rate > RTL8367C_QOS_RATE_INPUT_MAX) || (rate < RTL8367C_QOS_RATE_INPUT_MIN)) ++ return RT_ERR_QOS_EBW_RATE ; ++ } ++ ++ if (ifg_include >= RTK_ENABLE_END) ++ return RT_ERR_ENABLE; ++ ++ if ((retVal = rtl8367c_setAsicPortEgressRate(rtk_switch_port_L2P_get(port), rate>>3)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicPortEgressRateIfg(ifg_include)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_rate_egrBandwidthCtrlRate_get(rtk_port_t port, rtk_rate_t *pRate, rtk_enable_t *pIfg_include) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 regData; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(NULL == pRate) ++ return RT_ERR_NULL_POINTER; ++ ++ if(NULL == pIfg_include) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicPortEgressRate(rtk_switch_port_L2P_get(port), ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ *pRate = regData << 3; ++ ++ if ((retVal = rtl8367c_getAsicPortEgressRateIfg((rtk_uint32*)pIfg_include)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++ ++/* Function Name: ++ * rtk_rate_egrQueueBwCtrlEnable_get ++ * Description: ++ * Get enable status of egress bandwidth control on specified queue. ++ * Input: ++ * unit - unit id ++ * port - port id ++ * queue - queue id ++ * Output: ++ * pEnable - Pointer to enable status 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_NULL_POINTER - input parameter may be null pointer ++ * Note: ++ * None ++ */ ++rtk_api_ret_t rtk_rate_egrQueueBwCtrlEnable_get(rtk_port_t port, rtk_qid_t queue, rtk_enable_t *pEnable) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ /*for whole port function, the queue value should be 0xFF*/ ++ if (queue != RTK_WHOLE_SYSTEM) ++ return RT_ERR_QUEUE_ID; ++ ++ if(NULL == pEnable) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicAprEnable(rtk_switch_port_L2P_get(port),pEnable))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_rate_egrQueueBwCtrlEnable_set(rtk_port_t port, rtk_qid_t queue, rtk_enable_t enable) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ /*for whole port function, the queue value should be 0xFF*/ ++ if (queue != RTK_WHOLE_SYSTEM) ++ return RT_ERR_QUEUE_ID; ++ ++ if (enable>=RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicAprEnable(rtk_switch_port_L2P_get(port), enable))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_rate_egrQueueBwCtrlRate_get(rtk_port_t port, rtk_qid_t queue, rtk_meter_id_t *pIndex) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 offset_idx; ++ rtk_uint32 phy_port; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if (queue >= RTK_MAX_NUM_OF_QUEUE) ++ return RT_ERR_QUEUE_ID; ++ ++ if(NULL == pIndex) ++ return RT_ERR_NULL_POINTER; ++ ++ phy_port = rtk_switch_port_L2P_get(port); ++ if ((retVal=rtl8367c_getAsicAprMeter(phy_port, queue,&offset_idx))!=RT_ERR_OK) ++ return retVal; ++ ++ *pIndex = offset_idx + ((phy_port%4)*8); ++ ++ return RT_ERR_OK; ++} ++ ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_rate_egrQueueBwCtrlRate_set(rtk_port_t port, rtk_qid_t queue, rtk_meter_id_t index) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 offset_idx; ++ rtk_uint32 phy_port; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if (queue >= RTK_MAX_NUM_OF_QUEUE) ++ return RT_ERR_QUEUE_ID; ++ ++ if (index > RTK_MAX_METER_ID) ++ return RT_ERR_FILTER_METER_ID; ++ ++ phy_port = rtk_switch_port_L2P_get(port); ++ if (index < ((phy_port%4)*8) || index > (7 + (phy_port%4)*8)) ++ return RT_ERR_FILTER_METER_ID; ++ ++ offset_idx = index - ((phy_port%4)*8); ++ ++ if ((retVal=rtl8367c_setAsicAprMeter(phy_port,queue,offset_idx))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rldp.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rldp.c +new file mode 100644 +index 0000000000..d3ca029751 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rldp.c +@@ -0,0 +1,468 @@ ++/* ++ * 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 ++ * ++ */ ++ ++ ++/* ++ * Include Files ++ */ ++#include ++#include ++//#include ++#include ++ ++#include ++#include ++ ++/* ++ * Symbol Definition ++ */ ++ ++ ++/* ++ * Data Declaration ++ */ ++ ++ ++/* ++ * Macro Declaration ++ */ ++ ++ ++/* ++ * 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 ++ */ ++rtk_api_ret_t rtk_rldp_config_set(rtk_rldp_config_t *pConfig) ++{ ++ rtk_api_ret_t retVal; ++ ether_addr_t magic; ++ rtk_uint32 pmsk; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (pConfig->rldp_enable >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if (pConfig->trigger_mode >= RTK_RLDP_TRIGGER_END) ++ return RT_ERR_INPUT; ++ ++ if (pConfig->compare_type >= RTK_RLDP_CMPTYPE_END) ++ return RT_ERR_INPUT; ++ ++ if (pConfig->num_check >= RTK_RLDP_NUM_MAX) ++ return RT_ERR_INPUT; ++ ++ if (pConfig->interval_check >= RTK_RLDP_INTERVAL_MAX) ++ return RT_ERR_INPUT; ++ ++ if (pConfig->num_loop >= RTK_RLDP_NUM_MAX) ++ return RT_ERR_INPUT; ++ ++ if (pConfig->interval_loop >= RTK_RLDP_INTERVAL_MAX) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_getAsicRldpTxPortmask(&pmsk))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRldpTxPortmask(0x00))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRldpTxPortmask(pmsk))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRldp(pConfig->rldp_enable))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRldpTriggerMode(pConfig->trigger_mode))!=RT_ERR_OK) ++ return retVal; ++ ++ memcpy(&magic, &pConfig->magic, sizeof(ether_addr_t)); ++ if ((retVal = rtl8367c_setAsicRldpMagicNum(magic))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRldpCompareRandomNumber(pConfig->compare_type))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRldpCompareRandomNumber(pConfig->compare_type))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRldpCheckingStatePara(pConfig->num_check, pConfig->interval_check))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRldpLoopStatePara(pConfig->num_loop, pConfig->interval_loop))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_rldp_config_get(rtk_rldp_config_t *pConfig) ++{ ++ rtk_api_ret_t retVal; ++ ether_addr_t magic; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ((retVal = rtl8367c_getAsicRldp(&pConfig->rldp_enable))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicRldpTriggerMode(&pConfig->trigger_mode))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicRldpMagicNum(&magic))!=RT_ERR_OK) ++ return retVal; ++ memcpy(&pConfig->magic, &magic, sizeof(ether_addr_t)); ++ ++ if ((retVal = rtl8367c_getAsicRldpCompareRandomNumber(&pConfig->compare_type))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicRldpCompareRandomNumber(&pConfig->compare_type))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicRldpCheckingStatePara(&pConfig->num_check, &pConfig->interval_check))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicRldpLoopStatePara(&pConfig->num_loop, &pConfig->interval_loop))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_rldp_portConfig_set(rtk_port_t port, rtk_rldp_portConfig_t *pPortConfig) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmsk; ++ rtk_uint32 phy_port; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if (pPortConfig->tx_enable>= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ phy_port = rtk_switch_port_L2P_get(port); ++ ++ if ((retVal = rtl8367c_getAsicRldpTxPortmask(&pmsk))!=RT_ERR_OK) ++ return retVal; ++ ++ if (pPortConfig->tx_enable) ++ { ++ pmsk |=(1<tx_enable = ENABLED; ++ } ++ else ++ { ++ pPortConfig->tx_enable = DISABLED; ++ } ++ ++ return RT_ERR_OK; ++} /* end of rtk_rldp_portConfig_get */ ++ ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_rldp_status_get(rtk_rldp_status_t *pStatus) ++{ ++ rtk_api_ret_t retVal; ++ ether_addr_t seed; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ((retVal = rtl8367c_getAsicRldpRandomNumber(&seed))!=RT_ERR_OK) ++ return retVal; ++ memcpy(&pStatus->id, &seed, sizeof(ether_addr_t)); ++ ++ return RT_ERR_OK; ++} /* end of rtk_rldp_status_get */ ++ ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_rldp_portStatus_get(rtk_port_t port, rtk_rldp_portStatus_t *pPortStatus) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmsk; ++ rtk_portmask_t logicalPmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if ((retVal = rtl8367c_getAsicRldpLoopedPortmask(&pmsk))!=RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtk_switch_portmask_P2L_get(pmsk, &logicalPmask)) != RT_ERR_OK) ++ return retVal; ++ ++ if (logicalPmask.bits[0] & (1<loop_status = RTK_RLDP_LOOPSTS_LOOPING; ++ } ++ else ++ { ++ pPortStatus->loop_status = RTK_RLDP_LOOPSTS_NONE; ++ } ++ ++ if ((retVal = rtl8367c_getAsicRldpEnterLoopedPortmask(&pmsk))!=RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtk_switch_portmask_P2L_get(pmsk, &logicalPmask)) != RT_ERR_OK) ++ return retVal; ++ ++ if (logicalPmask.bits[0] & (1<loop_enter = RTK_RLDP_LOOPSTS_LOOPING; ++ } ++ else ++ { ++ pPortStatus->loop_enter = RTK_RLDP_LOOPSTS_NONE; ++ } ++ ++ if ((retVal = rtl8367c_getAsicRldpLeaveLoopedPortmask(&pmsk))!=RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtk_switch_portmask_P2L_get(pmsk, &logicalPmask)) != RT_ERR_OK) ++ return retVal; ++ ++ if (logicalPmask.bits[0] & (1<loop_leave = RTK_RLDP_LOOPSTS_LOOPING; ++ } ++ else ++ { ++ pPortStatus->loop_leave = RTK_RLDP_LOOPSTS_NONE; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++ ++/* 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. Loop status cab't be clean. ++ */ ++rtk_api_ret_t rtk_rldp_portStatus_set(rtk_port_t port, rtk_rldp_portStatus_t *pPortStatus) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmsk; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ pmsk = (pPortStatus->loop_enter)<loop_leave)< ++#include ++#include "./include/rtk_switch.h" ++#include "./include/vlan.h" ++#include "./include/port.h" ++#include "./include/rate.h" ++#include "./include/rtk_hal.h" ++#include "./include/l2.h" ++#include "./include/stat.h" ++#include "./include/igmp.h" ++#include "./include/trap.h" ++#include "./include/leaky.h" ++#include "./include/mirror.h" ++#include "./include/rtl8367c_asicdrv_port.h" ++#include "./include/rtl8367c_asicdrv_mib.h" ++#include "./include/smi.h" ++#include "./include/qos.h" ++#include "./include/trunk.h" ++ ++void rtk_hal_switch_init(void) ++{ ++ if(rtk_switch_init() != 0) ++ printk("rtk_switch_init failed\n"); ++ mdelay(500); ++ /*vlan init */ ++ if (rtk_vlan_init() != 0) ++ printk("rtk_vlan_init failed\n"); ++} ++ ++void rtk_hal_dump_full_mib(void) ++{ ++ rtk_port_t port; ++ rtk_stat_counter_t Cntr; ++ rtk_stat_port_type_t cntr_idx; ++ ++ for (port = UTP_PORT0; port < (UTP_PORT0 + 5); port++) { ++ printk("\nPort%d\n", port); ++ for (cntr_idx = STAT_IfInOctets; cntr_idx < STAT_PORT_CNTR_END; cntr_idx ++) { ++ rtk_stat_port_get(port, cntr_idx, &Cntr); ++ printk("%8llu ", Cntr); ++ if (((cntr_idx%10) == 9)) ++ printk("\n"); ++ } ++ } ++ ++ for (port = EXT_PORT0; port < (EXT_PORT0 + 2); port++) { ++ printk("\nPort%d\n", port); ++ for (cntr_idx = STAT_IfInOctets; cntr_idx < STAT_PORT_CNTR_END; cntr_idx ++) { ++ rtk_stat_port_get(port, cntr_idx, &Cntr); ++ printk("%8llu ", Cntr); ++ if (((cntr_idx%10) == 9)) ++ printk("\n"); ++ } ++ } ++ rtk_stat_global_reset(); ++} ++void rtk_dump_mib_type(rtk_stat_port_type_t cntr_idx) ++{ ++ rtk_port_t port; ++ rtk_stat_counter_t Cntr; ++ ++ for (port = UTP_PORT0; port < (UTP_PORT0 + 5); port++) { ++ rtk_stat_port_get(port, cntr_idx, &Cntr); ++ printk("%8llu", Cntr); ++ } ++ for (port = EXT_PORT0; port < (EXT_PORT0 + 2); port++) { ++ rtk_stat_port_get(port, cntr_idx, &Cntr); ++ printk("%8llu", Cntr); ++ } ++ printk("\n"); ++} ++ ++void rtk_hal_dump_mib(void) ++{ ++ ++ printk("==================%8s%8s%8s%8s%8s%8s%8s\n", "Port0", "Port1", ++ "Port2", "Port3", "Port4", "Port16", "Port17"); ++ /* Get TX Unicast Pkts */ ++ printk("TX Unicast Pkts :"); ++ rtk_dump_mib_type(STAT_IfOutUcastPkts); ++ /* Get TX Multicast Pkts */ ++ printk("TX Multicast Pkts:"); ++ rtk_dump_mib_type(STAT_IfOutMulticastPkts); ++ /* Get TX BroadCast Pkts */ ++ printk("TX BroadCast Pkts:"); ++ rtk_dump_mib_type(STAT_IfOutBroadcastPkts); ++ /* Get TX Collisions */ ++ /* Get TX Puase Frames */ ++ printk("TX Pause Frames :"); ++ rtk_dump_mib_type(STAT_Dot3OutPauseFrames); ++ /* Get TX Drop Events */ ++ /* Get RX Unicast Pkts */ ++ printk("RX Unicast Pkts :"); ++ rtk_dump_mib_type(STAT_IfInUcastPkts); ++ /* Get RX Multicast Pkts */ ++ printk("RX Multicast Pkts:"); ++ rtk_dump_mib_type(STAT_IfInMulticastPkts); ++ /* Get RX Broadcast Pkts */ ++ printk("RX Broadcast Pkts:"); ++ rtk_dump_mib_type(STAT_IfInBroadcastPkts); ++ /* Get RX FCS Erros */ ++ printk("RX FCS Errors :"); ++ rtk_dump_mib_type(STAT_Dot3StatsFCSErrors); ++ /* Get RX Undersize Pkts */ ++ printk("RX Undersize Pkts:"); ++ rtk_dump_mib_type(STAT_EtherStatsUnderSizePkts); ++ /* Get RX Discard Pkts */ ++ printk("RX Discard Pkts :"); ++ rtk_dump_mib_type(STAT_Dot1dTpPortInDiscards); ++ /* Get RX Fragments */ ++ printk("RX Fragments :"); ++ rtk_dump_mib_type(STAT_EtherStatsFragments); ++ /* Get RX Oversize Pkts */ ++ printk("RX Oversize Pkts :"); ++ rtk_dump_mib_type(STAT_EtherOversizeStats); ++ /* Get RX Jabbers */ ++ printk("RX Jabbers :"); ++ rtk_dump_mib_type(STAT_EtherStatsJabbers); ++ /* Get RX Pause Frames */ ++ printk("RX Pause Frames :"); ++ rtk_dump_mib_type(STAT_Dot3InPauseFrames); ++ /* clear MIB */ ++ rtk_stat_global_reset(); ++} ++EXPORT_SYMBOL(rtk_hal_dump_mib); ++ ++int rtk_hal_dump_vlan(void) ++{ ++ rtk_vlan_cfg_t vlan; ++ int i; ++ ++ printk("vid portmap\n"); ++ for (i = 0; i < RTK_SW_VID_RANGE; i++) { ++ rtk_vlan_get(i, &vlan); ++ printk("%3d ", i); ++ printk("%c", ++ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, ++ UTP_PORT0) ? '1' : '-'); ++ printk("%c", ++ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, ++ UTP_PORT1) ? '1' : '-'); ++ printk("%c", ++ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, ++ UTP_PORT2) ? '1' : '-'); ++ printk("%c", ++ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, ++ UTP_PORT3) ? '1' : '-'); ++ printk("%c", ++ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, ++ UTP_PORT4) ? '1' : '-'); ++ printk("%c", ++ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, ++ EXT_PORT0) ? '1' : '-'); ++ printk("%c", ++ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, ++ EXT_PORT1) ? '1' : '-'); ++ printk("\n"); ++ } ++ return 0; ++} ++ ++void rtk_hal_clear_vlan(void) ++{ ++ rtk_api_ret_t ret; ++ ++ ret = rtk_vlan_reset(); ++ if (ret != RT_ERR_OK) ++ printk("rtk_vlan_reset failed\n"); ++} ++ ++int rtk_hal_set_vlan(struct ra_switch_ioctl_data *data) ++{ ++ rtk_vlan_cfg_t vlan; ++ rtk_api_ret_t ret; ++ int i; ++ ++ /* clear vlan entry first */ ++ memset(&vlan, 0x00, sizeof(rtk_vlan_cfg_t)); ++ RTK_PORTMASK_CLEAR(vlan.mbr); ++ RTK_PORTMASK_CLEAR(vlan.untag); ++ rtk_vlan_set(data->vid, &vlan); ++ ++ memset(&vlan, 0x00, sizeof(rtk_vlan_cfg_t)); ++ for (i = 0; i < 5; i++) { ++ if (data->port_map & (1 << i)) { ++ RTK_PORTMASK_PORT_SET(vlan.mbr, i); ++ RTK_PORTMASK_PORT_SET(vlan.untag, i); ++ rtk_vlan_portPvid_set(i, data->vid, 0); ++ } ++ } ++ for (i = 0; i < 2; i++) { ++ if (data->port_map & (1 << (i + 5))) { ++ RTK_PORTMASK_PORT_SET(vlan.mbr, (i + EXT_PORT0)); ++ RTK_PORTMASK_PORT_SET(vlan.untag, (i + EXT_PORT0)); ++ rtk_vlan_portPvid_set((i + EXT_PORT0), data->vid, 0); ++ } ++ } ++ vlan.ivl_en = 1; ++ ret = rtk_vlan_set(data->vid, &vlan); ++ ++ return 0; ++} ++ ++void rtk_hal_vlan_portpvid_set(rtk_port_t port, rtk_vlan_t pvid, rtk_pri_t priority) ++{ ++ rtk_vlan_portPvid_set(port, pvid, priority); ++} ++ ++int rtk_hal_set_ingress_rate(struct ra_switch_ioctl_data *data) ++{ ++ rtk_api_ret_t ret; ++ ++ if (data->on_off == 1) ++ ret = ++ rtk_rate_igrBandwidthCtrlRate_set(data->port, data->bw, 0, ++ 1); ++ else ++ ret = ++ rtk_rate_igrBandwidthCtrlRate_set(data->port, 1048568, 0, ++ 1); ++ ++ return ret; ++} ++ ++int rtk_hal_set_egress_rate(struct ra_switch_ioctl_data *data) ++{ ++ rtk_api_ret_t ret; ++ ++ if (data->on_off == 1) ++ ret = ++ rtk_rate_egrBandwidthCtrlRate_set(data->port, data->bw, 1); ++ else ++ ret = rtk_rate_egrBandwidthCtrlRate_set(data->port, 1048568, 1); ++ ++ return ret; ++} ++ ++void rtk_hal_dump_table(void) ++{ ++ rtk_uint32 i; ++ rtk_uint32 address = 0; ++ rtk_l2_ucastAddr_t l2_data; ++ rtk_l2_ipMcastAddr_t ipMcastAddr; ++ ++ printk("hash port(0:17) fid vid mac-address\n"); ++ while (1) { ++ if (rtk_l2_addr_next_get(READMETHOD_NEXT_L2UC, UTP_PORT0, &address, &l2_data) != RT_ERR_OK) { ++ break; ++ } else { ++ printk("%03x ", l2_data.address); ++ for (i = 0; i < 5; i++) ++ if ( l2_data.port == i) ++ printk("1"); ++ else ++ printk("-"); ++ for (i = 16; i < 18; i++) ++ if ( l2_data.port == i) ++ printk("1"); ++ else ++ printk("-"); ++ ++ printk(" %2d", l2_data.fid); ++ printk(" %4d", l2_data.cvid); ++ printk(" %02x%02x%02x%02x%02x%02x\n", l2_data.mac.octet[0], ++ l2_data.mac.octet[1], l2_data.mac.octet[2], l2_data.mac.octet[3], ++ l2_data.mac.octet[4], l2_data.mac.octet[5]); ++ address ++; ++ } ++ } ++ ++ address = 0; ++ while (1) { ++ if (rtk_l2_ipMcastAddr_next_get(&address, &ipMcastAddr) != RT_ERR_OK) { ++ break; ++ } else { ++ printk("%03x ", ipMcastAddr.address); ++ for (i = 0; i < 5; i++) ++ printk("%c", RTK_PORTMASK_IS_PORT_SET(ipMcastAddr.portmask, i) ? '1' : '-'); ++ for (i = 16; i < 18; i++) ++ printk("%c", RTK_PORTMASK_IS_PORT_SET(ipMcastAddr.portmask, i) ? '1' : '-'); ++ printk(" "); ++ printk("01005E%06x\n", (ipMcastAddr.dip & 0xefffff)); ++ address ++; ++ } ++ } ++} ++ ++void rtk_hal_clear_table(void) ++{ ++ rtk_api_ret_t ret; ++ ++ ret = rtk_l2_table_clear(); ++ if (ret != RT_ERR_OK) ++ printk("rtk_l2_table_clear failed\n"); ++} ++ ++void rtk_hal_add_table(struct ra_switch_ioctl_data *data) ++{ ++ rtk_api_ret_t ret; ++ rtk_l2_ucastAddr_t l2_entry; ++ rtk_mac_t mac; ++ ++ mac.octet[0] =data->mac[0]; ++ mac.octet[1] =data->mac[1]; ++ mac.octet[2] =data->mac[2]; ++ mac.octet[3] =data->mac[3]; ++ mac.octet[4] =data->mac[4]; ++ mac.octet[5] =data->mac[5]; ++ ++ memset(&l2_entry, 0x00, sizeof(rtk_l2_ucastAddr_t)); ++ l2_entry.port = data->port; ++ l2_entry.ivl = 1; ++ l2_entry.cvid = data->vid; ++ l2_entry.fid = 0; ++ l2_entry.efid = 0; ++ l2_entry.is_static = 1; ++ ret = rtk_l2_addr_add(&mac, &l2_entry); ++ if (ret != RT_ERR_OK) ++ printk("rtk_hal_add_table failed\n"); ++} ++ ++void rtk_hal_del_table(struct ra_switch_ioctl_data *data) ++{ ++ rtk_api_ret_t ret; ++ rtk_l2_ucastAddr_t l2_entry; ++ rtk_mac_t mac; ++ ++ mac.octet[0] =data->mac[0]; ++ mac.octet[1] =data->mac[1]; ++ mac.octet[2] =data->mac[2]; ++ mac.octet[3] =data->mac[3]; ++ mac.octet[4] =data->mac[4]; ++ mac.octet[5] =data->mac[5]; ++ ++ memset(&l2_entry, 0x00, sizeof(rtk_l2_ucastAddr_t)); ++ l2_entry.port = data->port; ++ l2_entry.ivl = 1; ++ l2_entry.cvid = data->vid; ++ l2_entry.fid = 0; ++ l2_entry.efid = 0; ++ ret = rtk_l2_addr_del(&mac, &l2_entry); ++ if (ret != RT_ERR_OK) ++ printk("rtk_hal_add_table failed\n"); ++} ++void rtk_hal_get_phy_status(struct ra_switch_ioctl_data *data) ++{ ++ rtk_port_linkStatus_t linkStatus; ++ rtk_port_speed_t speed; ++ rtk_port_duplex_t duplex; ++ ++ rtk_port_phyStatus_get(data->port, &linkStatus, &speed, &duplex); ++ printk("Port%d Status:\n", data->port); ++ if (linkStatus == 1) { ++ printk("Link Up"); ++ if (speed == 0) ++ printk(" 10M"); ++ else if (speed == 1) ++ printk(" 100M"); ++ else if (speed == 2) ++ printk(" 1000M"); ++ if (duplex == 0) ++ printk(" Half Duplex\n"); ++ else ++ printk(" Full Duplex\n"); ++ } else ++ printk("Link Down\n"); ++ ++} ++ ++void rtk_hal_set_port_mirror(struct ra_switch_ioctl_data *data) ++{ ++ rtk_portmask_t rx_portmask; ++ rtk_portmask_t tx_portmask; ++ rtk_api_ret_t ret; ++ int i; ++ ++ rtk_mirror_portIso_set(ENABLED); ++ RTK_PORTMASK_CLEAR(rx_portmask); ++ RTK_PORTMASK_CLEAR(tx_portmask); ++ for (i = 0; i < 5; i++) ++ if (data->rx_port_map & (1 << i)) ++ RTK_PORTMASK_PORT_SET(rx_portmask, i); ++ for (i = 0; i < 2; i++) ++ if (data->rx_port_map & (1 << (i + 5))) ++ RTK_PORTMASK_PORT_SET(rx_portmask, (i + EXT_PORT0)); ++ ++ RTK_PORTMASK_CLEAR(tx_portmask); ++ for (i = 0; i < 5; i++) ++ if (data->tx_port_map & (1 << i)) ++ RTK_PORTMASK_PORT_SET(tx_portmask, i); ++ for (i = 0; i < 2; i++) ++ if (data->tx_port_map & (1 << (i + 5))) ++ RTK_PORTMASK_PORT_SET(tx_portmask, (i + EXT_PORT0)); ++ ++ ret = rtk_mirror_portBased_set(data->port, &rx_portmask, &tx_portmask); ++ if (!ret) ++ printk("rtk_mirror_portBased_set success\n"); ++} ++ ++void rtk_hal_read_reg(struct ra_switch_ioctl_data *data) ++{ ++ ret_t retVal; ++ ++ retVal = smi_read(data->reg_addr, &data->reg_val); ++ if(retVal != RT_ERR_OK) ++ printk("switch reg read failed\n"); ++ else ++ printk("reg0x%x = 0x%x\n", data->reg_addr, data->reg_val); ++} ++ ++void rtk_hal_write_reg(struct ra_switch_ioctl_data *data) ++{ ++ ret_t retVal; ++ ++ retVal = smi_write(data->reg_addr, data->reg_val); ++ if(retVal != RT_ERR_OK) ++ printk("switch reg write failed\n"); ++ else ++ printk("write switch reg0x%x 0x%x success\n", data->reg_addr, data->reg_val); ++} ++ ++void rtk_hal_get_phy_reg(struct ra_switch_ioctl_data *data) ++{ ++ ret_t retVal; ++ rtk_port_phy_data_t Data; ++ ++ retVal = rtk_port_phyReg_get(data->port, data->reg_addr, &Data); ++ if (retVal == RT_ERR_OK) ++ printk("Get: phy[%d].reg[%d] = 0x%04x\n", data->port, data->reg_addr, Data); ++ else ++ printk("read phy reg failed\n"); ++} ++ ++void rtk_hal_set_phy_reg(struct ra_switch_ioctl_data *data) ++{ ++ ret_t retVal; ++ ++ retVal = rtk_port_phyReg_set(data->port, data->reg_addr, data->reg_val); ++ if (retVal == RT_ERR_OK) ++ printk("Set: phy[%d].reg[%d] = 0x%04x\n", data->port, data->reg_addr, data->reg_val); ++ else ++ printk("write phy reg failed\n"); ++} ++void rtk_hal_qos_en(struct ra_switch_ioctl_data *data) ++{ ++ ++ if (data->on_off == 1) { ++ if (rtk_qos_init(8) != 0) ++ printk("rtk_qos_init(8) failed\n"); ++ } ++ else { ++ if (rtk_qos_init(1) != 0) ++ printk("rtk_qos_init(1) failed\n"); ++ } ++} ++ ++void rtk_hal_qos_set_table2type(struct ra_switch_ioctl_data *data) ++{ ++ rtk_api_ret_t ret; ++ rtk_priority_select_t PriDec; ++ ++ /* write all pri to 0 */ ++ PriDec.port_pri = 0; ++ PriDec.dot1q_pri = 0; ++ PriDec.acl_pri = 0; ++ PriDec.cvlan_pri = 0; ++ PriDec.svlan_pri = 0; ++ PriDec.dscp_pri = 0; ++ PriDec.dmac_pri = 0; ++ PriDec.smac_pri = 0; ++ ++ if (data->qos_type == 0) ++ PriDec.port_pri = 1; ++ else if (data->qos_type == 1) ++ PriDec.dot1q_pri = 1; ++ else if (data->qos_type == 2) ++ PriDec.acl_pri = 1; ++ else if (data->qos_type == 3) ++ PriDec.dscp_pri = 1; ++ else if (data->qos_type == 4) ++ PriDec.cvlan_pri = 1; ++ else if (data->qos_type == 5) ++ PriDec.svlan_pri = 1; ++ else if (data->qos_type == 6) ++ PriDec.dmac_pri = 1; ++ else if (data->qos_type == 7) ++ PriDec.smac_pri = 1; ++ ++ if (data->qos_table_idx == 0) ++ ret = rtk_qos_priSel_set(PRIDECTBL_IDX0, &PriDec); ++ else ++ ret = rtk_qos_priSel_set(PRIDECTBL_IDX1, &PriDec); ++ ++ if (ret != 0) ++ printk("rtk_qos_priSel_set failed\n"); ++ ++} ++ ++void rtk_hal_qos_get_table2type(struct ra_switch_ioctl_data *data) ++{ ++ rtk_api_ret_t ret; ++ rtk_priority_select_t PriDec; ++ ++ if (data->qos_table_idx == 0) ++ ret = rtk_qos_priSel_get(PRIDECTBL_IDX0, &PriDec); ++ else ++ ret = rtk_qos_priSel_get(PRIDECTBL_IDX1, &PriDec); ++ ++ if (ret != 0) ++ printk("rtk_qos_priSel_set failed\n"); ++ else { ++ printk("port_pri = %d\n", PriDec.port_pri); ++ printk("dot1q_pri = %d\n", PriDec.dot1q_pri); ++ printk("acl_pri = %d\n", PriDec.acl_pri); ++ printk("dscp_pri = %d\n", PriDec.dscp_pri); ++ printk("cvlan_pri = %d\n", PriDec.cvlan_pri); ++ printk("svlan_pri = %d\n", PriDec.svlan_pri); ++ printk("dmac_pri = %d\n", PriDec.dmac_pri); ++ printk("smac_pri = %d\n", PriDec.smac_pri); ++ } ++} ++ ++void rtk_hal_qos_set_port2table(struct ra_switch_ioctl_data *data) ++{ ++ rtk_api_ret_t ret; ++ ++ ret = rtk_qos_portPriSelIndex_set(data->port, data->qos_table_idx); ++ if (ret != 0) ++ printk("rtk_qos_portPriSelIndex_set failed\n"); ++} ++ ++void rtk_hal_qos_get_port2table(struct ra_switch_ioctl_data *data) ++{ ++ rtk_api_ret_t ret; ++ rtk_qos_priDecTbl_t Index; ++ ++ ret = rtk_qos_portPriSelIndex_get(data->port, &Index); ++ if (ret != 0) ++ printk("rtk_qos_portPriSelIndex_set failed\n"); ++ else ++ printk("port%d belongs to table%d\n", data->port, Index); ++} ++ ++void rtk_hal_qos_set_port2pri(struct ra_switch_ioctl_data *data) ++{ ++ rtk_api_ret_t ret; ++ ++ ret = rtk_qos_portPri_set(data->port, data->qos_pri); ++ if (ret != 0) ++ printk("rtk_qos_portPri_set failed\n"); ++} ++ ++void rtk_hal_qos_get_port2pri(struct ra_switch_ioctl_data *data) ++{ ++ rtk_api_ret_t ret; ++ rtk_pri_t Int_pri; ++ ++ ret = rtk_qos_portPri_get(data->port, &Int_pri); ++ if (ret != 0) ++ printk("rtk_qos_portPri_set failed\n"); ++ else ++ printk("port%d priority = %d\n", data->port, Int_pri); ++} ++ ++void rtk_hal_qos_set_dscp2pri(struct ra_switch_ioctl_data *data) ++{ ++ rtk_api_ret_t ret; ++ ++ ret = rtk_qos_dscpPriRemap_set(data->qos_dscp, data->qos_pri); ++ if (ret != 0) ++ printk("rtk_qos_dscpPriRemap_set failed\n"); ++} ++ ++void rtk_hal_qos_get_dscp2pri(struct ra_switch_ioctl_data *data) ++{ ++ rtk_api_ret_t ret; ++ rtk_pri_t Int_pri; ++ ++ ret = rtk_qos_dscpPriRemap_get(data->qos_dscp, &Int_pri); ++ if (ret != 0) ++ printk("rtk_qos_dscpPriRemap_set failed\n"); ++ else ++ printk("dscp%d priority is %d\n", data->qos_dscp, Int_pri); ++} ++ ++void rtk_hal_qos_set_pri2queue(struct ra_switch_ioctl_data *data) ++{ ++ rtk_api_ret_t ret; ++ rtk_qos_pri2queue_t pri2qid; ++ ++ ret = rtk_qos_priMap_get(8, &pri2qid); ++ pri2qid.pri2queue[data->qos_queue_num] = data->qos_pri; ++ ret = rtk_qos_priMap_set(8, &pri2qid); ++ if (ret != 0) ++ printk("rtk_qos_priMap_set failed\n"); ++} ++ ++void rtk_hal_qos_get_pri2queue(struct ra_switch_ioctl_data *data) ++{ ++ int i; ++ rtk_api_ret_t ret; ++ rtk_qos_pri2queue_t pri2qid; ++ ++ ret = rtk_qos_priMap_get(8, &pri2qid); ++ if (ret != 0) ++ printk("rtk_qos_priMap_get failed\n"); ++ else { ++ for (i = 0; i < 8; i++) ++ printk("pri2qid.pri2queue[%d] = %d\n", i, pri2qid.pri2queue[i]); ++ } ++} ++ ++void rtk_hal_qos_set_queue_weight(struct ra_switch_ioctl_data *data) ++{ ++ rtk_api_ret_t ret; ++ rtk_qos_queue_weights_t qweights; ++ ++ ret = rtk_qos_schedulingQueue_get(data->port, &qweights); ++ qweights.weights[data->qos_queue_num] = data->qos_weight; ++ ret = rtk_qos_schedulingQueue_set(data->port, &qweights); ++ if (ret != 0) ++ printk("rtk_qos_schedulingQueue_set failed\n"); ++} ++ ++void rtk_hal_qos_get_queue_weight(struct ra_switch_ioctl_data *data) ++{ ++ int i; ++ rtk_api_ret_t ret; ++ rtk_qos_queue_weights_t qweights; ++ ++ ret = rtk_qos_schedulingQueue_get(data->port, &qweights); ++ if (ret != 0) ++ printk("rtk_qos_schedulingQueue_get failed\n"); ++ else { ++ printk("=== Port%d queue weight ===\n", data->port); ++ for (i = 0; i < 8; i++) ++ printk("qweights.weights[%d] = %d\n",i ,qweights.weights[i]); ++ } ++} ++ ++void rtk_hal_enable_igmpsnoop(struct ra_switch_ioctl_data *data) ++{ ++ rtk_api_ret_t ret; ++ rtk_portmask_t pmask; ++ ++ ++ ret = rtk_igmp_init(); ++ if (data->on_off == 1) { ++ RTK_PORTMASK_CLEAR(pmask); ++ RTK_PORTMASK_PORT_SET(pmask, EXT_PORT0); ++ ret |= rtk_igmp_static_router_port_set(&pmask); ++ ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_IGMPv1, IGMP_ACTION_FORWARD); ++ ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_IGMPv2, IGMP_ACTION_FORWARD); ++ ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_MLDv1, IGMP_ACTION_FORWARD); ++ ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_IGMPv1, IGMP_ACTION_FORWARD); ++ ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_IGMPv2, IGMP_ACTION_FORWARD); ++ ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_MLDv1, IGMP_ACTION_FORWARD); ++ ret |= rtk_igmp_protocol_set(UTP_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); ++ ret |= rtk_igmp_protocol_set(UTP_PORT1, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); ++ ret |= rtk_igmp_protocol_set(UTP_PORT2, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); ++ ret |= rtk_igmp_protocol_set(UTP_PORT3, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); ++ ret |= rtk_igmp_protocol_set(EXT_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); ++ ++ ret |= rtk_leaky_vlan_set(LEAKY_IPMULTICAST, ENABLED); ++ ret |= rtk_l2_ipMcastForwardRouterPort_set(DISABLED); ++ /* drop unknown multicast packets*/ ++ /* ret |= rtk_trap_unknownMcastPktAction_set(UTP_PORT4, MCAST_IPV4, MCAST_ACTION_DROP);*/ ++ } else { ++ RTK_PORTMASK_CLEAR(pmask); ++ RTK_PORTMASK_PORT_SET(pmask, EXT_PORT0); ++ RTK_PORTMASK_PORT_SET(pmask, EXT_PORT1); ++ ret |= rtk_igmp_protocol_set(UTP_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); ++ ret |= rtk_igmp_protocol_set(UTP_PORT1, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); ++ ret |= rtk_igmp_protocol_set(UTP_PORT2, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); ++ ret |= rtk_igmp_protocol_set(UTP_PORT3, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); ++ ret |= rtk_igmp_protocol_set(EXT_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); ++ ++ ret |= rtk_igmp_static_router_port_set(&pmask); ++ } ++ if(ret != RT_ERR_OK) ++ printk("enable switch igmpsnoop failed\n"); ++} ++ ++void rtk_hal_disable_igmpsnoop(void) ++{ ++ if (rtk_igmp_state_set(DISABLED) != RT_ERR_OK) ++ printk("Disable IGMP SNOOPING failed\n"); ++} ++ ++rtk_api_ret_t rtk_port_phyTestMode_set(rtk_port_t port, rtk_port_phy_test_mode_t mode) ++{ ++ rtk_uint32 data, regData, i; ++ rtk_api_ret_t retVal; ++ ++ RTK_CHK_PORT_IS_UTP(port); ++ ++ if(mode >= PHY_TEST_MODE_END) ++ return RT_ERR_INPUT; ++ ++ if( (mode == PHY_TEST_MODE_2) || (mode == PHY_TEST_MODE_3) ) ++ return RT_ERR_INPUT; ++ ++ if (PHY_TEST_MODE_NORMAL != mode) ++ { ++ /* Other port should be Normal mode */ ++ RTK_SCAN_ALL_LOG_PORT(i) ++ { ++ if(rtk_switch_isUtpPort(i) == RT_ERR_OK) ++ { ++ if(i != port) ++ { ++ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(i), 9, &data)) != RT_ERR_OK) ++ return retVal; ++ ++ if((data & 0xE000) != 0) ++ return RT_ERR_NOT_ALLOWED; ++ } ++ } ++ } ++ } ++ ++ if ((retVal = rtl8367c_getAsicPHYReg(rtk_switch_port_L2P_get(port), 9, &data)) != RT_ERR_OK) ++ return retVal; ++ ++ data &= ~0xE000; ++ data |= (mode << 13); ++ if ((retVal = rtl8367c_setAsicPHYReg(rtk_switch_port_L2P_get(port), 9, data)) != RT_ERR_OK) ++ return retVal; ++ ++ if (PHY_TEST_MODE_4 == mode) ++ { ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (regData == 0x0276) || (regData == 0x0597) ) ++ { ++ if ((retVal = rtl8367c_setAsicPHYOCPReg(rtk_switch_port_L2P_get(port), 0xbcc2, 0xF4F4)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ if( (regData == 0x6367) ) ++ { ++ if ((retVal = rtl8367c_setAsicPHYOCPReg(rtk_switch_port_L2P_get(port), 0xa436, 0x80c1)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicPHYOCPReg(rtk_switch_port_L2P_get(port), 0xa438, 0xfe00)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ ++ return RT_ERR_OK; ++} ++ ++void rtk_hal_set_phy_test_mode(struct ra_switch_ioctl_data *data) ++{ ++ rtk_api_ret_t ret; ++ ++ ret = rtk_port_phyTestMode_set(data->port, data->mode); ++ if (ret != RT_ERR_OK) ++ printk("rtk_port_phyTestMode_set failed\n"); ++ else ++ printk("set port%d in test mode %d.\n", data->port, data->mode); ++} ++ ++void rtk_hal_set_port_trunk(struct ra_switch_ioctl_data *data) ++{ ++ ++ rtk_api_ret_t ret; ++ rtk_portmask_t member; ++ int i; ++ ++ RTK_PORTMASK_CLEAR(member); ++ for (i = 0; i < 4; i++) { ++ if (data->port_map & (1 << i)) ++ RTK_PORTMASK_PORT_SET(member, i); ++ } ++ ++ ret = rtk_trunk_port_set(TRUNK_GROUP0, &member); ++ if (ret != RT_ERR_OK) ++ printk("rtk_trunk_port_set failed\n"); ++ ++ ret = rtk_trunk_distributionAlgorithm_set(RTK_WHOLE_SYSTEM, 0x7F); ++ if (ret != RT_ERR_OK) ++ printk("rtk_trunk_distributionAlgorithm_set failed\n"); ++} ++ ++void rtk_hal_vlan_tag(struct ra_switch_ioctl_data *data) ++{ ++ rtk_api_ret_t ret; ++ rtk_vlan_cfg_t vlan; ++ ++ ret = rtk_vlan_get(data->vid, &vlan); ++ if (ret != RT_ERR_OK) ++ printk("rtk_vlan_get failed\n"); ++ else { ++ if (data->on_off == 0) ++ RTK_PORTMASK_PORT_SET(vlan.untag, data->port); ++ else ++ RTK_PORTMASK_PORT_CLEAR(vlan.untag, data->port); ++ ++ ret = rtk_vlan_set(data->vid, &vlan); ++ if (ret != RT_ERR_OK) ++ printk("rtk_vlan_set failed\n"); ++ } ++} ++ ++void rtk_hal_vlan_mode(struct ra_switch_ioctl_data *data) ++{ ++ rtk_vlan_cfg_t vlan1, vlan2; ++ rtk_api_ret_t ret; ++ ++ ret = rtk_vlan_get(1, &vlan1); ++ if (ret != RT_ERR_OK) ++ printk("rtk_vlan_get failed\n"); ++ ++ ret = rtk_vlan_get(2, &vlan2); ++ if (ret != RT_ERR_OK) ++ printk("rtk_vlan_get failed\n"); ++ ++ if (data->mode == 0) { //ivl ++ vlan1.ivl_en = 1; ++ vlan1.fid_msti = 0; ++ rtk_vlan_set(1, &vlan1); ++ vlan2.ivl_en = 1; ++ vlan2.fid_msti = 0; ++ rtk_vlan_set(2, &vlan2); ++ } else if(data->mode == 1) {//svl ++ vlan1.ivl_en = 0; ++ vlan1.fid_msti = 0; ++ rtk_vlan_set(1, &vlan1); ++ vlan2.ivl_en = 0; ++ vlan2.fid_msti = 1; ++ rtk_vlan_set(2, &vlan2); ++ } else ++ printk("mode not supported\n"); ++} +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtk_switch.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtk_switch.c +new file mode 100644 +index 0000000000..0bb0db0776 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtk_switch.c +@@ -0,0 +1,1796 @@ ++/* ++ * 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. ++ * ++ */ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if defined(FORCE_PROBE_RTL8367C) ++static init_state_t init_state = INIT_COMPLETED; ++#elif defined(FORCE_PROBE_RTL8370B) ++static init_state_t init_state = INIT_COMPLETED; ++#elif defined(FORCE_PROBE_RTL8364B) ++static init_state_t init_state = INIT_COMPLETED; ++#elif defined(FORCE_PROBE_RTL8363SC_VB) ++static init_state_t init_state = INIT_COMPLETED; ++#else ++static init_state_t init_state = INIT_NOT_COMPLETED; ++#endif ++ ++#define AUTO_PROBE (!defined(FORCE_PROBE_RTL8367C) && !defined(FORCE_PROBE_RTL8370B) && !defined(FORCE_PROBE_RTL8364B) && !defined(FORCE_PROBE_RTL8363SC_VB)) ++ ++#if (AUTO_PROBE || defined(FORCE_PROBE_RTL8367C)) ++static rtk_switch_halCtrl_t rtl8367c_hal_Ctrl = ++{ ++ /* Switch Chip */ ++ CHIP_RTL8367C, ++ ++ /* Logical to Physical */ ++ {0, 1, 2, 3, 4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ++ 6, 7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, ++ ++ /* Physical to Logical */ ++ {UTP_PORT0, UTP_PORT1, UTP_PORT2, UTP_PORT3, UTP_PORT4, UNDEFINE_PORT, EXT_PORT0, EXT_PORT1, ++ UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, ++ UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, ++ UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT}, ++ ++ /* Port Type */ ++ {UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, ++ UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, ++ EXT_PORT, EXT_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, ++ UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT}, ++ ++ /* PTP port */ ++ {1, 1, 1, 1, 1, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0 }, ++ ++ /* Valid port mask */ ++ ( (0x1 << UTP_PORT0) | (0x1 << UTP_PORT1) | (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) | (0x1 << UTP_PORT4) | (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), ++ ++ /* Valid UTP port mask */ ++ ( (0x1 << UTP_PORT0) | (0x1 << UTP_PORT1) | (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) | (0x1 << UTP_PORT4) ), ++ ++ /* Valid EXT port mask */ ++ ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), ++ ++ /* Valid CPU port mask */ ++ 0x00, ++ ++ /* Minimum physical port number */ ++ 0, ++ ++ /* Maxmum physical port number */ ++ 7, ++ ++ /* Physical port mask */ ++ 0xDF, ++ ++ /* Combo Logical port ID */ ++ 4, ++ ++ /* HSG Logical port ID */ ++ EXT_PORT0, ++ ++ /* SGMII Logical portmask */ ++ (0x1 << EXT_PORT0), ++ ++ /* Max Meter ID */ ++ 31, ++ ++ /* MAX LUT Address Number */ ++ 2112, ++ ++ /* Trunk Group Mask */ ++ 0x03 ++}; ++#endif ++ ++#if (AUTO_PROBE || defined(FORCE_PROBE_RTL8370B)) ++static rtk_switch_halCtrl_t rtl8370b_hal_Ctrl = ++{ ++ /* Switch Chip */ ++ CHIP_RTL8370B, ++ ++ /* Logical to Physical */ ++ {0, 1, 2, 3, 4, 5, 6, 7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ++ 8, 9, 10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, ++ ++ /* Physical to Logical */ ++ {UTP_PORT0, UTP_PORT1, UTP_PORT2, UTP_PORT3, UTP_PORT4, UTP_PORT5, UTP_PORT6, UTP_PORT7, ++ EXT_PORT0, EXT_PORT1, EXT_PORT2, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, ++ UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, ++ UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT}, ++ ++ /* Port Type */ ++ {UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, UTP_PORT, ++ UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, ++ EXT_PORT, EXT_PORT, EXT_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, ++ UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT}, ++ ++ /* PTP port */ ++ {1, 1, 1, 1, 1, 1, 1, 1, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 1, 1, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0 }, ++ ++ /* Valid port mask */ ++ ( (0x1 << UTP_PORT0) | (0x1 << UTP_PORT1) | (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) | (0x1 << UTP_PORT4) | (0x1 << UTP_PORT5) | (0x1 << UTP_PORT6) | (0x1 << UTP_PORT7) | (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) | (0x1 << EXT_PORT2) ), ++ ++ /* Valid UTP port mask */ ++ ( (0x1 << UTP_PORT0) | (0x1 << UTP_PORT1) | (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) | (0x1 << UTP_PORT4) | (0x1 << UTP_PORT5) | (0x1 << UTP_PORT6) | (0x1 << UTP_PORT7) ), ++ ++ /* Valid EXT port mask */ ++ ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) | (0x1 << EXT_PORT2) ), ++ ++ /* Valid CPU port mask */ ++ (0x1 << EXT_PORT2), ++ ++ /* Minimum physical port number */ ++ 0, ++ ++ /* Maxmum physical port number */ ++ 10, ++ ++ /* Physical port mask */ ++ 0x7FF, ++ ++ /* Combo Logical port ID */ ++ 7, ++ ++ /* HSG Logical port ID */ ++ EXT_PORT1, ++ ++ /* SGMII Logical portmask */ ++ ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), ++ ++ /* Max Meter ID */ ++ 63, ++ ++ /* MAX LUT Address Number 4096 + 64*/ ++ 4160, ++ ++ /* Trunk Group Mask */ ++ 0x07 ++}; ++#endif ++ ++#if (AUTO_PROBE || defined(FORCE_PROBE_RTL8364B)) ++static rtk_switch_halCtrl_t rtl8364b_hal_Ctrl = ++{ ++ /* Switch Chip */ ++ CHIP_RTL8364B, ++ ++ /* Logical to Physical */ ++ {0xFF, 1, 0xFF, 3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ++ 6, 7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, ++ ++ /* Physical to Logical */ ++ {UNDEFINE_PORT, UTP_PORT1, UNDEFINE_PORT, UTP_PORT3, UNDEFINE_PORT, UNDEFINE_PORT, EXT_PORT0, EXT_PORT1, ++ UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, ++ UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, ++ UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT}, ++ ++ /* Port Type */ ++ {UNKNOWN_PORT, UTP_PORT, UNKNOWN_PORT, UTP_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, ++ UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, ++ EXT_PORT, EXT_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, ++ UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT}, ++ ++ /* PTP port */ ++ {0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0 }, ++ ++ /* Valid port mask */ ++ ( (0x1 << UTP_PORT1) | (0x1 << UTP_PORT3) | (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), ++ ++ /* Valid UTP port mask */ ++ ( (0x1 << UTP_PORT1) | (0x1 << UTP_PORT3) ), ++ ++ /* Valid EXT port mask */ ++ ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), ++ ++ /* Valid CPU port mask */ ++ 0x00, ++ ++ /* Minimum physical port number */ ++ 0, ++ ++ /* Maxmum physical port number */ ++ 7, ++ ++ /* Physical port mask */ ++ 0xCA, ++ ++ /* Combo Logical port ID */ ++ 4, ++ ++ /* HSG Logical port ID */ ++ EXT_PORT0, ++ ++ /* SGMII Logical portmask */ ++ ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), ++ ++ /* Max Meter ID */ ++ 32, ++ ++ /* MAX LUT Address Number */ ++ 2112, ++ ++ /* Trunk Group Mask */ ++ 0x01 ++}; ++#endif ++ ++#if (AUTO_PROBE || defined(FORCE_PROBE_RTL8363SC_VB)) ++static rtk_switch_halCtrl_t rtl8363sc_vb_hal_Ctrl = ++{ ++ /* Switch Chip */ ++ CHIP_RTL8363SC_VB, ++ ++ /* Logical to Physical */ ++ {0xFF, 0xFF, 1, 3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ++ 6, 7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, ++ ++ /* Physical to Logical */ ++ {UNDEFINE_PORT, UTP_PORT2, UNDEFINE_PORT, UTP_PORT3, UNDEFINE_PORT, UNDEFINE_PORT, EXT_PORT0, EXT_PORT1, ++ UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, ++ UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, ++ UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT, UNDEFINE_PORT}, ++ ++ /* Port Type */ ++ {UNKNOWN_PORT, UNKNOWN_PORT, UTP_PORT, UTP_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, ++ UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, ++ EXT_PORT, EXT_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, ++ UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT, UNKNOWN_PORT}, ++ ++ /* PTP port */ ++ {0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0 }, ++ ++ /* Valid port mask */ ++ ( (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) | (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), ++ ++ /* Valid UTP port mask */ ++ ( (0x1 << UTP_PORT2) | (0x1 << UTP_PORT3) ), ++ ++ /* Valid EXT port mask */ ++ ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), ++ ++ /* Valid CPU port mask */ ++ 0x00, ++ ++ /* Minimum physical port number */ ++ 0, ++ ++ /* Maxmum physical port number */ ++ 7, ++ ++ /* Physical port mask */ ++ 0xCA, ++ ++ /* Combo Logical port ID */ ++ 4, ++ ++ /* HSG Logical port ID */ ++ EXT_PORT0, ++ ++ /* SGMII Logical portmask */ ++ ( (0x1 << EXT_PORT0) | (0x1 << EXT_PORT1) ), ++ ++ /* Max Meter ID */ ++ 32, ++ ++ /* MAX LUT Address Number */ ++ 2112, ++ ++ /* Trunk Group Mask */ ++ 0x01 ++}; ++#endif ++ ++#if defined(FORCE_PROBE_RTL8367C) ++static rtk_switch_halCtrl_t *halCtrl = &rtl8367c_hal_Ctrl; ++#elif defined(FORCE_PROBE_RTL8370B) ++static rtk_switch_halCtrl_t *halCtrl = &rtl8370b_hal_Ctrl; ++#elif defined(FORCE_PROBE_RTL8364B) ++static rtk_switch_halCtrl_t *halCtrl = &rtl8364b_hal_Ctrl; ++#elif defined(FORCE_PROBE_RTL8363SC_VB) ++static rtk_switch_halCtrl_t *halCtrl = &rtl8363sc_vb_hal_Ctrl; ++#else ++static rtk_switch_halCtrl_t *halCtrl = NULL; ++#endif ++ ++static rtk_uint32 PatchChipData[210][2] = ++{ ++ {0xa436, 0x8028}, {0xa438, 0x6800}, {0xb82e, 0x0001}, {0xa436, 0xb820}, {0xa438, 0x0090}, {0xa436, 0xa012}, {0xa438, 0x0000}, {0xa436, 0xa014}, {0xa438, 0x2c04}, {0xa438, 0x2c6c}, ++ {0xa438, 0x2c75}, {0xa438, 0x2c77}, {0xa438, 0x1414}, {0xa438, 0x1579}, {0xa438, 0x1536}, {0xa438, 0xc432}, {0xa438, 0x32c0}, {0xa438, 0x42d6}, {0xa438, 0x32b5}, {0xa438, 0x003e}, ++ {0xa438, 0x614c}, {0xa438, 0x1569}, {0xa438, 0xd705}, {0xa438, 0x318c}, {0xa438, 0x42d6}, {0xa438, 0xd702}, {0xa438, 0x31ef}, {0xa438, 0x42d6}, {0xa438, 0x629c}, {0xa438, 0x2c04}, ++ {0xa438, 0x653c}, {0xa438, 0x422a}, {0xa438, 0x5d83}, {0xa438, 0xd06a}, {0xa438, 0xd1b0}, {0xa438, 0x1536}, {0xa438, 0xc43a}, {0xa438, 0x32c0}, {0xa438, 0x42d6}, {0xa438, 0x32b5}, ++ {0xa438, 0x003e}, {0xa438, 0x314a}, {0xa438, 0x42fe}, {0xa438, 0x337b}, {0xa438, 0x02d6}, {0xa438, 0x3063}, {0xa438, 0x0c1b}, {0xa438, 0x22fe}, {0xa438, 0xc435}, {0xa438, 0xd0be}, ++ {0xa438, 0xd1f7}, {0xa438, 0xe0f0}, {0xa438, 0x1a40}, {0xa438, 0xa320}, {0xa438, 0xd702}, {0xa438, 0x154a}, {0xa438, 0xc434}, {0xa438, 0x32c0}, {0xa438, 0x42d6}, {0xa438, 0x32b5}, ++ {0xa438, 0x003e}, {0xa438, 0x60ec}, {0xa438, 0x1569}, {0xa438, 0xd705}, {0xa438, 0x619f}, {0xa438, 0xd702}, {0xa438, 0x414f}, {0xa438, 0x2c2e}, {0xa438, 0x610a}, {0xa438, 0xd705}, ++ {0xa438, 0x5e1f}, {0xa438, 0xc43f}, {0xa438, 0xc88b}, {0xa438, 0xd702}, {0xa438, 0x7fe0}, {0xa438, 0x22f3}, {0xa438, 0xd0a0}, {0xa438, 0xd1b2}, {0xa438, 0xd0c3}, {0xa438, 0xd1c3}, ++ {0xa438, 0x8d01}, {0xa438, 0x1536}, {0xa438, 0xc438}, {0xa438, 0xe0f0}, {0xa438, 0x1a80}, {0xa438, 0xd706}, {0xa438, 0x60c0}, {0xa438, 0xd710}, {0xa438, 0x409e}, {0xa438, 0xa804}, ++ {0xa438, 0xad01}, {0xa438, 0x8804}, {0xa438, 0xd702}, {0xa438, 0x32c0}, {0xa438, 0x42d6}, {0xa438, 0x32b5}, {0xa438, 0x003e}, {0xa438, 0x405b}, {0xa438, 0x1576}, {0xa438, 0x7c9c}, ++ {0xa438, 0x60ec}, {0xa438, 0x1569}, {0xa438, 0xd702}, {0xa438, 0x5d43}, {0xa438, 0x31ef}, {0xa438, 0x02fe}, {0xa438, 0x22d6}, {0xa438, 0x590a}, {0xa438, 0xd706}, {0xa438, 0x5c80}, ++ {0xa438, 0xd702}, {0xa438, 0x5c44}, {0xa438, 0x3063}, {0xa438, 0x02d6}, {0xa438, 0x5be2}, {0xa438, 0x22fb}, {0xa438, 0xa240}, {0xa438, 0xa104}, {0xa438, 0x8c03}, {0xa438, 0x8178}, ++ {0xa438, 0xd701}, {0xa438, 0x31ad}, {0xa438, 0x4917}, {0xa438, 0x8102}, {0xa438, 0x2917}, {0xa438, 0xc302}, {0xa438, 0x268a}, {0xa436, 0xA01A}, {0xa438, 0x0000}, {0xa436, 0xA006}, ++ {0xa438, 0x0fff}, {0xa436, 0xA004}, {0xa438, 0x0689}, {0xa436, 0xA002}, {0xa438, 0x0911}, {0xa436, 0xA000}, {0xa438, 0x7302}, {0xa436, 0xB820}, {0xa438, 0x0010}, {0xa436, 0x8412}, ++ {0xa438, 0xaf84}, {0xa438, 0x1eaf}, {0xa438, 0x8427}, {0xa438, 0xaf84}, {0xa438, 0x27af}, {0xa438, 0x8427}, {0xa438, 0x0251}, {0xa438, 0x6802}, {0xa438, 0x8427}, {0xa438, 0xaf04}, ++ {0xa438, 0x0af8}, {0xa438, 0xf9bf}, {0xa438, 0x5581}, {0xa438, 0x0255}, {0xa438, 0x27ef}, {0xa438, 0x310d}, {0xa438, 0x345b}, {0xa438, 0x0fa3}, {0xa438, 0x032a}, {0xa438, 0xe087}, ++ {0xa438, 0xffac}, {0xa438, 0x2040}, {0xa438, 0xbf56}, {0xa438, 0x7402}, {0xa438, 0x5527}, {0xa438, 0xef31}, {0xa438, 0xef20}, {0xa438, 0xe787}, {0xa438, 0xfee6}, {0xa438, 0x87fd}, ++ {0xa438, 0xd488}, {0xa438, 0x88bf}, {0xa438, 0x5674}, {0xa438, 0x0254}, {0xa438, 0xe3e0}, {0xa438, 0x87ff}, {0xa438, 0xf720}, {0xa438, 0xe487}, {0xa438, 0xffaf}, {0xa438, 0x847e}, ++ {0xa438, 0xe087}, {0xa438, 0xffad}, {0xa438, 0x2016}, {0xa438, 0xe387}, {0xa438, 0xfee2}, {0xa438, 0x87fd}, {0xa438, 0xef45}, {0xa438, 0xbf56}, {0xa438, 0x7402}, {0xa438, 0x54e3}, ++ {0xa438, 0xe087}, {0xa438, 0xfff6}, {0xa438, 0x20e4}, {0xa438, 0x87ff}, {0xa438, 0xfdfc}, {0xa438, 0x0400}, {0xa436, 0xb818}, {0xa438, 0x0407}, {0xa436, 0xb81a}, {0xa438, 0xfffd}, ++ {0xa436, 0xb81c}, {0xa438, 0xfffd}, {0xa436, 0xb81e}, {0xa438, 0xfffd}, {0xa436, 0xb832}, {0xa438, 0x0001}, {0xb820, 0x0000}, {0xb82e, 0x0000}, {0xa436, 0x8028}, {0xa438, 0x0000} ++}; ++ ++static rtk_api_ret_t _rtk_switch_init_8367c(void) ++{ ++ rtk_port_t port; ++ rtk_uint32 retVal; ++ rtk_uint32 regData; ++ rtk_uint32 regValue; ++ ++ if( (retVal = rtl8367c_setAsicReg(0x13c2, 0x0249)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_getAsicReg(0x1301, ®Value)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(0x13c2, 0x0000)) != RT_ERR_OK) ++ return retVal; ++ ++ RTK_SCAN_ALL_LOG_PORT(port) ++ { ++ if(rtk_switch_isUtpPort(port) == RT_ERR_OK) ++ { ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_PORT0_EEECFG + (0x20 * port), RTL8367C_PORT0_EEECFG_EEE_100M_OFFSET, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_PORT0_EEECFG + (0x20 * port), RTL8367C_PORT0_EEECFG_EEE_GIGA_500M_OFFSET, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_PORT0_EEECFG + (0x20 * port), RTL8367C_PORT0_EEECFG_EEE_TX_OFFSET, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_PORT0_EEECFG + (0x20 * port), RTL8367C_PORT0_EEECFG_EEE_RX_OFFSET, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xA428, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ regData &= ~(0x0200); ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA428, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ if((regValue & 0x00F0) == 0x00A0) ++ { ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xA5D0, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ regData |= 0x0006; ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA5D0, regData)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ } ++ ++ if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_UTP_FIB_DET, 0x15BB)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x1303, 0x06D6)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x1304, 0x0700)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13E2, 0x003F)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13F9, 0x0090)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x121e, 0x03CA)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x1233, 0x0352)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x1237, 0x00a0)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x123a, 0x0030)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x1239, 0x0084)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x0301, 0x1000)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x1349, 0x001F)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x18e0, 0, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x122b, 14, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBits(0x1305, 0xC000, 3)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++static rtk_api_ret_t _rtk_switch_init_8370b(void) ++{ ++ ret_t retVal; ++ rtk_uint32 regData, tmp = 0; ++ rtk_uint32 i, prf, counter; ++ rtk_uint32 long_link[8] = {0x0210, 0x03e8, 0x0218, 0x03f0, 0x0220, 0x03f8, 0x0208, 0x03e0 }; ++ ++ if((retVal = rtl8367c_setAsicRegBits(0x1205, 0x0300, 3)) != RT_ERR_OK) ++ return retVal; ++ ++ ++ for(i=0; i<8; i++) ++ { ++ if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xa420, ®Data)) != RT_ERR_OK) ++ return retVal; ++ tmp = regData & 0x7 ; ++ if(tmp == 0x3) ++ { ++ prf = 1; ++ if((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb83e, 0x6fa9)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb840, 0xa9)) != RT_ERR_OK) ++ return retVal; ++ for(counter = 0; counter < 10000; counter++); //delay ++ ++ if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xb820, ®Data)) != RT_ERR_OK) ++ return retVal; ++ tmp = regData | 0x10; ++ if ((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb820, tmp)) != RT_ERR_OK) ++ return retVal; ++ for(counter = 0; counter < 10000; counter++); //delay ++ counter = 0; ++ do{ ++ counter = counter + 1; ++ if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xb800, ®Data)) != RT_ERR_OK) ++ return retVal; ++ tmp = regData & 0x40; ++ if(tmp != 0) ++ break; ++ } while (counter < 20); //Wait for patch ready = 1... ++ } ++ } ++ if ((retVal = rtl8367c_getAsicReg(0x1d01, ®Data)) != RT_ERR_OK) ++ return retVal; ++ tmp = regData; ++ tmp = tmp | 0x3BE0; /*Broadcast port enable*/ ++ tmp = tmp & 0xFFE0; /*Phy_id = 0 */ ++ if((retVal = rtl8367c_setAsicReg(0x1d01, tmp)) != RT_ERR_OK) ++ return retVal; ++ ++ for(i=0;i < 210; i++) ++ { ++ if((retVal = rtl8367c_setAsicPHYOCPReg(0, PatchChipData[i][0], PatchChipData[i][1])) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ if((retVal = rtl8367c_setAsicReg(0x1d01, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ for(i=0; i < 8; i++) ++ { ++ if((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xa4b4, long_link[i])) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ if (prf == 0x1) ++ { ++ for(i=0; i<8; i++) ++ { ++ if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xb820, ®Data)) != RT_ERR_OK) ++ return retVal; ++ tmp = regData & 0xFFEF; ++ if ((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb820, tmp)) != RT_ERR_OK) ++ return retVal; ++ ++ for(counter = 0; counter < 10000; counter++); //delay ++ ++ counter = 0; ++ do{ ++ counter = counter + 1; ++ if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xb800, ®Data)) != RT_ERR_OK) ++ return retVal; ++ tmp = regData & 0x40; ++ if( tmp == 0 ) ++ break; ++ } while (counter < 20); //Wait for patch ready = 1... ++ if ((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb83e, 0x6f48)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xb840, 0xfa)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ ++ /*Check phy link status*/ ++ for(i=0; i<8; i++) ++ { ++ if ((retVal = rtl8367c_getAsicPHYOCPReg(i, 0xa400, ®Data)) != RT_ERR_OK) ++ return retVal; ++ tmp = regData & 0x800; ++ if(tmp == 0x0) ++ { ++ tmp = regData | 0x200; ++ if ((retVal = rtl8367c_setAsicPHYOCPReg(i, 0xa400, tmp)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ ++ for(counter = 0; counter < 10000; counter++); //delay ++ ++ return RT_ERR_OK; ++} ++ ++static rtk_api_ret_t _rtk_switch_init_8364b(void) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ /*enable EEE, include mac & phy*/ ++ ++ if ((retVal = rtl8367c_setAsicRegBits(0x38, 0x300, 3)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0x78, 0x300, 3)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0xd8, 0x300, 0)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0xf8, 0x300, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicPHYOCPReg(1, 0xa5d0, 6)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicPHYOCPReg(3, 0xa5d0, 6)) != RT_ERR_OK) ++ return retVal; ++ ++ /*PAD para*/ ++ ++ /*EXT1 PAD Para*/ ++ if ((retVal = rtl8367c_getAsicReg(0x1303, ®Data)) != RT_ERR_OK) ++ return retVal; ++ regData &= 0xFFFFFFFE; ++ regData |= 0x250; ++ if((retVal = rtl8367c_setAsicReg(0x1303, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1304, 0x7000, 0)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0x1304, 0x700, 7)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x38, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*EXT2 PAD Para*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1303, 10, 1)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0x13E2, 0x1ff, 0x26)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x1c0, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ ++ /*SDS PATCH*/ ++ /*SP_CFG_EN_LINK_FIB1G*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Data)) != RT_ERR_OK) ++ return retVal; ++ regData |= 0x4; ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ /*FIB100 Down-speed*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 1, 0, ®Data)) != RT_ERR_OK) ++ return retVal; ++ regData |= 0x20; ++ if((retVal = rtl8367c_setAsicSdsReg(0,1,0, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++static rtk_api_ret_t _rtk_switch_init_8363sc_vb(void) ++{ ++ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ /*enable EEE, include mac & phy*/ ++ ++ if ((retVal = rtl8367c_setAsicRegBits(0x38, 0x300, 3)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0x78, 0x300, 3)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0xd8, 0x300, 0)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0xf8, 0x300, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicPHYOCPReg(1, 0xa5d0, 6)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicPHYOCPReg(3, 0xa5d0, 6)) != RT_ERR_OK) ++ return retVal; ++ ++ /*PAD para*/ ++ ++ /*EXT1 PAD Para*/ ++ if ((retVal = rtl8367c_getAsicReg(0x1303, ®Data)) != RT_ERR_OK) ++ return retVal; ++ regData &= 0xFFFFFFFE; ++ regData |= 0x250; ++ if((retVal = rtl8367c_setAsicReg(0x1303, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1304, 0x7000, 0)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0x1304, 0x700, 7)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x38, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*EXT2 PAD Para*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1303, 10, 1)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0x13E2, 0x1ff, 0x26)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x1c0, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ ++ /*SDS PATCH*/ ++ /*SP_CFG_EN_LINK_FIB1G*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Data)) != RT_ERR_OK) ++ return retVal; ++ regData |= 0x4; ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ /*FIB100 Down-speed*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 1, 0, ®Data)) != RT_ERR_OK) ++ return retVal; ++ regData |= 0x20; ++ if((retVal = rtl8367c_setAsicSdsReg(0,1,0, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_switch_probe ++ * Description: ++ * Probe switch ++ * Input: ++ * None ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Switch probed ++ * RT_ERR_FAILED - Switch Unprobed. ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_switch_probe(switch_chip_t *pSwitchChip) ++{ ++#if defined(FORCE_PROBE_RTL8367C) ++ ++ *pSwitchChip = CHIP_RTL8367C; ++ halCtrl = &rtl8367c_hal_Ctrl; ++ ++#elif defined(FORCE_PROBE_RTL8370B) ++ ++ *pSwitchChip = CHIP_RTL8370B; ++ halCtrl = &rtl8370b_hal_Ctrl; ++ ++#elif defined(FORCE_PROBE_RTL8364B) ++ ++ *pSwitchChip = CHIP_RTL8364B; ++ halCtrl = &rtl8364b_hal_Ctrl; ++ ++#elif defined(FORCE_PROBE_RTL8363SC_VB) ++ ++ *pSwitchChip = CHIP_RTL8363SC_VB; ++ halCtrl = &rtl8363sc_vb_hal_Ctrl; ++ ++#else ++ rtk_uint32 retVal; ++ rtk_uint32 data, regValue; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicReg(0x1300, &data)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicReg(0x1301, ®Value)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) ++ return retVal; ++ ++ switch (data) ++ { ++ case 0x0276: ++ case 0x0597: ++ case 0x6367: ++ *pSwitchChip = CHIP_RTL8367C; ++ halCtrl = &rtl8367c_hal_Ctrl; ++ break; ++ case 0x0652: ++ case 0x6368: ++ *pSwitchChip = CHIP_RTL8370B; ++ halCtrl = &rtl8370b_hal_Ctrl; ++ break; ++ case 0x0801: ++ case 0x6511: ++ if( (regValue & 0x00F0) == 0x0080) ++ { ++ *pSwitchChip = CHIP_RTL8363SC_VB; ++ halCtrl = &rtl8363sc_vb_hal_Ctrl; ++ } ++ else ++ { ++ *pSwitchChip = CHIP_RTL8364B; ++ halCtrl = &rtl8364b_hal_Ctrl; ++ } ++ break; ++ default: ++ return RT_ERR_FAILED; ++ } ++#endif ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_switch_initialState_set(init_state_t state) ++{ ++ if(state >= INIT_STATE_END) ++ return RT_ERR_FAILED; ++ ++ init_state = state; ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_switch_initialState_get ++ * Description: ++ * Get initial status ++ * Input: ++ * None ++ * Output: ++ * None ++ * Return: ++ * INIT_COMPLETED - Initialized ++ * INIT_NOT_COMPLETED - Uninitialized ++ * Note: ++ * ++ */ ++init_state_t rtk_switch_initialState_get(void) ++{ ++ return init_state; ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_switch_logicalPortCheck(rtk_port_t logicalPort) ++{ ++ if(init_state != INIT_COMPLETED) ++ return RT_ERR_NOT_INIT; ++ ++ if(logicalPort >= RTK_SWITCH_PORT_NUM) ++ return RT_ERR_FAILED; ++ ++ if(halCtrl->l2p_port[logicalPort] == 0xFF) ++ return RT_ERR_FAILED; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_switch_isUtpPort(rtk_port_t logicalPort) ++{ ++ if(init_state != INIT_COMPLETED) ++ return RT_ERR_NOT_INIT; ++ ++ if(logicalPort >= RTK_SWITCH_PORT_NUM) ++ return RT_ERR_FAILED; ++ ++ if(halCtrl->log_port_type[logicalPort] == UTP_PORT) ++ return RT_ERR_OK; ++ else ++ return RT_ERR_FAILED; ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_switch_isExtPort(rtk_port_t logicalPort) ++{ ++ if(init_state != INIT_COMPLETED) ++ return RT_ERR_NOT_INIT; ++ ++ if(logicalPort >= RTK_SWITCH_PORT_NUM) ++ return RT_ERR_FAILED; ++ ++ if(halCtrl->log_port_type[logicalPort] == EXT_PORT) ++ return RT_ERR_OK; ++ else ++ return RT_ERR_FAILED; ++} ++ ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_switch_isHsgPort(rtk_port_t logicalPort) ++{ ++ if(init_state != INIT_COMPLETED) ++ return RT_ERR_NOT_INIT; ++ ++ if(logicalPort >= RTK_SWITCH_PORT_NUM) ++ return RT_ERR_FAILED; ++ ++ if(logicalPort == halCtrl->hsg_logical_port) ++ return RT_ERR_OK; ++ else ++ return RT_ERR_FAILED; ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_switch_isSgmiiPort(rtk_port_t logicalPort) ++{ ++ if(init_state != INIT_COMPLETED) ++ return RT_ERR_NOT_INIT; ++ ++ if(logicalPort >= RTK_SWITCH_PORT_NUM) ++ return RT_ERR_FAILED; ++ ++ if( ((0x01 << logicalPort) & halCtrl->sg_logical_portmask) != 0) ++ return RT_ERR_OK; ++ else ++ return RT_ERR_FAILED; ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_switch_isCPUPort(rtk_port_t logicalPort) ++{ ++ if(init_state != INIT_COMPLETED) ++ return RT_ERR_NOT_INIT; ++ ++ if(logicalPort >= RTK_SWITCH_PORT_NUM) ++ return RT_ERR_FAILED; ++ ++ if( ((0x01 << logicalPort) & halCtrl->valid_cpu_portmask) != 0) ++ return RT_ERR_OK; ++ else ++ return RT_ERR_FAILED; ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_switch_isComboPort(rtk_port_t logicalPort) ++{ ++ if(init_state != INIT_COMPLETED) ++ return RT_ERR_NOT_INIT; ++ ++ if(logicalPort >= RTK_SWITCH_PORT_NUM) ++ return RT_ERR_FAILED; ++ ++ if(halCtrl->combo_logical_port == logicalPort) ++ return RT_ERR_OK; ++ else ++ return RT_ERR_FAILED; ++} ++ ++/* Function Name: ++ * rtk_switch_ComboPort_get ++ * Description: ++ * Get Combo port ID ++ * Input: ++ * None ++ * Output: ++ * None ++ * Return: ++ * Port ID of combo port ++ * Note: ++ * ++ */ ++rtk_uint32 rtk_switch_ComboPort_get(void) ++{ ++ return halCtrl->combo_logical_port; ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_switch_isPtpPort(rtk_port_t logicalPort) ++{ ++ if(init_state != INIT_COMPLETED) ++ return RT_ERR_NOT_INIT; ++ ++ if(logicalPort >= RTK_SWITCH_PORT_NUM) ++ return RT_ERR_FAILED; ++ ++ if(halCtrl->ptp_port[logicalPort] == 1) ++ return RT_ERR_OK; ++ else ++ return RT_ERR_FAILED; ++} ++ ++/* Function Name: ++ * rtk_switch_port_L2P_get ++ * Description: ++ * Get physical port ID ++ * Input: ++ * logicalPort - logical port ID ++ * Output: ++ * None ++ * Return: ++ * Physical port ID ++ * Note: ++ * ++ */ ++rtk_uint32 rtk_switch_port_L2P_get(rtk_port_t logicalPort) ++{ ++ if(init_state != INIT_COMPLETED) ++ return UNDEFINE_PHY_PORT; ++ ++ if(logicalPort >= RTK_SWITCH_PORT_NUM) ++ return UNDEFINE_PHY_PORT; ++ ++ return (halCtrl->l2p_port[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: ++ * ++ */ ++rtk_port_t rtk_switch_port_P2L_get(rtk_uint32 physicalPort) ++{ ++ if(init_state != INIT_COMPLETED) ++ return UNDEFINE_PORT; ++ ++ if(physicalPort >= RTK_SWITCH_PORT_NUM) ++ return UNDEFINE_PORT; ++ ++ return (halCtrl->p2l_port[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: ++ * ++ */ ++rtk_api_ret_t rtk_switch_isPortMaskValid(rtk_portmask_t *pPmask) ++{ ++ if(init_state != INIT_COMPLETED) ++ return RT_ERR_NOT_INIT; ++ ++ if(NULL == pPmask) ++ return RT_ERR_NULL_POINTER; ++ ++ if( (pPmask->bits[0] | halCtrl->valid_portmask) != halCtrl->valid_portmask ) ++ return RT_ERR_FAILED; ++ else ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_switch_isPortMaskUtp(rtk_portmask_t *pPmask) ++{ ++ if(init_state != INIT_COMPLETED) ++ return RT_ERR_NOT_INIT; ++ ++ if(NULL == pPmask) ++ return RT_ERR_NULL_POINTER; ++ ++ if( (pPmask->bits[0] | halCtrl->valid_utp_portmask) != halCtrl->valid_utp_portmask ) ++ return RT_ERR_FAILED; ++ else ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_switch_isPortMaskExt(rtk_portmask_t *pPmask) ++{ ++ if(init_state != INIT_COMPLETED) ++ return RT_ERR_NOT_INIT; ++ ++ if(NULL == pPmask) ++ return RT_ERR_NULL_POINTER; ++ ++ if( (pPmask->bits[0] | halCtrl->valid_ext_portmask) != halCtrl->valid_ext_portmask ) ++ return RT_ERR_FAILED; ++ else ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_switch_portmask_L2P_get(rtk_portmask_t *pLogicalPmask, rtk_uint32 *pPhysicalPortmask) ++{ ++ rtk_uint32 log_port, phy_port; ++ ++ if(init_state != INIT_COMPLETED) ++ return RT_ERR_NOT_INIT; ++ ++ if(NULL == pLogicalPmask) ++ return RT_ERR_NULL_POINTER; ++ ++ if(NULL == pPhysicalPortmask) ++ return RT_ERR_NULL_POINTER; ++ ++ if(rtk_switch_isPortMaskValid(pLogicalPmask) != RT_ERR_OK) ++ return RT_ERR_PORT_MASK; ++ ++ /* reset physical port mask */ ++ *pPhysicalPortmask = 0; ++ ++ RTK_PORTMASK_SCAN((*pLogicalPmask), log_port) ++ { ++ phy_port = rtk_switch_port_L2P_get((rtk_port_t)log_port); ++ *pPhysicalPortmask |= (0x0001 << phy_port); ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ * ++ */ ++rtk_api_ret_t rtk_switch_portmask_P2L_get(rtk_uint32 physicalPortmask, rtk_portmask_t *pLogicalPmask) ++{ ++ rtk_uint32 log_port, phy_port; ++ ++ if(init_state != INIT_COMPLETED) ++ return RT_ERR_NOT_INIT; ++ ++ if(NULL == pLogicalPmask) ++ return RT_ERR_NULL_POINTER; ++ ++ RTK_PORTMASK_CLEAR(*pLogicalPmask); ++ ++ for(phy_port = halCtrl->min_phy_port; phy_port <= halCtrl->max_phy_port; phy_port++) ++ { ++ if(physicalPortmask & (0x0001 << phy_port)) ++ { ++ log_port = rtk_switch_port_P2L_get(phy_port); ++ if(log_port != UNDEFINE_PORT) ++ { ++ RTK_PORTMASK_PORT_SET(*pLogicalPmask, log_port); ++ } ++ } ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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) ++{ ++ if(init_state != INIT_COMPLETED) ++ return 0x00; /* No port in portmask */ ++ ++ return (halCtrl->phy_portmask); ++} ++ ++/* 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) ++{ ++ if(init_state != INIT_COMPLETED) ++ return RT_ERR_FAILED; ++ ++ if(NULL == pPortmask) ++ return RT_ERR_NULL_POINTER; ++ ++ pPortmask->bits[0] = halCtrl->valid_portmask; ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_switch_init(void) ++{ ++ rtk_uint32 retVal; ++ rtl8367c_rma_t rmaCfg; ++ switch_chip_t switchChip; ++ ++ /* probe switch */ ++ if((retVal = rtk_switch_probe(&switchChip)) != RT_ERR_OK) ++ return retVal; ++ ++ /* Set initial state */ ++ ++ if((retVal = rtk_switch_initialState_set(INIT_COMPLETED)) != RT_ERR_OK) ++ return retVal; ++ ++ /* Initial */ ++ switch(switchChip) ++ { ++ case CHIP_RTL8367C: ++ if((retVal = _rtk_switch_init_8367c()) != RT_ERR_OK) ++ return retVal; ++ break; ++ case CHIP_RTL8370B: ++ if((retVal = _rtk_switch_init_8370b()) != RT_ERR_OK) ++ return retVal; ++ break; ++ case CHIP_RTL8364B: ++ if((retVal = _rtk_switch_init_8364b()) != RT_ERR_OK) ++ return retVal; ++ break; ++ case CHIP_RTL8363SC_VB: ++ if((retVal = _rtk_switch_init_8363sc_vb()) != RT_ERR_OK) ++ return retVal; ++ break; ++ default: ++ return RT_ERR_CHIP_NOT_FOUND; ++ } ++ ++ /* Set Old max packet length to 16K */ ++ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_MAX_LENGTH_LIMINT_IPG, RTL8367C_MAX_LENTH_CTRL_MASK, 3)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_MAX_LEN_RX_TX, RTL8367C_MAX_LEN_RX_TX_MASK, 3)) != RT_ERR_OK) ++ return retVal; ++ ++ /* ACL Mode */ ++ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_ACL_ACCESS_MODE, RTL8367C_ACL_ACCESS_MODE_MASK, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /* Max rate */ ++ if((retVal = rtk_rate_igrBandwidthCtrlRate_set(halCtrl->hsg_logical_port, RTL8367C_QOS_RATE_INPUT_MAX_HSG, DISABLED, ENABLED)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtk_rate_egrBandwidthCtrlRate_set(halCtrl->hsg_logical_port, RTL8367C_QOS_RATE_INPUT_MAX_HSG, ENABLED)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x03fa, 0x0007)) != RT_ERR_OK) ++ return retVal; ++ ++ /* Change unknown DA to per port setting */ ++ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_PORT_SECURIT_CTRL_REG, RTL8367C_UNKNOWN_UNICAST_DA_BEHAVE_MASK, 3)) != RT_ERR_OK) ++ return retVal; ++ ++ /* LUT lookup OP = 1 */ ++ if ((retVal = rtl8367c_setAsicLutIpLookupMethod(1))!=RT_ERR_OK) ++ return retVal; ++ ++ /* Set RMA */ ++ rmaCfg.portiso_leaky = 0; ++ rmaCfg.vlan_leaky = 0; ++ rmaCfg.keep_format = 0; ++ rmaCfg.trap_priority = 0; ++ rmaCfg.discard_storm_filter = 0; ++ rmaCfg.operation = 0; ++ if ((retVal = rtl8367c_setAsicRma(2, &rmaCfg))!=RT_ERR_OK) ++ return retVal; ++ ++ /* Enable TX Mirror isolation leaky */ ++ if ((retVal = rtl8367c_setAsicPortMirrorIsolationTxLeaky(ENABLED)) != RT_ERR_OK) ++ return retVal; ++ ++ /* INT EN */ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IO_MISC_FUNC, RTL8367C_INT_EN_OFFSET, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ */ ++rtk_api_ret_t rtk_switch_portMaxPktLen_set(rtk_port_t port, rtk_switch_maxPktLen_linkSpeed_t speed, rtk_uint32 cfgId) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(speed >= MAXPKTLEN_LINK_SPEED_END) ++ return RT_ERR_INPUT; ++ ++ if(cfgId > MAXPKTLEN_CFG_ID_MAX) ++ return RT_ERR_INPUT; ++ ++ if((retVal = rtl8367c_setAsicMaxLength(rtk_switch_port_L2P_get(port), (rtk_uint32)speed, cfgId)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ */ ++rtk_api_ret_t rtk_switch_portMaxPktLen_get(rtk_port_t port, rtk_switch_maxPktLen_linkSpeed_t speed, rtk_uint32 *pCfgId) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(speed >= MAXPKTLEN_LINK_SPEED_END) ++ return RT_ERR_INPUT; ++ ++ if(NULL == pCfgId) ++ return RT_ERR_NULL_POINTER; ++ ++ if((retVal = rtl8367c_getAsicMaxLength(rtk_switch_port_L2P_get(port), (rtk_uint32)speed, pCfgId)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ */ ++rtk_api_ret_t rtk_switch_maxPktLenCfg_set(rtk_uint32 cfgId, rtk_uint32 pktLen) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(cfgId > MAXPKTLEN_CFG_ID_MAX) ++ return RT_ERR_INPUT; ++ ++ if(pktLen > RTK_SWITCH_MAX_PKTLEN) ++ return RT_ERR_INPUT; ++ ++ if((retVal = rtl8367c_setAsicMaxLengthCfg(cfgId, pktLen)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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: ++ */ ++rtk_api_ret_t rtk_switch_maxPktLenCfg_get(rtk_uint32 cfgId, rtk_uint32 *pPktLen) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(cfgId > MAXPKTLEN_CFG_ID_MAX) ++ return RT_ERR_INPUT; ++ ++ if(NULL == pPktLen) ++ return RT_ERR_NULL_POINTER; ++ ++ if((retVal = rtl8367c_getAsicMaxLengthCfg(cfgId, pPktLen)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_api_ret_t rtk_switch_greenEthernet_set(rtk_enable_t enable) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 port; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ RTK_SCAN_ALL_LOG_PORT(port) ++ { ++ if(rtk_switch_isUtpPort(port) == RT_ERR_OK) ++ { ++ if ((retVal = rtl8367c_setAsicPowerSaving(rtk_switch_port_L2P_get(port),enable))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicGreenEthernet(rtk_switch_port_L2P_get(port), enable))!=RT_ERR_OK) ++ return retVal; ++ } ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* 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. ++ */ ++rtk_api_ret_t rtk_switch_greenEthernet_get(rtk_enable_t *pEnable) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 port; ++ rtk_uint32 state; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ RTK_SCAN_ALL_LOG_PORT(port) ++ { ++ if(rtk_switch_isUtpPort(port) == RT_ERR_OK) ++ { ++ if ((retVal = rtl8367c_getAsicPowerSaving(rtk_switch_port_L2P_get(port), &state))!=RT_ERR_OK) ++ return retVal; ++ ++ if(state == DISABLED) ++ { ++ *pEnable = DISABLED; ++ return RT_ERR_OK; ++ } ++ ++ if ((retVal = rtl8367c_getAsicGreenEthernet(rtk_switch_port_L2P_get(port), &state))!=RT_ERR_OK) ++ return retVal; ++ ++ if(state == DISABLED) ++ { ++ *pEnable = DISABLED; ++ return RT_ERR_OK; ++ } ++ } ++ } ++ ++ *pEnable = ENABLED; ++ return RT_ERR_OK; ++} ++ ++/* 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 ++ */ ++rtk_port_t rtk_switch_maxLogicalPort_get(void) ++{ ++ rtk_port_t port, maxLogicalPort = 0; ++ ++ /* Check initialization state */ ++ if(rtk_switch_initialState_get() != INIT_COMPLETED) ++ { ++ return UNDEFINE_PORT; ++ } ++ ++ for(port = 0; port < RTK_SWITCH_PORT_NUM; port++) ++ { ++ if( (halCtrl->log_port_type[port] == UTP_PORT) || (halCtrl->log_port_type[port] == EXT_PORT) ) ++ maxLogicalPort = port; ++ } ++ ++ return maxLogicalPort; ++} ++ ++/* 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: ++ * ++ */ ++rtk_uint32 rtk_switch_maxMeterId_get(void) ++{ ++ if(init_state != INIT_COMPLETED) ++ return 0x00; ++ ++ return (halCtrl->max_meter_id); ++} ++ ++/* 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: ++ * ++ */ ++rtk_uint32 rtk_switch_maxLutAddrNumber_get(void) ++{ ++ if(init_state != INIT_COMPLETED) ++ return 0x00; ++ ++ return (halCtrl->max_lut_addr_num); ++} ++ ++/* 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) ++{ ++ if(init_state != INIT_COMPLETED) ++ return 0x00; ++ ++ if( (halCtrl->trunk_group_mask & (0x01 << grpId) ) != 0) ++ return RT_ERR_OK; ++ else ++ return RT_ERR_LA_TRUNK_ID; ++ ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv.c +new file mode 100644 +index 0000000000..7858edcf53 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv.c +@@ -0,0 +1,639 @@ ++/* ++ * 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 : ++ * ++ */ ++ ++#include ++ ++#if defined(RTK_X86_ASICDRV) ++#include ++#else ++#include ++#endif ++ ++/*for driver verify testing only*/ ++#ifdef CONFIG_RTL8367C_ASICDRV_TEST ++#define CLE_VIRTUAL_REG_SIZE 0x10000 ++rtk_uint16 CleVirtualReg[CLE_VIRTUAL_REG_SIZE]; ++#endif ++ ++#if defined(CONFIG_RTL865X_CLE) || defined (RTK_X86_CLE) ++rtk_uint32 cleDebuggingDisplay; ++#endif ++ ++#ifdef EMBEDDED_SUPPORT ++extern void setReg(rtk_uint16, rtk_uint16); ++extern rtk_uint16 getReg(rtk_uint16); ++#endif ++ ++/* Function Name: ++ * rtl8367c_setAsicRegBit ++ * Description: ++ * Set a bit value of a specified register ++ * Input: ++ * reg - register's address ++ * bit - bit location ++ * value - value to set. It can be value 0 or 1. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameter ++ * Note: ++ * Set a bit of a specified register to 1 or 0. ++ */ ++ret_t rtl8367c_setAsicRegBit(rtk_uint32 reg, rtk_uint32 bit, rtk_uint32 value) ++{ ++ ++#if defined(RTK_X86_ASICDRV) ++ rtk_uint32 regData; ++ ret_t retVal; ++ ++ if(bit >= RTL8367C_REGBITLENGTH) ++ return RT_ERR_INPUT; ++ ++ retVal = Access_Read(reg, 2, ®Data); ++ if(TRUE != retVal) ++ return RT_ERR_SMI; ++ ++ if(0x8367B == cleDebuggingDisplay) ++ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); ++ ++ if(value) ++ regData = regData | (1 << bit); ++ else ++ regData = regData & (~(1 << bit)); ++ ++ retVal = Access_Write(reg,2, regData); ++ if(TRUE != retVal) ++ return RT_ERR_SMI; ++ ++ if(0x8367B == cleDebuggingDisplay) ++ PRINT("W[0x%4.4x]=0x%4.4x\n", reg, regData); ++ ++ ++#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) ++ ++ if(bit >= RTL8367C_REGBITLENGTH) ++ return RT_ERR_INPUT; ++ ++ else if(reg >= CLE_VIRTUAL_REG_SIZE) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(value) ++ { ++ CleVirtualReg[reg] = CleVirtualReg[reg] | (1 << bit); ++ } ++ else ++ { ++ CleVirtualReg[reg] = CleVirtualReg[reg] & (~(1 << bit)); ++ } ++ ++ if(0x8367B == cleDebuggingDisplay) ++ PRINT("W[0x%4.4x]=0x%4.4x\n", reg, CleVirtualReg[reg]); ++ ++#elif defined(EMBEDDED_SUPPORT) ++ rtk_uint16 tmp; ++ ++ if(reg > RTL8367C_REGDATAMAX || value > 1) ++ return RT_ERR_INPUT; ++ ++ tmp = getReg(reg); ++ tmp &= (1 << bitIdx); ++ tmp |= (value << bitIdx); ++ setReg(reg, tmp); ++ ++#else ++ rtk_uint32 regData; ++ ret_t retVal; ++ ++ if(bit >= RTL8367C_REGBITLENGTH) ++ return RT_ERR_INPUT; ++ ++ retVal = smi_read(reg, ®Data); ++ if(retVal != RT_ERR_OK) ++ return RT_ERR_SMI; ++ ++ #ifdef CONFIG_RTL865X_CLE ++ if(0x8367B == cleDebuggingDisplay) ++ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); ++ #endif ++ if(value) ++ regData = regData | (1 << bit); ++ else ++ regData = regData & (~(1 << bit)); ++ ++ retVal = smi_write(reg, regData); ++ if(retVal != RT_ERR_OK) ++ return RT_ERR_SMI; ++ ++ #ifdef CONFIG_RTL865X_CLE ++ if(0x8367B == cleDebuggingDisplay) ++ PRINT("W[0x%4.4x]=0x%4.4x\n", reg, regData); ++ #endif ++ ++#endif ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicRegBit ++ * Description: ++ * Get a bit value of a specified register ++ * Input: ++ * reg - register's address ++ * bit - bit location ++ * value - value to get. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameter ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRegBit(rtk_uint32 reg, rtk_uint32 bit, rtk_uint32 *pValue) ++{ ++ ++#if defined(RTK_X86_ASICDRV) ++ ++ rtk_uint32 regData; ++ ret_t retVal; ++ ++ if(bit >= RTL8367C_REGBITLENGTH) ++ return RT_ERR_INPUT; ++ ++ retVal = Access_Read(reg, 2, ®Data); ++ if(TRUE != retVal) ++ return RT_ERR_SMI; ++ ++ *pValue = (regData & (0x1 << bit)) >> bit; ++ ++ if(0x8367B == cleDebuggingDisplay) ++ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); ++ ++#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) ++ ++ if(bit >= RTL8367C_REGBITLENGTH) ++ return RT_ERR_INPUT; ++ ++ if(reg >= CLE_VIRTUAL_REG_SIZE) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ *pValue = (CleVirtualReg[reg] & (0x1 << bit)) >> bit; ++ ++ if(0x8367B == cleDebuggingDisplay) ++ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, CleVirtualReg[reg]); ++ ++#elif defined(EMBEDDED_SUPPORT) ++ rtk_uint16 tmp; ++ ++ if(reg > RTL8367C_REGDATAMAX ) ++ return RT_ERR_INPUT; ++ ++ tmp = getReg(reg); ++ tmp = tmp >> bitIdx; ++ tmp &= 1; ++ *value = tmp; ++#else ++ rtk_uint32 regData; ++ ret_t retVal; ++ ++ retVal = smi_read(reg, ®Data); ++ if(retVal != RT_ERR_OK) ++ return RT_ERR_SMI; ++ ++ #ifdef CONFIG_RTL865X_CLE ++ if(0x8367B == cleDebuggingDisplay) ++ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); ++ #endif ++ ++ *pValue = (regData & (0x1 << bit)) >> bit; ++ ++#endif ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicRegBits ++ * Description: ++ * Set bits value of a specified register ++ * Input: ++ * reg - register's address ++ * bits - bits mask for setting ++ * value - bits value for setting ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameter ++ * Note: ++ * Set bits of a specified register to value. Both bits and value are be treated as bit-mask ++ */ ++ret_t rtl8367c_setAsicRegBits(rtk_uint32 reg, rtk_uint32 bits, rtk_uint32 value) ++{ ++ ++#if defined(RTK_X86_ASICDRV) ++ ++ rtk_uint32 regData; ++ ret_t retVal; ++ rtk_uint32 bitsShift; ++ rtk_uint32 valueShifted; ++ ++ if(bits >= (1 << RTL8367C_REGBITLENGTH) ) ++ return RT_ERR_INPUT; ++ ++ bitsShift = 0; ++ while(!(bits & (1 << bitsShift))) ++ { ++ bitsShift++; ++ if(bitsShift >= RTL8367C_REGBITLENGTH) ++ return RT_ERR_INPUT; ++ } ++ ++ valueShifted = value << bitsShift; ++ if(valueShifted > RTL8367C_REGDATAMAX) ++ return RT_ERR_INPUT; ++ ++ retVal = Access_Read(reg, 2, ®Data); ++ if(TRUE != retVal) ++ return RT_ERR_SMI; ++ ++ if(0x8367B == cleDebuggingDisplay) ++ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); ++ ++ regData = regData & (~bits); ++ regData = regData | (valueShifted & bits); ++ ++ retVal = Access_Write(reg,2, regData); ++ if(TRUE != retVal) ++ return RT_ERR_SMI; ++ ++ if(0x8367B == cleDebuggingDisplay) ++ PRINT("W[0x%4.4x]=0x%4.4x\n", reg, regData); ++ ++#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) ++ rtk_uint32 regData; ++ rtk_uint32 bitsShift; ++ rtk_uint32 valueShifted; ++ ++ if(bits >= (1 << RTL8367C_REGBITLENGTH) ) ++ return RT_ERR_INPUT; ++ ++ bitsShift = 0; ++ while(!(bits & (1 << bitsShift))) ++ { ++ bitsShift++; ++ if(bitsShift >= RTL8367C_REGBITLENGTH) ++ return RT_ERR_INPUT; ++ } ++ valueShifted = value << bitsShift; ++ ++ if(valueShifted > RTL8367C_REGDATAMAX) ++ return RT_ERR_INPUT; ++ ++ if(reg >= CLE_VIRTUAL_REG_SIZE) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ regData = CleVirtualReg[reg] & (~bits); ++ regData = regData | (valueShifted & bits); ++ ++ CleVirtualReg[reg] = regData; ++ ++ if(0x8367B == cleDebuggingDisplay) ++ PRINT("W[0x%4.4x]=0x%4.4x\n", reg, regData); ++ ++#elif defined(EMBEDDED_SUPPORT) ++ rtk_uint32 regData; ++ rtk_uint32 bitsShift; ++ rtk_uint32 valueShifted; ++ ++ if(reg > RTL8367C_REGDATAMAX ) ++ return RT_ERR_INPUT; ++ ++ if(bits >= (1 << RTL8367C_REGBITLENGTH) ) ++ return RT_ERR_INPUT; ++ ++ bitsShift = 0; ++ while(!(bits & (1 << bitsShift))) ++ { ++ bitsShift++; ++ if(bitsShift >= RTL8367C_REGBITLENGTH) ++ return RT_ERR_INPUT; ++ } ++ ++ valueShifted = value << bitsShift; ++ if(valueShifted > RTL8367C_REGDATAMAX) ++ return RT_ERR_INPUT; ++ ++ regData = getReg(reg); ++ regData = regData & (~bits); ++ regData = regData | (valueShifted & bits); ++ ++ setReg(reg, regData); ++ ++#else ++ rtk_uint32 regData; ++ ret_t retVal; ++ rtk_uint32 bitsShift; ++ rtk_uint32 valueShifted; ++ ++ if(bits >= (1 << RTL8367C_REGBITLENGTH) ) ++ return RT_ERR_INPUT; ++ ++ bitsShift = 0; ++ while(!(bits & (1 << bitsShift))) ++ { ++ bitsShift++; ++ if(bitsShift >= RTL8367C_REGBITLENGTH) ++ return RT_ERR_INPUT; ++ } ++ valueShifted = value << bitsShift; ++ ++ if(valueShifted > RTL8367C_REGDATAMAX) ++ return RT_ERR_INPUT; ++ ++ retVal = smi_read(reg, ®Data); ++ if(retVal != RT_ERR_OK) ++ return RT_ERR_SMI; ++ #ifdef CONFIG_RTL865X_CLE ++ if(0x8367B == cleDebuggingDisplay) ++ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); ++ #endif ++ ++ regData = regData & (~bits); ++ regData = regData | (valueShifted & bits); ++ ++ retVal = smi_write(reg, regData); ++ if(retVal != RT_ERR_OK) ++ return RT_ERR_SMI; ++ #ifdef CONFIG_RTL865X_CLE ++ if(0x8367B == cleDebuggingDisplay) ++ PRINT("W[0x%4.4x]=0x%4.4x\n", reg, regData); ++ #endif ++#endif ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicRegBits ++ * Description: ++ * Get bits value of a specified register ++ * Input: ++ * reg - register's address ++ * bits - bits mask for setting ++ * value - bits value for setting ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameter ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRegBits(rtk_uint32 reg, rtk_uint32 bits, rtk_uint32 *pValue) ++{ ++ ++#if defined(RTK_X86_ASICDRV) ++ ++ rtk_uint32 regData; ++ ret_t retVal; ++ rtk_uint32 bitsShift; ++ ++ if(bits >= (1 << RTL8367C_REGBITLENGTH) ) ++ return RT_ERR_INPUT; ++ ++ bitsShift = 0; ++ while(!(bits & (1 << bitsShift))) ++ { ++ bitsShift++; ++ if(bitsShift >= RTL8367C_REGBITLENGTH) ++ return RT_ERR_INPUT; ++ } ++ ++ retVal = Access_Read(reg, 2, ®Data); ++ if(TRUE != retVal) ++ return RT_ERR_SMI; ++ ++ *pValue = (regData & bits) >> bitsShift; ++ ++ if(0x8367B == cleDebuggingDisplay) ++ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); ++ ++#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) ++ rtk_uint32 bitsShift; ++ ++ if(bits >= (1 << RTL8367C_REGBITLENGTH) ) ++ return RT_ERR_INPUT; ++ ++ bitsShift = 0; ++ while(!(bits & (1 << bitsShift))) ++ { ++ bitsShift++; ++ if(bitsShift >= RTL8367C_REGBITLENGTH) ++ return RT_ERR_INPUT; ++ } ++ ++ if(reg >= CLE_VIRTUAL_REG_SIZE) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ *pValue = (CleVirtualReg[reg] & bits) >> bitsShift; ++ ++ if(0x8367B == cleDebuggingDisplay) ++ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, CleVirtualReg[reg]); ++ ++#elif defined(EMBEDDED_SUPPORT) ++ rtk_uint32 regData; ++ rtk_uint32 bitsShift; ++ ++ if(reg > RTL8367C_REGDATAMAX ) ++ return RT_ERR_INPUT; ++ ++ if(bits >= (1UL << RTL8367C_REGBITLENGTH) ) ++ return RT_ERR_INPUT; ++ ++ bitsShift = 0; ++ while(!(bits & (1UL << bitsShift))) ++ { ++ bitsShift++; ++ if(bitsShift >= RTL8367C_REGBITLENGTH) ++ return RT_ERR_INPUT; ++ } ++ ++ regData = getReg(reg); ++ *value = (regData & bits) >> bitsShift; ++ ++#else ++ rtk_uint32 regData; ++ ret_t retVal; ++ rtk_uint32 bitsShift; ++ ++ if(bits>= (1<= RTL8367C_REGBITLENGTH) ++ return RT_ERR_INPUT; ++ } ++ ++ retVal = smi_read(reg, ®Data); ++ if(retVal != RT_ERR_OK) return RT_ERR_SMI; ++ ++ *pValue = (regData & bits) >> bitsShift; ++ #ifdef CONFIG_RTL865X_CLE ++ if(0x8367B == cleDebuggingDisplay) ++ PRINT("R[0x%4.4x]=0x%4.4x\n",reg, regData); ++ #endif ++ ++#endif ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicReg ++ * Description: ++ * Set content of asic register ++ * Input: ++ * reg - register's address ++ * value - Value setting to register ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * The value will be set to ASIC mapping address only and it is always return RT_ERR_OK while setting un-mapping address registers ++ */ ++ret_t rtl8367c_setAsicReg(rtk_uint32 reg, rtk_uint32 value) ++{ ++#if defined(RTK_X86_ASICDRV)/*RTK-CNSD2-NickWu-20061222: for x86 compile*/ ++ ++ ret_t retVal; ++ ++ retVal = Access_Write(reg,2,value); ++ if(TRUE != retVal) return RT_ERR_SMI; ++ ++ if(0x8367B == cleDebuggingDisplay) ++ PRINT("W[0x%4.4x]=0x%4.4x\n",reg,value); ++ ++#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) ++ ++ /*MIBs emulating*/ ++ if(reg == RTL8367C_REG_MIB_ADDRESS) ++ { ++ CleVirtualReg[RTL8367C_MIB_COUNTER_BASE_REG] = 0x1; ++ CleVirtualReg[RTL8367C_MIB_COUNTER_BASE_REG+1] = 0x2; ++ CleVirtualReg[RTL8367C_MIB_COUNTER_BASE_REG+2] = 0x3; ++ CleVirtualReg[RTL8367C_MIB_COUNTER_BASE_REG+3] = 0x4; ++ } ++ ++ if(reg >= CLE_VIRTUAL_REG_SIZE) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ CleVirtualReg[reg] = value; ++ ++ if(0x8367B == cleDebuggingDisplay) ++ PRINT("W[0x%4.4x]=0x%4.4x\n",reg,CleVirtualReg[reg]); ++ ++#elif defined(EMBEDDED_SUPPORT) ++ if(reg > RTL8367C_REGDATAMAX || value > RTL8367C_REGDATAMAX ) ++ return RT_ERR_INPUT; ++ ++ setReg(reg, value); ++ ++#else ++ ret_t retVal; ++ ++ retVal = smi_write(reg, value); ++ if(retVal != RT_ERR_OK) ++ return RT_ERR_SMI; ++ #ifdef CONFIG_RTL865X_CLE ++ if(0x8367B == cleDebuggingDisplay) ++ PRINT("W[0x%4.4x]=0x%4.4x\n",reg,value); ++ #endif ++ ++#endif ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicReg ++ * Description: ++ * Get content of asic register ++ * Input: ++ * reg - register's address ++ * value - Value setting to register ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * Value 0x0000 will be returned for ASIC un-mapping address ++ */ ++ret_t rtl8367c_getAsicReg(rtk_uint32 reg, rtk_uint32 *pValue) ++{ ++ ++#if defined(RTK_X86_ASICDRV) ++ ++ rtk_uint32 regData; ++ ret_t retVal; ++ ++ retVal = Access_Read(reg, 2, ®Data); ++ if(TRUE != retVal) ++ return RT_ERR_SMI; ++ ++ *pValue = regData; ++ ++ if(0x8367B == cleDebuggingDisplay) ++ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); ++ ++#elif defined(CONFIG_RTL8367C_ASICDRV_TEST) ++ if(reg >= CLE_VIRTUAL_REG_SIZE) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ *pValue = CleVirtualReg[reg]; ++ ++ if(0x8367B == cleDebuggingDisplay) ++ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, CleVirtualReg[reg]); ++ ++#elif defined(EMBEDDED_SUPPORT) ++ if(reg > RTL8367C_REGDATAMAX ) ++ return RT_ERR_INPUT; ++ ++ *value = getReg(reg); ++ ++#else ++ rtk_uint32 regData; ++ ret_t retVal; ++ ++ retVal = smi_read(reg, ®Data); ++ if(retVal != RT_ERR_OK) ++ return RT_ERR_SMI; ++ ++ *pValue = regData; ++ #ifdef CONFIG_RTL865X_CLE ++ if(0x8367B == cleDebuggingDisplay) ++ PRINT("R[0x%4.4x]=0x%4.4x\n", reg, regData); ++ #endif ++ ++#endif ++ ++ return RT_ERR_OK; ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_acl.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_acl.c +new file mode 100644 +index 0000000000..d9ccd97118 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_acl.c +@@ -0,0 +1,1173 @@ ++/* ++ * 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 : ACL related function drivers ++ * ++ */ ++#include ++ ++#include ++ ++#if defined(CONFIG_RTL8367C_ASICDRV_TEST) ++rtl8367c_aclrulesmi Rtl8370sVirtualAclRuleTable[RTL8367C_ACLRULENO]; ++rtk_uint16 Rtl8370sVirtualAclActTable[RTL8367C_ACLRULENO][RTL8367C_ACL_ACT_TABLE_LEN]; ++#endif ++ ++/* ++ Exchange structure type define with MMI and SMI ++*/ ++static void _rtl8367c_aclRuleStSmi2User( rtl8367c_aclrule *pAclUser, rtl8367c_aclrulesmi *pAclSmi) ++{ ++ rtk_uint8 *care_ptr, *data_ptr; ++ rtk_uint8 care_tmp, data_tmp; ++ rtk_uint32 i; ++ ++ pAclUser->data_bits.active_portmsk = (((pAclSmi->data_bits_ext.rule_info >> 1) & 0x0007) << 8) | ((pAclSmi->data_bits.rule_info >> 8) & 0x00FF); ++ pAclUser->data_bits.type = (pAclSmi->data_bits.rule_info & 0x0007); ++ pAclUser->data_bits.tag_exist = (pAclSmi->data_bits.rule_info & 0x00F8) >> 3; ++ ++ care_ptr = (rtk_uint8*)&pAclSmi->care_bits; ++ data_ptr = (rtk_uint8*)&pAclSmi->data_bits; ++ ++ for ( i = 0; i < sizeof(struct acl_rule_smi_st); i++) ++ { ++ care_tmp = *(care_ptr + i) ^ (*(data_ptr + i)); ++ data_tmp = *(data_ptr + i); ++ ++ *(care_ptr + i) = care_tmp; ++ *(data_ptr + i) = data_tmp; ++ } ++ ++ care_ptr = (rtk_uint8*)&pAclSmi->care_bits_ext; ++ data_ptr = (rtk_uint8*)&pAclSmi->data_bits_ext; ++ care_tmp = (*care_ptr) ^ (*data_ptr); ++ data_tmp = (*data_ptr); ++ *care_ptr = care_tmp; ++ *data_ptr = data_tmp; ++ ++ for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++) ++ pAclUser->data_bits.field[i] = pAclSmi->data_bits.field[i]; ++ ++ pAclUser->valid = pAclSmi->valid; ++ ++ pAclUser->care_bits.active_portmsk = (((pAclSmi->care_bits_ext.rule_info >> 1) & 0x0007) << 8) | ((pAclSmi->care_bits.rule_info >> 8) & 0x00FF); ++ pAclUser->care_bits.type = (pAclSmi->care_bits.rule_info & 0x0007); ++ pAclUser->care_bits.tag_exist = (pAclSmi->care_bits.rule_info & 0x00F8) >> 3; ++ ++ for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++) ++ pAclUser->care_bits.field[i] = pAclSmi->care_bits.field[i]; ++} ++ ++/* ++ Exchange structure type define with MMI and SMI ++*/ ++static void _rtl8367c_aclRuleStUser2Smi(rtl8367c_aclrule *pAclUser, rtl8367c_aclrulesmi *pAclSmi) ++{ ++ rtk_uint8 *care_ptr, *data_ptr; ++ rtk_uint8 care_tmp, data_tmp; ++ rtk_uint32 i; ++ ++ pAclSmi->data_bits_ext.rule_info = ((pAclUser->data_bits.active_portmsk >> 8) & 0x7) << 1; ++ pAclSmi->data_bits.rule_info = ((pAclUser->data_bits.active_portmsk & 0xff) << 8) | ((pAclUser->data_bits.tag_exist & 0x1F) << 3) | (pAclUser->data_bits.type & 0x07); ++ ++ for(i = 0;i < RTL8367C_ACLRULEFIELDNO; i++) ++ pAclSmi->data_bits.field[i] = pAclUser->data_bits.field[i]; ++ ++ pAclSmi->valid = pAclUser->valid; ++ ++ pAclSmi->care_bits_ext.rule_info = ((pAclUser->care_bits.active_portmsk >> 8) & 0x7) << 1; ++ pAclSmi->care_bits.rule_info = ((pAclUser->care_bits.active_portmsk & 0xff) << 8) | ((pAclUser->care_bits.tag_exist & 0x1F) << 3) | (pAclUser->care_bits.type & 0x07); ++ ++ for(i = 0; i < RTL8367C_ACLRULEFIELDNO; i++) ++ pAclSmi->care_bits.field[i] = pAclUser->care_bits.field[i]; ++ ++ care_ptr = (rtk_uint8*)&pAclSmi->care_bits; ++ data_ptr = (rtk_uint8*)&pAclSmi->data_bits; ++ ++ for ( i = 0; i < sizeof(struct acl_rule_smi_st); i++) ++ { ++ care_tmp = *(care_ptr + i) & ~(*(data_ptr + i)); ++ data_tmp = *(care_ptr + i) & *(data_ptr + i); ++ ++ *(care_ptr + i) = care_tmp; ++ *(data_ptr + i) = data_tmp; ++ } ++ ++ care_ptr = (rtk_uint8*)&pAclSmi->care_bits_ext; ++ data_ptr = (rtk_uint8*)&pAclSmi->data_bits_ext; ++ care_tmp = *care_ptr & ~(*data_ptr); ++ data_tmp = *care_ptr & *data_ptr; ++ ++ *care_ptr = care_tmp; ++ *data_ptr = data_tmp; ++} ++ ++/* ++ Exchange structure type define with MMI and SMI ++*/ ++static void _rtl8367c_aclActStSmi2User(rtl8367c_acl_act_t *pAclUser, rtk_uint16 *pAclSmi) ++{ ++ pAclUser->cact = (pAclSmi[0] & 0x00C0) >> 6; ++ pAclUser->cvidx_cact = (pAclSmi[0] & 0x003F) | (((pAclSmi[3] & 0x0008) >> 3) << 6); ++ ++ pAclUser->sact = (pAclSmi[0] & 0xC000) >> 14; ++ pAclUser->svidx_sact = ((pAclSmi[0] & 0x3F00) >> 8) | (((pAclSmi[3] & 0x0010) >> 4) << 6); ++ ++ pAclUser->aclmeteridx = (pAclSmi[1] & 0x003F) | (((pAclSmi[3] & 0x0020) >> 5) << 6); ++ ++ pAclUser->fwdact = (pAclSmi[1] & 0xC000) >> 14; ++ pAclUser->fwdpmask = ((pAclSmi[1] & 0x3FC0) >> 6) | (((pAclSmi[3] & 0x01C0) >> 6) << 8); ++ ++ pAclUser->priact = (pAclSmi[2] & 0x00C0) >> 6; ++ pAclUser->pridx = (pAclSmi[2] & 0x003F) | (((pAclSmi[3] & 0x0200) >> 9) << 6); ++ ++ pAclUser->aclint = (pAclSmi[2] & 0x2000) >> 13; ++ pAclUser->gpio_en = (pAclSmi[2] & 0x1000) >> 12; ++ pAclUser->gpio_pin = (pAclSmi[2] & 0x0F00) >> 8; ++ ++ pAclUser->cact_ext = (pAclSmi[2] & 0xC000) >> 14; ++ pAclUser->tag_fmt = (pAclSmi[3] & 0x0003); ++ pAclUser->fwdact_ext = (pAclSmi[3] & 0x0004) >> 2; ++} ++ ++/* ++ Exchange structure type define with MMI and SMI ++*/ ++static void _rtl8367c_aclActStUser2Smi(rtl8367c_acl_act_t *pAclUser, rtk_uint16 *pAclSmi) ++{ ++ pAclSmi[0] |= (pAclUser->cvidx_cact & 0x003F); ++ pAclSmi[0] |= (pAclUser->cact & 0x0003) << 6; ++ pAclSmi[0] |= (pAclUser->svidx_sact & 0x003F) << 8; ++ pAclSmi[0] |= (pAclUser->sact & 0x0003) << 14; ++ ++ pAclSmi[1] |= (pAclUser->aclmeteridx & 0x003F); ++ pAclSmi[1] |= (pAclUser->fwdpmask & 0x00FF) << 6; ++ pAclSmi[1] |= (pAclUser->fwdact & 0x0003) << 14; ++ ++ pAclSmi[2] |= (pAclUser->pridx & 0x003F); ++ pAclSmi[2] |= (pAclUser->priact & 0x0003) << 6; ++ pAclSmi[2] |= (pAclUser->gpio_pin & 0x000F) << 8; ++ pAclSmi[2] |= (pAclUser->gpio_en & 0x0001) << 12; ++ pAclSmi[2] |= (pAclUser->aclint & 0x0001) << 13; ++ pAclSmi[2] |= (pAclUser->cact_ext & 0x0003) << 14; ++ ++ pAclSmi[3] |= (pAclUser->tag_fmt & 0x0003); ++ pAclSmi[3] |= (pAclUser->fwdact_ext & 0x0001) << 2; ++ pAclSmi[3] |= ((pAclUser->cvidx_cact & 0x0040) >> 6) << 3; ++ pAclSmi[3] |= ((pAclUser->svidx_sact & 0x0040) >> 6) << 4; ++ pAclSmi[3] |= ((pAclUser->aclmeteridx & 0x0040) >> 6) << 5; ++ pAclSmi[3] |= ((pAclUser->fwdpmask & 0x0700) >> 8) << 6; ++ pAclSmi[3] |= ((pAclUser->pridx & 0x0040) >> 6) << 9; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicAcl ++ * Description: ++ * Set port acl function enable/disable ++ * Input: ++ * port - Physical port number (0~10) ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicAcl(rtk_uint32 port, rtk_uint32 enabled) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_ACL_ENABLE_REG, port, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicAcl ++ * Description: ++ * Get port acl function enable/disable ++ * Input: ++ * port - Physical port number (0~10) ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicAcl(rtk_uint32 port, rtk_uint32* pEnabled) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_ACL_ENABLE_REG, port, pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicAclUnmatchedPermit ++ * Description: ++ * Set port acl function unmatched permit action ++ * Input: ++ * port - Physical port number (0~10) ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicAclUnmatchedPermit(rtk_uint32 port, rtk_uint32 enabled) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_ACL_UNMATCH_PERMIT_REG, port, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicAclUnmatchedPermit ++ * Description: ++ * Get port acl function unmatched permit action ++ * Input: ++ * port - Physical port number (0~10) ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicAclUnmatchedPermit(rtk_uint32 port, rtk_uint32* pEnabled) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_ACL_UNMATCH_PERMIT_REG, port, pEnabled); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicAclRule ++ * Description: ++ * Set acl rule content ++ * Input: ++ * index - ACL rule index (0-95) of 96 ACL rules ++ * pAclRule - ACL rule stucture for setting ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) ++ * Note: ++ * System supported 95 shared 289-bit ACL ingress rule. Index was available at range 0-95 only. ++ * If software want to modify ACL rule, the ACL function should be disable at first or unspecify ++ * acl action will be executed. ++ * One ACL rule structure has three parts setting: ++ * Bit 0-147 Data Bits of this Rule ++ * Bit 148 Valid Bit ++ * Bit 149-296 Care Bits of this Rule ++ * There are four kinds of field in Data Bits and Care Bits: Active Portmask, Type, Tag Exist, and 8 fields ++ */ ++ret_t rtl8367c_setAsicAclRule(rtk_uint32 index, rtl8367c_aclrule* pAclRule) ++{ ++ rtl8367c_aclrulesmi aclRuleSmi; ++ rtk_uint16* tableAddr; ++ rtk_uint32 regAddr; ++ rtk_uint32 regData; ++ rtk_uint32 i; ++ ret_t retVal; ++ ++ if(index > RTL8367C_ACLRULEMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ memset(&aclRuleSmi, 0x00, sizeof(rtl8367c_aclrulesmi)); ++ ++ _rtl8367c_aclRuleStUser2Smi(pAclRule, &aclRuleSmi); ++ ++ /* Write valid bit = 0 */ ++ regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; ++ if(index >= 64) ++ regData = RTL8367C_ACLRULETBADDR2(DATABITS, index); ++ else ++ regData = RTL8367C_ACLRULETBADDR(DATABITS, index); ++ retVal = rtl8367c_setAsicReg(regAddr,regData); ++ if(retVal !=RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_TABLE_ACCESS_WRDATA_REG(RTL8367C_ACLRULETBLEN), 0x1, 0); ++ if(retVal !=RT_ERR_OK) ++ return retVal; ++ ++ regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; ++ regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE, TB_TARGET_ACLRULE); ++ retVal = rtl8367c_setAsicReg(regAddr, regData); ++ if(retVal !=RT_ERR_OK) ++ return retVal; ++ ++ ++ ++ /* Write ACS_ADR register */ ++ regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; ++ if(index >= 64) ++ regData = RTL8367C_ACLRULETBADDR2(CAREBITS, index); ++ else ++ regData = RTL8367C_ACLRULETBADDR(CAREBITS, index); ++ retVal = rtl8367c_setAsicReg(regAddr, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /* Write Care Bits to ACS_DATA registers */ ++ tableAddr = (rtk_uint16*)&aclRuleSmi.care_bits; ++ regAddr = RTL8367C_TABLE_ACCESS_WRDATA_BASE; ++ ++ for(i = 0; i < RTL8367C_ACLRULETBLEN; i++) ++ { ++ regData = *tableAddr; ++ retVal = rtl8367c_setAsicReg(regAddr, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ regAddr++; ++ tableAddr++; ++ } ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_TABLE_ACCESS_WRDATA_REG(RTL8367C_ACLRULETBLEN), (0x0007 << 1), (aclRuleSmi.care_bits_ext.rule_info >> 1) & 0x0007); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /* Write ACS_CMD register */ ++ regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; ++ regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE, TB_TARGET_ACLRULE); ++ retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK,regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ ++ ++ /* Write ACS_ADR register for data bits */ ++ regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; ++ if(index >= 64) ++ regData = RTL8367C_ACLRULETBADDR2(DATABITS, index); ++ else ++ regData = RTL8367C_ACLRULETBADDR(DATABITS, index); ++ ++ retVal = rtl8367c_setAsicReg(regAddr, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /* Write Data Bits to ACS_DATA registers */ ++ tableAddr = (rtk_uint16*)&aclRuleSmi.data_bits; ++ regAddr = RTL8367C_TABLE_ACCESS_WRDATA_BASE; ++ ++ for(i = 0; i < RTL8367C_ACLRULETBLEN; i++) ++ { ++ regData = *tableAddr; ++ retVal = rtl8367c_setAsicReg(regAddr, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ regAddr++; ++ tableAddr++; ++ } ++ ++ retVal = rtl8367c_setAsicRegBit(RTL8367C_TABLE_ACCESS_WRDATA_REG(RTL8367C_ACLRULETBLEN), 0, aclRuleSmi.valid); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_TABLE_ACCESS_WRDATA_REG(RTL8367C_ACLRULETBLEN), (0x0007 << 1), (aclRuleSmi.data_bits_ext.rule_info >> 1) & 0x0007); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /* Write ACS_CMD register for care bits*/ ++ regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; ++ regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE, TB_TARGET_ACLRULE); ++ retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++#ifdef CONFIG_RTL8367C_ASICDRV_TEST ++ memcpy(&Rtl8370sVirtualAclRuleTable[index], &aclRuleSmi, sizeof(rtl8367c_aclrulesmi)); ++#endif ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicAclRule ++ * Description: ++ * Get acl rule content ++ * Input: ++ * index - ACL rule index (0-63) of 64 ACL rules ++ * pAclRule - ACL rule stucture for setting ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-63) ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicAclRule(rtk_uint32 index, rtl8367c_aclrule *pAclRule) ++{ ++ rtl8367c_aclrulesmi aclRuleSmi; ++ rtk_uint32 regAddr, regData; ++ ret_t retVal; ++ rtk_uint16* tableAddr; ++ rtk_uint32 i; ++ ++ if(index > RTL8367C_ACLRULEMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ memset(&aclRuleSmi, 0x00, sizeof(rtl8367c_aclrulesmi)); ++ ++ /* Write ACS_ADR register for data bits */ ++ regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; ++ if(index >= 64) ++ regData = RTL8367C_ACLRULETBADDR2(DATABITS, index); ++ else ++ regData = RTL8367C_ACLRULETBADDR(DATABITS, index); ++ ++ retVal = rtl8367c_setAsicReg(regAddr, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ ++ /* Write ACS_CMD register */ ++ regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; ++ regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ, TB_TARGET_ACLRULE); ++ retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /* Read Data Bits */ ++ regAddr = RTL8367C_TABLE_ACCESS_RDDATA_BASE; ++ tableAddr = (rtk_uint16*)&aclRuleSmi.data_bits; ++ for(i = 0; i < RTL8367C_ACLRULETBLEN; i++) ++ { ++ retVal = rtl8367c_getAsicReg(regAddr, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *tableAddr = regData; ++ ++ regAddr ++; ++ tableAddr ++; ++ } ++ ++ /* Read Valid Bit */ ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_RDDATA_REG(RTL8367C_ACLRULETBLEN), 0, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ aclRuleSmi.valid = regData & 0x1; ++ /* Read active_portmsk_ext Bits */ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_TABLE_ACCESS_RDDATA_REG(RTL8367C_ACLRULETBLEN), 0x7<<1, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ aclRuleSmi.data_bits_ext.rule_info = (regData % 0x0007) << 1; ++ ++ ++ /* Write ACS_ADR register for carebits*/ ++ regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; ++ if(index >= 64) ++ regData = RTL8367C_ACLRULETBADDR2(CAREBITS, index); ++ else ++ regData = RTL8367C_ACLRULETBADDR(CAREBITS, index); ++ ++ retVal = rtl8367c_setAsicReg(regAddr, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /* Write ACS_CMD register */ ++ regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; ++ regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ, TB_TARGET_ACLRULE); ++ retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /* Read Care Bits */ ++ regAddr = RTL8367C_TABLE_ACCESS_RDDATA_BASE; ++ tableAddr = (rtk_uint16*)&aclRuleSmi.care_bits; ++ for(i = 0; i < RTL8367C_ACLRULETBLEN; i++) ++ { ++ retVal = rtl8367c_getAsicReg(regAddr, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *tableAddr = regData; ++ ++ regAddr ++; ++ tableAddr ++; ++ } ++ /* Read active_portmsk_ext care Bits */ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_TABLE_ACCESS_RDDATA_REG(RTL8367C_ACLRULETBLEN), 0x7<<1, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ aclRuleSmi.care_bits_ext.rule_info = (regData & 0x0007) << 1; ++ ++#ifdef CONFIG_RTL8367C_ASICDRV_TEST ++ memcpy(&aclRuleSmi,&Rtl8370sVirtualAclRuleTable[index], sizeof(rtl8367c_aclrulesmi)); ++#endif ++ ++ _rtl8367c_aclRuleStSmi2User(pAclRule, &aclRuleSmi); ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicAclNot ++ * Description: ++ * Set rule comparison result inversion / no inversion ++ * Input: ++ * index - ACL rule index (0-95) of 96 ACL rules ++ * not - 1: inverse, 0: don't inverse ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicAclNot(rtk_uint32 index, rtk_uint32 not) ++{ ++ if(index > RTL8367C_ACLRULEMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(index < 64) ++ return rtl8367c_setAsicRegBit(RTL8367C_ACL_ACTION_CTRL_REG(index), RTL8367C_ACL_OP_NOT_OFFSET(index), not); ++ else ++ return rtl8367c_setAsicRegBit(RTL8367C_ACL_ACTION_CTRL2_REG(index), RTL8367C_ACL_OP_NOT_OFFSET(index), not); ++ ++} ++/* Function Name: ++ * rtl8367c_getAsicAcl ++ * Description: ++ * Get rule comparison result inversion / no inversion ++ * Input: ++ * index - ACL rule index (0-95) of 95 ACL rules ++ * pNot - 1: inverse, 0: don't inverse ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicAclNot(rtk_uint32 index, rtk_uint32* pNot) ++{ ++ if(index > RTL8367C_ACLRULEMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(index < 64) ++ return rtl8367c_getAsicRegBit(RTL8367C_ACL_ACTION_CTRL_REG(index), RTL8367C_ACL_OP_NOT_OFFSET(index), pNot); ++ else ++ return rtl8367c_getAsicRegBit(RTL8367C_ACL_ACTION_CTRL2_REG(index), RTL8367C_ACL_OP_NOT_OFFSET(index), pNot); ++ ++} ++/* Function Name: ++ * rtl8367c_setAsicAclTemplate ++ * Description: ++ * Set fields of a ACL Template ++ * Input: ++ * index - ACL template index(0~4) ++ * pAclType - ACL type stucture for setting ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - Invalid ACL template index(0~4) ++ * Note: ++ * The API can set type field of the 5 ACL rule templates. ++ * Each type has 8 fields. One field means what data in one field of a ACL rule means ++ * 8 fields of ACL rule 0~95 is descripted by one type in ACL group ++ */ ++ret_t rtl8367c_setAsicAclTemplate(rtk_uint32 index, rtl8367c_acltemplate_t* pAclType) ++{ ++ ret_t retVal; ++ rtk_uint32 i; ++ rtk_uint32 regAddr, regData; ++ ++ if(index >= RTL8367C_ACLTEMPLATENO) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ regAddr = RTL8367C_ACL_RULE_TEMPLATE_CTRL_REG(index); ++ ++ for(i = 0; i < (RTL8367C_ACLRULEFIELDNO/2); i++) ++ { ++ regData = pAclType->field[i*2+1]; ++ regData = regData << 8 | pAclType->field[i*2]; ++ ++ retVal = rtl8367c_setAsicReg(regAddr + i, regData); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicAclTemplate ++ * Description: ++ * Get fields of a ACL Template ++ * Input: ++ * index - ACL template index(0~4) ++ * pAclType - ACL type stucture for setting ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - Invalid ACL template index(0~4) ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicAclTemplate(rtk_uint32 index, rtl8367c_acltemplate_t *pAclType) ++{ ++ ret_t retVal; ++ rtk_uint32 i; ++ rtk_uint32 regData, regAddr; ++ ++ if(index >= RTL8367C_ACLTEMPLATENO) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ regAddr = RTL8367C_ACL_RULE_TEMPLATE_CTRL_REG(index); ++ ++ for(i = 0; i < (RTL8367C_ACLRULEFIELDNO/2); i++) ++ { ++ retVal = rtl8367c_getAsicReg(regAddr + i,®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pAclType->field[i*2] = regData & 0xFF; ++ pAclType->field[i*2 + 1] = (regData >> 8) & 0xFF; ++ } ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicAclAct ++ * Description: ++ * Set ACL rule matched Action ++ * Input: ++ * index - ACL rule index (0-95) of 96 ACL rules ++ * pAclAct - ACL action stucture for setting ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicAclAct(rtk_uint32 index, rtl8367c_acl_act_t* pAclAct) ++{ ++ rtk_uint16 aclActSmi[RTL8367C_ACL_ACT_TABLE_LEN]; ++ ret_t retVal; ++ rtk_uint32 regAddr, regData; ++ rtk_uint16* tableAddr; ++ rtk_uint32 i; ++ ++ if(index > RTL8367C_ACLRULEMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ memset(aclActSmi, 0x00, sizeof(rtk_uint16) * RTL8367C_ACL_ACT_TABLE_LEN); ++ _rtl8367c_aclActStUser2Smi(pAclAct, aclActSmi); ++ ++ /* Write ACS_ADR register for data bits */ ++ regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; ++ regData = index; ++ retVal = rtl8367c_setAsicReg(regAddr, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /* Write Data Bits to ACS_DATA registers */ ++ tableAddr = aclActSmi; ++ regAddr = RTL8367C_TABLE_ACCESS_WRDATA_BASE; ++ ++ for(i = 0; i < RTL8367C_ACLACTTBLEN; i++) ++ { ++ regData = *tableAddr; ++ retVal = rtl8367c_setAsicReg(regAddr, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ regAddr++; ++ tableAddr++; ++ } ++ ++ /* Write ACS_CMD register for care bits*/ ++ regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; ++ regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE, TB_TARGET_ACLACT); ++ retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++#ifdef CONFIG_RTL8367C_ASICDRV_TEST ++ memcpy(&Rtl8370sVirtualAclActTable[index][0], aclActSmi, sizeof(rtk_uint16) * RTL8367C_ACL_ACT_TABLE_LEN); ++#endif ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicAclAct ++ * Description: ++ * Get ACL rule matched Action ++ * Input: ++ * index - ACL rule index (0-95) of 96 ACL rules ++ * pAclAct - ACL action stucture for setting ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicAclAct(rtk_uint32 index, rtl8367c_acl_act_t *pAclAct) ++{ ++ rtk_uint16 aclActSmi[RTL8367C_ACL_ACT_TABLE_LEN]; ++ ret_t retVal; ++ rtk_uint32 regAddr, regData; ++ rtk_uint16 *tableAddr; ++ rtk_uint32 i; ++ ++ if(index > RTL8367C_ACLRULEMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ memset(aclActSmi, 0x00, sizeof(rtk_uint16) * RTL8367C_ACL_ACT_TABLE_LEN); ++ ++ /* Write ACS_ADR register for data bits */ ++ regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; ++ regData = index; ++ retVal = rtl8367c_setAsicReg(regAddr, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /* Write ACS_CMD register */ ++ regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; ++ regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ, TB_TARGET_ACLACT); ++ retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /* Read Data Bits */ ++ regAddr = RTL8367C_TABLE_ACCESS_RDDATA_BASE; ++ tableAddr = aclActSmi; ++ for(i = 0; i < RTL8367C_ACLACTTBLEN; i++) ++ { ++ retVal = rtl8367c_getAsicReg(regAddr, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *tableAddr = regData; ++ ++ regAddr ++; ++ tableAddr ++; ++ } ++ ++#ifdef CONFIG_RTL8367C_ASICDRV_TEST ++ memcpy(aclActSmi, &Rtl8370sVirtualAclActTable[index][0], sizeof(rtk_uint16) * RTL8367C_ACL_ACT_TABLE_LEN); ++#endif ++ ++ _rtl8367c_aclActStSmi2User(pAclAct, aclActSmi); ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicAclActCtrl ++ * Description: ++ * Set ACL rule matched Action Control Bits ++ * Input: ++ * index - ACL rule index (0-95) of 96 ACL rules ++ * aclActCtrl - 6 ACL Control Bits ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) ++ * Note: ++ * ACL Action Control Bits Indicate which actions will be take when a rule matches ++ */ ++ret_t rtl8367c_setAsicAclActCtrl(rtk_uint32 index, rtk_uint32 aclActCtrl) ++{ ++ ret_t retVal; ++ ++ if(index > RTL8367C_ACLRULEMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(index >= 64) ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_ACL_ACTION_CTRL2_REG(index), RTL8367C_ACL_OP_ACTION_MASK(index), aclActCtrl); ++ else ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_ACL_ACTION_CTRL_REG(index), RTL8367C_ACL_OP_ACTION_MASK(index), aclActCtrl); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicAclActCtrl ++ * Description: ++ * Get ACL rule matched Action Control Bits ++ * Input: ++ * index - ACL rule index (0-95) of 96 ACL rules ++ * pAclActCtrl - 6 ACL Control Bits ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - Invalid ACL rule index (0-95) ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicAclActCtrl(rtk_uint32 index, rtk_uint32 *pAclActCtrl) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ if(index > RTL8367C_ACLRULEMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(index >= 64) ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_ACL_ACTION_CTRL2_REG(index), RTL8367C_ACL_OP_ACTION_MASK(index), ®Data); ++ else ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_ACL_ACTION_CTRL_REG(index), RTL8367C_ACL_OP_ACTION_MASK(index), ®Data); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *pAclActCtrl = regData; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicAclPortRange ++ * Description: ++ * Set ACL TCP/UDP range check ++ * Input: ++ * index - TCP/UDP port range check table index ++ * type - Range check type ++ * upperPort - TCP/UDP port range upper bound ++ * lowerPort - TCP/UDP port range lower bound ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - Invalid TCP/UDP port range check table index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicAclPortRange(rtk_uint32 index, rtk_uint32 type, rtk_uint32 upperPort, rtk_uint32 lowerPort) ++{ ++ ret_t retVal; ++ ++ if(index > RTL8367C_ACLRANGEMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL2 + index*3, RTL8367C_ACL_SDPORT_RANGE_ENTRY0_CTRL2_MASK, type); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL1 + index*3, upperPort); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL0 + index*3, lowerPort); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicAclPortRange ++ * Description: ++ * Get ACL TCP/UDP range check ++ * Input: ++ * index - TCP/UDP port range check table index ++ * pType - Range check type ++ * pUpperPort - TCP/UDP port range upper bound ++ * pLowerPort - TCP/UDP port range lower bound ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - Invalid TCP/UDP port range check table index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicAclPortRange(rtk_uint32 index, rtk_uint32* pType, rtk_uint32* pUpperPort, rtk_uint32* pLowerPort) ++{ ++ ret_t retVal; ++ ++ if(index > RTL8367C_ACLRANGEMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL2 + index*3, RTL8367C_ACL_SDPORT_RANGE_ENTRY0_CTRL2_MASK, pType); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL1 + index*3, pUpperPort); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_SDPORT_RANGE_ENTRY0_CTRL0 + index*3, pLowerPort); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicAclVidRange ++ * Description: ++ * Set ACL VID range check ++ * Input: ++ * index - ACL VID range check index(0~15) ++ * type - Range check type ++ * upperVid - VID range upper bound ++ * lowerVid - VID range lower bound ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - Invalid ACL VID range check index(0~15) ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicAclVidRange(rtk_uint32 index, rtk_uint32 type, rtk_uint32 upperVid, rtk_uint32 lowerVid) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ if(index > RTL8367C_ACLRANGEMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ regData = ((type << RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_OFFSET) & RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_MASK) | ++ (upperVid & RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_HIGH_MASK); ++ ++ retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL1 + index*2, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL0 + index*2, lowerVid); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicAclVidRange ++ * Description: ++ * Get ACL VID range check ++ * Input: ++ * index - ACL VID range check index(0~15) ++ * pType - Range check type ++ * pUpperVid - VID range upper bound ++ * pLowerVid - VID range lower bound ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - Invalid ACL VID range check index(0~15) ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicAclVidRange(rtk_uint32 index, rtk_uint32* pType, rtk_uint32* pUpperVid, rtk_uint32* pLowerVid) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ if(index > RTL8367C_ACLRANGEMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL1 + index*2, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *pType = (regData & RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_MASK) >> RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_TYPE_OFFSET; ++ *pUpperVid = regData & RTL8367C_ACL_VID_RANGE_ENTRY0_CTRL1_CHECK0_HIGH_MASK; ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_VID_RANGE_ENTRY0_CTRL0 + index*2, pLowerVid); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicAclIpRange ++ * Description: ++ * Set ACL IP range check ++ * Input: ++ * index - ACL IP range check index(0~15) ++ * type - Range check type ++ * upperIp - IP range upper bound ++ * lowerIp - IP range lower bound ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - Invalid ACL IP range check index(0~15) ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicAclIpRange(rtk_uint32 index, rtk_uint32 type, ipaddr_t upperIp, ipaddr_t lowerIp) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ipaddr_t ipData; ++ ++ if(index > RTL8367C_ACLRANGEMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL4 + index*5, RTL8367C_ACL_IP_RANGE_ENTRY0_CTRL4_MASK, type); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ ipData = upperIp; ++ ++ regData = ipData & 0xFFFF; ++ retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL2 + index*5, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ regData = (ipData>>16) & 0xFFFF; ++ retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL3 + index*5, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ ipData = lowerIp; ++ ++ regData = ipData & 0xFFFF; ++ retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL0 + index*5, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ regData = (ipData>>16) & 0xFFFF; ++ retVal = rtl8367c_setAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL1 + index*5, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicAclIpRange ++ * Description: ++ * Get ACL IP range check ++ * Input: ++ * index - ACL IP range check index(0~15) ++ * pType - Range check type ++ * pUpperIp - IP range upper bound ++ * pLowerIp - IP range lower bound ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - Invalid ACL IP range check index(0~15) ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicAclIpRange(rtk_uint32 index, rtk_uint32* pType, ipaddr_t* pUpperIp, ipaddr_t* pLowerIp) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ipaddr_t ipData; ++ ++ if(index > RTL8367C_ACLRANGEMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL4 + index*5, RTL8367C_ACL_IP_RANGE_ENTRY0_CTRL4_MASK, pType); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL2 + index*5, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ipData = regData; ++ ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL3 + index*5, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ ipData = (regData <<16) | ipData; ++ *pUpperIp = ipData; ++ ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL0 + index*5, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ipData = regData; ++ ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_ACL_IP_RANGE_ENTRY0_CTRL1 + index*5, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ ipData = (regData << 16) | ipData; ++ *pLowerIp = ipData; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicAclGpioPolarity ++ * 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 ++ */ ++ret_t rtl8367c_setAsicAclGpioPolarity(rtk_uint32 polarity) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_ACL_GPIO_POLARITY, RTL8367C_ACL_GPIO_POLARITY_OFFSET, polarity); ++} ++/* Function Name: ++ * rtl8367c_getAsicAclGpioPolarity ++ * 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 ++ */ ++ret_t rtl8367c_getAsicAclGpioPolarity(rtk_uint32* pPolarity) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_ACL_GPIO_POLARITY, RTL8367C_ACL_GPIO_POLARITY_OFFSET, pPolarity); ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_cputag.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_cputag.c +new file mode 100644 +index 0000000000..d22bf65eaa +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_cputag.c +@@ -0,0 +1,369 @@ ++/* ++ * 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 : Proprietary CPU-tag related function drivers ++ * ++ */ ++#include ++/* Function Name: ++ * rtl8367c_setAsicCputagEnable ++ * Description: ++ * Set cpu tag function enable/disable ++ * Input: ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_ENABLE - Invalid enable/disable input ++ * Note: ++ * If CPU tag function is disabled, CPU tag will not be added to frame ++ * forwarded to CPU port, and all ports cannot parse CPU tag. ++ */ ++ret_t rtl8367c_setAsicCputagEnable(rtk_uint32 enabled) ++{ ++ if(enabled > 1) ++ return RT_ERR_ENABLE; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_EN_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicCputagEnable ++ * Description: ++ * Get cpu tag function enable/disable ++ * Input: ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicCputagEnable(rtk_uint32 *pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_EN_OFFSET, pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicCputagTrapPort ++ * Description: ++ * Set cpu tag trap port ++ * Input: ++ * port - port number ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * API can set destination port of trapping frame ++ */ ++ret_t rtl8367c_setAsicCputagTrapPort(rtk_uint32 port) ++{ ++ ret_t retVal; ++ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TRAP_PORT_MASK, port & 7); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TRAP_PORT_EXT_MASK, (port>>3) & 1); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicCputagTrapPort ++ * Description: ++ * Get cpu tag trap port ++ * Input: ++ * pPort - port number ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicCputagTrapPort(rtk_uint32 *pPort) ++{ ++ ret_t retVal; ++ rtk_uint32 tmpPort; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TRAP_PORT_MASK, &tmpPort); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ *pPort = tmpPort; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TRAP_PORT_EXT_MASK, &tmpPort); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ *pPort |= (tmpPort & 1) << 3; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicCputagPortmask ++ * Description: ++ * Set ports that can parse CPU tag ++ * Input: ++ * portmask - port mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_MASK - Invalid portmask ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicCputagPortmask(rtk_uint32 portmask) ++{ ++ if(portmask > RTL8367C_PORTMASK) ++ return RT_ERR_PORT_MASK; ++ ++ return rtl8367c_setAsicReg(RTL8367C_CPU_PORT_MASK_REG, portmask); ++} ++/* Function Name: ++ * rtl8367c_getAsicCputagPortmask ++ * Description: ++ * Get ports that can parse CPU tag ++ * Input: ++ * pPortmask - port mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicCputagPortmask(rtk_uint32 *pPortmask) ++{ ++ return rtl8367c_getAsicReg(RTL8367C_CPU_PORT_MASK_REG, pPortmask); ++} ++/* Function Name: ++ * rtl8367c_setAsicCputagInsertMode ++ * Description: ++ * Set CPU-tag insert mode ++ * Input: ++ * mode - 0: insert to all packets; 1: insert to trapped packets; 2: don't insert ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NOT_ALLOWED - Actions not allowed by the function ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicCputagInsertMode(rtk_uint32 mode) ++{ ++ if(mode >= CPUTAG_INSERT_END) ++ return RT_ERR_NOT_ALLOWED; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_INSERTMODE_MASK, mode); ++} ++/* Function Name: ++ * rtl8367c_getAsicCputagInsertMode ++ * Description: ++ * Get CPU-tag insert mode ++ * Input: ++ * pMode - 0: insert to all packets; 1: insert to trapped packets; 2: don't insert ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicCputagInsertMode(rtk_uint32 *pMode) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_INSERTMODE_MASK, pMode); ++} ++/* Function Name: ++ * rtl8367c_setAsicCputagPriorityRemapping ++ * Description: ++ * Set queue assignment of CPU port ++ * Input: ++ * srcPri - internal priority (0~7) ++ * newPri - internal priority after remapping (0~7) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicCputagPriorityRemapping(rtk_uint32 srcPri, rtk_uint32 newPri) ++{ ++ if((srcPri > RTL8367C_PRIMAX) || (newPri > RTL8367C_PRIMAX)) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_REG(srcPri), RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_MASK(srcPri), newPri); ++} ++/* Function Name: ++ * rtl8367c_getAsicCputagPriorityRemapping ++ * Description: ++ * Get queue assignment of CPU port ++ * Input: ++ * srcPri - internal priority (0~7) ++ * pNewPri - internal priority after remapping (0~7) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicCputagPriorityRemapping(rtk_uint32 srcPri, rtk_uint32 *pNewPri) ++{ ++ if(srcPri > RTL8367C_PRIMAX) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_REG(srcPri), RTL8367C_QOS_PRIPORITY_REMAPPING_IN_CPU_MASK(srcPri), pNewPri); ++} ++/* Function Name: ++ * rtl8367c_setAsicCputagPosition ++ * Description: ++ * Set cpu tag insert position ++ * Input: ++ * postion - 1: After entire packet(before CRC field), 0: After MAC_SA (Default) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicCputagPosition(rtk_uint32 postion) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_POSITION_OFFSET, postion); ++} ++/* Function Name: ++ * rtl8367c_getAsicCputagPosition ++ * Description: ++ * Get cpu tag insert position ++ * Input: ++ * pPostion - 1: After entire packet(before CRC field), 0: After MAC_SA (Default) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicCputagPosition(rtk_uint32* pPostion) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_POSITION_OFFSET, pPostion); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicCputagMode ++ * Description: ++ * Set cpu tag mode ++ * Input: ++ * mode - 1: 4bytes mode, 0: 8bytes mode ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters ++ * Note: ++ * If CPU tag function is disabled, CPU tag will not be added to frame ++ * forwarded to CPU port, and all ports cannot parse CPU tag. ++ */ ++ret_t rtl8367c_setAsicCputagMode(rtk_uint32 mode) ++{ ++ if(mode > 1) ++ return RT_ERR_INPUT; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_FORMAT_OFFSET, mode); ++} ++/* Function Name: ++ * rtl8367c_getAsicCputagMode ++ * Description: ++ * Get cpu tag mode ++ * Input: ++ * pMode - 1: 4bytes mode, 0: 8bytes mode ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicCputagMode(rtk_uint32 *pMode) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_FORMAT_OFFSET, pMode); ++} ++/* Function Name: ++ * rtl8367c_setAsicCputagRxMinLength ++ * Description: ++ * Set cpu tag mode ++ * Input: ++ * mode - 1: 64bytes, 0: 72bytes ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters ++ * Note: ++ * If CPU tag function is disabled, CPU tag will not be added to frame ++ * forwarded to CPU port, and all ports cannot parse CPU tag. ++ */ ++ret_t rtl8367c_setAsicCputagRxMinLength(rtk_uint32 mode) ++{ ++ if(mode > 1) ++ return RT_ERR_INPUT; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_RXBYTECOUNT_OFFSET, mode); ++} ++/* Function Name: ++ * rtl8367c_getAsicCputagRxMinLength ++ * Description: ++ * Get cpu tag mode ++ * Input: ++ * pMode - 1: 64bytes, 0: 72bytes ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicCputagRxMinLength(rtk_uint32 *pMode) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_CPU_CTRL, RTL8367C_CPU_TAG_RXBYTECOUNT_OFFSET, pMode); ++} ++ ++ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_dot1x.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_dot1x.c +new file mode 100644 +index 0000000000..73153e177e +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_dot1x.c +@@ -0,0 +1,415 @@ ++/* ++ * 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 : 802.1X related functions ++ * ++ */ ++#include ++/* Function Name: ++ * rtl8367c_setAsic1xPBEnConfig ++ * Description: ++ * Set 802.1x port-based port enable configuration ++ * Input: ++ * port - Physical port number (0~7) ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsic1xPBEnConfig(rtk_uint32 port, rtk_uint32 enabled) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_PORT_ENABLE_REG, port, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsic1xPBEnConfig ++ * Description: ++ * Get 802.1x port-based port enable configuration ++ * Input: ++ * port - Physical port number (0~7) ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsic1xPBEnConfig(rtk_uint32 port, rtk_uint32 *pEnabled) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_PORT_ENABLE_REG, port, pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsic1xPBAuthConfig ++ * Description: ++ * Set 802.1x port-based authorised port configuration ++ * Input: ++ * port - Physical port number (0~7) ++ * auth - 1: authorised, 0: non-authorised ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsic1xPBAuthConfig(rtk_uint32 port, rtk_uint32 auth) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_PORT_AUTH_REG, port, auth); ++} ++/* Function Name: ++ * rtl8367c_getAsic1xPBAuthConfig ++ * Description: ++ * Get 802.1x port-based authorised port configuration ++ * Input: ++ * port - Physical port number (0~7) ++ * pAuth - 1: authorised, 0: non-authorised ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsic1xPBAuthConfig(rtk_uint32 port, rtk_uint32 *pAuth) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_PORT_AUTH_REG, port, pAuth); ++} ++/* Function Name: ++ * rtl8367c_setAsic1xPBOpdirConfig ++ * Description: ++ * Set 802.1x port-based operational direction ++ * Input: ++ * port - Physical port number (0~7) ++ * opdir - Operation direction 1: IN, 0:BOTH ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsic1xPBOpdirConfig(rtk_uint32 port, rtk_uint32 opdir) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_PORT_OPDIR_REG, port, opdir); ++} ++/* Function Name: ++ * rtl8367c_getAsic1xPBOpdirConfig ++ * Description: ++ * Get 802.1x port-based operational direction ++ * Input: ++ * port - Physical port number (0~7) ++ * pOpdir - Operation direction 1: IN, 0:BOTH ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsic1xPBOpdirConfig(rtk_uint32 port, rtk_uint32* pOpdir) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_PORT_OPDIR_REG, port, pOpdir); ++} ++/* Function Name: ++ * rtl8367c_setAsic1xMBEnConfig ++ * Description: ++ * Set 802.1x mac-based port enable configuration ++ * Input: ++ * port - Physical port number (0~7) ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsic1xMBEnConfig(rtk_uint32 port, rtk_uint32 enabled) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_MAC_ENABLE_REG, port, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsic1xMBEnConfig ++ * Description: ++ * Get 802.1x mac-based port enable configuration ++ * Input: ++ * port - Physical port number (0~7) ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsic1xMBEnConfig(rtk_uint32 port, rtk_uint32 *pEnabled) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_MAC_ENABLE_REG, port, pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsic1xMBOpdirConfig ++ * Description: ++ * Set 802.1x mac-based operational direction ++ * Input: ++ * opdir - Operation direction 1: IN, 0:BOTH ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsic1xMBOpdirConfig(rtk_uint32 opdir) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_MAC_OPDIR_OFFSET, opdir); ++} ++/* Function Name: ++ * rtl8367c_getAsic1xMBOpdirConfig ++ * Description: ++ * Get 802.1x mac-based operational direction ++ * Input: ++ * pOpdir - Operation direction 1: IN, 0:BOTH ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsic1xMBOpdirConfig(rtk_uint32 *pOpdir) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_MAC_OPDIR_OFFSET, pOpdir); ++} ++/* Function Name: ++ * rtl8367c_setAsic1xProcConfig ++ * Description: ++ * Set 802.1x unauth. behavior configuration ++ * Input: ++ * port - Physical port number (0~7) ++ * proc - 802.1x unauth. behavior configuration 0:drop 1:trap to CPU 2:Guest VLAN ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_DOT1X_PROC - Unauthorized behavior error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsic1xProcConfig(rtk_uint32 port, rtk_uint32 proc) ++{ ++ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ if(proc >= DOT1X_UNAUTH_END) ++ return RT_ERR_DOT1X_PROC; ++ ++ if(port < 8) ++ { ++ return rtl8367c_setAsicRegBits(RTL8367C_DOT1X_UNAUTH_ACT_BASE, RTL8367C_DOT1X_UNAUTH_ACT_MASK(port),proc); ++ } ++ else ++ { ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_DOT1X_UNAUTH_ACT_W1, RTL8367C_DOT1X_UNAUTH_ACT_MASK(port),proc); ++ } ++} ++/* Function Name: ++ * rtl8367c_getAsic1xProcConfig ++ * Description: ++ * Get 802.1x unauth. behavior configuration ++ * Input: ++ * port - Physical port number (0~7) ++ * pProc - 802.1x unauth. behavior configuration 0:drop 1:trap to CPU 2:Guest VLAN ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsic1xProcConfig(rtk_uint32 port, rtk_uint32* pProc) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ if(port < 8) ++ return rtl8367c_getAsicRegBits(RTL8367C_DOT1X_UNAUTH_ACT_BASE, RTL8367C_DOT1X_UNAUTH_ACT_MASK(port),pProc); ++ else ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_DOT1X_UNAUTH_ACT_W1, RTL8367C_DOT1X_UNAUTH_ACT_MASK(port),pProc); ++} ++/* Function Name: ++ * rtl8367c_setAsic1xGuestVidx ++ * Description: ++ * Set 802.1x guest vlan index ++ * Input: ++ * index - 802.1x guest vlan index (0~31) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_DOT1X_GVLANIDX - Invalid cvid index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsic1xGuestVidx(rtk_uint32 index) ++{ ++ if(index >= RTL8367C_CVIDXNO) ++ return RT_ERR_DOT1X_GVLANIDX; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_GVIDX_MASK, index); ++} ++/* Function Name: ++ * rtl8367c_getAsic1xGuestVidx ++ * Description: ++ * Get 802.1x guest vlan index ++ * Input: ++ * pIndex - 802.1x guest vlan index (0~31) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsic1xGuestVidx(rtk_uint32 *pIndex) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_GVIDX_MASK, pIndex); ++} ++/* Function Name: ++ * rtl8367c_setAsic1xGVOpdir ++ * Description: ++ * Set 802.1x guest vlan talk to auth. DA ++ * Input: ++ * enabled - 0:disable 1:enable ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsic1xGVOpdir(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_GVOPDIR_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsic1xGVOpdir ++ * Description: ++ * Get 802.1x guest vlan talk to auth. DA ++ * Input: ++ * pEnabled - 0:disable 1:enable ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsic1xGVOpdir(rtk_uint32 *pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_DOT1X_CFG_REG, RTL8367C_DOT1X_GVOPDIR_OFFSET, pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsic1xTrapPriority ++ * Description: ++ * Set 802.1x Trap priority ++ * Input: ++ * priority - priority (0~7) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsic1xTrapPriority(rtk_uint32 priority) ++{ ++ if(priority > RTL8367C_PRIMAX) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_DOT1X_PRIORTY_MASK,priority); ++} ++/* Function Name: ++ * rtl8367c_getAsic1xTrapPriority ++ * Description: ++ * Get 802.1x Trap priority ++ * Input: ++ * pPriority - priority (0~7) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsic1xTrapPriority(rtk_uint32 *pPriority) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_DOT1X_PRIORTY_MASK, pPriority); ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eav.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eav.c +new file mode 100644 +index 0000000000..370b7c6f3a +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eav.c +@@ -0,0 +1,877 @@ ++/* ++ * 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 : Ethernet AV related functions ++ * ++ */ ++ ++#include ++/* Function Name: ++ * rtl8367c_setAsicEavMacAddress ++ * Description: ++ * Set PTP MAC address ++ * Input: ++ * mac - PTP mac ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicEavMacAddress(ether_addr_t mac) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint8 *accessPtr; ++ rtk_uint32 i; ++ ++ accessPtr = (rtk_uint8*)&mac; ++ ++ regData = *accessPtr; ++ accessPtr ++; ++ regData = (regData << 8) | *accessPtr; ++ accessPtr ++; ++ for(i = 0; i <=2; i++) ++ { ++ retVal = rtl8367c_setAsicReg(RTL8367C_REG_MAC_ADDR_H - i, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ regData = *accessPtr; ++ accessPtr ++; ++ regData = (regData << 8) | *accessPtr; ++ accessPtr ++; ++ } ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicEavMacAddress ++ * Description: ++ * Get PTP MAC address ++ * Input: ++ * None ++ * Output: ++ * pMac - PTP mac ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicEavMacAddress(ether_addr_t *pMac) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint8 *accessPtr; ++ rtk_uint32 i; ++ ++ accessPtr = (rtk_uint8*)pMac; ++ ++ for(i = 0; i <= 2; i++) ++ { ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_MAC_ADDR_H - i, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *accessPtr = (regData & 0xFF00) >> 8; ++ accessPtr ++; ++ *accessPtr = regData & 0xFF; ++ accessPtr ++; ++ } ++ ++ return retVal; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicEavTpid ++ * Description: ++ * Set PTP parser tag TPID. ++ * Input: ++ * outerTag - outter tag TPID ++ * innerTag - inner tag TPID ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicEavTpid(rtk_uint32 outerTag, rtk_uint32 innerTag) ++{ ++ ret_t retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_OTAG_TPID, outerTag)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_ITAG_TPID, innerTag)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicEavTpid ++ * Description: ++ * Get PTP parser tag TPID. ++ * Input: ++ * None ++ * Output: ++ * pOuterTag - outter tag TPID ++ * pInnerTag - inner tag TPID ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicEavTpid(rtk_uint32* pOuterTag, rtk_uint32* pInnerTag) ++{ ++ ret_t retVal; ++ ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_OTAG_TPID, pOuterTag)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_ITAG_TPID, pInnerTag)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicEavSysTime ++ * Description: ++ * Set PTP system time ++ * Input: ++ * second - seconds ++ * nanoSecond - nano seconds ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * The time granuality is 8 nano seconds. ++ */ ++ret_t rtl8367c_setAsicEavSysTime(rtk_uint32 second, rtk_uint32 nanoSecond) ++{ ++ ret_t retVal; ++ rtk_uint32 sec_h, sec_l, nsec8_h, nsec8_l; ++ rtk_uint32 nano_second_8; ++ rtk_uint32 regData, busyFlag, count; ++ ++ if(nanoSecond > RTL8367C_EAV_NANOSECONDMAX) ++ return RT_ERR_INPUT; ++ ++ regData = 0; ++ sec_h = second >>16; ++ sec_l = second & 0xFFFF; ++ nano_second_8 = nanoSecond >> 3; ++ nsec8_h = (nano_second_8 >>16) & RTL8367C_PTP_TIME_NSEC_H_NSEC_MASK; ++ nsec8_l = nano_second_8 &0xFFFF; ++ ++ if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_SEC_H_SEC, sec_h)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_SEC_L_SEC, sec_l)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_NSEC_L_NSEC, nsec8_l)) != RT_ERR_OK) ++ return retVal; ++ ++ regData = nsec8_h | (PTP_TIME_WRITE<= PTP_TIME_ADJ_END) ++ return RT_ERR_INPUT; ++ if(nanoSecond > RTL8367C_EAV_NANOSECONDMAX) ++ return RT_ERR_INPUT; ++ ++ regData = 0; ++ sec_h = second >>16; ++ sec_l = second & 0xFFFF; ++ nano_second_8 = nanoSecond >> 3; ++ nsec8_h = (nano_second_8 >>16) & RTL8367C_PTP_TIME_NSEC_H_NSEC_MASK; ++ nsec8_l = nano_second_8 &0xFFFF; ++ ++ if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_SEC_H_SEC, sec_h)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_SEC_L_SEC, sec_l)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_NSEC_L_NSEC, nsec8_l)) != RT_ERR_OK) ++ return retVal; ++ ++ if (PTP_TIME_ADJ_INC == type) ++ regData = nsec8_h | (PTP_TIME_INC<=PTP_TIME_CTRL_END) ++ return RT_ERR_INPUT; ++ ++ regData = 0; ++ if (PTP_TIME_CTRL_START == control) ++ regData = RTL8367C_CFG_TIMER_EN_FRC_MASK | RTL8367C_CFG_TIMER_1588_EN_MASK; ++ else ++ regData = 0; ++ ++ if((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PTP_TIME_CFG, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicEavSysTimeCtrl ++ * Description: ++ * Get PTP system time control ++ * Input: ++ * None ++ * Output: ++ * pControl - start or stop ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicEavSysTimeCtrl(rtk_uint32* pControl) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint32 mask; ++ ++ mask = RTL8367C_CFG_TIMER_EN_FRC_MASK | RTL8367C_CFG_TIMER_1588_EN_MASK; ++ ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_PTP_TIME_CFG, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (regData & mask) == mask) ++ *pControl = PTP_TIME_CTRL_START; ++ else if( (regData & mask) == 0) ++ *pControl = PTP_TIME_CTRL_STOP; ++ else ++ return RT_ERR_NOT_ALLOWED; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicEavInterruptMask ++ * Description: ++ * Set PTP interrupt enable mask ++ * Input: ++ * imr - Interrupt mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * [0]:TX_SYNC, ++ * [1]:TX_DELAY, ++ * [2]:TX_PDELAY_REQ, ++ * [3]:TX_PDELAY_RESP, ++ * [4]:RX_SYNC, ++ * [5]:RX_DELAY, ++ * [6]:RX_PDELAY_REQ, ++ * [7]:RX_PDELAY_RESP, ++ */ ++ret_t rtl8367c_setAsicEavInterruptMask(rtk_uint32 imr) ++{ ++ if ((imr&(RTL8367C_PTP_INTR_MASK<<8))>0) ++ return RT_ERR_INPUT; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_PTP_TIME_CFG2, RTL8367C_PTP_INTR_MASK, imr); ++} ++/* Function Name: ++ * rtl8367c_getAsicEavInterruptMask ++ * Description: ++ * Get PTP interrupt enable mask ++ * Input: ++ * pImr - Interrupt mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * [0]:TX_SYNC, ++ * [1]:TX_DELAY, ++ * [2]:TX_PDELAY_REQ, ++ * [3]:TX_PDELAY_RESP, ++ * [4]:RX_SYNC, ++ * [5]:RX_DELAY, ++ * [6]:RX_PDELAY_REQ, ++ * [7]:RX_PDELAY_RESP, ++ */ ++ret_t rtl8367c_getAsicEavInterruptMask(rtk_uint32* pImr) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_PTP_TIME_CFG2, RTL8367C_PTP_INTR_MASK, pImr); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicEavInterruptStatus ++ * Description: ++ * Get PTP interrupt port status mask ++ * Input: ++ * pIms - Interrupt mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * [0]:p0 interrupt, ++ * [1]:p1 interrupt, ++ * [2]:p2 interrupt, ++ * [3]:p3 interrupt, ++ * [4]:p4 interrupt, ++ */ ++ret_t rtl8367c_getAsicEavInterruptStatus(rtk_uint32* pIms) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_PTP_INTERRUPT_CFG, RTL8367C_PTP_PORT_MASK, pIms); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicInterruptMask ++ * Description: ++ * Clear interrupt enable mask ++ * Input: ++ * ims - Interrupt status mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * This API can be used to clear ASIC interrupt status and register will be cleared by writting 1. ++ * [0]:TX_SYNC, ++ * [1]:TX_DELAY, ++ * [2]:TX_PDELAY_REQ, ++ * [3]:TX_PDELAY_RESP, ++ * [4]:RX_SYNC, ++ * [5]:RX_DELAY, ++ * [6]:RX_PDELAY_REQ, ++ * [7]:RX_PDELAY_RESP, ++ */ ++ret_t rtl8367c_setAsicEavPortInterruptStatus(rtk_uint32 port, rtk_uint32 ims) ++{ ++ ++ if(port > RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ if(port < 5) ++ return rtl8367c_setAsicRegBits(RTL8367C_EAV_PORT_CFG_REG(port), RTL8367C_PTP_INTR_MASK,ims); ++ else if(port == 5) ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_P5_EAV_CFG, RTL8367C_PTP_INTR_MASK,ims); ++ else if(port == 6) ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_P6_EAV_CFG, RTL8367C_PTP_INTR_MASK,ims); ++ else if(port == 7) ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_P7_EAV_CFG, RTL8367C_PTP_INTR_MASK,ims); ++ else if(port == 8) ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_P8_EAV_CFG, RTL8367C_PTP_INTR_MASK,ims); ++ else if(port == 9) ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_P9_EAV_CFG, RTL8367C_PTP_INTR_MASK,ims); ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicInterruptStatus ++ * Description: ++ * Get interrupt enable mask ++ * Input: ++ * pIms - Interrupt status mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * [0]:TX_SYNC, ++ * [1]:TX_DELAY, ++ * [2]:TX_PDELAY_REQ, ++ * [3]:TX_PDELAY_RESP, ++ * [4]:RX_SYNC, ++ * [5]:RX_DELAY, ++ * [6]:RX_PDELAY_REQ, ++ * [7]:RX_PDELAY_RESP, ++ */ ++ret_t rtl8367c_getAsicEavPortInterruptStatus(rtk_uint32 port, rtk_uint32* pIms) ++{ ++ ++ if(port > RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ if(port < 5) ++ return rtl8367c_getAsicRegBits(RTL8367C_EAV_PORT_CFG_REG(port), RTL8367C_PTP_INTR_MASK, pIms); ++ else if(port == 5) ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_P5_EAV_CFG, RTL8367C_PTP_INTR_MASK, pIms); ++ else if(port == 6) ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_P6_EAV_CFG, RTL8367C_PTP_INTR_MASK,pIms); ++ else if(port == 7) ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_P7_EAV_CFG, RTL8367C_PTP_INTR_MASK,pIms); ++ else if(port == 8) ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_P8_EAV_CFG, RTL8367C_PTP_INTR_MASK,pIms); ++ else if(port == 9) ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_P9_EAV_CFG, RTL8367C_PTP_INTR_MASK,pIms); ++ ++ return RT_ERR_OK; ++ ++} ++ ++ ++/* Function Name: ++ * rtl8367c_setAsicEavPortEnable ++ * Description: ++ * Set per-port EAV function enable/disable ++ * Input: ++ * port - Physical port number (0~9) ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * If EAV function is enabled, PTP event messgae packet will be attached PTP timestamp for trapping ++ */ ++ret_t rtl8367c_setAsicEavPortEnable(rtk_uint32 port, rtk_uint32 enabled) ++{ ++ if(port > RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ if(port < 5) ++ return rtl8367c_setAsicRegBit(RTL8367C_EAV_PORT_CFG_REG(port), RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); ++ else if(port == 5) ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_P5_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); ++ else if(port == 6) ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_P6_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); ++ else if(port == 7) ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_P7_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); ++ else if(port == 8) ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_P8_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); ++ else if(port == 9) ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_P9_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, enabled); ++ ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicEavPortEnable ++ * Description: ++ * Get per-port EAV function enable/disable ++ * Input: ++ * port - Physical port number (0~9) ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicEavPortEnable(rtk_uint32 port, rtk_uint32 *pEnabled) ++{ ++ if(port > RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ ++ ++ if(port < 5) ++ return rtl8367c_getAsicRegBit(RTL8367C_EAV_PORT_CFG_REG(port), RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); ++ else if(port == 5) ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_P5_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); ++ else if(port == 6) ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_P6_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); ++ else if(port == 7) ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_P7_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); ++ else if(port == 8) ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_P8_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); ++ else if(port == 9) ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_P9_EAV_CFG, RTL8367C_EAV_CFG_PTP_PHY_EN_EN_OFFSET, pEnabled); ++ ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicEavPortTimeStamp ++ * Description: ++ * Get PTP port time stamp ++ * Input: ++ * port - Physical port number (0~9) ++ * type - PTP packet type ++ * Output: ++ * timeStamp - seconds ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * The time granuality is 8 nano seconds. ++ */ ++ret_t rtl8367c_getAsicEavPortTimeStamp(rtk_uint32 port, rtk_uint32 type, rtl8367c_ptp_time_stamp_t* timeStamp) ++{ ++ ret_t retVal; ++ rtk_uint32 sec_h, sec_l, nsec8_h, nsec8_l; ++ rtk_uint32 nano_second_8; ++ ++ if(port > 9) ++ return RT_ERR_PORT_ID; ++ if(type >= PTP_PKT_TYPE_END) ++ return RT_ERR_INPUT; ++ ++ if(port < 5){ ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SEQ_ID(port, type), &timeStamp->sequence_id))!= RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_PORT_SEC_H(port) , &sec_h)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_PORT_SEC_L(port), &sec_l)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_NSEC_H(port) , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_PORT_NSEC_L(port) , &nsec8_l)) != RT_ERR_OK) ++ return retVal; ++ }else if(port == 5){ ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P5_TX_SYNC_SEQ_ID+type, &timeStamp->sequence_id))!= RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P5_PORT_SEC_31_16, &sec_h)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P5_PORT_SEC_15_0, &sec_l)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_P5_PORT_NSEC_26_16 , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P5_PORT_NSEC_15_0, &nsec8_l)) != RT_ERR_OK) ++ return retVal; ++ }else if(port == 6){ ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P6_TX_SYNC_SEQ_ID+type, &timeStamp->sequence_id))!= RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P6_PORT_SEC_31_16, &sec_h)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P6_PORT_SEC_15_0, &sec_l)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_P6_PORT_NSEC_26_16 , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P6_PORT_NSEC_15_0, &nsec8_l)) != RT_ERR_OK) ++ return retVal; ++ }else if(port == 7){ ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P7_TX_SYNC_SEQ_ID+type, &timeStamp->sequence_id))!= RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P7_PORT_SEC_31_16, &sec_h)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P7_PORT_SEC_15_0, &sec_l)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_P7_PORT_NSEC_26_16 , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P7_PORT_NSEC_15_0, &nsec8_l)) != RT_ERR_OK) ++ return retVal; ++ }else if(port == 8){ ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P8_TX_SYNC_SEQ_ID+type, &timeStamp->sequence_id))!= RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P8_PORT_SEC_31_16, &sec_h)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P8_PORT_SEC_15_0, &sec_l)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_P8_PORT_NSEC_26_16 , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P8_PORT_NSEC_15_0, &nsec8_l)) != RT_ERR_OK) ++ return retVal; ++ }else if(port == 9){ ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P9_TX_SYNC_SEQ_ID+type, &timeStamp->sequence_id))!= RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P9_PORT_SEC_31_16, &sec_h)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P9_PORT_SEC_15_0, &sec_l)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_P9_PORT_NSEC_26_16 , RTL8367C_PORT_NSEC_H_MASK,&nsec8_h)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicReg(RTL8367C_REG_P9_PORT_NSEC_15_0, &nsec8_l)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ timeStamp->second = (sec_h<<16) | sec_l; ++ nano_second_8 = (nsec8_h<<16) | nsec8_l; ++ timeStamp->nano_second = nano_second_8<<3; ++ ++ return RT_ERR_OK; ++} ++ ++ ++/* Function Name: ++ * rtl8367c_setAsicEavTrap ++ * Description: ++ * Set per-port PTP packet trap to CPU ++ * Input: ++ * port - Physical port number (0~5) ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * If EAV trap enabled, switch will trap PTP packet to CPU ++ */ ++ret_t rtl8367c_setAsicEavTrap(rtk_uint32 port, rtk_uint32 enabled) ++{ ++ if(port > RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_PTP_PORT0_CFG1 + (port * 0x20), RTL8367C_PTP_PORT0_CFG1_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicEavTimeSyncEn ++ * Description: ++ * Get per-port EPTP packet trap to CPU ++ * Input: ++ * port - Physical port number (0~5) ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicEavTrap(rtk_uint32 port, rtk_uint32 *pEnabled) ++{ ++ if(port > RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_PTP_PORT0_CFG1 + (port * 0x20), RTL8367C_PTP_PORT0_CFG1_OFFSET, pEnabled); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicEavEnable ++ * Description: ++ * Set per-port EAV function enable/disable ++ * Input: ++ * port - Physical port number (0~5) ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * If EAV function is enabled, PTP event messgae packet will be attached PTP timestamp for trapping ++ */ ++ret_t rtl8367c_setAsicEavEnable(rtk_uint32 port, rtk_uint32 enabled) ++{ ++ if(port > RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_EAV_CTRL0, port, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicEavEnable ++ * Description: ++ * Get per-port EAV function enable/disable ++ * Input: ++ * port - Physical port number (0~5) ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicEavEnable(rtk_uint32 port, rtk_uint32 *pEnabled) ++{ ++ if(port > RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_EAV_CTRL0, port, pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicEavPriRemapping ++ * Description: ++ * Set non-EAV streaming priority remapping ++ * Input: ++ * srcpriority - Priority value ++ * priority - Absolute priority value ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicEavPriRemapping(rtk_uint32 srcpriority, rtk_uint32 priority) ++{ ++ if(srcpriority > RTL8367C_PRIMAX || priority > RTL8367C_PRIMAX) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_EAV_PRIORITY_REMAPPING_REG(srcpriority), RTL8367C_EAV_PRIORITY_REMAPPING_MASK(srcpriority),priority); ++} ++/* Function Name: ++ * rtl8367c_getAsicEavPriRemapping ++ * Description: ++ * Get non-EAV streaming priority remapping ++ * Input: ++ * srcpriority - Priority value ++ * pPriority - Absolute priority value ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicEavPriRemapping(rtk_uint32 srcpriority, rtk_uint32 *pPriority) ++{ ++ if(srcpriority > RTL8367C_PRIMAX ) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_EAV_PRIORITY_REMAPPING_REG(srcpriority), RTL8367C_EAV_PRIORITY_REMAPPING_MASK(srcpriority),pPriority); ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eee.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eee.c +new file mode 100644 +index 0000000000..f4dda6a6ae +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_eee.c +@@ -0,0 +1,141 @@ ++/* ++ * 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 (週二, 01 七月 2014) $ ++ * ++ * Purpose : RTL8370 switch high-level API for RTL8367C ++ * Feature : ++ * ++ */ ++ ++#include ++#include ++ ++/* ++@func ret_t | rtl8367c_setAsicEee100M | Set eee force mode function enable/disable. ++@parm rtk_uint32 | port | The port number. ++@parm rtk_uint32 | enabled | 1: enabled, 0: disabled. ++@rvalue RT_ERR_OK | Success. ++@rvalue RT_ERR_SMI | SMI access error. ++@rvalue RT_ERR_INPUT | Invalid input parameter. ++@comm ++ This API set the 100M EEE enable function. ++ ++*/ ++ret_t rtl8367c_setAsicEee100M(rtk_uint32 port, rtk_uint32 enable) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 regData; ++ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ if (enable > 1) ++ return RT_ERR_INPUT; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ if(enable) ++ regData |= (0x0001 << 1); ++ else ++ regData &= ~(0x0001 << 1); ++ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* ++@func ret_t | rtl8367c_getAsicEee100M | Get 100M eee enable/disable. ++@parm rtk_uint32 | port | The port number. ++@parm rtk_uint32* | enabled | 1: enabled, 0: disabled. ++@rvalue RT_ERR_OK | Success. ++@rvalue RT_ERR_SMI | SMI access error. ++@rvalue RT_ERR_INPUT | Invalid input parameter. ++@comm ++ This API get the 100M EEE function. ++*/ ++ret_t rtl8367c_getAsicEee100M(rtk_uint32 port, rtk_uint32 *enable) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 regData; ++ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ *enable = (regData & (0x0001 << 1)) ? ENABLED : DISABLED; ++ return RT_ERR_OK; ++} ++ ++/* ++@func ret_t | rtl8367c_setAsicEeeGiga | Set eee force mode function enable/disable. ++@parm rtk_uint32 | port | The port number. ++@parm rtk_uint32 | enabled | 1: enabled, 0: disabled. ++@rvalue RT_ERR_OK | Success. ++@rvalue RT_ERR_SMI | SMI access error. ++@rvalue RT_ERR_INPUT | Invalid input parameter. ++@comm ++ This API set the 100M EEE enable function. ++ ++*/ ++ret_t rtl8367c_setAsicEeeGiga(rtk_uint32 port, rtk_uint32 enable) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 regData; ++ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ if (enable > 1) ++ return RT_ERR_INPUT; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ if(enable) ++ regData |= (0x0001 << 2); ++ else ++ regData &= ~(0x0001 << 2); ++ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* ++@func ret_t | rtl8367c_getAsicEeeGiga | Get 100M eee enable/disable. ++@parm rtk_uint32 | port | The port number. ++@parm rtk_uint32* | enabled | 1: enabled, 0: disabled. ++@rvalue RT_ERR_OK | Success. ++@rvalue RT_ERR_SMI | SMI access error. ++@rvalue RT_ERR_INPUT | Invalid input parameter. ++@comm ++ This API get the 100M EEE function. ++*/ ++ret_t rtl8367c_getAsicEeeGiga(rtk_uint32 port, rtk_uint32 *enable) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 regData; ++ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, EEE_OCP_PHY_ADDR, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ *enable = (regData & (0x0001 << 2)) ? ENABLED : DISABLED; ++ return RT_ERR_OK; ++} +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_fc.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_fc.c +new file mode 100644 +index 0000000000..28f49b1ba7 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_fc.c +@@ -0,0 +1,1354 @@ ++/* ++ * 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 : Flow control related functions ++ * ++ */ ++ ++#include ++/* Function Name: ++ * rtl8367c_setAsicFlowControlSelect ++ * Description: ++ * Set system flow control type ++ * Input: ++ * select - System flow control type 1: Ingress flow control 0:Egress flow control ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicFlowControlSelect(rtk_uint32 select) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_FLOWCTRL_CTRL0, RTL8367C_FLOWCTRL_TYPE_OFFSET, select); ++} ++/* Function Name: ++ * rtl8367c_getAsicFlowControlSelect ++ * Description: ++ * Get system flow control type ++ * Input: ++ * pSelect - System flow control type 1: Ingress flow control 0:Egress flow control ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicFlowControlSelect(rtk_uint32 *pSelect) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_FLOWCTRL_CTRL0, RTL8367C_FLOWCTRL_TYPE_OFFSET, pSelect); ++} ++/* Function Name: ++ * rtl8367c_setAsicFlowControlJumboMode ++ * Description: ++ * Set Jumbo threhsold for flow control ++ * Input: ++ * enabled - Jumbo mode flow control 1: Enable 0:Disable ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicFlowControlJumboMode(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_FLOWCTRL_JUMBO_SIZE, RTL8367C_JUMBO_MODE_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicFlowControlJumboMode ++ * Description: ++ * Get Jumbo threhsold for flow control ++ * Input: ++ * pEnabled - Jumbo mode flow control 1: Enable 0:Disable ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicFlowControlJumboMode(rtk_uint32* pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_FLOWCTRL_JUMBO_SIZE, RTL8367C_JUMBO_MODE_OFFSET, pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicFlowControlJumboModeSize ++ * Description: ++ * Set Jumbo size for Jumbo mode flow control ++ * Input: ++ * size - Jumbo size 0:3Kbytes 1:4Kbytes 2:6Kbytes 3:9Kbytes ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicFlowControlJumboModeSize(rtk_uint32 size) ++{ ++ if(size >= FC_JUMBO_SIZE_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SIZE, RTL8367C_JUMBO_SIZE_MASK, size); ++} ++/* Function Name: ++ * rtl8367c_getAsicFlowControlJumboModeSize ++ * Description: ++ * Get Jumbo size for Jumbo mode flow control ++ * Input: ++ * pSize - Jumbo size 0:3Kbytes 1:4Kbytes 2:6Kbytes 3:9Kbytes ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicFlowControlJumboModeSize(rtk_uint32* pSize) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SIZE, RTL8367C_JUMBO_SIZE_MASK, pSize); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicFlowControlQueueEgressEnable ++ * Description: ++ * Set flow control ability for each queue ++ * Input: ++ * port - Physical port number (0~7) ++ * qid - Queue id ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_QUEUE_ID - Invalid queue id ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicFlowControlQueueEgressEnable(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 enabled) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(qid > RTL8367C_QIDMAX) ++ return RT_ERR_QUEUE_ID; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG(port), RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG_OFFSET(port)+ qid, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicFlowControlQueueEgressEnable ++ * Description: ++ * Get flow control ability for each queue ++ * Input: ++ * port - Physical port number (0~7) ++ * qid - Queue id ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_QUEUE_ID - Invalid queue id ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicFlowControlQueueEgressEnable(rtk_uint32 port, rtk_uint32 qid, rtk_uint32* pEnabled) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(qid > RTL8367C_QIDMAX) ++ return RT_ERR_QUEUE_ID; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG(port), RTL8367C_FLOWCRTL_EGRESS_QUEUE_ENABLE_REG_OFFSET(port)+ qid, pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicFlowControlDropAll ++ * Description: ++ * Set system-based drop parameters ++ * Input: ++ * dropall - Whole system drop threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicFlowControlDropAll(rtk_uint32 dropall) ++{ ++ if(dropall >= RTL8367C_PAGE_NUMBER) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_CTRL0, RTL8367C_DROP_ALL_THRESHOLD_MASK, dropall); ++} ++/* Function Name: ++ * rtl8367c_getAsicFlowControlDropAll ++ * Description: ++ * Get system-based drop parameters ++ * Input: ++ * pDropall - Whole system drop threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicFlowControlDropAll(rtk_uint32* pDropall) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_CTRL0, RTL8367C_DROP_ALL_THRESHOLD_MASK, pDropall); ++} ++/* Function Name: ++ * rtl8367c_setAsicFlowControlPauseAll ++ * Description: ++ * Set system-based all ports enable flow control parameters ++ * Input: ++ * threshold - Whole system pause all threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicFlowControlPauseAllThreshold(rtk_uint32 threshold) ++{ ++ if(threshold >= RTL8367C_PAGE_NUMBER) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_ALL_ON, RTL8367C_FLOWCTRL_ALL_ON_THRESHOLD_MASK, threshold); ++} ++/* Function Name: ++ * rtl8367c_getAsicFlowControlPauseAllThreshold ++ * Description: ++ * Get system-based all ports enable flow control parameters ++ * Input: ++ * pThreshold - Whole system pause all threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicFlowControlPauseAllThreshold(rtk_uint32 *pThreshold) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_ALL_ON, RTL8367C_FLOWCTRL_ALL_ON_THRESHOLD_MASK, pThreshold); ++} ++/* Function Name: ++ * rtl8367c_setAsicFlowControlSystemThreshold ++ * Description: ++ * Set system-based flow control parameters ++ * Input: ++ * onThreshold - Flow control turn ON threshold ++ * offThreshold - Flow control turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicFlowControlSystemThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) ++{ ++ ret_t retVal; ++ ++ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_SYS_OFF, RTL8367C_FLOWCTRL_SYS_OFF_MASK, offThreshold); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_SYS_ON, RTL8367C_FLOWCTRL_SYS_ON_MASK, onThreshold); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicFlowControlSystemThreshold ++ * Description: ++ * Get system-based flow control parameters ++ * Input: ++ * pOnThreshold - Flow control turn ON threshold ++ * pOffThreshold - Flow control turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicFlowControlSystemThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_SYS_OFF, RTL8367C_FLOWCTRL_SYS_OFF_MASK, pOffThreshold); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_SYS_ON, RTL8367C_FLOWCTRL_SYS_ON_MASK, pOnThreshold); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_setAsicFlowControlSharedThreshold ++ * Description: ++ * Set share-based flow control parameters ++ * Input: ++ * onThreshold - Flow control turn ON threshold ++ * offThreshold - Flow control turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicFlowControlSharedThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) ++{ ++ ret_t retVal; ++ ++ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_SHARE_OFF, RTL8367C_FLOWCTRL_SHARE_OFF_MASK, offThreshold); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_SHARE_ON, RTL8367C_FLOWCTRL_SHARE_ON_MASK, onThreshold); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicFlowControlSharedThreshold ++ * Description: ++ * Get share-based flow control parameters ++ * Input: ++ * pOnThreshold - Flow control turn ON threshold ++ * pOffThreshold - Flow control turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicFlowControlSharedThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_SHARE_OFF, RTL8367C_FLOWCTRL_SHARE_OFF_MASK, pOffThreshold); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_SHARE_ON, RTL8367C_FLOWCTRL_SHARE_ON_MASK, pOnThreshold); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_setAsicFlowControlPortThreshold ++ * Description: ++ * Set Port-based flow control parameters ++ * Input: ++ * onThreshold - Flow control turn ON threshold ++ * offThreshold - Flow control turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicFlowControlPortThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) ++{ ++ ret_t retVal; ++ ++ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_OFF, RTL8367C_FLOWCTRL_PORT_OFF_MASK, offThreshold); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_ON, RTL8367C_FLOWCTRL_PORT_ON_MASK, onThreshold); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicFlowControlPortThreshold ++ * Description: ++ * Get Port-based flow control parameters ++ * Input: ++ * pOnThreshold - Flow control turn ON threshold ++ * pOffThreshold - Flow control turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicFlowControlPortThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_OFF, RTL8367C_FLOWCTRL_PORT_OFF_MASK, pOffThreshold); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_ON, RTL8367C_FLOWCTRL_PORT_ON_MASK, pOnThreshold); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_setAsicFlowControlPortPrivateThreshold ++ * Description: ++ * Set Port-private-based flow control parameters ++ * Input: ++ * onThreshold - Flow control turn ON threshold ++ * offThreshold - Flow control turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicFlowControlPortPrivateThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) ++{ ++ ret_t retVal; ++ ++ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_PORT_PRIVATE_OFF_MASK, offThreshold); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_PORT_PRIVATE_ON_MASK, onThreshold); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicFlowControlPortPrivateThreshold ++ * Description: ++ * Get Port-private-based flow control parameters ++ * Input: ++ * pOnThreshold - Flow control turn ON threshold ++ * pOffThreshold - Flow control turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicFlowControlPortPrivateThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_PORT_PRIVATE_OFF_MASK, pOffThreshold); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_PORT_PRIVATE_ON_MASK, pOnThreshold); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_setAsicFlowControlSystemDropThreshold ++ * Description: ++ * Set system-based drop parameters ++ * Input: ++ * onThreshold - Drop turn ON threshold ++ * offThreshold - Drop turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicFlowControlSystemDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) ++{ ++ ret_t retVal; ++ ++ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SYS_OFF, RTL8367C_FLOWCTRL_FCOFF_SYS_OFF_MASK, offThreshold); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SYS_ON, RTL8367C_FLOWCTRL_FCOFF_SYS_ON_MASK, onThreshold); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicFlowControlSystemDropThreshold ++ * Description: ++ * Get system-based drop parameters ++ * Input: ++ * pOnThreshold - Drop turn ON threshold ++ * pOffThreshold - Drop turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicFlowControlSystemDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SYS_OFF, RTL8367C_FLOWCTRL_FCOFF_SYS_OFF_MASK, pOffThreshold); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SYS_ON, RTL8367C_FLOWCTRL_FCOFF_SYS_ON_MASK, pOnThreshold); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_setAsicFlowControlSharedDropThreshold ++ * Description: ++ * Set share-based fdrop parameters ++ * Input: ++ * onThreshold - Drop turn ON threshold ++ * offThreshold - Drop turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicFlowControlSharedDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) ++{ ++ ret_t retVal; ++ ++ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_OFF, RTL8367C_FLOWCTRL_FCOFF_SHARE_OFF_MASK, offThreshold); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_ON, RTL8367C_FLOWCTRL_FCOFF_SHARE_ON_MASK, onThreshold); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicFlowControlSharedDropThreshold ++ * Description: ++ * Get share-based fdrop parameters ++ * Input: ++ * pOnThreshold - Drop turn ON threshold ++ * pOffThreshold - Drop turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicFlowControlSharedDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_OFF, RTL8367C_FLOWCTRL_FCOFF_SHARE_OFF_MASK, pOffThreshold); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_SHARE_ON, RTL8367C_FLOWCTRL_FCOFF_SHARE_ON_MASK, pOnThreshold); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_setAsicFlowControlPortDropThreshold ++ * Description: ++ * Set Port-based drop parameters ++ * Input: ++ * onThreshold - Drop turn ON threshold ++ * offThreshold - Drop turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicFlowControlPortDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) ++{ ++ ret_t retVal; ++ ++ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_OFF, RTL8367C_FLOWCTRL_FCOFF_PORT_OFF_MASK, offThreshold); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_ON, RTL8367C_FLOWCTRL_FCOFF_PORT_ON_MASK, onThreshold); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicFlowControlPortDropThreshold ++ * Description: ++ * Get Port-based drop parameters ++ * Input: ++ * pOnThreshold - Drop turn ON threshold ++ * pOffThreshold - Drop turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicFlowControlPortDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_OFF, RTL8367C_FLOWCTRL_FCOFF_PORT_OFF_MASK, pOffThreshold); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_ON, RTL8367C_FLOWCTRL_FCOFF_PORT_ON_MASK, pOnThreshold); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_setAsicFlowControlPortPrivateDropThreshold ++ * Description: ++ * Set Port-private-based drop parameters ++ * Input: ++ * onThreshold - Drop turn ON threshold ++ * offThreshold - Drop turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicFlowControlPortPrivateDropThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) ++{ ++ ret_t retVal; ++ ++ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF_MASK, offThreshold); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_ON_MASK, onThreshold); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicFlowControlPortPrivateDropThreshold ++ * Description: ++ * Get Port-private-based drop parameters ++ * Input: ++ * pOnThreshold - Drop turn ON threshold ++ * pOffThreshold - Drop turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicFlowControlPortPrivateDropThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_OFF_MASK, pOffThreshold); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_FCOFF_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_FCOFF_PORT_PRIVATE_ON_MASK, pOnThreshold); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_setAsicFlowControlSystemJumboThreshold ++ * Description: ++ * Set Jumbo system-based flow control parameters ++ * Input: ++ * onThreshold - Flow control turn ON threshold ++ * offThreshold - Flow control turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicFlowControlSystemJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) ++{ ++ ret_t retVal; ++ ++ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SYS_OFF, RTL8367C_FLOWCTRL_JUMBO_SYS_OFF_MASK, offThreshold); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SYS_ON, RTL8367C_FLOWCTRL_JUMBO_SYS_ON_MASK, onThreshold); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicFlowControlSystemJumboThreshold ++ * Description: ++ * Get Jumbo system-based flow control parameters ++ * Input: ++ * pOnThreshold - Flow control turn ON threshold ++ * pOffThreshold - Flow control turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicFlowControlSystemJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SYS_OFF, RTL8367C_FLOWCTRL_JUMBO_SYS_OFF_MASK, pOffThreshold); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SYS_ON, RTL8367C_FLOWCTRL_JUMBO_SYS_ON_MASK, pOnThreshold); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_setAsicFlowControlSharedJumboThreshold ++ * Description: ++ * Set Jumbo share-based flow control parameters ++ * Input: ++ * onThreshold - Flow control turn ON threshold ++ * offThreshold - Flow control turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicFlowControlSharedJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) ++{ ++ ret_t retVal; ++ ++ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_OFF, RTL8367C_FLOWCTRL_JUMBO_SHARE_OFF_MASK, offThreshold); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_ON, RTL8367C_FLOWCTRL_JUMBO_SHARE_ON_MASK, onThreshold); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicFlowControlSharedJumboThreshold ++ * Description: ++ * Get Jumbo share-based flow control parameters ++ * Input: ++ * pOnThreshold - Flow control turn ON threshold ++ * pOffThreshold - Flow control turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicFlowControlSharedJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_OFF, RTL8367C_FLOWCTRL_JUMBO_SHARE_OFF_MASK, pOffThreshold); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_SHARE_ON, RTL8367C_FLOWCTRL_JUMBO_SHARE_ON_MASK, pOnThreshold); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_setAsicFlowControlPortJumboThreshold ++ * Description: ++ * Set Jumbo Port-based flow control parameters ++ * Input: ++ * onThreshold - Flow control turn ON threshold ++ * offThreshold - Flow control turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicFlowControlPortJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) ++{ ++ ret_t retVal; ++ ++ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_OFF, RTL8367C_FLOWCTRL_JUMBO_PORT_OFF_MASK, offThreshold); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_ON, RTL8367C_FLOWCTRL_JUMBO_PORT_ON_MASK, onThreshold); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicFlowControlPortJumboThreshold ++ * Description: ++ * Get Jumbo Port-based flow control parameters ++ * Input: ++ * pOnThreshold - Flow control turn ON threshold ++ * pOffThreshold - Flow control turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicFlowControlPortJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_OFF, RTL8367C_FLOWCTRL_JUMBO_PORT_OFF_MASK, pOffThreshold); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_ON, RTL8367C_FLOWCTRL_JUMBO_PORT_ON_MASK, pOnThreshold); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_setAsicFlowControlPortPrivateJumboThreshold ++ * Description: ++ * Set Jumbo Port-private-based flow control parameters ++ * Input: ++ * onThreshold - Flow control turn ON threshold ++ * offThreshold - Flow control turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicFlowControlPortPrivateJumboThreshold(rtk_uint32 onThreshold, rtk_uint32 offThreshold) ++{ ++ ret_t retVal; ++ ++ if((onThreshold >= RTL8367C_PAGE_NUMBER) || (offThreshold >= RTL8367C_PAGE_NUMBER)) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF_MASK, offThreshold); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_ON_MASK, onThreshold); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicFlowControlPortPrivateJumboThreshold ++ * Description: ++ * Get Jumbo Port-private-based flow control parameters ++ * Input: ++ * pOnThreshold - Flow control turn ON threshold ++ * pOffThreshold - Flow control turn OFF threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicFlowControlPortPrivateJumboThreshold(rtk_uint32 *pOnThreshold, rtk_uint32 *pOffThreshold) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF, RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_OFF_MASK, pOffThreshold); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_JUMBO_PORT_PRIVATE_ON, RTL8367C_FLOWCTRL_JUMBO_PORT_PRIVATE_ON_MASK, pOnThreshold); ++ ++ return retVal; ++} ++ ++ ++ ++/* Function Name: ++ * rtl8367c_setAsicEgressFlowControlQueueDropThreshold ++ * Description: ++ * Set Queue-based egress flow control turn on or ingress flow control drop on threshold ++ * Input: ++ * qid - The queue id ++ * threshold - Queue-based flown control/drop turn ON threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * RT_ERR_QUEUE_ID - Invalid queue id ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicEgressFlowControlQueueDropThreshold(rtk_uint32 qid, rtk_uint32 threshold) ++{ ++ if( threshold >= RTL8367C_PAGE_NUMBER) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(qid > RTL8367C_QIDMAX) ++ return RT_ERR_QUEUE_ID; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_FLOWCTRL_QUEUE_DROP_ON_REG(qid), RTL8367C_FLOWCTRL_QUEUE_DROP_ON_MASK, threshold); ++} ++/* Function Name: ++ * rtl8367c_getAsicEgressFlowControlQueueDropThreshold ++ * Description: ++ * Get Queue-based egress flow control turn on or ingress flow control drop on threshold ++ * Input: ++ * qid - The queue id ++ * pThreshold - Queue-based flown control/drop turn ON threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_QUEUE_ID - Invalid queue id ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicEgressFlowControlQueueDropThreshold(rtk_uint32 qid, rtk_uint32 *pThreshold) ++{ ++ if(qid > RTL8367C_QIDMAX) ++ return RT_ERR_QUEUE_ID; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_FLOWCTRL_QUEUE_DROP_ON_REG(qid), RTL8367C_FLOWCTRL_QUEUE_DROP_ON_MASK, pThreshold); ++} ++/* Function Name: ++ * rtl8367c_setAsicEgressFlowControlPortDropThreshold ++ * Description: ++ * Set port-based egress flow control turn on or ingress flow control drop on threshold ++ * Input: ++ * port - Physical port number (0~7) ++ * threshold - Queue-based flown control/drop turn ON threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicEgressFlowControlPortDropThreshold(rtk_uint32 port, rtk_uint32 threshold) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(threshold >= RTL8367C_PAGE_NUMBER) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_FLOWCTRL_PORT_DROP_ON_REG(port), RTL8367C_FLOWCTRL_PORT_DROP_ON_MASK, threshold); ++} ++/* Function Name: ++ * rtl8367c_setAsicEgressFlowControlPortDropThreshold ++ * Description: ++ * Set port-based egress flow control turn on or ingress flow control drop on threshold ++ * Input: ++ * port - Physical port number (0~7) ++ * pThreshold - Queue-based flown control/drop turn ON threshold ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicEgressFlowControlPortDropThreshold(rtk_uint32 port, rtk_uint32 *pThreshold) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_FLOWCTRL_PORT_DROP_ON_REG(port), RTL8367C_FLOWCTRL_PORT_DROP_ON_MASK, pThreshold); ++} ++/* Function Name: ++ * rtl8367c_setAsicEgressFlowControlPortDropGap ++ * Description: ++ * Set port-based egress flow control turn off or ingress flow control drop off gap ++ * Input: ++ * gap - Flow control/drop turn OFF threshold = turn ON threshold - gap ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicEgressFlowControlPortDropGap(rtk_uint32 gap) ++{ ++ if(gap >= RTL8367C_PAGE_NUMBER) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_GAP, RTL8367C_FLOWCTRL_PORT_GAP_MASK, gap); ++} ++/* Function Name: ++ * rtl8367c_getAsicEgressFlowControlPortDropGap ++ * Description: ++ * Get port-based egress flow control turn off or ingress flow control drop off gap ++ * Input: ++ * pGap - Flow control/drop turn OFF threshold = turn ON threshold - gap ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicEgressFlowControlPortDropGap(rtk_uint32 *pGap) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT_GAP, RTL8367C_FLOWCTRL_PORT_GAP_MASK, pGap); ++} ++/* Function Name: ++ * rtl8367c_setAsicEgressFlowControlQueueDropGap ++ * Description: ++ * Set Queue-based egress flow control turn off or ingress flow control drop off gap ++ * Input: ++ * gap - Flow control/drop turn OFF threshold = turn ON threshold - gap ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicEgressFlowControlQueueDropGap(rtk_uint32 gap) ++{ ++ if(gap >= RTL8367C_PAGE_NUMBER) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_FLOWCTRL_QUEUE_GAP, RTL8367C_FLOWCTRL_QUEUE_GAP_MASK, gap); ++} ++/* Function Name: ++ * rtl8367c_getAsicEgressFlowControlQueueDropGap ++ * Description: ++ * Get Queue-based egress flow control turn off or ingress flow control drop off gap ++ * Input: ++ * pGap - Flow control/drop turn OFF threshold = turn ON threshold - gap ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicEgressFlowControlQueueDropGap(rtk_uint32 *pGap) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_QUEUE_GAP, RTL8367C_FLOWCTRL_QUEUE_GAP_MASK, pGap); ++} ++/* Function Name: ++ * rtl8367c_getAsicEgressQueueEmptyPortMask ++ * Description: ++ * Get queue empty port mask ++ * Input: ++ * pPortmask - Queue empty port mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicEgressQueueEmptyPortMask(rtk_uint32 *pPortmask) ++{ ++ return rtl8367c_getAsicReg(RTL8367C_REG_PORT_QEMPTY, pPortmask); ++} ++/* Function Name: ++ * rtl8367c_getAsicTotalPage ++ * Description: ++ * Get system total page usage number ++ * Input: ++ * pPageCount - page usage number ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicTotalPage(rtk_uint32 *pPageCount) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_TOTAL_PAGE_COUNTER, RTL8367C_FLOWCTRL_TOTAL_PAGE_COUNTER_MASK, pPageCount); ++} ++/* Function Name: ++ * rtl8367c_getAsicPulbicPage ++ * Description: ++ * Get system public page usage number ++ * Input: ++ * pPageCount - page usage number ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPulbicPage(rtk_uint32 *pPageCount) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PUBLIC_PAGE_COUNTER, RTL8367C_FLOWCTRL_PUBLIC_PAGE_COUNTER_MASK, pPageCount); ++} ++/* Function Name: ++ * rtl8367c_getAsicMaxTotalPage ++ * Description: ++ * Get system total page max usage number ++ * Input: ++ * pPageCount - page usage number ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicMaxTotalPage(rtk_uint32 *pPageCount) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_TOTAL_PAGE_MAX, RTL8367C_FLOWCTRL_TOTAL_PAGE_MAX_MASK, pPageCount); ++} ++/* Function Name: ++ * rtl8367c_getAsicPulbicPage ++ * Description: ++ * Get system public page max usage number ++ * Input: ++ * pPageCount - page usage number ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicMaxPulbicPage(rtk_uint32 *pPageCount) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PUBLIC_PAGE_MAX, RTL8367C_FLOWCTRL_PUBLIC_PAGE_MAX_MASK, pPageCount); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortPage ++ * Description: ++ * Get per-port page usage number ++ * Input: ++ * port - Physical port number (0~7) ++ * pPageCount - page usage number ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortPage(rtk_uint32 port, rtk_uint32 *pPageCount) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(port < 8) ++ return rtl8367c_getAsicRegBits(RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_REG(port), RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_MASK, pPageCount); ++ else ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT8_PAGE_COUNTER+port - 8, RTL8367C_FLOWCTRL_PORT_PAGE_COUNTER_MASK, pPageCount); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortPage ++ * Description: ++ * Get per-port page max usage number ++ * Input: ++ * port - Physical port number (0~7) ++ * pPageCount - page usage number ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortPageMax(rtk_uint32 port, rtk_uint32 *pPageCount) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ if(port < 8) ++ return rtl8367c_getAsicRegBits(RTL8367C_FLOWCTRL_PORT_PAGE_MAX_REG(port), RTL8367C_FLOWCTRL_PORT_PAGE_MAX_MASK, pPageCount); ++ else ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_FLOWCTRL_PORT0_PAGE_MAX+port-8, RTL8367C_FLOWCTRL_PORT_PAGE_MAX_MASK, pPageCount); ++ ++ ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicFlowControlEgressPortIndep ++ * Description: ++ * Set per-port egress flow control independent ++ * Input: ++ * port - Physical port number (0~7) ++ * enabled - Egress port flow control usage 1:enable 0:disable. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicFlowControlEgressPortIndep(rtk_uint32 port, rtk_uint32 enable) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_PORT0_MISC_CFG + (port *0x20), RTL8367C_PORT0_MISC_CFG_FLOWCTRL_INDEP_OFFSET,enable); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicFlowControlEgressPortIndep ++ * Description: ++ * Get per-port egress flow control independent ++ * Input: ++ * port - Physical port number (0~7) ++ * enabled - Egress port flow control usage 1:enable 0:disable. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicFlowControlEgressPortIndep(rtk_uint32 port, rtk_uint32 *pEnable) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_PORT0_MISC_CFG + (port *0x20),RTL8367C_PORT0_MISC_CFG_FLOWCTRL_INDEP_OFFSET,pEnable); ++} +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_green.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_green.c +new file mode 100644 +index 0000000000..a38623850b +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_green.c +@@ -0,0 +1,445 @@ ++/* ++ * 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 : Green ethernet related functions ++ * ++ */ ++#include ++ ++/* Function Name: ++ * rtl8367c_getAsicGreenPortPage ++ * Description: ++ * Get per-Port ingress page usage per second ++ * Input: ++ * port - Physical port number (0~7) ++ * pPage - page number of ingress packet occuping per second ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * Ingress traffic occuping page number per second for high layer green feature usage ++ */ ++ret_t rtl8367c_getAsicGreenPortPage(rtk_uint32 port, rtk_uint32* pPage) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint32 pageMeter; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_PAGEMETER_PORT_REG(port), ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pageMeter = regData; ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_PAGEMETER_PORT_REG(port) + 1, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pageMeter = pageMeter + (regData << 16); ++ ++ *pPage = pageMeter; ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicGreenTrafficType ++ * Description: ++ * Set traffic type for each priority ++ * Input: ++ * priority - internal priority (0~7) ++ * traffictype - high/low traffic type, 1:high priority traffic type, 0:low priority traffic type ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicGreenTrafficType(rtk_uint32 priority, rtk_uint32 traffictype) ++{ ++ ++ if(priority > RTL8367C_PRIMAX) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_HIGHPRI_CFG, priority, (traffictype?1:0)); ++} ++/* Function Name: ++ * rtl8367c_getAsicGreenTrafficType ++ * Description: ++ * Get traffic type for each priority ++ * Input: ++ * priority - internal priority (0~7) ++ * pTraffictype - high/low traffic type, 1:high priority traffic type, 0:low priority traffic type ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicGreenTrafficType(rtk_uint32 priority, rtk_uint32* pTraffictype) ++{ ++ if(priority > RTL8367C_PRIMAX) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_HIGHPRI_CFG, priority, pTraffictype); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicGreenHighPriorityTraffic ++ * Description: ++ * Set indicator which ASIC had received high priority traffic ++ * Input: ++ * port - Physical port number (0~7) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicGreenHighPriorityTraffic(rtk_uint32 port) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_HIGHPRI_INDICATOR, port, 1); ++} ++ ++ ++/* Function Name: ++ * rtl8367c_getAsicGreenHighPriorityTraffic ++ * Description: ++ * Get indicator which ASIC had received high priority traffic or not ++ * Input: ++ * port - Physical port number (0~7) ++ * pIndicator - Have received high priority traffic indicator. If 1 means ASCI had received high priority in 1second checking priod ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicGreenHighPriorityTraffic(rtk_uint32 port, rtk_uint32* pIndicator) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_HIGHPRI_INDICATOR, port, pIndicator); ++} ++ ++/* ++@func rtk_int32 | rtl8367c_setAsicGreenEthernet | Set green ethernet function. ++@parm rtk_uint32 | green | Green feature function usage 1:enable 0:disable. ++@rvalue RT_ERR_OK | Success. ++@rvalue RT_ERR_SMI | SMI access error. ++@comm ++ The API can set Green Ethernet function to reduce power consumption. While green feature is enabled, ASIC will automatic ++ detect the cable length and then select different power mode for best performance with minimums power consumption. Link down ++ ports will enter power savining mode in 10 seconds after the cable disconnected if power saving function is enabled. ++*/ ++ret_t rtl8367c_setAsicGreenEthernet(rtk_uint32 port, rtk_uint32 green) ++{ ++ ret_t retVal; ++ rtk_uint32 checkCounter; ++ rtk_uint32 regData; ++ rtk_uint32 phy_status; ++ rtk_uint32 patchData[6][2] = { {0x809A, 0x8911}, {0x80A3, 0x9233}, {0x80AC, 0xA444}, {0x809F, 0x6B20}, {0x80A8, 0x6B22}, {0x80B1, 0x6B23} }; ++ rtk_uint32 idx; ++ rtk_uint32 data; ++ ++ if (green > 1) ++ return RT_ERR_INPUT; ++ ++ /* 0xa420[2:0] */ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xA420, ®Data)) != RT_ERR_OK) ++ return retVal; ++ phy_status = (regData & 0x0007); ++ ++ if(phy_status == 3) ++ { ++ /* 0xb820[4] = 1 */ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xB820, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ regData |= (0x0001 << 4); ++ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xB820, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ /* wait 0xb800[6] = 1 */ ++ checkCounter = 100; ++ while(checkCounter) ++ { ++ retVal = rtl8367c_getAsicPHYOCPReg(port, 0xB800, ®Data); ++ if( (retVal != RT_ERR_OK) || ((regData & 0x0040) != 0x0040) ) ++ { ++ checkCounter --; ++ if(0 == checkCounter) ++ return RT_ERR_BUSYWAIT_TIMEOUT; ++ } ++ else ++ checkCounter = 0; ++ } ++ } ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicReg(0x1300, &data)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) ++ return retVal; ++ ++ switch (data) ++ { ++ case 0x0276: ++ case 0x0597: ++ case 0x6367: ++ if(green) ++ { ++ for(idx = 0; idx < 6; idx++ ) ++ { ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA436, patchData[idx][0])) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA438, patchData[idx][1])) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ break; ++ default: ++ break;; ++ } ++ ++ ++ ++ /* 0xa436 = 0x8011 */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA436, 0x8011)) != RT_ERR_OK) ++ return retVal; ++ ++ /* wr 0xa438[15] = 0: disable, 1: enable */ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xA438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ if(green) ++ regData |= 0x8000; ++ else ++ regData &= 0x7FFF; ++ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA438, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ if(phy_status == 3) ++ { ++ /* 0xb820[4] = 0 */ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xB820, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ regData &= ~(0x0001 << 4); ++ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xB820, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ /* wait 0xb800[6] = 0 */ ++ checkCounter = 100; ++ while(checkCounter) ++ { ++ retVal = rtl8367c_getAsicPHYOCPReg(port, 0xB800, ®Data); ++ if( (retVal != RT_ERR_OK) || ((regData & 0x0040) != 0x0000) ) ++ { ++ checkCounter --; ++ if(0 == checkCounter) ++ return RT_ERR_BUSYWAIT_TIMEOUT; ++ } ++ else ++ checkCounter = 0; ++ } ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* ++@func rtk_int32 | rtl8367c_getAsicGreenEthernet | Get green ethernet function. ++@parm rtk_uint32 | *green | Green feature function usage 1:enable 0:disable. ++@rvalue RT_ERR_OK | Success. ++@rvalue RT_ERR_SMI | SMI access error. ++@comm ++ The API can set Green Ethernet function to reduce power consumption. While green feature is enabled, ASIC will automatic ++ detect the cable length and then select different power mode for best performance with minimums power consumption. Link down ++ ports will enter power savining mode in 10 seconds after the cable disconnected if power saving function is enabled. ++*/ ++ret_t rtl8367c_getAsicGreenEthernet(rtk_uint32 port, rtk_uint32* green) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ /* 0xa436 = 0x8011 */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xA436, 0x8011)) != RT_ERR_OK) ++ return retVal; ++ ++ /* wr 0xa438[15] = 0: disable, 1: enable */ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xA438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ if(regData & 0x8000) ++ *green = ENABLED; ++ else ++ *green = DISABLED; ++ ++ return RT_ERR_OK; ++} ++ ++ ++/* ++@func ret_t | rtl8367c_setAsicPowerSaving | Set power saving mode ++@parm rtk_uint32 | phy | phy number ++@parm rtk_uint32 | enable | enable power saving mode. ++@rvalue RT_ERR_OK | Success. ++@rvalue RT_ERR_SMI | SMI access error. ++@rvalue RT_ERR_PORT_ID | Invalid port number. ++@comm ++ The API can set power saving mode per phy. ++*/ ++ret_t rtl8367c_setAsicPowerSaving(rtk_uint32 phy, rtk_uint32 enable) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 phyData; ++ rtk_uint32 regData; ++ rtk_uint32 phy_status; ++ rtk_uint32 checkCounter; ++ ++ if (enable > 1) ++ return RT_ERR_INPUT; ++ ++ /* 0xa420[2:0] */ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(phy, 0xA420, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ phy_status = (regData & 0x0007); ++ ++ if(phy_status == 3) ++ { ++ /* 0xb820[4] = 1 */ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(phy, 0xB820, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ regData |= (0x0001 << 4); ++ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(phy, 0xB820, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ /* wait 0xb800[6] = 1 */ ++ checkCounter = 100; ++ while(checkCounter) ++ { ++ retVal = rtl8367c_getAsicPHYOCPReg(phy, 0xB800, ®Data); ++ if( (retVal != RT_ERR_OK) || ((regData & 0x0040) != 0x0040) ) ++ { ++ checkCounter --; ++ if(0 == checkCounter) ++ { ++ return RT_ERR_BUSYWAIT_TIMEOUT; ++ } ++ } ++ else ++ checkCounter = 0; ++ } ++ } ++ ++ if ((retVal = rtl8367c_getAsicPHYReg(phy,PHY_POWERSAVING_REG,&phyData))!=RT_ERR_OK) ++ return retVal; ++ ++ phyData = phyData & ~(0x0001 << 2); ++ phyData = phyData | (enable << 2); ++ ++ if ((retVal = rtl8367c_setAsicPHYReg(phy,PHY_POWERSAVING_REG,phyData))!=RT_ERR_OK) ++ return retVal; ++ ++ if(phy_status == 3) ++ { ++ /* 0xb820[4] = 0 */ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(phy, 0xB820, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ regData &= ~(0x0001 << 4); ++ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(phy, 0xB820, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ /* wait 0xb800[6] = 0 */ ++ checkCounter = 100; ++ while(checkCounter) ++ { ++ retVal = rtl8367c_getAsicPHYOCPReg(phy, 0xB800, ®Data); ++ if( (retVal != RT_ERR_OK) || ((regData & 0x0040) != 0x0000) ) ++ { ++ checkCounter --; ++ if(0 == checkCounter) ++ { ++ return RT_ERR_BUSYWAIT_TIMEOUT; ++ } ++ } ++ else ++ checkCounter = 0; ++ } ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* ++@func ret_t | rtl8367c_getAsicPowerSaving | Get power saving mode ++@parm rtk_uint32 | port | The port number ++@parm rtk_uint32* | enable | enable power saving mode. ++@rvalue RT_ERR_OK | Success. ++@rvalue RT_ERR_SMI | SMI access error. ++@rvalue RT_ERR_PORT_ID | Invalid port number. ++@comm ++ The API can get power saving mode per phy. ++*/ ++ret_t rtl8367c_getAsicPowerSaving(rtk_uint32 phy, rtk_uint32* enable) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 phyData; ++ ++ if(NULL == enable) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicPHYReg(phy,PHY_POWERSAVING_REG,&phyData))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((phyData & 0x0004) > 0) ++ *enable = 1; ++ else ++ *enable = 0; ++ ++ return RT_ERR_OK; ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_hsb.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_hsb.c +new file mode 100644 +index 0000000000..435368d51b +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_hsb.c +@@ -0,0 +1,81 @@ ++/* ++ * 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 : Field selector related functions ++ * ++ */ ++#include ++/* Function Name: ++ * rtl8367c_setAsicFieldSelector ++ * 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 - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * 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. ++ */ ++ret_t rtl8367c_setAsicFieldSelector(rtk_uint32 index, rtk_uint32 format, rtk_uint32 offset) ++{ ++ rtk_uint32 regData; ++ ++ if(index > RTL8367C_FIELDSEL_FORMAT_NUMBER) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(format >= FIELDSEL_FORMAT_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ regData = (((format << RTL8367C_FIELD_SELECTOR_FORMAT_OFFSET) & RTL8367C_FIELD_SELECTOR_FORMAT_MASK ) | ++ ((offset << RTL8367C_FIELD_SELECTOR_OFFSET_OFFSET) & RTL8367C_FIELD_SELECTOR_OFFSET_MASK )); ++ ++ return rtl8367c_setAsicReg(RTL8367C_FIELD_SELECTOR_REG(index), regData); ++} ++/* Function Name: ++ * rtl8367c_getAsicFieldSelector ++ * Description: ++ * Get user defined field selectors in HSB ++ * Input: ++ * index - index of field selector 0-15 ++ * pFormat - Format of field selector ++ * pOffset - Retrieving data offset ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicFieldSelector(rtk_uint32 index, rtk_uint32* pFormat, rtk_uint32* pOffset) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_FIELD_SELECTOR_REG(index), ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *pFormat = ((regData & RTL8367C_FIELD_SELECTOR_FORMAT_MASK) >> RTL8367C_FIELD_SELECTOR_FORMAT_OFFSET); ++ *pOffset = ((regData & RTL8367C_FIELD_SELECTOR_OFFSET_MASK) >> RTL8367C_FIELD_SELECTOR_OFFSET_OFFSET); ++ ++ return RT_ERR_OK; ++} +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_i2c.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_i2c.c +new file mode 100644 +index 0000000000..69f20a0188 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_i2c.c +@@ -0,0 +1,474 @@ ++/* ++ * 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 (周三, 17 四月 2016) $ ++ * ++ * Purpose : RTL8367C switch high-level API for RTL8367C ++ * Feature : I2C related functions ++ * ++ */ ++ ++ ++#include ++#include ++#include ++ ++ ++ ++/* Function Name: ++ * rtl8367c_setAsicI2C_checkBusIdle ++ * Description: ++ * Check i2c bus status idle or not ++ * Input: ++ * None ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_BUSYWAIT_TIMEOUT - i2c bus is busy ++ * Note: ++ * This API can check i2c bus status. ++ */ ++ret_t rtl8367c_setAsicI2C_checkBusIdle(void) ++{ ++ rtk_uint32 regData; ++ ret_t retVal; ++ ++ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_M_I2C_BUS_IDLE_OFFSET, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ if(regData == 0x0001) ++ return RT_ERR_OK; /*i2c is idle*/ ++ else ++ return RT_ERR_BUSYWAIT_TIMEOUT; /*i2c is busy*/ ++} ++ ++ ++/* Function Name: ++ * rtl8367c_setAsicI2CStartCmd ++ * Description: ++ * Set I2C start command ++ * Input: ++ * None ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * Note: ++ * This API can set i2c start command ,start a i2c traffic . ++ */ ++ret_t rtl8367c_setAsicI2CStartCmd(void) ++{ ++ rtk_uint32 regData; ++ ret_t retVal; ++ ++ /* Bits [4-1] = 0b0000, Start Command; Bit [0] = 1, Trigger the Command */ ++ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) ++ return retVal; ++ regData &= 0xFFE0; ++ regData |= 0x0001; ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ /* wait for command finished */ ++ do{ ++ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) ++ return retVal; ++ }while( regData != 0x0); ++ ++ return RT_ERR_OK ; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicI2CStopCmd ++ * Description: ++ * Set I2C stop command ++ * Input: ++ * None ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * Note: ++ * This API can set i2c stop command ,stop a i2c traffic. ++ */ ++ret_t rtl8367c_setAsicI2CStopCmd(void) ++{ ++ ++ rtk_uint32 regData; ++ ret_t retVal; ++ ++ /* Bits [4-1] = 0b0001, Stop Command; Bit [0] = 1, Trigger the Command */ ++ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) ++ return retVal; ++ regData &= 0xFFE0; ++ regData |= 0x0003; ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ ++ /* wait for command finished */ ++ do{ ++ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) ++ return retVal; ++ }while( regData != 0x0); ++ ++ return RT_ERR_OK ; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicI2CTxOneCharCmd ++ * Description: ++ * Set I2C Tx a char command, with a 8-bit data ++ * Input: ++ * oneChar - 8-bit data ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * Note: ++ * This API can set i2c Tx command and with a 8-bit data. ++ */ ++ret_t rtl8367c_setAsicI2CTxOneCharCmd(rtk_uint8 oneChar) ++{ ++ rtk_uint32 regData; ++ ret_t retVal; ++ ++ /* Bits [4-1] = 0b0010, tx one char; Bit [0] = 1, Trigger the Command */ ++ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ regData &= 0xFFE0; ++ regData |= 0x0005; ++ regData &= 0x00FF; ++ regData |= (rtk_uint16) (oneChar << 8); ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ ++ /* wait for command finished */ ++ do{ ++ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) ++ return retVal; ++ }while( regData != 0x0); ++ ++ return RT_ERR_OK ; ++} ++ ++ ++/* Function Name: ++ * rtl8367c_setAsicI2CcheckRxAck ++ * Description: ++ * Check if rx an Ack ++ * Input: ++ * None ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * Note: ++ * This API can check if rx an ack from i2c slave. ++ */ ++ret_t rtl8367c_setAsicI2CcheckRxAck(void) ++{ ++ rtk_uint32 regData; ++ ret_t retVal; ++ rtk_uint32 count = 0; ++ ++ do{ ++ count++; ++ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_SLV_ACK_FLAG_OFFSET, ®Data)) != RT_ERR_OK) ++ return retVal; ++ }while( (regData != 0x1) && (count < TIMEROUT_FOR_MICROSEMI) ); ++ ++ if(regData != 0x1) ++ return RT_ERR_FAILED; ++ else ++ return RT_ERR_OK; ++} ++ ++ ++/* Function Name: ++ * rtl8367c_setAsicI2CRxOneCharCmd ++ * Description: ++ * Set I2C Rx command and get 8-bit data ++ * Input: ++ * None ++ * Output: ++ * pValue - 8bit-data ++ * Return: ++ * RT_ERR_OK - Success ++ * Note: ++ * This API can set I2C Rx command and get 8-bit data. ++ */ ++ret_t rtl8367c_setAsicI2CRxOneCharCmd(rtk_uint8 *pValue) ++{ ++ rtk_uint32 regData; ++ ret_t retVal; ++ ++ /* Bits [4-1] = 0b0011, Rx one char; Bit [0] = 1, Trigger the Command */ ++ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) ++ return retVal; ++ regData &= 0xFFE0; ++ regData |= 0x0007; ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ /* wait for command finished */ ++ do{ ++ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) ++ return retVal; ++ }while( (regData & 0x1) != 0x0); ++ ++ *pValue = (rtk_uint8)(regData >> 8); ++ return RT_ERR_OK ; ++ ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicI2CTxAckCmd ++ * Description: ++ * Set I2C Tx ACK command ++ * Input: ++ * None ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * Note: ++ * This API can set I2C Tx ack command. ++ */ ++ret_t rtl8367c_setAsicI2CTxAckCmd(void) ++{ ++ rtk_uint32 regData; ++ ret_t retVal; ++ ++ /* Bits [4-1] = 0b0100, tx ACK Command; Bit [0] = 1, Trigger the Command */ ++ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) ++ return retVal; ++ regData &= 0xFFE0; ++ regData |= 0x0009; ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ /* wait for command finished */ ++ do{ ++ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) ++ return retVal; ++ }while( regData != 0x0); ++ ++ return RT_ERR_OK ; ++ ++} ++ ++ ++/* Function Name: ++ * rtl8367c_setAsicI2CTxNoAckCmd ++ * Description: ++ * Set I2C master Tx noACK command ++ * Input: ++ * None ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * Note: ++ * This API can set I2C master Tx noACK command. ++ */ ++ret_t rtl8367c_setAsicI2CTxNoAckCmd(void) ++{ ++ rtk_uint32 regData; ++ ret_t retVal; ++ ++ /* Bits [4-1] = 0b0101, tx noACK Command; Bit [0] = 1, Trigger the Command */ ++ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) ++ return retVal; ++ regData &= 0xFFE0; ++ regData |= 0x000b; ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ /* wait for command finished */ ++ do{ ++ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) ++ return retVal; ++ }while( regData != 0x0); ++ ++ return RT_ERR_OK ; ++ ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicI2CSoftRSTseqCmd ++ * Description: ++ * set I2C master tx soft reset command ++ * Input: ++ * None ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * Note: ++ * This API can set I2C master tx soft reset command. ++ */ ++ret_t rtl8367c_setAsicI2CSoftRSTseqCmd(void) ++{ ++ ++ rtk_uint32 regData; ++ ret_t retVal; ++ ++ /*Bits [4-1] = 0b0110, tx soft reset Command; Bit [0] = 1, Trigger the Command */ ++ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, ®Data)) != RT_ERR_OK) ++ return retVal; ++ regData &= 0xFFE0; ++ regData |= 0x000d; ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_CTL_STA_REG, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ ++ /* wait for command finished */ ++ do{ ++ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_M_I2C_CTL_STA_REG, RTL8367C_I2C_CMD_EXEC_OFFSET, ®Data)) != RT_ERR_OK) ++ return retVal; ++ }while( regData != 0x0); ++ ++ return RT_ERR_OK ; ++} ++ ++ ++/* Function Name: ++ * rtl8367c_setAsicI2CGpioPinGroup ++ * Description: ++ * set I2C function used gpio pins ++ * Input: ++ * pinGroup_ID - gpio pins group ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_INPUT _ Invalid input parameter ++ * Note: ++ * This API can set I2C function used gpio pins. ++ * There are three group gpio pins ++ */ ++ret_t rtl8367c_setAsicI2CGpioPinGroup(rtk_uint32 pinGroup_ID) ++{ ++ rtk_uint32 regData; ++ ret_t retVal; ++ ++ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, ®Data)) != RT_ERR_OK) ++ return retVal; ++ if( pinGroup_ID==0 ) ++ { ++ regData &= 0x0FFF; ++ regData |= 0x5000; ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, regData)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ else if( pinGroup_ID==1 ) ++ { ++ regData &= 0x0FFF; ++ regData |= 0xA000; ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, regData)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ else if( pinGroup_ID==2 ) ++ { ++ regData &= 0x0FFF; ++ regData |= 0xF000; ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, regData)) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ return RT_ERR_INPUT; ++ ++ return RT_ERR_OK ; ++ ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicI2CGpioPinGroup ++ * Description: ++ * set I2C function used gpio pins ++ * Input: ++ * pinGroup_ID - gpio pins group ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_INPUT _ Invalid input parameter ++ * Note: ++ * This API can set I2C function used gpio pins. ++ * There are three group gpio pins ++ */ ++ret_t rtl8367c_getAsicI2CGpioPinGroup(rtk_uint32 * pPinGroup_ID) ++{ ++ ++ rtk_uint32 regData; ++ ret_t retVal; ++ if( (retVal = rtl8367c_getAsicReg(RTL8367C_REG_M_I2C_SYS_CTL, ®Data)) != RT_ERR_OK) ++ return retVal; ++ regData &= 0xF000 ; ++ regData = (regData >> 12); ++ ++ if( regData == 0x5 ) ++ *pPinGroup_ID = 0; ++ else if(regData == 0xA) ++ *pPinGroup_ID = 1; ++ else if(regData == 0xF) ++ *pPinGroup_ID = 2; ++ else ++ return RT_ERR_FAILED; ++ return RT_ERR_OK ; ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_igmp.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_igmp.c +new file mode 100644 +index 0000000000..e0e734d61e +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_igmp.c +@@ -0,0 +1,2109 @@ ++/* ++ * 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 ++ * ++ */ ++#include ++/* Function Name: ++ * rtl8367c_setAsicIgmp ++ * Description: ++ * Set IGMP/MLD state ++ * Input: ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIgmp(rtk_uint32 enabled) ++{ ++ ret_t retVal; ++ ++ /* Enable/Disable H/W IGMP/MLD */ ++ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_EN_OFFSET, enabled); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicIgmp ++ * Description: ++ * Get IGMP/MLD state ++ * Input: ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIgmp(rtk_uint32 *ptr_enabled) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_EN_OFFSET, ptr_enabled); ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_setAsicIpMulticastVlanLeaky ++ * Description: ++ * Set IP multicast VLAN Leaky function ++ * Input: ++ * port - Physical port number (0~7) ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * When enabling this function, ++ * if the lookup result(forwarding portmap) of IP Multicast packet is over VLAN boundary, ++ * the packet can be forwarded across VLAN ++ */ ++ret_t rtl8367c_setAsicIpMulticastVlanLeaky(rtk_uint32 port, rtk_uint32 enabled) ++{ ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IPMCAST_VLAN_LEAKY, port, enabled); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicIpMulticastVlanLeaky ++ * Description: ++ * Get IP multicast VLAN Leaky function ++ * Input: ++ * port - Physical port number (0~7) ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIpMulticastVlanLeaky(rtk_uint32 port, rtk_uint32 *ptr_enabled) ++{ ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IPMCAST_VLAN_LEAKY, port, ptr_enabled); ++ ++ return retVal; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPTableFullOP ++ * Description: ++ * Set Table Full operation ++ * Input: ++ * operation - The operation should be taken when the IGMP table is full. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter is out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPTableFullOP(rtk_uint32 operation) ++{ ++ ret_t retVal; ++ ++ if(operation >= TABLE_FULL_OP_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ /* Table full Operation */ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG1, RTL8367C_TABLE_FULL_OP_MASK, operation); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPTableFullOP ++ * Description: ++ * Get Table Full operation ++ * Input: ++ * None ++ * Output: ++ * poperation - The operation should be taken when the IGMP table is full. ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPTableFullOP(rtk_uint32 *poperation) ++{ ++ ret_t retVal; ++ rtk_uint32 value; ++ ++ /* Table full Operation */ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG1, RTL8367C_TABLE_FULL_OP_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *poperation = value; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPCRCErrOP ++ * Description: ++ * Set the operation when ASIC receive a Checksum error packet ++ * Input: ++ * operation -The operation when ASIC receive a Checksum error packet ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter is out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPCRCErrOP(rtk_uint32 operation) ++{ ++ ret_t retVal; ++ ++ if(operation >= CRC_ERR_OP_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ /* CRC Error Operation */ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_CKS_ERR_OP_MASK, operation); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPCRCErrOP ++ * Description: ++ * Get the operation when ASIC receive a Checksum error packet ++ * Input: ++ * None ++ * Output: ++ * poperation - The operation of Checksum error packet ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPCRCErrOP(rtk_uint32 *poperation) ++{ ++ ret_t retVal; ++ rtk_uint32 value; ++ ++ /* CRC Error Operation */ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_CKS_ERR_OP_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *poperation = value; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPFastLeaveEn ++ * Description: ++ * Enable/Disable Fast Leave ++ * Input: ++ * enabled - 1:enable Fast Leave; 0:disable Fast Leave ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPFastLeaveEn(rtk_uint32 enabled) ++{ ++ ret_t retVal; ++ ++ /* Fast Leave */ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_FAST_LEAVE_EN_MASK, (enabled >= 1) ? 1 : 0); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPFastLeaveEn ++ * Description: ++ * Get Fast Leave state ++ * Input: ++ * None ++ * Output: ++ * penabled - 1:enable Fast Leave; 0:disable Fast Leave ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPFastLeaveEn(rtk_uint32 *penabled) ++{ ++ ret_t retVal; ++ rtk_uint32 value; ++ ++ /* Fast Leave */ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_FAST_LEAVE_EN_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *penabled = value; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPLeaveTimer ++ * Description: ++ * Set the Leave timer of IGMP/MLD ++ * Input: ++ * leave_timer - Leave timer ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter is out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPLeaveTimer(rtk_uint32 leave_timer) ++{ ++ ret_t retVal; ++ ++ if(leave_timer > RTL8367C_MAX_LEAVE_TIMER) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ /* Leave timer */ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_LEAVE_TIMER_MASK, leave_timer); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPLeaveTimer ++ * Description: ++ * Get the Leave timer of IGMP/MLD ++ * Input: ++ * None ++ * Output: ++ * pleave_timer - Leave timer ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPLeaveTimer(rtk_uint32 *pleave_timer) ++{ ++ ret_t retVal; ++ rtk_uint32 value; ++ ++ /* Leave timer */ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_LEAVE_TIMER_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *pleave_timer = value; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPQueryInterval ++ * Description: ++ * Set Query Interval of IGMP/MLD ++ * Input: ++ * interval - Query Interval ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter is out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPQueryInterval(rtk_uint32 interval) ++{ ++ ret_t retVal; ++ ++ if(interval > RTL8367C_MAX_QUERY_INT) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ /* Query Interval */ ++ retVal = rtl8367c_setAsicReg(RTL8367C_REG_IGMP_MLD_CFG2, interval); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPQueryInterval ++ * Description: ++ * Get Query Interval of IGMP/MLD ++ * Input: ++ * None ++ * Output: ++ * pinterval - Query Interval ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPQueryInterval(rtk_uint32 *pinterval) ++{ ++ ret_t retVal; ++ rtk_uint32 value; ++ ++ /* Query Interval */ ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_IGMP_MLD_CFG2, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *pinterval = value; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPRobVar ++ * Description: ++ * Set Robustness Variable of IGMP/MLD ++ * Input: ++ * rob_var - Robustness Variable ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter is out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPRobVar(rtk_uint32 rob_var) ++{ ++ ret_t retVal; ++ ++ if(rob_var > RTL8367C_MAX_ROB_VAR) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ /* Bourstness variable */ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_ROBURSTNESS_VAR_MASK, rob_var); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPRobVar ++ * Description: ++ * Get Robustness Variable of IGMP/MLD ++ * Input: ++ * none ++ * Output: ++ * prob_var - Robustness Variable ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPRobVar(rtk_uint32 *prob_var) ++{ ++ ret_t retVal; ++ rtk_uint32 value; ++ ++ /* Bourstness variable */ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_ROBURSTNESS_VAR_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *prob_var = value; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPStaticRouterPort ++ * Description: ++ * Set IGMP static router port mask ++ * Input: ++ * pmsk - Static portmask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_MASK - Invalid port mask ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPStaticRouterPort(rtk_uint32 pmsk) ++{ ++ if(pmsk > RTL8367C_PORTMASK) ++ return RT_ERR_PORT_MASK; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_STATIC_ROUTER_PORT, RTL8367C_IGMP_STATIC_ROUTER_PORT_MASK, pmsk); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPStaticRouterPort ++ * Description: ++ * Get IGMP static router port mask ++ * Input: ++ * pmsk - Static portmask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPStaticRouterPort(rtk_uint32 *pmsk) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_STATIC_ROUTER_PORT, RTL8367C_IGMP_STATIC_ROUTER_PORT_MASK, pmsk); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPAllowDynamicRouterPort ++ * Description: ++ * Set IGMP dynamic router port allow mask ++ * Input: ++ * pmsk - Allow dynamic router port mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_MASK - Invalid port mask ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPAllowDynamicRouterPort(rtk_uint32 pmsk) ++{ ++ return rtl8367c_setAsicReg(RTL8367C_REG_IGMP_MLD_CFG4, pmsk); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPAllowDynamicRouterPort ++ * Description: ++ * Get IGMP dynamic router port allow mask ++ * Input: ++ * None. ++ * Output: ++ * pPmsk - Allow dynamic router port mask ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_MASK - Invalid port mask ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPAllowDynamicRouterPort(rtk_uint32 *pPmsk) ++{ ++ return rtl8367c_getAsicReg(RTL8367C_REG_IGMP_MLD_CFG4, pPmsk); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPdynamicRouterPort1 ++ * Description: ++ * Get 1st dynamic router port and timer ++ * Input: ++ * port - Physical port number (0~7) ++ * timer - router port timer ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPdynamicRouterPort1(rtk_uint32 *port, rtk_uint32 *timer) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_DYNAMIC_ROUTER_PORT, RTL8367C_D_ROUTER_PORT_1_MASK, port); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_DYNAMIC_ROUTER_PORT, RTL8367C_D_ROUTER_PORT_TMR_1_MASK, timer); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPdynamicRouterPort2 ++ * Description: ++ * Get 2nd dynamic router port and timer ++ * Input: ++ * port - Physical port number (0~7) ++ * timer - router port timer ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPdynamicRouterPort2(rtk_uint32 *port, rtk_uint32 *timer) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_DYNAMIC_ROUTER_PORT, RTL8367C_D_ROUTER_PORT_2_MASK, port); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_DYNAMIC_ROUTER_PORT, RTL8367C_D_ROUTER_PORT_TMR_2_MASK, timer); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPSuppression ++ * Description: ++ * Set the suppression function ++ * Input: ++ * report_supp_enabled - Report suppression, 1:Enable, 0:disable ++ * leave_supp_enabled - Leave suppression, 1:Enable, 0:disable ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPSuppression(rtk_uint32 report_supp_enabled, rtk_uint32 leave_supp_enabled) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_REPORT_SUPPRESSION_MASK, report_supp_enabled); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_LEAVE_SUPPRESSION_MASK, leave_supp_enabled); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPSuppression ++ * Description: ++ * Get the suppression function ++ * Input: ++ * report_supp_enabled - Report suppression, 1:Enable, 0:disable ++ * leave_supp_enabled - Leave suppression, 1:Enable, 0:disable ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPSuppression(rtk_uint32 *report_supp_enabled, rtk_uint32 *leave_supp_enabled) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_REPORT_SUPPRESSION_MASK, report_supp_enabled); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_LEAVE_SUPPRESSION_MASK, leave_supp_enabled); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPQueryRX ++ * Description: ++ * Set port-based Query packet RX allowance ++ * Input: ++ * port - port number ++ * allow_query - allowance of Query packet RX, 1:Allow, 0:Drop ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_PORT_ID - Error PORT ID ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPQueryRX(rtk_uint32 port, rtk_uint32 allow_query) ++{ ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ /* Allow Query */ ++ if (port < 8) ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_MASK, allow_query); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_MASK, allow_query); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPQueryRX ++ * Description: ++ * Get port-based Query packet RX allowance ++ * Input: ++ * port - port number ++ * Output: ++ * allow_query - allowance of Query packet RX, 1:Allow, 0:Drop ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_PORT_ID - Error PORT ID ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPQueryRX(rtk_uint32 port, rtk_uint32 *allow_query) ++{ ++ ret_t retVal; ++ rtk_uint32 value; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ /* Allow Query */ ++ if (port < 8) ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_QUERY_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ *allow_query = value; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPReportRX ++ * Description: ++ * Set port-based Report packet RX allowance ++ * Input: ++ * port - port number ++ * allow_report - allowance of Report packet RX, 1:Allow, 0:Drop ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_PORT_ID - Error PORT ID ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPReportRX(rtk_uint32 port, rtk_uint32 allow_report) ++{ ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(port < 8) ++ { ++ /* Allow Report */ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_MASK, allow_report); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_MASK, allow_report); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPReportRX ++ * Description: ++ * Get port-based Report packet RX allowance ++ * Input: ++ * port - port number ++ * Output: ++ * allow_report - allowance of Report packet RX, 1:Allow, 0:Drop ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_PORT_ID - Error PORT ID ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPReportRX(rtk_uint32 port, rtk_uint32 *allow_report) ++{ ++ ret_t retVal; ++ rtk_uint32 value; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(port < 8) ++ { ++ /* Allow Report */ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_REPORT_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ *allow_report = value; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPLeaveRX ++ * Description: ++ * Set port-based Leave packet RX allowance ++ * Input: ++ * port - port number ++ * allow_leave - allowance of Leave packet RX, 1:Allow, 0:Drop ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_PORT_ID - Error PORT ID ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPLeaveRX(rtk_uint32 port, rtk_uint32 allow_leave) ++{ ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(port < 8) ++ { ++ /* Allow Leave */ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_MASK, allow_leave); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_MASK, allow_leave); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPLeaveRX ++ * Description: ++ * Get port-based Leave packet RX allowance ++ * Input: ++ * port - port number ++ * Output: ++ * allow_leave - allowance of Leave packet RX, 1:Allow, 0:Drop ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_PORT_ID - Error PORT ID ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPLeaveRX(rtk_uint32 port, rtk_uint32 *allow_leave) ++{ ++ ret_t retVal; ++ rtk_uint32 value; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(port < 8) ++ { ++ /* Allow Leave */ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_LEAVE_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ *allow_leave = value; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPMRPRX ++ * Description: ++ * Set port-based Multicast Routing Protocol packet RX allowance ++ * Input: ++ * port - port number ++ * allow_mrp - allowance of Multicast Routing Protocol packet RX, 1:Allow, 0:Drop ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_PORT_ID - Error PORT ID ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPMRPRX(rtk_uint32 port, rtk_uint32 allow_mrp) ++{ ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(port < 8) ++ { ++ /* Allow Multicast Routing Protocol */ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_MASK, allow_mrp); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_MASK, allow_mrp); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPMRPRX ++ * Description: ++ * Get port-based Multicast Routing Protocol packet RX allowance ++ * Input: ++ * port - port number ++ * Output: ++ * allow_mrp - allowance of Multicast Routing Protocol packet RX, 1:Allow, 0:Drop ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_PORT_ID - Error PORT ID ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPMRPRX(rtk_uint32 port, rtk_uint32 *allow_mrp) ++{ ++ ret_t retVal; ++ rtk_uint32 value; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ /* Allow Multicast Routing Protocol */ ++ if(port < 8) ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MRP_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ *allow_mrp = value; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPMcDataRX ++ * Description: ++ * Set port-based Multicast data packet RX allowance ++ * Input: ++ * port - port number ++ * allow_mcdata - allowance of Multicast data packet RX, 1:Allow, 0:Drop ++ * Output: ++ * none ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_PORT_ID - Error PORT ID ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPMcDataRX(rtk_uint32 port, rtk_uint32 allow_mcdata) ++{ ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ /* Allow Multicast Data */ ++ if(port < 8) ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_MASK, allow_mcdata); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_MASK, allow_mcdata); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPMcDataRX ++ * Description: ++ * Get port-based Multicast data packet RX allowance ++ * Input: ++ * port - port number ++ * Output: ++ * allow_mcdata - allowance of Multicast data packet RX, 1:Allow, 0:Drop ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_PORT_ID - Error PORT ID ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPMcDataRX(rtk_uint32 port, rtk_uint32 *allow_mcdata) ++{ ++ ret_t retVal; ++ rtk_uint32 value; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ /* Allow Multicast data */ ++ if(port < 8) ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_ALLOW_MC_DATA_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ *allow_mcdata = value; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPv1Opeartion ++ * Description: ++ * Set port-based IGMPv1 Control packet action ++ * Input: ++ * port - port number ++ * igmpv1_op - IGMPv1 control packet action ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_PORT_ID - Error PORT ID ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPv1Opeartion(rtk_uint32 port, rtk_uint32 igmpv1_op) ++{ ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(igmpv1_op >= PROTOCOL_OP_END) ++ return RT_ERR_INPUT; ++ ++ /* IGMPv1 operation */ ++ if(port < 8) ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_MASK, igmpv1_op); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_MASK, igmpv1_op); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPv1Opeartion ++ * Description: ++ * Get port-based IGMPv1 Control packet action ++ * Input: ++ * port - port number ++ * Output: ++ * igmpv1_op - IGMPv1 control packet action ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_PORT_ID - Error PORT ID ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPv1Opeartion(rtk_uint32 port, rtk_uint32 *igmpv1_op) ++{ ++ ret_t retVal; ++ rtk_uint32 value; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ /* IGMPv1 operation */ ++ if(port < 8) ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV1_OP_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ *igmpv1_op = value; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPv2Opeartion ++ * Description: ++ * Set port-based IGMPv2 Control packet action ++ * Input: ++ * port - port number ++ * igmpv2_op - IGMPv2 control packet action ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_PORT_ID - Error PORT ID ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPv2Opeartion(rtk_uint32 port, rtk_uint32 igmpv2_op) ++{ ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(igmpv2_op >= PROTOCOL_OP_END) ++ return RT_ERR_INPUT; ++ ++ /* IGMPv2 operation */ ++ if(port < 8) ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_MASK, igmpv2_op); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_MASK, igmpv2_op); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPv2Opeartion ++ * Description: ++ * Get port-based IGMPv2 Control packet action ++ * Input: ++ * port - port number ++ * Output: ++ * igmpv2_op - IGMPv2 control packet action ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_PORT_ID - Error PORT ID ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPv2Opeartion(rtk_uint32 port, rtk_uint32 *igmpv2_op) ++{ ++ ret_t retVal; ++ rtk_uint32 value; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ /* IGMPv2 operation */ ++ if(port < 8) ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV2_OP_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ *igmpv2_op = value; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPv3Opeartion ++ * Description: ++ * Set port-based IGMPv3 Control packet action ++ * Input: ++ * port - port number ++ * igmpv3_op - IGMPv3 control packet action ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_PORT_ID - Error PORT ID ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPv3Opeartion(rtk_uint32 port, rtk_uint32 igmpv3_op) ++{ ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(igmpv3_op >= PROTOCOL_OP_END) ++ return RT_ERR_INPUT; ++ ++ /* IGMPv3 operation */ ++ if(port < 8) ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_MASK, igmpv3_op); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_MASK, igmpv3_op); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPv3Opeartion ++ * Description: ++ * Get port-based IGMPv3 Control packet action ++ * Input: ++ * port - port number ++ * Output: ++ * igmpv3_op - IGMPv3 control packet action ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_PORT_ID - Error PORT ID ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPv3Opeartion(rtk_uint32 port, rtk_uint32 *igmpv3_op) ++{ ++ ret_t retVal; ++ rtk_uint32 value; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ /* IGMPv3 operation */ ++ if(port < 8) ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_IGMPV3_OP_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ *igmpv3_op = value; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicMLDv1Opeartion ++ * Description: ++ * Set port-based MLDv1 Control packet action ++ * Input: ++ * port - port number ++ * mldv1_op - MLDv1 control packet action ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_PORT_ID - Error PORT ID ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicMLDv1Opeartion(rtk_uint32 port, rtk_uint32 mldv1_op) ++{ ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(mldv1_op >= PROTOCOL_OP_END) ++ return RT_ERR_INPUT; ++ ++ /* MLDv1 operation */ ++ if(port < 8) ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_MASK, mldv1_op); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_MASK, mldv1_op); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicMLDv1Opeartion ++ * Description: ++ * Get port-based MLDv1 Control packet action ++ * Input: ++ * port - port number ++ * Output: ++ * mldv1_op - MLDv1 control packet action ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_PORT_ID - Error PORT ID ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicMLDv1Opeartion(rtk_uint32 port, rtk_uint32 *mldv1_op) ++{ ++ ret_t retVal; ++ rtk_uint32 value; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ /* MLDv1 operation */ ++ if(port < 8) ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_MLDv1_OP_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ *mldv1_op = value; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicMLDv2Opeartion ++ * Description: ++ * Set port-based MLDv2 Control packet action ++ * Input: ++ * port - port number ++ * mldv2_op - MLDv2 control packet action ++ * Output: ++ * none ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_PORT_ID - Error PORT ID ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicMLDv2Opeartion(rtk_uint32 port, rtk_uint32 mldv2_op) ++{ ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(mldv2_op >= PROTOCOL_OP_END) ++ return RT_ERR_INPUT; ++ ++ /* MLDv2 operation */ ++ if(port < 8) ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_MASK, mldv2_op); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_MASK, mldv2_op); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicMLDv2Opeartion ++ * Description: ++ * Get port-based MLDv2 Control packet action ++ * Input: ++ * port - port number ++ * Output: ++ * mldv2_op - MLDv2 control packet action ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_PORT_ID - Error PORT ID ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicMLDv2Opeartion(rtk_uint32 port, rtk_uint32 *mldv2_op) ++{ ++ ret_t retVal; ++ rtk_uint32 value; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ /* MLDv2 operation */ ++ if(port < 8) ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT0_CONTROL + port, RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT8_CONTROL + port - 8, RTL8367C_IGMP_PORT0_CONTROL_MLDv2_OP_MASK, &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ *mldv2_op = value; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPPortMAXGroup ++ * Description: ++ * Set per-port Max group number ++ * Input: ++ * port - Physical port number (0~7) ++ * max_group - max IGMP group ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPPortMAXGroup(rtk_uint32 port, rtk_uint32 max_group) ++{ ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(max_group > RTL8367C_IGMP_MAX_GOUP) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(port < 8) ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT01_MAX_GROUP + (port/2), RTL8367C_PORT0_MAX_GROUP_MASK << (RTL8367C_PORT1_MAX_GROUP_OFFSET * (port%2)), max_group); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_PORT89_MAX_GROUP + (port/2), RTL8367C_PORT0_MAX_GROUP_MASK << (RTL8367C_PORT1_MAX_GROUP_OFFSET * (port%2)), max_group); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicIGMPPortMAXGroup ++ * Description: ++ * Get per-port Max group number ++ * Input: ++ * port - Physical port number (0~7) ++ * max_group - max IGMP group ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPPortMAXGroup(rtk_uint32 port, rtk_uint32 *max_group) ++{ ++ ret_t retVal; ++ rtk_uint32 value; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(port < 8) ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT01_MAX_GROUP + (port/2), RTL8367C_PORT0_MAX_GROUP_MASK << (RTL8367C_PORT1_MAX_GROUP_OFFSET * (port%2)), &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT89_MAX_GROUP + (port/2), RTL8367C_PORT0_MAX_GROUP_MASK << (RTL8367C_PORT1_MAX_GROUP_OFFSET * (port%2)), &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ *max_group = value; ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicIGMPPortCurrentGroup ++ * Description: ++ * Get per-port current group number ++ * Input: ++ * port - Physical port number (0~7) ++ * current_group - current IGMP group ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPPortCurrentGroup(rtk_uint32 port, rtk_uint32 *current_group) ++{ ++ ret_t retVal; ++ rtk_uint32 value; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(port < 8) ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT01_CURRENT_GROUP + (port/2), RTL8367C_PORT0_CURRENT_GROUP_MASK << (RTL8367C_PORT1_CURRENT_GROUP_OFFSET * (port%2)), &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_PORT89_CURRENT_GROUP + ((port - 8)/2), RTL8367C_PORT0_CURRENT_GROUP_MASK << (RTL8367C_PORT1_CURRENT_GROUP_OFFSET * (port%2)), &value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ *current_group = value; ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicIGMPGroup ++ * Description: ++ * Get IGMP group ++ * Input: ++ * idx - Group index (0~255) ++ * valid - valid bit ++ * grp - IGMP group ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - Group index is out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPGroup(rtk_uint32 idx, rtk_uint32 *valid, rtl8367c_igmpgroup *grp) ++{ ++ ret_t retVal; ++ rtk_uint32 regAddr, regData; ++ rtk_uint32 i; ++ rtk_uint32 groupInfo = 0; ++ ++ if(idx > RTL8367C_IGMP_MAX_GOUP) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ /* Write ACS_ADR register for data bits */ ++ regAddr = RTL8367C_TABLE_ACCESS_ADDR_REG; ++ regData = idx; ++ retVal = rtl8367c_setAsicReg(regAddr, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /* Write ACS_CMD register */ ++ regAddr = RTL8367C_TABLE_ACCESS_CTRL_REG; ++ regData = RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ, TB_TARGET_IGMP_GROUP); ++ retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /* Read Data Bits */ ++ regAddr = RTL8367C_TABLE_ACCESS_RDDATA_BASE; ++ for(i = 0 ;i <= 1; i++) ++ { ++ retVal = rtl8367c_getAsicReg(regAddr, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ groupInfo |= ((regData & 0xFFFF) << (i * 16)); ++ regAddr ++; ++ } ++ ++ grp->p0_timer = groupInfo & 0x00000007; ++ grp->p1_timer = (groupInfo >> 3) & 0x00000007; ++ grp->p2_timer = (groupInfo >> 6) & 0x00000007; ++ grp->p3_timer = (groupInfo >> 9) & 0x00000007; ++ grp->p4_timer = (groupInfo >> 12) & 0x00000007; ++ grp->p5_timer = (groupInfo >> 15) & 0x00000007; ++ grp->p6_timer = (groupInfo >> 18) & 0x00000007; ++ grp->p7_timer = (groupInfo >> 21) & 0x00000007; ++ grp->report_supp_flag = (groupInfo >> 24) & 0x00000001; ++ grp->p8_timer = (groupInfo >> 25) & 0x00000007; ++ grp->p9_timer = (groupInfo >> 28) & 0x00000007; ++ grp->p10_timer = (groupInfo >> 31) & 0x00000001; ++ ++ regAddr = RTL8367C_TABLE_ACCESS_RDDATA_BASE + 2; ++ retVal = rtl8367c_getAsicReg(regAddr, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ grp->p10_timer |= (regData & 0x00000003) << 1; ++ ++ /* Valid bit */ ++ retVal = rtl8367c_getAsicReg(RTL8367C_IGMP_GROUP_USAGE_REG(idx), ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *valid = ((regData & (0x0001 << (idx %16))) != 0) ? 1 : 0; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicIpMulticastPortIsoLeaky ++ * Description: ++ * Set IP multicast Port Isolation leaky ++ * Input: ++ * port - Physical port number (0~7) ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIpMulticastPortIsoLeaky(rtk_uint32 port, rtk_uint32 enabled) ++{ ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_IPMCAST_PORTISO_LEAKY_REG, (0x0001 << port), enabled); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIpMulticastPortIsoLeaky ++ * Description: ++ * Get IP multicast Port Isolation leaky ++ * Input: ++ * port - Physical port number (0~7) ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIpMulticastPortIsoLeaky(rtk_uint32 port, rtk_uint32 *enabled) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_IPMCAST_PORTISO_LEAKY_REG, (0x0001 << port), ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *enabled = regData; ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPReportLeaveFlood ++ * Description: ++ * Set IGMP/MLD Report/Leave flood ++ * Input: ++ * flood - 0: Reserved, 1: flooding to router ports, 2: flooding to all ports, 3: flooding to router port or to all ports if there is no router port ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPReportLeaveFlood(rtk_uint32 flood) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG3, RTL8367C_REPORT_LEAVE_FORWARD_MASK, flood); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPReportLeaveFlood ++ * Description: ++ * Get IGMP/MLD Report/Leave flood ++ * Input: ++ * None ++ * Output: ++ * pflood - 0: Reserved, 1: flooding to router ports, 2: flooding to all ports, 3: flooding to router port or to all ports if there is no router port ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPReportLeaveFlood(rtk_uint32 *pFlood) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_IGMP_MLD_CFG3, RTL8367C_REPORT_LEAVE_FORWARD_MASK, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *pFlood = regData; ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPDropLeaveZero ++ * Description: ++ * Set the function of droppping Leave packet with group IP = 0.0.0.0 ++ * Input: ++ * drop - 1: Drop, 0:Bypass ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPDropLeaveZero(rtk_uint32 drop) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG1, RTL8367C_DROP_LEAVE_ZERO_OFFSET, drop); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPDropLeaveZero ++ * Description: ++ * Get the function of droppping Leave packet with group IP = 0.0.0.0 ++ * Input: ++ * None ++ * Output: ++ * pDrop - 1: Drop, 0:Bypass ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPDropLeaveZero(rtk_uint32 *pDrop) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG1, RTL8367C_DROP_LEAVE_ZERO_OFFSET, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *pDrop = regData; ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPBypassStormCTRL ++ * Description: ++ * Set the function of bypass strom control for IGMP/MLD packet ++ * Input: ++ * bypass - 1: Bypass, 0:not bypass ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPBypassStormCTRL(rtk_uint32 bypass) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_DISCARD_STORM_FILTER_OFFSET, bypass); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPBypassStormCTRL ++ * Description: ++ * Set the function of bypass strom control for IGMP/MLD packet ++ * Input: ++ * None ++ * Output: ++ * pBypass - 1: Bypass, 0:not bypass ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPBypassStormCTRL(rtk_uint32 *pBypass) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_DISCARD_STORM_FILTER_OFFSET, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *pBypass = regData; ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPIsoLeaky ++ * Description: ++ * Set Port Isolation leaky for IGMP/MLD packet ++ * Input: ++ * leaky - 1: Leaky, 0:not leaky ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPIsoLeaky(rtk_uint32 leaky) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_PORTISO_LEAKY_OFFSET, leaky); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPIsoLeaky ++ * Description: ++ * Get Port Isolation leaky for IGMP/MLD packet ++ * Input: ++ * Noen ++ * Output: ++ * pLeaky - 1: Leaky, 0:not leaky ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPIsoLeaky(rtk_uint32 *pLeaky) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_PORTISO_LEAKY_OFFSET, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *pLeaky = regData; ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPVLANLeaky ++ * Description: ++ * Set VLAN leaky for IGMP/MLD packet ++ * Input: ++ * leaky - 1: Leaky, 0:not leaky ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPVLANLeaky(rtk_uint32 leaky) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_VLAN_LEAKY_OFFSET, leaky); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPVLANLeaky ++ * Description: ++ * Get VLAN leaky for IGMP/MLD packet ++ * Input: ++ * Noen ++ * Output: ++ * pLeaky - 1: Leaky, 0:not leaky ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPVLANLeaky(rtk_uint32 *pLeaky) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG0, RTL8367C_IGMP_MLD_VLAN_LEAKY_OFFSET, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *pLeaky = regData; ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicIGMPBypassGroup ++ * Description: ++ * Set IGMP/MLD Bypass group ++ * Input: ++ * bypassType - Bypass type ++ * enabled - enabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicIGMPBypassGroup(rtk_uint32 bypassType, rtk_uint32 enabled) ++{ ++ ret_t retVal; ++ rtk_uint32 offset; ++ ++ switch(bypassType) ++ { ++ case BYPASS_224_0_0_X: ++ offset = RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_0_OFFSET; ++ break; ++ case BYPASS_224_0_1_X: ++ offset = RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_1_OFFSET; ++ break; ++ case BYPASS_239_255_255_X: ++ offset = RTL8367C_IGMP_MLD_IP4_BYPASS_239_255_255_OFFSET; ++ break; ++ case BYPASS_IPV6_00XX: ++ offset = RTL8367C_IGMP_MLD_IP6_BYPASS_OFFSET; ++ break; ++ default: ++ return RT_ERR_INPUT; ++ } ++ ++ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG3, offset, enabled); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicIGMPBypassGroup ++ * Description: ++ * Get IGMP/MLD Bypass group ++ * Input: ++ * bypassType - Bypass type ++ * Output: ++ * pEnabled - enabled ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicIGMPBypassGroup(rtk_uint32 bypassType, rtk_uint32 *pEnabled) ++{ ++ ret_t retVal; ++ rtk_uint32 offset; ++ ++ switch(bypassType) ++ { ++ case BYPASS_224_0_0_X: ++ offset = RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_0_OFFSET; ++ break; ++ case BYPASS_224_0_1_X: ++ offset = RTL8367C_IGMP_MLD_IP4_BYPASS_224_0_1_OFFSET; ++ break; ++ case BYPASS_239_255_255_X: ++ offset = RTL8367C_IGMP_MLD_IP4_BYPASS_239_255_255_OFFSET; ++ break; ++ case BYPASS_IPV6_00XX: ++ offset = RTL8367C_IGMP_MLD_IP6_BYPASS_OFFSET; ++ break; ++ default: ++ return RT_ERR_INPUT; ++ } ++ ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_IGMP_MLD_CFG3, offset, pEnabled); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_inbwctrl.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_inbwctrl.c +new file mode 100644 +index 0000000000..abb36bec2d +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_inbwctrl.c +@@ -0,0 +1,164 @@ ++/* ++ * 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 : Ingress bandwidth control related functions ++ * ++ */ ++#include ++/* Function Name: ++ * rtl8367c_setAsicPortIngressBandwidth ++ * Description: ++ * Set per-port total ingress bandwidth ++ * Input: ++ * port - Physical port number (0~7) ++ * bandwidth - The total ingress bandwidth (unit: 8Kbps), 0x1FFFF:disable ++ * preifg - Include preamble and IFG, 0:Exclude, 1:Include ++ * enableFC - Action when input rate exceeds. 0: Drop 1: Flow Control ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortIngressBandwidth(rtk_uint32 port, rtk_uint32 bandwidth, rtk_uint32 preifg, rtk_uint32 enableFC) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint32 regAddr; ++ ++ /* Invalid input parameter */ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ if(bandwidth > RTL8367C_QOS_GRANULARTY_MAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ regAddr = RTL8367C_INGRESSBW_PORT_RATE_LSB_REG(port); ++ regData = bandwidth & RTL8367C_QOS_GRANULARTY_LSB_MASK; ++ retVal = rtl8367c_setAsicReg(regAddr, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ regAddr += 1; ++ regData = (bandwidth & RTL8367C_QOS_GRANULARTY_MSB_MASK) >> RTL8367C_QOS_GRANULARTY_MSB_OFFSET; ++ retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_INGRESSBW_RATE16_MASK, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ regAddr = RTL8367C_PORT_MISC_CFG_REG(port); ++ retVal = rtl8367c_setAsicRegBit(regAddr, RTL8367C_PORT0_MISC_CFG_INGRESSBW_IFG_OFFSET, preifg); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ regAddr = RTL8367C_PORT_MISC_CFG_REG(port); ++ retVal = rtl8367c_setAsicRegBit(regAddr, RTL8367C_PORT0_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET, enableFC); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicPortIngressBandwidth ++ * Description: ++ * Get per-port total ingress bandwidth ++ * Input: ++ * port - Physical port number (0~7) ++ * pBandwidth - The total ingress bandwidth (unit: 8Kbps), 0x1FFFF:disable ++ * pPreifg - Include preamble and IFG, 0:Exclude, 1:Include ++ * pEnableFC - Action when input rate exceeds. 0: Drop 1: Flow Control ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortIngressBandwidth(rtk_uint32 port, rtk_uint32* pBandwidth, rtk_uint32* pPreifg, rtk_uint32* pEnableFC) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint32 regAddr; ++ ++ /* Invalid input parameter */ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ regAddr = RTL8367C_INGRESSBW_PORT_RATE_LSB_REG(port); ++ retVal = rtl8367c_getAsicReg(regAddr, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *pBandwidth = regData; ++ ++ regAddr += 1; ++ retVal = rtl8367c_getAsicRegBits(regAddr, RTL8367C_INGRESSBW_PORT0_RATE_CTRL1_INGRESSBW_RATE16_MASK, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *pBandwidth |= (regData << RTL8367C_QOS_GRANULARTY_MSB_OFFSET); ++ ++ regAddr = RTL8367C_PORT_MISC_CFG_REG(port); ++ retVal = rtl8367c_getAsicRegBit(regAddr, RTL8367C_PORT0_MISC_CFG_INGRESSBW_IFG_OFFSET, pPreifg); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ regAddr = RTL8367C_PORT_MISC_CFG_REG(port); ++ retVal = rtl8367c_getAsicRegBit(regAddr, RTL8367C_PORT0_MISC_CFG_INGRESSBW_FLOWCTRL_OFFSET, pEnableFC); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicPortIngressBandwidthBypass ++ * Description: ++ * Set ingress bandwidth control bypasss 8899, RMA 01-80-C2-00-00-xx and IGMP ++ * Input: ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortIngressBandwidthBypass(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_SW_DUMMY0, RTL8367C_INGRESSBW_BYPASS_EN_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortIngressBandwidthBypass ++ * Description: ++ * Set ingress bandwidth control bypasss 8899, RMA 01-80-C2-00-00-xx and IGMP ++ * Input: ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortIngressBandwidthBypass(rtk_uint32* pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_SW_DUMMY0, RTL8367C_INGRESSBW_BYPASS_EN_OFFSET, pEnabled); ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_interrupt.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_interrupt.c +new file mode 100644 +index 0000000000..fb6cbcdf1f +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_interrupt.c +@@ -0,0 +1,205 @@ ++/* ++ * 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 : Interrupt related functions ++ * ++ */ ++#include ++/* Function Name: ++ * rtl8367c_setAsicInterruptPolarity ++ * Description: ++ * Set interrupt trigger polarity ++ * Input: ++ * polarity - 0:pull high 1: pull low ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicInterruptPolarity(rtk_uint32 polarity) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_INTR_CTRL, RTL8367C_INTR_CTRL_OFFSET, polarity); ++} ++/* Function Name: ++ * rtl8367c_getAsicInterruptPolarity ++ * Description: ++ * Get interrupt trigger polarity ++ * Input: ++ * pPolarity - 0:pull high 1: pull low ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicInterruptPolarity(rtk_uint32* pPolarity) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_INTR_CTRL, RTL8367C_INTR_CTRL_OFFSET, pPolarity); ++} ++/* Function Name: ++ * rtl8367c_setAsicInterruptMask ++ * Description: ++ * Set interrupt enable mask ++ * Input: ++ * imr - Interrupt mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicInterruptMask(rtk_uint32 imr) ++{ ++ return rtl8367c_setAsicReg(RTL8367C_REG_INTR_IMR, imr); ++} ++/* Function Name: ++ * rtl8367c_getAsicInterruptMask ++ * Description: ++ * Get interrupt enable mask ++ * Input: ++ * pImr - Interrupt mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicInterruptMask(rtk_uint32* pImr) ++{ ++ return rtl8367c_getAsicReg(RTL8367C_REG_INTR_IMR, pImr); ++} ++/* Function Name: ++ * rtl8367c_setAsicInterruptMask ++ * Description: ++ * Clear interrupt enable mask ++ * Input: ++ * ims - Interrupt status mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * This API can be used to clear ASIC interrupt status and register will be cleared by writting 1. ++ * [0]:Link change, ++ * [1]:Share meter exceed, ++ * [2]:Learn number overed, ++ * [3]:Speed Change, ++ * [4]:Tx special congestion ++ * [5]:1 second green feature ++ * [6]:loop detection ++ * [7]:interrupt from 8051 ++ * [8]:Cable diagnostic finish ++ * [9]:ACL action interrupt trigger ++ * [11]: Silent Start ++ */ ++ret_t rtl8367c_setAsicInterruptStatus(rtk_uint32 ims) ++{ ++ return rtl8367c_setAsicReg(RTL8367C_REG_INTR_IMS, ims); ++} ++/* Function Name: ++ * rtl8367c_getAsicInterruptStatus ++ * Description: ++ * Get interrupt enable mask ++ * Input: ++ * pIms - Interrupt status mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicInterruptStatus(rtk_uint32* pIms) ++{ ++ return rtl8367c_getAsicReg(RTL8367C_REG_INTR_IMS, pIms); ++} ++/* Function Name: ++ * rtl8367c_setAsicInterruptRelatedStatus ++ * Description: ++ * Clear interrupt status ++ * Input: ++ * type - per port Learn over, per-port speed change, per-port special congest, share meter exceed status ++ * status - exceed status, write 1 to clear ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicInterruptRelatedStatus(rtk_uint32 type, rtk_uint32 status) ++{ ++ CONST rtk_uint32 indicatorAddress[INTRST_END] = {RTL8367C_REG_LEARN_OVER_INDICATOR, ++ RTL8367C_REG_SPEED_CHANGE_INDICATOR, ++ RTL8367C_REG_SPECIAL_CONGEST_INDICATOR, ++ RTL8367C_REG_PORT_LINKDOWN_INDICATOR, ++ RTL8367C_REG_PORT_LINKUP_INDICATOR, ++ RTL8367C_REG_METER_OVERRATE_INDICATOR0, ++ RTL8367C_REG_METER_OVERRATE_INDICATOR1, ++ RTL8367C_REG_RLDP_LOOPED_INDICATOR, ++ RTL8367C_REG_RLDP_RELEASED_INDICATOR, ++ RTL8367C_REG_SYSTEM_LEARN_OVER_INDICATOR}; ++ ++ if(type >= INTRST_END ) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ return rtl8367c_setAsicReg(indicatorAddress[type], status); ++} ++/* Function Name: ++ * rtl8367c_getAsicInterruptRelatedStatus ++ * Description: ++ * Get interrupt status ++ * Input: ++ * type - per port Learn over, per-port speed change, per-port special congest, share meter exceed status ++ * pStatus - exceed status, write 1 to clear ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicInterruptRelatedStatus(rtk_uint32 type, rtk_uint32* pStatus) ++{ ++ CONST rtk_uint32 indicatorAddress[INTRST_END] = {RTL8367C_REG_LEARN_OVER_INDICATOR, ++ RTL8367C_REG_SPEED_CHANGE_INDICATOR, ++ RTL8367C_REG_SPECIAL_CONGEST_INDICATOR, ++ RTL8367C_REG_PORT_LINKDOWN_INDICATOR, ++ RTL8367C_REG_PORT_LINKUP_INDICATOR, ++ RTL8367C_REG_METER_OVERRATE_INDICATOR0, ++ RTL8367C_REG_METER_OVERRATE_INDICATOR1, ++ RTL8367C_REG_RLDP_LOOPED_INDICATOR, ++ RTL8367C_REG_RLDP_RELEASED_INDICATOR, ++ RTL8367C_REG_SYSTEM_LEARN_OVER_INDICATOR}; ++ ++ if(type >= INTRST_END ) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ return rtl8367c_getAsicReg(indicatorAddress[type], pStatus); ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_led.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_led.c +new file mode 100644 +index 0000000000..1189028161 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_led.c +@@ -0,0 +1,727 @@ ++/* ++ * 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 : LED related functions ++ * ++ */ ++#include ++/* Function Name: ++ * rtl8367c_setAsicLedIndicateInfoConfig ++ * Description: ++ * Set Leds indicated information mode ++ * Input: ++ * ledno - LED group number. There are 1 to 1 led mapping to each port in each led group ++ * config - Support 16 types configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * 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. Blinking every 43ms when collision happens. Low for full duplex, and high for half duplex mode. ++ * 0010 Link/Act Link, Activity Indicator. Low for link established. Link/Act Blinks every 43ms when the corresponding port is transmitting or receiving. ++ * 0011 Spd1000 1000Mb/s Speed Indicator. Low for 1000Mb/s. ++ * 0100 Spd100 100Mb/s Speed Indicator. Low for 100Mb/s. ++ * 0101 Spd10 10Mb/s Speed Indicator. Low for 10Mb/s. ++ * 0110 Spd1000/Act 1000Mb/s Speed/Activity Indicator. Low for 1000Mb/s. Blinks every 43ms when the corresponding port is transmitting or receiving. ++ * 0111 Spd100/Act 100Mb/s Speed/Activity Indicator. Low for 100Mb/s. Blinks every 43ms when the corresponding port is transmitting or receiving. ++ * 1000 Spd10/Act 10Mb/s Speed/Activity Indicator. Low for 10Mb/s. Blinks every 43ms when the corresponding port is transmitting or receiving. ++ * 1001 Spd100 (10)/Act 10/100Mb/s Speed/Activity Indicator. Low for 10/100Mb/s. Blinks every 43ms when the corresponding port is transmitting or receiving. ++ * 1010 Fiber Fiber link Indicator. Low for Fiber. ++ * 1011 Fault Auto-negotiation Fault Indicator. Low for Fault. ++ * 1100 Link/Rx Link, Activity Indicator. Low for link established. Link/Rx Blinks every 43ms when the corresponding port is transmitting. ++ * 1101 Link/Tx Link, Activity Indicator. Low for link established. Link/Tx Blinks every 43ms when the corresponding port is receiving. ++ * 1110 Master Link on Master Indicator. Low for link Master established. ++ * 1111 LED_Force Force LED output, LED output value reference ++ */ ++ret_t rtl8367c_setAsicLedIndicateInfoConfig(rtk_uint32 ledno, rtk_uint32 config) ++{ ++ ret_t retVal; ++ CONST rtk_uint16 bits[RTL8367C_LEDGROUPNO] = {RTL8367C_LED0_CFG_MASK, RTL8367C_LED1_CFG_MASK, RTL8367C_LED2_CFG_MASK}; ++ ++ if(ledno >= RTL8367C_LEDGROUPNO) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(config >= LEDCONF_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_CONFIGURATION, RTL8367C_LED_CONFIG_SEL_OFFSET, 0); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_LED_CONFIGURATION, bits[ledno], config); ++} ++/* Function Name: ++ * rtl8367c_getAsicLedIndicateInfoConfig ++ * Description: ++ * Get Leds indicated information mode ++ * Input: ++ * ledno - LED group number. There are 1 to 1 led mapping to each port in each led group ++ * pConfig - Support 16 types configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicLedIndicateInfoConfig(rtk_uint32 ledno, rtk_uint32* pConfig) ++{ ++ CONST rtk_uint16 bits[RTL8367C_LEDGROUPNO]= {RTL8367C_LED0_CFG_MASK, RTL8367C_LED1_CFG_MASK, RTL8367C_LED2_CFG_MASK}; ++ ++ if(ledno >= RTL8367C_LEDGROUPNO) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ /* Get register value */ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_LED_CONFIGURATION, bits[ledno], pConfig); ++} ++/* Function Name: ++ * rtl8367c_setAsicLedGroupMode ++ * Description: ++ * Set Led Group mode ++ * Input: ++ * mode - LED mode ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicLedGroupMode(rtk_uint32 mode) ++{ ++ ret_t retVal; ++ ++ /* Invalid input parameter */ ++ if(mode >= RTL8367C_LED_MODE_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_CONFIGURATION, RTL8367C_LED_CONFIG_SEL_OFFSET, 1); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_LED_CONFIGURATION, RTL8367C_DATA_LED_MASK, mode); ++} ++/* Function Name: ++ * rtl8367c_getAsicLedGroupMode ++ * Description: ++ * Get Led Group mode ++ * Input: ++ * pMode - LED mode ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicLedGroupMode(rtk_uint32* pMode) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LED_CONFIGURATION, RTL8367C_LED_CONFIG_SEL_OFFSET, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ if(regData!=1) ++ return RT_ERR_FAILED; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_LED_CONFIGURATION, RTL8367C_DATA_LED_MASK, pMode); ++} ++/* Function Name: ++ * rtl8367c_setAsicForceLeds ++ * Description: ++ * Set group LED mode ++ * Input: ++ * port - Physical port number (0~7) ++ * group - LED group number ++ * mode - LED mode ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicForceLed(rtk_uint32 port, rtk_uint32 group, rtk_uint32 mode) ++{ ++ rtk_uint16 regAddr; ++ ret_t retVal; ++ ++ /* Invalid input parameter */ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(group >= RTL8367C_LEDGROUPNO) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(mode >= LEDFORCEMODE_END) ++ return RT_ERR_OUT_OF_RANGE; ++ /* Set Related Registers */ ++ if(port < 8){ ++ regAddr = RTL8367C_LED_FORCE_MODE_BASE + (group << 1); ++ if((retVal = rtl8367c_setAsicRegBits(regAddr, 0x3 << (port * 2), mode)) != RT_ERR_OK) ++ return retVal; ++ }else if(port >= 8){ ++ regAddr = RTL8367C_REG_CPU_FORCE_LED0_CFG1 + (group << 1); ++ if((retVal = rtl8367c_setAsicRegBits(regAddr, 0x3 << ((port-8) * 2), mode)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicForceLed ++ * Description: ++ * Get group LED mode ++ * Input: ++ * port - Physical port number (0~7) ++ * group - LED group number ++ * pMode - LED mode ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicForceLed(rtk_uint32 port, rtk_uint32 group, rtk_uint32* pMode) ++{ ++ rtk_uint16 regAddr; ++ ret_t retVal; ++ ++ /* Invalid input parameter */ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(group >= RTL8367C_LEDGROUPNO) ++ return RT_ERR_INPUT; ++ ++ /* Get Related Registers */ ++ if(port < 8){ ++ regAddr = RTL8367C_LED_FORCE_MODE_BASE + (group << 1); ++ if((retVal = rtl8367c_getAsicRegBits(regAddr, 0x3 << (port * 2), pMode)) != RT_ERR_OK) ++ return retVal; ++ }else if(port >= 8){ ++ regAddr = RTL8367C_REG_CPU_FORCE_LED0_CFG1 + (group << 1); ++ if((retVal = rtl8367c_getAsicRegBits(regAddr, 0x3 << ((port-8) * 2), pMode)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicForceGroupLed ++ * Description: ++ * Turn on/off Led of all ports ++ * Input: ++ * group - LED group number ++ * mode - 0b00:normal mode, 0b01:force blink, 0b10:force off, 0b11:force on ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicForceGroupLed(rtk_uint32 groupmask, rtk_uint32 mode) ++{ ++ ret_t retVal; ++ rtk_uint32 i,bitmask; ++ CONST rtk_uint16 bits[3]= {0x0004,0x0010,0x0040}; ++ ++ /* Invalid input parameter */ ++ if(groupmask > RTL8367C_LEDGROUPMASK) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(mode >= LEDFORCEMODE_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ bitmask = 0; ++ for(i = 0; i < RTL8367C_LEDGROUPNO; i++) ++ { ++ if(groupmask & (1 << i)) ++ { ++ bitmask = bitmask | bits[i]; ++ } ++ ++ } ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_LED_FORCE_CTRL, RTL8367C_LED_FORCE_MODE_MASK, bitmask); ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_LED_FORCE_CTRL, RTL8367C_FORCE_MODE_MASK, mode); ++ ++ if(LEDFORCEMODE_NORMAL == mode) ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_LED_FORCE_CTRL, RTL8367C_LED_FORCE_MODE_MASK, 0); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicForceGroupLed ++ * Description: ++ * Turn on/off Led of all ports ++ * Input: ++ * group - LED group number ++ * pMode - 0b00:normal mode, 0b01:force blink, 0b10:force off, 0b11:force on ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicForceGroupLed(rtk_uint32* groupmask, rtk_uint32* pMode) ++{ ++ ret_t retVal; ++ rtk_uint32 i,regData; ++ CONST rtk_uint16 bits[3] = {0x0004,0x0010,0x0040}; ++ ++ /* Get Related Registers */ ++ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_LED_FORCE_CTRL, RTL8367C_LED_FORCE_MODE_MASK, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ for(i = 0; i< RTL8367C_LEDGROUPNO; i++) ++ { ++ if((regData & bits[i]) == bits[i]) ++ { ++ *groupmask = *groupmask | (1 << i); ++ } ++ } ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_LED_FORCE_CTRL, RTL8367C_FORCE_MODE_MASK, pMode); ++} ++/* Function Name: ++ * rtl8367c_setAsicLedBlinkRate ++ * Description: ++ * Set led blinking rate at mode 0 to mode 3 ++ * Input: ++ * blinkRate - Support 6 blink rates ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * LED blink rate can be at 43ms, 84ms, 120ms, 170ms, 340ms and 670ms ++ */ ++ret_t rtl8367c_setAsicLedBlinkRate(rtk_uint32 blinkRate) ++{ ++ if(blinkRate >= LEDBLINKRATE_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_LED_MODE, RTL8367C_SEL_LEDRATE_MASK, blinkRate); ++} ++/* Function Name: ++ * rtl8367c_getAsicLedBlinkRate ++ * Description: ++ * Get led blinking rate at mode 0 to mode 3 ++ * Input: ++ * pBlinkRate - Support 6 blink rates ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicLedBlinkRate(rtk_uint32* pBlinkRate) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_LED_MODE, RTL8367C_SEL_LEDRATE_MASK, pBlinkRate); ++} ++/* Function Name: ++ * rtl8367c_setAsicLedForceBlinkRate ++ * Description: ++ * Set LEd blinking rate for force mode led ++ * Input: ++ * blinkRate - Support 6 blink rates ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicLedForceBlinkRate(rtk_uint32 blinkRate) ++{ ++ if(blinkRate >= LEDFORCERATE_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_LED_MODE, RTL8367C_FORCE_RATE_MASK, blinkRate); ++} ++/* Function Name: ++ * rtl8367c_getAsicLedForceBlinkRate ++ * Description: ++ * Get LED blinking rate for force mode led ++ * Input: ++ * pBlinkRate - Support 6 blink rates ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicLedForceBlinkRate(rtk_uint32* pBlinkRate) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_LED_MODE, RTL8367C_FORCE_RATE_MASK, pBlinkRate); ++} ++ ++/* ++@func ret_t | rtl8367c_setAsicLedGroupEnable | Turn on/off Led of all system ports ++@parm rtk_uint32 | group | LED group id. ++@parm rtk_uint32 | portmask | LED port mask. ++@rvalue RT_ERR_OK | Success. ++@rvalue RT_ERR_SMI | SMI access error. ++@rvalue RT_ERR_PORT_ID | Invalid port number. ++@rvalue RT_ERR_INPUT | Invalid input value. ++@comm ++ The API can turn on/off leds of dedicated port while indicated information configuration of LED group is set to force mode. ++ */ ++ret_t rtl8367c_setAsicLedGroupEnable(rtk_uint32 group, rtk_uint32 portmask) ++{ ++ ret_t retVal; ++ rtk_uint32 regAddr; ++ rtk_uint32 regDataMask; ++ ++ if ( group >= RTL8367C_LEDGROUPNO ) ++ return RT_ERR_INPUT; ++ ++ regAddr = RTL8367C_REG_PARA_LED_IO_EN1 + group/2; ++ regDataMask = 0xFF << ((group%2)*8); ++ retVal = rtl8367c_setAsicRegBits(regAddr, regDataMask, portmask&0xff); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ regAddr = RTL8367C_REG_PARA_LED_IO_EN3; ++ regDataMask = 0x3 << (group*2); ++ retVal = rtl8367c_setAsicRegBits(regAddr, regDataMask, (portmask>>8)&0x7); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ ++ return RT_ERR_OK; ++} ++ ++/* ++@func ret_t | rtl8367c_getAsicLedGroupEnable | Get on/off status of Led of all system ports ++@parm rtk_uint32 | group | LED group id. ++@parm rtk_uint32 | *portmask | LED port mask. ++@rvalue RT_ERR_OK | Success. ++@rvalue RT_ERR_SMI | SMI access error. ++@rvalue RT_ERR_PORT_ID | Invalid port number. ++@rvalue RT_ERR_INPUT | Invalid input value. ++@comm ++ The API can turn on/off leds of dedicated port while indicated information configuration of LED group is set to force mode. ++ */ ++ret_t rtl8367c_getAsicLedGroupEnable(rtk_uint32 group, rtk_uint32 *portmask) ++{ ++ ret_t retVal; ++ rtk_uint32 regAddr; ++ rtk_uint32 regDataMask,regData; ++ ++ if ( group >= RTL8367C_LEDGROUPNO ) ++ return RT_ERR_INPUT; ++ ++ regAddr = RTL8367C_REG_PARA_LED_IO_EN1 + group/2; ++ regDataMask = 0xFF << ((group%2)*8); ++ retVal = rtl8367c_getAsicRegBits(regAddr, regDataMask, portmask); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ ++ regAddr = RTL8367C_REG_PARA_LED_IO_EN3; ++ regDataMask = 0x3 << (group*2); ++ retVal = rtl8367c_getAsicRegBits(regAddr, regDataMask, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *portmask = (regData << 8) | *portmask; ++ ++ return RT_ERR_OK; ++} ++ ++/* ++@func ret_t | rtl8367c_setAsicLedOperationMode | Set LED operation mode ++@parm rtk_uint32 | mode | LED mode. 1:scan mode 1, 2:parallel mode, 3:mdx mode (serial mode) ++@rvalue RT_ERR_OK | Success. ++@rvalue RT_ERR_SMI | SMI access error. ++@rvalue RT_ERR_INPUT | Invalid input value. ++@comm ++ The API can turn on/off led serial mode and set signal to active high/low. ++ */ ++ret_t rtl8367c_setAsicLedOperationMode(rtk_uint32 mode) ++{ ++ ret_t retVal; ++ ++ /* Invalid input parameter */ ++ if( mode >= LEDOP_END) ++ return RT_ERR_INPUT; ++ ++ switch(mode) ++ { ++ case LEDOP_PARALLEL: ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_LED_SELECT_OFFSET, 0))!= RT_ERR_OK) ++ return retVal; ++ /*Disable serial CLK mode*/ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SCAN0_LED_IO_EN1,RTL8367C_LED_SERI_CLK_EN_OFFSET, 0))!= RT_ERR_OK) ++ return retVal; ++ /*Disable serial DATA mode*/ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SCAN0_LED_IO_EN1,RTL8367C_LED_SERI_DATA_EN_OFFSET, 0))!= RT_ERR_OK) ++ return retVal; ++ break; ++ case LEDOP_SERIAL: ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_LED_SELECT_OFFSET, 1))!= RT_ERR_OK) ++ return retVal; ++ /*Enable serial CLK mode*/ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SCAN0_LED_IO_EN1,RTL8367C_LED_SERI_CLK_EN_OFFSET, 1))!= RT_ERR_OK) ++ return retVal; ++ /*Enable serial DATA mode*/ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SCAN0_LED_IO_EN1,RTL8367C_LED_SERI_DATA_EN_OFFSET, 1))!= RT_ERR_OK) ++ return retVal; ++ break; ++ default: ++ return RT_ERR_INPUT; ++ break; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++ ++/* ++@func ret_t | rtl8367c_getAsicLedOperationMode | Get LED OP mode setup ++@parm rtk_uint32*| mode | LED mode. 1:scan mode 1, 2:parallel mode, 3:mdx mode (serial mode) ++@rvalue RT_ERR_OK | Success. ++@rvalue RT_ERR_SMI | SMI access error. ++@rvalue RT_ERR_INPUT | Invalid input value. ++@comm ++ The API can get LED serial mode setup and get signal active high/low. ++ */ ++ret_t rtl8367c_getAsicLedOperationMode(rtk_uint32 *mode) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_LED_SELECT_OFFSET, ®Data))!= RT_ERR_OK) ++ return retVal; ++ ++ if (regData == 1) ++ *mode = LEDOP_SERIAL; ++ else if (regData == 0) ++ *mode = LEDOP_PARALLEL; ++ else ++ return RT_ERR_FAILED; ++ ++ return RT_ERR_OK; ++} ++ ++/* ++@func ret_t | rtl8367c_setAsicLedSerialModeConfig | Set LED serial mode ++@parm rtk_uint32 | active | Active High or Low. ++@rvalue RT_ERR_OK | Success. ++@rvalue RT_ERR_SMI | SMI access error. ++@rvalue RT_ERR_INPUT | Invalid input value. ++@comm ++ The API can turn on/off led serial mode and set signal to active high/low. ++ */ ++ret_t rtl8367c_setAsicLedSerialModeConfig(rtk_uint32 active, rtk_uint32 serimode) ++{ ++ ret_t retVal; ++ ++ /* Invalid input parameter */ ++ if( active >= LEDSERACT_MAX) ++ return RT_ERR_INPUT; ++ if( serimode >= LEDSER_MAX) ++ return RT_ERR_INPUT; ++ ++ /* Set Active High or Low */ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_SERI_LED_ACT_LOW_OFFSET, active)) != RT_ERR_OK) ++ return retVal; ++ ++ /*set to 8G mode (not 16G mode)*/ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_MODE, RTL8367C_DLINK_TIME_OFFSET, serimode))!= RT_ERR_OK) ++ return retVal; ++ ++ ++ return RT_ERR_OK; ++} ++ ++ ++/* ++@func ret_t | rtl8367c_getAsicLedSerialModeConfig | Get LED serial mode setup ++@parm rtk_uint32*| active | Active High or Low. ++@rvalue RT_ERR_OK | Success. ++@rvalue RT_ERR_SMI | SMI access error. ++@rvalue RT_ERR_INPUT | Invalid input value. ++@comm ++ The API can get LED serial mode setup and get signal active high/low. ++ */ ++ret_t rtl8367c_getAsicLedSerialModeConfig(rtk_uint32 *active, rtk_uint32 *serimode) ++{ ++ ret_t retVal; ++ ++ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_SERI_LED_ACT_LOW_OFFSET, active))!= RT_ERR_OK) ++ return retVal; ++ ++ /*get to 8G mode (not 16G mode)*/ ++ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LED_MODE, RTL8367C_DLINK_TIME_OFFSET, serimode))!= RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++ ++/* ++@func ret_t | rtl8367c_setAsicLedOutputEnable | Set LED output enable ++@parm rtk_uint32 | enabled | enable or disalbe. ++@rvalue RT_ERR_OK | Success. ++@rvalue RT_ERR_SMI | SMI access error. ++@rvalue RT_ERR_INPUT | Invalid input value. ++@comm ++ The API can turn on/off LED output Enable ++ */ ++ret_t rtl8367c_setAsicLedOutputEnable(rtk_uint32 enabled) ++{ ++ ret_t retVal; ++ rtk_uint32 regdata; ++ ++ if (enabled == 1) ++ regdata = 0; ++ else ++ regdata = 1; ++ ++ /* Enable/Disable H/W IGMP/MLD */ ++ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_LED_IO_DISABLE_OFFSET, regdata); ++ ++ return retVal; ++} ++ ++ ++/* ++@func ret_t | rtl8367c_getAsicLedOutputEnable | Get LED serial mode setup ++@parm rtk_uint32*| active | Active High or Low. ++@rvalue RT_ERR_OK | Success. ++@rvalue RT_ERR_SMI | SMI access error. ++@rvalue RT_ERR_INPUT | Invalid input value. ++@comm ++ The API can get LED serial mode setup and get signal active high/low. ++ */ ++ret_t rtl8367c_getAsicLedOutputEnable(rtk_uint32 *ptr_enabled) ++{ ++ ret_t retVal; ++ rtk_uint32 regdata; ++ ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LED_SYS_CONFIG, RTL8367C_LED_IO_DISABLE_OFFSET, ®data); ++ if (retVal != RT_ERR_OK) ++ return retVal; ++ ++ if (regdata == 1) ++ *ptr_enabled = 0; ++ else ++ *ptr_enabled = 1; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicLedSerialOutput ++ * Description: ++ * Set serial LED output group and portmask. ++ * Input: ++ * output - Serial LED output group ++ * pmask - Serial LED output portmask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicLedSerialOutput(rtk_uint32 output, rtk_uint32 pmask) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SERIAL_LED_CTRL, RTL8367C_SERIAL_LED_GROUP_NUM_MASK, output); ++ if (retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SERIAL_LED_CTRL, RTL8367C_SERIAL_LED_PORT_EN_MASK, pmask); ++ if (retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicLedSerialOutput ++ * Description: ++ * Get serial LED output group and portmask. ++ * Input: ++ * None ++ * Output: ++ * pOutput - Serial LED output group ++ * pPmask - Serial LED output portmask ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicLedSerialOutput(rtk_uint32 *pOutput, rtk_uint32 *pPmask) ++{ ++ ret_t retVal; ++ ++ if(pOutput == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ if(pPmask == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SERIAL_LED_CTRL, RTL8367C_SERIAL_LED_GROUP_NUM_MASK, pOutput); ++ if (retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SERIAL_LED_CTRL, RTL8367C_SERIAL_LED_PORT_EN_MASK, pPmask); ++ if (retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_lut.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_lut.c +new file mode 100644 +index 0000000000..343a6f159c +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_lut.c +@@ -0,0 +1,1549 @@ ++/* ++ * 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 : LUT related functions ++ * ++ */ ++ ++#include ++ ++#include ++ ++static void _rtl8367c_fdbStUser2Smi( rtl8367c_luttb *pLutSt, rtk_uint16 *pFdbSmi) ++{ ++ /* L3 lookup */ ++ if(pLutSt->l3lookup) ++ { ++ if(pLutSt->l3vidlookup) ++ { ++ pFdbSmi[0] = (pLutSt->sip & 0x0000FFFF); ++ pFdbSmi[1] = (pLutSt->sip & 0xFFFF0000) >> 16; ++ ++ pFdbSmi[2] = (pLutSt->dip & 0x0000FFFF); ++ pFdbSmi[3] = (pLutSt->dip & 0x0FFF0000) >> 16; ++ ++ pFdbSmi[3] |= (pLutSt->l3lookup & 0x0001) << 12; ++ pFdbSmi[3] |= (pLutSt->l3vidlookup & 0x0001) << 13; ++ pFdbSmi[3] |= ((pLutSt->mbr & 0x0300) >> 8) << 14; ++ ++ pFdbSmi[4] |= (pLutSt->mbr & 0x00FF); ++ pFdbSmi[4] |= (pLutSt->l3_vid & 0x00FF) << 8; ++ ++ pFdbSmi[5] |= ((pLutSt->l3_vid & 0x0F00) >> 8); ++ pFdbSmi[5] |= (pLutSt->nosalearn & 0x0001) << 5; ++ pFdbSmi[5] |= ((pLutSt->mbr & 0x0400) >> 10) << 7; ++ } ++ else ++ { ++ pFdbSmi[0] = (pLutSt->sip & 0x0000FFFF); ++ pFdbSmi[1] = (pLutSt->sip & 0xFFFF0000) >> 16; ++ ++ pFdbSmi[2] = (pLutSt->dip & 0x0000FFFF); ++ pFdbSmi[3] = (pLutSt->dip & 0x0FFF0000) >> 16; ++ ++ pFdbSmi[3] |= (pLutSt->l3lookup & 0x0001) << 12; ++ pFdbSmi[3] |= (pLutSt->l3vidlookup & 0x0001) << 13; ++ pFdbSmi[3] |= ((pLutSt->mbr & 0x0300) >> 8) << 14; ++ ++ pFdbSmi[4] |= (pLutSt->mbr & 0x00FF); ++ pFdbSmi[4] |= (pLutSt->igmpidx & 0x00FF) << 8; ++ ++ pFdbSmi[5] |= (pLutSt->igmp_asic & 0x0001); ++ pFdbSmi[5] |= (pLutSt->lut_pri & 0x0007) << 1; ++ pFdbSmi[5] |= (pLutSt->fwd_en & 0x0001) << 4; ++ pFdbSmi[5] |= (pLutSt->nosalearn & 0x0001) << 5; ++ pFdbSmi[5] |= ((pLutSt->mbr & 0x0400) >> 10) << 7; ++ } ++ } ++ else if(pLutSt->mac.octet[0] & 0x01) /*Multicast L2 Lookup*/ ++ { ++ pFdbSmi[0] |= pLutSt->mac.octet[5]; ++ pFdbSmi[0] |= pLutSt->mac.octet[4] << 8; ++ ++ pFdbSmi[1] |= pLutSt->mac.octet[3]; ++ pFdbSmi[1] |= pLutSt->mac.octet[2] << 8; ++ ++ pFdbSmi[2] |= pLutSt->mac.octet[1]; ++ pFdbSmi[2] |= pLutSt->mac.octet[0] << 8; ++ ++ pFdbSmi[3] |= pLutSt->cvid_fid; ++ pFdbSmi[3] |= (pLutSt->l3lookup & 0x0001) << 12; ++ pFdbSmi[3] |= (pLutSt->ivl_svl & 0x0001) << 13; ++ pFdbSmi[3] |= ((pLutSt->mbr & 0x0300) >> 8) << 14; ++ ++ pFdbSmi[4] |= (pLutSt->mbr & 0x00FF); ++ pFdbSmi[4] |= (pLutSt->igmpidx & 0x00FF) << 8; ++ ++ pFdbSmi[5] |= pLutSt->igmp_asic; ++ pFdbSmi[5] |= (pLutSt->lut_pri & 0x0007) << 1; ++ pFdbSmi[5] |= (pLutSt->fwd_en & 0x0001) << 4; ++ pFdbSmi[5] |= (pLutSt->nosalearn & 0x0001) << 5; ++ pFdbSmi[5] |= ((pLutSt->mbr & 0x0400) >> 10) << 7; ++ } ++ else /*Asic auto-learning*/ ++ { ++ pFdbSmi[0] |= pLutSt->mac.octet[5]; ++ pFdbSmi[0] |= pLutSt->mac.octet[4] << 8; ++ ++ pFdbSmi[1] |= pLutSt->mac.octet[3]; ++ pFdbSmi[1] |= pLutSt->mac.octet[2] << 8; ++ ++ pFdbSmi[2] |= pLutSt->mac.octet[1]; ++ pFdbSmi[2] |= pLutSt->mac.octet[0] << 8; ++ ++ pFdbSmi[3] |= pLutSt->cvid_fid; ++ pFdbSmi[3] |= (pLutSt->l3lookup & 0x0001) << 12; ++ pFdbSmi[3] |= (pLutSt->ivl_svl & 0x0001) << 13; ++ pFdbSmi[3] |= ((pLutSt->spa & 0x0008) >> 3) << 15; ++ ++ pFdbSmi[4] |= pLutSt->efid; ++ pFdbSmi[4] |= (pLutSt->fid & 0x000F) << 3; ++ pFdbSmi[4] |= (pLutSt->sa_en & 0x0001) << 7; ++ pFdbSmi[4] |= (pLutSt->spa & 0x0007) << 8; ++ pFdbSmi[4] |= (pLutSt->age & 0x0007) << 11; ++ pFdbSmi[4] |= (pLutSt->auth & 0x0001) << 14; ++ pFdbSmi[4] |= (pLutSt->sa_block & 0x0001) << 15; ++ ++ pFdbSmi[5] |= pLutSt->da_block; ++ pFdbSmi[5] |= (pLutSt->lut_pri & 0x0007) << 1; ++ pFdbSmi[5] |= (pLutSt->fwd_en & 0x0001) << 4; ++ pFdbSmi[5] |= (pLutSt->nosalearn & 0x0001) << 5; ++ } ++} ++ ++ ++static void _rtl8367c_fdbStSmi2User( rtl8367c_luttb *pLutSt, rtk_uint16 *pFdbSmi) ++{ ++ /*L3 lookup*/ ++ if(pFdbSmi[3] & 0x1000) ++ { ++ if(pFdbSmi[3] & 0x2000) ++ { ++ pLutSt->sip = pFdbSmi[0] | (pFdbSmi[1] << 16); ++ pLutSt->dip = pFdbSmi[2] | ((pFdbSmi[3] & 0x0FFF) << 16); ++ ++ pLutSt->mbr = (pFdbSmi[4] & 0x00FF) | (((pFdbSmi[3] & 0xC000) >> 14) << 8) | (((pFdbSmi[5] & 0x0080) >> 7) << 10); ++ pLutSt->l3_vid = ((pFdbSmi[4] & 0xFF00) >> 8) | (pFdbSmi[5] & 0x000F); ++ ++ pLutSt->l3lookup = (pFdbSmi[3] & 0x1000) >> 12; ++ pLutSt->l3vidlookup = (pFdbSmi[3] & 0x2000) >> 13; ++ pLutSt->nosalearn = (pFdbSmi[5] & 0x0020) >> 5; ++ } ++ else ++ { ++ pLutSt->sip = pFdbSmi[0] | (pFdbSmi[1] << 16); ++ pLutSt->dip = pFdbSmi[2] | ((pFdbSmi[3] & 0x0FFF) << 16); ++ ++ pLutSt->lut_pri = (pFdbSmi[5] & 0x000E) >> 1; ++ pLutSt->fwd_en = (pFdbSmi[5] & 0x0010) >> 4; ++ ++ pLutSt->mbr = (pFdbSmi[4] & 0x00FF) | (((pFdbSmi[3] & 0xC000) >> 14) << 8) | (((pFdbSmi[5] & 0x0080) >> 7) << 10); ++ pLutSt->igmpidx = (pFdbSmi[4] & 0xFF00) >> 8; ++ ++ pLutSt->igmp_asic = (pFdbSmi[5] & 0x0001); ++ pLutSt->l3lookup = (pFdbSmi[3] & 0x1000) >> 12; ++ pLutSt->nosalearn = (pFdbSmi[5] & 0x0020) >> 5; ++ } ++ } ++ else if(pFdbSmi[2] & 0x0100) /*Multicast L2 Lookup*/ ++ { ++ pLutSt->mac.octet[0] = (pFdbSmi[2] & 0xFF00) >> 8; ++ pLutSt->mac.octet[1] = (pFdbSmi[2] & 0x00FF); ++ pLutSt->mac.octet[2] = (pFdbSmi[1] & 0xFF00) >> 8; ++ pLutSt->mac.octet[3] = (pFdbSmi[1] & 0x00FF); ++ pLutSt->mac.octet[4] = (pFdbSmi[0] & 0xFF00) >> 8; ++ pLutSt->mac.octet[5] = (pFdbSmi[0] & 0x00FF); ++ ++ pLutSt->cvid_fid = pFdbSmi[3] & 0x0FFF; ++ pLutSt->lut_pri = (pFdbSmi[5] & 0x000E) >> 1; ++ pLutSt->fwd_en = (pFdbSmi[5] & 0x0010) >> 4; ++ ++ pLutSt->mbr = (pFdbSmi[4] & 0x00FF) | (((pFdbSmi[3] & 0xC000) >> 14) << 8) | (((pFdbSmi[5] & 0x0080) >> 7) << 10); ++ pLutSt->igmpidx = (pFdbSmi[4] & 0xFF00) >> 8; ++ ++ pLutSt->igmp_asic = (pFdbSmi[5] & 0x0001); ++ pLutSt->l3lookup = (pFdbSmi[3] & 0x1000) >> 12; ++ pLutSt->ivl_svl = (pFdbSmi[3] & 0x2000) >> 13; ++ pLutSt->nosalearn = (pFdbSmi[5] & 0x0020) >> 5; ++ } ++ else /*Asic auto-learning*/ ++ { ++ pLutSt->mac.octet[0] = (pFdbSmi[2] & 0xFF00) >> 8; ++ pLutSt->mac.octet[1] = (pFdbSmi[2] & 0x00FF); ++ pLutSt->mac.octet[2] = (pFdbSmi[1] & 0xFF00) >> 8; ++ pLutSt->mac.octet[3] = (pFdbSmi[1] & 0x00FF); ++ pLutSt->mac.octet[4] = (pFdbSmi[0] & 0xFF00) >> 8; ++ pLutSt->mac.octet[5] = (pFdbSmi[0] & 0x00FF); ++ ++ pLutSt->cvid_fid = pFdbSmi[3] & 0x0FFF; ++ pLutSt->lut_pri = (pFdbSmi[5] & 0x000E) >> 1; ++ pLutSt->fwd_en = (pFdbSmi[5] & 0x0010) >> 4; ++ ++ pLutSt->sa_en = (pFdbSmi[4] & 0x0080) >> 7; ++ pLutSt->auth = (pFdbSmi[4] & 0x4000) >> 14; ++ pLutSt->spa = ((pFdbSmi[4] & 0x0700) >> 8) | (((pFdbSmi[3] & 0x8000) >> 15) << 3); ++ pLutSt->age = (pFdbSmi[4] & 0x3800) >> 11; ++ pLutSt->fid = (pFdbSmi[4] & 0x0078) >> 3; ++ pLutSt->efid = (pFdbSmi[4] & 0x0007); ++ pLutSt->sa_block = (pFdbSmi[4] & 0x8000) >> 15; ++ ++ pLutSt->da_block = (pFdbSmi[5] & 0x0001); ++ pLutSt->l3lookup = (pFdbSmi[3] & 0x1000) >> 12; ++ pLutSt->ivl_svl = (pFdbSmi[3] & 0x2000) >> 13; ++ pLutSt->nosalearn = (pFdbSmi[3] & 0x0020) >> 5; ++ } ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicLutIpMulticastLookup ++ * Description: ++ * Set Lut IP multicast lookup function ++ * Input: ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicLutIpMulticastLookup(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LUT_IPMC_HASH_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicLutIpMulticastLookup ++ * Description: ++ * Get Lut IP multicast lookup function ++ * Input: ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicLutIpMulticastLookup(rtk_uint32* pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LUT_IPMC_HASH_OFFSET, pEnabled); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicLutIpMulticastLookup ++ * Description: ++ * Set Lut IP multicast + VID lookup function ++ * Input: ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicLutIpMulticastVidLookup(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG2, RTL8367C_LUT_IPMC_VID_HASH_OFFSET, enabled); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicLutIpMulticastVidLookup ++ * Description: ++ * Get Lut IP multicast lookup function ++ * Input: ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicLutIpMulticastVidLookup(rtk_uint32* pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG2, RTL8367C_LUT_IPMC_VID_HASH_OFFSET, pEnabled); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicLutIpLookupMethod ++ * Description: ++ * Set Lut IP lookup hash with DIP or {DIP,SIP} pair ++ * Input: ++ * type - 1: When DIP can be found in IPMC_GROUP_TABLE, use DIP+SIP Hash, otherwise, use DIP+(SIP=0.0.0.0) Hash. ++ * 0: When DIP can be found in IPMC_GROUP_TABLE, use DIP+(SIP=0.0.0.0) Hash, otherwise use DIP+SIP Hash. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicLutIpLookupMethod(rtk_uint32 type) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LUT_IPMC_LOOKUP_OP_OFFSET, type); ++} ++/* Function Name: ++ * rtl8367c_getAsicLutIpLookupMethod ++ * Description: ++ * Get Lut IP lookup hash with DIP or {DIP,SIP} pair ++ * Input: ++ * pType - 1: When DIP can be found in IPMC_GROUP_TABLE, use DIP+SIP Hash, otherwise, use DIP+(SIP=0.0.0.0) Hash. ++ * 0: When DIP can be found in IPMC_GROUP_TABLE, use DIP+(SIP=0.0.0.0) Hash, otherwise use DIP+SIP Hash. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicLutIpLookupMethod(rtk_uint32* pType) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LUT_IPMC_LOOKUP_OP_OFFSET, pType); ++} ++/* Function Name: ++ * rtl8367c_setAsicLutAgeTimerSpeed ++ * Description: ++ * Set LUT agging out speed ++ * Input: ++ * timer - Agging out timer 0:Has been aged out ++ * speed - Agging out speed 0-fastest 3-slowest ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicLutAgeTimerSpeed(rtk_uint32 timer, rtk_uint32 speed) ++{ ++ if(timer>RTL8367C_LUT_AGETIMERMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(speed >RTL8367C_LUT_AGESPEEDMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_LUT_CFG, RTL8367C_AGE_TIMER_MASK | RTL8367C_AGE_SPEED_MASK, (timer << RTL8367C_AGE_TIMER_OFFSET) | (speed << RTL8367C_AGE_SPEED_OFFSET)); ++} ++/* Function Name: ++ * rtl8367c_getAsicLutAgeTimerSpeed ++ * Description: ++ * Get LUT agging out speed ++ * Input: ++ * pTimer - Agging out timer 0:Has been aged out ++ * pSpeed - Agging out speed 0-fastest 3-slowest ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicLutAgeTimerSpeed(rtk_uint32* pTimer, rtk_uint32* pSpeed) ++{ ++ rtk_uint32 regData; ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_LUT_CFG, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *pTimer = (regData & RTL8367C_AGE_TIMER_MASK) >> RTL8367C_AGE_TIMER_OFFSET; ++ ++ *pSpeed = (regData & RTL8367C_AGE_SPEED_MASK) >> RTL8367C_AGE_SPEED_OFFSET; ++ ++ return RT_ERR_OK; ++ ++} ++/* Function Name: ++ * rtl8367c_setAsicLutCamTbUsage ++ * Description: ++ * Configure Lut CAM table usage ++ * Input: ++ * enabled - L2 CAM table usage 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicLutCamTbUsage(rtk_uint32 enabled) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_BCAM_DISABLE_OFFSET, enabled ? 0 : 1); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicLutCamTbUsage ++ * Description: ++ * Get Lut CAM table usage ++ * Input: ++ * pEnabled - L2 CAM table usage 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicLutCamTbUsage(rtk_uint32* pEnabled) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_BCAM_DISABLE_OFFSET, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEnabled = regData ? 0 : 1; ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicLutLearnLimitNo ++ * Description: ++ * Set per-Port auto learning limit number ++ * Input: ++ * port - Physical port number (0~7) ++ * number - ASIC auto learning entries limit number ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number ++ * Note: ++ * None ++ */ ++ /*ÐÞ¸Ä: RTL8367C_PORTIDMAX, RTL8367C_LUT_LEARNLIMITMAX, RTL8367C_LUT_PORT_LEARN_LIMITNO_REG*/ ++ret_t rtl8367c_setAsicLutLearnLimitNo(rtk_uint32 port, rtk_uint32 number) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(number > RTL8367C_LUT_LEARNLIMITMAX) ++ return RT_ERR_LIMITED_L2ENTRY_NUM; ++ ++ if(port < 8) ++ return rtl8367c_setAsicReg(RTL8367C_LUT_PORT_LEARN_LIMITNO_REG(port), number); ++ else ++ return rtl8367c_setAsicReg(RTL8367C_REG_LUT_PORT8_LEARN_LIMITNO+port-8, number); ++ ++} ++/* Function Name: ++ * rtl8367c_getAsicLutLearnLimitNo ++ * Description: ++ * Get per-Port auto learning limit number ++ * Input: ++ * port - Physical port number (0~7) ++ * pNumber - ASIC auto learning entries limit number ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ /*ÐÞ¸Ä: RTL8367C_PORTIDMAX, RTL8367C_LUT_PORT_LEARN_LIMITNO_REG*/ ++ret_t rtl8367c_getAsicLutLearnLimitNo(rtk_uint32 port, rtk_uint32* pNumber) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(port < 8) ++ return rtl8367c_getAsicReg(RTL8367C_LUT_PORT_LEARN_LIMITNO_REG(port), pNumber); ++ else ++ return rtl8367c_getAsicReg(RTL8367C_REG_LUT_PORT8_LEARN_LIMITNO+port-8, pNumber); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicSystemLutLearnLimitNo ++ * Description: ++ * Set system auto learning limit number ++ * Input: ++ * number - ASIC auto learning entries limit number ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_LIMITED_L2ENTRY_NUM - Invalid auto learning limit number ++ * Note: ++ * None ++ */ ++ /*ÐÞ¸Ä: RTL8367C_LUT_LEARNLIMITMAX*/ ++ret_t rtl8367c_setAsicSystemLutLearnLimitNo(rtk_uint32 number) ++{ ++ if(number > RTL8367C_LUT_LEARNLIMITMAX) ++ return RT_ERR_LIMITED_L2ENTRY_NUM; ++ ++ return rtl8367c_setAsicReg(RTL8367C_REG_LUT_SYS_LEARN_LIMITNO, number); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicSystemLutLearnLimitNo ++ * Description: ++ * Get system auto learning limit number ++ * Input: ++ * port - Physical port number (0~7) ++ * pNumber - ASIC auto learning entries limit number ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicSystemLutLearnLimitNo(rtk_uint32 *pNumber) ++{ ++ if(NULL == pNumber) ++ return RT_ERR_NULL_POINTER; ++ ++ return rtl8367c_getAsicReg(RTL8367C_REG_LUT_SYS_LEARN_LIMITNO, pNumber); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicLutLearnOverAct ++ * Description: ++ * Set auto learn over limit number action ++ * Input: ++ * action - Learn over action 0:normal, 1:drop 2:trap ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NOT_ALLOWED - Invalid learn over action ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicLutLearnOverAct(rtk_uint32 action) ++{ ++ if(action >= LRNOVERACT_END) ++ return RT_ERR_NOT_ALLOWED; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_SECURITY_CTRL, RTL8367C_LUT_LEARN_OVER_ACT_MASK, action); ++} ++/* Function Name: ++ * rtl8367c_getAsicLutLearnOverAct ++ * Description: ++ * Get auto learn over limit number action ++ * Input: ++ * pAction - Learn over action 0:normal, 1:drop 2:trap ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicLutLearnOverAct(rtk_uint32* pAction) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_SECURITY_CTRL, RTL8367C_LUT_LEARN_OVER_ACT_MASK, pAction); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicSystemLutLearnOverAct ++ * Description: ++ * Set system auto learn over limit number action ++ * Input: ++ * action - Learn over action 0:normal, 1:drop, 2:trap ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NOT_ALLOWED - Invalid learn over action ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicSystemLutLearnOverAct(rtk_uint32 action) ++{ ++ if(action >= LRNOVERACT_END) ++ return RT_ERR_NOT_ALLOWED; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_OVER_ACT_MASK, action); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicSystemLutLearnOverAct ++ * Description: ++ * Get system auto learn over limit number action ++ * Input: ++ * pAction - Learn over action 0:normal, 1:drop 2:trap ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicSystemLutLearnOverAct(rtk_uint32 *pAction) ++{ ++ if(NULL == pAction) ++ return RT_ERR_NULL_POINTER; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_OVER_ACT_MASK, pAction); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicSystemLutLearnPortMask ++ * Description: ++ * Set system auto learn limit port mask ++ * Input: ++ * portmask - port mask of system learning limit ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_MASK - Error port mask ++ * Note: ++ * None ++ */ ++ /*ÐÞ¸Ä: RTL8367C_LUT_SYSTEM_LEARN_PMASK_MASK*/ ++ret_t rtl8367c_setAsicSystemLutLearnPortMask(rtk_uint32 portmask) ++{ ++ ret_t retVal; ++ ++ if(portmask > RTL8367C_PORTMASK) ++ return RT_ERR_PORT_MASK; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_PMASK_MASK, portmask & 0xff); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_PMASK1_MASK, (portmask>>8) & 0x7); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++ ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicSystemLutLearnPortMask ++ * Description: ++ * Get system auto learn limit port mask ++ * Input: ++ * None ++ * Output: ++ * pPortmask - port mask of system learning limit ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NULL_POINTER - NULL pointer ++ * Note: ++ * None ++ */ ++ /*ÐÞ¸Ä: RTL8367C_LUT_SYSTEM_LEARN_PMASK_MASK*/ ++ret_t rtl8367c_getAsicSystemLutLearnPortMask(rtk_uint32 *pPortmask) ++{ ++ rtk_uint32 tmpmask; ++ ret_t retVal; ++ ++ if(NULL == pPortmask) ++ return RT_ERR_NULL_POINTER; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_PMASK_MASK, &tmpmask); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ *pPortmask = tmpmask & 0xff; ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_LUT_LRN_SYS_LMT_CTRL, RTL8367C_LUT_SYSTEM_LEARN_PMASK1_MASK, &tmpmask); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ *pPortmask |= (tmpmask & 0x7) << 8; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicL2LookupTb ++ * Description: ++ * Set filtering database entry ++ * Input: ++ * pL2Table - L2 table entry writing to 8K+64 filtering database ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicL2LookupTb(rtl8367c_luttb *pL2Table) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint16 *accessPtr; ++ rtk_uint32 i; ++ rtk_uint16 smil2Table[RTL8367C_LUT_TABLE_SIZE]; ++ rtk_uint32 tblCmd; ++ rtk_uint32 busyCounter; ++ ++ memset(smil2Table, 0x00, sizeof(rtk_uint16) * RTL8367C_LUT_TABLE_SIZE); ++ _rtl8367c_fdbStUser2Smi(pL2Table, smil2Table); ++ ++ if(pL2Table->wait_time == 0) ++ busyCounter = RTL8367C_LUT_BUSY_CHECK_NO; ++ else ++ busyCounter = pL2Table->wait_time; ++ ++ while(busyCounter) ++ { ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pL2Table->lookup_busy = regData; ++ if(!regData) ++ break; ++ ++ busyCounter --; ++ if(busyCounter == 0) ++ return RT_ERR_BUSYWAIT_TIMEOUT; ++ } ++ ++ accessPtr = smil2Table; ++ regData = *accessPtr; ++ for(i = 0; i < RTL8367C_LUT_ENTRY_SIZE; i++) ++ { ++ retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_WRDATA_BASE + i, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ accessPtr ++; ++ regData = *accessPtr; ++ ++ } ++ ++ tblCmd = (RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE,TB_TARGET_L2)) & (RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK); ++ /* Write Command */ ++ retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_CTRL_REG, tblCmd); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ if(pL2Table->wait_time == 0) ++ busyCounter = RTL8367C_LUT_BUSY_CHECK_NO; ++ else ++ busyCounter = pL2Table->wait_time; ++ ++ while(busyCounter) ++ { ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pL2Table->lookup_busy = regData; ++ if(!regData) ++ break; ++ ++ busyCounter --; ++ if(busyCounter == 0) ++ return RT_ERR_BUSYWAIT_TIMEOUT; ++ } ++ ++ /*Read access status*/ ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_HIT_STATUS_OFFSET, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pL2Table->lookup_hit = regData; ++ if(!pL2Table->lookup_hit) ++ return RT_ERR_FAILED; ++ ++ /*Read access address*/ ++ /* ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_TYPE_MASK | RTL8367C_TABLE_LUT_ADDR_ADDRESS_MASK,®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pL2Table->address = regData;*/ ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_TABLE_ACCESS_STATUS_REG, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pL2Table->address = (regData & 0x7ff) | ((regData & 0x4000) >> 3) | ((regData & 0x800) << 1); ++ pL2Table->lookup_busy = 0; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicL2LookupTb ++ * Description: ++ * Get filtering database entry ++ * Input: ++ * pL2Table - L2 table entry writing to 2K+64 filtering database ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameter ++ * RT_ERR_BUSYWAIT_TIMEOUT - LUT is busy at retrieving ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicL2LookupTb(rtk_uint32 method, rtl8367c_luttb *pL2Table) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint16* accessPtr; ++ rtk_uint32 i; ++ rtk_uint16 smil2Table[RTL8367C_LUT_TABLE_SIZE]; ++ rtk_uint32 busyCounter; ++ rtk_uint32 tblCmd; ++ ++ if(pL2Table->wait_time == 0) ++ busyCounter = RTL8367C_LUT_BUSY_CHECK_NO; ++ else ++ busyCounter = pL2Table->wait_time; ++ ++ while(busyCounter) ++ { ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pL2Table->lookup_busy = regData; ++ if(!pL2Table->lookup_busy) ++ break; ++ ++ busyCounter --; ++ if(busyCounter == 0) ++ return RT_ERR_BUSYWAIT_TIMEOUT; ++ } ++ ++ ++ tblCmd = (method << RTL8367C_ACCESS_METHOD_OFFSET) & RTL8367C_ACCESS_METHOD_MASK; ++ ++ switch(method) ++ { ++ case LUTREADMETHOD_ADDRESS: ++ case LUTREADMETHOD_NEXT_ADDRESS: ++ case LUTREADMETHOD_NEXT_L2UC: ++ case LUTREADMETHOD_NEXT_L2MC: ++ case LUTREADMETHOD_NEXT_L3MC: ++ case LUTREADMETHOD_NEXT_L2L3MC: ++ retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_ADDR_REG, pL2Table->address); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ break; ++ case LUTREADMETHOD_MAC: ++ memset(smil2Table, 0x00, sizeof(rtk_uint16) * RTL8367C_LUT_TABLE_SIZE); ++ _rtl8367c_fdbStUser2Smi(pL2Table, smil2Table); ++ ++ accessPtr = smil2Table; ++ regData = *accessPtr; ++ for(i=0; iaddress); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ tblCmd = tblCmd | ((pL2Table->spa << RTL8367C_TABLE_ACCESS_CTRL_SPA_OFFSET) & RTL8367C_TABLE_ACCESS_CTRL_SPA_MASK); ++ ++ break; ++ default: ++ return RT_ERR_INPUT; ++ } ++ ++ tblCmd = tblCmd | ((RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ,TB_TARGET_L2)) & (RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK)); ++ /* Read Command */ ++ retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_CTRL_REG, tblCmd); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ if(pL2Table->wait_time == 0) ++ busyCounter = RTL8367C_LUT_BUSY_CHECK_NO; ++ else ++ busyCounter = pL2Table->wait_time; ++ ++ while(busyCounter) ++ { ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pL2Table->lookup_busy = regData; ++ if(!pL2Table->lookup_busy) ++ break; ++ ++ busyCounter --; ++ if(busyCounter == 0) ++ return RT_ERR_BUSYWAIT_TIMEOUT; ++ } ++ ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_HIT_STATUS_OFFSET,®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ pL2Table->lookup_hit = regData; ++ if(!pL2Table->lookup_hit) ++ return RT_ERR_L2_ENTRY_NOTFOUND; ++ ++ /*Read access address*/ ++ //retVal = rtl8367c_getAsicRegBits(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_TYPE_MASK | RTL8367C_TABLE_LUT_ADDR_ADDRESS_MASK,®Data); ++ retVal = rtl8367c_getAsicReg(RTL8367C_TABLE_ACCESS_STATUS_REG, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pL2Table->address = (regData & 0x7ff) | ((regData & 0x4000) >> 3) | ((regData & 0x800) << 1); ++ ++ /*read L2 entry */ ++ memset(smil2Table, 0x00, sizeof(rtk_uint16) * RTL8367C_LUT_TABLE_SIZE); ++ ++ accessPtr = smil2Table; ++ ++ for(i = 0; i < RTL8367C_LUT_ENTRY_SIZE; i++) ++ { ++ retVal = rtl8367c_getAsicReg(RTL8367C_TABLE_ACCESS_RDDATA_BASE + i, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *accessPtr = regData; ++ ++ accessPtr ++; ++ } ++ ++ _rtl8367c_fdbStSmi2User(pL2Table, smil2Table); ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicLutLearnNo ++ * Description: ++ * Get per-Port auto learning number ++ * Input: ++ * port - Physical port number (0~7) ++ * pNumber - ASIC auto learning entries number ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ /*ÐÞ¸ÄRTL8367C_PORTIDMAX, RTL8367C_REG_L2_LRN_CNT_REG, port10 reg is not contnious, wait for updating of base.h*/ ++ret_t rtl8367c_getAsicLutLearnNo(rtk_uint32 port, rtk_uint32* pNumber) ++{ ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(port < 10) ++ { ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_L2_LRN_CNT_REG(port), pNumber); ++ if (retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_L2_LRN_CNT_CTRL10, pNumber); ++ if (retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicLutFlushAll ++ * Description: ++ * Flush all entries in LUT. Includes static & dynamic entries ++ * Input: ++ * None ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicLutFlushAll(void) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_L2_FLUSH_CTRL3, RTL8367C_L2_FLUSH_CTRL3_OFFSET, 1); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicLutFlushAllStatus ++ * Description: ++ * Get Flush all status, 1:Busy, 0 normal ++ * Input: ++ * None ++ * Output: ++ * pBusyStatus - Busy state ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NULL_POINTER - Null pointer ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicLutFlushAllStatus(rtk_uint32 *pBusyStatus) ++{ ++ if(NULL == pBusyStatus) ++ return RT_ERR_NULL_POINTER; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_L2_FLUSH_CTRL3, RTL8367C_L2_FLUSH_CTRL3_OFFSET, pBusyStatus); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicLutForceFlush ++ * Description: ++ * Set per port force flush setting ++ * Input: ++ * portmask - portmask(0~0xFF) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_MASK - Invalid portmask ++ * Note: ++ * None ++ */ ++ /*port8~port10µÄÉèÖÃÔÚÁíÍâÒ»¸öregister, wait for updating of base.h, reg.h*/ ++ret_t rtl8367c_setAsicLutForceFlush(rtk_uint32 portmask) ++{ ++ ret_t retVal; ++ ++ if(portmask > RTL8367C_PORTMASK) ++ return RT_ERR_PORT_MASK; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_FORCE_FLUSH_REG, RTL8367C_FORCE_FLUSH_PORTMASK_MASK, portmask & 0xff); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_FORCE_FLUSH1, RTL8367C_PORTMASK1_MASK, (portmask >> 8) & 0x7); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicLutForceFlushStatus ++ * Description: ++ * Get per port force flush status ++ * Input: ++ * pPortmask - portmask(0~0xFF) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ /*port8~port10µÄÉèÖÃÔÚÁíÍâÒ»¸öregister, wait for updating of base.h, reg.h*/ ++ret_t rtl8367c_getAsicLutForceFlushStatus(rtk_uint32 *pPortmask) ++{ ++ rtk_uint32 tmpMask; ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_FORCE_FLUSH_REG, RTL8367C_BUSY_STATUS_MASK,&tmpMask); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ *pPortmask = tmpMask & 0xff; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_FORCE_FLUSH1, RTL8367C_BUSY_STATUS1_MASK,&tmpMask); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ *pPortmask |= (tmpMask & 7) << 8; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicLutFlushMode ++ * Description: ++ * Set user force L2 pLutSt table flush mode ++ * Input: ++ * mode - 0:Port based 1: Port + VLAN based 2:Port + FID/MSTI based ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NOT_ALLOWED - Actions not allowed by the function ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicLutFlushMode(rtk_uint32 mode) ++{ ++ if( mode >= FLUSHMDOE_END ) ++ return RT_ERR_NOT_ALLOWED; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL2, RTL8367C_LUT_FLUSH_MODE_MASK, mode); ++} ++/* Function Name: ++ * rtl8367c_getAsicLutFlushMode ++ * Description: ++ * Get user force L2 pLutSt table flush mode ++ * Input: ++ * pMode - 0:Port based 1: Port + VLAN based 2:Port + FID/MSTI based ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicLutFlushMode(rtk_uint32* pMode) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL2, RTL8367C_LUT_FLUSH_MODE_MASK, pMode); ++} ++/* Function Name: ++ * rtl8367c_setAsicLutFlushType ++ * Description: ++ * Get L2 LUT flush type ++ * Input: ++ * type - 0: dynamice unicast; 1: both dynamic and static unicast entry ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicLutFlushType(rtk_uint32 type) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_L2_FLUSH_CTRL2, RTL8367C_LUT_FLUSH_TYPE_OFFSET,type); ++} ++/* Function Name: ++ * rtl8367c_getAsicLutFlushType ++ * Description: ++ * Set L2 LUT flush type ++ * Input: ++ * pType - 0: dynamice unicast; 1: both dynamic and static unicast entry ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicLutFlushType(rtk_uint32* pType) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_L2_FLUSH_CTRL2, RTL8367C_LUT_FLUSH_TYPE_OFFSET,pType); ++} ++ ++ ++/* Function Name: ++ * rtl8367c_setAsicLutFlushVid ++ * Description: ++ * Set VID of Port + VID pLutSt flush mode ++ * Input: ++ * vid - Vid (0~4095) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_VLAN_VID - Invalid VID parameter (0~4095) ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicLutFlushVid(rtk_uint32 vid) ++{ ++ if( vid > RTL8367C_VIDMAX ) ++ return RT_ERR_VLAN_VID; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL1, RTL8367C_LUT_FLUSH_VID_MASK, vid); ++} ++/* Function Name: ++ * rtl8367c_getAsicLutFlushVid ++ * Description: ++ * Get VID of Port + VID pLutSt flush mode ++ * Input: ++ * pVid - Vid (0~4095) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicLutFlushVid(rtk_uint32* pVid) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL1, RTL8367C_LUT_FLUSH_VID_MASK, pVid); ++} ++/* Function Name: ++ * rtl8367c_setAsicPortFlusdFid ++ * Description: ++ * Set FID of Port + FID pLutSt flush mode ++ * Input: ++ * fid - FID/MSTI for force flush ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_L2_FID - Invalid FID (0~15) ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicLutFlushFid(rtk_uint32 fid) ++{ ++ if( fid > RTL8367C_FIDMAX ) ++ return RT_ERR_L2_FID; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL1, RTL8367C_LUT_FLUSH_FID_MASK, fid); ++} ++/* Function Name: ++ * rtl8367c_getAsicLutFlushFid ++ * Description: ++ * Get FID of Port + FID pLutSt flush mode ++ * Input: ++ * pFid - FID/MSTI for force flush ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicLutFlushFid(rtk_uint32* pFid) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_L2_FLUSH_CTRL1, RTL8367C_LUT_FLUSH_FID_MASK, pFid); ++} ++/* Function Name: ++ * rtl8367c_setAsicLutDisableAging ++ * Description: ++ * Set L2 LUT aging per port setting ++ * Input: ++ * port - Physical port number (0~7) ++ * disabled - 0: enable aging; 1: disabling aging ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ /*ÐÞ¸ÄRTL8367C_PORTIDMAX*/ ++ret_t rtl8367c_setAsicLutDisableAging(rtk_uint32 port, rtk_uint32 disabled) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_LUT_AGEOUT_CTRL_REG, port, disabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicLutDisableAging ++ * Description: ++ * Get L2 LUT aging per port setting ++ * Input: ++ * port - Physical port number (0~7) ++ * pDisabled - 0: enable aging; 1: disabling aging ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ /*ÐÞ¸ÄRTL8367C_PORTIDMAX*/ ++ret_t rtl8367c_getAsicLutDisableAging(rtk_uint32 port, rtk_uint32 *pDisabled) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_LUT_AGEOUT_CTRL_REG, port, pDisabled); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicLutIPMCGroup ++ * Description: ++ * Set IPMC Group Table ++ * Input: ++ * index - the entry index in table (0 ~ 63) ++ * group_addr - the multicast group address (224.0.0.0 ~ 239.255.255.255) ++ * vid - VLAN ID ++ * pmask - portmask ++ * valid - valid bit ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid parameter ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicLutIPMCGroup(rtk_uint32 index, ipaddr_t group_addr, rtk_uint32 vid, rtk_uint32 pmask, rtk_uint32 valid) ++{ ++ rtk_uint32 regAddr, regData, bitoffset; ++ ipaddr_t ipData; ++ ret_t retVal; ++ ++ if(index > RTL8367C_LUT_IPMCGRP_TABLE_MAX) ++ return RT_ERR_INPUT; ++ ++ if (vid > RTL8367C_VIDMAX) ++ return RT_ERR_VLAN_VID; ++ ++ ipData = group_addr; ++ ++ if( (ipData & 0xF0000000) != 0xE0000000) /* not in 224.0.0.0 ~ 239.255.255.255 */ ++ return RT_ERR_INPUT; ++ ++ /* Group Address */ ++ regAddr = RTL8367C_REG_IPMC_GROUP_ENTRY0_H + (index * 2); ++ regData = ((ipData & 0x0FFFFFFF) >> 16); ++ ++ if( (retVal = rtl8367c_setAsicReg(regAddr, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ regAddr++; ++ regData = (ipData & 0x0000FFFF); ++ ++ if( (retVal = rtl8367c_setAsicReg(regAddr, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ /* VID */ ++ regAddr = RTL8367C_REG_IPMC_GROUP_VID_00 + index; ++ regData = vid; ++ ++ if( (retVal = rtl8367c_setAsicReg(regAddr, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ /* portmask */ ++ regAddr = RTL8367C_REG_IPMC_GROUP_PMSK_00 + index; ++ regData = pmask; ++ ++ if( (retVal = rtl8367c_setAsicReg(regAddr, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ /* valid */ ++ regAddr = RTL8367C_REG_IPMC_GROUP_VALID_15_0 + (index / 16); ++ bitoffset = index % 16; ++ if( (retVal = rtl8367c_setAsicRegBit(regAddr, bitoffset, valid)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicLutIPMCGroup ++ * Description: ++ * Set IPMC Group Table ++ * Input: ++ * index - the entry index in table (0 ~ 63) ++ * Output: ++ * pGroup_addr - the multicast group address (224.0.0.0 ~ 239.255.255.255) ++ * pVid - VLAN ID ++ * pPmask - portmask ++ * pValid - Valid bit ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid parameter ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicLutIPMCGroup(rtk_uint32 index, ipaddr_t *pGroup_addr, rtk_uint32 *pVid, rtk_uint32 *pPmask, rtk_uint32 *pValid) ++{ ++ rtk_uint32 regAddr, regData, bitoffset; ++ ipaddr_t ipData; ++ ret_t retVal; ++ ++ if(index > RTL8367C_LUT_IPMCGRP_TABLE_MAX) ++ return RT_ERR_INPUT; ++ ++ if (NULL == pGroup_addr) ++ return RT_ERR_NULL_POINTER; ++ ++ if (NULL == pVid) ++ return RT_ERR_NULL_POINTER; ++ ++ if (NULL == pPmask) ++ return RT_ERR_NULL_POINTER; ++ ++ /* Group address */ ++ regAddr = RTL8367C_REG_IPMC_GROUP_ENTRY0_H + (index * 2); ++ if( (retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ *pGroup_addr = (((regData & 0x00000FFF) << 16) | 0xE0000000); ++ ++ regAddr++; ++ if( (retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ ipData = (*pGroup_addr | (regData & 0x0000FFFF)); ++ *pGroup_addr = ipData; ++ ++ /* VID */ ++ regAddr = RTL8367C_REG_IPMC_GROUP_VID_00 + index; ++ if( (retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ *pVid = regData; ++ ++ /* portmask */ ++ regAddr = RTL8367C_REG_IPMC_GROUP_PMSK_00 + index; ++ if( (retVal = rtl8367c_getAsicReg(regAddr, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ *pPmask = regData; ++ ++ /* valid */ ++ regAddr = RTL8367C_REG_IPMC_GROUP_VALID_15_0 + (index / 16); ++ bitoffset = index % 16; ++ if( (retVal = rtl8367c_getAsicRegBit(regAddr, bitoffset, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ *pValid = regData; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicLutLinkDownForceAging ++ * Description: ++ * Set LUT link down aging setting. ++ * Input: ++ * enable - link down aging setting ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_ENABLE - Invalid parameter ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicLutLinkDownForceAging(rtk_uint32 enable) ++{ ++ if(enable > 1) ++ return RT_ERR_ENABLE; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LINKDOWN_AGEOUT_OFFSET, enable ? 0 : 1); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicLutLinkDownForceAging ++ * Description: ++ * Get LUT link down aging setting. ++ * Input: ++ * pEnable - link down aging setting ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_ENABLE - Invalid parameter ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicLutLinkDownForceAging(rtk_uint32 *pEnable) ++{ ++ rtk_uint32 value; ++ ret_t retVal; ++ ++ if ((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG, RTL8367C_LINKDOWN_AGEOUT_OFFSET, &value)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEnable = value ? 0 : 1; ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicLutIpmcFwdRouterPort ++ * Description: ++ * Set IPMC packet forward to rounter port also or not ++ * Input: ++ * enable - 1: Inlcude router port, 0, exclude router port ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_ENABLE Invalid parameter ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicLutIpmcFwdRouterPort(rtk_uint32 enable) ++{ ++ if(enable > 1) ++ return RT_ERR_ENABLE; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_LUT_CFG2, RTL8367C_LUT_IPMC_FWD_RPORT_OFFSET, enable); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicLutIpmcFwdRouterPort ++ * Description: ++ * Get IPMC packet forward to rounter port also or not ++ * Input: ++ * None ++ * Output: ++ * pEnable - 1: Inlcude router port, 0, exclude router port ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NULL_POINTER - Null pointer ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicLutIpmcFwdRouterPort(rtk_uint32 *pEnable) ++{ ++ if(NULL == pEnable) ++ return RT_ERR_NULL_POINTER; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_LUT_CFG2, RTL8367C_LUT_IPMC_FWD_RPORT_OFFSET, pEnable); ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_meter.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_meter.c +new file mode 100644 +index 0000000000..5412591a82 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_meter.c +@@ -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 ++ * ++ * $Revision: 76306 $ ++ * $Date: 2017-03-08 15:13:58 +0800 (週三, 08 三月 2017) $ ++ * ++ * Purpose : RTL8367C switch high-level API for RTL8367C ++ * Feature : Shared meter related functions ++ * ++ */ ++#include ++/* Function Name: ++ * rtl8367c_setAsicShareMeter ++ * Description: ++ * Set meter configuration ++ * Input: ++ * index - hared meter index (0-31) ++ * rate - 17-bits rate of share meter, unit is 8Kpbs ++ * ifg - Including IFG in rate calculation, 1:include 0:exclude ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_FILTER_METER_ID - Invalid meter ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicShareMeter(rtk_uint32 index, rtk_uint32 rate, rtk_uint32 ifg) ++{ ++ ret_t retVal; ++ ++ if(index > RTL8367C_METERMAX) ++ return RT_ERR_FILTER_METER_ID; ++ ++ if(index < 32) ++ { ++ /*19-bits Rate*/ ++ retVal = rtl8367c_setAsicReg(RTL8367C_METER_RATE_REG(index), rate&0xFFFF); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicReg(RTL8367C_METER_RATE_REG(index) + 1, (rate &0x70000) >> 16); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicRegBit(RTL8367C_METER_IFG_CTRL_REG(index), RTL8367C_METER_IFG_OFFSET(index), ifg); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ /*19-bits Rate*/ ++ retVal = rtl8367c_setAsicReg(RTL8367C_REG_METER32_RATE_CTRL0 + ((index-32) << 1), rate&0xFFFF); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicReg(RTL8367C_REG_METER32_RATE_CTRL0 + ((index-32) << 1) + 1, (rate &0x70000) >> 16); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_METER_IFG_CTRL2 + ((index-32) >> 4), RTL8367C_METER_IFG_OFFSET(index), ifg); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicShareMeter ++ * Description: ++ * Get meter configuration ++ * Input: ++ * index - hared meter index (0-31) ++ * pRate - 17-bits rate of share meter, unit is 8Kpbs ++ * pIfg - Including IFG in rate calculation, 1:include 0:exclude ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_FILTER_METER_ID - Invalid meter ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicShareMeter(rtk_uint32 index, rtk_uint32 *pRate, rtk_uint32 *pIfg) ++{ ++ rtk_uint32 regData; ++ rtk_uint32 regData2; ++ ret_t retVal; ++ ++ if(index > RTL8367C_METERMAX) ++ return RT_ERR_FILTER_METER_ID; ++ ++ if(index < 32) ++ { ++ /*17-bits Rate*/ ++ retVal = rtl8367c_getAsicReg(RTL8367C_METER_RATE_REG(index), ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_METER_RATE_REG(index) + 1, ®Data2); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *pRate = ((regData2 << 16) & 0x70000) | regData; ++ /*IFG*/ ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_METER_IFG_CTRL_REG(index), RTL8367C_METER_IFG_OFFSET(index), pIfg); ++ ++ return retVal; ++ } ++ else ++ { ++ /*17-bits Rate*/ ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_METER32_RATE_CTRL0 + ((index-32) << 1), ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_METER32_RATE_CTRL0 + ((index-32) << 1) + 1, ®Data2); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *pRate = ((regData2 << 16) & 0x70000) | regData; ++ /*IFG*/ ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_METER_IFG_CTRL2 + ((index-32) >> 4), RTL8367C_METER_IFG_OFFSET(index), pIfg); ++ ++ return retVal; ++ } ++} ++/* Function Name: ++ * rtl8367c_setAsicShareMeterBucketSize ++ * Description: ++ * Set meter related leaky bucket threshold ++ * Input: ++ * index - hared meter index (0-31) ++ * lbthreshold - Leaky bucket threshold of meter ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_FILTER_METER_ID - Invalid meter ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicShareMeterBucketSize(rtk_uint32 index, rtk_uint32 lbthreshold) ++{ ++ ++ if(index > RTL8367C_METERMAX) ++ return RT_ERR_FILTER_METER_ID; ++ ++ if(index < 32) ++ return rtl8367c_setAsicReg(RTL8367C_METER_BUCKET_SIZE_REG(index), lbthreshold); ++ else ++ return rtl8367c_setAsicReg(RTL8367C_REG_METER32_BUCKET_SIZE + index - 32, lbthreshold); ++} ++/* Function Name: ++ * rtl8367c_getAsicShareMeterBucketSize ++ * Description: ++ * Get meter related leaky bucket threshold ++ * Input: ++ * index - hared meter index (0-31) ++ * pLbthreshold - Leaky bucket threshold of meter ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_FILTER_METER_ID - Invalid meter ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicShareMeterBucketSize(rtk_uint32 index, rtk_uint32 *pLbthreshold) ++{ ++ if(index > RTL8367C_METERMAX) ++ return RT_ERR_FILTER_METER_ID; ++ ++ if(index < 32) ++ return rtl8367c_getAsicReg(RTL8367C_METER_BUCKET_SIZE_REG(index), pLbthreshold); ++ else ++ return rtl8367c_getAsicReg(RTL8367C_REG_METER32_BUCKET_SIZE + index - 32, pLbthreshold); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicShareMeterType ++ * Description: ++ * Set meter Type ++ * Input: ++ * index - shared meter index (0-31) ++ * Type - 0: kbps, 1: pps ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_FILTER_METER_ID - Invalid meter ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicShareMeterType(rtk_uint32 index, rtk_uint32 type) ++{ ++ rtk_uint32 reg; ++ ++ if(index > RTL8367C_METERMAX) ++ return RT_ERR_FILTER_METER_ID; ++ ++ if(index < 32) ++ reg = RTL8367C_REG_METER_MODE_SETTING0 + (index / 16); ++ else ++ reg = RTL8367C_REG_METER_MODE_SETTING2 + ((index - 32) / 16); ++ return rtl8367c_setAsicRegBit(reg, index % 16, type); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicShareMeterType ++ * Description: ++ * Get meter Type ++ * Input: ++ * index - shared meter index (0-31) ++ * Output: ++ * pType - 0: kbps, 1: pps ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_FILTER_METER_ID - Invalid meter ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicShareMeterType(rtk_uint32 index, rtk_uint32 *pType) ++{ ++ rtk_uint32 reg; ++ ++ if(index > RTL8367C_METERMAX) ++ return RT_ERR_FILTER_METER_ID; ++ ++ if(NULL == pType) ++ return RT_ERR_NULL_POINTER; ++ ++ if(index < 32) ++ reg = RTL8367C_REG_METER_MODE_SETTING0 + (index / 16); ++ else ++ reg = RTL8367C_REG_METER_MODE_SETTING2 + ((index - 32) / 16); ++ return rtl8367c_getAsicRegBit(reg, index % 16, pType); ++} ++ ++ ++/* Function Name: ++ * rtl8367c_setAsicMeterExceedStatus ++ * Description: ++ * Clear shared meter status ++ * Input: ++ * index - hared meter index (0-31) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_FILTER_METER_ID - Invalid meter ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicMeterExceedStatus(rtk_uint32 index) ++{ ++ if(index > RTL8367C_METERMAX) ++ return RT_ERR_FILTER_METER_ID; ++ ++ if(index < 32) ++ return rtl8367c_setAsicRegBit(RTL8367C_METER_OVERRATE_INDICATOR_REG(index), RTL8367C_METER_EXCEED_OFFSET(index), 1); ++ else ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_METER_OVERRATE_INDICATOR2 + ((index - 32) >> 4), RTL8367C_METER_EXCEED_OFFSET(index), 1); ++ ++} ++/* Function Name: ++ * rtl8367c_getAsicMeterExceedStatus ++ * Description: ++ * Get shared meter status ++ * Input: ++ * index - hared meter index (0-31) ++ * pStatus - 0: rate doesn't exceed 1: rate exceeds ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_FILTER_METER_ID - Invalid meter ++ * Note: ++ * If rate is over rate*8Kbps of a meter, the state bit of this meter is set to 1. ++ */ ++ret_t rtl8367c_getAsicMeterExceedStatus(rtk_uint32 index, rtk_uint32* pStatus) ++{ ++ if(index > RTL8367C_METERMAX) ++ return RT_ERR_FILTER_METER_ID; ++ ++ if(index < 32) ++ return rtl8367c_getAsicRegBit(RTL8367C_METER_OVERRATE_INDICATOR_REG(index), RTL8367C_METER_EXCEED_OFFSET(index), pStatus); ++ else ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_METER_OVERRATE_INDICATOR2 + ((index - 32) >> 4), RTL8367C_METER_EXCEED_OFFSET(index), pStatus); ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_mib.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_mib.c +new file mode 100644 +index 0000000000..c9aaa01d3e +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_mib.c +@@ -0,0 +1,570 @@ ++/* ++ * 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 : MIB related functions ++ * ++ */ ++ ++#include ++/* Function Name: ++ * rtl8367c_setAsicMIBsCounterReset ++ * Description: ++ * Reset global/queue manage or per-port MIB counter ++ * Input: ++ * greset - Global reset ++ * qmreset - Queue maganement reset ++ * portmask - Port reset mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicMIBsCounterReset(rtk_uint32 greset, rtk_uint32 qmreset, rtk_uint32 portmask) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint32 regBits; ++ ++ regBits = RTL8367C_GLOBAL_RESET_MASK | ++ RTL8367C_QM_RESET_MASK | ++ RTL8367C_MIB_PORT07_MASK | ++ ((rtk_uint32)0x7 << 13); ++ regData = ((greset << RTL8367C_GLOBAL_RESET_OFFSET) & RTL8367C_GLOBAL_RESET_MASK) | ++ ((qmreset << RTL8367C_QM_RESET_OFFSET) & RTL8367C_QM_RESET_MASK) | ++ (((portmask & 0xFF) << RTL8367C_PORT0_RESET_OFFSET) & RTL8367C_MIB_PORT07_MASK) | ++ (((portmask >> 8)&0x7) << 13); ++ ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_MIB_CTRL0, regBits, (regData >> RTL8367C_PORT0_RESET_OFFSET)); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicMIBsCounter ++ * Description: ++ * Get MIBs counter ++ * Input: ++ * port - Physical port number (0~7) ++ * mibIdx - MIB counter index ++ * pCounter - MIB retrived counter ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_BUSYWAIT_TIMEOUT - MIB is busy at retrieving ++ * RT_ERR_STAT_CNTR_FAIL - MIB is resetting ++ * Note: ++ * Before MIBs counter retrieving, writting accessing address to ASIC at first and check the MIB ++ * control register status. If busy bit of MIB control is set, that means MIB counter have been ++ * waiting for preparing, then software must wait atfer this busy flag reset by ASIC. This driver ++ * did not recycle reading user desired counter. Software must use driver again to get MIB counter ++ * if return value is not RT_ERR_OK. ++ */ ++ret_t rtl8367c_getAsicMIBsCounter(rtk_uint32 port, RTL8367C_MIBCOUNTER mibIdx, rtk_uint64* pCounter) ++{ ++ ret_t retVal; ++ rtk_uint32 regAddr; ++ rtk_uint32 regData; ++ rtk_uint32 mibAddr; ++ rtk_uint32 mibOff=0; ++ ++ /* address offset to MIBs counter */ ++ CONST rtk_uint16 mibLength[RTL8367C_MIBS_NUMBER]= { ++ 4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, ++ 4,2,2,2,2,2,2,2,2, ++ 4,2,2,2,2,2,2,2,2,2,2,2,2,2,2, ++ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2}; ++ ++ rtk_uint16 i; ++ rtk_uint64 mibCounter; ++ ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(mibIdx >= RTL8367C_MIBS_NUMBER) ++ return RT_ERR_STAT_INVALID_CNTR; ++ ++ if(dot1dTpLearnedEntryDiscards == mibIdx) ++ { ++ mibAddr = RTL8367C_MIB_LEARNENTRYDISCARD_OFFSET; ++ } ++ else ++ { ++ i = 0; ++ mibOff = RTL8367C_MIB_PORT_OFFSET * port; ++ ++ if(port > 7) ++ mibOff = mibOff + 68; ++ ++ while(i < mibIdx) ++ { ++ mibOff += mibLength[i]; ++ i++; ++ } ++ ++ mibAddr = mibOff; ++ } ++ ++ ++ /*writing access counter address first*/ ++ /*This address is SRAM address, and SRAM address = MIB register address >> 2*/ ++ /*then ASIC will prepare 64bits counter wait for being retrived*/ ++ /*Write Mib related address to access control register*/ ++ retVal = rtl8367c_setAsicReg(RTL8367C_REG_MIB_ADDRESS, (mibAddr >> 2)); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ ++ ++ /* polling busy flag */ ++ i = 100; ++ while(i > 0) ++ { ++ /*read MIB control register*/ ++ retVal = rtl8367c_getAsicReg(RTL8367C_MIB_CTRL_REG,®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ if((regData & RTL8367C_MIB_CTRL0_BUSY_FLAG_MASK) == 0) ++ { ++ break; ++ } ++ ++ i--; ++ } ++ ++ if(regData & RTL8367C_MIB_CTRL0_BUSY_FLAG_MASK) ++ return RT_ERR_BUSYWAIT_TIMEOUT; ++ ++ if(regData & RTL8367C_RESET_FLAG_MASK) ++ return RT_ERR_STAT_CNTR_FAIL; ++ ++ mibCounter = 0; ++ i = mibLength[mibIdx]; ++ if(4 == i) ++ regAddr = RTL8367C_MIB_COUNTER_BASE_REG + 3; ++ else ++ regAddr = RTL8367C_MIB_COUNTER_BASE_REG + ((mibOff + 1) % 4); ++ ++ while(i) ++ { ++ retVal = rtl8367c_getAsicReg(regAddr, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ mibCounter = (mibCounter << 16) | (regData & 0xFFFF); ++ ++ regAddr --; ++ i --; ++ ++ } ++ ++ *pCounter = mibCounter; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicMIBsLogCounter ++ * Description: ++ * Get MIBs Loggin counter ++ * Input: ++ * index - The index of 32 logging counter (0 ~ 31) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_ENTRY_INDEX - Wrong index ++ * RT_ERR_BUSYWAIT_TIMEOUT - MIB is busy at retrieving ++ * RT_ERR_STAT_CNTR_FAIL - MIB is resetting ++ * Note: ++ * This API get 32 logging counter ++ */ ++ret_t rtl8367c_getAsicMIBsLogCounter(rtk_uint32 index, rtk_uint32 *pCounter) ++{ ++ ret_t retVal; ++ rtk_uint32 regAddr; ++ rtk_uint32 regData; ++ rtk_uint32 mibAddr; ++ rtk_uint16 i; ++ rtk_uint64 mibCounter; ++ ++ if(index > RTL8367C_MIB_MAX_LOG_CNT_IDX) ++ return RT_ERR_ENTRY_INDEX; ++ ++ mibAddr = RTL8367C_MIB_LOG_CNT_OFFSET + ((index / 2) * 4); ++ ++ retVal = rtl8367c_setAsicReg(RTL8367C_REG_MIB_ADDRESS, (mibAddr >> 2)); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /*read MIB control register*/ ++ retVal = rtl8367c_getAsicReg(RTL8367C_MIB_CTRL_REG, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ if(regData & RTL8367C_MIB_CTRL0_BUSY_FLAG_MASK) ++ return RT_ERR_BUSYWAIT_TIMEOUT; ++ ++ if(regData & RTL8367C_RESET_FLAG_MASK) ++ return RT_ERR_STAT_CNTR_FAIL; ++ ++ mibCounter = 0; ++ if((index % 2) == 1) ++ regAddr = RTL8367C_MIB_COUNTER_BASE_REG + 3; ++ else ++ regAddr = RTL8367C_MIB_COUNTER_BASE_REG + 1; ++ ++ for(i = 0; i <= 1; i++) ++ { ++ retVal = rtl8367c_getAsicReg(regAddr, ®Data); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ mibCounter = (mibCounter << 16) | (regData & 0xFFFF); ++ ++ regAddr --; ++ } ++ ++ *pCounter = mibCounter; ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicMIBsControl ++ * Description: ++ * Get MIB control register ++ * Input: ++ * pMask - MIB control status mask bit[0]-busy bit[1] ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * Software need to check this control register atfer doing port resetting or global resetting ++ */ ++ret_t rtl8367c_getAsicMIBsControl(rtk_uint32* pMask) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_MIB_CTRL_REG, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *pMask = regData & (RTL8367C_MIB_CTRL0_BUSY_FLAG_MASK | RTL8367C_RESET_FLAG_MASK); ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicMIBsResetValue ++ * Description: ++ * Reset all counter to 0 or 1 ++ * Input: ++ * value - Reset to value 0 or 1 ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicMIBsResetValue(rtk_uint32 value) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_MIB_CTRL0, RTL8367C_RESET_VALUE_OFFSET, value); ++} ++/* Function Name: ++ * rtl8367c_getAsicMIBsResetValue ++ * Description: ++ * Reset all counter to 0 or 1 ++ * Input: ++ * value - Reset to value 0 or 1 ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicMIBsResetValue(rtk_uint32* value) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_MIB_CTRL0, RTL8367C_RESET_VALUE_OFFSET, value); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicMIBsUsageMode ++ * Description: ++ * MIB update mode ++ * Input: ++ * mode - 1: latch all MIBs by timer 0:normal free run counting ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicMIBsUsageMode(rtk_uint32 mode) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_MIB_CTRL4, RTL8367C_MIB_USAGE_MODE_OFFSET, mode); ++} ++/* Function Name: ++ * rtl8367c_getAsicMIBsUsageMode ++ * Description: ++ * MIB update mode ++ * Input: ++ * pMode - 1: latch all MIBs by timer 0:normal free run counting ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicMIBsUsageMode(rtk_uint32* pMode) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_MIB_CTRL4, RTL8367C_MIB_USAGE_MODE_OFFSET, pMode); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicMIBsTimer ++ * Description: ++ * MIB latching timer ++ * Input: ++ * timer - latch timer, unit 1 second ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicMIBsTimer(rtk_uint32 timer) ++{ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_MIB_CTRL4, RTL8367C_MIB_TIMER_MASK, timer); ++} ++/* Function Name: ++ * rtl8367c_getAsicMIBsTimer ++ * Description: ++ * MIB latching timer ++ * Input: ++ * pTimer - latch timer, unit 1 second ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicMIBsTimer(rtk_uint32* pTimer) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_MIB_CTRL4, RTL8367C_MIB_TIMER_MASK, pTimer); ++} ++/* Function Name: ++ * rtl8367c_setAsicMIBsLoggingMode ++ * Description: ++ * MIB logging counter mode ++ * Input: ++ * index - logging counter mode index (0~15) ++ * mode - 0:32-bits mode 1:64-bits mode ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicMIBsLoggingMode(rtk_uint32 index, rtk_uint32 mode) ++{ ++ if(index > RTL8367C_MIB_MAX_LOG_MODE_IDX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_MIB_CTRL3, index,mode); ++} ++/* Function Name: ++ * rtl8367c_getAsicMIBsLoggingMode ++ * Description: ++ * MIB logging counter mode ++ * Input: ++ * index - logging counter mode index (0~15) ++ * pMode - 0:32-bits mode 1:64-bits mode ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicMIBsLoggingMode(rtk_uint32 index, rtk_uint32* pMode) ++{ ++ if(index > RTL8367C_MIB_MAX_LOG_MODE_IDX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_MIB_CTRL3, index,pMode); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicMIBsLoggingType ++ * Description: ++ * MIB logging counter type ++ * Input: ++ * index - logging counter mode index (0~15) ++ * type - 0:Packet count 1:Byte count ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicMIBsLoggingType(rtk_uint32 index, rtk_uint32 type) ++{ ++ if(index > RTL8367C_MIB_MAX_LOG_MODE_IDX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_MIB_CTRL5, index,type); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicMIBsLoggingType ++ * Description: ++ * MIB logging counter type ++ * Input: ++ * index - logging counter mode index (0~15) ++ * pType - 0:Packet count 1:Byte count ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicMIBsLoggingType(rtk_uint32 index, rtk_uint32* pType) ++{ ++ if(index > RTL8367C_MIB_MAX_LOG_MODE_IDX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_MIB_CTRL5, index,pType); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicMIBsResetLoggingCounter ++ * Description: ++ * MIB logging counter type ++ * Input: ++ * index - logging counter index (0~31) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicMIBsResetLoggingCounter(rtk_uint32 index) ++{ ++ ret_t retVal; ++ ++ if(index > RTL8367C_MIB_MAX_LOG_CNT_IDX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(index < 16) ++ retVal = rtl8367c_setAsicReg(RTL8367C_REG_MIB_CTRL1, 1< ++/* Function Name: ++ * rtl8367c_setAsicPortMirror ++ * Description: ++ * Set port mirror function ++ * Input: ++ * source - Source port ++ * monitor - Monitor (destination) port ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortMirror(rtk_uint32 source, rtk_uint32 monitor) ++{ ++ ret_t retVal; ++ ++ if((source > RTL8367C_PORTIDMAX) || (monitor > RTL8367C_PORTIDMAX)) ++ return RT_ERR_PORT_ID; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_SOURCE_PORT_MASK, source); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_MONITOR_PORT_MASK, monitor); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortMirror ++ * Description: ++ * Get port mirror function ++ * Input: ++ * pSource - Source port ++ * pMonitor - Monitor (destination) port ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortMirror(rtk_uint32 *pSource, rtk_uint32 *pMonitor) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_SOURCE_PORT_MASK, pSource); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_MONITOR_PORT_MASK, pMonitor); ++} ++/* Function Name: ++ * rtl8367c_setAsicPortMirrorRxFunction ++ * Description: ++ * Set the mirror function on RX of the mirrored ++ * Input: ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortMirrorRxFunction(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_RX_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortMirrorRxFunction ++ * Description: ++ * Get the mirror function on RX of the mirrored ++ * Input: ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortMirrorRxFunction(rtk_uint32* pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_RX_OFFSET, pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicPortMirrorTxFunction ++ * Description: ++ * Set the mirror function on TX of the mirrored ++ * Input: ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortMirrorTxFunction(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_TX_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortMirrorTxFunction ++ * Description: ++ * Get the mirror function on TX of the mirrored ++ * Input: ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortMirrorTxFunction(rtk_uint32* pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_TX_OFFSET, pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicPortMirrorIsolation ++ * Description: ++ * Set the traffic isolation on monitor port ++ * Input: ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortMirrorIsolation(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_ISO_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortMirrorIsolation ++ * Description: ++ * Get the traffic isolation on monitor port ++ * Input: ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortMirrorIsolation(rtk_uint32* pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_MIRROR_CTRL_REG, RTL8367C_MIRROR_ISO_OFFSET, pEnabled); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicPortMirrorMask ++ * Description: ++ * Set mirror source port mask ++ * Input: ++ * SourcePortmask - Source Portmask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_MASK- Port Mask Error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortMirrorMask(rtk_uint32 SourcePortmask) ++{ ++ if( SourcePortmask > RTL8367C_PORTMASK) ++ return RT_ERR_PORT_MASK; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_MIRROR_SRC_PMSK, RTL8367C_MIRROR_SRC_PMSK_MASK, SourcePortmask); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicPortMirrorMask ++ * Description: ++ * Get mirror source port mask ++ * Input: ++ * None ++ * Output: ++ * pSourcePortmask - Source Portmask ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_MASK- Port Mask Error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortMirrorMask(rtk_uint32 *pSourcePortmask) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_MIRROR_SRC_PMSK, RTL8367C_MIRROR_SRC_PMSK_MASK, pSourcePortmask); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicPortMirrorVlanRxLeaky ++ * Description: ++ * Set the mirror function of VLAN RX leaky ++ * Input: ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortMirrorVlanRxLeaky(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_RX_VLAN_LEAKY_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortMirrorVlanRxLeaky ++ * Description: ++ * Get the mirror function of VLAN RX leaky ++ * Input: ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortMirrorVlanRxLeaky(rtk_uint32* pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_RX_VLAN_LEAKY_OFFSET, pEnabled); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicPortMirrorVlanTxLeaky ++ * Description: ++ * Set the mirror function of VLAN TX leaky ++ * Input: ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortMirrorVlanTxLeaky(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_TX_VLAN_LEAKY_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortMirrorVlanTxLeaky ++ * Description: ++ * Get the mirror function of VLAN TX leaky ++ * Input: ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortMirrorVlanTxLeaky(rtk_uint32* pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_TX_VLAN_LEAKY_OFFSET, pEnabled); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicPortMirrorIsolationRxLeaky ++ * Description: ++ * Set the mirror function of Isolation RX leaky ++ * Input: ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortMirrorIsolationRxLeaky(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_RX_ISOLATION_LEAKY_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortMirrorIsolationRxLeaky ++ * Description: ++ * Get the mirror function of VLAN RX leaky ++ * Input: ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortMirrorIsolationRxLeaky(rtk_uint32* pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_RX_ISOLATION_LEAKY_OFFSET, pEnabled); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicPortMirrorIsolationTxLeaky ++ * Description: ++ * Set the mirror function of Isolation TX leaky ++ * Input: ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortMirrorIsolationTxLeaky(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_TX_ISOLATION_LEAKY_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortMirrorIsolationTxLeaky ++ * Description: ++ * Get the mirror function of VLAN TX leaky ++ * Input: ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortMirrorIsolationTxLeaky(rtk_uint32* pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_TX_ISOLATION_LEAKY_OFFSET, pEnabled); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicPortMirrorRealKeep ++ * Description: ++ * Set the mirror function of keep format ++ * Input: ++ * mode - 1: keep original format, 0: follow VLAN config ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortMirrorRealKeep(rtk_uint32 mode) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_REALKEEP_EN_OFFSET, mode); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortMirrorRealKeep ++ * Description: ++ * Get the mirror function of keep format ++ * Input: ++ * pMode - 1: keep original format, 0: follow VLAN config ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortMirrorRealKeep(rtk_uint32* pMode) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL2, RTL8367C_MIRROR_REALKEEP_EN_OFFSET, pMode); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicPortMirrorOverride ++ * Description: ++ * Set the mirror function of override ++ * Input: ++ * rxMirror - 1: output rx Mirror format, 0: output forward format ++ * txMirror - 1: output tx Mirror format, 0: output forward format ++ * aclMirror - 1: output ACL Mirror format, 0: output forward format ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortMirrorOverride(rtk_uint32 rxMirror, rtk_uint32 txMirror, rtk_uint32 aclMirror) ++{ ++ ret_t retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_RX_OVERRIDE_EN_OFFSET, rxMirror)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_TX_OVERRIDE_EN_OFFSET, txMirror)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_ACL_OVERRIDE_EN_OFFSET, aclMirror)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicPortMirrorOverride ++ * Description: ++ * Get the mirror function of override ++ * Input: ++ * None ++ * Output: ++ * pRxMirror - 1: output rx Mirror format, 0: output forward format ++ * pTxMirror - 1: output tx Mirror format, 0: output forward format ++ * pAclMirror - 1: output ACL Mirror format, 0: output forward format ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortMirrorOverride(rtk_uint32 *pRxMirror, rtk_uint32 *pTxMirror, rtk_uint32 *pAclMirror) ++{ ++ ret_t retVal; ++ ++ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_RX_OVERRIDE_EN_OFFSET, pRxMirror)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_TX_OVERRIDE_EN_OFFSET, pTxMirror)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_MIRROR_CTRL3, RTL8367C_MIRROR_ACL_OVERRIDE_EN_OFFSET, pAclMirror)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_misc.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_misc.c +new file mode 100644 +index 0000000000..2189b151c3 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_misc.c +@@ -0,0 +1,268 @@ ++/* ++ * 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 : Miscellaneous functions ++ * ++ */ ++ ++#include ++/* Function Name: ++ * rtl8367c_setAsicMacAddress ++ * Description: ++ * Set switch MAC address ++ * Input: ++ * mac - switch mac ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicMacAddress(ether_addr_t mac) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint8 *accessPtr; ++ rtk_uint32 i; ++ ++ accessPtr = (rtk_uint8*)&mac; ++ ++ regData = *accessPtr; ++ accessPtr ++; ++ regData = (regData << 8) | *accessPtr; ++ accessPtr ++; ++ for(i = 0; i <=2; i++) ++ { ++ retVal = rtl8367c_setAsicReg(RTL8367C_REG_SWITCH_MAC2 - i, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ regData = *accessPtr; ++ accessPtr ++; ++ regData = (regData << 8) | *accessPtr; ++ accessPtr ++; ++ } ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicMacAddress ++ * Description: ++ * Get switch MAC address ++ * Input: ++ * pMac - switch mac ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicMacAddress(ether_addr_t *pMac) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint8 *accessPtr; ++ rtk_uint32 i; ++ ++ ++ accessPtr = (rtk_uint8*)pMac; ++ ++ for(i = 0; i <= 2; i++) ++ { ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_SWITCH_MAC2 - i, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *accessPtr = (regData & 0xFF00) >> 8; ++ accessPtr ++; ++ *accessPtr = regData & 0xFF; ++ accessPtr ++; ++ } ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicDebugInfo ++ * Description: ++ * Get per-port packet forward debugging information ++ * Input: ++ * port - Physical port number (0~7) ++ * pDebugifo - per-port packet trap/drop/forward reason ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicDebugInfo(rtk_uint32 port, rtk_uint32 *pDebugifo) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_DEBUG_INFO_REG(port), RTL8367C_DEBUG_INFO_MASK(port), pDebugifo); ++} ++/* Function Name: ++ * rtl8367c_setAsicPortJamMode ++ * Description: ++ * Set half duplex flow control setting ++ * Input: ++ * mode - 0: Back-Pressure 1: DEFER ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortJamMode(rtk_uint32 mode) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_CFG_BACKPRESSURE, RTL8367C_LONGTXE_OFFSET,mode); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortJamMode ++ * Description: ++ * Get half duplex flow control setting ++ * Input: ++ * pMode - 0: Back-Pressure 1: DEFER ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortJamMode(rtk_uint32* pMode) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_CFG_BACKPRESSURE, RTL8367C_LONGTXE_OFFSET, pMode); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicMaxLengthCfg ++ * Description: ++ * Set Max packet length configuration ++ * Input: ++ * cfgId - Configuration ID ++ * maxLength - Max Length ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicMaxLengthCfg(rtk_uint32 cfgId, rtk_uint32 maxLength) ++{ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_MAX_LEN_RX_TX_CFG0 + cfgId, RTL8367C_MAX_LEN_RX_TX_CFG0_MASK, maxLength); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicMaxLengthCfg ++ * Description: ++ * Get Max packet length configuration ++ * Input: ++ * cfgId - Configuration ID ++ * maxLength - Max Length ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicMaxLengthCfg(rtk_uint32 cfgId, rtk_uint32 *pMaxLength) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_MAX_LEN_RX_TX_CFG0 + cfgId, RTL8367C_MAX_LEN_RX_TX_CFG0_MASK, pMaxLength); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicMaxLength ++ * Description: ++ * Set Max packet length ++ * Input: ++ * port - port ID ++ * type - 0: 10M/100M speed, 1: giga speed ++ * cfgId - Configuration ID ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicMaxLength(rtk_uint32 port, rtk_uint32 type, rtk_uint32 cfgId) ++{ ++ ret_t retVal; ++ ++ if(port < 8) ++ { ++ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MAX_LENGTH_CFG, (type * 8) + port, cfgId); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MAX_LENGTH_CFG_EXT, (type * 3) + port - 8, cfgId); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicMaxLength ++ * Description: ++ * Get Max packet length ++ * Input: ++ * port - port ID ++ * type - 0: 10M/100M speed, 1: giga speed ++ * cfgId - Configuration ID ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicMaxLength(rtk_uint32 port, rtk_uint32 type, rtk_uint32 *pCfgId) ++{ ++ ret_t retVal; ++ ++ if(port < 8) ++ { ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_MAX_LENGTH_CFG, (type * 8) + port, pCfgId); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_MAX_LENGTH_CFG_EXT, (type * 3) + port - 8, pCfgId); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ return RT_ERR_OK; ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_oam.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_oam.c +new file mode 100644 +index 0000000000..1556f4500d +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_oam.c +@@ -0,0 +1,194 @@ ++/* ++ * 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: 42321 $ ++ * $Date: 2013-08-26 13:51:29 +0800 (週一, 26 八月 2013) $ ++ * ++ * Purpose : RTL8367C switch high-level API for RTL8367C ++ * Feature : OAM related functions ++ * ++ */ ++ ++#include ++/* Function Name: ++ * rtl8367c_setAsicOamParser ++ * Description: ++ * Set OAM parser state ++ * Input: ++ * port - Physical port number (0~7) ++ * parser - Per-Port OAM parser state ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_NOT_ALLOWED - Invalid paser state ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicOamParser(rtk_uint32 port, rtk_uint32 parser) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ if(parser > OAM_PARFWDCPU) ++ return RT_ERR_NOT_ALLOWED; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_OAM_PARSER_CTRL0 + port/8, RTL8367C_OAM_PARSER_MASK(port % 8), parser); ++} ++/* Function Name: ++ * rtl8367c_getAsicOamParser ++ * Description: ++ * Get OAM parser state ++ * Input: ++ * port - Physical port number (0~7) ++ * pParser - Per-Port OAM parser state ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicOamParser(rtk_uint32 port, rtk_uint32* pParser) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_OAM_PARSER_CTRL0 + port/8, RTL8367C_OAM_PARSER_MASK(port%8), pParser); ++} ++/* Function Name: ++ * rtl8367c_setAsicOamMultiplexer ++ * Description: ++ * Set OAM multiplexer state ++ * Input: ++ * port - Physical port number (0~7) ++ * multiplexer - Per-Port OAM multiplexer state ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_NOT_ALLOWED - Invalid multiplexer state ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicOamMultiplexer(rtk_uint32 port, rtk_uint32 multiplexer) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ if(multiplexer > OAM_MULCPU) ++ return RT_ERR_NOT_ALLOWED; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_OAM_MULTIPLEXER_CTRL0 + port/8, RTL8367C_OAM_MULTIPLEXER_MASK(port%8), multiplexer); ++} ++/* Function Name: ++ * rtl8367c_getAsicOamMultiplexer ++ * Description: ++ * Get OAM multiplexer state ++ * Input: ++ * port - Physical port number (0~7) ++ * pMultiplexer - Per-Port OAM multiplexer state ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicOamMultiplexer(rtk_uint32 port, rtk_uint32* pMultiplexer) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_OAM_MULTIPLEXER_CTRL0 + port/8, RTL8367C_OAM_MULTIPLEXER_MASK(port%8), pMultiplexer); ++} ++/* Function Name: ++ * rtl8367c_setAsicOamCpuPri ++ * Description: ++ * Set trap priority for OAM packet ++ * Input: ++ * priority - priority (0~7) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicOamCpuPri(rtk_uint32 priority) ++{ ++ if(priority > RTL8367C_PRIMAX) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_OAM_PRIOIRTY_MASK, priority); ++} ++/* Function Name: ++ * rtl8367c_getAsicOamCpuPri ++ * Description: ++ * Get trap priority for OAM packet ++ * Input: ++ * pPriority - priority (0~7) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicOamCpuPri(rtk_uint32 *pPriority) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_OAM_PRIOIRTY_MASK, pPriority); ++} ++/* Function Name: ++ * rtl8367c_setAsicOamEnable ++ * Description: ++ * Set OAM function state ++ * Input: ++ * enabled - OAM function usage 1:enable, 0:disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicOamEnable(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_OAM_CTRL, RTL8367C_OAM_CTRL_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicOamEnable ++ * Description: ++ * Get OAM function state ++ * Input: ++ * pEnabled - OAM function usage 1:enable, 0:disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicOamEnable(rtk_uint32 *pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_OAM_CTRL, RTL8367C_OAM_CTRL_OFFSET, pEnabled); ++} +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c +new file mode 100644 +index 0000000000..fb4db113a9 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_phy.c +@@ -0,0 +1,394 @@ ++/* ++ * 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 : PHY related functions ++ * ++ */ ++#include ++ ++#if defined(MDC_MDIO_OPERATION) ++/* Function Name: ++ * rtl8367c_setAsicPHYOCPReg ++ * Description: ++ * Set PHY OCP registers ++ * Input: ++ * phyNo - Physical port number (0~7) ++ * ocpAddr - OCP address ++ * ocpData - Writing data ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PHY_REG_ID - invalid PHY address ++ * RT_ERR_PHY_ID - invalid PHY no ++ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 ocpData ) ++{ ++ ret_t retVal; ++ rtk_uint32 regAddr; ++ rtk_uint32 ocpAddrPrefix, ocpAddr9_6, ocpAddr5_1; ++ ++ /* OCP prefix */ ++ ocpAddrPrefix = ((ocpAddr & 0xFC00) >> 10); ++ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0, RTL8367C_CFG_CPU_OCPADR_MSB_MASK, ocpAddrPrefix)) != RT_ERR_OK) ++ return retVal; ++ ++ /*prepare access address*/ ++ ocpAddr9_6 = ((ocpAddr >> 6) & 0x000F); ++ ocpAddr5_1 = ((ocpAddr >> 1) & 0x001F); ++ regAddr = RTL8367C_PHY_BASE | (ocpAddr9_6 << 8) | (phyNo << RTL8367C_PHY_OFFSET) | ocpAddr5_1; ++ if((retVal = rtl8367c_setAsicReg(regAddr, ocpData)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicPHYOCPReg ++ * Description: ++ * Get PHY OCP registers ++ * Input: ++ * phyNo - Physical port number (0~7) ++ * ocpAddr - PHY address ++ * pRegData - read data ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PHY_REG_ID - invalid PHY address ++ * RT_ERR_PHY_ID - invalid PHY no ++ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 *pRegData ) ++{ ++ ret_t retVal; ++ rtk_uint32 regAddr; ++ rtk_uint32 ocpAddrPrefix, ocpAddr9_6, ocpAddr5_1; ++ /* OCP prefix */ ++ ocpAddrPrefix = ((ocpAddr & 0xFC00) >> 10); ++ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0, RTL8367C_CFG_CPU_OCPADR_MSB_MASK, ocpAddrPrefix)) != RT_ERR_OK) ++ return retVal; ++ ++ /*prepare access address*/ ++ ocpAddr9_6 = ((ocpAddr >> 6) & 0x000F); ++ ocpAddr5_1 = ((ocpAddr >> 1) & 0x001F); ++ regAddr = RTL8367C_PHY_BASE | (ocpAddr9_6 << 8) | (phyNo << RTL8367C_PHY_OFFSET) | ocpAddr5_1; ++ if((retVal = rtl8367c_getAsicReg(regAddr, pRegData)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++#else ++ ++/* Function Name: ++ * rtl8367c_setAsicPHYOCPReg ++ * Description: ++ * Set PHY OCP registers ++ * Input: ++ * phyNo - Physical port number (0~7) ++ * ocpAddr - OCP address ++ * ocpData - Writing data ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PHY_REG_ID - invalid PHY address ++ * RT_ERR_PHY_ID - invalid PHY no ++ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 ocpData ) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint32 busyFlag, checkCounter; ++ rtk_uint32 ocpAddrPrefix, ocpAddr9_6, ocpAddr5_1; ++ ++ /*Check internal phy access busy or not*/ ++ /*retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_INDRECT_ACCESS_STATUS, RTL8367C_INDRECT_ACCESS_STATUS_OFFSET,&busyFlag);*/ ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS,&busyFlag); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ if(busyFlag) ++ return RT_ERR_BUSYWAIT_TIMEOUT; ++ ++ /* OCP prefix */ ++ ocpAddrPrefix = ((ocpAddr & 0xFC00) >> 10); ++ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0, RTL8367C_CFG_CPU_OCPADR_MSB_MASK, ocpAddrPrefix)) != RT_ERR_OK) ++ return retVal; ++ ++ /*prepare access data*/ ++ retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_WRITE_DATA, ocpData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /*prepare access address*/ ++ ocpAddr9_6 = ((ocpAddr >> 6) & 0x000F); ++ ocpAddr5_1 = ((ocpAddr >> 1) & 0x001F); ++ regData = RTL8367C_PHY_BASE | (ocpAddr9_6 << 8) | (phyNo << RTL8367C_PHY_OFFSET) | ocpAddr5_1; ++ retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_ADDRESS, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /*Set WRITE Command*/ ++ retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_CTRL, RTL8367C_CMD_MASK | RTL8367C_RW_MASK); ++ ++ checkCounter = 100; ++ while(checkCounter) ++ { ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS,&busyFlag); ++ if((retVal != RT_ERR_OK) || busyFlag) ++ { ++ checkCounter --; ++ if(0 == checkCounter) ++ return RT_ERR_BUSYWAIT_TIMEOUT; ++ } ++ else ++ { ++ checkCounter = 0; ++ } ++ } ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicPHYOCPReg ++ * Description: ++ * Get PHY OCP registers ++ * Input: ++ * phyNo - Physical port number (0~7) ++ * ocpAddr - PHY address ++ * pRegData - read data ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PHY_REG_ID - invalid PHY address ++ * RT_ERR_PHY_ID - invalid PHY no ++ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPHYOCPReg(rtk_uint32 phyNo, rtk_uint32 ocpAddr, rtk_uint32 *pRegData ) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint32 busyFlag,checkCounter; ++ rtk_uint32 ocpAddrPrefix, ocpAddr9_6, ocpAddr5_1; ++ /*Check internal phy access busy or not*/ ++ /*retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_INDRECT_ACCESS_STATUS, RTL8367C_INDRECT_ACCESS_STATUS_OFFSET,&busyFlag);*/ ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS,&busyFlag); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ if(busyFlag) ++ return RT_ERR_BUSYWAIT_TIMEOUT; ++ ++ /* OCP prefix */ ++ ocpAddrPrefix = ((ocpAddr & 0xFC00) >> 10); ++ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_GPHY_OCP_MSB_0, RTL8367C_CFG_CPU_OCPADR_MSB_MASK, ocpAddrPrefix)) != RT_ERR_OK) ++ return retVal; ++ ++ /*prepare access address*/ ++ ocpAddr9_6 = ((ocpAddr >> 6) & 0x000F); ++ ocpAddr5_1 = ((ocpAddr >> 1) & 0x001F); ++ regData = RTL8367C_PHY_BASE | (ocpAddr9_6 << 8) | (phyNo << RTL8367C_PHY_OFFSET) | ocpAddr5_1; ++ retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_ADDRESS, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /*Set READ Command*/ ++ retVal = rtl8367c_setAsicReg(RTL8367C_REG_INDRECT_ACCESS_CTRL, RTL8367C_CMD_MASK ); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ checkCounter = 100; ++ while(checkCounter) ++ { ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_STATUS,&busyFlag); ++ if((retVal != RT_ERR_OK) || busyFlag) ++ { ++ checkCounter --; ++ if(0 == checkCounter) ++ return RT_ERR_FAILED; ++ } ++ else ++ { ++ checkCounter = 0; ++ } ++ } ++ ++ /*get PHY register*/ ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_INDRECT_ACCESS_READ_DATA, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *pRegData = regData; ++ ++ return RT_ERR_OK; ++} ++ ++#endif ++ ++/* Function Name: ++ * rtl8367c_setAsicPHYReg ++ * Description: ++ * Set PHY registers ++ * Input: ++ * phyNo - Physical port number (0~7) ++ * phyAddr - PHY address (0~31) ++ * phyData - Writing data ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PHY_REG_ID - invalid PHY address ++ * RT_ERR_PHY_ID - invalid PHY no ++ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPHYReg(rtk_uint32 phyNo, rtk_uint32 phyAddr, rtk_uint32 phyData ) ++{ ++ rtk_uint32 ocp_addr; ++ ++ if(phyAddr > RTL8367C_PHY_REGNOMAX) ++ return RT_ERR_PHY_REG_ID; ++ ++ ocp_addr = 0xa400 + phyAddr*2; ++ ++ return rtl8367c_setAsicPHYOCPReg(phyNo, ocp_addr, phyData); ++} ++/* Function Name: ++ * rtl8367c_getAsicPHYReg ++ * Description: ++ * Get PHY registers ++ * Input: ++ * phyNo - Physical port number (0~7) ++ * phyAddr - PHY address (0~31) ++ * pRegData - Writing data ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PHY_REG_ID - invalid PHY address ++ * RT_ERR_PHY_ID - invalid PHY no ++ * RT_ERR_BUSYWAIT_TIMEOUT - PHY access busy ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPHYReg(rtk_uint32 phyNo, rtk_uint32 phyAddr, rtk_uint32 *pRegData ) ++{ ++ rtk_uint32 ocp_addr; ++ ++ if(phyAddr > RTL8367C_PHY_REGNOMAX) ++ return RT_ERR_PHY_REG_ID; ++ ++ ocp_addr = 0xa400 + phyAddr*2; ++ ++ return rtl8367c_getAsicPHYOCPReg(phyNo, ocp_addr, pRegData); ++} ++ ++ ++/* Function Name: ++ * rtl8367c_setAsicSdsReg ++ * Description: ++ * Set Serdes registers ++ * Input: ++ * sdsId - sdsid (0~1) ++ * sdsReg - reg address (0~31) ++ * sdsPage - Writing data ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ ++ * Note: ++ * None ++ */ ++ ++ret_t rtl8367c_setAsicSdsReg(rtk_uint32 sdsId, rtk_uint32 sdsReg, rtk_uint32 sdsPage, rtk_uint32 value) ++{ ++ rtk_uint32 retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, value)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (sdsPage<<5) | sdsReg)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0|sdsId)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++ ++} ++ ++/* Function Name: ++ * rtl8367c_getAiscSdsReg ++ * Description: ++ * Get Serdes registers ++ * Input: ++ * sdsId - sdsid (0~1) ++ * sdsReg - reg address (0~31) ++ * sdsPage - Writing data ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicSdsReg(rtk_uint32 sdsId, rtk_uint32 sdsReg, rtk_uint32 sdsPage, rtk_uint32 *value) ++{ ++ rtk_uint32 retVal, busy; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (sdsPage<<5) | sdsReg)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x0080|sdsId)) != RT_ERR_OK) ++ return retVal; ++ ++ while(1) ++ { ++ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SDS_INDACS_CMD, &busy))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((busy & 0x100) == 0) ++ break; ++ } ++ ++ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_SDS_INDACS_DATA, value))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++ ++ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_port.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_port.c +new file mode 100644 +index 0000000000..78e80a0b20 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_port.c +@@ -0,0 +1,5752 @@ ++/* ++ * 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: 76333 $ ++ * $Date: 2017-03-09 09:33:15 +0800 (週四, 09 三月 2017) $ ++ * ++ * Purpose : RTL8367C switch high-level API for RTL8367C ++ * Feature : Port security related functions ++ * ++ */ ++ ++#include ++ ++#include ++ ++ ++#define FIBER2_AUTO_INIT_SIZE 2038 ++rtk_uint8 Fiber2_Auto[FIBER2_AUTO_INIT_SIZE] = { ++0x02,0x05,0x8F,0xE4,0xF5,0xA8,0xD2,0xAF, ++0x22,0x00,0x00,0x02,0x07,0x2C,0xC5,0xF0, ++0xF8,0xA3,0xE0,0x28,0xF0,0xC5,0xF0,0xF8, ++0xE5,0x82,0x15,0x82,0x70,0x02,0x15,0x83, ++0xE0,0x38,0xF0,0x22,0x75,0xF0,0x08,0x75, ++0x82,0x00,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, ++0xCD,0x33,0xCD,0xCC,0x33,0xCC,0xC5,0x82, ++0x33,0xC5,0x82,0x9B,0xED,0x9A,0xEC,0x99, ++0xE5,0x82,0x98,0x40,0x0C,0xF5,0x82,0xEE, ++0x9B,0xFE,0xED,0x9A,0xFD,0xEC,0x99,0xFC, ++0x0F,0xD5,0xF0,0xD6,0xE4,0xCE,0xFB,0xE4, ++0xCD,0xFA,0xE4,0xCC,0xF9,0xA8,0x82,0x22, ++0xB8,0x00,0xC1,0xB9,0x00,0x59,0xBA,0x00, ++0x2D,0xEC,0x8B,0xF0,0x84,0xCF,0xCE,0xCD, ++0xFC,0xE5,0xF0,0xCB,0xF9,0x78,0x18,0xEF, ++0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33,0xFD, ++0xEC,0x33,0xFC,0xEB,0x33,0xFB,0x10,0xD7, ++0x03,0x99,0x40,0x04,0xEB,0x99,0xFB,0x0F, ++0xD8,0xE5,0xE4,0xF9,0xFA,0x22,0x78,0x18, ++0xEF,0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33, ++0xFD,0xEC,0x33,0xFC,0xC9,0x33,0xC9,0x10, ++0xD7,0x05,0x9B,0xE9,0x9A,0x40,0x07,0xEC, ++0x9B,0xFC,0xE9,0x9A,0xF9,0x0F,0xD8,0xE0, ++0xE4,0xC9,0xFA,0xE4,0xCC,0xFB,0x22,0x75, ++0xF0,0x10,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, ++0xED,0x33,0xFD,0xCC,0x33,0xCC,0xC8,0x33, ++0xC8,0x10,0xD7,0x07,0x9B,0xEC,0x9A,0xE8, ++0x99,0x40,0x0A,0xED,0x9B,0xFD,0xEC,0x9A, ++0xFC,0xE8,0x99,0xF8,0x0F,0xD5,0xF0,0xDA, ++0xE4,0xCD,0xFB,0xE4,0xCC,0xFA,0xE4,0xC8, ++0xF9,0x22,0xEB,0x9F,0xF5,0xF0,0xEA,0x9E, ++0x42,0xF0,0xE9,0x9D,0x42,0xF0,0xE8,0x9C, ++0x45,0xF0,0x22,0xE0,0xFC,0xA3,0xE0,0xFD, ++0xA3,0xE0,0xFE,0xA3,0xE0,0xFF,0x22,0xE0, ++0xF8,0xA3,0xE0,0xF9,0xA3,0xE0,0xFA,0xA3, ++0xE0,0xFB,0x22,0xEC,0xF0,0xA3,0xED,0xF0, ++0xA3,0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0x7D, ++0xD7,0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12, ++0x07,0xAB,0x7D,0x80,0x7C,0x04,0x7F,0x01, ++0x7E,0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C, ++0x00,0x7F,0x00,0x7E,0x66,0x12,0x07,0xAB, ++0x7D,0x94,0x7C,0xF9,0x7F,0x02,0x7E,0x66, ++0x12,0x07,0xAB,0x7D,0x81,0x7C,0x04,0x7F, ++0x01,0x7E,0x66,0x12,0x07,0xAB,0x7D,0xC0, ++0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,0x07, ++0xAB,0x7D,0xA2,0x7C,0x31,0x7F,0x02,0x7E, ++0x66,0x12,0x07,0xAB,0x7D,0x82,0x7C,0x04, ++0x7F,0x01,0x7E,0x66,0x12,0x07,0xAB,0x7D, ++0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, ++0x07,0xAB,0x7D,0x60,0x7C,0x69,0x7F,0x02, ++0x7E,0x66,0x12,0x07,0xAB,0x7D,0x83,0x7C, ++0x04,0x7F,0x01,0x7E,0x66,0x12,0x07,0xAB, ++0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66, ++0x12,0x07,0xAB,0x7D,0x28,0x7C,0x97,0x7F, ++0x02,0x7E,0x66,0x12,0x07,0xAB,0x7D,0x84, ++0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12,0x07, ++0xAB,0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E, ++0x66,0x12,0x07,0xAB,0x7D,0x85,0x7C,0x9D, ++0x7F,0x02,0x7E,0x66,0x12,0x07,0xAB,0x7D, ++0x23,0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12, ++0x07,0xAB,0x7D,0xC0,0x7C,0x00,0x7F,0x00, ++0x7E,0x66,0x12,0x07,0xAB,0x7D,0x10,0x7C, ++0xD8,0x7F,0x02,0x7E,0x66,0x12,0x07,0xAB, ++0x7D,0x24,0x7C,0x04,0x7F,0x01,0x7E,0x66, ++0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00,0x7F, ++0x00,0x7E,0x66,0x12,0x07,0xAB,0x7D,0x00, ++0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12,0x07, ++0xAB,0x7D,0x2F,0x7C,0x00,0x7F,0x01,0x7E, ++0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00, ++0x7F,0x00,0x7E,0x66,0x02,0x07,0xAB,0x7D, ++0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, ++0x07,0xAB,0x7D,0x80,0x7C,0x00,0x7F,0x00, ++0x7E,0x66,0x12,0x07,0xAB,0x7F,0x02,0x7E, ++0x66,0x12,0x07,0x66,0xEF,0x44,0x40,0xFD, ++0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, ++0xAB,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, ++0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00, ++0x7F,0x00,0x7E,0x66,0x12,0x07,0xAB,0x7D, ++0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, ++0x07,0xAB,0x7D,0x80,0x7C,0x00,0x7F,0x00, ++0x7E,0x66,0x12,0x07,0xAB,0x7F,0x02,0x7E, ++0x66,0x12,0x07,0x66,0xEF,0x54,0xBF,0xFD, ++0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, ++0xAB,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, ++0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00, ++0x7F,0x00,0x7E,0x66,0x12,0x07,0xAB,0xE4, ++0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, ++0xAB,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, ++0x66,0x12,0x07,0xAB,0x7F,0x02,0x7E,0x66, ++0x12,0x07,0x66,0xEF,0x54,0xFD,0x54,0xFE, ++0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, ++0x07,0xAB,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, ++0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00, ++0x7F,0x00,0x7E,0x66,0x12,0x07,0xAB,0xE4, ++0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, ++0xAB,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, ++0x66,0x12,0x07,0xAB,0x7F,0x02,0x7E,0x66, ++0x12,0x07,0x66,0xEF,0x44,0x02,0x44,0x01, ++0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, ++0x07,0xAB,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, ++0x66,0x12,0x07,0xAB,0x7D,0xC0,0x7C,0x00, ++0x7F,0x00,0x7E,0x66,0x02,0x07,0xAB,0xE4, ++0x90,0x06,0x2C,0xF0,0xFD,0x7C,0x01,0x7F, ++0x3F,0x7E,0x1D,0x12,0x07,0xAB,0x7D,0x40, ++0x7C,0x00,0x7F,0x36,0x7E,0x13,0x12,0x07, ++0xAB,0xE4,0xFF,0xFE,0xFD,0x80,0x25,0xE4, ++0x7F,0xFF,0x7E,0xFF,0xFD,0xFC,0x90,0x06, ++0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, ++0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, ++0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, ++0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, ++0x12,0x01,0x1B,0x80,0xD2,0xE4,0xF5,0xA8, ++0xD2,0xAF,0x7D,0x1F,0xFC,0x7F,0x49,0x7E, ++0x13,0x12,0x07,0xAB,0x12,0x07,0xDB,0x12, ++0x01,0x27,0x12,0x06,0x1B,0x12,0x07,0x8A, ++0x12,0x06,0xEA,0x7D,0x41,0x7C,0x00,0x7F, ++0x36,0x7E,0x13,0x12,0x07,0xAB,0xE4,0xFF, ++0xFE,0xFD,0x80,0x26,0x7F,0xFF,0x7E,0xFF, ++0x7D,0x05,0x7C,0x00,0x90,0x06,0x24,0x12, ++0x01,0x0F,0xC3,0x12,0x00,0xF2,0x50,0x1B, ++0x90,0x06,0x24,0x12,0x01,0x03,0xEF,0x24, ++0x01,0xFF,0xE4,0x3E,0xFE,0xE4,0x3D,0xFD, ++0xE4,0x3C,0xFC,0x90,0x06,0x24,0x12,0x01, ++0x1B,0x80,0xD1,0xC2,0x00,0xC2,0x01,0xD2, ++0xA9,0xD2,0x8C,0x7F,0x01,0x7E,0x62,0x12, ++0x07,0x66,0xEF,0x30,0xE2,0x07,0xE4,0x90, ++0x06,0x2C,0xF0,0x80,0xEE,0x90,0x06,0x2C, ++0xE0,0x70,0x12,0x12,0x04,0xF0,0x90,0x06, ++0x2C,0x74,0x01,0xF0,0xE4,0x90,0x06,0x33, ++0xF0,0xA3,0xF0,0x80,0xD6,0xC3,0x90,0x06, ++0x34,0xE0,0x94,0x62,0x90,0x06,0x33,0xE0, ++0x94,0x00,0x40,0xC7,0xE4,0xF0,0xA3,0xF0, ++0x12,0x04,0xF0,0x90,0x06,0x2C,0x74,0x01, ++0xF0,0x80,0xB8,0x75,0x0F,0x80,0x75,0x0E, ++0x7E,0x75,0x0D,0xAA,0x75,0x0C,0x83,0xE4, ++0xF5,0x10,0x7F,0x36,0x7E,0x13,0x12,0x07, ++0x66,0xEE,0xC4,0xF8,0x54,0xF0,0xC8,0xEF, ++0xC4,0x54,0x0F,0x48,0x54,0x07,0xFB,0x7A, ++0x00,0xEA,0x70,0x4A,0xEB,0x14,0x60,0x1C, ++0x14,0x60,0x27,0x24,0xFE,0x60,0x31,0x14, ++0x60,0x3C,0x24,0x05,0x70,0x38,0x75,0x0B, ++0x00,0x75,0x0A,0xC2,0x75,0x09,0xEB,0x75, ++0x08,0x0B,0x80,0x36,0x75,0x0B,0x40,0x75, ++0x0A,0x59,0x75,0x09,0x73,0x75,0x08,0x07, ++0x80,0x28,0x75,0x0B,0x00,0x75,0x0A,0xE1, ++0x75,0x09,0xF5,0x75,0x08,0x05,0x80,0x1A, ++0x75,0x0B,0xA0,0x75,0x0A,0xAC,0x75,0x09, ++0xB9,0x75,0x08,0x03,0x80,0x0C,0x75,0x0B, ++0x00,0x75,0x0A,0x62,0x75,0x09,0x3D,0x75, ++0x08,0x01,0x75,0x89,0x11,0xE4,0x7B,0x60, ++0x7A,0x09,0xF9,0xF8,0xAF,0x0B,0xAE,0x0A, ++0xAD,0x09,0xAC,0x08,0x12,0x00,0x60,0xAA, ++0x06,0xAB,0x07,0xC3,0xE4,0x9B,0xFB,0xE4, ++0x9A,0xFA,0x78,0x17,0xF6,0xAF,0x03,0xEF, ++0x08,0xF6,0x18,0xE6,0xF5,0x8C,0x08,0xE6, ++0xF5,0x8A,0x74,0x0D,0x2B,0xFB,0xE4,0x3A, ++0x18,0xF6,0xAF,0x03,0xEF,0x08,0xF6,0x75, ++0x88,0x10,0x53,0x8E,0xC7,0xD2,0xA9,0x22, ++0x7F,0x10,0x7E,0x13,0x12,0x07,0x66,0x90, ++0x06,0x2D,0xEE,0xF0,0xA3,0xEF,0xF0,0xEE, ++0x44,0x10,0xFE,0x90,0x06,0x2D,0xF0,0xA3, ++0xEF,0xF0,0x54,0xEF,0xFF,0x90,0x06,0x2D, ++0xEE,0xF0,0xFC,0xA3,0xEF,0xF0,0xFD,0x7F, ++0x10,0x7E,0x13,0x12,0x07,0xAB,0xE4,0xFF, ++0xFE,0x0F,0xBF,0x00,0x01,0x0E,0xEF,0x64, ++0x64,0x4E,0x70,0xF5,0x7D,0x04,0x7C,0x00, ++0x7F,0x02,0x7E,0x66,0x12,0x07,0xAB,0x7D, ++0x00,0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12, ++0x07,0xAB,0x7D,0xC0,0x7C,0x00,0x7F,0x00, ++0x7E,0x66,0x12,0x07,0xAB,0xE4,0xFD,0xFC, ++0x7F,0x02,0x7E,0x66,0x12,0x07,0xAB,0x7D, ++0x00,0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12, ++0x07,0xAB,0x7D,0xC0,0x7C,0x00,0x7F,0x00, ++0x7E,0x66,0x12,0x07,0xAB,0x7F,0x10,0x7E, ++0x13,0x12,0x07,0x66,0x90,0x06,0x2D,0xEE, ++0xF0,0xA3,0xEF,0xF0,0xEE,0x54,0xEF,0x90, ++0x06,0x2D,0xF0,0xFC,0xA3,0xEF,0xF0,0xFD, ++0x7F,0x10,0x7E,0x13,0x02,0x07,0xAB,0x78, ++0x7F,0xE4,0xF6,0xD8,0xFD,0x75,0x81,0x3C, ++0x02,0x05,0xD6,0x02,0x03,0x2F,0xE4,0x93, ++0xA3,0xF8,0xE4,0x93,0xA3,0x40,0x03,0xF6, ++0x80,0x01,0xF2,0x08,0xDF,0xF4,0x80,0x29, ++0xE4,0x93,0xA3,0xF8,0x54,0x07,0x24,0x0C, ++0xC8,0xC3,0x33,0xC4,0x54,0x0F,0x44,0x20, ++0xC8,0x83,0x40,0x04,0xF4,0x56,0x80,0x01, ++0x46,0xF6,0xDF,0xE4,0x80,0x0B,0x01,0x02, ++0x04,0x08,0x10,0x20,0x40,0x80,0x90,0x07, ++0xE7,0xE4,0x7E,0x01,0x93,0x60,0xBC,0xA3, ++0xFF,0x54,0x3F,0x30,0xE5,0x09,0x54,0x1F, ++0xFE,0xE4,0x93,0xA3,0x60,0x01,0x0E,0xCF, ++0x54,0xC0,0x25,0xE0,0x60,0xA8,0x40,0xB8, ++0xE4,0x93,0xA3,0xFA,0xE4,0x93,0xA3,0xF8, ++0xE4,0x93,0xA3,0xC8,0xC5,0x82,0xC8,0xCA, ++0xC5,0x83,0xCA,0xF0,0xA3,0xC8,0xC5,0x82, ++0xC8,0xCA,0xC5,0x83,0xCA,0xDF,0xE9,0xDE, ++0xE7,0x80,0xBE,0x7D,0x40,0x7C,0x17,0x7F, ++0x11,0x7E,0x1D,0x12,0x07,0xAB,0x7F,0x41, ++0x7E,0x1D,0x12,0x07,0x66,0xEF,0x44,0x20, ++0x44,0x80,0xFD,0xAC,0x06,0x7F,0x41,0x7E, ++0x1D,0x12,0x07,0xAB,0x7D,0xBB,0x7C,0x15, ++0x7F,0xEB,0x7E,0x13,0x12,0x07,0xAB,0x7D, ++0x07,0x7C,0x00,0x7F,0xE7,0x7E,0x13,0x12, ++0x07,0xAB,0x7D,0x40,0x7C,0x11,0x7F,0x00, ++0x7E,0x62,0x12,0x07,0xAB,0x02,0x02,0x2F, ++0x7D,0xC0,0x7C,0x16,0x7F,0x11,0x7E,0x1D, ++0x12,0x07,0xAB,0x7D,0xBB,0x7C,0x15,0x7F, ++0xEB,0x7E,0x13,0x12,0x07,0xAB,0x7D,0x0D, ++0x7C,0x00,0x7F,0xE7,0x7E,0x13,0x12,0x07, ++0xAB,0x7F,0x41,0x7E,0x1D,0x12,0x07,0x66, ++0xEF,0x44,0x20,0x44,0x80,0xFD,0xAC,0x06, ++0x7F,0x41,0x7E,0x1D,0x12,0x07,0xAB,0x7D, ++0x00,0x7C,0x21,0x7F,0x00,0x7E,0x62,0x12, ++0x07,0xAB,0x02,0x02,0x2F,0x7D,0x40,0x7C, ++0x17,0x7F,0x11,0x7E,0x1D,0x12,0x07,0xAB, ++0x7D,0xBB,0x7C,0x15,0x7F,0xEB,0x7E,0x13, ++0x12,0x07,0xAB,0x7D,0x0C,0x7C,0x00,0x7F, ++0xE7,0x7E,0x13,0x12,0x07,0xAB,0x7F,0x41, ++0x7E,0x1D,0x12,0x07,0x66,0xEF,0x44,0x20, ++0x44,0x80,0xFD,0xAC,0x06,0x7F,0x41,0x7E, ++0x1D,0x12,0x07,0xAB,0x7D,0x40,0x7C,0x11, ++0x7F,0x00,0x7E,0x62,0x12,0x07,0xAB,0x02, ++0x02,0x2F,0x7D,0x04,0x7C,0x00,0x7F,0x01, ++0x7E,0x66,0x12,0x07,0xAB,0x7D,0x80,0x7C, ++0x00,0x7F,0x00,0x7E,0x66,0x12,0x07,0xAB, ++0x7F,0x02,0x7E,0x66,0x12,0x07,0x66,0xEF, ++0x44,0x02,0x44,0x04,0xFD,0xAC,0x06,0x7F, ++0x02,0x7E,0x66,0x12,0x07,0xAB,0x7D,0x04, ++0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12,0x07, ++0xAB,0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E, ++0x66,0x02,0x07,0xAB,0xC0,0xE0,0xC0,0xF0, ++0xC0,0x83,0xC0,0x82,0xC0,0xD0,0x75,0xD0, ++0x00,0xC0,0x00,0x78,0x17,0xE6,0xF5,0x8C, ++0x78,0x18,0xE6,0xF5,0x8A,0x90,0x06,0x31, ++0xE4,0x75,0xF0,0x01,0x12,0x00,0x0E,0x90, ++0x06,0x33,0xE4,0x75,0xF0,0x01,0x12,0x00, ++0x0E,0xD0,0x00,0xD0,0xD0,0xD0,0x82,0xD0, ++0x83,0xD0,0xF0,0xD0,0xE0,0x32,0xC2,0xAF, ++0xAD,0x07,0xAC,0x06,0x8C,0xA2,0x8D,0xA3, ++0x75,0xA0,0x01,0x00,0x00,0x00,0x00,0x00, ++0x00,0x00,0x00,0x00,0x00,0x00,0xAE,0xA1, ++0xBE,0x00,0xF0,0xAE,0xA6,0xAF,0xA7,0xD2, ++0xAF,0x22,0x7D,0x20,0x7C,0x0F,0x7F,0x02, ++0x7E,0x66,0x12,0x07,0xAB,0x7D,0x01,0x7C, ++0x00,0x7F,0x01,0x7E,0x66,0x12,0x07,0xAB, ++0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66, ++0x02,0x07,0xAB,0xC2,0xAF,0xAB,0x07,0xAA, ++0x06,0x8A,0xA2,0x8B,0xA3,0x8C,0xA4,0x8D, ++0xA5,0x75,0xA0,0x03,0x00,0x00,0x00,0xAA, ++0xA1,0xBA,0x00,0xF8,0xD2,0xAF,0x22,0x7F, ++0x0C,0x7E,0x13,0x12,0x07,0x66,0xEF,0x44, ++0x50,0xFD,0xAC,0x06,0x7F,0x0C,0x7E,0x13, ++0x02,0x07,0xAB,0x12,0x07,0xC7,0x12,0x07, ++0xF2,0x12,0x04,0x2B,0x02,0x00,0x03,0x42, ++0x06,0x33,0x00,0x00,0x42,0x06,0x31,0x00, ++0x00,0x00,0xE4,0xF5,0x8E,0x22,}; ++ ++#define FIBER2_1G_INIT_SIZE 2032 ++rtk_uint8 Fiber2_1G[FIBER2_1G_INIT_SIZE] = { ++0x02,0x05,0x89,0xE4,0xF5,0xA8,0xD2,0xAF, ++0x22,0x00,0x00,0x02,0x07,0x26,0xC5,0xF0, ++0xF8,0xA3,0xE0,0x28,0xF0,0xC5,0xF0,0xF8, ++0xE5,0x82,0x15,0x82,0x70,0x02,0x15,0x83, ++0xE0,0x38,0xF0,0x22,0x75,0xF0,0x08,0x75, ++0x82,0x00,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, ++0xCD,0x33,0xCD,0xCC,0x33,0xCC,0xC5,0x82, ++0x33,0xC5,0x82,0x9B,0xED,0x9A,0xEC,0x99, ++0xE5,0x82,0x98,0x40,0x0C,0xF5,0x82,0xEE, ++0x9B,0xFE,0xED,0x9A,0xFD,0xEC,0x99,0xFC, ++0x0F,0xD5,0xF0,0xD6,0xE4,0xCE,0xFB,0xE4, ++0xCD,0xFA,0xE4,0xCC,0xF9,0xA8,0x82,0x22, ++0xB8,0x00,0xC1,0xB9,0x00,0x59,0xBA,0x00, ++0x2D,0xEC,0x8B,0xF0,0x84,0xCF,0xCE,0xCD, ++0xFC,0xE5,0xF0,0xCB,0xF9,0x78,0x18,0xEF, ++0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33,0xFD, ++0xEC,0x33,0xFC,0xEB,0x33,0xFB,0x10,0xD7, ++0x03,0x99,0x40,0x04,0xEB,0x99,0xFB,0x0F, ++0xD8,0xE5,0xE4,0xF9,0xFA,0x22,0x78,0x18, ++0xEF,0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33, ++0xFD,0xEC,0x33,0xFC,0xC9,0x33,0xC9,0x10, ++0xD7,0x05,0x9B,0xE9,0x9A,0x40,0x07,0xEC, ++0x9B,0xFC,0xE9,0x9A,0xF9,0x0F,0xD8,0xE0, ++0xE4,0xC9,0xFA,0xE4,0xCC,0xFB,0x22,0x75, ++0xF0,0x10,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, ++0xED,0x33,0xFD,0xCC,0x33,0xCC,0xC8,0x33, ++0xC8,0x10,0xD7,0x07,0x9B,0xEC,0x9A,0xE8, ++0x99,0x40,0x0A,0xED,0x9B,0xFD,0xEC,0x9A, ++0xFC,0xE8,0x99,0xF8,0x0F,0xD5,0xF0,0xDA, ++0xE4,0xCD,0xFB,0xE4,0xCC,0xFA,0xE4,0xC8, ++0xF9,0x22,0xEB,0x9F,0xF5,0xF0,0xEA,0x9E, ++0x42,0xF0,0xE9,0x9D,0x42,0xF0,0xE8,0x9C, ++0x45,0xF0,0x22,0xE0,0xFC,0xA3,0xE0,0xFD, ++0xA3,0xE0,0xFE,0xA3,0xE0,0xFF,0x22,0xE0, ++0xF8,0xA3,0xE0,0xF9,0xA3,0xE0,0xFA,0xA3, ++0xE0,0xFB,0x22,0xEC,0xF0,0xA3,0xED,0xF0, ++0xA3,0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0x7D, ++0xD7,0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12, ++0x07,0xA5,0x7D,0x80,0x7C,0x04,0x7F,0x01, ++0x7E,0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C, ++0x00,0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5, ++0x7D,0x94,0x7C,0xF9,0x7F,0x02,0x7E,0x66, ++0x12,0x07,0xA5,0x7D,0x81,0x7C,0x04,0x7F, ++0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D,0xC0, ++0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,0x07, ++0xA5,0x7D,0xA2,0x7C,0x31,0x7F,0x02,0x7E, ++0x66,0x12,0x07,0xA5,0x7D,0x82,0x7C,0x04, ++0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D, ++0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, ++0x07,0xA5,0x7D,0x60,0x7C,0x69,0x7F,0x02, ++0x7E,0x66,0x12,0x07,0xA5,0x7D,0x83,0x7C, ++0x04,0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5, ++0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66, ++0x12,0x07,0xA5,0x7D,0x28,0x7C,0x97,0x7F, ++0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D,0x84, ++0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12,0x07, ++0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E, ++0x66,0x12,0x07,0xA5,0x7D,0x85,0x7C,0x9D, ++0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D, ++0x23,0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12, ++0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00, ++0x7E,0x66,0x12,0x07,0xA5,0x7D,0x10,0x7C, ++0xD8,0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5, ++0x7D,0x24,0x7C,0x04,0x7F,0x01,0x7E,0x66, ++0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F, ++0x00,0x7E,0x66,0x12,0x07,0xA5,0x7D,0x00, ++0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12,0x07, ++0xA5,0x7D,0x2F,0x7C,0x00,0x7F,0x01,0x7E, ++0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, ++0x7F,0x00,0x7E,0x66,0x02,0x07,0xA5,0x7D, ++0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, ++0x07,0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00, ++0x7E,0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E, ++0x66,0x12,0x07,0x60,0xEF,0x44,0x40,0xFD, ++0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, ++0xA5,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, ++0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, ++0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0x7D, ++0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, ++0x07,0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00, ++0x7E,0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E, ++0x66,0x12,0x07,0x60,0xEF,0x54,0xBF,0xFD, ++0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, ++0xA5,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, ++0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, ++0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, ++0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, ++0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, ++0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E,0x66, ++0x12,0x07,0x60,0xEF,0x54,0xFD,0x54,0xFE, ++0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, ++0x07,0xA5,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, ++0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, ++0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, ++0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, ++0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, ++0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E,0x66, ++0x12,0x07,0x60,0xEF,0x44,0x02,0x44,0x01, ++0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, ++0x07,0xA5,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, ++0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, ++0x7F,0x00,0x7E,0x66,0x02,0x07,0xA5,0xE4, ++0x90,0x06,0x2C,0xF0,0xFD,0x7C,0x01,0x7F, ++0x3F,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0x40, ++0x7C,0x00,0x7F,0x36,0x7E,0x13,0x12,0x07, ++0xA5,0xE4,0xFF,0xFE,0xFD,0x80,0x25,0xE4, ++0x7F,0xFF,0x7E,0xFF,0xFD,0xFC,0x90,0x06, ++0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, ++0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, ++0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, ++0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, ++0x12,0x01,0x1B,0x80,0xD2,0xE4,0xF5,0xA8, ++0xD2,0xAF,0x7D,0x1F,0xFC,0x7F,0x49,0x7E, ++0x13,0x12,0x07,0xA5,0x12,0x07,0xD5,0x12, ++0x01,0x27,0x12,0x06,0x9F,0x7D,0x41,0x7C, ++0x00,0x7F,0x36,0x7E,0x13,0x12,0x07,0xA5, ++0xE4,0xFF,0xFE,0xFD,0x80,0x26,0x7F,0xFF, ++0x7E,0xFF,0x7D,0x05,0x7C,0x00,0x90,0x06, ++0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, ++0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, ++0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, ++0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, ++0x12,0x01,0x1B,0x80,0xD1,0xC2,0x00,0xC2, ++0x01,0xD2,0xA9,0xD2,0x8C,0x7F,0x01,0x7E, ++0x62,0x12,0x07,0x60,0xEF,0x30,0xE2,0x07, ++0xE4,0x90,0x06,0x2C,0xF0,0x80,0xEE,0x90, ++0x06,0x2C,0xE0,0x70,0x12,0x12,0x04,0xEA, ++0x90,0x06,0x2C,0x74,0x01,0xF0,0xE4,0x90, ++0x06,0x33,0xF0,0xA3,0xF0,0x80,0xD6,0xC3, ++0x90,0x06,0x34,0xE0,0x94,0x62,0x90,0x06, ++0x33,0xE0,0x94,0x00,0x40,0xC7,0xE4,0xF0, ++0xA3,0xF0,0x12,0x04,0xEA,0x90,0x06,0x2C, ++0x74,0x01,0xF0,0x80,0xB8,0x75,0x0F,0x80, ++0x75,0x0E,0x7E,0x75,0x0D,0xAA,0x75,0x0C, ++0x83,0xE4,0xF5,0x10,0x7F,0x36,0x7E,0x13, ++0x12,0x07,0x60,0xEE,0xC4,0xF8,0x54,0xF0, ++0xC8,0xEF,0xC4,0x54,0x0F,0x48,0x54,0x07, ++0xFB,0x7A,0x00,0xEA,0x70,0x4A,0xEB,0x14, ++0x60,0x1C,0x14,0x60,0x27,0x24,0xFE,0x60, ++0x31,0x14,0x60,0x3C,0x24,0x05,0x70,0x38, ++0x75,0x0B,0x00,0x75,0x0A,0xC2,0x75,0x09, ++0xEB,0x75,0x08,0x0B,0x80,0x36,0x75,0x0B, ++0x40,0x75,0x0A,0x59,0x75,0x09,0x73,0x75, ++0x08,0x07,0x80,0x28,0x75,0x0B,0x00,0x75, ++0x0A,0xE1,0x75,0x09,0xF5,0x75,0x08,0x05, ++0x80,0x1A,0x75,0x0B,0xA0,0x75,0x0A,0xAC, ++0x75,0x09,0xB9,0x75,0x08,0x03,0x80,0x0C, ++0x75,0x0B,0x00,0x75,0x0A,0x62,0x75,0x09, ++0x3D,0x75,0x08,0x01,0x75,0x89,0x11,0xE4, ++0x7B,0x60,0x7A,0x09,0xF9,0xF8,0xAF,0x0B, ++0xAE,0x0A,0xAD,0x09,0xAC,0x08,0x12,0x00, ++0x60,0xAA,0x06,0xAB,0x07,0xC3,0xE4,0x9B, ++0xFB,0xE4,0x9A,0xFA,0x78,0x17,0xF6,0xAF, ++0x03,0xEF,0x08,0xF6,0x18,0xE6,0xF5,0x8C, ++0x08,0xE6,0xF5,0x8A,0x74,0x0D,0x2B,0xFB, ++0xE4,0x3A,0x18,0xF6,0xAF,0x03,0xEF,0x08, ++0xF6,0x75,0x88,0x10,0x53,0x8E,0xC7,0xD2, ++0xA9,0x22,0x7F,0x10,0x7E,0x13,0x12,0x07, ++0x60,0x90,0x06,0x2D,0xEE,0xF0,0xA3,0xEF, ++0xF0,0xEE,0x44,0x10,0xFE,0x90,0x06,0x2D, ++0xF0,0xA3,0xEF,0xF0,0x54,0xEF,0xFF,0x90, ++0x06,0x2D,0xEE,0xF0,0xFC,0xA3,0xEF,0xF0, ++0xFD,0x7F,0x10,0x7E,0x13,0x12,0x07,0xA5, ++0xE4,0xFF,0xFE,0x0F,0xBF,0x00,0x01,0x0E, ++0xEF,0x64,0x64,0x4E,0x70,0xF5,0x7D,0x04, ++0x7C,0x00,0x7F,0x02,0x7E,0x66,0x12,0x07, ++0xA5,0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E, ++0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, ++0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, ++0xFD,0xFC,0x7F,0x02,0x7E,0x66,0x12,0x07, ++0xA5,0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E, ++0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, ++0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0x7F, ++0x10,0x7E,0x13,0x12,0x07,0x60,0x90,0x06, ++0x2D,0xEE,0xF0,0xA3,0xEF,0xF0,0xEE,0x54, ++0xEF,0x90,0x06,0x2D,0xF0,0xFC,0xA3,0xEF, ++0xF0,0xFD,0x7F,0x10,0x7E,0x13,0x02,0x07, ++0xA5,0x78,0x7F,0xE4,0xF6,0xD8,0xFD,0x75, ++0x81,0x3C,0x02,0x05,0xD0,0x02,0x03,0x2F, ++0xE4,0x93,0xA3,0xF8,0xE4,0x93,0xA3,0x40, ++0x03,0xF6,0x80,0x01,0xF2,0x08,0xDF,0xF4, ++0x80,0x29,0xE4,0x93,0xA3,0xF8,0x54,0x07, ++0x24,0x0C,0xC8,0xC3,0x33,0xC4,0x54,0x0F, ++0x44,0x20,0xC8,0x83,0x40,0x04,0xF4,0x56, ++0x80,0x01,0x46,0xF6,0xDF,0xE4,0x80,0x0B, ++0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80, ++0x90,0x07,0xE1,0xE4,0x7E,0x01,0x93,0x60, ++0xBC,0xA3,0xFF,0x54,0x3F,0x30,0xE5,0x09, ++0x54,0x1F,0xFE,0xE4,0x93,0xA3,0x60,0x01, ++0x0E,0xCF,0x54,0xC0,0x25,0xE0,0x60,0xA8, ++0x40,0xB8,0xE4,0x93,0xA3,0xFA,0xE4,0x93, ++0xA3,0xF8,0xE4,0x93,0xA3,0xC8,0xC5,0x82, ++0xC8,0xCA,0xC5,0x83,0xCA,0xF0,0xA3,0xC8, ++0xC5,0x82,0xC8,0xCA,0xC5,0x83,0xCA,0xDF, ++0xE9,0xDE,0xE7,0x80,0xBE,0x7D,0x40,0x7C, ++0x17,0x7F,0x11,0x7E,0x1D,0x12,0x07,0xA5, ++0x7F,0x41,0x7E,0x1D,0x12,0x07,0x60,0xEF, ++0x44,0x20,0x44,0x80,0xFD,0xAC,0x06,0x7F, ++0x41,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0xBB, ++0x7C,0x15,0x7F,0xEB,0x7E,0x13,0x12,0x07, ++0xA5,0x7D,0x07,0x7C,0x00,0x7F,0xE7,0x7E, ++0x13,0x12,0x07,0xA5,0x7D,0x40,0x7C,0x11, ++0x7F,0x00,0x7E,0x62,0x12,0x07,0xA5,0x02, ++0x02,0x2F,0x7D,0xC0,0x7C,0x16,0x7F,0x11, ++0x7E,0x1D,0x12,0x07,0xA5,0x7D,0xBB,0x7C, ++0x15,0x7F,0xEB,0x7E,0x13,0x12,0x07,0xA5, ++0x7D,0x0D,0x7C,0x00,0x7F,0xE7,0x7E,0x13, ++0x12,0x07,0xA5,0x7F,0x41,0x7E,0x1D,0x12, ++0x07,0x60,0xEF,0x44,0x20,0x44,0x80,0xFD, ++0xAC,0x06,0x7F,0x41,0x7E,0x1D,0x12,0x07, ++0xA5,0x7D,0x00,0x7C,0x21,0x7F,0x00,0x7E, ++0x62,0x12,0x07,0xA5,0x02,0x02,0x2F,0x7D, ++0x40,0x7C,0x17,0x7F,0x11,0x7E,0x1D,0x12, ++0x07,0xA5,0x7D,0xBB,0x7C,0x15,0x7F,0xEB, ++0x7E,0x13,0x12,0x07,0xA5,0x7D,0x0C,0x7C, ++0x00,0x7F,0xE7,0x7E,0x13,0x12,0x07,0xA5, ++0x7F,0x41,0x7E,0x1D,0x12,0x07,0x60,0xEF, ++0x44,0x20,0x44,0x80,0xFD,0xAC,0x06,0x7F, ++0x41,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0x40, ++0x7C,0x11,0x7F,0x00,0x7E,0x62,0x12,0x07, ++0xA5,0x02,0x02,0x2F,0x7D,0x04,0x7C,0x00, ++0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D, ++0x80,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, ++0x07,0xA5,0x7F,0x02,0x7E,0x66,0x12,0x07, ++0x60,0xEF,0x44,0x02,0x44,0x04,0xFD,0xAC, ++0x06,0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5, ++0x7D,0x04,0x7C,0x00,0x7F,0x01,0x7E,0x66, ++0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F, ++0x00,0x7E,0x66,0x02,0x07,0xA5,0xC0,0xE0, ++0xC0,0xF0,0xC0,0x83,0xC0,0x82,0xC0,0xD0, ++0x75,0xD0,0x00,0xC0,0x00,0x78,0x17,0xE6, ++0xF5,0x8C,0x78,0x18,0xE6,0xF5,0x8A,0x90, ++0x06,0x31,0xE4,0x75,0xF0,0x01,0x12,0x00, ++0x0E,0x90,0x06,0x33,0xE4,0x75,0xF0,0x01, ++0x12,0x00,0x0E,0xD0,0x00,0xD0,0xD0,0xD0, ++0x82,0xD0,0x83,0xD0,0xF0,0xD0,0xE0,0x32, ++0xC2,0xAF,0xAD,0x07,0xAC,0x06,0x8C,0xA2, ++0x8D,0xA3,0x75,0xA0,0x01,0x00,0x00,0x00, ++0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ++0xAE,0xA1,0xBE,0x00,0xF0,0xAE,0xA6,0xAF, ++0xA7,0xD2,0xAF,0x22,0x7D,0x20,0x7C,0x0F, ++0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D, ++0x01,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, ++0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00, ++0x7E,0x66,0x02,0x07,0xA5,0xC2,0xAF,0xAB, ++0x07,0xAA,0x06,0x8A,0xA2,0x8B,0xA3,0x8C, ++0xA4,0x8D,0xA5,0x75,0xA0,0x03,0x00,0x00, ++0x00,0xAA,0xA1,0xBA,0x00,0xF8,0xD2,0xAF, ++0x22,0x7F,0x0C,0x7E,0x13,0x12,0x07,0x60, ++0xEF,0x44,0x50,0xFD,0xAC,0x06,0x7F,0x0C, ++0x7E,0x13,0x02,0x07,0xA5,0x12,0x07,0xC1, ++0x12,0x07,0xEC,0x12,0x04,0x25,0x02,0x00, ++0x03,0x42,0x06,0x33,0x00,0x00,0x42,0x06, ++0x31,0x00,0x00,0x00,0xE4,0xF5,0x8E,0x22,}; ++ ++#define FIBER2_100M_INIT_SIZE 2032 ++rtk_uint8 Fiber2_100M[FIBER2_100M_INIT_SIZE] = { ++0x02,0x05,0x89,0xE4,0xF5,0xA8,0xD2,0xAF, ++0x22,0x00,0x00,0x02,0x07,0x26,0xC5,0xF0, ++0xF8,0xA3,0xE0,0x28,0xF0,0xC5,0xF0,0xF8, ++0xE5,0x82,0x15,0x82,0x70,0x02,0x15,0x83, ++0xE0,0x38,0xF0,0x22,0x75,0xF0,0x08,0x75, ++0x82,0x00,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, ++0xCD,0x33,0xCD,0xCC,0x33,0xCC,0xC5,0x82, ++0x33,0xC5,0x82,0x9B,0xED,0x9A,0xEC,0x99, ++0xE5,0x82,0x98,0x40,0x0C,0xF5,0x82,0xEE, ++0x9B,0xFE,0xED,0x9A,0xFD,0xEC,0x99,0xFC, ++0x0F,0xD5,0xF0,0xD6,0xE4,0xCE,0xFB,0xE4, ++0xCD,0xFA,0xE4,0xCC,0xF9,0xA8,0x82,0x22, ++0xB8,0x00,0xC1,0xB9,0x00,0x59,0xBA,0x00, ++0x2D,0xEC,0x8B,0xF0,0x84,0xCF,0xCE,0xCD, ++0xFC,0xE5,0xF0,0xCB,0xF9,0x78,0x18,0xEF, ++0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33,0xFD, ++0xEC,0x33,0xFC,0xEB,0x33,0xFB,0x10,0xD7, ++0x03,0x99,0x40,0x04,0xEB,0x99,0xFB,0x0F, ++0xD8,0xE5,0xE4,0xF9,0xFA,0x22,0x78,0x18, ++0xEF,0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33, ++0xFD,0xEC,0x33,0xFC,0xC9,0x33,0xC9,0x10, ++0xD7,0x05,0x9B,0xE9,0x9A,0x40,0x07,0xEC, ++0x9B,0xFC,0xE9,0x9A,0xF9,0x0F,0xD8,0xE0, ++0xE4,0xC9,0xFA,0xE4,0xCC,0xFB,0x22,0x75, ++0xF0,0x10,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, ++0xED,0x33,0xFD,0xCC,0x33,0xCC,0xC8,0x33, ++0xC8,0x10,0xD7,0x07,0x9B,0xEC,0x9A,0xE8, ++0x99,0x40,0x0A,0xED,0x9B,0xFD,0xEC,0x9A, ++0xFC,0xE8,0x99,0xF8,0x0F,0xD5,0xF0,0xDA, ++0xE4,0xCD,0xFB,0xE4,0xCC,0xFA,0xE4,0xC8, ++0xF9,0x22,0xEB,0x9F,0xF5,0xF0,0xEA,0x9E, ++0x42,0xF0,0xE9,0x9D,0x42,0xF0,0xE8,0x9C, ++0x45,0xF0,0x22,0xE0,0xFC,0xA3,0xE0,0xFD, ++0xA3,0xE0,0xFE,0xA3,0xE0,0xFF,0x22,0xE0, ++0xF8,0xA3,0xE0,0xF9,0xA3,0xE0,0xFA,0xA3, ++0xE0,0xFB,0x22,0xEC,0xF0,0xA3,0xED,0xF0, ++0xA3,0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0x7D, ++0xD7,0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12, ++0x07,0xA5,0x7D,0x80,0x7C,0x04,0x7F,0x01, ++0x7E,0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C, ++0x00,0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5, ++0x7D,0x94,0x7C,0xF9,0x7F,0x02,0x7E,0x66, ++0x12,0x07,0xA5,0x7D,0x81,0x7C,0x04,0x7F, ++0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D,0xC0, ++0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12,0x07, ++0xA5,0x7D,0xA2,0x7C,0x31,0x7F,0x02,0x7E, ++0x66,0x12,0x07,0xA5,0x7D,0x82,0x7C,0x04, ++0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D, ++0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, ++0x07,0xA5,0x7D,0x60,0x7C,0x69,0x7F,0x02, ++0x7E,0x66,0x12,0x07,0xA5,0x7D,0x83,0x7C, ++0x04,0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5, ++0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E,0x66, ++0x12,0x07,0xA5,0x7D,0x28,0x7C,0x97,0x7F, ++0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D,0x84, ++0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12,0x07, ++0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00,0x7E, ++0x66,0x12,0x07,0xA5,0x7D,0x85,0x7C,0x9D, ++0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D, ++0x23,0x7C,0x04,0x7F,0x01,0x7E,0x66,0x12, ++0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00, ++0x7E,0x66,0x12,0x07,0xA5,0x7D,0x10,0x7C, ++0xD8,0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5, ++0x7D,0x24,0x7C,0x04,0x7F,0x01,0x7E,0x66, ++0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F, ++0x00,0x7E,0x66,0x12,0x07,0xA5,0x7D,0x00, ++0x7C,0x04,0x7F,0x02,0x7E,0x66,0x12,0x07, ++0xA5,0x7D,0x2F,0x7C,0x00,0x7F,0x01,0x7E, ++0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, ++0x7F,0x00,0x7E,0x66,0x02,0x07,0xA5,0x7D, ++0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, ++0x07,0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00, ++0x7E,0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E, ++0x66,0x12,0x07,0x60,0xEF,0x44,0x40,0xFD, ++0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, ++0xA5,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, ++0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, ++0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0x7D, ++0x03,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, ++0x07,0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00, ++0x7E,0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E, ++0x66,0x12,0x07,0x60,0xEF,0x54,0xBF,0xFD, ++0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12,0x07, ++0xA5,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, ++0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, ++0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, ++0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, ++0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, ++0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E,0x66, ++0x12,0x07,0x60,0xEF,0x54,0xFD,0x54,0xFE, ++0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, ++0x07,0xA5,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, ++0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, ++0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, ++0xFD,0xFC,0x7F,0x01,0x7E,0x66,0x12,0x07, ++0xA5,0x7D,0x80,0x7C,0x00,0x7F,0x00,0x7E, ++0x66,0x12,0x07,0xA5,0x7F,0x02,0x7E,0x66, ++0x12,0x07,0x60,0xEF,0x44,0x02,0x44,0x01, ++0xFD,0xAC,0x06,0x7F,0x02,0x7E,0x66,0x12, ++0x07,0xA5,0xE4,0xFD,0xFC,0x7F,0x01,0x7E, ++0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, ++0x7F,0x00,0x7E,0x66,0x02,0x07,0xA5,0xE4, ++0x90,0x06,0x2C,0xF0,0xFD,0x7C,0x01,0x7F, ++0x3F,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0x40, ++0x7C,0x00,0x7F,0x36,0x7E,0x13,0x12,0x07, ++0xA5,0xE4,0xFF,0xFE,0xFD,0x80,0x25,0xE4, ++0x7F,0xFF,0x7E,0xFF,0xFD,0xFC,0x90,0x06, ++0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, ++0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, ++0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, ++0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, ++0x12,0x01,0x1B,0x80,0xD2,0xE4,0xF5,0xA8, ++0xD2,0xAF,0x7D,0x1F,0xFC,0x7F,0x49,0x7E, ++0x13,0x12,0x07,0xA5,0x12,0x07,0xD5,0x12, ++0x01,0x27,0x12,0x06,0x5A,0x7D,0x41,0x7C, ++0x00,0x7F,0x36,0x7E,0x13,0x12,0x07,0xA5, ++0xE4,0xFF,0xFE,0xFD,0x80,0x26,0x7F,0xFF, ++0x7E,0xFF,0x7D,0x05,0x7C,0x00,0x90,0x06, ++0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, ++0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, ++0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, ++0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, ++0x12,0x01,0x1B,0x80,0xD1,0xC2,0x00,0xC2, ++0x01,0xD2,0xA9,0xD2,0x8C,0x7F,0x01,0x7E, ++0x62,0x12,0x07,0x60,0xEF,0x30,0xE2,0x07, ++0xE4,0x90,0x06,0x2C,0xF0,0x80,0xEE,0x90, ++0x06,0x2C,0xE0,0x70,0x12,0x12,0x04,0xEA, ++0x90,0x06,0x2C,0x74,0x01,0xF0,0xE4,0x90, ++0x06,0x33,0xF0,0xA3,0xF0,0x80,0xD6,0xC3, ++0x90,0x06,0x34,0xE0,0x94,0x62,0x90,0x06, ++0x33,0xE0,0x94,0x00,0x40,0xC7,0xE4,0xF0, ++0xA3,0xF0,0x12,0x04,0xEA,0x90,0x06,0x2C, ++0x74,0x01,0xF0,0x80,0xB8,0x75,0x0F,0x80, ++0x75,0x0E,0x7E,0x75,0x0D,0xAA,0x75,0x0C, ++0x83,0xE4,0xF5,0x10,0x7F,0x36,0x7E,0x13, ++0x12,0x07,0x60,0xEE,0xC4,0xF8,0x54,0xF0, ++0xC8,0xEF,0xC4,0x54,0x0F,0x48,0x54,0x07, ++0xFB,0x7A,0x00,0xEA,0x70,0x4A,0xEB,0x14, ++0x60,0x1C,0x14,0x60,0x27,0x24,0xFE,0x60, ++0x31,0x14,0x60,0x3C,0x24,0x05,0x70,0x38, ++0x75,0x0B,0x00,0x75,0x0A,0xC2,0x75,0x09, ++0xEB,0x75,0x08,0x0B,0x80,0x36,0x75,0x0B, ++0x40,0x75,0x0A,0x59,0x75,0x09,0x73,0x75, ++0x08,0x07,0x80,0x28,0x75,0x0B,0x00,0x75, ++0x0A,0xE1,0x75,0x09,0xF5,0x75,0x08,0x05, ++0x80,0x1A,0x75,0x0B,0xA0,0x75,0x0A,0xAC, ++0x75,0x09,0xB9,0x75,0x08,0x03,0x80,0x0C, ++0x75,0x0B,0x00,0x75,0x0A,0x62,0x75,0x09, ++0x3D,0x75,0x08,0x01,0x75,0x89,0x11,0xE4, ++0x7B,0x60,0x7A,0x09,0xF9,0xF8,0xAF,0x0B, ++0xAE,0x0A,0xAD,0x09,0xAC,0x08,0x12,0x00, ++0x60,0xAA,0x06,0xAB,0x07,0xC3,0xE4,0x9B, ++0xFB,0xE4,0x9A,0xFA,0x78,0x17,0xF6,0xAF, ++0x03,0xEF,0x08,0xF6,0x18,0xE6,0xF5,0x8C, ++0x08,0xE6,0xF5,0x8A,0x74,0x0D,0x2B,0xFB, ++0xE4,0x3A,0x18,0xF6,0xAF,0x03,0xEF,0x08, ++0xF6,0x75,0x88,0x10,0x53,0x8E,0xC7,0xD2, ++0xA9,0x22,0x7F,0x10,0x7E,0x13,0x12,0x07, ++0x60,0x90,0x06,0x2D,0xEE,0xF0,0xA3,0xEF, ++0xF0,0xEE,0x44,0x10,0xFE,0x90,0x06,0x2D, ++0xF0,0xA3,0xEF,0xF0,0x54,0xEF,0xFF,0x90, ++0x06,0x2D,0xEE,0xF0,0xFC,0xA3,0xEF,0xF0, ++0xFD,0x7F,0x10,0x7E,0x13,0x12,0x07,0xA5, ++0xE4,0xFF,0xFE,0x0F,0xBF,0x00,0x01,0x0E, ++0xEF,0x64,0x64,0x4E,0x70,0xF5,0x7D,0x04, ++0x7C,0x00,0x7F,0x02,0x7E,0x66,0x12,0x07, ++0xA5,0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E, ++0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, ++0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0xE4, ++0xFD,0xFC,0x7F,0x02,0x7E,0x66,0x12,0x07, ++0xA5,0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E, ++0x66,0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00, ++0x7F,0x00,0x7E,0x66,0x12,0x07,0xA5,0x7F, ++0x10,0x7E,0x13,0x12,0x07,0x60,0x90,0x06, ++0x2D,0xEE,0xF0,0xA3,0xEF,0xF0,0xEE,0x54, ++0xEF,0x90,0x06,0x2D,0xF0,0xFC,0xA3,0xEF, ++0xF0,0xFD,0x7F,0x10,0x7E,0x13,0x02,0x07, ++0xA5,0x78,0x7F,0xE4,0xF6,0xD8,0xFD,0x75, ++0x81,0x3C,0x02,0x05,0xD0,0x02,0x03,0x2F, ++0xE4,0x93,0xA3,0xF8,0xE4,0x93,0xA3,0x40, ++0x03,0xF6,0x80,0x01,0xF2,0x08,0xDF,0xF4, ++0x80,0x29,0xE4,0x93,0xA3,0xF8,0x54,0x07, ++0x24,0x0C,0xC8,0xC3,0x33,0xC4,0x54,0x0F, ++0x44,0x20,0xC8,0x83,0x40,0x04,0xF4,0x56, ++0x80,0x01,0x46,0xF6,0xDF,0xE4,0x80,0x0B, ++0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80, ++0x90,0x07,0xE1,0xE4,0x7E,0x01,0x93,0x60, ++0xBC,0xA3,0xFF,0x54,0x3F,0x30,0xE5,0x09, ++0x54,0x1F,0xFE,0xE4,0x93,0xA3,0x60,0x01, ++0x0E,0xCF,0x54,0xC0,0x25,0xE0,0x60,0xA8, ++0x40,0xB8,0xE4,0x93,0xA3,0xFA,0xE4,0x93, ++0xA3,0xF8,0xE4,0x93,0xA3,0xC8,0xC5,0x82, ++0xC8,0xCA,0xC5,0x83,0xCA,0xF0,0xA3,0xC8, ++0xC5,0x82,0xC8,0xCA,0xC5,0x83,0xCA,0xDF, ++0xE9,0xDE,0xE7,0x80,0xBE,0x7D,0x40,0x7C, ++0x17,0x7F,0x11,0x7E,0x1D,0x12,0x07,0xA5, ++0x7F,0x41,0x7E,0x1D,0x12,0x07,0x60,0xEF, ++0x44,0x20,0x44,0x80,0xFD,0xAC,0x06,0x7F, ++0x41,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0xBB, ++0x7C,0x15,0x7F,0xEB,0x7E,0x13,0x12,0x07, ++0xA5,0x7D,0x07,0x7C,0x00,0x7F,0xE7,0x7E, ++0x13,0x12,0x07,0xA5,0x7D,0x40,0x7C,0x11, ++0x7F,0x00,0x7E,0x62,0x12,0x07,0xA5,0x02, ++0x02,0x2F,0x7D,0xC0,0x7C,0x16,0x7F,0x11, ++0x7E,0x1D,0x12,0x07,0xA5,0x7D,0xBB,0x7C, ++0x15,0x7F,0xEB,0x7E,0x13,0x12,0x07,0xA5, ++0x7D,0x0D,0x7C,0x00,0x7F,0xE7,0x7E,0x13, ++0x12,0x07,0xA5,0x7F,0x41,0x7E,0x1D,0x12, ++0x07,0x60,0xEF,0x44,0x20,0x44,0x80,0xFD, ++0xAC,0x06,0x7F,0x41,0x7E,0x1D,0x12,0x07, ++0xA5,0x7D,0x00,0x7C,0x21,0x7F,0x00,0x7E, ++0x62,0x12,0x07,0xA5,0x02,0x02,0x2F,0x7D, ++0x40,0x7C,0x17,0x7F,0x11,0x7E,0x1D,0x12, ++0x07,0xA5,0x7D,0xBB,0x7C,0x15,0x7F,0xEB, ++0x7E,0x13,0x12,0x07,0xA5,0x7D,0x0C,0x7C, ++0x00,0x7F,0xE7,0x7E,0x13,0x12,0x07,0xA5, ++0x7F,0x41,0x7E,0x1D,0x12,0x07,0x60,0xEF, ++0x44,0x20,0x44,0x80,0xFD,0xAC,0x06,0x7F, ++0x41,0x7E,0x1D,0x12,0x07,0xA5,0x7D,0x40, ++0x7C,0x11,0x7F,0x00,0x7E,0x62,0x12,0x07, ++0xA5,0x02,0x02,0x2F,0x7D,0x04,0x7C,0x00, ++0x7F,0x01,0x7E,0x66,0x12,0x07,0xA5,0x7D, ++0x80,0x7C,0x00,0x7F,0x00,0x7E,0x66,0x12, ++0x07,0xA5,0x7F,0x02,0x7E,0x66,0x12,0x07, ++0x60,0xEF,0x44,0x02,0x44,0x04,0xFD,0xAC, ++0x06,0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5, ++0x7D,0x04,0x7C,0x00,0x7F,0x01,0x7E,0x66, ++0x12,0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F, ++0x00,0x7E,0x66,0x02,0x07,0xA5,0xC0,0xE0, ++0xC0,0xF0,0xC0,0x83,0xC0,0x82,0xC0,0xD0, ++0x75,0xD0,0x00,0xC0,0x00,0x78,0x17,0xE6, ++0xF5,0x8C,0x78,0x18,0xE6,0xF5,0x8A,0x90, ++0x06,0x31,0xE4,0x75,0xF0,0x01,0x12,0x00, ++0x0E,0x90,0x06,0x33,0xE4,0x75,0xF0,0x01, ++0x12,0x00,0x0E,0xD0,0x00,0xD0,0xD0,0xD0, ++0x82,0xD0,0x83,0xD0,0xF0,0xD0,0xE0,0x32, ++0xC2,0xAF,0xAD,0x07,0xAC,0x06,0x8C,0xA2, ++0x8D,0xA3,0x75,0xA0,0x01,0x00,0x00,0x00, ++0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, ++0xAE,0xA1,0xBE,0x00,0xF0,0xAE,0xA6,0xAF, ++0xA7,0xD2,0xAF,0x22,0x7D,0x20,0x7C,0x0F, ++0x7F,0x02,0x7E,0x66,0x12,0x07,0xA5,0x7D, ++0x01,0x7C,0x00,0x7F,0x01,0x7E,0x66,0x12, ++0x07,0xA5,0x7D,0xC0,0x7C,0x00,0x7F,0x00, ++0x7E,0x66,0x02,0x07,0xA5,0xC2,0xAF,0xAB, ++0x07,0xAA,0x06,0x8A,0xA2,0x8B,0xA3,0x8C, ++0xA4,0x8D,0xA5,0x75,0xA0,0x03,0x00,0x00, ++0x00,0xAA,0xA1,0xBA,0x00,0xF8,0xD2,0xAF, ++0x22,0x7F,0x0C,0x7E,0x13,0x12,0x07,0x60, ++0xEF,0x44,0x50,0xFD,0xAC,0x06,0x7F,0x0C, ++0x7E,0x13,0x02,0x07,0xA5,0x12,0x07,0xC1, ++0x12,0x07,0xEC,0x12,0x04,0x25,0x02,0x00, ++0x03,0x42,0x06,0x33,0x00,0x00,0x42,0x06, ++0x31,0x00,0x00,0x00,0xE4,0xF5,0x8E,0x22,}; ++ ++ ++#define SGMII_INIT_SIZE 1183 ++rtk_uint8 Sgmii_Init[SGMII_INIT_SIZE] = { ++0x02,0x03,0x81,0xE4,0xF5,0xA8,0xD2,0xAF, ++0x22,0x00,0x00,0x02,0x04,0x0D,0xC5,0xF0, ++0xF8,0xA3,0xE0,0x28,0xF0,0xC5,0xF0,0xF8, ++0xE5,0x82,0x15,0x82,0x70,0x02,0x15,0x83, ++0xE0,0x38,0xF0,0x22,0x75,0xF0,0x08,0x75, ++0x82,0x00,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, ++0xCD,0x33,0xCD,0xCC,0x33,0xCC,0xC5,0x82, ++0x33,0xC5,0x82,0x9B,0xED,0x9A,0xEC,0x99, ++0xE5,0x82,0x98,0x40,0x0C,0xF5,0x82,0xEE, ++0x9B,0xFE,0xED,0x9A,0xFD,0xEC,0x99,0xFC, ++0x0F,0xD5,0xF0,0xD6,0xE4,0xCE,0xFB,0xE4, ++0xCD,0xFA,0xE4,0xCC,0xF9,0xA8,0x82,0x22, ++0xB8,0x00,0xC1,0xB9,0x00,0x59,0xBA,0x00, ++0x2D,0xEC,0x8B,0xF0,0x84,0xCF,0xCE,0xCD, ++0xFC,0xE5,0xF0,0xCB,0xF9,0x78,0x18,0xEF, ++0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33,0xFD, ++0xEC,0x33,0xFC,0xEB,0x33,0xFB,0x10,0xD7, ++0x03,0x99,0x40,0x04,0xEB,0x99,0xFB,0x0F, ++0xD8,0xE5,0xE4,0xF9,0xFA,0x22,0x78,0x18, ++0xEF,0x2F,0xFF,0xEE,0x33,0xFE,0xED,0x33, ++0xFD,0xEC,0x33,0xFC,0xC9,0x33,0xC9,0x10, ++0xD7,0x05,0x9B,0xE9,0x9A,0x40,0x07,0xEC, ++0x9B,0xFC,0xE9,0x9A,0xF9,0x0F,0xD8,0xE0, ++0xE4,0xC9,0xFA,0xE4,0xCC,0xFB,0x22,0x75, ++0xF0,0x10,0xEF,0x2F,0xFF,0xEE,0x33,0xFE, ++0xED,0x33,0xFD,0xCC,0x33,0xCC,0xC8,0x33, ++0xC8,0x10,0xD7,0x07,0x9B,0xEC,0x9A,0xE8, ++0x99,0x40,0x0A,0xED,0x9B,0xFD,0xEC,0x9A, ++0xFC,0xE8,0x99,0xF8,0x0F,0xD5,0xF0,0xDA, ++0xE4,0xCD,0xFB,0xE4,0xCC,0xFA,0xE4,0xC8, ++0xF9,0x22,0xEB,0x9F,0xF5,0xF0,0xEA,0x9E, ++0x42,0xF0,0xE9,0x9D,0x42,0xF0,0xE8,0x9C, ++0x45,0xF0,0x22,0xE0,0xFC,0xA3,0xE0,0xFD, ++0xA3,0xE0,0xFE,0xA3,0xE0,0xFF,0x22,0xE0, ++0xF8,0xA3,0xE0,0xF9,0xA3,0xE0,0xFA,0xA3, ++0xE0,0xFB,0x22,0xEC,0xF0,0xA3,0xED,0xF0, ++0xA3,0xEE,0xF0,0xA3,0xEF,0xF0,0x22,0xE4, ++0x90,0x06,0x2C,0xF0,0xFD,0x7C,0x01,0x7F, ++0x3F,0x7E,0x1D,0x12,0x04,0x6B,0x7D,0x40, ++0x7C,0x00,0x7F,0x36,0x7E,0x13,0x12,0x04, ++0x6B,0xE4,0xFF,0xFE,0xFD,0x80,0x25,0xE4, ++0x7F,0xFF,0x7E,0xFF,0xFD,0xFC,0x90,0x06, ++0x24,0x12,0x01,0x0F,0xC3,0x12,0x00,0xF2, ++0x50,0x1B,0x90,0x06,0x24,0x12,0x01,0x03, ++0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE,0xE4, ++0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06,0x24, ++0x12,0x01,0x1B,0x80,0xD2,0xE4,0xF5,0xA8, ++0xD2,0xAF,0x7D,0x1F,0xFC,0x7F,0x49,0x7E, ++0x13,0x12,0x04,0x6B,0x12,0x04,0x92,0x7D, ++0x41,0x7C,0x00,0x7F,0x36,0x7E,0x13,0x12, ++0x04,0x6B,0xE4,0xFF,0xFE,0xFD,0x80,0x25, ++0xE4,0x7F,0x20,0x7E,0x4E,0xFD,0xFC,0x90, ++0x06,0x24,0x12,0x01,0x0F,0xC3,0x12,0x00, ++0xF2,0x50,0x1B,0x90,0x06,0x24,0x12,0x01, ++0x03,0xEF,0x24,0x01,0xFF,0xE4,0x3E,0xFE, ++0xE4,0x3D,0xFD,0xE4,0x3C,0xFC,0x90,0x06, ++0x24,0x12,0x01,0x1B,0x80,0xD2,0xC2,0x00, ++0xC2,0x01,0xD2,0xA9,0xD2,0x8C,0x7F,0x01, ++0x7E,0x62,0x12,0x04,0x47,0xEF,0x30,0xE2, ++0x07,0xE4,0x90,0x06,0x2C,0xF0,0x80,0xEE, ++0x90,0x06,0x2C,0xE0,0x70,0x12,0x12,0x02, ++0xDB,0x90,0x06,0x2C,0x74,0x01,0xF0,0xE4, ++0x90,0x06,0x2F,0xF0,0xA3,0xF0,0x80,0xD6, ++0xC3,0x90,0x06,0x30,0xE0,0x94,0x62,0x90, ++0x06,0x2F,0xE0,0x94,0x00,0x40,0xC7,0xE4, ++0xF0,0xA3,0xF0,0x12,0x02,0xDB,0x90,0x06, ++0x2C,0x74,0x01,0xF0,0x80,0xB8,0x75,0x0F, ++0x80,0x75,0x0E,0x7E,0x75,0x0D,0xAA,0x75, ++0x0C,0x83,0xE4,0xF5,0x10,0x7F,0x36,0x7E, ++0x13,0x12,0x04,0x47,0xEE,0xC4,0xF8,0x54, ++0xF0,0xC8,0xEF,0xC4,0x54,0x0F,0x48,0x54, ++0x07,0xFB,0x7A,0x00,0xEA,0x70,0x4A,0xEB, ++0x14,0x60,0x1C,0x14,0x60,0x27,0x24,0xFE, ++0x60,0x31,0x14,0x60,0x3C,0x24,0x05,0x70, ++0x38,0x75,0x0B,0x00,0x75,0x0A,0xC2,0x75, ++0x09,0xEB,0x75,0x08,0x0B,0x80,0x36,0x75, ++0x0B,0x40,0x75,0x0A,0x59,0x75,0x09,0x73, ++0x75,0x08,0x07,0x80,0x28,0x75,0x0B,0x00, ++0x75,0x0A,0xE1,0x75,0x09,0xF5,0x75,0x08, ++0x05,0x80,0x1A,0x75,0x0B,0xA0,0x75,0x0A, ++0xAC,0x75,0x09,0xB9,0x75,0x08,0x03,0x80, ++0x0C,0x75,0x0B,0x00,0x75,0x0A,0x62,0x75, ++0x09,0x3D,0x75,0x08,0x01,0x75,0x89,0x11, ++0xE4,0x7B,0x60,0x7A,0x09,0xF9,0xF8,0xAF, ++0x0B,0xAE,0x0A,0xAD,0x09,0xAC,0x08,0x12, ++0x00,0x60,0xAA,0x06,0xAB,0x07,0xC3,0xE4, ++0x9B,0xFB,0xE4,0x9A,0xFA,0x78,0x17,0xF6, ++0xAF,0x03,0xEF,0x08,0xF6,0x18,0xE6,0xF5, ++0x8C,0x08,0xE6,0xF5,0x8A,0x74,0x0D,0x2B, ++0xFB,0xE4,0x3A,0x18,0xF6,0xAF,0x03,0xEF, ++0x08,0xF6,0x75,0x88,0x10,0x53,0x8E,0xC7, ++0xD2,0xA9,0x22,0x7D,0x02,0x7C,0x00,0x7F, ++0x4A,0x7E,0x13,0x12,0x04,0x6B,0x7D,0x46, ++0x7C,0x71,0x7F,0x02,0x7E,0x66,0x12,0x04, ++0x6B,0x7D,0x03,0x7C,0x00,0x7F,0x01,0x7E, ++0x66,0x12,0x04,0x6B,0x7D,0xC0,0x7C,0x00, ++0x7F,0x00,0x7E,0x66,0x12,0x04,0x6B,0xE4, ++0xFF,0xFE,0x0F,0xBF,0x00,0x01,0x0E,0xEF, ++0x64,0x64,0x4E,0x70,0xF5,0x7D,0x04,0x7C, ++0x00,0x7F,0x02,0x7E,0x66,0x12,0x04,0x6B, ++0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E,0x66, ++0x12,0x04,0x6B,0x7D,0xC0,0x7C,0x00,0x7F, ++0x00,0x7E,0x66,0x12,0x04,0x6B,0xE4,0xFD, ++0xFC,0x7F,0x02,0x7E,0x66,0x12,0x04,0x6B, ++0x7D,0x00,0x7C,0x04,0x7F,0x01,0x7E,0x66, ++0x12,0x04,0x6B,0x7D,0xC0,0x7C,0x00,0x7F, ++0x00,0x7E,0x66,0x12,0x04,0x6B,0xE4,0xFD, ++0xFC,0x7F,0x4A,0x7E,0x13,0x12,0x04,0x6B, ++0x7D,0x06,0x7C,0x71,0x7F,0x02,0x7E,0x66, ++0x12,0x04,0x6B,0x7D,0x03,0x7C,0x00,0x7F, ++0x01,0x7E,0x66,0x12,0x04,0x6B,0x7D,0xC0, ++0x7C,0x00,0x7F,0x00,0x7E,0x66,0x02,0x04, ++0x6B,0x78,0x7F,0xE4,0xF6,0xD8,0xFD,0x75, ++0x81,0x3C,0x02,0x03,0xC8,0x02,0x01,0x27, ++0xE4,0x93,0xA3,0xF8,0xE4,0x93,0xA3,0x40, ++0x03,0xF6,0x80,0x01,0xF2,0x08,0xDF,0xF4, ++0x80,0x29,0xE4,0x93,0xA3,0xF8,0x54,0x07, ++0x24,0x0C,0xC8,0xC3,0x33,0xC4,0x54,0x0F, ++0x44,0x20,0xC8,0x83,0x40,0x04,0xF4,0x56, ++0x80,0x01,0x46,0xF6,0xDF,0xE4,0x80,0x0B, ++0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80, ++0x90,0x04,0x87,0xE4,0x7E,0x01,0x93,0x60, ++0xBC,0xA3,0xFF,0x54,0x3F,0x30,0xE5,0x09, ++0x54,0x1F,0xFE,0xE4,0x93,0xA3,0x60,0x01, ++0x0E,0xCF,0x54,0xC0,0x25,0xE0,0x60,0xA8, ++0x40,0xB8,0xE4,0x93,0xA3,0xFA,0xE4,0x93, ++0xA3,0xF8,0xE4,0x93,0xA3,0xC8,0xC5,0x82, ++0xC8,0xCA,0xC5,0x83,0xCA,0xF0,0xA3,0xC8, ++0xC5,0x82,0xC8,0xCA,0xC5,0x83,0xCA,0xDF, ++0xE9,0xDE,0xE7,0x80,0xBE,0xC0,0xE0,0xC0, ++0xF0,0xC0,0x83,0xC0,0x82,0xC0,0xD0,0x75, ++0xD0,0x00,0xC0,0x00,0x78,0x17,0xE6,0xF5, ++0x8C,0x78,0x18,0xE6,0xF5,0x8A,0x90,0x06, ++0x2D,0xE4,0x75,0xF0,0x01,0x12,0x00,0x0E, ++0x90,0x06,0x2F,0xE4,0x75,0xF0,0x01,0x12, ++0x00,0x0E,0xD0,0x00,0xD0,0xD0,0xD0,0x82, ++0xD0,0x83,0xD0,0xF0,0xD0,0xE0,0x32,0xC2, ++0xAF,0xAD,0x07,0xAC,0x06,0x8C,0xA2,0x8D, ++0xA3,0x75,0xA0,0x01,0x00,0x00,0x00,0x00, ++0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAE, ++0xA1,0xBE,0x00,0xF0,0xAE,0xA6,0xAF,0xA7, ++0xD2,0xAF,0x22,0xC2,0xAF,0xAB,0x07,0xAA, ++0x06,0x8A,0xA2,0x8B,0xA3,0x8C,0xA4,0x8D, ++0xA5,0x75,0xA0,0x03,0x00,0x00,0x00,0xAA, ++0xA1,0xBA,0x00,0xF8,0xD2,0xAF,0x22,0x42, ++0x06,0x2F,0x00,0x00,0x42,0x06,0x2D,0x00, ++0x00,0x00,0x12,0x04,0x9B,0x12,0x02,0x16, ++0x02,0x00,0x03,0xE4,0xF5,0x8E,0x22,}; ++ ++ ++/* Function Name: ++ * rtl8367c_setAsicPortUnknownDaBehavior ++ * Description: ++ * Set UNDA behavior ++ * Input: ++ * port - port ID ++ * behavior - 0: flooding to unknwon DA portmask; 1: drop; 2:trap; 3: flooding ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NOT_ALLOWED - Invalid behavior ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortUnknownDaBehavior(rtk_uint32 port, rtk_uint32 behavior) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ if(behavior >= L2_UNDA_BEHAVE_END) ++ return RT_ERR_NOT_ALLOWED; ++ ++ if(port < 8) ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE, RTL8367C_Port0_ACTION_MASK << (port * 2), behavior); ++ else ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE_EXT, RTL8367C_PORT8_ACTION_MASK << ((port-8) * 2), behavior); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortUnknownDaBehavior ++ * Description: ++ * Get UNDA behavior ++ * Input: ++ * port - port ID ++ * Output: ++ * pBehavior - 0: flooding to unknwon DA portmask; 1: drop; 2:trap; 3: flooding ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortUnknownDaBehavior(rtk_uint32 port, rtk_uint32 *pBehavior) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ if(port < 8) ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE, RTL8367C_Port0_ACTION_MASK << (port * 2), pBehavior); ++ else ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_UNKNOWN_UNICAST_DA_PORT_BEHAVE_EXT, RTL8367C_PORT8_ACTION_MASK << ((port-8) * 2), pBehavior); ++} ++/* Function Name: ++ * rtl8367c_setAsicPortUnknownSaBehavior ++ * Description: ++ * Set UNSA behavior ++ * Input: ++ * behavior - 0: flooding; 1: drop; 2:trap ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NOT_ALLOWED - Invalid behavior ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortUnknownSaBehavior(rtk_uint32 behavior) ++{ ++ if(behavior >= L2_BEHAVE_SA_END) ++ return RT_ERR_NOT_ALLOWED; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_PORT_SECURIT_CTRL_REG, RTL8367C_UNKNOWN_SA_BEHAVE_MASK, behavior); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortUnknownSaBehavior ++ * Description: ++ * Get UNSA behavior ++ * Input: ++ * pBehavior - 0: flooding; 1: drop; 2:trap ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortUnknownSaBehavior(rtk_uint32 *pBehavior) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_PORT_SECURIT_CTRL_REG, RTL8367C_UNKNOWN_SA_BEHAVE_MASK, pBehavior); ++} ++/* Function Name: ++ * rtl8367c_setAsicPortUnmatchedSaBehavior ++ * Description: ++ * Set Unmatched SA behavior ++ * Input: ++ * behavior - 0: flooding; 1: drop; 2:trap ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NOT_ALLOWED - Invalid behavior ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortUnmatchedSaBehavior(rtk_uint32 behavior) ++{ ++ if(behavior >= L2_BEHAVE_SA_END) ++ return RT_ERR_NOT_ALLOWED; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_PORT_SECURIT_CTRL_REG, RTL8367C_UNMATCHED_SA_BEHAVE_MASK, behavior); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortUnmatchedSaBehavior ++ * Description: ++ * Get Unmatched SA behavior ++ * Input: ++ * pBehavior - 0: flooding; 1: drop; 2:trap ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortUnmatchedSaBehavior(rtk_uint32 *pBehavior) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_PORT_SECURIT_CTRL_REG, RTL8367C_UNMATCHED_SA_BEHAVE_MASK, pBehavior); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicPortUnmatchedSaMoving ++ * Description: ++ * Set Unmatched SA moving state ++ * Input: ++ * port - Port ID ++ * enabled - 0: can't move to new port; 1: can move to new port ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Error Port ID ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortUnmatchedSaMoving(rtk_uint32 port, rtk_uint32 enabled) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_L2_SA_MOVING_FORBID, port, (enabled == 1) ? 0 : 1); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicPortUnmatchedSaMoving ++ * Description: ++ * Get Unmatched SA moving state ++ * Input: ++ * port - Port ID ++ * Output: ++ * pEnabled - 0: can't move to new port; 1: can move to new port ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Error Port ID ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortUnmatchedSaMoving(rtk_uint32 port, rtk_uint32 *pEnabled) ++{ ++ rtk_uint32 data; ++ ret_t retVal; ++ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_L2_SA_MOVING_FORBID, port, &data)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEnabled = (data == 1) ? 0 : 1; ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicPortUnknownDaFloodingPortmask ++ * Description: ++ * Set UNDA flooding portmask ++ * Input: ++ * portmask - portmask(0~0xFF) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_MASK - Invalid portmask ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortUnknownDaFloodingPortmask(rtk_uint32 portmask) ++{ ++ if(portmask > RTL8367C_PORTMASK) ++ return RT_ERR_PORT_MASK; ++ ++ return rtl8367c_setAsicReg(RTL8367C_UNUCAST_FLOADING_PMSK_REG, portmask); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortUnknownDaFloodingPortmask ++ * Description: ++ * Get UNDA flooding portmask ++ * Input: ++ * pPortmask - portmask(0~0xFF) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortUnknownDaFloodingPortmask(rtk_uint32 *pPortmask) ++{ ++ return rtl8367c_getAsicReg(RTL8367C_UNUCAST_FLOADING_PMSK_REG, pPortmask); ++} ++/* Function Name: ++ * rtl8367c_setAsicPortUnknownMulticastFloodingPortmask ++ * Description: ++ * Set UNMC flooding portmask ++ * Input: ++ * portmask - portmask(0~0xFF) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_MASK - Invalid portmask ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortUnknownMulticastFloodingPortmask(rtk_uint32 portmask) ++{ ++ if(portmask > RTL8367C_PORTMASK) ++ return RT_ERR_PORT_MASK; ++ ++ return rtl8367c_setAsicReg(RTL8367C_UNMCAST_FLOADING_PMSK_REG, portmask); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortUnknownMulticastFloodingPortmask ++ * Description: ++ * Get UNMC flooding portmask ++ * Input: ++ * pPortmask - portmask(0~0xFF) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortUnknownMulticastFloodingPortmask(rtk_uint32 *pPortmask) ++{ ++ return rtl8367c_getAsicReg(RTL8367C_UNMCAST_FLOADING_PMSK_REG, pPortmask); ++} ++/* Function Name: ++ * rtl8367c_setAsicPortBcastFloodingPortmask ++ * Description: ++ * Set Bcast flooding portmask ++ * Input: ++ * portmask - portmask(0~0xFF) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_MASK - Invalid portmask ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortBcastFloodingPortmask(rtk_uint32 portmask) ++{ ++ if(portmask > RTL8367C_PORTMASK) ++ return RT_ERR_PORT_MASK; ++ ++ return rtl8367c_setAsicReg(RTL8367C_BCAST_FLOADING_PMSK_REG, portmask); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortBcastFloodingPortmask ++ * Description: ++ * Get Bcast flooding portmask ++ * Input: ++ * pPortmask - portmask(0~0xFF) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortBcastFloodingPortmask(rtk_uint32 *pPortmask) ++{ ++ return rtl8367c_getAsicReg(RTL8367C_BCAST_FLOADING_PMSK_REG, pPortmask); ++} ++/* Function Name: ++ * rtl8367c_setAsicPortBlockSpa ++ * Description: ++ * Set disabling blocking frame if source port and destination port are the same ++ * Input: ++ * port - Physical port number (0~7) ++ * permit - 0: block; 1: permit ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortBlockSpa(rtk_uint32 port, rtk_uint32 permit) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_SOURCE_PORT_BLOCK_REG, port, permit); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortBlockSpa ++ * Description: ++ * Get disabling blocking frame if source port and destination port are the same ++ * Input: ++ * port - Physical port number (0~7) ++ * pPermit - 0: block; 1: permit ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortBlockSpa(rtk_uint32 port, rtk_uint32* pPermit) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_SOURCE_PORT_BLOCK_REG, port, pPermit); ++} ++/* Function Name: ++ * rtl8367c_setAsicPortDos ++ * Description: ++ * Set DOS function ++ * Input: ++ * type - DOS type ++ * drop - 0: permit; 1: drop ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - Invalid payload index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortDos(rtk_uint32 type, rtk_uint32 drop) ++{ ++ if(type >= DOS_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_DOS_CFG, RTL8367C_DROP_DAEQSA_OFFSET + type, drop); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortDos ++ * Description: ++ * Get DOS function ++ * Input: ++ * type - DOS type ++ * pDrop - 0: permit; 1: drop ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - Invalid payload index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortDos(rtk_uint32 type, rtk_uint32* pDrop) ++{ ++ if(type >= DOS_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_DOS_CFG, RTL8367C_DROP_DAEQSA_OFFSET + type,pDrop); ++} ++/* Function Name: ++ * rtl8367c_setAsicPortForceLink ++ * Description: ++ * Set port force linking configuration ++ * Input: ++ * port - Physical port number (0~7) ++ * pPortAbility - port ability configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortForceLink(rtk_uint32 port, rtl8367c_port_ability_t *pPortAbility) ++{ ++ rtk_uint32 regData = 0; ++ ++ /* Invalid input parameter */ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ regData |= pPortAbility->forcemode << 12; ++ regData |= pPortAbility->mstfault << 9; ++ regData |= pPortAbility->mstmode << 8; ++ regData |= pPortAbility->nway << 7; ++ regData |= pPortAbility->txpause << 6; ++ regData |= pPortAbility->rxpause << 5; ++ regData |= pPortAbility->link << 4; ++ regData |= pPortAbility->duplex << 2; ++ regData |= pPortAbility->speed; ++ ++ return rtl8367c_setAsicReg(RTL8367C_REG_MAC0_FORCE_SELECT+port, regData); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortForceLink ++ * Description: ++ * Get port force linking configuration ++ * Input: ++ * port - Physical port number (0~7) ++ * pPortAbility - port ability configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortForceLink(rtk_uint32 port, rtl8367c_port_ability_t *pPortAbility) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ /* Invalid input parameter */ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_MAC0_FORCE_SELECT + port, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pPortAbility->forcemode = (regData >> 12) & 0x0001; ++ pPortAbility->mstfault = (regData >> 9) & 0x0001; ++ pPortAbility->mstmode = (regData >> 8) & 0x0001; ++ pPortAbility->nway = (regData >> 7) & 0x0001; ++ pPortAbility->txpause = (regData >> 6) & 0x0001; ++ pPortAbility->rxpause = (regData >> 5) & 0x0001; ++ pPortAbility->link = (regData >> 4) & 0x0001; ++ pPortAbility->duplex = (regData >> 2) & 0x0001; ++ pPortAbility->speed = regData & 0x0003; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicPortStatus ++ * Description: ++ * Get port link status ++ * Input: ++ * port - Physical port number (0~7) ++ * pPortAbility - port ability configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortStatus(rtk_uint32 port, rtl8367c_port_status_t *pPortStatus) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ /* Invalid input parameter */ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_PORT0_STATUS+port,®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pPortStatus->lpi1000 = (regData >> 11) & 0x0001; ++ pPortStatus->lpi100 = (regData >> 10) & 0x0001; ++ pPortStatus->mstfault = (regData >> 9) & 0x0001; ++ pPortStatus->mstmode = (regData >> 8) & 0x0001; ++ pPortStatus->nway = (regData >> 7) & 0x0001; ++ pPortStatus->txpause = (regData >> 6) & 0x0001; ++ pPortStatus->rxpause = (regData >> 5) & 0x0001; ++ pPortStatus->link = (regData >> 4) & 0x0001; ++ pPortStatus->duplex = (regData >> 2) & 0x0001; ++ pPortStatus->speed = regData & 0x0003; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicPortForceLinkExt ++ * Description: ++ * Set external interface force linking configuration ++ * Input: ++ * id - external interface id (0~2) ++ * portAbility - port ability configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortForceLinkExt(rtk_uint32 id, rtl8367c_port_ability_t *pPortAbility) ++{ ++ rtk_uint32 retVal, regValue, regValue2, type, sgmiibit, hisgmiibit; ++ rtk_uint32 reg_data = 0; ++ rtk_uint32 i = 0; ++ ++ /* Invalid input parameter */ ++ if(id >= RTL8367C_EXTNO) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ reg_data |= pPortAbility->forcemode << 12; ++ reg_data |= pPortAbility->mstfault << 9; ++ reg_data |= pPortAbility->mstmode << 8; ++ reg_data |= pPortAbility->nway << 7; ++ reg_data |= pPortAbility->txpause << 6; ++ reg_data |= pPortAbility->rxpause << 5; ++ reg_data |= pPortAbility->link << 4; ++ reg_data |= pPortAbility->duplex << 2; ++ reg_data |= pPortAbility->speed; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) ++ return retVal; ++ /*get chip ID */ ++ if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) ++ return retVal; ++ ++ type = 0; ++ ++ switch (regValue) ++ { ++ case 0x0276: ++ case 0x0597: ++ case 0x6367: ++ type = 1; ++ break; ++ case 0x0652: ++ case 0x6368: ++ type = 2; ++ break; ++ case 0x0801: ++ case 0x6511: ++ type = 3; ++ break; ++ default: ++ return RT_ERR_FAILED; ++ } ++ ++ if (1 == type) ++ { ++ if(1 == id) ++ { ++ if ((retVal = rtl8367c_getAsicReg(RTL8367C_REG_REG_TO_ECO4, ®Value)) != RT_ERR_OK) ++ return retVal; ++ ++ if((regValue & (0x0001 << 5)) && (regValue & (0x0001 << 7))) ++ { ++ return RT_ERR_OK; ++ } ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ if(0 == id || 1 == id) ++ return rtl8367c_setAsicReg(RTL8367C_REG_DIGITAL_INTERFACE0_FORCE + id, reg_data); ++ else ++ return rtl8367c_setAsicReg(RTL8367C_REG_DIGITAL_INTERFACE2_FORCE, reg_data); ++ } ++ else if (2 == type) ++ { ++ if (1 == id) ++ { ++ if((retVal = rtl8367c_setAsicRegBit(0x1311, 2, pPortAbility->duplex)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, pPortAbility->speed)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, pPortAbility->link)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x1311, 6, pPortAbility->txpause)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x1311, 5, pPortAbility->rxpause)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x1311, 12, pPortAbility->forcemode)) != RT_ERR_OK) ++ return retVal; ++ ++ if (pPortAbility->link == 1) ++ { ++ if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 1)) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, 2)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (2 == id) ++ { ++ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 2, pPortAbility->duplex)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBits(0x13c4, 0x3, pPortAbility->speed)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, pPortAbility->link)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 6, pPortAbility->txpause)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 5, pPortAbility->rxpause)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 12, pPortAbility->forcemode)) != RT_ERR_OK) ++ return retVal; ++ ++ if (pPortAbility->link == 1) ++ { ++ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, 1)) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ if((retVal = rtl8367c_setAsicRegBits(0x13c4, 0x3, 2)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x1dc1, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBits(0x1dc1, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x1dc1, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x1dc1, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x1dc1, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ } ++ else if(3 == type) ++ { ++ if(1 == id) ++ { ++ if((retVal = rtl8367c_getAsicRegBit(0x1d11, 6, &sgmiibit)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicRegBit(0x1d11, 11, &hisgmiibit)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((sgmiibit == 1) || (hisgmiibit == 1)) ++ { ++ /*for 1000x/100fx/1000x_100fx, param has to be set to serdes registers*/ ++ if((retVal = rtl8367c_getAsicReg(0x1d41, ®Value)) != RT_ERR_OK) ++ return retVal; ++ ++ /*bit5: cfg_mac6_fib =1, bit7: cfg_mac6_fib2=1*/ ++ if((regValue & 0xa0) == 0xa0) ++ { ++ /* new_cfg_sds_mode */ ++ if((retVal = rtl8367c_getAsicRegBits(0x1d95, 0x1f00, ®Value2)) != RT_ERR_OK) ++ return retVal; ++ ++ /*1000X*/ ++ if(regValue2 == 0x4) ++ { ++#if 0 ++ /* new_cfg_sds_mode:reset mode */ ++ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) ++ return retVal; ++#endif ++ /* Enable new sds mode config */ ++ if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 0 bit 12 set 1, bit15~13 = 4*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFF0FFF; ++ reg_data |= 0x9000; ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 0 2 bit 6 set 1, bit13 set to 0, bit12 nway_en*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFFDFFF; ++ reg_data |= 0x40; ++ if(pPortAbility->forcemode) ++ reg_data &= 0xffffefff; ++ else ++ reg_data |= 0x1000; ++ ++ if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) ++ return retVal; ++ ++ if (pPortAbility->txpause) ++ reg_data |= 0x80; ++ else ++ reg_data &= (~0x80); ++ ++ if (pPortAbility->rxpause) ++ reg_data |= 0x100; ++ else ++ reg_data &= (~0x100); ++ ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 0 bit 12 set 0*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFFEFFF; ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /*new_cfg_sds_mode=1000x*/ ++ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x4)) != RT_ERR_OK) ++ return retVal; ++ ++ } ++ else if(regValue2 == 0x5) ++ { ++#if 0 ++ /*100FX*/ ++ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) ++ return retVal; ++#endif ++ /*cfg_sds_mode_sel_new=1 */ ++ if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 0 bit 12 set 1, bit15~13 = 5*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFF0FFF; ++ reg_data |= 0xB000; ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 0 2 bit 6 set 0, bit13 set to 1, bit12 0*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFFFFBF; ++ reg_data |= 0x2000; ++ reg_data &= 0xffffefff; ++ ++ if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) ++ return retVal; ++ if (pPortAbility->txpause) ++ reg_data |= 0x80; ++ else ++ reg_data &= (~0x80); ++ if (pPortAbility->rxpause) ++ reg_data |= 0x100; ++ else ++ reg_data &= (~0x100); ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 0 bit 12 set 0*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFFEFFF; ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ /* new_cfg_sds_mode=1000x */ ++ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x5)) != RT_ERR_OK) ++ return retVal; ++ ++ } ++ else if(regValue2 == 0x7) ++ { ++#if 0 ++ /*100FX*/ ++ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) ++ return retVal; ++#endif ++ if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 0 bit 12 set 1, bit15~13 = 4*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFF0FFF; ++ reg_data |= 0x9000; ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 0 2 bit 6 set 1, bit13 set to 0, bit12 nway_en*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFFDFFF; ++ reg_data |= 0x40; ++ if(pPortAbility->forcemode) ++ reg_data &= 0xffffefff; ++ else ++ reg_data |= 0x1000; ++ ++ if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) ++ return retVal; ++ if (pPortAbility->txpause) ++ reg_data |= 0x80; ++ else ++ reg_data &= (~0x80); ++ if (pPortAbility->rxpause) ++ reg_data |= 0x100; ++ else ++ reg_data &=(~0x100); ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 0 bit 12 set 0*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFFEFFF; ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 0 bit 12 set 1, bit15~13 = 5*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFF0FFF; ++ reg_data |= 0xB000; ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 0 2 bit 6 set 0, bit13 set to 1, bit12 0*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFFFFBF; ++ reg_data |= 0x2000; ++ reg_data &= 0xffffefff; ++ ++ if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) ++ return retVal; ++ if (pPortAbility->txpause) ++ reg_data |= 0x80; ++ else ++ reg_data &= 0xffffff7f; ++ if (pPortAbility->rxpause) ++ reg_data |= 0x100; ++ else ++ reg_data &= 0xfffffeff; ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 0 bit 12 set 0*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFFEFFF; ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ /*sds_mode:*/ ++ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x7)) != RT_ERR_OK) ++ return retVal; ++ ++ } ++ ++ /*disable force ability --- */ ++ if((retVal = rtl8367c_setAsicRegBit(0x137c, 12, 0)) != RT_ERR_OK) ++ return retVal; ++ return RT_ERR_OK; ++ ++ } ++ ++ /* new_cfg_sds_mode */ ++ if((retVal = rtl8367c_getAsicRegBits(0x1d95, 0x1f00, ®Value2)) != RT_ERR_OK) ++ return retVal; ++ if(regValue2 == 0x2) ++ { ++#if 0 ++ /*SGMII*/ ++ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) ++ return retVal; ++#endif ++ if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ for(i=0;i<0xfff; i++); ++ ++ /* 0 2 0 bit 8-9 nway*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xfffffcff; ++ if (pPortAbility->nway) ++ reg_data &= 0xfffffcff; ++ else ++ reg_data |= 0x100; ++ if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x2)) != RT_ERR_OK) ++ return retVal; ++ ++ for(i=0;i<0xfff; i++); ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) ++ return retVal; ++ ++ /*disable force ability --- */ ++ if((retVal = rtl8367c_setAsicRegBit(0x137c, 12, 0)) != RT_ERR_OK) ++ return retVal; ++ return RT_ERR_OK; ++ } ++ else if(regValue2 == 0x12) ++ { ++#if 0 ++ /*HiSGMII*/ ++ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) ++ return retVal; ++#endif ++ if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ for(i=0;i<0xfff; i++); ++ ++ /* 0 2 0 bit 8-9 nway*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xfffffcff; ++ if (pPortAbility->nway) ++ reg_data &= 0xfffffcff; ++ else ++ reg_data |= 0x100; ++ if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ ++ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x12)) != RT_ERR_OK) ++ return retVal; ++ ++ for(i=0;i<0xfff; i++); ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0x1)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) ++ return retVal; ++ ++ /*disable force ability --- */ ++ if((retVal = rtl8367c_setAsicRegBit(0x137c, 12, 0)) != RT_ERR_OK) ++ return retVal; ++ return RT_ERR_OK; ++ ++ } ++ } ++ else ++ { ++ if((retVal = rtl8367c_getAsicRegBits(0x1d3d, 10, ®Value2)) != RT_ERR_OK) ++ return retVal; ++ if (regValue2 == 0) ++ { ++ /*ext1_force_ablty*/ ++ if((retVal = rtl8367c_setAsicRegBit(0x1311, 2, pPortAbility->duplex)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, pPortAbility->speed)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, pPortAbility->link)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x1311, 6, pPortAbility->txpause)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x1311, 5, pPortAbility->rxpause)) != RT_ERR_OK) ++ return retVal; ++ ++ /*force mode for ext1*/ ++ if((retVal = rtl8367c_setAsicRegBit(0x1311, 12, pPortAbility->forcemode)) != RT_ERR_OK) ++ return retVal; ++ ++ if (pPortAbility->link == 1) ++ { ++ if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 1)) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, 2)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ /*disable force ability --- */ ++ if((retVal = rtl8367c_setAsicRegBit(0x137c, 12, 0)) != RT_ERR_OK) ++ return retVal; ++ return RT_ERR_OK; ++ } ++ } ++ ++ ++ } ++ else if (2 == id) ++ { ++ ++ if((retVal = rtl8367c_getAsicRegBit(0x1d95, 0, &sgmiibit)) != RT_ERR_OK) ++ return retVal; ++ if (sgmiibit == 1) ++ { ++ /*for 1000x/100fx/1000x_100fx, param has to bet set to serdes registers*/ ++ if((retVal = rtl8367c_getAsicReg(0x1d95, ®Value)) != RT_ERR_OK) ++ return retVal; ++ /*cfg_mac7_sel_sgmii=1 & cfg_mac7_fib =1*/ ++ if((regValue & 0x3) == 0x3) ++ { ++ if((retVal = rtl8367c_getAsicRegBits(0x1d95, 0x1f00, ®Value2)) != RT_ERR_OK) ++ return retVal; ++ ++ if(regValue2 == 0x4) ++ { ++ /*1000X*/ ++#if 0 ++ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) ++ return retVal; ++#endif ++ if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 0 bit 12 set 1, bit15~13 = 4*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFF0FFF; ++ reg_data |= 0x9000; ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 0 2 bit 6 set 1, bit13 set to 0, bit12 nway_en*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFFDFFF; ++ reg_data |= 0x40; ++ if(pPortAbility->forcemode) ++ reg_data &= 0xffffefff; ++ else ++ reg_data |= 0x1000; ++ ++ if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) ++ return retVal; ++ if (pPortAbility->txpause) ++ reg_data |= 0x80; ++ else ++ reg_data &= 0xffffff7f; ++ if (pPortAbility->rxpause) ++ reg_data |= 0x100; ++ else ++ reg_data &= 0xfffffeff; ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 0 bit 12 set 0*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFFEFFF; ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x4)) != RT_ERR_OK) ++ return retVal; ++ ++ } ++ else if(regValue2 == 0x5) ++ { ++ /*100FX*/ ++#if 0 ++ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) ++ return retVal; ++#endif ++ if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 0 bit 12 set 1, bit15~13 = 5*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFF0FFF; ++ reg_data |= 0xB000; ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 0 2 bit 6 set 0, bit13 set to 1, bit12 0*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFFFFBF; ++ reg_data |= 0x2000; ++ reg_data &= 0xffffefff; ++ ++ if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) ++ return retVal; ++ if (pPortAbility->txpause) ++ reg_data |= 0x80; ++ else ++ reg_data &= 0xffffff7f; ++ if (pPortAbility->rxpause) ++ reg_data |= 0x100; ++ else ++ reg_data &= 0xfffffeff; ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 0 bit 12 set 0*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFFEFFF; ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x5)) != RT_ERR_OK) ++ return retVal; ++ ++ } ++ else if(regValue2 == 0x7) ++ { ++ /*100FX*/ ++#if 0 ++ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) ++ return retVal; ++#endif ++ if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 0 bit 12 set 1, bit15~13 = 4*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFF0FFF; ++ reg_data |= 0x9000; ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 0 2 bit 6 set 1, bit13 set to 0, bit12 nway_en*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFFDFFF; ++ reg_data |= 0x40; ++ if(pPortAbility->forcemode) ++ reg_data &= 0xffffefff; ++ else ++ reg_data |= 0x1000; ++ ++ if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) ++ return retVal; ++ if (pPortAbility->txpause) ++ reg_data |= 0x80; ++ else ++ reg_data &= 0xffffff7f; ++ if (pPortAbility->rxpause) ++ reg_data |= 0x100; ++ else ++ reg_data &= 0xfffffeff; ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 0 bit 12 set 0*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFFEFFF; ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 0 bit 12 set 1, bit15~13 = 5*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFF0FFF; ++ reg_data |= 0xB000; ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 0 2 bit 6 set 0, bit13 set to 1, bit12 0*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFFFFBF; ++ reg_data |= 0x2000; ++ reg_data &= 0xffffefff; ++ ++ if((retVal = rtl8367c_setAsicSdsReg(0,0,2, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 2 bit 8 rx pause, bit7 tx pause*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 2, ®_data)) != RT_ERR_OK) ++ return retVal; ++ if (pPortAbility->txpause) ++ reg_data |= 0x80; ++ else ++ reg_data &= 0xffffff7f; ++ if (pPortAbility->rxpause) ++ reg_data |= 0x100; ++ else ++ reg_data &= 0xfffffeff; ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,2, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 4 0 bit 12 set 0*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFFEFFF; ++ if((retVal = rtl8367c_setAsicSdsReg(0,4,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x7)) != RT_ERR_OK) ++ return retVal; ++ ++ } ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x137d, 12, 0)) != RT_ERR_OK) ++ return retVal; ++ return RT_ERR_OK; ++ ++ } ++ /* new_cfg_sds_mode */ ++ if((retVal = rtl8367c_getAsicRegBits(0x1d95, 0x1f00, ®Value2)) != RT_ERR_OK) ++ return retVal; ++ if(regValue2 == 0x2) ++ { ++ /*SGMII*/ ++#if 0 ++ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) ++ return retVal; ++#endif ++ if((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ for(i=0;i<0xfff; i++); ++ ++ /* 0 2 0 bit 8-9 nway*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xfffffcff; ++ if (pPortAbility->nway) ++ reg_data &= 0xfffffcff; ++ else ++ reg_data |= 0x100; ++ if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x2)) != RT_ERR_OK) ++ return retVal; ++ ++ for(i=0;i<0xfff; i++); ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x137d, 12, 0)) != RT_ERR_OK) ++ return retVal; ++ return RT_ERR_OK; ++ } ++ } ++ else ++ { ++ ++ /*ext2_force_ablty*/ ++ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 2, pPortAbility->duplex)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBits(0x13c4, 0x3, pPortAbility->speed)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, pPortAbility->link)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 6, pPortAbility->txpause)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 5, pPortAbility->rxpause)) != RT_ERR_OK) ++ return retVal; ++ ++ /*force mode for ext2*/ ++ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 12, pPortAbility->forcemode)) != RT_ERR_OK) ++ return retVal; ++ ++ if (pPortAbility->link == 1) ++ { ++ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x13c4, 4, 1)) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ if((retVal = rtl8367c_setAsicRegBits(0x13c4, 0x3, 2)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ ++ if((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) ++ return retVal; ++ if(reg_data == 1) ++ { ++ if((retVal = rtl8367c_setAsicRegBit(0x1311, 2, pPortAbility->duplex)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, pPortAbility->speed)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, pPortAbility->link)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x1311, 6, pPortAbility->txpause)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x1311, 5, pPortAbility->rxpause)) != RT_ERR_OK) ++ return retVal; ++ ++ /*force mode for ext1*/ ++ if((retVal = rtl8367c_setAsicRegBit(0x1311, 12, pPortAbility->forcemode)) != RT_ERR_OK) ++ return retVal; ++ ++ if (pPortAbility->link == 1) ++ { ++ if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(0x1311, 4, 1)) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ if((retVal = rtl8367c_setAsicRegBits(0x1311, 0x3, 2)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ ++ ++ } ++ ++ /*disable force ability --- */ ++ if((retVal = rtl8367c_setAsicRegBit(0x137d, 12, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++#if 0 ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, pPortAbility->duplex)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, pPortAbility->speed)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, pPortAbility->txpause)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, pPortAbility->rxpause)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, pPortAbility->link)) != RT_ERR_OK) ++ return retVal; ++#endif ++ } ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicPortForceLinkExt ++ * Description: ++ * Get external interface force linking configuration ++ * Input: ++ * id - external interface id (0~1) ++ * pPortAbility - port ability configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortForceLinkExt(rtk_uint32 id, rtl8367c_port_ability_t *pPortAbility) ++{ ++ rtk_uint32 reg_data, regValue, type; ++ rtk_uint32 sgmiiSel; ++ rtk_uint32 hsgmiiSel; ++ ret_t retVal; ++ ++ /* Invalid input parameter */ ++ if(id >= RTL8367C_EXTNO) ++ return RT_ERR_OUT_OF_RANGE; ++ /*cfg_magic_id & get chip_id*/ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) ++ return retVal; ++ ++ type = 0; ++ ++ switch (regValue) ++ { ++ case 0x0276: ++ case 0x0597: ++ case 0x6367: ++ type = 1; ++ break; ++ case 0x0652: ++ case 0x6368: ++ type = 2; ++ break; ++ case 0x0801: ++ case 0x6511: ++ type = 3; ++ break; ++ default: ++ return RT_ERR_FAILED; ++ } ++ ++ if (1 == type) ++ { ++ if(1 == id) ++ { ++ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET, &sgmiiSel)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, &hsgmiiSel)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (sgmiiSel == 1) || (hsgmiiSel == 1) ) ++ { ++ memset(pPortAbility, 0x00, sizeof(rtl8367c_port_ability_t)); ++ pPortAbility->forcemode = 1; ++ ++ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_FDUP_OFFSET, ®_data)) != RT_ERR_OK) ++ return retVal; ++ ++ pPortAbility->duplex = reg_data; ++ ++ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_SPD_MASK, ®_data)) != RT_ERR_OK) ++ return retVal; ++ ++ pPortAbility->speed = reg_data; ++ ++ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_LINK_OFFSET, ®_data)) != RT_ERR_OK) ++ return retVal; ++ ++ pPortAbility->link = reg_data; ++ ++ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_TXFC_OFFSET, ®_data)) != RT_ERR_OK) ++ return retVal; ++ ++ pPortAbility->txpause = reg_data; ++ ++ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_SGMII_RXFC_OFFSET, ®_data)) != RT_ERR_OK) ++ return retVal; ++ ++ pPortAbility->rxpause = reg_data; ++ ++ return RT_ERR_OK; ++ } ++ } ++ ++ if(0 == id || 1 == id) ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_DIGITAL_INTERFACE0_FORCE+id, ®_data); ++ else ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_DIGITAL_INTERFACE2_FORCE, ®_data); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pPortAbility->forcemode = (reg_data >> 12) & 0x0001; ++ pPortAbility->mstfault = (reg_data >> 9) & 0x0001; ++ pPortAbility->mstmode = (reg_data >> 8) & 0x0001; ++ pPortAbility->nway = (reg_data >> 7) & 0x0001; ++ pPortAbility->txpause = (reg_data >> 6) & 0x0001; ++ pPortAbility->rxpause = (reg_data >> 5) & 0x0001; ++ pPortAbility->link = (reg_data >> 4) & 0x0001; ++ pPortAbility->duplex = (reg_data >> 2) & 0x0001; ++ pPortAbility->speed = reg_data & 0x0003; ++ } ++ else if (2 == type) ++ { ++ if (id == 1) ++ { ++ if ((retVal = rtl8367c_getAsicReg(0x1311, ®_data))!=RT_ERR_OK) ++ return retVal; ++ ++ pPortAbility->forcemode = (reg_data >> 12) & 1; ++ pPortAbility->duplex = (reg_data >> 2) & 1; ++ pPortAbility->link = (reg_data >> 4) & 1; ++ pPortAbility->speed = reg_data & 3; ++ pPortAbility->rxpause = (reg_data >> 5) & 1; ++ pPortAbility->txpause = (reg_data >> 6) & 1; ++ } ++ else if (2 == id) ++ { ++ if ((retVal = rtl8367c_getAsicReg(0x13c4, ®_data))!=RT_ERR_OK) ++ return retVal; ++ ++ pPortAbility->forcemode = (reg_data >> 12) & 1; ++ pPortAbility->duplex = (reg_data >> 2) & 1; ++ pPortAbility->link = (reg_data >> 4) & 1; ++ pPortAbility->speed = reg_data & 3; ++ pPortAbility->rxpause = (reg_data >> 5) & 1; ++ pPortAbility->txpause = (reg_data >> 6) & 1; ++ } ++ } ++ else if (3 == type) ++ { ++ if (id == 1) ++ { ++ if ((retVal = rtl8367c_getAsicReg(0x1311, ®_data))!=RT_ERR_OK) ++ return retVal; ++ ++ pPortAbility->forcemode = (reg_data >> 12) & 1; ++ pPortAbility->duplex = (reg_data >> 2) & 1; ++ pPortAbility->link = (reg_data >> 4) & 1; ++ pPortAbility->speed = reg_data & 3; ++ pPortAbility->rxpause = (reg_data >> 5) & 1; ++ pPortAbility->txpause = (reg_data >> 6) & 1; ++ } ++ else if (2 == id) ++ { ++ if ((retVal = rtl8367c_getAsicReg(0x13c4, ®_data))!=RT_ERR_OK) ++ return retVal; ++ ++ pPortAbility->forcemode = (reg_data >> 12) & 1; ++ pPortAbility->duplex = (reg_data >> 2) & 1; ++ pPortAbility->link = (reg_data >> 4) & 1; ++ pPortAbility->speed = reg_data & 3; ++ pPortAbility->rxpause = (reg_data >> 5) & 1; ++ pPortAbility->txpause = (reg_data >> 6) & 1; ++ } ++ } ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicPortExtMode ++ * Description: ++ * Set external interface mode configuration ++ * Input: ++ * id - external interface id (0~2) ++ * mode - external interface mode ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortExtMode(rtk_uint32 id, rtk_uint32 mode) ++{ ++ ret_t retVal; ++ rtk_uint32 i, regValue, type, option,reg_data; ++ rtk_uint32 idx; ++ rtk_uint32 redData[][2] = { {0x04D7, 0x0480}, {0xF994, 0x0481}, {0x21A2, 0x0482}, {0x6960, 0x0483}, {0x9728, 0x0484}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x83F2, 0x002E} }; ++ rtk_uint32 redDataSB[][2] = { {0x04D7, 0x0480}, {0xF994, 0x0481}, {0x31A2, 0x0482}, {0x6960, 0x0483}, {0x9728, 0x0484}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x83F2, 0x002E} }; ++ rtk_uint32 redData1[][2] = { {0x82F1, 0x0500}, {0xF195, 0x0501}, {0x31A2, 0x0502}, {0x796C, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; ++ rtk_uint32 redData5[][2] = { {0x82F1, 0x0500}, {0xF195, 0x0501}, {0x31A2, 0x0502}, {0x796C, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; ++ rtk_uint32 redData6[][2] = { {0x82F1, 0x0500}, {0xF195, 0x0501}, {0x31A2, 0x0502}, {0x796C, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; ++ rtk_uint32 redData8[][2] = { {0x82F1, 0x0500}, {0xF995, 0x0501}, {0x31A2, 0x0502}, {0x796C, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; ++ rtk_uint32 redData9[][2] = { {0x82F1, 0x0500}, {0xF995, 0x0501}, {0x31A2, 0x0502}, {0x796C, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; ++ rtk_uint32 redDataHB[][2] = { {0x82F0, 0x0500}, {0xF195, 0x0501}, {0x31A2, 0x0502}, {0x7960, 0x0503}, {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, {0x83F2, 0x002E} }; ++ ++ if(id >= RTL8367C_EXTNO) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(mode >= EXT_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ /* magic number*/ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) ++ return retVal; ++ /* Chip num */ ++ if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) ++ return retVal; ++ ++ type = 0; ++ ++ switch (regValue) ++ { ++ case 0x0276: ++ case 0x0597: ++ case 0x6367: ++ type = 1; ++ break; ++ case 0x0652: ++ case 0x6368: ++ type = 2; ++ break; ++ case 0x0801: ++ case 0x6511: ++ type = 3; ++ break; ++ default: ++ return RT_ERR_FAILED; ++ } ++ ++ ++ if (1==type) ++ { ++ if((mode == EXT_1000X_100FX) || (mode == EXT_1000X) || (mode == EXT_100FX)) ++ { ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_REG_TO_ECO4, 5, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_REG_TO_ECO4, 7, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MISCELLANEOUS_CONFIGURE0, RTL8367C_DW8051_EN_OFFSET, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if(mode == EXT_1000X_100FX) ++ { ++ for(idx = 0; idx < FIBER2_AUTO_INIT_SIZE; idx++) ++ { ++ if ((retVal = rtl8367c_setAsicReg(0xE000 + idx, (rtk_uint32)Fiber2_Auto[idx])) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ ++ if(mode == EXT_1000X) ++ { ++ for(idx = 0; idx < FIBER2_1G_INIT_SIZE; idx++) ++ { ++ if ((retVal = rtl8367c_setAsicReg(0xE000 + idx, (rtk_uint32)Fiber2_1G[idx])) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ ++ if(mode == EXT_100FX) ++ { ++ for(idx = 0; idx < FIBER2_100M_INIT_SIZE; idx++) ++ { ++ if ((retVal = rtl8367c_setAsicReg(0xE000 + idx, (rtk_uint32)Fiber2_100M[idx])) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ if(mode == EXT_GMII) ++ { ++ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_EXT0_RGMXF, RTL8367C_EXT0_RGTX_INV_OFFSET, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_EXT1_RGMXF, RTL8367C_EXT1_RGTX_INV_OFFSET, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_EXT_TXC_DLY, RTL8367C_EXT1_GMII_TX_DELAY_MASK, 5)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_EXT_TXC_DLY, RTL8367C_EXT0_GMII_TX_DELAY_MASK, 6)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ /* Serdes reset */ ++ if( (mode == EXT_TMII_MAC) || (mode == EXT_TMII_PHY) ) ++ { ++ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_BYPASS_LINE_RATE, id, 1)) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_BYPASS_LINE_RATE, id, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ if( (mode == EXT_SGMII) || (mode == EXT_HSGMII) ) ++ { ++ if(id != 1) ++ return RT_ERR_PORT_ID; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C0, 0x0249)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicReg(0x13C1, &option)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C0, 0x0000)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ if(mode == EXT_SGMII) ++ { ++ if(option == 0) ++ { ++ for(i = 0; i <= 7; i++) ++ { ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData[i][0])) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData[i][1])) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ else ++ { ++ for(i = 0; i <= 7; i++) ++ { ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redDataSB[i][0])) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redDataSB[i][1])) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ } ++ ++ if(mode == EXT_HSGMII) ++ { ++ if(option == 0) ++ { ++ if( (retVal = rtl8367c_setAsicReg(0x13c2, 0x0249)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_getAsicReg(0x1301, ®Value)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(0x13c2, 0x0000)) != RT_ERR_OK) ++ return retVal; ++ ++ if ( ((regValue & 0x00F0) >> 4) == 0x0001) ++ { ++ for(i = 0; i <= 8; i++) ++ { ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData1[i][0])) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData1[i][1])) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ else if ( ((regValue & 0x00F0) >> 4) == 0x0005) ++ { ++ for(i = 0; i <= 8; i++) ++ { ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData5[i][0])) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData5[i][1])) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ else if ( ((regValue & 0x00F0) >> 4) == 0x0006) ++ { ++ for(i = 0; i <= 8; i++) ++ { ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData6[i][0])) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData6[i][1])) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ else if ( ((regValue & 0x00F0) >> 4) == 0x0008) ++ { ++ for(i = 0; i <= 8; i++) ++ { ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData8[i][0])) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData8[i][1])) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ else if ( ((regValue & 0x00F0) >> 4) == 0x0009) ++ { ++ for(i = 0; i <= 8; i++) ++ { ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redData9[i][0])) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redData9[i][1])) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ } ++ else ++ { ++ for(i = 0; i <= 8; i++) ++ { ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, redDataHB[i][0])) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, redDataHB[i][1])) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ } ++ ++ /* Only one ext port should care SGMII setting */ ++ if(id == 1) ++ { ++ ++ if(mode == EXT_SGMII) ++ { ++ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if(mode == EXT_HSGMII) ++ { ++ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, 1)) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ ++ if((mode != EXT_1000X_100FX) && (mode != EXT_1000X) && (mode != EXT_100FX)) ++ { ++ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ } ++ ++ if(0 == id || 1 == id) ++ { ++ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_DIGITAL_INTERFACE_SELECT, RTL8367C_SELECT_GMII_0_MASK << (id * RTL8367C_SELECT_GMII_1_OFFSET), mode)) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_DIGITAL_INTERFACE_SELECT_1, RTL8367C_SELECT_GMII_2_MASK, mode)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ /* Serdes not reset */ ++ if( (mode == EXT_SGMII) || (mode == EXT_HSGMII) ) ++ { ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x7106)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, 0x0003)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ if( (mode == EXT_SGMII) || (mode == EXT_HSGMII) ) ++ { ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_MISCELLANEOUS_CONFIGURE0, RTL8367C_DW8051_EN_OFFSET, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ for(idx = 0; idx < SGMII_INIT_SIZE; idx++) ++ { ++ if ((retVal = rtl8367c_setAsicReg(0xE000 + idx, (rtk_uint32)Sgmii_Init[idx])) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_IROM_MSB_OFFSET, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_DW8051_RDY, RTL8367C_ACS_IROM_ENABLE_OFFSET, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_CHIP_RESET, RTL8367C_DW8051_RST_OFFSET, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ else if (2 == type) ++ { ++ /* Serdes reset */ ++ if( (mode == EXT_TMII_MAC) || (mode == EXT_TMII_PHY) ) ++ { ++ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_BYPASS_LINE_RATE, id+2, 1)) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ if( (retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_BYPASS_LINE_RATE, id+2, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ /*set MAC mode*/ ++ if (id == 1) ++ { ++ if(mode == EXT_HSGMII) ++ return RT_ERR_PORT_ID; ++ ++ if (mode == EXT_SGMII) ++ { ++ /*cfg port8 with MII mac mode*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*enable port8 SGMII*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 14, 1)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (mode == EXT_1000X || mode == EXT_100FX || mode == EXT_1000X_100FX) ++ { ++ /*cfg port8 with MII mac mode*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*disable port8 SGMII*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 14, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*set fiber link up*/ ++ if((retVal = rtl8367c_setAsicRegBit(0x6210, 11, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ /*cfg port8 with MII mac mode*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, mode)) != RT_ERR_OK) ++ return retVal; ++ ++ /*disable port8 SGMII*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 14, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ /*disable SDS 1*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 0x1f)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if(id == 2) ++ { ++ if (mode == EXT_HSGMII) ++ { ++ if ((retVal = rtl8367c_setAsicReg(0x130, 7)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(0x39f, 7)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(0x3fa, 7)) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ if ((retVal = rtl8367c_setAsicReg(0x130, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(0x39f, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(0x3fa, 4)) != RT_ERR_OK) ++ return retVal; ++ ++ } ++ ++ ++ if (mode == EXT_SGMII) ++ { ++ /*cfg port9 with MII mac mode*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*enable port9 SGMII*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 6, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /*disable port9 HSGMII*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 7, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (mode == EXT_HSGMII) ++ { ++ /*cfg port9 with MII mac mode*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*disable port9 SGMII*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 6, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*enable port9 HSGMII*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 7, 1)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (mode == EXT_1000X || mode == EXT_100FX || mode == EXT_1000X_100FX) ++ { ++ /*cfg port9 with MII mac mode*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*disable port9 SGMII*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 6, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*disable port9 HSGMII*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 7, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*set fiber link up*/ ++ if((retVal = rtl8367c_setAsicRegBit(0x6200, 11, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ /*cfg port9 with MII mac mode*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, mode)) != RT_ERR_OK) ++ return retVal; ++ ++ /*disable port9 SGMII*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 6, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*disable port9 HSGMII*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d92, 7, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ /*disable SDS 0*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 0x1f)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ /*SET TO RGMII MODE*/ ++ if (mode == EXT_RGMII) ++ { ++ /*disable paral led pad*/ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PARA_LED_IO_EN3, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PARA_LED_IO_EN1, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(RTL8367C_REG_PARA_LED_IO_EN2, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*set MAC8 mode*/ ++ if (id == 1) ++ { ++ /*1: RGMII1 bias work at 3.3V, 0: RGMII1 bias work at 2.5V*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1303, 9, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /*drving 1*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1303, 6, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /*drving 1*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1303, 4, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /*show rate = 0*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1303, 1, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*EXT1 RGMII TXC delay 2ns*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1307, 3, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_Ext1_rgtxc_dly = 0*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x38, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*RXDLY = 0*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1307, 0x7, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_rg1_dn = 4*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1304, 0x7000, 4)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_rg1_dp = 4*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x700, 4)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (id == 2) ++ { ++ /*1: RGMII1 bias work at 3.3V, 0: RGMII1 bias work at 2.5V*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1303, 10, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /*drving 1*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x13e2, 2, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /*drving 1*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x13e2, 1, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /*show rate = 0*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x13e2, 0, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*EXT1 RGMII TXC delay 2ns*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x13c5, 3, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_Ext1_rgtxc_dly = 0*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x13f9, 0x1c0, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*RXDLY = 0*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x13c5, 0x7, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_rg1_dn = 4*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x13e2, 0x1c0, 4)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_rg1_dp = 4*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x13e2, 0x38, 4)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ else if (mode == EXT_SGMII) ++ { ++ if (id == 1) ++ { ++ /*sds 1 reg 1 page 0x21 write value 0xec91*/ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0xec91)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x21<<5) | 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C1)) != RT_ERR_OK) ++ return retVal; ++ ++ /*sds 1 reg 5 page 0x24 write value 0x5825*/ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x5825)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x24<<5) | 5)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C1)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 2)) != RT_ERR_OK) ++ return retVal; ++ ++ /*?????????????????*/ ++ ++ } ++ else if (id == 2) ++ { ++ /*sds 0 reg 0 page 0x28 write value 0x942c*/ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x942c)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x28<<5) | 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*sds 0 reg 0 page 0x24 write value 0x942c*/ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x942c)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x24<<5) | 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*sds 0 reg 5 page 0x21 write value 0x8dc3*/ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x8dc3)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x21<<5) | 5)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 2)) != RT_ERR_OK) ++ return retVal; ++ ++ /*?????????????????*/ ++ } ++ } ++ else if (mode == EXT_HSGMII) ++ { ++ if (id == 2) ++ { ++ /*sds 0 reg 0 page 0x28 write value 0x942c*/ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x942c)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x28<<5) | 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*sds 0 reg 0 page 0x24 write value 0x942c*/ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x942c)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x24<<5) | 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*sds 0 reg 5 page 0x21 write value 0x8dc3*/ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x8dc3)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x21<<5) | 5)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) ++ return retVal; ++ ++ ++ /* optimizing HISGMII performance while RGMII used & */ ++ /*sds 0 reg 9 page 0x21 write value 0x3931*/ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_DATA, 0x3931)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_ADR, (0x21<<5)|9) ) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_setAsicReg(RTL8367C_REG_SDS_INDACS_CMD, 0x00C0)) != RT_ERR_OK) ++ return retVal; ++ ++ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 0x12)) != RT_ERR_OK) ++ return retVal; ++ ++ /*?????????????????*/ ++ } ++ } ++ else if (mode == EXT_1000X) ++ { ++ if (id == 1) ++ { ++ ++ if( (retVal = rtl8367c_setAsicSdsReg(1, 1, 0x21, 0xec91)) != RT_ERR_OK) ++ return retVal; ++ if( (retVal = rtl8367c_setAsicSdsReg(1, 5, 0x24, 0x5825)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 4)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 0x1f)) != RT_ERR_OK) ++ return retVal; ++ ++ /*patch speed change sds1 1000M*/ ++ if( (retVal = rtl8367c_getAsicSdsReg(1, 4, 0, ®Value)) != RT_ERR_OK) ++ return retVal; ++ regValue &= 0xFFFF0FFF; ++ regValue |= 0x9000; ++ if( (retVal = rtl8367c_setAsicSdsReg(1, 4, 0, regValue)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_getAsicSdsReg(1, 0, 2, ®Value)) != RT_ERR_OK) ++ return retVal; ++ regValue &= 0xFFFFdFFF; ++ regValue |= 0x40; ++ if( (retVal = rtl8367c_setAsicSdsReg(1, 0, 2, regValue)) != RT_ERR_OK) ++ return retVal; ++ ++ ++ if( (retVal = rtl8367c_getAsicSdsReg(1, 4, 0, ®Value)) != RT_ERR_OK) ++ return retVal; ++ regValue &= 0xFFFFEFFF; ++ if( (retVal = rtl8367c_setAsicSdsReg(1, 4, 0, regValue)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 4)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x6000, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ } ++ else if (id == 2) ++ { ++ if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x28, 0x942c)) != RT_ERR_OK) ++ return retVal; ++ if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x24, 0x942c)) != RT_ERR_OK) ++ return retVal; ++ if( (retVal = rtl8367c_setAsicSdsReg(0, 5, 0x21, 0x8dc3)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 4)) != RT_ERR_OK) ++ return retVal; ++ ++ /*patch speed change sds0 1000M*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 0x1f)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Value)) != RT_ERR_OK) ++ return retVal; ++ regValue &= 0xFFFF0FFF; ++ regValue |= 0x9000; ++ if( (retVal = rtl8367c_setAsicSdsReg(0, 4, 0, regValue)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®Value)) != RT_ERR_OK) ++ return retVal; ++ regValue &= 0xFFFFDFFF; ++ regValue |= 0x40; ++ if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 2, regValue)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Value)) != RT_ERR_OK) ++ return retVal; ++ regValue &= 0xFFFFEFFF; ++ if( (retVal = rtl8367c_setAsicSdsReg(0, 4, 0, regValue)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 4)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0xe0, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ } ++ } ++ else if (mode == EXT_100FX) ++ { ++ if (id == 1) ++ { ++ if( (retVal = rtl8367c_setAsicSdsReg(1, 1, 0x21, 0xec91)) != RT_ERR_OK) ++ return retVal; ++ if( (retVal = rtl8367c_setAsicSdsReg(1, 5, 0x24, 0x5825)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 5)) != RT_ERR_OK) ++ return retVal; ++ ++ /*patch speed change sds1 100M*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 0x1f)) != RT_ERR_OK) ++ return retVal; ++ if( (retVal = rtl8367c_getAsicSdsReg(1, 4, 0, ®Value)) != RT_ERR_OK) ++ return retVal; ++ regValue &= 0xFFFF0FFF; ++ regValue |= 0xb000; ++ if( (retVal = rtl8367c_setAsicSdsReg(1, 4, 0, regValue)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_getAsicSdsReg(1, 0, 2, ®Value)) != RT_ERR_OK) ++ return retVal; ++ regValue &= 0xFFFFFFBF; ++ regValue |= 0x2000; ++ if( (retVal = rtl8367c_setAsicSdsReg(1, 0, 2, regValue)) != RT_ERR_OK) ++ return retVal; ++#if 0 ++ if( (retVal = rtl8367c_setAsicReg(0x6214, 0x1a0)) != RT_ERR_OK) ++ return retVal; ++#endif ++ if( (retVal = rtl8367c_getAsicSdsReg(1, 4, 0, ®Value)) != RT_ERR_OK) ++ return retVal; ++ regValue &= 0xFFFFEFFF; ++ if( (retVal = rtl8367c_setAsicSdsReg(1, 4, 0, regValue)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 5)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x6000, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (id == 2) ++ { ++ if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x28, 0x942c)) != RT_ERR_OK) ++ return retVal; ++ if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x24, 0x942c)) != RT_ERR_OK) ++ return retVal; ++ if( (retVal = rtl8367c_setAsicSdsReg(0, 5, 0x21, 0x8dc3)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 5)) != RT_ERR_OK) ++ return retVal; ++ ++ /*patch speed change sds0 100M*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 0x1f)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Value)) != RT_ERR_OK) ++ return retVal; ++ regValue &= 0xFFFF0FFF; ++ regValue |= 0xb000; ++ if( (retVal = rtl8367c_setAsicSdsReg(0, 4, 0, regValue)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_getAsicSdsReg(0, 0, 2, ®Value)) != RT_ERR_OK) ++ return retVal; ++ regValue &= 0xFFFFFFBF; ++ regValue |= 0x2000; ++ if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 2, regValue)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (retVal = rtl8367c_getAsicSdsReg(0, 4, 0, ®Value)) != RT_ERR_OK) ++ return retVal; ++ regValue &= 0xFFFFEFFF; ++ if( (retVal = rtl8367c_setAsicSdsReg(0, 4, 0, regValue)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 5)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0xe0, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ else if (mode == EXT_1000X_100FX) ++ { ++ if (id == 1) ++ { ++ if( (retVal = rtl8367c_setAsicSdsReg(1, 1, 0x21, 0xec91)) != RT_ERR_OK) ++ return retVal; ++ if( (retVal = rtl8367c_setAsicSdsReg(1, 5, 0x24, 0x5825)) != RT_ERR_OK) ++ return retVal; ++ if( (retVal = rtl8367c_setAsicSdsReg(1, 13, 0, 0x4616)) != RT_ERR_OK) ++ return retVal; ++ if( (retVal = rtl8367c_setAsicSdsReg(1, 1, 0, 0xf20)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f00, 7)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (id == 2) ++ { ++ if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x28, 0x942c)) != RT_ERR_OK) ++ return retVal; ++ if( (retVal = rtl8367c_setAsicSdsReg(0, 0, 0x24, 0x942c)) != RT_ERR_OK) ++ return retVal; ++ if( (retVal = rtl8367c_setAsicSdsReg(0, 5, 0x21, 0x8dc3)) != RT_ERR_OK) ++ return retVal; ++ if( (retVal = rtl8367c_setAsicSdsReg(0, 13, 0, 0x4616)) != RT_ERR_OK) ++ return retVal; ++ if( (retVal = rtl8367c_setAsicSdsReg(0, 1, 0, 0xf20)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d92, 0x1f, 7)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ ++ } ++ else if (3 == type) ++ { ++ ++ /*restore patch, by designer. patch Tx FIFO issue, when not HSGMII 2.5G mode ++ #sds0, page 1, reg 1, bit4=0*/ ++ if( (retVal = rtl8367c_getAsicSdsReg(0, 1, 1, ®Value)) != RT_ERR_OK) ++ return retVal; ++ regValue &= 0xFFFFFFEF; ++ if( (retVal = rtl8367c_setAsicSdsReg(0, 1, 1, regValue)) != RT_ERR_OK) ++ return retVal; ++ ++ /*set for mac 6*/ ++ if (1 == id) ++ { ++ /*force port6 linkdown*/ ++ if ((retVal = rtl8367c_setAsicReg(0x137c, 0x1000)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicRegBit(0x1d9d, 6, ®_data)) != RT_ERR_OK) ++ return retVal; ++ while(reg_data == 0) ++ { ++ if ((retVal = rtl8367c_getAsicRegBit(0x1d9d, 6, ®_data)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ if (mode == EXT_SGMII) ++ { ++ /* disable mac6 mode_ext1 mode*/ ++ if ((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) ++ return retVal; ++ if(reg_data == 0) ++ { ++ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ /*cfg_bypass_line_rate[1]=0*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ ++ ++ /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_mac7_fib=0*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 1, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_mac7_sel_sgmii= 0: MAC7 is not SGMII mode*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 0, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*#cfg_sgmii_link=0*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 9, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_mac6_sel_hsgmii=0*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ ++ /*bit13: cfg_sds_mode_sel_new=1 :Enable new sds mode config method*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 ++ new_cfg_sds_mode=0x1F (reset mode) */ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_mac6_sel_sgmii= 1*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 ++ new_cfg_sds_mode=0x12 */ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x2)) != RT_ERR_OK) ++ return retVal; ++ ++ /* MAC link source*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 2, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ ++ } ++ else if (mode == EXT_HSGMII) ++ { ++ ++ /*restore patch, by designer. patch Tx FIFO issue, when HSGMII 2.5G mode ++ #sds0, page 1, reg 1, bit4=1*/ ++ if( (retVal = rtl8367c_getAsicSdsReg(0, 1, 1, ®Value)) != RT_ERR_OK) ++ return retVal; ++ regValue |= 0x10; ++ if( (retVal = rtl8367c_setAsicSdsReg(0, 1, 1, regValue)) != RT_ERR_OK) ++ return retVal; ++ ++ /* mode_ext1 = disable*/ ++ /* disable mac6 mode_ext1 mode*/ ++ if ((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) ++ return retVal; ++ if(reg_data == 0) ++ { ++ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_mac7_fib=0*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 1, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_mac7_sel_sgmii= 0*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 0, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_mac6_sel_sgmii=0*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 9, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_mac6_sel_hsgmii=1*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_mac6_sel_sgmii= 0*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(0xd0,7)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicReg(0x399, 7)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicReg(0x3fa, 7)) != RT_ERR_OK) ++ return retVal; ++ ++ /*bit13: cfg_sds_mode_sel_new=1 :Enable new sds mode config method*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) ++ return retVal; ++ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 ++ new_cfg_sds_mode=0x12 */ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x12)) != RT_ERR_OK) ++ return retVal; ++ /* ++ 1: MAC link = SGMII SerDes link ++ 0: MAC link = SGMII config link £¨cfg_sgmii_link£© ++ */ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 2, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ } ++ else if(mode == EXT_1000X) ++ { ++ /* 0 2 0 bit 8~9 set 0, force n-way*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFFFCFF; ++ if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* disable mac6 mode_ext1 mode*/ ++ if ((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) ++ return retVal; ++ if(reg_data == 0) ++ { ++ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) ++ return retVal; ++ ++ /*bit13: cfg_sds_mode_sel_new=1 :Enable new sds mode config method ++ bit[1:0]:cfg_mac7_fib= 0 & cfg_mac7_sel_sgmii=0 ++ */ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /* bit0 :UTP/Fiber auto detect function enable or not, cfg_dis_det=1:disable ++ bit3:Force UTP/Fiber auto detect function enable or not, cfg_force_auto-detect=1 */ ++ if ((retVal = rtl8367c_setAsicReg(0x13eb, 0x15bb)) != RT_ERR_OK) ++ return retVal; ++ ++ /*bit3: Serdes force mode:cfg_sds_frc_mode=1 ++ bit[2:0]: Serdes chip mode, cfg_sds_mode=3b'100 (force sds FIB1G mode) */ ++ if ((retVal = rtl8367c_setAsicReg(0x13e7, 0xc)) != RT_ERR_OK) ++ return retVal; ++ ++ ++ /*bit5: cfg_mac6_fib=1 & bit7: cfg_mac6_fib2=1*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 1)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_mac6_sel_hsgmii=0*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_mac6_sel_sgmii= 1*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 ++ new_cfg_sds_mode=0x4 */ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x4)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if(mode == EXT_100FX) ++ { ++ /* 0 2 0 bit 8~9 set 0, force n-way*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFFFCFF; ++ if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* disable mac6 mode_ext1 mode*/ ++ if ((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) ++ return retVal; ++ if(reg_data == 0) ++ { ++ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) ++ return retVal; ++ ++ /*bit13: cfg_sds_mode_sel_new=1 :Enable new sds mode config method ++ bit[1:0]:cfg_mac7_fib= 0 & cfg_mac7_sel_sgmii=0 ++ */ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /* bit0 :UTP/Fiber auto detect function enable or not, cfg_dis_det=1:disable ++ bit3:Force UTP/Fiber auto detect function enable or not, cfg_force_auto-detect=1 */ ++ if ((retVal = rtl8367c_setAsicReg(0x13eb, 0x15bb)) != RT_ERR_OK) ++ return retVal; ++ ++ /*!!!!! cfg_sds_frc_mode=1 & cfg_sds_mode=3b'101 (force sds fib100M mode)*/ ++ if ((retVal = rtl8367c_setAsicReg(0x13e7, 0xc)) != RT_ERR_OK) ++ return retVal; ++ ++ ++ /*bit5: cfg_mac6_fib=1 & bit7: cfg_mac6_fib2=1*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 1)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_mac6_sel_hsgmii=0*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_mac6_sel_sgmii= 1*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 ++ new_cfg_sds_mode=0x5 */ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x5)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if(mode == EXT_1000X_100FX) ++ { ++ /* 0 2 0 bit 8~9 set 0, force n-way*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFFFCFF; ++ if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /* disable mac6 mode_ext1 mode*/ ++ if ((retVal = rtl8367c_getAsicRegBit(0x1d3d, 10, ®_data)) != RT_ERR_OK) ++ return retVal; ++ if(reg_data == 0) ++ { ++ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) ++ return retVal; ++ ++ /*bit13: cfg_sds_mode_sel_new=1 :Enable new sds mode config method ++ bit[1:0]:cfg_mac7_fib= 0 & cfg_mac7_sel_sgmii=0 ++ */ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 0)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /* bit0 :UTP/Fiber auto detect function enable or not, cfg_dis_det=1:disable ++ bit3:Force UTP/Fiber auto detect function enable or not, cfg_force_auto-detect=1 */ ++ if ((retVal = rtl8367c_setAsicReg(0x13eb, 0x15bb)) != RT_ERR_OK) ++ return retVal; ++ ++ /*!!!!!! cfg_sds_frc_mode=1 & cfg_sds_mode=3'b111: Fib1G/Fib100M auto detect */ ++ if ((retVal = rtl8367c_setAsicReg(0x13e7, 0xc)) != RT_ERR_OK) ++ return retVal; ++ ++ ++ /*bit5: cfg_mac6_fib=1 & bit7: cfg_mac6_fib2=1*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 1)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_mac6_sel_hsgmii=0*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_mac6_sel_sgmii= 1*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 ++ new_cfg_sds_mode=0x7 */ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x7)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if(mode < EXT_SGMII) ++ { ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d3d, 10, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /* keep default setting, disable mac6 sel SerDes mode,*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if (mode < EXT_GMII) ++ { ++ /* set mac6 mode*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, mode)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if(mode == EXT_RMII_MAC) ++ { ++ /*!!!!!!*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 7)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if(mode == EXT_RMII_PHY) ++ { ++ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, 8)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ if ((mode == EXT_TMII_MAC) || (mode == EXT_TMII_PHY)) ++ { ++ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 1, 1)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ ++ } ++ else if (2 == id) ++ { ++ ++ /*force port7 linkdown*/ ++ if ((retVal = rtl8367c_setAsicReg(0x137d, 0x1000)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicRegBit(0x1d9d, 7, ®_data)) != RT_ERR_OK) ++ return retVal; ++ while(reg_data == 0) ++ { ++ if ((retVal = rtl8367c_getAsicRegBit(0x1d9d, 7, ®_data)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ if (mode == EXT_SGMII) ++ { ++ /*disable mac7 sel ext2 xMII mode*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf,0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*restore ext2 ability*/ ++ if ((retVal = rtl8367c_setAsicReg(0x13c4, 0)) != RT_ERR_OK) ++ return retVal; ++ /* disable mac7 mode_ext2 */ ++ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /* ++ bit0:cfg_mac7_sel_sgmii=0,MAC7 is not SGMII mode ++ bit1:cfg_mac7_fib= 0 */ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_mac6_sel_hsgmii=0*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 11, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_mac6_sel_sgmii= 1*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*Enable new sds mode config method, cfg_sds_mode_sel_new=1*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 ++ new_cfg_sds_mode=0x1F (reset mode) */ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_mac7_sel_sgmii= 1*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 0, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 ++ new_cfg_sds_mode=0x2 (SGMII mode)*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x2)) != RT_ERR_OK) ++ return retVal; ++ ++ /*select MAC link source when port6/7 be set sgmii mode £¨cfg_sgmii_link£©*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 2, 0)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (mode == EXT_1000X) ++ { ++ /* disable mac7 MII/TMM/RMII/GMII/RGMII mode, mode_ext2 = disable */ ++ if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*restore ext2 ability*/ ++ if ((retVal = rtl8367c_setAsicReg(0x13c4, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 2 0 bit 8~9 set 0, force n-way*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFFFCFF; ++ if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /*restore ext2 ability*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /* keep default setting, disable mac6 sel serdes*/ ++ if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) ++ return retVal; ++ ++ /*Enable new sds mode config method, cfg_sds_mode_sel_new=1*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 ++ new_cfg_sds_mode=0x1F (reset mode) */ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) ++ return retVal; ++ ++ /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_mac7_sel_sgmii= 1 & cfg_mac7_fib=1*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 3)) != RT_ERR_OK) ++ return retVal; ++ ++ /*new_cfg_sds_mode=0x4 (FIB1000 mode)*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x4)) != RT_ERR_OK) ++ return retVal; ++ ++ } ++ else if (mode == EXT_100FX) ++ { ++ /* disable mac7 MII/TMM/RMII/GMII/RGMII mode, mode_ext2 = disable */ ++ if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*restore ext2 ability*/ ++ if ((retVal = rtl8367c_setAsicReg(0x13c4, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 2 0 bit 8~9 set 0, force n-way*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFFFCFF; ++ if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /*restore ext2 ability*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /* keep default setting, disable mac6 sel serdes*/ ++ if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) ++ return retVal; ++ ++ /*Enable new sds mode config method, cfg_sds_mode_sel_new=1*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 ++ new_cfg_sds_mode=0x1F (reset mode) */ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) ++ return retVal; ++ ++ /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_mac7_sel_sgmii= 1 & cfg_mac7_fib=1*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 3)) != RT_ERR_OK) ++ return retVal; ++ ++ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 ++ new_cfg_sds_mode=0x5 */ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x5)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (mode == EXT_1000X_100FX) ++ { ++ /* disable mac7 MII/TMM/RMII/GMII/RGMII mode, mode_ext2 = disable */ ++ if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*restore ext2 ability*/ ++ if ((retVal = rtl8367c_setAsicReg(0x13c4, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /* 0 2 0 bit 8~9 set 0, force n-way*/ ++ if((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®_data)) != RT_ERR_OK) ++ return retVal; ++ reg_data &= 0xFFFFFCFF; ++ if((retVal = rtl8367c_setAsicSdsReg(0,2,0, reg_data)) != RT_ERR_OK) ++ return retVal; ++ ++ /*restore ext2 ability*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /* keep default setting, disable mac6 sel serdes*/ ++ if ((retVal = rtl8367c_setAsicReg(0x1d11, 0x1500)) != RT_ERR_OK) ++ return retVal; ++ ++ /*Enable new sds mode config method, cfg_sds_mode_sel_new=1*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d95, 13, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 ++ new_cfg_sds_mode=0x1F (reset mode) */ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x1f)) != RT_ERR_OK) ++ return retVal; ++ ++ /*bit5: cfg_mac6_fib=0 & bit7: cfg_mac6_fib2=0*/ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 5, 0)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d41, 7, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_mac7_sel_sgmii= 1 & cfg_mac7_fib=1*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 3)) != RT_ERR_OK) ++ return retVal; ++ ++ /* bit[12:8]: Only valid when cfg_sds_mode_sel_new=1 ++ new_cfg_sds_mode=0x7 */ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 0x1f00, 0x7)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (mode < EXT_SGMII) ++ { ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d3d, 10, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /* keep default setting, disable mac7 sel SerDes mode*/ ++ if ((retVal = rtl8367c_setAsicReg(0x1d95, 0x1f00)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_mac7_sel_sgmii= 0 & cfg_mac7_fib=0*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /* set port7 mode*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x13c3, 0xf, mode)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((mode == EXT_TMII_MAC) || (mode == EXT_TMII_PHY)) ++ { ++ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 1)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ } ++ else if ((mode < EXT_END) && (mode > EXT_100FX)) ++ { ++ if ((retVal = rtl8367c_setAsicRegBits(0x13C3, 0xf, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*cfg_mac7_sel_sgmii= 0 & cfg_mac7_fib=0*/ ++ if ((retVal = rtl8367c_setAsicRegBits(0x1d95, 3, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d3d, 10, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicRegBit(0x1d11, 11, ®_data)) != RT_ERR_OK) ++ return retVal; ++ if(reg_data == 0) ++ { ++ if ((retVal = rtl8367c_setAsicRegBit(0x1d11, 6, 1)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ /* set port7 mode*/ ++ if (mode < EXT_RMII_MAC_2) ++ { ++ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, (mode-13))) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ if ((retVal = rtl8367c_setAsicRegBits(0x1305, 0xf0, (mode-12))) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ if ((mode == EXT_TMII_MAC_2) || (mode == EXT_TMII_PHY_2)) ++ { ++ if ((retVal = rtl8367c_setAsicRegBit(0x3f7, 2, 1)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ ++ } ++ ++ } ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicPortExtMode ++ * Description: ++ * Get external interface mode configuration ++ * Input: ++ * id - external interface id (0~1) ++ * pMode - external interface mode ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortExtMode(rtk_uint32 id, rtk_uint32 *pMode) ++{ ++ ret_t retVal; ++ rtk_uint32 regData, regValue, type; ++ ++ if(id >= RTL8367C_EXTNO) ++ return RT_ERR_OUT_OF_RANGE; ++ /*cfg_magic_id & get chip_id*/ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) ++ return retVal; ++ ++ type = 0; ++ ++ switch (regValue) ++ { ++ case 0x0276: ++ case 0x0597: ++ case 0x6367: ++ type = 1; ++ break; ++ case 0x0652: ++ case 0x6368: ++ type = 2; ++ break; ++ case 0x0801: ++ case 0x6511: ++ type = 3; ++ break; ++ default: ++ return RT_ERR_FAILED; ++ } ++ ++ ++ if (1 == type) ++ { ++ ++ if (1 == id) ++ { ++ if( (retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_SGMII_OFFSET, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ if(1 == regData) ++ { ++ *pMode = EXT_SGMII; ++ return RT_ERR_OK; ++ } ++ ++ if( (retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SDS_MISC, RTL8367C_CFG_MAC8_SEL_HSGMII_OFFSET, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ if(1 == regData) ++ { ++ *pMode = EXT_HSGMII; ++ return RT_ERR_OK; ++ } ++ } ++ ++ if(0 == id || 1 == id) ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_DIGITAL_INTERFACE_SELECT, RTL8367C_SELECT_GMII_0_MASK << (id * RTL8367C_SELECT_GMII_1_OFFSET), pMode); ++ else ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_DIGITAL_INTERFACE_SELECT_1, RTL8367C_SELECT_GMII_2_MASK, pMode); ++ ++ } ++ else if (2 == type) ++ { ++ if (1 == id) ++ { ++ if ((retVal = rtl8367c_getAsicReg(0x1d92, ®Data))!=RT_ERR_OK) ++ return retVal; ++ ++ if (regData & 0x4000) ++ { ++ *pMode = EXT_SGMII; ++ return RT_ERR_OK; ++ } ++ ++ else if (((regData >> 8) & 0x1f) == 4) ++ { ++ *pMode = EXT_1000X; ++ return RT_ERR_OK; ++ } ++ else if (((regData >> 8) & 0x1f) == 5) ++ { ++ *pMode = EXT_100FX; ++ return RT_ERR_OK; ++ } ++ else if (((regData >> 8) & 0x1f) == 7) ++ { ++ *pMode = EXT_1000X_100FX; ++ return RT_ERR_OK; ++ } ++ ++ return rtl8367c_getAsicRegBits(0x1305, 0xf0, pMode); ++ } ++ else if (2 == id) ++ { ++#if 0 ++ if ((retVal = rtl8367c_getAsicRegBit(0x1d92, 6, ®Data))!=RT_ERR_OK) ++ return retVal; ++ ++ if (regData == 1) ++ { ++ *pMode = EXT_SGMII; ++ return RT_ERR_OK; ++ } ++ ++ if ((retVal = rtl8367c_getAsicRegBit(0x1d92, 7, ®Data))!=RT_ERR_OK) ++ return retVal; ++ ++ if (regData == 1) ++ { ++ *pMode = EXT_HSGMII; ++ return RT_ERR_OK; ++ } ++#endif ++ if ((retVal = rtl8367c_getAsicReg(0x1d92, ®Data))!=RT_ERR_OK) ++ return retVal; ++ ++ if (regData & 0x40) ++ { ++ *pMode = EXT_SGMII; ++ return RT_ERR_OK; ++ } ++ else if (regData & 0x80) ++ { ++ *pMode = EXT_HSGMII; ++ return RT_ERR_OK; ++ } ++ else if ((regData & 0x1f) == 4) ++ { ++ *pMode = EXT_1000X; ++ return RT_ERR_OK; ++ } ++ else if ((regData & 0x1f) == 5) ++ { ++ *pMode = EXT_100FX; ++ return RT_ERR_OK; ++ } ++ else if ((regData & 0x1f) == 7) ++ { ++ *pMode = EXT_1000X_100FX; ++ return RT_ERR_OK; ++ } ++ ++ return rtl8367c_getAsicRegBits(0x1305, 0xf, pMode); ++ } ++ } ++ else if(3 == type) ++ { ++ if (1 == id) ++ { ++ /* SDS_CFG_NEW */ ++ if ((retVal = rtl8367c_getAsicReg(0x1d95, ®Data))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicReg(0x1d41, ®Value))!=RT_ERR_OK) ++ return retVal; ++ ++ /* bit5: cfg_mac6_fib=1 && bit7: cfg_mac6_fib2 =1 */ ++ if((regValue & 0xa0) == 0xa0 ) ++ { ++ /* new_cfg_sds_mode */ ++ regData = regData >> 8; ++ if((regData & 0x1f) == 4) ++ { ++ *pMode = EXT_1000X; ++ return RT_ERR_OK; ++ } ++ else if((regData & 0x1f) == 5) ++ { ++ *pMode = EXT_100FX; ++ return RT_ERR_OK; ++ } ++ else if((regData & 0x1f) == 7) ++ { ++ *pMode = EXT_1000X_100FX; ++ return RT_ERR_OK; ++ } ++ ++ } ++ ++ ++ if ((retVal = rtl8367c_getAsicReg(0x1d11, ®Data))!=RT_ERR_OK) ++ return retVal; ++ ++ /* check cfg_mac6_sel_sgmii */ ++ if((regData >> 6) & 1) ++ { ++ *pMode = EXT_SGMII; ++ return RT_ERR_OK; ++ } ++ else if((regData >> 11) & 1) ++ { ++ *pMode = EXT_HSGMII; ++ return RT_ERR_OK; ++ } ++ else ++ { ++ /* check port6 MAC mode */ ++ if ((retVal = rtl8367c_getAsicRegBits(0x1305, 0xf0, ®Data))!=RT_ERR_OK) ++ return retVal; ++ ++ if(regData < 6) ++ *pMode = regData; ++ else if(regData == 6) ++ *pMode = EXT_RMII_MAC; ++ else if(regData == 7) ++ *pMode = EXT_RMII_PHY; ++ ++ return RT_ERR_OK; ++ } ++ } ++ else if (2 == id) ++ { ++ if ((retVal = rtl8367c_getAsicReg(0x1d95, ®Data))!=RT_ERR_OK) ++ return retVal; ++ ++ /* bit0: cfg_mac7_sel_sgmii ++ bit1: cfg_mac7_fib ++ bit[12:8]: new_cfg_sds_mode*/ ++ if(((regData & 0x3) == 3) && (((regData >> 8) & 0x1f) == 0x4)) ++ { ++ *pMode = EXT_1000X; ++ return RT_ERR_OK; ++ } ++ else if (((regData & 0x3) == 3) && (((regData >> 8) & 0x1f) == 0x5)) ++ { ++ *pMode = EXT_100FX; ++ return RT_ERR_OK; ++ } ++ else if (((regData & 0x3) == 3) && (((regData >> 8) & 0x1f) == 0x7)) ++ { ++ *pMode = EXT_1000X_100FX; ++ return RT_ERR_OK; ++ } ++ else if(regData & 1) ++ { ++ *pMode = EXT_SGMII; ++ return RT_ERR_OK; ++ } ++ else ++ { ++ /* check port7 MAC mode */ ++ if ((retVal = rtl8367c_getAsicRegBits(0x13c3, 0xf, ®Data))!=RT_ERR_OK) ++ return retVal; ++ ++ *pMode = regData; ++ ++ return RT_ERR_OK; ++ } ++ } ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8370_setAsicPortEnableAll ++ * Description: ++ * Set ALL ports enable. ++ * Input: ++ * enable - enable all ports. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortEnableAll(rtk_uint32 enable) ++{ ++ if(enable >= 2) ++ return RT_ERR_INPUT; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_PHY_AD, RTL8367C_PDNPHY_OFFSET, !enable); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicPortEnableAll ++ * Description: ++ * Set ALL ports enable. ++ * Input: ++ * enable - enable all ports. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortEnableAll(rtk_uint32 *pEnable) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_PHY_AD, RTL8367C_PDNPHY_OFFSET, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ if (regData==0) ++ *pEnable = 1; ++ else ++ *pEnable = 0; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicPortSmallIpg ++ * Description: ++ * Set small ipg egress mode ++ * Input: ++ * port - Physical port number (0~7) ++ * enable - 0: normal, 1: small ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortSmallIpg(rtk_uint32 port, rtk_uint32 enable) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_PORT_SMALL_IPG_REG(port), RTL8367C_PORT0_MISC_CFG_SMALL_TAG_IPG_OFFSET, enable); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicPortSmallIpg ++ * Description: ++ * Get small ipg egress mode ++ * Input: ++ * port - Physical port number (0~7) ++ * pEnable - 0: normal, 1: small ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortSmallIpg(rtk_uint32 port, rtk_uint32* pEnable) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_PORT_SMALL_IPG_REG(port), RTL8367C_PORT0_MISC_CFG_SMALL_TAG_IPG_OFFSET, pEnable); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicPortLoopback ++ * Description: ++ * Set MAC loopback ++ * Input: ++ * port - Physical port number (0~7) ++ * enable - 0: Disable, 1: enable ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortLoopback(rtk_uint32 port, rtk_uint32 enable) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_PORT0_MISC_CFG_MAC_LOOPBACK_OFFSET, enable); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicPortLoopback ++ * Description: ++ * Set MAC loopback ++ * Input: ++ * port - Physical port number (0~7) ++ * Output: ++ * pEnable - 0: Disable, 1: enable ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortLoopback(rtk_uint32 port, rtk_uint32 *pEnable) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_PORT0_MISC_CFG_MAC_LOOPBACK_OFFSET, pEnable); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicPortRTCTEnable ++ * Description: ++ * Set RTCT Enable echo response mode ++ * Input: ++ * portmask - Port mask of RTCT enabled (0-4) ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_MASK - Invalid port mask ++ * Note: ++ * RTCT test takes 4.8 seconds at most. ++ */ ++ret_t rtl8367c_setAsicPortRTCTEnable(rtk_uint32 portmask) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint32 port; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (regData == 0x0276) || (regData == 0x0597) ) ++ return RT_ERR_CHIP_NOT_SUPPORTED; ++ ++ for(port = 0; port <= 10 ; port++) ++ { ++ if(portmask & (0x0001 << port)) ++ { ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa422, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ regData &= 0x7FFF; ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ regData |= 0x00F2;/*RTCT set to echo response mode*/ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ regData |= 0x0001; ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicPortRTCTDisable ++ * Description: ++ * Set RTCT Disable ++ * Input: ++ * portmask - Port mask of RTCT enabled (0-4) ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_MASK - Invalid port mask ++ * Note: ++ * RTCT test takes 4.8 seconds at most. ++ */ ++ret_t rtl8367c_setAsicPortRTCTDisable(rtk_uint32 portmask) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint32 port; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (regData == 0x0276) || (regData == 0x0597) ) ++ return RT_ERR_CHIP_NOT_SUPPORTED; ++ ++ for(port = 0; port <= 10 ; port++) ++ { ++ if(portmask & (0x0001 << port)) ++ { ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa422, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ regData &= 0x7FFF; ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ regData |= 0x00F0; ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) ++ return retVal; ++ ++ regData &= ~0x0001; ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa422, regData)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ ++ return RT_ERR_OK; ++} ++ ++ ++/* Function Name: ++ * rtl8367c_getAsicPortRTCTResult ++ * Description: ++ * Get RTCT result ++ * Input: ++ * port - Port ID of RTCT result ++ * Output: ++ * pResult - The result of port ID ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_MASK - Invalid port mask ++ * RT_ERR_PHY_RTCT_NOT_FINISH - RTCT test doesn't finish. ++ * Note: ++ * RTCT test takes 4.8 seconds at most. ++ * If this API returns RT_ERR_PHY_RTCT_NOT_FINISH, ++ * users should wait a whole then read it again. ++ */ ++ret_t rtl8367c_getAsicPortRTCTResult(rtk_uint32 port, rtl8367c_port_rtct_result_t *pResult) ++{ ++ ret_t retVal; ++ rtk_uint32 regData, finish = 1; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicReg(0x1300, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (regData == 0x6367) ) ++ { ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa422, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ if((regData & 0x8000) == 0x8000) ++ { ++ /* Channel A */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802a)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelAOpen = (regData == 0x0048) ? 1 : 0; ++ pResult->channelAShort = (regData == 0x0050) ? 1 : 0; ++ pResult->channelAMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; ++ pResult->channelALinedriver = (regData == 0x0041) ? 1 : 0; ++ ++ /* Channel B */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802e)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelBOpen = (regData == 0x0048) ? 1 : 0; ++ pResult->channelBShort = (regData == 0x0050) ? 1 : 0; ++ pResult->channelBMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; ++ pResult->channelBLinedriver = (regData == 0x0041) ? 1 : 0; ++ ++ /* Channel C */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8032)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelCOpen = (regData == 0x0048) ? 1 : 0; ++ pResult->channelCShort = (regData == 0x0050) ? 1 : 0; ++ pResult->channelCMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; ++ pResult->channelCLinedriver = (regData == 0x0041) ? 1 : 0; ++ ++ /* Channel D */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8036)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelDOpen = (regData == 0x0048) ? 1 : 0; ++ pResult->channelDShort = (regData == 0x0050) ? 1 : 0; ++ pResult->channelDMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; ++ pResult->channelDLinedriver = (regData == 0x0041) ? 1 : 0; ++ ++ /* Channel A Length */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802c)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelALen = (regData / 2); ++ ++ /* Channel B Length */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8030)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelBLen = (regData / 2); ++ ++ /* Channel C Length */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8034)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelCLen = (regData / 2); ++ ++ /* Channel D Length */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8038)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelDLen = (regData / 2); ++ } ++ else ++ finish = 0; ++ } ++ else if(regData == 0x6368) ++ { ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa422, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ if((regData & 0x8000) == 0x8000) ++ { ++ /* Channel A */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802b)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelAOpen = (regData == 0x0048) ? 1 : 0; ++ pResult->channelAShort = (regData == 0x0050) ? 1 : 0; ++ pResult->channelAMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; ++ pResult->channelALinedriver = (regData == 0x0041) ? 1 : 0; ++ ++ /* Channel B */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802f)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelBOpen = (regData == 0x0048) ? 1 : 0; ++ pResult->channelBShort = (regData == 0x0050) ? 1 : 0; ++ pResult->channelBMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; ++ pResult->channelBLinedriver = (regData == 0x0041) ? 1 : 0; ++ ++ /* Channel C */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8033)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelCOpen = (regData == 0x0048) ? 1 : 0; ++ pResult->channelCShort = (regData == 0x0050) ? 1 : 0; ++ pResult->channelCMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; ++ pResult->channelCLinedriver = (regData == 0x0041) ? 1 : 0; ++ ++ /* Channel D */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8037)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelDOpen = (regData == 0x0048) ? 1 : 0; ++ pResult->channelDShort = (regData == 0x0050) ? 1 : 0; ++ pResult->channelDMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; ++ pResult->channelDLinedriver = (regData == 0x0041) ? 1 : 0; ++ ++ /* Channel A Length */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802d)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelALen = (regData / 2); ++ ++ /* Channel B Length */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8031)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelBLen = (regData / 2); ++ ++ /* Channel C Length */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8035)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelCLen = (regData / 2); ++ ++ /* Channel D Length */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8039)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelDLen = (regData / 2); ++ } ++ else ++ finish = 0; ++ ++ } ++ else if((regData == 0x6511) || (regData == 0x0801)) ++ { ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa422, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ if((regData & 0x8000) == 0x8000) ++ { ++ /* Channel A */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802a)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelAOpen = (regData == 0x0048) ? 1 : 0; ++ pResult->channelAShort = (regData == 0x0050) ? 1 : 0; ++ pResult->channelAMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; ++ pResult->channelALinedriver = (regData == 0x0041) ? 1 : 0; ++ ++ /* Channel B */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802e)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelBOpen = (regData == 0x0048) ? 1 : 0; ++ pResult->channelBShort = (regData == 0x0050) ? 1 : 0; ++ pResult->channelBMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; ++ pResult->channelBLinedriver = (regData == 0x0041) ? 1 : 0; ++ ++ /* Channel C */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8032)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelCOpen = (regData == 0x0048) ? 1 : 0; ++ pResult->channelCShort = (regData == 0x0050) ? 1 : 0; ++ pResult->channelCMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; ++ pResult->channelCLinedriver = (regData == 0x0041) ? 1 : 0; ++ ++ /* Channel D */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8036)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelDOpen = (regData == 0x0048) ? 1 : 0; ++ pResult->channelDShort = (regData == 0x0050) ? 1 : 0; ++ pResult->channelDMismatch = ((regData == 0x0042) || (regData == 0x0044)) ? 1 : 0; ++ pResult->channelDLinedriver = (regData == 0x0041) ? 1 : 0; ++ ++ /* Channel A Length */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x802c)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelALen = (regData / 2); ++ ++ /* Channel B Length */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8030)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelBLen = (regData / 2); ++ ++ /* Channel C Length */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8034)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelCLen = (regData / 2); ++ ++ /* Channel D Length */ ++ if((retVal = rtl8367c_setAsicPHYOCPReg(port, 0xa436, 0x8038)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicPHYOCPReg(port, 0xa438, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ pResult->channelDLen = (regData / 2); ++ } ++ else ++ finish = 0; ++ ++ } ++ else ++ return RT_ERR_CHIP_NOT_SUPPORTED; ++ ++ if(finish == 0) ++ return RT_ERR_PHY_RTCT_NOT_FINISH; ++ else ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_sdsReset ++ * Description: ++ * Reset Serdes ++ * Input: ++ * id - EXT ID ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None. ++ */ ++ret_t rtl8367c_sdsReset(rtk_uint32 id) ++{ ++ rtk_uint32 retVal, regValue, state, i, option, running = 0, retVal2; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) ++ return retVal; ++ ++ switch (regValue) ++ { ++ case 0x0276: ++ case 0x0597: ++ case 0x6367: ++ option = 0; ++ break; ++ case 0x0652: ++ case 0x6368: ++ option = 1; ++ break; ++ case 0x0801: ++ case 0x6511: ++ option = 2; ++ break; ++ default: ++ return RT_ERR_FAILED; ++ } ++ ++ if(option == 0) ++ { ++ if (1 == id) ++ { ++ if ((retVal = rtl8367c_getAsicRegBit(0x130c, 5, &running))!=RT_ERR_OK) ++ return retVal; ++ ++ if(running == 1) ++ { ++ if ((retVal = rtl8367c_setAsicRegBit(0x130c, 5, 0))!=RT_ERR_OK) ++ return retVal; ++ } ++ ++ retVal = rtl8367c_setAsicReg(0x6601, 0x0000); ++ ++ if(retVal == RT_ERR_OK) ++ retVal = rtl8367c_setAsicReg(0x6602, 0x1401); ++ ++ if(retVal == RT_ERR_OK) ++ retVal = rtl8367c_setAsicReg(0x6600, 0x00C0); ++ ++ if(retVal == RT_ERR_OK) ++ retVal = rtl8367c_setAsicReg(0x6601, 0x0000); ++ ++ if(retVal == RT_ERR_OK) ++ retVal = rtl8367c_setAsicReg(0x6602, 0x1403); ++ ++ if(retVal == RT_ERR_OK) ++ retVal = rtl8367c_setAsicReg(0x6600, 0x00C0); ++ ++ if(running == 1) ++ { ++ if ((retVal2 = rtl8367c_setAsicRegBit(0x130c, 5, 1))!=RT_ERR_OK) ++ return retVal2; ++ } ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ return RT_ERR_PORT_ID; ++ } ++ else if(option == 1) ++ { ++ if (1 == id) ++ { ++ if((retVal = rtl8367c_getAsicReg(0x1311, &state)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x1311, 0x66)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x1311, 0x1066)) != RT_ERR_OK) ++ return retVal; ++ ++ while(1) ++ { ++ if((retVal = rtl8367c_getAsicReg(0x1d9d, ®Value)) != RT_ERR_OK) ++ return retVal; ++ if((regValue >> 8) & 1) ++ break; ++ } ++ ++ for (i=0; i<0xffff; i++); ++ ++ if((retVal = rtl8367c_setAsicReg(0x133d, 0x2)) != RT_ERR_OK) ++ return retVal; ++ ++ for (i=0; i<0xffff; i++); ++ ++ if((retVal = rtl8367c_setAsicReg(0x6601, 0x0)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_setAsicReg(0x6602, 0x1401)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_setAsicReg(0x6600, 0xc1)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_setAsicReg(0x6601, 0x0)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_setAsicReg(0x6602, 0x1403)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_setAsicReg(0x6600, 0xc1)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x133d, 0x0)) != RT_ERR_OK) ++ return retVal; ++ ++ for (i=0; i<0xffff; i++); ++ ++ if((retVal = rtl8367c_setAsicReg(0x1311, state)) != RT_ERR_OK) ++ return retVal; ++ ++ ++ } ++ else if (2== id) ++ { ++ if((retVal = rtl8367c_getAsicReg(0x13c4, &state)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13c4, 0x66)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13c4, 0x1066)) != RT_ERR_OK) ++ return retVal; ++ ++ while(1) ++ { ++ if((retVal = rtl8367c_getAsicReg(0x1d9d, ®Value)) != RT_ERR_OK) ++ return retVal; ++ if((regValue >> 9) & 1) ++ break; ++ } ++ ++ for (i=0; i<0xffff; i++); ++ ++ if((retVal = rtl8367c_setAsicReg(0x133d, 0x2)) != RT_ERR_OK) ++ return retVal; ++ ++ for (i=0; i<0xffff; i++); ++ ++ if((retVal = rtl8367c_setAsicReg(0x6601, 0x0)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_setAsicReg(0x6602, 0x1401)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_setAsicReg(0x6600, 0xc0)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_setAsicReg(0x6601, 0x0)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_setAsicReg(0x6602, 0x1403)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_setAsicReg(0x6600, 0xc0)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x133d, 0x0)) != RT_ERR_OK) ++ return retVal; ++ ++ for (i=0; i<0xffff; i++); ++ ++ if((retVal = rtl8367c_setAsicReg(0x13c4, state)) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ return RT_ERR_PORT_ID; ++ } ++ else if(option == 2) ++ { ++ if ((retVal = rtl8367c_getAsicSdsReg(0, 3, 0, ®Value))!=RT_ERR_OK) ++ return retVal; ++ regValue |= 0x40; ++ if ((retVal = rtl8367c_setAsicSdsReg(0, 3, 0, regValue))!=RT_ERR_OK) ++ return retVal; ++ ++ for (i=0; i<0xffff; i++); ++ ++ regValue &= ~(0x40); ++ if ((retVal = rtl8367c_setAsicSdsReg(0, 3, 0, regValue))!=RT_ERR_OK) ++ return retVal; ++ ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getSdsLinkStatus ++ * Description: ++ * Get SGMII status ++ * Input: ++ * id - EXT ID ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None. ++ */ ++ret_t rtl8367c_getSdsLinkStatus(rtk_uint32 ext_id, rtk_uint32 *pSignalDetect, rtk_uint32 *pSync, rtk_uint32 *pLink) ++{ ++ rtk_uint32 retVal, regValue, type, running = 0, retVal2; ++ ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) ++ return retVal; ++ ++ switch (regValue) ++ { ++ case 0x0276: ++ case 0x0597: ++ case 0x6367: ++ type = 0; ++ break; ++ case 0x0652: ++ case 0x6368: ++ type = 1; ++ break; ++ case 0x0801: ++ case 0x6511: ++ type = 2; ++ break; ++ default: ++ return RT_ERR_FAILED; ++ } ++ ++ if(type == 0) ++ { ++ if (1 == ext_id) ++ { ++ if ((retVal = rtl8367c_getAsicRegBit(0x130c, 5, &running))!=RT_ERR_OK) ++ return retVal; ++ ++ if(running == 1) ++ { ++ if ((retVal = rtl8367c_setAsicRegBit(0x130c, 5, 0))!=RT_ERR_OK) ++ return retVal; ++ } ++ ++ retVal = rtl8367c_setAsicReg(0x6601, 0x003D); ++ ++ if(retVal == RT_ERR_OK) ++ retVal = rtl8367c_setAsicReg(0x6600, 0x0080); ++ ++ if(retVal == RT_ERR_OK) ++ retVal = rtl8367c_getAsicReg(0x6602, ®Value); ++ ++ if(running == 1) ++ { ++ if ((retVal2 = rtl8367c_setAsicRegBit(0x130c, 5, 1))!=RT_ERR_OK) ++ return retVal2; ++ } ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *pSignalDetect = (regValue & 0x0100) ? 1 : 0; ++ *pSync = (regValue & 0x0001) ? 1 : 0; ++ *pLink = (regValue & 0x0010) ? 1 : 0; ++ } ++ else ++ return RT_ERR_PORT_ID; ++ } ++ else if(type == 1) ++ { ++ if (1 == ext_id) ++ { ++ if ((retVal = rtl8367c_setAsicReg(0x6601, 0x003D))!=RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0081))!=RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) ++ return retVal; ++ ++ *pSignalDetect = (regValue & 0x0100) ? 1 : 0; ++ *pSync = (regValue & 0x0001) ? 1 : 0; ++ *pLink = (regValue & 0x0010) ? 1 : 0; ++ } ++ else if (2 == ext_id) ++ { ++ if ((retVal = rtl8367c_setAsicReg(0x6601, 0x003D))!=RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0080))!=RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) ++ return retVal; ++ ++ *pSignalDetect = (regValue & 0x0100) ? 1 : 0; ++ *pSync = (regValue & 0x0001) ? 1 : 0; ++ *pLink = (regValue & 0x0010) ? 1 : 0; ++ } ++ else ++ return RT_ERR_PORT_ID; ++ } ++ else if(type == 2) ++ { ++ if((retVal = rtl8367c_getAsicSdsReg(0, 30, 1, ®Value)) != RT_ERR_OK) ++ return retVal; ++ if((retVal = rtl8367c_getAsicSdsReg(0, 30, 1, ®Value)) != RT_ERR_OK) ++ return retVal; ++ ++ *pSignalDetect = (regValue & 0x0100) ? 1 : 0; ++ *pSync = (regValue & 0x0001) ? 1 : 0; ++ *pLink = (regValue & 0x0010) ? 1 : 0; ++ ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setSgmiiNway ++ * Description: ++ * Set SGMII Nway ++ * Input: ++ * ext_id - EXT ID ++ * state - SGMII Nway state ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None. ++ */ ++ret_t rtl8367c_setSgmiiNway(rtk_uint32 ext_id, rtk_uint32 state) ++{ ++ rtk_uint32 retVal, regValue, type, running = 0, retVal2; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) ++ return retVal; ++ ++ switch (regValue) ++ { ++ case 0x0276: ++ case 0x0597: ++ case 0x6367: ++ type = 0; ++ break; ++ case 0x0652: ++ case 0x6368: ++ type = 1; ++ break; ++ case 0x0801: ++ case 0x6511: ++ type = 2; ++ break; ++ default: ++ return RT_ERR_FAILED; ++ } ++ ++ if(type == 0) ++ { ++ if (1 == ext_id) ++ { ++ if ((retVal = rtl8367c_getAsicRegBit(0x130c, 5, &running))!=RT_ERR_OK) ++ return retVal; ++ ++ if(running == 1) ++ { ++ if ((retVal = rtl8367c_setAsicRegBit(0x130c, 5, 0))!=RT_ERR_OK) ++ return retVal; ++ } ++ ++ retVal = rtl8367c_setAsicReg(0x6601, 0x0002); ++ ++ if(retVal == RT_ERR_OK) ++ retVal = rtl8367c_setAsicReg(0x6600, 0x0080); ++ ++ if(retVal == RT_ERR_OK) ++ retVal = rtl8367c_getAsicReg(0x6602, ®Value); ++ ++ if(retVal == RT_ERR_OK) ++ { ++ if(state) ++ regValue |= 0x0200; ++ else ++ regValue &= ~0x0200; ++ ++ regValue |= 0x0100; ++ } ++ ++ if(retVal == RT_ERR_OK) ++ retVal = rtl8367c_setAsicReg(0x6602, regValue); ++ ++ if(retVal == RT_ERR_OK) ++ retVal = rtl8367c_setAsicReg(0x6601, 0x0002); ++ ++ if(retVal == RT_ERR_OK) ++ retVal = rtl8367c_setAsicReg(0x6600, 0x00C0); ++ ++ if(running == 1) ++ { ++ if ((retVal2 = rtl8367c_setAsicRegBit(0x130c, 5, 1))!=RT_ERR_OK) ++ return retVal2; ++ } ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ return RT_ERR_PORT_ID; ++ } ++ else if(type == 1) ++ { ++ if (1 == ext_id) ++ { ++ if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0081))!=RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) ++ return retVal; ++ ++ if(state) ++ regValue |= 0x0200; ++ else ++ regValue &= ~0x0200; ++ ++ regValue |= 0x0100; ++ ++ if ((retVal = rtl8367c_setAsicReg(0x6602, regValue))!=RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicReg(0x6600, 0x00C1))!=RT_ERR_OK) ++ return retVal; ++ } ++ else if (2 == ext_id) ++ { ++ if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0080))!=RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) ++ return retVal; ++ ++ if(state) ++ regValue |= 0x0200; ++ else ++ regValue &= ~0x0200; ++ ++ regValue |= 0x0100; ++ ++ if ((retVal = rtl8367c_setAsicReg(0x6602, regValue))!=RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicReg(0x6600, 0x00C0))!=RT_ERR_OK) ++ return retVal; ++ } ++ else ++ return RT_ERR_PORT_ID; ++ } ++ else if(type == 2) ++ { ++ if ((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®Value))!=RT_ERR_OK) ++ return retVal; ++ ++ if(state & 1) ++ regValue &= ~0x100; ++ else ++ regValue |= 0x100; ++ ++ if ((retVal = rtl8367c_setAsicSdsReg(0, 2, 0, regValue))!=RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getSgmiiNway ++ * Description: ++ * Get SGMII Nway ++ * Input: ++ * ext_id - EXT ID ++ * state - SGMII Nway state ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None. ++ */ ++ret_t rtl8367c_getSgmiiNway(rtk_uint32 ext_id, rtk_uint32 *pState) ++{ ++ rtk_uint32 retVal, regValue, type, running = 0, retVal2; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) ++ return retVal; ++ ++ switch (regValue) ++ { ++ case 0x0276: ++ case 0x0597: ++ case 0x6367: ++ type = 0; ++ break; ++ case 0x0652: ++ case 0x6368: ++ type = 1; ++ break; ++ case 0x0801: ++ case 0x6511: ++ type = 2; ++ break; ++ default: ++ return RT_ERR_FAILED; ++ } ++ ++ if(type == 0) ++ { ++ if (1 == ext_id) ++ { ++ if ((retVal = rtl8367c_getAsicRegBit(0x130c, 5, &running))!=RT_ERR_OK) ++ return retVal; ++ ++ if(running == 1) ++ { ++ if ((retVal = rtl8367c_setAsicRegBit(0x130c, 5, 0))!=RT_ERR_OK) ++ return retVal; ++ } ++ ++ retVal = rtl8367c_setAsicReg(0x6601, 0x0002); ++ ++ if(retVal == RT_ERR_OK) ++ retVal = rtl8367c_setAsicReg(0x6600, 0x0080); ++ ++ if(retVal == RT_ERR_OK) ++ retVal = rtl8367c_getAsicReg(0x6602, ®Value); ++ ++ if(running == 1) ++ { ++ if ((retVal2 = rtl8367c_setAsicRegBit(0x130c, 5, 1))!=RT_ERR_OK) ++ return retVal2; ++ } ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ if(regValue & 0x0200) ++ *pState = 1; ++ else ++ *pState = 0; ++ } ++ else ++ return RT_ERR_PORT_ID; ++ } ++ else if(type == 1) ++ { ++ if (1 == ext_id) ++ { ++ if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0081))!=RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) ++ return retVal; ++ ++ if(regValue & 0x0200) ++ *pState = 1; ++ else ++ *pState = 0; ++ } ++ else if (2 == ext_id) ++ { ++ if ((retVal = rtl8367c_setAsicReg(0x6601, 0x0002))!=RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicReg(0x6600, 0x0080))!=RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_getAsicReg(0x6602, ®Value))!=RT_ERR_OK) ++ return retVal; ++ ++ if(regValue & 0x0200) ++ *pState = 1; ++ else ++ *pState = 0; ++ } ++ else ++ return RT_ERR_PORT_ID; ++ } ++ else if(type == 2) ++ { ++ if ((retVal = rtl8367c_getAsicSdsReg(0, 2, 0, ®Value))!=RT_ERR_OK) ++ return retVal; ++ ++ if(regValue & 0x100) ++ *pState = 0; ++ else ++ *pState = 1; ++ } ++ ++ return RT_ERR_OK; ++} +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_portIsolation.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_portIsolation.c +new file mode 100644 +index 0000000000..e0b9db4bfb +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_portIsolation.c +@@ -0,0 +1,119 @@ ++/* ++ * 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 : Port isolation related functions ++ * ++ */ ++ ++#include ++/* Function Name: ++ * rtl8367c_setAsicPortIsolationPermittedPortmask ++ * Description: ++ * Set permitted port isolation portmask ++ * Input: ++ * port - Physical port number (0~10) ++ * permitPortmask - port mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_PORT_MASK - Invalid portmask ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortIsolationPermittedPortmask(rtk_uint32 port, rtk_uint32 permitPortmask) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ if( permitPortmask > RTL8367C_PORTMASK) ++ return RT_ERR_PORT_MASK; ++ ++ return rtl8367c_setAsicReg(RTL8367C_PORT_ISOLATION_PORT_MASK_REG(port), permitPortmask); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortIsolationPermittedPortmask ++ * Description: ++ * Get permitted port isolation portmask ++ * Input: ++ * port - Physical port number (0~10) ++ * pPermitPortmask - port mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortIsolationPermittedPortmask(rtk_uint32 port, rtk_uint32 *pPermitPortmask) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicReg(RTL8367C_PORT_ISOLATION_PORT_MASK_REG(port), pPermitPortmask); ++} ++/* Function Name: ++ * rtl8367c_setAsicPortIsolationEfid ++ * Description: ++ * Set port isolation EFID ++ * Input: ++ * port - Physical port number (0~10) ++ * efid - EFID (0~7) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_OUT_OF_RANGE - Input parameter out of range ++ * Note: ++ * EFID is used in individual learning in filtering database ++ */ ++ret_t rtl8367c_setAsicPortIsolationEfid(rtk_uint32 port, rtk_uint32 efid) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ if( efid > RTL8367C_EFIDMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_PORT_EFID_REG(port), RTL8367C_PORT_EFID_MASK(port), efid); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortIsolationEfid ++ * Description: ++ * Get port isolation EFID ++ * Input: ++ * port - Physical port number (0~10) ++ * pEfid - EFID (0~7) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortIsolationEfid(rtk_uint32 port, rtk_uint32 *pEfid) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_PORT_EFID_REG(port), RTL8367C_PORT_EFID_MASK(port), pEfid); ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_qos.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_qos.c +new file mode 100644 +index 0000000000..89c3c3e02e +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_qos.c +@@ -0,0 +1,778 @@ ++/* ++ * 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 : Qos related functions ++ * ++ */ ++ ++#include ++/* Function Name: ++ * rtl8367c_setAsicPriorityDot1qRemapping ++ * Description: ++ * Set 802.1Q absolutely priority ++ * Input: ++ * srcpriority - Priority value ++ * priority - Absolute priority value ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPriorityDot1qRemapping(rtk_uint32 srcpriority, rtk_uint32 priority ) ++{ ++ if((srcpriority > RTL8367C_PRIMAX) || (priority > RTL8367C_PRIMAX)) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_QOS_1Q_PRIORITY_REMAPPING_REG(srcpriority), RTL8367C_QOS_1Q_PRIORITY_REMAPPING_MASK(srcpriority),priority); ++} ++/* Function Name: ++ * rtl8367c_getAsicPriorityDot1qRemapping ++ * Description: ++ * Get 802.1Q absolutely priority ++ * Input: ++ * srcpriority - Priority value ++ * pPriority - Absolute priority value ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPriorityDot1qRemapping(rtk_uint32 srcpriority, rtk_uint32 *pPriority ) ++{ ++ if(srcpriority > RTL8367C_PRIMAX ) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_QOS_1Q_PRIORITY_REMAPPING_REG(srcpriority), RTL8367C_QOS_1Q_PRIORITY_REMAPPING_MASK(srcpriority), pPriority); ++} ++/* Function Name: ++ * rtl8367c_setAsicPriorityPortBased ++ * Description: ++ * Set port based priority ++ * Input: ++ * port - Physical port number (0~7) ++ * priority - Priority value ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPriorityPortBased(rtk_uint32 port, rtk_uint32 priority ) ++{ ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(priority > RTL8367C_PRIMAX ) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ if(port < 8) ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_QOS_PORTBASED_PRIORITY_REG(port), RTL8367C_QOS_PORTBASED_PRIORITY_MASK(port), priority); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL2, 0x7 << ((port - 8) << 2), priority); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicPriorityPortBased ++ * Description: ++ * Get port based priority ++ * Input: ++ * port - Physical port number (0~7) ++ * pPriority - Priority value ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPriorityPortBased(rtk_uint32 port, rtk_uint32 *pPriority ) ++{ ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(port < 8) ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_QOS_PORTBASED_PRIORITY_REG(port), RTL8367C_QOS_PORTBASED_PRIORITY_MASK(port), pPriority); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_QOS_PORTBASED_PRIORITY_CTRL2, 0x7 << ((port - 8) << 2), pPriority); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicPriorityDscpBased ++ * Description: ++ * Set DSCP-based priority ++ * Input: ++ * dscp - DSCP value ++ * priority - Priority value ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPriorityDscpBased(rtk_uint32 dscp, rtk_uint32 priority ) ++{ ++ if(priority > RTL8367C_PRIMAX ) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ if(dscp > RTL8367C_DSCPMAX) ++ return RT_ERR_QOS_DSCP_VALUE; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_QOS_DSCP_TO_PRIORITY_REG(dscp), RTL8367C_QOS_DSCP_TO_PRIORITY_MASK(dscp), priority); ++} ++/* Function Name: ++ * rtl8367c_getAsicPriorityDscpBased ++ * Description: ++ * Get DSCP-based priority ++ * Input: ++ * dscp - DSCP value ++ * pPriority - Priority value ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPriorityDscpBased(rtk_uint32 dscp, rtk_uint32 *pPriority ) ++{ ++ if(dscp > RTL8367C_DSCPMAX) ++ return RT_ERR_QOS_DSCP_VALUE; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_QOS_DSCP_TO_PRIORITY_REG(dscp), RTL8367C_QOS_DSCP_TO_PRIORITY_MASK(dscp), pPriority); ++} ++/* Function Name: ++ * rtl8367c_setAsicPriorityDecision ++ * Description: ++ * Set priority decision table ++ * Input: ++ * prisrc - Priority decision source ++ * decisionPri - Decision priority assignment ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * RT_ERR_QOS_SEL_PRI_SOURCE - Invalid priority decision source parameter ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPriorityDecision(rtk_uint32 index, rtk_uint32 prisrc, rtk_uint32 decisionPri) ++{ ++ ret_t retVal; ++ ++ if(index >= PRIDEC_IDX_END ) ++ return RT_ERR_ENTRY_INDEX; ++ ++ if(prisrc >= PRIDEC_END ) ++ return RT_ERR_QOS_SEL_PRI_SOURCE; ++ ++ if(decisionPri > RTL8367C_DECISIONPRIMAX ) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ switch(index) ++ { ++ case PRIDEC_IDX0: ++ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_REG(prisrc), RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_MASK(prisrc), decisionPri))!= RT_ERR_OK) ++ return retVal; ++ break; ++ case PRIDEC_IDX1: ++ if((retVal = rtl8367c_setAsicRegBits(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_REG(prisrc), RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_MASK(prisrc), decisionPri))!= RT_ERR_OK) ++ return retVal; ++ break; ++ default: ++ break; ++ }; ++ ++ return RT_ERR_OK; ++ ++ ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicPriorityDecision ++ * Description: ++ * Get priority decision table ++ * Input: ++ * prisrc - Priority decision source ++ * pDecisionPri - Decision priority assignment ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_QOS_SEL_PRI_SOURCE - Invalid priority decision source parameter ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPriorityDecision(rtk_uint32 index, rtk_uint32 prisrc, rtk_uint32* pDecisionPri) ++{ ++ ret_t retVal; ++ ++ if(index >= PRIDEC_IDX_END ) ++ return RT_ERR_ENTRY_INDEX; ++ ++ if(prisrc >= PRIDEC_END ) ++ return RT_ERR_QOS_SEL_PRI_SOURCE; ++ ++ switch(index) ++ { ++ case PRIDEC_IDX0: ++ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_REG(prisrc), RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_MASK(prisrc), pDecisionPri))!= RT_ERR_OK) ++ return retVal; ++ break; ++ case PRIDEC_IDX1: ++ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_REG(prisrc), RTL8367C_QOS_INTERNAL_PRIORITY_DECISION2_MASK(prisrc), pDecisionPri))!= RT_ERR_OK) ++ return retVal; ++ break; ++ default: ++ break; ++ }; ++ ++ return RT_ERR_OK; ++ ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicPortPriorityDecisionIndex ++ * Description: ++ * Set priority decision index for each port ++ * Input: ++ * port - Physical port number (0~7) ++ * index - Table index ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_QUEUE_NUM - Invalid queue number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortPriorityDecisionIndex(rtk_uint32 port, rtk_uint32 index ) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(index >= PRIDEC_IDX_END) ++ return RT_ERR_ENTRY_INDEX; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX_CTRL, port, index); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortPriorityDecisionIndex ++ * Description: ++ * Get priority decision index for each port ++ * Input: ++ * port - Physical port number (0~7) ++ * pIndex - Table index ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortPriorityDecisionIndex(rtk_uint32 port, rtk_uint32 *pIndex ) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_QOS_INTERNAL_PRIORITY_DECISION_IDX_CTRL, port, pIndex); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicOutputQueueMappingIndex ++ * Description: ++ * Set output queue number for each port ++ * Input: ++ * port - Physical port number (0~7) ++ * index - Mapping table index ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_QUEUE_NUM - Invalid queue number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicOutputQueueMappingIndex(rtk_uint32 port, rtk_uint32 index ) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(index >= RTL8367C_QUEUENO) ++ return RT_ERR_QUEUE_NUM; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_QOS_PORT_QUEUE_NUMBER_REG(port), RTL8367C_QOS_PORT_QUEUE_NUMBER_MASK(port), index); ++} ++/* Function Name: ++ * rtl8367c_getAsicOutputQueueMappingIndex ++ * Description: ++ * Get output queue number for each port ++ * Input: ++ * port - Physical port number (0~7) ++ * pIndex - Mapping table index ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicOutputQueueMappingIndex(rtk_uint32 port, rtk_uint32 *pIndex ) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_QOS_PORT_QUEUE_NUMBER_REG(port), RTL8367C_QOS_PORT_QUEUE_NUMBER_MASK(port), pIndex); ++} ++/* Function Name: ++ * rtl8367c_setAsicPriorityToQIDMappingTable ++ * Description: ++ * Set priority to QID mapping table parameters ++ * Input: ++ * index - Mapping table index ++ * priority - The priority value ++ * qid - Queue id ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_QUEUE_ID - Invalid queue id ++ * RT_ERR_QUEUE_NUM - Invalid queue number ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPriorityToQIDMappingTable(rtk_uint32 index, rtk_uint32 priority, rtk_uint32 qid ) ++{ ++ if(index >= RTL8367C_QUEUENO) ++ return RT_ERR_QUEUE_NUM; ++ ++ if(priority > RTL8367C_PRIMAX) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ if(qid > RTL8367C_QIDMAX) ++ return RT_ERR_QUEUE_ID; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_QOS_1Q_PRIORITY_TO_QID_REG(index, priority), RTL8367C_QOS_1Q_PRIORITY_TO_QID_MASK(priority), qid); ++} ++/* Function Name: ++ * rtl8367c_getAsicPriorityToQIDMappingTable ++ * Description: ++ * Get priority to QID mapping table parameters ++ * Input: ++ * index - Mapping table index ++ * priority - The priority value ++ * pQid - Queue id ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_QUEUE_NUM - Invalid queue number ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPriorityToQIDMappingTable(rtk_uint32 index, rtk_uint32 priority, rtk_uint32* pQid) ++{ ++ if(index >= RTL8367C_QUEUENO) ++ return RT_ERR_QUEUE_NUM; ++ ++ if(priority > RTL8367C_PRIMAX) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_QOS_1Q_PRIORITY_TO_QID_REG(index, priority), RTL8367C_QOS_1Q_PRIORITY_TO_QID_MASK(priority), pQid); ++} ++/* Function Name: ++ * rtl8367c_setAsicRemarkingDot1pAbility ++ * Description: ++ * Set 802.1p remarking ability ++ * Input: ++ * port - Physical port number (0~7) ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicRemarkingDot1pAbility(rtk_uint32 port, rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_1QREMARK_ENABLE_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicRemarkingDot1pAbility ++ * Description: ++ * Get 802.1p remarking ability ++ * Input: ++ * port - Physical port number (0~7) ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRemarkingDot1pAbility(rtk_uint32 port, rtk_uint32* pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_1QREMARK_ENABLE_OFFSET, pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicRemarkingDot1pParameter ++ * Description: ++ * Set 802.1p remarking parameter ++ * Input: ++ * priority - Priority value ++ * newPriority - New priority value ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicRemarkingDot1pParameter(rtk_uint32 priority, rtk_uint32 newPriority ) ++{ ++ if(priority > RTL8367C_PRIMAX || newPriority > RTL8367C_PRIMAX) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_QOS_1Q_REMARK_REG(priority), RTL8367C_QOS_1Q_REMARK_MASK(priority), newPriority); ++} ++/* Function Name: ++ * rtl8367c_getAsicRemarkingDot1pParameter ++ * Description: ++ * Get 802.1p remarking parameter ++ * Input: ++ * priority - Priority value ++ * pNewPriority - New priority value ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRemarkingDot1pParameter(rtk_uint32 priority, rtk_uint32 *pNewPriority ) ++{ ++ if(priority > RTL8367C_PRIMAX ) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_QOS_1Q_REMARK_REG(priority), RTL8367C_QOS_1Q_REMARK_MASK(priority), pNewPriority); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicRemarkingDot1pSrc ++ * 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 DSCP value or internal ++ * priority to TX DSCP value. ++ */ ++ret_t rtl8367c_setAsicRemarkingDot1pSrc(rtk_uint32 type) ++{ ++ ++ if(type >= DOT1P_PRISEL_END ) ++ return RT_ERR_QOS_SEL_PRI_SOURCE; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_RMK_CFG_SEL_CTRL, RTL8367C_RMK_1Q_CFG_SEL_OFFSET, type); ++} ++ ++ ++/* Function Name: ++ * rtl8367c_getAsicRemarkingDot1pSrc ++ * Description: ++ * Get remarking source of 802.1p remarking. ++ * 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 ++ */ ++ret_t rtl8367c_getAsicRemarkingDot1pSrc(rtk_uint32 *pType) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_RMK_CFG_SEL_CTRL, RTL8367C_RMK_1Q_CFG_SEL_OFFSET, pType); ++} ++ ++ ++ ++ ++ ++/* Function Name: ++ * rtl8367c_setAsicRemarkingDscpAbility ++ * Description: ++ * Set DSCP remarking ability ++ * Input: ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicRemarkingDscpAbility(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REMARKING_CTRL_REG, RTL8367C_REMARKING_DSCP_ENABLE_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicRemarkingDscpAbility ++ * Description: ++ * Get DSCP remarking ability ++ * Input: ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRemarkingDscpAbility(rtk_uint32* pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REMARKING_CTRL_REG, RTL8367C_REMARKING_DSCP_ENABLE_OFFSET, pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicRemarkingDscpParameter ++ * Description: ++ * Set DSCP remarking parameter ++ * Input: ++ * priority - Priority value ++ * newDscp - New DSCP value ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_QOS_DSCP_VALUE - Invalid DSCP value ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicRemarkingDscpParameter(rtk_uint32 priority, rtk_uint32 newDscp ) ++{ ++ if(priority > RTL8367C_PRIMAX ) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ if(newDscp > RTL8367C_DSCPMAX) ++ return RT_ERR_QOS_DSCP_VALUE; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_QOS_DSCP_REMARK_REG(priority), RTL8367C_QOS_DSCP_REMARK_MASK(priority), newDscp); ++} ++/* Function Name: ++ * rtl8367c_getAsicRemarkingDscpParameter ++ * Description: ++ * Get DSCP remarking parameter ++ * Input: ++ * priority - Priority value ++ * pNewDscp - New DSCP value ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRemarkingDscpParameter(rtk_uint32 priority, rtk_uint32* pNewDscp ) ++{ ++ if(priority > RTL8367C_PRIMAX ) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_QOS_DSCP_REMARK_REG(priority), RTL8367C_QOS_DSCP_REMARK_MASK(priority), pNewDscp); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicRemarkingDscpSrc ++ * 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. ++ */ ++ret_t rtl8367c_setAsicRemarkingDscpSrc(rtk_uint32 type) ++{ ++ ++ if(type >= DSCP_PRISEL_END ) ++ return RT_ERR_QOS_SEL_PRI_SOURCE; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_RMK_CFG_SEL_CTRL, RTL8367C_RMK_DSCP_CFG_SEL_MASK, type); ++} ++ ++ ++/* Function Name: ++ * rtl8367c_getAsicRemarkingDscpSrc ++ * Description: ++ * Get remarking source of DSCP remarking. ++ * 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 ++ */ ++ret_t rtl8367c_getAsicRemarkingDscpSrc(rtk_uint32 *pType) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_RMK_CFG_SEL_CTRL, RTL8367C_RMK_DSCP_CFG_SEL_MASK, pType); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicRemarkingDscp2Dscp ++ * 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_UNIT_ID - Invalid unit id ++ * 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. ++ */ ++ret_t rtl8367c_setAsicRemarkingDscp2Dscp(rtk_uint32 dscp, rtk_uint32 rmkDscp) ++{ ++ if((dscp > RTL8367C_DSCPMAX ) || (rmkDscp > RTL8367C_DSCPMAX)) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_QOS_DSCP_TO_DSCP_REG(dscp), RTL8367C_QOS_DSCP_TO_DSCP_MASK(dscp), rmkDscp); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicRemarkingDscp2Dscp ++ * Description: ++ * Get DSCP to remarked DSCP mapping. ++ * Input: ++ * dscp - DSCP value ++ * Output: ++ * pRmkDscp - 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. ++ */ ++ret_t rtl8367c_getAsicRemarkingDscp2Dscp(rtk_uint32 dscp, rtk_uint32 *pRmkDscp) ++{ ++ if(dscp > RTL8367C_DSCPMAX) ++ return RT_ERR_QOS_DSCP_VALUE; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_QOS_DSCP_TO_DSCP_REG(dscp), RTL8367C_QOS_DSCP_TO_DSCP_MASK(dscp), pRmkDscp); ++ ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rldp.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rldp.c +new file mode 100644 +index 0000000000..0309689d39 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rldp.c +@@ -0,0 +1,674 @@ ++/* ++ * 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: 42321 $ ++ * $Date: 2013-08-26 13:51:29 +0800 (週一, 26 八月 2013) $ ++ * ++ * Purpose : RTL8367C switch high-level API for RTL8367C ++ * Feature : RLDP related functions ++ * ++ */ ++ ++#include ++/* Function Name: ++ * rtl8367c_setAsicRldp ++ * Description: ++ * Set RLDP function enable/disable ++ * Input: ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicRldp(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_ENABLE_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicRldp ++ * Description: ++ * Get RLDP function enable/disable ++ * Input: ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRldp(rtk_uint32 *pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_ENABLE_OFFSET, pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicRldpEnable8051 ++ * Description: ++ * Set RLDP function handled by ASIC or 8051 ++ * Input: ++ * enabled - 1: enabled 8051, 0: disabled 8051 (RLDP is handled by ASIC) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicRldpEnable8051(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_8051_ENABLE_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicRldrtl8367c_getAsicRldpEnable8051pEnable8051 ++ * Description: ++ * Get RLDP function handled by ASIC or 8051 ++ * Input: ++ * pEnabled - 1: enabled 8051, 0: disabled 8051 (RLDP is handled by ASIC) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRldpEnable8051(rtk_uint32 *pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_8051_ENABLE_OFFSET, pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicRldpCompareRandomNumber ++ * Description: ++ * Set enable compare the random number field and seed field of RLDP frame ++ * Input: ++ * enabled - 1: enabled comparing random number, 0: disabled comparing random number ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicRldpCompareRandomNumber(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_COMP_ID_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicRldpCompareRandomNumber ++ * Description: ++ * Get enable compare the random number field and seed field of RLDP frame ++ * Input: ++ * pEnabled - 1: enabled comparing random number, 0: disabled comparing random number ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRldpCompareRandomNumber(rtk_uint32 *pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_COMP_ID_OFFSET, pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicRldpIndicatorSource ++ * Description: ++ * Set buzzer and LED source when detecting a loop ++ * Input: ++ * src - 0: ASIC, 1: 8051 ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicRldpIndicatorSource(rtk_uint32 src) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_INDICATOR_SOURCE_OFFSET, src); ++} ++/* Function Name: ++ * rtl8367c_getAsicRldpIndicatorSource ++ * Description: ++ * Get buzzer and LED source when detecting a loop ++ * Input: ++ * pSrc - 0: ASIC, 1: 8051 ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRldpIndicatorSource(rtk_uint32 *pSrc) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_INDICATOR_SOURCE_OFFSET, pSrc); ++} ++/* Function Name: ++ * rtl8367c_setAsicRldpCheckingStatePara ++ * Description: ++ * Set retry count and retry period of checking state ++ * Input: ++ * retryCount - 0~0xFF (times) ++ * retryPeriod - 0~0xFFFF (ms) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicRldpCheckingStatePara(rtk_uint32 retryCount, rtk_uint32 retryPeriod) ++{ ++ ret_t retVal; ++ ++ if(retryCount > 0xFF) ++ return RT_ERR_OUT_OF_RANGE; ++ if(retryPeriod > RTL8367C_REGDATAMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_RLDP_RETRY_COUNT_REG, RTL8367C_RLDP_RETRY_COUNT_CHKSTATE_MASK, retryCount); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return rtl8367c_setAsicReg(RTL8367C_RLDP_RETRY_PERIOD_CHKSTATE_REG, retryPeriod); ++} ++/* Function Name: ++ * rtl8367c_getAsicRldpCheckingStatePara ++ * Description: ++ * Get retry count and retry period of checking state ++ * Input: ++ * pRetryCount - 0~0xFF (times) ++ * pRetryPeriod - 0~0xFFFF (ms) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRldpCheckingStatePara(rtk_uint32 *pRetryCount, rtk_uint32 *pRetryPeriod) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_RLDP_RETRY_COUNT_REG, RTL8367C_RLDP_RETRY_COUNT_CHKSTATE_MASK, pRetryCount); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return rtl8367c_getAsicReg(RTL8367C_RLDP_RETRY_PERIOD_CHKSTATE_REG, pRetryPeriod); ++} ++/* Function Name: ++ * rtl8367c_setAsicRldpLoopStatePara ++ * Description: ++ * Set retry count and retry period of loop state ++ * Input: ++ * retryCount - 0~0xFF (times) ++ * retryPeriod - 0~0xFFFF (ms) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicRldpLoopStatePara(rtk_uint32 retryCount, rtk_uint32 retryPeriod) ++{ ++ ret_t retVal; ++ ++ if(retryCount > 0xFF) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(retryPeriod > RTL8367C_REGDATAMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_RLDP_RETRY_COUNT_REG, RTL8367C_RLDP_RETRY_COUNT_LOOPSTATE_MASK, retryCount); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return rtl8367c_setAsicReg(RTL8367C_RLDP_RETRY_PERIOD_LOOPSTATE_REG, retryPeriod); ++} ++/* Function Name: ++ * rtl8367c_getAsicRldpLoopStatePara ++ * Description: ++ * Get retry count and retry period of loop state ++ * Input: ++ * pRetryCount - 0~0xFF (times) ++ * pRetryPeriod - 0~0xFFFF (ms) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - input parameter out of range ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRldpLoopStatePara(rtk_uint32 *pRetryCount, rtk_uint32 *pRetryPeriod) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_RLDP_RETRY_COUNT_REG, RTL8367C_RLDP_RETRY_COUNT_LOOPSTATE_MASK, pRetryCount); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return rtl8367c_getAsicReg(RTL8367C_RLDP_RETRY_PERIOD_LOOPSTATE_REG, pRetryPeriod); ++} ++/* Function Name: ++ * rtl8367c_setAsicRldpTxPortmask ++ * Description: ++ * Set portmask that send/forward RLDP frame ++ * Input: ++ * portmask - 0~0xFF ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_MASK - Invalid portmask ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicRldpTxPortmask(rtk_uint32 portmask) ++{ ++ if(portmask > RTL8367C_PORTMASK) ++ return RT_ERR_PORT_MASK; ++ ++ return rtl8367c_setAsicReg(RTL8367C_RLDP_TX_PMSK_REG, portmask); ++} ++/* Function Name: ++ * rtl8367c_getAsicRldpTxPortmask ++ * Description: ++ * Get portmask that send/forward RLDP frame ++ * Input: ++ * pPortmask - 0~0xFF ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRldpTxPortmask(rtk_uint32 *pPortmask) ++{ ++ return rtl8367c_getAsicReg(RTL8367C_RLDP_TX_PMSK_REG, pPortmask); ++} ++/* Function Name: ++ * rtl8367c_setAsicRldpMagicNum ++ * Description: ++ * Set Random seed of RLDP ++ * Input: ++ * seed - MAC ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicRldpMagicNum(ether_addr_t seed) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint16 *accessPtr; ++ rtk_uint32 i; ++ ++ accessPtr = (rtk_uint16*)&seed; ++ ++ for (i = 0; i < 3; i++) ++ { ++ regData = *accessPtr; ++ retVal = rtl8367c_setAsicReg(RTL8367C_RLDP_MAGIC_NUM_REG_BASE + i, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ accessPtr++; ++ } ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicRldpMagicNum ++ * Description: ++ * Get Random seed of RLDP ++ * Input: ++ * pSeed - MAC ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRldpMagicNum(ether_addr_t *pSeed) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint16 *accessPtr; ++ rtk_uint32 i; ++ ++ accessPtr = (rtk_uint16*)pSeed; ++ ++ for(i = 0; i < 3; i++) ++ { ++ retVal = rtl8367c_getAsicReg(RTL8367C_RLDP_MAGIC_NUM_REG_BASE + i, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *accessPtr = regData; ++ accessPtr++; ++ } ++ ++ return retVal; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicRldpLoopedPortmask ++ * Description: ++ * Get looped portmask ++ * Input: ++ * pPortmask - 0~0xFF ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRldpLoopedPortmask(rtk_uint32 *pPortmask) ++{ ++ return rtl8367c_getAsicReg(RTL8367C_RLDP_LOOP_PMSK_REG, pPortmask); ++} ++/* Function Name: ++ * rtl8367c_getAsicRldpRandomNumber ++ * Description: ++ * Get Random number of RLDP ++ * Input: ++ * pRandNumber - MAC ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRldpRandomNumber(ether_addr_t *pRandNumber) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ rtk_int16 accessPtr[3]; ++ rtk_uint32 i; ++ ++ for(i = 0; i < 3; i++) ++ { ++ retVal = rtl8367c_getAsicReg(RTL8367C_RLDP_RAND_NUM_REG_BASE+ i, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ accessPtr[i] = regData; ++ } ++ ++ memcpy(pRandNumber, accessPtr, 6); ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicRldpLoopedPortmask ++ * Description: ++ * Get port number of looped pair ++ * Input: ++ * port - Physical port number (0~7) ++ * pLoopedPair - port (0~7) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRldpLoopedPortPair(rtk_uint32 port, rtk_uint32 *pLoopedPair) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(port < 8) ++ return rtl8367c_getAsicRegBits(RTL8367C_RLDP_LOOP_PORT_REG(port), RTL8367C_RLDP_LOOP_PORT_MASK(port), pLoopedPair); ++ else ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_RLDP_LOOP_PORT_REG4 + ((port - 8) >> 1), RTL8367C_RLDP_LOOP_PORT_MASK(port), pLoopedPair); ++} ++/* Function Name: ++ * rtl8367c_setAsicRlppTrap8051 ++ * Description: ++ * Set trap RLPP packet to 8051 ++ * Input: ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicRlppTrap8051(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLPP_8051_TRAP_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicRlppTrap8051 ++ * Description: ++ * Get trap RLPP packet to 8051 ++ * Input: ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRlppTrap8051(rtk_uint32 *pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLPP_8051_TRAP_OFFSET, pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicRldpLeaveLoopedPortmask ++ * Description: ++ * Clear leaved looped portmask ++ * Input: ++ * portmask - 0~0xFF ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicRldpLeaveLoopedPortmask(rtk_uint32 portmask) ++{ ++ return rtl8367c_setAsicReg(RTL8367C_REG_RLDP_RELEASED_INDICATOR, portmask); ++} ++/* Function Name: ++ * rtl8367c_getAsicRldpLeaveLoopedPortmask ++ * Description: ++ * Get leaved looped portmask ++ * Input: ++ * pPortmask - 0~0xFF ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRldpLeaveLoopedPortmask(rtk_uint32 *pPortmask) ++{ ++ return rtl8367c_getAsicReg(RTL8367C_REG_RLDP_RELEASED_INDICATOR, pPortmask); ++} ++/* Function Name: ++ * rtl8367c_setAsicRldpEnterLoopedPortmask ++ * Description: ++ * Clear enter loop portmask ++ * Input: ++ * portmask - 0~0xFF ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicRldpEnterLoopedPortmask(rtk_uint32 portmask) ++{ ++ return rtl8367c_setAsicReg(RTL8367C_REG_RLDP_LOOPED_INDICATOR, portmask); ++} ++/* Function Name: ++ * rtl8367c_getAsicRldpEnterLoopedPortmask ++ * Description: ++ * Get enter loop portmask ++ * Input: ++ * pPortmask - 0~0xFF ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRldpEnterLoopedPortmask(rtk_uint32 *pPortmask) ++{ ++ return rtl8367c_getAsicReg(RTL8367C_REG_RLDP_LOOPED_INDICATOR, pPortmask); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicRldpTriggerMode ++ * Description: ++ * Set trigger RLDP mode ++ * Input: ++ * mode - 1: Periodically, 0: SA moving ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicRldpTriggerMode(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_TRIGGER_MODE_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicRldpTriggerMode ++ * Description: ++ * Get trigger RLDP mode ++ * Input: ++ * pMode - - 1: Periodically, 0: SA moving ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRldpTriggerMode(rtk_uint32 *pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_RLDP_CTRL0, RTL8367C_RLDP_TRIGGER_MODE_OFFSET, pEnabled); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicRldp8051Portmask ++ * Description: ++ * Set 8051/CPU configured looped portmask ++ * Input: ++ * portmask - 0~0xFF ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_MASK - Invalid portmask ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicRldp8051Portmask(rtk_uint32 portmask) ++{ ++ ret_t retVal; ++ if(portmask > RTL8367C_PORTMASK) ++ return RT_ERR_PORT_MASK; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_RLDP_CTRL0_REG,RTL8367C_RLDP_8051_LOOP_PORTMSK_MASK,portmask & 0xff); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_RLDP_CTRL5,RTL8367C_RLDP_CTRL5_MASK,(portmask >> 8) & 7); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicRldp8051Portmask ++ * Description: ++ * Get 8051/CPU configured looped portmask ++ * Input: ++ * pPortmask - 0~0xFF ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRldp8051Portmask(rtk_uint32 *pPortmask) ++{ ++ rtk_uint32 tmpPmsk; ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_RLDP_CTRL0_REG,RTL8367C_RLDP_8051_LOOP_PORTMSK_MASK,&tmpPmsk); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ *pPortmask = tmpPmsk & 0xff; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_RLDP_CTRL5,RTL8367C_RLDP_CTRL5_MASK,&tmpPmsk); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ *pPortmask |= (tmpPmsk & 7) <<8; ++ ++ return RT_ERR_OK; ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rma.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rma.c +new file mode 100644 +index 0000000000..f297defa78 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_rma.c +@@ -0,0 +1,362 @@ ++/* ++ * 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: 64716 $ ++ * $Date: 2015-12-31 16:31:55 +0800 (週四, 31 å二月 2015) $ ++ * ++ * Purpose : RTL8367C switch high-level API for RTL8367C ++ * Feature : RMA related functions ++ * ++ */ ++ ++#include ++/* Function Name: ++ * rtl8367c_setAsicRma ++ * Description: ++ * Set reserved multicast address for CPU trapping ++ * Input: ++ * index - reserved multicast LSB byte, 0x00~0x2F is available value ++ * pRmacfg - type of RMA for trapping frame type setting ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_RMA_ADDR - Invalid RMA address index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicRma(rtk_uint32 index, rtl8367c_rma_t* pRmacfg) ++{ ++ rtk_uint32 regData = 0; ++ ret_t retVal; ++ ++ if(index > RTL8367C_RMAMAX) ++ return RT_ERR_RMA_ADDR; ++ ++ regData |= (pRmacfg->portiso_leaky & 0x0001); ++ regData |= ((pRmacfg->vlan_leaky & 0x0001) << 1); ++ regData |= ((pRmacfg->keep_format & 0x0001) << 2); ++ regData |= ((pRmacfg->trap_priority & 0x0007) << 3); ++ regData |= ((pRmacfg->discard_storm_filter & 0x0001) << 6); ++ regData |= ((pRmacfg->operation & 0x0003) << 7); ++ ++ if( (index >= 0x4 && index <= 0x7) || (index >= 0x9 && index <= 0x0C) || (0x0F == index)) ++ index = 0x04; ++ else if((index >= 0x13 && index <= 0x17) || (0x19 == index) || (index >= 0x1B && index <= 0x1f)) ++ index = 0x13; ++ else if(index >= 0x22 && index <= 0x2F) ++ index = 0x22; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, pRmacfg->trap_priority); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return rtl8367c_setAsicReg(RTL8367C_REG_RMA_CTRL00+index, regData); ++} ++/* Function Name: ++ * rtl8367c_getAsicRma ++ * Description: ++ * Get reserved multicast address for CPU trapping ++ * Input: ++ * index - reserved multicast LSB byte, 0x00~0x2F is available value ++ * rmacfg - type of RMA for trapping frame type setting ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_RMA_ADDR - Invalid RMA address index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRma(rtk_uint32 index, rtl8367c_rma_t* pRmacfg) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ if(index > RTL8367C_RMAMAX) ++ return RT_ERR_RMA_ADDR; ++ ++ if( (index >= 0x4 && index <= 0x7) || (index >= 0x9 && index <= 0x0C) || (0x0F == index)) ++ index = 0x04; ++ else if((index >= 0x13 && index <= 0x17) || (0x19 == index) || (index >= 0x1B && index <= 0x1f)) ++ index = 0x13; ++ else if(index >= 0x22 && index <= 0x2F) ++ index = 0x22; ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_RMA_CTRL00+index, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pRmacfg->operation = ((regData >> 7) & 0x0003); ++ pRmacfg->discard_storm_filter = ((regData >> 6) & 0x0001); ++ pRmacfg->trap_priority = ((regData >> 3) & 0x0007); ++ pRmacfg->keep_format = ((regData >> 2) & 0x0001); ++ pRmacfg->vlan_leaky = ((regData >> 1) & 0x0001); ++ pRmacfg->portiso_leaky = (regData & 0x0001); ++ ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pRmacfg->trap_priority = regData; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicRmaCdp ++ * Description: ++ * Set CDP(Cisco Discovery Protocol) for CPU trapping ++ * Input: ++ * pRmacfg - type of RMA for trapping frame type setting ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_RMA_ADDR - Invalid RMA address index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicRmaCdp(rtl8367c_rma_t* pRmacfg) ++{ ++ rtk_uint32 regData = 0; ++ ret_t retVal; ++ ++ if(pRmacfg->operation >= RMAOP_END) ++ return RT_ERR_RMA_ACTION; ++ ++ if(pRmacfg->trap_priority > RTL8367C_PRIMAX) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ regData |= (pRmacfg->portiso_leaky & 0x0001); ++ regData |= ((pRmacfg->vlan_leaky & 0x0001) << 1); ++ regData |= ((pRmacfg->keep_format & 0x0001) << 2); ++ regData |= ((pRmacfg->trap_priority & 0x0007) << 3); ++ regData |= ((pRmacfg->discard_storm_filter & 0x0001) << 6); ++ regData |= ((pRmacfg->operation & 0x0003) << 7); ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, pRmacfg->trap_priority); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return rtl8367c_setAsicReg(RTL8367C_REG_RMA_CTRL_CDP, regData); ++} ++/* Function Name: ++ * rtl8367c_getAsicRmaCdp ++ * Description: ++ * Get CDP(Cisco Discovery Protocol) for CPU trapping ++ * Input: ++ * None ++ * Output: ++ * pRmacfg - type of RMA for trapping frame type setting ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_RMA_ADDR - Invalid RMA address index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRmaCdp(rtl8367c_rma_t* pRmacfg) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_RMA_CTRL_CDP, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pRmacfg->operation = ((regData >> 7) & 0x0003); ++ pRmacfg->discard_storm_filter = ((regData >> 6) & 0x0001); ++ pRmacfg->trap_priority = ((regData >> 3) & 0x0007); ++ pRmacfg->keep_format = ((regData >> 2) & 0x0001); ++ pRmacfg->vlan_leaky = ((regData >> 1) & 0x0001); ++ pRmacfg->portiso_leaky = (regData & 0x0001); ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pRmacfg->trap_priority = regData; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicRmaCsstp ++ * Description: ++ * Set CSSTP(Cisco Shared Spanning Tree Protocol) for CPU trapping ++ * Input: ++ * pRmacfg - type of RMA for trapping frame type setting ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_RMA_ADDR - Invalid RMA address index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicRmaCsstp(rtl8367c_rma_t* pRmacfg) ++{ ++ rtk_uint32 regData = 0; ++ ret_t retVal; ++ ++ if(pRmacfg->operation >= RMAOP_END) ++ return RT_ERR_RMA_ACTION; ++ ++ if(pRmacfg->trap_priority > RTL8367C_PRIMAX) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ regData |= (pRmacfg->portiso_leaky & 0x0001); ++ regData |= ((pRmacfg->vlan_leaky & 0x0001) << 1); ++ regData |= ((pRmacfg->keep_format & 0x0001) << 2); ++ regData |= ((pRmacfg->trap_priority & 0x0007) << 3); ++ regData |= ((pRmacfg->discard_storm_filter & 0x0001) << 6); ++ regData |= ((pRmacfg->operation & 0x0003) << 7); ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, pRmacfg->trap_priority); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return rtl8367c_setAsicReg(RTL8367C_REG_RMA_CTRL_CSSTP, regData); ++} ++/* Function Name: ++ * rtl8367c_getAsicRmaCsstp ++ * Description: ++ * Get CSSTP(Cisco Shared Spanning Tree Protocol) for CPU trapping ++ * Input: ++ * None ++ * Output: ++ * pRmacfg - type of RMA for trapping frame type setting ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_RMA_ADDR - Invalid RMA address index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRmaCsstp(rtl8367c_rma_t* pRmacfg) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_RMA_CTRL_CSSTP, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pRmacfg->operation = ((regData >> 7) & 0x0003); ++ pRmacfg->discard_storm_filter = ((regData >> 6) & 0x0001); ++ pRmacfg->trap_priority = ((regData >> 3) & 0x0007); ++ pRmacfg->keep_format = ((regData >> 2) & 0x0001); ++ pRmacfg->vlan_leaky = ((regData >> 1) & 0x0001); ++ pRmacfg->portiso_leaky = (regData & 0x0001); ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pRmacfg->trap_priority = regData; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicRmaLldp ++ * Description: ++ * Set LLDP for CPU trapping ++ * Input: ++ * pRmacfg - type of RMA for trapping frame type setting ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_RMA_ADDR - Invalid RMA address index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicRmaLldp(rtk_uint32 enabled, rtl8367c_rma_t* pRmacfg) ++{ ++ rtk_uint32 regData = 0; ++ ret_t retVal; ++ ++ if(enabled > 1) ++ return RT_ERR_ENABLE; ++ ++ if(pRmacfg->operation >= RMAOP_END) ++ return RT_ERR_RMA_ACTION; ++ ++ if(pRmacfg->trap_priority > RTL8367C_PRIMAX) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_RMA_LLDP_EN, RTL8367C_RMA_LLDP_EN_OFFSET,enabled); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ regData |= (pRmacfg->portiso_leaky & 0x0001); ++ regData |= ((pRmacfg->vlan_leaky & 0x0001) << 1); ++ regData |= ((pRmacfg->keep_format & 0x0001) << 2); ++ regData |= ((pRmacfg->trap_priority & 0x0007) << 3); ++ regData |= ((pRmacfg->discard_storm_filter & 0x0001) << 6); ++ regData |= ((pRmacfg->operation & 0x0003) << 7); ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, pRmacfg->trap_priority); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return rtl8367c_setAsicReg(RTL8367C_REG_RMA_CTRL_LLDP, regData); ++} ++/* Function Name: ++ * rtl8367c_getAsicRmaLldp ++ * Description: ++ * Get LLDP for CPU trapping ++ * Input: ++ * None ++ * Output: ++ * pRmacfg - type of RMA for trapping frame type setting ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_RMA_ADDR - Invalid RMA address index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicRmaLldp(rtk_uint32 *pEnabled, rtl8367c_rma_t* pRmacfg) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_RMA_LLDP_EN, RTL8367C_RMA_LLDP_EN_OFFSET,pEnabled); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_REG_RMA_CTRL_LLDP, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pRmacfg->operation = ((regData >> 7) & 0x0003); ++ pRmacfg->discard_storm_filter = ((regData >> 6) & 0x0001); ++ pRmacfg->trap_priority = ((regData >> 3) & 0x0007); ++ pRmacfg->keep_format = ((regData >> 2) & 0x0001); ++ pRmacfg->vlan_leaky = ((regData >> 1) & 0x0001); ++ pRmacfg->portiso_leaky = (regData & 0x0001); ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_RMA_CTRL00, RTL8367C_TRAP_PRIORITY_MASK, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pRmacfg->trap_priority = regData; ++ ++ return RT_ERR_OK; ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_scheduling.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_scheduling.c +new file mode 100644 +index 0000000000..8ebd6796dc +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_scheduling.c +@@ -0,0 +1,525 @@ ++/* ++ * 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 : Packet Scheduling related functions ++ * ++ */ ++ ++#include ++/* Function Name: ++ * rtl8367c_setAsicLeakyBucketParameter ++ * Description: ++ * Set Leaky Bucket Paramters ++ * Input: ++ * tick - Tick is used for time slot size unit ++ * token - Token is used for adding budget in each time slot ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_TICK - Invalid TICK ++ * RT_ERR_TOKEN - Invalid TOKEN ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicLeakyBucketParameter(rtk_uint32 tick, rtk_uint32 token) ++{ ++ ret_t retVal; ++ ++ if(tick > 0xFF) ++ return RT_ERR_TICK; ++ ++ if(token > 0xFF) ++ return RT_ERR_TOKEN; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_LEAKY_BUCKET_TICK_REG, RTL8367C_LEAKY_BUCKET_TICK_MASK, tick); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_LEAKY_BUCKET_TOKEN_REG, RTL8367C_LEAKY_BUCKET_TOKEN_MASK, token); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicLeakyBucketParameter ++ * Description: ++ * Get Leaky Bucket Paramters ++ * Input: ++ * tick - Tick is used for time slot size unit ++ * token - Token is used for adding budget in each time slot ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicLeakyBucketParameter(rtk_uint32 *tick, rtk_uint32 *token) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_LEAKY_BUCKET_TICK_REG, RTL8367C_LEAKY_BUCKET_TICK_MASK, tick); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_LEAKY_BUCKET_TOKEN_REG, RTL8367C_LEAKY_BUCKET_TOKEN_MASK, token); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_setAsicAprMeter ++ * Description: ++ * Set per-port per-queue APR shared meter index ++ * Input: ++ * port - Physical port number (0~10) ++ * qid - Queue id ++ * apridx - dedicated shared meter index for APR (0~7) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_QUEUE_ID - Invalid queue id ++ * RT_ERR_FILTER_METER_ID - Invalid meter ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicAprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 apridx) ++{ ++ ret_t retVal; ++ rtk_uint32 regAddr; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(qid > RTL8367C_QIDMAX) ++ return RT_ERR_QUEUE_ID; ++ ++ if(apridx > RTL8367C_PORT_QUEUE_METER_INDEX_MAX) ++ return RT_ERR_FILTER_METER_ID; ++ ++ if(port < 8) ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_SCHEDULE_PORT_APR_METER_REG(port, qid), RTL8367C_SCHEDULE_PORT_APR_METER_MASK(qid), apridx); ++ else { ++ regAddr = RTL8367C_REG_SCHEDULE_PORT8_APR_METER_CTRL0 + ((port-8) << 1) + (qid / 5); ++ retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_SCHEDULE_PORT_APR_METER_MASK(qid), apridx); ++ } ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicAprMeter ++ * Description: ++ * Get per-port per-queue APR shared meter index ++ * Input: ++ * port - Physical port number (0~10) ++ * qid - Queue id ++ * apridx - dedicated shared meter index for APR (0~7) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_QUEUE_ID - Invalid queue id ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicAprMeter(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *apridx) ++{ ++ ret_t retVal; ++ rtk_uint32 regAddr; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(qid > RTL8367C_QIDMAX) ++ return RT_ERR_QUEUE_ID; ++ ++ if(port < 8) ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_SCHEDULE_PORT_APR_METER_REG(port, qid), RTL8367C_SCHEDULE_PORT_APR_METER_MASK(qid), apridx); ++ else { ++ regAddr = RTL8367C_REG_SCHEDULE_PORT8_APR_METER_CTRL0 + ((port-8) << 1) + (qid / 5); ++ retVal = rtl8367c_getAsicRegBits(regAddr, RTL8367C_SCHEDULE_PORT_APR_METER_MASK(qid), apridx); ++ } ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_setAsicAprEnable ++ * Description: ++ * Set per-port APR enable ++ * Input: ++ * port - Physical port number (0~7) ++ * aprEnable - APR enable seting 1:enable 0:disable ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicAprEnable(rtk_uint32 port, rtk_uint32 aprEnable) ++{ ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ retVal = rtl8367c_setAsicRegBit(RTL8367C_SCHEDULE_APR_CTRL_REG, RTL8367C_SCHEDULE_APR_CTRL_OFFSET(port), aprEnable); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicAprEnable ++ * Description: ++ * Get per-port APR enable ++ * Input: ++ * port - Physical port number (0~7) ++ * aprEnable - APR enable seting 1:enable 0:disable ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicAprEnable(rtk_uint32 port, rtk_uint32 *aprEnable) ++{ ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_SCHEDULE_APR_CTRL_REG, RTL8367C_SCHEDULE_APR_CTRL_OFFSET(port), aprEnable); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_setAsicWFQWeight ++ * Description: ++ * Set weight of a queue ++ * Input: ++ * port - Physical port number (0~10) ++ * qid - The queue ID wanted to set ++ * qWeight - The weight value wanted to set (valid:0~127) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_QUEUE_ID - Invalid queue id ++ * RT_ERR_QOS_QUEUE_WEIGHT - Invalid queue weight ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicWFQWeight(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 qWeight) ++{ ++ ret_t retVal; ++ ++ /* Invalid input parameter */ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(qid > RTL8367C_QIDMAX) ++ return RT_ERR_QUEUE_ID; ++ ++ if(qWeight > RTL8367C_QWEIGHTMAX && qid > 0) ++ return RT_ERR_QOS_QUEUE_WEIGHT; ++ ++ retVal = rtl8367c_setAsicReg(RTL8367C_SCHEDULE_PORT_QUEUE_WFQ_WEIGHT_REG(port, qid), qWeight); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicWFQWeight ++ * Description: ++ * Get weight of a queue ++ * Input: ++ * port - Physical port number (0~10) ++ * qid - The queue ID wanted to set ++ * qWeight - The weight value wanted to set (valid:0~127) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_QUEUE_ID - Invalid queue id ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicWFQWeight(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *qWeight) ++{ ++ ret_t retVal; ++ ++ ++ /* Invalid input parameter */ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(qid > RTL8367C_QIDMAX) ++ return RT_ERR_QUEUE_ID; ++ ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_SCHEDULE_PORT_QUEUE_WFQ_WEIGHT_REG(port, qid), qWeight); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_setAsicWFQBurstSize ++ * Description: ++ * Set WFQ leaky bucket burst size ++ * Input: ++ * burstsize - Leaky bucket burst size, unit byte ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicWFQBurstSize(rtk_uint32 burstsize) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_setAsicReg(RTL8367C_SCHEDULE_WFQ_BURST_SIZE_REG, burstsize); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicWFQBurstSize ++ * Description: ++ * Get WFQ leaky bucket burst size ++ * Input: ++ * burstsize - Leaky bucket burst size, unit byte ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicWFQBurstSize(rtk_uint32 *burstsize) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_SCHEDULE_WFQ_BURST_SIZE_REG, burstsize); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_setAsicQueueType ++ * Description: ++ * Set type of a queue ++ * Input: ++ * port - Physical port number (0~10) ++ * qid - The queue ID wanted to set ++ * queueType - The specified queue type. 0b0: Strict priority, 0b1: WFQ ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_QUEUE_ID - Invalid queue id ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicQueueType(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 queueType) ++{ ++ ret_t retVal; ++ ++ /* Invalid input parameter */ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(qid > RTL8367C_QIDMAX) ++ return RT_ERR_QUEUE_ID; ++ ++ /* Set Related Registers */ ++ retVal = rtl8367c_setAsicRegBit(RTL8367C_SCHEDULE_QUEUE_TYPE_REG(port), RTL8367C_SCHEDULE_QUEUE_TYPE_OFFSET(port, qid),queueType); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicQueueType ++ * Description: ++ * Get type of a queue ++ * Input: ++ * port - Physical port number (0~7) ++ * qid - The queue ID wanted to set ++ * queueType - The specified queue type. 0b0: Strict priority, 0b1: WFQ ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_QUEUE_ID - Invalid queue id ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicQueueType(rtk_uint32 port, rtk_uint32 qid, rtk_uint32 *queueType) ++{ ++ ret_t retVal; ++ ++ /* Invalid input parameter */ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(qid > RTL8367C_QIDMAX) ++ return RT_ERR_QUEUE_ID; ++ ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_SCHEDULE_QUEUE_TYPE_REG(port), RTL8367C_SCHEDULE_QUEUE_TYPE_OFFSET(port, qid),queueType); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_setAsicPortEgressRate ++ * Description: ++ * Set per-port egress rate ++ * Input: ++ * port - Physical port number (0~10) ++ * rate - Egress rate ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_QOS_EBW_RATE - Invalid bandwidth/rate ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortEgressRate(rtk_uint32 port, rtk_uint32 rate) ++{ ++ ret_t retVal; ++ rtk_uint32 regAddr, regData; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(rate > RTL8367C_QOS_GRANULARTY_MAX) ++ return RT_ERR_QOS_EBW_RATE; ++ ++ regAddr = RTL8367C_PORT_EGRESSBW_LSB_REG(port); ++ regData = RTL8367C_QOS_GRANULARTY_LSB_MASK & rate; ++ ++ retVal = rtl8367c_setAsicReg(regAddr, regData); ++ ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ regAddr = RTL8367C_PORT_EGRESSBW_MSB_REG(port); ++ regData = (RTL8367C_QOS_GRANULARTY_MSB_MASK & rate) >> RTL8367C_QOS_GRANULARTY_MSB_OFFSET; ++ ++ retVal = rtl8367c_setAsicRegBits(regAddr, RTL8367C_PORT6_EGRESSBW_CTRL1_MASK, regData); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicPortEgressRate ++ * Description: ++ * Get per-port egress rate ++ * Input: ++ * port - Physical port number (0~10) ++ * rate - Egress rate ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortEgressRate(rtk_uint32 port, rtk_uint32 *rate) ++{ ++ ret_t retVal; ++ rtk_uint32 regAddr, regData,regData2; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ regAddr = RTL8367C_PORT_EGRESSBW_LSB_REG(port); ++ ++ retVal = rtl8367c_getAsicReg(regAddr, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ regAddr = RTL8367C_PORT_EGRESSBW_MSB_REG(port); ++ retVal = rtl8367c_getAsicRegBits(regAddr, RTL8367C_PORT6_EGRESSBW_CTRL1_MASK, ®Data2); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *rate = regData | (regData2 << RTL8367C_QOS_GRANULARTY_MSB_OFFSET); ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicPortEgressRateIfg ++ * Description: ++ * Set per-port egress rate calculate include/exclude IFG ++ * Input: ++ * ifg - 1:include IFG 0:exclude IFG ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortEgressRateIfg(rtk_uint32 ifg) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_SCHEDULE_WFQ_CTRL, RTL8367C_SCHEDULE_WFQ_CTRL_OFFSET, ifg); ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicPortEgressRateIfg ++ * Description: ++ * Get per-port egress rate calculate include/exclude IFG ++ * Input: ++ * ifg - 1:include IFG 0:exclude IFG ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortEgressRateIfg(rtk_uint32 *ifg) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_SCHEDULE_WFQ_CTRL, RTL8367C_SCHEDULE_WFQ_CTRL_OFFSET, ifg); ++ ++ return retVal; ++} +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_storm.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_storm.c +new file mode 100644 +index 0000000000..a29f64769d +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_storm.c +@@ -0,0 +1,851 @@ ++/* ++ * 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 : Storm control filtering related functions ++ * ++ */ ++ ++#include ++/* Function Name: ++ * rtl8367c_setAsicStormFilterBroadcastEnable ++ * Description: ++ * Set per-port broadcast storm filter enable/disable ++ * Input: ++ * port - Physical port number (0~7) ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicStormFilterBroadcastEnable(rtk_uint32 port, rtk_uint32 enabled) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_STORM_BCAST_REG, port, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicStormFilterBroadcastEnable ++ * Description: ++ * Get per-port broadcast storm filter enable/disable ++ * Input: ++ * port - Physical port number (0~7) ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicStormFilterBroadcastEnable(rtk_uint32 port, rtk_uint32 *pEnabled) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_STORM_BCAST_REG, port, pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicStormFilterBroadcastMeter ++ * Description: ++ * Set per-port broadcast storm filter meter ++ * Input: ++ * port - Physical port number (0~7) ++ * meter - meter index (0~31) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_FILTER_METER_ID - Invalid meter index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicStormFilterBroadcastMeter(rtk_uint32 port, rtk_uint32 meter) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ if(meter > RTL8367C_METERMAX) ++ return RT_ERR_FILTER_METER_ID; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_STORM_BCAST_METER_CTRL_REG(port), RTL8367C_STORM_BCAST_METER_CTRL_MASK(port), meter); ++} ++/* Function Name: ++ * rtl8367c_getAsicStormFilterBroadcastMeter ++ * Description: ++ * Get per-port broadcast storm filter meter ++ * Input: ++ * port - Physical port number (0~7) ++ * pMeter - meter index (0~31) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicStormFilterBroadcastMeter(rtk_uint32 port, rtk_uint32 *pMeter) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_STORM_BCAST_METER_CTRL_REG(port), RTL8367C_STORM_BCAST_METER_CTRL_MASK(port), pMeter); ++} ++/* Function Name: ++ * rtl8367c_setAsicStormFilterMulticastEnable ++ * Description: ++ * Set per-port multicast storm filter enable/disable ++ * Input: ++ * port - Physical port number (0~7) ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicStormFilterMulticastEnable(rtk_uint32 port, rtk_uint32 enabled) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_STORM_MCAST_REG, port, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicStormFilterMulticastEnable ++ * Description: ++ * Get per-port multicast storm filter enable/disable ++ * Input: ++ * port - Physical port number (0~7) ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicStormFilterMulticastEnable(rtk_uint32 port, rtk_uint32 *pEnabled) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_STORM_MCAST_REG, port, pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicStormFilterMulticastMeter ++ * Description: ++ * Set per-port multicast storm filter meter ++ * Input: ++ * port - Physical port number (0~7) ++ * meter - meter index (0~31) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_FILTER_METER_ID - Invalid meter index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicStormFilterMulticastMeter(rtk_uint32 port, rtk_uint32 meter) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ if(meter > RTL8367C_METERMAX) ++ return RT_ERR_FILTER_METER_ID; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_STORM_MCAST_METER_CTRL_REG(port), RTL8367C_STORM_MCAST_METER_CTRL_MASK(port), meter); ++} ++/* Function Name: ++ * rtl8367c_getAsicStormFilterMulticastMeter ++ * Description: ++ * Get per-port multicast storm filter meter ++ * Input: ++ * port - Physical port number (0~7) ++ * pMeter - meter index (0~31) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicStormFilterMulticastMeter(rtk_uint32 port, rtk_uint32 *pMeter) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_STORM_MCAST_METER_CTRL_REG(port), RTL8367C_STORM_MCAST_METER_CTRL_MASK(port), pMeter); ++} ++/* Function Name: ++ * rtl8367c_setAsicStormFilterUnknownMulticastEnable ++ * Description: ++ * Set per-port unknown multicast storm filter enable/disable ++ * Input: ++ * port - Physical port number (0~7) ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicStormFilterUnknownMulticastEnable(rtk_uint32 port, rtk_uint32 enabled) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_STORM_UNKNOWN_MCAST_REG, port, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicStormFilterUnknownMulticastEnable ++ * Description: ++ * Get per-port unknown multicast storm filter enable/disable ++ * Input: ++ * port - Physical port number (0~7) ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicStormFilterUnknownMulticastEnable(rtk_uint32 port, rtk_uint32 *pEnabled) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_STORM_UNKNOWN_MCAST_REG, port, pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicStormFilterUnknownMulticastMeter ++ * Description: ++ * Set per-port unknown multicast storm filter meter ++ * Input: ++ * port - Physical port number (0~7) ++ * meter - meter index (0~31) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_FILTER_METER_ID - Invalid meter index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicStormFilterUnknownMulticastMeter(rtk_uint32 port, rtk_uint32 meter) ++{ ++ ret_t retVal; ++ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ if(meter > RTL8367C_METERMAX) ++ return RT_ERR_FILTER_METER_ID; ++ ++ if(port < 8) ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_STORM_UNMC_METER_CTRL_REG(port), RTL8367C_STORM_UNMC_METER_CTRL_MASK(port), meter); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_UNMC_METER_CTRL4 + ((port - 8) >> 1), RTL8367C_STORM_UNMC_METER_CTRL_MASK(port), meter); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicStormFilterUnknownMulticastMeter ++ * Description: ++ * Get per-port unknown multicast storm filter meter ++ * Input: ++ * port - Physical port number (0~7) ++ * pMeter - meter index (0~31) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicStormFilterUnknownMulticastMeter(rtk_uint32 port, rtk_uint32 *pMeter) ++{ ++ ret_t retVal; ++ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ if(port < 8) ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_STORM_UNMC_METER_CTRL_REG(port), RTL8367C_STORM_UNMC_METER_CTRL_MASK(port), pMeter); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_UNMC_METER_CTRL4 + ((port - 8) >> 1), RTL8367C_STORM_UNMC_METER_CTRL_MASK(port), pMeter); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicStormFilterUnknownUnicastEnable ++ * Description: ++ * Set per-port unknown unicast storm filter enable/disable ++ * Input: ++ * port - Physical port number (0~7) ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicStormFilterUnknownUnicastEnable(rtk_uint32 port, rtk_uint32 enabled) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_STORM_UNKNOWN_UCAST_REG, port, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicStormFilterUnknownUnicastEnable ++ * Description: ++ * get per-port unknown unicast storm filter enable/disable ++ * Input: ++ * port - Physical port number (0~7) ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicStormFilterUnknownUnicastEnable(rtk_uint32 port, rtk_uint32 *pEnabled) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_STORM_UNKNOWN_UCAST_REG, port, pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicStormFilterUnknownUnicastMeter ++ * Description: ++ * Set per-port unknown unicast storm filter meter ++ * Input: ++ * port - Physical port number (0~7) ++ * meter - meter index (0~31) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_FILTER_METER_ID - Invalid meter index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicStormFilterUnknownUnicastMeter(rtk_uint32 port, rtk_uint32 meter) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ if(meter > RTL8367C_METERMAX) ++ return RT_ERR_FILTER_METER_ID; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_STORM_UNDA_METER_CTRL_REG(port), RTL8367C_STORM_UNDA_METER_CTRL_MASK(port), meter); ++} ++/* Function Name: ++ * rtl8367c_getAsicStormFilterUnknownUnicastMeter ++ * Description: ++ * Get per-port unknown unicast storm filter meter ++ * Input: ++ * port - Physical port number (0~7) ++ * pMeter - meter index (0~31) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicStormFilterUnknownUnicastMeter(rtk_uint32 port, rtk_uint32 *pMeter) ++{ ++ if(port >= RTL8367C_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_STORM_UNDA_METER_CTRL_REG(port), RTL8367C_STORM_UNDA_METER_CTRL_MASK(port), pMeter); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicStormFilterExtBroadcastMeter ++ * Description: ++ * Set extension broadcast storm filter meter ++ * Input: ++ * meter - meter index (0~31) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_FILTER_METER_ID - Invalid meter index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicStormFilterExtBroadcastMeter(rtk_uint32 meter) ++{ ++ if(meter > RTL8367C_METERMAX) ++ return RT_ERR_FILTER_METER_ID; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG0, RTL8367C_BC_STORM_EXT_METERIDX_MASK, meter); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicStormFilterExtBroadcastMeter ++ * Description: ++ * get extension broadcast storm filter meter ++ * Input: ++ * None ++ * Output: ++ * pMeter - meter index (0~31) ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NULL_POINTER - Invalid meter index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicStormFilterExtBroadcastMeter(rtk_uint32 *pMeter) ++{ ++ if(NULL == pMeter) ++ return RT_ERR_NULL_POINTER; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG0, RTL8367C_BC_STORM_EXT_METERIDX_MASK, pMeter); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicStormFilterExtMulticastMeter ++ * Description: ++ * Set extension multicast storm filter meter ++ * Input: ++ * meter - meter index (0~31) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_FILTER_METER_ID - Invalid meter index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicStormFilterExtMulticastMeter(rtk_uint32 meter) ++{ ++ if(meter > RTL8367C_METERMAX) ++ return RT_ERR_FILTER_METER_ID; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG0, RTL8367C_MC_STORM_EXT_METERIDX_MASK, meter); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicStormFilterExtMulticastMeter ++ * Description: ++ * get extension multicast storm filter meter ++ * Input: ++ * None ++ * Output: ++ * pMeter - meter index (0~31) ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NULL_POINTER - Invalid meter index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicStormFilterExtMulticastMeter(rtk_uint32 *pMeter) ++{ ++ if(NULL == pMeter) ++ return RT_ERR_NULL_POINTER; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG0, RTL8367C_MC_STORM_EXT_METERIDX_MASK, pMeter); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicStormFilterExtUnknownMulticastMeter ++ * Description: ++ * Set extension unknown multicast storm filter meter ++ * Input: ++ * meter - meter index (0~31) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_FILTER_METER_ID - Invalid meter index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicStormFilterExtUnknownMulticastMeter(rtk_uint32 meter) ++{ ++ if(meter > RTL8367C_METERMAX) ++ return RT_ERR_FILTER_METER_ID; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG1, RTL8367C_UNMC_STORM_EXT_METERIDX_MASK, meter); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicStormFilterExtUnknownMulticastMeter ++ * Description: ++ * get extension unknown multicast storm filter meter ++ * Input: ++ * None ++ * Output: ++ * pMeter - meter index (0~31) ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NULL_POINTER - Invalid meter index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicStormFilterExtUnknownMulticastMeter(rtk_uint32 *pMeter) ++{ ++ if(NULL == pMeter) ++ return RT_ERR_NULL_POINTER; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG1, RTL8367C_UNMC_STORM_EXT_METERIDX_MASK, pMeter); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicStormFilterExtUnknownUnicastMeter ++ * Description: ++ * Set extension unknown unicast storm filter meter ++ * Input: ++ * meter - meter index (0~31) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_FILTER_METER_ID - Invalid meter index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicStormFilterExtUnknownUnicastMeter(rtk_uint32 meter) ++{ ++ if(meter > RTL8367C_METERMAX) ++ return RT_ERR_FILTER_METER_ID; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG1, RTL8367C_UNUC_STORM_EXT_METERIDX_MASK, meter); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicStormFilterExtUnknownUnicastMeter ++ * Description: ++ * get extension unknown unicast storm filter meter ++ * Input: ++ * None ++ * Output: ++ * pMeter - meter index (0~31) ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NULL_POINTER - Invalid meter index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicStormFilterExtUnknownUnicastMeter(rtk_uint32 *pMeter) ++{ ++ if(NULL == pMeter) ++ return RT_ERR_NULL_POINTER; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_MTRIDX_CFG1, RTL8367C_UNUC_STORM_EXT_METERIDX_MASK, pMeter); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicStormFilterExtBroadcastEnable ++ * Description: ++ * Set extension broadcast storm filter state ++ * Input: ++ * enabled - state ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicStormFilterExtBroadcastEnable(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_BCAST_EXT_EN_OFFSET, enabled); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicStormFilterExtBroadcastEnable ++ * Description: ++ * Get extension broadcast storm filter state ++ * Input: ++ * None ++ * Output: ++ * pEnabled - state ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NULL_POINTER - Null pointer ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicStormFilterExtBroadcastEnable(rtk_uint32 *pEnabled) ++{ ++ if(NULL == pEnabled) ++ return RT_ERR_NULL_POINTER; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_BCAST_EXT_EN_OFFSET, pEnabled); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicStormFilterExtMulticastEnable ++ * Description: ++ * Set extension multicast storm filter state ++ * Input: ++ * enabled - state ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicStormFilterExtMulticastEnable(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_MCAST_EXT_EN_OFFSET, enabled); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicStormFilterExtMulticastEnable ++ * Description: ++ * Get extension multicast storm filter state ++ * Input: ++ * None ++ * Output: ++ * pEnabled - state ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NULL_POINTER - Null pointer ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicStormFilterExtMulticastEnable(rtk_uint32 *pEnabled) ++{ ++ if(NULL == pEnabled) ++ return RT_ERR_NULL_POINTER; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_MCAST_EXT_EN_OFFSET, pEnabled); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicStormFilterExtUnknownMulticastEnable ++ * Description: ++ * Set extension unknown multicast storm filter state ++ * Input: ++ * enabled - state ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicStormFilterExtUnknownMulticastEnable(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_UNKNOWN_MCAST_EXT_EN_OFFSET, enabled); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicStormFilterExtUnknownMulticastEnable ++ * Description: ++ * Get extension unknown multicast storm filter state ++ * Input: ++ * None ++ * Output: ++ * pEnabled - state ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NULL_POINTER - Null pointer ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicStormFilterExtUnknownMulticastEnable(rtk_uint32 *pEnabled) ++{ ++ if(NULL == pEnabled) ++ return RT_ERR_NULL_POINTER; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_UNKNOWN_MCAST_EXT_EN_OFFSET, pEnabled); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicStormFilterExtUnknownUnicastEnable ++ * Description: ++ * Set extension unknown unicast storm filter state ++ * Input: ++ * enabled - state ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicStormFilterExtUnknownUnicastEnable(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_UNKNOWN_UCAST_EXT_EN_OFFSET, enabled); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicStormFilterExtUnknownUnicastEnable ++ * Description: ++ * Get extension unknown unicast storm filter state ++ * Input: ++ * None ++ * Output: ++ * pEnabled - state ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NULL_POINTER - Null pointer ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicStormFilterExtUnknownUnicastEnable(rtk_uint32 *pEnabled) ++{ ++ if(NULL == pEnabled) ++ return RT_ERR_NULL_POINTER; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_UNKNOWN_UCAST_EXT_EN_OFFSET, pEnabled); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicStormFilterExtEnablePortMask ++ * Description: ++ * Set extension storm filter port mask ++ * Input: ++ * portmask - port mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicStormFilterExtEnablePortMask(rtk_uint32 portmask) ++{ ++ ret_t retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_EXT_EN_PORTMASK_MASK, portmask & 0x3FF); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_EXT_EN_PORTMASK_EXT_MASK, (portmask >> 10)&1); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicStormFilterExtEnablePortMask ++ * Description: ++ * Get extension storm filter port mask ++ * Input: ++ * portmask - port mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NULL_POINTER - Null pointer ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicStormFilterExtEnablePortMask(rtk_uint32 *pPortmask) ++{ ++ rtk_uint32 tmpPmsk; ++ ret_t retVal; ++ ++ if(NULL == pPortmask) ++ return RT_ERR_NULL_POINTER; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_EXT_EN_PORTMASK_MASK, &tmpPmsk); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ *pPortmask = tmpPmsk & 0x3ff; ++ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_STORM_EXT_CFG, RTL8367C_STORM_EXT_EN_PORTMASK_EXT_MASK, &tmpPmsk); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ *pPortmask |= (tmpPmsk & 1) << 10; ++ ++ return RT_ERR_OK; ++} ++ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_svlan.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_svlan.c +new file mode 100644 +index 0000000000..f19ceba5a9 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_svlan.c +@@ -0,0 +1,1003 @@ ++/* ++ * 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 : SVLAN related functions ++ * ++ */ ++#include ++ ++#include ++ ++static void _rtl8367c_svlanConfStUser2Smi( rtl8367c_svlan_memconf_t *pUserSt, rtk_uint16 *pSmiSt) ++{ ++ pSmiSt[0] |= (pUserSt->vs_member & 0x00FF); ++ pSmiSt[0] |= (pUserSt->vs_untag & 0x00FF) << 8; ++ ++ pSmiSt[1] |= (pUserSt->vs_fid_msti & 0x000F); ++ pSmiSt[1] |= (pUserSt->vs_priority & 0x0007) << 4; ++ pSmiSt[1] |= (pUserSt->vs_force_fid & 0x0001) << 7; ++ ++ pSmiSt[2] |= (pUserSt->vs_svid & 0x0FFF); ++ pSmiSt[2] |= (pUserSt->vs_efiden & 0x0001) << 12; ++ pSmiSt[2] |= (pUserSt->vs_efid & 0x0007) << 13; ++ ++ pSmiSt[3] |= ((pUserSt->vs_member & 0x0700) >> 8); ++ pSmiSt[3] |= ((pUserSt->vs_untag & 0x0700) >> 8) << 3; ++} ++ ++static void _rtl8367c_svlanConfStSmi2User( rtl8367c_svlan_memconf_t *pUserSt, rtk_uint16 *pSmiSt) ++{ ++ ++ pUserSt->vs_member = (pSmiSt[0] & 0x00FF) | ((pSmiSt[3] & 0x0007) << 8); ++ pUserSt->vs_untag = ((pSmiSt[0] & 0xFF00) >> 8) | (((pSmiSt[3] & 0x0038) >> 3) << 8); ++ ++ pUserSt->vs_fid_msti = (pSmiSt[1] & 0x000F); ++ pUserSt->vs_priority = (pSmiSt[1] & 0x0070) >> 4; ++ pUserSt->vs_force_fid = (pSmiSt[1] & 0x0080) >> 7; ++ ++ pUserSt->vs_svid = (pSmiSt[2] & 0x0FFF); ++ pUserSt->vs_efiden = (pSmiSt[2] & 0x1000) >> 12; ++ pUserSt->vs_efid = (pSmiSt[2] & 0xE000) >> 13; ++} ++ ++static void _rtl8367c_svlanMc2sStUser2Smi(rtl8367c_svlan_mc2s_t *pUserSt, rtk_uint16 *pSmiSt) ++{ ++ pSmiSt[0] |= (pUserSt->svidx & 0x003F); ++ pSmiSt[0] |= (pUserSt->format & 0x0001) << 6; ++ pSmiSt[0] |= (pUserSt->valid & 0x0001) << 7; ++ ++ pSmiSt[1] = (rtk_uint16)(pUserSt->smask & 0x0000FFFF); ++ pSmiSt[2] = (rtk_uint16)((pUserSt->smask & 0xFFFF0000) >> 16); ++ ++ pSmiSt[3] = (rtk_uint16)(pUserSt->sdata & 0x0000FFFF); ++ pSmiSt[4] = (rtk_uint16)((pUserSt->sdata & 0xFFFF0000) >> 16); ++} ++ ++static void _rtl8367c_svlanMc2sStSmi2User(rtl8367c_svlan_mc2s_t *pUserSt, rtk_uint16 *pSmiSt) ++{ ++ pUserSt->svidx = (pSmiSt[0] & 0x003F); ++ pUserSt->format = (pSmiSt[0] & 0x0040) >> 6; ++ pUserSt->valid = (pSmiSt[0] & 0x0080) >> 7; ++ ++ pUserSt->smask = pSmiSt[1] | (pSmiSt[2] << 16); ++ pUserSt->sdata = pSmiSt[3] | (pSmiSt[4] << 16); ++} ++ ++static void _rtl8367c_svlanSp2cStUser2Smi(rtl8367c_svlan_s2c_t *pUserSt, rtk_uint16 *pSmiSt) ++{ ++ pSmiSt[0] |= (pUserSt->dstport & 0x0007); ++ pSmiSt[0] |= (pUserSt->svidx & 0x003F) << 3; ++ pSmiSt[0] |= ((pUserSt->dstport & 0x0008) >> 3) << 9; ++ ++ pSmiSt[1] |= (pUserSt->vid & 0x0FFF); ++ pSmiSt[1] |= (pUserSt->valid & 0x0001) << 12; ++} ++ ++static void _rtl8367c_svlanSp2cStSmi2User(rtl8367c_svlan_s2c_t *pUserSt, rtk_uint16 *pSmiSt) ++{ ++ pUserSt->dstport = (((pSmiSt[0] & 0x0200) >> 9) << 3) | (pSmiSt[0] & 0x0007); ++ pUserSt->svidx = (pSmiSt[0] & 0x01F8) >> 3; ++ pUserSt->vid = (pSmiSt[1] & 0x0FFF); ++ pUserSt->valid = (pSmiSt[1] & 0x1000) >> 12; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicSvlanUplinkPortMask ++ * Description: ++ * Set uplink ports mask ++ * Input: ++ * portMask - Uplink port mask setting ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicSvlanUplinkPortMask(rtk_uint32 portMask) ++{ ++ return rtl8367c_setAsicReg(RTL8367C_REG_SVLAN_UPLINK_PORTMASK, portMask); ++} ++/* Function Name: ++ * rtl8367c_getAsicSvlanUplinkPortMask ++ * Description: ++ * Get uplink ports mask ++ * Input: ++ * pPortmask - Uplink port mask setting ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicSvlanUplinkPortMask(rtk_uint32* pPortmask) ++{ ++ return rtl8367c_getAsicReg(RTL8367C_REG_SVLAN_UPLINK_PORTMASK, pPortmask); ++} ++/* Function Name: ++ * rtl8367c_setAsicSvlanTpid ++ * Description: ++ * Set accepted S-VLAN ether type. The default ether type of S-VLAN is 0x88a8 ++ * Input: ++ * protocolType - Ether type of S-tag frame parsing in uplink ports ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * Ether type of S-tag in 802.1ad is 0x88a8 and there are existed ether type 0x9100 and 0x9200 ++ * for Q-in-Q SLAN design. User can set mathced ether type as service provider supported protocol ++ */ ++ret_t rtl8367c_setAsicSvlanTpid(rtk_uint32 protocolType) ++{ ++ return rtl8367c_setAsicReg(RTL8367C_REG_VS_TPID, protocolType); ++} ++/* Function Name: ++ * rtl8367c_getAsicReg ++ * Description: ++ * Get accepted S-VLAN ether type. The default ether type of S-VLAN is 0x88a8 ++ * Input: ++ * pProtocolType - Ether type of S-tag frame parsing in uplink ports ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicSvlanTpid(rtk_uint32* pProtocolType) ++{ ++ return rtl8367c_getAsicReg(RTL8367C_REG_VS_TPID, pProtocolType); ++} ++/* Function Name: ++ * rtl8367c_setAsicSvlanPrioritySel ++ * Description: ++ * Set SVLAN priority field setting ++ * Input: ++ * priSel - S-priority assignment method, 0:internal priority 1:C-tag priority 2:using Svlan member configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameter ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicSvlanPrioritySel(rtk_uint32 priSel) ++{ ++ if(priSel >= SPRISEL_END) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_SPRISEL_MASK, priSel); ++} ++/* Function Name: ++ * rtl8367c_getAsicSvlanPrioritySel ++ * Description: ++ * Get SVLAN priority field setting ++ * Input: ++ * pPriSel - S-priority assignment method, 0:internal priority 1:C-tag priority 2:using Svlan member configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicSvlanPrioritySel(rtk_uint32* pPriSel) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_SPRISEL_MASK, pPriSel); ++} ++/* Function Name: ++ * rtl8367c_setAsicSvlanTrapPriority ++ * Description: ++ * Set trap to CPU priority assignment ++ * Input: ++ * priority - Priority assignment ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicSvlanTrapPriority(rtk_uint32 priority) ++{ ++ if(priority > RTL8367C_PRIMAX) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_SVLAN_PRIOIRTY_MASK, priority); ++} ++/* Function Name: ++ * rtl8367c_getAsicSvlanTrapPriority ++ * Description: ++ * Get trap to CPU priority assignment ++ * Input: ++ * pPriority - Priority assignment ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicSvlanTrapPriority(rtk_uint32* pPriority) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_QOS_TRAP_PRIORITY0, RTL8367C_SVLAN_PRIOIRTY_MASK, pPriority); ++} ++/* Function Name: ++ * rtl8367c_setAsicSvlanDefaultVlan ++ * Description: ++ * Set default egress SVLAN ++ * Input: ++ * port - Physical port number (0~10) ++ * index - index SVLAN member configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_SVLAN_ENTRY_INDEX - Invalid SVLAN index parameter ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicSvlanDefaultVlan(rtk_uint32 port, rtk_uint32 index) ++{ ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(index > RTL8367C_SVIDXMAX) ++ return RT_ERR_SVLAN_ENTRY_INDEX; ++ ++ if(port < 8){ ++ if(port & 1) ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL0 + (port >> 1), RTL8367C_VS_PORT1_SVIDX_MASK,index); ++ else ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL0 + (port >> 1), RTL8367C_VS_PORT0_SVIDX_MASK,index); ++ }else{ ++ switch(port){ ++ case 8: ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL4, RTL8367C_VS_PORT8_SVIDX_MASK,index); ++ break; ++ ++ case 9: ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL4, RTL8367C_VS_PORT9_SVIDX_MASK,index); ++ break; ++ ++ case 10: ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL5, RTL8367C_SVLAN_PORTBASED_SVIDX_CTRL5_MASK,index); ++ break; ++ } ++ } ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicSvlanDefaultVlan ++ * Description: ++ * Get default egress SVLAN ++ * Input: ++ * port - Physical port number (0~7) ++ * pIndex - index SVLAN member configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicSvlanDefaultVlan(rtk_uint32 port, rtk_uint32* pIndex) ++{ ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(port < 8){ ++ if(port & 1) ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL0 + (port >> 1), RTL8367C_VS_PORT1_SVIDX_MASK,pIndex); ++ else ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL0 + (port >> 1), RTL8367C_VS_PORT0_SVIDX_MASK,pIndex); ++ }else{ ++ switch(port){ ++ case 8: ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL4, RTL8367C_VS_PORT8_SVIDX_MASK,pIndex); ++ break; ++ ++ case 9: ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL4, RTL8367C_VS_PORT9_SVIDX_MASK,pIndex); ++ break; ++ ++ case 10: ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_PORTBASED_SVIDX_CTRL5, RTL8367C_SVLAN_PORTBASED_SVIDX_CTRL5_MASK,pIndex); ++ break; ++ } ++ } ++ ++ return retVal; ++ ++} ++/* Function Name: ++ * rtl8367c_setAsicSvlanIngressUntag ++ * Description: ++ * Set action received un-Stag frame from unplink port ++ * Input: ++ * mode - 0:Drop 1:Trap 2:Assign SVLAN ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicSvlanIngressUntag(rtk_uint32 mode) ++{ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UNTAG_MASK, mode); ++} ++/* Function Name: ++ * rtl8367c_getAsicSvlanIngressUntag ++ * Description: ++ * Get action received un-Stag frame from unplink port ++ * Input: ++ * pMode - 0:Drop 1:Trap 2:Assign SVLAN ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicSvlanIngressUntag(rtk_uint32* pMode) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UNTAG_MASK, pMode); ++} ++/* Function Name: ++ * rtl8367c_setAsicSvlanIngressUnmatch ++ * Description: ++ * Set action received unmatched Stag frame from unplink port ++ * Input: ++ * mode - 0:Drop 1:Trap 2:Assign SVLAN ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicSvlanIngressUnmatch(rtk_uint32 mode) ++{ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UNMAT_MASK, mode); ++} ++/* Function Name: ++ * rtl8367c_getAsicSvlanIngressUnmatch ++ * Description: ++ * Get action received unmatched Stag frame from unplink port ++ * Input: ++ * pMode - 0:Drop 1:Trap 2:Assign SVLAN ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicSvlanIngressUnmatch(rtk_uint32* pMode) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UNMAT_MASK, pMode); ++ ++} ++/* Function Name: ++ * rtl8367c_setAsicSvlanEgressUnassign ++ * Description: ++ * Set unplink stream without egress SVID action ++ * Input: ++ * enabled - 1:Trap egress unassigned frames to CPU, 0: Use SVLAN setup in VS_CPSVIDX as egress SVID ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicSvlanEgressUnassign(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UIFSEG_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicSvlanEgressUnassign ++ * Description: ++ * Get unplink stream without egress SVID action ++ * Input: ++ * pEnabled - 1:Trap egress unassigned frames to CPU, 0: Use SVLAN setup in VS_CPSVIDX as egress SVID ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicSvlanEgressUnassign(rtk_uint32* pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_UIFSEG_OFFSET, pEnabled); ++} ++ ++ ++/* Function Name: ++ * rtl8367c_setAsicSvlanMemberConfiguration ++ * Description: ++ * Set system 64 S-tag content ++ * Input: ++ * index - index of 64 s-tag configuration ++ * pSvlanMemCfg - SVLAN member configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_ENTRY_INDEX - Invalid SVLAN index parameter ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicSvlanMemberConfiguration(rtk_uint32 index, rtl8367c_svlan_memconf_t* pSvlanMemCfg) ++{ ++ ret_t retVal; ++ rtk_uint32 regAddr, regData; ++ rtk_uint16 *accessPtr; ++ rtk_uint32 i; ++ rtk_uint16 smiSvlanMemConf[RTL8367C_SVLAN_MEMCONF_LEN]; ++ ++ if(index > RTL8367C_SVIDXMAX) ++ return RT_ERR_SVLAN_ENTRY_INDEX; ++ ++ memset(smiSvlanMemConf, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_MEMCONF_LEN); ++ _rtl8367c_svlanConfStUser2Smi(pSvlanMemCfg, smiSvlanMemConf); ++ ++ accessPtr = smiSvlanMemConf; ++ ++ regData = *accessPtr; ++ for(i = 0; i < 3; i++) ++ { ++ retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_MEMBERCFG_BASE_REG(index) + i, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ accessPtr ++; ++ regData = *accessPtr; ++ } ++ ++ if(index < 63) ++ regAddr = RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL4+index; ++ else if(index == 63) ++ regAddr = RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL4; ++ ++ retVal = rtl8367c_setAsicReg(regAddr, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++ ++} ++/* Function Name: ++ * rtl8367c_getAsicSvlanMemberConfiguration ++ * Description: ++ * Get system 64 S-tag content ++ * Input: ++ * index - index of 64 s-tag configuration ++ * pSvlanMemCfg - SVLAN member configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_ENTRY_INDEX - Invalid SVLAN index parameter ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicSvlanMemberConfiguration(rtk_uint32 index,rtl8367c_svlan_memconf_t* pSvlanMemCfg) ++{ ++ ret_t retVal; ++ rtk_uint32 regAddr,regData; ++ rtk_uint16 *accessPtr; ++ rtk_uint32 i; ++ rtk_uint16 smiSvlanMemConf[RTL8367C_SVLAN_MEMCONF_LEN]; ++ ++ if(index > RTL8367C_SVIDXMAX) ++ return RT_ERR_SVLAN_ENTRY_INDEX; ++ ++ memset(smiSvlanMemConf, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_MEMCONF_LEN); ++ ++ accessPtr = smiSvlanMemConf; ++ ++ for(i = 0; i < 3; i++) ++ { ++ retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_MEMBERCFG_BASE_REG(index) + i, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *accessPtr = regData; ++ ++ accessPtr ++; ++ } ++ ++ if(index < 63) ++ regAddr = RTL8367C_REG_SVLAN_MEMBERCFG0_CTRL4+index; ++ else if(index == 63) ++ regAddr = RTL8367C_REG_SVLAN_MEMBERCFG63_CTRL4; ++ ++ retVal = rtl8367c_getAsicReg(regAddr, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *accessPtr = regData; ++ ++ _rtl8367c_svlanConfStSmi2User(pSvlanMemCfg, smiSvlanMemConf); ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicSvlanC2SConf ++ * Description: ++ * Set SVLAN C2S table ++ * Input: ++ * index - index of 128 Svlan C2S configuration ++ * evid - Enhanced VID ++ * portmask - available c2s port mask ++ * svidx - index of 64 Svlan member configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_ENTRY_INDEX - Invalid entry index ++ * Note: ++ * ASIC will check upstream's VID and assign related SVID to mathed packet ++ */ ++ret_t rtl8367c_setAsicSvlanC2SConf(rtk_uint32 index, rtk_uint32 evid, rtk_uint32 portmask, rtk_uint32 svidx) ++{ ++ ret_t retVal; ++ ++ if(index > RTL8367C_C2SIDXMAX) ++ return RT_ERR_ENTRY_INDEX; ++ ++ retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index), svidx); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index) + 1, portmask); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index) + 2, evid); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicSvlanC2SConf ++ * Description: ++ * Get SVLAN C2S table ++ * Input: ++ * index - index of 128 Svlan C2S configuration ++ * pEvid - Enhanced VID ++ * pPortmask - available c2s port mask ++ * pSvidx - index of 64 Svlan member configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_ENTRY_INDEX - Invalid entry index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicSvlanC2SConf(rtk_uint32 index, rtk_uint32* pEvid, rtk_uint32* pPortmask, rtk_uint32* pSvidx) ++{ ++ ret_t retVal; ++ ++ if(index > RTL8367C_C2SIDXMAX) ++ return RT_ERR_ENTRY_INDEX; ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index), pSvidx); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index) + 1, pPortmask); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_C2SCFG_BASE_REG(index) + 2, pEvid); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicSvlanMC2SConf ++ * Description: ++ * Set system MC2S content ++ * Input: ++ * index - index of 32 SVLAN 32 MC2S configuration ++ * pSvlanMc2sCfg - SVLAN Multicast to SVLAN member configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_ENTRY_INDEX - Invalid entry index ++ * Note: ++ * If upstream packet is L2 multicast or IPv4 multicast packet and DMAC/DIP is matched MC2S ++ * configuration, ASIC will assign egress SVID to the packet ++ */ ++ret_t rtl8367c_setAsicSvlanMC2SConf(rtk_uint32 index,rtl8367c_svlan_mc2s_t* pSvlanMc2sCfg) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint16 *accessPtr; ++ rtk_uint32 i; ++ rtk_uint16 smiSvlanMC2S[RTL8367C_SVLAN_MC2S_LEN]; ++ ++ if(index > RTL8367C_MC2SIDXMAX) ++ return RT_ERR_ENTRY_INDEX; ++ ++ memset(smiSvlanMC2S, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_MC2S_LEN); ++ _rtl8367c_svlanMc2sStUser2Smi(pSvlanMc2sCfg, smiSvlanMC2S); ++ ++ accessPtr = smiSvlanMC2S; ++ ++ regData = *accessPtr; ++ for(i = 0; i < 5; i++) ++ { ++ retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_MCAST2S_ENTRY_BASE_REG(index) + i, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ accessPtr ++; ++ regData = *accessPtr; ++ } ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicSvlanMC2SConf ++ * Description: ++ * Get system MC2S content ++ * Input: ++ * index - index of 32 SVLAN 32 MC2S configuration ++ * pSvlanMc2sCfg - SVLAN Multicast to SVLAN member configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_ENTRY_INDEX - Invalid entry index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicSvlanMC2SConf(rtk_uint32 index, rtl8367c_svlan_mc2s_t* pSvlanMc2sCfg) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint16 *accessPtr; ++ rtk_uint32 i; ++ rtk_uint16 smiSvlanMC2S[RTL8367C_SVLAN_MC2S_LEN]; ++ ++ if(index > RTL8367C_MC2SIDXMAX) ++ return RT_ERR_ENTRY_INDEX; ++ ++ memset(smiSvlanMC2S, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_MC2S_LEN); ++ ++ accessPtr = smiSvlanMC2S; ++ ++ for(i = 0; i < 5; i++) ++ { ++ retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_MCAST2S_ENTRY_BASE_REG(index) + i, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *accessPtr = regData; ++ accessPtr ++; ++ } ++ ++ ++ _rtl8367c_svlanMc2sStSmi2User(pSvlanMc2sCfg, smiSvlanMC2S); ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicSvlanSP2CConf ++ * Description: ++ * Set system 128 SP2C content ++ * Input: ++ * index - index of 128 SVLAN & Port to CVLAN configuration ++ * pSvlanSp2cCfg - SVLAN & Port to CVLAN configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_ENTRY_INDEX - Invalid entry index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicSvlanSP2CConf(rtk_uint32 index, rtl8367c_svlan_s2c_t* pSvlanSp2cCfg) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint16 *accessPtr; ++ rtk_uint32 i; ++ rtk_uint16 smiSvlanSP2C[RTL8367C_SVLAN_SP2C_LEN]; ++ ++ if(index > RTL8367C_SP2CMAX) ++ return RT_ERR_ENTRY_INDEX; ++ ++ memset(smiSvlanSP2C, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_SP2C_LEN); ++ _rtl8367c_svlanSp2cStUser2Smi(pSvlanSp2cCfg,smiSvlanSP2C); ++ ++ accessPtr = smiSvlanSP2C; ++ ++ regData = *accessPtr; ++ for(i = 0; i < 2; i++) ++ { ++ retVal = rtl8367c_setAsicReg(RTL8367C_SVLAN_S2C_ENTRY_BASE_REG(index) + i, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ accessPtr ++; ++ regData = *accessPtr; ++ } ++ ++ return retVal; ++} ++/* Function Name: ++ * rtl8367c_getAsicSvlanSP2CConf ++ * Description: ++ * Get system 128 SP2C content ++ * Input: ++ * index - index of 128 SVLAN & Port to CVLAN configuration ++ * pSvlanSp2cCfg - SVLAN & Port to CVLAN configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_ENTRY_INDEX - Invalid entry index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicSvlanSP2CConf(rtk_uint32 index,rtl8367c_svlan_s2c_t* pSvlanSp2cCfg) ++{ ++ ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint16 *accessPtr; ++ rtk_uint32 i; ++ rtk_uint16 smiSvlanSP2C[RTL8367C_SVLAN_SP2C_LEN]; ++ ++ if(index > RTL8367C_SP2CMAX) ++ return RT_ERR_ENTRY_INDEX; ++ ++ memset(smiSvlanSP2C, 0x00, sizeof(rtk_uint16) * RTL8367C_SVLAN_SP2C_LEN); ++ ++ accessPtr = smiSvlanSP2C; ++ ++ for(i = 0; i < 2; i++) ++ { ++ retVal = rtl8367c_getAsicReg(RTL8367C_SVLAN_S2C_ENTRY_BASE_REG(index) + i, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *accessPtr = regData; ++ ++ accessPtr ++; ++ } ++ ++ _rtl8367c_svlanSp2cStSmi2User(pSvlanSp2cCfg, smiSvlanSP2C); ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicSvlanDmacCvidSel ++ * Description: ++ * Set downstream CVID decision by DMAC ++ * Input: ++ * port - Physical port number (0~7) ++ * enabled - 0:disabled, 1:enabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicSvlanDmacCvidSel(rtk_uint32 port, rtk_uint32 enabled) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(port < 8) ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_PORT0_DMACVIDSEL_OFFSET + port, enabled); ++ else ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_SVLAN_CFG_EXT, RTL8367C_VS_PORT8_DMACVIDSEL_OFFSET + (port-8), enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicSvlanDmacCvidSel ++ * Description: ++ * Get downstream CVID decision by DMAC ++ * Input: ++ * port - Physical port number (0~7) ++ * pEnabled - 0:disabled, 1:enabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicSvlanDmacCvidSel(rtk_uint32 port, rtk_uint32* pEnabled) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(port < 8) ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_SVLAN_CFG, RTL8367C_VS_PORT0_DMACVIDSEL_OFFSET + port, pEnabled); ++ else ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_SVLAN_CFG_EXT, RTL8367C_VS_PORT8_DMACVIDSEL_OFFSET + (port-8), pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicSvlanUntagVlan ++ * Description: ++ * Set default ingress untag SVLAN ++ * Input: ++ * index - index SVLAN member configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_ENTRY_INDEX - Invalid SVLAN index parameter ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicSvlanUntagVlan(rtk_uint32 index) ++{ ++ if(index > RTL8367C_SVIDXMAX) ++ return RT_ERR_SVLAN_ENTRY_INDEX; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_UNTAG_UNMAT_CFG, RTL8367C_VS_UNTAG_SVIDX_MASK, index); ++} ++/* Function Name: ++ * rtl8367c_getAsicSvlanUntagVlan ++ * Description: ++ * Get default ingress untag SVLAN ++ * Input: ++ * pIndex - index SVLAN member configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicSvlanUntagVlan(rtk_uint32* pIndex) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_UNTAG_UNMAT_CFG, RTL8367C_VS_UNTAG_SVIDX_MASK, pIndex); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicSvlanUnmatchVlan ++ * Description: ++ * Set default ingress unmatch SVLAN ++ * Input: ++ * index - index SVLAN member configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_ENTRY_INDEX - Invalid SVLAN index parameter ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicSvlanUnmatchVlan(rtk_uint32 index) ++{ ++ if(index > RTL8367C_SVIDXMAX) ++ return RT_ERR_SVLAN_ENTRY_INDEX; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_SVLAN_UNTAG_UNMAT_CFG, RTL8367C_VS_UNMAT_SVIDX_MASK, index); ++} ++/* Function Name: ++ * rtl8367c_getAsicSvlanUnmatchVlan ++ * Description: ++ * Get default ingress unmatch SVLAN ++ * Input: ++ * pIndex - index SVLAN member configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicSvlanUnmatchVlan(rtk_uint32* pIndex) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_SVLAN_UNTAG_UNMAT_CFG, RTL8367C_VS_UNMAT_SVIDX_MASK, pIndex); ++} ++ ++ ++/* Function Name: ++ * rtl8367c_setAsicSvlanLookupType ++ * Description: ++ * Set svlan lookup table selection ++ * Input: ++ * type - lookup type ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicSvlanLookupType(rtk_uint32 type) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_SVLAN_LOOKUP_TYPE, RTL8367C_SVLAN_LOOKUP_TYPE_OFFSET, type); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicSvlanLookupType ++ * Description: ++ * Get svlan lookup table selection ++ * Input: ++ * pType - lookup type ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicSvlanLookupType(rtk_uint32* pType) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_SVLAN_LOOKUP_TYPE, RTL8367C_SVLAN_LOOKUP_TYPE_OFFSET, pType); ++} ++ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_trunking.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_trunking.c +new file mode 100644 +index 0000000000..26d4c29b83 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_trunking.c +@@ -0,0 +1,356 @@ ++/* ++ * 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 : Port trunking related functions ++ * ++ */ ++ ++#include ++/* Function Name: ++ * rtl8367c_setAsicTrunkingMode ++ * Description: ++ * Set port trunking mode ++ * Input: ++ * mode - 1:dumb 0:user defined ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicTrunkingMode(rtk_uint32 mode) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_DUMB_OFFSET, mode); ++} ++/* Function Name: ++ * rtl8367c_getAsicTrunkingMode ++ * Description: ++ * Get port trunking mode ++ * Input: ++ * pMode - 1:dumb 0:user defined ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicTrunkingMode(rtk_uint32* pMode) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_DUMB_OFFSET, pMode); ++} ++/* Function Name: ++ * rtl8367c_setAsicTrunkingFc ++ * Description: ++ * Set port trunking flow control ++ * Input: ++ * group - Trunk Group ID ++ * enabled - 0:disable, 1:enable ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicTrunkingFc(rtk_uint32 group, rtk_uint32 enabled) ++{ ++ ret_t retVal; ++ ++ if(group > RTL8367C_MAX_TRUNK_GID) ++ return RT_ERR_LA_TRUNK_ID; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_PORT_TRUNK_DROP_CTRL, RTL8367C_PORT_TRUNK_DROP_CTRL_OFFSET, ENABLED)) != RT_ERR_OK) ++ return retVal; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_PORT_TRUNK_FLOWCTRL, (RTL8367C_EN_FLOWCTRL_TG0_OFFSET + group), enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicTrunkingFc ++ * Description: ++ * Get port trunking flow control ++ * Input: ++ * group - Trunk Group ID ++ * pEnabled - 0:disable, 1:enable ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicTrunkingFc(rtk_uint32 group, rtk_uint32* pEnabled) ++{ ++ if(group > RTL8367C_MAX_TRUNK_GID) ++ return RT_ERR_LA_TRUNK_ID; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_PORT_TRUNK_FLOWCTRL, (RTL8367C_EN_FLOWCTRL_TG0_OFFSET + group), pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicTrunkingGroup ++ * Description: ++ * Set trunking group available port mask ++ * Input: ++ * group - Trunk Group ID ++ * portmask - Logic trunking enable port mask, max 4 ports ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicTrunkingGroup(rtk_uint32 group, rtk_uint32 portmask) ++{ ++ if(group > RTL8367C_MAX_TRUNK_GID) ++ return RT_ERR_LA_TRUNK_ID; ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_GROUP_MASK, RTL8367C_PORT_TRUNK_GROUP0_MASK_MASK << (group * 4), portmask); ++} ++/* Function Name: ++ * rtl8367c_getAsicTrunkingGroup ++ * Description: ++ * Get trunking group available port mask ++ * Input: ++ * group - Trunk Group ID ++ * Output: ++ * pPortmask - Logic trunking enable port mask, max 4 ports ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicTrunkingGroup(rtk_uint32 group, rtk_uint32* pPortmask) ++{ ++ if(group > RTL8367C_MAX_TRUNK_GID) ++ return RT_ERR_LA_TRUNK_ID; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_GROUP_MASK, RTL8367C_PORT_TRUNK_GROUP0_MASK_MASK << (group * 4), pPortmask); ++} ++/* Function Name: ++ * rtl8367c_setAsicTrunkingFlood ++ * Description: ++ * Set port trunking flood function ++ * Input: ++ * enabled - Port trunking flooding function 0:disable 1:enable ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicTrunkingFlood(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_FLOOD_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicTrunkingFlood ++ * Description: ++ * Get port trunking flood function ++ * Input: ++ * pEnabled - Port trunking flooding function 0:disable 1:enable ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicTrunkingFlood(rtk_uint32* pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_FLOOD_OFFSET, pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicTrunkingHashSelect ++ * Description: ++ * Set port trunking hash select sources ++ * Input: ++ * hashsel - hash sources mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * 7 bits mask for link aggregation group0 hash parameter selection {DIP, SIP, DMAC, SMAC, SPA} ++ * 0b0000001: SPA ++ * 0b0000010: SMAC ++ * 0b0000100: DMAC ++ * 0b0001000: SIP ++ * 0b0010000: DIP ++ * 0b0100000: TCP/UDP Source Port ++ * 0b1000000: TCP/UDP Destination Port ++ */ ++ret_t rtl8367c_setAsicTrunkingHashSelect(rtk_uint32 hashsel) ++{ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_HASH_MASK, hashsel); ++} ++/* Function Name: ++ * rtl8367c_getAsicTrunkingHashSelect ++ * Description: ++ * Get port trunking hash select sources ++ * Input: ++ * pHashsel - hash sources mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicTrunkingHashSelect(rtk_uint32* pHashsel) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_CTRL, RTL8367C_PORT_TRUNK_HASH_MASK, pHashsel); ++} ++/* Function Name: ++ * rtl8367c_getAsicQeueuEmptyStatus ++ * Description: ++ * Get current output queue if empty status ++ * Input: ++ * portmask - queue empty port mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicQeueuEmptyStatus(rtk_uint32* portmask) ++{ ++ return rtl8367c_getAsicReg(RTL8367C_REG_PORT_QEMPTY, portmask); ++} ++/* Function Name: ++ * rtl8367c_setAsicTrunkingHashTable ++ * Description: ++ * Set port trunking hash value mapping table ++ * Input: ++ * hashval - hashing value 0-15 ++ * portId - trunking port id 0-3 ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_OUT_OF_RANGE - Invalid hashing value (0-15) ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicTrunkingHashTable(rtk_uint32 hashval, rtk_uint32 portId) ++{ ++ if(hashval > RTL8367C_TRUNKING_HASHVALUE_MAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(portId >= RTL8367C_TRUNKING_PORTNO) ++ return RT_ERR_PORT_ID; ++ ++ if(hashval >= 8) ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL1, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH8_MASK<<((hashval-8)*2), portId); ++ else ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL0, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH0_MASK<<(hashval*2), portId); ++} ++/* Function Name: ++ * rtl8367c_getAsicTrunkingHashTable ++ * Description: ++ * Get port trunking hash value mapping table ++ * Input: ++ * hashval - hashing value 0-15 ++ * pPortId - trunking port id 0-3 ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - Invalid hashing value (0-15) ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicTrunkingHashTable(rtk_uint32 hashval, rtk_uint32* pPortId) ++{ ++ if(hashval > RTL8367C_TRUNKING_HASHVALUE_MAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(hashval >= 8) ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL1, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL1_HASH8_MASK<<((hashval-8)*2), pPortId); ++ else ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL0, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL0_HASH0_MASK<<(hashval*2), pPortId); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicTrunkingHashTable1 ++ * Description: ++ * Set port trunking hash value mapping table ++ * Input: ++ * hashval - hashing value 0-15 ++ * portId - trunking port id 0-3 ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_OUT_OF_RANGE - Invalid hashing value (0-15) ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicTrunkingHashTable1(rtk_uint32 hashval, rtk_uint32 portId) ++{ ++ if(hashval > RTL8367C_TRUNKING_HASHVALUE_MAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(portId >= RTL8367C_TRUNKING1_PORTN0) ++ return RT_ERR_PORT_ID; ++ ++ if(hashval >= 8) ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL3, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH8_MASK<<((hashval-8)*2), portId); ++ else ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL2, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH0_MASK<<(hashval*2), portId); ++} ++/* Function Name: ++ * rtl8367c_getAsicTrunkingHashTable1 ++ * Description: ++ * Get port trunking hash value mapping table ++ * Input: ++ * hashval - hashing value 0-15 ++ * pPortId - trunking port id 0-3 ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_OUT_OF_RANGE - Invalid hashing value (0-15) ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicTrunkingHashTable1(rtk_uint32 hashval, rtk_uint32* pPortId) ++{ ++ if(hashval > RTL8367C_TRUNKING_HASHVALUE_MAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(hashval >= 8) ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL3, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL3_HASH8_MASK<<((hashval-8)*2), pPortId); ++ else ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_PORT_TRUNK_HASH_MAPPING_CTRL2, RTL8367C_PORT_TRUNK_HASH_MAPPING_CTRL2_HASH0_MASK<<(hashval*2), pPortId); ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_unknownMulticast.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_unknownMulticast.c +new file mode 100644 +index 0000000000..fcebd1b7f7 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_unknownMulticast.c +@@ -0,0 +1,238 @@ ++/* ++ * 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 : Unkown multicast related functions ++ * ++ */ ++ ++#include ++ ++/* Function Name: ++ * rtl8367c_setAsicUnknownL2MulticastBehavior ++ * Description: ++ * Set behavior of L2 multicast ++ * Input: ++ * port - Physical port number (0~7) ++ * behave - 0: flooding, 1: drop, 2: trap ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_NOT_ALLOWED - Invalid operation ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicUnknownL2MulticastBehavior(rtk_uint32 port, rtk_uint32 behave) ++{ ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(behave >= L2_UNKOWN_MULTICAST_END) ++ return RT_ERR_NOT_ALLOWED; ++ if(port < 8) ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_UNKNOWN_L2_MULTICAST_REG(port), RTL8367C_UNKNOWN_L2_MULTICAST_MASK(port), behave); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_UNKNOWN_L2_MULTICAST_CTRL1, 3 << ((port - 8) << 1), behave); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicUnknownL2MulticastBehavior ++ * Description: ++ * Get behavior of L2 multicast ++ * Input: ++ * port - Physical port number (0~7) ++ * pBehave - 0: flooding, 1: drop, 2: trap ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicUnknownL2MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave) ++{ ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(port < 8) ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_UNKNOWN_L2_MULTICAST_REG(port), RTL8367C_UNKNOWN_L2_MULTICAST_MASK(port), pBehave); ++ if (retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_UNKNOWN_L2_MULTICAST_CTRL1, 3 << ((port - 8) << 1), pBehave); ++ if (retVal != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicUnknownIPv4MulticastBehavior ++ * Description: ++ * Set behavior of IPv4 multicast ++ * Input: ++ * port - Physical port number (0~7) ++ * behave - 0: flooding, 1: drop, 2: trap ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_NOT_ALLOWED - Invalid operation ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicUnknownIPv4MulticastBehavior(rtk_uint32 port, rtk_uint32 behave) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(behave >= L3_UNKOWN_MULTICAST_END) ++ return RT_ERR_NOT_ALLOWED; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_UNKNOWN_IPV4_MULTICAST_REG(port), RTL8367C_UNKNOWN_IPV4_MULTICAST_MASK(port), behave); ++} ++/* Function Name: ++ * rtl8367c_getAsicUnknownIPv4MulticastBehavior ++ * Description: ++ * Get behavior of IPv4 multicast ++ * Input: ++ * port - Physical port number (0~7) ++ * pBehave - 0: flooding, 1: drop, 2: trap ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicUnknownIPv4MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_UNKNOWN_IPV4_MULTICAST_REG(port), RTL8367C_UNKNOWN_IPV4_MULTICAST_MASK(port), pBehave); ++} ++/* Function Name: ++ * rtl8367c_setAsicUnknownIPv6MulticastBehavior ++ * Description: ++ * Set behavior of IPv6 multicast ++ * Input: ++ * port - Physical port number (0~7) ++ * behave - 0: flooding, 1: drop, 2: trap ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_NOT_ALLOWED - Invalid operation ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicUnknownIPv6MulticastBehavior(rtk_uint32 port, rtk_uint32 behave) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(behave >= L3_UNKOWN_MULTICAST_END) ++ return RT_ERR_NOT_ALLOWED; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_UNKNOWN_IPV6_MULTICAST_REG(port), RTL8367C_UNKNOWN_IPV6_MULTICAST_MASK(port), behave); ++} ++/* Function Name: ++ * rtl8367c_getAsicUnknownIPv6MulticastBehavior ++ * Description: ++ * Get behavior of IPv6 multicast ++ * Input: ++ * port - Physical port number (0~7) ++ * pBehave - 0: flooding, 1: drop, 2: trap ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicUnknownIPv6MulticastBehavior(rtk_uint32 port, rtk_uint32 *pBehave) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_UNKNOWN_IPV6_MULTICAST_REG(port), RTL8367C_UNKNOWN_IPV6_MULTICAST_MASK(port), pBehave); ++} ++/* Function Name: ++ * rtl8367c_setAsicUnknownMulticastTrapPriority ++ * Description: ++ * Set trap priority of unknown multicast frame ++ * Input: ++ * priority - priority (0~7) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicUnknownMulticastTrapPriority(rtk_uint32 priority) ++{ ++ if(priority > RTL8367C_PRIMAX) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_QOS_TRAP_PRIORITY_CTRL0_REG, RTL8367C_UNKNOWN_MC_PRIORTY_MASK, priority); ++} ++/* Function Name: ++ * rtl8367c_getAsicUnknownMulticastTrapPriority ++ * Description: ++ * Get trap priority of unknown multicast frame ++ * Input: ++ * pPriority - priority (0~7) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicUnknownMulticastTrapPriority(rtk_uint32 *pPriority) ++{ ++ return rtl8367c_getAsicRegBits(RTL8367C_QOS_TRAP_PRIORITY_CTRL0_REG, RTL8367C_UNKNOWN_MC_PRIORTY_MASK, pPriority); ++} +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_vlan.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_vlan.c +new file mode 100644 +index 0000000000..1e283e7432 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/rtl8367c_asicdrv_vlan.c +@@ -0,0 +1,1505 @@ ++/* ++ * 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 : VLAN related functions ++ * ++ */ ++#include ++ ++#include ++ ++#if defined(CONFIG_RTL8367C_ASICDRV_TEST) ++rtl8367c_user_vlan4kentry Rtl8370sVirtualVlanTable[RTL8367C_VIDMAX + 1]; ++#endif ++ ++static void _rtl8367c_VlanMCStUser2Smi(rtl8367c_vlanconfiguser *pVlanCg, rtk_uint16 *pSmiVlanCfg) ++{ ++ pSmiVlanCfg[0] |= pVlanCg->mbr & 0x07FF; ++ ++ pSmiVlanCfg[1] |= pVlanCg->fid_msti & 0x000F; ++ ++ pSmiVlanCfg[2] |= pVlanCg->vbpen & 0x0001; ++ pSmiVlanCfg[2] |= (pVlanCg->vbpri & 0x0007) << 1; ++ pSmiVlanCfg[2] |= (pVlanCg->envlanpol & 0x0001) << 4; ++ pSmiVlanCfg[2] |= (pVlanCg->meteridx & 0x003F) << 5; ++ ++ pSmiVlanCfg[3] |= pVlanCg->evid & 0x1FFF; ++} ++ ++static void _rtl8367c_VlanMCStSmi2User(rtk_uint16 *pSmiVlanCfg, rtl8367c_vlanconfiguser *pVlanCg) ++{ ++ pVlanCg->mbr = pSmiVlanCfg[0] & 0x07FF; ++ pVlanCg->fid_msti = pSmiVlanCfg[1] & 0x000F; ++ pVlanCg->meteridx = (pSmiVlanCfg[2] >> 5) & 0x003F; ++ pVlanCg->envlanpol = (pSmiVlanCfg[2] >> 4) & 0x0001; ++ pVlanCg->vbpri = (pSmiVlanCfg[2] >> 1) & 0x0007; ++ pVlanCg->vbpen = pSmiVlanCfg[2] & 0x0001; ++ pVlanCg->evid = pSmiVlanCfg[3] & 0x1FFF; ++} ++ ++static void _rtl8367c_Vlan4kStUser2Smi(rtl8367c_user_vlan4kentry *pUserVlan4kEntry, rtk_uint16 *pSmiVlan4kEntry) ++{ ++ pSmiVlan4kEntry[0] |= (pUserVlan4kEntry->mbr & 0x00FF); ++ pSmiVlan4kEntry[0] |= (pUserVlan4kEntry->untag & 0x00FF) << 8; ++ ++ pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->fid_msti & 0x000F); ++ pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->vbpen & 0x0001) << 4; ++ pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->vbpri & 0x0007) << 5; ++ pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->envlanpol & 0x0001) << 8; ++ pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->meteridx & 0x001F) << 9; ++ pSmiVlan4kEntry[1] |= (pUserVlan4kEntry->ivl_svl & 0x0001) << 14; ++ ++ pSmiVlan4kEntry[2] |= ((pUserVlan4kEntry->mbr & 0x0700) >> 8); ++ pSmiVlan4kEntry[2] |= ((pUserVlan4kEntry->untag & 0x0700) >> 8) << 3; ++ pSmiVlan4kEntry[2] |= ((pUserVlan4kEntry->meteridx & 0x0020) >> 5) << 6; ++} ++ ++ ++static void _rtl8367c_Vlan4kStSmi2User(rtk_uint16 *pSmiVlan4kEntry, rtl8367c_user_vlan4kentry *pUserVlan4kEntry) ++{ ++ pUserVlan4kEntry->mbr = (pSmiVlan4kEntry[0] & 0x00FF) | ((pSmiVlan4kEntry[2] & 0x0007) << 8); ++ pUserVlan4kEntry->untag = ((pSmiVlan4kEntry[0] & 0xFF00) >> 8) | (((pSmiVlan4kEntry[2] & 0x0038) >> 3) << 8); ++ pUserVlan4kEntry->fid_msti = pSmiVlan4kEntry[1] & 0x000F; ++ pUserVlan4kEntry->vbpen = (pSmiVlan4kEntry[1] & 0x0010) >> 4; ++ pUserVlan4kEntry->vbpri = (pSmiVlan4kEntry[1] & 0x00E0) >> 5; ++ pUserVlan4kEntry->envlanpol = (pSmiVlan4kEntry[1] & 0x0100) >> 8; ++ pUserVlan4kEntry->meteridx = ((pSmiVlan4kEntry[1] & 0x3E00) >> 9) | (((pSmiVlan4kEntry[2] & 0x0040) >> 6) << 5); ++ pUserVlan4kEntry->ivl_svl = (pSmiVlan4kEntry[1] & 0x4000) >> 14; ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicVlanMemberConfig ++ * Description: ++ * Set 32 VLAN member configurations ++ * Input: ++ * index - VLAN member configuration index (0~31) ++ * pVlanCg - VLAN member configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameter ++ * RT_ERR_L2_FID - Invalid FID ++ * RT_ERR_PORT_MASK - Invalid portmask ++ * RT_ERR_FILTER_METER_ID - Invalid meter ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * RT_ERR_VLAN_ENTRY_NOT_FOUND - Invalid VLAN member configuration index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicVlanMemberConfig(rtk_uint32 index, rtl8367c_vlanconfiguser *pVlanCg) ++{ ++ ret_t retVal; ++ rtk_uint32 regAddr; ++ rtk_uint32 regData; ++ rtk_uint16 *tableAddr; ++ rtk_uint32 page_idx; ++ rtk_uint16 smi_vlancfg[RTL8367C_VLAN_MBRCFG_LEN]; ++ ++ /* Error Checking */ ++ if(index > RTL8367C_CVIDXMAX) ++ return RT_ERR_VLAN_ENTRY_NOT_FOUND; ++ ++ if(pVlanCg->evid > RTL8367C_EVIDMAX) ++ return RT_ERR_INPUT; ++ ++ ++ if(pVlanCg->mbr > RTL8367C_PORTMASK) ++ return RT_ERR_PORT_MASK; ++ ++ if(pVlanCg->fid_msti > RTL8367C_FIDMAX) ++ return RT_ERR_L2_FID; ++ ++ if(pVlanCg->meteridx > RTL8367C_METERMAX) ++ return RT_ERR_FILTER_METER_ID; ++ ++ if(pVlanCg->vbpri > RTL8367C_PRIMAX) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ memset(smi_vlancfg, 0x00, sizeof(rtk_uint16) * RTL8367C_VLAN_MBRCFG_LEN); ++ _rtl8367c_VlanMCStUser2Smi(pVlanCg, smi_vlancfg); ++ tableAddr = smi_vlancfg; ++ ++ for(page_idx = 0; page_idx < 4; page_idx++) /* 4 pages per VLAN Member Config */ ++ { ++ regAddr = RTL8367C_VLAN_MEMBER_CONFIGURATION_BASE + (index * 4) + page_idx; ++ regData = *tableAddr; ++ ++ retVal = rtl8367c_setAsicReg(regAddr, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ tableAddr++; ++ } ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicVlanMemberConfig ++ * Description: ++ * Get 32 VLAN member configurations ++ * Input: ++ * index - VLAN member configuration index (0~31) ++ * pVlanCg - VLAN member configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameter ++ * RT_ERR_VLAN_ENTRY_NOT_FOUND - Invalid VLAN member configuration index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicVlanMemberConfig(rtk_uint32 index, rtl8367c_vlanconfiguser *pVlanCg) ++{ ++ ret_t retVal; ++ rtk_uint32 page_idx; ++ rtk_uint32 regAddr; ++ rtk_uint32 regData; ++ rtk_uint16 *tableAddr; ++ rtk_uint16 smi_vlancfg[RTL8367C_VLAN_MBRCFG_LEN]; ++ ++ if(index > RTL8367C_CVIDXMAX) ++ return RT_ERR_VLAN_ENTRY_NOT_FOUND; ++ ++ memset(smi_vlancfg, 0x00, sizeof(rtk_uint16) * RTL8367C_VLAN_MBRCFG_LEN); ++ tableAddr = smi_vlancfg; ++ ++ for(page_idx = 0; page_idx < 4; page_idx++) /* 4 pages per VLAN Member Config */ ++ { ++ regAddr = RTL8367C_VLAN_MEMBER_CONFIGURATION_BASE + (index * 4) + page_idx; ++ ++ retVal = rtl8367c_getAsicReg(regAddr, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *tableAddr = (rtk_uint16)regData; ++ tableAddr++; ++ } ++ ++ _rtl8367c_VlanMCStSmi2User(smi_vlancfg, pVlanCg); ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicVlan4kEntry ++ * Description: ++ * Set VID mapped entry to 4K VLAN table ++ * Input: ++ * pVlan4kEntry - 4K VLAN configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameter ++ * RT_ERR_L2_FID - Invalid FID ++ * RT_ERR_VLAN_VID - Invalid VID parameter (0~4095) ++ * RT_ERR_PORT_MASK - Invalid portmask ++ * RT_ERR_FILTER_METER_ID - Invalid meter ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicVlan4kEntry(rtl8367c_user_vlan4kentry *pVlan4kEntry ) ++{ ++ rtk_uint16 vlan_4k_entry[RTL8367C_VLAN_4KTABLE_LEN]; ++ rtk_uint32 page_idx; ++ rtk_uint16 *tableAddr; ++ ret_t retVal; ++ rtk_uint32 regData; ++ ++ if(pVlan4kEntry->vid > RTL8367C_VIDMAX) ++ return RT_ERR_VLAN_VID; ++ ++ if(pVlan4kEntry->mbr > RTL8367C_PORTMASK) ++ return RT_ERR_PORT_MASK; ++ ++ if(pVlan4kEntry->untag > RTL8367C_PORTMASK) ++ return RT_ERR_PORT_MASK; ++ ++ if(pVlan4kEntry->fid_msti > RTL8367C_FIDMAX) ++ return RT_ERR_L2_FID; ++ ++ if(pVlan4kEntry->meteridx > RTL8367C_METERMAX) ++ return RT_ERR_FILTER_METER_ID; ++ ++ if(pVlan4kEntry->vbpri > RTL8367C_PRIMAX) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ memset(vlan_4k_entry, 0x00, sizeof(rtk_uint16) * RTL8367C_VLAN_4KTABLE_LEN); ++ _rtl8367c_Vlan4kStUser2Smi(pVlan4kEntry, vlan_4k_entry); ++ ++ /* Prepare Data */ ++ tableAddr = vlan_4k_entry; ++ for(page_idx = 0; page_idx < RTL8367C_VLAN_4KTABLE_LEN; page_idx++) ++ { ++ regData = *tableAddr; ++ retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_WRDATA_BASE + page_idx, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ tableAddr++; ++ } ++ ++ /* Write Address (VLAN_ID) */ ++ regData = pVlan4kEntry->vid; ++ retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_ADDR_REG, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /* Write Command */ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_TABLE_ACCESS_CTRL_REG, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK,RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_WRITE,TB_TARGET_CVLAN)); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++#if defined(CONFIG_RTL8367C_ASICDRV_TEST) ++ memcpy(&Rtl8370sVirtualVlanTable[pVlan4kEntry->vid], pVlan4kEntry, sizeof(rtl8367c_user_vlan4kentry)); ++#endif ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicVlan4kEntry ++ * Description: ++ * Get VID mapped entry to 4K VLAN table ++ * Input: ++ * pVlan4kEntry - 4K VLAN configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_VLAN_VID - Invalid VID parameter (0~4095) ++ * RT_ERR_BUSYWAIT_TIMEOUT - LUT is busy at retrieving ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicVlan4kEntry(rtl8367c_user_vlan4kentry *pVlan4kEntry ) ++{ ++ rtk_uint16 vlan_4k_entry[RTL8367C_VLAN_4KTABLE_LEN]; ++ rtk_uint32 page_idx; ++ rtk_uint16 *tableAddr; ++ ret_t retVal; ++ rtk_uint32 regData; ++ rtk_uint32 busyCounter; ++ ++ if(pVlan4kEntry->vid > RTL8367C_VIDMAX) ++ return RT_ERR_VLAN_VID; ++ ++ /* Polling status */ ++ busyCounter = RTL8367C_VLAN_BUSY_CHECK_NO; ++ while(busyCounter) ++ { ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ if(regData == 0) ++ break; ++ ++ busyCounter --; ++ if(busyCounter == 0) ++ return RT_ERR_BUSYWAIT_TIMEOUT; ++ } ++ ++ /* Write Address (VLAN_ID) */ ++ regData = pVlan4kEntry->vid; ++ retVal = rtl8367c_setAsicReg(RTL8367C_TABLE_ACCESS_ADDR_REG, regData); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /* Read Command */ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_TABLE_ACCESS_CTRL_REG, RTL8367C_TABLE_TYPE_MASK | RTL8367C_COMMAND_TYPE_MASK, RTL8367C_TABLE_ACCESS_REG_DATA(TB_OP_READ,TB_TARGET_CVLAN)); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /* Polling status */ ++ busyCounter = RTL8367C_VLAN_BUSY_CHECK_NO; ++ while(busyCounter) ++ { ++ retVal = rtl8367c_getAsicRegBit(RTL8367C_TABLE_ACCESS_STATUS_REG, RTL8367C_TABLE_LUT_ADDR_BUSY_FLAG_OFFSET,®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ if(regData == 0) ++ break; ++ ++ busyCounter --; ++ if(busyCounter == 0) ++ return RT_ERR_BUSYWAIT_TIMEOUT; ++ } ++ ++ /* Read VLAN data from register */ ++ tableAddr = vlan_4k_entry; ++ for(page_idx = 0; page_idx < RTL8367C_VLAN_4KTABLE_LEN; page_idx++) ++ { ++ retVal = rtl8367c_getAsicReg(RTL8367C_TABLE_ACCESS_RDDATA_BASE + page_idx, ®Data); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *tableAddr = regData; ++ tableAddr++; ++ } ++ ++ _rtl8367c_Vlan4kStSmi2User(vlan_4k_entry, pVlan4kEntry); ++ ++#if defined(CONFIG_RTL8367C_ASICDRV_TEST) ++ memcpy(pVlan4kEntry, &Rtl8370sVirtualVlanTable[pVlan4kEntry->vid], sizeof(rtl8367c_user_vlan4kentry)); ++#endif ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicVlanAccpetFrameType ++ * Description: ++ * Set per-port acceptable frame type ++ * Input: ++ * port - Physical port number (0~10) ++ * frameType - The acceptable frame type ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_VLAN_ACCEPT_FRAME_TYPE - Invalid frame type ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicVlanAccpetFrameType(rtk_uint32 port, rtl8367c_accframetype frameType) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(frameType >= FRAME_TYPE_MAX_BOUND) ++ return RT_ERR_VLAN_ACCEPT_FRAME_TYPE; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_VLAN_ACCEPT_FRAME_TYPE_REG(port), RTL8367C_VLAN_ACCEPT_FRAME_TYPE_MASK(port), frameType); ++} ++/* Function Name: ++ * rtl8367c_getAsicVlanAccpetFrameType ++ * Description: ++ * Get per-port acceptable frame type ++ * Input: ++ * port - Physical port number (0~10) ++ * pFrameType - The acceptable frame type ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_VLAN_ACCEPT_FRAME_TYPE - Invalid frame type ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicVlanAccpetFrameType(rtk_uint32 port, rtl8367c_accframetype *pFrameType) ++{ ++ rtk_uint32 regData; ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_VLAN_ACCEPT_FRAME_TYPE_REG(port), RTL8367C_VLAN_ACCEPT_FRAME_TYPE_MASK(port), ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ *pFrameType = (rtl8367c_accframetype)regData; ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicVlanIngressFilter ++ * Description: ++ * Set VLAN Ingress Filter ++ * Input: ++ * port - Physical port number (0~10) ++ * enabled - Enable or disable Ingress filter ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicVlanIngressFilter(rtk_uint32 port, rtk_uint32 enabled) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_VLAN_INGRESS_REG, port, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicVlanIngressFilter ++ * Description: ++ * Get VLAN Ingress Filter ++ * Input: ++ * port - Physical port number (0~10) ++ * pEnable - Enable or disable Ingress filter ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicVlanIngressFilter(rtk_uint32 port, rtk_uint32 *pEnable) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_VLAN_INGRESS_REG, port, pEnable); ++} ++/* Function Name: ++ * rtl8367c_setAsicVlanEgressTagMode ++ * Description: ++ * Set CVLAN egress tag mode ++ * Input: ++ * port - Physical port number (0~10) ++ * tagMode - The egress tag mode. Including Original mode, Keep tag mode and Priority tag mode ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameter ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicVlanEgressTagMode(rtk_uint32 port, rtl8367c_egtagmode tagMode) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(tagMode >= EG_TAG_MODE_END) ++ return RT_ERR_INPUT; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_VLAN_EGRESS_MDOE_MASK, tagMode); ++} ++/* Function Name: ++ * rtl8367c_getAsicVlanEgressTagMode ++ * Description: ++ * Get CVLAN egress tag mode ++ * Input: ++ * port - Physical port number (0~10) ++ * pTagMode - The egress tag mode. Including Original mode, Keep tag mode and Priority tag mode ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicVlanEgressTagMode(rtk_uint32 port, rtl8367c_egtagmode *pTagMode) ++{ ++ rtk_uint32 regData; ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if((retVal = rtl8367c_getAsicRegBits(RTL8367C_PORT_MISC_CFG_REG(port), RTL8367C_VLAN_EGRESS_MDOE_MASK, ®Data)) != RT_ERR_OK) ++ return retVal; ++ ++ *pTagMode = (rtl8367c_egtagmode)regData; ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicVlanPortBasedVID ++ * Description: ++ * Set port based VID which is indexed to 32 VLAN member configurations ++ * Input: ++ * port - Physical port number (0~10) ++ * index - Index to VLAN member configuration ++ * pri - 1Q Port based VLAN priority ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * RT_ERR_VLAN_ENTRY_NOT_FOUND - Invalid VLAN member configuration index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicVlanPortBasedVID(rtk_uint32 port, rtk_uint32 index, rtk_uint32 pri) ++{ ++ rtk_uint32 regAddr, bit_mask; ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(index > RTL8367C_CVIDXMAX) ++ return RT_ERR_VLAN_ENTRY_NOT_FOUND; ++ ++ if(pri > RTL8367C_PRIMAX) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ regAddr = RTL8367C_VLAN_PVID_CTRL_REG(port); ++ bit_mask = RTL8367C_PORT_VIDX_MASK(port); ++ retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, index); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ regAddr = RTL8367C_VLAN_PORTBASED_PRIORITY_REG(port); ++ bit_mask = RTL8367C_VLAN_PORTBASED_PRIORITY_MASK(port); ++ retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, pri); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicVlanPortBasedVID ++ * Description: ++ * Get port based VID which is indexed to 32 VLAN member configurations ++ * Input: ++ * port - Physical port number (0~10) ++ * pIndex - Index to VLAN member configuration ++ * pPri - 1Q Port based VLAN priority ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicVlanPortBasedVID(rtk_uint32 port, rtk_uint32 *pIndex, rtk_uint32 *pPri) ++{ ++ rtk_uint32 regAddr,bit_mask; ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ regAddr = RTL8367C_VLAN_PVID_CTRL_REG(port); ++ bit_mask = RTL8367C_PORT_VIDX_MASK(port); ++ retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, pIndex); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ regAddr = RTL8367C_VLAN_PORTBASED_PRIORITY_REG(port); ++ bit_mask = RTL8367C_VLAN_PORTBASED_PRIORITY_MASK(port); ++ retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, pPri); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicVlanProtocolBasedGroupData ++ * Description: ++ * Set protocol and port based group database ++ * Input: ++ * index - Index to VLAN member configuration ++ * pPbCfg - Protocol and port based group database entry ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameter ++ * RT_ERR_VLAN_PROTO_AND_PORT - Invalid protocol base group database index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicVlanProtocolBasedGroupData(rtk_uint32 index, rtl8367c_protocolgdatacfg *pPbCfg) ++{ ++ rtk_uint32 frameType; ++ rtk_uint32 etherType; ++ ret_t retVal; ++ ++ /* Error Checking */ ++ if(index > RTL8367C_PROTOVLAN_GIDX_MAX) ++ return RT_ERR_VLAN_PROTO_AND_PORT; ++ ++ if(pPbCfg->frameType >= PPVLAN_FRAME_TYPE_END ) ++ return RT_ERR_INPUT; ++ ++ frameType = pPbCfg->frameType; ++ etherType = pPbCfg->etherType; ++ ++ /* Frame type */ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_VLAN_PPB_FRAMETYPE_REG(index), RTL8367C_VLAN_PPB_FRAMETYPE_MASK, frameType); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /* Ether type */ ++ retVal = rtl8367c_setAsicReg(RTL8367C_VLAN_PPB_ETHERTYPR_REG(index), etherType); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicVlanProtocolBasedGroupData ++ * Description: ++ * Get protocol and port based group database ++ * Input: ++ * index - Index to VLAN member configuration ++ * pPbCfg - Protocol and port based group database entry ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameter ++ * RT_ERR_VLAN_PROTO_AND_PORT - Invalid protocol base group database index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicVlanProtocolBasedGroupData(rtk_uint32 index, rtl8367c_protocolgdatacfg *pPbCfg) ++{ ++ rtk_uint32 frameType; ++ rtk_uint32 etherType; ++ ret_t retVal; ++ ++ /* Error Checking */ ++ if(index > RTL8367C_PROTOVLAN_GIDX_MAX) ++ return RT_ERR_VLAN_PROTO_AND_PORT; ++ ++ /* Read Frame type */ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_VLAN_PPB_FRAMETYPE_REG(index), RTL8367C_VLAN_PPB_FRAMETYPE_MASK, &frameType); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /* Read Ether type */ ++ retVal = rtl8367c_getAsicReg(RTL8367C_VLAN_PPB_ETHERTYPR_REG(index), ðerType); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ ++ pPbCfg->frameType = frameType; ++ pPbCfg->etherType = etherType; ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicVlanPortAndProtocolBased ++ * Description: ++ * Set protocol and port based VLAN configuration ++ * Input: ++ * port - Physical port number (0~10) ++ * index - Index of protocol and port based database index ++ * pPpbCfg - Protocol and port based VLAN configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameter ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_QOS_INT_PRIORITY - Invalid priority ++ * RT_ERR_VLAN_PROTO_AND_PORT - Invalid protocol base group database index ++ * RT_ERR_VLAN_ENTRY_NOT_FOUND - Invalid VLAN member configuration index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicVlanPortAndProtocolBased(rtk_uint32 port, rtk_uint32 index, rtl8367c_protocolvlancfg *pPpbCfg) ++{ ++ rtk_uint32 reg_addr, bit_mask, bit_value; ++ ret_t retVal; ++ ++ /* Error Checking */ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(index > RTL8367C_PROTOVLAN_GIDX_MAX) ++ return RT_ERR_VLAN_PROTO_AND_PORT; ++ ++ if( (pPpbCfg->valid != FALSE) && (pPpbCfg->valid != TRUE) ) ++ return RT_ERR_INPUT; ++ ++ if(pPpbCfg->vlan_idx > RTL8367C_CVIDXMAX) ++ return RT_ERR_VLAN_ENTRY_NOT_FOUND; ++ ++ if(pPpbCfg->priority > RTL8367C_PRIMAX) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ /* Valid bit */ ++ reg_addr = RTL8367C_VLAN_PPB_VALID_REG(index); ++ bit_mask = 0x0001 << port; ++ bit_value = ((TRUE == pPpbCfg->valid) ? 0x1 : 0x0); ++ retVal = rtl8367c_setAsicRegBits(reg_addr, bit_mask, bit_value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /* Calculate the actual register address for CVLAN index*/ ++ if(port < 8) ++ { ++ reg_addr = RTL8367C_VLAN_PPB_CTRL_REG(index, port); ++ bit_mask = RTL8367C_VLAN_PPB_CTRL_MASK(port); ++ } ++ else if(port == 8) ++ { ++ reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; ++ bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT8_INDEX_MASK; ++ } ++ else if(port == 9) ++ { ++ reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; ++ bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT9_INDEX_MASK; ++ } ++ else if(port == 10) ++ { ++ reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; ++ bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT10_INDEX_MASK; ++ } ++ ++ bit_value = pPpbCfg->vlan_idx; ++ retVal = rtl8367c_setAsicRegBits(reg_addr, bit_mask, bit_value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ /* write priority */ ++ reg_addr = RTL8367C_VLAN_PPB_PRIORITY_ITEM_REG(port, index); ++ bit_mask = RTL8367C_VLAN_PPB_PRIORITY_ITEM_MASK(port); ++ bit_value = pPpbCfg->priority; ++ retVal = rtl8367c_setAsicRegBits(reg_addr, bit_mask, bit_value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_getAsicVlanPortAndProtocolBased ++ * Description: ++ * Get protocol and port based VLAN configuration ++ * Input: ++ * port - Physical port number (0~7) ++ * index - Index of protocol and port based database index ++ * pPpbCfg - Protocol and port based VLAN configuration ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameter ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_VLAN_PROTO_AND_PORT - Invalid protocol base group database index ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicVlanPortAndProtocolBased(rtk_uint32 port, rtk_uint32 index, rtl8367c_protocolvlancfg *pPpbCfg) ++{ ++ rtk_uint32 reg_addr, bit_mask, bit_value; ++ ret_t retVal; ++ ++ /* Error Checking */ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(index > RTL8367C_PROTOVLAN_GIDX_MAX) ++ return RT_ERR_VLAN_PROTO_AND_PORT; ++ ++ if(pPpbCfg == NULL) ++ return RT_ERR_INPUT; ++ ++ /* Valid bit */ ++ reg_addr = RTL8367C_VLAN_PPB_VALID_REG(index); ++ bit_mask = 0x0001 << port; ++ retVal = rtl8367c_getAsicRegBits(reg_addr, bit_mask, &bit_value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pPpbCfg->valid = bit_value; ++ ++ /* CVLAN index */ ++ if(port < 8) ++ { ++ reg_addr = RTL8367C_VLAN_PPB_CTRL_REG(index, port); ++ bit_mask = RTL8367C_VLAN_PPB_CTRL_MASK(port); ++ } ++ else if(port == 8) ++ { ++ reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; ++ bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT8_INDEX_MASK; ++ } ++ else if(port == 9) ++ { ++ reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; ++ bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT9_INDEX_MASK; ++ } ++ else if(port == 10) ++ { ++ reg_addr = RTL8367C_REG_VLAN_PPB0_CTRL4; ++ bit_mask = RTL8367C_VLAN_PPB0_CTRL4_PORT10_INDEX_MASK; ++ } ++ ++ retVal = rtl8367c_getAsicRegBits(reg_addr, bit_mask, &bit_value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pPpbCfg->vlan_idx = bit_value; ++ ++ ++ /* priority */ ++ reg_addr = RTL8367C_VLAN_PPB_PRIORITY_ITEM_REG(port,index); ++ bit_mask = RTL8367C_VLAN_PPB_PRIORITY_ITEM_MASK(port); ++ retVal = rtl8367c_getAsicRegBits(reg_addr, bit_mask, &bit_value); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ pPpbCfg->priority = bit_value; ++ return RT_ERR_OK; ++} ++/* Function Name: ++ * rtl8367c_setAsicVlanFilter ++ * Description: ++ * Set enable CVLAN filtering function ++ * Input: ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicVlanFilter(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_VLAN_CTRL, RTL8367C_VLAN_CTRL_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicVlanFilter ++ * Description: ++ * Get enable CVLAN filtering function ++ * Input: ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicVlanFilter(rtk_uint32* pEnabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_VLAN_CTRL, RTL8367C_VLAN_CTRL_OFFSET, pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicVlanUntagDscpPriorityEn ++ * Description: ++ * Set enable Dscp to untag 1Q priority ++ * Input: ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicVlanUntagDscpPriorityEn(rtk_uint32 enabled) ++{ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_UNTAG_DSCP_PRI_CFG, RTL8367C_UNTAG_DSCP_PRI_CFG_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicVlanUntagDscpPriorityEn ++ * Description: ++ * Get enable Dscp to untag 1Q priority ++ * Input: ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicVlanUntagDscpPriorityEn(rtk_uint32* enabled) ++{ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_UNTAG_DSCP_PRI_CFG, RTL8367C_UNTAG_DSCP_PRI_CFG_OFFSET, enabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicPortBasedFid ++ * Description: ++ * Set port based FID ++ * Input: ++ * port - Physical port number (0~10) ++ * fid - Port based fid ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_L2_FID - Invalid FID ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortBasedFid(rtk_uint32 port, rtk_uint32 fid) ++{ ++ rtk_uint32 reg_addr; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(fid > RTL8367C_FIDMAX) ++ return RT_ERR_L2_FID; ++ ++ if(port < 8) ++ return rtl8367c_setAsicReg(RTL8367C_PORT_PBFID_REG(port),fid); ++ else { ++ reg_addr = RTL8367C_REG_PORT8_PBFID + port-8; ++ return rtl8367c_setAsicReg(reg_addr, fid); ++ } ++ ++} ++/* Function Name: ++ * rtl8367c_getAsicPortBasedFid ++ * Description: ++ * Get port based FID ++ * Input: ++ * port - Physical port number (0~7) ++ * pFid - Port based fid ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortBasedFid(rtk_uint32 port, rtk_uint32* pFid) ++{ ++ rtk_uint32 reg_addr; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(port < 8) ++ return rtl8367c_getAsicReg(RTL8367C_PORT_PBFID_REG(port), pFid); ++ else{ ++ reg_addr = RTL8367C_REG_PORT8_PBFID + port-8; ++ return rtl8367c_getAsicReg(reg_addr, pFid); ++ } ++} ++/* Function Name: ++ * rtl8367c_setAsicPortBasedFidEn ++ * Description: ++ * Set port based FID selection enable ++ * Input: ++ * port - Physical port number (0~10) ++ * enabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicPortBasedFidEn(rtk_uint32 port, rtk_uint32 enabled) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_setAsicRegBit(RTL8367C_REG_PORT_PBFIDEN,port, enabled); ++} ++/* Function Name: ++ * rtl8367c_getAsicPortBasedFidEn ++ * Description: ++ * Get port based FID selection enable ++ * Input: ++ * port - Physical port number (0~10) ++ * pEnabled - 1: enabled, 0: disabled ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicPortBasedFidEn(rtk_uint32 port, rtk_uint32* pEnabled) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBit(RTL8367C_REG_PORT_PBFIDEN,port, pEnabled); ++} ++/* Function Name: ++ * rtl8367c_setAsicSpanningTreeStatus ++ * Description: ++ * Set spanning tree state per each port ++ * Input: ++ * port - Physical port number (0~10) ++ * msti - Multiple spanning tree instance ++ * state - Spanning tree state for msti ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_MSTI - Invalid msti parameter ++ * RT_ERR_PORT_ID - Invalid port number ++ * RT_ERR_MSTP_STATE - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicSpanningTreeStatus(rtk_uint32 port, rtk_uint32 msti, rtk_uint32 state) ++{ ++ rtk_uint32 reg_addr,bits_msk; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(msti > RTL8367C_MSTIMAX) ++ return RT_ERR_MSTI; ++ ++ if(state > STPST_FORWARDING) ++ return RT_ERR_MSTP_STATE; ++ ++ if(port < 8) ++ return rtl8367c_setAsicRegBits(RTL8367C_VLAN_MSTI_REG(msti,port), RTL8367C_VLAN_MSTI_MASK(port),state); ++ else{ ++ reg_addr = RTL8367C_VLAN_MSTI_REG(msti,port); ++ switch(port){ ++ case 8: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT8_STATE_MASK;break; ++ case 9: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT9_STATE_MASK;break; ++ case 10: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT10_STATE_MASK;break; ++ } ++ return rtl8367c_setAsicRegBits(reg_addr, bits_msk,state); ++ } ++} ++/* Function Name: ++ * rtl8367c_getAsicSpanningTreeStatus ++ * Description: ++ * Set spanning tree state per each port ++ * Input: ++ * port - Physical port number (0~10) ++ * msti - Multiple spanning tree instance ++ * pState - Spanning tree state for msti ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_MSTI - Invalid msti parameter ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicSpanningTreeStatus(rtk_uint32 port, rtk_uint32 msti, rtk_uint32* pState) ++{ ++ rtk_uint32 reg_addr,bits_msk; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(msti > RTL8367C_MSTIMAX) ++ return RT_ERR_MSTI; ++ ++ if(port < 8) ++ return rtl8367c_getAsicRegBits(RTL8367C_VLAN_MSTI_REG(msti,port), RTL8367C_VLAN_MSTI_MASK(port), pState); ++ else{ ++ reg_addr = RTL8367C_VLAN_MSTI_REG(msti,port); ++ switch(port){ ++ case 8: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT8_STATE_MASK;break; ++ case 9: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT9_STATE_MASK;break; ++ case 10: bits_msk = RTL8367C_VLAN_MSTI0_CTRL1_PORT10_STATE_MASK;break; ++ } ++ return rtl8367c_getAsicRegBits(reg_addr, bits_msk, pState); ++ } ++ ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicVlanTransparent ++ * Description: ++ * Set VLAN transparent ++ * Input: ++ * port - Physical port number (0~10) ++ * portmask - portmask(0~0xFF) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_MASK - Invalid portmask ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicVlanTransparent(rtk_uint32 port, rtk_uint32 portmask) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(portmask > RTL8367C_PORTMASK) ++ return RT_ERR_PORT_MASK; ++ ++ return rtl8367c_setAsicRegBits(RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL0 + port, RTL8367C_VLAN_EGRESS_TRANS_CTRL0_MASK, portmask); ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicVlanTransparent ++ * Description: ++ * Get VLAN transparent ++ * Input: ++ * port - Physical port number (0~10) ++ * Output: ++ * pPortmask - Ingress port mask ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_MASK - Invalid portmask ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicVlanTransparent(rtk_uint32 port, rtk_uint32 *pPortmask) ++{ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ return rtl8367c_getAsicRegBits(RTL8367C_REG_VLAN_EGRESS_TRANS_CTRL0 + port, RTL8367C_VLAN_EGRESS_TRANS_CTRL0_MASK, pPortmask); ++} ++ ++/* Function Name: ++ * rtl8367c_setAsicVlanEgressKeep ++ * Description: ++ * Set per egress port VLAN keep mode ++ * Input: ++ * port - Physical port number (0~10) ++ * portmask - portmask(0~0xFF) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_MASK - Invalid portmask ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setAsicVlanEgressKeep(rtk_uint32 port, rtk_uint32 portmask) ++{ ++ rtk_uint32 regAddr, bit_mask; ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(portmask > RTL8367C_PORTMASK) ++ return RT_ERR_PORT_MASK; ++ ++ if(port < 8){ ++ retVal = rtl8367c_setAsicRegBits(RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0 + (port>>1),RTL8367C_PORT0_VLAN_KEEP_MASK_MASK<<((port&1)*8),portmask & 0xff); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0_EXT + (port>>1); ++ bit_mask = RTL8367C_PORT0_VLAN_KEEP_MASK_EXT_MASK; ++ bit_mask <<= (port&1)*3; ++ retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, (portmask>>8)&0x7); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ } ++ else{ ++ switch(port){ ++ case 8: ++ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4; ++ bit_mask = RTL8367C_PORT8_VLAN_KEEP_MASK_MASK; ++ retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, portmask & 0xff); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4_EXT; ++ bit_mask = RTL8367C_PORT8_VLAN_KEEP_MASK_EXT_MASK; ++ retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, (portmask>>8)&0x7); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ break; ++ ++ case 9: ++ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4; ++ bit_mask = RTL8367C_PORT9_VLAN_KEEP_MASK_MASK; ++ retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, portmask & 0xff); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4_EXT; ++ bit_mask = RTL8367C_PORT9_VLAN_KEEP_MASK_EXT_MASK; ++ retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, (portmask>>8)&0x7); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ break; ++ ++ case 10: ++ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5; ++ bit_mask = RTL8367C_VLAN_EGRESS_KEEP_CTRL5_MASK; ++ retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, portmask & 0xff); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5_EXT; ++ bit_mask = RTL8367C_VLAN_EGRESS_KEEP_CTRL5_EXT_MASK; ++ retVal = rtl8367c_setAsicRegBits(regAddr, bit_mask, (portmask>>8)&0x7); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ break; ++ } ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getAsicVlanEgressKeep ++ * Description: ++ * Get per egress port VLAN keep mode ++ * Input: ++ * port - Physical port number (0~7) ++ * pPortmask - portmask(0~0xFF) ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getAsicVlanEgressKeep(rtk_uint32 port, rtk_uint32* pPortmask) ++{ ++ rtk_uint32 regAddr, bit_mask, regval_l, regval_h; ++ ret_t retVal; ++ ++ if(port > RTL8367C_PORTIDMAX) ++ return RT_ERR_PORT_ID; ++ ++ if(port < 8){ ++ retVal = rtl8367c_getAsicRegBits(RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0 + (port>>1),RTL8367C_PORT0_VLAN_KEEP_MASK_MASK<<((port&1)*8),®val_l); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL0_EXT + (port>>1); ++ bit_mask = RTL8367C_PORT0_VLAN_KEEP_MASK_EXT_MASK; ++ bit_mask <<= (port&1)*3; ++ retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_h); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ *pPortmask = (regval_h << 8) | regval_l; ++ } ++ else{ ++ switch(port){ ++ case 8: ++ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4; ++ bit_mask = RTL8367C_PORT8_VLAN_KEEP_MASK_MASK; ++ retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_l); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4_EXT; ++ bit_mask = RTL8367C_PORT8_VLAN_KEEP_MASK_EXT_MASK; ++ retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_h); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *pPortmask = (regval_h << 8) | regval_l; ++ break; ++ ++ case 9: ++ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4; ++ bit_mask = RTL8367C_PORT9_VLAN_KEEP_MASK_MASK; ++ retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_l); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL4_EXT; ++ bit_mask = RTL8367C_PORT9_VLAN_KEEP_MASK_EXT_MASK; ++ retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_h); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *pPortmask = (regval_h << 8) | regval_l; ++ break; ++ ++ case 10: ++ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5; ++ bit_mask = RTL8367C_VLAN_EGRESS_KEEP_CTRL5_MASK; ++ retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_l); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ regAddr = RTL8367C_REG_VLAN_EGRESS_KEEP_CTRL5_EXT; ++ bit_mask = RTL8367C_VLAN_EGRESS_KEEP_CTRL5_EXT_MASK; ++ retVal = rtl8367c_getAsicRegBits(regAddr, bit_mask, ®val_h); ++ if(retVal != RT_ERR_OK) ++ return retVal; ++ ++ *pPortmask = (regval_h << 8) | regval_l; ++ break; ++ } ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_setReservedVidAction ++ * Description: ++ * Set reserved VID action ++ * Input: ++ * vid0Action - VID 0 action ++ * vid4095Action - VID 4095 action ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Error input ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setReservedVidAction(rtk_uint32 vid0Action, rtk_uint32 vid4095Action) ++{ ++ ret_t retVal; ++ ++ if(vid0Action >= RES_VID_ACT_END) ++ return RT_ERR_INPUT; ++ ++ if(vid4095Action >= RES_VID_ACT_END) ++ return RT_ERR_INPUT; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_VID0_TYPE_OFFSET, vid0Action)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_VID4095_TYPE_OFFSET, vid4095Action)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getReservedVidAction ++ * Description: ++ * Get reserved VID action ++ * Input: ++ * pVid0Action - VID 0 action ++ * pVid4095Action - VID 4095 action ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NULL_POINTER - Null pointer ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getReservedVidAction(rtk_uint32 *pVid0Action, rtk_uint32 *pVid4095Action) ++{ ++ ret_t retVal; ++ ++ if(pVid0Action == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ if(pVid4095Action == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_VID0_TYPE_OFFSET, pVid0Action)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_VID4095_TYPE_OFFSET, pVid4095Action)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++ ++} ++ ++/* Function Name: ++ * rtl8367c_setRealKeepRemarkEn ++ * Description: ++ * Set Real Keep Remark ++ * Input: ++ * enabled - 0: 1P remarking is forbidden at real keep packet, 1: 1P remarking is enabled at real keep packet ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Error input ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_setRealKeepRemarkEn(rtk_uint32 enabled) ++{ ++ ret_t retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_1P_REMARK_BYPASS_REALKEEP_OFFSET, enabled)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_getRealKeepRemarkEn ++ * Description: ++ * Get Real Keep Remark ++ * Input: ++ * None ++ * Output: ++ * pEnabled - 0: 1P remarking is forbidden at real keep packet, 1: 1P remarking is enabled at real keep packet ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Error input ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_getRealKeepRemarkEn(rtk_uint32 *pEnabled) ++{ ++ ret_t retVal; ++ ++ if((retVal = rtl8367c_getAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL, RTL8367C_VLAN_1P_REMARK_BYPASS_REALKEEP_OFFSET, pEnabled)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtl8367c_resetVlan ++ * Description: ++ * Reset VLAN table ++ * Input: ++ * None. ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - Success ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * None ++ */ ++ret_t rtl8367c_resetVlan(void) ++{ ++ ret_t retVal; ++ ++ if((retVal = rtl8367c_setAsicRegBit(RTL8367C_REG_VLAN_EXT_CTRL2, RTL8367C_VLAN_EXT_CTRL2_OFFSET, 1)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/smi.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/smi.c +new file mode 100644 +index 0000000000..c272cad48e +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/smi.c +@@ -0,0 +1,444 @@ ++/* ++ * 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 : RTL8367C switch low-level function for access register ++ * Feature : SMI related functions ++ * ++ */ ++ ++ ++#include ++#include ++#include "rtk_error.h" ++ ++ ++#if defined(MDC_MDIO_OPERATION) ++/*******************************************************************************/ ++/* MDC/MDIO porting */ ++/*******************************************************************************/ ++/* define the PHY ID currently used */ ++/* carlos */ ++#if 0 ++#define MDC_MDIO_PHY_ID 0 /* PHY ID 0 or 29 */ ++#else ++#define MDC_MDIO_PHY_ID 29 /* PHY ID 0 or 29 */ ++#endif ++ ++/* MDC/MDIO, redefine/implement the following Macro */ /*carlos*/ ++#if 0 ++#define MDC_MDIO_WRITE(preamableLength, phyID, regID, data) ++#define MDC_MDIO_READ(preamableLength, phyID, regID, pData) ++#else ++#define u32 unsigned int ++extern u32 mii_mgr_read(u32 phy_addr, u32 phy_register, u32 *read_data); ++extern u32 mii_mgr_write(u32 phy_addr, u32 phy_register, u32 write_data); ++ ++#define MDC_MDIO_WRITE(preamableLength, phyID, regID, data) mii_mgr_write(phyID, regID, data) ++#define MDC_MDIO_READ(preamableLength, phyID, regID, pData) mii_mgr_read(phyID, regID, pData) ++#endif ++ ++ ++ ++ ++ ++#elif defined(SPI_OPERATION) ++/*******************************************************************************/ ++/* SPI porting */ ++/*******************************************************************************/ ++/* SPI, redefine/implement the following Macro */ ++#define SPI_WRITE(data, length) ++#define SPI_READ(pData, length) ++ ++ ++ ++ ++ ++#else ++/*******************************************************************************/ ++/* I2C porting */ ++/*******************************************************************************/ ++/* Define the GPIO ID for SCK & SDA */ ++rtk_uint32 smi_SCK = 1; /* GPIO used for SMI Clock Generation */ ++rtk_uint32 smi_SDA = 2; /* GPIO used for SMI Data signal */ ++ ++/* I2C, redefine/implement the following Macro */ ++#define GPIO_DIRECTION_SET(gpioID, direction) ++#define GPIO_DATA_SET(gpioID, data) ++#define GPIO_DATA_GET(gpioID, pData) ++ ++ ++ ++ ++ ++#endif ++ ++static void rtlglue_drvMutexLock(void) ++{ ++ /* It is empty currently. Implement this function if Lock/Unlock function is needed */ ++ return; ++} ++ ++static void rtlglue_drvMutexUnlock(void) ++{ ++ /* It is empty currently. Implement this function if Lock/Unlock function is needed */ ++ return; ++} ++ ++ ++ ++#if defined(MDC_MDIO_OPERATION) || defined(SPI_OPERATION) ++ /* No local function in MDC/MDIO & SPI mode */ ++#else ++static void _smi_start(void) ++{ ++ ++ /* change GPIO pin to Output only */ ++ GPIO_DIRECTION_SET(smi_SCK, GPIO_DIR_OUT); ++ GPIO_DIRECTION_SET(smi_SDA, GPIO_DIR_OUT); ++ ++ /* Initial state: SCK: 0, SDA: 1 */ ++ GPIO_DATA_SET(smi_SCK, 0); ++ GPIO_DATA_SET(smi_SDA, 1); ++ CLK_DURATION(DELAY); ++ ++ /* CLK 1: 0 -> 1, 1 -> 0 */ ++ GPIO_DATA_SET(smi_SCK, 1); ++ CLK_DURATION(DELAY); ++ GPIO_DATA_SET(smi_SCK, 0); ++ CLK_DURATION(DELAY); ++ ++ /* CLK 2: */ ++ GPIO_DATA_SET(smi_SCK, 1); ++ CLK_DURATION(DELAY); ++ GPIO_DATA_SET(smi_SDA, 0); ++ CLK_DURATION(DELAY); ++ GPIO_DATA_SET(smi_SCK, 0); ++ CLK_DURATION(DELAY); ++ GPIO_DATA_SET(smi_SDA, 1); ++ ++} ++ ++ ++ ++static void _smi_writeBit(rtk_uint16 signal, rtk_uint32 bitLen) ++{ ++ for( ; bitLen > 0; bitLen--) ++ { ++ CLK_DURATION(DELAY); ++ ++ /* prepare data */ ++ if ( signal & (1<<(bitLen-1)) ) ++ { ++ GPIO_DATA_SET(smi_SDA, 1); ++ } ++ else ++ { ++ GPIO_DATA_SET(smi_SDA, 0); ++ } ++ CLK_DURATION(DELAY); ++ ++ /* clocking */ ++ GPIO_DATA_SET(smi_SCK, 1); ++ CLK_DURATION(DELAY); ++ GPIO_DATA_SET(smi_SCK, 0); ++ } ++} ++ ++ ++ ++static void _smi_readBit(rtk_uint32 bitLen, rtk_uint32 *rData) ++{ ++ rtk_uint32 u = 0; ++ ++ /* change GPIO pin to Input only */ ++ GPIO_DIRECTION_SET(smi_SDA, GPIO_DIR_IN); ++ ++ for (*rData = 0; bitLen > 0; bitLen--) ++ { ++ CLK_DURATION(DELAY); ++ ++ /* clocking */ ++ GPIO_DATA_SET(smi_SCK, 1); ++ CLK_DURATION(DELAY); ++ GPIO_DATA_GET(smi_SDA, &u); ++ GPIO_DATA_SET(smi_SCK, 0); ++ ++ *rData |= (u << (bitLen - 1)); ++ } ++ ++ /* change GPIO pin to Output only */ ++ GPIO_DIRECTION_SET(smi_SDA, GPIO_DIR_OUT); ++} ++ ++ ++ ++static void _smi_stop(void) ++{ ++ ++ CLK_DURATION(DELAY); ++ GPIO_DATA_SET(smi_SDA, 0); ++ GPIO_DATA_SET(smi_SCK, 1); ++ CLK_DURATION(DELAY); ++ GPIO_DATA_SET(smi_SDA, 1); ++ CLK_DURATION(DELAY); ++ GPIO_DATA_SET(smi_SCK, 1); ++ CLK_DURATION(DELAY); ++ GPIO_DATA_SET(smi_SCK, 0); ++ CLK_DURATION(DELAY); ++ GPIO_DATA_SET(smi_SCK, 1); ++ ++ /* add a click */ ++ CLK_DURATION(DELAY); ++ GPIO_DATA_SET(smi_SCK, 0); ++ CLK_DURATION(DELAY); ++ GPIO_DATA_SET(smi_SCK, 1); ++ ++ ++ /* change GPIO pin to Input only */ ++ GPIO_DIRECTION_SET(smi_SDA, GPIO_DIR_IN); ++ GPIO_DIRECTION_SET(smi_SCK, GPIO_DIR_IN); ++} ++ ++#endif /* End of #if defined(MDC_MDIO_OPERATION) || defined(SPI_OPERATION) */ ++ ++rtk_int32 smi_read(rtk_uint32 mAddrs, rtk_uint32 *rData) ++{ ++#if (!defined(MDC_MDIO_OPERATION) && !defined(SPI_OPERATION)) ++ rtk_uint32 rawData=0, ACK; ++ rtk_uint8 con; ++ rtk_uint32 ret = RT_ERR_OK; ++#endif ++ ++ if(mAddrs > 0xFFFF) ++ return RT_ERR_INPUT; ++ ++ if(rData == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++#if defined(MDC_MDIO_OPERATION) ++ ++ /* Lock */ ++ rtlglue_drvMutexLock(); ++ ++ /* Write address control code to register 31 */ ++ MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_CTRL0_REG, MDC_MDIO_ADDR_OP); ++ ++ /* Write address to register 23 */ ++ MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_ADDRESS_REG, mAddrs); ++ ++ /* Write read control code to register 21 */ ++ MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_CTRL1_REG, MDC_MDIO_READ_OP); ++ ++ /* Read data from register 25 */ ++ MDC_MDIO_READ(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_DATA_READ_REG, rData); ++ ++ /* Unlock */ ++ rtlglue_drvMutexUnlock(); ++ ++ return RT_ERR_OK; ++ ++#elif defined(SPI_OPERATION) ++ ++ /* Lock */ ++ rtlglue_drvMutexLock(); ++ ++ /* Write 8 bits READ OP_CODE */ ++ SPI_WRITE(SPI_READ_OP, SPI_READ_OP_LEN); ++ ++ /* Write 16 bits register address */ ++ SPI_WRITE(mAddrs, SPI_REG_LEN); ++ ++ /* Read 16 bits data */ ++ SPI_READ(rData, SPI_DATA_LEN); ++ ++ /* Unlock */ ++ rtlglue_drvMutexUnlock(); ++ ++ return RT_ERR_OK; ++ ++#else ++ ++ /*Disable CPU interrupt to ensure that the SMI operation is atomic. ++ The API is based on RTL865X, rewrite the API if porting to other platform.*/ ++ rtlglue_drvMutexLock(); ++ ++ _smi_start(); /* Start SMI */ ++ ++ _smi_writeBit(0x0b, 4); /* CTRL code: 4'b1011 for RTL8370 */ ++ ++ _smi_writeBit(0x4, 3); /* CTRL code: 3'b100 */ ++ ++ _smi_writeBit(0x1, 1); /* 1: issue READ command */ ++ ++ con = 0; ++ do { ++ con++; ++ _smi_readBit(1, &ACK); /* ACK for issuing READ command*/ ++ } while ((ACK != 0) && (con < ack_timer)); ++ ++ if (ACK != 0) ret = RT_ERR_FAILED; ++ ++ _smi_writeBit((mAddrs&0xff), 8); /* Set reg_addr[7:0] */ ++ ++ con = 0; ++ do { ++ con++; ++ _smi_readBit(1, &ACK); /* ACK for setting reg_addr[7:0] */ ++ } while ((ACK != 0) && (con < ack_timer)); ++ ++ if (ACK != 0) ret = RT_ERR_FAILED; ++ ++ _smi_writeBit((mAddrs>>8), 8); /* Set reg_addr[15:8] */ ++ ++ con = 0; ++ do { ++ con++; ++ _smi_readBit(1, &ACK); /* ACK by RTL8369 */ ++ } while ((ACK != 0) && (con < ack_timer)); ++ if (ACK != 0) ret = RT_ERR_FAILED; ++ ++ _smi_readBit(8, &rawData); /* Read DATA [7:0] */ ++ *rData = rawData&0xff; ++ ++ _smi_writeBit(0x00, 1); /* ACK by CPU */ ++ ++ _smi_readBit(8, &rawData); /* Read DATA [15: 8] */ ++ ++ _smi_writeBit(0x01, 1); /* ACK by CPU */ ++ *rData |= (rawData<<8); ++ ++ _smi_stop(); ++ ++ rtlglue_drvMutexUnlock();/*enable CPU interrupt*/ ++ ++ return ret; ++#endif /* end of #if defined(MDC_MDIO_OPERATION) */ ++} ++ ++ ++ ++rtk_int32 smi_write(rtk_uint32 mAddrs, rtk_uint32 rData) ++{ ++#if (!defined(MDC_MDIO_OPERATION) && !defined(SPI_OPERATION)) ++ rtk_int8 con; ++ rtk_uint32 ACK; ++ rtk_uint32 ret = RT_ERR_OK; ++#endif ++ ++ if(mAddrs > 0xFFFF) ++ return RT_ERR_INPUT; ++ ++ if(rData > 0xFFFF) ++ return RT_ERR_INPUT; ++ ++#if defined(MDC_MDIO_OPERATION) ++ ++ /* Lock */ ++ rtlglue_drvMutexLock(); ++ ++ /* Write address control code to register 31 */ ++ MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_CTRL0_REG, MDC_MDIO_ADDR_OP); ++ ++ /* Write address to register 23 */ ++ MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_ADDRESS_REG, mAddrs); ++ ++ /* Write data to register 24 */ ++ MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_DATA_WRITE_REG, rData); ++ ++ /* Write data control code to register 21 */ ++ MDC_MDIO_WRITE(MDC_MDIO_PREAMBLE_LEN, MDC_MDIO_PHY_ID, MDC_MDIO_CTRL1_REG, MDC_MDIO_WRITE_OP); ++ ++ /* Unlock */ ++ rtlglue_drvMutexUnlock(); ++ ++ return RT_ERR_OK; ++ ++#elif defined(SPI_OPERATION) ++ ++ /* Lock */ ++ rtlglue_drvMutexLock(); ++ ++ /* Write 8 bits WRITE OP_CODE */ ++ SPI_WRITE(SPI_WRITE_OP, SPI_WRITE_OP_LEN); ++ ++ /* Write 16 bits register address */ ++ SPI_WRITE(mAddrs, SPI_REG_LEN); ++ ++ /* Write 16 bits data */ ++ SPI_WRITE(rData, SPI_DATA_LEN); ++ ++ /* Unlock */ ++ rtlglue_drvMutexUnlock(); ++ ++ return RT_ERR_OK; ++#else ++ ++ /*Disable CPU interrupt to ensure that the SMI operation is atomic. ++ The API is based on RTL865X, rewrite the API if porting to other platform.*/ ++ rtlglue_drvMutexLock(); ++ ++ _smi_start(); /* Start SMI */ ++ ++ _smi_writeBit(0x0b, 4); /* CTRL code: 4'b1011 for RTL8370*/ ++ ++ _smi_writeBit(0x4, 3); /* CTRL code: 3'b100 */ ++ ++ _smi_writeBit(0x0, 1); /* 0: issue WRITE command */ ++ ++ con = 0; ++ do { ++ con++; ++ _smi_readBit(1, &ACK); /* ACK for issuing WRITE command*/ ++ } while ((ACK != 0) && (con < ack_timer)); ++ if (ACK != 0) ret = RT_ERR_FAILED; ++ ++ _smi_writeBit((mAddrs&0xff), 8); /* Set reg_addr[7:0] */ ++ ++ con = 0; ++ do { ++ con++; ++ _smi_readBit(1, &ACK); /* ACK for setting reg_addr[7:0] */ ++ } while ((ACK != 0) && (con < ack_timer)); ++ if (ACK != 0) ret = RT_ERR_FAILED; ++ ++ _smi_writeBit((mAddrs>>8), 8); /* Set reg_addr[15:8] */ ++ ++ con = 0; ++ do { ++ con++; ++ _smi_readBit(1, &ACK); /* ACK for setting reg_addr[15:8] */ ++ } while ((ACK != 0) && (con < ack_timer)); ++ if (ACK != 0) ret = RT_ERR_FAILED; ++ ++ _smi_writeBit(rData&0xff, 8); /* Write Data [7:0] out */ ++ ++ con = 0; ++ do { ++ con++; ++ _smi_readBit(1, &ACK); /* ACK for writting data [7:0] */ ++ } while ((ACK != 0) && (con < ack_timer)); ++ if (ACK != 0) ret = RT_ERR_FAILED; ++ ++ _smi_writeBit(rData>>8, 8); /* Write Data [15:8] out */ ++ ++ con = 0; ++ do { ++ con++; ++ _smi_readBit(1, &ACK); /* ACK for writting data [15:8] */ ++ } while ((ACK != 0) && (con < ack_timer)); ++ if (ACK != 0) ret = RT_ERR_FAILED; ++ ++ _smi_stop(); ++ ++ rtlglue_drvMutexUnlock();/*enable CPU interrupt*/ ++ ++ return ret; ++#endif /* end of #if defined(MDC_MDIO_OPERATION) */ ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/stat.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/stat.c +new file mode 100644 +index 0000000000..3a328b0ca4 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/stat.c +@@ -0,0 +1,626 @@ ++/* ++ * 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 MIB module. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++/* Function Name: ++ * rtk_stat_global_reset ++ * Description: ++ * Reset global MIB counter. ++ * Input: ++ * None ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * Reset MIB counter of ports. API will use global reset while port mask is all-ports. ++ */ ++rtk_api_ret_t rtk_stat_global_reset(void) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ((retVal = rtl8367c_setAsicMIBsCounterReset(TRUE,FALSE, 0)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_stat_port_reset ++ * Description: ++ * Reset per port MIB counter by port. ++ * Input: ++ * port - port id. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_stat_port_reset(rtk_port_t port) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check port valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if ((retVal = rtl8367c_setAsicMIBsCounterReset(FALSE,FALSE,1 << rtk_switch_port_L2P_get(port))) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_stat_queueManage_reset ++ * Description: ++ * Reset queue manage MIB counter. ++ * Input: ++ * None ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_stat_queueManage_reset(void) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ((retVal = rtl8367c_setAsicMIBsCounterReset(FALSE,TRUE,0)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++ ++/* Function Name: ++ * rtk_stat_global_get ++ * Description: ++ * Get global MIB counter ++ * Input: ++ * cntr_idx - global counter index. ++ * Output: ++ * pCntr - global counter value. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * Get global MIB counter by index definition. ++ */ ++rtk_api_ret_t rtk_stat_global_get(rtk_stat_global_type_t cntr_idx, rtk_stat_counter_t *pCntr) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pCntr) ++ return RT_ERR_NULL_POINTER; ++ ++ if (cntr_idx!=DOT1D_TP_LEARNED_ENTRY_DISCARDS_INDEX) ++ return RT_ERR_STAT_INVALID_GLOBAL_CNTR; ++ ++ if ((retVal = rtl8367c_getAsicMIBsCounter(0, cntr_idx, pCntr)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_stat_global_getAll ++ * Description: ++ * Get all global MIB counter ++ * Input: ++ * None ++ * Output: ++ * pGlobal_cntrs - global counter structure. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * Get all global MIB counter by index definition. ++ */ ++rtk_api_ret_t rtk_stat_global_getAll(rtk_stat_global_cntr_t *pGlobal_cntrs) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pGlobal_cntrs) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicMIBsCounter(0,DOT1D_TP_LEARNED_ENTRY_DISCARDS_INDEX, &pGlobal_cntrs->dot1dTpLearnedEntryDiscards)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++#define MIB_NOT_SUPPORT (0xFFFF) ++static rtk_api_ret_t _get_asic_mib_idx(rtk_stat_port_type_t cnt_idx, RTL8367C_MIBCOUNTER *pMib_idx) ++{ ++ RTL8367C_MIBCOUNTER mib_asic_idx[STAT_PORT_CNTR_END]= ++ { ++ ifInOctets, /* STAT_IfInOctets */ ++ dot3StatsFCSErrors, /* STAT_Dot3StatsFCSErrors */ ++ dot3StatsSymbolErrors, /* STAT_Dot3StatsSymbolErrors */ ++ dot3InPauseFrames, /* STAT_Dot3InPauseFrames */ ++ dot3ControlInUnknownOpcodes, /* STAT_Dot3ControlInUnknownOpcodes */ ++ etherStatsFragments, /* STAT_EtherStatsFragments */ ++ etherStatsJabbers, /* STAT_EtherStatsJabbers */ ++ ifInUcastPkts, /* STAT_IfInUcastPkts */ ++ etherStatsDropEvents, /* STAT_EtherStatsDropEvents */ ++ etherStatsOctets, /* STAT_EtherStatsOctets */ ++ etherStatsUnderSizePkts, /* STAT_EtherStatsUnderSizePkts */ ++ etherOversizeStats, /* STAT_EtherOversizeStats */ ++ etherStatsPkts64Octets, /* STAT_EtherStatsPkts64Octets */ ++ etherStatsPkts65to127Octets, /* STAT_EtherStatsPkts65to127Octets */ ++ etherStatsPkts128to255Octets, /* STAT_EtherStatsPkts128to255Octets */ ++ etherStatsPkts256to511Octets, /* STAT_EtherStatsPkts256to511Octets */ ++ etherStatsPkts512to1023Octets, /* STAT_EtherStatsPkts512to1023Octets */ ++ etherStatsPkts1024to1518Octets, /* STAT_EtherStatsPkts1024to1518Octets */ ++ ifInMulticastPkts, /* STAT_EtherStatsMulticastPkts */ ++ ifInBroadcastPkts, /* STAT_EtherStatsBroadcastPkts */ ++ ifOutOctets, /* STAT_IfOutOctets */ ++ dot3StatsSingleCollisionFrames, /* STAT_Dot3StatsSingleCollisionFrames */ ++ dot3StatMultipleCollisionFrames,/* STAT_Dot3StatsMultipleCollisionFrames */ ++ dot3sDeferredTransmissions, /* STAT_Dot3StatsDeferredTransmissions */ ++ dot3StatsLateCollisions, /* STAT_Dot3StatsLateCollisions */ ++ etherStatsCollisions, /* STAT_EtherStatsCollisions */ ++ dot3StatsExcessiveCollisions, /* STAT_Dot3StatsExcessiveCollisions */ ++ dot3OutPauseFrames, /* STAT_Dot3OutPauseFrames */ ++ MIB_NOT_SUPPORT, /* STAT_Dot1dBasePortDelayExceededDiscards */ ++ dot1dTpPortInDiscards, /* STAT_Dot1dTpPortInDiscards */ ++ ifOutUcastPkts, /* STAT_IfOutUcastPkts */ ++ ifOutMulticastPkts, /* STAT_IfOutMulticastPkts */ ++ ifOutBroadcastPkts, /* STAT_IfOutBroadcastPkts */ ++ outOampduPkts, /* STAT_OutOampduPkts */ ++ inOampduPkts, /* STAT_InOampduPkts */ ++ MIB_NOT_SUPPORT, /* STAT_PktgenPkts */ ++ inMldChecksumError, /* STAT_InMldChecksumError */ ++ inIgmpChecksumError, /* STAT_InIgmpChecksumError */ ++ inMldSpecificQuery, /* STAT_InMldSpecificQuery */ ++ inMldGeneralQuery, /* STAT_InMldGeneralQuery */ ++ inIgmpSpecificQuery, /* STAT_InIgmpSpecificQuery */ ++ inIgmpGeneralQuery, /* STAT_InIgmpGeneralQuery */ ++ inMldLeaves, /* STAT_InMldLeaves */ ++ inIgmpLeaves, /* STAT_InIgmpInterfaceLeaves */ ++ inIgmpJoinsSuccess, /* STAT_InIgmpJoinsSuccess */ ++ inIgmpJoinsFail, /* STAT_InIgmpJoinsFail */ ++ inMldJoinsSuccess, /* STAT_InMldJoinsSuccess */ ++ inMldJoinsFail, /* STAT_InMldJoinsFail */ ++ inReportSuppressionDrop, /* STAT_InReportSuppressionDrop */ ++ inLeaveSuppressionDrop, /* STAT_InLeaveSuppressionDrop */ ++ outIgmpReports, /* STAT_OutIgmpReports */ ++ outIgmpLeaves, /* STAT_OutIgmpLeaves */ ++ outIgmpGeneralQuery, /* STAT_OutIgmpGeneralQuery */ ++ outIgmpSpecificQuery, /* STAT_OutIgmpSpecificQuery */ ++ outMldReports, /* STAT_OutMldReports */ ++ outMldLeaves, /* STAT_OutMldLeaves */ ++ outMldGeneralQuery, /* STAT_OutMldGeneralQuery */ ++ outMldSpecificQuery, /* STAT_OutMldSpecificQuery */ ++ inKnownMulticastPkts, /* STAT_InKnownMulticastPkts */ ++ ifInMulticastPkts, /* STAT_IfInMulticastPkts */ ++ ifInBroadcastPkts, /* STAT_IfInBroadcastPkts */ ++ ifOutDiscards /* STAT_IfOutDiscards */ ++ }; ++ ++ if(cnt_idx >= STAT_PORT_CNTR_END) ++ return RT_ERR_STAT_INVALID_PORT_CNTR; ++ ++ if(mib_asic_idx[cnt_idx] == MIB_NOT_SUPPORT) ++ return RT_ERR_CHIP_NOT_SUPPORTED; ++ ++ *pMib_idx = mib_asic_idx[cnt_idx]; ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_stat_port_get ++ * Description: ++ * Get per port MIB counter by index ++ * Input: ++ * port - port id. ++ * cntr_idx - port counter index. ++ * Output: ++ * pCntr - MIB retrived counter. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * Get per port MIB counter by index definition. ++ */ ++rtk_api_ret_t rtk_stat_port_get(rtk_port_t port, rtk_stat_port_type_t cntr_idx, rtk_stat_counter_t *pCntr) ++{ ++ rtk_api_ret_t retVal; ++ RTL8367C_MIBCOUNTER mib_idx; ++ rtk_stat_counter_t second_cnt; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pCntr) ++ return RT_ERR_NULL_POINTER; ++ ++ /* Check port valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if (cntr_idx>=STAT_PORT_CNTR_END) ++ return RT_ERR_STAT_INVALID_PORT_CNTR; ++ ++ if((retVal = _get_asic_mib_idx(cntr_idx, &mib_idx)) != RT_ERR_OK) ++ return retVal; ++ ++ if(mib_idx == MIB_NOT_SUPPORT) ++ return RT_ERR_CHIP_NOT_SUPPORTED; ++ ++ if ((retVal = rtl8367c_getAsicMIBsCounter(rtk_switch_port_L2P_get(port), mib_idx, pCntr)) != RT_ERR_OK) ++ return retVal; ++ ++ if(cntr_idx == STAT_EtherStatsMulticastPkts) ++ { ++ if((retVal = _get_asic_mib_idx(STAT_IfOutMulticastPkts, &mib_idx)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicMIBsCounter(rtk_switch_port_L2P_get(port), mib_idx, &second_cnt)) != RT_ERR_OK) ++ return retVal; ++ ++ *pCntr += second_cnt; ++ } ++ ++ if(cntr_idx == STAT_EtherStatsBroadcastPkts) ++ { ++ if((retVal = _get_asic_mib_idx(STAT_IfOutBroadcastPkts, &mib_idx)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicMIBsCounter(rtk_switch_port_L2P_get(port), mib_idx, &second_cnt)) != RT_ERR_OK) ++ return retVal; ++ ++ *pCntr += second_cnt; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_stat_port_getAll ++ * Description: ++ * Get all counters of one specified port in the specified device. ++ * Input: ++ * port - port id. ++ * Output: ++ * pPort_cntrs - buffer pointer of counter value. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * Get all MIB counters of one port. ++ */ ++rtk_api_ret_t rtk_stat_port_getAll(rtk_port_t port, rtk_stat_port_cntr_t *pPort_cntrs) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 mibIndex; ++ rtk_uint64 mibCounter; ++ rtk_uint32 *accessPtr; ++ /* address offset to MIBs counter */ ++ CONST_T rtk_uint16 mibLength[STAT_PORT_CNTR_END]= { ++ 2,1,1,1,1,1,1,1,1, ++ 2,1,1,1,1,1,1,1,1,1,1, ++ 2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, ++ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pPort_cntrs) ++ return RT_ERR_NULL_POINTER; ++ ++ /* Check port valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ accessPtr = (rtk_uint32*)pPort_cntrs; ++ for (mibIndex=0;mibIndex RTL8367C_MIB_MAX_LOG_CNT_IDX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if((idx % 2) == 1) ++ return RT_ERR_INPUT; ++ ++ if(mode >= LOGGING_MODE_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(type >= LOGGING_TYPE_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if((retVal = rtl8367c_setAsicMIBsLoggingType((idx / 2), (rtk_uint32)type)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicMIBsLoggingMode((idx / 2), (rtk_uint32)mode)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_stat_logging_counterCfg_get ++ * Description: ++ * Get the type and mode of Logging Counter ++ * Input: ++ * idx - The index of Logging Counter. Should be even number only.(0,2,4,6,8.....30) ++ * Output: ++ * pMode - 32 bits or 64 bits mode ++ * pType - Packet counter or byte counter ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_OUT_OF_RANGE - Out of range. ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_NULL_POINTER - NULL Pointer ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * Get the type and mode of Logging Counter. ++ */ ++rtk_api_ret_t rtk_stat_logging_counterCfg_get(rtk_uint32 idx, rtk_logging_counter_mode_t *pMode, rtk_logging_counter_type_t *pType) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 type, mode; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(idx > RTL8367C_MIB_MAX_LOG_CNT_IDX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if((idx % 2) == 1) ++ return RT_ERR_INPUT; ++ ++ if(pMode == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ if(pType == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ if((retVal = rtl8367c_getAsicMIBsLoggingType((idx / 2), &type)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicMIBsLoggingMode((idx / 2), &mode)) != RT_ERR_OK) ++ return retVal; ++ ++ *pMode = (rtk_logging_counter_mode_t)mode; ++ *pType = (rtk_logging_counter_type_t)type; ++ ++ return RT_ERR_OK; ++} ++ ++ ++/* Function Name: ++ * rtk_stat_logging_counter_reset ++ * Description: ++ * Reset Logging Counter ++ * Input: ++ * idx - The index of Logging Counter. (0~31) ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_OUT_OF_RANGE - Out of range. ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * Reset Logging Counter. ++ */ ++rtk_api_ret_t rtk_stat_logging_counter_reset(rtk_uint32 idx) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(idx > RTL8367C_MIB_MAX_LOG_CNT_IDX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if((retVal = rtl8367c_setAsicMIBsResetLoggingCounter(idx)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_stat_logging_counter_get ++ * Description: ++ * Get Logging Counter ++ * Input: ++ * idx - The index of Logging Counter. (0~31) ++ * Output: ++ * pCnt - Logging counter value ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_OUT_OF_RANGE - Out of range. ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * Get Logging Counter. ++ */ ++rtk_api_ret_t rtk_stat_logging_counter_get(rtk_uint32 idx, rtk_uint32 *pCnt) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pCnt) ++ return RT_ERR_NULL_POINTER; ++ ++ if(idx > RTL8367C_MIB_MAX_LOG_CNT_IDX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if((retVal = rtl8367c_getAsicMIBsLogCounter(idx, pCnt)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_stat_lengthMode_set ++ * Description: ++ * Set Legnth mode. ++ * Input: ++ * txMode - The length counting mode ++ * rxMode - The length counting mode ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_INPUT - Out of range. ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_stat_lengthMode_set(rtk_stat_lengthMode_t txMode, rtk_stat_lengthMode_t rxMode) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(txMode >= LENGTH_MODE_END) ++ return RT_ERR_INPUT; ++ ++ if(rxMode >= LENGTH_MODE_END) ++ return RT_ERR_INPUT; ++ ++ if((retVal = rtl8367c_setAsicMIBsLength((rtk_uint32)txMode, (rtk_uint32)rxMode)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_stat_lengthMode_get ++ * Description: ++ * Get Legnth mode. ++ * Input: ++ * None. ++ * Output: ++ * pTxMode - The length counting mode ++ * pRxMode - The length counting mode ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_INPUT - Out of range. ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ */ ++rtk_api_ret_t rtk_stat_lengthMode_get(rtk_stat_lengthMode_t *pTxMode, rtk_stat_lengthMode_t *pRxMode) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pTxMode) ++ return RT_ERR_NULL_POINTER; ++ ++ if(NULL == pRxMode) ++ return RT_ERR_NULL_POINTER; ++ ++ if((retVal = rtl8367c_getAsicMIBsLength((rtk_uint32 *)pTxMode, (rtk_uint32 *)pRxMode)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/storm.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/storm.c +new file mode 100644 +index 0000000000..13cf4e3cb4 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/storm.c +@@ -0,0 +1,816 @@ ++/* ++ * 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 Storm module. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Function Name: ++ * rtk_rate_stormControlMeterIdx_set ++ * Description: ++ * Set the storm control meter index. ++ * Input: ++ * port - port id ++ * storm_type - storm group type ++ * index - storm control meter index. ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_PORT_ID - Invalid port id ++ * RT_ERR_FILTER_METER_ID - Invalid meter ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_rate_stormControlMeterIdx_set(rtk_port_t port, rtk_rate_storm_group_t stormType, rtk_uint32 index) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if (stormType >= STORM_GROUP_END) ++ return RT_ERR_SFC_UNKNOWN_GROUP; ++ ++ if (index > RTK_MAX_METER_ID) ++ return RT_ERR_FILTER_METER_ID; ++ ++ switch (stormType) ++ { ++ case STORM_GROUP_UNKNOWN_UNICAST: ++ if ((retVal = rtl8367c_setAsicStormFilterUnknownUnicastMeter(rtk_switch_port_L2P_get(port), index))!=RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_UNKNOWN_MULTICAST: ++ if ((retVal = rtl8367c_setAsicStormFilterUnknownMulticastMeter(rtk_switch_port_L2P_get(port), index))!=RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_MULTICAST: ++ if ((retVal = rtl8367c_setAsicStormFilterMulticastMeter(rtk_switch_port_L2P_get(port), index))!=RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_BROADCAST: ++ if ((retVal = rtl8367c_setAsicStormFilterBroadcastMeter(rtk_switch_port_L2P_get(port), index))!=RT_ERR_OK) ++ return retVal; ++ break; ++ default: ++ break; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_rate_stormControlMeterIdx_get ++ * Description: ++ * Get the storm control meter index. ++ * Input: ++ * port - port id ++ * storm_type - storm group type ++ * Output: ++ * pIndex - storm control meter index. ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_PORT_ID - Invalid port id ++ * RT_ERR_FILTER_METER_ID - Invalid meter ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_rate_stormControlMeterIdx_get(rtk_port_t port, rtk_rate_storm_group_t stormType, rtk_uint32 *pIndex) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if (stormType >= STORM_GROUP_END) ++ return RT_ERR_SFC_UNKNOWN_GROUP; ++ ++ if (NULL == pIndex ) ++ return RT_ERR_NULL_POINTER; ++ ++ switch (stormType) ++ { ++ case STORM_GROUP_UNKNOWN_UNICAST: ++ if ((retVal = rtl8367c_getAsicStormFilterUnknownUnicastMeter(rtk_switch_port_L2P_get(port), pIndex))!=RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_UNKNOWN_MULTICAST: ++ if ((retVal = rtl8367c_getAsicStormFilterUnknownMulticastMeter(rtk_switch_port_L2P_get(port), pIndex))!=RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_MULTICAST: ++ if ((retVal = rtl8367c_getAsicStormFilterMulticastMeter(rtk_switch_port_L2P_get(port), pIndex))!=RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_BROADCAST: ++ if ((retVal = rtl8367c_getAsicStormFilterBroadcastMeter(rtk_switch_port_L2P_get(port), pIndex))!=RT_ERR_OK) ++ return retVal; ++ break; ++ default: ++ break; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_rate_stormControlPortEnable_set ++ * Description: ++ * Set enable status of storm control on specified port. ++ * Input: ++ * port - port id ++ * stormType - storm group type ++ * enable - enable status of storm control ++ * 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: ++ * ++ */ ++rtk_api_ret_t rtk_rate_stormControlPortEnable_set(rtk_port_t port, rtk_rate_storm_group_t stormType, 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 (stormType >= STORM_GROUP_END) ++ return RT_ERR_SFC_UNKNOWN_GROUP; ++ ++ if (enable >= RTK_ENABLE_END) ++ return RT_ERR_ENABLE; ++ ++ switch (stormType) ++ { ++ case STORM_GROUP_UNKNOWN_UNICAST: ++ if ((retVal = rtl8367c_setAsicStormFilterUnknownUnicastEnable(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_UNKNOWN_MULTICAST: ++ if ((retVal = rtl8367c_setAsicStormFilterUnknownMulticastEnable(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_MULTICAST: ++ if ((retVal = rtl8367c_setAsicStormFilterMulticastEnable(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_BROADCAST: ++ if ((retVal = rtl8367c_setAsicStormFilterBroadcastEnable(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) ++ return retVal; ++ break; ++ default: ++ break; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_rate_stormControlPortEnable_set ++ * Description: ++ * Set enable status of storm control on specified port. ++ * Input: ++ * port - port id ++ * stormType - storm group type ++ * Output: ++ * pEnable - enable status of storm control ++ * 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: ++ * ++ */ ++rtk_api_ret_t rtk_rate_stormControlPortEnable_get(rtk_port_t port, rtk_rate_storm_group_t stormType, 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 (stormType >= STORM_GROUP_END) ++ return RT_ERR_SFC_UNKNOWN_GROUP; ++ ++ if (NULL == pEnable) ++ return RT_ERR_ENABLE; ++ ++ switch (stormType) ++ { ++ case STORM_GROUP_UNKNOWN_UNICAST: ++ if ((retVal = rtl8367c_getAsicStormFilterUnknownUnicastEnable(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_UNKNOWN_MULTICAST: ++ if ((retVal = rtl8367c_getAsicStormFilterUnknownMulticastEnable(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_MULTICAST: ++ if ((retVal = rtl8367c_getAsicStormFilterMulticastEnable(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_BROADCAST: ++ if ((retVal = rtl8367c_getAsicStormFilterBroadcastEnable(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) ++ return retVal; ++ break; ++ default: ++ break; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_storm_bypass_set ++ * Description: ++ * Set bypass storm filter control configuration. ++ * Input: ++ * type - Bypass storm filter control type. ++ * enable - Bypass 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 IFG parameter ++ * Note: ++ * ++ * This API can set per-port bypass stomr filter control frame type including RMA and igmp. ++ * The bypass frame type is as following: ++ * - BYPASS_BRG_GROUP, ++ * - BYPASS_FD_PAUSE, ++ * - BYPASS_SP_MCAST, ++ * - BYPASS_1X_PAE, ++ * - BYPASS_UNDEF_BRG_04, ++ * - BYPASS_UNDEF_BRG_05, ++ * - BYPASS_UNDEF_BRG_06, ++ * - BYPASS_UNDEF_BRG_07, ++ * - BYPASS_PROVIDER_BRIDGE_GROUP_ADDRESS, ++ * - BYPASS_UNDEF_BRG_09, ++ * - BYPASS_UNDEF_BRG_0A, ++ * - BYPASS_UNDEF_BRG_0B, ++ * - BYPASS_UNDEF_BRG_0C, ++ * - BYPASS_PROVIDER_BRIDGE_GVRP_ADDRESS, ++ * - BYPASS_8021AB, ++ * - BYPASS_UNDEF_BRG_0F, ++ * - BYPASS_BRG_MNGEMENT, ++ * - BYPASS_UNDEFINED_11, ++ * - BYPASS_UNDEFINED_12, ++ * - BYPASS_UNDEFINED_13, ++ * - BYPASS_UNDEFINED_14, ++ * - BYPASS_UNDEFINED_15, ++ * - BYPASS_UNDEFINED_16, ++ * - BYPASS_UNDEFINED_17, ++ * - BYPASS_UNDEFINED_18, ++ * - BYPASS_UNDEFINED_19, ++ * - BYPASS_UNDEFINED_1A, ++ * - BYPASS_UNDEFINED_1B, ++ * - BYPASS_UNDEFINED_1C, ++ * - BYPASS_UNDEFINED_1D, ++ * - BYPASS_UNDEFINED_1E, ++ * - BYPASS_UNDEFINED_1F, ++ * - BYPASS_GMRP, ++ * - BYPASS_GVRP, ++ * - BYPASS_UNDEF_GARP_22, ++ * - BYPASS_UNDEF_GARP_23, ++ * - BYPASS_UNDEF_GARP_24, ++ * - BYPASS_UNDEF_GARP_25, ++ * - BYPASS_UNDEF_GARP_26, ++ * - BYPASS_UNDEF_GARP_27, ++ * - BYPASS_UNDEF_GARP_28, ++ * - BYPASS_UNDEF_GARP_29, ++ * - BYPASS_UNDEF_GARP_2A, ++ * - BYPASS_UNDEF_GARP_2B, ++ * - BYPASS_UNDEF_GARP_2C, ++ * - BYPASS_UNDEF_GARP_2D, ++ * - BYPASS_UNDEF_GARP_2E, ++ * - BYPASS_UNDEF_GARP_2F, ++ * - BYPASS_IGMP. ++ * - BYPASS_CDP. ++ * - BYPASS_CSSTP. ++ * - BYPASS_LLDP. ++ */ ++rtk_api_ret_t rtk_storm_bypass_set(rtk_storm_bypass_t type, rtk_enable_t enable) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_rma_t rmacfg; ++ rtk_uint32 tmp; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (type >= BYPASS_END) ++ return RT_ERR_INPUT; ++ ++ if (enable >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if (type >= 0 && type <= BYPASS_UNDEF_GARP_2F) ++ { ++ if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ rmacfg.discard_storm_filter = enable; ++ ++ if ((retVal = rtl8367c_setAsicRma(type, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if(type == BYPASS_IGMP) ++ { ++ if ((retVal = rtl8367c_setAsicIGMPBypassStormCTRL(enable)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (type == BYPASS_CDP) ++ { ++ if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ rmacfg.discard_storm_filter = enable; ++ ++ if ((retVal = rtl8367c_setAsicRmaCdp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (type == BYPASS_CSSTP) ++ { ++ if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ rmacfg.discard_storm_filter = enable; ++ ++ if ((retVal = rtl8367c_setAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (type == BYPASS_LLDP) ++ { ++ if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ rmacfg.discard_storm_filter = enable; ++ ++ if ((retVal = rtl8367c_setAsicRmaLldp(tmp, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ return RT_ERR_INPUT; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_storm_bypass_get ++ * Description: ++ * Get bypass storm filter control configuration. ++ * Input: ++ * type - Bypass storm filter control type. ++ * Output: ++ * pEnable - Bypass 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 per-port bypass stomr filter control frame type including RMA and igmp. ++ * The bypass frame type is as following: ++ * - BYPASS_BRG_GROUP, ++ * - BYPASS_FD_PAUSE, ++ * - BYPASS_SP_MCAST, ++ * - BYPASS_1X_PAE, ++ * - BYPASS_UNDEF_BRG_04, ++ * - BYPASS_UNDEF_BRG_05, ++ * - BYPASS_UNDEF_BRG_06, ++ * - BYPASS_UNDEF_BRG_07, ++ * - BYPASS_PROVIDER_BRIDGE_GROUP_ADDRESS, ++ * - BYPASS_UNDEF_BRG_09, ++ * - BYPASS_UNDEF_BRG_0A, ++ * - BYPASS_UNDEF_BRG_0B, ++ * - BYPASS_UNDEF_BRG_0C, ++ * - BYPASS_PROVIDER_BRIDGE_GVRP_ADDRESS, ++ * - BYPASS_8021AB, ++ * - BYPASS_UNDEF_BRG_0F, ++ * - BYPASS_BRG_MNGEMENT, ++ * - BYPASS_UNDEFINED_11, ++ * - BYPASS_UNDEFINED_12, ++ * - BYPASS_UNDEFINED_13, ++ * - BYPASS_UNDEFINED_14, ++ * - BYPASS_UNDEFINED_15, ++ * - BYPASS_UNDEFINED_16, ++ * - BYPASS_UNDEFINED_17, ++ * - BYPASS_UNDEFINED_18, ++ * - BYPASS_UNDEFINED_19, ++ * - BYPASS_UNDEFINED_1A, ++ * - BYPASS_UNDEFINED_1B, ++ * - BYPASS_UNDEFINED_1C, ++ * - BYPASS_UNDEFINED_1D, ++ * - BYPASS_UNDEFINED_1E, ++ * - BYPASS_UNDEFINED_1F, ++ * - BYPASS_GMRP, ++ * - BYPASS_GVRP, ++ * - BYPASS_UNDEF_GARP_22, ++ * - BYPASS_UNDEF_GARP_23, ++ * - BYPASS_UNDEF_GARP_24, ++ * - BYPASS_UNDEF_GARP_25, ++ * - BYPASS_UNDEF_GARP_26, ++ * - BYPASS_UNDEF_GARP_27, ++ * - BYPASS_UNDEF_GARP_28, ++ * - BYPASS_UNDEF_GARP_29, ++ * - BYPASS_UNDEF_GARP_2A, ++ * - BYPASS_UNDEF_GARP_2B, ++ * - BYPASS_UNDEF_GARP_2C, ++ * - BYPASS_UNDEF_GARP_2D, ++ * - BYPASS_UNDEF_GARP_2E, ++ * - BYPASS_UNDEF_GARP_2F, ++ * - BYPASS_IGMP. ++ * - BYPASS_CDP. ++ * - BYPASS_CSSTP. ++ * - BYPASS_LLDP. ++ */ ++rtk_api_ret_t rtk_storm_bypass_get(rtk_storm_bypass_t type, rtk_enable_t *pEnable) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_rma_t rmacfg; ++ rtk_uint32 tmp; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (type >= BYPASS_END) ++ return RT_ERR_INPUT; ++ ++ if(NULL == pEnable) ++ return RT_ERR_NULL_POINTER; ++ ++ if (type >= 0 && type <= BYPASS_UNDEF_GARP_2F) ++ { ++ if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEnable = rmacfg.discard_storm_filter; ++ } ++ else if(type == BYPASS_IGMP) ++ { ++ if ((retVal = rtl8367c_getAsicIGMPBypassStormCTRL(pEnable)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (type == BYPASS_CDP) ++ { ++ if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEnable = rmacfg.discard_storm_filter; ++ } ++ else if (type == BYPASS_CSSTP) ++ { ++ if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEnable = rmacfg.discard_storm_filter; ++ } ++ else if (type == BYPASS_LLDP) ++ { ++ if ((retVal = rtl8367c_getAsicRmaLldp(&tmp,&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEnable = rmacfg.discard_storm_filter; ++ } ++ else ++ return RT_ERR_INPUT; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_rate_stormControlExtPortmask_set ++ * Description: ++ * Set externsion storm control port mask ++ * Input: ++ * pPortmask - port mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_NOT_INIT - The module is not initial ++ * RT_ERR_INPUT - invalid input parameter ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_rate_stormControlExtPortmask_set(rtk_portmask_t *pPortmask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pPortmask) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtk_switch_portmask_L2P_get(pPortmask, &pmask)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicStormFilterExtEnablePortMask(pmask)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_rate_stormControlExtPortmask_get ++ * Description: ++ * Set externsion storm control port mask ++ * Input: ++ * None ++ * Output: ++ * pPortmask - port mask ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_NOT_INIT - The module is not initial ++ * RT_ERR_INPUT - invalid input parameter ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_rate_stormControlExtPortmask_get(rtk_portmask_t *pPortmask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pPortmask) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicStormFilterExtEnablePortMask(&pmask)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtk_switch_portmask_P2L_get(pmask, pPortmask)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_rate_stormControlExtEnable_set ++ * Description: ++ * Set externsion storm control state ++ * Input: ++ * stormType - storm group type ++ * enable - externsion storm control state ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_NOT_INIT - The module is not initial ++ * RT_ERR_INPUT - invalid input parameter ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_rate_stormControlExtEnable_set(rtk_rate_storm_group_t stormType, rtk_enable_t enable) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (stormType >= STORM_GROUP_END) ++ return RT_ERR_SFC_UNKNOWN_GROUP; ++ ++ if (enable >= RTK_ENABLE_END) ++ return RT_ERR_ENABLE; ++ ++ switch (stormType) ++ { ++ case STORM_GROUP_UNKNOWN_UNICAST: ++ if ((retVal = rtl8367c_setAsicStormFilterExtUnknownUnicastEnable(enable)) != RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_UNKNOWN_MULTICAST: ++ if ((retVal = rtl8367c_setAsicStormFilterExtUnknownMulticastEnable(enable)) != RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_MULTICAST: ++ if ((retVal = rtl8367c_setAsicStormFilterExtMulticastEnable(enable)) != RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_BROADCAST: ++ if ((retVal = rtl8367c_setAsicStormFilterExtBroadcastEnable(enable)) != RT_ERR_OK) ++ return retVal; ++ break; ++ default: ++ break; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_rate_stormControlExtEnable_get ++ * Description: ++ * Get externsion storm control state ++ * Input: ++ * stormType - storm group type ++ * Output: ++ * pEnable - externsion storm control state ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_NOT_INIT - The module is not initial ++ * RT_ERR_INPUT - invalid input parameter ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_rate_stormControlExtEnable_get(rtk_rate_storm_group_t stormType, rtk_enable_t *pEnable) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (stormType >= STORM_GROUP_END) ++ return RT_ERR_SFC_UNKNOWN_GROUP; ++ ++ if (NULL == pEnable) ++ return RT_ERR_NULL_POINTER; ++ ++ switch (stormType) ++ { ++ case STORM_GROUP_UNKNOWN_UNICAST: ++ if ((retVal = rtl8367c_getAsicStormFilterExtUnknownUnicastEnable((rtk_uint32 *)pEnable)) != RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_UNKNOWN_MULTICAST: ++ if ((retVal = rtl8367c_getAsicStormFilterExtUnknownMulticastEnable((rtk_uint32 *)pEnable)) != RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_MULTICAST: ++ if ((retVal = rtl8367c_getAsicStormFilterExtMulticastEnable((rtk_uint32 *)pEnable)) != RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_BROADCAST: ++ if ((retVal = rtl8367c_getAsicStormFilterExtBroadcastEnable((rtk_uint32 *)pEnable)) != RT_ERR_OK) ++ return retVal; ++ break; ++ default: ++ break; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_rate_stormControlExtMeterIdx_set ++ * Description: ++ * Set externsion storm control meter index ++ * Input: ++ * stormType - storm group type ++ * index - externsion storm control state ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_NOT_INIT - The module is not initial ++ * RT_ERR_INPUT - invalid input parameter ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_rate_stormControlExtMeterIdx_set(rtk_rate_storm_group_t stormType, rtk_uint32 index) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (stormType >= STORM_GROUP_END) ++ return RT_ERR_SFC_UNKNOWN_GROUP; ++ ++ if (index > RTK_MAX_METER_ID) ++ return RT_ERR_FILTER_METER_ID; ++ ++ switch (stormType) ++ { ++ case STORM_GROUP_UNKNOWN_UNICAST: ++ if ((retVal = rtl8367c_setAsicStormFilterExtUnknownUnicastMeter(index))!=RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_UNKNOWN_MULTICAST: ++ if ((retVal = rtl8367c_setAsicStormFilterExtUnknownMulticastMeter(index))!=RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_MULTICAST: ++ if ((retVal = rtl8367c_setAsicStormFilterExtMulticastMeter(index))!=RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_BROADCAST: ++ if ((retVal = rtl8367c_setAsicStormFilterExtBroadcastMeter(index))!=RT_ERR_OK) ++ return retVal; ++ break; ++ default: ++ break; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_rate_stormControlExtMeterIdx_get ++ * Description: ++ * Get externsion storm control meter index ++ * Input: ++ * stormType - storm group type ++ * pIndex - externsion storm control state ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_NOT_INIT - The module is not initial ++ * RT_ERR_INPUT - invalid input parameter ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_rate_stormControlExtMeterIdx_get(rtk_rate_storm_group_t stormType, rtk_uint32 *pIndex) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (stormType >= STORM_GROUP_END) ++ return RT_ERR_SFC_UNKNOWN_GROUP; ++ ++ if(NULL == pIndex) ++ return RT_ERR_NULL_POINTER; ++ ++ switch (stormType) ++ { ++ case STORM_GROUP_UNKNOWN_UNICAST: ++ if ((retVal = rtl8367c_getAsicStormFilterExtUnknownUnicastMeter(pIndex))!=RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_UNKNOWN_MULTICAST: ++ if ((retVal = rtl8367c_getAsicStormFilterExtUnknownMulticastMeter(pIndex))!=RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_MULTICAST: ++ if ((retVal = rtl8367c_getAsicStormFilterExtMulticastMeter(pIndex))!=RT_ERR_OK) ++ return retVal; ++ break; ++ case STORM_GROUP_BROADCAST: ++ if ((retVal = rtl8367c_getAsicStormFilterExtBroadcastMeter(pIndex))!=RT_ERR_OK) ++ return retVal; ++ break; ++ default: ++ break; ++ } ++ ++ return RT_ERR_OK; ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/svlan.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/svlan.c +new file mode 100644 +index 0000000000..bf4ef044d1 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/svlan.c +@@ -0,0 +1,2415 @@ ++/* ++ * 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 SVLAN module. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++rtk_uint8 svlan_mbrCfgUsage[RTL8367C_SVIDXNO]; ++rtk_uint16 svlan_mbrCfgVid[RTL8367C_SVIDXNO]; ++rtk_svlan_lookupType_t svlan_lookupType; ++/* Function Name: ++ * rtk_svlan_init ++ * Description: ++ * Initialize SVLAN Configuration ++ * Input: ++ * None ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * Ether type of S-tag in 802.1ad is 0x88a8 and there are existed ether type 0x9100 and 0x9200 for Q-in-Q SLAN design. ++ * User can set mathced ether type as service provider supported protocol. ++ */ ++rtk_api_ret_t rtk_svlan_init(void) ++{ ++ rtk_uint32 i; ++ rtk_api_ret_t retVal; ++ rtl8367c_svlan_memconf_t svlanMemConf; ++ rtl8367c_svlan_s2c_t svlanSP2CConf; ++ rtl8367c_svlan_mc2s_t svlanMC2SConf; ++ rtk_uint32 svidx; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /*default use C-priority*/ ++ if ((retVal = rtl8367c_setAsicSvlanPrioritySel(SPRISEL_CTAGPRI)) != RT_ERR_OK) ++ return retVal; ++ ++ /*Drop SVLAN untag frame*/ ++ if ((retVal = rtl8367c_setAsicSvlanIngressUntag(UNTAG_DROP)) != RT_ERR_OK) ++ return retVal; ++ ++ /*Drop SVLAN unmatch frame*/ ++ if ((retVal = rtl8367c_setAsicSvlanIngressUnmatch(UNMATCH_DROP)) != RT_ERR_OK) ++ return retVal; ++ ++ /*Set TPID to 0x88a8*/ ++ if ((retVal = rtl8367c_setAsicSvlanTpid(0x88a8)) != RT_ERR_OK) ++ return retVal; ++ ++ /*Clean Uplink Port Mask to none*/ ++ if ((retVal = rtl8367c_setAsicSvlanUplinkPortMask(0)) != RT_ERR_OK) ++ return retVal; ++ ++ /*Clean SVLAN Member Configuration*/ ++ for (i=0; i<= RTL8367C_SVIDXMAX; i++) ++ { ++ memset(&svlanMemConf, 0, sizeof(rtl8367c_svlan_memconf_t)); ++ if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ /*Clean C2S Configuration*/ ++ for (i=0; i<= RTL8367C_C2SIDXMAX; i++) ++ { ++ if ((retVal = rtl8367c_setAsicSvlanC2SConf(i, 0,0,0)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ /*Clean SP2C Configuration*/ ++ for (i=0; i <= RTL8367C_SP2CMAX ; i++) ++ { ++ memset(&svlanSP2CConf, 0, sizeof(rtl8367c_svlan_s2c_t)); ++ if ((retVal = rtl8367c_setAsicSvlanSP2CConf(i, &svlanSP2CConf)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ /*Clean MC2S Configuration*/ ++ for (i=0 ; i<= RTL8367C_MC2SIDXMAX; i++) ++ { ++ memset(&svlanMC2SConf, 0, sizeof(rtl8367c_svlan_mc2s_t)); ++ if ((retVal = rtl8367c_setAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ ++ if ((retVal = rtk_svlan_lookupType_set(SVLAN_LOOKUP_S64MBRCGF)) != RT_ERR_OK) ++ return retVal; ++ ++ ++ for (svidx = 0; svidx <= RTL8367C_SVIDXMAX; svidx++) ++ { ++ svlan_mbrCfgUsage[svidx] = FALSE; ++ } ++ ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_svlan_servicePort_add ++ * Description: ++ * Add one service port in the specified device ++ * 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 number. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * This API is setting which port is connected to provider switch. All frames receiving from this port must ++ * contain accept SVID in S-tag field. ++ */ ++rtk_api_ret_t rtk_svlan_servicePort_add(rtk_port_t port) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmsk; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* check port valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if ((retVal = rtl8367c_getAsicSvlanUplinkPortMask(&pmsk)) != RT_ERR_OK) ++ return retVal; ++ ++ pmsk = pmsk | (1<RTK_MAX_NUM_OF_PROTO_TYPE) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicSvlanTpid(svlan_tag_id)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_svlan_tpidEntry_get ++ * Description: ++ * Get accepted S-VLAN ether type setting. ++ * Input: ++ * None ++ * Output: ++ * pSvlan_tag_id - Ether type of S-tag frame parsing in uplink ports. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * This API is setting which port is connected to provider switch. All frames receiving from this port must ++ * contain accept SVID in S-tag field. ++ */ ++rtk_api_ret_t rtk_svlan_tpidEntry_get(rtk_svlan_tpid_t *pSvlan_tag_id) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pSvlan_tag_id) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicSvlanTpid(pSvlan_tag_id)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_svlan_priorityRef_set ++ * Description: ++ * Set S-VLAN upstream priority reference setting. ++ * Input: ++ * ref - reference selection parameter. ++ * 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 API can set the upstream SVLAN tag priority reference source. The related priority ++ * sources are as following: ++ * - REF_INTERNAL_PRI, ++ * - REF_CTAG_PRI, ++ * - REF_SVLAN_PRI, ++ * - REF_PB_PRI. ++ */ ++rtk_api_ret_t rtk_svlan_priorityRef_set(rtk_svlan_pri_ref_t ref) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (ref >= REF_PRI_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicSvlanPrioritySel(ref)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_svlan_priorityRef_get ++ * Description: ++ * Get S-VLAN upstream priority reference setting. ++ * Input: ++ * None ++ * Output: ++ * pRef - reference selection parameter. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * The API can get the upstream SVLAN tag priority reference source. The related priority ++ * sources are as following: ++ * - REF_INTERNAL_PRI, ++ * - REF_CTAG_PRI, ++ * - REF_SVLAN_PRI, ++ * - REF_PB_PRI ++ */ ++rtk_api_ret_t rtk_svlan_priorityRef_get(rtk_svlan_pri_ref_t *pRef) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pRef) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicSvlanPrioritySel(pRef)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_svlan_memberPortEntry_set ++ * Description: ++ * Configure system SVLAN member content ++ * Input: ++ * svid - SVLAN id ++ * psvlan_cfg - SVLAN member configuration ++ * 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_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_PORT_MASK - Invalid portmask. ++ * RT_ERR_SVLAN_TABLE_FULL - SVLAN configuration is full. ++ * Note: ++ * The API can set system 64 accepted s-tag frame format. Only 64 SVID S-tag frame will be accpeted ++ * to receiving from uplink ports. Other SVID S-tag frame or S-untagged frame will be droped by default setup. ++ * - rtk_svlan_memberCfg_t->svid is SVID of SVLAN member configuration. ++ * - rtk_svlan_memberCfg_t->memberport is member port mask of SVLAN member configuration. ++ * - rtk_svlan_memberCfg_t->fid is filtering database of SVLAN member configuration. ++ * - rtk_svlan_memberCfg_t->priority is priority of SVLAN member configuration. ++ */ ++rtk_api_ret_t rtk_svlan_memberPortEntry_set(rtk_vlan_t svid, rtk_svlan_memberCfg_t *pSvlan_cfg) ++{ ++ rtk_api_ret_t retVal; ++ rtk_int32 i; ++ rtk_uint32 empty_idx; ++ rtl8367c_svlan_memconf_t svlanMemConf; ++ rtk_uint32 phyMbrPmask; ++ rtk_vlan_cfg_t vlanCfg; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pSvlan_cfg) ++ return RT_ERR_NULL_POINTER; ++ ++ if(svid > RTL8367C_VIDMAX) ++ return RT_ERR_SVLAN_VID; ++ ++ RTK_CHK_PORTMASK_VALID(&(pSvlan_cfg->memberport)); ++ ++ RTK_CHK_PORTMASK_VALID(&(pSvlan_cfg->untagport)); ++ ++ if (pSvlan_cfg->fiden > ENABLED) ++ return RT_ERR_ENABLE; ++ ++ if (pSvlan_cfg->fid > RTL8367C_FIDMAX) ++ return RT_ERR_L2_FID; ++ ++ if (pSvlan_cfg->priority > RTL8367C_PRIMAX) ++ return RT_ERR_VLAN_PRIORITY; ++ ++ if (pSvlan_cfg->efiden > ENABLED) ++ return RT_ERR_ENABLE; ++ ++ if (pSvlan_cfg->efid > RTL8367C_EFIDMAX) ++ return RT_ERR_L2_FID; ++ ++ if(SVLAN_LOOKUP_C4KVLAN == svlan_lookupType) ++ { ++ if ((retVal = rtk_vlan_get(svid, &vlanCfg)) != RT_ERR_OK) ++ return retVal; ++ ++ vlanCfg.mbr = pSvlan_cfg->memberport; ++ vlanCfg.untag = pSvlan_cfg->untagport; ++ ++ if ((retVal = rtk_vlan_set(svid, &vlanCfg)) != RT_ERR_OK) ++ return retVal; ++ ++ empty_idx = 0xFF; ++ ++ for (i = 0; i<= RTL8367C_SVIDXMAX; i++) ++ { ++ if (svid == svlan_mbrCfgVid[i] && TRUE == svlan_mbrCfgUsage[i]) ++ { ++ memset(&svlanMemConf, 0, sizeof(rtl8367c_svlan_memconf_t)); ++ svlanMemConf.vs_svid = svid; ++ svlanMemConf.vs_efiden = pSvlan_cfg->efiden; ++ svlanMemConf.vs_efid = pSvlan_cfg->efid; ++ svlanMemConf.vs_priority = pSvlan_cfg->priority; ++ ++ /*for create check*/ ++ if(0 == svlanMemConf.vs_efiden && 0 == svlanMemConf.vs_efid) ++ svlanMemConf.vs_efid = 1; ++ ++ if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++ } ++ else if (FALSE == svlan_mbrCfgUsage[i] && 0xFF == empty_idx) ++ { ++ empty_idx = i; ++ } ++ } ++ ++ if (empty_idx != 0xFF) ++ { ++ svlan_mbrCfgUsage[empty_idx] = TRUE; ++ svlan_mbrCfgVid[empty_idx] = svid; ++ ++ memset(&svlanMemConf, 0, sizeof(rtl8367c_svlan_memconf_t)); ++ svlanMemConf.vs_svid = svid; ++ svlanMemConf.vs_efiden = pSvlan_cfg->efiden; ++ svlanMemConf.vs_efid = pSvlan_cfg->efid; ++ svlanMemConf.vs_priority = pSvlan_cfg->priority; ++ ++ /*for create check*/ ++ if(0 == svlanMemConf.vs_efiden && 0 == svlanMemConf.vs_efid) ++ svlanMemConf.vs_efid = 1; ++ ++ if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(empty_idx, &svlanMemConf)) != RT_ERR_OK) ++ return retVal; ++ ++ } ++ ++ return RT_ERR_OK; ++ } ++ ++ ++ empty_idx = 0xFF; ++ ++ for (i = 0; i<= RTL8367C_SVIDXMAX; i++) ++ { ++ /* ++ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) ++ return retVal; ++ */ ++ if (svid == svlan_mbrCfgVid[i] && TRUE == svlan_mbrCfgUsage[i]) ++ { ++ svlanMemConf.vs_svid = svid; ++ ++ if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->memberport), &phyMbrPmask) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ ++ svlanMemConf.vs_member = phyMbrPmask; ++ ++ if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->untagport), &phyMbrPmask) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ ++ svlanMemConf.vs_untag = phyMbrPmask; ++ ++ svlanMemConf.vs_force_fid = pSvlan_cfg->fiden; ++ svlanMemConf.vs_fid_msti = pSvlan_cfg->fid; ++ svlanMemConf.vs_priority = pSvlan_cfg->priority; ++ svlanMemConf.vs_efiden = pSvlan_cfg->efiden; ++ svlanMemConf.vs_efid = pSvlan_cfg->efid; ++ ++ /*all items are reset means deleting*/ ++ if( 0 == svlanMemConf.vs_member && ++ 0 == svlanMemConf.vs_untag && ++ 0 == svlanMemConf.vs_force_fid && ++ 0 == svlanMemConf.vs_fid_msti && ++ 0 == svlanMemConf.vs_priority && ++ 0 == svlanMemConf.vs_efiden && ++ 0 == svlanMemConf.vs_efid) ++ { ++ svlan_mbrCfgUsage[i] = FALSE; ++ svlan_mbrCfgVid[i] = 0; ++ ++ /* Clear SVID also */ ++ svlanMemConf.vs_svid = 0; ++ } ++ else ++ { ++ svlan_mbrCfgUsage[i] = TRUE; ++ svlan_mbrCfgVid[i] = svlanMemConf.vs_svid; ++ ++ if(0 == svlanMemConf.vs_svid) ++ { ++ /*for create check*/ ++ if(0 == svlanMemConf.vs_efiden && 0 == svlanMemConf.vs_efid) ++ { ++ svlanMemConf.vs_efid = 1; ++ } ++ } ++ } ++ ++ if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++ } ++ else if (FALSE == svlan_mbrCfgUsage[i] && 0xFF == empty_idx) ++ { ++ empty_idx = i; ++ } ++ } ++ ++ if (empty_idx != 0xFF) ++ { ++ memset(&svlanMemConf, 0, sizeof(rtl8367c_svlan_memconf_t)); ++ svlanMemConf.vs_svid = svid; ++ ++ if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->memberport), &phyMbrPmask) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ ++ svlanMemConf.vs_member = phyMbrPmask; ++ ++ if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->untagport), &phyMbrPmask) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ ++ svlanMemConf.vs_untag = phyMbrPmask; ++ ++ svlanMemConf.vs_force_fid = pSvlan_cfg->fiden; ++ svlanMemConf.vs_fid_msti = pSvlan_cfg->fid; ++ svlanMemConf.vs_priority = pSvlan_cfg->priority; ++ ++ svlanMemConf.vs_efiden = pSvlan_cfg->efiden; ++ svlanMemConf.vs_efid = pSvlan_cfg->efid; ++ ++ /*change efid for empty svid 0*/ ++ if(0 == svlanMemConf.vs_svid) ++ { /*for create check*/ ++ if(0 == svlanMemConf.vs_efiden && 0 == svlanMemConf.vs_efid) ++ { ++ svlanMemConf.vs_efid = 1; ++ } ++ } ++ ++ svlan_mbrCfgUsage[empty_idx] = TRUE; ++ svlan_mbrCfgVid[empty_idx] = svlanMemConf.vs_svid; ++ ++ if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(empty_idx, &svlanMemConf)) != RT_ERR_OK) ++ { ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++ } ++ ++ return RT_ERR_SVLAN_TABLE_FULL; ++} ++ ++/* Function Name: ++ * rtk_svlan_memberPortEntry_get ++ * Description: ++ * Get SVLAN member Configure. ++ * Input: ++ * svid - SVLAN id ++ * Output: ++ * pSvlan_cfg - SVLAN member configuration ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can get system 64 accepted s-tag frame format. Only 64 SVID S-tag frame will be accpeted ++ * to receiving from uplink ports. Other SVID S-tag frame or S-untagged frame will be droped. ++ */ ++rtk_api_ret_t rtk_svlan_memberPortEntry_get(rtk_vlan_t svid, rtk_svlan_memberCfg_t *pSvlan_cfg) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 i; ++ rtl8367c_svlan_memconf_t svlanMemConf; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pSvlan_cfg) ++ return RT_ERR_NULL_POINTER; ++ ++ if (svid > RTL8367C_VIDMAX) ++ return RT_ERR_SVLAN_VID; ++ ++ ++ for (i = 0; i<= RTL8367C_SVIDXMAX; i++) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) ++ return retVal; ++ ++ if (svid == svlanMemConf.vs_svid) ++ { ++ pSvlan_cfg->svid = svlanMemConf.vs_svid; ++ ++ if(rtk_switch_portmask_P2L_get(svlanMemConf.vs_member,&(pSvlan_cfg->memberport)) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ ++ if(rtk_switch_portmask_P2L_get(svlanMemConf.vs_untag,&(pSvlan_cfg->untagport)) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ ++ pSvlan_cfg->fiden = svlanMemConf.vs_force_fid; ++ pSvlan_cfg->fid = svlanMemConf.vs_fid_msti; ++ pSvlan_cfg->priority = svlanMemConf.vs_priority; ++ pSvlan_cfg->efiden = svlanMemConf.vs_efiden; ++ pSvlan_cfg->efid = svlanMemConf.vs_efid; ++ ++ return RT_ERR_OK; ++ } ++ } ++ ++ return RT_ERR_SVLAN_ENTRY_NOT_FOUND; ++ ++} ++ ++/* Function Name: ++ * rtk_svlan_memberPortEntry_adv_set ++ * Description: ++ * Configure system SVLAN member by index ++ * Input: ++ * idx - Index (0 ~ 63) ++ * psvlan_cfg - SVLAN member configuration ++ * 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_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_PORT_MASK - Invalid portmask. ++ * RT_ERR_SVLAN_TABLE_FULL - SVLAN configuration is full. ++ * Note: ++ * The API can set system 64 accepted s-tag frame format by index. ++ * - rtk_svlan_memberCfg_t->svid is SVID of SVLAN member configuration. ++ * - rtk_svlan_memberCfg_t->memberport is member port mask of SVLAN member configuration. ++ * - rtk_svlan_memberCfg_t->fid is filtering database of SVLAN member configuration. ++ * - rtk_svlan_memberCfg_t->priority is priority of SVLAN member configuration. ++ */ ++rtk_api_ret_t rtk_svlan_memberPortEntry_adv_set(rtk_uint32 idx, rtk_svlan_memberCfg_t *pSvlan_cfg) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_svlan_memconf_t svlanMemConf; ++ rtk_uint32 phyMbrPmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pSvlan_cfg) ++ return RT_ERR_NULL_POINTER; ++ ++ if (idx > RTL8367C_SVIDXMAX) ++ return RT_ERR_SVLAN_ENTRY_INDEX; ++ ++ if (pSvlan_cfg->svid>RTL8367C_VIDMAX) ++ return RT_ERR_SVLAN_VID; ++ ++ RTK_CHK_PORTMASK_VALID(&(pSvlan_cfg->memberport)); ++ ++ RTK_CHK_PORTMASK_VALID(&(pSvlan_cfg->untagport)); ++ ++ if (pSvlan_cfg->fiden > ENABLED) ++ return RT_ERR_ENABLE; ++ ++ if (pSvlan_cfg->fid > RTL8367C_FIDMAX) ++ return RT_ERR_L2_FID; ++ ++ if (pSvlan_cfg->priority > RTL8367C_PRIMAX) ++ return RT_ERR_VLAN_PRIORITY; ++ ++ if (pSvlan_cfg->efiden > ENABLED) ++ return RT_ERR_ENABLE; ++ ++ if (pSvlan_cfg->efid > RTL8367C_EFIDMAX) ++ return RT_ERR_L2_FID; ++ ++ memset(&svlanMemConf, 0, sizeof(rtl8367c_svlan_memconf_t)); ++ svlanMemConf.vs_svid = pSvlan_cfg->svid; ++ if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->memberport), &phyMbrPmask) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ ++ svlanMemConf.vs_member = phyMbrPmask; ++ ++ if(rtk_switch_portmask_L2P_get(&(pSvlan_cfg->untagport), &phyMbrPmask) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ ++ svlanMemConf.vs_untag = phyMbrPmask; ++ ++ ++ svlanMemConf.vs_force_fid = pSvlan_cfg->fiden; ++ svlanMemConf.vs_fid_msti = pSvlan_cfg->fid; ++ svlanMemConf.vs_priority = pSvlan_cfg->priority; ++ svlanMemConf.vs_efiden = pSvlan_cfg->efiden; ++ svlanMemConf.vs_efid = pSvlan_cfg->efid; ++ ++ if(0 == svlanMemConf.vs_svid && ++ 0 == svlanMemConf.vs_member && ++ 0 == svlanMemConf.vs_untag && ++ 0 == svlanMemConf.vs_force_fid && ++ 0 == svlanMemConf.vs_fid_msti && ++ 0 == svlanMemConf.vs_priority && ++ 0 == svlanMemConf.vs_efiden && ++ 0 == svlanMemConf.vs_efid) ++ { ++ svlan_mbrCfgUsage[idx] = FALSE; ++ svlan_mbrCfgVid[idx] = 0; ++ } ++ else ++ { ++ svlan_mbrCfgUsage[idx] = TRUE; ++ svlan_mbrCfgVid[idx] = svlanMemConf.vs_svid; ++ } ++ ++ if ((retVal = rtl8367c_setAsicSvlanMemberConfiguration(idx, &svlanMemConf)) != RT_ERR_OK) ++ return retVal; ++ ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_svlan_memberPortEntry_adv_get ++ * Description: ++ * Get SVLAN member Configure by index. ++ * Input: ++ * idx - Index (0 ~ 63) ++ * Output: ++ * pSvlan_cfg - SVLAN member configuration ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can get system 64 accepted s-tag frame format. Only 64 SVID S-tag frame will be accpeted ++ * to receiving from uplink ports. Other SVID S-tag frame or S-untagged frame will be droped. ++ */ ++rtk_api_ret_t rtk_svlan_memberPortEntry_adv_get(rtk_uint32 idx, rtk_svlan_memberCfg_t *pSvlan_cfg) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_svlan_memconf_t svlanMemConf; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pSvlan_cfg) ++ return RT_ERR_NULL_POINTER; ++ ++ if (idx > RTL8367C_SVIDXMAX) ++ return RT_ERR_SVLAN_ENTRY_INDEX; ++ ++ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(idx, &svlanMemConf)) != RT_ERR_OK) ++ return retVal; ++ ++ pSvlan_cfg->svid = svlanMemConf.vs_svid; ++ if(rtk_switch_portmask_P2L_get(svlanMemConf.vs_member,&(pSvlan_cfg->memberport)) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ ++ if(rtk_switch_portmask_P2L_get(svlanMemConf.vs_untag,&(pSvlan_cfg->untagport)) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ ++ pSvlan_cfg->fiden = svlanMemConf.vs_force_fid; ++ pSvlan_cfg->fid = svlanMemConf.vs_fid_msti; ++ pSvlan_cfg->priority = svlanMemConf.vs_priority; ++ pSvlan_cfg->efiden = svlanMemConf.vs_efiden; ++ pSvlan_cfg->efid = svlanMemConf.vs_efid; ++ ++ return RT_ERR_OK; ++ ++} ++ ++/* Function Name: ++ * rtk_svlan_defaultSvlan_set ++ * Description: ++ * Configure default egress SVLAN. ++ * Input: ++ * port - Source port ++ * svid - SVLAN id ++ * 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_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. ++ * Note: ++ * The API can set port n S-tag format index while receiving frame from port n ++ * is transmit through uplink port with s-tag field ++ */ ++rtk_api_ret_t rtk_svlan_defaultSvlan_set(rtk_port_t port, rtk_vlan_t svid) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 i; ++ rtl8367c_svlan_memconf_t svlanMemConf; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ /* svid must be 0~4095 */ ++ if (svid > RTL8367C_VIDMAX) ++ return RT_ERR_SVLAN_VID; ++ ++ for (i = 0; i < RTL8367C_SVIDXNO; i++) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) ++ return retVal; ++ ++ if (svid == svlanMemConf.vs_svid) ++ { ++ if ((retVal = rtl8367c_setAsicSvlanDefaultVlan(rtk_switch_port_L2P_get(port), i)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++ } ++ } ++ ++ return RT_ERR_SVLAN_ENTRY_NOT_FOUND; ++} ++ ++/* Function Name: ++ * rtk_svlan_defaultSvlan_get ++ * Description: ++ * Get the configure default egress SVLAN. ++ * Input: ++ * port - Source port ++ * Output: ++ * pSvid - SVLAN VID ++ * 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 port n S-tag format index while receiving frame from port n ++ * is transmit through uplink port with s-tag field ++ */ ++rtk_api_ret_t rtk_svlan_defaultSvlan_get(rtk_port_t port, rtk_vlan_t *pSvid) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 idx; ++ rtl8367c_svlan_memconf_t svlanMemConf; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pSvid) ++ return RT_ERR_NULL_POINTER; ++ ++ /* Check port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if ((retVal = rtl8367c_getAsicSvlanDefaultVlan(rtk_switch_port_L2P_get(port), &idx)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(idx, &svlanMemConf)) != RT_ERR_OK) ++ return retVal; ++ ++ *pSvid = svlanMemConf.vs_svid; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_svlan_c2s_add ++ * Description: ++ * Configure SVLAN C2S table ++ * Input: ++ * vid - VLAN ID ++ * src_port - Ingress Port ++ * svid - SVLAN VID ++ * 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_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_VLAN_VID - Invalid VID parameter. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can set system C2S configuration. ASIC will check upstream's VID and assign related ++ * SVID to mathed packet. There are 128 SVLAN C2S configurations. ++ */ ++rtk_api_ret_t rtk_svlan_c2s_add(rtk_vlan_t vid, rtk_port_t src_port, rtk_vlan_t svid) ++{ ++ rtk_api_ret_t retVal, i; ++ rtk_uint32 empty_idx; ++ rtk_uint32 evid, pmsk, svidx, c2s_svidx; ++ rtl8367c_svlan_memconf_t svlanMemConf; ++ rtk_port_t phyPort; ++ rtk_uint16 doneFlag; ++ ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ ++ if (vid > RTL8367C_VIDMAX) ++ return RT_ERR_VLAN_VID; ++ ++ if (svid > RTL8367C_VIDMAX) ++ return RT_ERR_SVLAN_VID; ++ ++ /* Check port Valid */ ++ RTK_CHK_PORT_VALID(src_port); ++ ++ phyPort = rtk_switch_port_L2P_get(src_port); ++ ++ empty_idx = 0xFFFF; ++ svidx = 0xFFFF; ++ doneFlag = FALSE; ++ ++ for (i = 0; i<= RTL8367C_SVIDXMAX; i++) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) ++ return retVal; ++ ++ if (svid == svlanMemConf.vs_svid) ++ { ++ svidx = i; ++ break; ++ } ++ } ++ ++ if (0xFFFF == svidx) ++ return RT_ERR_SVLAN_VID; ++ ++ for (i=RTL8367C_C2SIDXMAX; i>=0; i--) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanC2SConf(i, &evid, &pmsk, &c2s_svidx)) != RT_ERR_OK) ++ return retVal; ++ ++ if (evid == vid) ++ { ++ /* Check Src_port */ ++ if(pmsk & (1 << phyPort)) ++ { ++ /* Check SVIDX */ ++ if(c2s_svidx == svidx) ++ { ++ /* All the same, do nothing */ ++ } ++ else ++ { ++ /* New svidx, remove src_port and find a new slot to add a new enrty */ ++ pmsk = pmsk & ~(1 << phyPort); ++ if(pmsk == 0) ++ c2s_svidx = 0; ++ ++ if ((retVal = rtl8367c_setAsicSvlanC2SConf(i, vid, pmsk, c2s_svidx)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ else ++ { ++ if(c2s_svidx == svidx && doneFlag == FALSE) ++ { ++ pmsk = pmsk | (1 << phyPort); ++ if ((retVal = rtl8367c_setAsicSvlanC2SConf(i, vid, pmsk, svidx)) != RT_ERR_OK) ++ return retVal; ++ ++ doneFlag = TRUE; ++ } ++ } ++ } ++ else if (evid==0&&pmsk==0) ++ { ++ empty_idx = i; ++ } ++ } ++ ++ if (0xFFFF != empty_idx && doneFlag ==FALSE) ++ { ++ if ((retVal = rtl8367c_setAsicSvlanC2SConf(empty_idx, vid, (1< RTL8367C_EVIDMAX) ++ return RT_ERR_VLAN_VID; ++ ++ /* Check port Valid */ ++ RTK_CHK_PORT_VALID(src_port); ++ phyPort = rtk_switch_port_L2P_get(src_port); ++ ++ for (i = 0; i <= RTL8367C_C2SIDXMAX; i++) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanC2SConf(i, &evid, &pmsk, &svidx)) != RT_ERR_OK) ++ return retVal; ++ ++ if (evid == vid) ++ { ++ if(pmsk & (1 << phyPort)) ++ { ++ pmsk = pmsk & ~(1 << phyPort); ++ if(pmsk == 0) ++ { ++ vid = 0; ++ svidx = 0; ++ } ++ ++ if ((retVal = rtl8367c_setAsicSvlanC2SConf(i, vid, pmsk, svidx)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++ } ++ } ++ } ++ ++ return RT_ERR_OUT_OF_RANGE; ++} ++ ++/* Function Name: ++ * rtk_svlan_c2s_get ++ * Description: ++ * Get configure SVLAN C2S table ++ * Input: ++ * vid - VLAN ID ++ * src_port - Ingress Port ++ * Output: ++ * pSvid - SVLAN ID ++ * 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. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * Note: ++ * The API can get system C2S configuration. There are 128 SVLAN C2S configurations. ++ */ ++rtk_api_ret_t rtk_svlan_c2s_get(rtk_vlan_t vid, rtk_port_t src_port, rtk_vlan_t *pSvid) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 i; ++ rtk_uint32 evid, pmsk, svidx; ++ rtl8367c_svlan_memconf_t svlanMemConf; ++ rtk_port_t phyPort; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pSvid) ++ return RT_ERR_NULL_POINTER; ++ ++ if (vid > RTL8367C_VIDMAX) ++ return RT_ERR_VLAN_VID; ++ ++ /* Check port Valid */ ++ RTK_CHK_PORT_VALID(src_port); ++ phyPort = rtk_switch_port_L2P_get(src_port); ++ ++ for (i = 0; i <= RTL8367C_C2SIDXMAX; i++) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanC2SConf(i, &evid, &pmsk, &svidx)) != RT_ERR_OK) ++ return retVal; ++ ++ if (evid == vid) ++ { ++ if(pmsk & (1 << phyPort)) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(svidx, &svlanMemConf)) != RT_ERR_OK) ++ return retVal; ++ ++ *pSvid = svlanMemConf.vs_svid; ++ return RT_ERR_OK; ++ } ++ } ++ } ++ ++ return RT_ERR_OUT_OF_RANGE; ++} ++ ++/* Function Name: ++ * rtk_svlan_untag_action_set ++ * Description: ++ * Configure Action of downstream UnStag packet ++ * Input: ++ * action - Action for UnStag ++ * svid - The SVID assigned to UnStag packet ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can configure action of downstream Un-Stag packet. A SVID assigned ++ * to the un-stag is also supported by this API. The parameter of svid is ++ * only referenced when the action is set to UNTAG_ASSIGN ++ */ ++rtk_api_ret_t rtk_svlan_untag_action_set(rtk_svlan_untag_action_t action, rtk_vlan_t svid) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 i; ++ rtl8367c_svlan_memconf_t svlanMemConf; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (action >= UNTAG_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if(action == UNTAG_ASSIGN) ++ { ++ if (svid > RTL8367C_VIDMAX) ++ return RT_ERR_SVLAN_VID; ++ } ++ ++ if ((retVal = rtl8367c_setAsicSvlanIngressUntag((rtk_uint32)action)) != RT_ERR_OK) ++ return retVal; ++ ++ if(action == UNTAG_ASSIGN) ++ { ++ for (i = 0; i < RTL8367C_SVIDXNO; i++) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) ++ return retVal; ++ ++ if (svid == svlanMemConf.vs_svid) ++ { ++ if ((retVal = rtl8367c_setAsicSvlanUntagVlan(i)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++ } ++ } ++ ++ return RT_ERR_SVLAN_ENTRY_NOT_FOUND; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_svlan_untag_action_get ++ * Description: ++ * Get Action of downstream UnStag packet ++ * Input: ++ * None ++ * Output: ++ * pAction - Action for UnStag ++ * pSvid - The SVID assigned to UnStag packet ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can Get action of downstream Un-Stag packet. A SVID assigned ++ * to the un-stag is also retrieved by this API. The parameter pSvid is ++ * only refernced when the action is UNTAG_ASSIGN ++ */ ++rtk_api_ret_t rtk_svlan_untag_action_get(rtk_svlan_untag_action_t *pAction, rtk_vlan_t *pSvid) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 svidx; ++ rtl8367c_svlan_memconf_t svlanMemConf; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pAction || NULL == pSvid) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicSvlanIngressUntag(pAction)) != RT_ERR_OK) ++ return retVal; ++ ++ if(*pAction == UNTAG_ASSIGN) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanUntagVlan(&svidx)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(svidx, &svlanMemConf)) != RT_ERR_OK) ++ return retVal; ++ ++ *pSvid = svlanMemConf.vs_svid; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_svlan_unmatch_action_set ++ * Description: ++ * Configure Action of downstream Unmatch packet ++ * Input: ++ * action - Action for Unmatch ++ * svid - The SVID assigned to Unmatch packet ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can configure action of downstream Un-match packet. A SVID assigned ++ * to the un-match is also supported by this API. The parameter od svid is ++ * only refernced when the action is set to UNMATCH_ASSIGN ++ */ ++rtk_api_ret_t rtk_svlan_unmatch_action_set(rtk_svlan_unmatch_action_t action, rtk_vlan_t svid) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 i; ++ rtl8367c_svlan_memconf_t svlanMemConf; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (action >= UNMATCH_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if (action == UNMATCH_ASSIGN) ++ { ++ if (svid > RTL8367C_VIDMAX) ++ return RT_ERR_SVLAN_VID; ++ } ++ ++ if ((retVal = rtl8367c_setAsicSvlanIngressUnmatch((rtk_uint32)action)) != RT_ERR_OK) ++ return retVal; ++ ++ if(action == UNMATCH_ASSIGN) ++ { ++ for (i = 0; i < RTL8367C_SVIDXNO; i++) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) ++ return retVal; ++ ++ if (svid == svlanMemConf.vs_svid) ++ { ++ if ((retVal = rtl8367c_setAsicSvlanUnmatchVlan(i)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++ } ++ } ++ ++ return RT_ERR_SVLAN_ENTRY_NOT_FOUND; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_svlan_unmatch_action_get ++ * Description: ++ * Get Action of downstream Unmatch packet ++ * Input: ++ * None ++ * Output: ++ * pAction - Action for Unmatch ++ * pSvid - The SVID assigned to Unmatch packet ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can Get action of downstream Un-match packet. A SVID assigned ++ * to the un-match is also retrieved by this API. The parameter pSvid is ++ * only refernced when the action is UNMATCH_ASSIGN ++ */ ++rtk_api_ret_t rtk_svlan_unmatch_action_get(rtk_svlan_unmatch_action_t *pAction, rtk_vlan_t *pSvid) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 svidx; ++ rtl8367c_svlan_memconf_t svlanMemConf; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pAction || NULL == pSvid) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicSvlanIngressUnmatch(pAction)) != RT_ERR_OK) ++ return retVal; ++ ++ if(*pAction == UNMATCH_ASSIGN) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanUnmatchVlan(&svidx)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(svidx, &svlanMemConf)) != RT_ERR_OK) ++ return retVal; ++ ++ *pSvid = svlanMemConf.vs_svid; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_svlan_unassign_action_set ++ * Description: ++ * Configure Action of upstream without svid assign action ++ * Input: ++ * action - Action for Un-assign ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can configure action of upstream Un-assign svid packet. If action is not ++ * trap to CPU, the port-based SVID sure be assign as system need ++ */ ++rtk_api_ret_t rtk_svlan_unassign_action_set(rtk_svlan_unassign_action_t action) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (action >= UNASSIGN_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ retVal = rtl8367c_setAsicSvlanEgressUnassign((rtk_uint32)action); ++ ++ return retVal; ++} ++ ++/* Function Name: ++ * rtk_svlan_unassign_action_get ++ * Description: ++ * Get action of upstream without svid assignment ++ * Input: ++ * None ++ * Output: ++ * pAction - Action for Un-assign ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * Note: ++ * None ++ */ ++rtk_api_ret_t rtk_svlan_unassign_action_get(rtk_svlan_unassign_action_t *pAction) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pAction) ++ return RT_ERR_NULL_POINTER; ++ ++ retVal = rtl8367c_getAsicSvlanEgressUnassign(pAction); ++ ++ return retVal; ++} ++ ++/* Function Name: ++ * rtk_svlan_dmac_vidsel_set ++ * Description: ++ * Set DMAC CVID selection ++ * Input: ++ * port - Port ++ * enable - state of DMAC CVID Selection ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * This API can set DMAC CVID Selection state ++ */ ++rtk_api_ret_t rtk_svlan_dmac_vidsel_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_setAsicSvlanDmacCvidSel(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_svlan_dmac_vidsel_get ++ * Description: ++ * Get DMAC CVID selection ++ * Input: ++ * port - Port ++ * Output: ++ * pEnable - state of DMAC CVID Selection ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * This API can get DMAC CVID Selection state ++ */ ++rtk_api_ret_t rtk_svlan_dmac_vidsel_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_getAsicSvlanDmacCvidSel(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_svlan_ipmc2s_add ++ * Description: ++ * add ip multicast address to SVLAN ++ * Input: ++ * svid - SVLAN VID ++ * ipmc - ip multicast address ++ * ipmcMsk - ip multicast mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can set IP mutlicast to SVID configuration. If upstream packet is IPv4 multicast ++ * packet and DIP is matched MC2S configuration, ASIC will assign egress SVID to the packet. ++ * There are 32 SVLAN multicast configurations for IP and L2 multicast. ++ */ ++rtk_api_ret_t rtk_svlan_ipmc2s_add(ipaddr_t ipmc, ipaddr_t ipmcMsk,rtk_vlan_t svid) ++{ ++ rtk_api_ret_t retVal, i; ++ rtk_uint32 empty_idx; ++ rtk_uint32 svidx; ++ rtl8367c_svlan_memconf_t svlanMemConf; ++ rtl8367c_svlan_mc2s_t svlanMC2SConf; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (svid > RTL8367C_VIDMAX) ++ return RT_ERR_SVLAN_VID; ++ ++ if ((ipmc&0xF0000000)!=0xE0000000) ++ return RT_ERR_INPUT; ++ ++ svidx = 0xFFFF; ++ ++ for (i = 0; i < RTL8367C_SVIDXNO; i++) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) ++ return retVal; ++ ++ if (svid == svlanMemConf.vs_svid) ++ { ++ svidx = i; ++ break; ++ } ++ } ++ ++ if (0xFFFF == svidx) ++ return RT_ERR_SVLAN_ENTRY_NOT_FOUND; ++ ++ ++ empty_idx = 0xFFFF; ++ ++ for (i = RTL8367C_MC2SIDXMAX; i >= 0; i--) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) ++ return retVal; ++ ++ if (TRUE == svlanMC2SConf.valid) ++ { ++ if (svlanMC2SConf.format == SVLAN_MC2S_MODE_IP && ++ svlanMC2SConf.sdata==ipmc&& ++ svlanMC2SConf.smask==ipmcMsk) ++ { ++ svlanMC2SConf.svidx = svidx; ++ if ((retVal = rtl8367c_setAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ else ++ { ++ empty_idx = i; ++ } ++ } ++ ++ if (empty_idx!=0xFFFF) ++ { ++ svlanMC2SConf.valid = TRUE; ++ svlanMC2SConf.svidx = svidx; ++ svlanMC2SConf.format = SVLAN_MC2S_MODE_IP; ++ svlanMC2SConf.sdata = ipmc; ++ svlanMC2SConf.smask = ipmcMsk; ++ if ((retVal = rtl8367c_setAsicSvlanMC2SConf(empty_idx, &svlanMC2SConf)) != RT_ERR_OK) ++ return retVal; ++ return RT_ERR_OK; ++ } ++ ++ return RT_ERR_OUT_OF_RANGE; ++ ++} ++ ++/* Function Name: ++ * rtk_svlan_ipmc2s_del ++ * Description: ++ * delete ip multicast address to SVLAN ++ * Input: ++ * ipmc - ip multicast address ++ * ipmcMsk - ip multicast mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * Note: ++ * The API can delete IP mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. ++ */ ++rtk_api_ret_t rtk_svlan_ipmc2s_del(ipaddr_t ipmc, ipaddr_t ipmcMsk) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 i; ++ rtl8367c_svlan_mc2s_t svlanMC2SConf; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ((ipmc&0xF0000000)!=0xE0000000) ++ return RT_ERR_INPUT; ++ ++ for (i = 0; i <= RTL8367C_MC2SIDXMAX; i++) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) ++ return retVal; ++ ++ if (TRUE == svlanMC2SConf.valid) ++ { ++ if (svlanMC2SConf.format == SVLAN_MC2S_MODE_IP && ++ svlanMC2SConf.sdata==ipmc&& ++ svlanMC2SConf.smask==ipmcMsk) ++ { ++ memset(&svlanMC2SConf, 0, sizeof(rtl8367c_svlan_mc2s_t)); ++ if ((retVal = rtl8367c_setAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) ++ return retVal; ++ return RT_ERR_OK; ++ } ++ } ++ } ++ ++ return RT_ERR_OUT_OF_RANGE; ++} ++ ++/* Function Name: ++ * rtk_svlan_ipmc2s_get ++ * Description: ++ * Get ip multicast address to SVLAN ++ * Input: ++ * ipmc - ip multicast address ++ * ipmcMsk - ip multicast mask ++ * Output: ++ * pSvid - SVLAN VID ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * Note: ++ * The API can get IP mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. ++ */ ++rtk_api_ret_t rtk_svlan_ipmc2s_get(ipaddr_t ipmc, ipaddr_t ipmcMsk, rtk_vlan_t *pSvid) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 i; ++ rtl8367c_svlan_memconf_t svlanMemConf; ++ rtl8367c_svlan_mc2s_t svlanMC2SConf; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pSvid) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((ipmc&0xF0000000)!=0xE0000000) ++ return RT_ERR_INPUT; ++ ++ for (i = 0; i <= RTL8367C_MC2SIDXMAX; i++) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) ++ return retVal; ++ ++ if (TRUE == svlanMC2SConf.valid && ++ svlanMC2SConf.format == SVLAN_MC2S_MODE_IP && ++ svlanMC2SConf.sdata == ipmc && ++ svlanMC2SConf.smask == ipmcMsk) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(svlanMC2SConf.svidx, &svlanMemConf)) != RT_ERR_OK) ++ return retVal; ++ *pSvid = svlanMemConf.vs_svid; ++ return RT_ERR_OK; ++ } ++ } ++ ++ return RT_ERR_OUT_OF_RANGE; ++} ++ ++/* Function Name: ++ * rtk_svlan_l2mc2s_add ++ * Description: ++ * Add L2 multicast address to SVLAN ++ * Input: ++ * mac - L2 multicast address ++ * macMsk - L2 multicast address mask ++ * svid - SVLAN VID ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_SVLAN_ENTRY_NOT_FOUND - specified svlan entry not found. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can set L2 Mutlicast to SVID configuration. If upstream packet is L2 multicast ++ * packet and DMAC is matched, ASIC will assign egress SVID to the packet. There are 32 ++ * SVLAN multicast configurations for IP and L2 multicast. ++ */ ++rtk_api_ret_t rtk_svlan_l2mc2s_add(rtk_mac_t mac, rtk_mac_t macMsk, rtk_vlan_t svid) ++{ ++ rtk_api_ret_t retVal, i; ++ rtk_uint32 empty_idx; ++ rtk_uint32 svidx, l2add, l2Mask; ++ rtl8367c_svlan_memconf_t svlanMemConf; ++ rtl8367c_svlan_mc2s_t svlanMC2SConf; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (svid > RTL8367C_VIDMAX) ++ return RT_ERR_SVLAN_VID; ++ ++ if (mac.octet[0]!= 1&&mac.octet[1]!=0) ++ return RT_ERR_INPUT; ++ ++ l2add = (mac.octet[2] << 24) | (mac.octet[3] << 16) | (mac.octet[4] << 8) | mac.octet[5]; ++ l2Mask = (macMsk.octet[2] << 24) | (macMsk.octet[3] << 16) | (macMsk.octet[4] << 8) | macMsk.octet[5]; ++ ++ svidx = 0xFFFF; ++ ++ for (i = 0; i < RTL8367C_SVIDXNO; i++) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) ++ return retVal; ++ ++ if (svid == svlanMemConf.vs_svid) ++ { ++ svidx = i; ++ break; ++ } ++ } ++ ++ if (0xFFFF == svidx) ++ return RT_ERR_SVLAN_ENTRY_NOT_FOUND; ++ ++ empty_idx = 0xFFFF; ++ ++ for (i = RTL8367C_MC2SIDXMAX; i >=0; i--) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) ++ return retVal; ++ ++ if (TRUE == svlanMC2SConf.valid) ++ { ++ if (svlanMC2SConf.format == SVLAN_MC2S_MODE_MAC && ++ svlanMC2SConf.sdata==l2add&& ++ svlanMC2SConf.smask==l2Mask) ++ { ++ svlanMC2SConf.svidx = svidx; ++ if ((retVal = rtl8367c_setAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ else ++ { ++ empty_idx = i; ++ } ++ } ++ ++ if (empty_idx!=0xFFFF) ++ { ++ svlanMC2SConf.valid = TRUE; ++ svlanMC2SConf.svidx = svidx; ++ svlanMC2SConf.format = SVLAN_MC2S_MODE_MAC; ++ svlanMC2SConf.sdata = l2add; ++ svlanMC2SConf.smask = l2Mask; ++ ++ if ((retVal = rtl8367c_setAsicSvlanMC2SConf(empty_idx, &svlanMC2SConf)) != RT_ERR_OK) ++ return retVal; ++ return RT_ERR_OK; ++ } ++ ++ return RT_ERR_OUT_OF_RANGE; ++} ++ ++/* Function Name: ++ * rtk_svlan_l2mc2s_del ++ * Description: ++ * delete L2 multicast address to SVLAN ++ * Input: ++ * mac - L2 multicast address ++ * macMsk - L2 multicast address mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * Note: ++ * The API can delete Mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. ++ */ ++rtk_api_ret_t rtk_svlan_l2mc2s_del(rtk_mac_t mac, rtk_mac_t macMsk) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 i; ++ rtk_uint32 l2add, l2Mask; ++ rtl8367c_svlan_mc2s_t svlanMC2SConf; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (mac.octet[0]!= 1&&mac.octet[1]!=0) ++ return RT_ERR_INPUT; ++ ++ l2add = (mac.octet[2] << 24) | (mac.octet[3] << 16) | (mac.octet[4] << 8) | mac.octet[5]; ++ l2Mask = (macMsk.octet[2] << 24) | (macMsk.octet[3] << 16) | (macMsk.octet[4] << 8) | macMsk.octet[5]; ++ ++ for (i = 0; i <= RTL8367C_MC2SIDXMAX; i++) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) ++ return retVal; ++ ++ if (TRUE == svlanMC2SConf.valid) ++ { ++ if (svlanMC2SConf.format == SVLAN_MC2S_MODE_MAC && ++ svlanMC2SConf.sdata==l2add&& ++ svlanMC2SConf.smask==l2Mask) ++ { ++ memset(&svlanMC2SConf, 0, sizeof(rtl8367c_svlan_mc2s_t)); ++ if ((retVal = rtl8367c_setAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) ++ return retVal; ++ return RT_ERR_OK; ++ } ++ } ++ } ++ ++ return RT_ERR_OUT_OF_RANGE; ++} ++ ++/* Function Name: ++ * rtk_svlan_l2mc2s_get ++ * Description: ++ * Get L2 multicast address to SVLAN ++ * Input: ++ * mac - L2 multicast address ++ * macMsk - L2 multicast address mask ++ * Output: ++ * pSvid - SVLAN VID ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * Note: ++ * The API can get L2 mutlicast to SVID configuration. There are 32 SVLAN multicast configurations for IP and L2 multicast. ++ */ ++rtk_api_ret_t rtk_svlan_l2mc2s_get(rtk_mac_t mac, rtk_mac_t macMsk, rtk_vlan_t *pSvid) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 i; ++ rtk_uint32 l2add,l2Mask; ++ rtl8367c_svlan_memconf_t svlanMemConf; ++ rtl8367c_svlan_mc2s_t svlanMC2SConf; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pSvid) ++ return RT_ERR_NULL_POINTER; ++ ++ if (mac.octet[0]!= 1&&mac.octet[1]!=0) ++ return RT_ERR_INPUT; ++ ++ l2add = (mac.octet[2] << 24) | (mac.octet[3] << 16) | (mac.octet[4] << 8) | mac.octet[5]; ++ l2Mask = (macMsk.octet[2] << 24) | (macMsk.octet[3] << 16) | (macMsk.octet[4] << 8) | macMsk.octet[5]; ++ ++ for (i = 0; i <= RTL8367C_MC2SIDXMAX; i++) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanMC2SConf(i, &svlanMC2SConf)) != RT_ERR_OK) ++ return retVal; ++ ++ if (TRUE == svlanMC2SConf.valid) ++ { ++ if (svlanMC2SConf.format == SVLAN_MC2S_MODE_MAC && ++ svlanMC2SConf.sdata==l2add&& ++ svlanMC2SConf.smask==l2Mask) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(svlanMC2SConf.svidx, &svlanMemConf)) != RT_ERR_OK) ++ return retVal; ++ *pSvid = svlanMemConf.vs_svid; ++ ++ return RT_ERR_OK; ++ } ++ } ++ } ++ ++ return RT_ERR_OUT_OF_RANGE; ++} ++ ++/* Function Name: ++ * rtk_svlan_sp2c_add ++ * Description: ++ * Add system SP2C configuration ++ * Input: ++ * cvid - VLAN ID ++ * dst_port - Destination port of SVLAN to CVLAN configuration ++ * svid - SVLAN VID ++ * 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_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_VLAN_VID - Invalid VID parameter. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * The API can add SVID & Destination Port to CVLAN configuration. The downstream frames with assigned ++ * SVID will be add C-tag with assigned CVID if the output port is the assigned destination port. ++ * There are 128 SP2C configurations. ++ */ ++rtk_api_ret_t rtk_svlan_sp2c_add(rtk_vlan_t svid, rtk_port_t dst_port, rtk_vlan_t cvid) ++{ ++ rtk_api_ret_t retVal, i; ++ rtk_uint32 empty_idx, svidx; ++ rtl8367c_svlan_memconf_t svlanMemConf; ++ rtl8367c_svlan_s2c_t svlanSP2CConf; ++ rtk_port_t port; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (svid > RTL8367C_VIDMAX) ++ return RT_ERR_SVLAN_VID; ++ ++ if (cvid > RTL8367C_VIDMAX) ++ return RT_ERR_VLAN_VID; ++ ++ /* Check port Valid */ ++ RTK_CHK_PORT_VALID(dst_port); ++ port = rtk_switch_port_L2P_get(dst_port); ++ ++ svidx = 0xFFFF; ++ ++ for (i = 0; i < RTL8367C_SVIDXNO; i++) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) ++ return retVal; ++ ++ if (svid == svlanMemConf.vs_svid) ++ { ++ svidx = i; ++ break; ++ } ++ } ++ ++ if (0xFFFF == svidx) ++ return RT_ERR_SVLAN_ENTRY_NOT_FOUND; ++ ++ empty_idx = 0xFFFF; ++ ++ for (i=RTL8367C_SP2CMAX; i >=0 ; i--) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanSP2CConf(i, &svlanSP2CConf)) != RT_ERR_OK) ++ return retVal; ++ ++ if ( (svlanSP2CConf.svidx == svidx) && (svlanSP2CConf.dstport == port) && (svlanSP2CConf.valid == 1)) ++ { ++ empty_idx = i; ++ break; ++ } ++ else if (svlanSP2CConf.valid == 0) ++ { ++ empty_idx = i; ++ } ++ } ++ ++ if (empty_idx!=0xFFFF) ++ { ++ svlanSP2CConf.valid = 1; ++ svlanSP2CConf.vid = cvid; ++ svlanSP2CConf.svidx = svidx; ++ svlanSP2CConf.dstport = port; ++ ++ if ((retVal = rtl8367c_setAsicSvlanSP2CConf(empty_idx, &svlanSP2CConf)) != RT_ERR_OK) ++ return retVal; ++ return RT_ERR_OK; ++ } ++ ++ return RT_ERR_OUT_OF_RANGE; ++ ++} ++ ++/* Function Name: ++ * rtk_svlan_sp2c_get ++ * Description: ++ * Get configure system SP2C content ++ * Input: ++ * svid - SVLAN VID ++ * dst_port - Destination port of SVLAN to CVLAN configuration ++ * Output: ++ * pCvid - VLAN ID ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_PORT_ID - Invalid port number. ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * Note: ++ * The API can get SVID & Destination Port to CVLAN configuration. There are 128 SP2C configurations. ++ */ ++rtk_api_ret_t rtk_svlan_sp2c_get(rtk_vlan_t svid, rtk_port_t dst_port, rtk_vlan_t *pCvid) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 i, svidx; ++ rtl8367c_svlan_memconf_t svlanMemConf; ++ rtl8367c_svlan_s2c_t svlanSP2CConf; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pCvid) ++ return RT_ERR_NULL_POINTER; ++ ++ if (svid > RTL8367C_VIDMAX) ++ return RT_ERR_SVLAN_VID; ++ ++ /* Check port Valid */ ++ RTK_CHK_PORT_VALID(dst_port); ++ dst_port = rtk_switch_port_L2P_get(dst_port); ++ ++ svidx = 0xFFFF; ++ ++ for (i = 0; i < RTL8367C_SVIDXNO; i++) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) ++ return retVal; ++ ++ if (svid == svlanMemConf.vs_svid) ++ { ++ svidx = i; ++ break; ++ } ++ } ++ ++ if (0xFFFF == svidx) ++ return RT_ERR_SVLAN_ENTRY_NOT_FOUND; ++ ++ for (i = 0; i <= RTL8367C_SP2CMAX; i++) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanSP2CConf(i, &svlanSP2CConf)) != RT_ERR_OK) ++ return retVal; ++ ++ if ( (svlanSP2CConf.svidx == svidx) && (svlanSP2CConf.dstport == dst_port) && (svlanSP2CConf.valid == 1) ) ++ { ++ *pCvid = svlanSP2CConf.vid; ++ return RT_ERR_OK; ++ } ++ } ++ ++ return RT_ERR_OUT_OF_RANGE; ++} ++ ++/* Function Name: ++ * rtk_svlan_sp2c_del ++ * Description: ++ * Delete system SP2C configuration ++ * Input: ++ * svid - SVLAN VID ++ * dst_port - Destination port of SVLAN to CVLAN 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. ++ * RT_ERR_SVLAN_VID - Invalid SVLAN VID parameter. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * Note: ++ * The API can delete SVID & Destination Port to CVLAN configuration. There are 128 SP2C configurations. ++ */ ++rtk_api_ret_t rtk_svlan_sp2c_del(rtk_vlan_t svid, rtk_port_t dst_port) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 i, svidx; ++ rtl8367c_svlan_memconf_t svlanMemConf; ++ rtl8367c_svlan_s2c_t svlanSP2CConf; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (svid > RTL8367C_VIDMAX) ++ return RT_ERR_SVLAN_VID; ++ ++ /* Check port Valid */ ++ RTK_CHK_PORT_VALID(dst_port); ++ dst_port = rtk_switch_port_L2P_get(dst_port); ++ ++ svidx = 0xFFFF; ++ ++ for (i = 0; i < RTL8367C_SVIDXNO; i++) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanMemberConfiguration(i, &svlanMemConf)) != RT_ERR_OK) ++ return retVal; ++ ++ if (svid == svlanMemConf.vs_svid) ++ { ++ svidx = i; ++ break; ++ } ++ } ++ ++ if (0xFFFF == svidx) ++ return RT_ERR_SVLAN_ENTRY_NOT_FOUND; ++ ++ for (i = 0; i <= RTL8367C_SP2CMAX; i++) ++ { ++ if ((retVal = rtl8367c_getAsicSvlanSP2CConf(i, &svlanSP2CConf)) != RT_ERR_OK) ++ return retVal; ++ ++ if ( (svlanSP2CConf.svidx == svidx) && (svlanSP2CConf.dstport == dst_port) && (svlanSP2CConf.valid == 1) ) ++ { ++ svlanSP2CConf.valid = 0; ++ svlanSP2CConf.vid = 0; ++ svlanSP2CConf.svidx = 0; ++ svlanSP2CConf.dstport = 0; ++ ++ if ((retVal = rtl8367c_setAsicSvlanSP2CConf(i, &svlanSP2CConf)) != RT_ERR_OK) ++ return retVal; ++ return RT_ERR_OK; ++ } ++ ++ } ++ ++ return RT_ERR_OUT_OF_RANGE; ++} ++ ++/* Function Name: ++ * rtk_svlan_lookupType_set ++ * Description: ++ * Set lookup type of SVLAN ++ * Input: ++ * type - lookup type ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * Note: ++ * none ++ */ ++rtk_api_ret_t rtk_svlan_lookupType_set(rtk_svlan_lookupType_t type) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (type >= SVLAN_LOOKUP_END) ++ return RT_ERR_CHIP_NOT_SUPPORTED; ++ ++ ++ svlan_lookupType = type; ++ ++ retVal = rtl8367c_setAsicSvlanLookupType((rtk_uint32)type); ++ ++ return retVal; ++} ++ ++/* Function Name: ++ * rtk_svlan_lookupType_get ++ * Description: ++ * Get lookup type of SVLAN ++ * Input: ++ * pType - lookup type ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * Note: ++ * none ++ */ ++rtk_api_ret_t rtk_svlan_lookupType_get(rtk_svlan_lookupType_t *pType) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pType) ++ return RT_ERR_NULL_POINTER; ++ ++ retVal = rtl8367c_getAsicSvlanLookupType(pType); ++ ++ svlan_lookupType = *pType; ++ ++ return retVal; ++} ++ ++/* Function Name: ++ * rtk_svlan_trapPri_set ++ * Description: ++ * Set svlan trap priority ++ * Input: ++ * priority - priority for trap packets ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_QOS_INT_PRIORITY ++ * Note: ++ * None ++ */ ++rtk_api_ret_t rtk_svlan_trapPri_set(rtk_pri_t priority) ++{ ++ rtk_api_ret_t retVal; ++ ++ RTK_CHK_INIT_STATE(); ++ ++ if(priority > RTL8367C_PRIMAX) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ retVal = rtl8367c_setAsicSvlanTrapPriority(priority); ++ ++ return retVal; ++} /* end of rtk_svlan_trapPri_set */ ++ ++/* Function Name: ++ * rtk_svlan_trapPri_get ++ * Description: ++ * Get svlan trap priority ++ * Input: ++ * None ++ * Output: ++ * pPriority - priority for trap packets ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_NULL_POINTER - input parameter may be null pointer ++ * Note: ++ * None ++ */ ++rtk_api_ret_t rtk_svlan_trapPri_get(rtk_pri_t *pPriority) ++{ ++ rtk_api_ret_t retVal; ++ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pPriority) ++ return RT_ERR_NULL_POINTER; ++ ++ retVal = rtl8367c_getAsicSvlanTrapPriority(pPriority); ++ ++ return retVal; ++} /* end of rtk_svlan_trapPri_get */ ++ ++ ++/* Function Name: ++ * rtk_svlan_checkAndCreateMbr ++ * Description: ++ * Check and create Member configuration and return index ++ * Input: ++ * vid - VLAN id. ++ * Output: ++ * pIndex - Member configuration index ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_VLAN_VID - Invalid VLAN ID. ++ * RT_ERR_TBL_FULL - Member Configuration table full ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_svlan_checkAndCreateMbr(rtk_vlan_t vid, rtk_uint32 *pIndex) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 svidx; ++ rtk_uint32 empty_idx = 0xFFFF; ++ rtl8367c_svlan_memconf_t svlan_cfg; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* vid must be 0~4095 */ ++ if (vid > RTL8367C_VIDMAX) ++ return RT_ERR_VLAN_VID; ++ ++ /* Null pointer check */ ++ if(NULL == pIndex) ++ return RT_ERR_NULL_POINTER; ++ ++ /* Search exist entry */ ++ for (svidx = 0; svidx <= RTL8367C_SVIDXMAX; svidx++) ++ { ++ if(svlan_mbrCfgUsage[svidx] == TRUE) ++ { ++ if(svlan_mbrCfgVid[svidx] == vid) ++ { ++ /* Found! return index */ ++ *pIndex = svidx; ++ return RT_ERR_OK; ++ } ++ } ++ else if(empty_idx == 0xFFFF) ++ { ++ empty_idx = svidx; ++ } ++ ++ } ++ ++ if(empty_idx == 0xFFFF) ++ { ++ /* No empty index */ ++ return RT_ERR_TBL_FULL; ++ } ++ ++ svlan_mbrCfgUsage[empty_idx] = TRUE; ++ svlan_mbrCfgVid[empty_idx] = vid; ++ ++ memset(&svlan_cfg, 0, sizeof(rtl8367c_svlan_memconf_t)); ++ ++ svlan_cfg.vs_svid = vid; ++ /*for create check*/ ++ if(vid == 0) ++ { ++ svlan_cfg.vs_efid = 1; ++ } ++ ++ if((retVal = rtl8367c_setAsicSvlanMemberConfiguration(empty_idx, &svlan_cfg)) != RT_ERR_OK) ++ return retVal; ++ ++ *pIndex = empty_idx; ++ return RT_ERR_OK; ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/trap.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/trap.c +new file mode 100644 +index 0000000000..af9661058b +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/trap.c +@@ -0,0 +1,1229 @@ ++/* ++ * 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 Trap module. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Function Name: ++ * rtk_trap_unknownUnicastPktAction_set ++ * Description: ++ * Set unknown unicast packet action configuration. ++ * Input: ++ * port - ingress port ID for unknown unicast packet ++ * ucast_action - Unknown unicast action. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NOT_ALLOWED - Invalid action. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * This API can set unknown unicast packet action configuration. ++ * The unknown unicast action is as following: ++ * - UCAST_ACTION_FORWARD_PMASK ++ * - UCAST_ACTION_DROP ++ * - UCAST_ACTION_TRAP2CPU ++ * - UCAST_ACTION_FLOODING ++ */ ++rtk_api_ret_t rtk_trap_unknownUnicastPktAction_set(rtk_port_t port, rtk_trap_ucast_action_t ucast_action) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* check port valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if (ucast_action >= UCAST_ACTION_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicPortUnknownDaBehavior(rtk_switch_port_L2P_get(port), ucast_action)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trap_unknownUnicastPktAction_get ++ * Description: ++ * Get unknown unicast packet action configuration. ++ * Input: ++ * port - ingress port ID for unknown unicast packet ++ * Output: ++ * pUcast_action - Unknown unicast action. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NOT_ALLOWED - Invalid action. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * RT_ERR_NULL_POINTER - Null pointer ++ * Note: ++ * This API can get unknown unicast packet action configuration. ++ * The unknown unicast action is as following: ++ * - UCAST_ACTION_FORWARD_PMASK ++ * - UCAST_ACTION_DROP ++ * - UCAST_ACTION_TRAP2CPU ++ * - UCAST_ACTION_FLOODING ++ */ ++rtk_api_ret_t rtk_trap_unknownUnicastPktAction_get(rtk_port_t port, rtk_trap_ucast_action_t *pUcast_action) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* check port valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if (NULL == pUcast_action) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicPortUnknownDaBehavior(rtk_switch_port_L2P_get(port), pUcast_action)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trap_unknownMacPktAction_set ++ * Description: ++ * Set unknown source MAC packet action configuration. ++ * Input: ++ * ucast_action - Unknown source MAC action. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NOT_ALLOWED - Invalid action. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * This API can set unknown unicast packet action configuration. ++ * The unknown unicast action is as following: ++ * - UCAST_ACTION_FORWARD_PMASK ++ * - UCAST_ACTION_DROP ++ * - UCAST_ACTION_TRAP2CPU ++ */ ++rtk_api_ret_t rtk_trap_unknownMacPktAction_set(rtk_trap_ucast_action_t ucast_action) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (ucast_action >= UCAST_ACTION_FLOODING) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicPortUnknownSaBehavior(ucast_action)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trap_unknownMacPktAction_get ++ * Description: ++ * Get unknown source MAC packet action configuration. ++ * Input: ++ * None. ++ * Output: ++ * pUcast_action - Unknown source MAC action. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NULL_POINTER - Null Pointer. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_trap_unknownMacPktAction_get(rtk_trap_ucast_action_t *pUcast_action) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pUcast_action) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicPortUnknownSaBehavior(pUcast_action)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trap_unmatchMacPktAction_set ++ * Description: ++ * Set unmatch source MAC packet action configuration. ++ * Input: ++ * ucast_action - Unknown source MAC action. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NOT_ALLOWED - Invalid action. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * This API can set unknown unicast packet action configuration. ++ * The unknown unicast action is as following: ++ * - UCAST_ACTION_FORWARD_PMASK ++ * - UCAST_ACTION_DROP ++ * - UCAST_ACTION_TRAP2CPU ++ */ ++rtk_api_ret_t rtk_trap_unmatchMacPktAction_set(rtk_trap_ucast_action_t ucast_action) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (ucast_action >= UCAST_ACTION_FLOODING) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicPortUnmatchedSaBehavior(ucast_action)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trap_unmatchMacPktAction_get ++ * Description: ++ * Get unmatch source MAC packet action configuration. ++ * Input: ++ * None. ++ * Output: ++ * pUcast_action - Unknown source MAC action. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NOT_ALLOWED - Invalid action. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * This API can set unknown unicast packet action configuration. ++ * The unknown unicast action is as following: ++ * - UCAST_ACTION_FORWARD_PMASK ++ * - UCAST_ACTION_DROP ++ * - UCAST_ACTION_TRAP2CPU ++ */ ++rtk_api_ret_t rtk_trap_unmatchMacPktAction_get(rtk_trap_ucast_action_t *pUcast_action) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pUcast_action) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicPortUnmatchedSaBehavior(pUcast_action)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trap_unmatchMacMoving_set ++ * Description: ++ * Set unmatch source MAC packet moving state. ++ * Input: ++ * port - Port ID. ++ * enable - ENABLED: allow SA moving, DISABLE: don't allow SA moving. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NOT_ALLOWED - Invalid action. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ */ ++rtk_api_ret_t rtk_trap_unmatchMacMoving_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_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicPortUnmatchedSaMoving(rtk_switch_port_L2P_get(port), enable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trap_unmatchMacMoving_get ++ * Description: ++ * Set unmatch source MAC packet moving state. ++ * Input: ++ * port - Port ID. ++ * Output: ++ * pEnable - ENABLED: allow SA moving, DISABLE: don't allow SA moving. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NOT_ALLOWED - Invalid action. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ */ ++rtk_api_ret_t rtk_trap_unmatchMacMoving_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_getAsicPortUnmatchedSaMoving(rtk_switch_port_L2P_get(port), pEnable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trap_unknownMcastPktAction_set ++ * Description: ++ * Set behavior of unknown multicast ++ * Input: ++ * port - Port id. ++ * type - unknown multicast packet type. ++ * mcast_action - unknown multicast 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_NOT_ALLOWED - Invalid action. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * When receives an unknown multicast packet, switch may trap, drop or flood this packet ++ * (1) The unknown multicast packet type is as following: ++ * - MCAST_L2 ++ * - MCAST_IPV4 ++ * - MCAST_IPV6 ++ * (2) The unknown multicast action is as following: ++ * - MCAST_ACTION_FORWARD ++ * - MCAST_ACTION_DROP ++ * - MCAST_ACTION_TRAP2CPU ++ */ ++rtk_api_ret_t rtk_trap_unknownMcastPktAction_set(rtk_port_t port, rtk_mcast_type_t type, rtk_trap_mcast_action_t mcast_action) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 rawAction; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if (type >= MCAST_END) ++ return RT_ERR_INPUT; ++ ++ if (mcast_action >= MCAST_ACTION_END) ++ return RT_ERR_INPUT; ++ ++ ++ switch (type) ++ { ++ case MCAST_L2: ++ if (MCAST_ACTION_ROUTER_PORT == mcast_action) ++ return RT_ERR_INPUT; ++ else if(MCAST_ACTION_DROP_EX_RMA == mcast_action) ++ rawAction = L2_UNKOWN_MULTICAST_DROP_EXCLUDE_RMA; ++ else ++ rawAction = (rtk_uint32)mcast_action; ++ ++ if ((retVal = rtl8367c_setAsicUnknownL2MulticastBehavior(rtk_switch_port_L2P_get(port), rawAction)) != RT_ERR_OK) ++ return retVal; ++ ++ break; ++ case MCAST_IPV4: ++ if (MCAST_ACTION_DROP_EX_RMA == mcast_action) ++ return RT_ERR_INPUT; ++ else ++ rawAction = (rtk_uint32)mcast_action; ++ ++ if ((retVal = rtl8367c_setAsicUnknownIPv4MulticastBehavior(rtk_switch_port_L2P_get(port), rawAction)) != RT_ERR_OK) ++ return retVal; ++ ++ break; ++ case MCAST_IPV6: ++ if (MCAST_ACTION_DROP_EX_RMA == mcast_action) ++ return RT_ERR_INPUT; ++ else ++ rawAction = (rtk_uint32)mcast_action; ++ ++ if ((retVal = rtl8367c_setAsicUnknownIPv6MulticastBehavior(rtk_switch_port_L2P_get(port), rawAction)) != RT_ERR_OK) ++ return retVal; ++ ++ break; ++ default: ++ break; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trap_unknownMcastPktAction_get ++ * Description: ++ * Get behavior of unknown multicast ++ * Input: ++ * type - unknown multicast packet type. ++ * Output: ++ * pMcast_action - unknown multicast action. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number. ++ * RT_ERR_NOT_ALLOWED - Invalid operation. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * When receives an unknown multicast packet, switch may trap, drop or flood this packet ++ * (1) The unknown multicast packet type is as following: ++ * - MCAST_L2 ++ * - MCAST_IPV4 ++ * - MCAST_IPV6 ++ * (2) The unknown multicast action is as following: ++ * - MCAST_ACTION_FORWARD ++ * - MCAST_ACTION_DROP ++ * - MCAST_ACTION_TRAP2CPU ++ */ ++rtk_api_ret_t rtk_trap_unknownMcastPktAction_get(rtk_port_t port, rtk_mcast_type_t type, rtk_trap_mcast_action_t *pMcast_action) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 rawAction; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if (type >= MCAST_END) ++ return RT_ERR_INPUT; ++ ++ if(NULL == pMcast_action) ++ return RT_ERR_NULL_POINTER; ++ ++ switch (type) ++ { ++ case MCAST_L2: ++ if ((retVal = rtl8367c_getAsicUnknownL2MulticastBehavior(rtk_switch_port_L2P_get(port), &rawAction)) != RT_ERR_OK) ++ return retVal; ++ ++ if(L2_UNKOWN_MULTICAST_DROP_EXCLUDE_RMA == rawAction) ++ *pMcast_action = MCAST_ACTION_DROP_EX_RMA; ++ else ++ *pMcast_action = (rtk_trap_mcast_action_t)rawAction; ++ ++ break; ++ case MCAST_IPV4: ++ if ((retVal = rtl8367c_getAsicUnknownIPv4MulticastBehavior(rtk_switch_port_L2P_get(port), &rawAction)) != RT_ERR_OK) ++ return retVal; ++ ++ *pMcast_action = (rtk_trap_mcast_action_t)rawAction; ++ break; ++ case MCAST_IPV6: ++ if ((retVal = rtl8367c_getAsicUnknownIPv6MulticastBehavior(rtk_switch_port_L2P_get(port), &rawAction)) != RT_ERR_OK) ++ return retVal; ++ ++ *pMcast_action = (rtk_trap_mcast_action_t)rawAction; ++ break; ++ default: ++ break; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trap_lldpEnable_set ++ * Description: ++ * Set LLDP enable. ++ * Input: ++ * enabled - LLDP enable, 0: follow RMA, 1: use LLDP action. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NOT_ALLOWED - Invalid action. ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * - DMAC Assignment ++ * - 01:80:c2:00:00:0e ethertype = 0x88CC LLDP ++ * - 01:80:c2:00:00:03 ethertype = 0x88CC ++ * - 01:80:c2:00:00:00 ethertype = 0x88CC ++ ++ */ ++rtk_api_ret_t rtk_trap_lldpEnable_set(rtk_enable_t enabled) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_rma_t rmacfg; ++ rtk_enable_t tmp; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (enabled >= RTK_ENABLE_END) ++ return RT_ERR_ENABLE; ++ ++ if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicRmaLldp(enabled, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trap_lldpEnable_get ++ * Description: ++ * Get LLDP status. ++ * Input: ++ * None ++ * Output: ++ * pEnabled - LLDP enable, 0: follow RMA, 1: use LLDP action. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * LLDP is as following definition. ++ * - DMAC Assignment ++ * - 01:80:c2:00:00:0e ethertype = 0x88CC LLDP ++ * - 01:80:c2:00:00:03 ethertype = 0x88CC ++ * - 01:80:c2:00:00:00 ethertype = 0x88CC ++ */ ++rtk_api_ret_t rtk_trap_lldpEnable_get(rtk_enable_t *pEnabled) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_rma_t rmacfg; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pEnabled) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicRmaLldp(pEnabled, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trap_reasonTrapToCpuPriority_set ++ * Description: ++ * Set priority value of a packet that trapped to CPU port according to specific reason. ++ * Input: ++ * type - reason that trap to CPU port. ++ * priority - internal priority that is going to be set for specific trap reason. ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_NOT_INIT - The module is not initial ++ * RT_ERR_INPUT - Invalid input parameter ++ * Note: ++ * Currently the trap reason that supported are listed as follows: ++ * - TRAP_REASON_RMA ++ * - TRAP_REASON_OAM ++ * - TRAP_REASON_1XUNAUTH ++ * - TRAP_REASON_VLANSTACK ++ * - TRAP_REASON_UNKNOWNMC ++ */ ++rtk_api_ret_t rtk_trap_reasonTrapToCpuPriority_set(rtk_trap_reason_type_t type, rtk_pri_t priority) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_rma_t rmacfg; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (type >= TRAP_REASON_END) ++ return RT_ERR_INPUT; ++ ++ if (priority > RTL8367C_PRIMAX) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ switch (type) ++ { ++ case TRAP_REASON_RMA: ++ if ((retVal = rtl8367c_getAsicRma(0, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ rmacfg.trap_priority= priority; ++ if ((retVal = rtl8367c_setAsicRma(0, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ break; ++ case TRAP_REASON_OAM: ++ if ((retVal = rtl8367c_setAsicOamCpuPri(priority)) != RT_ERR_OK) ++ return retVal; ++ ++ break; ++ case TRAP_REASON_1XUNAUTH: ++ if ((retVal = rtl8367c_setAsic1xTrapPriority(priority)) != RT_ERR_OK) ++ return retVal; ++ ++ break; ++ case TRAP_REASON_VLANSTACK: ++ if ((retVal = rtl8367c_setAsicSvlanTrapPriority(priority)) != RT_ERR_OK) ++ return retVal; ++ ++ break; ++ case TRAP_REASON_UNKNOWNMC: ++ if ((retVal = rtl8367c_setAsicUnknownMulticastTrapPriority(priority)) != RT_ERR_OK) ++ return retVal; ++ ++ break; ++ default: ++ return RT_ERR_CHIP_NOT_SUPPORTED; ++ } ++ ++ ++ return RT_ERR_OK; ++} ++ ++ ++/* Function Name: ++ * rtk_trap_reasonTrapToCpuPriority_get ++ * Description: ++ * Get priority value of a packet that trapped to CPU port according to specific reason. ++ * Input: ++ * type - reason that trap to CPU port. ++ * Output: ++ * pPriority - configured internal priority for such reason. ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_NOT_INIT - The module is not initial ++ * RT_ERR_INPUT - Invalid input parameter ++ * RT_ERR_NULL_POINTER - NULL pointer ++ * Note: ++ * Currently the trap reason that supported are listed as follows: ++ * - TRAP_REASON_RMA ++ * - TRAP_REASON_OAM ++ * - TRAP_REASON_1XUNAUTH ++ * - TRAP_REASON_VLANSTACK ++ * - TRAP_REASON_UNKNOWNMC ++ */ ++rtk_api_ret_t rtk_trap_reasonTrapToCpuPriority_get(rtk_trap_reason_type_t type, rtk_pri_t *pPriority) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_rma_t rmacfg; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (type >= TRAP_REASON_END) ++ return RT_ERR_INPUT; ++ ++ if(NULL == pPriority) ++ return RT_ERR_NULL_POINTER; ++ ++ switch (type) ++ { ++ case TRAP_REASON_RMA: ++ if ((retVal = rtl8367c_getAsicRma(0, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ *pPriority = rmacfg.trap_priority; ++ ++ break; ++ case TRAP_REASON_OAM: ++ if ((retVal = rtl8367c_getAsicOamCpuPri(pPriority)) != RT_ERR_OK) ++ return retVal; ++ ++ break; ++ case TRAP_REASON_1XUNAUTH: ++ if ((retVal = rtl8367c_getAsic1xTrapPriority(pPriority)) != RT_ERR_OK) ++ return retVal; ++ ++ break; ++ case TRAP_REASON_VLANSTACK: ++ if ((retVal = rtl8367c_getAsicSvlanTrapPriority(pPriority)) != RT_ERR_OK) ++ return retVal; ++ ++ break; ++ case TRAP_REASON_UNKNOWNMC: ++ if ((retVal = rtl8367c_getAsicUnknownMulticastTrapPriority(pPriority)) != RT_ERR_OK) ++ return retVal; ++ ++ break; ++ default: ++ return RT_ERR_CHIP_NOT_SUPPORTED; ++ ++ } ++ ++ return RT_ERR_OK; ++} ++ ++ ++ ++/* Function Name: ++ * rtk_trap_rmaAction_set ++ * Description: ++ * Set Reserved multicast address action configuration. ++ * Input: ++ * type - rma type. ++ * rma_action - RMA action. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * ++ * There are 48 types of Reserved Multicast Address frame for application usage. ++ * (1)They are as following definition. ++ * - TRAP_BRG_GROUP, ++ * - TRAP_FD_PAUSE, ++ * - TRAP_SP_MCAST, ++ * - TRAP_1X_PAE, ++ * - TRAP_UNDEF_BRG_04, ++ * - TRAP_UNDEF_BRG_05, ++ * - TRAP_UNDEF_BRG_06, ++ * - TRAP_UNDEF_BRG_07, ++ * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, ++ * - TRAP_UNDEF_BRG_09, ++ * - TRAP_UNDEF_BRG_0A, ++ * - TRAP_UNDEF_BRG_0B, ++ * - TRAP_UNDEF_BRG_0C, ++ * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, ++ * - TRAP_8021AB, ++ * - TRAP_UNDEF_BRG_0F, ++ * - TRAP_BRG_MNGEMENT, ++ * - TRAP_UNDEFINED_11, ++ * - TRAP_UNDEFINED_12, ++ * - TRAP_UNDEFINED_13, ++ * - TRAP_UNDEFINED_14, ++ * - TRAP_UNDEFINED_15, ++ * - TRAP_UNDEFINED_16, ++ * - TRAP_UNDEFINED_17, ++ * - TRAP_UNDEFINED_18, ++ * - TRAP_UNDEFINED_19, ++ * - TRAP_UNDEFINED_1A, ++ * - TRAP_UNDEFINED_1B, ++ * - TRAP_UNDEFINED_1C, ++ * - TRAP_UNDEFINED_1D, ++ * - TRAP_UNDEFINED_1E, ++ * - TRAP_UNDEFINED_1F, ++ * - TRAP_GMRP, ++ * - TRAP_GVRP, ++ * - TRAP_UNDEF_GARP_22, ++ * - TRAP_UNDEF_GARP_23, ++ * - TRAP_UNDEF_GARP_24, ++ * - TRAP_UNDEF_GARP_25, ++ * - TRAP_UNDEF_GARP_26, ++ * - TRAP_UNDEF_GARP_27, ++ * - TRAP_UNDEF_GARP_28, ++ * - TRAP_UNDEF_GARP_29, ++ * - TRAP_UNDEF_GARP_2A, ++ * - TRAP_UNDEF_GARP_2B, ++ * - TRAP_UNDEF_GARP_2C, ++ * - TRAP_UNDEF_GARP_2D, ++ * - TRAP_UNDEF_GARP_2E, ++ * - TRAP_UNDEF_GARP_2F, ++ * - TRAP_CDP. ++ * - TRAP_CSSTP. ++ * - TRAP_LLDP. ++ * (2) The RMA action is as following: ++ * - RMA_ACTION_FORWARD ++ * - RMA_ACTION_TRAP2CPU ++ * - RMA_ACTION_DROP ++ * - RMA_ACTION_FORWARD_EXCLUDE_CPU ++ */ ++rtk_api_ret_t rtk_trap_rmaAction_set(rtk_trap_type_t type, rtk_trap_rma_action_t rma_action) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_rma_t rmacfg; ++ rtk_uint32 tmp; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (type >= TRAP_END) ++ return RT_ERR_INPUT; ++ ++ if (rma_action >= RMA_ACTION_END) ++ return RT_ERR_RMA_ACTION; ++ ++ if (type >= 0 && type <= TRAP_UNDEF_GARP_2F) ++ { ++ if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ rmacfg.operation = rma_action; ++ ++ if ((retVal = rtl8367c_setAsicRma(type, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (type == TRAP_CDP) ++ { ++ if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ rmacfg.operation = rma_action; ++ ++ if ((retVal = rtl8367c_setAsicRmaCdp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (type == TRAP_CSSTP) ++ { ++ if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ rmacfg.operation = rma_action; ++ ++ if ((retVal = rtl8367c_setAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (type == TRAP_LLDP) ++ { ++ if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ rmacfg.operation = rma_action; ++ ++ if ((retVal = rtl8367c_setAsicRmaLldp(tmp, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ return RT_ERR_INPUT; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trap_rmaAction_get ++ * Description: ++ * Get Reserved multicast address action configuration. ++ * Input: ++ * type - rma type. ++ * Output: ++ * pRma_action - RMA action. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * There are 48 types of Reserved Multicast Address frame for application usage. ++ * (1)They are as following definition. ++ * - TRAP_BRG_GROUP, ++ * - TRAP_FD_PAUSE, ++ * - TRAP_SP_MCAST, ++ * - TRAP_1X_PAE, ++ * - TRAP_UNDEF_BRG_04, ++ * - TRAP_UNDEF_BRG_05, ++ * - TRAP_UNDEF_BRG_06, ++ * - TRAP_UNDEF_BRG_07, ++ * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, ++ * - TRAP_UNDEF_BRG_09, ++ * - TRAP_UNDEF_BRG_0A, ++ * - TRAP_UNDEF_BRG_0B, ++ * - TRAP_UNDEF_BRG_0C, ++ * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, ++ * - TRAP_8021AB, ++ * - TRAP_UNDEF_BRG_0F, ++ * - TRAP_BRG_MNGEMENT, ++ * - TRAP_UNDEFINED_11, ++ * - TRAP_UNDEFINED_12, ++ * - TRAP_UNDEFINED_13, ++ * - TRAP_UNDEFINED_14, ++ * - TRAP_UNDEFINED_15, ++ * - TRAP_UNDEFINED_16, ++ * - TRAP_UNDEFINED_17, ++ * - TRAP_UNDEFINED_18, ++ * - TRAP_UNDEFINED_19, ++ * - TRAP_UNDEFINED_1A, ++ * - TRAP_UNDEFINED_1B, ++ * - TRAP_UNDEFINED_1C, ++ * - TRAP_UNDEFINED_1D, ++ * - TRAP_UNDEFINED_1E, ++ * - TRAP_UNDEFINED_1F, ++ * - TRAP_GMRP, ++ * - TRAP_GVRP, ++ * - TRAP_UNDEF_GARP_22, ++ * - TRAP_UNDEF_GARP_23, ++ * - TRAP_UNDEF_GARP_24, ++ * - TRAP_UNDEF_GARP_25, ++ * - TRAP_UNDEF_GARP_26, ++ * - TRAP_UNDEF_GARP_27, ++ * - TRAP_UNDEF_GARP_28, ++ * - TRAP_UNDEF_GARP_29, ++ * - TRAP_UNDEF_GARP_2A, ++ * - TRAP_UNDEF_GARP_2B, ++ * - TRAP_UNDEF_GARP_2C, ++ * - TRAP_UNDEF_GARP_2D, ++ * - TRAP_UNDEF_GARP_2E, ++ * - TRAP_UNDEF_GARP_2F, ++ * - TRAP_CDP. ++ * - TRAP_CSSTP. ++ * - TRAP_LLDP. ++ * (2) The RMA action is as following: ++ * - RMA_ACTION_FORWARD ++ * - RMA_ACTION_TRAP2CPU ++ * - RMA_ACTION_DROP ++ * - RMA_ACTION_FORWARD_EXCLUDE_CPU ++ */ ++rtk_api_ret_t rtk_trap_rmaAction_get(rtk_trap_type_t type, rtk_trap_rma_action_t *pRma_action) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_rma_t rmacfg; ++ rtk_uint32 tmp; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (type >= TRAP_END) ++ return RT_ERR_INPUT; ++ ++ if(NULL == pRma_action) ++ return RT_ERR_NULL_POINTER; ++ ++ if (type >= 0 && type <= TRAP_UNDEF_GARP_2F) ++ { ++ if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ *pRma_action = rmacfg.operation; ++ } ++ else if (type == TRAP_CDP) ++ { ++ if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ *pRma_action = rmacfg.operation; ++ } ++ else if (type == TRAP_CSSTP) ++ { ++ if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ *pRma_action = rmacfg.operation; ++ } ++ else if (type == TRAP_LLDP) ++ { ++ if ((retVal = rtl8367c_getAsicRmaLldp(&tmp,&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ *pRma_action = rmacfg.operation; ++ } ++ else ++ return RT_ERR_INPUT; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trap_rmaKeepFormat_set ++ * Description: ++ * Set Reserved multicast address keep format configuration. ++ * Input: ++ * type - rma type. ++ * enable - enable keep format. ++ * 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 IFG parameter ++ * Note: ++ * ++ * There are 48 types of Reserved Multicast Address frame for application usage. ++ * They are as following definition. ++ * - TRAP_BRG_GROUP, ++ * - TRAP_FD_PAUSE, ++ * - TRAP_SP_MCAST, ++ * - TRAP_1X_PAE, ++ * - TRAP_UNDEF_BRG_04, ++ * - TRAP_UNDEF_BRG_05, ++ * - TRAP_UNDEF_BRG_06, ++ * - TRAP_UNDEF_BRG_07, ++ * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, ++ * - TRAP_UNDEF_BRG_09, ++ * - TRAP_UNDEF_BRG_0A, ++ * - TRAP_UNDEF_BRG_0B, ++ * - TRAP_UNDEF_BRG_0C, ++ * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, ++ * - TRAP_8021AB, ++ * - TRAP_UNDEF_BRG_0F, ++ * - TRAP_BRG_MNGEMENT, ++ * - TRAP_UNDEFINED_11, ++ * - TRAP_UNDEFINED_12, ++ * - TRAP_UNDEFINED_13, ++ * - TRAP_UNDEFINED_14, ++ * - TRAP_UNDEFINED_15, ++ * - TRAP_UNDEFINED_16, ++ * - TRAP_UNDEFINED_17, ++ * - TRAP_UNDEFINED_18, ++ * - TRAP_UNDEFINED_19, ++ * - TRAP_UNDEFINED_1A, ++ * - TRAP_UNDEFINED_1B, ++ * - TRAP_UNDEFINED_1C, ++ * - TRAP_UNDEFINED_1D, ++ * - TRAP_UNDEFINED_1E, ++ * - TRAP_UNDEFINED_1F, ++ * - TRAP_GMRP, ++ * - TRAP_GVRP, ++ * - TRAP_UNDEF_GARP_22, ++ * - TRAP_UNDEF_GARP_23, ++ * - TRAP_UNDEF_GARP_24, ++ * - TRAP_UNDEF_GARP_25, ++ * - TRAP_UNDEF_GARP_26, ++ * - TRAP_UNDEF_GARP_27, ++ * - TRAP_UNDEF_GARP_28, ++ * - TRAP_UNDEF_GARP_29, ++ * - TRAP_UNDEF_GARP_2A, ++ * - TRAP_UNDEF_GARP_2B, ++ * - TRAP_UNDEF_GARP_2C, ++ * - TRAP_UNDEF_GARP_2D, ++ * - TRAP_UNDEF_GARP_2E, ++ * - TRAP_UNDEF_GARP_2F, ++ * - TRAP_CDP. ++ * - TRAP_CSSTP. ++ * - TRAP_LLDP. ++ */ ++rtk_api_ret_t rtk_trap_rmaKeepFormat_set(rtk_trap_type_t type, rtk_enable_t enable) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_rma_t rmacfg; ++ rtk_uint32 tmp; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (type >= TRAP_END) ++ return RT_ERR_INPUT; ++ ++ if (enable >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if (type >= 0 && type <= TRAP_UNDEF_GARP_2F) ++ { ++ if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ rmacfg.keep_format = enable; ++ ++ if ((retVal = rtl8367c_setAsicRma(type, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (type == TRAP_CDP) ++ { ++ if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ rmacfg.keep_format = enable; ++ ++ if ((retVal = rtl8367c_setAsicRmaCdp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (type == TRAP_CSSTP) ++ { ++ if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ rmacfg.keep_format = enable; ++ ++ if ((retVal = rtl8367c_setAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ else if (type == TRAP_LLDP) ++ { ++ if ((retVal = rtl8367c_getAsicRmaLldp(&tmp, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ rmacfg.keep_format = enable; ++ ++ if ((retVal = rtl8367c_setAsicRmaLldp(tmp, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ return RT_ERR_INPUT; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trap_rmaKeepFormat_get ++ * Description: ++ * Get Reserved multicast address action configuration. ++ * Input: ++ * type - rma type. ++ * Output: ++ * pEnable - keep format status. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters. ++ * Note: ++ * There are 48 types of Reserved Multicast Address frame for application usage. ++ * They are as following definition. ++ * - TRAP_BRG_GROUP, ++ * - TRAP_FD_PAUSE, ++ * - TRAP_SP_MCAST, ++ * - TRAP_1X_PAE, ++ * - TRAP_UNDEF_BRG_04, ++ * - TRAP_UNDEF_BRG_05, ++ * - TRAP_UNDEF_BRG_06, ++ * - TRAP_UNDEF_BRG_07, ++ * - TRAP_PROVIDER_BRIDGE_GROUP_ADDRESS, ++ * - TRAP_UNDEF_BRG_09, ++ * - TRAP_UNDEF_BRG_0A, ++ * - TRAP_UNDEF_BRG_0B, ++ * - TRAP_UNDEF_BRG_0C, ++ * - TRAP_PROVIDER_BRIDGE_GVRP_ADDRESS, ++ * - TRAP_8021AB, ++ * - TRAP_UNDEF_BRG_0F, ++ * - TRAP_BRG_MNGEMENT, ++ * - TRAP_UNDEFINED_11, ++ * - TRAP_UNDEFINED_12, ++ * - TRAP_UNDEFINED_13, ++ * - TRAP_UNDEFINED_14, ++ * - TRAP_UNDEFINED_15, ++ * - TRAP_UNDEFINED_16, ++ * - TRAP_UNDEFINED_17, ++ * - TRAP_UNDEFINED_18, ++ * - TRAP_UNDEFINED_19, ++ * - TRAP_UNDEFINED_1A, ++ * - TRAP_UNDEFINED_1B, ++ * - TRAP_UNDEFINED_1C, ++ * - TRAP_UNDEFINED_1D, ++ * - TRAP_UNDEFINED_1E, ++ * - TRAP_UNDEFINED_1F, ++ * - TRAP_GMRP, ++ * - TRAP_GVRP, ++ * - TRAP_UNDEF_GARP_22, ++ * - TRAP_UNDEF_GARP_23, ++ * - TRAP_UNDEF_GARP_24, ++ * - TRAP_UNDEF_GARP_25, ++ * - TRAP_UNDEF_GARP_26, ++ * - TRAP_UNDEF_GARP_27, ++ * - TRAP_UNDEF_GARP_28, ++ * - TRAP_UNDEF_GARP_29, ++ * - TRAP_UNDEF_GARP_2A, ++ * - TRAP_UNDEF_GARP_2B, ++ * - TRAP_UNDEF_GARP_2C, ++ * - TRAP_UNDEF_GARP_2D, ++ * - TRAP_UNDEF_GARP_2E, ++ * - TRAP_UNDEF_GARP_2F, ++ * - TRAP_CDP. ++ * - TRAP_CSSTP. ++ * - TRAP_LLDP. ++ */ ++rtk_api_ret_t rtk_trap_rmaKeepFormat_get(rtk_trap_type_t type, rtk_enable_t *pEnable) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_rma_t rmacfg; ++ rtk_uint32 tmp; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (type >= TRAP_END) ++ return RT_ERR_INPUT; ++ ++ if(NULL == pEnable) ++ return RT_ERR_NULL_POINTER; ++ ++ if (type >= 0 && type <= TRAP_UNDEF_GARP_2F) ++ { ++ if ((retVal = rtl8367c_getAsicRma(type, &rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEnable = rmacfg.keep_format; ++ } ++ else if (type == TRAP_CDP) ++ { ++ if ((retVal = rtl8367c_getAsicRmaCdp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEnable = rmacfg.keep_format; ++ } ++ else if (type == TRAP_CSSTP) ++ { ++ if ((retVal = rtl8367c_getAsicRmaCsstp(&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEnable = rmacfg.keep_format; ++ } ++ else if (type == TRAP_LLDP) ++ { ++ if ((retVal = rtl8367c_getAsicRmaLldp(&tmp,&rmacfg)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEnable = rmacfg.keep_format; ++ } ++ else ++ return RT_ERR_INPUT; ++ ++ return RT_ERR_OK; ++} ++ ++ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/trunk.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/trunk.c +new file mode 100644 +index 0000000000..8a88dc5ff0 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/trunk.c +@@ -0,0 +1,605 @@ ++/* ++ * 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 Trunk module. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++/* Function Name: ++ * rtk_trunk_port_set ++ * Description: ++ * Set trunking group available port mask ++ * Input: ++ * trk_gid - trunk group id ++ * pTrunk_member_portmask - Logic trunking member port mask ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_LA_TRUNK_ID - Invalid trunking group ++ * RT_ERR_PORT_MASK - Invalid portmask. ++ * Note: ++ * The API can set port trunking group port mask. Each port trunking group has max 4 ports. ++ * If enabled port mask has less than 2 ports available setting, then this trunking group function is disabled. ++ */ ++rtk_api_ret_t rtk_trunk_port_set(rtk_trunk_group_t trk_gid, rtk_portmask_t *pTrunk_member_portmask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmsk; ++ rtk_uint32 regValue, type, tmp; ++ ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0249)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_getAsicReg(0x1300, ®Value)) != RT_ERR_OK) ++ return retVal; ++ ++ if((retVal = rtl8367c_setAsicReg(0x13C2, 0x0000)) != RT_ERR_OK) ++ return retVal; ++ ++ switch (regValue) ++ { ++ case 0x0276: ++ case 0x0597: ++ case 0x6367: ++ type = 0; ++ break; ++ case 0x0652: ++ case 0x6368: ++ type = 1; ++ break; ++ case 0x0801: ++ case 0x6511: ++ type = 2; ++ break; ++ default: ++ return RT_ERR_FAILED; ++ } ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Trunk Group Valid */ ++ RTK_CHK_TRUNK_GROUP_VALID(trk_gid); ++ ++ if(NULL == pTrunk_member_portmask) ++ return RT_ERR_NULL_POINTER; ++ ++ RTK_CHK_PORTMASK_VALID(pTrunk_member_portmask); ++ ++ if((retVal = rtk_switch_portmask_L2P_get(pTrunk_member_portmask, &pmsk)) != RT_ERR_OK) ++ return retVal; ++ ++ if((type == 0) || (type == 1)) ++ { ++ if ((pmsk | RTL8367C_PORT_TRUNK_GROUP_MASK_MASK(trk_gid)) != (rtk_uint32)RTL8367C_PORT_TRUNK_GROUP_MASK_MASK(trk_gid)) ++ return RT_ERR_PORT_MASK; ++ ++ pmsk = (pmsk & RTL8367C_PORT_TRUNK_GROUP_MASK_MASK(trk_gid)) >> RTL8367C_PORT_TRUNK_GROUP_MASK_OFFSET(trk_gid); ++ } ++ else if(type == 2) ++ { ++ tmp = 0; ++ ++ if(pmsk & 0x2) ++ tmp |= 1; ++ if(pmsk & 0x8) ++ tmp |=2; ++ if(pmsk & 0x80) ++ tmp |=8; ++ ++ pmsk = tmp; ++ } ++ ++ if ((retVal = rtl8367c_setAsicTrunkingGroup(trk_gid, pmsk)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trunk_port_get ++ * Description: ++ * Get trunking group available port mask ++ * Input: ++ * trk_gid - trunk group id ++ * Output: ++ * pTrunk_member_portmask - Logic trunking member port mask ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_LA_TRUNK_ID - Invalid trunking group ++ * Note: ++ * The API can get 2 port trunking group. ++ */ ++rtk_api_ret_t rtk_trunk_port_get(rtk_trunk_group_t trk_gid, rtk_portmask_t *pTrunk_member_portmask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmsk; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Trunk Group Valid */ ++ RTK_CHK_TRUNK_GROUP_VALID(trk_gid); ++ ++ if ((retVal = rtl8367c_getAsicTrunkingGroup(trk_gid, &pmsk)) != RT_ERR_OK) ++ return retVal; ++ ++ pmsk = pmsk << RTL8367C_PORT_TRUNK_GROUP_MASK_OFFSET(trk_gid); ++ ++ if((retVal = rtk_switch_portmask_P2L_get(pmsk, pTrunk_member_portmask)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trunk_distributionAlgorithm_set ++ * Description: ++ * Set port trunking hash select sources ++ * Input: ++ * trk_gid - trunk group id ++ * algo_bitmask - Bitmask of the distribution algorithm ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_LA_TRUNK_ID - Invalid trunking group ++ * RT_ERR_LA_HASHMASK - Hash algorithm selection error. ++ * RT_ERR_PORT_MASK - Invalid portmask. ++ * Note: ++ * The API can set port trunking hash algorithm sources. ++ * 7 bits mask for link aggregation group0 hash parameter selection {DIP, SIP, DMAC, SMAC, SPA} ++ * - 0b0000001: SPA ++ * - 0b0000010: SMAC ++ * - 0b0000100: DMAC ++ * - 0b0001000: SIP ++ * - 0b0010000: DIP ++ * - 0b0100000: TCP/UDP Source Port ++ * - 0b1000000: TCP/UDP Destination Port ++ * Example: ++ * - 0b0000011: SMAC & SPA ++ * - Note that it could be an arbitrary combination or independent set ++ */ ++rtk_api_ret_t rtk_trunk_distributionAlgorithm_set(rtk_trunk_group_t trk_gid, rtk_uint32 algo_bitmask) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (trk_gid != RTK_WHOLE_SYSTEM) ++ return RT_ERR_LA_TRUNK_ID; ++ ++ if (algo_bitmask >= 128) ++ return RT_ERR_LA_HASHMASK; ++ ++ if ((retVal = rtl8367c_setAsicTrunkingHashSelect(algo_bitmask)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trunk_distributionAlgorithm_get ++ * Description: ++ * Get port trunking hash select sources ++ * Input: ++ * trk_gid - trunk group id ++ * Output: ++ * pAlgo_bitmask - Bitmask of the distribution algorithm ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_LA_TRUNK_ID - Invalid trunking group ++ * Note: ++ * The API can get port trunking hash algorithm sources. ++ */ ++rtk_api_ret_t rtk_trunk_distributionAlgorithm_get(rtk_trunk_group_t trk_gid, rtk_uint32 *pAlgo_bitmask) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (trk_gid != RTK_WHOLE_SYSTEM) ++ return RT_ERR_LA_TRUNK_ID; ++ ++ if(NULL == pAlgo_bitmask) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicTrunkingHashSelect((rtk_uint32 *)pAlgo_bitmask)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trunk_trafficSeparate_set ++ * Description: ++ * Set the traffic separation setting of a trunk group from the specified device. ++ * Input: ++ * trk_gid - trunk group id ++ * separateType - traffic separation setting ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_UNIT_ID - invalid unit id ++ * RT_ERR_LA_TRUNK_ID - invalid trunk ID ++ * RT_ERR_LA_HASHMASK - invalid hash mask ++ * Note: ++ * SEPARATE_NONE: disable traffic separation ++ * SEPARATE_FLOOD: trunk MSB link up port is dedicated to TX flooding (L2 lookup miss) traffic ++ */ ++rtk_api_ret_t rtk_trunk_trafficSeparate_set(rtk_trunk_group_t trk_gid, rtk_trunk_separateType_t separateType) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 enabled; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (trk_gid != RTK_WHOLE_SYSTEM) ++ return RT_ERR_LA_TRUNK_ID; ++ ++ if(separateType >= SEPARATE_END) ++ return RT_ERR_INPUT; ++ ++ enabled = (separateType == SEPARATE_FLOOD) ? ENABLED : DISABLED; ++ if ((retVal = rtl8367c_setAsicTrunkingFlood(enabled)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trunk_trafficSeparate_get ++ * Description: ++ * Get the traffic separation setting of a trunk group from the specified device. ++ * Input: ++ * trk_gid - trunk group id ++ * Output: ++ * pSeparateType - pointer separated traffic type ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_UNIT_ID - invalid unit id ++ * RT_ERR_LA_TRUNK_ID - invalid trunk ID ++ * RT_ERR_NULL_POINTER - input parameter may be null pointer ++ * Note: ++ * SEPARATE_NONE: disable traffic separation ++ * SEPARATE_FLOOD: trunk MSB link up port is dedicated to TX flooding (L2 lookup miss) traffic ++ */ ++rtk_api_ret_t rtk_trunk_trafficSeparate_get(rtk_trunk_group_t trk_gid, rtk_trunk_separateType_t *pSeparateType) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 enabled; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if (trk_gid != RTK_WHOLE_SYSTEM) ++ return RT_ERR_LA_TRUNK_ID; ++ ++ if(NULL == pSeparateType) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicTrunkingFlood(&enabled)) != RT_ERR_OK) ++ return retVal; ++ ++ *pSeparateType = (enabled == ENABLED) ? SEPARATE_FLOOD : SEPARATE_NONE; ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trunk_mode_set ++ * Description: ++ * Set the trunk mode to the specified device. ++ * Input: ++ * mode - trunk mode ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_INPUT - invalid input parameter ++ * Note: ++ * The enum of the trunk mode as following ++ * - TRUNK_MODE_NORMAL ++ * - TRUNK_MODE_DUMB ++ */ ++rtk_api_ret_t rtk_trunk_mode_set(rtk_trunk_mode_t mode) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(mode >= TRUNK_MODE_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicTrunkingMode((rtk_uint32)mode)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trunk_mode_get ++ * Description: ++ * Get the trunk mode from the specified device. ++ * Input: ++ * None ++ * Output: ++ * pMode - pointer buffer of trunk mode ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_NULL_POINTER - input parameter may be null pointer ++ * Note: ++ * The enum of the trunk mode as following ++ * - TRUNK_MODE_NORMAL ++ * - TRUNK_MODE_DUMB ++ */ ++rtk_api_ret_t rtk_trunk_mode_get(rtk_trunk_mode_t *pMode) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pMode) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicTrunkingMode((rtk_uint32 *)pMode)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trunk_trafficPause_set ++ * Description: ++ * Set the traffic pause setting of a trunk group. ++ * Input: ++ * trk_gid - trunk group id ++ * enable - traffic pause state ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_LA_TRUNK_ID - invalid trunk ID ++ * Note: ++ * None. ++ */ ++rtk_api_ret_t rtk_trunk_trafficPause_set(rtk_trunk_group_t trk_gid, rtk_enable_t enable) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Trunk Group Valid */ ++ RTK_CHK_TRUNK_GROUP_VALID(trk_gid); ++ ++ if(enable >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setAsicTrunkingFc((rtk_uint32)trk_gid, (rtk_uint32)enable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trunk_trafficPause_get ++ * Description: ++ * Get the traffic pause setting of a trunk group. ++ * Input: ++ * trk_gid - trunk group id ++ * Output: ++ * pEnable - pointer of traffic pause state. ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_LA_TRUNK_ID - invalid trunk ID ++ * RT_ERR_NULL_POINTER - input parameter may be null pointer ++ * Note: ++ * None. ++ */ ++rtk_api_ret_t rtk_trunk_trafficPause_get(rtk_trunk_group_t trk_gid, rtk_enable_t *pEnable) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Trunk Group Valid */ ++ RTK_CHK_TRUNK_GROUP_VALID(trk_gid); ++ ++ if(NULL == pEnable) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicTrunkingFc((rtk_uint32)trk_gid, (rtk_uint32 *)pEnable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trunk_hashMappingTable_set ++ * Description: ++ * Set hash value to port array in the trunk group id from the specified device. ++ * Input: ++ * trk_gid - trunk group id ++ * pHash2Port_array - ports associate with the hash value ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_UNIT_ID - invalid unit id ++ * RT_ERR_LA_TRUNK_ID - invalid trunk ID ++ * RT_ERR_NULL_POINTER - input parameter may be null pointer ++ * RT_ERR_LA_TRUNK_NOT_EXIST - the trunk doesn't exist ++ * RT_ERR_LA_NOT_MEMBER_PORT - the port is not a member port of the trunk ++ * RT_ERR_LA_CPUPORT - CPU port can not be aggregated port ++ * Note: ++ * Trunk group 0 & 1 shares the same hash mapping table. ++ * Trunk group 2 uses a independent table. ++ */ ++rtk_api_ret_t rtk_trunk_hashMappingTable_set(rtk_trunk_group_t trk_gid, rtk_trunk_hashVal2Port_t *pHash2Port_array) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 hashValue; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Trunk Group Valid */ ++ RTK_CHK_TRUNK_GROUP_VALID(trk_gid); ++ ++ if(NULL == pHash2Port_array) ++ return RT_ERR_NULL_POINTER; ++ ++ if(trk_gid <= TRUNK_GROUP1) ++ { ++ for(hashValue = 0; hashValue < RTK_MAX_NUM_OF_TRUNK_HASH_VAL; hashValue++) ++ { ++ if ((retVal = rtl8367c_setAsicTrunkingHashTable(hashValue, pHash2Port_array->value[hashValue])) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ else ++ { ++ for(hashValue = 0; hashValue < RTK_MAX_NUM_OF_TRUNK_HASH_VAL; hashValue++) ++ { ++ if ((retVal = rtl8367c_setAsicTrunkingHashTable1(hashValue, pHash2Port_array->value[hashValue])) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trunk_hashMappingTable_get ++ * Description: ++ * Get hash value to port array in the trunk group id from the specified device. ++ * Input: ++ * trk_gid - trunk group id ++ * Output: ++ * pHash2Port_array - pointer buffer of ports associate with the hash value ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_UNIT_ID - invalid unit id ++ * RT_ERR_LA_TRUNK_ID - invalid trunk ID ++ * RT_ERR_NULL_POINTER - input parameter may be null pointer ++ * Note: ++ * Trunk group 0 & 1 shares the same hash mapping table. ++ * Trunk group 2 uses a independent table. ++ */ ++rtk_api_ret_t rtk_trunk_hashMappingTable_get(rtk_trunk_group_t trk_gid, rtk_trunk_hashVal2Port_t *pHash2Port_array) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 hashValue; ++ rtk_uint32 hashPort; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Trunk Group Valid */ ++ RTK_CHK_TRUNK_GROUP_VALID(trk_gid); ++ ++ if(NULL == pHash2Port_array) ++ return RT_ERR_NULL_POINTER; ++ ++ if(trk_gid <= TRUNK_GROUP1) ++ { ++ for(hashValue = 0; hashValue < RTK_MAX_NUM_OF_TRUNK_HASH_VAL; hashValue++) ++ { ++ if ((retVal = rtl8367c_getAsicTrunkingHashTable(hashValue, &hashPort)) != RT_ERR_OK) ++ return retVal; ++ ++ pHash2Port_array->value[hashValue] = hashPort; ++ } ++ } ++ else ++ { ++ for(hashValue = 0; hashValue < RTK_MAX_NUM_OF_TRUNK_HASH_VAL; hashValue++) ++ { ++ if ((retVal = rtl8367c_getAsicTrunkingHashTable1(hashValue, &hashPort)) != RT_ERR_OK) ++ return retVal; ++ ++ pHash2Port_array->value[hashValue] = hashPort; ++ } ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_trunk_portQueueEmpty_get ++ * Description: ++ * Get the port mask which all queues are empty. ++ * Input: ++ * None. ++ * Output: ++ * pEmpty_portmask - pointer empty port mask ++ * Return: ++ * RT_ERR_OK ++ * RT_ERR_FAILED ++ * RT_ERR_NULL_POINTER - input parameter may be null pointer ++ * Note: ++ * None. ++ */ ++rtk_api_ret_t rtk_trunk_portQueueEmpty_get(rtk_portmask_t *pEmpty_portmask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pEmpty_portmask) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicQeueuEmptyStatus(&pmask)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtk_switch_portmask_P2L_get(pmask, pEmpty_portmask)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/vlan.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/vlan.c +new file mode 100644 +index 0000000000..f7480c4906 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367c/vlan.c +@@ -0,0 +1,2124 @@ ++/* ++ * 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 VLAN module. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++typedef enum vlan_mbrCfgType_e ++{ ++ MBRCFG_UNUSED = 0, ++ MBRCFG_USED_BY_VLAN, ++ MBRCFG_END ++}vlan_mbrCfgType_t; ++ ++static rtk_vlan_t vlan_mbrCfgVid[RTL8367C_CVIDXNO]; ++static vlan_mbrCfgType_t vlan_mbrCfgUsage[RTL8367C_CVIDXNO]; ++ ++/* Function Name: ++ * rtk_vlan_init ++ * Description: ++ * Initialize VLAN. ++ * Input: ++ * None ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * Note: ++ * VLAN is disabled by default. User has to call this API to enable VLAN before ++ * using it. And It will set a default VLAN(vid 1) including all ports and set ++ * all ports PVID to the default VLAN. ++ */ ++rtk_api_ret_t rtk_vlan_init(void) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 i; ++ rtl8367c_user_vlan4kentry vlan4K; ++ rtl8367c_vlanconfiguser vlanMC; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Clean Database */ ++ memset(vlan_mbrCfgVid, 0x00, sizeof(rtk_vlan_t) * RTL8367C_CVIDXNO); ++ memset(vlan_mbrCfgUsage, 0x00, sizeof(vlan_mbrCfgType_t) * RTL8367C_CVIDXNO); ++ ++ /* clean 32 VLAN member configuration */ ++ for (i = 0; i <= RTL8367C_CVIDXMAX; i++) ++ { ++ vlanMC.evid = 0; ++ vlanMC.mbr = 0; ++ vlanMC.fid_msti = 0; ++ vlanMC.envlanpol = 0; ++ vlanMC.meteridx = 0; ++ vlanMC.vbpen = 0; ++ vlanMC.vbpri = 0; ++ if ((retVal = rtl8367c_setAsicVlanMemberConfig(i, &vlanMC)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ /* Set a default VLAN with vid 1 to 4K table for all ports */ ++ memset(&vlan4K, 0, sizeof(rtl8367c_user_vlan4kentry)); ++ vlan4K.vid = 1; ++ vlan4K.mbr = RTK_PHY_PORTMASK_ALL; ++ vlan4K.untag = RTK_PHY_PORTMASK_ALL; ++ vlan4K.fid_msti = 0; ++ if ((retVal = rtl8367c_setAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) ++ return retVal; ++ ++ /* Also set the default VLAN to 32 member configuration index 0 */ ++ memset(&vlanMC, 0, sizeof(rtl8367c_vlanconfiguser)); ++ vlanMC.evid = 1; ++ vlanMC.mbr = RTK_PHY_PORTMASK_ALL; ++ vlanMC.fid_msti = 0; ++ if ((retVal = rtl8367c_setAsicVlanMemberConfig(0, &vlanMC)) != RT_ERR_OK) ++ return retVal; ++ ++ /* Set all ports PVID to default VLAN and tag-mode to original */ ++ RTK_SCAN_ALL_PHY_PORTMASK(i) ++ { ++ if ((retVal = rtl8367c_setAsicVlanPortBasedVID(i, 0, 0)) != RT_ERR_OK) ++ return retVal; ++ if ((retVal = rtl8367c_setAsicVlanEgressTagMode(i, EG_TAG_MODE_ORI)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ /* Updata Databse */ ++ vlan_mbrCfgUsage[0] = MBRCFG_USED_BY_VLAN; ++ vlan_mbrCfgVid[0] = 1; ++ ++ /* Enable Ingress filter */ ++ RTK_SCAN_ALL_PHY_PORTMASK(i) ++ { ++ if ((retVal = rtl8367c_setAsicVlanIngressFilter(i, ENABLED)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ /* enable VLAN */ ++ if ((retVal = rtl8367c_setAsicVlanFilter(ENABLED)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_set ++ * Description: ++ * Set a VLAN entry. ++ * Input: ++ * vid - VLAN ID to configure. ++ * pVlanCfg - VLAN Configuration ++ * 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_L2_FID - Invalid FID. ++ * RT_ERR_VLAN_PORT_MBR_EXIST - Invalid member port mask. ++ * RT_ERR_VLAN_VID - Invalid VID parameter. ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_vlan_set(rtk_vlan_t vid, rtk_vlan_cfg_t *pVlanCfg) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 phyMbrPmask; ++ rtk_uint32 phyUntagPmask; ++ rtl8367c_user_vlan4kentry vlan4K; ++ rtl8367c_vlanconfiguser vlanMC; ++ rtk_uint32 idx; ++ rtk_uint32 empty_index = 0xffff; ++ rtk_uint32 update_evid = 0; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* vid must be 0~8191 */ ++ if (vid > RTL8367C_EVIDMAX) ++ return RT_ERR_VLAN_VID; ++ ++ /* Null pointer check */ ++ if(NULL == pVlanCfg) ++ return RT_ERR_NULL_POINTER; ++ ++ /* Check port mask valid */ ++ RTK_CHK_PORTMASK_VALID(&(pVlanCfg->mbr)); ++ ++ if (vid <= RTL8367C_VIDMAX) ++ { ++ /* Check untag port mask valid */ ++ RTK_CHK_PORTMASK_VALID(&(pVlanCfg->untag)); ++ } ++ ++ /* IVL_EN */ ++ if(pVlanCfg->ivl_en >= RTK_ENABLE_END) ++ return RT_ERR_ENABLE; ++ ++ /* fid must be 0~15 */ ++ if(pVlanCfg->fid_msti > RTL8367C_FIDMAX) ++ return RT_ERR_L2_FID; ++ ++ /* Policing */ ++ if(pVlanCfg->envlanpol >= RTK_ENABLE_END) ++ return RT_ERR_ENABLE; ++ ++ /* Meter ID */ ++ if(pVlanCfg->meteridx > RTK_MAX_METER_ID) ++ return RT_ERR_INPUT; ++ ++ /* VLAN based priority */ ++ if(pVlanCfg->vbpen >= RTK_ENABLE_END) ++ return RT_ERR_ENABLE; ++ ++ /* Priority */ ++ if(pVlanCfg->vbpri > RTL8367C_PRIMAX) ++ return RT_ERR_INPUT; ++ ++ /* Get physical port mask */ ++ if(rtk_switch_portmask_L2P_get(&(pVlanCfg->mbr), &phyMbrPmask) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ ++ if(rtk_switch_portmask_L2P_get(&(pVlanCfg->untag), &phyUntagPmask) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ ++ if (vid <= RTL8367C_VIDMAX) ++ { ++ /* update 4K table */ ++ memset(&vlan4K, 0, sizeof(rtl8367c_user_vlan4kentry)); ++ vlan4K.vid = vid; ++ ++ vlan4K.mbr = (phyMbrPmask & 0xFFFF); ++ vlan4K.untag = (phyUntagPmask & 0xFFFF); ++ ++ vlan4K.ivl_svl = pVlanCfg->ivl_en; ++ vlan4K.fid_msti = pVlanCfg->fid_msti; ++ vlan4K.envlanpol = pVlanCfg->envlanpol; ++ vlan4K.meteridx = pVlanCfg->meteridx; ++ vlan4K.vbpen = pVlanCfg->vbpen; ++ vlan4K.vbpri = pVlanCfg->vbpri; ++ ++ if ((retVal = rtl8367c_setAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) ++ return retVal; ++ ++ /* Update Member configuration if exist */ ++ for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) ++ { ++ if(vlan_mbrCfgUsage[idx] == MBRCFG_USED_BY_VLAN) ++ { ++ if(vlan_mbrCfgVid[idx] == vid) ++ { ++ /* Found! Update */ ++ if(phyMbrPmask == 0x00) ++ { ++ /* Member port = 0x00, delete this VLAN from Member Configuration */ ++ memset(&vlanMC, 0x00, sizeof(rtl8367c_vlanconfiguser)); ++ if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) ++ return retVal; ++ ++ /* Clear Database */ ++ vlan_mbrCfgUsage[idx] = MBRCFG_UNUSED; ++ vlan_mbrCfgVid[idx] = 0; ++ } ++ else ++ { ++ /* Normal VLAN config, update to member configuration */ ++ vlanMC.evid = vid; ++ vlanMC.mbr = vlan4K.mbr; ++ vlanMC.fid_msti = vlan4K.fid_msti; ++ vlanMC.meteridx = vlan4K.meteridx; ++ vlanMC.envlanpol= vlan4K.envlanpol; ++ vlanMC.vbpen = vlan4K.vbpen; ++ vlanMC.vbpri = vlan4K.vbpri; ++ if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ break; ++ } ++ } ++ } ++ } ++ else ++ { ++ /* vid > 4095 */ ++ for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) ++ { ++ if(vlan_mbrCfgUsage[idx] == MBRCFG_USED_BY_VLAN) ++ { ++ if(vlan_mbrCfgVid[idx] == vid) ++ { ++ /* Found! Update */ ++ if(phyMbrPmask == 0x00) ++ { ++ /* Member port = 0x00, delete this VLAN from Member Configuration */ ++ memset(&vlanMC, 0x00, sizeof(rtl8367c_vlanconfiguser)); ++ if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) ++ return retVal; ++ ++ /* Clear Database */ ++ vlan_mbrCfgUsage[idx] = MBRCFG_UNUSED; ++ vlan_mbrCfgVid[idx] = 0; ++ } ++ else ++ { ++ /* Normal VLAN config, update to member configuration */ ++ vlanMC.evid = vid; ++ vlanMC.mbr = phyMbrPmask; ++ vlanMC.fid_msti = pVlanCfg->fid_msti; ++ vlanMC.meteridx = pVlanCfg->meteridx; ++ vlanMC.envlanpol= pVlanCfg->envlanpol; ++ vlanMC.vbpen = pVlanCfg->vbpen; ++ vlanMC.vbpri = pVlanCfg->vbpri; ++ if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) ++ return retVal; ++ ++ break; ++ } ++ ++ update_evid = 1; ++ } ++ } ++ ++ if(vlan_mbrCfgUsage[idx] == MBRCFG_UNUSED) ++ { ++ if(0xffff == empty_index) ++ empty_index = idx; ++ } ++ } ++ ++ /* doesn't find out same EVID entry and there is empty index in member configuration */ ++ if( (phyMbrPmask != 0x00) && (update_evid == 0) && (empty_index != 0xFFFF) ) ++ { ++ vlanMC.evid = vid; ++ vlanMC.mbr = phyMbrPmask; ++ vlanMC.fid_msti = pVlanCfg->fid_msti; ++ vlanMC.meteridx = pVlanCfg->meteridx; ++ vlanMC.envlanpol= pVlanCfg->envlanpol; ++ vlanMC.vbpen = pVlanCfg->vbpen; ++ vlanMC.vbpri = pVlanCfg->vbpri; ++ if ((retVal = rtl8367c_setAsicVlanMemberConfig(empty_index, &vlanMC)) != RT_ERR_OK) ++ return retVal; ++ ++ vlan_mbrCfgUsage[empty_index] = MBRCFG_USED_BY_VLAN; ++ vlan_mbrCfgVid[empty_index] = vid; ++ ++ } ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_get ++ * Description: ++ * Get a VLAN entry. ++ * Input: ++ * vid - VLAN ID to configure. ++ * Output: ++ * pVlanCfg - VLAN Configuration ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters. ++ * RT_ERR_VLAN_VID - Invalid VID parameter. ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_vlan_get(rtk_vlan_t vid, rtk_vlan_cfg_t *pVlanCfg) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 phyMbrPmask; ++ rtk_uint32 phyUntagPmask; ++ rtl8367c_user_vlan4kentry vlan4K; ++ rtl8367c_vlanconfiguser vlanMC; ++ rtk_uint32 idx; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* vid must be 0~8191 */ ++ if (vid > RTL8367C_EVIDMAX) ++ return RT_ERR_VLAN_VID; ++ ++ /* Null pointer check */ ++ if(NULL == pVlanCfg) ++ return RT_ERR_NULL_POINTER; ++ ++ if (vid <= RTL8367C_VIDMAX) ++ { ++ vlan4K.vid = vid; ++ ++ if ((retVal = rtl8367c_getAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) ++ return retVal; ++ ++ phyMbrPmask = vlan4K.mbr; ++ phyUntagPmask = vlan4K.untag; ++ if(rtk_switch_portmask_P2L_get(phyMbrPmask, &(pVlanCfg->mbr)) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ ++ if(rtk_switch_portmask_P2L_get(phyUntagPmask, &(pVlanCfg->untag)) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ ++ pVlanCfg->ivl_en = vlan4K.ivl_svl; ++ pVlanCfg->fid_msti = vlan4K.fid_msti; ++ pVlanCfg->envlanpol = vlan4K.envlanpol; ++ pVlanCfg->meteridx = vlan4K.meteridx; ++ pVlanCfg->vbpen = vlan4K.vbpen; ++ pVlanCfg->vbpri = vlan4K.vbpri; ++ } ++ else ++ { ++ for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) ++ { ++ if(vlan_mbrCfgUsage[idx] == MBRCFG_USED_BY_VLAN) ++ { ++ if(vlan_mbrCfgVid[idx] == vid) ++ { ++ if ((retVal = rtl8367c_getAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) ++ return retVal; ++ ++ phyMbrPmask = vlanMC.mbr; ++ if(rtk_switch_portmask_P2L_get(phyMbrPmask, &(pVlanCfg->mbr)) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ ++ pVlanCfg->untag.bits[0] = 0; ++ pVlanCfg->ivl_en = 0; ++ pVlanCfg->fid_msti = vlanMC.fid_msti; ++ pVlanCfg->envlanpol = vlanMC.envlanpol; ++ pVlanCfg->meteridx = vlanMC.meteridx; ++ pVlanCfg->vbpen = vlanMC.vbpen; ++ pVlanCfg->vbpri = vlanMC.vbpri; ++ } ++ } ++ } ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_egrFilterEnable_set ++ * Description: ++ * Set VLAN egress filter. ++ * Input: ++ * egrFilter - Egress filtering ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_ENABLE - Invalid input parameters. ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_vlan_egrFilterEnable_set(rtk_enable_t egrFilter) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(egrFilter >= RTK_ENABLE_END) ++ return RT_ERR_ENABLE; ++ ++ /* enable VLAN */ ++ if ((retVal = rtl8367c_setAsicVlanFilter((rtk_uint32)egrFilter)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_egrFilterEnable_get ++ * Description: ++ * Get VLAN egress filter. ++ * Input: ++ * pEgrFilter - Egress filtering ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NULL_POINTER - NULL Pointer. ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_vlan_egrFilterEnable_get(rtk_enable_t *pEgrFilter) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 state; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pEgrFilter) ++ return RT_ERR_NULL_POINTER; ++ ++ /* enable VLAN */ ++ if ((retVal = rtl8367c_getAsicVlanFilter(&state)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEgrFilter = (rtk_enable_t)state; ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_mbrCfg_set ++ * Description: ++ * Set a VLAN Member Configuration entry by index. ++ * Input: ++ * idx - Index of VLAN Member Configuration. ++ * pMbrcfg - VLAN member Configuration. ++ * 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_VID - Invalid VID parameter. ++ * Note: ++ * Set a VLAN Member Configuration entry by index. ++ */ ++rtk_api_ret_t rtk_vlan_mbrCfg_set(rtk_uint32 idx, rtk_vlan_mbrcfg_t *pMbrcfg) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 phyMbrPmask; ++ rtl8367c_vlanconfiguser mbrCfg; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Error check */ ++ if(pMbrcfg == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ if(idx > RTL8367C_CVIDXMAX) ++ return RT_ERR_INPUT; ++ ++ if(pMbrcfg->evid > RTL8367C_EVIDMAX) ++ return RT_ERR_INPUT; ++ ++ if(pMbrcfg->fid_msti > RTL8367C_FIDMAX) ++ return RT_ERR_L2_FID; ++ ++ if(pMbrcfg->envlanpol >= RTK_ENABLE_END) ++ return RT_ERR_ENABLE; ++ ++ if(pMbrcfg->meteridx > RTK_MAX_METER_ID) ++ return RT_ERR_FILTER_METER_ID; ++ ++ if(pMbrcfg->vbpen >= RTK_ENABLE_END) ++ return RT_ERR_ENABLE; ++ ++ if(pMbrcfg->vbpri > RTL8367C_PRIMAX) ++ return RT_ERR_QOS_INT_PRIORITY; ++ ++ /* Check port mask valid */ ++ RTK_CHK_PORTMASK_VALID(&(pMbrcfg->mbr)); ++ ++ mbrCfg.evid = pMbrcfg->evid; ++ mbrCfg.fid_msti = pMbrcfg->fid_msti; ++ mbrCfg.envlanpol = pMbrcfg->envlanpol; ++ mbrCfg.meteridx = pMbrcfg->meteridx; ++ mbrCfg.vbpen = pMbrcfg->vbpen; ++ mbrCfg.vbpri = pMbrcfg->vbpri; ++ ++ if(rtk_switch_portmask_L2P_get(&(pMbrcfg->mbr), &phyMbrPmask) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ ++ mbrCfg.mbr = phyMbrPmask; ++ ++ if ((retVal = rtl8367c_setAsicVlanMemberConfig(idx, &mbrCfg)) != RT_ERR_OK) ++ return retVal; ++ ++ /* Update Database */ ++ if( (mbrCfg.evid == 0) && (mbrCfg.mbr == 0) ) ++ { ++ vlan_mbrCfgUsage[idx] = MBRCFG_UNUSED; ++ vlan_mbrCfgVid[idx] = 0; ++ } ++ else ++ { ++ vlan_mbrCfgUsage[idx] = MBRCFG_USED_BY_VLAN; ++ vlan_mbrCfgVid[idx] = mbrCfg.evid; ++ } ++ ++ return RT_ERR_OK; ++ ++} ++ ++/* Function Name: ++ * rtk_vlan_mbrCfg_get ++ * Description: ++ * Get a VLAN Member Configuration entry by index. ++ * Input: ++ * idx - Index of VLAN Member Configuration. ++ * Output: ++ * pMbrcfg - VLAN member Configuration. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters. ++ * RT_ERR_VLAN_VID - Invalid VID parameter. ++ * Note: ++ * Get a VLAN Member Configuration entry by index. ++ */ ++rtk_api_ret_t rtk_vlan_mbrCfg_get(rtk_uint32 idx, rtk_vlan_mbrcfg_t *pMbrcfg) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 phyMbrPmask; ++ rtl8367c_vlanconfiguser mbrCfg; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Error check */ ++ if(pMbrcfg == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ if(idx > RTL8367C_CVIDXMAX) ++ return RT_ERR_INPUT; ++ ++ memset(&mbrCfg, 0x00, sizeof(rtl8367c_vlanconfiguser)); ++ if ((retVal = rtl8367c_getAsicVlanMemberConfig(idx, &mbrCfg)) != RT_ERR_OK) ++ return retVal; ++ ++ pMbrcfg->evid = mbrCfg.evid; ++ pMbrcfg->fid_msti = mbrCfg.fid_msti; ++ pMbrcfg->envlanpol = mbrCfg.envlanpol; ++ pMbrcfg->meteridx = mbrCfg.meteridx; ++ pMbrcfg->vbpen = mbrCfg.vbpen; ++ pMbrcfg->vbpri = mbrCfg.vbpri; ++ ++ phyMbrPmask = mbrCfg.mbr; ++ if(rtk_switch_portmask_P2L_get(phyMbrPmask, &(pMbrcfg->mbr)) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_portPvid_set ++ * Description: ++ * Set port to specified VLAN ID(PVID). ++ * Input: ++ * port - Port id. ++ * pvid - Specified VLAN ID. ++ * priority - 802.1p priority for the PVID. ++ * 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_VLAN_PRIORITY - Invalid priority. ++ * RT_ERR_VLAN_ENTRY_NOT_FOUND - VLAN entry not found. ++ * RT_ERR_VLAN_VID - Invalid VID parameter. ++ * Note: ++ * The API is used for Port-based VLAN. The untagged frame received from the ++ * port will be classified to the specified VLAN and assigned to the specified priority. ++ */ ++rtk_api_ret_t rtk_vlan_portPvid_set(rtk_port_t port, rtk_vlan_t pvid, rtk_pri_t priority) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 index; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ /* vid must be 0~8191 */ ++ if (pvid > RTL8367C_EVIDMAX) ++ return RT_ERR_VLAN_VID; ++ ++ /* priority must be 0~7 */ ++ if (priority > RTL8367C_PRIMAX) ++ return RT_ERR_VLAN_PRIORITY; ++ ++ if((retVal = rtk_vlan_checkAndCreateMbr(pvid, &index)) != RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicVlanPortBasedVID(rtk_switch_port_L2P_get(port), index, priority)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_portPvid_get ++ * Description: ++ * Get VLAN ID(PVID) on specified port. ++ * Input: ++ * port - Port id. ++ * Output: ++ * pPvid - Specified VLAN ID. ++ * pPriority - 802.1p priority for the PVID. ++ * 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 PVID and 802.1p priority for the PVID of Port-based VLAN. ++ */ ++rtk_api_ret_t rtk_vlan_portPvid_get(rtk_port_t port, rtk_vlan_t *pPvid, rtk_pri_t *pPriority) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 index, pri; ++ rtl8367c_vlanconfiguser mbrCfg; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(NULL == pPvid) ++ return RT_ERR_NULL_POINTER; ++ ++ if(NULL == pPriority) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicVlanPortBasedVID(rtk_switch_port_L2P_get(port), &index, &pri)) != RT_ERR_OK) ++ return retVal; ++ ++ memset(&mbrCfg, 0x00, sizeof(rtl8367c_vlanconfiguser)); ++ if ((retVal = rtl8367c_getAsicVlanMemberConfig(index, &mbrCfg)) != RT_ERR_OK) ++ return retVal; ++ ++ *pPvid = mbrCfg.evid; ++ *pPriority = pri; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_portIgrFilterEnable_set ++ * Description: ++ * Set VLAN ingress for each port. ++ * Input: ++ * port - Port id. ++ * igr_filter - VLAN ingress function enable 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: ++ * The status of vlan ingress filter is as following: ++ * - DISABLED ++ * - ENABLED ++ * While VLAN function is enabled, ASIC will decide VLAN ID for each received frame and get belonged member ++ * ports from VLAN table. If received port is not belonged to VLAN member ports, ASIC will drop received frame if VLAN ingress function is enabled. ++ */ ++rtk_api_ret_t rtk_vlan_portIgrFilterEnable_set(rtk_port_t port, rtk_enable_t igr_filter) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if (igr_filter >= RTK_ENABLE_END) ++ return RT_ERR_ENABLE; ++ ++ if ((retVal = rtl8367c_setAsicVlanIngressFilter(rtk_switch_port_L2P_get(port), igr_filter)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_portIgrFilterEnable_get ++ * Description: ++ * Get VLAN Ingress Filter ++ * Input: ++ * port - Port id. ++ * Output: ++ * pIgr_filter - VLAN ingress function enable status. ++ * 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 VLAN ingress filter status. ++ * The status of vlan ingress filter is as following: ++ * - DISABLED ++ * - ENABLED ++ */ ++rtk_api_ret_t rtk_vlan_portIgrFilterEnable_get(rtk_port_t port, rtk_enable_t *pIgr_filter) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(NULL == pIgr_filter) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicVlanIngressFilter(rtk_switch_port_L2P_get(port), pIgr_filter)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_portAcceptFrameType_set ++ * Description: ++ * Set VLAN accept_frame_type ++ * Input: ++ * port - Port id. ++ * accept_frame_type - accept frame type ++ * 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_VLAN_ACCEPT_FRAME_TYPE - Invalid frame type. ++ * Note: ++ * The API is used for checking 802.1Q tagged frames. ++ * The accept frame type as following: ++ * - ACCEPT_FRAME_TYPE_ALL ++ * - ACCEPT_FRAME_TYPE_TAG_ONLY ++ * - ACCEPT_FRAME_TYPE_UNTAG_ONLY ++ */ ++rtk_api_ret_t rtk_vlan_portAcceptFrameType_set(rtk_port_t port, rtk_vlan_acceptFrameType_t accept_frame_type) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if (accept_frame_type >= ACCEPT_FRAME_TYPE_END) ++ return RT_ERR_VLAN_ACCEPT_FRAME_TYPE; ++ ++ if ((retVal = rtl8367c_setAsicVlanAccpetFrameType(rtk_switch_port_L2P_get(port), (rtl8367c_accframetype)accept_frame_type)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_portAcceptFrameType_get ++ * Description: ++ * Get VLAN accept_frame_type ++ * Input: ++ * port - Port id. ++ * Output: ++ * pAccept_frame_type - accept frame type ++ * 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 VLAN ingress filter. ++ * The accept frame type as following: ++ * - ACCEPT_FRAME_TYPE_ALL ++ * - ACCEPT_FRAME_TYPE_TAG_ONLY ++ * - ACCEPT_FRAME_TYPE_UNTAG_ONLY ++ */ ++rtk_api_ret_t rtk_vlan_portAcceptFrameType_get(rtk_port_t port, rtk_vlan_acceptFrameType_t *pAccept_frame_type) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_accframetype acc_frm_type; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(NULL == pAccept_frame_type) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicVlanAccpetFrameType(rtk_switch_port_L2P_get(port), &acc_frm_type)) != RT_ERR_OK) ++ return retVal; ++ ++ *pAccept_frame_type = (rtk_vlan_acceptFrameType_t)acc_frm_type; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_protoAndPortBasedVlan_add ++ * Description: ++ * Add the protocol-and-port-based vlan to the specified port of device. ++ * Input: ++ * port - Port id. ++ * pInfo - Protocol and port based VLAN configuration information. ++ * 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_VLAN_VID - Invalid VID parameter. ++ * RT_ERR_VLAN_PRIORITY - Invalid priority. ++ * RT_ERR_TBL_FULL - Table is full. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * Note: ++ * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline ++ * The frame type is shown in the following: ++ * - FRAME_TYPE_ETHERNET ++ * - FRAME_TYPE_RFC1042 ++ * - FRAME_TYPE_LLCOTHER ++ */ ++rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_add(rtk_port_t port, rtk_vlan_protoAndPortInfo_t *pInfo) ++{ ++ rtk_api_ret_t retVal, i; ++ rtk_uint32 exist, empty, used, index; ++ rtl8367c_protocolgdatacfg ppb_data_cfg; ++ rtl8367c_protocolvlancfg ppb_vlan_cfg; ++ rtl8367c_provlan_frametype tmp; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(NULL == pInfo) ++ return RT_ERR_NULL_POINTER; ++ ++ if (pInfo->proto_type > RTK_MAX_NUM_OF_PROTO_TYPE) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if (pInfo->frame_type >= FRAME_TYPE_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if (pInfo->cvid > RTL8367C_VIDMAX) ++ return RT_ERR_VLAN_VID; ++ ++ if (pInfo->cpri > RTL8367C_PRIMAX) ++ return RT_ERR_VLAN_PRIORITY; ++ ++ exist = 0xFF; ++ empty = 0xFF; ++ for (i = RTL8367C_PROTOVLAN_GIDX_MAX; i >= 0; i--) ++ { ++ if ((retVal = rtl8367c_getAsicVlanProtocolBasedGroupData(i, &ppb_data_cfg)) != RT_ERR_OK) ++ return retVal; ++ tmp = pInfo->frame_type; ++ if (ppb_data_cfg.etherType == pInfo->proto_type && ppb_data_cfg.frameType == tmp) ++ { ++ /*Already exist*/ ++ exist = i; ++ break; ++ } ++ else if (ppb_data_cfg.etherType == 0 && ppb_data_cfg.frameType == 0) ++ { ++ /*find empty index*/ ++ empty = i; ++ } ++ } ++ ++ used = 0xFF; ++ /*No empty and exist index*/ ++ if (0xFF == exist && 0xFF == empty) ++ return RT_ERR_TBL_FULL; ++ else if (existframe_type; ++ ppb_data_cfg.etherType = pInfo->proto_type; ++ if ((retVal = rtl8367c_setAsicVlanProtocolBasedGroupData(empty, &ppb_data_cfg)) != RT_ERR_OK) ++ return retVal; ++ used = empty; ++ } ++ else ++ return RT_ERR_FAILED; ++ ++ if((retVal = rtk_vlan_checkAndCreateMbr(pInfo->cvid, &index)) != RT_ERR_OK) ++ return retVal; ++ ++ ppb_vlan_cfg.vlan_idx = index; ++ ppb_vlan_cfg.valid = TRUE; ++ ppb_vlan_cfg.priority = pInfo->cpri; ++ if ((retVal = rtl8367c_setAsicVlanPortAndProtocolBased(rtk_switch_port_L2P_get(port), used, &ppb_vlan_cfg)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_protoAndPortBasedVlan_get ++ * Description: ++ * Get the protocol-and-port-based vlan to the specified port of device. ++ * Input: ++ * port - Port id. ++ * proto_type - protocol-and-port-based vlan protocol type. ++ * frame_type - protocol-and-port-based vlan frame type. ++ * Output: ++ * pInfo - Protocol and port based VLAN configuration information. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * RT_ERR_TBL_FULL - Table is full. ++ * Note: ++ * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline ++ * The frame type is shown in the following: ++ * - FRAME_TYPE_ETHERNET ++ * - FRAME_TYPE_RFC1042 ++ * - FRAME_TYPE_LLCOTHER ++ */ ++rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_get(rtk_port_t port, rtk_vlan_proto_type_t proto_type, rtk_vlan_protoVlan_frameType_t frame_type, rtk_vlan_protoAndPortInfo_t *pInfo) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 i; ++ rtk_uint32 ppb_idx; ++ rtl8367c_protocolgdatacfg ppb_data_cfg; ++ rtl8367c_protocolvlancfg ppb_vlan_cfg; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if (proto_type > RTK_MAX_NUM_OF_PROTO_TYPE) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if (frame_type >= FRAME_TYPE_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ ppb_idx = 0; ++ ++ for (i = 0; i<= RTL8367C_PROTOVLAN_GIDX_MAX; i++) ++ { ++ if ((retVal = rtl8367c_getAsicVlanProtocolBasedGroupData(i, &ppb_data_cfg)) != RT_ERR_OK) ++ return retVal; ++ ++ if ( (ppb_data_cfg.frameType == (rtl8367c_provlan_frametype)frame_type) && (ppb_data_cfg.etherType == proto_type) ) ++ { ++ ppb_idx = i; ++ break; ++ } ++ else if (RTL8367C_PROTOVLAN_GIDX_MAX == i) ++ return RT_ERR_TBL_FULL; ++ } ++ ++ if ((retVal = rtl8367c_getAsicVlanPortAndProtocolBased(rtk_switch_port_L2P_get(port), ppb_idx, &ppb_vlan_cfg)) != RT_ERR_OK) ++ return retVal; ++ ++ if (FALSE == ppb_vlan_cfg.valid) ++ return RT_ERR_FAILED; ++ ++ pInfo->frame_type = frame_type; ++ pInfo->proto_type = proto_type; ++ pInfo->cvid = vlan_mbrCfgVid[ppb_vlan_cfg.vlan_idx]; ++ pInfo->cpri = ppb_vlan_cfg.priority; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_protoAndPortBasedVlan_del ++ * Description: ++ * Delete the protocol-and-port-based vlan from the specified port of device. ++ * Input: ++ * port - Port id. ++ * proto_type - protocol-and-port-based vlan protocol type. ++ * frame_type - protocol-and-port-based vlan frame type. ++ * 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_OUT_OF_RANGE - input out of range. ++ * RT_ERR_TBL_FULL - Table is full. ++ * Note: ++ * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline ++ * The frame type is shown in the following: ++ * - FRAME_TYPE_ETHERNET ++ * - FRAME_TYPE_RFC1042 ++ * - FRAME_TYPE_LLCOTHER ++ */ ++rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_del(rtk_port_t port, rtk_vlan_proto_type_t proto_type, rtk_vlan_protoVlan_frameType_t frame_type) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 i, bUsed; ++ rtk_uint32 ppb_idx; ++ rtl8367c_protocolgdatacfg ppb_data_cfg; ++ rtl8367c_protocolvlancfg ppb_vlan_cfg; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if (proto_type > RTK_MAX_NUM_OF_PROTO_TYPE) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ if (frame_type >= FRAME_TYPE_END) ++ return RT_ERR_OUT_OF_RANGE; ++ ++ ppb_idx = 0; ++ ++ for (i = 0; i<= RTL8367C_PROTOVLAN_GIDX_MAX; i++) ++ { ++ if ((retVal = rtl8367c_getAsicVlanProtocolBasedGroupData(i, &ppb_data_cfg)) != RT_ERR_OK) ++ return retVal; ++ ++ if ( (ppb_data_cfg.frameType == (rtl8367c_provlan_frametype)frame_type) && (ppb_data_cfg.etherType == proto_type) ) ++ { ++ ppb_idx = i; ++ ppb_vlan_cfg.valid = FALSE; ++ ppb_vlan_cfg.vlan_idx = 0; ++ ppb_vlan_cfg.priority = 0; ++ if ((retVal = rtl8367c_setAsicVlanPortAndProtocolBased(rtk_switch_port_L2P_get(port), ppb_idx, &ppb_vlan_cfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ ++ bUsed = FALSE; ++ RTK_SCAN_ALL_PHY_PORTMASK(i) ++ { ++ if ((retVal = rtl8367c_getAsicVlanPortAndProtocolBased(i, ppb_idx, &ppb_vlan_cfg)) != RT_ERR_OK) ++ return retVal; ++ ++ if (TRUE == ppb_vlan_cfg.valid) ++ { ++ bUsed = TRUE; ++ break; ++ } ++ } ++ ++ if (FALSE == bUsed) /*No Port use this PPB Index, Delete it*/ ++ { ++ ppb_data_cfg.etherType=0; ++ ppb_data_cfg.frameType=0; ++ if ((retVal = rtl8367c_setAsicVlanProtocolBasedGroupData(ppb_idx, &ppb_data_cfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_protoAndPortBasedVlan_delAll ++ * Description: ++ * Delete all protocol-and-port-based vlans from the specified port of device. ++ * 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 number. ++ * RT_ERR_OUT_OF_RANGE - input out of range. ++ * Note: ++ * The incoming packet which match the protocol-and-port-based vlan will use the configure vid for ingress pipeline ++ * Delete all flow table protocol-and-port-based vlan entries. ++ */ ++rtk_api_ret_t rtk_vlan_protoAndPortBasedVlan_delAll(rtk_port_t port) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 i, j, bUsed[4]; ++ rtl8367c_protocolgdatacfg ppb_data_cfg; ++ rtl8367c_protocolvlancfg ppb_vlan_cfg; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ for (i = 0; i<= RTL8367C_PROTOVLAN_GIDX_MAX; i++) ++ { ++ ppb_vlan_cfg.valid = FALSE; ++ ppb_vlan_cfg.vlan_idx = 0; ++ ppb_vlan_cfg.priority = 0; ++ if ((retVal = rtl8367c_setAsicVlanPortAndProtocolBased(rtk_switch_port_L2P_get(port), i, &ppb_vlan_cfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ bUsed[0] = FALSE; ++ bUsed[1] = FALSE; ++ bUsed[2] = FALSE; ++ bUsed[3] = FALSE; ++ RTK_SCAN_ALL_PHY_PORTMASK(i) ++ { ++ for (j = 0; j <= RTL8367C_PROTOVLAN_GIDX_MAX; j++) ++ { ++ if ((retVal = rtl8367c_getAsicVlanPortAndProtocolBased(i,j, &ppb_vlan_cfg)) != RT_ERR_OK) ++ return retVal; ++ ++ if (TRUE == ppb_vlan_cfg.valid) ++ { ++ bUsed[j] = TRUE; ++ } ++ } ++ } ++ ++ for (i = 0; i<= RTL8367C_PROTOVLAN_GIDX_MAX; i++) ++ { ++ if (FALSE == bUsed[i]) /*No Port use this PPB Index, Delete it*/ ++ { ++ ppb_data_cfg.etherType=0; ++ ppb_data_cfg.frameType=0; ++ if ((retVal = rtl8367c_setAsicVlanProtocolBasedGroupData(i, &ppb_data_cfg)) != RT_ERR_OK) ++ return retVal; ++ } ++ } ++ ++ ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_tagMode_set ++ * Description: ++ * Set CVLAN egress tag mode ++ * Input: ++ * port - Port id. ++ * tag_mode - The egress tag mode. ++ * 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. ++ * RT_ERR_ENABLE - Invalid enable input. ++ * Note: ++ * The API can set Egress tag mode. There are 4 mode for egress tag: ++ * - VLAN_TAG_MODE_ORIGINAL, ++ * - VLAN_TAG_MODE_KEEP_FORMAT, ++ * - VLAN_TAG_MODE_PRI. ++ * - VLAN_TAG_MODE_REAL_KEEP_FORMAT, ++ */ ++rtk_api_ret_t rtk_vlan_tagMode_set(rtk_port_t port, rtk_vlan_tagMode_t tag_mode) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if (tag_mode >= VLAN_TAG_MODE_END) ++ return RT_ERR_PORT_ID; ++ ++ if ((retVal = rtl8367c_setAsicVlanEgressTagMode(rtk_switch_port_L2P_get(port), tag_mode)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_tagMode_get ++ * Description: ++ * Get CVLAN egress tag mode ++ * Input: ++ * port - Port id. ++ * Output: ++ * pTag_mode - The egress tag mode. ++ * 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 Egress tag mode. There are 4 mode for egress tag: ++ * - VLAN_TAG_MODE_ORIGINAL, ++ * - VLAN_TAG_MODE_KEEP_FORMAT, ++ * - VLAN_TAG_MODE_PRI. ++ * - VLAN_TAG_MODE_REAL_KEEP_FORMAT, ++ */ ++rtk_api_ret_t rtk_vlan_tagMode_get(rtk_port_t port, rtk_vlan_tagMode_t *pTag_mode) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_egtagmode mode; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if(NULL == pTag_mode) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicVlanEgressTagMode(rtk_switch_port_L2P_get(port), &mode)) != RT_ERR_OK) ++ return retVal; ++ ++ *pTag_mode = (rtk_vlan_tagMode_t)mode; ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_transparent_set ++ * Description: ++ * Set VLAN transparent mode ++ * Input: ++ * egr_port - Egress Port id. ++ * pIgr_pmask - Ingress 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. ++ * RT_ERR_PORT_ID - Invalid port number. ++ * Note: ++ * None. ++ */ ++rtk_api_ret_t rtk_vlan_transparent_set(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(egr_port); ++ ++ if(NULL == pIgr_pmask) ++ return RT_ERR_NULL_POINTER; ++ ++ RTK_CHK_PORTMASK_VALID(pIgr_pmask); ++ ++ if(rtk_switch_portmask_L2P_get(pIgr_pmask, &pmask) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ ++ if ((retVal = rtl8367c_setAsicVlanTransparent(rtk_switch_port_L2P_get(egr_port), pmask)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_transparent_get ++ * Description: ++ * Get VLAN transparent mode ++ * Input: ++ * egr_port - Egress Port id. ++ * Output: ++ * pIgr_pmask - Ingress Port Mask ++ * 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: ++ * None. ++ */ ++rtk_api_ret_t rtk_vlan_transparent_get(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(egr_port); ++ ++ if(NULL == pIgr_pmask) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicVlanTransparent(rtk_switch_port_L2P_get(egr_port), &pmask)) != RT_ERR_OK) ++ return retVal; ++ ++ if(rtk_switch_portmask_P2L_get(pmask, pIgr_pmask) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_keep_set ++ * Description: ++ * Set VLAN egress keep mode ++ * Input: ++ * egr_port - Egress Port id. ++ * pIgr_pmask - Ingress 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. ++ * RT_ERR_PORT_ID - Invalid port number. ++ * Note: ++ * None. ++ */ ++rtk_api_ret_t rtk_vlan_keep_set(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(egr_port); ++ ++ if(NULL == pIgr_pmask) ++ return RT_ERR_NULL_POINTER; ++ ++ RTK_CHK_PORTMASK_VALID(pIgr_pmask); ++ ++ if(rtk_switch_portmask_L2P_get(pIgr_pmask, &pmask) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ ++ if ((retVal = rtl8367c_setAsicVlanEgressKeep(rtk_switch_port_L2P_get(egr_port), pmask)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_keep_get ++ * Description: ++ * Get VLAN egress keep mode ++ * Input: ++ * egr_port - Egress Port id. ++ * Output: ++ * pIgr_pmask - Ingress Port Mask ++ * 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: ++ * None. ++ */ ++rtk_api_ret_t rtk_vlan_keep_get(rtk_port_t egr_port, rtk_portmask_t *pIgr_pmask) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 pmask; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(egr_port); ++ ++ if(NULL == pIgr_pmask) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicVlanEgressKeep(rtk_switch_port_L2P_get(egr_port), &pmask)) != RT_ERR_OK) ++ return retVal; ++ ++ if(rtk_switch_portmask_P2L_get(pmask, pIgr_pmask) != RT_ERR_OK) ++ return RT_ERR_FAILED; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_stg_set ++ * Description: ++ * Set spanning tree group instance of the vlan to the specified device ++ * Input: ++ * vid - Specified VLAN ID. ++ * stg - spanning tree group instance. ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_MSTI - Invalid msti parameter ++ * RT_ERR_INPUT - Invalid input parameter. ++ * RT_ERR_VLAN_VID - Invalid VID parameter. ++ * Note: ++ * The API can set spanning tree group instance of the vlan to the specified device. ++ */ ++rtk_api_ret_t rtk_vlan_stg_set(rtk_vlan_t vid, rtk_stp_msti_id_t stg) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_user_vlan4kentry vlan4K; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* vid must be 0~4095 */ ++ if (vid > RTL8367C_VIDMAX) ++ return RT_ERR_VLAN_VID; ++ ++ /* priority must be 0~15 */ ++ if (stg > RTL8367C_MSTIMAX) ++ return RT_ERR_MSTI; ++ ++ /* update 4K table */ ++ vlan4K.vid = vid; ++ if ((retVal = rtl8367c_getAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) ++ return retVal; ++ ++ vlan4K.fid_msti= stg; ++ if ((retVal = rtl8367c_setAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_stg_get ++ * Description: ++ * Get spanning tree group instance of the vlan to the specified device ++ * Input: ++ * vid - Specified VLAN ID. ++ * Output: ++ * pStg - spanning tree group instance. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Invalid input parameters. ++ * RT_ERR_VLAN_VID - Invalid VID parameter. ++ * Note: ++ * The API can get spanning tree group instance of the vlan to the specified device. ++ */ ++rtk_api_ret_t rtk_vlan_stg_get(rtk_vlan_t vid, rtk_stp_msti_id_t *pStg) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_user_vlan4kentry vlan4K; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* vid must be 0~4095 */ ++ if (vid > RTL8367C_VIDMAX) ++ return RT_ERR_VLAN_VID; ++ ++ if(NULL == pStg) ++ return RT_ERR_NULL_POINTER; ++ ++ /* update 4K table */ ++ vlan4K.vid = vid; ++ if ((retVal = rtl8367c_getAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) ++ return retVal; ++ ++ *pStg = vlan4K.fid_msti; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_portFid_set ++ * Description: ++ * Set port-based filtering database ++ * Input: ++ * port - Port id. ++ * enable - ebable port-based FID ++ * fid - Specified 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 filtering database. If the function is enabled, all input ++ * packets will be assigned to the port-based fid regardless vlan tag. ++ */ ++rtk_api_ret_t rtk_vlan_portFid_set(rtk_port_t port, rtk_enable_t enable, rtk_fid_t fid) ++{ ++ 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; ++ ++ /* fid must be 0~4095 */ ++ if (fid > RTK_FID_MAX) ++ return RT_ERR_L2_FID; ++ ++ if ((retVal = rtl8367c_setAsicPortBasedFidEn(rtk_switch_port_L2P_get(port), enable))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_setAsicPortBasedFid(rtk_switch_port_L2P_get(port), fid))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_portFid_get ++ * Description: ++ * Get port-based filtering database ++ * Input: ++ * port - Port id. ++ * Output: ++ * pEnable - ebable port-based FID ++ * pFid - Specified 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 filtering database status. If the function is enabled, all input ++ * packets will be assigned to the port-based fid regardless vlan tag. ++ */ ++rtk_api_ret_t rtk_vlan_portFid_get(rtk_port_t port, rtk_enable_t *pEnable, rtk_fid_t *pFid) ++{ ++ 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(NULL == pFid) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicPortBasedFidEn(rtk_switch_port_L2P_get(port), pEnable))!=RT_ERR_OK) ++ return retVal; ++ ++ if ((retVal = rtl8367c_getAsicPortBasedFid(rtk_switch_port_L2P_get(port), pFid))!=RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_UntagDscpPriorityEnable_set ++ * Description: ++ * Set Untag DSCP priority assign ++ * Input: ++ * enable - state of Untag DSCP priority assign ++ * Output: ++ * None ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_ENABLE - Invalid input parameters. ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_vlan_UntagDscpPriorityEnable_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_setAsicVlanUntagDscpPriorityEn((rtk_uint32)enable)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_UntagDscpPriorityEnable_get ++ * Description: ++ * Get Untag DSCP priority assign ++ * Input: ++ * None ++ * Output: ++ * pEnable - state of Untag DSCP priority assign ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NULL_POINTER - Null pointer ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_vlan_UntagDscpPriorityEnable_get(rtk_enable_t *pEnable) ++{ ++ rtk_api_ret_t retVal; ++ rtk_uint32 value; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pEnable) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicVlanUntagDscpPriorityEn(&value)) != RT_ERR_OK) ++ return retVal; ++ ++ *pEnable = (rtk_enable_t)value; ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_stp_mstpState_set ++ * Description: ++ * Configure spanning tree state per each port. ++ * Input: ++ * port - Port id ++ * msti - Multiple spanning tree instance. ++ * stp_state - Spanning tree state for msti ++ * 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_MSTI - Invalid msti parameter. ++ * RT_ERR_MSTP_STATE - Invalid STP state. ++ * Note: ++ * System supports per-port multiple spanning tree state for each msti. ++ * There are four states supported by ASIC. ++ * - STP_STATE_DISABLED ++ * - STP_STATE_BLOCKING ++ * - STP_STATE_LEARNING ++ * - STP_STATE_FORWARDING ++ */ ++rtk_api_ret_t rtk_stp_mstpState_set(rtk_stp_msti_id_t msti, rtk_port_t port, rtk_stp_state_t stp_state) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if (msti > RTK_MAX_NUM_OF_MSTI) ++ return RT_ERR_MSTI; ++ ++ if (stp_state >= STP_STATE_END) ++ return RT_ERR_MSTP_STATE; ++ ++ if ((retVal = rtl8367c_setAsicSpanningTreeStatus(rtk_switch_port_L2P_get(port), msti, stp_state)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_stp_mstpState_get ++ * Description: ++ * Get spanning tree state per each port. ++ * Input: ++ * port - Port id. ++ * msti - Multiple spanning tree instance. ++ * Output: ++ * pStp_state - Spanning tree state for msti ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_PORT_ID - Invalid port number. ++ * RT_ERR_MSTI - Invalid msti parameter. ++ * Note: ++ * System supports per-port multiple spanning tree state for each msti. ++ * There are four states supported by ASIC. ++ * - STP_STATE_DISABLED ++ * - STP_STATE_BLOCKING ++ * - STP_STATE_LEARNING ++ * - STP_STATE_FORWARDING ++ */ ++rtk_api_ret_t rtk_stp_mstpState_get(rtk_stp_msti_id_t msti, rtk_port_t port, rtk_stp_state_t *pStp_state) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* Check Port Valid */ ++ RTK_CHK_PORT_VALID(port); ++ ++ if (msti > RTK_MAX_NUM_OF_MSTI) ++ return RT_ERR_MSTI; ++ ++ if(NULL == pStp_state) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getAsicSpanningTreeStatus(rtk_switch_port_L2P_get(port), msti, pStp_state)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_checkAndCreateMbr ++ * Description: ++ * Check and create Member configuration and return index ++ * Input: ++ * vid - VLAN id. ++ * Output: ++ * pIndex - Member configuration index ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_VLAN_VID - Invalid VLAN ID. ++ * RT_ERR_VLAN_ENTRY_NOT_FOUND - VLAN not found ++ * RT_ERR_TBL_FULL - Member Configuration table full ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_vlan_checkAndCreateMbr(rtk_vlan_t vid, rtk_uint32 *pIndex) ++{ ++ rtk_api_ret_t retVal; ++ rtl8367c_user_vlan4kentry vlan4K; ++ rtl8367c_vlanconfiguser vlanMC; ++ rtk_uint32 idx; ++ rtk_uint32 empty_idx = 0xFFFF; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ /* vid must be 0~8191 */ ++ if (vid > RTL8367C_EVIDMAX) ++ return RT_ERR_VLAN_VID; ++ ++ /* Null pointer check */ ++ if(NULL == pIndex) ++ return RT_ERR_NULL_POINTER; ++ ++ /* Get 4K VLAN */ ++ if (vid <= RTL8367C_VIDMAX) ++ { ++ memset(&vlan4K, 0x00, sizeof(rtl8367c_user_vlan4kentry)); ++ vlan4K.vid = vid; ++ if ((retVal = rtl8367c_getAsicVlan4kEntry(&vlan4K)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ /* Search exist entry */ ++ for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) ++ { ++ if(vlan_mbrCfgUsage[idx] == MBRCFG_USED_BY_VLAN) ++ { ++ if(vlan_mbrCfgVid[idx] == vid) ++ { ++ /* Found! return index */ ++ *pIndex = idx; ++ return RT_ERR_OK; ++ } ++ } ++ } ++ ++ /* Not found, Read H/W Member Configuration table to update database */ ++ for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) ++ { ++ if ((retVal = rtl8367c_getAsicVlanMemberConfig(idx, &vlanMC)) != RT_ERR_OK) ++ return retVal; ++ ++ if( (vlanMC.evid == 0) && (vlanMC.mbr == 0x00)) ++ { ++ vlan_mbrCfgUsage[idx] = MBRCFG_UNUSED; ++ vlan_mbrCfgVid[idx] = 0; ++ } ++ else ++ { ++ vlan_mbrCfgUsage[idx] = MBRCFG_USED_BY_VLAN; ++ vlan_mbrCfgVid[idx] = vlanMC.evid; ++ } ++ } ++ ++ /* Search exist entry again */ ++ for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) ++ { ++ if(vlan_mbrCfgUsage[idx] == MBRCFG_USED_BY_VLAN) ++ { ++ if(vlan_mbrCfgVid[idx] == vid) ++ { ++ /* Found! return index */ ++ *pIndex = idx; ++ return RT_ERR_OK; ++ } ++ } ++ } ++ ++ /* try to look up an empty index */ ++ for (idx = 0; idx <= RTL8367C_CVIDXMAX; idx++) ++ { ++ if(vlan_mbrCfgUsage[idx] == MBRCFG_UNUSED) ++ { ++ empty_idx = idx; ++ break; ++ } ++ } ++ ++ if(empty_idx == 0xFFFF) ++ { ++ /* No empty index */ ++ return RT_ERR_TBL_FULL; ++ } ++ ++ if (vid > RTL8367C_VIDMAX) ++ { ++ /* > 4K, there is no 4K entry, create on member configuration directly */ ++ memset(&vlanMC, 0x00, sizeof(rtl8367c_vlanconfiguser)); ++ vlanMC.evid = vid; ++ if ((retVal = rtl8367c_setAsicVlanMemberConfig(empty_idx, &vlanMC)) != RT_ERR_OK) ++ return retVal; ++ } ++ else ++ { ++ /* Copy from 4K table */ ++ vlanMC.evid = vid; ++ vlanMC.mbr = vlan4K.mbr; ++ vlanMC.fid_msti = vlan4K.fid_msti; ++ vlanMC.meteridx= vlan4K.meteridx; ++ vlanMC.envlanpol= vlan4K.envlanpol; ++ vlanMC.vbpen = vlan4K.vbpen; ++ vlanMC.vbpri = vlan4K.vbpri; ++ if ((retVal = rtl8367c_setAsicVlanMemberConfig(empty_idx, &vlanMC)) != RT_ERR_OK) ++ return retVal; ++ } ++ ++ /* Update Database */ ++ vlan_mbrCfgUsage[empty_idx] = MBRCFG_USED_BY_VLAN; ++ vlan_mbrCfgVid[empty_idx] = vid; ++ ++ *pIndex = empty_idx; ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_reservedVidAction_set ++ * Description: ++ * Set Action of VLAN ID = 0 & 4095 tagged packet ++ * Input: ++ * action_vid0 - Action for VID 0. ++ * action_vid4095 - Action for VID 4095. ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Error Input ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_vlan_reservedVidAction_set(rtk_vlan_resVidAction_t action_vid0, rtk_vlan_resVidAction_t action_vid4095) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(action_vid0 >= RESVID_ACTION_END) ++ return RT_ERR_INPUT; ++ ++ if(action_vid4095 >= RESVID_ACTION_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setReservedVidAction((rtk_uint32)action_vid0, (rtk_uint32)action_vid4095)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_reservedVidAction_get ++ * Description: ++ * Get Action of VLAN ID = 0 & 4095 tagged packet ++ * Input: ++ * pAction_vid0 - Action for VID 0. ++ * pAction_vid4095 - Action for VID 4095. ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_NULL_POINTER - NULL Pointer ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_vlan_reservedVidAction_get(rtk_vlan_resVidAction_t *pAction_vid0, rtk_vlan_resVidAction_t *pAction_vid4095) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(pAction_vid0 == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ if(pAction_vid4095 == NULL) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getReservedVidAction((rtk_uint32 *)pAction_vid0, (rtk_uint32 *)pAction_vid4095)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_realKeepRemarkEnable_set ++ * Description: ++ * Set Real keep 1p remarking feature ++ * Input: ++ * enabled - State of 1p remarking at real keep packet ++ * Output: ++ * None. ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Error Input ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_vlan_realKeepRemarkEnable_set(rtk_enable_t enabled) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(enabled >= RTK_ENABLE_END) ++ return RT_ERR_INPUT; ++ ++ if ((retVal = rtl8367c_setRealKeepRemarkEn((rtk_uint32)enabled)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_realKeepRemarkEnable_get ++ * Description: ++ * Get Real keep 1p remarking feature ++ * Input: ++ * None. ++ * Output: ++ * pEnabled - State of 1p remarking at real keep packet ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Error Input ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_vlan_realKeepRemarkEnable_get(rtk_enable_t *pEnabled) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if(NULL == pEnabled) ++ return RT_ERR_NULL_POINTER; ++ ++ if ((retVal = rtl8367c_getRealKeepRemarkEn((rtk_uint32 *)pEnabled)) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ ++/* Function Name: ++ * rtk_vlan_reset ++ * Description: ++ * Reset VLAN ++ * Input: ++ * None. ++ * Output: ++ * pEnabled - State of 1p remarking at real keep packet ++ * Return: ++ * RT_ERR_OK - OK ++ * RT_ERR_FAILED - Failed ++ * RT_ERR_SMI - SMI access error ++ * RT_ERR_INPUT - Error Input ++ * Note: ++ * ++ */ ++rtk_api_ret_t rtk_vlan_reset(void) ++{ ++ rtk_api_ret_t retVal; ++ ++ /* Check initialization state */ ++ RTK_CHK_INIT_STATE(); ++ ++ if ((retVal = rtl8367c_resetVlan()) != RT_ERR_OK) ++ return retVal; ++ ++ return RT_ERR_OK; ++} ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367s.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367s.c +new file mode 100644 +index 0000000000..6a55631d52 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367s.c +@@ -0,0 +1,580 @@ ++/* ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++//include from rtl8367c dir ++#include "./rtl8367c/include/rtk_switch.h" ++#include "./rtl8367c/include/vlan.h" ++#include "./rtl8367c/include/stat.h" ++#include "./rtl8367c/include/port.h" ++ ++#define RTL8367C_SW_CPU_PORT 6 ++ ++ //RTL8367C_PHY_PORT_NUM + ext0 + ext1 ++#define RTL8367C_NUM_PORTS 7 ++#define RTL8367C_NUM_VIDS 4096 ++ ++struct rtl8367_priv { ++ struct switch_dev swdev; ++ bool global_vlan_enable; ++}; ++ ++struct rtl8367_mib_counter { ++ const char *name; ++}; ++ ++struct rtl8367_vlan_info { ++ unsigned short vid; ++ unsigned int untag; ++ unsigned int member; ++ unsigned char fid; ++}; ++ ++struct rtl8367_priv rtl8367_priv_data; ++ ++unsigned int rtl8367c_port_id[RTL8367C_NUM_PORTS]={0,1,2,3,4,EXT_PORT1,EXT_PORT0}; ++ ++void (*rtl8367_switch_reset_func)(void)=NULL; ++ ++static struct rtl8367_mib_counter rtl8367c_mib_counters[] = { ++ {"ifInOctets"}, ++ {"dot3StatsFCSErrors"}, ++ {"dot3StatsSymbolErrors"}, ++ {"dot3InPauseFrames"}, ++ {"dot3ControlInUnknownOpcodes"}, ++ {"etherStatsFragments"}, ++ {"etherStatsJabbers"}, ++ {"ifInUcastPkts"}, ++ {"etherStatsDropEvents"}, ++ {"etherStatsOctets"}, ++ {"etherStatsUndersizePkts"}, ++ {"etherStatsOversizePkts"}, ++ {"etherStatsPkts64Octets"}, ++ {"etherStatsPkts65to127Octets"}, ++ {"etherStatsPkts128to255Octets"}, ++ {"etherStatsPkts256to511Octets"}, ++ {"etherStatsPkts512to1023Octets"}, ++ {"etherStatsPkts1024toMaxOctets"}, ++ {"etherStatsMcastPkts"}, ++ {"etherStatsBcastPkts"}, ++ {"ifOutOctets"}, ++ {"dot3StatsSingleCollisionFrames"}, ++ {"dot3StatsMultipleCollisionFrames"}, ++ {"dot3StatsDeferredTransmissions"}, ++ {"dot3StatsLateCollisions"}, ++ {"etherStatsCollisions"}, ++ {"dot3StatsExcessiveCollisions"}, ++ {"dot3OutPauseFrames"}, ++ {"dot1dBasePortDelayExceededDiscards"}, ++ {"dot1dTpPortInDiscards"}, ++ {"ifOutUcastPkts"}, ++ {"ifOutMulticastPkts"}, ++ {"ifOutBrocastPkts"}, ++ {"outOampduPkts"}, ++ {"inOampduPkts"}, ++ {"pktgenPkts"}, ++ {"inMldChecksumError"}, ++ {"inIgmpChecksumError"}, ++ {"inMldSpecificQuery"}, ++ {"inMldGeneralQuery"}, ++ {"inIgmpSpecificQuery"}, ++ {"inIgmpGeneralQuery"}, ++ {"inMldLeaves"}, ++ {"inIgmpLeaves"}, ++ {"inIgmpJoinsSuccess"}, ++ {"inIgmpJoinsFail"}, ++ {"inMldJoinsSuccess"}, ++ {"inMldJoinsFail"}, ++ {"inReportSuppressionDrop"}, ++ {"inLeaveSuppressionDrop"}, ++ {"outIgmpReports"}, ++ {"outIgmpLeaves"}, ++ {"outIgmpGeneralQuery"}, ++ {"outIgmpSpecificQuery"}, ++ {"outMldReports"}, ++ {"outMldLeaves"}, ++ {"outMldGeneralQuery"}, ++ {"outMldSpecificQuery"}, ++ {"inKnownMulticastPkts"}, ++ {"ifInMulticastPkts"}, ++ {"ifInBroadcastPkts"}, ++ {"ifOutDiscards"} ++}; ++ ++/*rtl8367c proprietary switch API wrapper */ ++static inline unsigned int rtl8367c_sw_to_phy_port(int port) ++{ ++ return rtl8367c_port_id[port]; ++} ++ ++static inline unsigned int rtl8367c_portmask_phy_to_sw(rtk_portmask_t phy_portmask) ++{ ++ int i; ++ for (i = 0; i < RTL8367C_NUM_PORTS; i++) { ++ if(RTK_PORTMASK_IS_PORT_SET(phy_portmask,rtl8367c_sw_to_phy_port(i))) { ++ RTK_PORTMASK_PORT_CLEAR(phy_portmask,rtl8367c_sw_to_phy_port(i)); ++ RTK_PORTMASK_PORT_SET(phy_portmask,i); ++ } ++ ++ } ++ return (unsigned int)phy_portmask.bits[0]; ++} ++ ++static int rtl8367c_reset_mibs(void) ++{ ++ return rtk_stat_global_reset(); ++} ++ ++static int rtl8367c_reset_port_mibs(int port) ++{ ++ ++ return rtk_stat_port_reset(rtl8367c_sw_to_phy_port(port)); ++} ++ ++static int rtl8367c_get_mibs_num(void) ++{ ++ return ARRAY_SIZE(rtl8367c_mib_counters); ++} ++ ++static const char *rtl8367c_get_mib_name(int idx) ++{ ++ ++ return rtl8367c_mib_counters[idx].name; ++} ++ ++static int rtl8367c_get_port_mib_counter(int idx, int port, unsigned long long *counter) ++{ ++ return rtk_stat_port_get(rtl8367c_sw_to_phy_port(port), idx, counter); ++} ++ ++static int rtl8367c_is_vlan_valid(unsigned int vlan) ++{ ++ unsigned max = RTL8367C_NUM_VIDS; ++ ++ if (vlan == 0 || vlan >= max) ++ return 0; ++ ++ return 1; ++} ++ ++static int rtl8367c_get_vlan( unsigned short vid, struct rtl8367_vlan_info *vlan) ++{ ++ rtk_vlan_cfg_t vlan_cfg; ++ ++ memset(vlan, '\0', sizeof(struct rtl8367_vlan_info)); ++ ++ if (vid >= RTL8367C_NUM_VIDS) ++ return -EINVAL; ++ ++ if(rtk_vlan_get(vid,&vlan_cfg)) ++ return -EINVAL; ++ ++ vlan->vid = vid; ++ vlan->member = rtl8367c_portmask_phy_to_sw(vlan_cfg.mbr); ++ vlan->untag = rtl8367c_portmask_phy_to_sw(vlan_cfg.untag); ++ vlan->fid = vlan_cfg.fid_msti; ++ ++ return 0; ++} ++ ++static int rtl8367c_set_vlan( unsigned short vid, u32 mbr, u32 untag, u8 fid) ++{ ++ rtk_vlan_cfg_t vlan_cfg; ++ int i; ++ ++ memset(&vlan_cfg, 0x00, sizeof(rtk_vlan_cfg_t)); ++ ++ for (i = 0; i < RTL8367C_NUM_PORTS; i++) { ++ if (mbr & (1 << i)) { ++ RTK_PORTMASK_PORT_SET(vlan_cfg.mbr, rtl8367c_sw_to_phy_port(i)); ++ if(untag & (1 << i)) ++ RTK_PORTMASK_PORT_SET(vlan_cfg.untag, rtl8367c_sw_to_phy_port(i)); ++ } ++ } ++ vlan_cfg.fid_msti=fid; ++ vlan_cfg.ivl_en = 1; ++ return rtk_vlan_set(vid, &vlan_cfg); ++} ++ ++ ++static int rtl8367c_get_pvid( int port, int *pvid) ++{ ++ u32 prio=0; ++ ++ if (port >= RTL8367C_NUM_PORTS) ++ return -EINVAL; ++ ++ return rtk_vlan_portPvid_get(rtl8367c_sw_to_phy_port(port),pvid,&prio); ++} ++ ++ ++static int rtl8367c_set_pvid( int port, int pvid) ++{ ++ u32 prio=0; ++ ++ if (port >= RTL8367C_NUM_PORTS) ++ return -EINVAL; ++ ++ return rtk_vlan_portPvid_set(rtl8367c_sw_to_phy_port(port),pvid,prio); ++} ++ ++static int rtl8367c_get_port_link(int port, int *link, int *speed, int *duplex) ++{ ++ ++ if(rtk_port_phyStatus_get(rtl8367c_sw_to_phy_port(port),(rtk_port_linkStatus_t *)link, ++ (rtk_port_speed_t *)speed,(rtk_port_duplex_t *)duplex)) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++/*common rtl8367 swconfig entry API*/ ++ ++static int ++rtl8367_sw_set_vlan_enable(struct switch_dev *dev, ++ const struct switch_attr *attr, ++ struct switch_val *val) ++{ ++ struct rtl8367_priv *priv = container_of(dev, struct rtl8367_priv, swdev); ++ ++ priv->global_vlan_enable = val->value.i ; ++ ++ return 0; ++} ++ ++static int ++rtl8367_sw_get_vlan_enable(struct switch_dev *dev, ++ const struct switch_attr *attr, ++ struct switch_val *val) ++{ ++ struct rtl8367_priv *priv = container_of(dev, struct rtl8367_priv, swdev); ++ ++ val->value.i = priv->global_vlan_enable; ++ ++ return 0; ++} ++ ++static int rtl8367_sw_reset_mibs(struct switch_dev *dev, ++ const struct switch_attr *attr, ++ struct switch_val *val) ++{ ++ return rtl8367c_reset_mibs(); ++} ++ ++ ++static int rtl8367_sw_reset_port_mibs(struct switch_dev *dev, ++ const struct switch_attr *attr, ++ struct switch_val *val) ++{ ++ int port; ++ ++ port = val->port_vlan; ++ if (port >= RTL8367C_NUM_PORTS) ++ return -EINVAL; ++ ++ return rtl8367c_reset_port_mibs(port); ++} ++ ++static int rtl8367_sw_get_port_mib(struct switch_dev *dev, ++ const struct switch_attr *attr, ++ struct switch_val *val) ++{ ++ int i, len = 0; ++ unsigned long long counter = 0; ++ static char mib_buf[4096]; ++ ++ if (val->port_vlan >= RTL8367C_NUM_PORTS) ++ return -EINVAL; ++ ++ len += snprintf(mib_buf + len, sizeof(mib_buf) - len, ++ "Port %d MIB counters\n", ++ val->port_vlan); ++ ++ for (i = 0; i port_vlan, ++ &counter)) ++ len += snprintf(mib_buf + len, sizeof(mib_buf) - len, ++ "%llu\n", counter); ++ else ++ len += snprintf(mib_buf + len, sizeof(mib_buf) - len, ++ "%s\n", "N/A"); ++ } ++ ++ val->value.s = mib_buf; ++ val->len = len; ++ return 0; ++} ++ ++ ++static int rtl8367_sw_get_vlan_info(struct switch_dev *dev, ++ const struct switch_attr *attr, ++ struct switch_val *val) ++{ ++ int i; ++ u32 len = 0; ++ struct rtl8367_vlan_info vlan; ++ static char vlan_buf[256]; ++ int err; ++ ++ if (!rtl8367c_is_vlan_valid(val->port_vlan)) ++ return -EINVAL; ++ ++ memset(vlan_buf, '\0', sizeof(vlan_buf)); ++ ++ err = rtl8367c_get_vlan(val->port_vlan, &vlan); ++ if (err) ++ return err; ++ ++ len += snprintf(vlan_buf + len, sizeof(vlan_buf) - len, ++ "VLAN %d: Ports: '", vlan.vid); ++ ++ for (i = 0; i value.s = vlan_buf; ++ val->len = len; ++ ++ return 0; ++} ++ ++ ++static int rtl8367_sw_get_vlan_ports(struct switch_dev *dev, struct switch_val *val) ++{ ++ struct switch_port *port; ++ struct rtl8367_vlan_info vlan; ++ int i; ++ ++ if (!rtl8367c_is_vlan_valid(val->port_vlan)) ++ return -EINVAL; ++ ++ if(rtl8367c_get_vlan(val->port_vlan, &vlan)) ++ return -EINVAL; ++ ++ port = &val->value.ports[0]; ++ val->len = 0; ++ for (i = 0; i id = i; ++ port->flags = (vlan.untag & BIT(i)) ? ++ 0 : BIT(SWITCH_PORT_FLAG_TAGGED); ++ val->len++; ++ port++; ++ } ++ return 0; ++} ++ ++ ++static int rtl8367_sw_set_vlan_ports(struct switch_dev *dev, struct switch_val *val) ++{ ++ struct switch_port *port; ++ u32 member = 0; ++ u32 untag = 0; ++ u8 fid=0; ++ int err; ++ int i; ++ ++ if (!rtl8367c_is_vlan_valid(val->port_vlan)) ++ return -EINVAL; ++ ++ port = &val->value.ports[0]; ++ for (i = 0; i < val->len; i++, port++) { ++ int pvid = 0; ++ member |= BIT(port->id); ++ ++ if (!(port->flags & BIT(SWITCH_PORT_FLAG_TAGGED))) ++ untag |= BIT(port->id); ++ ++ /* ++ * To ensure that we have a valid MC entry for this VLAN, ++ * initialize the port VLAN ID here. ++ */ ++ err = rtl8367c_get_pvid(port->id, &pvid); ++ if (err < 0) ++ return err; ++ if (pvid == 0) { ++ err = rtl8367c_set_pvid(port->id, val->port_vlan); ++ if (err < 0) ++ return err; ++ } ++ } ++ ++ //pr_info("[%s] vid=%d , mem=%x,untag=%x,fid=%d \n",__func__,val->port_vlan,member,untag,fid); ++ ++ return rtl8367c_set_vlan(val->port_vlan, member, untag, fid); ++ ++} ++ ++ ++static int rtl8367_sw_get_port_pvid(struct switch_dev *dev, int port, int *val) ++{ ++ return rtl8367c_get_pvid(port, val); ++} ++ ++ ++static int rtl8367_sw_set_port_pvid(struct switch_dev *dev, int port, int val) ++{ ++ return rtl8367c_set_pvid(port, val); ++} ++ ++ ++static int rtl8367_sw_reset_switch(struct switch_dev *dev) ++{ ++ if(rtl8367_switch_reset_func) ++ (*rtl8367_switch_reset_func)(); ++ else ++ printk("rest switch is not supported\n"); ++ ++ return 0; ++} ++ ++static int rtl8367_sw_get_port_link(struct switch_dev *dev, int port, ++ struct switch_port_link *link) ++{ ++ int speed; ++ ++ if (port >= RTL8367C_NUM_PORTS) ++ return -EINVAL; ++ ++ if(rtl8367c_get_port_link(port,(int *)&link->link,(int *)&speed,(int *)&link->duplex)) ++ return -EINVAL; ++ ++ if (!link->link) ++ return 0; ++ ++ switch (speed) { ++ case 0: ++ link->speed = SWITCH_PORT_SPEED_10; ++ break; ++ case 1: ++ link->speed = SWITCH_PORT_SPEED_100; ++ break; ++ case 2: ++ link->speed = SWITCH_PORT_SPEED_1000; ++ break; ++ default: ++ link->speed = SWITCH_PORT_SPEED_UNKNOWN; ++ break; ++ } ++ ++ return 0; ++} ++ ++ ++static struct switch_attr rtl8367_globals[] = { ++ { ++ .type = SWITCH_TYPE_INT, ++ .name = "enable_vlan", ++ .description = "Enable VLAN mode", ++ .set = rtl8367_sw_set_vlan_enable, ++ .get = rtl8367_sw_get_vlan_enable, ++ .max = 1, ++ }, { ++ .type = SWITCH_TYPE_NOVAL, ++ .name = "reset_mibs", ++ .description = "Reset all MIB counters", ++ .set = rtl8367_sw_reset_mibs, ++ } ++}; ++ ++static struct switch_attr rtl8367_port[] = { ++ { ++ .type = SWITCH_TYPE_NOVAL, ++ .name = "reset_mib", ++ .description = "Reset single port MIB counters", ++ .set = rtl8367_sw_reset_port_mibs, ++ }, { ++ .type = SWITCH_TYPE_STRING, ++ .name = "mib", ++ .description = "Get MIB counters for port", ++ //.max = 33, ++ .set = NULL, ++ .get = rtl8367_sw_get_port_mib, ++ }, ++}; ++ ++static struct switch_attr rtl8367_vlan[] = { ++ { ++ .type = SWITCH_TYPE_STRING, ++ .name = "info", ++ .description = "Get vlan information", ++ .max = 1, ++ .set = NULL, ++ .get = rtl8367_sw_get_vlan_info, ++ }, ++}; ++ ++static const struct switch_dev_ops rtl8367_sw_ops = { ++ .attr_global = { ++ .attr = rtl8367_globals, ++ .n_attr = ARRAY_SIZE(rtl8367_globals), ++ }, ++ .attr_port = { ++ .attr = rtl8367_port, ++ .n_attr = ARRAY_SIZE(rtl8367_port), ++ }, ++ .attr_vlan = { ++ .attr = rtl8367_vlan, ++ .n_attr = ARRAY_SIZE(rtl8367_vlan), ++ }, ++ ++ .get_vlan_ports = rtl8367_sw_get_vlan_ports, ++ .set_vlan_ports = rtl8367_sw_set_vlan_ports, ++ .get_port_pvid = rtl8367_sw_get_port_pvid, ++ .set_port_pvid = rtl8367_sw_set_port_pvid, ++ .reset_switch = rtl8367_sw_reset_switch, ++ .get_port_link = rtl8367_sw_get_port_link, ++}; ++ ++int rtl8367s_swconfig_init(void (*reset_func)(void)) ++{ ++ struct rtl8367_priv *priv = &rtl8367_priv_data; ++ struct switch_dev *dev=&priv->swdev; ++ int err=0; ++ ++ rtl8367_switch_reset_func = reset_func ; ++ ++ memset(priv, 0, sizeof(struct rtl8367_priv)); ++ priv->global_vlan_enable =0; ++ ++ dev->name = "RTL8367C"; ++ dev->cpu_port = RTL8367C_SW_CPU_PORT; ++ dev->ports = RTL8367C_NUM_PORTS; ++ dev->vlans = RTL8367C_NUM_VIDS; ++ dev->ops = &rtl8367_sw_ops; ++ dev->alias = "RTL8367C"; ++ err = register_switch(dev, NULL); ++ ++ pr_info("[%s]\n",__func__); ++ ++ return err; ++} +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367s_dbg.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367s_dbg.c +new file mode 100644 +index 0000000000..039d73d876 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367s_dbg.c +@@ -0,0 +1,648 @@ ++#include ++#include ++#include ++#include ++#include ++ ++#include "./rtl8367c/include/rtk_switch.h" ++#include "./rtl8367c/include/port.h" ++#include "./rtl8367c/include/vlan.h" ++#include "./rtl8367c/include/rtl8367c_asicdrv_port.h" ++#include "./rtl8367c/include/stat.h" ++#include "./rtl8367c/include/l2.h" ++#include "./rtl8367c/include/smi.h" ++#include "./rtl8367c/include/mirror.h" ++#include "./rtl8367c/include/igmp.h" ++#include "./rtl8367c/include/leaky.h" ++ ++static struct proc_dir_entry *proc_reg_dir; ++static struct proc_dir_entry *proc_esw_cnt; ++static struct proc_dir_entry *proc_vlan_cnt; ++static struct proc_dir_entry *proc_mac_tbl; ++static struct proc_dir_entry *proc_reg; ++static struct proc_dir_entry *proc_phyreg; ++static struct proc_dir_entry *proc_mirror; ++static struct proc_dir_entry *proc_igmp; ++ ++#define PROCREG_ESW_CNT "esw_cnt" ++#define PROCREG_VLAN "vlan" ++#define PROCREG_MAC_TBL "mac_tbl" ++#define PROCREG_REG "reg" ++#define PROCREG_PHYREG "phyreg" ++#define PROCREG_MIRROR "mirror" ++#define PROCREG_IGMP "igmp" ++#define PROCREG_DIR "rtk_gsw" ++ ++#define RTK_SW_VID_RANGE 16 ++ ++static void rtk_dump_mib_type(rtk_stat_port_type_t cntr_idx) ++{ ++ rtk_port_t port; ++ rtk_stat_counter_t Cntr; ++ ++ for (port = UTP_PORT0; port < (UTP_PORT0 + 5); port++) { ++ rtk_stat_port_get(port, cntr_idx, &Cntr); ++ printk("%8llu", Cntr); ++ } ++ ++ for (port = EXT_PORT0; port < (EXT_PORT0 + 2); port++) { ++ rtk_stat_port_get(port, cntr_idx, &Cntr); ++ printk("%8llu", Cntr); ++ } ++ ++ printk("\n"); ++} ++static void rtk_hal_dump_mib(void) ++{ ++ ++ printk("==================%8s%8s%8s%8s%8s%8s%8s\n", "Port0", "Port1", ++ "Port2", "Port3", "Port4", "Port16", "Port17"); ++ /* Get TX Unicast Pkts */ ++ printk("TX Unicast Pkts :"); ++ rtk_dump_mib_type(STAT_IfOutUcastPkts); ++ /* Get TX Multicast Pkts */ ++ printk("TX Multicast Pkts:"); ++ rtk_dump_mib_type(STAT_IfOutMulticastPkts); ++ /* Get TX BroadCast Pkts */ ++ printk("TX BroadCast Pkts:"); ++ rtk_dump_mib_type(STAT_IfOutBroadcastPkts); ++ /* Get TX Collisions */ ++ /* Get TX Puase Frames */ ++ printk("TX Pause Frames :"); ++ rtk_dump_mib_type(STAT_Dot3OutPauseFrames); ++ /* Get TX Drop Events */ ++ /* Get RX Unicast Pkts */ ++ printk("RX Unicast Pkts :"); ++ rtk_dump_mib_type(STAT_IfInUcastPkts); ++ /* Get RX Multicast Pkts */ ++ printk("RX Multicast Pkts:"); ++ rtk_dump_mib_type(STAT_IfInMulticastPkts); ++ /* Get RX Broadcast Pkts */ ++ printk("RX Broadcast Pkts:"); ++ rtk_dump_mib_type(STAT_IfInBroadcastPkts); ++ /* Get RX FCS Erros */ ++ printk("RX FCS Errors :"); ++ rtk_dump_mib_type(STAT_Dot3StatsFCSErrors); ++ /* Get RX Undersize Pkts */ ++ printk("RX Undersize Pkts:"); ++ rtk_dump_mib_type(STAT_EtherStatsUnderSizePkts); ++ /* Get RX Discard Pkts */ ++ printk("RX Discard Pkts :"); ++ rtk_dump_mib_type(STAT_Dot1dTpPortInDiscards); ++ /* Get RX Fragments */ ++ printk("RX Fragments :"); ++ rtk_dump_mib_type(STAT_EtherStatsFragments); ++ /* Get RX Oversize Pkts */ ++ printk("RX Oversize Pkts :"); ++ rtk_dump_mib_type(STAT_EtherOversizeStats); ++ /* Get RX Jabbers */ ++ printk("RX Jabbers :"); ++ rtk_dump_mib_type(STAT_EtherStatsJabbers); ++ /* Get RX Pause Frames */ ++ printk("RX Pause Frames :"); ++ rtk_dump_mib_type(STAT_Dot3InPauseFrames); ++ /* clear MIB */ ++ rtk_stat_global_reset(); ++ ++} ++ ++static int rtk_hal_dump_vlan(void) ++{ ++ rtk_vlan_cfg_t vlan; ++ int i; ++ ++ printk("vid portmap\n"); ++ for (i = 0; i < RTK_SW_VID_RANGE; i++) { ++ rtk_vlan_get(i, &vlan); ++ printk("%3d ", i); ++ printk("%c", ++ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, ++ UTP_PORT0) ? '1' : '-'); ++ printk("%c", ++ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, ++ UTP_PORT1) ? '1' : '-'); ++ printk("%c", ++ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, ++ UTP_PORT2) ? '1' : '-'); ++ printk("%c", ++ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, ++ UTP_PORT3) ? '1' : '-'); ++ printk("%c", ++ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, ++ UTP_PORT4) ? '1' : '-'); ++ printk("%c", ++ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, ++ EXT_PORT0) ? '1' : '-'); ++ printk("%c", ++ RTK_PORTMASK_IS_PORT_SET(vlan.mbr, ++ EXT_PORT1) ? '1' : '-'); ++ printk("\n"); ++ } ++ ++ return 0; ++} ++ ++static void rtk_hal_dump_table(void) ++{ ++ rtk_uint32 i; ++ rtk_uint32 address = 0; ++ rtk_l2_ucastAddr_t l2_data; ++ rtk_l2_ipMcastAddr_t ipMcastAddr; ++ rtk_l2_age_time_t age_timout; ++ ++ rtk_l2_aging_get(&age_timout); ++ printk("Mac table age timeout =%d\n",(unsigned int)age_timout); ++ ++ printk("hash port(0:17) fid vid mac-address\n"); ++ while (1) { ++ if (rtk_l2_addr_next_get(READMETHOD_NEXT_L2UC, UTP_PORT0, &address, &l2_data) != RT_ERR_OK) { ++ break; ++ } else { ++ printk("%03x ", l2_data.address); ++ for (i = 0; i < 5; i++) ++ if ( l2_data.port == i) ++ printk("1"); ++ else ++ printk("-"); ++ for (i = 16; i < 18; i++) ++ if ( l2_data.port == i) ++ printk("1"); ++ else ++ printk("-"); ++ ++ printk(" %2d", l2_data.fid); ++ printk(" %4d", l2_data.cvid); ++ printk(" %02x%02x%02x%02x%02x%02x\n", l2_data.mac.octet[0], ++ l2_data.mac.octet[1], l2_data.mac.octet[2], l2_data.mac.octet[3], ++ l2_data.mac.octet[4], l2_data.mac.octet[5]); ++ address ++; ++ } ++ } ++ ++ address = 0; ++ while (1) { ++ if (rtk_l2_ipMcastAddr_next_get(&address, &ipMcastAddr) != RT_ERR_OK) { ++ break; ++ } else { ++ printk("%03x ", ipMcastAddr.address); ++ for (i = 0; i < 5; i++) ++ printk("%c", RTK_PORTMASK_IS_PORT_SET(ipMcastAddr.portmask, i) ? '1' : '-'); ++ for (i = 16; i < 18; i++) ++ printk("%c", RTK_PORTMASK_IS_PORT_SET(ipMcastAddr.portmask, i) ? '1' : '-'); ++ printk(" "); ++ printk("01005E%06x\n", (ipMcastAddr.dip & 0xefffff)); ++ address ++; ++ } ++ } ++} ++ ++static void rtk_hal_clear_table(void) ++{ ++ rtk_api_ret_t ret; ++ ++ ret = rtk_l2_table_clear(); ++ if (ret != RT_ERR_OK) ++ printk("rtk_l2_table_clear failed\n"); ++} ++ ++static void rtk_hal_read_reg(unsigned int reg_addr) ++{ ++ ret_t retVal; ++ unsigned int reg_val; ++ ++ retVal = smi_read(reg_addr, ®_val); ++ ++ if(retVal != RT_ERR_OK) ++ printk("switch reg read failed\n"); ++ else ++ printk("reg0x%x = 0x%x\n", reg_addr, reg_val); ++} ++ ++static void rtk_hal_write_reg(unsigned int reg_addr , unsigned int reg_val) ++{ ++ ret_t retVal; ++ ++ retVal = smi_write(reg_addr, reg_val); ++ ++ if(retVal != RT_ERR_OK) ++ printk("switch reg write failed\n"); ++ else ++ printk("write switch reg0x%x 0x%x success\n", reg_addr, reg_val); ++} ++ ++static void rtk_hal_get_phy_reg(unsigned int port ,unsigned int reg_addr ) ++{ ++ ret_t retVal; ++ rtk_port_phy_data_t Data; ++ ++ retVal = rtk_port_phyReg_get(port, reg_addr, &Data); ++ if (retVal == RT_ERR_OK) ++ printk("Get: phy[%d].reg[%d] = 0x%04x\n", port, reg_addr, Data); ++ else ++ printk("read phy reg failed\n"); ++} ++ ++static void rtk_hal_set_phy_reg(unsigned int port ,unsigned int reg_addr,unsigned int reg_val) ++{ ++ ret_t retVal; ++ ++ retVal = rtk_port_phyReg_set(port, reg_addr, reg_val); ++ if (retVal == RT_ERR_OK) ++ printk("Set: phy[%d].reg[%d] = 0x%04x\n", port, reg_addr, reg_val); ++ else ++ printk("write phy reg failed\n"); ++} ++ ++static void rtk_hal_set_port_mirror(unsigned int port ,unsigned int rx_port_map,unsigned int tx_port_map) ++{ ++ rtk_portmask_t rx_portmask; ++ rtk_portmask_t tx_portmask; ++ rtk_api_ret_t ret; ++ int i; ++ ++ rtk_mirror_portIso_set(ENABLED); ++ RTK_PORTMASK_CLEAR(rx_portmask); ++ RTK_PORTMASK_CLEAR(tx_portmask); ++ ++ for (i = 0; i < 5; i++) ++ if (rx_port_map & (1 << i)) ++ RTK_PORTMASK_PORT_SET(rx_portmask, i); ++ ++ for (i = 0; i < 2; i++) ++ if (rx_port_map & (1 << (i + 5))) ++ RTK_PORTMASK_PORT_SET(rx_portmask, (i + EXT_PORT0)); ++ ++ RTK_PORTMASK_CLEAR(tx_portmask); ++ ++ for (i = 0; i < 5; i++) ++ if (tx_port_map & (1 << i)) ++ RTK_PORTMASK_PORT_SET(tx_portmask, i); ++ ++ for (i = 0; i < 2; i++) ++ if (tx_port_map & (1 << (i + 5))) ++ RTK_PORTMASK_PORT_SET(tx_portmask, (i + EXT_PORT0)); ++ ++ ret = rtk_mirror_portBased_set(port, &rx_portmask, &tx_portmask); ++ ++ if (!ret) ++ printk("rtk_mirror_portBased_set success\n"); ++ ++} ++ ++static void rtk_hal_enable_igmpsnoop(int hw_on) ++{ ++ rtk_api_ret_t ret; ++ rtk_portmask_t pmask; ++ ++ ret = rtk_igmp_init(); ++ if (hw_on == 1) { ++ RTK_PORTMASK_CLEAR(pmask); ++ RTK_PORTMASK_PORT_SET(pmask, EXT_PORT0); ++ ret |= rtk_igmp_static_router_port_set(&pmask); ++ ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_IGMPv1, IGMP_ACTION_FORWARD); ++ ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_IGMPv2, IGMP_ACTION_FORWARD); ++ ret |= rtk_igmp_protocol_set(UTP_PORT4, PROTOCOL_MLDv1, IGMP_ACTION_FORWARD); ++ ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_IGMPv1, IGMP_ACTION_FORWARD); ++ ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_IGMPv2, IGMP_ACTION_FORWARD); ++ ret |= rtk_igmp_protocol_set(EXT_PORT1, PROTOCOL_MLDv1, IGMP_ACTION_FORWARD); ++ ret |= rtk_igmp_protocol_set(UTP_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); ++ ret |= rtk_igmp_protocol_set(UTP_PORT1, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); ++ ret |= rtk_igmp_protocol_set(UTP_PORT2, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); ++ ret |= rtk_igmp_protocol_set(UTP_PORT3, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); ++ ret |= rtk_igmp_protocol_set(EXT_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); ++ ++ ret |= rtk_leaky_vlan_set(LEAKY_IPMULTICAST, ENABLED); ++ ret |= rtk_l2_ipMcastForwardRouterPort_set(DISABLED); ++ /* drop unknown multicast packets*/ ++ /* ret |= rtk_trap_unknownMcastPktAction_set(UTP_PORT4, MCAST_IPV4, MCAST_ACTION_DROP);*/ ++ } else { ++ RTK_PORTMASK_CLEAR(pmask); ++ RTK_PORTMASK_PORT_SET(pmask, EXT_PORT0); ++ RTK_PORTMASK_PORT_SET(pmask, EXT_PORT1); ++ ret |= rtk_igmp_protocol_set(UTP_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); ++ ret |= rtk_igmp_protocol_set(UTP_PORT1, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); ++ ret |= rtk_igmp_protocol_set(UTP_PORT2, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); ++ ret |= rtk_igmp_protocol_set(UTP_PORT3, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); ++ ret |= rtk_igmp_protocol_set(EXT_PORT0, PROTOCOL_IGMPv3, IGMP_ACTION_ASIC); ++ ++ ret |= rtk_igmp_static_router_port_set(&pmask); ++ } ++ ++ if(ret != RT_ERR_OK) ++ printk("enable switch igmpsnoop failed\n"); ++ ++} ++ ++static void rtk_hal_disable_igmpsnoop(void) ++{ ++ if (rtk_igmp_state_set(DISABLED) != RT_ERR_OK) ++ printk("Disable IGMP SNOOPING failed\n"); ++} ++ ++static ssize_t mac_tbl_write(struct file *file, ++ const char __user *buffer, size_t count, ++ loff_t *data) ++{ ++ rtk_hal_clear_table(); ++ ++ return count; ++} ++ ++ ++static ssize_t phyreg_ops(struct file *file, ++ const char __user *buffer, size_t count, ++ loff_t *data) ++{ ++ char buf[64]; ++ unsigned int port; ++ unsigned int offset; ++ unsigned int val; ++ ++ memset(buf, 0, 64); ++ ++ if (copy_from_user(buf, buffer, count)) ++ return -EFAULT; ++ ++ ++ if(buf[0] == 'w') { ++ ++ if(sscanf(buf, "w %d %x %x", &port,&offset,&val) == -1) ++ return -EFAULT; ++ else ++ rtk_hal_set_phy_reg(port,offset,val); ++ ++ } else { ++ ++ if(sscanf(buf, "r %d %x",&port, &offset) == -1) ++ return -EFAULT; ++ else ++ rtk_hal_get_phy_reg(port,offset); ++ } ++ ++ return count; ++} ++ ++static ssize_t reg_ops(struct file *file, ++ const char __user *buffer, size_t count, ++ loff_t *data) ++{ ++ char buf[64]; ++ unsigned int offset; ++ unsigned int val; ++ ++ memset(buf, 0, 64); ++ ++ if (copy_from_user(buf, buffer, count)) ++ return -EFAULT; ++ ++ ++ if(buf[0] == 'w') { ++ ++ if(sscanf(buf, "w %x %x", &offset,&val) == -1) ++ return -EFAULT; ++ else ++ rtk_hal_write_reg(offset,val); ++ ++ } else { ++ ++ if(sscanf(buf, "r %x", &offset) == -1) ++ return -EFAULT; ++ else ++ rtk_hal_read_reg(offset); ++ } ++ ++ return count; ++} ++ ++static ssize_t mirror_ops(struct file *file, ++ const char __user *buffer, size_t count, ++ loff_t *data) ++{ ++ char buf[64]; ++ unsigned int port; ++ unsigned int tx_map,rx_map; ++ ++ memset(buf, 0, 64); ++ ++ if (copy_from_user(buf, buffer, count)) ++ return -EFAULT; ++ ++ if(sscanf(buf, "%d %x %x", &port,&rx_map,&tx_map) == -1) ++ return -EFAULT; ++ else ++ rtk_hal_set_port_mirror(port,rx_map,tx_map); ++ ++ return count; ++} ++ ++ ++static ssize_t igmp_ops(struct file *file, ++ const char __user *buffer, size_t count, ++ loff_t *data) ++{ ++ char buf[8]; ++ unsigned int ops; ++ ++ if (copy_from_user(buf, buffer, count)) ++ return -EFAULT; ++ ++ if(sscanf(buf, "%d", &ops) == -1) ++ return -EFAULT; ++ ++ if(ops == 0) ++ rtk_hal_disable_igmpsnoop(); ++ else if (ops == 1) ++ rtk_hal_enable_igmpsnoop(0); ++ else //hw igmp ++ rtk_hal_enable_igmpsnoop(1); ++ ++ return count; ++} ++ ++ ++static int esw_cnt_read(struct seq_file *seq, void *v) ++{ ++ rtk_hal_dump_mib(); ++ return 0; ++} ++ ++static int vlan_read(struct seq_file *seq, void *v) ++{ ++ rtk_hal_dump_vlan(); ++ return 0; ++} ++ ++static int mac_tbl_read(struct seq_file *seq, void *v) ++{ ++ rtk_hal_dump_table(); ++ return 0; ++} ++ ++static int reg_show(struct seq_file *seq, void *v) ++{ ++ return 0; ++} ++ ++static int phyreg_show(struct seq_file *seq, void *v) ++{ ++ return 0; ++} ++ ++static int mirror_show(struct seq_file *seq, void *v) ++{ ++ return 0; ++} ++ ++static int igmp_show(struct seq_file *seq, void *v) ++{ ++ return 0; ++} ++ ++static int switch_count_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, esw_cnt_read, 0); ++} ++ ++static int switch_vlan_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, vlan_read, 0); ++} ++ ++static int mac_tbl_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, mac_tbl_read, 0); ++} ++ ++static int reg_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, reg_show, 0); ++} ++ ++static int phyreg_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, phyreg_show, 0); ++} ++ ++static int mirror_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, mirror_show, 0); ++} ++ ++static int igmp_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, igmp_show, 0); ++} ++ ++ ++static const struct proc_ops switch_count_fops = { ++ .proc_open = switch_count_open, ++ .proc_read = seq_read, ++ .proc_lseek = seq_lseek, ++ .proc_release = single_release ++}; ++ ++static const struct proc_ops switch_vlan_fops = { ++ .proc_open = switch_vlan_open, ++ .proc_read = seq_read, ++ .proc_lseek = seq_lseek, ++ .proc_release = single_release ++}; ++ ++static const struct proc_ops mac_tbl_fops = { ++ .proc_open = mac_tbl_open, ++ .proc_read = seq_read, ++ .proc_lseek = seq_lseek, ++ .proc_write = mac_tbl_write, ++ .proc_release = single_release ++}; ++ ++static const struct proc_ops reg_fops = { ++ .proc_open = reg_open, ++ .proc_read = seq_read, ++ .proc_lseek = seq_lseek, ++ .proc_write = reg_ops, ++ .proc_release = single_release ++}; ++ ++static const struct proc_ops phyreg_fops = { ++ .proc_open = phyreg_open, ++ .proc_read = seq_read, ++ .proc_lseek = seq_lseek, ++ .proc_write = phyreg_ops, ++ .proc_release = single_release ++}; ++ ++static const struct proc_ops mirror_fops = { ++ .proc_open = mirror_open, ++ .proc_read = seq_read, ++ .proc_lseek = seq_lseek, ++ .proc_write = mirror_ops, ++ .proc_release = single_release ++}; ++ ++static const struct proc_ops igmp_fops = { ++ .proc_open = igmp_open, ++ .proc_read = seq_read, ++ .proc_lseek = seq_lseek, ++ .proc_write = igmp_ops, ++ .proc_release = single_release ++}; ++ ++int gsw_debug_proc_init(void) ++{ ++ ++ if (!proc_reg_dir) ++ proc_reg_dir = proc_mkdir(PROCREG_DIR, NULL); ++ ++ proc_esw_cnt = ++ proc_create(PROCREG_ESW_CNT, 0, proc_reg_dir, &switch_count_fops); ++ ++ if (!proc_esw_cnt) ++ pr_err("!! FAIL to create %s PROC !!\n", PROCREG_ESW_CNT); ++ ++ proc_vlan_cnt = ++ proc_create(PROCREG_VLAN, 0, proc_reg_dir, &switch_vlan_fops); ++ ++ if (!proc_vlan_cnt) ++ pr_err("!! FAIL to create %s PROC !!\n", PROCREG_VLAN); ++ ++ proc_mac_tbl = ++ proc_create(PROCREG_MAC_TBL, 0, proc_reg_dir, &mac_tbl_fops); ++ ++ if (!proc_mac_tbl) ++ pr_err("!! FAIL to create %s PROC !!\n", PROCREG_MAC_TBL); ++ ++ proc_reg = ++ proc_create(PROCREG_REG, 0, proc_reg_dir, ®_fops); ++ ++ if (!proc_reg) ++ pr_err("!! FAIL to create %s PROC !!\n", PROCREG_REG); ++ ++ proc_phyreg = ++ proc_create(PROCREG_PHYREG, 0, proc_reg_dir, &phyreg_fops); ++ ++ if (!proc_phyreg) ++ pr_err("!! FAIL to create %s PROC !!\n", PROCREG_PHYREG); ++ ++ proc_mirror = ++ proc_create(PROCREG_MIRROR, 0, proc_reg_dir, &mirror_fops); ++ ++ if (!proc_mirror) ++ pr_err("!! FAIL to create %s PROC !!\n", PROCREG_MIRROR); ++ ++ proc_igmp = ++ proc_create(PROCREG_IGMP, 0, proc_reg_dir, &igmp_fops); ++ ++ if (!proc_igmp) ++ pr_err("!! FAIL to create %s PROC !!\n", PROCREG_IGMP); ++ ++ return 0; ++} ++ ++void gsw_debug_proc_exit(void) ++{ ++ if (proc_esw_cnt) ++ remove_proc_entry(PROCREG_ESW_CNT, proc_reg_dir); ++} ++ ++ +diff --git a/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367s_mdio.c b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367s_mdio.c +new file mode 100644 +index 0000000000..ae958e8967 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/drivers/net/phy/rtk/rtl8367s_mdio.c +@@ -0,0 +1,312 @@ ++/* ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2 ++ * of the License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#include "./rtl8367c/include/rtk_switch.h" ++#include "./rtl8367c/include/port.h" ++#include "./rtl8367c/include/vlan.h" ++#include "./rtl8367c/include/rtl8367c_asicdrv_port.h" ++ ++struct rtk_gsw { ++ struct device *dev; ++ struct mii_bus *bus; ++ int reset_pin; ++}; ++ ++static struct rtk_gsw *_gsw; ++ ++extern int gsw_debug_proc_init(void); ++extern void gsw_debug_proc_exit(void); ++ ++#ifdef CONFIG_SWCONFIG ++extern int rtl8367s_swconfig_init( void (*reset_func)(void) ); ++#endif ++ ++/*mii_mgr_read/mii_mgr_write is the callback API for rtl8367 driver*/ ++unsigned int mii_mgr_read(unsigned int phy_addr,unsigned int phy_register,unsigned int *read_data) ++{ ++ struct mii_bus *bus = _gsw->bus; ++ ++ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); ++ ++ *read_data = bus->read(bus, phy_addr, phy_register); ++ ++ mutex_unlock(&bus->mdio_lock); ++ ++ return 0; ++} ++ ++unsigned int mii_mgr_write(unsigned int phy_addr,unsigned int phy_register,unsigned int write_data) ++{ ++ struct mii_bus *bus = _gsw->bus; ++ ++ mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED); ++ ++ bus->write(bus, phy_addr, phy_register, write_data); ++ ++ mutex_unlock(&bus->mdio_lock); ++ ++ return 0; ++} ++ ++static int rtl8367s_hw_reset(void) ++{ ++ struct rtk_gsw *gsw = _gsw; ++ int ret; ++ ++ if (gsw->reset_pin < 0) ++ return 0; ++ ++ ret = devm_gpio_request(gsw->dev, gsw->reset_pin, "mediatek,reset-pin"); ++ ++ if (ret) ++ printk("fail to devm_gpio_request\n"); ++ ++ gpio_direction_output(gsw->reset_pin, 0); ++ ++ usleep_range(1000, 1100); ++ ++ gpio_set_value(gsw->reset_pin, 1); ++ ++ mdelay(500); ++ ++ devm_gpio_free(gsw->dev, gsw->reset_pin); ++ ++ return 0; ++ ++} ++ ++static int rtl8367s_vlan_config(int want_at_p0) ++{ ++ rtk_vlan_cfg_t vlan1, vlan2; ++ ++ /* Set LAN/WAN VLAN partition */ ++ memset(&vlan1, 0x00, sizeof(rtk_vlan_cfg_t)); ++ ++ RTK_PORTMASK_PORT_SET(vlan1.mbr, EXT_PORT0); ++ RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT1); ++ RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT2); ++ RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT3); ++ RTK_PORTMASK_PORT_SET(vlan1.untag, EXT_PORT0); ++ RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT1); ++ RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT2); ++ RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT3); ++ ++ if (want_at_p0) { ++ RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT4); ++ RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT4); ++ } else { ++ RTK_PORTMASK_PORT_SET(vlan1.mbr, UTP_PORT0); ++ RTK_PORTMASK_PORT_SET(vlan1.untag, UTP_PORT0); ++ } ++ ++ vlan1.ivl_en = 1; ++ ++ rtk_vlan_set(1, &vlan1); ++ ++ memset(&vlan2, 0x00, sizeof(rtk_vlan_cfg_t)); ++ ++ RTK_PORTMASK_PORT_SET(vlan2.mbr, EXT_PORT1); ++ RTK_PORTMASK_PORT_SET(vlan2.untag, EXT_PORT1); ++ ++ if (want_at_p0) { ++ RTK_PORTMASK_PORT_SET(vlan2.mbr, UTP_PORT0); ++ RTK_PORTMASK_PORT_SET(vlan2.untag, UTP_PORT0); ++ } else { ++ RTK_PORTMASK_PORT_SET(vlan2.mbr, UTP_PORT4); ++ RTK_PORTMASK_PORT_SET(vlan2.untag, UTP_PORT4); ++ } ++ ++ vlan2.ivl_en = 1; ++ rtk_vlan_set(2, &vlan2); ++ ++ rtk_vlan_portPvid_set(EXT_PORT0, 1, 0); ++ rtk_vlan_portPvid_set(UTP_PORT1, 1, 0); ++ rtk_vlan_portPvid_set(UTP_PORT2, 1, 0); ++ rtk_vlan_portPvid_set(UTP_PORT3, 1, 0); ++ rtk_vlan_portPvid_set(EXT_PORT1, 2, 0); ++ ++ if (want_at_p0) { ++ rtk_vlan_portPvid_set(UTP_PORT0, 2, 0); ++ rtk_vlan_portPvid_set(UTP_PORT4, 1, 0); ++ } else { ++ rtk_vlan_portPvid_set(UTP_PORT0, 1, 0); ++ rtk_vlan_portPvid_set(UTP_PORT4, 2, 0); ++ } ++ ++ return 0; ++} ++ ++static int rtl8367s_hw_init(void) ++{ ++ ++ rtl8367s_hw_reset(); ++ ++ if(rtk_switch_init()) ++ return -1; ++ ++ mdelay(500); ++ ++ if (rtk_vlan_reset()) ++ return -1; ++ ++ if (rtk_vlan_init()) ++ return -1; ++ ++ return 0; ++} ++ ++static void set_rtl8367s_sgmii(void) ++{ ++ rtk_port_mac_ability_t mac_cfg; ++ rtk_mode_ext_t mode; ++ ++ mode = MODE_EXT_HSGMII; ++ mac_cfg.forcemode = MAC_FORCE; ++ mac_cfg.speed = PORT_SPEED_2500M; ++ mac_cfg.duplex = PORT_FULL_DUPLEX; ++ mac_cfg.link = PORT_LINKUP; ++ mac_cfg.nway = DISABLED; ++ mac_cfg.txpause = ENABLED; ++ mac_cfg.rxpause = ENABLED; ++ rtk_port_macForceLinkExt_set(EXT_PORT0, mode, &mac_cfg); ++ rtk_port_sgmiiNway_set(EXT_PORT0, DISABLED); ++ rtk_port_phyEnableAll_set(ENABLED); ++ ++} ++ ++static void set_rtl8367s_rgmii(void) ++{ ++ rtk_port_mac_ability_t mac_cfg; ++ rtk_mode_ext_t mode; ++ ++ mode = MODE_EXT_RGMII; ++ mac_cfg.forcemode = MAC_FORCE; ++ mac_cfg.speed = PORT_SPEED_1000M; ++ mac_cfg.duplex = PORT_FULL_DUPLEX; ++ mac_cfg.link = PORT_LINKUP; ++ mac_cfg.nway = DISABLED; ++ mac_cfg.txpause = ENABLED; ++ mac_cfg.rxpause = ENABLED; ++ rtk_port_macForceLinkExt_set(EXT_PORT1, mode, &mac_cfg); ++ rtk_port_rgmiiDelayExt_set(EXT_PORT1, 1, 3); ++ rtk_port_phyEnableAll_set(ENABLED); ++ ++} ++ ++void init_gsw(void) ++{ ++ rtl8367s_hw_init(); ++ set_rtl8367s_sgmii(); ++ set_rtl8367s_rgmii(); ++} ++ ++// bleow are platform driver ++static const struct of_device_id rtk_gsw_match[] = { ++ { .compatible = "mediatek,rtk-gsw" }, ++ {}, ++}; ++ ++MODULE_DEVICE_TABLE(of, rtk_gsw_match); ++ ++static int rtk_gsw_probe(struct platform_device *pdev) ++{ ++ struct device_node *np = pdev->dev.of_node; ++ struct device_node *mdio; ++ struct mii_bus *mdio_bus; ++ struct rtk_gsw *gsw; ++ const char *pm; ++ ++ 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 rtk_gsw), GFP_KERNEL); ++ ++ if (!gsw) ++ return -ENOMEM; ++ ++ gsw->dev = &pdev->dev; ++ ++ gsw->bus = mdio_bus; ++ ++ gsw->reset_pin = of_get_named_gpio(np, "mediatek,reset-pin", 0); ++ ++ _gsw = gsw; ++ ++ init_gsw(); ++ ++ //init default vlan or init swocnfig ++ if(!of_property_read_string(pdev->dev.of_node, ++ "mediatek,port_map", &pm)) { ++ ++ if (!strcasecmp(pm, "wllll")) ++ rtl8367s_vlan_config(1); ++ else ++ rtl8367s_vlan_config(0); ++ ++ } else { ++#ifdef CONFIG_SWCONFIG ++ rtl8367s_swconfig_init(&init_gsw); ++#else ++ rtl8367s_vlan_config(0); ++#endif ++ } ++ ++ gsw_debug_proc_init(); ++ ++ platform_set_drvdata(pdev, gsw); ++ ++ return 0; ++ ++} ++ ++static int rtk_gsw_remove(struct platform_device *pdev) ++{ ++ platform_set_drvdata(pdev, NULL); ++ gsw_debug_proc_exit(); ++ ++ return 0; ++} ++ ++static struct platform_driver gsw_driver = { ++ .probe = rtk_gsw_probe, ++ .remove = rtk_gsw_remove, ++ .driver = { ++ .name = "rtk-gsw", ++ .owner = THIS_MODULE, ++ .of_match_table = rtk_gsw_match, ++ }, ++}; ++ ++module_platform_driver(gsw_driver); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Mark Lee "); ++MODULE_DESCRIPTION("rtl8367c switch driver for MT7622"); ++ +diff --git a/target/linux/mediatek/image/mt7622.mk b/target/linux/mediatek/image/mt7622.mk +index bf706930e4..74f6eba19a 100644 +--- a/target/linux/mediatek/image/mt7622.mk ++++ b/target/linux/mediatek/image/mt7622.mk +@@ -1,4 +1,8 @@ +-KERNEL_LOADADDR := 0x44080000 ++ifdef CONFIG_LINUX_5_4 ++ KERNEL_LOADADDR := 0x44080000 ++else ++ KERNEL_LOADADDR := 0x44000000 ++endif + + define Device/bpi_bananapi-r64 + DEVICE_VENDOR := Bpi +diff --git a/target/linux/mediatek/mt7622/config-5.10 b/target/linux/mediatek/mt7622/config-5.10 +new file mode 100755 +index 0000000000..ccb54471c3 +--- /dev/null ++++ b/target/linux/mediatek/mt7622/config-5.10 +@@ -0,0 +1,433 @@ ++CONFIG_64BIT=y ++CONFIG_AHCI_MTK=y ++CONFIG_ARCH_DMA_ADDR_T_64BIT=y ++CONFIG_ARCH_KEEP_MEMBLOCK=y ++CONFIG_ARCH_MEDIATEK=y ++CONFIG_ARCH_MMAP_RND_BITS=18 ++CONFIG_ARCH_MMAP_RND_BITS_MAX=24 ++CONFIG_ARCH_MMAP_RND_BITS_MIN=18 ++CONFIG_ARCH_MMAP_RND_COMPAT_BITS=11 ++CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=11 ++CONFIG_ARCH_PROC_KCORE_TEXT=y ++CONFIG_ARCH_SELECT_MEMORY_MODEL=y ++CONFIG_ARCH_SPARSEMEM_DEFAULT=y ++CONFIG_ARCH_SPARSEMEM_ENABLE=y ++CONFIG_ARCH_STACKWALK=y ++CONFIG_ARCH_SUSPEND_POSSIBLE=y ++CONFIG_ARM64=y ++CONFIG_ARM64_4K_PAGES=y ++# CONFIG_ARM64_CNP is not set ++# CONFIG_ARM64_ERRATUM_1165522 is not set ++# CONFIG_ARM64_ERRATUM_1286807 is not set ++# CONFIG_ARM64_ERRATUM_1418040 is not set ++CONFIG_ARM64_ERRATUM_843419=y ++CONFIG_ARM64_ERRATUM_845719=y ++CONFIG_ARM64_MODULE_PLTS=y ++CONFIG_ARM64_PAGE_SHIFT=12 ++CONFIG_ARM64_PA_BITS=48 ++CONFIG_ARM64_PA_BITS_48=y ++# CONFIG_ARM64_PTR_AUTH is not set ++# CONFIG_ARM64_SVE is not set ++# CONFIG_ARM64_SW_TTBR0_PAN is not set ++CONFIG_ARM64_TAGGED_ADDR_ABI=y ++CONFIG_ARM64_VA_BITS=39 ++CONFIG_ARM64_VA_BITS_39=y ++# CONFIG_ARMV8_DEPRECATED is not set ++CONFIG_ARM_AMBA=y ++CONFIG_ARM_ARCH_TIMER=y ++CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y ++CONFIG_ARM_GIC=y ++CONFIG_ARM_GIC_V2M=y ++CONFIG_ARM_GIC_V3=y ++CONFIG_ARM_GIC_V3_ITS=y ++CONFIG_ARM_GIC_V3_ITS_PCI=y ++CONFIG_ARM_MEDIATEK_CPUFREQ=y ++CONFIG_ARM_PMU=y ++CONFIG_ARM_PSCI_FW=y ++CONFIG_ATA=y ++CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y ++CONFIG_BLK_DEV_SD=y ++CONFIG_BLK_MQ_PCI=y ++CONFIG_BLK_PM=y ++CONFIG_BLK_SCSI_REQUEST=y ++CONFIG_BLOCK_COMPAT=y ++CONFIG_BSD_PROCESS_ACCT=y ++CONFIG_BSD_PROCESS_ACCT_V3=y ++# CONFIG_CAVIUM_TX2_ERRATUM_219 is not set ++CONFIG_CLKDEV_LOOKUP=y ++CONFIG_CLKSRC_MMIO=y ++CONFIG_CLONE_BACKWARDS=y ++CONFIG_COMMON_CLK=y ++CONFIG_COMMON_CLK_MEDIATEK=y ++CONFIG_COMMON_CLK_MT2712=y ++# CONFIG_COMMON_CLK_MT2712_BDPSYS is not set ++# CONFIG_COMMON_CLK_MT2712_IMGSYS is not set ++# CONFIG_COMMON_CLK_MT2712_JPGDECSYS is not set ++# CONFIG_COMMON_CLK_MT2712_MFGCFG is not set ++# CONFIG_COMMON_CLK_MT2712_MMSYS is not set ++# CONFIG_COMMON_CLK_MT2712_VDECSYS is not set ++# CONFIG_COMMON_CLK_MT2712_VENCSYS is not set ++# CONFIG_COMMON_CLK_MT6779 is not set ++# CONFIG_COMMON_CLK_MT6797 is not set ++CONFIG_COMMON_CLK_MT7622=y ++CONFIG_COMMON_CLK_MT7622_AUDSYS=y ++CONFIG_COMMON_CLK_MT7622_ETHSYS=y ++CONFIG_COMMON_CLK_MT7622_HIFSYS=y ++# CONFIG_COMMON_CLK_MT8173 is not set ++CONFIG_COMMON_CLK_MT8183=y ++# CONFIG_COMMON_CLK_MT8183_AUDIOSYS is not set ++# CONFIG_COMMON_CLK_MT8183_CAMSYS is not set ++# CONFIG_COMMON_CLK_MT8183_IMGSYS is not set ++# CONFIG_COMMON_CLK_MT8183_IPU_ADL is not set ++# CONFIG_COMMON_CLK_MT8183_IPU_CONN is not set ++# CONFIG_COMMON_CLK_MT8183_IPU_CORE0 is not set ++# CONFIG_COMMON_CLK_MT8183_IPU_CORE1 is not set ++# CONFIG_COMMON_CLK_MT8183_MFGCFG is not set ++# CONFIG_COMMON_CLK_MT8183_MMSYS is not set ++# CONFIG_COMMON_CLK_MT8183_VDECSYS is not set ++# CONFIG_COMMON_CLK_MT8183_VENCSYS is not set ++CONFIG_COMMON_CLK_MT8516=y ++# CONFIG_COMMON_CLK_MT8516_AUDSYS is not set ++CONFIG_COMPAT=y ++CONFIG_COMPAT_32BIT_TIME=y ++CONFIG_COMPAT_BINFMT_ELF=y ++CONFIG_COMPAT_NETLINK_MESSAGES=y ++CONFIG_COMPAT_OLD_SIGACTION=y ++CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15 ++# CONFIG_CPUFREQ_DT is not set ++CONFIG_CPU_FREQ=y ++# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set ++CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y ++CONFIG_CPU_FREQ_GOV_ATTR_SET=y ++CONFIG_CPU_FREQ_GOV_COMMON=y ++CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y ++CONFIG_CPU_FREQ_GOV_ONDEMAND=y ++CONFIG_CPU_FREQ_GOV_PERFORMANCE=y ++CONFIG_CPU_FREQ_GOV_POWERSAVE=y ++CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y ++CONFIG_CPU_FREQ_GOV_USERSPACE=y ++CONFIG_CPU_FREQ_STAT=y ++CONFIG_CPU_RMAP=y ++CONFIG_CPU_THERMAL=y ++CONFIG_CRC16=y ++CONFIG_CRYPTO_ACOMP2=y ++CONFIG_CRYPTO_AEAD=y ++CONFIG_CRYPTO_AEAD2=y ++CONFIG_CRYPTO_CMAC=y ++CONFIG_CRYPTO_DEFLATE=y ++CONFIG_CRYPTO_DRBG=y ++CONFIG_CRYPTO_DRBG_HMAC=y ++CONFIG_CRYPTO_DRBG_MENU=y ++CONFIG_CRYPTO_ECB=y ++CONFIG_CRYPTO_ECC=y ++CONFIG_CRYPTO_ECDH=y ++CONFIG_CRYPTO_HASH=y ++CONFIG_CRYPTO_HASH2=y ++CONFIG_CRYPTO_HASH_INFO=y ++CONFIG_CRYPTO_HMAC=y ++CONFIG_CRYPTO_JITTERENTROPY=y ++CONFIG_CRYPTO_KPP=y ++CONFIG_CRYPTO_KPP2=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_RNG_DEFAULT=y ++CONFIG_CRYPTO_SHA256=y ++CONFIG_DCACHE_WORD_ACCESS=y ++CONFIG_DEBUG_MISC=y ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_DIMLIB=y ++CONFIG_DMADEVICES=y ++CONFIG_DMATEST=y ++CONFIG_DMA_DIRECT_REMAP=y ++CONFIG_DMA_ENGINE=y ++CONFIG_DMA_ENGINE_RAID=y ++CONFIG_DMA_OF=y ++CONFIG_DMA_REMAP=y ++CONFIG_DMA_VIRTUAL_CHANNELS=y ++CONFIG_DTC=y ++CONFIG_DYNAMIC_DEBUG=y ++CONFIG_EDAC_SUPPORT=y ++CONFIG_EINT_MTK=y ++CONFIG_FIXED_PHY=y ++CONFIG_FIX_EARLYCON_MEM=y ++# CONFIG_FLATMEM_MANUAL is not set ++CONFIG_FRAME_POINTER=y ++# CONFIG_FUJITSU_ERRATUM_010001 is not set ++CONFIG_FW_LOADER_PAGED_BUF=y ++CONFIG_GENERIC_ALLOCATOR=y ++CONFIG_GENERIC_ARCH_TOPOLOGY=y ++CONFIG_GENERIC_BUG=y ++CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y ++CONFIG_GENERIC_CLOCKEVENTS=y ++CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y ++CONFIG_GENERIC_CPU_AUTOPROBE=y ++CONFIG_GENERIC_CPU_VULNERABILITIES=y ++CONFIG_GENERIC_CSUM=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_GLOB=y ++CONFIG_GPIOLIB=y ++CONFIG_GRO_CELLS=y ++CONFIG_HANDLE_DOMAIN_IRQ=y ++CONFIG_HARDIRQS_SW_RESEND=y ++CONFIG_HAS_DMA=y ++CONFIG_HAS_IOMEM=y ++CONFIG_HAS_IOPORT_MAP=y ++CONFIG_HOLES_IN_ZONE=y ++CONFIG_HZ=250 ++CONFIG_HZ_250=y ++CONFIG_ICPLUS_PHY=y ++CONFIG_IIO=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 ++CONFIG_INITRAMFS_SOURCE="" ++CONFIG_IO_URING=y ++CONFIG_IRQCHIP=y ++CONFIG_IRQ_DOMAIN=y ++CONFIG_IRQ_DOMAIN_HIERARCHY=y ++CONFIG_IRQ_FORCED_THREADING=y ++CONFIG_IRQ_TIME_ACCOUNTING=y ++CONFIG_IRQ_WORK=y ++CONFIG_JUMP_LABEL=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_MAGIC_SYSRQ=y ++CONFIG_MDIO_BUS=y ++CONFIG_MDIO_DEVICE=y ++CONFIG_MEDIATEK_MT6577_AUXADC=y ++CONFIG_MEDIATEK_WATCHDOG=y ++CONFIG_MEMFD_CREATE=y ++CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7 ++CONFIG_MFD_SYSCON=y ++CONFIG_MIGRATION=y ++CONFIG_MMC=y ++CONFIG_MMC_CQHCI=y ++CONFIG_MMC_MTK=y ++# CONFIG_MMC_TIFM_SD is not set ++CONFIG_MODULES_TREE_LOOKUP=y ++CONFIG_MODULES_USE_ELF_RELA=y ++CONFIG_MTD_NAND_CORE=y ++CONFIG_MTD_NAND_ECC=y ++CONFIG_MTD_NAND_ECC_SW_HAMMING=y ++CONFIG_MTD_NAND_MTK=y ++CONFIG_MTD_NAND_MTK_BMT=y ++CONFIG_MTD_RAW_NAND=y ++CONFIG_MTD_SPI_NAND=y ++CONFIG_MTD_SPI_NOR=y ++CONFIG_MTD_SPLIT_FIRMWARE=y ++CONFIG_MTD_SPLIT_FIT_FW=y ++CONFIG_MTD_UBI=y ++CONFIG_MTD_UBI_BEB_LIMIT=20 ++CONFIG_MTD_UBI_BLOCK=y ++CONFIG_MTD_UBI_WL_THRESHOLD=4096 ++# CONFIG_MTK_CMDQ is not set ++# CONFIG_MTK_CQDMA is not set ++CONFIG_MTK_EFUSE=y ++CONFIG_MTK_HSDMA=y ++CONFIG_MTK_INFRACFG=y ++CONFIG_MTK_PMIC_WRAP=y ++CONFIG_MTK_SCPSYS=y ++CONFIG_MTK_THERMAL=y ++CONFIG_MTK_TIMER=y ++# CONFIG_MTK_UART_APDMA is not set ++CONFIG_MUTEX_SPIN_ON_OWNER=y ++CONFIG_NEED_DMA_MAP_STATE=y ++CONFIG_NEED_SG_DMA_LENGTH=y ++CONFIG_NET_DEVLINK=y ++CONFIG_NET_DSA=y ++CONFIG_NET_DSA_MT7530=y ++CONFIG_NET_DSA_TAG_MTK=y ++CONFIG_NET_FLOW_LIMIT=y ++CONFIG_NET_MEDIATEK_SOC=y ++CONFIG_NET_SWITCHDEV=y ++CONFIG_NET_VENDOR_MEDIATEK=y ++CONFIG_NLS=y ++CONFIG_NO_HZ_COMMON=y ++CONFIG_NO_HZ_IDLE=y ++CONFIG_NR_CPUS=2 ++CONFIG_NVMEM=y ++CONFIG_NVMEM_SYSFS=y ++# CONFIG_OCTEONTX2_AF 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_SIGSUSPEND3=y ++CONFIG_PADATA=y ++CONFIG_PARTITION_PERCPU=y ++CONFIG_PCI=y ++CONFIG_PCIEAER=y ++CONFIG_PCIEASPM=y ++# CONFIG_PCIEASPM_DEFAULT is not set ++CONFIG_PCIEASPM_PERFORMANCE=y ++# CONFIG_PCIEASPM_POWERSAVE is not set ++# CONFIG_PCIEASPM_POWER_SUPERSAVE is not set ++CONFIG_PCIEPORTBUS=y ++# CONFIG_PCIE_AL is not set ++CONFIG_PCIE_MEDIATEK=y ++CONFIG_PCIE_PME=y ++CONFIG_PCI_DEBUG=y ++CONFIG_PCI_DOMAINS=y ++CONFIG_PCI_DOMAINS_GENERIC=y ++CONFIG_PCI_MSI=y ++CONFIG_PCI_MSI_IRQ_DOMAIN=y ++CONFIG_PERF_EVENTS=y ++CONFIG_PGTABLE_LEVELS=3 ++CONFIG_PHYLIB=y ++CONFIG_PHYLINK=y ++CONFIG_PHYS_ADDR_T_64BIT=y ++CONFIG_PHY_MTK_TPHY=y ++# CONFIG_PHY_MTK_UFS is not set ++# CONFIG_PHY_MTK_XSPHY is not set ++CONFIG_PINCTRL=y ++# CONFIG_PINCTRL_MT2712 is not set ++# CONFIG_PINCTRL_MT6765 is not set ++# CONFIG_PINCTRL_MT6797 is not set ++CONFIG_PINCTRL_MT7622=y ++# CONFIG_PINCTRL_MT8173 is not set ++# CONFIG_PINCTRL_MT8183 is not set ++CONFIG_PINCTRL_MT8516=y ++CONFIG_PINCTRL_MTK=y ++CONFIG_PINCTRL_MTK_MOORE=y ++CONFIG_PINCTRL_MTK_V2=y ++CONFIG_PM=y ++CONFIG_PM_CLK=y ++CONFIG_PM_GENERIC_DOMAINS=y ++CONFIG_PM_GENERIC_DOMAINS_OF=y ++CONFIG_PM_OPP=y ++CONFIG_POWER_RESET=y ++CONFIG_POWER_RESET_SYSCON=y ++CONFIG_POWER_SUPPLY=y ++CONFIG_PRINTK_TIME=y ++CONFIG_PWM=y ++CONFIG_PWM_MEDIATEK=y ++# CONFIG_PWM_MTK_DISP is not set ++CONFIG_PWM_SYSFS=y ++CONFIG_QUEUED_RWLOCKS=y ++CONFIG_QUEUED_SPINLOCKS=y ++CONFIG_RAS=y ++CONFIG_RATIONAL=y ++# CONFIG_RAVE_SP_CORE is not set ++CONFIG_RCU_NEED_SEGCBLIST=y ++CONFIG_RCU_STALL_COMMON=y ++CONFIG_REALTEK_PHY=y ++CONFIG_REGMAP=y ++CONFIG_REGMAP_MMIO=y ++CONFIG_REGULATOR=y ++CONFIG_REGULATOR_FIXED_VOLTAGE=y ++CONFIG_REGULATOR_MT6380=y ++CONFIG_RESET_CONTROLLER=y ++CONFIG_RFS_ACCEL=y ++CONFIG_RODATA_FULL_DEFAULT_ENABLED=y ++CONFIG_RPS=y ++CONFIG_RTC_CLASS=y ++CONFIG_RTC_DRV_MT7622=y ++CONFIG_RTC_I2C_AND_SPI=y ++CONFIG_RTL8367S_GSW=y ++CONFIG_RWSEM_SPIN_ON_OWNER=y ++CONFIG_SATA_HOST=y ++CONFIG_SCSI=y ++# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set ++CONFIG_SERIAL_8250_FSL=y ++CONFIG_SERIAL_8250_MT6577=y ++CONFIG_SERIAL_8250_NR_UARTS=3 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=3 ++CONFIG_SERIAL_DEV_BUS=y ++CONFIG_SERIAL_DEV_CTRL_TTYPORT=y ++CONFIG_SERIAL_MCTRL_GPIO=y ++CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_SGL_ALLOC=y ++CONFIG_SG_POOL=y ++CONFIG_SMP=y ++CONFIG_SPARSEMEM=y ++CONFIG_SPARSEMEM_EXTREME=y ++CONFIG_SPARSEMEM_MANUAL=y ++CONFIG_SPARSEMEM_VMEMMAP=y ++CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y ++CONFIG_SPARSE_IRQ=y ++CONFIG_SPI=y ++CONFIG_SPI_MASTER=y ++CONFIG_SPI_MEM=y ++CONFIG_SPI_MT65XX=y ++# CONFIG_SPI_MTK_NOR is not set ++CONFIG_SPI_MTK_SNFI=y ++CONFIG_SRCU=y ++CONFIG_SWCONFIG=y ++CONFIG_SWIOTLB=y ++CONFIG_SWPHY=y ++CONFIG_SYSCTL_EXCEPTION_TRACE=y ++CONFIG_SYSVIPC_COMPAT=y ++CONFIG_SYS_SUPPORTS_HUGETLBFS=y ++CONFIG_THERMAL=y ++CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y ++CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0 ++CONFIG_THERMAL_EMULATION=y ++CONFIG_THERMAL_GOV_BANG_BANG=y ++CONFIG_THERMAL_GOV_FAIR_SHARE=y ++CONFIG_THERMAL_GOV_STEP_WISE=y ++CONFIG_THERMAL_GOV_USER_SPACE=y ++CONFIG_THERMAL_OF=y ++CONFIG_THERMAL_WRITABLE_TRIPS=y ++CONFIG_THREAD_INFO_IN_TASK=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_UCLAMP_TASK is not set ++# CONFIG_UNMAP_KERNEL_AT_EL0 is not set ++CONFIG_USB=y ++CONFIG_USB_COMMON=y ++CONFIG_USB_SUPPORT=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_MTK=y ++# CONFIG_USB_XHCI_PLATFORM is not set ++CONFIG_VMAP_STACK=y ++CONFIG_WATCHDOG_CORE=y ++CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC=y ++CONFIG_WATCHDOG_PRETIMEOUT_GOV=y ++# CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP is not set ++CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC=y ++CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL=m ++CONFIG_WATCHDOG_SYSFS=y ++CONFIG_XPS=y ++CONFIG_ZLIB_DEFLATE=y ++CONFIG_ZLIB_INFLATE=y ++CONFIG_ZONE_DMA32=y +diff --git a/target/linux/mediatek/patches-5.10/100-dts-update-mt7622-rfb1.patch b/target/linux/mediatek/patches-5.10/100-dts-update-mt7622-rfb1.patch +new file mode 100644 +index 0000000000..f4e77cf69c +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/100-dts-update-mt7622-rfb1.patch +@@ -0,0 +1,119 @@ ++--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts +++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts ++@@ -1,7 +1,6 @@ ++ /* ++- * Copyright (c) 2017 MediaTek Inc. ++- * Author: Ming Huang ++- * Sean Wang +++ * Copyright (c) 2018 MediaTek Inc. +++ * Author: Ryder Lee ++ * ++ * SPDX-License-Identifier: (GPL-2.0 OR MIT) ++ */ ++@@ -23,7 +22,7 @@ ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++- bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512"; +++ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512"; ++ }; ++ ++ cpus { ++@@ -40,23 +39,22 @@ ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++- poll-interval = <100>; ++ ++ factory { ++ label = "factory"; ++ linux,code = ; ++- gpios = <&pio 0 0>; +++ gpios = <&pio 0 GPIO_ACTIVE_LOW>; ++ }; ++ ++ wps { ++ label = "wps"; ++ linux,code = ; ++- gpios = <&pio 102 0>; +++ gpios = <&pio 102 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ memory { ++- reg = <0 0x40000000 0 0x20000000>; +++ reg = <0 0x40000000 0 0x40000000>; ++ }; ++ ++ reg_1p8v: regulator-1p8v { ++@@ -132,22 +130,22 @@ ++ ++ port@0 { ++ reg = <0>; ++- label = "lan0"; +++ label = "lan1"; ++ }; ++ ++ port@1 { ++ reg = <1>; ++- label = "lan1"; +++ label = "lan2"; ++ }; ++ ++ port@2 { ++ reg = <2>; ++- label = "lan2"; +++ label = "lan3"; ++ }; ++ ++ port@3 { ++ reg = <3>; ++- label = "lan3"; +++ label = "lan4"; ++ }; ++ ++ port@4 { ++@@ -236,15 +234,28 @@ ++ ++ &pcie { ++ pinctrl-names = "default"; ++- pinctrl-0 = <&pcie0_pins>; +++ pinctrl-0 = <&pcie0_pins>, <&pcie1_pins>; ++ status = "okay"; ++ ++ pcie@0,0 { ++ status = "okay"; ++ }; +++ +++ pcie@1,0 { +++ status = "okay"; +++ }; ++ }; ++ ++ &pio { +++ /* Attention: GPIO 90 is used to switch between PCIe@1,0 and +++ * SATA functions. i.e. output-high: PCIe, output-low: SATA +++ */ +++ asm_sel { +++ gpio-hog; +++ gpios = <90 GPIO_ACTIVE_HIGH>; +++ output-high; +++ }; +++ ++ /* eMMC is shared pin with parallel NAND */ ++ emmc_pins_default: emmc-pins-default { ++ mux { ++@@ -511,11 +522,11 @@ ++ }; ++ ++ &sata { ++- status = "okay"; +++ status = "disabled"; ++ }; ++ ++ &sata_phy { ++- status = "okay"; +++ status = "disabled"; ++ }; ++ ++ &spi0 { +diff --git a/target/linux/mediatek/patches-5.10/101-dts-update-mt7629-rfb.patch b/target/linux/mediatek/patches-5.10/101-dts-update-mt7629-rfb.patch +new file mode 100644 +index 0000000000..8d3e283315 +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/101-dts-update-mt7629-rfb.patch +@@ -0,0 +1,37 @@ ++--- a/arch/arm/boot/dts/mt7629-rfb.dts +++++ b/arch/arm/boot/dts/mt7629-rfb.dts ++@@ -18,6 +18,7 @@ ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; +++ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n8"; ++ }; ++ ++ gpio-keys { ++@@ -69,6 +70,7 @@ ++ gmac0: mac@0 { ++ compatible = "mediatek,eth-mac"; ++ reg = <0>; +++ mtd-mac-address = <&factory 0x2a>; ++ phy-mode = "2500base-x"; ++ fixed-link { ++ speed = <2500>; ++@@ -80,6 +82,7 @@ ++ gmac1: mac@1 { ++ compatible = "mediatek,eth-mac"; ++ reg = <1>; +++ mtd-mac-address = <&factory 0x24>; ++ phy-mode = "gmii"; ++ phy-handle = <&phy0>; ++ }; ++@@ -133,8 +136,9 @@ ++ }; ++ ++ partition@b0000 { ++- label = "kernel"; +++ label = "firmware"; ++ reg = <0xb0000 0xb50000>; +++ compatible = "denx,fit"; ++ }; ++ }; ++ }; +diff --git a/target/linux/mediatek/patches-5.10/110-dts-fix-bpi2-console.patch b/target/linux/mediatek/patches-5.10/110-dts-fix-bpi2-console.patch +new file mode 100644 +index 0000000000..c696e7d369 +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/110-dts-fix-bpi2-console.patch +@@ -0,0 +1,10 @@ ++--- a/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts +++++ b/arch/arm/boot/dts/mt7623n-bananapi-bpi-r2.dts ++@@ -19,6 +19,7 @@ ++ ++ chosen { ++ stdout-path = "serial2:115200n8"; +++ bootargs = "console=ttyS2,115200n8"; ++ }; ++ ++ connector { +diff --git a/target/linux/mediatek/patches-5.10/111-dts-fix-bpi64-console.patch b/target/linux/mediatek/patches-5.10/111-dts-fix-bpi64-console.patch +new file mode 100644 +index 0000000000..07a2eae245 +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/111-dts-fix-bpi64-console.patch +@@ -0,0 +1,11 @@ ++--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts +++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts ++@@ -22,7 +22,7 @@ ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++- bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512"; +++ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512"; ++ }; ++ ++ cpus { +diff --git a/target/linux/mediatek/patches-5.10/120-arm-dts-Add-Unielec-U7623-DTS.patch b/target/linux/mediatek/patches-5.10/120-arm-dts-Add-Unielec-U7623-DTS.patch +new file mode 100644 +index 0000000000..56d51aac38 +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/120-arm-dts-Add-Unielec-U7623-DTS.patch +@@ -0,0 +1,390 @@ ++From 004eb24e939b5b31f828333f37fb5cb2a877d6f2 Mon Sep 17 00:00:00 2001 ++From: Kristian Evensen ++Date: Sun, 17 Jun 2018 14:41:47 +0200 ++Subject: [PATCH] arm: dts: Add Unielec U7623 DTS ++ ++--- ++ arch/arm/boot/dts/Makefile | 1 + ++ .../dts/mt7623a-unielec-u7623-02-emmc-512m.dts | 18 + ++ .../boot/dts/mt7623a-unielec-u7623-02-emmc.dtsi | 366 +++++++++++++++++++++ ++ 3 files changed, 385 insertions(+) ++ create mode 100644 arch/arm/boot/dts/mt7623a-unielec-u7623-02-emmc-512m.dts ++ create mode 100644 arch/arm/boot/dts/mt7623a-unielec-u7623-02-emmc.dtsi ++ ++--- a/arch/arm/boot/dts/Makefile +++++ b/arch/arm/boot/dts/Makefile ++@@ -1366,6 +1366,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ ++ mt7623a-rfb-nand.dtb \ ++ mt7623n-rfb-emmc.dtb \ ++ mt7623n-bananapi-bpi-r2.dtb \ +++ mt7623a-unielec-u7623-02-emmc-512m.dtb \ ++ mt7629-rfb.dtb \ ++ mt8127-moose.dtb \ ++ mt8135-evbp1.dtb ++--- /dev/null +++++ b/arch/arm/boot/dts/mt7623a-unielec-u7623-02-emmc-512m.dts ++@@ -0,0 +1,18 @@ +++/* +++ * Copyright 2018 Kristian Evensen +++ * +++ * SPDX-License-Identifier: (GPL-2.0+ OR MIT) +++ */ +++ +++/dts-v1/; +++#include "mt7623a-unielec-u7623-02-emmc.dtsi" +++ +++/ { +++ model = "UniElec U7623-02 eMMC (512M RAM)"; +++ compatible = "unielec,u7623-02-emmc-512m", "unielec,u7623-02-emmc", "mediatek,mt7623"; +++ +++ memory@80000000 { +++ device_type = "memory"; +++ reg = <0 0x80000000 0 0x20000000>; +++ }; +++}; ++--- /dev/null +++++ b/arch/arm/boot/dts/mt7623a-unielec-u7623-02-emmc.dtsi ++@@ -0,0 +1,343 @@ +++/* +++ * Copyright 2018 Kristian Evensen +++ * +++ * SPDX-License-Identifier: (GPL-2.0+ OR MIT) +++ */ +++ +++#include +++#include "mt7623.dtsi" +++#include "mt6323.dtsi" +++ +++/ { +++ compatible = "unielec,u7623-02-emmc", "mediatek,mt7623"; +++ +++ aliases { +++ serial2 = &uart2; +++ }; +++ +++ chosen { +++ bootargs = "root=/dev/mmcblk0p2 rootfstype=squashfs,f2fs console=ttyS0,115200 blkdevparts=mmcblk0:3M@6M(recovery),256M@9M(root)"; +++ stdout-path = "serial2:115200n8"; +++ }; +++ +++ cpus { +++ cpu@0 { +++ proc-supply = <&mt6323_vproc_reg>; +++ }; +++ +++ cpu@1 { +++ proc-supply = <&mt6323_vproc_reg>; +++ }; +++ +++ cpu@2 { +++ proc-supply = <&mt6323_vproc_reg>; +++ }; +++ +++ cpu@3 { +++ proc-supply = <&mt6323_vproc_reg>; +++ }; +++ }; +++ +++ reg_1p8v: regulator-1p8v { +++ compatible = "regulator-fixed"; +++ regulator-name = "fixed-1.8V"; +++ regulator-min-microvolt = <1800000>; +++ regulator-max-microvolt = <1800000>; +++ regulator-boot-on; +++ regulator-always-on; +++ }; +++ +++ reg_3p3v: regulator-3p3v { +++ compatible = "regulator-fixed"; +++ regulator-name = "fixed-3.3V"; +++ regulator-min-microvolt = <3300000>; +++ regulator-max-microvolt = <3300000>; +++ regulator-boot-on; +++ regulator-always-on; +++ }; +++ +++ reg_5v: regulator-5v { +++ compatible = "regulator-fixed"; +++ regulator-name = "fixed-5V"; +++ regulator-min-microvolt = <5000000>; +++ regulator-max-microvolt = <5000000>; +++ regulator-boot-on; +++ regulator-always-on; +++ }; +++ +++ gpio-keys { +++ compatible = "gpio-keys"; +++ pinctrl-names = "default"; +++ pinctrl-0 = <&key_pins_a>; +++ +++ factory { +++ label = "factory"; +++ linux,code = ; +++ gpios = <&pio 256 GPIO_ACTIVE_LOW>; +++ }; +++ }; +++ +++ leds { +++ compatible = "gpio-leds"; +++ pinctrl-names = "default"; +++ pinctrl-0 = <&led_pins_unielec>; +++ +++ led3 { +++ label = "u7623-01:green:led3"; +++ gpios = <&pio 14 GPIO_ACTIVE_LOW>; +++ default-state = "off"; +++ }; +++ +++ led4 { +++ label = "u7623-01:green:led4"; +++ gpios = <&pio 15 GPIO_ACTIVE_LOW>; +++ default-state = "off"; +++ }; +++ }; +++}; +++ +++&crypto { +++ status = "okay"; +++}; +++ +++ð { +++ status = "okay"; +++ +++ gmac0: mac@0 { +++ compatible = "mediatek,eth-mac"; +++ reg = <0>; +++ phy-mode = "trgmii"; +++ +++ fixed-link { +++ speed = <1000>; +++ full-duplex; +++ pause; +++ }; +++ }; +++ +++ mdio: mdio-bus { +++ #address-cells = <1>; +++ #size-cells = <0>; +++ +++ mt7530: switch@0 { +++ compatible = "mediatek,mt7530"; +++ }; +++ }; +++}; +++ +++&mt7530 { +++ compatible = "mediatek,mt7530"; +++ #address-cells = <1>; +++ #size-cells = <0>; +++ reg = <0>; +++ pinctrl-names = "default"; +++ mediatek,mcm; +++ resets = <ðsys 2>; +++ reset-names = "mcm"; +++ core-supply = <&mt6323_vpa_reg>; +++ io-supply = <&mt6323_vemc3v3_reg>; +++ +++ dsa,mii-bus = <&mdio>; +++ +++ ports { +++ #address-cells = <1>; +++ #size-cells = <0>; +++ reg = <0>; +++ +++ port@0 { +++ reg = <0>; +++ label = "lan0"; +++ cpu = <&cpu_port0>; +++ }; +++ +++ port@1 { +++ reg = <1>; +++ label = "lan1"; +++ cpu = <&cpu_port0>; +++ }; +++ +++ port@2 { +++ reg = <2>; +++ label = "lan2"; +++ cpu = <&cpu_port0>; +++ }; +++ +++ port@3 { +++ reg = <3>; +++ label = "lan3"; +++ cpu = <&cpu_port0>; +++ }; +++ +++ port@4 { +++ reg = <4>; +++ label = "wan"; +++ cpu = <&cpu_port0>; +++ }; +++ +++ cpu_port0: port@6 { +++ reg = <6>; +++ label = "cpu"; +++ ethernet = <&gmac0>; +++ phy-mode = "trgmii"; +++ +++ fixed-link { +++ speed = <1000>; +++ full-duplex; +++ }; +++ }; +++ }; +++}; +++ +++&mmc0 { +++ pinctrl-names = "default", "state_uhs"; +++ pinctrl-0 = <&mmc0_pins_default>; +++ pinctrl-1 = <&mmc0_pins_uhs>; +++ status = "okay"; +++ bus-width = <8>; +++ max-frequency = <50000000>; +++ cap-mmc-highspeed; +++ vmmc-supply = <®_3p3v>; +++ vqmmc-supply = <®_1p8v>; +++ non-removable; +++}; +++ +++&pio { +++ key_pins_a: keys-alt { +++ pins-keys { +++ pinmux = , +++ ; +++ input-enable; +++ }; +++ }; +++ +++ led_pins_unielec: leds-unielec { +++ pins-leds { +++ pinmux = , +++ ; +++ }; +++ }; +++ +++ mmc0_pins_default: mmc0default { +++ pins_cmd_dat { +++ pinmux = , +++ , +++ , +++ , +++ , +++ , +++ , +++ , +++ ; +++ input-enable; +++ bias-pull-up; +++ }; +++ +++ pins_clk { +++ pinmux = ; +++ bias-pull-down; +++ }; +++ +++ pins_rst { +++ pinmux = ; +++ bias-pull-up; +++ }; +++ }; +++ +++ mmc0_pins_uhs: mmc0 { +++ pins_cmd_dat { +++ pinmux = , +++ , +++ , +++ , +++ , +++ , +++ , +++ , +++ ; +++ input-enable; +++ drive-strength = ; +++ bias-pull-up = ; +++ }; +++ +++ pins_clk { +++ pinmux = ; +++ drive-strength = ; +++ bias-pull-down = ; +++ }; +++ +++ pins_rst { +++ pinmux = ; +++ bias-pull-up; +++ }; +++ }; +++ +++ pcie_default: pcie_pin_default { +++ pins_cmd_dat { +++ pinmux = , +++ ; +++ bias-disable; +++ }; +++ }; +++}; +++ +++&pwm { +++ pinctrl-names = "default"; +++ pinctrl-0 = <&pwm_pins_a>; +++ status = "okay"; +++}; +++ +++&pwrap { +++ mt6323 { +++ mt6323led: led { +++ compatible = "mediatek,mt6323-led"; +++ #address-cells = <1>; +++ #size-cells = <0>; +++ +++ led@0 { +++ reg = <0>; +++ label = "led0"; +++ default-state = "off"; +++ }; +++ }; +++ }; +++}; +++ +++&uart2 { +++ pinctrl-names = "default"; +++ pinctrl-0 = <&uart2_pins_b>; +++ status = "okay"; +++}; +++ +++&usb1 { +++ vusb33-supply = <®_3p3v>; +++ vbus-supply = <®_3p3v>; +++ status = "okay"; +++}; +++ +++&u3phy1 { +++ status = "okay"; +++}; +++ +++&u3phy2 { +++ status = "okay"; +++ mediatek,phy-switch = <&hifsys>; +++}; +++ +++&pcie { +++ pinctrl-names = "default"; +++ pinctrl-0 = <&pcie_default>; +++ status = "okay"; +++ +++ pcie@1,0 { +++ status = "okay"; +++ }; +++ +++ pcie@2,0 { +++ status = "okay"; +++ }; +++}; +++ +++&pcie1_phy { +++ status = "okay"; +++}; +++ +diff --git a/target/linux/mediatek/patches-5.10/130-dts-mt7629-add-snand-support.patch b/target/linux/mediatek/patches-5.10/130-dts-mt7629-add-snand-support.patch +new file mode 100644 +index 0000000000..479694b400 +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/130-dts-mt7629-add-snand-support.patch +@@ -0,0 +1,97 @@ ++From c813fbe806257c574240770ef716fbee19f7dbfa Mon Sep 17 00:00:00 2001 ++From: Xiangsheng Hou ++Date: Thu, 6 Jun 2019 16:29:04 +0800 ++Subject: [PATCH] spi: spi-mem: Mediatek: Add SPI Nand support for MT7629 ++ ++Signed-off-by: Xiangsheng Hou ++--- ++ arch/arm/boot/dts/mt7629-rfb.dts | 45 ++++++++++++++++++++++++++++++++ ++ arch/arm/boot/dts/mt7629.dtsi | 22 ++++++++++++++++ ++ 3 files changed, 79 insertions(+) ++ ++--- a/arch/arm/boot/dts/mt7629.dtsi +++++ b/arch/arm/boot/dts/mt7629.dtsi ++@@ -272,6 +272,28 @@ ++ status = "disabled"; ++ }; ++ +++ bch: ecc@1100e000 { +++ compatible = "mediatek,mt7622-ecc"; +++ reg = <0x1100e000 0x1000>; +++ interrupts = ; +++ clocks = <&pericfg CLK_PERI_NFIECC_PD>; +++ clock-names = "nfiecc_clk"; +++ status = "disabled"; +++ }; +++ +++ snfi: spi@1100d000 { +++ compatible = "mediatek,mt7629-snfi"; +++ reg = <0x1100d000 0x1000>; +++ interrupts = ; +++ clocks = <&pericfg CLK_PERI_NFI_PD>, +++ <&pericfg CLK_PERI_SNFI_PD>; +++ clock-names = "nfi_clk", "spi_clk"; +++ ecc-engine = <&bch>; +++ #address-cells = <1>; +++ #size-cells = <0>; +++ status = "disabled"; +++ }; +++ ++ spi: spi@1100a000 { ++ compatible = "mediatek,mt7629-spi", ++ "mediatek,mt7622-spi"; ++--- a/arch/arm/boot/dts/mt7629-rfb.dts +++++ b/arch/arm/boot/dts/mt7629-rfb.dts ++@@ -249,6 +249,52 @@ ++ }; ++ }; ++ +++&bch { +++ status = "okay"; +++}; +++ +++&snfi { +++ pinctrl-names = "default"; +++ pinctrl-0 = <&serial_nand_pins>; +++ status = "okay"; +++ +++ spi_nand@0 { +++ #address-cells = <1>; +++ #size-cells = <1>; +++ compatible = "spi-nand"; +++ spi-max-frequency = <104000000>; +++ reg = <0>; +++ +++ partitions { +++ compatible = "fixed-partitions"; +++ #address-cells = <1>; +++ #size-cells = <1>; +++ +++ partition@0 { +++ label = "Bootloader"; +++ reg = <0x00000 0x0100000>; +++ read-only; +++ }; +++ +++ partition@100000 { +++ label = "Config"; +++ reg = <0x100000 0x0040000>; +++ }; +++ +++ partition@140000 { +++ label = "factory"; +++ reg = <0x140000 0x0080000>; +++ }; +++ +++ partition@1c0000 { +++ label = "firmware"; +++ reg = <0x1c0000 0x1000000>; +++ }; +++ +++ }; +++ }; +++}; +++ ++ &spi { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi_pins>; +diff --git a/target/linux/mediatek/patches-5.10/131-dts-mt7622-add-snand-support.patch b/target/linux/mediatek/patches-5.10/131-dts-mt7622-add-snand-support.patch +new file mode 100644 +index 0000000000..de96162e8a +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/131-dts-mt7622-add-snand-support.patch +@@ -0,0 +1,96 @@ ++--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi +++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi ++@@ -554,6 +554,19 @@ ++ status = "disabled"; ++ }; ++ +++ snfi: spi@1100d000 { +++ compatible = "mediatek,mt7622-snfi"; +++ reg = <0 0x1100d000 0 0x1000>; +++ interrupts = ; +++ clocks = <&pericfg CLK_PERI_NFI_PD>, +++ <&pericfg CLK_PERI_SNFI_PD>; +++ clock-names = "nfi_clk", "spi_clk"; +++ ecc-engine = <&bch>; +++ #address-cells = <1>; +++ #size-cells = <0>; +++ status = "disabled"; +++ }; +++ ++ nor_flash: spi@11014000 { ++ compatible = "mediatek,mt7622-nor", ++ "mediatek,mt8173-nor"; ++--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts +++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts ++@@ -85,7 +85,7 @@ ++ }; ++ ++ &bch { ++- status = "disabled"; +++ status = "okay"; ++ }; ++ ++ &btif { ++@@ -529,6 +529,62 @@ ++ status = "disabled"; ++ }; ++ +++&snfi { +++ pinctrl-names = "default"; +++ pinctrl-0 = <&serial_nand_pins>; +++ status = "okay"; +++ +++ spi_nand@0 { +++ #address-cells = <1>; +++ #size-cells = <1>; +++ compatible = "spi-nand"; +++ spi-max-frequency = <104000000>; +++ reg = <0>; +++ +++ partitions { +++ compatible = "fixed-partitions"; +++ #address-cells = <1>; +++ #size-cells = <1>; +++ +++ partition@0 { +++ label = "Preloader"; +++ reg = <0x00000 0x0080000>; +++ read-only; +++ }; +++ +++ partition@80000 { +++ label = "ATF"; +++ reg = <0x80000 0x0040000>; +++ }; +++ +++ partition@c0000 { +++ label = "Bootloader"; +++ reg = <0xc0000 0x0080000>; +++ }; +++ +++ partition@140000 { +++ label = "Config"; +++ reg = <0x140000 0x0080000>; +++ }; +++ +++ partition@1c0000 { +++ label = "Factory"; +++ reg = <0x1c0000 0x0100000>; +++ }; +++ +++ partition@200000 { +++ label = "firmware"; +++ reg = <0x2c0000 0x2000000>; +++ }; +++ +++ partition@2200000 { +++ label = "User_data"; +++ reg = <0x22c0000 0x4000000>; +++ }; +++ }; +++ }; +++}; +++ ++ &spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spic0_pins>; +diff --git a/target/linux/mediatek/patches-5.10/140-dts-fix-wmac-support-for-mt7622-rfb1.patch b/target/linux/mediatek/patches-5.10/140-dts-fix-wmac-support-for-mt7622-rfb1.patch +new file mode 100644 +index 0000000000..d6d471520f +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/140-dts-fix-wmac-support-for-mt7622-rfb1.patch +@@ -0,0 +1,18 @@ ++--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts +++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts ++@@ -567,7 +567,7 @@ ++ reg = <0x140000 0x0080000>; ++ }; ++ ++- partition@1c0000 { +++ factory: partition@1c0000 { ++ label = "Factory"; ++ reg = <0x1c0000 0x0100000>; ++ }; ++@@ -626,5 +626,6 @@ ++ }; ++ ++ &wmac { +++ mediatek,mtd-eeprom = <&factory 0x0000>; ++ status = "okay"; ++ }; +diff --git a/target/linux/mediatek/patches-5.10/150-dts-mt7623-eip97-inside-secure-support.patch b/target/linux/mediatek/patches-5.10/150-dts-mt7623-eip97-inside-secure-support.patch +new file mode 100644 +index 0000000000..38947a3a94 +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/150-dts-mt7623-eip97-inside-secure-support.patch +@@ -0,0 +1,23 @@ ++--- a/arch/arm/boot/dts/mt7623.dtsi +++++ b/arch/arm/boot/dts/mt7623.dtsi ++@@ -949,17 +949,14 @@ ++ }; ++ ++ crypto: crypto@1b240000 { ++- compatible = "mediatek,eip97-crypto"; +++ compatible = "inside-secure,safexcel-eip97"; ++ reg = <0 0x1b240000 0 0x20000>; ++ interrupts = , ++ , ++ , ++- , ++- ; +++ ; +++ interrupt-names = "ring0", "ring1", "ring2", "ring3"; ++ clocks = <ðsys CLK_ETHSYS_CRYPTO>; ++- clock-names = "cryp"; ++- power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>; ++- status = "disabled"; ++ }; ++ ++ bdpsys: syscon@1c000000 { +diff --git a/target/linux/mediatek/patches-5.10/200-phy-phy-mtk-tphy-Add-hifsys-support.patch b/target/linux/mediatek/patches-5.10/200-phy-phy-mtk-tphy-Add-hifsys-support.patch +new file mode 100644 +index 0000000000..bd24ddc0c0 +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/200-phy-phy-mtk-tphy-Add-hifsys-support.patch +@@ -0,0 +1,66 @@ ++From 28f9a5e2a3f5441ab5594669ed82da11e32277a9 Mon Sep 17 00:00:00 2001 ++From: Kristian Evensen ++Date: Mon, 30 Apr 2018 14:38:01 +0200 ++Subject: [PATCH] phy: phy-mtk-tphy: Add hifsys-support ++ ++--- ++ drivers/phy/mediatek/phy-mtk-tphy.c | 20 ++++++++++++++++++++ ++ 1 file changed, 20 insertions(+) ++ ++--- a/drivers/phy/mediatek/phy-mtk-tphy.c +++++ b/drivers/phy/mediatek/phy-mtk-tphy.c ++@@ -15,6 +15,8 @@ ++ #include ++ #include ++ #include +++#include +++#include ++ ++ /* version V1 sub-banks offset base address */ ++ /* banks shared by multiple phys */ ++@@ -267,6 +269,9 @@ ++ #define RG_CDR_BIRLTD0_GEN3_MSK GENMASK(4, 0) ++ #define RG_CDR_BIRLTD0_GEN3_VAL(x) (0x1f & (x)) ++ +++#define HIF_SYSCFG1 0x14 +++#define HIF_SYSCFG1_PHY2_MASK (0x3 << 20) +++ ++ enum mtk_phy_version { ++ MTK_PHY_V1 = 1, ++ MTK_PHY_V2, ++@@ -315,6 +320,7 @@ struct mtk_tphy { ++ void __iomem *sif_base; /* only shared sif */ ++ const struct mtk_phy_pdata *pdata; ++ struct mtk_phy_instance **phys; +++ struct regmap *hif; ++ int nphys; ++ int src_ref_clk; /* MHZ, reference clock for slew rate calibrate */ ++ int src_coef; /* coefficient for slew rate calibrate */ ++@@ -634,6 +640,10 @@ static void pcie_phy_instance_init(struc ++ if (tphy->pdata->version != MTK_PHY_V1) ++ return; ++ +++ if (tphy->hif) +++ regmap_update_bits(tphy->hif, HIF_SYSCFG1, +++ HIF_SYSCFG1_PHY2_MASK, 0); +++ ++ tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG0); ++ tmp &= ~(P3A_RG_XTAL_EXT_PE1H | P3A_RG_XTAL_EXT_PE2H); ++ tmp |= P3A_RG_XTAL_EXT_PE1H_VAL(0x2) | P3A_RG_XTAL_EXT_PE2H_VAL(0x2); ++@@ -1134,6 +1144,16 @@ static int mtk_tphy_probe(struct platfor ++ &tphy->src_ref_clk); ++ device_property_read_u32(dev, "mediatek,src-coef", &tphy->src_coef); ++ +++ if (of_find_property(np, "mediatek,phy-switch", NULL)) { +++ tphy->hif = syscon_regmap_lookup_by_phandle(np, +++ "mediatek,phy-switch"); +++ if (IS_ERR(tphy->hif)) { +++ dev_err(&pdev->dev, +++ "missing \"mediatek,phy-switch\" phandle\n"); +++ return PTR_ERR(tphy->hif); +++ } +++ } +++ ++ port = 0; ++ for_each_child_of_node(np, child_np) { ++ struct mtk_phy_instance *instance; +diff --git a/target/linux/mediatek/patches-5.10/300-mtd-mtk-ecc-move-mtk-ecc-header-file-to-include-mtd.patch b/target/linux/mediatek/patches-5.10/300-mtd-mtk-ecc-move-mtk-ecc-header-file-to-include-mtd.patch +new file mode 100644 +index 0000000000..d9ab339fa8 +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/300-mtd-mtk-ecc-move-mtk-ecc-header-file-to-include-mtd.patch +@@ -0,0 +1,139 @@ ++From a2479dc254ebe31c84fbcfda73f35e2321576494 Mon Sep 17 00:00:00 2001 ++From: Xiangsheng Hou ++Date: Tue, 19 Mar 2019 13:57:38 +0800 ++Subject: [PATCH 1/6] mtd: mtk ecc: move mtk ecc header file to include/mtd ++ ++Change-Id: I8dc1d30e21b40d68ef5efd9587012f82970156a5 ++Signed-off-by: Xiangsheng Hou ++--- ++ drivers/mtd/nand/raw/mtk_ecc.c | 3 +-- ++ drivers/mtd/nand/raw/mtk_nand.c | 2 +- ++ {drivers/mtd/nand/raw => include/linux/mtd}/mtk_ecc.h | 0 ++ 3 files changed, 2 insertions(+), 3 deletions(-) ++ rename {drivers/mtd/nand/raw => include/linux/mtd}/mtk_ecc.h (100%) ++ ++--- a/drivers/mtd/nand/raw/mtk_ecc.c +++++ b/drivers/mtd/nand/raw/mtk_ecc.c ++@@ -15,8 +15,7 @@ ++ #include ++ #include ++ #include ++- ++-#include "mtk_ecc.h" +++#include ++ ++ #define ECC_IDLE_MASK BIT(0) ++ #define ECC_IRQ_EN BIT(0) ++--- a/drivers/mtd/nand/raw/mtk_nand.c +++++ b/drivers/mtd/nand/raw/mtk_nand.c ++@@ -17,7 +17,7 @@ ++ #include ++ #include ++ #include ++-#include "mtk_ecc.h" +++#include ++ ++ /* NAND controller register definition */ ++ #define NFI_CNFG (0x00) ++--- /dev/null +++++ b/include/linux/mtd/mtk_ecc.h ++@@ -0,0 +1,49 @@ +++/* +++ * MTK SDG1 ECC controller +++ * +++ * Copyright (c) 2016 Mediatek +++ * Authors: Xiaolei Li +++ * Jorge Ramirez-Ortiz +++ * This program is free software; you can redistribute it and/or modify it +++ * under the terms of the GNU General Public License version 2 as published +++ * by the Free Software Foundation. +++ */ +++ +++#ifndef __DRIVERS_MTD_NAND_MTK_ECC_H__ +++#define __DRIVERS_MTD_NAND_MTK_ECC_H__ +++ +++#include +++ +++enum mtk_ecc_mode {ECC_DMA_MODE = 0, ECC_NFI_MODE = 1}; +++enum mtk_ecc_operation {ECC_ENCODE, ECC_DECODE}; +++ +++struct device_node; +++struct mtk_ecc; +++ +++struct mtk_ecc_stats { +++ u32 corrected; +++ u32 bitflips; +++ u32 failed; +++}; +++ +++struct mtk_ecc_config { +++ enum mtk_ecc_operation op; +++ enum mtk_ecc_mode mode; +++ dma_addr_t addr; +++ u32 strength; +++ u32 sectors; +++ u32 len; +++}; +++ +++int mtk_ecc_encode(struct mtk_ecc *, struct mtk_ecc_config *, u8 *, u32); +++void mtk_ecc_get_stats(struct mtk_ecc *, struct mtk_ecc_stats *, int); +++int mtk_ecc_wait_done(struct mtk_ecc *, enum mtk_ecc_operation); +++int mtk_ecc_enable(struct mtk_ecc *, struct mtk_ecc_config *); +++void mtk_ecc_disable(struct mtk_ecc *); +++void mtk_ecc_adjust_strength(struct mtk_ecc *ecc, u32 *p); +++unsigned int mtk_ecc_get_parity_bits(struct mtk_ecc *ecc); +++ +++struct mtk_ecc *of_mtk_ecc_get(struct device_node *); +++void mtk_ecc_release(struct mtk_ecc *); +++ +++#endif ++--- a/drivers/mtd/nand/raw/mtk_ecc.h +++++ /dev/null ++@@ -1,47 +0,0 @@ ++-/* SPDX-License-Identifier: GPL-2.0 OR MIT */ ++-/* ++- * MTK SDG1 ECC controller ++- * ++- * Copyright (c) 2016 Mediatek ++- * Authors: Xiaolei Li ++- * Jorge Ramirez-Ortiz ++- */ ++- ++-#ifndef __DRIVERS_MTD_NAND_MTK_ECC_H__ ++-#define __DRIVERS_MTD_NAND_MTK_ECC_H__ ++- ++-#include ++- ++-enum mtk_ecc_mode {ECC_DMA_MODE = 0, ECC_NFI_MODE = 1}; ++-enum mtk_ecc_operation {ECC_ENCODE, ECC_DECODE}; ++- ++-struct device_node; ++-struct mtk_ecc; ++- ++-struct mtk_ecc_stats { ++- u32 corrected; ++- u32 bitflips; ++- u32 failed; ++-}; ++- ++-struct mtk_ecc_config { ++- enum mtk_ecc_operation op; ++- enum mtk_ecc_mode mode; ++- dma_addr_t addr; ++- u32 strength; ++- u32 sectors; ++- u32 len; ++-}; ++- ++-int mtk_ecc_encode(struct mtk_ecc *, struct mtk_ecc_config *, u8 *, u32); ++-void mtk_ecc_get_stats(struct mtk_ecc *, struct mtk_ecc_stats *, int); ++-int mtk_ecc_wait_done(struct mtk_ecc *, enum mtk_ecc_operation); ++-int mtk_ecc_enable(struct mtk_ecc *, struct mtk_ecc_config *); ++-void mtk_ecc_disable(struct mtk_ecc *); ++-void mtk_ecc_adjust_strength(struct mtk_ecc *ecc, u32 *p); ++-unsigned int mtk_ecc_get_parity_bits(struct mtk_ecc *ecc); ++- ++-struct mtk_ecc *of_mtk_ecc_get(struct device_node *); ++-void mtk_ecc_release(struct mtk_ecc *); ++- ++-#endif +diff --git a/target/linux/mediatek/patches-5.10/310-mtd-spinand-disable-on-die-ECC.patch b/target/linux/mediatek/patches-5.10/310-mtd-spinand-disable-on-die-ECC.patch +new file mode 100644 +index 0000000000..e608113865 +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/310-mtd-spinand-disable-on-die-ECC.patch +@@ -0,0 +1,31 @@ ++From b341f120cfc9ca1dfd48364b7f36ac2c1fbdea43 Mon Sep 17 00:00:00 2001 ++From: Xiangsheng Hou ++Date: Wed, 3 Apr 2019 16:30:01 +0800 ++Subject: [PATCH 3/6] mtd: spinand: disable on-die ECC ++ ++Change-Id: I9745adaed5295202fabbe8ab8947885c57a5b847 ++Signed-off-by: Xiangsheng Hou ++--- ++ drivers/mtd/nand/spi/core.c | 4 ++-- ++ 1 file changed, 2 insertions(+), 2 deletions(-) ++ ++--- a/drivers/mtd/nand/spi/core.c +++++ b/drivers/mtd/nand/spi/core.c ++@@ -493,7 +493,7 @@ static int spinand_mtd_read(struct mtd_i ++ int ret = 0; ++ ++ if (ops->mode != MTD_OPS_RAW && spinand->eccinfo.ooblayout) ++- enable_ecc = true; +++ enable_ecc = false; ++ ++ mutex_lock(&spinand->lock); ++ ++@@ -541,7 +541,7 @@ static int spinand_mtd_write(struct mtd_ ++ int ret = 0; ++ ++ if (ops->mode != MTD_OPS_RAW && mtd->ooblayout) ++- enable_ecc = true; +++ enable_ecc = false; ++ ++ mutex_lock(&spinand->lock); ++ +diff --git a/target/linux/mediatek/patches-5.10/320-spi-spi-mem-MediaTek-Add-SPI-NAND-Flash-interface-dr.patch b/target/linux/mediatek/patches-5.10/320-spi-spi-mem-MediaTek-Add-SPI-NAND-Flash-interface-dr.patch +new file mode 100644 +index 0000000000..53e2aed51e +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/320-spi-spi-mem-MediaTek-Add-SPI-NAND-Flash-interface-dr.patch +@@ -0,0 +1,1246 @@ ++From 1ecb38eabd90efe93957d0a822a167560c39308a Mon Sep 17 00:00:00 2001 ++From: Xiangsheng Hou ++Date: Wed, 20 Mar 2019 16:19:51 +0800 ++Subject: [PATCH 6/6] spi: spi-mem: MediaTek: Add SPI NAND Flash interface ++ driver for MediaTek MT7622 ++ ++Change-Id: I3e78406bb9b46b0049d3988a5c71c7069e4f809c ++Signed-off-by: Xiangsheng Hou ++--- ++ drivers/spi/Kconfig | 9 + ++ drivers/spi/Makefile | 1 + ++ drivers/spi/spi-mtk-snfi.c | 1183 ++++++++++++++++++++++++++++++++++++ ++ 3 files changed, 1193 insertions(+) ++ create mode 100644 drivers/spi/spi-mtk-snfi.c ++ ++--- a/drivers/spi/Makefile +++++ b/drivers/spi/Makefile ++@@ -67,6 +67,7 @@ obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mp ++ obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o ++ obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o ++ obj-$(CONFIG_SPI_MT65XX) += spi-mt65xx.o +++obj-$(CONFIG_SPI_MTK_SNFI) += spi-mtk-snfi.o ++ obj-$(CONFIG_SPI_MT7621) += spi-mt7621.o ++ obj-$(CONFIG_SPI_MTK_NOR) += spi-mtk-nor.o ++ obj-$(CONFIG_SPI_MXIC) += spi-mxic.o ++--- a/drivers/spi/Kconfig +++++ b/drivers/spi/Kconfig ++@@ -495,6 +495,15 @@ config SPI_MT65XX ++ say Y or M here.If you are not sure, say N. ++ SPI drivers for Mediatek MT65XX and MT81XX series ARM SoCs. ++ +++config SPI_MTK_SNFI +++ tristate "MediaTek SPI NAND interface" +++ select MTD_SPI_NAND +++ help +++ This selects the SPI NAND FLASH interface(SNFI), +++ which could be found on MediaTek Soc. +++ Say Y or M here.If you are not sure, say N. +++ Note Parallel Nand and SPI NAND is alternative on MediaTek SoCs. +++ ++ config SPI_MT7621 ++ tristate "MediaTek MT7621 SPI Controller" ++ depends on RALINK || COMPILE_TEST ++--- /dev/null +++++ b/drivers/spi/spi-mtk-snfi.c ++@@ -0,0 +1,1200 @@ +++// SPDX-License-Identifier: GPL-2.0 +++/* +++ * Driver for MediaTek SPI Nand interface +++ * +++ * Copyright (C) 2018 MediaTek Inc. +++ * Authors: Xiangsheng Hou +++ * +++ */ +++ +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++ +++/* NAND controller register definition */ +++/* NFI control */ +++#define NFI_CNFG 0x00 +++#define CNFG_DMA BIT(0) +++#define CNFG_READ_EN BIT(1) +++#define CNFG_DMA_BURST_EN BIT(2) +++#define CNFG_BYTE_RW BIT(6) +++#define CNFG_HW_ECC_EN BIT(8) +++#define CNFG_AUTO_FMT_EN BIT(9) +++#define CNFG_OP_PROGRAM (3UL << 12) +++#define CNFG_OP_CUST (6UL << 12) +++#define NFI_PAGEFMT 0x04 +++#define PAGEFMT_512 0 +++#define PAGEFMT_2K 1 +++#define PAGEFMT_4K 2 +++#define PAGEFMT_FDM_SHIFT 8 +++#define PAGEFMT_FDM_ECC_SHIFT 12 +++#define NFI_CON 0x08 +++#define CON_FIFO_FLUSH BIT(0) +++#define CON_NFI_RST BIT(1) +++#define CON_BRD BIT(8) +++#define CON_BWR BIT(9) +++#define CON_SEC_SHIFT 12 +++#define NFI_INTR_EN 0x10 +++#define INTR_AHB_DONE_EN BIT(6) +++#define NFI_INTR_STA 0x14 +++#define NFI_CMD 0x20 +++#define NFI_STA 0x60 +++#define STA_EMP_PAGE BIT(12) +++#define NAND_FSM_MASK (0x1f << 24) +++#define NFI_FSM_MASK (0xf << 16) +++#define NFI_ADDRCNTR 0x70 +++#define CNTR_MASK GENMASK(16, 12) +++#define ADDRCNTR_SEC_SHIFT 12 +++#define ADDRCNTR_SEC(val) \ +++ (((val) & CNTR_MASK) >> ADDRCNTR_SEC_SHIFT) +++#define NFI_STRADDR 0x80 +++#define NFI_BYTELEN 0x84 +++#define NFI_CSEL 0x90 +++#define NFI_FDML(x) (0xa0 + (x) * sizeof(u32) * 2) +++#define NFI_FDMM(x) (0xa4 + (x) * sizeof(u32) * 2) +++#define NFI_MASTER_STA 0x224 +++#define MASTER_STA_MASK 0x0fff +++/* NFI_SPI control */ +++#define SNFI_MAC_OUTL 0x504 +++#define SNFI_MAC_INL 0x508 +++#define SNFI_RD_CTL2 0x510 +++#define RD_CMD_MASK 0x00ff +++#define RD_DUMMY_SHIFT 8 +++#define SNFI_RD_CTL3 0x514 +++#define RD_ADDR_MASK 0xffff +++#define SNFI_MISC_CTL 0x538 +++#define RD_MODE_X2 BIT(16) +++#define RD_MODE_X4 (2UL << 16) +++#define RD_QDUAL_IO (4UL << 16) +++#define RD_MODE_MASK (7UL << 16) +++#define RD_CUSTOM_EN BIT(6) +++#define WR_CUSTOM_EN BIT(7) +++#define WR_X4_EN BIT(20) +++#define SW_RST BIT(28) +++#define SNFI_MISC_CTL2 0x53c +++#define WR_LEN_SHIFT 16 +++#define SNFI_PG_CTL1 0x524 +++#define WR_LOAD_CMD_SHIFT 8 +++#define SNFI_PG_CTL2 0x528 +++#define WR_LOAD_ADDR_MASK 0xffff +++#define SNFI_MAC_CTL 0x500 +++#define MAC_WIP BIT(0) +++#define MAC_WIP_READY BIT(1) +++#define MAC_TRIG BIT(2) +++#define MAC_EN BIT(3) +++#define MAC_SIO_SEL BIT(4) +++#define SNFI_STA_CTL1 0x550 +++#define SPI_STATE_IDLE 0xf +++#define SNFI_CNFG 0x55c +++#define SNFI_MODE_EN BIT(0) +++#define SNFI_GPRAM_DATA 0x800 +++#define SNFI_GPRAM_MAX_LEN 16 +++ +++/* Dummy command trigger NFI to spi mode */ +++#define NAND_CMD_DUMMYREAD 0x00 +++#define NAND_CMD_DUMMYPROG 0x80 +++ +++#define MTK_TIMEOUT 500000 +++#define MTK_RESET_TIMEOUT 1000000 +++#define MTK_SNFC_MIN_SPARE 16 +++#define KB(x) ((x) * 1024UL) +++ +++/* +++ * supported spare size of each IP. +++ * order should be the same with the spare size bitfiled defination of +++ * register NFI_PAGEFMT. +++ */ +++static const u8 spare_size_mt7622[] = { +++ 16, 26, 27, 28 +++}; +++ +++struct mtk_snfi_caps { +++ const u8 *spare_size; +++ u8 num_spare_size; +++ u32 nand_sec_size; +++ u8 nand_fdm_size; +++ u8 nand_fdm_ecc_size; +++ u8 ecc_parity_bits; +++ u8 pageformat_spare_shift; +++ u8 bad_mark_swap; +++}; +++ +++struct mtk_snfi_bad_mark_ctl { +++ void (*bm_swap)(struct spi_mem *mem, u8 *buf, int raw); +++ u32 sec; +++ u32 pos; +++}; +++ +++struct mtk_snfi_nand_chip { +++ struct mtk_snfi_bad_mark_ctl bad_mark; +++ u32 spare_per_sector; +++}; +++ +++struct mtk_snfi_clk { +++ struct clk *nfi_clk; +++ struct clk *spi_clk; +++}; +++ +++struct mtk_snfi { +++ const struct mtk_snfi_caps *caps; +++ struct mtk_snfi_nand_chip snfi_nand; +++ struct mtk_snfi_clk clk; +++ struct mtk_ecc_config ecc_cfg; +++ struct mtk_ecc *ecc; +++ struct completion done; +++ struct device *dev; +++ +++ void __iomem *regs; +++ +++ u8 *buffer; +++}; +++ +++static inline u8 *oob_ptr(struct spi_mem *mem, int i) +++{ +++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); +++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); +++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; +++ u8 *poi; +++ +++ /* map the sector's FDM data to free oob: +++ * the beginning of the oob area stores the FDM data of bad mark +++ */ +++ +++ if (i < snfi_nand->bad_mark.sec) +++ poi = spinand->oobbuf + (i + 1) * snfi->caps->nand_fdm_size; +++ else if (i == snfi_nand->bad_mark.sec) +++ poi = spinand->oobbuf; +++ else +++ poi = spinand->oobbuf + i * snfi->caps->nand_fdm_size; +++ +++ return poi; +++} +++ +++static inline int mtk_data_len(struct spi_mem *mem) +++{ +++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); +++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; +++ +++ return snfi->caps->nand_sec_size + snfi_nand->spare_per_sector; +++} +++ +++static inline u8 *mtk_oob_ptr(struct spi_mem *mem, +++ const u8 *p, int i) +++{ +++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); +++ +++ return (u8 *)p + i * mtk_data_len(mem) + snfi->caps->nand_sec_size; +++} +++ +++static void mtk_snfi_bad_mark_swap(struct spi_mem *mem, +++ u8 *buf, int raw) +++{ +++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); +++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); +++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; +++ u32 bad_pos = snfi_nand->bad_mark.pos; +++ +++ if (raw) +++ bad_pos += snfi_nand->bad_mark.sec * mtk_data_len(mem); +++ else +++ bad_pos += snfi_nand->bad_mark.sec * snfi->caps->nand_sec_size; +++ +++ swap(spinand->oobbuf[0], buf[bad_pos]); +++} +++ +++static void mtk_snfi_set_bad_mark_ctl(struct mtk_snfi_bad_mark_ctl *bm_ctl, +++ struct spi_mem *mem) +++{ +++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); +++ struct mtd_info *mtd = spinand_to_mtd(spinand); +++ +++ bm_ctl->bm_swap = mtk_snfi_bad_mark_swap; +++ bm_ctl->sec = mtd->writesize / mtk_data_len(mem); +++ bm_ctl->pos = mtd->writesize % mtk_data_len(mem); +++} +++ +++static void mtk_snfi_mac_enable(struct mtk_snfi *snfi) +++{ +++ u32 mac; +++ +++ mac = readl(snfi->regs + SNFI_MAC_CTL); +++ mac &= ~MAC_SIO_SEL; +++ mac |= MAC_EN; +++ +++ writel(mac, snfi->regs + SNFI_MAC_CTL); +++} +++ +++static int mtk_snfi_mac_trigger(struct mtk_snfi *snfi) +++{ +++ u32 mac, reg; +++ int ret = 0; +++ +++ mac = readl(snfi->regs + SNFI_MAC_CTL); +++ mac |= MAC_TRIG; +++ writel(mac, snfi->regs + SNFI_MAC_CTL); +++ +++ ret = readl_poll_timeout_atomic(snfi->regs + SNFI_MAC_CTL, reg, +++ reg & MAC_WIP_READY, 10, +++ MTK_TIMEOUT); +++ if (ret < 0) { +++ dev_err(snfi->dev, "polling wip ready for read timeout\n"); +++ return -EIO; +++ } +++ +++ ret = readl_poll_timeout_atomic(snfi->regs + SNFI_MAC_CTL, reg, +++ !(reg & MAC_WIP), 10, +++ MTK_TIMEOUT); +++ if (ret < 0) { +++ dev_err(snfi->dev, "polling flash update timeout\n"); +++ return -EIO; +++ } +++ +++ return ret; +++} +++ +++static void mtk_snfi_mac_leave(struct mtk_snfi *snfi) +++{ +++ u32 mac; +++ +++ mac = readl(snfi->regs + SNFI_MAC_CTL); +++ mac &= ~(MAC_TRIG | MAC_EN | MAC_SIO_SEL); +++ writel(mac, snfi->regs + SNFI_MAC_CTL); +++} +++ +++static int mtk_snfi_mac_op(struct mtk_snfi *snfi) +++{ +++ int ret = 0; +++ +++ mtk_snfi_mac_enable(snfi); +++ +++ ret = mtk_snfi_mac_trigger(snfi); +++ if (ret) +++ return ret; +++ +++ mtk_snfi_mac_leave(snfi); +++ +++ return ret; +++} +++ +++static irqreturn_t mtk_snfi_irq(int irq, void *id) +++{ +++ struct mtk_snfi *snfi = id; +++ u16 sta, ien; +++ +++ sta = readw(snfi->regs + NFI_INTR_STA); +++ ien = readw(snfi->regs + NFI_INTR_EN); +++ +++ if (!(sta & ien)) +++ return IRQ_NONE; +++ +++ writew(~sta & ien, snfi->regs + NFI_INTR_EN); +++ complete(&snfi->done); +++ +++ return IRQ_HANDLED; +++} +++ +++static int mtk_snfi_enable_clk(struct device *dev, struct mtk_snfi_clk *clk) +++{ +++ int ret; +++ +++ ret = clk_prepare_enable(clk->nfi_clk); +++ if (ret) { +++ dev_err(dev, "failed to enable nfi clk\n"); +++ return ret; +++ } +++ +++ ret = clk_prepare_enable(clk->spi_clk); +++ if (ret) { +++ dev_err(dev, "failed to enable spi clk\n"); +++ clk_disable_unprepare(clk->nfi_clk); +++ return ret; +++ } +++ +++ return 0; +++} +++ +++static void mtk_snfi_disable_clk(struct mtk_snfi_clk *clk) +++{ +++ clk_disable_unprepare(clk->nfi_clk); +++ clk_disable_unprepare(clk->spi_clk); +++} +++ +++static int mtk_snfi_reset(struct mtk_snfi *snfi) +++{ +++ u32 val; +++ int ret; +++ +++ /* SW reset controller */ +++ val = readl(snfi->regs + SNFI_MISC_CTL) | SW_RST; +++ writel(val, snfi->regs + SNFI_MISC_CTL); +++ +++ ret = readw_poll_timeout(snfi->regs + SNFI_STA_CTL1, val, +++ !(val & SPI_STATE_IDLE), 50, +++ MTK_RESET_TIMEOUT); +++ if (ret) { +++ dev_warn(snfi->dev, "spi state active in reset [0x%x] = 0x%x\n", +++ SNFI_STA_CTL1, val); +++ return ret; +++ } +++ +++ val = readl(snfi->regs + SNFI_MISC_CTL); +++ val &= ~SW_RST; +++ writel(val, snfi->regs + SNFI_MISC_CTL); +++ +++ /* reset all registers and force the NFI master to terminate */ +++ writew(CON_FIFO_FLUSH | CON_NFI_RST, snfi->regs + NFI_CON); +++ ret = readw_poll_timeout(snfi->regs + NFI_STA, val, +++ !(val & (NFI_FSM_MASK | NAND_FSM_MASK)), 50, +++ MTK_RESET_TIMEOUT); +++ if (ret) { +++ dev_warn(snfi->dev, "nfi active in reset [0x%x] = 0x%x\n", +++ NFI_STA, val); +++ return ret; +++ } +++ +++ return 0; +++} +++ +++static int mtk_snfi_set_spare_per_sector(struct spinand_device *spinand, +++ const struct mtk_snfi_caps *caps, +++ u32 *sps) +++{ +++ struct mtd_info *mtd = spinand_to_mtd(spinand); +++ const u8 *spare = caps->spare_size; +++ u32 sectors, i, closest_spare = 0; +++ +++ sectors = mtd->writesize / caps->nand_sec_size; +++ *sps = mtd->oobsize / sectors; +++ +++ if (*sps < MTK_SNFC_MIN_SPARE) +++ return -EINVAL; +++ +++ for (i = 0; i < caps->num_spare_size; i++) { +++ if (*sps >= spare[i] && spare[i] >= spare[closest_spare]) { +++ closest_spare = i; +++ if (*sps == spare[i]) +++ break; +++ } +++ } +++ +++ *sps = spare[closest_spare]; +++ +++ return 0; +++} +++ +++static void mtk_snfi_read_fdm_data(struct spi_mem *mem, +++ u32 sectors) +++{ +++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); +++ const struct mtk_snfi_caps *caps = snfi->caps; +++ u32 vall, valm; +++ int i, j; +++ u8 *oobptr; +++ +++ for (i = 0; i < sectors; i++) { +++ oobptr = oob_ptr(mem, i); +++ vall = readl(snfi->regs + NFI_FDML(i)); +++ valm = readl(snfi->regs + NFI_FDMM(i)); +++ +++ for (j = 0; j < caps->nand_fdm_size; j++) +++ oobptr[j] = (j >= 4 ? valm : vall) >> ((j % 4) * 8); +++ } +++} +++ +++static void mtk_snfi_write_fdm_data(struct spi_mem *mem, +++ u32 sectors) +++{ +++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); +++ const struct mtk_snfi_caps *caps = snfi->caps; +++ u32 vall, valm; +++ int i, j; +++ u8 *oobptr; +++ +++ for (i = 0; i < sectors; i++) { +++ oobptr = oob_ptr(mem, i); +++ vall = 0; +++ valm = 0; +++ for (j = 0; j < 8; j++) { +++ if (j < 4) +++ vall |= (j < caps->nand_fdm_size ? oobptr[j] : +++ 0xff) << (j * 8); +++ else +++ valm |= (j < caps->nand_fdm_size ? oobptr[j] : +++ 0xff) << ((j - 4) * 8); +++ } +++ writel(vall, snfi->regs + NFI_FDML(i)); +++ writel(valm, snfi->regs + NFI_FDMM(i)); +++ } +++} +++ +++static int mtk_snfi_update_ecc_stats(struct spi_mem *mem, +++ u8 *buf, u32 sectors) +++{ +++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); +++ struct mtd_info *mtd = spinand_to_mtd(spinand); +++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); +++ struct mtk_ecc_stats stats; +++ int rc, i; +++ +++ rc = readl(snfi->regs + NFI_STA) & STA_EMP_PAGE; +++ if (rc) { +++ memset(buf, 0xff, sectors * snfi->caps->nand_sec_size); +++ for (i = 0; i < sectors; i++) +++ memset(spinand->oobbuf, 0xff, +++ snfi->caps->nand_fdm_size); +++ return 0; +++ } +++ +++ mtk_ecc_get_stats(snfi->ecc, &stats, sectors); +++ mtd->ecc_stats.corrected += stats.corrected; +++ mtd->ecc_stats.failed += stats.failed; +++ +++ return 0; +++} +++ +++static int mtk_snfi_hw_runtime_config(struct spi_mem *mem) +++{ +++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); +++ struct mtd_info *mtd = spinand_to_mtd(spinand); +++ struct nand_device *nand = mtd_to_nanddev(mtd); +++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); +++ const struct mtk_snfi_caps *caps = snfi->caps; +++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; +++ u32 fmt, spare, i = 0; +++ int ret; +++ +++ ret = mtk_snfi_set_spare_per_sector(spinand, caps, &spare); +++ if (ret) +++ return ret; +++ +++ /* calculate usable oob bytes for ecc parity data */ +++ snfi_nand->spare_per_sector = spare; +++ spare -= caps->nand_fdm_size; +++ +++ nand->memorg.oobsize = snfi_nand->spare_per_sector +++ * (mtd->writesize / caps->nand_sec_size); +++ mtd->oobsize = nanddev_per_page_oobsize(nand); +++ +++ snfi->ecc_cfg.strength = (spare << 3) / caps->ecc_parity_bits; +++ mtk_ecc_adjust_strength(snfi->ecc, &snfi->ecc_cfg.strength); +++ +++ switch (mtd->writesize) { +++ case 512: +++ fmt = PAGEFMT_512; +++ break; +++ case KB(2): +++ fmt = PAGEFMT_2K; +++ break; +++ case KB(4): +++ fmt = PAGEFMT_4K; +++ break; +++ default: +++ dev_err(snfi->dev, "invalid page len: %d\n", mtd->writesize); +++ return -EINVAL; +++ } +++ +++ /* Setup PageFormat */ +++ while (caps->spare_size[i] != snfi_nand->spare_per_sector) { +++ i++; +++ if (i == (caps->num_spare_size - 1)) { +++ dev_err(snfi->dev, "invalid spare size %d\n", +++ snfi_nand->spare_per_sector); +++ return -EINVAL; +++ } +++ } +++ +++ fmt |= i << caps->pageformat_spare_shift; +++ fmt |= caps->nand_fdm_size << PAGEFMT_FDM_SHIFT; +++ fmt |= caps->nand_fdm_ecc_size << PAGEFMT_FDM_ECC_SHIFT; +++ writel(fmt, snfi->regs + NFI_PAGEFMT); +++ +++ snfi->ecc_cfg.len = caps->nand_sec_size + caps->nand_fdm_ecc_size; +++ +++ mtk_snfi_set_bad_mark_ctl(&snfi_nand->bad_mark, mem); +++ +++ return 0; +++} +++ +++static int mtk_snfi_read_from_cache(struct spi_mem *mem, +++ const struct spi_mem_op *op, int oob_on) +++{ +++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); +++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); +++ struct mtd_info *mtd = spinand_to_mtd(spinand); +++ u32 sectors = mtd->writesize / snfi->caps->nand_sec_size; +++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; +++ u32 reg, len, col_addr = 0; +++ int dummy_cycle, ret; +++ dma_addr_t dma_addr; +++ +++ len = sectors * (snfi->caps->nand_sec_size +++ + snfi_nand->spare_per_sector); +++ +++ dma_addr = dma_map_single(snfi->dev, snfi->buffer, +++ len, DMA_FROM_DEVICE); +++ ret = dma_mapping_error(snfi->dev, dma_addr); +++ if (ret) { +++ dev_err(snfi->dev, "dma mapping error\n"); +++ return -EINVAL; +++ } +++ +++ /* set Read cache command and dummy cycle */ +++ dummy_cycle = (op->dummy.nbytes << 3) >> (ffs(op->dummy.buswidth) - 1); +++ reg = ((op->cmd.opcode & RD_CMD_MASK) | +++ (dummy_cycle << RD_DUMMY_SHIFT)); +++ writel(reg, snfi->regs + SNFI_RD_CTL2); +++ +++ writel((col_addr & RD_ADDR_MASK), snfi->regs + SNFI_RD_CTL3); +++ +++ reg = readl(snfi->regs + SNFI_MISC_CTL); +++ reg |= RD_CUSTOM_EN; +++ reg &= ~(RD_MODE_MASK | WR_X4_EN); +++ +++ /* set data and addr buswidth */ +++ if (op->data.buswidth == 4) +++ reg |= RD_MODE_X4; +++ else if (op->data.buswidth == 2) +++ reg |= RD_MODE_X2; +++ +++ if (op->addr.buswidth == 4 || op->addr.buswidth == 2) +++ reg |= RD_QDUAL_IO; +++ writel(reg, snfi->regs + SNFI_MISC_CTL); +++ +++ writel(len, snfi->regs + SNFI_MISC_CTL2); +++ writew(sectors << CON_SEC_SHIFT, snfi->regs + NFI_CON); +++ reg = readw(snfi->regs + NFI_CNFG); +++ reg |= CNFG_READ_EN | CNFG_DMA_BURST_EN | CNFG_DMA | CNFG_OP_CUST; +++ +++ if (!oob_on) { +++ reg |= CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN; +++ writew(reg, snfi->regs + NFI_CNFG); +++ +++ snfi->ecc_cfg.mode = ECC_NFI_MODE; +++ snfi->ecc_cfg.sectors = sectors; +++ snfi->ecc_cfg.op = ECC_DECODE; +++ ret = mtk_ecc_enable(snfi->ecc, &snfi->ecc_cfg); +++ if (ret) { +++ dev_err(snfi->dev, "ecc enable failed\n"); +++ /* clear NFI_CNFG */ +++ reg &= ~(CNFG_READ_EN | CNFG_DMA_BURST_EN | CNFG_DMA | +++ CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN); +++ writew(reg, snfi->regs + NFI_CNFG); +++ goto out; +++ } +++ } else { +++ writew(reg, snfi->regs + NFI_CNFG); +++ } +++ +++ writel(lower_32_bits(dma_addr), snfi->regs + NFI_STRADDR); +++ readw(snfi->regs + NFI_INTR_STA); +++ writew(INTR_AHB_DONE_EN, snfi->regs + NFI_INTR_EN); +++ +++ init_completion(&snfi->done); +++ +++ /* set dummy command to trigger NFI enter SPI mode */ +++ writew(NAND_CMD_DUMMYREAD, snfi->regs + NFI_CMD); +++ reg = readl(snfi->regs + NFI_CON) | CON_BRD; +++ writew(reg, snfi->regs + NFI_CON); +++ +++ ret = wait_for_completion_timeout(&snfi->done, msecs_to_jiffies(500)); +++ if (!ret) { +++ dev_err(snfi->dev, "read ahb done timeout\n"); +++ writew(0, snfi->regs + NFI_INTR_EN); +++ ret = -ETIMEDOUT; +++ goto out; +++ } +++ +++ ret = readl_poll_timeout_atomic(snfi->regs + NFI_BYTELEN, reg, +++ ADDRCNTR_SEC(reg) >= sectors, 10, +++ MTK_TIMEOUT); +++ if (ret < 0) { +++ dev_err(snfi->dev, "polling read byte len timeout\n"); +++ ret = -EIO; +++ } else { +++ if (!oob_on) { +++ ret = mtk_ecc_wait_done(snfi->ecc, ECC_DECODE); +++ if (ret) { +++ dev_warn(snfi->dev, "wait ecc done timeout\n"); +++ } else { +++ mtk_snfi_update_ecc_stats(mem, snfi->buffer, +++ sectors); +++ mtk_snfi_read_fdm_data(mem, sectors); +++ } +++ } +++ } +++ +++ if (oob_on) +++ goto out; +++ +++ mtk_ecc_disable(snfi->ecc); +++out: +++ dma_unmap_single(snfi->dev, dma_addr, len, DMA_FROM_DEVICE); +++ writel(0, snfi->regs + NFI_CON); +++ writel(0, snfi->regs + NFI_CNFG); +++ reg = readl(snfi->regs + SNFI_MISC_CTL); +++ reg &= ~RD_CUSTOM_EN; +++ writel(reg, snfi->regs + SNFI_MISC_CTL); +++ +++ return ret; +++} +++ +++static int mtk_snfi_write_to_cache(struct spi_mem *mem, +++ const struct spi_mem_op *op, +++ int oob_on) +++{ +++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); +++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); +++ struct mtd_info *mtd = spinand_to_mtd(spinand); +++ u32 sectors = mtd->writesize / snfi->caps->nand_sec_size; +++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; +++ u32 reg, len, col_addr = 0; +++ dma_addr_t dma_addr; +++ int ret; +++ +++ len = sectors * (snfi->caps->nand_sec_size +++ + snfi_nand->spare_per_sector); +++ +++ dma_addr = dma_map_single(snfi->dev, snfi->buffer, len, +++ DMA_TO_DEVICE); +++ ret = dma_mapping_error(snfi->dev, dma_addr); +++ if (ret) { +++ dev_err(snfi->dev, "dma mapping error\n"); +++ return -EINVAL; +++ } +++ +++ /* set program load cmd and address */ +++ reg = (op->cmd.opcode << WR_LOAD_CMD_SHIFT); +++ writel(reg, snfi->regs + SNFI_PG_CTL1); +++ writel(col_addr & WR_LOAD_ADDR_MASK, snfi->regs + SNFI_PG_CTL2); +++ +++ reg = readl(snfi->regs + SNFI_MISC_CTL); +++ reg |= WR_CUSTOM_EN; +++ reg &= ~(RD_MODE_MASK | WR_X4_EN); +++ +++ if (op->data.buswidth == 4) +++ reg |= WR_X4_EN; +++ writel(reg, snfi->regs + SNFI_MISC_CTL); +++ +++ writel(len << WR_LEN_SHIFT, snfi->regs + SNFI_MISC_CTL2); +++ writew(sectors << CON_SEC_SHIFT, snfi->regs + NFI_CON); +++ +++ reg = readw(snfi->regs + NFI_CNFG); +++ reg &= ~(CNFG_READ_EN | CNFG_BYTE_RW); +++ reg |= CNFG_DMA | CNFG_DMA_BURST_EN | CNFG_OP_PROGRAM; +++ +++ if (!oob_on) { +++ reg |= CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN; +++ writew(reg, snfi->regs + NFI_CNFG); +++ +++ snfi->ecc_cfg.mode = ECC_NFI_MODE; +++ snfi->ecc_cfg.op = ECC_ENCODE; +++ ret = mtk_ecc_enable(snfi->ecc, &snfi->ecc_cfg); +++ if (ret) { +++ dev_err(snfi->dev, "ecc enable failed\n"); +++ /* clear NFI_CNFG */ +++ reg &= ~(CNFG_DMA_BURST_EN | CNFG_DMA | +++ CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN); +++ writew(reg, snfi->regs + NFI_CNFG); +++ dma_unmap_single(snfi->dev, dma_addr, len, +++ DMA_FROM_DEVICE); +++ goto out; +++ } +++ /* write OOB into the FDM registers (OOB area in MTK NAND) */ +++ mtk_snfi_write_fdm_data(mem, sectors); +++ } else { +++ writew(reg, snfi->regs + NFI_CNFG); +++ } +++ writel(lower_32_bits(dma_addr), snfi->regs + NFI_STRADDR); +++ readw(snfi->regs + NFI_INTR_STA); +++ writew(INTR_AHB_DONE_EN, snfi->regs + NFI_INTR_EN); +++ +++ init_completion(&snfi->done); +++ +++ /* set dummy command to trigger NFI enter SPI mode */ +++ writew(NAND_CMD_DUMMYPROG, snfi->regs + NFI_CMD); +++ reg = readl(snfi->regs + NFI_CON) | CON_BWR; +++ writew(reg, snfi->regs + NFI_CON); +++ +++ ret = wait_for_completion_timeout(&snfi->done, msecs_to_jiffies(500)); +++ if (!ret) { +++ dev_err(snfi->dev, "custom program done timeout\n"); +++ writew(0, snfi->regs + NFI_INTR_EN); +++ ret = -ETIMEDOUT; +++ goto ecc_disable; +++ } +++ +++ ret = readl_poll_timeout_atomic(snfi->regs + NFI_ADDRCNTR, reg, +++ ADDRCNTR_SEC(reg) >= sectors, +++ 10, MTK_TIMEOUT); +++ if (ret) +++ dev_err(snfi->dev, "hwecc write timeout\n"); +++ +++ecc_disable: +++ mtk_ecc_disable(snfi->ecc); +++ +++out: +++ dma_unmap_single(snfi->dev, dma_addr, len, DMA_TO_DEVICE); +++ writel(0, snfi->regs + NFI_CON); +++ writel(0, snfi->regs + NFI_CNFG); +++ reg = readl(snfi->regs + SNFI_MISC_CTL); +++ reg &= ~WR_CUSTOM_EN; +++ writel(reg, snfi->regs + SNFI_MISC_CTL); +++ +++ return ret; +++} +++ +++static int mtk_snfi_read(struct spi_mem *mem, +++ const struct spi_mem_op *op) +++{ +++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); +++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); +++ struct mtd_info *mtd = spinand_to_mtd(spinand); +++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; +++ u32 col_addr = op->addr.val; +++ int i, ret, sectors, oob_on = false; +++ +++ if (col_addr == mtd->writesize) +++ oob_on = true; +++ +++ ret = mtk_snfi_read_from_cache(mem, op, oob_on); +++ if (ret) { +++ dev_warn(snfi->dev, "read from cache fail\n"); +++ return ret; +++ } +++ +++ sectors = mtd->writesize / snfi->caps->nand_sec_size; +++ for (i = 0; i < sectors; i++) { +++ if (oob_on) +++ memcpy(oob_ptr(mem, i), +++ mtk_oob_ptr(mem, snfi->buffer, i), +++ snfi->caps->nand_fdm_size); +++ +++ if (i == snfi_nand->bad_mark.sec && snfi->caps->bad_mark_swap) +++ snfi_nand->bad_mark.bm_swap(mem, snfi->buffer, +++ oob_on); +++ } +++ +++ if (!oob_on) +++ memcpy(spinand->databuf, snfi->buffer, mtd->writesize); +++ +++ return ret; +++} +++ +++static int mtk_snfi_write(struct spi_mem *mem, +++ const struct spi_mem_op *op) +++{ +++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); +++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); +++ struct mtd_info *mtd = spinand_to_mtd(spinand); +++ struct mtk_snfi_nand_chip *snfi_nand = &snfi->snfi_nand; +++ u32 ret, i, sectors, col_addr = op->addr.val; +++ int oob_on = false; +++ +++ if (col_addr == mtd->writesize) +++ oob_on = true; +++ +++ sectors = mtd->writesize / snfi->caps->nand_sec_size; +++ memset(snfi->buffer, 0xff, mtd->writesize + mtd->oobsize); +++ +++ if (!oob_on) +++ memcpy(snfi->buffer, spinand->databuf, mtd->writesize); +++ +++ for (i = 0; i < sectors; i++) { +++ if (i == snfi_nand->bad_mark.sec && snfi->caps->bad_mark_swap) +++ snfi_nand->bad_mark.bm_swap(mem, snfi->buffer, oob_on); +++ +++ if (oob_on) +++ memcpy(mtk_oob_ptr(mem, snfi->buffer, i), +++ oob_ptr(mem, i), +++ snfi->caps->nand_fdm_size); +++ } +++ +++ ret = mtk_snfi_write_to_cache(mem, op, oob_on); +++ if (ret) +++ dev_warn(snfi->dev, "write to cache fail\n"); +++ +++ return ret; +++} +++ +++static int mtk_snfi_command_exec(struct mtk_snfi *snfi, +++ const u8 *txbuf, u8 *rxbuf, +++ const u32 txlen, const u32 rxlen) +++{ +++ u32 tmp, i, j, reg, m; +++ u8 *p_tmp = (u8 *)(&tmp); +++ int ret = 0; +++ +++ /* Moving tx data to NFI_SPI GPRAM */ +++ for (i = 0, m = 0; i < txlen; ) { +++ for (j = 0, tmp = 0; i < txlen && j < 4; i++, j++) +++ p_tmp[j] = txbuf[i]; +++ +++ writel(tmp, snfi->regs + SNFI_GPRAM_DATA + m); +++ m += 4; +++ } +++ +++ writel(txlen, snfi->regs + SNFI_MAC_OUTL); +++ writel(rxlen, snfi->regs + SNFI_MAC_INL); +++ ret = mtk_snfi_mac_op(snfi); +++ if (ret) +++ return ret; +++ +++ /* For NULL input data, this loop will be skipped */ +++ if (rxlen) +++ for (i = 0, m = 0; i < rxlen; ) { +++ reg = readl(snfi->regs + +++ SNFI_GPRAM_DATA + m); +++ for (j = 0; i < rxlen && j < 4; i++, j++, rxbuf++) { +++ if (m == 0 && i == 0) +++ j = i + txlen; +++ *rxbuf = (reg >> (j * 8)) & 0xFF; +++ } +++ m += 4; +++ } +++ +++ return ret; +++} +++ +++/* +++ * mtk_snfi_exec_op - to process command/data to send to the +++ * SPI NAND by mtk controller +++ */ +++static int mtk_snfi_exec_op(struct spi_mem *mem, +++ const struct spi_mem_op *op) +++ +++{ +++ struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master); +++ struct spinand_device *spinand = spi_mem_get_drvdata(mem); +++ struct mtd_info *mtd = spinand_to_mtd(spinand); +++ struct nand_device *nand = mtd_to_nanddev(mtd); +++ const struct spi_mem_op *read_cache; +++ const struct spi_mem_op *write_cache; +++ const struct spi_mem_op *update_cache; +++ u32 tmpbufsize, txlen = 0, rxlen = 0; +++ u8 *txbuf, *rxbuf = NULL, *buf; +++ int i, ret = 0; +++ +++ ret = mtk_snfi_reset(snfi); +++ if (ret) { +++ dev_warn(snfi->dev, "reset spi memory controller fail\n"); +++ return ret; +++ } +++ +++ /*if bbt initial, framework have detect nand information */ +++ if (nand->bbt.cache) { +++ read_cache = spinand->op_templates.read_cache; +++ write_cache = spinand->op_templates.write_cache; +++ update_cache = spinand->op_templates.update_cache; +++ +++ ret = mtk_snfi_hw_runtime_config(mem); +++ if (ret) +++ return ret; +++ +++ /* For Read/Write with cache, Erase use framework flow */ +++ if (op->cmd.opcode == read_cache->cmd.opcode) { +++ ret = mtk_snfi_read(mem, op); +++ if (ret) +++ dev_warn(snfi->dev, "snfi read fail\n"); +++ +++ return ret; +++ } else if ((op->cmd.opcode == write_cache->cmd.opcode) +++ || (op->cmd.opcode == update_cache->cmd.opcode)) { +++ ret = mtk_snfi_write(mem, op); +++ if (ret) +++ dev_warn(snfi->dev, "snfi write fail\n"); +++ +++ return ret; +++ } +++ } +++ +++ tmpbufsize = sizeof(op->cmd.opcode) + op->addr.nbytes + +++ op->dummy.nbytes + op->data.nbytes; +++ +++ txbuf = kzalloc(tmpbufsize, GFP_KERNEL); +++ if (!txbuf) +++ return -ENOMEM; +++ +++ txbuf[txlen++] = op->cmd.opcode; +++ +++ if (op->addr.nbytes) +++ for (i = 0; i < op->addr.nbytes; i++) +++ txbuf[txlen++] = op->addr.val >> +++ (8 * (op->addr.nbytes - i - 1)); +++ +++ txlen += op->dummy.nbytes; +++ +++ if (op->data.dir == SPI_MEM_DATA_OUT) +++ for (i = 0; i < op->data.nbytes; i++) { +++ buf = (u8 *)op->data.buf.out; +++ txbuf[txlen++] = buf[i]; +++ } +++ +++ if (op->data.dir == SPI_MEM_DATA_IN) { +++ rxbuf = (u8 *)op->data.buf.in; +++ rxlen += op->data.nbytes; +++ } +++ +++ ret = mtk_snfi_command_exec(snfi, txbuf, rxbuf, txlen, rxlen); +++ kfree(txbuf); +++ +++ return ret; +++} +++ +++static int mtk_snfi_init(struct mtk_snfi *snfi) +++{ +++ int ret; +++ +++ /* Reset the state machine and data FIFO */ +++ ret = mtk_snfi_reset(snfi); +++ if (ret) { +++ dev_warn(snfi->dev, "MTK reset controller fail\n"); +++ return ret; +++ } +++ +++ snfi->buffer = devm_kzalloc(snfi->dev, 4096 + 256, GFP_KERNEL); +++ if (!snfi->buffer) +++ return -ENOMEM; +++ +++ /* Clear interrupt, read clear. */ +++ readw(snfi->regs + NFI_INTR_STA); +++ writew(0, snfi->regs + NFI_INTR_EN); +++ +++ writel(0, snfi->regs + NFI_CON); +++ writel(0, snfi->regs + NFI_CNFG); +++ +++ /* Change to NFI_SPI mode. */ +++ writel(SNFI_MODE_EN, snfi->regs + SNFI_CNFG); +++ +++ return 0; +++} +++ +++static int mtk_snfi_check_buswidth(u8 width) +++{ +++ switch (width) { +++ case 1: +++ case 2: +++ case 4: +++ return 0; +++ +++ default: +++ break; +++ } +++ +++ return -ENOTSUPP; +++} +++ +++static bool mtk_snfi_supports_op(struct spi_mem *mem, +++ const struct spi_mem_op *op) +++{ +++ int ret = 0; +++ +++ /* For MTK Spi Nand controller, cmd buswidth just support 1 bit*/ +++ if (op->cmd.buswidth != 1) +++ ret = -ENOTSUPP; +++ +++ if (op->addr.nbytes) +++ ret |= mtk_snfi_check_buswidth(op->addr.buswidth); +++ +++ if (op->dummy.nbytes) +++ ret |= mtk_snfi_check_buswidth(op->dummy.buswidth); +++ +++ if (op->data.nbytes) +++ ret |= mtk_snfi_check_buswidth(op->data.buswidth); +++ +++ if (ret) +++ return false; +++ +++ return true; +++} +++ +++static const struct spi_controller_mem_ops mtk_snfi_ops = { +++ .supports_op = mtk_snfi_supports_op, +++ .exec_op = mtk_snfi_exec_op, +++}; +++ +++static const struct mtk_snfi_caps snfi_mt7622 = { +++ .spare_size = spare_size_mt7622, +++ .num_spare_size = 4, +++ .nand_sec_size = 512, +++ .nand_fdm_size = 8, +++ .nand_fdm_ecc_size = 1, +++ .ecc_parity_bits = 13, +++ .pageformat_spare_shift = 4, +++ .bad_mark_swap = 0, +++}; +++ +++static const struct mtk_snfi_caps snfi_mt7629 = { +++ .spare_size = spare_size_mt7622, +++ .num_spare_size = 4, +++ .nand_sec_size = 512, +++ .nand_fdm_size = 8, +++ .nand_fdm_ecc_size = 1, +++ .ecc_parity_bits = 13, +++ .pageformat_spare_shift = 4, +++ .bad_mark_swap = 1, +++}; +++ +++static const struct of_device_id mtk_snfi_id_table[] = { +++ { .compatible = "mediatek,mt7622-snfi", .data = &snfi_mt7622, }, +++ { .compatible = "mediatek,mt7629-snfi", .data = &snfi_mt7629, }, +++ { /* sentinel */ } +++}; +++ +++static int mtk_snfi_probe(struct platform_device *pdev) +++{ +++ struct device *dev = &pdev->dev; +++ struct device_node *np = dev->of_node; +++ struct spi_controller *ctlr; +++ struct mtk_snfi *snfi; +++ struct resource *res; +++ int ret = 0, irq; +++ +++ ctlr = spi_alloc_master(&pdev->dev, sizeof(*snfi)); +++ if (!ctlr) +++ return -ENOMEM; +++ +++ snfi = spi_controller_get_devdata(ctlr); +++ snfi->caps = of_device_get_match_data(dev); +++ snfi->dev = dev; +++ +++ snfi->ecc = of_mtk_ecc_get(np); +++ if (IS_ERR_OR_NULL(snfi->ecc)) +++ goto err_put_master; +++ +++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +++ snfi->regs = devm_ioremap_resource(dev, res); +++ if (IS_ERR(snfi->regs)) { +++ ret = PTR_ERR(snfi->regs); +++ goto release_ecc; +++ } +++ +++ /* find the clocks */ +++ snfi->clk.nfi_clk = devm_clk_get(dev, "nfi_clk"); +++ if (IS_ERR(snfi->clk.nfi_clk)) { +++ dev_err(dev, "no nfi clk\n"); +++ ret = PTR_ERR(snfi->clk.nfi_clk); +++ goto release_ecc; +++ } +++ +++ snfi->clk.spi_clk = devm_clk_get(dev, "spi_clk"); +++ if (IS_ERR(snfi->clk.spi_clk)) { +++ dev_err(dev, "no spi clk\n"); +++ ret = PTR_ERR(snfi->clk.spi_clk); +++ goto release_ecc; +++ } +++ +++ ret = mtk_snfi_enable_clk(dev, &snfi->clk); +++ if (ret) +++ goto release_ecc; +++ +++ /* find the irq */ +++ irq = platform_get_irq(pdev, 0); +++ if (irq < 0) { +++ dev_err(dev, "no snfi irq resource\n"); +++ ret = -EINVAL; +++ goto clk_disable; +++ } +++ +++ ret = devm_request_irq(dev, irq, mtk_snfi_irq, 0, "mtk-snfi", snfi); +++ if (ret) { +++ dev_err(dev, "failed to request snfi irq\n"); +++ goto clk_disable; +++ } +++ +++ ret = dma_set_mask(dev, DMA_BIT_MASK(32)); +++ if (ret) { +++ dev_err(dev, "failed to set dma mask\n"); +++ goto clk_disable; +++ } +++ +++ ctlr->dev.of_node = np; +++ ctlr->mem_ops = &mtk_snfi_ops; +++ +++ platform_set_drvdata(pdev, snfi); +++ ret = mtk_snfi_init(snfi); +++ if (ret) { +++ dev_err(dev, "failed to init snfi\n"); +++ goto clk_disable; +++ } +++ +++ ret = devm_spi_register_master(dev, ctlr); +++ if (ret) +++ goto clk_disable; +++ +++ return 0; +++ +++clk_disable: +++ mtk_snfi_disable_clk(&snfi->clk); +++ +++release_ecc: +++ mtk_ecc_release(snfi->ecc); +++ +++err_put_master: +++ spi_master_put(ctlr); +++ +++ dev_err(dev, "MediaTek SPI NAND interface probe failed %d\n", ret); +++ return ret; +++} +++ +++static int mtk_snfi_remove(struct platform_device *pdev) +++{ +++ struct mtk_snfi *snfi = platform_get_drvdata(pdev); +++ +++ mtk_snfi_disable_clk(&snfi->clk); +++ +++ return 0; +++} +++ +++static int mtk_snfi_suspend(struct platform_device *pdev, pm_message_t state) +++{ +++ struct mtk_snfi *snfi = platform_get_drvdata(pdev); +++ +++ mtk_snfi_disable_clk(&snfi->clk); +++ +++ return 0; +++} +++ +++static int mtk_snfi_resume(struct platform_device *pdev) +++{ +++ struct device *dev = &pdev->dev; +++ struct mtk_snfi *snfi = dev_get_drvdata(dev); +++ int ret; +++ +++ ret = mtk_snfi_enable_clk(dev, &snfi->clk); +++ if (ret) +++ return ret; +++ +++ ret = mtk_snfi_init(snfi); +++ if (ret) +++ dev_err(dev, "failed to init snfi controller\n"); +++ +++ return ret; +++} +++ +++static struct platform_driver mtk_snfi_driver = { +++ .driver = { +++ .name = "mtk-snfi", +++ .of_match_table = mtk_snfi_id_table, +++ }, +++ .probe = mtk_snfi_probe, +++ .remove = mtk_snfi_remove, +++ .suspend = mtk_snfi_suspend, +++ .resume = mtk_snfi_resume, +++}; +++ +++module_platform_driver(mtk_snfi_driver); +++ +++MODULE_LICENSE("GPL v2"); +++MODULE_AUTHOR("Xiangsheng Hou "); +++MODULE_DESCRIPTION("Mediatek SPI Memory Interface Driver"); +diff --git a/target/linux/mediatek/patches-5.10/330-mtk-bmt-support.patch b/target/linux/mediatek/patches-5.10/330-mtk-bmt-support.patch +new file mode 100644 +index 0000000000..5c20952611 +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/330-mtk-bmt-support.patch +@@ -0,0 +1,840 @@ ++--- a/drivers/mtd/nand/Kconfig +++++ b/drivers/mtd/nand/Kconfig ++@@ -15,6 +15,10 @@ config MTD_NAND_ECC ++ bool ++ depends on MTD_NAND_CORE ++ +++config MTD_NAND_MTK_BMT +++ bool "Support MediaTek NAND Bad-block Management Table" +++ default n +++ ++ endmenu ++ ++ endmenu ++--- a/drivers/mtd/nand/Makefile +++++ b/drivers/mtd/nand/Makefile ++@@ -2,6 +2,7 @@ ++ ++ nandcore-objs := core.o bbt.o ++ obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o +++obj-$(CONFIG_MTD_NAND_MTK_BMT) += mtk_bmt.o ++ ++ obj-y += onenand/ ++ obj-y += raw/ ++--- /dev/null +++++ b/drivers/mtd/nand/mtk_bmt.c ++@@ -0,0 +1,766 @@ +++/* +++ * Copyright (c) 2017 MediaTek Inc. +++ * Author: Xiangsheng Hou +++ * Copyright (c) 2020 Felix Fietkau +++ * +++ * This program is free software; you can redistribute it and/or modify +++ * it under the terms of the GNU General Public License version 2 as +++ * published by the Free Software Foundation. +++ * +++ * This program is distributed in the hope that it will be useful, +++ * but WITHOUT ANY WARRANTY; without even the implied warranty of +++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +++ * GNU General Public License for more details. +++ */ +++ +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++ +++#define MAIN_SIGNATURE_OFFSET 0 +++#define OOB_SIGNATURE_OFFSET 1 +++#define BBPOOL_RATIO 2 +++ +++#define BBT_LOG(fmt, ...) pr_debug("[BBT][%s|%d] "fmt"\n", __func__, __LINE__, ##__VA_ARGS__) +++ +++/* Maximum 8k blocks */ +++#define BB_TABLE_MAX 0x2000U +++#define BMT_TABLE_MAX (BB_TABLE_MAX * BBPOOL_RATIO / 100) +++#define BMT_TBL_DEF_VAL 0x0 +++ +++/* +++ * Burner Bad Block Table +++ * --------- Only support SLC Nand Chips!!!!!!!!!!! ---------- +++ */ +++ +++struct bbbt { +++ char signature[3]; +++ /* This version is used to distinguish the legacy and new algorithm */ +++#define BBMT_VERSION 2 +++ unsigned char version; +++ /* Below 2 tables will be written in SLC */ +++ u16 bb_tbl[BB_TABLE_MAX]; +++ struct bbmt { +++ u16 block; +++#define NO_MAPPED 0 +++#define NORMAL_MAPPED 1 +++#define BMT_MAPPED 2 +++ u16 mapped; +++ } bmt_tbl[BMT_TABLE_MAX]; +++}; +++ +++static struct bmt_desc { +++ struct mtd_info *mtd; +++ +++ int (*_read_oob) (struct mtd_info *mtd, loff_t from, +++ struct mtd_oob_ops *ops); +++ int (*_write_oob) (struct mtd_info *mtd, loff_t to, +++ struct mtd_oob_ops *ops); +++ const struct nand_ops *nand_ops; +++ +++ struct bbbt *bbt; +++ +++ struct dentry *debugfs_dir; +++ +++ u32 pg_size; +++ u32 blk_size; +++ u16 pg_shift; +++ u16 blk_shift; +++ /* bbt logical address */ +++ u16 pool_lba; +++ /* bbt physical address */ +++ u16 pool_pba; +++ /* Maximum count of bad blocks that the vendor guaranteed */ +++ u16 bb_max; +++ /* Total blocks of the Nand Chip */ +++ u16 total_blks; +++ /* The block(n) BMT is located at (bmt_tbl[n]) */ +++ u16 bmt_blk_idx; +++ /* How many pages needs to store 'struct bbbt' */ +++ u32 bmt_pgs; +++ +++ /* to compensate for driver level remapping */ +++ u8 oob_offset; +++} bmtd = {0}; +++ +++static unsigned char *nand_bbt_buf; +++static unsigned char *nand_data_buf; +++ +++/* -------- Unit conversions -------- */ +++static inline u32 blk_pg(u16 block) +++{ +++ return (u32)(block << (bmtd.blk_shift - bmtd.pg_shift)); +++} +++ +++/* -------- Nand operations wrapper -------- */ +++static inline int +++bbt_nand_read(u32 page, unsigned char *dat, int dat_len, +++ unsigned char *fdm, int fdm_len) +++{ +++ struct mtd_oob_ops ops = { +++ .mode = MTD_OPS_PLACE_OOB, +++ .ooboffs = bmtd.oob_offset, +++ .oobbuf = fdm, +++ .ooblen = fdm_len, +++ .datbuf = dat, +++ .len = dat_len, +++ }; +++ +++ return bmtd._read_oob(bmtd.mtd, page << bmtd.pg_shift, &ops); +++} +++ +++static inline int bbt_nand_erase(u16 block) +++{ +++ struct nand_device *nand = mtd_to_nanddev(bmtd.mtd); +++ loff_t addr = (loff_t)block << bmtd.blk_shift; +++ struct nand_pos pos; +++ +++ nanddev_offs_to_pos(nand, addr, &pos); +++ return bmtd.nand_ops->erase(nand, &pos); +++} +++ +++/* -------- Bad Blocks Management -------- */ +++static int +++read_bmt(u16 block, unsigned char *dat, unsigned char *fdm, int fdm_len) +++{ +++ u32 len = bmtd.bmt_pgs << bmtd.pg_shift; +++ +++ return bbt_nand_read(blk_pg(block), dat, len, fdm, fdm_len); +++} +++ +++static int write_bmt(u16 block, unsigned char *dat) +++{ +++ struct mtd_oob_ops ops = { +++ .mode = MTD_OPS_PLACE_OOB, +++ .ooboffs = OOB_SIGNATURE_OFFSET + bmtd.oob_offset, +++ .oobbuf = "bmt", +++ .ooblen = 3, +++ .datbuf = dat, +++ .len = bmtd.bmt_pgs << bmtd.pg_shift, +++ }; +++ loff_t addr = (loff_t)block << bmtd.blk_shift; +++ +++ return bmtd._write_oob(bmtd.mtd, addr, &ops); +++} +++ +++static u16 find_valid_block(u16 block) +++{ +++ u8 fdm[4]; +++ int ret; +++ int loop = 0; +++ +++retry: +++ if (block >= bmtd.total_blks) +++ return 0; +++ +++ ret = bbt_nand_read(blk_pg(block), nand_data_buf, bmtd.pg_size, +++ fdm, sizeof(fdm)); +++ /* Read the 1st byte of FDM to judge whether it's a bad +++ * or not +++ */ +++ if (ret || fdm[0] != 0xff) { +++ pr_info("nand: found bad block 0x%x\n", block); +++ if (loop >= bmtd.bb_max) { +++ pr_info("nand: FATAL ERR: too many bad blocks!!\n"); +++ return 0; +++ } +++ +++ loop++; +++ block++; +++ goto retry; +++ } +++ +++ return block; +++} +++ +++/* Find out all bad blocks, and fill in the mapping table */ +++static int scan_bad_blocks(struct bbbt *bbt) +++{ +++ int i; +++ u16 block = 0; +++ +++ /* First time download, the block0 MUST NOT be a bad block, +++ * this is guaranteed by vendor +++ */ +++ bbt->bb_tbl[0] = 0; +++ +++ /* +++ * Construct the mapping table of Normal data area(non-PMT/BMTPOOL) +++ * G - Good block; B - Bad block +++ * --------------------------- +++ * physical |G|G|B|G|B|B|G|G|G|G|B|G|B| +++ * --------------------------- +++ * What bb_tbl[i] looks like: +++ * physical block(i): +++ * 0 1 2 3 4 5 6 7 8 9 a b c +++ * mapped block(bb_tbl[i]): +++ * 0 1 3 6 7 8 9 b ...... +++ * ATTENTION: +++ * If new bad block ocurred(n), search bmt_tbl to find +++ * a available block(x), and fill in the bb_tbl[n] = x; +++ */ +++ for (i = 1; i < bmtd.pool_lba; i++) { +++ bbt->bb_tbl[i] = find_valid_block(bbt->bb_tbl[i - 1] + 1); +++ BBT_LOG("bb_tbl[0x%x] = 0x%x", i, bbt->bb_tbl[i]); +++ if (bbt->bb_tbl[i] == 0) +++ return -1; +++ } +++ +++ /* Physical Block start Address of BMT pool */ +++ bmtd.pool_pba = bbt->bb_tbl[i - 1] + 1; +++ if (bmtd.pool_pba >= bmtd.total_blks - 2) { +++ pr_info("nand: FATAL ERR: Too many bad blocks!!\n"); +++ return -1; +++ } +++ +++ BBT_LOG("pool_pba=0x%x", bmtd.pool_pba); +++ i = 0; +++ block = bmtd.pool_pba; +++ /* +++ * The bmt table is used for runtime bad block mapping +++ * G - Good block; B - Bad block +++ * --------------------------- +++ * physical |G|G|B|G|B|B|G|G|G|G|B|G|B| +++ * --------------------------- +++ * block: 0 1 2 3 4 5 6 7 8 9 a b c +++ * What bmt_tbl[i] looks like in initial state: +++ * i: +++ * 0 1 2 3 4 5 6 7 +++ * bmt_tbl[i].block: +++ * 0 1 3 6 7 8 9 b +++ * bmt_tbl[i].mapped: +++ * N N N N N N N B +++ * N - Not mapped(Available) +++ * M - Mapped +++ * B - BMT +++ * ATTENTION: +++ * BMT always in the last valid block in pool +++ */ +++ while ((block = find_valid_block(block)) != 0) { +++ bbt->bmt_tbl[i].block = block; +++ bbt->bmt_tbl[i].mapped = NO_MAPPED; +++ BBT_LOG("bmt_tbl[%d].block = 0x%x", i, block); +++ block++; +++ i++; +++ } +++ +++ /* i - How many available blocks in pool, which is the length of bmt_tbl[] +++ * bmtd.bmt_blk_idx - bmt_tbl[bmtd.bmt_blk_idx].block => the BMT block +++ */ +++ bmtd.bmt_blk_idx = i - 1; +++ bbt->bmt_tbl[bmtd.bmt_blk_idx].mapped = BMT_MAPPED; +++ +++ if (i < 1) { +++ pr_info("nand: FATAL ERR: no space to store BMT!!\n"); +++ return -1; +++ } +++ +++ pr_info("[BBT] %d available blocks in BMT pool\n", i); +++ +++ return 0; +++} +++ +++static bool is_valid_bmt(unsigned char *buf, unsigned char *fdm) +++{ +++ struct bbbt *bbt = (struct bbbt *)buf; +++ u8 *sig = (u8*)bbt->signature + MAIN_SIGNATURE_OFFSET; +++ +++ +++ if (memcmp(bbt->signature + MAIN_SIGNATURE_OFFSET, "BMT", 3) == 0 && +++ memcmp(fdm + OOB_SIGNATURE_OFFSET, "bmt", 3) == 0) { +++ if (bbt->version == BBMT_VERSION) +++ return true; +++ } +++ BBT_LOG("[BBT] BMT Version not match,upgrage preloader and uboot please! sig=%02x%02x%02x, fdm=%02x%02x%02x", +++ sig[0], sig[1], sig[2], +++ fdm[1], fdm[2], fdm[3]); +++ return false; +++} +++ +++static u16 get_bmt_index(struct bbmt *bmt) +++{ +++ int i = 0; +++ +++ while (bmt[i].block != BMT_TBL_DEF_VAL) { +++ if (bmt[i].mapped == BMT_MAPPED) +++ return i; +++ i++; +++ } +++ return 0; +++} +++ +++static struct bbbt *scan_bmt(u16 block) +++{ +++ u8 fdm[4]; +++ +++ if (block < bmtd.pool_lba) +++ return NULL; +++ +++ if (read_bmt(block, nand_bbt_buf, fdm, sizeof(fdm))) +++ return scan_bmt(block - 1); +++ +++ if (is_valid_bmt(nand_bbt_buf, fdm)) { +++ bmtd.bmt_blk_idx = get_bmt_index(((struct bbbt *)nand_bbt_buf)->bmt_tbl); +++ if (bmtd.bmt_blk_idx == 0) { +++ pr_info("[BBT] FATAL ERR: bmt block index is wrong!\n"); +++ return NULL; +++ } +++ pr_info("[BBT] BMT.v2 is found at 0x%x\n", block); +++ return (struct bbbt *)nand_bbt_buf; +++ } else +++ return scan_bmt(block - 1); +++} +++ +++/* Write the Burner Bad Block Table to Nand Flash +++ * n - write BMT to bmt_tbl[n] +++ */ +++static u16 upload_bmt(struct bbbt *bbt, int n) +++{ +++ u16 block; +++ +++retry: +++ if (n < 0 || bbt->bmt_tbl[n].mapped == NORMAL_MAPPED) { +++ pr_info("nand: FATAL ERR: no space to store BMT!\n"); +++ return (u16)-1; +++ } +++ +++ block = bbt->bmt_tbl[n].block; +++ BBT_LOG("n = 0x%x, block = 0x%x", n, block); +++ if (bbt_nand_erase(block)) { +++ bbt->bmt_tbl[n].block = 0; +++ /* erase failed, try the previous block: bmt_tbl[n - 1].block */ +++ n--; +++ goto retry; +++ } +++ +++ /* The signature offset is fixed set to 0, +++ * oob signature offset is fixed set to 1 +++ */ +++ memcpy(bbt->signature + MAIN_SIGNATURE_OFFSET, "BMT", 3); +++ bbt->version = BBMT_VERSION; +++ +++ if (write_bmt(block, (unsigned char *)bbt)) { +++ bbt->bmt_tbl[n].block = 0; +++ +++ /* write failed, try the previous block in bmt_tbl[n - 1] */ +++ n--; +++ goto retry; +++ } +++ +++ /* Return the current index(n) of BMT pool (bmt_tbl[n]) */ +++ return n; +++} +++ +++static u16 find_valid_block_in_pool(struct bbbt *bbt) +++{ +++ int i; +++ +++ if (bmtd.bmt_blk_idx == 0) +++ goto error; +++ +++ for (i = 0; i < bmtd.bmt_blk_idx; i++) { +++ if (bbt->bmt_tbl[i].block != 0 && bbt->bmt_tbl[i].mapped == NO_MAPPED) { +++ bbt->bmt_tbl[i].mapped = NORMAL_MAPPED; +++ return bbt->bmt_tbl[i].block; +++ } +++ } +++ +++error: +++ pr_info("nand: FATAL ERR: BMT pool is run out!\n"); +++ return 0; +++} +++ +++/* We met a bad block, mark it as bad and map it to a valid block in pool, +++ * if it's a write failure, we need to write the data to mapped block +++ */ +++static bool update_bmt(u16 block) +++{ +++ u16 mapped_blk; +++ struct bbbt *bbt; +++ +++ bbt = bmtd.bbt; +++ mapped_blk = find_valid_block_in_pool(bbt); +++ if (mapped_blk == 0) +++ return false; +++ +++ /* Map new bad block to available block in pool */ +++ bbt->bb_tbl[block] = mapped_blk; +++ bmtd.bmt_blk_idx = upload_bmt(bbt, bmtd.bmt_blk_idx); +++ +++ return true; +++} +++ +++u16 get_mapping_block_index(int block) +++{ +++ int mapping_block; +++ +++ if (block < bmtd.pool_lba) +++ mapping_block = bmtd.bbt->bb_tbl[block]; +++ else +++ mapping_block = block; +++ BBT_LOG("0x%x mapped to 0x%x", block, mapping_block); +++ +++ return mapping_block; +++} +++ +++static int +++mtk_bmt_read(struct mtd_info *mtd, loff_t from, +++ struct mtd_oob_ops *ops) +++{ +++ struct mtd_oob_ops cur_ops = *ops; +++ int retry_count = 0; +++ loff_t cur_from; +++ int ret; +++ +++ ops->retlen = 0; +++ ops->oobretlen = 0; +++ +++ while (ops->retlen < ops->len || ops->oobretlen < ops->ooblen) { +++ u32 offset = from & (bmtd.blk_size - 1); +++ u32 block = from >> bmtd.blk_shift; +++ u32 cur_block; +++ +++ cur_block = get_mapping_block_index(block); +++ cur_from = ((loff_t)cur_block << bmtd.blk_shift) + offset; +++ +++ cur_ops.oobretlen = 0; +++ cur_ops.retlen = 0; +++ cur_ops.len = min_t(u32, mtd->erasesize - offset, +++ ops->len - ops->retlen); +++ ret = bmtd._read_oob(mtd, cur_from, &cur_ops); +++ if (ret < 0) { +++ update_bmt(block); +++ if (retry_count++ < 10) +++ continue; +++ +++ return ret; +++ } +++ +++ ops->retlen += cur_ops.retlen; +++ ops->oobretlen += cur_ops.oobretlen; +++ +++ cur_ops.datbuf += cur_ops.retlen; +++ cur_ops.oobbuf += cur_ops.oobretlen; +++ cur_ops.ooblen -= cur_ops.oobretlen; +++ +++ if (!cur_ops.len) +++ cur_ops.len = mtd->erasesize - offset; +++ +++ from += cur_ops.len; +++ retry_count = 0; +++ } +++ +++ return 0; +++} +++ +++static int +++mtk_bmt_write(struct mtd_info *mtd, loff_t to, +++ struct mtd_oob_ops *ops) +++{ +++ struct mtd_oob_ops cur_ops = *ops; +++ int retry_count = 0; +++ loff_t cur_to; +++ int ret; +++ +++ ops->retlen = 0; +++ ops->oobretlen = 0; +++ +++ while (ops->retlen < ops->len || ops->oobretlen < ops->ooblen) { +++ u32 offset = to & (bmtd.blk_size - 1); +++ u32 block = to >> bmtd.blk_shift; +++ u32 cur_block; +++ +++ cur_block = get_mapping_block_index(block); +++ cur_to = ((loff_t)cur_block << bmtd.blk_shift) + offset; +++ +++ cur_ops.oobretlen = 0; +++ cur_ops.retlen = 0; +++ cur_ops.len = min_t(u32, bmtd.blk_size - offset, +++ ops->len - ops->retlen); +++ ret = bmtd._write_oob(mtd, cur_to, &cur_ops); +++ if (ret < 0) { +++ update_bmt(block); +++ if (retry_count++ < 10) +++ continue; +++ +++ return ret; +++ } +++ +++ ops->retlen += cur_ops.retlen; +++ ops->oobretlen += cur_ops.oobretlen; +++ +++ cur_ops.datbuf += cur_ops.retlen; +++ cur_ops.oobbuf += cur_ops.oobretlen; +++ cur_ops.ooblen -= cur_ops.oobretlen; +++ +++ if (!cur_ops.len) +++ cur_ops.len = mtd->erasesize - offset; +++ +++ to += cur_ops.len; +++ retry_count = 0; +++ } +++ +++ return 0; +++} +++ +++ +++ +++static int +++mtk_bmt_erase(struct nand_device *nand, const struct nand_pos *pos) +++{ +++ struct nand_pos new_pos = *pos; +++ int retry_count = 0; +++ int ret; +++ +++retry: +++ new_pos.eraseblock = get_mapping_block_index(pos->eraseblock); +++ +++ ret = bmtd.nand_ops->erase(nand, &new_pos); +++ if (ret) { +++ update_bmt(pos->eraseblock); +++ if (retry_count++ < 10) +++ goto retry; +++ } +++ +++ return ret; +++} +++ +++static bool +++mtk_bmt_isbad(struct nand_device *nand, const struct nand_pos *pos) +++{ +++ struct nand_pos new_pos = *pos; +++ int retry_count = 0; +++ bool ret; +++ +++retry: +++ new_pos.eraseblock = get_mapping_block_index(pos->eraseblock); +++ +++ ret = bmtd.nand_ops->isbad(nand, &new_pos); +++ if (ret) { +++ update_bmt(pos->eraseblock); +++ if (retry_count++ < 10) +++ goto retry; +++ } +++ +++ return ret; +++} +++ +++static int +++mtk_bmt_markbad(struct nand_device *nand, const struct nand_pos *pos) +++{ +++ struct nand_pos new_pos = *pos; +++ +++ new_pos.eraseblock = get_mapping_block_index(new_pos.eraseblock); +++ update_bmt(pos->eraseblock); +++ +++ return bmtd.nand_ops->markbad(nand, &new_pos); +++} +++ +++static void +++mtk_bmt_replace_ops(struct mtd_info *mtd) +++{ +++ static const struct nand_ops mtk_bmt_nand_ops = { +++ .erase = mtk_bmt_erase, +++ .isbad = mtk_bmt_isbad, +++ .markbad = mtk_bmt_markbad, +++ }; +++ struct nand_device *nand = mtd_to_nanddev(mtd); +++ +++ bmtd.nand_ops = nand->ops; +++ bmtd._read_oob = mtd->_read_oob; +++ bmtd._write_oob = mtd->_write_oob; +++ +++ mtd->_read_oob = mtk_bmt_read; +++ mtd->_write_oob = mtk_bmt_write; +++ nand->ops = &mtk_bmt_nand_ops; +++} +++ +++static int mtk_bmt_debug_mark_good(void *data, u64 val) +++{ +++ u32 block = val >> bmtd.blk_shift; +++ +++ bmtd.bbt->bb_tbl[block] = block; +++ bmtd.bmt_blk_idx = upload_bmt(bmtd.bbt, bmtd.bmt_blk_idx); +++ +++ return 0; +++} +++ +++static int mtk_bmt_debug_mark_bad(void *data, u64 val) +++{ +++ u32 block = val >> bmtd.blk_shift; +++ +++ update_bmt(block); +++ +++ return 0; +++} +++ +++DEFINE_DEBUGFS_ATTRIBUTE(fops_mark_good, NULL, mtk_bmt_debug_mark_good, "%llu\n"); +++DEFINE_DEBUGFS_ATTRIBUTE(fops_mark_bad, NULL, mtk_bmt_debug_mark_bad, "%llu\n"); +++ +++static void +++mtk_bmt_add_debugfs(void) +++{ +++ struct dentry *dir; +++ +++ dir = bmtd.debugfs_dir = debugfs_create_dir("mtk-bmt", NULL); +++ if (!dir) +++ return; +++ +++ debugfs_create_file_unsafe("mark_good", S_IWUSR, dir, NULL, &fops_mark_good); +++ debugfs_create_file_unsafe("mark_bad", S_IWUSR, dir, NULL, &fops_mark_bad); +++} +++ +++void mtk_bmt_detach(struct mtd_info *mtd) +++{ +++ struct nand_device *nand = mtd_to_nanddev(mtd); +++ +++ if (bmtd.mtd != mtd) +++ return; +++ +++ if (bmtd.debugfs_dir) +++ debugfs_remove_recursive(bmtd.debugfs_dir); +++ bmtd.debugfs_dir = NULL; +++ +++ kfree(nand_bbt_buf); +++ kfree(nand_data_buf); +++ +++ mtd->_read_oob = bmtd._read_oob; +++ mtd->_write_oob = bmtd._write_oob; +++ mtd->size = bmtd.total_blks << bmtd.blk_shift; +++ nand->ops = bmtd.nand_ops; +++ +++ memset(&bmtd, 0, sizeof(bmtd)); +++} +++ +++/* total_blocks - The total count of blocks that the Nand Chip has */ +++int mtk_bmt_attach(struct mtd_info *mtd) +++{ +++ struct device_node *np; +++ struct bbbt *bbt; +++ u32 bufsz; +++ u32 block; +++ u16 total_blocks, pmt_block; +++ int ret = 0; +++ u32 bmt_pool_size; +++ +++ if (bmtd.mtd) +++ return -ENOSPC; +++ +++ np = mtd_get_of_node(mtd); +++ if (!np) +++ return 0; +++ +++ if (!of_property_read_bool(np, "mediatek,bmt-v2")) +++ return 0; +++ +++ if (of_property_read_u32(np, "mediatek,bmt-pool-size", +++ &bmt_pool_size) != 0) +++ bmt_pool_size = 80; +++ +++ if (of_property_read_u8(np, "mediatek,bmt-oob-offset", +++ &bmtd.oob_offset) != 0) +++ bmtd.oob_offset = 8; +++ +++ bmtd.mtd = mtd; +++ mtk_bmt_replace_ops(mtd); +++ +++ bmtd.blk_size = mtd->erasesize; +++ bmtd.blk_shift = ffs(bmtd.blk_size) - 1; +++ bmtd.pg_size = mtd->writesize; +++ bmtd.pg_shift = ffs(bmtd.pg_size) - 1; +++ total_blocks = mtd->size >> bmtd.blk_shift; +++ pmt_block = total_blocks - bmt_pool_size - 2; +++ +++ mtd->size = pmt_block << bmtd.blk_shift; +++ +++ /* +++ * --------------------------------------- +++ * | PMT(2blks) | BMT POOL(totalblks * 2%) | +++ * --------------------------------------- +++ * ^ ^ +++ * | | +++ * pmt_block pmt_block + 2blocks(pool_lba) +++ * +++ * ATTETION!!!!!! +++ * The blocks ahead of the boundary block are stored in bb_tbl +++ * and blocks behind are stored in bmt_tbl +++ */ +++ +++ bmtd.pool_lba = (u16)(pmt_block + 2); +++ bmtd.total_blks = total_blocks; +++ bmtd.bb_max = bmtd.total_blks * BBPOOL_RATIO / 100; +++ +++ /* 3 buffers we need */ +++ bufsz = round_up(sizeof(struct bbbt), bmtd.pg_size); +++ bmtd.bmt_pgs = bufsz >> bmtd.pg_shift; +++ +++ nand_bbt_buf = kzalloc(bufsz, GFP_KERNEL); +++ nand_data_buf = kzalloc(bmtd.pg_size, GFP_KERNEL); +++ +++ if (!nand_bbt_buf || !nand_data_buf) { +++ pr_info("nand: FATAL ERR: allocate buffer failed!\n"); +++ ret = -1; +++ goto error; +++ } +++ +++ memset(nand_bbt_buf, 0xff, bufsz); +++ memset(nand_data_buf, 0xff, bmtd.pg_size); +++ +++ BBT_LOG("bbtbuf=0x%p(0x%x) dat=0x%p(0x%x)", +++ nand_bbt_buf, bufsz, nand_data_buf, bmtd.pg_size); +++ BBT_LOG("pool_lba=0x%x total_blks=0x%x bb_max=0x%x", +++ bmtd.pool_lba, bmtd.total_blks, bmtd.bb_max); +++ +++ /* Scanning start from the first page of the last block +++ * of whole flash +++ */ +++ bbt = scan_bmt(bmtd.total_blks - 1); +++ if (!bbt) { +++ /* BMT not found */ +++ if (bmtd.total_blks > BB_TABLE_MAX + BMT_TABLE_MAX) { +++ pr_info("nand: FATAL: Too many blocks, can not support!\n"); +++ ret = -1; +++ goto error; +++ } +++ +++ bbt = (struct bbbt *)nand_bbt_buf; +++ memset(bbt->bmt_tbl, BMT_TBL_DEF_VAL, sizeof(bbt->bmt_tbl)); +++ +++ if (scan_bad_blocks(bbt)) { +++ ret = -1; +++ goto error; +++ } +++ +++ /* BMT always in the last valid block in pool */ +++ bmtd.bmt_blk_idx = upload_bmt(bbt, bmtd.bmt_blk_idx); +++ block = bbt->bmt_tbl[bmtd.bmt_blk_idx].block; +++ pr_notice("[BBT] BMT.v2 is written into PBA:0x%x\n", block); +++ +++ if (bmtd.bmt_blk_idx == 0) +++ pr_info("nand: Warning: no available block in BMT pool!\n"); +++ else if (bmtd.bmt_blk_idx == (u16)-1) { +++ ret = -1; +++ goto error; +++ } +++ } +++ mtk_bmt_add_debugfs(); +++ +++ bmtd.bbt = bbt; +++ return 0; +++ +++error: +++ mtk_bmt_detach(mtd); +++ return ret; +++} +++ +++ +++MODULE_LICENSE("GPL"); +++MODULE_AUTHOR("Xiangsheng Hou , Felix Fietkau "); +++MODULE_DESCRIPTION("Bad Block mapping management v2 for MediaTek NAND Flash Driver"); +++ ++--- a/drivers/mtd/nand/spi/core.c +++++ b/drivers/mtd/nand/spi/core.c ++@@ -19,6 +19,7 @@ ++ #include ++ #include ++ #include +++#include ++ ++ static int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val) ++ { ++@@ -1139,6 +1140,8 @@ static int spinand_probe(struct spi_mem ++ if (ret) ++ return ret; ++ +++ mtk_bmt_attach(mtd); +++ ++ ret = mtd_device_register(mtd, NULL, 0); ++ if (ret) ++ goto err_spinand_cleanup; ++@@ -1164,6 +1167,7 @@ static int spinand_remove(struct spi_mem ++ if (ret) ++ return ret; ++ +++ mtk_bmt_detach(mtd); ++ spinand_cleanup(spinand); ++ ++ return 0; ++--- /dev/null +++++ b/include/linux/mtd/mtk_bmt.h ++@@ -0,0 +1,18 @@ +++#ifndef __MTK_BMT_H +++#define __MTK_BMT_H +++ +++#ifdef CONFIG_MTD_NAND_MTK_BMT +++int mtk_bmt_attach(struct mtd_info *mtd); +++void mtk_bmt_detach(struct mtd_info *mtd); +++#else +++static inline int mtk_bmt_attach(struct mtd_info *mtd) +++{ +++ return 0; +++} +++ +++static inline void mtk_bmt_detach(struct mtd_info *mtd) +++{ +++} +++#endif +++ +++#endif +diff --git a/target/linux/mediatek/patches-5.10/400-crypto-add-eip97-inside-secure-support.patch b/target/linux/mediatek/patches-5.10/400-crypto-add-eip97-inside-secure-support.patch +new file mode 100644 +index 0000000000..e0941a9550 +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/400-crypto-add-eip97-inside-secure-support.patch +@@ -0,0 +1,27 @@ ++--- a/drivers/crypto/inside-secure/safexcel.c +++++ b/drivers/crypto/inside-secure/safexcel.c ++@@ -600,6 +600,14 @@ static int safexcel_hw_init(struct safex ++ val |= EIP197_MST_CTRL_TX_MAX_CMD(5); ++ writel(val, EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL); ++ } +++ /* +++ * Set maximum number of TX commands to 2^4 = 16 for EIP97 HW2.1/HW2.3 +++ */ +++ else { +++ val = 0; +++ val |= EIP97_MST_CTRL_TX_MAX_CMD(4); +++ writel(val, EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL); +++ } ++ ++ /* Configure wr/rd cache values */ ++ writel(EIP197_MST_CTRL_RD_CACHE(RD_CACHE_4BITS) | ++--- a/drivers/crypto/inside-secure/safexcel.h +++++ b/drivers/crypto/inside-secure/safexcel.h ++@@ -314,6 +314,7 @@ ++ #define EIP197_MST_CTRL_RD_CACHE(n) (((n) & 0xf) << 0) ++ #define EIP197_MST_CTRL_WD_CACHE(n) (((n) & 0xf) << 4) ++ #define EIP197_MST_CTRL_TX_MAX_CMD(n) (((n) & 0xf) << 20) +++#define EIP97_MST_CTRL_TX_MAX_CMD(n) (((n) & 0xf) << 4) ++ #define EIP197_MST_CTRL_BYTE_SWAP BIT(24) ++ #define EIP197_MST_CTRL_NO_BYTE_SWAP BIT(25) ++ #define EIP197_MST_CTRL_BYTE_SWAP_BITS GENMASK(25, 24) +diff --git a/target/linux/mediatek/patches-5.10/401-crypto-fix-eip97-cache-incoherent.patch b/target/linux/mediatek/patches-5.10/401-crypto-fix-eip97-cache-incoherent.patch +new file mode 100644 +index 0000000000..be2bffb749 +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/401-crypto-fix-eip97-cache-incoherent.patch +@@ -0,0 +1,26 @@ ++--- a/drivers/crypto/inside-secure/safexcel.h +++++ b/drivers/crypto/inside-secure/safexcel.h ++@@ -736,6 +736,9 @@ enum safexcel_eip_version { ++ /* Priority we use for advertising our algorithms */ ++ #define SAFEXCEL_CRA_PRIORITY 300 ++ +++/* System cache line size */ +++#define SYSTEM_CACHELINE_SIZE 64 +++ ++ /* SM3 digest result for zero length message */ ++ #define EIP197_SM3_ZEROM_HASH "\x1A\xB2\x1D\x83\x55\xCF\xA1\x7F" \ ++ "\x8E\x61\x19\x48\x31\xE8\x1A\x8F" \ ++--- a/drivers/crypto/inside-secure/safexcel_hash.c +++++ b/drivers/crypto/inside-secure/safexcel_hash.c ++@@ -53,9 +53,9 @@ struct safexcel_ahash_req { ++ u8 block_sz; /* block size, only set once */ ++ u8 digest_sz; /* output digest size, only set once */ ++ __le32 state[SHA3_512_BLOCK_SIZE / ++- sizeof(__le32)] __aligned(sizeof(__le32)); +++ sizeof(__le32)] __aligned(SYSTEM_CACHELINE_SIZE); ++ ++- u64 len; +++ u64 len __aligned(SYSTEM_CACHELINE_SIZE); ++ u64 processed; ++ ++ u8 cache[HASH_CACHE_SIZE] __aligned(sizeof(u32)); +diff --git a/target/linux/mediatek/patches-5.10/410-bt-mtk-serial-fix.patch b/target/linux/mediatek/patches-5.10/410-bt-mtk-serial-fix.patch +new file mode 100644 +index 0000000000..2e474dd5fe +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/410-bt-mtk-serial-fix.patch +@@ -0,0 +1,33 @@ ++--- a/drivers/tty/serial/8250/8250.h +++++ b/drivers/tty/serial/8250/8250.h ++@@ -82,6 +82,7 @@ struct serial8250_config { ++ #define UART_CAP_MINI (1 << 17) /* Mini UART on BCM283X family lacks: ++ * STOP PARITY EPAR SPAR WLEN5 WLEN6 ++ */ +++#define UART_CAP_NMOD (1 << 18) /* UART doesn't do termios */ ++ ++ #define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */ ++ #define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */ ++--- a/drivers/tty/serial/8250/8250_port.c +++++ b/drivers/tty/serial/8250/8250_port.c ++@@ -287,7 +287,7 @@ static const struct serial8250_config ua ++ .tx_loadsz = 16, ++ .fcr = UART_FCR_ENABLE_FIFO | ++ UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, ++- .flags = UART_CAP_FIFO, +++ .flags = UART_CAP_FIFO | UART_CAP_NMOD, ++ }, ++ [PORT_NPCM] = { ++ .name = "Nuvoton 16550", ++@@ -2687,6 +2687,11 @@ serial8250_do_set_termios(struct uart_po ++ unsigned long flags; ++ unsigned int baud, quot, frac = 0; ++ +++ if (up->capabilities & UART_CAP_NMOD) { +++ termios->c_cflag = 0; +++ return; +++ } +++ ++ if (up->capabilities & UART_CAP_MINI) { ++ termios->c_cflag &= ~(CSTOPB | PARENB | PARODD | CMSPAR); ++ if ((termios->c_cflag & CSIZE) == CS5 || +diff --git a/target/linux/mediatek/patches-5.10/500-gsw-rtl8367s-mt7622-support.patch b/target/linux/mediatek/patches-5.10/500-gsw-rtl8367s-mt7622-support.patch +new file mode 100644 +index 0000000000..bdd482def3 +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/500-gsw-rtl8367s-mt7622-support.patch +@@ -0,0 +1,25 @@ ++--- a/drivers/net/phy/Kconfig +++++ b/drivers/net/phy/Kconfig ++@@ -334,6 +334,12 @@ config ROCKCHIP_PHY ++ help ++ Currently supports the integrated Ethernet PHY. ++ +++config RTL8367S_GSW +++ tristate "rtl8367 Gigabit Switch support for mt7622" +++ depends on NET_VENDOR_MEDIATEK +++ help +++ This driver supports rtl8367s in mt7622 +++ ++ config SMSC_PHY ++ tristate "SMSC PHYs" ++ help ++--- a/drivers/net/phy/Makefile +++++ b/drivers/net/phy/Makefile ++@@ -88,6 +88,7 @@ obj-$(CONFIG_QSEMI_PHY) += qsemi.o ++ obj-$(CONFIG_REALTEK_PHY) += realtek.o ++ obj-$(CONFIG_RENESAS_PHY) += uPD60620.o ++ obj-$(CONFIG_ROCKCHIP_PHY) += rockchip.o +++obj-$(CONFIG_RTL8367S_GSW) += rtk/ ++ obj-$(CONFIG_SMSC_PHY) += smsc.o ++ obj-$(CONFIG_STE10XP) += ste10Xp.o ++ obj-$(CONFIG_TERANETICS_PHY) += teranetics.o +diff --git a/target/linux/mediatek/patches-5.10/600-dt-bindings-PCI-Mediatek-Update-PCIe-binding.patch b/target/linux/mediatek/patches-5.10/600-dt-bindings-PCI-Mediatek-Update-PCIe-binding.patch +new file mode 100644 +index 0000000000..02e4c130ea +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/600-dt-bindings-PCI-Mediatek-Update-PCIe-binding.patch +@@ -0,0 +1,415 @@ ++From patchwork Thu May 28 06:16:45 2020 ++Content-Type: text/plain; charset="utf-8" ++MIME-Version: 1.0 ++Content-Transfer-Encoding: 7bit ++X-Patchwork-Submitter: Chuanjia Liu ++X-Patchwork-Id: 11574793 ++Return-Path: ++ ++Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org ++ [172.30.200.123]) ++ by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 391201392 ++ for ; ++ Thu, 28 May 2020 06:20:27 +0000 (UTC) ++Received: from bombadil.infradead.org (bombadil.infradead.org ++ [198.137.202.133]) ++ (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) ++ (No client certificate requested) ++ by mail.kernel.org (Postfix) with ESMTPS id 104F620657 ++ for ; ++ Thu, 28 May 2020 06:20:27 +0000 (UTC) ++Authentication-Results: mail.kernel.org; ++ dkim=pass (2048-bit key) header.d=lists.infradead.org ++ header.i=@lists.infradead.org header.b="raZHaWxs"; ++ dkim=fail reason="signature verification failed" (1024-bit key) ++ header.d=mediatek.com header.i=@mediatek.com header.b="YztrByG/" ++DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 104F620657 ++Authentication-Results: mail.kernel.org; ++ dmarc=fail (p=none dis=none) header.from=mediatek.com ++Authentication-Results: mail.kernel.org; ++ spf=none ++ smtp.mailfrom=linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org ++DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; ++ d=lists.infradead.org; s=bombadil.20170209; h=Sender: ++ Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: ++ List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: ++ Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: ++ Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: ++ List-Owner; bh=aVtKU+Ey8KEM97+S66fz9ZMo+H8BP570jhAAvaRsNWc=; b=raZHaWxsfCxsrd ++ Byn/w1oLN/J82ApnNdBBXixq9Qj0uXIU2tBVqkiQ9lG6QDk7uguxQSJLeTqrsI/uxQmCI/PGQtZdP ++ sH0oboi2sbQSqJ/1ud4uL2pPaiLRJCxINF5oWjoZMsjn/b2fWvn52P6vTr/dxDTaabiVhY0HL0J+X ++ 7YGc1aYtO76HZHE2ke3puR42QkI8hE9E2cEhiLWeuUiLdUBegNM5MdYftu4nJTcCXnAeJjp/wIpYG ++ 7X737N9cmanDf6Bxr2bNPgaYzH+m7JK6eGxuAvWo0+PE9OX7MLrXY3KjixcjD/b0he0mfEM++gBAq ++ KBYKl5wh1mnlR2WIWXew==; ++Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) ++ by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) ++ id 1jeBtx-0005JC-DJ; Thu, 28 May 2020 06:20:25 +0000 ++Received: from mailgw01.mediatek.com ([216.200.240.184]) ++ by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) ++ id 1jeBtW-0002f2-75; Thu, 28 May 2020 06:20:01 +0000 ++X-UUID: d5cb6d96c2a5421796c2f8a284ff3670-20200527 ++DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; ++ d=mediatek.com; ++ s=dk; ++ h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; ++ bh=EqjC+5cHgv6eykN7FPf2mtwK9UivJ3XSCE0jEvb8h+8=; ++ b=YztrByG/Ia304l9KDPBwoHFYkFCN6qBXPqwZgg56CA9VitadAg2+K1VgfEU+oHqsqcsGAMdZTRMQh17tpm4bJParw6MMzAQ28te2TcxvQMV8PZMkerJdZyyYblI7ybauPWuofAQgQMtuwSKVii8eTRJbf99OZ9vDGJP3zo2j1wU=; ++X-UUID: d5cb6d96c2a5421796c2f8a284ff3670-20200527 ++Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by ++ mailgw01.mediatek.com ++ (envelope-from ) ++ (musrelay.mediatek.com ESMTP with TLS) ++ with ESMTP id 681958707; Wed, 27 May 2020 22:20:16 -0800 ++Received: from MTKMBS07N2.mediatek.inc (172.21.101.141) by ++ MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id ++ 15.0.1497.2; Wed, 27 May 2020 23:18:52 -0700 ++Received: from mtkcas07.mediatek.inc (172.21.101.84) by ++ mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server (TLS) id ++ 15.0.1497.2; Thu, 28 May 2020 14:18:49 +0800 ++Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc ++ (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend ++ Transport; Thu, 28 May 2020 14:18:47 +0800 ++From: ++To: , , ++Subject: [PATCH v2 1/4] dt-bindings: PCI: Mediatek: Update PCIe binding ++Date: Thu, 28 May 2020 14:16:45 +0800 ++Message-ID: <20200528061648.32078-2-chuanjia.liu@mediatek.com> ++X-Mailer: git-send-email 2.18.0 ++In-Reply-To: <20200528061648.32078-1-chuanjia.liu@mediatek.com> ++References: <20200528061648.32078-1-chuanjia.liu@mediatek.com> ++MIME-Version: 1.0 ++X-MTK: N ++X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 ++X-CRM114-CacheID: sfid-20200527_231958_261064_608CC03E ++X-CRM114-Status: GOOD ( 13.95 ) ++X-Spam-Score: -0.2 (/) ++X-Spam-Report: SpamAssassin version 3.4.4 on bombadil.infradead.org summary: ++ Content analysis details: (-0.2 points) ++ pts rule name description ++ ---- ---------------------- ++ -------------------------------------------------- ++ -0.0 SPF_PASS SPF: sender matches SPF record ++ 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record ++ 0.0 MIME_BASE64_TEXT RAW: Message text disguised using base64 ++ encoding ++ -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from ++ author's domain ++ 0.1 DKIM_SIGNED Message has a DKIM or DK signature, ++ not necessarily ++ valid ++ -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature ++ -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from ++ envelope-from domain ++ 0.0 UNPARSEABLE_RELAY Informational: message has unparseable relay ++ lines ++X-BeenThere: linux-mediatek@lists.infradead.org ++X-Mailman-Version: 2.1.29 ++Precedence: list ++List-Id: ++List-Unsubscribe: , ++ ++List-Archive: ++List-Post: ++List-Help: ++List-Subscribe: , ++ ++Cc: devicetree@vger.kernel.org, lorenzo.pieralisi@arm.com, ++ srv_heupstream@mediatek.com, "chuanjia.liu" , ++ linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, ++ jianjun.wang@mediatek.com, linux-mediatek@lists.infradead.org, ++ yong.wu@mediatek.com, bhelgaas@google.com, ++ linux-arm-kernel@lists.infradead.org, amurray@thegoodpenguin.co.uk ++Sender: "Linux-mediatek" ++Errors-To: ++ linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org ++ ++From: "chuanjia.liu" ++ ++There are two independent PCIe controllers in MT2712/MT7622 platform, ++and each of them should contain an independent MSI domain. ++ ++In current architecture, MSI domain will be inherited from the root ++bridge, and all of the devices will share the same MSI domain. ++Hence that, the PCIe devices will not work properly if the irq number ++which required is more than 32. ++ ++Split the PCIe node for MT2712/MT7622 platform to fix MSI issue and ++comply with the hardware design. ++ ++Signed-off-by: chuanjia.liu ++--- ++ .../bindings/pci/mediatek-pcie-cfg.yaml | 38 +++++ ++ .../devicetree/bindings/pci/mediatek-pcie.txt | 144 +++++++++++------- ++ 2 files changed, 129 insertions(+), 53 deletions(-) ++ create mode 100644 Documentation/devicetree/bindings/pci/mediatek-pcie-cfg.yaml ++ ++--- /dev/null +++++ b/Documentation/devicetree/bindings/pci/mediatek-pcie-cfg.yaml ++@@ -0,0 +1,38 @@ +++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +++%YAML 1.2 +++--- +++$id: http://devicetree.org/schemas/pci/mediatek-pcie-cfg.yaml# +++$schema: http://devicetree.org/meta-schemas/core.yaml# +++ +++title: Mediatek PCIECFG controller +++ +++maintainers: +++ - Chuanjia Liu +++ - Jianjun Wang +++ +++description: | +++ The MediaTek PCIECFG controller controls some feature about +++ LTSSM, ASPM and so on. +++ +++properties: +++ compatible: +++ items: +++ - enum: +++ - mediatek,mt7622-pciecfg +++ - mediatek,mt7629-pciecfg +++ - const: syscon +++ +++ reg: +++ maxItems: 1 +++ +++required: +++ - compatible +++ - reg +++ +++examples: +++ - | +++ pciecfg: pciecfg@1a140000 { +++ compatible = "mediatek,mt7622-pciecfg", "syscon"; +++ reg = <0 0x1a140000 0 0x1000>; +++ }; +++... ++--- a/Documentation/devicetree/bindings/pci/mediatek-pcie.txt +++++ b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt ++@@ -8,7 +8,7 @@ Required properties: ++ "mediatek,mt7623-pcie" ++ "mediatek,mt7629-pcie" ++ - device_type: Must be "pci" ++-- reg: Base addresses and lengths of the PCIe subsys and root ports. +++- reg: Base addresses and lengths of the root ports. ++ - reg-names: Names of the above areas to use during resource lookup. ++ - #address-cells: Address representation for root ports (must be 3) ++ - #size-cells: Size representation for root ports (must be 2) ++@@ -19,10 +19,10 @@ Required properties: ++ - sys_ckN :transaction layer and data link layer clock ++ Required entries for MT2701/MT7623: ++ - free_ck :for reference clock of PCIe subsys ++- Required entries for MT2712/MT7622: +++ Required entries for MT2712/MT7622/MT7629: ++ - ahb_ckN :AHB slave interface operating clock for CSR access and RC ++ initiated MMIO access ++- Required entries for MT7622: +++ Required entries for MT7622/MT7629: ++ - axi_ckN :application layer MMIO channel operating clock ++ - aux_ckN :pe2_mac_bridge and pe2_mac_core operating clock when ++ pcie_mac_ck/pcie_pipe_ck is turned off ++@@ -47,10 +47,13 @@ Required properties for MT7623/MT2701: ++ - reset-names: Must be "pcie-rst0", "pcie-rst1", "pcie-rstN".. based on the ++ number of root ports. ++ ++-Required properties for MT2712/MT7622: +++Required properties for MT2712/MT7622/MT7629: ++ -interrupts: A list of interrupt outputs of the controller, must have one ++ entry for each PCIe port ++ +++Required properties for MT7622/MT7629: +++- mediatek,pcie-subsys: Should be a phandle of the pciecfg node. +++ ++ In addition, the device tree node must have sub-nodes describing each ++ PCIe port interface, having the following mandatory properties: ++ ++@@ -143,56 +146,73 @@ Examples for MT7623: ++ ++ Examples for MT2712: ++ ++- pcie: pcie@11700000 { +++ pcie1: pcie@112ff000 { ++ compatible = "mediatek,mt2712-pcie"; ++ device_type = "pci"; ++- reg = <0 0x11700000 0 0x1000>, ++- <0 0x112ff000 0 0x1000>; ++- reg-names = "port0", "port1"; +++ reg = <0 0x112ff000 0 0x1000>; +++ reg-names = "port1"; ++ #address-cells = <3>; ++ #size-cells = <2>; ++- interrupts = , ++- ; ++- clocks = <&topckgen CLK_TOP_PE2_MAC_P0_SEL>, ++- <&topckgen CLK_TOP_PE2_MAC_P1_SEL>, ++- <&pericfg CLK_PERI_PCIE0>, +++ interrupts = ; +++ interrupt-names = "pcie_irq"; +++ clocks = <&topckgen CLK_TOP_PE2_MAC_P1_SEL>, ++ <&pericfg CLK_PERI_PCIE1>; ++- clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1"; ++- phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>; ++- phy-names = "pcie-phy0", "pcie-phy1"; +++ clock-names = "sys_ck1", "ahb_ck1"; +++ phys = <&u3port1 PHY_TYPE_PCIE>; +++ phy-names = "pcie-phy1"; ++ bus-range = <0x00 0xff>; ++- ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; +++ ranges = <0x82000000 0 0x11400000 0x0 0x11400000 0 0x300000>; +++ status = "disabled"; ++ ++- pcie0: pcie@0,0 { ++- reg = <0x0000 0 0 0 0>; +++ slot1: pcie@1,0 { +++ reg = <0x0800 0 0 0 0>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ #interrupt-cells = <1>; ++ ranges; ++ interrupt-map-mask = <0 0 0 7>; ++- interrupt-map = <0 0 0 1 &pcie_intc0 0>, ++- <0 0 0 2 &pcie_intc0 1>, ++- <0 0 0 3 &pcie_intc0 2>, ++- <0 0 0 4 &pcie_intc0 3>; ++- pcie_intc0: interrupt-controller { +++ interrupt-map = <0 0 0 1 &pcie_intc1 0>, +++ <0 0 0 2 &pcie_intc1 1>, +++ <0 0 0 3 &pcie_intc1 2>, +++ <0 0 0 4 &pcie_intc1 3>; +++ pcie_intc1: interrupt-controller { ++ interrupt-controller; ++ #address-cells = <0>; ++ #interrupt-cells = <1>; ++ }; ++ }; +++ }; ++ ++- pcie1: pcie@1,0 { ++- reg = <0x0800 0 0 0 0>; +++ pcie0: pcie@11700000 { +++ compatible = "mediatek,mt2712-pcie"; +++ device_type = "pci"; +++ reg = <0 0x11700000 0 0x1000>; +++ reg-names = "port0"; +++ #address-cells = <3>; +++ #size-cells = <2>; +++ interrupts = ; +++ interrupt-names = "pcie_irq"; +++ clocks = <&topckgen CLK_TOP_PE2_MAC_P0_SEL>, +++ <&pericfg CLK_PERI_PCIE0>; +++ clock-names = "sys_ck0", "ahb_ck0"; +++ phys = <&u3port0 PHY_TYPE_PCIE>; +++ phy-names = "pcie-phy0"; +++ bus-range = <0x00 0xff>; +++ ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; +++ status = "disabled"; +++ +++ slot0: pcie@0,0 { +++ reg = <0x0000 0 0 0 0>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ #interrupt-cells = <1>; ++ ranges; ++ interrupt-map-mask = <0 0 0 7>; ++- interrupt-map = <0 0 0 1 &pcie_intc1 0>, ++- <0 0 0 2 &pcie_intc1 1>, ++- <0 0 0 3 &pcie_intc1 2>, ++- <0 0 0 4 &pcie_intc1 3>; ++- pcie_intc1: interrupt-controller { +++ interrupt-map = <0 0 0 1 &pcie_intc0 0>, +++ <0 0 0 2 &pcie_intc0 1>, +++ <0 0 0 3 &pcie_intc0 2>, +++ <0 0 0 4 &pcie_intc0 3>; +++ pcie_intc0: interrupt-controller { ++ interrupt-controller; ++ #address-cells = <0>; ++ #interrupt-cells = <1>; ++@@ -202,39 +222,31 @@ Examples for MT2712: ++ ++ Examples for MT7622: ++ ++- pcie: pcie@1a140000 { +++ pcie0: pcie@1a143000 { ++ compatible = "mediatek,mt7622-pcie"; ++ device_type = "pci"; ++- reg = <0 0x1a140000 0 0x1000>, ++- <0 0x1a143000 0 0x1000>, ++- <0 0x1a145000 0 0x1000>; ++- reg-names = "subsys", "port0", "port1"; +++ reg = <0 0x1a143000 0 0x1000>; +++ reg-names = "port0"; +++ mediatek,pcie-cfg = <&pciecfg>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++- interrupts = , ++- ; +++ interrupts = ; +++ interrupt-names = "pcie_irq"; ++ clocks = <&pciesys CLK_PCIE_P0_MAC_EN>, ++- <&pciesys CLK_PCIE_P1_MAC_EN>, ++ <&pciesys CLK_PCIE_P0_AHB_EN>, ++- <&pciesys CLK_PCIE_P1_AHB_EN>, ++ <&pciesys CLK_PCIE_P0_AUX_EN>, ++- <&pciesys CLK_PCIE_P1_AUX_EN>, ++ <&pciesys CLK_PCIE_P0_AXI_EN>, ++- <&pciesys CLK_PCIE_P1_AXI_EN>, ++ <&pciesys CLK_PCIE_P0_OBFF_EN>, ++- <&pciesys CLK_PCIE_P1_OBFF_EN>, ++- <&pciesys CLK_PCIE_P0_PIPE_EN>, ++- <&pciesys CLK_PCIE_P1_PIPE_EN>; ++- clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1", ++- "aux_ck0", "aux_ck1", "axi_ck0", "axi_ck1", ++- "obff_ck0", "obff_ck1", "pipe_ck0", "pipe_ck1"; ++- phys = <&pcie0_phy PHY_TYPE_PCIE>, <&pcie1_phy PHY_TYPE_PCIE>; ++- phy-names = "pcie-phy0", "pcie-phy1"; +++ <&pciesys CLK_PCIE_P0_PIPE_EN>; +++ clock-names = "sys_ck0", "ahb_ck0", "aux_ck0", +++ "axi_ck0", "obff_ck0", "pipe_ck0"; +++ ++ power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; ++ bus-range = <0x00 0xff>; ++- ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; +++ ranges = <0x82000000 0 0x20000000 0 0x20000000 0 0x8000000>; +++ status = "disabled"; ++ ++- pcie0: pcie@0,0 { +++ slot0: pcie@0,0 { ++ reg = <0x0000 0 0 0 0>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++@@ -251,8 +263,34 @@ Examples for MT7622: ++ #interrupt-cells = <1>; ++ }; ++ }; +++ }; +++ +++ pcie1: pcie@1a145000 { +++ compatible = "mediatek,mt7622-pcie"; +++ device_type = "pci"; +++ reg = <0 0x1a145000 0 0x1000>; +++ reg-names = "port1"; +++ mediatek,pcie-cfg = <&pciecfg>; +++ #address-cells = <3>; +++ #size-cells = <2>; +++ interrupts = ; +++ interrupt-names = "pcie_irq"; +++ clocks = <&pciesys CLK_PCIE_P1_MAC_EN>, +++ /* designer has connect RC1 with p0_ahb clock */ +++ <&pciesys CLK_PCIE_P0_AHB_EN>, +++ <&pciesys CLK_PCIE_P1_AUX_EN>, +++ <&pciesys CLK_PCIE_P1_AXI_EN>, +++ <&pciesys CLK_PCIE_P1_OBFF_EN>, +++ <&pciesys CLK_PCIE_P1_PIPE_EN>; +++ clock-names = "sys_ck1", "ahb_ck1", "aux_ck1", +++ "axi_ck1", "obff_ck1", "pipe_ck1"; +++ +++ power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; +++ bus-range = <0x00 0xff>; +++ ranges = <0x82000000 0 0x28000000 0 0x28000000 0 0x8000000>; +++ status = "disabled"; ++ ++- pcie1: pcie@1,0 { +++ slot1: pcie@1,0 { ++ reg = <0x0800 0 0 0 0>; ++ #address-cells = <3>; ++ #size-cells = <2>; +diff --git a/target/linux/mediatek/patches-5.10/601-PCI-mediatek-Use-regmap-to-get-shared-pcie-cfg-base.patch b/target/linux/mediatek/patches-5.10/601-PCI-mediatek-Use-regmap-to-get-shared-pcie-cfg-base.patch +new file mode 100644 +index 0000000000..9c18565319 +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/601-PCI-mediatek-Use-regmap-to-get-shared-pcie-cfg-base.patch +@@ -0,0 +1,217 @@ ++From patchwork Thu May 28 06:16:46 2020 ++Content-Type: text/plain; charset="utf-8" ++MIME-Version: 1.0 ++Content-Transfer-Encoding: 7bit ++X-Patchwork-Submitter: Chuanjia Liu ++X-Patchwork-Id: 11574781 ++Return-Path: ++ ++Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org ++ [172.30.200.123]) ++ by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0A99B60D ++ for ; ++ Thu, 28 May 2020 06:19:04 +0000 (UTC) ++Received: from bombadil.infradead.org (bombadil.infradead.org ++ [198.137.202.133]) ++ (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) ++ (No client certificate requested) ++ by mail.kernel.org (Postfix) with ESMTPS id DCC99208FE ++ for ; ++ Thu, 28 May 2020 06:19:03 +0000 (UTC) ++Authentication-Results: mail.kernel.org; ++ dkim=pass (2048-bit key) header.d=lists.infradead.org ++ header.i=@lists.infradead.org header.b="SpOi0ueF"; ++ dkim=fail reason="signature verification failed" (1024-bit key) ++ header.d=mediatek.com header.i=@mediatek.com header.b="UGIBoIEG" ++DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DCC99208FE ++Authentication-Results: mail.kernel.org; ++ dmarc=fail (p=none dis=none) header.from=mediatek.com ++Authentication-Results: mail.kernel.org; ++ spf=none ++ smtp.mailfrom=linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org ++DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; ++ d=lists.infradead.org; s=bombadil.20170209; h=Sender: ++ Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: ++ List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: ++ Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: ++ Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: ++ List-Owner; bh=LIr5poLUT/UdH6/akh/pnICGGa3rUBkN+4FhE1DyOrU=; b=SpOi0ueFcoJ/ka ++ 4esa6cDd5oU4fp0z684ZVPaVvvhm/azSZBBMYinHaAW6EvzKcMNYIX9grP8eg/728lEPNTKVq0I8H ++ PQZ9KvD4uTu8Opo1hD8LsRSLr+YLpNKt3KPOY/4gpwQ97uU9rI5PwkuAxPBgR949Vh5EiG0Vaww1H ++ Ep+I5BFRn2LVVQZP1Z7U0A0VUcOTLJ4znoWRLEXxtM9/Wd4hwQsrEPQszeDFti/RbwGfJ5efOb5UL ++ fhwBzSxELEzAAgH7env/XD2sSSpVf2Qsn6WO8D3ZepMtWrRtARiaRKSNxSBQTg2SSHcjmBSJSzcX+ ++ w8wqWaUMs0crlBuZWS1g==; ++Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) ++ by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) ++ id 1jeBsc-0001tI-88; Thu, 28 May 2020 06:19:02 +0000 ++Received: from mailgw01.mediatek.com ([216.200.240.184]) ++ by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) ++ id 1jeBsZ-0001rp-6g; Thu, 28 May 2020 06:19:01 +0000 ++X-UUID: beeaf5765357439c91eab1f67ca7ef43-20200527 ++DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; ++ d=mediatek.com; ++ s=dk; ++ h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; ++ bh=+IjWjsF/DhknqZB+lLSZ50cyvxDap+8w4tvqhp8Dv68=; ++ b=UGIBoIEGJUuq5pEvYEad1HVGpiv6yma+94hva83D2gD8lYmihRWkpJxB2yn+dVtNm7ZXXoQBf+jvvULOmslJgs1HZTLJTnjpdvLmQqo42OXRXSVpTE49HdRkJZDAIWIAReBfOEkFgNxcIX3uedrtnww/NLJ2lagrYPG5ET4lI2E=; ++X-UUID: beeaf5765357439c91eab1f67ca7ef43-20200527 ++Received: from mtkcas68.mediatek.inc [(172.29.94.19)] by mailgw01.mediatek.com ++ (envelope-from ) ++ (musrelay.mediatek.com ESMTP with TLS) ++ with ESMTP id 603406343; Wed, 27 May 2020 22:19:17 -0800 ++Received: from mtkmbs07n1.mediatek.inc (172.21.101.16) by ++ MTKMBS62DR.mediatek.inc (172.29.94.18) with Microsoft SMTP Server (TLS) id ++ 15.0.1497.2; Wed, 27 May 2020 23:18:47 -0700 ++Received: from mtkcas07.mediatek.inc (172.21.101.84) by ++ mtkmbs07n1.mediatek.inc (172.21.101.16) with Microsoft SMTP Server (TLS) id ++ 15.0.1497.2; Thu, 28 May 2020 14:18:51 +0800 ++Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc ++ (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend ++ Transport; Thu, 28 May 2020 14:18:49 +0800 ++From: ++To: , , ++Subject: [PATCH v2 2/4] PCI: mediatek: Use regmap to get shared pcie-cfg base ++Date: Thu, 28 May 2020 14:16:46 +0800 ++Message-ID: <20200528061648.32078-3-chuanjia.liu@mediatek.com> ++X-Mailer: git-send-email 2.18.0 ++In-Reply-To: <20200528061648.32078-1-chuanjia.liu@mediatek.com> ++References: <20200528061648.32078-1-chuanjia.liu@mediatek.com> ++MIME-Version: 1.0 ++X-MTK: N ++X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 ++X-CRM114-CacheID: sfid-20200527_231859_251275_BED2B1E2 ++X-CRM114-Status: GOOD ( 11.62 ) ++X-Spam-Score: -0.2 (/) ++X-Spam-Report: SpamAssassin version 3.4.4 on bombadil.infradead.org summary: ++ Content analysis details: (-0.2 points) ++ pts rule name description ++ ---- ---------------------- ++ -------------------------------------------------- ++ -0.0 SPF_PASS SPF: sender matches SPF record ++ 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record ++ 0.0 MIME_BASE64_TEXT RAW: Message text disguised using base64 ++ encoding ++ -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from ++ author's domain ++ 0.1 DKIM_SIGNED Message has a DKIM or DK signature, ++ not necessarily ++ valid ++ -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature ++ -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from ++ envelope-from domain ++ 0.0 UNPARSEABLE_RELAY Informational: message has unparseable relay ++ lines ++X-BeenThere: linux-mediatek@lists.infradead.org ++X-Mailman-Version: 2.1.29 ++Precedence: list ++List-Id: ++List-Unsubscribe: , ++ ++List-Archive: ++List-Post: ++List-Help: ++List-Subscribe: , ++ ++Cc: devicetree@vger.kernel.org, lorenzo.pieralisi@arm.com, ++ srv_heupstream@mediatek.com, "chuanjia.liu" , ++ linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, ++ jianjun.wang@mediatek.com, linux-mediatek@lists.infradead.org, ++ yong.wu@mediatek.com, bhelgaas@google.com, ++ linux-arm-kernel@lists.infradead.org, amurray@thegoodpenguin.co.uk ++Sender: "Linux-mediatek" ++Errors-To: ++ linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org ++ ++From: "chuanjia.liu" ++ ++Use regmap to get shared pcie-cfg base and change ++the method to get pcie irq. ++ ++Signed-off-by: chuanjia.liu ++--- ++ drivers/pci/controller/pcie-mediatek.c | 25 ++++++++++++++++++------- ++ 1 file changed, 18 insertions(+), 7 deletions(-) ++ ++--- a/drivers/pci/controller/pcie-mediatek.c +++++ b/drivers/pci/controller/pcie-mediatek.c ++@@ -14,6 +14,7 @@ ++ #include ++ #include ++ #include +++#include ++ #include ++ #include ++ #include ++@@ -23,6 +24,7 @@ ++ #include ++ #include ++ #include +++#include ++ #include ++ ++ #include "../pci.h" ++@@ -205,6 +207,7 @@ struct mtk_pcie_port { ++ * struct mtk_pcie - PCIe host information ++ * @dev: pointer to PCIe device ++ * @base: IO mapped register base +++ * @cfg: IO mapped register map for PCIe config ++ * @free_ck: free-run reference clock ++ * @mem: non-prefetchable memory resource ++ * @ports: pointer to PCIe port information ++@@ -213,6 +216,7 @@ struct mtk_pcie_port { ++ struct mtk_pcie { ++ struct device *dev; ++ void __iomem *base; +++ struct regmap *cfg; ++ struct clk *free_ck; ++ ++ struct list_head ports; ++@@ -648,7 +652,7 @@ static int mtk_pcie_setup_irq(struct mtk ++ return err; ++ } ++ ++- port->irq = platform_get_irq(pdev, port->slot); +++ port->irq = platform_get_irq_byname(pdev, "pcie_irq"); ++ if (port->irq < 0) ++ return port->irq; ++ ++@@ -674,12 +678,11 @@ static int mtk_pcie_startup_port_v2(stru ++ if (!mem) ++ return -EINVAL; ++ ++- /* MT7622 platforms need to enable LTSSM and ASPM from PCIe subsys */ ++- if (pcie->base) { ++- val = readl(pcie->base + PCIE_SYS_CFG_V2); ++- val |= PCIE_CSR_LTSSM_EN(port->slot) | ++- PCIE_CSR_ASPM_L1_EN(port->slot); ++- writel(val, pcie->base + PCIE_SYS_CFG_V2); +++ /* MT7622/MT7629 platforms need to enable LTSSM and ASPM. */ +++ if (pcie->cfg) { +++ val = PCIE_CSR_LTSSM_EN(port->slot) | +++ PCIE_CSR_ASPM_L1_EN(port->slot); +++ regmap_update_bits(pcie->cfg, PCIE_SYS_CFG_V2, val, val); ++ } ++ ++ /* Assert all reset signals */ ++@@ -983,6 +986,7 @@ static int mtk_pcie_subsys_powerup(struc ++ struct device *dev = pcie->dev; ++ struct platform_device *pdev = to_platform_device(dev); ++ struct resource *regs; +++ struct device_node *cfg_node; ++ int err; ++ ++ /* get shared registers, which are optional */ ++@@ -995,6 +999,13 @@ static int mtk_pcie_subsys_powerup(struc ++ } ++ } ++ +++ cfg_node = of_parse_phandle(dev->of_node, "mediatek,pcie-cfg", 0); +++ if (cfg_node) { +++ pcie->cfg = syscon_node_to_regmap(cfg_node); +++ if (IS_ERR(pcie->cfg)) +++ return PTR_ERR(pcie->cfg); +++ } +++ ++ pcie->free_ck = devm_clk_get(dev, "free_ck"); ++ if (IS_ERR(pcie->free_ck)) { ++ if (PTR_ERR(pcie->free_ck) == -EPROBE_DEFER) +diff --git a/target/linux/mediatek/patches-5.10/602-arm64-dts-mediatek-Split-PCIe-node-for-MT2712-MT7622.patch b/target/linux/mediatek/patches-5.10/602-arm64-dts-mediatek-Split-PCIe-node-for-MT2712-MT7622.patch +new file mode 100644 +index 0000000000..fa4a6ce2db +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/602-arm64-dts-mediatek-Split-PCIe-node-for-MT2712-MT7622.patch +@@ -0,0 +1,417 @@ ++From patchwork Thu May 28 06:16:47 2020 ++Content-Type: text/plain; charset="utf-8" ++MIME-Version: 1.0 ++Content-Transfer-Encoding: 7bit ++X-Patchwork-Submitter: Chuanjia Liu ++X-Patchwork-Id: 11574785 ++Return-Path: ++ ++Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org ++ [172.30.200.123]) ++ by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 933301391 ++ for ; ++ Thu, 28 May 2020 06:19:16 +0000 (UTC) ++Received: from bombadil.infradead.org (bombadil.infradead.org ++ [198.137.202.133]) ++ (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) ++ (No client certificate requested) ++ by mail.kernel.org (Postfix) with ESMTPS id D19F02078C ++ for ; ++ Thu, 28 May 2020 06:19:15 +0000 (UTC) ++Authentication-Results: mail.kernel.org; ++ dkim=pass (2048-bit key) header.d=lists.infradead.org ++ header.i=@lists.infradead.org header.b="s8K7t7DF"; ++ dkim=fail reason="signature verification failed" (1024-bit key) ++ header.d=mediatek.com header.i=@mediatek.com header.b="RhX81Iqp" ++DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D19F02078C ++Authentication-Results: mail.kernel.org; ++ dmarc=fail (p=none dis=none) header.from=mediatek.com ++Authentication-Results: mail.kernel.org; ++ spf=none ++ smtp.mailfrom=linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org ++DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; ++ d=lists.infradead.org; s=bombadil.20170209; h=Sender: ++ Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: ++ List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: ++ Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: ++ Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: ++ List-Owner; bh=NHyHqNMcE7LW10MwduOJoKiWe8cv+XayY+L6WDZeSu0=; b=s8K7t7DFh1iQ5w ++ eGvuMRgXEQv/YWRuSZRyX8lx8R2H9IuawEIgkhO6lEo6xv0VdsRuj8SptfoWg5afCItMhih373M21 ++ 6sUy3tEiuKGgklfxLU0reLEkaATkKRGLJDY3eSSs1mvZDrydKuZLDTka+YDGaiESlOhqMr95Nm6YM ++ yK8O00qTwSRPJUILRsBv1e/Kz8NRCmYhs56snABJkKeJ51NRAkb20R6qGTEd6UyBlz3jTVYwluLgF ++ bdqzywDT6+BNg/Agh6Zd+v2PpO4cmwCpGm62+3UUyZkfi/aQ4qZ/AFAfSQI+3ZBAgsKMC1PGifOi/ ++ FgGxIvAUk6atBy7DAHuw==; ++Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) ++ by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) ++ id 1jeBsn-00025C-EF; Thu, 28 May 2020 06:19:13 +0000 ++Received: from mailgw01.mediatek.com ([216.200.240.184]) ++ by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) ++ id 1jeBsZ-0001s4-6j; Thu, 28 May 2020 06:19:01 +0000 ++X-UUID: c6210e6371fa445db0ae40a8b8a7a0a1-20200527 ++DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; ++ d=mediatek.com; ++ s=dk; ++ h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; ++ bh=X9AwTdbhpWmlWY4LjTm8KLq4Cca3YI9UnyCX3O0BAak=; ++ b=RhX81Iqp0mWhBDyMQMFSEtt23+DGAWoin1SrFGP1bzp6GEtu38b2pK5RJVBshJtuxi/a1uMXZjeDsHJn02VGdNA07FrzZ7jq6YYEL+8cJs2DnhySmNElZazXPv2vKu9TWygfilTT24h/u8V/eszuRuhkdoUKWol8LwDlPl9gskg=; ++X-UUID: c6210e6371fa445db0ae40a8b8a7a0a1-20200527 ++Received: from mtkcas68.mediatek.inc [(172.29.94.19)] by mailgw01.mediatek.com ++ (envelope-from ) ++ (musrelay.mediatek.com ESMTP with TLS) ++ with ESMTP id 7561992; Wed, 27 May 2020 22:19:17 -0800 ++Received: from mtkmbs07n1.mediatek.inc (172.21.101.16) by ++ MTKMBS62DR.mediatek.inc (172.29.94.18) with Microsoft SMTP Server (TLS) id ++ 15.0.1497.2; Wed, 27 May 2020 23:18:47 -0700 ++Received: from mtkcas07.mediatek.inc (172.21.101.84) by ++ mtkmbs07n1.mediatek.inc (172.21.101.16) with Microsoft SMTP Server (TLS) id ++ 15.0.1497.2; Thu, 28 May 2020 14:18:52 +0800 ++Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc ++ (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend ++ Transport; Thu, 28 May 2020 14:18:51 +0800 ++From: ++To: , , ++Subject: [PATCH v2 3/4] arm64: dts: mediatek: Split PCIe node for ++ MT2712/MT7622 ++Date: Thu, 28 May 2020 14:16:47 +0800 ++Message-ID: <20200528061648.32078-4-chuanjia.liu@mediatek.com> ++X-Mailer: git-send-email 2.18.0 ++In-Reply-To: <20200528061648.32078-1-chuanjia.liu@mediatek.com> ++References: <20200528061648.32078-1-chuanjia.liu@mediatek.com> ++MIME-Version: 1.0 ++X-MTK: N ++X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 ++X-CRM114-CacheID: sfid-20200527_231859_253529_B6751C5A ++X-CRM114-Status: GOOD ( 12.20 ) ++X-Spam-Score: -0.2 (/) ++X-Spam-Report: SpamAssassin version 3.4.4 on bombadil.infradead.org summary: ++ Content analysis details: (-0.2 points) ++ pts rule name description ++ ---- ---------------------- ++ -------------------------------------------------- ++ -0.0 SPF_PASS SPF: sender matches SPF record ++ 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record ++ 0.0 MIME_BASE64_TEXT RAW: Message text disguised using base64 ++ encoding ++ -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from ++ author's domain ++ 0.1 DKIM_SIGNED Message has a DKIM or DK signature, ++ not necessarily ++ valid ++ -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature ++ -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from ++ envelope-from domain ++ 0.0 UNPARSEABLE_RELAY Informational: message has unparseable relay ++ lines ++X-BeenThere: linux-mediatek@lists.infradead.org ++X-Mailman-Version: 2.1.29 ++Precedence: list ++List-Id: ++List-Unsubscribe: , ++ ++List-Archive: ++List-Post: ++List-Help: ++List-Subscribe: , ++ ++Cc: devicetree@vger.kernel.org, lorenzo.pieralisi@arm.com, ++ srv_heupstream@mediatek.com, "chuanjia.liu" , ++ linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, ++ jianjun.wang@mediatek.com, linux-mediatek@lists.infradead.org, ++ yong.wu@mediatek.com, bhelgaas@google.com, ++ linux-arm-kernel@lists.infradead.org, amurray@thegoodpenguin.co.uk ++Sender: "Linux-mediatek" ++Errors-To: ++ linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org ++ ++From: "chuanjia.liu" ++ ++There are two independent PCIe controllers in MT2712/MT7622 platform, ++and each of them should contain an independent MSI domain. ++ ++In current architecture, MSI domain will be inherited from the root ++bridge, and all of the devices will share the same MSI domain. ++Hence that, the PCIe devices will not work properly if the irq number ++which required is more than 32. ++ ++Split the PCIe node for MT2712/MT7622 platform to fix MSI issue and ++comply with the hardware design. ++ ++Signed-off-by: chuanjia.liu ++--- ++ arch/arm64/boot/dts/mediatek/mt2712e.dtsi | 75 +++++++++++-------- ++ .../dts/mediatek/mt7622-bananapi-bpi-r64.dts | 16 ++-- ++ arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 6 +- ++ arch/arm64/boot/dts/mediatek/mt7622.dtsi | 68 +++++++++++------ ++ 4 files changed, 96 insertions(+), 69 deletions(-) ++ ++--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi +++++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi ++@@ -915,60 +915,73 @@ ++ }; ++ }; ++ ++- pcie: pcie@11700000 { +++ pcie1: pcie@112ff000 { ++ compatible = "mediatek,mt2712-pcie"; ++ device_type = "pci"; ++- reg = <0 0x11700000 0 0x1000>, ++- <0 0x112ff000 0 0x1000>; ++- reg-names = "port0", "port1"; +++ reg = <0 0x112ff000 0 0x1000>; +++ reg-names = "port1"; ++ #address-cells = <3>; ++ #size-cells = <2>; ++- interrupts = , ++- ; ++- clocks = <&topckgen CLK_TOP_PE2_MAC_P0_SEL>, ++- <&topckgen CLK_TOP_PE2_MAC_P1_SEL>, ++- <&pericfg CLK_PERI_PCIE0>, +++ interrupts = ; +++ interrupt-names = "pcie_irq"; +++ clocks = <&topckgen CLK_TOP_PE2_MAC_P1_SEL>, ++ <&pericfg CLK_PERI_PCIE1>; ++- clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1"; ++- phys = <&u3port0 PHY_TYPE_PCIE>, <&u3port1 PHY_TYPE_PCIE>; ++- phy-names = "pcie-phy0", "pcie-phy1"; +++ clock-names = "sys_ck1", "ahb_ck1"; +++ phys = <&u3port1 PHY_TYPE_PCIE>; +++ phy-names = "pcie-phy1"; ++ bus-range = <0x00 0xff>; ++- ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; +++ ranges = <0x82000000 0 0x11400000 0x0 0x11400000 0 0x300000>; +++ status = "disabled"; ++ ++- pcie0: pcie@0,0 { ++- device_type = "pci"; ++- status = "disabled"; ++- reg = <0x0000 0 0 0 0>; +++ slot1: pcie@1,0 { +++ reg = <0x0800 0 0 0 0>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ #interrupt-cells = <1>; ++ ranges; ++ interrupt-map-mask = <0 0 0 7>; ++- interrupt-map = <0 0 0 1 &pcie_intc0 0>, ++- <0 0 0 2 &pcie_intc0 1>, ++- <0 0 0 3 &pcie_intc0 2>, ++- <0 0 0 4 &pcie_intc0 3>; ++- pcie_intc0: interrupt-controller { +++ interrupt-map = <0 0 0 1 &pcie_intc1 0>, +++ <0 0 0 2 &pcie_intc1 1>, +++ <0 0 0 3 &pcie_intc1 2>, +++ <0 0 0 4 &pcie_intc1 3>; +++ pcie_intc1: interrupt-controller { ++ interrupt-controller; ++ #address-cells = <0>; ++ #interrupt-cells = <1>; ++ }; ++ }; +++ }; ++ ++- pcie1: pcie@1,0 { ++- device_type = "pci"; ++- status = "disabled"; ++- reg = <0x0800 0 0 0 0>; +++ pcie0: pcie@11700000 { +++ compatible = "mediatek,mt2712-pcie"; +++ device_type = "pci"; +++ reg = <0 0x11700000 0 0x1000>; +++ reg-names = "port0"; +++ #address-cells = <3>; +++ #size-cells = <2>; +++ interrupts = ; +++ interrupt-names = "pcie_irq"; +++ clocks = <&topckgen CLK_TOP_PE2_MAC_P0_SEL>, +++ <&pericfg CLK_PERI_PCIE0>; +++ clock-names = "sys_ck0", "ahb_ck0"; +++ phys = <&u3port0 PHY_TYPE_PCIE>; +++ phy-names = "pcie-phy0"; +++ bus-range = <0x00 0xff>; +++ ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; +++ status = "disabled"; +++ +++ slot0: pcie@0,0 { +++ reg = <0x0000 0 0 0 0>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ #interrupt-cells = <1>; ++ ranges; ++ interrupt-map-mask = <0 0 0 7>; ++- interrupt-map = <0 0 0 1 &pcie_intc1 0>, ++- <0 0 0 2 &pcie_intc1 1>, ++- <0 0 0 3 &pcie_intc1 2>, ++- <0 0 0 4 &pcie_intc1 3>; ++- pcie_intc1: interrupt-controller { +++ interrupt-map = <0 0 0 1 &pcie_intc0 0>, +++ <0 0 0 2 &pcie_intc0 1>, +++ <0 0 0 3 &pcie_intc0 2>, +++ <0 0 0 4 &pcie_intc0 3>; +++ pcie_intc0: interrupt-controller { ++ interrupt-controller; ++ #address-cells = <0>; ++ #interrupt-cells = <1>; ++--- a/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts +++++ b/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts ++@@ -257,18 +257,16 @@ ++ }; ++ }; ++ ++-&pcie { +++&pcie0 { ++ pinctrl-names = "default"; ++- pinctrl-0 = <&pcie0_pins>, <&pcie1_pins>; +++ pinctrl-0 = <&pcie0_pins>; ++ status = "okay"; +++}; ++ ++- pcie@0,0 { ++- status = "okay"; ++- }; ++- ++- pcie@1,0 { ++- status = "okay"; ++- }; +++&pcie1 { +++ pinctrl-names = "default"; +++ pinctrl-0 = <&pcie1_pins>; +++ status = "okay"; ++ }; ++ ++ &pio { ++--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi +++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi ++@@ -792,45 +792,41 @@ ++ #reset-cells = <1>; ++ }; ++ ++- pcie: pcie@1a140000 { +++ pciecfg: pciecfg@1a140000 { +++ compatible = "mediatek,mt7622-pciecfg", "syscon"; +++ reg = <0 0x1a140000 0 0x1000>; +++ }; +++ +++ pcie0: pcie@1a143000 { ++ compatible = "mediatek,mt7622-pcie"; ++ device_type = "pci"; ++- reg = <0 0x1a140000 0 0x1000>, ++- <0 0x1a143000 0 0x1000>, ++- <0 0x1a145000 0 0x1000>; ++- reg-names = "subsys", "port0", "port1"; +++ reg = <0 0x1a143000 0 0x1000>; +++ reg-names = "port0"; +++ mediatek,pcie-cfg = <&pciecfg>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++- interrupts = , ++- ; +++ interrupts = ; +++ interrupt-names = "pcie_irq"; ++ clocks = <&pciesys CLK_PCIE_P0_MAC_EN>, ++- <&pciesys CLK_PCIE_P1_MAC_EN>, ++- <&pciesys CLK_PCIE_P0_AHB_EN>, ++ <&pciesys CLK_PCIE_P0_AHB_EN>, ++ <&pciesys CLK_PCIE_P0_AUX_EN>, ++- <&pciesys CLK_PCIE_P1_AUX_EN>, ++ <&pciesys CLK_PCIE_P0_AXI_EN>, ++- <&pciesys CLK_PCIE_P1_AXI_EN>, ++ <&pciesys CLK_PCIE_P0_OBFF_EN>, ++- <&pciesys CLK_PCIE_P1_OBFF_EN>, ++- <&pciesys CLK_PCIE_P0_PIPE_EN>, ++- <&pciesys CLK_PCIE_P1_PIPE_EN>; ++- clock-names = "sys_ck0", "sys_ck1", "ahb_ck0", "ahb_ck1", ++- "aux_ck0", "aux_ck1", "axi_ck0", "axi_ck1", ++- "obff_ck0", "obff_ck1", "pipe_ck0", "pipe_ck1"; +++ <&pciesys CLK_PCIE_P0_PIPE_EN>; +++ clock-names = "sys_ck0", "ahb_ck0", "aux_ck0", +++ "axi_ck0", "obff_ck0", "pipe_ck0"; +++ ++ power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; ++ bus-range = <0x00 0xff>; ++- ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x10000000>; +++ ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x8000000>; ++ status = "disabled"; ++ ++- pcie0: pcie@0,0 { +++ slot0: pcie@0,0 { ++ reg = <0x0000 0 0 0 0>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ #interrupt-cells = <1>; ++ ranges; ++- status = "disabled"; ++- ++ interrupt-map-mask = <0 0 0 7>; ++ interrupt-map = <0 0 0 1 &pcie_intc0 0>, ++ <0 0 0 2 &pcie_intc0 1>, ++@@ -842,15 +838,39 @@ ++ #interrupt-cells = <1>; ++ }; ++ }; +++ }; ++ ++- pcie1: pcie@1,0 { +++ pcie1: pcie@1a145000 { +++ compatible = "mediatek,mt7622-pcie"; +++ device_type = "pci"; +++ reg = <0 0x1a145000 0 0x1000>; +++ reg-names = "port1"; +++ mediatek,pcie-cfg = <&pciecfg>; +++ #address-cells = <3>; +++ #size-cells = <2>; +++ interrupts = ; +++ interrupt-names = "pcie_irq"; +++ clocks = <&pciesys CLK_PCIE_P1_MAC_EN>, +++ /* designer has connect RC1 with p0_ahb clock */ +++ <&pciesys CLK_PCIE_P0_AHB_EN>, +++ <&pciesys CLK_PCIE_P1_AUX_EN>, +++ <&pciesys CLK_PCIE_P1_AXI_EN>, +++ <&pciesys CLK_PCIE_P1_OBFF_EN>, +++ <&pciesys CLK_PCIE_P1_PIPE_EN>; +++ clock-names = "sys_ck1", "ahb_ck1", "aux_ck1", +++ "axi_ck1", "obff_ck1", "pipe_ck1"; +++ +++ power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; +++ bus-range = <0x00 0xff>; +++ ranges = <0x82000000 0 0x28000000 0x0 0x28000000 0 0x8000000>; +++ status = "disabled"; +++ +++ slot1: pcie@1,0 { ++ reg = <0x0800 0 0 0 0>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ #interrupt-cells = <1>; ++ ranges; ++- status = "disabled"; ++- ++ interrupt-map-mask = <0 0 0 7>; ++ interrupt-map = <0 0 0 1 &pcie_intc1 0>, ++ <0 0 0 2 &pcie_intc1 1>, ++--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts +++++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts ++@@ -232,18 +232,16 @@ ++ }; ++ }; ++ ++-&pcie { +++&pcie0 { ++ pinctrl-names = "default"; ++- pinctrl-0 = <&pcie0_pins>, <&pcie1_pins>; +++ pinctrl-0 = <&pcie0_pins>; ++ status = "okay"; +++}; ++ ++- pcie@0,0 { ++- status = "okay"; ++- }; ++- ++- pcie@1,0 { ++- status = "okay"; ++- }; +++&pcie1 { +++ pinctrl-names = "default"; +++ pinctrl-0 = <&pcie1_pins>; +++ status = "okay"; ++ }; ++ ++ &pio { +diff --git a/target/linux/mediatek/patches-5.10/603-ARM-dts-mediatek-Update-mt7629-PCIe-node.patch b/target/linux/mediatek/patches-5.10/603-ARM-dts-mediatek-Update-mt7629-PCIe-node.patch +new file mode 100644 +index 0000000000..799cc31ab7 +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/603-ARM-dts-mediatek-Update-mt7629-PCIe-node.patch +@@ -0,0 +1,203 @@ ++From patchwork Thu May 28 06:16:48 2020 ++Content-Type: text/plain; charset="utf-8" ++MIME-Version: 1.0 ++Content-Transfer-Encoding: 7bit ++X-Patchwork-Submitter: Chuanjia Liu ++X-Patchwork-Id: 11574797 ++Return-Path: ++ ++Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org ++ [172.30.200.123]) ++ by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 30A5E1392 ++ for ; ++ Thu, 28 May 2020 06:29:05 +0000 (UTC) ++Received: from bombadil.infradead.org (bombadil.infradead.org ++ [198.137.202.133]) ++ (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) ++ (No client certificate requested) ++ by mail.kernel.org (Postfix) with ESMTPS id 08B6320721 ++ for ; ++ Thu, 28 May 2020 06:29:05 +0000 (UTC) ++Authentication-Results: mail.kernel.org; ++ dkim=pass (2048-bit key) header.d=lists.infradead.org ++ header.i=@lists.infradead.org header.b="auhxDafY"; ++ dkim=fail reason="signature verification failed" (1024-bit key) ++ header.d=mediatek.com header.i=@mediatek.com header.b="Kj09Arxb" ++DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 08B6320721 ++Authentication-Results: mail.kernel.org; ++ dmarc=fail (p=none dis=none) header.from=mediatek.com ++Authentication-Results: mail.kernel.org; ++ spf=none ++ smtp.mailfrom=linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org ++DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; ++ d=lists.infradead.org; s=bombadil.20170209; h=Sender: ++ Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: ++ List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: ++ Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: ++ Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: ++ List-Owner; bh=+QPxF1vlOH7StIZYuXJa3V40x8QVDxCLF9AFXHblB9M=; b=auhxDafYBeaUZO ++ aYp2KVO8Aie0v4tYtRwBon7hF+x55JwD78SAxQR2RsSvrlOo9cMYYby+ToUWflVUWQ60FapAl+w+l ++ nkEjIOrLBErHwxNOcsD8T5kjyCBMqlz4OMAQYUDNJ3fSugRlGhOtxkjCGd9ebB8N2Rvu6/U8P1A9n ++ P15mEQoc+RLonR1+9mBgwTEXErjsraxkimTD4Txsp4IvMs3UdsMkP+r3OT5S/p+Uj6O9ES0h7xIon ++ aL79KaVqRLHrfZxnrVwuGiecAiTp8qLy9clHuJU32NA6ZcXH1OnWipKApgp8Ck7ys80WPKaMrat9B ++ XuskJ63w13DZAbCVvuGQ==; ++Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) ++ by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) ++ id 1jeC2J-00014n-M9; Thu, 28 May 2020 06:29:03 +0000 ++Received: from mailgw02.mediatek.com ([216.200.240.185]) ++ by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) ++ id 1jeC2H-00013t-Li; Thu, 28 May 2020 06:29:03 +0000 ++X-UUID: a4877c1586e64afeb2d6172e10605d2b-20200527 ++DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; ++ d=mediatek.com; ++ s=dk; ++ h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; ++ bh=CIwcBFK1x0LbOjDt1BG6/knHFxDHRiqj8ov/jWEZDBY=; ++ b=Kj09ArxbnLVTc9bpaVPT3jQrIVjhL87sSYyVF9dFypS976k78Ce9gZd0f4K3zAZbYZHYoQtuyOQ9TOeufQfgD+Cr+j5VR7pTdO2E1iXHFs/eQAz5gAjvjlK01z1JiunrLnn9dvIr6c1gEkjQHny0VpuZ1duxx79jwYusg/Nw6Wc=; ++X-UUID: a4877c1586e64afeb2d6172e10605d2b-20200527 ++Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by ++ mailgw02.mediatek.com ++ (envelope-from ) ++ (musrelay.mediatek.com ESMTP with TLS) ++ with ESMTP id 899663677; Wed, 27 May 2020 22:29:21 -0800 ++Received: from MTKMBS07N2.mediatek.inc (172.21.101.141) by ++ MTKMBS62DR.mediatek.inc (172.29.94.18) with Microsoft SMTP Server (TLS) id ++ 15.0.1497.2; Wed, 27 May 2020 23:18:50 -0700 ++Received: from mtkcas07.mediatek.inc (172.21.101.84) by ++ mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server (TLS) id ++ 15.0.1497.2; Thu, 28 May 2020 14:18:54 +0800 ++Received: from localhost.localdomain (10.17.3.153) by mtkcas07.mediatek.inc ++ (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend ++ Transport; Thu, 28 May 2020 14:18:52 +0800 ++From: ++To: , , ++Subject: [PATCH v2 4/4] ARM: dts: mediatek: Update mt7629 PCIe node ++Date: Thu, 28 May 2020 14:16:48 +0800 ++Message-ID: <20200528061648.32078-5-chuanjia.liu@mediatek.com> ++X-Mailer: git-send-email 2.18.0 ++In-Reply-To: <20200528061648.32078-1-chuanjia.liu@mediatek.com> ++References: <20200528061648.32078-1-chuanjia.liu@mediatek.com> ++MIME-Version: 1.0 ++X-MTK: N ++X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 ++X-CRM114-CacheID: sfid-20200527_232901_719172_E5A99C62 ++X-CRM114-Status: GOOD ( 11.61 ) ++X-Spam-Score: -0.2 (/) ++X-Spam-Report: SpamAssassin version 3.4.4 on bombadil.infradead.org summary: ++ Content analysis details: (-0.2 points) ++ pts rule name description ++ ---- ---------------------- ++ -------------------------------------------------- ++ -0.0 SPF_PASS SPF: sender matches SPF record ++ 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record ++ 0.0 MIME_BASE64_TEXT RAW: Message text disguised using base64 ++ encoding ++ -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from ++ author's domain ++ 0.1 DKIM_SIGNED Message has a DKIM or DK signature, ++ not necessarily ++ valid ++ -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature ++ -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from ++ envelope-from domain ++ 0.0 UNPARSEABLE_RELAY Informational: message has unparseable relay ++ lines ++X-BeenThere: linux-mediatek@lists.infradead.org ++X-Mailman-Version: 2.1.29 ++Precedence: list ++List-Id: ++List-Unsubscribe: , ++ ++List-Archive: ++List-Post: ++List-Help: ++List-Subscribe: , ++ ++Cc: devicetree@vger.kernel.org, lorenzo.pieralisi@arm.com, ++ srv_heupstream@mediatek.com, "chuanjia.liu" , ++ linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, ++ jianjun.wang@mediatek.com, linux-mediatek@lists.infradead.org, ++ yong.wu@mediatek.com, bhelgaas@google.com, ++ linux-arm-kernel@lists.infradead.org, amurray@thegoodpenguin.co.uk ++Sender: "Linux-mediatek" ++Errors-To: ++ linux-mediatek-bounces+patchwork-linux-mediatek=patchwork.kernel.org@lists.infradead.org ++ ++From: "chuanjia.liu" ++ ++Remove unused property and add pciecfg node. ++ ++Signed-off-by: chuanjia.liu ++--- ++ arch/arm/boot/dts/mt7629-rfb.dts | 3 ++- ++ arch/arm/boot/dts/mt7629.dtsi | 23 +++++++++++++---------- ++ 2 files changed, 15 insertions(+), 11 deletions(-) ++ ++--- a/arch/arm/boot/dts/mt7629-rfb.dts +++++ b/arch/arm/boot/dts/mt7629-rfb.dts ++@@ -144,9 +144,10 @@ ++ }; ++ }; ++ ++-&pcie { +++&pcie1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie_pins>; +++ status = "okay"; ++ }; ++ ++ &pciephy1 { ++--- a/arch/arm/boot/dts/mt7629.dtsi +++++ b/arch/arm/boot/dts/mt7629.dtsi ++@@ -382,16 +382,21 @@ ++ #reset-cells = <1>; ++ }; ++ ++- pcie: pcie@1a140000 { +++ pciecfg: pciecfg@1a140000 { +++ compatible = "mediatek,mt7629-pciecfg", "syscon"; +++ reg = <0x1a140000 0x1000>; +++ }; +++ +++ pcie1: pcie@1a145000 { ++ compatible = "mediatek,mt7629-pcie"; ++ device_type = "pci"; ++- reg = <0x1a140000 0x1000>, ++- <0x1a145000 0x1000>; ++- reg-names = "subsys","port1"; +++ reg = <0x1a145000 0x1000>; +++ reg-names = "port1"; +++ mediatek,pcie-cfg = <&pciecfg>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++- interrupts = , ++- ; +++ interrupts = ; +++ interrupt-names = "pcie_irq"; ++ clocks = <&pciesys CLK_PCIE_P1_MAC_EN>, ++ <&pciesys CLK_PCIE_P0_AHB_EN>, ++ <&pciesys CLK_PCIE_P1_AUX_EN>, ++@@ -412,21 +417,19 @@ ++ power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>; ++ bus-range = <0x00 0xff>; ++ ranges = <0x82000000 0 0x20000000 0x20000000 0 0x10000000>; +++ status = "disabled"; ++ ++- pcie1: pcie@1,0 { ++- device_type = "pci"; +++ slot1: pcie@1,0 { ++ reg = <0x0800 0 0 0 0>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ #interrupt-cells = <1>; ++ ranges; ++- num-lanes = <1>; ++ interrupt-map-mask = <0 0 0 7>; ++ interrupt-map = <0 0 0 1 &pcie_intc1 0>, ++ <0 0 0 2 &pcie_intc1 1>, ++ <0 0 0 3 &pcie_intc1 2>, ++ <0 0 0 4 &pcie_intc1 3>; ++- ++ pcie_intc1: interrupt-controller { ++ interrupt-controller; ++ #address-cells = <0>; +diff --git a/target/linux/mediatek/patches-5.10/610-pcie-mediatek-fix-clearing-interrupt-status.patch b/target/linux/mediatek/patches-5.10/610-pcie-mediatek-fix-clearing-interrupt-status.patch +new file mode 100644 +index 0000000000..7b74a8ac73 +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/610-pcie-mediatek-fix-clearing-interrupt-status.patch +@@ -0,0 +1,24 @@ ++From: Felix Fietkau ++Date: Fri, 4 Sep 2020 18:33:27 +0200 ++Subject: [PATCH] pcie-mediatek: fix clearing interrupt status ++ ++Clearing the status needs to happen after running the handler, otherwise ++we will get an extra spurious interrupt after the cause has been cleared ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/drivers/pci/controller/pcie-mediatek.c +++++ b/drivers/pci/controller/pcie-mediatek.c ++@@ -613,10 +613,10 @@ static void mtk_pcie_intr_handler(struct ++ if (status & INTX_MASK) { ++ for_each_set_bit_from(bit, &status, PCI_NUM_INTX + INTX_SHIFT) { ++ /* Clear the INTx */ ++- writel(1 << bit, port->base + PCIE_INT_STATUS); ++ virq = irq_find_mapping(port->irq_domain, ++ bit - INTX_SHIFT); ++ generic_handle_irq(virq); +++ writel(1 << bit, port->base + PCIE_INT_STATUS); ++ } ++ } ++ +diff --git a/target/linux/mediatek/patches-5.10/700-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch b/target/linux/mediatek/patches-5.10/700-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch +new file mode 100644 +index 0000000000..8c9194e5f2 +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/700-net-ethernet-mtk_eth_soc-add-support-for-coherent-DM.patch +@@ -0,0 +1,85 @@ ++From: Felix Fietkau ++Date: Fri, 4 Sep 2020 18:36:06 +0200 ++Subject: [PATCH] net: ethernet: mtk_eth_soc: add support for coherent DMA ++ ++It improves performance by eliminating the need for a cache flush on rx and tx ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi +++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi ++@@ -357,7 +357,7 @@ ++ }; ++ ++ cci_control2: slave-if@5000 { ++- compatible = "arm,cci-400-ctrl-if"; +++ compatible = "arm,cci-400-ctrl-if", "syscon"; ++ interface-type = "ace"; ++ reg = <0x5000 0x1000>; ++ }; ++@@ -967,6 +967,8 @@ ++ power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>; ++ mediatek,ethsys = <ðsys>; ++ mediatek,sgmiisys = <&sgmiisys>; +++ mediatek,cci-control = <&cci_control2>; +++ dma-coherent; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c ++@@ -9,6 +9,7 @@ ++ #include ++ #include ++ #include +++#include ++ #include ++ #include ++ #include ++@@ -2482,6 +2483,13 @@ static int mtk_hw_init(struct mtk_eth *e ++ if (ret) ++ goto err_disable_pm; ++ +++ if (of_dma_is_coherent(eth->dev->of_node)) { +++ u32 mask = ETHSYS_DMA_AG_MAP_PDMA | ETHSYS_DMA_AG_MAP_QDMA | +++ ETHSYS_DMA_AG_MAP_PPE; +++ +++ regmap_update_bits(eth->ethsys, ETHSYS_DMA_AG_MAP, mask, mask); +++ } +++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) { ++ ret = device_reset(eth->dev); ++ if (ret) { ++@@ -3061,6 +3069,16 @@ static int mtk_probe(struct platform_dev ++ } ++ } ++ +++ if (of_dma_is_coherent(pdev->dev.of_node)) { +++ struct regmap *cci; +++ +++ cci = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, +++ "mediatek,cci-control"); +++ /* enable CPU/bus coherency */ +++ if (!IS_ERR(cci)) +++ regmap_write(cci, 0, 3); +++ } +++ ++ if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) { ++ eth->sgmii = devm_kzalloc(eth->dev, sizeof(*eth->sgmii), ++ GFP_KERNEL); ++--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++@@ -437,6 +437,12 @@ ++ #define RSTCTRL_FE BIT(6) ++ #define RSTCTRL_PPE BIT(31) ++ +++/* ethernet dma channel agent map */ +++#define ETHSYS_DMA_AG_MAP 0x408 +++#define ETHSYS_DMA_AG_MAP_PDMA BIT(0) +++#define ETHSYS_DMA_AG_MAP_QDMA BIT(1) +++#define ETHSYS_DMA_AG_MAP_PPE BIT(2) +++ ++ /* SGMII subsystem config registers */ ++ /* Register to auto-negotiation restart */ ++ #define SGMSYS_PCS_CONTROL_1 0x0 +diff --git a/target/linux/mediatek/patches-5.10/710-pci-pcie-mediatek-add-support-for-coherent-DMA.patch b/target/linux/mediatek/patches-5.10/710-pci-pcie-mediatek-add-support-for-coherent-DMA.patch +new file mode 100644 +index 0000000000..503cc8937d +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/710-pci-pcie-mediatek-add-support-for-coherent-DMA.patch +@@ -0,0 +1,108 @@ ++From: Felix Fietkau ++Date: Fri, 4 Sep 2020 18:42:42 +0200 ++Subject: [PATCH] pci: pcie-mediatek: add support for coherent DMA ++ ++It improves performance by eliminating the need for a cache flush for DMA on ++attached devices ++ ++Signed-off-by: Felix Fietkau ++--- ++ ++--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi +++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi ++@@ -803,6 +803,8 @@ ++ reg = <0 0x1a143000 0 0x1000>; ++ reg-names = "port0"; ++ mediatek,pcie-cfg = <&pciecfg>; +++ mediatek,hifsys = <&hifsys>; +++ mediatek,cci-control = <&cci_control2>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ interrupts = ; ++@@ -820,6 +822,7 @@ ++ bus-range = <0x00 0xff>; ++ ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x8000000>; ++ status = "disabled"; +++ dma-coherent; ++ ++ slot0: pcie@0,0 { ++ reg = <0x0000 0 0 0 0>; ++@@ -846,6 +849,8 @@ ++ reg = <0 0x1a145000 0 0x1000>; ++ reg-names = "port1"; ++ mediatek,pcie-cfg = <&pciecfg>; +++ mediatek,hifsys = <&hifsys>; +++ mediatek,cci-control = <&cci_control2>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ interrupts = ; ++@@ -864,6 +869,7 @@ ++ bus-range = <0x00 0xff>; ++ ranges = <0x82000000 0 0x28000000 0x0 0x28000000 0 0x8000000>; ++ status = "disabled"; +++ dma-coherent; ++ ++ slot1: pcie@1,0 { ++ reg = <0x0800 0 0 0 0>; ++@@ -923,6 +929,11 @@ ++ }; ++ }; ++ +++ hifsys: syscon@1af00000 { +++ compatible = "mediatek,mt7622-hifsys", "syscon"; +++ reg = <0 0x1af00000 0 0x70>; +++ }; +++ ++ ethsys: syscon@1b000000 { ++ compatible = "mediatek,mt7622-ethsys", ++ "syscon"; ++--- a/drivers/pci/controller/pcie-mediatek.c +++++ b/drivers/pci/controller/pcie-mediatek.c ++@@ -20,6 +20,7 @@ ++ #include ++ #include ++ #include +++#include ++ #include ++ #include ++ #include ++@@ -139,6 +140,11 @@ ++ #define PCIE_LINK_STATUS_V2 0x804 ++ #define PCIE_PORT_LINKUP_V2 BIT(10) ++ +++/* DMA channel mapping */ +++#define HIFSYS_DMA_AG_MAP 0x008 +++#define HIFSYS_DMA_AG_MAP_PCIE0 BIT(0) +++#define HIFSYS_DMA_AG_MAP_PCIE1 BIT(1) +++ ++ struct mtk_pcie_port; ++ ++ /** ++@@ -1040,6 +1046,27 @@ static int mtk_pcie_setup(struct mtk_pci ++ struct mtk_pcie_port *port, *tmp; ++ int err; ++ +++ if (of_dma_is_coherent(node)) { +++ struct regmap *con; +++ u32 mask; +++ +++ con = syscon_regmap_lookup_by_phandle(node, +++ "mediatek,cci-control"); +++ /* enable CPU/bus coherency */ +++ if (!IS_ERR(con)) +++ regmap_write(con, 0, 3); +++ +++ con = syscon_regmap_lookup_by_phandle(node, +++ "mediatek,hifsys"); +++ if (IS_ERR(con)) { +++ dev_err(dev, "missing hifsys node\n"); +++ return PTR_ERR(con); +++ } +++ +++ mask = HIFSYS_DMA_AG_MAP_PCIE0 | HIFSYS_DMA_AG_MAP_PCIE1; +++ regmap_update_bits(con, HIFSYS_DMA_AG_MAP, mask, mask); +++ } +++ ++ for_each_available_child_of_node(node, child) { ++ int slot; ++ +-- +2.25.1 + diff --git a/backports/0013-mediatek-add-support-for-configuring-BMT-table-size-.patch b/backports/0013-mediatek-add-support-for-configuring-BMT-table-size-.patch new file mode 100644 index 000000000..ccb3406a6 --- /dev/null +++ b/backports/0013-mediatek-add-support-for-configuring-BMT-table-size-.patch @@ -0,0 +1,215 @@ +From 1572b27651f11ac0e8f14a543815963147eb26ae Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Wed, 3 Feb 2021 19:34:29 +0100 +Subject: [PATCH 13/22] mediatek: add support for configuring BMT table size + via device tree + +Signed-off-by: Felix Fietkau +--- + .../patches-5.10/330-mtk-bmt-support.patch | 59 ++++++++++++------- + 1 file changed, 37 insertions(+), 22 deletions(-) + +diff --git a/target/linux/mediatek/patches-5.10/330-mtk-bmt-support.patch b/target/linux/mediatek/patches-5.10/330-mtk-bmt-support.patch +index 5c20952611..504c602c50 100644 +--- a/target/linux/mediatek/patches-5.10/330-mtk-bmt-support.patch ++++ b/target/linux/mediatek/patches-5.10/330-mtk-bmt-support.patch +@@ -23,7 +23,7 @@ + obj-y += raw/ + --- /dev/null + +++ b/drivers/mtd/nand/mtk_bmt.c +-@@ -0,0 +1,766 @@ ++@@ -0,0 +1,781 @@ + +/* + + * Copyright (c) 2017 MediaTek Inc. + + * Author: Xiangsheng Hou +@@ -56,7 +56,7 @@ + +#define BBT_LOG(fmt, ...) pr_debug("[BBT][%s|%d] "fmt"\n", __func__, __LINE__, ##__VA_ARGS__) + + + +/* Maximum 8k blocks */ +-+#define BB_TABLE_MAX 0x2000U +++#define BB_TABLE_MAX bmtd.table_size + +#define BMT_TABLE_MAX (BB_TABLE_MAX * BBPOOL_RATIO / 100) + +#define BMT_TBL_DEF_VAL 0x0 + + +@@ -71,14 +71,15 @@ + +#define BBMT_VERSION 2 + + unsigned char version; + + /* Below 2 tables will be written in SLC */ +-+ u16 bb_tbl[BB_TABLE_MAX]; +-+ struct bbmt { +-+ u16 block; +++ u16 bb_tbl[]; +++}; +++ +++struct bbmt { +++ u16 block; + +#define NO_MAPPED 0 + +#define NORMAL_MAPPED 1 + +#define BMT_MAPPED 2 +-+ u16 mapped; +-+ } bmt_tbl[BMT_TABLE_MAX]; +++ u16 mapped; + +}; + + + +static struct bmt_desc { +@@ -94,6 +95,7 @@ + + + + struct dentry *debugfs_dir; + + +++ u32 table_size; + + u32 pg_size; + + u32 blk_size; + + u16 pg_shift; +@@ -152,6 +154,11 @@ + +} + + + +/* -------- Bad Blocks Management -------- */ +++static inline struct bbmt *bmt_tbl(struct bbbt *bbbt) +++{ +++ return (struct bbmt *)&bbbt->bb_tbl[bmtd.table_size]; +++} +++ + +static int + +read_bmt(u16 block, unsigned char *dat, unsigned char *fdm, int fdm_len) + +{ +@@ -269,8 +276,8 @@ + + * BMT always in the last valid block in pool + + */ + + while ((block = find_valid_block(block)) != 0) { +-+ bbt->bmt_tbl[i].block = block; +-+ bbt->bmt_tbl[i].mapped = NO_MAPPED; +++ bmt_tbl(bbt)[i].block = block; +++ bmt_tbl(bbt)[i].mapped = NO_MAPPED; + + BBT_LOG("bmt_tbl[%d].block = 0x%x", i, block); + + block++; + + i++; +@@ -280,7 +287,7 @@ + + * bmtd.bmt_blk_idx - bmt_tbl[bmtd.bmt_blk_idx].block => the BMT block + + */ + + bmtd.bmt_blk_idx = i - 1; +-+ bbt->bmt_tbl[bmtd.bmt_blk_idx].mapped = BMT_MAPPED; +++ bmt_tbl(bbt)[bmtd.bmt_blk_idx].mapped = BMT_MAPPED; + + + + if (i < 1) { + + pr_info("nand: FATAL ERR: no space to store BMT!!\n"); +@@ -332,7 +339,7 @@ + + return scan_bmt(block - 1); + + + + if (is_valid_bmt(nand_bbt_buf, fdm)) { +-+ bmtd.bmt_blk_idx = get_bmt_index(((struct bbbt *)nand_bbt_buf)->bmt_tbl); +++ bmtd.bmt_blk_idx = get_bmt_index(bmt_tbl((struct bbbt *)nand_bbt_buf)); + + if (bmtd.bmt_blk_idx == 0) { + + pr_info("[BBT] FATAL ERR: bmt block index is wrong!\n"); + + return NULL; +@@ -351,15 +358,15 @@ + + u16 block; + + + +retry: +-+ if (n < 0 || bbt->bmt_tbl[n].mapped == NORMAL_MAPPED) { +++ if (n < 0 || bmt_tbl(bbt)[n].mapped == NORMAL_MAPPED) { + + pr_info("nand: FATAL ERR: no space to store BMT!\n"); + + return (u16)-1; + + } + + +-+ block = bbt->bmt_tbl[n].block; +++ block = bmt_tbl(bbt)[n].block; + + BBT_LOG("n = 0x%x, block = 0x%x", n, block); + + if (bbt_nand_erase(block)) { +-+ bbt->bmt_tbl[n].block = 0; +++ bmt_tbl(bbt)[n].block = 0; + + /* erase failed, try the previous block: bmt_tbl[n - 1].block */ + + n--; + + goto retry; +@@ -372,7 +379,7 @@ + + bbt->version = BBMT_VERSION; + + + + if (write_bmt(block, (unsigned char *)bbt)) { +-+ bbt->bmt_tbl[n].block = 0; +++ bmt_tbl(bbt)[n].block = 0; + + + + /* write failed, try the previous block in bmt_tbl[n - 1] */ + + n--; +@@ -391,9 +398,9 @@ + + goto error; + + + + for (i = 0; i < bmtd.bmt_blk_idx; i++) { +-+ if (bbt->bmt_tbl[i].block != 0 && bbt->bmt_tbl[i].mapped == NO_MAPPED) { +-+ bbt->bmt_tbl[i].mapped = NORMAL_MAPPED; +-+ return bbt->bmt_tbl[i].block; +++ if (bmt_tbl(bbt)[i].block != 0 && bmt_tbl(bbt)[i].mapped == NO_MAPPED) { +++ bmt_tbl(bbt)[i].mapped = NORMAL_MAPPED; +++ return bmt_tbl(bbt)[i].block; + + } + + } + + +@@ -471,6 +478,7 @@ + + ops->retlen += cur_ops.retlen; + + ops->oobretlen += cur_ops.oobretlen; + + +++ cur_ops.ooboffs = 0; + + cur_ops.datbuf += cur_ops.retlen; + + cur_ops.oobbuf += cur_ops.oobretlen; + + cur_ops.ooblen -= cur_ops.oobretlen; +@@ -521,6 +529,7 @@ + + ops->retlen += cur_ops.retlen; + + ops->oobretlen += cur_ops.oobretlen; + + +++ cur_ops.ooboffs = 0; + + cur_ops.datbuf += cur_ops.retlen; + + cur_ops.oobbuf += cur_ops.oobretlen; + + cur_ops.ooblen -= cur_ops.oobretlen; +@@ -673,7 +682,7 @@ + + u32 block; + + u16 total_blocks, pmt_block; + + int ret = 0; +-+ u32 bmt_pool_size; +++ u32 bmt_pool_size, bmt_table_size; + + + + if (bmtd.mtd) + + return -ENOSPC; +@@ -693,9 +702,14 @@ + + &bmtd.oob_offset) != 0) + + bmtd.oob_offset = 8; + + +++ if (of_property_read_u32(np, "mediatek,bmt-table-size", +++ &bmt_table_size) != 0) +++ bmt_table_size = 0x2000U; +++ + + bmtd.mtd = mtd; + + mtk_bmt_replace_ops(mtd); + + +++ bmtd.table_size = bmt_table_size; + + bmtd.blk_size = mtd->erasesize; + + bmtd.blk_shift = ffs(bmtd.blk_size) - 1; + + bmtd.pg_size = mtd->writesize; +@@ -723,7 +737,8 @@ + + bmtd.bb_max = bmtd.total_blks * BBPOOL_RATIO / 100; + + + + /* 3 buffers we need */ +-+ bufsz = round_up(sizeof(struct bbbt), bmtd.pg_size); +++ bufsz = round_up(sizeof(struct bbbt) + +++ bmt_table_size * sizeof(struct bbmt), bmtd.pg_size); + + bmtd.bmt_pgs = bufsz >> bmtd.pg_shift; + + + + nand_bbt_buf = kzalloc(bufsz, GFP_KERNEL); +@@ -756,7 +771,7 @@ + + } + + + + bbt = (struct bbbt *)nand_bbt_buf; +-+ memset(bbt->bmt_tbl, BMT_TBL_DEF_VAL, sizeof(bbt->bmt_tbl)); +++ memset(bmt_tbl(bbt), BMT_TBL_DEF_VAL, bmtd.table_size * sizeof(struct bbmt)); + + + + if (scan_bad_blocks(bbt)) { + + ret = -1; +@@ -765,7 +780,7 @@ + + + + /* BMT always in the last valid block in pool */ + + bmtd.bmt_blk_idx = upload_bmt(bbt, bmtd.bmt_blk_idx); +-+ block = bbt->bmt_tbl[bmtd.bmt_blk_idx].block; +++ block = bmt_tbl(bbt)[bmtd.bmt_blk_idx].block; + + pr_notice("[BBT] BMT.v2 is written into PBA:0x%x\n", block); + + + + if (bmtd.bmt_blk_idx == 0) +-- +2.25.1 + diff --git a/backports/0014-kernel-add-support-for-enabling-fit-firmware-partiti.patch b/backports/0014-kernel-add-support-for-enabling-fit-firmware-partiti.patch new file mode 100644 index 000000000..748bb6d55 --- /dev/null +++ b/backports/0014-kernel-add-support-for-enabling-fit-firmware-partiti.patch @@ -0,0 +1,43 @@ +From 29da2c500a856b214e9a0eca3ccdc98a6470da48 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Wed, 3 Feb 2021 20:37:03 +0100 +Subject: [PATCH 14/22] kernel: add support for enabling fit firmware partition + parser via cmdline + +This is useful for dual-boot setups where the loader sets variables depending +on the flash boot partition. +For example the Linksys E8450 sets mtdparts=master for the first partition +and mtdparts=slave for the second one. + +Signed-off-by: Felix Fietkau +--- + .../linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_fit.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_fit.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_fit.c +index 67ee33d085..5cc1658dbd 100644 +--- a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_fit.c ++++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_fit.c +@@ -49,6 +49,8 @@ mtdsplit_fit_parse(struct mtd_info *mtd, + const struct mtd_partition **pparts, + struct mtd_part_parser_data *data) + { ++ struct device_node *np = mtd_get_of_node(mtd); ++ const char *cmdline_match = NULL; + struct fdt_header hdr; + size_t hdr_len, retlen; + size_t offset; +@@ -57,6 +59,10 @@ mtdsplit_fit_parse(struct mtd_info *mtd, + struct mtd_partition *parts; + int ret; + ++ of_property_read_string(np, "openwrt,cmdline-match", &cmdline_match); ++ if (cmdline_match && !strstr(saved_command_line, cmdline_match)) ++ return -ENODEV; ++ + hdr_len = sizeof(struct fdt_header); + + /* Parse the MTD device & search for the FIT image location */ +-- +2.25.1 + diff --git a/backports/0015-mediatek-add-linksys-e8450-support.patch b/backports/0015-mediatek-add-linksys-e8450-support.patch new file mode 100644 index 000000000..14a7ca486 --- /dev/null +++ b/backports/0015-mediatek-add-linksys-e8450-support.patch @@ -0,0 +1,757 @@ +From f0d0621227f82d56676485cb31918c17fb3ed564 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Tue, 2 Feb 2021 16:29:58 +0100 +Subject: [PATCH 15/22] mediatek: add linksys-e8450 support + +Signed-off-by: John Crispin +Signed-off-by: Felix Fietkau +--- + .../dts/mediatek/mt7622-linksys-e8450.dts | 488 ++++++++++++++++++ + target/linux/mediatek/image/mt7622.mk | 10 + + .../mt7622/base-files/etc/board.d/01_leds | 18 + + .../mt7622/base-files/etc/board.d/02_network | 11 +- + .../mt7622/base-files/etc/init.d/bootcount | 11 + + .../mt7622/base-files/lib/upgrade/platform.sh | 8 + + ...Add-support-for-the-Fidelix-FM35X1GA.patch | 122 +++++ + 7 files changed, 667 insertions(+), 1 deletion(-) + create mode 100644 target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-linksys-e8450.dts + create mode 100755 target/linux/mediatek/mt7622/base-files/etc/board.d/01_leds + create mode 100755 target/linux/mediatek/mt7622/base-files/etc/init.d/bootcount + create mode 100644 target/linux/mediatek/patches-5.10/340-mtd-spinand-Add-support-for-the-Fidelix-FM35X1GA.patch + +diff --git a/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-linksys-e8450.dts b/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-linksys-e8450.dts +new file mode 100644 +index 0000000000..00b11690f0 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-linksys-e8450.dts +@@ -0,0 +1,488 @@ ++/* ++ * SPDX-License-Identifier: (GPL-2.0 OR MIT) ++ */ ++ ++/dts-v1/; ++#include ++#include ++ ++#include "mt7622.dtsi" ++#include "mt6380.dtsi" ++ ++/ { ++ model = "Linksys E8450"; ++ compatible = "linksys,e8450", "mediatek,mt7622"; ++ ++ aliases { ++ serial0 = &uart0; ++ led-boot = &led_power; ++ led-failsafe = &led_power; ++ led-running = &led_power; ++ led-upgrade = &led_power; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512"; ++ }; ++ ++ cpus { ++ cpu@0 { ++ proc-supply = <&mt6380_vcpu_reg>; ++ sram-supply = <&mt6380_vm_reg>; ++ }; ++ ++ cpu@1 { ++ proc-supply = <&mt6380_vcpu_reg>; ++ sram-supply = <&mt6380_vm_reg>; ++ }; ++ }; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ ++ factory { ++ label = "reset"; ++ linux,code = ; ++ gpios = <&pio 0 GPIO_ACTIVE_LOW>; ++ }; ++ ++ wps { ++ label = "wps"; ++ linux,code = ; ++ gpios = <&pio 102 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ gpio-leds { ++ compatible = "gpio-leds"; ++ ++ led_power: power_blue { ++ label = "power:blue"; ++ gpios = <&pio 95 GPIO_ACTIVE_LOW>; ++ default-state = "on"; ++ }; ++ ++ power_orange { ++ label = "power:orange"; ++ gpios = <&pio 96 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ ++ inet_blue { ++ label = "inet:blue"; ++ gpios = <&pio 97 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ ++ inet_orange { ++ label = "inet:orange"; ++ gpios = <&pio 98 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ }; ++ ++ memory { ++ reg = <0 0x40000000 0 0x40000000>; ++ }; ++ ++ reg_1p8v: regulator-1p8v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-1.8V"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ }; ++ ++ reg_3p3v: regulator-3p3v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-3.3V"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ reg_5v: regulator-5v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-5V"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++}; ++ ++&bch { ++ status = "okay"; ++}; ++ ++&btif { ++ status = "okay"; ++}; ++ ++&cir { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&irrx_pins>; ++ status = "okay"; ++}; ++ ++ð { ++ pinctrl-names = "default"; ++ pinctrl-0 = <ð_pins>; ++ status = "okay"; ++ ++ gmac0: mac@0 { ++ compatible = "mediatek,eth-mac"; ++ reg = <0>; ++ phy-mode = "2500base-x"; ++ ++ fixed-link { ++ speed = <2500>; ++ full-duplex; ++ pause; ++ }; ++ }; ++ ++ mdio-bus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ switch@0 { ++ compatible = "mediatek,mt7531"; ++ reg = <0>; ++ reset-gpios = <&pio 54 0>; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ label = "lan1"; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ label = "lan2"; ++ }; ++ ++ port@2 { ++ reg = <2>; ++ label = "lan3"; ++ }; ++ ++ port@3 { ++ reg = <3>; ++ label = "lan4"; ++ }; ++ ++ port@4 { ++ reg = <4>; ++ label = "wan"; ++ }; ++ ++ port@6 { ++ reg = <6>; ++ label = "cpu"; ++ ethernet = <&gmac0>; ++ phy-mode = "2500base-x"; ++ ++ fixed-link { ++ speed = <2500>; ++ full-duplex; ++ pause; ++ }; ++ }; ++ }; ++ }; ++ ++ }; ++}; ++ ++&pcie0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie0_pins>; ++ status = "okay"; ++}; ++ ++&pcie1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie1_pins>; ++ status = "okay"; ++}; ++ ++&slot0 { ++ mt7915@0,0 { ++ reg = <0x0000 0 0 0 0>; ++ mediatek,mtd-eeprom = <&factory 0x05000>; ++ }; ++}; ++ ++&pio { ++ /* Attention: GPIO 90 is used to switch between PCIe@1,0 and ++ * SATA functions. i.e. output-high: PCIe, output-low: SATA ++ */ ++// asm_sel { ++// gpio-hog; ++// gpios = <90 GPIO_ACTIVE_HIGH>; ++// output-high; ++// }; ++ ++ eth_pins: eth-pins { ++ mux { ++ function = "eth"; ++ groups = "mdc_mdio", "rgmii_via_gmac2"; ++ }; ++ }; ++ ++ irrx_pins: irrx-pins { ++ mux { ++ function = "ir"; ++ groups = "ir_1_rx"; ++ }; ++ }; ++ ++ irtx_pins: irtx-pins { ++ mux { ++ function = "ir"; ++ groups = "ir_1_tx"; ++ }; ++ }; ++ ++ pcie0_pins: pcie0-pins { ++ mux { ++ function = "pcie"; ++ groups = "pcie0_pad_perst", ++ "pcie0_1_waken", ++ "pcie0_1_clkreq"; ++ }; ++ }; ++ ++ pcie1_pins: pcie1-pins { ++ mux { ++ function = "pcie"; ++ groups = "pcie1_pad_perst", ++ "pcie1_0_waken", ++ "pcie1_0_clkreq"; ++ }; ++ }; ++ ++ pmic_bus_pins: pmic-bus-pins { ++ mux { ++ function = "pmic"; ++ groups = "pmic_bus"; ++ }; ++ }; ++ ++ pwm7_pins: pwm1-2-pins { ++ mux { ++ function = "pwm"; ++ groups = "pwm_ch7_2"; ++ }; ++ }; ++ ++ wled_pins: wled-pins { ++ mux { ++ function = "led"; ++ groups = "wled"; ++ }; ++ }; ++ ++ /* Serial NAND is shared pin with SPI-NOR */ ++ serial_nand_pins: serial-nand-pins { ++ mux { ++ function = "flash"; ++ groups = "snfi"; ++ }; ++ }; ++ ++ spic0_pins: spic0-pins { ++ mux { ++ function = "spi"; ++ groups = "spic0_0"; ++ }; ++ }; ++ ++ spic1_pins: spic1-pins { ++ mux { ++ function = "spi"; ++ groups = "spic1_0"; ++ }; ++ }; ++ ++ uart0_pins: uart0-pins { ++ mux { ++ function = "uart"; ++ groups = "uart0_0_tx_rx" ; ++ }; ++ }; ++ ++ uart2_pins: uart2-pins { ++ mux { ++ function = "uart"; ++ groups = "uart2_1_tx_rx" ; ++ }; ++ }; ++ ++ watchdog_pins: watchdog-pins { ++ mux { ++ function = "watchdog"; ++ groups = "watchdog"; ++ }; ++ }; ++}; ++ ++&pwm { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm7_pins>; ++ status = "okay"; ++}; ++ ++&pwrap { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_bus_pins>; ++ ++ status = "okay"; ++}; ++ ++&sata { ++ status = "disabled"; ++}; ++ ++&sata_phy { ++ status = "disabled"; ++}; ++ ++&snfi { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&serial_nand_pins>; ++ status = "okay"; ++ ++ spi_nand@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "spi-nand"; ++ spi-max-frequency = <104000000>; ++ reg = <0>; ++ ++ mediatek,bmt-v2; ++ mediatek,bmt-table-size = <0x1000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "Preloader"; ++ reg = <0x00000 0x0080000>; ++ read-only; ++ }; ++ ++ partition@80000 { ++ label = "ATF"; ++ reg = <0x80000 0x0040000>; ++ }; ++ ++ partition@c0000 { ++ label = "u-boot"; ++ reg = <0xc0000 0x0080000>; ++ }; ++ ++ partition@140000 { ++ label = "u-boot-env"; ++ reg = <0x140000 0x0080000>; ++ }; ++ ++ factory: partition@1c0000 { ++ label = "factory"; ++ reg = <0x1c0000 0x0100000>; ++ }; ++ ++ partition@300000 { ++ label = "devinfo"; ++ reg = <0x300000 0x020000>; ++ }; ++ ++ partition@320000 { ++ label = "senv"; ++ reg = <0x320000 0x020000>; ++ }; ++ ++ partition@360000 { ++ label = "bootseq"; ++ reg = <0x360000 0x020000>; ++ }; ++ ++ partition@500000 { ++ label = "firmware1"; ++ compatible = "denx,fit"; ++ openwrt,cmdline-match = "mtdparts=master"; ++ reg = <0x500000 0x1E00000>; ++ }; ++ ++ partition@2300000 { ++ label = "firmware2"; ++ compatible = "denx,fit"; ++ openwrt,cmdline-match = "mtdparts=slave"; ++ reg = <0x2300000 0x1E00000>; ++ }; ++ ++ partition@4100000 { ++ label = "data"; ++ reg = <0x4100000 0x1900000>; ++ }; ++ ++ partition@5100000 { ++ label = "mfg"; ++ reg = <0x5a00000 0x1400000>; ++ }; ++ }; ++ }; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spic0_pins>; ++ status = "okay"; ++}; ++ ++&spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spic1_pins>; ++ status = "okay"; ++}; ++ ++&ssusb { ++ vusb33-supply = <®_3p3v>; ++ vbus-supply = <®_5v>; ++ status = "okay"; ++}; ++ ++&u3phy { ++ status = "okay"; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pins>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2_pins>; ++ status = "okay"; ++}; ++ ++&watchdog { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&watchdog_pins>; ++ status = "okay"; ++}; ++ ++&wmac { ++ mediatek,mtd-eeprom = <&factory 0x0000>; ++ status = "okay"; ++}; +diff --git a/target/linux/mediatek/image/mt7622.mk b/target/linux/mediatek/image/mt7622.mk +index 74f6eba19a..efaa3bcaa3 100644 +--- a/target/linux/mediatek/image/mt7622.mk ++++ b/target/linux/mediatek/image/mt7622.mk +@@ -36,6 +36,16 @@ define Device/elecom_wrc-2533gent + endef + TARGET_DEVICES += elecom_wrc-2533gent + ++define Device/linksys_e8450 ++ DEVICE_VENDOR := Linksys ++ DEVICE_MODEL := E8450 ++ DEVICE_DTS := mt7622-linksys-e8450 ++ DEVICE_DTS_DIR := $(DTS_DIR)/mediatek ++ DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-usb3 kmod-ata-ahci-mtk \ ++ kmod-mt7615e kmod-mt7615-firmware kmod-mt7915 ++endef ++TARGET_DEVICES += linksys_e8450 ++ + define Device/mediatek_mt7622-rfb1 + DEVICE_VENDOR := MediaTek + DEVICE_MODEL := MTK7622 rfb1 AP +diff --git a/target/linux/mediatek/mt7622/base-files/etc/board.d/01_leds b/target/linux/mediatek/mt7622/base-files/etc/board.d/01_leds +new file mode 100755 +index 0000000000..e74944a65f +--- /dev/null ++++ b/target/linux/mediatek/mt7622/base-files/etc/board.d/01_leds +@@ -0,0 +1,18 @@ ++#!/bin/sh ++ ++. /lib/functions/leds.sh ++. /lib/functions/uci-defaults.sh ++ ++board=$(board_name) ++ ++board_config_update ++ ++case $board in ++linksys,e8450) ++ ucidef_set_led_netdev "wan" "WAN" "inet:blue" "wan" ++ ;; ++esac ++ ++board_config_flush ++ ++exit 0 +diff --git a/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network b/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network +index 3a409c8ec9..f6cd4ba3fc 100755 +--- a/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network ++++ b/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network +@@ -10,7 +10,8 @@ mediatek_setup_interfaces() + + case $board in + bananapi,bpi-r64-rootdisk|\ +- bananapi,bpi-r64) ++ bananapi,bpi-r64|\ ++ linksys,e8450) + ucidef_set_interfaces_lan_wan "lan0 lan1 lan2 lan3" wan + ;; + mediatek,mt7622-rfb1) +@@ -31,7 +32,15 @@ mediatek_setup_macs() + local board="$1" + + case $board in ++ linksys,e8450) ++ wan_mac=$(mtd_get_mac_ascii devinfo wan_mac_addr) ++ lan_mac=$(mtd_get_mac_ascii devinfo lan_mac_addr) ++ label_mac=$wan_mac ++ ;; + esac ++ [ -n "$lan_mac" ] && ucidef_set_interface_macaddr "lan" $lan_mac ++ [ -n "$wan_mac" ] && ucidef_set_interface_macaddr "wan" $wan_mac ++ [ -n "$label_mac" ] && ucidef_set_label_macaddr $label_mac + } + + board_config_update +diff --git a/target/linux/mediatek/mt7622/base-files/etc/init.d/bootcount b/target/linux/mediatek/mt7622/base-files/etc/init.d/bootcount +new file mode 100755 +index 0000000000..bc4eeb6530 +--- /dev/null ++++ b/target/linux/mediatek/mt7622/base-files/etc/init.d/bootcount +@@ -0,0 +1,11 @@ ++#!/bin/sh /etc/rc.common ++ ++START=99 ++ ++boot() { ++ case $(board_name) in ++ linksys,e8450) ++ mtd erase senv || true ++ ;; ++ esac ++} +diff --git a/target/linux/mediatek/mt7622/base-files/lib/upgrade/platform.sh b/target/linux/mediatek/mt7622/base-files/lib/upgrade/platform.sh +index 8144476943..95ac8b5657 100755 +--- a/target/linux/mediatek/mt7622/base-files/lib/upgrade/platform.sh ++++ b/target/linux/mediatek/mt7622/base-files/lib/upgrade/platform.sh +@@ -10,6 +10,14 @@ platform_do_upgrade() { + mediatek,mt7622,ubi) + nand_do_upgrade "$1" + ;; ++ linksys,e8450) ++ if grep -q mtdparts=slave /proc/cmdline; then ++ PART_NAME=firmware2 ++ else ++ PART_NAME=firmware1 ++ fi ++ default_do_upgrade "$1" ++ ;; + *) + default_do_upgrade "$1" + ;; +diff --git a/target/linux/mediatek/patches-5.10/340-mtd-spinand-Add-support-for-the-Fidelix-FM35X1GA.patch b/target/linux/mediatek/patches-5.10/340-mtd-spinand-Add-support-for-the-Fidelix-FM35X1GA.patch +new file mode 100644 +index 0000000000..69a9297e1f +--- /dev/null ++++ b/target/linux/mediatek/patches-5.10/340-mtd-spinand-Add-support-for-the-Fidelix-FM35X1GA.patch +@@ -0,0 +1,122 @@ ++From ea0df4552efcdcc2806fe6eba0540b5f719d80b6 Mon Sep 17 00:00:00 2001 ++From: Davide Fioravanti ++Date: Fri, 8 Jan 2021 15:35:24 +0100 ++Subject: [PATCH 1/1] mtd: spinand: Add support for the Fidelix FM35X1GA ++ ++Datasheet: http://www.hobos.com.cn/upload/datasheet/DS35X1GAXXX_100_rev00.pdf ++ ++Signed-off-by: Davide Fioravanti ++--- ++ drivers/mtd/nand/spi/Makefile | 2 +- ++ drivers/mtd/nand/spi/core.c | 1 + ++ drivers/mtd/nand/spi/fidelix.c | 80 ++++++++++++++++++++++++++++++++++ ++ include/linux/mtd/spinand.h | 1 + ++ 4 files changed, 83 insertions(+), 1 deletion(-) ++ create mode 100644 drivers/mtd/nand/spi/fidelix.c ++ ++--- a/drivers/mtd/nand/spi/Makefile +++++ b/drivers/mtd/nand/spi/Makefile ++@@ -1,3 +1,3 @@ ++ # SPDX-License-Identifier: GPL-2.0 ++-spinand-objs := core.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o +++spinand-objs := core.o fidelix.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o ++ obj-$(CONFIG_MTD_SPI_NAND) += spinand.o ++--- a/drivers/mtd/nand/spi/core.c +++++ b/drivers/mtd/nand/spi/core.c ++@@ -755,6 +755,7 @@ static const struct nand_ops spinand_ops ++ }; ++ ++ static const struct spinand_manufacturer *spinand_manufacturers[] = { +++ &fidelix_spinand_manufacturer, ++ &gigadevice_spinand_manufacturer, ++ ¯onix_spinand_manufacturer, ++ µn_spinand_manufacturer, ++--- /dev/null +++++ b/drivers/mtd/nand/spi/fidelix.c ++@@ -0,0 +1,76 @@ +++// SPDX-License-Identifier: GPL-2.0 +++/* +++ * Copyright (c) 2020 Davide Fioravanti +++ */ +++ +++#include +++#include +++#include +++ +++#define SPINAND_MFR_FIDELIX 0xE5 +++#define FIDELIX_ECCSR_MASK 0x0F +++ +++static SPINAND_OP_VARIANTS(read_cache_variants, +++ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), +++ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), +++ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); +++ +++static SPINAND_OP_VARIANTS(write_cache_variants, +++ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), +++ SPINAND_PROG_LOAD(true, 0, NULL, 0)); +++ +++static SPINAND_OP_VARIANTS(update_cache_variants, +++ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), +++ SPINAND_PROG_LOAD(false, 0, NULL, 0)); +++ +++static int fm35x1ga_ooblayout_ecc(struct mtd_info *mtd, int section, +++ struct mtd_oob_region *region) +++{ +++ if (section > 3) +++ return -ERANGE; +++ +++ region->offset = (16 * section) + 8; +++ region->length = 8; +++ +++ return 0; +++} +++ +++static int fm35x1ga_ooblayout_free(struct mtd_info *mtd, int section, +++ struct mtd_oob_region *region) +++{ +++ if (section > 3) +++ return -ERANGE; +++ +++ region->offset = (16 * section) + 2; +++ region->length = 6; +++ +++ return 0; +++} +++ +++static const struct mtd_ooblayout_ops fm35x1ga_ooblayout = { +++ .ecc = fm35x1ga_ooblayout_ecc, +++ .free = fm35x1ga_ooblayout_free, +++}; +++ +++static const struct spinand_info fidelix_spinand_table[] = { +++ SPINAND_INFO("FM35X1GA", +++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x71), +++ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), +++ NAND_ECCREQ(4, 512), +++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, +++ &write_cache_variants, +++ &update_cache_variants), +++ SPINAND_HAS_QE_BIT, +++ SPINAND_ECCINFO(&fm35x1ga_ooblayout, NULL)), +++}; +++ +++static const struct spinand_manufacturer_ops fidelix_spinand_manuf_ops = { +++}; +++ +++const struct spinand_manufacturer fidelix_spinand_manufacturer = { +++ .id = SPINAND_MFR_FIDELIX, +++ .name = "Fidelix", +++ .chips = fidelix_spinand_table, +++ .nchips = ARRAY_SIZE(fidelix_spinand_table), +++ .ops = &fidelix_spinand_manuf_ops, +++}; ++--- a/include/linux/mtd/spinand.h +++++ b/include/linux/mtd/spinand.h ++@@ -238,6 +238,7 @@ struct spinand_manufacturer { ++ }; ++ ++ /* SPI NAND manufacturers */ +++extern const struct spinand_manufacturer fidelix_spinand_manufacturer; ++ extern const struct spinand_manufacturer gigadevice_spinand_manufacturer; ++ extern const struct spinand_manufacturer macronix_spinand_manufacturer; ++ extern const struct spinand_manufacturer micron_spinand_manufacturer; +-- +2.25.1 + diff --git a/backports/0016-mediatek-linksys-e8450-fix-wifi-and-lan4.patch b/backports/0016-mediatek-linksys-e8450-fix-wifi-and-lan4.patch new file mode 100644 index 000000000..d3dc47776 --- /dev/null +++ b/backports/0016-mediatek-linksys-e8450-fix-wifi-and-lan4.patch @@ -0,0 +1,42 @@ +From d8505bfc5491c7b3c9cfb6a58380c115f83ffeb7 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Sat, 30 Jan 2021 23:08:27 +0000 +Subject: [PATCH 16/22] mediatek: linksys-e8450: fix wifi and lan4 + +Signed-off-by: Daniel Golle +--- + target/linux/mediatek/image/mt7622.mk | 2 +- + .../linux/mediatek/mt7622/base-files/etc/board.d/02_network | 4 +--- + 2 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/target/linux/mediatek/image/mt7622.mk b/target/linux/mediatek/image/mt7622.mk +index efaa3bcaa3..df9e0d7d17 100644 +--- a/target/linux/mediatek/image/mt7622.mk ++++ b/target/linux/mediatek/image/mt7622.mk +@@ -42,7 +42,7 @@ define Device/linksys_e8450 + DEVICE_DTS := mt7622-linksys-e8450 + DEVICE_DTS_DIR := $(DTS_DIR)/mediatek + DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-usb3 kmod-ata-ahci-mtk \ +- kmod-mt7615e kmod-mt7615-firmware kmod-mt7915 ++ kmod-mt7615e kmod-mt7615-firmware kmod-mt7915e + endef + TARGET_DEVICES += linksys_e8450 + +diff --git a/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network b/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network +index f6cd4ba3fc..3d2b9ffe49 100755 +--- a/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network ++++ b/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network +@@ -11,9 +11,7 @@ mediatek_setup_interfaces() + case $board in + bananapi,bpi-r64-rootdisk|\ + bananapi,bpi-r64|\ +- linksys,e8450) +- ucidef_set_interfaces_lan_wan "lan0 lan1 lan2 lan3" wan +- ;; ++ linksys,e8450|\ + mediatek,mt7622-rfb1) + ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" wan + ;; +-- +2.25.1 + diff --git a/backports/0017-image-add-support-for-building-FIT-image-with-filesy.patch b/backports/0017-image-add-support-for-building-FIT-image-with-filesy.patch new file mode 100644 index 000000000..e16525cad --- /dev/null +++ b/backports/0017-image-add-support-for-building-FIT-image-with-filesy.patch @@ -0,0 +1,754 @@ +From 86c2de0e5b6b800525df4abf533366c34554064f Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Mon, 15 Feb 2021 14:37:17 +0000 +Subject: [PATCH 17/22] image: add support for building FIT image with + filesystem + +Allow for single (external-data) FIT image to hold kernel, dtb and +squashfs. In that way, the bootloader verify the system integrity +including the rootfs, flashing sysupgrade and factory on many platforms +becomes much easier. +In short: mkimage has a parameter '-E' which allows generating FIT +images with 'external' data rather than embedding the data into the +device-tree blob itself. In this way, the FIT structure itself remains +small and can be parsed easily (rather than having to page around +megabytes of image content). This patch makes use of that and adds +support for adding sub-images of type 'filesystem' which are used to +store the squashfs. Now U-Boot can verify the whole OS and the new +partition parsers added in the Linux kernel can detect the filesystem +sub-images and create partitions for them, and select the active +rootfs volume based on the configuration in FIT. + +This new FIT partition parser works for NOR flash (on top of mtdblock), +NAND flash (on top of ubiblock) as well as classic block devices +(ie. eMMC, SDcard, SATA, NVME, ...) as well as . +See the follow-up commits for a good example of its use (on SPI-NAND). + +Signed-off-by: Daniel Golle +--- + include/image-commands.mk | 3 +- + package/base-files/files/lib/upgrade/nand.sh | 102 +++++--- + scripts/mkits.sh | 45 +++- + target/linux/generic/config-5.10 | 1 + + .../generic/files/block/partitions/fit.c | 234 ++++++++++++++++++ + .../400-block-fit-partition-parser.patch | 96 +++++++ + ...to-create-ubiblock-device-for-rootfs.patch | 5 +- + 7 files changed, 442 insertions(+), 44 deletions(-) + create mode 100644 target/linux/generic/files/block/partitions/fit.c + create mode 100644 target/linux/generic/hack-5.10/400-block-fit-partition-parser.patch + +diff --git a/include/image-commands.mk b/include/image-commands.mk +index 51e745958e..bddbed6052 100644 +--- a/include/image-commands.mk ++++ b/include/image-commands.mk +@@ -200,11 +200,12 @@ define Build/fit + $(TOPDIR)/scripts/mkits.sh \ + -D $(DEVICE_NAME) -o $@.its -k $@ \ + $(if $(word 2,$(1)),-d $(word 2,$(1))) -C $(word 1,$(1)) \ ++ $(if $(word 3,$(1)),-r $(IMAGE_ROOTFS) -f $(subst _,$(comma),$(DEVICE_NAME))) \ + -a $(KERNEL_LOADADDR) -e $(if $(KERNEL_ENTRY),$(KERNEL_ENTRY),$(KERNEL_LOADADDR)) \ + $(if $(DEVICE_FDT_NUM),-n $(DEVICE_FDT_NUM)) \ + -c $(if $(DEVICE_DTS_CONFIG),$(DEVICE_DTS_CONFIG),"config@1") \ + -A $(LINUX_KARCH) -v $(LINUX_VERSION) +- PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage -f $@.its $@.new ++ PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage $(if $(word 3,$(1)),-E -B 0x1000 -p 0x1000) -f $@.its $@.new + @mv $@.new $@ + endef + +diff --git a/package/base-files/files/lib/upgrade/nand.sh b/package/base-files/files/lib/upgrade/nand.sh +index e6f58df4f5..5bc9ff83f9 100644 +--- a/package/base-files/files/lib/upgrade/nand.sh ++++ b/package/base-files/files/lib/upgrade/nand.sh +@@ -3,13 +3,13 @@ + + . /lib/functions.sh + +-# 'kernel' partition on NAND contains the kernel ++# 'kernel' partition or UBI volume on NAND contains the kernel + CI_KERNPART="${CI_KERNPART:-kernel}" + + # 'ubi' partition on NAND contains UBI + CI_UBIPART="${CI_UBIPART:-ubi}" + +-# 'rootfs' partition on NAND contains the rootfs ++# 'rootfs' UBI volume on NAND contains the rootfs + CI_ROOTPART="${CI_ROOTPART:-rootfs}" + + ubi_mknod() { +@@ -117,9 +117,11 @@ nand_restore_config() { + nand_upgrade_prepare_ubi() { + local rootfs_length="$1" + local rootfs_type="$2" +- local has_kernel="${3:-0}" ++ local kernel_length="$3" + local has_env="${4:-0}" + ++ [ -n "$rootfs_length" -o -n "$kernel_length" ] || return 1 ++ + local mtdnum="$( find_mtd_index "$CI_UBIPART" )" + if [ ! "$mtdnum" ]; then + echo "cannot find ubi mtd partition $CI_UBIPART" +@@ -148,23 +150,24 @@ nand_upgrade_prepare_ubi() { + local root_ubivol="$( nand_find_volume $ubidev $CI_ROOTPART )" + local data_ubivol="$( nand_find_volume $ubidev rootfs_data )" + +- # remove ubiblock device of rootfs +- local root_ubiblk="ubiblock${root_ubivol:3}" +- if [ "$root_ubivol" -a -e "/dev/$root_ubiblk" ]; then +- echo "removing $root_ubiblk" +- if ! ubiblock -r /dev/$root_ubivol; then +- echo "cannot remove $root_ubiblk" +- return 1; ++ local ubiblk ubiblkvol ++ for ubiblk in /dev/ubiblock*_? ; do ++ [ -e "$ubiblk" ] || continue ++ echo "removing ubiblock${ubiblk:13}" ++ ubiblkvol=ubi${ubiblk:13} ++ if ! ubiblock -r /dev/$ubiblkvol; then ++ echo "cannot remove $ubiblk" ++ return 1 + fi +- fi ++ done + + # kill volumes + [ "$kern_ubivol" ] && ubirmvol /dev/$ubidev -N $CI_KERNPART || true +- [ "$root_ubivol" ] && ubirmvol /dev/$ubidev -N $CI_ROOTPART || true ++ [ "$root_ubivol" -a "$root_ubivol" != "$kern_ubivol" ] && ubirmvol /dev/$ubidev -N $CI_ROOTPART || true + [ "$data_ubivol" ] && ubirmvol /dev/$ubidev -N rootfs_data || true + + # update kernel +- if [ "$has_kernel" = "1" ]; then ++ if [ -n "$kernel_length" ]; then + if ! ubimkvol /dev/$ubidev -N $CI_KERNPART -s $kernel_length; then + echo "cannot create kernel volume" + return 1; +@@ -172,15 +175,17 @@ nand_upgrade_prepare_ubi() { + fi + + # update rootfs +- local root_size_param +- if [ "$rootfs_type" = "ubifs" ]; then +- root_size_param="-m" +- else +- root_size_param="-s $rootfs_length" +- fi +- if ! ubimkvol /dev/$ubidev -N $CI_ROOTPART $root_size_param; then +- echo "cannot create rootfs volume" +- return 1; ++ if [ -n "$rootfs_length" ]; then ++ local root_size_param ++ if [ "$rootfs_type" = "ubifs" ]; then ++ root_size_param="-m" ++ else ++ root_size_param="-s $rootfs_length" ++ fi ++ if ! ubimkvol /dev/$ubidev -N $CI_ROOTPART $rootfs_size_param; then ++ echo "cannot create rootfs volume" ++ return 1; ++ fi + fi + + # create rootfs_data for non-ubifs rootfs +@@ -232,7 +237,7 @@ nand_upgrade_ubinized() { + nand_upgrade_ubifs() { + local rootfs_length=$( (cat $1 | wc -c) 2> /dev/null) + +- nand_upgrade_prepare_ubi "$rootfs_length" "ubifs" "0" "0" ++ nand_upgrade_prepare_ubi "$rootfs_length" "ubifs" "" "" + + local ubidev="$( nand_find_ubi "$CI_UBIPART" )" + local root_ubivol="$(nand_find_volume $ubidev $CI_ROOTPART)" +@@ -241,39 +246,59 @@ nand_upgrade_ubifs() { + nand_do_upgrade_success + } + ++nand_upgrade_fit() { ++ local fit_file="$1" ++ local fit_length="$(wc -c < "$fit_file")" ++ ++ nand_upgrade_prepare_ubi "" "" "$fit_length" "1" ++ ++ local fit_ubidev="$(nand_find_ubi "$CI_UBIPART")" ++ local fit_ubivol="$(nand_find_volume $fit_ubidev "$CI_KERNPART")" ++ ubiupdatevol /dev/$fit_ubivol -s $fit_length $fit_file ++ ++ nand_do_upgrade_success ++} ++ + nand_upgrade_tar() { + local tar_file="$1" + local kernel_mtd="$(find_mtd_index $CI_KERNPART)" + +- local board_dir=$(tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$') ++ local board_dir=$(tar tf "$tar_file" | grep -m 1 '^sysupgrade-.*/$') + board_dir=${board_dir%/} + +- local kernel_length=$( (tar xf $tar_file ${board_dir}/kernel -O | wc -c) 2> /dev/null) +- local rootfs_length=$( (tar xf $tar_file ${board_dir}/root -O | wc -c) 2> /dev/null) ++ kernel_length=$( (tar xf "$tar_file" ${board_dir}/kernel -O | wc -c) 2> /dev/null) ++ local has_rootfs=0 ++ local rootfs_length ++ local rootfs_type + +- local rootfs_type="$(identify_tar "$tar_file" ${board_dir}/root)" ++ tar tf "$tar_file" ${board_dir}/root 1>/dev/null 2>/dev/null && has_rootfs=1 ++ [ "$has_rootfs" = "1" ] && { ++ rootfs_length=$( (tar xf "$tar_file" ${board_dir}/root -O | wc -c) 2> /dev/null) ++ rootfs_type="$(identify_tar "$tar_file" ${board_dir}/root)" ++ } + + local has_kernel=1 + local has_env=0 + + [ "$kernel_length" != 0 -a -n "$kernel_mtd" ] && { +- tar xf $tar_file ${board_dir}/kernel -O | mtd write - $CI_KERNPART ++ tar xf "$tar_file" ${board_dir}/kernel -O | mtd write - $CI_KERNPART + } +- [ "$kernel_length" = 0 -o ! -z "$kernel_mtd" ] && has_kernel=0 ++ [ "$kernel_length" = 0 -o ! -z "$kernel_mtd" ] && has_kernel= + +- nand_upgrade_prepare_ubi "$rootfs_length" "$rootfs_type" "$has_kernel" "$has_env" ++ nand_upgrade_prepare_ubi "$rootfs_length" "$rootfs_type" "${has_kernel:+$kernel_length}" "$has_env" + + local ubidev="$( nand_find_ubi "$CI_UBIPART" )" + [ "$has_kernel" = "1" ] && { +- local kern_ubivol="$(nand_find_volume $ubidev $CI_KERNPART)" +- tar xf $tar_file ${board_dir}/kernel -O | \ ++ local kern_ubivol="$( nand_find_volume $ubidev $CI_KERNPART )" ++ tar xf "$tar_file" ${board_dir}/kernel -O | \ + ubiupdatevol /dev/$kern_ubivol -s $kernel_length - + } + +- local root_ubivol="$(nand_find_volume $ubidev $CI_ROOTPART)" +- tar xf $tar_file ${board_dir}/root -O | \ +- ubiupdatevol /dev/$root_ubivol -s $rootfs_length - +- ++ [ "$has_rootfs" = "1" ] && { ++ local root_ubivol="$( nand_find_volume $ubidev $CI_ROOTPART )" ++ tar xf "$tar_file" ${board_dir}/root -O | \ ++ ubiupdatevol /dev/$root_ubivol -s $rootfs_length - ++ } + nand_do_upgrade_success + } + +@@ -281,9 +306,10 @@ nand_upgrade_tar() { + nand_do_upgrade() { + local file_type=$(identify $1) + +- [ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART="rootfs" ++ [ ! "$( find_mtd_index "$CI_UBIPART" )" ] && CI_UBIPART="rootfs" + + case "$file_type" in ++ "fit") nand_upgrade_fit $1;; + "ubi") nand_upgrade_ubinized $1;; + "ubifs") nand_upgrade_ubifs $1;; + *) nand_upgrade_tar $1;; +@@ -309,7 +335,7 @@ nand_do_platform_check() { + local control_length=$( (tar xf $tar_file sysupgrade-$board_name/CONTROL -O | wc -c) 2> /dev/null) + local file_type="$(identify $2)" + +- [ "$control_length" = 0 -a "$file_type" != "ubi" -a "$file_type" != "ubifs" ] && { ++ [ "$control_length" = 0 -a "$file_type" != "ubi" -a "$file_type" != "ubifs" -a "$file_type" != "fit" ] && { + echo "Invalid sysupgrade file." + return 1 + } +diff --git a/scripts/mkits.sh b/scripts/mkits.sh +index bb629d6fca..3d68fdacbc 100755 +--- a/scripts/mkits.sh ++++ b/scripts/mkits.sh +@@ -23,18 +23,23 @@ usage() { + printf "\n\t-c ==> set config name 'config'" + printf "\n\t-a ==> set load address to 'addr' (hex)" + printf "\n\t-e ==> set entry point to 'entry' (hex)" ++ printf "\n\t-f ==> set device tree compatible string" + printf "\n\t-v ==> set kernel version to 'version'" + printf "\n\t-k ==> include kernel image 'kernel'" + printf "\n\t-D ==> human friendly Device Tree Blob 'name'" + printf "\n\t-n ==> fdt unit-address 'address'" + printf "\n\t-d ==> include Device Tree Blob 'dtb'" ++ printf "\n\t-r ==> include RootFS blob" ++ printf "\n\t-H ==> specify hash algo instead of SHA1" + printf "\n\t-o ==> create output file 'its_file'\n" + exit 1 + } + + FDTNUM=1 ++ROOTFSNUM=1 ++HASH=sha1 + +-while getopts ":A:a:c:C:D:d:e:k:n:o:v:" OPTION ++while getopts ":A:a:c:C:D:d:e:f:k:n:o:v:r:S" OPTION + do + case $OPTION in + A ) ARCH=$OPTARG;; +@@ -44,9 +49,12 @@ do + D ) DEVICE=$OPTARG;; + d ) DTB=$OPTARG;; + e ) ENTRY_ADDR=$OPTARG;; ++ f ) COMPATIBLE=$OPTARG;; + k ) KERNEL=$OPTARG;; + n ) FDTNUM=$OPTARG;; + o ) OUTPUT=$OPTARG;; ++ r ) ROOTFS=$OPTARG;; ++ S ) HASH=$OPTARG;; + v ) VERSION=$OPTARG;; + * ) echo "Invalid option passed to '$0' (options:$*)" + usage;; +@@ -62,11 +70,16 @@ fi + + ARCH_UPPER=$(echo "$ARCH" | tr '[:lower:]' '[:upper:]') + ++if [ -n "${COMPATIBLE}" ]; then ++ COMPATIBLE_PROP="compatible = \"${COMPATIBLE}\";" ++fi ++ + # Conditionally create fdt information + if [ -n "${DTB}" ]; then + FDT_NODE=" + fdt@$FDTNUM { + description = \"${ARCH_UPPER} OpenWrt ${DEVICE} device tree blob\"; ++ ${COMPATIBLE_PROP} + data = /incbin/(\"${DTB}\"); + type = \"flat_dt\"; + arch = \"${ARCH}\"; +@@ -75,13 +88,34 @@ if [ -n "${DTB}" ]; then + algo = \"crc32\"; + }; + hash@2 { +- algo = \"sha1\"; ++ algo = \"${HASH}\"; + }; + }; + " + FDT_PROP="fdt = \"fdt@$FDTNUM\";" + fi + ++if [ -n "${ROOTFS}" ]; then ++ dd if="${ROOTFS}" of="${ROOTFS}.pagesync" bs=4096 conv=sync ++ ROOTFS_NODE=" ++ rootfs@$ROOTFSNUM { ++ description = \"${ARCH_UPPER} OpenWrt ${DEVICE} rootfs\"; ++ ${COMPATIBLE_PROP} ++ data = /incbin/(\"${ROOTFS}.pagesync\"); ++ type = \"filesystem\"; ++ arch = \"${ARCH}\"; ++ compression = \"none\"; ++ hash@1 { ++ algo = \"crc32\"; ++ }; ++ hash@2 { ++ algo = \"${HASH}\"; ++ }; ++ }; ++" ++ ROOTFS_PROP="loadables = \"rootfs@${ROOTFSNUM}\";" ++fi ++ + # Create a default, fully populated DTS file + DATA="/dts-v1/; + +@@ -103,18 +137,21 @@ DATA="/dts-v1/; + algo = \"crc32\"; + }; + hash@2 { +- algo = \"sha1\"; ++ algo = \"$HASH\"; + }; + }; + ${FDT_NODE} ++${ROOTFS_NODE} + }; + + configurations { + default = \"${CONFIG}\"; + ${CONFIG} { +- description = \"OpenWrt\"; ++ description = \"OpenWrt ${DEVICE}\"; + kernel = \"kernel@1\"; + ${FDT_PROP} ++ ${ROOTFS_PROP} ++ ${COMPATIBLE_PROP} + }; + }; + };" +diff --git a/target/linux/generic/config-5.10 b/target/linux/generic/config-5.10 +index f7cc6c8561..ba6317e35f 100644 +--- a/target/linux/generic/config-5.10 ++++ b/target/linux/generic/config-5.10 +@@ -1859,6 +1859,7 @@ CONFIG_FIB_RULES=y + # CONFIG_FIELDBUS_DEV is not set + CONFIG_FILE_LOCKING=y + # CONFIG_FIND_BIT_BENCHMARK is not set ++# CONFIG_FIT_PARTITION is not set + # CONFIG_FIREWIRE is not set + # CONFIG_FIREWIRE_NOSY is not set + # CONFIG_FIREWIRE_SERIAL is not set +diff --git a/target/linux/generic/files/block/partitions/fit.c b/target/linux/generic/files/block/partitions/fit.c +new file mode 100644 +index 0000000000..3694a22667 +--- /dev/null ++++ b/target/linux/generic/files/block/partitions/fit.c +@@ -0,0 +1,234 @@ ++// SPvDX-License-Identifier: GPL-2.0 ++/* ++ * fs/partitions/fit.c ++ * Copyright (C) 2021 Daniel Golle ++ * ++ * headers extracted from U-Boot mkimage sources ++ * (C) Copyright 2008 Semihalf ++ * (C) Copyright 2000-2005 ++ * Wolfgang Denk, DENX Software Engineering, wd@denx.de. ++ * ++ * based on existing partition parsers ++ * Copyright (C) 1991-1998 Linus Torvalds ++ * Re-organised Feb 1998 Russell King ++ */ ++ ++#define pr_fmt(fmt) fmt ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "check.h" ++ ++#define FIT_IMAGES_PATH "/images" ++#define FIT_CONFS_PATH "/configurations" ++ ++/* hash/signature/key node */ ++#define FIT_HASH_NODENAME "hash" ++#define FIT_ALGO_PROP "algo" ++#define FIT_VALUE_PROP "value" ++#define FIT_IGNORE_PROP "uboot-ignore" ++#define FIT_SIG_NODENAME "signature" ++#define FIT_KEY_REQUIRED "required" ++#define FIT_KEY_HINT "key-name-hint" ++ ++/* cipher node */ ++#define FIT_CIPHER_NODENAME "cipher" ++#define FIT_ALGO_PROP "algo" ++ ++/* image node */ ++#define FIT_DATA_PROP "data" ++#define FIT_DATA_POSITION_PROP "data-position" ++#define FIT_DATA_OFFSET_PROP "data-offset" ++#define FIT_DATA_SIZE_PROP "data-size" ++#define FIT_TIMESTAMP_PROP "timestamp" ++#define FIT_DESC_PROP "description" ++#define FIT_ARCH_PROP "arch" ++#define FIT_TYPE_PROP "type" ++#define FIT_OS_PROP "os" ++#define FIT_COMP_PROP "compression" ++#define FIT_ENTRY_PROP "entry" ++#define FIT_LOAD_PROP "load" ++ ++/* configuration node */ ++#define FIT_KERNEL_PROP "kernel" ++#define FIT_FILESYSTEM_PROP "filesystem" ++#define FIT_RAMDISK_PROP "ramdisk" ++#define FIT_FDT_PROP "fdt" ++#define FIT_LOADABLE_PROP "loadables" ++#define FIT_DEFAULT_PROP "default" ++#define FIT_SETUP_PROP "setup" ++#define FIT_FPGA_PROP "fpga" ++#define FIT_FIRMWARE_PROP "firmware" ++#define FIT_STANDALONE_PROP "standalone" ++ ++#define FIT_MAX_HASH_LEN HASH_MAX_DIGEST_SIZE ++ ++int fit_partition(struct parsed_partitions *state) ++{ ++ struct address_space *mapping = state->bdev->bd_inode->i_mapping; ++ struct page *page = read_mapping_page(mapping, 0, NULL); ++ void *fit, *init_fit; ++ struct partition_meta_info *info; ++ char tmp[sizeof(info->volname)]; ++ u64 dsize, dsectors, isectors; ++ u32 size, image_pos, image_len; ++ const u32 *image_offset_be, *image_len_be, *image_pos_be; ++ int ret = 1, node, images, config, slot; ++ const char *image_name, *image_type, *image_description, *config_default, ++ *config_description, *config_loadables; ++ int image_name_len, image_type_len, image_description_len, config_default_len, ++ config_description_len, config_loadables_len; ++ sector_t start_sect, nr_sects; ++ size_t label_min; ++ ++ if (!page) ++ return -ENOMEM; ++ ++ init_fit = page_address(page); ++ ++ if (!init_fit) { ++ put_page(page); ++ return -EFAULT; ++ } ++ ++ if (fdt_check_header(init_fit)) { ++ put_page(page); ++ return 0; ++ } ++ ++ dsectors = get_capacity(state->bdev->bd_disk); ++ dsize = dsectors << SECTOR_SHIFT; ++ ++ printk(KERN_INFO "FIT: volume size: %llu sectors (%llu bytes)\n", dsectors, dsize); ++ ++ size = fdt_totalsize(init_fit); ++ isectors = size >> SECTOR_SHIFT; ++ if ((isectors << SECTOR_SHIFT) < size) ++ ++isectors; ++ ++ printk(KERN_INFO "FIT: FDT structure size: %llu sectors (%u bytes)\n", isectors, size); ++ ++ if (size >= dsize || size > PAGE_SIZE) ++ { ++ put_page(page); ++ state->access_beyond_eod = (size >= dsize); ++ return 0; ++ } ++ ++ fit = kmemdup(init_fit, size, GFP_KERNEL); ++ put_page(page); ++ if (!fit) ++ return -ENOMEM; ++ ++ config = fdt_path_offset(fit, FIT_CONFS_PATH); ++ if (config < 0) { ++ printk(KERN_INFO "FIT: Cannot find %s node: %d\n", FIT_CONFS_PATH, images); ++ ret = -ENOENT; ++ goto ret_out; ++ } ++ ++ config_default = fdt_getprop(fit, config, FIT_DEFAULT_PROP, &config_default_len); ++ ++ if (!config_default) { ++ printk(KERN_INFO "FIT: Cannot find default configuration\n"); ++ ret = -ENOENT; ++ goto ret_out; ++ } ++ ++ node = fdt_subnode_offset(fit, config, config_default); ++ if (node < 0) { ++ printk(KERN_INFO "FIT: Cannot find %s node: %d\n", config_default, node); ++ ret = -ENOENT; ++ goto ret_out; ++ } ++ ++ config_description = fdt_getprop(fit, node, FIT_DESC_PROP, &config_description_len); ++ config_loadables = fdt_getprop(fit, node, FIT_LOADABLE_PROP, &config_loadables_len); ++ ++ printk(KERN_INFO "FIT: Default configuration: %s%s%s%s\n", config_default, ++ config_description?" (":"", config_description?:"", config_description?")":""); ++ ++ images = fdt_path_offset(fit, FIT_IMAGES_PATH); ++ if (images < 0) { ++ printk(KERN_INFO "FIT: Cannot find %s node: %d\n", FIT_IMAGES_PATH, images); ++ ret = -EINVAL; ++ goto ret_out; ++ } ++ ++ slot = 1; ++ fdt_for_each_subnode(node, fit, images) { ++ image_name = fdt_get_name(fit, node, &image_name_len); ++ image_type = fdt_getprop(fit, node, FIT_TYPE_PROP, &image_type_len); ++ image_offset_be = fdt_getprop(fit, node, FIT_DATA_OFFSET_PROP, NULL); ++ image_pos_be = fdt_getprop(fit, node, FIT_DATA_POSITION_PROP, NULL); ++ image_len_be = fdt_getprop(fit, node, FIT_DATA_SIZE_PROP, NULL); ++ if (!image_name || !image_type || !image_len_be) ++ continue; ++ ++ image_len = be32_to_cpu(*image_len_be); ++ if (!image_len) ++ continue; ++ ++ if (image_offset_be) ++ image_pos = be32_to_cpu(*image_offset_be) + size; ++ else if (image_pos_be) ++ image_pos = be32_to_cpu(*image_pos_be); ++ else ++ continue; ++ ++ image_description = fdt_getprop(fit, node, FIT_DESC_PROP, &image_description_len); ++ ++ printk(KERN_INFO "FIT: %16s sub-image 0x%08x - 0x%08x '%s' %s%s%s\n", ++ image_type, image_pos, image_pos + image_len, image_name, ++ image_description?"(":"", image_description?:"", image_description?") ":""); ++ ++ if (strcmp(image_type, FIT_FILESYSTEM_PROP)) ++ continue; ++ ++ if (image_pos & ((1 << PAGE_SHIFT)-1)) { ++ printk(KERN_INFO "FIT: image %s start not aligned to page boundaries, skipping\n", image_name); ++ continue; ++ } ++ ++ if (image_len & ((1 << PAGE_SHIFT)-1)) { ++ printk(KERN_INFO "FIT: sub-image %s end not aligned to page boundaries, skipping\n", image_name); ++ continue; ++ } ++ ++ start_sect = image_pos >> SECTOR_SHIFT; ++ nr_sects = image_len >> SECTOR_SHIFT; ++ ++ if (start_sect + nr_sects > dsectors) { ++ state->access_beyond_eod = 1; ++ continue; ++ } ++ ++ put_partition(state, slot, start_sect, nr_sects); ++ state->parts[slot].flags = 0; ++ info = &state->parts[slot].info; ++ ++ label_min = min_t(int, sizeof(info->volname) - 1, image_name_len); ++ strncpy(info->volname, image_name, label_min); ++ info->volname[label_min] = '\0'; ++ ++ snprintf(tmp, sizeof(tmp), "(%s)", info->volname); ++ strlcat(state->pp_buf, tmp, PAGE_SIZE); ++ ++ state->parts[slot].has_info = true; ++ ++ if (config_loadables && !strcmp(image_name, config_loadables)) { ++ printk(KERN_INFO "FIT: selecting configured loadable %s to be root filesystem\n", image_name); ++ state->parts[slot].flags |= ADDPART_FLAG_ROOTDEV; ++ } ++ ++ ++slot; ++ } ++ ++ret_out: ++ kfree(fit); ++ return ret; ++} +diff --git a/target/linux/generic/hack-5.10/400-block-fit-partition-parser.patch b/target/linux/generic/hack-5.10/400-block-fit-partition-parser.patch +new file mode 100644 +index 0000000000..9eaf8637d0 +--- /dev/null ++++ b/target/linux/generic/hack-5.10/400-block-fit-partition-parser.patch +@@ -0,0 +1,96 @@ ++--- a/block/blk.h +++++ b/block/blk.h ++@@ -357,6 +357,7 @@ char *disk_name(struct gendisk *hd, int ++ #define ADDPART_FLAG_NONE 0 ++ #define ADDPART_FLAG_RAID 1 ++ #define ADDPART_FLAG_WHOLEDISK 2 +++#define ADDPART_FLAG_ROOTDEV 4 ++ void delete_partition(struct hd_struct *part); ++ int bdev_add_partition(struct block_device *bdev, int partno, ++ sector_t start, sector_t length); ++--- a/block/partitions/Kconfig +++++ b/block/partitions/Kconfig ++@@ -101,6 +101,13 @@ config ATARI_PARTITION ++ Say Y here if you would like to use hard disks under Linux which ++ were partitioned under the Atari OS. ++ +++config FIT_PARTITION +++ bool "Flattened-Image-Tree (FIT) partition support" if PARTITION_ADVANCED +++ default n +++ help +++ Say Y here if your system needs to mount the filesystem part of +++ a Flattened-Image-Tree (FIT) image commonly used with Das U-Boot. +++ ++ config IBM_PARTITION ++ bool "IBM disk label and partition support" ++ depends on PARTITION_ADVANCED && S390 ++--- a/block/partitions/Makefile +++++ b/block/partitions/Makefile ++@@ -8,6 +8,7 @@ obj-$(CONFIG_ACORN_PARTITION) += acorn.o ++ obj-$(CONFIG_AMIGA_PARTITION) += amiga.o ++ obj-$(CONFIG_ATARI_PARTITION) += atari.o ++ obj-$(CONFIG_AIX_PARTITION) += aix.o +++obj-$(CONFIG_FIT_PARTITION) += fit.o ++ obj-$(CONFIG_CMDLINE_PARTITION) += cmdline.o ++ obj-$(CONFIG_MAC_PARTITION) += mac.o ++ obj-$(CONFIG_LDM_PARTITION) += ldm.o ++--- a/block/partitions/check.h +++++ b/block/partitions/check.h ++@@ -58,6 +58,7 @@ int amiga_partition(struct parsed_partit ++ int atari_partition(struct parsed_partitions *state); ++ int cmdline_partition(struct parsed_partitions *state); ++ int efi_partition(struct parsed_partitions *state); +++int fit_partition(struct parsed_partitions *state); ++ int ibm_partition(struct parsed_partitions *); ++ int karma_partition(struct parsed_partitions *state); ++ int ldm_partition(struct parsed_partitions *state); ++--- a/block/partitions/core.c +++++ b/block/partitions/core.c ++@@ -10,6 +10,8 @@ ++ #include ++ #include ++ #include +++#include +++ ++ #include "check.h" ++ ++ static int (*check_part[])(struct parsed_partitions *) = { ++@@ -46,6 +48,9 @@ static int (*check_part[])(struct parsed ++ #ifdef CONFIG_EFI_PARTITION ++ efi_partition, /* this must come before msdos */ ++ #endif +++#ifdef CONFIG_FIT_PARTITION +++ fit_partition, +++#endif ++ #ifdef CONFIG_SGI_PARTITION ++ sgi_partition, ++ #endif ++@@ -694,6 +699,9 @@ static bool blk_add_partition(struct gen ++ (state->parts[p].flags & ADDPART_FLAG_RAID)) ++ md_autodetect_dev(part_to_dev(part)->devt); ++ +++ if ((state->parts[p].flags & ADDPART_FLAG_ROOTDEV) && ROOT_DEV == 0) +++ ROOT_DEV = part_to_dev(part)->devt; +++ ++ return true; ++ } ++ ++--- a/drivers/mtd/ubi/block.c +++++ b/drivers/mtd/ubi/block.c ++@@ -396,7 +396,7 @@ int ubiblock_create(struct ubi_volume_in ++ dev->leb_size = vi->usable_leb_size; ++ ++ /* Initialize the gendisk of this ubiblock device */ ++- gd = alloc_disk(1); +++ gd = alloc_disk(0); ++ if (!gd) { ++ pr_err("UBI: block: alloc_disk failed\n"); ++ ret = -ENODEV; ++@@ -413,6 +413,7 @@ int ubiblock_create(struct ubi_volume_in ++ goto out_put_disk; ++ } ++ gd->private_data = dev; +++ gd->flags |= GENHD_FL_EXT_DEVT; ++ sprintf(gd->disk_name, "ubiblock%d_%d", dev->ubi_num, dev->vol_id); ++ set_capacity(gd, disk_capacity); ++ dev->gd = gd; +diff --git a/target/linux/generic/pending-5.10/491-ubi-auto-create-ubiblock-device-for-rootfs.patch b/target/linux/generic/pending-5.10/491-ubi-auto-create-ubiblock-device-for-rootfs.patch +index e5ee2c8656..a2b48fd4fc 100644 +--- a/target/linux/generic/pending-5.10/491-ubi-auto-create-ubiblock-device-for-rootfs.patch ++++ b/target/linux/generic/pending-5.10/491-ubi-auto-create-ubiblock-device-for-rootfs.patch +@@ -8,7 +8,7 @@ Signed-off-by: Daniel Golle + + --- a/drivers/mtd/ubi/block.c + +++ b/drivers/mtd/ubi/block.c +-@@ -652,6 +652,44 @@ static void __init ubiblock_create_from_ ++@@ -652,6 +652,47 @@ static void __init ubiblock_create_from_ + } + } + +@@ -33,6 +33,9 @@ Signed-off-by: Daniel Golle + + for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++) { + + desc = ubi_open_volume_nm(ubi_num, "rootfs", UBI_READONLY); + + if (IS_ERR(desc)) +++ desc = ubi_open_volume_nm(ubi_num, "fit", UBI_READONLY);; +++ +++ if (IS_ERR(desc)) + + continue; + + + + ubi_get_volume_info(desc, &vi); +-- +2.25.1 + diff --git a/backports/0018-sysupgrade-nand-allow-limiting-rootfs_data-by-settin.patch b/backports/0018-sysupgrade-nand-allow-limiting-rootfs_data-by-settin.patch new file mode 100644 index 000000000..f7aef475f --- /dev/null +++ b/backports/0018-sysupgrade-nand-allow-limiting-rootfs_data-by-settin.patch @@ -0,0 +1,74 @@ +From 9f0be984310a4d2bdacf94e53bd198aba3fa8675 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Sat, 20 Feb 2021 08:36:43 +0100 +Subject: [PATCH 18/22] sysupgrade-nand: allow limiting rootfs_data by setting + env variable + +Check if firmware environment variable 'rootfs_data_max' exists and is +set to a numerical value greater than 0. If so, limit rootfs_data +volume to that size instead of using the maximum available size. + +This is useful on devices with lots of flash where users may want to +have eg. a volume for persistent logs and statistics or for external +applications/containers. Persistence on rootfs overlay is limited by +the size of memory available during the sysugprade process as that +data needs to be copied to RAM while the volume is being recreated +during sysupgrade. Hence it is unsuitable for keeping larger amounts +of data accross upgrade which makes additional volume(s) for +application data desirable. + +Signed-off-by: Daniel Golle +--- + package/base-files/files/lib/upgrade/nand.sh | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +diff --git a/package/base-files/files/lib/upgrade/nand.sh b/package/base-files/files/lib/upgrade/nand.sh +index 5bc9ff83f9..e335d940ed 100644 +--- a/package/base-files/files/lib/upgrade/nand.sh ++++ b/package/base-files/files/lib/upgrade/nand.sh +@@ -117,6 +117,9 @@ nand_restore_config() { + nand_upgrade_prepare_ubi() { + local rootfs_length="$1" + local rootfs_type="$2" ++ local rootfs_data_max="$(fw_printenv -n rootfs_data_max 2>/dev/null)" ++ [ -n "$rootfs_data_max" ] && rootfs_data_max=$(printf %d "$rootfs_data_max") ++ + local kernel_length="$3" + local has_env="${4:-0}" + +@@ -176,11 +179,11 @@ nand_upgrade_prepare_ubi() { + + # update rootfs + if [ -n "$rootfs_length" ]; then +- local root_size_param ++ local rootfs_size_param + if [ "$rootfs_type" = "ubifs" ]; then +- root_size_param="-m" ++ rootfs_size_param="-m" + else +- root_size_param="-s $rootfs_length" ++ rootfs_size_param="-s $rootfs_length" + fi + if ! ubimkvol /dev/$ubidev -N $CI_ROOTPART $rootfs_size_param; then + echo "cannot create rootfs volume" +@@ -190,7 +193,16 @@ nand_upgrade_prepare_ubi() { + + # create rootfs_data for non-ubifs rootfs + if [ "$rootfs_type" != "ubifs" ]; then +- if ! ubimkvol /dev/$ubidev -N rootfs_data -m; then ++ local availeb=$(cat /sys/devices/virtual/ubi/$ubidev/avail_eraseblocks) ++ local ebsize=$(cat /sys/devices/virtual/ubi/$ubidev/eraseblock_size) ++ local avail_size=$(( $availeb * $ebsize )) ++ local rootfs_data_size_param="-m" ++ if [ -n "$rootfs_data_max" ] && ++ [ "$rootfs_data_max" != "0" ] && ++ [ "$rootfs_data_max" -le "$avail_size" ]; then ++ rootfs_data_size_param="-s $rootfs_data_max" ++ fi ++ if ! ubimkvol /dev/$ubidev -N rootfs_data $rootfs_data_size_param; then + echo "cannot initialize rootfs_data volume" + return 1 + fi +-- +2.25.1 + diff --git a/backports/0019-uboot-mediatek-add-support-for-linksys-e8450.patch b/backports/0019-uboot-mediatek-add-support-for-linksys-e8450.patch new file mode 100644 index 000000000..dd8bb6d92 --- /dev/null +++ b/backports/0019-uboot-mediatek-add-support-for-linksys-e8450.patch @@ -0,0 +1,1351 @@ +From 071191934f2b2eeb080f5e60f405ccc43c2d2ed8 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Sat, 30 Jan 2021 13:58:16 +0000 +Subject: [PATCH 19/22] uboot-mediatek: add support for linksys e8450 + +Build U-Boot for the Linksys E8450 in order to have support for UBI. +The loader has a default environment with scripts handling the reset +button as well as fall-back to recovery firmware. If the loader comes +up without a valid environment found in UBI, it will automatically +make sure UBI is formatted and create a new environment and proceed +to load recovery firmware (either from UBI or via TFTP if recovery is +corrupted or unavailable). + +If the button is held down during power-on, the yellow status LED +turns on and the bootloader environment is reset to factory defaults. +If the button is released at this point, the recovery firmware (if +existing) is loaded from UBI and booted. +If the button is continously held down even beyond the point that +the yellow LED turned on, the loader will try to load the recovery +firmware via TFTP from server 192.168.1.254, write it to UBI and +boot. + +Signed-off-by: Daniel Golle +--- + package/boot/uboot-mediatek/Makefile | 35 +- + .../002-nand-add-spi-nand-driver.patch | 123 +---- + ...boot-add-dts-and-config-for-spi-nand.patch | 11 +- + ...le-mtd-and-mtk_spi_nand-in-defconfig.patch | 17 - + .../patches/005-update-bpir2-defconfig.patch | 11 +- + .../006-cmd-button-return-button-status.patch | 38 ++ + .../patches/007-env-readmem.patch | 116 +++++ + .../patches/008-bootmenu-custom-title.patch | 32 ++ + ...7622-generic-reset-button-ignore-env.patch | 35 ++ + .../patches/010-no-binman.patch | 6 +- + .../patches/010-update-u7623-defconfig.patch | 2 - + .../patches/020-add-linksys-e8450.patch | 436 ++++++++++++++++++ + .../100-increase-CONFIG_SYS_BOOTM_LEN.patch | 11 + + 13 files changed, 713 insertions(+), 160 deletions(-) + create mode 100644 package/boot/uboot-mediatek/patches/006-cmd-button-return-button-status.patch + create mode 100644 package/boot/uboot-mediatek/patches/007-env-readmem.patch + create mode 100644 package/boot/uboot-mediatek/patches/008-bootmenu-custom-title.patch + create mode 100644 package/boot/uboot-mediatek/patches/009-mt7622-generic-reset-button-ignore-env.patch + create mode 100644 package/boot/uboot-mediatek/patches/020-add-linksys-e8450.patch + create mode 100644 package/boot/uboot-mediatek/patches/100-increase-CONFIG_SYS_BOOTM_LEN.patch + +diff --git a/package/boot/uboot-mediatek/Makefile b/package/boot/uboot-mediatek/Makefile +index c46b906cb5..b61f432644 100644 +--- a/package/boot/uboot-mediatek/Makefile ++++ b/package/boot/uboot-mediatek/Makefile +@@ -3,6 +3,7 @@ include $(INCLUDE_DIR)/kernel.mk + + PKG_VERSION:=2020.10 + PKG_HASH:=0d481bbdc05c0ee74908ec2f56a6daa53166cc6a78a0e4fac2ac5d025770a622 ++PKG_BUILD_DEPENDS:=arm-trusted-firmware-tools/host + + include $(INCLUDE_DIR)/u-boot.mk + include $(INCLUDE_DIR)/package.mk +@@ -20,6 +21,16 @@ define U-Boot/mt7622 + UBOOT_CONFIG:=mt7622_rfb + endef + ++define U-Boot/mt7622_linksys_e8450 ++ NAME:=Linksys E8450 ++ BUILD_SUBTARGET:=mt7622 ++ UBOOT_CONFIG:=mt7622_linksys_e8450 ++ UBOOT_IMAGE:=u-boot.fip ++ BL2_BOOTDEV:=snand ++ BL2_DDRBLOB:=1 ++ DEPENDS:=+trusted-firmware-a-mt7622-snand-1ddr ++endef ++ + define U-Boot/mt7623a_unielec_u7623 + NAME:=UniElec U7623 (mt7623) + BUILD_SUBTARGET:=mt7623 +@@ -39,15 +50,33 @@ define U-Boot/mt7629 + UBOOT_CONFIG:=mt7629_rfb + endef + +-UBOOT_TARGETS := mt7629 mt7622 mt7623n_bpir2 mt7623a_unielec_u7623 ++UBOOT_TARGETS := mt7629 mt7622 mt7622_linksys_e8450 mt7623n_bpir2 mt7623a_unielec_u7623 + +-UBOOT_MAKE_FLAGS += $(UBOOT_IMAGE) ++UBOOT_MAKE_FLAGS += $(UBOOT_IMAGE:.fip=.bin) + + Build/Exports:=$(Host/Exports) + ++define Build/fip-image ++ $(STAGING_DIR_HOST)/bin/fiptool create \ ++ --soc-fw $(STAGING_DIR_IMAGE)/$(BUILD_SUBTARGET)-$(BL2_BOOTDEV)-$(BL2_DDRBLOB)ddr-bl31.bin \ ++ --nt-fw $(PKG_BUILD_DIR)/u-boot.bin \ ++ $(PKG_BUILD_DIR)/u-boot.fip ++endef ++ ++define Build/Compile ++ $(call Build/Compile/U-Boot) ++ifeq ($(UBOOT_IMAGE),u-boot.fip)) ++ $(call Build/fip-image) ++endif ++endef ++ ++# don't stage files to bindir, let target/linux/mediatek/image/*.mk do that ++define Package/u-boot/install ++endef ++ + define Build/InstallDev + $(INSTALL_DIR) $(STAGING_DIR_IMAGE) +- $(INSTALL_BIN) $(PKG_BUILD_DIR)/$(UBOOT_IMAGE) $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-$(UBOOT_IMAGE) ++ $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(UBOOT_IMAGE) $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-$(UBOOT_IMAGE) + endef + + $(eval $(call BuildPackage/U-Boot)) +diff --git a/package/boot/uboot-mediatek/patches/002-nand-add-spi-nand-driver.patch b/package/boot/uboot-mediatek/patches/002-nand-add-spi-nand-driver.patch +index dc3ebaf7af..5d3e94ac86 100644 +--- a/package/boot/uboot-mediatek/patches/002-nand-add-spi-nand-driver.patch ++++ b/package/boot/uboot-mediatek/patches/002-nand-add-spi-nand-driver.patch +@@ -85,11 +85,9 @@ Signed-off-by: Xiangsheng Hou + create mode 100644 drivers/mtd/nandx/include/internal/nandx_util.h + create mode 100644 drivers/mtd/nandx/include/uboot/nandx_os.h + +-diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig +-index 5e7571cf3d..34a59b44b9 100644 + --- a/drivers/mtd/Kconfig + +++ b/drivers/mtd/Kconfig +-@@ -101,6 +101,13 @@ config HBMC_AM654 ++@@ -108,6 +108,13 @@ config HBMC_AM654 + This is the driver for HyperBus controller on TI's AM65x and + other SoCs + +@@ -103,11 +101,9 @@ index 5e7571cf3d..34a59b44b9 100644 + source "drivers/mtd/nand/Kconfig" + + source "drivers/mtd/spi/Kconfig" +-diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile +-index 318788c5e2..1df1031b23 100644 + --- a/drivers/mtd/Makefile + +++ b/drivers/mtd/Makefile +-@@ -41,3 +41,7 @@ obj-$(CONFIG_$(SPL_TPL_)SPI_FLASH_SUPPORT) += spi/ ++@@ -41,3 +41,7 @@ obj-$(CONFIG_$(SPL_TPL_)SPI_FLASH_SUPPOR + obj-$(CONFIG_SPL_UBI) += ubispl/ + + endif +@@ -115,8 +111,6 @@ index 318788c5e2..1df1031b23 100644 + +ifeq ($(CONFIG_MTK_SPI_NAND), y) + +include $(srctree)/drivers/mtd/nandx/Nandx.mk + +endif +-diff --git a/drivers/mtd/nand/raw/nand.c b/drivers/mtd/nand/raw/nand.c +-index 026419e4e6..4be0c7d8f3 100644 + --- a/drivers/mtd/nand/raw/nand.c + +++ b/drivers/mtd/nand/raw/nand.c + @@ -91,8 +91,10 @@ static void nand_init_chip(int i) +@@ -130,9 +124,6 @@ index 026419e4e6..4be0c7d8f3 100644 + + nand_register(i, mtd); + } +-diff --git a/drivers/mtd/nandx/NOTICE b/drivers/mtd/nandx/NOTICE +-new file mode 100644 +-index 0000000000..1a06ca3867 + --- /dev/null + +++ b/drivers/mtd/nandx/NOTICE + @@ -0,0 +1,52 @@ +@@ -189,9 +180,6 @@ index 0000000000..1a06ca3867 + + + +#################################################################################################### + \ No newline at end of file +-diff --git a/drivers/mtd/nandx/Nandx.config b/drivers/mtd/nandx/Nandx.config +-new file mode 100644 +-index 0000000000..35705ee28d + --- /dev/null + +++ b/drivers/mtd/nandx/Nandx.config + @@ -0,0 +1,17 @@ +@@ -212,9 +200,6 @@ index 0000000000..35705ee28d + +NANDX_NFI_BASE := y + +NANDX_NFI_ECC := y + +NANDX_NFI_SPI := y +-diff --git a/drivers/mtd/nandx/Nandx.mk b/drivers/mtd/nandx/Nandx.mk +-new file mode 100644 +-index 0000000000..f5a6f2a628 + --- /dev/null + +++ b/drivers/mtd/nandx/Nandx.mk + @@ -0,0 +1,91 @@ +@@ -309,9 +294,6 @@ index 0000000000..f5a6f2a628 + +clean: + + rm -rf $(sim-obj) nandx + +endif +-diff --git a/drivers/mtd/nandx/README b/drivers/mtd/nandx/README +-new file mode 100644 +-index 0000000000..0feaeaeb88 + --- /dev/null + +++ b/drivers/mtd/nandx/README + @@ -0,0 +1,31 @@ +@@ -346,9 +328,6 @@ index 0000000000..0feaeaeb88 + + Any block of above graph can be extended at your will, if you + +want add new feature into this code, please make sure that your code + +would follow the framework, and we will be appreciated about it. +-diff --git a/drivers/mtd/nandx/core/Nandx.mk b/drivers/mtd/nandx/core/Nandx.mk +-new file mode 100644 +-index 0000000000..7a5661c044 + --- /dev/null + +++ b/drivers/mtd/nandx/core/Nandx.mk + @@ -0,0 +1,38 @@ +@@ -390,9 +369,6 @@ index 0000000000..7a5661c044 + +nandx-header-$(NANDX_NFI_ECC) += nfi/nfiecc_regs.h + +nandx-header-$(NANDX_NFI_SPI) += nfi/nfi_spi.h + +nandx-header-$(NANDX_NFI_SPI) += nfi/nfi_spi_regs.h +-diff --git a/drivers/mtd/nandx/core/core_io.c b/drivers/mtd/nandx/core/core_io.c +-new file mode 100644 +-index 0000000000..716eeed38d + --- /dev/null + +++ b/drivers/mtd/nandx/core/core_io.c + @@ -0,0 +1,735 @@ +@@ -1131,9 +1107,6 @@ index 0000000000..716eeed38d + + return ret; + +} + +#endif +-diff --git a/drivers/mtd/nandx/core/core_io.h b/drivers/mtd/nandx/core/core_io.h +-new file mode 100644 +-index 0000000000..edcb60908a + --- /dev/null + +++ b/drivers/mtd/nandx/core/core_io.h + @@ -0,0 +1,39 @@ +@@ -1176,9 +1149,6 @@ index 0000000000..edcb60908a + +}; + + + +#endif /* __CORE_IO_H__ */ +-diff --git a/drivers/mtd/nandx/core/nand/device_spi.c b/drivers/mtd/nandx/core/nand/device_spi.c +-new file mode 100644 +-index 0000000000..db338c28c2 + --- /dev/null + +++ b/drivers/mtd/nandx/core/nand/device_spi.c + @@ -0,0 +1,200 @@ +@@ -1382,9 +1352,6 @@ index 0000000000..db338c28c2 + + return &spi_nand[index].dev; + +} + + +-diff --git a/drivers/mtd/nandx/core/nand/device_spi.h b/drivers/mtd/nandx/core/nand/device_spi.h +-new file mode 100644 +-index 0000000000..1676b61fc8 + --- /dev/null + +++ b/drivers/mtd/nandx/core/nand/device_spi.h + @@ -0,0 +1,132 @@ +@@ -1520,9 +1487,6 @@ index 0000000000..1676b61fc8 + +u8 spi_replace_tx_col_cycle(u8 mode); + + + +#endif /* __DEVICE_SPI_H__ */ +-diff --git a/drivers/mtd/nandx/core/nand/nand_spi.c b/drivers/mtd/nandx/core/nand/nand_spi.c +-new file mode 100644 +-index 0000000000..2ae03e1cf4 + --- /dev/null + +++ b/drivers/mtd/nandx/core/nand/nand_spi.c + @@ -0,0 +1,526 @@ +@@ -2052,9 +2016,6 @@ index 0000000000..2ae03e1cf4 + + nand_base_exit(spi->parent); + + mem_free(spi); + +} +-diff --git a/drivers/mtd/nandx/core/nand/nand_spi.h b/drivers/mtd/nandx/core/nand/nand_spi.h +-new file mode 100644 +-index 0000000000..e55e4de6f7 + --- /dev/null + +++ b/drivers/mtd/nandx/core/nand/nand_spi.h + @@ -0,0 +1,35 @@ +@@ -2093,9 +2054,6 @@ index 0000000000..e55e4de6f7 + +} + + + +#endif /* __NAND_SPI_H__ */ +-diff --git a/drivers/mtd/nandx/core/nand_base.c b/drivers/mtd/nandx/core/nand_base.c +-new file mode 100644 +-index 0000000000..65998e5460 + --- /dev/null + +++ b/drivers/mtd/nandx/core/nand_base.c + @@ -0,0 +1,304 @@ +@@ -2403,9 +2361,6 @@ index 0000000000..65998e5460 + + nfi_exit(base->nfi); + + mem_free(base); + +} +-diff --git a/drivers/mtd/nandx/core/nand_base.h b/drivers/mtd/nandx/core/nand_base.h +-new file mode 100644 +-index 0000000000..13217978e5 + --- /dev/null + +++ b/drivers/mtd/nandx/core/nand_base.h + @@ -0,0 +1,71 @@ +@@ -2480,9 +2435,6 @@ index 0000000000..13217978e5 + +int nand_detect_device(struct nand_base *nand); + + + +#endif /* __NAND_BASE_H__ */ +-diff --git a/drivers/mtd/nandx/core/nand_chip.c b/drivers/mtd/nandx/core/nand_chip.c +-new file mode 100644 +-index 0000000000..02adc6f52e + --- /dev/null + +++ b/drivers/mtd/nandx/core/nand_chip.c + @@ -0,0 +1,272 @@ +@@ -2758,9 +2710,6 @@ index 0000000000..02adc6f52e + + nand_exit(chip->nand); + + mem_free(chip); + +} +-diff --git a/drivers/mtd/nandx/core/nand_chip.h b/drivers/mtd/nandx/core/nand_chip.h +-new file mode 100644 +-index 0000000000..3e9c8e6ca3 + --- /dev/null + +++ b/drivers/mtd/nandx/core/nand_chip.h + @@ -0,0 +1,103 @@ +@@ -2867,9 +2816,6 @@ index 0000000000..3e9c8e6ca3 + +struct nand_chip *nand_chip_init(struct nfi_resource *res); + +void nand_chip_exit(struct nand_chip *chip); + +#endif /* __NAND_CHIP_H__ */ +-diff --git a/drivers/mtd/nandx/core/nand_device.c b/drivers/mtd/nandx/core/nand_device.c +-new file mode 100644 +-index 0000000000..9f6764d1bc + --- /dev/null + +++ b/drivers/mtd/nandx/core/nand_device.c + @@ -0,0 +1,285 @@ +@@ -3158,9 +3104,6 @@ index 0000000000..9f6764d1bc + + return 0; + +} + + +-diff --git a/drivers/mtd/nandx/core/nand_device.h b/drivers/mtd/nandx/core/nand_device.h +-new file mode 100644 +-index 0000000000..e142cf529d + --- /dev/null + +++ b/drivers/mtd/nandx/core/nand_device.h + @@ -0,0 +1,608 @@ +@@ -3772,9 +3715,6 @@ index 0000000000..e142cf529d + + + +struct nand_device *nand_get_device(int index); + +#endif /* __NAND_DEVICE_H__ */ +-diff --git a/drivers/mtd/nandx/core/nfi.h b/drivers/mtd/nandx/core/nfi.h +-new file mode 100644 +-index 0000000000..ba84e73ccc + --- /dev/null + +++ b/drivers/mtd/nandx/core/nfi.h + @@ -0,0 +1,51 @@ +@@ -3829,9 +3769,6 @@ index 0000000000..ba84e73ccc + +void nfi_exit(struct nfi *nfi); + + + +#endif /* __NFI_H__ */ +-diff --git a/drivers/mtd/nandx/core/nfi/nfi_base.c b/drivers/mtd/nandx/core/nfi/nfi_base.c +-new file mode 100644 +-index 0000000000..d8679d7aa3 + --- /dev/null + +++ b/drivers/mtd/nandx/core/nfi/nfi_base.c + @@ -0,0 +1,1357 @@ +@@ -5192,9 +5129,6 @@ index 0000000000..d8679d7aa3 + + nfi_extend_exit(nb); + +} + + +-diff --git a/drivers/mtd/nandx/core/nfi/nfi_base.h b/drivers/mtd/nandx/core/nfi/nfi_base.h +-new file mode 100644 +-index 0000000000..ae894eaa31 + --- /dev/null + +++ b/drivers/mtd/nandx/core/nfi/nfi_base.h + @@ -0,0 +1,95 @@ +@@ -5293,9 +5227,6 @@ index 0000000000..ae894eaa31 + +void nfi_extend_exit(struct nfi_base *nb); + + + +#endif /* __NFI_BASE_H__ */ +-diff --git a/drivers/mtd/nandx/core/nfi/nfi_regs.h b/drivers/mtd/nandx/core/nfi/nfi_regs.h +-new file mode 100644 +-index 0000000000..ba4868acc8 + --- /dev/null + +++ b/drivers/mtd/nandx/core/nfi/nfi_regs.h + @@ -0,0 +1,114 @@ +@@ -5413,9 +5344,6 @@ index 0000000000..ba4868acc8 + + + +#endif /* __NFI_REGS_H__ */ + + +-diff --git a/drivers/mtd/nandx/core/nfi/nfi_spi.c b/drivers/mtd/nandx/core/nfi/nfi_spi.c +-new file mode 100644 +-index 0000000000..67cd0aaad9 + --- /dev/null + +++ b/drivers/mtd/nandx/core/nfi/nfi_spi.c + @@ -0,0 +1,689 @@ +@@ -6108,9 +6036,6 @@ index 0000000000..67cd0aaad9 + + mem_free(nfi_spi); + +} + + +-diff --git a/drivers/mtd/nandx/core/nfi/nfi_spi.h b/drivers/mtd/nandx/core/nfi/nfi_spi.h +-new file mode 100644 +-index 0000000000..a52255663a + --- /dev/null + +++ b/drivers/mtd/nandx/core/nfi/nfi_spi.h + @@ -0,0 +1,44 @@ +@@ -6158,9 +6083,6 @@ index 0000000000..a52255663a + +}; + + + +#endif /* __NFI_SPI_H__ */ +-diff --git a/drivers/mtd/nandx/core/nfi/nfi_spi_regs.h b/drivers/mtd/nandx/core/nfi/nfi_spi_regs.h +-new file mode 100644 +-index 0000000000..77adf46782 + --- /dev/null + +++ b/drivers/mtd/nandx/core/nfi/nfi_spi_regs.h + @@ -0,0 +1,64 @@ +@@ -6228,9 +6150,6 @@ index 0000000000..77adf46782 + +#define SPI_GPRAM_ADDR 0x800 + + + +#endif /* __NFI_SPI_REGS_H__ */ +-diff --git a/drivers/mtd/nandx/core/nfi/nfiecc.c b/drivers/mtd/nandx/core/nfi/nfiecc.c +-new file mode 100644 +-index 0000000000..14246fbc3e + --- /dev/null + +++ b/drivers/mtd/nandx/core/nfi/nfiecc.c + @@ -0,0 +1,510 @@ +@@ -6744,9 +6663,6 @@ index 0000000000..14246fbc3e + + mem_free(ecc); + +} + + +-diff --git a/drivers/mtd/nandx/core/nfi/nfiecc.h b/drivers/mtd/nandx/core/nfi/nfiecc.h +-new file mode 100644 +-index 0000000000..b02a5c3534 + --- /dev/null + +++ b/drivers/mtd/nandx/core/nfi/nfiecc.h + @@ -0,0 +1,90 @@ +@@ -6840,9 +6756,6 @@ index 0000000000..b02a5c3534 + +void nfiecc_exit(struct nfiecc *ecc); + + + +#endif /* __NFIECC_H__ */ +-diff --git a/drivers/mtd/nandx/core/nfi/nfiecc_regs.h b/drivers/mtd/nandx/core/nfi/nfiecc_regs.h +-new file mode 100644 +-index 0000000000..96564cf872 + --- /dev/null + +++ b/drivers/mtd/nandx/core/nfi/nfiecc_regs.h + @@ -0,0 +1,51 @@ +@@ -6897,9 +6810,6 @@ index 0000000000..96564cf872 + +#define NFIECC_DECEL(x) (0x120 + (x) * 4) + + + +#endif /* __NFIECC_REGS_H__ */ +-diff --git a/drivers/mtd/nandx/driver/Nandx.mk b/drivers/mtd/nandx/driver/Nandx.mk +-new file mode 100644 +-index 0000000000..3fb93d37c5 + --- /dev/null + +++ b/drivers/mtd/nandx/driver/Nandx.mk + @@ -0,0 +1,18 @@ +@@ -6921,9 +6831,6 @@ index 0000000000..3fb93d37c5 + +nandx-$(NANDX_KERNEL_SUPPORT) += kernel/driver.c + +nandx-$(NANDX_LK_SUPPORT) += lk/driver.c + +nandx-$(NANDX_UBOOT_SUPPORT) += uboot/driver.c +-diff --git a/drivers/mtd/nandx/driver/bbt/bbt.c b/drivers/mtd/nandx/driver/bbt/bbt.c +-new file mode 100644 +-index 0000000000..c9d4823e09 + --- /dev/null + +++ b/drivers/mtd/nandx/driver/bbt/bbt.c + @@ -0,0 +1,408 @@ +@@ -7335,9 +7242,6 @@ index 0000000000..c9d4823e09 + + + + return get_bbt_mark(g_bbt_manager.bbt, block) != BBT_BLOCK_GOOD; + +} +-diff --git a/drivers/mtd/nandx/driver/uboot/driver.c b/drivers/mtd/nandx/driver/uboot/driver.c +-new file mode 100644 +-index 0000000000..7bd3342452 + --- /dev/null + +++ b/drivers/mtd/nandx/driver/uboot/driver.c + @@ -0,0 +1,574 @@ +@@ -7915,9 +7819,6 @@ index 0000000000..7bd3342452 + +MODULE_LICENSE("GPL v2"); + +MODULE_DESCRIPTION("MTK Nand Flash Controller Driver"); + +MODULE_AUTHOR("MediaTek"); +-diff --git a/drivers/mtd/nandx/include/Nandx.mk b/drivers/mtd/nandx/include/Nandx.mk +-new file mode 100644 +-index 0000000000..667402790e + --- /dev/null + +++ b/drivers/mtd/nandx/include/Nandx.mk + @@ -0,0 +1,16 @@ +@@ -7937,9 +7838,6 @@ index 0000000000..667402790e + +nandx-header-$(NANDX_LK_SUPPORT) += lk/nandx_os.h + +nandx-header-$(NANDX_KERNEL_SUPPORT) += kernel/nandx_os.h + +nandx-header-$(NANDX_UBOOT_SUPPORT) += uboot/nandx_os.h +-diff --git a/drivers/mtd/nandx/include/internal/bbt.h b/drivers/mtd/nandx/include/internal/bbt.h +-new file mode 100644 +-index 0000000000..4676def1f5 + --- /dev/null + +++ b/drivers/mtd/nandx/include/internal/bbt.h + @@ -0,0 +1,62 @@ +@@ -8005,9 +7903,6 @@ index 0000000000..4676def1f5 + +int bbt_is_bad(struct nandx_info *nand, off_t offset); + + + +#endif /*__BBT_H__*/ +-diff --git a/drivers/mtd/nandx/include/internal/nandx_core.h b/drivers/mtd/nandx/include/internal/nandx_core.h +-new file mode 100644 +-index 0000000000..09aff72224 + --- /dev/null + +++ b/drivers/mtd/nandx/include/internal/nandx_core.h + @@ -0,0 +1,250 @@ +@@ -8261,9 +8156,6 @@ index 0000000000..09aff72224 + +#endif + + + +#endif /* __NANDX_CORE_H__ */ +-diff --git a/drivers/mtd/nandx/include/internal/nandx_errno.h b/drivers/mtd/nandx/include/internal/nandx_errno.h +-new file mode 100644 +-index 0000000000..51fb299c03 + --- /dev/null + +++ b/drivers/mtd/nandx/include/internal/nandx_errno.h + @@ -0,0 +1,40 @@ +@@ -8307,9 +8199,6 @@ index 0000000000..51fb299c03 + +#endif + + + +#endif /* __NANDX_ERRNO_H__ */ +-diff --git a/drivers/mtd/nandx/include/internal/nandx_util.h b/drivers/mtd/nandx/include/internal/nandx_util.h +-new file mode 100644 +-index 0000000000..1990b000ee + --- /dev/null + +++ b/drivers/mtd/nandx/include/internal/nandx_util.h + @@ -0,0 +1,221 @@ +@@ -8534,9 +8423,6 @@ index 0000000000..1990b000ee + +} + + + +#endif /* __NANDX_UTIL_H__ */ +-diff --git a/drivers/mtd/nandx/include/uboot/nandx_os.h b/drivers/mtd/nandx/include/uboot/nandx_os.h +-new file mode 100644 +-index 0000000000..8ea53378bf + --- /dev/null + +++ b/drivers/mtd/nandx/include/uboot/nandx_os.h + @@ -0,0 +1,78 @@ +@@ -8618,8 +8504,6 @@ index 0000000000..8ea53378bf + +} + + + +#endif /* __NANDX_OS_H__ */ +-diff --git a/include/configs/mt7622.h b/include/configs/mt7622.h +-index dfd506ed24..6d0c956484 100644 + --- a/include/configs/mt7622.h + +++ b/include/configs/mt7622.h + @@ -11,6 +11,31 @@ +@@ -8654,6 +8538,3 @@ index dfd506ed24..6d0c956484 100644 + #define CONFIG_SYS_MAXARGS 8 + #define CONFIG_SYS_BOOTM_LEN SZ_64M + #define CONFIG_SYS_CBSIZE SZ_1K +--- +-2.17.1 +- +diff --git a/package/boot/uboot-mediatek/patches/003-mt7622-uboot-add-dts-and-config-for-spi-nand.patch b/package/boot/uboot-mediatek/patches/003-mt7622-uboot-add-dts-and-config-for-spi-nand.patch +index 2c021e1c80..7167a498ad 100644 +--- a/package/boot/uboot-mediatek/patches/003-mt7622-uboot-add-dts-and-config-for-spi-nand.patch ++++ b/package/boot/uboot-mediatek/patches/003-mt7622-uboot-add-dts-and-config-for-spi-nand.patch +@@ -11,11 +11,9 @@ Signed-off-by: Xiangsheng Hou + arch/arm/dts/mt7622.dtsi | 20 ++++++++++++++++++++ + 2 files changed, 26 insertions(+) + +-diff --git a/arch/arm/dts/mt7622-rfb.dts b/arch/arm/dts/mt7622-rfb.dts +-index f05c3fe14d..05502bddec 100644 + --- a/arch/arm/dts/mt7622-rfb.dts + +++ b/arch/arm/dts/mt7622-rfb.dts +-@@ -143,6 +143,12 @@ ++@@ -174,6 +174,12 @@ + }; + }; + +@@ -28,11 +26,9 @@ index f05c3fe14d..05502bddec 100644 + &uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; +-diff --git a/arch/arm/dts/mt7622.dtsi b/arch/arm/dts/mt7622.dtsi +-index 1e8ec9b48b..63fdb63d4a 100644 + --- a/arch/arm/dts/mt7622.dtsi + +++ b/arch/arm/dts/mt7622.dtsi +-@@ -52,6 +52,26 @@ ++@@ -53,6 +53,26 @@ + #size-cells = <0>; + }; + +@@ -59,6 +55,3 @@ index 1e8ec9b48b..63fdb63d4a 100644 + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; +--- +-2.17.1 +- +diff --git a/package/boot/uboot-mediatek/patches/004-configs-enable-mtd-and-mtk_spi_nand-in-defconfig.patch b/package/boot/uboot-mediatek/patches/004-configs-enable-mtd-and-mtk_spi_nand-in-defconfig.patch +index cb564965c7..6999e5e235 100644 +--- a/package/boot/uboot-mediatek/patches/004-configs-enable-mtd-and-mtk_spi_nand-in-defconfig.patch ++++ b/package/boot/uboot-mediatek/patches/004-configs-enable-mtd-and-mtk_spi_nand-in-defconfig.patch +@@ -10,8 +10,6 @@ Signed-off-by: Sam Shih + configs/mt7622_rfb_defconfig | 5 +++++ + 1 file changed, 5 insertions(+) + +-diff --git a/configs/mt7622_rfb_defconfig b/configs/mt7622_rfb_defconfig +-index 1ce6ebdfeb..816126267b 100644 + --- a/configs/mt7622_rfb_defconfig + +++ b/configs/mt7622_rfb_defconfig + @@ -13,6 +13,7 @@ CONFIG_DEFAULT_FDT_FILE="mt7622-rfb" +@@ -22,18 +20,3 @@ index 1ce6ebdfeb..816126267b 100644 + CONFIG_CMD_PCI=y + CONFIG_CMD_SF_TEST=y + CONFIG_CMD_PING=y +- CONFIG_CMD_SMC=y +-@@ -25,6 +26,10 @@ CONFIG_CLK=y +- CONFIG_DM_MMC=y +- CONFIG_MMC_HS200_SUPPORT=y +- CONFIG_MMC_MTK=y +-+CONFIG_MTD=y +-+CONFIG_DM_MTD=y +-+CONFIG_MTK_SPI_NAND=y +-+CONFIG_MTD_RAW_NAND=y +- CONFIG_DM_SPI_FLASH=y +- CONFIG_SPI_FLASH_EON=y +- CONFIG_SPI_FLASH_GIGADEVICE=y +--- +-2.17.1 +- +diff --git a/package/boot/uboot-mediatek/patches/005-update-bpir2-defconfig.patch b/package/boot/uboot-mediatek/patches/005-update-bpir2-defconfig.patch +index cc7ed89280..b750dda6e8 100644 +--- a/package/boot/uboot-mediatek/patches/005-update-bpir2-defconfig.patch ++++ b/package/boot/uboot-mediatek/patches/005-update-bpir2-defconfig.patch +@@ -1,10 +1,9 @@ +-diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig +-index 6b9fbd7e22..fb2a004803 100644 + --- a/configs/mt7623n_bpir2_defconfig + +++ b/configs/mt7623n_bpir2_defconfig +-@@ -52,3 +52,13 @@ CONFIG_TIMER=y +- CONFIG_WDT_MTK=y +- CONFIG_LZMA=y ++@@ -51,5 +51,15 @@ CONFIG_SYSRESET=y ++ CONFIG_SYSRESET_WATCHDOG=y ++ CONFIG_TIMER=y ++ CONFIG_MTK_TIMER=y + +CONFIG_CMD_BOOTZ=y + +CONFIG_OF_LIBFDT_OVERLAY=y + +#enables savenenv-command +@@ -15,3 +14,5 @@ index 6b9fbd7e22..fb2a004803 100644 + +CONFIG_CMD_ASKENV=y + +CONFIG_ENV_SIZE=0x2000 + +CONFIG_CMD_SETEXPR=y ++ CONFIG_WDT_MTK=y ++ CONFIG_LZMA=y +diff --git a/package/boot/uboot-mediatek/patches/006-cmd-button-return-button-status.patch b/package/boot/uboot-mediatek/patches/006-cmd-button-return-button-status.patch +new file mode 100644 +index 0000000000..a413688f1c +--- /dev/null ++++ b/package/boot/uboot-mediatek/patches/006-cmd-button-return-button-status.patch +@@ -0,0 +1,38 @@ ++From a6bfd71a96201127836d59736abcb54dc2d5e1a5 Mon Sep 17 00:00:00 2001 ++From: Heinrich Schuchardt ++Date: Mon, 14 Sep 2020 12:50:56 +0200 ++Subject: [PATCH] cmd/button: return button status ++ ++To make the button command useful in a shell script it should return the ++status of the button: ++ ++* 0 (true) - pressed, on ++* 1 (false) - not pressed, off ++ ++The button command takes only one argument. Correct maxargs. ++ ++Adjust the Python unit test. ++ ++Signed-off-by: Heinrich Schuchardt ++Reviewed-by: Philippe Reynes ++--- ++ cmd/button.c | 4 ++-- ++ test/py/tests/test_button.py | 34 ++++++++++++++++++++++++++-------- ++ 2 files changed, 28 insertions(+), 10 deletions(-) ++ ++--- a/cmd/button.c +++++ b/cmd/button.c ++@@ -75,11 +75,11 @@ int do_button(struct cmd_tbl *cmdtp, int ++ ++ ret = show_button_state(dev); ++ ++- return 0; +++ return !ret; ++ } ++ ++ U_BOOT_CMD( ++- button, 4, 1, do_button, +++ button, 2, 1, do_button, ++ "manage buttons", ++ " \tGet button state\n" ++ "button list\t\tShow a list of buttons" +diff --git a/package/boot/uboot-mediatek/patches/007-env-readmem.patch b/package/boot/uboot-mediatek/patches/007-env-readmem.patch +new file mode 100644 +index 0000000000..a8c88a2757 +--- /dev/null ++++ b/package/boot/uboot-mediatek/patches/007-env-readmem.patch +@@ -0,0 +1,116 @@ ++--- a/cmd/Kconfig +++++ b/cmd/Kconfig ++@@ -571,6 +571,12 @@ config CMD_ENV_EXISTS ++ Check if a variable is defined in the environment for use in ++ shell scripting. ++ +++config CMD_ENV_READMEM +++ bool "env readmem" +++ default y +++ help +++ Store memory content into environment variable. +++ ++ config CMD_ENV_CALLBACK ++ bool "env callbacks - print callbacks and their associated variables" ++ help ++--- a/cmd/nvedit.c +++++ b/cmd/nvedit.c ++@@ -469,6 +469,60 @@ int do_env_ask(struct cmd_tbl *cmdtp, in ++ } ++ #endif ++ +++#if defined(CONFIG_CMD_ENV_READMEM) +++int do_env_readmem(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +++{ +++ char varstr[CONFIG_SYS_CBSIZE]; +++ const void *buf; +++ char *local_args[4]; +++ ulong addr, bytes = 6; +++ int hexdump = 0; +++ +++ /* +++ * Check the syntax: +++ * +++ * readmem [-b] name address [size] +++ */ +++ if (argc < 3) +++ return CMD_RET_USAGE; +++ +++ local_args[0] = argv[0]; +++ +++ if (!strncmp(argv[1], "-b", 3)) +++ hexdump = 1; +++ +++ local_args[1] = argv[hexdump + 1]; +++ local_args[2] = varstr; +++ local_args[3] = NULL; +++ +++ addr = simple_strtoul(argv[hexdump + 2], NULL, 16); +++ +++ if (!hexdump) +++ bytes = simple_strtoul(argv[hexdump + 3], NULL, 16); +++ +++ if (bytes < 1) +++ return 1; +++ +++ if ((hexdump * 3) * bytes >= CONFIG_SYS_CBSIZE) +++ return 1; +++ +++ buf = map_sysmem(addr, bytes); +++ if (!buf) +++ return 1; +++ +++ if (hexdump) { +++ sprintf(varstr, "%pM", buf); +++ } else { +++ memcpy(varstr, buf, bytes); +++ varstr[bytes] = '\0'; +++ } +++ unmap_sysmem(buf); +++ +++ /* Continue calling setenv code */ +++ return _do_env_set(flag, 3, local_args, H_INTERACTIVE); +++} +++#endif +++ ++ #if defined(CONFIG_CMD_ENV_CALLBACK) ++ static int print_static_binding(const char *var_name, const char *callback_name, ++ void *priv) ++@@ -1373,6 +1427,9 @@ static struct cmd_tbl cmd_env_sub[] = { ++ U_BOOT_CMD_MKENT(load, 1, 0, do_env_load, "", ""), ++ #endif ++ U_BOOT_CMD_MKENT(print, CONFIG_SYS_MAXARGS, 1, do_env_print, "", ""), +++#if defined(CONFIG_CMD_ENV_READMEM) +++ U_BOOT_CMD_MKENT(readmem, CONFIG_SYS_MAXARGS, 3, do_env_readmem, "", ""), +++#endif ++ #if defined(CONFIG_CMD_RUN) ++ U_BOOT_CMD_MKENT(run, CONFIG_SYS_MAXARGS, 1, do_run, "", ""), ++ #endif ++@@ -1461,6 +1518,9 @@ static char env_help_text[] = ++ #if defined(CONFIG_CMD_NVEDIT_EFI) ++ "env print -e [-guid guid] [-n] [name ...] - print UEFI environment\n" ++ #endif +++#if defined(CONFIG_CMD_ENV_READMEM) +++ "env readmem [-b] name address size - read variable from memory\n" +++#endif ++ #if defined(CONFIG_CMD_RUN) ++ "env run var [...] - run commands in an environment variable\n" ++ #endif ++@@ -1570,6 +1630,17 @@ U_BOOT_CMD( ++ ); ++ #endif ++ +++#if defined(CONFIG_CMD_ENV_READMEM) +++U_BOOT_CMD_COMPLETE( +++ readmem, CONFIG_SYS_MAXARGS, 3, do_env_readmem, +++ "get environment variable from memory address", +++ "name [-b] address size\n" +++ " - store memory address to env variable\n" +++ " \"-b\": read binary ethaddr", +++ var_complete +++); +++#endif +++ ++ #if defined(CONFIG_CMD_RUN) ++ U_BOOT_CMD_COMPLETE( ++ run, CONFIG_SYS_MAXARGS, 1, do_run, +diff --git a/package/boot/uboot-mediatek/patches/008-bootmenu-custom-title.patch b/package/boot/uboot-mediatek/patches/008-bootmenu-custom-title.patch +new file mode 100644 +index 0000000000..32f26ece8e +--- /dev/null ++++ b/package/boot/uboot-mediatek/patches/008-bootmenu-custom-title.patch +@@ -0,0 +1,32 @@ ++--- a/cmd/bootmenu.c +++++ b/cmd/bootmenu.c ++@@ -38,6 +38,7 @@ struct bootmenu_data { ++ int active; /* active menu entry */ ++ int count; /* total count of menu entries */ ++ struct bootmenu_entry *first; /* first menu entry */ +++ char *mtitle; /* custom menu title */ ++ }; ++ ++ enum bootmenu_key { ++@@ -380,7 +381,12 @@ static void menu_display_statusline(stru ++ printf(ANSI_CURSOR_POSITION, 1, 1); ++ puts(ANSI_CLEAR_LINE); ++ printf(ANSI_CURSOR_POSITION, 2, 1); ++- puts(" *** U-Boot Boot Menu ***"); +++ +++ if (menu->mtitle) +++ puts(menu->mtitle); +++ else +++ puts(" *** U-Boot Boot Menu ***"); +++ ++ puts(ANSI_CLEAR_LINE_TO_END); ++ printf(ANSI_CURSOR_POSITION, 3, 1); ++ puts(ANSI_CLEAR_LINE); ++@@ -434,6 +440,7 @@ static void bootmenu_show(int delay) ++ return; ++ } ++ +++ bootmenu->mtitle = env_get("bootmenu_title"); ++ for (iter = bootmenu->first; iter; iter = iter->next) { ++ if (!menu_item_add(menu, iter->key, iter)) ++ goto cleanup; +diff --git a/package/boot/uboot-mediatek/patches/009-mt7622-generic-reset-button-ignore-env.patch b/package/boot/uboot-mediatek/patches/009-mt7622-generic-reset-button-ignore-env.patch +new file mode 100644 +index 0000000000..037bbb89ea +--- /dev/null ++++ b/package/boot/uboot-mediatek/patches/009-mt7622-generic-reset-button-ignore-env.patch +@@ -0,0 +1,35 @@ ++--- a/board/mediatek/mt7622/mt7622_rfb.c +++++ b/board/mediatek/mt7622/mt7622_rfb.c ++@@ -6,9 +6,15 @@ ++ ++ #include ++ #include +++#include +++#include ++ #include ++ #include ++ +++#ifndef CONFIG_RESET_BUTTON_LABEL +++#define CONFIG_RESET_BUTTON_LABEL "reset" +++#endif +++ ++ DECLARE_GLOBAL_DATA_PTR; ++ ++ int board_init(void) ++@@ -19,7 +25,15 @@ int board_init(void) ++ ++ int board_late_init(void) ++ { ++- gd->env_valid = 1; //to load environment variable from persistent store +++ struct udevice *dev; +++ int ret; +++ +++ ret = !!button_get_by_label(CONFIG_RESET_BUTTON_LABEL, &dev); +++ +++ if (!ret) +++ ret = !button_get_state(dev); +++ +++ gd->env_valid = ret; //to load environment variable from persistent store ++ env_relocate(); ++ return 0; ++ } +diff --git a/package/boot/uboot-mediatek/patches/010-no-binman.patch b/package/boot/uboot-mediatek/patches/010-no-binman.patch +index a2680e56fd..7071a6c410 100644 +--- a/package/boot/uboot-mediatek/patches/010-no-binman.patch ++++ b/package/boot/uboot-mediatek/patches/010-no-binman.patch +@@ -1,6 +1,6 @@ +---- a/Makefile 2020-10-13 13:39:06.471438591 +0800 +-+++ b/Makefile 2020-10-13 13:39:39.190798462 +0800 +-@@ -1725,6 +1725,10 @@ ++--- a/Makefile +++++ b/Makefile ++@@ -1716,6 +1716,10 @@ u-boot-elf.lds: arch/u-boot-elf.lds prep + + ifeq ($(CONFIG_SPL),y) + spl/u-boot-spl-mtk.bin: spl/u-boot-spl +diff --git a/package/boot/uboot-mediatek/patches/010-update-u7623-defconfig.patch b/package/boot/uboot-mediatek/patches/010-update-u7623-defconfig.patch +index ec189f82dc..37d1b6a671 100644 +--- a/package/boot/uboot-mediatek/patches/010-update-u7623-defconfig.patch ++++ b/package/boot/uboot-mediatek/patches/010-update-u7623-defconfig.patch +@@ -1,5 +1,3 @@ +-diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig +-index 6b9fbd7e22..fb2a004803 100644 + --- a/configs/mt7623a_unielec_u7623_02_defconfig + +++ b/configs/mt7623a_unielec_u7623_02_defconfig + @@ -52,3 +52,12 @@ CONFIG_TIMER=y +diff --git a/package/boot/uboot-mediatek/patches/020-add-linksys-e8450.patch b/package/boot/uboot-mediatek/patches/020-add-linksys-e8450.patch +new file mode 100644 +index 0000000000..5f84b28ba9 +--- /dev/null ++++ b/package/boot/uboot-mediatek/patches/020-add-linksys-e8450.patch +@@ -0,0 +1,436 @@ ++--- /dev/null +++++ b/configs/mt7622_linksys_e8450_defconfig ++@@ -0,0 +1,130 @@ +++CONFIG_ARM=y +++CONFIG_POSITION_INDEPENDENT=y +++CONFIG_ARCH_MEDIATEK=y +++CONFIG_SYS_TEXT_BASE=0x41e00000 +++CONFIG_SYS_MALLOC_F_LEN=0x4000 +++CONFIG_USE_DEFAULT_ENV_FILE=y +++CONFIG_BOARD_LATE_INIT=y +++CONFIG_BOOTP_SEND_HOSTNAME=y +++CONFIG_DEFAULT_ENV_FILE="linksys_e8450_env" +++CONFIG_NR_DRAM_BANKS=1 +++CONFIG_DEFAULT_DEVICE_TREE="mt7622-linksys-e8450" +++CONFIG_SMBIOS_PRODUCT_NAME="" +++CONFIG_AUTOBOOT_KEYED=y +++CONFIG_BOOTDELAY=30 +++CONFIG_AUTOBOOT_MENU_SHOW=y +++CONFIG_CFB_CONSOLE_ANSI=y +++CONFIG_BUTTON=y +++CONFIG_BUTTON_GPIO=y +++CONFIG_CMD_ENV_FLAGS=y +++CONFIG_FIT=y +++CONFIG_FIT_ENABLE_SHA256_SUPPORT=y +++CONFIG_LED=y +++CONFIG_LED_BLINK=y +++CONFIG_LED_GPIO=y +++CONFIG_LOGLEVEL=7 +++CONFIG_LOG=y +++CONFIG_DEFAULT_FDT_FILE="mt7622-linksys-e8450" +++CONFIG_SYS_PROMPT="MT7622> " +++CONFIG_CMD_BOOTMENU=y +++CONFIG_CMD_BOOTP=y +++CONFIG_CMD_BUTTON=y +++CONFIG_CMD_CDP=y +++CONFIG_CMD_DHCP=y +++CONFIG_CMD_DNS=y +++CONFIG_CMD_ECHO=y +++CONFIG_CMD_ENV_READMEM=y +++CONFIG_CMD_ERASEENV=y +++CONFIG_CMD_EXT4=y +++CONFIG_CMD_FAT=y +++CONFIG_CMD_FS_GENERIC=y +++CONFIG_CMD_FS_UUID=y +++CONFIG_CMD_GPIO=y +++CONFIG_CMD_GPT=y +++CONFIG_CMD_HASH=y +++CONFIG_CMD_ITEST=y +++CONFIG_CMD_LED=y +++CONFIG_CMD_LICENSE=y +++CONFIG_CMD_LINK_LOCAL=y +++CONFIG_CMD_MBR=y +++CONFIG_CMD_MTD=y +++CONFIG_CMD_MTDPART=y +++CONFIG_CMD_NAND=y +++CONFIG_CMD_PCI=y +++CONFIG_CMD_SF_TEST=y +++CONFIG_CMD_PING=y +++CONFIG_CMD_PXE=y +++CONFIG_CMD_SMC=y +++CONFIG_CMD_TFTPBOOT=y +++CONFIG_CMD_TFTPSRV=y +++CONFIG_CMD_UBI=y +++CONFIG_CMD_UBI_RENAME=y +++CONFIG_CMD_UBIFS=y +++CONFIG_CMD_ASKENV=y +++CONFIG_CMD_PART=y +++CONFIG_CMD_PSTORE=y +++CONFIG_CMD_RARP=y +++CONFIG_CMD_SETEXPR=y +++CONFIG_CMD_SLEEP=y +++CONFIG_CMD_SNTP=y +++CONFIG_CMD_SOURCE=y +++CONFIG_CMD_USB=y +++CONFIG_CMD_UUID=y +++CONFIG_DISPLAY_CPUINFO=y +++CONFIG_DM_REGULATOR=y +++CONFIG_DM_REGULATOR_FIXED=y +++CONFIG_DM_REGULATOR_GPIO=y +++CONFIG_DM_USB=y +++CONFIG_HUSH_PARSER=y +++CONFIG_SYS_REDUNDAND_ENVIRONMENT=y +++CONFIG_SYS_RELOC_GD_ENV_ADDR=y +++CONFIG_ENV_IS_IN_UBI=y +++CONFIG_ENV_UBI_PART="ubi" +++CONFIG_ENV_UBI_VOLUME="ubootenv" +++CONFIG_ENV_UBI_VOLUME_REDUND="ubootenv2" +++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +++CONFIG_VERSION_VARIABLE=y +++CONFIG_PARTITION_UUIDS=y +++CONFIG_NETCONSOLE=y +++CONFIG_REGMAP=y +++CONFIG_SYSCON=y +++CONFIG_CLK=y +++CONFIG_DM_MTD=y +++CONFIG_PHY_FIXED=y +++CONFIG_DM_ETH=y +++CONFIG_MEDIATEK_ETH=y +++CONFIG_PCI=y +++CONFIG_MTD=y +++CONFIG_MTD_RAW_NAND=y +++CONFIG_MTD_UBI_FASTMAP=y +++CONFIG_DM_PCI=y +++CONFIG_PCIE_MEDIATEK=y +++CONFIG_PINCTRL=y +++CONFIG_PINCONF=y +++CONFIG_PINCTRL_MT7622=y +++CONFIG_POWER_DOMAIN=y +++CONFIG_PRE_CONSOLE_BUFFER=y +++CONFIG_PRE_CON_BUF_ADDR=0x4007EF00 +++CONFIG_MTK_POWER_DOMAIN=y +++CONFIG_RAM=y +++CONFIG_DM_SERIAL=y +++CONFIG_MTK_SERIAL=y +++CONFIG_SPI=y +++CONFIG_DM_SPI=y +++CONFIG_MTK_SNFI_SPI=y +++CONFIG_MTK_SPI_NAND=y +++CONFIG_NAND_SUPPORT=y +++CONFIG_SYSRESET_WATCHDOG=y +++CONFIG_TIMER=y +++CONFIG_MTK_TIMER=y +++CONFIG_WDT_MTK=y +++CONFIG_LZO=y +++CONFIG_ZSTD=y +++CONFIG_HEXDUMP=y +++CONFIG_RANDOM_UUID=y +++CONFIG_REGEX=y +++CONFIG_USB=y +++CONFIG_USB_HOST=y +++CONFIG_USB_XHCI_HCD=y +++CONFIG_USB_XHCI_MTK=y +++CONFIG_USB_STORAGE=y ++--- /dev/null +++++ b/arch/arm/dts/mt7622-linksys-e8450.dts ++@@ -0,0 +1,206 @@ +++// SPDX-License-Identifier: GPL-2.0 +++/* +++ * Copyright (c) 2019 MediaTek Inc. +++ * Author: Sam Shih +++ */ +++ +++/dts-v1/; +++#include "mt7622.dtsi" +++#include "mt7622-u-boot.dtsi" +++ +++/ { +++ #address-cells = <1>; +++ #size-cells = <1>; +++ model = "mt7622-linksys-e8450"; +++ compatible = "mediatek,mt7622", "linksys,e8450"; +++ chosen { +++ stdout-path = &uart0; +++ tick-timer = &timer0; +++ }; +++ +++ aliases { +++ spi0 = &snfi; +++ }; +++ +++ gpio-keys { +++ compatible = "gpio-keys"; +++ +++ factory { +++ label = "reset"; +++ gpios = <&gpio 0 GPIO_ACTIVE_LOW>; +++ }; +++ +++ wps { +++ label = "wps"; +++ gpios = <&gpio 102 GPIO_ACTIVE_LOW>; +++ }; +++ }; +++ +++ gpio-leds { +++ compatible = "gpio-leds"; +++ +++ led_power: power_blue { +++ label = "power:blue"; +++ gpios = <&gpio 95 GPIO_ACTIVE_LOW>; +++ default-state = "on"; +++ }; +++ +++ power_orange { +++ label = "power:orange"; +++ gpios = <&gpio 96 GPIO_ACTIVE_LOW>; +++ default-state = "off"; +++ }; +++ +++ inet_blue { +++ label = "inet:blue"; +++ gpios = <&gpio 97 GPIO_ACTIVE_LOW>; +++ default-state = "off"; +++ }; +++ +++ inet_orange { +++ label = "inet:orange"; +++ gpios = <&gpio 98 GPIO_ACTIVE_LOW>; +++ default-state = "off"; +++ }; +++ }; +++ +++ memory@40000000 { +++ device_type = "memory"; +++ reg = <0x40000000 0x1F000000>; +++ }; +++ +++ reg_1p8v: regulator-1p8v { +++ compatible = "regulator-fixed"; +++ regulator-name = "fixed-1.8V"; +++ regulator-min-microvolt = <1800000>; +++ regulator-max-microvolt = <1800000>; +++ regulator-boot-on; +++ regulator-always-on; +++ }; +++ +++ reg_3p3v: regulator-3p3v { +++ compatible = "regulator-fixed"; +++ regulator-name = "fixed-3.3V"; +++ regulator-min-microvolt = <3300000>; +++ regulator-max-microvolt = <3300000>; +++ regulator-boot-on; +++ regulator-always-on; +++ }; +++ +++ reg_5v: regulator-5v { +++ compatible = "regulator-fixed"; +++ regulator-name = "fixed-5V"; +++ regulator-min-microvolt = <5000000>; +++ regulator-max-microvolt = <5000000>; +++ regulator-boot-on; +++ regulator-always-on; +++ }; +++}; +++ +++&pcie { +++ pinctrl-names = "default"; +++ pinctrl-0 = <&pcie0_pins>, <&pcie1_pins>; +++ status = "okay"; +++ +++ pcie@0,0 { +++ status = "okay"; +++ }; +++ +++ pcie@1,0 { +++ status = "okay"; +++ }; +++}; +++ +++&pinctrl { +++ pcie0_pins: pcie0-pins { +++ mux { +++ function = "pcie"; +++ groups = "pcie0_pad_perst", +++ "pcie0_1_waken", +++ "pcie0_1_clkreq"; +++ }; +++ }; +++ +++ pcie1_pins: pcie1-pins { +++ mux { +++ function = "pcie"; +++ groups = "pcie1_pad_perst", +++ "pcie1_0_waken", +++ "pcie1_0_clkreq"; +++ }; +++ }; +++ +++ snfi_pins: snfi-pins { +++ mux { +++ function = "flash"; +++ groups = "snfi"; +++ }; +++ }; +++ +++ uart0_pins: uart0 { +++ mux { +++ function = "uart"; +++ groups = "uart0_0_tx_rx" ; +++ }; +++ }; +++ +++ watchdog_pins: watchdog-default { +++ mux { +++ function = "watchdog"; +++ groups = "watchdog"; +++ }; +++ }; +++}; +++ +++&snfi { +++ pinctrl-names = "default"; +++ pinctrl-0 = <&snfi_pins>; +++ status = "okay"; +++ +++ mediatek,bmt-v2; +++ +++ spi-flash@0{ +++ compatible = "jedec,spi-nor"; +++ reg = <0>; +++ u-boot,dm-pre-reloc; +++ }; +++}; +++ +++&nandc { +++ status = "okay"; +++}; +++ +++&uart0 { +++ pinctrl-names = "default"; +++ pinctrl-0 = <&uart0_pins>; +++ status = "okay"; +++}; +++ +++&watchdog { +++ pinctrl-names = "default"; +++ pinctrl-0 = <&watchdog_pins>; +++ status = "okay"; +++}; +++ +++ð { +++ status = "okay"; +++ mediatek,gmac-id = <0>; +++ phy-mode = "sgmii"; +++ mediatek,switch = "mt7531"; +++ reset-gpios = <&gpio 54 GPIO_ACTIVE_HIGH>; +++ +++ fixed-link { +++ speed = <1000>; +++ full-duplex; +++ }; +++}; +++ +++&ssusb { +++ vusb33-supply = <®_3p3v>; +++ vbus-supply = <®_5v>; +++ status = "okay"; +++}; +++ +++&u3phy { +++ status = "okay"; +++}; ++--- a/arch/arm/dts/Makefile +++++ b/arch/arm/dts/Makefile ++@@ -963,6 +963,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ ++ mt7622-rfb.dtb \ ++ mt7623a-unielec-u7623-02-emmc.dtb \ ++ mt7622-bananapi-bpi-r64.dtb \ +++ mt7622-linksys-e8450.dtb \ ++ mt7623n-bananapi-bpi-r2.dtb \ ++ mt7629-rfb.dtb \ ++ mt8512-bm1-emmc.dtb \ ++--- a/drivers/mtd/nandx/core/nand/device_spi.c +++++ b/drivers/mtd/nandx/core/nand/device_spi.c ++@@ -150,6 +150,21 @@ static struct device_spi spi_nand[] = { ++ &spi_extend_cmds, 0xff, 0xff ++ }, ++ { +++ NAND_DEVICE("FM35X1GA", +++ NAND_PACK_ID(0xe5, 0x71, 0, 0, 0, 0, 0, 0), +++ 2, 0, 3, 3, +++ 1, 1, 1, 1024, KB(128), KB(2), 64, 1, +++ &spi_cmds, &spi_addressing, &spi_status[0], +++ &spi_endurance, &spi_array_timing), +++ { +++ NAND_SPI_PROTECT(0xa0, 1, 2, 6), +++ NAND_SPI_CONFIG(0xb0, 4, 6, 1), +++ NAND_SPI_STATUS(0xc0, 4, 5), +++ NAND_SPI_CHARACTER(0xff, 0xff, 0xff, 0xff) +++ }, +++ &spi_extend_cmds, 0xff, 0xff +++ }, +++ { ++ NAND_DEVICE("NO-DEVICE", ++ NAND_PACK_ID(0, 0, 0, 0, 0, 0, 0, 0), 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 1, ++--- /dev/null +++++ b/linksys_e8450_env ++@@ -0,0 +1,57 @@ +++mtdparts=nand0:512k(bl2),1280k(fip),1024k(factory),256k(reserved),-(ubi) +++ethaddr_factory=nand read 0x40080000 0x220000 0x20000 && env readmem -b ethaddr 0x4009fffa 0x6 ; setenv ethaddr_factory +++ipaddr=192.168.1.1 +++serverip=192.168.1.254 +++loadaddr=0x4007ff28 +++bootcmd=run boot_ubi +++bootdelay=0 +++bootfile=openwrt-mediatek-mt7622-linksys_e8450_ubi-initramfs-kernel.bin +++bootfile_bl2=openwrt-mediatek-mt7622-linksys_e8450_ubi-preloader.bin +++bootfile_fip=openwrt-mediatek-mt7622-linksys_e8450_ubi-bl31-uboot.fip +++bootfile_upd=openwrt-mediatek-mt7622-linksys_e8450_ubi-squashfs-sysupgrade.fit +++bootmenu_confirm_return=askenv - Press ENTER to return to menu ; bootmenu +++bootmenu_default=0 +++bootmenu_delay=0 +++bootmenu_title= ( ( ( OpenWrt ) ) ) +++bootmenu_0=0. Initialize environment.=run _firstboot +++bootmenu_0d=0. Run default boot command.=run boot_default +++bootmenu_1=1. Boot recovery system from flash.=run boot_recovery ; run bootmenu_confirm_return +++bootmenu_2=2. Boot production system from flash.=run boot_production ; run bootmenu_confirm_return +++bootmenu_3=3. Boot system from TFTP.=run boot_tftp ; run bootmenu_confirm_return +++bootmenu_4=4. Load recovery system then write to flash via TFTP.=setenv noboot 1 ; run boot_tftp_recovery ; setenv noboot ; run bootmenu_confirm_return +++bootmenu_5=5. Load production system then write to flash via TFTP.=setenv noboot 1 ; run boot_tftp_production ; setenv noboot ; run bootmenu_confirm_return +++bootmenu_6=6. Load BL31+U-Boot FIP then write to flash via TFTP.=run boot_tftp_write_fip ; run bootmenu_confirm_return +++bootmenu_7=7. Load BL2 preloader then write to flash via TFTP.=run boot_tftp_write_preloader ; run bootmenu_confirm_return +++bootmenu_8=8. Reboot.=reset +++bootmenu_9=9. Reset all settings to factory defaults.=run reset_factory ; reset +++boot_first=if button reset ; then run boot_tftp_forever ; fi ; setenv flag_recover 1 ; bootmenu +++boot_default=if env exists flag_recover ; then else run bootcmd ; fi ; run boot_recovery ; run boot_tftp_forever +++boot_production=led power:blue on ; run ubi_read_production && bootm $loadaddr +++boot_production_or_recovery=run boot_production ; run boot_recovery +++boot_recovery=led power:blue off ; led power:orange on ; run check_recovery +++boot_serial_write_fip=loadx $loadaddr 115200 && run boot_write_fip +++boot_serial_write_preloader=loadx $loadaddr 115200 && run boot_write_preloader +++boot_tftp_forever=led inet:blue on ; while true ; do run boot_tftp_recovery ; led inet:blue off ; led inet:orange on ; sleep 1 ; done +++boot_tftp_production=tftpboot $loadaddr $bootfile_upd && iminfo $loadaddr && ubi part ubi && run ubi_write_production ubi_prepare_rootfs ; if env exists noboot ; then else bootm $loadaddr ; fi +++boot_tftp_recovery=tftpboot $loadaddr $bootfile && iminfo $loadaddr && ubi part ubi && run ubi_write_recovery ; if env exists noboot ; then else bootm $loadaddr ; fi +++boot_tftp=tftpboot $loadaddr $bootfile && bootm $loadaddr +++boot_tftp_write_fip=tftpboot $loadaddr $bootfile_fip && run boot_write_fip +++boot_tftp_write_preloader=tftpboot $loadaddr $bootfile_bl2 && run boot_write_preloader +++boot_ubi=ubi part ubi && run boot_production_or_recovery +++boot_write_fip=nand erase 0x80000 0x140000 && nand write $loadaddr 0x80000 0x140000 +++boot_write_preloader=nand erase 0x0 0x80000 && nand write $loadaddr 0x0 0x20000 && nand write $loadaddr 0x20000 0x20000 && nand write $loadaddr 0x40000 0x20000 && nand write $loadaddr 0x60000 0x20000 +++check_recovery=run ubi_read_recovery ; if iminfo $loadaddr ; then bootm $loadaddr ; else ubi remove recovery ; fi +++check_ubi=ubi part ubi || run ubi_format +++reset_factory=ubi part ubi ; ubi write 0x0 ubootenv 0x0 ; ubi write 0x0 ubootenv2 0x0 ; ubi remove rootfs_data +++ubi_format=ubi detach ; nand erase 0x300000 0x7D00000 && ubi part ubi ; reset +++ubi_prepare_rootfs=if ubi check rootfs_data ; then else if env exists rootfs_data_max ; then ubi create rootfs_data $rootfs_data_max dynamic || ubi create rootfs_data - dynamic ; else ubi create rootfs_data - dynamic ; fi ; fi +++ubi_read_production=ubi read $loadaddr fit && iminfo $loadaddr && run ubi_prepare_rootfs +++ubi_read_recovery=ubi check recovery && ubi read $loadaddr recovery +++ubi_remove_rootfs=ubi check rootfs_data && ubi remove rootfs_data +++ubi_write_production=run ubi_remove_rootfs ; ubi check fit && ubi remove fit ; run ubi_remove_rootfs ; ubi create fit $filesize dynamic && ubi write $loadaddr fit $filesize +++ubi_write_recovery=run ubi_remove_rootfs ; ubi check recovery && ubi remove recovery; ubi create recovery $filesize dynamic && ubi write $loadaddr recovery $filesize +++_create_env=ubi create ubootenv 0x100000 dynamic ; ubi create ubootenv2 0x100000 dynamic +++_init_env=setenv _init_env ; if ubi check ubootenv && ubi check ubootenv2 ; then else run _create_env ; fi ; setenv _create_env ; saveenv || run ubi_format ; saveenv || run ubi_format +++_firstboot=setenv _firstboot ; led power:orange on ; run _switch_to_menu ; run ethaddr_factory ; run check_ubi ; run _init_env ; run boot_first +++_switch_to_menu=setenv _switch_to_menu ; setenv bootdelay 3 ; setenv bootmenu_delay 3 ; setenv bootmenu_0 $bootmenu_0d ; setenv bootmenu_0d ; run _bootmenu_update_title +++_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title $ver" +diff --git a/package/boot/uboot-mediatek/patches/100-increase-CONFIG_SYS_BOOTM_LEN.patch b/package/boot/uboot-mediatek/patches/100-increase-CONFIG_SYS_BOOTM_LEN.patch +new file mode 100644 +index 0000000000..811e8489dd +--- /dev/null ++++ b/package/boot/uboot-mediatek/patches/100-increase-CONFIG_SYS_BOOTM_LEN.patch +@@ -0,0 +1,11 @@ ++--- a/include/configs/mt7622.h +++++ b/include/configs/mt7622.h ++@@ -37,7 +37,7 @@ ++ #endif ++ ++ #define CONFIG_SYS_MAXARGS 8 ++-#define CONFIG_SYS_BOOTM_LEN SZ_64M +++#define CONFIG_SYS_BOOTM_LEN SZ_128M ++ #define CONFIG_SYS_CBSIZE SZ_1K ++ #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ ++ sizeof(CONFIG_SYS_PROMPT) + 16) +-- +2.25.1 + diff --git a/backports/0020-uboot-envtools-add-defaults-for-linksys-e8450-ubi.patch b/backports/0020-uboot-envtools-add-defaults-for-linksys-e8450-ubi.patch new file mode 100644 index 000000000..63a2d112f --- /dev/null +++ b/backports/0020-uboot-envtools-add-defaults-for-linksys-e8450-ubi.patch @@ -0,0 +1,49 @@ +From ce99ccf70f226ea3aac19120ab8634b8cb6a1478 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Fri, 12 Feb 2021 03:09:39 +0000 +Subject: [PATCH 20/22] uboot-envtools: add defaults for linksys-e8450-ubi + +Add U-Boot environment configuration for the Linksys E8450 (UBI) to +allow access to the bootloader environment from OpenWrt via +'fw_printenv' and 'fw_setenv'. + +Signed-off-by: Daniel Golle +--- + package/boot/uboot-envtools/files/mediatek | 25 ++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + create mode 100644 package/boot/uboot-envtools/files/mediatek + +diff --git a/package/boot/uboot-envtools/files/mediatek b/package/boot/uboot-envtools/files/mediatek +new file mode 100644 +index 0000000000..92a04ea73d +--- /dev/null ++++ b/package/boot/uboot-envtools/files/mediatek +@@ -0,0 +1,25 @@ ++#!/bin/sh ++# ++# Copyright (C) 2021 OpenWrt.org ++# ++ ++[ -e /etc/config/ubootenv ] && exit 0 ++ ++touch /etc/config/ubootenv ++ ++. /lib/uboot-envtools.sh ++. /lib/functions.sh ++ ++board=$(board_name) ++ ++case "$board" in ++"linksys,e8450,ubi") ++ ubootenv_add_uci_config "/dev/ubi0_0" "0x0" "0x1f000" "0x1f000" "1" ++ ubootenv_add_uci_config "/dev/ubi0_1" "0x0" "0x1f000" "0x1f000" "1" ++ ;; ++esac ++ ++config_load ubootenv ++config_foreach ubootenv_add_app_config ubootenv ++ ++exit 0 +-- +2.25.1 + diff --git a/backports/0021-mediatek-linksys-e8450-ubi-add-alternative-UBI-NAND-.patch b/backports/0021-mediatek-linksys-e8450-ubi-add-alternative-UBI-NAND-.patch new file mode 100644 index 000000000..919386188 --- /dev/null +++ b/backports/0021-mediatek-linksys-e8450-ubi-add-alternative-UBI-NAND-.patch @@ -0,0 +1,1584 @@ +From 75d5297ad7f52a705f543e98e683f54bf1fafff6 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 9 Feb 2021 23:07:42 +0000 +Subject: [PATCH 01/23] mediatek: linksys-e8450-ubi: add alternative UBI NAND + layout + +The vendor flash layout of the Linksys E8450 is problematic as it uses +the SPI-NAND chip without any wear-leveling while at the same time +wasting a lot of space for padding. +Use an all-UBI layout instead, storing the kernel+dtb+squashfs in +uImage.FIT standard format in UBI volume 'fit', the read-write +overlay in UBI volume 'rootfs_data' as well as reduntant U-Boot +environments 'ubootenv' and 'ubootenv2', and a 'recovery' +kernel+dtb+initramfs uImage.FIT for dual-boot. + +** WARNING ** +THIS PROCEDURE CAN EASILY BRICK YOUR DEVICE PERMANENTLY IF NOT CARRIED +OUT VERY CAREFULLY AND EXACTLY AS DESCRIBED! +MAKE A COMPLETE BACKUP OF YOUR FLASH NOW! +(you can use *linksys_e8450_ubi-initramfs-kernel.bin to have full +access to the flash including raw access to the BBT area which is at +the end. this area at the end of the flash is used for legacy MTK +bad-block management and you will need to write it back there if you +ever want to go back to the vendor firmware or non-UBI OpenWrt!) + +In order to make use of a UBI-based flash layout, the complete boot- +chain needs to be replaced **in one go** (eg. using the original +bootloader). +Write the following files to the addresses listed below in flash: + +0x00000000-0x00020000 *-mt7622-linksys_e8450_ubi-preloader.bin +0x00080000-0x00180000 *-mt7622-linksys_e8450_ubi-bl31-uboot.fip + +An easy way to do that in the vendor loader's console: + +tftpboot 0x40080000 openwrt-mediatek-mt7622-linksys_e8450_ubi-preloader.bin +tftpboot 0x40100000 openwrt-mediatek-mt7622-linksys_e8450_ubi-bl31-uboot.fip +nand erase 0x0 0x180000 +nand write 0x40080000 0x0 0x180000 +reset + +Once the new bootchain comes up, the loader will initialize UBI and the +ubootenv volumes. It will then of course fail to find any bootable +volume and hence resort to load kernel via TFTP from server +192.168.1.254 while giving itself the address 192.168.1.1 +(bootp or even PXE could easily be used instead). + +The requested file is called +openwrt-mediatek-mt7622-linksys_e8450_ubi-initramfs-kernel.bin +and you should provide exactly that :) +It will be written to UBI as recovery image and booted. +You can then continue and flash the production OS image, either +by using sysupgrade in the booted initramfs recovery OS, or by using +the bootloader menu and TFTP. + +That's it. Go ahead and mess around with a bootchain built almost +completely from source (only DRAM calibration blobs are fitted in bl2, +and the irreplacable on-chip ROM loader remains, of course). +And enjoy U-Boot built with many great features out-of-the-box. + +You can access the bootloader environment from within OpenWrt using the +'fw_printenv' and 'fw_setenv' commands. Don't be afraid, once you got +the new bootchain installed the device should be fairly unbrickable +(holding reset button before and during power-on resets things and +allows reflashing recovery image via TFTP) + +Special thanks to @dvn0 (Devan Carpenter) for providing amazingly fast +infra for test-builds, allowing for `make clean ; make -j$(nproc)` in +less than two minutes :) + +Signed-off-by: Daniel Golle +--- + .../dts/mediatek/mt7622-linksys-e8450-ubi.dts | 59 +++ + .../dts/mediatek/mt7622-linksys-e8450.dts | 494 ++---------------- + .../dts/mediatek/mt7622-linksys-e8450.dtsi | 408 +++++++++++++++ + .../dts/mediatek/mt7622-ubnt-unifi-6-lr.dts | 327 ++++++++++++ + target/linux/mediatek/image/Makefile | 1 + + target/linux/mediatek/image/mt7622.mk | 28 + + .../mt7622/base-files/etc/board.d/01_leds | 2 +- + .../mt7622/base-files/etc/board.d/02_network | 8 +- + .../mt7622/base-files/lib/upgrade/platform.sh | 6 + + target/linux/mediatek/mt7622/config-5.10 | 1 + + 10 files changed, 890 insertions(+), 444 deletions(-) + create mode 100644 target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-linksys-e8450-ubi.dts + create mode 100644 target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-linksys-e8450.dtsi + create mode 100644 target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-ubnt-unifi-6-lr.dts + mode change 100755 => 100644 target/linux/mediatek/mt7622/config-5.10 + +diff --git a/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-linksys-e8450-ubi.dts b/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-linksys-e8450-ubi.dts +new file mode 100644 +index 0000000000..02b3bc8adc +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-linksys-e8450-ubi.dts +@@ -0,0 +1,59 @@ ++/* ++ * SPDX-License-Identifier: (GPL-2.0 OR MIT) ++ */ ++ ++/dts-v1/; ++#include "mt7622-linksys-e8450.dtsi" ++ ++/ { ++ model = "Linksys E8450 (UBI)"; ++ compatible = "linksys,e8450,ubi", "mediatek,mt7622"; ++ ++ aliases { ++ label-mac-device = &gmac0; ++ }; ++}; ++ ++&snand { ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "bl2"; ++ reg = <0x00000 0x0080000>; ++ read-only; ++ }; ++ ++ partition@80000 { ++ label = "fip"; ++ reg = <0x80000 0x0140000>; ++ read-only; ++ }; ++ ++ factory: partition@1c0000 { ++ label = "factory"; ++ reg = <0x1c0000 0x0100000>; ++ read-only; ++ }; ++ ++ partition@300000 { ++ label = "ubi"; ++ reg = <0x300000 0x7d00000>; ++ }; ++ }; ++}; ++ ++&wmac { ++ mediatek,mtd-eeprom = <&factory 0x0000>; ++ status = "okay"; ++}; ++ ++&wmac1 { ++ mediatek,mtd-eeprom = <&factory 0x05000>; ++}; ++ ++&gmac0 { ++ mtd-mac-address = <&factory 0x7fffa>; ++}; +diff --git a/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-linksys-e8450.dts b/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-linksys-e8450.dts +index 00b11690f0..53762d3fd1 100644 +--- a/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-linksys-e8450.dts ++++ b/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-linksys-e8450.dts +@@ -3,486 +3,102 @@ + */ + + /dts-v1/; +-#include +-#include +- +-#include "mt7622.dtsi" +-#include "mt6380.dtsi" ++#include "mt7622-linksys-e8450.dtsi" + + / { + model = "Linksys E8450"; + compatible = "linksys,e8450", "mediatek,mt7622"; + + aliases { +- serial0 = &uart0; +- led-boot = &led_power; +- led-failsafe = &led_power; +- led-running = &led_power; +- led-upgrade = &led_power; +- }; +- +- chosen { +- stdout-path = "serial0:115200n8"; +- bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512"; +- }; +- +- cpus { +- cpu@0 { +- proc-supply = <&mt6380_vcpu_reg>; +- sram-supply = <&mt6380_vm_reg>; +- }; +- +- cpu@1 { +- proc-supply = <&mt6380_vcpu_reg>; +- sram-supply = <&mt6380_vm_reg>; +- }; +- }; +- +- gpio-keys { +- compatible = "gpio-keys"; +- +- factory { +- label = "reset"; +- linux,code = ; +- gpios = <&pio 0 GPIO_ACTIVE_LOW>; +- }; +- +- wps { +- label = "wps"; +- linux,code = ; +- gpios = <&pio 102 GPIO_ACTIVE_LOW>; +- }; +- }; +- +- gpio-leds { +- compatible = "gpio-leds"; +- +- led_power: power_blue { +- label = "power:blue"; +- gpios = <&pio 95 GPIO_ACTIVE_LOW>; +- default-state = "on"; +- }; +- +- power_orange { +- label = "power:orange"; +- gpios = <&pio 96 GPIO_ACTIVE_LOW>; +- default-state = "off"; +- }; +- +- inet_blue { +- label = "inet:blue"; +- gpios = <&pio 97 GPIO_ACTIVE_LOW>; +- default-state = "off"; +- }; +- +- inet_orange { +- label = "inet:orange"; +- gpios = <&pio 98 GPIO_ACTIVE_LOW>; +- default-state = "off"; +- }; +- }; +- +- memory { +- reg = <0 0x40000000 0 0x40000000>; +- }; +- +- reg_1p8v: regulator-1p8v { +- compatible = "regulator-fixed"; +- regulator-name = "fixed-1.8V"; +- regulator-min-microvolt = <1800000>; +- regulator-max-microvolt = <1800000>; +- regulator-always-on; +- }; +- +- reg_3p3v: regulator-3p3v { +- compatible = "regulator-fixed"; +- regulator-name = "fixed-3.3V"; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; +- regulator-boot-on; +- regulator-always-on; +- }; +- +- reg_5v: regulator-5v { +- compatible = "regulator-fixed"; +- regulator-name = "fixed-5V"; +- regulator-min-microvolt = <5000000>; +- regulator-max-microvolt = <5000000>; +- regulator-boot-on; +- regulator-always-on; ++ label-mac-device = &gmac0; + }; + }; + +-&bch { +- status = "okay"; +-}; ++&snand { ++ mediatek,bmt-v2; ++ mediatek,bmt-table-size = <0x1000>; + +-&btif { +- status = "okay"; +-}; +- +-&cir { +- pinctrl-names = "default"; +- pinctrl-0 = <&irrx_pins>; +- status = "okay"; +-}; +- +-ð { +- pinctrl-names = "default"; +- pinctrl-0 = <ð_pins>; +- status = "okay"; +- +- gmac0: mac@0 { +- compatible = "mediatek,eth-mac"; +- reg = <0>; +- phy-mode = "2500base-x"; +- +- fixed-link { +- speed = <2500>; +- full-duplex; +- pause; +- }; +- }; +- +- mdio-bus { ++ partitions { ++ compatible = "fixed-partitions"; + #address-cells = <1>; +- #size-cells = <0>; +- +- switch@0 { +- compatible = "mediatek,mt7531"; +- reg = <0>; +- reset-gpios = <&pio 54 0>; +- +- ports { +- #address-cells = <1>; +- #size-cells = <0>; +- +- port@0 { +- reg = <0>; +- label = "lan1"; +- }; +- +- port@1 { +- reg = <1>; +- label = "lan2"; +- }; +- +- port@2 { +- reg = <2>; +- label = "lan3"; +- }; +- +- port@3 { +- reg = <3>; +- label = "lan4"; +- }; +- +- port@4 { +- reg = <4>; +- label = "wan"; +- }; +- +- port@6 { +- reg = <6>; +- label = "cpu"; +- ethernet = <&gmac0>; +- phy-mode = "2500base-x"; +- +- fixed-link { +- speed = <2500>; +- full-duplex; +- pause; +- }; +- }; +- }; +- }; +- +- }; +-}; +- +-&pcie0 { +- pinctrl-names = "default"; +- pinctrl-0 = <&pcie0_pins>; +- status = "okay"; +-}; +- +-&pcie1 { +- pinctrl-names = "default"; +- pinctrl-0 = <&pcie1_pins>; +- status = "okay"; +-}; +- +-&slot0 { +- mt7915@0,0 { +- reg = <0x0000 0 0 0 0>; +- mediatek,mtd-eeprom = <&factory 0x05000>; +- }; +-}; +- +-&pio { +- /* Attention: GPIO 90 is used to switch between PCIe@1,0 and +- * SATA functions. i.e. output-high: PCIe, output-low: SATA +- */ +-// asm_sel { +-// gpio-hog; +-// gpios = <90 GPIO_ACTIVE_HIGH>; +-// output-high; +-// }; +- +- eth_pins: eth-pins { +- mux { +- function = "eth"; +- groups = "mdc_mdio", "rgmii_via_gmac2"; +- }; +- }; +- +- irrx_pins: irrx-pins { +- mux { +- function = "ir"; +- groups = "ir_1_rx"; +- }; +- }; +- +- irtx_pins: irtx-pins { +- mux { +- function = "ir"; +- groups = "ir_1_tx"; +- }; +- }; ++ #size-cells = <1>; + +- pcie0_pins: pcie0-pins { +- mux { +- function = "pcie"; +- groups = "pcie0_pad_perst", +- "pcie0_1_waken", +- "pcie0_1_clkreq"; ++ partition@0 { ++ label = "Preloader"; ++ reg = <0x00000 0x0080000>; ++ read-only; + }; +- }; + +- pcie1_pins: pcie1-pins { +- mux { +- function = "pcie"; +- groups = "pcie1_pad_perst", +- "pcie1_0_waken", +- "pcie1_0_clkreq"; ++ partition@80000 { ++ label = "ATF"; ++ reg = <0x80000 0x0040000>; + }; +- }; + +- pmic_bus_pins: pmic-bus-pins { +- mux { +- function = "pmic"; +- groups = "pmic_bus"; ++ partition@c0000 { ++ label = "u-boot"; ++ reg = <0xc0000 0x0080000>; + }; +- }; + +- pwm7_pins: pwm1-2-pins { +- mux { +- function = "pwm"; +- groups = "pwm_ch7_2"; ++ partition@140000 { ++ label = "u-boot-env"; ++ reg = <0x140000 0x0080000>; + }; +- }; + +- wled_pins: wled-pins { +- mux { +- function = "led"; +- groups = "wled"; ++ factory: partition@1c0000 { ++ label = "factory"; ++ reg = <0x1c0000 0x0100000>; + }; +- }; + +- /* Serial NAND is shared pin with SPI-NOR */ +- serial_nand_pins: serial-nand-pins { +- mux { +- function = "flash"; +- groups = "snfi"; ++ partition@300000 { ++ label = "devinfo"; ++ reg = <0x300000 0x020000>; + }; +- }; + +- spic0_pins: spic0-pins { +- mux { +- function = "spi"; +- groups = "spic0_0"; ++ partition@320000 { ++ label = "senv"; ++ reg = <0x320000 0x020000>; + }; +- }; + +- spic1_pins: spic1-pins { +- mux { +- function = "spi"; +- groups = "spic1_0"; ++ partition@360000 { ++ label = "bootseq"; ++ reg = <0x360000 0x020000>; + }; +- }; + +- uart0_pins: uart0-pins { +- mux { +- function = "uart"; +- groups = "uart0_0_tx_rx" ; ++ partition@500000 { ++ label = "firmware1"; ++ compatible = "denx,fit"; ++ openwrt,cmdline-match = "mtdparts=master"; ++ reg = <0x500000 0x1E00000>; + }; +- }; + +- uart2_pins: uart2-pins { +- mux { +- function = "uart"; +- groups = "uart2_1_tx_rx" ; ++ partition@2300000 { ++ label = "firmware2"; ++ compatible = "denx,fit"; ++ openwrt,cmdline-match = "mtdparts=slave"; ++ reg = <0x2300000 0x1E00000>; + }; +- }; + +- watchdog_pins: watchdog-pins { +- mux { +- function = "watchdog"; +- groups = "watchdog"; ++ partition@4100000 { ++ label = "data"; ++ reg = <0x4100000 0x1900000>; + }; +- }; +-}; +- +-&pwm { +- pinctrl-names = "default"; +- pinctrl-0 = <&pwm7_pins>; +- status = "okay"; +-}; +- +-&pwrap { +- pinctrl-names = "default"; +- pinctrl-0 = <&pmic_bus_pins>; +- +- status = "okay"; +-}; +- +-&sata { +- status = "disabled"; +-}; +- +-&sata_phy { +- status = "disabled"; +-}; +- +-&snfi { +- pinctrl-names = "default"; +- pinctrl-0 = <&serial_nand_pins>; +- status = "okay"; +- +- spi_nand@0 { +- #address-cells = <1>; +- #size-cells = <1>; +- compatible = "spi-nand"; +- spi-max-frequency = <104000000>; +- reg = <0>; +- +- mediatek,bmt-v2; +- mediatek,bmt-table-size = <0x1000>; +- +- partitions { +- compatible = "fixed-partitions"; +- #address-cells = <1>; +- #size-cells = <1>; +- +- partition@0 { +- label = "Preloader"; +- reg = <0x00000 0x0080000>; +- read-only; +- }; +- +- partition@80000 { +- label = "ATF"; +- reg = <0x80000 0x0040000>; +- }; +- +- partition@c0000 { +- label = "u-boot"; +- reg = <0xc0000 0x0080000>; +- }; +- +- partition@140000 { +- label = "u-boot-env"; +- reg = <0x140000 0x0080000>; +- }; +- +- factory: partition@1c0000 { +- label = "factory"; +- reg = <0x1c0000 0x0100000>; +- }; +- +- partition@300000 { +- label = "devinfo"; +- reg = <0x300000 0x020000>; +- }; + +- partition@320000 { +- label = "senv"; +- reg = <0x320000 0x020000>; +- }; +- +- partition@360000 { +- label = "bootseq"; +- reg = <0x360000 0x020000>; +- }; +- +- partition@500000 { +- label = "firmware1"; +- compatible = "denx,fit"; +- openwrt,cmdline-match = "mtdparts=master"; +- reg = <0x500000 0x1E00000>; +- }; +- +- partition@2300000 { +- label = "firmware2"; +- compatible = "denx,fit"; +- openwrt,cmdline-match = "mtdparts=slave"; +- reg = <0x2300000 0x1E00000>; +- }; +- +- partition@4100000 { +- label = "data"; +- reg = <0x4100000 0x1900000>; +- }; +- +- partition@5100000 { +- label = "mfg"; +- reg = <0x5a00000 0x1400000>; +- }; ++ partition@5100000 { ++ label = "mfg"; ++ reg = <0x5a00000 0x1400000>; + }; + }; + }; + +-&spi0 { +- pinctrl-names = "default"; +- pinctrl-0 = <&spic0_pins>; +- status = "okay"; +-}; +- +-&spi1 { +- pinctrl-names = "default"; +- pinctrl-0 = <&spic1_pins>; +- status = "okay"; +-}; +- +-&ssusb { +- vusb33-supply = <®_3p3v>; +- vbus-supply = <®_5v>; +- status = "okay"; +-}; +- +-&u3phy { +- status = "okay"; +-}; +- +-&uart0 { +- pinctrl-names = "default"; +- pinctrl-0 = <&uart0_pins>; +- status = "okay"; +-}; +- +-&uart2 { +- pinctrl-names = "default"; +- pinctrl-0 = <&uart2_pins>; ++&wmac { ++ mediatek,mtd-eeprom = <&factory 0x0000>; + status = "okay"; + }; + +-&watchdog { +- pinctrl-names = "default"; +- pinctrl-0 = <&watchdog_pins>; +- status = "okay"; ++&wmac1 { ++ mediatek,mtd-eeprom = <&factory 0x05000>; + }; + +-&wmac { +- mediatek,mtd-eeprom = <&factory 0x0000>; +- status = "okay"; ++&gmac0 { ++ mtd-mac-address = <&factory 0x7fffa>; + }; +diff --git a/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-linksys-e8450.dtsi b/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-linksys-e8450.dtsi +new file mode 100644 +index 0000000000..032e5b4320 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-linksys-e8450.dtsi +@@ -0,0 +1,408 @@ ++/* ++ * SPDX-License-Identifier: (GPL-2.0 OR MIT) ++ */ ++ ++/dts-v1/; ++#include ++#include ++ ++#include "mt7622.dtsi" ++#include "mt6380.dtsi" ++ ++/ { ++ compatible = "linksys,e8450", "mediatek,mt7622"; ++ ++ aliases { ++ serial0 = &uart0; ++ led-boot = &led_power; ++ led-failsafe = &led_power; ++ led-running = &led_power; ++ led-upgrade = &led_power; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512"; ++ }; ++ ++ cpus { ++ cpu@0 { ++ proc-supply = <&mt6380_vcpu_reg>; ++ sram-supply = <&mt6380_vm_reg>; ++ }; ++ ++ cpu@1 { ++ proc-supply = <&mt6380_vcpu_reg>; ++ sram-supply = <&mt6380_vm_reg>; ++ }; ++ }; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ ++ factory { ++ label = "reset"; ++ linux,code = ; ++ gpios = <&pio 0 GPIO_ACTIVE_LOW>; ++ }; ++ ++ wps { ++ label = "wps"; ++ linux,code = ; ++ gpios = <&pio 102 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ gpio-leds { ++ compatible = "gpio-leds"; ++ ++ led_power: power_blue { ++ label = "power:blue"; ++ gpios = <&pio 95 GPIO_ACTIVE_LOW>; ++ default-state = "on"; ++ }; ++ ++ power_orange { ++ label = "power:orange"; ++ gpios = <&pio 96 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ ++ inet_blue { ++ label = "inet:blue"; ++ gpios = <&pio 97 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ ++ inet_orange { ++ label = "inet:orange"; ++ gpios = <&pio 98 GPIO_ACTIVE_LOW>; ++ default-state = "off"; ++ }; ++ }; ++ ++ memory { ++ reg = <0 0x40000000 0 0x40000000>; ++ }; ++ ++ reg_1p8v: regulator-1p8v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-1.8V"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ }; ++ ++ reg_3p3v: regulator-3p3v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-3.3V"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ reg_5v: regulator-5v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-5V"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++}; ++ ++&bch { ++ status = "okay"; ++}; ++ ++&btif { ++ status = "okay"; ++}; ++ ++&cir { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&irrx_pins>; ++ status = "okay"; ++}; ++ ++ð { ++ pinctrl-names = "default"; ++ pinctrl-0 = <ð_pins>; ++ status = "okay"; ++ ++ gmac0: mac@0 { ++ compatible = "mediatek,eth-mac"; ++ reg = <0>; ++ phy-mode = "2500base-x"; ++ ++ fixed-link { ++ speed = <2500>; ++ full-duplex; ++ pause; ++ }; ++ }; ++ ++ mdio-bus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ switch@0 { ++ compatible = "mediatek,mt7531"; ++ reg = <0>; ++ reset-gpios = <&pio 54 0>; ++ ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ port@0 { ++ reg = <0>; ++ label = "lan1"; ++ }; ++ ++ port@1 { ++ reg = <1>; ++ label = "lan2"; ++ }; ++ ++ port@2 { ++ reg = <2>; ++ label = "lan3"; ++ }; ++ ++ port@3 { ++ reg = <3>; ++ label = "lan4"; ++ }; ++ ++ port@4 { ++ reg = <4>; ++ label = "wan"; ++ }; ++ ++ port@6 { ++ reg = <6>; ++ label = "cpu"; ++ ethernet = <&gmac0>; ++ phy-mode = "2500base-x"; ++ ++ fixed-link { ++ speed = <2500>; ++ full-duplex; ++ pause; ++ }; ++ }; ++ }; ++ }; ++ ++ }; ++}; ++ ++&pcie0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie0_pins>; ++ status = "okay"; ++}; ++ ++&pcie1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie1_pins>; ++ status = "okay"; ++}; ++ ++&pio { ++ /* Attention: GPIO 90 is used to switch between PCIe@1,0 and ++ * SATA functions. i.e. output-high: PCIe, output-low: SATA ++ */ ++// asm_sel { ++// gpio-hog; ++// gpios = <90 GPIO_ACTIVE_HIGH>; ++// output-high; ++// }; ++ ++ eth_pins: eth-pins { ++ mux { ++ function = "eth"; ++ groups = "mdc_mdio", "rgmii_via_gmac2"; ++ }; ++ }; ++ ++ irrx_pins: irrx-pins { ++ mux { ++ function = "ir"; ++ groups = "ir_1_rx"; ++ }; ++ }; ++ ++ irtx_pins: irtx-pins { ++ mux { ++ function = "ir"; ++ groups = "ir_1_tx"; ++ }; ++ }; ++ ++ pcie0_pins: pcie0-pins { ++ mux { ++ function = "pcie"; ++ groups = "pcie0_pad_perst", ++ "pcie0_1_waken", ++ "pcie0_1_clkreq"; ++ }; ++ }; ++ ++ pcie1_pins: pcie1-pins { ++ mux { ++ function = "pcie"; ++ groups = "pcie1_pad_perst", ++ "pcie1_0_waken", ++ "pcie1_0_clkreq"; ++ }; ++ }; ++ ++ pmic_bus_pins: pmic-bus-pins { ++ mux { ++ function = "pmic"; ++ groups = "pmic_bus"; ++ }; ++ }; ++ ++ pwm7_pins: pwm1-2-pins { ++ mux { ++ function = "pwm"; ++ groups = "pwm_ch7_2"; ++ }; ++ }; ++ ++ wled_pins: wled-pins { ++ mux { ++ function = "led"; ++ groups = "wled"; ++ }; ++ }; ++ ++ /* Serial NAND is shared pin with SPI-NOR */ ++ serial_nand_pins: serial-nand-pins { ++ mux { ++ function = "flash"; ++ groups = "snfi"; ++ }; ++ }; ++ ++ spic0_pins: spic0-pins { ++ mux { ++ function = "spi"; ++ groups = "spic0_0"; ++ }; ++ }; ++ ++ spic1_pins: spic1-pins { ++ mux { ++ function = "spi"; ++ groups = "spic1_0"; ++ }; ++ }; ++ ++ uart0_pins: uart0-pins { ++ mux { ++ function = "uart"; ++ groups = "uart0_0_tx_rx" ; ++ }; ++ }; ++ ++ uart2_pins: uart2-pins { ++ mux { ++ function = "uart"; ++ groups = "uart2_1_tx_rx" ; ++ }; ++ }; ++ ++ watchdog_pins: watchdog-pins { ++ mux { ++ function = "watchdog"; ++ groups = "watchdog"; ++ }; ++ }; ++}; ++ ++&pwm { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm7_pins>; ++ status = "okay"; ++}; ++ ++&pwrap { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_bus_pins>; ++ ++ status = "okay"; ++}; ++ ++&sata { ++ status = "disabled"; ++}; ++ ++&sata_phy { ++ status = "disabled"; ++}; ++ ++&slot0 { ++ wmac1: mt7915@0,0 { ++ reg = <0x0000 0 0 0 0>; ++ ieee80211-freq-limit = <5000000 6000000>; ++ }; ++}; ++ ++&snfi { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&serial_nand_pins>; ++ status = "okay"; ++ ++ snand: spi_nand@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "spi-nand"; ++ spi-max-frequency = <104000000>; ++ reg = <0>; ++ }; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spic0_pins>; ++ status = "okay"; ++}; ++ ++&spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spic1_pins>; ++ status = "okay"; ++}; ++ ++&ssusb { ++ vusb33-supply = <®_3p3v>; ++ vbus-supply = <®_5v>; ++ status = "okay"; ++}; ++ ++&u3phy { ++ status = "okay"; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pins>; ++ status = "okay"; ++}; ++ ++&uart2 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart2_pins>; ++ status = "okay"; ++}; ++ ++&watchdog { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&watchdog_pins>; ++ status = "okay"; ++}; +diff --git a/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-ubnt-unifi-6-lr.dts b/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-ubnt-unifi-6-lr.dts +new file mode 100644 +index 0000000000..1f410b1d47 +--- /dev/null ++++ b/target/linux/mediatek/files-5.10/arch/arm64/boot/dts/mediatek/mt7622-ubnt-unifi-6-lr.dts +@@ -0,0 +1,327 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later OR MIT ++ ++/dts-v1/; ++#include ++#include ++#include ++ ++#include "mt7622.dtsi" ++#include "mt6380.dtsi" ++ ++/ { ++ model = "Ubiquiti UniFi 6 LR"; ++ compatible = "ubnt,unifi-6-lr", "mediatek,mt7622"; ++ ++ aliases { ++ led-boot = &led_blue; ++ led-failsafe = &led_blue; ++ led-running = &led_blue; ++ led-upgrade = &led_blue; ++ label-mac-device = &gmac0; ++ serial0 = &uart0; ++ }; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ bootargs = "earlycon=uart8250,mmio32,0x11002000 swiotlb=512 console=ttyS0,115200n8"; ++ }; ++ ++ cpus { ++ cpu@0 { ++ proc-supply = <&mt6380_vcpu_reg>; ++ sram-supply = <&mt6380_vm_reg>; ++ }; ++ ++ cpu@1 { ++ proc-supply = <&mt6380_vcpu_reg>; ++ sram-supply = <&mt6380_vm_reg>; ++ }; ++ }; ++ ++ gpio-keys { ++ compatible = "gpio-keys"; ++ ++ reset { ++ label = "reset"; ++ linux,code = ; ++ gpios = <&pio 62 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ memory { ++ reg = <0 0x40000000 0 0x3f000000>; ++ }; ++ ++ reg_1p8v: regulator-1p8v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-1.8V"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ }; ++ ++ reg_3p3v: regulator-3p3v { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-3.3V"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++}; ++ ++&pcie0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie0_pins>; ++ status = "okay"; ++}; ++ ++&slot0 { ++ wifi@0,0 { ++ reg = <0x0 0 0 0 0>; ++ mediatek,mtd-eeprom = <&factory 0x20000>; ++ mtd-mac-address = <&eeprom 0x6>; ++ ieee80211-freq-limit = <5000000 6000000>; ++ }; ++}; ++ ++&pio { ++ eth_pins: eth-pins { ++ mux { ++ function = "eth"; ++ groups = "mdc_mdio", "rgmii_via_gmac2"; ++ }; ++ }; ++ ++ pcie0_pins: pcie0-pins { ++ mux { ++ function = "pcie"; ++ groups = "pcie0_pad_perst", ++ "pcie0_1_waken", ++ "pcie0_1_clkreq"; ++ }; ++ }; ++ ++ pcie1_pins: pcie1-pins { ++ mux { ++ function = "pcie"; ++ groups = "pcie1_pad_perst", ++ "pcie1_0_waken", ++ "pcie1_0_clkreq"; ++ }; ++ }; ++ ++ pmic_bus_pins: pmic-bus-pins { ++ mux { ++ function = "pmic"; ++ groups = "pmic_bus"; ++ }; ++ }; ++ ++ spi_nor_pins: spi-nor-pins { ++ mux { ++ function = "flash"; ++ groups = "spi_nor"; ++ }; ++ }; ++ ++ uart0_pins: uart0-pins { ++ mux { ++ function = "uart"; ++ groups = "uart0_0_tx_rx" ; ++ }; ++ }; ++ ++ uart3_pins: uart3-pins { ++ mux { ++ function = "uart"; ++ groups = "uart3_1_tx_rx" ; ++ }; ++ }; ++ ++ i2c0_pins: i2c0-pins { ++ mux { ++ function = "i2c"; ++ groups = "i2c0"; ++ }; ++ }; ++ ++ watchdog_pins: watchdog-pins { ++ mux { ++ function = "watchdog"; ++ groups = "watchdog"; ++ }; ++ }; ++}; ++ ++&bch { ++ status = "okay"; ++}; ++ ++&btif { ++ status = "disabled"; ++}; ++ ++ð { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <ð_pins>; ++ ++ gmac0: mac@0 { ++ compatible = "mediatek,eth-mac"; ++ reg = <0>; ++ ++ phy-mode = "2500base-x"; ++ mtd-mac-address = <&eeprom 0x0>; ++ ++ fixed-link { ++ speed = <2500>; ++ full-duplex; ++ }; ++ }; ++ ++ mdio: mdio-bus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ ethernet-phy@8 { ++ /* Marvell AQRate AQR112W - no driver */ ++ compatible = "ethernet-phy-ieee802.3-c45"; ++ reg = <0x8>; ++ }; ++ }; ++}; ++ ++&pwrap { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pmic_bus_pins>; ++ ++ status = "okay"; ++}; ++ ++&nor_flash { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi_nor_pins>; ++ ++ status = "okay"; ++ ++ flash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <50000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "preloader"; ++ reg = <0x0 0x40000>; ++ read-only; ++ }; ++ ++ partition@40000 { ++ label = "atf"; ++ reg = <0x40000 0x20000>; ++ read-only; ++ }; ++ ++ partition@60000 { ++ label = "u-boot"; ++ reg = <0x60000 0x60000>; ++ read-only; ++ }; ++ ++ partition@c0000 { ++ label = "u-boot-env"; ++ reg = <0xc0000 0x10000>; ++ }; ++ ++ factory: partition@d0000 { ++ label = "factory"; ++ reg = <0xd0000 0x40000>; ++ read-only; ++ }; ++ ++ eeprom: partition@110000 { ++ label = "eeprom"; ++ reg = <0x110000 0x10000>; ++ read-only; ++ }; ++ ++ partition@120000 { ++ label = "bs"; ++ reg = <0x120000 0x10000>; ++ }; ++ ++ partition@130000 { ++ label = "cfg"; ++ reg = <0x130000 0x100000>; ++ read-only; ++ }; ++ ++ partition@230000 { ++ compatible = "denx,fit"; ++ label = "firmware"; ++ reg = <0x230000 0x1ee0000>; ++ }; ++ ++ partition@2110000 { ++ label = "kernel1"; ++ reg = <0x2110000 0x1ee0000>; ++ }; ++ }; ++ }; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pins>; ++ status = "okay"; ++}; ++ ++&uart3 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart3_pins>; ++ status = "okay"; ++ ++ /* MT7915 Bluetooth */ ++}; ++ ++&i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_pins>; ++ status = "okay"; ++ ++ led-controller@30 { ++ compatible = "ubnt,ledbar"; ++ reg = <0x30>; ++ ++ enable-gpio = <&pio 59 0>; ++ ++ red { ++ label = "red"; ++ }; ++ ++ green { ++ label = "green"; ++ }; ++ ++ led_blue: blue { ++ label = "blue"; ++ }; ++ }; ++}; ++ ++&watchdog { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&watchdog_pins>; ++ status = "okay"; ++}; ++ ++&wmac { ++ mediatek,mtd-eeprom = <&factory 0x0>; ++ mtd-mac-address = <&eeprom 0x0>; ++ status = "okay"; ++}; +diff --git a/target/linux/mediatek/image/Makefile b/target/linux/mediatek/image/Makefile +index 45e83cece5..0ad447e6c9 100644 +--- a/target/linux/mediatek/image/Makefile ++++ b/target/linux/mediatek/image/Makefile +@@ -29,6 +29,7 @@ define Device/Default + IMAGES := sysupgrade.bin + IMAGE/sysupgrade.bin := append-kernel | pad-to 128k | append-rootfs | \ + pad-rootfs | append-metadata ++ SUPPORTED_DEVICES := + endef + + include $(SUBTARGET).mk +diff --git a/target/linux/mediatek/image/mt7622.mk b/target/linux/mediatek/image/mt7622.mk +index df9e0d7d17..c33949ce05 100644 +--- a/target/linux/mediatek/image/mt7622.mk ++++ b/target/linux/mediatek/image/mt7622.mk +@@ -4,6 +4,14 @@ else + KERNEL_LOADADDR := 0x44000000 + endif + ++define Build/bl2 ++ $(CP) $(STAGING_DIR_IMAGE)/mt7622-$1-bl2.img $@ ++endef ++ ++define Build/bl31-uboot ++ $(CP) $(STAGING_DIR_IMAGE)/mt7622_$1-u-boot.fip $@ ++endef ++ + define Device/bpi_bananapi-r64 + DEVICE_VENDOR := Bpi + DEVICE_MODEL := Banana Pi R64 +@@ -46,6 +54,26 @@ define Device/linksys_e8450 + endef + TARGET_DEVICES += linksys_e8450 + ++define Device/linksys_e8450_ubi ++ DEVICE_VENDOR := Linksys ++ DEVICE_MODEL := E8450 (UBI) ++ DEVICE_DTS := mt7622-linksys-e8450-ubi ++ DEVICE_DTS_DIR := $(DTS_DIR)/mediatek ++ UBINIZE_OPTS := -E 5 ++ BLOCKSIZE := 128k ++ PAGESIZE := 2048 ++ UBOOTENV_IN_UBI := 1 ++ KERNEL_IN_UBI := 1 ++ KERNEL := kernel-bin | gzip ++ KERNEL_INITRAMFS := kernel-bin | gzip | fit gzip $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb ++ IMAGES := sysupgrade.fit ++ IMAGE/sysupgrade.fit := append-kernel | fit gzip $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb with-rootfs | append-metadata ++ DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-usb3 kmod-ata-ahci-mtk \ ++ kmod-mt7615e kmod-mt7615-firmware kmod-mt7915e \ ++ uboot-envtools ++endef ++TARGET_DEVICES += linksys_e8450_ubi ++ + define Device/mediatek_mt7622-rfb1 + DEVICE_VENDOR := MediaTek + DEVICE_MODEL := MTK7622 rfb1 AP +diff --git a/target/linux/mediatek/mt7622/base-files/etc/board.d/01_leds b/target/linux/mediatek/mt7622/base-files/etc/board.d/01_leds +index e74944a65f..214e53257b 100755 +--- a/target/linux/mediatek/mt7622/base-files/etc/board.d/01_leds ++++ b/target/linux/mediatek/mt7622/base-files/etc/board.d/01_leds +@@ -8,7 +8,7 @@ board=$(board_name) + board_config_update + + case $board in +-linksys,e8450) ++linksys,e8450*) + ucidef_set_led_netdev "wan" "WAN" "inet:blue" "wan" + ;; + esac +diff --git a/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network b/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network +index 3d2b9ffe49..82dba44587 100755 +--- a/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network ++++ b/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network +@@ -11,7 +11,7 @@ mediatek_setup_interfaces() + case $board in + bananapi,bpi-r64-rootdisk|\ + bananapi,bpi-r64|\ +- linksys,e8450|\ ++ linksys,e8450*|\ + mediatek,mt7622-rfb1) + ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" wan + ;; +@@ -30,9 +30,9 @@ mediatek_setup_macs() + local board="$1" + + case $board in +- linksys,e8450) +- wan_mac=$(mtd_get_mac_ascii devinfo wan_mac_addr) +- lan_mac=$(mtd_get_mac_ascii devinfo lan_mac_addr) ++ linksys,e8450*) ++ wan_mac=$(mtd_get_mac_binary factory 524282) ++ lan_mac=$(macaddr_add "$wan_mac" 1) + label_mac=$wan_mac + ;; + esac +diff --git a/target/linux/mediatek/mt7622/base-files/lib/upgrade/platform.sh b/target/linux/mediatek/mt7622/base-files/lib/upgrade/platform.sh +index 95ac8b5657..682724d85a 100755 +--- a/target/linux/mediatek/mt7622/base-files/lib/upgrade/platform.sh ++++ b/target/linux/mediatek/mt7622/base-files/lib/upgrade/platform.sh +@@ -1,5 +1,9 @@ ++RAMFS_COPY_BIN='fw_printenv fw_setenv' ++RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock' ++ + platform_do_upgrade() { + local board=$(board_name) ++ local file_type=$(identify $1) + + case "$board" in + bananapi,bpi-r64-rootdisk) +@@ -7,7 +11,9 @@ platform_do_upgrade() { + #of eMMC and to the location of the kernel + get_image "$1" | dd of=/dev/mmcblk0 bs=2097152 seek=1 conv=fsync + ;; ++ linksys,e8450,ubi|\ + mediatek,mt7622,ubi) ++ CI_KERNPART="fit" + nand_do_upgrade "$1" + ;; + linksys,e8450) +diff --git a/target/linux/mediatek/mt7622/config-5.10 b/target/linux/mediatek/mt7622/config-5.10 +old mode 100755 +new mode 100644 +index ccb54471c3..0098aa7204 +--- a/target/linux/mediatek/mt7622/config-5.10 ++++ b/target/linux/mediatek/mt7622/config-5.10 +@@ -154,6 +154,7 @@ CONFIG_DTC=y + CONFIG_DYNAMIC_DEBUG=y + CONFIG_EDAC_SUPPORT=y + CONFIG_EINT_MTK=y ++CONFIG_FIT_PARTITION=y + CONFIG_FIXED_PHY=y + CONFIG_FIX_EARLYCON_MEM=y + # CONFIG_FLATMEM_MANUAL is not set +-- +2.25.1 + diff --git a/backports/0022-realtek-update-to-latest-owrt-HEAD.patch b/backports/0022-realtek-update-to-latest-owrt-HEAD.patch new file mode 100644 index 000000000..ef7891372 --- /dev/null +++ b/backports/0022-realtek-update-to-latest-owrt-HEAD.patch @@ -0,0 +1,1506 @@ +From 7af6b8d742289a728629ecae929a0f8fa441ba3f Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Tue, 16 Mar 2021 10:46:51 +0100 +Subject: [PATCH 22/22] realtek: update to latest owrt HEAD + +Signed-off-by: John Crispin +--- + package/boot/uboot-envtools/files/realtek | 7 + + .../realtek/base-files/etc/board.d/01_leds | 1 - + .../realtek/base-files/etc/board.d/02_network | 3 + + target/linux/realtek/config-5.4 | 30 +- + .../realtek/dts/rtl8380_zyxel_gs1900-10hp.dts | 20 +- + .../dts/rtl8392_edgecore_ecs4100-12ph.dts | 297 ++++++++++++++++++ + target/linux/realtek/dts/rtl839x.dtsi | 198 ++++++++++++ + .../files-5.4/arch/mips/rtl838x/setup.c | 18 -- + .../files-5.4/drivers/gpio/edgecore_reboot.c | 61 ++++ + .../files-5.4/drivers/gpio/gpio-rtl838x.c | 3 + + .../drivers/net/dsa/rtl83xx/common.c | 22 +- + .../files-5.4/drivers/net/dsa/rtl83xx/dsa.c | 56 +++- + .../drivers/net/dsa/rtl83xx/rtl839x.c | 8 +- + .../drivers/net/ethernet/rtl838x_eth.c | 4 +- + .../files-5.4/drivers/net/phy/rtl83xx-phy.c | 9 +- + target/linux/realtek/image/Makefile | 9 + + .../realtek/patches-5.4/706-sysled.patch | 294 +++++++++++++++++ + .../realtek/patches-5.4/707-reboot.patch | 9 + + .../realtek/patches-5.4/708-poor-stp.patch | 16 + + .../realtek/patches-5.4/710-adt7470.patch | 22 ++ + 20 files changed, 1024 insertions(+), 63 deletions(-) + create mode 100644 target/linux/realtek/dts/rtl8392_edgecore_ecs4100-12ph.dts + create mode 100644 target/linux/realtek/dts/rtl839x.dtsi + create mode 100644 target/linux/realtek/files-5.4/drivers/gpio/edgecore_reboot.c + create mode 100644 target/linux/realtek/patches-5.4/706-sysled.patch + create mode 100644 target/linux/realtek/patches-5.4/707-reboot.patch + create mode 100644 target/linux/realtek/patches-5.4/708-poor-stp.patch + create mode 100644 target/linux/realtek/patches-5.4/710-adt7470.patch + +diff --git a/package/boot/uboot-envtools/files/realtek b/package/boot/uboot-envtools/files/realtek +index cce0628ffc..a4b7089d62 100644 +--- a/package/boot/uboot-envtools/files/realtek ++++ b/package/boot/uboot-envtools/files/realtek +@@ -11,11 +11,18 @@ case "$board" in + d-link,dgs-1210-16|\ + d-link,dgs-1210-28|\ + d-link,dgs-1210-10p|\ ++zyxel,gs1900-8hp-v1|\ ++zyxel,gs1900-8hp-v2|\ + zyxel,gs1900-10hp) + idx="$(find_mtd_index u-boot-env)" + [ -n "$idx" ] && \ + ubootenv_add_uci_config "/dev/mtd$idx" "0x0" "0x400" "0x10000" + ;; ++edgecore,ecs4100-12ph) ++ idx="$(find_mtd_index u-boot-env)" ++ [ -n "$idx" ] && \ ++ ubootenv_add_uci_config "/dev/mtd$idx" "0x0" "0x20000" "0x10000" ++ ;; + *) + idx="$(find_mtd_index u-boot-env)" + [ -n "$idx" ] && \ +diff --git a/target/linux/realtek/base-files/etc/board.d/01_leds b/target/linux/realtek/base-files/etc/board.d/01_leds +index 699ab817dd..36ca01a696 100755 +--- a/target/linux/realtek/base-files/etc/board.d/01_leds ++++ b/target/linux/realtek/base-files/etc/board.d/01_leds +@@ -1,5 +1,4 @@ + #!/bin/sh +- + . /lib/functions/uci-defaults.sh + + board=$(board_name) +diff --git a/target/linux/realtek/base-files/etc/board.d/02_network b/target/linux/realtek/base-files/etc/board.d/02_network +index 2568fd2e0e..4d025b0975 100755 +--- a/target/linux/realtek/base-files/etc/board.d/02_network ++++ b/target/linux/realtek/base-files/etc/board.d/02_network +@@ -49,6 +49,9 @@ done + [ -n "$label_mac" ] && ucidef_set_label_macaddr $label_mac + + case $board in ++edgecore,ecs4100-12ph) ++ ucidef_set_poe 60 "$lan_list" ++ ;; + netgear,gs110tpp-v1) + ucidef_set_poe 130 "$lan_list" + ;; +diff --git a/target/linux/realtek/config-5.4 b/target/linux/realtek/config-5.4 +index 2fbd904376..3b455f17e9 100644 +--- a/target/linux/realtek/config-5.4 ++++ b/target/linux/realtek/config-5.4 +@@ -2,17 +2,18 @@ CONFIG_ARCH_32BIT_OFF_T=y + CONFIG_ARCH_CLOCKSOURCE_DATA=y + CONFIG_ARCH_HIBERNATION_POSSIBLE=y + CONFIG_ARCH_MMAP_RND_BITS_MAX=15 ++CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15 + CONFIG_ARCH_SUSPEND_POSSIBLE=y + CONFIG_BLK_DEV_RAM=y + CONFIG_BLK_DEV_RAM_COUNT=16 + CONFIG_BLK_DEV_RAM_SIZE=4096 + CONFIG_CEVT_R4K=y +-CONFIG_CLONE_BACKWARDS=y +-CONFIG_COMPAT_32BIT_TIME=y +-CONFIG_HAVE_CLK=y + CONFIG_CLKDEV_LOOKUP=y ++CONFIG_CLKSRC_MMIO=y ++CONFIG_CLONE_BACKWARDS=y + CONFIG_COMMON_CLK=y + CONFIG_COMMON_CLK_BOSTON=y ++CONFIG_COMPAT_32BIT_TIME=y + CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15 + CONFIG_CPU_BIG_ENDIAN=y + CONFIG_CPU_GENERIC_DUMP_TLB=y +@@ -40,14 +41,10 @@ CONFIG_DMA_NONCOHERENT_CACHE_SYNC=y + CONFIG_DTC=y + CONFIG_EARLY_PRINTK=y + CONFIG_EARLY_PRINTK_8250=y +-CONFIG_EFI_EARLYCON=y + CONFIG_ETHERNET_PACKET_MANGLE=y + CONFIG_EXTRA_FIRMWARE="rtl838x_phy/rtl838x_8214fc.fw rtl838x_phy/rtl838x_8218b.fw rtl838x_phy/rtl838x_8380.fw" + CONFIG_EXTRA_FIRMWARE_DIR="firmware" + CONFIG_FIXED_PHY=y +-CONFIG_FONT_8x16=y +-CONFIG_FONT_AUTOSELECT=y +-CONFIG_FONT_SUPPORT=y + CONFIG_FW_LOADER_PAGED_BUF=y + CONFIG_GENERIC_ATOMIC64=y + CONFIG_GENERIC_CLOCKEVENTS=y +@@ -74,7 +71,8 @@ CONFIG_GENERIC_TIME_VSYSCALL=y + CONFIG_GPIOLIB=y + CONFIG_GPIO_RTL8231=y + CONFIG_GPIO_RTL838X=y +-CONFIG_REALTEK_SOC_PHY=y ++CONFIG_GPIO_WATCHDOG=y ++# CONFIG_GPIO_WATCHDOG_ARCH_INITCALL is not set + CONFIG_GRO_CELLS=y + CONFIG_HANDLE_DOMAIN_IRQ=y + CONFIG_HARDWARE_WATCHPOINTS=y +@@ -82,12 +80,14 @@ CONFIG_HAS_DMA=y + CONFIG_HAS_IOMEM=y + CONFIG_HAS_IOPORT_MAP=y + # CONFIG_HIGH_RES_TIMERS is not set ++CONFIG_HWMON=y + CONFIG_HZ=250 + CONFIG_HZ_250=y + CONFIG_HZ_PERIODIC=y + CONFIG_I2C=y + CONFIG_I2C_ALGOBIT=y + CONFIG_I2C_BOARDINFO=y ++CONFIG_I2C_CHARDEV=y + CONFIG_I2C_GPIO=y + CONFIG_INITRAMFS_SOURCE="" + CONFIG_IRQCHIP=y +@@ -101,10 +101,13 @@ CONFIG_LEGACY_PTYS=y + CONFIG_LEGACY_PTY_COUNT=256 + CONFIG_LIBFDT=y + CONFIG_LOCK_DEBUGGING_SUPPORT=y ++CONFIG_MARVELL_PHY=y + CONFIG_MDIO_BUS=y + CONFIG_MDIO_DEVICE=y + CONFIG_MDIO_I2C=y + CONFIG_MEMFD_CREATE=y ++CONFIG_MFD_CORE=y ++CONFIG_MFD_REALTEK_EIO=y + CONFIG_MFD_SYSCON=y + CONFIG_MIGRATION=y + CONFIG_MIPS=y +@@ -159,11 +162,17 @@ CONFIG_PINCTRL=y + CONFIG_POWER_RESET=y + CONFIG_POWER_RESET_SYSCON=y + CONFIG_PSB6970_PHY=y ++CONFIG_RATIONAL=y ++CONFIG_REALTEK_PHY=y ++CONFIG_REALTEK_SOC_PHY=y + CONFIG_REGMAP=y ++CONFIG_REGMAP_I2C=y + CONFIG_REGMAP_MMIO=y + CONFIG_RESET_CONTROLLER=y + CONFIG_RTL838X=y + CONFIG_RTL9300_TIMER=y ++CONFIG_SENSORS_GPIO_FAN=y ++CONFIG_SENSORS_LM75=y + CONFIG_SERIAL_MCTRL_GPIO=y + CONFIG_SERIAL_OF_PLATFORM=y + CONFIG_SFP=y +@@ -172,7 +181,7 @@ CONFIG_SPI_MASTER=y + CONFIG_SPI_MEM=y + CONFIG_SPI_RTL838X=y + CONFIG_SRCU=y +-CONFIG_SWAP_IO_SPACE=y ++CONFIG_SWCONFIG=y + CONFIG_SWPHY=y + CONFIG_SYSCTL_EXCEPTION_TRACE=y + CONFIG_SYS_HAS_CPU_MIPS32_R1=y +@@ -184,8 +193,11 @@ CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y + CONFIG_SYS_SUPPORTS_MIPS16=y + CONFIG_TARGET_ISA_REV=2 + CONFIG_TICK_CPU_ACCOUNTING=y ++CONFIG_TIMER_OF=y ++CONFIG_TIMER_PROBE=y + CONFIG_TINY_SRCU=y + CONFIG_USE_GENERIC_EARLY_PRINTK_8250=y + CONFIG_USE_OF=y ++CONFIG_WATCHDOG_CORE=y + CONFIG_ZLIB_DEFLATE=y + CONFIG_ZLIB_INFLATE=y +diff --git a/target/linux/realtek/dts/rtl8380_zyxel_gs1900-10hp.dts b/target/linux/realtek/dts/rtl8380_zyxel_gs1900-10hp.dts +index 92d0e25fc4..a590450055 100644 +--- a/target/linux/realtek/dts/rtl8380_zyxel_gs1900-10hp.dts ++++ b/target/linux/realtek/dts/rtl8380_zyxel_gs1900-10hp.dts +@@ -55,29 +55,17 @@ + port@24 { + reg = <24>; + label = "lan9"; +- phy-mode = "rgmii-id"; +- phy-handle = <&phy24>; ++ phy-mode = "1000base-x"; ++ managed = "in-band-status"; + sfp = <&sfp0>; +- +- fixed-link { +- speed = <1000>; +- full-duplex; +- pause; +- }; + }; + + port@26 { + reg = <26>; + label = "lan10"; +- phy-mode = "rgmii-id"; +- phy-handle = <&phy26>; ++ phy-mode = "1000base-x"; ++ managed = "in-band-status"; + sfp = <&sfp1>; +- +- fixed-link { +- speed = <1000>; +- full-duplex; +- pause; +- }; + }; + }; + }; +diff --git a/target/linux/realtek/dts/rtl8392_edgecore_ecs4100-12ph.dts b/target/linux/realtek/dts/rtl8392_edgecore_ecs4100-12ph.dts +new file mode 100644 +index 0000000000..7a1bccfa00 +--- /dev/null ++++ b/target/linux/realtek/dts/rtl8392_edgecore_ecs4100-12ph.dts +@@ -0,0 +1,297 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++ ++#include "rtl839x.dtsi" ++ ++#include ++#include ++ ++/ { ++ compatible = "edgecore,ecs4100-12ph", "realtek,rtl838x-soc"; ++ model = "Edgecore ECS4100-12PH Switch"; ++ ++ aliases { ++ led-boot = &led_sys; ++ led-failsafe = &led_sys; ++ led-running = &led_sys; ++ led-upgrade = &led_sys; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200"; ++ }; ++ ++ memory@0 { ++ device_type = "memory"; ++ reg = <0x0 0x10000000>; ++ }; ++ ++ /* i2c of the left SFP cage: port 9 */ ++ i2c0: i2c-gpio-0 { ++ compatible = "i2c-gpio"; ++ sda-gpios = <&gpio1 6 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; ++ scl-gpios = <&gpio1 7 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; ++ i2c-gpio,delay-us = <2>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ sfp0: sfp-p9 { ++ compatible = "sff,sfp"; ++ i2c-bus = <&i2c0>; ++ los-gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>; ++ mod-def0-gpio = <&gpio1 8 GPIO_ACTIVE_LOW>; ++ }; ++ ++ i2c1: i2c-gpio-1 { ++ compatible = "i2c-gpio"; ++ sda-gpios = <&gpio1 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; ++ scl-gpios = <&gpio1 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; ++ i2c-gpio,delay-us = <2>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ sfp1: sfp-p10 { ++ compatible = "sff,sfp"; ++ i2c-bus = <&i2c1>; ++ los-gpio = <&gpio0 14 GPIO_ACTIVE_HIGH>; ++ mod-def0-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>; ++ }; ++ ++ i2c2: i2c-gpio-2 { ++ compatible = "i2c-gpio"; ++ sda-gpios = <&gpio1 22 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; ++ scl-gpios = <&gpio1 23 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; ++ i2c-gpio,delay-us = <2>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ sfp2: sfp-p11 { ++ compatible = "sff,sfp"; ++ i2c-bus = <&i2c2>; ++ los-gpio = <&gpio0 21 GPIO_ACTIVE_HIGH>; ++ mod-def0-gpio = <&gpio1 24 GPIO_ACTIVE_LOW>; ++ }; ++ ++ i2c3: i2c-gpio-3 { ++ compatible = "i2c-gpio"; ++ sda-gpios = <&gpio1 11 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; ++ scl-gpios = <&gpio1 12 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; ++ i2c-gpio,delay-us = <2>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ sfp3: sfp-p12 { ++ compatible = "sff,sfp"; ++ i2c-bus = <&i2c3>; ++ los-gpio = <&gpio0 22 GPIO_ACTIVE_HIGH>; ++ mod-def0-gpio = <&gpio1 13 GPIO_ACTIVE_LOW>; ++ }; ++ ++ i2c4: i2c-gpio-4 { ++ compatible = "i2c-gpio"; ++ sda-gpios = <&gpio1 29 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; ++ scl-gpios = <&gpio1 30 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; ++ i2c-gpio,delay-us = <2>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ adt7470@2f { ++ compatible = "adi,adt7470"; ++ reg = <0x2f>; ++ }; ++ ++ lm75b@48 { ++ compatible = "nxp,lm75a"; ++ reg = <0x48>; ++ }; ++ ++ eeprom@506 { ++ compatible = "atmel,24c32"; ++ reg = <0x56>; ++ }; ++ }; ++ ++ watchdog { ++ compatible = "linux,wdt-gpio"; ++ gpios = <&gpio0 20 GPIO_ACTIVE_LOW>; ++ hw_algo = "toggle"; ++ hw_margin_ms = <1200>; ++ }; ++ ++ reboot@0 { ++ compatible = "edgecore,reboot"; ++ gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ fan0: gpio-fan { ++ #cooling-cells = <2>; ++ compatible = "gpio-fan"; ++ gpio-fan,speed-map = <0 0 3000 1>; ++ gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; ++ status = "okay"; ++ }; ++}; ++ ++&gpio1 { ++ status = "okay"; ++}; ++ ++&gpio0 { ++ poe_enable { ++ gpio-hog; ++ gpios = <16 GPIO_ACTIVE_HIGH>; ++ output-high; ++ }; ++ ++ poe_reset { ++ gpio-hog; ++ gpios = <18 GPIO_ACTIVE_HIGH>; ++ output-high; ++ }; ++}; ++ ++&spi0 { ++ status = "okay"; ++ ++ flash@0 { ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <10000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "u-boot"; ++ reg = <0x0 0x40000>; ++ read-only; ++ }; ++ partition@100000 { ++ label = "u-boot-env"; ++ reg = <0x100000 0x120000>; ++ read-only; ++ }; ++ partition@b260000 { ++ label = "firmware"; ++ reg = <0x200000 0xe00000>; ++ compatible = "openwrt,uimage", "denx,uimage"; ++ }; ++ }; ++ }; ++}; ++ ++ðernet0 { ++ mdio: mdio-bus { ++ compatible = "realtek,rtl838x-mdio"; ++ regmap = <ðernet0>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ INTERNAL_PHY(0) ++ INTERNAL_PHY(1) ++ INTERNAL_PHY(2) ++ INTERNAL_PHY(3) ++ INTERNAL_PHY(4) ++ INTERNAL_PHY(5) ++ INTERNAL_PHY(6) ++ INTERNAL_PHY(7) ++ ++ phy48: ethernet-phy@48 { ++ reg = <48>; ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ sfp = <&sfp0>; ++ }; ++ ++ phy49: ethernet-phy@49 { ++ reg = <49>; ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ sfp = <&sfp1>; ++ }; ++ ++ phy50: ethernet-phy@50 { ++ reg = <50>; ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ sfp = <&sfp2>; ++ }; ++ ++ phy51: ethernet-phy@51 { ++ reg = <51>; ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ sfp = <&sfp3>; ++ }; ++ }; ++}; ++ ++&switch0 { ++ ext_io: ext-io@e4 { ++ compatible = "realtek,rtl8390-eio", "syscon"; ++ reg = <0xe4 0x17c>; ++ ++ led_sys: sys-led { ++ active-low; ++ label = "green:status"; ++ linux,default-trigger = "default-on"; ++ }; ++ }; ++ ports { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ SWITCH_PORT(0, 1, internal) ++ SWITCH_PORT(1, 2, internal) ++ SWITCH_PORT(2, 3, internal) ++ SWITCH_PORT(3, 4, internal) ++ SWITCH_PORT(4, 5, internal) ++ SWITCH_PORT(5, 6, internal) ++ SWITCH_PORT(6, 7, internal) ++ SWITCH_PORT(7, 8, internal) ++ ++ port@48 { ++ reg = <48>; ++ label = "lan9"; ++ phy-mode = "sgmii"; ++ phy-handle = <&phy48>; ++ managed = "in-band-status"; ++ }; ++ ++ port@49 { ++ reg = <49>; ++ label = "lan10"; ++ phy-mode = "sgmii"; ++ phy-handle = <&phy49>; ++ managed = "in-band-status"; ++ }; ++ ++ port@50 { ++ reg = <50>; ++ label = "lan11"; ++ phy-mode = "sgmii"; ++ phy-handle = <&phy50>; ++ managed = "in-band-status"; ++ }; ++ ++ port@51 { ++ reg = <51>; ++ label = "lan12"; ++ phy-mode = "sgmii"; ++ phy-handle = <&phy51>; ++ managed = "in-band-status"; ++ }; ++ ++ port@28 { ++ ethernet = <ðernet0>; ++ reg = <28>; ++ phy-mode = "internal"; ++ ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ }; ++ }; ++ }; ++}; +diff --git a/target/linux/realtek/dts/rtl839x.dtsi b/target/linux/realtek/dts/rtl839x.dtsi +new file mode 100644 +index 0000000000..1eda5b77b4 +--- /dev/null ++++ b/target/linux/realtek/dts/rtl839x.dtsi +@@ -0,0 +1,198 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later OR MIT ++ ++/dts-v1/; ++ ++#define STRINGIZE(s) #s ++#define LAN_LABEL(p, s) STRINGIZE(p ## s) ++#define SWITCH_PORT_LABEL(n) LAN_LABEL(lan, n) ++ ++#define INTERNAL_PHY(n) \ ++ phy##n: ethernet-phy@##n { \ ++ reg = <##n>; \ ++ compatible = "ethernet-phy-ieee802.3-c22"; \ ++ phy-is-integrated; \ ++ }; ++ ++#define EXTERNAL_PHY(n) \ ++ phy##n: ethernet-phy@##n { \ ++ reg = <##n>; \ ++ compatible = "ethernet-phy-ieee802.3-c22"; \ ++ }; ++ ++#define EXTERNAL_SFP_PHY(n) \ ++ phy##n: ethernet-phy@##n { \ ++ compatible = "ethernet-phy-ieee802.3-c22"; \ ++ sfp; \ ++ media = "fibre"; \ ++ reg = <##n>; \ ++ }; ++ ++#define SWITCH_PORT(n, s, m) \ ++ port@##n { \ ++ reg = <##n>; \ ++ label = SWITCH_PORT_LABEL(s) ; \ ++ phy-handle = <&phy##n>; \ ++ phy-mode = #m ; \ ++ }; ++ ++#define SWITCH_SFP_PORT(n, s, m) \ ++ port@##n { \ ++ reg = <##n>; \ ++ label = SWITCH_PORT_LABEL(s) ; \ ++ phy-handle = <&phy##n>; \ ++ phy-mode = #m ; \ ++ fixed-link { \ ++ speed = <1000>; \ ++ full-duplex; \ ++ }; \ ++ }; ++ ++/ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ compatible = "realtek,rtl838x-soc"; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ frequency = <700000000>; ++ ++ cpu@0 { ++ compatible = "mips,mips34Kc"; ++ reg = <0>; ++ }; ++ }; ++ ++ memory@0 { ++ device_type = "memory"; ++ reg = <0x0 0x8000000>; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,38400"; ++ }; ++ ++ ++ cpuintc: cpuintc { ++ #address-cells = <0>; ++ #interrupt-cells = <1>; ++ interrupt-controller; ++ compatible = "mti,cpu-interrupt-controller"; ++ }; ++ ++ intc: rtlintc { ++ #address-cells = <0>; ++ #interrupt-cells = <1>; ++ interrupt-controller; ++ compatible = "realtek,rt8380-intc"; ++ reg = <0xb8003000 0x20>; ++ }; ++ ++ spi0: spi@b8001200 { ++ status = "okay"; ++ ++ compatible = "realtek,rtl838x-nor"; ++ reg = <0xb8001200 0x100>; ++ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ uart0: uart@b8002000 { ++ status = "okay"; ++ ++ compatible = "ns16550a"; ++ reg = <0xb8002000 0x100>; ++ ++ clock-frequency = <200000000>; ++ ++ interrupt-parent = <&intc>; ++ interrupts = <31>; ++ ++ reg-io-width = <1>; ++ reg-shift = <2>; ++ fifo-size = <1>; ++ no-loopback-test; ++ }; ++ ++ uart1: uart@b8002100 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&enable_uart1>; ++ ++ status = "okay"; ++ ++ compatible = "ns16550a"; ++ reg = <0xb8002100 0x100>; ++ ++ clock-frequency = <200000000>; ++ ++ interrupt-parent = <&intc>; ++ interrupts = <30>; ++ ++ reg-io-width = <1>; ++ reg-shift = <2>; ++ fifo-size = <1>; ++ no-loopback-test; ++ }; ++ ++ gpio0: gpio-controller@b8003500 { ++ compatible = "realtek,rtl838x-gpio"; ++ reg = <0xb8003500 0x20>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-parent = <&intc>; ++ interrupts = <23>; ++ }; ++ ++ gpio1: rtl8231-gpio { ++ status = "disabled"; ++ compatible = "realtek,rtl8231-gpio"; ++ #gpio-cells = <2>; ++ indirect-access-bus-id = <3>; ++ gpio-controller; ++ }; ++ ++ pinmux: pinmux@bb001000 { ++ compatible = "pinctrl-single"; ++ reg = <0xbb000004 0x4>; ++ ++ pinctrl-single,bit-per-mux; ++ pinctrl-single,register-width = <32>; ++ pinctrl-single,function-mask = <0x1>; ++ #pinctrl-cells = <2>; ++ ++ enable_uart1: pinmux_enable_uart1 { ++ pinctrl-single,bits = <0x0 0x01 0x03>; ++ }; ++ }; ++ ++ ethernet0: ethernet@bb00a300 { ++ status = "okay"; ++ ++ compatible = "realtek,rtl838x-eth"; ++ reg = <0xbb00a300 0x100>; ++ interrupt-parent = <&intc>; ++ interrupts = <24>; ++ #interrupt-cells = <1>; ++ phy-mode = "internal"; ++ ++ fixed-link { ++ speed = <1000>; ++ full-duplex; ++ }; ++ }; ++ ++ switch0: switch@bb000000 { ++ status = "okay"; ++ ++ interrupt-parent = <&intc>; ++ interrupts = <20>; ++ ++ compatible = "realtek,rtl83xx-switch", "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0x0 0xbb000000 0x10000>; ++ ++ }; ++}; +diff --git a/target/linux/realtek/files-5.4/arch/mips/rtl838x/setup.c b/target/linux/realtek/files-5.4/arch/mips/rtl838x/setup.c +index ef97d485e1..ea2dd0c866 100644 +--- a/target/linux/realtek/files-5.4/arch/mips/rtl838x/setup.c ++++ b/target/linux/realtek/files-5.4/arch/mips/rtl838x/setup.c +@@ -46,21 +46,6 @@ static void rtl838x_restart(char *command) + sw_w32(1, RTL838X_RST_GLB_CTRL_1); + } + +-static void rtl839x_restart(char *command) +-{ +- /* SoC reset vector (in flash memory): on RTL839x platform preferred way to reset */ +- void (*f)(void) = (void *) 0xbfc00000; +- +- pr_info("System restart.\n"); +- /* Reset SoC */ +- sw_w32(0xFFFFFFFF, RTL839X_RST_GLB_CTRL); +- /* and call reset vector */ +- f(); +- /* If this fails, halt the CPU */ +- while +- (1); +-} +- + static void rtl930x_restart(char *command) + { + pr_info("System restart.\n"); +@@ -109,8 +94,6 @@ static void __init rtl838x_setup(void) + static void __init rtl839x_setup(void) + { + pr_info("Registering _machine_restart\n"); +- _machine_restart = rtl839x_restart; +- _machine_halt = rtl838x_halt; + + /* Setup System LED. Bit 14 of RTL839X_LED_GLB_CTRL then allows to toggle it */ + sw_w32_mask(0, 3 << 15, RTL839X_LED_GLB_CTRL); +@@ -141,7 +124,6 @@ void __init plat_mem_setup(void) + void *dtb; + + set_io_port_base(KSEG1); +- _machine_restart = rtl838x_restart; + + if (fw_passed_dtb) /* UHI interface */ + dtb = (void *)fw_passed_dtb; +diff --git a/target/linux/realtek/files-5.4/drivers/gpio/edgecore_reboot.c b/target/linux/realtek/files-5.4/drivers/gpio/edgecore_reboot.c +new file mode 100644 +index 0000000000..2cafab4279 +--- /dev/null ++++ b/target/linux/realtek/files-5.4/drivers/gpio/edgecore_reboot.c +@@ -0,0 +1,61 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* Copyright (C) 2021 John Crispin */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static struct notifier_block edgecore_reboot_handler; ++static struct gpio_desc *gpiod; ++static int edgecore_reboot_handle(struct notifier_block *this, ++ unsigned long mode, void *cmd) ++{ ++ gpiod_direction_output(gpiod, 0); ++ mdelay(1000); ++ ++ pr_emerg("Unable to restart system\n"); ++ return NOTIFY_DONE; ++} ++ ++static int __init edgecore_reboot_probe(struct platform_device *pdev) ++{ ++ int err; ++ unsigned long flags = GPIOF_IN; ++ ++ gpiod = devm_gpiod_get_index(&pdev->dev, NULL, 0, flags); ++ if (!IS_ERR(gpiod)) ++ gpiod_set_consumer_name(gpiod, "reboot"); ++ else ++ return -EPROBE_DEFER; ++ ++ edgecore_reboot_handler.notifier_call = edgecore_reboot_handle; ++ edgecore_reboot_handler.priority = 255; ++ err = register_restart_handler(&edgecore_reboot_handler); ++ if (err) ++ printk("can't register restart notifier (err=%d)\n", err); ++ ++ ++ return 0; ++} ++ ++static const struct of_device_id edgecore_reboot_of_ids[] = { ++ { .compatible = "edgecore,reboot"}, ++ { /* sentinel */ } ++}; ++ ++ ++static struct platform_driver edgecore_reboot_driver = { ++ .probe = edgecore_reboot_probe, ++ .driver = { ++ .name = "edgecore_reboot", ++ .of_match_table = edgecore_reboot_of_ids, ++ }, ++}; ++ ++module_platform_driver(edgecore_reboot_driver); +diff --git a/target/linux/realtek/files-5.4/drivers/gpio/gpio-rtl838x.c b/target/linux/realtek/files-5.4/drivers/gpio/gpio-rtl838x.c +index 8207e4bb73..60b6f08834 100644 +--- a/target/linux/realtek/files-5.4/drivers/gpio/gpio-rtl838x.c ++++ b/target/linux/realtek/files-5.4/drivers/gpio/gpio-rtl838x.c +@@ -348,6 +348,9 @@ static int rtl838x_gpio_probe(struct platform_device *pdev) + case 0x8391: + pr_debug("Found RTL8391 GPIO\n"); + break; ++ case 0x8392: ++ pr_debug("Found RTL8392 GPIO\n"); ++ break; + case 0x8393: + pr_debug("Found RTL8393 GPIO\n"); + break; +diff --git a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/common.c b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/common.c +index 698f2892ea..2f0e568bc2 100644 +--- a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/common.c ++++ b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/common.c +@@ -368,8 +368,8 @@ static int __init rtl83xx_mdio_probe(struct rtl838x_switch_priv *priv) + + /* Enable PHY control via SoC */ + if (priv->family_id == RTL8380_FAMILY_ID) { +- /* Enable PHY control via SoC */ +- sw_w32_mask(0, BIT(15), RTL838X_SMI_GLB_CTRL); ++ /* Enable SerDes NWAY and PHY control via SoC */ ++ sw_w32_mask(BIT(7), BIT(15), RTL838X_SMI_GLB_CTRL); + } else { + /* Disable PHY polling via SoC */ + sw_w32_mask(BIT(7), 0, RTL839X_SMI_GLB_CTRL); +@@ -555,7 +555,6 @@ static int __init rtl83xx_sw_probe(struct platform_device *pdev) + int err = 0, i; + struct rtl838x_switch_priv *priv; + struct device *dev = &pdev->dev; +- u64 irq_mask; + u64 bpdu_mask; + + pr_debug("Probing RTL838X switch device\n"); +@@ -650,9 +649,9 @@ static int __init rtl83xx_sw_probe(struct platform_device *pdev) + + /* Enable link and media change interrupts. Are the SERDES masks needed? */ + sw_w32_mask(0, 3, priv->r->isr_glb_src); +- +- priv->r->set_port_reg_le(irq_mask, priv->r->isr_port_link_sts_chg); +- priv->r->set_port_reg_le(irq_mask, priv->r->imr_port_link_sts_chg); ++ ++ priv->r->set_port_reg_le(priv->irq_mask, priv->r->isr_port_link_sts_chg); ++ priv->r->set_port_reg_le(priv->irq_mask, priv->r->imr_port_link_sts_chg); + + priv->link_state_irq = platform_get_irq(pdev, 0); + pr_info("LINK state irq: %d\n", priv->link_state_irq); +@@ -708,6 +707,17 @@ static int __init rtl83xx_sw_probe(struct platform_device *pdev) + rtl838x_dbgfs_init(priv); + } + ++ if (of_machine_is_compatible("edgecore,ecs4100-12ph")) { ++ sw_w32(0x000000FF, 0x110); ++ sw_w32(0x00000000, 0x114); ++ sw_w32(0x00000000, 0x118); ++ sw_w32(0x000f0000, 0x11c); ++ sw_w32(0x00000000, 0x120); ++ sw_w32(0x000f0000, 0x124); ++ sw_w32(0x3DEA, 0xec); ++ sw_w32(0x707568, 0xe4); ++ } ++ + return err; + } + +diff --git a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/dsa.c b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/dsa.c +index e0832c42b8..9c088ea8b1 100644 +--- a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/dsa.c ++++ b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/dsa.c +@@ -79,7 +79,7 @@ static void rtl83xx_enable_phy_polling(struct rtl838x_switch_priv *priv) + /* Enable all ports with a PHY, including the SFP-ports */ + for (i = 0; i < priv->cpu_port; i++) { + if (priv->ports[i].phy) +- v |= BIT(i); ++ v |= BIT_ULL(i); + } + + pr_debug("%s: %16llx\n", __func__, v); +@@ -174,7 +174,7 @@ static int rtl83xx_setup(struct dsa_switch *ds) + */ + for (i = 0; i < priv->cpu_port; i++) { + if (priv->ports[i].phy) { +- priv->r->set_port_reg_be(BIT_ULL(priv->cpu_port) | BIT(i), ++ priv->r->set_port_reg_be(BIT_ULL(priv->cpu_port) | BIT_ULL(i), + priv->r->port_iso_ctrl(i)); + port_bitmap |= BIT_ULL(i); + } +@@ -218,8 +218,8 @@ static int rtl930x_setup(struct dsa_switch *ds) + + for (i = 0; i < priv->cpu_port; i++) { + if (priv->ports[i].phy) { +- priv->r->traffic_set(i, BIT(priv->cpu_port) | BIT(i)); +- port_bitmap |= 1ULL << i; ++ priv->r->traffic_set(i, BIT_ULL(priv->cpu_port) | BIT_ULL(i)); ++ port_bitmap |= BIT_ULL(i); + } + } + priv->r->traffic_set(priv->cpu_port, port_bitmap); +@@ -245,6 +245,7 @@ static void rtl83xx_phylink_validate(struct dsa_switch *ds, int port, + pr_debug("In %s port %d", __func__, port); + + if (!phy_interface_mode_is_rgmii(state->interface) && ++ state->interface != PHY_INTERFACE_MODE_NA && + state->interface != PHY_INTERFACE_MODE_1000BASEX && + state->interface != PHY_INTERFACE_MODE_MII && + state->interface != PHY_INTERFACE_MODE_REVMII && +@@ -278,6 +279,10 @@ static void rtl83xx_phylink_validate(struct dsa_switch *ds, int port, + if (port >= 24 && port <= 27 && priv->family_id == RTL8380_FAMILY_ID) + phylink_set(mask, 1000baseX_Full); + ++ /* On the RTL839x family of SoCs, ports 48 to 51 are SFP ports */ ++ if (port >=48 && port <= 51 && priv->family_id == RTL8390_FAMILY_ID) ++ phylink_set(mask, 1000baseX_Full); ++ + phylink_set(mask, 10baseT_Half); + phylink_set(mask, 10baseT_Full); + phylink_set(mask, 100baseT_Half); +@@ -310,7 +315,7 @@ static int rtl83xx_phylink_mac_link_state(struct dsa_switch *ds, int port, + link = priv->r->get_port_reg_le(priv->r->mac_link_sts); + if (link & BIT_ULL(port)) + state->link = 1; +- pr_info("%s: link state: %llx\n", __func__, link & BIT_ULL(port)); ++ pr_info("%s: link state port %d: %llx\n", __func__, port, link & BIT_ULL(port)); + + state->duplex = 0; + if (priv->r->get_port_reg_le(priv->r->mac_link_dup_sts) & BIT_ULL(port)) +@@ -343,6 +348,44 @@ static int rtl83xx_phylink_mac_link_state(struct dsa_switch *ds, int port, + return 1; + } + ++ ++static void rtl83xx_config_interface(int port, phy_interface_t interface) ++{ ++ u32 old, int_shift, sds_shift; ++ ++ switch (port) { ++ case 24: ++ int_shift = 0; ++ sds_shift = 5; ++ break; ++ case 26: ++ int_shift = 3; ++ sds_shift = 0; ++ break; ++ default: ++ return; ++ } ++ ++ old = sw_r32(RTL838X_SDS_MODE_SEL); ++ switch (interface) { ++ case PHY_INTERFACE_MODE_1000BASEX: ++ if ((old >> sds_shift & 0x1f) == 4) ++ return; ++ sw_w32_mask(0x7 << int_shift, 1 << int_shift, RTL838X_INT_MODE_CTRL); ++ sw_w32_mask(0x1f << sds_shift, 4 << sds_shift, RTL838X_SDS_MODE_SEL); ++ break; ++ case PHY_INTERFACE_MODE_SGMII: ++ if ((old >> sds_shift & 0x1f) == 2) ++ return; ++ sw_w32_mask(0x7 << int_shift, 2 << int_shift, RTL838X_INT_MODE_CTRL); ++ sw_w32_mask(0x1f << sds_shift, 2 << sds_shift, RTL838X_SDS_MODE_SEL); ++ break; ++ default: ++ return; ++ } ++ pr_debug("configured port %d for interface %s\n", port, phy_modes(interface)); ++} ++ + static void rtl83xx_phylink_mac_config(struct dsa_switch *ds, int port, + unsigned int mode, + const struct phylink_link_state *state) +@@ -376,10 +419,11 @@ static void rtl83xx_phylink_mac_config(struct dsa_switch *ds, int port, + reg = sw_r32(priv->r->mac_force_mode_ctrl(port)); + /* Auto-Negotiation does not work for MAC in RTL8390 */ + if (priv->family_id == RTL8380_FAMILY_ID) { +- if (mode == MLO_AN_PHY) { ++ if (mode == MLO_AN_PHY || phylink_autoneg_inband(mode)) { + pr_debug("PHY autonegotiates\n"); + reg |= BIT(2); + sw_w32(reg, priv->r->mac_force_mode_ctrl(port)); ++ rtl83xx_config_interface(port, state->interface); + return; + } + } +diff --git a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c +index 5106bd2e9d..91947a20ed 100644 +--- a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c ++++ b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c +@@ -275,7 +275,7 @@ void rtl839x_traffic_enable(int source, int dest) + + void rtl839x_traffic_disable(int source, int dest) + { +- rtl839x_mask_port_reg_be(BIT(dest), 0, rtl839x_port_iso_ctrl(source)); ++ rtl839x_mask_port_reg_be(BIT_ULL(dest), 0, rtl839x_port_iso_ctrl(source)); + } + + irqreturn_t rtl839x_switch_irq(int irq, void *dev_id) +@@ -290,10 +290,10 @@ irqreturn_t rtl839x_switch_irq(int irq, void *dev_id) + rtl839x_set_port_reg_le(ports, RTL839X_ISR_PORT_LINK_STS_CHG); + pr_debug("RTL8390 Link change: status: %x, ports %llx\n", status, ports); + +- for (i = 0; i < 52; i++) { +- if (ports & (1ULL << i)) { ++ for (i = 0; i < RTL839X_CPU_PORT; i++) { ++ if (ports & BIT_ULL(i)) { + link = rtl839x_get_port_reg_le(RTL839X_MAC_LINK_STS); +- if (link & (1ULL << i)) ++ if (link & BIT_ULL(i)) + dsa_port_phylink_mac_change(ds, i, true); + else + dsa_port_phylink_mac_change(ds, i, false); +diff --git a/target/linux/realtek/files-5.4/drivers/net/ethernet/rtl838x_eth.c b/target/linux/realtek/files-5.4/drivers/net/ethernet/rtl838x_eth.c +index 7931daff07..7d0f692ee3 100644 +--- a/target/linux/realtek/files-5.4/drivers/net/ethernet/rtl838x_eth.c ++++ b/target/linux/realtek/files-5.4/drivers/net/ethernet/rtl838x_eth.c +@@ -1580,7 +1580,7 @@ static int rtl839x_mdio_read(struct mii_bus *bus, int mii_id, int regnum) + int err; + struct rtl838x_eth_priv *priv = bus->priv; + +- if (mii_id >= 48 && mii_id <= 49 && priv->id == 0x8393) ++ if (mii_id >= 48 && mii_id <= 51 && priv->id == 0x8393) + return rtl839x_read_sds_phy(mii_id, regnum); + + err = rtl839x_read_phy(mii_id, 0, regnum, &val); +@@ -1644,7 +1644,7 @@ static int rtl839x_mdio_write(struct mii_bus *bus, int mii_id, + { + struct rtl838x_eth_priv *priv = bus->priv; + +- if (mii_id >= 48 && mii_id <= 49 && priv->id == 0x8393) ++ if (mii_id >= 48 && mii_id <= 51 && priv->id == 0x8393) + return rtl839x_write_sds_phy(mii_id, regnum, value); + + return rtl839x_write_phy(mii_id, 0, regnum, value); +diff --git a/target/linux/realtek/files-5.4/drivers/net/phy/rtl83xx-phy.c b/target/linux/realtek/files-5.4/drivers/net/phy/rtl83xx-phy.c +index 78953c6d17..7a153ec7bd 100644 +--- a/target/linux/realtek/files-5.4/drivers/net/phy/rtl83xx-phy.c ++++ b/target/linux/realtek/files-5.4/drivers/net/phy/rtl83xx-phy.c +@@ -1296,7 +1296,7 @@ static int rtl8380_configure_rtl8214fc(struct phy_device *phydev) + for (i = 0; i < 4; i++) { + for (l = 0; l < 100; l++) { + read_phy(mac + i, 0xb80, 0x10, &val); +- if (val & 0x40) ++ if (val & 0x80) + break; + } + if (l >= 100) { +@@ -1336,6 +1336,13 @@ static int rtl8380_configure_rtl8214fc(struct phy_device *phydev) + write_phy(mac + i, 0xfff, 0x1e, 0x0000); + } + ++ if (of_machine_is_compatible("edgecore,ecs4100-12ph")) { ++ printk("setting edgecore specific SFP modes\n"); ++ rtl8380_rtl8214fc_media_set(mac + 0, 0); ++ rtl8380_rtl8214fc_media_set(mac + 1, 0); ++ rtl8380_rtl8214fc_media_set(mac + 2, 1); ++ rtl8380_rtl8214fc_media_set(mac + 3, 1); ++ } + return 0; + } + +diff --git a/target/linux/realtek/image/Makefile b/target/linux/realtek/image/Makefile +index 424726c8a9..760ebc6bc1 100644 +--- a/target/linux/realtek/image/Makefile ++++ b/target/linux/realtek/image/Makefile +@@ -118,4 +118,13 @@ define Device/zyxel_gs1900-8hp-v2 + endef + TARGET_DEVICES += zyxel_gs1900-8hp-v2 + ++define Device/edgecore_ecs4100-12ph ++ SOC := rtl8392 ++ IMAGE_SIZE := 6976k ++ DEVICE_VENDOR := Edgecore ++ DEVICE_MODEL := ECS4100-12PH ++ DEVICE_PACKAGES += lua-rs232 ++endef ++TARGET_DEVICES += edgecore_ecs4100-12ph ++ + $(eval $(call BuildImage)) +diff --git a/target/linux/realtek/patches-5.4/706-sysled.patch b/target/linux/realtek/patches-5.4/706-sysled.patch +new file mode 100644 +index 0000000000..c13885d5ac +--- /dev/null ++++ b/target/linux/realtek/patches-5.4/706-sysled.patch +@@ -0,0 +1,294 @@ ++From c1a89fdf22862379bb4150fc76504e2d3384cd67 Mon Sep 17 00:00:00 2001 ++From: Bert Vermeulen ++Date: Mon, 1 Mar 2021 12:41:35 +0100 ++Subject: [PATCH] mfd: Add Realtek RTL838x/RTL839x sys-led driver ++ ++--- ++ drivers/mfd/Kconfig | 11 ++ ++ drivers/mfd/Makefile | 1 + ++ drivers/mfd/realtek-eio.c | 243 ++++++++++++++++++++++++++++++++++++++ ++ 3 files changed, 255 insertions(+) ++ create mode 100644 drivers/mfd/realtek-eio.c ++ ++Index: linux-5.4.92/drivers/mfd/Kconfig ++=================================================================== ++--- linux-5.4.92.orig/drivers/mfd/Kconfig +++++ linux-5.4.92/drivers/mfd/Kconfig ++@@ -923,6 +923,16 @@ config MFD_RETU ++ Retu and Tahvo are a multi-function devices found on Nokia ++ Internet Tablets (770, N800 and N810). ++ +++config MFD_REALTEK_EIO +++ tristate "Realtek external LED and GPIO driver" +++ select MFD_CORE +++ select MFD_SYSCON +++ select GENERIC_PINCONF +++ default y +++ help +++ Say yes here if you want external LED/GPIO support for Realtek +++ switch SoCs. +++ ++ config MFD_PCF50633 ++ tristate "NXP PCF50633" ++ depends on I2C ++Index: linux-5.4.92/drivers/mfd/realtek-eio.c ++=================================================================== ++--- /dev/null +++++ linux-5.4.92/drivers/mfd/realtek-eio.c ++@@ -0,0 +1,246 @@ +++// SPDX-License-Identifier: GPL-2.0-or-later +++ +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++#include +++ +++#define REALTEK_EIO_GLOBAL_CTRL 0x0 +++ +++/* +++ * Management of external RTL8231 GPIO expanders. +++ * One RTL8231's GPIO registers can be shadowed to the internal GPIO_DIR +++ * and GPIO_DAT registers. +++ */ +++#define RTL8380_EIO_GPIO_INDIRECT_ACCESS 0x9C +++#define RTL8380_EIO_GPIO_CTRL 0xE0 +++#define RTL8380_EIO_GPIO_DIR(pin) (0xE4 + 4*((pin)/32)) +++#define RTL8380_EIO_GPIO_DAT(pin) (0xEC + 4*((pin)/32)) +++ +++struct realtek_eio_ctrl; +++ +++struct realtek_eio_data { +++ unsigned int sys_led_pos; +++ const struct mfd_cell *mfd_devices; +++ unsigned int mfd_device_count; +++}; +++ +++struct realtek_eio_ctrl { +++ struct device *dev; +++ struct regmap *map; +++ const struct realtek_eio_data *data; +++ struct led_classdev sys_led; +++ bool active_low; +++}; +++ +++ +++#define OF_MFD_CELL(_name, _compat) \ +++ { \ +++ .name = (_name), \ +++ .of_compatible = (_compat), \ +++ } +++ +++/* +++ * Realtek hardware system LED +++ * +++ * The switch SoC supports one hardware managed direct LED output +++ * to manage a system LED, with two supported blinking rates. +++ */ +++enum { +++ REALTEK_SYS_LED_OFF = 0, +++ REALTEK_SYS_LED_BLINK_64MS, +++ REALTEK_SYS_LED_BLINK_1024MS, +++ REALTEK_SYS_LED_ON +++}; +++ +++static void realtek_sys_led_set(const struct realtek_eio_ctrl *ctrl, +++ unsigned int mode) +++{ +++ regmap_update_bits(ctrl->map, REALTEK_EIO_GLOBAL_CTRL, +++ (0x3 << ctrl->data->sys_led_pos), +++ ((mode & 0x3) << ctrl->data->sys_led_pos)); +++} +++ +++static void realtek_sys_led_brightness_set(struct led_classdev *led_cdev, +++ enum led_brightness brightness) +++{ +++ struct realtek_eio_ctrl *ctrl = +++ container_of(led_cdev, struct realtek_eio_ctrl, sys_led); +++ +++ if ((!ctrl->active_low && brightness == LED_OFF) || +++ (ctrl->active_low && brightness != LED_OFF)) +++ realtek_sys_led_set(ctrl, REALTEK_SYS_LED_OFF); +++ else +++ realtek_sys_led_set(ctrl, REALTEK_SYS_LED_ON); +++} +++ +++static enum led_brightness realtek_sys_led_brightness_get( +++ struct led_classdev *led_cdev) +++{ +++ struct realtek_eio_ctrl *ctrl = +++ container_of(led_cdev, struct realtek_eio_ctrl, sys_led); +++ u32 val; +++ +++ regmap_read(ctrl->map, REALTEK_EIO_GLOBAL_CTRL, &val); +++ val = (val >> ctrl->data->sys_led_pos) & 0x3; +++ +++ if ((!ctrl->active_low && val == REALTEK_SYS_LED_OFF) || +++ (ctrl->active_low && val == REALTEK_SYS_LED_ON)) +++ return LED_OFF; +++ else +++ return LED_ON; +++} +++ +++static int realtek_sys_led_blink_set(struct led_classdev *led_cdev, +++ unsigned long *delay_on, unsigned long *delay_off) +++{ +++ struct realtek_eio_ctrl *ctrl = +++ container_of(led_cdev, struct realtek_eio_ctrl, sys_led); +++ u32 blink_interval = *delay_on + *delay_off; +++ +++ /* Split range at geometric mean of 64 and 1024 */ +++ if (blink_interval == 0 || blink_interval > 2*256) { +++ *delay_on = 1024; +++ *delay_off = 1024; +++ realtek_sys_led_set(ctrl, REALTEK_SYS_LED_BLINK_1024MS); +++ } +++ else { +++ *delay_on = 64; +++ *delay_off = 64; +++ realtek_sys_led_set(ctrl, REALTEK_SYS_LED_BLINK_64MS); +++ } +++ +++ return 0; +++} +++ +++static int realtek_sys_led_probe(struct realtek_eio_ctrl *ctrl, +++ struct device *parent, struct device_node *np) +++{ +++ struct led_classdev *sys_led = &ctrl->sys_led; +++ struct led_init_data init_data = {}; +++ +++ init_data.fwnode = of_fwnode_handle(np); +++ +++ ctrl->active_low = of_property_read_bool(np, "active-low"); +++ +++ sys_led->max_brightness = 1; +++ sys_led->brightness_set = realtek_sys_led_brightness_set; +++ sys_led->brightness_get = realtek_sys_led_brightness_get; +++ sys_led->blink_set = realtek_sys_led_blink_set; +++ +++ return devm_led_classdev_register_ext(parent, sys_led, &init_data); +++} +++ +++static const struct mfd_cell rtl8380_mfd_devices[] = { +++ OF_MFD_CELL("realtek-eio-port-leds", "realtek,rtl8380-eio-port-led"), +++ OF_MFD_CELL("realtek-eio-mdio", "realtek,rtl8380-eio-mdio"), +++ OF_MFD_CELL("realtek-eio-pinctrl", "realtek,rtl8380-eio-pinctrl"), +++}; +++ +++static const struct realtek_eio_data rtl8380_eio_data = { +++ .sys_led_pos = 16, +++ .mfd_devices = rtl8380_mfd_devices, +++ .mfd_device_count = ARRAY_SIZE(rtl8380_mfd_devices) +++}; +++ +++static const struct mfd_cell rtl8390_mfd_devices[] = { +++ OF_MFD_CELL("realtek-eio-port-leds", "realtek,rtl8390-eio-port-led"), +++}; +++ +++static struct realtek_eio_data rtl8390_eio_data = { +++ .sys_led_pos = 15, +++ .mfd_devices = rtl8390_mfd_devices, +++ .mfd_device_count = ARRAY_SIZE(rtl8390_mfd_devices) +++}; +++ +++static const struct of_device_id of_realtek_eio_match[] = { +++ { +++ .compatible = "realtek,rtl8380-eio", +++ .data = &rtl8380_eio_data, +++ }, +++ { +++ .compatible = "realtek,rtl8390-eio", +++ .data = &rtl8390_eio_data, +++ }, +++}; +++ +++MODULE_DEVICE_TABLE(of, of_realtek_eio_match); +++ +++static int realtek_eio_probe(struct platform_device *pdev) +++{ +++ struct device *dev = &pdev->dev; +++ struct device_node *np = dev->of_node; +++ struct device_node *np_sys_led; +++ const struct of_device_id *match; +++ struct realtek_eio_ctrl *ctrl; +++ int err, val; +++ unsigned r; +++ +++ ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL); +++ if (!ctrl) +++ return -ENOMEM; +++ +++ match = of_match_device(of_realtek_eio_match, dev); +++ if (match) +++ ctrl->data = (struct realtek_eio_data *) match->data; +++ else { +++ dev_err(dev, "no device match\n"); +++ return -EINVAL; +++ } +++ +++ ctrl->dev = dev; +++ +++ if (!np) { +++ dev_err(dev, "no DT node found\n"); +++ return -EINVAL; +++ } +++ +++ ctrl->map = device_node_to_regmap(np); +++ if (!ctrl->map) { +++ dev_err(dev, "failed to get regmap\n"); +++ return -EINVAL; +++ } +++ +++ /* Parse optional sys-led child */ +++ np_sys_led = of_get_child_by_name(np, "sys-led"); +++ if (IS_ERR(np_sys_led)) +++ return PTR_ERR(np_sys_led); +++ +++ if (np_sys_led) { +++ err = realtek_sys_led_probe(ctrl, dev, np_sys_led); +++ if (err) +++ return err; +++ } +++ +++ /* Find sub-devices */ +++ if (ctrl->data->mfd_devices) +++ mfd_add_devices(dev, 0, ctrl->data->mfd_devices, +++ ctrl->data->mfd_device_count, NULL, 0, NULL); +++ +++ /* Dump register values */ +++ for (r = 0; r <= regmap_get_max_register(ctrl->map); r += 4) { +++ regmap_read(ctrl->map, r, &val); +++ dev_info(dev, "%02x %08x\n", r, val); +++ } +++ +++ return 0; +++} +++ +++static struct platform_driver realtek_eio_driver = { +++ .probe = realtek_eio_probe, +++ .driver = { +++ .name = "realtek-ext-io", +++ .of_match_table = of_realtek_eio_match +++ } +++}; +++ +++module_platform_driver(realtek_eio_driver); +++ +++MODULE_AUTHOR("Sander Vanheule "); +++MODULE_DESCRIPTION("Realtek switch SoC external LED/GPIO driver"); +++MODULE_LICENSE("GPL v2"); ++Index: linux-5.4.92/drivers/mfd/Makefile ++=================================================================== ++--- linux-5.4.92.orig/drivers/mfd/Makefile +++++ linux-5.4.92/drivers/mfd/Makefile ++@@ -255,4 +255,4 @@ obj-$(CONFIG_RAVE_SP_CORE) += rave-sp.o ++ obj-$(CONFIG_MFD_ROHM_BD70528) += rohm-bd70528.o ++ obj-$(CONFIG_MFD_ROHM_BD718XX) += rohm-bd718x7.o ++ obj-$(CONFIG_MFD_STMFX) += stmfx.o ++- +++obj-$(CONFIG_MFD_REALTEK_EIO) += realtek-eio.o +diff --git a/target/linux/realtek/patches-5.4/707-reboot.patch b/target/linux/realtek/patches-5.4/707-reboot.patch +new file mode 100644 +index 0000000000..420b91d809 +--- /dev/null ++++ b/target/linux/realtek/patches-5.4/707-reboot.patch +@@ -0,0 +1,9 @@ ++Index: linux-5.4.92/drivers/gpio/Makefile ++=================================================================== ++--- linux-5.4.92.orig/drivers/gpio/Makefile +++++ linux-5.4.92/drivers/gpio/Makefile ++@@ -171,3 +171,4 @@ obj-$(CONFIG_GPIO_XTENSA) += gpio-xtens ++ obj-$(CONFIG_GPIO_ZEVIO) += gpio-zevio.o ++ obj-$(CONFIG_GPIO_ZX) += gpio-zx.o ++ obj-$(CONFIG_GPIO_ZYNQ) += gpio-zynq.o +++obj-y += edgecore_reboot.o +diff --git a/target/linux/realtek/patches-5.4/708-poor-stp.patch b/target/linux/realtek/patches-5.4/708-poor-stp.patch +new file mode 100644 +index 0000000000..1980914961 +--- /dev/null ++++ b/target/linux/realtek/patches-5.4/708-poor-stp.patch +@@ -0,0 +1,16 @@ ++Index: linux-5.4.102/net/bridge/br_fdb.c ++=================================================================== ++--- linux-5.4.102.orig/net/bridge/br_fdb.c +++++ linux-5.4.102/net/bridge/br_fdb.c ++@@ -573,9 +573,9 @@ void br_fdb_update(struct net_bridge *br ++ if (likely(fdb)) { ++ /* attempt to update an entry for a local interface */ ++ if (unlikely(fdb->is_local)) { ++- if (net_ratelimit()) ++- br_warn(br, "received packet on %s with own address as source address (addr:%pM, vlan:%u)\n", +++ br_warn(br, "received packet on %s with own address as source address (addr:%pM, vlan:%u) shutting port down\n", ++ source->dev->name, addr, vid); +++ br_set_state(source, BR_STATE_BLOCKING); ++ } else { ++ unsigned long now = jiffies; ++ +diff --git a/target/linux/realtek/patches-5.4/710-adt7470.patch b/target/linux/realtek/patches-5.4/710-adt7470.patch +new file mode 100644 +index 0000000000..b76b0b33cf +--- /dev/null ++++ b/target/linux/realtek/patches-5.4/710-adt7470.patch +@@ -0,0 +1,22 @@ ++Index: linux-5.4.92/drivers/hwmon/adt7470.c ++=================================================================== ++--- linux-5.4.92.orig/drivers/hwmon/adt7470.c +++++ linux-5.4.92/drivers/hwmon/adt7470.c ++@@ -1271,10 +1271,17 @@ static const struct i2c_device_id adt747 ++ }; ++ MODULE_DEVICE_TABLE(i2c, adt7470_id); ++ +++static const struct of_device_id __maybe_unused adt7470_of_match = +++{ +++ .compatible = "adi,adt7470", +++}; +++MODULE_DEVICE_TABLE(of, adt7470_of_match); +++ ++ static struct i2c_driver adt7470_driver = { ++ .class = I2C_CLASS_HWMON, ++ .driver = { ++ .name = "adt7470", +++ .of_match_table = of_match_ptr(&adt7470_of_match), ++ }, ++ .probe = adt7470_probe, ++ .remove = adt7470_remove, +-- +2.25.1 + diff --git a/build.sh b/build.sh new file mode 100755 index 000000000..2609393c0 --- /dev/null +++ b/build.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +set -ex +ROOT_PATH=${PWD} +BUILD_DIR=${ROOT_PATH}/openwrt +TARGET=${1} + +if [ -z "$1" ]; then + echo "Error: please specify TARGET" + echo "One of: WF194C, ZYXEL_GS1900-10HP" + exit 1 +fi + +if [ ! "$(ls -A $BUILD_DIR)" ]; then + python3 setup.py --setup || exit 1 + +else + python3 setup.py --rebase + echo "### OpenWrt repo already setup" +fi + +case "${TARGET}" in +WF194C) + TARGET=wf194c + ;; +ZYXEL_GS1900-10HP) + TARGET=zyxel_gs1900-10hp + ;; +*) + echo "${TARGET} is unknown" + exit 1 + ;; +esac +cd ${BUILD_DIR} +./scripts/gen_config.py ${TARGET} ucentral-ap || exit 1 +cd - + +echo "### Building image ..." +cd $BUILD_DIR +make -j$(nproc) V=s 2>&1 | tee build.log +echo "Done" diff --git a/config.yml b/config.yml new file mode 100644 index 000000000..816a87ef2 --- /dev/null +++ b/config.yml @@ -0,0 +1,8 @@ +repo: https://github.com/openwrt/openwrt.git +branch: openwrt-21.02 +revision: fdc0342704b692c46ccb65c6372a853ff89094c4 +output_dir: ./output + +patch_folders: + - backports/ + - patches/ diff --git a/dock-run.sh b/dock-run.sh new file mode 100755 index 000000000..94cffd136 --- /dev/null +++ b/dock-run.sh @@ -0,0 +1,9 @@ +#!/bin/bash -ex + +tag=$(echo ${PWD} | tr / - | cut -b2- | tr A-Z a-z) +groups=$(id -G | xargs -n1 echo -n " --group-add ") +params="-v ${PWD}:${PWD} --rm -w ${PWD} -u"$(id -u):$(id -g)" $groups -v/etc/passwd:/etc/passwd:ro -v/etc/group:/etc/group:ro -v$HOME/.gitconfig:$HOME/.gitconfig:ro ${tag}" + +docker build --tag=${tag} docker + +docker run $params $@ diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 000000000..aeca8e89f --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,12 @@ +FROM ubuntu:20.04 + +RUN apt-get update \ + && DEBIAN_FRONTEND="noninteractive" apt-get -y install tzdata \ + && apt-get install -y \ + time git-core build-essential gcc-multilib \ + libncurses5-dev zlib1g-dev gawk flex gettext wget unzip python \ + python3 python3-pip python3-yaml openvswitch-common openvswitch-switch libssl-dev rsync \ + && apt-get clean +RUN git config --global user.email "you@example.com" +RUN git config --global user.name "Your Name" +RUN pip3 install kconfiglib diff --git a/feeds/bluetooth/bluetooth-6lowpand/Makefile b/feeds/bluetooth/bluetooth-6lowpand/Makefile new file mode 100644 index 000000000..646fc3e8e --- /dev/null +++ b/feeds/bluetooth/bluetooth-6lowpand/Makefile @@ -0,0 +1,53 @@ +# +# Copyright (C) 2016 Nordic Semiconductor ASA. +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=bluetooth-6lowpand +PKG_VERSION:=0.0.1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE_URL:=https://github.com/NordicSemiconductor/Linux-ble-6lowpan-joiner.git +PKG_SOURCE_VERSION:=5ce5b248846a6d4ac4a609eb0e8d023cf920b247 +PKG_SOURCE_PROTO:=git + +BLUEZ_DIR:=$(wildcard $(BUILD_DIR)/bluez-*) + +TARGET_CFLAGS += -I$(BLUEZ_DIR) +TARGET_LDFLAGS += -L$(BLUEZ_DIR)/lib/.libs/ -L$(BLUEZ_DIR)/src/.libs/ -lshared-mainloop -lbluetooth-internal + +include $(INCLUDE_DIR)/package.mk + +define Package/bluetooth-6lowpand + SECTION:=base + CATEGORY:=Network + TITLE:=Bluetooth LE 6lowpan joiner daemon + URL:=http://www.nordicsemi.com/ + DEPENDS:=+libusb-1.0 +bluez-libs +endef + +define Package/bluetooth-6lowpand/description + Bluetooth Low Energy IPSP device scanner and connection daemon. + The Daemon can be used to whitelist certain IPSP Bluetooth LE MAC + addresses, or autoconnect using SSID and Key derived from Wifi AP + setup to authenticate the devices in order to connect. Also, manual + configuration of software SSID and Key can be used. +endef + +define Package/bluetooth-6lowpand/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/bluetooth_6lowpand.init $(1)/etc/init.d/bluetooth_6lowpand + + $(INSTALL_DIR) $(1)/etc/bluetooth + $(INSTALL_DATA) ./files/bluetooth_6lowpand.conf $(1)/etc/bluetooth + + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/bluetooth_6lowpand $(1)/usr/sbin +endef + +$(eval $(call BuildPackage,bluetooth-6lowpand)) diff --git a/feeds/bluetooth/bluetooth-6lowpand/files/bluetooth_6lowpand.conf b/feeds/bluetooth/bluetooth-6lowpand/files/bluetooth_6lowpand.conf new file mode 100644 index 000000000..e69de29bb diff --git a/feeds/bluetooth/bluetooth-6lowpand/files/bluetooth_6lowpand.init b/feeds/bluetooth/bluetooth-6lowpand/files/bluetooth_6lowpand.init new file mode 100644 index 000000000..7bfd0d428 --- /dev/null +++ b/feeds/bluetooth/bluetooth-6lowpand/files/bluetooth_6lowpand.init @@ -0,0 +1,24 @@ +#!/bin/sh /etc/rc.common + +START=63 +PROG=/usr/sbin/bluetooth_6lowpand +HCICONFIG=/usr/bin/hciconfig + +start() { + config_load btle + config_get enable bluetooth_6lowpand enable 0 + [ "$enable" -eq 1 ] || return + echo "start bluetooth_6lowpand" + sleep 1 + echo 1 > /sys/kernel/debug/bluetooth/6lowpan_enable + sleep 1 + killall bluetoothd + sleep 1 + $HCICONFIG hci0 reset + $PROG -w 3 -t 5 -a -d +} + +stop() { + echo "stop bluetooth_6lowpand" + killall -9 bluetooth_6lowpand +} diff --git a/feeds/bluetooth/bluez-ibeacon/Makefile b/feeds/bluetooth/bluez-ibeacon/Makefile new file mode 100644 index 000000000..bb66bb9c3 --- /dev/null +++ b/feeds/bluetooth/bluez-ibeacon/Makefile @@ -0,0 +1,33 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=bluez-ibeacon +PKG_RELEASE:=1 + +PKG_SOURCE_URL=https://github.com/blogic/bluez-ibeacon +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2022-10-31 +PKG_SOURCE_VERSION:=07c082bf3e139ce061ff62a42b7876860256f4ea + +PKG_MAINTAINER:=John Crispin +PKG_LICENSE:=MIT + +include $(INCLUDE_DIR)/package.mk + +define Package/bluez-ibeacon + SECTION:=utils + CATEGORY:=Utilities + TITLE:=bluez-ibeacon + DEPENDS:=+bluez-libs +endef + +define Build/Compile + $(MAKE_VARS) $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/bluez-beacon $(MAKE_FLAGS) +endef + +define Package/bluez-ibeacon/install + $(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/init.d + $(INSTALL_BIN) $(PKG_BUILD_DIR)/bluez-beacon/ibeacon $(1)/usr/sbin/ + $(INSTALL_BIN) ./files/ibeacon $(1)/etc/init.d/ibeacon +endef + +$(eval $(call BuildPackage,bluez-ibeacon)) diff --git a/feeds/bluetooth/bluez-ibeacon/files/ibeacon b/feeds/bluetooth/bluez-ibeacon/files/ibeacon new file mode 100644 index 000000000..7d309ce43 --- /dev/null +++ b/feeds/bluetooth/bluez-ibeacon/files/ibeacon @@ -0,0 +1,25 @@ +#!/bin/sh /etc/rc.common + +START=80 + +USE_PROCD=1 +PROG=/usr/sbin/ibeacon + +service_triggers() { + procd_add_reload_trigger btle +} + +start_service() { + config_load btle + config_get enable ibeacon enable 0 + config_get uuid ibeacon uuid 0 + config_get major ibeacon major 0 + config_get minor ibeacon minor 0 + + [ "$enable" -eq 1 ] || return + + procd_open_instance + procd_set_param command "$PROG" 200 "${uuid}" "${major}" "${minor}" -29 + procd_set_param respawn + procd_close_instance +} diff --git a/feeds/bluetooth/ubtled/Makefile b/feeds/bluetooth/ubtled/Makefile new file mode 100644 index 000000000..8864aaabe --- /dev/null +++ b/feeds/bluetooth/ubtled/Makefile @@ -0,0 +1,32 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=ubtled +PKG_RELEASE:=1 + +PKG_SOURCE_URL=https://github.com/blogic/ubtled.git +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2022-10-31 +PKG_SOURCE_VERSION:=7e01ab86c562fc8ab3777d04e60b8dce596a4c5f + +PKG_MAINTAINER:=John Crispin +PKG_LICENSE:=GPL-2.0 + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/ubtled + SECTION:=utils + CATEGORY:=Utilities + TITLE:=OpenWrt BTLE daemon + DEPENDS:=+libubox +libubus +bluez-libs +endef + +define Package/ubtled/install + $(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/{config,init.d,uci-defaults} + $(INSTALL_BIN) $(PKG_BUILD_DIR)/ubtled $(1)/usr/sbin/ + $(INSTALL_BIN) ./files/ubtled.init $(1)/etc/init.d/ubtled + $(INSTALL_DATA) ./files/btle.config $(1)/etc/config/btle + $(INSTALL_DATA) ./files/99-btle $(1)/etc/uci-defaults/ +endef + +$(eval $(call BuildPackage,ubtled)) diff --git a/feeds/bluetooth/ubtled/files/99-btle b/feeds/bluetooth/ubtled/files/99-btle new file mode 100644 index 000000000..565020d5c --- /dev/null +++ b/feeds/bluetooth/ubtled/files/99-btle @@ -0,0 +1,8 @@ +#!/bin/sh + +cat >> /etc/bluetooth/main.conf < + +#include "AQ_User.h" +#include "AQ_ReturnCodes.h" + +/******************************************************************* + General +*******************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*! This typedef defines the bool datatype which takes the values +true and false.*/ +typedef enum {False = 0, True = 1} AQ_boolean; + + +/*@}*/ + + +/******************************************************************* + Device Identity +*******************************************************************/ + +/*! \defgroup deviceIdentity Device Identity +All AQ_API functions accept a parameter identifying the target PHY that +should be acted upon. */ +/*@{*/ + + +/*! This enumeration is used to describe the different types of + Aquantia PHY.*/ +typedef enum +{ + /*! 1/2/4-port package, 40nm architechture.*/ + AQ_DEVICE_APPIA, + /*! 1/2/4-port package, 28nm architechture.*/ + AQ_DEVICE_HHD +} AQ_API_Device; + +/*! This structure is used to specify a particular Aquantia PHY port + within the system.*/ +typedef struct +{ + /*! The type of Aquantia PHY*/ + AQ_API_Device device; + /*! Uniquely identifies the port within the system. AQ_Port must be + defined to whatever data type is suitable for the platform. + AQ_API functions will never do anything with PHY_ID other than + pass it down to the platform's PHY register read/write + functions.*/ + AQ_Port PHY_ID; +} AQ_API_Port; + +/*@}*/ + + +/*! This function boot-loads the instruction and data memory (IRAM and + DRAM) of a set of Aquantia PHYs from a .cld format image file (the + same image file used to burn the FLASH). During boot-load of each + Aquantia PHY, the processor is halted, and after programming is + complete the processor is released. Note that calling this + function leaves the daisy-chain disabled to prevent RAM over- + write. To exit MDIO boot-load mode, use the function + AQ_API_EnableDaisyChain. + Unlike most of the other functions in this API, this function can + operate on a group of PHYs simultaneously. This is referred to as + gang-loading. To facilitate this, this function takes as + parameters 3 parallel arrays: PHY_IDs, provisioningAddresses, and + resultCodes. The length of these arrays must be identical, and is + specified by the num_PHY_IDs parameter. + In order to check the integrity of the boot-load operation, a + CRC-16 value is calculated over the IRAM and DRAM. After the image + has been loaded, this value is directly compared against each + PHY's Mailbox CRC-16 in 1E.0201. + The value of register 1E.C441 must be the same for all the boot- + loaded PHYs. This will be checked before the boot-load is + performed, and if a non-uniform value is read from any of the + PHYs, the function will fail before any writes are performed. + A separate result code is returned for each of the boot-loaded + PHYs, in the OUT parameter, resultCodes. + Individual Port Return codes: + AQ_RET_BOOTLOAD_PROVADDR_OOR: The specified provisioning address + was outside of the permitted range. + AQ_RET_BOOTLOAD_NONUNIFORM_REGVALS: The values of the register(s) + that must be uniform across the ports being bootloaded were not + uniform. + AQ_RET_BOOTLOAD_CRC_MISMATCH: The image was completely loaded into + memory, but the after the port exited bootload the running + checksum that was read from the uP memory mailbox was not the + expected value. This indicates that the memory has potentially + been corrupted, and the PHY should be reset before trying the + bootload again. + Overall Return codes (the return value from the function call): + AQ_RET_OK: all ports were successfully bootloaded. + AQ_RET_ERROR: One or more ports were not successfully bootloaded. + */ +AQ_Retcode AQ_API_WriteBootLoadImage +( + /*! An array identifying the target PHY ports.*/ + AQ_API_Port** ports, + /*! The length of the arrays ports, provisioningAddresses, and + resultCodes. These are parallel arrays, and must all be of the + same length.*/ + unsigned int numPorts, + /*! The provisioning addresses of each of the PHYs specified in + ports. This can range from 0 through 47, and is also known as + the daisy-chain address or the hop-count. If the PHYs are + connected to a FLASH using the daisy-chain, this is the distance + from the PHY to the FLASH, and is used to identify customized + provisioning for each PHY from the provisioning data within the + image. Otherwise, it is an arbitrary number. The length of this + array must match the length of ports.*/ + unsigned int* provisioningAddresses, + /*! OUT: The result code indicating success or failure of boot- + loading each of the PHYs specified in ports.*/ + AQ_Retcode* resultCodes, + /*! A pointer to the size of the image (in bytes) that is being + loaded into the Aquantia PHY.*/ + uint32_t* imageSizePointer, + /*! The image being loaded into the Aquantia PHY. This is the same + regardless of whether the target is internal RAM or FLASH.*/ + uint8_t* image, + /*! The 5-bit address to be used during the gang-loading operation. + During the boot-loading process, each of the PHYs specified in + ports will be changed such that they are addressed on the MDIO + bus at gangloadAddress. This allows all the PHYs to be loaded + simultaneously. Before returning, each PHY will be moved back to + its original MDIO address. If ports contains only a single + element, callers will probably want to use the PHY's original + MDIO address for this parameter.*/ + uint8_t gangload_MDIO_address, + /*! The address of the PHYs while in gangload mode. This is + ultimately some combination of the system address and the + gangload MDIO address, specified by gangload_MDIO_address. For + most platforms, gangload_MDIO_address and gangload_PHY_ID should + have the same value.*/ + AQ_API_Port* gangloadPort +); + +/*! This function boot-loads the instruction and data memory (IRAM and + DRAM) of a set of Aquantia PHYs from a .cld format image file (the + same image file used to burn the FLASH), as well as a separately + provided provisioning table image file.The provisioning table + image allows additional provisioning to be provided, beyond what + is built in to the .cld image. If provTableSizePointer or + provTableImage are NULL, this function behaves like + AQ_API_WriteBootLoadImage. + Aside from the additional provisioing table, this function behaves + exactly the same as AQ_API_WriteBootLoadImage. For additional + documentation and information on return codes, refer to + AQ_API_WriteBootLoadImage. + Individual Port Return codes (same as AQ_API_WriteBootLoadImage, + plus): + AQ_RET_BOOTLOAD_PROVTABLE_TOO_LARGE: The supplied provisioning + table image does not fit within the alloted space.*/ +AQ_Retcode AQ_API_WriteBootLoadImageWithProvTable +( + /*! An array identifying the target PHY ports.*/ + AQ_API_Port** ports, + /*! The length of the arrays ports, provisioningAddresses, and + resultCodes. These are parallel arrays, and must all be of the + same length.*/ + unsigned int numPorts, + /*! The provisioning addresses of each of the PHYs specified in + ports. This can range from 0 through 47, and is also known as + the daisy-chain address or the hop-count. If the PHYs are + connected to a FLASH using the daisy-chain, this is the distance + from the PHY to the FLASH, and is used to identify customized + provisioning for each PHY from the provisioning data within the + image. Otherwise, it is an arbitrary number. The length of this + array must match the length of ports.*/ + unsigned int* provisioningAddresses, + /*! OUT: The result code indicating success or failure of boot- + loading each of the PHYs specified in ports.*/ + AQ_Retcode* resultCodes, + /*! A pointer to the size of the image (in bytes) that is being + loaded into the Aquantia PHY.*/ + uint32_t* imageSizePointer, + /*! The image being loaded into the Aquantia PHY. This is the same + regardless of whether the target is internal RAM or FLASH.*/ + uint8_t* image, + /*! The 5-bit address to be used during the gang-loading operation. + During the boot-loading process, each of the PHYs specified in + ports will be changed such that they are addressed on the MDIO + bus at gangloadAddress. This allows all the PHYs to be loaded + simultaneously. Before returning, each PHY will be moved back to + its original MDIO address. If ports contains only a single + element, callers will probably want to use the PHY's original + MDIO address for this parameter.*/ + uint8_t gangload_MDIO_address, + /*! The address of the PHYs while in gangload mode. This is + ultimately some combination of the system address and the + gangload MDIO address, specified by gangload_MDIO_address. For + most platforms, gangload_MDIO_address and gangload_PHY_ID should + have the same value.*/ + AQ_API_Port* gangloadPort, + /*! A pointer to the size of the provTableImage (in bytes) that is + being loaded into the Aquantia PHY.*/ + uint32_t* provTableSizePointer, + /*! The additional provisioning table image being loaded into the + Aquantia PHY.*/ + uint8_t* provTableImage +); + +/*! Calling this function disables boot-loading and enables the daisy- + chain. This would typically be called after using MDIO boot- + loading on a daisy-chain enabled PHY. Re-enabling the daisy-chain + after performing an MDIO bootload will cause the PHY to reboot + from FLASH.*/ +AQ_Retcode AQ_API_EnableDaisyChain +( + /*! The target PHY port.*/ + AQ_API_Port* port +); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/feeds/ipq807x/aq-fw-download/src/include/AQ_PhyInterface.h b/feeds/ipq807x/aq-fw-download/src/include/AQ_PhyInterface.h new file mode 100755 index 000000000..66eb817be --- /dev/null +++ b/feeds/ipq807x/aq-fw-download/src/include/AQ_PhyInterface.h @@ -0,0 +1,171 @@ +/* AQ_PhyInterface.h */ + +/*********************************************************************** +* Copyright (c) 2015, Aquantia +* +* Permission to use, copy, modify, and/or distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +* +* Description: +* +* Declares the base PHY register read and write functions that are +* called by the API functions. The platform integrator must provide +* the implementation of these routines. +* +***********************************************************************/ + + +/*! \file + * Declares the base PHY register read and write functions that are + * called by the API functions. The platform integrator must provide + * the implementation of these routines. */ + + +#ifndef AQ_PHY_INTERFACE_TOKEN +#define AQ_PHY_INTERFACE_TOKEN + + +#include "AQ_API.h" +#include "AQ_User.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/******************************************************************* + MDIO Access Functions +*******************************************************************/ + +/*! \defgroup mdioAccessFunctions MDIO Access Functions +The MDIO access functions are required by the API to access the register space +of each Aquantia PHY deployed in a system. The body of these functions needs to +be written by the system designer, as the method of accessing the PHY will +be unique to the target system. They are designed to be generic read and +write access functions, as the MDIO addressing scheme relies on each +MMD to maintain a 16 bit address pointer that determines the register where +the next read or write is coming from. Consequently, various levels of +optimization of the MDIO interface are possible: from re-writing the MMD +address pointer on every transaction, to storing shadow copies of the MMD +address pointers and only updating the MMD address pointer as necessary. +Thus these functions leave the MDIO optimization to the system engineer. + */ +/*@{*/ + + +/*! Provides generic synchronous PHY register write functionality. It is the + * responsibility of the system designer to provide the specific MDIO address + * pointer updates, etc. in order to accomplish this write operation. + * It will be assumed that the write has been completed by the time this + * function returns.*/ +void AQ_API_MDIO_Write +( + /*! Uniquely identifies the port within the system. AQ_Port must be + * defined to a whatever data type is suitable for the platform.*/ + AQ_Port PHY_ID, + /*! The address of the MMD within the target PHY. */ + unsigned int MMD, + /*! The 16-bit address of the PHY register being written. */ + unsigned int address, + /*! The 16-bits of data to write to the specified PHY register. */ + unsigned int data +); + +/*! Provides generic synchronous PHY register read functionality. It is the + * responsibility of the system designer to provide the specific MDIO address + * pointer updates, etc. in order to accomplish this read operation.*/ +unsigned int AQ_API_MDIO_Read +( + /*! Uniquely identifies the port within the system. AQ_Port must be + * defined to a whatever data type is suitable for the platform.*/ + AQ_Port PHY_ID, + /*! The address of the MMD within the target PHY. */ + unsigned int MMD, + /*! The 16-bit address of the PHY register being read. */ + unsigned int address +); + +#ifdef AQ_PHY_SUPPORTS_BLOCK_READ_WRITE + +/*! Provides generic asynchronous/buffered PHY register write functionality. + * It is the responsibility of the system designer to provide the specific + * MDIO address pointer updates, etc. in order to accomplish this write + * operation. The write need not necessarily have been completed by the time + * this function returns. All register reads and writes to a particular PHY_ID + * that are requested by calling AQ_API_MDIO_BlockWrite or AQ_API_MDIO_BlockRead + * MUST be performed in the order that the calls are made. */ +void AQ_API_MDIO_BlockWrite +( + /*! Uniquely identifies the port within the system. AQ_Port must be + * defined to a whatever data type is suitable for the platform.*/ + AQ_Port PHY_ID, + /*! The address of the MMD within the target PHY. */ + unsigned int MMD, + /*! The 16-bit address of the PHY register being written. */ + unsigned int address, + /*! The 16-bits of data to write to the specified PHY register. */ + unsigned int data +); + +/*! Provides generic asynchronous/buffered PHY register read functionality. + * It is the responsibility of the system designer to provide the specific + * MDIO address pointer updates, etc. in order to accomplish this read + * operation. All register reads and writes to a particular PHY_ID that + * are requested by calling AQ_API_MDIO_BlockWrite or AQ_API_MDIO_BlockRead + * MUST be performed in the order that the calls are made. The register value + * may subsequently be fetched by calling AQ_API_MDIO_BlockOperationExecute.*/ +void AQ_API_MDIO_BlockRead +( + /*! Uniquely identifies the port within the system. AQ_Port must be + * defined to a whatever data type is suitable for the platform.*/ + AQ_Port PHY_ID, + /*! The address of the MMD within the target PHY. */ + unsigned int MMD, + /*! The 16-bit address of the PHY register being read. */ + unsigned int address +); + +/* Retrieve the results of all PHY register reads to PHY_ID previously + * requested via calls to AQ_API_MDIO_BlockRead. The read and write + * operations previously performed by calls to AQ_API_MDIO_BlockRead and + * AQ_API_MDIO_BlockRead must have all been completed by the time this + * function returns, in the order that the calls were performed. The + * return value is an array representing the fetched results of all + * pending calls to AQ_API_MDIO_BlockRead, in the order that the calls + * were performed. Callers should track the number of pending block + * reads to determine the size of the returned array. */ +unsigned int * AQ_API_MDIO_BlockOperationExecute +( + /*! Uniquely identifies the port within the system. AQ_Port must be + * defined to a whatever data type is suitable for the platform.*/ + AQ_Port PHY_ID +); + +/* Returns the maximum number of asynchronous/buffered PHY register + * read/write operations. Callers will call AQ_API_MDIO_BlockOperationExecute + * before issuing additional calls to AQ_API_MDIO_BlockWrite or + * AQ_API_MDIO_BlockRead to avoid a buffer overflow. */ +unsigned int AQ_API_MDIO_MaxBlockOperations +( +); + +#endif + +/*@}*/ + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/feeds/ipq807x/aq-fw-download/src/include/AQ_PlatformRoutines.h b/feeds/ipq807x/aq-fw-download/src/include/AQ_PlatformRoutines.h new file mode 100755 index 000000000..9a16d6408 --- /dev/null +++ b/feeds/ipq807x/aq-fw-download/src/include/AQ_PlatformRoutines.h @@ -0,0 +1,71 @@ +/*AQ_PlatformRoutines.h*/ + +/************************************************************************************ +* Copyright (c) 2015, Aquantia +* +* Permission to use, copy, modify, and/or distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +* +* Description: +* +* Declares the platform interface functions that will be called by AQ_API +* functions. The platform integrator must provide the implementation of +* these functions. +* +************************************************************************************/ + +/*! \file + * Declares the platform interface functions that will be called by AQ_API + * functions. The platform integrator must provide the implementation of + * these functions. */ + + +#ifndef AQ_PHY_PLATFORMROUTINES_TOKEN +#define AQ_PHY_PLATFORMROUTINES_TOKEN + +#include + +#include "AQ_API.h" +#include "AQ_User.h" +#include "AQ_ReturnCodes.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/******************************************************************* + Time Delay +*******************************************************************/ + +/*! \defgroup delay Time Delay + @{ +*/ + +/*! Returns after at least milliseconds have elapsed. This must be implemented + * in a platform-approriate way. AQ_API functions will call this function to + * block for the specified period of time. If necessary, PHY register reads + * may be performed on port to busy-wait. */ +void AQ_API_Wait +( + uint32_t milliseconds, /*!< The delay in milliseconds */ + AQ_API_Port* port /*!< The PHY to use if delay reads are necessary*/ +); + +/*@}*/ + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/feeds/ipq807x/aq-fw-download/src/include/AQ_RegMacro.h b/feeds/ipq807x/aq-fw-download/src/include/AQ_RegMacro.h new file mode 100755 index 000000000..8dcca522b --- /dev/null +++ b/feeds/ipq807x/aq-fw-download/src/include/AQ_RegMacro.h @@ -0,0 +1,323 @@ +/* Copyright (c) 2015, Aquantia +* +* Permission to use, copy, modify, and/or distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +/*! \file + This file contains macros for accessing the AQ PHYs' registers + using the device-specific register map data structures and definitions. +*/ + +#ifndef AQ_REG_MACRO_TOKEN +#define AQ_REG_MACRO_TOKEN + +#include "AQ_PhyInterface.h" + + +#define AQ_API_ReadRegister(id,reg,wd) AQ_API_ReadRegister_DeviceRestricted(APPIA_HHD,id,reg,wd) + +#define AQ_API_ReadRegister_DeviceRestricted(devices,id,reg,wd) AQ_API_ReadRegister_Devs_ ## devices(id,reg,wd) + +#define AQ_API_ReadRegister_Devs_APPIA(id,reg,wd) \ + ((port->device == AQ_DEVICE_APPIA) ? AQ_API_MDIO_Read (id,reg ## _APPIA_mmdAddress,(reg ## _APPIA_baseRegisterAddress + wd)) : \ + (0)) + +#define AQ_API_ReadRegister_Devs_HHD(id,reg,wd) \ + ((port->device == AQ_DEVICE_HHD) ? AQ_API_MDIO_Read (id,reg ## _HHD_mmdAddress,(reg ## _HHD_baseRegisterAddress + wd)) : \ + (0)) + +#define AQ_API_ReadRegister_Devs_APPIA_HHD(id,reg,wd) \ + ((port->device == AQ_DEVICE_HHD) ? AQ_API_MDIO_Read (id,reg ## _HHD_mmdAddress,(reg ## _HHD_baseRegisterAddress + wd)) : \ + ((port->device == AQ_DEVICE_APPIA) ? AQ_API_MDIO_Read (id,reg ## _APPIA_mmdAddress,(reg ## _APPIA_baseRegisterAddress + wd)) : \ + (0))) + +#define AQ_API_ReadRegister_Devs_HHD_APPIA(id,reg,wd) AQ_API_ReadRegister_Devs_APPIA_HHD(id,reg,wd) + + +#define AQ_API_WriteRegister(id,reg,wd,value) AQ_API_WriteRegister_DeviceRestricted(APPIA_HHD,id,reg,wd,value) + +#define AQ_API_WriteRegister_DeviceRestricted(devices,id,reg,wd,value) AQ_API_WriteRegister_Devs_ ## devices(id,reg,wd,value) + +#define AQ_API_WriteRegister_Devs_APPIA(id,reg,wd,value) \ + ((port->device == AQ_DEVICE_APPIA) ? AQ_API_MDIO_Write (id,reg ## _APPIA_mmdAddress,(reg ## _APPIA_baseRegisterAddress + wd),value) : \ + ((void)0)) + +#define AQ_API_WriteRegister_Devs_HHD(id,reg,wd,value) \ + ((port->device == AQ_DEVICE_HHD) ? AQ_API_MDIO_Write (id,reg ## _HHD_mmdAddress,(reg ## _HHD_baseRegisterAddress + wd),value) : \ + ((void)0)) + +#define AQ_API_WriteRegister_Devs_APPIA_HHD(id,reg,wd,value) \ + ((port->device == AQ_DEVICE_HHD) ? AQ_API_MDIO_Write (id,reg ## _HHD_mmdAddress,(reg ## _HHD_baseRegisterAddress + wd),value) : \ + ((port->device == AQ_DEVICE_APPIA) ? AQ_API_MDIO_Write (id,reg ## _APPIA_mmdAddress,(reg ## _APPIA_baseRegisterAddress + wd),value) : \ + ((void)0))) + +#define AQ_API_WriteRegister_Devs_HHD_APPIA(id,reg,wd,value) AQ_API_WriteRegister_Devs_APPIA_HHD(id,reg,wd,value) + + +#ifdef AQ_PHY_SUPPORTS_BLOCK_READ_WRITE + +#define AQ_API_BlockReadRegister(id,reg,wd) AQ_API_BlockReadRegister_DeviceRestricted(APPIA_HHD,id,reg,wd) + +#define AQ_API_BlockReadRegister_DeviceRestricted(devices,id,reg,wd) AQ_API_BlockReadRegister_Devs_ ## devices(id,reg,wd) + +#define AQ_API_BlockReadRegister_Devs_APPIA(id,reg,wd) \ + ((port->device == AQ_DEVICE_APPIA) ? AQ_API_MDIO_BlockRead (id,reg ## _APPIA_mmdAddress,(reg ## _APPIA_baseRegisterAddress + wd)) : \ + ((void)0)) + +#define AQ_API_BlockReadRegister_Devs_HHD(id,reg,wd) \ + ((port->device == AQ_DEVICE_HHD) ? AQ_API_MDIO_BlockRead (id,reg ## _HHD_mmdAddress,(reg ## _HHD_baseRegisterAddress + wd)) : \ + ((void)0)) + +#define AQ_API_BlockReadRegister_Devs_APPIA_HHD(id,reg,wd) \ + ((port->device == AQ_DEVICE_HHD) ? AQ_API_MDIO_BlockRead (id,reg ## _HHD_mmdAddress,(reg ## _HHD_baseRegisterAddress + wd)) : \ + ((port->device == AQ_DEVICE_APPIA) ? AQ_API_MDIO_BlockRead (id,reg ## _APPIA_mmdAddress,(reg ## _APPIA_baseRegisterAddress + wd)) : \ + ((void)0))) + +#define AQ_API_BlockReadRegister_Devs_HHD_APPIA(id,reg,wd) AQ_API_BlockReadRegister_Devs_APPIA_HHD(id,reg,wd) + + +#define AQ_API_BlockWriteRegister(id,reg,wd,value) AQ_API_BlockWriteRegister_DeviceRestricted(APPIA_HHD,id,reg,wd,value) + +#define AQ_API_BlockWriteRegister_DeviceRestricted(devices,id,reg,wd,value) AQ_API_BlockWriteRegister_Devs_ ## devices(id,reg,wd,value) + +#define AQ_API_BlockWriteRegister_Devs_APPIA(id,reg,wd,value) \ + ((port->device == AQ_DEVICE_APPIA) ? AQ_API_MDIO_BlockWrite (id,reg ## _APPIA_mmdAddress,(reg ## _APPIA_baseRegisterAddress + wd),value) : \ + ((void)0)) + +#define AQ_API_BlockWriteRegister_Devs_HHD(id,reg,wd,value) \ + ((port->device == AQ_DEVICE_HHD) ? AQ_API_MDIO_BlockWrite (id,reg ## _HHD_mmdAddress,(reg ## _HHD_baseRegisterAddress + wd),value) : \ + ((void)0)) + +#define AQ_API_BlockWriteRegister_Devs_APPIA_HHD(id,reg,wd,value) \ + ((port->device == AQ_DEVICE_HHD) ? AQ_API_MDIO_BlockWrite (id,reg ## _HHD_mmdAddress,(reg ## _HHD_baseRegisterAddress + wd),value) : \ + ((port->device == AQ_DEVICE_APPIA) ? AQ_API_MDIO_BlockWrite (id,reg ## _APPIA_mmdAddress,(reg ## _APPIA_baseRegisterAddress + wd),value) : \ + ((void)0))) + +#define AQ_API_BlockWriteRegister_Devs_HHD_APPIA(id,reg,wd,value) AQ_API_BlockWriteRegister_Devs_APPIA_HHD(id,reg,wd,value) + + +#endif + +#define AQ_API_Variable(reg) AQ_API_Variable_DeviceRestricted(APPIA_HHD,reg) + +#define AQ_API_Variable_DeviceRestricted(devices,reg) AQ_API_Variable_Devs_ ## devices(reg) + +#define AQ_API_Variable_Devs_APPIA(reg) uint8_t _local ## reg ## _space[ sizeof(reg ## _BiggestVersion) ];\ + reg ## _APPIA* _local ## reg ## _APPIA = (reg ## _APPIA*) _local ## reg ## _space; \ + +#define AQ_API_Variable_Devs_HHD(reg) uint8_t _local ## reg ## _space[ sizeof(reg ## _BiggestVersion) ];\ + reg ## _HHD* _local ## reg ## _HHD = (reg ## _HHD*) _local ## reg ## _space; \ + +#define AQ_API_Variable_Devs_APPIA_HHD(reg) uint8_t _local ## reg ## _space[ sizeof(reg ## _BiggestVersion) ];\ + reg ## _APPIA* _local ## reg ## _APPIA = (reg ## _APPIA*) _local ## reg ## _space; \ + reg ## _HHD* _local ## reg ## _HHD = (reg ## _HHD*) _local ## reg ## _space; \ + +#define AQ_API_Variable_Devs_HHD_APPIA(reg) AQ_API_Variable_Devs_APPIA_HHD(reg) + + +#define AQ_API_DeclareLocalStruct(reg,localvar) AQ_API_DeclareLocalStruct_DeviceRestricted(APPIA_HHD,reg,localvar) + +#define AQ_API_DeclareLocalStruct_DeviceRestricted(devices,reg,localvar) AQ_API_DeclareLocalStruct_Devs_ ## devices(reg,localvar) + +#define AQ_API_DeclareLocalStruct_Devs_APPIA(reg,localvar) uint8_t localvar ## _space[ sizeof(reg ## _BiggestVersion) ];\ + reg ## _APPIA* localvar ## _APPIA = (reg ## _APPIA*) localvar ## _space; \ + +#define AQ_API_DeclareLocalStruct_Devs_HHD(reg,localvar) uint8_t localvar ## _space[ sizeof(reg ## _BiggestVersion) ];\ + reg ## _HHD* localvar ## _HHD = (reg ## _HHD*) localvar ## _space; \ + +#define AQ_API_DeclareLocalStruct_Devs_APPIA_HHD(reg,localvar) uint8_t localvar ## _space[ sizeof(reg ## _BiggestVersion) ];\ + reg ## _APPIA* localvar ## _APPIA = (reg ## _APPIA*) localvar ## _space; \ + reg ## _HHD* localvar ## _HHD = (reg ## _HHD*) localvar ## _space; \ + +#define AQ_API_DeclareLocalStruct_Devs_HHD_APPIA(reg,localvar) AQ_API_DeclareLocalStruct_Devs_APPIA_HHD(reg,localvar) + + +#define AQ_API_Set(id,reg,field,value) AQ_API_Set_DeviceRestricted(APPIA_HHD,id,reg,field,value) + +#define AQ_API_Set_DeviceRestricted(devices,id,reg,field,value) AQ_API_Set_Devs_ ## devices(id,reg,field,value) + +#define AQ_API_Set_Devs_APPIA(id,reg,field,value) { \ + switch (port->device) { \ + case AQ_DEVICE_APPIA: \ + _local ## reg ## _APPIA->word_ ## reg ## _APPIA_ ## field = AQ_API_ReadRegister_Devs_APPIA(id,reg,reg ## _APPIA_ ## field); \ + if (_local ## reg ## _APPIA->bits_ ## reg ## _APPIA_ ## field.field != value) \ + { \ + _local ## reg ## _APPIA->bits_ ## reg ## _APPIA_ ## field.field = value; \ + AQ_API_WriteRegister_Devs_APPIA(id,reg,reg ## _APPIA_ ## field,_local ## reg ## _APPIA->word_ ## reg ## _APPIA_ ## field); \ + } \ + break; \ + default: break; \ + } \ +} + +#define AQ_API_Set_Devs_HHD(id,reg,field,value) { \ + switch (port->device) { \ + case AQ_DEVICE_HHD: \ + _local ## reg ## _HHD->word_ ## reg ## _HHD_ ## field = AQ_API_ReadRegister_Devs_HHD(id,reg,reg ## _HHD_ ## field); \ + if (_local ## reg ## _HHD->bits_ ## reg ## _HHD_ ## field.field != value) \ + { \ + _local ## reg ## _HHD->bits_ ## reg ## _HHD_ ## field.field = value; \ + AQ_API_WriteRegister_Devs_HHD(id,reg,reg ## _HHD_ ## field,_local ## reg ## _HHD->word_ ## reg ## _HHD_ ## field); \ + } \ + break; \ + default: break; \ + } \ +} + +#define AQ_API_Set_Devs_APPIA_HHD(id,reg,field,value) { \ + switch (port->device) { \ + case AQ_DEVICE_APPIA: \ + _local ## reg ## _APPIA->word_ ## reg ## _APPIA_ ## field = AQ_API_ReadRegister_Devs_APPIA_HHD(id,reg,reg ## _APPIA_ ## field); \ + if (_local ## reg ## _APPIA->bits_ ## reg ## _APPIA_ ## field.field != value) \ + { \ + _local ## reg ## _APPIA->bits_ ## reg ## _APPIA_ ## field.field = value; \ + AQ_API_WriteRegister_Devs_APPIA_HHD(id,reg,reg ## _APPIA_ ## field,_local ## reg ## _APPIA->word_ ## reg ## _APPIA_ ## field); \ + } \ + break; \ + case AQ_DEVICE_HHD: \ + _local ## reg ## _HHD->word_ ## reg ## _HHD_ ## field = AQ_API_ReadRegister_Devs_APPIA_HHD(id,reg,reg ## _HHD_ ## field); \ + if (_local ## reg ## _HHD->bits_ ## reg ## _HHD_ ## field.field != value) \ + { \ + _local ## reg ## _HHD->bits_ ## reg ## _HHD_ ## field.field = value; \ + AQ_API_WriteRegister_Devs_APPIA_HHD(id,reg,reg ## _HHD_ ## field,_local ## reg ## _HHD->word_ ## reg ## _HHD_ ## field); \ + } \ + break; \ + default: break; \ + } \ +} + +#define AQ_API_Set_Devs_HHD_APPIA(id,reg,field,value) AQ_API_Set_Devs_APPIA_HHD(id,reg,field,value) + + +#define AQ_API_Get(id,reg,field,value) AQ_API_Get_DeviceRestricted(APPIA_HHD,id,reg,field,value) + +#define AQ_API_Get_DeviceRestricted(devices,id,reg,field,value) AQ_API_Get_Devs_ ## devices(id,reg,field,value) + +#define AQ_API_Get_Devs_APPIA(id,reg,field,value) { \ + switch (port->device) { \ + case AQ_DEVICE_APPIA: \ + _local ## reg ## _APPIA->word_ ## reg ## _APPIA_ ## field = AQ_API_ReadRegister_Devs_APPIA(id,reg,reg ## _APPIA_ ## field); \ + value = _local ## reg ## _APPIA->bits_ ## reg ## _APPIA_ ## field.field; \ + break; \ + default: value = 0; break; \ + } \ +} + +#define AQ_API_Get_Devs_HHD(id,reg,field,value) { \ + switch (port->device) { \ + case AQ_DEVICE_HHD: \ + _local ## reg ## _HHD->word_ ## reg ## _HHD_ ## field = AQ_API_ReadRegister_Devs_HHD(id,reg,reg ## _HHD_ ## field); \ + value = _local ## reg ## _HHD->bits_ ## reg ## _HHD_ ## field.field; \ + break; \ + default: value = 0; break; \ + } \ +} + +#define AQ_API_Get_Devs_APPIA_HHD(id,reg,field,value) { \ + switch (port->device) { \ + case AQ_DEVICE_APPIA: \ + _local ## reg ## _APPIA->word_ ## reg ## _APPIA_ ## field = AQ_API_ReadRegister_Devs_APPIA_HHD(id,reg,reg ## _APPIA_ ## field); \ + value = _local ## reg ## _APPIA->bits_ ## reg ## _APPIA_ ## field.field; \ + break; \ + case AQ_DEVICE_HHD: \ + _local ## reg ## _HHD->word_ ## reg ## _HHD_ ## field = AQ_API_ReadRegister_Devs_APPIA_HHD(id,reg,reg ## _HHD_ ## field); \ + value = _local ## reg ## _HHD->bits_ ## reg ## _HHD_ ## field.field; \ + break; \ + default: value = 0; break; \ + } \ +} + +#define AQ_API_Get_Devs_HHD_APPIA(id,reg,field,value) AQ_API_Get_Devs_APPIA_HHD(id,reg,field,value) + + +#define AQ_API_BitfieldOfLocalStruct(reg,localvar,field) AQ_API_BitfieldOfLocalStruct_DeviceRestricted(APPIA_HHD,reg,localvar,field) + +#define AQ_API_BitfieldOfLocalStruct_DeviceRestricted(devices,reg,localvar,field) AQ_API_BitfieldOfLocalStruct_Devs_ ## devices(reg,localvar,field) + +#define AQ_API_BitfieldOfLocalStruct_Devs_APPIA(reg,localvar,field) \ + ((port->device == AQ_DEVICE_APPIA) ? ((localvar ## _APPIA)->bits_ ## reg ## _APPIA ## _ ## field.field) : \ + (0)) + +#define AQ_API_BitfieldOfLocalStruct_Devs_HHD(reg,localvar,field) \ + ((port->device == AQ_DEVICE_HHD) ? ((localvar ## _HHD)->bits_ ## reg ## _HHD ## _ ## field.field) : \ + (0)) + +#define AQ_API_BitfieldOfLocalStruct_Devs_APPIA_HHD(reg,localvar,field) \ + ((port->device == AQ_DEVICE_HHD) ? ((localvar ## _HHD)->bits_ ## reg ## _HHD ## _ ## field.field) : \ + ((port->device == AQ_DEVICE_APPIA) ? ((localvar ## _APPIA)->bits_ ## reg ## _APPIA ## _ ## field.field) : \ + (0))) + +#define AQ_API_BitfieldOfLocalStruct_Devs_HHD_APPIA(reg,localvar,field) AQ_API_BitfieldOfLocalStruct_Devs_APPIA_HHD(reg,localvar,field) + + +#define AQ_API_AssignBitfieldOfLocalStruct(reg,localvar,field,value) AQ_API_AssignBitfieldOfLocalStruct_DeviceRestricted(APPIA_HHD,reg,localvar,field,value) + +#define AQ_API_AssignBitfieldOfLocalStruct_DeviceRestricted(devices,reg,localvar,field,value) AQ_API_AssignBitfieldOfLocalStruct_Devs_ ## devices(reg,localvar,field,value) + +#define AQ_API_AssignBitfieldOfLocalStruct_Devs_APPIA(reg,localvar,field,value) \ + ((port->device == AQ_DEVICE_APPIA) ? ((localvar ## _APPIA)->bits_ ## reg ## _APPIA ## _ ## field.field = value) : \ + (0)) + +#define AQ_API_AssignBitfieldOfLocalStruct_Devs_HHD(reg,localvar,field,value) \ + ((port->device == AQ_DEVICE_HHD) ? ((localvar ## _HHD)->bits_ ## reg ## _HHD ## _ ## field.field = value) : \ + (0)) + +#define AQ_API_AssignBitfieldOfLocalStruct_Devs_APPIA_HHD(reg,localvar,field,value) \ + ((port->device == AQ_DEVICE_HHD) ? ((localvar ## _HHD)->bits_ ## reg ## _HHD ## _ ## field.field = value) : \ + ((port->device == AQ_DEVICE_APPIA) ? ((localvar ## _APPIA)->bits_ ## reg ## _APPIA ## _ ## field.field = value) : \ + (0))) + +#define AQ_API_AssignBitfieldOfLocalStruct_Devs_HHD_APPIA(reg,localvar,field,value) AQ_API_AssignBitfieldOfLocalStruct_Devs_APPIA_HHD(reg,localvar,field,value) + + +#define AQ_API_WordOfLocalStruct(localvar,wd) AQ_API_WordOfLocalStruct_DeviceRestricted(APPIA_HHD,localvar,wd) + +#define AQ_API_WordOfLocalStruct_DeviceRestricted(devices,localvar,wd) AQ_API_WordOfLocalStruct_Devs_ ## devices(localvar,wd) + +#define AQ_API_WordOfLocalStruct_Devs_APPIA(localvar,wd) \ + ((port->device == AQ_DEVICE_APPIA) ? ((localvar ## _APPIA)->u ## wd.word_ ## wd) : \ + (0)) + +#define AQ_API_WordOfLocalStruct_Devs_HHD(localvar,wd) \ + ((port->device == AQ_DEVICE_HHD) ? ((localvar ## _HHD)->u ## wd.word_ ## wd) : \ + (0)) + +#define AQ_API_WordOfLocalStruct_Devs_APPIA_HHD(localvar,wd) \ + ((port->device == AQ_DEVICE_HHD) ? ((localvar ## _HHD)->u ## wd.word_ ## wd) : \ + ((port->device == AQ_DEVICE_APPIA) ? ((localvar ## _APPIA)->u ## wd.word_ ## wd) : \ + (0))) + +#define AQ_API_WordOfLocalStruct_Devs_HHD_APPIA(localvar,wd) AQ_API_WordOfLocalStruct_Devs_APPIA_HHD(localvar,wd) + + +#define AQ_API_AssignWordOfLocalStruct(localvar,wd,value) AQ_API_AssignWordOfLocalStruct_DeviceRestricted(APPIA_HHD,localvar,wd,value) + +#define AQ_API_AssignWordOfLocalStruct_DeviceRestricted(devices,localvar,wd,value) AQ_API_AssignWordOfLocalStruct_Devs_ ## devices(localvar,wd,value) + +#define AQ_API_AssignWordOfLocalStruct_Devs_APPIA(localvar,wd,value) \ + ((port->device == AQ_DEVICE_APPIA) ? ((localvar ## _APPIA)->u ## wd.word_ ## wd = value) : \ + (0)) + +#define AQ_API_AssignWordOfLocalStruct_Devs_HHD(localvar,wd,value) \ + ((port->device == AQ_DEVICE_HHD) ? ((localvar ## _HHD)->u ## wd.word_ ## wd = value) : \ + (0)) + +#define AQ_API_AssignWordOfLocalStruct_Devs_APPIA_HHD(localvar,wd,value) \ + ((port->device == AQ_DEVICE_HHD) ? ((localvar ## _HHD)->u ## wd.word_ ## wd = value) : \ + ((port->device == AQ_DEVICE_APPIA) ? ((localvar ## _APPIA)->u ## wd.word_ ## wd = value) : \ + (0))) + +#define AQ_API_AssignWordOfLocalStruct_Devs_HHD_APPIA(localvar,wd,value) AQ_API_AssignWordOfLocalStruct_Devs_APPIA_HHD(localvar,wd,value) + + +#endif + diff --git a/feeds/ipq807x/aq-fw-download/src/include/AQ_ReturnCodes.h b/feeds/ipq807x/aq-fw-download/src/include/AQ_ReturnCodes.h new file mode 100755 index 000000000..bff083b03 --- /dev/null +++ b/feeds/ipq807x/aq-fw-download/src/include/AQ_ReturnCodes.h @@ -0,0 +1,113 @@ +/* AQ_ReturnCodes.h */ + +/************************************************************************************ +* Copyright (c) 2015, Aquantia +* +* Permission to use, copy, modify, and/or distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +* +* Description: +* +* This file defines the AQ_API functions' integral return codes. +* +* +************************************************************************************/ + +/*! \file + This file defines the AQ_API functions' integral return codes. +*/ + +#ifndef AQ_RETURNCODES_TOKEN +#define AQ_RETURNCODES_TOKEN + + +/*! \defgroup ReturnCodes + @{ +*/ + +/*! Most AQ_API functions return AQ_Retcode to report success or failure. + * The values used are defined as preprocessor symbols in AQ_ReturnCodes.h. + * Callers should prefer to test the return values by equivalence to these + * symbols, rather than using the integer values directly, as these may + * not be stable across releases. The set of possible return codes that may + * be returned by a particular API function can be found in the function's + * documentation, as well as information on how to interpret each of the + * possible return codes. */ +typedef unsigned int AQ_Retcode; + +/*! \defgroup Success + @{ */ +#define AQ_RET_OK 0 +/*@}*/ + + +/*! \defgroup GeneralErrors + @{ */ +#define AQ_RET_ERROR 100 +#define AQ_RET_UP_BUSY_TIMEOUT 101 +/*@}*/ + +/*! \defgroup FunctionSpecificResults + @{ */ +#define AQ_RET_FLASH_READY 200 +#define AQ_RET_FLASH_READINESS_TIMEOUT 204 + +#define AQ_RET_FLASHINTF_READY 201 +#define AQ_RET_FLASHINTF_NOTREADY 202 +#define AQ_RET_FLASHINTF_READINESS_TIMEOUT 203 + +#define AQ_RET_FLASH_TYPE_UNKNOWN 205 +#define AQ_RET_FLASH_TYPE_BAD 206 + +#define AQ_RET_FLASH_IMAGE_CORRUPT 207 +#define AQ_RET_FLASH_IMAGE_TOO_LARGE 208 +#define AQ_RET_FLASH_IMAGE_MISMATCH 209 + +#define AQ_RET_FLASH_PAGE_SIZE_CHANGED 210 + +#define AQ_RET_BOOTLOAD_PROVADDR_OOR 211 +#define AQ_RET_BOOTLOAD_NONUNIFORM_REGVALS 212 +#define AQ_RET_BOOTLOAD_CRC_MISMATCH 213 +#define AQ_RET_BOOTLOAD_PROVTABLE_TOO_LARGE 228 + +#define AQ_RET_LOOPBACK_BAD_ENTRY_STATE 214 + +#define AQ_RET_DEBUGTRACE_FREEZE_TIMEOUT 215 +#define AQ_RET_DEBUGTRACE_UNFREEZE_TIMEOUT 216 + +#define AQ_RET_CABLEDIAG_ALREADY_RUNNING 217 +#define AQ_RET_CABLEDIAG_STILL_RUNNING 218 +#define AQ_RET_CABLEDIAG_BAD_PAIRSTATUS 219 +#define AQ_RET_CABLEDIAG_RESULTS_ALREDY_COLLECTED 220 +#define AQ_RET_CABLEDIAG_BAD_NUM_SAMPLES 221 +#define AQ_RET_CABLEDIAG_REPORTEDPAIR_MISMATCH 222 +#define AQ_RET_CABLEDIAG_REPORTEDPAIR_OOR 223 +#define AQ_RET_CABLEDIAG_STARTED_PAIR_B 224 +#define AQ_RET_CABLEDIAG_STARTED_PAIR_C 225 +#define AQ_RET_CABLEDIAG_STARTED_PAIR_D 226 +#define AQ_RET_CABLEDIAG_TXENABLE_MISMATCH 227 + +#define AQ_RET_SERDESEYE_BAD_SERDES_MODE 229 +#define AQ_RET_SERDESEYE_BAD_MEAS_COUNT 230 +#define AQ_RET_SERDESEYE_MEAS_TIMEOUT 231 +#define AQ_RET_SERDESEYE_LANE_OOR 232 +#define AQ_RET_SERDESEYE_COORD_OOR 233 + +#define AQ_RET_PIFMAILBOX_ERROR 234 +#define AQ_RET_PIFMAILBOX_TIMEOUT 235 + +#define AQ_RET_SEC_TABLE_INDEX_OOR 236 +/*@}*/ + +/*@}*/ + +#endif diff --git a/feeds/ipq807x/aq-fw-download/src/include/AQ_User.h b/feeds/ipq807x/aq-fw-download/src/include/AQ_User.h new file mode 100755 index 000000000..c7526a7cb --- /dev/null +++ b/feeds/ipq807x/aq-fw-download/src/include/AQ_User.h @@ -0,0 +1,97 @@ +/*AQ_User.h*/ + +/************************************************************************************ +* Copyright (c) 2015, Aquantia +* +* Permission to use, copy, modify, and/or distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +* +* Description: +* +* This file contains preprocessor symbol definitions and type definitions +* for the platform-integrator controlled compile-time AQ_API options. +* +************************************************************************************/ + +/*! \file + This file contains preprocessor symbol definitions and type definitions + for the platform-integrator controlled compile-time AQ_API options. +*/ + +#ifndef AQ_USER_TOKEN +#define AQ_USER_TOKEN + +/*! \defgroup User User Definitions +This module contains the definitions used to configure AQ_API behavior as desired. */ +/*@{*/ + + +/*! Specify the proper data type for AQ_Port. This will depend on the + * platform-specific implementation of the PHY register read/write functions.*/ +typedef unsigned int AQ_Port; + + +/*! If defined, AQ_API functions will print various error and info messages + * to stdout. If not, nothing will be printed and AQ_API.c will NOT include + * stdio.h. */ +#define AQ_VERBOSE + + +/*! If defined, the PHY interface supports block (asynchronous) read/write + * operation. If AQ_PHY_SUPPORTS_BLOCK_READ_WRITE is defined, then + * the API will call the block-operation functions and so implementations + * for each must be provided. If AQ_PHY_SUPPORTS_BLOCK_READ_WRITE is not + * defined, they will not be called, and need not be implemented. */ +#undef AQ_PHY_SUPPORTS_BLOCK_READ_WRITE + + +/*! If defined, time.h exists, and so the associated functions wil be used to + * compute the elapsed time spent in a polling loop, to ensure that the + * maximum time-out period will not be exceeded. If not defined, then + * AQ_MDIO_READS_PER_SECOND will be used to calculate the minimum possible + * elapsed time. */ +#define AQ_TIME_T_EXISTS + + +/*! The maximum number of synchronous PHY register reads that can be performed + * per second. A worst case number can be derived as follows: + * + * AQ_MDIO_READS_PER_SECOND = MDIO Clock Frequency / 64 + * + * If using MDIO preamble suppression, multiply this number by 2 + * + * For instance, if a 5MHz MDIO clock is being used without preamble supression + * AQ_MDIO_READS_PER_SECOND = 78125 + * + * If AQ_TIME_T_EXISTS is defined, this will be ignored and need not be + * defined. If AQ_TIME_T_EXISTS is not defined, this must be defined. */ +#define AQ_MDIO_READS_PER_SECOND 78125 + + +/*! If defined, after writing to one of the registers that can trigger a + * processor-intensive MDIO operation, AQ_API functions will poll the + * the "processor intensive MDIO operation in progress" bit and wait for it + * to be zero before proceeding. */ +#define AQ_ENABLE_UP_BUSY_CHECKS + + +/*! If defined, the register map header files containing reverse-packed + * structs will be included. If not, the register map header files containing + * non-reverse-packed structs will be included. The proper choice is typically + * a function of the endianness of the platform; on big-endian systems the + * reverse-packed structs should be used, and on little-endian systems the + * non-reverse-packed structs should be used. */ +/*#define AQ_REVERSED_BITFIELD_ORDERING*/ + +/*@}*/ +#endif + diff --git a/feeds/ipq807x/aq-fw-download/src/include/registerMap/APPIA/AQ_APPIA_Global_registers.h b/feeds/ipq807x/aq-fw-download/src/include/registerMap/APPIA/AQ_APPIA_Global_registers.h new file mode 100755 index 000000000..a9485f5a4 --- /dev/null +++ b/feeds/ipq807x/aq-fw-download/src/include/registerMap/APPIA/AQ_APPIA_Global_registers.h @@ -0,0 +1,5581 @@ +/*! \file +* This file contains the data structures and doxygen comments +* for the Global Registers block. + */ + +/*! \addtogroup registerMap + @{ +*/ + +/*! \defgroup Global_registers Global Registers +* This module contains the data structures and doxygen comments +* for the Global Registers block. + */ +/*********************************************************************** +* Copyright (c) 2015, Aquantia +* +* Permission to use, copy, modify, and/or distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +* +* $Date: 2014/04/08 $ +* +* $Label: $ +* +* Description: +* +* This file contains the c header structures for the registers contained in the Global Registers block. +* +* The bit fields in this structure are from LSbit to MSbit +* +***********************************************************************/ + + +/*@{*/ +#ifndef AQ_APPIA_GLOBAL_REGS_HEADER +#define AQ_APPIA_GLOBAL_REGS_HEADER + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Control 1: 1E.0000 */ +/* Global Standard Control 1: 1E.0000 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Control 1 */ + union + { + struct + { + unsigned int reserved1 : 11; + /*! \brief 1E.0000.B R/WPD Low Power + AQ_GlobalStandardControl_1_APPIA.u0.bits_0.lowPower + + Provisionable Default = 0x0 + + 1 = Low-power mode + 0 = Normal operation + + + Notes: + A one written to this register causes the chip to enter low-power mode. This bit puts the entire chip in low-power mode, with only the MDIO and microprocessor functioning, and turns off the analog front-end: i.e. places it in high-impedance mode. Setting this bit also sets all of the Low Power bits in the other MMDs. */ + unsigned int lowPower : 1; /* 1E.0000.B R/WPD Provisionable Default = 0x0 */ + /* 1 = Low-power mode + 0 = Normal operation + */ + unsigned int reserved0 : 2; + /*! \brief 1E.0000.E R/WSC Hard Reset + AQ_GlobalStandardControl_1_APPIA.u0.bits_0.hardReset + + Default = 0x0 + + 1 = Global hard reset + 0 = Normal operation + + + Notes: + Setting this bit initiates a global hard reset, equivalent to pulling the reset pin low. This is a level sensitive pin that connects into the power-on reset generation circuitry to initiate a complete power-on reset. */ + unsigned int hardReset : 1; /* 1E.0000.E R/WSC Default = 0x0 */ + /* 1 = Global hard reset + 0 = Normal operation + */ + /*! \brief 1E.0000.F R/WSC Soft Reset + AQ_GlobalStandardControl_1_APPIA.u0.bits_0.softReset + + Default = 0x1 + + 1 = Global soft reset + 0 = Normal operation + + + Notes: + Setting this bit initiates a global soft reset on all of the digital logic, including the microprocessor. Upon completion of the reset sequence, this bit is set back to 0. */ + unsigned int softReset : 1; /* 1E.0000.F R/WSC Default = 0x1 */ + /* 1 = Global soft reset + 0 = Normal operation + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalStandardControl_1_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Device Identifier: 1E.0002 */ +/* Global Standard Device Identifier: 1E.0002 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Device Identifier */ + union + { + struct + { + /*! \brief 1E.0002.F:0 RO Device ID MSW [1F:10] + AQ_GlobalStandardDeviceIdentifier_APPIA.u0.bits_0.deviceIdMSW + + + + Bits 31 - 16 of Device ID + */ + unsigned int deviceIdMSW : 16; /* 1E.0002.F:0 RO */ + /* Bits 31 - 16 of Device ID */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Standard Device Identifier */ + union + { + struct + { + /*! \brief 1E.0003.F:0 RO Device ID LSW [F:0] + AQ_GlobalStandardDeviceIdentifier_APPIA.u1.bits_1.deviceIdLSW + + + + Bits 15 - 0 of Device ID + */ + unsigned int deviceIdLSW : 16; /* 1E.0003.F:0 RO */ + /* Bits 15 - 0 of Device ID */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalStandardDeviceIdentifier_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Devices in Package: 1E.0005 */ +/* Global Standard Devices in Package: 1E.0005 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Devices in Package */ + union + { + struct + { + /*! \brief 1E.0005.0 ROS Clause 22 Registers Present + AQ_GlobalStandardDevicesInPackage_APPIA.u0.bits_0.clause_22RegistersPresent + + Default = 0x0 + + 1 = Clause 22 registers are present in package + 0 = Clause 22 registers are not present in package + + Notes: + This is always set to 0 in the PHY, as there are no Clause 22 registers in the device. */ + unsigned int clause_22RegistersPresent : 1; /* 1E.0005.0 ROS Default = 0x0 */ + /* 1 = Clause 22 registers are present in package + 0 = Clause 22 registers are not present in package */ + /*! \brief 1E.0005.1 ROS PMA Present + AQ_GlobalStandardDevicesInPackage_APPIA.u0.bits_0.pmaPresent + + Default = 0x1 + + 1 = PMA is present in package + 0 = PMA is not present + + Notes: + This is always set to 1 as there is PMA functionality in the PHY. */ + unsigned int pmaPresent : 1; /* 1E.0005.1 ROS Default = 0x1 */ + /* 1 = PMA is present in package + 0 = PMA is not present */ + /*! \brief 1E.0005.2 ROS WIS Present + AQ_GlobalStandardDevicesInPackage_APPIA.u0.bits_0.wisPresent + + Default = 0x0 + + 1 = WIS is present in package + 0 = WIS is not present in package + + Notes: + This is always set to 0, as there is no WIS functionality in the PHY. */ + unsigned int wisPresent : 1; /* 1E.0005.2 ROS Default = 0x0 */ + /* 1 = WIS is present in package + 0 = WIS is not present in package */ + /*! \brief 1E.0005.3 ROS PCS Present + AQ_GlobalStandardDevicesInPackage_APPIA.u0.bits_0.pcsPresent + + Default = 0x1 + + 1 = PCS is present in package + 0 = PCS is not present in package + + Notes: + This is always set to 1 as there is PCS functionality in the PHY. */ + unsigned int pcsPresent : 1; /* 1E.0005.3 ROS Default = 0x1 */ + /* 1 = PCS is present in package + 0 = PCS is not present in package */ + /*! \brief 1E.0005.4 ROS PHY XS Present + AQ_GlobalStandardDevicesInPackage_APPIA.u0.bits_0.phyXS_Present + + Default = 0x1 + + 1 = PHY XS is present in package + 0 = PHY XS is not present in package + + Notes: + This is always set to 1 as there is a PHY XS interface in the PHY. */ + unsigned int phyXS_Present : 1; /* 1E.0005.4 ROS Default = 0x1 */ + /* 1 = PHY XS is present in package + 0 = PHY XS is not present in package */ + /*! \brief 1E.0005.5 ROS DTE XS Present + AQ_GlobalStandardDevicesInPackage_APPIA.u0.bits_0.dteXsPresent + + Default = 0x0 + + 1 = DTE XS is present in package + 0 = DTE XS is not present in package + + + Notes: + This is always set to 0, as there is no DTE XAUI interface in the PHY. */ + unsigned int dteXsPresent : 1; /* 1E.0005.5 ROS Default = 0x0 */ + /* 1 = DTE XS is present in package + 0 = DTE XS is not present in package + */ + /*! \brief 1E.0005.6 ROS TC Present + AQ_GlobalStandardDevicesInPackage_APPIA.u0.bits_0.tcPresent + + Default = 0x0 + + 1 = TC is present in package + 0 = TC is not present in package + + Notes: + This is always set to 0, as there is no TC functionality in the PHY. */ + unsigned int tcPresent : 1; /* 1E.0005.6 ROS Default = 0x0 */ + /* 1 = TC is present in package + 0 = TC is not present in package */ + /*! \brief 1E.0005.7 ROS Autonegotiation Present + AQ_GlobalStandardDevicesInPackage_APPIA.u0.bits_0.autonegotiationPresent + + Default = 0x1 + + 1 = Autonegotiation is present in package + 0 = Autonegotiation is not present in package + + Notes: + This is always set to 1, as there is Autonegotiation in the PHY. */ + unsigned int autonegotiationPresent : 1; /* 1E.0005.7 ROS Default = 0x1 */ + /* 1 = Autonegotiation is present in package + 0 = Autonegotiation is not present in package */ + unsigned int reserved0 : 8; + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalStandardDevicesInPackage_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Vendor Devices in Package: 1E.0006 */ +/* Global Standard Vendor Devices in Package: 1E.0006 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Vendor Devices in Package */ + union + { + struct + { + unsigned int reserved0 : 13; + /*! \brief 1E.0006.D ROS Clause 22 Extension Present + AQ_GlobalStandardVendorDevicesInPackage_APPIA.u0.bits_0.clause_22ExtensionPresent + + Default = 0x1 + + 1 = Clause 22 Extension is present in package + 0 = Clause 22 Extension is not present in package + + Notes: + This is always set to 1 as the PHY utilizes this device for the GbE registers. */ + unsigned int clause_22ExtensionPresent : 1; /* 1E.0006.D ROS Default = 0x1 */ + /* 1 = Clause 22 Extension is present in package + 0 = Clause 22 Extension is not present in package */ + /*! \brief 1E.0006.E ROS Vendor Specific Device #1 Present + AQ_GlobalStandardVendorDevicesInPackage_APPIA.u0.bits_0.vendorSpecificDevice_1Present + + Default = 0x1 + + 1 = Device #1 is present in package + 0 = Device #1 is not present in package + + Notes: + This is always set to 1 as the PHY utilizes this device for the global control registers. */ + unsigned int vendorSpecificDevice_1Present : 1; /* 1E.0006.E ROS Default = 0x1 */ + /* 1 = Device #1 is present in package + 0 = Device #1 is not present in package */ + /*! \brief 1E.0006.F ROS Vendor Specific Device #2 Present + AQ_GlobalStandardVendorDevicesInPackage_APPIA.u0.bits_0.vendorSpecificDevice_2Present + + Default = 0x1 + + 1 = Device #2 is present in package + 0 = Device #2 is not present in package + + Notes: + This is always set to 1 as the PHY utilizes this device for the DSP PMA registers. */ + unsigned int vendorSpecificDevice_2Present : 1; /* 1E.0006.F ROS Default = 0x1 */ + /* 1 = Device #2 is present in package + 0 = Device #2 is not present in package */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalStandardVendorDevicesInPackage_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Status 2: 1E.0008 */ +/* Global Standard Status 2: 1E.0008 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Status 2 */ + union + { + struct + { + unsigned int reserved0 : 14; + /*! \brief 1E.0008.F:E ROS Device Present [1:0] + AQ_GlobalStandardStatus_2_APPIA.u0.bits_0.devicePresent + + Default = 0x2 + + [F:E] + 0x3 = No device at this address + 0x2 = Device present at this address + 0x1 = No device at this address + 0x0 = No device at this address + + Notes: + This field is always set to 0x2, as the Global MMD resides here in the PHY. */ + unsigned int devicePresent : 2; /* 1E.0008.F:E ROS Default = 0x2 */ + /* [F:E] + 0x3 = No device at this address + 0x2 = Device present at this address + 0x1 = No device at this address + 0x0 = No device at this address */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalStandardStatus_2_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Package Identifier: 1E.000E */ +/* Global Standard Package Identifier: 1E.000E */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Package Identifier */ + union + { + struct + { + /*! \brief 1E.000E.F:0 RO Package ID MSW [1F:10] + AQ_GlobalStandardPackageIdentifier_APPIA.u0.bits_0.packageIdMSW + + + + Bits 31- 16 of Package ID + */ + unsigned int packageIdMSW : 16; /* 1E.000E.F:0 RO */ + /* Bits 31- 16 of Package ID */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Standard Package Identifier */ + union + { + struct + { + /*! \brief 1E.000F.F:0 RO Package ID LSW [F:0] + AQ_GlobalStandardPackageIdentifier_APPIA.u1.bits_1.packageIdLSW + + + + Bits 15 - 0 of Package ID + */ + unsigned int packageIdLSW : 16; /* 1E.000F.F:0 RO */ + /* Bits 15 - 0 of Package ID */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalStandardPackageIdentifier_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Firmware ID: 1E.0020 */ +/* Global Firmware ID: 1E.0020 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Firmware ID */ + union + { + struct + { + /*! \brief 1E.0020.7:0 RO Firmware Minor Revision Number [7:0] + AQ_GlobalFirmwareID_APPIA.u0.bits_0.firmwareMinorRevisionNumber + + + + [7:0] = Minor revision number + + Notes: + + + The lower six bits of major and minor firmware revision are exchanged in autonegotiation when the PHYID message is sent. */ + unsigned int firmwareMinorRevisionNumber : 8; /* 1E.0020.7:0 RO */ + /* [7:0] = Minor revision number */ + /*! \brief 1E.0020.F:8 RO Firmware Major Revision Number [7:0] + AQ_GlobalFirmwareID_APPIA.u0.bits_0.firmwareMajorRevisionNumber + + + + [F:8] = Major revision number + + Notes: + + + The lower six bits of major and minor firmware revision are exchanged in autonegotiation when the PHYID message is sent. */ + unsigned int firmwareMajorRevisionNumber : 8; /* 1E.0020.F:8 RO */ + /* [F:8] = Major revision number */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalFirmwareID_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Chip Identification: 1E.0021 */ +/* Global Chip Identification: 1E.0021 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Chip Identification */ + union + { + struct + { + /*! \brief 1E.0021.F:0 RO Chip Identification [F:0] + AQ_GlobalChipIdentification_APPIA.u0.bits_0.chipIdentification + + + + Hardware Chip ID + + Notes: + This value is a hard-coded chip ID */ + unsigned int chipIdentification : 16; /* 1E.0021.F:0 RO */ + /* Hardware Chip ID */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalChipIdentification_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Chip Revision: 1E.0022 */ +/* Global Chip Revision: 1E.0022 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Chip Revision */ + union + { + struct + { + /*! \brief 1E.0022.F:0 RO Chip Revision [F:0] + AQ_GlobalChipRevision_APPIA.u0.bits_0.chipRevision + + + + Hardware Chip Revision + + Notes: + This value is a hard-coded chip revision */ + unsigned int chipRevision : 16; /* 1E.0022.F:0 RO */ + /* Hardware Chip Revision */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalChipRevision_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global NVR Interface: 1E.0100 */ +/* Global NVR Interface: 1E.0100 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global NVR Interface */ + union + { + struct + { + /*! \brief 1E.0100.7:0 R/W NVR Opcode [7:0] + AQ_GlobalNvrInterface_APPIA.u0.bits_0.nvrOpcode + + Default = 0x03 + + NVR instruction opcode + + */ + unsigned int nvrOpcode : 8; /* 1E.0100.7:0 R/W Default = 0x03 */ + /* NVR instruction opcode + */ + /*! \brief 1E.0100.8 RO NVR Busy + AQ_GlobalNvrInterface_APPIA.u0.bits_0.nvrBusy + + + + 1 = NVR is busy + 0 = NVR is ready + + + Notes: + When set to 1, the NVR is busy. A new NVR operation should not occur until this bit is 0. If the NVR clock is greater than 64/63 of the MDIO clock, this bit never needs to be polled when operating over the MDIO. */ + unsigned int nvrBusy : 1; /* 1E.0100.8 RO */ + /* 1 = NVR is busy + 0 = NVR is ready + */ + unsigned int reserved1 : 1; + /*! \brief 1E.0100.A R/W NVR Burst + AQ_GlobalNvrInterface_APPIA.u0.bits_0.nvrBurst + + Default = 0x0 + + 0 = Single read or write operation of up to 4 bytes + 1 = Burst operation + + + Notes: + When this bit is set, the operation is a burst operation where more than 32-bits is read from the NVR or written to the NVR. This bit should be set to one until the last burst in the read or write operation, when it should be set to zero. It operates by gating the SPI clock, and not restarting it until new data is ready to be written, or the previous contents have been read. Each burst of data requires the NVR Execute Operation bit to be set to initiate the next phase. */ + unsigned int nvrBurst : 1; /* 1E.0100.A R/W Default = 0x0 */ + /* 0 = Single read or write operation of up to 4 bytes + 1 = Burst operation + */ + unsigned int reserved0 : 1; + /*! \brief 1E.0100.C R/WSC Reset NVR CRC + AQ_GlobalNvrInterface_APPIA.u0.bits_0.resetNvrCrc + + Default = 0x0 + + 1 = Reset NVR Mailbox CRC calculation register + + + Notes: + To prevent an erroneous answer, this bit should not be set at the same time the See NVR Operation Valid bit is set. */ + unsigned int resetNvrCrc : 1; /* 1E.0100.C R/WSC Default = 0x0 */ + /* 1 = Reset NVR Mailbox CRC calculation register + */ + /*! \brief 1E.0100.D R/W Freeze NVR CRC + AQ_GlobalNvrInterface_APPIA.u0.bits_0.freezeNvrCrc + + Default = 0x0 + + 1 = Freeze NVR Mailbox CRC calculation register + + + Notes: + To prevent an erroneous answer, this bit should not be set at the same time the See NVR Operation Valid bit is set. */ + unsigned int freezeNvrCrc : 1; /* 1E.0100.D R/W Default = 0x0 */ + /* 1 = Freeze NVR Mailbox CRC calculation register + */ + /*! \brief 1E.0100.E R/W NVR Write Mode + AQ_GlobalNvrInterface_APPIA.u0.bits_0.nvrWriteMode + + Default = 0x0 + + 1 = Write to NVR + 0 = Read from NVR + + */ + unsigned int nvrWriteMode : 1; /* 1E.0100.E R/W Default = 0x0 */ + /* 1 = Write to NVR + 0 = Read from NVR + */ + /*! \brief 1E.0100.F R/WSC NVR Execute Operation + AQ_GlobalNvrInterface_APPIA.u0.bits_0.nvrExecuteOperation + + Default = 0x0 + + 1 = Start NVR Operation + + + Notes: + When set to 1, the NVR operation will begin. Ensure that the uP is stalled using the See MCP Run Stall bit to ensure no NVR contention. */ + unsigned int nvrExecuteOperation : 1; /* 1E.0100.F R/WSC Default = 0x0 */ + /* 1 = Start NVR Operation + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global NVR Interface */ + union + { + struct + { + /*! \brief 1E.0101.F:0 RO NVR Mailbox CRC [F:0] + AQ_GlobalNvrInterface_APPIA.u1.bits_1.nvrMailboxCrc + + + + The running CRC-16 of everything passing through the NVR interface + + + Notes: + The CRC-16 over all data written or read through the NVR interface. The CRC-16 is calculated by dividing the data by: + x^16 + x^12 + x^5 + 1 */ + unsigned int nvrMailboxCrc : 16; /* 1E.0101.F:0 RO */ + /* The running CRC-16 of everything passing through the NVR interface + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global NVR Interface */ + union + { + struct + { + /*! \brief 1E.0102.7:0 R/W NVR Address MSW [17:10] + AQ_GlobalNvrInterface_APPIA.u2.bits_2.nvrAddressMSW + + Default = 0x00 + + NVR address MSW bits [17:10] + + + Notes: + The address of where to read and write from in the NVR. This is self-incrementing and will automatically increment after each read or write operation. The increment amount is based on the data length (i.e. increments by 4 if the data length is 4 bytes) */ + unsigned int nvrAddressMSW : 8; /* 1E.0102.7:0 R/W Default = 0x00 */ + /* NVR address MSW bits [17:10] + */ + unsigned int reserved0 : 8; + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global NVR Interface */ + union + { + struct + { + /*! \brief 1E.0103.F:0 R/W NVR Address LSW [F:0] + AQ_GlobalNvrInterface_APPIA.u3.bits_3.nvrAddressLSW + + Default = 0x0000 + + NVR address LSW bits [F:0] + + + Notes: + The address of where to read and write from in the NVR. This is self-incrementing and will automatically increment after each read or write operation. */ + unsigned int nvrAddressLSW : 16; /* 1E.0103.F:0 R/W Default = 0x0000 */ + /* NVR address LSW bits [F:0] + */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global NVR Interface */ + union + { + struct + { + /*! \brief 1E.0104.F:0 R/W NVR Data MSW [1F:10] + AQ_GlobalNvrInterface_APPIA.u4.bits_4.nvrDataMSW + + Default = 0x0000 + + NVR data MSW bits [1F:10] + + + Notes: + Data is stored and read-out from these registers in little-endian format for operations such as FLASH device ID, and for programming the processor. + + For instance the 64K Atmel device code reads out as two bytes 0x651F into the LSW register, whereas the datasheet indicates that 1F is the first byte read, followed by 65 as the second byte. + + To burst read and write these 4 bytes in the correct order (where DD is written to address x), they should be stored as: + + AA BB in the MSW + CC DD in the LSW. */ + unsigned int nvrDataMSW : 16; /* 1E.0104.F:0 R/W Default = 0x0000 */ + /* NVR data MSW bits [1F:10] + */ + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of Global NVR Interface */ + union + { + struct + { + /*! \brief 1E.0105.F:0 R/W NVR Data LSW [F:0] + AQ_GlobalNvrInterface_APPIA.u5.bits_5.nvrDataLSW + + Default = 0x0000 + + NVR data LSW bits [F:0] + + + Notes: + Data is stored and read-out from these registers in little-endian format for operations such as FLASH device ID, and for programming the processor. + + For instance the 64K Atmel device code reads out as two bytes 0x651F into the LSW register, whereas the datasheet indicates that 1F is the first byte read, followed by 65 as the second byte. + To burst read and write these 4 bytes in the correct order (where DD is written to address x), they should be stored as: + + AA BB in the MSW + CC DD in the LSW. */ + unsigned int nvrDataLSW : 16; /* 1E.0105.F:0 R/W Default = 0x0000 */ + /* NVR data LSW bits [F:0] + */ + } bits_5; + uint16_t word_5; + } u5; +} AQ_GlobalNvrInterface_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Mailbox Interface: 1E.0200 */ +/* Global Mailbox Interface: 1E.0200 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Mailbox Interface */ + union + { + struct + { + unsigned int reserved2 : 8; + /*! \brief 1E.0200.8 RO uP Mailbox Busy + AQ_GlobalMailboxInterface_APPIA.u0.bits_0.upMailboxBusy + + + + 1 = uP mailbox busy + 0 = uP mailbox ready + + + Notes: + In general the uP will respond within a few processor cycles to any PIF slave request, much faster than the MDIO. If the busy is asserted over multiple MDIO polling cycles, then a H/W error may have occured and a Global S/W reset or uP reset is required. */ + unsigned int upMailboxBusy : 1; /* 1E.0200.8 RO */ + /* 1 = uP mailbox busy + 0 = uP mailbox ready + */ + unsigned int reserved1 : 3; + /*! \brief 1E.0200.C R/WSC Reset uP Mailbox CRC + AQ_GlobalMailboxInterface_APPIA.u0.bits_0.resetUpMailboxCrc + + Default = 0x0 + + 1 = Reset uP mailbox CRC calculation register + + */ + unsigned int resetUpMailboxCrc : 1; /* 1E.0200.C R/WSC Default = 0x0 */ + /* 1 = Reset uP mailbox CRC calculation register + */ + unsigned int reserved0 : 1; + /*! \brief 1E.0200.E R/W uP Mailbox Write Mode + AQ_GlobalMailboxInterface_APPIA.u0.bits_0.upMailboxWriteMode + + Default = 0x0 + + 1 = Write + 0 = Read + + + Notes: + Mailbox direction */ + unsigned int upMailboxWriteMode : 1; /* 1E.0200.E R/W Default = 0x0 */ + /* 1 = Write + 0 = Read + */ + /*! \brief 1E.0200.F R/WSC uP Mailbox Execute Operation + AQ_GlobalMailboxInterface_APPIA.u0.bits_0.upMailboxExecuteOperation + + Default = 0x0 + + 1 = Start of mailbox Operation + + + Notes: + Indicates mailbox is loaded and ready */ + unsigned int upMailboxExecuteOperation : 1; /* 1E.0200.F R/WSC Default = 0x0 */ + /* 1 = Start of mailbox Operation + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Mailbox Interface */ + union + { + struct + { + /*! \brief 1E.0201.F:0 RO uP Mailbox CRC [F:0] + AQ_GlobalMailboxInterface_APPIA.u1.bits_1.upMailboxCrc + + + + The running CRC-16 of everything passing through the mailbox interface + + */ + unsigned int upMailboxCrc : 16; /* 1E.0201.F:0 RO */ + /* The running CRC-16 of everything passing through the mailbox interface + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Mailbox Interface */ + union + { + struct + { + /*! \brief 1E.0202.F:0 R/W uP Mailbox Address MSW [1F:10] + AQ_GlobalMailboxInterface_APPIA.u2.bits_2.upMailboxAddressMSW + + Default = 0x0000 + + uP Mailbox MSW address + + + Notes: + The address of where to read and write from in the Microcontroller Mailbox. This is self-incrementing and automatically increments after each read and write operation.PHY */ + unsigned int upMailboxAddressMSW : 16; /* 1E.0202.F:0 R/W Default = 0x0000 */ + /* uP Mailbox MSW address + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global Mailbox Interface */ + union + { + struct + { + /*! \brief 1E.0203.1:0 RO uP Mailbox Address LSW Don't Care [1:0] + AQ_GlobalMailboxInterface_APPIA.u3.bits_3.upMailboxAddressLSW_Don_tCare + + + + Least significant uP LSW Mailbox address bits [1:0] + + + Notes: + These bits are always set to 0 since each memory access is on a 4-byte boundary. */ + unsigned int upMailboxAddressLSW_Don_tCare : 2; /* 1E.0203.1:0 RO */ + /* Least significant uP LSW Mailbox address bits [1:0] + */ + /*! \brief 1E.0203.F:2 R/W uP Mailbox Address LSW [F:2] + AQ_GlobalMailboxInterface_APPIA.u3.bits_3.upMailboxAddressLSW + + Default = 0x0000 + + uP LSW Mailbox address [F:2] + + + Notes: + The address of where to read and write from in the Microcontroller Mailbox. This is self-incrementing and automatically increments after each read and write operation.PHY */ + unsigned int upMailboxAddressLSW : 14; /* 1E.0203.F:2 R/W Default = 0x0000 */ + /* uP LSW Mailbox address [F:2] + */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global Mailbox Interface */ + union + { + struct + { + /*! \brief 1E.0204.F:0 R/W uP Mailbox Data MSW [1F:10] + AQ_GlobalMailboxInterface_APPIA.u4.bits_4.upMailboxDataMSW + + Default = 0x0000 + + uP Mailbox data MSW + + */ + unsigned int upMailboxDataMSW : 16; /* 1E.0204.F:0 R/W Default = 0x0000 */ + /* uP Mailbox data MSW + */ + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of Global Mailbox Interface */ + union + { + struct + { + /*! \brief 1E.0205.F:0 R/W uP Mailbox Data LSW [F:0] + AQ_GlobalMailboxInterface_APPIA.u5.bits_5.upMailboxDataLSW + + Default = 0x0000 + + uP Mailbox data LSW + + */ + unsigned int upMailboxDataLSW : 16; /* 1E.0205.F:0 R/W Default = 0x0000 */ + /* uP Mailbox data LSW + */ + } bits_5; + uint16_t word_5; + } u5; +} AQ_GlobalMailboxInterface_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Microprocessor Scratch Pad: 1E.0300 */ +/* Global Microprocessor Scratch Pad: 1E.0300 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Microprocessor Scratch Pad */ + union + { + struct + { + /*! \brief 1E.0300.F:0 R/W Scratch Pad 1[F:0] + AQ_GlobalMicroprocessorScratchPad_APPIA.u0.bits_0.scratchPad_1 + + Default = 0x0000 + + General Purpose Scratch Pad1 + */ + unsigned int scratchPad_1 : 16; /* 1E.0300.F:0 R/W Default = 0x0000 */ + /* General Purpose Scratch Pad1 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Microprocessor Scratch Pad */ + union + { + struct + { + /*! \brief 1E.0301.F:0 R/W Scratch Pad 2 [F:0] + AQ_GlobalMicroprocessorScratchPad_APPIA.u1.bits_1.scratchPad_2 + + Default = 0x0000 + + General Purpose Scratch P + */ + unsigned int scratchPad_2 : 16; /* 1E.0301.F:0 R/W Default = 0x0000 */ + /* General Purpose Scratch P */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalMicroprocessorScratchPad_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Control: 1E.C000 */ +/* Global Control: 1E.C000 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Control */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Control */ + union + { + struct + { + /*! \brief 1E.C001.0 R/W uP Run Stall + AQ_GlobalControl_APPIA.u1.bits_1.upRunStall + + Default = 0x0 + + 1 = uP Run Stall + 0 = uP normal mode + + + Notes: + Deactivates the uP. The PIF slave bus for inbound requests will still be active. This bit is muliplexed with the "MDIO Boot Load" pin with the See uP Run Stall Override bit as the select. When the "MDIO Boot Load" pin is asserted, the uP will be in Run Stall mode after reset. */ + unsigned int upRunStall : 1; /* 1E.C001.0 R/W Default = 0x0 */ + /* 1 = uP Run Stall + 0 = uP normal mode + */ + unsigned int reserved1 : 5; + /*! \brief 1E.C001.6 R/W uP Run Stall Override + AQ_GlobalControl_APPIA.u1.bits_1.upRunStallOverride + + Default = 0x0 + + 0 = uP Run Stall from "MDIO Boot Load" pin. + 1 = uP Run Stall from See MCP Run Stall bit + + + Notes: + This bit selects the uP Run Stall from either the "MDIO Boot Load" pin or the See MCP Run Stall bit. */ + unsigned int upRunStallOverride : 1; /* 1E.C001.6 R/W Default = 0x0 */ + /* 0 = uP Run Stall from "MDIO Boot Load" pin. + 1 = uP Run Stall from See MCP Run Stall bit + */ + unsigned int reserved0 : 8; + /*! \brief 1E.C001.F R/W uP Reset + AQ_GlobalControl_APPIA.u1.bits_1.upReset + + Default = 0x0 + + 1 = Reset + + + Notes: + Resets the uP and the PIF master and slave bus. Will be active for a minimum of 100 microseconds. */ + unsigned int upReset : 1; /* 1E.C001.F R/W Default = 0x0 */ + /* 1 = Reset + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalControl_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Reset Control: 1E.C006 */ +/* Global Reset Control: 1E.C006 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Reset Control */ + union + { + struct + { + unsigned int reserved1 : 14; + /*! \brief 1E.C006.E R/WPD Global MMD Reset Disable + AQ_GlobalResetControl_APPIA.u0.bits_0.globalMMD_ResetDisable + + Provisionable Default = 0x0 + + 1 = Disable the S/W reset to the Global MMD registers + 0 = Enable the S/W reset to the Global MMD registers + + + Notes: + Setting this bit prevents a Global S/W reset or Global S/W reset from resetting the Global MMD registers */ + unsigned int globalMMD_ResetDisable : 1; /* 1E.C006.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Disable the S/W reset to the Global MMD registers + 0 = Enable the S/W reset to the Global MMD registers + */ + unsigned int reserved0 : 1; + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalResetControl_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Diagnostic Provisioning: 1E.C400 */ +/* Global Diagnostic Provisioning: 1E.C400 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Diagnostic Provisioning */ + union + { + struct + { + unsigned int reserved0 : 15; + /*! \brief 1E.C400.F R/WPD Enable Diagnostics + AQ_GlobalDiagnosticProvisioning_APPIA.u0.bits_0.enableDiagnostics + + Provisionable Default = 0x1 + + 1 = Chip performs diagnostics on power-up + */ + unsigned int enableDiagnostics : 1; /* 1E.C400.F R/WPD Provisionable Default = 0x1 */ + /* 1 = Chip performs diagnostics on power-up */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalDiagnosticProvisioning_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Thermal Provisioning: 1E.C420 */ +/* Global Thermal Provisioning: 1E.C420 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Thermal Provisioning */ + union + { + struct + { + /*! \brief 1E.C420.F:0 R/WPD Reserved 0 [F:0] + AQ_GlobalThermalProvisioning_APPIA.u0.bits_0.reserved_0 + + Provisionable Default = 0x0000 + + Internal reserved - do not modify + + */ + unsigned int reserved_0 : 16; /* 1E.C420.F:0 R/WPD Provisionable Default = 0x0000 */ + /* Internal reserved - do not modify + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Thermal Provisioning */ + union + { + struct + { + /*! \brief 1E.C421.F:0 R/WPD High Temp Failure Threshold [F:0] + AQ_GlobalThermalProvisioning_APPIA.u1.bits_1.highTempFailureThreshold + + Provisionable Default = 0x4600 + + [F:0] of high temperature failure threshold + + Notes: + 2's complement value with the LSB representing 1/256 of a degree Celsius. This corresponds to -40 degreesC = 0xD800. Default is 70 degreesC. + + In XENPAK mode, F/W will use the XENPAK register 1.A000 - 1.A001: instead of this register. + + NOTE! All Thresholds are orthogonal and can be set to any value regardless the value of the other thresholds. i.e. - High-Temperature-Warning (1E.C423) could be higher than High-Temperature-Failure (1E.C421). */ + unsigned int highTempFailureThreshold : 16; /* 1E.C421.F:0 R/WPD Provisionable Default = 0x4600 */ + /* [F:0] of high temperature failure threshold */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Thermal Provisioning */ + union + { + struct + { + /*! \brief 1E.C422.F:0 R/WPD Low Temp Failure Threshold [F:0] + AQ_GlobalThermalProvisioning_APPIA.u2.bits_2.lowTempFailureThreshold + + Provisionable Default = 0x0000 + + [F:0] of low temperature failure threshold + + Notes: + 2's complement value with the LSB representing 1/256 of a degree Celsius. This corresponds to -40 degreesC = 0xD800. Default is 0 degreesC. + + In XENPAK mode, F/W will use the XENPAK register 1.A002 - 1.A003: instead of this register. + + NOTE! All Thresholds are orthogonal and can be set to any value regardless the value of the other thresholds. i.e. - High-Temperature-Warning (1E.C423) could be higher than High-Temperature-Failure (1E.C421). */ + unsigned int lowTempFailureThreshold : 16; /* 1E.C422.F:0 R/WPD Provisionable Default = 0x0000 */ + /* [F:0] of low temperature failure threshold */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global Thermal Provisioning */ + union + { + struct + { + /*! \brief 1E.C423.F:0 R/WPD High Temp Warning Threshold [F:0] + AQ_GlobalThermalProvisioning_APPIA.u3.bits_3.highTempWarningThreshold + + Provisionable Default = 0x3C00 + + [F:0] of high temperature warning threshold + + Notes: + 2's complement value with the LSB representing 1/256 of a degree Celsius. This corresponds to -40 degreesC = 0xD008. Default is 60 degreesC. + + In XENPAK mode, F/W will use the XENPAK register 1.A004 - 1.A005: instead of this register. + + NOTE! All Thresholds are orthogonal and can be set to any value regardless the value of the other thresholds. i.e. - High-Temperature-Warning (1E.C423) could be higher than High-Temperature-Failure (1E.C421). */ + unsigned int highTempWarningThreshold : 16; /* 1E.C423.F:0 R/WPD Provisionable Default = 0x3C00 */ + /* [F:0] of high temperature warning threshold */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global Thermal Provisioning */ + union + { + struct + { + /*! \brief 1E.C424.F:0 R/WPD Low Temp Warning Threshold [F:0] + AQ_GlobalThermalProvisioning_APPIA.u4.bits_4.lowTempWarningThreshold + + Provisionable Default = 0x0A00 + + [F:0] of low temperature warning threshold + + Notes: + 2's complement value with the LSB representing 1/256 of a degree Celsius. This corresponds to -40 degreesC = 0xD800. Default is 10 degreesC. + + In XENPAK mode, F/W will use the XENPAK register 1.A006 - 1.A007: instead of this register. + + NOTE! All Thresholds are orthogonal and can be set to any value regardless the value of the other thresholds. i.e. - High-Temperature-Warning (1E.C423) could be higher than High-Temperature-Failure (1E.C421). */ + unsigned int lowTempWarningThreshold : 16; /* 1E.C424.F:0 R/WPD Provisionable Default = 0x0A00 */ + /* [F:0] of low temperature warning threshold */ + } bits_4; + uint16_t word_4; + } u4; +} AQ_GlobalThermalProvisioning_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global LED Provisioning: 1E.C430 */ +/* Global LED Provisioning: 1E.C430 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global LED Provisioning */ + union + { + struct + { + /*! \brief 1E.C430.1:0 R/WPD LED #0 Activity Stretch [1:0] + AQ_GlobalLedProvisioning_APPIA.u0.bits_0.led_0ActivityStretch + + Provisionable Default = 0x3 + + [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + + */ + unsigned int led_0ActivityStretch : 2; /* 1E.C430.1:0 R/WPD Provisionable Default = 0x3 */ + /* [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + */ + /*! \brief 1E.C430.2 R/WPD LED #0 Transmit Activity + AQ_GlobalLedProvisioning_APPIA.u0.bits_0.led_0TransmitActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on transmit activity + + */ + unsigned int led_0TransmitActivity : 1; /* 1E.C430.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on transmit activity + */ + /*! \brief 1E.C430.3 R/WPD LED #0 Receive Activity + AQ_GlobalLedProvisioning_APPIA.u0.bits_0.led_0ReceiveActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on receive activity + + */ + unsigned int led_0ReceiveActivity : 1; /* 1E.C430.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on receive activity + */ + /*! \brief 1E.C430.4 R/WPD LED #0 Connecting + AQ_GlobalLedProvisioning_APPIA.u0.bits_0.led_0Connecting + + Provisionable Default = 0x0 + + 1 = LED is on when attempting to connect. + + */ + unsigned int led_0Connecting : 1; /* 1E.C430.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when attempting to connect. + */ + /*! \brief 1E.C430.5 R/WPD LED #0 100 Mb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u0.bits_0.led_0_100Mb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 100 Mb/s + + */ + unsigned int led_0_100Mb_sLinkEstablished : 1; /* 1E.C430.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 100 Mb/s + */ + /*! \brief 1E.C430.6 R/WPD LED #0 1 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u0.bits_0.led_0_1Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 1 Gb/s + + */ + unsigned int led_0_1Gb_sLinkEstablished : 1; /* 1E.C430.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 1 Gb/s + */ + /*! \brief 1E.C430.7 R/WPD LED #0 10 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u0.bits_0.led_0_10Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 10 Gb/s + + */ + unsigned int led_0_10Gb_sLinkEstablished : 1; /* 1E.C430.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 10 Gb/s + */ + /*! \brief 1E.C430.8 R/WPD LED #0 Manual Set + AQ_GlobalLedProvisioning_APPIA.u0.bits_0.led_0ManualSet + + Provisionable Default = 0x0 + + 1 = LED On + + */ + unsigned int led_0ManualSet : 1; /* 1E.C430.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED On + */ + unsigned int reserved0 : 7; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global LED Provisioning */ + union + { + struct + { + /*! \brief 1E.C431.1:0 R/WPD LED #1 Activity Stretch [1:0] + AQ_GlobalLedProvisioning_APPIA.u1.bits_1.led_1ActivityStretch + + Provisionable Default = 0x3 + + [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + + */ + unsigned int led_1ActivityStretch : 2; /* 1E.C431.1:0 R/WPD Provisionable Default = 0x3 */ + /* [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + */ + /*! \brief 1E.C431.2 R/WPD LED #1 Transmit Activity + AQ_GlobalLedProvisioning_APPIA.u1.bits_1.led_1TransmitActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on transmit activity + + */ + unsigned int led_1TransmitActivity : 1; /* 1E.C431.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on transmit activity + */ + /*! \brief 1E.C431.3 R/WPD LED #1 Receive Activity + AQ_GlobalLedProvisioning_APPIA.u1.bits_1.led_1ReceiveActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on receive activity + + */ + unsigned int led_1ReceiveActivity : 1; /* 1E.C431.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on receive activity + */ + /*! \brief 1E.C431.4 R/WPD LED #1 Connecting + AQ_GlobalLedProvisioning_APPIA.u1.bits_1.led_1Connecting + + Provisionable Default = 0x0 + + 1 = LED is on when attempting to connect. + + */ + unsigned int led_1Connecting : 1; /* 1E.C431.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when attempting to connect. + */ + /*! \brief 1E.C431.5 R/WPD LED #1 100 Mb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u1.bits_1.led_1_100Mb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 100 Mb/s + + */ + unsigned int led_1_100Mb_sLinkEstablished : 1; /* 1E.C431.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 100 Mb/s + */ + /*! \brief 1E.C431.6 R/WPD LED #1 1 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u1.bits_1.led_1_1Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 1 Gb/s + + */ + unsigned int led_1_1Gb_sLinkEstablished : 1; /* 1E.C431.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 1 Gb/s + */ + /*! \brief 1E.C431.7 R/WPD LED #1 10 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u1.bits_1.led_1_10Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 10 Gb/s + + */ + unsigned int led_1_10Gb_sLinkEstablished : 1; /* 1E.C431.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 10 Gb/s + */ + /*! \brief 1E.C431.8 R/WPD LED #1 Manual Set + AQ_GlobalLedProvisioning_APPIA.u1.bits_1.led_1ManualSet + + Provisionable Default = 0x0 + + 1 = LED On + + */ + unsigned int led_1ManualSet : 1; /* 1E.C431.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED On + */ + unsigned int reserved0 : 7; + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global LED Provisioning */ + union + { + struct + { + /*! \brief 1E.C432.1:0 R/WPD LED #2 Activity Stretch [1:0] + AQ_GlobalLedProvisioning_APPIA.u2.bits_2.led_2ActivityStretch + + Provisionable Default = 0x3 + + [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + + */ + unsigned int led_2ActivityStretch : 2; /* 1E.C432.1:0 R/WPD Provisionable Default = 0x3 */ + /* [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + */ + /*! \brief 1E.C432.2 R/WPD LED #2 Transmit Activity + AQ_GlobalLedProvisioning_APPIA.u2.bits_2.led_2TransmitActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on transmit activity + + */ + unsigned int led_2TransmitActivity : 1; /* 1E.C432.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on transmit activity + */ + /*! \brief 1E.C432.3 R/WPD LED #2 Receive Activity + AQ_GlobalLedProvisioning_APPIA.u2.bits_2.led_2ReceiveActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on receive activity + + */ + unsigned int led_2ReceiveActivity : 1; /* 1E.C432.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on receive activity + */ + /*! \brief 1E.C432.4 R/WPD LED #2 Connecting + AQ_GlobalLedProvisioning_APPIA.u2.bits_2.led_2Connecting + + Provisionable Default = 0x0 + + 1 = LED is on when attempting to connect. + + */ + unsigned int led_2Connecting : 1; /* 1E.C432.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when attempting to connect. + */ + /*! \brief 1E.C432.5 R/WPD LED #2 100 Mb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u2.bits_2.led_2_100Mb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 100 Mb/s + + */ + unsigned int led_2_100Mb_sLinkEstablished : 1; /* 1E.C432.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 100 Mb/s + */ + /*! \brief 1E.C432.6 R/WPD LED #2 1 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u2.bits_2.led_2_1Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 1 Gb/s + + */ + unsigned int led_2_1Gb_sLinkEstablished : 1; /* 1E.C432.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 1 Gb/s + */ + /*! \brief 1E.C432.7 R/WPD LED #2 10 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u2.bits_2.led_2_10Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 10 Gb/s + + */ + unsigned int led_2_10Gb_sLinkEstablished : 1; /* 1E.C432.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 10 Gb/s + */ + /*! \brief 1E.C432.8 R/WPD LED #2 Manual Set + AQ_GlobalLedProvisioning_APPIA.u2.bits_2.led_2ManualSet + + Provisionable Default = 0x0 + + 1 = LED On + + */ + unsigned int led_2ManualSet : 1; /* 1E.C432.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED On + */ + unsigned int reserved0 : 7; + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global LED Provisioning */ + union + { + struct + { + /*! \brief 1E.C433.1:0 R/WPD LED #3 Activity Stretch [1:0] + AQ_GlobalLedProvisioning_APPIA.u3.bits_3.led_3ActivityStretch + + Provisionable Default = 0x3 + + [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + + */ + unsigned int led_3ActivityStretch : 2; /* 1E.C433.1:0 R/WPD Provisionable Default = 0x3 */ + /* [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + */ + /*! \brief 1E.C433.2 R/WPD LED #3 Transmit Activity + AQ_GlobalLedProvisioning_APPIA.u3.bits_3.led_3TransmitActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on transmit activity + + */ + unsigned int led_3TransmitActivity : 1; /* 1E.C433.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on transmit activity + */ + /*! \brief 1E.C433.3 R/WPD LED #3 Receive Activity + AQ_GlobalLedProvisioning_APPIA.u3.bits_3.led_3ReceiveActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on receive activity + + */ + unsigned int led_3ReceiveActivity : 1; /* 1E.C433.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on receive activity + */ + /*! \brief 1E.C433.4 R/WPD LED #3 Connecting + AQ_GlobalLedProvisioning_APPIA.u3.bits_3.led_3Connecting + + Provisionable Default = 0x0 + + 1 = LED is on when attempting to connect. + + */ + unsigned int led_3Connecting : 1; /* 1E.C433.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when attempting to connect. + */ + /*! \brief 1E.C433.5 R/WPD LED #3 100 Mb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u3.bits_3.led_3_100Mb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 100 Mb/s + + */ + unsigned int led_3_100Mb_sLinkEstablished : 1; /* 1E.C433.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 100 Mb/s + */ + /*! \brief 1E.C433.6 R/WPD LED #3 1 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u3.bits_3.led_3_1Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 1 Gb/s + + */ + unsigned int led_3_1Gb_sLinkEstablished : 1; /* 1E.C433.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 1 Gb/s + */ + /*! \brief 1E.C433.7 R/WPD LED #3 10 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u3.bits_3.led_3_10Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 10 Gb/s + + */ + unsigned int led_3_10Gb_sLinkEstablished : 1; /* 1E.C433.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 10 Gb/s + */ + /*! \brief 1E.C433.8 R/WPD LED #3 Manual Set + AQ_GlobalLedProvisioning_APPIA.u3.bits_3.led_3ManualSet + + Provisionable Default = 0x0 + + 1 = LED On + + */ + unsigned int led_3ManualSet : 1; /* 1E.C433.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED On + */ + unsigned int reserved0 : 7; + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global LED Provisioning */ + union + { + struct + { + /*! \brief 1E.C434.1:0 R/WPD LED #4 Activity Stretch [1:0] + AQ_GlobalLedProvisioning_APPIA.u4.bits_4.led_4ActivityStretch + + Provisionable Default = 0x3 + + [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + + */ + unsigned int led_4ActivityStretch : 2; /* 1E.C434.1:0 R/WPD Provisionable Default = 0x3 */ + /* [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + */ + /*! \brief 1E.C434.2 R/WPD LED #4 Transmit Activity + AQ_GlobalLedProvisioning_APPIA.u4.bits_4.led_4TransmitActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on transmit activity + + */ + unsigned int led_4TransmitActivity : 1; /* 1E.C434.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on transmit activity + */ + /*! \brief 1E.C434.3 R/WPD LED #4 Receive Activity + AQ_GlobalLedProvisioning_APPIA.u4.bits_4.led_4ReceiveActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on receive activity + + */ + unsigned int led_4ReceiveActivity : 1; /* 1E.C434.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on receive activity + */ + /*! \brief 1E.C434.4 R/WPD LED #4 Connecting + AQ_GlobalLedProvisioning_APPIA.u4.bits_4.led_4Connecting + + Provisionable Default = 0x0 + + 1 = LED is on when attempting to connect. + + */ + unsigned int led_4Connecting : 1; /* 1E.C434.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when attempting to connect. + */ + /*! \brief 1E.C434.5 R/WPD LED #4 100 Mb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u4.bits_4.led_4_100Mb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 100 Mb/s + + */ + unsigned int led_4_100Mb_sLinkEstablished : 1; /* 1E.C434.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 100 Mb/s + */ + /*! \brief 1E.C434.6 R/WPD LED #4 1 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u4.bits_4.led_4_1Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 1 Gb/s + + */ + unsigned int led_4_1Gb_sLinkEstablished : 1; /* 1E.C434.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 1 Gb/s + */ + /*! \brief 1E.C434.7 R/WPD LED #4 10 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u4.bits_4.led_4_10Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 10 Gb/s + + */ + unsigned int led_4_10Gb_sLinkEstablished : 1; /* 1E.C434.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 10 Gb/s + */ + /*! \brief 1E.C434.8 R/WPD LED #4 Manual Set + AQ_GlobalLedProvisioning_APPIA.u4.bits_4.led_4ManualSet + + Provisionable Default = 0x0 + + 1 = LED On + + */ + unsigned int led_4ManualSet : 1; /* 1E.C434.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED On + */ + unsigned int reserved0 : 7; + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of Global LED Provisioning */ + union + { + struct + { + /*! \brief 1E.C435.1:0 R/WPD LED #5 Activity Stretch [1:0] + AQ_GlobalLedProvisioning_APPIA.u5.bits_5.led_5ActivityStretch + + Provisionable Default = 0x3 + + [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + + */ + unsigned int led_5ActivityStretch : 2; /* 1E.C435.1:0 R/WPD Provisionable Default = 0x3 */ + /* [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + */ + /*! \brief 1E.C435.2 R/WPD LED #5 Transmit Activity + AQ_GlobalLedProvisioning_APPIA.u5.bits_5.led_5TransmitActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on transmit activity + + */ + unsigned int led_5TransmitActivity : 1; /* 1E.C435.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on transmit activity + */ + /*! \brief 1E.C435.3 R/WPD LED #5 Receive Activity + AQ_GlobalLedProvisioning_APPIA.u5.bits_5.led_5ReceiveActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on receive activity + + */ + unsigned int led_5ReceiveActivity : 1; /* 1E.C435.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on receive activity + */ + /*! \brief 1E.C435.4 R/WPD LED #5 Connecting + AQ_GlobalLedProvisioning_APPIA.u5.bits_5.led_5Connecting + + Provisionable Default = 0x0 + + 1 = LED is on when attempting to connect. + + */ + unsigned int led_5Connecting : 1; /* 1E.C435.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when attempting to connect. + */ + /*! \brief 1E.C435.5 R/WPD LED #5 100 Mb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u5.bits_5.led_5_100Mb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 100 Mb/s + + */ + unsigned int led_5_100Mb_sLinkEstablished : 1; /* 1E.C435.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 100 Mb/s + */ + /*! \brief 1E.C435.6 R/WPD LED #5 1 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u5.bits_5.led_5_1Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 1 Gb/s + + */ + unsigned int led_5_1Gb_sLinkEstablished : 1; /* 1E.C435.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 1 Gb/s + */ + /*! \brief 1E.C435.7 R/WPD LED #5 10 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u5.bits_5.led_5_10Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 10 Gb/s + + */ + unsigned int led_5_10Gb_sLinkEstablished : 1; /* 1E.C435.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 10 Gb/s + */ + /*! \brief 1E.C435.8 R/WPD LED #5 Manual Set + AQ_GlobalLedProvisioning_APPIA.u5.bits_5.led_5ManualSet + + Provisionable Default = 0x0 + + 1 = LED On + + */ + unsigned int led_5ManualSet : 1; /* 1E.C435.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED On + */ + unsigned int reserved0 : 7; + } bits_5; + uint16_t word_5; + } u5; + /*! \brief Union for bit and word level access of word 6 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_6; + uint16_t word_6; + } u6; + /*! \brief Union for bit and word level access of word 7 of Global LED Provisioning */ + union + { + struct + { + /*! \brief 1E.C437.0 R/WPD LED Operation Mode + AQ_GlobalLedProvisioning_APPIA.u7.bits_7.ledOperationMode + + Provisionable Default = 0x0 + + 1 = LED link activity in Mode #2 + 0 = LED link activity in classic mode + + + Notes: + When set to 1, the LED blinking rate is based on Mode #2 algorithm. When set to 0, the LED blinking rate is based on the classic algorithm. */ + unsigned int ledOperationMode : 1; /* 1E.C437.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED link activity in Mode #2 + 0 = LED link activity in classic mode + */ + unsigned int reserved0 : 15; + } bits_7; + uint16_t word_7; + } u7; + /*! \brief Union for bit and word level access of word 8 of Global LED Provisioning */ + union + { + struct + { + /*! \brief 1E.C438.0 R/WPD LED #0 Manual Active Select + AQ_GlobalLedProvisioning_APPIA.u8.bits_8.led_0ManualActiveSelect + + Provisionable Default = 0x0 + + 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + + */ + unsigned int led_0ManualActiveSelect : 1; /* 1E.C438.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + */ + /*! \brief 1E.C438.1 R/WPD LED #0 Active High Select + AQ_GlobalLedProvisioning_APPIA.u8.bits_8.led_0ActiveHighSelect + + Provisionable Default = 0x0 + + 1 = LED active high + 0 = LED active low + + + Notes: + The See LED #0 Manual Active Select bit must be 1 for this bit to take affect. */ + unsigned int led_0ActiveHighSelect : 1; /* 1E.C438.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED active high + 0 = LED active low + */ + /*! \brief 1E.C438.2 R/WPD LED #0 Drive Three State Select + AQ_GlobalLedProvisioning_APPIA.u8.bits_8.led_0DriveThreeStateSelect + + Provisionable Default = 0x0 + + 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + + */ + unsigned int led_0DriveThreeStateSelect : 1; /* 1E.C438.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + */ + unsigned int reserved0 : 13; + } bits_8; + uint16_t word_8; + } u8; + /*! \brief Union for bit and word level access of word 9 of Global LED Provisioning */ + union + { + struct + { + /*! \brief 1E.C439.0 R/WPD LED #1 Manual Active Select + AQ_GlobalLedProvisioning_APPIA.u9.bits_9.led_1ManualActiveSelect + + Provisionable Default = 0x0 + + 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + + */ + unsigned int led_1ManualActiveSelect : 1; /* 1E.C439.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + */ + /*! \brief 1E.C439.1 R/WPD LED #1 Active High Select + AQ_GlobalLedProvisioning_APPIA.u9.bits_9.led_1ActiveHighSelect + + Provisionable Default = 0x0 + + 1 = LED active high + 0 = LED active low + + + Notes: + The See LED #1 Manual Active Select bit must be 1 for this bit to take affect. */ + unsigned int led_1ActiveHighSelect : 1; /* 1E.C439.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED active high + 0 = LED active low + */ + /*! \brief 1E.C439.2 R/WPD LED #1 Drive Three State Select + AQ_GlobalLedProvisioning_APPIA.u9.bits_9.led_1DriveThreeStateSelect + + Provisionable Default = 0x0 + + 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + + */ + unsigned int led_1DriveThreeStateSelect : 1; /* 1E.C439.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + */ + unsigned int reserved0 : 13; + } bits_9; + uint16_t word_9; + } u9; + /*! \brief Union for bit and word level access of word 10 of Global LED Provisioning */ + union + { + struct + { + /*! \brief 1E.C43A.0 R/WPD LED #2 Manual Active Select + AQ_GlobalLedProvisioning_APPIA.u10.bits_10.led_2ManualActiveSelect + + Provisionable Default = 0x0 + + 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + + */ + unsigned int led_2ManualActiveSelect : 1; /* 1E.C43A.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + */ + /*! \brief 1E.C43A.1 R/WPD LED #2 Active High Select + AQ_GlobalLedProvisioning_APPIA.u10.bits_10.led_2ActiveHighSelect + + Provisionable Default = 0x0 + + 1 = LED active high + 0 = LED active low + + + Notes: + The See LED #2 Manual Active Select bit must be 1 for this bit to take affect. */ + unsigned int led_2ActiveHighSelect : 1; /* 1E.C43A.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED active high + 0 = LED active low + */ + /*! \brief 1E.C43A.2 R/WPD LED #2 Drive Three State Select + AQ_GlobalLedProvisioning_APPIA.u10.bits_10.led_2DriveThreeStateSelect + + Provisionable Default = 0x0 + + 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + + */ + unsigned int led_2DriveThreeStateSelect : 1; /* 1E.C43A.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + */ + unsigned int reserved0 : 13; + } bits_10; + uint16_t word_10; + } u10; + /*! \brief Union for bit and word level access of word 11 of Global LED Provisioning */ + union + { + struct + { + /*! \brief 1E.C43B.0 R/WPD LED #3 Manual Active Select + AQ_GlobalLedProvisioning_APPIA.u11.bits_11.led_3ManualActiveSelect + + Provisionable Default = 0x0 + + 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + + */ + unsigned int led_3ManualActiveSelect : 1; /* 1E.C43B.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + */ + /*! \brief 1E.C43B.1 R/WPD LED #3 Active High Select + AQ_GlobalLedProvisioning_APPIA.u11.bits_11.led_3ActiveHighSelect + + Provisionable Default = 0x0 + + 1 = LED active high + 0 = LED active low + + + Notes: + The See LED #3 Manual Active Select bit must be 1 for this bit to take affect. */ + unsigned int led_3ActiveHighSelect : 1; /* 1E.C43B.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED active high + 0 = LED active low + */ + /*! \brief 1E.C43B.2 R/WPD LED #3 Drive Three State Select + AQ_GlobalLedProvisioning_APPIA.u11.bits_11.led_3DriveThreeStateSelect + + Provisionable Default = 0x0 + + 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + + */ + unsigned int led_3DriveThreeStateSelect : 1; /* 1E.C43B.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + */ + unsigned int reserved0 : 13; + } bits_11; + uint16_t word_11; + } u11; + /*! \brief Union for bit and word level access of word 12 of Global LED Provisioning */ + union + { + struct + { + /*! \brief 1E.C43C.0 R/WPD LED #4 Manual Active Select + AQ_GlobalLedProvisioning_APPIA.u12.bits_12.led_4ManualActiveSelect + + Provisionable Default = 0x0 + + 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + + */ + unsigned int led_4ManualActiveSelect : 1; /* 1E.C43C.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + */ + /*! \brief 1E.C43C.1 R/WPD LED #4 Active High Select + AQ_GlobalLedProvisioning_APPIA.u12.bits_12.led_4ActiveHighSelect + + Provisionable Default = 0x0 + + 1 = LED active high + 0 = LED active low + + + Notes: + The See LED #4 Manual Active Select bit must be 1 for this bit to take affect. */ + unsigned int led_4ActiveHighSelect : 1; /* 1E.C43C.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED active high + 0 = LED active low + */ + /*! \brief 1E.C43C.2 R/WPD LED #4 Drive Three State Select + AQ_GlobalLedProvisioning_APPIA.u12.bits_12.led_4DriveThreeStateSelect + + Provisionable Default = 0x0 + + 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + + */ + unsigned int led_4DriveThreeStateSelect : 1; /* 1E.C43C.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + */ + unsigned int reserved0 : 13; + } bits_12; + uint16_t word_12; + } u12; + /*! \brief Union for bit and word level access of word 13 of Global LED Provisioning */ + union + { + struct + { + /*! \brief 1E.C43D.0 R/WPD LED #5 Manual Active Select + AQ_GlobalLedProvisioning_APPIA.u13.bits_13.led_5ManualActiveSelect + + Provisionable Default = 0x0 + + 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + + */ + unsigned int led_5ManualActiveSelect : 1; /* 1E.C43D.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + */ + /*! \brief 1E.C43D.1 R/WPD LED #5 Active High Select + AQ_GlobalLedProvisioning_APPIA.u13.bits_13.led_5ActiveHighSelect + + Provisionable Default = 0x0 + + 1 = LED active high + 0 = LED active low + + + Notes: + The See LED #5 Manual Active Select bit must be 1 for this bit to take affect. */ + unsigned int led_5ActiveHighSelect : 1; /* 1E.C43D.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED active high + 0 = LED active low + */ + /*! \brief 1E.C43D.2 R/WPD LED #5 Drive Three State Select + AQ_GlobalLedProvisioning_APPIA.u13.bits_13.led_5DriveThreeStateSelect + + Provisionable Default = 0x0 + + 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + + */ + unsigned int led_5DriveThreeStateSelect : 1; /* 1E.C43D.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + */ + unsigned int reserved0 : 13; + } bits_13; + uint16_t word_13; + } u13; +} AQ_GlobalLedProvisioning_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global General Provisioning: 1E.C440 */ +/* Global General Provisioning: 1E.C440 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global General Provisioning */ + union + { + struct + { + /*! \brief 1E.C440.0 RO Gang Load MDIO Write Only + AQ_GlobalGeneralProvisioning_APPIA.u0.bits_0.gangLoadMdioWriteOnly + + + + 1 = MDIO gang load enable + + + Notes: + This bit enables gang load operation with the address specified in Bits 8:4. */ + unsigned int gangLoadMdioWriteOnly : 1; /* 1E.C440.0 RO */ + /* 1 = MDIO gang load enable + */ + unsigned int reserved1 : 3; + /*! \brief 1E.C440.8:4 R/WPD Gang Load MDIO Address [4:0] + AQ_GlobalGeneralProvisioning_APPIA.u0.bits_0.gangLoadMdioAddress + + Provisionable Default = 0x00 + + MDIO Address to be used during gang load operation + + + Notes: + Gang load operation is used to load data into multiple PHYs all connected to the same MDIO bus. The address for gang load operation is provided by these bits (8:4), and enabling is done by writing Bit 0. Disabling of gang load mode is done by writing the See MDIO Address Reset (1E.C441.2) bit. These will revert the PHY's MDIO address back to the address provided by the MDIO Address pins. During gang load operation, MDIO reads are disabled to prevent bus contention. */ + unsigned int gangLoadMdioAddress : 5; /* 1E.C440.8:4 R/WPD Provisionable Default = 0x00 */ + /* MDIO Address to be used during gang load operation + */ + unsigned int reserved0 : 7; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global General Provisioning */ + union + { + struct + { + unsigned int reserved2 : 2; + /*! \brief 1E.C441.2 R/WSC MDIO Address Reset + AQ_GlobalGeneralProvisioning_APPIA.u1.bits_1.mdioAddressReset + + Default = 0x0 + + 1 = Load MDIO Address with the address on the MDIO address pins + + + Notes: + Used to reset the address after gang load and enable MDIO reads again. */ + unsigned int mdioAddressReset : 1; /* 1E.C441.2 R/WSC Default = 0x0 */ + /* 1 = Load MDIO Address with the address on the MDIO address pins + */ + /*! \brief 1E.C441.3 R/WPD MDIO Preamble Detection Disable + AQ_GlobalGeneralProvisioning_APPIA.u1.bits_1.mdioPreambleDetectionDisable + + Provisionable Default = 0x0 + + 1 = Suppress preamble detection on MDIO + 0 = Enable preamble detection on MDIO + + */ + unsigned int mdioPreambleDetectionDisable : 1; /* 1E.C441.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = Suppress preamble detection on MDIO + 0 = Enable preamble detection on MDIO + */ + /*! \brief 1E.C441.4 R/WPD MDIO Drive Configuration + AQ_GlobalGeneralProvisioning_APPIA.u1.bits_1.mdioDriveConfiguration + + Provisionable Default = 0x0 + + 0 = MDIO driver is in normal mode + 1 = MDIO driver is in open drain mode + + + Notes: + When the MDIO driver is in open drain mode during a read cycle, "0" data will be actively driven out of the MDIO, "1" data will set the MDIO driver in high impedance state and an external pullup will set the MDIO line to "1". The Turn-Around "0" will also be actively driven out of the MDIO, therefore in open drain mode, the Turn-Around is still "Z0". */ + unsigned int mdioDriveConfiguration : 1; /* 1E.C441.4 R/WPD Provisionable Default = 0x0 */ + /* 0 = MDIO driver is in normal mode + 1 = MDIO driver is in open drain mode + */ + unsigned int reserved1 : 8; + /*! \brief 1E.C441.D R/WPD MDIO Read MSW First Enable + AQ_GlobalGeneralProvisioning_APPIA.u1.bits_1.mdioReadMSW_FirstEnable + + Provisionable Default = 0x0 + + 1 = MSW of counter must be read first + 0 = LSW of counter must be read first + + + Notes: + This bit configures whether the MSW or LSW must be read first for counters greater than 16 bits. */ + unsigned int mdioReadMSW_FirstEnable : 1; /* 1E.C441.D R/WPD Provisionable Default = 0x0 */ + /* 1 = MSW of counter must be read first + 0 = LSW of counter must be read first + */ + /*! \brief 1E.C441.E R/WPD MDIO Broadcast Mode Enable + AQ_GlobalGeneralProvisioning_APPIA.u1.bits_1.mdioBroadcastModeEnable + + Provisionable Default = 0x0 + + 1 = Enable broadcast on Address 0 + 0 = Disable broadcast on Address 0 + + + Notes: + When set, this bit enables gang-load operation on address zero, simultaneous with normal MDIO operation. Obviously, this requires that no PHY use address 0 as its normal operating address. As well, reads on MDIO Address 0 are disabled to prevent bus contention. */ + unsigned int mdioBroadcastModeEnable : 1; /* 1E.C441.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable broadcast on Address 0 + 0 = Disable broadcast on Address 0 + */ + unsigned int reserved0 : 1; + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global General Provisioning */ + union + { + struct + { + /*! \brief 1E.C442.0 R/W Daisy Chain Reset + AQ_GlobalGeneralProvisioning_APPIA.u2.bits_2.daisyChainReset + + Default = 0x0 + + 1 = Reset the daisy chain + + + Notes: + Toggling this bit from 0 to 1 will reload the IRAM and DRAM and reset the uP. The uP will be in uP run stall during the reload process. After the reload process, uP run stall will be de-asserted adn the uP reset will be asserted. Note that before setting this bit, the See Soft Reset bit needs to be de-asserted. */ + unsigned int daisyChainReset : 1; /* 1E.C442.0 R/W Default = 0x0 */ + /* 1 = Reset the daisy chain + */ + unsigned int reserved0 : 15; + } bits_2; + uint16_t word_2; + } u2; +} AQ_GlobalGeneralProvisioning_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global NVR Provisioning: 1E.C450 */ +/* Global NVR Provisioning: 1E.C450 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global NVR Provisioning */ + union + { + struct + { + /*! \brief 1E.C450.1:0 R/WPD NVR Address Length [1:0] + AQ_GlobalNvrProvisioning_APPIA.u0.bits_0.nvrAddressLength + + Provisionable Default = 0x2 + + NVR address length ranges from 0 bytes up to 3 bytes. + + + Notes: + This sets the length of the address field used in read and write operations. Use of this field is enabled via Bit 8 of See Global NVR Provisioning 2: Address 1E.C451 . + */ + unsigned int nvrAddressLength : 2; /* 1E.C450.1:0 R/WPD Provisionable Default = 0x2 */ + /* NVR address length ranges from 0 bytes up to 3 bytes. + */ + unsigned int reserved2 : 2; + /*! \brief 1E.C450.6:4 R/WPD NVR Dummy Length [2:0] + AQ_GlobalNvrProvisioning_APPIA.u0.bits_0.nvrDummyLength + + Provisionable Default = 0x0 + + NVR dummy length ranges from 0 bytes to 4 bytes. + + + Notes: + This sets the length of the dummy field used in some maunfacturer's read status and write status operations. + */ + unsigned int nvrDummyLength : 3; /* 1E.C450.6:4 R/WPD Provisionable Default = 0x0 */ + /* NVR dummy length ranges from 0 bytes to 4 bytes. + */ + unsigned int reserved1 : 1; + /*! \brief 1E.C450.A:8 R/WPD NVR Data Length [2:0] + AQ_GlobalNvrProvisioning_APPIA.u0.bits_0.nvrDataLength + + Provisionable Default = 0x4 + + NVR data length ranges from 0 bytes to 4 bytes + + + Notes: + This sets the length of the data burst used in read and write operations. + */ + unsigned int nvrDataLength : 3; /* 1E.C450.A:8 R/WPD Provisionable Default = 0x4 */ + /* NVR data length ranges from 0 bytes to 4 bytes + */ + unsigned int reserved0 : 5; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global NVR Provisioning */ + union + { + struct + { + /*! \brief 1E.C451.7:0 R/WPD NVR Clock Divide [7:0] + AQ_GlobalNvrProvisioning_APPIA.u1.bits_1.nvrClockDivide + + Provisionable Default = 0xA0 + + NVR clock divide. Clock frequency is divided by the NVR clock divide + 1 + + */ + unsigned int nvrClockDivide : 8; /* 1E.C451.7:0 R/WPD Provisionable Default = 0xA0 */ + /* NVR clock divide. Clock frequency is divided by the NVR clock divide + 1 + */ + /*! \brief 1E.C451.8 R/WPD NVR Address Length Override + AQ_GlobalNvrProvisioning_APPIA.u1.bits_1.nvrAddressLengthOverride + + Provisionable Default = 0x0 + + 0 = NVR address length is based on the "NVR_SIZE" pin. + 1 = NVR address length is based on the See NVR Address Length [1:0] register. + + + Notes: + When the this bit = 0 and NVR_SIZE pin = 0, the NVR address length is 2 bytes. When this bit = 0 and the NVR_SIZE pin = 1, the NVR address length is 3 bytes. When this bit = 1 the NVR address length is from the See NVR Address Length [1:0] */ + unsigned int nvrAddressLengthOverride : 1; /* 1E.C451.8 R/WPD Provisionable Default = 0x0 */ + /* 0 = NVR address length is based on the "NVR_SIZE" pin. + 1 = NVR address length is based on the See NVR Address Length [1:0] register. + */ + unsigned int reserved0 : 7; + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global NVR Provisioning */ + union + { + struct + { + /*! \brief 1E.C452.0 R/W NVR Daisy Chain Disable + AQ_GlobalNvrProvisioning_APPIA.u2.bits_2.nvrDaisyChainDisable + + Default = 0x0 + + 1 = Disable the Daisy Chain + + + Notes: + When in daisy chain master mode, the daisy chain and MDIO can both access the SPI. Setting this bit to 1 will disable the dasiy chain from accessing the SPI and force it into a reset state. */ + unsigned int nvrDaisyChainDisable : 1; /* 1E.C452.0 R/W Default = 0x0 */ + /* 1 = Disable the Daisy Chain + */ + /*! \brief 1E.C452.1 R/W NVR Daisy Chain Clock Divide Override + AQ_GlobalNvrProvisioning_APPIA.u2.bits_2.nvrDaisyChainClockDivideOverride + + Default = 0x0 + + 1 = Override NVR clock divide when in daisy chain master mode + + + + Notes: + When in daisy chain master mode, the clock divide configuration is received from the flash. This bit will override the clock divide configuration from the flash with the See NVR Clock Divide [7:0] . */ + unsigned int nvrDaisyChainClockDivideOverride : 1; /* 1E.C452.1 R/W Default = 0x0 */ + /* 1 = Override NVR clock divide when in daisy chain master mode + + */ + unsigned int reserved0 : 14; + } bits_2; + uint16_t word_2; + } u2; +} AQ_GlobalNvrProvisioning_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Reserved Provisioning: 1E.C470 */ +/* Global Reserved Provisioning: 1E.C470 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Reserved Provisioning */ + union + { + struct + { + unsigned int reserved2 : 4; + /*! \brief 1E.C470.4 R/WSC Initiate Cable Diagnostics + AQ_GlobalReservedProvisioning_APPIA.u0.bits_0.initiateCableDiagnostics + + Default = 0x0 + + 1 = Perform cable diagnostics + + + Notes: + Perform cable diagnostics regardless of link state. If link is up, setting this bit will cause the link to drop while diagnostics are performed. This bit is self-clearing upon completion of the cable diagnostics. Further MDIO writes should be avoided until this bit has self-cleared, indicating completion of the diagnostic routine. */ + unsigned int initiateCableDiagnostics : 1; /* 1E.C470.4 R/WSC Default = 0x0 */ + /* 1 = Perform cable diagnostics + */ + /*! \brief 1E.C470.5 R/WSC Initiate Component Diagnostics + AQ_GlobalReservedProvisioning_APPIA.u0.bits_0.initiateComponentDiagnostics + + Default = 0x0 + + 1 = Perform component diagnostics + + + Notes: + Perform component diagnostics regardless of link state. If link is up, setting this bit will cause the link to drop while diagnostics are performed. This bit is self-clearing upon completion of the component diagnostics. Further MDIO writes should be avoided until this bit has self-cleared, indicating completion of the diagnostic routine. */ + unsigned int initiateComponentDiagnostics : 1; /* 1E.C470.5 R/WSC Default = 0x0 */ + /* 1 = Perform component diagnostics + */ + unsigned int reserved1 : 2; + unsigned int reserved0 : 5; + /*! \brief 1E.C470.E:D R/WPD Extended MDI Diagnostics Select [1:0] + AQ_GlobalReservedProvisioning_APPIA.u0.bits_0.extendedMdiDiagnosticsSelect + + Provisionable Default = 0x0 + + 0x0 = TDR Data + 0x1 = RFI Channel PSD + 0x2 = Noise PSD while the local Tx is Off + 0x3 = Noise PSD while the local Tx is On + + + Notes: + These bits select what sort of cable diagnostics to perform. For regular cable diagnostics, Bit F is set to zero, and the diagnostics are triggered by setting Bit 4. For extended diagnostics, Bit F is set to 1, and the desired extended diagnostics are selected by Bits E:D. The routine is then triggered by setting Bit 4. Each of the extended diagnostic routines present data for all for MDI pairs (A, B, C, D) consecutively, and after the data for each channel is gathered Bits F:D are reset. To get the data for the next pair, Bits F:D must be set back to the desired value (which must be the same as the initial channel). This continues until the data for all channels has been gathered. The address in memory where the data is stored is given in 1E.C802 and 1E.C804. + + For the case of PSD, the structure is as follows: + Int32 info + Int16 data[Len] + Info = Len << 16 | TxEnable << 8 | Pair (0 = A, etc.) + + For TDR: + Int32 info + Int16 tdr_A[Len] + Int16 tdr_B[Len] + Int16 tdr_C[Len] + Int16 tdr_D[Len] + + Info = Len << 16 | Channel + + TDR data is from the current pair to all other pairs. + + At the end of retrieving extended MDI diag data, the part will be reset. Conversly the only way to exit this routine once it starts is to issue a PMA reset. */ + unsigned int extendedMdiDiagnosticsSelect : 2; /* 1E.C470.E:D R/WPD Provisionable Default = 0x0 */ + /* 0x0 = TDR Data + 0x1 = RFI Channel PSD + 0x2 = Noise PSD while the local Tx is Off + 0x3 = Noise PSD while the local Tx is On + */ + /*! \brief 1E.C470.F R/WPD Diagnostics Select + AQ_GlobalReservedProvisioning_APPIA.u0.bits_0.diagnosticsSelect + + Provisionable Default = 0x0 + + 1 = Provide Extended MDI Diagnostics Information. + 0 = Provide normal cable diagnostics + + + Notes: + These bits select what sort of cable diagnostics to perform. For regular cable diagnostics, Bit F is set to zero, and the diagnostics are triggered by setting Bit 4. For extended diagnostics, Bit F is set to 1, and the desired extended diagnostics are selected by Bits E:D. The routine is then triggered by setting Bit 4. Each of the extended diagnostic routines present data for all for MDI pairs (A, B, C, D) consecutively, and after the data for each channel is gathered Bits F:D are reset. To get the data for the next pair, Bits F:D must be set back to the desired value (which must be the same as the initial channel). This continues until the data for all channels has been gathered. The address in memory where the data is stored is given in 1E.C802 and 1E.C804. + + For the case of PSD, the structure is as follows: + Int32 info + Int16 data[Len] + Info = Len << 16 | TxEnable << 8 | Pair (0 = A, etc.) + + For TDR: + Int32 info + Int16 tdr_A[Len] + Int16 tdr_B[Len] + Int16 tdr_C[Len] + Int16 tdr_D[Len] + + Info = Len << 16 | Channel + + TDR data is from the current pair to all other pairs. + + At the end of retrieving extended MDI diag data, the part will be reset. Conversly the only way to exit this routine once it starts is to issue a PMA reset. */ + unsigned int diagnosticsSelect : 1; /* 1E.C470.F R/WPD Provisionable Default = 0x0 */ + /* 1 = Provide Extended MDI Diagnostics Information. + 0 = Provide normal cable diagnostics + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Reserved Provisioning */ + union + { + struct + { + /*! \brief 1E.C471.5:0 R/WuP Daisy-Chain Hop-Count Override Value [5:0] + AQ_GlobalReservedProvisioning_APPIA.u1.bits_1.daisy_chainHop_countOverrideValue + + Default = 0x00 + + The value to use for the PHY's daisy-chain hop-count. Valid values are from 0 -> 47 + + + Notes: + Daisy-Chain Hop-Count Override should be used during MDIO boot-load operation, as the daisy-chain hop-count does not function when the daisy-chain is disabled (1E.C452.0). Setting this bit tells the processor where in the diasy-chain it is, so that the provisioning operation will function correctly. */ + unsigned int daisy_chainHop_countOverrideValue : 6; /* 1E.C471.5:0 R/WuP Default = 0x00 */ + /* The value to use for the PHY's daisy-chain hop-count. Valid values are from 0 -> 47 + */ + /*! \brief 1E.C471.6 R/WuP Enable Daisy-Chain Hop-Count Override + AQ_GlobalReservedProvisioning_APPIA.u1.bits_1.enableDaisy_chainHop_countOverride + + Default = 0x0 + + 1 = Hop-count is set by Bits 5:0 + 0 = Hop-count is determined by the daisy-chain + + + Notes: + Daisy-Chain Hop-Count Override should be used during MDIO boot-load operation, as the daisy-chain hop-count does not function when the daisy-chain is disabled (1E.C452.0). Setting this bit tells the processor where in the diasy-chain it is, so that the provisioning operation will function correctly. */ + unsigned int enableDaisy_chainHop_countOverride : 1; /* 1E.C471.6 R/WuP Default = 0x0 */ + /* 1 = Hop-count is set by Bits 5:0 + 0 = Hop-count is determined by the daisy-chain + */ + /*! \brief 1E.C471.F:7 R/WPD Reserved Provisioning 2 [8:0] + AQ_GlobalReservedProvisioning_APPIA.u1.bits_1.reservedProvisioning_2 + + Provisionable Default = 0x000 + + Reserved for future use + + */ + unsigned int reservedProvisioning_2 : 9; /* 1E.C471.F:7 R/WPD Provisionable Default = 0x000 */ + /* Reserved for future use + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Reserved Provisioning */ + union + { + struct + { + /*! \brief 1E.C472.0 R/WPDuP Enable 5th Channel RFI Cancellation + AQ_GlobalReservedProvisioning_APPIA.u2.bits_2.enable_5thChannelRfiCancellation + + Provisionable Default = 0x0 + + 1 = 5th channel and RFI cancellers operation enabled + 0 = 5th channel AFE is powered down, 5th channel digital is clock gated, RFI cancellers are disabled + + + Notes: + Note: The value of this bit at the time of Autonegotiation sets the local PHY behavior until the next time Autonegotiation occurs. */ + unsigned int enable_5thChannelRfiCancellation : 1; /* 1E.C472.0 R/WPDuP Provisionable Default = 0x0 */ + /* 1 = 5th channel and RFI cancellers operation enabled + 0 = 5th channel AFE is powered down, 5th channel digital is clock gated, RFI cancellers are disabled + */ + /*! \brief 1E.C472.1 R/WPDuP Enable XENPAK Register Space + AQ_GlobalReservedProvisioning_APPIA.u2.bits_2.enableXenpakRegisterSpace + + Provisionable Default = 0x0 + + 1 = XENPAK register space enabled + 0 = XENPAK register space disabled + + */ + unsigned int enableXenpakRegisterSpace : 1; /* 1E.C472.1 R/WPDuP Provisionable Default = 0x0 */ + /* 1 = XENPAK register space enabled + 0 = XENPAK register space disabled + */ + unsigned int reserved1 : 4; + /*! \brief 1E.C472.6 R/WPD Tunable External VDD Power Supply Present + AQ_GlobalReservedProvisioning_APPIA.u2.bits_2.tunableExternalVddPowerSupplyPresent + + Provisionable Default = 0x0 + + 1 = Tunable external VDD power supply present + 0 = No tunable external VDD power supply present + + + Notes: + + + + These bits must be set if tuning of external power supplies is desired (see Bits 7:6) */ + unsigned int tunableExternalVddPowerSupplyPresent : 1; /* 1E.C472.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = Tunable external VDD power supply present + 0 = No tunable external VDD power supply present + */ + /*! \brief 1E.C472.7 R/WPD Tunable External LVDD Power Supply Present + AQ_GlobalReservedProvisioning_APPIA.u2.bits_2.tunableExternalLvddPowerSupplyPresent + + Provisionable Default = 0x0 + + 1 = Tunable external LVDD power supply present + 0 = No tunable external LVDD power supply present + + + Notes: + + + + These bits must be set if tuning of external power supplies is desired (see Bits 7:6) */ + unsigned int tunableExternalLvddPowerSupplyPresent : 1; /* 1E.C472.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = Tunable external LVDD power supply present + 0 = No tunable external LVDD power supply present + */ + unsigned int reserved0 : 6; + /*! \brief 1E.C472.E R/WPD Enable VDD Power Supply Tuning + AQ_GlobalReservedProvisioning_APPIA.u2.bits_2.enableVddPowerSupplyTuning + + Provisionable Default = 0x0 + + 1 = Enable external VDD power supply tuning + 0 = Disable external VDD power supply tuning is disabled + + + Notes: + + + + These bits control whether the PHY attempts to tune the external VDD and LVDD power supplies via the PMBus. These bits are only operational if the external supplies are present (see Bits 7:6) */ + unsigned int enableVddPowerSupplyTuning : 1; /* 1E.C472.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable external VDD power supply tuning + 0 = Disable external VDD power supply tuning is disabled + */ + /*! \brief 1E.C472.F R/WPD Enable LVDD Power Supply Tuning + AQ_GlobalReservedProvisioning_APPIA.u2.bits_2.enableLvddPowerSupplyTuning + + Provisionable Default = 0x0 + + 1 = Enable external LVDD power supply tuning + 0 = Disable external LVDD power supply tuning is disabled + + + Notes: + + + + These bits control whether the PHY attempts to tune the external VDD and LVDD power supplies via the PMBus. These bits are only operational if the external supplies are present (see Bits 7:6) */ + unsigned int enableLvddPowerSupplyTuning : 1; /* 1E.C472.F R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable external LVDD power supply tuning + 0 = Disable external LVDD power supply tuning is disabled + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global Reserved Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global Reserved Provisioning */ + union + { + struct + { + /*! \brief 1E.C474.7:0 R/WPD Training SNR [7:0] + AQ_GlobalReservedProvisioning_APPIA.u4.bits_4.trainingSNR + + Provisionable Default = 0x00 + + SNR during 10G training on the worst channel. SNR is in steps of 0.1dB + + + Notes: + The SNR margin that is enjoyed by the worst channel, over and above the minimum SNR required to operate at a BER of 10-12. It is reported with 0.1 dB of resolution to an accuracy of 0.5 dB within the range of -12.7 dB to 12.7 dB. The number is in offset binary, with 0.0 dB represented by 0x8000. + */ + unsigned int trainingSNR : 8; /* 1E.C474.7:0 R/WPD Provisionable Default = 0x00 */ + /* SNR during 10G training on the worst channel. SNR is in steps of 0.1dB + */ + unsigned int reserved0 : 8; + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of Global Reserved Provisioning */ + union + { + struct + { + unsigned int reserved1 : 2; + /*! \brief 1E.C475.2 R/WPD Smart Power-Down Enable + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.smartPower_downEnable + + Provisionable Default = 0x0 + + 1 = Enable smart power down mode + 0 = Smart power-down mode disabled + + + Notes: + Smart power down (SPD) is the lowest power mode at which PHY is able to autonegotiate. SPD can be enabled with bit 1E.C475.2 */ + unsigned int smartPower_downEnable : 1; /* 1E.C475.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable smart power down mode + 0 = Smart power-down mode disabled + */ + /*! \brief 1E.C475.3 R/WPD Deadlock Avoidance Enable + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.deadlockAvoidanceEnable + + Provisionable Default = 0x0 + + 1 = SPD with deadlock avoidance: PHY transmits autonegotiation pulses (FLPs) at a slower rate (~ 1 FLP/ 100ms) than specified by autonegotiation standard (~1 FLP / 8.25ms). Receiver is active and able to detect the pulses. + 0 = SPD without deadlock avoidance: PHY transmitter is shut down, no autonegotiation pulses are sent on the line but the receiver is active and able to detect the pulses + + */ + unsigned int deadlockAvoidanceEnable : 1; /* 1E.C475.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = SPD with deadlock avoidance: PHY transmits autonegotiation pulses (FLPs) at a slower rate (~ 1 FLP/ 100ms) than specified by autonegotiation standard (~1 FLP / 8.25ms). Receiver is active and able to detect the pulses. + 0 = SPD without deadlock avoidance: PHY transmitter is shut down, no autonegotiation pulses are sent on the line but the receiver is active and able to detect the pulses + */ + /*! \brief 1E.C475.4 R/WPD CFR Support + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.cfrSupport + + Provisionable Default = 0x0 + + 1 = Local PHY supports Cisco Fast Retrain + 0 = Local PHY does support Cisco Fast Retrain + + */ + unsigned int cfrSupport : 1; /* 1E.C475.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = Local PHY supports Cisco Fast Retrain + 0 = Local PHY does support Cisco Fast Retrain + */ + /*! \brief 1E.C475.5 R/WPD CFR THP + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.cfrTHP + + Provisionable Default = 0x0 + + 1 = Local PHY requires local PHY to enable THP + 0 = Local PHY does not require local PHY to enable THP + + */ + unsigned int cfrTHP : 1; /* 1E.C475.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = Local PHY requires local PHY to enable THP + 0 = Local PHY does not require local PHY to enable THP + */ + /*! \brief 1E.C475.6 R/WPD CFR Extended Maxwait + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.cfrExtendedMaxwait + + Provisionable Default = 0x0 + + 1 = Local PHY requires extended maxwait + 0 = Local PHY does not require extended maxwait + + */ + unsigned int cfrExtendedMaxwait : 1; /* 1E.C475.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = Local PHY requires extended maxwait + 0 = Local PHY does not require extended maxwait + */ + /*! \brief 1E.C475.7 R/WPD CFR Disable Timer + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.cfrDisableTimer + + Provisionable Default = 0x0 + + 1 = Local PHY requires cfr_disable timer + 0 = Local PHY does not require cfr_disable timer + + */ + unsigned int cfrDisableTimer : 1; /* 1E.C475.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = Local PHY requires cfr_disable timer + 0 = Local PHY does not require cfr_disable timer + */ + /*! \brief 1E.C475.8 R/WPD CFR LP Support + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.cfrLpSupport + + Provisionable Default = 0x0 + + 1 = Link partner supports Cisco Fast Retrain + 0 = Link partner does support Cisco Fast Retrain + + */ + unsigned int cfrLpSupport : 1; /* 1E.C475.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = Link partner supports Cisco Fast Retrain + 0 = Link partner does support Cisco Fast Retrain + */ + /*! \brief 1E.C475.9 R/WPD CFR LP THP + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.cfrLpTHP + + Provisionable Default = 0x0 + + 1 = Link partner requires local PHY to enable THP + 0 = Link partner does not require local PHY to enable THP + + */ + unsigned int cfrLpTHP : 1; /* 1E.C475.9 R/WPD Provisionable Default = 0x0 */ + /* 1 = Link partner requires local PHY to enable THP + 0 = Link partner does not require local PHY to enable THP + */ + /*! \brief 1E.C475.A R/WPD CFR LP Extended Maxwait + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.cfrLpExtendedMaxwait + + Provisionable Default = 0x0 + + 1 = Link partner requires extended maxwait + 0 = Link partner does not require extended maxwait + + */ + unsigned int cfrLpExtendedMaxwait : 1; /* 1E.C475.A R/WPD Provisionable Default = 0x0 */ + /* 1 = Link partner requires extended maxwait + 0 = Link partner does not require extended maxwait + */ + /*! \brief 1E.C475.B R/WPD CFR LP Disable Timer + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.cfrLpDisableTimer + + Provisionable Default = 0x0 + + 1 = Link partner requires cfr_disable timer + 0 = Link partner does not require cfr_disable timer + + */ + unsigned int cfrLpDisableTimer : 1; /* 1E.C475.B R/WPD Provisionable Default = 0x0 */ + /* 1 = Link partner requires cfr_disable timer + 0 = Link partner does not require cfr_disable timer + */ + /*! \brief 1E.C475.C R/WPD Reserved Provisioning 6 + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.reservedProvisioning_6 + + Provisionable Default = 0x0 + + Reserved for future use + + */ + unsigned int reservedProvisioning_6 : 1; /* 1E.C475.C R/WPD Provisionable Default = 0x0 */ + /* Reserved for future use + */ + /*! \brief 1E.C475.D R/WPD Smart Power-Down Status + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.smartPower_downStatus + + Provisionable Default = 0x0 + + 1 = Smart Power-Down Active + 0 = Smart Power-Down Inactive + + */ + unsigned int smartPower_downStatus : 1; /* 1E.C475.D R/WPD Provisionable Default = 0x0 */ + /* 1 = Smart Power-Down Active + 0 = Smart Power-Down Inactive + */ + unsigned int reserved0 : 2; + } bits_5; + uint16_t word_5; + } u5; +} AQ_GlobalReservedProvisioning_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Cable Diagnostic Status: 1E.C800 */ +/* Global Cable Diagnostic Status: 1E.C800 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C800.2:0 RO Pair D Status [2:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u0.bits_0.pairDStatus + + + + (after running cable diags) + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair C + 010= Connected to Pair B + 001= Connected to Pair A + 000= OK + + OR: + + (after running component diags) + 100 = TX pin open + 011= TX bias open + 010= Capacitor short + 001= Inductor open + 000= OK + + Notes: + This bitfield reports the result, for pair D, of running either cable diagnostics or component diagnostics. */ + unsigned int pairDStatus : 3; /* 1E.C800.2:0 RO */ + /* (after running cable diags) + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair C + 010= Connected to Pair B + 001= Connected to Pair A + 000= OK + + OR: + + (after running component diags) + 100 = TX pin open + 011= TX bias open + 010= Capacitor short + 001= Inductor open + 000= OK */ + unsigned int reserved3 : 1; + /*! \brief 1E.C800.6:4 RO Pair C Status [2:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u0.bits_0.pairCStatus + + + + (after running cable diags) + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair B + 010= Connected to Pair A + 001= Connected to Pair D + 000= OK + + OR: + + (after running component diags) + 100 = TX pin open + 011= TX bias open + 010= Capacitor short + 001= Inductor open + 000= OK + + Notes: + This bitfield reports the result, for pair C, of running either cable diagnostics or component diagnostics. */ + unsigned int pairCStatus : 3; /* 1E.C800.6:4 RO */ + /* (after running cable diags) + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair B + 010= Connected to Pair A + 001= Connected to Pair D + 000= OK + + OR: + + (after running component diags) + 100 = TX pin open + 011= TX bias open + 010= Capacitor short + 001= Inductor open + 000= OK */ + unsigned int reserved2 : 1; + /*! \brief 1E.C800.A:8 RO Pair B Status [2:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u0.bits_0.pairBStatus + + + + (after running cable diags) + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair A + 010= Connected to Pair D + 001= Connected to Pair C + 000= OK + + OR: + + (after running component diags) + 100 = TX pin open + 011= TX bias open + 010= Capacitor short + 001= Inductor open + 000= OK + + Notes: + This bitfield reports the result, for pair B, of running either cable diagnostics or component diagnostics. */ + unsigned int pairBStatus : 3; /* 1E.C800.A:8 RO */ + /* (after running cable diags) + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair A + 010= Connected to Pair D + 001= Connected to Pair C + 000= OK + + OR: + + (after running component diags) + 100 = TX pin open + 011= TX bias open + 010= Capacitor short + 001= Inductor open + 000= OK */ + unsigned int reserved1 : 1; + /*! \brief 1E.C800.E:C RO Pair A Status [2:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u0.bits_0.pairAStatus + + + + (after running cable diags) + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair D + 010= Connected to Pair C + 001= Connected to Pair B + 000= OK + + OR: + + (after running component diags) + 100 = TX pin open + 011= TX bias open + 010= Capacitor short + 001= Inductor open + 000= OK + + Notes: + This bitfield reports the result, for pair A, of running either cable diagnostics or component diagnostics. */ + unsigned int pairAStatus : 3; /* 1E.C800.E:C RO */ + /* (after running cable diags) + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair D + 010= Connected to Pair C + 001= Connected to Pair B + 000= OK + + OR: + + (after running component diags) + 100 = TX pin open + 011= TX bias open + 010= Capacitor short + 001= Inductor open + 000= OK */ + unsigned int reserved0 : 1; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C801.7:0 RO Pair A Reflection #2 [7:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u1.bits_1.pairAReflection_2 + + + + The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair A + + Notes: + The distance to this reflection is given in See Global Reserved Status 1: Address 1E.C870 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairAReflection_2 : 8; /* 1E.C801.7:0 RO */ + /* The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair A */ + /*! \brief 1E.C801.F:8 RO Pair A Reflection #1 [7:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u1.bits_1.pairAReflection_1 + + + + The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair A + + Notes: + The distance to this reflection is given in See Global Reserved Status 1: Address 1E.C870 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairAReflection_1 : 8; /* 1E.C801.F:8 RO */ + /* The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair A */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C802.F:0 RO Impulse Response MSW [F:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u2.bits_2.impulseResponseMSW + + + + The MSW of the memory location that contains the start of the impulse response data for the Extended Diagnostic type in 1E.C470.E:D + + + Notes: + See 1E.C470 for more information */ + unsigned int impulseResponseMSW : 16; /* 1E.C802.F:0 RO */ + /* The MSW of the memory location that contains the start of the impulse response data for the Extended Diagnostic type in 1E.C470.E:D + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C803.7:0 RO Pair B Reflection #2 [7:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u3.bits_3.pairBReflection_2 + + + + The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair B + + Notes: + The distance to this reflection is given in See Global Reserved Status 2: Address 1E.C871 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairBReflection_2 : 8; /* 1E.C803.7:0 RO */ + /* The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair B */ + /*! \brief 1E.C803.F:8 RO Pair B Reflection #1 [7:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u3.bits_3.pairBReflection_1 + + + + The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair B + + Notes: + The distance to this reflection is given in See Global Reserved Status 2: Address 1E.C871 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairBReflection_1 : 8; /* 1E.C803.F:8 RO */ + /* The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair B */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C804.F:0 RO Impulse Response LSW [F:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u4.bits_4.impulseResponseLSW + + + + The LSW of the memory location that contains the start of the impulse response data for the Extended Diagnostic type specified in 1E.C470.E:D + + + Notes: + See 1E.C470 for more information */ + unsigned int impulseResponseLSW : 16; /* 1E.C804.F:0 RO */ + /* The LSW of the memory location that contains the start of the impulse response data for the Extended Diagnostic type specified in 1E.C470.E:D + */ + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C805.7:0 RO Pair C Reflection #2 [7:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u5.bits_5.pairCReflection_2 + + + + The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair C + + Notes: + The distance to this reflection is given in See Global Reserved Status 3: Address 1E.C872 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairCReflection_2 : 8; /* 1E.C805.7:0 RO */ + /* The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair C */ + /*! \brief 1E.C805.F:8 RO Pair C Reflection #1 [7:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u5.bits_5.pairCReflection_1 + + + + The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair C + + Notes: + The distance to this reflection is given in See Global Reserved Status 3: Address 1E.C872 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairCReflection_1 : 8; /* 1E.C805.F:8 RO */ + /* The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair C */ + } bits_5; + uint16_t word_5; + } u5; + /*! \brief Union for bit and word level access of word 6 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C806.F:0 RO Reserved 1 [F:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u6.bits_6.reserved_1 + + + + Reserved for future use + + */ + unsigned int reserved_1 : 16; /* 1E.C806.F:0 RO */ + /* Reserved for future use + */ + } bits_6; + uint16_t word_6; + } u6; + /*! \brief Union for bit and word level access of word 7 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C807.7:0 RO Pair D Reflection #2 [7:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u7.bits_7.pairDReflection_2 + + + + The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair D + + Notes: + The distance to this reflection is given in See Global Reserved Status 4: Address 1E.C873 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairDReflection_2 : 8; /* 1E.C807.7:0 RO */ + /* The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair D */ + /*! \brief 1E.C807.F:8 RO Pair D Reflection #1 [7:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u7.bits_7.pairDReflection_1 + + + + The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair D + + Notes: + The distance to this reflection is given in See Global Reserved Status 4: Address 1E.C873 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairDReflection_1 : 8; /* 1E.C807.F:8 RO */ + /* The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair D */ + } bits_7; + uint16_t word_7; + } u7; + /*! \brief Union for bit and word level access of word 8 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C808.F:0 RO Reserved 2[F:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u8.bits_8.reserved_2 + + + + Reserved for future use + + */ + unsigned int reserved_2 : 16; /* 1E.C808.F:0 RO */ + /* Reserved for future use + */ + } bits_8; + uint16_t word_8; + } u8; +} AQ_GlobalCableDiagnosticStatus_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Thermal Status: 1E.C820 */ +/* Global Thermal Status: 1E.C820 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Thermal Status */ + union + { + struct + { + /*! \brief 1E.C820.F:0 RO Temperature [F:0] + AQ_GlobalThermalStatus_APPIA.u0.bits_0.temperature + + + + [F:0] of temperature + + + Notes: + 2's complement value with the LSB representing 1/256 of a degree Celsius. This corresponds to -40 degreesC = 0xD800. Default is 70 degreesC. This is a mirror of the XENPAK register 1.A060 - 1.A061. The mirror is performed in H/W. */ + unsigned int temperature : 16; /* 1E.C820.F:0 RO */ + /* [F:0] of temperature + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Thermal Status */ + union + { + struct + { + /*! \brief 1E.C821.0 RO Temperature Ready + AQ_GlobalThermalStatus_APPIA.u1.bits_1.temperatureReady + + + + 1 = Temperature measurement is valid + + + Notes: + This is a mirror of the XENPAK register 1.A06E. */ + unsigned int temperatureReady : 1; /* 1E.C821.0 RO */ + /* 1 = Temperature measurement is valid + */ + unsigned int reserved0 : 15; + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalThermalStatus_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global General Status: 1E.C830 */ +/* Global General Status: 1E.C830 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global General Status */ + union + { + struct + { + unsigned int reserved1 : 11; + /*! \brief 1E.C830.B RO Low Temperature Warning State + AQ_GlobalGeneralStatus_APPIA.u0.bits_0.lowTemperatureWarningState + + + + 1 = Low temperature warning threshold has been exceeded + + Notes: + In XENPAK mode, F/W will copy this register to the 1.A074.6 register. + + */ + unsigned int lowTemperatureWarningState : 1; /* 1E.C830.B RO */ + /* 1 = Low temperature warning threshold has been exceeded */ + /*! \brief 1E.C830.C RO High Temperature Warning State + AQ_GlobalGeneralStatus_APPIA.u0.bits_0.highTemperatureWarningState + + + + 1 = High temperature warning threshold has been exceeded + + Notes: + In XENPAK mode, F/W will copy this register to the 1.A074.7 register. + + */ + unsigned int highTemperatureWarningState : 1; /* 1E.C830.C RO */ + /* 1 = High temperature warning threshold has been exceeded */ + /*! \brief 1E.C830.D RO Low Temperature Failure State + AQ_GlobalGeneralStatus_APPIA.u0.bits_0.lowTemperatureFailureState + + + + 1 = Low temperature failure threshold has been exceeded + + Notes: + In XENPAK mode, F/W will copy this register to the 1.A070.6 register. + + */ + unsigned int lowTemperatureFailureState : 1; /* 1E.C830.D RO */ + /* 1 = Low temperature failure threshold has been exceeded */ + /*! \brief 1E.C830.E RO High Temperature Failure State + AQ_GlobalGeneralStatus_APPIA.u0.bits_0.highTemperatureFailureState + + + + 1 = High temperature failure threshold has been exceeded + + Notes: + In XENPAK mode, F/W will copy this register to the 1.A070.7 register. + + */ + unsigned int highTemperatureFailureState : 1; /* 1E.C830.E RO */ + /* 1 = High temperature failure threshold has been exceeded */ + unsigned int reserved0 : 1; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global General Status */ + union + { + struct + { + unsigned int reserved0 : 15; + /*! \brief 1E.C831.F RO Processor Intensive MDIO Operation In- Progress + AQ_GlobalGeneralStatus_APPIA.u1.bits_1.processorIntensiveMdioOperationIn_Progress + + + + 1 = PHY microprocessor is busy with a processor-intensive MDIO operation + 0 = Processor-intensive MDIO operation completed + + + Notes: + This bit should may be used with certain processor-intensive MDIO commands (such as Loopbacks, Test Modes, Low power modes, Tx-Disable, Restart autoneg, Cable Diagnostics, etc.) that take longer than an MDIO cycle to complete. Upon receiving an MDIO command that involves the PHY's microprocessor, this bit is set, and when the command is completed, this bit is cleared. + + NOTE!!! This bit should be checked only after 1 ms of issuing a processor-intensive MDIO operation. + + The list of operations that set this bit are as follows: + + 1.0.0, PMA Loopback + 1.0.B, Low power mode + 1.9.4:0, Tx Disable + 1.84, 10G Test modes + 1.8000.5, XENPAK Control + 1.9000, XENPAK Rx Fault Enable + 1.9002, XENPAK Alarm Enable + 1.E400.F, External loopback + 3.0.B, Low power mode + 3.0.E, System PCS loopback + 3.C471.5, PRBS Test + 3.C471.6, PRBS Test + 3.E471.5, PRBS Test + 3.E471.6, PRBS Test + 4.0.B, Low power mode + 4.0.E, PHY-XS network loopback + 4.C440, Output clock control, Load SERDES parameters + 4.F802.E, System loopback + 4.C444.F:B, Loopback Control + 4.C444.4:2, Packet generation + 4.C445.C, SERDES calibration + 7.0.9, Restart autonegotiation + 1D.C280, 1G/100M Network loopback + 1D.C500, 1G System loopback + 1D.C501, 1G / 100M Test modes */ + unsigned int processorIntensiveMdioOperationIn_Progress : 1; /* 1E.C831.F RO */ + /* 1 = PHY microprocessor is busy with a processor-intensive MDIO operation + 0 = Processor-intensive MDIO operation completed + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalGeneralStatus_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Pin Status: 1E.C840 */ +/* Global Pin Status: 1E.C840 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Pin Status */ + union + { + struct + { + /*! \brief 1E.C840.5:0 RO LED Pullup State [5:0] + AQ_GlobalPinStatus_APPIA.u0.bits_0.ledPullupState + + + + 1 = LED output pin is pulled high + 0 = LED output pin is pulled low + + */ + unsigned int ledPullupState : 6; /* 1E.C840.5:0 RO */ + /* 1 = LED output pin is pulled high + 0 = LED output pin is pulled low + */ + unsigned int reserved3 : 1; + /*! \brief 1E.C840.7 RO Tx Enable + AQ_GlobalPinStatus_APPIA.u0.bits_0.txEnable + + + + Current Value of Tx Enable pin + + + Notes: + 0 = Disable Transmitter */ + unsigned int txEnable : 1; /* 1E.C840.7 RO */ + /* Current Value of Tx Enable pin + */ + unsigned int reserved2 : 1; + /*! \brief 1E.C840.9 RO Package Connectivity + AQ_GlobalPinStatus_APPIA.u0.bits_0.packageConnectivity + + + + Value of the package connection pin + + */ + unsigned int packageConnectivity : 1; /* 1E.C840.9 RO */ + /* Value of the package connection pin + */ + unsigned int reserved1 : 3; + /*! \brief 1E.C840.E:D RO MDIO Boot Load [1:0] + AQ_GlobalPinStatus_APPIA.u0.bits_0.mdioBootLoad + + + + Value of MDIO Boot Load pins + + 0x3 = PHY #0 Slave Daisy Chain Boot + 0x2 = PHY #0 Master Daisy Chain Boot from Flash + 0x1 = MDIO Boot Load + 0x0 = Boot from Flash (PHY #0 only) + + + Notes: + NOTES: + + PHY #0 is the primary PHY, and PHY #1 is the secondary PHY + + PHY #1 is always in Slave Daisy Chain Boot from Flash when set to 0x2 or 0x3. */ + unsigned int mdioBootLoad : 2; /* 1E.C840.E:D RO */ + /* Value of MDIO Boot Load pins + + 0x3 = PHY #0 Slave Daisy Chain Boot + 0x2 = PHY #0 Master Daisy Chain Boot from Flash + 0x1 = MDIO Boot Load + 0x0 = Boot from Flash (PHY #0 only) + */ + unsigned int reserved0 : 1; + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalPinStatus_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Daisy Chain Status: 1E.C842 */ +/* Global Daisy Chain Status: 1E.C842 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Daisy Chain Status */ + union + { + struct + { + /*! \brief 1E.C842.F:0 RO Rx Daisy Chain Calculated CRC [F:0] + AQ_GlobalDaisyChainStatus_APPIA.u0.bits_0.rxDaisyChainCalculatedCrc + + + + Rx Daisy Chain Calculated CRC + + + Notes: + This is the calculated daisy chain CRC. */ + unsigned int rxDaisyChainCalculatedCrc : 16; /* 1E.C842.F:0 RO */ + /* Rx Daisy Chain Calculated CRC + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalDaisyChainStatus_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Fault Message: 1E.C850 */ +/* Global Fault Message: 1E.C850 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Fault Message */ + union + { + struct + { + /*! \brief 1E.C850.F:0 RO Message [F:0] + AQ_GlobalFaultMessage_APPIA.u0.bits_0.message + + + + Error code describing fault + + Notes: + Code 0x8001: Firmware not compatible with chip architecture. This fault occurs when firmware compiled for a different Tensilica core is loaded. + Code 0x8002: VCO calibration failed. This occurs when the main PLLs on chip fail to lock: this is not possible to trigger. + Code 0x8003: XAUI calibration failed. This occurs when the XAUI PLLs fail to lock: this is not possible to trigger. + Code 0x8004: Failed to set operating voltages via PMBus. This only occurs when the processor has control over power supply voltage via an attached PMBus device and there is a protocol error on the I2C bus: this is not possible to trigger. + Code 0x8005: Unexpected device ID. This occurs if the device ID programmed into the internal E-Fuse registers in not valid: this is not possible to trigger. + Code 0x8006: Computed checksum does not match expected checksum. This occurs when the FLASH checksum check performed at boot time fails. This only occurs when the system boots from FLASH. + Code 0x8007: Detected a bit error in static memory. To trigger, corrupt one of the static regions. + Code 0xC001: Illegal Instruction exception. This occurs when the processor attempts to execute an illegal instruction. To trigger this, write an illegal instruction to program memory. It's possible that the bit error check will trigger before the illegal instruction is executed. + Code 0xC002 Instruction Fetch Error. Internal physical address or a data error during instruction fetch: this is not possible to trigger. + Code 0xC003 Load Store Error. Internal physical address or data error during load store operation: this is not possible to trigger.. + Code 0xC004 Privileged Instruction. Attempt to execute a privileged operation without sufficient privilege: this is not possible to trigger. + Code 0xC005 Unaligned Load or Store. Attempt to load or store data at an address which cannot be handled due to alignment: this is not possible to trigger. + Code 0xC006 Instruction fetch from prohibited space: this is not possible to trigger. + Code 0xC007 Data load from prohibited space: this is not possible to trigger. + Code 0xC008 Data store into prohibited space: this is not possible to trigger. */ + unsigned int message : 16; /* 1E.C850.F:0 RO */ + /* Error code describing fault */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalFaultMessage_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Primary Status: 1E.C851 */ +/* Global Primary Status: 1E.C851 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Primary Status */ + union + { + struct + { + /*! \brief 1E.C851.0 RO Primary Status + AQ_GlobalPrimaryStatus_APPIA.u0.bits_0.primaryStatus + + + + 1 = PHY is the primary PHY + 0 = PHY is is secondary PHY + + */ + unsigned int primaryStatus : 1; /* 1E.C851.0 RO */ + /* 1 = PHY is the primary PHY + 0 = PHY is is secondary PHY + */ + unsigned int reserved0 : 15; + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalPrimaryStatus_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Cable Diagnostic Impedance: 1E.C880 */ +/* Global Cable Diagnostic Impedance: 1E.C880 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Cable Diagnostic Impedance */ + union + { + struct + { + /*! \brief 1E.C880.2:0 RO Pair A Reflection #4 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u0.bits_0.pairAReflection_4 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the fourth worst reflection on Pair A. The corresponding length of this reflection from the PHY is given in See Global Power Control - Address 1E.21 */ + unsigned int pairAReflection_4 : 3; /* 1E.C880.2:0 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C880.3 RO Reserved 4 + AQ_GlobalCableDiagnosticImpedance_APPIA.u0.bits_0.reserved_4 + + + + Reserved for future use + + */ + unsigned int reserved_4 : 1; /* 1E.C880.3 RO */ + /* Reserved for future use + */ + /*! \brief 1E.C880.6:4 RO Pair A Reflection #3 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u0.bits_0.pairAReflection_3 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the third worst reflection on Pair A. The corresponding length of this reflection from the PHY is given in See Global Power Control - Address 1E.21 */ + unsigned int pairAReflection_3 : 3; /* 1E.C880.6:4 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C880.7 RO Reserved 3 + AQ_GlobalCableDiagnosticImpedance_APPIA.u0.bits_0.reserved_3 + + + + Reserved for future use + + */ + unsigned int reserved_3 : 1; /* 1E.C880.7 RO */ + /* Reserved for future use + */ + /*! \brief 1E.C880.A:8 RO Pair A Reflection #2 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u0.bits_0.pairAReflection_2 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the second worst reflection on Pair A. The corresponding length of this reflection from the PHY is given in See Global Power Control - Address 1E.21 */ + unsigned int pairAReflection_2 : 3; /* 1E.C880.A:8 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C880.B RO Reserved 2 + AQ_GlobalCableDiagnosticImpedance_APPIA.u0.bits_0.reserved_2 + + + + Reserved for future use + + */ + unsigned int reserved_2 : 1; /* 1E.C880.B RO */ + /* Reserved for future use + */ + /*! \brief 1E.C880.E:C RO Pair A Reflection #1 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u0.bits_0.pairAReflection_1 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the first worst reflection on Pair A. The corresponding length of this reflection from the PHY is given in See Global Power Control - Address 1E.21 */ + unsigned int pairAReflection_1 : 3; /* 1E.C880.E:C RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C880.F RO Reserved 1 + AQ_GlobalCableDiagnosticImpedance_APPIA.u0.bits_0.reserved_1 + + + + Reserved for future use + + */ + unsigned int reserved_1 : 1; /* 1E.C880.F RO */ + /* Reserved for future use + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Cable Diagnostic Impedance */ + union + { + struct + { + /*! \brief 1E.C881.2:0 RO Pair B Reflection #4 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u1.bits_1.pairBReflection_4 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the fourth worst reflection on Pair B. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 2 - Address 1E.32 - 1E.33 */ + unsigned int pairBReflection_4 : 3; /* 1E.C881.2:0 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C881.3 RO Reserved 8 + AQ_GlobalCableDiagnosticImpedance_APPIA.u1.bits_1.reserved_8 + + + + Reserved for future use + + */ + unsigned int reserved_8 : 1; /* 1E.C881.3 RO */ + /* Reserved for future use + */ + /*! \brief 1E.C881.6:4 RO Pair B Reflection #3 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u1.bits_1.pairBReflection_3 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the third worst reflection on Pair B. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 2 - Address 1E.32 - 1E.33 */ + unsigned int pairBReflection_3 : 3; /* 1E.C881.6:4 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C881.7 RO Reserved 7 + AQ_GlobalCableDiagnosticImpedance_APPIA.u1.bits_1.reserved_7 + + + + Reserved for future use + + */ + unsigned int reserved_7 : 1; /* 1E.C881.7 RO */ + /* Reserved for future use + */ + /*! \brief 1E.C881.A:8 RO Pair B Reflection #2 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u1.bits_1.pairBReflection_2 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the second worst reflection on Pair B. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 2 - Address 1E.32 - 1E.33 */ + unsigned int pairBReflection_2 : 3; /* 1E.C881.A:8 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C881.B RO Reserved 6 + AQ_GlobalCableDiagnosticImpedance_APPIA.u1.bits_1.reserved_6 + + + + Reserved for future use + + */ + unsigned int reserved_6 : 1; /* 1E.C881.B RO */ + /* Reserved for future use + */ + /*! \brief 1E.C881.E:C RO Pair B Reflection #1 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u1.bits_1.pairBReflection_1 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the first worst reflection on Pair B. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 2 - Address 1E.32 - 1E.33 */ + unsigned int pairBReflection_1 : 3; /* 1E.C881.E:C RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C881.F RO Reserved 5 + AQ_GlobalCableDiagnosticImpedance_APPIA.u1.bits_1.reserved_5 + + + + Reserved for future use + + */ + unsigned int reserved_5 : 1; /* 1E.C881.F RO */ + /* Reserved for future use + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Cable Diagnostic Impedance */ + union + { + struct + { + /*! \brief 1E.C882.2:0 RO Pair C Reflection #4 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u2.bits_2.pairCReflection_4 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the fourth worst reflection on Pair C. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.33 */ + unsigned int pairCReflection_4 : 3; /* 1E.C882.2:0 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C882.3 RO Reserved 12 + AQ_GlobalCableDiagnosticImpedance_APPIA.u2.bits_2.reserved_12 + + + + Reserved for future use + + */ + unsigned int reserved_12 : 1; /* 1E.C882.3 RO */ + /* Reserved for future use + */ + /*! \brief 1E.C882.6:4 RO Pair C Reflection #3 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u2.bits_2.pairCReflection_3 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the third worst reflection on Pair C. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.33 */ + unsigned int pairCReflection_3 : 3; /* 1E.C882.6:4 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C882.7 RO Reserved 11 + AQ_GlobalCableDiagnosticImpedance_APPIA.u2.bits_2.reserved_11 + + + + Reserved for future use + + */ + unsigned int reserved_11 : 1; /* 1E.C882.7 RO */ + /* Reserved for future use + */ + /*! \brief 1E.C882.A:8 RO Pair C Reflection #2 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u2.bits_2.pairCReflection_2 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the second worst reflection on Pair C. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.33 */ + unsigned int pairCReflection_2 : 3; /* 1E.C882.A:8 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C882.B RO Reserved 10 + AQ_GlobalCableDiagnosticImpedance_APPIA.u2.bits_2.reserved_10 + + + + Reserved for future use + + */ + unsigned int reserved_10 : 1; /* 1E.C882.B RO */ + /* Reserved for future use + */ + /*! \brief 1E.C882.E:C RO Pair C Reflection #1 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u2.bits_2.pairCReflection_1 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the first worst reflection on Pair C. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.33 */ + unsigned int pairCReflection_1 : 3; /* 1E.C882.E:C RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C882.F RO Reserved 9 + AQ_GlobalCableDiagnosticImpedance_APPIA.u2.bits_2.reserved_9 + + + + Reserved for future use + + */ + unsigned int reserved_9 : 1; /* 1E.C882.F RO */ + /* Reserved for future use + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global Cable Diagnostic Impedance */ + union + { + struct + { + /*! \brief 1E.C883.2:0 RO Pair D Reflection #4 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u3.bits_3.pairDReflection_4 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the fourth worst reflection on Pair D. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.34 - 1E.35 */ + unsigned int pairDReflection_4 : 3; /* 1E.C883.2:0 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C883.3 RO Reserved 16 + AQ_GlobalCableDiagnosticImpedance_APPIA.u3.bits_3.reserved_16 + + + + Reserved for future use + + */ + unsigned int reserved_16 : 1; /* 1E.C883.3 RO */ + /* Reserved for future use + */ + /*! \brief 1E.C883.6:4 RO Pair D Reflection #3 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u3.bits_3.pairDReflection_3 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the third worst reflection on Pair D. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.34 - 1E.35 */ + unsigned int pairDReflection_3 : 3; /* 1E.C883.6:4 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C883.7 RO Reserved 15 + AQ_GlobalCableDiagnosticImpedance_APPIA.u3.bits_3.reserved_15 + + + + Reserved for future use + + */ + unsigned int reserved_15 : 1; /* 1E.C883.7 RO */ + /* Reserved for future use + */ + /*! \brief 1E.C883.A:8 RO Pair D Reflection #2 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u3.bits_3.pairDReflection_2 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the second worst reflection on Pair D. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.34 - 1E.35 */ + unsigned int pairDReflection_2 : 3; /* 1E.C883.A:8 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C883.B RO Reserved 14 + AQ_GlobalCableDiagnosticImpedance_APPIA.u3.bits_3.reserved_14 + + + + Reserved for future use + + */ + unsigned int reserved_14 : 1; /* 1E.C883.B RO */ + /* Reserved for future use + */ + /*! \brief 1E.C883.E:C RO Pair D Reflection #1 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u3.bits_3.pairDReflection_1 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the first worst reflection on Pair D. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.34 - 1E.35 */ + unsigned int pairDReflection_1 : 3; /* 1E.C883.E:C RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C883.F RO Reserved 13 + AQ_GlobalCableDiagnosticImpedance_APPIA.u3.bits_3.reserved_13 + + + + Reserved for future use + + */ + unsigned int reserved_13 : 1; /* 1E.C883.F RO */ + /* Reserved for future use + */ + } bits_3; + uint16_t word_3; + } u3; +} AQ_GlobalCableDiagnosticImpedance_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Status: 1E.C884 */ +/* Global Status: 1E.C884 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Status */ + union + { + struct + { + /*! \brief 1E.C884.7:0 RO Cable Length [7:0] + AQ_GlobalStatus_APPIA.u0.bits_0.cableLength + + + + The estimated length of the cable in meters + + + Notes: + The length of the cable shown here is estimated from the cable diagnostic engine and should be accurate to +/-1m. */ + unsigned int cableLength : 8; /* 1E.C884.7:0 RO */ + /* The estimated length of the cable in meters + */ + /*! \brief 1E.C884.F:8 RO Reserved Status 0 [7:0] + AQ_GlobalStatus_APPIA.u0.bits_0.reservedStatus_0 + + + + Reserved for future use + + */ + unsigned int reservedStatus_0 : 8; /* 1E.C884.F:8 RO */ + /* Reserved for future use + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalStatus_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Reserved Status: 1E.C885 */ +/* Global Reserved Status: 1E.C885 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Reserved Status */ + union + { + struct + { + /*! \brief 1E.C885.7:0 ROSPD ROM Revision [7:0] + AQ_GlobalReservedStatus_APPIA.u0.bits_0.romRevision + + Provisionable Default = 0x00 + + ROM Revision Number + + + Notes: + Customers may receive multiple ROM images that differ only in their provisioning. This field is used to differentiate those images. This field is used in conjunction with the firmware major and minor revision numbers to uniquely identify ROM images. */ + unsigned int romRevision : 8; /* 1E.C885.7:0 ROSPD Provisionable Default = 0x00 */ + /* ROM Revision Number + */ + /*! \brief 1E.C885.9:8 ROSPD XENPAK NVR Status [1:0] + AQ_GlobalReservedStatus_APPIA.u0.bits_0.xenpakNvrStatus + + Provisionable Default = 0x0 + + Status of XENPAK NVR: + 0: NVR not enabled + 1: Last NVR operation succeeded + 2: Last NVR operation failed + 3: Reserved + + + Notes: + XENPAK register space is mirrored in NVR (SPI ROM). This register indicates the status of the last NVR operation. */ + unsigned int xenpakNvrStatus : 2; /* 1E.C885.9:8 ROSPD Provisionable Default = 0x0 */ + /* Status of XENPAK NVR: + 0: NVR not enabled + 1: Last NVR operation succeeded + 2: Last NVR operation failed + 3: Reserved + */ + /*! \brief 1E.C885.F:A RO Nearly Seconds MSW[5:0] + AQ_GlobalReservedStatus_APPIA.u0.bits_0.nearlySecondsMSW + + + + Bits 16 to 21 of the 22 bit "Nearly Seconds" uptime counter. + + + Notes: + The "Nearly Seconds" counter is incremented every 1024 milliseconds. */ + unsigned int nearlySecondsMSW : 6; /* 1E.C885.F:A RO */ + /* Bits 16 to 21 of the 22 bit "Nearly Seconds" uptime counter. + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Reserved Status */ + union + { + struct + { + /*! \brief 1E.C886.F:0 RO Nearly Seconds LSW[F:0] + AQ_GlobalReservedStatus_APPIA.u1.bits_1.nearlySecondsLSW + + + + Bits 0 to 15 of the 22 bit "Nearly Seconds" uptime counter. + + + Notes: + The "Nearly Seconds" counter is incremented every 1024 milliseconds. */ + unsigned int nearlySecondsLSW : 16; /* 1E.C886.F:0 RO */ + /* Bits 0 to 15 of the 22 bit "Nearly Seconds" uptime counter. + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalReservedStatus_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Alarms: 1E.CC00 */ +/* Global Alarms: 1E.CC00 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Alarms */ + union + { + struct + { + /*! \brief 1E.CC00.0 LH Reserved Alarm D + AQ_GlobalAlarms_APPIA.u0.bits_0.reservedAlarmD + + + + Reserved for future use + + */ + unsigned int reservedAlarmD : 1; /* 1E.CC00.0 LH */ + /* Reserved for future use + */ + /*! \brief 1E.CC00.1 LH Reserved Alarm C + AQ_GlobalAlarms_APPIA.u0.bits_0.reservedAlarmC + + + + Reserved for future use + + */ + unsigned int reservedAlarmC : 1; /* 1E.CC00.1 LH */ + /* Reserved for future use + */ + /*! \brief 1E.CC00.2 LH Reserved Alarm B + AQ_GlobalAlarms_APPIA.u0.bits_0.reservedAlarmB + + + + Reserved for future use + + */ + unsigned int reservedAlarmB : 1; /* 1E.CC00.2 LH */ + /* Reserved for future use + */ + /*! \brief 1E.CC00.3 LH Reserved Alarm A + AQ_GlobalAlarms_APPIA.u0.bits_0.reservedAlarmA + + + + Reserved for future use + + */ + unsigned int reservedAlarmA : 1; /* 1E.CC00.3 LH */ + /* Reserved for future use + */ + /*! \brief 1E.CC00.4 LH Device Fault + AQ_GlobalAlarms_APPIA.u0.bits_0.deviceFault + + + + 1 = Fault + + Notes: + When set, a fault has been detected by the uP and the associated 16 bit error code is visible in See Global Configuration Fault Message: Address 1E.C850 */ + unsigned int deviceFault : 1; /* 1E.CC00.4 LH */ + /* 1 = Fault */ + unsigned int reserved2 : 1; + /*! \brief 1E.CC00.6 LH Reset completed + AQ_GlobalAlarms_APPIA.u0.bits_0.resetCompleted + + + + 1 = Chip wide reset completed + + Notes: + This bit is set by the microprocessor when it has completed it's initialization sequence. This bit is mirrored in 1.CC02.0 */ + unsigned int resetCompleted : 1; /* 1E.CC00.6 LH */ + /* 1 = Chip wide reset completed */ + unsigned int reserved1 : 4; + /*! \brief 1E.CC00.B LH Low Temperature Warning + AQ_GlobalAlarms_APPIA.u0.bits_0.lowTemperatureWarning + + + + 1 = Low temperature warning threshold has been exceeded + + + Notes: + + + + + These bits mirror the matching bit in 1.A070 and 1.A074. These bits are driven by Bits E:B in See Global General Status 1: Address 1E.C830 . */ + unsigned int lowTemperatureWarning : 1; /* 1E.CC00.B LH */ + /* 1 = Low temperature warning threshold has been exceeded + */ + /*! \brief 1E.CC00.C LH High Temperature Warning + AQ_GlobalAlarms_APPIA.u0.bits_0.highTemperatureWarning + + + + 1 = High temperature warning threshold has been exceeded + + + Notes: + + + + + These bits mirror the matching bit in 1.A070 and 1.A074. These bits are driven by Bits E:B in See Global General Status 1: Address 1E.C830 . */ + unsigned int highTemperatureWarning : 1; /* 1E.CC00.C LH */ + /* 1 = High temperature warning threshold has been exceeded + */ + /*! \brief 1E.CC00.D LH Low Temperature Failure + AQ_GlobalAlarms_APPIA.u0.bits_0.lowTemperatureFailure + + + + 1 = Low temperature failure threshold has been exceeded + + + Notes: + + + + + These bits mirror the matching bit in 1.A070 and 1.A074. These bits are driven by Bits E:B in See Global General Status 1: Address 1E.C830 . */ + unsigned int lowTemperatureFailure : 1; /* 1E.CC00.D LH */ + /* 1 = Low temperature failure threshold has been exceeded + */ + /*! \brief 1E.CC00.E LH High Temperature Failure + AQ_GlobalAlarms_APPIA.u0.bits_0.highTemperatureFailure + + + + 1 = High temperature failure threshold has been exceeded + + + Notes: + + + + + These bits mirror the matching bit in 1.A070 and 1.A074. These bits are driven by Bits E:B in See Global General Status 1: Address 1E.C830 . */ + unsigned int highTemperatureFailure : 1; /* 1E.CC00.E LH */ + /* 1 = High temperature failure threshold has been exceeded + */ + unsigned int reserved0 : 1; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Alarms */ + union + { + struct + { + /*! \brief 1E.CC01.0 LH Diagnostic Alarm + AQ_GlobalAlarms_APPIA.u1.bits_1.diagnosticAlarm + + + + 1 = Alarm triggered by a write to 1E.C470.7 + + + Notes: + A diagnostic alarm use to test system alarm circuitry */ + unsigned int diagnosticAlarm : 1; /* 1E.CC01.0 LH */ + /* 1 = Alarm triggered by a write to 1E.C470.7 + */ + unsigned int reserved1 : 6; + /*! \brief 1E.CC01.7 LH MDIO Command Handling Overflow + AQ_GlobalAlarms_APPIA.u1.bits_1.mdioCommandHandlingOverflow + + + + 1 = PHY was issued more MDIO requests than it could service in it's request buffer + + + Notes: + Assertion of this bit means that more MDIO commands were issued than FW could handle. */ + unsigned int mdioCommandHandlingOverflow : 1; /* 1E.CC01.7 LH */ + /* 1 = PHY was issued more MDIO requests than it could service in it's request buffer + */ + /*! \brief 1E.CC01.C:8 LH Reserved Alarms [4:0] + AQ_GlobalAlarms_APPIA.u1.bits_1.reservedAlarms + + + + Reserved for future use + + */ + unsigned int reservedAlarms : 5; /* 1E.CC01.C:8 LH */ + /* Reserved for future use + */ + /*! \brief 1E.CC01.D RO XENPAK Alarm + AQ_GlobalAlarms_APPIA.u1.bits_1.xenpakAlarm + + + + 1 = XENPAK Alarm + + + Notes: + This alarm is performed by H/W. */ + unsigned int xenpakAlarm : 1; /* 1E.CC01.D RO */ + /* 1 = XENPAK Alarm + */ + /*! \brief 1E.CC01.E LH Smart Power-Down Entered + AQ_GlobalAlarms_APPIA.u1.bits_1.smartPower_downEntered + + + + 1 = Smart Power-Down State Entered + + + Notes: + When this bit is set, it indicates that the Smart Power-Down state was entered */ + unsigned int smartPower_downEntered : 1; /* 1E.CC01.E LH */ + /* 1 = Smart Power-Down State Entered + */ + unsigned int reserved0 : 1; + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Alarms */ + union + { + struct + { + /*! \brief 1E.CC02.0 LH Watchdog Timer Alarm + AQ_GlobalAlarms_APPIA.u2.bits_2.watchdogTimerAlarm + + + + 1 = Watchdog timer alarm + + */ + unsigned int watchdogTimerAlarm : 1; /* 1E.CC02.0 LH */ + /* 1 = Watchdog timer alarm + */ + /*! \brief 1E.CC02.1 LH MDIO Timeout Error + AQ_GlobalAlarms_APPIA.u2.bits_2.mdioTimeoutError + + + + 1 = MDIO timeout detected + + */ + unsigned int mdioTimeoutError : 1; /* 1E.CC02.1 LH */ + /* 1 = MDIO timeout detected + */ + /*! \brief 1E.CC02.2 LH MDIO MMD Error + AQ_GlobalAlarms_APPIA.u2.bits_2.mdioMMD_Error + + + + 1 = Invalid MMD address detected + + */ + unsigned int mdioMMD_Error : 1; /* 1E.CC02.2 LH */ + /* 1 = Invalid MMD address detected + */ + unsigned int reserved2 : 2; + /*! \brief 1E.CC02.5 LRF Tx Enable State Change + AQ_GlobalAlarms_APPIA.u2.bits_2.txEnableStateChange + + + + 1 = TX_EN pin has changed state + + */ + unsigned int txEnableStateChange : 1; /* 1E.CC02.5 LRF */ + /* 1 = TX_EN pin has changed state + */ + unsigned int reserved1 : 2; + /*! \brief 1E.CC02.9:8 LH uP IRAM Parity Error [1:0] + AQ_GlobalAlarms_APPIA.u2.bits_2.upIramParityError + + + + 1 = Parity error detected in the uP IRAM + + + Notes: + Bit 0 indicates a parity error was detected in the uP IRAM but was corrected. + Bit 1 indicates a multiple parity errors were detected in the uP IRAM and could not be corrected. + The uP IRAM is protected with ECC. */ + unsigned int upIramParityError : 2; /* 1E.CC02.9:8 LH */ + /* 1 = Parity error detected in the uP IRAM + */ + /*! \brief 1E.CC02.A LH uP DRAM Parity Error + AQ_GlobalAlarms_APPIA.u2.bits_2.upDramParityError + + + + 1 = Parity error detected in the uP DRAM + + */ + unsigned int upDramParityError : 1; /* 1E.CC02.A LH */ + /* 1 = Parity error detected in the uP DRAM + */ + unsigned int reserved0 : 3; + /*! \brief 1E.CC02.E LH Mailbox Operation: Complete + AQ_GlobalAlarms_APPIA.u2.bits_2.mailboxOperation_Complete + + + + 1 = Mailbox operation is complete + + + Notes: + Mailbox interface is ready interrupt for registers See Global Vendor Specific Control - Address 1E.C000 - See Global Vendor Specific Provisioning 5 - Address 1E.C404 */ + unsigned int mailboxOperation_Complete : 1; /* 1E.CC02.E LH */ + /* 1 = Mailbox operation is complete + */ + /*! \brief 1E.CC02.F LH NVR Operation Complete + AQ_GlobalAlarms_APPIA.u2.bits_2.nvrOperationComplete + + + + 1 = NVR operation is complete + + + Notes: + NVR interface is ready interrupt for registers See Global NVR Interface 1: Address 1E.100 - See Global NVR Provisioning Data MSW - Address 1E.17 . */ + unsigned int nvrOperationComplete : 1; /* 1E.CC02.F LH */ + /* 1 = NVR operation is complete + */ + } bits_2; + uint16_t word_2; + } u2; +} AQ_GlobalAlarms_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Interrupt Mask: 1E.D400 */ +/* Global Interrupt Mask: 1E.D400 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Interrupt Mask */ + union + { + struct + { + /*! \brief 1E.D400.0 R/WPD Reserved Alarm D Mask + AQ_GlobalInterruptMask_APPIA.u0.bits_0.reservedAlarmDMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int reservedAlarmDMask : 1; /* 1E.D400.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D400.1 R/WPD Reserved Alarm C Mask + AQ_GlobalInterruptMask_APPIA.u0.bits_0.reservedAlarmCMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int reservedAlarmCMask : 1; /* 1E.D400.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D400.2 R/WPD Reserved Alarm B Mask + AQ_GlobalInterruptMask_APPIA.u0.bits_0.reservedAlarmBMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int reservedAlarmBMask : 1; /* 1E.D400.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D400.3 R/WPD Reserved Alarm A Mask + AQ_GlobalInterruptMask_APPIA.u0.bits_0.reservedAlarmAMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int reservedAlarmAMask : 1; /* 1E.D400.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D400.4 R/WPD Device Fault Mask + AQ_GlobalInterruptMask_APPIA.u0.bits_0.deviceFaultMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int deviceFaultMask : 1; /* 1E.D400.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved2 : 1; + /*! \brief 1E.D400.6 R/WPD Reset completed Mask + AQ_GlobalInterruptMask_APPIA.u0.bits_0.resetCompletedMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int resetCompletedMask : 1; /* 1E.D400.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved1 : 4; + /*! \brief 1E.D400.B R/WPD Low Temperature Warning Mask + AQ_GlobalInterruptMask_APPIA.u0.bits_0.lowTemperatureWarningMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int lowTemperatureWarningMask : 1; /* 1E.D400.B R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D400.C R/WPD High Temperature Warning Mask + AQ_GlobalInterruptMask_APPIA.u0.bits_0.highTemperatureWarningMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int highTemperatureWarningMask : 1; /* 1E.D400.C R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D400.D R/WPD Low Temperature Failure Mask + AQ_GlobalInterruptMask_APPIA.u0.bits_0.lowTemperatureFailureMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int lowTemperatureFailureMask : 1; /* 1E.D400.D R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D400.E R/WPD High Temperature Failure Mask + AQ_GlobalInterruptMask_APPIA.u0.bits_0.highTemperatureFailureMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int highTemperatureFailureMask : 1; /* 1E.D400.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved0 : 1; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Interrupt Mask */ + union + { + struct + { + /*! \brief 1E.D401.0 R/WPD Diagnostic Alarm Mask + AQ_GlobalInterruptMask_APPIA.u1.bits_1.diagnosticAlarmMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int diagnosticAlarmMask : 1; /* 1E.D401.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int reserved1 : 6; + /*! \brief 1E.D401.7 R/WPD MDIO Command Handling Overflow Mask + AQ_GlobalInterruptMask_APPIA.u1.bits_1.mdioCommandHandlingOverflowMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int mdioCommandHandlingOverflowMask : 1; /* 1E.D401.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D401.C:8 R/WPD Reserved Alarms Mask [4:0] + AQ_GlobalInterruptMask_APPIA.u1.bits_1.reservedAlarmsMask + + Provisionable Default = 0x00 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int reservedAlarmsMask : 5; /* 1E.D401.C:8 R/WPD Provisionable Default = 0x00 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D401.D R/WPD XENPAK Alarm Mask + AQ_GlobalInterruptMask_APPIA.u1.bits_1.xenpakAlarmMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int xenpakAlarmMask : 1; /* 1E.D401.D R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D401.E R/WPD Smart Power-Down Entered Mask + AQ_GlobalInterruptMask_APPIA.u1.bits_1.smartPower_downEnteredMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int smartPower_downEnteredMask : 1; /* 1E.D401.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int reserved0 : 1; + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Interrupt Mask */ + union + { + struct + { + /*! \brief 1E.D402.0 R/WPD Watchdog Timer Alarm Mask + AQ_GlobalInterruptMask_APPIA.u2.bits_2.watchdogTimerAlarmMask + + Provisionable Default = 0x1 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int watchdogTimerAlarmMask : 1; /* 1E.D402.0 R/WPD Provisionable Default = 0x1 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D402.1 R/WPD MDIO Timeout Error Mask + AQ_GlobalInterruptMask_APPIA.u2.bits_2.mdioTimeoutErrorMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int mdioTimeoutErrorMask : 1; /* 1E.D402.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D402.2 R/WPD MDIO MMD Error Mask + AQ_GlobalInterruptMask_APPIA.u2.bits_2.mdioMMD_ErrorMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int mdioMMD_ErrorMask : 1; /* 1E.D402.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved2 : 2; + /*! \brief 1E.D402.5 R/WPD Tx Enable State Change Mask + AQ_GlobalInterruptMask_APPIA.u2.bits_2.txEnableStateChangeMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int txEnableStateChangeMask : 1; /* 1E.D402.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved1 : 2; + /*! \brief 1E.D402.9:8 R/WPD uP IRAM Parity Error Mask [1:0] + AQ_GlobalInterruptMask_APPIA.u2.bits_2.upIramParityErrorMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int upIramParityErrorMask : 2; /* 1E.D402.9:8 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D402.A R/WPD uP DRAM Parity Error Mask + AQ_GlobalInterruptMask_APPIA.u2.bits_2.upDramParityErrorMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int upDramParityErrorMask : 1; /* 1E.D402.A R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int reserved0 : 3; + /*! \brief 1E.D402.E R/WPD Mailbox Operation Complete Mask + AQ_GlobalInterruptMask_APPIA.u2.bits_2.mailboxOperationCompleteMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + Notes: + Mailbox interface is ready interrupt for registers See Global Vendor Specific Control - Address 1E.C000 - See Global Vendor Specific Provisioning 5 - Address 1E.C404 */ + unsigned int mailboxOperationCompleteMask : 1; /* 1E.D402.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D402.F R/WPD NVR Operation Complete Mask + AQ_GlobalInterruptMask_APPIA.u2.bits_2.nvrOperationCompleteMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + Notes: + NVR interface is ready interrupt for registers See Global NVR Interface 1: Address 1E.100 - See Global NVR Provisioning Data MSW - Address 1E.17 */ + unsigned int nvrOperationCompleteMask : 1; /* 1E.D402.F R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + } bits_2; + uint16_t word_2; + } u2; +} AQ_GlobalInterruptMask_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Chip-Wide Standard Interrupt Flags: 1E.FC00 */ +/* Global Chip-Wide Standard Interrupt Flags: 1E.FC00 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Chip-Wide Standard Interrupt Flags */ + union + { + struct + { + /*! \brief 1E.FC00.0 RO All Vendor Alarms Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_APPIA.u0.bits_0.allVendorAlarmsInterrupt + + + + 1 = Interrupt in all vendor alarms + + + Notes: + An interrupt was generated from status register ( See Global Chip-Wide LASI Vendor Interrupt Flags: Address 1E.FC01 ) and the corresponding mask register. ( See Global Interrupt LASI Mask: Address 1E.FF01 ) */ + unsigned int allVendorAlarmsInterrupt : 1; /* 1E.FC00.0 RO */ + /* 1 = Interrupt in all vendor alarms + */ + unsigned int reserved0 : 5; + /*! \brief 1E.FC00.6 RO GbE Standard Alarms Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_APPIA.u0.bits_0.gbeStandardAlarmsInterrupt + + + + 1 = Interrupt in GbE standard alarms + + + Notes: + An interrupt was generated from the TGE core. */ + unsigned int gbeStandardAlarmsInterrupt : 1; /* 1E.FC00.6 RO */ + /* 1 = Interrupt in GbE standard alarms + */ + /*! \brief 1E.FC00.7 RO Autonegotiation Standard Alarms 2 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_APPIA.u0.bits_0.autonegotiationStandardAlarms_2Interrupt + + + + 1 = Interrupt in Autonegotiation standard alarms 2 + + + Notes: + An interrupt was generated from status register ( See Autonegotiation 10GBASE-T Status Register - Address 7.21 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 8 - Address 4.A008 ) */ + unsigned int autonegotiationStandardAlarms_2Interrupt : 1; /* 1E.FC00.7 RO */ + /* 1 = Interrupt in Autonegotiation standard alarms 2 + */ + /*! \brief 1E.FC00.8 RO Autonegotiation Standard Alarms 1 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_APPIA.u0.bits_0.autonegotiationStandardAlarms_1Interrupt + + + + 1 = Interrupt in Autonegotiation standard alarms 1 + + + Notes: + An interrupt was generated from status register ( See PHY XS Standard Status 1 - Address 4.1 ) and the corresponding mask register. ( See Autonegotiation Standard LASI Interrupt Mask 1: Address 7.D000 ) */ + unsigned int autonegotiationStandardAlarms_1Interrupt : 1; /* 1E.FC00.8 RO */ + /* 1 = Interrupt in Autonegotiation standard alarms 1 + */ + /*! \brief 1E.FC00.9 RO PHY XS Standard Alarms 2 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_APPIA.u0.bits_0.phyXS_StandardAlarms_2Interrupt + + + + 1 = Interrupt in PHY XS standard alarms 2 + + + Notes: + An interrupt was generated from the status register ( See PHY XS Standard Vendor Devices in Package - Address 4.8 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 8 - Address 4.A008 ) */ + unsigned int phyXS_StandardAlarms_2Interrupt : 1; /* 1E.FC00.9 RO */ + /* 1 = Interrupt in PHY XS standard alarms 2 + */ + /*! \brief 1E.FC00.A RO PHY XS Standard Alarms 1 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_APPIA.u0.bits_0.phyXS_StandardAlarms_1Interrupt + + + + 1 = Interrupt in PHY XS standard alarms 1 + + + Notes: + An interrupt was generated from the status register ( See PHY XS Standard Status 1 - Address 4.1 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 2 - Address 4.A001 ) */ + unsigned int phyXS_StandardAlarms_1Interrupt : 1; /* 1E.FC00.A RO */ + /* 1 = Interrupt in PHY XS standard alarms 1 + */ + /*! \brief 1E.FC00.B RO PCS Standard Alarm 3 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_APPIA.u0.bits_0.pcsStandardAlarm_3Interrupt + + + + 1 = Interrupt in PCS standard alarms 3 + + + Notes: + An interrupt was generated from status register ( See PCS 10GBASE-T Status 2 - Address 3.21 ) and the corresponding mask register. ( See PCS Standard Interrupt Mask 1 - Address 3.E021 ) */ + unsigned int pcsStandardAlarm_3Interrupt : 1; /* 1E.FC00.B RO */ + /* 1 = Interrupt in PCS standard alarms 3 + */ + /*! \brief 1E.FC00.C RO PCS Standard Alarm 2 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_APPIA.u0.bits_0.pcsStandardAlarm_2Interrupt + + + + 1 = Interrupt in PCS standard alarms 2 + + + Notes: + An interrupt was generated from status register ( See PHY XS Standard Vendor Devices in Package - Address 4.8 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 8 - Address 4.A008 ) */ + unsigned int pcsStandardAlarm_2Interrupt : 1; /* 1E.FC00.C RO */ + /* 1 = Interrupt in PCS standard alarms 2 + */ + /*! \brief 1E.FC00.D RO PCS Standard Alarm 1 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_APPIA.u0.bits_0.pcsStandardAlarm_1Interrupt + + + + 1 = Interrupt in PCS standard alarms 1 + + + Notes: + An interrupt was generated from status register ( See PHY XS Standard Status 1 - Address 4.1 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 2 - Address 4.A001 ) */ + unsigned int pcsStandardAlarm_1Interrupt : 1; /* 1E.FC00.D RO */ + /* 1 = Interrupt in PCS standard alarms 1 + */ + /*! \brief 1E.FC00.E RO PMA Standard Alarm 2 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_APPIA.u0.bits_0.pmaStandardAlarm_2Interrupt + + + + 1 = Interrupt in PMA standard alarms 2 + + + Notes: + An interrupt was generated from either bit 1.8.B or 1.8.A. + An interrupt was generated from status register ( See PHY XS Standard Vendor Devices in Package - Address 4.8 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 8 - Address 4.A008 ) */ + unsigned int pmaStandardAlarm_2Interrupt : 1; /* 1E.FC00.E RO */ + /* 1 = Interrupt in PMA standard alarms 2 + */ + /*! \brief 1E.FC00.F RO PMA Standard Alarm 1 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_APPIA.u0.bits_0.pmaStandardAlarm_1Interrupt + + + + 1 = Interrupt in PMA standard alarms 1 + + + Notes: + An interrupt was generated from bit 1.1.2. + An interrupt was generated from status register ( See PHY XS Standard Status 1 - Address 4.1 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 2 - Address 4.A001 ) */ + unsigned int pmaStandardAlarm_1Interrupt : 1; /* 1E.FC00.F RO */ + /* 1 = Interrupt in PMA standard alarms 1 + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalChip_wideStandardInterruptFlags_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Chip-Wide Vendor Interrupt Flags: 1E.FC01 */ +/* Global Chip-Wide Vendor Interrupt Flags: 1E.FC01 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Chip-Wide Vendor Interrupt Flags */ + union + { + struct + { + /*! \brief 1E.FC01.0 RO Global Alarms 3 Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_APPIA.u0.bits_0.globalAlarms_3Interrupt + + + + 1 = Interrupt in Global alarms 3 + + + Notes: + An interrupt was generated from status register ( See Global Vendor Alarms 2: Address 1E.CC01 ) and the corresponding mask register. ( See Global LASI Interrupt Mask 2: Address 1E.D401 ) */ + unsigned int globalAlarms_3Interrupt : 1; /* 1E.FC01.0 RO */ + /* 1 = Interrupt in Global alarms 3 + */ + /*! \brief 1E.FC01.1 RO Global Alarms 2 Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_APPIA.u0.bits_0.globalAlarms_2Interrupt + + + + 1 = Interrupt in Global alarms 2 + + + Notes: + An interrupt was generated from status register ( See Global Alarms 2: Address 1E.CC01 ) and the corresponding mask register. ( See Global LASI Interrupt Mask 2: Address 1E.D401 ) */ + unsigned int globalAlarms_2Interrupt : 1; /* 1E.FC01.1 RO */ + /* 1 = Interrupt in Global alarms 2 + */ + /*! \brief 1E.FC01.2 RO Global Alarms 1 Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_APPIA.u0.bits_0.globalAlarms_1Interrupt + + + + 1 = Interrupt in Global alarms 1 + + + Notes: + An interrupt was generated from status register ( See Global Vendor Alarms 1 - Address 1E.CC00 ) and the corresponding mask register. ( See Global Vendor Interrupt Mask - Address 1E.D400 ) */ + unsigned int globalAlarms_1Interrupt : 1; /* 1E.FC01.2 RO */ + /* 1 = Interrupt in Global alarms 1 + */ + unsigned int reserved0 : 8; + /*! \brief 1E.FC01.B RO GbE Vendor Alarm Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_APPIA.u0.bits_0.gbeVendorAlarmInterrupt + + + + 1 = Interrupt in GbE vendor specific alarm + + + Notes: + A GbE alarm was generated. ( See GbE PHY Vendor Global LASI Interrupt Flags 1: Address 1D.FC00 ) */ + unsigned int gbeVendorAlarmInterrupt : 1; /* 1E.FC01.B RO */ + /* 1 = Interrupt in GbE vendor specific alarm + */ + /*! \brief 1E.FC01.C RO Autonegotiation Vendor Alarm Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_APPIA.u0.bits_0.autonegotiationVendorAlarmInterrupt + + + + 1 = Interrupt in Autonegotiation vendor specific alarm + + + Notes: + An Autonegotiation alarm was generated. ( See Autonegotiation Vendor Global LASI Interrupt Flags 1: Address 7.FC00 ) */ + unsigned int autonegotiationVendorAlarmInterrupt : 1; /* 1E.FC01.C RO */ + /* 1 = Interrupt in Autonegotiation vendor specific alarm + */ + /*! \brief 1E.FC01.D RO PHY XS Vendor Alarm Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_APPIA.u0.bits_0.phyXS_VendorAlarmInterrupt + + + + 1 = Interrupt in PHY XS vendor specific alarm + + + Notes: + A PHY XS alarm was generated. ( See PHY XS Vendor Global LASI Interrupt Flags 1: Address 4.FC00 ) */ + unsigned int phyXS_VendorAlarmInterrupt : 1; /* 1E.FC01.D RO */ + /* 1 = Interrupt in PHY XS vendor specific alarm + */ + /*! \brief 1E.FC01.E RO PCS Vendor Alarm Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_APPIA.u0.bits_0.pcsVendorAlarmInterrupt + + + + 1 = Interrupt in PCS vendor specific alarm + + + Notes: + A PCS alarm was generated. ( See PHY XS Vendor Global Interrupt Flags 1- Address 4.F800 ) */ + unsigned int pcsVendorAlarmInterrupt : 1; /* 1E.FC01.E RO */ + /* 1 = Interrupt in PCS vendor specific alarm + */ + /*! \brief 1E.FC01.F RO PMA Vendor Alarm Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_APPIA.u0.bits_0.pmaVendorAlarmInterrupt + + + + 1 = Interrupt in PMA vendor specific alarm + + + Notes: + A PMA alarm was generated. ( See PHY XS Vendor Global Interrupt Flags 1- Address 4.F800 ) */ + unsigned int pmaVendorAlarmInterrupt : 1; /* 1E.FC01.F RO */ + /* 1 = Interrupt in PMA vendor specific alarm + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalChip_wideVendorInterruptFlags_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Interrupt Chip-Wide Standard Mask: 1E.FF00 */ +/* Global Interrupt Chip-Wide Standard Mask: 1E.FF00 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Interrupt Chip-Wide Standard Mask */ + union + { + struct + { + /*! \brief 1E.FF00.0 R/WPD All Vendor Alarms Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_APPIA.u0.bits_0.allVendorAlarmsInterruptMask + + Provisionable Default = 0x1 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int allVendorAlarmsInterruptMask : 1; /* 1E.FF00.0 R/WPD Provisionable Default = 0x1 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved0 : 5; + /*! \brief 1E.FF00.6 R/WPD Gbe Standard Alarms Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_APPIA.u0.bits_0.gbeStandardAlarmsInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int gbeStandardAlarmsInterruptMask : 1; /* 1E.FF00.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.7 R/WPD Autonegotiation Standard Alarms 2 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_APPIA.u0.bits_0.autonegotiationStandardAlarms_2InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int autonegotiationStandardAlarms_2InterruptMask : 1; /* 1E.FF00.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.8 R/WPD Autonegotiation Standard Alarms 1 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_APPIA.u0.bits_0.autonegotiationStandardAlarms_1InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int autonegotiationStandardAlarms_1InterruptMask : 1; /* 1E.FF00.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.9 R/WPD PHY XS Standard Alarms 2 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_APPIA.u0.bits_0.phyXS_StandardAlarms_2InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int phyXS_StandardAlarms_2InterruptMask : 1; /* 1E.FF00.9 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.A R/WPD PHY XS Standard Alarms 1 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_APPIA.u0.bits_0.phyXS_StandardAlarms_1InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int phyXS_StandardAlarms_1InterruptMask : 1; /* 1E.FF00.A R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.B R/WPD PCS Standard Alarm 3 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_APPIA.u0.bits_0.pcsStandardAlarm_3InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pcsStandardAlarm_3InterruptMask : 1; /* 1E.FF00.B R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.C R/WPD PCS Standard Alarm 2 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_APPIA.u0.bits_0.pcsStandardAlarm_2InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pcsStandardAlarm_2InterruptMask : 1; /* 1E.FF00.C R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.D R/WPD PCS Standard Alarm 1 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_APPIA.u0.bits_0.pcsStandardAlarm_1InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pcsStandardAlarm_1InterruptMask : 1; /* 1E.FF00.D R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.E R/WPD PMA Standard Alarm 2 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_APPIA.u0.bits_0.pmaStandardAlarm_2InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pmaStandardAlarm_2InterruptMask : 1; /* 1E.FF00.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.F R/WPD PMA Standard Alarm 1 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_APPIA.u0.bits_0.pmaStandardAlarm_1InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pmaStandardAlarm_1InterruptMask : 1; /* 1E.FF00.F R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalInterruptChip_wideStandardMask_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Interrupt Chip-Wide Vendor Mask: 1E.FF01 */ +/* Global Interrupt Chip-Wide Vendor Mask: 1E.FF01 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Interrupt Chip-Wide Vendor Mask */ + union + { + struct + { + /*! \brief 1E.FF01.0 R/WPD Global Alarms 3 Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_APPIA.u0.bits_0.globalAlarms_3InterruptMask + + Provisionable Default = 0x1 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int globalAlarms_3InterruptMask : 1; /* 1E.FF01.0 R/WPD Provisionable Default = 0x1 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.1 R/WPD Global Alarms 2 Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_APPIA.u0.bits_0.globalAlarms_2InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int globalAlarms_2InterruptMask : 1; /* 1E.FF01.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.2 R/WPD Global Alarms 1 Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_APPIA.u0.bits_0.globalAlarms_1InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int globalAlarms_1InterruptMask : 1; /* 1E.FF01.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved0 : 8; + /*! \brief 1E.FF01.B R/WPD GbE Vendor Alarm Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_APPIA.u0.bits_0.gbeVendorAlarmInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int gbeVendorAlarmInterruptMask : 1; /* 1E.FF01.B R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.C R/WPD Autonegotiation Vendor Alarm Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_APPIA.u0.bits_0.autonegotiationVendorAlarmInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int autonegotiationVendorAlarmInterruptMask : 1; /* 1E.FF01.C R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.D R/WPD PHY XS Vendor Alarm Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_APPIA.u0.bits_0.phyXS_VendorAlarmInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int phyXS_VendorAlarmInterruptMask : 1; /* 1E.FF01.D R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.E R/WPD PCS Vendor Alarm Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_APPIA.u0.bits_0.pcsVendorAlarmInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pcsVendorAlarmInterruptMask : 1; /* 1E.FF01.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.F R/WPD PMA Vendor Alarm Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_APPIA.u0.bits_0.pmaVendorAlarmInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pmaVendorAlarmInterruptMask : 1; /* 1E.FF01.F R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalInterruptChip_wideVendorMask_APPIA; + +#endif +/*@}*/ +/*@}*/ diff --git a/feeds/ipq807x/aq-fw-download/src/include/registerMap/APPIA/AQ_APPIA_Global_registers_Defines.h b/feeds/ipq807x/aq-fw-download/src/include/registerMap/APPIA/AQ_APPIA_Global_registers_Defines.h new file mode 100755 index 000000000..9c7bb5cb5 --- /dev/null +++ b/feeds/ipq807x/aq-fw-download/src/include/registerMap/APPIA/AQ_APPIA_Global_registers_Defines.h @@ -0,0 +1,2134 @@ +/*! \file +* This file contains the compiler assist macros and doxygen comments +* for the Global Registers block. +*/ + +/*! \defgroup Global_registers_Defines Global Registers Defines +* This module contains the compiler assist macros and doxygen comments +* for the Global Registers block. +*/ +/*********************************************************************** +* Copyright (c) 2015, Aquantia +* +* Permission to use, copy, modify, and/or distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +* +* $File: //depot/icm/proj/Dena/rev1.0/c/Systems/tools/windows/regMapParser/src/gencheaders.py $ +* +* $Revision: #10 $ +* +* $DateTime: 2014/04/08 16:55:58 $ +* +* $Author: joshd $ +* +* $Label: $ +* +* Description: +* +* This file contains the compiler assist macros for the registers contained in the Global Registers block. +* +* +***********************************************************************/ + + +/*@{*/ +#ifndef AQ_APPIA_GLOBAL_REGS_DEFINES_HEADER +#define AQ_APPIA_GLOBAL_REGS_DEFINES_HEADER + + +/*-----------------------------------------------------------------------------*/ +/*Access macro definitions */ +/*-----------------------------------------------------------------------------*/ +/*! \brief Base register address of structure AQ_GlobalStandardControl_1_APPIA */ +#define AQ_GlobalStandardControl_1_APPIA_baseRegisterAddress 0x0000 +/*! \brief MMD address of structure AQ_GlobalStandardControl_1_APPIA */ +#define AQ_GlobalStandardControl_1_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure softReset in AQ_GlobalStandardControl_1_APPIA */ +#define AQ_GlobalStandardControl_1_APPIA_softReset 0 +/*! \brief Preprocessor variable to relate field to bit position in structure softReset in AQ_GlobalStandardControl_1_APPIA */ +#define bits_AQ_GlobalStandardControl_1_APPIA_softReset u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure softReset in AQ_GlobalStandardControl_1_APPIA */ +#define word_AQ_GlobalStandardControl_1_APPIA_softReset u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure hardReset in AQ_GlobalStandardControl_1_APPIA */ +#define AQ_GlobalStandardControl_1_APPIA_hardReset 0 +/*! \brief Preprocessor variable to relate field to bit position in structure hardReset in AQ_GlobalStandardControl_1_APPIA */ +#define bits_AQ_GlobalStandardControl_1_APPIA_hardReset u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure hardReset in AQ_GlobalStandardControl_1_APPIA */ +#define word_AQ_GlobalStandardControl_1_APPIA_hardReset u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure lowPower in AQ_GlobalStandardControl_1_APPIA */ +#define AQ_GlobalStandardControl_1_APPIA_lowPower 0 +/*! \brief Preprocessor variable to relate field to bit position in structure lowPower in AQ_GlobalStandardControl_1_APPIA */ +#define bits_AQ_GlobalStandardControl_1_APPIA_lowPower u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure lowPower in AQ_GlobalStandardControl_1_APPIA */ +#define word_AQ_GlobalStandardControl_1_APPIA_lowPower u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalStandardDeviceIdentifier_APPIA */ +#define AQ_GlobalStandardDeviceIdentifier_APPIA_baseRegisterAddress 0x0002 +/*! \brief MMD address of structure AQ_GlobalStandardDeviceIdentifier_APPIA */ +#define AQ_GlobalStandardDeviceIdentifier_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure deviceIdMSW in AQ_GlobalStandardDeviceIdentifier_APPIA */ +#define AQ_GlobalStandardDeviceIdentifier_APPIA_deviceIdMSW 0 +/*! \brief Preprocessor variable to relate field to bit position in structure deviceIdMSW in AQ_GlobalStandardDeviceIdentifier_APPIA */ +#define bits_AQ_GlobalStandardDeviceIdentifier_APPIA_deviceIdMSW u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure deviceIdMSW in AQ_GlobalStandardDeviceIdentifier_APPIA */ +#define word_AQ_GlobalStandardDeviceIdentifier_APPIA_deviceIdMSW u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure deviceIdLSW in AQ_GlobalStandardDeviceIdentifier_APPIA */ +#define AQ_GlobalStandardDeviceIdentifier_APPIA_deviceIdLSW 1 +/*! \brief Preprocessor variable to relate field to bit position in structure deviceIdLSW in AQ_GlobalStandardDeviceIdentifier_APPIA */ +#define bits_AQ_GlobalStandardDeviceIdentifier_APPIA_deviceIdLSW u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure deviceIdLSW in AQ_GlobalStandardDeviceIdentifier_APPIA */ +#define word_AQ_GlobalStandardDeviceIdentifier_APPIA_deviceIdLSW u1.word_1 + +/*! \brief Base register address of structure AQ_GlobalStandardDevicesInPackage_APPIA */ +#define AQ_GlobalStandardDevicesInPackage_APPIA_baseRegisterAddress 0x0005 +/*! \brief MMD address of structure AQ_GlobalStandardDevicesInPackage_APPIA */ +#define AQ_GlobalStandardDevicesInPackage_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure autonegotiationPresent in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define AQ_GlobalStandardDevicesInPackage_APPIA_autonegotiationPresent 0 +/*! \brief Preprocessor variable to relate field to bit position in structure autonegotiationPresent in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define bits_AQ_GlobalStandardDevicesInPackage_APPIA_autonegotiationPresent u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure autonegotiationPresent in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define word_AQ_GlobalStandardDevicesInPackage_APPIA_autonegotiationPresent u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure tcPresent in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define AQ_GlobalStandardDevicesInPackage_APPIA_tcPresent 0 +/*! \brief Preprocessor variable to relate field to bit position in structure tcPresent in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define bits_AQ_GlobalStandardDevicesInPackage_APPIA_tcPresent u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure tcPresent in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define word_AQ_GlobalStandardDevicesInPackage_APPIA_tcPresent u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure dteXsPresent in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define AQ_GlobalStandardDevicesInPackage_APPIA_dteXsPresent 0 +/*! \brief Preprocessor variable to relate field to bit position in structure dteXsPresent in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define bits_AQ_GlobalStandardDevicesInPackage_APPIA_dteXsPresent u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure dteXsPresent in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define word_AQ_GlobalStandardDevicesInPackage_APPIA_dteXsPresent u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure phyXS_Present in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define AQ_GlobalStandardDevicesInPackage_APPIA_phyXS_Present 0 +/*! \brief Preprocessor variable to relate field to bit position in structure phyXS_Present in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define bits_AQ_GlobalStandardDevicesInPackage_APPIA_phyXS_Present u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure phyXS_Present in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define word_AQ_GlobalStandardDevicesInPackage_APPIA_phyXS_Present u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pcsPresent in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define AQ_GlobalStandardDevicesInPackage_APPIA_pcsPresent 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pcsPresent in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define bits_AQ_GlobalStandardDevicesInPackage_APPIA_pcsPresent u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pcsPresent in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define word_AQ_GlobalStandardDevicesInPackage_APPIA_pcsPresent u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure wisPresent in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define AQ_GlobalStandardDevicesInPackage_APPIA_wisPresent 0 +/*! \brief Preprocessor variable to relate field to bit position in structure wisPresent in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define bits_AQ_GlobalStandardDevicesInPackage_APPIA_wisPresent u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure wisPresent in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define word_AQ_GlobalStandardDevicesInPackage_APPIA_wisPresent u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pmaPresent in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define AQ_GlobalStandardDevicesInPackage_APPIA_pmaPresent 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pmaPresent in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define bits_AQ_GlobalStandardDevicesInPackage_APPIA_pmaPresent u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pmaPresent in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define word_AQ_GlobalStandardDevicesInPackage_APPIA_pmaPresent u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure clause_22RegistersPresent in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define AQ_GlobalStandardDevicesInPackage_APPIA_clause_22RegistersPresent 0 +/*! \brief Preprocessor variable to relate field to bit position in structure clause_22RegistersPresent in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define bits_AQ_GlobalStandardDevicesInPackage_APPIA_clause_22RegistersPresent u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure clause_22RegistersPresent in AQ_GlobalStandardDevicesInPackage_APPIA */ +#define word_AQ_GlobalStandardDevicesInPackage_APPIA_clause_22RegistersPresent u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalStandardVendorDevicesInPackage_APPIA */ +#define AQ_GlobalStandardVendorDevicesInPackage_APPIA_baseRegisterAddress 0x0006 +/*! \brief MMD address of structure AQ_GlobalStandardVendorDevicesInPackage_APPIA */ +#define AQ_GlobalStandardVendorDevicesInPackage_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure vendorSpecificDevice_2Present in AQ_GlobalStandardVendorDevicesInPackage_APPIA */ +#define AQ_GlobalStandardVendorDevicesInPackage_APPIA_vendorSpecificDevice_2Present 0 +/*! \brief Preprocessor variable to relate field to bit position in structure vendorSpecificDevice_2Present in AQ_GlobalStandardVendorDevicesInPackage_APPIA */ +#define bits_AQ_GlobalStandardVendorDevicesInPackage_APPIA_vendorSpecificDevice_2Present u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure vendorSpecificDevice_2Present in AQ_GlobalStandardVendorDevicesInPackage_APPIA */ +#define word_AQ_GlobalStandardVendorDevicesInPackage_APPIA_vendorSpecificDevice_2Present u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure vendorSpecificDevice_1Present in AQ_GlobalStandardVendorDevicesInPackage_APPIA */ +#define AQ_GlobalStandardVendorDevicesInPackage_APPIA_vendorSpecificDevice_1Present 0 +/*! \brief Preprocessor variable to relate field to bit position in structure vendorSpecificDevice_1Present in AQ_GlobalStandardVendorDevicesInPackage_APPIA */ +#define bits_AQ_GlobalStandardVendorDevicesInPackage_APPIA_vendorSpecificDevice_1Present u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure vendorSpecificDevice_1Present in AQ_GlobalStandardVendorDevicesInPackage_APPIA */ +#define word_AQ_GlobalStandardVendorDevicesInPackage_APPIA_vendorSpecificDevice_1Present u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure clause_22ExtensionPresent in AQ_GlobalStandardVendorDevicesInPackage_APPIA */ +#define AQ_GlobalStandardVendorDevicesInPackage_APPIA_clause_22ExtensionPresent 0 +/*! \brief Preprocessor variable to relate field to bit position in structure clause_22ExtensionPresent in AQ_GlobalStandardVendorDevicesInPackage_APPIA */ +#define bits_AQ_GlobalStandardVendorDevicesInPackage_APPIA_clause_22ExtensionPresent u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure clause_22ExtensionPresent in AQ_GlobalStandardVendorDevicesInPackage_APPIA */ +#define word_AQ_GlobalStandardVendorDevicesInPackage_APPIA_clause_22ExtensionPresent u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalStandardStatus_2_APPIA */ +#define AQ_GlobalStandardStatus_2_APPIA_baseRegisterAddress 0x0008 +/*! \brief MMD address of structure AQ_GlobalStandardStatus_2_APPIA */ +#define AQ_GlobalStandardStatus_2_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure devicePresent in AQ_GlobalStandardStatus_2_APPIA */ +#define AQ_GlobalStandardStatus_2_APPIA_devicePresent 0 +/*! \brief Preprocessor variable to relate field to bit position in structure devicePresent in AQ_GlobalStandardStatus_2_APPIA */ +#define bits_AQ_GlobalStandardStatus_2_APPIA_devicePresent u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure devicePresent in AQ_GlobalStandardStatus_2_APPIA */ +#define word_AQ_GlobalStandardStatus_2_APPIA_devicePresent u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalStandardPackageIdentifier_APPIA */ +#define AQ_GlobalStandardPackageIdentifier_APPIA_baseRegisterAddress 0x000E +/*! \brief MMD address of structure AQ_GlobalStandardPackageIdentifier_APPIA */ +#define AQ_GlobalStandardPackageIdentifier_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure packageIdMSW in AQ_GlobalStandardPackageIdentifier_APPIA */ +#define AQ_GlobalStandardPackageIdentifier_APPIA_packageIdMSW 0 +/*! \brief Preprocessor variable to relate field to bit position in structure packageIdMSW in AQ_GlobalStandardPackageIdentifier_APPIA */ +#define bits_AQ_GlobalStandardPackageIdentifier_APPIA_packageIdMSW u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure packageIdMSW in AQ_GlobalStandardPackageIdentifier_APPIA */ +#define word_AQ_GlobalStandardPackageIdentifier_APPIA_packageIdMSW u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure packageIdLSW in AQ_GlobalStandardPackageIdentifier_APPIA */ +#define AQ_GlobalStandardPackageIdentifier_APPIA_packageIdLSW 1 +/*! \brief Preprocessor variable to relate field to bit position in structure packageIdLSW in AQ_GlobalStandardPackageIdentifier_APPIA */ +#define bits_AQ_GlobalStandardPackageIdentifier_APPIA_packageIdLSW u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure packageIdLSW in AQ_GlobalStandardPackageIdentifier_APPIA */ +#define word_AQ_GlobalStandardPackageIdentifier_APPIA_packageIdLSW u1.word_1 + +/*! \brief Base register address of structure AQ_GlobalFirmwareID_APPIA */ +#define AQ_GlobalFirmwareID_APPIA_baseRegisterAddress 0x0020 +/*! \brief MMD address of structure AQ_GlobalFirmwareID_APPIA */ +#define AQ_GlobalFirmwareID_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure firmwareMajorRevisionNumber in AQ_GlobalFirmwareID_APPIA */ +#define AQ_GlobalFirmwareID_APPIA_firmwareMajorRevisionNumber 0 +/*! \brief Preprocessor variable to relate field to bit position in structure firmwareMajorRevisionNumber in AQ_GlobalFirmwareID_APPIA */ +#define bits_AQ_GlobalFirmwareID_APPIA_firmwareMajorRevisionNumber u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure firmwareMajorRevisionNumber in AQ_GlobalFirmwareID_APPIA */ +#define word_AQ_GlobalFirmwareID_APPIA_firmwareMajorRevisionNumber u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure firmwareMinorRevisionNumber in AQ_GlobalFirmwareID_APPIA */ +#define AQ_GlobalFirmwareID_APPIA_firmwareMinorRevisionNumber 0 +/*! \brief Preprocessor variable to relate field to bit position in structure firmwareMinorRevisionNumber in AQ_GlobalFirmwareID_APPIA */ +#define bits_AQ_GlobalFirmwareID_APPIA_firmwareMinorRevisionNumber u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure firmwareMinorRevisionNumber in AQ_GlobalFirmwareID_APPIA */ +#define word_AQ_GlobalFirmwareID_APPIA_firmwareMinorRevisionNumber u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalChipIdentification_APPIA */ +#define AQ_GlobalChipIdentification_APPIA_baseRegisterAddress 0x0021 +/*! \brief MMD address of structure AQ_GlobalChipIdentification_APPIA */ +#define AQ_GlobalChipIdentification_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure chipIdentification in AQ_GlobalChipIdentification_APPIA */ +#define AQ_GlobalChipIdentification_APPIA_chipIdentification 0 +/*! \brief Preprocessor variable to relate field to bit position in structure chipIdentification in AQ_GlobalChipIdentification_APPIA */ +#define bits_AQ_GlobalChipIdentification_APPIA_chipIdentification u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure chipIdentification in AQ_GlobalChipIdentification_APPIA */ +#define word_AQ_GlobalChipIdentification_APPIA_chipIdentification u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalChipRevision_APPIA */ +#define AQ_GlobalChipRevision_APPIA_baseRegisterAddress 0x0022 +/*! \brief MMD address of structure AQ_GlobalChipRevision_APPIA */ +#define AQ_GlobalChipRevision_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure chipRevision in AQ_GlobalChipRevision_APPIA */ +#define AQ_GlobalChipRevision_APPIA_chipRevision 0 +/*! \brief Preprocessor variable to relate field to bit position in structure chipRevision in AQ_GlobalChipRevision_APPIA */ +#define bits_AQ_GlobalChipRevision_APPIA_chipRevision u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure chipRevision in AQ_GlobalChipRevision_APPIA */ +#define word_AQ_GlobalChipRevision_APPIA_chipRevision u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalNvrInterface_APPIA */ +#define AQ_GlobalNvrInterface_APPIA_baseRegisterAddress 0x0100 +/*! \brief MMD address of structure AQ_GlobalNvrInterface_APPIA */ +#define AQ_GlobalNvrInterface_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure nvrExecuteOperation in AQ_GlobalNvrInterface_APPIA */ +#define AQ_GlobalNvrInterface_APPIA_nvrExecuteOperation 0 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrExecuteOperation in AQ_GlobalNvrInterface_APPIA */ +#define bits_AQ_GlobalNvrInterface_APPIA_nvrExecuteOperation u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure nvrExecuteOperation in AQ_GlobalNvrInterface_APPIA */ +#define word_AQ_GlobalNvrInterface_APPIA_nvrExecuteOperation u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure nvrWriteMode in AQ_GlobalNvrInterface_APPIA */ +#define AQ_GlobalNvrInterface_APPIA_nvrWriteMode 0 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrWriteMode in AQ_GlobalNvrInterface_APPIA */ +#define bits_AQ_GlobalNvrInterface_APPIA_nvrWriteMode u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure nvrWriteMode in AQ_GlobalNvrInterface_APPIA */ +#define word_AQ_GlobalNvrInterface_APPIA_nvrWriteMode u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure freezeNvrCrc in AQ_GlobalNvrInterface_APPIA */ +#define AQ_GlobalNvrInterface_APPIA_freezeNvrCrc 0 +/*! \brief Preprocessor variable to relate field to bit position in structure freezeNvrCrc in AQ_GlobalNvrInterface_APPIA */ +#define bits_AQ_GlobalNvrInterface_APPIA_freezeNvrCrc u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure freezeNvrCrc in AQ_GlobalNvrInterface_APPIA */ +#define word_AQ_GlobalNvrInterface_APPIA_freezeNvrCrc u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure resetNvrCrc in AQ_GlobalNvrInterface_APPIA */ +#define AQ_GlobalNvrInterface_APPIA_resetNvrCrc 0 +/*! \brief Preprocessor variable to relate field to bit position in structure resetNvrCrc in AQ_GlobalNvrInterface_APPIA */ +#define bits_AQ_GlobalNvrInterface_APPIA_resetNvrCrc u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure resetNvrCrc in AQ_GlobalNvrInterface_APPIA */ +#define word_AQ_GlobalNvrInterface_APPIA_resetNvrCrc u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure nvrBurst in AQ_GlobalNvrInterface_APPIA */ +#define AQ_GlobalNvrInterface_APPIA_nvrBurst 0 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrBurst in AQ_GlobalNvrInterface_APPIA */ +#define bits_AQ_GlobalNvrInterface_APPIA_nvrBurst u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure nvrBurst in AQ_GlobalNvrInterface_APPIA */ +#define word_AQ_GlobalNvrInterface_APPIA_nvrBurst u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure nvrBusy in AQ_GlobalNvrInterface_APPIA */ +#define AQ_GlobalNvrInterface_APPIA_nvrBusy 0 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrBusy in AQ_GlobalNvrInterface_APPIA */ +#define bits_AQ_GlobalNvrInterface_APPIA_nvrBusy u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure nvrBusy in AQ_GlobalNvrInterface_APPIA */ +#define word_AQ_GlobalNvrInterface_APPIA_nvrBusy u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure nvrOpcode in AQ_GlobalNvrInterface_APPIA */ +#define AQ_GlobalNvrInterface_APPIA_nvrOpcode 0 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrOpcode in AQ_GlobalNvrInterface_APPIA */ +#define bits_AQ_GlobalNvrInterface_APPIA_nvrOpcode u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure nvrOpcode in AQ_GlobalNvrInterface_APPIA */ +#define word_AQ_GlobalNvrInterface_APPIA_nvrOpcode u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure nvrMailboxCrc in AQ_GlobalNvrInterface_APPIA */ +#define AQ_GlobalNvrInterface_APPIA_nvrMailboxCrc 1 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrMailboxCrc in AQ_GlobalNvrInterface_APPIA */ +#define bits_AQ_GlobalNvrInterface_APPIA_nvrMailboxCrc u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure nvrMailboxCrc in AQ_GlobalNvrInterface_APPIA */ +#define word_AQ_GlobalNvrInterface_APPIA_nvrMailboxCrc u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure nvrAddressMSW in AQ_GlobalNvrInterface_APPIA */ +#define AQ_GlobalNvrInterface_APPIA_nvrAddressMSW 2 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrAddressMSW in AQ_GlobalNvrInterface_APPIA */ +#define bits_AQ_GlobalNvrInterface_APPIA_nvrAddressMSW u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure nvrAddressMSW in AQ_GlobalNvrInterface_APPIA */ +#define word_AQ_GlobalNvrInterface_APPIA_nvrAddressMSW u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure nvrAddressLSW in AQ_GlobalNvrInterface_APPIA */ +#define AQ_GlobalNvrInterface_APPIA_nvrAddressLSW 3 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrAddressLSW in AQ_GlobalNvrInterface_APPIA */ +#define bits_AQ_GlobalNvrInterface_APPIA_nvrAddressLSW u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure nvrAddressLSW in AQ_GlobalNvrInterface_APPIA */ +#define word_AQ_GlobalNvrInterface_APPIA_nvrAddressLSW u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure nvrDataMSW in AQ_GlobalNvrInterface_APPIA */ +#define AQ_GlobalNvrInterface_APPIA_nvrDataMSW 4 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrDataMSW in AQ_GlobalNvrInterface_APPIA */ +#define bits_AQ_GlobalNvrInterface_APPIA_nvrDataMSW u4.bits_4 +/*! \brief Preprocessor variable to relate field to word position in structure nvrDataMSW in AQ_GlobalNvrInterface_APPIA */ +#define word_AQ_GlobalNvrInterface_APPIA_nvrDataMSW u4.word_4 +/*! \brief Preprocessor variable to relate field to word number in structure nvrDataLSW in AQ_GlobalNvrInterface_APPIA */ +#define AQ_GlobalNvrInterface_APPIA_nvrDataLSW 5 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrDataLSW in AQ_GlobalNvrInterface_APPIA */ +#define bits_AQ_GlobalNvrInterface_APPIA_nvrDataLSW u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure nvrDataLSW in AQ_GlobalNvrInterface_APPIA */ +#define word_AQ_GlobalNvrInterface_APPIA_nvrDataLSW u5.word_5 + +/*! \brief Base register address of structure AQ_GlobalMailboxInterface_APPIA */ +#define AQ_GlobalMailboxInterface_APPIA_baseRegisterAddress 0x0200 +/*! \brief MMD address of structure AQ_GlobalMailboxInterface_APPIA */ +#define AQ_GlobalMailboxInterface_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure upMailboxExecuteOperation in AQ_GlobalMailboxInterface_APPIA */ +#define AQ_GlobalMailboxInterface_APPIA_upMailboxExecuteOperation 0 +/*! \brief Preprocessor variable to relate field to bit position in structure upMailboxExecuteOperation in AQ_GlobalMailboxInterface_APPIA */ +#define bits_AQ_GlobalMailboxInterface_APPIA_upMailboxExecuteOperation u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure upMailboxExecuteOperation in AQ_GlobalMailboxInterface_APPIA */ +#define word_AQ_GlobalMailboxInterface_APPIA_upMailboxExecuteOperation u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure upMailboxWriteMode in AQ_GlobalMailboxInterface_APPIA */ +#define AQ_GlobalMailboxInterface_APPIA_upMailboxWriteMode 0 +/*! \brief Preprocessor variable to relate field to bit position in structure upMailboxWriteMode in AQ_GlobalMailboxInterface_APPIA */ +#define bits_AQ_GlobalMailboxInterface_APPIA_upMailboxWriteMode u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure upMailboxWriteMode in AQ_GlobalMailboxInterface_APPIA */ +#define word_AQ_GlobalMailboxInterface_APPIA_upMailboxWriteMode u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure resetUpMailboxCrc in AQ_GlobalMailboxInterface_APPIA */ +#define AQ_GlobalMailboxInterface_APPIA_resetUpMailboxCrc 0 +/*! \brief Preprocessor variable to relate field to bit position in structure resetUpMailboxCrc in AQ_GlobalMailboxInterface_APPIA */ +#define bits_AQ_GlobalMailboxInterface_APPIA_resetUpMailboxCrc u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure resetUpMailboxCrc in AQ_GlobalMailboxInterface_APPIA */ +#define word_AQ_GlobalMailboxInterface_APPIA_resetUpMailboxCrc u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure upMailboxBusy in AQ_GlobalMailboxInterface_APPIA */ +#define AQ_GlobalMailboxInterface_APPIA_upMailboxBusy 0 +/*! \brief Preprocessor variable to relate field to bit position in structure upMailboxBusy in AQ_GlobalMailboxInterface_APPIA */ +#define bits_AQ_GlobalMailboxInterface_APPIA_upMailboxBusy u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure upMailboxBusy in AQ_GlobalMailboxInterface_APPIA */ +#define word_AQ_GlobalMailboxInterface_APPIA_upMailboxBusy u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure upMailboxCrc in AQ_GlobalMailboxInterface_APPIA */ +#define AQ_GlobalMailboxInterface_APPIA_upMailboxCrc 1 +/*! \brief Preprocessor variable to relate field to bit position in structure upMailboxCrc in AQ_GlobalMailboxInterface_APPIA */ +#define bits_AQ_GlobalMailboxInterface_APPIA_upMailboxCrc u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure upMailboxCrc in AQ_GlobalMailboxInterface_APPIA */ +#define word_AQ_GlobalMailboxInterface_APPIA_upMailboxCrc u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure upMailboxAddressMSW in AQ_GlobalMailboxInterface_APPIA */ +#define AQ_GlobalMailboxInterface_APPIA_upMailboxAddressMSW 2 +/*! \brief Preprocessor variable to relate field to bit position in structure upMailboxAddressMSW in AQ_GlobalMailboxInterface_APPIA */ +#define bits_AQ_GlobalMailboxInterface_APPIA_upMailboxAddressMSW u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure upMailboxAddressMSW in AQ_GlobalMailboxInterface_APPIA */ +#define word_AQ_GlobalMailboxInterface_APPIA_upMailboxAddressMSW u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure upMailboxAddressLSW in AQ_GlobalMailboxInterface_APPIA */ +#define AQ_GlobalMailboxInterface_APPIA_upMailboxAddressLSW 3 +/*! \brief Preprocessor variable to relate field to bit position in structure upMailboxAddressLSW in AQ_GlobalMailboxInterface_APPIA */ +#define bits_AQ_GlobalMailboxInterface_APPIA_upMailboxAddressLSW u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure upMailboxAddressLSW in AQ_GlobalMailboxInterface_APPIA */ +#define word_AQ_GlobalMailboxInterface_APPIA_upMailboxAddressLSW u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure upMailboxAddressLSW_Don_tCare in AQ_GlobalMailboxInterface_APPIA */ +#define AQ_GlobalMailboxInterface_APPIA_upMailboxAddressLSW_Don_tCare 3 +/*! \brief Preprocessor variable to relate field to bit position in structure upMailboxAddressLSW_Don_tCare in AQ_GlobalMailboxInterface_APPIA */ +#define bits_AQ_GlobalMailboxInterface_APPIA_upMailboxAddressLSW_Don_tCare u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure upMailboxAddressLSW_Don_tCare in AQ_GlobalMailboxInterface_APPIA */ +#define word_AQ_GlobalMailboxInterface_APPIA_upMailboxAddressLSW_Don_tCare u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure upMailboxDataMSW in AQ_GlobalMailboxInterface_APPIA */ +#define AQ_GlobalMailboxInterface_APPIA_upMailboxDataMSW 4 +/*! \brief Preprocessor variable to relate field to bit position in structure upMailboxDataMSW in AQ_GlobalMailboxInterface_APPIA */ +#define bits_AQ_GlobalMailboxInterface_APPIA_upMailboxDataMSW u4.bits_4 +/*! \brief Preprocessor variable to relate field to word position in structure upMailboxDataMSW in AQ_GlobalMailboxInterface_APPIA */ +#define word_AQ_GlobalMailboxInterface_APPIA_upMailboxDataMSW u4.word_4 +/*! \brief Preprocessor variable to relate field to word number in structure upMailboxDataLSW in AQ_GlobalMailboxInterface_APPIA */ +#define AQ_GlobalMailboxInterface_APPIA_upMailboxDataLSW 5 +/*! \brief Preprocessor variable to relate field to bit position in structure upMailboxDataLSW in AQ_GlobalMailboxInterface_APPIA */ +#define bits_AQ_GlobalMailboxInterface_APPIA_upMailboxDataLSW u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure upMailboxDataLSW in AQ_GlobalMailboxInterface_APPIA */ +#define word_AQ_GlobalMailboxInterface_APPIA_upMailboxDataLSW u5.word_5 + +/*! \brief Base register address of structure AQ_GlobalMicroprocessorScratchPad_APPIA */ +#define AQ_GlobalMicroprocessorScratchPad_APPIA_baseRegisterAddress 0x0300 +/*! \brief MMD address of structure AQ_GlobalMicroprocessorScratchPad_APPIA */ +#define AQ_GlobalMicroprocessorScratchPad_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure scratchPad_1 in AQ_GlobalMicroprocessorScratchPad_APPIA */ +#define AQ_GlobalMicroprocessorScratchPad_APPIA_scratchPad_1 0 +/*! \brief Preprocessor variable to relate field to bit position in structure scratchPad_1 in AQ_GlobalMicroprocessorScratchPad_APPIA */ +#define bits_AQ_GlobalMicroprocessorScratchPad_APPIA_scratchPad_1 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure scratchPad_1 in AQ_GlobalMicroprocessorScratchPad_APPIA */ +#define word_AQ_GlobalMicroprocessorScratchPad_APPIA_scratchPad_1 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure scratchPad_2 in AQ_GlobalMicroprocessorScratchPad_APPIA */ +#define AQ_GlobalMicroprocessorScratchPad_APPIA_scratchPad_2 1 +/*! \brief Preprocessor variable to relate field to bit position in structure scratchPad_2 in AQ_GlobalMicroprocessorScratchPad_APPIA */ +#define bits_AQ_GlobalMicroprocessorScratchPad_APPIA_scratchPad_2 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure scratchPad_2 in AQ_GlobalMicroprocessorScratchPad_APPIA */ +#define word_AQ_GlobalMicroprocessorScratchPad_APPIA_scratchPad_2 u1.word_1 + +/*! \brief Base register address of structure AQ_GlobalControl_APPIA */ +#define AQ_GlobalControl_APPIA_baseRegisterAddress 0xC000 +/*! \brief MMD address of structure AQ_GlobalControl_APPIA */ +#define AQ_GlobalControl_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure upReset in AQ_GlobalControl_APPIA */ +#define AQ_GlobalControl_APPIA_upReset 1 +/*! \brief Preprocessor variable to relate field to bit position in structure upReset in AQ_GlobalControl_APPIA */ +#define bits_AQ_GlobalControl_APPIA_upReset u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure upReset in AQ_GlobalControl_APPIA */ +#define word_AQ_GlobalControl_APPIA_upReset u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure upRunStallOverride in AQ_GlobalControl_APPIA */ +#define AQ_GlobalControl_APPIA_upRunStallOverride 1 +/*! \brief Preprocessor variable to relate field to bit position in structure upRunStallOverride in AQ_GlobalControl_APPIA */ +#define bits_AQ_GlobalControl_APPIA_upRunStallOverride u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure upRunStallOverride in AQ_GlobalControl_APPIA */ +#define word_AQ_GlobalControl_APPIA_upRunStallOverride u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure upRunStall in AQ_GlobalControl_APPIA */ +#define AQ_GlobalControl_APPIA_upRunStall 1 +/*! \brief Preprocessor variable to relate field to bit position in structure upRunStall in AQ_GlobalControl_APPIA */ +#define bits_AQ_GlobalControl_APPIA_upRunStall u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure upRunStall in AQ_GlobalControl_APPIA */ +#define word_AQ_GlobalControl_APPIA_upRunStall u1.word_1 + +/*! \brief Base register address of structure AQ_GlobalResetControl_APPIA */ +#define AQ_GlobalResetControl_APPIA_baseRegisterAddress 0xC006 +/*! \brief MMD address of structure AQ_GlobalResetControl_APPIA */ +#define AQ_GlobalResetControl_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure globalMMD_ResetDisable in AQ_GlobalResetControl_APPIA */ +#define AQ_GlobalResetControl_APPIA_globalMMD_ResetDisable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure globalMMD_ResetDisable in AQ_GlobalResetControl_APPIA */ +#define bits_AQ_GlobalResetControl_APPIA_globalMMD_ResetDisable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure globalMMD_ResetDisable in AQ_GlobalResetControl_APPIA */ +#define word_AQ_GlobalResetControl_APPIA_globalMMD_ResetDisable u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalDiagnosticProvisioning_APPIA */ +#define AQ_GlobalDiagnosticProvisioning_APPIA_baseRegisterAddress 0xC400 +/*! \brief MMD address of structure AQ_GlobalDiagnosticProvisioning_APPIA */ +#define AQ_GlobalDiagnosticProvisioning_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure enableDiagnostics in AQ_GlobalDiagnosticProvisioning_APPIA */ +#define AQ_GlobalDiagnosticProvisioning_APPIA_enableDiagnostics 0 +/*! \brief Preprocessor variable to relate field to bit position in structure enableDiagnostics in AQ_GlobalDiagnosticProvisioning_APPIA */ +#define bits_AQ_GlobalDiagnosticProvisioning_APPIA_enableDiagnostics u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure enableDiagnostics in AQ_GlobalDiagnosticProvisioning_APPIA */ +#define word_AQ_GlobalDiagnosticProvisioning_APPIA_enableDiagnostics u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalThermalProvisioning_APPIA */ +#define AQ_GlobalThermalProvisioning_APPIA_baseRegisterAddress 0xC420 +/*! \brief MMD address of structure AQ_GlobalThermalProvisioning_APPIA */ +#define AQ_GlobalThermalProvisioning_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure reserved_0 in AQ_GlobalThermalProvisioning_APPIA */ +#define AQ_GlobalThermalProvisioning_APPIA_reserved_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_0 in AQ_GlobalThermalProvisioning_APPIA */ +#define bits_AQ_GlobalThermalProvisioning_APPIA_reserved_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_0 in AQ_GlobalThermalProvisioning_APPIA */ +#define word_AQ_GlobalThermalProvisioning_APPIA_reserved_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure highTempFailureThreshold in AQ_GlobalThermalProvisioning_APPIA */ +#define AQ_GlobalThermalProvisioning_APPIA_highTempFailureThreshold 1 +/*! \brief Preprocessor variable to relate field to bit position in structure highTempFailureThreshold in AQ_GlobalThermalProvisioning_APPIA */ +#define bits_AQ_GlobalThermalProvisioning_APPIA_highTempFailureThreshold u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure highTempFailureThreshold in AQ_GlobalThermalProvisioning_APPIA */ +#define word_AQ_GlobalThermalProvisioning_APPIA_highTempFailureThreshold u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure lowTempFailureThreshold in AQ_GlobalThermalProvisioning_APPIA */ +#define AQ_GlobalThermalProvisioning_APPIA_lowTempFailureThreshold 2 +/*! \brief Preprocessor variable to relate field to bit position in structure lowTempFailureThreshold in AQ_GlobalThermalProvisioning_APPIA */ +#define bits_AQ_GlobalThermalProvisioning_APPIA_lowTempFailureThreshold u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure lowTempFailureThreshold in AQ_GlobalThermalProvisioning_APPIA */ +#define word_AQ_GlobalThermalProvisioning_APPIA_lowTempFailureThreshold u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure highTempWarningThreshold in AQ_GlobalThermalProvisioning_APPIA */ +#define AQ_GlobalThermalProvisioning_APPIA_highTempWarningThreshold 3 +/*! \brief Preprocessor variable to relate field to bit position in structure highTempWarningThreshold in AQ_GlobalThermalProvisioning_APPIA */ +#define bits_AQ_GlobalThermalProvisioning_APPIA_highTempWarningThreshold u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure highTempWarningThreshold in AQ_GlobalThermalProvisioning_APPIA */ +#define word_AQ_GlobalThermalProvisioning_APPIA_highTempWarningThreshold u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure lowTempWarningThreshold in AQ_GlobalThermalProvisioning_APPIA */ +#define AQ_GlobalThermalProvisioning_APPIA_lowTempWarningThreshold 4 +/*! \brief Preprocessor variable to relate field to bit position in structure lowTempWarningThreshold in AQ_GlobalThermalProvisioning_APPIA */ +#define bits_AQ_GlobalThermalProvisioning_APPIA_lowTempWarningThreshold u4.bits_4 +/*! \brief Preprocessor variable to relate field to word position in structure lowTempWarningThreshold in AQ_GlobalThermalProvisioning_APPIA */ +#define word_AQ_GlobalThermalProvisioning_APPIA_lowTempWarningThreshold u4.word_4 + +/*! \brief Base register address of structure AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_baseRegisterAddress 0xC430 +/*! \brief MMD address of structure AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure led_0ManualSet in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_0ManualSet 0 +/*! \brief Preprocessor variable to relate field to bit position in structure led_0ManualSet in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_0ManualSet u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure led_0ManualSet in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_0ManualSet u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure led_0_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_0_10Gb_sLinkEstablished 0 +/*! \brief Preprocessor variable to relate field to bit position in structure led_0_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_0_10Gb_sLinkEstablished u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure led_0_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_0_10Gb_sLinkEstablished u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure led_0_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_0_1Gb_sLinkEstablished 0 +/*! \brief Preprocessor variable to relate field to bit position in structure led_0_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_0_1Gb_sLinkEstablished u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure led_0_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_0_1Gb_sLinkEstablished u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure led_0_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_0_100Mb_sLinkEstablished 0 +/*! \brief Preprocessor variable to relate field to bit position in structure led_0_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_0_100Mb_sLinkEstablished u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure led_0_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_0_100Mb_sLinkEstablished u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure led_0Connecting in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_0Connecting 0 +/*! \brief Preprocessor variable to relate field to bit position in structure led_0Connecting in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_0Connecting u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure led_0Connecting in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_0Connecting u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure led_0ReceiveActivity in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_0ReceiveActivity 0 +/*! \brief Preprocessor variable to relate field to bit position in structure led_0ReceiveActivity in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_0ReceiveActivity u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure led_0ReceiveActivity in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_0ReceiveActivity u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure led_0TransmitActivity in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_0TransmitActivity 0 +/*! \brief Preprocessor variable to relate field to bit position in structure led_0TransmitActivity in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_0TransmitActivity u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure led_0TransmitActivity in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_0TransmitActivity u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure led_0ActivityStretch in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_0ActivityStretch 0 +/*! \brief Preprocessor variable to relate field to bit position in structure led_0ActivityStretch in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_0ActivityStretch u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure led_0ActivityStretch in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_0ActivityStretch u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure led_1ManualSet in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_1ManualSet 1 +/*! \brief Preprocessor variable to relate field to bit position in structure led_1ManualSet in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_1ManualSet u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure led_1ManualSet in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_1ManualSet u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure led_1_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_1_10Gb_sLinkEstablished 1 +/*! \brief Preprocessor variable to relate field to bit position in structure led_1_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_1_10Gb_sLinkEstablished u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure led_1_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_1_10Gb_sLinkEstablished u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure led_1_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_1_1Gb_sLinkEstablished 1 +/*! \brief Preprocessor variable to relate field to bit position in structure led_1_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_1_1Gb_sLinkEstablished u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure led_1_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_1_1Gb_sLinkEstablished u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure led_1_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_1_100Mb_sLinkEstablished 1 +/*! \brief Preprocessor variable to relate field to bit position in structure led_1_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_1_100Mb_sLinkEstablished u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure led_1_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_1_100Mb_sLinkEstablished u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure led_1Connecting in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_1Connecting 1 +/*! \brief Preprocessor variable to relate field to bit position in structure led_1Connecting in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_1Connecting u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure led_1Connecting in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_1Connecting u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure led_1ReceiveActivity in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_1ReceiveActivity 1 +/*! \brief Preprocessor variable to relate field to bit position in structure led_1ReceiveActivity in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_1ReceiveActivity u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure led_1ReceiveActivity in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_1ReceiveActivity u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure led_1TransmitActivity in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_1TransmitActivity 1 +/*! \brief Preprocessor variable to relate field to bit position in structure led_1TransmitActivity in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_1TransmitActivity u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure led_1TransmitActivity in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_1TransmitActivity u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure led_1ActivityStretch in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_1ActivityStretch 1 +/*! \brief Preprocessor variable to relate field to bit position in structure led_1ActivityStretch in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_1ActivityStretch u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure led_1ActivityStretch in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_1ActivityStretch u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure led_2ManualSet in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_2ManualSet 2 +/*! \brief Preprocessor variable to relate field to bit position in structure led_2ManualSet in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_2ManualSet u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure led_2ManualSet in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_2ManualSet u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure led_2_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_2_10Gb_sLinkEstablished 2 +/*! \brief Preprocessor variable to relate field to bit position in structure led_2_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_2_10Gb_sLinkEstablished u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure led_2_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_2_10Gb_sLinkEstablished u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure led_2_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_2_1Gb_sLinkEstablished 2 +/*! \brief Preprocessor variable to relate field to bit position in structure led_2_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_2_1Gb_sLinkEstablished u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure led_2_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_2_1Gb_sLinkEstablished u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure led_2_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_2_100Mb_sLinkEstablished 2 +/*! \brief Preprocessor variable to relate field to bit position in structure led_2_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_2_100Mb_sLinkEstablished u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure led_2_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_2_100Mb_sLinkEstablished u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure led_2Connecting in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_2Connecting 2 +/*! \brief Preprocessor variable to relate field to bit position in structure led_2Connecting in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_2Connecting u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure led_2Connecting in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_2Connecting u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure led_2ReceiveActivity in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_2ReceiveActivity 2 +/*! \brief Preprocessor variable to relate field to bit position in structure led_2ReceiveActivity in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_2ReceiveActivity u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure led_2ReceiveActivity in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_2ReceiveActivity u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure led_2TransmitActivity in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_2TransmitActivity 2 +/*! \brief Preprocessor variable to relate field to bit position in structure led_2TransmitActivity in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_2TransmitActivity u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure led_2TransmitActivity in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_2TransmitActivity u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure led_2ActivityStretch in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_2ActivityStretch 2 +/*! \brief Preprocessor variable to relate field to bit position in structure led_2ActivityStretch in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_2ActivityStretch u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure led_2ActivityStretch in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_2ActivityStretch u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure led_3ManualSet in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_3ManualSet 3 +/*! \brief Preprocessor variable to relate field to bit position in structure led_3ManualSet in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_3ManualSet u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure led_3ManualSet in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_3ManualSet u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure led_3_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_3_10Gb_sLinkEstablished 3 +/*! \brief Preprocessor variable to relate field to bit position in structure led_3_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_3_10Gb_sLinkEstablished u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure led_3_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_3_10Gb_sLinkEstablished u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure led_3_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_3_1Gb_sLinkEstablished 3 +/*! \brief Preprocessor variable to relate field to bit position in structure led_3_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_3_1Gb_sLinkEstablished u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure led_3_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_3_1Gb_sLinkEstablished u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure led_3_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_3_100Mb_sLinkEstablished 3 +/*! \brief Preprocessor variable to relate field to bit position in structure led_3_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_3_100Mb_sLinkEstablished u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure led_3_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_3_100Mb_sLinkEstablished u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure led_3Connecting in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_3Connecting 3 +/*! \brief Preprocessor variable to relate field to bit position in structure led_3Connecting in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_3Connecting u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure led_3Connecting in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_3Connecting u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure led_3ReceiveActivity in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_3ReceiveActivity 3 +/*! \brief Preprocessor variable to relate field to bit position in structure led_3ReceiveActivity in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_3ReceiveActivity u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure led_3ReceiveActivity in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_3ReceiveActivity u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure led_3TransmitActivity in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_3TransmitActivity 3 +/*! \brief Preprocessor variable to relate field to bit position in structure led_3TransmitActivity in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_3TransmitActivity u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure led_3TransmitActivity in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_3TransmitActivity u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure led_3ActivityStretch in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_3ActivityStretch 3 +/*! \brief Preprocessor variable to relate field to bit position in structure led_3ActivityStretch in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_3ActivityStretch u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure led_3ActivityStretch in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_3ActivityStretch u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure led_4ManualSet in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_4ManualSet 4 +/*! \brief Preprocessor variable to relate field to bit position in structure led_4ManualSet in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_4ManualSet u4.bits_4 +/*! \brief Preprocessor variable to relate field to word position in structure led_4ManualSet in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_4ManualSet u4.word_4 +/*! \brief Preprocessor variable to relate field to word number in structure led_4_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_4_10Gb_sLinkEstablished 4 +/*! \brief Preprocessor variable to relate field to bit position in structure led_4_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_4_10Gb_sLinkEstablished u4.bits_4 +/*! \brief Preprocessor variable to relate field to word position in structure led_4_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_4_10Gb_sLinkEstablished u4.word_4 +/*! \brief Preprocessor variable to relate field to word number in structure led_4_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_4_1Gb_sLinkEstablished 4 +/*! \brief Preprocessor variable to relate field to bit position in structure led_4_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_4_1Gb_sLinkEstablished u4.bits_4 +/*! \brief Preprocessor variable to relate field to word position in structure led_4_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_4_1Gb_sLinkEstablished u4.word_4 +/*! \brief Preprocessor variable to relate field to word number in structure led_4_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_4_100Mb_sLinkEstablished 4 +/*! \brief Preprocessor variable to relate field to bit position in structure led_4_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_4_100Mb_sLinkEstablished u4.bits_4 +/*! \brief Preprocessor variable to relate field to word position in structure led_4_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_4_100Mb_sLinkEstablished u4.word_4 +/*! \brief Preprocessor variable to relate field to word number in structure led_4Connecting in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_4Connecting 4 +/*! \brief Preprocessor variable to relate field to bit position in structure led_4Connecting in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_4Connecting u4.bits_4 +/*! \brief Preprocessor variable to relate field to word position in structure led_4Connecting in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_4Connecting u4.word_4 +/*! \brief Preprocessor variable to relate field to word number in structure led_4ReceiveActivity in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_4ReceiveActivity 4 +/*! \brief Preprocessor variable to relate field to bit position in structure led_4ReceiveActivity in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_4ReceiveActivity u4.bits_4 +/*! \brief Preprocessor variable to relate field to word position in structure led_4ReceiveActivity in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_4ReceiveActivity u4.word_4 +/*! \brief Preprocessor variable to relate field to word number in structure led_4TransmitActivity in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_4TransmitActivity 4 +/*! \brief Preprocessor variable to relate field to bit position in structure led_4TransmitActivity in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_4TransmitActivity u4.bits_4 +/*! \brief Preprocessor variable to relate field to word position in structure led_4TransmitActivity in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_4TransmitActivity u4.word_4 +/*! \brief Preprocessor variable to relate field to word number in structure led_4ActivityStretch in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_4ActivityStretch 4 +/*! \brief Preprocessor variable to relate field to bit position in structure led_4ActivityStretch in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_4ActivityStretch u4.bits_4 +/*! \brief Preprocessor variable to relate field to word position in structure led_4ActivityStretch in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_4ActivityStretch u4.word_4 +/*! \brief Preprocessor variable to relate field to word number in structure led_5ManualSet in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_5ManualSet 5 +/*! \brief Preprocessor variable to relate field to bit position in structure led_5ManualSet in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_5ManualSet u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure led_5ManualSet in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_5ManualSet u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure led_5_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_5_10Gb_sLinkEstablished 5 +/*! \brief Preprocessor variable to relate field to bit position in structure led_5_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_5_10Gb_sLinkEstablished u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure led_5_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_5_10Gb_sLinkEstablished u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure led_5_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_5_1Gb_sLinkEstablished 5 +/*! \brief Preprocessor variable to relate field to bit position in structure led_5_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_5_1Gb_sLinkEstablished u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure led_5_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_5_1Gb_sLinkEstablished u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure led_5_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_5_100Mb_sLinkEstablished 5 +/*! \brief Preprocessor variable to relate field to bit position in structure led_5_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_5_100Mb_sLinkEstablished u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure led_5_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_5_100Mb_sLinkEstablished u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure led_5Connecting in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_5Connecting 5 +/*! \brief Preprocessor variable to relate field to bit position in structure led_5Connecting in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_5Connecting u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure led_5Connecting in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_5Connecting u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure led_5ReceiveActivity in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_5ReceiveActivity 5 +/*! \brief Preprocessor variable to relate field to bit position in structure led_5ReceiveActivity in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_5ReceiveActivity u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure led_5ReceiveActivity in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_5ReceiveActivity u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure led_5TransmitActivity in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_5TransmitActivity 5 +/*! \brief Preprocessor variable to relate field to bit position in structure led_5TransmitActivity in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_5TransmitActivity u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure led_5TransmitActivity in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_5TransmitActivity u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure led_5ActivityStretch in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_5ActivityStretch 5 +/*! \brief Preprocessor variable to relate field to bit position in structure led_5ActivityStretch in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_5ActivityStretch u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure led_5ActivityStretch in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_5ActivityStretch u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure ledOperationMode in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_ledOperationMode 7 +/*! \brief Preprocessor variable to relate field to bit position in structure ledOperationMode in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_ledOperationMode u7.bits_7 +/*! \brief Preprocessor variable to relate field to word position in structure ledOperationMode in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_ledOperationMode u7.word_7 +/*! \brief Preprocessor variable to relate field to word number in structure led_0DriveThreeStateSelect in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_0DriveThreeStateSelect 8 +/*! \brief Preprocessor variable to relate field to bit position in structure led_0DriveThreeStateSelect in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_0DriveThreeStateSelect u8.bits_8 +/*! \brief Preprocessor variable to relate field to word position in structure led_0DriveThreeStateSelect in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_0DriveThreeStateSelect u8.word_8 +/*! \brief Preprocessor variable to relate field to word number in structure led_0ActiveHighSelect in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_0ActiveHighSelect 8 +/*! \brief Preprocessor variable to relate field to bit position in structure led_0ActiveHighSelect in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_0ActiveHighSelect u8.bits_8 +/*! \brief Preprocessor variable to relate field to word position in structure led_0ActiveHighSelect in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_0ActiveHighSelect u8.word_8 +/*! \brief Preprocessor variable to relate field to word number in structure led_0ManualActiveSelect in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_0ManualActiveSelect 8 +/*! \brief Preprocessor variable to relate field to bit position in structure led_0ManualActiveSelect in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_0ManualActiveSelect u8.bits_8 +/*! \brief Preprocessor variable to relate field to word position in structure led_0ManualActiveSelect in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_0ManualActiveSelect u8.word_8 +/*! \brief Preprocessor variable to relate field to word number in structure led_1DriveThreeStateSelect in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_1DriveThreeStateSelect 9 +/*! \brief Preprocessor variable to relate field to bit position in structure led_1DriveThreeStateSelect in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_1DriveThreeStateSelect u9.bits_9 +/*! \brief Preprocessor variable to relate field to word position in structure led_1DriveThreeStateSelect in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_1DriveThreeStateSelect u9.word_9 +/*! \brief Preprocessor variable to relate field to word number in structure led_1ActiveHighSelect in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_1ActiveHighSelect 9 +/*! \brief Preprocessor variable to relate field to bit position in structure led_1ActiveHighSelect in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_1ActiveHighSelect u9.bits_9 +/*! \brief Preprocessor variable to relate field to word position in structure led_1ActiveHighSelect in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_1ActiveHighSelect u9.word_9 +/*! \brief Preprocessor variable to relate field to word number in structure led_1ManualActiveSelect in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_1ManualActiveSelect 9 +/*! \brief Preprocessor variable to relate field to bit position in structure led_1ManualActiveSelect in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_1ManualActiveSelect u9.bits_9 +/*! \brief Preprocessor variable to relate field to word position in structure led_1ManualActiveSelect in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_1ManualActiveSelect u9.word_9 +/*! \brief Preprocessor variable to relate field to word number in structure led_2DriveThreeStateSelect in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_2DriveThreeStateSelect 10 +/*! \brief Preprocessor variable to relate field to bit position in structure led_2DriveThreeStateSelect in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_2DriveThreeStateSelect u10.bits_10 +/*! \brief Preprocessor variable to relate field to word position in structure led_2DriveThreeStateSelect in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_2DriveThreeStateSelect u10.word_10 +/*! \brief Preprocessor variable to relate field to word number in structure led_2ActiveHighSelect in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_2ActiveHighSelect 10 +/*! \brief Preprocessor variable to relate field to bit position in structure led_2ActiveHighSelect in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_2ActiveHighSelect u10.bits_10 +/*! \brief Preprocessor variable to relate field to word position in structure led_2ActiveHighSelect in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_2ActiveHighSelect u10.word_10 +/*! \brief Preprocessor variable to relate field to word number in structure led_2ManualActiveSelect in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_2ManualActiveSelect 10 +/*! \brief Preprocessor variable to relate field to bit position in structure led_2ManualActiveSelect in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_2ManualActiveSelect u10.bits_10 +/*! \brief Preprocessor variable to relate field to word position in structure led_2ManualActiveSelect in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_2ManualActiveSelect u10.word_10 +/*! \brief Preprocessor variable to relate field to word number in structure led_3DriveThreeStateSelect in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_3DriveThreeStateSelect 11 +/*! \brief Preprocessor variable to relate field to bit position in structure led_3DriveThreeStateSelect in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_3DriveThreeStateSelect u11.bits_11 +/*! \brief Preprocessor variable to relate field to word position in structure led_3DriveThreeStateSelect in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_3DriveThreeStateSelect u11.word_11 +/*! \brief Preprocessor variable to relate field to word number in structure led_3ActiveHighSelect in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_3ActiveHighSelect 11 +/*! \brief Preprocessor variable to relate field to bit position in structure led_3ActiveHighSelect in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_3ActiveHighSelect u11.bits_11 +/*! \brief Preprocessor variable to relate field to word position in structure led_3ActiveHighSelect in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_3ActiveHighSelect u11.word_11 +/*! \brief Preprocessor variable to relate field to word number in structure led_3ManualActiveSelect in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_3ManualActiveSelect 11 +/*! \brief Preprocessor variable to relate field to bit position in structure led_3ManualActiveSelect in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_3ManualActiveSelect u11.bits_11 +/*! \brief Preprocessor variable to relate field to word position in structure led_3ManualActiveSelect in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_3ManualActiveSelect u11.word_11 +/*! \brief Preprocessor variable to relate field to word number in structure led_4DriveThreeStateSelect in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_4DriveThreeStateSelect 12 +/*! \brief Preprocessor variable to relate field to bit position in structure led_4DriveThreeStateSelect in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_4DriveThreeStateSelect u12.bits_12 +/*! \brief Preprocessor variable to relate field to word position in structure led_4DriveThreeStateSelect in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_4DriveThreeStateSelect u12.word_12 +/*! \brief Preprocessor variable to relate field to word number in structure led_4ActiveHighSelect in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_4ActiveHighSelect 12 +/*! \brief Preprocessor variable to relate field to bit position in structure led_4ActiveHighSelect in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_4ActiveHighSelect u12.bits_12 +/*! \brief Preprocessor variable to relate field to word position in structure led_4ActiveHighSelect in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_4ActiveHighSelect u12.word_12 +/*! \brief Preprocessor variable to relate field to word number in structure led_4ManualActiveSelect in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_4ManualActiveSelect 12 +/*! \brief Preprocessor variable to relate field to bit position in structure led_4ManualActiveSelect in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_4ManualActiveSelect u12.bits_12 +/*! \brief Preprocessor variable to relate field to word position in structure led_4ManualActiveSelect in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_4ManualActiveSelect u12.word_12 +/*! \brief Preprocessor variable to relate field to word number in structure led_5DriveThreeStateSelect in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_5DriveThreeStateSelect 13 +/*! \brief Preprocessor variable to relate field to bit position in structure led_5DriveThreeStateSelect in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_5DriveThreeStateSelect u13.bits_13 +/*! \brief Preprocessor variable to relate field to word position in structure led_5DriveThreeStateSelect in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_5DriveThreeStateSelect u13.word_13 +/*! \brief Preprocessor variable to relate field to word number in structure led_5ActiveHighSelect in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_5ActiveHighSelect 13 +/*! \brief Preprocessor variable to relate field to bit position in structure led_5ActiveHighSelect in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_5ActiveHighSelect u13.bits_13 +/*! \brief Preprocessor variable to relate field to word position in structure led_5ActiveHighSelect in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_5ActiveHighSelect u13.word_13 +/*! \brief Preprocessor variable to relate field to word number in structure led_5ManualActiveSelect in AQ_GlobalLedProvisioning_APPIA */ +#define AQ_GlobalLedProvisioning_APPIA_led_5ManualActiveSelect 13 +/*! \brief Preprocessor variable to relate field to bit position in structure led_5ManualActiveSelect in AQ_GlobalLedProvisioning_APPIA */ +#define bits_AQ_GlobalLedProvisioning_APPIA_led_5ManualActiveSelect u13.bits_13 +/*! \brief Preprocessor variable to relate field to word position in structure led_5ManualActiveSelect in AQ_GlobalLedProvisioning_APPIA */ +#define word_AQ_GlobalLedProvisioning_APPIA_led_5ManualActiveSelect u13.word_13 + +/*! \brief Base register address of structure AQ_GlobalGeneralProvisioning_APPIA */ +#define AQ_GlobalGeneralProvisioning_APPIA_baseRegisterAddress 0xC440 +/*! \brief MMD address of structure AQ_GlobalGeneralProvisioning_APPIA */ +#define AQ_GlobalGeneralProvisioning_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure gangLoadMdioAddress in AQ_GlobalGeneralProvisioning_APPIA */ +#define AQ_GlobalGeneralProvisioning_APPIA_gangLoadMdioAddress 0 +/*! \brief Preprocessor variable to relate field to bit position in structure gangLoadMdioAddress in AQ_GlobalGeneralProvisioning_APPIA */ +#define bits_AQ_GlobalGeneralProvisioning_APPIA_gangLoadMdioAddress u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure gangLoadMdioAddress in AQ_GlobalGeneralProvisioning_APPIA */ +#define word_AQ_GlobalGeneralProvisioning_APPIA_gangLoadMdioAddress u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure gangLoadMdioWriteOnly in AQ_GlobalGeneralProvisioning_APPIA */ +#define AQ_GlobalGeneralProvisioning_APPIA_gangLoadMdioWriteOnly 0 +/*! \brief Preprocessor variable to relate field to bit position in structure gangLoadMdioWriteOnly in AQ_GlobalGeneralProvisioning_APPIA */ +#define bits_AQ_GlobalGeneralProvisioning_APPIA_gangLoadMdioWriteOnly u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure gangLoadMdioWriteOnly in AQ_GlobalGeneralProvisioning_APPIA */ +#define word_AQ_GlobalGeneralProvisioning_APPIA_gangLoadMdioWriteOnly u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mdioBroadcastModeEnable in AQ_GlobalGeneralProvisioning_APPIA */ +#define AQ_GlobalGeneralProvisioning_APPIA_mdioBroadcastModeEnable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioBroadcastModeEnable in AQ_GlobalGeneralProvisioning_APPIA */ +#define bits_AQ_GlobalGeneralProvisioning_APPIA_mdioBroadcastModeEnable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mdioBroadcastModeEnable in AQ_GlobalGeneralProvisioning_APPIA */ +#define word_AQ_GlobalGeneralProvisioning_APPIA_mdioBroadcastModeEnable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mdioReadMSW_FirstEnable in AQ_GlobalGeneralProvisioning_APPIA */ +#define AQ_GlobalGeneralProvisioning_APPIA_mdioReadMSW_FirstEnable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioReadMSW_FirstEnable in AQ_GlobalGeneralProvisioning_APPIA */ +#define bits_AQ_GlobalGeneralProvisioning_APPIA_mdioReadMSW_FirstEnable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mdioReadMSW_FirstEnable in AQ_GlobalGeneralProvisioning_APPIA */ +#define word_AQ_GlobalGeneralProvisioning_APPIA_mdioReadMSW_FirstEnable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mdioDriveConfiguration in AQ_GlobalGeneralProvisioning_APPIA */ +#define AQ_GlobalGeneralProvisioning_APPIA_mdioDriveConfiguration 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioDriveConfiguration in AQ_GlobalGeneralProvisioning_APPIA */ +#define bits_AQ_GlobalGeneralProvisioning_APPIA_mdioDriveConfiguration u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mdioDriveConfiguration in AQ_GlobalGeneralProvisioning_APPIA */ +#define word_AQ_GlobalGeneralProvisioning_APPIA_mdioDriveConfiguration u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mdioPreambleDetectionDisable in AQ_GlobalGeneralProvisioning_APPIA */ +#define AQ_GlobalGeneralProvisioning_APPIA_mdioPreambleDetectionDisable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioPreambleDetectionDisable in AQ_GlobalGeneralProvisioning_APPIA */ +#define bits_AQ_GlobalGeneralProvisioning_APPIA_mdioPreambleDetectionDisable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mdioPreambleDetectionDisable in AQ_GlobalGeneralProvisioning_APPIA */ +#define word_AQ_GlobalGeneralProvisioning_APPIA_mdioPreambleDetectionDisable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mdioAddressReset in AQ_GlobalGeneralProvisioning_APPIA */ +#define AQ_GlobalGeneralProvisioning_APPIA_mdioAddressReset 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioAddressReset in AQ_GlobalGeneralProvisioning_APPIA */ +#define bits_AQ_GlobalGeneralProvisioning_APPIA_mdioAddressReset u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mdioAddressReset in AQ_GlobalGeneralProvisioning_APPIA */ +#define word_AQ_GlobalGeneralProvisioning_APPIA_mdioAddressReset u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure daisyChainReset in AQ_GlobalGeneralProvisioning_APPIA */ +#define AQ_GlobalGeneralProvisioning_APPIA_daisyChainReset 2 +/*! \brief Preprocessor variable to relate field to bit position in structure daisyChainReset in AQ_GlobalGeneralProvisioning_APPIA */ +#define bits_AQ_GlobalGeneralProvisioning_APPIA_daisyChainReset u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure daisyChainReset in AQ_GlobalGeneralProvisioning_APPIA */ +#define word_AQ_GlobalGeneralProvisioning_APPIA_daisyChainReset u2.word_2 + +/*! \brief Base register address of structure AQ_GlobalNvrProvisioning_APPIA */ +#define AQ_GlobalNvrProvisioning_APPIA_baseRegisterAddress 0xC450 +/*! \brief MMD address of structure AQ_GlobalNvrProvisioning_APPIA */ +#define AQ_GlobalNvrProvisioning_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure nvrDataLength in AQ_GlobalNvrProvisioning_APPIA */ +#define AQ_GlobalNvrProvisioning_APPIA_nvrDataLength 0 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrDataLength in AQ_GlobalNvrProvisioning_APPIA */ +#define bits_AQ_GlobalNvrProvisioning_APPIA_nvrDataLength u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure nvrDataLength in AQ_GlobalNvrProvisioning_APPIA */ +#define word_AQ_GlobalNvrProvisioning_APPIA_nvrDataLength u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure nvrDummyLength in AQ_GlobalNvrProvisioning_APPIA */ +#define AQ_GlobalNvrProvisioning_APPIA_nvrDummyLength 0 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrDummyLength in AQ_GlobalNvrProvisioning_APPIA */ +#define bits_AQ_GlobalNvrProvisioning_APPIA_nvrDummyLength u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure nvrDummyLength in AQ_GlobalNvrProvisioning_APPIA */ +#define word_AQ_GlobalNvrProvisioning_APPIA_nvrDummyLength u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure nvrAddressLength in AQ_GlobalNvrProvisioning_APPIA */ +#define AQ_GlobalNvrProvisioning_APPIA_nvrAddressLength 0 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrAddressLength in AQ_GlobalNvrProvisioning_APPIA */ +#define bits_AQ_GlobalNvrProvisioning_APPIA_nvrAddressLength u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure nvrAddressLength in AQ_GlobalNvrProvisioning_APPIA */ +#define word_AQ_GlobalNvrProvisioning_APPIA_nvrAddressLength u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure nvrAddressLengthOverride in AQ_GlobalNvrProvisioning_APPIA */ +#define AQ_GlobalNvrProvisioning_APPIA_nvrAddressLengthOverride 1 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrAddressLengthOverride in AQ_GlobalNvrProvisioning_APPIA */ +#define bits_AQ_GlobalNvrProvisioning_APPIA_nvrAddressLengthOverride u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure nvrAddressLengthOverride in AQ_GlobalNvrProvisioning_APPIA */ +#define word_AQ_GlobalNvrProvisioning_APPIA_nvrAddressLengthOverride u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure nvrClockDivide in AQ_GlobalNvrProvisioning_APPIA */ +#define AQ_GlobalNvrProvisioning_APPIA_nvrClockDivide 1 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrClockDivide in AQ_GlobalNvrProvisioning_APPIA */ +#define bits_AQ_GlobalNvrProvisioning_APPIA_nvrClockDivide u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure nvrClockDivide in AQ_GlobalNvrProvisioning_APPIA */ +#define word_AQ_GlobalNvrProvisioning_APPIA_nvrClockDivide u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure nvrDaisyChainClockDivideOverride in AQ_GlobalNvrProvisioning_APPIA */ +#define AQ_GlobalNvrProvisioning_APPIA_nvrDaisyChainClockDivideOverride 2 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrDaisyChainClockDivideOverride in AQ_GlobalNvrProvisioning_APPIA */ +#define bits_AQ_GlobalNvrProvisioning_APPIA_nvrDaisyChainClockDivideOverride u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure nvrDaisyChainClockDivideOverride in AQ_GlobalNvrProvisioning_APPIA */ +#define word_AQ_GlobalNvrProvisioning_APPIA_nvrDaisyChainClockDivideOverride u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure nvrDaisyChainDisable in AQ_GlobalNvrProvisioning_APPIA */ +#define AQ_GlobalNvrProvisioning_APPIA_nvrDaisyChainDisable 2 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrDaisyChainDisable in AQ_GlobalNvrProvisioning_APPIA */ +#define bits_AQ_GlobalNvrProvisioning_APPIA_nvrDaisyChainDisable u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure nvrDaisyChainDisable in AQ_GlobalNvrProvisioning_APPIA */ +#define word_AQ_GlobalNvrProvisioning_APPIA_nvrDaisyChainDisable u2.word_2 + +/*! \brief Base register address of structure AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_baseRegisterAddress 0xC470 +/*! \brief MMD address of structure AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure diagnosticsSelect in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_diagnosticsSelect 0 +/*! \brief Preprocessor variable to relate field to bit position in structure diagnosticsSelect in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_diagnosticsSelect u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure diagnosticsSelect in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_diagnosticsSelect u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure extendedMdiDiagnosticsSelect in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_extendedMdiDiagnosticsSelect 0 +/*! \brief Preprocessor variable to relate field to bit position in structure extendedMdiDiagnosticsSelect in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_extendedMdiDiagnosticsSelect u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure extendedMdiDiagnosticsSelect in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_extendedMdiDiagnosticsSelect u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure initiateComponentDiagnostics in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_initiateComponentDiagnostics 0 +/*! \brief Preprocessor variable to relate field to bit position in structure initiateComponentDiagnostics in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_initiateComponentDiagnostics u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure initiateComponentDiagnostics in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_initiateComponentDiagnostics u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure initiateCableDiagnostics in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_initiateCableDiagnostics 0 +/*! \brief Preprocessor variable to relate field to bit position in structure initiateCableDiagnostics in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_initiateCableDiagnostics u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure initiateCableDiagnostics in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_initiateCableDiagnostics u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reservedProvisioning_2 in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_reservedProvisioning_2 1 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedProvisioning_2 in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_reservedProvisioning_2 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure reservedProvisioning_2 in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_reservedProvisioning_2 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure enableDaisy_chainHop_countOverride in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_enableDaisy_chainHop_countOverride 1 +/*! \brief Preprocessor variable to relate field to bit position in structure enableDaisy_chainHop_countOverride in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_enableDaisy_chainHop_countOverride u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure enableDaisy_chainHop_countOverride in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_enableDaisy_chainHop_countOverride u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure daisy_chainHop_countOverrideValue in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_daisy_chainHop_countOverrideValue 1 +/*! \brief Preprocessor variable to relate field to bit position in structure daisy_chainHop_countOverrideValue in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_daisy_chainHop_countOverrideValue u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure daisy_chainHop_countOverrideValue in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_daisy_chainHop_countOverrideValue u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure enableLvddPowerSupplyTuning in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_enableLvddPowerSupplyTuning 2 +/*! \brief Preprocessor variable to relate field to bit position in structure enableLvddPowerSupplyTuning in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_enableLvddPowerSupplyTuning u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure enableLvddPowerSupplyTuning in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_enableLvddPowerSupplyTuning u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure enableVddPowerSupplyTuning in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_enableVddPowerSupplyTuning 2 +/*! \brief Preprocessor variable to relate field to bit position in structure enableVddPowerSupplyTuning in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_enableVddPowerSupplyTuning u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure enableVddPowerSupplyTuning in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_enableVddPowerSupplyTuning u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure tunableExternalLvddPowerSupplyPresent in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_tunableExternalLvddPowerSupplyPresent 2 +/*! \brief Preprocessor variable to relate field to bit position in structure tunableExternalLvddPowerSupplyPresent in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_tunableExternalLvddPowerSupplyPresent u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure tunableExternalLvddPowerSupplyPresent in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_tunableExternalLvddPowerSupplyPresent u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure tunableExternalVddPowerSupplyPresent in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_tunableExternalVddPowerSupplyPresent 2 +/*! \brief Preprocessor variable to relate field to bit position in structure tunableExternalVddPowerSupplyPresent in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_tunableExternalVddPowerSupplyPresent u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure tunableExternalVddPowerSupplyPresent in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_tunableExternalVddPowerSupplyPresent u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure enableXenpakRegisterSpace in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_enableXenpakRegisterSpace 2 +/*! \brief Preprocessor variable to relate field to bit position in structure enableXenpakRegisterSpace in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_enableXenpakRegisterSpace u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure enableXenpakRegisterSpace in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_enableXenpakRegisterSpace u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure enable_5thChannelRfiCancellation in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_enable_5thChannelRfiCancellation 2 +/*! \brief Preprocessor variable to relate field to bit position in structure enable_5thChannelRfiCancellation in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_enable_5thChannelRfiCancellation u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure enable_5thChannelRfiCancellation in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_enable_5thChannelRfiCancellation u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure trainingSNR in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_trainingSNR 4 +/*! \brief Preprocessor variable to relate field to bit position in structure trainingSNR in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_trainingSNR u4.bits_4 +/*! \brief Preprocessor variable to relate field to word position in structure trainingSNR in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_trainingSNR u4.word_4 +/*! \brief Preprocessor variable to relate field to word number in structure smartPower_downStatus in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_smartPower_downStatus 5 +/*! \brief Preprocessor variable to relate field to bit position in structure smartPower_downStatus in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_smartPower_downStatus u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure smartPower_downStatus in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_smartPower_downStatus u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure reservedProvisioning_6 in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_reservedProvisioning_6 5 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedProvisioning_6 in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_reservedProvisioning_6 u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure reservedProvisioning_6 in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_reservedProvisioning_6 u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure cfrLpDisableTimer in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_cfrLpDisableTimer 5 +/*! \brief Preprocessor variable to relate field to bit position in structure cfrLpDisableTimer in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_cfrLpDisableTimer u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure cfrLpDisableTimer in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_cfrLpDisableTimer u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure cfrLpExtendedMaxwait in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_cfrLpExtendedMaxwait 5 +/*! \brief Preprocessor variable to relate field to bit position in structure cfrLpExtendedMaxwait in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_cfrLpExtendedMaxwait u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure cfrLpExtendedMaxwait in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_cfrLpExtendedMaxwait u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure cfrLpTHP in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_cfrLpTHP 5 +/*! \brief Preprocessor variable to relate field to bit position in structure cfrLpTHP in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_cfrLpTHP u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure cfrLpTHP in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_cfrLpTHP u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure cfrLpSupport in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_cfrLpSupport 5 +/*! \brief Preprocessor variable to relate field to bit position in structure cfrLpSupport in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_cfrLpSupport u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure cfrLpSupport in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_cfrLpSupport u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure cfrDisableTimer in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_cfrDisableTimer 5 +/*! \brief Preprocessor variable to relate field to bit position in structure cfrDisableTimer in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_cfrDisableTimer u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure cfrDisableTimer in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_cfrDisableTimer u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure cfrExtendedMaxwait in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_cfrExtendedMaxwait 5 +/*! \brief Preprocessor variable to relate field to bit position in structure cfrExtendedMaxwait in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_cfrExtendedMaxwait u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure cfrExtendedMaxwait in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_cfrExtendedMaxwait u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure cfrTHP in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_cfrTHP 5 +/*! \brief Preprocessor variable to relate field to bit position in structure cfrTHP in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_cfrTHP u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure cfrTHP in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_cfrTHP u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure cfrSupport in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_cfrSupport 5 +/*! \brief Preprocessor variable to relate field to bit position in structure cfrSupport in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_cfrSupport u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure cfrSupport in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_cfrSupport u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure deadlockAvoidanceEnable in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_deadlockAvoidanceEnable 5 +/*! \brief Preprocessor variable to relate field to bit position in structure deadlockAvoidanceEnable in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_deadlockAvoidanceEnable u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure deadlockAvoidanceEnable in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_deadlockAvoidanceEnable u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure smartPower_downEnable in AQ_GlobalReservedProvisioning_APPIA */ +#define AQ_GlobalReservedProvisioning_APPIA_smartPower_downEnable 5 +/*! \brief Preprocessor variable to relate field to bit position in structure smartPower_downEnable in AQ_GlobalReservedProvisioning_APPIA */ +#define bits_AQ_GlobalReservedProvisioning_APPIA_smartPower_downEnable u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure smartPower_downEnable in AQ_GlobalReservedProvisioning_APPIA */ +#define word_AQ_GlobalReservedProvisioning_APPIA_smartPower_downEnable u5.word_5 + +/*! \brief Base register address of structure AQ_GlobalCableDiagnosticStatus_APPIA */ +#define AQ_GlobalCableDiagnosticStatus_APPIA_baseRegisterAddress 0xC800 +/*! \brief MMD address of structure AQ_GlobalCableDiagnosticStatus_APPIA */ +#define AQ_GlobalCableDiagnosticStatus_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure pairAStatus in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define AQ_GlobalCableDiagnosticStatus_APPIA_pairAStatus 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pairAStatus in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define bits_AQ_GlobalCableDiagnosticStatus_APPIA_pairAStatus u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pairAStatus in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define word_AQ_GlobalCableDiagnosticStatus_APPIA_pairAStatus u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pairBStatus in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define AQ_GlobalCableDiagnosticStatus_APPIA_pairBStatus 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pairBStatus in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define bits_AQ_GlobalCableDiagnosticStatus_APPIA_pairBStatus u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pairBStatus in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define word_AQ_GlobalCableDiagnosticStatus_APPIA_pairBStatus u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pairCStatus in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define AQ_GlobalCableDiagnosticStatus_APPIA_pairCStatus 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pairCStatus in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define bits_AQ_GlobalCableDiagnosticStatus_APPIA_pairCStatus u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pairCStatus in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define word_AQ_GlobalCableDiagnosticStatus_APPIA_pairCStatus u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pairDStatus in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define AQ_GlobalCableDiagnosticStatus_APPIA_pairDStatus 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pairDStatus in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define bits_AQ_GlobalCableDiagnosticStatus_APPIA_pairDStatus u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pairDStatus in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define word_AQ_GlobalCableDiagnosticStatus_APPIA_pairDStatus u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pairAReflection_1 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define AQ_GlobalCableDiagnosticStatus_APPIA_pairAReflection_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure pairAReflection_1 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define bits_AQ_GlobalCableDiagnosticStatus_APPIA_pairAReflection_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure pairAReflection_1 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define word_AQ_GlobalCableDiagnosticStatus_APPIA_pairAReflection_1 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure pairAReflection_2 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define AQ_GlobalCableDiagnosticStatus_APPIA_pairAReflection_2 1 +/*! \brief Preprocessor variable to relate field to bit position in structure pairAReflection_2 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define bits_AQ_GlobalCableDiagnosticStatus_APPIA_pairAReflection_2 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure pairAReflection_2 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define word_AQ_GlobalCableDiagnosticStatus_APPIA_pairAReflection_2 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure impulseResponseMSW in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define AQ_GlobalCableDiagnosticStatus_APPIA_impulseResponseMSW 2 +/*! \brief Preprocessor variable to relate field to bit position in structure impulseResponseMSW in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define bits_AQ_GlobalCableDiagnosticStatus_APPIA_impulseResponseMSW u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure impulseResponseMSW in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define word_AQ_GlobalCableDiagnosticStatus_APPIA_impulseResponseMSW u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure pairBReflection_1 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define AQ_GlobalCableDiagnosticStatus_APPIA_pairBReflection_1 3 +/*! \brief Preprocessor variable to relate field to bit position in structure pairBReflection_1 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define bits_AQ_GlobalCableDiagnosticStatus_APPIA_pairBReflection_1 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure pairBReflection_1 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define word_AQ_GlobalCableDiagnosticStatus_APPIA_pairBReflection_1 u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure pairBReflection_2 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define AQ_GlobalCableDiagnosticStatus_APPIA_pairBReflection_2 3 +/*! \brief Preprocessor variable to relate field to bit position in structure pairBReflection_2 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define bits_AQ_GlobalCableDiagnosticStatus_APPIA_pairBReflection_2 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure pairBReflection_2 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define word_AQ_GlobalCableDiagnosticStatus_APPIA_pairBReflection_2 u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure impulseResponseLSW in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define AQ_GlobalCableDiagnosticStatus_APPIA_impulseResponseLSW 4 +/*! \brief Preprocessor variable to relate field to bit position in structure impulseResponseLSW in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define bits_AQ_GlobalCableDiagnosticStatus_APPIA_impulseResponseLSW u4.bits_4 +/*! \brief Preprocessor variable to relate field to word position in structure impulseResponseLSW in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define word_AQ_GlobalCableDiagnosticStatus_APPIA_impulseResponseLSW u4.word_4 +/*! \brief Preprocessor variable to relate field to word number in structure pairCReflection_1 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define AQ_GlobalCableDiagnosticStatus_APPIA_pairCReflection_1 5 +/*! \brief Preprocessor variable to relate field to bit position in structure pairCReflection_1 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define bits_AQ_GlobalCableDiagnosticStatus_APPIA_pairCReflection_1 u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure pairCReflection_1 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define word_AQ_GlobalCableDiagnosticStatus_APPIA_pairCReflection_1 u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure pairCReflection_2 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define AQ_GlobalCableDiagnosticStatus_APPIA_pairCReflection_2 5 +/*! \brief Preprocessor variable to relate field to bit position in structure pairCReflection_2 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define bits_AQ_GlobalCableDiagnosticStatus_APPIA_pairCReflection_2 u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure pairCReflection_2 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define word_AQ_GlobalCableDiagnosticStatus_APPIA_pairCReflection_2 u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_1 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define AQ_GlobalCableDiagnosticStatus_APPIA_reserved_1 6 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_1 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define bits_AQ_GlobalCableDiagnosticStatus_APPIA_reserved_1 u6.bits_6 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_1 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define word_AQ_GlobalCableDiagnosticStatus_APPIA_reserved_1 u6.word_6 +/*! \brief Preprocessor variable to relate field to word number in structure pairDReflection_1 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define AQ_GlobalCableDiagnosticStatus_APPIA_pairDReflection_1 7 +/*! \brief Preprocessor variable to relate field to bit position in structure pairDReflection_1 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define bits_AQ_GlobalCableDiagnosticStatus_APPIA_pairDReflection_1 u7.bits_7 +/*! \brief Preprocessor variable to relate field to word position in structure pairDReflection_1 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define word_AQ_GlobalCableDiagnosticStatus_APPIA_pairDReflection_1 u7.word_7 +/*! \brief Preprocessor variable to relate field to word number in structure pairDReflection_2 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define AQ_GlobalCableDiagnosticStatus_APPIA_pairDReflection_2 7 +/*! \brief Preprocessor variable to relate field to bit position in structure pairDReflection_2 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define bits_AQ_GlobalCableDiagnosticStatus_APPIA_pairDReflection_2 u7.bits_7 +/*! \brief Preprocessor variable to relate field to word position in structure pairDReflection_2 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define word_AQ_GlobalCableDiagnosticStatus_APPIA_pairDReflection_2 u7.word_7 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_2 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define AQ_GlobalCableDiagnosticStatus_APPIA_reserved_2 8 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_2 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define bits_AQ_GlobalCableDiagnosticStatus_APPIA_reserved_2 u8.bits_8 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_2 in AQ_GlobalCableDiagnosticStatus_APPIA */ +#define word_AQ_GlobalCableDiagnosticStatus_APPIA_reserved_2 u8.word_8 + +/*! \brief Base register address of structure AQ_GlobalThermalStatus_APPIA */ +#define AQ_GlobalThermalStatus_APPIA_baseRegisterAddress 0xC820 +/*! \brief MMD address of structure AQ_GlobalThermalStatus_APPIA */ +#define AQ_GlobalThermalStatus_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure temperature in AQ_GlobalThermalStatus_APPIA */ +#define AQ_GlobalThermalStatus_APPIA_temperature 0 +/*! \brief Preprocessor variable to relate field to bit position in structure temperature in AQ_GlobalThermalStatus_APPIA */ +#define bits_AQ_GlobalThermalStatus_APPIA_temperature u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure temperature in AQ_GlobalThermalStatus_APPIA */ +#define word_AQ_GlobalThermalStatus_APPIA_temperature u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure temperatureReady in AQ_GlobalThermalStatus_APPIA */ +#define AQ_GlobalThermalStatus_APPIA_temperatureReady 1 +/*! \brief Preprocessor variable to relate field to bit position in structure temperatureReady in AQ_GlobalThermalStatus_APPIA */ +#define bits_AQ_GlobalThermalStatus_APPIA_temperatureReady u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure temperatureReady in AQ_GlobalThermalStatus_APPIA */ +#define word_AQ_GlobalThermalStatus_APPIA_temperatureReady u1.word_1 + +/*! \brief Base register address of structure AQ_GlobalGeneralStatus_APPIA */ +#define AQ_GlobalGeneralStatus_APPIA_baseRegisterAddress 0xC830 +/*! \brief MMD address of structure AQ_GlobalGeneralStatus_APPIA */ +#define AQ_GlobalGeneralStatus_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure highTemperatureFailureState in AQ_GlobalGeneralStatus_APPIA */ +#define AQ_GlobalGeneralStatus_APPIA_highTemperatureFailureState 0 +/*! \brief Preprocessor variable to relate field to bit position in structure highTemperatureFailureState in AQ_GlobalGeneralStatus_APPIA */ +#define bits_AQ_GlobalGeneralStatus_APPIA_highTemperatureFailureState u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure highTemperatureFailureState in AQ_GlobalGeneralStatus_APPIA */ +#define word_AQ_GlobalGeneralStatus_APPIA_highTemperatureFailureState u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure lowTemperatureFailureState in AQ_GlobalGeneralStatus_APPIA */ +#define AQ_GlobalGeneralStatus_APPIA_lowTemperatureFailureState 0 +/*! \brief Preprocessor variable to relate field to bit position in structure lowTemperatureFailureState in AQ_GlobalGeneralStatus_APPIA */ +#define bits_AQ_GlobalGeneralStatus_APPIA_lowTemperatureFailureState u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure lowTemperatureFailureState in AQ_GlobalGeneralStatus_APPIA */ +#define word_AQ_GlobalGeneralStatus_APPIA_lowTemperatureFailureState u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure highTemperatureWarningState in AQ_GlobalGeneralStatus_APPIA */ +#define AQ_GlobalGeneralStatus_APPIA_highTemperatureWarningState 0 +/*! \brief Preprocessor variable to relate field to bit position in structure highTemperatureWarningState in AQ_GlobalGeneralStatus_APPIA */ +#define bits_AQ_GlobalGeneralStatus_APPIA_highTemperatureWarningState u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure highTemperatureWarningState in AQ_GlobalGeneralStatus_APPIA */ +#define word_AQ_GlobalGeneralStatus_APPIA_highTemperatureWarningState u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure lowTemperatureWarningState in AQ_GlobalGeneralStatus_APPIA */ +#define AQ_GlobalGeneralStatus_APPIA_lowTemperatureWarningState 0 +/*! \brief Preprocessor variable to relate field to bit position in structure lowTemperatureWarningState in AQ_GlobalGeneralStatus_APPIA */ +#define bits_AQ_GlobalGeneralStatus_APPIA_lowTemperatureWarningState u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure lowTemperatureWarningState in AQ_GlobalGeneralStatus_APPIA */ +#define word_AQ_GlobalGeneralStatus_APPIA_lowTemperatureWarningState u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure processorIntensiveMdioOperationIn_Progress in AQ_GlobalGeneralStatus_APPIA */ +#define AQ_GlobalGeneralStatus_APPIA_processorIntensiveMdioOperationIn_Progress 1 +/*! \brief Preprocessor variable to relate field to bit position in structure processorIntensiveMdioOperationIn_Progress in AQ_GlobalGeneralStatus_APPIA */ +#define bits_AQ_GlobalGeneralStatus_APPIA_processorIntensiveMdioOperationIn_Progress u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure processorIntensiveMdioOperationIn_Progress in AQ_GlobalGeneralStatus_APPIA */ +#define word_AQ_GlobalGeneralStatus_APPIA_processorIntensiveMdioOperationIn_Progress u1.word_1 + +/*! \brief Base register address of structure AQ_GlobalPinStatus_APPIA */ +#define AQ_GlobalPinStatus_APPIA_baseRegisterAddress 0xC840 +/*! \brief MMD address of structure AQ_GlobalPinStatus_APPIA */ +#define AQ_GlobalPinStatus_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mdioBootLoad in AQ_GlobalPinStatus_APPIA */ +#define AQ_GlobalPinStatus_APPIA_mdioBootLoad 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioBootLoad in AQ_GlobalPinStatus_APPIA */ +#define bits_AQ_GlobalPinStatus_APPIA_mdioBootLoad u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mdioBootLoad in AQ_GlobalPinStatus_APPIA */ +#define word_AQ_GlobalPinStatus_APPIA_mdioBootLoad u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure packageConnectivity in AQ_GlobalPinStatus_APPIA */ +#define AQ_GlobalPinStatus_APPIA_packageConnectivity 0 +/*! \brief Preprocessor variable to relate field to bit position in structure packageConnectivity in AQ_GlobalPinStatus_APPIA */ +#define bits_AQ_GlobalPinStatus_APPIA_packageConnectivity u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure packageConnectivity in AQ_GlobalPinStatus_APPIA */ +#define word_AQ_GlobalPinStatus_APPIA_packageConnectivity u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure txEnable in AQ_GlobalPinStatus_APPIA */ +#define AQ_GlobalPinStatus_APPIA_txEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure txEnable in AQ_GlobalPinStatus_APPIA */ +#define bits_AQ_GlobalPinStatus_APPIA_txEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure txEnable in AQ_GlobalPinStatus_APPIA */ +#define word_AQ_GlobalPinStatus_APPIA_txEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure ledPullupState in AQ_GlobalPinStatus_APPIA */ +#define AQ_GlobalPinStatus_APPIA_ledPullupState 0 +/*! \brief Preprocessor variable to relate field to bit position in structure ledPullupState in AQ_GlobalPinStatus_APPIA */ +#define bits_AQ_GlobalPinStatus_APPIA_ledPullupState u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure ledPullupState in AQ_GlobalPinStatus_APPIA */ +#define word_AQ_GlobalPinStatus_APPIA_ledPullupState u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalDaisyChainStatus_APPIA */ +#define AQ_GlobalDaisyChainStatus_APPIA_baseRegisterAddress 0xC842 +/*! \brief MMD address of structure AQ_GlobalDaisyChainStatus_APPIA */ +#define AQ_GlobalDaisyChainStatus_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure rxDaisyChainCalculatedCrc in AQ_GlobalDaisyChainStatus_APPIA */ +#define AQ_GlobalDaisyChainStatus_APPIA_rxDaisyChainCalculatedCrc 0 +/*! \brief Preprocessor variable to relate field to bit position in structure rxDaisyChainCalculatedCrc in AQ_GlobalDaisyChainStatus_APPIA */ +#define bits_AQ_GlobalDaisyChainStatus_APPIA_rxDaisyChainCalculatedCrc u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure rxDaisyChainCalculatedCrc in AQ_GlobalDaisyChainStatus_APPIA */ +#define word_AQ_GlobalDaisyChainStatus_APPIA_rxDaisyChainCalculatedCrc u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalFaultMessage_APPIA */ +#define AQ_GlobalFaultMessage_APPIA_baseRegisterAddress 0xC850 +/*! \brief MMD address of structure AQ_GlobalFaultMessage_APPIA */ +#define AQ_GlobalFaultMessage_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure message in AQ_GlobalFaultMessage_APPIA */ +#define AQ_GlobalFaultMessage_APPIA_message 0 +/*! \brief Preprocessor variable to relate field to bit position in structure message in AQ_GlobalFaultMessage_APPIA */ +#define bits_AQ_GlobalFaultMessage_APPIA_message u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure message in AQ_GlobalFaultMessage_APPIA */ +#define word_AQ_GlobalFaultMessage_APPIA_message u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalPrimaryStatus_APPIA */ +#define AQ_GlobalPrimaryStatus_APPIA_baseRegisterAddress 0xC851 +/*! \brief MMD address of structure AQ_GlobalPrimaryStatus_APPIA */ +#define AQ_GlobalPrimaryStatus_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure primaryStatus in AQ_GlobalPrimaryStatus_APPIA */ +#define AQ_GlobalPrimaryStatus_APPIA_primaryStatus 0 +/*! \brief Preprocessor variable to relate field to bit position in structure primaryStatus in AQ_GlobalPrimaryStatus_APPIA */ +#define bits_AQ_GlobalPrimaryStatus_APPIA_primaryStatus u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure primaryStatus in AQ_GlobalPrimaryStatus_APPIA */ +#define word_AQ_GlobalPrimaryStatus_APPIA_primaryStatus u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_baseRegisterAddress 0xC880 +/*! \brief MMD address of structure AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure reserved_1 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_1 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_1 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_1 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_1 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_1 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pairAReflection_1 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_pairAReflection_1 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pairAReflection_1 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_pairAReflection_1 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pairAReflection_1 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_pairAReflection_1 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_2 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_2 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_2 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_2 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_2 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_2 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pairAReflection_2 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_pairAReflection_2 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pairAReflection_2 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_pairAReflection_2 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pairAReflection_2 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_pairAReflection_2 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_3 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_3 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_3 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_3 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_3 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_3 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pairAReflection_3 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_pairAReflection_3 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pairAReflection_3 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_pairAReflection_3 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pairAReflection_3 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_pairAReflection_3 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_4 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_4 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_4 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_4 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_4 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_4 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pairAReflection_4 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_pairAReflection_4 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pairAReflection_4 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_pairAReflection_4 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pairAReflection_4 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_pairAReflection_4 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_5 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_5 1 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_5 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_5 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_5 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_5 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure pairBReflection_1 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_pairBReflection_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure pairBReflection_1 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_pairBReflection_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure pairBReflection_1 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_pairBReflection_1 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_6 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_6 1 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_6 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_6 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_6 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_6 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure pairBReflection_2 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_pairBReflection_2 1 +/*! \brief Preprocessor variable to relate field to bit position in structure pairBReflection_2 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_pairBReflection_2 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure pairBReflection_2 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_pairBReflection_2 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_7 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_7 1 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_7 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_7 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_7 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_7 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure pairBReflection_3 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_pairBReflection_3 1 +/*! \brief Preprocessor variable to relate field to bit position in structure pairBReflection_3 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_pairBReflection_3 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure pairBReflection_3 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_pairBReflection_3 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_8 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_8 1 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_8 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_8 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_8 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_8 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure pairBReflection_4 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_pairBReflection_4 1 +/*! \brief Preprocessor variable to relate field to bit position in structure pairBReflection_4 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_pairBReflection_4 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure pairBReflection_4 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_pairBReflection_4 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_9 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_9 2 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_9 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_9 u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_9 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_9 u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure pairCReflection_1 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_pairCReflection_1 2 +/*! \brief Preprocessor variable to relate field to bit position in structure pairCReflection_1 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_pairCReflection_1 u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure pairCReflection_1 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_pairCReflection_1 u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_10 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_10 2 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_10 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_10 u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_10 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_10 u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure pairCReflection_2 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_pairCReflection_2 2 +/*! \brief Preprocessor variable to relate field to bit position in structure pairCReflection_2 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_pairCReflection_2 u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure pairCReflection_2 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_pairCReflection_2 u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_11 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_11 2 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_11 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_11 u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_11 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_11 u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure pairCReflection_3 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_pairCReflection_3 2 +/*! \brief Preprocessor variable to relate field to bit position in structure pairCReflection_3 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_pairCReflection_3 u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure pairCReflection_3 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_pairCReflection_3 u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_12 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_12 2 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_12 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_12 u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_12 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_12 u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure pairCReflection_4 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_pairCReflection_4 2 +/*! \brief Preprocessor variable to relate field to bit position in structure pairCReflection_4 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_pairCReflection_4 u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure pairCReflection_4 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_pairCReflection_4 u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_13 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_13 3 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_13 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_13 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_13 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_13 u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure pairDReflection_1 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_pairDReflection_1 3 +/*! \brief Preprocessor variable to relate field to bit position in structure pairDReflection_1 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_pairDReflection_1 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure pairDReflection_1 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_pairDReflection_1 u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_14 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_14 3 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_14 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_14 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_14 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_14 u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure pairDReflection_2 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_pairDReflection_2 3 +/*! \brief Preprocessor variable to relate field to bit position in structure pairDReflection_2 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_pairDReflection_2 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure pairDReflection_2 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_pairDReflection_2 u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_15 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_15 3 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_15 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_15 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_15 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_15 u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure pairDReflection_3 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_pairDReflection_3 3 +/*! \brief Preprocessor variable to relate field to bit position in structure pairDReflection_3 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_pairDReflection_3 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure pairDReflection_3 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_pairDReflection_3 u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_16 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_16 3 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_16 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_16 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_16 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_reserved_16 u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure pairDReflection_4 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define AQ_GlobalCableDiagnosticImpedance_APPIA_pairDReflection_4 3 +/*! \brief Preprocessor variable to relate field to bit position in structure pairDReflection_4 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define bits_AQ_GlobalCableDiagnosticImpedance_APPIA_pairDReflection_4 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure pairDReflection_4 in AQ_GlobalCableDiagnosticImpedance_APPIA */ +#define word_AQ_GlobalCableDiagnosticImpedance_APPIA_pairDReflection_4 u3.word_3 + +/*! \brief Base register address of structure AQ_GlobalStatus_APPIA */ +#define AQ_GlobalStatus_APPIA_baseRegisterAddress 0xC884 +/*! \brief MMD address of structure AQ_GlobalStatus_APPIA */ +#define AQ_GlobalStatus_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure reservedStatus_0 in AQ_GlobalStatus_APPIA */ +#define AQ_GlobalStatus_APPIA_reservedStatus_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedStatus_0 in AQ_GlobalStatus_APPIA */ +#define bits_AQ_GlobalStatus_APPIA_reservedStatus_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reservedStatus_0 in AQ_GlobalStatus_APPIA */ +#define word_AQ_GlobalStatus_APPIA_reservedStatus_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure cableLength in AQ_GlobalStatus_APPIA */ +#define AQ_GlobalStatus_APPIA_cableLength 0 +/*! \brief Preprocessor variable to relate field to bit position in structure cableLength in AQ_GlobalStatus_APPIA */ +#define bits_AQ_GlobalStatus_APPIA_cableLength u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure cableLength in AQ_GlobalStatus_APPIA */ +#define word_AQ_GlobalStatus_APPIA_cableLength u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalReservedStatus_APPIA */ +#define AQ_GlobalReservedStatus_APPIA_baseRegisterAddress 0xC885 +/*! \brief MMD address of structure AQ_GlobalReservedStatus_APPIA */ +#define AQ_GlobalReservedStatus_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure nearlySecondsMSW in AQ_GlobalReservedStatus_APPIA */ +#define AQ_GlobalReservedStatus_APPIA_nearlySecondsMSW 0 +/*! \brief Preprocessor variable to relate field to bit position in structure nearlySecondsMSW in AQ_GlobalReservedStatus_APPIA */ +#define bits_AQ_GlobalReservedStatus_APPIA_nearlySecondsMSW u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure nearlySecondsMSW in AQ_GlobalReservedStatus_APPIA */ +#define word_AQ_GlobalReservedStatus_APPIA_nearlySecondsMSW u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure xenpakNvrStatus in AQ_GlobalReservedStatus_APPIA */ +#define AQ_GlobalReservedStatus_APPIA_xenpakNvrStatus 0 +/*! \brief Preprocessor variable to relate field to bit position in structure xenpakNvrStatus in AQ_GlobalReservedStatus_APPIA */ +#define bits_AQ_GlobalReservedStatus_APPIA_xenpakNvrStatus u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure xenpakNvrStatus in AQ_GlobalReservedStatus_APPIA */ +#define word_AQ_GlobalReservedStatus_APPIA_xenpakNvrStatus u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure romRevision in AQ_GlobalReservedStatus_APPIA */ +#define AQ_GlobalReservedStatus_APPIA_romRevision 0 +/*! \brief Preprocessor variable to relate field to bit position in structure romRevision in AQ_GlobalReservedStatus_APPIA */ +#define bits_AQ_GlobalReservedStatus_APPIA_romRevision u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure romRevision in AQ_GlobalReservedStatus_APPIA */ +#define word_AQ_GlobalReservedStatus_APPIA_romRevision u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure nearlySecondsLSW in AQ_GlobalReservedStatus_APPIA */ +#define AQ_GlobalReservedStatus_APPIA_nearlySecondsLSW 1 +/*! \brief Preprocessor variable to relate field to bit position in structure nearlySecondsLSW in AQ_GlobalReservedStatus_APPIA */ +#define bits_AQ_GlobalReservedStatus_APPIA_nearlySecondsLSW u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure nearlySecondsLSW in AQ_GlobalReservedStatus_APPIA */ +#define word_AQ_GlobalReservedStatus_APPIA_nearlySecondsLSW u1.word_1 + +/*! \brief Base register address of structure AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_baseRegisterAddress 0xCC00 +/*! \brief MMD address of structure AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure highTemperatureFailure in AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_highTemperatureFailure 0 +/*! \brief Preprocessor variable to relate field to bit position in structure highTemperatureFailure in AQ_GlobalAlarms_APPIA */ +#define bits_AQ_GlobalAlarms_APPIA_highTemperatureFailure u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure highTemperatureFailure in AQ_GlobalAlarms_APPIA */ +#define word_AQ_GlobalAlarms_APPIA_highTemperatureFailure u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure lowTemperatureFailure in AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_lowTemperatureFailure 0 +/*! \brief Preprocessor variable to relate field to bit position in structure lowTemperatureFailure in AQ_GlobalAlarms_APPIA */ +#define bits_AQ_GlobalAlarms_APPIA_lowTemperatureFailure u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure lowTemperatureFailure in AQ_GlobalAlarms_APPIA */ +#define word_AQ_GlobalAlarms_APPIA_lowTemperatureFailure u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure highTemperatureWarning in AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_highTemperatureWarning 0 +/*! \brief Preprocessor variable to relate field to bit position in structure highTemperatureWarning in AQ_GlobalAlarms_APPIA */ +#define bits_AQ_GlobalAlarms_APPIA_highTemperatureWarning u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure highTemperatureWarning in AQ_GlobalAlarms_APPIA */ +#define word_AQ_GlobalAlarms_APPIA_highTemperatureWarning u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure lowTemperatureWarning in AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_lowTemperatureWarning 0 +/*! \brief Preprocessor variable to relate field to bit position in structure lowTemperatureWarning in AQ_GlobalAlarms_APPIA */ +#define bits_AQ_GlobalAlarms_APPIA_lowTemperatureWarning u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure lowTemperatureWarning in AQ_GlobalAlarms_APPIA */ +#define word_AQ_GlobalAlarms_APPIA_lowTemperatureWarning u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure resetCompleted in AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_resetCompleted 0 +/*! \brief Preprocessor variable to relate field to bit position in structure resetCompleted in AQ_GlobalAlarms_APPIA */ +#define bits_AQ_GlobalAlarms_APPIA_resetCompleted u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure resetCompleted in AQ_GlobalAlarms_APPIA */ +#define word_AQ_GlobalAlarms_APPIA_resetCompleted u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure deviceFault in AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_deviceFault 0 +/*! \brief Preprocessor variable to relate field to bit position in structure deviceFault in AQ_GlobalAlarms_APPIA */ +#define bits_AQ_GlobalAlarms_APPIA_deviceFault u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure deviceFault in AQ_GlobalAlarms_APPIA */ +#define word_AQ_GlobalAlarms_APPIA_deviceFault u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reservedAlarmA in AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_reservedAlarmA 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedAlarmA in AQ_GlobalAlarms_APPIA */ +#define bits_AQ_GlobalAlarms_APPIA_reservedAlarmA u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reservedAlarmA in AQ_GlobalAlarms_APPIA */ +#define word_AQ_GlobalAlarms_APPIA_reservedAlarmA u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reservedAlarmB in AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_reservedAlarmB 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedAlarmB in AQ_GlobalAlarms_APPIA */ +#define bits_AQ_GlobalAlarms_APPIA_reservedAlarmB u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reservedAlarmB in AQ_GlobalAlarms_APPIA */ +#define word_AQ_GlobalAlarms_APPIA_reservedAlarmB u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reservedAlarmC in AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_reservedAlarmC 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedAlarmC in AQ_GlobalAlarms_APPIA */ +#define bits_AQ_GlobalAlarms_APPIA_reservedAlarmC u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reservedAlarmC in AQ_GlobalAlarms_APPIA */ +#define word_AQ_GlobalAlarms_APPIA_reservedAlarmC u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reservedAlarmD in AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_reservedAlarmD 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedAlarmD in AQ_GlobalAlarms_APPIA */ +#define bits_AQ_GlobalAlarms_APPIA_reservedAlarmD u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reservedAlarmD in AQ_GlobalAlarms_APPIA */ +#define word_AQ_GlobalAlarms_APPIA_reservedAlarmD u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure smartPower_downEntered in AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_smartPower_downEntered 1 +/*! \brief Preprocessor variable to relate field to bit position in structure smartPower_downEntered in AQ_GlobalAlarms_APPIA */ +#define bits_AQ_GlobalAlarms_APPIA_smartPower_downEntered u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure smartPower_downEntered in AQ_GlobalAlarms_APPIA */ +#define word_AQ_GlobalAlarms_APPIA_smartPower_downEntered u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure xenpakAlarm in AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_xenpakAlarm 1 +/*! \brief Preprocessor variable to relate field to bit position in structure xenpakAlarm in AQ_GlobalAlarms_APPIA */ +#define bits_AQ_GlobalAlarms_APPIA_xenpakAlarm u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure xenpakAlarm in AQ_GlobalAlarms_APPIA */ +#define word_AQ_GlobalAlarms_APPIA_xenpakAlarm u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure reservedAlarms in AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_reservedAlarms 1 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedAlarms in AQ_GlobalAlarms_APPIA */ +#define bits_AQ_GlobalAlarms_APPIA_reservedAlarms u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure reservedAlarms in AQ_GlobalAlarms_APPIA */ +#define word_AQ_GlobalAlarms_APPIA_reservedAlarms u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mdioCommandHandlingOverflow in AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_mdioCommandHandlingOverflow 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioCommandHandlingOverflow in AQ_GlobalAlarms_APPIA */ +#define bits_AQ_GlobalAlarms_APPIA_mdioCommandHandlingOverflow u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mdioCommandHandlingOverflow in AQ_GlobalAlarms_APPIA */ +#define word_AQ_GlobalAlarms_APPIA_mdioCommandHandlingOverflow u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure diagnosticAlarm in AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_diagnosticAlarm 1 +/*! \brief Preprocessor variable to relate field to bit position in structure diagnosticAlarm in AQ_GlobalAlarms_APPIA */ +#define bits_AQ_GlobalAlarms_APPIA_diagnosticAlarm u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure diagnosticAlarm in AQ_GlobalAlarms_APPIA */ +#define word_AQ_GlobalAlarms_APPIA_diagnosticAlarm u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure nvrOperationComplete in AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_nvrOperationComplete 2 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrOperationComplete in AQ_GlobalAlarms_APPIA */ +#define bits_AQ_GlobalAlarms_APPIA_nvrOperationComplete u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure nvrOperationComplete in AQ_GlobalAlarms_APPIA */ +#define word_AQ_GlobalAlarms_APPIA_nvrOperationComplete u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure mailboxOperation_Complete in AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_mailboxOperation_Complete 2 +/*! \brief Preprocessor variable to relate field to bit position in structure mailboxOperation_Complete in AQ_GlobalAlarms_APPIA */ +#define bits_AQ_GlobalAlarms_APPIA_mailboxOperation_Complete u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure mailboxOperation_Complete in AQ_GlobalAlarms_APPIA */ +#define word_AQ_GlobalAlarms_APPIA_mailboxOperation_Complete u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure upDramParityError in AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_upDramParityError 2 +/*! \brief Preprocessor variable to relate field to bit position in structure upDramParityError in AQ_GlobalAlarms_APPIA */ +#define bits_AQ_GlobalAlarms_APPIA_upDramParityError u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure upDramParityError in AQ_GlobalAlarms_APPIA */ +#define word_AQ_GlobalAlarms_APPIA_upDramParityError u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure upIramParityError in AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_upIramParityError 2 +/*! \brief Preprocessor variable to relate field to bit position in structure upIramParityError in AQ_GlobalAlarms_APPIA */ +#define bits_AQ_GlobalAlarms_APPIA_upIramParityError u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure upIramParityError in AQ_GlobalAlarms_APPIA */ +#define word_AQ_GlobalAlarms_APPIA_upIramParityError u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure txEnableStateChange in AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_txEnableStateChange 2 +/*! \brief Preprocessor variable to relate field to bit position in structure txEnableStateChange in AQ_GlobalAlarms_APPIA */ +#define bits_AQ_GlobalAlarms_APPIA_txEnableStateChange u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure txEnableStateChange in AQ_GlobalAlarms_APPIA */ +#define word_AQ_GlobalAlarms_APPIA_txEnableStateChange u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure mdioMMD_Error in AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_mdioMMD_Error 2 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioMMD_Error in AQ_GlobalAlarms_APPIA */ +#define bits_AQ_GlobalAlarms_APPIA_mdioMMD_Error u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure mdioMMD_Error in AQ_GlobalAlarms_APPIA */ +#define word_AQ_GlobalAlarms_APPIA_mdioMMD_Error u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure mdioTimeoutError in AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_mdioTimeoutError 2 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioTimeoutError in AQ_GlobalAlarms_APPIA */ +#define bits_AQ_GlobalAlarms_APPIA_mdioTimeoutError u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure mdioTimeoutError in AQ_GlobalAlarms_APPIA */ +#define word_AQ_GlobalAlarms_APPIA_mdioTimeoutError u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure watchdogTimerAlarm in AQ_GlobalAlarms_APPIA */ +#define AQ_GlobalAlarms_APPIA_watchdogTimerAlarm 2 +/*! \brief Preprocessor variable to relate field to bit position in structure watchdogTimerAlarm in AQ_GlobalAlarms_APPIA */ +#define bits_AQ_GlobalAlarms_APPIA_watchdogTimerAlarm u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure watchdogTimerAlarm in AQ_GlobalAlarms_APPIA */ +#define word_AQ_GlobalAlarms_APPIA_watchdogTimerAlarm u2.word_2 + +/*! \brief Base register address of structure AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_baseRegisterAddress 0xD400 +/*! \brief MMD address of structure AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure highTemperatureFailureMask in AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_highTemperatureFailureMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure highTemperatureFailureMask in AQ_GlobalInterruptMask_APPIA */ +#define bits_AQ_GlobalInterruptMask_APPIA_highTemperatureFailureMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure highTemperatureFailureMask in AQ_GlobalInterruptMask_APPIA */ +#define word_AQ_GlobalInterruptMask_APPIA_highTemperatureFailureMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure lowTemperatureFailureMask in AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_lowTemperatureFailureMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure lowTemperatureFailureMask in AQ_GlobalInterruptMask_APPIA */ +#define bits_AQ_GlobalInterruptMask_APPIA_lowTemperatureFailureMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure lowTemperatureFailureMask in AQ_GlobalInterruptMask_APPIA */ +#define word_AQ_GlobalInterruptMask_APPIA_lowTemperatureFailureMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure highTemperatureWarningMask in AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_highTemperatureWarningMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure highTemperatureWarningMask in AQ_GlobalInterruptMask_APPIA */ +#define bits_AQ_GlobalInterruptMask_APPIA_highTemperatureWarningMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure highTemperatureWarningMask in AQ_GlobalInterruptMask_APPIA */ +#define word_AQ_GlobalInterruptMask_APPIA_highTemperatureWarningMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure lowTemperatureWarningMask in AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_lowTemperatureWarningMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure lowTemperatureWarningMask in AQ_GlobalInterruptMask_APPIA */ +#define bits_AQ_GlobalInterruptMask_APPIA_lowTemperatureWarningMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure lowTemperatureWarningMask in AQ_GlobalInterruptMask_APPIA */ +#define word_AQ_GlobalInterruptMask_APPIA_lowTemperatureWarningMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure resetCompletedMask in AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_resetCompletedMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure resetCompletedMask in AQ_GlobalInterruptMask_APPIA */ +#define bits_AQ_GlobalInterruptMask_APPIA_resetCompletedMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure resetCompletedMask in AQ_GlobalInterruptMask_APPIA */ +#define word_AQ_GlobalInterruptMask_APPIA_resetCompletedMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure deviceFaultMask in AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_deviceFaultMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure deviceFaultMask in AQ_GlobalInterruptMask_APPIA */ +#define bits_AQ_GlobalInterruptMask_APPIA_deviceFaultMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure deviceFaultMask in AQ_GlobalInterruptMask_APPIA */ +#define word_AQ_GlobalInterruptMask_APPIA_deviceFaultMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reservedAlarmAMask in AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_reservedAlarmAMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedAlarmAMask in AQ_GlobalInterruptMask_APPIA */ +#define bits_AQ_GlobalInterruptMask_APPIA_reservedAlarmAMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reservedAlarmAMask in AQ_GlobalInterruptMask_APPIA */ +#define word_AQ_GlobalInterruptMask_APPIA_reservedAlarmAMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reservedAlarmBMask in AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_reservedAlarmBMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedAlarmBMask in AQ_GlobalInterruptMask_APPIA */ +#define bits_AQ_GlobalInterruptMask_APPIA_reservedAlarmBMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reservedAlarmBMask in AQ_GlobalInterruptMask_APPIA */ +#define word_AQ_GlobalInterruptMask_APPIA_reservedAlarmBMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reservedAlarmCMask in AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_reservedAlarmCMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedAlarmCMask in AQ_GlobalInterruptMask_APPIA */ +#define bits_AQ_GlobalInterruptMask_APPIA_reservedAlarmCMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reservedAlarmCMask in AQ_GlobalInterruptMask_APPIA */ +#define word_AQ_GlobalInterruptMask_APPIA_reservedAlarmCMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reservedAlarmDMask in AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_reservedAlarmDMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedAlarmDMask in AQ_GlobalInterruptMask_APPIA */ +#define bits_AQ_GlobalInterruptMask_APPIA_reservedAlarmDMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reservedAlarmDMask in AQ_GlobalInterruptMask_APPIA */ +#define word_AQ_GlobalInterruptMask_APPIA_reservedAlarmDMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure smartPower_downEnteredMask in AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_smartPower_downEnteredMask 1 +/*! \brief Preprocessor variable to relate field to bit position in structure smartPower_downEnteredMask in AQ_GlobalInterruptMask_APPIA */ +#define bits_AQ_GlobalInterruptMask_APPIA_smartPower_downEnteredMask u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure smartPower_downEnteredMask in AQ_GlobalInterruptMask_APPIA */ +#define word_AQ_GlobalInterruptMask_APPIA_smartPower_downEnteredMask u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure xenpakAlarmMask in AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_xenpakAlarmMask 1 +/*! \brief Preprocessor variable to relate field to bit position in structure xenpakAlarmMask in AQ_GlobalInterruptMask_APPIA */ +#define bits_AQ_GlobalInterruptMask_APPIA_xenpakAlarmMask u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure xenpakAlarmMask in AQ_GlobalInterruptMask_APPIA */ +#define word_AQ_GlobalInterruptMask_APPIA_xenpakAlarmMask u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure reservedAlarmsMask in AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_reservedAlarmsMask 1 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedAlarmsMask in AQ_GlobalInterruptMask_APPIA */ +#define bits_AQ_GlobalInterruptMask_APPIA_reservedAlarmsMask u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure reservedAlarmsMask in AQ_GlobalInterruptMask_APPIA */ +#define word_AQ_GlobalInterruptMask_APPIA_reservedAlarmsMask u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mdioCommandHandlingOverflowMask in AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_mdioCommandHandlingOverflowMask 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioCommandHandlingOverflowMask in AQ_GlobalInterruptMask_APPIA */ +#define bits_AQ_GlobalInterruptMask_APPIA_mdioCommandHandlingOverflowMask u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mdioCommandHandlingOverflowMask in AQ_GlobalInterruptMask_APPIA */ +#define word_AQ_GlobalInterruptMask_APPIA_mdioCommandHandlingOverflowMask u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure diagnosticAlarmMask in AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_diagnosticAlarmMask 1 +/*! \brief Preprocessor variable to relate field to bit position in structure diagnosticAlarmMask in AQ_GlobalInterruptMask_APPIA */ +#define bits_AQ_GlobalInterruptMask_APPIA_diagnosticAlarmMask u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure diagnosticAlarmMask in AQ_GlobalInterruptMask_APPIA */ +#define word_AQ_GlobalInterruptMask_APPIA_diagnosticAlarmMask u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure nvrOperationCompleteMask in AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_nvrOperationCompleteMask 2 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrOperationCompleteMask in AQ_GlobalInterruptMask_APPIA */ +#define bits_AQ_GlobalInterruptMask_APPIA_nvrOperationCompleteMask u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure nvrOperationCompleteMask in AQ_GlobalInterruptMask_APPIA */ +#define word_AQ_GlobalInterruptMask_APPIA_nvrOperationCompleteMask u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure mailboxOperationCompleteMask in AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_mailboxOperationCompleteMask 2 +/*! \brief Preprocessor variable to relate field to bit position in structure mailboxOperationCompleteMask in AQ_GlobalInterruptMask_APPIA */ +#define bits_AQ_GlobalInterruptMask_APPIA_mailboxOperationCompleteMask u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure mailboxOperationCompleteMask in AQ_GlobalInterruptMask_APPIA */ +#define word_AQ_GlobalInterruptMask_APPIA_mailboxOperationCompleteMask u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure upDramParityErrorMask in AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_upDramParityErrorMask 2 +/*! \brief Preprocessor variable to relate field to bit position in structure upDramParityErrorMask in AQ_GlobalInterruptMask_APPIA */ +#define bits_AQ_GlobalInterruptMask_APPIA_upDramParityErrorMask u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure upDramParityErrorMask in AQ_GlobalInterruptMask_APPIA */ +#define word_AQ_GlobalInterruptMask_APPIA_upDramParityErrorMask u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure upIramParityErrorMask in AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_upIramParityErrorMask 2 +/*! \brief Preprocessor variable to relate field to bit position in structure upIramParityErrorMask in AQ_GlobalInterruptMask_APPIA */ +#define bits_AQ_GlobalInterruptMask_APPIA_upIramParityErrorMask u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure upIramParityErrorMask in AQ_GlobalInterruptMask_APPIA */ +#define word_AQ_GlobalInterruptMask_APPIA_upIramParityErrorMask u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure txEnableStateChangeMask in AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_txEnableStateChangeMask 2 +/*! \brief Preprocessor variable to relate field to bit position in structure txEnableStateChangeMask in AQ_GlobalInterruptMask_APPIA */ +#define bits_AQ_GlobalInterruptMask_APPIA_txEnableStateChangeMask u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure txEnableStateChangeMask in AQ_GlobalInterruptMask_APPIA */ +#define word_AQ_GlobalInterruptMask_APPIA_txEnableStateChangeMask u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure mdioMMD_ErrorMask in AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_mdioMMD_ErrorMask 2 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioMMD_ErrorMask in AQ_GlobalInterruptMask_APPIA */ +#define bits_AQ_GlobalInterruptMask_APPIA_mdioMMD_ErrorMask u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure mdioMMD_ErrorMask in AQ_GlobalInterruptMask_APPIA */ +#define word_AQ_GlobalInterruptMask_APPIA_mdioMMD_ErrorMask u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure mdioTimeoutErrorMask in AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_mdioTimeoutErrorMask 2 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioTimeoutErrorMask in AQ_GlobalInterruptMask_APPIA */ +#define bits_AQ_GlobalInterruptMask_APPIA_mdioTimeoutErrorMask u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure mdioTimeoutErrorMask in AQ_GlobalInterruptMask_APPIA */ +#define word_AQ_GlobalInterruptMask_APPIA_mdioTimeoutErrorMask u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure watchdogTimerAlarmMask in AQ_GlobalInterruptMask_APPIA */ +#define AQ_GlobalInterruptMask_APPIA_watchdogTimerAlarmMask 2 +/*! \brief Preprocessor variable to relate field to bit position in structure watchdogTimerAlarmMask in AQ_GlobalInterruptMask_APPIA */ +#define bits_AQ_GlobalInterruptMask_APPIA_watchdogTimerAlarmMask u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure watchdogTimerAlarmMask in AQ_GlobalInterruptMask_APPIA */ +#define word_AQ_GlobalInterruptMask_APPIA_watchdogTimerAlarmMask u2.word_2 + +/*! \brief Base register address of structure AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define AQ_GlobalChip_wideStandardInterruptFlags_APPIA_baseRegisterAddress 0xFC00 +/*! \brief MMD address of structure AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define AQ_GlobalChip_wideStandardInterruptFlags_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure pmaStandardAlarm_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define AQ_GlobalChip_wideStandardInterruptFlags_APPIA_pmaStandardAlarm_1Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pmaStandardAlarm_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define bits_AQ_GlobalChip_wideStandardInterruptFlags_APPIA_pmaStandardAlarm_1Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pmaStandardAlarm_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define word_AQ_GlobalChip_wideStandardInterruptFlags_APPIA_pmaStandardAlarm_1Interrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pmaStandardAlarm_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define AQ_GlobalChip_wideStandardInterruptFlags_APPIA_pmaStandardAlarm_2Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pmaStandardAlarm_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define bits_AQ_GlobalChip_wideStandardInterruptFlags_APPIA_pmaStandardAlarm_2Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pmaStandardAlarm_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define word_AQ_GlobalChip_wideStandardInterruptFlags_APPIA_pmaStandardAlarm_2Interrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pcsStandardAlarm_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define AQ_GlobalChip_wideStandardInterruptFlags_APPIA_pcsStandardAlarm_1Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pcsStandardAlarm_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define bits_AQ_GlobalChip_wideStandardInterruptFlags_APPIA_pcsStandardAlarm_1Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pcsStandardAlarm_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define word_AQ_GlobalChip_wideStandardInterruptFlags_APPIA_pcsStandardAlarm_1Interrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pcsStandardAlarm_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define AQ_GlobalChip_wideStandardInterruptFlags_APPIA_pcsStandardAlarm_2Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pcsStandardAlarm_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define bits_AQ_GlobalChip_wideStandardInterruptFlags_APPIA_pcsStandardAlarm_2Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pcsStandardAlarm_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define word_AQ_GlobalChip_wideStandardInterruptFlags_APPIA_pcsStandardAlarm_2Interrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pcsStandardAlarm_3Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define AQ_GlobalChip_wideStandardInterruptFlags_APPIA_pcsStandardAlarm_3Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pcsStandardAlarm_3Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define bits_AQ_GlobalChip_wideStandardInterruptFlags_APPIA_pcsStandardAlarm_3Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pcsStandardAlarm_3Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define word_AQ_GlobalChip_wideStandardInterruptFlags_APPIA_pcsStandardAlarm_3Interrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure phyXS_StandardAlarms_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define AQ_GlobalChip_wideStandardInterruptFlags_APPIA_phyXS_StandardAlarms_1Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure phyXS_StandardAlarms_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define bits_AQ_GlobalChip_wideStandardInterruptFlags_APPIA_phyXS_StandardAlarms_1Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure phyXS_StandardAlarms_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define word_AQ_GlobalChip_wideStandardInterruptFlags_APPIA_phyXS_StandardAlarms_1Interrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure phyXS_StandardAlarms_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define AQ_GlobalChip_wideStandardInterruptFlags_APPIA_phyXS_StandardAlarms_2Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure phyXS_StandardAlarms_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define bits_AQ_GlobalChip_wideStandardInterruptFlags_APPIA_phyXS_StandardAlarms_2Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure phyXS_StandardAlarms_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define word_AQ_GlobalChip_wideStandardInterruptFlags_APPIA_phyXS_StandardAlarms_2Interrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure autonegotiationStandardAlarms_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define AQ_GlobalChip_wideStandardInterruptFlags_APPIA_autonegotiationStandardAlarms_1Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure autonegotiationStandardAlarms_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define bits_AQ_GlobalChip_wideStandardInterruptFlags_APPIA_autonegotiationStandardAlarms_1Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure autonegotiationStandardAlarms_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define word_AQ_GlobalChip_wideStandardInterruptFlags_APPIA_autonegotiationStandardAlarms_1Interrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure autonegotiationStandardAlarms_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define AQ_GlobalChip_wideStandardInterruptFlags_APPIA_autonegotiationStandardAlarms_2Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure autonegotiationStandardAlarms_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define bits_AQ_GlobalChip_wideStandardInterruptFlags_APPIA_autonegotiationStandardAlarms_2Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure autonegotiationStandardAlarms_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define word_AQ_GlobalChip_wideStandardInterruptFlags_APPIA_autonegotiationStandardAlarms_2Interrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure gbeStandardAlarmsInterrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define AQ_GlobalChip_wideStandardInterruptFlags_APPIA_gbeStandardAlarmsInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure gbeStandardAlarmsInterrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define bits_AQ_GlobalChip_wideStandardInterruptFlags_APPIA_gbeStandardAlarmsInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure gbeStandardAlarmsInterrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define word_AQ_GlobalChip_wideStandardInterruptFlags_APPIA_gbeStandardAlarmsInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure allVendorAlarmsInterrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define AQ_GlobalChip_wideStandardInterruptFlags_APPIA_allVendorAlarmsInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure allVendorAlarmsInterrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define bits_AQ_GlobalChip_wideStandardInterruptFlags_APPIA_allVendorAlarmsInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure allVendorAlarmsInterrupt in AQ_GlobalChip_wideStandardInterruptFlags_APPIA */ +#define word_AQ_GlobalChip_wideStandardInterruptFlags_APPIA_allVendorAlarmsInterrupt u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define AQ_GlobalChip_wideVendorInterruptFlags_APPIA_baseRegisterAddress 0xFC01 +/*! \brief MMD address of structure AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define AQ_GlobalChip_wideVendorInterruptFlags_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure pmaVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define AQ_GlobalChip_wideVendorInterruptFlags_APPIA_pmaVendorAlarmInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pmaVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define bits_AQ_GlobalChip_wideVendorInterruptFlags_APPIA_pmaVendorAlarmInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pmaVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define word_AQ_GlobalChip_wideVendorInterruptFlags_APPIA_pmaVendorAlarmInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pcsVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define AQ_GlobalChip_wideVendorInterruptFlags_APPIA_pcsVendorAlarmInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pcsVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define bits_AQ_GlobalChip_wideVendorInterruptFlags_APPIA_pcsVendorAlarmInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pcsVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define word_AQ_GlobalChip_wideVendorInterruptFlags_APPIA_pcsVendorAlarmInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure phyXS_VendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define AQ_GlobalChip_wideVendorInterruptFlags_APPIA_phyXS_VendorAlarmInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure phyXS_VendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define bits_AQ_GlobalChip_wideVendorInterruptFlags_APPIA_phyXS_VendorAlarmInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure phyXS_VendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define word_AQ_GlobalChip_wideVendorInterruptFlags_APPIA_phyXS_VendorAlarmInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure autonegotiationVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define AQ_GlobalChip_wideVendorInterruptFlags_APPIA_autonegotiationVendorAlarmInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure autonegotiationVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define bits_AQ_GlobalChip_wideVendorInterruptFlags_APPIA_autonegotiationVendorAlarmInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure autonegotiationVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define word_AQ_GlobalChip_wideVendorInterruptFlags_APPIA_autonegotiationVendorAlarmInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure gbeVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define AQ_GlobalChip_wideVendorInterruptFlags_APPIA_gbeVendorAlarmInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure gbeVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define bits_AQ_GlobalChip_wideVendorInterruptFlags_APPIA_gbeVendorAlarmInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure gbeVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define word_AQ_GlobalChip_wideVendorInterruptFlags_APPIA_gbeVendorAlarmInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure globalAlarms_1Interrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define AQ_GlobalChip_wideVendorInterruptFlags_APPIA_globalAlarms_1Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure globalAlarms_1Interrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define bits_AQ_GlobalChip_wideVendorInterruptFlags_APPIA_globalAlarms_1Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure globalAlarms_1Interrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define word_AQ_GlobalChip_wideVendorInterruptFlags_APPIA_globalAlarms_1Interrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure globalAlarms_2Interrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define AQ_GlobalChip_wideVendorInterruptFlags_APPIA_globalAlarms_2Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure globalAlarms_2Interrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define bits_AQ_GlobalChip_wideVendorInterruptFlags_APPIA_globalAlarms_2Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure globalAlarms_2Interrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define word_AQ_GlobalChip_wideVendorInterruptFlags_APPIA_globalAlarms_2Interrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure globalAlarms_3Interrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define AQ_GlobalChip_wideVendorInterruptFlags_APPIA_globalAlarms_3Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure globalAlarms_3Interrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define bits_AQ_GlobalChip_wideVendorInterruptFlags_APPIA_globalAlarms_3Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure globalAlarms_3Interrupt in AQ_GlobalChip_wideVendorInterruptFlags_APPIA */ +#define word_AQ_GlobalChip_wideVendorInterruptFlags_APPIA_globalAlarms_3Interrupt u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define AQ_GlobalInterruptChip_wideStandardMask_APPIA_baseRegisterAddress 0xFF00 +/*! \brief MMD address of structure AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define AQ_GlobalInterruptChip_wideStandardMask_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure pmaStandardAlarm_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define AQ_GlobalInterruptChip_wideStandardMask_APPIA_pmaStandardAlarm_1InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pmaStandardAlarm_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define bits_AQ_GlobalInterruptChip_wideStandardMask_APPIA_pmaStandardAlarm_1InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pmaStandardAlarm_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define word_AQ_GlobalInterruptChip_wideStandardMask_APPIA_pmaStandardAlarm_1InterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pmaStandardAlarm_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define AQ_GlobalInterruptChip_wideStandardMask_APPIA_pmaStandardAlarm_2InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pmaStandardAlarm_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define bits_AQ_GlobalInterruptChip_wideStandardMask_APPIA_pmaStandardAlarm_2InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pmaStandardAlarm_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define word_AQ_GlobalInterruptChip_wideStandardMask_APPIA_pmaStandardAlarm_2InterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pcsStandardAlarm_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define AQ_GlobalInterruptChip_wideStandardMask_APPIA_pcsStandardAlarm_1InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pcsStandardAlarm_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define bits_AQ_GlobalInterruptChip_wideStandardMask_APPIA_pcsStandardAlarm_1InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pcsStandardAlarm_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define word_AQ_GlobalInterruptChip_wideStandardMask_APPIA_pcsStandardAlarm_1InterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pcsStandardAlarm_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define AQ_GlobalInterruptChip_wideStandardMask_APPIA_pcsStandardAlarm_2InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pcsStandardAlarm_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define bits_AQ_GlobalInterruptChip_wideStandardMask_APPIA_pcsStandardAlarm_2InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pcsStandardAlarm_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define word_AQ_GlobalInterruptChip_wideStandardMask_APPIA_pcsStandardAlarm_2InterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pcsStandardAlarm_3InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define AQ_GlobalInterruptChip_wideStandardMask_APPIA_pcsStandardAlarm_3InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pcsStandardAlarm_3InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define bits_AQ_GlobalInterruptChip_wideStandardMask_APPIA_pcsStandardAlarm_3InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pcsStandardAlarm_3InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define word_AQ_GlobalInterruptChip_wideStandardMask_APPIA_pcsStandardAlarm_3InterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure phyXS_StandardAlarms_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define AQ_GlobalInterruptChip_wideStandardMask_APPIA_phyXS_StandardAlarms_1InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure phyXS_StandardAlarms_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define bits_AQ_GlobalInterruptChip_wideStandardMask_APPIA_phyXS_StandardAlarms_1InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure phyXS_StandardAlarms_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define word_AQ_GlobalInterruptChip_wideStandardMask_APPIA_phyXS_StandardAlarms_1InterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure phyXS_StandardAlarms_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define AQ_GlobalInterruptChip_wideStandardMask_APPIA_phyXS_StandardAlarms_2InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure phyXS_StandardAlarms_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define bits_AQ_GlobalInterruptChip_wideStandardMask_APPIA_phyXS_StandardAlarms_2InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure phyXS_StandardAlarms_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define word_AQ_GlobalInterruptChip_wideStandardMask_APPIA_phyXS_StandardAlarms_2InterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure autonegotiationStandardAlarms_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define AQ_GlobalInterruptChip_wideStandardMask_APPIA_autonegotiationStandardAlarms_1InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure autonegotiationStandardAlarms_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define bits_AQ_GlobalInterruptChip_wideStandardMask_APPIA_autonegotiationStandardAlarms_1InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure autonegotiationStandardAlarms_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define word_AQ_GlobalInterruptChip_wideStandardMask_APPIA_autonegotiationStandardAlarms_1InterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure autonegotiationStandardAlarms_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define AQ_GlobalInterruptChip_wideStandardMask_APPIA_autonegotiationStandardAlarms_2InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure autonegotiationStandardAlarms_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define bits_AQ_GlobalInterruptChip_wideStandardMask_APPIA_autonegotiationStandardAlarms_2InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure autonegotiationStandardAlarms_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define word_AQ_GlobalInterruptChip_wideStandardMask_APPIA_autonegotiationStandardAlarms_2InterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure gbeStandardAlarmsInterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define AQ_GlobalInterruptChip_wideStandardMask_APPIA_gbeStandardAlarmsInterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure gbeStandardAlarmsInterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define bits_AQ_GlobalInterruptChip_wideStandardMask_APPIA_gbeStandardAlarmsInterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure gbeStandardAlarmsInterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define word_AQ_GlobalInterruptChip_wideStandardMask_APPIA_gbeStandardAlarmsInterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure allVendorAlarmsInterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define AQ_GlobalInterruptChip_wideStandardMask_APPIA_allVendorAlarmsInterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure allVendorAlarmsInterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define bits_AQ_GlobalInterruptChip_wideStandardMask_APPIA_allVendorAlarmsInterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure allVendorAlarmsInterruptMask in AQ_GlobalInterruptChip_wideStandardMask_APPIA */ +#define word_AQ_GlobalInterruptChip_wideStandardMask_APPIA_allVendorAlarmsInterruptMask u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define AQ_GlobalInterruptChip_wideVendorMask_APPIA_baseRegisterAddress 0xFF01 +/*! \brief MMD address of structure AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define AQ_GlobalInterruptChip_wideVendorMask_APPIA_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure pmaVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define AQ_GlobalInterruptChip_wideVendorMask_APPIA_pmaVendorAlarmInterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pmaVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define bits_AQ_GlobalInterruptChip_wideVendorMask_APPIA_pmaVendorAlarmInterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pmaVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define word_AQ_GlobalInterruptChip_wideVendorMask_APPIA_pmaVendorAlarmInterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pcsVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define AQ_GlobalInterruptChip_wideVendorMask_APPIA_pcsVendorAlarmInterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pcsVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define bits_AQ_GlobalInterruptChip_wideVendorMask_APPIA_pcsVendorAlarmInterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pcsVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define word_AQ_GlobalInterruptChip_wideVendorMask_APPIA_pcsVendorAlarmInterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure phyXS_VendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define AQ_GlobalInterruptChip_wideVendorMask_APPIA_phyXS_VendorAlarmInterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure phyXS_VendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define bits_AQ_GlobalInterruptChip_wideVendorMask_APPIA_phyXS_VendorAlarmInterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure phyXS_VendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define word_AQ_GlobalInterruptChip_wideVendorMask_APPIA_phyXS_VendorAlarmInterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure autonegotiationVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define AQ_GlobalInterruptChip_wideVendorMask_APPIA_autonegotiationVendorAlarmInterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure autonegotiationVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define bits_AQ_GlobalInterruptChip_wideVendorMask_APPIA_autonegotiationVendorAlarmInterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure autonegotiationVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define word_AQ_GlobalInterruptChip_wideVendorMask_APPIA_autonegotiationVendorAlarmInterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure gbeVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define AQ_GlobalInterruptChip_wideVendorMask_APPIA_gbeVendorAlarmInterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure gbeVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define bits_AQ_GlobalInterruptChip_wideVendorMask_APPIA_gbeVendorAlarmInterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure gbeVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define word_AQ_GlobalInterruptChip_wideVendorMask_APPIA_gbeVendorAlarmInterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure globalAlarms_1InterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define AQ_GlobalInterruptChip_wideVendorMask_APPIA_globalAlarms_1InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure globalAlarms_1InterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define bits_AQ_GlobalInterruptChip_wideVendorMask_APPIA_globalAlarms_1InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure globalAlarms_1InterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define word_AQ_GlobalInterruptChip_wideVendorMask_APPIA_globalAlarms_1InterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure globalAlarms_2InterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define AQ_GlobalInterruptChip_wideVendorMask_APPIA_globalAlarms_2InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure globalAlarms_2InterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define bits_AQ_GlobalInterruptChip_wideVendorMask_APPIA_globalAlarms_2InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure globalAlarms_2InterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define word_AQ_GlobalInterruptChip_wideVendorMask_APPIA_globalAlarms_2InterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure globalAlarms_3InterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define AQ_GlobalInterruptChip_wideVendorMask_APPIA_globalAlarms_3InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure globalAlarms_3InterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define bits_AQ_GlobalInterruptChip_wideVendorMask_APPIA_globalAlarms_3InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure globalAlarms_3InterruptMask in AQ_GlobalInterruptChip_wideVendorMask_APPIA */ +#define word_AQ_GlobalInterruptChip_wideVendorMask_APPIA_globalAlarms_3InterruptMask u0.word_0 +#endif +/*@}*/ +/*@}*/ diff --git a/feeds/ipq807x/aq-fw-download/src/include/registerMap/APPIA/AQ_APPIA_Global_registers_reversed.h b/feeds/ipq807x/aq-fw-download/src/include/registerMap/APPIA/AQ_APPIA_Global_registers_reversed.h new file mode 100755 index 000000000..89e02c325 --- /dev/null +++ b/feeds/ipq807x/aq-fw-download/src/include/registerMap/APPIA/AQ_APPIA_Global_registers_reversed.h @@ -0,0 +1,5581 @@ +/*! \file +* This file contains the data structures and doxygen comments +* for the Global Registers block. + */ + +/*! \addtogroup registerMap + @{ +*/ + +/*! \defgroup Global_registers Global Registers +* This module contains the data structures and doxygen comments +* for the Global Registers block. + */ +/*********************************************************************** +* Copyright (c) 2015, Aquantia +* +* Permission to use, copy, modify, and/or distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +* +* $Date: 2014/04/08 $ +* +* $Label: $ +* +* Description: +* +* This file contains the c header structures for the registers contained in the Global Registers block. +* +* The bit fields in this structure are from MSbit to LSbit +* +***********************************************************************/ + + +/*@{*/ +#ifndef AQ_APPIA_GLOBAL_REGS_HEADER +#define AQ_APPIA_GLOBAL_REGS_HEADER + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Control 1: 1E.0000 */ +/* Global Standard Control 1: 1E.0000 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Control 1 */ + union + { + struct + { + /*! \brief 1E.0000.F R/WSC Soft Reset + AQ_GlobalStandardControl_1_APPIA.u0.bits_0.softReset + + Default = 0x1 + + 1 = Global soft reset + 0 = Normal operation + + + Notes: + Setting this bit initiates a global soft reset on all of the digital logic, including the microprocessor. Upon completion of the reset sequence, this bit is set back to 0. */ + unsigned int softReset : 1; /* 1E.0000.F R/WSC Default = 0x1 */ + /* 1 = Global soft reset + 0 = Normal operation + */ + /*! \brief 1E.0000.E R/WSC Hard Reset + AQ_GlobalStandardControl_1_APPIA.u0.bits_0.hardReset + + Default = 0x0 + + 1 = Global hard reset + 0 = Normal operation + + + Notes: + Setting this bit initiates a global hard reset, equivalent to pulling the reset pin low. This is a level sensitive pin that connects into the power-on reset generation circuitry to initiate a complete power-on reset. */ + unsigned int hardReset : 1; /* 1E.0000.E R/WSC Default = 0x0 */ + /* 1 = Global hard reset + 0 = Normal operation + */ + unsigned int reserved0 : 2; + /*! \brief 1E.0000.B R/WPD Low Power + AQ_GlobalStandardControl_1_APPIA.u0.bits_0.lowPower + + Provisionable Default = 0x0 + + 1 = Low-power mode + 0 = Normal operation + + + Notes: + A one written to this register causes the chip to enter low-power mode. This bit puts the entire chip in low-power mode, with only the MDIO and microprocessor functioning, and turns off the analog front-end: i.e. places it in high-impedance mode. Setting this bit also sets all of the Low Power bits in the other MMDs. */ + unsigned int lowPower : 1; /* 1E.0000.B R/WPD Provisionable Default = 0x0 */ + /* 1 = Low-power mode + 0 = Normal operation + */ + unsigned int reserved1 : 11; + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalStandardControl_1_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Device Identifier: 1E.0002 */ +/* Global Standard Device Identifier: 1E.0002 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Device Identifier */ + union + { + struct + { + /*! \brief 1E.0002.F:0 RO Device ID MSW [1F:10] + AQ_GlobalStandardDeviceIdentifier_APPIA.u0.bits_0.deviceIdMSW + + + + Bits 31 - 16 of Device ID + */ + unsigned int deviceIdMSW : 16; /* 1E.0002.F:0 RO */ + /* Bits 31 - 16 of Device ID */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Standard Device Identifier */ + union + { + struct + { + /*! \brief 1E.0003.F:0 RO Device ID LSW [F:0] + AQ_GlobalStandardDeviceIdentifier_APPIA.u1.bits_1.deviceIdLSW + + + + Bits 15 - 0 of Device ID + */ + unsigned int deviceIdLSW : 16; /* 1E.0003.F:0 RO */ + /* Bits 15 - 0 of Device ID */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalStandardDeviceIdentifier_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Devices in Package: 1E.0005 */ +/* Global Standard Devices in Package: 1E.0005 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Devices in Package */ + union + { + struct + { + unsigned int reserved0 : 8; + /*! \brief 1E.0005.7 ROS Autonegotiation Present + AQ_GlobalStandardDevicesInPackage_APPIA.u0.bits_0.autonegotiationPresent + + Default = 0x1 + + 1 = Autonegotiation is present in package + 0 = Autonegotiation is not present in package + + Notes: + This is always set to 1, as there is Autonegotiation in the PHY. */ + unsigned int autonegotiationPresent : 1; /* 1E.0005.7 ROS Default = 0x1 */ + /* 1 = Autonegotiation is present in package + 0 = Autonegotiation is not present in package */ + /*! \brief 1E.0005.6 ROS TC Present + AQ_GlobalStandardDevicesInPackage_APPIA.u0.bits_0.tcPresent + + Default = 0x0 + + 1 = TC is present in package + 0 = TC is not present in package + + Notes: + This is always set to 0, as there is no TC functionality in the PHY. */ + unsigned int tcPresent : 1; /* 1E.0005.6 ROS Default = 0x0 */ + /* 1 = TC is present in package + 0 = TC is not present in package */ + /*! \brief 1E.0005.5 ROS DTE XS Present + AQ_GlobalStandardDevicesInPackage_APPIA.u0.bits_0.dteXsPresent + + Default = 0x0 + + 1 = DTE XS is present in package + 0 = DTE XS is not present in package + + + Notes: + This is always set to 0, as there is no DTE XAUI interface in the PHY. */ + unsigned int dteXsPresent : 1; /* 1E.0005.5 ROS Default = 0x0 */ + /* 1 = DTE XS is present in package + 0 = DTE XS is not present in package + */ + /*! \brief 1E.0005.4 ROS PHY XS Present + AQ_GlobalStandardDevicesInPackage_APPIA.u0.bits_0.phyXS_Present + + Default = 0x1 + + 1 = PHY XS is present in package + 0 = PHY XS is not present in package + + Notes: + This is always set to 1 as there is a PHY XS interface in the PHY. */ + unsigned int phyXS_Present : 1; /* 1E.0005.4 ROS Default = 0x1 */ + /* 1 = PHY XS is present in package + 0 = PHY XS is not present in package */ + /*! \brief 1E.0005.3 ROS PCS Present + AQ_GlobalStandardDevicesInPackage_APPIA.u0.bits_0.pcsPresent + + Default = 0x1 + + 1 = PCS is present in package + 0 = PCS is not present in package + + Notes: + This is always set to 1 as there is PCS functionality in the PHY. */ + unsigned int pcsPresent : 1; /* 1E.0005.3 ROS Default = 0x1 */ + /* 1 = PCS is present in package + 0 = PCS is not present in package */ + /*! \brief 1E.0005.2 ROS WIS Present + AQ_GlobalStandardDevicesInPackage_APPIA.u0.bits_0.wisPresent + + Default = 0x0 + + 1 = WIS is present in package + 0 = WIS is not present in package + + Notes: + This is always set to 0, as there is no WIS functionality in the PHY. */ + unsigned int wisPresent : 1; /* 1E.0005.2 ROS Default = 0x0 */ + /* 1 = WIS is present in package + 0 = WIS is not present in package */ + /*! \brief 1E.0005.1 ROS PMA Present + AQ_GlobalStandardDevicesInPackage_APPIA.u0.bits_0.pmaPresent + + Default = 0x1 + + 1 = PMA is present in package + 0 = PMA is not present + + Notes: + This is always set to 1 as there is PMA functionality in the PHY. */ + unsigned int pmaPresent : 1; /* 1E.0005.1 ROS Default = 0x1 */ + /* 1 = PMA is present in package + 0 = PMA is not present */ + /*! \brief 1E.0005.0 ROS Clause 22 Registers Present + AQ_GlobalStandardDevicesInPackage_APPIA.u0.bits_0.clause_22RegistersPresent + + Default = 0x0 + + 1 = Clause 22 registers are present in package + 0 = Clause 22 registers are not present in package + + Notes: + This is always set to 0 in the PHY, as there are no Clause 22 registers in the device. */ + unsigned int clause_22RegistersPresent : 1; /* 1E.0005.0 ROS Default = 0x0 */ + /* 1 = Clause 22 registers are present in package + 0 = Clause 22 registers are not present in package */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalStandardDevicesInPackage_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Vendor Devices in Package: 1E.0006 */ +/* Global Standard Vendor Devices in Package: 1E.0006 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Vendor Devices in Package */ + union + { + struct + { + /*! \brief 1E.0006.F ROS Vendor Specific Device #2 Present + AQ_GlobalStandardVendorDevicesInPackage_APPIA.u0.bits_0.vendorSpecificDevice_2Present + + Default = 0x1 + + 1 = Device #2 is present in package + 0 = Device #2 is not present in package + + Notes: + This is always set to 1 as the PHY utilizes this device for the DSP PMA registers. */ + unsigned int vendorSpecificDevice_2Present : 1; /* 1E.0006.F ROS Default = 0x1 */ + /* 1 = Device #2 is present in package + 0 = Device #2 is not present in package */ + /*! \brief 1E.0006.E ROS Vendor Specific Device #1 Present + AQ_GlobalStandardVendorDevicesInPackage_APPIA.u0.bits_0.vendorSpecificDevice_1Present + + Default = 0x1 + + 1 = Device #1 is present in package + 0 = Device #1 is not present in package + + Notes: + This is always set to 1 as the PHY utilizes this device for the global control registers. */ + unsigned int vendorSpecificDevice_1Present : 1; /* 1E.0006.E ROS Default = 0x1 */ + /* 1 = Device #1 is present in package + 0 = Device #1 is not present in package */ + /*! \brief 1E.0006.D ROS Clause 22 Extension Present + AQ_GlobalStandardVendorDevicesInPackage_APPIA.u0.bits_0.clause_22ExtensionPresent + + Default = 0x1 + + 1 = Clause 22 Extension is present in package + 0 = Clause 22 Extension is not present in package + + Notes: + This is always set to 1 as the PHY utilizes this device for the GbE registers. */ + unsigned int clause_22ExtensionPresent : 1; /* 1E.0006.D ROS Default = 0x1 */ + /* 1 = Clause 22 Extension is present in package + 0 = Clause 22 Extension is not present in package */ + unsigned int reserved0 : 13; + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalStandardVendorDevicesInPackage_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Status 2: 1E.0008 */ +/* Global Standard Status 2: 1E.0008 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Status 2 */ + union + { + struct + { + /*! \brief 1E.0008.F:E ROS Device Present [1:0] + AQ_GlobalStandardStatus_2_APPIA.u0.bits_0.devicePresent + + Default = 0x2 + + [F:E] + 0x3 = No device at this address + 0x2 = Device present at this address + 0x1 = No device at this address + 0x0 = No device at this address + + Notes: + This field is always set to 0x2, as the Global MMD resides here in the PHY. */ + unsigned int devicePresent : 2; /* 1E.0008.F:E ROS Default = 0x2 */ + /* [F:E] + 0x3 = No device at this address + 0x2 = Device present at this address + 0x1 = No device at this address + 0x0 = No device at this address */ + unsigned int reserved0 : 14; + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalStandardStatus_2_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Package Identifier: 1E.000E */ +/* Global Standard Package Identifier: 1E.000E */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Package Identifier */ + union + { + struct + { + /*! \brief 1E.000E.F:0 RO Package ID MSW [1F:10] + AQ_GlobalStandardPackageIdentifier_APPIA.u0.bits_0.packageIdMSW + + + + Bits 31- 16 of Package ID + */ + unsigned int packageIdMSW : 16; /* 1E.000E.F:0 RO */ + /* Bits 31- 16 of Package ID */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Standard Package Identifier */ + union + { + struct + { + /*! \brief 1E.000F.F:0 RO Package ID LSW [F:0] + AQ_GlobalStandardPackageIdentifier_APPIA.u1.bits_1.packageIdLSW + + + + Bits 15 - 0 of Package ID + */ + unsigned int packageIdLSW : 16; /* 1E.000F.F:0 RO */ + /* Bits 15 - 0 of Package ID */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalStandardPackageIdentifier_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Firmware ID: 1E.0020 */ +/* Global Firmware ID: 1E.0020 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Firmware ID */ + union + { + struct + { + /*! \brief 1E.0020.F:8 RO Firmware Major Revision Number [7:0] + AQ_GlobalFirmwareID_APPIA.u0.bits_0.firmwareMajorRevisionNumber + + + + [F:8] = Major revision number + + Notes: + + + The lower six bits of major and minor firmware revision are exchanged in autonegotiation when the PHYID message is sent. */ + unsigned int firmwareMajorRevisionNumber : 8; /* 1E.0020.F:8 RO */ + /* [F:8] = Major revision number */ + /*! \brief 1E.0020.7:0 RO Firmware Minor Revision Number [7:0] + AQ_GlobalFirmwareID_APPIA.u0.bits_0.firmwareMinorRevisionNumber + + + + [7:0] = Minor revision number + + Notes: + + + The lower six bits of major and minor firmware revision are exchanged in autonegotiation when the PHYID message is sent. */ + unsigned int firmwareMinorRevisionNumber : 8; /* 1E.0020.7:0 RO */ + /* [7:0] = Minor revision number */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalFirmwareID_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Chip Identification: 1E.0021 */ +/* Global Chip Identification: 1E.0021 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Chip Identification */ + union + { + struct + { + /*! \brief 1E.0021.F:0 RO Chip Identification [F:0] + AQ_GlobalChipIdentification_APPIA.u0.bits_0.chipIdentification + + + + Hardware Chip ID + + Notes: + This value is a hard-coded chip ID */ + unsigned int chipIdentification : 16; /* 1E.0021.F:0 RO */ + /* Hardware Chip ID */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalChipIdentification_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Chip Revision: 1E.0022 */ +/* Global Chip Revision: 1E.0022 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Chip Revision */ + union + { + struct + { + /*! \brief 1E.0022.F:0 RO Chip Revision [F:0] + AQ_GlobalChipRevision_APPIA.u0.bits_0.chipRevision + + + + Hardware Chip Revision + + Notes: + This value is a hard-coded chip revision */ + unsigned int chipRevision : 16; /* 1E.0022.F:0 RO */ + /* Hardware Chip Revision */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalChipRevision_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global NVR Interface: 1E.0100 */ +/* Global NVR Interface: 1E.0100 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global NVR Interface */ + union + { + struct + { + /*! \brief 1E.0100.F R/WSC NVR Execute Operation + AQ_GlobalNvrInterface_APPIA.u0.bits_0.nvrExecuteOperation + + Default = 0x0 + + 1 = Start NVR Operation + + + Notes: + When set to 1, the NVR operation will begin. Ensure that the uP is stalled using the See MCP Run Stall bit to ensure no NVR contention. */ + unsigned int nvrExecuteOperation : 1; /* 1E.0100.F R/WSC Default = 0x0 */ + /* 1 = Start NVR Operation + */ + /*! \brief 1E.0100.E R/W NVR Write Mode + AQ_GlobalNvrInterface_APPIA.u0.bits_0.nvrWriteMode + + Default = 0x0 + + 1 = Write to NVR + 0 = Read from NVR + + */ + unsigned int nvrWriteMode : 1; /* 1E.0100.E R/W Default = 0x0 */ + /* 1 = Write to NVR + 0 = Read from NVR + */ + /*! \brief 1E.0100.D R/W Freeze NVR CRC + AQ_GlobalNvrInterface_APPIA.u0.bits_0.freezeNvrCrc + + Default = 0x0 + + 1 = Freeze NVR Mailbox CRC calculation register + + + Notes: + To prevent an erroneous answer, this bit should not be set at the same time the See NVR Operation Valid bit is set. */ + unsigned int freezeNvrCrc : 1; /* 1E.0100.D R/W Default = 0x0 */ + /* 1 = Freeze NVR Mailbox CRC calculation register + */ + /*! \brief 1E.0100.C R/WSC Reset NVR CRC + AQ_GlobalNvrInterface_APPIA.u0.bits_0.resetNvrCrc + + Default = 0x0 + + 1 = Reset NVR Mailbox CRC calculation register + + + Notes: + To prevent an erroneous answer, this bit should not be set at the same time the See NVR Operation Valid bit is set. */ + unsigned int resetNvrCrc : 1; /* 1E.0100.C R/WSC Default = 0x0 */ + /* 1 = Reset NVR Mailbox CRC calculation register + */ + unsigned int reserved0 : 1; + /*! \brief 1E.0100.A R/W NVR Burst + AQ_GlobalNvrInterface_APPIA.u0.bits_0.nvrBurst + + Default = 0x0 + + 0 = Single read or write operation of up to 4 bytes + 1 = Burst operation + + + Notes: + When this bit is set, the operation is a burst operation where more than 32-bits is read from the NVR or written to the NVR. This bit should be set to one until the last burst in the read or write operation, when it should be set to zero. It operates by gating the SPI clock, and not restarting it until new data is ready to be written, or the previous contents have been read. Each burst of data requires the NVR Execute Operation bit to be set to initiate the next phase. */ + unsigned int nvrBurst : 1; /* 1E.0100.A R/W Default = 0x0 */ + /* 0 = Single read or write operation of up to 4 bytes + 1 = Burst operation + */ + unsigned int reserved1 : 1; + /*! \brief 1E.0100.8 RO NVR Busy + AQ_GlobalNvrInterface_APPIA.u0.bits_0.nvrBusy + + + + 1 = NVR is busy + 0 = NVR is ready + + + Notes: + When set to 1, the NVR is busy. A new NVR operation should not occur until this bit is 0. If the NVR clock is greater than 64/63 of the MDIO clock, this bit never needs to be polled when operating over the MDIO. */ + unsigned int nvrBusy : 1; /* 1E.0100.8 RO */ + /* 1 = NVR is busy + 0 = NVR is ready + */ + /*! \brief 1E.0100.7:0 R/W NVR Opcode [7:0] + AQ_GlobalNvrInterface_APPIA.u0.bits_0.nvrOpcode + + Default = 0x03 + + NVR instruction opcode + + */ + unsigned int nvrOpcode : 8; /* 1E.0100.7:0 R/W Default = 0x03 */ + /* NVR instruction opcode + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global NVR Interface */ + union + { + struct + { + /*! \brief 1E.0101.F:0 RO NVR Mailbox CRC [F:0] + AQ_GlobalNvrInterface_APPIA.u1.bits_1.nvrMailboxCrc + + + + The running CRC-16 of everything passing through the NVR interface + + + Notes: + The CRC-16 over all data written or read through the NVR interface. The CRC-16 is calculated by dividing the data by: + x^16 + x^12 + x^5 + 1 */ + unsigned int nvrMailboxCrc : 16; /* 1E.0101.F:0 RO */ + /* The running CRC-16 of everything passing through the NVR interface + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global NVR Interface */ + union + { + struct + { + unsigned int reserved0 : 8; + /*! \brief 1E.0102.7:0 R/W NVR Address MSW [17:10] + AQ_GlobalNvrInterface_APPIA.u2.bits_2.nvrAddressMSW + + Default = 0x00 + + NVR address MSW bits [17:10] + + + Notes: + The address of where to read and write from in the NVR. This is self-incrementing and will automatically increment after each read or write operation. The increment amount is based on the data length (i.e. increments by 4 if the data length is 4 bytes) */ + unsigned int nvrAddressMSW : 8; /* 1E.0102.7:0 R/W Default = 0x00 */ + /* NVR address MSW bits [17:10] + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global NVR Interface */ + union + { + struct + { + /*! \brief 1E.0103.F:0 R/W NVR Address LSW [F:0] + AQ_GlobalNvrInterface_APPIA.u3.bits_3.nvrAddressLSW + + Default = 0x0000 + + NVR address LSW bits [F:0] + + + Notes: + The address of where to read and write from in the NVR. This is self-incrementing and will automatically increment after each read or write operation. */ + unsigned int nvrAddressLSW : 16; /* 1E.0103.F:0 R/W Default = 0x0000 */ + /* NVR address LSW bits [F:0] + */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global NVR Interface */ + union + { + struct + { + /*! \brief 1E.0104.F:0 R/W NVR Data MSW [1F:10] + AQ_GlobalNvrInterface_APPIA.u4.bits_4.nvrDataMSW + + Default = 0x0000 + + NVR data MSW bits [1F:10] + + + Notes: + Data is stored and read-out from these registers in little-endian format for operations such as FLASH device ID, and for programming the processor. + + For instance the 64K Atmel device code reads out as two bytes 0x651F into the LSW register, whereas the datasheet indicates that 1F is the first byte read, followed by 65 as the second byte. + + To burst read and write these 4 bytes in the correct order (where DD is written to address x), they should be stored as: + + AA BB in the MSW + CC DD in the LSW. */ + unsigned int nvrDataMSW : 16; /* 1E.0104.F:0 R/W Default = 0x0000 */ + /* NVR data MSW bits [1F:10] + */ + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of Global NVR Interface */ + union + { + struct + { + /*! \brief 1E.0105.F:0 R/W NVR Data LSW [F:0] + AQ_GlobalNvrInterface_APPIA.u5.bits_5.nvrDataLSW + + Default = 0x0000 + + NVR data LSW bits [F:0] + + + Notes: + Data is stored and read-out from these registers in little-endian format for operations such as FLASH device ID, and for programming the processor. + + For instance the 64K Atmel device code reads out as two bytes 0x651F into the LSW register, whereas the datasheet indicates that 1F is the first byte read, followed by 65 as the second byte. + To burst read and write these 4 bytes in the correct order (where DD is written to address x), they should be stored as: + + AA BB in the MSW + CC DD in the LSW. */ + unsigned int nvrDataLSW : 16; /* 1E.0105.F:0 R/W Default = 0x0000 */ + /* NVR data LSW bits [F:0] + */ + } bits_5; + uint16_t word_5; + } u5; +} AQ_GlobalNvrInterface_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Mailbox Interface: 1E.0200 */ +/* Global Mailbox Interface: 1E.0200 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Mailbox Interface */ + union + { + struct + { + /*! \brief 1E.0200.F R/WSC uP Mailbox Execute Operation + AQ_GlobalMailboxInterface_APPIA.u0.bits_0.upMailboxExecuteOperation + + Default = 0x0 + + 1 = Start of mailbox Operation + + + Notes: + Indicates mailbox is loaded and ready */ + unsigned int upMailboxExecuteOperation : 1; /* 1E.0200.F R/WSC Default = 0x0 */ + /* 1 = Start of mailbox Operation + */ + /*! \brief 1E.0200.E R/W uP Mailbox Write Mode + AQ_GlobalMailboxInterface_APPIA.u0.bits_0.upMailboxWriteMode + + Default = 0x0 + + 1 = Write + 0 = Read + + + Notes: + Mailbox direction */ + unsigned int upMailboxWriteMode : 1; /* 1E.0200.E R/W Default = 0x0 */ + /* 1 = Write + 0 = Read + */ + unsigned int reserved0 : 1; + /*! \brief 1E.0200.C R/WSC Reset uP Mailbox CRC + AQ_GlobalMailboxInterface_APPIA.u0.bits_0.resetUpMailboxCrc + + Default = 0x0 + + 1 = Reset uP mailbox CRC calculation register + + */ + unsigned int resetUpMailboxCrc : 1; /* 1E.0200.C R/WSC Default = 0x0 */ + /* 1 = Reset uP mailbox CRC calculation register + */ + unsigned int reserved1 : 3; + /*! \brief 1E.0200.8 RO uP Mailbox Busy + AQ_GlobalMailboxInterface_APPIA.u0.bits_0.upMailboxBusy + + + + 1 = uP mailbox busy + 0 = uP mailbox ready + + + Notes: + In general the uP will respond within a few processor cycles to any PIF slave request, much faster than the MDIO. If the busy is asserted over multiple MDIO polling cycles, then a H/W error may have occured and a Global S/W reset or uP reset is required. */ + unsigned int upMailboxBusy : 1; /* 1E.0200.8 RO */ + /* 1 = uP mailbox busy + 0 = uP mailbox ready + */ + unsigned int reserved2 : 8; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Mailbox Interface */ + union + { + struct + { + /*! \brief 1E.0201.F:0 RO uP Mailbox CRC [F:0] + AQ_GlobalMailboxInterface_APPIA.u1.bits_1.upMailboxCrc + + + + The running CRC-16 of everything passing through the mailbox interface + + */ + unsigned int upMailboxCrc : 16; /* 1E.0201.F:0 RO */ + /* The running CRC-16 of everything passing through the mailbox interface + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Mailbox Interface */ + union + { + struct + { + /*! \brief 1E.0202.F:0 R/W uP Mailbox Address MSW [1F:10] + AQ_GlobalMailboxInterface_APPIA.u2.bits_2.upMailboxAddressMSW + + Default = 0x0000 + + uP Mailbox MSW address + + + Notes: + The address of where to read and write from in the Microcontroller Mailbox. This is self-incrementing and automatically increments after each read and write operation.PHY */ + unsigned int upMailboxAddressMSW : 16; /* 1E.0202.F:0 R/W Default = 0x0000 */ + /* uP Mailbox MSW address + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global Mailbox Interface */ + union + { + struct + { + /*! \brief 1E.0203.F:2 R/W uP Mailbox Address LSW [F:2] + AQ_GlobalMailboxInterface_APPIA.u3.bits_3.upMailboxAddressLSW + + Default = 0x0000 + + uP LSW Mailbox address [F:2] + + + Notes: + The address of where to read and write from in the Microcontroller Mailbox. This is self-incrementing and automatically increments after each read and write operation.PHY */ + unsigned int upMailboxAddressLSW : 14; /* 1E.0203.F:2 R/W Default = 0x0000 */ + /* uP LSW Mailbox address [F:2] + */ + /*! \brief 1E.0203.1:0 RO uP Mailbox Address LSW Don't Care [1:0] + AQ_GlobalMailboxInterface_APPIA.u3.bits_3.upMailboxAddressLSW_Don_tCare + + + + Least significant uP LSW Mailbox address bits [1:0] + + + Notes: + These bits are always set to 0 since each memory access is on a 4-byte boundary. */ + unsigned int upMailboxAddressLSW_Don_tCare : 2; /* 1E.0203.1:0 RO */ + /* Least significant uP LSW Mailbox address bits [1:0] + */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global Mailbox Interface */ + union + { + struct + { + /*! \brief 1E.0204.F:0 R/W uP Mailbox Data MSW [1F:10] + AQ_GlobalMailboxInterface_APPIA.u4.bits_4.upMailboxDataMSW + + Default = 0x0000 + + uP Mailbox data MSW + + */ + unsigned int upMailboxDataMSW : 16; /* 1E.0204.F:0 R/W Default = 0x0000 */ + /* uP Mailbox data MSW + */ + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of Global Mailbox Interface */ + union + { + struct + { + /*! \brief 1E.0205.F:0 R/W uP Mailbox Data LSW [F:0] + AQ_GlobalMailboxInterface_APPIA.u5.bits_5.upMailboxDataLSW + + Default = 0x0000 + + uP Mailbox data LSW + + */ + unsigned int upMailboxDataLSW : 16; /* 1E.0205.F:0 R/W Default = 0x0000 */ + /* uP Mailbox data LSW + */ + } bits_5; + uint16_t word_5; + } u5; +} AQ_GlobalMailboxInterface_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Microprocessor Scratch Pad: 1E.0300 */ +/* Global Microprocessor Scratch Pad: 1E.0300 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Microprocessor Scratch Pad */ + union + { + struct + { + /*! \brief 1E.0300.F:0 R/W Scratch Pad 1[F:0] + AQ_GlobalMicroprocessorScratchPad_APPIA.u0.bits_0.scratchPad_1 + + Default = 0x0000 + + General Purpose Scratch Pad1 + */ + unsigned int scratchPad_1 : 16; /* 1E.0300.F:0 R/W Default = 0x0000 */ + /* General Purpose Scratch Pad1 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Microprocessor Scratch Pad */ + union + { + struct + { + /*! \brief 1E.0301.F:0 R/W Scratch Pad 2 [F:0] + AQ_GlobalMicroprocessorScratchPad_APPIA.u1.bits_1.scratchPad_2 + + Default = 0x0000 + + General Purpose Scratch P + */ + unsigned int scratchPad_2 : 16; /* 1E.0301.F:0 R/W Default = 0x0000 */ + /* General Purpose Scratch P */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalMicroprocessorScratchPad_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Control: 1E.C000 */ +/* Global Control: 1E.C000 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Control */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Control */ + union + { + struct + { + /*! \brief 1E.C001.F R/W uP Reset + AQ_GlobalControl_APPIA.u1.bits_1.upReset + + Default = 0x0 + + 1 = Reset + + + Notes: + Resets the uP and the PIF master and slave bus. Will be active for a minimum of 100 microseconds. */ + unsigned int upReset : 1; /* 1E.C001.F R/W Default = 0x0 */ + /* 1 = Reset + */ + unsigned int reserved0 : 8; + /*! \brief 1E.C001.6 R/W uP Run Stall Override + AQ_GlobalControl_APPIA.u1.bits_1.upRunStallOverride + + Default = 0x0 + + 0 = uP Run Stall from "MDIO Boot Load" pin. + 1 = uP Run Stall from See MCP Run Stall bit + + + Notes: + This bit selects the uP Run Stall from either the "MDIO Boot Load" pin or the See MCP Run Stall bit. */ + unsigned int upRunStallOverride : 1; /* 1E.C001.6 R/W Default = 0x0 */ + /* 0 = uP Run Stall from "MDIO Boot Load" pin. + 1 = uP Run Stall from See MCP Run Stall bit + */ + unsigned int reserved1 : 5; + /*! \brief 1E.C001.0 R/W uP Run Stall + AQ_GlobalControl_APPIA.u1.bits_1.upRunStall + + Default = 0x0 + + 1 = uP Run Stall + 0 = uP normal mode + + + Notes: + Deactivates the uP. The PIF slave bus for inbound requests will still be active. This bit is muliplexed with the "MDIO Boot Load" pin with the See uP Run Stall Override bit as the select. When the "MDIO Boot Load" pin is asserted, the uP will be in Run Stall mode after reset. */ + unsigned int upRunStall : 1; /* 1E.C001.0 R/W Default = 0x0 */ + /* 1 = uP Run Stall + 0 = uP normal mode + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalControl_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Reset Control: 1E.C006 */ +/* Global Reset Control: 1E.C006 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Reset Control */ + union + { + struct + { + unsigned int reserved0 : 1; + /*! \brief 1E.C006.E R/WPD Global MMD Reset Disable + AQ_GlobalResetControl_APPIA.u0.bits_0.globalMMD_ResetDisable + + Provisionable Default = 0x0 + + 1 = Disable the S/W reset to the Global MMD registers + 0 = Enable the S/W reset to the Global MMD registers + + + Notes: + Setting this bit prevents a Global S/W reset or Global S/W reset from resetting the Global MMD registers */ + unsigned int globalMMD_ResetDisable : 1; /* 1E.C006.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Disable the S/W reset to the Global MMD registers + 0 = Enable the S/W reset to the Global MMD registers + */ + unsigned int reserved1 : 14; + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalResetControl_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Diagnostic Provisioning: 1E.C400 */ +/* Global Diagnostic Provisioning: 1E.C400 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Diagnostic Provisioning */ + union + { + struct + { + /*! \brief 1E.C400.F R/WPD Enable Diagnostics + AQ_GlobalDiagnosticProvisioning_APPIA.u0.bits_0.enableDiagnostics + + Provisionable Default = 0x1 + + 1 = Chip performs diagnostics on power-up + */ + unsigned int enableDiagnostics : 1; /* 1E.C400.F R/WPD Provisionable Default = 0x1 */ + /* 1 = Chip performs diagnostics on power-up */ + unsigned int reserved0 : 15; + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalDiagnosticProvisioning_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Thermal Provisioning: 1E.C420 */ +/* Global Thermal Provisioning: 1E.C420 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Thermal Provisioning */ + union + { + struct + { + /*! \brief 1E.C420.F:0 R/WPD Reserved 0 [F:0] + AQ_GlobalThermalProvisioning_APPIA.u0.bits_0.reserved_0 + + Provisionable Default = 0x0000 + + Internal reserved - do not modify + + */ + unsigned int reserved_0 : 16; /* 1E.C420.F:0 R/WPD Provisionable Default = 0x0000 */ + /* Internal reserved - do not modify + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Thermal Provisioning */ + union + { + struct + { + /*! \brief 1E.C421.F:0 R/WPD High Temp Failure Threshold [F:0] + AQ_GlobalThermalProvisioning_APPIA.u1.bits_1.highTempFailureThreshold + + Provisionable Default = 0x4600 + + [F:0] of high temperature failure threshold + + Notes: + 2's complement value with the LSB representing 1/256 of a degree Celsius. This corresponds to -40 degreesC = 0xD800. Default is 70 degreesC. + + In XENPAK mode, F/W will use the XENPAK register 1.A000 - 1.A001: instead of this register. + + NOTE! All Thresholds are orthogonal and can be set to any value regardless the value of the other thresholds. i.e. - High-Temperature-Warning (1E.C423) could be higher than High-Temperature-Failure (1E.C421). */ + unsigned int highTempFailureThreshold : 16; /* 1E.C421.F:0 R/WPD Provisionable Default = 0x4600 */ + /* [F:0] of high temperature failure threshold */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Thermal Provisioning */ + union + { + struct + { + /*! \brief 1E.C422.F:0 R/WPD Low Temp Failure Threshold [F:0] + AQ_GlobalThermalProvisioning_APPIA.u2.bits_2.lowTempFailureThreshold + + Provisionable Default = 0x0000 + + [F:0] of low temperature failure threshold + + Notes: + 2's complement value with the LSB representing 1/256 of a degree Celsius. This corresponds to -40 degreesC = 0xD800. Default is 0 degreesC. + + In XENPAK mode, F/W will use the XENPAK register 1.A002 - 1.A003: instead of this register. + + NOTE! All Thresholds are orthogonal and can be set to any value regardless the value of the other thresholds. i.e. - High-Temperature-Warning (1E.C423) could be higher than High-Temperature-Failure (1E.C421). */ + unsigned int lowTempFailureThreshold : 16; /* 1E.C422.F:0 R/WPD Provisionable Default = 0x0000 */ + /* [F:0] of low temperature failure threshold */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global Thermal Provisioning */ + union + { + struct + { + /*! \brief 1E.C423.F:0 R/WPD High Temp Warning Threshold [F:0] + AQ_GlobalThermalProvisioning_APPIA.u3.bits_3.highTempWarningThreshold + + Provisionable Default = 0x3C00 + + [F:0] of high temperature warning threshold + + Notes: + 2's complement value with the LSB representing 1/256 of a degree Celsius. This corresponds to -40 degreesC = 0xD008. Default is 60 degreesC. + + In XENPAK mode, F/W will use the XENPAK register 1.A004 - 1.A005: instead of this register. + + NOTE! All Thresholds are orthogonal and can be set to any value regardless the value of the other thresholds. i.e. - High-Temperature-Warning (1E.C423) could be higher than High-Temperature-Failure (1E.C421). */ + unsigned int highTempWarningThreshold : 16; /* 1E.C423.F:0 R/WPD Provisionable Default = 0x3C00 */ + /* [F:0] of high temperature warning threshold */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global Thermal Provisioning */ + union + { + struct + { + /*! \brief 1E.C424.F:0 R/WPD Low Temp Warning Threshold [F:0] + AQ_GlobalThermalProvisioning_APPIA.u4.bits_4.lowTempWarningThreshold + + Provisionable Default = 0x0A00 + + [F:0] of low temperature warning threshold + + Notes: + 2's complement value with the LSB representing 1/256 of a degree Celsius. This corresponds to -40 degreesC = 0xD800. Default is 10 degreesC. + + In XENPAK mode, F/W will use the XENPAK register 1.A006 - 1.A007: instead of this register. + + NOTE! All Thresholds are orthogonal and can be set to any value regardless the value of the other thresholds. i.e. - High-Temperature-Warning (1E.C423) could be higher than High-Temperature-Failure (1E.C421). */ + unsigned int lowTempWarningThreshold : 16; /* 1E.C424.F:0 R/WPD Provisionable Default = 0x0A00 */ + /* [F:0] of low temperature warning threshold */ + } bits_4; + uint16_t word_4; + } u4; +} AQ_GlobalThermalProvisioning_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global LED Provisioning: 1E.C430 */ +/* Global LED Provisioning: 1E.C430 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 7; + /*! \brief 1E.C430.8 R/WPD LED #0 Manual Set + AQ_GlobalLedProvisioning_APPIA.u0.bits_0.led_0ManualSet + + Provisionable Default = 0x0 + + 1 = LED On + + */ + unsigned int led_0ManualSet : 1; /* 1E.C430.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED On + */ + /*! \brief 1E.C430.7 R/WPD LED #0 10 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u0.bits_0.led_0_10Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 10 Gb/s + + */ + unsigned int led_0_10Gb_sLinkEstablished : 1; /* 1E.C430.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 10 Gb/s + */ + /*! \brief 1E.C430.6 R/WPD LED #0 1 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u0.bits_0.led_0_1Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 1 Gb/s + + */ + unsigned int led_0_1Gb_sLinkEstablished : 1; /* 1E.C430.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 1 Gb/s + */ + /*! \brief 1E.C430.5 R/WPD LED #0 100 Mb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u0.bits_0.led_0_100Mb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 100 Mb/s + + */ + unsigned int led_0_100Mb_sLinkEstablished : 1; /* 1E.C430.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 100 Mb/s + */ + /*! \brief 1E.C430.4 R/WPD LED #0 Connecting + AQ_GlobalLedProvisioning_APPIA.u0.bits_0.led_0Connecting + + Provisionable Default = 0x0 + + 1 = LED is on when attempting to connect. + + */ + unsigned int led_0Connecting : 1; /* 1E.C430.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when attempting to connect. + */ + /*! \brief 1E.C430.3 R/WPD LED #0 Receive Activity + AQ_GlobalLedProvisioning_APPIA.u0.bits_0.led_0ReceiveActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on receive activity + + */ + unsigned int led_0ReceiveActivity : 1; /* 1E.C430.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on receive activity + */ + /*! \brief 1E.C430.2 R/WPD LED #0 Transmit Activity + AQ_GlobalLedProvisioning_APPIA.u0.bits_0.led_0TransmitActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on transmit activity + + */ + unsigned int led_0TransmitActivity : 1; /* 1E.C430.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on transmit activity + */ + /*! \brief 1E.C430.1:0 R/WPD LED #0 Activity Stretch [1:0] + AQ_GlobalLedProvisioning_APPIA.u0.bits_0.led_0ActivityStretch + + Provisionable Default = 0x3 + + [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + + */ + unsigned int led_0ActivityStretch : 2; /* 1E.C430.1:0 R/WPD Provisionable Default = 0x3 */ + /* [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 7; + /*! \brief 1E.C431.8 R/WPD LED #1 Manual Set + AQ_GlobalLedProvisioning_APPIA.u1.bits_1.led_1ManualSet + + Provisionable Default = 0x0 + + 1 = LED On + + */ + unsigned int led_1ManualSet : 1; /* 1E.C431.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED On + */ + /*! \brief 1E.C431.7 R/WPD LED #1 10 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u1.bits_1.led_1_10Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 10 Gb/s + + */ + unsigned int led_1_10Gb_sLinkEstablished : 1; /* 1E.C431.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 10 Gb/s + */ + /*! \brief 1E.C431.6 R/WPD LED #1 1 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u1.bits_1.led_1_1Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 1 Gb/s + + */ + unsigned int led_1_1Gb_sLinkEstablished : 1; /* 1E.C431.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 1 Gb/s + */ + /*! \brief 1E.C431.5 R/WPD LED #1 100 Mb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u1.bits_1.led_1_100Mb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 100 Mb/s + + */ + unsigned int led_1_100Mb_sLinkEstablished : 1; /* 1E.C431.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 100 Mb/s + */ + /*! \brief 1E.C431.4 R/WPD LED #1 Connecting + AQ_GlobalLedProvisioning_APPIA.u1.bits_1.led_1Connecting + + Provisionable Default = 0x0 + + 1 = LED is on when attempting to connect. + + */ + unsigned int led_1Connecting : 1; /* 1E.C431.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when attempting to connect. + */ + /*! \brief 1E.C431.3 R/WPD LED #1 Receive Activity + AQ_GlobalLedProvisioning_APPIA.u1.bits_1.led_1ReceiveActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on receive activity + + */ + unsigned int led_1ReceiveActivity : 1; /* 1E.C431.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on receive activity + */ + /*! \brief 1E.C431.2 R/WPD LED #1 Transmit Activity + AQ_GlobalLedProvisioning_APPIA.u1.bits_1.led_1TransmitActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on transmit activity + + */ + unsigned int led_1TransmitActivity : 1; /* 1E.C431.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on transmit activity + */ + /*! \brief 1E.C431.1:0 R/WPD LED #1 Activity Stretch [1:0] + AQ_GlobalLedProvisioning_APPIA.u1.bits_1.led_1ActivityStretch + + Provisionable Default = 0x3 + + [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + + */ + unsigned int led_1ActivityStretch : 2; /* 1E.C431.1:0 R/WPD Provisionable Default = 0x3 */ + /* [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 7; + /*! \brief 1E.C432.8 R/WPD LED #2 Manual Set + AQ_GlobalLedProvisioning_APPIA.u2.bits_2.led_2ManualSet + + Provisionable Default = 0x0 + + 1 = LED On + + */ + unsigned int led_2ManualSet : 1; /* 1E.C432.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED On + */ + /*! \brief 1E.C432.7 R/WPD LED #2 10 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u2.bits_2.led_2_10Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 10 Gb/s + + */ + unsigned int led_2_10Gb_sLinkEstablished : 1; /* 1E.C432.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 10 Gb/s + */ + /*! \brief 1E.C432.6 R/WPD LED #2 1 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u2.bits_2.led_2_1Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 1 Gb/s + + */ + unsigned int led_2_1Gb_sLinkEstablished : 1; /* 1E.C432.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 1 Gb/s + */ + /*! \brief 1E.C432.5 R/WPD LED #2 100 Mb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u2.bits_2.led_2_100Mb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 100 Mb/s + + */ + unsigned int led_2_100Mb_sLinkEstablished : 1; /* 1E.C432.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 100 Mb/s + */ + /*! \brief 1E.C432.4 R/WPD LED #2 Connecting + AQ_GlobalLedProvisioning_APPIA.u2.bits_2.led_2Connecting + + Provisionable Default = 0x0 + + 1 = LED is on when attempting to connect. + + */ + unsigned int led_2Connecting : 1; /* 1E.C432.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when attempting to connect. + */ + /*! \brief 1E.C432.3 R/WPD LED #2 Receive Activity + AQ_GlobalLedProvisioning_APPIA.u2.bits_2.led_2ReceiveActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on receive activity + + */ + unsigned int led_2ReceiveActivity : 1; /* 1E.C432.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on receive activity + */ + /*! \brief 1E.C432.2 R/WPD LED #2 Transmit Activity + AQ_GlobalLedProvisioning_APPIA.u2.bits_2.led_2TransmitActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on transmit activity + + */ + unsigned int led_2TransmitActivity : 1; /* 1E.C432.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on transmit activity + */ + /*! \brief 1E.C432.1:0 R/WPD LED #2 Activity Stretch [1:0] + AQ_GlobalLedProvisioning_APPIA.u2.bits_2.led_2ActivityStretch + + Provisionable Default = 0x3 + + [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + + */ + unsigned int led_2ActivityStretch : 2; /* 1E.C432.1:0 R/WPD Provisionable Default = 0x3 */ + /* [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 7; + /*! \brief 1E.C433.8 R/WPD LED #3 Manual Set + AQ_GlobalLedProvisioning_APPIA.u3.bits_3.led_3ManualSet + + Provisionable Default = 0x0 + + 1 = LED On + + */ + unsigned int led_3ManualSet : 1; /* 1E.C433.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED On + */ + /*! \brief 1E.C433.7 R/WPD LED #3 10 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u3.bits_3.led_3_10Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 10 Gb/s + + */ + unsigned int led_3_10Gb_sLinkEstablished : 1; /* 1E.C433.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 10 Gb/s + */ + /*! \brief 1E.C433.6 R/WPD LED #3 1 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u3.bits_3.led_3_1Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 1 Gb/s + + */ + unsigned int led_3_1Gb_sLinkEstablished : 1; /* 1E.C433.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 1 Gb/s + */ + /*! \brief 1E.C433.5 R/WPD LED #3 100 Mb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u3.bits_3.led_3_100Mb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 100 Mb/s + + */ + unsigned int led_3_100Mb_sLinkEstablished : 1; /* 1E.C433.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 100 Mb/s + */ + /*! \brief 1E.C433.4 R/WPD LED #3 Connecting + AQ_GlobalLedProvisioning_APPIA.u3.bits_3.led_3Connecting + + Provisionable Default = 0x0 + + 1 = LED is on when attempting to connect. + + */ + unsigned int led_3Connecting : 1; /* 1E.C433.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when attempting to connect. + */ + /*! \brief 1E.C433.3 R/WPD LED #3 Receive Activity + AQ_GlobalLedProvisioning_APPIA.u3.bits_3.led_3ReceiveActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on receive activity + + */ + unsigned int led_3ReceiveActivity : 1; /* 1E.C433.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on receive activity + */ + /*! \brief 1E.C433.2 R/WPD LED #3 Transmit Activity + AQ_GlobalLedProvisioning_APPIA.u3.bits_3.led_3TransmitActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on transmit activity + + */ + unsigned int led_3TransmitActivity : 1; /* 1E.C433.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on transmit activity + */ + /*! \brief 1E.C433.1:0 R/WPD LED #3 Activity Stretch [1:0] + AQ_GlobalLedProvisioning_APPIA.u3.bits_3.led_3ActivityStretch + + Provisionable Default = 0x3 + + [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + + */ + unsigned int led_3ActivityStretch : 2; /* 1E.C433.1:0 R/WPD Provisionable Default = 0x3 */ + /* [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 7; + /*! \brief 1E.C434.8 R/WPD LED #4 Manual Set + AQ_GlobalLedProvisioning_APPIA.u4.bits_4.led_4ManualSet + + Provisionable Default = 0x0 + + 1 = LED On + + */ + unsigned int led_4ManualSet : 1; /* 1E.C434.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED On + */ + /*! \brief 1E.C434.7 R/WPD LED #4 10 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u4.bits_4.led_4_10Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 10 Gb/s + + */ + unsigned int led_4_10Gb_sLinkEstablished : 1; /* 1E.C434.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 10 Gb/s + */ + /*! \brief 1E.C434.6 R/WPD LED #4 1 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u4.bits_4.led_4_1Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 1 Gb/s + + */ + unsigned int led_4_1Gb_sLinkEstablished : 1; /* 1E.C434.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 1 Gb/s + */ + /*! \brief 1E.C434.5 R/WPD LED #4 100 Mb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u4.bits_4.led_4_100Mb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 100 Mb/s + + */ + unsigned int led_4_100Mb_sLinkEstablished : 1; /* 1E.C434.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 100 Mb/s + */ + /*! \brief 1E.C434.4 R/WPD LED #4 Connecting + AQ_GlobalLedProvisioning_APPIA.u4.bits_4.led_4Connecting + + Provisionable Default = 0x0 + + 1 = LED is on when attempting to connect. + + */ + unsigned int led_4Connecting : 1; /* 1E.C434.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when attempting to connect. + */ + /*! \brief 1E.C434.3 R/WPD LED #4 Receive Activity + AQ_GlobalLedProvisioning_APPIA.u4.bits_4.led_4ReceiveActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on receive activity + + */ + unsigned int led_4ReceiveActivity : 1; /* 1E.C434.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on receive activity + */ + /*! \brief 1E.C434.2 R/WPD LED #4 Transmit Activity + AQ_GlobalLedProvisioning_APPIA.u4.bits_4.led_4TransmitActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on transmit activity + + */ + unsigned int led_4TransmitActivity : 1; /* 1E.C434.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on transmit activity + */ + /*! \brief 1E.C434.1:0 R/WPD LED #4 Activity Stretch [1:0] + AQ_GlobalLedProvisioning_APPIA.u4.bits_4.led_4ActivityStretch + + Provisionable Default = 0x3 + + [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + + */ + unsigned int led_4ActivityStretch : 2; /* 1E.C434.1:0 R/WPD Provisionable Default = 0x3 */ + /* [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + */ + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 7; + /*! \brief 1E.C435.8 R/WPD LED #5 Manual Set + AQ_GlobalLedProvisioning_APPIA.u5.bits_5.led_5ManualSet + + Provisionable Default = 0x0 + + 1 = LED On + + */ + unsigned int led_5ManualSet : 1; /* 1E.C435.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED On + */ + /*! \brief 1E.C435.7 R/WPD LED #5 10 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u5.bits_5.led_5_10Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 10 Gb/s + + */ + unsigned int led_5_10Gb_sLinkEstablished : 1; /* 1E.C435.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 10 Gb/s + */ + /*! \brief 1E.C435.6 R/WPD LED #5 1 Gb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u5.bits_5.led_5_1Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 1 Gb/s + + */ + unsigned int led_5_1Gb_sLinkEstablished : 1; /* 1E.C435.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 1 Gb/s + */ + /*! \brief 1E.C435.5 R/WPD LED #5 100 Mb/s Link Established + AQ_GlobalLedProvisioning_APPIA.u5.bits_5.led_5_100Mb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 100 Mb/s + + */ + unsigned int led_5_100Mb_sLinkEstablished : 1; /* 1E.C435.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 100 Mb/s + */ + /*! \brief 1E.C435.4 R/WPD LED #5 Connecting + AQ_GlobalLedProvisioning_APPIA.u5.bits_5.led_5Connecting + + Provisionable Default = 0x0 + + 1 = LED is on when attempting to connect. + + */ + unsigned int led_5Connecting : 1; /* 1E.C435.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when attempting to connect. + */ + /*! \brief 1E.C435.3 R/WPD LED #5 Receive Activity + AQ_GlobalLedProvisioning_APPIA.u5.bits_5.led_5ReceiveActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on receive activity + + */ + unsigned int led_5ReceiveActivity : 1; /* 1E.C435.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on receive activity + */ + /*! \brief 1E.C435.2 R/WPD LED #5 Transmit Activity + AQ_GlobalLedProvisioning_APPIA.u5.bits_5.led_5TransmitActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on transmit activity + + */ + unsigned int led_5TransmitActivity : 1; /* 1E.C435.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on transmit activity + */ + /*! \brief 1E.C435.1:0 R/WPD LED #5 Activity Stretch [1:0] + AQ_GlobalLedProvisioning_APPIA.u5.bits_5.led_5ActivityStretch + + Provisionable Default = 0x3 + + [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + + */ + unsigned int led_5ActivityStretch : 2; /* 1E.C435.1:0 R/WPD Provisionable Default = 0x3 */ + /* [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + */ + } bits_5; + uint16_t word_5; + } u5; + /*! \brief Union for bit and word level access of word 6 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_6; + uint16_t word_6; + } u6; + /*! \brief Union for bit and word level access of word 7 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 15; + /*! \brief 1E.C437.0 R/WPD LED Operation Mode + AQ_GlobalLedProvisioning_APPIA.u7.bits_7.ledOperationMode + + Provisionable Default = 0x0 + + 1 = LED link activity in Mode #2 + 0 = LED link activity in classic mode + + + Notes: + When set to 1, the LED blinking rate is based on Mode #2 algorithm. When set to 0, the LED blinking rate is based on the classic algorithm. */ + unsigned int ledOperationMode : 1; /* 1E.C437.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED link activity in Mode #2 + 0 = LED link activity in classic mode + */ + } bits_7; + uint16_t word_7; + } u7; + /*! \brief Union for bit and word level access of word 8 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 13; + /*! \brief 1E.C438.2 R/WPD LED #0 Drive Three State Select + AQ_GlobalLedProvisioning_APPIA.u8.bits_8.led_0DriveThreeStateSelect + + Provisionable Default = 0x0 + + 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + + */ + unsigned int led_0DriveThreeStateSelect : 1; /* 1E.C438.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + */ + /*! \brief 1E.C438.1 R/WPD LED #0 Active High Select + AQ_GlobalLedProvisioning_APPIA.u8.bits_8.led_0ActiveHighSelect + + Provisionable Default = 0x0 + + 1 = LED active high + 0 = LED active low + + + Notes: + The See LED #0 Manual Active Select bit must be 1 for this bit to take affect. */ + unsigned int led_0ActiveHighSelect : 1; /* 1E.C438.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED active high + 0 = LED active low + */ + /*! \brief 1E.C438.0 R/WPD LED #0 Manual Active Select + AQ_GlobalLedProvisioning_APPIA.u8.bits_8.led_0ManualActiveSelect + + Provisionable Default = 0x0 + + 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + + */ + unsigned int led_0ManualActiveSelect : 1; /* 1E.C438.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + */ + } bits_8; + uint16_t word_8; + } u8; + /*! \brief Union for bit and word level access of word 9 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 13; + /*! \brief 1E.C439.2 R/WPD LED #1 Drive Three State Select + AQ_GlobalLedProvisioning_APPIA.u9.bits_9.led_1DriveThreeStateSelect + + Provisionable Default = 0x0 + + 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + + */ + unsigned int led_1DriveThreeStateSelect : 1; /* 1E.C439.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + */ + /*! \brief 1E.C439.1 R/WPD LED #1 Active High Select + AQ_GlobalLedProvisioning_APPIA.u9.bits_9.led_1ActiveHighSelect + + Provisionable Default = 0x0 + + 1 = LED active high + 0 = LED active low + + + Notes: + The See LED #1 Manual Active Select bit must be 1 for this bit to take affect. */ + unsigned int led_1ActiveHighSelect : 1; /* 1E.C439.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED active high + 0 = LED active low + */ + /*! \brief 1E.C439.0 R/WPD LED #1 Manual Active Select + AQ_GlobalLedProvisioning_APPIA.u9.bits_9.led_1ManualActiveSelect + + Provisionable Default = 0x0 + + 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + + */ + unsigned int led_1ManualActiveSelect : 1; /* 1E.C439.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + */ + } bits_9; + uint16_t word_9; + } u9; + /*! \brief Union for bit and word level access of word 10 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 13; + /*! \brief 1E.C43A.2 R/WPD LED #2 Drive Three State Select + AQ_GlobalLedProvisioning_APPIA.u10.bits_10.led_2DriveThreeStateSelect + + Provisionable Default = 0x0 + + 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + + */ + unsigned int led_2DriveThreeStateSelect : 1; /* 1E.C43A.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + */ + /*! \brief 1E.C43A.1 R/WPD LED #2 Active High Select + AQ_GlobalLedProvisioning_APPIA.u10.bits_10.led_2ActiveHighSelect + + Provisionable Default = 0x0 + + 1 = LED active high + 0 = LED active low + + + Notes: + The See LED #2 Manual Active Select bit must be 1 for this bit to take affect. */ + unsigned int led_2ActiveHighSelect : 1; /* 1E.C43A.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED active high + 0 = LED active low + */ + /*! \brief 1E.C43A.0 R/WPD LED #2 Manual Active Select + AQ_GlobalLedProvisioning_APPIA.u10.bits_10.led_2ManualActiveSelect + + Provisionable Default = 0x0 + + 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + + */ + unsigned int led_2ManualActiveSelect : 1; /* 1E.C43A.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + */ + } bits_10; + uint16_t word_10; + } u10; + /*! \brief Union for bit and word level access of word 11 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 13; + /*! \brief 1E.C43B.2 R/WPD LED #3 Drive Three State Select + AQ_GlobalLedProvisioning_APPIA.u11.bits_11.led_3DriveThreeStateSelect + + Provisionable Default = 0x0 + + 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + + */ + unsigned int led_3DriveThreeStateSelect : 1; /* 1E.C43B.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + */ + /*! \brief 1E.C43B.1 R/WPD LED #3 Active High Select + AQ_GlobalLedProvisioning_APPIA.u11.bits_11.led_3ActiveHighSelect + + Provisionable Default = 0x0 + + 1 = LED active high + 0 = LED active low + + + Notes: + The See LED #3 Manual Active Select bit must be 1 for this bit to take affect. */ + unsigned int led_3ActiveHighSelect : 1; /* 1E.C43B.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED active high + 0 = LED active low + */ + /*! \brief 1E.C43B.0 R/WPD LED #3 Manual Active Select + AQ_GlobalLedProvisioning_APPIA.u11.bits_11.led_3ManualActiveSelect + + Provisionable Default = 0x0 + + 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + + */ + unsigned int led_3ManualActiveSelect : 1; /* 1E.C43B.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + */ + } bits_11; + uint16_t word_11; + } u11; + /*! \brief Union for bit and word level access of word 12 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 13; + /*! \brief 1E.C43C.2 R/WPD LED #4 Drive Three State Select + AQ_GlobalLedProvisioning_APPIA.u12.bits_12.led_4DriveThreeStateSelect + + Provisionable Default = 0x0 + + 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + + */ + unsigned int led_4DriveThreeStateSelect : 1; /* 1E.C43C.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + */ + /*! \brief 1E.C43C.1 R/WPD LED #4 Active High Select + AQ_GlobalLedProvisioning_APPIA.u12.bits_12.led_4ActiveHighSelect + + Provisionable Default = 0x0 + + 1 = LED active high + 0 = LED active low + + + Notes: + The See LED #4 Manual Active Select bit must be 1 for this bit to take affect. */ + unsigned int led_4ActiveHighSelect : 1; /* 1E.C43C.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED active high + 0 = LED active low + */ + /*! \brief 1E.C43C.0 R/WPD LED #4 Manual Active Select + AQ_GlobalLedProvisioning_APPIA.u12.bits_12.led_4ManualActiveSelect + + Provisionable Default = 0x0 + + 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + + */ + unsigned int led_4ManualActiveSelect : 1; /* 1E.C43C.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + */ + } bits_12; + uint16_t word_12; + } u12; + /*! \brief Union for bit and word level access of word 13 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 13; + /*! \brief 1E.C43D.2 R/WPD LED #5 Drive Three State Select + AQ_GlobalLedProvisioning_APPIA.u13.bits_13.led_5DriveThreeStateSelect + + Provisionable Default = 0x0 + + 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + + */ + unsigned int led_5DriveThreeStateSelect : 1; /* 1E.C43D.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Drive LED tri-state when not active + 0 = Drive LED opposite of active level when not active + */ + /*! \brief 1E.C43D.1 R/WPD LED #5 Active High Select + AQ_GlobalLedProvisioning_APPIA.u13.bits_13.led_5ActiveHighSelect + + Provisionable Default = 0x0 + + 1 = LED active high + 0 = LED active low + + + Notes: + The See LED #5 Manual Active Select bit must be 1 for this bit to take affect. */ + unsigned int led_5ActiveHighSelect : 1; /* 1E.C43D.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED active high + 0 = LED active low + */ + /*! \brief 1E.C43D.0 R/WPD LED #5 Manual Active Select + AQ_GlobalLedProvisioning_APPIA.u13.bits_13.led_5ManualActiveSelect + + Provisionable Default = 0x0 + + 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + + */ + unsigned int led_5ManualActiveSelect : 1; /* 1E.C43D.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = Manual selection of LED active high or low + 0 = Determine the active high or low based on the external pull-up or pull-down + */ + } bits_13; + uint16_t word_13; + } u13; +} AQ_GlobalLedProvisioning_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global General Provisioning: 1E.C440 */ +/* Global General Provisioning: 1E.C440 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global General Provisioning */ + union + { + struct + { + unsigned int reserved0 : 7; + /*! \brief 1E.C440.8:4 R/WPD Gang Load MDIO Address [4:0] + AQ_GlobalGeneralProvisioning_APPIA.u0.bits_0.gangLoadMdioAddress + + Provisionable Default = 0x00 + + MDIO Address to be used during gang load operation + + + Notes: + Gang load operation is used to load data into multiple PHYs all connected to the same MDIO bus. The address for gang load operation is provided by these bits (8:4), and enabling is done by writing Bit 0. Disabling of gang load mode is done by writing the See MDIO Address Reset (1E.C441.2) bit. These will revert the PHY's MDIO address back to the address provided by the MDIO Address pins. During gang load operation, MDIO reads are disabled to prevent bus contention. */ + unsigned int gangLoadMdioAddress : 5; /* 1E.C440.8:4 R/WPD Provisionable Default = 0x00 */ + /* MDIO Address to be used during gang load operation + */ + unsigned int reserved1 : 3; + /*! \brief 1E.C440.0 RO Gang Load MDIO Write Only + AQ_GlobalGeneralProvisioning_APPIA.u0.bits_0.gangLoadMdioWriteOnly + + + + 1 = MDIO gang load enable + + + Notes: + This bit enables gang load operation with the address specified in Bits 8:4. */ + unsigned int gangLoadMdioWriteOnly : 1; /* 1E.C440.0 RO */ + /* 1 = MDIO gang load enable + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global General Provisioning */ + union + { + struct + { + unsigned int reserved0 : 1; + /*! \brief 1E.C441.E R/WPD MDIO Broadcast Mode Enable + AQ_GlobalGeneralProvisioning_APPIA.u1.bits_1.mdioBroadcastModeEnable + + Provisionable Default = 0x0 + + 1 = Enable broadcast on Address 0 + 0 = Disable broadcast on Address 0 + + + Notes: + When set, this bit enables gang-load operation on address zero, simultaneous with normal MDIO operation. Obviously, this requires that no PHY use address 0 as its normal operating address. As well, reads on MDIO Address 0 are disabled to prevent bus contention. */ + unsigned int mdioBroadcastModeEnable : 1; /* 1E.C441.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable broadcast on Address 0 + 0 = Disable broadcast on Address 0 + */ + /*! \brief 1E.C441.D R/WPD MDIO Read MSW First Enable + AQ_GlobalGeneralProvisioning_APPIA.u1.bits_1.mdioReadMSW_FirstEnable + + Provisionable Default = 0x0 + + 1 = MSW of counter must be read first + 0 = LSW of counter must be read first + + + Notes: + This bit configures whether the MSW or LSW must be read first for counters greater than 16 bits. */ + unsigned int mdioReadMSW_FirstEnable : 1; /* 1E.C441.D R/WPD Provisionable Default = 0x0 */ + /* 1 = MSW of counter must be read first + 0 = LSW of counter must be read first + */ + unsigned int reserved1 : 8; + /*! \brief 1E.C441.4 R/WPD MDIO Drive Configuration + AQ_GlobalGeneralProvisioning_APPIA.u1.bits_1.mdioDriveConfiguration + + Provisionable Default = 0x0 + + 0 = MDIO driver is in normal mode + 1 = MDIO driver is in open drain mode + + + Notes: + When the MDIO driver is in open drain mode during a read cycle, "0" data will be actively driven out of the MDIO, "1" data will set the MDIO driver in high impedance state and an external pullup will set the MDIO line to "1". The Turn-Around "0" will also be actively driven out of the MDIO, therefore in open drain mode, the Turn-Around is still "Z0". */ + unsigned int mdioDriveConfiguration : 1; /* 1E.C441.4 R/WPD Provisionable Default = 0x0 */ + /* 0 = MDIO driver is in normal mode + 1 = MDIO driver is in open drain mode + */ + /*! \brief 1E.C441.3 R/WPD MDIO Preamble Detection Disable + AQ_GlobalGeneralProvisioning_APPIA.u1.bits_1.mdioPreambleDetectionDisable + + Provisionable Default = 0x0 + + 1 = Suppress preamble detection on MDIO + 0 = Enable preamble detection on MDIO + + */ + unsigned int mdioPreambleDetectionDisable : 1; /* 1E.C441.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = Suppress preamble detection on MDIO + 0 = Enable preamble detection on MDIO + */ + /*! \brief 1E.C441.2 R/WSC MDIO Address Reset + AQ_GlobalGeneralProvisioning_APPIA.u1.bits_1.mdioAddressReset + + Default = 0x0 + + 1 = Load MDIO Address with the address on the MDIO address pins + + + Notes: + Used to reset the address after gang load and enable MDIO reads again. */ + unsigned int mdioAddressReset : 1; /* 1E.C441.2 R/WSC Default = 0x0 */ + /* 1 = Load MDIO Address with the address on the MDIO address pins + */ + unsigned int reserved2 : 2; + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global General Provisioning */ + union + { + struct + { + unsigned int reserved0 : 15; + /*! \brief 1E.C442.0 R/W Daisy Chain Reset + AQ_GlobalGeneralProvisioning_APPIA.u2.bits_2.daisyChainReset + + Default = 0x0 + + 1 = Reset the daisy chain + + + Notes: + Toggling this bit from 0 to 1 will reload the IRAM and DRAM and reset the uP. The uP will be in uP run stall during the reload process. After the reload process, uP run stall will be de-asserted adn the uP reset will be asserted. Note that before setting this bit, the See Soft Reset bit needs to be de-asserted. */ + unsigned int daisyChainReset : 1; /* 1E.C442.0 R/W Default = 0x0 */ + /* 1 = Reset the daisy chain + */ + } bits_2; + uint16_t word_2; + } u2; +} AQ_GlobalGeneralProvisioning_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global NVR Provisioning: 1E.C450 */ +/* Global NVR Provisioning: 1E.C450 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global NVR Provisioning */ + union + { + struct + { + unsigned int reserved0 : 5; + /*! \brief 1E.C450.A:8 R/WPD NVR Data Length [2:0] + AQ_GlobalNvrProvisioning_APPIA.u0.bits_0.nvrDataLength + + Provisionable Default = 0x4 + + NVR data length ranges from 0 bytes to 4 bytes + + + Notes: + This sets the length of the data burst used in read and write operations. + */ + unsigned int nvrDataLength : 3; /* 1E.C450.A:8 R/WPD Provisionable Default = 0x4 */ + /* NVR data length ranges from 0 bytes to 4 bytes + */ + unsigned int reserved1 : 1; + /*! \brief 1E.C450.6:4 R/WPD NVR Dummy Length [2:0] + AQ_GlobalNvrProvisioning_APPIA.u0.bits_0.nvrDummyLength + + Provisionable Default = 0x0 + + NVR dummy length ranges from 0 bytes to 4 bytes. + + + Notes: + This sets the length of the dummy field used in some maunfacturer's read status and write status operations. + */ + unsigned int nvrDummyLength : 3; /* 1E.C450.6:4 R/WPD Provisionable Default = 0x0 */ + /* NVR dummy length ranges from 0 bytes to 4 bytes. + */ + unsigned int reserved2 : 2; + /*! \brief 1E.C450.1:0 R/WPD NVR Address Length [1:0] + AQ_GlobalNvrProvisioning_APPIA.u0.bits_0.nvrAddressLength + + Provisionable Default = 0x2 + + NVR address length ranges from 0 bytes up to 3 bytes. + + + Notes: + This sets the length of the address field used in read and write operations. Use of this field is enabled via Bit 8 of See Global NVR Provisioning 2: Address 1E.C451 . + */ + unsigned int nvrAddressLength : 2; /* 1E.C450.1:0 R/WPD Provisionable Default = 0x2 */ + /* NVR address length ranges from 0 bytes up to 3 bytes. + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global NVR Provisioning */ + union + { + struct + { + unsigned int reserved0 : 7; + /*! \brief 1E.C451.8 R/WPD NVR Address Length Override + AQ_GlobalNvrProvisioning_APPIA.u1.bits_1.nvrAddressLengthOverride + + Provisionable Default = 0x0 + + 0 = NVR address length is based on the "NVR_SIZE" pin. + 1 = NVR address length is based on the See NVR Address Length [1:0] register. + + + Notes: + When the this bit = 0 and NVR_SIZE pin = 0, the NVR address length is 2 bytes. When this bit = 0 and the NVR_SIZE pin = 1, the NVR address length is 3 bytes. When this bit = 1 the NVR address length is from the See NVR Address Length [1:0] */ + unsigned int nvrAddressLengthOverride : 1; /* 1E.C451.8 R/WPD Provisionable Default = 0x0 */ + /* 0 = NVR address length is based on the "NVR_SIZE" pin. + 1 = NVR address length is based on the See NVR Address Length [1:0] register. + */ + /*! \brief 1E.C451.7:0 R/WPD NVR Clock Divide [7:0] + AQ_GlobalNvrProvisioning_APPIA.u1.bits_1.nvrClockDivide + + Provisionable Default = 0xA0 + + NVR clock divide. Clock frequency is divided by the NVR clock divide + 1 + + */ + unsigned int nvrClockDivide : 8; /* 1E.C451.7:0 R/WPD Provisionable Default = 0xA0 */ + /* NVR clock divide. Clock frequency is divided by the NVR clock divide + 1 + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global NVR Provisioning */ + union + { + struct + { + unsigned int reserved0 : 14; + /*! \brief 1E.C452.1 R/W NVR Daisy Chain Clock Divide Override + AQ_GlobalNvrProvisioning_APPIA.u2.bits_2.nvrDaisyChainClockDivideOverride + + Default = 0x0 + + 1 = Override NVR clock divide when in daisy chain master mode + + + + Notes: + When in daisy chain master mode, the clock divide configuration is received from the flash. This bit will override the clock divide configuration from the flash with the See NVR Clock Divide [7:0] . */ + unsigned int nvrDaisyChainClockDivideOverride : 1; /* 1E.C452.1 R/W Default = 0x0 */ + /* 1 = Override NVR clock divide when in daisy chain master mode + + */ + /*! \brief 1E.C452.0 R/W NVR Daisy Chain Disable + AQ_GlobalNvrProvisioning_APPIA.u2.bits_2.nvrDaisyChainDisable + + Default = 0x0 + + 1 = Disable the Daisy Chain + + + Notes: + When in daisy chain master mode, the daisy chain and MDIO can both access the SPI. Setting this bit to 1 will disable the dasiy chain from accessing the SPI and force it into a reset state. */ + unsigned int nvrDaisyChainDisable : 1; /* 1E.C452.0 R/W Default = 0x0 */ + /* 1 = Disable the Daisy Chain + */ + } bits_2; + uint16_t word_2; + } u2; +} AQ_GlobalNvrProvisioning_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Reserved Provisioning: 1E.C470 */ +/* Global Reserved Provisioning: 1E.C470 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Reserved Provisioning */ + union + { + struct + { + /*! \brief 1E.C470.F R/WPD Diagnostics Select + AQ_GlobalReservedProvisioning_APPIA.u0.bits_0.diagnosticsSelect + + Provisionable Default = 0x0 + + 1 = Provide Extended MDI Diagnostics Information. + 0 = Provide normal cable diagnostics + + + Notes: + These bits select what sort of cable diagnostics to perform. For regular cable diagnostics, Bit F is set to zero, and the diagnostics are triggered by setting Bit 4. For extended diagnostics, Bit F is set to 1, and the desired extended diagnostics are selected by Bits E:D. The routine is then triggered by setting Bit 4. Each of the extended diagnostic routines present data for all for MDI pairs (A, B, C, D) consecutively, and after the data for each channel is gathered Bits F:D are reset. To get the data for the next pair, Bits F:D must be set back to the desired value (which must be the same as the initial channel). This continues until the data for all channels has been gathered. The address in memory where the data is stored is given in 1E.C802 and 1E.C804. + + For the case of PSD, the structure is as follows: + Int32 info + Int16 data[Len] + Info = Len << 16 | TxEnable << 8 | Pair (0 = A, etc.) + + For TDR: + Int32 info + Int16 tdr_A[Len] + Int16 tdr_B[Len] + Int16 tdr_C[Len] + Int16 tdr_D[Len] + + Info = Len << 16 | Channel + + TDR data is from the current pair to all other pairs. + + At the end of retrieving extended MDI diag data, the part will be reset. Conversly the only way to exit this routine once it starts is to issue a PMA reset. */ + unsigned int diagnosticsSelect : 1; /* 1E.C470.F R/WPD Provisionable Default = 0x0 */ + /* 1 = Provide Extended MDI Diagnostics Information. + 0 = Provide normal cable diagnostics + */ + /*! \brief 1E.C470.E:D R/WPD Extended MDI Diagnostics Select [1:0] + AQ_GlobalReservedProvisioning_APPIA.u0.bits_0.extendedMdiDiagnosticsSelect + + Provisionable Default = 0x0 + + 0x0 = TDR Data + 0x1 = RFI Channel PSD + 0x2 = Noise PSD while the local Tx is Off + 0x3 = Noise PSD while the local Tx is On + + + Notes: + These bits select what sort of cable diagnostics to perform. For regular cable diagnostics, Bit F is set to zero, and the diagnostics are triggered by setting Bit 4. For extended diagnostics, Bit F is set to 1, and the desired extended diagnostics are selected by Bits E:D. The routine is then triggered by setting Bit 4. Each of the extended diagnostic routines present data for all for MDI pairs (A, B, C, D) consecutively, and after the data for each channel is gathered Bits F:D are reset. To get the data for the next pair, Bits F:D must be set back to the desired value (which must be the same as the initial channel). This continues until the data for all channels has been gathered. The address in memory where the data is stored is given in 1E.C802 and 1E.C804. + + For the case of PSD, the structure is as follows: + Int32 info + Int16 data[Len] + Info = Len << 16 | TxEnable << 8 | Pair (0 = A, etc.) + + For TDR: + Int32 info + Int16 tdr_A[Len] + Int16 tdr_B[Len] + Int16 tdr_C[Len] + Int16 tdr_D[Len] + + Info = Len << 16 | Channel + + TDR data is from the current pair to all other pairs. + + At the end of retrieving extended MDI diag data, the part will be reset. Conversly the only way to exit this routine once it starts is to issue a PMA reset. */ + unsigned int extendedMdiDiagnosticsSelect : 2; /* 1E.C470.E:D R/WPD Provisionable Default = 0x0 */ + /* 0x0 = TDR Data + 0x1 = RFI Channel PSD + 0x2 = Noise PSD while the local Tx is Off + 0x3 = Noise PSD while the local Tx is On + */ + unsigned int reserved0 : 5; + unsigned int reserved1 : 2; + /*! \brief 1E.C470.5 R/WSC Initiate Component Diagnostics + AQ_GlobalReservedProvisioning_APPIA.u0.bits_0.initiateComponentDiagnostics + + Default = 0x0 + + 1 = Perform component diagnostics + + + Notes: + Perform component diagnostics regardless of link state. If link is up, setting this bit will cause the link to drop while diagnostics are performed. This bit is self-clearing upon completion of the component diagnostics. Further MDIO writes should be avoided until this bit has self-cleared, indicating completion of the diagnostic routine. */ + unsigned int initiateComponentDiagnostics : 1; /* 1E.C470.5 R/WSC Default = 0x0 */ + /* 1 = Perform component diagnostics + */ + /*! \brief 1E.C470.4 R/WSC Initiate Cable Diagnostics + AQ_GlobalReservedProvisioning_APPIA.u0.bits_0.initiateCableDiagnostics + + Default = 0x0 + + 1 = Perform cable diagnostics + + + Notes: + Perform cable diagnostics regardless of link state. If link is up, setting this bit will cause the link to drop while diagnostics are performed. This bit is self-clearing upon completion of the cable diagnostics. Further MDIO writes should be avoided until this bit has self-cleared, indicating completion of the diagnostic routine. */ + unsigned int initiateCableDiagnostics : 1; /* 1E.C470.4 R/WSC Default = 0x0 */ + /* 1 = Perform cable diagnostics + */ + unsigned int reserved2 : 4; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Reserved Provisioning */ + union + { + struct + { + /*! \brief 1E.C471.F:7 R/WPD Reserved Provisioning 2 [8:0] + AQ_GlobalReservedProvisioning_APPIA.u1.bits_1.reservedProvisioning_2 + + Provisionable Default = 0x000 + + Reserved for future use + + */ + unsigned int reservedProvisioning_2 : 9; /* 1E.C471.F:7 R/WPD Provisionable Default = 0x000 */ + /* Reserved for future use + */ + /*! \brief 1E.C471.6 R/WuP Enable Daisy-Chain Hop-Count Override + AQ_GlobalReservedProvisioning_APPIA.u1.bits_1.enableDaisy_chainHop_countOverride + + Default = 0x0 + + 1 = Hop-count is set by Bits 5:0 + 0 = Hop-count is determined by the daisy-chain + + + Notes: + Daisy-Chain Hop-Count Override should be used during MDIO boot-load operation, as the daisy-chain hop-count does not function when the daisy-chain is disabled (1E.C452.0). Setting this bit tells the processor where in the diasy-chain it is, so that the provisioning operation will function correctly. */ + unsigned int enableDaisy_chainHop_countOverride : 1; /* 1E.C471.6 R/WuP Default = 0x0 */ + /* 1 = Hop-count is set by Bits 5:0 + 0 = Hop-count is determined by the daisy-chain + */ + /*! \brief 1E.C471.5:0 R/WuP Daisy-Chain Hop-Count Override Value [5:0] + AQ_GlobalReservedProvisioning_APPIA.u1.bits_1.daisy_chainHop_countOverrideValue + + Default = 0x00 + + The value to use for the PHY's daisy-chain hop-count. Valid values are from 0 -> 47 + + + Notes: + Daisy-Chain Hop-Count Override should be used during MDIO boot-load operation, as the daisy-chain hop-count does not function when the daisy-chain is disabled (1E.C452.0). Setting this bit tells the processor where in the diasy-chain it is, so that the provisioning operation will function correctly. */ + unsigned int daisy_chainHop_countOverrideValue : 6; /* 1E.C471.5:0 R/WuP Default = 0x00 */ + /* The value to use for the PHY's daisy-chain hop-count. Valid values are from 0 -> 47 + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Reserved Provisioning */ + union + { + struct + { + /*! \brief 1E.C472.F R/WPD Enable LVDD Power Supply Tuning + AQ_GlobalReservedProvisioning_APPIA.u2.bits_2.enableLvddPowerSupplyTuning + + Provisionable Default = 0x0 + + 1 = Enable external LVDD power supply tuning + 0 = Disable external LVDD power supply tuning is disabled + + + Notes: + + + + These bits control whether the PHY attempts to tune the external VDD and LVDD power supplies via the PMBus. These bits are only operational if the external supplies are present (see Bits 7:6) */ + unsigned int enableLvddPowerSupplyTuning : 1; /* 1E.C472.F R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable external LVDD power supply tuning + 0 = Disable external LVDD power supply tuning is disabled + */ + /*! \brief 1E.C472.E R/WPD Enable VDD Power Supply Tuning + AQ_GlobalReservedProvisioning_APPIA.u2.bits_2.enableVddPowerSupplyTuning + + Provisionable Default = 0x0 + + 1 = Enable external VDD power supply tuning + 0 = Disable external VDD power supply tuning is disabled + + + Notes: + + + + These bits control whether the PHY attempts to tune the external VDD and LVDD power supplies via the PMBus. These bits are only operational if the external supplies are present (see Bits 7:6) */ + unsigned int enableVddPowerSupplyTuning : 1; /* 1E.C472.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable external VDD power supply tuning + 0 = Disable external VDD power supply tuning is disabled + */ + unsigned int reserved0 : 6; + /*! \brief 1E.C472.7 R/WPD Tunable External LVDD Power Supply Present + AQ_GlobalReservedProvisioning_APPIA.u2.bits_2.tunableExternalLvddPowerSupplyPresent + + Provisionable Default = 0x0 + + 1 = Tunable external LVDD power supply present + 0 = No tunable external LVDD power supply present + + + Notes: + + + + These bits must be set if tuning of external power supplies is desired (see Bits 7:6) */ + unsigned int tunableExternalLvddPowerSupplyPresent : 1; /* 1E.C472.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = Tunable external LVDD power supply present + 0 = No tunable external LVDD power supply present + */ + /*! \brief 1E.C472.6 R/WPD Tunable External VDD Power Supply Present + AQ_GlobalReservedProvisioning_APPIA.u2.bits_2.tunableExternalVddPowerSupplyPresent + + Provisionable Default = 0x0 + + 1 = Tunable external VDD power supply present + 0 = No tunable external VDD power supply present + + + Notes: + + + + These bits must be set if tuning of external power supplies is desired (see Bits 7:6) */ + unsigned int tunableExternalVddPowerSupplyPresent : 1; /* 1E.C472.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = Tunable external VDD power supply present + 0 = No tunable external VDD power supply present + */ + unsigned int reserved1 : 4; + /*! \brief 1E.C472.1 R/WPDuP Enable XENPAK Register Space + AQ_GlobalReservedProvisioning_APPIA.u2.bits_2.enableXenpakRegisterSpace + + Provisionable Default = 0x0 + + 1 = XENPAK register space enabled + 0 = XENPAK register space disabled + + */ + unsigned int enableXenpakRegisterSpace : 1; /* 1E.C472.1 R/WPDuP Provisionable Default = 0x0 */ + /* 1 = XENPAK register space enabled + 0 = XENPAK register space disabled + */ + /*! \brief 1E.C472.0 R/WPDuP Enable 5th Channel RFI Cancellation + AQ_GlobalReservedProvisioning_APPIA.u2.bits_2.enable_5thChannelRfiCancellation + + Provisionable Default = 0x0 + + 1 = 5th channel and RFI cancellers operation enabled + 0 = 5th channel AFE is powered down, 5th channel digital is clock gated, RFI cancellers are disabled + + + Notes: + Note: The value of this bit at the time of Autonegotiation sets the local PHY behavior until the next time Autonegotiation occurs. */ + unsigned int enable_5thChannelRfiCancellation : 1; /* 1E.C472.0 R/WPDuP Provisionable Default = 0x0 */ + /* 1 = 5th channel and RFI cancellers operation enabled + 0 = 5th channel AFE is powered down, 5th channel digital is clock gated, RFI cancellers are disabled + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global Reserved Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global Reserved Provisioning */ + union + { + struct + { + unsigned int reserved0 : 8; + /*! \brief 1E.C474.7:0 R/WPD Training SNR [7:0] + AQ_GlobalReservedProvisioning_APPIA.u4.bits_4.trainingSNR + + Provisionable Default = 0x00 + + SNR during 10G training on the worst channel. SNR is in steps of 0.1dB + + + Notes: + The SNR margin that is enjoyed by the worst channel, over and above the minimum SNR required to operate at a BER of 10-12. It is reported with 0.1 dB of resolution to an accuracy of 0.5 dB within the range of -12.7 dB to 12.7 dB. The number is in offset binary, with 0.0 dB represented by 0x8000. + */ + unsigned int trainingSNR : 8; /* 1E.C474.7:0 R/WPD Provisionable Default = 0x00 */ + /* SNR during 10G training on the worst channel. SNR is in steps of 0.1dB + */ + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of Global Reserved Provisioning */ + union + { + struct + { + unsigned int reserved0 : 2; + /*! \brief 1E.C475.D R/WPD Smart Power-Down Status + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.smartPower_downStatus + + Provisionable Default = 0x0 + + 1 = Smart Power-Down Active + 0 = Smart Power-Down Inactive + + */ + unsigned int smartPower_downStatus : 1; /* 1E.C475.D R/WPD Provisionable Default = 0x0 */ + /* 1 = Smart Power-Down Active + 0 = Smart Power-Down Inactive + */ + /*! \brief 1E.C475.C R/WPD Reserved Provisioning 6 + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.reservedProvisioning_6 + + Provisionable Default = 0x0 + + Reserved for future use + + */ + unsigned int reservedProvisioning_6 : 1; /* 1E.C475.C R/WPD Provisionable Default = 0x0 */ + /* Reserved for future use + */ + /*! \brief 1E.C475.B R/WPD CFR LP Disable Timer + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.cfrLpDisableTimer + + Provisionable Default = 0x0 + + 1 = Link partner requires cfr_disable timer + 0 = Link partner does not require cfr_disable timer + + */ + unsigned int cfrLpDisableTimer : 1; /* 1E.C475.B R/WPD Provisionable Default = 0x0 */ + /* 1 = Link partner requires cfr_disable timer + 0 = Link partner does not require cfr_disable timer + */ + /*! \brief 1E.C475.A R/WPD CFR LP Extended Maxwait + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.cfrLpExtendedMaxwait + + Provisionable Default = 0x0 + + 1 = Link partner requires extended maxwait + 0 = Link partner does not require extended maxwait + + */ + unsigned int cfrLpExtendedMaxwait : 1; /* 1E.C475.A R/WPD Provisionable Default = 0x0 */ + /* 1 = Link partner requires extended maxwait + 0 = Link partner does not require extended maxwait + */ + /*! \brief 1E.C475.9 R/WPD CFR LP THP + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.cfrLpTHP + + Provisionable Default = 0x0 + + 1 = Link partner requires local PHY to enable THP + 0 = Link partner does not require local PHY to enable THP + + */ + unsigned int cfrLpTHP : 1; /* 1E.C475.9 R/WPD Provisionable Default = 0x0 */ + /* 1 = Link partner requires local PHY to enable THP + 0 = Link partner does not require local PHY to enable THP + */ + /*! \brief 1E.C475.8 R/WPD CFR LP Support + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.cfrLpSupport + + Provisionable Default = 0x0 + + 1 = Link partner supports Cisco Fast Retrain + 0 = Link partner does support Cisco Fast Retrain + + */ + unsigned int cfrLpSupport : 1; /* 1E.C475.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = Link partner supports Cisco Fast Retrain + 0 = Link partner does support Cisco Fast Retrain + */ + /*! \brief 1E.C475.7 R/WPD CFR Disable Timer + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.cfrDisableTimer + + Provisionable Default = 0x0 + + 1 = Local PHY requires cfr_disable timer + 0 = Local PHY does not require cfr_disable timer + + */ + unsigned int cfrDisableTimer : 1; /* 1E.C475.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = Local PHY requires cfr_disable timer + 0 = Local PHY does not require cfr_disable timer + */ + /*! \brief 1E.C475.6 R/WPD CFR Extended Maxwait + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.cfrExtendedMaxwait + + Provisionable Default = 0x0 + + 1 = Local PHY requires extended maxwait + 0 = Local PHY does not require extended maxwait + + */ + unsigned int cfrExtendedMaxwait : 1; /* 1E.C475.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = Local PHY requires extended maxwait + 0 = Local PHY does not require extended maxwait + */ + /*! \brief 1E.C475.5 R/WPD CFR THP + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.cfrTHP + + Provisionable Default = 0x0 + + 1 = Local PHY requires local PHY to enable THP + 0 = Local PHY does not require local PHY to enable THP + + */ + unsigned int cfrTHP : 1; /* 1E.C475.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = Local PHY requires local PHY to enable THP + 0 = Local PHY does not require local PHY to enable THP + */ + /*! \brief 1E.C475.4 R/WPD CFR Support + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.cfrSupport + + Provisionable Default = 0x0 + + 1 = Local PHY supports Cisco Fast Retrain + 0 = Local PHY does support Cisco Fast Retrain + + */ + unsigned int cfrSupport : 1; /* 1E.C475.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = Local PHY supports Cisco Fast Retrain + 0 = Local PHY does support Cisco Fast Retrain + */ + /*! \brief 1E.C475.3 R/WPD Deadlock Avoidance Enable + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.deadlockAvoidanceEnable + + Provisionable Default = 0x0 + + 1 = SPD with deadlock avoidance: PHY transmits autonegotiation pulses (FLPs) at a slower rate (~ 1 FLP/ 100ms) than specified by autonegotiation standard (~1 FLP / 8.25ms). Receiver is active and able to detect the pulses. + 0 = SPD without deadlock avoidance: PHY transmitter is shut down, no autonegotiation pulses are sent on the line but the receiver is active and able to detect the pulses + + */ + unsigned int deadlockAvoidanceEnable : 1; /* 1E.C475.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = SPD with deadlock avoidance: PHY transmits autonegotiation pulses (FLPs) at a slower rate (~ 1 FLP/ 100ms) than specified by autonegotiation standard (~1 FLP / 8.25ms). Receiver is active and able to detect the pulses. + 0 = SPD without deadlock avoidance: PHY transmitter is shut down, no autonegotiation pulses are sent on the line but the receiver is active and able to detect the pulses + */ + /*! \brief 1E.C475.2 R/WPD Smart Power-Down Enable + AQ_GlobalReservedProvisioning_APPIA.u5.bits_5.smartPower_downEnable + + Provisionable Default = 0x0 + + 1 = Enable smart power down mode + 0 = Smart power-down mode disabled + + + Notes: + Smart power down (SPD) is the lowest power mode at which PHY is able to autonegotiate. SPD can be enabled with bit 1E.C475.2 */ + unsigned int smartPower_downEnable : 1; /* 1E.C475.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable smart power down mode + 0 = Smart power-down mode disabled + */ + unsigned int reserved1 : 2; + } bits_5; + uint16_t word_5; + } u5; +} AQ_GlobalReservedProvisioning_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Cable Diagnostic Status: 1E.C800 */ +/* Global Cable Diagnostic Status: 1E.C800 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Cable Diagnostic Status */ + union + { + struct + { + unsigned int reserved0 : 1; + /*! \brief 1E.C800.E:C RO Pair A Status [2:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u0.bits_0.pairAStatus + + + + (after running cable diags) + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair D + 010= Connected to Pair C + 001= Connected to Pair B + 000= OK + + OR: + + (after running component diags) + 100 = TX pin open + 011= TX bias open + 010= Capacitor short + 001= Inductor open + 000= OK + + Notes: + This bitfield reports the result, for pair A, of running either cable diagnostics or component diagnostics. */ + unsigned int pairAStatus : 3; /* 1E.C800.E:C RO */ + /* (after running cable diags) + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair D + 010= Connected to Pair C + 001= Connected to Pair B + 000= OK + + OR: + + (after running component diags) + 100 = TX pin open + 011= TX bias open + 010= Capacitor short + 001= Inductor open + 000= OK */ + unsigned int reserved1 : 1; + /*! \brief 1E.C800.A:8 RO Pair B Status [2:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u0.bits_0.pairBStatus + + + + (after running cable diags) + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair A + 010= Connected to Pair D + 001= Connected to Pair C + 000= OK + + OR: + + (after running component diags) + 100 = TX pin open + 011= TX bias open + 010= Capacitor short + 001= Inductor open + 000= OK + + Notes: + This bitfield reports the result, for pair B, of running either cable diagnostics or component diagnostics. */ + unsigned int pairBStatus : 3; /* 1E.C800.A:8 RO */ + /* (after running cable diags) + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair A + 010= Connected to Pair D + 001= Connected to Pair C + 000= OK + + OR: + + (after running component diags) + 100 = TX pin open + 011= TX bias open + 010= Capacitor short + 001= Inductor open + 000= OK */ + unsigned int reserved2 : 1; + /*! \brief 1E.C800.6:4 RO Pair C Status [2:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u0.bits_0.pairCStatus + + + + (after running cable diags) + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair B + 010= Connected to Pair A + 001= Connected to Pair D + 000= OK + + OR: + + (after running component diags) + 100 = TX pin open + 011= TX bias open + 010= Capacitor short + 001= Inductor open + 000= OK + + Notes: + This bitfield reports the result, for pair C, of running either cable diagnostics or component diagnostics. */ + unsigned int pairCStatus : 3; /* 1E.C800.6:4 RO */ + /* (after running cable diags) + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair B + 010= Connected to Pair A + 001= Connected to Pair D + 000= OK + + OR: + + (after running component diags) + 100 = TX pin open + 011= TX bias open + 010= Capacitor short + 001= Inductor open + 000= OK */ + unsigned int reserved3 : 1; + /*! \brief 1E.C800.2:0 RO Pair D Status [2:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u0.bits_0.pairDStatus + + + + (after running cable diags) + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair C + 010= Connected to Pair B + 001= Connected to Pair A + 000= OK + + OR: + + (after running component diags) + 100 = TX pin open + 011= TX bias open + 010= Capacitor short + 001= Inductor open + 000= OK + + Notes: + This bitfield reports the result, for pair D, of running either cable diagnostics or component diagnostics. */ + unsigned int pairDStatus : 3; /* 1E.C800.2:0 RO */ + /* (after running cable diags) + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair C + 010= Connected to Pair B + 001= Connected to Pair A + 000= OK + + OR: + + (after running component diags) + 100 = TX pin open + 011= TX bias open + 010= Capacitor short + 001= Inductor open + 000= OK */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C801.F:8 RO Pair A Reflection #1 [7:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u1.bits_1.pairAReflection_1 + + + + The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair A + + Notes: + The distance to this reflection is given in See Global Reserved Status 1: Address 1E.C870 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairAReflection_1 : 8; /* 1E.C801.F:8 RO */ + /* The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair A */ + /*! \brief 1E.C801.7:0 RO Pair A Reflection #2 [7:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u1.bits_1.pairAReflection_2 + + + + The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair A + + Notes: + The distance to this reflection is given in See Global Reserved Status 1: Address 1E.C870 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairAReflection_2 : 8; /* 1E.C801.7:0 RO */ + /* The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair A */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C802.F:0 RO Impulse Response MSW [F:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u2.bits_2.impulseResponseMSW + + + + The MSW of the memory location that contains the start of the impulse response data for the Extended Diagnostic type in 1E.C470.E:D + + + Notes: + See 1E.C470 for more information */ + unsigned int impulseResponseMSW : 16; /* 1E.C802.F:0 RO */ + /* The MSW of the memory location that contains the start of the impulse response data for the Extended Diagnostic type in 1E.C470.E:D + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C803.F:8 RO Pair B Reflection #1 [7:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u3.bits_3.pairBReflection_1 + + + + The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair B + + Notes: + The distance to this reflection is given in See Global Reserved Status 2: Address 1E.C871 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairBReflection_1 : 8; /* 1E.C803.F:8 RO */ + /* The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair B */ + /*! \brief 1E.C803.7:0 RO Pair B Reflection #2 [7:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u3.bits_3.pairBReflection_2 + + + + The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair B + + Notes: + The distance to this reflection is given in See Global Reserved Status 2: Address 1E.C871 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairBReflection_2 : 8; /* 1E.C803.7:0 RO */ + /* The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair B */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C804.F:0 RO Impulse Response LSW [F:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u4.bits_4.impulseResponseLSW + + + + The LSW of the memory location that contains the start of the impulse response data for the Extended Diagnostic type specified in 1E.C470.E:D + + + Notes: + See 1E.C470 for more information */ + unsigned int impulseResponseLSW : 16; /* 1E.C804.F:0 RO */ + /* The LSW of the memory location that contains the start of the impulse response data for the Extended Diagnostic type specified in 1E.C470.E:D + */ + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C805.F:8 RO Pair C Reflection #1 [7:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u5.bits_5.pairCReflection_1 + + + + The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair C + + Notes: + The distance to this reflection is given in See Global Reserved Status 3: Address 1E.C872 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairCReflection_1 : 8; /* 1E.C805.F:8 RO */ + /* The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair C */ + /*! \brief 1E.C805.7:0 RO Pair C Reflection #2 [7:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u5.bits_5.pairCReflection_2 + + + + The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair C + + Notes: + The distance to this reflection is given in See Global Reserved Status 3: Address 1E.C872 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairCReflection_2 : 8; /* 1E.C805.7:0 RO */ + /* The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair C */ + } bits_5; + uint16_t word_5; + } u5; + /*! \brief Union for bit and word level access of word 6 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C806.F:0 RO Reserved 1 [F:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u6.bits_6.reserved_1 + + + + Reserved for future use + + */ + unsigned int reserved_1 : 16; /* 1E.C806.F:0 RO */ + /* Reserved for future use + */ + } bits_6; + uint16_t word_6; + } u6; + /*! \brief Union for bit and word level access of word 7 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C807.F:8 RO Pair D Reflection #1 [7:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u7.bits_7.pairDReflection_1 + + + + The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair D + + Notes: + The distance to this reflection is given in See Global Reserved Status 4: Address 1E.C873 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairDReflection_1 : 8; /* 1E.C807.F:8 RO */ + /* The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair D */ + /*! \brief 1E.C807.7:0 RO Pair D Reflection #2 [7:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u7.bits_7.pairDReflection_2 + + + + The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair D + + Notes: + The distance to this reflection is given in See Global Reserved Status 4: Address 1E.C873 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairDReflection_2 : 8; /* 1E.C807.7:0 RO */ + /* The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair D */ + } bits_7; + uint16_t word_7; + } u7; + /*! \brief Union for bit and word level access of word 8 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C808.F:0 RO Reserved 2[F:0] + AQ_GlobalCableDiagnosticStatus_APPIA.u8.bits_8.reserved_2 + + + + Reserved for future use + + */ + unsigned int reserved_2 : 16; /* 1E.C808.F:0 RO */ + /* Reserved for future use + */ + } bits_8; + uint16_t word_8; + } u8; +} AQ_GlobalCableDiagnosticStatus_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Thermal Status: 1E.C820 */ +/* Global Thermal Status: 1E.C820 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Thermal Status */ + union + { + struct + { + /*! \brief 1E.C820.F:0 RO Temperature [F:0] + AQ_GlobalThermalStatus_APPIA.u0.bits_0.temperature + + + + [F:0] of temperature + + + Notes: + 2's complement value with the LSB representing 1/256 of a degree Celsius. This corresponds to -40 degreesC = 0xD800. Default is 70 degreesC. This is a mirror of the XENPAK register 1.A060 - 1.A061. The mirror is performed in H/W. */ + unsigned int temperature : 16; /* 1E.C820.F:0 RO */ + /* [F:0] of temperature + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Thermal Status */ + union + { + struct + { + unsigned int reserved0 : 15; + /*! \brief 1E.C821.0 RO Temperature Ready + AQ_GlobalThermalStatus_APPIA.u1.bits_1.temperatureReady + + + + 1 = Temperature measurement is valid + + + Notes: + This is a mirror of the XENPAK register 1.A06E. */ + unsigned int temperatureReady : 1; /* 1E.C821.0 RO */ + /* 1 = Temperature measurement is valid + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalThermalStatus_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global General Status: 1E.C830 */ +/* Global General Status: 1E.C830 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global General Status */ + union + { + struct + { + unsigned int reserved0 : 1; + /*! \brief 1E.C830.E RO High Temperature Failure State + AQ_GlobalGeneralStatus_APPIA.u0.bits_0.highTemperatureFailureState + + + + 1 = High temperature failure threshold has been exceeded + + Notes: + In XENPAK mode, F/W will copy this register to the 1.A070.7 register. + + */ + unsigned int highTemperatureFailureState : 1; /* 1E.C830.E RO */ + /* 1 = High temperature failure threshold has been exceeded */ + /*! \brief 1E.C830.D RO Low Temperature Failure State + AQ_GlobalGeneralStatus_APPIA.u0.bits_0.lowTemperatureFailureState + + + + 1 = Low temperature failure threshold has been exceeded + + Notes: + In XENPAK mode, F/W will copy this register to the 1.A070.6 register. + + */ + unsigned int lowTemperatureFailureState : 1; /* 1E.C830.D RO */ + /* 1 = Low temperature failure threshold has been exceeded */ + /*! \brief 1E.C830.C RO High Temperature Warning State + AQ_GlobalGeneralStatus_APPIA.u0.bits_0.highTemperatureWarningState + + + + 1 = High temperature warning threshold has been exceeded + + Notes: + In XENPAK mode, F/W will copy this register to the 1.A074.7 register. + + */ + unsigned int highTemperatureWarningState : 1; /* 1E.C830.C RO */ + /* 1 = High temperature warning threshold has been exceeded */ + /*! \brief 1E.C830.B RO Low Temperature Warning State + AQ_GlobalGeneralStatus_APPIA.u0.bits_0.lowTemperatureWarningState + + + + 1 = Low temperature warning threshold has been exceeded + + Notes: + In XENPAK mode, F/W will copy this register to the 1.A074.6 register. + + */ + unsigned int lowTemperatureWarningState : 1; /* 1E.C830.B RO */ + /* 1 = Low temperature warning threshold has been exceeded */ + unsigned int reserved1 : 11; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global General Status */ + union + { + struct + { + /*! \brief 1E.C831.F RO Processor Intensive MDIO Operation In- Progress + AQ_GlobalGeneralStatus_APPIA.u1.bits_1.processorIntensiveMdioOperationIn_Progress + + + + 1 = PHY microprocessor is busy with a processor-intensive MDIO operation + 0 = Processor-intensive MDIO operation completed + + + Notes: + This bit should may be used with certain processor-intensive MDIO commands (such as Loopbacks, Test Modes, Low power modes, Tx-Disable, Restart autoneg, Cable Diagnostics, etc.) that take longer than an MDIO cycle to complete. Upon receiving an MDIO command that involves the PHY's microprocessor, this bit is set, and when the command is completed, this bit is cleared. + + NOTE!!! This bit should be checked only after 1 ms of issuing a processor-intensive MDIO operation. + + The list of operations that set this bit are as follows: + + 1.0.0, PMA Loopback + 1.0.B, Low power mode + 1.9.4:0, Tx Disable + 1.84, 10G Test modes + 1.8000.5, XENPAK Control + 1.9000, XENPAK Rx Fault Enable + 1.9002, XENPAK Alarm Enable + 1.E400.F, External loopback + 3.0.B, Low power mode + 3.0.E, System PCS loopback + 3.C471.5, PRBS Test + 3.C471.6, PRBS Test + 3.E471.5, PRBS Test + 3.E471.6, PRBS Test + 4.0.B, Low power mode + 4.0.E, PHY-XS network loopback + 4.C440, Output clock control, Load SERDES parameters + 4.F802.E, System loopback + 4.C444.F:B, Loopback Control + 4.C444.4:2, Packet generation + 4.C445.C, SERDES calibration + 7.0.9, Restart autonegotiation + 1D.C280, 1G/100M Network loopback + 1D.C500, 1G System loopback + 1D.C501, 1G / 100M Test modes */ + unsigned int processorIntensiveMdioOperationIn_Progress : 1; /* 1E.C831.F RO */ + /* 1 = PHY microprocessor is busy with a processor-intensive MDIO operation + 0 = Processor-intensive MDIO operation completed + */ + unsigned int reserved0 : 15; + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalGeneralStatus_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Pin Status: 1E.C840 */ +/* Global Pin Status: 1E.C840 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Pin Status */ + union + { + struct + { + unsigned int reserved0 : 1; + /*! \brief 1E.C840.E:D RO MDIO Boot Load [1:0] + AQ_GlobalPinStatus_APPIA.u0.bits_0.mdioBootLoad + + + + Value of MDIO Boot Load pins + + 0x3 = PHY #0 Slave Daisy Chain Boot + 0x2 = PHY #0 Master Daisy Chain Boot from Flash + 0x1 = MDIO Boot Load + 0x0 = Boot from Flash (PHY #0 only) + + + Notes: + NOTES: + + PHY #0 is the primary PHY, and PHY #1 is the secondary PHY + + PHY #1 is always in Slave Daisy Chain Boot from Flash when set to 0x2 or 0x3. */ + unsigned int mdioBootLoad : 2; /* 1E.C840.E:D RO */ + /* Value of MDIO Boot Load pins + + 0x3 = PHY #0 Slave Daisy Chain Boot + 0x2 = PHY #0 Master Daisy Chain Boot from Flash + 0x1 = MDIO Boot Load + 0x0 = Boot from Flash (PHY #0 only) + */ + unsigned int reserved1 : 3; + /*! \brief 1E.C840.9 RO Package Connectivity + AQ_GlobalPinStatus_APPIA.u0.bits_0.packageConnectivity + + + + Value of the package connection pin + + */ + unsigned int packageConnectivity : 1; /* 1E.C840.9 RO */ + /* Value of the package connection pin + */ + unsigned int reserved2 : 1; + /*! \brief 1E.C840.7 RO Tx Enable + AQ_GlobalPinStatus_APPIA.u0.bits_0.txEnable + + + + Current Value of Tx Enable pin + + + Notes: + 0 = Disable Transmitter */ + unsigned int txEnable : 1; /* 1E.C840.7 RO */ + /* Current Value of Tx Enable pin + */ + unsigned int reserved3 : 1; + /*! \brief 1E.C840.5:0 RO LED Pullup State [5:0] + AQ_GlobalPinStatus_APPIA.u0.bits_0.ledPullupState + + + + 1 = LED output pin is pulled high + 0 = LED output pin is pulled low + + */ + unsigned int ledPullupState : 6; /* 1E.C840.5:0 RO */ + /* 1 = LED output pin is pulled high + 0 = LED output pin is pulled low + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalPinStatus_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Daisy Chain Status: 1E.C842 */ +/* Global Daisy Chain Status: 1E.C842 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Daisy Chain Status */ + union + { + struct + { + /*! \brief 1E.C842.F:0 RO Rx Daisy Chain Calculated CRC [F:0] + AQ_GlobalDaisyChainStatus_APPIA.u0.bits_0.rxDaisyChainCalculatedCrc + + + + Rx Daisy Chain Calculated CRC + + + Notes: + This is the calculated daisy chain CRC. */ + unsigned int rxDaisyChainCalculatedCrc : 16; /* 1E.C842.F:0 RO */ + /* Rx Daisy Chain Calculated CRC + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalDaisyChainStatus_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Fault Message: 1E.C850 */ +/* Global Fault Message: 1E.C850 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Fault Message */ + union + { + struct + { + /*! \brief 1E.C850.F:0 RO Message [F:0] + AQ_GlobalFaultMessage_APPIA.u0.bits_0.message + + + + Error code describing fault + + Notes: + Code 0x8001: Firmware not compatible with chip architecture. This fault occurs when firmware compiled for a different Tensilica core is loaded. + Code 0x8002: VCO calibration failed. This occurs when the main PLLs on chip fail to lock: this is not possible to trigger. + Code 0x8003: XAUI calibration failed. This occurs when the XAUI PLLs fail to lock: this is not possible to trigger. + Code 0x8004: Failed to set operating voltages via PMBus. This only occurs when the processor has control over power supply voltage via an attached PMBus device and there is a protocol error on the I2C bus: this is not possible to trigger. + Code 0x8005: Unexpected device ID. This occurs if the device ID programmed into the internal E-Fuse registers in not valid: this is not possible to trigger. + Code 0x8006: Computed checksum does not match expected checksum. This occurs when the FLASH checksum check performed at boot time fails. This only occurs when the system boots from FLASH. + Code 0x8007: Detected a bit error in static memory. To trigger, corrupt one of the static regions. + Code 0xC001: Illegal Instruction exception. This occurs when the processor attempts to execute an illegal instruction. To trigger this, write an illegal instruction to program memory. It's possible that the bit error check will trigger before the illegal instruction is executed. + Code 0xC002 Instruction Fetch Error. Internal physical address or a data error during instruction fetch: this is not possible to trigger. + Code 0xC003 Load Store Error. Internal physical address or data error during load store operation: this is not possible to trigger.. + Code 0xC004 Privileged Instruction. Attempt to execute a privileged operation without sufficient privilege: this is not possible to trigger. + Code 0xC005 Unaligned Load or Store. Attempt to load or store data at an address which cannot be handled due to alignment: this is not possible to trigger. + Code 0xC006 Instruction fetch from prohibited space: this is not possible to trigger. + Code 0xC007 Data load from prohibited space: this is not possible to trigger. + Code 0xC008 Data store into prohibited space: this is not possible to trigger. */ + unsigned int message : 16; /* 1E.C850.F:0 RO */ + /* Error code describing fault */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalFaultMessage_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Primary Status: 1E.C851 */ +/* Global Primary Status: 1E.C851 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Primary Status */ + union + { + struct + { + unsigned int reserved0 : 15; + /*! \brief 1E.C851.0 RO Primary Status + AQ_GlobalPrimaryStatus_APPIA.u0.bits_0.primaryStatus + + + + 1 = PHY is the primary PHY + 0 = PHY is is secondary PHY + + */ + unsigned int primaryStatus : 1; /* 1E.C851.0 RO */ + /* 1 = PHY is the primary PHY + 0 = PHY is is secondary PHY + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalPrimaryStatus_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Cable Diagnostic Impedance: 1E.C880 */ +/* Global Cable Diagnostic Impedance: 1E.C880 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Cable Diagnostic Impedance */ + union + { + struct + { + /*! \brief 1E.C880.F RO Reserved 1 + AQ_GlobalCableDiagnosticImpedance_APPIA.u0.bits_0.reserved_1 + + + + Reserved for future use + + */ + unsigned int reserved_1 : 1; /* 1E.C880.F RO */ + /* Reserved for future use + */ + /*! \brief 1E.C880.E:C RO Pair A Reflection #1 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u0.bits_0.pairAReflection_1 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the first worst reflection on Pair A. The corresponding length of this reflection from the PHY is given in See Global Power Control - Address 1E.21 */ + unsigned int pairAReflection_1 : 3; /* 1E.C880.E:C RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C880.B RO Reserved 2 + AQ_GlobalCableDiagnosticImpedance_APPIA.u0.bits_0.reserved_2 + + + + Reserved for future use + + */ + unsigned int reserved_2 : 1; /* 1E.C880.B RO */ + /* Reserved for future use + */ + /*! \brief 1E.C880.A:8 RO Pair A Reflection #2 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u0.bits_0.pairAReflection_2 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the second worst reflection on Pair A. The corresponding length of this reflection from the PHY is given in See Global Power Control - Address 1E.21 */ + unsigned int pairAReflection_2 : 3; /* 1E.C880.A:8 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C880.7 RO Reserved 3 + AQ_GlobalCableDiagnosticImpedance_APPIA.u0.bits_0.reserved_3 + + + + Reserved for future use + + */ + unsigned int reserved_3 : 1; /* 1E.C880.7 RO */ + /* Reserved for future use + */ + /*! \brief 1E.C880.6:4 RO Pair A Reflection #3 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u0.bits_0.pairAReflection_3 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the third worst reflection on Pair A. The corresponding length of this reflection from the PHY is given in See Global Power Control - Address 1E.21 */ + unsigned int pairAReflection_3 : 3; /* 1E.C880.6:4 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C880.3 RO Reserved 4 + AQ_GlobalCableDiagnosticImpedance_APPIA.u0.bits_0.reserved_4 + + + + Reserved for future use + + */ + unsigned int reserved_4 : 1; /* 1E.C880.3 RO */ + /* Reserved for future use + */ + /*! \brief 1E.C880.2:0 RO Pair A Reflection #4 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u0.bits_0.pairAReflection_4 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the fourth worst reflection on Pair A. The corresponding length of this reflection from the PHY is given in See Global Power Control - Address 1E.21 */ + unsigned int pairAReflection_4 : 3; /* 1E.C880.2:0 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Cable Diagnostic Impedance */ + union + { + struct + { + /*! \brief 1E.C881.F RO Reserved 5 + AQ_GlobalCableDiagnosticImpedance_APPIA.u1.bits_1.reserved_5 + + + + Reserved for future use + + */ + unsigned int reserved_5 : 1; /* 1E.C881.F RO */ + /* Reserved for future use + */ + /*! \brief 1E.C881.E:C RO Pair B Reflection #1 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u1.bits_1.pairBReflection_1 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the first worst reflection on Pair B. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 2 - Address 1E.32 - 1E.33 */ + unsigned int pairBReflection_1 : 3; /* 1E.C881.E:C RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C881.B RO Reserved 6 + AQ_GlobalCableDiagnosticImpedance_APPIA.u1.bits_1.reserved_6 + + + + Reserved for future use + + */ + unsigned int reserved_6 : 1; /* 1E.C881.B RO */ + /* Reserved for future use + */ + /*! \brief 1E.C881.A:8 RO Pair B Reflection #2 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u1.bits_1.pairBReflection_2 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the second worst reflection on Pair B. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 2 - Address 1E.32 - 1E.33 */ + unsigned int pairBReflection_2 : 3; /* 1E.C881.A:8 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C881.7 RO Reserved 7 + AQ_GlobalCableDiagnosticImpedance_APPIA.u1.bits_1.reserved_7 + + + + Reserved for future use + + */ + unsigned int reserved_7 : 1; /* 1E.C881.7 RO */ + /* Reserved for future use + */ + /*! \brief 1E.C881.6:4 RO Pair B Reflection #3 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u1.bits_1.pairBReflection_3 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the third worst reflection on Pair B. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 2 - Address 1E.32 - 1E.33 */ + unsigned int pairBReflection_3 : 3; /* 1E.C881.6:4 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C881.3 RO Reserved 8 + AQ_GlobalCableDiagnosticImpedance_APPIA.u1.bits_1.reserved_8 + + + + Reserved for future use + + */ + unsigned int reserved_8 : 1; /* 1E.C881.3 RO */ + /* Reserved for future use + */ + /*! \brief 1E.C881.2:0 RO Pair B Reflection #4 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u1.bits_1.pairBReflection_4 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the fourth worst reflection on Pair B. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 2 - Address 1E.32 - 1E.33 */ + unsigned int pairBReflection_4 : 3; /* 1E.C881.2:0 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Cable Diagnostic Impedance */ + union + { + struct + { + /*! \brief 1E.C882.F RO Reserved 9 + AQ_GlobalCableDiagnosticImpedance_APPIA.u2.bits_2.reserved_9 + + + + Reserved for future use + + */ + unsigned int reserved_9 : 1; /* 1E.C882.F RO */ + /* Reserved for future use + */ + /*! \brief 1E.C882.E:C RO Pair C Reflection #1 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u2.bits_2.pairCReflection_1 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the first worst reflection on Pair C. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.33 */ + unsigned int pairCReflection_1 : 3; /* 1E.C882.E:C RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C882.B RO Reserved 10 + AQ_GlobalCableDiagnosticImpedance_APPIA.u2.bits_2.reserved_10 + + + + Reserved for future use + + */ + unsigned int reserved_10 : 1; /* 1E.C882.B RO */ + /* Reserved for future use + */ + /*! \brief 1E.C882.A:8 RO Pair C Reflection #2 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u2.bits_2.pairCReflection_2 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the second worst reflection on Pair C. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.33 */ + unsigned int pairCReflection_2 : 3; /* 1E.C882.A:8 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C882.7 RO Reserved 11 + AQ_GlobalCableDiagnosticImpedance_APPIA.u2.bits_2.reserved_11 + + + + Reserved for future use + + */ + unsigned int reserved_11 : 1; /* 1E.C882.7 RO */ + /* Reserved for future use + */ + /*! \brief 1E.C882.6:4 RO Pair C Reflection #3 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u2.bits_2.pairCReflection_3 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the third worst reflection on Pair C. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.33 */ + unsigned int pairCReflection_3 : 3; /* 1E.C882.6:4 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C882.3 RO Reserved 12 + AQ_GlobalCableDiagnosticImpedance_APPIA.u2.bits_2.reserved_12 + + + + Reserved for future use + + */ + unsigned int reserved_12 : 1; /* 1E.C882.3 RO */ + /* Reserved for future use + */ + /*! \brief 1E.C882.2:0 RO Pair C Reflection #4 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u2.bits_2.pairCReflection_4 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the fourth worst reflection on Pair C. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.33 */ + unsigned int pairCReflection_4 : 3; /* 1E.C882.2:0 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global Cable Diagnostic Impedance */ + union + { + struct + { + /*! \brief 1E.C883.F RO Reserved 13 + AQ_GlobalCableDiagnosticImpedance_APPIA.u3.bits_3.reserved_13 + + + + Reserved for future use + + */ + unsigned int reserved_13 : 1; /* 1E.C883.F RO */ + /* Reserved for future use + */ + /*! \brief 1E.C883.E:C RO Pair D Reflection #1 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u3.bits_3.pairDReflection_1 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the first worst reflection on Pair D. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.34 - 1E.35 */ + unsigned int pairDReflection_1 : 3; /* 1E.C883.E:C RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C883.B RO Reserved 14 + AQ_GlobalCableDiagnosticImpedance_APPIA.u3.bits_3.reserved_14 + + + + Reserved for future use + + */ + unsigned int reserved_14 : 1; /* 1E.C883.B RO */ + /* Reserved for future use + */ + /*! \brief 1E.C883.A:8 RO Pair D Reflection #2 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u3.bits_3.pairDReflection_2 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the second worst reflection on Pair D. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.34 - 1E.35 */ + unsigned int pairDReflection_2 : 3; /* 1E.C883.A:8 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C883.7 RO Reserved 15 + AQ_GlobalCableDiagnosticImpedance_APPIA.u3.bits_3.reserved_15 + + + + Reserved for future use + + */ + unsigned int reserved_15 : 1; /* 1E.C883.7 RO */ + /* Reserved for future use + */ + /*! \brief 1E.C883.6:4 RO Pair D Reflection #3 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u3.bits_3.pairDReflection_3 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the third worst reflection on Pair D. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.34 - 1E.35 */ + unsigned int pairDReflection_3 : 3; /* 1E.C883.6:4 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C883.3 RO Reserved 16 + AQ_GlobalCableDiagnosticImpedance_APPIA.u3.bits_3.reserved_16 + + + + Reserved for future use + + */ + unsigned int reserved_16 : 1; /* 1E.C883.3 RO */ + /* Reserved for future use + */ + /*! \brief 1E.C883.2:0 RO Pair D Reflection #4 [2:0] + AQ_GlobalCableDiagnosticImpedance_APPIA.u3.bits_3.pairDReflection_4 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the fourth worst reflection on Pair D. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.34 - 1E.35 */ + unsigned int pairDReflection_4 : 3; /* 1E.C883.2:0 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + } bits_3; + uint16_t word_3; + } u3; +} AQ_GlobalCableDiagnosticImpedance_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Status: 1E.C884 */ +/* Global Status: 1E.C884 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Status */ + union + { + struct + { + /*! \brief 1E.C884.F:8 RO Reserved Status 0 [7:0] + AQ_GlobalStatus_APPIA.u0.bits_0.reservedStatus_0 + + + + Reserved for future use + + */ + unsigned int reservedStatus_0 : 8; /* 1E.C884.F:8 RO */ + /* Reserved for future use + */ + /*! \brief 1E.C884.7:0 RO Cable Length [7:0] + AQ_GlobalStatus_APPIA.u0.bits_0.cableLength + + + + The estimated length of the cable in meters + + + Notes: + The length of the cable shown here is estimated from the cable diagnostic engine and should be accurate to +/-1m. */ + unsigned int cableLength : 8; /* 1E.C884.7:0 RO */ + /* The estimated length of the cable in meters + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalStatus_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Reserved Status: 1E.C885 */ +/* Global Reserved Status: 1E.C885 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Reserved Status */ + union + { + struct + { + /*! \brief 1E.C885.F:A RO Nearly Seconds MSW[5:0] + AQ_GlobalReservedStatus_APPIA.u0.bits_0.nearlySecondsMSW + + + + Bits 16 to 21 of the 22 bit "Nearly Seconds" uptime counter. + + + Notes: + The "Nearly Seconds" counter is incremented every 1024 milliseconds. */ + unsigned int nearlySecondsMSW : 6; /* 1E.C885.F:A RO */ + /* Bits 16 to 21 of the 22 bit "Nearly Seconds" uptime counter. + */ + /*! \brief 1E.C885.9:8 ROSPD XENPAK NVR Status [1:0] + AQ_GlobalReservedStatus_APPIA.u0.bits_0.xenpakNvrStatus + + Provisionable Default = 0x0 + + Status of XENPAK NVR: + 0: NVR not enabled + 1: Last NVR operation succeeded + 2: Last NVR operation failed + 3: Reserved + + + Notes: + XENPAK register space is mirrored in NVR (SPI ROM). This register indicates the status of the last NVR operation. */ + unsigned int xenpakNvrStatus : 2; /* 1E.C885.9:8 ROSPD Provisionable Default = 0x0 */ + /* Status of XENPAK NVR: + 0: NVR not enabled + 1: Last NVR operation succeeded + 2: Last NVR operation failed + 3: Reserved + */ + /*! \brief 1E.C885.7:0 ROSPD ROM Revision [7:0] + AQ_GlobalReservedStatus_APPIA.u0.bits_0.romRevision + + Provisionable Default = 0x00 + + ROM Revision Number + + + Notes: + Customers may receive multiple ROM images that differ only in their provisioning. This field is used to differentiate those images. This field is used in conjunction with the firmware major and minor revision numbers to uniquely identify ROM images. */ + unsigned int romRevision : 8; /* 1E.C885.7:0 ROSPD Provisionable Default = 0x00 */ + /* ROM Revision Number + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Reserved Status */ + union + { + struct + { + /*! \brief 1E.C886.F:0 RO Nearly Seconds LSW[F:0] + AQ_GlobalReservedStatus_APPIA.u1.bits_1.nearlySecondsLSW + + + + Bits 0 to 15 of the 22 bit "Nearly Seconds" uptime counter. + + + Notes: + The "Nearly Seconds" counter is incremented every 1024 milliseconds. */ + unsigned int nearlySecondsLSW : 16; /* 1E.C886.F:0 RO */ + /* Bits 0 to 15 of the 22 bit "Nearly Seconds" uptime counter. + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalReservedStatus_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Alarms: 1E.CC00 */ +/* Global Alarms: 1E.CC00 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Alarms */ + union + { + struct + { + unsigned int reserved0 : 1; + /*! \brief 1E.CC00.E LH High Temperature Failure + AQ_GlobalAlarms_APPIA.u0.bits_0.highTemperatureFailure + + + + 1 = High temperature failure threshold has been exceeded + + + Notes: + + + + + These bits mirror the matching bit in 1.A070 and 1.A074. These bits are driven by Bits E:B in See Global General Status 1: Address 1E.C830 . */ + unsigned int highTemperatureFailure : 1; /* 1E.CC00.E LH */ + /* 1 = High temperature failure threshold has been exceeded + */ + /*! \brief 1E.CC00.D LH Low Temperature Failure + AQ_GlobalAlarms_APPIA.u0.bits_0.lowTemperatureFailure + + + + 1 = Low temperature failure threshold has been exceeded + + + Notes: + + + + + These bits mirror the matching bit in 1.A070 and 1.A074. These bits are driven by Bits E:B in See Global General Status 1: Address 1E.C830 . */ + unsigned int lowTemperatureFailure : 1; /* 1E.CC00.D LH */ + /* 1 = Low temperature failure threshold has been exceeded + */ + /*! \brief 1E.CC00.C LH High Temperature Warning + AQ_GlobalAlarms_APPIA.u0.bits_0.highTemperatureWarning + + + + 1 = High temperature warning threshold has been exceeded + + + Notes: + + + + + These bits mirror the matching bit in 1.A070 and 1.A074. These bits are driven by Bits E:B in See Global General Status 1: Address 1E.C830 . */ + unsigned int highTemperatureWarning : 1; /* 1E.CC00.C LH */ + /* 1 = High temperature warning threshold has been exceeded + */ + /*! \brief 1E.CC00.B LH Low Temperature Warning + AQ_GlobalAlarms_APPIA.u0.bits_0.lowTemperatureWarning + + + + 1 = Low temperature warning threshold has been exceeded + + + Notes: + + + + + These bits mirror the matching bit in 1.A070 and 1.A074. These bits are driven by Bits E:B in See Global General Status 1: Address 1E.C830 . */ + unsigned int lowTemperatureWarning : 1; /* 1E.CC00.B LH */ + /* 1 = Low temperature warning threshold has been exceeded + */ + unsigned int reserved1 : 4; + /*! \brief 1E.CC00.6 LH Reset completed + AQ_GlobalAlarms_APPIA.u0.bits_0.resetCompleted + + + + 1 = Chip wide reset completed + + Notes: + This bit is set by the microprocessor when it has completed it's initialization sequence. This bit is mirrored in 1.CC02.0 */ + unsigned int resetCompleted : 1; /* 1E.CC00.6 LH */ + /* 1 = Chip wide reset completed */ + unsigned int reserved2 : 1; + /*! \brief 1E.CC00.4 LH Device Fault + AQ_GlobalAlarms_APPIA.u0.bits_0.deviceFault + + + + 1 = Fault + + Notes: + When set, a fault has been detected by the uP and the associated 16 bit error code is visible in See Global Configuration Fault Message: Address 1E.C850 */ + unsigned int deviceFault : 1; /* 1E.CC00.4 LH */ + /* 1 = Fault */ + /*! \brief 1E.CC00.3 LH Reserved Alarm A + AQ_GlobalAlarms_APPIA.u0.bits_0.reservedAlarmA + + + + Reserved for future use + + */ + unsigned int reservedAlarmA : 1; /* 1E.CC00.3 LH */ + /* Reserved for future use + */ + /*! \brief 1E.CC00.2 LH Reserved Alarm B + AQ_GlobalAlarms_APPIA.u0.bits_0.reservedAlarmB + + + + Reserved for future use + + */ + unsigned int reservedAlarmB : 1; /* 1E.CC00.2 LH */ + /* Reserved for future use + */ + /*! \brief 1E.CC00.1 LH Reserved Alarm C + AQ_GlobalAlarms_APPIA.u0.bits_0.reservedAlarmC + + + + Reserved for future use + + */ + unsigned int reservedAlarmC : 1; /* 1E.CC00.1 LH */ + /* Reserved for future use + */ + /*! \brief 1E.CC00.0 LH Reserved Alarm D + AQ_GlobalAlarms_APPIA.u0.bits_0.reservedAlarmD + + + + Reserved for future use + + */ + unsigned int reservedAlarmD : 1; /* 1E.CC00.0 LH */ + /* Reserved for future use + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Alarms */ + union + { + struct + { + unsigned int reserved0 : 1; + /*! \brief 1E.CC01.E LH Smart Power-Down Entered + AQ_GlobalAlarms_APPIA.u1.bits_1.smartPower_downEntered + + + + 1 = Smart Power-Down State Entered + + + Notes: + When this bit is set, it indicates that the Smart Power-Down state was entered */ + unsigned int smartPower_downEntered : 1; /* 1E.CC01.E LH */ + /* 1 = Smart Power-Down State Entered + */ + /*! \brief 1E.CC01.D RO XENPAK Alarm + AQ_GlobalAlarms_APPIA.u1.bits_1.xenpakAlarm + + + + 1 = XENPAK Alarm + + + Notes: + This alarm is performed by H/W. */ + unsigned int xenpakAlarm : 1; /* 1E.CC01.D RO */ + /* 1 = XENPAK Alarm + */ + /*! \brief 1E.CC01.C:8 LH Reserved Alarms [4:0] + AQ_GlobalAlarms_APPIA.u1.bits_1.reservedAlarms + + + + Reserved for future use + + */ + unsigned int reservedAlarms : 5; /* 1E.CC01.C:8 LH */ + /* Reserved for future use + */ + /*! \brief 1E.CC01.7 LH MDIO Command Handling Overflow + AQ_GlobalAlarms_APPIA.u1.bits_1.mdioCommandHandlingOverflow + + + + 1 = PHY was issued more MDIO requests than it could service in it's request buffer + + + Notes: + Assertion of this bit means that more MDIO commands were issued than FW could handle. */ + unsigned int mdioCommandHandlingOverflow : 1; /* 1E.CC01.7 LH */ + /* 1 = PHY was issued more MDIO requests than it could service in it's request buffer + */ + unsigned int reserved1 : 6; + /*! \brief 1E.CC01.0 LH Diagnostic Alarm + AQ_GlobalAlarms_APPIA.u1.bits_1.diagnosticAlarm + + + + 1 = Alarm triggered by a write to 1E.C470.7 + + + Notes: + A diagnostic alarm use to test system alarm circuitry */ + unsigned int diagnosticAlarm : 1; /* 1E.CC01.0 LH */ + /* 1 = Alarm triggered by a write to 1E.C470.7 + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Alarms */ + union + { + struct + { + /*! \brief 1E.CC02.F LH NVR Operation Complete + AQ_GlobalAlarms_APPIA.u2.bits_2.nvrOperationComplete + + + + 1 = NVR operation is complete + + + Notes: + NVR interface is ready interrupt for registers See Global NVR Interface 1: Address 1E.100 - See Global NVR Provisioning Data MSW - Address 1E.17 . */ + unsigned int nvrOperationComplete : 1; /* 1E.CC02.F LH */ + /* 1 = NVR operation is complete + */ + /*! \brief 1E.CC02.E LH Mailbox Operation: Complete + AQ_GlobalAlarms_APPIA.u2.bits_2.mailboxOperation_Complete + + + + 1 = Mailbox operation is complete + + + Notes: + Mailbox interface is ready interrupt for registers See Global Vendor Specific Control - Address 1E.C000 - See Global Vendor Specific Provisioning 5 - Address 1E.C404 */ + unsigned int mailboxOperation_Complete : 1; /* 1E.CC02.E LH */ + /* 1 = Mailbox operation is complete + */ + unsigned int reserved0 : 3; + /*! \brief 1E.CC02.A LH uP DRAM Parity Error + AQ_GlobalAlarms_APPIA.u2.bits_2.upDramParityError + + + + 1 = Parity error detected in the uP DRAM + + */ + unsigned int upDramParityError : 1; /* 1E.CC02.A LH */ + /* 1 = Parity error detected in the uP DRAM + */ + /*! \brief 1E.CC02.9:8 LH uP IRAM Parity Error [1:0] + AQ_GlobalAlarms_APPIA.u2.bits_2.upIramParityError + + + + 1 = Parity error detected in the uP IRAM + + + Notes: + Bit 0 indicates a parity error was detected in the uP IRAM but was corrected. + Bit 1 indicates a multiple parity errors were detected in the uP IRAM and could not be corrected. + The uP IRAM is protected with ECC. */ + unsigned int upIramParityError : 2; /* 1E.CC02.9:8 LH */ + /* 1 = Parity error detected in the uP IRAM + */ + unsigned int reserved1 : 2; + /*! \brief 1E.CC02.5 LRF Tx Enable State Change + AQ_GlobalAlarms_APPIA.u2.bits_2.txEnableStateChange + + + + 1 = TX_EN pin has changed state + + */ + unsigned int txEnableStateChange : 1; /* 1E.CC02.5 LRF */ + /* 1 = TX_EN pin has changed state + */ + unsigned int reserved2 : 2; + /*! \brief 1E.CC02.2 LH MDIO MMD Error + AQ_GlobalAlarms_APPIA.u2.bits_2.mdioMMD_Error + + + + 1 = Invalid MMD address detected + + */ + unsigned int mdioMMD_Error : 1; /* 1E.CC02.2 LH */ + /* 1 = Invalid MMD address detected + */ + /*! \brief 1E.CC02.1 LH MDIO Timeout Error + AQ_GlobalAlarms_APPIA.u2.bits_2.mdioTimeoutError + + + + 1 = MDIO timeout detected + + */ + unsigned int mdioTimeoutError : 1; /* 1E.CC02.1 LH */ + /* 1 = MDIO timeout detected + */ + /*! \brief 1E.CC02.0 LH Watchdog Timer Alarm + AQ_GlobalAlarms_APPIA.u2.bits_2.watchdogTimerAlarm + + + + 1 = Watchdog timer alarm + + */ + unsigned int watchdogTimerAlarm : 1; /* 1E.CC02.0 LH */ + /* 1 = Watchdog timer alarm + */ + } bits_2; + uint16_t word_2; + } u2; +} AQ_GlobalAlarms_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Interrupt Mask: 1E.D400 */ +/* Global Interrupt Mask: 1E.D400 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Interrupt Mask */ + union + { + struct + { + unsigned int reserved0 : 1; + /*! \brief 1E.D400.E R/WPD High Temperature Failure Mask + AQ_GlobalInterruptMask_APPIA.u0.bits_0.highTemperatureFailureMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int highTemperatureFailureMask : 1; /* 1E.D400.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D400.D R/WPD Low Temperature Failure Mask + AQ_GlobalInterruptMask_APPIA.u0.bits_0.lowTemperatureFailureMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int lowTemperatureFailureMask : 1; /* 1E.D400.D R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D400.C R/WPD High Temperature Warning Mask + AQ_GlobalInterruptMask_APPIA.u0.bits_0.highTemperatureWarningMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int highTemperatureWarningMask : 1; /* 1E.D400.C R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D400.B R/WPD Low Temperature Warning Mask + AQ_GlobalInterruptMask_APPIA.u0.bits_0.lowTemperatureWarningMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int lowTemperatureWarningMask : 1; /* 1E.D400.B R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved1 : 4; + /*! \brief 1E.D400.6 R/WPD Reset completed Mask + AQ_GlobalInterruptMask_APPIA.u0.bits_0.resetCompletedMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int resetCompletedMask : 1; /* 1E.D400.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved2 : 1; + /*! \brief 1E.D400.4 R/WPD Device Fault Mask + AQ_GlobalInterruptMask_APPIA.u0.bits_0.deviceFaultMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int deviceFaultMask : 1; /* 1E.D400.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D400.3 R/WPD Reserved Alarm A Mask + AQ_GlobalInterruptMask_APPIA.u0.bits_0.reservedAlarmAMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int reservedAlarmAMask : 1; /* 1E.D400.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D400.2 R/WPD Reserved Alarm B Mask + AQ_GlobalInterruptMask_APPIA.u0.bits_0.reservedAlarmBMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int reservedAlarmBMask : 1; /* 1E.D400.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D400.1 R/WPD Reserved Alarm C Mask + AQ_GlobalInterruptMask_APPIA.u0.bits_0.reservedAlarmCMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int reservedAlarmCMask : 1; /* 1E.D400.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D400.0 R/WPD Reserved Alarm D Mask + AQ_GlobalInterruptMask_APPIA.u0.bits_0.reservedAlarmDMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int reservedAlarmDMask : 1; /* 1E.D400.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Interrupt Mask */ + union + { + struct + { + unsigned int reserved0 : 1; + /*! \brief 1E.D401.E R/WPD Smart Power-Down Entered Mask + AQ_GlobalInterruptMask_APPIA.u1.bits_1.smartPower_downEnteredMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int smartPower_downEnteredMask : 1; /* 1E.D401.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D401.D R/WPD XENPAK Alarm Mask + AQ_GlobalInterruptMask_APPIA.u1.bits_1.xenpakAlarmMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int xenpakAlarmMask : 1; /* 1E.D401.D R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D401.C:8 R/WPD Reserved Alarms Mask [4:0] + AQ_GlobalInterruptMask_APPIA.u1.bits_1.reservedAlarmsMask + + Provisionable Default = 0x00 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int reservedAlarmsMask : 5; /* 1E.D401.C:8 R/WPD Provisionable Default = 0x00 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D401.7 R/WPD MDIO Command Handling Overflow Mask + AQ_GlobalInterruptMask_APPIA.u1.bits_1.mdioCommandHandlingOverflowMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int mdioCommandHandlingOverflowMask : 1; /* 1E.D401.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int reserved1 : 6; + /*! \brief 1E.D401.0 R/WPD Diagnostic Alarm Mask + AQ_GlobalInterruptMask_APPIA.u1.bits_1.diagnosticAlarmMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int diagnosticAlarmMask : 1; /* 1E.D401.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Interrupt Mask */ + union + { + struct + { + /*! \brief 1E.D402.F R/WPD NVR Operation Complete Mask + AQ_GlobalInterruptMask_APPIA.u2.bits_2.nvrOperationCompleteMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + Notes: + NVR interface is ready interrupt for registers See Global NVR Interface 1: Address 1E.100 - See Global NVR Provisioning Data MSW - Address 1E.17 */ + unsigned int nvrOperationCompleteMask : 1; /* 1E.D402.F R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D402.E R/WPD Mailbox Operation Complete Mask + AQ_GlobalInterruptMask_APPIA.u2.bits_2.mailboxOperationCompleteMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + Notes: + Mailbox interface is ready interrupt for registers See Global Vendor Specific Control - Address 1E.C000 - See Global Vendor Specific Provisioning 5 - Address 1E.C404 */ + unsigned int mailboxOperationCompleteMask : 1; /* 1E.D402.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved0 : 3; + /*! \brief 1E.D402.A R/WPD uP DRAM Parity Error Mask + AQ_GlobalInterruptMask_APPIA.u2.bits_2.upDramParityErrorMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int upDramParityErrorMask : 1; /* 1E.D402.A R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D402.9:8 R/WPD uP IRAM Parity Error Mask [1:0] + AQ_GlobalInterruptMask_APPIA.u2.bits_2.upIramParityErrorMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int upIramParityErrorMask : 2; /* 1E.D402.9:8 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int reserved1 : 2; + /*! \brief 1E.D402.5 R/WPD Tx Enable State Change Mask + AQ_GlobalInterruptMask_APPIA.u2.bits_2.txEnableStateChangeMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int txEnableStateChangeMask : 1; /* 1E.D402.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved2 : 2; + /*! \brief 1E.D402.2 R/WPD MDIO MMD Error Mask + AQ_GlobalInterruptMask_APPIA.u2.bits_2.mdioMMD_ErrorMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int mdioMMD_ErrorMask : 1; /* 1E.D402.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D402.1 R/WPD MDIO Timeout Error Mask + AQ_GlobalInterruptMask_APPIA.u2.bits_2.mdioTimeoutErrorMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int mdioTimeoutErrorMask : 1; /* 1E.D402.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D402.0 R/WPD Watchdog Timer Alarm Mask + AQ_GlobalInterruptMask_APPIA.u2.bits_2.watchdogTimerAlarmMask + + Provisionable Default = 0x1 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int watchdogTimerAlarmMask : 1; /* 1E.D402.0 R/WPD Provisionable Default = 0x1 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + } bits_2; + uint16_t word_2; + } u2; +} AQ_GlobalInterruptMask_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Chip-Wide Standard Interrupt Flags: 1E.FC00 */ +/* Global Chip-Wide Standard Interrupt Flags: 1E.FC00 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Chip-Wide Standard Interrupt Flags */ + union + { + struct + { + /*! \brief 1E.FC00.F RO PMA Standard Alarm 1 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_APPIA.u0.bits_0.pmaStandardAlarm_1Interrupt + + + + 1 = Interrupt in PMA standard alarms 1 + + + Notes: + An interrupt was generated from bit 1.1.2. + An interrupt was generated from status register ( See PHY XS Standard Status 1 - Address 4.1 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 2 - Address 4.A001 ) */ + unsigned int pmaStandardAlarm_1Interrupt : 1; /* 1E.FC00.F RO */ + /* 1 = Interrupt in PMA standard alarms 1 + */ + /*! \brief 1E.FC00.E RO PMA Standard Alarm 2 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_APPIA.u0.bits_0.pmaStandardAlarm_2Interrupt + + + + 1 = Interrupt in PMA standard alarms 2 + + + Notes: + An interrupt was generated from either bit 1.8.B or 1.8.A. + An interrupt was generated from status register ( See PHY XS Standard Vendor Devices in Package - Address 4.8 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 8 - Address 4.A008 ) */ + unsigned int pmaStandardAlarm_2Interrupt : 1; /* 1E.FC00.E RO */ + /* 1 = Interrupt in PMA standard alarms 2 + */ + /*! \brief 1E.FC00.D RO PCS Standard Alarm 1 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_APPIA.u0.bits_0.pcsStandardAlarm_1Interrupt + + + + 1 = Interrupt in PCS standard alarms 1 + + + Notes: + An interrupt was generated from status register ( See PHY XS Standard Status 1 - Address 4.1 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 2 - Address 4.A001 ) */ + unsigned int pcsStandardAlarm_1Interrupt : 1; /* 1E.FC00.D RO */ + /* 1 = Interrupt in PCS standard alarms 1 + */ + /*! \brief 1E.FC00.C RO PCS Standard Alarm 2 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_APPIA.u0.bits_0.pcsStandardAlarm_2Interrupt + + + + 1 = Interrupt in PCS standard alarms 2 + + + Notes: + An interrupt was generated from status register ( See PHY XS Standard Vendor Devices in Package - Address 4.8 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 8 - Address 4.A008 ) */ + unsigned int pcsStandardAlarm_2Interrupt : 1; /* 1E.FC00.C RO */ + /* 1 = Interrupt in PCS standard alarms 2 + */ + /*! \brief 1E.FC00.B RO PCS Standard Alarm 3 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_APPIA.u0.bits_0.pcsStandardAlarm_3Interrupt + + + + 1 = Interrupt in PCS standard alarms 3 + + + Notes: + An interrupt was generated from status register ( See PCS 10GBASE-T Status 2 - Address 3.21 ) and the corresponding mask register. ( See PCS Standard Interrupt Mask 1 - Address 3.E021 ) */ + unsigned int pcsStandardAlarm_3Interrupt : 1; /* 1E.FC00.B RO */ + /* 1 = Interrupt in PCS standard alarms 3 + */ + /*! \brief 1E.FC00.A RO PHY XS Standard Alarms 1 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_APPIA.u0.bits_0.phyXS_StandardAlarms_1Interrupt + + + + 1 = Interrupt in PHY XS standard alarms 1 + + + Notes: + An interrupt was generated from the status register ( See PHY XS Standard Status 1 - Address 4.1 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 2 - Address 4.A001 ) */ + unsigned int phyXS_StandardAlarms_1Interrupt : 1; /* 1E.FC00.A RO */ + /* 1 = Interrupt in PHY XS standard alarms 1 + */ + /*! \brief 1E.FC00.9 RO PHY XS Standard Alarms 2 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_APPIA.u0.bits_0.phyXS_StandardAlarms_2Interrupt + + + + 1 = Interrupt in PHY XS standard alarms 2 + + + Notes: + An interrupt was generated from the status register ( See PHY XS Standard Vendor Devices in Package - Address 4.8 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 8 - Address 4.A008 ) */ + unsigned int phyXS_StandardAlarms_2Interrupt : 1; /* 1E.FC00.9 RO */ + /* 1 = Interrupt in PHY XS standard alarms 2 + */ + /*! \brief 1E.FC00.8 RO Autonegotiation Standard Alarms 1 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_APPIA.u0.bits_0.autonegotiationStandardAlarms_1Interrupt + + + + 1 = Interrupt in Autonegotiation standard alarms 1 + + + Notes: + An interrupt was generated from status register ( See PHY XS Standard Status 1 - Address 4.1 ) and the corresponding mask register. ( See Autonegotiation Standard LASI Interrupt Mask 1: Address 7.D000 ) */ + unsigned int autonegotiationStandardAlarms_1Interrupt : 1; /* 1E.FC00.8 RO */ + /* 1 = Interrupt in Autonegotiation standard alarms 1 + */ + /*! \brief 1E.FC00.7 RO Autonegotiation Standard Alarms 2 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_APPIA.u0.bits_0.autonegotiationStandardAlarms_2Interrupt + + + + 1 = Interrupt in Autonegotiation standard alarms 2 + + + Notes: + An interrupt was generated from status register ( See Autonegotiation 10GBASE-T Status Register - Address 7.21 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 8 - Address 4.A008 ) */ + unsigned int autonegotiationStandardAlarms_2Interrupt : 1; /* 1E.FC00.7 RO */ + /* 1 = Interrupt in Autonegotiation standard alarms 2 + */ + /*! \brief 1E.FC00.6 RO GbE Standard Alarms Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_APPIA.u0.bits_0.gbeStandardAlarmsInterrupt + + + + 1 = Interrupt in GbE standard alarms + + + Notes: + An interrupt was generated from the TGE core. */ + unsigned int gbeStandardAlarmsInterrupt : 1; /* 1E.FC00.6 RO */ + /* 1 = Interrupt in GbE standard alarms + */ + unsigned int reserved0 : 5; + /*! \brief 1E.FC00.0 RO All Vendor Alarms Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_APPIA.u0.bits_0.allVendorAlarmsInterrupt + + + + 1 = Interrupt in all vendor alarms + + + Notes: + An interrupt was generated from status register ( See Global Chip-Wide LASI Vendor Interrupt Flags: Address 1E.FC01 ) and the corresponding mask register. ( See Global Interrupt LASI Mask: Address 1E.FF01 ) */ + unsigned int allVendorAlarmsInterrupt : 1; /* 1E.FC00.0 RO */ + /* 1 = Interrupt in all vendor alarms + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalChip_wideStandardInterruptFlags_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Chip-Wide Vendor Interrupt Flags: 1E.FC01 */ +/* Global Chip-Wide Vendor Interrupt Flags: 1E.FC01 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Chip-Wide Vendor Interrupt Flags */ + union + { + struct + { + /*! \brief 1E.FC01.F RO PMA Vendor Alarm Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_APPIA.u0.bits_0.pmaVendorAlarmInterrupt + + + + 1 = Interrupt in PMA vendor specific alarm + + + Notes: + A PMA alarm was generated. ( See PHY XS Vendor Global Interrupt Flags 1- Address 4.F800 ) */ + unsigned int pmaVendorAlarmInterrupt : 1; /* 1E.FC01.F RO */ + /* 1 = Interrupt in PMA vendor specific alarm + */ + /*! \brief 1E.FC01.E RO PCS Vendor Alarm Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_APPIA.u0.bits_0.pcsVendorAlarmInterrupt + + + + 1 = Interrupt in PCS vendor specific alarm + + + Notes: + A PCS alarm was generated. ( See PHY XS Vendor Global Interrupt Flags 1- Address 4.F800 ) */ + unsigned int pcsVendorAlarmInterrupt : 1; /* 1E.FC01.E RO */ + /* 1 = Interrupt in PCS vendor specific alarm + */ + /*! \brief 1E.FC01.D RO PHY XS Vendor Alarm Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_APPIA.u0.bits_0.phyXS_VendorAlarmInterrupt + + + + 1 = Interrupt in PHY XS vendor specific alarm + + + Notes: + A PHY XS alarm was generated. ( See PHY XS Vendor Global LASI Interrupt Flags 1: Address 4.FC00 ) */ + unsigned int phyXS_VendorAlarmInterrupt : 1; /* 1E.FC01.D RO */ + /* 1 = Interrupt in PHY XS vendor specific alarm + */ + /*! \brief 1E.FC01.C RO Autonegotiation Vendor Alarm Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_APPIA.u0.bits_0.autonegotiationVendorAlarmInterrupt + + + + 1 = Interrupt in Autonegotiation vendor specific alarm + + + Notes: + An Autonegotiation alarm was generated. ( See Autonegotiation Vendor Global LASI Interrupt Flags 1: Address 7.FC00 ) */ + unsigned int autonegotiationVendorAlarmInterrupt : 1; /* 1E.FC01.C RO */ + /* 1 = Interrupt in Autonegotiation vendor specific alarm + */ + /*! \brief 1E.FC01.B RO GbE Vendor Alarm Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_APPIA.u0.bits_0.gbeVendorAlarmInterrupt + + + + 1 = Interrupt in GbE vendor specific alarm + + + Notes: + A GbE alarm was generated. ( See GbE PHY Vendor Global LASI Interrupt Flags 1: Address 1D.FC00 ) */ + unsigned int gbeVendorAlarmInterrupt : 1; /* 1E.FC01.B RO */ + /* 1 = Interrupt in GbE vendor specific alarm + */ + unsigned int reserved0 : 8; + /*! \brief 1E.FC01.2 RO Global Alarms 1 Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_APPIA.u0.bits_0.globalAlarms_1Interrupt + + + + 1 = Interrupt in Global alarms 1 + + + Notes: + An interrupt was generated from status register ( See Global Vendor Alarms 1 - Address 1E.CC00 ) and the corresponding mask register. ( See Global Vendor Interrupt Mask - Address 1E.D400 ) */ + unsigned int globalAlarms_1Interrupt : 1; /* 1E.FC01.2 RO */ + /* 1 = Interrupt in Global alarms 1 + */ + /*! \brief 1E.FC01.1 RO Global Alarms 2 Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_APPIA.u0.bits_0.globalAlarms_2Interrupt + + + + 1 = Interrupt in Global alarms 2 + + + Notes: + An interrupt was generated from status register ( See Global Alarms 2: Address 1E.CC01 ) and the corresponding mask register. ( See Global LASI Interrupt Mask 2: Address 1E.D401 ) */ + unsigned int globalAlarms_2Interrupt : 1; /* 1E.FC01.1 RO */ + /* 1 = Interrupt in Global alarms 2 + */ + /*! \brief 1E.FC01.0 RO Global Alarms 3 Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_APPIA.u0.bits_0.globalAlarms_3Interrupt + + + + 1 = Interrupt in Global alarms 3 + + + Notes: + An interrupt was generated from status register ( See Global Vendor Alarms 2: Address 1E.CC01 ) and the corresponding mask register. ( See Global LASI Interrupt Mask 2: Address 1E.D401 ) */ + unsigned int globalAlarms_3Interrupt : 1; /* 1E.FC01.0 RO */ + /* 1 = Interrupt in Global alarms 3 + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalChip_wideVendorInterruptFlags_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Interrupt Chip-Wide Standard Mask: 1E.FF00 */ +/* Global Interrupt Chip-Wide Standard Mask: 1E.FF00 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Interrupt Chip-Wide Standard Mask */ + union + { + struct + { + /*! \brief 1E.FF00.F R/WPD PMA Standard Alarm 1 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_APPIA.u0.bits_0.pmaStandardAlarm_1InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pmaStandardAlarm_1InterruptMask : 1; /* 1E.FF00.F R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.E R/WPD PMA Standard Alarm 2 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_APPIA.u0.bits_0.pmaStandardAlarm_2InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pmaStandardAlarm_2InterruptMask : 1; /* 1E.FF00.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.D R/WPD PCS Standard Alarm 1 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_APPIA.u0.bits_0.pcsStandardAlarm_1InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pcsStandardAlarm_1InterruptMask : 1; /* 1E.FF00.D R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.C R/WPD PCS Standard Alarm 2 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_APPIA.u0.bits_0.pcsStandardAlarm_2InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pcsStandardAlarm_2InterruptMask : 1; /* 1E.FF00.C R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.B R/WPD PCS Standard Alarm 3 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_APPIA.u0.bits_0.pcsStandardAlarm_3InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pcsStandardAlarm_3InterruptMask : 1; /* 1E.FF00.B R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.A R/WPD PHY XS Standard Alarms 1 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_APPIA.u0.bits_0.phyXS_StandardAlarms_1InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int phyXS_StandardAlarms_1InterruptMask : 1; /* 1E.FF00.A R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.9 R/WPD PHY XS Standard Alarms 2 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_APPIA.u0.bits_0.phyXS_StandardAlarms_2InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int phyXS_StandardAlarms_2InterruptMask : 1; /* 1E.FF00.9 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.8 R/WPD Autonegotiation Standard Alarms 1 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_APPIA.u0.bits_0.autonegotiationStandardAlarms_1InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int autonegotiationStandardAlarms_1InterruptMask : 1; /* 1E.FF00.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.7 R/WPD Autonegotiation Standard Alarms 2 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_APPIA.u0.bits_0.autonegotiationStandardAlarms_2InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int autonegotiationStandardAlarms_2InterruptMask : 1; /* 1E.FF00.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.6 R/WPD Gbe Standard Alarms Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_APPIA.u0.bits_0.gbeStandardAlarmsInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int gbeStandardAlarmsInterruptMask : 1; /* 1E.FF00.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved0 : 5; + /*! \brief 1E.FF00.0 R/WPD All Vendor Alarms Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_APPIA.u0.bits_0.allVendorAlarmsInterruptMask + + Provisionable Default = 0x1 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int allVendorAlarmsInterruptMask : 1; /* 1E.FF00.0 R/WPD Provisionable Default = 0x1 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalInterruptChip_wideStandardMask_APPIA; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Interrupt Chip-Wide Vendor Mask: 1E.FF01 */ +/* Global Interrupt Chip-Wide Vendor Mask: 1E.FF01 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Interrupt Chip-Wide Vendor Mask */ + union + { + struct + { + /*! \brief 1E.FF01.F R/WPD PMA Vendor Alarm Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_APPIA.u0.bits_0.pmaVendorAlarmInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pmaVendorAlarmInterruptMask : 1; /* 1E.FF01.F R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.E R/WPD PCS Vendor Alarm Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_APPIA.u0.bits_0.pcsVendorAlarmInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pcsVendorAlarmInterruptMask : 1; /* 1E.FF01.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.D R/WPD PHY XS Vendor Alarm Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_APPIA.u0.bits_0.phyXS_VendorAlarmInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int phyXS_VendorAlarmInterruptMask : 1; /* 1E.FF01.D R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.C R/WPD Autonegotiation Vendor Alarm Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_APPIA.u0.bits_0.autonegotiationVendorAlarmInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int autonegotiationVendorAlarmInterruptMask : 1; /* 1E.FF01.C R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.B R/WPD GbE Vendor Alarm Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_APPIA.u0.bits_0.gbeVendorAlarmInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int gbeVendorAlarmInterruptMask : 1; /* 1E.FF01.B R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved0 : 8; + /*! \brief 1E.FF01.2 R/WPD Global Alarms 1 Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_APPIA.u0.bits_0.globalAlarms_1InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int globalAlarms_1InterruptMask : 1; /* 1E.FF01.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.1 R/WPD Global Alarms 2 Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_APPIA.u0.bits_0.globalAlarms_2InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int globalAlarms_2InterruptMask : 1; /* 1E.FF01.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.0 R/WPD Global Alarms 3 Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_APPIA.u0.bits_0.globalAlarms_3InterruptMask + + Provisionable Default = 0x1 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int globalAlarms_3InterruptMask : 1; /* 1E.FF01.0 R/WPD Provisionable Default = 0x1 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalInterruptChip_wideVendorMask_APPIA; + +#endif +/*@}*/ +/*@}*/ diff --git a/feeds/ipq807x/aq-fw-download/src/include/registerMap/AQ_RegGroupMaxSizes.h b/feeds/ipq807x/aq-fw-download/src/include/registerMap/AQ_RegGroupMaxSizes.h new file mode 100755 index 000000000..08e255860 --- /dev/null +++ b/feeds/ipq807x/aq-fw-download/src/include/registerMap/AQ_RegGroupMaxSizes.h @@ -0,0 +1,387 @@ +/* Copyright (c) 2015, Aquantia +* +* Permission to use, copy, modify, and/or distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +#ifndef AQ_REG_GROUP_MAX_SIZES +#define AQ_REG_GROUP_MAX_SIZES + +#define AQ_Autonegotiation10GBaseT_ControlRegister_BiggestVersion AQ_Autonegotiation10GBaseT_ControlRegister_HHD +#define AQ_Autonegotiation10GBaseT_StatusRegister_BiggestVersion AQ_Autonegotiation10GBaseT_StatusRegister_HHD +#define AQ_AutonegotiationAdvertisementRegister_BiggestVersion AQ_AutonegotiationAdvertisementRegister_HHD +#define AQ_AutonegotiationEeeAdvertisementRegister_BiggestVersion AQ_AutonegotiationEeeAdvertisementRegister_HHD +#define AQ_AutonegotiationEeeLinkPartnerAbilityRegister_BiggestVersion AQ_AutonegotiationEeeLinkPartnerAbilityRegister_HHD +#define AQ_AutonegotiationExtendedNextPageTransmitRegister_BiggestVersion AQ_AutonegotiationExtendedNextPageTransmitRegister_HHD +#define AQ_AutonegotiationExtendedNextPageUnformattedCodeRegister_BiggestVersion AQ_AutonegotiationExtendedNextPageUnformattedCodeRegister_HHD +#define AQ_AutonegotiationLinkPartnerBasePageAbilityRegister_BiggestVersion AQ_AutonegotiationLinkPartnerBasePageAbilityRegister_HHD +#define AQ_AutonegotiationLinkPartnerExtendedNextPageAbilityRegister_BiggestVersion AQ_AutonegotiationLinkPartnerExtendedNextPageAbilityRegister_HHD +#define AQ_AutonegotiationLinkPartnerExtendedNextPageUnformattedCodeRegister_BiggestVersion AQ_AutonegotiationLinkPartnerExtendedNextPageUnformattedCodeRegister_HHD +#define AQ_AutonegotiationReceiveLinkPartnerStatus_BiggestVersion AQ_AutonegotiationReceiveLinkPartnerStatus_HHD +#define AQ_AutonegotiationReceiveReservedVendorProvisioning_BiggestVersion AQ_AutonegotiationReceiveReservedVendorProvisioning_APPIA +#define AQ_AutonegotiationReceiveReservedVendorStatus_BiggestVersion AQ_AutonegotiationReceiveReservedVendorStatus_HHD +#define AQ_AutonegotiationReceiveVendorAlarms_BiggestVersion AQ_AutonegotiationReceiveVendorAlarms_HHD +#define AQ_AutonegotiationReceiveVendorInterruptMask_BiggestVersion AQ_AutonegotiationReceiveVendorInterruptMask_HHD +#define AQ_AutonegotiationReservedVendorProvisioning_BiggestVersion AQ_AutonegotiationReservedVendorProvisioning_HHD +#define AQ_AutonegotiationReservedVendorStatus_BiggestVersion AQ_AutonegotiationReservedVendorStatus_HHD +#define AQ_AutonegotiationStandardControl_1_BiggestVersion AQ_AutonegotiationStandardControl_1_HHD +#define AQ_AutonegotiationStandardDeviceIdentifier_BiggestVersion AQ_AutonegotiationStandardDeviceIdentifier_HHD +#define AQ_AutonegotiationStandardDevicesInPackage_BiggestVersion AQ_AutonegotiationStandardDevicesInPackage_HHD +#define AQ_AutonegotiationStandardInterruptMask_BiggestVersion AQ_AutonegotiationStandardInterruptMask_HHD +#define AQ_AutonegotiationStandardPackageIdentifier_BiggestVersion AQ_AutonegotiationStandardPackageIdentifier_HHD +#define AQ_AutonegotiationStandardStatus_1_BiggestVersion AQ_AutonegotiationStandardStatus_1_HHD +#define AQ_AutonegotiationStandardStatus_2_BiggestVersion AQ_AutonegotiationStandardStatus_2_HHD +#define AQ_AutonegotiationTransmitVendorAlarms_BiggestVersion AQ_AutonegotiationTransmitVendorAlarms_APPIA +#define AQ_AutonegotiationTransmitVendorInterruptMask_BiggestVersion AQ_AutonegotiationTransmitVendorInterruptMask_HHD +#define AQ_AutonegotiationVendorGlobalInterruptFlags_BiggestVersion AQ_AutonegotiationVendorGlobalInterruptFlags_HHD +#define AQ_AutonegotiationVendorProvisioning_BiggestVersion AQ_AutonegotiationVendorProvisioning_HHD +#define AQ_AutonegotiationVendorStatus_BiggestVersion AQ_AutonegotiationVendorStatus_HHD +#define AQ_GbePhyExtendedWolControl_BiggestVersion AQ_GbePhyExtendedWolControl_HHD +#define AQ_GbePhySgmii0RxStatus_BiggestVersion AQ_GbePhySgmii0RxStatus_HHD +#define AQ_GbePhySgmii0TxStatus_BiggestVersion AQ_GbePhySgmii0TxStatus_HHD +#define AQ_GbePhySgmii1RxStatus_BiggestVersion AQ_GbePhySgmii1RxStatus_HHD +#define AQ_GbePhySgmii1TxStatus_BiggestVersion AQ_GbePhySgmii1TxStatus_HHD +#define AQ_GbePhySgmii1WolStatus_BiggestVersion AQ_GbePhySgmii1WolStatus_HHD +#define AQ_GbePhySgmiiRxAlarms_BiggestVersion AQ_GbePhySgmiiRxAlarms_HHD +#define AQ_GbePhySgmiiRxInterruptMask_BiggestVersion AQ_GbePhySgmiiRxInterruptMask_HHD +#define AQ_GbePhySgmiiTestControl_BiggestVersion AQ_GbePhySgmiiTestControl_HHD +#define AQ_GbePhySgmiiTxAlarms_BiggestVersion AQ_GbePhySgmiiTxAlarms_HHD +#define AQ_GbePhySgmiiTxInterruptMask_BiggestVersion AQ_GbePhySgmiiTxInterruptMask_HHD +#define AQ_GbePhySgmiiWolStatus_BiggestVersion AQ_GbePhySgmiiWolStatus_HHD +#define AQ_GbePhyVendorGlobalInterruptFlags_BiggestVersion AQ_GbePhyVendorGlobalInterruptFlags_HHD +#define AQ_GbePhyWolControl_BiggestVersion AQ_GbePhyWolControl_HHD +#define AQ_GbePhysgmii1WolStatus_BiggestVersion AQ_GbePhysgmii1WolStatus_APPIA +#define AQ_GbeReservedProvisioning_BiggestVersion AQ_GbeReservedProvisioning_HHD +#define AQ_GbeStandardDeviceIdentifier_BiggestVersion AQ_GbeStandardDeviceIdentifier_HHD +#define AQ_GbeStandardDevicesInPackage_BiggestVersion AQ_GbeStandardDevicesInPackage_HHD +#define AQ_GbeStandardPackageIdentifier_BiggestVersion AQ_GbeStandardPackageIdentifier_HHD +#define AQ_GbeStandardStatus_2_BiggestVersion AQ_GbeStandardStatus_2_HHD +#define AQ_GbeStandardVendorDevicesInPackage_BiggestVersion AQ_GbeStandardVendorDevicesInPackage_HHD +#define AQ_GlobalAlarms_BiggestVersion AQ_GlobalAlarms_HHD +#define AQ_GlobalCableDiagnosticImpedance_BiggestVersion AQ_GlobalCableDiagnosticImpedance_HHD +#define AQ_GlobalCableDiagnosticStatus_BiggestVersion AQ_GlobalCableDiagnosticStatus_APPIA +#define AQ_GlobalChipIdentification_BiggestVersion AQ_GlobalChipIdentification_APPIA +#define AQ_GlobalChipRevision_BiggestVersion AQ_GlobalChipRevision_APPIA +#define AQ_GlobalChip_wideStandardInterruptFlags_BiggestVersion AQ_GlobalChip_wideStandardInterruptFlags_HHD +#define AQ_GlobalChip_wideVendorInterruptFlags_BiggestVersion AQ_GlobalChip_wideVendorInterruptFlags_HHD +#define AQ_GlobalControl_BiggestVersion AQ_GlobalControl_HHD +#define AQ_GlobalDaisyChainStatus_BiggestVersion AQ_GlobalDaisyChainStatus_HHD +#define AQ_GlobalDiagnosticProvisioning_BiggestVersion AQ_GlobalDiagnosticProvisioning_HHD +#define AQ_GlobalEeeProvisioning_BiggestVersion AQ_GlobalEeeProvisioning_HHD +#define AQ_GlobalFaultMessage_BiggestVersion AQ_GlobalFaultMessage_HHD +#define AQ_GlobalFirmwareID_BiggestVersion AQ_GlobalFirmwareID_HHD +#define AQ_GlobalGeneralProvisioning_BiggestVersion AQ_GlobalGeneralProvisioning_HHD +#define AQ_GlobalGeneralStatus_BiggestVersion AQ_GlobalGeneralStatus_HHD +#define AQ_GlobalInterruptChip_wideStandardMask_BiggestVersion AQ_GlobalInterruptChip_wideStandardMask_HHD +#define AQ_GlobalInterruptChip_wideVendorMask_BiggestVersion AQ_GlobalInterruptChip_wideVendorMask_HHD +#define AQ_GlobalInterruptMask_BiggestVersion AQ_GlobalInterruptMask_HHD +#define AQ_GlobalLedProvisioning_BiggestVersion AQ_GlobalLedProvisioning_HHD +#define AQ_GlobalMailboxInterface_BiggestVersion AQ_GlobalMailboxInterface_HHD +#define AQ_GlobalMicroprocessorScratchPad_BiggestVersion AQ_GlobalMicroprocessorScratchPad_HHD +#define AQ_GlobalNvrInterface_BiggestVersion AQ_GlobalNvrInterface_HHD +#define AQ_GlobalNvrProvisioning_BiggestVersion AQ_GlobalNvrProvisioning_HHD +#define AQ_GlobalPinStatus_BiggestVersion AQ_GlobalPinStatus_HHD +#define AQ_GlobalPrimaryStatus_BiggestVersion AQ_GlobalPrimaryStatus_APPIA +#define AQ_GlobalReservedProvisioning_BiggestVersion AQ_GlobalReservedProvisioning_HHD +#define AQ_GlobalReservedStatus_BiggestVersion AQ_GlobalReservedStatus_HHD +#define AQ_GlobalResetControl_BiggestVersion AQ_GlobalResetControl_HHD +#define AQ_GlobalSmbus_0Provisioning_BiggestVersion AQ_GlobalSmbus_0Provisioning_HHD +#define AQ_GlobalSmbus_1Provisioning_BiggestVersion AQ_GlobalSmbus_1Provisioning_HHD +#define AQ_GlobalStandardControl_1_BiggestVersion AQ_GlobalStandardControl_1_HHD +#define AQ_GlobalStandardDeviceIdentifier_BiggestVersion AQ_GlobalStandardDeviceIdentifier_HHD +#define AQ_GlobalStandardDevicesInPackage_BiggestVersion AQ_GlobalStandardDevicesInPackage_HHD +#define AQ_GlobalStandardPackageIdentifier_BiggestVersion AQ_GlobalStandardPackageIdentifier_HHD +#define AQ_GlobalStandardStatus_2_BiggestVersion AQ_GlobalStandardStatus_2_HHD +#define AQ_GlobalStandardVendorDevicesInPackage_BiggestVersion AQ_GlobalStandardVendorDevicesInPackage_HHD +#define AQ_GlobalStatus_BiggestVersion AQ_GlobalStatus_HHD +#define AQ_GlobalThermalProvisioning_BiggestVersion AQ_GlobalThermalProvisioning_HHD +#define AQ_GlobalThermalStatus_BiggestVersion AQ_GlobalThermalStatus_HHD +#define AQ_Kr0AutonegotiationAdvertisementWord_BiggestVersion AQ_Kr0AutonegotiationAdvertisementWord_HHD +#define AQ_Kr0AutonegotiationControl_BiggestVersion AQ_Kr0AutonegotiationControl_HHD +#define AQ_Kr0AutonegotiationExtendedNextPageAdvertisementWord_BiggestVersion AQ_Kr0AutonegotiationExtendedNextPageAdvertisementWord_HHD +#define AQ_Kr0AutonegotiationStatus_BiggestVersion AQ_Kr0AutonegotiationStatus_HHD +#define AQ_Kr0LinkPartnerAutonegotiationAdvertisementWord_BiggestVersion AQ_Kr0LinkPartnerAutonegotiationAdvertisementWord_HHD +#define AQ_Kr0LinkPartnerAutonegotiationExtendedNextPageAdvertisementWord_BiggestVersion AQ_Kr0LinkPartnerAutonegotiationExtendedNextPageAdvertisementWord_HHD +#define AQ_Kr1AutonegotiationAdvertisementWord_BiggestVersion AQ_Kr1AutonegotiationAdvertisementWord_HHD +#define AQ_Kr1AutonegotiationControl_BiggestVersion AQ_Kr1AutonegotiationControl_HHD +#define AQ_Kr1AutonegotiationExtendedNextPageAdvertisementWord_BiggestVersion AQ_Kr1AutonegotiationExtendedNextPageAdvertisementWord_HHD +#define AQ_Kr1AutonegotiationStatus_BiggestVersion AQ_Kr1AutonegotiationStatus_HHD +#define AQ_Kr1LinkPartnerAutonegotiationAdvertisementWord_BiggestVersion AQ_Kr1LinkPartnerAutonegotiationAdvertisementWord_HHD +#define AQ_Kr1LinkPartnerAutonegotiationExtendedNextPageAdvertisementWord_BiggestVersion AQ_Kr1LinkPartnerAutonegotiationExtendedNextPageAdvertisementWord_HHD +#define AQ_MsmLineFifoControlRegister_BiggestVersion AQ_MsmLineFifoControlRegister_HHD +#define AQ_MsmLineGeneralControlRegister_BiggestVersion AQ_MsmLineGeneralControlRegister_HHD +#define AQ_MsmLineGeneralStatusRegister_BiggestVersion AQ_MsmLineGeneralStatusRegister_HHD +#define AQ_MsmLineRxAlignmentErrorsCounterRegister_BiggestVersion AQ_MsmLineRxAlignmentErrorsCounterRegister_HHD +#define AQ_MsmLineRxBroadcastFramesCounterRegister_BiggestVersion AQ_MsmLineRxBroadcastFramesCounterRegister_HHD +#define AQ_MsmLineRxErrorsCounterRegister_BiggestVersion AQ_MsmLineRxErrorsCounterRegister_HHD +#define AQ_MsmLineRxFcsErrorsCounterRegister_BiggestVersion AQ_MsmLineRxFcsErrorsCounterRegister_HHD +#define AQ_MsmLineRxGoodFramesCounterRegister_BiggestVersion AQ_MsmLineRxGoodFramesCounterRegister_HHD +#define AQ_MsmLineRxInRangeLengthErrorsCounterRegister_BiggestVersion AQ_MsmLineRxInRangeLengthErrorsCounterRegister_HHD +#define AQ_MsmLineRxMulticastFramesCounterRegister_BiggestVersion AQ_MsmLineRxMulticastFramesCounterRegister_HHD +#define AQ_MsmLineRxOctetsCounterRegister_BiggestVersion AQ_MsmLineRxOctetsCounterRegister_HHD +#define AQ_MsmLineRxPauseFramesCounterRegister_BiggestVersion AQ_MsmLineRxPauseFramesCounterRegister_HHD +#define AQ_MsmLineRxTooLongErrorsCounterRegister_BiggestVersion AQ_MsmLineRxTooLongErrorsCounterRegister_HHD +#define AQ_MsmLineRxUnicastFramesCounterRegister_BiggestVersion AQ_MsmLineRxUnicastFramesCounterRegister_HHD +#define AQ_MsmLineRxVlanFramesCounterRegister_BiggestVersion AQ_MsmLineRxVlanFramesCounterRegister_HHD +#define AQ_MsmLineTxBroadcastFramesCounterRegister_BiggestVersion AQ_MsmLineTxBroadcastFramesCounterRegister_HHD +#define AQ_MsmLineTxErrorsCounterRegister_BiggestVersion AQ_MsmLineTxErrorsCounterRegister_HHD +#define AQ_MsmLineTxGoodFramesCounterRegister_BiggestVersion AQ_MsmLineTxGoodFramesCounterRegister_HHD +#define AQ_MsmLineTxIpgControlRegister_BiggestVersion AQ_MsmLineTxIpgControlRegister_HHD +#define AQ_MsmLineTxMulticastFramesCounterRegister_BiggestVersion AQ_MsmLineTxMulticastFramesCounterRegister_HHD +#define AQ_MsmLineTxOctetsCounterRegister_BiggestVersion AQ_MsmLineTxOctetsCounterRegister_HHD +#define AQ_MsmLineTxPauseFramesCounterRegister_BiggestVersion AQ_MsmLineTxPauseFramesCounterRegister_HHD +#define AQ_MsmLineTxUnicastFramesCounterRegister_BiggestVersion AQ_MsmLineTxUnicastFramesCounterRegister_HHD +#define AQ_MsmLineTxVlanFramesCounterRegister_BiggestVersion AQ_MsmLineTxVlanFramesCounterRegister_HHD +#define AQ_MsmSystemFifoControlRegister_BiggestVersion AQ_MsmSystemFifoControlRegister_HHD +#define AQ_MsmSystemGeneralControlRegister_BiggestVersion AQ_MsmSystemGeneralControlRegister_HHD +#define AQ_MsmSystemGeneralStatusRegister_BiggestVersion AQ_MsmSystemGeneralStatusRegister_HHD +#define AQ_MsmSystemRxAlignmentErrorsCounterRegister_BiggestVersion AQ_MsmSystemRxAlignmentErrorsCounterRegister_HHD +#define AQ_MsmSystemRxBroadcastFramesCounterRegister_BiggestVersion AQ_MsmSystemRxBroadcastFramesCounterRegister_HHD +#define AQ_MsmSystemRxErrorsCounterRegister_BiggestVersion AQ_MsmSystemRxErrorsCounterRegister_HHD +#define AQ_MsmSystemRxFcsErrorsCounterRegister_BiggestVersion AQ_MsmSystemRxFcsErrorsCounterRegister_HHD +#define AQ_MsmSystemRxGoodFramesCounterRegister_BiggestVersion AQ_MsmSystemRxGoodFramesCounterRegister_HHD +#define AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_BiggestVersion AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_HHD +#define AQ_MsmSystemRxMulticastFramesCounterRegister_BiggestVersion AQ_MsmSystemRxMulticastFramesCounterRegister_HHD +#define AQ_MsmSystemRxOctetsCounterRegister_BiggestVersion AQ_MsmSystemRxOctetsCounterRegister_HHD +#define AQ_MsmSystemRxPauseFramesCounterRegister_BiggestVersion AQ_MsmSystemRxPauseFramesCounterRegister_HHD +#define AQ_MsmSystemRxTooLongErrorsCounterRegister_BiggestVersion AQ_MsmSystemRxTooLongErrorsCounterRegister_HHD +#define AQ_MsmSystemRxUnicastFramesCounterRegister_BiggestVersion AQ_MsmSystemRxUnicastFramesCounterRegister_HHD +#define AQ_MsmSystemRxVlanFramesCounterRegister_BiggestVersion AQ_MsmSystemRxVlanFramesCounterRegister_HHD +#define AQ_MsmSystemTxBroadcastFramesCounterRegister_BiggestVersion AQ_MsmSystemTxBroadcastFramesCounterRegister_HHD +#define AQ_MsmSystemTxErrorsCounterRegister_BiggestVersion AQ_MsmSystemTxErrorsCounterRegister_HHD +#define AQ_MsmSystemTxGoodFramesCounterRegister_BiggestVersion AQ_MsmSystemTxGoodFramesCounterRegister_HHD +#define AQ_MsmSystemTxIpgControlRegister_BiggestVersion AQ_MsmSystemTxIpgControlRegister_HHD +#define AQ_MsmSystemTxMulticastFramesCounterRegister_BiggestVersion AQ_MsmSystemTxMulticastFramesCounterRegister_HHD +#define AQ_MsmSystemTxOctetsCounterRegister_BiggestVersion AQ_MsmSystemTxOctetsCounterRegister_HHD +#define AQ_MsmSystemTxPauseFramesCounterRegister_BiggestVersion AQ_MsmSystemTxPauseFramesCounterRegister_HHD +#define AQ_MsmSystemTxUnicastFramesCounterRegister_BiggestVersion AQ_MsmSystemTxUnicastFramesCounterRegister_HHD +#define AQ_MsmSystemTxVlanFramesCounterRegister_BiggestVersion AQ_MsmSystemTxVlanFramesCounterRegister_HHD +#define AQ_MssEgressControlRegister_BiggestVersion AQ_MssEgressControlRegister_HHD +#define AQ_MssEgressEccInterruptStatusRegister_BiggestVersion AQ_MssEgressEccInterruptStatusRegister_HHD +#define AQ_MssEgressInterruptMaskRegister_BiggestVersion AQ_MssEgressInterruptMaskRegister_HHD +#define AQ_MssEgressInterruptStatusRegister_BiggestVersion AQ_MssEgressInterruptStatusRegister_HHD +#define AQ_MssEgressLutAddressControlRegister_BiggestVersion AQ_MssEgressLutAddressControlRegister_HHD +#define AQ_MssEgressLutControlRegister_BiggestVersion AQ_MssEgressLutControlRegister_HHD +#define AQ_MssEgressLutDataControlRegister_BiggestVersion AQ_MssEgressLutDataControlRegister_HHD +#define AQ_MssEgressMtuSizeControlRegister_BiggestVersion AQ_MssEgressMtuSizeControlRegister_HHD +#define AQ_MssEgressPnControlRegister_BiggestVersion AQ_MssEgressPnControlRegister_HHD +#define AQ_MssEgressSaExpiredStatusRegister_BiggestVersion AQ_MssEgressSaExpiredStatusRegister_HHD +#define AQ_MssEgressSaThresholdExpiredStatusRegister_BiggestVersion AQ_MssEgressSaThresholdExpiredStatusRegister_HHD +#define AQ_MssEgressVlanControlRegister_BiggestVersion AQ_MssEgressVlanControlRegister_HHD +#define AQ_MssEgressVlanTpid_0Register_BiggestVersion AQ_MssEgressVlanTpid_0Register_HHD +#define AQ_MssEgressVlanTpid_1Register_BiggestVersion AQ_MssEgressVlanTpid_1Register_HHD +#define AQ_MssIngressControlRegister_BiggestVersion AQ_MssIngressControlRegister_HHD +#define AQ_MssIngressEccInterruptStatusRegister_BiggestVersion AQ_MssIngressEccInterruptStatusRegister_HHD +#define AQ_MssIngressInterruptMaskRegister_BiggestVersion AQ_MssIngressInterruptMaskRegister_HHD +#define AQ_MssIngressInterruptStatusRegister_BiggestVersion AQ_MssIngressInterruptStatusRegister_HHD +#define AQ_MssIngressLutAddressControlRegister_BiggestVersion AQ_MssIngressLutAddressControlRegister_HHD +#define AQ_MssIngressLutControlRegister_BiggestVersion AQ_MssIngressLutControlRegister_HHD +#define AQ_MssIngressLutDataControlRegister_BiggestVersion AQ_MssIngressLutDataControlRegister_HHD +#define AQ_MssIngressMtuSizeControlRegister_BiggestVersion AQ_MssIngressMtuSizeControlRegister_HHD +#define AQ_MssIngressSaControlRegister_BiggestVersion AQ_MssIngressSaControlRegister_HHD +#define AQ_MssIngressSaExpiredStatusRegister_BiggestVersion AQ_MssIngressSaExpiredStatusRegister_HHD +#define AQ_MssIngressSaIcvErrorStatusRegister_BiggestVersion AQ_MssIngressSaIcvErrorStatusRegister_HHD +#define AQ_MssIngressSaReplayErrorStatusRegister_BiggestVersion AQ_MssIngressSaReplayErrorStatusRegister_HHD +#define AQ_MssIngressSaThresholdExpiredStatusRegister_BiggestVersion AQ_MssIngressSaThresholdExpiredStatusRegister_HHD +#define AQ_MssIngressVlanControlRegister_BiggestVersion AQ_MssIngressVlanControlRegister_HHD +#define AQ_MssIngressVlanTpid_0Register_BiggestVersion AQ_MssIngressVlanTpid_0Register_HHD +#define AQ_MssIngressVlanTpid_1Register_BiggestVersion AQ_MssIngressVlanTpid_1Register_HHD +#define AQ_Pcs10GBaseT_Status_BiggestVersion AQ_Pcs10GBaseT_Status_APPIA +#define AQ_Pcs10G_Status_BiggestVersion AQ_Pcs10G_Status_HHD +#define AQ_Pcs10G_base_rPcsTest_patternControl_BiggestVersion AQ_Pcs10G_base_rPcsTest_patternControl_HHD +#define AQ_Pcs10G_base_rPcsTest_patternErrorCounter_BiggestVersion AQ_Pcs10G_base_rPcsTest_patternErrorCounter_HHD +#define AQ_Pcs10G_base_rTestPatternSeedA_BiggestVersion AQ_Pcs10G_base_rTestPatternSeedA_HHD +#define AQ_Pcs10G_base_rTestPatternSeedB_BiggestVersion AQ_Pcs10G_base_rTestPatternSeedB_HHD +#define AQ_PcsEeeCapabilityRegister_BiggestVersion AQ_PcsEeeCapabilityRegister_HHD +#define AQ_PcsEeeWakeErrorCounter_BiggestVersion AQ_PcsEeeWakeErrorCounter_HHD +#define AQ_PcsReceiveStandardInterruptMask_BiggestVersion AQ_PcsReceiveStandardInterruptMask_APPIA +#define AQ_PcsReceiveVendorAlarms_BiggestVersion AQ_PcsReceiveVendorAlarms_HHD +#define AQ_PcsReceiveVendorCorrectedFrame_1IterationCounter_BiggestVersion AQ_PcsReceiveVendorCorrectedFrame_1IterationCounter_HHD +#define AQ_PcsReceiveVendorCorrectedFrame_2IterationCounter_BiggestVersion AQ_PcsReceiveVendorCorrectedFrame_2IterationCounter_HHD +#define AQ_PcsReceiveVendorCorrectedFrame_3IterationCounter_BiggestVersion AQ_PcsReceiveVendorCorrectedFrame_3IterationCounter_HHD +#define AQ_PcsReceiveVendorCorrectedFrame_4IterationCounter_BiggestVersion AQ_PcsReceiveVendorCorrectedFrame_4IterationCounter_HHD +#define AQ_PcsReceiveVendorCorrectedFrame_5IterationCounter_BiggestVersion AQ_PcsReceiveVendorCorrectedFrame_5IterationCounter_HHD +#define AQ_PcsReceiveVendorCorrectedFrame_6IterationCounter_BiggestVersion AQ_PcsReceiveVendorCorrectedFrame_6IterationCounter_HHD +#define AQ_PcsReceiveVendorCorrectedFrame_7IterationCounter_BiggestVersion AQ_PcsReceiveVendorCorrectedFrame_7IterationCounter_HHD +#define AQ_PcsReceiveVendorCorrectedFrame_8IterationCounter_BiggestVersion AQ_PcsReceiveVendorCorrectedFrame_8IterationCounter_HHD +#define AQ_PcsReceiveVendorCrc_8ErrorCounter_BiggestVersion AQ_PcsReceiveVendorCrc_8ErrorCounter_HHD +#define AQ_PcsReceiveVendorDebug_BiggestVersion AQ_PcsReceiveVendorDebug_HHD +#define AQ_PcsReceiveVendorFcsErrorFrameCounter_BiggestVersion AQ_PcsReceiveVendorFcsErrorFrameCounter_HHD +#define AQ_PcsReceiveVendorFcsNoErrorFrameCounter_BiggestVersion AQ_PcsReceiveVendorFcsNoErrorFrameCounter_HHD +#define AQ_PcsReceiveVendorInterruptMask_BiggestVersion AQ_PcsReceiveVendorInterruptMask_HHD +#define AQ_PcsReceiveVendorProvisioning_BiggestVersion AQ_PcsReceiveVendorProvisioning_HHD +#define AQ_PcsReceiveVendorState_BiggestVersion AQ_PcsReceiveVendorState_HHD +#define AQ_PcsReceiveVendorUncorrectedFrameCounter_BiggestVersion AQ_PcsReceiveVendorUncorrectedFrameCounter_HHD +#define AQ_PcsReceiveXfi0Provisioning_BiggestVersion AQ_PcsReceiveXfi0Provisioning_HHD +#define AQ_PcsReceiveXfi0VendorState_BiggestVersion AQ_PcsReceiveXfi0VendorState_HHD +#define AQ_PcsReceiveXfi1Provisioning_BiggestVersion AQ_PcsReceiveXfi1Provisioning_HHD +#define AQ_PcsReceiveXfi1VendorState_BiggestVersion AQ_PcsReceiveXfi1VendorState_HHD +#define AQ_PcsSerdesMuxSwapTxrxRegister_BiggestVersion AQ_PcsSerdesMuxSwapTxrxRegister_HHD +#define AQ_PcsStandardControl_1_BiggestVersion AQ_PcsStandardControl_1_HHD +#define AQ_PcsStandardControl_2_BiggestVersion AQ_PcsStandardControl_2_HHD +#define AQ_PcsStandardDeviceIdentifier_BiggestVersion AQ_PcsStandardDeviceIdentifier_HHD +#define AQ_PcsStandardDevicesInPackage_BiggestVersion AQ_PcsStandardDevicesInPackage_HHD +#define AQ_PcsStandardInterruptMask_BiggestVersion AQ_PcsStandardInterruptMask_HHD +#define AQ_PcsStandardPackageIdentifier_BiggestVersion AQ_PcsStandardPackageIdentifier_HHD +#define AQ_PcsStandardSpeedAbility_BiggestVersion AQ_PcsStandardSpeedAbility_HHD +#define AQ_PcsStandardStatus_1_BiggestVersion AQ_PcsStandardStatus_1_HHD +#define AQ_PcsStandardStatus_2_BiggestVersion AQ_PcsStandardStatus_2_HHD +#define AQ_PcsTransmitReservedVendorProvisioning_BiggestVersion AQ_PcsTransmitReservedVendorProvisioning_HHD +#define AQ_PcsTransmitVendorAlarms_BiggestVersion AQ_PcsTransmitVendorAlarms_APPIA +#define AQ_PcsTransmitVendorDebug_BiggestVersion AQ_PcsTransmitVendorDebug_HHD +#define AQ_PcsTransmitVendorFcsErrorFrameCounter_BiggestVersion AQ_PcsTransmitVendorFcsErrorFrameCounter_HHD +#define AQ_PcsTransmitVendorFcsNoErrorFrameCounter_BiggestVersion AQ_PcsTransmitVendorFcsNoErrorFrameCounter_HHD +#define AQ_PcsTransmitVendorInterruptMask_BiggestVersion AQ_PcsTransmitVendorInterruptMask_APPIA +#define AQ_PcsTransmitVendorProvisioning_BiggestVersion AQ_PcsTransmitVendorProvisioning_HHD +#define AQ_PcsTransmitXfi0VendorProvisioning_BiggestVersion AQ_PcsTransmitXfi0VendorProvisioning_HHD +#define AQ_PcsTransmitXfi0VendorState_BiggestVersion AQ_PcsTransmitXfi0VendorState_HHD +#define AQ_PcsTransmitXfi1VendorProvisioning_BiggestVersion AQ_PcsTransmitXfi1VendorProvisioning_HHD +#define AQ_PcsTransmitXfi1VendorState_BiggestVersion AQ_PcsTransmitXfi1VendorState_HHD +#define AQ_PcsTransmitXfiVendorProvisioning_BiggestVersion AQ_PcsTransmitXfiVendorProvisioning_HHD +#define AQ_PcsTransmitXgsVendorState_BiggestVersion AQ_PcsTransmitXgsVendorState_HHD +#define AQ_PcsVendorGlobalInterruptFlags_BiggestVersion AQ_PcsVendorGlobalInterruptFlags_HHD +#define AQ_PhyXS_EeeCapabilityRegister_BiggestVersion AQ_PhyXS_EeeCapabilityRegister_HHD +#define AQ_PhyXS_EeeWakeErrorCounter_BiggestVersion AQ_PhyXS_EeeWakeErrorCounter_HHD +#define AQ_PhyXS_Receive_xauiTx_PcsStatus_BiggestVersion AQ_PhyXS_Receive_xauiTx_PcsStatus_HHD +#define AQ_PhyXS_Receive_xauiTx_ReservedVendorProvisioning_BiggestVersion AQ_PhyXS_Receive_xauiTx_ReservedVendorProvisioning_HHD +#define AQ_PhyXS_Receive_xauiTx_VendorAlarms_BiggestVersion AQ_PhyXS_Receive_xauiTx_VendorAlarms_HHD +#define AQ_PhyXS_Receive_xauiTx_VendorDebug_BiggestVersion AQ_PhyXS_Receive_xauiTx_VendorDebug_HHD +#define AQ_PhyXS_Receive_xauiTx_VendorInterruptMask_BiggestVersion AQ_PhyXS_Receive_xauiTx_VendorInterruptMask_HHD +#define AQ_PhyXS_SerdesConfiguration_BiggestVersion AQ_PhyXS_SerdesConfiguration_HHD +#define AQ_PhyXS_SerdesLane_0Configuration_BiggestVersion AQ_PhyXS_SerdesLane_0Configuration_HHD +#define AQ_PhyXS_SerdesLane_1Configuration_BiggestVersion AQ_PhyXS_SerdesLane_1Configuration_HHD +#define AQ_PhyXS_SerdesLane_2Configuration_BiggestVersion AQ_PhyXS_SerdesLane_2Configuration_HHD +#define AQ_PhyXS_SerdesLane_3Configuration_BiggestVersion AQ_PhyXS_SerdesLane_3Configuration_HHD +#define AQ_PhyXS_SerdesLut_BiggestVersion AQ_PhyXS_SerdesLut_HHD +#define AQ_PhyXS_StandardControl_1_BiggestVersion AQ_PhyXS_StandardControl_1_HHD +#define AQ_PhyXS_StandardDeviceIdentifier_BiggestVersion AQ_PhyXS_StandardDeviceIdentifier_HHD +#define AQ_PhyXS_StandardDevicesInPackage_BiggestVersion AQ_PhyXS_StandardDevicesInPackage_HHD +#define AQ_PhyXS_StandardPackageIdentifier_BiggestVersion AQ_PhyXS_StandardPackageIdentifier_HHD +#define AQ_PhyXS_StandardSpeedAbility_BiggestVersion AQ_PhyXS_StandardSpeedAbility_HHD +#define AQ_PhyXS_StandardStatus_1_BiggestVersion AQ_PhyXS_StandardStatus_1_HHD +#define AQ_PhyXS_StandardStatus_2_BiggestVersion AQ_PhyXS_StandardStatus_2_HHD +#define AQ_PhyXS_StandardXGXS_LaneStatus_BiggestVersion AQ_PhyXS_StandardXGXS_LaneStatus_HHD +#define AQ_PhyXS_StandardXGXS_TestControl_BiggestVersion AQ_PhyXS_StandardXGXS_TestControl_HHD +#define AQ_PhyXS_SystemInterfaceConnectionStatus_BiggestVersion AQ_PhyXS_SystemInterfaceConnectionStatus_HHD +#define AQ_PhyXS_Transmit_xauiRx_PcsStatus_BiggestVersion AQ_PhyXS_Transmit_xauiRx_PcsStatus_HHD +#define AQ_PhyXS_Transmit_xauiRx_ReservedVendorProvisioning_BiggestVersion AQ_PhyXS_Transmit_xauiRx_ReservedVendorProvisioning_HHD +#define AQ_PhyXS_Transmit_xauiRx_ReservedVendorState_BiggestVersion AQ_PhyXS_Transmit_xauiRx_ReservedVendorState_HHD +#define AQ_PhyXS_Transmit_xauiRx_StandardInterruptMask_BiggestVersion AQ_PhyXS_Transmit_xauiRx_StandardInterruptMask_HHD +#define AQ_PhyXS_Transmit_xauiRx_TestPatternErrorCounter_BiggestVersion AQ_PhyXS_Transmit_xauiRx_TestPatternErrorCounter_HHD +#define AQ_PhyXS_Transmit_xauiRx_VendorAlarms_BiggestVersion AQ_PhyXS_Transmit_xauiRx_VendorAlarms_HHD +#define AQ_PhyXS_Transmit_xauiRx_VendorDebug_BiggestVersion AQ_PhyXS_Transmit_xauiRx_VendorDebug_HHD +#define AQ_PhyXS_Transmit_xauiRx_VendorInterruptMask_BiggestVersion AQ_PhyXS_Transmit_xauiRx_VendorInterruptMask_HHD +#define AQ_PhyXS_VendorGlobalInterruptFlags_BiggestVersion AQ_PhyXS_VendorGlobalInterruptFlags_HHD +#define AQ_PifMailboxControl_BiggestVersion AQ_PifMailboxControl_HHD +#define AQ_Pma10GBaseT_FastRetrainStatusAndControl_BiggestVersion AQ_Pma10GBaseT_FastRetrainStatusAndControl_HHD +#define AQ_Pma10GBaseT_PairSwapAndPolarityStatus_BiggestVersion AQ_Pma10GBaseT_PairSwapAndPolarityStatus_HHD +#define AQ_Pma10GBaseT_ReceiveSignalPowerChannelA_BiggestVersion AQ_Pma10GBaseT_ReceiveSignalPowerChannelA_HHD +#define AQ_Pma10GBaseT_ReceiveSignalPowerChannelB_BiggestVersion AQ_Pma10GBaseT_ReceiveSignalPowerChannelB_HHD +#define AQ_Pma10GBaseT_ReceiveSignalPowerChannelC_BiggestVersion AQ_Pma10GBaseT_ReceiveSignalPowerChannelC_HHD +#define AQ_Pma10GBaseT_ReceiveSignalPowerChannelD_BiggestVersion AQ_Pma10GBaseT_ReceiveSignalPowerChannelD_HHD +#define AQ_Pma10GBaseT_SNR_MinimumOperatingMarginChannelA_BiggestVersion AQ_Pma10GBaseT_SNR_MinimumOperatingMarginChannelA_HHD +#define AQ_Pma10GBaseT_SNR_MinimumOperatingMarginChannelB_BiggestVersion AQ_Pma10GBaseT_SNR_MinimumOperatingMarginChannelB_HHD +#define AQ_Pma10GBaseT_SNR_MinimumOperatingMarginChannelC_BiggestVersion AQ_Pma10GBaseT_SNR_MinimumOperatingMarginChannelC_HHD +#define AQ_Pma10GBaseT_SNR_MinimumOperatingMarginChannelD_BiggestVersion AQ_Pma10GBaseT_SNR_MinimumOperatingMarginChannelD_HHD +#define AQ_Pma10GBaseT_SNR_OperatingMarginChannelA_BiggestVersion AQ_Pma10GBaseT_SNR_OperatingMarginChannelA_HHD +#define AQ_Pma10GBaseT_SNR_OperatingMarginChannelB_BiggestVersion AQ_Pma10GBaseT_SNR_OperatingMarginChannelB_HHD +#define AQ_Pma10GBaseT_SNR_OperatingMarginChannelC_BiggestVersion AQ_Pma10GBaseT_SNR_OperatingMarginChannelC_HHD +#define AQ_Pma10GBaseT_SNR_OperatingMarginChannelD_BiggestVersion AQ_Pma10GBaseT_SNR_OperatingMarginChannelD_HHD +#define AQ_Pma10GBaseT_SkewDelay_BiggestVersion AQ_Pma10GBaseT_SkewDelay_HHD +#define AQ_Pma10GBaseT_Status_BiggestVersion AQ_Pma10GBaseT_Status_HHD +#define AQ_Pma10GBaseT_TestModes_BiggestVersion AQ_Pma10GBaseT_TestModes_HHD +#define AQ_Pma10GBaseT_TxPowerBackoffAndShortReachSetting_BiggestVersion AQ_Pma10GBaseT_TxPowerBackoffAndShortReachSetting_HHD +#define AQ_PmaReceiveReservedVendorProvisioning_BiggestVersion AQ_PmaReceiveReservedVendorProvisioning_HHD +#define AQ_PmaReceiveReservedVendorState_BiggestVersion AQ_PmaReceiveReservedVendorState_HHD +#define AQ_PmaReceiveVendorState_BiggestVersion AQ_PmaReceiveVendorState_HHD +#define AQ_PmaStandardControl_1_BiggestVersion AQ_PmaStandardControl_1_HHD +#define AQ_PmaStandardControl_2_BiggestVersion AQ_PmaStandardControl_2_HHD +#define AQ_PmaStandardDeviceIdentifier_BiggestVersion AQ_PmaStandardDeviceIdentifier_HHD +#define AQ_PmaStandardDevicesInPackage_BiggestVersion AQ_PmaStandardDevicesInPackage_HHD +#define AQ_PmaStandardPackageIdentifier_BiggestVersion AQ_PmaStandardPackageIdentifier_HHD +#define AQ_PmaStandardSpeedAbility_BiggestVersion AQ_PmaStandardSpeedAbility_HHD +#define AQ_PmaStandardStatus_1_BiggestVersion AQ_PmaStandardStatus_1_HHD +#define AQ_PmaStandardStatus_2_BiggestVersion AQ_PmaStandardStatus_2_HHD +#define AQ_PmaTransmitReservedVendorProvisioning_BiggestVersion AQ_PmaTransmitReservedVendorProvisioning_HHD +#define AQ_PmaTransmitStandardInterruptMask_BiggestVersion AQ_PmaTransmitStandardInterruptMask_HHD +#define AQ_PmaTransmitVendorAlarms_BiggestVersion AQ_PmaTransmitVendorAlarms_HHD +#define AQ_PmaTransmitVendorDebug_BiggestVersion AQ_PmaTransmitVendorDebug_HHD +#define AQ_PmaTransmitVendorLASI_InterruptMask_BiggestVersion AQ_PmaTransmitVendorLASI_InterruptMask_HHD +#define AQ_PmaVendorGlobalInterruptFlags_BiggestVersion AQ_PmaVendorGlobalInterruptFlags_HHD +#define AQ_PmdStandard10G_ExtendedAbilityRegister_BiggestVersion AQ_PmdStandard10G_ExtendedAbilityRegister_HHD +#define AQ_PmdStandardSignalDetect_BiggestVersion AQ_PmdStandardSignalDetect_HHD +#define AQ_PmdStandardTransmitDisableControl_BiggestVersion AQ_PmdStandardTransmitDisableControl_HHD +#define AQ_Sgmii0WolStatus_BiggestVersion AQ_Sgmii0WolStatus_HHD +#define AQ_TimesyncPcsCapability_BiggestVersion AQ_TimesyncPcsCapability_HHD +#define AQ_TimesyncPcsReceivePathDataDelay_BiggestVersion AQ_TimesyncPcsReceivePathDataDelay_HHD +#define AQ_TimesyncPcsTransmitPathDataDelay_BiggestVersion AQ_TimesyncPcsTransmitPathDataDelay_HHD +#define AQ_TimesyncPhyXsCapability_BiggestVersion AQ_TimesyncPhyXsCapability_HHD +#define AQ_TimesyncPhyXsReceivePathDataDelay_BiggestVersion AQ_TimesyncPhyXsReceivePathDataDelay_HHD +#define AQ_TimesyncPhyXsTransmitPathDataDelay_BiggestVersion AQ_TimesyncPhyXsTransmitPathDataDelay_HHD +#define AQ_TimesyncPmaCapability_BiggestVersion AQ_TimesyncPmaCapability_HHD +#define AQ_TimesyncPmaReceivePathDataDelay_BiggestVersion AQ_TimesyncPmaReceivePathDataDelay_HHD +#define AQ_TimesyncPmaTransmitPathDataDelay_BiggestVersion AQ_TimesyncPmaTransmitPathDataDelay_HHD +#define AQ_XenpakBasic_ApsLoading_BiggestVersion AQ_XenpakBasic_ApsLoading_HHD +#define AQ_XenpakBasic_ApsVoltage_BiggestVersion AQ_XenpakBasic_ApsVoltage_HHD +#define AQ_XenpakBasic_BitRate_BiggestVersion AQ_XenpakBasic_BitRate_HHD +#define AQ_XenpakBasic_Checksum_BiggestVersion AQ_XenpakBasic_Checksum_HHD +#define AQ_XenpakBasic_ConnectorType_BiggestVersion AQ_XenpakBasic_ConnectorType_HHD +#define AQ_XenpakBasic_DomCapability_BiggestVersion AQ_XenpakBasic_DomCapability_HHD +#define AQ_XenpakBasic_Encoding_BiggestVersion AQ_XenpakBasic_Encoding_HHD +#define AQ_XenpakBasic_Low_powerStartupCapability_BiggestVersion AQ_XenpakBasic_Low_powerStartupCapability_HHD +#define AQ_XenpakBasic_PackageIdentifier_BiggestVersion AQ_XenpakBasic_PackageIdentifier_HHD +#define AQ_XenpakBasic_Protocol_BiggestVersion AQ_XenpakBasic_Protocol_HHD +#define AQ_XenpakBasic_Reserved_0x11_BiggestVersion AQ_XenpakBasic_Reserved_0x11_HHD +#define AQ_XenpakBasic_Reserved_0x19_BiggestVersion AQ_XenpakBasic_Reserved_0x19_HHD +#define AQ_XenpakBasic_Reserved_0x7c_BiggestVersion AQ_XenpakBasic_Reserved_0x7c_HHD +#define AQ_XenpakBasic_StandardsComplianceCodes_BiggestVersion AQ_XenpakBasic_StandardsComplianceCodes_HHD +#define AQ_XenpakBasic_TransceiverType_BiggestVersion AQ_XenpakBasic_TransceiverType_HHD +#define AQ_XenpakBasic_VendorDateCode_BiggestVersion AQ_XenpakBasic_VendorDateCode_HHD +#define AQ_XenpakBasic_VendorIdentifier_BiggestVersion AQ_XenpakBasic_VendorIdentifier_HHD +#define AQ_XenpakBasic_VendorName_BiggestVersion AQ_XenpakBasic_VendorName_HHD +#define AQ_XenpakBasic_VendorPartNumber_BiggestVersion AQ_XenpakBasic_VendorPartNumber_HHD +#define AQ_XenpakBasic_VendorPartRevisionNumber_BiggestVersion AQ_XenpakBasic_VendorPartRevisionNumber_HHD +#define AQ_XenpakBasic_VendorSerialNumber_BiggestVersion AQ_XenpakBasic_VendorSerialNumber_HHD +#define AQ_XenpakBasic__3_3vLoading_BiggestVersion AQ_XenpakBasic__3_3vLoading_HHD +#define AQ_XenpakBasic__5vLoading_BiggestVersion AQ_XenpakBasic__5vLoading_HHD +#define AQ_XenpakControl_BiggestVersion AQ_XenpakControl_HHD +#define AQ_XenpakCustomer_Reserved_0x7e_BiggestVersion AQ_XenpakCustomer_Reserved_0x7e_HHD +#define AQ_XenpakDom_Alarms_BiggestVersion AQ_XenpakDom_Alarms_HHD +#define AQ_XenpakDom_Capability_BiggestVersion AQ_XenpakDom_Capability_HHD +#define AQ_XenpakDom_ControlAndStatus_BiggestVersion AQ_XenpakDom_ControlAndStatus_HHD +#define AQ_XenpakDom_HighTemperatureAlarmThresholdLSW_BiggestVersion AQ_XenpakDom_HighTemperatureAlarmThresholdLSW_HHD +#define AQ_XenpakDom_HighTemperatureAlarmThresholdMSW_BiggestVersion AQ_XenpakDom_HighTemperatureAlarmThresholdMSW_HHD +#define AQ_XenpakDom_HighTemperatureWarningThresholdLSW_BiggestVersion AQ_XenpakDom_HighTemperatureWarningThresholdLSW_HHD +#define AQ_XenpakDom_HighTemperatureWarningThresholdMSW_BiggestVersion AQ_XenpakDom_HighTemperatureWarningThresholdMSW_HHD +#define AQ_XenpakDom_LowTemperatureAlarmThresholdLSW_BiggestVersion AQ_XenpakDom_LowTemperatureAlarmThresholdLSW_HHD +#define AQ_XenpakDom_LowTemperatureAlarmThresholdMSW_BiggestVersion AQ_XenpakDom_LowTemperatureAlarmThresholdMSW_HHD +#define AQ_XenpakDom_LowTemperatureWarningThresholdLSW_BiggestVersion AQ_XenpakDom_LowTemperatureWarningThresholdLSW_HHD +#define AQ_XenpakDom_LowTemperatureWarningThresholdMSW_BiggestVersion AQ_XenpakDom_LowTemperatureWarningThresholdMSW_HHD +#define AQ_XenpakDom_Status_BiggestVersion AQ_XenpakDom_Status_HHD +#define AQ_XenpakDom_TemperatureLSW_BiggestVersion AQ_XenpakDom_TemperatureLSW_HHD +#define AQ_XenpakDom_TemperatureMSW_BiggestVersion AQ_XenpakDom_TemperatureMSW_HHD +#define AQ_XenpakDom_TxControl_BiggestVersion AQ_XenpakDom_TxControl_HHD +#define AQ_XenpakHeader_BasicMemoryStartAddress_BiggestVersion AQ_XenpakHeader_BasicMemoryStartAddress_HHD +#define AQ_XenpakHeader_CustomerMemoryOffset_BiggestVersion AQ_XenpakHeader_CustomerMemoryOffset_HHD +#define AQ_XenpakHeader_ExtendedVendorMemoryOffset_BiggestVersion AQ_XenpakHeader_ExtendedVendorMemoryOffset_HHD +#define AQ_XenpakHeader_MemoryUsed_BiggestVersion AQ_XenpakHeader_MemoryUsed_HHD +#define AQ_XenpakHeader_NvrSize_BiggestVersion AQ_XenpakHeader_NvrSize_HHD +#define AQ_XenpakHeader_VendorMemoryStartAddress_BiggestVersion AQ_XenpakHeader_VendorMemoryStartAddress_HHD +#define AQ_XenpakHeader_XenpakMsaVersionSupported_BiggestVersion AQ_XenpakHeader_XenpakMsaVersionSupported_HHD +#define AQ_XenpakLASI__Control_BiggestVersion AQ_XenpakLASI__Control_HHD +#define AQ_XenpakLASI__Status_BiggestVersion AQ_XenpakLASI__Status_HHD +#define AQ_XenpakRxAlarm_Control_BiggestVersion AQ_XenpakRxAlarm_Control_HHD +#define AQ_XenpakRxAlarm_Status_BiggestVersion AQ_XenpakRxAlarm_Status_HHD +#define AQ_XenpakTxAlarm_Control_BiggestVersion AQ_XenpakTxAlarm_Control_HHD +#define AQ_XenpakTxAlarm_Status_BiggestVersion AQ_XenpakTxAlarm_Status_HHD +#define AQ_XenpakVendor_Reserved_0xae_BiggestVersion AQ_XenpakVendor_Reserved_0xae_HHD + +#endif diff --git a/feeds/ipq807x/aq-fw-download/src/include/registerMap/AQ_RegMaps.h b/feeds/ipq807x/aq-fw-download/src/include/registerMap/AQ_RegMaps.h new file mode 100755 index 000000000..52a24e385 --- /dev/null +++ b/feeds/ipq807x/aq-fw-download/src/include/registerMap/AQ_RegMaps.h @@ -0,0 +1,69 @@ +/*AQ_RegMaps.h*/ + +/************************************************************************************ +* Copyright (c) 2015, Aquantia +* +* Permission to use, copy, modify, and/or distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +* +* Description: +* +* This file contains includes all appropriate Aquantia PHY device-specific +* register map headers. +* +************************************************************************************/ + +/*! \file +* This file contains includes all appropriate Aquantia PHY device-specific +* register map headers. + */ + +#ifndef AQ_REGISTERMAPS_HEADER +#define AQ_REGISTERMAPS_HEADER + +#include "AQ_User.h" +#include "AQ_RegGroupMaxSizes.h" + + +#ifndef AQ_REVERSED_BITFIELD_ORDERING +/* + * Include non-reversed header files (bitfields ordered from LSbit to MSbit) + */ + +/* APPIA */ +#include "AQ_APPIA_Global_registers.h" + +#include "AQ_APPIA_Global_registers_Defines.h" + +/* HHD */ +#include "AQ_HHD_Global_registers.h" + +#include "AQ_HHD_Global_registers_Defines.h" + +#else +/* + * Include reversed header files (bitfields ordered from MSbit to LSbit) + */ + +/* APPIA */ +#include "AQ_APPIA_Global_registers_reversed.h" + +#include "AQ_APPIA_Global_registers_Defines.h" + +/* HHD */ +#include "AQ_HHD_Global_registers_reversed.h" + +#include "AQ_HHD_Global_registers_Defines.h" + +#endif + +#endif diff --git a/feeds/ipq807x/aq-fw-download/src/include/registerMap/HHD/AQ_HHD_Global_registers.h b/feeds/ipq807x/aq-fw-download/src/include/registerMap/HHD/AQ_HHD_Global_registers.h new file mode 100755 index 000000000..e0a2fa27b --- /dev/null +++ b/feeds/ipq807x/aq-fw-download/src/include/registerMap/HHD/AQ_HHD_Global_registers.h @@ -0,0 +1,12123 @@ +/*! \file +* This file contains the data structures and doxygen comments +* for the Global Registers block. + */ + +/*! \addtogroup registerMap + @{ +*/ + +/*! \defgroup Global_registers Global Registers +* This module contains the data structures and doxygen comments +* for the Global Registers block. + */ +/*********************************************************************** +* Copyright (c) 2015, Aquantia +* +* Permission to use, copy, modify, and/or distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +* +* $Date: 2014/04/08 $ +* +* $Label: $ +* +* Description: +* +* This file contains the c header structures for the registers contained in the Global Registers block. +* +* The bit fields in this structure are from LSbit to MSbit +* +***********************************************************************/ + + +/*@{*/ +#ifndef AQ_HHD_GLOBAL_REGS_HEADER +#define AQ_HHD_GLOBAL_REGS_HEADER + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Control 1: 1E.0000 */ +/* Global Standard Control 1: 1E.0000 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Control 1 */ + union + { + struct + { + unsigned int reserved1 : 11; + /*! \brief 1E.0000.B R/WPD Low Power + AQ_GlobalStandardControl_1_HHD.u0.bits_0.lowPower + + Provisionable Default = 0x0 + + 1 = Low-power mode + 0 = Normal operation + + + Notes: + A one written to this register causes the chip to enter low-power mode. This bit puts the entire chip in low-power mode, with only the MDIO and microprocessor functioning, and turns off the analog front-end: i.e. places it in high-impedance mode. Setting this bit also sets all of the Low Power bits in the other MMDs. */ + unsigned int lowPower : 1; /* 1E.0000.B R/WPD Provisionable Default = 0x0 */ + /* 1 = Low-power mode + 0 = Normal operation + */ + unsigned int reserved0 : 3; + /*! \brief 1E.0000.F R/WSC Soft Reset + AQ_GlobalStandardControl_1_HHD.u0.bits_0.softReset + + Default = 0x1 + + 1 = Global soft reset + 0 = Normal operation + + + Notes: + Resets the entire PHY. + Setting this bit initiates a global soft reset on all of the digital logic not including the microprocessor (i.e. microprocessor is not reset). Upon completion of the reset sequence, this bit is set back to 0by the microprocessor. Note this bit is OR'ed with the individual MMD resets. This bit should be set to 0 before setting the individual MMD resets. */ + unsigned int softReset : 1; /* 1E.0000.F R/WSC Default = 0x1 */ + /* 1 = Global soft reset + 0 = Normal operation + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalStandardControl_1_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Device Identifier: 1E.0002 */ +/* Global Standard Device Identifier: 1E.0002 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Device Identifier */ + union + { + struct + { + /*! \brief 1E.0002.F:0 RO Device ID MSW [1F:10] + AQ_GlobalStandardDeviceIdentifier_HHD.u0.bits_0.deviceIdMSW + + + + Bits 31 - 16 of Device ID + */ + unsigned int deviceIdMSW : 16; /* 1E.0002.F:0 RO */ + /* Bits 31 - 16 of Device ID */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Standard Device Identifier */ + union + { + struct + { + /*! \brief 1E.0003.F:0 RO Device ID LSW [F:0] + AQ_GlobalStandardDeviceIdentifier_HHD.u1.bits_1.deviceIdLSW + + + + Bits 15 - 0 of Device ID + */ + unsigned int deviceIdLSW : 16; /* 1E.0003.F:0 RO */ + /* Bits 15 - 0 of Device ID */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalStandardDeviceIdentifier_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Devices in Package: 1E.0005 */ +/* Global Standard Devices in Package: 1E.0005 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Devices in Package */ + union + { + struct + { + /*! \brief 1E.0005.0 ROS Clause 22 Registers Present + AQ_GlobalStandardDevicesInPackage_HHD.u0.bits_0.clause_22RegistersPresent + + Default = 0x0 + + 1 = Clause 22 registers are present in package + 0 = Clause 22 registers are not present in package + + Notes: + This is always set to 0 in the PHY, as there are no Clause 22 registers in the device. */ + unsigned int clause_22RegistersPresent : 1; /* 1E.0005.0 ROS Default = 0x0 */ + /* 1 = Clause 22 registers are present in package + 0 = Clause 22 registers are not present in package */ + /*! \brief 1E.0005.1 ROS PMA Present + AQ_GlobalStandardDevicesInPackage_HHD.u0.bits_0.pmaPresent + + Default = 0x1 + + 1 = PMA is present in package + 0 = PMA is not present + + Notes: + This is always set to 1 as there is PMA functionality in the PHY. */ + unsigned int pmaPresent : 1; /* 1E.0005.1 ROS Default = 0x1 */ + /* 1 = PMA is present in package + 0 = PMA is not present */ + /*! \brief 1E.0005.2 ROS WIS Present + AQ_GlobalStandardDevicesInPackage_HHD.u0.bits_0.wisPresent + + Default = 0x0 + + 1 = WIS is present in package + 0 = WIS is not present in package + + Notes: + This is always set to 0, as there is no WIS functionality in the PHY. */ + unsigned int wisPresent : 1; /* 1E.0005.2 ROS Default = 0x0 */ + /* 1 = WIS is present in package + 0 = WIS is not present in package */ + /*! \brief 1E.0005.3 ROS PCS Present + AQ_GlobalStandardDevicesInPackage_HHD.u0.bits_0.pcsPresent + + Default = 0x1 + + 1 = PCS is present in package + 0 = PCS is not present in package + + Notes: + This is always set to 1 as there is PCS functionality in the PHY. */ + unsigned int pcsPresent : 1; /* 1E.0005.3 ROS Default = 0x1 */ + /* 1 = PCS is present in package + 0 = PCS is not present in package */ + /*! \brief 1E.0005.4 ROS PHY XS Present + AQ_GlobalStandardDevicesInPackage_HHD.u0.bits_0.phyXS_Present + + Default = 0x1 + + 1 = PHY XS is present in package + 0 = PHY XS is not present in package + + Notes: + This is always set to 1 as there is a PHY XS interface in the PHY. */ + unsigned int phyXS_Present : 1; /* 1E.0005.4 ROS Default = 0x1 */ + /* 1 = PHY XS is present in package + 0 = PHY XS is not present in package */ + /*! \brief 1E.0005.5 ROS DTE XS Present + AQ_GlobalStandardDevicesInPackage_HHD.u0.bits_0.dteXsPresent + + Default = 0x0 + + 1 = DTE XS is present in package + 0 = DTE XS is not present in package + + + Notes: + This is always set to 0, as there is no DTE XAUI interface in the PHY. */ + unsigned int dteXsPresent : 1; /* 1E.0005.5 ROS Default = 0x0 */ + /* 1 = DTE XS is present in package + 0 = DTE XS is not present in package + */ + /*! \brief 1E.0005.6 ROS TC Present + AQ_GlobalStandardDevicesInPackage_HHD.u0.bits_0.tcPresent + + Default = 0x0 + + 1 = TC is present in package + 0 = TC is not present in package + + Notes: + This is always set to 0, as there is no TC functionality in the PHY. */ + unsigned int tcPresent : 1; /* 1E.0005.6 ROS Default = 0x0 */ + /* 1 = TC is present in package + 0 = TC is not present in package */ + /*! \brief 1E.0005.7 ROS Autonegotiation Present + AQ_GlobalStandardDevicesInPackage_HHD.u0.bits_0.autonegotiationPresent + + Default = 0x1 + + 1 = Autonegotiation is present in package + 0 = Autonegotiation is not present in package + + Notes: + This is always set to 1, as there is Autonegotiation in the PHY. */ + unsigned int autonegotiationPresent : 1; /* 1E.0005.7 ROS Default = 0x1 */ + /* 1 = Autonegotiation is present in package + 0 = Autonegotiation is not present in package */ + unsigned int reserved0 : 8; + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalStandardDevicesInPackage_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Vendor Devices in Package: 1E.0006 */ +/* Global Standard Vendor Devices in Package: 1E.0006 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Vendor Devices in Package */ + union + { + struct + { + unsigned int reserved0 : 13; + /*! \brief 1E.0006.D ROS Clause 22 Extension Present + AQ_GlobalStandardVendorDevicesInPackage_HHD.u0.bits_0.clause_22ExtensionPresent + + Default = 0x1 + + 1 = Clause 22 Extension is present in package + 0 = Clause 22 Extension is not present in package + + Notes: + This is always set to 1 as the PHY utilizes this device for the GbE registers. */ + unsigned int clause_22ExtensionPresent : 1; /* 1E.0006.D ROS Default = 0x1 */ + /* 1 = Clause 22 Extension is present in package + 0 = Clause 22 Extension is not present in package */ + /*! \brief 1E.0006.E ROS Vendor Specific Device #1 Present + AQ_GlobalStandardVendorDevicesInPackage_HHD.u0.bits_0.vendorSpecificDevice_1Present + + Default = 0x1 + + 1 = Device #1 is present in package + 0 = Device #1 is not present in package + + Notes: + This is always set to 1 as the PHY utilizes this device for the global control registers. */ + unsigned int vendorSpecificDevice_1Present : 1; /* 1E.0006.E ROS Default = 0x1 */ + /* 1 = Device #1 is present in package + 0 = Device #1 is not present in package */ + /*! \brief 1E.0006.F ROS Vendor Specific Device #2 Present + AQ_GlobalStandardVendorDevicesInPackage_HHD.u0.bits_0.vendorSpecificDevice_2Present + + Default = 0x1 + + 1 = Device #2 is present in package + 0 = Device #2 is not present in package + + Notes: + This is always set to 1 as the PHY utilizes this device for the DSP PMA registers. */ + unsigned int vendorSpecificDevice_2Present : 1; /* 1E.0006.F ROS Default = 0x1 */ + /* 1 = Device #2 is present in package + 0 = Device #2 is not present in package */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalStandardVendorDevicesInPackage_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Status 2: 1E.0008 */ +/* Global Standard Status 2: 1E.0008 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Status 2 */ + union + { + struct + { + unsigned int reserved0 : 14; + /*! \brief 1E.0008.F:E ROS Device Present [1:0] + AQ_GlobalStandardStatus_2_HHD.u0.bits_0.devicePresent + + Default = 0x2 + + [F:E] + 0x3 = No device at this address + 0x2 = Device present at this address + 0x1 = No device at this address + 0x0 = No device at this address + + Notes: + This field is always set to 0x2, as the Global MMD resides here in the PHY. */ + unsigned int devicePresent : 2; /* 1E.0008.F:E ROS Default = 0x2 */ + /* [F:E] + 0x3 = No device at this address + 0x2 = Device present at this address + 0x1 = No device at this address + 0x0 = No device at this address */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalStandardStatus_2_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Package Identifier: 1E.000E */ +/* Global Standard Package Identifier: 1E.000E */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Package Identifier */ + union + { + struct + { + /*! \brief 1E.000E.F:0 RO Package ID MSW [1F:10] + AQ_GlobalStandardPackageIdentifier_HHD.u0.bits_0.packageIdMSW + + + + Bits 31- 16 of Package ID + */ + unsigned int packageIdMSW : 16; /* 1E.000E.F:0 RO */ + /* Bits 31- 16 of Package ID */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Standard Package Identifier */ + union + { + struct + { + /*! \brief 1E.000F.F:0 RO Package ID LSW [F:0] + AQ_GlobalStandardPackageIdentifier_HHD.u1.bits_1.packageIdLSW + + + + Bits 15 - 0 of Package ID + */ + unsigned int packageIdLSW : 16; /* 1E.000F.F:0 RO */ + /* Bits 15 - 0 of Package ID */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalStandardPackageIdentifier_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Firmware ID: 1E.0020 */ +/* Global Firmware ID: 1E.0020 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Firmware ID */ + union + { + struct + { + /*! \brief 1E.0020.7:0 RO Firmware Minor Revision Number [7:0] + AQ_GlobalFirmwareID_HHD.u0.bits_0.firmwareMinorRevisionNumber + + + + [7:0] = Minor revision number + + Notes: + + + The lower six bits of major and minor firmware revision are exchanged in autonegotiation when the PHYID message is sent. */ + unsigned int firmwareMinorRevisionNumber : 8; /* 1E.0020.7:0 RO */ + /* [7:0] = Minor revision number */ + /*! \brief 1E.0020.F:8 RO Firmware Major Revision Number [7:0] + AQ_GlobalFirmwareID_HHD.u0.bits_0.firmwareMajorRevisionNumber + + + + [F:8] = Major revision number + + Notes: + + + The lower six bits of major and minor firmware revision are exchanged in autonegotiation when the PHYID message is sent. */ + unsigned int firmwareMajorRevisionNumber : 8; /* 1E.0020.F:8 RO */ + /* [F:8] = Major revision number */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalFirmwareID_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global NVR Interface: 1E.0100 */ +/* Global NVR Interface: 1E.0100 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global NVR Interface */ + union + { + struct + { + /*! \brief 1E.0100.7:0 R/W NVR Opcode [7:0] + AQ_GlobalNvrInterface_HHD.u0.bits_0.nvrOpcode + + Default = 0x03 + + NVR instruction opcode + + */ + unsigned int nvrOpcode : 8; /* 1E.0100.7:0 R/W Default = 0x03 */ + /* NVR instruction opcode + */ + /*! \brief 1E.0100.8 RO NVR Busy + AQ_GlobalNvrInterface_HHD.u0.bits_0.nvrBusy + + + + 1 = NVR is busy + 0 = NVR is ready + + + Notes: + When set to 1, the NVR is busy. A new NVR operation should not occur until this bit is 0. If the NVR clock is greater than 64/63 of the MDIO clock, this bit never needs to be polled when operating over the MDIO. */ + unsigned int nvrBusy : 1; /* 1E.0100.8 RO */ + /* 1 = NVR is busy + 0 = NVR is ready + */ + unsigned int reserved1 : 1; + /*! \brief 1E.0100.A R/W NVR Burst + AQ_GlobalNvrInterface_HHD.u0.bits_0.nvrBurst + + Default = 0x0 + + 0 = Single read or write operation of up to 4 bytes + 1 = Burst operation + + + Notes: + When this bit is set, the operation is a burst operation where more than 32-bits is read from the NVR or written to the NVR. This bit should be set to one until the last burst in the read or write operation, when it should be set to zero. It operates by gating the SPI clock, and not restarting it until new data is ready to be written, or the previous contents have been read. Each burst of data requires the NVR Execute Operation bit to be set to initiate the next phase. */ + unsigned int nvrBurst : 1; /* 1E.0100.A R/W Default = 0x0 */ + /* 0 = Single read or write operation of up to 4 bytes + 1 = Burst operation + */ + unsigned int reserved0 : 1; + /*! \brief 1E.0100.C R/WSC Reset NVR CRC + AQ_GlobalNvrInterface_HHD.u0.bits_0.resetNvrCrc + + Default = 0x0 + + 1 = Reset NVR Mailbox CRC calculation register + + + + Notes: + To prevent an erroneous answer, this bit should not be set at the same time the See NVR Operation Valid bit is set. */ + unsigned int resetNvrCrc : 1; /* 1E.0100.C R/WSC Default = 0x0 */ + /* 1 = Reset NVR Mailbox CRC calculation register + + */ + /*! \brief 1E.0100.D R/W Freeze NVR CRC + AQ_GlobalNvrInterface_HHD.u0.bits_0.freezeNvrCrc + + Default = 0x0 + + 1 = Freeze NVR Mailbox CRC calculation register + + + Notes: + To prevent an erroneous answer, this bit should not be set at the same time the See NVR Operation Valid bit is set. */ + unsigned int freezeNvrCrc : 1; /* 1E.0100.D R/W Default = 0x0 */ + /* 1 = Freeze NVR Mailbox CRC calculation register + */ + /*! \brief 1E.0100.E R/W NVR Write Mode + AQ_GlobalNvrInterface_HHD.u0.bits_0.nvrWriteMode + + Default = 0x0 + + 1 = Write to NVR + 0 = Read from NVR + + */ + unsigned int nvrWriteMode : 1; /* 1E.0100.E R/W Default = 0x0 */ + /* 1 = Write to NVR + 0 = Read from NVR + */ + /*! \brief 1E.0100.F R/WSC NVR Execute Operation + AQ_GlobalNvrInterface_HHD.u0.bits_0.nvrExecuteOperation + + Default = 0x0 + + 1 = Start NVR Operation + + + + Notes: + When set to 1, the NVR operation will begin. Ensure that the uP is stalled using the See MCP Run Stall bit to ensure no NVR contention. */ + unsigned int nvrExecuteOperation : 1; /* 1E.0100.F R/WSC Default = 0x0 */ + /* 1 = Start NVR Operation + + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global NVR Interface */ + union + { + struct + { + /*! \brief 1E.0101.F:0 RO NVR Mailbox CRC [F:0] + AQ_GlobalNvrInterface_HHD.u1.bits_1.nvrMailboxCrc + + + + The running CRC-16 of everything passing through the NVR interface + + + Notes: + The CRC-16 over all data written or read through the NVR interface. The CRC-16 is calculated by dividing the data by: + x^16 + x^12 + x^5 + 1 */ + unsigned int nvrMailboxCrc : 16; /* 1E.0101.F:0 RO */ + /* The running CRC-16 of everything passing through the NVR interface + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global NVR Interface */ + union + { + struct + { + /*! \brief 1E.0102.7:0 R/W NVR Address MSW [17:10] + AQ_GlobalNvrInterface_HHD.u2.bits_2.nvrAddressMSW + + Default = 0x00 + + NVR address MSW bits [17:10] + + + Notes: + The address of where to read and write from in the NVR. This is self-incrementing and will automatically increment after each read or write operation. The increment amount is based on the data length (i.e. increments by 4 if the data length is 4 bytes) */ + unsigned int nvrAddressMSW : 8; /* 1E.0102.7:0 R/W Default = 0x00 */ + /* NVR address MSW bits [17:10] + */ + unsigned int reserved0 : 8; + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global NVR Interface */ + union + { + struct + { + /*! \brief 1E.0103.F:0 R/W NVR Address LSW [F:0] + AQ_GlobalNvrInterface_HHD.u3.bits_3.nvrAddressLSW + + Default = 0x0000 + + NVR address LSW bits [F:0] + + + Notes: + The address of where to read and write from in the NVR. This is self-incrementing and will automatically increment after each read or write operation. */ + unsigned int nvrAddressLSW : 16; /* 1E.0103.F:0 R/W Default = 0x0000 */ + /* NVR address LSW bits [F:0] + */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global NVR Interface */ + union + { + struct + { + /*! \brief 1E.0104.F:0 R/W NVR Data MSW [1F:10] + AQ_GlobalNvrInterface_HHD.u4.bits_4.nvrDataMSW + + Default = 0x0000 + + NVR data MSW bits [1F:10] + + + Notes: + Data is stored and read-out from these registers in little-endian format for operations such as FLASH device ID, and for programming the processor. + + For instance the 64K Atmel device code reads out as two bytes 0x651F into the LSW register, whereas the datasheet indicates that 1F is the first byte read, followed by 65 as the second byte. + + To burst read and write these 4 bytes in the correct order (where DD is written to address x), they should be stored as: + + AA BB in the MSW + CC DD in the LSW. */ + unsigned int nvrDataMSW : 16; /* 1E.0104.F:0 R/W Default = 0x0000 */ + /* NVR data MSW bits [1F:10] + */ + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of Global NVR Interface */ + union + { + struct + { + /*! \brief 1E.0105.F:0 R/W NVR Data LSW [F:0] + AQ_GlobalNvrInterface_HHD.u5.bits_5.nvrDataLSW + + Default = 0x0000 + + NVR data LSW bits [F:0] + + + Notes: + Data is stored and read-out from these registers in little-endian format for operations such as FLASH device ID, and for programming the processor. + + For instance the 64K Atmel device code reads out as two bytes 0x651F into the LSW register, whereas the datasheet indicates that 1F is the first byte read, followed by 65 as the second byte. + To burst read and write these 4 bytes in the correct order (where DD is written to address x), they should be stored as: + + AA BB in the MSW + CC DD in the LSW. */ + unsigned int nvrDataLSW : 16; /* 1E.0105.F:0 R/W Default = 0x0000 */ + /* NVR data LSW bits [F:0] + */ + } bits_5; + uint16_t word_5; + } u5; +} AQ_GlobalNvrInterface_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Mailbox Interface: 1E.0200 */ +/* Global Mailbox Interface: 1E.0200 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Mailbox Interface */ + union + { + struct + { + unsigned int reserved2 : 8; + /*! \brief 1E.0200.8 RO uP Mailbox Busy + AQ_GlobalMailboxInterface_HHD.u0.bits_0.upMailboxBusy + + + + 1 = uP mailbox busy + 0 = uP mailbox ready + + + Notes: + In general the uP will respond within a few processor cycles to any PIF slave request, much faster than the MDIO. If the busy is asserted over multiple MDIO polling cycles, then a H/W error may have occurred and a Global S/W reset or uP reset is required. */ + unsigned int upMailboxBusy : 1; /* 1E.0200.8 RO */ + /* 1 = uP mailbox busy + 0 = uP mailbox ready + */ + unsigned int reserved1 : 3; + /*! \brief 1E.0200.C R/WSC Reset uP Mailbox CRC + AQ_GlobalMailboxInterface_HHD.u0.bits_0.resetUpMailboxCrc + + Default = 0x0 + + 1 = Reset uP mailbox CRC calculation register + + + */ + unsigned int resetUpMailboxCrc : 1; /* 1E.0200.C R/WSC Default = 0x0 */ + /* 1 = Reset uP mailbox CRC calculation register + + */ + unsigned int reserved0 : 1; + /*! \brief 1E.0200.E R/W uP Mailbox Write Mode + AQ_GlobalMailboxInterface_HHD.u0.bits_0.upMailboxWriteMode + + Default = 0x0 + + 1 = Write + 0 = Read + + + Notes: + Mailbox direction */ + unsigned int upMailboxWriteMode : 1; /* 1E.0200.E R/W Default = 0x0 */ + /* 1 = Write + 0 = Read + */ + /*! \brief 1E.0200.F R/WSC uP Mailbox Execute Operation + AQ_GlobalMailboxInterface_HHD.u0.bits_0.upMailboxExecuteOperation + + Default = 0x0 + + 1 = Start of mailbox Operation + + + + Notes: + Indicates mailbox is loaded and ready */ + unsigned int upMailboxExecuteOperation : 1; /* 1E.0200.F R/WSC Default = 0x0 */ + /* 1 = Start of mailbox Operation + + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Mailbox Interface */ + union + { + struct + { + /*! \brief 1E.0201.F:0 RO uP Mailbox CRC [F:0] + AQ_GlobalMailboxInterface_HHD.u1.bits_1.upMailboxCrc + + + + The running CRC-16 of everything passing through the mailbox interface + + */ + unsigned int upMailboxCrc : 16; /* 1E.0201.F:0 RO */ + /* The running CRC-16 of everything passing through the mailbox interface + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Mailbox Interface */ + union + { + struct + { + /*! \brief 1E.0202.F:0 R/W uP Mailbox Address MSW [1F:10] + AQ_GlobalMailboxInterface_HHD.u2.bits_2.upMailboxAddressMSW + + Default = 0x0000 + + uP Mailbox MSW address + + + Notes: + The address of where to read and write from in the Microcontroller Mailbox. This is self-incrementing and automatically increments after each read and write operation.PHY */ + unsigned int upMailboxAddressMSW : 16; /* 1E.0202.F:0 R/W Default = 0x0000 */ + /* uP Mailbox MSW address + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global Mailbox Interface */ + union + { + struct + { + /*! \brief 1E.0203.1:0 RO uP Mailbox Address LSW Don't Care [1:0] + AQ_GlobalMailboxInterface_HHD.u3.bits_3.upMailboxAddressLSW_Don_tCare + + + + Least significant uP LSW Mailbox address bits [1:0] + + + Notes: + These bits are always set to 0 since each memory access is on a 4-byte boundary. */ + unsigned int upMailboxAddressLSW_Don_tCare : 2; /* 1E.0203.1:0 RO */ + /* Least significant uP LSW Mailbox address bits [1:0] + */ + /*! \brief 1E.0203.F:2 R/W uP Mailbox Address LSW [F:2] + AQ_GlobalMailboxInterface_HHD.u3.bits_3.upMailboxAddressLSW + + Default = 0x0000 + + uP LSW Mailbox address [F:2] + + + Notes: + The address of where to read and write from in the Microcontroller Mailbox. This is self-incrementing and automatically increments after each read and write operation.PHY */ + unsigned int upMailboxAddressLSW : 14; /* 1E.0203.F:2 R/W Default = 0x0000 */ + /* uP LSW Mailbox address [F:2] + */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global Mailbox Interface */ + union + { + struct + { + /*! \brief 1E.0204.F:0 R/W uP Mailbox Data MSW [1F:10] + AQ_GlobalMailboxInterface_HHD.u4.bits_4.upMailboxDataMSW + + Default = 0x0000 + + uP Mailbox data MSW + + */ + unsigned int upMailboxDataMSW : 16; /* 1E.0204.F:0 R/W Default = 0x0000 */ + /* uP Mailbox data MSW + */ + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of Global Mailbox Interface */ + union + { + struct + { + /*! \brief 1E.0205.F:0 R/W uP Mailbox Data LSW [F:0] + AQ_GlobalMailboxInterface_HHD.u5.bits_5.upMailboxDataLSW + + Default = 0x0000 + + uP Mailbox data LSW + + */ + unsigned int upMailboxDataLSW : 16; /* 1E.0205.F:0 R/W Default = 0x0000 */ + /* uP Mailbox data LSW + */ + } bits_5; + uint16_t word_5; + } u5; + /*! \brief Union for bit and word level access of word 6 of Global Mailbox Interface */ + union + { + struct + { + unsigned int reserved1 : 1; + /*! \brief 1E.0206.1 R/W uP Mailbox CRC Read Enable + AQ_GlobalMailboxInterface_HHD.u6.bits_6.upMailboxCrcReadEnable + + Default = 0x0 + + 1 = Update uP mailbox CRC on read + + */ + unsigned int upMailboxCrcReadEnable : 1; /* 1E.0206.1 R/W Default = 0x0 */ + /* 1 = Update uP mailbox CRC on read + */ + unsigned int reserved0 : 14; + } bits_6; + uint16_t word_6; + } u6; +} AQ_GlobalMailboxInterface_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Microprocessor Scratch Pad: 1E.0300 */ +/* Global Microprocessor Scratch Pad: 1E.0300 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Microprocessor Scratch Pad */ + union + { + struct + { + /*! \brief 1E.0300.F:0 R/W Scratch Pad 1[F:0] + AQ_GlobalMicroprocessorScratchPad_HHD.u0.bits_0.scratchPad_1 + + Default = 0x0000 + + General Purpose Scratch Pad + */ + unsigned int scratchPad_1 : 16; /* 1E.0300.F:0 R/W Default = 0x0000 */ + /* General Purpose Scratch Pad */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Microprocessor Scratch Pad */ + union + { + struct + { + /*! \brief 1E.0301.F:0 R/W Scratch Pad 2 [F:0] + AQ_GlobalMicroprocessorScratchPad_HHD.u1.bits_1.scratchPad_2 + + Default = 0x0000 + + General Purpose Scratch Pad + */ + unsigned int scratchPad_2 : 16; /* 1E.0301.F:0 R/W Default = 0x0000 */ + /* General Purpose Scratch Pad */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalMicroprocessorScratchPad_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress Control Register: 1E.5002 */ +/* MSS Egress Control Register: 1E.5002 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress Control Register */ + union + { + struct + { + /*! \brief 1E.5002.0 R/W MSS Egress Soft Reset + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressSoftReset + + Default = 0x0 + + 1 = Soft reset + + + Notes: + S/W reset */ + unsigned int mssEgressSoftReset : 1; /* 1E.5002.0 R/W Default = 0x0 */ + /* 1 = Soft reset + */ + /*! \brief 1E.5002.1 R/W MSS Egress Drop KAY Packet + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressDropKayPacket + + Default = 0x0 + + 1 = Drop KAY packet + + + Notes: + Decides whether KAY packets have to be dropped */ + unsigned int mssEgressDropKayPacket : 1; /* 1E.5002.1 R/W Default = 0x0 */ + /* 1 = Drop KAY packet + */ + /*! \brief 1E.5002.2 R/W MSS Egress Drop EGPRC LUT Miss + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressDropEgprcLutMiss + + Default = 0x0 + + 1 = Drop Egress Classification LUT miss packets + + + + Notes: + Decides whether Egress Pre-Security Classification (EGPRC) LUT miss packets are to be dropped */ + unsigned int mssEgressDropEgprcLutMiss : 1; /* 1E.5002.2 R/W Default = 0x0 */ + /* 1 = Drop Egress Classification LUT miss packets + + */ + /*! \brief 1E.5002.3 R/W MSS Egress GCM Start + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressGcmStart + + Default = 0x0 + + 1 = Start GCM + + + + Notes: + Indicates GCM to start */ + unsigned int mssEgressGcmStart : 1; /* 1E.5002.3 R/W Default = 0x0 */ + /* 1 = Start GCM + + */ + /*! \brief 1E.5002.4 R/W MSS Egresss GCM Test Mode + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgresssGcmTestMode + + Default = 0x0 + + 1 = Enable GCM test mode + + + + Notes: + Enables GCM test mode */ + unsigned int mssEgresssGcmTestMode : 1; /* 1E.5002.4 R/W Default = 0x0 */ + /* 1 = Enable GCM test mode + + */ + /*! \brief 1E.5002.5 R/W MSS Egress Unmatched Use SC 0 + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressUnmatchedUseSc_0 + + Default = 0x0 + + 1 = Use SC 0 for unmatched packets + 0 = Unmatched packets are uncontrolled packets + + + + Notes: + Use SC-Index 0 as default SC for unmatched packets. Otherwise the packets are treated as uncontrolled packets. */ + unsigned int mssEgressUnmatchedUseSc_0 : 1; /* 1E.5002.5 R/W Default = 0x0 */ + /* 1 = Use SC 0 for unmatched packets + 0 = Unmatched packets are uncontrolled packets + + */ + /*! \brief 1E.5002.6 R/W MSS Egress Drop Invalid SA/SC Packets + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressDropInvalidSa_scPackets + + Default = 0x0 + + 1 = Drop invalid SA/SC packets + + + + Notes: + Enables dropping of invalid SA/SC packets. */ + unsigned int mssEgressDropInvalidSa_scPackets : 1; /* 1E.5002.6 R/W Default = 0x0 */ + /* 1 = Drop invalid SA/SC packets + + */ + /*! \brief 1E.5002.7 R/W MSS Egress Explicit SECTag Report Short Length + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressExplicitSectagReportShortLength + + Default = 0x0 + + Reserved + + + + Notes: + Unused. */ + unsigned int mssEgressExplicitSectagReportShortLength : 1; /* 1E.5002.7 R/W Default = 0x0 */ + /* Reserved + + */ + /*! \brief 1E.5002.8 R/W MSS Egress External Classification Enable + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressExternalClassificationEnable + + Default = 0x0 + + 1 = Drop EGPRC miss packets + + + + Notes: + If set, internal classification is bypassed. Should always be set to 0. */ + unsigned int mssEgressExternalClassificationEnable : 1; /* 1E.5002.8 R/W Default = 0x0 */ + /* 1 = Drop EGPRC miss packets + + */ + /*! \brief 1E.5002.9 R/W MSS Egress ICV LSB 8 Bytes Enable + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressIcvLsb_8BytesEnable + + Default = 0x0 + + 1 = Use LSB + 0 = Use MSB + + + + Notes: + This bit selects MSB or LSB 8 bytes selection in the case where the ICV is 8 bytes. + 0 = MSB is used. */ + unsigned int mssEgressIcvLsb_8BytesEnable : 1; /* 1E.5002.9 R/W Default = 0x0 */ + /* 1 = Use LSB + 0 = Use MSB + + */ + /*! \brief 1E.5002.A R/W MSS Egress High Priority + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressHighPriority + + Default = 0x0 + + 1 = MIB counter clear on read enable + + + + Notes: + If this bit is set to 1, read is given high priority and the MIB count value becomes 0 after read. */ + unsigned int mssEgressHighPriority : 1; /* 1E.5002.A R/W Default = 0x0 */ + /* 1 = MIB counter clear on read enable + + */ + /*! \brief 1E.5002.B R/W MSS Egress Clear Counter + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressClearCounter + + Default = 0x0 + + 1 = Clear all MIB counters + + + + Notes: + If this bit is set to 1, all MIB counters will be cleared. */ + unsigned int mssEgressClearCounter : 1; /* 1E.5002.B R/W Default = 0x0 */ + /* 1 = Clear all MIB counters + + */ + /*! \brief 1E.5002.C R/W MSS Egress Clear Global Time + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressClearGlobalTime + + Default = 0x0 + + 1 = Clear global time + + + + Notes: + Clear global time. */ + unsigned int mssEgressClearGlobalTime : 1; /* 1E.5002.C R/W Default = 0x0 */ + /* 1 = Clear global time + + */ + /*! \brief 1E.5002.F:D R/W MSS Egress Ethertype Explicit SECTag LSB [2:0] + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressEthertypeExplicitSectagLsb + + Default = 0x0 + + Ethertype for explicit SECTag bits 2:0. + + + Notes: + Ethertype for explicity SECTag. */ + unsigned int mssEgressEthertypeExplicitSectagLsb : 3; /* 1E.5002.F:D R/W Default = 0x0 */ + /* Ethertype for explicit SECTag bits 2:0. + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress Control Register */ + union + { + struct + { + /*! \brief 1E.5003.C:0 R/W MSS Egress Ethertype Explicit SECTag MSB [F:3] + AQ_MssEgressControlRegister_HHD.u1.bits_1.mssEgressEthertypeExplicitSectagMsb + + Default = 0x0000 + + Ethertype for explicit SECTag bits 15:3. + + + Notes: + Ethertype for explicity SECTag. */ + unsigned int mssEgressEthertypeExplicitSectagMsb : 13; /* 1E.5003.C:0 R/W Default = 0x0000 */ + /* Ethertype for explicit SECTag bits 15:3. + */ + unsigned int reserved0 : 3; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssEgressControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress VLAN TPID 0 Register: 1E.5008 */ +/* MSS Egress VLAN TPID 0 Register: 1E.5008 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress VLAN TPID 0 Register */ + union + { + struct + { + /*! \brief 1E.5008.F:0 R/W MSS Egress VLAN STag TPID [F:0] + AQ_MssEgressVlanTpid_0Register_HHD.u0.bits_0.mssEgressVlanStagTpid + + Default = 0x0000 + + STag TPID + + + Notes: + Service Tag Protocol Identifier (TPID) values to identify a VLAN tag. The " See SEC Egress VLAN CP Tag Parse STag " bit must be set to 1 for the incoming packet's TPID to be parsed. */ + unsigned int mssEgressVlanStagTpid : 16; /* 1E.5008.F:0 R/W Default = 0x0000 */ + /* STag TPID + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress VLAN TPID 0 Register */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssEgressVlanTpid_0Register_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress VLAN TPID 1 Register: 1E.500A */ +/* MSS Egress VLAN TPID 1 Register: 1E.500A */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress VLAN TPID 1 Register */ + union + { + struct + { + /*! \brief 1E.500A.F:0 R/W MSS Egress VLAN QTag TPID [F:0] + AQ_MssEgressVlanTpid_1Register_HHD.u0.bits_0.mssEgressVlanQtagTpid + + Default = 0x0000 + + QTag TPID + + + Notes: + Customer Tag Protocol Identifier (TPID) values to identify a VLAN tag. The " See SEC Egress VLAN CP Tag Parse QTag " bit must be set to 1 for the incoming packet's TPID to be parsed. */ + unsigned int mssEgressVlanQtagTpid : 16; /* 1E.500A.F:0 R/W Default = 0x0000 */ + /* QTag TPID + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress VLAN TPID 1 Register */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssEgressVlanTpid_1Register_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress VLAN Control Register: 1E.500C */ +/* MSS Egress VLAN Control Register: 1E.500C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress VLAN Control Register */ + union + { + struct + { + /*! \brief 1E.500C.F:0 R/W MSS Egress VLAN UP Map Table [F:0] + AQ_MssEgressVlanControlRegister_HHD.u0.bits_0.mssEgressVlanUpMapTable + + Default = 0x0000 + + UP Map table bits 15:0 + + + Notes: + If there is a customer TPID Tag match and no service TPID Tag match or the service TPID Tag match is disabled, the outer TAG's PCP is used to index into this map table to generate the packets user priority. + 2:0 : UP value for customer Tag PCP 0x0 + 5:3: UP value for customer Tag PCP 0x0 + 8:6 : UP value for customer Tag PCP 0x0 + 11:9 : UP value for customer Tag PCP 0x0 + 14:12 : UP value for customer Tag PCP 0x0 + 17:15 : UP value for customer Tag PCP 0x0 + 20:18 : UP value for customer Tag PCP 0x0 + 23:21 : UP value for customer Tag PCP 0x0 */ + unsigned int mssEgressVlanUpMapTable : 16; /* 1E.500C.F:0 R/W Default = 0x0000 */ + /* UP Map table bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress VLAN Control Register */ + union + { + struct + { + /*! \brief 1E.500D.7:0 R/W MSS Egress VLAN UP Map Table MSW [17:10] + AQ_MssEgressVlanControlRegister_HHD.u1.bits_1.mssEgressVlanUpMapTableMSW + + Default = 0x00 + + UP Map table bits 23:16 + + + Notes: + If there is a customer TPID Tag match and no service TPID Tag match or the service TPID Tag match is disabled, the outer TAG's PCP is used to index into this map table to generate the packets user priority. + 2:0 : UP value for customer Tag PCP 0x0 + 5:3: UP value for customer Tag PCP 0x0 + 8:6 : UP value for customer Tag PCP 0x0 + 11:9 : UP value for customer Tag PCP 0x0 + 14:12 : UP value for customer Tag PCP 0x0 + 17:15 : UP value for customer Tag PCP 0x0 + 20:18 : UP value for customer Tag PCP 0x0 + 23:21 : UP value for customer Tag PCP 0x0 */ + unsigned int mssEgressVlanUpMapTableMSW : 8; /* 1E.500D.7:0 R/W Default = 0x00 */ + /* UP Map table bits 23:16 + */ + /*! \brief 1E.500D.A:8 R/W MSS Egress VLAN UP Default [2:0] + AQ_MssEgressVlanControlRegister_HHD.u1.bits_1.mssEgressVlanUpDefault + + Default = 0x0 + + UP default + + + Notes: + User priority default */ + unsigned int mssEgressVlanUpDefault : 3; /* 1E.500D.A:8 R/W Default = 0x0 */ + /* UP default + */ + /*! \brief 1E.500D.B R/W MSS Egress VLAN STag UP Parse Enable + AQ_MssEgressVlanControlRegister_HHD.u1.bits_1.mssEgressVlanStagUpParseEnable + + Default = 0x0 + + VLAN CP Tag STag UP enable + + + Notes: + Enable controlled port service VLAN service Tag user priority field parsing. */ + unsigned int mssEgressVlanStagUpParseEnable : 1; /* 1E.500D.B R/W Default = 0x0 */ + /* VLAN CP Tag STag UP enable + */ + /*! \brief 1E.500D.C R/W MSS Egress VLAN QTag UP Parse Enable + AQ_MssEgressVlanControlRegister_HHD.u1.bits_1.mssEgressVlanQtagUpParseEnable + + Default = 0x0 + + VLAN CP Tag QTag UP enable + + + Notes: + Enable controlled port customer VLAN customer Tag user priority field parsing. */ + unsigned int mssEgressVlanQtagUpParseEnable : 1; /* 1E.500D.C R/W Default = 0x0 */ + /* VLAN CP Tag QTag UP enable + */ + /*! \brief 1E.500D.D R/W MSS Egress VLAN QinQ Parse Enable + AQ_MssEgressVlanControlRegister_HHD.u1.bits_1.mssEgressVlanQinqParseEnable + + Default = 0x0 + + VLAN CP Tag Parse QinQ + + + Notes: + Enable controlled port VLAN QinQ Tag parsing. When this bit is set to 1 both the outer and inner VLAN Tags will be parsed. */ + unsigned int mssEgressVlanQinqParseEnable : 1; /* 1E.500D.D R/W Default = 0x0 */ + /* VLAN CP Tag Parse QinQ + */ + /*! \brief 1E.500D.E R/W MSS Egress VLAN STag Parse Enable + AQ_MssEgressVlanControlRegister_HHD.u1.bits_1.mssEgressVlanStagParseEnable + + Default = 0x0 + + 1 = Enable VLAN STag parsing + + + Notes: + Enable controlled port VLAN service Tag parsing. When this bit is set to 1, the incoming packets outer TPID will be compared with the configured " See SEC Egress TPID 0 [F:0] " for matching. If the " See SEC Egress VLAN CP Tag Parse QinQ " bit is set to1, this will also be used to compare the incoming packet's inner TPID. */ + unsigned int mssEgressVlanStagParseEnable : 1; /* 1E.500D.E R/W Default = 0x0 */ + /* 1 = Enable VLAN STag parsing + */ + /*! \brief 1E.500D.F R/W MSS Egress VLAN QTag Parse Enable + AQ_MssEgressVlanControlRegister_HHD.u1.bits_1.mssEgressVlanQtagParseEnable + + Default = 0x0 + + 1 = Enable VLAN QTag parsing + + + Notes: + Enable controlled port VLAN customer Tag parsing. When this bit is set to 1, the incoming packet's outer TPID will be compared with the configured " See SEC Egress TPID 1 [F:0] " for matching. If the " See SEC Egress VLAN CP Tag Parse QinQ " bit is set to1, this will also be used to compare the incoming packet's inner TPID. */ + unsigned int mssEgressVlanQtagParseEnable : 1; /* 1E.500D.F R/W Default = 0x0 */ + /* 1 = Enable VLAN QTag parsing + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssEgressVlanControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress PN Control Register: 1E.500E */ +/* MSS Egress PN Control Register: 1E.500E */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress PN Control Register */ + union + { + struct + { + /*! \brief 1E.500E.F:0 R/W MSS Egress SA PN Threshold LSW [F:0] + AQ_MssEgressPnControlRegister_HHD.u0.bits_0.mssEgressSaPnThresholdLSW + + Default = 0x0000 + + PN threshold bits 15:0 + + + Notes: + Egress PN threshold to generate SA threshold interrupt. */ + unsigned int mssEgressSaPnThresholdLSW : 16; /* 1E.500E.F:0 R/W Default = 0x0000 */ + /* PN threshold bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress PN Control Register */ + union + { + struct + { + /*! \brief 1E.500F.F:0 R/W MSS Egress SA PN Threshold MSW [1F:10] + AQ_MssEgressPnControlRegister_HHD.u1.bits_1.mssEgressSaPnThresholdMSW + + Default = 0x0000 + + PN threshold bits 31:16 + + + Notes: + Egress PN threshold to generate SA threshold interrupt. */ + unsigned int mssEgressSaPnThresholdMSW : 16; /* 1E.500F.F:0 R/W Default = 0x0000 */ + /* PN threshold bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssEgressPnControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress MTU Size Control Register: 1E.5010 */ +/* MSS Egress MTU Size Control Register: 1E.5010 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress MTU Size Control Register */ + union + { + struct + { + /*! \brief 1E.5010.F:0 R/W MSS Egress Controlled Packet MTU Size [F:0] + AQ_MssEgressMtuSizeControlRegister_HHD.u0.bits_0.mssEgressControlledPacketMtuSize + + Default = 0x05DC + + Maximum transmission unit for controlled packet + + + Notes: + Maximum transmission unit of controlled packet */ + unsigned int mssEgressControlledPacketMtuSize : 16; /* 1E.5010.F:0 R/W Default = 0x05DC */ + /* Maximum transmission unit for controlled packet + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress MTU Size Control Register */ + union + { + struct + { + /*! \brief 1E.5011.F:0 R/W MSS Egress Uncontrolled Packet MTU Size [F:0] + AQ_MssEgressMtuSizeControlRegister_HHD.u1.bits_1.mssEgressUncontrolledPacketMtuSize + + Default = 0x05DC + + Maximum transmission unit for uncontrolled packet + + + Notes: + Maximum transmission unit of uncontrolled packet */ + unsigned int mssEgressUncontrolledPacketMtuSize : 16; /* 1E.5011.F:0 R/W Default = 0x05DC */ + /* Maximum transmission unit for uncontrolled packet + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssEgressMtuSizeControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress Interrupt Status Register: 1E.505C */ +/* MSS Egress Interrupt Status Register: 1E.505C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress Interrupt Status Register */ + union + { + struct + { + /*! \brief 1E.505C.0 COW MSS Egress Master Interrupt + AQ_MssEgressInterruptStatusRegister_HHD.u0.bits_0.mssEgressMasterInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. This bit is set when any one of the above interrupt and the corresponding interrupt enable are both set. The interrupt enable for this bit must also be set for this bit to be set. */ + unsigned int mssEgressMasterInterrupt : 1; /* 1E.505C.0 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.505C.1 COW MSS Egress SA Expired Interrupt + AQ_MssEgressInterruptStatusRegister_HHD.u0.bits_0.mssEgressSaExpiredInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. This bit is set when the SA PN reaches all ones saturation. */ + unsigned int mssEgressSaExpiredInterrupt : 1; /* 1E.505C.1 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.505C.2 COW MSS Egress SA Threshold Expired Interrupt + AQ_MssEgressInterruptStatusRegister_HHD.u0.bits_0.mssEgressSaThresholdExpiredInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. This bit is set when the SA PN reaches the See SEC Egress PN Threshold [F:0] and See SEC Egress PN Threshold [1F:10] . */ + unsigned int mssEgressSaThresholdExpiredInterrupt : 1; /* 1E.505C.2 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.505C.3 COW MSS Egress MIB Saturation Interrupt + AQ_MssEgressInterruptStatusRegister_HHD.u0.bits_0.mssEgressMibSaturationInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. This bit is set when the MIB counters reaches all ones saturation. */ + unsigned int mssEgressMibSaturationInterrupt : 1; /* 1E.505C.3 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.505C.4 COW MSS Egress ECC Error Interrupt + AQ_MssEgressInterruptStatusRegister_HHD.u0.bits_0.mssEgressEccErrorInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. This bit is set when anyone of the memories detects an ECC error. */ + unsigned int mssEgressEccErrorInterrupt : 1; /* 1E.505C.4 COW Default = 0x0 */ + /* 1 = Interrupt + */ + unsigned int reserved0 : 11; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress Interrupt Status Register */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssEgressInterruptStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress Interrupt Mask Register: 1E.505E */ +/* MSS Egress Interrupt Mask Register: 1E.505E */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress Interrupt Mask Register */ + union + { + struct + { + /*! \brief 1E.505E.0 COW MSS Egress Master Interrupt Enable + AQ_MssEgressInterruptMaskRegister_HHD.u0.bits_0.mssEgressMasterInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + + Notes: + Write to 1 to clear. */ + unsigned int mssEgressMasterInterruptEnable : 1; /* 1E.505E.0 COW Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.505E.1 COW MSS Egress SA Expired Interrupt Enable + AQ_MssEgressInterruptMaskRegister_HHD.u0.bits_0.mssEgressSaExpiredInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + + Notes: + Write to 1 to clear. This bit is set when the SA PN reaches all ones saturation. */ + unsigned int mssEgressSaExpiredInterruptEnable : 1; /* 1E.505E.1 COW Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.505E.2 COW MSS Egress SA Expired Threshold Interrupt Enable + AQ_MssEgressInterruptMaskRegister_HHD.u0.bits_0.mssEgressSaExpiredThresholdInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + + Notes: + Write to 1 to clear. This bit is set when the SA PN reaches the configured threshold See SEC Egress PN Threshold [F:0] and See SEC Egress PN Threshold [1F:10] . */ + unsigned int mssEgressSaExpiredThresholdInterruptEnable : 1; /* 1E.505E.2 COW Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.505E.3 COW MSS Egress MIB Saturation Interrupt Enable + AQ_MssEgressInterruptMaskRegister_HHD.u0.bits_0.mssEgressMibSaturationInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + + Notes: + Write to 1 to clear. This bit is set when the MIB counters reaches all ones saturation. */ + unsigned int mssEgressMibSaturationInterruptEnable : 1; /* 1E.505E.3 COW Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.505E.4 COW MSS Egress ECC Error Interrupt Enable + AQ_MssEgressInterruptMaskRegister_HHD.u0.bits_0.mssEgressEccErrorInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + + Notes: + Write to 1 to clear. This bit is set when anyone of the memories detects an ECC error. */ + unsigned int mssEgressEccErrorInterruptEnable : 1; /* 1E.505E.4 COW Default = 0x0 */ + /* 1 = Interrupt enabled + */ + unsigned int reserved0 : 11; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress Interrupt Mask Register */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssEgressInterruptMaskRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress SA Expired Status Register: 1E.5060 */ +/* MSS Egress SA Expired Status Register: 1E.5060 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress SA Expired Status Register */ + union + { + struct + { + /*! \brief 1E.5060.F:0 COW MSS Egress SA Expired LSW [F:0] + AQ_MssEgressSaExpiredStatusRegister_HHD.u0.bits_0.mssEgressSaExpiredLSW + + Default = 0x0000 + + SA expired bits 15:0 + + + Notes: + Write these bits to 1 to clear. + When set, these bits identify the SA that has expired when the SA PN reaches all-ones saturation. */ + unsigned int mssEgressSaExpiredLSW : 16; /* 1E.5060.F:0 COW Default = 0x0000 */ + /* SA expired bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress SA Expired Status Register */ + union + { + struct + { + /*! \brief 1E.5061.F:0 COW MSS Egress SA Expired MSW [1F:10] + AQ_MssEgressSaExpiredStatusRegister_HHD.u1.bits_1.mssEgressSaExpiredMSW + + Default = 0x0000 + + SA expired bits 31:16 + + + Notes: + Write these bits to 1 to clear. + When set, these bits identify the SA that has expired when the SA PN reaches all-ones saturation. */ + unsigned int mssEgressSaExpiredMSW : 16; /* 1E.5061.F:0 COW Default = 0x0000 */ + /* SA expired bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssEgressSaExpiredStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress SA Threshold Expired Status Register: 1E.5062 */ +/* MSS Egress SA Threshold Expired Status Register: 1E.5062 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress SA Threshold Expired Status Register */ + union + { + struct + { + /*! \brief 1E.5062.F:0 COW MSS Egress SA Threshold Expired LSW [F:0] + AQ_MssEgressSaThresholdExpiredStatusRegister_HHD.u0.bits_0.mssEgressSaThresholdExpiredLSW + + Default = 0x0000 + + SA threshold expired bits 15:0 + + + Notes: + Write these bits to 1 to clear. + When set, these bits identify the SA that has expired when the SA PN has reached the configured threshold See SEC Egress PN Threshold [F:0] and See SEC Egress PN Threshold [1F:10] . */ + unsigned int mssEgressSaThresholdExpiredLSW : 16; /* 1E.5062.F:0 COW Default = 0x0000 */ + /* SA threshold expired bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress SA Threshold Expired Status Register */ + union + { + struct + { + /*! \brief 1E.5063.F:0 COW MSS Egress SA Threshold Expired MSW [1F:10] + AQ_MssEgressSaThresholdExpiredStatusRegister_HHD.u1.bits_1.mssEgressSaThresholdExpiredMSW + + Default = 0x0000 + + SA threshold expired bits 31:16 + + + Notes: + Write these bits to 1 to clear. + When set, these bits identify the SA that has expired when the SA PN has reached the configured threshold See SEC Egress PN Threshold [F:0] and See SEC Egress PN Threshold [1F:10] . */ + unsigned int mssEgressSaThresholdExpiredMSW : 16; /* 1E.5063.F:0 COW Default = 0x0000 */ + /* SA threshold expired bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssEgressSaThresholdExpiredStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress ECC Interrupt Status Register: 1E.5064 */ +/* MSS Egress ECC Interrupt Status Register: 1E.5064 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress ECC Interrupt Status Register */ + union + { + struct + { + /*! \brief 1E.5064.F:0 COW MSS Egress SA ECC Error Interrupt LSW [F:0] + AQ_MssEgressEccInterruptStatusRegister_HHD.u0.bits_0.mssEgressSaEccErrorInterruptLSW + + Default = 0x0000 + + SA ECC error interrupt bits 15:0 + + + Notes: + Write these bits to 1 to clear. + When set to 1, indicates that an ECC error occured for the SA. */ + unsigned int mssEgressSaEccErrorInterruptLSW : 16; /* 1E.5064.F:0 COW Default = 0x0000 */ + /* SA ECC error interrupt bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress ECC Interrupt Status Register */ + union + { + struct + { + /*! \brief 1E.5065.F:0 COW MSS Egress SA ECC Error Interrupt MSW [1F:10] + AQ_MssEgressEccInterruptStatusRegister_HHD.u1.bits_1.mssEgressSaEccErrorInterruptMSW + + Default = 0x0000 + + SA ECC error interrupt bits 31:16 + + + Notes: + Write these bits to 1 to clear. + When set to 1, indicates that an ECC error occured for the SA. */ + unsigned int mssEgressSaEccErrorInterruptMSW : 16; /* 1E.5065.F:0 COW Default = 0x0000 */ + /* SA ECC error interrupt bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssEgressEccInterruptStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress LUT Address Control Register: 1E.5080 */ +/* MSS Egress LUT Address Control Register: 1E.5080 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress LUT Address Control Register */ + union + { + struct + { + /*! \brief 1E.5080.8:0 R/W MSS Egress LUT Address [8:0] + AQ_MssEgressLutAddressControlRegister_HHD.u0.bits_0.mssEgressLutAddress + + Default = 0x000 + + LUT address + + */ + unsigned int mssEgressLutAddress : 9; /* 1E.5080.8:0 R/W Default = 0x000 */ + /* LUT address + */ + unsigned int reserved0 : 3; + /*! \brief 1E.5080.F:C R/W MSS Egress LUT Select [3:0] + AQ_MssEgressLutAddressControlRegister_HHD.u0.bits_0.mssEgressLutSelect + + Default = 0x0 + + LUT select + + + Notes: + 0x0 : Egress MAC Control FIlter (CTLF) LUT + 0x1 : Egress Classification LUT + 0x2 : Egress SC/SA LUT + 0x3 : Egress SMIB */ + unsigned int mssEgressLutSelect : 4; /* 1E.5080.F:C R/W Default = 0x0 */ + /* LUT select + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_MssEgressLutAddressControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress LUT Control Register: 1E.5081 */ +/* MSS Egress LUT Control Register: 1E.5081 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress LUT Control Register */ + union + { + struct + { + unsigned int reserved0 : 14; + /*! \brief 1E.5081.E R/W MSS Egress LUT Read + AQ_MssEgressLutControlRegister_HHD.u0.bits_0.mssEgressLutRead + + Default = 0x0 + + 1 = LUT read + + + Notes: + Setting this bit to 1, will read the LUT. This bit will automatically clear to 0. */ + unsigned int mssEgressLutRead : 1; /* 1E.5081.E R/W Default = 0x0 */ + /* 1 = LUT read + */ + /*! \brief 1E.5081.F R/W MSS Egress LUT Write + AQ_MssEgressLutControlRegister_HHD.u0.bits_0.mssEgressLutWrite + + Default = 0x0 + + 1 = LUT write + + + Notes: + Setting this bit to 1, will write the LUT. This bit will automatically clear to 0. */ + unsigned int mssEgressLutWrite : 1; /* 1E.5081.F R/W Default = 0x0 */ + /* 1 = LUT write + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_MssEgressLutControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress LUT Data Control Register: 1E.50A0 */ +/* MSS Egress LUT Data Control Register: 1E.50A0 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50A0.F:0 R/W MSS Egress LUT Data 0 [F:0] + AQ_MssEgressLutDataControlRegister_HHD.u0.bits_0.mssEgressLutData_0 + + Default = 0x0000 + + LUT data bits 15:0 + + */ + unsigned int mssEgressLutData_0 : 16; /* 1E.50A0.F:0 R/W Default = 0x0000 */ + /* LUT data bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50A1.F:0 R/W MSS Egress LUT Data 1 [1F:10] + AQ_MssEgressLutDataControlRegister_HHD.u1.bits_1.mssEgressLutData_1 + + Default = 0x0000 + + LUT data bits 31:16 + + */ + unsigned int mssEgressLutData_1 : 16; /* 1E.50A1.F:0 R/W Default = 0x0000 */ + /* LUT data bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50A2.F:0 R/W MSS Egress LUT Data 2 [2F:20] + AQ_MssEgressLutDataControlRegister_HHD.u2.bits_2.mssEgressLutData_2 + + Default = 0x0000 + + LUT data bits 47:32 + + */ + unsigned int mssEgressLutData_2 : 16; /* 1E.50A2.F:0 R/W Default = 0x0000 */ + /* LUT data bits 47:32 + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50A3.F:0 R/W MSS Egress LUT Data 3 [3F:30] + AQ_MssEgressLutDataControlRegister_HHD.u3.bits_3.mssEgressLutData_3 + + Default = 0x0000 + + LUT data bits 63:48 + + */ + unsigned int mssEgressLutData_3 : 16; /* 1E.50A3.F:0 R/W Default = 0x0000 */ + /* LUT data bits 63:48 + */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50A4.F:0 R/W MSS Egress LUT Data 4 [4F:40] + AQ_MssEgressLutDataControlRegister_HHD.u4.bits_4.mssEgressLutData_4 + + Default = 0x0000 + + LUT data bits 79:64 + + */ + unsigned int mssEgressLutData_4 : 16; /* 1E.50A4.F:0 R/W Default = 0x0000 */ + /* LUT data bits 79:64 + */ + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50A5.F:0 R/W MSS Egress LUT Data 5 [5F:50] + AQ_MssEgressLutDataControlRegister_HHD.u5.bits_5.mssEgressLutData_5 + + Default = 0x0000 + + LUT data bits 95:80 + + */ + unsigned int mssEgressLutData_5 : 16; /* 1E.50A5.F:0 R/W Default = 0x0000 */ + /* LUT data bits 95:80 + */ + } bits_5; + uint16_t word_5; + } u5; + /*! \brief Union for bit and word level access of word 6 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50A6.F:0 R/W MSS Egress LUT Data 6 [6F:60] + AQ_MssEgressLutDataControlRegister_HHD.u6.bits_6.mssEgressLutData_6 + + Default = 0x0000 + + LUT data bits 111:96 + + */ + unsigned int mssEgressLutData_6 : 16; /* 1E.50A6.F:0 R/W Default = 0x0000 */ + /* LUT data bits 111:96 + */ + } bits_6; + uint16_t word_6; + } u6; + /*! \brief Union for bit and word level access of word 7 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50A7.F:0 R/W MSS Egress LUT Data 7 [7F:70] + AQ_MssEgressLutDataControlRegister_HHD.u7.bits_7.mssEgressLutData_7 + + Default = 0x0000 + + LUT data bits 127:112 + + */ + unsigned int mssEgressLutData_7 : 16; /* 1E.50A7.F:0 R/W Default = 0x0000 */ + /* LUT data bits 127:112 + */ + } bits_7; + uint16_t word_7; + } u7; + /*! \brief Union for bit and word level access of word 8 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50A8.F:0 R/W MSS Egress LUT Data 8 [8F:80] + AQ_MssEgressLutDataControlRegister_HHD.u8.bits_8.mssEgressLutData_8 + + Default = 0x0000 + + LUT data bits 143:128 + + */ + unsigned int mssEgressLutData_8 : 16; /* 1E.50A8.F:0 R/W Default = 0x0000 */ + /* LUT data bits 143:128 + */ + } bits_8; + uint16_t word_8; + } u8; + /*! \brief Union for bit and word level access of word 9 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50A9.F:0 R/W MSS Egress LUT Data 9 [9F:90] + AQ_MssEgressLutDataControlRegister_HHD.u9.bits_9.mssEgressLutData_9 + + Default = 0x0000 + + LUT data bits 159:144 + + */ + unsigned int mssEgressLutData_9 : 16; /* 1E.50A9.F:0 R/W Default = 0x0000 */ + /* LUT data bits 159:144 + */ + } bits_9; + uint16_t word_9; + } u9; + /*! \brief Union for bit and word level access of word 10 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50AA.F:0 R/W MSS Egress LUT Data 10 [AF:A0] + AQ_MssEgressLutDataControlRegister_HHD.u10.bits_10.mssEgressLutData_10 + + Default = 0x0000 + + LUT data bits 175:160 + + */ + unsigned int mssEgressLutData_10 : 16; /* 1E.50AA.F:0 R/W Default = 0x0000 */ + /* LUT data bits 175:160 + */ + } bits_10; + uint16_t word_10; + } u10; + /*! \brief Union for bit and word level access of word 11 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50AB.F:0 R/W MSS Egress LUT Data 11 [BF:B0] + AQ_MssEgressLutDataControlRegister_HHD.u11.bits_11.mssEgressLutData_11 + + Default = 0x0000 + + LUT data bits 191:176 + + */ + unsigned int mssEgressLutData_11 : 16; /* 1E.50AB.F:0 R/W Default = 0x0000 */ + /* LUT data bits 191:176 + */ + } bits_11; + uint16_t word_11; + } u11; + /*! \brief Union for bit and word level access of word 12 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50AC.F:0 R/W MSS Egress LUT Data 12 [CF:C0] + AQ_MssEgressLutDataControlRegister_HHD.u12.bits_12.mssEgressLutData_12 + + Default = 0x0000 + + LUT data bits 207:192 + + */ + unsigned int mssEgressLutData_12 : 16; /* 1E.50AC.F:0 R/W Default = 0x0000 */ + /* LUT data bits 207:192 + */ + } bits_12; + uint16_t word_12; + } u12; + /*! \brief Union for bit and word level access of word 13 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50AD.F:0 R/W MSS Egress LUT Data 13 [DF:D0] + AQ_MssEgressLutDataControlRegister_HHD.u13.bits_13.mssEgressLutData_13 + + Default = 0x0000 + + LUT data bits 223:208 + + */ + unsigned int mssEgressLutData_13 : 16; /* 1E.50AD.F:0 R/W Default = 0x0000 */ + /* LUT data bits 223:208 + */ + } bits_13; + uint16_t word_13; + } u13; + /*! \brief Union for bit and word level access of word 14 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50AE.F:0 R/W MSS Egress LUT Data 14 [EF:E0] + AQ_MssEgressLutDataControlRegister_HHD.u14.bits_14.mssEgressLutData_14 + + Default = 0x0000 + + LUT data bits 239:224 + + */ + unsigned int mssEgressLutData_14 : 16; /* 1E.50AE.F:0 R/W Default = 0x0000 */ + /* LUT data bits 239:224 + */ + } bits_14; + uint16_t word_14; + } u14; + /*! \brief Union for bit and word level access of word 15 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50AF.F:0 R/W MSS Egress LUT Data 15 [FF:F0] + AQ_MssEgressLutDataControlRegister_HHD.u15.bits_15.mssEgressLutData_15 + + Default = 0x0000 + + LUT data bits 255:240 + + */ + unsigned int mssEgressLutData_15 : 16; /* 1E.50AF.F:0 R/W Default = 0x0000 */ + /* LUT data bits 255:240 + */ + } bits_15; + uint16_t word_15; + } u15; + /*! \brief Union for bit and word level access of word 16 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50B0.F:0 R/W MSS Egress LUT Data 16 [10F:100] + AQ_MssEgressLutDataControlRegister_HHD.u16.bits_16.mssEgressLutData_16 + + Default = 0x0000 + + LUT data bits 271:256 + + */ + unsigned int mssEgressLutData_16 : 16; /* 1E.50B0.F:0 R/W Default = 0x0000 */ + /* LUT data bits 271:256 + */ + } bits_16; + uint16_t word_16; + } u16; + /*! \brief Union for bit and word level access of word 17 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50B1.F:0 R/W MSS Egress LUT Data 17 [11F:110] + AQ_MssEgressLutDataControlRegister_HHD.u17.bits_17.mssEgressLutData_17 + + Default = 0x0000 + + LUT data bits 287:272 + + */ + unsigned int mssEgressLutData_17 : 16; /* 1E.50B1.F:0 R/W Default = 0x0000 */ + /* LUT data bits 287:272 + */ + } bits_17; + uint16_t word_17; + } u17; + /*! \brief Union for bit and word level access of word 18 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50B2.F:0 R/W MSS Egress LUT Data 18 [12F:120] + AQ_MssEgressLutDataControlRegister_HHD.u18.bits_18.mssEgressLutData_18 + + Default = 0x0000 + + LUT data bits 303:288 + + */ + unsigned int mssEgressLutData_18 : 16; /* 1E.50B2.F:0 R/W Default = 0x0000 */ + /* LUT data bits 303:288 + */ + } bits_18; + uint16_t word_18; + } u18; + /*! \brief Union for bit and word level access of word 19 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50B3.F:0 R/W MSS Egress LUT Data 19 [13F:130] + AQ_MssEgressLutDataControlRegister_HHD.u19.bits_19.mssEgressLutData_19 + + Default = 0x0000 + + LUT data bits 319:304 + + */ + unsigned int mssEgressLutData_19 : 16; /* 1E.50B3.F:0 R/W Default = 0x0000 */ + /* LUT data bits 319:304 + */ + } bits_19; + uint16_t word_19; + } u19; + /*! \brief Union for bit and word level access of word 20 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50B4.F:0 R/W MSS Egress LUT Data 20 [14F:140] + AQ_MssEgressLutDataControlRegister_HHD.u20.bits_20.mssEgressLutData_20 + + Default = 0x0000 + + LUT data bits 335:320 + + */ + unsigned int mssEgressLutData_20 : 16; /* 1E.50B4.F:0 R/W Default = 0x0000 */ + /* LUT data bits 335:320 + */ + } bits_20; + uint16_t word_20; + } u20; + /*! \brief Union for bit and word level access of word 21 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50B5.F:0 R/W MSS Egress LUT Data 21 [15F:150] + AQ_MssEgressLutDataControlRegister_HHD.u21.bits_21.mssEgressLutData_21 + + Default = 0x0000 + + LUT data bits 351:336 + + */ + unsigned int mssEgressLutData_21 : 16; /* 1E.50B5.F:0 R/W Default = 0x0000 */ + /* LUT data bits 351:336 + */ + } bits_21; + uint16_t word_21; + } u21; + /*! \brief Union for bit and word level access of word 22 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50B6.F:0 R/W MSS Egress LUT Data 22 [16F:160] + AQ_MssEgressLutDataControlRegister_HHD.u22.bits_22.mssEgressLutData_22 + + Default = 0x0000 + + LUT data bits 367:352 + + */ + unsigned int mssEgressLutData_22 : 16; /* 1E.50B6.F:0 R/W Default = 0x0000 */ + /* LUT data bits 367:352 + */ + } bits_22; + uint16_t word_22; + } u22; + /*! \brief Union for bit and word level access of word 23 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50B7.F:0 R/W MSS Egress LUT Data 23 [17F:170] + AQ_MssEgressLutDataControlRegister_HHD.u23.bits_23.mssEgressLutData_23 + + Default = 0x0000 + + LUT data bits 383:368 + + */ + unsigned int mssEgressLutData_23 : 16; /* 1E.50B7.F:0 R/W Default = 0x0000 */ + /* LUT data bits 383:368 + */ + } bits_23; + uint16_t word_23; + } u23; + /*! \brief Union for bit and word level access of word 24 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50B8.F:0 R/W MSS Egress LUT Data 24 [18F:180] + AQ_MssEgressLutDataControlRegister_HHD.u24.bits_24.mssEgressLutData_24 + + Default = 0x0000 + + LUT data bits 399:384 + + */ + unsigned int mssEgressLutData_24 : 16; /* 1E.50B8.F:0 R/W Default = 0x0000 */ + /* LUT data bits 399:384 + */ + } bits_24; + uint16_t word_24; + } u24; + /*! \brief Union for bit and word level access of word 25 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50B9.F:0 R/W MSS Egress LUT Data 25 [19F:190] + AQ_MssEgressLutDataControlRegister_HHD.u25.bits_25.mssEgressLutData_25 + + Default = 0x0000 + + LUT data bits 415:400 + + */ + unsigned int mssEgressLutData_25 : 16; /* 1E.50B9.F:0 R/W Default = 0x0000 */ + /* LUT data bits 415:400 + */ + } bits_25; + uint16_t word_25; + } u25; + /*! \brief Union for bit and word level access of word 26 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50BA.F:0 R/W MSS Egress LUT Data 26 [1AF:1A0] + AQ_MssEgressLutDataControlRegister_HHD.u26.bits_26.mssEgressLutData_26 + + Default = 0x0000 + + LUT data bits 431:416 + + */ + unsigned int mssEgressLutData_26 : 16; /* 1E.50BA.F:0 R/W Default = 0x0000 */ + /* LUT data bits 431:416 + */ + } bits_26; + uint16_t word_26; + } u26; + /*! \brief Union for bit and word level access of word 27 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50BB.F:0 R/W MSS Egress LUT Data 27 [1BF:1B0] + AQ_MssEgressLutDataControlRegister_HHD.u27.bits_27.mssEgressLutData_27 + + Default = 0x0000 + + LUT data bits 447:432 + + */ + unsigned int mssEgressLutData_27 : 16; /* 1E.50BB.F:0 R/W Default = 0x0000 */ + /* LUT data bits 447:432 + */ + } bits_27; + uint16_t word_27; + } u27; +} AQ_MssEgressLutDataControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System General Control Register: 1E.6004 */ +/* MSM System General Control Register: 1E.6004 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System General Control Register */ + union + { + struct + { + /*! \brief 1E.6004.0 R/W MSM System Tx Enable + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemTxEnable + + Default = 0x0 + + 1 = Tx enable + + Notes: + MAC Rx path enable. Should be set to 1 to enable the MAC Rx path. Should be set to 0 to disable the MAC Rx path. */ + unsigned int msmSystemTxEnable : 1; /* 1E.6004.0 R/W Default = 0x0 */ + /* 1 = Tx enable */ + /*! \brief 1E.6004.1 R/W MSM System Rx Enable + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemRxEnable + + Default = 0x0 + + 1 = Rx enable + + Notes: + MAC Tx path enable. Should be set to 1 to enable the MAC Tx path. Should be set to 0 to disable the MAC Tx path. */ + unsigned int msmSystemRxEnable : 1; /* 1E.6004.1 R/W Default = 0x0 */ + /* 1 = Rx enable */ + unsigned int reserved0 : 1; + /*! \brief 1E.6004.3 R/W MSM System WAN Mode + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemWanMode + + Default = 0x0 + + 1 = WAN mode + 0 = LAN mode + + + Notes: + WAN mode enable. Sets WAN mode when set to 1 and LAN mode when set to 0. Note: When changing the mode, verifiy correct setting of the Tx IPG. */ + unsigned int msmSystemWanMode : 1; /* 1E.6004.3 R/W Default = 0x0 */ + /* 1 = WAN mode + 0 = LAN mode + */ + /*! \brief 1E.6004.4 R/W MSM System Promiscuous Mode + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemPromiscuousMode + + Default = 0x0 + + 1 = Promiscuous mode + + + Notes: + When set to 1, all frames are received without any MAC address filtering. */ + unsigned int msmSystemPromiscuousMode : 1; /* 1E.6004.4 R/W Default = 0x0 */ + /* 1 = Promiscuous mode + */ + /*! \brief 1E.6004.5 R/W MSM System PAD Enable + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemPadEnable + + Default = 0x0 + + 1 = Enable frame padding removal on Rx + + + Notes: + When set to 1, enable frame padding removal on the Rx path. If enabled, padding is removed before the frame is transferred to the MAC client application. If disabled, no padding is removed on the Rx by the MAC. + Note : On Tx, the MAC always adds padding as required. */ + unsigned int msmSystemPadEnable : 1; /* 1E.6004.5 R/W Default = 0x0 */ + /* 1 = Enable frame padding removal on Rx + */ + /*! \brief 1E.6004.6 R/W MSM System CRC Forward + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemCrcForward + + Default = 0x0 + + 1 = Enable CRC forwarding + + + Notes: + When set to 1, the CRC field of the received frames is forwarded with the frame to the user application. If disabled, the CRC field is stripped from the frame. + Note : If padding is enabled ( See MAC PAD Enable set to 1), this bit is ignored. */ + unsigned int msmSystemCrcForward : 1; /* 1E.6004.6 R/W Default = 0x0 */ + /* 1 = Enable CRC forwarding + */ + /*! \brief 1E.6004.7 R/W MSM System Pause Forward + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemPauseForward + + Default = 0x0 + + 1 = Enable Pause forwarding + + + Notes: + Terminate or forward pause frames. If set to 1, pause frames are forwarded to the user application. In normal mode, when set to 0, pause frames are terminated and discarded within the MAC. */ + unsigned int msmSystemPauseForward : 1; /* 1E.6004.7 R/W Default = 0x0 */ + /* 1 = Enable Pause forwarding + */ + /*! \brief 1E.6004.8 R/W MSM System Pause Ignore + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemPauseIgnore + + Default = 0x0 + + 1 = Ignore pause frames + + + Notes: + Ignore pause frame quanta. If set to 1, received pause frames are ignored by the MAC. When set to 0, the Tx is stopped for the amount of time specified in the pause quanta received within the pause frame. */ + unsigned int msmSystemPauseIgnore : 1; /* 1E.6004.8 R/W Default = 0x0 */ + /* 1 = Ignore pause frames + */ + /*! \brief 1E.6004.9 R/W MSM System Tx Address Insert Enable + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemTxAddressInsertEnable + + Default = 0x0 + + 1 = Insert Tx MAC source address + + + Notes: + Set the source MAC address on transmit. If set to 1, the MAC overwrites the source MAC address with the MAC programmed address in all transmitted frames. When set to 0, the source MAC address is transmitted unmodified from the MAC Tx client application. */ + unsigned int msmSystemTxAddressInsertEnable : 1; /* 1E.6004.9 R/W Default = 0x0 */ + /* 1 = Insert Tx MAC source address + */ + /*! \brief 1E.6004.A R/W MSM System Tx CRC Append + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemTxCrcAppend + + Default = 0x0 + + 1 = Append Tx CRC + + + Notes: + Permanently enable CRC append on transmit. If set to 1, the Tx will append a CRC to all transmitted frames. If set to 0, CRC append can be controlled on a per frame basis using the pin ff_tx_crc. + This configuration bit is OR'ed with the external ff_tx_crc pin to instruct the Tx to append a CRC to transmitted frames. The ff_tx_crc pin is tied to 0. */ + unsigned int msmSystemTxCrcAppend : 1; /* 1E.6004.A R/W Default = 0x0 */ + /* 1 = Append Tx CRC + */ + /*! \brief 1E.6004.B R/W MSM System Tx Pad Enable + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemTxPadEnable + + Default = 0x1 + + 1 = Enable Tx padding + + + Notes: + When set to 1, enable padding of frames in the Tx direction. When set to 0, the MAC will not extend frames from the application to a minimum of 64 bytes, allowing to transmit short frames (violating the Ethernet mimimum size requirements). Must be set to 1 for normal operation. */ + unsigned int msmSystemTxPadEnable : 1; /* 1E.6004.B R/W Default = 0x1 */ + /* 1 = Enable Tx padding + */ + /*! \brief 1E.6004.C R/WSC MSM System Soft Reset + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemSoftReset + + Default = 0x0 + + 1 = Soft reset + + + Notes: + Software reset. Self clearing bit. When set to 1, resets all statistic counters as well as the Tx and Rx FIFOs. It should be issued after all traffic has been stopped as a result of clearing the Rx/Tx enable bits ( See MAC Rx Enable set to 0 and See MAC Tx Enable set to 0). + Note : Can lead to an Rx interface (ff_rx_xxx) violations to the application if the reset is issued in the middle of a receive frame transfer. Then the end of packet (assertion of ff_rx_eop) is lost and the application should be prepeared to handle this exception. */ + unsigned int msmSystemSoftReset : 1; /* 1E.6004.C R/WSC Default = 0x0 */ + /* 1 = Soft reset + */ + /*! \brief 1E.6004.D R/W MSM System Control Frame Enable + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemControlFrameEnable + + Default = 0x0 + + 1 = Control frame enabled + + + Notes: + MAC control frame enable. When set to 1, the MAC control frames with any Opcode other than 0x0001 are accepted and forwarded to the client interface. When set to 0, MAC control frames with any opcode other than 0x0001 are silently discarded. */ + unsigned int msmSystemControlFrameEnable : 1; /* 1E.6004.D R/W Default = 0x0 */ + /* 1 = Control frame enabled + */ + /*! \brief 1E.6004.E R/W MSM System Rx Error Discard + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemRxErrorDiscard + + Default = 0x0 + + 1 = Enable discard of received errored frames + + + Notes: + Rx errored frame discard enable. When set to 1, any frame received with an error is discarded and not forwarded to the client interface. When set to 0, errored frames are forwarded to the client interface with ff_rx_err asserted. + Note : It is recommended to set this bit to 1 only when store and forward operation is enabled (RX_SECTION_FULL TBD). */ + unsigned int msmSystemRxErrorDiscard : 1; /* 1E.6004.E R/W Default = 0x0 */ + /* 1 = Enable discard of received errored frames + */ + /*! \brief 1E.6004.F R/W MSM System PHY Tx Enable + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemPhyTxEnable + + Default = 0x0 + + 1 = Enable PHY Tx + + + Notes: + Directly controls the phy_tx_ena pin. */ + unsigned int msmSystemPhyTxEnable : 1; /* 1E.6004.F R/W Default = 0x0 */ + /* 1 = Enable PHY Tx + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System General Control Register */ + union + { + struct + { + /*! \brief 1E.6005.0 R/W MSM System Force Send IDLE + AQ_MsmSystemGeneralControlRegister_HHD.u1.bits_1.msmSystemForceSendIdle + + Default = 0x0 + + 1 = Force send idle + + Notes: + When set to 1, suppress any frame transmissions and forces IDLE n the Tx interface instead of frames. This control affects the MAC reconciliation layer (RS) which acts after all MAC datapath has processed the frame. + Note : Does not have an effect on fault handling (i.e. reception of local fault will still cause transmit of remote fault). + Must be 0 for normal operation. */ + unsigned int msmSystemForceSendIdle : 1; /* 1E.6005.0 R/W Default = 0x0 */ + /* 1 = Force send idle */ + /*! \brief 1E.6005.1 R/W MSM System Length Check Disable + AQ_MsmSystemGeneralControlRegister_HHD.u1.bits_1.msmSystemLengthCheckDisable + + Default = 0x0 + + 1 = Disable length check + + Notes: + Payload length check disable. When set to 0, the MAC checks the frames payload length with the frame length/type field. When set to 1, the payload length check is disabled. */ + unsigned int msmSystemLengthCheckDisable : 1; /* 1E.6005.1 R/W Default = 0x0 */ + /* 1 = Disable length check */ + /*! \brief 1E.6005.2 R/W MSM System IDLE Column Count Extend + AQ_MsmSystemGeneralControlRegister_HHD.u1.bits_1.msmSystemIdleColumnCountExtend + + Default = 0x0 + + 1 = Extend IDLE column count + + Notes: + When set to 1, extends the RS layer IDLE column counter by 2x. The IEEE 802.3ae defines the fault condition to be cleared after 128 columns of IDLE have been received. If the MAC operates together with a WAN mode PCS (WIS) it may may happen (depending on PCS) that this period is too short to bridge the IDLE stuffing occurring in this mode, leading to a toggling fault indication. In this case, extending the counter helps to aoivd toggling fault indications. */ + unsigned int msmSystemIdleColumnCountExtend : 1; /* 1E.6005.2 R/W Default = 0x0 */ + /* 1 = Extend IDLE column count */ + /*! \brief 1E.6005.3 R/W MSM System Priority Flow Control Enable + AQ_MsmSystemGeneralControlRegister_HHD.u1.bits_1.msmSystemPriorityFlowControlEnable + + Default = 0x0 + + 1 = Enable priority flow control + 0 = Enable link flow control + + + Notes: + Enable priority flow control (PFC) mode of operation. When set to 0, the MAC uses standard link pause frames. When set to 1, the MAC will transmit and accept PFC frames. */ + unsigned int msmSystemPriorityFlowControlEnable : 1; /* 1E.6005.3 R/W Default = 0x0 */ + /* 1 = Enable priority flow control + 0 = Enable link flow control + */ + unsigned int reserved2 : 1; + /*! \brief 1E.6005.5 R/W MSM System SFD Check Disable + AQ_MsmSystemGeneralControlRegister_HHD.u1.bits_1.msmSystemSfdCheckDisable + + Default = 0x0 + + 1 = Disable SFD check + + + Notes: + Disable check of SFD (0xD5) character at frame start. When set to 1, the frame is accepted even if the SFD byte following the preamble is not 0xD5. When set to 0, a frame is accepted only if the SFD byte is found with the value 0xD5. */ + unsigned int msmSystemSfdCheckDisable : 1; /* 1E.6005.5 R/W Default = 0x0 */ + /* 1 = Disable SFD check + */ + unsigned int reserved1 : 1; + /*! \brief 1E.6005.7 R/W MSM System Tx Low Power IDLE Enable + AQ_MsmSystemGeneralControlRegister_HHD.u1.bits_1.msmSystemTxLowPowerIdleEnable + + Default = 0x0 + + 1 = Transmit LPI enable + + + Notes: + Transmit low power IDLE enable. When set to 1, the MAC completes the transmission of the current frame and generates low power IDLE sequences (LPI) to the XGMII/SGMII. When set to 0, the MAC operates in normal mode. This bit is OR'ed with the reg_lowp_ena pin. */ + unsigned int msmSystemTxLowPowerIdleEnable : 1; /* 1E.6005.7 R/W Default = 0x0 */ + /* 1 = Transmit LPI enable + */ + unsigned int reserved0 : 8; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemGeneralControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System FIFO Control Register: 1E.600E */ +/* MSM System FIFO Control Register: 1E.600E */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System FIFO Control Register */ + union + { + struct + { + /*! \brief 1E.600E.7:0 R/W MSM System Rx FIFO Full Threshold [7:0] + AQ_MsmSystemFifoControlRegister_HHD.u0.bits_0.msmSystemRxFifoFullThreshold + + Default = 0x08 + + Rx FIFO full threshold + + Notes: + All threshold values are in steps of FIFO words. */ + unsigned int msmSystemRxFifoFullThreshold : 8; /* 1E.600E.7:0 R/W Default = 0x08 */ + /* Rx FIFO full threshold */ + unsigned int reserved0 : 8; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System FIFO Control Register */ + union + { + struct + { + /*! \brief 1E.600F.7:0 R/W MSM System Rx FIFO Empty Threshold [7:0] + AQ_MsmSystemFifoControlRegister_HHD.u1.bits_1.msmSystemRxFifoEmptyThreshold + + Default = 0x00 + + Rx FIFO empty threshold + + Notes: + All threshold values are in steps of FIFO words. */ + unsigned int msmSystemRxFifoEmptyThreshold : 8; /* 1E.600F.7:0 R/W Default = 0x00 */ + /* Rx FIFO empty threshold */ + unsigned int reserved0 : 8; + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of MSM System FIFO Control Register */ + union + { + struct + { + /*! \brief 1E.6010.5:0 R/W MSM System Tx FIFO Full Threshold [5:0] + AQ_MsmSystemFifoControlRegister_HHD.u2.bits_2.msmSystemTxFifoFullThreshold + + Default = 0x08 + + Tx FIFO full threshold + + Notes: + All threshold values are in steps of FIFO words. */ + unsigned int msmSystemTxFifoFullThreshold : 6; /* 1E.6010.5:0 R/W Default = 0x08 */ + /* Tx FIFO full threshold */ + unsigned int reserved0 : 10; + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of MSM System FIFO Control Register */ + union + { + struct + { + /*! \brief 1E.6011.5:0 R/W MSM System Tx FIFO Empty Threshold [5:0] + AQ_MsmSystemFifoControlRegister_HHD.u3.bits_3.msmSystemTxFifoEmptyThreshold + + Default = 0x00 + + Tx FIFO empty threshold + + Notes: + All threshold values are in steps of FIFO words. */ + unsigned int msmSystemTxFifoEmptyThreshold : 6; /* 1E.6011.5:0 R/W Default = 0x00 */ + /* Tx FIFO empty threshold */ + unsigned int reserved0 : 10; + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of MSM System FIFO Control Register */ + union + { + struct + { + /*! \brief 1E.6012.7:0 ROS MSM System Rx FIFO Almost Full Threshold [7:0] + AQ_MsmSystemFifoControlRegister_HHD.u4.bits_4.msmSystemRxFifoAlmostFullThreshold + + Default = 0x00 + + Rx FIFO almost full threshold + + Notes: + Unused. */ + unsigned int msmSystemRxFifoAlmostFullThreshold : 8; /* 1E.6012.7:0 ROS Default = 0x00 */ + /* Rx FIFO almost full threshold */ + unsigned int reserved0 : 8; + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of MSM System FIFO Control Register */ + union + { + struct + { + /*! \brief 1E.6013.7:0 ROS MSM System Rx FIFO Almost Empty Threshold [7:0] + AQ_MsmSystemFifoControlRegister_HHD.u5.bits_5.msmSystemRxFifoAlmostEmptyThreshold + + Default = 0x00 + + Rx FIFO almost empty threshold + + Notes: + Unused. */ + unsigned int msmSystemRxFifoAlmostEmptyThreshold : 8; /* 1E.6013.7:0 ROS Default = 0x00 */ + /* Rx FIFO almost empty threshold */ + unsigned int reserved0 : 8; + } bits_5; + uint16_t word_5; + } u5; + /*! \brief Union for bit and word level access of word 6 of MSM System FIFO Control Register */ + union + { + struct + { + /*! \brief 1E.6014.7:0 ROS MSM System Tx FIFO Almost Full Threshold [7:0] + AQ_MsmSystemFifoControlRegister_HHD.u6.bits_6.msmSystemTxFifoAlmostFullThreshold + + Default = 0x00 + + Tx FIFO almost full threshold + + Notes: + Unused. */ + unsigned int msmSystemTxFifoAlmostFullThreshold : 8; /* 1E.6014.7:0 ROS Default = 0x00 */ + /* Tx FIFO almost full threshold */ + unsigned int reserved0 : 8; + } bits_6; + uint16_t word_6; + } u6; + /*! \brief Union for bit and word level access of word 7 of MSM System FIFO Control Register */ + union + { + struct + { + /*! \brief 1E.6015.7:0 ROS MSM System Tx FIFO Almost Empty Threshold [7:0] + AQ_MsmSystemFifoControlRegister_HHD.u7.bits_7.msmSystemTxFifoAlmostEmptyThreshold + + Default = 0x00 + + Tx FIFO almost empty threshold + + Notes: + Unused. */ + unsigned int msmSystemTxFifoAlmostEmptyThreshold : 8; /* 1E.6015.7:0 ROS Default = 0x00 */ + /* Tx FIFO almost empty threshold */ + unsigned int reserved0 : 8; + } bits_7; + uint16_t word_7; + } u7; +} AQ_MsmSystemFifoControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System General Status Register: 1E.6020 */ +/* MSM System General Status Register: 1E.6020 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System General Status Register */ + union + { + struct + { + /*! \brief 1E.6020.0 BLH MSM System Rx Local Fault + AQ_MsmSystemGeneralStatusRegister_HHD.u0.bits_0.msmSystemRxLocalFault + + + + Rx local fault detected + + Notes: + Latch high local fault status. Set to 1, whent he MAC detects Rx local fault sequences on the Rx interface. Reset to 0 after read and after reset. */ + unsigned int msmSystemRxLocalFault : 1; /* 1E.6020.0 BLH */ + /* Rx local fault detected */ + /*! \brief 1E.6020.1 BLH MSM System Rx Remote Fault + AQ_MsmSystemGeneralStatusRegister_HHD.u0.bits_0.msmSystemRxRemoteFault + + + + Rx remote fault detected + + Notes: + Latch high local fault status. Set to 1, whent he MAC detects Rx local fault sequences on the Rx interface. Reset to 0 after read and after reset. */ + unsigned int msmSystemRxRemoteFault : 1; /* 1E.6020.1 BLH */ + /* Rx remote fault detected */ + /*! \brief 1E.6020.2 RO MSM System PHY Loss of Signal + AQ_MsmSystemGeneralStatusRegister_HHD.u0.bits_0.msmSystemPhyLossOfSignal + + + + PHY loss of signal + + Notes: + PHY indicates loss of signal. This is the value of pin phy_los which is tied to 0. */ + unsigned int msmSystemPhyLossOfSignal : 1; /* 1E.6020.2 RO */ + /* PHY loss of signal */ + /*! \brief 1E.6020.3 R/W MSM System Timestamp Available + AQ_MsmSystemGeneralStatusRegister_HHD.u0.bits_0.msmSystemTimestampAvailable + + Default = 0x0 + + Timestamp available + + Notes: + Transmit timestamp available. Indicates that the timestamp of the last transmitted event frame (which had ff_tx_ts_frm=1) is available in the register See MAC Time Stamp Status 0 [F:0] and See MAC Time Stamp Status 1 [F:0] . To clear this bit, the bit must be written with a 1. + */ + unsigned int msmSystemTimestampAvailable : 1; /* 1E.6020.3 R/W Default = 0x0 */ + /* Timestamp available */ + /*! \brief 1E.6020.4 RO MSM System Rx Low Power IDLE + AQ_MsmSystemGeneralStatusRegister_HHD.u0.bits_0.msmSystemRxLowPowerIdle + + + + Rx LPI detected + + Notes: + Receive low power IDLE (LPI). Set to 1 when LPI is currently detected on the MAC Rx interface. Set to 0, when the MAC currently operates in normal mode. */ + unsigned int msmSystemRxLowPowerIdle : 1; /* 1E.6020.4 RO */ + /* Rx LPI detected */ + /*! \brief 1E.6020.5 RO MSM System Tx FIFO Empty + AQ_MsmSystemGeneralStatusRegister_HHD.u0.bits_0.msmSystemTxFifoEmpty + + + + Tx FIFO empty + + Notes: + When set to 1, indicates the Tx FIFO is empty. When set to 0, Tx FIFO is non-empty. */ + unsigned int msmSystemTxFifoEmpty : 1; /* 1E.6020.5 RO */ + /* Tx FIFO empty */ + unsigned int reserved0 : 10; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System General Status Register */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemGeneralStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Tx IPG Control Register: 1E.6022 */ +/* MSM System Tx IPG Control Register: 1E.6022 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Tx IPG Control Register */ + union + { + struct + { + /*! \brief 1E.6022.5:0 R/W MSM System Tx IPG Length [5:0] + AQ_MsmSystemTxIpgControlRegister_HHD.u0.bits_0.msmSystemTxIpgLength + + Default = 0x0C + + Tx IPG length + + Notes: + Tx inter-packet gap (IPG) value. Depending on LAN or WAN mode of operation. + LAN Mode : Number of octets in steps of 4. Valid values are 8, 12, 16,..., 100. DIC is supported for any setting > 8. A default of 12 must be set to conform to IEEE802.3ae. + WAN Mode : Stretch factor. Valid values are 4 ... 15. The stretch factor is calculated as (value+1)*8. A default of 12 must be set to conform to IEEE802.3ae (i.e. 13*8=104). A larger value shrinks the IPG (increasing bandwidth). + The reset value of 12 leads to IEEE802.3ae conformant behavior in both modes. + Note : WAN mode is only available in 10G mode of operation. */ + unsigned int msmSystemTxIpgLength : 6; /* 1E.6022.5:0 R/W Default = 0x0C */ + /* Tx IPG length */ + unsigned int reserved0 : 10; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Tx IPG Control Register */ + union + { + struct + { + /*! \brief 1E.6023.F:0 MSM System Tx IPG Reserved + AQ_MsmSystemTxIpgControlRegister_HHD.u1.bits_1.msmSystemTxIpgReserved + + + + Value always 0, writes ignored + */ + unsigned int msmSystemTxIpgReserved : 16; /* 1E.6023.F:0 */ + /* Value always 0, writes ignored */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemTxIpgControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Tx Good Frames Counter Register: 1E.6040 */ +/* MSM System Tx Good Frames Counter Register: 1E.6040 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Tx Good Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6040.F:0 ROS MSM System Tx Good Frames Counter 0 [F:0] + AQ_MsmSystemTxGoodFramesCounterRegister_HHD.u0.bits_0.msmSystemTxGoodFramesCounter_0 + + Default = 0x0000 + + Tx good frame counter bits 15:0 + + Notes: + Count of frames transmitted without error (Including pause frames). */ + unsigned int msmSystemTxGoodFramesCounter_0 : 16; /* 1E.6040.F:0 ROS Default = 0x0000 */ + /* Tx good frame counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Tx Good Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6041.F:0 ROS MSM System Tx Good Frames Counter 1 [F:0] + AQ_MsmSystemTxGoodFramesCounterRegister_HHD.u1.bits_1.msmSystemTxGoodFramesCounter_1 + + Default = 0x0000 + + Tx good frame counter bits 31:16 + + + Notes: + Count of frames transmitted without error (Including pause frames). */ + unsigned int msmSystemTxGoodFramesCounter_1 : 16; /* 1E.6041.F:0 ROS Default = 0x0000 */ + /* Tx good frame counter bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemTxGoodFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx Good Frames Counter Register: 1E.6044 */ +/* MSM System Rx Good Frames Counter Register: 1E.6044 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx Good Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6044.F:0 ROS MSM System Rx Good Frames Counter 0 [F:0] + AQ_MsmSystemRxGoodFramesCounterRegister_HHD.u0.bits_0.msmSystemRxGoodFramesCounter_0 + + Default = 0x0000 + + Rx good frame counter bits 15:0 + + Notes: + Count of frames received without error (Including pause frames). */ + unsigned int msmSystemRxGoodFramesCounter_0 : 16; /* 1E.6044.F:0 ROS Default = 0x0000 */ + /* Rx good frame counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx Good Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6045.F:0 ROS MSM System Rx Good Frames Counter 1 [F:0] + AQ_MsmSystemRxGoodFramesCounterRegister_HHD.u1.bits_1.msmSystemRxGoodFramesCounter_1 + + Default = 0x0000 + + Rx good frame counter bits 31:16 + + Notes: + Count of frames received without error (Including pause frames). */ + unsigned int msmSystemRxGoodFramesCounter_1 : 16; /* 1E.6045.F:0 ROS Default = 0x0000 */ + /* Rx good frame counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxGoodFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx FCS Errors Counter Register: 1E.6048 */ +/* MSM System Rx FCS Errors Counter Register: 1E.6048 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx FCS Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.6048.F:0 ROS MSM System FCS Error Counter 0 [F:0] + AQ_MsmSystemRxFcsErrorsCounterRegister_HHD.u0.bits_0.msmSystemFcsErrorCounter_0 + + Default = 0x0000 + + Frame check sequence error counter bits 15:0 + + Notes: + Count of frames for which a CRC-32 Error is detected but the frame is otherwise of correct length. */ + unsigned int msmSystemFcsErrorCounter_0 : 16; /* 1E.6048.F:0 ROS Default = 0x0000 */ + /* Frame check sequence error counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx FCS Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.6049.F:0 ROS MSM System FCS Error Counter 1 [F:0] + AQ_MsmSystemRxFcsErrorsCounterRegister_HHD.u1.bits_1.msmSystemFcsErrorCounter_1 + + Default = 0x0000 + + Frame check sequence error counter bits 31:16 + + Notes: + Count of frames for which a CRC-32 Error is detected but the frame is otherwise of correct length. */ + unsigned int msmSystemFcsErrorCounter_1 : 16; /* 1E.6049.F:0 ROS Default = 0x0000 */ + /* Frame check sequence error counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxFcsErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx Alignment Errors Counter Register: 1E.604C */ +/* MSM System Rx Alignment Errors Counter Register: 1E.604C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx Alignment Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.604C.F:0 ROS MSM System Alignment Error Counter 0 [F:0] + AQ_MsmSystemRxAlignmentErrorsCounterRegister_HHD.u0.bits_0.msmSystemAlignmentErrorCounter_0 + + Default = 0x0000 + + Alignment error counter bits 15:0 + + Notes: + Count of frames received with an alignment error. */ + unsigned int msmSystemAlignmentErrorCounter_0 : 16; /* 1E.604C.F:0 ROS Default = 0x0000 */ + /* Alignment error counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx Alignment Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.604D.F:0 ROS MSM System Alignment Error Counter 1 [F:0] + AQ_MsmSystemRxAlignmentErrorsCounterRegister_HHD.u1.bits_1.msmSystemAlignmentErrorCounter_1 + + Default = 0x0000 + + Alignment error counter bits 31:16 + + Notes: + Count of frames received with an alignment error. */ + unsigned int msmSystemAlignmentErrorCounter_1 : 16; /* 1E.604D.F:0 ROS Default = 0x0000 */ + /* Alignment error counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxAlignmentErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Tx Pause Frames Counter Register: 1E.6050 */ +/* MSM System Tx Pause Frames Counter Register: 1E.6050 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Tx Pause Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6050.F:0 ROS MSM System Tx Pause Frames Counter 0 [F:0] + AQ_MsmSystemTxPauseFramesCounterRegister_HHD.u0.bits_0.msmSystemTxPauseFramesCounter_0 + + Default = 0x0000 + + Tx pause frame counter bits 15:0 + + Notes: + Valid pause frames transmitted. */ + unsigned int msmSystemTxPauseFramesCounter_0 : 16; /* 1E.6050.F:0 ROS Default = 0x0000 */ + /* Tx pause frame counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Tx Pause Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6051.F:0 ROS MSM System Tx Pause Frames Counter 1 [F:0] + AQ_MsmSystemTxPauseFramesCounterRegister_HHD.u1.bits_1.msmSystemTxPauseFramesCounter_1 + + Default = 0x0000 + + Tx pause frame counter bits 31:16 + + + Notes: + Valid pause frames transmitted. */ + unsigned int msmSystemTxPauseFramesCounter_1 : 16; /* 1E.6051.F:0 ROS Default = 0x0000 */ + /* Tx pause frame counter bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemTxPauseFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx Pause Frames Counter Register: 1E.6054 */ +/* MSM System Rx Pause Frames Counter Register: 1E.6054 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx Pause Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6054.F:0 ROS MSM System Rx Pause Frames Counter 0 [F:0] + AQ_MsmSystemRxPauseFramesCounterRegister_HHD.u0.bits_0.msmSystemRxPauseFramesCounter_0 + + Default = 0x0000 + + Rx pause frame counter bits 15:0 + + Notes: + Valid pause frames received. */ + unsigned int msmSystemRxPauseFramesCounter_0 : 16; /* 1E.6054.F:0 ROS Default = 0x0000 */ + /* Rx pause frame counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx Pause Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6055.F:0 ROS MSM System Rx Pause Frames Counter 1 [F:0] + AQ_MsmSystemRxPauseFramesCounterRegister_HHD.u1.bits_1.msmSystemRxPauseFramesCounter_1 + + Default = 0x0000 + + Rx pause frame counter bits 31:16 + + Notes: + Valid pause frames received. */ + unsigned int msmSystemRxPauseFramesCounter_1 : 16; /* 1E.6055.F:0 ROS Default = 0x0000 */ + /* Rx pause frame counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxPauseFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx Too Long Errors Counter Register: 1E.6058 */ +/* MSM System Rx Too Long Errors Counter Register: 1E.6058 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx Too Long Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.6058.F:0 ROS MSM System Rx Too Long Errors Counter 0 [F:0] + AQ_MsmSystemRxTooLongErrorsCounterRegister_HHD.u0.bits_0.msmSystemRxTooLongErrorsCounter_0 + + Default = 0x0000 + + Too-long errors counter bits 15:0 + + Notes: + Frame received exceeded the maximum length programmed with register FRM_LGTH. */ + unsigned int msmSystemRxTooLongErrorsCounter_0 : 16; /* 1E.6058.F:0 ROS Default = 0x0000 */ + /* Too-long errors counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx Too Long Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.6059.F:0 ROS MSM System Rx Too Long Errors Counter 1 [F:0] + AQ_MsmSystemRxTooLongErrorsCounterRegister_HHD.u1.bits_1.msmSystemRxTooLongErrorsCounter_1 + + Default = 0x0000 + + Too-long errors counter bits 31:16 + + Notes: + Frame received exceeded the maximum length programmed with register FRM_LGTH. */ + unsigned int msmSystemRxTooLongErrorsCounter_1 : 16; /* 1E.6059.F:0 ROS Default = 0x0000 */ + /* Too-long errors counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxTooLongErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx In Range Length Errors Counter Register: 1E.605C */ +/* MSM System Rx In Range Length Errors Counter Register: 1E.605C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx In Range Length Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.605C.F:0 ROS MSM System Rx In Range Length Errors Counter 0 [F:0] + AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_HHD.u0.bits_0.msmSystemRxInRangeLengthErrorsCounter_0 + + Default = 0x0000 + + In-range-length errors counter bits 15:0 + + Notes: + A count of frames with a length/type field value between 46 (VLAN: 42) and less than 0x0600, that does not match the number of payload data octets received. Should count also if length/type field is less than 46 (VLAN: 42) and the frame is longer than 64 bytes. */ + unsigned int msmSystemRxInRangeLengthErrorsCounter_0 : 16; /* 1E.605C.F:0 ROS Default = 0x0000 */ + /* In-range-length errors counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx In Range Length Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.605D.F:0 ROS MSM System Rx In Range Length Errors Counter 1 [F:0] + AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_HHD.u1.bits_1.msmSystemRxInRangeLengthErrorsCounter_1 + + Default = 0x0000 + + In-range-length errors counter bits 31:16 + + Notes: + A count of frames with a length/type field value between 46 (VLAN: 42) and less than 0x0600, that does not match the number of payload data octets received. Should count also if length/type field is less than 46 (VLAN: 42) and the frame is longer than 64 bytes. */ + unsigned int msmSystemRxInRangeLengthErrorsCounter_1 : 16; /* 1E.605D.F:0 ROS Default = 0x0000 */ + /* In-range-length errors counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Tx VLAN Frames Counter Register: 1E.6060 */ +/* MSM System Tx VLAN Frames Counter Register: 1E.6060 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Tx VLAN Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6060.F:0 ROS MSM System Tx VLAN Frames Counter 0 [F:0] + AQ_MsmSystemTxVlanFramesCounterRegister_HHD.u0.bits_0.msmSystemTxVlanFramesCounter_0 + + Default = 0x0000 + + Tx VLAN frames counter bits 15:0 + + Notes: + Valid VLAN tagged frames transmitted. */ + unsigned int msmSystemTxVlanFramesCounter_0 : 16; /* 1E.6060.F:0 ROS Default = 0x0000 */ + /* Tx VLAN frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Tx VLAN Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6061.F:0 ROS MSM System Tx VLAN Frames Counter 1 [F:0] + AQ_MsmSystemTxVlanFramesCounterRegister_HHD.u1.bits_1.msmSystemTxVlanFramesCounter_1 + + Default = 0x0000 + + Tx VLAN frames counter bits 31:16 + + Notes: + Valid VLAN tagged frames transmitted. */ + unsigned int msmSystemTxVlanFramesCounter_1 : 16; /* 1E.6061.F:0 ROS Default = 0x0000 */ + /* Tx VLAN frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemTxVlanFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx VLAN Frames Counter Register: 1E.6064 */ +/* MSM System Rx VLAN Frames Counter Register: 1E.6064 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx VLAN Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6064.F:0 ROS MSM System Rx VLAN Frames Counter 0 [F:0] + AQ_MsmSystemRxVlanFramesCounterRegister_HHD.u0.bits_0.msmSystemRxVlanFramesCounter_0 + + Default = 0x0000 + + Rx VLAN frames counter bits 15:0 + + Notes: + Valid VLAN tagged frames received. */ + unsigned int msmSystemRxVlanFramesCounter_0 : 16; /* 1E.6064.F:0 ROS Default = 0x0000 */ + /* Rx VLAN frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx VLAN Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6065.F:0 ROS MSM System Rx VLAN Frames Counter 1 [F:0] + AQ_MsmSystemRxVlanFramesCounterRegister_HHD.u1.bits_1.msmSystemRxVlanFramesCounter_1 + + Default = 0x0000 + + Rx VLAN frames counter bits 31:16 + + Notes: + Valid VLAN tagged frames received. */ + unsigned int msmSystemRxVlanFramesCounter_1 : 16; /* 1E.6065.F:0 ROS Default = 0x0000 */ + /* Rx VLAN frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxVlanFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Tx Octets Counter Register: 1E.6068 */ +/* MSM System Tx Octets Counter Register: 1E.6068 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Tx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.6068.F:0 ROS MSM System Tx Octets Counter 0 [F:0] + AQ_MsmSystemTxOctetsCounterRegister_HHD.u0.bits_0.msmSystemTxOctetsCounter_0 + + Default = 0x0000 + + Tx octets counter bits 15:0 + + Notes: + All octets transmitted except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames transmitted. */ + unsigned int msmSystemTxOctetsCounter_0 : 16; /* 1E.6068.F:0 ROS Default = 0x0000 */ + /* Tx octets counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Tx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.6069.F:0 ROS MSM System Tx Octets Counter 1 [F:0] + AQ_MsmSystemTxOctetsCounterRegister_HHD.u1.bits_1.msmSystemTxOctetsCounter_1 + + Default = 0x0000 + + Tx octets counter bits 31:16 + + Notes: + All octets transmitted except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames transmitted. */ + unsigned int msmSystemTxOctetsCounter_1 : 16; /* 1E.6069.F:0 ROS Default = 0x0000 */ + /* Tx octets counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of MSM System Tx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.606A.F:0 ROS MSM System Tx Octets Counter 2 [F:0] + AQ_MsmSystemTxOctetsCounterRegister_HHD.u2.bits_2.msmSystemTxOctetsCounter_2 + + Default = 0x0000 + + Tx octets counter bits 47:32 + + Notes: + All octets transmitted except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames transmitted. */ + unsigned int msmSystemTxOctetsCounter_2 : 16; /* 1E.606A.F:0 ROS Default = 0x0000 */ + /* Tx octets counter bits 47:32 */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of MSM System Tx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.606B.F:0 ROS MSM System Tx Octets Counter 3 [F:0] + AQ_MsmSystemTxOctetsCounterRegister_HHD.u3.bits_3.msmSystemTxOctetsCounter_3 + + Default = 0x0000 + + Tx octets counter bits 63:48 + + Notes: + All octets transmitted except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames transmitted. */ + unsigned int msmSystemTxOctetsCounter_3 : 16; /* 1E.606B.F:0 ROS Default = 0x0000 */ + /* Tx octets counter bits 63:48 */ + } bits_3; + uint16_t word_3; + } u3; +} AQ_MsmSystemTxOctetsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx Octets Counter Register: 1E.606C */ +/* MSM System Rx Octets Counter Register: 1E.606C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.606C.F:0 ROS MSM System Rx Octets Counter 0 [F:0] + AQ_MsmSystemRxOctetsCounterRegister_HHD.u0.bits_0.msmSystemRxOctetsCounter_0 + + Default = 0x0000 + + Rx octets counter bits 15:0 + + Notes: + All octets received except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames received. */ + unsigned int msmSystemRxOctetsCounter_0 : 16; /* 1E.606C.F:0 ROS Default = 0x0000 */ + /* Rx octets counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.606D.F:0 ROS MSM System Rx Octets Counter 1 [F:0] + AQ_MsmSystemRxOctetsCounterRegister_HHD.u1.bits_1.msmSystemRxOctetsCounter_1 + + Default = 0x0000 + + Rx octets counter bits 31:16 + + Notes: + All octets received except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames received. */ + unsigned int msmSystemRxOctetsCounter_1 : 16; /* 1E.606D.F:0 ROS Default = 0x0000 */ + /* Rx octets counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxOctetsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx Unicast Frames Counter Register: 1E.6070 */ +/* MSM System Rx Unicast Frames Counter Register: 1E.6070 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx Unicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6070.F:0 ROS MSM System Rx Unicast Frames Counter 0 [F:0] + AQ_MsmSystemRxUnicastFramesCounterRegister_HHD.u0.bits_0.msmSystemRxUnicastFramesCounter_0 + + Default = 0x0000 + + Rx unicast frames counter bits 15:0 + + Notes: + Incremented with each valid frame received on the receive FIFO interface and bit 0 of the destination address was '0'. */ + unsigned int msmSystemRxUnicastFramesCounter_0 : 16; /* 1E.6070.F:0 ROS Default = 0x0000 */ + /* Rx unicast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx Unicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6071.F:0 ROS MSM System Rx Unicast Frames Counter 1 [F:0] + AQ_MsmSystemRxUnicastFramesCounterRegister_HHD.u1.bits_1.msmSystemRxUnicastFramesCounter_1 + + Default = 0x0000 + + Rx unicast frames counter bits 31:16 + + Notes: + Incremented with each valid frame received on the receive FIFO interface and bit 0 of the destination address was '0'. */ + unsigned int msmSystemRxUnicastFramesCounter_1 : 16; /* 1E.6071.F:0 ROS Default = 0x0000 */ + /* Rx unicast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxUnicastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx Multicast Frames Counter Register: 1E.6074 */ +/* MSM System Rx Multicast Frames Counter Register: 1E.6074 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx Multicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6074.F:0 ROS MSM System Rx Multicast Frames Counter 0 [F:0] + AQ_MsmSystemRxMulticastFramesCounterRegister_HHD.u0.bits_0.msmSystemRxMulticastFramesCounter_0 + + Default = 0x0000 + + Rx multicast frames counter bits 15:0 + + Notes: + Incremented with each valid frame received on the receive FIFO interface and bit 0 of the destination address was '1' but not the broadcast address (all bits set '1' ). Pause frames are not counted. */ + unsigned int msmSystemRxMulticastFramesCounter_0 : 16; /* 1E.6074.F:0 ROS Default = 0x0000 */ + /* Rx multicast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx Multicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6075.F:0 ROS MSM System Rx Multicast Frames Counter 1 [F:0] + AQ_MsmSystemRxMulticastFramesCounterRegister_HHD.u1.bits_1.msmSystemRxMulticastFramesCounter_1 + + Default = 0x0000 + + Rx multicast frames counter bits 31:16 + + Notes: + Incremented with each valid frame received on the receive FIFO interface and bit 0 of the destination address was '1' but not the broadcast address (all bits set '1' ). Pause frames are not counted. */ + unsigned int msmSystemRxMulticastFramesCounter_1 : 16; /* 1E.6075.F:0 ROS Default = 0x0000 */ + /* Rx multicast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxMulticastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx Broadcast Frames Counter Register: 1E.6078 */ +/* MSM System Rx Broadcast Frames Counter Register: 1E.6078 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx Broadcast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6078.F:0 ROS MSM System Rx Broadcast Frames Counter 0 [F:0] + AQ_MsmSystemRxBroadcastFramesCounterRegister_HHD.u0.bits_0.msmSystemRxBroadcastFramesCounter_0 + + Default = 0x0000 + + Rx broadcast frames counter bits 15:0 + + Notes: + Incremented with each valid frame received on the receive FIFO interface (FIFO) and all bits of the destination address were set '1'. */ + unsigned int msmSystemRxBroadcastFramesCounter_0 : 16; /* 1E.6078.F:0 ROS Default = 0x0000 */ + /* Rx broadcast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx Broadcast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6079.F:0 ROS MSM System Rx Broadcast Frames Counter 1 [F:0] + AQ_MsmSystemRxBroadcastFramesCounterRegister_HHD.u1.bits_1.msmSystemRxBroadcastFramesCounter_1 + + Default = 0x0000 + + Rx broadcast frames counter bits 31:16 + + Notes: + Incremented with each valid frame received on the receive FIFO interface (FIFO) and all bits of the destination address were set '1'. */ + unsigned int msmSystemRxBroadcastFramesCounter_1 : 16; /* 1E.6079.F:0 ROS Default = 0x0000 */ + /* Rx broadcast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxBroadcastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Tx Errors Counter Register: 1E.607C */ +/* MSM System Tx Errors Counter Register: 1E.607C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Tx Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.607C.F:0 ROS MSM System Tx Errors Counter 0 [F:0] + AQ_MsmSystemTxErrorsCounterRegister_HHD.u0.bits_0.msmSystemTxErrorsCounter_0 + + Default = 0x0000 + + Rx errors counter bits 15:0 + + Notes: + Number of frames transmitted with error: + - FIFO Overflow Errors + - FIFO Underflow Errors */ + unsigned int msmSystemTxErrorsCounter_0 : 16; /* 1E.607C.F:0 ROS Default = 0x0000 */ + /* Rx errors counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Tx Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.607D.F:0 ROS MSM System Tx Errors Counter 1 [F:0] + AQ_MsmSystemTxErrorsCounterRegister_HHD.u1.bits_1.msmSystemTxErrorsCounter_1 + + Default = 0x0000 + + Tx errors counter bits 31:16 + + Notes: + Number of frames transmitted with error: + - FIFO Overflow Errors + - FIFO Underflow Errors */ + unsigned int msmSystemTxErrorsCounter_1 : 16; /* 1E.607D.F:0 ROS Default = 0x0000 */ + /* Tx errors counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemTxErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Tx Unicast Frames Counter Register: 1E.6084 */ +/* MSM System Tx Unicast Frames Counter Register: 1E.6084 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Tx Unicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6084.F:0 ROS MSM System Tx Unicast Frames Counter 0 [F:0] + AQ_MsmSystemTxUnicastFramesCounterRegister_HHD.u0.bits_0.msmSystemTxUnicastFramesCounter_0 + + Default = 0x0000 + + Tx unicast frames counter bits 15:0 + + Notes: + Incremented with each frame written to the FIFO interface and bit 0 of the destination address set to '0'. */ + unsigned int msmSystemTxUnicastFramesCounter_0 : 16; /* 1E.6084.F:0 ROS Default = 0x0000 */ + /* Tx unicast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Tx Unicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6085.F:0 ROS MSM System Tx Unicast Frames Counter 1 [F:0] + AQ_MsmSystemTxUnicastFramesCounterRegister_HHD.u1.bits_1.msmSystemTxUnicastFramesCounter_1 + + Default = 0x0000 + + Tx unicast frames counter bits 31:16 + + Notes: + Incremented with each frame written to the FIFO interface and bit 0 of the destination address set to '0'. */ + unsigned int msmSystemTxUnicastFramesCounter_1 : 16; /* 1E.6085.F:0 ROS Default = 0x0000 */ + /* Tx unicast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemTxUnicastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Tx Multicast Frames Counter Register: 1E.6088 */ +/* MSM System Tx Multicast Frames Counter Register: 1E.6088 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Tx Multicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6088.F:0 ROS MSM System Tx Multicast Frames Counter 0 [F:0] + AQ_MsmSystemTxMulticastFramesCounterRegister_HHD.u0.bits_0.msmSystemTxMulticastFramesCounter_0 + + Default = 0x0000 + + Tx multicast frames counter bits 15:0 + + Notes: + Incremented with each frame written to the FIFO interface and bit 0 of the destination address set to '1' but not the broadcast address (all bits '1'). */ + unsigned int msmSystemTxMulticastFramesCounter_0 : 16; /* 1E.6088.F:0 ROS Default = 0x0000 */ + /* Tx multicast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Tx Multicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6089.F:0 ROS MSM System Tx Multicast Frames Counter 1 [F:0] + AQ_MsmSystemTxMulticastFramesCounterRegister_HHD.u1.bits_1.msmSystemTxMulticastFramesCounter_1 + + Default = 0x0000 + + Tx multicast frames counter bits 31:16 + + Notes: + Incremented with each frame written to the FIFO interface and bit 0 of the destination address set to '1' but not the broadcast address (all bits '1'). */ + unsigned int msmSystemTxMulticastFramesCounter_1 : 16; /* 1E.6089.F:0 ROS Default = 0x0000 */ + /* Tx multicast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemTxMulticastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Tx Broadcast Frames Counter Register: 1E.608C */ +/* MSM System Tx Broadcast Frames Counter Register: 1E.608C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Tx Broadcast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.608C.F:0 ROS MSM System Tx Broadcast Frames Counter 0 [F:0] + AQ_MsmSystemTxBroadcastFramesCounterRegister_HHD.u0.bits_0.msmSystemTxBroadcastFramesCounter_0 + + Default = 0x0000 + + Tx broadcast frames counter bits 15:0 + + Notes: + Incremented with each frame written to the FIFO interface and all bits of the destination address set to '1'. */ + unsigned int msmSystemTxBroadcastFramesCounter_0 : 16; /* 1E.608C.F:0 ROS Default = 0x0000 */ + /* Tx broadcast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Tx Broadcast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.608D.F:0 ROS MSM System Tx Broadcast Frames Counter 1 [F:0] + AQ_MsmSystemTxBroadcastFramesCounterRegister_HHD.u1.bits_1.msmSystemTxBroadcastFramesCounter_1 + + Default = 0x0000 + + Tx broadcast frames counter bits 31:16 + + Notes: + Incremented with each frame written to the FIFO interface and all bits of the destination address set to '1'. */ + unsigned int msmSystemTxBroadcastFramesCounter_1 : 16; /* 1E.608D.F:0 ROS Default = 0x0000 */ + /* Tx broadcast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemTxBroadcastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx Errors Counter Register: 1E.60C8 */ +/* MSM System Rx Errors Counter Register: 1E.60C8 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.60C8.F:0 ROS MSM System Rx Errors Counter 0 [F:0] + AQ_MsmSystemRxErrorsCounterRegister_HHD.u0.bits_0.msmSystemRxErrorsCounter_0 + + Default = 0x0000 + + Rx errors counter bits 15:0 + + Notes: + Number of frames received with error: + - FIFO Overflow Errors + - CRC Errors + - Payload Length Errors + - Jabber and Oversized Errors + - Alignment Errors + - The dedicated Error Code (0xfe, not a code error) was received */ + unsigned int msmSystemRxErrorsCounter_0 : 16; /* 1E.60C8.F:0 ROS Default = 0x0000 */ + /* Rx errors counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.60C9.F:0 ROS MSM System Rx Errors Counter 1 [F:0] + AQ_MsmSystemRxErrorsCounterRegister_HHD.u1.bits_1.msmSystemRxErrorsCounter_1 + + Default = 0x0000 + + Rx errors counter bits 31:16 + + Notes: + Number of frames received with error: + - FIFO Overflow Errors + - CRC Errors + - Payload Length Errors + - Jabber and Oversized Errors + - Alignment Errors + - The dedicated Error Code (0xfe, not a code error) was received */ + unsigned int msmSystemRxErrorsCounter_1 : 16; /* 1E.60C9.F:0 ROS Default = 0x0000 */ + /* Rx errors counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress VLAN TPID 0 Register: 1E.8006 */ +/* MSS Ingress VLAN TPID 0 Register: 1E.8006 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress VLAN TPID 0 Register */ + union + { + struct + { + /*! \brief 1E.8006.F:0 R/W MSS Ingress VLAN STag [F:0] + AQ_MssIngressVlanTpid_0Register_HHD.u0.bits_0.mssIngressVlanStag + + Default = 0x0000 + + STag TPID + + + Notes: + Service Tag Protocol Identifier (TPID) values to identify a VLAN tag. The " See SEC Egress VLAN CP Tag Parse STag " bit must be set to 1 for the incoming packet's TPID to be parsed. */ + unsigned int mssIngressVlanStag : 16; /* 1E.8006.F:0 R/W Default = 0x0000 */ + /* STag TPID + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress VLAN TPID 0 Register */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressVlanTpid_0Register_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress VLAN TPID 1 Register: 1E.8008 */ +/* MSS Ingress VLAN TPID 1 Register: 1E.8008 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress VLAN TPID 1 Register */ + union + { + struct + { + /*! \brief 1E.8008.F:0 R/W MSS Ingress VLAN QTag [F:0] + AQ_MssIngressVlanTpid_1Register_HHD.u0.bits_0.mssIngressVlanQtag + + Default = 0x0000 + + QTag TPID + + + Notes: + Customer Tag Protocol Identifier (TPID) values to identify a VLAN tag. The " See SEC Egress VLAN CP Tag Parse QTag " bit must be set to 1 for the incoming packet's TPID to be parsed. */ + unsigned int mssIngressVlanQtag : 16; /* 1E.8008.F:0 R/W Default = 0x0000 */ + /* QTag TPID + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress VLAN TPID 1 Register */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressVlanTpid_1Register_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress VLAN Control Register: 1E.800A */ +/* MSS Ingress VLAN Control Register: 1E.800A */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress VLAN Control Register */ + union + { + struct + { + /*! \brief 1E.800A.F:0 R/W MSS Ingress VLAN UP Map Table LSW [F:0] + AQ_MssIngressVlanControlRegister_HHD.u0.bits_0.mssIngressVlanUpMapTableLSW + + Default = 0x0000 + + Map table bits 15:0 + + + Notes: + If there is a customer TPID Tag match and no service TPID Tag match or the service TPID Tag match is disabled, the outer TAG's PCP is used to index into this map table to generate the packets user priority. + 2:0 : UP value for customer Tag PCP 0x0 + 5:3: UP value for customer Tag PCP 0x0 + 8:6 : UP value for customer Tag PCP 0x0 + 11:9 : UP value for customer Tag PCP 0x0 + 14:12 : UP value for customer Tag PCP 0x0 + 17:15 : UP value for customer Tag PCP 0x0 */ + unsigned int mssIngressVlanUpMapTableLSW : 16; /* 1E.800A.F:0 R/W Default = 0x0000 */ + /* Map table bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress VLAN Control Register */ + union + { + struct + { + /*! \brief 1E.800B.7:0 R/W MSS Ingress VLAN UP Map Table MSW [17:10] + AQ_MssIngressVlanControlRegister_HHD.u1.bits_1.mssIngressVlanUpMapTableMSW + + Default = 0x00 + + UP Map table bits 23:16 + + + Notes: + If there is a customer TPID Tag match and no service TPID Tag match or the service TPID Tag match is disabled, the outer TAG's PCP is used to index into this map table to generate the packets user priority. + 2:0 : UP value for customer Tag PCP 0x0 + 5:3: UP value for customer Tag PCP 0x0 + 8:6 : UP value for customer Tag PCP 0x0 + 11:9 : UP value for customer Tag PCP 0x0 + 14:12 : UP value for customer Tag PCP 0x0 + 17:15 : UP value for customer Tag PCP 0x0 + 20:18 : UP value for customer Tag PCP 0x0 + 23:21 : UP value for customer Tag PCP 0x0 */ + unsigned int mssIngressVlanUpMapTableMSW : 8; /* 1E.800B.7:0 R/W Default = 0x00 */ + /* UP Map table bits 23:16 + */ + /*! \brief 1E.800B.A:8 R/W MSS Ingress VLAN UP Default [2:0] + AQ_MssIngressVlanControlRegister_HHD.u1.bits_1.mssIngressVlanUpDefault + + Default = 0x0 + + UP default + + + Notes: + User priority default */ + unsigned int mssIngressVlanUpDefault : 3; /* 1E.800B.A:8 R/W Default = 0x0 */ + /* UP default + */ + /*! \brief 1E.800B.B R/W MSS Ingress VLAN STag UP Parse Enable + AQ_MssIngressVlanControlRegister_HHD.u1.bits_1.mssIngressVlanStagUpParseEnable + + Default = 0x0 + + VLAN CP Tag STag UP enable + + + Notes: + Enable controlled port service VLAN service Tag user priority field parsing. */ + unsigned int mssIngressVlanStagUpParseEnable : 1; /* 1E.800B.B R/W Default = 0x0 */ + /* VLAN CP Tag STag UP enable + */ + /*! \brief 1E.800B.C R/W MSS Ingress VLAN QTag UP Parse Enable + AQ_MssIngressVlanControlRegister_HHD.u1.bits_1.mssIngressVlanQtagUpParseEnable + + Default = 0x0 + + VLAN CP Tag QTag UP enable + + + Notes: + Enable controlled port customer VLAN customer Tag user priority field parsing. */ + unsigned int mssIngressVlanQtagUpParseEnable : 1; /* 1E.800B.C R/W Default = 0x0 */ + /* VLAN CP Tag QTag UP enable + */ + /*! \brief 1E.800B.D R/W MSS Ingress VLAN QinQ Parse Enable + AQ_MssIngressVlanControlRegister_HHD.u1.bits_1.mssIngressVlanQinqParseEnable + + Default = 0x0 + + VLAN CP Tag Parse QinQ + + + Notes: + Enable controlled port VLAN QinQ Tag parsing. When this bit is set to 1 both the outer and inner VLAN Tags will be parsed. */ + unsigned int mssIngressVlanQinqParseEnable : 1; /* 1E.800B.D R/W Default = 0x0 */ + /* VLAN CP Tag Parse QinQ + */ + /*! \brief 1E.800B.E R/W MSS Ingress VLAN STag Parse Enable + AQ_MssIngressVlanControlRegister_HHD.u1.bits_1.mssIngressVlanStagParseEnable + + Default = 0x0 + + 1 = Enable VLAN STag parsing + + + Notes: + Enable controlled port VLAN service Tag parsing. When this bit is set to 1, the incoming packets outer TPID will be compared with the configured " See MSS Ingress VLAN Stag [F:0] " for matching. If the " See SEC Egress VLAN CP Tag Parse QinQ " bit is set to1, this will also be used to compare the incoming packet's inner TPID. */ + unsigned int mssIngressVlanStagParseEnable : 1; /* 1E.800B.E R/W Default = 0x0 */ + /* 1 = Enable VLAN STag parsing + */ + /*! \brief 1E.800B.F R/W MSS Ingress VLAN QTag Parse Enable + AQ_MssIngressVlanControlRegister_HHD.u1.bits_1.mssIngressVlanQtagParseEnable + + Default = 0x0 + + 1 = Enable VLAN QTag parsing + + + Notes: + Enable controlled port VLAN customer Tag parsing. When this bit is set to 1, the incoming packet's outer TPID will be compared with the configured " See MSS Ingress VLAN QTag [F:0] " for matching. If the " See SEC Egress VLAN CP Tag Parse QinQ " bit is set to1, this will also be used to compare the incoming packet's inner TPID. */ + unsigned int mssIngressVlanQtagParseEnable : 1; /* 1E.800B.F R/W Default = 0x0 */ + /* 1 = Enable VLAN QTag parsing + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressVlanControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress MTU Size Control Register: 1E.800C */ +/* MSS Ingress MTU Size Control Register: 1E.800C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress MTU Size Control Register */ + union + { + struct + { + /*! \brief 1E.800C.F:0 R/W MSS Ingress Controlled Packet MTU Size [F:0] + AQ_MssIngressMtuSizeControlRegister_HHD.u0.bits_0.mssIngressControlledPacketMtuSize + + Default = 0x05DC + + Maximum transmission unit for controlled packet + + + Notes: + Maximum transmission unit of controlled packet */ + unsigned int mssIngressControlledPacketMtuSize : 16; /* 1E.800C.F:0 R/W Default = 0x05DC */ + /* Maximum transmission unit for controlled packet + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress MTU Size Control Register */ + union + { + struct + { + /*! \brief 1E.800D.F:0 R/W MSS Ingress Uncontrolled Packet MTU Size [F:0] + AQ_MssIngressMtuSizeControlRegister_HHD.u1.bits_1.mssIngressUncontrolledPacketMtuSize + + Default = 0x05DC + + Maximum transmission unit for uncontrolled packet + + + Notes: + Maximum transmission unit of uncontrolled packet */ + unsigned int mssIngressUncontrolledPacketMtuSize : 16; /* 1E.800D.F:0 R/W Default = 0x05DC */ + /* Maximum transmission unit for uncontrolled packet + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressMtuSizeControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress Control Register: 1E.800E */ +/* MSS Ingress Control Register: 1E.800E */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress Control Register */ + union + { + struct + { + /*! \brief 1E.800E.0 R/W MSS Ingress Soft Reset + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressSoftReset + + Default = 0x0 + + 1 = Soft reset + + + Notes: + S/W reset */ + unsigned int mssIngressSoftReset : 1; /* 1E.800E.0 R/W Default = 0x0 */ + /* 1 = Soft reset + */ + /*! \brief 1E.800E.1 R/W MSS Ingress Operation Point To Point + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressOperationPointToPoint + + Default = 0x0 + + 1 = Enable the SCI for authorization default + + + Notes: + The default SCI for authorization is configured in See MSS Ingress SCI Default [F:0] See MSS Ingress SCI Default [1F:10] , See MSS Ingress SCI Default [2F:20] , and See MSS Ingress SCI Default [3F:30] . */ + unsigned int mssIngressOperationPointToPoint : 1; /* 1E.800E.1 R/W Default = 0x0 */ + /* 1 = Enable the SCI for authorization default + */ + /*! \brief 1E.800E.2 R/W MSS Ingress Create SCI + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressCreateSci + + Default = 0x0 + + 0 = SCI from IGPRC LUT + + + Notes: + If the SCI is not in the packet and this bit is set to 0, the SCI will be taken from the IGPRC LUT. */ + unsigned int mssIngressCreateSci : 1; /* 1E.800E.2 R/W Default = 0x0 */ + /* 0 = SCI from IGPRC LUT + */ + /*! \brief 1E.800E.3 R/W MSS Ingress Mask Short Length Error + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressMaskShortLengthError + + Default = 0x0 + + Unused + + + Notes: + Unused */ + unsigned int mssIngressMaskShortLengthError : 1; /* 1E.800E.3 R/W Default = 0x0 */ + /* Unused + */ + /*! \brief 1E.800E.4 R/W MSS Ingress Drop Kay Packet + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressDropKayPacket + + Default = 0x0 + + 1 = Drop KaY packets + + + Notes: + Decides whether KaY packets have to be dropped */ + unsigned int mssIngressDropKayPacket : 1; /* 1E.800E.4 R/W Default = 0x0 */ + /* 1 = Drop KaY packets + */ + /*! \brief 1E.800E.5 R/W MSS Ingress Drop IGPRC Miss + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressDropIgprcMiss + + Default = 0x0 + + 1 = Drop IGPRC miss packets + + + Notes: + Decides whether Ingress Pre-Security Classification (IGPRC) LUT miss packets are to be dropped */ + unsigned int mssIngressDropIgprcMiss : 1; /* 1E.800E.5 R/W Default = 0x0 */ + /* 1 = Drop IGPRC miss packets + */ + /*! \brief 1E.800E.6 R/W MSS Ingress Check ICV + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressCheckIcv + + Default = 0x0 + + Unused + + + Notes: + Unused */ + unsigned int mssIngressCheckIcv : 1; /* 1E.800E.6 R/W Default = 0x0 */ + /* Unused + */ + /*! \brief 1E.800E.7 R/W MSS Ingress Clear Global Time + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressClearGlobalTime + + Default = 0x0 + + 1 = Clear global time + + + Notes: + Clear global time */ + unsigned int mssIngressClearGlobalTime : 1; /* 1E.800E.7 R/W Default = 0x0 */ + /* 1 = Clear global time + */ + /*! \brief 1E.800E.8 R/W MSS Ingress Clear Count + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressClearCount + + Default = 0x0 + + 1 = Clear all MIB counters + + + Notes: + If this bit is set to 1, all MIB counters will be cleared. */ + unsigned int mssIngressClearCount : 1; /* 1E.800E.8 R/W Default = 0x0 */ + /* 1 = Clear all MIB counters + */ + /*! \brief 1E.800E.9 R/W MSS Ingress High Priority + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressHighPriority + + Default = 0x0 + + 1 = MIB counter clear on read enable + + + Notes: + If this bit is set to 1, read is given high priority and the MIB count value becomes 0 after read. */ + unsigned int mssIngressHighPriority : 1; /* 1E.800E.9 R/W Default = 0x0 */ + /* 1 = MIB counter clear on read enable + */ + /*! \brief 1E.800E.A R/W MSS Ingress Remove SECTag + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressRemoveSectag + + Default = 0x0 + + 1 = Enable removal of SECTag + + + Notes: + If this bit is set and either of the following two conditions occurs, the SECTag will be removed. + Controlled packet and either the SA or SC is invalid. + IGPRC miss. */ + unsigned int mssIngressRemoveSectag : 1; /* 1E.800E.A R/W Default = 0x0 */ + /* 1 = Enable removal of SECTag + */ + /*! \brief 1E.800E.C:B R/W MSS Ingress Global Validate Frames [1:0] + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressGlobalValidateFrames + + Default = 0x0 + + Default validate frames configuration + + + Notes: + If the SC is invalid or if an IGPRC miss packet condition occurs, this default will be used for the validate frames configuration instead of the validate frame entry in the Ingress SC Table (IGSCT). */ + unsigned int mssIngressGlobalValidateFrames : 2; /* 1E.800E.C:B R/W Default = 0x0 */ + /* Default validate frames configuration + */ + /*! \brief 1E.800E.D R/W MSS Ingress ICV LSB 8 Bytes Enable + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressIcvLsb_8BytesEnable + + Default = 0x0 + + 1 = Use LSB + 0 = Use MSB + + + + Notes: + This bit selects MSB or LSB 8 bytes selection in the case where the ICV is 8 bytes. + 0 = MSB is used. */ + unsigned int mssIngressIcvLsb_8BytesEnable : 1; /* 1E.800E.D R/W Default = 0x0 */ + /* 1 = Use LSB + 0 = Use MSB + + */ + unsigned int reserved0 : 2; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress Control Register */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress SA Control Register: 1E.8010 */ +/* MSS Ingress SA Control Register: 1E.8010 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress SA Control Register */ + union + { + struct + { + /*! \brief 1E.8010.F:0 R/W MSS Ingress SA Threshold LSW [F:0] + AQ_MssIngressSaControlRegister_HHD.u0.bits_0.mssIngressSaThresholdLSW + + Default = 0x0000 + + SA threshold bits 15:0 + + + Notes: + Ingress PN threshold to generate SA threshold interrupt. */ + unsigned int mssIngressSaThresholdLSW : 16; /* 1E.8010.F:0 R/W Default = 0x0000 */ + /* SA threshold bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress SA Control Register */ + union + { + struct + { + /*! \brief 1E.8011.F:0 R/W MSS Ingress SA Threshold MSW [1F:10] + AQ_MssIngressSaControlRegister_HHD.u1.bits_1.mssIngressSaThresholdMSW + + Default = 0x0000 + + SA threshold bits 31:16 + + + Notes: + Ingress PN threshold to generate SA threshold interrupt. */ + unsigned int mssIngressSaThresholdMSW : 16; /* 1E.8011.F:0 R/W Default = 0x0000 */ + /* SA threshold bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressSaControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress Interrupt Status Register: 1E.802E */ +/* MSS Ingress Interrupt Status Register: 1E.802E */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress Interrupt Status Register */ + union + { + struct + { + /*! \brief 1E.802E.0 COW MSS Master Ingress Interrupt + AQ_MssIngressInterruptStatusRegister_HHD.u0.bits_0.mssMasterIngressInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. This bit is set when any one of the above interrupt and the corresponding interrupt enable are both set. The interrupt enable for this bit must also be set for this bit to be set. */ + unsigned int mssMasterIngressInterrupt : 1; /* 1E.802E.0 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.802E.1 COW MSS Ingress SA Expired Interrupt + AQ_MssIngressInterruptStatusRegister_HHD.u0.bits_0.mssIngressSaExpiredInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. This bit is set when the SA PN reaches all ones saturation. */ + unsigned int mssIngressSaExpiredInterrupt : 1; /* 1E.802E.1 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.802E.2 COW MSS Ingress SA Threshold Expired Interrupt + AQ_MssIngressInterruptStatusRegister_HHD.u0.bits_0.mssIngressSaThresholdExpiredInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. This bit is set when the SA PN reaches the See SEC Egress PN Threshold [F:0] and See SEC Egress PN Threshold [1F:10] . */ + unsigned int mssIngressSaThresholdExpiredInterrupt : 1; /* 1E.802E.2 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.802E.3 COW MSS Ingress ICV Error Interrupt + AQ_MssIngressInterruptStatusRegister_HHD.u0.bits_0.mssIngressIcvErrorInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. */ + unsigned int mssIngressIcvErrorInterrupt : 1; /* 1E.802E.3 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.802E.4 COW MSS Ingress Replay Error Interrupt + AQ_MssIngressInterruptStatusRegister_HHD.u0.bits_0.mssIngressReplayErrorInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. */ + unsigned int mssIngressReplayErrorInterrupt : 1; /* 1E.802E.4 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.802E.5 COW MSS Ingress MIB Saturation Interrupt + AQ_MssIngressInterruptStatusRegister_HHD.u0.bits_0.mssIngressMibSaturationInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. This bit is set when the MIB counters reaches all ones saturation. */ + unsigned int mssIngressMibSaturationInterrupt : 1; /* 1E.802E.5 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.802E.6 COW MSS Ingress ECC Error Interrupt + AQ_MssIngressInterruptStatusRegister_HHD.u0.bits_0.mssIngressEccErrorInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. */ + unsigned int mssIngressEccErrorInterrupt : 1; /* 1E.802E.6 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.802E.7 COW MSS Ingress TCI E/C Error Interrupt + AQ_MssIngressInterruptStatusRegister_HHD.u0.bits_0.mssIngressTciE_cErrorInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. This error occurs when the TCI E bit is 1 and the TCI C bit is 0. The packet is not dropped, uncontrolled, or untagged. */ + unsigned int mssIngressTciE_cErrorInterrupt : 1; /* 1E.802E.7 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.802E.8 COW MSS Ingress IGPOC Miss Interrupt + AQ_MssIngressInterruptStatusRegister_HHD.u0.bits_0.mssIngressIgpocMissInterrupt + + Default = 0x0 + + 1 = Interrupt + + */ + unsigned int mssIngressIgpocMissInterrupt : 1; /* 1E.802E.8 COW Default = 0x0 */ + /* 1 = Interrupt + */ + unsigned int reserved0 : 7; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress Interrupt Status Register */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressInterruptStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress Interrupt Mask Register: 1E.8030 */ +/* MSS Ingress Interrupt Mask Register: 1E.8030 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress Interrupt Mask Register */ + union + { + struct + { + /*! \brief 1E.8030.0 R/W MSS Ingress Master Interrupt Enable + AQ_MssIngressInterruptMaskRegister_HHD.u0.bits_0.mssIngressMasterInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + */ + unsigned int mssIngressMasterInterruptEnable : 1; /* 1E.8030.0 R/W Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.8030.1 R/W MSS Ingress SA Expired Interrupt Enable + AQ_MssIngressInterruptMaskRegister_HHD.u0.bits_0.mssIngressSaExpiredInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + */ + unsigned int mssIngressSaExpiredInterruptEnable : 1; /* 1E.8030.1 R/W Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.8030.2 R/W MSS Ingress SA Threshold Expired Interrupt Enable + AQ_MssIngressInterruptMaskRegister_HHD.u0.bits_0.mssIngressSaThresholdExpiredInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + */ + unsigned int mssIngressSaThresholdExpiredInterruptEnable : 1; /* 1E.8030.2 R/W Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.8030.3 R/W MSS Ingress ICV Error Interrupt Enable + AQ_MssIngressInterruptMaskRegister_HHD.u0.bits_0.mssIngressIcvErrorInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + */ + unsigned int mssIngressIcvErrorInterruptEnable : 1; /* 1E.8030.3 R/W Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.8030.4 R/W MSS Ingress Replay Error Interrupt Enable + AQ_MssIngressInterruptMaskRegister_HHD.u0.bits_0.mssIngressReplayErrorInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + */ + unsigned int mssIngressReplayErrorInterruptEnable : 1; /* 1E.8030.4 R/W Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.8030.5 R/W MSS Ingress MIB Saturation Interrupt Enable + AQ_MssIngressInterruptMaskRegister_HHD.u0.bits_0.mssIngressMibSaturationInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + */ + unsigned int mssIngressMibSaturationInterruptEnable : 1; /* 1E.8030.5 R/W Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.8030.6 R/W MSS Ingress ECC Error Interrupt Enable + AQ_MssIngressInterruptMaskRegister_HHD.u0.bits_0.mssIngressEccErrorInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + */ + unsigned int mssIngressEccErrorInterruptEnable : 1; /* 1E.8030.6 R/W Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.8030.7 R/W MSS Ingress TCI E/C Error Interrupt Enable + AQ_MssIngressInterruptMaskRegister_HHD.u0.bits_0.mssIngressTciE_cErrorInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + */ + unsigned int mssIngressTciE_cErrorInterruptEnable : 1; /* 1E.8030.7 R/W Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.8030.8 R/W MSS Ingress IGPOC Miss Interrupt Enable + AQ_MssIngressInterruptMaskRegister_HHD.u0.bits_0.mssIngressIgpocMissInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + */ + unsigned int mssIngressIgpocMissInterruptEnable : 1; /* 1E.8030.8 R/W Default = 0x0 */ + /* 1 = Interrupt enabled + */ + unsigned int reserved0 : 7; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress Interrupt Mask Register */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressInterruptMaskRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress SA ICV Error Status Register: 1E.8032 */ +/* MSS Ingress SA ICV Error Status Register: 1E.8032 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress SA ICV Error Status Register */ + union + { + struct + { + /*! \brief 1E.8032.F:0 COW MSS Ingress SA ICV Error LSW [F:0] + AQ_MssIngressSaIcvErrorStatusRegister_HHD.u0.bits_0.mssIngressSaIcvErrorLSW + + Default = 0x0000 + + SA ICV error bits 15:0 + + + Notes: + When set, these bits identify the SA that has an ICV error. Write these bits to 1 to clear. */ + unsigned int mssIngressSaIcvErrorLSW : 16; /* 1E.8032.F:0 COW Default = 0x0000 */ + /* SA ICV error bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress SA ICV Error Status Register */ + union + { + struct + { + /*! \brief 1E.8033.F:0 COW MSS Ingress SA ICV Error MSW [1F:10] + AQ_MssIngressSaIcvErrorStatusRegister_HHD.u1.bits_1.mssIngressSaIcvErrorMSW + + Default = 0x0000 + + SA ICV error bits 31:16 + + + Notes: + When set, these bits identify the SA that has an ICV error. Write these bits to 1 to clear. */ + unsigned int mssIngressSaIcvErrorMSW : 16; /* 1E.8033.F:0 COW Default = 0x0000 */ + /* SA ICV error bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressSaIcvErrorStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress SA Replay Error Status Register: 1E.8034 */ +/* MSS Ingress SA Replay Error Status Register: 1E.8034 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress SA Replay Error Status Register */ + union + { + struct + { + /*! \brief 1E.8034.F:0 COW MSS Ingress SA Replay Error LSW [F:0] + AQ_MssIngressSaReplayErrorStatusRegister_HHD.u0.bits_0.mssIngressSaReplayErrorLSW + + Default = 0x0000 + + SA replay error bits 15:0 + + + Notes: + When set, these bits identify the SA that has a replay error. Write these bits to 1 to clear. */ + unsigned int mssIngressSaReplayErrorLSW : 16; /* 1E.8034.F:0 COW Default = 0x0000 */ + /* SA replay error bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress SA Replay Error Status Register */ + union + { + struct + { + /*! \brief 1E.8035.F:0 COW MSS Ingress SA Replay Error MSW [1F:10] + AQ_MssIngressSaReplayErrorStatusRegister_HHD.u1.bits_1.mssIngressSaReplayErrorMSW + + Default = 0x0000 + + SA replay error bits 31:16 + + + Notes: + When set, these bits identify the SA that has a replay error. Write these bits to 1 to clear. */ + unsigned int mssIngressSaReplayErrorMSW : 16; /* 1E.8035.F:0 COW Default = 0x0000 */ + /* SA replay error bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressSaReplayErrorStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress SA Expired Status Register: 1E.8036 */ +/* MSS Ingress SA Expired Status Register: 1E.8036 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress SA Expired Status Register */ + union + { + struct + { + /*! \brief 1E.8036.F:0 ROS MSS Ingress SA Expired LSW [F:0] + AQ_MssIngressSaExpiredStatusRegister_HHD.u0.bits_0.mssIngressSaExpiredLSW + + Default = 0x0000 + + SA expired bits 15:0 + + + Notes: + When set, these bits identify the SA that has expired when the SA PN reaches all-ones saturation. Write these bits to 1 to clear. */ + unsigned int mssIngressSaExpiredLSW : 16; /* 1E.8036.F:0 ROS Default = 0x0000 */ + /* SA expired bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress SA Expired Status Register */ + union + { + struct + { + /*! \brief 1E.8037.F:0 ROS MSS Ingress SA Expired MSW [1F:10] + AQ_MssIngressSaExpiredStatusRegister_HHD.u1.bits_1.mssIngressSaExpiredMSW + + Default = 0x0000 + + SA expired bits 31:16 + + + Notes: + When set, these bits identify the SA that has expired when the SA PN reaches all-ones saturation. Write these bits to 1 to clear. */ + unsigned int mssIngressSaExpiredMSW : 16; /* 1E.8037.F:0 ROS Default = 0x0000 */ + /* SA expired bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressSaExpiredStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress SA Threshold Expired Status Register: 1E.8038 */ +/* MSS Ingress SA Threshold Expired Status Register: 1E.8038 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress SA Threshold Expired Status Register */ + union + { + struct + { + /*! \brief 1E.8038.F:0 ROS MSS Ingress SA Threshold Expired LSW [F:0] + AQ_MssIngressSaThresholdExpiredStatusRegister_HHD.u0.bits_0.mssIngressSaThresholdExpiredLSW + + Default = 0x0000 + + SA threshold expired bits 15:0 + + + Notes: + When set, these bits identify the SA that has expired when the SA PN has reached the configured threshold See SEC Egress PN Threshold [F:0] and See SEC Egress PN Threshold [1F:10] . Write these bits to 1 to clear. */ + unsigned int mssIngressSaThresholdExpiredLSW : 16; /* 1E.8038.F:0 ROS Default = 0x0000 */ + /* SA threshold expired bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress SA Threshold Expired Status Register */ + union + { + struct + { + /*! \brief 1E.8039.F:0 ROS MSS Ingress SA Threshold Expired MSW [1F:10] + AQ_MssIngressSaThresholdExpiredStatusRegister_HHD.u1.bits_1.mssIngressSaThresholdExpiredMSW + + Default = 0x0000 + + SA threshold expired bits 31:16 + + + Notes: + When set, these bits identify the SA that has expired when the SA PN has reached the configured threshold See SEC Egress PN Threshold [F:0] and See SEC Egress PN Threshold [1F:10] . Write these bits to 1 to clear. */ + unsigned int mssIngressSaThresholdExpiredMSW : 16; /* 1E.8039.F:0 ROS Default = 0x0000 */ + /* SA threshold expired bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressSaThresholdExpiredStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress ECC Interrupt Status Register: 1E.803A */ +/* MSS Ingress ECC Interrupt Status Register: 1E.803A */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress ECC Interrupt Status Register */ + union + { + struct + { + /*! \brief 1E.803A.F:0 R/W MSS Ingress SA ECC Error Interrupt LSW [F:0] + AQ_MssIngressEccInterruptStatusRegister_HHD.u0.bits_0.mssIngressSaEccErrorInterruptLSW + + Default = 0x0000 + + SA ECC error interrupt bits 15:0 + + + Notes: + When set to 1, indicates that an ECC error occured for the SA. */ + unsigned int mssIngressSaEccErrorInterruptLSW : 16; /* 1E.803A.F:0 R/W Default = 0x0000 */ + /* SA ECC error interrupt bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress ECC Interrupt Status Register */ + union + { + struct + { + /*! \brief 1E.803B.F:0 R/W MSS Ingress SA ECC Error Interrupt MSW [1F:10] + AQ_MssIngressEccInterruptStatusRegister_HHD.u1.bits_1.mssIngressSaEccErrorInterruptMSW + + Default = 0x0000 + + SA ECC error interrupt bits 31:16 + + + Notes: + When set to 1, indicates that an ECC error occured for the SA. */ + unsigned int mssIngressSaEccErrorInterruptMSW : 16; /* 1E.803B.F:0 R/W Default = 0x0000 */ + /* SA ECC error interrupt bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressEccInterruptStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress LUT Address Control Register: 1E.8080 */ +/* MSS Ingress LUT Address Control Register: 1E.8080 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress LUT Address Control Register */ + union + { + struct + { + /*! \brief 1E.8080.8:0 R/W MSS Ingress LUT Address [8:0] + AQ_MssIngressLutAddressControlRegister_HHD.u0.bits_0.mssIngressLutAddress + + Default = 0x000 + + LUT address + + */ + unsigned int mssIngressLutAddress : 9; /* 1E.8080.8:0 R/W Default = 0x000 */ + /* LUT address + */ + unsigned int reserved0 : 3; + /*! \brief 1E.8080.F:C R/W MSS Ingress LUT Select [3:0] + AQ_MssIngressLutAddressControlRegister_HHD.u0.bits_0.mssIngressLutSelect + + Default = 0x0 + + LUT select + + + Notes: + 0x0 : Ingress Pre-Security MAC Control FIlter (IGPRCTLF) LUT + 0x1 : Ingress Pre-Security Classification LUT (IGPRC) + 0x2 : Ingress Packet Format (IGPFMT) SAKey LUT + 0x3 : Ingress Packet Format (IGPFMT) SC/SA LUT + 0x4 : Ingress Post-Security Classification LUT (IGPOC) + 0x5 : Ingress Post-Security MAC Control Filter (IGPOCTLF) LUT + 0x6 : Ingress MIB (IGMIB) */ + unsigned int mssIngressLutSelect : 4; /* 1E.8080.F:C R/W Default = 0x0 */ + /* LUT select + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_MssIngressLutAddressControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress LUT Control Register: 1E.8081 */ +/* MSS Ingress LUT Control Register: 1E.8081 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress LUT Control Register */ + union + { + struct + { + unsigned int reserved0 : 14; + /*! \brief 1E.8081.E R/W MSS Ingress LUT Read + AQ_MssIngressLutControlRegister_HHD.u0.bits_0.mssIngressLutRead + + Default = 0x0 + + 1 = LUT read + + + Notes: + Setting this bit to 1, will read the LUT. This bit will automatically clear to 0. */ + unsigned int mssIngressLutRead : 1; /* 1E.8081.E R/W Default = 0x0 */ + /* 1 = LUT read + */ + /*! \brief 1E.8081.F R/W MSS Ingress LUT Write + AQ_MssIngressLutControlRegister_HHD.u0.bits_0.mssIngressLutWrite + + Default = 0x0 + + 1 = LUT write + + + Notes: + Setting this bit to 1, will write the LUT. This bit will automatically clear to 0. */ + unsigned int mssIngressLutWrite : 1; /* 1E.8081.F R/W Default = 0x0 */ + /* 1 = LUT write + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_MssIngressLutControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress LUT Data Control Register: 1E.80A0 */ +/* MSS Ingress LUT Data Control Register: 1E.80A0 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80A0.F:0 R/W MSS Ingress LUT Data 0 [F:0] + AQ_MssIngressLutDataControlRegister_HHD.u0.bits_0.mssIngressLutData_0 + + Default = 0x0000 + + LUT data bits 15:0 + + */ + unsigned int mssIngressLutData_0 : 16; /* 1E.80A0.F:0 R/W Default = 0x0000 */ + /* LUT data bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80A1.F:0 R/W MSS Ingress LUT Data 1 [1F:10] + AQ_MssIngressLutDataControlRegister_HHD.u1.bits_1.mssIngressLutData_1 + + Default = 0x0000 + + LUT data bits 31:16 + + */ + unsigned int mssIngressLutData_1 : 16; /* 1E.80A1.F:0 R/W Default = 0x0000 */ + /* LUT data bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80A2.F:0 R/W MSS Ingress LUT Data 2 [2F:20] + AQ_MssIngressLutDataControlRegister_HHD.u2.bits_2.mssIngressLutData_2 + + Default = 0x0000 + + LUT data bits 47:32 + + */ + unsigned int mssIngressLutData_2 : 16; /* 1E.80A2.F:0 R/W Default = 0x0000 */ + /* LUT data bits 47:32 + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80A3.F:0 R/W MSS Ingress LUT Data 3 [3F:30] + AQ_MssIngressLutDataControlRegister_HHD.u3.bits_3.mssIngressLutData_3 + + Default = 0x0000 + + LUT data bits 63:48 + + */ + unsigned int mssIngressLutData_3 : 16; /* 1E.80A3.F:0 R/W Default = 0x0000 */ + /* LUT data bits 63:48 + */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80A4.F:0 R/W MSS Ingress LUT Data 4 [4F:40] + AQ_MssIngressLutDataControlRegister_HHD.u4.bits_4.mssIngressLutData_4 + + Default = 0x0000 + + LUT data bits 79:64 + + */ + unsigned int mssIngressLutData_4 : 16; /* 1E.80A4.F:0 R/W Default = 0x0000 */ + /* LUT data bits 79:64 + */ + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80A5.F:0 R/W MSS Ingress LUT Data 5 [5F:50] + AQ_MssIngressLutDataControlRegister_HHD.u5.bits_5.mssIngressLutData_5 + + Default = 0x0000 + + LUT data bits 95:80 + + */ + unsigned int mssIngressLutData_5 : 16; /* 1E.80A5.F:0 R/W Default = 0x0000 */ + /* LUT data bits 95:80 + */ + } bits_5; + uint16_t word_5; + } u5; + /*! \brief Union for bit and word level access of word 6 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80A6.F:0 R/W MSS Ingress LUT Data 6 [6F:60] + AQ_MssIngressLutDataControlRegister_HHD.u6.bits_6.mssIngressLutData_6 + + Default = 0x0000 + + LUT data bits 111:96 + + */ + unsigned int mssIngressLutData_6 : 16; /* 1E.80A6.F:0 R/W Default = 0x0000 */ + /* LUT data bits 111:96 + */ + } bits_6; + uint16_t word_6; + } u6; + /*! \brief Union for bit and word level access of word 7 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80A7.F:0 R/W MSS Ingress LUT Data 7 [7F:70] + AQ_MssIngressLutDataControlRegister_HHD.u7.bits_7.mssIngressLutData_7 + + Default = 0x0000 + + LUT data bits 127:112 + + */ + unsigned int mssIngressLutData_7 : 16; /* 1E.80A7.F:0 R/W Default = 0x0000 */ + /* LUT data bits 127:112 + */ + } bits_7; + uint16_t word_7; + } u7; + /*! \brief Union for bit and word level access of word 8 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80A8.F:0 R/W MSS Ingress LUT Data 8 [8F:80] + AQ_MssIngressLutDataControlRegister_HHD.u8.bits_8.mssIngressLutData_8 + + Default = 0x0000 + + LUT data bits 143:128 + + */ + unsigned int mssIngressLutData_8 : 16; /* 1E.80A8.F:0 R/W Default = 0x0000 */ + /* LUT data bits 143:128 + */ + } bits_8; + uint16_t word_8; + } u8; + /*! \brief Union for bit and word level access of word 9 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80A9.F:0 R/W MSS Ingress LUT Data 9 [9F:90] + AQ_MssIngressLutDataControlRegister_HHD.u9.bits_9.mssIngressLutData_9 + + Default = 0x0000 + + LUT data bits 159:144 + + */ + unsigned int mssIngressLutData_9 : 16; /* 1E.80A9.F:0 R/W Default = 0x0000 */ + /* LUT data bits 159:144 + */ + } bits_9; + uint16_t word_9; + } u9; + /*! \brief Union for bit and word level access of word 10 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80AA.F:0 R/W MSS Ingress LUT Data 10 [AF:A0] + AQ_MssIngressLutDataControlRegister_HHD.u10.bits_10.mssIngressLutData_10 + + Default = 0x0000 + + LUT data bits 175:160 + + */ + unsigned int mssIngressLutData_10 : 16; /* 1E.80AA.F:0 R/W Default = 0x0000 */ + /* LUT data bits 175:160 + */ + } bits_10; + uint16_t word_10; + } u10; + /*! \brief Union for bit and word level access of word 11 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80AB.F:0 R/W MSS Ingress LUT Data 11 [BF:B0] + AQ_MssIngressLutDataControlRegister_HHD.u11.bits_11.mssIngressLutData_11 + + Default = 0x0000 + + LUT data bits 191:176 + + */ + unsigned int mssIngressLutData_11 : 16; /* 1E.80AB.F:0 R/W Default = 0x0000 */ + /* LUT data bits 191:176 + */ + } bits_11; + uint16_t word_11; + } u11; + /*! \brief Union for bit and word level access of word 12 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80AC.F:0 R/W MSS Ingress LUT Data 12 [CF:C0] + AQ_MssIngressLutDataControlRegister_HHD.u12.bits_12.mssIngressLutData_12 + + Default = 0x0000 + + LUT data bits 207:192 + + */ + unsigned int mssIngressLutData_12 : 16; /* 1E.80AC.F:0 R/W Default = 0x0000 */ + /* LUT data bits 207:192 + */ + } bits_12; + uint16_t word_12; + } u12; + /*! \brief Union for bit and word level access of word 13 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80AD.F:0 R/W MSS Ingress LUT Data 13 [DF:D0] + AQ_MssIngressLutDataControlRegister_HHD.u13.bits_13.mssIngressLutData_13 + + Default = 0x0000 + + LUT data bits 223:208 + + */ + unsigned int mssIngressLutData_13 : 16; /* 1E.80AD.F:0 R/W Default = 0x0000 */ + /* LUT data bits 223:208 + */ + } bits_13; + uint16_t word_13; + } u13; + /*! \brief Union for bit and word level access of word 14 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80AE.F:0 R/W MSS Ingress LUT Data 14 [EF:E0] + AQ_MssIngressLutDataControlRegister_HHD.u14.bits_14.mssIngressLutData_14 + + Default = 0x0000 + + LUT data bits 239:224 + + */ + unsigned int mssIngressLutData_14 : 16; /* 1E.80AE.F:0 R/W Default = 0x0000 */ + /* LUT data bits 239:224 + */ + } bits_14; + uint16_t word_14; + } u14; + /*! \brief Union for bit and word level access of word 15 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80AF.F:0 R/W MSS Ingress LUT Data 15 [FF:F0] + AQ_MssIngressLutDataControlRegister_HHD.u15.bits_15.mssIngressLutData_15 + + Default = 0x0000 + + LUT data bits 255:240 + + */ + unsigned int mssIngressLutData_15 : 16; /* 1E.80AF.F:0 R/W Default = 0x0000 */ + /* LUT data bits 255:240 + */ + } bits_15; + uint16_t word_15; + } u15; + /*! \brief Union for bit and word level access of word 16 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80B0.F:0 R/W MSS Ingress LUT Data 16 [10F:100] + AQ_MssIngressLutDataControlRegister_HHD.u16.bits_16.mssIngressLutData_16 + + Default = 0x0000 + + LUT data bits 271:256 + + */ + unsigned int mssIngressLutData_16 : 16; /* 1E.80B0.F:0 R/W Default = 0x0000 */ + /* LUT data bits 271:256 + */ + } bits_16; + uint16_t word_16; + } u16; + /*! \brief Union for bit and word level access of word 17 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80B1.F:0 R/W MSS Ingress LUT Data 17 [11F:110] + AQ_MssIngressLutDataControlRegister_HHD.u17.bits_17.mssIngressLutData_17 + + Default = 0x0000 + + LUT data bits 287:272 + + */ + unsigned int mssIngressLutData_17 : 16; /* 1E.80B1.F:0 R/W Default = 0x0000 */ + /* LUT data bits 287:272 + */ + } bits_17; + uint16_t word_17; + } u17; + /*! \brief Union for bit and word level access of word 18 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80B2.F:0 R/W MSS Ingress LUT Data 18 [12F:120] + AQ_MssIngressLutDataControlRegister_HHD.u18.bits_18.mssIngressLutData_18 + + Default = 0x0000 + + LUT data bits 303:288 + + */ + unsigned int mssIngressLutData_18 : 16; /* 1E.80B2.F:0 R/W Default = 0x0000 */ + /* LUT data bits 303:288 + */ + } bits_18; + uint16_t word_18; + } u18; + /*! \brief Union for bit and word level access of word 19 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80B3.F:0 R/W MSS Ingress LUT Data 19 [13F:130] + AQ_MssIngressLutDataControlRegister_HHD.u19.bits_19.mssIngressLutData_19 + + Default = 0x0000 + + LUT data bits 319:304 + + */ + unsigned int mssIngressLutData_19 : 16; /* 1E.80B3.F:0 R/W Default = 0x0000 */ + /* LUT data bits 319:304 + */ + } bits_19; + uint16_t word_19; + } u19; + /*! \brief Union for bit and word level access of word 20 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80B4.F:0 R/W MSS Ingress LUT Data 20 [14F:140] + AQ_MssIngressLutDataControlRegister_HHD.u20.bits_20.mssIngressLutData_20 + + Default = 0x0000 + + LUT data bits 335:320 + + */ + unsigned int mssIngressLutData_20 : 16; /* 1E.80B4.F:0 R/W Default = 0x0000 */ + /* LUT data bits 335:320 + */ + } bits_20; + uint16_t word_20; + } u20; + /*! \brief Union for bit and word level access of word 21 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80B5.F:0 R/W MSS Ingress LUT Data 21 [15F:150] + AQ_MssIngressLutDataControlRegister_HHD.u21.bits_21.mssIngressLutData_21 + + Default = 0x0000 + + LUT data bits 351:336 + + */ + unsigned int mssIngressLutData_21 : 16; /* 1E.80B5.F:0 R/W Default = 0x0000 */ + /* LUT data bits 351:336 + */ + } bits_21; + uint16_t word_21; + } u21; + /*! \brief Union for bit and word level access of word 22 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80B6.F:0 R/W MSS Ingress LUT Data 22 [16F:160] + AQ_MssIngressLutDataControlRegister_HHD.u22.bits_22.mssIngressLutData_22 + + Default = 0x0000 + + LUT data bits 367:352 + + */ + unsigned int mssIngressLutData_22 : 16; /* 1E.80B6.F:0 R/W Default = 0x0000 */ + /* LUT data bits 367:352 + */ + } bits_22; + uint16_t word_22; + } u22; + /*! \brief Union for bit and word level access of word 23 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80B7.F:0 R/W MSS Ingress LUT Data 23 [17F:170] + AQ_MssIngressLutDataControlRegister_HHD.u23.bits_23.mssIngressLutData_23 + + Default = 0x0000 + + LUT data bits 383:368 + + */ + unsigned int mssIngressLutData_23 : 16; /* 1E.80B7.F:0 R/W Default = 0x0000 */ + /* LUT data bits 383:368 + */ + } bits_23; + uint16_t word_23; + } u23; +} AQ_MssIngressLutDataControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line General Control Register: 1E.9004 */ +/* MSM Line General Control Register: 1E.9004 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line General Control Register */ + union + { + struct + { + /*! \brief 1E.9004.0 R/W MSM Line Tx Enable + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLineTxEnable + + Default = 0x0 + + 1 = Tx enable + + Notes: + MAC Rx path enable. Should be set to 1 to enable the MAC Rx path. Should be set to 0 to disable the MAC Rx path. */ + unsigned int msmLineTxEnable : 1; /* 1E.9004.0 R/W Default = 0x0 */ + /* 1 = Tx enable */ + /*! \brief 1E.9004.1 R/W MSM Line Rx Enable + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLineRxEnable + + Default = 0x0 + + 1 = Rx enable + + Notes: + MAC Tx path enable. Should be set to 1 to enable the MAC Tx path. Should be set to 0 to disable the MAC Tx path. */ + unsigned int msmLineRxEnable : 1; /* 1E.9004.1 R/W Default = 0x0 */ + /* 1 = Rx enable */ + unsigned int reserved0 : 1; + /*! \brief 1E.9004.3 R/W MSM Line WAN Mode + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLineWanMode + + Default = 0x0 + + 1 = WAN mode + 0 = LAN mode + + + Notes: + WAN mode enable. Sets WAN mode when set to 1 and LAN mode when set to 0. Note: When changing the mode, verifiy correct setting of the Tx IPG. */ + unsigned int msmLineWanMode : 1; /* 1E.9004.3 R/W Default = 0x0 */ + /* 1 = WAN mode + 0 = LAN mode + */ + /*! \brief 1E.9004.4 R/W MSM Line Promiscuous Mode + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLinePromiscuousMode + + Default = 0x0 + + 1 = Promiscuous mode + + + Notes: + When set to 1, all frames are received without any MAC address filtering. */ + unsigned int msmLinePromiscuousMode : 1; /* 1E.9004.4 R/W Default = 0x0 */ + /* 1 = Promiscuous mode + */ + /*! \brief 1E.9004.5 R/W MSM Line PAD Enable + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLinePadEnable + + Default = 0x0 + + 1 = Enable frame padding removal on Rx + + + Notes: + When set to 1, enable frame padding removal on the Rx path. If enabled, padding is removed before the frame is transferred to the MAC client application. If disabled, no padding is removed on the Rx by the MAC. + Note : On Tx, the MAC always adds padding as required. */ + unsigned int msmLinePadEnable : 1; /* 1E.9004.5 R/W Default = 0x0 */ + /* 1 = Enable frame padding removal on Rx + */ + /*! \brief 1E.9004.6 R/W MSM Line CRC Forward + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLineCrcForward + + Default = 0x0 + + 1 = Enable CRC forwarding + + + Notes: + When set to 1, the CRC field of the received frames is forwarded with the frame to the user application. If disabled, the CRC field is stripped from the frame. + Note : If padding is enabled ( See MAC PAD Enable set to 1), this bit is ignored. */ + unsigned int msmLineCrcForward : 1; /* 1E.9004.6 R/W Default = 0x0 */ + /* 1 = Enable CRC forwarding + */ + /*! \brief 1E.9004.7 R/W MSM Line Pause Forward + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLinePauseForward + + Default = 0x0 + + 1 = Enable Pause forwarding + + + Notes: + Terminate or forward pause frames. If set to 1, pause frames are forwarded to the user application. In normal mode, when set to 0, pause frames are terminated and discarded within the MAC. */ + unsigned int msmLinePauseForward : 1; /* 1E.9004.7 R/W Default = 0x0 */ + /* 1 = Enable Pause forwarding + */ + /*! \brief 1E.9004.8 R/W MSM Line Pause Ignore + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLinePauseIgnore + + Default = 0x0 + + 1 = Ignore pause frames + + + Notes: + Ignore pause frame quanta. If set to 1, received pause frames are ignored by the MAC. When set to 0, the Tx is stopped for the amount of time specified in the pause quanta received within the pause frame. */ + unsigned int msmLinePauseIgnore : 1; /* 1E.9004.8 R/W Default = 0x0 */ + /* 1 = Ignore pause frames + */ + /*! \brief 1E.9004.9 R/W MSM Line Tx Address Insert Enable + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLineTxAddressInsertEnable + + Default = 0x0 + + 1 = Insert Tx MAC source address + + + Notes: + Set the source MAC address on transmit. If set to 1, the MAC overwrites the source MAC address with the MAC programmed address in all transmitted frames. When set to 0, the source MAC address is transmitted unmodified from the MAC Tx client application. */ + unsigned int msmLineTxAddressInsertEnable : 1; /* 1E.9004.9 R/W Default = 0x0 */ + /* 1 = Insert Tx MAC source address + */ + /*! \brief 1E.9004.A R/W MSM Line Tx CRC Append + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLineTxCrcAppend + + Default = 0x0 + + 1 = Append Tx CRC + + + Notes: + Permanently enable CRC append on transmit. If set to 1, the Tx will append a CRC to all transmitted frames. If set to 0, CRC append can be controlled on a per frame basis using the pin ff_tx_crc. + This configuration bit is OR'ed with the external ff_tx_crc pin to instruct the Tx to append a CRC to transmitted frames. The ff_tx_crc pin is tied to 0. */ + unsigned int msmLineTxCrcAppend : 1; /* 1E.9004.A R/W Default = 0x0 */ + /* 1 = Append Tx CRC + */ + /*! \brief 1E.9004.B R/W MSM Line Tx Pad Enable + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLineTxPadEnable + + Default = 0x1 + + 1 = Enable Tx padding + + + Notes: + When set to 1, enable padding of frames in the Tx direction. When set to 0, the MAC will not extend frames from the application to a minimum of 64 bytes, allowing to transmit short frames (violating the Ethernet mimimum size requirements). Must be set to 1 for normal operation. */ + unsigned int msmLineTxPadEnable : 1; /* 1E.9004.B R/W Default = 0x1 */ + /* 1 = Enable Tx padding + */ + /*! \brief 1E.9004.C R/WSC MSM Line Soft Reset + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLineSoftReset + + Default = 0x0 + + 1 = Soft reset + + + Notes: + Software reset. Self clearing bit. When set to 1, resets all statistic counters as well as the Tx and Rx FIFOs. It should be issued after all traffic has been stopped as a result of clearing the Rx/Tx enable bits ( See MAC Rx Enable set to 0 and See MAC Tx Enable set to 0). + Note : Can lead to an Rx interface (ff_rx_xxx) violations to the application if the reset is issued in the middle of a receive frame transfer. Then the end of packet (assertion of ff_rx_eop) is lost and the application should be prepeared to handle this exception. */ + unsigned int msmLineSoftReset : 1; /* 1E.9004.C R/WSC Default = 0x0 */ + /* 1 = Soft reset + */ + /*! \brief 1E.9004.D R/W MSM Line Control Frame Enable + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLineControlFrameEnable + + Default = 0x0 + + 1 = Control frame enabled + + + Notes: + MAC control frame enable. When set to 1, the MAC control frames with any Opcode other than 0x0001 are accepted and forwarded to the client interface. When set to 0, MAC control frames with any opcode other than 0x0001 are silently discarded. */ + unsigned int msmLineControlFrameEnable : 1; /* 1E.9004.D R/W Default = 0x0 */ + /* 1 = Control frame enabled + */ + /*! \brief 1E.9004.E R/W MSM Line Rx Error Discard + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLineRxErrorDiscard + + Default = 0x0 + + 1 = Enable discard of received errored frames + + + Notes: + Rx errored frame discard enable. When set to 1, any frame received with an error is discarded and not forwarded to the client interface. When set to 0, errored frames are forwarded to the client interface with ff_rx_err asserted. + Note : It is recommended to set this bit to 1 only when store and forward operation is enabled (RX_SECTION_FULL TBD). */ + unsigned int msmLineRxErrorDiscard : 1; /* 1E.9004.E R/W Default = 0x0 */ + /* 1 = Enable discard of received errored frames + */ + /*! \brief 1E.9004.F R/W MSM Line PHY Tx Enable + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLinePhyTxEnable + + Default = 0x0 + + 1 = Enable PHY Tx + + + Notes: + Directly controls the phy_tx_ena pin. */ + unsigned int msmLinePhyTxEnable : 1; /* 1E.9004.F R/W Default = 0x0 */ + /* 1 = Enable PHY Tx + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line General Control Register */ + union + { + struct + { + /*! \brief 1E.9005.0 R/W MSM Line Force Send IDLE + AQ_MsmLineGeneralControlRegister_HHD.u1.bits_1.msmLineForceSendIdle + + Default = 0x0 + + 1 = Force send idle + + Notes: + When set to 1, suppress any frame transmissions and forces IDLE n the Tx interface instead of frames. This control affects the MAC reconciliation layer (RS) which acts after all MAC datapath has processed the frame. + Note : Does not have an effect on fault handling (i.e. reception of local fault will still cause transmit of remote fault). + Must be 0 for normal operation. */ + unsigned int msmLineForceSendIdle : 1; /* 1E.9005.0 R/W Default = 0x0 */ + /* 1 = Force send idle */ + /*! \brief 1E.9005.1 R/W MSM Line Length Check Disable + AQ_MsmLineGeneralControlRegister_HHD.u1.bits_1.msmLineLengthCheckDisable + + Default = 0x0 + + 1 = Disable length check + + Notes: + Payload length check disable. When set to 0, the MAC checks the frames payload length with the frame length/type field. When set to 1, the payload length check is disabled. */ + unsigned int msmLineLengthCheckDisable : 1; /* 1E.9005.1 R/W Default = 0x0 */ + /* 1 = Disable length check */ + /*! \brief 1E.9005.2 R/W MSM Line IDLE Column Count Extend + AQ_MsmLineGeneralControlRegister_HHD.u1.bits_1.msmLineIdleColumnCountExtend + + Default = 0x0 + + 1 = Extend IDLE column count + + Notes: + When set to 1, extends the RS layer IDLE column counter by 2x. The IEEE 802.3ae defines the fault condition to be cleared after 128 columns of IDLE have been received. If the MAC operates together with a WAN mode PCS (WIS) it may may happen (depending on PCS) that this period is too short to bridge the IDLE stuffing occurring in this mode, leading to a toggling fault indication. In this case, extending the counter helps to aoivd toggling fault indications. */ + unsigned int msmLineIdleColumnCountExtend : 1; /* 1E.9005.2 R/W Default = 0x0 */ + /* 1 = Extend IDLE column count */ + /*! \brief 1E.9005.3 R/W MSM Line Priority Flow Control Enable + AQ_MsmLineGeneralControlRegister_HHD.u1.bits_1.msmLinePriorityFlowControlEnable + + Default = 0x0 + + 1 = Enable priority flow control + 0 = Enable link flow control + + + Notes: + Enable priority flow control (PFC) mode of operation. When set to 0, the MAC uses standard link pause frames. When set to 1, the MAC will transmit and accept PFC frames. */ + unsigned int msmLinePriorityFlowControlEnable : 1; /* 1E.9005.3 R/W Default = 0x0 */ + /* 1 = Enable priority flow control + 0 = Enable link flow control + */ + unsigned int reserved2 : 1; + /*! \brief 1E.9005.5 R/W MSM Line SFD Check Disable + AQ_MsmLineGeneralControlRegister_HHD.u1.bits_1.msmLineSfdCheckDisable + + Default = 0x0 + + 1 = Disable SFD check + + + Notes: + Disable check of SFD (0xD5) character at frame start. When set to 1, the frame is accepted even if the SFD byte following the preamble is not 0xD5. When set to 0, a frame is accepted only if the SFD byte is found with the value 0xD5. */ + unsigned int msmLineSfdCheckDisable : 1; /* 1E.9005.5 R/W Default = 0x0 */ + /* 1 = Disable SFD check + */ + unsigned int reserved1 : 1; + /*! \brief 1E.9005.7 R/W MSM Line Tx Low Power IDLE Enable + AQ_MsmLineGeneralControlRegister_HHD.u1.bits_1.msmLineTxLowPowerIdleEnable + + Default = 0x0 + + 1 = Transmit LPI enable + + + Notes: + Transmit low power IDLE enable. When set to 1, the MAC completes the transmission of the current frame and generates low power IDLE sequences (LPI) to the XGMII/SGMII. When set to 0, the MAC operates in normal mode. This bit is OR'ed with the reg_lowp_ena pin. */ + unsigned int msmLineTxLowPowerIdleEnable : 1; /* 1E.9005.7 R/W Default = 0x0 */ + /* 1 = Transmit LPI enable + */ + unsigned int reserved0 : 8; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineGeneralControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line FIFO Control Register: 1E.900E */ +/* MSM Line FIFO Control Register: 1E.900E */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line FIFO Control Register */ + union + { + struct + { + /*! \brief 1E.900E.7:0 R/W MSM Line Rx FIFO Full Threshold [7:0] + AQ_MsmLineFifoControlRegister_HHD.u0.bits_0.msmLineRxFifoFullThreshold + + Default = 0x08 + + Rx FIFO full threshold + + Notes: + All threshold values are in steps of FIFO words. */ + unsigned int msmLineRxFifoFullThreshold : 8; /* 1E.900E.7:0 R/W Default = 0x08 */ + /* Rx FIFO full threshold */ + unsigned int reserved0 : 8; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line FIFO Control Register */ + union + { + struct + { + /*! \brief 1E.900F.7:0 R/W MSM Line Rx FIFO Empty Threshold [7:0] + AQ_MsmLineFifoControlRegister_HHD.u1.bits_1.msmLineRxFifoEmptyThreshold + + Default = 0x00 + + Rx FIFO empty threshold + + Notes: + All threshold values are in steps of FIFO words. */ + unsigned int msmLineRxFifoEmptyThreshold : 8; /* 1E.900F.7:0 R/W Default = 0x00 */ + /* Rx FIFO empty threshold */ + unsigned int reserved0 : 8; + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of MSM Line FIFO Control Register */ + union + { + struct + { + /*! \brief 1E.9010.5:0 R/W MSM Line Tx FIFO Full Threshold [5:0] + AQ_MsmLineFifoControlRegister_HHD.u2.bits_2.msmLineTxFifoFullThreshold + + Default = 0x08 + + Tx FIFO full threshold + + Notes: + All threshold values are in steps of FIFO words. */ + unsigned int msmLineTxFifoFullThreshold : 6; /* 1E.9010.5:0 R/W Default = 0x08 */ + /* Tx FIFO full threshold */ + unsigned int reserved0 : 10; + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of MSM Line FIFO Control Register */ + union + { + struct + { + /*! \brief 1E.9011.5:0 R/W MSM Line Tx FIFO Empty Threshold [5:0] + AQ_MsmLineFifoControlRegister_HHD.u3.bits_3.msmLineTxFifoEmptyThreshold + + Default = 0x00 + + Tx FIFO empty threshold + + Notes: + All threshold values are in steps of FIFO words. */ + unsigned int msmLineTxFifoEmptyThreshold : 6; /* 1E.9011.5:0 R/W Default = 0x00 */ + /* Tx FIFO empty threshold */ + unsigned int reserved0 : 10; + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of MSM Line FIFO Control Register */ + union + { + struct + { + /*! \brief 1E.9012.7:0 ROS MSM Line Rx FIFO Almost Full Threshold [7:0] + AQ_MsmLineFifoControlRegister_HHD.u4.bits_4.msmLineRxFifoAlmostFullThreshold + + Default = 0x00 + + Rx FIFO almost full threshold + + Notes: + Unused. */ + unsigned int msmLineRxFifoAlmostFullThreshold : 8; /* 1E.9012.7:0 ROS Default = 0x00 */ + /* Rx FIFO almost full threshold */ + unsigned int reserved0 : 8; + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of MSM Line FIFO Control Register */ + union + { + struct + { + /*! \brief 1E.9013.7:0 ROS MSM Line Rx FIFO Almost Empty Threshold [7:0] + AQ_MsmLineFifoControlRegister_HHD.u5.bits_5.msmLineRxFifoAlmostEmptyThreshold + + Default = 0x00 + + Rx FIFO almost empty threshold + + Notes: + Unused. */ + unsigned int msmLineRxFifoAlmostEmptyThreshold : 8; /* 1E.9013.7:0 ROS Default = 0x00 */ + /* Rx FIFO almost empty threshold */ + unsigned int reserved0 : 8; + } bits_5; + uint16_t word_5; + } u5; + /*! \brief Union for bit and word level access of word 6 of MSM Line FIFO Control Register */ + union + { + struct + { + /*! \brief 1E.9014.7:0 ROS MSM Line Tx FIFO Almost Full Threshold [7:0] + AQ_MsmLineFifoControlRegister_HHD.u6.bits_6.msmLineTxFifoAlmostFullThreshold + + Default = 0x00 + + Tx FIFO almost full threshold + + Notes: + Unused. */ + unsigned int msmLineTxFifoAlmostFullThreshold : 8; /* 1E.9014.7:0 ROS Default = 0x00 */ + /* Tx FIFO almost full threshold */ + unsigned int reserved0 : 8; + } bits_6; + uint16_t word_6; + } u6; + /*! \brief Union for bit and word level access of word 7 of MSM Line FIFO Control Register */ + union + { + struct + { + /*! \brief 1E.9015.7:0 ROS MSM Line Tx FIFO Almost Empty Threshold [7:0] + AQ_MsmLineFifoControlRegister_HHD.u7.bits_7.msmLineTxFifoAlmostEmptyThreshold + + Default = 0x00 + + Tx FIFO almost empty threshold + + Notes: + Unused. */ + unsigned int msmLineTxFifoAlmostEmptyThreshold : 8; /* 1E.9015.7:0 ROS Default = 0x00 */ + /* Tx FIFO almost empty threshold */ + unsigned int reserved0 : 8; + } bits_7; + uint16_t word_7; + } u7; +} AQ_MsmLineFifoControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line General Status Register: 1E.9020 */ +/* MSM Line General Status Register: 1E.9020 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line General Status Register */ + union + { + struct + { + /*! \brief 1E.9020.0 BLH MSM Line Rx Local Fault + AQ_MsmLineGeneralStatusRegister_HHD.u0.bits_0.msmLineRxLocalFault + + + + Rx local fault detected + + Notes: + Latch high local fault status. Set to 1, whent he MAC detects Rx local fault sequences on the Rx interface. Reset to 0 after read and after reset. */ + unsigned int msmLineRxLocalFault : 1; /* 1E.9020.0 BLH */ + /* Rx local fault detected */ + /*! \brief 1E.9020.1 BLH MSM Line Rx Remote Fault + AQ_MsmLineGeneralStatusRegister_HHD.u0.bits_0.msmLineRxRemoteFault + + + + Rx remote fault detected + + Notes: + Latch high local fault status. Set to 1, whent he MAC detects Rx local fault sequences on the Rx interface. Reset to 0 after read and after reset. */ + unsigned int msmLineRxRemoteFault : 1; /* 1E.9020.1 BLH */ + /* Rx remote fault detected */ + /*! \brief 1E.9020.2 RO MSM Line PHY Loss of Signal + AQ_MsmLineGeneralStatusRegister_HHD.u0.bits_0.msmLinePhyLossOfSignal + + + + PHY loss of signal + + Notes: + PHY indicates loss of signal. This is the value of pin phy_los which is tied to 0. */ + unsigned int msmLinePhyLossOfSignal : 1; /* 1E.9020.2 RO */ + /* PHY loss of signal */ + /*! \brief 1E.9020.3 R/W MSM Line Timestamp Available + AQ_MsmLineGeneralStatusRegister_HHD.u0.bits_0.msmLineTimestampAvailable + + Default = 0x0 + + Timestamp available + + Notes: + Transmit timestamp available. Indicates that the timestamp of the last transmitted event frame (which had ff_tx_ts_frm=1) is available in the register See MAC Time Stamp Status 0 [F:0] and See MAC Time Stamp Status 1 [F:0] . To clear this bit, the bit must be written with a 1. + */ + unsigned int msmLineTimestampAvailable : 1; /* 1E.9020.3 R/W Default = 0x0 */ + /* Timestamp available */ + /*! \brief 1E.9020.4 RO MSM Line Rx Low Power IDLE + AQ_MsmLineGeneralStatusRegister_HHD.u0.bits_0.msmLineRxLowPowerIdle + + + + Rx LPI detected + + Notes: + Receive low power IDLE (LPI). Set to 1 when LPI is currently detected on the MAC Rx interface. Set to 0, when the MAC currently operates in normal mode. */ + unsigned int msmLineRxLowPowerIdle : 1; /* 1E.9020.4 RO */ + /* Rx LPI detected */ + /*! \brief 1E.9020.5 RO MSM Line Tx FIFO Empty + AQ_MsmLineGeneralStatusRegister_HHD.u0.bits_0.msmLineTxFifoEmpty + + + + Tx FIFO empty + + Notes: + When set to 1, indicates the Tx FIFO is empty. When set to 0, Tx FIFO is non-empty. */ + unsigned int msmLineTxFifoEmpty : 1; /* 1E.9020.5 RO */ + /* Tx FIFO empty */ + unsigned int reserved0 : 10; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line General Status Register */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineGeneralStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Tx IPG Control Register: 1E.9022 */ +/* MSM Line Tx IPG Control Register: 1E.9022 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Tx IPG Control Register */ + union + { + struct + { + /*! \brief 1E.9022.5:0 R/W MSM Line Tx IPG Length [5:0] + AQ_MsmLineTxIpgControlRegister_HHD.u0.bits_0.msmLineTxIpgLength + + Default = 0x0C + + Tx IPG length + + Notes: + Tx inter-packet gap (IPG) value. Depending on LAN or WAN mode of operation. + LAN Mode : Number of octets in steps of 4. Valid values are 8, 12, 16,..., 100. DIC is supported for any setting > 8. A default of 12 must be set to conform to IEEE802.3ae. + WAN Mode : Stretch factor. Valid values are 4 ... 15. The stretch factor is calculated as (value+1)*8. A default of 12 must be set to conform to IEEE802.3ae (i.e. 13*8=104). A larger value shrinks the IPG (increasing bandwidth). + The reset value of 12 leads to IEEE802.3ae conformant behavior in both modes. + Note : WAN mode is only available in 10G mode of operation. */ + unsigned int msmLineTxIpgLength : 6; /* 1E.9022.5:0 R/W Default = 0x0C */ + /* Tx IPG length */ + unsigned int reserved0 : 10; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Tx IPG Control Register */ + union + { + struct + { + /*! \brief 1E.9023.F:0 MSM Line Tx IPG Reserved + AQ_MsmLineTxIpgControlRegister_HHD.u1.bits_1.msmLineTxIpgReserved + + + + Value always 0, writes ignored + */ + unsigned int msmLineTxIpgReserved : 16; /* 1E.9023.F:0 */ + /* Value always 0, writes ignored */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineTxIpgControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Tx Good Frames Counter Register: 1E.9040 */ +/* MSM Line Tx Good Frames Counter Register: 1E.9040 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Tx Good Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9040.F:0 ROS MSM Line Tx Good Frames Counter 0 [F:0] + AQ_MsmLineTxGoodFramesCounterRegister_HHD.u0.bits_0.msmLineTxGoodFramesCounter_0 + + Default = 0x0000 + + Tx good frame counter bits 15:0 + + Notes: + Count of frames transmitted without error (Including pause frames). */ + unsigned int msmLineTxGoodFramesCounter_0 : 16; /* 1E.9040.F:0 ROS Default = 0x0000 */ + /* Tx good frame counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Tx Good Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9041.F:0 ROS MSM Line Tx Good Frames Counter 1 [F:0] + AQ_MsmLineTxGoodFramesCounterRegister_HHD.u1.bits_1.msmLineTxGoodFramesCounter_1 + + Default = 0x0000 + + Tx good frame counter bits 31:16 + + + Notes: + Count of frames transmitted without error (Including pause frames). */ + unsigned int msmLineTxGoodFramesCounter_1 : 16; /* 1E.9041.F:0 ROS Default = 0x0000 */ + /* Tx good frame counter bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineTxGoodFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx Good Frames Counter Register: 1E.9044 */ +/* MSM Line Rx Good Frames Counter Register: 1E.9044 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx Good Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9044.F:0 ROS MSM Line Rx Good Frames Counter 0 [F:0] + AQ_MsmLineRxGoodFramesCounterRegister_HHD.u0.bits_0.msmLineRxGoodFramesCounter_0 + + Default = 0x0000 + + Rx good frame counter bits 15:0 + + Notes: + Count of frames received without error (Including pause frames). */ + unsigned int msmLineRxGoodFramesCounter_0 : 16; /* 1E.9044.F:0 ROS Default = 0x0000 */ + /* Rx good frame counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx Good Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9045.F:0 ROS MSM Line Rx Good Frames Counter 1 [F:0] + AQ_MsmLineRxGoodFramesCounterRegister_HHD.u1.bits_1.msmLineRxGoodFramesCounter_1 + + Default = 0x0000 + + Rx good frame counter bits 31:16 + + Notes: + Count of frames received without error (Including pause frames). */ + unsigned int msmLineRxGoodFramesCounter_1 : 16; /* 1E.9045.F:0 ROS Default = 0x0000 */ + /* Rx good frame counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxGoodFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx FCS Errors Counter Register: 1E.9048 */ +/* MSM Line Rx FCS Errors Counter Register: 1E.9048 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx FCS Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.9048.F:0 ROS MSM Line FCS Error Counter 0 [F:0] + AQ_MsmLineRxFcsErrorsCounterRegister_HHD.u0.bits_0.msmLineFcsErrorCounter_0 + + Default = 0x0000 + + Frame check sequence error counter bits 15:0 + + Notes: + Count of frames for which a CRC-32 Error is detected but the frame is otherwise of correct length. */ + unsigned int msmLineFcsErrorCounter_0 : 16; /* 1E.9048.F:0 ROS Default = 0x0000 */ + /* Frame check sequence error counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx FCS Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.9049.F:0 ROS MSM Line FCS Error Counter 1 [F:0] + AQ_MsmLineRxFcsErrorsCounterRegister_HHD.u1.bits_1.msmLineFcsErrorCounter_1 + + Default = 0x0000 + + Frame check sequence error counter bits 31:16 + + Notes: + Count of frames for which a CRC-32 Error is detected but the frame is otherwise of correct length. */ + unsigned int msmLineFcsErrorCounter_1 : 16; /* 1E.9049.F:0 ROS Default = 0x0000 */ + /* Frame check sequence error counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxFcsErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx Alignment Errors Counter Register: 1E.904C */ +/* MSM Line Rx Alignment Errors Counter Register: 1E.904C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx Alignment Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.904C.F:0 ROS MSM Line Alignment Error Counter 0 [F:0] + AQ_MsmLineRxAlignmentErrorsCounterRegister_HHD.u0.bits_0.msmLineAlignmentErrorCounter_0 + + Default = 0x0000 + + Alignment error counter bits 15:0 + + Notes: + Count of frames received with an alignment error. */ + unsigned int msmLineAlignmentErrorCounter_0 : 16; /* 1E.904C.F:0 ROS Default = 0x0000 */ + /* Alignment error counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx Alignment Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.904D.F:0 ROS MSM Line Alignment Error Counter 1 [F:0] + AQ_MsmLineRxAlignmentErrorsCounterRegister_HHD.u1.bits_1.msmLineAlignmentErrorCounter_1 + + Default = 0x0000 + + Alignment error counter bits 31:16 + + Notes: + Count of frames received with an alignment error. */ + unsigned int msmLineAlignmentErrorCounter_1 : 16; /* 1E.904D.F:0 ROS Default = 0x0000 */ + /* Alignment error counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxAlignmentErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Tx Pause Frames Counter Register: 1E.9050 */ +/* MSM Line Tx Pause Frames Counter Register: 1E.9050 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Tx Pause Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9050.F:0 ROS MSM Line Tx Pause Frames Counter 0 [F:0] + AQ_MsmLineTxPauseFramesCounterRegister_HHD.u0.bits_0.msmLineTxPauseFramesCounter_0 + + Default = 0x0000 + + Tx pause frame counter bits 15:0 + + Notes: + Valid pause frames transmitted. */ + unsigned int msmLineTxPauseFramesCounter_0 : 16; /* 1E.9050.F:0 ROS Default = 0x0000 */ + /* Tx pause frame counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Tx Pause Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9051.F:0 ROS MSM Line Tx Pause Frames Counter 1 [F:0] + AQ_MsmLineTxPauseFramesCounterRegister_HHD.u1.bits_1.msmLineTxPauseFramesCounter_1 + + Default = 0x0000 + + Tx pause frame counter bits 31:16 + + + Notes: + Valid pause frames transmitted. */ + unsigned int msmLineTxPauseFramesCounter_1 : 16; /* 1E.9051.F:0 ROS Default = 0x0000 */ + /* Tx pause frame counter bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineTxPauseFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx Pause Frames Counter Register: 1E.9054 */ +/* MSM Line Rx Pause Frames Counter Register: 1E.9054 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx Pause Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9054.F:0 ROS MSM Line Rx Pause Frames Counter 0 [F:0] + AQ_MsmLineRxPauseFramesCounterRegister_HHD.u0.bits_0.msmLineRxPauseFramesCounter_0 + + Default = 0x0000 + + Rx pause frame counter bits 15:0 + + Notes: + Valid pause frames received. */ + unsigned int msmLineRxPauseFramesCounter_0 : 16; /* 1E.9054.F:0 ROS Default = 0x0000 */ + /* Rx pause frame counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx Pause Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9055.F:0 ROS MSM Line Rx Pause Frames Counter 1 [F:0] + AQ_MsmLineRxPauseFramesCounterRegister_HHD.u1.bits_1.msmLineRxPauseFramesCounter_1 + + Default = 0x0000 + + Rx pause frame counter bits 31:16 + + Notes: + Valid pause frames received. */ + unsigned int msmLineRxPauseFramesCounter_1 : 16; /* 1E.9055.F:0 ROS Default = 0x0000 */ + /* Rx pause frame counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxPauseFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx Too Long Errors Counter Register: 1E.9058 */ +/* MSM Line Rx Too Long Errors Counter Register: 1E.9058 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx Too Long Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.9058.F:0 ROS MSM Line Rx Too Long Errors Counter 0 [F:0] + AQ_MsmLineRxTooLongErrorsCounterRegister_HHD.u0.bits_0.msmLineRxTooLongErrorsCounter_0 + + Default = 0x0000 + + Too-long errors counter bits 15:0 + + Notes: + Frame received exceeded the maximum length programmed with register FRM_LGTH. */ + unsigned int msmLineRxTooLongErrorsCounter_0 : 16; /* 1E.9058.F:0 ROS Default = 0x0000 */ + /* Too-long errors counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx Too Long Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.9059.F:0 ROS MSM Line Rx Too Long Errors Counter 1 [F:0] + AQ_MsmLineRxTooLongErrorsCounterRegister_HHD.u1.bits_1.msmLineRxTooLongErrorsCounter_1 + + Default = 0x0000 + + Too-long errors counter bits 31:16 + + Notes: + Frame received exceeded the maximum length programmed with register FRM_LGTH. */ + unsigned int msmLineRxTooLongErrorsCounter_1 : 16; /* 1E.9059.F:0 ROS Default = 0x0000 */ + /* Too-long errors counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxTooLongErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx In Range Length Errors Counter Register: 1E.905C */ +/* MSM Line Rx In Range Length Errors Counter Register: 1E.905C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx In Range Length Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.905C.F:0 ROS MSM Line Rx In Range Length Errors Counter 0 [F:0] + AQ_MsmLineRxInRangeLengthErrorsCounterRegister_HHD.u0.bits_0.msmLineRxInRangeLengthErrorsCounter_0 + + Default = 0x0000 + + In-range-length errors counter bits 15:0 + + Notes: + A count of frames with a length/type field value between 46 (VLAN: 42) and less than 0x0600, that does not match the number of payload data octets received. Should count also if length/type field is less than 46 (VLAN: 42) and the frame is longer than 64 bytes. */ + unsigned int msmLineRxInRangeLengthErrorsCounter_0 : 16; /* 1E.905C.F:0 ROS Default = 0x0000 */ + /* In-range-length errors counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx In Range Length Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.905D.F:0 ROS MSM Line Rx In Range Length Errors Counter 1 [F:0] + AQ_MsmLineRxInRangeLengthErrorsCounterRegister_HHD.u1.bits_1.msmLineRxInRangeLengthErrorsCounter_1 + + Default = 0x0000 + + In-range-length errors counter bits 31:16 + + Notes: + A count of frames with a length/type field value between 46 (VLAN: 42) and less than 0x0600, that does not match the number of payload data octets received. Should count also if length/type field is less than 46 (VLAN: 42) and the frame is longer than 64 bytes. */ + unsigned int msmLineRxInRangeLengthErrorsCounter_1 : 16; /* 1E.905D.F:0 ROS Default = 0x0000 */ + /* In-range-length errors counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxInRangeLengthErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Tx VLAN Frames Counter Register: 1E.9060 */ +/* MSM Line Tx VLAN Frames Counter Register: 1E.9060 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Tx VLAN Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9060.F:0 ROS MSM Line Tx VLAN Frames Counter 0 [F:0] + AQ_MsmLineTxVlanFramesCounterRegister_HHD.u0.bits_0.msmLineTxVlanFramesCounter_0 + + Default = 0x0000 + + Tx VLAN frames counter bits 15:0 + + Notes: + Valid VLAN tagged frames transmitted. */ + unsigned int msmLineTxVlanFramesCounter_0 : 16; /* 1E.9060.F:0 ROS Default = 0x0000 */ + /* Tx VLAN frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Tx VLAN Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9061.F:0 ROS MSM Line Tx VLAN Frames Counter 1 [F:0] + AQ_MsmLineTxVlanFramesCounterRegister_HHD.u1.bits_1.msmLineTxVlanFramesCounter_1 + + Default = 0x0000 + + Tx VLAN frames counter bits 31:16 + + Notes: + Valid VLAN tagged frames transmitted. */ + unsigned int msmLineTxVlanFramesCounter_1 : 16; /* 1E.9061.F:0 ROS Default = 0x0000 */ + /* Tx VLAN frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineTxVlanFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx VLAN Frames Counter Register: 1E.9064 */ +/* MSM Line Rx VLAN Frames Counter Register: 1E.9064 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx VLAN Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9064.F:0 ROS MSM Line Rx VLAN Frames Counter 0 [F:0] + AQ_MsmLineRxVlanFramesCounterRegister_HHD.u0.bits_0.msmLineRxVlanFramesCounter_0 + + Default = 0x0000 + + Rx VLAN frames counter bits 15:0 + + Notes: + Valid VLAN tagged frames received. */ + unsigned int msmLineRxVlanFramesCounter_0 : 16; /* 1E.9064.F:0 ROS Default = 0x0000 */ + /* Rx VLAN frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx VLAN Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9065.F:0 ROS MSM Line Rx VLAN Frames Counter 1 [F:0] + AQ_MsmLineRxVlanFramesCounterRegister_HHD.u1.bits_1.msmLineRxVlanFramesCounter_1 + + Default = 0x0000 + + Rx VLAN frames counter bits 31:16 + + Notes: + Valid VLAN tagged frames received. */ + unsigned int msmLineRxVlanFramesCounter_1 : 16; /* 1E.9065.F:0 ROS Default = 0x0000 */ + /* Rx VLAN frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxVlanFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Tx Octets Counter Register: 1E.9068 */ +/* MSM Line Tx Octets Counter Register: 1E.9068 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Tx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.9068.F:0 ROS MSM Line Tx Octets Counter 0 [F:0] + AQ_MsmLineTxOctetsCounterRegister_HHD.u0.bits_0.msmLineTxOctetsCounter_0 + + Default = 0x0000 + + Tx octets counter bits 15:0 + + Notes: + All octets transmitted except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames transmitted. */ + unsigned int msmLineTxOctetsCounter_0 : 16; /* 1E.9068.F:0 ROS Default = 0x0000 */ + /* Tx octets counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Tx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.9069.F:0 ROS MSM Line Tx Octets Counter 1 [F:0] + AQ_MsmLineTxOctetsCounterRegister_HHD.u1.bits_1.msmLineTxOctetsCounter_1 + + Default = 0x0000 + + Tx octets counter bits 31:16 + + Notes: + All octets transmitted except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames transmitted. */ + unsigned int msmLineTxOctetsCounter_1 : 16; /* 1E.9069.F:0 ROS Default = 0x0000 */ + /* Tx octets counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of MSM Line Tx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.906A.F:0 ROS MSM Line Tx Octets Counter 2 [F:0] + AQ_MsmLineTxOctetsCounterRegister_HHD.u2.bits_2.msmLineTxOctetsCounter_2 + + Default = 0x0000 + + Tx octets counter bits 47:32 + + Notes: + All octets transmitted except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames transmitted. */ + unsigned int msmLineTxOctetsCounter_2 : 16; /* 1E.906A.F:0 ROS Default = 0x0000 */ + /* Tx octets counter bits 47:32 */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of MSM Line Tx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.906B.F:0 ROS MSM Line Tx Octets Counter 3 [F:0] + AQ_MsmLineTxOctetsCounterRegister_HHD.u3.bits_3.msmLineTxOctetsCounter_3 + + Default = 0x0000 + + Tx octets counter bits 63:48 + + Notes: + All octets transmitted except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames transmitted. */ + unsigned int msmLineTxOctetsCounter_3 : 16; /* 1E.906B.F:0 ROS Default = 0x0000 */ + /* Tx octets counter bits 63:48 */ + } bits_3; + uint16_t word_3; + } u3; +} AQ_MsmLineTxOctetsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx Octets Counter Register: 1E.906C */ +/* MSM Line Rx Octets Counter Register: 1E.906C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.906C.F:0 ROS MSM Line Rx Octets Counter 0 [F:0] + AQ_MsmLineRxOctetsCounterRegister_HHD.u0.bits_0.msmLineRxOctetsCounter_0 + + Default = 0x0000 + + Rx octets counter bits 15:0 + + Notes: + All octets received except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames received. */ + unsigned int msmLineRxOctetsCounter_0 : 16; /* 1E.906C.F:0 ROS Default = 0x0000 */ + /* Rx octets counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.906D.F:0 ROS MSM Line Rx Octets Counter 1 [F:0] + AQ_MsmLineRxOctetsCounterRegister_HHD.u1.bits_1.msmLineRxOctetsCounter_1 + + Default = 0x0000 + + Rx octets counter bits 31:16 + + Notes: + All octets received except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames received. */ + unsigned int msmLineRxOctetsCounter_1 : 16; /* 1E.906D.F:0 ROS Default = 0x0000 */ + /* Rx octets counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxOctetsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx Unicast Frames Counter Register: 1E.9070 */ +/* MSM Line Rx Unicast Frames Counter Register: 1E.9070 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx Unicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9070.F:0 ROS MSM Line Rx Unicast Frames Counter 0 [F:0] + AQ_MsmLineRxUnicastFramesCounterRegister_HHD.u0.bits_0.msmLineRxUnicastFramesCounter_0 + + Default = 0x0000 + + Rx unicast frames counter bits 15:0 + + Notes: + Incremented with each valid frame received on the receive FIFO interface and bit 0 of the destination address was '0'. */ + unsigned int msmLineRxUnicastFramesCounter_0 : 16; /* 1E.9070.F:0 ROS Default = 0x0000 */ + /* Rx unicast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx Unicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9071.F:0 ROS MSM Line Rx Unicast Frames Counter 1 [F:0] + AQ_MsmLineRxUnicastFramesCounterRegister_HHD.u1.bits_1.msmLineRxUnicastFramesCounter_1 + + Default = 0x0000 + + Rx unicast frames counter bits 31:16 + + Notes: + Incremented with each valid frame received on the receive FIFO interface and bit 0 of the destination address was '0'. */ + unsigned int msmLineRxUnicastFramesCounter_1 : 16; /* 1E.9071.F:0 ROS Default = 0x0000 */ + /* Rx unicast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxUnicastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx Multicast Frames Counter Register: 1E.9074 */ +/* MSM Line Rx Multicast Frames Counter Register: 1E.9074 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx Multicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9074.F:0 ROS MSM Line Rx Multicast Frames Counter 0 [F:0] + AQ_MsmLineRxMulticastFramesCounterRegister_HHD.u0.bits_0.msmLineRxMulticastFramesCounter_0 + + Default = 0x0000 + + Rx multicast frames counter bits 15:0 + + Notes: + Incremented with each valid frame received on the receive FIFO interface and bit 0 of the destination address was '1' but not the broadcast address (all bits set '1' ). Pause frames are not counted. */ + unsigned int msmLineRxMulticastFramesCounter_0 : 16; /* 1E.9074.F:0 ROS Default = 0x0000 */ + /* Rx multicast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx Multicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9075.F:0 ROS MSM Line Rx Multicast Frames Counter 1 [F:0] + AQ_MsmLineRxMulticastFramesCounterRegister_HHD.u1.bits_1.msmLineRxMulticastFramesCounter_1 + + Default = 0x0000 + + Rx multicast frames counter bits 31:16 + + Notes: + Incremented with each valid frame received on the receive FIFO interface and bit 0 of the destination address was '1' but not the broadcast address (all bits set '1' ). Pause frames are not counted. */ + unsigned int msmLineRxMulticastFramesCounter_1 : 16; /* 1E.9075.F:0 ROS Default = 0x0000 */ + /* Rx multicast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxMulticastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx Broadcast Frames Counter Register: 1E.9078 */ +/* MSM Line Rx Broadcast Frames Counter Register: 1E.9078 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx Broadcast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9078.F:0 ROS MSM Line Rx Broadcast Frames Counter 0 [F:0] + AQ_MsmLineRxBroadcastFramesCounterRegister_HHD.u0.bits_0.msmLineRxBroadcastFramesCounter_0 + + Default = 0x0000 + + Rx broadcast frames counter bits 15:0 + + Notes: + Incremented with each valid frame received on the receive FIFO interface (FIFO) and all bits of the destination address were set '1'. */ + unsigned int msmLineRxBroadcastFramesCounter_0 : 16; /* 1E.9078.F:0 ROS Default = 0x0000 */ + /* Rx broadcast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx Broadcast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9079.F:0 ROS MSM Line Rx Broadcast Frames Counter 1 [F:0] + AQ_MsmLineRxBroadcastFramesCounterRegister_HHD.u1.bits_1.msmLineRxBroadcastFramesCounter_1 + + Default = 0x0000 + + Rx broadcast frames counter bits 31:16 + + Notes: + Incremented with each valid frame received on the receive FIFO interface (FIFO) and all bits of the destination address were set '1'. */ + unsigned int msmLineRxBroadcastFramesCounter_1 : 16; /* 1E.9079.F:0 ROS Default = 0x0000 */ + /* Rx broadcast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxBroadcastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Tx Errors Counter Register: 1E.907C */ +/* MSM Line Tx Errors Counter Register: 1E.907C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Tx Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.907C.F:0 ROS MSM Line Tx Errors Counter 0 [F:0] + AQ_MsmLineTxErrorsCounterRegister_HHD.u0.bits_0.msmLineTxErrorsCounter_0 + + Default = 0x0000 + + Rx errors counter bits 15:0 + + Notes: + Number of frames transmitted with error: + - FIFO Overflow Errors + - FIFO Underflow Errors */ + unsigned int msmLineTxErrorsCounter_0 : 16; /* 1E.907C.F:0 ROS Default = 0x0000 */ + /* Rx errors counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Tx Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.907D.F:0 ROS MSM Line Tx Errors Counter 1 [F:0] + AQ_MsmLineTxErrorsCounterRegister_HHD.u1.bits_1.msmLineTxErrorsCounter_1 + + Default = 0x0000 + + Tx errors counter bits 31:16 + + Notes: + Number of frames transmitted with error: + - FIFO Overflow Errors + - FIFO Underflow Errors */ + unsigned int msmLineTxErrorsCounter_1 : 16; /* 1E.907D.F:0 ROS Default = 0x0000 */ + /* Tx errors counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineTxErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Tx Unicast Frames Counter Register: 1E.9084 */ +/* MSM Line Tx Unicast Frames Counter Register: 1E.9084 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Tx Unicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9084.F:0 ROS MSM Line Tx Unicast Frames Counter 0 [F:0] + AQ_MsmLineTxUnicastFramesCounterRegister_HHD.u0.bits_0.msmLineTxUnicastFramesCounter_0 + + Default = 0x0000 + + Tx unicast frames counter bits 15:0 + + Notes: + Incremented with each frame written to the FIFO interface and bit 0 of the destination address set to '0'. */ + unsigned int msmLineTxUnicastFramesCounter_0 : 16; /* 1E.9084.F:0 ROS Default = 0x0000 */ + /* Tx unicast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Tx Unicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9085.F:0 ROS MSM Line Tx Unicast Frames Counter 1 [F:0] + AQ_MsmLineTxUnicastFramesCounterRegister_HHD.u1.bits_1.msmLineTxUnicastFramesCounter_1 + + Default = 0x0000 + + Tx unicast frames counter bits 31:16 + + Notes: + Incremented with each frame written to the FIFO interface and bit 0 of the destination address set to '0'. */ + unsigned int msmLineTxUnicastFramesCounter_1 : 16; /* 1E.9085.F:0 ROS Default = 0x0000 */ + /* Tx unicast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineTxUnicastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Tx Multicast Frames Counter Register: 1E.9088 */ +/* MSM Line Tx Multicast Frames Counter Register: 1E.9088 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Tx Multicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9088.F:0 ROS MSM Line Tx Multicast Frames Counter 0 [F:0] + AQ_MsmLineTxMulticastFramesCounterRegister_HHD.u0.bits_0.msmLineTxMulticastFramesCounter_0 + + Default = 0x0000 + + Tx multicast frames counter bits 15:0 + + Notes: + Incremented with each frame written to the FIFO interface and bit 0 of the destination address set to '1' but not the broadcast address (all bits '1'). */ + unsigned int msmLineTxMulticastFramesCounter_0 : 16; /* 1E.9088.F:0 ROS Default = 0x0000 */ + /* Tx multicast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Tx Multicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9089.F:0 ROS MSM Line Tx Multicast Frames Counter 1 [F:0] + AQ_MsmLineTxMulticastFramesCounterRegister_HHD.u1.bits_1.msmLineTxMulticastFramesCounter_1 + + Default = 0x0000 + + Tx multicast frames counter bits 31:16 + + Notes: + Incremented with each frame written to the FIFO interface and bit 0 of the destination address set to '1' but not the broadcast address (all bits '1'). */ + unsigned int msmLineTxMulticastFramesCounter_1 : 16; /* 1E.9089.F:0 ROS Default = 0x0000 */ + /* Tx multicast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineTxMulticastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Tx Broadcast Frames Counter Register: 1E.908C */ +/* MSM Line Tx Broadcast Frames Counter Register: 1E.908C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Tx Broadcast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.908C.F:0 ROS MSM Line Tx Broadcast Frames Counter 0 [F:0] + AQ_MsmLineTxBroadcastFramesCounterRegister_HHD.u0.bits_0.msmLineTxBroadcastFramesCounter_0 + + Default = 0x0000 + + Tx broadcast frames counter bits 15:0 + + Notes: + Incremented with each frame written to the FIFO interface and all bits of the destination address set to '1'. */ + unsigned int msmLineTxBroadcastFramesCounter_0 : 16; /* 1E.908C.F:0 ROS Default = 0x0000 */ + /* Tx broadcast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Tx Broadcast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.908D.F:0 ROS MSM Line Tx Broadcast Frames Counter 1 [F:0] + AQ_MsmLineTxBroadcastFramesCounterRegister_HHD.u1.bits_1.msmLineTxBroadcastFramesCounter_1 + + Default = 0x0000 + + Tx broadcast frames counter bits 31:16 + + Notes: + Incremented with each frame written to the FIFO interface and all bits of the destination address set to '1'. */ + unsigned int msmLineTxBroadcastFramesCounter_1 : 16; /* 1E.908D.F:0 ROS Default = 0x0000 */ + /* Tx broadcast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineTxBroadcastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx Errors Counter Register: 1E.90C8 */ +/* MSM Line Rx Errors Counter Register: 1E.90C8 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.90C8.F:0 ROS MSM Line Rx Errors Counter 0 [F:0] + AQ_MsmLineRxErrorsCounterRegister_HHD.u0.bits_0.msmLineRxErrorsCounter_0 + + Default = 0x0000 + + Rx errors counter bits 15:0 + + Notes: + Number of frames received with error: + - FIFO Overflow Errors + - CRC Errors + - Payload Length Errors + - Jabber and Oversized Errors + - Alignment Errors + - The dedicated Error Code (0xfe, not a code error) was received */ + unsigned int msmLineRxErrorsCounter_0 : 16; /* 1E.90C8.F:0 ROS Default = 0x0000 */ + /* Rx errors counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.90C9.F:0 ROS MSM Line Rx Errors Counter 1 [F:0] + AQ_MsmLineRxErrorsCounterRegister_HHD.u1.bits_1.msmLineRxErrorsCounter_1 + + Default = 0x0000 + + Rx errors counter bits 31:16 + + Notes: + Number of frames received with error: + - FIFO Overflow Errors + - CRC Errors + - Payload Length Errors + - Jabber and Oversized Errors + - Alignment Errors + - The dedicated Error Code (0xfe, not a code error) was received */ + unsigned int msmLineRxErrorsCounter_1 : 16; /* 1E.90C9.F:0 ROS Default = 0x0000 */ + /* Rx errors counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Control: 1E.C000 */ +/* Global Control: 1E.C000 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Control */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Control */ + union + { + struct + { + /*! \brief 1E.C001.0 R/W uP Run Stall + AQ_GlobalControl_HHD.u1.bits_1.upRunStall + + Default = 0x0 + + 1 = uP Run Stall + 0 = uP normal mode + + + Notes: + Deactivates the uP. */ + unsigned int upRunStall : 1; /* 1E.C001.0 R/W Default = 0x0 */ + /* 1 = uP Run Stall + 0 = uP normal mode + */ + unsigned int reserved1 : 5; + /*! \brief 1E.C001.6 R/W uP Run Stall Override + AQ_GlobalControl_HHD.u1.bits_1.upRunStallOverride + + Default = 0x0 + + 0 = uP Run Stall from "MDIO Boot Load" pin. + 1 = uP Run Stall from See MCP Run Stall bit + + + + Notes: + This bit selects the uP Run Stall from either the "MDIO Boot Load" pin or the See MCP Run Stall bit. Pin no longer brought out as deprecated. */ + unsigned int upRunStallOverride : 1; /* 1E.C001.6 R/W Default = 0x0 */ + /* 0 = uP Run Stall from "MDIO Boot Load" pin. + 1 = uP Run Stall from See MCP Run Stall bit + + */ + unsigned int reserved0 : 8; + /*! \brief 1E.C001.F R/W uP Reset + AQ_GlobalControl_HHD.u1.bits_1.upReset + + Default = 0x0 + + 1 = Reset + + + Notes: + Resets the uP and the PIF master and slave bus. Will be active for a minimum of 100 microseconds. */ + unsigned int upReset : 1; /* 1E.C001.F R/W Default = 0x0 */ + /* 1 = Reset + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalControl_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Reset Control: 1E.C006 */ +/* Global Reset Control: 1E.C006 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Reset Control */ + union + { + struct + { + unsigned int reserved1 : 14; + /*! \brief 1E.C006.E R/WPD Global MMD Reset Disable + AQ_GlobalResetControl_HHD.u0.bits_0.globalMMD_ResetDisable + + Provisionable Default = 0x0 + + 1 = Disable the S/W reset to the Global MMD registers + 0 = Enable the S/W reset to the Global MMD registers + + + Notes: + Setting this bit prevents a Global S/W reset or Global S/W reset from resetting the Global MMD registers */ + unsigned int globalMMD_ResetDisable : 1; /* 1E.C006.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Disable the S/W reset to the Global MMD registers + 0 = Enable the S/W reset to the Global MMD registers + */ + unsigned int reserved0 : 1; + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalResetControl_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Diagnostic Provisioning: 1E.C400 */ +/* Global Diagnostic Provisioning: 1E.C400 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Diagnostic Provisioning */ + union + { + struct + { + unsigned int reserved0 : 15; + /*! \brief 1E.C400.F R/WPD Enable Diagnostics + AQ_GlobalDiagnosticProvisioning_HHD.u0.bits_0.enableDiagnostics + + Provisionable Default = 0x1 + + 1 = Chip performs diagnostics on power-up + */ + unsigned int enableDiagnostics : 1; /* 1E.C400.F R/WPD Provisionable Default = 0x1 */ + /* 1 = Chip performs diagnostics on power-up */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalDiagnosticProvisioning_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Thermal Provisioning: 1E.C420 */ +/* Global Thermal Provisioning: 1E.C420 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Thermal Provisioning */ + union + { + struct + { + /*! \brief 1E.C420.F:0 R/WPD Reserved 0 [F:0] + AQ_GlobalThermalProvisioning_HHD.u0.bits_0.reserved_0 + + Provisionable Default = 0x0000 + + Internal reserved - do not modify + + */ + unsigned int reserved_0 : 16; /* 1E.C420.F:0 R/WPD Provisionable Default = 0x0000 */ + /* Internal reserved - do not modify + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Thermal Provisioning */ + union + { + struct + { + /*! \brief 1E.C421.F:0 R/WPD High Temp Failure Threshold [F:0] + AQ_GlobalThermalProvisioning_HHD.u1.bits_1.highTempFailureThreshold + + Provisionable Default = 0x4600 + + [F:0] of high temperature failure threshold + + Notes: + 2's complement value with the LSB representing 1/256 of a degree Celsius. This corresponds to -40 degreesC = 0xD800. Default is 70 degreesC. + + In XENPAK mode, F/W will use the XENPAK register 1.A000 - 1.A001: instead of this register. + + NOTE! All Thresholds are orthogonal and can be set to any value regardless the value of the other thresholds. i.e. High-Temperature-Warning (1E.C423) could be higher than High-Temperature-Failure (1E.C421). */ + unsigned int highTempFailureThreshold : 16; /* 1E.C421.F:0 R/WPD Provisionable Default = 0x4600 */ + /* [F:0] of high temperature failure threshold */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Thermal Provisioning */ + union + { + struct + { + /*! \brief 1E.C422.F:0 R/WPD Low Temp Failure Threshold [F:0] + AQ_GlobalThermalProvisioning_HHD.u2.bits_2.lowTempFailureThreshold + + Provisionable Default = 0x0000 + + [F:0] of low temperature failure threshold + + Notes: + 2's complement value with the LSB representing 1/256 of a degree Celsius. This corresponds to -40 degreesC = 0xD800. Default is 0 degreesC. + + In XENPAK mode, F/W will use the XENPAK register 1.A002 - 1.A003: instead of this register. + + NOTE! All Thresholds are orthogonal and can be set to any value regardless the value of the other thresholds. i.e. High-Temperature-Warning (1E.C423) could be higher than High-Temperature-Failure (1E.C421). */ + unsigned int lowTempFailureThreshold : 16; /* 1E.C422.F:0 R/WPD Provisionable Default = 0x0000 */ + /* [F:0] of low temperature failure threshold */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global Thermal Provisioning */ + union + { + struct + { + /*! \brief 1E.C423.F:0 R/WPD High Temp Warning Threshold [F:0] + AQ_GlobalThermalProvisioning_HHD.u3.bits_3.highTempWarningThreshold + + Provisionable Default = 0x3C00 + + [F:0] of high temperature warning threshold + + Notes: + 2's complement value with the LSB representing 1/256 of a degree Celsius. This corresponds to -40 degreesC = 0xD008. Default is 60 degreesC. + + In XENPAK mode, F/W will use the XENPAK register 1.A004 - 1.A005: instead of this register. + + NOTE! All Thresholds are orthogonal and can be set to any value regardless the value of the other thresholds. i.e. High-Temperature-Warning (1E.C423) could be higher than High-Temperature-Failure (1E.C421). */ + unsigned int highTempWarningThreshold : 16; /* 1E.C423.F:0 R/WPD Provisionable Default = 0x3C00 */ + /* [F:0] of high temperature warning threshold */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global Thermal Provisioning */ + union + { + struct + { + /*! \brief 1E.C424.F:0 R/WPD Low Temp Warning Threshold [F:0] + AQ_GlobalThermalProvisioning_HHD.u4.bits_4.lowTempWarningThreshold + + Provisionable Default = 0x0A00 + + [F:0] of low temperature warning threshold + + Notes: + 2's complement value with the LSB representing 1/256 of a degree Celsius. This corresponds to -40 degreesC = 0xD800. Default is 10 degreesC. + + In XENPAK mode, F/W will use the XENPAK register 1.A006 - 1.A007: instead of this register. + + NOTE! All Thresholds are orthogonal and can be set to any value regardless the value of the other thresholds. i.e. High-Temperature-Warning (1E.C423) could be higher than High-Temperature-Failure (1E.C421). */ + unsigned int lowTempWarningThreshold : 16; /* 1E.C424.F:0 R/WPD Provisionable Default = 0x0A00 */ + /* [F:0] of low temperature warning threshold */ + } bits_4; + uint16_t word_4; + } u4; +} AQ_GlobalThermalProvisioning_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global LED Provisioning: 1E.C430 */ +/* Global LED Provisioning: 1E.C430 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global LED Provisioning */ + union + { + struct + { + /*! \brief 1E.C430.1:0 R/WPD LED #0 Activity Stretch [1:0] + AQ_GlobalLedProvisioning_HHD.u0.bits_0.led_0ActivityStretch + + Provisionable Default = 0x3 + + [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + + */ + unsigned int led_0ActivityStretch : 2; /* 1E.C430.1:0 R/WPD Provisionable Default = 0x3 */ + /* [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + */ + /*! \brief 1E.C430.2 R/WPD LED #0 Transmit Activity + AQ_GlobalLedProvisioning_HHD.u0.bits_0.led_0TransmitActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on transmit activity + + */ + unsigned int led_0TransmitActivity : 1; /* 1E.C430.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on transmit activity + */ + /*! \brief 1E.C430.3 R/WPD LED #0 Receive Activity + AQ_GlobalLedProvisioning_HHD.u0.bits_0.led_0ReceiveActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on receive activity + + */ + unsigned int led_0ReceiveActivity : 1; /* 1E.C430.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on receive activity + */ + /*! \brief 1E.C430.4 R/WPD LED #0 Connecting + AQ_GlobalLedProvisioning_HHD.u0.bits_0.led_0Connecting + + Provisionable Default = 0x0 + + 1 = LED is on when attempting to connect. + + */ + unsigned int led_0Connecting : 1; /* 1E.C430.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when attempting to connect. + */ + /*! \brief 1E.C430.5 R/WPD LED #0 100 Mb/s Link Established + AQ_GlobalLedProvisioning_HHD.u0.bits_0.led_0_100Mb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 100 Mb/s. + + */ + unsigned int led_0_100Mb_sLinkEstablished : 1; /* 1E.C430.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 100 Mb/s. + */ + /*! \brief 1E.C430.6 R/WPD LED #0 1 Gb/s Link Established + AQ_GlobalLedProvisioning_HHD.u0.bits_0.led_0_1Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 1 Gb/s + + */ + unsigned int led_0_1Gb_sLinkEstablished : 1; /* 1E.C430.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 1 Gb/s + */ + /*! \brief 1E.C430.7 R/WPD LED #0 10 Gb/s Link Established + AQ_GlobalLedProvisioning_HHD.u0.bits_0.led_0_10Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 10 Gb/s + + */ + unsigned int led_0_10Gb_sLinkEstablished : 1; /* 1E.C430.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 10 Gb/s + */ + /*! \brief 1E.C430.8 R/WPD LED #0 Manual Set + AQ_GlobalLedProvisioning_HHD.u0.bits_0.led_0ManualSet + + Provisionable Default = 0x0 + + 1 = LED On + + */ + unsigned int led_0ManualSet : 1; /* 1E.C430.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED On + */ + /*! \brief 1E.C430.D:9 R/WPD Reserved Provisioning C430 [4:0] + AQ_GlobalLedProvisioning_HHD.u0.bits_0.reservedProvisioningC430 + + Provisionable Default = 0x00 + + Reserved for future use + */ + unsigned int reservedProvisioningC430 : 5; /* 1E.C430.D:9 R/WPD Provisionable Default = 0x00 */ + /* Reserved for future use */ + unsigned int reserved0 : 2; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global LED Provisioning */ + union + { + struct + { + /*! \brief 1E.C431.1:0 R/WPD LED #1 Activity Stretch [1:0] + AQ_GlobalLedProvisioning_HHD.u1.bits_1.led_1ActivityStretch + + Provisionable Default = 0x3 + + [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + + */ + unsigned int led_1ActivityStretch : 2; /* 1E.C431.1:0 R/WPD Provisionable Default = 0x3 */ + /* [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + */ + /*! \brief 1E.C431.2 R/WPD LED #1 Transmit Activity + AQ_GlobalLedProvisioning_HHD.u1.bits_1.led_1TransmitActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on transmit activity + + */ + unsigned int led_1TransmitActivity : 1; /* 1E.C431.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on transmit activity + */ + /*! \brief 1E.C431.3 R/WPD LED #1 Receive Activity + AQ_GlobalLedProvisioning_HHD.u1.bits_1.led_1ReceiveActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on receive activity + + */ + unsigned int led_1ReceiveActivity : 1; /* 1E.C431.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on receive activity + */ + /*! \brief 1E.C431.4 R/WPD LED #1 Connecting + AQ_GlobalLedProvisioning_HHD.u1.bits_1.led_1Connecting + + Provisionable Default = 0x0 + + 1 = LED is on when attempting to connect. + + */ + unsigned int led_1Connecting : 1; /* 1E.C431.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when attempting to connect. + */ + /*! \brief 1E.C431.5 R/WPD LED #1 100 Mb/s Link Established + AQ_GlobalLedProvisioning_HHD.u1.bits_1.led_1_100Mb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 100 Mb/s. + + */ + unsigned int led_1_100Mb_sLinkEstablished : 1; /* 1E.C431.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 100 Mb/s. + */ + /*! \brief 1E.C431.6 R/WPD LED #1 1 Gb/s Link Established + AQ_GlobalLedProvisioning_HHD.u1.bits_1.led_1_1Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 1 Gb/s + + */ + unsigned int led_1_1Gb_sLinkEstablished : 1; /* 1E.C431.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 1 Gb/s + */ + /*! \brief 1E.C431.7 R/WPD LED #1 10 Gb/s Link Established + AQ_GlobalLedProvisioning_HHD.u1.bits_1.led_1_10Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 10 Gb/s + + */ + unsigned int led_1_10Gb_sLinkEstablished : 1; /* 1E.C431.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 10 Gb/s + */ + /*! \brief 1E.C431.8 R/WPD LED #1 Manual Set + AQ_GlobalLedProvisioning_HHD.u1.bits_1.led_1ManualSet + + Provisionable Default = 0x0 + + 1 = LED On + + */ + unsigned int led_1ManualSet : 1; /* 1E.C431.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED On + */ + /*! \brief 1E.C431.D:9 R/WPD Reserved Provisioning C431 [4:0] + AQ_GlobalLedProvisioning_HHD.u1.bits_1.reservedProvisioningC431 + + Provisionable Default = 0x00 + + Reserved for future use + */ + unsigned int reservedProvisioningC431 : 5; /* 1E.C431.D:9 R/WPD Provisionable Default = 0x00 */ + /* Reserved for future use */ + unsigned int reserved0 : 2; + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global LED Provisioning */ + union + { + struct + { + /*! \brief 1E.C432.1:0 R/WPD LED #2 Activity Stretch [1:0] + AQ_GlobalLedProvisioning_HHD.u2.bits_2.led_2ActivityStretch + + Provisionable Default = 0x3 + + [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + + */ + unsigned int led_2ActivityStretch : 2; /* 1E.C432.1:0 R/WPD Provisionable Default = 0x3 */ + /* [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + */ + /*! \brief 1E.C432.2 R/WPD LED #2 Transmit Activity + AQ_GlobalLedProvisioning_HHD.u2.bits_2.led_2TransmitActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on transmit activity + + */ + unsigned int led_2TransmitActivity : 1; /* 1E.C432.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on transmit activity + */ + /*! \brief 1E.C432.3 R/WPD LED #2 Receive Activity + AQ_GlobalLedProvisioning_HHD.u2.bits_2.led_2ReceiveActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on receive activity + + */ + unsigned int led_2ReceiveActivity : 1; /* 1E.C432.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on receive activity + */ + /*! \brief 1E.C432.4 R/WPD LED #2 Connecting + AQ_GlobalLedProvisioning_HHD.u2.bits_2.led_2Connecting + + Provisionable Default = 0x0 + + 1 = LED is on when attempting to connect. + + */ + unsigned int led_2Connecting : 1; /* 1E.C432.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when attempting to connect. + */ + /*! \brief 1E.C432.5 R/WPD LED #2 100 Mb/s Link Established + AQ_GlobalLedProvisioning_HHD.u2.bits_2.led_2_100Mb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 100 Mb/s. + */ + unsigned int led_2_100Mb_sLinkEstablished : 1; /* 1E.C432.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 100 Mb/s. */ + /*! \brief 1E.C432.6 R/WPD LED #2 1 Gb/s Link Established + AQ_GlobalLedProvisioning_HHD.u2.bits_2.led_2_1Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 1 Gb/s + + */ + unsigned int led_2_1Gb_sLinkEstablished : 1; /* 1E.C432.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 1 Gb/s + */ + /*! \brief 1E.C432.7 R/WPD LED #2 10 Gb/s Link Established + AQ_GlobalLedProvisioning_HHD.u2.bits_2.led_2_10Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 10 Gb/s + + */ + unsigned int led_2_10Gb_sLinkEstablished : 1; /* 1E.C432.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 10 Gb/s + */ + /*! \brief 1E.C432.8 R/WPD LED #2 Manual Set + AQ_GlobalLedProvisioning_HHD.u2.bits_2.led_2ManualSet + + Provisionable Default = 0x0 + + 1 = LED On + + */ + unsigned int led_2ManualSet : 1; /* 1E.C432.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED On + */ + /*! \brief 1E.C432.D:9 R/WPD Reserved Provisioning C432 [4:0] + AQ_GlobalLedProvisioning_HHD.u2.bits_2.reservedProvisioningC432 + + Provisionable Default = 0x00 + + Reserved for future use + */ + unsigned int reservedProvisioningC432 : 5; /* 1E.C432.D:9 R/WPD Provisionable Default = 0x00 */ + /* Reserved for future use */ + unsigned int reserved0 : 2; + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_5; + uint16_t word_5; + } u5; + /*! \brief Union for bit and word level access of word 6 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_6; + uint16_t word_6; + } u6; + /*! \brief Union for bit and word level access of word 7 of Global LED Provisioning */ + union + { + struct + { + /*! \brief 1E.C437.0 R/WPD LED Operation Mode + AQ_GlobalLedProvisioning_HHD.u7.bits_7.ledOperationMode + + Provisionable Default = 0x0 + + 1 = LED link activity in Mode #2 + 0 = LED link activity in Aquantia classic mode + + + Notes: + When set to 1, the LED blinking rate is based on Mode #2 algorithm. When set to 0, the LED blinking rate is based on the classic Aquantia algorithm. */ + unsigned int ledOperationMode : 1; /* 1E.C437.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED link activity in Mode #2 + 0 = LED link activity in Aquantia classic mode + */ + unsigned int reserved0 : 15; + } bits_7; + uint16_t word_7; + } u7; + /*! \brief Dummy union to fill space in the structure Global LED Provisioning */ + union + { + struct + { + unsigned int reserved : 16; + } bits_8; + uint16_t word_8; + } u8; + /*! \brief Dummy union to fill space in the structure Global LED Provisioning */ + union + { + struct + { + unsigned int reserved : 16; + } bits_9; + uint16_t word_9; + } u9; + /*! \brief Dummy union to fill space in the structure Global LED Provisioning */ + union + { + struct + { + unsigned int reserved : 16; + } bits_10; + uint16_t word_10; + } u10; + /*! \brief Dummy union to fill space in the structure Global LED Provisioning */ + union + { + struct + { + unsigned int reserved : 16; + } bits_11; + uint16_t word_11; + } u11; + /*! \brief Dummy union to fill space in the structure Global LED Provisioning */ + union + { + struct + { + unsigned int reserved : 16; + } bits_12; + uint16_t word_12; + } u12; + /*! \brief Dummy union to fill space in the structure Global LED Provisioning */ + union + { + struct + { + unsigned int reserved : 16; + } bits_13; + uint16_t word_13; + } u13; + /*! \brief Union for bit and word level access of word 14 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_14; + uint16_t word_14; + } u14; +} AQ_GlobalLedProvisioning_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global General Provisioning: 1E.C440 */ +/* Global General Provisioning: 1E.C440 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global General Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global General Provisioning */ + union + { + struct + { + unsigned int reserved3 : 2; + unsigned int reserved2 : 1; + /*! \brief 1E.C441.3 R/WPD MDIO Preamble Detection Disable + AQ_GlobalGeneralProvisioning_HHD.u1.bits_1.mdioPreambleDetectionDisable + + Provisionable Default = 0x0 + + 1 = Suppress preamble detection on MDIO + 0 = Enable preamble detection on MDIO + + */ + unsigned int mdioPreambleDetectionDisable : 1; /* 1E.C441.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = Suppress preamble detection on MDIO + 0 = Enable preamble detection on MDIO + */ + /*! \brief 1E.C441.4 R/WPD MDIO Drive Configuration + AQ_GlobalGeneralProvisioning_HHD.u1.bits_1.mdioDriveConfiguration + + Provisionable Default = 0x0 + + 0 = MDIO driver is in normal mode + 1 = MDIO driver is in open drain mode + + + Notes: + When the MDIO driver is in open drain mode during a read cycle, "0" data will be actively driven out of the MDIO, "1" data will set the MDIO driver in high impedance state and an external pullup will set the MDIO line to "1". The Turn-Around "0" will also be actively driven out of the MDIO, therefore in open drain mode, the Turn-Around is still "Z0". */ + unsigned int mdioDriveConfiguration : 1; /* 1E.C441.4 R/WPD Provisionable Default = 0x0 */ + /* 0 = MDIO driver is in normal mode + 1 = MDIO driver is in open drain mode + */ + unsigned int reserved1 : 8; + /*! \brief 1E.C441.D R/WPD MDIO Read MSW First Enable + AQ_GlobalGeneralProvisioning_HHD.u1.bits_1.mdioReadMSW_FirstEnable + + Provisionable Default = 0x0 + + 1 = MSW of counter must be read first + 0 = LSW of counter must be read first + + + Notes: + This bit configures whether the MSW or LSW must be read first for counters greater than 16 bits. */ + unsigned int mdioReadMSW_FirstEnable : 1; /* 1E.C441.D R/WPD Provisionable Default = 0x0 */ + /* 1 = MSW of counter must be read first + 0 = LSW of counter must be read first + */ + /*! \brief 1E.C441.E R/WPD MDIO Broadcast Mode Enable + AQ_GlobalGeneralProvisioning_HHD.u1.bits_1.mdioBroadcastModeEnable + + Provisionable Default = 0x0 + + 1 = Enable broadcast on address set in 1E.C446 + 0 = Disable broadcast on n address set in 1E.C446 + + + Notes: + When enabled, writes and load MMD address opcodes are supported. Read opcodes are ignored. */ + unsigned int mdioBroadcastModeEnable : 1; /* 1E.C441.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable broadcast on address set in 1E.C446 + 0 = Disable broadcast on n address set in 1E.C446 + */ + unsigned int reserved0 : 1; + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global General Provisioning */ + union + { + struct + { + /*! \brief 1E.C442.0 R/W Daisy Chain Reset + AQ_GlobalGeneralProvisioning_HHD.u2.bits_2.daisyChainReset + + Default = 0x0 + + 1 = Reset the daisy chain + + + Notes: + Toggling this bit from 0 to 1 will reload the IRAM and DRAM and reset the uP. The uP will be in uP run stall during the reload process. After the reload process, uP run stall will be de-asserted and the uP reset will be asserted. Note that before setting this bit, the See Soft Reset bit needs to be de-asserted. */ + unsigned int daisyChainReset : 1; /* 1E.C442.0 R/W Default = 0x0 */ + /* 1 = Reset the daisy chain + */ + unsigned int reserved0 : 15; + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global General Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global General Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of Global General Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_5; + uint16_t word_5; + } u5; + /*! \brief Union for bit and word level access of word 6 of Global General Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_6; + uint16_t word_6; + } u6; + /*! \brief Union for bit and word level access of word 7 of Global General Provisioning */ + union + { + struct + { + /*! \brief 1E.C447.4:0 R/WPD MDIO Broadcast Address Configuration [4:0] + AQ_GlobalGeneralProvisioning_HHD.u7.bits_7.mdioBroadcastAddressConfiguration + + Provisionable Default = 0x1F + + Broadcast address + + + Notes: + Allows setting the broadcast address. By default this is set to 0x1F */ + unsigned int mdioBroadcastAddressConfiguration : 5; /* 1E.C447.4:0 R/WPD Provisionable Default = 0x1F */ + /* Broadcast address + */ + unsigned int reserved0 : 11; + } bits_7; + uint16_t word_7; + } u7; + /*! \brief Union for bit and word level access of word 8 of Global General Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_8; + uint16_t word_8; + } u8; + /*! \brief Union for bit and word level access of word 9 of Global General Provisioning */ + union + { + struct + { + /*! \brief 1E.C449.6:0 R/W MDIO Preamble Length [6:0] + AQ_GlobalGeneralProvisioning_HHD.u9.bits_9.mdioPreambleLength + + Default = 0x02 + + MDIO Preamble Length + + */ + unsigned int mdioPreambleLength : 7; /* 1E.C449.6:0 R/W Default = 0x02 */ + /* MDIO Preamble Length + */ + unsigned int reserved0 : 9; + } bits_9; + uint16_t word_9; + } u9; +} AQ_GlobalGeneralProvisioning_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global NVR Provisioning: 1E.C450 */ +/* Global NVR Provisioning: 1E.C450 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global NVR Provisioning */ + union + { + struct + { + /*! \brief 1E.C450.1:0 R/WPD NVR Address Length [1:0] + AQ_GlobalNvrProvisioning_HHD.u0.bits_0.nvrAddressLength + + Provisionable Default = 0x2 + + NVR address length ranges from 0 bytes up to 3 bytes + + + Notes: + This sets the length of the address field used in read and write operations. Use of this field is enabled via Bit 8 of See Global NVR Provisioning 2: Address 1E.C451 . + */ + unsigned int nvrAddressLength : 2; /* 1E.C450.1:0 R/WPD Provisionable Default = 0x2 */ + /* NVR address length ranges from 0 bytes up to 3 bytes + */ + unsigned int reserved2 : 2; + /*! \brief 1E.C450.6:4 R/WPD NVR Dummy Length [2:0] + AQ_GlobalNvrProvisioning_HHD.u0.bits_0.nvrDummyLength + + Provisionable Default = 0x0 + + NVR dummy length ranges from 0 bytes to 4 bytes + + + Notes: + This sets the length of the dummy field used in some manufacturer's read status and write status operations. + */ + unsigned int nvrDummyLength : 3; /* 1E.C450.6:4 R/WPD Provisionable Default = 0x0 */ + /* NVR dummy length ranges from 0 bytes to 4 bytes + */ + unsigned int reserved1 : 1; + /*! \brief 1E.C450.A:8 R/WPD NVR Data Length [2:0] + AQ_GlobalNvrProvisioning_HHD.u0.bits_0.nvrDataLength + + Provisionable Default = 0x4 + + NVR data length ranges from 0 bytes to 4 bytes + + + Notes: + This sets the length of the data burst used in read and write operations. + */ + unsigned int nvrDataLength : 3; /* 1E.C450.A:8 R/WPD Provisionable Default = 0x4 */ + /* NVR data length ranges from 0 bytes to 4 bytes + */ + unsigned int reserved0 : 5; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global NVR Provisioning */ + union + { + struct + { + /*! \brief 1E.C451.7:0 R/WPD NVR Clock Divide [7:0] + AQ_GlobalNvrProvisioning_HHD.u1.bits_1.nvrClockDivide + + Provisionable Default = 0xA0 + + NVR clock divide. Clock frequency is divided by the NVR clock divide + 1 + + */ + unsigned int nvrClockDivide : 8; /* 1E.C451.7:0 R/WPD Provisionable Default = 0xA0 */ + /* NVR clock divide. Clock frequency is divided by the NVR clock divide + 1 + */ + /*! \brief 1E.C451.8 R/WPD NVR Address Length Override + AQ_GlobalNvrProvisioning_HHD.u1.bits_1.nvrAddressLengthOverride + + Provisionable Default = 0x0 + + 0 = NVR address length is based on the "NVR_SIZE" pin. + 1 = NVR address length is based on the See NVR Address Length [1:0] register + + + Notes: + When this bit = 0 and NVR_SIZE pin = 0, the NVR address length is 2 bytes. When this bit = 0 and the NVR_SIZE pin = 1, the NVR address length is 3 bytes. When this bit = 1 the NVR address length is from the See NVR Address Length [1:0] */ + unsigned int nvrAddressLengthOverride : 1; /* 1E.C451.8 R/WPD Provisionable Default = 0x0 */ + /* 0 = NVR address length is based on the "NVR_SIZE" pin. + 1 = NVR address length is based on the See NVR Address Length [1:0] register + */ + unsigned int reserved0 : 7; + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global NVR Provisioning */ + union + { + struct + { + /*! \brief 1E.C452.0 R/W NVR Daisy Chain Disable + AQ_GlobalNvrProvisioning_HHD.u2.bits_2.nvrDaisyChainDisable + + Default = 0x0 + + 1 = Disable the Daisy Chain + + + Notes: + When in daisy chain master mode, the daisy chain and MDIO can both access the SPI. Setting this bit to 1 will disable the daisy chain from accessing the SPI and force it into a reset state. */ + unsigned int nvrDaisyChainDisable : 1; /* 1E.C452.0 R/W Default = 0x0 */ + /* 1 = Disable the Daisy Chain + */ + /*! \brief 1E.C452.1 R/W NVR Daisy Chain Clock Divide Override + AQ_GlobalNvrProvisioning_HHD.u2.bits_2.nvrDaisyChainClockDivideOverride + + Default = 0x0 + + 1 = Override NVR clock divide when in daisy chain master mode + + + Notes: + When in daisy chain master mode, the clock divide configuration is received from the FLASH. This bit will override the clock divide configuration from the FLASH with the See NVR Clock Divide [7:0] . */ + unsigned int nvrDaisyChainClockDivideOverride : 1; /* 1E.C452.1 R/W Default = 0x0 */ + /* 1 = Override NVR clock divide when in daisy chain master mode + */ + unsigned int reserved0 : 14; + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global NVR Provisioning */ + union + { + struct + { + unsigned int reserved1 : 4; + /*! \brief 1E.C453.4 R/W NVR Reset + AQ_GlobalNvrProvisioning_HHD.u3.bits_3.nvrReset + + Default = 0x0 + + 1 = Reset SPI + + */ + unsigned int nvrReset : 1; /* 1E.C453.4 R/W Default = 0x0 */ + /* 1 = Reset SPI + */ + unsigned int reserved0 : 11; + } bits_3; + uint16_t word_3; + } u3; +} AQ_GlobalNvrProvisioning_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Reserved Provisioning: 1E.C470 */ +/* Global Reserved Provisioning: 1E.C470 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Reserved Provisioning */ + union + { + struct + { + unsigned int reserved2 : 4; + /*! \brief 1E.C470.4 R/WSC Initiate Cable Diagnostics + AQ_GlobalReservedProvisioning_HHD.u0.bits_0.initiateCableDiagnostics + + Default = 0x0 + + 1 = Perform cable diagnostics + + + Notes: + Perform cable diagnostics regardless of link state. If link is up, setting this bit will cause the link to drop while diagnostics are performed. This bit is self-clearing upon completion of the cable diagnostics. + + NOTE!! This is a processor intensive operation. Completion of this operation can also be monitored via 1E.C831.F */ + unsigned int initiateCableDiagnostics : 1; /* 1E.C470.4 R/WSC Default = 0x0 */ + /* 1 = Perform cable diagnostics + */ + unsigned int reserved1 : 3; + unsigned int reserved0 : 5; + /*! \brief 1E.C470.E:D R/WPD Extended MDI Diagnostics Select [1:0] + AQ_GlobalReservedProvisioning_HHD.u0.bits_0.extendedMdiDiagnosticsSelect + + Provisionable Default = 0x0 + + 0x0 = TDR Data + 0x1 = RFI Channel PSD + 0x2 = Noise PSD while the local Tx is Off + 0x3 = Noise PSD while the local Tx is On + + + Notes: + These bits select what sort of cable diagnostics to perform. For regular cable diagnostics, Bit F is set to zero, and the diagnostics are triggered by setting Bit 4. For extended diagnostics, Bit F is set to 1, and the desired extended diagnostics are selected by Bits E:D. The routine is then triggered by setting Bit 4. Each of the extended diagnostic routines present data for all for MDI pairs (A, B, C, D) consecutively, and after the data for each channel is gathered Bits F:D are reset. To get the data for the next pair, Bits F:D must be set back to the desired value (which must be the same as the initial channel). This continues until the data for all channels has been gathered. The address in memory where the data is stored is given in 1E.C802 and 1E.C804. + + For the case of PSD, the structure is as follows: + Int32 info + Int16 data[Len] + Info = Len << 16 | TxEnable << 8 | Pair (0 = A, etc.) + + For TDR: + Int32 info + Int16 tdr_A[Len] + Int16 tdr_B[Len] + Int16 tdr_C[Len] + Int16 tdr_D[Len] + + Info = Len << 16 | Channel + + TDR data is from the current pair to all other pairs. + + At the end of retrieving extended MDI diag data, the part will be reset. Conversely the only way to exit this routine once it starts is to issue a PMA reset. */ + unsigned int extendedMdiDiagnosticsSelect : 2; /* 1E.C470.E:D R/WPD Provisionable Default = 0x0 */ + /* 0x0 = TDR Data + 0x1 = RFI Channel PSD + 0x2 = Noise PSD while the local Tx is Off + 0x3 = Noise PSD while the local Tx is On + */ + /*! \brief 1E.C470.F R/WPD Diagnostics Select + AQ_GlobalReservedProvisioning_HHD.u0.bits_0.diagnosticsSelect + + Provisionable Default = 0x0 + + 1 = Provide Extended MDI Diagnostics Information. + 0 = Provide normal cable diagnostics + + + Notes: + These bits select what sort of cable diagnostics to perform. For regular cable diagnostics, Bit F is set to zero, and the diagnostics are triggered by setting Bit 4. For extended diagnostics, Bit F is set to 1, and the desired extended diagnostics are selected by Bits E:D. The routine is then triggered by setting Bit 4. Each of the extended diagnostic routines present data for all for MDI pairs (A, B, C, D) consecutively, and after the data for each channel is gathered Bits F:D are reset. To get the data for the next pair, Bits F:D must be set back to the desired value (which must be the same as the initial channel). This continues until the data for all channels has been gathered. The address in memory where the data is stored is given in 1E.C802 and 1E.C804. + + For the case of PSD, the structure is as follows: + Int32 info + Int16 data[Len] + Info = Len << 16 | TxEnable << 8 | Pair (0 = A, etc.) + + For TDR: + Int32 info + Int16 tdr_A[Len] + Int16 tdr_B[Len] + Int16 tdr_C[Len] + Int16 tdr_D[Len] + + Info = Len << 16 | Channel + + TDR data is from the current pair to all other pairs. + + At the end of retrieving extended MDI diag data, the part will be reset. Conversely the only way to exit this routine once it starts is to issue a PMA reset. */ + unsigned int diagnosticsSelect : 1; /* 1E.C470.F R/WPD Provisionable Default = 0x0 */ + /* 1 = Provide Extended MDI Diagnostics Information. + 0 = Provide normal cable diagnostics + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Reserved Provisioning */ + union + { + struct + { + /*! \brief 1E.C471.5:0 R/WuP Daisy-Chain Hop-Count Override Value [5:0] + AQ_GlobalReservedProvisioning_HHD.u1.bits_1.daisy_chainHop_countOverrideValue + + Default = 0x00 + + The value to use for the PHY's daisy-chain hop-count. Valid values are from 0 -> 47 + + + Notes: + Daisy-Chain Hop-Count Override should be used during MDIO boot-load operation, as the daisy-chain hop-count does not function when the daisy-chain is disabled (1E.C452.0). Setting this bit tells the processor where in the daisy-chain it is, so that the provisioning operation will function correctly. */ + unsigned int daisy_chainHop_countOverrideValue : 6; /* 1E.C471.5:0 R/WuP Default = 0x00 */ + /* The value to use for the PHY's daisy-chain hop-count. Valid values are from 0 -> 47 + */ + /*! \brief 1E.C471.6 R/WuP Enable Daisy-Chain Hop-Count Override + AQ_GlobalReservedProvisioning_HHD.u1.bits_1.enableDaisy_chainHop_countOverride + + Default = 0x0 + + 1 = Hop-count is set by Bits 5:0 + 0 = Hop-count is determined by the daisy-chain + + + Notes: + Daisy-Chain Hop-Count Override should be used during MDIO boot-load operation, as the daisy-chain hop-count does not function when the daisy-chain is disabled (1E.C452.0). Setting this bit tells the processor where in the daisy-chain it is, so that the provisioning operation will function correctly. */ + unsigned int enableDaisy_chainHop_countOverride : 1; /* 1E.C471.6 R/WuP Default = 0x0 */ + /* 1 = Hop-count is set by Bits 5:0 + 0 = Hop-count is determined by the daisy-chain + */ + unsigned int reserved0 : 9; + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Reserved Provisioning */ + union + { + struct + { + /*! \brief 1E.C472.0 R/WPDuP Enable 5th Channel RFI Cancellation + AQ_GlobalReservedProvisioning_HHD.u2.bits_2.enable_5thChannelRfiCancellation + + Provisionable Default = 0x0 + + 1 = 5th channel and RFI cancellers operation enabled + 0 = 5th channel AFE is powered down, 5th channel digital is clock gated, RFI cancellers are disabled + + + Notes: + Note: The value of this bit at the time of Autonegotiation sets the local PHY behavior until the next time Autonegotiation occurs. */ + unsigned int enable_5thChannelRfiCancellation : 1; /* 1E.C472.0 R/WPDuP Provisionable Default = 0x0 */ + /* 1 = 5th channel and RFI cancellers operation enabled + 0 = 5th channel AFE is powered down, 5th channel digital is clock gated, RFI cancellers are disabled + */ + /*! \brief 1E.C472.1 R/WPDuP Enable XENPAK Register Space + AQ_GlobalReservedProvisioning_HHD.u2.bits_2.enableXenpakRegisterSpace + + Provisionable Default = 0x0 + + 1 = XENPAK register space enabled + 0 = XENPAK register space disabled + + */ + unsigned int enableXenpakRegisterSpace : 1; /* 1E.C472.1 R/WPDuP Provisionable Default = 0x0 */ + /* 1 = XENPAK register space enabled + 0 = XENPAK register space disabled + */ + /*! \brief 1E.C472.5:2 R/WPD External VDD Change Request [3:0] + AQ_GlobalReservedProvisioning_HHD.u2.bits_2.externalVddChangeRequest + + Provisionable Default = 0x0 + + The amount of VDD change requested by firmware, in mV (2's complement value). + + */ + unsigned int externalVddChangeRequest : 4; /* 1E.C472.5:2 R/WPD Provisionable Default = 0x0 */ + /* The amount of VDD change requested by firmware, in mV (2's complement value). + */ + /*! \brief 1E.C472.6 R/WPD Tunable External VDD Power Supply Present + AQ_GlobalReservedProvisioning_HHD.u2.bits_2.tunableExternalVddPowerSupplyPresent + + Provisionable Default = 0x0 + + 1 = Tunable external VDD power supply present + 0 = No tunable external VDD power supply present + + + Notes: + This bit must be set if tuning of external power supply is desired. */ + unsigned int tunableExternalVddPowerSupplyPresent : 1; /* 1E.C472.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = Tunable external VDD power supply present + 0 = No tunable external VDD power supply present + */ + unsigned int reserved1 : 7; + /*! \brief 1E.C472.E R/WPD Enable VDD Power Supply Tuning + AQ_GlobalReservedProvisioning_HHD.u2.bits_2.enableVddPowerSupplyTuning + + Provisionable Default = 0x0 + + 1 = Enable external VDD power supply tuning + 0 = Disable external VDD power supply tuning is disabled + + + Notes: + This bit controls whether the PHY attempts to tune the external VDD power supply via the SMBus. This bit is only operational if the external supply is present. (See 1E.C472.6) */ + unsigned int enableVddPowerSupplyTuning : 1; /* 1E.C472.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable external VDD power supply tuning + 0 = Disable external VDD power supply tuning is disabled + */ + unsigned int reserved0 : 1; + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global Reserved Provisioning */ + union + { + struct + { + /*! \brief 1E.C473.7:0 R/WPD Training SNR [7:0] + AQ_GlobalReservedProvisioning_HHD.u3.bits_3.trainingSNR + + Provisionable Default = 0x00 + + SNR during 10G training on the worst channel. SNR is in steps of 0.1dB + + + Notes: + The SNR margin that is enjoyed by the worst channel, over and above the minimum SNR required to operate at a BER of 10-12. It is reported with 0.1 dB of resolution to an accuracy of 0.5 dB within the range of -12.7 dB to 12.7 dB. The number is in offset binary, with 0.0 dB represented by 0x8000. */ + unsigned int trainingSNR : 8; /* 1E.C473.7:0 R/WPD Provisionable Default = 0x00 */ + /* SNR during 10G training on the worst channel. SNR is in steps of 0.1dB + */ + /*! \brief 1E.C473.A:8 R/WPD Rate Transition Request [2:0] + AQ_GlobalReservedProvisioning_HHD.u3.bits_3.rateTransitionRequest + + Provisionable Default = 0x0 + + 0 = No Transition + 1 = Reserved + 2 = Reserved + 3 = Retrain at 10G + 4 = Retrain at 5G + 5 = Retrain at 2.5G + 6 = Retrain at 1G + 7 = Reserved + + */ + unsigned int rateTransitionRequest : 3; /* 1E.C473.A:8 R/WPD Provisionable Default = 0x0 */ + /* 0 = No Transition + 1 = Reserved + 2 = Reserved + 3 = Retrain at 10G + 4 = Retrain at 5G + 5 = Retrain at 2.5G + 6 = Retrain at 1G + 7 = Reserved + */ + unsigned int reserved0 : 5; + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global Reserved Provisioning */ + union + { + struct + { + /*! \brief 1E.C474.0 R/W NVR Daisy Chain Kickstart + AQ_GlobalReservedProvisioning_HHD.u4.bits_4.nvrDaisyChainKickstart + + Default = 0x0 + + 1 = Kickstart the Daisy Chain + + + Notes: + When in daisy chain master mode, the PHY0 can kickstart the daisy chain. The kickstart will not reload the IRAM/DRAM or reset the uP for PHY0. It will just read the FLASH and transfer the FLASH data to the daisy chain. */ + unsigned int nvrDaisyChainKickstart : 1; /* 1E.C474.0 R/W Default = 0x0 */ + /* 1 = Kickstart the Daisy Chain + */ + /*! \brief 1E.C474.F:1 R/WPD Reserved Provisioning 5 [F:1] + AQ_GlobalReservedProvisioning_HHD.u4.bits_4.reservedProvisioning_5 + + Provisionable Default = 0x0000 + + Reserved for future use + + */ + unsigned int reservedProvisioning_5 : 15; /* 1E.C474.F:1 R/WPD Provisionable Default = 0x0000 */ + /* Reserved for future use + */ + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of Global Reserved Provisioning */ + union + { + struct + { + unsigned int reserved1 : 2; + /*! \brief 1E.C475.2 R/WPD Smart Power-Down Enable + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.smartPower_downEnable + + Provisionable Default = 0x0 + + 1 = Enable smart power down mode + 0 = Smart power-down mode disabled + + + Notes: + Smart power down (SPD) is the lowest power mode at which PHY is able to autonegotiate. SPD can be enabled with bit 1E.C475.2 */ + unsigned int smartPower_downEnable : 1; /* 1E.C475.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable smart power down mode + 0 = Smart power-down mode disabled + */ + /*! \brief 1E.C475.3 R/WPD Deadlock Avoidance Enable + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.deadlockAvoidanceEnable + + Provisionable Default = 0x0 + + 1 = SPD with deadlock avoidance: PHY transmits autonegotiation pulses (FLPs) at a slower rate (~ 1 FLP/ 100ms) than specified by autonegotiation standard (~1 FLP / 8.25ms). Receiver is active and able to detect the pulses. + 0 = SPD without deadlock avoidance: PHY transmitter is shut down, no autonegotiation pulses are sent on the line but the receiver is active and able to detect the pulses + + */ + unsigned int deadlockAvoidanceEnable : 1; /* 1E.C475.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = SPD with deadlock avoidance: PHY transmits autonegotiation pulses (FLPs) at a slower rate (~ 1 FLP/ 100ms) than specified by autonegotiation standard (~1 FLP / 8.25ms). Receiver is active and able to detect the pulses. + 0 = SPD without deadlock avoidance: PHY transmitter is shut down, no autonegotiation pulses are sent on the line but the receiver is active and able to detect the pulses + */ + /*! \brief 1E.C475.4 R/WPD CFR Support + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.cfrSupport + + Provisionable Default = 0x0 + + 1 = Local PHY supports Cisco Fast Retrain + 0 = Local PHY does support Cisco Fast Retrain + + */ + unsigned int cfrSupport : 1; /* 1E.C475.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = Local PHY supports Cisco Fast Retrain + 0 = Local PHY does support Cisco Fast Retrain + */ + /*! \brief 1E.C475.5 R/WPD CFR THP + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.cfrTHP + + Provisionable Default = 0x0 + + 1 = Local PHY requires local PHY to enable THP + 0 = Local PHY does not require local PHY to enable THP + + */ + unsigned int cfrTHP : 1; /* 1E.C475.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = Local PHY requires local PHY to enable THP + 0 = Local PHY does not require local PHY to enable THP + */ + /*! \brief 1E.C475.6 R/WPD CFR Extended Maxwait + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.cfrExtendedMaxwait + + Provisionable Default = 0x0 + + 1 = Local PHY requires extended maxwait + 0 = Local PHY does not require extended maxwait + + */ + unsigned int cfrExtendedMaxwait : 1; /* 1E.C475.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = Local PHY requires extended maxwait + 0 = Local PHY does not require extended maxwait + */ + /*! \brief 1E.C475.7 R/WPD CFR Disable Timer + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.cfrDisableTimer + + Provisionable Default = 0x0 + + 1 = Local PHY requires cfr_disable timer + 0 = Local PHY does not require cfr_disable timer + + */ + unsigned int cfrDisableTimer : 1; /* 1E.C475.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = Local PHY requires cfr_disable timer + 0 = Local PHY does not require cfr_disable timer + */ + /*! \brief 1E.C475.8 R/WPD CFR LP Support + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.cfrLpSupport + + Provisionable Default = 0x0 + + 1 = Link partner supports Cisco Fast Retrain + 0 = Link partner does support Cisco Fast Retrain + + */ + unsigned int cfrLpSupport : 1; /* 1E.C475.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = Link partner supports Cisco Fast Retrain + 0 = Link partner does support Cisco Fast Retrain + */ + /*! \brief 1E.C475.9 R/WPD CFR LP THP + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.cfrLpTHP + + Provisionable Default = 0x0 + + 1 = Link partner requires local PHY to enable THP + 0 = Link partner does not require local PHY to enable THP + + */ + unsigned int cfrLpTHP : 1; /* 1E.C475.9 R/WPD Provisionable Default = 0x0 */ + /* 1 = Link partner requires local PHY to enable THP + 0 = Link partner does not require local PHY to enable THP + */ + /*! \brief 1E.C475.A R/WPD CFR LP Extended Maxwait + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.cfrLpExtendedMaxwait + + Provisionable Default = 0x0 + + 1 = Link partner requires extended maxwait + 0 = Link partner does not require extended maxwait + + */ + unsigned int cfrLpExtendedMaxwait : 1; /* 1E.C475.A R/WPD Provisionable Default = 0x0 */ + /* 1 = Link partner requires extended maxwait + 0 = Link partner does not require extended maxwait + */ + /*! \brief 1E.C475.B R/WPD CFR LP Disable Timer + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.cfrLpDisableTimer + + Provisionable Default = 0x0 + + 1 = Link partner requires cfr_disable timer + 0 = Link partner does not require cfr_disable timer + + */ + unsigned int cfrLpDisableTimer : 1; /* 1E.C475.B R/WPD Provisionable Default = 0x0 */ + /* 1 = Link partner requires cfr_disable timer + 0 = Link partner does not require cfr_disable timer + */ + /*! \brief 1E.C475.C R/WPD Reserved Provisioning 6 + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.reservedProvisioning_6 + + Provisionable Default = 0x0 + + Internal reserved - do not modify + + */ + unsigned int reservedProvisioning_6 : 1; /* 1E.C475.C R/WPD Provisionable Default = 0x0 */ + /* Internal reserved - do not modify + */ + /*! \brief 1E.C475.D R/WPD Smart Power-Down Status + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.smartPower_downStatus + + Provisionable Default = 0x0 + + 1 = Smart Power-Down Active + 0 = Smart Power-Down Inactive + + */ + unsigned int smartPower_downStatus : 1; /* 1E.C475.D R/WPD Provisionable Default = 0x0 */ + /* 1 = Smart Power-Down Active + 0 = Smart Power-Down Inactive + */ + unsigned int reserved0 : 2; + } bits_5; + uint16_t word_5; + } u5; + /*! \brief Dummy union to fill space in the structure Global Reserved Provisioning */ + union + { + struct + { + unsigned int reserved : 16; + } bits_6; + uint16_t word_6; + } u6; + /*! \brief Dummy union to fill space in the structure Global Reserved Provisioning */ + union + { + struct + { + unsigned int reserved : 16; + } bits_7; + uint16_t word_7; + } u7; + /*! \brief Union for bit and word level access of word 8 of Global Reserved Provisioning */ + union + { + struct + { + /*! \brief 1E.C478.A:0 R/WPD Reserved Provisioning 9 [A:0] + AQ_GlobalReservedProvisioning_HHD.u8.bits_8.reservedProvisioning_9 + + Provisionable Default = 0x000 + + Reserved for future use + + */ + unsigned int reservedProvisioning_9 : 11; /* 1E.C478.A:0 R/WPD Provisionable Default = 0x000 */ + /* Reserved for future use + */ + /*! \brief 1E.C478.E:B R/WPD DTE Drop Reporting Timer [3:0] + AQ_GlobalReservedProvisioning_HHD.u8.bits_8.dteDropReportingTimer + + Provisionable Default = 0x0 + + Number of seconds between loss of link partner filter and assertion of no-power-needed state, in 5 second increments (e.g. 0x4 = 20 seconds). + + + Notes: + These bits are used to set how long the PHY waits after it no longer detects the link partner filter before declaring that power is not needed. */ + unsigned int dteDropReportingTimer : 4; /* 1E.C478.E:B R/WPD Provisionable Default = 0x0 */ + /* Number of seconds between loss of link partner filter and assertion of no-power-needed state, in 5 second increments (e.g. 0x4 = 20 seconds). + */ + /*! \brief 1E.C478.F R/WPD DTE Enable + AQ_GlobalReservedProvisioning_HHD.u8.bits_8.dteEnable + + Provisionable Default = 0x0 + + 1 = Enable DTE + 0 = Disable DTE + + */ + unsigned int dteEnable : 1; /* 1E.C478.F R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable DTE + 0 = Disable DTE + */ + } bits_8; + uint16_t word_8; + } u8; + /*! \brief Union for bit and word level access of word 9 of Global Reserved Provisioning */ + union + { + struct + { + /*! \brief 1E.C479.E:0 R/WPD Reserved Provisioning 10 [E:0] + AQ_GlobalReservedProvisioning_HHD.u9.bits_9.reservedProvisioning_10 + + Provisionable Default = 0x0000 + + Reserved for future use + + */ + unsigned int reservedProvisioning_10 : 15; /* 1E.C479.E:0 R/WPD Provisionable Default = 0x0000 */ + /* Reserved for future use + */ + /*! \brief 1E.C479.F R/WPD Power Up Stall + AQ_GlobalReservedProvisioning_HHD.u9.bits_9.powerUpStall + + Provisionable Default = 0x0 + + 1 = Stall FW at Power Up + 0 = Unstall the FW + + + Notes: + This bit needs to be provisioned in Power Up Init for firmware to stall. */ + unsigned int powerUpStall : 1; /* 1E.C479.F R/WPD Provisionable Default = 0x0 */ + /* 1 = Stall FW at Power Up + 0 = Unstall the FW + */ + } bits_9; + uint16_t word_9; + } u9; + /*! \brief Union for bit and word level access of word 10 of Global Reserved Provisioning */ + union + { + struct + { + /*! \brief 1E.C47A.1:0 R/WPD Rate [1:0] + AQ_GlobalReservedProvisioning_HHD.u10.bits_10.rate + + Provisionable Default = 0x0 + + 0x3 = 10G + 0x2 = 1G + 0x1 = 100M + 0x0 = reserved + + + Notes: + These bits select the rate for the loopback and packet generation. SERDES configuration, as well autonegotiation is controlled accordingly when a loopback is selected. For instance, if 100M system loopback on the network interface is selected, SGMII on the system interface is enabled to connect at 100M, and if passthrough is enabled 100BASE-TX will be the only advertised rate and will force a re-autonegotiation if not already connected at 100M. + + NOTE!! This is a processor intensive operation. Completion of this operation can be monitored via 1E.C831.F + + The controls in this register are identical to, and mirrored with, the controls in 4.C444. */ + unsigned int rate : 2; /* 1E.C47A.1:0 R/WPD Provisionable Default = 0x0 */ + /* 0x3 = 10G + 0x2 = 1G + 0x1 = 100M + 0x0 = reserved + */ + /*! \brief 1E.C47A.2 R/WPD Reserved Provisioning 11a + AQ_GlobalReservedProvisioning_HHD.u10.bits_10.reservedProvisioning_11a + + Provisionable Default = 0x0 + + Reserved for future use + + */ + unsigned int reservedProvisioning_11a : 1; /* 1E.C47A.2 R/WPD Provisionable Default = 0x0 */ + /* Reserved for future use + */ + /*! \brief 1E.C47A.3 R/WPD System I/F Packet Generation + AQ_GlobalReservedProvisioning_HHD.u10.bits_10.systemI_fPacketGeneration + + Provisionable Default = 0x0 + + 1 = CRPAT packet generation out 10G system interface + 0 = No CRPAT packet generation out 10G system interface + + + Notes: + Selecting this mode of operation causes the CRPAT packet generator in the PHY to output CRPAT packets on the selected 10G system interface (4.C441.F:E) + + NOTE!! This is a processor intensive operation. Completion of this operation can be monitored via 1E.C831.F + + The controls in this register are identical to, and mirrored with, the controls in 4.C444. */ + unsigned int systemI_fPacketGeneration : 1; /* 1E.C47A.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = CRPAT packet generation out 10G system interface + 0 = No CRPAT packet generation out 10G system interface + */ + /*! \brief 1E.C47A.4 R/WPD Look-Aside Port Packet Generation + AQ_GlobalReservedProvisioning_HHD.u10.bits_10.look_asidePortPacketGeneration + + Provisionable Default = 0x0 + + 1 = CRPAT packet generation out 10G look-aside interface (KR0) + 0 = No CRPAT packet generation out 10G look-aside interface (KR0) + + + Notes: + Selecting this mode of operation causes the CRPAT packet generator in the PHY to output on KR0. + + NOTE!! This only functions if KR1 (SERDES2) is selected as the system interface in (4.C441.F:E). + + NOTE!! This is a processor intensive operation. Completion of this operation can be monitored via 1E.C831.F + + The controls in this register are identical to, and mirrored with, the controls in 4.C444. */ + unsigned int look_asidePortPacketGeneration : 1; /* 1E.C47A.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = CRPAT packet generation out 10G look-aside interface (KR0) + 0 = No CRPAT packet generation out 10G look-aside interface (KR0) + */ + /*! \brief 1E.C47A.5 R/WPD MDI Packet Generation + AQ_GlobalReservedProvisioning_HHD.u10.bits_10.mdiPacketGeneration + + Provisionable Default = 0x0 + + 1 = CRPAT packet generation out MDI interface + 0 = No CRPAT packet generation out MDI interface + + + Notes: + Selecting this mode of operation causes the CRPAT packet generator in the PHY to output on the MDI interface at the selected rate. + + NOTE!! This is a processor intensive operation. Completion of this operation can be monitored via 1E.C831.F + + The controls in this register are identical to, and mirrored with, the controls in 4.C444. */ + unsigned int mdiPacketGeneration : 1; /* 1E.C47A.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = CRPAT packet generation out MDI interface + 0 = No CRPAT packet generation out MDI interface + */ + /*! \brief 1E.C47A.A:6 R/WPD Reserved Provisioning 11 [4:0] + AQ_GlobalReservedProvisioning_HHD.u10.bits_10.reservedProvisioning_11 + + Provisionable Default = 0x00 + + Reserved for future use + + */ + unsigned int reservedProvisioning_11 : 5; /* 1E.C47A.A:6 R/WPD Provisionable Default = 0x00 */ + /* Reserved for future use + */ + /*! \brief 1E.C47A.F:B R/WPD Loopback Control [4:0] + AQ_GlobalReservedProvisioning_HHD.u10.bits_10.loopbackControl + + Provisionable Default = 0x00 + + 0x00 = No loopback + 0x01 = System Interface - System Loopback + 0x02 = System Interface - System Loopback with Passthrough + 0x03 = System Interface - Network Loopback + 0x04 = System Interface - Network Loopback with Passthrough + 0x05 = System Interface - Network Loopback with Passthrough and Merge + 0x06 = System Interface - Peer-to-peer loopback + 0x07 - 0x08 = Reserved + 0x09 = Network Interface - System Loopback + 0x0A = Network Interface - System Loopback with Passthrough + 0x0B = Network Interface - Network Loopback + 0x0C = Network Interface - Network Loopback with Passthrough + 0x0D = Network Interface - Peer-to-peer loopback + 0x0E - 0x0F = Reserved + 0x10 = Cross-connect System Loopback + 0x11 = Cross-connect Network Loopback + 0x12 - 0x13 = Reserved + 0x14 = Network Interface - System Loopback via Loopback Plug + 0x15 - 0x1F = Reserved + + + Notes: + These bits, in conjunction with the chip configuration and the rate (Bits 1:0), select the loopback to configure for the chip. Setting one of these loopbacks provisions the chip for the specified loopback. Upon clearing the loopback, the chip returns to it's configuration prior to entering loopback (irregardless of whether other loopbacks were selected after the initial loopback). + + NOTE!! This is a processor intensive operation. Completion of this operation can be monitored via 1E.C831.F. + + The controls in this register are identical to, and mirrored with, the controls in 4.C444. + */ + unsigned int loopbackControl : 5; /* 1E.C47A.F:B R/WPD Provisionable Default = 0x00 */ + /* 0x00 = No loopback + 0x01 = System Interface - System Loopback + 0x02 = System Interface - System Loopback with Passthrough + 0x03 = System Interface - Network Loopback + 0x04 = System Interface - Network Loopback with Passthrough + 0x05 = System Interface - Network Loopback with Passthrough and Merge + 0x06 = System Interface - Peer-to-peer loopback + 0x07 - 0x08 = Reserved + 0x09 = Network Interface - System Loopback + 0x0A = Network Interface - System Loopback with Passthrough + 0x0B = Network Interface - Network Loopback + 0x0C = Network Interface - Network Loopback with Passthrough + 0x0D = Network Interface - Peer-to-peer loopback + 0x0E - 0x0F = Reserved + 0x10 = Cross-connect System Loopback + 0x11 = Cross-connect Network Loopback + 0x12 - 0x13 = Reserved + 0x14 = Network Interface - System Loopback via Loopback Plug + 0x15 - 0x1F = Reserved + */ + } bits_10; + uint16_t word_10; + } u10; + /*! \brief Union for bit and word level access of word 11 of Global Reserved Provisioning */ + union + { + struct + { + /*! \brief 1E.C47B.0 R/WPD Enable PTP + AQ_GlobalReservedProvisioning_HHD.u11.bits_11.enablePtp + + Provisionable Default = 0x0 + + 1 = PTP functionality is enabled + 0 = PTP functionality is disabled + + + Notes: + If this bit is 1, the PTP/SEC block will be included in the data path, regardless of operating mode. */ + unsigned int enablePtp : 1; /* 1E.C47B.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = PTP functionality is enabled + 0 = PTP functionality is disabled + */ + /*! \brief 1E.C47B.1 R/WPD Enable MACSec + AQ_GlobalReservedProvisioning_HHD.u11.bits_11.enableMacsec + + Provisionable Default = 0x0 + + 1 = MACSec functionality is enabled + 0 = MACSec functionality is disabled + + + Notes: + If this bit is 1, the PTP/SEC block will be included in the data path, regardless of operating mode. */ + unsigned int enableMacsec : 1; /* 1E.C47B.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = MACSec functionality is enabled + 0 = MACSec functionality is disabled + */ + /*! \brief 1E.C47B.F:2 R/WPD Reserved Provisioning 12 [D:0] + AQ_GlobalReservedProvisioning_HHD.u11.bits_11.reservedProvisioning_12 + + Provisionable Default = 0x0000 + + Reserved for future use + + */ + unsigned int reservedProvisioning_12 : 14; /* 1E.C47B.F:2 R/WPD Provisionable Default = 0x0000 */ + /* Reserved for future use + */ + } bits_11; + uint16_t word_11; + } u11; +} AQ_GlobalReservedProvisioning_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief PIF Mailbox Control: 1E.C47C */ +/* PIF Mailbox Control: 1E.C47C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of PIF Mailbox Control */ + union + { + struct + { + /*! \brief 1E.C47C.F:0 R/WPDuP PIF Mailbox Address [F:0] + AQ_PifMailboxControl_HHD.u0.bits_0.pifMailboxAddress + + Provisionable Default = 0x0000 + + The least 16 bits of the PIF address to read or write. + + */ + unsigned int pifMailboxAddress : 16; /* 1E.C47C.F:0 R/WPDuP Provisionable Default = 0x0000 */ + /* The least 16 bits of the PIF address to read or write. + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of PIF Mailbox Control */ + union + { + struct + { + /*! \brief 1E.C47D.F:0 R/WPDuP PIF Mailbox Data [F:0] + AQ_PifMailboxControl_HHD.u1.bits_1.pifMailboxData + + Provisionable Default = 0x0000 + + The data to be written, or that had been read. + + */ + unsigned int pifMailboxData : 16; /* 1E.C47D.F:0 R/WPDuP Provisionable Default = 0x0000 */ + /* The data to be written, or that had been read. + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of PIF Mailbox Control */ + union + { + struct + { + /*! \brief 1E.C47E.7:0 R/WPDuP PIF Mailbox MMD [7:0] + AQ_PifMailboxControl_HHD.u2.bits_2.pifMailboxMMD + + Provisionable Default = 0x00 + + MMD (upper 8 bits) of the PID address to read or write. + + */ + unsigned int pifMailboxMMD : 8; /* 1E.C47E.7:0 R/WPDuP Provisionable Default = 0x00 */ + /* MMD (upper 8 bits) of the PID address to read or write. + */ + /*! \brief 1E.C47E.B:8 R/WPDuP PIF Mailbox Command Type [3:0] + AQ_PifMailboxControl_HHD.u2.bits_2.pifMailboxCommandType + + Provisionable Default = 0x0 + + 0 = No Action + 1 = Read + 2 = Write + + + Notes: + System SW writes non-zero value to start a PIF command. */ + unsigned int pifMailboxCommandType : 4; /* 1E.C47E.B:8 R/WPDuP Provisionable Default = 0x0 */ + /* 0 = No Action + 1 = Read + 2 = Write + */ + /*! \brief 1E.C47E.F:C R/WPD Reserved PIF Mailbox Control 3 [3:0] + AQ_PifMailboxControl_HHD.u2.bits_2.reservedPifMailboxControl_3 + + Provisionable Default = 0x0 + + Reserved for future use + + */ + unsigned int reservedPifMailboxControl_3 : 4; /* 1E.C47E.F:C R/WPD Provisionable Default = 0x0 */ + /* Reserved for future use + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of PIF Mailbox Control */ + union + { + struct + { + /*! \brief 1E.C47F.3:0 R/WPDuP PIF Mailbox Command Status [3:0] + AQ_PifMailboxControl_HHD.u3.bits_3.pifMailboxCommandStatus + + Provisionable Default = 0x0 + + 0 = Idle + 1 = Command completed + 2 = Command did not complete + + + Notes: + System SW should write 0 before writing Command Type to clear completion status */ + unsigned int pifMailboxCommandStatus : 4; /* 1E.C47F.3:0 R/WPDuP Provisionable Default = 0x0 */ + /* 0 = Idle + 1 = Command completed + 2 = Command did not complete + */ + /*! \brief 1E.C47F.F:4 R/WPD Reserved PIF Mailbox Control 4 [B:0] + AQ_PifMailboxControl_HHD.u3.bits_3.reservedPifMailboxControl_4 + + Provisionable Default = 0x000 + + Reserved for future use + + */ + unsigned int reservedPifMailboxControl_4 : 12; /* 1E.C47F.F:4 R/WPD Provisionable Default = 0x000 */ + /* Reserved for future use + */ + } bits_3; + uint16_t word_3; + } u3; +} AQ_PifMailboxControl_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global SMBus 0 Provisioning: 1E.C485 */ +/* Global SMBus 0 Provisioning: 1E.C485 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global SMBus 0 Provisioning */ + union + { + struct + { + unsigned int reserved1 : 1; + /*! \brief 1E.C485.7:1 R/W SMB 0 Slave Address [7:1] + AQ_GlobalSmbus_0Provisioning_HHD.u0.bits_0.smb_0SlaveAddress + + Default = 0x00 + + SMB slave address configuration + + */ + unsigned int smb_0SlaveAddress : 7; /* 1E.C485.7:1 R/W Default = 0x00 */ + /* SMB slave address configuration + */ + unsigned int reserved0 : 8; + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalSmbus_0Provisioning_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global SMBus 1 Provisioning: 1E.C495 */ +/* Global SMBus 1 Provisioning: 1E.C495 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global SMBus 1 Provisioning */ + union + { + struct + { + unsigned int reserved1 : 1; + /*! \brief 1E.C495.7:1 R/W SMB 1 Slave Address [7:1] + AQ_GlobalSmbus_1Provisioning_HHD.u0.bits_0.smb_1SlaveAddress + + Default = 0x00 + + SMB slave address configuration + + */ + unsigned int smb_1SlaveAddress : 7; /* 1E.C495.7:1 R/W Default = 0x00 */ + /* SMB slave address configuration + */ + unsigned int reserved0 : 8; + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalSmbus_1Provisioning_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global EEE Provisioning: 1E.C4A0 */ +/* Global EEE Provisioning: 1E.C4A0 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global EEE Provisioning */ + union + { + struct + { + /*! \brief 1E.C4A0.0 R/WPD EEE Mode + AQ_GlobalEeeProvisioning_HHD.u0.bits_0.eeeMode + + Provisionable Default = 0x0 + + 1 = EEE mode of operation + + + Notes: + EEE mode of operation (0=disable, 1=enable, default:0) */ + unsigned int eeeMode : 1; /* 1E.C4A0.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = EEE mode of operation + */ + unsigned int reserved0 : 15; + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalEeeProvisioning_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Cable Diagnostic Status: 1E.C800 */ +/* Global Cable Diagnostic Status: 1E.C800 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C800.2:0 RO Pair D Status [2:0] + AQ_GlobalCableDiagnosticStatus_HHD.u0.bits_0.pairDStatus + + + + [6:4] + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair C + 010= Connected to Pair B + 001= Connected to Pair A + 000= OK + + Notes: + This register summarizes the worst impairment on Pair D. */ + unsigned int pairDStatus : 3; /* 1E.C800.2:0 RO */ + /* [6:4] + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair C + 010= Connected to Pair B + 001= Connected to Pair A + 000= OK */ + unsigned int reserved3 : 1; + /*! \brief 1E.C800.6:4 RO Pair C Status [2:0] + AQ_GlobalCableDiagnosticStatus_HHD.u0.bits_0.pairCStatus + + + + [9:7] + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair B + 010= Connected to Pair A + 001= Connected to Pair D + 000= OK + + Notes: + This register summarizes the worst impairment on Pair C. */ + unsigned int pairCStatus : 3; /* 1E.C800.6:4 RO */ + /* [9:7] + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair B + 010= Connected to Pair A + 001= Connected to Pair D + 000= OK */ + unsigned int reserved2 : 1; + /*! \brief 1E.C800.A:8 RO Pair B Status [2:0] + AQ_GlobalCableDiagnosticStatus_HHD.u0.bits_0.pairBStatus + + + + [C:A] + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair A + 010= Connected to Pair D + 001= Connected to Pair C + 000= OK + + Notes: + This register summarizes the worst impairment on Pair B. */ + unsigned int pairBStatus : 3; /* 1E.C800.A:8 RO */ + /* [C:A] + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair A + 010= Connected to Pair D + 001= Connected to Pair C + 000= OK */ + unsigned int reserved1 : 1; + /*! \brief 1E.C800.E:C RO Pair A Status [2:0] + AQ_GlobalCableDiagnosticStatus_HHD.u0.bits_0.pairAStatus + + + + [F:D] + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair D + 010= Connected to Pair C + 001= Connected to Pair B + 000= OK + + Notes: + This register summarizes the worst impairment on Pair A. */ + unsigned int pairAStatus : 3; /* 1E.C800.E:C RO */ + /* [F:D] + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair D + 010= Connected to Pair C + 001= Connected to Pair B + 000= OK */ + unsigned int reserved0 : 1; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C801.7:0 RO Pair A Reflection #2 [7:0] + AQ_GlobalCableDiagnosticStatus_HHD.u1.bits_1.pairAReflection_2 + + + + The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair A + + Notes: + The distance to this reflection is given in See Global Reserved Status 1: Address 1E.C870 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairAReflection_2 : 8; /* 1E.C801.7:0 RO */ + /* The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair A */ + /*! \brief 1E.C801.F:8 RO Pair A Reflection #1 [7:0] + AQ_GlobalCableDiagnosticStatus_HHD.u1.bits_1.pairAReflection_1 + + + + The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair A + + Notes: + The distance to this reflection is given in See Global Reserved Status 1: Address 1E.C870 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairAReflection_1 : 8; /* 1E.C801.F:8 RO */ + /* The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair A */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C802.F:0 RO Impulse Response MSW [F:0] + AQ_GlobalCableDiagnosticStatus_HHD.u2.bits_2.impulseResponseMSW + + + + The MSW of the memory location that contains the start of the impulse response data for the Extended Diagnostic type in 1E.C470.E:D + + Notes: + See 1E.C470 for more information */ + unsigned int impulseResponseMSW : 16; /* 1E.C802.F:0 RO */ + /* The MSW of the memory location that contains the start of the impulse response data for the Extended Diagnostic type in 1E.C470.E:D */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C803.7:0 RO Pair B Reflection #2 [7:0] + AQ_GlobalCableDiagnosticStatus_HHD.u3.bits_3.pairBReflection_2 + + + + The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair B + + Notes: + The distance to this reflection is given in See Global Reserved Status 2: Address 1E.C871 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairBReflection_2 : 8; /* 1E.C803.7:0 RO */ + /* The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair B */ + /*! \brief 1E.C803.F:8 RO Pair B Reflection #1 [7:0] + AQ_GlobalCableDiagnosticStatus_HHD.u3.bits_3.pairBReflection_1 + + + + The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair B + + Notes: + The distance to this reflection is given in See Global Reserved Status 2: Address 1E.C871 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairBReflection_1 : 8; /* 1E.C803.F:8 RO */ + /* The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair B */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C804.F:0 RO Impulse Response LSW [F:0] + AQ_GlobalCableDiagnosticStatus_HHD.u4.bits_4.impulseResponseLSW + + + + The LSW of the memory location that contains the start of the impulse response data for the Extended Diagnostic type specified in 1E.C470.E:D + + Notes: + See 1E.C470 for more information */ + unsigned int impulseResponseLSW : 16; /* 1E.C804.F:0 RO */ + /* The LSW of the memory location that contains the start of the impulse response data for the Extended Diagnostic type specified in 1E.C470.E:D */ + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C805.7:0 RO Pair C Reflection #2 [7:0] + AQ_GlobalCableDiagnosticStatus_HHD.u5.bits_5.pairCReflection_2 + + + + The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair C + + Notes: + The distance to this reflection is given in See Global Reserved Status 3: Address 1E.C872 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairCReflection_2 : 8; /* 1E.C805.7:0 RO */ + /* The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair C */ + /*! \brief 1E.C805.F:8 RO Pair C Reflection #1 [7:0] + AQ_GlobalCableDiagnosticStatus_HHD.u5.bits_5.pairCReflection_1 + + + + The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair C + + Notes: + The distance to this reflection is given in See Global Reserved Status 3: Address 1E.C872 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairCReflection_1 : 8; /* 1E.C805.F:8 RO */ + /* The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair C */ + } bits_5; + uint16_t word_5; + } u5; + /*! \brief Union for bit and word level access of word 6 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C806.F:0 RO Reserved 1 [F:0] + AQ_GlobalCableDiagnosticStatus_HHD.u6.bits_6.reserved_1 + + + + Reserved for future use + */ + unsigned int reserved_1 : 16; /* 1E.C806.F:0 RO */ + /* Reserved for future use */ + } bits_6; + uint16_t word_6; + } u6; + /*! \brief Union for bit and word level access of word 7 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C807.7:0 RO Pair D Reflection #2 [7:0] + AQ_GlobalCableDiagnosticStatus_HHD.u7.bits_7.pairDReflection_2 + + + + The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair D + + Notes: + The distance to this reflection is given in See Global Reserved Status 4: Address 1E.C873 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairDReflection_2 : 8; /* 1E.C807.7:0 RO */ + /* The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair D */ + /*! \brief 1E.C807.F:8 RO Pair D Reflection #1 [7:0] + AQ_GlobalCableDiagnosticStatus_HHD.u7.bits_7.pairDReflection_1 + + + + The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair D + + Notes: + The distance to this reflection is given in See Global Reserved Status 4: Address 1E.C873 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairDReflection_1 : 8; /* 1E.C807.F:8 RO */ + /* The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair D */ + } bits_7; + uint16_t word_7; + } u7; +} AQ_GlobalCableDiagnosticStatus_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Thermal Status: 1E.C820 */ +/* Global Thermal Status: 1E.C820 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Thermal Status */ + union + { + struct + { + /*! \brief 1E.C820.F:0 RO Temperature [F:0] + AQ_GlobalThermalStatus_HHD.u0.bits_0.temperature + + + + [F:0] of temperature + + + Notes: + 2's complement value with the LSB representing 1/256 of a degree Celsius. This corresponds to -40 degreesC = 0xD800. Default is 70 degreesC. This is a mirror of the XENPAK register 1.A060 - 1.A061. The mirror is performed in H/W. */ + unsigned int temperature : 16; /* 1E.C820.F:0 RO */ + /* [F:0] of temperature + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Thermal Status */ + union + { + struct + { + /*! \brief 1E.C821.0 RO Temperature Ready + AQ_GlobalThermalStatus_HHD.u1.bits_1.temperatureReady + + + + 1 = Temperature measurement is valid + + + Notes: + This is a mirror of the XENPAK register 1.A06E. */ + unsigned int temperatureReady : 1; /* 1E.C821.0 RO */ + /* 1 = Temperature measurement is valid + */ + unsigned int reserved0 : 15; + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalThermalStatus_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global General Status: 1E.C830 */ +/* Global General Status: 1E.C830 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global General Status */ + union + { + struct + { + unsigned int reserved1 : 11; + /*! \brief 1E.C830.B RO Low Temperature Warning State + AQ_GlobalGeneralStatus_HHD.u0.bits_0.lowTemperatureWarningState + + + + 1 = Low temperature warning threshold has been exceeded + + Notes: + In XENPAK mode, F/W will copy this register to the 1.A074.6 register. + + */ + unsigned int lowTemperatureWarningState : 1; /* 1E.C830.B RO */ + /* 1 = Low temperature warning threshold has been exceeded */ + /*! \brief 1E.C830.C RO High Temperature Warning State + AQ_GlobalGeneralStatus_HHD.u0.bits_0.highTemperatureWarningState + + + + 1 = High temperature warning threshold has been exceeded + + Notes: + In XENPAK mode, F/W will copy this register to the 1.A074.7 register. + + */ + unsigned int highTemperatureWarningState : 1; /* 1E.C830.C RO */ + /* 1 = High temperature warning threshold has been exceeded */ + /*! \brief 1E.C830.D RO Low Temperature Failure State + AQ_GlobalGeneralStatus_HHD.u0.bits_0.lowTemperatureFailureState + + + + 1 = Low temperature failure threshold has been exceeded + + Notes: + In XENPAK mode, F/W will copy this register to the 1.A070.6 register. + + */ + unsigned int lowTemperatureFailureState : 1; /* 1E.C830.D RO */ + /* 1 = Low temperature failure threshold has been exceeded */ + /*! \brief 1E.C830.E RO High Temperature Failure State + AQ_GlobalGeneralStatus_HHD.u0.bits_0.highTemperatureFailureState + + + + 1 = High temperature failure threshold has been exceeded + + Notes: + In XENPAK mode, F/W will copy this register to the 1.A070.7 register. + + */ + unsigned int highTemperatureFailureState : 1; /* 1E.C830.E RO */ + /* 1 = High temperature failure threshold has been exceeded */ + unsigned int reserved0 : 1; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global General Status */ + union + { + struct + { + unsigned int reserved0 : 15; + /*! \brief 1E.C831.F RO Processor Intensive MDIO Operation In- Progress + AQ_GlobalGeneralStatus_HHD.u1.bits_1.processorIntensiveMdioOperationIn_Progress + + + + 1 = PHY microprocessor is busy with a processor-intensive MDIO operation + 0 = Processor-intensive MDIO operation completed + + + Notes: + This bit should may be used with certain processor-intensive MDIO commands (such as Loopbacks, Test Modes, Low power modes, Tx-Disable, Restart autonegotiation, Cable Diagnostics, etc.) that take longer than an MDIO cycle to complete. Upon receiving an MDIO command that involves the PHY's microprocessor, this bit is set, and when the command is completed, this bit is cleared. + + NOTE!!! This bit should be checked only after 1 ms of issuing a processor-intensive MDIO operation. + + The list of operations that set this bit are as follows: + + 1.0.0, PMA Loopback + 1.0.B, Low power mode + 1.9.4:0, Tx Disable + 1.84, 10G Test modes + 1.8000.5, XENPAK Control + 1.9000, XENPAK Rx Fault Enable + 1.9002, XENPAK Alarm Enable + 1.E400.F, External loopback + 3.0.B, Low power mode + 3.0.E, System PCS loopback + 3.C471.5, PRBS Test + 3.C471.6, PRBS Test + 3.E471.5, PRBS Test + 3.E471.6, PRBS Test + 4.0.B, Low power mode + 4.0.E, PHY-XS network loopback + 4.C440, Output clock control, Load SERDES parameters + 4.F802.E, System loopback + 4.C444.F:B, Loopback Control + 4.C444.4:2, Packet generation + 4.C445.C, SERDES calibration + 7.0.9, Restart autonegotiation + 1D.C280, 1G/100M Network loopback + 1D.C500, 1G System loopback + 1D.C501, 1G / 100M Test modes + 1E.C470.4, Cable diagnostics + 1E.C47A.F:B, Loopback Control + 1E.C47A.4:2, Packet generation */ + unsigned int processorIntensiveMdioOperationIn_Progress : 1; /* 1E.C831.F RO */ + /* 1 = PHY microprocessor is busy with a processor-intensive MDIO operation + 0 = Processor-intensive MDIO operation completed + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalGeneralStatus_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Pin Status: 1E.C840 */ +/* Global Pin Status: 1E.C840 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Pin Status */ + union + { + struct + { + /*! \brief 1E.C840.5:0 RO LED Pullup State [5:0] + AQ_GlobalPinStatus_HHD.u0.bits_0.ledPullupState + + + + 1 = LED output pin is pulled high + 0 = LED output pin is pulled low + + */ + unsigned int ledPullupState : 6; /* 1E.C840.5:0 RO */ + /* 1 = LED output pin is pulled high + 0 = LED output pin is pulled low + */ + unsigned int reserved4 : 1; + /*! \brief 1E.C840.7 RO Tx Enable + AQ_GlobalPinStatus_HHD.u0.bits_0.txEnable + + + + Current Value of Tx Enable pin + + + Notes: + 0 = Disable Transmitter */ + unsigned int txEnable : 1; /* 1E.C840.7 RO */ + /* Current Value of Tx Enable pin + */ + unsigned int reserved3 : 1; + /*! \brief 1E.C840.9 RO Package Connectivity + AQ_GlobalPinStatus_HHD.u0.bits_0.packageConnectivity + + + + Value of the package connection pin + + */ + unsigned int packageConnectivity : 1; /* 1E.C840.9 RO */ + /* Value of the package connection pin + */ + unsigned int reserved2 : 3; + /*! \brief 1E.C840.D RO DC_MASTER_N + AQ_GlobalPinStatus_HHD.u0.bits_0.dcMasterN + + + + Value of DC_MASTER_N pin: + + 0x1 = PHY Slave Daisy Chain Boot + 0x0 = PHY Master Daisy Chain Boot from FLASH + */ + unsigned int dcMasterN : 1; /* 1E.C840.D RO */ + /* Value of DC_MASTER_N pin: + + 0x1 = PHY Slave Daisy Chain Boot + 0x0 = PHY Master Daisy Chain Boot from FLASH */ + unsigned int reserved1 : 1; + unsigned int reserved0 : 1; + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalPinStatus_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Daisy Chain Status: 1E.C842 */ +/* Global Daisy Chain Status: 1E.C842 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Daisy Chain Status */ + union + { + struct + { + /*! \brief 1E.C842.F:0 RO Rx Daisy Chain Calculated CRC [F:0] + AQ_GlobalDaisyChainStatus_HHD.u0.bits_0.rxDaisyChainCalculatedCrc + + + + Rx Daisy Chain Calculated CRC + + + Notes: + This is the calculated daisy chain CRC. */ + unsigned int rxDaisyChainCalculatedCrc : 16; /* 1E.C842.F:0 RO */ + /* Rx Daisy Chain Calculated CRC + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalDaisyChainStatus_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Fault Message: 1E.C850 */ +/* Global Fault Message: 1E.C850 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Fault Message */ + union + { + struct + { + /*! \brief 1E.C850.F:0 RO Message [F:0] + AQ_GlobalFaultMessage_HHD.u0.bits_0.message + + + + Error code describing fault + + Notes: + Code 0x8001: Firmware not compatible with chip architecture. This fault occurs when firmware compiled for a different microprocessor core is loaded. + Code 0x8002: VCO calibration failed. This occurs when the main PLLs on chip fail to lock: this is not possible to trigger. + Code 0x8003: XAUI calibration failed. This occurs when the XAUI PLLs fail to lock: this is not possible to trigger. + Code 0x8005: Unexpected device ID. This occurs if the device ID programmed into the internal E-Fuse registers in not valid: this is not possible to trigger. + Code 0x8006: Computed checksum does not match expected checksum. This occurs when the FLASH checksum check performed at boot time fails. This only occurs when the system boots from FLASH. + Code 0x8007: Detected a bit error in static memory. To trigger, corrupt one of the static regions. + Code 0xC001: Illegal Instruction exception. This occurs when the processor attempts to execute an illegal instruction. To trigger this, write an illegal instruction to program memory. It's possible that the bit error check will trigger before the illegal instruction is executed. + Code 0xC002 Instruction Fetch Error. Internal physical address or a data error during instruction fetch: this is not possible to trigger. + Code 0xC003 Load Store Error. Internal physical address or data error during load store operation: this is not possible to trigger.. + Code 0xC004 Privileged Instruction. Attempt to execute a privileged operation without sufficient privilege: this is not possible to trigger. + Code 0xC005 Unaligned Load or Store. Attempt to load or store data at an address which cannot be handled due to alignment: this is not possible to trigger. + Code 0xC006 Instruction fetch from prohibited space: this is not possible to trigger. + Code 0xC007 Data load from prohibited space: this is not possible to trigger. + Code 0xC008 Data store into prohibited space: this is not possible to trigger. */ + unsigned int message : 16; /* 1E.C850.F:0 RO */ + /* Error code describing fault */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalFaultMessage_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Cable Diagnostic Impedance: 1E.C880 */ +/* Global Cable Diagnostic Impedance: 1E.C880 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Cable Diagnostic Impedance */ + union + { + struct + { + /*! \brief 1E.C880.2:0 RO Pair A Reflection #4 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u0.bits_0.pairAReflection_4 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the fourth worst reflection on Pair A. The corresponding length of this reflection from the PHY is given in See Global Power Control - Address 1E.21 */ + unsigned int pairAReflection_4 : 3; /* 1E.C880.2:0 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C880.3 RO Reserved 4 + AQ_GlobalCableDiagnosticImpedance_HHD.u0.bits_0.reserved_4 + + + + Reserved + + */ + unsigned int reserved_4 : 1; /* 1E.C880.3 RO */ + /* Reserved + */ + /*! \brief 1E.C880.6:4 RO Pair A Reflection #3 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u0.bits_0.pairAReflection_3 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the third worst reflection on Pair A. The corresponding length of this reflection from the PHY is given in See Global Power Control - Address 1E.21 */ + unsigned int pairAReflection_3 : 3; /* 1E.C880.6:4 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C880.7 RO Reserved 3 + AQ_GlobalCableDiagnosticImpedance_HHD.u0.bits_0.reserved_3 + + + + Reserved + + */ + unsigned int reserved_3 : 1; /* 1E.C880.7 RO */ + /* Reserved + */ + /*! \brief 1E.C880.A:8 RO Pair A Reflection #2 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u0.bits_0.pairAReflection_2 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the second worst reflection on Pair A. The corresponding length of this reflection from the PHY is given in See Global Power Control - Address 1E.21 */ + unsigned int pairAReflection_2 : 3; /* 1E.C880.A:8 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C880.B RO Reserved 2 + AQ_GlobalCableDiagnosticImpedance_HHD.u0.bits_0.reserved_2 + + + + Reserved + + */ + unsigned int reserved_2 : 1; /* 1E.C880.B RO */ + /* Reserved + */ + /*! \brief 1E.C880.E:C RO Pair A Reflection #1 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u0.bits_0.pairAReflection_1 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the first worst reflection on Pair A. The corresponding length of this reflection from the PHY is given in See Global Power Control - Address 1E.21 */ + unsigned int pairAReflection_1 : 3; /* 1E.C880.E:C RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C880.F RO Reserved 1 + AQ_GlobalCableDiagnosticImpedance_HHD.u0.bits_0.reserved_1 + + + + Reserved + + */ + unsigned int reserved_1 : 1; /* 1E.C880.F RO */ + /* Reserved + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Cable Diagnostic Impedance */ + union + { + struct + { + /*! \brief 1E.C881.2:0 RO Pair B Reflection #4 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u1.bits_1.pairBReflection_4 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the fourth worst reflection on Pair B. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 2 - Address 1E.32 - 1E.33 */ + unsigned int pairBReflection_4 : 3; /* 1E.C881.2:0 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C881.3 RO Reserved 8 + AQ_GlobalCableDiagnosticImpedance_HHD.u1.bits_1.reserved_8 + + + + Reserved + + */ + unsigned int reserved_8 : 1; /* 1E.C881.3 RO */ + /* Reserved + */ + /*! \brief 1E.C881.6:4 RO Pair B Reflection #3 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u1.bits_1.pairBReflection_3 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the third worst reflection on Pair B. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 2 - Address 1E.32 - 1E.33 */ + unsigned int pairBReflection_3 : 3; /* 1E.C881.6:4 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C881.7 RO Reserved 7 + AQ_GlobalCableDiagnosticImpedance_HHD.u1.bits_1.reserved_7 + + + + Reserved + + */ + unsigned int reserved_7 : 1; /* 1E.C881.7 RO */ + /* Reserved + */ + /*! \brief 1E.C881.A:8 RO Pair B Reflection #2 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u1.bits_1.pairBReflection_2 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the second worst reflection on Pair B. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 2 - Address 1E.32 - 1E.33 */ + unsigned int pairBReflection_2 : 3; /* 1E.C881.A:8 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C881.B RO Reserved 6 + AQ_GlobalCableDiagnosticImpedance_HHD.u1.bits_1.reserved_6 + + + + Reserved + + */ + unsigned int reserved_6 : 1; /* 1E.C881.B RO */ + /* Reserved + */ + /*! \brief 1E.C881.E:C RO Pair B Reflection #1 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u1.bits_1.pairBReflection_1 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the first worst reflection on Pair B. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 2 - Address 1E.32 - 1E.33 */ + unsigned int pairBReflection_1 : 3; /* 1E.C881.E:C RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C881.F RO Reserved 5 + AQ_GlobalCableDiagnosticImpedance_HHD.u1.bits_1.reserved_5 + + + + Reserved + + */ + unsigned int reserved_5 : 1; /* 1E.C881.F RO */ + /* Reserved + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Cable Diagnostic Impedance */ + union + { + struct + { + /*! \brief 1E.C882.2:0 RO Pair C Reflection #4 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u2.bits_2.pairCReflection_4 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the fourth worst reflection on Pair C. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.33 */ + unsigned int pairCReflection_4 : 3; /* 1E.C882.2:0 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C882.3 RO Reserved 12 + AQ_GlobalCableDiagnosticImpedance_HHD.u2.bits_2.reserved_12 + + + + Reserved + + */ + unsigned int reserved_12 : 1; /* 1E.C882.3 RO */ + /* Reserved + */ + /*! \brief 1E.C882.6:4 RO Pair C Reflection #3 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u2.bits_2.pairCReflection_3 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the third worst reflection on Pair C. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.33 */ + unsigned int pairCReflection_3 : 3; /* 1E.C882.6:4 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C882.7 RO Reserved 11 + AQ_GlobalCableDiagnosticImpedance_HHD.u2.bits_2.reserved_11 + + + + Reserved + + */ + unsigned int reserved_11 : 1; /* 1E.C882.7 RO */ + /* Reserved + */ + /*! \brief 1E.C882.A:8 RO Pair C Reflection #2 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u2.bits_2.pairCReflection_2 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the second worst reflection on Pair C. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.33 */ + unsigned int pairCReflection_2 : 3; /* 1E.C882.A:8 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C882.B RO Reserved 10 + AQ_GlobalCableDiagnosticImpedance_HHD.u2.bits_2.reserved_10 + + + + Reserved + + */ + unsigned int reserved_10 : 1; /* 1E.C882.B RO */ + /* Reserved + */ + /*! \brief 1E.C882.E:C RO Pair C Reflection #1 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u2.bits_2.pairCReflection_1 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the first worst reflection on Pair C. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.33 */ + unsigned int pairCReflection_1 : 3; /* 1E.C882.E:C RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C882.F RO Reserved 9 + AQ_GlobalCableDiagnosticImpedance_HHD.u2.bits_2.reserved_9 + + + + Reserved + + */ + unsigned int reserved_9 : 1; /* 1E.C882.F RO */ + /* Reserved + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global Cable Diagnostic Impedance */ + union + { + struct + { + /*! \brief 1E.C883.2:0 RO Pair D Reflection #4 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u3.bits_3.pairDReflection_4 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the fourth worst reflection on Pair D. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.34 - 1E.35 */ + unsigned int pairDReflection_4 : 3; /* 1E.C883.2:0 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C883.3 RO Reserved 16 + AQ_GlobalCableDiagnosticImpedance_HHD.u3.bits_3.reserved_16 + + + + Reserved + + */ + unsigned int reserved_16 : 1; /* 1E.C883.3 RO */ + /* Reserved + */ + /*! \brief 1E.C883.6:4 RO Pair D Reflection #3 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u3.bits_3.pairDReflection_3 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the third worst reflection on Pair D. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.34 - 1E.35 */ + unsigned int pairDReflection_3 : 3; /* 1E.C883.6:4 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C883.7 RO Reserved 15 + AQ_GlobalCableDiagnosticImpedance_HHD.u3.bits_3.reserved_15 + + + + Reserved + + */ + unsigned int reserved_15 : 1; /* 1E.C883.7 RO */ + /* Reserved + */ + /*! \brief 1E.C883.A:8 RO Pair D Reflection #2 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u3.bits_3.pairDReflection_2 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the second worst reflection on Pair D. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.34 - 1E.35 */ + unsigned int pairDReflection_2 : 3; /* 1E.C883.A:8 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C883.B RO Reserved 14 + AQ_GlobalCableDiagnosticImpedance_HHD.u3.bits_3.reserved_14 + + + + Reserved + + */ + unsigned int reserved_14 : 1; /* 1E.C883.B RO */ + /* Reserved + */ + /*! \brief 1E.C883.E:C RO Pair D Reflection #1 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u3.bits_3.pairDReflection_1 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the first worst reflection on Pair D. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.34 - 1E.35 */ + unsigned int pairDReflection_1 : 3; /* 1E.C883.E:C RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C883.F RO Reserved 13 + AQ_GlobalCableDiagnosticImpedance_HHD.u3.bits_3.reserved_13 + + + + Reserved + + */ + unsigned int reserved_13 : 1; /* 1E.C883.F RO */ + /* Reserved + */ + } bits_3; + uint16_t word_3; + } u3; +} AQ_GlobalCableDiagnosticImpedance_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Status: 1E.C884 */ +/* Global Status: 1E.C884 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Status */ + union + { + struct + { + /*! \brief 1E.C884.7:0 RO Cable Length [7:0] + AQ_GlobalStatus_HHD.u0.bits_0.cableLength + + + + The estimated length of the cable in meters + + + Notes: + The length of the cable shown here is estimated from the cable diagnostic engine and should be accurate to +/-1m. */ + unsigned int cableLength : 8; /* 1E.C884.7:0 RO */ + /* The estimated length of the cable in meters + */ + /*! \brief 1E.C884.F:8 RO Reserved Status 0 [7:0] + AQ_GlobalStatus_HHD.u0.bits_0.reservedStatus_0 + + + + Reserved + + */ + unsigned int reservedStatus_0 : 8; /* 1E.C884.F:8 RO */ + /* Reserved + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalStatus_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Reserved Status: 1E.C885 */ +/* Global Reserved Status: 1E.C885 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Reserved Status */ + union + { + struct + { + /*! \brief 1E.C885.3:0 ROSPD Provisioning ID [3:0] + AQ_GlobalReservedStatus_HHD.u0.bits_0.provisioningID + + Provisionable Default = 0x0 + + Provisioning ID + + + Notes: + Customers may receive multiple ROM images that differ only in their provisioning. This field is used to differentiate those images. This field is used in conjunction with the firmware major and minor revision numbers to uniquely identify ROM images. */ + unsigned int provisioningID : 4; /* 1E.C885.3:0 ROSPD Provisionable Default = 0x0 */ + /* Provisioning ID + */ + /*! \brief 1E.C885.7:4 ROSPD Firmware Build ID [3:0] + AQ_GlobalReservedStatus_HHD.u0.bits_0.firmwareBuildID + + Provisionable Default = 0x0 + + Firmware Build ID + + + Notes: + Customers may receive multiple ROM images that differ only in their provisioning. This field is used to differentiate those images. This field is used in conjunction with the firmware major and minor revision numbers to uniquely identify ROM images. */ + unsigned int firmwareBuildID : 4; /* 1E.C885.7:4 ROSPD Provisionable Default = 0x0 */ + /* Firmware Build ID + */ + /*! \brief 1E.C885.9:8 ROSPD XENPAK NVR Status [1:0] + AQ_GlobalReservedStatus_HHD.u0.bits_0.xenpakNvrStatus + + Provisionable Default = 0x0 + + Status of XENPAK NVR: + 0: NVR not enabled + 1: Last NVR operation succeeded + 2: Last NVR operation failed + 3: Reserved + + + Notes: + XENPAK register space is mirrored in NVR (SPI ROM). This register indicates the status of the last NVR operation. */ + unsigned int xenpakNvrStatus : 2; /* 1E.C885.9:8 ROSPD Provisionable Default = 0x0 */ + /* Status of XENPAK NVR: + 0: NVR not enabled + 1: Last NVR operation succeeded + 2: Last NVR operation failed + 3: Reserved + */ + /*! \brief 1E.C885.F:A RO Nearly Seconds MSW[5:0] + AQ_GlobalReservedStatus_HHD.u0.bits_0.nearlySecondsMSW + + + + Bits 16 to 21 of the 22 bit "Nearly Seconds" uptime counter. + + + Notes: + The "Nearly Seconds" counter is incremented every 1024 milliseconds. */ + unsigned int nearlySecondsMSW : 6; /* 1E.C885.F:A RO */ + /* Bits 16 to 21 of the 22 bit "Nearly Seconds" uptime counter. + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Reserved Status */ + union + { + struct + { + /*! \brief 1E.C886.F:0 RO Nearly Seconds LSW [F:0] + AQ_GlobalReservedStatus_HHD.u1.bits_1.nearlySecondsLSW + + + + Bits 0 to 15 of the 22 bit "Nearly Seconds" uptime counter + + + Notes: + The "Nearly Seconds" counter is incremented every 1024 milliseconds. */ + unsigned int nearlySecondsLSW : 16; /* 1E.C886.F:0 RO */ + /* Bits 0 to 15 of the 22 bit "Nearly Seconds" uptime counter + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Reserved Status */ + union + { + struct + { + /*! \brief 1E.C887.D:0 RO Reserved Status 3 [D:0] + AQ_GlobalReservedStatus_HHD.u2.bits_2.reservedStatus_3 + + + + Reserved for future use + + */ + unsigned int reservedStatus_3 : 14; /* 1E.C887.D:0 RO */ + /* Reserved for future use + */ + /*! \brief 1E.C887.E ROS Power Up Stall Status + AQ_GlobalReservedStatus_HHD.u2.bits_2.powerUpStallStatus + + Default = 0x0 + + 1 = FW is stalled at power up + 0 = Firmware is unstalled + + */ + unsigned int powerUpStallStatus : 1; /* 1E.C887.E ROS Default = 0x0 */ + /* 1 = FW is stalled at power up + 0 = Firmware is unstalled + */ + /*! \brief 1E.C887.F ROS DTE Status + AQ_GlobalReservedStatus_HHD.u2.bits_2.dteStatus + + Default = 0x0 + + 1 = Need power + 0 = Don't need power + + */ + unsigned int dteStatus : 1; /* 1E.C887.F ROS Default = 0x0 */ + /* 1 = Need power + 0 = Don't need power + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global Reserved Status */ + union + { + struct + { + /*! \brief 1E.C888.1:0 RO Rate [1:0] + AQ_GlobalReservedStatus_HHD.u3.bits_3.rate + + Default = 0x0 + + 0x3 = 10G + 0x2 = 1G + 0x1 = 100M + 0x0 = invalid + + + Notes: + These bits report the selected rate for the loopback and packet generation. */ + unsigned int rate : 2; /* 1E.C888.1:0 RO Default = 0x0 */ + /* 0x3 = 10G + 0x2 = 1G + 0x1 = 100M + 0x0 = invalid + */ + /*! \brief 1E.C888.2 RO Reserved Status 4a + AQ_GlobalReservedStatus_HHD.u3.bits_3.reservedStatus_4a + + Default = 0x0 + + Reserved for future use + + */ + unsigned int reservedStatus_4a : 1; /* 1E.C888.2 RO Default = 0x0 */ + /* Reserved for future use + */ + /*! \brief 1E.C888.3 RO System I/F Packet Generation Status + AQ_GlobalReservedStatus_HHD.u3.bits_3.systemI_fPacketGenerationStatus + + Default = 0x0 + + 1 = CRPAT packet generation out 10G system interface + 0 = No CRPAT packet generation out 10G system interface + + + Notes: + Reports whether the CRPAT packet generator in the PHY outputs on the selected system interface at the selected rate. */ + unsigned int systemI_fPacketGenerationStatus : 1; /* 1E.C888.3 RO Default = 0x0 */ + /* 1 = CRPAT packet generation out 10G system interface + 0 = No CRPAT packet generation out 10G system interface + */ + /*! \brief 1E.C888.4 RO Look-Aside Port Packet Generation Status + AQ_GlobalReservedStatus_HHD.u3.bits_3.look_asidePortPacketGenerationStatus + + Default = 0x0 + + 1 = CRPAT packet generation out 10G look-aside interface (KR0) + 0 = No CRPAT packet generation out 10G look-aside interface (KR0) + + + Notes: + Reports whether the CRPAT packet generator in the PHY outputs on the KR0 interface at the selected rate. */ + unsigned int look_asidePortPacketGenerationStatus : 1; /* 1E.C888.4 RO Default = 0x0 */ + /* 1 = CRPAT packet generation out 10G look-aside interface (KR0) + 0 = No CRPAT packet generation out 10G look-aside interface (KR0) + */ + /*! \brief 1E.C888.5 RO MDI Packet Generation Status + AQ_GlobalReservedStatus_HHD.u3.bits_3.mdiPacketGenerationStatus + + Default = 0x0 + + 1 = CRPAT packet generation out MDI interface + 0 = No CRPAT packet generation out MDI interface + + + Notes: + Reports whether the CRPAT packet generator in the PHY outputs on the MDI interface at the selected rate. */ + unsigned int mdiPacketGenerationStatus : 1; /* 1E.C888.5 RO Default = 0x0 */ + /* 1 = CRPAT packet generation out MDI interface + 0 = No CRPAT packet generation out MDI interface + */ + /*! \brief 1E.C888.A:6 RO Reserved Status 4 [4:0] + AQ_GlobalReservedStatus_HHD.u3.bits_3.reservedStatus_4 + + Default = 0x00 + + Reserved for future use + + */ + unsigned int reservedStatus_4 : 5; /* 1E.C888.A:6 RO Default = 0x00 */ + /* Reserved for future use + */ + /*! \brief 1E.C888.F:B RO Loopback Status [4:0] + AQ_GlobalReservedStatus_HHD.u3.bits_3.loopbackStatus + + Default = 0x00 + + 0x00 = No loopback + 0x01 = System Interface - System Loopback + 0x02 = System Interface - System Loopback with Passthrough + 0x03 = System Interface - Network Loopback + 0x04 = System Interface - Network Loopback with Passthrough + 0x05 = System Interface - Network Loopback with Passthrough and Merge + 0x06 = System Interface - Peer-to-peer loopback + 0x07 - 0x08 = Reserved + 0x09 = Network Interface - System Loopback + 0x0A = Network Interface - System Loopback with Passthrough + 0x0B = Network Interface - Network Loopback + 0x0C = Network Interface - Network Loopback with Passthrough + 0x0D = Network Interface - Peer-to-peer loopback + 0x0E - 0x0F = Reserved + 0x10 = Cross-connect System Loopback + 0x11 = Cross-connect Network Loopback + 0x12 - 0x13 = Reserved + 0x14 = Network Interface - System Loopback via Loopback Plug + 0x15 - 0x1F = Reserved + + + Notes: + These bits, in conjunction with the chip configuration and the rate (Bits 1:0), report the selected loopback. + + */ + unsigned int loopbackStatus : 5; /* 1E.C888.F:B RO Default = 0x00 */ + /* 0x00 = No loopback + 0x01 = System Interface - System Loopback + 0x02 = System Interface - System Loopback with Passthrough + 0x03 = System Interface - Network Loopback + 0x04 = System Interface - Network Loopback with Passthrough + 0x05 = System Interface - Network Loopback with Passthrough and Merge + 0x06 = System Interface - Peer-to-peer loopback + 0x07 - 0x08 = Reserved + 0x09 = Network Interface - System Loopback + 0x0A = Network Interface - System Loopback with Passthrough + 0x0B = Network Interface - Network Loopback + 0x0C = Network Interface - Network Loopback with Passthrough + 0x0D = Network Interface - Peer-to-peer loopback + 0x0E - 0x0F = Reserved + 0x10 = Cross-connect System Loopback + 0x11 = Cross-connect Network Loopback + 0x12 - 0x13 = Reserved + 0x14 = Network Interface - System Loopback via Loopback Plug + 0x15 - 0x1F = Reserved + */ + } bits_3; + uint16_t word_3; + } u3; +} AQ_GlobalReservedStatus_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Alarms: 1E.CC00 */ +/* Global Alarms: 1E.CC00 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Alarms */ + union + { + struct + { + /*! \brief 1E.CC00.0 LH Reserved Alarm D + AQ_GlobalAlarms_HHD.u0.bits_0.reservedAlarmD + + + + Reserved for future use + + */ + unsigned int reservedAlarmD : 1; /* 1E.CC00.0 LH */ + /* Reserved for future use + */ + /*! \brief 1E.CC00.1 LH Reserved Alarm C + AQ_GlobalAlarms_HHD.u0.bits_0.reservedAlarmC + + + + Reserved for future use + + */ + unsigned int reservedAlarmC : 1; /* 1E.CC00.1 LH */ + /* Reserved for future use + */ + /*! \brief 1E.CC00.2 LH Reserved Alarm B + AQ_GlobalAlarms_HHD.u0.bits_0.reservedAlarmB + + + + Reserved for future use + + */ + unsigned int reservedAlarmB : 1; /* 1E.CC00.2 LH */ + /* Reserved for future use + */ + /*! \brief 1E.CC00.3 LH Reserved Alarm A + AQ_GlobalAlarms_HHD.u0.bits_0.reservedAlarmA + + + + Reserved for future use + + */ + unsigned int reservedAlarmA : 1; /* 1E.CC00.3 LH */ + /* Reserved for future use + */ + /*! \brief 1E.CC00.4 LH Device Fault + AQ_GlobalAlarms_HHD.u0.bits_0.deviceFault + + + + 1 = Fault + + Notes: + When set, a fault has been detected by the uP and the associated 16 bit error code is visible in See Global Configuration Fault Message: Address 1E.C850 */ + unsigned int deviceFault : 1; /* 1E.CC00.4 LH */ + /* 1 = Fault */ + unsigned int reserved2 : 1; + /*! \brief 1E.CC00.6 LH Reset completed + AQ_GlobalAlarms_HHD.u0.bits_0.resetCompleted + + + + 1 = Chip wide reset completed + + Notes: + This bit is set by the microprocessor when it has completed it's initialization sequence. This bit is mirrored in 1.CC02.0 */ + unsigned int resetCompleted : 1; /* 1E.CC00.6 LH */ + /* 1 = Chip wide reset completed */ + unsigned int reserved1 : 4; + /*! \brief 1E.CC00.B LH Low Temperature Warning + AQ_GlobalAlarms_HHD.u0.bits_0.lowTemperatureWarning + + + + 1 = Low temperature warning threshold has been exceeded + + + Notes: + + + + + These bits mirror the matching bit in 1.A070 and 1.A074. These bits are driven by Bits E:B in See Global General Status 1: Address 1E.C830 . */ + unsigned int lowTemperatureWarning : 1; /* 1E.CC00.B LH */ + /* 1 = Low temperature warning threshold has been exceeded + */ + /*! \brief 1E.CC00.C LH High Temperature Warning + AQ_GlobalAlarms_HHD.u0.bits_0.highTemperatureWarning + + + + 1 = High temperature warning threshold has been exceeded + + + Notes: + + + + + These bits mirror the matching bit in 1.A070 and 1.A074. These bits are driven by Bits E:B in See Global General Status 1: Address 1E.C830 . */ + unsigned int highTemperatureWarning : 1; /* 1E.CC00.C LH */ + /* 1 = High temperature warning threshold has been exceeded + */ + /*! \brief 1E.CC00.D LH Low Temperature Failure + AQ_GlobalAlarms_HHD.u0.bits_0.lowTemperatureFailure + + + + 1 = Low temperature failure threshold has been exceeded + + + Notes: + + + + + These bits mirror the matching bit in 1.A070 and 1.A074. These bits are driven by Bits E:B in See Global General Status 1: Address 1E.C830 . */ + unsigned int lowTemperatureFailure : 1; /* 1E.CC00.D LH */ + /* 1 = Low temperature failure threshold has been exceeded + */ + /*! \brief 1E.CC00.E LH High Temperature Failure + AQ_GlobalAlarms_HHD.u0.bits_0.highTemperatureFailure + + + + 1 = High temperature failure threshold has been exceeded + + + Notes: + + + + + These bits mirror the matching bit in 1.A070 and 1.A074. These bits are driven by Bits E:B in See Global General Status 1: Address 1E.C830 . */ + unsigned int highTemperatureFailure : 1; /* 1E.CC00.E LH */ + /* 1 = High temperature failure threshold has been exceeded + */ + unsigned int reserved0 : 1; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Alarms */ + union + { + struct + { + unsigned int reserved2 : 1; + unsigned int reserved1 : 6; + /*! \brief 1E.CC01.7 LH MDIO Command Handling Overflow + AQ_GlobalAlarms_HHD.u1.bits_1.mdioCommandHandlingOverflow + + + + 1 = PHY was issued more MDIO requests than it could service in it's request buffer + + + Notes: + Assertion of this bit means that more MDIO commands were issued than FW could handle. */ + unsigned int mdioCommandHandlingOverflow : 1; /* 1E.CC01.7 LH */ + /* 1 = PHY was issued more MDIO requests than it could service in it's request buffer + */ + /*! \brief 1E.CC01.A:8 LH Reserved Alarms [2:0] + AQ_GlobalAlarms_HHD.u1.bits_1.reservedAlarms + + + + Reserved + + + */ + unsigned int reservedAlarms : 3; /* 1E.CC01.A:8 LH */ + /* Reserved + + */ + /*! \brief 1E.CC01.B LH DTE Status Change + AQ_GlobalAlarms_HHD.u1.bits_1.dteStatusChange + + + + 1 = DTE status change + + + Notes: + Change in 1E.C887[F]. */ + unsigned int dteStatusChange : 1; /* 1E.CC01.B LH */ + /* 1 = DTE status change + */ + /*! \brief 1E.CC01.C LH IP Phone Detect + AQ_GlobalAlarms_HHD.u1.bits_1.ipPhoneDetect + + + + 1 = IP Phone Detect + + + Notes: + Assertion of this bit means that the presence of an IP Phone has been detected. */ + unsigned int ipPhoneDetect : 1; /* 1E.CC01.C LH */ + /* 1 = IP Phone Detect + */ + /*! \brief 1E.CC01.D RO XENPAK Alarm + AQ_GlobalAlarms_HHD.u1.bits_1.xenpakAlarm + + + + 1 = XENPAK Alarm + + */ + unsigned int xenpakAlarm : 1; /* 1E.CC01.D RO */ + /* 1 = XENPAK Alarm + */ + /*! \brief 1E.CC01.E LH Smart Power-Down Entered + AQ_GlobalAlarms_HHD.u1.bits_1.smartPower_downEntered + + + + 1 = Smart Power-Down State Entered + + + Notes: + When this bit is set, it indicates that the Smart Power-Down state was entered */ + unsigned int smartPower_downEntered : 1; /* 1E.CC01.E LH */ + /* 1 = Smart Power-Down State Entered + */ + unsigned int reserved0 : 1; + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Alarms */ + union + { + struct + { + /*! \brief 1E.CC02.0 LH Watchdog Timer Alarm + AQ_GlobalAlarms_HHD.u2.bits_2.watchdogTimerAlarm + + + + 1 = Watchdog timer alarm + + */ + unsigned int watchdogTimerAlarm : 1; /* 1E.CC02.0 LH */ + /* 1 = Watchdog timer alarm + */ + /*! \brief 1E.CC02.1 LH MDIO Timeout Error + AQ_GlobalAlarms_HHD.u2.bits_2.mdioTimeoutError + + + + 1 = MDIO timeout detected + + */ + unsigned int mdioTimeoutError : 1; /* 1E.CC02.1 LH */ + /* 1 = MDIO timeout detected + */ + /*! \brief 1E.CC02.2 LH MDIO MMD Error + AQ_GlobalAlarms_HHD.u2.bits_2.mdioMMD_Error + + + + 1 = Invalid MMD address detected + + */ + unsigned int mdioMMD_Error : 1; /* 1E.CC02.2 LH */ + /* 1 = Invalid MMD address detected + */ + unsigned int reserved2 : 2; + /*! \brief 1E.CC02.5 LRF Tx Enable State Change + AQ_GlobalAlarms_HHD.u2.bits_2.txEnableStateChange + + + + 1 = TX_EN pin has changed state + + */ + unsigned int txEnableStateChange : 1; /* 1E.CC02.5 LRF */ + /* 1 = TX_EN pin has changed state + */ + unsigned int reserved1 : 2; + /*! \brief 1E.CC02.9:8 LH uP IRAM Parity Error [1:0] + AQ_GlobalAlarms_HHD.u2.bits_2.upIramParityError + + + + 1 = Parity error detected in the uP IRAM + + + Notes: + Bit 0 indicates a parity error was detected in the uP IRAM but was corrected. + Bit 1 indicates a multiple parity errors were detected in the uP IRAM and could not be corrected. + The uP IRAM is protected with ECC. */ + unsigned int upIramParityError : 2; /* 1E.CC02.9:8 LH */ + /* 1 = Parity error detected in the uP IRAM + */ + /*! \brief 1E.CC02.A LH uP DRAM Parity Error + AQ_GlobalAlarms_HHD.u2.bits_2.upDramParityError + + + + 1 = Parity error detected in the uP DRAM + + */ + unsigned int upDramParityError : 1; /* 1E.CC02.A LH */ + /* 1 = Parity error detected in the uP DRAM + */ + unsigned int reserved0 : 3; + /*! \brief 1E.CC02.E LH Mailbox Operation: Complete + AQ_GlobalAlarms_HHD.u2.bits_2.mailboxOperation_Complete + + + + 1 = Mailbox operation is complete + + + Notes: + Mailbox interface is ready interrupt for registers See Global Vendor Specific Control - Address 1E.C000 - See Global Vendor Specific Provisioning 5 - Address 1E.C404 */ + unsigned int mailboxOperation_Complete : 1; /* 1E.CC02.E LH */ + /* 1 = Mailbox operation is complete + */ + /*! \brief 1E.CC02.F LH NVR Operation Complete + AQ_GlobalAlarms_HHD.u2.bits_2.nvrOperationComplete + + + + 1 = NVR operation is complete + + + Notes: + NVR interface is ready interrupt for registers See Global NVR Interface 1: Address 1E.100 - See Global NVR Provisioning Data MSW - Address 1E.17 . */ + unsigned int nvrOperationComplete : 1; /* 1E.CC02.F LH */ + /* 1 = NVR operation is complete + */ + } bits_2; + uint16_t word_2; + } u2; +} AQ_GlobalAlarms_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Interrupt Mask: 1E.D400 */ +/* Global Interrupt Mask: 1E.D400 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Interrupt Mask */ + union + { + struct + { + /*! \brief 1E.D400.0 R/WPD Reserved Alarm D Mask + AQ_GlobalInterruptMask_HHD.u0.bits_0.reservedAlarmDMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int reservedAlarmDMask : 1; /* 1E.D400.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D400.1 R/WPD Reserved Alarm C Mask + AQ_GlobalInterruptMask_HHD.u0.bits_0.reservedAlarmCMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int reservedAlarmCMask : 1; /* 1E.D400.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D400.2 R/WPD Reserved Alarm B Mask + AQ_GlobalInterruptMask_HHD.u0.bits_0.reservedAlarmBMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int reservedAlarmBMask : 1; /* 1E.D400.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D400.3 R/WPD Reserved Alarm A Mask + AQ_GlobalInterruptMask_HHD.u0.bits_0.reservedAlarmAMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int reservedAlarmAMask : 1; /* 1E.D400.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D400.4 R/WPD Device Fault Mask + AQ_GlobalInterruptMask_HHD.u0.bits_0.deviceFaultMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int deviceFaultMask : 1; /* 1E.D400.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved2 : 1; + /*! \brief 1E.D400.6 R/WPD Reset completed Mask + AQ_GlobalInterruptMask_HHD.u0.bits_0.resetCompletedMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int resetCompletedMask : 1; /* 1E.D400.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved1 : 4; + /*! \brief 1E.D400.B R/WPD Low Temperature Warning Mask + AQ_GlobalInterruptMask_HHD.u0.bits_0.lowTemperatureWarningMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int lowTemperatureWarningMask : 1; /* 1E.D400.B R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D400.C R/WPD High Temperature Warning Mask + AQ_GlobalInterruptMask_HHD.u0.bits_0.highTemperatureWarningMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int highTemperatureWarningMask : 1; /* 1E.D400.C R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D400.D R/WPD Low Temperature Failure Mask + AQ_GlobalInterruptMask_HHD.u0.bits_0.lowTemperatureFailureMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int lowTemperatureFailureMask : 1; /* 1E.D400.D R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D400.E R/WPD High Temperature Failure Mask + AQ_GlobalInterruptMask_HHD.u0.bits_0.highTemperatureFailureMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int highTemperatureFailureMask : 1; /* 1E.D400.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved0 : 1; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Interrupt Mask */ + union + { + struct + { + /*! \brief 1E.D401.0 R/WPD Diagnostic Alarm Mask + AQ_GlobalInterruptMask_HHD.u1.bits_1.diagnosticAlarmMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int diagnosticAlarmMask : 1; /* 1E.D401.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int reserved1 : 6; + /*! \brief 1E.D401.7 R/WPD MDIO Command Handling Overflow Mask + AQ_GlobalInterruptMask_HHD.u1.bits_1.mdioCommandHandlingOverflowMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int mdioCommandHandlingOverflowMask : 1; /* 1E.D401.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D401.A:8 R/WPD Reserved Alarms Mask [2:0] + AQ_GlobalInterruptMask_HHD.u1.bits_1.reservedAlarmsMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int reservedAlarmsMask : 3; /* 1E.D401.A:8 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D401.B R/WPD DTE Status Change Mask + AQ_GlobalInterruptMask_HHD.u1.bits_1.dteStatusChangeMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int dteStatusChangeMask : 1; /* 1E.D401.B R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D401.C R/WPD IP Phone Detect Mask + AQ_GlobalInterruptMask_HHD.u1.bits_1.ipPhoneDetectMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int ipPhoneDetectMask : 1; /* 1E.D401.C R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D401.D R/WPD XENPAK Alarm Mask + AQ_GlobalInterruptMask_HHD.u1.bits_1.xenpakAlarmMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int xenpakAlarmMask : 1; /* 1E.D401.D R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D401.E R/WPD Smart Power-Down Entered Mask + AQ_GlobalInterruptMask_HHD.u1.bits_1.smartPower_downEnteredMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int smartPower_downEnteredMask : 1; /* 1E.D401.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int reserved0 : 1; + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Interrupt Mask */ + union + { + struct + { + /*! \brief 1E.D402.0 R/WPD Watchdog Timer Alarm Mask + AQ_GlobalInterruptMask_HHD.u2.bits_2.watchdogTimerAlarmMask + + Provisionable Default = 0x1 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int watchdogTimerAlarmMask : 1; /* 1E.D402.0 R/WPD Provisionable Default = 0x1 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D402.1 R/WPD MDIO Timeout Error Mask + AQ_GlobalInterruptMask_HHD.u2.bits_2.mdioTimeoutErrorMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int mdioTimeoutErrorMask : 1; /* 1E.D402.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D402.2 R/WPD MDIO MMD Error Mask + AQ_GlobalInterruptMask_HHD.u2.bits_2.mdioMMD_ErrorMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int mdioMMD_ErrorMask : 1; /* 1E.D402.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved2 : 2; + /*! \brief 1E.D402.5 R/WPD Tx Enable State Change Mask + AQ_GlobalInterruptMask_HHD.u2.bits_2.txEnableStateChangeMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int txEnableStateChangeMask : 1; /* 1E.D402.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved1 : 2; + /*! \brief 1E.D402.9:8 R/WPD uP IRAM Parity Error Mask [1:0] + AQ_GlobalInterruptMask_HHD.u2.bits_2.upIramParityErrorMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int upIramParityErrorMask : 2; /* 1E.D402.9:8 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D402.A R/WPD uP DRAM Parity Error Mask + AQ_GlobalInterruptMask_HHD.u2.bits_2.upDramParityErrorMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int upDramParityErrorMask : 1; /* 1E.D402.A R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int reserved0 : 3; + /*! \brief 1E.D402.E R/WPD Mailbox Operation Complete Mask + AQ_GlobalInterruptMask_HHD.u2.bits_2.mailboxOperationCompleteMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + Notes: + Mailbox interface is ready interrupt for registers See Global Vendor Specific Control - Address 1E.C000 - See Global Vendor Specific Provisioning 5 - Address 1E.C404 */ + unsigned int mailboxOperationCompleteMask : 1; /* 1E.D402.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D402.F R/WPD NVR Operation Complete Mask + AQ_GlobalInterruptMask_HHD.u2.bits_2.nvrOperationCompleteMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + Notes: + NVR interface is ready interrupt for registers See Global NVR Interface 1: Address 1E.100 - See Global NVR Provisioning Data MSW - Address 1E.17 */ + unsigned int nvrOperationCompleteMask : 1; /* 1E.D402.F R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + } bits_2; + uint16_t word_2; + } u2; +} AQ_GlobalInterruptMask_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Chip-Wide Standard Interrupt Flags: 1E.FC00 */ +/* Global Chip-Wide Standard Interrupt Flags: 1E.FC00 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Chip-Wide Standard Interrupt Flags */ + union + { + struct + { + /*! \brief 1E.FC00.0 RO All Vendor Alarms Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_HHD.u0.bits_0.allVendorAlarmsInterrupt + + + + 1 = Interrupt in all vendor alarms + + + Notes: + An interrupt was generated from status register ( See Global Chip-Wide LASI Vendor Interrupt Flags: Address 1E.FC01 ) and the corresponding mask register. ( See Global Interrupt LASI Mask: Address 1E.FF01 ) */ + unsigned int allVendorAlarmsInterrupt : 1; /* 1E.FC00.0 RO */ + /* 1 = Interrupt in all vendor alarms + */ + unsigned int reserved0 : 5; + /*! \brief 1E.FC00.6 RO GbE Standard Alarms Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_HHD.u0.bits_0.gbeStandardAlarmsInterrupt + + + + 1 = Interrupt in GbE standard alarms + + + Notes: + An interrupt was generated from the TGE core. */ + unsigned int gbeStandardAlarmsInterrupt : 1; /* 1E.FC00.6 RO */ + /* 1 = Interrupt in GbE standard alarms + */ + /*! \brief 1E.FC00.7 RO Autonegotiation Standard Alarms 2 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_HHD.u0.bits_0.autonegotiationStandardAlarms_2Interrupt + + + + 1 = Interrupt in Autonegotiation standard alarms 2 + + + Notes: + An interrupt was generated from status register ( See Autonegotiation 10GBASE-T Status Register - Address 7.21 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 8 - Address 4.A008 ) */ + unsigned int autonegotiationStandardAlarms_2Interrupt : 1; /* 1E.FC00.7 RO */ + /* 1 = Interrupt in Autonegotiation standard alarms 2 + */ + /*! \brief 1E.FC00.8 RO Autonegotiation Standard Alarms 1 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_HHD.u0.bits_0.autonegotiationStandardAlarms_1Interrupt + + + + 1 = Interrupt in Autonegotiation standard alarms 1 + + + Notes: + An interrupt was generated from status register ( See PHY XS Standard Status 1 - Address 4.1 ) and the corresponding mask register. ( See Autonegotiation Standard LASI Interrupt Mask 1: Address 7.D000 ) */ + unsigned int autonegotiationStandardAlarms_1Interrupt : 1; /* 1E.FC00.8 RO */ + /* 1 = Interrupt in Autonegotiation standard alarms 1 + */ + /*! \brief 1E.FC00.9 RO PHY XS Standard Alarms 2 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_HHD.u0.bits_0.phyXS_StandardAlarms_2Interrupt + + + + 1 = Interrupt in PHY XS standard alarms 2 + + + Notes: + An interrupt was generated from the status register ( See PHY XS Standard Vendor Devices in Package - Address 4.8 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 8 - Address 4.A008 ) */ + unsigned int phyXS_StandardAlarms_2Interrupt : 1; /* 1E.FC00.9 RO */ + /* 1 = Interrupt in PHY XS standard alarms 2 + */ + /*! \brief 1E.FC00.A RO PHY XS Standard Alarms 1 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_HHD.u0.bits_0.phyXS_StandardAlarms_1Interrupt + + + + 1 = Interrupt in PHY XS standard alarms 1 + + + Notes: + An interrupt was generated from the status register ( See PHY XS Standard Status 1 - Address 4.1 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 2 - Address 4.A001 ) */ + unsigned int phyXS_StandardAlarms_1Interrupt : 1; /* 1E.FC00.A RO */ + /* 1 = Interrupt in PHY XS standard alarms 1 + */ + /*! \brief 1E.FC00.B RO PCS Standard Alarm 3 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_HHD.u0.bits_0.pcsStandardAlarm_3Interrupt + + + + 1 = Interrupt in PCS standard alarms 3 + + + Notes: + An interrupt was generated from status register ( See PCS 10GBASE-T Status 2 - Address 3.21 ) and the corresponding mask register. ( See PCS Standard Interrupt Mask 1 - Address 3.E021 ) */ + unsigned int pcsStandardAlarm_3Interrupt : 1; /* 1E.FC00.B RO */ + /* 1 = Interrupt in PCS standard alarms 3 + */ + /*! \brief 1E.FC00.C RO PCS Standard Alarm 2 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_HHD.u0.bits_0.pcsStandardAlarm_2Interrupt + + + + 1 = Interrupt in PCS standard alarms 2 + + + Notes: + An interrupt was generated from status register ( See PHY XS Standard Vendor Devices in Package - Address 4.8 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 8 - Address 4.A008 ) */ + unsigned int pcsStandardAlarm_2Interrupt : 1; /* 1E.FC00.C RO */ + /* 1 = Interrupt in PCS standard alarms 2 + */ + /*! \brief 1E.FC00.D RO PCS Standard Alarm 1 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_HHD.u0.bits_0.pcsStandardAlarm_1Interrupt + + + + 1 = Interrupt in PCS standard alarms 1 + + + Notes: + An interrupt was generated from status register ( See PHY XS Standard Status 1 - Address 4.1 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 2 - Address 4.A001 ) */ + unsigned int pcsStandardAlarm_1Interrupt : 1; /* 1E.FC00.D RO */ + /* 1 = Interrupt in PCS standard alarms 1 + */ + /*! \brief 1E.FC00.E RO PMA Standard Alarm 2 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_HHD.u0.bits_0.pmaStandardAlarm_2Interrupt + + + + 1 = Interrupt in PMA standard alarms 2 + + + Notes: + An interrupt was generated from either bit 1.8.B or 1.8.A. + An interrupt was generated from status register ( See PHY XS Standard Vendor Devices in Package - Address 4.8 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 8 - Address 4.A008 ) */ + unsigned int pmaStandardAlarm_2Interrupt : 1; /* 1E.FC00.E RO */ + /* 1 = Interrupt in PMA standard alarms 2 + */ + /*! \brief 1E.FC00.F RO PMA Standard Alarm 1 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_HHD.u0.bits_0.pmaStandardAlarm_1Interrupt + + + + 1 = Interrupt in PMA standard alarms 1 + + + Notes: + An interrupt was generated from bit 1.1.2. + An interrupt was generated from status register ( See PHY XS Standard Status 1 - Address 4.1 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 2 - Address 4.A001 ) */ + unsigned int pmaStandardAlarm_1Interrupt : 1; /* 1E.FC00.F RO */ + /* 1 = Interrupt in PMA standard alarms 1 + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalChip_wideStandardInterruptFlags_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Chip-Wide Vendor Interrupt Flags: 1E.FC01 */ +/* Global Chip-Wide Vendor Interrupt Flags: 1E.FC01 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Chip-Wide Vendor Interrupt Flags */ + union + { + struct + { + /*! \brief 1E.FC01.0 RO Global Alarms 3 Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_HHD.u0.bits_0.globalAlarms_3Interrupt + + + + 1 = Interrupt in Global alarms 3 + + + Notes: + An interrupt was generated from status register ( See Global Vendor Alarms 2: Address 1E.CC01 ) and the corresponding mask register. ( See Global LASI Interrupt Mask 2: Address 1E.D401 ) */ + unsigned int globalAlarms_3Interrupt : 1; /* 1E.FC01.0 RO */ + /* 1 = Interrupt in Global alarms 3 + */ + /*! \brief 1E.FC01.1 RO Global Alarms 2 Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_HHD.u0.bits_0.globalAlarms_2Interrupt + + + + 1 = Interrupt in Global alarms 2 + + + Notes: + An interrupt was generated from status register ( See Global Alarms 2: Address 1E.CC01 ) and the corresponding mask register. ( See Global LASI Interrupt Mask 2: Address 1E.D401 ) */ + unsigned int globalAlarms_2Interrupt : 1; /* 1E.FC01.1 RO */ + /* 1 = Interrupt in Global alarms 2 + */ + /*! \brief 1E.FC01.2 RO Global Alarms 1 Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_HHD.u0.bits_0.globalAlarms_1Interrupt + + + + 1 = Interrupt in Global alarms 1 + + + Notes: + An interrupt was generated from status register ( See Global Vendor Alarms 1 - Address 1E.CC00 ) and the corresponding mask register. ( See Global Vendor Interrupt Mask - Address 1E.D400 ) */ + unsigned int globalAlarms_1Interrupt : 1; /* 1E.FC01.2 RO */ + /* 1 = Interrupt in Global alarms 1 + */ + unsigned int reserved0 : 8; + /*! \brief 1E.FC01.B RO GbE Vendor Alarm Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_HHD.u0.bits_0.gbeVendorAlarmInterrupt + + + + 1 = Interrupt in GbE vendor specific alarm + + + Notes: + A GbE alarm was generated. ( See GbE PHY Vendor Global LASI Interrupt Flags 1: Address 1D.FC00 ) */ + unsigned int gbeVendorAlarmInterrupt : 1; /* 1E.FC01.B RO */ + /* 1 = Interrupt in GbE vendor specific alarm + */ + /*! \brief 1E.FC01.C RO Autonegotiation Vendor Alarm Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_HHD.u0.bits_0.autonegotiationVendorAlarmInterrupt + + + + 1 = Interrupt in Autonegotiation vendor specific alarm + + + Notes: + An Autonegotiation alarm was generated. ( See Autonegotiation Vendor Global LASI Interrupt Flags 1: Address 7.FC00 ) */ + unsigned int autonegotiationVendorAlarmInterrupt : 1; /* 1E.FC01.C RO */ + /* 1 = Interrupt in Autonegotiation vendor specific alarm + */ + /*! \brief 1E.FC01.D RO PHY XS Vendor Alarm Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_HHD.u0.bits_0.phyXS_VendorAlarmInterrupt + + + + 1 = Interrupt in PHY XS vendor specific alarm + + + Notes: + A PHY XS alarm was generated. ( See PHY XS Vendor Global LASI Interrupt Flags 1: Address 4.FC00 ) */ + unsigned int phyXS_VendorAlarmInterrupt : 1; /* 1E.FC01.D RO */ + /* 1 = Interrupt in PHY XS vendor specific alarm + */ + /*! \brief 1E.FC01.E RO PCS Vendor Alarm Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_HHD.u0.bits_0.pcsVendorAlarmInterrupt + + + + 1 = Interrupt in PCS vendor specific alarm + + + Notes: + A PCS alarm was generated. ( See PHY XS Vendor Global Interrupt Flags 1- Address 4.F800 ) */ + unsigned int pcsVendorAlarmInterrupt : 1; /* 1E.FC01.E RO */ + /* 1 = Interrupt in PCS vendor specific alarm + */ + /*! \brief 1E.FC01.F RO PMA Vendor Alarm Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_HHD.u0.bits_0.pmaVendorAlarmInterrupt + + + + 1 = Interrupt in PMA vendor specific alarm + + + Notes: + A PMA alarm was generated. ( See PHY XS Vendor Global Interrupt Flags 1- Address 4.F800 ) */ + unsigned int pmaVendorAlarmInterrupt : 1; /* 1E.FC01.F RO */ + /* 1 = Interrupt in PMA vendor specific alarm + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalChip_wideVendorInterruptFlags_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Interrupt Chip-Wide Standard Mask: 1E.FF00 */ +/* Global Interrupt Chip-Wide Standard Mask: 1E.FF00 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Interrupt Chip-Wide Standard Mask */ + union + { + struct + { + /*! \brief 1E.FF00.0 R/WPD All Vendor Alarms Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_HHD.u0.bits_0.allVendorAlarmsInterruptMask + + Provisionable Default = 0x1 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int allVendorAlarmsInterruptMask : 1; /* 1E.FF00.0 R/WPD Provisionable Default = 0x1 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved0 : 5; + /*! \brief 1E.FF00.6 R/WPD Gbe Standard Alarms Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_HHD.u0.bits_0.gbeStandardAlarmsInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int gbeStandardAlarmsInterruptMask : 1; /* 1E.FF00.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.7 R/WPD Autonegotiation Standard Alarms 2 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_HHD.u0.bits_0.autonegotiationStandardAlarms_2InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int autonegotiationStandardAlarms_2InterruptMask : 1; /* 1E.FF00.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.8 R/WPD Autonegotiation Standard Alarms 1 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_HHD.u0.bits_0.autonegotiationStandardAlarms_1InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int autonegotiationStandardAlarms_1InterruptMask : 1; /* 1E.FF00.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.9 R/WPD PHY XS Standard Alarms 2 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_HHD.u0.bits_0.phyXS_StandardAlarms_2InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int phyXS_StandardAlarms_2InterruptMask : 1; /* 1E.FF00.9 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.A R/WPD PHY XS Standard Alarms 1 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_HHD.u0.bits_0.phyXS_StandardAlarms_1InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int phyXS_StandardAlarms_1InterruptMask : 1; /* 1E.FF00.A R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.B R/WPD PCS Standard Alarm 3 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_HHD.u0.bits_0.pcsStandardAlarm_3InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pcsStandardAlarm_3InterruptMask : 1; /* 1E.FF00.B R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.C R/WPD PCS Standard Alarm 2 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_HHD.u0.bits_0.pcsStandardAlarm_2InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pcsStandardAlarm_2InterruptMask : 1; /* 1E.FF00.C R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.D R/WPD PCS Standard Alarm 1 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_HHD.u0.bits_0.pcsStandardAlarm_1InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pcsStandardAlarm_1InterruptMask : 1; /* 1E.FF00.D R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.E R/WPD PMA Standard Alarm 2 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_HHD.u0.bits_0.pmaStandardAlarm_2InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pmaStandardAlarm_2InterruptMask : 1; /* 1E.FF00.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.F R/WPD PMA Standard Alarm 1 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_HHD.u0.bits_0.pmaStandardAlarm_1InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pmaStandardAlarm_1InterruptMask : 1; /* 1E.FF00.F R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalInterruptChip_wideStandardMask_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Interrupt Chip-Wide Vendor Mask: 1E.FF01 */ +/* Global Interrupt Chip-Wide Vendor Mask: 1E.FF01 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Interrupt Chip-Wide Vendor Mask */ + union + { + struct + { + /*! \brief 1E.FF01.0 R/WPD Global Alarms 3 Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_HHD.u0.bits_0.globalAlarms_3InterruptMask + + Provisionable Default = 0x1 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int globalAlarms_3InterruptMask : 1; /* 1E.FF01.0 R/WPD Provisionable Default = 0x1 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.1 R/WPD Global Alarms 2 Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_HHD.u0.bits_0.globalAlarms_2InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int globalAlarms_2InterruptMask : 1; /* 1E.FF01.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.2 R/WPD Global Alarms 1 Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_HHD.u0.bits_0.globalAlarms_1InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int globalAlarms_1InterruptMask : 1; /* 1E.FF01.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved0 : 8; + /*! \brief 1E.FF01.B R/WPD GbE Vendor Alarm Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_HHD.u0.bits_0.gbeVendorAlarmInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int gbeVendorAlarmInterruptMask : 1; /* 1E.FF01.B R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.C R/WPD Autonegotiation Vendor Alarm Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_HHD.u0.bits_0.autonegotiationVendorAlarmInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int autonegotiationVendorAlarmInterruptMask : 1; /* 1E.FF01.C R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.D R/WPD PHY XS Vendor Alarm Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_HHD.u0.bits_0.phyXS_VendorAlarmInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int phyXS_VendorAlarmInterruptMask : 1; /* 1E.FF01.D R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.E R/WPD PCS Vendor Alarm Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_HHD.u0.bits_0.pcsVendorAlarmInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pcsVendorAlarmInterruptMask : 1; /* 1E.FF01.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.F R/WPD PMA Vendor Alarm Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_HHD.u0.bits_0.pmaVendorAlarmInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pmaVendorAlarmInterruptMask : 1; /* 1E.FF01.F R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalInterruptChip_wideVendorMask_HHD; + +#endif +/*@}*/ +/*@}*/ diff --git a/feeds/ipq807x/aq-fw-download/src/include/registerMap/HHD/AQ_HHD_Global_registers_Defines.h b/feeds/ipq807x/aq-fw-download/src/include/registerMap/HHD/AQ_HHD_Global_registers_Defines.h new file mode 100755 index 000000000..d9a4429d5 --- /dev/null +++ b/feeds/ipq807x/aq-fw-download/src/include/registerMap/HHD/AQ_HHD_Global_registers_Defines.h @@ -0,0 +1,4413 @@ +/*! \file +* This file contains the compiler assist macros and doxygen comments +* for the Global Registers block. +*/ + +/*! \defgroup Global_registers_Defines Global Registers Defines +* This module contains the compiler assist macros and doxygen comments +* for the Global Registers block. +*/ +/*********************************************************************** +* Copyright (c) 2015, Aquantia +* +* Permission to use, copy, modify, and/or distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +* +* $File: //depot/icm/proj/Dena/rev1.0/c/Systems/tools/windows/regMapParser/src/gencheaders.py $ +* +* $Revision: #10 $ +* +* $DateTime: 2014/04/08 16:55:58 $ +* +* $Author: joshd $ +* +* $Label: $ +* +* Description: +* +* This file contains the compiler assist macros for the registers contained in the Global Registers block. +* +* +***********************************************************************/ + + +/*@{*/ +#ifndef AQ_HHD_GLOBAL_REGS_DEFINES_HEADER +#define AQ_HHD_GLOBAL_REGS_DEFINES_HEADER + + +/*-----------------------------------------------------------------------------*/ +/*Access macro definitions */ +/*-----------------------------------------------------------------------------*/ +/*! \brief Base register address of structure AQ_GlobalStandardControl_1_HHD */ +#define AQ_GlobalStandardControl_1_HHD_baseRegisterAddress 0x0000 +/*! \brief MMD address of structure AQ_GlobalStandardControl_1_HHD */ +#define AQ_GlobalStandardControl_1_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure softReset in AQ_GlobalStandardControl_1_HHD */ +#define AQ_GlobalStandardControl_1_HHD_softReset 0 +/*! \brief Preprocessor variable to relate field to bit position in structure softReset in AQ_GlobalStandardControl_1_HHD */ +#define bits_AQ_GlobalStandardControl_1_HHD_softReset u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure softReset in AQ_GlobalStandardControl_1_HHD */ +#define word_AQ_GlobalStandardControl_1_HHD_softReset u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure lowPower in AQ_GlobalStandardControl_1_HHD */ +#define AQ_GlobalStandardControl_1_HHD_lowPower 0 +/*! \brief Preprocessor variable to relate field to bit position in structure lowPower in AQ_GlobalStandardControl_1_HHD */ +#define bits_AQ_GlobalStandardControl_1_HHD_lowPower u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure lowPower in AQ_GlobalStandardControl_1_HHD */ +#define word_AQ_GlobalStandardControl_1_HHD_lowPower u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalStandardDeviceIdentifier_HHD */ +#define AQ_GlobalStandardDeviceIdentifier_HHD_baseRegisterAddress 0x0002 +/*! \brief MMD address of structure AQ_GlobalStandardDeviceIdentifier_HHD */ +#define AQ_GlobalStandardDeviceIdentifier_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure deviceIdMSW in AQ_GlobalStandardDeviceIdentifier_HHD */ +#define AQ_GlobalStandardDeviceIdentifier_HHD_deviceIdMSW 0 +/*! \brief Preprocessor variable to relate field to bit position in structure deviceIdMSW in AQ_GlobalStandardDeviceIdentifier_HHD */ +#define bits_AQ_GlobalStandardDeviceIdentifier_HHD_deviceIdMSW u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure deviceIdMSW in AQ_GlobalStandardDeviceIdentifier_HHD */ +#define word_AQ_GlobalStandardDeviceIdentifier_HHD_deviceIdMSW u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure deviceIdLSW in AQ_GlobalStandardDeviceIdentifier_HHD */ +#define AQ_GlobalStandardDeviceIdentifier_HHD_deviceIdLSW 1 +/*! \brief Preprocessor variable to relate field to bit position in structure deviceIdLSW in AQ_GlobalStandardDeviceIdentifier_HHD */ +#define bits_AQ_GlobalStandardDeviceIdentifier_HHD_deviceIdLSW u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure deviceIdLSW in AQ_GlobalStandardDeviceIdentifier_HHD */ +#define word_AQ_GlobalStandardDeviceIdentifier_HHD_deviceIdLSW u1.word_1 + +/*! \brief Base register address of structure AQ_GlobalStandardDevicesInPackage_HHD */ +#define AQ_GlobalStandardDevicesInPackage_HHD_baseRegisterAddress 0x0005 +/*! \brief MMD address of structure AQ_GlobalStandardDevicesInPackage_HHD */ +#define AQ_GlobalStandardDevicesInPackage_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure autonegotiationPresent in AQ_GlobalStandardDevicesInPackage_HHD */ +#define AQ_GlobalStandardDevicesInPackage_HHD_autonegotiationPresent 0 +/*! \brief Preprocessor variable to relate field to bit position in structure autonegotiationPresent in AQ_GlobalStandardDevicesInPackage_HHD */ +#define bits_AQ_GlobalStandardDevicesInPackage_HHD_autonegotiationPresent u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure autonegotiationPresent in AQ_GlobalStandardDevicesInPackage_HHD */ +#define word_AQ_GlobalStandardDevicesInPackage_HHD_autonegotiationPresent u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure tcPresent in AQ_GlobalStandardDevicesInPackage_HHD */ +#define AQ_GlobalStandardDevicesInPackage_HHD_tcPresent 0 +/*! \brief Preprocessor variable to relate field to bit position in structure tcPresent in AQ_GlobalStandardDevicesInPackage_HHD */ +#define bits_AQ_GlobalStandardDevicesInPackage_HHD_tcPresent u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure tcPresent in AQ_GlobalStandardDevicesInPackage_HHD */ +#define word_AQ_GlobalStandardDevicesInPackage_HHD_tcPresent u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure dteXsPresent in AQ_GlobalStandardDevicesInPackage_HHD */ +#define AQ_GlobalStandardDevicesInPackage_HHD_dteXsPresent 0 +/*! \brief Preprocessor variable to relate field to bit position in structure dteXsPresent in AQ_GlobalStandardDevicesInPackage_HHD */ +#define bits_AQ_GlobalStandardDevicesInPackage_HHD_dteXsPresent u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure dteXsPresent in AQ_GlobalStandardDevicesInPackage_HHD */ +#define word_AQ_GlobalStandardDevicesInPackage_HHD_dteXsPresent u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure phyXS_Present in AQ_GlobalStandardDevicesInPackage_HHD */ +#define AQ_GlobalStandardDevicesInPackage_HHD_phyXS_Present 0 +/*! \brief Preprocessor variable to relate field to bit position in structure phyXS_Present in AQ_GlobalStandardDevicesInPackage_HHD */ +#define bits_AQ_GlobalStandardDevicesInPackage_HHD_phyXS_Present u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure phyXS_Present in AQ_GlobalStandardDevicesInPackage_HHD */ +#define word_AQ_GlobalStandardDevicesInPackage_HHD_phyXS_Present u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pcsPresent in AQ_GlobalStandardDevicesInPackage_HHD */ +#define AQ_GlobalStandardDevicesInPackage_HHD_pcsPresent 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pcsPresent in AQ_GlobalStandardDevicesInPackage_HHD */ +#define bits_AQ_GlobalStandardDevicesInPackage_HHD_pcsPresent u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pcsPresent in AQ_GlobalStandardDevicesInPackage_HHD */ +#define word_AQ_GlobalStandardDevicesInPackage_HHD_pcsPresent u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure wisPresent in AQ_GlobalStandardDevicesInPackage_HHD */ +#define AQ_GlobalStandardDevicesInPackage_HHD_wisPresent 0 +/*! \brief Preprocessor variable to relate field to bit position in structure wisPresent in AQ_GlobalStandardDevicesInPackage_HHD */ +#define bits_AQ_GlobalStandardDevicesInPackage_HHD_wisPresent u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure wisPresent in AQ_GlobalStandardDevicesInPackage_HHD */ +#define word_AQ_GlobalStandardDevicesInPackage_HHD_wisPresent u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pmaPresent in AQ_GlobalStandardDevicesInPackage_HHD */ +#define AQ_GlobalStandardDevicesInPackage_HHD_pmaPresent 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pmaPresent in AQ_GlobalStandardDevicesInPackage_HHD */ +#define bits_AQ_GlobalStandardDevicesInPackage_HHD_pmaPresent u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pmaPresent in AQ_GlobalStandardDevicesInPackage_HHD */ +#define word_AQ_GlobalStandardDevicesInPackage_HHD_pmaPresent u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure clause_22RegistersPresent in AQ_GlobalStandardDevicesInPackage_HHD */ +#define AQ_GlobalStandardDevicesInPackage_HHD_clause_22RegistersPresent 0 +/*! \brief Preprocessor variable to relate field to bit position in structure clause_22RegistersPresent in AQ_GlobalStandardDevicesInPackage_HHD */ +#define bits_AQ_GlobalStandardDevicesInPackage_HHD_clause_22RegistersPresent u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure clause_22RegistersPresent in AQ_GlobalStandardDevicesInPackage_HHD */ +#define word_AQ_GlobalStandardDevicesInPackage_HHD_clause_22RegistersPresent u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalStandardVendorDevicesInPackage_HHD */ +#define AQ_GlobalStandardVendorDevicesInPackage_HHD_baseRegisterAddress 0x0006 +/*! \brief MMD address of structure AQ_GlobalStandardVendorDevicesInPackage_HHD */ +#define AQ_GlobalStandardVendorDevicesInPackage_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure vendorSpecificDevice_2Present in AQ_GlobalStandardVendorDevicesInPackage_HHD */ +#define AQ_GlobalStandardVendorDevicesInPackage_HHD_vendorSpecificDevice_2Present 0 +/*! \brief Preprocessor variable to relate field to bit position in structure vendorSpecificDevice_2Present in AQ_GlobalStandardVendorDevicesInPackage_HHD */ +#define bits_AQ_GlobalStandardVendorDevicesInPackage_HHD_vendorSpecificDevice_2Present u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure vendorSpecificDevice_2Present in AQ_GlobalStandardVendorDevicesInPackage_HHD */ +#define word_AQ_GlobalStandardVendorDevicesInPackage_HHD_vendorSpecificDevice_2Present u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure vendorSpecificDevice_1Present in AQ_GlobalStandardVendorDevicesInPackage_HHD */ +#define AQ_GlobalStandardVendorDevicesInPackage_HHD_vendorSpecificDevice_1Present 0 +/*! \brief Preprocessor variable to relate field to bit position in structure vendorSpecificDevice_1Present in AQ_GlobalStandardVendorDevicesInPackage_HHD */ +#define bits_AQ_GlobalStandardVendorDevicesInPackage_HHD_vendorSpecificDevice_1Present u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure vendorSpecificDevice_1Present in AQ_GlobalStandardVendorDevicesInPackage_HHD */ +#define word_AQ_GlobalStandardVendorDevicesInPackage_HHD_vendorSpecificDevice_1Present u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure clause_22ExtensionPresent in AQ_GlobalStandardVendorDevicesInPackage_HHD */ +#define AQ_GlobalStandardVendorDevicesInPackage_HHD_clause_22ExtensionPresent 0 +/*! \brief Preprocessor variable to relate field to bit position in structure clause_22ExtensionPresent in AQ_GlobalStandardVendorDevicesInPackage_HHD */ +#define bits_AQ_GlobalStandardVendorDevicesInPackage_HHD_clause_22ExtensionPresent u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure clause_22ExtensionPresent in AQ_GlobalStandardVendorDevicesInPackage_HHD */ +#define word_AQ_GlobalStandardVendorDevicesInPackage_HHD_clause_22ExtensionPresent u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalStandardStatus_2_HHD */ +#define AQ_GlobalStandardStatus_2_HHD_baseRegisterAddress 0x0008 +/*! \brief MMD address of structure AQ_GlobalStandardStatus_2_HHD */ +#define AQ_GlobalStandardStatus_2_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure devicePresent in AQ_GlobalStandardStatus_2_HHD */ +#define AQ_GlobalStandardStatus_2_HHD_devicePresent 0 +/*! \brief Preprocessor variable to relate field to bit position in structure devicePresent in AQ_GlobalStandardStatus_2_HHD */ +#define bits_AQ_GlobalStandardStatus_2_HHD_devicePresent u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure devicePresent in AQ_GlobalStandardStatus_2_HHD */ +#define word_AQ_GlobalStandardStatus_2_HHD_devicePresent u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalStandardPackageIdentifier_HHD */ +#define AQ_GlobalStandardPackageIdentifier_HHD_baseRegisterAddress 0x000E +/*! \brief MMD address of structure AQ_GlobalStandardPackageIdentifier_HHD */ +#define AQ_GlobalStandardPackageIdentifier_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure packageIdMSW in AQ_GlobalStandardPackageIdentifier_HHD */ +#define AQ_GlobalStandardPackageIdentifier_HHD_packageIdMSW 0 +/*! \brief Preprocessor variable to relate field to bit position in structure packageIdMSW in AQ_GlobalStandardPackageIdentifier_HHD */ +#define bits_AQ_GlobalStandardPackageIdentifier_HHD_packageIdMSW u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure packageIdMSW in AQ_GlobalStandardPackageIdentifier_HHD */ +#define word_AQ_GlobalStandardPackageIdentifier_HHD_packageIdMSW u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure packageIdLSW in AQ_GlobalStandardPackageIdentifier_HHD */ +#define AQ_GlobalStandardPackageIdentifier_HHD_packageIdLSW 1 +/*! \brief Preprocessor variable to relate field to bit position in structure packageIdLSW in AQ_GlobalStandardPackageIdentifier_HHD */ +#define bits_AQ_GlobalStandardPackageIdentifier_HHD_packageIdLSW u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure packageIdLSW in AQ_GlobalStandardPackageIdentifier_HHD */ +#define word_AQ_GlobalStandardPackageIdentifier_HHD_packageIdLSW u1.word_1 + +/*! \brief Base register address of structure AQ_GlobalFirmwareID_HHD */ +#define AQ_GlobalFirmwareID_HHD_baseRegisterAddress 0x0020 +/*! \brief MMD address of structure AQ_GlobalFirmwareID_HHD */ +#define AQ_GlobalFirmwareID_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure firmwareMajorRevisionNumber in AQ_GlobalFirmwareID_HHD */ +#define AQ_GlobalFirmwareID_HHD_firmwareMajorRevisionNumber 0 +/*! \brief Preprocessor variable to relate field to bit position in structure firmwareMajorRevisionNumber in AQ_GlobalFirmwareID_HHD */ +#define bits_AQ_GlobalFirmwareID_HHD_firmwareMajorRevisionNumber u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure firmwareMajorRevisionNumber in AQ_GlobalFirmwareID_HHD */ +#define word_AQ_GlobalFirmwareID_HHD_firmwareMajorRevisionNumber u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure firmwareMinorRevisionNumber in AQ_GlobalFirmwareID_HHD */ +#define AQ_GlobalFirmwareID_HHD_firmwareMinorRevisionNumber 0 +/*! \brief Preprocessor variable to relate field to bit position in structure firmwareMinorRevisionNumber in AQ_GlobalFirmwareID_HHD */ +#define bits_AQ_GlobalFirmwareID_HHD_firmwareMinorRevisionNumber u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure firmwareMinorRevisionNumber in AQ_GlobalFirmwareID_HHD */ +#define word_AQ_GlobalFirmwareID_HHD_firmwareMinorRevisionNumber u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalNvrInterface_HHD */ +#define AQ_GlobalNvrInterface_HHD_baseRegisterAddress 0x0100 +/*! \brief MMD address of structure AQ_GlobalNvrInterface_HHD */ +#define AQ_GlobalNvrInterface_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure nvrExecuteOperation in AQ_GlobalNvrInterface_HHD */ +#define AQ_GlobalNvrInterface_HHD_nvrExecuteOperation 0 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrExecuteOperation in AQ_GlobalNvrInterface_HHD */ +#define bits_AQ_GlobalNvrInterface_HHD_nvrExecuteOperation u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure nvrExecuteOperation in AQ_GlobalNvrInterface_HHD */ +#define word_AQ_GlobalNvrInterface_HHD_nvrExecuteOperation u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure nvrWriteMode in AQ_GlobalNvrInterface_HHD */ +#define AQ_GlobalNvrInterface_HHD_nvrWriteMode 0 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrWriteMode in AQ_GlobalNvrInterface_HHD */ +#define bits_AQ_GlobalNvrInterface_HHD_nvrWriteMode u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure nvrWriteMode in AQ_GlobalNvrInterface_HHD */ +#define word_AQ_GlobalNvrInterface_HHD_nvrWriteMode u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure freezeNvrCrc in AQ_GlobalNvrInterface_HHD */ +#define AQ_GlobalNvrInterface_HHD_freezeNvrCrc 0 +/*! \brief Preprocessor variable to relate field to bit position in structure freezeNvrCrc in AQ_GlobalNvrInterface_HHD */ +#define bits_AQ_GlobalNvrInterface_HHD_freezeNvrCrc u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure freezeNvrCrc in AQ_GlobalNvrInterface_HHD */ +#define word_AQ_GlobalNvrInterface_HHD_freezeNvrCrc u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure resetNvrCrc in AQ_GlobalNvrInterface_HHD */ +#define AQ_GlobalNvrInterface_HHD_resetNvrCrc 0 +/*! \brief Preprocessor variable to relate field to bit position in structure resetNvrCrc in AQ_GlobalNvrInterface_HHD */ +#define bits_AQ_GlobalNvrInterface_HHD_resetNvrCrc u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure resetNvrCrc in AQ_GlobalNvrInterface_HHD */ +#define word_AQ_GlobalNvrInterface_HHD_resetNvrCrc u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure nvrBurst in AQ_GlobalNvrInterface_HHD */ +#define AQ_GlobalNvrInterface_HHD_nvrBurst 0 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrBurst in AQ_GlobalNvrInterface_HHD */ +#define bits_AQ_GlobalNvrInterface_HHD_nvrBurst u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure nvrBurst in AQ_GlobalNvrInterface_HHD */ +#define word_AQ_GlobalNvrInterface_HHD_nvrBurst u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure nvrBusy in AQ_GlobalNvrInterface_HHD */ +#define AQ_GlobalNvrInterface_HHD_nvrBusy 0 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrBusy in AQ_GlobalNvrInterface_HHD */ +#define bits_AQ_GlobalNvrInterface_HHD_nvrBusy u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure nvrBusy in AQ_GlobalNvrInterface_HHD */ +#define word_AQ_GlobalNvrInterface_HHD_nvrBusy u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure nvrOpcode in AQ_GlobalNvrInterface_HHD */ +#define AQ_GlobalNvrInterface_HHD_nvrOpcode 0 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrOpcode in AQ_GlobalNvrInterface_HHD */ +#define bits_AQ_GlobalNvrInterface_HHD_nvrOpcode u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure nvrOpcode in AQ_GlobalNvrInterface_HHD */ +#define word_AQ_GlobalNvrInterface_HHD_nvrOpcode u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure nvrMailboxCrc in AQ_GlobalNvrInterface_HHD */ +#define AQ_GlobalNvrInterface_HHD_nvrMailboxCrc 1 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrMailboxCrc in AQ_GlobalNvrInterface_HHD */ +#define bits_AQ_GlobalNvrInterface_HHD_nvrMailboxCrc u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure nvrMailboxCrc in AQ_GlobalNvrInterface_HHD */ +#define word_AQ_GlobalNvrInterface_HHD_nvrMailboxCrc u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure nvrAddressMSW in AQ_GlobalNvrInterface_HHD */ +#define AQ_GlobalNvrInterface_HHD_nvrAddressMSW 2 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrAddressMSW in AQ_GlobalNvrInterface_HHD */ +#define bits_AQ_GlobalNvrInterface_HHD_nvrAddressMSW u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure nvrAddressMSW in AQ_GlobalNvrInterface_HHD */ +#define word_AQ_GlobalNvrInterface_HHD_nvrAddressMSW u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure nvrAddressLSW in AQ_GlobalNvrInterface_HHD */ +#define AQ_GlobalNvrInterface_HHD_nvrAddressLSW 3 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrAddressLSW in AQ_GlobalNvrInterface_HHD */ +#define bits_AQ_GlobalNvrInterface_HHD_nvrAddressLSW u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure nvrAddressLSW in AQ_GlobalNvrInterface_HHD */ +#define word_AQ_GlobalNvrInterface_HHD_nvrAddressLSW u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure nvrDataMSW in AQ_GlobalNvrInterface_HHD */ +#define AQ_GlobalNvrInterface_HHD_nvrDataMSW 4 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrDataMSW in AQ_GlobalNvrInterface_HHD */ +#define bits_AQ_GlobalNvrInterface_HHD_nvrDataMSW u4.bits_4 +/*! \brief Preprocessor variable to relate field to word position in structure nvrDataMSW in AQ_GlobalNvrInterface_HHD */ +#define word_AQ_GlobalNvrInterface_HHD_nvrDataMSW u4.word_4 +/*! \brief Preprocessor variable to relate field to word number in structure nvrDataLSW in AQ_GlobalNvrInterface_HHD */ +#define AQ_GlobalNvrInterface_HHD_nvrDataLSW 5 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrDataLSW in AQ_GlobalNvrInterface_HHD */ +#define bits_AQ_GlobalNvrInterface_HHD_nvrDataLSW u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure nvrDataLSW in AQ_GlobalNvrInterface_HHD */ +#define word_AQ_GlobalNvrInterface_HHD_nvrDataLSW u5.word_5 + +/*! \brief Base register address of structure AQ_GlobalMailboxInterface_HHD */ +#define AQ_GlobalMailboxInterface_HHD_baseRegisterAddress 0x0200 +/*! \brief MMD address of structure AQ_GlobalMailboxInterface_HHD */ +#define AQ_GlobalMailboxInterface_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure upMailboxExecuteOperation in AQ_GlobalMailboxInterface_HHD */ +#define AQ_GlobalMailboxInterface_HHD_upMailboxExecuteOperation 0 +/*! \brief Preprocessor variable to relate field to bit position in structure upMailboxExecuteOperation in AQ_GlobalMailboxInterface_HHD */ +#define bits_AQ_GlobalMailboxInterface_HHD_upMailboxExecuteOperation u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure upMailboxExecuteOperation in AQ_GlobalMailboxInterface_HHD */ +#define word_AQ_GlobalMailboxInterface_HHD_upMailboxExecuteOperation u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure upMailboxWriteMode in AQ_GlobalMailboxInterface_HHD */ +#define AQ_GlobalMailboxInterface_HHD_upMailboxWriteMode 0 +/*! \brief Preprocessor variable to relate field to bit position in structure upMailboxWriteMode in AQ_GlobalMailboxInterface_HHD */ +#define bits_AQ_GlobalMailboxInterface_HHD_upMailboxWriteMode u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure upMailboxWriteMode in AQ_GlobalMailboxInterface_HHD */ +#define word_AQ_GlobalMailboxInterface_HHD_upMailboxWriteMode u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure resetUpMailboxCrc in AQ_GlobalMailboxInterface_HHD */ +#define AQ_GlobalMailboxInterface_HHD_resetUpMailboxCrc 0 +/*! \brief Preprocessor variable to relate field to bit position in structure resetUpMailboxCrc in AQ_GlobalMailboxInterface_HHD */ +#define bits_AQ_GlobalMailboxInterface_HHD_resetUpMailboxCrc u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure resetUpMailboxCrc in AQ_GlobalMailboxInterface_HHD */ +#define word_AQ_GlobalMailboxInterface_HHD_resetUpMailboxCrc u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure upMailboxBusy in AQ_GlobalMailboxInterface_HHD */ +#define AQ_GlobalMailboxInterface_HHD_upMailboxBusy 0 +/*! \brief Preprocessor variable to relate field to bit position in structure upMailboxBusy in AQ_GlobalMailboxInterface_HHD */ +#define bits_AQ_GlobalMailboxInterface_HHD_upMailboxBusy u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure upMailboxBusy in AQ_GlobalMailboxInterface_HHD */ +#define word_AQ_GlobalMailboxInterface_HHD_upMailboxBusy u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure upMailboxCrc in AQ_GlobalMailboxInterface_HHD */ +#define AQ_GlobalMailboxInterface_HHD_upMailboxCrc 1 +/*! \brief Preprocessor variable to relate field to bit position in structure upMailboxCrc in AQ_GlobalMailboxInterface_HHD */ +#define bits_AQ_GlobalMailboxInterface_HHD_upMailboxCrc u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure upMailboxCrc in AQ_GlobalMailboxInterface_HHD */ +#define word_AQ_GlobalMailboxInterface_HHD_upMailboxCrc u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure upMailboxAddressMSW in AQ_GlobalMailboxInterface_HHD */ +#define AQ_GlobalMailboxInterface_HHD_upMailboxAddressMSW 2 +/*! \brief Preprocessor variable to relate field to bit position in structure upMailboxAddressMSW in AQ_GlobalMailboxInterface_HHD */ +#define bits_AQ_GlobalMailboxInterface_HHD_upMailboxAddressMSW u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure upMailboxAddressMSW in AQ_GlobalMailboxInterface_HHD */ +#define word_AQ_GlobalMailboxInterface_HHD_upMailboxAddressMSW u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure upMailboxAddressLSW in AQ_GlobalMailboxInterface_HHD */ +#define AQ_GlobalMailboxInterface_HHD_upMailboxAddressLSW 3 +/*! \brief Preprocessor variable to relate field to bit position in structure upMailboxAddressLSW in AQ_GlobalMailboxInterface_HHD */ +#define bits_AQ_GlobalMailboxInterface_HHD_upMailboxAddressLSW u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure upMailboxAddressLSW in AQ_GlobalMailboxInterface_HHD */ +#define word_AQ_GlobalMailboxInterface_HHD_upMailboxAddressLSW u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure upMailboxAddressLSW_Don_tCare in AQ_GlobalMailboxInterface_HHD */ +#define AQ_GlobalMailboxInterface_HHD_upMailboxAddressLSW_Don_tCare 3 +/*! \brief Preprocessor variable to relate field to bit position in structure upMailboxAddressLSW_Don_tCare in AQ_GlobalMailboxInterface_HHD */ +#define bits_AQ_GlobalMailboxInterface_HHD_upMailboxAddressLSW_Don_tCare u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure upMailboxAddressLSW_Don_tCare in AQ_GlobalMailboxInterface_HHD */ +#define word_AQ_GlobalMailboxInterface_HHD_upMailboxAddressLSW_Don_tCare u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure upMailboxDataMSW in AQ_GlobalMailboxInterface_HHD */ +#define AQ_GlobalMailboxInterface_HHD_upMailboxDataMSW 4 +/*! \brief Preprocessor variable to relate field to bit position in structure upMailboxDataMSW in AQ_GlobalMailboxInterface_HHD */ +#define bits_AQ_GlobalMailboxInterface_HHD_upMailboxDataMSW u4.bits_4 +/*! \brief Preprocessor variable to relate field to word position in structure upMailboxDataMSW in AQ_GlobalMailboxInterface_HHD */ +#define word_AQ_GlobalMailboxInterface_HHD_upMailboxDataMSW u4.word_4 +/*! \brief Preprocessor variable to relate field to word number in structure upMailboxDataLSW in AQ_GlobalMailboxInterface_HHD */ +#define AQ_GlobalMailboxInterface_HHD_upMailboxDataLSW 5 +/*! \brief Preprocessor variable to relate field to bit position in structure upMailboxDataLSW in AQ_GlobalMailboxInterface_HHD */ +#define bits_AQ_GlobalMailboxInterface_HHD_upMailboxDataLSW u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure upMailboxDataLSW in AQ_GlobalMailboxInterface_HHD */ +#define word_AQ_GlobalMailboxInterface_HHD_upMailboxDataLSW u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure upMailboxCrcReadEnable in AQ_GlobalMailboxInterface_HHD */ +#define AQ_GlobalMailboxInterface_HHD_upMailboxCrcReadEnable 6 +/*! \brief Preprocessor variable to relate field to bit position in structure upMailboxCrcReadEnable in AQ_GlobalMailboxInterface_HHD */ +#define bits_AQ_GlobalMailboxInterface_HHD_upMailboxCrcReadEnable u6.bits_6 +/*! \brief Preprocessor variable to relate field to word position in structure upMailboxCrcReadEnable in AQ_GlobalMailboxInterface_HHD */ +#define word_AQ_GlobalMailboxInterface_HHD_upMailboxCrcReadEnable u6.word_6 + +/*! \brief Base register address of structure AQ_GlobalMicroprocessorScratchPad_HHD */ +#define AQ_GlobalMicroprocessorScratchPad_HHD_baseRegisterAddress 0x0300 +/*! \brief MMD address of structure AQ_GlobalMicroprocessorScratchPad_HHD */ +#define AQ_GlobalMicroprocessorScratchPad_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure scratchPad_1 in AQ_GlobalMicroprocessorScratchPad_HHD */ +#define AQ_GlobalMicroprocessorScratchPad_HHD_scratchPad_1 0 +/*! \brief Preprocessor variable to relate field to bit position in structure scratchPad_1 in AQ_GlobalMicroprocessorScratchPad_HHD */ +#define bits_AQ_GlobalMicroprocessorScratchPad_HHD_scratchPad_1 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure scratchPad_1 in AQ_GlobalMicroprocessorScratchPad_HHD */ +#define word_AQ_GlobalMicroprocessorScratchPad_HHD_scratchPad_1 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure scratchPad_2 in AQ_GlobalMicroprocessorScratchPad_HHD */ +#define AQ_GlobalMicroprocessorScratchPad_HHD_scratchPad_2 1 +/*! \brief Preprocessor variable to relate field to bit position in structure scratchPad_2 in AQ_GlobalMicroprocessorScratchPad_HHD */ +#define bits_AQ_GlobalMicroprocessorScratchPad_HHD_scratchPad_2 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure scratchPad_2 in AQ_GlobalMicroprocessorScratchPad_HHD */ +#define word_AQ_GlobalMicroprocessorScratchPad_HHD_scratchPad_2 u1.word_1 + +/*! \brief Base register address of structure AQ_MssEgressControlRegister_HHD */ +#define AQ_MssEgressControlRegister_HHD_baseRegisterAddress 0x5002 +/*! \brief MMD address of structure AQ_MssEgressControlRegister_HHD */ +#define AQ_MssEgressControlRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressEthertypeExplicitSectagLsb in AQ_MssEgressControlRegister_HHD */ +#define AQ_MssEgressControlRegister_HHD_mssEgressEthertypeExplicitSectagLsb 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressEthertypeExplicitSectagLsb in AQ_MssEgressControlRegister_HHD */ +#define bits_AQ_MssEgressControlRegister_HHD_mssEgressEthertypeExplicitSectagLsb u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressEthertypeExplicitSectagLsb in AQ_MssEgressControlRegister_HHD */ +#define word_AQ_MssEgressControlRegister_HHD_mssEgressEthertypeExplicitSectagLsb u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressClearGlobalTime in AQ_MssEgressControlRegister_HHD */ +#define AQ_MssEgressControlRegister_HHD_mssEgressClearGlobalTime 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressClearGlobalTime in AQ_MssEgressControlRegister_HHD */ +#define bits_AQ_MssEgressControlRegister_HHD_mssEgressClearGlobalTime u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressClearGlobalTime in AQ_MssEgressControlRegister_HHD */ +#define word_AQ_MssEgressControlRegister_HHD_mssEgressClearGlobalTime u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressClearCounter in AQ_MssEgressControlRegister_HHD */ +#define AQ_MssEgressControlRegister_HHD_mssEgressClearCounter 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressClearCounter in AQ_MssEgressControlRegister_HHD */ +#define bits_AQ_MssEgressControlRegister_HHD_mssEgressClearCounter u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressClearCounter in AQ_MssEgressControlRegister_HHD */ +#define word_AQ_MssEgressControlRegister_HHD_mssEgressClearCounter u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressHighPriority in AQ_MssEgressControlRegister_HHD */ +#define AQ_MssEgressControlRegister_HHD_mssEgressHighPriority 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressHighPriority in AQ_MssEgressControlRegister_HHD */ +#define bits_AQ_MssEgressControlRegister_HHD_mssEgressHighPriority u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressHighPriority in AQ_MssEgressControlRegister_HHD */ +#define word_AQ_MssEgressControlRegister_HHD_mssEgressHighPriority u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressIcvLsb_8BytesEnable in AQ_MssEgressControlRegister_HHD */ +#define AQ_MssEgressControlRegister_HHD_mssEgressIcvLsb_8BytesEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressIcvLsb_8BytesEnable in AQ_MssEgressControlRegister_HHD */ +#define bits_AQ_MssEgressControlRegister_HHD_mssEgressIcvLsb_8BytesEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressIcvLsb_8BytesEnable in AQ_MssEgressControlRegister_HHD */ +#define word_AQ_MssEgressControlRegister_HHD_mssEgressIcvLsb_8BytesEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressExternalClassificationEnable in AQ_MssEgressControlRegister_HHD */ +#define AQ_MssEgressControlRegister_HHD_mssEgressExternalClassificationEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressExternalClassificationEnable in AQ_MssEgressControlRegister_HHD */ +#define bits_AQ_MssEgressControlRegister_HHD_mssEgressExternalClassificationEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressExternalClassificationEnable in AQ_MssEgressControlRegister_HHD */ +#define word_AQ_MssEgressControlRegister_HHD_mssEgressExternalClassificationEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressExplicitSectagReportShortLength in AQ_MssEgressControlRegister_HHD */ +#define AQ_MssEgressControlRegister_HHD_mssEgressExplicitSectagReportShortLength 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressExplicitSectagReportShortLength in AQ_MssEgressControlRegister_HHD */ +#define bits_AQ_MssEgressControlRegister_HHD_mssEgressExplicitSectagReportShortLength u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressExplicitSectagReportShortLength in AQ_MssEgressControlRegister_HHD */ +#define word_AQ_MssEgressControlRegister_HHD_mssEgressExplicitSectagReportShortLength u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressDropInvalidSa_scPackets in AQ_MssEgressControlRegister_HHD */ +#define AQ_MssEgressControlRegister_HHD_mssEgressDropInvalidSa_scPackets 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressDropInvalidSa_scPackets in AQ_MssEgressControlRegister_HHD */ +#define bits_AQ_MssEgressControlRegister_HHD_mssEgressDropInvalidSa_scPackets u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressDropInvalidSa_scPackets in AQ_MssEgressControlRegister_HHD */ +#define word_AQ_MssEgressControlRegister_HHD_mssEgressDropInvalidSa_scPackets u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressUnmatchedUseSc_0 in AQ_MssEgressControlRegister_HHD */ +#define AQ_MssEgressControlRegister_HHD_mssEgressUnmatchedUseSc_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressUnmatchedUseSc_0 in AQ_MssEgressControlRegister_HHD */ +#define bits_AQ_MssEgressControlRegister_HHD_mssEgressUnmatchedUseSc_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressUnmatchedUseSc_0 in AQ_MssEgressControlRegister_HHD */ +#define word_AQ_MssEgressControlRegister_HHD_mssEgressUnmatchedUseSc_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgresssGcmTestMode in AQ_MssEgressControlRegister_HHD */ +#define AQ_MssEgressControlRegister_HHD_mssEgresssGcmTestMode 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgresssGcmTestMode in AQ_MssEgressControlRegister_HHD */ +#define bits_AQ_MssEgressControlRegister_HHD_mssEgresssGcmTestMode u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgresssGcmTestMode in AQ_MssEgressControlRegister_HHD */ +#define word_AQ_MssEgressControlRegister_HHD_mssEgresssGcmTestMode u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressGcmStart in AQ_MssEgressControlRegister_HHD */ +#define AQ_MssEgressControlRegister_HHD_mssEgressGcmStart 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressGcmStart in AQ_MssEgressControlRegister_HHD */ +#define bits_AQ_MssEgressControlRegister_HHD_mssEgressGcmStart u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressGcmStart in AQ_MssEgressControlRegister_HHD */ +#define word_AQ_MssEgressControlRegister_HHD_mssEgressGcmStart u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressDropEgprcLutMiss in AQ_MssEgressControlRegister_HHD */ +#define AQ_MssEgressControlRegister_HHD_mssEgressDropEgprcLutMiss 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressDropEgprcLutMiss in AQ_MssEgressControlRegister_HHD */ +#define bits_AQ_MssEgressControlRegister_HHD_mssEgressDropEgprcLutMiss u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressDropEgprcLutMiss in AQ_MssEgressControlRegister_HHD */ +#define word_AQ_MssEgressControlRegister_HHD_mssEgressDropEgprcLutMiss u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressDropKayPacket in AQ_MssEgressControlRegister_HHD */ +#define AQ_MssEgressControlRegister_HHD_mssEgressDropKayPacket 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressDropKayPacket in AQ_MssEgressControlRegister_HHD */ +#define bits_AQ_MssEgressControlRegister_HHD_mssEgressDropKayPacket u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressDropKayPacket in AQ_MssEgressControlRegister_HHD */ +#define word_AQ_MssEgressControlRegister_HHD_mssEgressDropKayPacket u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressSoftReset in AQ_MssEgressControlRegister_HHD */ +#define AQ_MssEgressControlRegister_HHD_mssEgressSoftReset 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressSoftReset in AQ_MssEgressControlRegister_HHD */ +#define bits_AQ_MssEgressControlRegister_HHD_mssEgressSoftReset u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressSoftReset in AQ_MssEgressControlRegister_HHD */ +#define word_AQ_MssEgressControlRegister_HHD_mssEgressSoftReset u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressEthertypeExplicitSectagMsb in AQ_MssEgressControlRegister_HHD */ +#define AQ_MssEgressControlRegister_HHD_mssEgressEthertypeExplicitSectagMsb 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressEthertypeExplicitSectagMsb in AQ_MssEgressControlRegister_HHD */ +#define bits_AQ_MssEgressControlRegister_HHD_mssEgressEthertypeExplicitSectagMsb u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressEthertypeExplicitSectagMsb in AQ_MssEgressControlRegister_HHD */ +#define word_AQ_MssEgressControlRegister_HHD_mssEgressEthertypeExplicitSectagMsb u1.word_1 + +/*! \brief Base register address of structure AQ_MssEgressVlanTpid_0Register_HHD */ +#define AQ_MssEgressVlanTpid_0Register_HHD_baseRegisterAddress 0x5008 +/*! \brief MMD address of structure AQ_MssEgressVlanTpid_0Register_HHD */ +#define AQ_MssEgressVlanTpid_0Register_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressVlanStagTpid in AQ_MssEgressVlanTpid_0Register_HHD */ +#define AQ_MssEgressVlanTpid_0Register_HHD_mssEgressVlanStagTpid 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressVlanStagTpid in AQ_MssEgressVlanTpid_0Register_HHD */ +#define bits_AQ_MssEgressVlanTpid_0Register_HHD_mssEgressVlanStagTpid u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressVlanStagTpid in AQ_MssEgressVlanTpid_0Register_HHD */ +#define word_AQ_MssEgressVlanTpid_0Register_HHD_mssEgressVlanStagTpid u0.word_0 + +/*! \brief Base register address of structure AQ_MssEgressVlanTpid_1Register_HHD */ +#define AQ_MssEgressVlanTpid_1Register_HHD_baseRegisterAddress 0x500A +/*! \brief MMD address of structure AQ_MssEgressVlanTpid_1Register_HHD */ +#define AQ_MssEgressVlanTpid_1Register_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressVlanQtagTpid in AQ_MssEgressVlanTpid_1Register_HHD */ +#define AQ_MssEgressVlanTpid_1Register_HHD_mssEgressVlanQtagTpid 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressVlanQtagTpid in AQ_MssEgressVlanTpid_1Register_HHD */ +#define bits_AQ_MssEgressVlanTpid_1Register_HHD_mssEgressVlanQtagTpid u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressVlanQtagTpid in AQ_MssEgressVlanTpid_1Register_HHD */ +#define word_AQ_MssEgressVlanTpid_1Register_HHD_mssEgressVlanQtagTpid u0.word_0 + +/*! \brief Base register address of structure AQ_MssEgressVlanControlRegister_HHD */ +#define AQ_MssEgressVlanControlRegister_HHD_baseRegisterAddress 0x500C +/*! \brief MMD address of structure AQ_MssEgressVlanControlRegister_HHD */ +#define AQ_MssEgressVlanControlRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressVlanUpMapTable in AQ_MssEgressVlanControlRegister_HHD */ +#define AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanUpMapTable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressVlanUpMapTable in AQ_MssEgressVlanControlRegister_HHD */ +#define bits_AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanUpMapTable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressVlanUpMapTable in AQ_MssEgressVlanControlRegister_HHD */ +#define word_AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanUpMapTable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressVlanQtagParseEnable in AQ_MssEgressVlanControlRegister_HHD */ +#define AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanQtagParseEnable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressVlanQtagParseEnable in AQ_MssEgressVlanControlRegister_HHD */ +#define bits_AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanQtagParseEnable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressVlanQtagParseEnable in AQ_MssEgressVlanControlRegister_HHD */ +#define word_AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanQtagParseEnable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressVlanStagParseEnable in AQ_MssEgressVlanControlRegister_HHD */ +#define AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanStagParseEnable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressVlanStagParseEnable in AQ_MssEgressVlanControlRegister_HHD */ +#define bits_AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanStagParseEnable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressVlanStagParseEnable in AQ_MssEgressVlanControlRegister_HHD */ +#define word_AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanStagParseEnable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressVlanQinqParseEnable in AQ_MssEgressVlanControlRegister_HHD */ +#define AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanQinqParseEnable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressVlanQinqParseEnable in AQ_MssEgressVlanControlRegister_HHD */ +#define bits_AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanQinqParseEnable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressVlanQinqParseEnable in AQ_MssEgressVlanControlRegister_HHD */ +#define word_AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanQinqParseEnable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressVlanQtagUpParseEnable in AQ_MssEgressVlanControlRegister_HHD */ +#define AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanQtagUpParseEnable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressVlanQtagUpParseEnable in AQ_MssEgressVlanControlRegister_HHD */ +#define bits_AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanQtagUpParseEnable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressVlanQtagUpParseEnable in AQ_MssEgressVlanControlRegister_HHD */ +#define word_AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanQtagUpParseEnable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressVlanStagUpParseEnable in AQ_MssEgressVlanControlRegister_HHD */ +#define AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanStagUpParseEnable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressVlanStagUpParseEnable in AQ_MssEgressVlanControlRegister_HHD */ +#define bits_AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanStagUpParseEnable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressVlanStagUpParseEnable in AQ_MssEgressVlanControlRegister_HHD */ +#define word_AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanStagUpParseEnable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressVlanUpDefault in AQ_MssEgressVlanControlRegister_HHD */ +#define AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanUpDefault 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressVlanUpDefault in AQ_MssEgressVlanControlRegister_HHD */ +#define bits_AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanUpDefault u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressVlanUpDefault in AQ_MssEgressVlanControlRegister_HHD */ +#define word_AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanUpDefault u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressVlanUpMapTableMSW in AQ_MssEgressVlanControlRegister_HHD */ +#define AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanUpMapTableMSW 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressVlanUpMapTableMSW in AQ_MssEgressVlanControlRegister_HHD */ +#define bits_AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanUpMapTableMSW u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressVlanUpMapTableMSW in AQ_MssEgressVlanControlRegister_HHD */ +#define word_AQ_MssEgressVlanControlRegister_HHD_mssEgressVlanUpMapTableMSW u1.word_1 + +/*! \brief Base register address of structure AQ_MssEgressPnControlRegister_HHD */ +#define AQ_MssEgressPnControlRegister_HHD_baseRegisterAddress 0x500E +/*! \brief MMD address of structure AQ_MssEgressPnControlRegister_HHD */ +#define AQ_MssEgressPnControlRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressSaPnThresholdLSW in AQ_MssEgressPnControlRegister_HHD */ +#define AQ_MssEgressPnControlRegister_HHD_mssEgressSaPnThresholdLSW 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressSaPnThresholdLSW in AQ_MssEgressPnControlRegister_HHD */ +#define bits_AQ_MssEgressPnControlRegister_HHD_mssEgressSaPnThresholdLSW u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressSaPnThresholdLSW in AQ_MssEgressPnControlRegister_HHD */ +#define word_AQ_MssEgressPnControlRegister_HHD_mssEgressSaPnThresholdLSW u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressSaPnThresholdMSW in AQ_MssEgressPnControlRegister_HHD */ +#define AQ_MssEgressPnControlRegister_HHD_mssEgressSaPnThresholdMSW 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressSaPnThresholdMSW in AQ_MssEgressPnControlRegister_HHD */ +#define bits_AQ_MssEgressPnControlRegister_HHD_mssEgressSaPnThresholdMSW u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressSaPnThresholdMSW in AQ_MssEgressPnControlRegister_HHD */ +#define word_AQ_MssEgressPnControlRegister_HHD_mssEgressSaPnThresholdMSW u1.word_1 + +/*! \brief Base register address of structure AQ_MssEgressMtuSizeControlRegister_HHD */ +#define AQ_MssEgressMtuSizeControlRegister_HHD_baseRegisterAddress 0x5010 +/*! \brief MMD address of structure AQ_MssEgressMtuSizeControlRegister_HHD */ +#define AQ_MssEgressMtuSizeControlRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressControlledPacketMtuSize in AQ_MssEgressMtuSizeControlRegister_HHD */ +#define AQ_MssEgressMtuSizeControlRegister_HHD_mssEgressControlledPacketMtuSize 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressControlledPacketMtuSize in AQ_MssEgressMtuSizeControlRegister_HHD */ +#define bits_AQ_MssEgressMtuSizeControlRegister_HHD_mssEgressControlledPacketMtuSize u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressControlledPacketMtuSize in AQ_MssEgressMtuSizeControlRegister_HHD */ +#define word_AQ_MssEgressMtuSizeControlRegister_HHD_mssEgressControlledPacketMtuSize u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressUncontrolledPacketMtuSize in AQ_MssEgressMtuSizeControlRegister_HHD */ +#define AQ_MssEgressMtuSizeControlRegister_HHD_mssEgressUncontrolledPacketMtuSize 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressUncontrolledPacketMtuSize in AQ_MssEgressMtuSizeControlRegister_HHD */ +#define bits_AQ_MssEgressMtuSizeControlRegister_HHD_mssEgressUncontrolledPacketMtuSize u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressUncontrolledPacketMtuSize in AQ_MssEgressMtuSizeControlRegister_HHD */ +#define word_AQ_MssEgressMtuSizeControlRegister_HHD_mssEgressUncontrolledPacketMtuSize u1.word_1 + +/*! \brief Base register address of structure AQ_MssEgressInterruptStatusRegister_HHD */ +#define AQ_MssEgressInterruptStatusRegister_HHD_baseRegisterAddress 0x505C +/*! \brief MMD address of structure AQ_MssEgressInterruptStatusRegister_HHD */ +#define AQ_MssEgressInterruptStatusRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressEccErrorInterrupt in AQ_MssEgressInterruptStatusRegister_HHD */ +#define AQ_MssEgressInterruptStatusRegister_HHD_mssEgressEccErrorInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressEccErrorInterrupt in AQ_MssEgressInterruptStatusRegister_HHD */ +#define bits_AQ_MssEgressInterruptStatusRegister_HHD_mssEgressEccErrorInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressEccErrorInterrupt in AQ_MssEgressInterruptStatusRegister_HHD */ +#define word_AQ_MssEgressInterruptStatusRegister_HHD_mssEgressEccErrorInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressMibSaturationInterrupt in AQ_MssEgressInterruptStatusRegister_HHD */ +#define AQ_MssEgressInterruptStatusRegister_HHD_mssEgressMibSaturationInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressMibSaturationInterrupt in AQ_MssEgressInterruptStatusRegister_HHD */ +#define bits_AQ_MssEgressInterruptStatusRegister_HHD_mssEgressMibSaturationInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressMibSaturationInterrupt in AQ_MssEgressInterruptStatusRegister_HHD */ +#define word_AQ_MssEgressInterruptStatusRegister_HHD_mssEgressMibSaturationInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressSaThresholdExpiredInterrupt in AQ_MssEgressInterruptStatusRegister_HHD */ +#define AQ_MssEgressInterruptStatusRegister_HHD_mssEgressSaThresholdExpiredInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressSaThresholdExpiredInterrupt in AQ_MssEgressInterruptStatusRegister_HHD */ +#define bits_AQ_MssEgressInterruptStatusRegister_HHD_mssEgressSaThresholdExpiredInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressSaThresholdExpiredInterrupt in AQ_MssEgressInterruptStatusRegister_HHD */ +#define word_AQ_MssEgressInterruptStatusRegister_HHD_mssEgressSaThresholdExpiredInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressSaExpiredInterrupt in AQ_MssEgressInterruptStatusRegister_HHD */ +#define AQ_MssEgressInterruptStatusRegister_HHD_mssEgressSaExpiredInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressSaExpiredInterrupt in AQ_MssEgressInterruptStatusRegister_HHD */ +#define bits_AQ_MssEgressInterruptStatusRegister_HHD_mssEgressSaExpiredInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressSaExpiredInterrupt in AQ_MssEgressInterruptStatusRegister_HHD */ +#define word_AQ_MssEgressInterruptStatusRegister_HHD_mssEgressSaExpiredInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressMasterInterrupt in AQ_MssEgressInterruptStatusRegister_HHD */ +#define AQ_MssEgressInterruptStatusRegister_HHD_mssEgressMasterInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressMasterInterrupt in AQ_MssEgressInterruptStatusRegister_HHD */ +#define bits_AQ_MssEgressInterruptStatusRegister_HHD_mssEgressMasterInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressMasterInterrupt in AQ_MssEgressInterruptStatusRegister_HHD */ +#define word_AQ_MssEgressInterruptStatusRegister_HHD_mssEgressMasterInterrupt u0.word_0 + +/*! \brief Base register address of structure AQ_MssEgressInterruptMaskRegister_HHD */ +#define AQ_MssEgressInterruptMaskRegister_HHD_baseRegisterAddress 0x505E +/*! \brief MMD address of structure AQ_MssEgressInterruptMaskRegister_HHD */ +#define AQ_MssEgressInterruptMaskRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressEccErrorInterruptEnable in AQ_MssEgressInterruptMaskRegister_HHD */ +#define AQ_MssEgressInterruptMaskRegister_HHD_mssEgressEccErrorInterruptEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressEccErrorInterruptEnable in AQ_MssEgressInterruptMaskRegister_HHD */ +#define bits_AQ_MssEgressInterruptMaskRegister_HHD_mssEgressEccErrorInterruptEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressEccErrorInterruptEnable in AQ_MssEgressInterruptMaskRegister_HHD */ +#define word_AQ_MssEgressInterruptMaskRegister_HHD_mssEgressEccErrorInterruptEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressMibSaturationInterruptEnable in AQ_MssEgressInterruptMaskRegister_HHD */ +#define AQ_MssEgressInterruptMaskRegister_HHD_mssEgressMibSaturationInterruptEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressMibSaturationInterruptEnable in AQ_MssEgressInterruptMaskRegister_HHD */ +#define bits_AQ_MssEgressInterruptMaskRegister_HHD_mssEgressMibSaturationInterruptEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressMibSaturationInterruptEnable in AQ_MssEgressInterruptMaskRegister_HHD */ +#define word_AQ_MssEgressInterruptMaskRegister_HHD_mssEgressMibSaturationInterruptEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressSaExpiredThresholdInterruptEnable in AQ_MssEgressInterruptMaskRegister_HHD */ +#define AQ_MssEgressInterruptMaskRegister_HHD_mssEgressSaExpiredThresholdInterruptEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressSaExpiredThresholdInterruptEnable in AQ_MssEgressInterruptMaskRegister_HHD */ +#define bits_AQ_MssEgressInterruptMaskRegister_HHD_mssEgressSaExpiredThresholdInterruptEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressSaExpiredThresholdInterruptEnable in AQ_MssEgressInterruptMaskRegister_HHD */ +#define word_AQ_MssEgressInterruptMaskRegister_HHD_mssEgressSaExpiredThresholdInterruptEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressSaExpiredInterruptEnable in AQ_MssEgressInterruptMaskRegister_HHD */ +#define AQ_MssEgressInterruptMaskRegister_HHD_mssEgressSaExpiredInterruptEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressSaExpiredInterruptEnable in AQ_MssEgressInterruptMaskRegister_HHD */ +#define bits_AQ_MssEgressInterruptMaskRegister_HHD_mssEgressSaExpiredInterruptEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressSaExpiredInterruptEnable in AQ_MssEgressInterruptMaskRegister_HHD */ +#define word_AQ_MssEgressInterruptMaskRegister_HHD_mssEgressSaExpiredInterruptEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressMasterInterruptEnable in AQ_MssEgressInterruptMaskRegister_HHD */ +#define AQ_MssEgressInterruptMaskRegister_HHD_mssEgressMasterInterruptEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressMasterInterruptEnable in AQ_MssEgressInterruptMaskRegister_HHD */ +#define bits_AQ_MssEgressInterruptMaskRegister_HHD_mssEgressMasterInterruptEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressMasterInterruptEnable in AQ_MssEgressInterruptMaskRegister_HHD */ +#define word_AQ_MssEgressInterruptMaskRegister_HHD_mssEgressMasterInterruptEnable u0.word_0 + +/*! \brief Base register address of structure AQ_MssEgressSaExpiredStatusRegister_HHD */ +#define AQ_MssEgressSaExpiredStatusRegister_HHD_baseRegisterAddress 0x5060 +/*! \brief MMD address of structure AQ_MssEgressSaExpiredStatusRegister_HHD */ +#define AQ_MssEgressSaExpiredStatusRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressSaExpiredLSW in AQ_MssEgressSaExpiredStatusRegister_HHD */ +#define AQ_MssEgressSaExpiredStatusRegister_HHD_mssEgressSaExpiredLSW 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressSaExpiredLSW in AQ_MssEgressSaExpiredStatusRegister_HHD */ +#define bits_AQ_MssEgressSaExpiredStatusRegister_HHD_mssEgressSaExpiredLSW u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressSaExpiredLSW in AQ_MssEgressSaExpiredStatusRegister_HHD */ +#define word_AQ_MssEgressSaExpiredStatusRegister_HHD_mssEgressSaExpiredLSW u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressSaExpiredMSW in AQ_MssEgressSaExpiredStatusRegister_HHD */ +#define AQ_MssEgressSaExpiredStatusRegister_HHD_mssEgressSaExpiredMSW 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressSaExpiredMSW in AQ_MssEgressSaExpiredStatusRegister_HHD */ +#define bits_AQ_MssEgressSaExpiredStatusRegister_HHD_mssEgressSaExpiredMSW u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressSaExpiredMSW in AQ_MssEgressSaExpiredStatusRegister_HHD */ +#define word_AQ_MssEgressSaExpiredStatusRegister_HHD_mssEgressSaExpiredMSW u1.word_1 + +/*! \brief Base register address of structure AQ_MssEgressSaThresholdExpiredStatusRegister_HHD */ +#define AQ_MssEgressSaThresholdExpiredStatusRegister_HHD_baseRegisterAddress 0x5062 +/*! \brief MMD address of structure AQ_MssEgressSaThresholdExpiredStatusRegister_HHD */ +#define AQ_MssEgressSaThresholdExpiredStatusRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressSaThresholdExpiredLSW in AQ_MssEgressSaThresholdExpiredStatusRegister_HHD */ +#define AQ_MssEgressSaThresholdExpiredStatusRegister_HHD_mssEgressSaThresholdExpiredLSW 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressSaThresholdExpiredLSW in AQ_MssEgressSaThresholdExpiredStatusRegister_HHD */ +#define bits_AQ_MssEgressSaThresholdExpiredStatusRegister_HHD_mssEgressSaThresholdExpiredLSW u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressSaThresholdExpiredLSW in AQ_MssEgressSaThresholdExpiredStatusRegister_HHD */ +#define word_AQ_MssEgressSaThresholdExpiredStatusRegister_HHD_mssEgressSaThresholdExpiredLSW u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressSaThresholdExpiredMSW in AQ_MssEgressSaThresholdExpiredStatusRegister_HHD */ +#define AQ_MssEgressSaThresholdExpiredStatusRegister_HHD_mssEgressSaThresholdExpiredMSW 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressSaThresholdExpiredMSW in AQ_MssEgressSaThresholdExpiredStatusRegister_HHD */ +#define bits_AQ_MssEgressSaThresholdExpiredStatusRegister_HHD_mssEgressSaThresholdExpiredMSW u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressSaThresholdExpiredMSW in AQ_MssEgressSaThresholdExpiredStatusRegister_HHD */ +#define word_AQ_MssEgressSaThresholdExpiredStatusRegister_HHD_mssEgressSaThresholdExpiredMSW u1.word_1 + +/*! \brief Base register address of structure AQ_MssEgressEccInterruptStatusRegister_HHD */ +#define AQ_MssEgressEccInterruptStatusRegister_HHD_baseRegisterAddress 0x5064 +/*! \brief MMD address of structure AQ_MssEgressEccInterruptStatusRegister_HHD */ +#define AQ_MssEgressEccInterruptStatusRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressSaEccErrorInterruptLSW in AQ_MssEgressEccInterruptStatusRegister_HHD */ +#define AQ_MssEgressEccInterruptStatusRegister_HHD_mssEgressSaEccErrorInterruptLSW 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressSaEccErrorInterruptLSW in AQ_MssEgressEccInterruptStatusRegister_HHD */ +#define bits_AQ_MssEgressEccInterruptStatusRegister_HHD_mssEgressSaEccErrorInterruptLSW u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressSaEccErrorInterruptLSW in AQ_MssEgressEccInterruptStatusRegister_HHD */ +#define word_AQ_MssEgressEccInterruptStatusRegister_HHD_mssEgressSaEccErrorInterruptLSW u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressSaEccErrorInterruptMSW in AQ_MssEgressEccInterruptStatusRegister_HHD */ +#define AQ_MssEgressEccInterruptStatusRegister_HHD_mssEgressSaEccErrorInterruptMSW 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressSaEccErrorInterruptMSW in AQ_MssEgressEccInterruptStatusRegister_HHD */ +#define bits_AQ_MssEgressEccInterruptStatusRegister_HHD_mssEgressSaEccErrorInterruptMSW u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressSaEccErrorInterruptMSW in AQ_MssEgressEccInterruptStatusRegister_HHD */ +#define word_AQ_MssEgressEccInterruptStatusRegister_HHD_mssEgressSaEccErrorInterruptMSW u1.word_1 + +/*! \brief Base register address of structure AQ_MssEgressLutAddressControlRegister_HHD */ +#define AQ_MssEgressLutAddressControlRegister_HHD_baseRegisterAddress 0x5080 +/*! \brief MMD address of structure AQ_MssEgressLutAddressControlRegister_HHD */ +#define AQ_MssEgressLutAddressControlRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutSelect in AQ_MssEgressLutAddressControlRegister_HHD */ +#define AQ_MssEgressLutAddressControlRegister_HHD_mssEgressLutSelect 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutSelect in AQ_MssEgressLutAddressControlRegister_HHD */ +#define bits_AQ_MssEgressLutAddressControlRegister_HHD_mssEgressLutSelect u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutSelect in AQ_MssEgressLutAddressControlRegister_HHD */ +#define word_AQ_MssEgressLutAddressControlRegister_HHD_mssEgressLutSelect u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutAddress in AQ_MssEgressLutAddressControlRegister_HHD */ +#define AQ_MssEgressLutAddressControlRegister_HHD_mssEgressLutAddress 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutAddress in AQ_MssEgressLutAddressControlRegister_HHD */ +#define bits_AQ_MssEgressLutAddressControlRegister_HHD_mssEgressLutAddress u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutAddress in AQ_MssEgressLutAddressControlRegister_HHD */ +#define word_AQ_MssEgressLutAddressControlRegister_HHD_mssEgressLutAddress u0.word_0 + +/*! \brief Base register address of structure AQ_MssEgressLutControlRegister_HHD */ +#define AQ_MssEgressLutControlRegister_HHD_baseRegisterAddress 0x5081 +/*! \brief MMD address of structure AQ_MssEgressLutControlRegister_HHD */ +#define AQ_MssEgressLutControlRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutWrite in AQ_MssEgressLutControlRegister_HHD */ +#define AQ_MssEgressLutControlRegister_HHD_mssEgressLutWrite 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutWrite in AQ_MssEgressLutControlRegister_HHD */ +#define bits_AQ_MssEgressLutControlRegister_HHD_mssEgressLutWrite u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutWrite in AQ_MssEgressLutControlRegister_HHD */ +#define word_AQ_MssEgressLutControlRegister_HHD_mssEgressLutWrite u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutRead in AQ_MssEgressLutControlRegister_HHD */ +#define AQ_MssEgressLutControlRegister_HHD_mssEgressLutRead 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutRead in AQ_MssEgressLutControlRegister_HHD */ +#define bits_AQ_MssEgressLutControlRegister_HHD_mssEgressLutRead u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutRead in AQ_MssEgressLutControlRegister_HHD */ +#define word_AQ_MssEgressLutControlRegister_HHD_mssEgressLutRead u0.word_0 + +/*! \brief Base register address of structure AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_baseRegisterAddress 0x50A0 +/*! \brief MMD address of structure AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_0 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_0 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_0 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_1 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_1 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_1 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_1 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_2 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_2 2 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_2 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_2 u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_2 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_2 u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_3 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_3 3 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_3 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_3 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_3 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_3 u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_4 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_4 4 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_4 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_4 u4.bits_4 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_4 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_4 u4.word_4 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_5 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_5 5 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_5 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_5 u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_5 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_5 u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_6 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_6 6 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_6 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_6 u6.bits_6 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_6 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_6 u6.word_6 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_7 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_7 7 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_7 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_7 u7.bits_7 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_7 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_7 u7.word_7 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_8 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_8 8 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_8 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_8 u8.bits_8 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_8 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_8 u8.word_8 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_9 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_9 9 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_9 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_9 u9.bits_9 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_9 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_9 u9.word_9 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_10 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_10 10 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_10 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_10 u10.bits_10 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_10 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_10 u10.word_10 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_11 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_11 11 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_11 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_11 u11.bits_11 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_11 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_11 u11.word_11 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_12 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_12 12 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_12 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_12 u12.bits_12 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_12 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_12 u12.word_12 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_13 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_13 13 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_13 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_13 u13.bits_13 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_13 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_13 u13.word_13 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_14 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_14 14 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_14 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_14 u14.bits_14 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_14 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_14 u14.word_14 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_15 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_15 15 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_15 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_15 u15.bits_15 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_15 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_15 u15.word_15 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_16 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_16 16 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_16 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_16 u16.bits_16 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_16 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_16 u16.word_16 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_17 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_17 17 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_17 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_17 u17.bits_17 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_17 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_17 u17.word_17 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_18 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_18 18 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_18 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_18 u18.bits_18 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_18 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_18 u18.word_18 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_19 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_19 19 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_19 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_19 u19.bits_19 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_19 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_19 u19.word_19 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_20 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_20 20 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_20 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_20 u20.bits_20 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_20 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_20 u20.word_20 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_21 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_21 21 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_21 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_21 u21.bits_21 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_21 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_21 u21.word_21 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_22 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_22 22 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_22 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_22 u22.bits_22 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_22 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_22 u22.word_22 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_23 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_23 23 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_23 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_23 u23.bits_23 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_23 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_23 u23.word_23 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_24 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_24 24 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_24 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_24 u24.bits_24 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_24 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_24 u24.word_24 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_25 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_25 25 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_25 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_25 u25.bits_25 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_25 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_25 u25.word_25 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_26 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_26 26 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_26 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_26 u26.bits_26 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_26 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_26 u26.word_26 +/*! \brief Preprocessor variable to relate field to word number in structure mssEgressLutData_27 in AQ_MssEgressLutDataControlRegister_HHD */ +#define AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_27 27 +/*! \brief Preprocessor variable to relate field to bit position in structure mssEgressLutData_27 in AQ_MssEgressLutDataControlRegister_HHD */ +#define bits_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_27 u27.bits_27 +/*! \brief Preprocessor variable to relate field to word position in structure mssEgressLutData_27 in AQ_MssEgressLutDataControlRegister_HHD */ +#define word_AQ_MssEgressLutDataControlRegister_HHD_mssEgressLutData_27 u27.word_27 + +/*! \brief Base register address of structure AQ_MsmSystemGeneralControlRegister_HHD */ +#define AQ_MsmSystemGeneralControlRegister_HHD_baseRegisterAddress 0x6004 +/*! \brief MMD address of structure AQ_MsmSystemGeneralControlRegister_HHD */ +#define AQ_MsmSystemGeneralControlRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemPhyTxEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define AQ_MsmSystemGeneralControlRegister_HHD_msmSystemPhyTxEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemPhyTxEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define bits_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemPhyTxEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemPhyTxEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define word_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemPhyTxEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxErrorDiscard in AQ_MsmSystemGeneralControlRegister_HHD */ +#define AQ_MsmSystemGeneralControlRegister_HHD_msmSystemRxErrorDiscard 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxErrorDiscard in AQ_MsmSystemGeneralControlRegister_HHD */ +#define bits_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemRxErrorDiscard u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxErrorDiscard in AQ_MsmSystemGeneralControlRegister_HHD */ +#define word_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemRxErrorDiscard u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemControlFrameEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define AQ_MsmSystemGeneralControlRegister_HHD_msmSystemControlFrameEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemControlFrameEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define bits_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemControlFrameEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemControlFrameEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define word_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemControlFrameEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemSoftReset in AQ_MsmSystemGeneralControlRegister_HHD */ +#define AQ_MsmSystemGeneralControlRegister_HHD_msmSystemSoftReset 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemSoftReset in AQ_MsmSystemGeneralControlRegister_HHD */ +#define bits_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemSoftReset u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemSoftReset in AQ_MsmSystemGeneralControlRegister_HHD */ +#define word_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemSoftReset u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxPadEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define AQ_MsmSystemGeneralControlRegister_HHD_msmSystemTxPadEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxPadEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define bits_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemTxPadEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxPadEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define word_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemTxPadEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxCrcAppend in AQ_MsmSystemGeneralControlRegister_HHD */ +#define AQ_MsmSystemGeneralControlRegister_HHD_msmSystemTxCrcAppend 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxCrcAppend in AQ_MsmSystemGeneralControlRegister_HHD */ +#define bits_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemTxCrcAppend u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxCrcAppend in AQ_MsmSystemGeneralControlRegister_HHD */ +#define word_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemTxCrcAppend u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxAddressInsertEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define AQ_MsmSystemGeneralControlRegister_HHD_msmSystemTxAddressInsertEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxAddressInsertEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define bits_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemTxAddressInsertEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxAddressInsertEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define word_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemTxAddressInsertEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemPauseIgnore in AQ_MsmSystemGeneralControlRegister_HHD */ +#define AQ_MsmSystemGeneralControlRegister_HHD_msmSystemPauseIgnore 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemPauseIgnore in AQ_MsmSystemGeneralControlRegister_HHD */ +#define bits_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemPauseIgnore u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemPauseIgnore in AQ_MsmSystemGeneralControlRegister_HHD */ +#define word_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemPauseIgnore u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemPauseForward in AQ_MsmSystemGeneralControlRegister_HHD */ +#define AQ_MsmSystemGeneralControlRegister_HHD_msmSystemPauseForward 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemPauseForward in AQ_MsmSystemGeneralControlRegister_HHD */ +#define bits_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemPauseForward u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemPauseForward in AQ_MsmSystemGeneralControlRegister_HHD */ +#define word_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemPauseForward u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemCrcForward in AQ_MsmSystemGeneralControlRegister_HHD */ +#define AQ_MsmSystemGeneralControlRegister_HHD_msmSystemCrcForward 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemCrcForward in AQ_MsmSystemGeneralControlRegister_HHD */ +#define bits_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemCrcForward u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemCrcForward in AQ_MsmSystemGeneralControlRegister_HHD */ +#define word_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemCrcForward u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemPadEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define AQ_MsmSystemGeneralControlRegister_HHD_msmSystemPadEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemPadEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define bits_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemPadEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemPadEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define word_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemPadEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemPromiscuousMode in AQ_MsmSystemGeneralControlRegister_HHD */ +#define AQ_MsmSystemGeneralControlRegister_HHD_msmSystemPromiscuousMode 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemPromiscuousMode in AQ_MsmSystemGeneralControlRegister_HHD */ +#define bits_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemPromiscuousMode u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemPromiscuousMode in AQ_MsmSystemGeneralControlRegister_HHD */ +#define word_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemPromiscuousMode u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemWanMode in AQ_MsmSystemGeneralControlRegister_HHD */ +#define AQ_MsmSystemGeneralControlRegister_HHD_msmSystemWanMode 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemWanMode in AQ_MsmSystemGeneralControlRegister_HHD */ +#define bits_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemWanMode u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemWanMode in AQ_MsmSystemGeneralControlRegister_HHD */ +#define word_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemWanMode u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define AQ_MsmSystemGeneralControlRegister_HHD_msmSystemRxEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define bits_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemRxEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define word_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemRxEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define AQ_MsmSystemGeneralControlRegister_HHD_msmSystemTxEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define bits_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemTxEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define word_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemTxEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxLowPowerIdleEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define AQ_MsmSystemGeneralControlRegister_HHD_msmSystemTxLowPowerIdleEnable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxLowPowerIdleEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define bits_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemTxLowPowerIdleEnable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxLowPowerIdleEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define word_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemTxLowPowerIdleEnable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemSfdCheckDisable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define AQ_MsmSystemGeneralControlRegister_HHD_msmSystemSfdCheckDisable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemSfdCheckDisable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define bits_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemSfdCheckDisable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemSfdCheckDisable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define word_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemSfdCheckDisable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemPriorityFlowControlEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define AQ_MsmSystemGeneralControlRegister_HHD_msmSystemPriorityFlowControlEnable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemPriorityFlowControlEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define bits_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemPriorityFlowControlEnable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemPriorityFlowControlEnable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define word_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemPriorityFlowControlEnable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemIdleColumnCountExtend in AQ_MsmSystemGeneralControlRegister_HHD */ +#define AQ_MsmSystemGeneralControlRegister_HHD_msmSystemIdleColumnCountExtend 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemIdleColumnCountExtend in AQ_MsmSystemGeneralControlRegister_HHD */ +#define bits_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemIdleColumnCountExtend u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemIdleColumnCountExtend in AQ_MsmSystemGeneralControlRegister_HHD */ +#define word_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemIdleColumnCountExtend u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemLengthCheckDisable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define AQ_MsmSystemGeneralControlRegister_HHD_msmSystemLengthCheckDisable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemLengthCheckDisable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define bits_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemLengthCheckDisable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemLengthCheckDisable in AQ_MsmSystemGeneralControlRegister_HHD */ +#define word_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemLengthCheckDisable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemForceSendIdle in AQ_MsmSystemGeneralControlRegister_HHD */ +#define AQ_MsmSystemGeneralControlRegister_HHD_msmSystemForceSendIdle 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemForceSendIdle in AQ_MsmSystemGeneralControlRegister_HHD */ +#define bits_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemForceSendIdle u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemForceSendIdle in AQ_MsmSystemGeneralControlRegister_HHD */ +#define word_AQ_MsmSystemGeneralControlRegister_HHD_msmSystemForceSendIdle u1.word_1 + +/*! \brief Base register address of structure AQ_MsmSystemFifoControlRegister_HHD */ +#define AQ_MsmSystemFifoControlRegister_HHD_baseRegisterAddress 0x600E +/*! \brief MMD address of structure AQ_MsmSystemFifoControlRegister_HHD */ +#define AQ_MsmSystemFifoControlRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxFifoFullThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define AQ_MsmSystemFifoControlRegister_HHD_msmSystemRxFifoFullThreshold 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxFifoFullThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define bits_AQ_MsmSystemFifoControlRegister_HHD_msmSystemRxFifoFullThreshold u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxFifoFullThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define word_AQ_MsmSystemFifoControlRegister_HHD_msmSystemRxFifoFullThreshold u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxFifoEmptyThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define AQ_MsmSystemFifoControlRegister_HHD_msmSystemRxFifoEmptyThreshold 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxFifoEmptyThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define bits_AQ_MsmSystemFifoControlRegister_HHD_msmSystemRxFifoEmptyThreshold u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxFifoEmptyThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define word_AQ_MsmSystemFifoControlRegister_HHD_msmSystemRxFifoEmptyThreshold u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxFifoFullThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define AQ_MsmSystemFifoControlRegister_HHD_msmSystemTxFifoFullThreshold 2 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxFifoFullThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define bits_AQ_MsmSystemFifoControlRegister_HHD_msmSystemTxFifoFullThreshold u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxFifoFullThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define word_AQ_MsmSystemFifoControlRegister_HHD_msmSystemTxFifoFullThreshold u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxFifoEmptyThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define AQ_MsmSystemFifoControlRegister_HHD_msmSystemTxFifoEmptyThreshold 3 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxFifoEmptyThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define bits_AQ_MsmSystemFifoControlRegister_HHD_msmSystemTxFifoEmptyThreshold u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxFifoEmptyThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define word_AQ_MsmSystemFifoControlRegister_HHD_msmSystemTxFifoEmptyThreshold u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxFifoAlmostFullThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define AQ_MsmSystemFifoControlRegister_HHD_msmSystemRxFifoAlmostFullThreshold 4 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxFifoAlmostFullThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define bits_AQ_MsmSystemFifoControlRegister_HHD_msmSystemRxFifoAlmostFullThreshold u4.bits_4 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxFifoAlmostFullThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define word_AQ_MsmSystemFifoControlRegister_HHD_msmSystemRxFifoAlmostFullThreshold u4.word_4 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxFifoAlmostEmptyThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define AQ_MsmSystemFifoControlRegister_HHD_msmSystemRxFifoAlmostEmptyThreshold 5 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxFifoAlmostEmptyThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define bits_AQ_MsmSystemFifoControlRegister_HHD_msmSystemRxFifoAlmostEmptyThreshold u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxFifoAlmostEmptyThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define word_AQ_MsmSystemFifoControlRegister_HHD_msmSystemRxFifoAlmostEmptyThreshold u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxFifoAlmostFullThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define AQ_MsmSystemFifoControlRegister_HHD_msmSystemTxFifoAlmostFullThreshold 6 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxFifoAlmostFullThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define bits_AQ_MsmSystemFifoControlRegister_HHD_msmSystemTxFifoAlmostFullThreshold u6.bits_6 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxFifoAlmostFullThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define word_AQ_MsmSystemFifoControlRegister_HHD_msmSystemTxFifoAlmostFullThreshold u6.word_6 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxFifoAlmostEmptyThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define AQ_MsmSystemFifoControlRegister_HHD_msmSystemTxFifoAlmostEmptyThreshold 7 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxFifoAlmostEmptyThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define bits_AQ_MsmSystemFifoControlRegister_HHD_msmSystemTxFifoAlmostEmptyThreshold u7.bits_7 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxFifoAlmostEmptyThreshold in AQ_MsmSystemFifoControlRegister_HHD */ +#define word_AQ_MsmSystemFifoControlRegister_HHD_msmSystemTxFifoAlmostEmptyThreshold u7.word_7 + +/*! \brief Base register address of structure AQ_MsmSystemGeneralStatusRegister_HHD */ +#define AQ_MsmSystemGeneralStatusRegister_HHD_baseRegisterAddress 0x6020 +/*! \brief MMD address of structure AQ_MsmSystemGeneralStatusRegister_HHD */ +#define AQ_MsmSystemGeneralStatusRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxFifoEmpty in AQ_MsmSystemGeneralStatusRegister_HHD */ +#define AQ_MsmSystemGeneralStatusRegister_HHD_msmSystemTxFifoEmpty 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxFifoEmpty in AQ_MsmSystemGeneralStatusRegister_HHD */ +#define bits_AQ_MsmSystemGeneralStatusRegister_HHD_msmSystemTxFifoEmpty u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxFifoEmpty in AQ_MsmSystemGeneralStatusRegister_HHD */ +#define word_AQ_MsmSystemGeneralStatusRegister_HHD_msmSystemTxFifoEmpty u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxLowPowerIdle in AQ_MsmSystemGeneralStatusRegister_HHD */ +#define AQ_MsmSystemGeneralStatusRegister_HHD_msmSystemRxLowPowerIdle 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxLowPowerIdle in AQ_MsmSystemGeneralStatusRegister_HHD */ +#define bits_AQ_MsmSystemGeneralStatusRegister_HHD_msmSystemRxLowPowerIdle u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxLowPowerIdle in AQ_MsmSystemGeneralStatusRegister_HHD */ +#define word_AQ_MsmSystemGeneralStatusRegister_HHD_msmSystemRxLowPowerIdle u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTimestampAvailable in AQ_MsmSystemGeneralStatusRegister_HHD */ +#define AQ_MsmSystemGeneralStatusRegister_HHD_msmSystemTimestampAvailable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTimestampAvailable in AQ_MsmSystemGeneralStatusRegister_HHD */ +#define bits_AQ_MsmSystemGeneralStatusRegister_HHD_msmSystemTimestampAvailable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTimestampAvailable in AQ_MsmSystemGeneralStatusRegister_HHD */ +#define word_AQ_MsmSystemGeneralStatusRegister_HHD_msmSystemTimestampAvailable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemPhyLossOfSignal in AQ_MsmSystemGeneralStatusRegister_HHD */ +#define AQ_MsmSystemGeneralStatusRegister_HHD_msmSystemPhyLossOfSignal 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemPhyLossOfSignal in AQ_MsmSystemGeneralStatusRegister_HHD */ +#define bits_AQ_MsmSystemGeneralStatusRegister_HHD_msmSystemPhyLossOfSignal u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemPhyLossOfSignal in AQ_MsmSystemGeneralStatusRegister_HHD */ +#define word_AQ_MsmSystemGeneralStatusRegister_HHD_msmSystemPhyLossOfSignal u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxRemoteFault in AQ_MsmSystemGeneralStatusRegister_HHD */ +#define AQ_MsmSystemGeneralStatusRegister_HHD_msmSystemRxRemoteFault 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxRemoteFault in AQ_MsmSystemGeneralStatusRegister_HHD */ +#define bits_AQ_MsmSystemGeneralStatusRegister_HHD_msmSystemRxRemoteFault u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxRemoteFault in AQ_MsmSystemGeneralStatusRegister_HHD */ +#define word_AQ_MsmSystemGeneralStatusRegister_HHD_msmSystemRxRemoteFault u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxLocalFault in AQ_MsmSystemGeneralStatusRegister_HHD */ +#define AQ_MsmSystemGeneralStatusRegister_HHD_msmSystemRxLocalFault 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxLocalFault in AQ_MsmSystemGeneralStatusRegister_HHD */ +#define bits_AQ_MsmSystemGeneralStatusRegister_HHD_msmSystemRxLocalFault u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxLocalFault in AQ_MsmSystemGeneralStatusRegister_HHD */ +#define word_AQ_MsmSystemGeneralStatusRegister_HHD_msmSystemRxLocalFault u0.word_0 + +/*! \brief Base register address of structure AQ_MsmSystemTxIpgControlRegister_HHD */ +#define AQ_MsmSystemTxIpgControlRegister_HHD_baseRegisterAddress 0x6022 +/*! \brief MMD address of structure AQ_MsmSystemTxIpgControlRegister_HHD */ +#define AQ_MsmSystemTxIpgControlRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxIpgLength in AQ_MsmSystemTxIpgControlRegister_HHD */ +#define AQ_MsmSystemTxIpgControlRegister_HHD_msmSystemTxIpgLength 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxIpgLength in AQ_MsmSystemTxIpgControlRegister_HHD */ +#define bits_AQ_MsmSystemTxIpgControlRegister_HHD_msmSystemTxIpgLength u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxIpgLength in AQ_MsmSystemTxIpgControlRegister_HHD */ +#define word_AQ_MsmSystemTxIpgControlRegister_HHD_msmSystemTxIpgLength u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxIpgReserved in AQ_MsmSystemTxIpgControlRegister_HHD */ +#define AQ_MsmSystemTxIpgControlRegister_HHD_msmSystemTxIpgReserved 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxIpgReserved in AQ_MsmSystemTxIpgControlRegister_HHD */ +#define bits_AQ_MsmSystemTxIpgControlRegister_HHD_msmSystemTxIpgReserved u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxIpgReserved in AQ_MsmSystemTxIpgControlRegister_HHD */ +#define word_AQ_MsmSystemTxIpgControlRegister_HHD_msmSystemTxIpgReserved u1.word_1 + +/*! \brief Base register address of structure AQ_MsmSystemTxGoodFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxGoodFramesCounterRegister_HHD_baseRegisterAddress 0x6040 +/*! \brief MMD address of structure AQ_MsmSystemTxGoodFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxGoodFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxGoodFramesCounter_0 in AQ_MsmSystemTxGoodFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxGoodFramesCounterRegister_HHD_msmSystemTxGoodFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxGoodFramesCounter_0 in AQ_MsmSystemTxGoodFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemTxGoodFramesCounterRegister_HHD_msmSystemTxGoodFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxGoodFramesCounter_0 in AQ_MsmSystemTxGoodFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemTxGoodFramesCounterRegister_HHD_msmSystemTxGoodFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxGoodFramesCounter_1 in AQ_MsmSystemTxGoodFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxGoodFramesCounterRegister_HHD_msmSystemTxGoodFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxGoodFramesCounter_1 in AQ_MsmSystemTxGoodFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemTxGoodFramesCounterRegister_HHD_msmSystemTxGoodFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxGoodFramesCounter_1 in AQ_MsmSystemTxGoodFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemTxGoodFramesCounterRegister_HHD_msmSystemTxGoodFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmSystemRxGoodFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxGoodFramesCounterRegister_HHD_baseRegisterAddress 0x6044 +/*! \brief MMD address of structure AQ_MsmSystemRxGoodFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxGoodFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxGoodFramesCounter_0 in AQ_MsmSystemRxGoodFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxGoodFramesCounterRegister_HHD_msmSystemRxGoodFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxGoodFramesCounter_0 in AQ_MsmSystemRxGoodFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxGoodFramesCounterRegister_HHD_msmSystemRxGoodFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxGoodFramesCounter_0 in AQ_MsmSystemRxGoodFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemRxGoodFramesCounterRegister_HHD_msmSystemRxGoodFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxGoodFramesCounter_1 in AQ_MsmSystemRxGoodFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxGoodFramesCounterRegister_HHD_msmSystemRxGoodFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxGoodFramesCounter_1 in AQ_MsmSystemRxGoodFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxGoodFramesCounterRegister_HHD_msmSystemRxGoodFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxGoodFramesCounter_1 in AQ_MsmSystemRxGoodFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemRxGoodFramesCounterRegister_HHD_msmSystemRxGoodFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmSystemRxFcsErrorsCounterRegister_HHD */ +#define AQ_MsmSystemRxFcsErrorsCounterRegister_HHD_baseRegisterAddress 0x6048 +/*! \brief MMD address of structure AQ_MsmSystemRxFcsErrorsCounterRegister_HHD */ +#define AQ_MsmSystemRxFcsErrorsCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemFcsErrorCounter_0 in AQ_MsmSystemRxFcsErrorsCounterRegister_HHD */ +#define AQ_MsmSystemRxFcsErrorsCounterRegister_HHD_msmSystemFcsErrorCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemFcsErrorCounter_0 in AQ_MsmSystemRxFcsErrorsCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxFcsErrorsCounterRegister_HHD_msmSystemFcsErrorCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemFcsErrorCounter_0 in AQ_MsmSystemRxFcsErrorsCounterRegister_HHD */ +#define word_AQ_MsmSystemRxFcsErrorsCounterRegister_HHD_msmSystemFcsErrorCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemFcsErrorCounter_1 in AQ_MsmSystemRxFcsErrorsCounterRegister_HHD */ +#define AQ_MsmSystemRxFcsErrorsCounterRegister_HHD_msmSystemFcsErrorCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemFcsErrorCounter_1 in AQ_MsmSystemRxFcsErrorsCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxFcsErrorsCounterRegister_HHD_msmSystemFcsErrorCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemFcsErrorCounter_1 in AQ_MsmSystemRxFcsErrorsCounterRegister_HHD */ +#define word_AQ_MsmSystemRxFcsErrorsCounterRegister_HHD_msmSystemFcsErrorCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmSystemRxAlignmentErrorsCounterRegister_HHD */ +#define AQ_MsmSystemRxAlignmentErrorsCounterRegister_HHD_baseRegisterAddress 0x604C +/*! \brief MMD address of structure AQ_MsmSystemRxAlignmentErrorsCounterRegister_HHD */ +#define AQ_MsmSystemRxAlignmentErrorsCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemAlignmentErrorCounter_0 in AQ_MsmSystemRxAlignmentErrorsCounterRegister_HHD */ +#define AQ_MsmSystemRxAlignmentErrorsCounterRegister_HHD_msmSystemAlignmentErrorCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemAlignmentErrorCounter_0 in AQ_MsmSystemRxAlignmentErrorsCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxAlignmentErrorsCounterRegister_HHD_msmSystemAlignmentErrorCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemAlignmentErrorCounter_0 in AQ_MsmSystemRxAlignmentErrorsCounterRegister_HHD */ +#define word_AQ_MsmSystemRxAlignmentErrorsCounterRegister_HHD_msmSystemAlignmentErrorCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemAlignmentErrorCounter_1 in AQ_MsmSystemRxAlignmentErrorsCounterRegister_HHD */ +#define AQ_MsmSystemRxAlignmentErrorsCounterRegister_HHD_msmSystemAlignmentErrorCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemAlignmentErrorCounter_1 in AQ_MsmSystemRxAlignmentErrorsCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxAlignmentErrorsCounterRegister_HHD_msmSystemAlignmentErrorCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemAlignmentErrorCounter_1 in AQ_MsmSystemRxAlignmentErrorsCounterRegister_HHD */ +#define word_AQ_MsmSystemRxAlignmentErrorsCounterRegister_HHD_msmSystemAlignmentErrorCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmSystemTxPauseFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxPauseFramesCounterRegister_HHD_baseRegisterAddress 0x6050 +/*! \brief MMD address of structure AQ_MsmSystemTxPauseFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxPauseFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxPauseFramesCounter_0 in AQ_MsmSystemTxPauseFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxPauseFramesCounterRegister_HHD_msmSystemTxPauseFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxPauseFramesCounter_0 in AQ_MsmSystemTxPauseFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemTxPauseFramesCounterRegister_HHD_msmSystemTxPauseFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxPauseFramesCounter_0 in AQ_MsmSystemTxPauseFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemTxPauseFramesCounterRegister_HHD_msmSystemTxPauseFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxPauseFramesCounter_1 in AQ_MsmSystemTxPauseFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxPauseFramesCounterRegister_HHD_msmSystemTxPauseFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxPauseFramesCounter_1 in AQ_MsmSystemTxPauseFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemTxPauseFramesCounterRegister_HHD_msmSystemTxPauseFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxPauseFramesCounter_1 in AQ_MsmSystemTxPauseFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemTxPauseFramesCounterRegister_HHD_msmSystemTxPauseFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmSystemRxPauseFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxPauseFramesCounterRegister_HHD_baseRegisterAddress 0x6054 +/*! \brief MMD address of structure AQ_MsmSystemRxPauseFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxPauseFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxPauseFramesCounter_0 in AQ_MsmSystemRxPauseFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxPauseFramesCounterRegister_HHD_msmSystemRxPauseFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxPauseFramesCounter_0 in AQ_MsmSystemRxPauseFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxPauseFramesCounterRegister_HHD_msmSystemRxPauseFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxPauseFramesCounter_0 in AQ_MsmSystemRxPauseFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemRxPauseFramesCounterRegister_HHD_msmSystemRxPauseFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxPauseFramesCounter_1 in AQ_MsmSystemRxPauseFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxPauseFramesCounterRegister_HHD_msmSystemRxPauseFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxPauseFramesCounter_1 in AQ_MsmSystemRxPauseFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxPauseFramesCounterRegister_HHD_msmSystemRxPauseFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxPauseFramesCounter_1 in AQ_MsmSystemRxPauseFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemRxPauseFramesCounterRegister_HHD_msmSystemRxPauseFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmSystemRxTooLongErrorsCounterRegister_HHD */ +#define AQ_MsmSystemRxTooLongErrorsCounterRegister_HHD_baseRegisterAddress 0x6058 +/*! \brief MMD address of structure AQ_MsmSystemRxTooLongErrorsCounterRegister_HHD */ +#define AQ_MsmSystemRxTooLongErrorsCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxTooLongErrorsCounter_0 in AQ_MsmSystemRxTooLongErrorsCounterRegister_HHD */ +#define AQ_MsmSystemRxTooLongErrorsCounterRegister_HHD_msmSystemRxTooLongErrorsCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxTooLongErrorsCounter_0 in AQ_MsmSystemRxTooLongErrorsCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxTooLongErrorsCounterRegister_HHD_msmSystemRxTooLongErrorsCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxTooLongErrorsCounter_0 in AQ_MsmSystemRxTooLongErrorsCounterRegister_HHD */ +#define word_AQ_MsmSystemRxTooLongErrorsCounterRegister_HHD_msmSystemRxTooLongErrorsCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxTooLongErrorsCounter_1 in AQ_MsmSystemRxTooLongErrorsCounterRegister_HHD */ +#define AQ_MsmSystemRxTooLongErrorsCounterRegister_HHD_msmSystemRxTooLongErrorsCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxTooLongErrorsCounter_1 in AQ_MsmSystemRxTooLongErrorsCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxTooLongErrorsCounterRegister_HHD_msmSystemRxTooLongErrorsCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxTooLongErrorsCounter_1 in AQ_MsmSystemRxTooLongErrorsCounterRegister_HHD */ +#define word_AQ_MsmSystemRxTooLongErrorsCounterRegister_HHD_msmSystemRxTooLongErrorsCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_HHD */ +#define AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_HHD_baseRegisterAddress 0x605C +/*! \brief MMD address of structure AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_HHD */ +#define AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxInRangeLengthErrorsCounter_0 in AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_HHD */ +#define AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_HHD_msmSystemRxInRangeLengthErrorsCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxInRangeLengthErrorsCounter_0 in AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_HHD_msmSystemRxInRangeLengthErrorsCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxInRangeLengthErrorsCounter_0 in AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_HHD */ +#define word_AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_HHD_msmSystemRxInRangeLengthErrorsCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxInRangeLengthErrorsCounter_1 in AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_HHD */ +#define AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_HHD_msmSystemRxInRangeLengthErrorsCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxInRangeLengthErrorsCounter_1 in AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_HHD_msmSystemRxInRangeLengthErrorsCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxInRangeLengthErrorsCounter_1 in AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_HHD */ +#define word_AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_HHD_msmSystemRxInRangeLengthErrorsCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmSystemTxVlanFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxVlanFramesCounterRegister_HHD_baseRegisterAddress 0x6060 +/*! \brief MMD address of structure AQ_MsmSystemTxVlanFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxVlanFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxVlanFramesCounter_0 in AQ_MsmSystemTxVlanFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxVlanFramesCounterRegister_HHD_msmSystemTxVlanFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxVlanFramesCounter_0 in AQ_MsmSystemTxVlanFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemTxVlanFramesCounterRegister_HHD_msmSystemTxVlanFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxVlanFramesCounter_0 in AQ_MsmSystemTxVlanFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemTxVlanFramesCounterRegister_HHD_msmSystemTxVlanFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxVlanFramesCounter_1 in AQ_MsmSystemTxVlanFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxVlanFramesCounterRegister_HHD_msmSystemTxVlanFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxVlanFramesCounter_1 in AQ_MsmSystemTxVlanFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemTxVlanFramesCounterRegister_HHD_msmSystemTxVlanFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxVlanFramesCounter_1 in AQ_MsmSystemTxVlanFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemTxVlanFramesCounterRegister_HHD_msmSystemTxVlanFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmSystemRxVlanFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxVlanFramesCounterRegister_HHD_baseRegisterAddress 0x6064 +/*! \brief MMD address of structure AQ_MsmSystemRxVlanFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxVlanFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxVlanFramesCounter_0 in AQ_MsmSystemRxVlanFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxVlanFramesCounterRegister_HHD_msmSystemRxVlanFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxVlanFramesCounter_0 in AQ_MsmSystemRxVlanFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxVlanFramesCounterRegister_HHD_msmSystemRxVlanFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxVlanFramesCounter_0 in AQ_MsmSystemRxVlanFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemRxVlanFramesCounterRegister_HHD_msmSystemRxVlanFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxVlanFramesCounter_1 in AQ_MsmSystemRxVlanFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxVlanFramesCounterRegister_HHD_msmSystemRxVlanFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxVlanFramesCounter_1 in AQ_MsmSystemRxVlanFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxVlanFramesCounterRegister_HHD_msmSystemRxVlanFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxVlanFramesCounter_1 in AQ_MsmSystemRxVlanFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemRxVlanFramesCounterRegister_HHD_msmSystemRxVlanFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmSystemTxOctetsCounterRegister_HHD */ +#define AQ_MsmSystemTxOctetsCounterRegister_HHD_baseRegisterAddress 0x6068 +/*! \brief MMD address of structure AQ_MsmSystemTxOctetsCounterRegister_HHD */ +#define AQ_MsmSystemTxOctetsCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxOctetsCounter_0 in AQ_MsmSystemTxOctetsCounterRegister_HHD */ +#define AQ_MsmSystemTxOctetsCounterRegister_HHD_msmSystemTxOctetsCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxOctetsCounter_0 in AQ_MsmSystemTxOctetsCounterRegister_HHD */ +#define bits_AQ_MsmSystemTxOctetsCounterRegister_HHD_msmSystemTxOctetsCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxOctetsCounter_0 in AQ_MsmSystemTxOctetsCounterRegister_HHD */ +#define word_AQ_MsmSystemTxOctetsCounterRegister_HHD_msmSystemTxOctetsCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxOctetsCounter_1 in AQ_MsmSystemTxOctetsCounterRegister_HHD */ +#define AQ_MsmSystemTxOctetsCounterRegister_HHD_msmSystemTxOctetsCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxOctetsCounter_1 in AQ_MsmSystemTxOctetsCounterRegister_HHD */ +#define bits_AQ_MsmSystemTxOctetsCounterRegister_HHD_msmSystemTxOctetsCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxOctetsCounter_1 in AQ_MsmSystemTxOctetsCounterRegister_HHD */ +#define word_AQ_MsmSystemTxOctetsCounterRegister_HHD_msmSystemTxOctetsCounter_1 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxOctetsCounter_2 in AQ_MsmSystemTxOctetsCounterRegister_HHD */ +#define AQ_MsmSystemTxOctetsCounterRegister_HHD_msmSystemTxOctetsCounter_2 2 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxOctetsCounter_2 in AQ_MsmSystemTxOctetsCounterRegister_HHD */ +#define bits_AQ_MsmSystemTxOctetsCounterRegister_HHD_msmSystemTxOctetsCounter_2 u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxOctetsCounter_2 in AQ_MsmSystemTxOctetsCounterRegister_HHD */ +#define word_AQ_MsmSystemTxOctetsCounterRegister_HHD_msmSystemTxOctetsCounter_2 u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxOctetsCounter_3 in AQ_MsmSystemTxOctetsCounterRegister_HHD */ +#define AQ_MsmSystemTxOctetsCounterRegister_HHD_msmSystemTxOctetsCounter_3 3 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxOctetsCounter_3 in AQ_MsmSystemTxOctetsCounterRegister_HHD */ +#define bits_AQ_MsmSystemTxOctetsCounterRegister_HHD_msmSystemTxOctetsCounter_3 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxOctetsCounter_3 in AQ_MsmSystemTxOctetsCounterRegister_HHD */ +#define word_AQ_MsmSystemTxOctetsCounterRegister_HHD_msmSystemTxOctetsCounter_3 u3.word_3 + +/*! \brief Base register address of structure AQ_MsmSystemRxOctetsCounterRegister_HHD */ +#define AQ_MsmSystemRxOctetsCounterRegister_HHD_baseRegisterAddress 0x606C +/*! \brief MMD address of structure AQ_MsmSystemRxOctetsCounterRegister_HHD */ +#define AQ_MsmSystemRxOctetsCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxOctetsCounter_0 in AQ_MsmSystemRxOctetsCounterRegister_HHD */ +#define AQ_MsmSystemRxOctetsCounterRegister_HHD_msmSystemRxOctetsCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxOctetsCounter_0 in AQ_MsmSystemRxOctetsCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxOctetsCounterRegister_HHD_msmSystemRxOctetsCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxOctetsCounter_0 in AQ_MsmSystemRxOctetsCounterRegister_HHD */ +#define word_AQ_MsmSystemRxOctetsCounterRegister_HHD_msmSystemRxOctetsCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxOctetsCounter_1 in AQ_MsmSystemRxOctetsCounterRegister_HHD */ +#define AQ_MsmSystemRxOctetsCounterRegister_HHD_msmSystemRxOctetsCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxOctetsCounter_1 in AQ_MsmSystemRxOctetsCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxOctetsCounterRegister_HHD_msmSystemRxOctetsCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxOctetsCounter_1 in AQ_MsmSystemRxOctetsCounterRegister_HHD */ +#define word_AQ_MsmSystemRxOctetsCounterRegister_HHD_msmSystemRxOctetsCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmSystemRxUnicastFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxUnicastFramesCounterRegister_HHD_baseRegisterAddress 0x6070 +/*! \brief MMD address of structure AQ_MsmSystemRxUnicastFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxUnicastFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxUnicastFramesCounter_0 in AQ_MsmSystemRxUnicastFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxUnicastFramesCounterRegister_HHD_msmSystemRxUnicastFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxUnicastFramesCounter_0 in AQ_MsmSystemRxUnicastFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxUnicastFramesCounterRegister_HHD_msmSystemRxUnicastFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxUnicastFramesCounter_0 in AQ_MsmSystemRxUnicastFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemRxUnicastFramesCounterRegister_HHD_msmSystemRxUnicastFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxUnicastFramesCounter_1 in AQ_MsmSystemRxUnicastFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxUnicastFramesCounterRegister_HHD_msmSystemRxUnicastFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxUnicastFramesCounter_1 in AQ_MsmSystemRxUnicastFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxUnicastFramesCounterRegister_HHD_msmSystemRxUnicastFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxUnicastFramesCounter_1 in AQ_MsmSystemRxUnicastFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemRxUnicastFramesCounterRegister_HHD_msmSystemRxUnicastFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmSystemRxMulticastFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxMulticastFramesCounterRegister_HHD_baseRegisterAddress 0x6074 +/*! \brief MMD address of structure AQ_MsmSystemRxMulticastFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxMulticastFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxMulticastFramesCounter_0 in AQ_MsmSystemRxMulticastFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxMulticastFramesCounterRegister_HHD_msmSystemRxMulticastFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxMulticastFramesCounter_0 in AQ_MsmSystemRxMulticastFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxMulticastFramesCounterRegister_HHD_msmSystemRxMulticastFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxMulticastFramesCounter_0 in AQ_MsmSystemRxMulticastFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemRxMulticastFramesCounterRegister_HHD_msmSystemRxMulticastFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxMulticastFramesCounter_1 in AQ_MsmSystemRxMulticastFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxMulticastFramesCounterRegister_HHD_msmSystemRxMulticastFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxMulticastFramesCounter_1 in AQ_MsmSystemRxMulticastFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxMulticastFramesCounterRegister_HHD_msmSystemRxMulticastFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxMulticastFramesCounter_1 in AQ_MsmSystemRxMulticastFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemRxMulticastFramesCounterRegister_HHD_msmSystemRxMulticastFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmSystemRxBroadcastFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxBroadcastFramesCounterRegister_HHD_baseRegisterAddress 0x6078 +/*! \brief MMD address of structure AQ_MsmSystemRxBroadcastFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxBroadcastFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxBroadcastFramesCounter_0 in AQ_MsmSystemRxBroadcastFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxBroadcastFramesCounterRegister_HHD_msmSystemRxBroadcastFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxBroadcastFramesCounter_0 in AQ_MsmSystemRxBroadcastFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxBroadcastFramesCounterRegister_HHD_msmSystemRxBroadcastFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxBroadcastFramesCounter_0 in AQ_MsmSystemRxBroadcastFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemRxBroadcastFramesCounterRegister_HHD_msmSystemRxBroadcastFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxBroadcastFramesCounter_1 in AQ_MsmSystemRxBroadcastFramesCounterRegister_HHD */ +#define AQ_MsmSystemRxBroadcastFramesCounterRegister_HHD_msmSystemRxBroadcastFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxBroadcastFramesCounter_1 in AQ_MsmSystemRxBroadcastFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxBroadcastFramesCounterRegister_HHD_msmSystemRxBroadcastFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxBroadcastFramesCounter_1 in AQ_MsmSystemRxBroadcastFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemRxBroadcastFramesCounterRegister_HHD_msmSystemRxBroadcastFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmSystemTxErrorsCounterRegister_HHD */ +#define AQ_MsmSystemTxErrorsCounterRegister_HHD_baseRegisterAddress 0x607C +/*! \brief MMD address of structure AQ_MsmSystemTxErrorsCounterRegister_HHD */ +#define AQ_MsmSystemTxErrorsCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxErrorsCounter_0 in AQ_MsmSystemTxErrorsCounterRegister_HHD */ +#define AQ_MsmSystemTxErrorsCounterRegister_HHD_msmSystemTxErrorsCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxErrorsCounter_0 in AQ_MsmSystemTxErrorsCounterRegister_HHD */ +#define bits_AQ_MsmSystemTxErrorsCounterRegister_HHD_msmSystemTxErrorsCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxErrorsCounter_0 in AQ_MsmSystemTxErrorsCounterRegister_HHD */ +#define word_AQ_MsmSystemTxErrorsCounterRegister_HHD_msmSystemTxErrorsCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxErrorsCounter_1 in AQ_MsmSystemTxErrorsCounterRegister_HHD */ +#define AQ_MsmSystemTxErrorsCounterRegister_HHD_msmSystemTxErrorsCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxErrorsCounter_1 in AQ_MsmSystemTxErrorsCounterRegister_HHD */ +#define bits_AQ_MsmSystemTxErrorsCounterRegister_HHD_msmSystemTxErrorsCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxErrorsCounter_1 in AQ_MsmSystemTxErrorsCounterRegister_HHD */ +#define word_AQ_MsmSystemTxErrorsCounterRegister_HHD_msmSystemTxErrorsCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmSystemTxUnicastFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxUnicastFramesCounterRegister_HHD_baseRegisterAddress 0x6084 +/*! \brief MMD address of structure AQ_MsmSystemTxUnicastFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxUnicastFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxUnicastFramesCounter_0 in AQ_MsmSystemTxUnicastFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxUnicastFramesCounterRegister_HHD_msmSystemTxUnicastFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxUnicastFramesCounter_0 in AQ_MsmSystemTxUnicastFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemTxUnicastFramesCounterRegister_HHD_msmSystemTxUnicastFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxUnicastFramesCounter_0 in AQ_MsmSystemTxUnicastFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemTxUnicastFramesCounterRegister_HHD_msmSystemTxUnicastFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxUnicastFramesCounter_1 in AQ_MsmSystemTxUnicastFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxUnicastFramesCounterRegister_HHD_msmSystemTxUnicastFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxUnicastFramesCounter_1 in AQ_MsmSystemTxUnicastFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemTxUnicastFramesCounterRegister_HHD_msmSystemTxUnicastFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxUnicastFramesCounter_1 in AQ_MsmSystemTxUnicastFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemTxUnicastFramesCounterRegister_HHD_msmSystemTxUnicastFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmSystemTxMulticastFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxMulticastFramesCounterRegister_HHD_baseRegisterAddress 0x6088 +/*! \brief MMD address of structure AQ_MsmSystemTxMulticastFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxMulticastFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxMulticastFramesCounter_0 in AQ_MsmSystemTxMulticastFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxMulticastFramesCounterRegister_HHD_msmSystemTxMulticastFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxMulticastFramesCounter_0 in AQ_MsmSystemTxMulticastFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemTxMulticastFramesCounterRegister_HHD_msmSystemTxMulticastFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxMulticastFramesCounter_0 in AQ_MsmSystemTxMulticastFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemTxMulticastFramesCounterRegister_HHD_msmSystemTxMulticastFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxMulticastFramesCounter_1 in AQ_MsmSystemTxMulticastFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxMulticastFramesCounterRegister_HHD_msmSystemTxMulticastFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxMulticastFramesCounter_1 in AQ_MsmSystemTxMulticastFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemTxMulticastFramesCounterRegister_HHD_msmSystemTxMulticastFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxMulticastFramesCounter_1 in AQ_MsmSystemTxMulticastFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemTxMulticastFramesCounterRegister_HHD_msmSystemTxMulticastFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmSystemTxBroadcastFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxBroadcastFramesCounterRegister_HHD_baseRegisterAddress 0x608C +/*! \brief MMD address of structure AQ_MsmSystemTxBroadcastFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxBroadcastFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxBroadcastFramesCounter_0 in AQ_MsmSystemTxBroadcastFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxBroadcastFramesCounterRegister_HHD_msmSystemTxBroadcastFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxBroadcastFramesCounter_0 in AQ_MsmSystemTxBroadcastFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemTxBroadcastFramesCounterRegister_HHD_msmSystemTxBroadcastFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxBroadcastFramesCounter_0 in AQ_MsmSystemTxBroadcastFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemTxBroadcastFramesCounterRegister_HHD_msmSystemTxBroadcastFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemTxBroadcastFramesCounter_1 in AQ_MsmSystemTxBroadcastFramesCounterRegister_HHD */ +#define AQ_MsmSystemTxBroadcastFramesCounterRegister_HHD_msmSystemTxBroadcastFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemTxBroadcastFramesCounter_1 in AQ_MsmSystemTxBroadcastFramesCounterRegister_HHD */ +#define bits_AQ_MsmSystemTxBroadcastFramesCounterRegister_HHD_msmSystemTxBroadcastFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemTxBroadcastFramesCounter_1 in AQ_MsmSystemTxBroadcastFramesCounterRegister_HHD */ +#define word_AQ_MsmSystemTxBroadcastFramesCounterRegister_HHD_msmSystemTxBroadcastFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmSystemRxErrorsCounterRegister_HHD */ +#define AQ_MsmSystemRxErrorsCounterRegister_HHD_baseRegisterAddress 0x60C8 +/*! \brief MMD address of structure AQ_MsmSystemRxErrorsCounterRegister_HHD */ +#define AQ_MsmSystemRxErrorsCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxErrorsCounter_0 in AQ_MsmSystemRxErrorsCounterRegister_HHD */ +#define AQ_MsmSystemRxErrorsCounterRegister_HHD_msmSystemRxErrorsCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxErrorsCounter_0 in AQ_MsmSystemRxErrorsCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxErrorsCounterRegister_HHD_msmSystemRxErrorsCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxErrorsCounter_0 in AQ_MsmSystemRxErrorsCounterRegister_HHD */ +#define word_AQ_MsmSystemRxErrorsCounterRegister_HHD_msmSystemRxErrorsCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmSystemRxErrorsCounter_1 in AQ_MsmSystemRxErrorsCounterRegister_HHD */ +#define AQ_MsmSystemRxErrorsCounterRegister_HHD_msmSystemRxErrorsCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmSystemRxErrorsCounter_1 in AQ_MsmSystemRxErrorsCounterRegister_HHD */ +#define bits_AQ_MsmSystemRxErrorsCounterRegister_HHD_msmSystemRxErrorsCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmSystemRxErrorsCounter_1 in AQ_MsmSystemRxErrorsCounterRegister_HHD */ +#define word_AQ_MsmSystemRxErrorsCounterRegister_HHD_msmSystemRxErrorsCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MssIngressVlanTpid_0Register_HHD */ +#define AQ_MssIngressVlanTpid_0Register_HHD_baseRegisterAddress 0x8006 +/*! \brief MMD address of structure AQ_MssIngressVlanTpid_0Register_HHD */ +#define AQ_MssIngressVlanTpid_0Register_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressVlanStag in AQ_MssIngressVlanTpid_0Register_HHD */ +#define AQ_MssIngressVlanTpid_0Register_HHD_mssIngressVlanStag 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressVlanStag in AQ_MssIngressVlanTpid_0Register_HHD */ +#define bits_AQ_MssIngressVlanTpid_0Register_HHD_mssIngressVlanStag u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressVlanStag in AQ_MssIngressVlanTpid_0Register_HHD */ +#define word_AQ_MssIngressVlanTpid_0Register_HHD_mssIngressVlanStag u0.word_0 + +/*! \brief Base register address of structure AQ_MssIngressVlanTpid_1Register_HHD */ +#define AQ_MssIngressVlanTpid_1Register_HHD_baseRegisterAddress 0x8008 +/*! \brief MMD address of structure AQ_MssIngressVlanTpid_1Register_HHD */ +#define AQ_MssIngressVlanTpid_1Register_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressVlanQtag in AQ_MssIngressVlanTpid_1Register_HHD */ +#define AQ_MssIngressVlanTpid_1Register_HHD_mssIngressVlanQtag 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressVlanQtag in AQ_MssIngressVlanTpid_1Register_HHD */ +#define bits_AQ_MssIngressVlanTpid_1Register_HHD_mssIngressVlanQtag u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressVlanQtag in AQ_MssIngressVlanTpid_1Register_HHD */ +#define word_AQ_MssIngressVlanTpid_1Register_HHD_mssIngressVlanQtag u0.word_0 + +/*! \brief Base register address of structure AQ_MssIngressVlanControlRegister_HHD */ +#define AQ_MssIngressVlanControlRegister_HHD_baseRegisterAddress 0x800A +/*! \brief MMD address of structure AQ_MssIngressVlanControlRegister_HHD */ +#define AQ_MssIngressVlanControlRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressVlanUpMapTableLSW in AQ_MssIngressVlanControlRegister_HHD */ +#define AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanUpMapTableLSW 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressVlanUpMapTableLSW in AQ_MssIngressVlanControlRegister_HHD */ +#define bits_AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanUpMapTableLSW u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressVlanUpMapTableLSW in AQ_MssIngressVlanControlRegister_HHD */ +#define word_AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanUpMapTableLSW u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressVlanQtagParseEnable in AQ_MssIngressVlanControlRegister_HHD */ +#define AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanQtagParseEnable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressVlanQtagParseEnable in AQ_MssIngressVlanControlRegister_HHD */ +#define bits_AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanQtagParseEnable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressVlanQtagParseEnable in AQ_MssIngressVlanControlRegister_HHD */ +#define word_AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanQtagParseEnable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressVlanStagParseEnable in AQ_MssIngressVlanControlRegister_HHD */ +#define AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanStagParseEnable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressVlanStagParseEnable in AQ_MssIngressVlanControlRegister_HHD */ +#define bits_AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanStagParseEnable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressVlanStagParseEnable in AQ_MssIngressVlanControlRegister_HHD */ +#define word_AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanStagParseEnable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressVlanQinqParseEnable in AQ_MssIngressVlanControlRegister_HHD */ +#define AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanQinqParseEnable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressVlanQinqParseEnable in AQ_MssIngressVlanControlRegister_HHD */ +#define bits_AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanQinqParseEnable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressVlanQinqParseEnable in AQ_MssIngressVlanControlRegister_HHD */ +#define word_AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanQinqParseEnable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressVlanQtagUpParseEnable in AQ_MssIngressVlanControlRegister_HHD */ +#define AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanQtagUpParseEnable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressVlanQtagUpParseEnable in AQ_MssIngressVlanControlRegister_HHD */ +#define bits_AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanQtagUpParseEnable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressVlanQtagUpParseEnable in AQ_MssIngressVlanControlRegister_HHD */ +#define word_AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanQtagUpParseEnable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressVlanStagUpParseEnable in AQ_MssIngressVlanControlRegister_HHD */ +#define AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanStagUpParseEnable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressVlanStagUpParseEnable in AQ_MssIngressVlanControlRegister_HHD */ +#define bits_AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanStagUpParseEnable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressVlanStagUpParseEnable in AQ_MssIngressVlanControlRegister_HHD */ +#define word_AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanStagUpParseEnable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressVlanUpDefault in AQ_MssIngressVlanControlRegister_HHD */ +#define AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanUpDefault 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressVlanUpDefault in AQ_MssIngressVlanControlRegister_HHD */ +#define bits_AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanUpDefault u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressVlanUpDefault in AQ_MssIngressVlanControlRegister_HHD */ +#define word_AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanUpDefault u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressVlanUpMapTableMSW in AQ_MssIngressVlanControlRegister_HHD */ +#define AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanUpMapTableMSW 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressVlanUpMapTableMSW in AQ_MssIngressVlanControlRegister_HHD */ +#define bits_AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanUpMapTableMSW u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressVlanUpMapTableMSW in AQ_MssIngressVlanControlRegister_HHD */ +#define word_AQ_MssIngressVlanControlRegister_HHD_mssIngressVlanUpMapTableMSW u1.word_1 + +/*! \brief Base register address of structure AQ_MssIngressMtuSizeControlRegister_HHD */ +#define AQ_MssIngressMtuSizeControlRegister_HHD_baseRegisterAddress 0x800C +/*! \brief MMD address of structure AQ_MssIngressMtuSizeControlRegister_HHD */ +#define AQ_MssIngressMtuSizeControlRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressControlledPacketMtuSize in AQ_MssIngressMtuSizeControlRegister_HHD */ +#define AQ_MssIngressMtuSizeControlRegister_HHD_mssIngressControlledPacketMtuSize 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressControlledPacketMtuSize in AQ_MssIngressMtuSizeControlRegister_HHD */ +#define bits_AQ_MssIngressMtuSizeControlRegister_HHD_mssIngressControlledPacketMtuSize u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressControlledPacketMtuSize in AQ_MssIngressMtuSizeControlRegister_HHD */ +#define word_AQ_MssIngressMtuSizeControlRegister_HHD_mssIngressControlledPacketMtuSize u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressUncontrolledPacketMtuSize in AQ_MssIngressMtuSizeControlRegister_HHD */ +#define AQ_MssIngressMtuSizeControlRegister_HHD_mssIngressUncontrolledPacketMtuSize 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressUncontrolledPacketMtuSize in AQ_MssIngressMtuSizeControlRegister_HHD */ +#define bits_AQ_MssIngressMtuSizeControlRegister_HHD_mssIngressUncontrolledPacketMtuSize u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressUncontrolledPacketMtuSize in AQ_MssIngressMtuSizeControlRegister_HHD */ +#define word_AQ_MssIngressMtuSizeControlRegister_HHD_mssIngressUncontrolledPacketMtuSize u1.word_1 + +/*! \brief Base register address of structure AQ_MssIngressControlRegister_HHD */ +#define AQ_MssIngressControlRegister_HHD_baseRegisterAddress 0x800E +/*! \brief MMD address of structure AQ_MssIngressControlRegister_HHD */ +#define AQ_MssIngressControlRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressIcvLsb_8BytesEnable in AQ_MssIngressControlRegister_HHD */ +#define AQ_MssIngressControlRegister_HHD_mssIngressIcvLsb_8BytesEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressIcvLsb_8BytesEnable in AQ_MssIngressControlRegister_HHD */ +#define bits_AQ_MssIngressControlRegister_HHD_mssIngressIcvLsb_8BytesEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressIcvLsb_8BytesEnable in AQ_MssIngressControlRegister_HHD */ +#define word_AQ_MssIngressControlRegister_HHD_mssIngressIcvLsb_8BytesEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressGlobalValidateFrames in AQ_MssIngressControlRegister_HHD */ +#define AQ_MssIngressControlRegister_HHD_mssIngressGlobalValidateFrames 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressGlobalValidateFrames in AQ_MssIngressControlRegister_HHD */ +#define bits_AQ_MssIngressControlRegister_HHD_mssIngressGlobalValidateFrames u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressGlobalValidateFrames in AQ_MssIngressControlRegister_HHD */ +#define word_AQ_MssIngressControlRegister_HHD_mssIngressGlobalValidateFrames u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressRemoveSectag in AQ_MssIngressControlRegister_HHD */ +#define AQ_MssIngressControlRegister_HHD_mssIngressRemoveSectag 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressRemoveSectag in AQ_MssIngressControlRegister_HHD */ +#define bits_AQ_MssIngressControlRegister_HHD_mssIngressRemoveSectag u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressRemoveSectag in AQ_MssIngressControlRegister_HHD */ +#define word_AQ_MssIngressControlRegister_HHD_mssIngressRemoveSectag u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressHighPriority in AQ_MssIngressControlRegister_HHD */ +#define AQ_MssIngressControlRegister_HHD_mssIngressHighPriority 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressHighPriority in AQ_MssIngressControlRegister_HHD */ +#define bits_AQ_MssIngressControlRegister_HHD_mssIngressHighPriority u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressHighPriority in AQ_MssIngressControlRegister_HHD */ +#define word_AQ_MssIngressControlRegister_HHD_mssIngressHighPriority u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressClearCount in AQ_MssIngressControlRegister_HHD */ +#define AQ_MssIngressControlRegister_HHD_mssIngressClearCount 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressClearCount in AQ_MssIngressControlRegister_HHD */ +#define bits_AQ_MssIngressControlRegister_HHD_mssIngressClearCount u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressClearCount in AQ_MssIngressControlRegister_HHD */ +#define word_AQ_MssIngressControlRegister_HHD_mssIngressClearCount u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressClearGlobalTime in AQ_MssIngressControlRegister_HHD */ +#define AQ_MssIngressControlRegister_HHD_mssIngressClearGlobalTime 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressClearGlobalTime in AQ_MssIngressControlRegister_HHD */ +#define bits_AQ_MssIngressControlRegister_HHD_mssIngressClearGlobalTime u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressClearGlobalTime in AQ_MssIngressControlRegister_HHD */ +#define word_AQ_MssIngressControlRegister_HHD_mssIngressClearGlobalTime u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressCheckIcv in AQ_MssIngressControlRegister_HHD */ +#define AQ_MssIngressControlRegister_HHD_mssIngressCheckIcv 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressCheckIcv in AQ_MssIngressControlRegister_HHD */ +#define bits_AQ_MssIngressControlRegister_HHD_mssIngressCheckIcv u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressCheckIcv in AQ_MssIngressControlRegister_HHD */ +#define word_AQ_MssIngressControlRegister_HHD_mssIngressCheckIcv u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressDropIgprcMiss in AQ_MssIngressControlRegister_HHD */ +#define AQ_MssIngressControlRegister_HHD_mssIngressDropIgprcMiss 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressDropIgprcMiss in AQ_MssIngressControlRegister_HHD */ +#define bits_AQ_MssIngressControlRegister_HHD_mssIngressDropIgprcMiss u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressDropIgprcMiss in AQ_MssIngressControlRegister_HHD */ +#define word_AQ_MssIngressControlRegister_HHD_mssIngressDropIgprcMiss u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressDropKayPacket in AQ_MssIngressControlRegister_HHD */ +#define AQ_MssIngressControlRegister_HHD_mssIngressDropKayPacket 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressDropKayPacket in AQ_MssIngressControlRegister_HHD */ +#define bits_AQ_MssIngressControlRegister_HHD_mssIngressDropKayPacket u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressDropKayPacket in AQ_MssIngressControlRegister_HHD */ +#define word_AQ_MssIngressControlRegister_HHD_mssIngressDropKayPacket u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressMaskShortLengthError in AQ_MssIngressControlRegister_HHD */ +#define AQ_MssIngressControlRegister_HHD_mssIngressMaskShortLengthError 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressMaskShortLengthError in AQ_MssIngressControlRegister_HHD */ +#define bits_AQ_MssIngressControlRegister_HHD_mssIngressMaskShortLengthError u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressMaskShortLengthError in AQ_MssIngressControlRegister_HHD */ +#define word_AQ_MssIngressControlRegister_HHD_mssIngressMaskShortLengthError u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressCreateSci in AQ_MssIngressControlRegister_HHD */ +#define AQ_MssIngressControlRegister_HHD_mssIngressCreateSci 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressCreateSci in AQ_MssIngressControlRegister_HHD */ +#define bits_AQ_MssIngressControlRegister_HHD_mssIngressCreateSci u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressCreateSci in AQ_MssIngressControlRegister_HHD */ +#define word_AQ_MssIngressControlRegister_HHD_mssIngressCreateSci u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressOperationPointToPoint in AQ_MssIngressControlRegister_HHD */ +#define AQ_MssIngressControlRegister_HHD_mssIngressOperationPointToPoint 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressOperationPointToPoint in AQ_MssIngressControlRegister_HHD */ +#define bits_AQ_MssIngressControlRegister_HHD_mssIngressOperationPointToPoint u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressOperationPointToPoint in AQ_MssIngressControlRegister_HHD */ +#define word_AQ_MssIngressControlRegister_HHD_mssIngressOperationPointToPoint u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressSoftReset in AQ_MssIngressControlRegister_HHD */ +#define AQ_MssIngressControlRegister_HHD_mssIngressSoftReset 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressSoftReset in AQ_MssIngressControlRegister_HHD */ +#define bits_AQ_MssIngressControlRegister_HHD_mssIngressSoftReset u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressSoftReset in AQ_MssIngressControlRegister_HHD */ +#define word_AQ_MssIngressControlRegister_HHD_mssIngressSoftReset u0.word_0 + +/*! \brief Base register address of structure AQ_MssIngressSaControlRegister_HHD */ +#define AQ_MssIngressSaControlRegister_HHD_baseRegisterAddress 0x8010 +/*! \brief MMD address of structure AQ_MssIngressSaControlRegister_HHD */ +#define AQ_MssIngressSaControlRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressSaThresholdLSW in AQ_MssIngressSaControlRegister_HHD */ +#define AQ_MssIngressSaControlRegister_HHD_mssIngressSaThresholdLSW 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressSaThresholdLSW in AQ_MssIngressSaControlRegister_HHD */ +#define bits_AQ_MssIngressSaControlRegister_HHD_mssIngressSaThresholdLSW u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressSaThresholdLSW in AQ_MssIngressSaControlRegister_HHD */ +#define word_AQ_MssIngressSaControlRegister_HHD_mssIngressSaThresholdLSW u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressSaThresholdMSW in AQ_MssIngressSaControlRegister_HHD */ +#define AQ_MssIngressSaControlRegister_HHD_mssIngressSaThresholdMSW 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressSaThresholdMSW in AQ_MssIngressSaControlRegister_HHD */ +#define bits_AQ_MssIngressSaControlRegister_HHD_mssIngressSaThresholdMSW u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressSaThresholdMSW in AQ_MssIngressSaControlRegister_HHD */ +#define word_AQ_MssIngressSaControlRegister_HHD_mssIngressSaThresholdMSW u1.word_1 + +/*! \brief Base register address of structure AQ_MssIngressInterruptStatusRegister_HHD */ +#define AQ_MssIngressInterruptStatusRegister_HHD_baseRegisterAddress 0x802E +/*! \brief MMD address of structure AQ_MssIngressInterruptStatusRegister_HHD */ +#define AQ_MssIngressInterruptStatusRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressIgpocMissInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define AQ_MssIngressInterruptStatusRegister_HHD_mssIngressIgpocMissInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressIgpocMissInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define bits_AQ_MssIngressInterruptStatusRegister_HHD_mssIngressIgpocMissInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressIgpocMissInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define word_AQ_MssIngressInterruptStatusRegister_HHD_mssIngressIgpocMissInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressTciE_cErrorInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define AQ_MssIngressInterruptStatusRegister_HHD_mssIngressTciE_cErrorInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressTciE_cErrorInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define bits_AQ_MssIngressInterruptStatusRegister_HHD_mssIngressTciE_cErrorInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressTciE_cErrorInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define word_AQ_MssIngressInterruptStatusRegister_HHD_mssIngressTciE_cErrorInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressEccErrorInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define AQ_MssIngressInterruptStatusRegister_HHD_mssIngressEccErrorInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressEccErrorInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define bits_AQ_MssIngressInterruptStatusRegister_HHD_mssIngressEccErrorInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressEccErrorInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define word_AQ_MssIngressInterruptStatusRegister_HHD_mssIngressEccErrorInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressMibSaturationInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define AQ_MssIngressInterruptStatusRegister_HHD_mssIngressMibSaturationInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressMibSaturationInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define bits_AQ_MssIngressInterruptStatusRegister_HHD_mssIngressMibSaturationInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressMibSaturationInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define word_AQ_MssIngressInterruptStatusRegister_HHD_mssIngressMibSaturationInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressReplayErrorInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define AQ_MssIngressInterruptStatusRegister_HHD_mssIngressReplayErrorInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressReplayErrorInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define bits_AQ_MssIngressInterruptStatusRegister_HHD_mssIngressReplayErrorInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressReplayErrorInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define word_AQ_MssIngressInterruptStatusRegister_HHD_mssIngressReplayErrorInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressIcvErrorInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define AQ_MssIngressInterruptStatusRegister_HHD_mssIngressIcvErrorInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressIcvErrorInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define bits_AQ_MssIngressInterruptStatusRegister_HHD_mssIngressIcvErrorInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressIcvErrorInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define word_AQ_MssIngressInterruptStatusRegister_HHD_mssIngressIcvErrorInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressSaThresholdExpiredInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define AQ_MssIngressInterruptStatusRegister_HHD_mssIngressSaThresholdExpiredInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressSaThresholdExpiredInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define bits_AQ_MssIngressInterruptStatusRegister_HHD_mssIngressSaThresholdExpiredInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressSaThresholdExpiredInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define word_AQ_MssIngressInterruptStatusRegister_HHD_mssIngressSaThresholdExpiredInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressSaExpiredInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define AQ_MssIngressInterruptStatusRegister_HHD_mssIngressSaExpiredInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressSaExpiredInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define bits_AQ_MssIngressInterruptStatusRegister_HHD_mssIngressSaExpiredInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressSaExpiredInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define word_AQ_MssIngressInterruptStatusRegister_HHD_mssIngressSaExpiredInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssMasterIngressInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define AQ_MssIngressInterruptStatusRegister_HHD_mssMasterIngressInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssMasterIngressInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define bits_AQ_MssIngressInterruptStatusRegister_HHD_mssMasterIngressInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssMasterIngressInterrupt in AQ_MssIngressInterruptStatusRegister_HHD */ +#define word_AQ_MssIngressInterruptStatusRegister_HHD_mssMasterIngressInterrupt u0.word_0 + +/*! \brief Base register address of structure AQ_MssIngressInterruptMaskRegister_HHD */ +#define AQ_MssIngressInterruptMaskRegister_HHD_baseRegisterAddress 0x8030 +/*! \brief MMD address of structure AQ_MssIngressInterruptMaskRegister_HHD */ +#define AQ_MssIngressInterruptMaskRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressIgpocMissInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define AQ_MssIngressInterruptMaskRegister_HHD_mssIngressIgpocMissInterruptEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressIgpocMissInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define bits_AQ_MssIngressInterruptMaskRegister_HHD_mssIngressIgpocMissInterruptEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressIgpocMissInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define word_AQ_MssIngressInterruptMaskRegister_HHD_mssIngressIgpocMissInterruptEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressTciE_cErrorInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define AQ_MssIngressInterruptMaskRegister_HHD_mssIngressTciE_cErrorInterruptEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressTciE_cErrorInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define bits_AQ_MssIngressInterruptMaskRegister_HHD_mssIngressTciE_cErrorInterruptEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressTciE_cErrorInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define word_AQ_MssIngressInterruptMaskRegister_HHD_mssIngressTciE_cErrorInterruptEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressEccErrorInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define AQ_MssIngressInterruptMaskRegister_HHD_mssIngressEccErrorInterruptEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressEccErrorInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define bits_AQ_MssIngressInterruptMaskRegister_HHD_mssIngressEccErrorInterruptEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressEccErrorInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define word_AQ_MssIngressInterruptMaskRegister_HHD_mssIngressEccErrorInterruptEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressMibSaturationInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define AQ_MssIngressInterruptMaskRegister_HHD_mssIngressMibSaturationInterruptEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressMibSaturationInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define bits_AQ_MssIngressInterruptMaskRegister_HHD_mssIngressMibSaturationInterruptEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressMibSaturationInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define word_AQ_MssIngressInterruptMaskRegister_HHD_mssIngressMibSaturationInterruptEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressReplayErrorInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define AQ_MssIngressInterruptMaskRegister_HHD_mssIngressReplayErrorInterruptEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressReplayErrorInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define bits_AQ_MssIngressInterruptMaskRegister_HHD_mssIngressReplayErrorInterruptEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressReplayErrorInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define word_AQ_MssIngressInterruptMaskRegister_HHD_mssIngressReplayErrorInterruptEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressIcvErrorInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define AQ_MssIngressInterruptMaskRegister_HHD_mssIngressIcvErrorInterruptEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressIcvErrorInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define bits_AQ_MssIngressInterruptMaskRegister_HHD_mssIngressIcvErrorInterruptEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressIcvErrorInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define word_AQ_MssIngressInterruptMaskRegister_HHD_mssIngressIcvErrorInterruptEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressSaThresholdExpiredInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define AQ_MssIngressInterruptMaskRegister_HHD_mssIngressSaThresholdExpiredInterruptEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressSaThresholdExpiredInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define bits_AQ_MssIngressInterruptMaskRegister_HHD_mssIngressSaThresholdExpiredInterruptEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressSaThresholdExpiredInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define word_AQ_MssIngressInterruptMaskRegister_HHD_mssIngressSaThresholdExpiredInterruptEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressSaExpiredInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define AQ_MssIngressInterruptMaskRegister_HHD_mssIngressSaExpiredInterruptEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressSaExpiredInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define bits_AQ_MssIngressInterruptMaskRegister_HHD_mssIngressSaExpiredInterruptEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressSaExpiredInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define word_AQ_MssIngressInterruptMaskRegister_HHD_mssIngressSaExpiredInterruptEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressMasterInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define AQ_MssIngressInterruptMaskRegister_HHD_mssIngressMasterInterruptEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressMasterInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define bits_AQ_MssIngressInterruptMaskRegister_HHD_mssIngressMasterInterruptEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressMasterInterruptEnable in AQ_MssIngressInterruptMaskRegister_HHD */ +#define word_AQ_MssIngressInterruptMaskRegister_HHD_mssIngressMasterInterruptEnable u0.word_0 + +/*! \brief Base register address of structure AQ_MssIngressSaIcvErrorStatusRegister_HHD */ +#define AQ_MssIngressSaIcvErrorStatusRegister_HHD_baseRegisterAddress 0x8032 +/*! \brief MMD address of structure AQ_MssIngressSaIcvErrorStatusRegister_HHD */ +#define AQ_MssIngressSaIcvErrorStatusRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressSaIcvErrorLSW in AQ_MssIngressSaIcvErrorStatusRegister_HHD */ +#define AQ_MssIngressSaIcvErrorStatusRegister_HHD_mssIngressSaIcvErrorLSW 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressSaIcvErrorLSW in AQ_MssIngressSaIcvErrorStatusRegister_HHD */ +#define bits_AQ_MssIngressSaIcvErrorStatusRegister_HHD_mssIngressSaIcvErrorLSW u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressSaIcvErrorLSW in AQ_MssIngressSaIcvErrorStatusRegister_HHD */ +#define word_AQ_MssIngressSaIcvErrorStatusRegister_HHD_mssIngressSaIcvErrorLSW u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressSaIcvErrorMSW in AQ_MssIngressSaIcvErrorStatusRegister_HHD */ +#define AQ_MssIngressSaIcvErrorStatusRegister_HHD_mssIngressSaIcvErrorMSW 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressSaIcvErrorMSW in AQ_MssIngressSaIcvErrorStatusRegister_HHD */ +#define bits_AQ_MssIngressSaIcvErrorStatusRegister_HHD_mssIngressSaIcvErrorMSW u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressSaIcvErrorMSW in AQ_MssIngressSaIcvErrorStatusRegister_HHD */ +#define word_AQ_MssIngressSaIcvErrorStatusRegister_HHD_mssIngressSaIcvErrorMSW u1.word_1 + +/*! \brief Base register address of structure AQ_MssIngressSaReplayErrorStatusRegister_HHD */ +#define AQ_MssIngressSaReplayErrorStatusRegister_HHD_baseRegisterAddress 0x8034 +/*! \brief MMD address of structure AQ_MssIngressSaReplayErrorStatusRegister_HHD */ +#define AQ_MssIngressSaReplayErrorStatusRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressSaReplayErrorLSW in AQ_MssIngressSaReplayErrorStatusRegister_HHD */ +#define AQ_MssIngressSaReplayErrorStatusRegister_HHD_mssIngressSaReplayErrorLSW 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressSaReplayErrorLSW in AQ_MssIngressSaReplayErrorStatusRegister_HHD */ +#define bits_AQ_MssIngressSaReplayErrorStatusRegister_HHD_mssIngressSaReplayErrorLSW u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressSaReplayErrorLSW in AQ_MssIngressSaReplayErrorStatusRegister_HHD */ +#define word_AQ_MssIngressSaReplayErrorStatusRegister_HHD_mssIngressSaReplayErrorLSW u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressSaReplayErrorMSW in AQ_MssIngressSaReplayErrorStatusRegister_HHD */ +#define AQ_MssIngressSaReplayErrorStatusRegister_HHD_mssIngressSaReplayErrorMSW 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressSaReplayErrorMSW in AQ_MssIngressSaReplayErrorStatusRegister_HHD */ +#define bits_AQ_MssIngressSaReplayErrorStatusRegister_HHD_mssIngressSaReplayErrorMSW u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressSaReplayErrorMSW in AQ_MssIngressSaReplayErrorStatusRegister_HHD */ +#define word_AQ_MssIngressSaReplayErrorStatusRegister_HHD_mssIngressSaReplayErrorMSW u1.word_1 + +/*! \brief Base register address of structure AQ_MssIngressSaExpiredStatusRegister_HHD */ +#define AQ_MssIngressSaExpiredStatusRegister_HHD_baseRegisterAddress 0x8036 +/*! \brief MMD address of structure AQ_MssIngressSaExpiredStatusRegister_HHD */ +#define AQ_MssIngressSaExpiredStatusRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressSaExpiredLSW in AQ_MssIngressSaExpiredStatusRegister_HHD */ +#define AQ_MssIngressSaExpiredStatusRegister_HHD_mssIngressSaExpiredLSW 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressSaExpiredLSW in AQ_MssIngressSaExpiredStatusRegister_HHD */ +#define bits_AQ_MssIngressSaExpiredStatusRegister_HHD_mssIngressSaExpiredLSW u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressSaExpiredLSW in AQ_MssIngressSaExpiredStatusRegister_HHD */ +#define word_AQ_MssIngressSaExpiredStatusRegister_HHD_mssIngressSaExpiredLSW u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressSaExpiredMSW in AQ_MssIngressSaExpiredStatusRegister_HHD */ +#define AQ_MssIngressSaExpiredStatusRegister_HHD_mssIngressSaExpiredMSW 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressSaExpiredMSW in AQ_MssIngressSaExpiredStatusRegister_HHD */ +#define bits_AQ_MssIngressSaExpiredStatusRegister_HHD_mssIngressSaExpiredMSW u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressSaExpiredMSW in AQ_MssIngressSaExpiredStatusRegister_HHD */ +#define word_AQ_MssIngressSaExpiredStatusRegister_HHD_mssIngressSaExpiredMSW u1.word_1 + +/*! \brief Base register address of structure AQ_MssIngressSaThresholdExpiredStatusRegister_HHD */ +#define AQ_MssIngressSaThresholdExpiredStatusRegister_HHD_baseRegisterAddress 0x8038 +/*! \brief MMD address of structure AQ_MssIngressSaThresholdExpiredStatusRegister_HHD */ +#define AQ_MssIngressSaThresholdExpiredStatusRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressSaThresholdExpiredLSW in AQ_MssIngressSaThresholdExpiredStatusRegister_HHD */ +#define AQ_MssIngressSaThresholdExpiredStatusRegister_HHD_mssIngressSaThresholdExpiredLSW 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressSaThresholdExpiredLSW in AQ_MssIngressSaThresholdExpiredStatusRegister_HHD */ +#define bits_AQ_MssIngressSaThresholdExpiredStatusRegister_HHD_mssIngressSaThresholdExpiredLSW u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressSaThresholdExpiredLSW in AQ_MssIngressSaThresholdExpiredStatusRegister_HHD */ +#define word_AQ_MssIngressSaThresholdExpiredStatusRegister_HHD_mssIngressSaThresholdExpiredLSW u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressSaThresholdExpiredMSW in AQ_MssIngressSaThresholdExpiredStatusRegister_HHD */ +#define AQ_MssIngressSaThresholdExpiredStatusRegister_HHD_mssIngressSaThresholdExpiredMSW 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressSaThresholdExpiredMSW in AQ_MssIngressSaThresholdExpiredStatusRegister_HHD */ +#define bits_AQ_MssIngressSaThresholdExpiredStatusRegister_HHD_mssIngressSaThresholdExpiredMSW u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressSaThresholdExpiredMSW in AQ_MssIngressSaThresholdExpiredStatusRegister_HHD */ +#define word_AQ_MssIngressSaThresholdExpiredStatusRegister_HHD_mssIngressSaThresholdExpiredMSW u1.word_1 + +/*! \brief Base register address of structure AQ_MssIngressEccInterruptStatusRegister_HHD */ +#define AQ_MssIngressEccInterruptStatusRegister_HHD_baseRegisterAddress 0x803A +/*! \brief MMD address of structure AQ_MssIngressEccInterruptStatusRegister_HHD */ +#define AQ_MssIngressEccInterruptStatusRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressSaEccErrorInterruptLSW in AQ_MssIngressEccInterruptStatusRegister_HHD */ +#define AQ_MssIngressEccInterruptStatusRegister_HHD_mssIngressSaEccErrorInterruptLSW 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressSaEccErrorInterruptLSW in AQ_MssIngressEccInterruptStatusRegister_HHD */ +#define bits_AQ_MssIngressEccInterruptStatusRegister_HHD_mssIngressSaEccErrorInterruptLSW u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressSaEccErrorInterruptLSW in AQ_MssIngressEccInterruptStatusRegister_HHD */ +#define word_AQ_MssIngressEccInterruptStatusRegister_HHD_mssIngressSaEccErrorInterruptLSW u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressSaEccErrorInterruptMSW in AQ_MssIngressEccInterruptStatusRegister_HHD */ +#define AQ_MssIngressEccInterruptStatusRegister_HHD_mssIngressSaEccErrorInterruptMSW 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressSaEccErrorInterruptMSW in AQ_MssIngressEccInterruptStatusRegister_HHD */ +#define bits_AQ_MssIngressEccInterruptStatusRegister_HHD_mssIngressSaEccErrorInterruptMSW u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressSaEccErrorInterruptMSW in AQ_MssIngressEccInterruptStatusRegister_HHD */ +#define word_AQ_MssIngressEccInterruptStatusRegister_HHD_mssIngressSaEccErrorInterruptMSW u1.word_1 + +/*! \brief Base register address of structure AQ_MssIngressLutAddressControlRegister_HHD */ +#define AQ_MssIngressLutAddressControlRegister_HHD_baseRegisterAddress 0x8080 +/*! \brief MMD address of structure AQ_MssIngressLutAddressControlRegister_HHD */ +#define AQ_MssIngressLutAddressControlRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutSelect in AQ_MssIngressLutAddressControlRegister_HHD */ +#define AQ_MssIngressLutAddressControlRegister_HHD_mssIngressLutSelect 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutSelect in AQ_MssIngressLutAddressControlRegister_HHD */ +#define bits_AQ_MssIngressLutAddressControlRegister_HHD_mssIngressLutSelect u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutSelect in AQ_MssIngressLutAddressControlRegister_HHD */ +#define word_AQ_MssIngressLutAddressControlRegister_HHD_mssIngressLutSelect u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutAddress in AQ_MssIngressLutAddressControlRegister_HHD */ +#define AQ_MssIngressLutAddressControlRegister_HHD_mssIngressLutAddress 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutAddress in AQ_MssIngressLutAddressControlRegister_HHD */ +#define bits_AQ_MssIngressLutAddressControlRegister_HHD_mssIngressLutAddress u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutAddress in AQ_MssIngressLutAddressControlRegister_HHD */ +#define word_AQ_MssIngressLutAddressControlRegister_HHD_mssIngressLutAddress u0.word_0 + +/*! \brief Base register address of structure AQ_MssIngressLutControlRegister_HHD */ +#define AQ_MssIngressLutControlRegister_HHD_baseRegisterAddress 0x8081 +/*! \brief MMD address of structure AQ_MssIngressLutControlRegister_HHD */ +#define AQ_MssIngressLutControlRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutWrite in AQ_MssIngressLutControlRegister_HHD */ +#define AQ_MssIngressLutControlRegister_HHD_mssIngressLutWrite 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutWrite in AQ_MssIngressLutControlRegister_HHD */ +#define bits_AQ_MssIngressLutControlRegister_HHD_mssIngressLutWrite u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutWrite in AQ_MssIngressLutControlRegister_HHD */ +#define word_AQ_MssIngressLutControlRegister_HHD_mssIngressLutWrite u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutRead in AQ_MssIngressLutControlRegister_HHD */ +#define AQ_MssIngressLutControlRegister_HHD_mssIngressLutRead 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutRead in AQ_MssIngressLutControlRegister_HHD */ +#define bits_AQ_MssIngressLutControlRegister_HHD_mssIngressLutRead u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutRead in AQ_MssIngressLutControlRegister_HHD */ +#define word_AQ_MssIngressLutControlRegister_HHD_mssIngressLutRead u0.word_0 + +/*! \brief Base register address of structure AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_baseRegisterAddress 0x80A0 +/*! \brief MMD address of structure AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_0 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_0 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_0 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_1 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_1 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_1 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_1 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_2 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_2 2 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_2 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_2 u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_2 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_2 u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_3 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_3 3 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_3 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_3 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_3 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_3 u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_4 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_4 4 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_4 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_4 u4.bits_4 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_4 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_4 u4.word_4 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_5 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_5 5 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_5 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_5 u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_5 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_5 u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_6 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_6 6 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_6 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_6 u6.bits_6 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_6 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_6 u6.word_6 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_7 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_7 7 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_7 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_7 u7.bits_7 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_7 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_7 u7.word_7 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_8 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_8 8 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_8 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_8 u8.bits_8 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_8 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_8 u8.word_8 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_9 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_9 9 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_9 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_9 u9.bits_9 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_9 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_9 u9.word_9 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_10 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_10 10 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_10 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_10 u10.bits_10 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_10 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_10 u10.word_10 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_11 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_11 11 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_11 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_11 u11.bits_11 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_11 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_11 u11.word_11 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_12 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_12 12 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_12 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_12 u12.bits_12 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_12 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_12 u12.word_12 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_13 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_13 13 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_13 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_13 u13.bits_13 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_13 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_13 u13.word_13 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_14 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_14 14 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_14 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_14 u14.bits_14 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_14 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_14 u14.word_14 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_15 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_15 15 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_15 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_15 u15.bits_15 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_15 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_15 u15.word_15 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_16 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_16 16 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_16 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_16 u16.bits_16 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_16 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_16 u16.word_16 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_17 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_17 17 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_17 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_17 u17.bits_17 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_17 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_17 u17.word_17 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_18 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_18 18 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_18 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_18 u18.bits_18 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_18 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_18 u18.word_18 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_19 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_19 19 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_19 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_19 u19.bits_19 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_19 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_19 u19.word_19 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_20 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_20 20 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_20 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_20 u20.bits_20 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_20 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_20 u20.word_20 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_21 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_21 21 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_21 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_21 u21.bits_21 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_21 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_21 u21.word_21 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_22 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_22 22 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_22 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_22 u22.bits_22 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_22 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_22 u22.word_22 +/*! \brief Preprocessor variable to relate field to word number in structure mssIngressLutData_23 in AQ_MssIngressLutDataControlRegister_HHD */ +#define AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_23 23 +/*! \brief Preprocessor variable to relate field to bit position in structure mssIngressLutData_23 in AQ_MssIngressLutDataControlRegister_HHD */ +#define bits_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_23 u23.bits_23 +/*! \brief Preprocessor variable to relate field to word position in structure mssIngressLutData_23 in AQ_MssIngressLutDataControlRegister_HHD */ +#define word_AQ_MssIngressLutDataControlRegister_HHD_mssIngressLutData_23 u23.word_23 + +/*! \brief Base register address of structure AQ_MsmLineGeneralControlRegister_HHD */ +#define AQ_MsmLineGeneralControlRegister_HHD_baseRegisterAddress 0x9004 +/*! \brief MMD address of structure AQ_MsmLineGeneralControlRegister_HHD */ +#define AQ_MsmLineGeneralControlRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLinePhyTxEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define AQ_MsmLineGeneralControlRegister_HHD_msmLinePhyTxEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLinePhyTxEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define bits_AQ_MsmLineGeneralControlRegister_HHD_msmLinePhyTxEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLinePhyTxEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define word_AQ_MsmLineGeneralControlRegister_HHD_msmLinePhyTxEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxErrorDiscard in AQ_MsmLineGeneralControlRegister_HHD */ +#define AQ_MsmLineGeneralControlRegister_HHD_msmLineRxErrorDiscard 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxErrorDiscard in AQ_MsmLineGeneralControlRegister_HHD */ +#define bits_AQ_MsmLineGeneralControlRegister_HHD_msmLineRxErrorDiscard u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxErrorDiscard in AQ_MsmLineGeneralControlRegister_HHD */ +#define word_AQ_MsmLineGeneralControlRegister_HHD_msmLineRxErrorDiscard u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineControlFrameEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define AQ_MsmLineGeneralControlRegister_HHD_msmLineControlFrameEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineControlFrameEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define bits_AQ_MsmLineGeneralControlRegister_HHD_msmLineControlFrameEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineControlFrameEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define word_AQ_MsmLineGeneralControlRegister_HHD_msmLineControlFrameEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineSoftReset in AQ_MsmLineGeneralControlRegister_HHD */ +#define AQ_MsmLineGeneralControlRegister_HHD_msmLineSoftReset 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineSoftReset in AQ_MsmLineGeneralControlRegister_HHD */ +#define bits_AQ_MsmLineGeneralControlRegister_HHD_msmLineSoftReset u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineSoftReset in AQ_MsmLineGeneralControlRegister_HHD */ +#define word_AQ_MsmLineGeneralControlRegister_HHD_msmLineSoftReset u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxPadEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define AQ_MsmLineGeneralControlRegister_HHD_msmLineTxPadEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxPadEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define bits_AQ_MsmLineGeneralControlRegister_HHD_msmLineTxPadEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxPadEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define word_AQ_MsmLineGeneralControlRegister_HHD_msmLineTxPadEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxCrcAppend in AQ_MsmLineGeneralControlRegister_HHD */ +#define AQ_MsmLineGeneralControlRegister_HHD_msmLineTxCrcAppend 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxCrcAppend in AQ_MsmLineGeneralControlRegister_HHD */ +#define bits_AQ_MsmLineGeneralControlRegister_HHD_msmLineTxCrcAppend u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxCrcAppend in AQ_MsmLineGeneralControlRegister_HHD */ +#define word_AQ_MsmLineGeneralControlRegister_HHD_msmLineTxCrcAppend u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxAddressInsertEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define AQ_MsmLineGeneralControlRegister_HHD_msmLineTxAddressInsertEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxAddressInsertEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define bits_AQ_MsmLineGeneralControlRegister_HHD_msmLineTxAddressInsertEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxAddressInsertEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define word_AQ_MsmLineGeneralControlRegister_HHD_msmLineTxAddressInsertEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLinePauseIgnore in AQ_MsmLineGeneralControlRegister_HHD */ +#define AQ_MsmLineGeneralControlRegister_HHD_msmLinePauseIgnore 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLinePauseIgnore in AQ_MsmLineGeneralControlRegister_HHD */ +#define bits_AQ_MsmLineGeneralControlRegister_HHD_msmLinePauseIgnore u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLinePauseIgnore in AQ_MsmLineGeneralControlRegister_HHD */ +#define word_AQ_MsmLineGeneralControlRegister_HHD_msmLinePauseIgnore u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLinePauseForward in AQ_MsmLineGeneralControlRegister_HHD */ +#define AQ_MsmLineGeneralControlRegister_HHD_msmLinePauseForward 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLinePauseForward in AQ_MsmLineGeneralControlRegister_HHD */ +#define bits_AQ_MsmLineGeneralControlRegister_HHD_msmLinePauseForward u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLinePauseForward in AQ_MsmLineGeneralControlRegister_HHD */ +#define word_AQ_MsmLineGeneralControlRegister_HHD_msmLinePauseForward u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineCrcForward in AQ_MsmLineGeneralControlRegister_HHD */ +#define AQ_MsmLineGeneralControlRegister_HHD_msmLineCrcForward 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineCrcForward in AQ_MsmLineGeneralControlRegister_HHD */ +#define bits_AQ_MsmLineGeneralControlRegister_HHD_msmLineCrcForward u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineCrcForward in AQ_MsmLineGeneralControlRegister_HHD */ +#define word_AQ_MsmLineGeneralControlRegister_HHD_msmLineCrcForward u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLinePadEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define AQ_MsmLineGeneralControlRegister_HHD_msmLinePadEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLinePadEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define bits_AQ_MsmLineGeneralControlRegister_HHD_msmLinePadEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLinePadEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define word_AQ_MsmLineGeneralControlRegister_HHD_msmLinePadEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLinePromiscuousMode in AQ_MsmLineGeneralControlRegister_HHD */ +#define AQ_MsmLineGeneralControlRegister_HHD_msmLinePromiscuousMode 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLinePromiscuousMode in AQ_MsmLineGeneralControlRegister_HHD */ +#define bits_AQ_MsmLineGeneralControlRegister_HHD_msmLinePromiscuousMode u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLinePromiscuousMode in AQ_MsmLineGeneralControlRegister_HHD */ +#define word_AQ_MsmLineGeneralControlRegister_HHD_msmLinePromiscuousMode u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineWanMode in AQ_MsmLineGeneralControlRegister_HHD */ +#define AQ_MsmLineGeneralControlRegister_HHD_msmLineWanMode 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineWanMode in AQ_MsmLineGeneralControlRegister_HHD */ +#define bits_AQ_MsmLineGeneralControlRegister_HHD_msmLineWanMode u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineWanMode in AQ_MsmLineGeneralControlRegister_HHD */ +#define word_AQ_MsmLineGeneralControlRegister_HHD_msmLineWanMode u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define AQ_MsmLineGeneralControlRegister_HHD_msmLineRxEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define bits_AQ_MsmLineGeneralControlRegister_HHD_msmLineRxEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define word_AQ_MsmLineGeneralControlRegister_HHD_msmLineRxEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define AQ_MsmLineGeneralControlRegister_HHD_msmLineTxEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define bits_AQ_MsmLineGeneralControlRegister_HHD_msmLineTxEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define word_AQ_MsmLineGeneralControlRegister_HHD_msmLineTxEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxLowPowerIdleEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define AQ_MsmLineGeneralControlRegister_HHD_msmLineTxLowPowerIdleEnable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxLowPowerIdleEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define bits_AQ_MsmLineGeneralControlRegister_HHD_msmLineTxLowPowerIdleEnable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxLowPowerIdleEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define word_AQ_MsmLineGeneralControlRegister_HHD_msmLineTxLowPowerIdleEnable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineSfdCheckDisable in AQ_MsmLineGeneralControlRegister_HHD */ +#define AQ_MsmLineGeneralControlRegister_HHD_msmLineSfdCheckDisable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineSfdCheckDisable in AQ_MsmLineGeneralControlRegister_HHD */ +#define bits_AQ_MsmLineGeneralControlRegister_HHD_msmLineSfdCheckDisable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineSfdCheckDisable in AQ_MsmLineGeneralControlRegister_HHD */ +#define word_AQ_MsmLineGeneralControlRegister_HHD_msmLineSfdCheckDisable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure msmLinePriorityFlowControlEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define AQ_MsmLineGeneralControlRegister_HHD_msmLinePriorityFlowControlEnable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLinePriorityFlowControlEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define bits_AQ_MsmLineGeneralControlRegister_HHD_msmLinePriorityFlowControlEnable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLinePriorityFlowControlEnable in AQ_MsmLineGeneralControlRegister_HHD */ +#define word_AQ_MsmLineGeneralControlRegister_HHD_msmLinePriorityFlowControlEnable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineIdleColumnCountExtend in AQ_MsmLineGeneralControlRegister_HHD */ +#define AQ_MsmLineGeneralControlRegister_HHD_msmLineIdleColumnCountExtend 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineIdleColumnCountExtend in AQ_MsmLineGeneralControlRegister_HHD */ +#define bits_AQ_MsmLineGeneralControlRegister_HHD_msmLineIdleColumnCountExtend u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineIdleColumnCountExtend in AQ_MsmLineGeneralControlRegister_HHD */ +#define word_AQ_MsmLineGeneralControlRegister_HHD_msmLineIdleColumnCountExtend u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineLengthCheckDisable in AQ_MsmLineGeneralControlRegister_HHD */ +#define AQ_MsmLineGeneralControlRegister_HHD_msmLineLengthCheckDisable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineLengthCheckDisable in AQ_MsmLineGeneralControlRegister_HHD */ +#define bits_AQ_MsmLineGeneralControlRegister_HHD_msmLineLengthCheckDisable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineLengthCheckDisable in AQ_MsmLineGeneralControlRegister_HHD */ +#define word_AQ_MsmLineGeneralControlRegister_HHD_msmLineLengthCheckDisable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineForceSendIdle in AQ_MsmLineGeneralControlRegister_HHD */ +#define AQ_MsmLineGeneralControlRegister_HHD_msmLineForceSendIdle 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineForceSendIdle in AQ_MsmLineGeneralControlRegister_HHD */ +#define bits_AQ_MsmLineGeneralControlRegister_HHD_msmLineForceSendIdle u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineForceSendIdle in AQ_MsmLineGeneralControlRegister_HHD */ +#define word_AQ_MsmLineGeneralControlRegister_HHD_msmLineForceSendIdle u1.word_1 + +/*! \brief Base register address of structure AQ_MsmLineFifoControlRegister_HHD */ +#define AQ_MsmLineFifoControlRegister_HHD_baseRegisterAddress 0x900E +/*! \brief MMD address of structure AQ_MsmLineFifoControlRegister_HHD */ +#define AQ_MsmLineFifoControlRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxFifoFullThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define AQ_MsmLineFifoControlRegister_HHD_msmLineRxFifoFullThreshold 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxFifoFullThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define bits_AQ_MsmLineFifoControlRegister_HHD_msmLineRxFifoFullThreshold u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxFifoFullThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define word_AQ_MsmLineFifoControlRegister_HHD_msmLineRxFifoFullThreshold u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxFifoEmptyThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define AQ_MsmLineFifoControlRegister_HHD_msmLineRxFifoEmptyThreshold 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxFifoEmptyThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define bits_AQ_MsmLineFifoControlRegister_HHD_msmLineRxFifoEmptyThreshold u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxFifoEmptyThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define word_AQ_MsmLineFifoControlRegister_HHD_msmLineRxFifoEmptyThreshold u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxFifoFullThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define AQ_MsmLineFifoControlRegister_HHD_msmLineTxFifoFullThreshold 2 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxFifoFullThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define bits_AQ_MsmLineFifoControlRegister_HHD_msmLineTxFifoFullThreshold u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxFifoFullThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define word_AQ_MsmLineFifoControlRegister_HHD_msmLineTxFifoFullThreshold u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxFifoEmptyThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define AQ_MsmLineFifoControlRegister_HHD_msmLineTxFifoEmptyThreshold 3 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxFifoEmptyThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define bits_AQ_MsmLineFifoControlRegister_HHD_msmLineTxFifoEmptyThreshold u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxFifoEmptyThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define word_AQ_MsmLineFifoControlRegister_HHD_msmLineTxFifoEmptyThreshold u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxFifoAlmostFullThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define AQ_MsmLineFifoControlRegister_HHD_msmLineRxFifoAlmostFullThreshold 4 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxFifoAlmostFullThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define bits_AQ_MsmLineFifoControlRegister_HHD_msmLineRxFifoAlmostFullThreshold u4.bits_4 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxFifoAlmostFullThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define word_AQ_MsmLineFifoControlRegister_HHD_msmLineRxFifoAlmostFullThreshold u4.word_4 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxFifoAlmostEmptyThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define AQ_MsmLineFifoControlRegister_HHD_msmLineRxFifoAlmostEmptyThreshold 5 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxFifoAlmostEmptyThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define bits_AQ_MsmLineFifoControlRegister_HHD_msmLineRxFifoAlmostEmptyThreshold u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxFifoAlmostEmptyThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define word_AQ_MsmLineFifoControlRegister_HHD_msmLineRxFifoAlmostEmptyThreshold u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxFifoAlmostFullThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define AQ_MsmLineFifoControlRegister_HHD_msmLineTxFifoAlmostFullThreshold 6 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxFifoAlmostFullThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define bits_AQ_MsmLineFifoControlRegister_HHD_msmLineTxFifoAlmostFullThreshold u6.bits_6 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxFifoAlmostFullThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define word_AQ_MsmLineFifoControlRegister_HHD_msmLineTxFifoAlmostFullThreshold u6.word_6 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxFifoAlmostEmptyThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define AQ_MsmLineFifoControlRegister_HHD_msmLineTxFifoAlmostEmptyThreshold 7 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxFifoAlmostEmptyThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define bits_AQ_MsmLineFifoControlRegister_HHD_msmLineTxFifoAlmostEmptyThreshold u7.bits_7 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxFifoAlmostEmptyThreshold in AQ_MsmLineFifoControlRegister_HHD */ +#define word_AQ_MsmLineFifoControlRegister_HHD_msmLineTxFifoAlmostEmptyThreshold u7.word_7 + +/*! \brief Base register address of structure AQ_MsmLineGeneralStatusRegister_HHD */ +#define AQ_MsmLineGeneralStatusRegister_HHD_baseRegisterAddress 0x9020 +/*! \brief MMD address of structure AQ_MsmLineGeneralStatusRegister_HHD */ +#define AQ_MsmLineGeneralStatusRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxFifoEmpty in AQ_MsmLineGeneralStatusRegister_HHD */ +#define AQ_MsmLineGeneralStatusRegister_HHD_msmLineTxFifoEmpty 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxFifoEmpty in AQ_MsmLineGeneralStatusRegister_HHD */ +#define bits_AQ_MsmLineGeneralStatusRegister_HHD_msmLineTxFifoEmpty u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxFifoEmpty in AQ_MsmLineGeneralStatusRegister_HHD */ +#define word_AQ_MsmLineGeneralStatusRegister_HHD_msmLineTxFifoEmpty u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxLowPowerIdle in AQ_MsmLineGeneralStatusRegister_HHD */ +#define AQ_MsmLineGeneralStatusRegister_HHD_msmLineRxLowPowerIdle 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxLowPowerIdle in AQ_MsmLineGeneralStatusRegister_HHD */ +#define bits_AQ_MsmLineGeneralStatusRegister_HHD_msmLineRxLowPowerIdle u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxLowPowerIdle in AQ_MsmLineGeneralStatusRegister_HHD */ +#define word_AQ_MsmLineGeneralStatusRegister_HHD_msmLineRxLowPowerIdle u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTimestampAvailable in AQ_MsmLineGeneralStatusRegister_HHD */ +#define AQ_MsmLineGeneralStatusRegister_HHD_msmLineTimestampAvailable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTimestampAvailable in AQ_MsmLineGeneralStatusRegister_HHD */ +#define bits_AQ_MsmLineGeneralStatusRegister_HHD_msmLineTimestampAvailable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTimestampAvailable in AQ_MsmLineGeneralStatusRegister_HHD */ +#define word_AQ_MsmLineGeneralStatusRegister_HHD_msmLineTimestampAvailable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLinePhyLossOfSignal in AQ_MsmLineGeneralStatusRegister_HHD */ +#define AQ_MsmLineGeneralStatusRegister_HHD_msmLinePhyLossOfSignal 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLinePhyLossOfSignal in AQ_MsmLineGeneralStatusRegister_HHD */ +#define bits_AQ_MsmLineGeneralStatusRegister_HHD_msmLinePhyLossOfSignal u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLinePhyLossOfSignal in AQ_MsmLineGeneralStatusRegister_HHD */ +#define word_AQ_MsmLineGeneralStatusRegister_HHD_msmLinePhyLossOfSignal u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxRemoteFault in AQ_MsmLineGeneralStatusRegister_HHD */ +#define AQ_MsmLineGeneralStatusRegister_HHD_msmLineRxRemoteFault 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxRemoteFault in AQ_MsmLineGeneralStatusRegister_HHD */ +#define bits_AQ_MsmLineGeneralStatusRegister_HHD_msmLineRxRemoteFault u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxRemoteFault in AQ_MsmLineGeneralStatusRegister_HHD */ +#define word_AQ_MsmLineGeneralStatusRegister_HHD_msmLineRxRemoteFault u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxLocalFault in AQ_MsmLineGeneralStatusRegister_HHD */ +#define AQ_MsmLineGeneralStatusRegister_HHD_msmLineRxLocalFault 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxLocalFault in AQ_MsmLineGeneralStatusRegister_HHD */ +#define bits_AQ_MsmLineGeneralStatusRegister_HHD_msmLineRxLocalFault u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxLocalFault in AQ_MsmLineGeneralStatusRegister_HHD */ +#define word_AQ_MsmLineGeneralStatusRegister_HHD_msmLineRxLocalFault u0.word_0 + +/*! \brief Base register address of structure AQ_MsmLineTxIpgControlRegister_HHD */ +#define AQ_MsmLineTxIpgControlRegister_HHD_baseRegisterAddress 0x9022 +/*! \brief MMD address of structure AQ_MsmLineTxIpgControlRegister_HHD */ +#define AQ_MsmLineTxIpgControlRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxIpgLength in AQ_MsmLineTxIpgControlRegister_HHD */ +#define AQ_MsmLineTxIpgControlRegister_HHD_msmLineTxIpgLength 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxIpgLength in AQ_MsmLineTxIpgControlRegister_HHD */ +#define bits_AQ_MsmLineTxIpgControlRegister_HHD_msmLineTxIpgLength u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxIpgLength in AQ_MsmLineTxIpgControlRegister_HHD */ +#define word_AQ_MsmLineTxIpgControlRegister_HHD_msmLineTxIpgLength u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxIpgReserved in AQ_MsmLineTxIpgControlRegister_HHD */ +#define AQ_MsmLineTxIpgControlRegister_HHD_msmLineTxIpgReserved 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxIpgReserved in AQ_MsmLineTxIpgControlRegister_HHD */ +#define bits_AQ_MsmLineTxIpgControlRegister_HHD_msmLineTxIpgReserved u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxIpgReserved in AQ_MsmLineTxIpgControlRegister_HHD */ +#define word_AQ_MsmLineTxIpgControlRegister_HHD_msmLineTxIpgReserved u1.word_1 + +/*! \brief Base register address of structure AQ_MsmLineTxGoodFramesCounterRegister_HHD */ +#define AQ_MsmLineTxGoodFramesCounterRegister_HHD_baseRegisterAddress 0x9040 +/*! \brief MMD address of structure AQ_MsmLineTxGoodFramesCounterRegister_HHD */ +#define AQ_MsmLineTxGoodFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxGoodFramesCounter_0 in AQ_MsmLineTxGoodFramesCounterRegister_HHD */ +#define AQ_MsmLineTxGoodFramesCounterRegister_HHD_msmLineTxGoodFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxGoodFramesCounter_0 in AQ_MsmLineTxGoodFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineTxGoodFramesCounterRegister_HHD_msmLineTxGoodFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxGoodFramesCounter_0 in AQ_MsmLineTxGoodFramesCounterRegister_HHD */ +#define word_AQ_MsmLineTxGoodFramesCounterRegister_HHD_msmLineTxGoodFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxGoodFramesCounter_1 in AQ_MsmLineTxGoodFramesCounterRegister_HHD */ +#define AQ_MsmLineTxGoodFramesCounterRegister_HHD_msmLineTxGoodFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxGoodFramesCounter_1 in AQ_MsmLineTxGoodFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineTxGoodFramesCounterRegister_HHD_msmLineTxGoodFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxGoodFramesCounter_1 in AQ_MsmLineTxGoodFramesCounterRegister_HHD */ +#define word_AQ_MsmLineTxGoodFramesCounterRegister_HHD_msmLineTxGoodFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmLineRxGoodFramesCounterRegister_HHD */ +#define AQ_MsmLineRxGoodFramesCounterRegister_HHD_baseRegisterAddress 0x9044 +/*! \brief MMD address of structure AQ_MsmLineRxGoodFramesCounterRegister_HHD */ +#define AQ_MsmLineRxGoodFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxGoodFramesCounter_0 in AQ_MsmLineRxGoodFramesCounterRegister_HHD */ +#define AQ_MsmLineRxGoodFramesCounterRegister_HHD_msmLineRxGoodFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxGoodFramesCounter_0 in AQ_MsmLineRxGoodFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineRxGoodFramesCounterRegister_HHD_msmLineRxGoodFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxGoodFramesCounter_0 in AQ_MsmLineRxGoodFramesCounterRegister_HHD */ +#define word_AQ_MsmLineRxGoodFramesCounterRegister_HHD_msmLineRxGoodFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxGoodFramesCounter_1 in AQ_MsmLineRxGoodFramesCounterRegister_HHD */ +#define AQ_MsmLineRxGoodFramesCounterRegister_HHD_msmLineRxGoodFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxGoodFramesCounter_1 in AQ_MsmLineRxGoodFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineRxGoodFramesCounterRegister_HHD_msmLineRxGoodFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxGoodFramesCounter_1 in AQ_MsmLineRxGoodFramesCounterRegister_HHD */ +#define word_AQ_MsmLineRxGoodFramesCounterRegister_HHD_msmLineRxGoodFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmLineRxFcsErrorsCounterRegister_HHD */ +#define AQ_MsmLineRxFcsErrorsCounterRegister_HHD_baseRegisterAddress 0x9048 +/*! \brief MMD address of structure AQ_MsmLineRxFcsErrorsCounterRegister_HHD */ +#define AQ_MsmLineRxFcsErrorsCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLineFcsErrorCounter_0 in AQ_MsmLineRxFcsErrorsCounterRegister_HHD */ +#define AQ_MsmLineRxFcsErrorsCounterRegister_HHD_msmLineFcsErrorCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineFcsErrorCounter_0 in AQ_MsmLineRxFcsErrorsCounterRegister_HHD */ +#define bits_AQ_MsmLineRxFcsErrorsCounterRegister_HHD_msmLineFcsErrorCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineFcsErrorCounter_0 in AQ_MsmLineRxFcsErrorsCounterRegister_HHD */ +#define word_AQ_MsmLineRxFcsErrorsCounterRegister_HHD_msmLineFcsErrorCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineFcsErrorCounter_1 in AQ_MsmLineRxFcsErrorsCounterRegister_HHD */ +#define AQ_MsmLineRxFcsErrorsCounterRegister_HHD_msmLineFcsErrorCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineFcsErrorCounter_1 in AQ_MsmLineRxFcsErrorsCounterRegister_HHD */ +#define bits_AQ_MsmLineRxFcsErrorsCounterRegister_HHD_msmLineFcsErrorCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineFcsErrorCounter_1 in AQ_MsmLineRxFcsErrorsCounterRegister_HHD */ +#define word_AQ_MsmLineRxFcsErrorsCounterRegister_HHD_msmLineFcsErrorCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmLineRxAlignmentErrorsCounterRegister_HHD */ +#define AQ_MsmLineRxAlignmentErrorsCounterRegister_HHD_baseRegisterAddress 0x904C +/*! \brief MMD address of structure AQ_MsmLineRxAlignmentErrorsCounterRegister_HHD */ +#define AQ_MsmLineRxAlignmentErrorsCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLineAlignmentErrorCounter_0 in AQ_MsmLineRxAlignmentErrorsCounterRegister_HHD */ +#define AQ_MsmLineRxAlignmentErrorsCounterRegister_HHD_msmLineAlignmentErrorCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineAlignmentErrorCounter_0 in AQ_MsmLineRxAlignmentErrorsCounterRegister_HHD */ +#define bits_AQ_MsmLineRxAlignmentErrorsCounterRegister_HHD_msmLineAlignmentErrorCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineAlignmentErrorCounter_0 in AQ_MsmLineRxAlignmentErrorsCounterRegister_HHD */ +#define word_AQ_MsmLineRxAlignmentErrorsCounterRegister_HHD_msmLineAlignmentErrorCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineAlignmentErrorCounter_1 in AQ_MsmLineRxAlignmentErrorsCounterRegister_HHD */ +#define AQ_MsmLineRxAlignmentErrorsCounterRegister_HHD_msmLineAlignmentErrorCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineAlignmentErrorCounter_1 in AQ_MsmLineRxAlignmentErrorsCounterRegister_HHD */ +#define bits_AQ_MsmLineRxAlignmentErrorsCounterRegister_HHD_msmLineAlignmentErrorCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineAlignmentErrorCounter_1 in AQ_MsmLineRxAlignmentErrorsCounterRegister_HHD */ +#define word_AQ_MsmLineRxAlignmentErrorsCounterRegister_HHD_msmLineAlignmentErrorCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmLineTxPauseFramesCounterRegister_HHD */ +#define AQ_MsmLineTxPauseFramesCounterRegister_HHD_baseRegisterAddress 0x9050 +/*! \brief MMD address of structure AQ_MsmLineTxPauseFramesCounterRegister_HHD */ +#define AQ_MsmLineTxPauseFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxPauseFramesCounter_0 in AQ_MsmLineTxPauseFramesCounterRegister_HHD */ +#define AQ_MsmLineTxPauseFramesCounterRegister_HHD_msmLineTxPauseFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxPauseFramesCounter_0 in AQ_MsmLineTxPauseFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineTxPauseFramesCounterRegister_HHD_msmLineTxPauseFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxPauseFramesCounter_0 in AQ_MsmLineTxPauseFramesCounterRegister_HHD */ +#define word_AQ_MsmLineTxPauseFramesCounterRegister_HHD_msmLineTxPauseFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxPauseFramesCounter_1 in AQ_MsmLineTxPauseFramesCounterRegister_HHD */ +#define AQ_MsmLineTxPauseFramesCounterRegister_HHD_msmLineTxPauseFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxPauseFramesCounter_1 in AQ_MsmLineTxPauseFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineTxPauseFramesCounterRegister_HHD_msmLineTxPauseFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxPauseFramesCounter_1 in AQ_MsmLineTxPauseFramesCounterRegister_HHD */ +#define word_AQ_MsmLineTxPauseFramesCounterRegister_HHD_msmLineTxPauseFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmLineRxPauseFramesCounterRegister_HHD */ +#define AQ_MsmLineRxPauseFramesCounterRegister_HHD_baseRegisterAddress 0x9054 +/*! \brief MMD address of structure AQ_MsmLineRxPauseFramesCounterRegister_HHD */ +#define AQ_MsmLineRxPauseFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxPauseFramesCounter_0 in AQ_MsmLineRxPauseFramesCounterRegister_HHD */ +#define AQ_MsmLineRxPauseFramesCounterRegister_HHD_msmLineRxPauseFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxPauseFramesCounter_0 in AQ_MsmLineRxPauseFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineRxPauseFramesCounterRegister_HHD_msmLineRxPauseFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxPauseFramesCounter_0 in AQ_MsmLineRxPauseFramesCounterRegister_HHD */ +#define word_AQ_MsmLineRxPauseFramesCounterRegister_HHD_msmLineRxPauseFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxPauseFramesCounter_1 in AQ_MsmLineRxPauseFramesCounterRegister_HHD */ +#define AQ_MsmLineRxPauseFramesCounterRegister_HHD_msmLineRxPauseFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxPauseFramesCounter_1 in AQ_MsmLineRxPauseFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineRxPauseFramesCounterRegister_HHD_msmLineRxPauseFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxPauseFramesCounter_1 in AQ_MsmLineRxPauseFramesCounterRegister_HHD */ +#define word_AQ_MsmLineRxPauseFramesCounterRegister_HHD_msmLineRxPauseFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmLineRxTooLongErrorsCounterRegister_HHD */ +#define AQ_MsmLineRxTooLongErrorsCounterRegister_HHD_baseRegisterAddress 0x9058 +/*! \brief MMD address of structure AQ_MsmLineRxTooLongErrorsCounterRegister_HHD */ +#define AQ_MsmLineRxTooLongErrorsCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxTooLongErrorsCounter_0 in AQ_MsmLineRxTooLongErrorsCounterRegister_HHD */ +#define AQ_MsmLineRxTooLongErrorsCounterRegister_HHD_msmLineRxTooLongErrorsCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxTooLongErrorsCounter_0 in AQ_MsmLineRxTooLongErrorsCounterRegister_HHD */ +#define bits_AQ_MsmLineRxTooLongErrorsCounterRegister_HHD_msmLineRxTooLongErrorsCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxTooLongErrorsCounter_0 in AQ_MsmLineRxTooLongErrorsCounterRegister_HHD */ +#define word_AQ_MsmLineRxTooLongErrorsCounterRegister_HHD_msmLineRxTooLongErrorsCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxTooLongErrorsCounter_1 in AQ_MsmLineRxTooLongErrorsCounterRegister_HHD */ +#define AQ_MsmLineRxTooLongErrorsCounterRegister_HHD_msmLineRxTooLongErrorsCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxTooLongErrorsCounter_1 in AQ_MsmLineRxTooLongErrorsCounterRegister_HHD */ +#define bits_AQ_MsmLineRxTooLongErrorsCounterRegister_HHD_msmLineRxTooLongErrorsCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxTooLongErrorsCounter_1 in AQ_MsmLineRxTooLongErrorsCounterRegister_HHD */ +#define word_AQ_MsmLineRxTooLongErrorsCounterRegister_HHD_msmLineRxTooLongErrorsCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmLineRxInRangeLengthErrorsCounterRegister_HHD */ +#define AQ_MsmLineRxInRangeLengthErrorsCounterRegister_HHD_baseRegisterAddress 0x905C +/*! \brief MMD address of structure AQ_MsmLineRxInRangeLengthErrorsCounterRegister_HHD */ +#define AQ_MsmLineRxInRangeLengthErrorsCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxInRangeLengthErrorsCounter_0 in AQ_MsmLineRxInRangeLengthErrorsCounterRegister_HHD */ +#define AQ_MsmLineRxInRangeLengthErrorsCounterRegister_HHD_msmLineRxInRangeLengthErrorsCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxInRangeLengthErrorsCounter_0 in AQ_MsmLineRxInRangeLengthErrorsCounterRegister_HHD */ +#define bits_AQ_MsmLineRxInRangeLengthErrorsCounterRegister_HHD_msmLineRxInRangeLengthErrorsCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxInRangeLengthErrorsCounter_0 in AQ_MsmLineRxInRangeLengthErrorsCounterRegister_HHD */ +#define word_AQ_MsmLineRxInRangeLengthErrorsCounterRegister_HHD_msmLineRxInRangeLengthErrorsCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxInRangeLengthErrorsCounter_1 in AQ_MsmLineRxInRangeLengthErrorsCounterRegister_HHD */ +#define AQ_MsmLineRxInRangeLengthErrorsCounterRegister_HHD_msmLineRxInRangeLengthErrorsCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxInRangeLengthErrorsCounter_1 in AQ_MsmLineRxInRangeLengthErrorsCounterRegister_HHD */ +#define bits_AQ_MsmLineRxInRangeLengthErrorsCounterRegister_HHD_msmLineRxInRangeLengthErrorsCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxInRangeLengthErrorsCounter_1 in AQ_MsmLineRxInRangeLengthErrorsCounterRegister_HHD */ +#define word_AQ_MsmLineRxInRangeLengthErrorsCounterRegister_HHD_msmLineRxInRangeLengthErrorsCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmLineTxVlanFramesCounterRegister_HHD */ +#define AQ_MsmLineTxVlanFramesCounterRegister_HHD_baseRegisterAddress 0x9060 +/*! \brief MMD address of structure AQ_MsmLineTxVlanFramesCounterRegister_HHD */ +#define AQ_MsmLineTxVlanFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxVlanFramesCounter_0 in AQ_MsmLineTxVlanFramesCounterRegister_HHD */ +#define AQ_MsmLineTxVlanFramesCounterRegister_HHD_msmLineTxVlanFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxVlanFramesCounter_0 in AQ_MsmLineTxVlanFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineTxVlanFramesCounterRegister_HHD_msmLineTxVlanFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxVlanFramesCounter_0 in AQ_MsmLineTxVlanFramesCounterRegister_HHD */ +#define word_AQ_MsmLineTxVlanFramesCounterRegister_HHD_msmLineTxVlanFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxVlanFramesCounter_1 in AQ_MsmLineTxVlanFramesCounterRegister_HHD */ +#define AQ_MsmLineTxVlanFramesCounterRegister_HHD_msmLineTxVlanFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxVlanFramesCounter_1 in AQ_MsmLineTxVlanFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineTxVlanFramesCounterRegister_HHD_msmLineTxVlanFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxVlanFramesCounter_1 in AQ_MsmLineTxVlanFramesCounterRegister_HHD */ +#define word_AQ_MsmLineTxVlanFramesCounterRegister_HHD_msmLineTxVlanFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmLineRxVlanFramesCounterRegister_HHD */ +#define AQ_MsmLineRxVlanFramesCounterRegister_HHD_baseRegisterAddress 0x9064 +/*! \brief MMD address of structure AQ_MsmLineRxVlanFramesCounterRegister_HHD */ +#define AQ_MsmLineRxVlanFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxVlanFramesCounter_0 in AQ_MsmLineRxVlanFramesCounterRegister_HHD */ +#define AQ_MsmLineRxVlanFramesCounterRegister_HHD_msmLineRxVlanFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxVlanFramesCounter_0 in AQ_MsmLineRxVlanFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineRxVlanFramesCounterRegister_HHD_msmLineRxVlanFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxVlanFramesCounter_0 in AQ_MsmLineRxVlanFramesCounterRegister_HHD */ +#define word_AQ_MsmLineRxVlanFramesCounterRegister_HHD_msmLineRxVlanFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxVlanFramesCounter_1 in AQ_MsmLineRxVlanFramesCounterRegister_HHD */ +#define AQ_MsmLineRxVlanFramesCounterRegister_HHD_msmLineRxVlanFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxVlanFramesCounter_1 in AQ_MsmLineRxVlanFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineRxVlanFramesCounterRegister_HHD_msmLineRxVlanFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxVlanFramesCounter_1 in AQ_MsmLineRxVlanFramesCounterRegister_HHD */ +#define word_AQ_MsmLineRxVlanFramesCounterRegister_HHD_msmLineRxVlanFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmLineTxOctetsCounterRegister_HHD */ +#define AQ_MsmLineTxOctetsCounterRegister_HHD_baseRegisterAddress 0x9068 +/*! \brief MMD address of structure AQ_MsmLineTxOctetsCounterRegister_HHD */ +#define AQ_MsmLineTxOctetsCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxOctetsCounter_0 in AQ_MsmLineTxOctetsCounterRegister_HHD */ +#define AQ_MsmLineTxOctetsCounterRegister_HHD_msmLineTxOctetsCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxOctetsCounter_0 in AQ_MsmLineTxOctetsCounterRegister_HHD */ +#define bits_AQ_MsmLineTxOctetsCounterRegister_HHD_msmLineTxOctetsCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxOctetsCounter_0 in AQ_MsmLineTxOctetsCounterRegister_HHD */ +#define word_AQ_MsmLineTxOctetsCounterRegister_HHD_msmLineTxOctetsCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxOctetsCounter_1 in AQ_MsmLineTxOctetsCounterRegister_HHD */ +#define AQ_MsmLineTxOctetsCounterRegister_HHD_msmLineTxOctetsCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxOctetsCounter_1 in AQ_MsmLineTxOctetsCounterRegister_HHD */ +#define bits_AQ_MsmLineTxOctetsCounterRegister_HHD_msmLineTxOctetsCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxOctetsCounter_1 in AQ_MsmLineTxOctetsCounterRegister_HHD */ +#define word_AQ_MsmLineTxOctetsCounterRegister_HHD_msmLineTxOctetsCounter_1 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxOctetsCounter_2 in AQ_MsmLineTxOctetsCounterRegister_HHD */ +#define AQ_MsmLineTxOctetsCounterRegister_HHD_msmLineTxOctetsCounter_2 2 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxOctetsCounter_2 in AQ_MsmLineTxOctetsCounterRegister_HHD */ +#define bits_AQ_MsmLineTxOctetsCounterRegister_HHD_msmLineTxOctetsCounter_2 u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxOctetsCounter_2 in AQ_MsmLineTxOctetsCounterRegister_HHD */ +#define word_AQ_MsmLineTxOctetsCounterRegister_HHD_msmLineTxOctetsCounter_2 u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxOctetsCounter_3 in AQ_MsmLineTxOctetsCounterRegister_HHD */ +#define AQ_MsmLineTxOctetsCounterRegister_HHD_msmLineTxOctetsCounter_3 3 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxOctetsCounter_3 in AQ_MsmLineTxOctetsCounterRegister_HHD */ +#define bits_AQ_MsmLineTxOctetsCounterRegister_HHD_msmLineTxOctetsCounter_3 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxOctetsCounter_3 in AQ_MsmLineTxOctetsCounterRegister_HHD */ +#define word_AQ_MsmLineTxOctetsCounterRegister_HHD_msmLineTxOctetsCounter_3 u3.word_3 + +/*! \brief Base register address of structure AQ_MsmLineRxOctetsCounterRegister_HHD */ +#define AQ_MsmLineRxOctetsCounterRegister_HHD_baseRegisterAddress 0x906C +/*! \brief MMD address of structure AQ_MsmLineRxOctetsCounterRegister_HHD */ +#define AQ_MsmLineRxOctetsCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxOctetsCounter_0 in AQ_MsmLineRxOctetsCounterRegister_HHD */ +#define AQ_MsmLineRxOctetsCounterRegister_HHD_msmLineRxOctetsCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxOctetsCounter_0 in AQ_MsmLineRxOctetsCounterRegister_HHD */ +#define bits_AQ_MsmLineRxOctetsCounterRegister_HHD_msmLineRxOctetsCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxOctetsCounter_0 in AQ_MsmLineRxOctetsCounterRegister_HHD */ +#define word_AQ_MsmLineRxOctetsCounterRegister_HHD_msmLineRxOctetsCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxOctetsCounter_1 in AQ_MsmLineRxOctetsCounterRegister_HHD */ +#define AQ_MsmLineRxOctetsCounterRegister_HHD_msmLineRxOctetsCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxOctetsCounter_1 in AQ_MsmLineRxOctetsCounterRegister_HHD */ +#define bits_AQ_MsmLineRxOctetsCounterRegister_HHD_msmLineRxOctetsCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxOctetsCounter_1 in AQ_MsmLineRxOctetsCounterRegister_HHD */ +#define word_AQ_MsmLineRxOctetsCounterRegister_HHD_msmLineRxOctetsCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmLineRxUnicastFramesCounterRegister_HHD */ +#define AQ_MsmLineRxUnicastFramesCounterRegister_HHD_baseRegisterAddress 0x9070 +/*! \brief MMD address of structure AQ_MsmLineRxUnicastFramesCounterRegister_HHD */ +#define AQ_MsmLineRxUnicastFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxUnicastFramesCounter_0 in AQ_MsmLineRxUnicastFramesCounterRegister_HHD */ +#define AQ_MsmLineRxUnicastFramesCounterRegister_HHD_msmLineRxUnicastFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxUnicastFramesCounter_0 in AQ_MsmLineRxUnicastFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineRxUnicastFramesCounterRegister_HHD_msmLineRxUnicastFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxUnicastFramesCounter_0 in AQ_MsmLineRxUnicastFramesCounterRegister_HHD */ +#define word_AQ_MsmLineRxUnicastFramesCounterRegister_HHD_msmLineRxUnicastFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxUnicastFramesCounter_1 in AQ_MsmLineRxUnicastFramesCounterRegister_HHD */ +#define AQ_MsmLineRxUnicastFramesCounterRegister_HHD_msmLineRxUnicastFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxUnicastFramesCounter_1 in AQ_MsmLineRxUnicastFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineRxUnicastFramesCounterRegister_HHD_msmLineRxUnicastFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxUnicastFramesCounter_1 in AQ_MsmLineRxUnicastFramesCounterRegister_HHD */ +#define word_AQ_MsmLineRxUnicastFramesCounterRegister_HHD_msmLineRxUnicastFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmLineRxMulticastFramesCounterRegister_HHD */ +#define AQ_MsmLineRxMulticastFramesCounterRegister_HHD_baseRegisterAddress 0x9074 +/*! \brief MMD address of structure AQ_MsmLineRxMulticastFramesCounterRegister_HHD */ +#define AQ_MsmLineRxMulticastFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxMulticastFramesCounter_0 in AQ_MsmLineRxMulticastFramesCounterRegister_HHD */ +#define AQ_MsmLineRxMulticastFramesCounterRegister_HHD_msmLineRxMulticastFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxMulticastFramesCounter_0 in AQ_MsmLineRxMulticastFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineRxMulticastFramesCounterRegister_HHD_msmLineRxMulticastFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxMulticastFramesCounter_0 in AQ_MsmLineRxMulticastFramesCounterRegister_HHD */ +#define word_AQ_MsmLineRxMulticastFramesCounterRegister_HHD_msmLineRxMulticastFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxMulticastFramesCounter_1 in AQ_MsmLineRxMulticastFramesCounterRegister_HHD */ +#define AQ_MsmLineRxMulticastFramesCounterRegister_HHD_msmLineRxMulticastFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxMulticastFramesCounter_1 in AQ_MsmLineRxMulticastFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineRxMulticastFramesCounterRegister_HHD_msmLineRxMulticastFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxMulticastFramesCounter_1 in AQ_MsmLineRxMulticastFramesCounterRegister_HHD */ +#define word_AQ_MsmLineRxMulticastFramesCounterRegister_HHD_msmLineRxMulticastFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmLineRxBroadcastFramesCounterRegister_HHD */ +#define AQ_MsmLineRxBroadcastFramesCounterRegister_HHD_baseRegisterAddress 0x9078 +/*! \brief MMD address of structure AQ_MsmLineRxBroadcastFramesCounterRegister_HHD */ +#define AQ_MsmLineRxBroadcastFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxBroadcastFramesCounter_0 in AQ_MsmLineRxBroadcastFramesCounterRegister_HHD */ +#define AQ_MsmLineRxBroadcastFramesCounterRegister_HHD_msmLineRxBroadcastFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxBroadcastFramesCounter_0 in AQ_MsmLineRxBroadcastFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineRxBroadcastFramesCounterRegister_HHD_msmLineRxBroadcastFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxBroadcastFramesCounter_0 in AQ_MsmLineRxBroadcastFramesCounterRegister_HHD */ +#define word_AQ_MsmLineRxBroadcastFramesCounterRegister_HHD_msmLineRxBroadcastFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxBroadcastFramesCounter_1 in AQ_MsmLineRxBroadcastFramesCounterRegister_HHD */ +#define AQ_MsmLineRxBroadcastFramesCounterRegister_HHD_msmLineRxBroadcastFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxBroadcastFramesCounter_1 in AQ_MsmLineRxBroadcastFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineRxBroadcastFramesCounterRegister_HHD_msmLineRxBroadcastFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxBroadcastFramesCounter_1 in AQ_MsmLineRxBroadcastFramesCounterRegister_HHD */ +#define word_AQ_MsmLineRxBroadcastFramesCounterRegister_HHD_msmLineRxBroadcastFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmLineTxErrorsCounterRegister_HHD */ +#define AQ_MsmLineTxErrorsCounterRegister_HHD_baseRegisterAddress 0x907C +/*! \brief MMD address of structure AQ_MsmLineTxErrorsCounterRegister_HHD */ +#define AQ_MsmLineTxErrorsCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxErrorsCounter_0 in AQ_MsmLineTxErrorsCounterRegister_HHD */ +#define AQ_MsmLineTxErrorsCounterRegister_HHD_msmLineTxErrorsCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxErrorsCounter_0 in AQ_MsmLineTxErrorsCounterRegister_HHD */ +#define bits_AQ_MsmLineTxErrorsCounterRegister_HHD_msmLineTxErrorsCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxErrorsCounter_0 in AQ_MsmLineTxErrorsCounterRegister_HHD */ +#define word_AQ_MsmLineTxErrorsCounterRegister_HHD_msmLineTxErrorsCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxErrorsCounter_1 in AQ_MsmLineTxErrorsCounterRegister_HHD */ +#define AQ_MsmLineTxErrorsCounterRegister_HHD_msmLineTxErrorsCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxErrorsCounter_1 in AQ_MsmLineTxErrorsCounterRegister_HHD */ +#define bits_AQ_MsmLineTxErrorsCounterRegister_HHD_msmLineTxErrorsCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxErrorsCounter_1 in AQ_MsmLineTxErrorsCounterRegister_HHD */ +#define word_AQ_MsmLineTxErrorsCounterRegister_HHD_msmLineTxErrorsCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmLineTxUnicastFramesCounterRegister_HHD */ +#define AQ_MsmLineTxUnicastFramesCounterRegister_HHD_baseRegisterAddress 0x9084 +/*! \brief MMD address of structure AQ_MsmLineTxUnicastFramesCounterRegister_HHD */ +#define AQ_MsmLineTxUnicastFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxUnicastFramesCounter_0 in AQ_MsmLineTxUnicastFramesCounterRegister_HHD */ +#define AQ_MsmLineTxUnicastFramesCounterRegister_HHD_msmLineTxUnicastFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxUnicastFramesCounter_0 in AQ_MsmLineTxUnicastFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineTxUnicastFramesCounterRegister_HHD_msmLineTxUnicastFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxUnicastFramesCounter_0 in AQ_MsmLineTxUnicastFramesCounterRegister_HHD */ +#define word_AQ_MsmLineTxUnicastFramesCounterRegister_HHD_msmLineTxUnicastFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxUnicastFramesCounter_1 in AQ_MsmLineTxUnicastFramesCounterRegister_HHD */ +#define AQ_MsmLineTxUnicastFramesCounterRegister_HHD_msmLineTxUnicastFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxUnicastFramesCounter_1 in AQ_MsmLineTxUnicastFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineTxUnicastFramesCounterRegister_HHD_msmLineTxUnicastFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxUnicastFramesCounter_1 in AQ_MsmLineTxUnicastFramesCounterRegister_HHD */ +#define word_AQ_MsmLineTxUnicastFramesCounterRegister_HHD_msmLineTxUnicastFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmLineTxMulticastFramesCounterRegister_HHD */ +#define AQ_MsmLineTxMulticastFramesCounterRegister_HHD_baseRegisterAddress 0x9088 +/*! \brief MMD address of structure AQ_MsmLineTxMulticastFramesCounterRegister_HHD */ +#define AQ_MsmLineTxMulticastFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxMulticastFramesCounter_0 in AQ_MsmLineTxMulticastFramesCounterRegister_HHD */ +#define AQ_MsmLineTxMulticastFramesCounterRegister_HHD_msmLineTxMulticastFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxMulticastFramesCounter_0 in AQ_MsmLineTxMulticastFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineTxMulticastFramesCounterRegister_HHD_msmLineTxMulticastFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxMulticastFramesCounter_0 in AQ_MsmLineTxMulticastFramesCounterRegister_HHD */ +#define word_AQ_MsmLineTxMulticastFramesCounterRegister_HHD_msmLineTxMulticastFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxMulticastFramesCounter_1 in AQ_MsmLineTxMulticastFramesCounterRegister_HHD */ +#define AQ_MsmLineTxMulticastFramesCounterRegister_HHD_msmLineTxMulticastFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxMulticastFramesCounter_1 in AQ_MsmLineTxMulticastFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineTxMulticastFramesCounterRegister_HHD_msmLineTxMulticastFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxMulticastFramesCounter_1 in AQ_MsmLineTxMulticastFramesCounterRegister_HHD */ +#define word_AQ_MsmLineTxMulticastFramesCounterRegister_HHD_msmLineTxMulticastFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmLineTxBroadcastFramesCounterRegister_HHD */ +#define AQ_MsmLineTxBroadcastFramesCounterRegister_HHD_baseRegisterAddress 0x908C +/*! \brief MMD address of structure AQ_MsmLineTxBroadcastFramesCounterRegister_HHD */ +#define AQ_MsmLineTxBroadcastFramesCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxBroadcastFramesCounter_0 in AQ_MsmLineTxBroadcastFramesCounterRegister_HHD */ +#define AQ_MsmLineTxBroadcastFramesCounterRegister_HHD_msmLineTxBroadcastFramesCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxBroadcastFramesCounter_0 in AQ_MsmLineTxBroadcastFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineTxBroadcastFramesCounterRegister_HHD_msmLineTxBroadcastFramesCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxBroadcastFramesCounter_0 in AQ_MsmLineTxBroadcastFramesCounterRegister_HHD */ +#define word_AQ_MsmLineTxBroadcastFramesCounterRegister_HHD_msmLineTxBroadcastFramesCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineTxBroadcastFramesCounter_1 in AQ_MsmLineTxBroadcastFramesCounterRegister_HHD */ +#define AQ_MsmLineTxBroadcastFramesCounterRegister_HHD_msmLineTxBroadcastFramesCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineTxBroadcastFramesCounter_1 in AQ_MsmLineTxBroadcastFramesCounterRegister_HHD */ +#define bits_AQ_MsmLineTxBroadcastFramesCounterRegister_HHD_msmLineTxBroadcastFramesCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineTxBroadcastFramesCounter_1 in AQ_MsmLineTxBroadcastFramesCounterRegister_HHD */ +#define word_AQ_MsmLineTxBroadcastFramesCounterRegister_HHD_msmLineTxBroadcastFramesCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_MsmLineRxErrorsCounterRegister_HHD */ +#define AQ_MsmLineRxErrorsCounterRegister_HHD_baseRegisterAddress 0x90C8 +/*! \brief MMD address of structure AQ_MsmLineRxErrorsCounterRegister_HHD */ +#define AQ_MsmLineRxErrorsCounterRegister_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxErrorsCounter_0 in AQ_MsmLineRxErrorsCounterRegister_HHD */ +#define AQ_MsmLineRxErrorsCounterRegister_HHD_msmLineRxErrorsCounter_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxErrorsCounter_0 in AQ_MsmLineRxErrorsCounterRegister_HHD */ +#define bits_AQ_MsmLineRxErrorsCounterRegister_HHD_msmLineRxErrorsCounter_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxErrorsCounter_0 in AQ_MsmLineRxErrorsCounterRegister_HHD */ +#define word_AQ_MsmLineRxErrorsCounterRegister_HHD_msmLineRxErrorsCounter_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure msmLineRxErrorsCounter_1 in AQ_MsmLineRxErrorsCounterRegister_HHD */ +#define AQ_MsmLineRxErrorsCounterRegister_HHD_msmLineRxErrorsCounter_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure msmLineRxErrorsCounter_1 in AQ_MsmLineRxErrorsCounterRegister_HHD */ +#define bits_AQ_MsmLineRxErrorsCounterRegister_HHD_msmLineRxErrorsCounter_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure msmLineRxErrorsCounter_1 in AQ_MsmLineRxErrorsCounterRegister_HHD */ +#define word_AQ_MsmLineRxErrorsCounterRegister_HHD_msmLineRxErrorsCounter_1 u1.word_1 + +/*! \brief Base register address of structure AQ_GlobalControl_HHD */ +#define AQ_GlobalControl_HHD_baseRegisterAddress 0xC000 +/*! \brief MMD address of structure AQ_GlobalControl_HHD */ +#define AQ_GlobalControl_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure upReset in AQ_GlobalControl_HHD */ +#define AQ_GlobalControl_HHD_upReset 1 +/*! \brief Preprocessor variable to relate field to bit position in structure upReset in AQ_GlobalControl_HHD */ +#define bits_AQ_GlobalControl_HHD_upReset u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure upReset in AQ_GlobalControl_HHD */ +#define word_AQ_GlobalControl_HHD_upReset u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure upRunStallOverride in AQ_GlobalControl_HHD */ +#define AQ_GlobalControl_HHD_upRunStallOverride 1 +/*! \brief Preprocessor variable to relate field to bit position in structure upRunStallOverride in AQ_GlobalControl_HHD */ +#define bits_AQ_GlobalControl_HHD_upRunStallOverride u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure upRunStallOverride in AQ_GlobalControl_HHD */ +#define word_AQ_GlobalControl_HHD_upRunStallOverride u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure upRunStall in AQ_GlobalControl_HHD */ +#define AQ_GlobalControl_HHD_upRunStall 1 +/*! \brief Preprocessor variable to relate field to bit position in structure upRunStall in AQ_GlobalControl_HHD */ +#define bits_AQ_GlobalControl_HHD_upRunStall u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure upRunStall in AQ_GlobalControl_HHD */ +#define word_AQ_GlobalControl_HHD_upRunStall u1.word_1 + +/*! \brief Base register address of structure AQ_GlobalResetControl_HHD */ +#define AQ_GlobalResetControl_HHD_baseRegisterAddress 0xC006 +/*! \brief MMD address of structure AQ_GlobalResetControl_HHD */ +#define AQ_GlobalResetControl_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure globalMMD_ResetDisable in AQ_GlobalResetControl_HHD */ +#define AQ_GlobalResetControl_HHD_globalMMD_ResetDisable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure globalMMD_ResetDisable in AQ_GlobalResetControl_HHD */ +#define bits_AQ_GlobalResetControl_HHD_globalMMD_ResetDisable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure globalMMD_ResetDisable in AQ_GlobalResetControl_HHD */ +#define word_AQ_GlobalResetControl_HHD_globalMMD_ResetDisable u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalDiagnosticProvisioning_HHD */ +#define AQ_GlobalDiagnosticProvisioning_HHD_baseRegisterAddress 0xC400 +/*! \brief MMD address of structure AQ_GlobalDiagnosticProvisioning_HHD */ +#define AQ_GlobalDiagnosticProvisioning_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure enableDiagnostics in AQ_GlobalDiagnosticProvisioning_HHD */ +#define AQ_GlobalDiagnosticProvisioning_HHD_enableDiagnostics 0 +/*! \brief Preprocessor variable to relate field to bit position in structure enableDiagnostics in AQ_GlobalDiagnosticProvisioning_HHD */ +#define bits_AQ_GlobalDiagnosticProvisioning_HHD_enableDiagnostics u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure enableDiagnostics in AQ_GlobalDiagnosticProvisioning_HHD */ +#define word_AQ_GlobalDiagnosticProvisioning_HHD_enableDiagnostics u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalThermalProvisioning_HHD */ +#define AQ_GlobalThermalProvisioning_HHD_baseRegisterAddress 0xC420 +/*! \brief MMD address of structure AQ_GlobalThermalProvisioning_HHD */ +#define AQ_GlobalThermalProvisioning_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure reserved_0 in AQ_GlobalThermalProvisioning_HHD */ +#define AQ_GlobalThermalProvisioning_HHD_reserved_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_0 in AQ_GlobalThermalProvisioning_HHD */ +#define bits_AQ_GlobalThermalProvisioning_HHD_reserved_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_0 in AQ_GlobalThermalProvisioning_HHD */ +#define word_AQ_GlobalThermalProvisioning_HHD_reserved_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure highTempFailureThreshold in AQ_GlobalThermalProvisioning_HHD */ +#define AQ_GlobalThermalProvisioning_HHD_highTempFailureThreshold 1 +/*! \brief Preprocessor variable to relate field to bit position in structure highTempFailureThreshold in AQ_GlobalThermalProvisioning_HHD */ +#define bits_AQ_GlobalThermalProvisioning_HHD_highTempFailureThreshold u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure highTempFailureThreshold in AQ_GlobalThermalProvisioning_HHD */ +#define word_AQ_GlobalThermalProvisioning_HHD_highTempFailureThreshold u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure lowTempFailureThreshold in AQ_GlobalThermalProvisioning_HHD */ +#define AQ_GlobalThermalProvisioning_HHD_lowTempFailureThreshold 2 +/*! \brief Preprocessor variable to relate field to bit position in structure lowTempFailureThreshold in AQ_GlobalThermalProvisioning_HHD */ +#define bits_AQ_GlobalThermalProvisioning_HHD_lowTempFailureThreshold u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure lowTempFailureThreshold in AQ_GlobalThermalProvisioning_HHD */ +#define word_AQ_GlobalThermalProvisioning_HHD_lowTempFailureThreshold u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure highTempWarningThreshold in AQ_GlobalThermalProvisioning_HHD */ +#define AQ_GlobalThermalProvisioning_HHD_highTempWarningThreshold 3 +/*! \brief Preprocessor variable to relate field to bit position in structure highTempWarningThreshold in AQ_GlobalThermalProvisioning_HHD */ +#define bits_AQ_GlobalThermalProvisioning_HHD_highTempWarningThreshold u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure highTempWarningThreshold in AQ_GlobalThermalProvisioning_HHD */ +#define word_AQ_GlobalThermalProvisioning_HHD_highTempWarningThreshold u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure lowTempWarningThreshold in AQ_GlobalThermalProvisioning_HHD */ +#define AQ_GlobalThermalProvisioning_HHD_lowTempWarningThreshold 4 +/*! \brief Preprocessor variable to relate field to bit position in structure lowTempWarningThreshold in AQ_GlobalThermalProvisioning_HHD */ +#define bits_AQ_GlobalThermalProvisioning_HHD_lowTempWarningThreshold u4.bits_4 +/*! \brief Preprocessor variable to relate field to word position in structure lowTempWarningThreshold in AQ_GlobalThermalProvisioning_HHD */ +#define word_AQ_GlobalThermalProvisioning_HHD_lowTempWarningThreshold u4.word_4 + +/*! \brief Base register address of structure AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_baseRegisterAddress 0xC430 +/*! \brief MMD address of structure AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure reservedProvisioningC430 in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_reservedProvisioningC430 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedProvisioningC430 in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_reservedProvisioningC430 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reservedProvisioningC430 in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_reservedProvisioningC430 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure led_0ManualSet in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_0ManualSet 0 +/*! \brief Preprocessor variable to relate field to bit position in structure led_0ManualSet in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_0ManualSet u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure led_0ManualSet in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_0ManualSet u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure led_0_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_0_10Gb_sLinkEstablished 0 +/*! \brief Preprocessor variable to relate field to bit position in structure led_0_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_0_10Gb_sLinkEstablished u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure led_0_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_0_10Gb_sLinkEstablished u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure led_0_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_0_1Gb_sLinkEstablished 0 +/*! \brief Preprocessor variable to relate field to bit position in structure led_0_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_0_1Gb_sLinkEstablished u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure led_0_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_0_1Gb_sLinkEstablished u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure led_0_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_0_100Mb_sLinkEstablished 0 +/*! \brief Preprocessor variable to relate field to bit position in structure led_0_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_0_100Mb_sLinkEstablished u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure led_0_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_0_100Mb_sLinkEstablished u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure led_0Connecting in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_0Connecting 0 +/*! \brief Preprocessor variable to relate field to bit position in structure led_0Connecting in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_0Connecting u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure led_0Connecting in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_0Connecting u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure led_0ReceiveActivity in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_0ReceiveActivity 0 +/*! \brief Preprocessor variable to relate field to bit position in structure led_0ReceiveActivity in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_0ReceiveActivity u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure led_0ReceiveActivity in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_0ReceiveActivity u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure led_0TransmitActivity in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_0TransmitActivity 0 +/*! \brief Preprocessor variable to relate field to bit position in structure led_0TransmitActivity in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_0TransmitActivity u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure led_0TransmitActivity in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_0TransmitActivity u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure led_0ActivityStretch in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_0ActivityStretch 0 +/*! \brief Preprocessor variable to relate field to bit position in structure led_0ActivityStretch in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_0ActivityStretch u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure led_0ActivityStretch in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_0ActivityStretch u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reservedProvisioningC431 in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_reservedProvisioningC431 1 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedProvisioningC431 in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_reservedProvisioningC431 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure reservedProvisioningC431 in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_reservedProvisioningC431 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure led_1ManualSet in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_1ManualSet 1 +/*! \brief Preprocessor variable to relate field to bit position in structure led_1ManualSet in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_1ManualSet u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure led_1ManualSet in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_1ManualSet u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure led_1_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_1_10Gb_sLinkEstablished 1 +/*! \brief Preprocessor variable to relate field to bit position in structure led_1_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_1_10Gb_sLinkEstablished u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure led_1_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_1_10Gb_sLinkEstablished u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure led_1_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_1_1Gb_sLinkEstablished 1 +/*! \brief Preprocessor variable to relate field to bit position in structure led_1_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_1_1Gb_sLinkEstablished u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure led_1_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_1_1Gb_sLinkEstablished u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure led_1_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_1_100Mb_sLinkEstablished 1 +/*! \brief Preprocessor variable to relate field to bit position in structure led_1_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_1_100Mb_sLinkEstablished u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure led_1_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_1_100Mb_sLinkEstablished u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure led_1Connecting in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_1Connecting 1 +/*! \brief Preprocessor variable to relate field to bit position in structure led_1Connecting in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_1Connecting u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure led_1Connecting in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_1Connecting u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure led_1ReceiveActivity in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_1ReceiveActivity 1 +/*! \brief Preprocessor variable to relate field to bit position in structure led_1ReceiveActivity in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_1ReceiveActivity u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure led_1ReceiveActivity in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_1ReceiveActivity u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure led_1TransmitActivity in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_1TransmitActivity 1 +/*! \brief Preprocessor variable to relate field to bit position in structure led_1TransmitActivity in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_1TransmitActivity u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure led_1TransmitActivity in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_1TransmitActivity u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure led_1ActivityStretch in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_1ActivityStretch 1 +/*! \brief Preprocessor variable to relate field to bit position in structure led_1ActivityStretch in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_1ActivityStretch u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure led_1ActivityStretch in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_1ActivityStretch u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure reservedProvisioningC432 in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_reservedProvisioningC432 2 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedProvisioningC432 in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_reservedProvisioningC432 u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure reservedProvisioningC432 in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_reservedProvisioningC432 u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure led_2ManualSet in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_2ManualSet 2 +/*! \brief Preprocessor variable to relate field to bit position in structure led_2ManualSet in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_2ManualSet u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure led_2ManualSet in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_2ManualSet u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure led_2_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_2_10Gb_sLinkEstablished 2 +/*! \brief Preprocessor variable to relate field to bit position in structure led_2_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_2_10Gb_sLinkEstablished u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure led_2_10Gb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_2_10Gb_sLinkEstablished u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure led_2_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_2_1Gb_sLinkEstablished 2 +/*! \brief Preprocessor variable to relate field to bit position in structure led_2_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_2_1Gb_sLinkEstablished u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure led_2_1Gb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_2_1Gb_sLinkEstablished u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure led_2_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_2_100Mb_sLinkEstablished 2 +/*! \brief Preprocessor variable to relate field to bit position in structure led_2_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_2_100Mb_sLinkEstablished u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure led_2_100Mb_sLinkEstablished in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_2_100Mb_sLinkEstablished u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure led_2Connecting in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_2Connecting 2 +/*! \brief Preprocessor variable to relate field to bit position in structure led_2Connecting in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_2Connecting u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure led_2Connecting in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_2Connecting u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure led_2ReceiveActivity in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_2ReceiveActivity 2 +/*! \brief Preprocessor variable to relate field to bit position in structure led_2ReceiveActivity in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_2ReceiveActivity u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure led_2ReceiveActivity in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_2ReceiveActivity u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure led_2TransmitActivity in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_2TransmitActivity 2 +/*! \brief Preprocessor variable to relate field to bit position in structure led_2TransmitActivity in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_2TransmitActivity u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure led_2TransmitActivity in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_2TransmitActivity u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure led_2ActivityStretch in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_led_2ActivityStretch 2 +/*! \brief Preprocessor variable to relate field to bit position in structure led_2ActivityStretch in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_led_2ActivityStretch u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure led_2ActivityStretch in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_led_2ActivityStretch u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure ledOperationMode in AQ_GlobalLedProvisioning_HHD */ +#define AQ_GlobalLedProvisioning_HHD_ledOperationMode 7 +/*! \brief Preprocessor variable to relate field to bit position in structure ledOperationMode in AQ_GlobalLedProvisioning_HHD */ +#define bits_AQ_GlobalLedProvisioning_HHD_ledOperationMode u7.bits_7 +/*! \brief Preprocessor variable to relate field to word position in structure ledOperationMode in AQ_GlobalLedProvisioning_HHD */ +#define word_AQ_GlobalLedProvisioning_HHD_ledOperationMode u7.word_7 + +/*! \brief Base register address of structure AQ_GlobalGeneralProvisioning_HHD */ +#define AQ_GlobalGeneralProvisioning_HHD_baseRegisterAddress 0xC440 +/*! \brief MMD address of structure AQ_GlobalGeneralProvisioning_HHD */ +#define AQ_GlobalGeneralProvisioning_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure mdioBroadcastModeEnable in AQ_GlobalGeneralProvisioning_HHD */ +#define AQ_GlobalGeneralProvisioning_HHD_mdioBroadcastModeEnable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioBroadcastModeEnable in AQ_GlobalGeneralProvisioning_HHD */ +#define bits_AQ_GlobalGeneralProvisioning_HHD_mdioBroadcastModeEnable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mdioBroadcastModeEnable in AQ_GlobalGeneralProvisioning_HHD */ +#define word_AQ_GlobalGeneralProvisioning_HHD_mdioBroadcastModeEnable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mdioReadMSW_FirstEnable in AQ_GlobalGeneralProvisioning_HHD */ +#define AQ_GlobalGeneralProvisioning_HHD_mdioReadMSW_FirstEnable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioReadMSW_FirstEnable in AQ_GlobalGeneralProvisioning_HHD */ +#define bits_AQ_GlobalGeneralProvisioning_HHD_mdioReadMSW_FirstEnable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mdioReadMSW_FirstEnable in AQ_GlobalGeneralProvisioning_HHD */ +#define word_AQ_GlobalGeneralProvisioning_HHD_mdioReadMSW_FirstEnable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mdioDriveConfiguration in AQ_GlobalGeneralProvisioning_HHD */ +#define AQ_GlobalGeneralProvisioning_HHD_mdioDriveConfiguration 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioDriveConfiguration in AQ_GlobalGeneralProvisioning_HHD */ +#define bits_AQ_GlobalGeneralProvisioning_HHD_mdioDriveConfiguration u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mdioDriveConfiguration in AQ_GlobalGeneralProvisioning_HHD */ +#define word_AQ_GlobalGeneralProvisioning_HHD_mdioDriveConfiguration u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mdioPreambleDetectionDisable in AQ_GlobalGeneralProvisioning_HHD */ +#define AQ_GlobalGeneralProvisioning_HHD_mdioPreambleDetectionDisable 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioPreambleDetectionDisable in AQ_GlobalGeneralProvisioning_HHD */ +#define bits_AQ_GlobalGeneralProvisioning_HHD_mdioPreambleDetectionDisable u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mdioPreambleDetectionDisable in AQ_GlobalGeneralProvisioning_HHD */ +#define word_AQ_GlobalGeneralProvisioning_HHD_mdioPreambleDetectionDisable u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure daisyChainReset in AQ_GlobalGeneralProvisioning_HHD */ +#define AQ_GlobalGeneralProvisioning_HHD_daisyChainReset 2 +/*! \brief Preprocessor variable to relate field to bit position in structure daisyChainReset in AQ_GlobalGeneralProvisioning_HHD */ +#define bits_AQ_GlobalGeneralProvisioning_HHD_daisyChainReset u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure daisyChainReset in AQ_GlobalGeneralProvisioning_HHD */ +#define word_AQ_GlobalGeneralProvisioning_HHD_daisyChainReset u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure mdioBroadcastAddressConfiguration in AQ_GlobalGeneralProvisioning_HHD */ +#define AQ_GlobalGeneralProvisioning_HHD_mdioBroadcastAddressConfiguration 7 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioBroadcastAddressConfiguration in AQ_GlobalGeneralProvisioning_HHD */ +#define bits_AQ_GlobalGeneralProvisioning_HHD_mdioBroadcastAddressConfiguration u7.bits_7 +/*! \brief Preprocessor variable to relate field to word position in structure mdioBroadcastAddressConfiguration in AQ_GlobalGeneralProvisioning_HHD */ +#define word_AQ_GlobalGeneralProvisioning_HHD_mdioBroadcastAddressConfiguration u7.word_7 +/*! \brief Preprocessor variable to relate field to word number in structure mdioPreambleLength in AQ_GlobalGeneralProvisioning_HHD */ +#define AQ_GlobalGeneralProvisioning_HHD_mdioPreambleLength 9 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioPreambleLength in AQ_GlobalGeneralProvisioning_HHD */ +#define bits_AQ_GlobalGeneralProvisioning_HHD_mdioPreambleLength u9.bits_9 +/*! \brief Preprocessor variable to relate field to word position in structure mdioPreambleLength in AQ_GlobalGeneralProvisioning_HHD */ +#define word_AQ_GlobalGeneralProvisioning_HHD_mdioPreambleLength u9.word_9 + +/*! \brief Base register address of structure AQ_GlobalNvrProvisioning_HHD */ +#define AQ_GlobalNvrProvisioning_HHD_baseRegisterAddress 0xC450 +/*! \brief MMD address of structure AQ_GlobalNvrProvisioning_HHD */ +#define AQ_GlobalNvrProvisioning_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure nvrDataLength in AQ_GlobalNvrProvisioning_HHD */ +#define AQ_GlobalNvrProvisioning_HHD_nvrDataLength 0 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrDataLength in AQ_GlobalNvrProvisioning_HHD */ +#define bits_AQ_GlobalNvrProvisioning_HHD_nvrDataLength u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure nvrDataLength in AQ_GlobalNvrProvisioning_HHD */ +#define word_AQ_GlobalNvrProvisioning_HHD_nvrDataLength u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure nvrDummyLength in AQ_GlobalNvrProvisioning_HHD */ +#define AQ_GlobalNvrProvisioning_HHD_nvrDummyLength 0 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrDummyLength in AQ_GlobalNvrProvisioning_HHD */ +#define bits_AQ_GlobalNvrProvisioning_HHD_nvrDummyLength u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure nvrDummyLength in AQ_GlobalNvrProvisioning_HHD */ +#define word_AQ_GlobalNvrProvisioning_HHD_nvrDummyLength u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure nvrAddressLength in AQ_GlobalNvrProvisioning_HHD */ +#define AQ_GlobalNvrProvisioning_HHD_nvrAddressLength 0 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrAddressLength in AQ_GlobalNvrProvisioning_HHD */ +#define bits_AQ_GlobalNvrProvisioning_HHD_nvrAddressLength u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure nvrAddressLength in AQ_GlobalNvrProvisioning_HHD */ +#define word_AQ_GlobalNvrProvisioning_HHD_nvrAddressLength u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure nvrAddressLengthOverride in AQ_GlobalNvrProvisioning_HHD */ +#define AQ_GlobalNvrProvisioning_HHD_nvrAddressLengthOverride 1 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrAddressLengthOverride in AQ_GlobalNvrProvisioning_HHD */ +#define bits_AQ_GlobalNvrProvisioning_HHD_nvrAddressLengthOverride u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure nvrAddressLengthOverride in AQ_GlobalNvrProvisioning_HHD */ +#define word_AQ_GlobalNvrProvisioning_HHD_nvrAddressLengthOverride u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure nvrClockDivide in AQ_GlobalNvrProvisioning_HHD */ +#define AQ_GlobalNvrProvisioning_HHD_nvrClockDivide 1 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrClockDivide in AQ_GlobalNvrProvisioning_HHD */ +#define bits_AQ_GlobalNvrProvisioning_HHD_nvrClockDivide u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure nvrClockDivide in AQ_GlobalNvrProvisioning_HHD */ +#define word_AQ_GlobalNvrProvisioning_HHD_nvrClockDivide u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure nvrDaisyChainClockDivideOverride in AQ_GlobalNvrProvisioning_HHD */ +#define AQ_GlobalNvrProvisioning_HHD_nvrDaisyChainClockDivideOverride 2 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrDaisyChainClockDivideOverride in AQ_GlobalNvrProvisioning_HHD */ +#define bits_AQ_GlobalNvrProvisioning_HHD_nvrDaisyChainClockDivideOverride u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure nvrDaisyChainClockDivideOverride in AQ_GlobalNvrProvisioning_HHD */ +#define word_AQ_GlobalNvrProvisioning_HHD_nvrDaisyChainClockDivideOverride u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure nvrDaisyChainDisable in AQ_GlobalNvrProvisioning_HHD */ +#define AQ_GlobalNvrProvisioning_HHD_nvrDaisyChainDisable 2 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrDaisyChainDisable in AQ_GlobalNvrProvisioning_HHD */ +#define bits_AQ_GlobalNvrProvisioning_HHD_nvrDaisyChainDisable u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure nvrDaisyChainDisable in AQ_GlobalNvrProvisioning_HHD */ +#define word_AQ_GlobalNvrProvisioning_HHD_nvrDaisyChainDisable u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure nvrReset in AQ_GlobalNvrProvisioning_HHD */ +#define AQ_GlobalNvrProvisioning_HHD_nvrReset 3 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrReset in AQ_GlobalNvrProvisioning_HHD */ +#define bits_AQ_GlobalNvrProvisioning_HHD_nvrReset u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure nvrReset in AQ_GlobalNvrProvisioning_HHD */ +#define word_AQ_GlobalNvrProvisioning_HHD_nvrReset u3.word_3 + +/*! \brief Base register address of structure AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_baseRegisterAddress 0xC470 +/*! \brief MMD address of structure AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure diagnosticsSelect in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_diagnosticsSelect 0 +/*! \brief Preprocessor variable to relate field to bit position in structure diagnosticsSelect in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_diagnosticsSelect u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure diagnosticsSelect in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_diagnosticsSelect u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure extendedMdiDiagnosticsSelect in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_extendedMdiDiagnosticsSelect 0 +/*! \brief Preprocessor variable to relate field to bit position in structure extendedMdiDiagnosticsSelect in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_extendedMdiDiagnosticsSelect u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure extendedMdiDiagnosticsSelect in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_extendedMdiDiagnosticsSelect u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure initiateCableDiagnostics in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_initiateCableDiagnostics 0 +/*! \brief Preprocessor variable to relate field to bit position in structure initiateCableDiagnostics in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_initiateCableDiagnostics u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure initiateCableDiagnostics in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_initiateCableDiagnostics u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure enableDaisy_chainHop_countOverride in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_enableDaisy_chainHop_countOverride 1 +/*! \brief Preprocessor variable to relate field to bit position in structure enableDaisy_chainHop_countOverride in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_enableDaisy_chainHop_countOverride u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure enableDaisy_chainHop_countOverride in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_enableDaisy_chainHop_countOverride u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure daisy_chainHop_countOverrideValue in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_daisy_chainHop_countOverrideValue 1 +/*! \brief Preprocessor variable to relate field to bit position in structure daisy_chainHop_countOverrideValue in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_daisy_chainHop_countOverrideValue u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure daisy_chainHop_countOverrideValue in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_daisy_chainHop_countOverrideValue u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure enableVddPowerSupplyTuning in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_enableVddPowerSupplyTuning 2 +/*! \brief Preprocessor variable to relate field to bit position in structure enableVddPowerSupplyTuning in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_enableVddPowerSupplyTuning u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure enableVddPowerSupplyTuning in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_enableVddPowerSupplyTuning u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure tunableExternalVddPowerSupplyPresent in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_tunableExternalVddPowerSupplyPresent 2 +/*! \brief Preprocessor variable to relate field to bit position in structure tunableExternalVddPowerSupplyPresent in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_tunableExternalVddPowerSupplyPresent u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure tunableExternalVddPowerSupplyPresent in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_tunableExternalVddPowerSupplyPresent u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure externalVddChangeRequest in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_externalVddChangeRequest 2 +/*! \brief Preprocessor variable to relate field to bit position in structure externalVddChangeRequest in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_externalVddChangeRequest u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure externalVddChangeRequest in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_externalVddChangeRequest u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure enableXenpakRegisterSpace in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_enableXenpakRegisterSpace 2 +/*! \brief Preprocessor variable to relate field to bit position in structure enableXenpakRegisterSpace in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_enableXenpakRegisterSpace u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure enableXenpakRegisterSpace in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_enableXenpakRegisterSpace u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure enable_5thChannelRfiCancellation in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_enable_5thChannelRfiCancellation 2 +/*! \brief Preprocessor variable to relate field to bit position in structure enable_5thChannelRfiCancellation in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_enable_5thChannelRfiCancellation u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure enable_5thChannelRfiCancellation in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_enable_5thChannelRfiCancellation u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure rateTransitionRequest in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_rateTransitionRequest 3 +/*! \brief Preprocessor variable to relate field to bit position in structure rateTransitionRequest in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_rateTransitionRequest u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure rateTransitionRequest in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_rateTransitionRequest u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure trainingSNR in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_trainingSNR 3 +/*! \brief Preprocessor variable to relate field to bit position in structure trainingSNR in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_trainingSNR u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure trainingSNR in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_trainingSNR u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure reservedProvisioning_5 in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_reservedProvisioning_5 4 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedProvisioning_5 in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_reservedProvisioning_5 u4.bits_4 +/*! \brief Preprocessor variable to relate field to word position in structure reservedProvisioning_5 in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_reservedProvisioning_5 u4.word_4 +/*! \brief Preprocessor variable to relate field to word number in structure nvrDaisyChainKickstart in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_nvrDaisyChainKickstart 4 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrDaisyChainKickstart in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_nvrDaisyChainKickstart u4.bits_4 +/*! \brief Preprocessor variable to relate field to word position in structure nvrDaisyChainKickstart in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_nvrDaisyChainKickstart u4.word_4 +/*! \brief Preprocessor variable to relate field to word number in structure smartPower_downStatus in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_smartPower_downStatus 5 +/*! \brief Preprocessor variable to relate field to bit position in structure smartPower_downStatus in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_smartPower_downStatus u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure smartPower_downStatus in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_smartPower_downStatus u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure reservedProvisioning_6 in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_reservedProvisioning_6 5 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedProvisioning_6 in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_reservedProvisioning_6 u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure reservedProvisioning_6 in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_reservedProvisioning_6 u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure cfrLpDisableTimer in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_cfrLpDisableTimer 5 +/*! \brief Preprocessor variable to relate field to bit position in structure cfrLpDisableTimer in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_cfrLpDisableTimer u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure cfrLpDisableTimer in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_cfrLpDisableTimer u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure cfrLpExtendedMaxwait in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_cfrLpExtendedMaxwait 5 +/*! \brief Preprocessor variable to relate field to bit position in structure cfrLpExtendedMaxwait in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_cfrLpExtendedMaxwait u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure cfrLpExtendedMaxwait in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_cfrLpExtendedMaxwait u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure cfrLpTHP in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_cfrLpTHP 5 +/*! \brief Preprocessor variable to relate field to bit position in structure cfrLpTHP in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_cfrLpTHP u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure cfrLpTHP in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_cfrLpTHP u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure cfrLpSupport in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_cfrLpSupport 5 +/*! \brief Preprocessor variable to relate field to bit position in structure cfrLpSupport in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_cfrLpSupport u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure cfrLpSupport in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_cfrLpSupport u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure cfrDisableTimer in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_cfrDisableTimer 5 +/*! \brief Preprocessor variable to relate field to bit position in structure cfrDisableTimer in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_cfrDisableTimer u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure cfrDisableTimer in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_cfrDisableTimer u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure cfrExtendedMaxwait in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_cfrExtendedMaxwait 5 +/*! \brief Preprocessor variable to relate field to bit position in structure cfrExtendedMaxwait in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_cfrExtendedMaxwait u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure cfrExtendedMaxwait in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_cfrExtendedMaxwait u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure cfrTHP in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_cfrTHP 5 +/*! \brief Preprocessor variable to relate field to bit position in structure cfrTHP in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_cfrTHP u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure cfrTHP in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_cfrTHP u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure cfrSupport in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_cfrSupport 5 +/*! \brief Preprocessor variable to relate field to bit position in structure cfrSupport in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_cfrSupport u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure cfrSupport in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_cfrSupport u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure deadlockAvoidanceEnable in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_deadlockAvoidanceEnable 5 +/*! \brief Preprocessor variable to relate field to bit position in structure deadlockAvoidanceEnable in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_deadlockAvoidanceEnable u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure deadlockAvoidanceEnable in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_deadlockAvoidanceEnable u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure smartPower_downEnable in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_smartPower_downEnable 5 +/*! \brief Preprocessor variable to relate field to bit position in structure smartPower_downEnable in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_smartPower_downEnable u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure smartPower_downEnable in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_smartPower_downEnable u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure dteEnable in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_dteEnable 8 +/*! \brief Preprocessor variable to relate field to bit position in structure dteEnable in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_dteEnable u8.bits_8 +/*! \brief Preprocessor variable to relate field to word position in structure dteEnable in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_dteEnable u8.word_8 +/*! \brief Preprocessor variable to relate field to word number in structure dteDropReportingTimer in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_dteDropReportingTimer 8 +/*! \brief Preprocessor variable to relate field to bit position in structure dteDropReportingTimer in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_dteDropReportingTimer u8.bits_8 +/*! \brief Preprocessor variable to relate field to word position in structure dteDropReportingTimer in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_dteDropReportingTimer u8.word_8 +/*! \brief Preprocessor variable to relate field to word number in structure reservedProvisioning_9 in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_reservedProvisioning_9 8 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedProvisioning_9 in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_reservedProvisioning_9 u8.bits_8 +/*! \brief Preprocessor variable to relate field to word position in structure reservedProvisioning_9 in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_reservedProvisioning_9 u8.word_8 +/*! \brief Preprocessor variable to relate field to word number in structure powerUpStall in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_powerUpStall 9 +/*! \brief Preprocessor variable to relate field to bit position in structure powerUpStall in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_powerUpStall u9.bits_9 +/*! \brief Preprocessor variable to relate field to word position in structure powerUpStall in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_powerUpStall u9.word_9 +/*! \brief Preprocessor variable to relate field to word number in structure reservedProvisioning_10 in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_reservedProvisioning_10 9 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedProvisioning_10 in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_reservedProvisioning_10 u9.bits_9 +/*! \brief Preprocessor variable to relate field to word position in structure reservedProvisioning_10 in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_reservedProvisioning_10 u9.word_9 +/*! \brief Preprocessor variable to relate field to word number in structure loopbackControl in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_loopbackControl 10 +/*! \brief Preprocessor variable to relate field to bit position in structure loopbackControl in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_loopbackControl u10.bits_10 +/*! \brief Preprocessor variable to relate field to word position in structure loopbackControl in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_loopbackControl u10.word_10 +/*! \brief Preprocessor variable to relate field to word number in structure reservedProvisioning_11 in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_reservedProvisioning_11 10 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedProvisioning_11 in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_reservedProvisioning_11 u10.bits_10 +/*! \brief Preprocessor variable to relate field to word position in structure reservedProvisioning_11 in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_reservedProvisioning_11 u10.word_10 +/*! \brief Preprocessor variable to relate field to word number in structure mdiPacketGeneration in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_mdiPacketGeneration 10 +/*! \brief Preprocessor variable to relate field to bit position in structure mdiPacketGeneration in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_mdiPacketGeneration u10.bits_10 +/*! \brief Preprocessor variable to relate field to word position in structure mdiPacketGeneration in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_mdiPacketGeneration u10.word_10 +/*! \brief Preprocessor variable to relate field to word number in structure look_asidePortPacketGeneration in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_look_asidePortPacketGeneration 10 +/*! \brief Preprocessor variable to relate field to bit position in structure look_asidePortPacketGeneration in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_look_asidePortPacketGeneration u10.bits_10 +/*! \brief Preprocessor variable to relate field to word position in structure look_asidePortPacketGeneration in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_look_asidePortPacketGeneration u10.word_10 +/*! \brief Preprocessor variable to relate field to word number in structure systemI_fPacketGeneration in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_systemI_fPacketGeneration 10 +/*! \brief Preprocessor variable to relate field to bit position in structure systemI_fPacketGeneration in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_systemI_fPacketGeneration u10.bits_10 +/*! \brief Preprocessor variable to relate field to word position in structure systemI_fPacketGeneration in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_systemI_fPacketGeneration u10.word_10 +/*! \brief Preprocessor variable to relate field to word number in structure reservedProvisioning_11a in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_reservedProvisioning_11a 10 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedProvisioning_11a in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_reservedProvisioning_11a u10.bits_10 +/*! \brief Preprocessor variable to relate field to word position in structure reservedProvisioning_11a in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_reservedProvisioning_11a u10.word_10 +/*! \brief Preprocessor variable to relate field to word number in structure rate in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_rate 10 +/*! \brief Preprocessor variable to relate field to bit position in structure rate in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_rate u10.bits_10 +/*! \brief Preprocessor variable to relate field to word position in structure rate in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_rate u10.word_10 +/*! \brief Preprocessor variable to relate field to word number in structure reservedProvisioning_12 in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_reservedProvisioning_12 11 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedProvisioning_12 in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_reservedProvisioning_12 u11.bits_11 +/*! \brief Preprocessor variable to relate field to word position in structure reservedProvisioning_12 in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_reservedProvisioning_12 u11.word_11 +/*! \brief Preprocessor variable to relate field to word number in structure enableMacsec in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_enableMacsec 11 +/*! \brief Preprocessor variable to relate field to bit position in structure enableMacsec in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_enableMacsec u11.bits_11 +/*! \brief Preprocessor variable to relate field to word position in structure enableMacsec in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_enableMacsec u11.word_11 +/*! \brief Preprocessor variable to relate field to word number in structure enablePtp in AQ_GlobalReservedProvisioning_HHD */ +#define AQ_GlobalReservedProvisioning_HHD_enablePtp 11 +/*! \brief Preprocessor variable to relate field to bit position in structure enablePtp in AQ_GlobalReservedProvisioning_HHD */ +#define bits_AQ_GlobalReservedProvisioning_HHD_enablePtp u11.bits_11 +/*! \brief Preprocessor variable to relate field to word position in structure enablePtp in AQ_GlobalReservedProvisioning_HHD */ +#define word_AQ_GlobalReservedProvisioning_HHD_enablePtp u11.word_11 + +/*! \brief Base register address of structure AQ_PifMailboxControl_HHD */ +#define AQ_PifMailboxControl_HHD_baseRegisterAddress 0xC47C +/*! \brief MMD address of structure AQ_PifMailboxControl_HHD */ +#define AQ_PifMailboxControl_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure pifMailboxAddress in AQ_PifMailboxControl_HHD */ +#define AQ_PifMailboxControl_HHD_pifMailboxAddress 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pifMailboxAddress in AQ_PifMailboxControl_HHD */ +#define bits_AQ_PifMailboxControl_HHD_pifMailboxAddress u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pifMailboxAddress in AQ_PifMailboxControl_HHD */ +#define word_AQ_PifMailboxControl_HHD_pifMailboxAddress u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pifMailboxData in AQ_PifMailboxControl_HHD */ +#define AQ_PifMailboxControl_HHD_pifMailboxData 1 +/*! \brief Preprocessor variable to relate field to bit position in structure pifMailboxData in AQ_PifMailboxControl_HHD */ +#define bits_AQ_PifMailboxControl_HHD_pifMailboxData u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure pifMailboxData in AQ_PifMailboxControl_HHD */ +#define word_AQ_PifMailboxControl_HHD_pifMailboxData u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure reservedPifMailboxControl_3 in AQ_PifMailboxControl_HHD */ +#define AQ_PifMailboxControl_HHD_reservedPifMailboxControl_3 2 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedPifMailboxControl_3 in AQ_PifMailboxControl_HHD */ +#define bits_AQ_PifMailboxControl_HHD_reservedPifMailboxControl_3 u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure reservedPifMailboxControl_3 in AQ_PifMailboxControl_HHD */ +#define word_AQ_PifMailboxControl_HHD_reservedPifMailboxControl_3 u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure pifMailboxCommandType in AQ_PifMailboxControl_HHD */ +#define AQ_PifMailboxControl_HHD_pifMailboxCommandType 2 +/*! \brief Preprocessor variable to relate field to bit position in structure pifMailboxCommandType in AQ_PifMailboxControl_HHD */ +#define bits_AQ_PifMailboxControl_HHD_pifMailboxCommandType u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure pifMailboxCommandType in AQ_PifMailboxControl_HHD */ +#define word_AQ_PifMailboxControl_HHD_pifMailboxCommandType u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure pifMailboxMMD in AQ_PifMailboxControl_HHD */ +#define AQ_PifMailboxControl_HHD_pifMailboxMMD 2 +/*! \brief Preprocessor variable to relate field to bit position in structure pifMailboxMMD in AQ_PifMailboxControl_HHD */ +#define bits_AQ_PifMailboxControl_HHD_pifMailboxMMD u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure pifMailboxMMD in AQ_PifMailboxControl_HHD */ +#define word_AQ_PifMailboxControl_HHD_pifMailboxMMD u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure reservedPifMailboxControl_4 in AQ_PifMailboxControl_HHD */ +#define AQ_PifMailboxControl_HHD_reservedPifMailboxControl_4 3 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedPifMailboxControl_4 in AQ_PifMailboxControl_HHD */ +#define bits_AQ_PifMailboxControl_HHD_reservedPifMailboxControl_4 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure reservedPifMailboxControl_4 in AQ_PifMailboxControl_HHD */ +#define word_AQ_PifMailboxControl_HHD_reservedPifMailboxControl_4 u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure pifMailboxCommandStatus in AQ_PifMailboxControl_HHD */ +#define AQ_PifMailboxControl_HHD_pifMailboxCommandStatus 3 +/*! \brief Preprocessor variable to relate field to bit position in structure pifMailboxCommandStatus in AQ_PifMailboxControl_HHD */ +#define bits_AQ_PifMailboxControl_HHD_pifMailboxCommandStatus u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure pifMailboxCommandStatus in AQ_PifMailboxControl_HHD */ +#define word_AQ_PifMailboxControl_HHD_pifMailboxCommandStatus u3.word_3 + +/*! \brief Base register address of structure AQ_GlobalSmbus_0Provisioning_HHD */ +#define AQ_GlobalSmbus_0Provisioning_HHD_baseRegisterAddress 0xC485 +/*! \brief MMD address of structure AQ_GlobalSmbus_0Provisioning_HHD */ +#define AQ_GlobalSmbus_0Provisioning_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure smb_0SlaveAddress in AQ_GlobalSmbus_0Provisioning_HHD */ +#define AQ_GlobalSmbus_0Provisioning_HHD_smb_0SlaveAddress 0 +/*! \brief Preprocessor variable to relate field to bit position in structure smb_0SlaveAddress in AQ_GlobalSmbus_0Provisioning_HHD */ +#define bits_AQ_GlobalSmbus_0Provisioning_HHD_smb_0SlaveAddress u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure smb_0SlaveAddress in AQ_GlobalSmbus_0Provisioning_HHD */ +#define word_AQ_GlobalSmbus_0Provisioning_HHD_smb_0SlaveAddress u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalSmbus_1Provisioning_HHD */ +#define AQ_GlobalSmbus_1Provisioning_HHD_baseRegisterAddress 0xC495 +/*! \brief MMD address of structure AQ_GlobalSmbus_1Provisioning_HHD */ +#define AQ_GlobalSmbus_1Provisioning_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure smb_1SlaveAddress in AQ_GlobalSmbus_1Provisioning_HHD */ +#define AQ_GlobalSmbus_1Provisioning_HHD_smb_1SlaveAddress 0 +/*! \brief Preprocessor variable to relate field to bit position in structure smb_1SlaveAddress in AQ_GlobalSmbus_1Provisioning_HHD */ +#define bits_AQ_GlobalSmbus_1Provisioning_HHD_smb_1SlaveAddress u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure smb_1SlaveAddress in AQ_GlobalSmbus_1Provisioning_HHD */ +#define word_AQ_GlobalSmbus_1Provisioning_HHD_smb_1SlaveAddress u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalEeeProvisioning_HHD */ +#define AQ_GlobalEeeProvisioning_HHD_baseRegisterAddress 0xC4A0 +/*! \brief MMD address of structure AQ_GlobalEeeProvisioning_HHD */ +#define AQ_GlobalEeeProvisioning_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure eeeMode in AQ_GlobalEeeProvisioning_HHD */ +#define AQ_GlobalEeeProvisioning_HHD_eeeMode 0 +/*! \brief Preprocessor variable to relate field to bit position in structure eeeMode in AQ_GlobalEeeProvisioning_HHD */ +#define bits_AQ_GlobalEeeProvisioning_HHD_eeeMode u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure eeeMode in AQ_GlobalEeeProvisioning_HHD */ +#define word_AQ_GlobalEeeProvisioning_HHD_eeeMode u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalCableDiagnosticStatus_HHD */ +#define AQ_GlobalCableDiagnosticStatus_HHD_baseRegisterAddress 0xC800 +/*! \brief MMD address of structure AQ_GlobalCableDiagnosticStatus_HHD */ +#define AQ_GlobalCableDiagnosticStatus_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure pairAStatus in AQ_GlobalCableDiagnosticStatus_HHD */ +#define AQ_GlobalCableDiagnosticStatus_HHD_pairAStatus 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pairAStatus in AQ_GlobalCableDiagnosticStatus_HHD */ +#define bits_AQ_GlobalCableDiagnosticStatus_HHD_pairAStatus u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pairAStatus in AQ_GlobalCableDiagnosticStatus_HHD */ +#define word_AQ_GlobalCableDiagnosticStatus_HHD_pairAStatus u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pairBStatus in AQ_GlobalCableDiagnosticStatus_HHD */ +#define AQ_GlobalCableDiagnosticStatus_HHD_pairBStatus 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pairBStatus in AQ_GlobalCableDiagnosticStatus_HHD */ +#define bits_AQ_GlobalCableDiagnosticStatus_HHD_pairBStatus u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pairBStatus in AQ_GlobalCableDiagnosticStatus_HHD */ +#define word_AQ_GlobalCableDiagnosticStatus_HHD_pairBStatus u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pairCStatus in AQ_GlobalCableDiagnosticStatus_HHD */ +#define AQ_GlobalCableDiagnosticStatus_HHD_pairCStatus 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pairCStatus in AQ_GlobalCableDiagnosticStatus_HHD */ +#define bits_AQ_GlobalCableDiagnosticStatus_HHD_pairCStatus u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pairCStatus in AQ_GlobalCableDiagnosticStatus_HHD */ +#define word_AQ_GlobalCableDiagnosticStatus_HHD_pairCStatus u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pairDStatus in AQ_GlobalCableDiagnosticStatus_HHD */ +#define AQ_GlobalCableDiagnosticStatus_HHD_pairDStatus 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pairDStatus in AQ_GlobalCableDiagnosticStatus_HHD */ +#define bits_AQ_GlobalCableDiagnosticStatus_HHD_pairDStatus u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pairDStatus in AQ_GlobalCableDiagnosticStatus_HHD */ +#define word_AQ_GlobalCableDiagnosticStatus_HHD_pairDStatus u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pairAReflection_1 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define AQ_GlobalCableDiagnosticStatus_HHD_pairAReflection_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure pairAReflection_1 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define bits_AQ_GlobalCableDiagnosticStatus_HHD_pairAReflection_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure pairAReflection_1 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define word_AQ_GlobalCableDiagnosticStatus_HHD_pairAReflection_1 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure pairAReflection_2 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define AQ_GlobalCableDiagnosticStatus_HHD_pairAReflection_2 1 +/*! \brief Preprocessor variable to relate field to bit position in structure pairAReflection_2 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define bits_AQ_GlobalCableDiagnosticStatus_HHD_pairAReflection_2 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure pairAReflection_2 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define word_AQ_GlobalCableDiagnosticStatus_HHD_pairAReflection_2 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure impulseResponseMSW in AQ_GlobalCableDiagnosticStatus_HHD */ +#define AQ_GlobalCableDiagnosticStatus_HHD_impulseResponseMSW 2 +/*! \brief Preprocessor variable to relate field to bit position in structure impulseResponseMSW in AQ_GlobalCableDiagnosticStatus_HHD */ +#define bits_AQ_GlobalCableDiagnosticStatus_HHD_impulseResponseMSW u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure impulseResponseMSW in AQ_GlobalCableDiagnosticStatus_HHD */ +#define word_AQ_GlobalCableDiagnosticStatus_HHD_impulseResponseMSW u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure pairBReflection_1 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define AQ_GlobalCableDiagnosticStatus_HHD_pairBReflection_1 3 +/*! \brief Preprocessor variable to relate field to bit position in structure pairBReflection_1 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define bits_AQ_GlobalCableDiagnosticStatus_HHD_pairBReflection_1 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure pairBReflection_1 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define word_AQ_GlobalCableDiagnosticStatus_HHD_pairBReflection_1 u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure pairBReflection_2 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define AQ_GlobalCableDiagnosticStatus_HHD_pairBReflection_2 3 +/*! \brief Preprocessor variable to relate field to bit position in structure pairBReflection_2 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define bits_AQ_GlobalCableDiagnosticStatus_HHD_pairBReflection_2 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure pairBReflection_2 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define word_AQ_GlobalCableDiagnosticStatus_HHD_pairBReflection_2 u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure impulseResponseLSW in AQ_GlobalCableDiagnosticStatus_HHD */ +#define AQ_GlobalCableDiagnosticStatus_HHD_impulseResponseLSW 4 +/*! \brief Preprocessor variable to relate field to bit position in structure impulseResponseLSW in AQ_GlobalCableDiagnosticStatus_HHD */ +#define bits_AQ_GlobalCableDiagnosticStatus_HHD_impulseResponseLSW u4.bits_4 +/*! \brief Preprocessor variable to relate field to word position in structure impulseResponseLSW in AQ_GlobalCableDiagnosticStatus_HHD */ +#define word_AQ_GlobalCableDiagnosticStatus_HHD_impulseResponseLSW u4.word_4 +/*! \brief Preprocessor variable to relate field to word number in structure pairCReflection_1 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define AQ_GlobalCableDiagnosticStatus_HHD_pairCReflection_1 5 +/*! \brief Preprocessor variable to relate field to bit position in structure pairCReflection_1 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define bits_AQ_GlobalCableDiagnosticStatus_HHD_pairCReflection_1 u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure pairCReflection_1 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define word_AQ_GlobalCableDiagnosticStatus_HHD_pairCReflection_1 u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure pairCReflection_2 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define AQ_GlobalCableDiagnosticStatus_HHD_pairCReflection_2 5 +/*! \brief Preprocessor variable to relate field to bit position in structure pairCReflection_2 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define bits_AQ_GlobalCableDiagnosticStatus_HHD_pairCReflection_2 u5.bits_5 +/*! \brief Preprocessor variable to relate field to word position in structure pairCReflection_2 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define word_AQ_GlobalCableDiagnosticStatus_HHD_pairCReflection_2 u5.word_5 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_1 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define AQ_GlobalCableDiagnosticStatus_HHD_reserved_1 6 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_1 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define bits_AQ_GlobalCableDiagnosticStatus_HHD_reserved_1 u6.bits_6 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_1 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define word_AQ_GlobalCableDiagnosticStatus_HHD_reserved_1 u6.word_6 +/*! \brief Preprocessor variable to relate field to word number in structure pairDReflection_1 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define AQ_GlobalCableDiagnosticStatus_HHD_pairDReflection_1 7 +/*! \brief Preprocessor variable to relate field to bit position in structure pairDReflection_1 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define bits_AQ_GlobalCableDiagnosticStatus_HHD_pairDReflection_1 u7.bits_7 +/*! \brief Preprocessor variable to relate field to word position in structure pairDReflection_1 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define word_AQ_GlobalCableDiagnosticStatus_HHD_pairDReflection_1 u7.word_7 +/*! \brief Preprocessor variable to relate field to word number in structure pairDReflection_2 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define AQ_GlobalCableDiagnosticStatus_HHD_pairDReflection_2 7 +/*! \brief Preprocessor variable to relate field to bit position in structure pairDReflection_2 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define bits_AQ_GlobalCableDiagnosticStatus_HHD_pairDReflection_2 u7.bits_7 +/*! \brief Preprocessor variable to relate field to word position in structure pairDReflection_2 in AQ_GlobalCableDiagnosticStatus_HHD */ +#define word_AQ_GlobalCableDiagnosticStatus_HHD_pairDReflection_2 u7.word_7 + +/*! \brief Base register address of structure AQ_GlobalThermalStatus_HHD */ +#define AQ_GlobalThermalStatus_HHD_baseRegisterAddress 0xC820 +/*! \brief MMD address of structure AQ_GlobalThermalStatus_HHD */ +#define AQ_GlobalThermalStatus_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure temperature in AQ_GlobalThermalStatus_HHD */ +#define AQ_GlobalThermalStatus_HHD_temperature 0 +/*! \brief Preprocessor variable to relate field to bit position in structure temperature in AQ_GlobalThermalStatus_HHD */ +#define bits_AQ_GlobalThermalStatus_HHD_temperature u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure temperature in AQ_GlobalThermalStatus_HHD */ +#define word_AQ_GlobalThermalStatus_HHD_temperature u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure temperatureReady in AQ_GlobalThermalStatus_HHD */ +#define AQ_GlobalThermalStatus_HHD_temperatureReady 1 +/*! \brief Preprocessor variable to relate field to bit position in structure temperatureReady in AQ_GlobalThermalStatus_HHD */ +#define bits_AQ_GlobalThermalStatus_HHD_temperatureReady u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure temperatureReady in AQ_GlobalThermalStatus_HHD */ +#define word_AQ_GlobalThermalStatus_HHD_temperatureReady u1.word_1 + +/*! \brief Base register address of structure AQ_GlobalGeneralStatus_HHD */ +#define AQ_GlobalGeneralStatus_HHD_baseRegisterAddress 0xC830 +/*! \brief MMD address of structure AQ_GlobalGeneralStatus_HHD */ +#define AQ_GlobalGeneralStatus_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure highTemperatureFailureState in AQ_GlobalGeneralStatus_HHD */ +#define AQ_GlobalGeneralStatus_HHD_highTemperatureFailureState 0 +/*! \brief Preprocessor variable to relate field to bit position in structure highTemperatureFailureState in AQ_GlobalGeneralStatus_HHD */ +#define bits_AQ_GlobalGeneralStatus_HHD_highTemperatureFailureState u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure highTemperatureFailureState in AQ_GlobalGeneralStatus_HHD */ +#define word_AQ_GlobalGeneralStatus_HHD_highTemperatureFailureState u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure lowTemperatureFailureState in AQ_GlobalGeneralStatus_HHD */ +#define AQ_GlobalGeneralStatus_HHD_lowTemperatureFailureState 0 +/*! \brief Preprocessor variable to relate field to bit position in structure lowTemperatureFailureState in AQ_GlobalGeneralStatus_HHD */ +#define bits_AQ_GlobalGeneralStatus_HHD_lowTemperatureFailureState u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure lowTemperatureFailureState in AQ_GlobalGeneralStatus_HHD */ +#define word_AQ_GlobalGeneralStatus_HHD_lowTemperatureFailureState u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure highTemperatureWarningState in AQ_GlobalGeneralStatus_HHD */ +#define AQ_GlobalGeneralStatus_HHD_highTemperatureWarningState 0 +/*! \brief Preprocessor variable to relate field to bit position in structure highTemperatureWarningState in AQ_GlobalGeneralStatus_HHD */ +#define bits_AQ_GlobalGeneralStatus_HHD_highTemperatureWarningState u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure highTemperatureWarningState in AQ_GlobalGeneralStatus_HHD */ +#define word_AQ_GlobalGeneralStatus_HHD_highTemperatureWarningState u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure lowTemperatureWarningState in AQ_GlobalGeneralStatus_HHD */ +#define AQ_GlobalGeneralStatus_HHD_lowTemperatureWarningState 0 +/*! \brief Preprocessor variable to relate field to bit position in structure lowTemperatureWarningState in AQ_GlobalGeneralStatus_HHD */ +#define bits_AQ_GlobalGeneralStatus_HHD_lowTemperatureWarningState u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure lowTemperatureWarningState in AQ_GlobalGeneralStatus_HHD */ +#define word_AQ_GlobalGeneralStatus_HHD_lowTemperatureWarningState u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure processorIntensiveMdioOperationIn_Progress in AQ_GlobalGeneralStatus_HHD */ +#define AQ_GlobalGeneralStatus_HHD_processorIntensiveMdioOperationIn_Progress 1 +/*! \brief Preprocessor variable to relate field to bit position in structure processorIntensiveMdioOperationIn_Progress in AQ_GlobalGeneralStatus_HHD */ +#define bits_AQ_GlobalGeneralStatus_HHD_processorIntensiveMdioOperationIn_Progress u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure processorIntensiveMdioOperationIn_Progress in AQ_GlobalGeneralStatus_HHD */ +#define word_AQ_GlobalGeneralStatus_HHD_processorIntensiveMdioOperationIn_Progress u1.word_1 + +/*! \brief Base register address of structure AQ_GlobalPinStatus_HHD */ +#define AQ_GlobalPinStatus_HHD_baseRegisterAddress 0xC840 +/*! \brief MMD address of structure AQ_GlobalPinStatus_HHD */ +#define AQ_GlobalPinStatus_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure dcMasterN in AQ_GlobalPinStatus_HHD */ +#define AQ_GlobalPinStatus_HHD_dcMasterN 0 +/*! \brief Preprocessor variable to relate field to bit position in structure dcMasterN in AQ_GlobalPinStatus_HHD */ +#define bits_AQ_GlobalPinStatus_HHD_dcMasterN u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure dcMasterN in AQ_GlobalPinStatus_HHD */ +#define word_AQ_GlobalPinStatus_HHD_dcMasterN u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure packageConnectivity in AQ_GlobalPinStatus_HHD */ +#define AQ_GlobalPinStatus_HHD_packageConnectivity 0 +/*! \brief Preprocessor variable to relate field to bit position in structure packageConnectivity in AQ_GlobalPinStatus_HHD */ +#define bits_AQ_GlobalPinStatus_HHD_packageConnectivity u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure packageConnectivity in AQ_GlobalPinStatus_HHD */ +#define word_AQ_GlobalPinStatus_HHD_packageConnectivity u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure txEnable in AQ_GlobalPinStatus_HHD */ +#define AQ_GlobalPinStatus_HHD_txEnable 0 +/*! \brief Preprocessor variable to relate field to bit position in structure txEnable in AQ_GlobalPinStatus_HHD */ +#define bits_AQ_GlobalPinStatus_HHD_txEnable u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure txEnable in AQ_GlobalPinStatus_HHD */ +#define word_AQ_GlobalPinStatus_HHD_txEnable u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure ledPullupState in AQ_GlobalPinStatus_HHD */ +#define AQ_GlobalPinStatus_HHD_ledPullupState 0 +/*! \brief Preprocessor variable to relate field to bit position in structure ledPullupState in AQ_GlobalPinStatus_HHD */ +#define bits_AQ_GlobalPinStatus_HHD_ledPullupState u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure ledPullupState in AQ_GlobalPinStatus_HHD */ +#define word_AQ_GlobalPinStatus_HHD_ledPullupState u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalDaisyChainStatus_HHD */ +#define AQ_GlobalDaisyChainStatus_HHD_baseRegisterAddress 0xC842 +/*! \brief MMD address of structure AQ_GlobalDaisyChainStatus_HHD */ +#define AQ_GlobalDaisyChainStatus_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure rxDaisyChainCalculatedCrc in AQ_GlobalDaisyChainStatus_HHD */ +#define AQ_GlobalDaisyChainStatus_HHD_rxDaisyChainCalculatedCrc 0 +/*! \brief Preprocessor variable to relate field to bit position in structure rxDaisyChainCalculatedCrc in AQ_GlobalDaisyChainStatus_HHD */ +#define bits_AQ_GlobalDaisyChainStatus_HHD_rxDaisyChainCalculatedCrc u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure rxDaisyChainCalculatedCrc in AQ_GlobalDaisyChainStatus_HHD */ +#define word_AQ_GlobalDaisyChainStatus_HHD_rxDaisyChainCalculatedCrc u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalFaultMessage_HHD */ +#define AQ_GlobalFaultMessage_HHD_baseRegisterAddress 0xC850 +/*! \brief MMD address of structure AQ_GlobalFaultMessage_HHD */ +#define AQ_GlobalFaultMessage_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure message in AQ_GlobalFaultMessage_HHD */ +#define AQ_GlobalFaultMessage_HHD_message 0 +/*! \brief Preprocessor variable to relate field to bit position in structure message in AQ_GlobalFaultMessage_HHD */ +#define bits_AQ_GlobalFaultMessage_HHD_message u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure message in AQ_GlobalFaultMessage_HHD */ +#define word_AQ_GlobalFaultMessage_HHD_message u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_baseRegisterAddress 0xC880 +/*! \brief MMD address of structure AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure reserved_1 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_reserved_1 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_1 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_1 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_1 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_1 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pairAReflection_1 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_pairAReflection_1 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pairAReflection_1 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_pairAReflection_1 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pairAReflection_1 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_pairAReflection_1 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_2 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_reserved_2 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_2 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_2 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_2 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_2 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pairAReflection_2 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_pairAReflection_2 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pairAReflection_2 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_pairAReflection_2 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pairAReflection_2 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_pairAReflection_2 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_3 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_reserved_3 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_3 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_3 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_3 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_3 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pairAReflection_3 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_pairAReflection_3 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pairAReflection_3 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_pairAReflection_3 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pairAReflection_3 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_pairAReflection_3 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_4 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_reserved_4 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_4 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_4 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_4 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_4 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pairAReflection_4 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_pairAReflection_4 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pairAReflection_4 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_pairAReflection_4 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pairAReflection_4 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_pairAReflection_4 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_5 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_reserved_5 1 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_5 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_5 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_5 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_5 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure pairBReflection_1 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_pairBReflection_1 1 +/*! \brief Preprocessor variable to relate field to bit position in structure pairBReflection_1 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_pairBReflection_1 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure pairBReflection_1 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_pairBReflection_1 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_6 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_reserved_6 1 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_6 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_6 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_6 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_6 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure pairBReflection_2 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_pairBReflection_2 1 +/*! \brief Preprocessor variable to relate field to bit position in structure pairBReflection_2 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_pairBReflection_2 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure pairBReflection_2 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_pairBReflection_2 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_7 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_reserved_7 1 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_7 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_7 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_7 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_7 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure pairBReflection_3 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_pairBReflection_3 1 +/*! \brief Preprocessor variable to relate field to bit position in structure pairBReflection_3 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_pairBReflection_3 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure pairBReflection_3 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_pairBReflection_3 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_8 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_reserved_8 1 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_8 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_8 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_8 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_8 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure pairBReflection_4 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_pairBReflection_4 1 +/*! \brief Preprocessor variable to relate field to bit position in structure pairBReflection_4 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_pairBReflection_4 u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure pairBReflection_4 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_pairBReflection_4 u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_9 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_reserved_9 2 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_9 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_9 u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_9 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_9 u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure pairCReflection_1 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_pairCReflection_1 2 +/*! \brief Preprocessor variable to relate field to bit position in structure pairCReflection_1 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_pairCReflection_1 u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure pairCReflection_1 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_pairCReflection_1 u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_10 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_reserved_10 2 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_10 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_10 u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_10 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_10 u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure pairCReflection_2 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_pairCReflection_2 2 +/*! \brief Preprocessor variable to relate field to bit position in structure pairCReflection_2 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_pairCReflection_2 u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure pairCReflection_2 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_pairCReflection_2 u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_11 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_reserved_11 2 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_11 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_11 u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_11 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_11 u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure pairCReflection_3 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_pairCReflection_3 2 +/*! \brief Preprocessor variable to relate field to bit position in structure pairCReflection_3 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_pairCReflection_3 u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure pairCReflection_3 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_pairCReflection_3 u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_12 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_reserved_12 2 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_12 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_12 u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_12 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_12 u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure pairCReflection_4 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_pairCReflection_4 2 +/*! \brief Preprocessor variable to relate field to bit position in structure pairCReflection_4 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_pairCReflection_4 u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure pairCReflection_4 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_pairCReflection_4 u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_13 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_reserved_13 3 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_13 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_13 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_13 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_13 u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure pairDReflection_1 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_pairDReflection_1 3 +/*! \brief Preprocessor variable to relate field to bit position in structure pairDReflection_1 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_pairDReflection_1 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure pairDReflection_1 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_pairDReflection_1 u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_14 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_reserved_14 3 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_14 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_14 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_14 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_14 u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure pairDReflection_2 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_pairDReflection_2 3 +/*! \brief Preprocessor variable to relate field to bit position in structure pairDReflection_2 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_pairDReflection_2 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure pairDReflection_2 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_pairDReflection_2 u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_15 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_reserved_15 3 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_15 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_15 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_15 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_15 u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure pairDReflection_3 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_pairDReflection_3 3 +/*! \brief Preprocessor variable to relate field to bit position in structure pairDReflection_3 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_pairDReflection_3 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure pairDReflection_3 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_pairDReflection_3 u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure reserved_16 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_reserved_16 3 +/*! \brief Preprocessor variable to relate field to bit position in structure reserved_16 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_16 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure reserved_16 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_reserved_16 u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure pairDReflection_4 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define AQ_GlobalCableDiagnosticImpedance_HHD_pairDReflection_4 3 +/*! \brief Preprocessor variable to relate field to bit position in structure pairDReflection_4 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define bits_AQ_GlobalCableDiagnosticImpedance_HHD_pairDReflection_4 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure pairDReflection_4 in AQ_GlobalCableDiagnosticImpedance_HHD */ +#define word_AQ_GlobalCableDiagnosticImpedance_HHD_pairDReflection_4 u3.word_3 + +/*! \brief Base register address of structure AQ_GlobalStatus_HHD */ +#define AQ_GlobalStatus_HHD_baseRegisterAddress 0xC884 +/*! \brief MMD address of structure AQ_GlobalStatus_HHD */ +#define AQ_GlobalStatus_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure reservedStatus_0 in AQ_GlobalStatus_HHD */ +#define AQ_GlobalStatus_HHD_reservedStatus_0 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedStatus_0 in AQ_GlobalStatus_HHD */ +#define bits_AQ_GlobalStatus_HHD_reservedStatus_0 u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reservedStatus_0 in AQ_GlobalStatus_HHD */ +#define word_AQ_GlobalStatus_HHD_reservedStatus_0 u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure cableLength in AQ_GlobalStatus_HHD */ +#define AQ_GlobalStatus_HHD_cableLength 0 +/*! \brief Preprocessor variable to relate field to bit position in structure cableLength in AQ_GlobalStatus_HHD */ +#define bits_AQ_GlobalStatus_HHD_cableLength u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure cableLength in AQ_GlobalStatus_HHD */ +#define word_AQ_GlobalStatus_HHD_cableLength u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalReservedStatus_HHD */ +#define AQ_GlobalReservedStatus_HHD_baseRegisterAddress 0xC885 +/*! \brief MMD address of structure AQ_GlobalReservedStatus_HHD */ +#define AQ_GlobalReservedStatus_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure nearlySecondsMSW in AQ_GlobalReservedStatus_HHD */ +#define AQ_GlobalReservedStatus_HHD_nearlySecondsMSW 0 +/*! \brief Preprocessor variable to relate field to bit position in structure nearlySecondsMSW in AQ_GlobalReservedStatus_HHD */ +#define bits_AQ_GlobalReservedStatus_HHD_nearlySecondsMSW u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure nearlySecondsMSW in AQ_GlobalReservedStatus_HHD */ +#define word_AQ_GlobalReservedStatus_HHD_nearlySecondsMSW u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure xenpakNvrStatus in AQ_GlobalReservedStatus_HHD */ +#define AQ_GlobalReservedStatus_HHD_xenpakNvrStatus 0 +/*! \brief Preprocessor variable to relate field to bit position in structure xenpakNvrStatus in AQ_GlobalReservedStatus_HHD */ +#define bits_AQ_GlobalReservedStatus_HHD_xenpakNvrStatus u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure xenpakNvrStatus in AQ_GlobalReservedStatus_HHD */ +#define word_AQ_GlobalReservedStatus_HHD_xenpakNvrStatus u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure firmwareBuildID in AQ_GlobalReservedStatus_HHD */ +#define AQ_GlobalReservedStatus_HHD_firmwareBuildID 0 +/*! \brief Preprocessor variable to relate field to bit position in structure firmwareBuildID in AQ_GlobalReservedStatus_HHD */ +#define bits_AQ_GlobalReservedStatus_HHD_firmwareBuildID u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure firmwareBuildID in AQ_GlobalReservedStatus_HHD */ +#define word_AQ_GlobalReservedStatus_HHD_firmwareBuildID u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure provisioningID in AQ_GlobalReservedStatus_HHD */ +#define AQ_GlobalReservedStatus_HHD_provisioningID 0 +/*! \brief Preprocessor variable to relate field to bit position in structure provisioningID in AQ_GlobalReservedStatus_HHD */ +#define bits_AQ_GlobalReservedStatus_HHD_provisioningID u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure provisioningID in AQ_GlobalReservedStatus_HHD */ +#define word_AQ_GlobalReservedStatus_HHD_provisioningID u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure nearlySecondsLSW in AQ_GlobalReservedStatus_HHD */ +#define AQ_GlobalReservedStatus_HHD_nearlySecondsLSW 1 +/*! \brief Preprocessor variable to relate field to bit position in structure nearlySecondsLSW in AQ_GlobalReservedStatus_HHD */ +#define bits_AQ_GlobalReservedStatus_HHD_nearlySecondsLSW u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure nearlySecondsLSW in AQ_GlobalReservedStatus_HHD */ +#define word_AQ_GlobalReservedStatus_HHD_nearlySecondsLSW u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure dteStatus in AQ_GlobalReservedStatus_HHD */ +#define AQ_GlobalReservedStatus_HHD_dteStatus 2 +/*! \brief Preprocessor variable to relate field to bit position in structure dteStatus in AQ_GlobalReservedStatus_HHD */ +#define bits_AQ_GlobalReservedStatus_HHD_dteStatus u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure dteStatus in AQ_GlobalReservedStatus_HHD */ +#define word_AQ_GlobalReservedStatus_HHD_dteStatus u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure powerUpStallStatus in AQ_GlobalReservedStatus_HHD */ +#define AQ_GlobalReservedStatus_HHD_powerUpStallStatus 2 +/*! \brief Preprocessor variable to relate field to bit position in structure powerUpStallStatus in AQ_GlobalReservedStatus_HHD */ +#define bits_AQ_GlobalReservedStatus_HHD_powerUpStallStatus u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure powerUpStallStatus in AQ_GlobalReservedStatus_HHD */ +#define word_AQ_GlobalReservedStatus_HHD_powerUpStallStatus u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure reservedStatus_3 in AQ_GlobalReservedStatus_HHD */ +#define AQ_GlobalReservedStatus_HHD_reservedStatus_3 2 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedStatus_3 in AQ_GlobalReservedStatus_HHD */ +#define bits_AQ_GlobalReservedStatus_HHD_reservedStatus_3 u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure reservedStatus_3 in AQ_GlobalReservedStatus_HHD */ +#define word_AQ_GlobalReservedStatus_HHD_reservedStatus_3 u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure loopbackStatus in AQ_GlobalReservedStatus_HHD */ +#define AQ_GlobalReservedStatus_HHD_loopbackStatus 3 +/*! \brief Preprocessor variable to relate field to bit position in structure loopbackStatus in AQ_GlobalReservedStatus_HHD */ +#define bits_AQ_GlobalReservedStatus_HHD_loopbackStatus u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure loopbackStatus in AQ_GlobalReservedStatus_HHD */ +#define word_AQ_GlobalReservedStatus_HHD_loopbackStatus u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure reservedStatus_4 in AQ_GlobalReservedStatus_HHD */ +#define AQ_GlobalReservedStatus_HHD_reservedStatus_4 3 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedStatus_4 in AQ_GlobalReservedStatus_HHD */ +#define bits_AQ_GlobalReservedStatus_HHD_reservedStatus_4 u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure reservedStatus_4 in AQ_GlobalReservedStatus_HHD */ +#define word_AQ_GlobalReservedStatus_HHD_reservedStatus_4 u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure mdiPacketGenerationStatus in AQ_GlobalReservedStatus_HHD */ +#define AQ_GlobalReservedStatus_HHD_mdiPacketGenerationStatus 3 +/*! \brief Preprocessor variable to relate field to bit position in structure mdiPacketGenerationStatus in AQ_GlobalReservedStatus_HHD */ +#define bits_AQ_GlobalReservedStatus_HHD_mdiPacketGenerationStatus u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure mdiPacketGenerationStatus in AQ_GlobalReservedStatus_HHD */ +#define word_AQ_GlobalReservedStatus_HHD_mdiPacketGenerationStatus u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure look_asidePortPacketGenerationStatus in AQ_GlobalReservedStatus_HHD */ +#define AQ_GlobalReservedStatus_HHD_look_asidePortPacketGenerationStatus 3 +/*! \brief Preprocessor variable to relate field to bit position in structure look_asidePortPacketGenerationStatus in AQ_GlobalReservedStatus_HHD */ +#define bits_AQ_GlobalReservedStatus_HHD_look_asidePortPacketGenerationStatus u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure look_asidePortPacketGenerationStatus in AQ_GlobalReservedStatus_HHD */ +#define word_AQ_GlobalReservedStatus_HHD_look_asidePortPacketGenerationStatus u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure systemI_fPacketGenerationStatus in AQ_GlobalReservedStatus_HHD */ +#define AQ_GlobalReservedStatus_HHD_systemI_fPacketGenerationStatus 3 +/*! \brief Preprocessor variable to relate field to bit position in structure systemI_fPacketGenerationStatus in AQ_GlobalReservedStatus_HHD */ +#define bits_AQ_GlobalReservedStatus_HHD_systemI_fPacketGenerationStatus u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure systemI_fPacketGenerationStatus in AQ_GlobalReservedStatus_HHD */ +#define word_AQ_GlobalReservedStatus_HHD_systemI_fPacketGenerationStatus u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure reservedStatus_4a in AQ_GlobalReservedStatus_HHD */ +#define AQ_GlobalReservedStatus_HHD_reservedStatus_4a 3 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedStatus_4a in AQ_GlobalReservedStatus_HHD */ +#define bits_AQ_GlobalReservedStatus_HHD_reservedStatus_4a u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure reservedStatus_4a in AQ_GlobalReservedStatus_HHD */ +#define word_AQ_GlobalReservedStatus_HHD_reservedStatus_4a u3.word_3 +/*! \brief Preprocessor variable to relate field to word number in structure rate in AQ_GlobalReservedStatus_HHD */ +#define AQ_GlobalReservedStatus_HHD_rate 3 +/*! \brief Preprocessor variable to relate field to bit position in structure rate in AQ_GlobalReservedStatus_HHD */ +#define bits_AQ_GlobalReservedStatus_HHD_rate u3.bits_3 +/*! \brief Preprocessor variable to relate field to word position in structure rate in AQ_GlobalReservedStatus_HHD */ +#define word_AQ_GlobalReservedStatus_HHD_rate u3.word_3 + +/*! \brief Base register address of structure AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_baseRegisterAddress 0xCC00 +/*! \brief MMD address of structure AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure highTemperatureFailure in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_highTemperatureFailure 0 +/*! \brief Preprocessor variable to relate field to bit position in structure highTemperatureFailure in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_highTemperatureFailure u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure highTemperatureFailure in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_highTemperatureFailure u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure lowTemperatureFailure in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_lowTemperatureFailure 0 +/*! \brief Preprocessor variable to relate field to bit position in structure lowTemperatureFailure in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_lowTemperatureFailure u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure lowTemperatureFailure in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_lowTemperatureFailure u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure highTemperatureWarning in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_highTemperatureWarning 0 +/*! \brief Preprocessor variable to relate field to bit position in structure highTemperatureWarning in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_highTemperatureWarning u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure highTemperatureWarning in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_highTemperatureWarning u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure lowTemperatureWarning in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_lowTemperatureWarning 0 +/*! \brief Preprocessor variable to relate field to bit position in structure lowTemperatureWarning in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_lowTemperatureWarning u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure lowTemperatureWarning in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_lowTemperatureWarning u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure resetCompleted in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_resetCompleted 0 +/*! \brief Preprocessor variable to relate field to bit position in structure resetCompleted in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_resetCompleted u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure resetCompleted in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_resetCompleted u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure deviceFault in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_deviceFault 0 +/*! \brief Preprocessor variable to relate field to bit position in structure deviceFault in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_deviceFault u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure deviceFault in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_deviceFault u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reservedAlarmA in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_reservedAlarmA 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedAlarmA in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_reservedAlarmA u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reservedAlarmA in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_reservedAlarmA u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reservedAlarmB in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_reservedAlarmB 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedAlarmB in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_reservedAlarmB u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reservedAlarmB in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_reservedAlarmB u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reservedAlarmC in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_reservedAlarmC 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedAlarmC in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_reservedAlarmC u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reservedAlarmC in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_reservedAlarmC u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reservedAlarmD in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_reservedAlarmD 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedAlarmD in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_reservedAlarmD u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reservedAlarmD in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_reservedAlarmD u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure smartPower_downEntered in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_smartPower_downEntered 1 +/*! \brief Preprocessor variable to relate field to bit position in structure smartPower_downEntered in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_smartPower_downEntered u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure smartPower_downEntered in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_smartPower_downEntered u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure xenpakAlarm in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_xenpakAlarm 1 +/*! \brief Preprocessor variable to relate field to bit position in structure xenpakAlarm in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_xenpakAlarm u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure xenpakAlarm in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_xenpakAlarm u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure ipPhoneDetect in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_ipPhoneDetect 1 +/*! \brief Preprocessor variable to relate field to bit position in structure ipPhoneDetect in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_ipPhoneDetect u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure ipPhoneDetect in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_ipPhoneDetect u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure dteStatusChange in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_dteStatusChange 1 +/*! \brief Preprocessor variable to relate field to bit position in structure dteStatusChange in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_dteStatusChange u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure dteStatusChange in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_dteStatusChange u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure reservedAlarms in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_reservedAlarms 1 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedAlarms in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_reservedAlarms u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure reservedAlarms in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_reservedAlarms u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mdioCommandHandlingOverflow in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_mdioCommandHandlingOverflow 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioCommandHandlingOverflow in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_mdioCommandHandlingOverflow u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mdioCommandHandlingOverflow in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_mdioCommandHandlingOverflow u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure nvrOperationComplete in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_nvrOperationComplete 2 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrOperationComplete in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_nvrOperationComplete u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure nvrOperationComplete in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_nvrOperationComplete u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure mailboxOperation_Complete in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_mailboxOperation_Complete 2 +/*! \brief Preprocessor variable to relate field to bit position in structure mailboxOperation_Complete in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_mailboxOperation_Complete u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure mailboxOperation_Complete in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_mailboxOperation_Complete u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure upDramParityError in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_upDramParityError 2 +/*! \brief Preprocessor variable to relate field to bit position in structure upDramParityError in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_upDramParityError u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure upDramParityError in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_upDramParityError u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure upIramParityError in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_upIramParityError 2 +/*! \brief Preprocessor variable to relate field to bit position in structure upIramParityError in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_upIramParityError u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure upIramParityError in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_upIramParityError u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure txEnableStateChange in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_txEnableStateChange 2 +/*! \brief Preprocessor variable to relate field to bit position in structure txEnableStateChange in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_txEnableStateChange u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure txEnableStateChange in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_txEnableStateChange u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure mdioMMD_Error in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_mdioMMD_Error 2 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioMMD_Error in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_mdioMMD_Error u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure mdioMMD_Error in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_mdioMMD_Error u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure mdioTimeoutError in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_mdioTimeoutError 2 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioTimeoutError in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_mdioTimeoutError u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure mdioTimeoutError in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_mdioTimeoutError u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure watchdogTimerAlarm in AQ_GlobalAlarms_HHD */ +#define AQ_GlobalAlarms_HHD_watchdogTimerAlarm 2 +/*! \brief Preprocessor variable to relate field to bit position in structure watchdogTimerAlarm in AQ_GlobalAlarms_HHD */ +#define bits_AQ_GlobalAlarms_HHD_watchdogTimerAlarm u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure watchdogTimerAlarm in AQ_GlobalAlarms_HHD */ +#define word_AQ_GlobalAlarms_HHD_watchdogTimerAlarm u2.word_2 + +/*! \brief Base register address of structure AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_baseRegisterAddress 0xD400 +/*! \brief MMD address of structure AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure highTemperatureFailureMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_highTemperatureFailureMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure highTemperatureFailureMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_highTemperatureFailureMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure highTemperatureFailureMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_highTemperatureFailureMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure lowTemperatureFailureMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_lowTemperatureFailureMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure lowTemperatureFailureMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_lowTemperatureFailureMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure lowTemperatureFailureMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_lowTemperatureFailureMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure highTemperatureWarningMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_highTemperatureWarningMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure highTemperatureWarningMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_highTemperatureWarningMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure highTemperatureWarningMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_highTemperatureWarningMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure lowTemperatureWarningMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_lowTemperatureWarningMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure lowTemperatureWarningMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_lowTemperatureWarningMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure lowTemperatureWarningMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_lowTemperatureWarningMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure resetCompletedMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_resetCompletedMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure resetCompletedMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_resetCompletedMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure resetCompletedMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_resetCompletedMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure deviceFaultMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_deviceFaultMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure deviceFaultMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_deviceFaultMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure deviceFaultMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_deviceFaultMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reservedAlarmAMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_reservedAlarmAMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedAlarmAMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_reservedAlarmAMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reservedAlarmAMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_reservedAlarmAMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reservedAlarmBMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_reservedAlarmBMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedAlarmBMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_reservedAlarmBMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reservedAlarmBMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_reservedAlarmBMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reservedAlarmCMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_reservedAlarmCMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedAlarmCMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_reservedAlarmCMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reservedAlarmCMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_reservedAlarmCMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure reservedAlarmDMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_reservedAlarmDMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedAlarmDMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_reservedAlarmDMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure reservedAlarmDMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_reservedAlarmDMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure smartPower_downEnteredMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_smartPower_downEnteredMask 1 +/*! \brief Preprocessor variable to relate field to bit position in structure smartPower_downEnteredMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_smartPower_downEnteredMask u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure smartPower_downEnteredMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_smartPower_downEnteredMask u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure xenpakAlarmMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_xenpakAlarmMask 1 +/*! \brief Preprocessor variable to relate field to bit position in structure xenpakAlarmMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_xenpakAlarmMask u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure xenpakAlarmMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_xenpakAlarmMask u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure ipPhoneDetectMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_ipPhoneDetectMask 1 +/*! \brief Preprocessor variable to relate field to bit position in structure ipPhoneDetectMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_ipPhoneDetectMask u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure ipPhoneDetectMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_ipPhoneDetectMask u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure dteStatusChangeMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_dteStatusChangeMask 1 +/*! \brief Preprocessor variable to relate field to bit position in structure dteStatusChangeMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_dteStatusChangeMask u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure dteStatusChangeMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_dteStatusChangeMask u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure reservedAlarmsMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_reservedAlarmsMask 1 +/*! \brief Preprocessor variable to relate field to bit position in structure reservedAlarmsMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_reservedAlarmsMask u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure reservedAlarmsMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_reservedAlarmsMask u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure mdioCommandHandlingOverflowMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_mdioCommandHandlingOverflowMask 1 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioCommandHandlingOverflowMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_mdioCommandHandlingOverflowMask u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure mdioCommandHandlingOverflowMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_mdioCommandHandlingOverflowMask u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure diagnosticAlarmMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_diagnosticAlarmMask 1 +/*! \brief Preprocessor variable to relate field to bit position in structure diagnosticAlarmMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_diagnosticAlarmMask u1.bits_1 +/*! \brief Preprocessor variable to relate field to word position in structure diagnosticAlarmMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_diagnosticAlarmMask u1.word_1 +/*! \brief Preprocessor variable to relate field to word number in structure nvrOperationCompleteMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_nvrOperationCompleteMask 2 +/*! \brief Preprocessor variable to relate field to bit position in structure nvrOperationCompleteMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_nvrOperationCompleteMask u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure nvrOperationCompleteMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_nvrOperationCompleteMask u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure mailboxOperationCompleteMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_mailboxOperationCompleteMask 2 +/*! \brief Preprocessor variable to relate field to bit position in structure mailboxOperationCompleteMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_mailboxOperationCompleteMask u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure mailboxOperationCompleteMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_mailboxOperationCompleteMask u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure upDramParityErrorMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_upDramParityErrorMask 2 +/*! \brief Preprocessor variable to relate field to bit position in structure upDramParityErrorMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_upDramParityErrorMask u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure upDramParityErrorMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_upDramParityErrorMask u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure upIramParityErrorMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_upIramParityErrorMask 2 +/*! \brief Preprocessor variable to relate field to bit position in structure upIramParityErrorMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_upIramParityErrorMask u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure upIramParityErrorMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_upIramParityErrorMask u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure txEnableStateChangeMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_txEnableStateChangeMask 2 +/*! \brief Preprocessor variable to relate field to bit position in structure txEnableStateChangeMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_txEnableStateChangeMask u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure txEnableStateChangeMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_txEnableStateChangeMask u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure mdioMMD_ErrorMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_mdioMMD_ErrorMask 2 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioMMD_ErrorMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_mdioMMD_ErrorMask u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure mdioMMD_ErrorMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_mdioMMD_ErrorMask u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure mdioTimeoutErrorMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_mdioTimeoutErrorMask 2 +/*! \brief Preprocessor variable to relate field to bit position in structure mdioTimeoutErrorMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_mdioTimeoutErrorMask u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure mdioTimeoutErrorMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_mdioTimeoutErrorMask u2.word_2 +/*! \brief Preprocessor variable to relate field to word number in structure watchdogTimerAlarmMask in AQ_GlobalInterruptMask_HHD */ +#define AQ_GlobalInterruptMask_HHD_watchdogTimerAlarmMask 2 +/*! \brief Preprocessor variable to relate field to bit position in structure watchdogTimerAlarmMask in AQ_GlobalInterruptMask_HHD */ +#define bits_AQ_GlobalInterruptMask_HHD_watchdogTimerAlarmMask u2.bits_2 +/*! \brief Preprocessor variable to relate field to word position in structure watchdogTimerAlarmMask in AQ_GlobalInterruptMask_HHD */ +#define word_AQ_GlobalInterruptMask_HHD_watchdogTimerAlarmMask u2.word_2 + +/*! \brief Base register address of structure AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define AQ_GlobalChip_wideStandardInterruptFlags_HHD_baseRegisterAddress 0xFC00 +/*! \brief MMD address of structure AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define AQ_GlobalChip_wideStandardInterruptFlags_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure pmaStandardAlarm_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define AQ_GlobalChip_wideStandardInterruptFlags_HHD_pmaStandardAlarm_1Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pmaStandardAlarm_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define bits_AQ_GlobalChip_wideStandardInterruptFlags_HHD_pmaStandardAlarm_1Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pmaStandardAlarm_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define word_AQ_GlobalChip_wideStandardInterruptFlags_HHD_pmaStandardAlarm_1Interrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pmaStandardAlarm_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define AQ_GlobalChip_wideStandardInterruptFlags_HHD_pmaStandardAlarm_2Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pmaStandardAlarm_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define bits_AQ_GlobalChip_wideStandardInterruptFlags_HHD_pmaStandardAlarm_2Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pmaStandardAlarm_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define word_AQ_GlobalChip_wideStandardInterruptFlags_HHD_pmaStandardAlarm_2Interrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pcsStandardAlarm_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define AQ_GlobalChip_wideStandardInterruptFlags_HHD_pcsStandardAlarm_1Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pcsStandardAlarm_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define bits_AQ_GlobalChip_wideStandardInterruptFlags_HHD_pcsStandardAlarm_1Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pcsStandardAlarm_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define word_AQ_GlobalChip_wideStandardInterruptFlags_HHD_pcsStandardAlarm_1Interrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pcsStandardAlarm_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define AQ_GlobalChip_wideStandardInterruptFlags_HHD_pcsStandardAlarm_2Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pcsStandardAlarm_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define bits_AQ_GlobalChip_wideStandardInterruptFlags_HHD_pcsStandardAlarm_2Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pcsStandardAlarm_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define word_AQ_GlobalChip_wideStandardInterruptFlags_HHD_pcsStandardAlarm_2Interrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pcsStandardAlarm_3Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define AQ_GlobalChip_wideStandardInterruptFlags_HHD_pcsStandardAlarm_3Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pcsStandardAlarm_3Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define bits_AQ_GlobalChip_wideStandardInterruptFlags_HHD_pcsStandardAlarm_3Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pcsStandardAlarm_3Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define word_AQ_GlobalChip_wideStandardInterruptFlags_HHD_pcsStandardAlarm_3Interrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure phyXS_StandardAlarms_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define AQ_GlobalChip_wideStandardInterruptFlags_HHD_phyXS_StandardAlarms_1Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure phyXS_StandardAlarms_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define bits_AQ_GlobalChip_wideStandardInterruptFlags_HHD_phyXS_StandardAlarms_1Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure phyXS_StandardAlarms_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define word_AQ_GlobalChip_wideStandardInterruptFlags_HHD_phyXS_StandardAlarms_1Interrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure phyXS_StandardAlarms_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define AQ_GlobalChip_wideStandardInterruptFlags_HHD_phyXS_StandardAlarms_2Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure phyXS_StandardAlarms_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define bits_AQ_GlobalChip_wideStandardInterruptFlags_HHD_phyXS_StandardAlarms_2Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure phyXS_StandardAlarms_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define word_AQ_GlobalChip_wideStandardInterruptFlags_HHD_phyXS_StandardAlarms_2Interrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure autonegotiationStandardAlarms_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define AQ_GlobalChip_wideStandardInterruptFlags_HHD_autonegotiationStandardAlarms_1Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure autonegotiationStandardAlarms_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define bits_AQ_GlobalChip_wideStandardInterruptFlags_HHD_autonegotiationStandardAlarms_1Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure autonegotiationStandardAlarms_1Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define word_AQ_GlobalChip_wideStandardInterruptFlags_HHD_autonegotiationStandardAlarms_1Interrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure autonegotiationStandardAlarms_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define AQ_GlobalChip_wideStandardInterruptFlags_HHD_autonegotiationStandardAlarms_2Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure autonegotiationStandardAlarms_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define bits_AQ_GlobalChip_wideStandardInterruptFlags_HHD_autonegotiationStandardAlarms_2Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure autonegotiationStandardAlarms_2Interrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define word_AQ_GlobalChip_wideStandardInterruptFlags_HHD_autonegotiationStandardAlarms_2Interrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure gbeStandardAlarmsInterrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define AQ_GlobalChip_wideStandardInterruptFlags_HHD_gbeStandardAlarmsInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure gbeStandardAlarmsInterrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define bits_AQ_GlobalChip_wideStandardInterruptFlags_HHD_gbeStandardAlarmsInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure gbeStandardAlarmsInterrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define word_AQ_GlobalChip_wideStandardInterruptFlags_HHD_gbeStandardAlarmsInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure allVendorAlarmsInterrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define AQ_GlobalChip_wideStandardInterruptFlags_HHD_allVendorAlarmsInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure allVendorAlarmsInterrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define bits_AQ_GlobalChip_wideStandardInterruptFlags_HHD_allVendorAlarmsInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure allVendorAlarmsInterrupt in AQ_GlobalChip_wideStandardInterruptFlags_HHD */ +#define word_AQ_GlobalChip_wideStandardInterruptFlags_HHD_allVendorAlarmsInterrupt u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define AQ_GlobalChip_wideVendorInterruptFlags_HHD_baseRegisterAddress 0xFC01 +/*! \brief MMD address of structure AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define AQ_GlobalChip_wideVendorInterruptFlags_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure pmaVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define AQ_GlobalChip_wideVendorInterruptFlags_HHD_pmaVendorAlarmInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pmaVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define bits_AQ_GlobalChip_wideVendorInterruptFlags_HHD_pmaVendorAlarmInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pmaVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define word_AQ_GlobalChip_wideVendorInterruptFlags_HHD_pmaVendorAlarmInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pcsVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define AQ_GlobalChip_wideVendorInterruptFlags_HHD_pcsVendorAlarmInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pcsVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define bits_AQ_GlobalChip_wideVendorInterruptFlags_HHD_pcsVendorAlarmInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pcsVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define word_AQ_GlobalChip_wideVendorInterruptFlags_HHD_pcsVendorAlarmInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure phyXS_VendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define AQ_GlobalChip_wideVendorInterruptFlags_HHD_phyXS_VendorAlarmInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure phyXS_VendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define bits_AQ_GlobalChip_wideVendorInterruptFlags_HHD_phyXS_VendorAlarmInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure phyXS_VendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define word_AQ_GlobalChip_wideVendorInterruptFlags_HHD_phyXS_VendorAlarmInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure autonegotiationVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define AQ_GlobalChip_wideVendorInterruptFlags_HHD_autonegotiationVendorAlarmInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure autonegotiationVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define bits_AQ_GlobalChip_wideVendorInterruptFlags_HHD_autonegotiationVendorAlarmInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure autonegotiationVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define word_AQ_GlobalChip_wideVendorInterruptFlags_HHD_autonegotiationVendorAlarmInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure gbeVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define AQ_GlobalChip_wideVendorInterruptFlags_HHD_gbeVendorAlarmInterrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure gbeVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define bits_AQ_GlobalChip_wideVendorInterruptFlags_HHD_gbeVendorAlarmInterrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure gbeVendorAlarmInterrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define word_AQ_GlobalChip_wideVendorInterruptFlags_HHD_gbeVendorAlarmInterrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure globalAlarms_1Interrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define AQ_GlobalChip_wideVendorInterruptFlags_HHD_globalAlarms_1Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure globalAlarms_1Interrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define bits_AQ_GlobalChip_wideVendorInterruptFlags_HHD_globalAlarms_1Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure globalAlarms_1Interrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define word_AQ_GlobalChip_wideVendorInterruptFlags_HHD_globalAlarms_1Interrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure globalAlarms_2Interrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define AQ_GlobalChip_wideVendorInterruptFlags_HHD_globalAlarms_2Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure globalAlarms_2Interrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define bits_AQ_GlobalChip_wideVendorInterruptFlags_HHD_globalAlarms_2Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure globalAlarms_2Interrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define word_AQ_GlobalChip_wideVendorInterruptFlags_HHD_globalAlarms_2Interrupt u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure globalAlarms_3Interrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define AQ_GlobalChip_wideVendorInterruptFlags_HHD_globalAlarms_3Interrupt 0 +/*! \brief Preprocessor variable to relate field to bit position in structure globalAlarms_3Interrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define bits_AQ_GlobalChip_wideVendorInterruptFlags_HHD_globalAlarms_3Interrupt u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure globalAlarms_3Interrupt in AQ_GlobalChip_wideVendorInterruptFlags_HHD */ +#define word_AQ_GlobalChip_wideVendorInterruptFlags_HHD_globalAlarms_3Interrupt u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define AQ_GlobalInterruptChip_wideStandardMask_HHD_baseRegisterAddress 0xFF00 +/*! \brief MMD address of structure AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define AQ_GlobalInterruptChip_wideStandardMask_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure pmaStandardAlarm_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define AQ_GlobalInterruptChip_wideStandardMask_HHD_pmaStandardAlarm_1InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pmaStandardAlarm_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define bits_AQ_GlobalInterruptChip_wideStandardMask_HHD_pmaStandardAlarm_1InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pmaStandardAlarm_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define word_AQ_GlobalInterruptChip_wideStandardMask_HHD_pmaStandardAlarm_1InterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pmaStandardAlarm_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define AQ_GlobalInterruptChip_wideStandardMask_HHD_pmaStandardAlarm_2InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pmaStandardAlarm_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define bits_AQ_GlobalInterruptChip_wideStandardMask_HHD_pmaStandardAlarm_2InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pmaStandardAlarm_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define word_AQ_GlobalInterruptChip_wideStandardMask_HHD_pmaStandardAlarm_2InterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pcsStandardAlarm_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define AQ_GlobalInterruptChip_wideStandardMask_HHD_pcsStandardAlarm_1InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pcsStandardAlarm_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define bits_AQ_GlobalInterruptChip_wideStandardMask_HHD_pcsStandardAlarm_1InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pcsStandardAlarm_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define word_AQ_GlobalInterruptChip_wideStandardMask_HHD_pcsStandardAlarm_1InterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pcsStandardAlarm_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define AQ_GlobalInterruptChip_wideStandardMask_HHD_pcsStandardAlarm_2InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pcsStandardAlarm_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define bits_AQ_GlobalInterruptChip_wideStandardMask_HHD_pcsStandardAlarm_2InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pcsStandardAlarm_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define word_AQ_GlobalInterruptChip_wideStandardMask_HHD_pcsStandardAlarm_2InterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pcsStandardAlarm_3InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define AQ_GlobalInterruptChip_wideStandardMask_HHD_pcsStandardAlarm_3InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pcsStandardAlarm_3InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define bits_AQ_GlobalInterruptChip_wideStandardMask_HHD_pcsStandardAlarm_3InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pcsStandardAlarm_3InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define word_AQ_GlobalInterruptChip_wideStandardMask_HHD_pcsStandardAlarm_3InterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure phyXS_StandardAlarms_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define AQ_GlobalInterruptChip_wideStandardMask_HHD_phyXS_StandardAlarms_1InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure phyXS_StandardAlarms_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define bits_AQ_GlobalInterruptChip_wideStandardMask_HHD_phyXS_StandardAlarms_1InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure phyXS_StandardAlarms_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define word_AQ_GlobalInterruptChip_wideStandardMask_HHD_phyXS_StandardAlarms_1InterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure phyXS_StandardAlarms_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define AQ_GlobalInterruptChip_wideStandardMask_HHD_phyXS_StandardAlarms_2InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure phyXS_StandardAlarms_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define bits_AQ_GlobalInterruptChip_wideStandardMask_HHD_phyXS_StandardAlarms_2InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure phyXS_StandardAlarms_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define word_AQ_GlobalInterruptChip_wideStandardMask_HHD_phyXS_StandardAlarms_2InterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure autonegotiationStandardAlarms_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define AQ_GlobalInterruptChip_wideStandardMask_HHD_autonegotiationStandardAlarms_1InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure autonegotiationStandardAlarms_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define bits_AQ_GlobalInterruptChip_wideStandardMask_HHD_autonegotiationStandardAlarms_1InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure autonegotiationStandardAlarms_1InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define word_AQ_GlobalInterruptChip_wideStandardMask_HHD_autonegotiationStandardAlarms_1InterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure autonegotiationStandardAlarms_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define AQ_GlobalInterruptChip_wideStandardMask_HHD_autonegotiationStandardAlarms_2InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure autonegotiationStandardAlarms_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define bits_AQ_GlobalInterruptChip_wideStandardMask_HHD_autonegotiationStandardAlarms_2InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure autonegotiationStandardAlarms_2InterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define word_AQ_GlobalInterruptChip_wideStandardMask_HHD_autonegotiationStandardAlarms_2InterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure gbeStandardAlarmsInterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define AQ_GlobalInterruptChip_wideStandardMask_HHD_gbeStandardAlarmsInterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure gbeStandardAlarmsInterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define bits_AQ_GlobalInterruptChip_wideStandardMask_HHD_gbeStandardAlarmsInterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure gbeStandardAlarmsInterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define word_AQ_GlobalInterruptChip_wideStandardMask_HHD_gbeStandardAlarmsInterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure allVendorAlarmsInterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define AQ_GlobalInterruptChip_wideStandardMask_HHD_allVendorAlarmsInterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure allVendorAlarmsInterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define bits_AQ_GlobalInterruptChip_wideStandardMask_HHD_allVendorAlarmsInterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure allVendorAlarmsInterruptMask in AQ_GlobalInterruptChip_wideStandardMask_HHD */ +#define word_AQ_GlobalInterruptChip_wideStandardMask_HHD_allVendorAlarmsInterruptMask u0.word_0 + +/*! \brief Base register address of structure AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define AQ_GlobalInterruptChip_wideVendorMask_HHD_baseRegisterAddress 0xFF01 +/*! \brief MMD address of structure AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define AQ_GlobalInterruptChip_wideVendorMask_HHD_mmdAddress 0x1E +/*! \brief Preprocessor variable to relate field to word number in structure pmaVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define AQ_GlobalInterruptChip_wideVendorMask_HHD_pmaVendorAlarmInterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pmaVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define bits_AQ_GlobalInterruptChip_wideVendorMask_HHD_pmaVendorAlarmInterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pmaVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define word_AQ_GlobalInterruptChip_wideVendorMask_HHD_pmaVendorAlarmInterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure pcsVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define AQ_GlobalInterruptChip_wideVendorMask_HHD_pcsVendorAlarmInterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure pcsVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define bits_AQ_GlobalInterruptChip_wideVendorMask_HHD_pcsVendorAlarmInterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure pcsVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define word_AQ_GlobalInterruptChip_wideVendorMask_HHD_pcsVendorAlarmInterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure phyXS_VendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define AQ_GlobalInterruptChip_wideVendorMask_HHD_phyXS_VendorAlarmInterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure phyXS_VendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define bits_AQ_GlobalInterruptChip_wideVendorMask_HHD_phyXS_VendorAlarmInterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure phyXS_VendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define word_AQ_GlobalInterruptChip_wideVendorMask_HHD_phyXS_VendorAlarmInterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure autonegotiationVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define AQ_GlobalInterruptChip_wideVendorMask_HHD_autonegotiationVendorAlarmInterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure autonegotiationVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define bits_AQ_GlobalInterruptChip_wideVendorMask_HHD_autonegotiationVendorAlarmInterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure autonegotiationVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define word_AQ_GlobalInterruptChip_wideVendorMask_HHD_autonegotiationVendorAlarmInterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure gbeVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define AQ_GlobalInterruptChip_wideVendorMask_HHD_gbeVendorAlarmInterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure gbeVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define bits_AQ_GlobalInterruptChip_wideVendorMask_HHD_gbeVendorAlarmInterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure gbeVendorAlarmInterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define word_AQ_GlobalInterruptChip_wideVendorMask_HHD_gbeVendorAlarmInterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure globalAlarms_1InterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define AQ_GlobalInterruptChip_wideVendorMask_HHD_globalAlarms_1InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure globalAlarms_1InterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define bits_AQ_GlobalInterruptChip_wideVendorMask_HHD_globalAlarms_1InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure globalAlarms_1InterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define word_AQ_GlobalInterruptChip_wideVendorMask_HHD_globalAlarms_1InterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure globalAlarms_2InterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define AQ_GlobalInterruptChip_wideVendorMask_HHD_globalAlarms_2InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure globalAlarms_2InterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define bits_AQ_GlobalInterruptChip_wideVendorMask_HHD_globalAlarms_2InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure globalAlarms_2InterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define word_AQ_GlobalInterruptChip_wideVendorMask_HHD_globalAlarms_2InterruptMask u0.word_0 +/*! \brief Preprocessor variable to relate field to word number in structure globalAlarms_3InterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define AQ_GlobalInterruptChip_wideVendorMask_HHD_globalAlarms_3InterruptMask 0 +/*! \brief Preprocessor variable to relate field to bit position in structure globalAlarms_3InterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define bits_AQ_GlobalInterruptChip_wideVendorMask_HHD_globalAlarms_3InterruptMask u0.bits_0 +/*! \brief Preprocessor variable to relate field to word position in structure globalAlarms_3InterruptMask in AQ_GlobalInterruptChip_wideVendorMask_HHD */ +#define word_AQ_GlobalInterruptChip_wideVendorMask_HHD_globalAlarms_3InterruptMask u0.word_0 +#endif +/*@}*/ +/*@}*/ diff --git a/feeds/ipq807x/aq-fw-download/src/include/registerMap/HHD/AQ_HHD_Global_registers_reversed.h b/feeds/ipq807x/aq-fw-download/src/include/registerMap/HHD/AQ_HHD_Global_registers_reversed.h new file mode 100755 index 000000000..f6fe99831 --- /dev/null +++ b/feeds/ipq807x/aq-fw-download/src/include/registerMap/HHD/AQ_HHD_Global_registers_reversed.h @@ -0,0 +1,12123 @@ +/*! \file +* This file contains the data structures and doxygen comments +* for the Global Registers block. + */ + +/*! \addtogroup registerMap + @{ +*/ + +/*! \defgroup Global_registers Global Registers +* This module contains the data structures and doxygen comments +* for the Global Registers block. + */ +/*********************************************************************** +* Copyright (c) 2015, Aquantia +* +* Permission to use, copy, modify, and/or distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +* +* $Date: 2014/04/08 $ +* +* $Label: $ +* +* Description: +* +* This file contains the c header structures for the registers contained in the Global Registers block. +* +* The bit fields in this structure are from MSbit to LSbit +* +***********************************************************************/ + + +/*@{*/ +#ifndef AQ_HHD_GLOBAL_REGS_HEADER +#define AQ_HHD_GLOBAL_REGS_HEADER + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Control 1: 1E.0000 */ +/* Global Standard Control 1: 1E.0000 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Control 1 */ + union + { + struct + { + /*! \brief 1E.0000.F R/WSC Soft Reset + AQ_GlobalStandardControl_1_HHD.u0.bits_0.softReset + + Default = 0x1 + + 1 = Global soft reset + 0 = Normal operation + + + Notes: + Resets the entire PHY. + Setting this bit initiates a global soft reset on all of the digital logic not including the microprocessor (i.e. microprocessor is not reset). Upon completion of the reset sequence, this bit is set back to 0by the microprocessor. Note this bit is OR'ed with the individual MMD resets. This bit should be set to 0 before setting the individual MMD resets. */ + unsigned int softReset : 1; /* 1E.0000.F R/WSC Default = 0x1 */ + /* 1 = Global soft reset + 0 = Normal operation + */ + unsigned int reserved0 : 3; + /*! \brief 1E.0000.B R/WPD Low Power + AQ_GlobalStandardControl_1_HHD.u0.bits_0.lowPower + + Provisionable Default = 0x0 + + 1 = Low-power mode + 0 = Normal operation + + + Notes: + A one written to this register causes the chip to enter low-power mode. This bit puts the entire chip in low-power mode, with only the MDIO and microprocessor functioning, and turns off the analog front-end: i.e. places it in high-impedance mode. Setting this bit also sets all of the Low Power bits in the other MMDs. */ + unsigned int lowPower : 1; /* 1E.0000.B R/WPD Provisionable Default = 0x0 */ + /* 1 = Low-power mode + 0 = Normal operation + */ + unsigned int reserved1 : 11; + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalStandardControl_1_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Device Identifier: 1E.0002 */ +/* Global Standard Device Identifier: 1E.0002 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Device Identifier */ + union + { + struct + { + /*! \brief 1E.0002.F:0 RO Device ID MSW [1F:10] + AQ_GlobalStandardDeviceIdentifier_HHD.u0.bits_0.deviceIdMSW + + + + Bits 31 - 16 of Device ID + */ + unsigned int deviceIdMSW : 16; /* 1E.0002.F:0 RO */ + /* Bits 31 - 16 of Device ID */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Standard Device Identifier */ + union + { + struct + { + /*! \brief 1E.0003.F:0 RO Device ID LSW [F:0] + AQ_GlobalStandardDeviceIdentifier_HHD.u1.bits_1.deviceIdLSW + + + + Bits 15 - 0 of Device ID + */ + unsigned int deviceIdLSW : 16; /* 1E.0003.F:0 RO */ + /* Bits 15 - 0 of Device ID */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalStandardDeviceIdentifier_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Devices in Package: 1E.0005 */ +/* Global Standard Devices in Package: 1E.0005 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Devices in Package */ + union + { + struct + { + unsigned int reserved0 : 8; + /*! \brief 1E.0005.7 ROS Autonegotiation Present + AQ_GlobalStandardDevicesInPackage_HHD.u0.bits_0.autonegotiationPresent + + Default = 0x1 + + 1 = Autonegotiation is present in package + 0 = Autonegotiation is not present in package + + Notes: + This is always set to 1, as there is Autonegotiation in the PHY. */ + unsigned int autonegotiationPresent : 1; /* 1E.0005.7 ROS Default = 0x1 */ + /* 1 = Autonegotiation is present in package + 0 = Autonegotiation is not present in package */ + /*! \brief 1E.0005.6 ROS TC Present + AQ_GlobalStandardDevicesInPackage_HHD.u0.bits_0.tcPresent + + Default = 0x0 + + 1 = TC is present in package + 0 = TC is not present in package + + Notes: + This is always set to 0, as there is no TC functionality in the PHY. */ + unsigned int tcPresent : 1; /* 1E.0005.6 ROS Default = 0x0 */ + /* 1 = TC is present in package + 0 = TC is not present in package */ + /*! \brief 1E.0005.5 ROS DTE XS Present + AQ_GlobalStandardDevicesInPackage_HHD.u0.bits_0.dteXsPresent + + Default = 0x0 + + 1 = DTE XS is present in package + 0 = DTE XS is not present in package + + + Notes: + This is always set to 0, as there is no DTE XAUI interface in the PHY. */ + unsigned int dteXsPresent : 1; /* 1E.0005.5 ROS Default = 0x0 */ + /* 1 = DTE XS is present in package + 0 = DTE XS is not present in package + */ + /*! \brief 1E.0005.4 ROS PHY XS Present + AQ_GlobalStandardDevicesInPackage_HHD.u0.bits_0.phyXS_Present + + Default = 0x1 + + 1 = PHY XS is present in package + 0 = PHY XS is not present in package + + Notes: + This is always set to 1 as there is a PHY XS interface in the PHY. */ + unsigned int phyXS_Present : 1; /* 1E.0005.4 ROS Default = 0x1 */ + /* 1 = PHY XS is present in package + 0 = PHY XS is not present in package */ + /*! \brief 1E.0005.3 ROS PCS Present + AQ_GlobalStandardDevicesInPackage_HHD.u0.bits_0.pcsPresent + + Default = 0x1 + + 1 = PCS is present in package + 0 = PCS is not present in package + + Notes: + This is always set to 1 as there is PCS functionality in the PHY. */ + unsigned int pcsPresent : 1; /* 1E.0005.3 ROS Default = 0x1 */ + /* 1 = PCS is present in package + 0 = PCS is not present in package */ + /*! \brief 1E.0005.2 ROS WIS Present + AQ_GlobalStandardDevicesInPackage_HHD.u0.bits_0.wisPresent + + Default = 0x0 + + 1 = WIS is present in package + 0 = WIS is not present in package + + Notes: + This is always set to 0, as there is no WIS functionality in the PHY. */ + unsigned int wisPresent : 1; /* 1E.0005.2 ROS Default = 0x0 */ + /* 1 = WIS is present in package + 0 = WIS is not present in package */ + /*! \brief 1E.0005.1 ROS PMA Present + AQ_GlobalStandardDevicesInPackage_HHD.u0.bits_0.pmaPresent + + Default = 0x1 + + 1 = PMA is present in package + 0 = PMA is not present + + Notes: + This is always set to 1 as there is PMA functionality in the PHY. */ + unsigned int pmaPresent : 1; /* 1E.0005.1 ROS Default = 0x1 */ + /* 1 = PMA is present in package + 0 = PMA is not present */ + /*! \brief 1E.0005.0 ROS Clause 22 Registers Present + AQ_GlobalStandardDevicesInPackage_HHD.u0.bits_0.clause_22RegistersPresent + + Default = 0x0 + + 1 = Clause 22 registers are present in package + 0 = Clause 22 registers are not present in package + + Notes: + This is always set to 0 in the PHY, as there are no Clause 22 registers in the device. */ + unsigned int clause_22RegistersPresent : 1; /* 1E.0005.0 ROS Default = 0x0 */ + /* 1 = Clause 22 registers are present in package + 0 = Clause 22 registers are not present in package */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalStandardDevicesInPackage_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Vendor Devices in Package: 1E.0006 */ +/* Global Standard Vendor Devices in Package: 1E.0006 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Vendor Devices in Package */ + union + { + struct + { + /*! \brief 1E.0006.F ROS Vendor Specific Device #2 Present + AQ_GlobalStandardVendorDevicesInPackage_HHD.u0.bits_0.vendorSpecificDevice_2Present + + Default = 0x1 + + 1 = Device #2 is present in package + 0 = Device #2 is not present in package + + Notes: + This is always set to 1 as the PHY utilizes this device for the DSP PMA registers. */ + unsigned int vendorSpecificDevice_2Present : 1; /* 1E.0006.F ROS Default = 0x1 */ + /* 1 = Device #2 is present in package + 0 = Device #2 is not present in package */ + /*! \brief 1E.0006.E ROS Vendor Specific Device #1 Present + AQ_GlobalStandardVendorDevicesInPackage_HHD.u0.bits_0.vendorSpecificDevice_1Present + + Default = 0x1 + + 1 = Device #1 is present in package + 0 = Device #1 is not present in package + + Notes: + This is always set to 1 as the PHY utilizes this device for the global control registers. */ + unsigned int vendorSpecificDevice_1Present : 1; /* 1E.0006.E ROS Default = 0x1 */ + /* 1 = Device #1 is present in package + 0 = Device #1 is not present in package */ + /*! \brief 1E.0006.D ROS Clause 22 Extension Present + AQ_GlobalStandardVendorDevicesInPackage_HHD.u0.bits_0.clause_22ExtensionPresent + + Default = 0x1 + + 1 = Clause 22 Extension is present in package + 0 = Clause 22 Extension is not present in package + + Notes: + This is always set to 1 as the PHY utilizes this device for the GbE registers. */ + unsigned int clause_22ExtensionPresent : 1; /* 1E.0006.D ROS Default = 0x1 */ + /* 1 = Clause 22 Extension is present in package + 0 = Clause 22 Extension is not present in package */ + unsigned int reserved0 : 13; + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalStandardVendorDevicesInPackage_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Status 2: 1E.0008 */ +/* Global Standard Status 2: 1E.0008 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Status 2 */ + union + { + struct + { + /*! \brief 1E.0008.F:E ROS Device Present [1:0] + AQ_GlobalStandardStatus_2_HHD.u0.bits_0.devicePresent + + Default = 0x2 + + [F:E] + 0x3 = No device at this address + 0x2 = Device present at this address + 0x1 = No device at this address + 0x0 = No device at this address + + Notes: + This field is always set to 0x2, as the Global MMD resides here in the PHY. */ + unsigned int devicePresent : 2; /* 1E.0008.F:E ROS Default = 0x2 */ + /* [F:E] + 0x3 = No device at this address + 0x2 = Device present at this address + 0x1 = No device at this address + 0x0 = No device at this address */ + unsigned int reserved0 : 14; + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalStandardStatus_2_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Standard Package Identifier: 1E.000E */ +/* Global Standard Package Identifier: 1E.000E */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Standard Package Identifier */ + union + { + struct + { + /*! \brief 1E.000E.F:0 RO Package ID MSW [1F:10] + AQ_GlobalStandardPackageIdentifier_HHD.u0.bits_0.packageIdMSW + + + + Bits 31- 16 of Package ID + */ + unsigned int packageIdMSW : 16; /* 1E.000E.F:0 RO */ + /* Bits 31- 16 of Package ID */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Standard Package Identifier */ + union + { + struct + { + /*! \brief 1E.000F.F:0 RO Package ID LSW [F:0] + AQ_GlobalStandardPackageIdentifier_HHD.u1.bits_1.packageIdLSW + + + + Bits 15 - 0 of Package ID + */ + unsigned int packageIdLSW : 16; /* 1E.000F.F:0 RO */ + /* Bits 15 - 0 of Package ID */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalStandardPackageIdentifier_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Firmware ID: 1E.0020 */ +/* Global Firmware ID: 1E.0020 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Firmware ID */ + union + { + struct + { + /*! \brief 1E.0020.F:8 RO Firmware Major Revision Number [7:0] + AQ_GlobalFirmwareID_HHD.u0.bits_0.firmwareMajorRevisionNumber + + + + [F:8] = Major revision number + + Notes: + + + The lower six bits of major and minor firmware revision are exchanged in autonegotiation when the PHYID message is sent. */ + unsigned int firmwareMajorRevisionNumber : 8; /* 1E.0020.F:8 RO */ + /* [F:8] = Major revision number */ + /*! \brief 1E.0020.7:0 RO Firmware Minor Revision Number [7:0] + AQ_GlobalFirmwareID_HHD.u0.bits_0.firmwareMinorRevisionNumber + + + + [7:0] = Minor revision number + + Notes: + + + The lower six bits of major and minor firmware revision are exchanged in autonegotiation when the PHYID message is sent. */ + unsigned int firmwareMinorRevisionNumber : 8; /* 1E.0020.7:0 RO */ + /* [7:0] = Minor revision number */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalFirmwareID_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global NVR Interface: 1E.0100 */ +/* Global NVR Interface: 1E.0100 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global NVR Interface */ + union + { + struct + { + /*! \brief 1E.0100.F R/WSC NVR Execute Operation + AQ_GlobalNvrInterface_HHD.u0.bits_0.nvrExecuteOperation + + Default = 0x0 + + 1 = Start NVR Operation + + + + Notes: + When set to 1, the NVR operation will begin. Ensure that the uP is stalled using the See MCP Run Stall bit to ensure no NVR contention. */ + unsigned int nvrExecuteOperation : 1; /* 1E.0100.F R/WSC Default = 0x0 */ + /* 1 = Start NVR Operation + + */ + /*! \brief 1E.0100.E R/W NVR Write Mode + AQ_GlobalNvrInterface_HHD.u0.bits_0.nvrWriteMode + + Default = 0x0 + + 1 = Write to NVR + 0 = Read from NVR + + */ + unsigned int nvrWriteMode : 1; /* 1E.0100.E R/W Default = 0x0 */ + /* 1 = Write to NVR + 0 = Read from NVR + */ + /*! \brief 1E.0100.D R/W Freeze NVR CRC + AQ_GlobalNvrInterface_HHD.u0.bits_0.freezeNvrCrc + + Default = 0x0 + + 1 = Freeze NVR Mailbox CRC calculation register + + + Notes: + To prevent an erroneous answer, this bit should not be set at the same time the See NVR Operation Valid bit is set. */ + unsigned int freezeNvrCrc : 1; /* 1E.0100.D R/W Default = 0x0 */ + /* 1 = Freeze NVR Mailbox CRC calculation register + */ + /*! \brief 1E.0100.C R/WSC Reset NVR CRC + AQ_GlobalNvrInterface_HHD.u0.bits_0.resetNvrCrc + + Default = 0x0 + + 1 = Reset NVR Mailbox CRC calculation register + + + + Notes: + To prevent an erroneous answer, this bit should not be set at the same time the See NVR Operation Valid bit is set. */ + unsigned int resetNvrCrc : 1; /* 1E.0100.C R/WSC Default = 0x0 */ + /* 1 = Reset NVR Mailbox CRC calculation register + + */ + unsigned int reserved0 : 1; + /*! \brief 1E.0100.A R/W NVR Burst + AQ_GlobalNvrInterface_HHD.u0.bits_0.nvrBurst + + Default = 0x0 + + 0 = Single read or write operation of up to 4 bytes + 1 = Burst operation + + + Notes: + When this bit is set, the operation is a burst operation where more than 32-bits is read from the NVR or written to the NVR. This bit should be set to one until the last burst in the read or write operation, when it should be set to zero. It operates by gating the SPI clock, and not restarting it until new data is ready to be written, or the previous contents have been read. Each burst of data requires the NVR Execute Operation bit to be set to initiate the next phase. */ + unsigned int nvrBurst : 1; /* 1E.0100.A R/W Default = 0x0 */ + /* 0 = Single read or write operation of up to 4 bytes + 1 = Burst operation + */ + unsigned int reserved1 : 1; + /*! \brief 1E.0100.8 RO NVR Busy + AQ_GlobalNvrInterface_HHD.u0.bits_0.nvrBusy + + + + 1 = NVR is busy + 0 = NVR is ready + + + Notes: + When set to 1, the NVR is busy. A new NVR operation should not occur until this bit is 0. If the NVR clock is greater than 64/63 of the MDIO clock, this bit never needs to be polled when operating over the MDIO. */ + unsigned int nvrBusy : 1; /* 1E.0100.8 RO */ + /* 1 = NVR is busy + 0 = NVR is ready + */ + /*! \brief 1E.0100.7:0 R/W NVR Opcode [7:0] + AQ_GlobalNvrInterface_HHD.u0.bits_0.nvrOpcode + + Default = 0x03 + + NVR instruction opcode + + */ + unsigned int nvrOpcode : 8; /* 1E.0100.7:0 R/W Default = 0x03 */ + /* NVR instruction opcode + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global NVR Interface */ + union + { + struct + { + /*! \brief 1E.0101.F:0 RO NVR Mailbox CRC [F:0] + AQ_GlobalNvrInterface_HHD.u1.bits_1.nvrMailboxCrc + + + + The running CRC-16 of everything passing through the NVR interface + + + Notes: + The CRC-16 over all data written or read through the NVR interface. The CRC-16 is calculated by dividing the data by: + x^16 + x^12 + x^5 + 1 */ + unsigned int nvrMailboxCrc : 16; /* 1E.0101.F:0 RO */ + /* The running CRC-16 of everything passing through the NVR interface + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global NVR Interface */ + union + { + struct + { + unsigned int reserved0 : 8; + /*! \brief 1E.0102.7:0 R/W NVR Address MSW [17:10] + AQ_GlobalNvrInterface_HHD.u2.bits_2.nvrAddressMSW + + Default = 0x00 + + NVR address MSW bits [17:10] + + + Notes: + The address of where to read and write from in the NVR. This is self-incrementing and will automatically increment after each read or write operation. The increment amount is based on the data length (i.e. increments by 4 if the data length is 4 bytes) */ + unsigned int nvrAddressMSW : 8; /* 1E.0102.7:0 R/W Default = 0x00 */ + /* NVR address MSW bits [17:10] + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global NVR Interface */ + union + { + struct + { + /*! \brief 1E.0103.F:0 R/W NVR Address LSW [F:0] + AQ_GlobalNvrInterface_HHD.u3.bits_3.nvrAddressLSW + + Default = 0x0000 + + NVR address LSW bits [F:0] + + + Notes: + The address of where to read and write from in the NVR. This is self-incrementing and will automatically increment after each read or write operation. */ + unsigned int nvrAddressLSW : 16; /* 1E.0103.F:0 R/W Default = 0x0000 */ + /* NVR address LSW bits [F:0] + */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global NVR Interface */ + union + { + struct + { + /*! \brief 1E.0104.F:0 R/W NVR Data MSW [1F:10] + AQ_GlobalNvrInterface_HHD.u4.bits_4.nvrDataMSW + + Default = 0x0000 + + NVR data MSW bits [1F:10] + + + Notes: + Data is stored and read-out from these registers in little-endian format for operations such as FLASH device ID, and for programming the processor. + + For instance the 64K Atmel device code reads out as two bytes 0x651F into the LSW register, whereas the datasheet indicates that 1F is the first byte read, followed by 65 as the second byte. + + To burst read and write these 4 bytes in the correct order (where DD is written to address x), they should be stored as: + + AA BB in the MSW + CC DD in the LSW. */ + unsigned int nvrDataMSW : 16; /* 1E.0104.F:0 R/W Default = 0x0000 */ + /* NVR data MSW bits [1F:10] + */ + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of Global NVR Interface */ + union + { + struct + { + /*! \brief 1E.0105.F:0 R/W NVR Data LSW [F:0] + AQ_GlobalNvrInterface_HHD.u5.bits_5.nvrDataLSW + + Default = 0x0000 + + NVR data LSW bits [F:0] + + + Notes: + Data is stored and read-out from these registers in little-endian format for operations such as FLASH device ID, and for programming the processor. + + For instance the 64K Atmel device code reads out as two bytes 0x651F into the LSW register, whereas the datasheet indicates that 1F is the first byte read, followed by 65 as the second byte. + To burst read and write these 4 bytes in the correct order (where DD is written to address x), they should be stored as: + + AA BB in the MSW + CC DD in the LSW. */ + unsigned int nvrDataLSW : 16; /* 1E.0105.F:0 R/W Default = 0x0000 */ + /* NVR data LSW bits [F:0] + */ + } bits_5; + uint16_t word_5; + } u5; +} AQ_GlobalNvrInterface_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Mailbox Interface: 1E.0200 */ +/* Global Mailbox Interface: 1E.0200 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Mailbox Interface */ + union + { + struct + { + /*! \brief 1E.0200.F R/WSC uP Mailbox Execute Operation + AQ_GlobalMailboxInterface_HHD.u0.bits_0.upMailboxExecuteOperation + + Default = 0x0 + + 1 = Start of mailbox Operation + + + + Notes: + Indicates mailbox is loaded and ready */ + unsigned int upMailboxExecuteOperation : 1; /* 1E.0200.F R/WSC Default = 0x0 */ + /* 1 = Start of mailbox Operation + + */ + /*! \brief 1E.0200.E R/W uP Mailbox Write Mode + AQ_GlobalMailboxInterface_HHD.u0.bits_0.upMailboxWriteMode + + Default = 0x0 + + 1 = Write + 0 = Read + + + Notes: + Mailbox direction */ + unsigned int upMailboxWriteMode : 1; /* 1E.0200.E R/W Default = 0x0 */ + /* 1 = Write + 0 = Read + */ + unsigned int reserved0 : 1; + /*! \brief 1E.0200.C R/WSC Reset uP Mailbox CRC + AQ_GlobalMailboxInterface_HHD.u0.bits_0.resetUpMailboxCrc + + Default = 0x0 + + 1 = Reset uP mailbox CRC calculation register + + + */ + unsigned int resetUpMailboxCrc : 1; /* 1E.0200.C R/WSC Default = 0x0 */ + /* 1 = Reset uP mailbox CRC calculation register + + */ + unsigned int reserved1 : 3; + /*! \brief 1E.0200.8 RO uP Mailbox Busy + AQ_GlobalMailboxInterface_HHD.u0.bits_0.upMailboxBusy + + + + 1 = uP mailbox busy + 0 = uP mailbox ready + + + Notes: + In general the uP will respond within a few processor cycles to any PIF slave request, much faster than the MDIO. If the busy is asserted over multiple MDIO polling cycles, then a H/W error may have occurred and a Global S/W reset or uP reset is required. */ + unsigned int upMailboxBusy : 1; /* 1E.0200.8 RO */ + /* 1 = uP mailbox busy + 0 = uP mailbox ready + */ + unsigned int reserved2 : 8; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Mailbox Interface */ + union + { + struct + { + /*! \brief 1E.0201.F:0 RO uP Mailbox CRC [F:0] + AQ_GlobalMailboxInterface_HHD.u1.bits_1.upMailboxCrc + + + + The running CRC-16 of everything passing through the mailbox interface + + */ + unsigned int upMailboxCrc : 16; /* 1E.0201.F:0 RO */ + /* The running CRC-16 of everything passing through the mailbox interface + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Mailbox Interface */ + union + { + struct + { + /*! \brief 1E.0202.F:0 R/W uP Mailbox Address MSW [1F:10] + AQ_GlobalMailboxInterface_HHD.u2.bits_2.upMailboxAddressMSW + + Default = 0x0000 + + uP Mailbox MSW address + + + Notes: + The address of where to read and write from in the Microcontroller Mailbox. This is self-incrementing and automatically increments after each read and write operation.PHY */ + unsigned int upMailboxAddressMSW : 16; /* 1E.0202.F:0 R/W Default = 0x0000 */ + /* uP Mailbox MSW address + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global Mailbox Interface */ + union + { + struct + { + /*! \brief 1E.0203.F:2 R/W uP Mailbox Address LSW [F:2] + AQ_GlobalMailboxInterface_HHD.u3.bits_3.upMailboxAddressLSW + + Default = 0x0000 + + uP LSW Mailbox address [F:2] + + + Notes: + The address of where to read and write from in the Microcontroller Mailbox. This is self-incrementing and automatically increments after each read and write operation.PHY */ + unsigned int upMailboxAddressLSW : 14; /* 1E.0203.F:2 R/W Default = 0x0000 */ + /* uP LSW Mailbox address [F:2] + */ + /*! \brief 1E.0203.1:0 RO uP Mailbox Address LSW Don't Care [1:0] + AQ_GlobalMailboxInterface_HHD.u3.bits_3.upMailboxAddressLSW_Don_tCare + + + + Least significant uP LSW Mailbox address bits [1:0] + + + Notes: + These bits are always set to 0 since each memory access is on a 4-byte boundary. */ + unsigned int upMailboxAddressLSW_Don_tCare : 2; /* 1E.0203.1:0 RO */ + /* Least significant uP LSW Mailbox address bits [1:0] + */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global Mailbox Interface */ + union + { + struct + { + /*! \brief 1E.0204.F:0 R/W uP Mailbox Data MSW [1F:10] + AQ_GlobalMailboxInterface_HHD.u4.bits_4.upMailboxDataMSW + + Default = 0x0000 + + uP Mailbox data MSW + + */ + unsigned int upMailboxDataMSW : 16; /* 1E.0204.F:0 R/W Default = 0x0000 */ + /* uP Mailbox data MSW + */ + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of Global Mailbox Interface */ + union + { + struct + { + /*! \brief 1E.0205.F:0 R/W uP Mailbox Data LSW [F:0] + AQ_GlobalMailboxInterface_HHD.u5.bits_5.upMailboxDataLSW + + Default = 0x0000 + + uP Mailbox data LSW + + */ + unsigned int upMailboxDataLSW : 16; /* 1E.0205.F:0 R/W Default = 0x0000 */ + /* uP Mailbox data LSW + */ + } bits_5; + uint16_t word_5; + } u5; + /*! \brief Union for bit and word level access of word 6 of Global Mailbox Interface */ + union + { + struct + { + unsigned int reserved0 : 14; + /*! \brief 1E.0206.1 R/W uP Mailbox CRC Read Enable + AQ_GlobalMailboxInterface_HHD.u6.bits_6.upMailboxCrcReadEnable + + Default = 0x0 + + 1 = Update uP mailbox CRC on read + + */ + unsigned int upMailboxCrcReadEnable : 1; /* 1E.0206.1 R/W Default = 0x0 */ + /* 1 = Update uP mailbox CRC on read + */ + unsigned int reserved1 : 1; + } bits_6; + uint16_t word_6; + } u6; +} AQ_GlobalMailboxInterface_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Microprocessor Scratch Pad: 1E.0300 */ +/* Global Microprocessor Scratch Pad: 1E.0300 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Microprocessor Scratch Pad */ + union + { + struct + { + /*! \brief 1E.0300.F:0 R/W Scratch Pad 1[F:0] + AQ_GlobalMicroprocessorScratchPad_HHD.u0.bits_0.scratchPad_1 + + Default = 0x0000 + + General Purpose Scratch Pad + */ + unsigned int scratchPad_1 : 16; /* 1E.0300.F:0 R/W Default = 0x0000 */ + /* General Purpose Scratch Pad */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Microprocessor Scratch Pad */ + union + { + struct + { + /*! \brief 1E.0301.F:0 R/W Scratch Pad 2 [F:0] + AQ_GlobalMicroprocessorScratchPad_HHD.u1.bits_1.scratchPad_2 + + Default = 0x0000 + + General Purpose Scratch Pad + */ + unsigned int scratchPad_2 : 16; /* 1E.0301.F:0 R/W Default = 0x0000 */ + /* General Purpose Scratch Pad */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalMicroprocessorScratchPad_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress Control Register: 1E.5002 */ +/* MSS Egress Control Register: 1E.5002 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress Control Register */ + union + { + struct + { + /*! \brief 1E.5002.F:D R/W MSS Egress Ethertype Explicit SECTag LSB [2:0] + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressEthertypeExplicitSectagLsb + + Default = 0x0 + + Ethertype for explicit SECTag bits 2:0. + + + Notes: + Ethertype for explicity SECTag. */ + unsigned int mssEgressEthertypeExplicitSectagLsb : 3; /* 1E.5002.F:D R/W Default = 0x0 */ + /* Ethertype for explicit SECTag bits 2:0. + */ + /*! \brief 1E.5002.C R/W MSS Egress Clear Global Time + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressClearGlobalTime + + Default = 0x0 + + 1 = Clear global time + + + + Notes: + Clear global time. */ + unsigned int mssEgressClearGlobalTime : 1; /* 1E.5002.C R/W Default = 0x0 */ + /* 1 = Clear global time + + */ + /*! \brief 1E.5002.B R/W MSS Egress Clear Counter + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressClearCounter + + Default = 0x0 + + 1 = Clear all MIB counters + + + + Notes: + If this bit is set to 1, all MIB counters will be cleared. */ + unsigned int mssEgressClearCounter : 1; /* 1E.5002.B R/W Default = 0x0 */ + /* 1 = Clear all MIB counters + + */ + /*! \brief 1E.5002.A R/W MSS Egress High Priority + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressHighPriority + + Default = 0x0 + + 1 = MIB counter clear on read enable + + + + Notes: + If this bit is set to 1, read is given high priority and the MIB count value becomes 0 after read. */ + unsigned int mssEgressHighPriority : 1; /* 1E.5002.A R/W Default = 0x0 */ + /* 1 = MIB counter clear on read enable + + */ + /*! \brief 1E.5002.9 R/W MSS Egress ICV LSB 8 Bytes Enable + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressIcvLsb_8BytesEnable + + Default = 0x0 + + 1 = Use LSB + 0 = Use MSB + + + + Notes: + This bit selects MSB or LSB 8 bytes selection in the case where the ICV is 8 bytes. + 0 = MSB is used. */ + unsigned int mssEgressIcvLsb_8BytesEnable : 1; /* 1E.5002.9 R/W Default = 0x0 */ + /* 1 = Use LSB + 0 = Use MSB + + */ + /*! \brief 1E.5002.8 R/W MSS Egress External Classification Enable + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressExternalClassificationEnable + + Default = 0x0 + + 1 = Drop EGPRC miss packets + + + + Notes: + If set, internal classification is bypassed. Should always be set to 0. */ + unsigned int mssEgressExternalClassificationEnable : 1; /* 1E.5002.8 R/W Default = 0x0 */ + /* 1 = Drop EGPRC miss packets + + */ + /*! \brief 1E.5002.7 R/W MSS Egress Explicit SECTag Report Short Length + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressExplicitSectagReportShortLength + + Default = 0x0 + + Reserved + + + + Notes: + Unused. */ + unsigned int mssEgressExplicitSectagReportShortLength : 1; /* 1E.5002.7 R/W Default = 0x0 */ + /* Reserved + + */ + /*! \brief 1E.5002.6 R/W MSS Egress Drop Invalid SA/SC Packets + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressDropInvalidSa_scPackets + + Default = 0x0 + + 1 = Drop invalid SA/SC packets + + + + Notes: + Enables dropping of invalid SA/SC packets. */ + unsigned int mssEgressDropInvalidSa_scPackets : 1; /* 1E.5002.6 R/W Default = 0x0 */ + /* 1 = Drop invalid SA/SC packets + + */ + /*! \brief 1E.5002.5 R/W MSS Egress Unmatched Use SC 0 + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressUnmatchedUseSc_0 + + Default = 0x0 + + 1 = Use SC 0 for unmatched packets + 0 = Unmatched packets are uncontrolled packets + + + + Notes: + Use SC-Index 0 as default SC for unmatched packets. Otherwise the packets are treated as uncontrolled packets. */ + unsigned int mssEgressUnmatchedUseSc_0 : 1; /* 1E.5002.5 R/W Default = 0x0 */ + /* 1 = Use SC 0 for unmatched packets + 0 = Unmatched packets are uncontrolled packets + + */ + /*! \brief 1E.5002.4 R/W MSS Egresss GCM Test Mode + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgresssGcmTestMode + + Default = 0x0 + + 1 = Enable GCM test mode + + + + Notes: + Enables GCM test mode */ + unsigned int mssEgresssGcmTestMode : 1; /* 1E.5002.4 R/W Default = 0x0 */ + /* 1 = Enable GCM test mode + + */ + /*! \brief 1E.5002.3 R/W MSS Egress GCM Start + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressGcmStart + + Default = 0x0 + + 1 = Start GCM + + + + Notes: + Indicates GCM to start */ + unsigned int mssEgressGcmStart : 1; /* 1E.5002.3 R/W Default = 0x0 */ + /* 1 = Start GCM + + */ + /*! \brief 1E.5002.2 R/W MSS Egress Drop EGPRC LUT Miss + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressDropEgprcLutMiss + + Default = 0x0 + + 1 = Drop Egress Classification LUT miss packets + + + + Notes: + Decides whether Egress Pre-Security Classification (EGPRC) LUT miss packets are to be dropped */ + unsigned int mssEgressDropEgprcLutMiss : 1; /* 1E.5002.2 R/W Default = 0x0 */ + /* 1 = Drop Egress Classification LUT miss packets + + */ + /*! \brief 1E.5002.1 R/W MSS Egress Drop KAY Packet + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressDropKayPacket + + Default = 0x0 + + 1 = Drop KAY packet + + + Notes: + Decides whether KAY packets have to be dropped */ + unsigned int mssEgressDropKayPacket : 1; /* 1E.5002.1 R/W Default = 0x0 */ + /* 1 = Drop KAY packet + */ + /*! \brief 1E.5002.0 R/W MSS Egress Soft Reset + AQ_MssEgressControlRegister_HHD.u0.bits_0.mssEgressSoftReset + + Default = 0x0 + + 1 = Soft reset + + + Notes: + S/W reset */ + unsigned int mssEgressSoftReset : 1; /* 1E.5002.0 R/W Default = 0x0 */ + /* 1 = Soft reset + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress Control Register */ + union + { + struct + { + unsigned int reserved0 : 3; + /*! \brief 1E.5003.C:0 R/W MSS Egress Ethertype Explicit SECTag MSB [F:3] + AQ_MssEgressControlRegister_HHD.u1.bits_1.mssEgressEthertypeExplicitSectagMsb + + Default = 0x0000 + + Ethertype for explicit SECTag bits 15:3. + + + Notes: + Ethertype for explicity SECTag. */ + unsigned int mssEgressEthertypeExplicitSectagMsb : 13; /* 1E.5003.C:0 R/W Default = 0x0000 */ + /* Ethertype for explicit SECTag bits 15:3. + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssEgressControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress VLAN TPID 0 Register: 1E.5008 */ +/* MSS Egress VLAN TPID 0 Register: 1E.5008 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress VLAN TPID 0 Register */ + union + { + struct + { + /*! \brief 1E.5008.F:0 R/W MSS Egress VLAN STag TPID [F:0] + AQ_MssEgressVlanTpid_0Register_HHD.u0.bits_0.mssEgressVlanStagTpid + + Default = 0x0000 + + STag TPID + + + Notes: + Service Tag Protocol Identifier (TPID) values to identify a VLAN tag. The " See SEC Egress VLAN CP Tag Parse STag " bit must be set to 1 for the incoming packet's TPID to be parsed. */ + unsigned int mssEgressVlanStagTpid : 16; /* 1E.5008.F:0 R/W Default = 0x0000 */ + /* STag TPID + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress VLAN TPID 0 Register */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssEgressVlanTpid_0Register_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress VLAN TPID 1 Register: 1E.500A */ +/* MSS Egress VLAN TPID 1 Register: 1E.500A */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress VLAN TPID 1 Register */ + union + { + struct + { + /*! \brief 1E.500A.F:0 R/W MSS Egress VLAN QTag TPID [F:0] + AQ_MssEgressVlanTpid_1Register_HHD.u0.bits_0.mssEgressVlanQtagTpid + + Default = 0x0000 + + QTag TPID + + + Notes: + Customer Tag Protocol Identifier (TPID) values to identify a VLAN tag. The " See SEC Egress VLAN CP Tag Parse QTag " bit must be set to 1 for the incoming packet's TPID to be parsed. */ + unsigned int mssEgressVlanQtagTpid : 16; /* 1E.500A.F:0 R/W Default = 0x0000 */ + /* QTag TPID + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress VLAN TPID 1 Register */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssEgressVlanTpid_1Register_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress VLAN Control Register: 1E.500C */ +/* MSS Egress VLAN Control Register: 1E.500C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress VLAN Control Register */ + union + { + struct + { + /*! \brief 1E.500C.F:0 R/W MSS Egress VLAN UP Map Table [F:0] + AQ_MssEgressVlanControlRegister_HHD.u0.bits_0.mssEgressVlanUpMapTable + + Default = 0x0000 + + UP Map table bits 15:0 + + + Notes: + If there is a customer TPID Tag match and no service TPID Tag match or the service TPID Tag match is disabled, the outer TAG's PCP is used to index into this map table to generate the packets user priority. + 2:0 : UP value for customer Tag PCP 0x0 + 5:3: UP value for customer Tag PCP 0x0 + 8:6 : UP value for customer Tag PCP 0x0 + 11:9 : UP value for customer Tag PCP 0x0 + 14:12 : UP value for customer Tag PCP 0x0 + 17:15 : UP value for customer Tag PCP 0x0 + 20:18 : UP value for customer Tag PCP 0x0 + 23:21 : UP value for customer Tag PCP 0x0 */ + unsigned int mssEgressVlanUpMapTable : 16; /* 1E.500C.F:0 R/W Default = 0x0000 */ + /* UP Map table bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress VLAN Control Register */ + union + { + struct + { + /*! \brief 1E.500D.F R/W MSS Egress VLAN QTag Parse Enable + AQ_MssEgressVlanControlRegister_HHD.u1.bits_1.mssEgressVlanQtagParseEnable + + Default = 0x0 + + 1 = Enable VLAN QTag parsing + + + Notes: + Enable controlled port VLAN customer Tag parsing. When this bit is set to 1, the incoming packet's outer TPID will be compared with the configured " See SEC Egress TPID 1 [F:0] " for matching. If the " See SEC Egress VLAN CP Tag Parse QinQ " bit is set to1, this will also be used to compare the incoming packet's inner TPID. */ + unsigned int mssEgressVlanQtagParseEnable : 1; /* 1E.500D.F R/W Default = 0x0 */ + /* 1 = Enable VLAN QTag parsing + */ + /*! \brief 1E.500D.E R/W MSS Egress VLAN STag Parse Enable + AQ_MssEgressVlanControlRegister_HHD.u1.bits_1.mssEgressVlanStagParseEnable + + Default = 0x0 + + 1 = Enable VLAN STag parsing + + + Notes: + Enable controlled port VLAN service Tag parsing. When this bit is set to 1, the incoming packets outer TPID will be compared with the configured " See SEC Egress TPID 0 [F:0] " for matching. If the " See SEC Egress VLAN CP Tag Parse QinQ " bit is set to1, this will also be used to compare the incoming packet's inner TPID. */ + unsigned int mssEgressVlanStagParseEnable : 1; /* 1E.500D.E R/W Default = 0x0 */ + /* 1 = Enable VLAN STag parsing + */ + /*! \brief 1E.500D.D R/W MSS Egress VLAN QinQ Parse Enable + AQ_MssEgressVlanControlRegister_HHD.u1.bits_1.mssEgressVlanQinqParseEnable + + Default = 0x0 + + VLAN CP Tag Parse QinQ + + + Notes: + Enable controlled port VLAN QinQ Tag parsing. When this bit is set to 1 both the outer and inner VLAN Tags will be parsed. */ + unsigned int mssEgressVlanQinqParseEnable : 1; /* 1E.500D.D R/W Default = 0x0 */ + /* VLAN CP Tag Parse QinQ + */ + /*! \brief 1E.500D.C R/W MSS Egress VLAN QTag UP Parse Enable + AQ_MssEgressVlanControlRegister_HHD.u1.bits_1.mssEgressVlanQtagUpParseEnable + + Default = 0x0 + + VLAN CP Tag QTag UP enable + + + Notes: + Enable controlled port customer VLAN customer Tag user priority field parsing. */ + unsigned int mssEgressVlanQtagUpParseEnable : 1; /* 1E.500D.C R/W Default = 0x0 */ + /* VLAN CP Tag QTag UP enable + */ + /*! \brief 1E.500D.B R/W MSS Egress VLAN STag UP Parse Enable + AQ_MssEgressVlanControlRegister_HHD.u1.bits_1.mssEgressVlanStagUpParseEnable + + Default = 0x0 + + VLAN CP Tag STag UP enable + + + Notes: + Enable controlled port service VLAN service Tag user priority field parsing. */ + unsigned int mssEgressVlanStagUpParseEnable : 1; /* 1E.500D.B R/W Default = 0x0 */ + /* VLAN CP Tag STag UP enable + */ + /*! \brief 1E.500D.A:8 R/W MSS Egress VLAN UP Default [2:0] + AQ_MssEgressVlanControlRegister_HHD.u1.bits_1.mssEgressVlanUpDefault + + Default = 0x0 + + UP default + + + Notes: + User priority default */ + unsigned int mssEgressVlanUpDefault : 3; /* 1E.500D.A:8 R/W Default = 0x0 */ + /* UP default + */ + /*! \brief 1E.500D.7:0 R/W MSS Egress VLAN UP Map Table MSW [17:10] + AQ_MssEgressVlanControlRegister_HHD.u1.bits_1.mssEgressVlanUpMapTableMSW + + Default = 0x00 + + UP Map table bits 23:16 + + + Notes: + If there is a customer TPID Tag match and no service TPID Tag match or the service TPID Tag match is disabled, the outer TAG's PCP is used to index into this map table to generate the packets user priority. + 2:0 : UP value for customer Tag PCP 0x0 + 5:3: UP value for customer Tag PCP 0x0 + 8:6 : UP value for customer Tag PCP 0x0 + 11:9 : UP value for customer Tag PCP 0x0 + 14:12 : UP value for customer Tag PCP 0x0 + 17:15 : UP value for customer Tag PCP 0x0 + 20:18 : UP value for customer Tag PCP 0x0 + 23:21 : UP value for customer Tag PCP 0x0 */ + unsigned int mssEgressVlanUpMapTableMSW : 8; /* 1E.500D.7:0 R/W Default = 0x00 */ + /* UP Map table bits 23:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssEgressVlanControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress PN Control Register: 1E.500E */ +/* MSS Egress PN Control Register: 1E.500E */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress PN Control Register */ + union + { + struct + { + /*! \brief 1E.500E.F:0 R/W MSS Egress SA PN Threshold LSW [F:0] + AQ_MssEgressPnControlRegister_HHD.u0.bits_0.mssEgressSaPnThresholdLSW + + Default = 0x0000 + + PN threshold bits 15:0 + + + Notes: + Egress PN threshold to generate SA threshold interrupt. */ + unsigned int mssEgressSaPnThresholdLSW : 16; /* 1E.500E.F:0 R/W Default = 0x0000 */ + /* PN threshold bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress PN Control Register */ + union + { + struct + { + /*! \brief 1E.500F.F:0 R/W MSS Egress SA PN Threshold MSW [1F:10] + AQ_MssEgressPnControlRegister_HHD.u1.bits_1.mssEgressSaPnThresholdMSW + + Default = 0x0000 + + PN threshold bits 31:16 + + + Notes: + Egress PN threshold to generate SA threshold interrupt. */ + unsigned int mssEgressSaPnThresholdMSW : 16; /* 1E.500F.F:0 R/W Default = 0x0000 */ + /* PN threshold bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssEgressPnControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress MTU Size Control Register: 1E.5010 */ +/* MSS Egress MTU Size Control Register: 1E.5010 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress MTU Size Control Register */ + union + { + struct + { + /*! \brief 1E.5010.F:0 R/W MSS Egress Controlled Packet MTU Size [F:0] + AQ_MssEgressMtuSizeControlRegister_HHD.u0.bits_0.mssEgressControlledPacketMtuSize + + Default = 0x05DC + + Maximum transmission unit for controlled packet + + + Notes: + Maximum transmission unit of controlled packet */ + unsigned int mssEgressControlledPacketMtuSize : 16; /* 1E.5010.F:0 R/W Default = 0x05DC */ + /* Maximum transmission unit for controlled packet + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress MTU Size Control Register */ + union + { + struct + { + /*! \brief 1E.5011.F:0 R/W MSS Egress Uncontrolled Packet MTU Size [F:0] + AQ_MssEgressMtuSizeControlRegister_HHD.u1.bits_1.mssEgressUncontrolledPacketMtuSize + + Default = 0x05DC + + Maximum transmission unit for uncontrolled packet + + + Notes: + Maximum transmission unit of uncontrolled packet */ + unsigned int mssEgressUncontrolledPacketMtuSize : 16; /* 1E.5011.F:0 R/W Default = 0x05DC */ + /* Maximum transmission unit for uncontrolled packet + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssEgressMtuSizeControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress Interrupt Status Register: 1E.505C */ +/* MSS Egress Interrupt Status Register: 1E.505C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress Interrupt Status Register */ + union + { + struct + { + unsigned int reserved0 : 11; + /*! \brief 1E.505C.4 COW MSS Egress ECC Error Interrupt + AQ_MssEgressInterruptStatusRegister_HHD.u0.bits_0.mssEgressEccErrorInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. This bit is set when anyone of the memories detects an ECC error. */ + unsigned int mssEgressEccErrorInterrupt : 1; /* 1E.505C.4 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.505C.3 COW MSS Egress MIB Saturation Interrupt + AQ_MssEgressInterruptStatusRegister_HHD.u0.bits_0.mssEgressMibSaturationInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. This bit is set when the MIB counters reaches all ones saturation. */ + unsigned int mssEgressMibSaturationInterrupt : 1; /* 1E.505C.3 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.505C.2 COW MSS Egress SA Threshold Expired Interrupt + AQ_MssEgressInterruptStatusRegister_HHD.u0.bits_0.mssEgressSaThresholdExpiredInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. This bit is set when the SA PN reaches the See SEC Egress PN Threshold [F:0] and See SEC Egress PN Threshold [1F:10] . */ + unsigned int mssEgressSaThresholdExpiredInterrupt : 1; /* 1E.505C.2 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.505C.1 COW MSS Egress SA Expired Interrupt + AQ_MssEgressInterruptStatusRegister_HHD.u0.bits_0.mssEgressSaExpiredInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. This bit is set when the SA PN reaches all ones saturation. */ + unsigned int mssEgressSaExpiredInterrupt : 1; /* 1E.505C.1 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.505C.0 COW MSS Egress Master Interrupt + AQ_MssEgressInterruptStatusRegister_HHD.u0.bits_0.mssEgressMasterInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. This bit is set when any one of the above interrupt and the corresponding interrupt enable are both set. The interrupt enable for this bit must also be set for this bit to be set. */ + unsigned int mssEgressMasterInterrupt : 1; /* 1E.505C.0 COW Default = 0x0 */ + /* 1 = Interrupt + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress Interrupt Status Register */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssEgressInterruptStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress Interrupt Mask Register: 1E.505E */ +/* MSS Egress Interrupt Mask Register: 1E.505E */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress Interrupt Mask Register */ + union + { + struct + { + unsigned int reserved0 : 11; + /*! \brief 1E.505E.4 COW MSS Egress ECC Error Interrupt Enable + AQ_MssEgressInterruptMaskRegister_HHD.u0.bits_0.mssEgressEccErrorInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + + Notes: + Write to 1 to clear. This bit is set when anyone of the memories detects an ECC error. */ + unsigned int mssEgressEccErrorInterruptEnable : 1; /* 1E.505E.4 COW Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.505E.3 COW MSS Egress MIB Saturation Interrupt Enable + AQ_MssEgressInterruptMaskRegister_HHD.u0.bits_0.mssEgressMibSaturationInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + + Notes: + Write to 1 to clear. This bit is set when the MIB counters reaches all ones saturation. */ + unsigned int mssEgressMibSaturationInterruptEnable : 1; /* 1E.505E.3 COW Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.505E.2 COW MSS Egress SA Expired Threshold Interrupt Enable + AQ_MssEgressInterruptMaskRegister_HHD.u0.bits_0.mssEgressSaExpiredThresholdInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + + Notes: + Write to 1 to clear. This bit is set when the SA PN reaches the configured threshold See SEC Egress PN Threshold [F:0] and See SEC Egress PN Threshold [1F:10] . */ + unsigned int mssEgressSaExpiredThresholdInterruptEnable : 1; /* 1E.505E.2 COW Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.505E.1 COW MSS Egress SA Expired Interrupt Enable + AQ_MssEgressInterruptMaskRegister_HHD.u0.bits_0.mssEgressSaExpiredInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + + Notes: + Write to 1 to clear. This bit is set when the SA PN reaches all ones saturation. */ + unsigned int mssEgressSaExpiredInterruptEnable : 1; /* 1E.505E.1 COW Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.505E.0 COW MSS Egress Master Interrupt Enable + AQ_MssEgressInterruptMaskRegister_HHD.u0.bits_0.mssEgressMasterInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + + Notes: + Write to 1 to clear. */ + unsigned int mssEgressMasterInterruptEnable : 1; /* 1E.505E.0 COW Default = 0x0 */ + /* 1 = Interrupt enabled + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress Interrupt Mask Register */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssEgressInterruptMaskRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress SA Expired Status Register: 1E.5060 */ +/* MSS Egress SA Expired Status Register: 1E.5060 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress SA Expired Status Register */ + union + { + struct + { + /*! \brief 1E.5060.F:0 COW MSS Egress SA Expired LSW [F:0] + AQ_MssEgressSaExpiredStatusRegister_HHD.u0.bits_0.mssEgressSaExpiredLSW + + Default = 0x0000 + + SA expired bits 15:0 + + + Notes: + Write these bits to 1 to clear. + When set, these bits identify the SA that has expired when the SA PN reaches all-ones saturation. */ + unsigned int mssEgressSaExpiredLSW : 16; /* 1E.5060.F:0 COW Default = 0x0000 */ + /* SA expired bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress SA Expired Status Register */ + union + { + struct + { + /*! \brief 1E.5061.F:0 COW MSS Egress SA Expired MSW [1F:10] + AQ_MssEgressSaExpiredStatusRegister_HHD.u1.bits_1.mssEgressSaExpiredMSW + + Default = 0x0000 + + SA expired bits 31:16 + + + Notes: + Write these bits to 1 to clear. + When set, these bits identify the SA that has expired when the SA PN reaches all-ones saturation. */ + unsigned int mssEgressSaExpiredMSW : 16; /* 1E.5061.F:0 COW Default = 0x0000 */ + /* SA expired bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssEgressSaExpiredStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress SA Threshold Expired Status Register: 1E.5062 */ +/* MSS Egress SA Threshold Expired Status Register: 1E.5062 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress SA Threshold Expired Status Register */ + union + { + struct + { + /*! \brief 1E.5062.F:0 COW MSS Egress SA Threshold Expired LSW [F:0] + AQ_MssEgressSaThresholdExpiredStatusRegister_HHD.u0.bits_0.mssEgressSaThresholdExpiredLSW + + Default = 0x0000 + + SA threshold expired bits 15:0 + + + Notes: + Write these bits to 1 to clear. + When set, these bits identify the SA that has expired when the SA PN has reached the configured threshold See SEC Egress PN Threshold [F:0] and See SEC Egress PN Threshold [1F:10] . */ + unsigned int mssEgressSaThresholdExpiredLSW : 16; /* 1E.5062.F:0 COW Default = 0x0000 */ + /* SA threshold expired bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress SA Threshold Expired Status Register */ + union + { + struct + { + /*! \brief 1E.5063.F:0 COW MSS Egress SA Threshold Expired MSW [1F:10] + AQ_MssEgressSaThresholdExpiredStatusRegister_HHD.u1.bits_1.mssEgressSaThresholdExpiredMSW + + Default = 0x0000 + + SA threshold expired bits 31:16 + + + Notes: + Write these bits to 1 to clear. + When set, these bits identify the SA that has expired when the SA PN has reached the configured threshold See SEC Egress PN Threshold [F:0] and See SEC Egress PN Threshold [1F:10] . */ + unsigned int mssEgressSaThresholdExpiredMSW : 16; /* 1E.5063.F:0 COW Default = 0x0000 */ + /* SA threshold expired bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssEgressSaThresholdExpiredStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress ECC Interrupt Status Register: 1E.5064 */ +/* MSS Egress ECC Interrupt Status Register: 1E.5064 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress ECC Interrupt Status Register */ + union + { + struct + { + /*! \brief 1E.5064.F:0 COW MSS Egress SA ECC Error Interrupt LSW [F:0] + AQ_MssEgressEccInterruptStatusRegister_HHD.u0.bits_0.mssEgressSaEccErrorInterruptLSW + + Default = 0x0000 + + SA ECC error interrupt bits 15:0 + + + Notes: + Write these bits to 1 to clear. + When set to 1, indicates that an ECC error occured for the SA. */ + unsigned int mssEgressSaEccErrorInterruptLSW : 16; /* 1E.5064.F:0 COW Default = 0x0000 */ + /* SA ECC error interrupt bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress ECC Interrupt Status Register */ + union + { + struct + { + /*! \brief 1E.5065.F:0 COW MSS Egress SA ECC Error Interrupt MSW [1F:10] + AQ_MssEgressEccInterruptStatusRegister_HHD.u1.bits_1.mssEgressSaEccErrorInterruptMSW + + Default = 0x0000 + + SA ECC error interrupt bits 31:16 + + + Notes: + Write these bits to 1 to clear. + When set to 1, indicates that an ECC error occured for the SA. */ + unsigned int mssEgressSaEccErrorInterruptMSW : 16; /* 1E.5065.F:0 COW Default = 0x0000 */ + /* SA ECC error interrupt bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssEgressEccInterruptStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress LUT Address Control Register: 1E.5080 */ +/* MSS Egress LUT Address Control Register: 1E.5080 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress LUT Address Control Register */ + union + { + struct + { + /*! \brief 1E.5080.F:C R/W MSS Egress LUT Select [3:0] + AQ_MssEgressLutAddressControlRegister_HHD.u0.bits_0.mssEgressLutSelect + + Default = 0x0 + + LUT select + + + Notes: + 0x0 : Egress MAC Control FIlter (CTLF) LUT + 0x1 : Egress Classification LUT + 0x2 : Egress SC/SA LUT + 0x3 : Egress SMIB */ + unsigned int mssEgressLutSelect : 4; /* 1E.5080.F:C R/W Default = 0x0 */ + /* LUT select + */ + unsigned int reserved0 : 3; + /*! \brief 1E.5080.8:0 R/W MSS Egress LUT Address [8:0] + AQ_MssEgressLutAddressControlRegister_HHD.u0.bits_0.mssEgressLutAddress + + Default = 0x000 + + LUT address + + */ + unsigned int mssEgressLutAddress : 9; /* 1E.5080.8:0 R/W Default = 0x000 */ + /* LUT address + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_MssEgressLutAddressControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress LUT Control Register: 1E.5081 */ +/* MSS Egress LUT Control Register: 1E.5081 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress LUT Control Register */ + union + { + struct + { + /*! \brief 1E.5081.F R/W MSS Egress LUT Write + AQ_MssEgressLutControlRegister_HHD.u0.bits_0.mssEgressLutWrite + + Default = 0x0 + + 1 = LUT write + + + Notes: + Setting this bit to 1, will write the LUT. This bit will automatically clear to 0. */ + unsigned int mssEgressLutWrite : 1; /* 1E.5081.F R/W Default = 0x0 */ + /* 1 = LUT write + */ + /*! \brief 1E.5081.E R/W MSS Egress LUT Read + AQ_MssEgressLutControlRegister_HHD.u0.bits_0.mssEgressLutRead + + Default = 0x0 + + 1 = LUT read + + + Notes: + Setting this bit to 1, will read the LUT. This bit will automatically clear to 0. */ + unsigned int mssEgressLutRead : 1; /* 1E.5081.E R/W Default = 0x0 */ + /* 1 = LUT read + */ + unsigned int reserved0 : 14; + } bits_0; + uint16_t word_0; + } u0; +} AQ_MssEgressLutControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Egress LUT Data Control Register: 1E.50A0 */ +/* MSS Egress LUT Data Control Register: 1E.50A0 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50A0.F:0 R/W MSS Egress LUT Data 0 [F:0] + AQ_MssEgressLutDataControlRegister_HHD.u0.bits_0.mssEgressLutData_0 + + Default = 0x0000 + + LUT data bits 15:0 + + */ + unsigned int mssEgressLutData_0 : 16; /* 1E.50A0.F:0 R/W Default = 0x0000 */ + /* LUT data bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50A1.F:0 R/W MSS Egress LUT Data 1 [1F:10] + AQ_MssEgressLutDataControlRegister_HHD.u1.bits_1.mssEgressLutData_1 + + Default = 0x0000 + + LUT data bits 31:16 + + */ + unsigned int mssEgressLutData_1 : 16; /* 1E.50A1.F:0 R/W Default = 0x0000 */ + /* LUT data bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50A2.F:0 R/W MSS Egress LUT Data 2 [2F:20] + AQ_MssEgressLutDataControlRegister_HHD.u2.bits_2.mssEgressLutData_2 + + Default = 0x0000 + + LUT data bits 47:32 + + */ + unsigned int mssEgressLutData_2 : 16; /* 1E.50A2.F:0 R/W Default = 0x0000 */ + /* LUT data bits 47:32 + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50A3.F:0 R/W MSS Egress LUT Data 3 [3F:30] + AQ_MssEgressLutDataControlRegister_HHD.u3.bits_3.mssEgressLutData_3 + + Default = 0x0000 + + LUT data bits 63:48 + + */ + unsigned int mssEgressLutData_3 : 16; /* 1E.50A3.F:0 R/W Default = 0x0000 */ + /* LUT data bits 63:48 + */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50A4.F:0 R/W MSS Egress LUT Data 4 [4F:40] + AQ_MssEgressLutDataControlRegister_HHD.u4.bits_4.mssEgressLutData_4 + + Default = 0x0000 + + LUT data bits 79:64 + + */ + unsigned int mssEgressLutData_4 : 16; /* 1E.50A4.F:0 R/W Default = 0x0000 */ + /* LUT data bits 79:64 + */ + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50A5.F:0 R/W MSS Egress LUT Data 5 [5F:50] + AQ_MssEgressLutDataControlRegister_HHD.u5.bits_5.mssEgressLutData_5 + + Default = 0x0000 + + LUT data bits 95:80 + + */ + unsigned int mssEgressLutData_5 : 16; /* 1E.50A5.F:0 R/W Default = 0x0000 */ + /* LUT data bits 95:80 + */ + } bits_5; + uint16_t word_5; + } u5; + /*! \brief Union for bit and word level access of word 6 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50A6.F:0 R/W MSS Egress LUT Data 6 [6F:60] + AQ_MssEgressLutDataControlRegister_HHD.u6.bits_6.mssEgressLutData_6 + + Default = 0x0000 + + LUT data bits 111:96 + + */ + unsigned int mssEgressLutData_6 : 16; /* 1E.50A6.F:0 R/W Default = 0x0000 */ + /* LUT data bits 111:96 + */ + } bits_6; + uint16_t word_6; + } u6; + /*! \brief Union for bit and word level access of word 7 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50A7.F:0 R/W MSS Egress LUT Data 7 [7F:70] + AQ_MssEgressLutDataControlRegister_HHD.u7.bits_7.mssEgressLutData_7 + + Default = 0x0000 + + LUT data bits 127:112 + + */ + unsigned int mssEgressLutData_7 : 16; /* 1E.50A7.F:0 R/W Default = 0x0000 */ + /* LUT data bits 127:112 + */ + } bits_7; + uint16_t word_7; + } u7; + /*! \brief Union for bit and word level access of word 8 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50A8.F:0 R/W MSS Egress LUT Data 8 [8F:80] + AQ_MssEgressLutDataControlRegister_HHD.u8.bits_8.mssEgressLutData_8 + + Default = 0x0000 + + LUT data bits 143:128 + + */ + unsigned int mssEgressLutData_8 : 16; /* 1E.50A8.F:0 R/W Default = 0x0000 */ + /* LUT data bits 143:128 + */ + } bits_8; + uint16_t word_8; + } u8; + /*! \brief Union for bit and word level access of word 9 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50A9.F:0 R/W MSS Egress LUT Data 9 [9F:90] + AQ_MssEgressLutDataControlRegister_HHD.u9.bits_9.mssEgressLutData_9 + + Default = 0x0000 + + LUT data bits 159:144 + + */ + unsigned int mssEgressLutData_9 : 16; /* 1E.50A9.F:0 R/W Default = 0x0000 */ + /* LUT data bits 159:144 + */ + } bits_9; + uint16_t word_9; + } u9; + /*! \brief Union for bit and word level access of word 10 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50AA.F:0 R/W MSS Egress LUT Data 10 [AF:A0] + AQ_MssEgressLutDataControlRegister_HHD.u10.bits_10.mssEgressLutData_10 + + Default = 0x0000 + + LUT data bits 175:160 + + */ + unsigned int mssEgressLutData_10 : 16; /* 1E.50AA.F:0 R/W Default = 0x0000 */ + /* LUT data bits 175:160 + */ + } bits_10; + uint16_t word_10; + } u10; + /*! \brief Union for bit and word level access of word 11 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50AB.F:0 R/W MSS Egress LUT Data 11 [BF:B0] + AQ_MssEgressLutDataControlRegister_HHD.u11.bits_11.mssEgressLutData_11 + + Default = 0x0000 + + LUT data bits 191:176 + + */ + unsigned int mssEgressLutData_11 : 16; /* 1E.50AB.F:0 R/W Default = 0x0000 */ + /* LUT data bits 191:176 + */ + } bits_11; + uint16_t word_11; + } u11; + /*! \brief Union for bit and word level access of word 12 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50AC.F:0 R/W MSS Egress LUT Data 12 [CF:C0] + AQ_MssEgressLutDataControlRegister_HHD.u12.bits_12.mssEgressLutData_12 + + Default = 0x0000 + + LUT data bits 207:192 + + */ + unsigned int mssEgressLutData_12 : 16; /* 1E.50AC.F:0 R/W Default = 0x0000 */ + /* LUT data bits 207:192 + */ + } bits_12; + uint16_t word_12; + } u12; + /*! \brief Union for bit and word level access of word 13 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50AD.F:0 R/W MSS Egress LUT Data 13 [DF:D0] + AQ_MssEgressLutDataControlRegister_HHD.u13.bits_13.mssEgressLutData_13 + + Default = 0x0000 + + LUT data bits 223:208 + + */ + unsigned int mssEgressLutData_13 : 16; /* 1E.50AD.F:0 R/W Default = 0x0000 */ + /* LUT data bits 223:208 + */ + } bits_13; + uint16_t word_13; + } u13; + /*! \brief Union for bit and word level access of word 14 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50AE.F:0 R/W MSS Egress LUT Data 14 [EF:E0] + AQ_MssEgressLutDataControlRegister_HHD.u14.bits_14.mssEgressLutData_14 + + Default = 0x0000 + + LUT data bits 239:224 + + */ + unsigned int mssEgressLutData_14 : 16; /* 1E.50AE.F:0 R/W Default = 0x0000 */ + /* LUT data bits 239:224 + */ + } bits_14; + uint16_t word_14; + } u14; + /*! \brief Union for bit and word level access of word 15 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50AF.F:0 R/W MSS Egress LUT Data 15 [FF:F0] + AQ_MssEgressLutDataControlRegister_HHD.u15.bits_15.mssEgressLutData_15 + + Default = 0x0000 + + LUT data bits 255:240 + + */ + unsigned int mssEgressLutData_15 : 16; /* 1E.50AF.F:0 R/W Default = 0x0000 */ + /* LUT data bits 255:240 + */ + } bits_15; + uint16_t word_15; + } u15; + /*! \brief Union for bit and word level access of word 16 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50B0.F:0 R/W MSS Egress LUT Data 16 [10F:100] + AQ_MssEgressLutDataControlRegister_HHD.u16.bits_16.mssEgressLutData_16 + + Default = 0x0000 + + LUT data bits 271:256 + + */ + unsigned int mssEgressLutData_16 : 16; /* 1E.50B0.F:0 R/W Default = 0x0000 */ + /* LUT data bits 271:256 + */ + } bits_16; + uint16_t word_16; + } u16; + /*! \brief Union for bit and word level access of word 17 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50B1.F:0 R/W MSS Egress LUT Data 17 [11F:110] + AQ_MssEgressLutDataControlRegister_HHD.u17.bits_17.mssEgressLutData_17 + + Default = 0x0000 + + LUT data bits 287:272 + + */ + unsigned int mssEgressLutData_17 : 16; /* 1E.50B1.F:0 R/W Default = 0x0000 */ + /* LUT data bits 287:272 + */ + } bits_17; + uint16_t word_17; + } u17; + /*! \brief Union for bit and word level access of word 18 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50B2.F:0 R/W MSS Egress LUT Data 18 [12F:120] + AQ_MssEgressLutDataControlRegister_HHD.u18.bits_18.mssEgressLutData_18 + + Default = 0x0000 + + LUT data bits 303:288 + + */ + unsigned int mssEgressLutData_18 : 16; /* 1E.50B2.F:0 R/W Default = 0x0000 */ + /* LUT data bits 303:288 + */ + } bits_18; + uint16_t word_18; + } u18; + /*! \brief Union for bit and word level access of word 19 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50B3.F:0 R/W MSS Egress LUT Data 19 [13F:130] + AQ_MssEgressLutDataControlRegister_HHD.u19.bits_19.mssEgressLutData_19 + + Default = 0x0000 + + LUT data bits 319:304 + + */ + unsigned int mssEgressLutData_19 : 16; /* 1E.50B3.F:0 R/W Default = 0x0000 */ + /* LUT data bits 319:304 + */ + } bits_19; + uint16_t word_19; + } u19; + /*! \brief Union for bit and word level access of word 20 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50B4.F:0 R/W MSS Egress LUT Data 20 [14F:140] + AQ_MssEgressLutDataControlRegister_HHD.u20.bits_20.mssEgressLutData_20 + + Default = 0x0000 + + LUT data bits 335:320 + + */ + unsigned int mssEgressLutData_20 : 16; /* 1E.50B4.F:0 R/W Default = 0x0000 */ + /* LUT data bits 335:320 + */ + } bits_20; + uint16_t word_20; + } u20; + /*! \brief Union for bit and word level access of word 21 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50B5.F:0 R/W MSS Egress LUT Data 21 [15F:150] + AQ_MssEgressLutDataControlRegister_HHD.u21.bits_21.mssEgressLutData_21 + + Default = 0x0000 + + LUT data bits 351:336 + + */ + unsigned int mssEgressLutData_21 : 16; /* 1E.50B5.F:0 R/W Default = 0x0000 */ + /* LUT data bits 351:336 + */ + } bits_21; + uint16_t word_21; + } u21; + /*! \brief Union for bit and word level access of word 22 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50B6.F:0 R/W MSS Egress LUT Data 22 [16F:160] + AQ_MssEgressLutDataControlRegister_HHD.u22.bits_22.mssEgressLutData_22 + + Default = 0x0000 + + LUT data bits 367:352 + + */ + unsigned int mssEgressLutData_22 : 16; /* 1E.50B6.F:0 R/W Default = 0x0000 */ + /* LUT data bits 367:352 + */ + } bits_22; + uint16_t word_22; + } u22; + /*! \brief Union for bit and word level access of word 23 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50B7.F:0 R/W MSS Egress LUT Data 23 [17F:170] + AQ_MssEgressLutDataControlRegister_HHD.u23.bits_23.mssEgressLutData_23 + + Default = 0x0000 + + LUT data bits 383:368 + + */ + unsigned int mssEgressLutData_23 : 16; /* 1E.50B7.F:0 R/W Default = 0x0000 */ + /* LUT data bits 383:368 + */ + } bits_23; + uint16_t word_23; + } u23; + /*! \brief Union for bit and word level access of word 24 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50B8.F:0 R/W MSS Egress LUT Data 24 [18F:180] + AQ_MssEgressLutDataControlRegister_HHD.u24.bits_24.mssEgressLutData_24 + + Default = 0x0000 + + LUT data bits 399:384 + + */ + unsigned int mssEgressLutData_24 : 16; /* 1E.50B8.F:0 R/W Default = 0x0000 */ + /* LUT data bits 399:384 + */ + } bits_24; + uint16_t word_24; + } u24; + /*! \brief Union for bit and word level access of word 25 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50B9.F:0 R/W MSS Egress LUT Data 25 [19F:190] + AQ_MssEgressLutDataControlRegister_HHD.u25.bits_25.mssEgressLutData_25 + + Default = 0x0000 + + LUT data bits 415:400 + + */ + unsigned int mssEgressLutData_25 : 16; /* 1E.50B9.F:0 R/W Default = 0x0000 */ + /* LUT data bits 415:400 + */ + } bits_25; + uint16_t word_25; + } u25; + /*! \brief Union for bit and word level access of word 26 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50BA.F:0 R/W MSS Egress LUT Data 26 [1AF:1A0] + AQ_MssEgressLutDataControlRegister_HHD.u26.bits_26.mssEgressLutData_26 + + Default = 0x0000 + + LUT data bits 431:416 + + */ + unsigned int mssEgressLutData_26 : 16; /* 1E.50BA.F:0 R/W Default = 0x0000 */ + /* LUT data bits 431:416 + */ + } bits_26; + uint16_t word_26; + } u26; + /*! \brief Union for bit and word level access of word 27 of MSS Egress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.50BB.F:0 R/W MSS Egress LUT Data 27 [1BF:1B0] + AQ_MssEgressLutDataControlRegister_HHD.u27.bits_27.mssEgressLutData_27 + + Default = 0x0000 + + LUT data bits 447:432 + + */ + unsigned int mssEgressLutData_27 : 16; /* 1E.50BB.F:0 R/W Default = 0x0000 */ + /* LUT data bits 447:432 + */ + } bits_27; + uint16_t word_27; + } u27; +} AQ_MssEgressLutDataControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System General Control Register: 1E.6004 */ +/* MSM System General Control Register: 1E.6004 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System General Control Register */ + union + { + struct + { + /*! \brief 1E.6004.F R/W MSM System PHY Tx Enable + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemPhyTxEnable + + Default = 0x0 + + 1 = Enable PHY Tx + + + Notes: + Directly controls the phy_tx_ena pin. */ + unsigned int msmSystemPhyTxEnable : 1; /* 1E.6004.F R/W Default = 0x0 */ + /* 1 = Enable PHY Tx + */ + /*! \brief 1E.6004.E R/W MSM System Rx Error Discard + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemRxErrorDiscard + + Default = 0x0 + + 1 = Enable discard of received errored frames + + + Notes: + Rx errored frame discard enable. When set to 1, any frame received with an error is discarded and not forwarded to the client interface. When set to 0, errored frames are forwarded to the client interface with ff_rx_err asserted. + Note : It is recommended to set this bit to 1 only when store and forward operation is enabled (RX_SECTION_FULL TBD). */ + unsigned int msmSystemRxErrorDiscard : 1; /* 1E.6004.E R/W Default = 0x0 */ + /* 1 = Enable discard of received errored frames + */ + /*! \brief 1E.6004.D R/W MSM System Control Frame Enable + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemControlFrameEnable + + Default = 0x0 + + 1 = Control frame enabled + + + Notes: + MAC control frame enable. When set to 1, the MAC control frames with any Opcode other than 0x0001 are accepted and forwarded to the client interface. When set to 0, MAC control frames with any opcode other than 0x0001 are silently discarded. */ + unsigned int msmSystemControlFrameEnable : 1; /* 1E.6004.D R/W Default = 0x0 */ + /* 1 = Control frame enabled + */ + /*! \brief 1E.6004.C R/WSC MSM System Soft Reset + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemSoftReset + + Default = 0x0 + + 1 = Soft reset + + + Notes: + Software reset. Self clearing bit. When set to 1, resets all statistic counters as well as the Tx and Rx FIFOs. It should be issued after all traffic has been stopped as a result of clearing the Rx/Tx enable bits ( See MAC Rx Enable set to 0 and See MAC Tx Enable set to 0). + Note : Can lead to an Rx interface (ff_rx_xxx) violations to the application if the reset is issued in the middle of a receive frame transfer. Then the end of packet (assertion of ff_rx_eop) is lost and the application should be prepeared to handle this exception. */ + unsigned int msmSystemSoftReset : 1; /* 1E.6004.C R/WSC Default = 0x0 */ + /* 1 = Soft reset + */ + /*! \brief 1E.6004.B R/W MSM System Tx Pad Enable + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemTxPadEnable + + Default = 0x1 + + 1 = Enable Tx padding + + + Notes: + When set to 1, enable padding of frames in the Tx direction. When set to 0, the MAC will not extend frames from the application to a minimum of 64 bytes, allowing to transmit short frames (violating the Ethernet mimimum size requirements). Must be set to 1 for normal operation. */ + unsigned int msmSystemTxPadEnable : 1; /* 1E.6004.B R/W Default = 0x1 */ + /* 1 = Enable Tx padding + */ + /*! \brief 1E.6004.A R/W MSM System Tx CRC Append + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemTxCrcAppend + + Default = 0x0 + + 1 = Append Tx CRC + + + Notes: + Permanently enable CRC append on transmit. If set to 1, the Tx will append a CRC to all transmitted frames. If set to 0, CRC append can be controlled on a per frame basis using the pin ff_tx_crc. + This configuration bit is OR'ed with the external ff_tx_crc pin to instruct the Tx to append a CRC to transmitted frames. The ff_tx_crc pin is tied to 0. */ + unsigned int msmSystemTxCrcAppend : 1; /* 1E.6004.A R/W Default = 0x0 */ + /* 1 = Append Tx CRC + */ + /*! \brief 1E.6004.9 R/W MSM System Tx Address Insert Enable + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemTxAddressInsertEnable + + Default = 0x0 + + 1 = Insert Tx MAC source address + + + Notes: + Set the source MAC address on transmit. If set to 1, the MAC overwrites the source MAC address with the MAC programmed address in all transmitted frames. When set to 0, the source MAC address is transmitted unmodified from the MAC Tx client application. */ + unsigned int msmSystemTxAddressInsertEnable : 1; /* 1E.6004.9 R/W Default = 0x0 */ + /* 1 = Insert Tx MAC source address + */ + /*! \brief 1E.6004.8 R/W MSM System Pause Ignore + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemPauseIgnore + + Default = 0x0 + + 1 = Ignore pause frames + + + Notes: + Ignore pause frame quanta. If set to 1, received pause frames are ignored by the MAC. When set to 0, the Tx is stopped for the amount of time specified in the pause quanta received within the pause frame. */ + unsigned int msmSystemPauseIgnore : 1; /* 1E.6004.8 R/W Default = 0x0 */ + /* 1 = Ignore pause frames + */ + /*! \brief 1E.6004.7 R/W MSM System Pause Forward + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemPauseForward + + Default = 0x0 + + 1 = Enable Pause forwarding + + + Notes: + Terminate or forward pause frames. If set to 1, pause frames are forwarded to the user application. In normal mode, when set to 0, pause frames are terminated and discarded within the MAC. */ + unsigned int msmSystemPauseForward : 1; /* 1E.6004.7 R/W Default = 0x0 */ + /* 1 = Enable Pause forwarding + */ + /*! \brief 1E.6004.6 R/W MSM System CRC Forward + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemCrcForward + + Default = 0x0 + + 1 = Enable CRC forwarding + + + Notes: + When set to 1, the CRC field of the received frames is forwarded with the frame to the user application. If disabled, the CRC field is stripped from the frame. + Note : If padding is enabled ( See MAC PAD Enable set to 1), this bit is ignored. */ + unsigned int msmSystemCrcForward : 1; /* 1E.6004.6 R/W Default = 0x0 */ + /* 1 = Enable CRC forwarding + */ + /*! \brief 1E.6004.5 R/W MSM System PAD Enable + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemPadEnable + + Default = 0x0 + + 1 = Enable frame padding removal on Rx + + + Notes: + When set to 1, enable frame padding removal on the Rx path. If enabled, padding is removed before the frame is transferred to the MAC client application. If disabled, no padding is removed on the Rx by the MAC. + Note : On Tx, the MAC always adds padding as required. */ + unsigned int msmSystemPadEnable : 1; /* 1E.6004.5 R/W Default = 0x0 */ + /* 1 = Enable frame padding removal on Rx + */ + /*! \brief 1E.6004.4 R/W MSM System Promiscuous Mode + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemPromiscuousMode + + Default = 0x0 + + 1 = Promiscuous mode + + + Notes: + When set to 1, all frames are received without any MAC address filtering. */ + unsigned int msmSystemPromiscuousMode : 1; /* 1E.6004.4 R/W Default = 0x0 */ + /* 1 = Promiscuous mode + */ + /*! \brief 1E.6004.3 R/W MSM System WAN Mode + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemWanMode + + Default = 0x0 + + 1 = WAN mode + 0 = LAN mode + + + Notes: + WAN mode enable. Sets WAN mode when set to 1 and LAN mode when set to 0. Note: When changing the mode, verifiy correct setting of the Tx IPG. */ + unsigned int msmSystemWanMode : 1; /* 1E.6004.3 R/W Default = 0x0 */ + /* 1 = WAN mode + 0 = LAN mode + */ + unsigned int reserved0 : 1; + /*! \brief 1E.6004.1 R/W MSM System Rx Enable + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemRxEnable + + Default = 0x0 + + 1 = Rx enable + + Notes: + MAC Tx path enable. Should be set to 1 to enable the MAC Tx path. Should be set to 0 to disable the MAC Tx path. */ + unsigned int msmSystemRxEnable : 1; /* 1E.6004.1 R/W Default = 0x0 */ + /* 1 = Rx enable */ + /*! \brief 1E.6004.0 R/W MSM System Tx Enable + AQ_MsmSystemGeneralControlRegister_HHD.u0.bits_0.msmSystemTxEnable + + Default = 0x0 + + 1 = Tx enable + + Notes: + MAC Rx path enable. Should be set to 1 to enable the MAC Rx path. Should be set to 0 to disable the MAC Rx path. */ + unsigned int msmSystemTxEnable : 1; /* 1E.6004.0 R/W Default = 0x0 */ + /* 1 = Tx enable */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System General Control Register */ + union + { + struct + { + unsigned int reserved0 : 8; + /*! \brief 1E.6005.7 R/W MSM System Tx Low Power IDLE Enable + AQ_MsmSystemGeneralControlRegister_HHD.u1.bits_1.msmSystemTxLowPowerIdleEnable + + Default = 0x0 + + 1 = Transmit LPI enable + + + Notes: + Transmit low power IDLE enable. When set to 1, the MAC completes the transmission of the current frame and generates low power IDLE sequences (LPI) to the XGMII/SGMII. When set to 0, the MAC operates in normal mode. This bit is OR'ed with the reg_lowp_ena pin. */ + unsigned int msmSystemTxLowPowerIdleEnable : 1; /* 1E.6005.7 R/W Default = 0x0 */ + /* 1 = Transmit LPI enable + */ + unsigned int reserved1 : 1; + /*! \brief 1E.6005.5 R/W MSM System SFD Check Disable + AQ_MsmSystemGeneralControlRegister_HHD.u1.bits_1.msmSystemSfdCheckDisable + + Default = 0x0 + + 1 = Disable SFD check + + + Notes: + Disable check of SFD (0xD5) character at frame start. When set to 1, the frame is accepted even if the SFD byte following the preamble is not 0xD5. When set to 0, a frame is accepted only if the SFD byte is found with the value 0xD5. */ + unsigned int msmSystemSfdCheckDisable : 1; /* 1E.6005.5 R/W Default = 0x0 */ + /* 1 = Disable SFD check + */ + unsigned int reserved2 : 1; + /*! \brief 1E.6005.3 R/W MSM System Priority Flow Control Enable + AQ_MsmSystemGeneralControlRegister_HHD.u1.bits_1.msmSystemPriorityFlowControlEnable + + Default = 0x0 + + 1 = Enable priority flow control + 0 = Enable link flow control + + + Notes: + Enable priority flow control (PFC) mode of operation. When set to 0, the MAC uses standard link pause frames. When set to 1, the MAC will transmit and accept PFC frames. */ + unsigned int msmSystemPriorityFlowControlEnable : 1; /* 1E.6005.3 R/W Default = 0x0 */ + /* 1 = Enable priority flow control + 0 = Enable link flow control + */ + /*! \brief 1E.6005.2 R/W MSM System IDLE Column Count Extend + AQ_MsmSystemGeneralControlRegister_HHD.u1.bits_1.msmSystemIdleColumnCountExtend + + Default = 0x0 + + 1 = Extend IDLE column count + + Notes: + When set to 1, extends the RS layer IDLE column counter by 2x. The IEEE 802.3ae defines the fault condition to be cleared after 128 columns of IDLE have been received. If the MAC operates together with a WAN mode PCS (WIS) it may may happen (depending on PCS) that this period is too short to bridge the IDLE stuffing occurring in this mode, leading to a toggling fault indication. In this case, extending the counter helps to aoivd toggling fault indications. */ + unsigned int msmSystemIdleColumnCountExtend : 1; /* 1E.6005.2 R/W Default = 0x0 */ + /* 1 = Extend IDLE column count */ + /*! \brief 1E.6005.1 R/W MSM System Length Check Disable + AQ_MsmSystemGeneralControlRegister_HHD.u1.bits_1.msmSystemLengthCheckDisable + + Default = 0x0 + + 1 = Disable length check + + Notes: + Payload length check disable. When set to 0, the MAC checks the frames payload length with the frame length/type field. When set to 1, the payload length check is disabled. */ + unsigned int msmSystemLengthCheckDisable : 1; /* 1E.6005.1 R/W Default = 0x0 */ + /* 1 = Disable length check */ + /*! \brief 1E.6005.0 R/W MSM System Force Send IDLE + AQ_MsmSystemGeneralControlRegister_HHD.u1.bits_1.msmSystemForceSendIdle + + Default = 0x0 + + 1 = Force send idle + + Notes: + When set to 1, suppress any frame transmissions and forces IDLE n the Tx interface instead of frames. This control affects the MAC reconciliation layer (RS) which acts after all MAC datapath has processed the frame. + Note : Does not have an effect on fault handling (i.e. reception of local fault will still cause transmit of remote fault). + Must be 0 for normal operation. */ + unsigned int msmSystemForceSendIdle : 1; /* 1E.6005.0 R/W Default = 0x0 */ + /* 1 = Force send idle */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemGeneralControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System FIFO Control Register: 1E.600E */ +/* MSM System FIFO Control Register: 1E.600E */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System FIFO Control Register */ + union + { + struct + { + unsigned int reserved0 : 8; + /*! \brief 1E.600E.7:0 R/W MSM System Rx FIFO Full Threshold [7:0] + AQ_MsmSystemFifoControlRegister_HHD.u0.bits_0.msmSystemRxFifoFullThreshold + + Default = 0x08 + + Rx FIFO full threshold + + Notes: + All threshold values are in steps of FIFO words. */ + unsigned int msmSystemRxFifoFullThreshold : 8; /* 1E.600E.7:0 R/W Default = 0x08 */ + /* Rx FIFO full threshold */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System FIFO Control Register */ + union + { + struct + { + unsigned int reserved0 : 8; + /*! \brief 1E.600F.7:0 R/W MSM System Rx FIFO Empty Threshold [7:0] + AQ_MsmSystemFifoControlRegister_HHD.u1.bits_1.msmSystemRxFifoEmptyThreshold + + Default = 0x00 + + Rx FIFO empty threshold + + Notes: + All threshold values are in steps of FIFO words. */ + unsigned int msmSystemRxFifoEmptyThreshold : 8; /* 1E.600F.7:0 R/W Default = 0x00 */ + /* Rx FIFO empty threshold */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of MSM System FIFO Control Register */ + union + { + struct + { + unsigned int reserved0 : 10; + /*! \brief 1E.6010.5:0 R/W MSM System Tx FIFO Full Threshold [5:0] + AQ_MsmSystemFifoControlRegister_HHD.u2.bits_2.msmSystemTxFifoFullThreshold + + Default = 0x08 + + Tx FIFO full threshold + + Notes: + All threshold values are in steps of FIFO words. */ + unsigned int msmSystemTxFifoFullThreshold : 6; /* 1E.6010.5:0 R/W Default = 0x08 */ + /* Tx FIFO full threshold */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of MSM System FIFO Control Register */ + union + { + struct + { + unsigned int reserved0 : 10; + /*! \brief 1E.6011.5:0 R/W MSM System Tx FIFO Empty Threshold [5:0] + AQ_MsmSystemFifoControlRegister_HHD.u3.bits_3.msmSystemTxFifoEmptyThreshold + + Default = 0x00 + + Tx FIFO empty threshold + + Notes: + All threshold values are in steps of FIFO words. */ + unsigned int msmSystemTxFifoEmptyThreshold : 6; /* 1E.6011.5:0 R/W Default = 0x00 */ + /* Tx FIFO empty threshold */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of MSM System FIFO Control Register */ + union + { + struct + { + unsigned int reserved0 : 8; + /*! \brief 1E.6012.7:0 ROS MSM System Rx FIFO Almost Full Threshold [7:0] + AQ_MsmSystemFifoControlRegister_HHD.u4.bits_4.msmSystemRxFifoAlmostFullThreshold + + Default = 0x00 + + Rx FIFO almost full threshold + + Notes: + Unused. */ + unsigned int msmSystemRxFifoAlmostFullThreshold : 8; /* 1E.6012.7:0 ROS Default = 0x00 */ + /* Rx FIFO almost full threshold */ + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of MSM System FIFO Control Register */ + union + { + struct + { + unsigned int reserved0 : 8; + /*! \brief 1E.6013.7:0 ROS MSM System Rx FIFO Almost Empty Threshold [7:0] + AQ_MsmSystemFifoControlRegister_HHD.u5.bits_5.msmSystemRxFifoAlmostEmptyThreshold + + Default = 0x00 + + Rx FIFO almost empty threshold + + Notes: + Unused. */ + unsigned int msmSystemRxFifoAlmostEmptyThreshold : 8; /* 1E.6013.7:0 ROS Default = 0x00 */ + /* Rx FIFO almost empty threshold */ + } bits_5; + uint16_t word_5; + } u5; + /*! \brief Union for bit and word level access of word 6 of MSM System FIFO Control Register */ + union + { + struct + { + unsigned int reserved0 : 8; + /*! \brief 1E.6014.7:0 ROS MSM System Tx FIFO Almost Full Threshold [7:0] + AQ_MsmSystemFifoControlRegister_HHD.u6.bits_6.msmSystemTxFifoAlmostFullThreshold + + Default = 0x00 + + Tx FIFO almost full threshold + + Notes: + Unused. */ + unsigned int msmSystemTxFifoAlmostFullThreshold : 8; /* 1E.6014.7:0 ROS Default = 0x00 */ + /* Tx FIFO almost full threshold */ + } bits_6; + uint16_t word_6; + } u6; + /*! \brief Union for bit and word level access of word 7 of MSM System FIFO Control Register */ + union + { + struct + { + unsigned int reserved0 : 8; + /*! \brief 1E.6015.7:0 ROS MSM System Tx FIFO Almost Empty Threshold [7:0] + AQ_MsmSystemFifoControlRegister_HHD.u7.bits_7.msmSystemTxFifoAlmostEmptyThreshold + + Default = 0x00 + + Tx FIFO almost empty threshold + + Notes: + Unused. */ + unsigned int msmSystemTxFifoAlmostEmptyThreshold : 8; /* 1E.6015.7:0 ROS Default = 0x00 */ + /* Tx FIFO almost empty threshold */ + } bits_7; + uint16_t word_7; + } u7; +} AQ_MsmSystemFifoControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System General Status Register: 1E.6020 */ +/* MSM System General Status Register: 1E.6020 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System General Status Register */ + union + { + struct + { + unsigned int reserved0 : 10; + /*! \brief 1E.6020.5 RO MSM System Tx FIFO Empty + AQ_MsmSystemGeneralStatusRegister_HHD.u0.bits_0.msmSystemTxFifoEmpty + + + + Tx FIFO empty + + Notes: + When set to 1, indicates the Tx FIFO is empty. When set to 0, Tx FIFO is non-empty. */ + unsigned int msmSystemTxFifoEmpty : 1; /* 1E.6020.5 RO */ + /* Tx FIFO empty */ + /*! \brief 1E.6020.4 RO MSM System Rx Low Power IDLE + AQ_MsmSystemGeneralStatusRegister_HHD.u0.bits_0.msmSystemRxLowPowerIdle + + + + Rx LPI detected + + Notes: + Receive low power IDLE (LPI). Set to 1 when LPI is currently detected on the MAC Rx interface. Set to 0, when the MAC currently operates in normal mode. */ + unsigned int msmSystemRxLowPowerIdle : 1; /* 1E.6020.4 RO */ + /* Rx LPI detected */ + /*! \brief 1E.6020.3 R/W MSM System Timestamp Available + AQ_MsmSystemGeneralStatusRegister_HHD.u0.bits_0.msmSystemTimestampAvailable + + Default = 0x0 + + Timestamp available + + Notes: + Transmit timestamp available. Indicates that the timestamp of the last transmitted event frame (which had ff_tx_ts_frm=1) is available in the register See MAC Time Stamp Status 0 [F:0] and See MAC Time Stamp Status 1 [F:0] . To clear this bit, the bit must be written with a 1. + */ + unsigned int msmSystemTimestampAvailable : 1; /* 1E.6020.3 R/W Default = 0x0 */ + /* Timestamp available */ + /*! \brief 1E.6020.2 RO MSM System PHY Loss of Signal + AQ_MsmSystemGeneralStatusRegister_HHD.u0.bits_0.msmSystemPhyLossOfSignal + + + + PHY loss of signal + + Notes: + PHY indicates loss of signal. This is the value of pin phy_los which is tied to 0. */ + unsigned int msmSystemPhyLossOfSignal : 1; /* 1E.6020.2 RO */ + /* PHY loss of signal */ + /*! \brief 1E.6020.1 BLH MSM System Rx Remote Fault + AQ_MsmSystemGeneralStatusRegister_HHD.u0.bits_0.msmSystemRxRemoteFault + + + + Rx remote fault detected + + Notes: + Latch high local fault status. Set to 1, whent he MAC detects Rx local fault sequences on the Rx interface. Reset to 0 after read and after reset. */ + unsigned int msmSystemRxRemoteFault : 1; /* 1E.6020.1 BLH */ + /* Rx remote fault detected */ + /*! \brief 1E.6020.0 BLH MSM System Rx Local Fault + AQ_MsmSystemGeneralStatusRegister_HHD.u0.bits_0.msmSystemRxLocalFault + + + + Rx local fault detected + + Notes: + Latch high local fault status. Set to 1, whent he MAC detects Rx local fault sequences on the Rx interface. Reset to 0 after read and after reset. */ + unsigned int msmSystemRxLocalFault : 1; /* 1E.6020.0 BLH */ + /* Rx local fault detected */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System General Status Register */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemGeneralStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Tx IPG Control Register: 1E.6022 */ +/* MSM System Tx IPG Control Register: 1E.6022 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Tx IPG Control Register */ + union + { + struct + { + unsigned int reserved0 : 10; + /*! \brief 1E.6022.5:0 R/W MSM System Tx IPG Length [5:0] + AQ_MsmSystemTxIpgControlRegister_HHD.u0.bits_0.msmSystemTxIpgLength + + Default = 0x0C + + Tx IPG length + + Notes: + Tx inter-packet gap (IPG) value. Depending on LAN or WAN mode of operation. + LAN Mode : Number of octets in steps of 4. Valid values are 8, 12, 16,..., 100. DIC is supported for any setting > 8. A default of 12 must be set to conform to IEEE802.3ae. + WAN Mode : Stretch factor. Valid values are 4 ... 15. The stretch factor is calculated as (value+1)*8. A default of 12 must be set to conform to IEEE802.3ae (i.e. 13*8=104). A larger value shrinks the IPG (increasing bandwidth). + The reset value of 12 leads to IEEE802.3ae conformant behavior in both modes. + Note : WAN mode is only available in 10G mode of operation. */ + unsigned int msmSystemTxIpgLength : 6; /* 1E.6022.5:0 R/W Default = 0x0C */ + /* Tx IPG length */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Tx IPG Control Register */ + union + { + struct + { + /*! \brief 1E.6023.F:0 MSM System Tx IPG Reserved + AQ_MsmSystemTxIpgControlRegister_HHD.u1.bits_1.msmSystemTxIpgReserved + + + + Value always 0, writes ignored + */ + unsigned int msmSystemTxIpgReserved : 16; /* 1E.6023.F:0 */ + /* Value always 0, writes ignored */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemTxIpgControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Tx Good Frames Counter Register: 1E.6040 */ +/* MSM System Tx Good Frames Counter Register: 1E.6040 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Tx Good Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6040.F:0 ROS MSM System Tx Good Frames Counter 0 [F:0] + AQ_MsmSystemTxGoodFramesCounterRegister_HHD.u0.bits_0.msmSystemTxGoodFramesCounter_0 + + Default = 0x0000 + + Tx good frame counter bits 15:0 + + Notes: + Count of frames transmitted without error (Including pause frames). */ + unsigned int msmSystemTxGoodFramesCounter_0 : 16; /* 1E.6040.F:0 ROS Default = 0x0000 */ + /* Tx good frame counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Tx Good Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6041.F:0 ROS MSM System Tx Good Frames Counter 1 [F:0] + AQ_MsmSystemTxGoodFramesCounterRegister_HHD.u1.bits_1.msmSystemTxGoodFramesCounter_1 + + Default = 0x0000 + + Tx good frame counter bits 31:16 + + + Notes: + Count of frames transmitted without error (Including pause frames). */ + unsigned int msmSystemTxGoodFramesCounter_1 : 16; /* 1E.6041.F:0 ROS Default = 0x0000 */ + /* Tx good frame counter bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemTxGoodFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx Good Frames Counter Register: 1E.6044 */ +/* MSM System Rx Good Frames Counter Register: 1E.6044 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx Good Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6044.F:0 ROS MSM System Rx Good Frames Counter 0 [F:0] + AQ_MsmSystemRxGoodFramesCounterRegister_HHD.u0.bits_0.msmSystemRxGoodFramesCounter_0 + + Default = 0x0000 + + Rx good frame counter bits 15:0 + + Notes: + Count of frames received without error (Including pause frames). */ + unsigned int msmSystemRxGoodFramesCounter_0 : 16; /* 1E.6044.F:0 ROS Default = 0x0000 */ + /* Rx good frame counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx Good Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6045.F:0 ROS MSM System Rx Good Frames Counter 1 [F:0] + AQ_MsmSystemRxGoodFramesCounterRegister_HHD.u1.bits_1.msmSystemRxGoodFramesCounter_1 + + Default = 0x0000 + + Rx good frame counter bits 31:16 + + Notes: + Count of frames received without error (Including pause frames). */ + unsigned int msmSystemRxGoodFramesCounter_1 : 16; /* 1E.6045.F:0 ROS Default = 0x0000 */ + /* Rx good frame counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxGoodFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx FCS Errors Counter Register: 1E.6048 */ +/* MSM System Rx FCS Errors Counter Register: 1E.6048 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx FCS Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.6048.F:0 ROS MSM System FCS Error Counter 0 [F:0] + AQ_MsmSystemRxFcsErrorsCounterRegister_HHD.u0.bits_0.msmSystemFcsErrorCounter_0 + + Default = 0x0000 + + Frame check sequence error counter bits 15:0 + + Notes: + Count of frames for which a CRC-32 Error is detected but the frame is otherwise of correct length. */ + unsigned int msmSystemFcsErrorCounter_0 : 16; /* 1E.6048.F:0 ROS Default = 0x0000 */ + /* Frame check sequence error counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx FCS Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.6049.F:0 ROS MSM System FCS Error Counter 1 [F:0] + AQ_MsmSystemRxFcsErrorsCounterRegister_HHD.u1.bits_1.msmSystemFcsErrorCounter_1 + + Default = 0x0000 + + Frame check sequence error counter bits 31:16 + + Notes: + Count of frames for which a CRC-32 Error is detected but the frame is otherwise of correct length. */ + unsigned int msmSystemFcsErrorCounter_1 : 16; /* 1E.6049.F:0 ROS Default = 0x0000 */ + /* Frame check sequence error counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxFcsErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx Alignment Errors Counter Register: 1E.604C */ +/* MSM System Rx Alignment Errors Counter Register: 1E.604C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx Alignment Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.604C.F:0 ROS MSM System Alignment Error Counter 0 [F:0] + AQ_MsmSystemRxAlignmentErrorsCounterRegister_HHD.u0.bits_0.msmSystemAlignmentErrorCounter_0 + + Default = 0x0000 + + Alignment error counter bits 15:0 + + Notes: + Count of frames received with an alignment error. */ + unsigned int msmSystemAlignmentErrorCounter_0 : 16; /* 1E.604C.F:0 ROS Default = 0x0000 */ + /* Alignment error counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx Alignment Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.604D.F:0 ROS MSM System Alignment Error Counter 1 [F:0] + AQ_MsmSystemRxAlignmentErrorsCounterRegister_HHD.u1.bits_1.msmSystemAlignmentErrorCounter_1 + + Default = 0x0000 + + Alignment error counter bits 31:16 + + Notes: + Count of frames received with an alignment error. */ + unsigned int msmSystemAlignmentErrorCounter_1 : 16; /* 1E.604D.F:0 ROS Default = 0x0000 */ + /* Alignment error counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxAlignmentErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Tx Pause Frames Counter Register: 1E.6050 */ +/* MSM System Tx Pause Frames Counter Register: 1E.6050 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Tx Pause Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6050.F:0 ROS MSM System Tx Pause Frames Counter 0 [F:0] + AQ_MsmSystemTxPauseFramesCounterRegister_HHD.u0.bits_0.msmSystemTxPauseFramesCounter_0 + + Default = 0x0000 + + Tx pause frame counter bits 15:0 + + Notes: + Valid pause frames transmitted. */ + unsigned int msmSystemTxPauseFramesCounter_0 : 16; /* 1E.6050.F:0 ROS Default = 0x0000 */ + /* Tx pause frame counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Tx Pause Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6051.F:0 ROS MSM System Tx Pause Frames Counter 1 [F:0] + AQ_MsmSystemTxPauseFramesCounterRegister_HHD.u1.bits_1.msmSystemTxPauseFramesCounter_1 + + Default = 0x0000 + + Tx pause frame counter bits 31:16 + + + Notes: + Valid pause frames transmitted. */ + unsigned int msmSystemTxPauseFramesCounter_1 : 16; /* 1E.6051.F:0 ROS Default = 0x0000 */ + /* Tx pause frame counter bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemTxPauseFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx Pause Frames Counter Register: 1E.6054 */ +/* MSM System Rx Pause Frames Counter Register: 1E.6054 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx Pause Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6054.F:0 ROS MSM System Rx Pause Frames Counter 0 [F:0] + AQ_MsmSystemRxPauseFramesCounterRegister_HHD.u0.bits_0.msmSystemRxPauseFramesCounter_0 + + Default = 0x0000 + + Rx pause frame counter bits 15:0 + + Notes: + Valid pause frames received. */ + unsigned int msmSystemRxPauseFramesCounter_0 : 16; /* 1E.6054.F:0 ROS Default = 0x0000 */ + /* Rx pause frame counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx Pause Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6055.F:0 ROS MSM System Rx Pause Frames Counter 1 [F:0] + AQ_MsmSystemRxPauseFramesCounterRegister_HHD.u1.bits_1.msmSystemRxPauseFramesCounter_1 + + Default = 0x0000 + + Rx pause frame counter bits 31:16 + + Notes: + Valid pause frames received. */ + unsigned int msmSystemRxPauseFramesCounter_1 : 16; /* 1E.6055.F:0 ROS Default = 0x0000 */ + /* Rx pause frame counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxPauseFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx Too Long Errors Counter Register: 1E.6058 */ +/* MSM System Rx Too Long Errors Counter Register: 1E.6058 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx Too Long Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.6058.F:0 ROS MSM System Rx Too Long Errors Counter 0 [F:0] + AQ_MsmSystemRxTooLongErrorsCounterRegister_HHD.u0.bits_0.msmSystemRxTooLongErrorsCounter_0 + + Default = 0x0000 + + Too-long errors counter bits 15:0 + + Notes: + Frame received exceeded the maximum length programmed with register FRM_LGTH. */ + unsigned int msmSystemRxTooLongErrorsCounter_0 : 16; /* 1E.6058.F:0 ROS Default = 0x0000 */ + /* Too-long errors counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx Too Long Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.6059.F:0 ROS MSM System Rx Too Long Errors Counter 1 [F:0] + AQ_MsmSystemRxTooLongErrorsCounterRegister_HHD.u1.bits_1.msmSystemRxTooLongErrorsCounter_1 + + Default = 0x0000 + + Too-long errors counter bits 31:16 + + Notes: + Frame received exceeded the maximum length programmed with register FRM_LGTH. */ + unsigned int msmSystemRxTooLongErrorsCounter_1 : 16; /* 1E.6059.F:0 ROS Default = 0x0000 */ + /* Too-long errors counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxTooLongErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx In Range Length Errors Counter Register: 1E.605C */ +/* MSM System Rx In Range Length Errors Counter Register: 1E.605C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx In Range Length Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.605C.F:0 ROS MSM System Rx In Range Length Errors Counter 0 [F:0] + AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_HHD.u0.bits_0.msmSystemRxInRangeLengthErrorsCounter_0 + + Default = 0x0000 + + In-range-length errors counter bits 15:0 + + Notes: + A count of frames with a length/type field value between 46 (VLAN: 42) and less than 0x0600, that does not match the number of payload data octets received. Should count also if length/type field is less than 46 (VLAN: 42) and the frame is longer than 64 bytes. */ + unsigned int msmSystemRxInRangeLengthErrorsCounter_0 : 16; /* 1E.605C.F:0 ROS Default = 0x0000 */ + /* In-range-length errors counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx In Range Length Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.605D.F:0 ROS MSM System Rx In Range Length Errors Counter 1 [F:0] + AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_HHD.u1.bits_1.msmSystemRxInRangeLengthErrorsCounter_1 + + Default = 0x0000 + + In-range-length errors counter bits 31:16 + + Notes: + A count of frames with a length/type field value between 46 (VLAN: 42) and less than 0x0600, that does not match the number of payload data octets received. Should count also if length/type field is less than 46 (VLAN: 42) and the frame is longer than 64 bytes. */ + unsigned int msmSystemRxInRangeLengthErrorsCounter_1 : 16; /* 1E.605D.F:0 ROS Default = 0x0000 */ + /* In-range-length errors counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxInRangeLengthErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Tx VLAN Frames Counter Register: 1E.6060 */ +/* MSM System Tx VLAN Frames Counter Register: 1E.6060 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Tx VLAN Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6060.F:0 ROS MSM System Tx VLAN Frames Counter 0 [F:0] + AQ_MsmSystemTxVlanFramesCounterRegister_HHD.u0.bits_0.msmSystemTxVlanFramesCounter_0 + + Default = 0x0000 + + Tx VLAN frames counter bits 15:0 + + Notes: + Valid VLAN tagged frames transmitted. */ + unsigned int msmSystemTxVlanFramesCounter_0 : 16; /* 1E.6060.F:0 ROS Default = 0x0000 */ + /* Tx VLAN frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Tx VLAN Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6061.F:0 ROS MSM System Tx VLAN Frames Counter 1 [F:0] + AQ_MsmSystemTxVlanFramesCounterRegister_HHD.u1.bits_1.msmSystemTxVlanFramesCounter_1 + + Default = 0x0000 + + Tx VLAN frames counter bits 31:16 + + Notes: + Valid VLAN tagged frames transmitted. */ + unsigned int msmSystemTxVlanFramesCounter_1 : 16; /* 1E.6061.F:0 ROS Default = 0x0000 */ + /* Tx VLAN frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemTxVlanFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx VLAN Frames Counter Register: 1E.6064 */ +/* MSM System Rx VLAN Frames Counter Register: 1E.6064 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx VLAN Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6064.F:0 ROS MSM System Rx VLAN Frames Counter 0 [F:0] + AQ_MsmSystemRxVlanFramesCounterRegister_HHD.u0.bits_0.msmSystemRxVlanFramesCounter_0 + + Default = 0x0000 + + Rx VLAN frames counter bits 15:0 + + Notes: + Valid VLAN tagged frames received. */ + unsigned int msmSystemRxVlanFramesCounter_0 : 16; /* 1E.6064.F:0 ROS Default = 0x0000 */ + /* Rx VLAN frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx VLAN Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6065.F:0 ROS MSM System Rx VLAN Frames Counter 1 [F:0] + AQ_MsmSystemRxVlanFramesCounterRegister_HHD.u1.bits_1.msmSystemRxVlanFramesCounter_1 + + Default = 0x0000 + + Rx VLAN frames counter bits 31:16 + + Notes: + Valid VLAN tagged frames received. */ + unsigned int msmSystemRxVlanFramesCounter_1 : 16; /* 1E.6065.F:0 ROS Default = 0x0000 */ + /* Rx VLAN frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxVlanFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Tx Octets Counter Register: 1E.6068 */ +/* MSM System Tx Octets Counter Register: 1E.6068 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Tx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.6068.F:0 ROS MSM System Tx Octets Counter 0 [F:0] + AQ_MsmSystemTxOctetsCounterRegister_HHD.u0.bits_0.msmSystemTxOctetsCounter_0 + + Default = 0x0000 + + Tx octets counter bits 15:0 + + Notes: + All octets transmitted except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames transmitted. */ + unsigned int msmSystemTxOctetsCounter_0 : 16; /* 1E.6068.F:0 ROS Default = 0x0000 */ + /* Tx octets counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Tx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.6069.F:0 ROS MSM System Tx Octets Counter 1 [F:0] + AQ_MsmSystemTxOctetsCounterRegister_HHD.u1.bits_1.msmSystemTxOctetsCounter_1 + + Default = 0x0000 + + Tx octets counter bits 31:16 + + Notes: + All octets transmitted except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames transmitted. */ + unsigned int msmSystemTxOctetsCounter_1 : 16; /* 1E.6069.F:0 ROS Default = 0x0000 */ + /* Tx octets counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of MSM System Tx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.606A.F:0 ROS MSM System Tx Octets Counter 2 [F:0] + AQ_MsmSystemTxOctetsCounterRegister_HHD.u2.bits_2.msmSystemTxOctetsCounter_2 + + Default = 0x0000 + + Tx octets counter bits 47:32 + + Notes: + All octets transmitted except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames transmitted. */ + unsigned int msmSystemTxOctetsCounter_2 : 16; /* 1E.606A.F:0 ROS Default = 0x0000 */ + /* Tx octets counter bits 47:32 */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of MSM System Tx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.606B.F:0 ROS MSM System Tx Octets Counter 3 [F:0] + AQ_MsmSystemTxOctetsCounterRegister_HHD.u3.bits_3.msmSystemTxOctetsCounter_3 + + Default = 0x0000 + + Tx octets counter bits 63:48 + + Notes: + All octets transmitted except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames transmitted. */ + unsigned int msmSystemTxOctetsCounter_3 : 16; /* 1E.606B.F:0 ROS Default = 0x0000 */ + /* Tx octets counter bits 63:48 */ + } bits_3; + uint16_t word_3; + } u3; +} AQ_MsmSystemTxOctetsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx Octets Counter Register: 1E.606C */ +/* MSM System Rx Octets Counter Register: 1E.606C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.606C.F:0 ROS MSM System Rx Octets Counter 0 [F:0] + AQ_MsmSystemRxOctetsCounterRegister_HHD.u0.bits_0.msmSystemRxOctetsCounter_0 + + Default = 0x0000 + + Rx octets counter bits 15:0 + + Notes: + All octets received except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames received. */ + unsigned int msmSystemRxOctetsCounter_0 : 16; /* 1E.606C.F:0 ROS Default = 0x0000 */ + /* Rx octets counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.606D.F:0 ROS MSM System Rx Octets Counter 1 [F:0] + AQ_MsmSystemRxOctetsCounterRegister_HHD.u1.bits_1.msmSystemRxOctetsCounter_1 + + Default = 0x0000 + + Rx octets counter bits 31:16 + + Notes: + All octets received except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames received. */ + unsigned int msmSystemRxOctetsCounter_1 : 16; /* 1E.606D.F:0 ROS Default = 0x0000 */ + /* Rx octets counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxOctetsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx Unicast Frames Counter Register: 1E.6070 */ +/* MSM System Rx Unicast Frames Counter Register: 1E.6070 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx Unicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6070.F:0 ROS MSM System Rx Unicast Frames Counter 0 [F:0] + AQ_MsmSystemRxUnicastFramesCounterRegister_HHD.u0.bits_0.msmSystemRxUnicastFramesCounter_0 + + Default = 0x0000 + + Rx unicast frames counter bits 15:0 + + Notes: + Incremented with each valid frame received on the receive FIFO interface and bit 0 of the destination address was '0'. */ + unsigned int msmSystemRxUnicastFramesCounter_0 : 16; /* 1E.6070.F:0 ROS Default = 0x0000 */ + /* Rx unicast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx Unicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6071.F:0 ROS MSM System Rx Unicast Frames Counter 1 [F:0] + AQ_MsmSystemRxUnicastFramesCounterRegister_HHD.u1.bits_1.msmSystemRxUnicastFramesCounter_1 + + Default = 0x0000 + + Rx unicast frames counter bits 31:16 + + Notes: + Incremented with each valid frame received on the receive FIFO interface and bit 0 of the destination address was '0'. */ + unsigned int msmSystemRxUnicastFramesCounter_1 : 16; /* 1E.6071.F:0 ROS Default = 0x0000 */ + /* Rx unicast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxUnicastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx Multicast Frames Counter Register: 1E.6074 */ +/* MSM System Rx Multicast Frames Counter Register: 1E.6074 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx Multicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6074.F:0 ROS MSM System Rx Multicast Frames Counter 0 [F:0] + AQ_MsmSystemRxMulticastFramesCounterRegister_HHD.u0.bits_0.msmSystemRxMulticastFramesCounter_0 + + Default = 0x0000 + + Rx multicast frames counter bits 15:0 + + Notes: + Incremented with each valid frame received on the receive FIFO interface and bit 0 of the destination address was '1' but not the broadcast address (all bits set '1' ). Pause frames are not counted. */ + unsigned int msmSystemRxMulticastFramesCounter_0 : 16; /* 1E.6074.F:0 ROS Default = 0x0000 */ + /* Rx multicast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx Multicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6075.F:0 ROS MSM System Rx Multicast Frames Counter 1 [F:0] + AQ_MsmSystemRxMulticastFramesCounterRegister_HHD.u1.bits_1.msmSystemRxMulticastFramesCounter_1 + + Default = 0x0000 + + Rx multicast frames counter bits 31:16 + + Notes: + Incremented with each valid frame received on the receive FIFO interface and bit 0 of the destination address was '1' but not the broadcast address (all bits set '1' ). Pause frames are not counted. */ + unsigned int msmSystemRxMulticastFramesCounter_1 : 16; /* 1E.6075.F:0 ROS Default = 0x0000 */ + /* Rx multicast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxMulticastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx Broadcast Frames Counter Register: 1E.6078 */ +/* MSM System Rx Broadcast Frames Counter Register: 1E.6078 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx Broadcast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6078.F:0 ROS MSM System Rx Broadcast Frames Counter 0 [F:0] + AQ_MsmSystemRxBroadcastFramesCounterRegister_HHD.u0.bits_0.msmSystemRxBroadcastFramesCounter_0 + + Default = 0x0000 + + Rx broadcast frames counter bits 15:0 + + Notes: + Incremented with each valid frame received on the receive FIFO interface (FIFO) and all bits of the destination address were set '1'. */ + unsigned int msmSystemRxBroadcastFramesCounter_0 : 16; /* 1E.6078.F:0 ROS Default = 0x0000 */ + /* Rx broadcast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx Broadcast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6079.F:0 ROS MSM System Rx Broadcast Frames Counter 1 [F:0] + AQ_MsmSystemRxBroadcastFramesCounterRegister_HHD.u1.bits_1.msmSystemRxBroadcastFramesCounter_1 + + Default = 0x0000 + + Rx broadcast frames counter bits 31:16 + + Notes: + Incremented with each valid frame received on the receive FIFO interface (FIFO) and all bits of the destination address were set '1'. */ + unsigned int msmSystemRxBroadcastFramesCounter_1 : 16; /* 1E.6079.F:0 ROS Default = 0x0000 */ + /* Rx broadcast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxBroadcastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Tx Errors Counter Register: 1E.607C */ +/* MSM System Tx Errors Counter Register: 1E.607C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Tx Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.607C.F:0 ROS MSM System Tx Errors Counter 0 [F:0] + AQ_MsmSystemTxErrorsCounterRegister_HHD.u0.bits_0.msmSystemTxErrorsCounter_0 + + Default = 0x0000 + + Rx errors counter bits 15:0 + + Notes: + Number of frames transmitted with error: + - FIFO Overflow Errors + - FIFO Underflow Errors */ + unsigned int msmSystemTxErrorsCounter_0 : 16; /* 1E.607C.F:0 ROS Default = 0x0000 */ + /* Rx errors counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Tx Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.607D.F:0 ROS MSM System Tx Errors Counter 1 [F:0] + AQ_MsmSystemTxErrorsCounterRegister_HHD.u1.bits_1.msmSystemTxErrorsCounter_1 + + Default = 0x0000 + + Tx errors counter bits 31:16 + + Notes: + Number of frames transmitted with error: + - FIFO Overflow Errors + - FIFO Underflow Errors */ + unsigned int msmSystemTxErrorsCounter_1 : 16; /* 1E.607D.F:0 ROS Default = 0x0000 */ + /* Tx errors counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemTxErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Tx Unicast Frames Counter Register: 1E.6084 */ +/* MSM System Tx Unicast Frames Counter Register: 1E.6084 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Tx Unicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6084.F:0 ROS MSM System Tx Unicast Frames Counter 0 [F:0] + AQ_MsmSystemTxUnicastFramesCounterRegister_HHD.u0.bits_0.msmSystemTxUnicastFramesCounter_0 + + Default = 0x0000 + + Tx unicast frames counter bits 15:0 + + Notes: + Incremented with each frame written to the FIFO interface and bit 0 of the destination address set to '0'. */ + unsigned int msmSystemTxUnicastFramesCounter_0 : 16; /* 1E.6084.F:0 ROS Default = 0x0000 */ + /* Tx unicast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Tx Unicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6085.F:0 ROS MSM System Tx Unicast Frames Counter 1 [F:0] + AQ_MsmSystemTxUnicastFramesCounterRegister_HHD.u1.bits_1.msmSystemTxUnicastFramesCounter_1 + + Default = 0x0000 + + Tx unicast frames counter bits 31:16 + + Notes: + Incremented with each frame written to the FIFO interface and bit 0 of the destination address set to '0'. */ + unsigned int msmSystemTxUnicastFramesCounter_1 : 16; /* 1E.6085.F:0 ROS Default = 0x0000 */ + /* Tx unicast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemTxUnicastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Tx Multicast Frames Counter Register: 1E.6088 */ +/* MSM System Tx Multicast Frames Counter Register: 1E.6088 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Tx Multicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6088.F:0 ROS MSM System Tx Multicast Frames Counter 0 [F:0] + AQ_MsmSystemTxMulticastFramesCounterRegister_HHD.u0.bits_0.msmSystemTxMulticastFramesCounter_0 + + Default = 0x0000 + + Tx multicast frames counter bits 15:0 + + Notes: + Incremented with each frame written to the FIFO interface and bit 0 of the destination address set to '1' but not the broadcast address (all bits '1'). */ + unsigned int msmSystemTxMulticastFramesCounter_0 : 16; /* 1E.6088.F:0 ROS Default = 0x0000 */ + /* Tx multicast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Tx Multicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.6089.F:0 ROS MSM System Tx Multicast Frames Counter 1 [F:0] + AQ_MsmSystemTxMulticastFramesCounterRegister_HHD.u1.bits_1.msmSystemTxMulticastFramesCounter_1 + + Default = 0x0000 + + Tx multicast frames counter bits 31:16 + + Notes: + Incremented with each frame written to the FIFO interface and bit 0 of the destination address set to '1' but not the broadcast address (all bits '1'). */ + unsigned int msmSystemTxMulticastFramesCounter_1 : 16; /* 1E.6089.F:0 ROS Default = 0x0000 */ + /* Tx multicast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemTxMulticastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Tx Broadcast Frames Counter Register: 1E.608C */ +/* MSM System Tx Broadcast Frames Counter Register: 1E.608C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Tx Broadcast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.608C.F:0 ROS MSM System Tx Broadcast Frames Counter 0 [F:0] + AQ_MsmSystemTxBroadcastFramesCounterRegister_HHD.u0.bits_0.msmSystemTxBroadcastFramesCounter_0 + + Default = 0x0000 + + Tx broadcast frames counter bits 15:0 + + Notes: + Incremented with each frame written to the FIFO interface and all bits of the destination address set to '1'. */ + unsigned int msmSystemTxBroadcastFramesCounter_0 : 16; /* 1E.608C.F:0 ROS Default = 0x0000 */ + /* Tx broadcast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Tx Broadcast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.608D.F:0 ROS MSM System Tx Broadcast Frames Counter 1 [F:0] + AQ_MsmSystemTxBroadcastFramesCounterRegister_HHD.u1.bits_1.msmSystemTxBroadcastFramesCounter_1 + + Default = 0x0000 + + Tx broadcast frames counter bits 31:16 + + Notes: + Incremented with each frame written to the FIFO interface and all bits of the destination address set to '1'. */ + unsigned int msmSystemTxBroadcastFramesCounter_1 : 16; /* 1E.608D.F:0 ROS Default = 0x0000 */ + /* Tx broadcast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemTxBroadcastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM System Rx Errors Counter Register: 1E.60C8 */ +/* MSM System Rx Errors Counter Register: 1E.60C8 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM System Rx Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.60C8.F:0 ROS MSM System Rx Errors Counter 0 [F:0] + AQ_MsmSystemRxErrorsCounterRegister_HHD.u0.bits_0.msmSystemRxErrorsCounter_0 + + Default = 0x0000 + + Rx errors counter bits 15:0 + + Notes: + Number of frames received with error: + - FIFO Overflow Errors + - CRC Errors + - Payload Length Errors + - Jabber and Oversized Errors + - Alignment Errors + - The dedicated Error Code (0xfe, not a code error) was received */ + unsigned int msmSystemRxErrorsCounter_0 : 16; /* 1E.60C8.F:0 ROS Default = 0x0000 */ + /* Rx errors counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM System Rx Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.60C9.F:0 ROS MSM System Rx Errors Counter 1 [F:0] + AQ_MsmSystemRxErrorsCounterRegister_HHD.u1.bits_1.msmSystemRxErrorsCounter_1 + + Default = 0x0000 + + Rx errors counter bits 31:16 + + Notes: + Number of frames received with error: + - FIFO Overflow Errors + - CRC Errors + - Payload Length Errors + - Jabber and Oversized Errors + - Alignment Errors + - The dedicated Error Code (0xfe, not a code error) was received */ + unsigned int msmSystemRxErrorsCounter_1 : 16; /* 1E.60C9.F:0 ROS Default = 0x0000 */ + /* Rx errors counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmSystemRxErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress VLAN TPID 0 Register: 1E.8006 */ +/* MSS Ingress VLAN TPID 0 Register: 1E.8006 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress VLAN TPID 0 Register */ + union + { + struct + { + /*! \brief 1E.8006.F:0 R/W MSS Ingress VLAN STag [F:0] + AQ_MssIngressVlanTpid_0Register_HHD.u0.bits_0.mssIngressVlanStag + + Default = 0x0000 + + STag TPID + + + Notes: + Service Tag Protocol Identifier (TPID) values to identify a VLAN tag. The " See SEC Egress VLAN CP Tag Parse STag " bit must be set to 1 for the incoming packet's TPID to be parsed. */ + unsigned int mssIngressVlanStag : 16; /* 1E.8006.F:0 R/W Default = 0x0000 */ + /* STag TPID + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress VLAN TPID 0 Register */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressVlanTpid_0Register_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress VLAN TPID 1 Register: 1E.8008 */ +/* MSS Ingress VLAN TPID 1 Register: 1E.8008 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress VLAN TPID 1 Register */ + union + { + struct + { + /*! \brief 1E.8008.F:0 R/W MSS Ingress VLAN QTag [F:0] + AQ_MssIngressVlanTpid_1Register_HHD.u0.bits_0.mssIngressVlanQtag + + Default = 0x0000 + + QTag TPID + + + Notes: + Customer Tag Protocol Identifier (TPID) values to identify a VLAN tag. The " See SEC Egress VLAN CP Tag Parse QTag " bit must be set to 1 for the incoming packet's TPID to be parsed. */ + unsigned int mssIngressVlanQtag : 16; /* 1E.8008.F:0 R/W Default = 0x0000 */ + /* QTag TPID + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress VLAN TPID 1 Register */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressVlanTpid_1Register_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress VLAN Control Register: 1E.800A */ +/* MSS Ingress VLAN Control Register: 1E.800A */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress VLAN Control Register */ + union + { + struct + { + /*! \brief 1E.800A.F:0 R/W MSS Ingress VLAN UP Map Table LSW [F:0] + AQ_MssIngressVlanControlRegister_HHD.u0.bits_0.mssIngressVlanUpMapTableLSW + + Default = 0x0000 + + Map table bits 15:0 + + + Notes: + If there is a customer TPID Tag match and no service TPID Tag match or the service TPID Tag match is disabled, the outer TAG's PCP is used to index into this map table to generate the packets user priority. + 2:0 : UP value for customer Tag PCP 0x0 + 5:3: UP value for customer Tag PCP 0x0 + 8:6 : UP value for customer Tag PCP 0x0 + 11:9 : UP value for customer Tag PCP 0x0 + 14:12 : UP value for customer Tag PCP 0x0 + 17:15 : UP value for customer Tag PCP 0x0 */ + unsigned int mssIngressVlanUpMapTableLSW : 16; /* 1E.800A.F:0 R/W Default = 0x0000 */ + /* Map table bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress VLAN Control Register */ + union + { + struct + { + /*! \brief 1E.800B.F R/W MSS Ingress VLAN QTag Parse Enable + AQ_MssIngressVlanControlRegister_HHD.u1.bits_1.mssIngressVlanQtagParseEnable + + Default = 0x0 + + 1 = Enable VLAN QTag parsing + + + Notes: + Enable controlled port VLAN customer Tag parsing. When this bit is set to 1, the incoming packet's outer TPID will be compared with the configured " See MSS Ingress VLAN QTag [F:0] " for matching. If the " See SEC Egress VLAN CP Tag Parse QinQ " bit is set to1, this will also be used to compare the incoming packet's inner TPID. */ + unsigned int mssIngressVlanQtagParseEnable : 1; /* 1E.800B.F R/W Default = 0x0 */ + /* 1 = Enable VLAN QTag parsing + */ + /*! \brief 1E.800B.E R/W MSS Ingress VLAN STag Parse Enable + AQ_MssIngressVlanControlRegister_HHD.u1.bits_1.mssIngressVlanStagParseEnable + + Default = 0x0 + + 1 = Enable VLAN STag parsing + + + Notes: + Enable controlled port VLAN service Tag parsing. When this bit is set to 1, the incoming packets outer TPID will be compared with the configured " See MSS Ingress VLAN Stag [F:0] " for matching. If the " See SEC Egress VLAN CP Tag Parse QinQ " bit is set to1, this will also be used to compare the incoming packet's inner TPID. */ + unsigned int mssIngressVlanStagParseEnable : 1; /* 1E.800B.E R/W Default = 0x0 */ + /* 1 = Enable VLAN STag parsing + */ + /*! \brief 1E.800B.D R/W MSS Ingress VLAN QinQ Parse Enable + AQ_MssIngressVlanControlRegister_HHD.u1.bits_1.mssIngressVlanQinqParseEnable + + Default = 0x0 + + VLAN CP Tag Parse QinQ + + + Notes: + Enable controlled port VLAN QinQ Tag parsing. When this bit is set to 1 both the outer and inner VLAN Tags will be parsed. */ + unsigned int mssIngressVlanQinqParseEnable : 1; /* 1E.800B.D R/W Default = 0x0 */ + /* VLAN CP Tag Parse QinQ + */ + /*! \brief 1E.800B.C R/W MSS Ingress VLAN QTag UP Parse Enable + AQ_MssIngressVlanControlRegister_HHD.u1.bits_1.mssIngressVlanQtagUpParseEnable + + Default = 0x0 + + VLAN CP Tag QTag UP enable + + + Notes: + Enable controlled port customer VLAN customer Tag user priority field parsing. */ + unsigned int mssIngressVlanQtagUpParseEnable : 1; /* 1E.800B.C R/W Default = 0x0 */ + /* VLAN CP Tag QTag UP enable + */ + /*! \brief 1E.800B.B R/W MSS Ingress VLAN STag UP Parse Enable + AQ_MssIngressVlanControlRegister_HHD.u1.bits_1.mssIngressVlanStagUpParseEnable + + Default = 0x0 + + VLAN CP Tag STag UP enable + + + Notes: + Enable controlled port service VLAN service Tag user priority field parsing. */ + unsigned int mssIngressVlanStagUpParseEnable : 1; /* 1E.800B.B R/W Default = 0x0 */ + /* VLAN CP Tag STag UP enable + */ + /*! \brief 1E.800B.A:8 R/W MSS Ingress VLAN UP Default [2:0] + AQ_MssIngressVlanControlRegister_HHD.u1.bits_1.mssIngressVlanUpDefault + + Default = 0x0 + + UP default + + + Notes: + User priority default */ + unsigned int mssIngressVlanUpDefault : 3; /* 1E.800B.A:8 R/W Default = 0x0 */ + /* UP default + */ + /*! \brief 1E.800B.7:0 R/W MSS Ingress VLAN UP Map Table MSW [17:10] + AQ_MssIngressVlanControlRegister_HHD.u1.bits_1.mssIngressVlanUpMapTableMSW + + Default = 0x00 + + UP Map table bits 23:16 + + + Notes: + If there is a customer TPID Tag match and no service TPID Tag match or the service TPID Tag match is disabled, the outer TAG's PCP is used to index into this map table to generate the packets user priority. + 2:0 : UP value for customer Tag PCP 0x0 + 5:3: UP value for customer Tag PCP 0x0 + 8:6 : UP value for customer Tag PCP 0x0 + 11:9 : UP value for customer Tag PCP 0x0 + 14:12 : UP value for customer Tag PCP 0x0 + 17:15 : UP value for customer Tag PCP 0x0 + 20:18 : UP value for customer Tag PCP 0x0 + 23:21 : UP value for customer Tag PCP 0x0 */ + unsigned int mssIngressVlanUpMapTableMSW : 8; /* 1E.800B.7:0 R/W Default = 0x00 */ + /* UP Map table bits 23:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressVlanControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress MTU Size Control Register: 1E.800C */ +/* MSS Ingress MTU Size Control Register: 1E.800C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress MTU Size Control Register */ + union + { + struct + { + /*! \brief 1E.800C.F:0 R/W MSS Ingress Controlled Packet MTU Size [F:0] + AQ_MssIngressMtuSizeControlRegister_HHD.u0.bits_0.mssIngressControlledPacketMtuSize + + Default = 0x05DC + + Maximum transmission unit for controlled packet + + + Notes: + Maximum transmission unit of controlled packet */ + unsigned int mssIngressControlledPacketMtuSize : 16; /* 1E.800C.F:0 R/W Default = 0x05DC */ + /* Maximum transmission unit for controlled packet + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress MTU Size Control Register */ + union + { + struct + { + /*! \brief 1E.800D.F:0 R/W MSS Ingress Uncontrolled Packet MTU Size [F:0] + AQ_MssIngressMtuSizeControlRegister_HHD.u1.bits_1.mssIngressUncontrolledPacketMtuSize + + Default = 0x05DC + + Maximum transmission unit for uncontrolled packet + + + Notes: + Maximum transmission unit of uncontrolled packet */ + unsigned int mssIngressUncontrolledPacketMtuSize : 16; /* 1E.800D.F:0 R/W Default = 0x05DC */ + /* Maximum transmission unit for uncontrolled packet + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressMtuSizeControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress Control Register: 1E.800E */ +/* MSS Ingress Control Register: 1E.800E */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress Control Register */ + union + { + struct + { + unsigned int reserved0 : 2; + /*! \brief 1E.800E.D R/W MSS Ingress ICV LSB 8 Bytes Enable + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressIcvLsb_8BytesEnable + + Default = 0x0 + + 1 = Use LSB + 0 = Use MSB + + + + Notes: + This bit selects MSB or LSB 8 bytes selection in the case where the ICV is 8 bytes. + 0 = MSB is used. */ + unsigned int mssIngressIcvLsb_8BytesEnable : 1; /* 1E.800E.D R/W Default = 0x0 */ + /* 1 = Use LSB + 0 = Use MSB + + */ + /*! \brief 1E.800E.C:B R/W MSS Ingress Global Validate Frames [1:0] + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressGlobalValidateFrames + + Default = 0x0 + + Default validate frames configuration + + + Notes: + If the SC is invalid or if an IGPRC miss packet condition occurs, this default will be used for the validate frames configuration instead of the validate frame entry in the Ingress SC Table (IGSCT). */ + unsigned int mssIngressGlobalValidateFrames : 2; /* 1E.800E.C:B R/W Default = 0x0 */ + /* Default validate frames configuration + */ + /*! \brief 1E.800E.A R/W MSS Ingress Remove SECTag + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressRemoveSectag + + Default = 0x0 + + 1 = Enable removal of SECTag + + + Notes: + If this bit is set and either of the following two conditions occurs, the SECTag will be removed. + Controlled packet and either the SA or SC is invalid. + IGPRC miss. */ + unsigned int mssIngressRemoveSectag : 1; /* 1E.800E.A R/W Default = 0x0 */ + /* 1 = Enable removal of SECTag + */ + /*! \brief 1E.800E.9 R/W MSS Ingress High Priority + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressHighPriority + + Default = 0x0 + + 1 = MIB counter clear on read enable + + + Notes: + If this bit is set to 1, read is given high priority and the MIB count value becomes 0 after read. */ + unsigned int mssIngressHighPriority : 1; /* 1E.800E.9 R/W Default = 0x0 */ + /* 1 = MIB counter clear on read enable + */ + /*! \brief 1E.800E.8 R/W MSS Ingress Clear Count + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressClearCount + + Default = 0x0 + + 1 = Clear all MIB counters + + + Notes: + If this bit is set to 1, all MIB counters will be cleared. */ + unsigned int mssIngressClearCount : 1; /* 1E.800E.8 R/W Default = 0x0 */ + /* 1 = Clear all MIB counters + */ + /*! \brief 1E.800E.7 R/W MSS Ingress Clear Global Time + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressClearGlobalTime + + Default = 0x0 + + 1 = Clear global time + + + Notes: + Clear global time */ + unsigned int mssIngressClearGlobalTime : 1; /* 1E.800E.7 R/W Default = 0x0 */ + /* 1 = Clear global time + */ + /*! \brief 1E.800E.6 R/W MSS Ingress Check ICV + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressCheckIcv + + Default = 0x0 + + Unused + + + Notes: + Unused */ + unsigned int mssIngressCheckIcv : 1; /* 1E.800E.6 R/W Default = 0x0 */ + /* Unused + */ + /*! \brief 1E.800E.5 R/W MSS Ingress Drop IGPRC Miss + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressDropIgprcMiss + + Default = 0x0 + + 1 = Drop IGPRC miss packets + + + Notes: + Decides whether Ingress Pre-Security Classification (IGPRC) LUT miss packets are to be dropped */ + unsigned int mssIngressDropIgprcMiss : 1; /* 1E.800E.5 R/W Default = 0x0 */ + /* 1 = Drop IGPRC miss packets + */ + /*! \brief 1E.800E.4 R/W MSS Ingress Drop Kay Packet + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressDropKayPacket + + Default = 0x0 + + 1 = Drop KaY packets + + + Notes: + Decides whether KaY packets have to be dropped */ + unsigned int mssIngressDropKayPacket : 1; /* 1E.800E.4 R/W Default = 0x0 */ + /* 1 = Drop KaY packets + */ + /*! \brief 1E.800E.3 R/W MSS Ingress Mask Short Length Error + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressMaskShortLengthError + + Default = 0x0 + + Unused + + + Notes: + Unused */ + unsigned int mssIngressMaskShortLengthError : 1; /* 1E.800E.3 R/W Default = 0x0 */ + /* Unused + */ + /*! \brief 1E.800E.2 R/W MSS Ingress Create SCI + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressCreateSci + + Default = 0x0 + + 0 = SCI from IGPRC LUT + + + Notes: + If the SCI is not in the packet and this bit is set to 0, the SCI will be taken from the IGPRC LUT. */ + unsigned int mssIngressCreateSci : 1; /* 1E.800E.2 R/W Default = 0x0 */ + /* 0 = SCI from IGPRC LUT + */ + /*! \brief 1E.800E.1 R/W MSS Ingress Operation Point To Point + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressOperationPointToPoint + + Default = 0x0 + + 1 = Enable the SCI for authorization default + + + Notes: + The default SCI for authorization is configured in See MSS Ingress SCI Default [F:0] See MSS Ingress SCI Default [1F:10] , See MSS Ingress SCI Default [2F:20] , and See MSS Ingress SCI Default [3F:30] . */ + unsigned int mssIngressOperationPointToPoint : 1; /* 1E.800E.1 R/W Default = 0x0 */ + /* 1 = Enable the SCI for authorization default + */ + /*! \brief 1E.800E.0 R/W MSS Ingress Soft Reset + AQ_MssIngressControlRegister_HHD.u0.bits_0.mssIngressSoftReset + + Default = 0x0 + + 1 = Soft reset + + + Notes: + S/W reset */ + unsigned int mssIngressSoftReset : 1; /* 1E.800E.0 R/W Default = 0x0 */ + /* 1 = Soft reset + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress Control Register */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress SA Control Register: 1E.8010 */ +/* MSS Ingress SA Control Register: 1E.8010 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress SA Control Register */ + union + { + struct + { + /*! \brief 1E.8010.F:0 R/W MSS Ingress SA Threshold LSW [F:0] + AQ_MssIngressSaControlRegister_HHD.u0.bits_0.mssIngressSaThresholdLSW + + Default = 0x0000 + + SA threshold bits 15:0 + + + Notes: + Ingress PN threshold to generate SA threshold interrupt. */ + unsigned int mssIngressSaThresholdLSW : 16; /* 1E.8010.F:0 R/W Default = 0x0000 */ + /* SA threshold bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress SA Control Register */ + union + { + struct + { + /*! \brief 1E.8011.F:0 R/W MSS Ingress SA Threshold MSW [1F:10] + AQ_MssIngressSaControlRegister_HHD.u1.bits_1.mssIngressSaThresholdMSW + + Default = 0x0000 + + SA threshold bits 31:16 + + + Notes: + Ingress PN threshold to generate SA threshold interrupt. */ + unsigned int mssIngressSaThresholdMSW : 16; /* 1E.8011.F:0 R/W Default = 0x0000 */ + /* SA threshold bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressSaControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress Interrupt Status Register: 1E.802E */ +/* MSS Ingress Interrupt Status Register: 1E.802E */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress Interrupt Status Register */ + union + { + struct + { + unsigned int reserved0 : 7; + /*! \brief 1E.802E.8 COW MSS Ingress IGPOC Miss Interrupt + AQ_MssIngressInterruptStatusRegister_HHD.u0.bits_0.mssIngressIgpocMissInterrupt + + Default = 0x0 + + 1 = Interrupt + + */ + unsigned int mssIngressIgpocMissInterrupt : 1; /* 1E.802E.8 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.802E.7 COW MSS Ingress TCI E/C Error Interrupt + AQ_MssIngressInterruptStatusRegister_HHD.u0.bits_0.mssIngressTciE_cErrorInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. This error occurs when the TCI E bit is 1 and the TCI C bit is 0. The packet is not dropped, uncontrolled, or untagged. */ + unsigned int mssIngressTciE_cErrorInterrupt : 1; /* 1E.802E.7 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.802E.6 COW MSS Ingress ECC Error Interrupt + AQ_MssIngressInterruptStatusRegister_HHD.u0.bits_0.mssIngressEccErrorInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. */ + unsigned int mssIngressEccErrorInterrupt : 1; /* 1E.802E.6 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.802E.5 COW MSS Ingress MIB Saturation Interrupt + AQ_MssIngressInterruptStatusRegister_HHD.u0.bits_0.mssIngressMibSaturationInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. This bit is set when the MIB counters reaches all ones saturation. */ + unsigned int mssIngressMibSaturationInterrupt : 1; /* 1E.802E.5 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.802E.4 COW MSS Ingress Replay Error Interrupt + AQ_MssIngressInterruptStatusRegister_HHD.u0.bits_0.mssIngressReplayErrorInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. */ + unsigned int mssIngressReplayErrorInterrupt : 1; /* 1E.802E.4 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.802E.3 COW MSS Ingress ICV Error Interrupt + AQ_MssIngressInterruptStatusRegister_HHD.u0.bits_0.mssIngressIcvErrorInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. */ + unsigned int mssIngressIcvErrorInterrupt : 1; /* 1E.802E.3 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.802E.2 COW MSS Ingress SA Threshold Expired Interrupt + AQ_MssIngressInterruptStatusRegister_HHD.u0.bits_0.mssIngressSaThresholdExpiredInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. This bit is set when the SA PN reaches the See SEC Egress PN Threshold [F:0] and See SEC Egress PN Threshold [1F:10] . */ + unsigned int mssIngressSaThresholdExpiredInterrupt : 1; /* 1E.802E.2 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.802E.1 COW MSS Ingress SA Expired Interrupt + AQ_MssIngressInterruptStatusRegister_HHD.u0.bits_0.mssIngressSaExpiredInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. This bit is set when the SA PN reaches all ones saturation. */ + unsigned int mssIngressSaExpiredInterrupt : 1; /* 1E.802E.1 COW Default = 0x0 */ + /* 1 = Interrupt + */ + /*! \brief 1E.802E.0 COW MSS Master Ingress Interrupt + AQ_MssIngressInterruptStatusRegister_HHD.u0.bits_0.mssMasterIngressInterrupt + + Default = 0x0 + + 1 = Interrupt + + + Notes: + Write to 1 to clear. This bit is set when any one of the above interrupt and the corresponding interrupt enable are both set. The interrupt enable for this bit must also be set for this bit to be set. */ + unsigned int mssMasterIngressInterrupt : 1; /* 1E.802E.0 COW Default = 0x0 */ + /* 1 = Interrupt + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress Interrupt Status Register */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressInterruptStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress Interrupt Mask Register: 1E.8030 */ +/* MSS Ingress Interrupt Mask Register: 1E.8030 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress Interrupt Mask Register */ + union + { + struct + { + unsigned int reserved0 : 7; + /*! \brief 1E.8030.8 R/W MSS Ingress IGPOC Miss Interrupt Enable + AQ_MssIngressInterruptMaskRegister_HHD.u0.bits_0.mssIngressIgpocMissInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + */ + unsigned int mssIngressIgpocMissInterruptEnable : 1; /* 1E.8030.8 R/W Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.8030.7 R/W MSS Ingress TCI E/C Error Interrupt Enable + AQ_MssIngressInterruptMaskRegister_HHD.u0.bits_0.mssIngressTciE_cErrorInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + */ + unsigned int mssIngressTciE_cErrorInterruptEnable : 1; /* 1E.8030.7 R/W Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.8030.6 R/W MSS Ingress ECC Error Interrupt Enable + AQ_MssIngressInterruptMaskRegister_HHD.u0.bits_0.mssIngressEccErrorInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + */ + unsigned int mssIngressEccErrorInterruptEnable : 1; /* 1E.8030.6 R/W Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.8030.5 R/W MSS Ingress MIB Saturation Interrupt Enable + AQ_MssIngressInterruptMaskRegister_HHD.u0.bits_0.mssIngressMibSaturationInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + */ + unsigned int mssIngressMibSaturationInterruptEnable : 1; /* 1E.8030.5 R/W Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.8030.4 R/W MSS Ingress Replay Error Interrupt Enable + AQ_MssIngressInterruptMaskRegister_HHD.u0.bits_0.mssIngressReplayErrorInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + */ + unsigned int mssIngressReplayErrorInterruptEnable : 1; /* 1E.8030.4 R/W Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.8030.3 R/W MSS Ingress ICV Error Interrupt Enable + AQ_MssIngressInterruptMaskRegister_HHD.u0.bits_0.mssIngressIcvErrorInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + */ + unsigned int mssIngressIcvErrorInterruptEnable : 1; /* 1E.8030.3 R/W Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.8030.2 R/W MSS Ingress SA Threshold Expired Interrupt Enable + AQ_MssIngressInterruptMaskRegister_HHD.u0.bits_0.mssIngressSaThresholdExpiredInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + */ + unsigned int mssIngressSaThresholdExpiredInterruptEnable : 1; /* 1E.8030.2 R/W Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.8030.1 R/W MSS Ingress SA Expired Interrupt Enable + AQ_MssIngressInterruptMaskRegister_HHD.u0.bits_0.mssIngressSaExpiredInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + */ + unsigned int mssIngressSaExpiredInterruptEnable : 1; /* 1E.8030.1 R/W Default = 0x0 */ + /* 1 = Interrupt enabled + */ + /*! \brief 1E.8030.0 R/W MSS Ingress Master Interrupt Enable + AQ_MssIngressInterruptMaskRegister_HHD.u0.bits_0.mssIngressMasterInterruptEnable + + Default = 0x0 + + 1 = Interrupt enabled + + */ + unsigned int mssIngressMasterInterruptEnable : 1; /* 1E.8030.0 R/W Default = 0x0 */ + /* 1 = Interrupt enabled + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress Interrupt Mask Register */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressInterruptMaskRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress SA ICV Error Status Register: 1E.8032 */ +/* MSS Ingress SA ICV Error Status Register: 1E.8032 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress SA ICV Error Status Register */ + union + { + struct + { + /*! \brief 1E.8032.F:0 COW MSS Ingress SA ICV Error LSW [F:0] + AQ_MssIngressSaIcvErrorStatusRegister_HHD.u0.bits_0.mssIngressSaIcvErrorLSW + + Default = 0x0000 + + SA ICV error bits 15:0 + + + Notes: + When set, these bits identify the SA that has an ICV error. Write these bits to 1 to clear. */ + unsigned int mssIngressSaIcvErrorLSW : 16; /* 1E.8032.F:0 COW Default = 0x0000 */ + /* SA ICV error bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress SA ICV Error Status Register */ + union + { + struct + { + /*! \brief 1E.8033.F:0 COW MSS Ingress SA ICV Error MSW [1F:10] + AQ_MssIngressSaIcvErrorStatusRegister_HHD.u1.bits_1.mssIngressSaIcvErrorMSW + + Default = 0x0000 + + SA ICV error bits 31:16 + + + Notes: + When set, these bits identify the SA that has an ICV error. Write these bits to 1 to clear. */ + unsigned int mssIngressSaIcvErrorMSW : 16; /* 1E.8033.F:0 COW Default = 0x0000 */ + /* SA ICV error bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressSaIcvErrorStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress SA Replay Error Status Register: 1E.8034 */ +/* MSS Ingress SA Replay Error Status Register: 1E.8034 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress SA Replay Error Status Register */ + union + { + struct + { + /*! \brief 1E.8034.F:0 COW MSS Ingress SA Replay Error LSW [F:0] + AQ_MssIngressSaReplayErrorStatusRegister_HHD.u0.bits_0.mssIngressSaReplayErrorLSW + + Default = 0x0000 + + SA replay error bits 15:0 + + + Notes: + When set, these bits identify the SA that has a replay error. Write these bits to 1 to clear. */ + unsigned int mssIngressSaReplayErrorLSW : 16; /* 1E.8034.F:0 COW Default = 0x0000 */ + /* SA replay error bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress SA Replay Error Status Register */ + union + { + struct + { + /*! \brief 1E.8035.F:0 COW MSS Ingress SA Replay Error MSW [1F:10] + AQ_MssIngressSaReplayErrorStatusRegister_HHD.u1.bits_1.mssIngressSaReplayErrorMSW + + Default = 0x0000 + + SA replay error bits 31:16 + + + Notes: + When set, these bits identify the SA that has a replay error. Write these bits to 1 to clear. */ + unsigned int mssIngressSaReplayErrorMSW : 16; /* 1E.8035.F:0 COW Default = 0x0000 */ + /* SA replay error bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressSaReplayErrorStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress SA Expired Status Register: 1E.8036 */ +/* MSS Ingress SA Expired Status Register: 1E.8036 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress SA Expired Status Register */ + union + { + struct + { + /*! \brief 1E.8036.F:0 ROS MSS Ingress SA Expired LSW [F:0] + AQ_MssIngressSaExpiredStatusRegister_HHD.u0.bits_0.mssIngressSaExpiredLSW + + Default = 0x0000 + + SA expired bits 15:0 + + + Notes: + When set, these bits identify the SA that has expired when the SA PN reaches all-ones saturation. Write these bits to 1 to clear. */ + unsigned int mssIngressSaExpiredLSW : 16; /* 1E.8036.F:0 ROS Default = 0x0000 */ + /* SA expired bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress SA Expired Status Register */ + union + { + struct + { + /*! \brief 1E.8037.F:0 ROS MSS Ingress SA Expired MSW [1F:10] + AQ_MssIngressSaExpiredStatusRegister_HHD.u1.bits_1.mssIngressSaExpiredMSW + + Default = 0x0000 + + SA expired bits 31:16 + + + Notes: + When set, these bits identify the SA that has expired when the SA PN reaches all-ones saturation. Write these bits to 1 to clear. */ + unsigned int mssIngressSaExpiredMSW : 16; /* 1E.8037.F:0 ROS Default = 0x0000 */ + /* SA expired bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressSaExpiredStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress SA Threshold Expired Status Register: 1E.8038 */ +/* MSS Ingress SA Threshold Expired Status Register: 1E.8038 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress SA Threshold Expired Status Register */ + union + { + struct + { + /*! \brief 1E.8038.F:0 ROS MSS Ingress SA Threshold Expired LSW [F:0] + AQ_MssIngressSaThresholdExpiredStatusRegister_HHD.u0.bits_0.mssIngressSaThresholdExpiredLSW + + Default = 0x0000 + + SA threshold expired bits 15:0 + + + Notes: + When set, these bits identify the SA that has expired when the SA PN has reached the configured threshold See SEC Egress PN Threshold [F:0] and See SEC Egress PN Threshold [1F:10] . Write these bits to 1 to clear. */ + unsigned int mssIngressSaThresholdExpiredLSW : 16; /* 1E.8038.F:0 ROS Default = 0x0000 */ + /* SA threshold expired bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress SA Threshold Expired Status Register */ + union + { + struct + { + /*! \brief 1E.8039.F:0 ROS MSS Ingress SA Threshold Expired MSW [1F:10] + AQ_MssIngressSaThresholdExpiredStatusRegister_HHD.u1.bits_1.mssIngressSaThresholdExpiredMSW + + Default = 0x0000 + + SA threshold expired bits 31:16 + + + Notes: + When set, these bits identify the SA that has expired when the SA PN has reached the configured threshold See SEC Egress PN Threshold [F:0] and See SEC Egress PN Threshold [1F:10] . Write these bits to 1 to clear. */ + unsigned int mssIngressSaThresholdExpiredMSW : 16; /* 1E.8039.F:0 ROS Default = 0x0000 */ + /* SA threshold expired bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressSaThresholdExpiredStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress ECC Interrupt Status Register: 1E.803A */ +/* MSS Ingress ECC Interrupt Status Register: 1E.803A */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress ECC Interrupt Status Register */ + union + { + struct + { + /*! \brief 1E.803A.F:0 R/W MSS Ingress SA ECC Error Interrupt LSW [F:0] + AQ_MssIngressEccInterruptStatusRegister_HHD.u0.bits_0.mssIngressSaEccErrorInterruptLSW + + Default = 0x0000 + + SA ECC error interrupt bits 15:0 + + + Notes: + When set to 1, indicates that an ECC error occured for the SA. */ + unsigned int mssIngressSaEccErrorInterruptLSW : 16; /* 1E.803A.F:0 R/W Default = 0x0000 */ + /* SA ECC error interrupt bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress ECC Interrupt Status Register */ + union + { + struct + { + /*! \brief 1E.803B.F:0 R/W MSS Ingress SA ECC Error Interrupt MSW [1F:10] + AQ_MssIngressEccInterruptStatusRegister_HHD.u1.bits_1.mssIngressSaEccErrorInterruptMSW + + Default = 0x0000 + + SA ECC error interrupt bits 31:16 + + + Notes: + When set to 1, indicates that an ECC error occured for the SA. */ + unsigned int mssIngressSaEccErrorInterruptMSW : 16; /* 1E.803B.F:0 R/W Default = 0x0000 */ + /* SA ECC error interrupt bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MssIngressEccInterruptStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress LUT Address Control Register: 1E.8080 */ +/* MSS Ingress LUT Address Control Register: 1E.8080 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress LUT Address Control Register */ + union + { + struct + { + /*! \brief 1E.8080.F:C R/W MSS Ingress LUT Select [3:0] + AQ_MssIngressLutAddressControlRegister_HHD.u0.bits_0.mssIngressLutSelect + + Default = 0x0 + + LUT select + + + Notes: + 0x0 : Ingress Pre-Security MAC Control FIlter (IGPRCTLF) LUT + 0x1 : Ingress Pre-Security Classification LUT (IGPRC) + 0x2 : Ingress Packet Format (IGPFMT) SAKey LUT + 0x3 : Ingress Packet Format (IGPFMT) SC/SA LUT + 0x4 : Ingress Post-Security Classification LUT (IGPOC) + 0x5 : Ingress Post-Security MAC Control Filter (IGPOCTLF) LUT + 0x6 : Ingress MIB (IGMIB) */ + unsigned int mssIngressLutSelect : 4; /* 1E.8080.F:C R/W Default = 0x0 */ + /* LUT select + */ + unsigned int reserved0 : 3; + /*! \brief 1E.8080.8:0 R/W MSS Ingress LUT Address [8:0] + AQ_MssIngressLutAddressControlRegister_HHD.u0.bits_0.mssIngressLutAddress + + Default = 0x000 + + LUT address + + */ + unsigned int mssIngressLutAddress : 9; /* 1E.8080.8:0 R/W Default = 0x000 */ + /* LUT address + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_MssIngressLutAddressControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress LUT Control Register: 1E.8081 */ +/* MSS Ingress LUT Control Register: 1E.8081 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress LUT Control Register */ + union + { + struct + { + /*! \brief 1E.8081.F R/W MSS Ingress LUT Write + AQ_MssIngressLutControlRegister_HHD.u0.bits_0.mssIngressLutWrite + + Default = 0x0 + + 1 = LUT write + + + Notes: + Setting this bit to 1, will write the LUT. This bit will automatically clear to 0. */ + unsigned int mssIngressLutWrite : 1; /* 1E.8081.F R/W Default = 0x0 */ + /* 1 = LUT write + */ + /*! \brief 1E.8081.E R/W MSS Ingress LUT Read + AQ_MssIngressLutControlRegister_HHD.u0.bits_0.mssIngressLutRead + + Default = 0x0 + + 1 = LUT read + + + Notes: + Setting this bit to 1, will read the LUT. This bit will automatically clear to 0. */ + unsigned int mssIngressLutRead : 1; /* 1E.8081.E R/W Default = 0x0 */ + /* 1 = LUT read + */ + unsigned int reserved0 : 14; + } bits_0; + uint16_t word_0; + } u0; +} AQ_MssIngressLutControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSS Ingress LUT Data Control Register: 1E.80A0 */ +/* MSS Ingress LUT Data Control Register: 1E.80A0 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80A0.F:0 R/W MSS Ingress LUT Data 0 [F:0] + AQ_MssIngressLutDataControlRegister_HHD.u0.bits_0.mssIngressLutData_0 + + Default = 0x0000 + + LUT data bits 15:0 + + */ + unsigned int mssIngressLutData_0 : 16; /* 1E.80A0.F:0 R/W Default = 0x0000 */ + /* LUT data bits 15:0 + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80A1.F:0 R/W MSS Ingress LUT Data 1 [1F:10] + AQ_MssIngressLutDataControlRegister_HHD.u1.bits_1.mssIngressLutData_1 + + Default = 0x0000 + + LUT data bits 31:16 + + */ + unsigned int mssIngressLutData_1 : 16; /* 1E.80A1.F:0 R/W Default = 0x0000 */ + /* LUT data bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80A2.F:0 R/W MSS Ingress LUT Data 2 [2F:20] + AQ_MssIngressLutDataControlRegister_HHD.u2.bits_2.mssIngressLutData_2 + + Default = 0x0000 + + LUT data bits 47:32 + + */ + unsigned int mssIngressLutData_2 : 16; /* 1E.80A2.F:0 R/W Default = 0x0000 */ + /* LUT data bits 47:32 + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80A3.F:0 R/W MSS Ingress LUT Data 3 [3F:30] + AQ_MssIngressLutDataControlRegister_HHD.u3.bits_3.mssIngressLutData_3 + + Default = 0x0000 + + LUT data bits 63:48 + + */ + unsigned int mssIngressLutData_3 : 16; /* 1E.80A3.F:0 R/W Default = 0x0000 */ + /* LUT data bits 63:48 + */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80A4.F:0 R/W MSS Ingress LUT Data 4 [4F:40] + AQ_MssIngressLutDataControlRegister_HHD.u4.bits_4.mssIngressLutData_4 + + Default = 0x0000 + + LUT data bits 79:64 + + */ + unsigned int mssIngressLutData_4 : 16; /* 1E.80A4.F:0 R/W Default = 0x0000 */ + /* LUT data bits 79:64 + */ + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80A5.F:0 R/W MSS Ingress LUT Data 5 [5F:50] + AQ_MssIngressLutDataControlRegister_HHD.u5.bits_5.mssIngressLutData_5 + + Default = 0x0000 + + LUT data bits 95:80 + + */ + unsigned int mssIngressLutData_5 : 16; /* 1E.80A5.F:0 R/W Default = 0x0000 */ + /* LUT data bits 95:80 + */ + } bits_5; + uint16_t word_5; + } u5; + /*! \brief Union for bit and word level access of word 6 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80A6.F:0 R/W MSS Ingress LUT Data 6 [6F:60] + AQ_MssIngressLutDataControlRegister_HHD.u6.bits_6.mssIngressLutData_6 + + Default = 0x0000 + + LUT data bits 111:96 + + */ + unsigned int mssIngressLutData_6 : 16; /* 1E.80A6.F:0 R/W Default = 0x0000 */ + /* LUT data bits 111:96 + */ + } bits_6; + uint16_t word_6; + } u6; + /*! \brief Union for bit and word level access of word 7 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80A7.F:0 R/W MSS Ingress LUT Data 7 [7F:70] + AQ_MssIngressLutDataControlRegister_HHD.u7.bits_7.mssIngressLutData_7 + + Default = 0x0000 + + LUT data bits 127:112 + + */ + unsigned int mssIngressLutData_7 : 16; /* 1E.80A7.F:0 R/W Default = 0x0000 */ + /* LUT data bits 127:112 + */ + } bits_7; + uint16_t word_7; + } u7; + /*! \brief Union for bit and word level access of word 8 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80A8.F:0 R/W MSS Ingress LUT Data 8 [8F:80] + AQ_MssIngressLutDataControlRegister_HHD.u8.bits_8.mssIngressLutData_8 + + Default = 0x0000 + + LUT data bits 143:128 + + */ + unsigned int mssIngressLutData_8 : 16; /* 1E.80A8.F:0 R/W Default = 0x0000 */ + /* LUT data bits 143:128 + */ + } bits_8; + uint16_t word_8; + } u8; + /*! \brief Union for bit and word level access of word 9 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80A9.F:0 R/W MSS Ingress LUT Data 9 [9F:90] + AQ_MssIngressLutDataControlRegister_HHD.u9.bits_9.mssIngressLutData_9 + + Default = 0x0000 + + LUT data bits 159:144 + + */ + unsigned int mssIngressLutData_9 : 16; /* 1E.80A9.F:0 R/W Default = 0x0000 */ + /* LUT data bits 159:144 + */ + } bits_9; + uint16_t word_9; + } u9; + /*! \brief Union for bit and word level access of word 10 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80AA.F:0 R/W MSS Ingress LUT Data 10 [AF:A0] + AQ_MssIngressLutDataControlRegister_HHD.u10.bits_10.mssIngressLutData_10 + + Default = 0x0000 + + LUT data bits 175:160 + + */ + unsigned int mssIngressLutData_10 : 16; /* 1E.80AA.F:0 R/W Default = 0x0000 */ + /* LUT data bits 175:160 + */ + } bits_10; + uint16_t word_10; + } u10; + /*! \brief Union for bit and word level access of word 11 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80AB.F:0 R/W MSS Ingress LUT Data 11 [BF:B0] + AQ_MssIngressLutDataControlRegister_HHD.u11.bits_11.mssIngressLutData_11 + + Default = 0x0000 + + LUT data bits 191:176 + + */ + unsigned int mssIngressLutData_11 : 16; /* 1E.80AB.F:0 R/W Default = 0x0000 */ + /* LUT data bits 191:176 + */ + } bits_11; + uint16_t word_11; + } u11; + /*! \brief Union for bit and word level access of word 12 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80AC.F:0 R/W MSS Ingress LUT Data 12 [CF:C0] + AQ_MssIngressLutDataControlRegister_HHD.u12.bits_12.mssIngressLutData_12 + + Default = 0x0000 + + LUT data bits 207:192 + + */ + unsigned int mssIngressLutData_12 : 16; /* 1E.80AC.F:0 R/W Default = 0x0000 */ + /* LUT data bits 207:192 + */ + } bits_12; + uint16_t word_12; + } u12; + /*! \brief Union for bit and word level access of word 13 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80AD.F:0 R/W MSS Ingress LUT Data 13 [DF:D0] + AQ_MssIngressLutDataControlRegister_HHD.u13.bits_13.mssIngressLutData_13 + + Default = 0x0000 + + LUT data bits 223:208 + + */ + unsigned int mssIngressLutData_13 : 16; /* 1E.80AD.F:0 R/W Default = 0x0000 */ + /* LUT data bits 223:208 + */ + } bits_13; + uint16_t word_13; + } u13; + /*! \brief Union for bit and word level access of word 14 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80AE.F:0 R/W MSS Ingress LUT Data 14 [EF:E0] + AQ_MssIngressLutDataControlRegister_HHD.u14.bits_14.mssIngressLutData_14 + + Default = 0x0000 + + LUT data bits 239:224 + + */ + unsigned int mssIngressLutData_14 : 16; /* 1E.80AE.F:0 R/W Default = 0x0000 */ + /* LUT data bits 239:224 + */ + } bits_14; + uint16_t word_14; + } u14; + /*! \brief Union for bit and word level access of word 15 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80AF.F:0 R/W MSS Ingress LUT Data 15 [FF:F0] + AQ_MssIngressLutDataControlRegister_HHD.u15.bits_15.mssIngressLutData_15 + + Default = 0x0000 + + LUT data bits 255:240 + + */ + unsigned int mssIngressLutData_15 : 16; /* 1E.80AF.F:0 R/W Default = 0x0000 */ + /* LUT data bits 255:240 + */ + } bits_15; + uint16_t word_15; + } u15; + /*! \brief Union for bit and word level access of word 16 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80B0.F:0 R/W MSS Ingress LUT Data 16 [10F:100] + AQ_MssIngressLutDataControlRegister_HHD.u16.bits_16.mssIngressLutData_16 + + Default = 0x0000 + + LUT data bits 271:256 + + */ + unsigned int mssIngressLutData_16 : 16; /* 1E.80B0.F:0 R/W Default = 0x0000 */ + /* LUT data bits 271:256 + */ + } bits_16; + uint16_t word_16; + } u16; + /*! \brief Union for bit and word level access of word 17 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80B1.F:0 R/W MSS Ingress LUT Data 17 [11F:110] + AQ_MssIngressLutDataControlRegister_HHD.u17.bits_17.mssIngressLutData_17 + + Default = 0x0000 + + LUT data bits 287:272 + + */ + unsigned int mssIngressLutData_17 : 16; /* 1E.80B1.F:0 R/W Default = 0x0000 */ + /* LUT data bits 287:272 + */ + } bits_17; + uint16_t word_17; + } u17; + /*! \brief Union for bit and word level access of word 18 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80B2.F:0 R/W MSS Ingress LUT Data 18 [12F:120] + AQ_MssIngressLutDataControlRegister_HHD.u18.bits_18.mssIngressLutData_18 + + Default = 0x0000 + + LUT data bits 303:288 + + */ + unsigned int mssIngressLutData_18 : 16; /* 1E.80B2.F:0 R/W Default = 0x0000 */ + /* LUT data bits 303:288 + */ + } bits_18; + uint16_t word_18; + } u18; + /*! \brief Union for bit and word level access of word 19 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80B3.F:0 R/W MSS Ingress LUT Data 19 [13F:130] + AQ_MssIngressLutDataControlRegister_HHD.u19.bits_19.mssIngressLutData_19 + + Default = 0x0000 + + LUT data bits 319:304 + + */ + unsigned int mssIngressLutData_19 : 16; /* 1E.80B3.F:0 R/W Default = 0x0000 */ + /* LUT data bits 319:304 + */ + } bits_19; + uint16_t word_19; + } u19; + /*! \brief Union for bit and word level access of word 20 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80B4.F:0 R/W MSS Ingress LUT Data 20 [14F:140] + AQ_MssIngressLutDataControlRegister_HHD.u20.bits_20.mssIngressLutData_20 + + Default = 0x0000 + + LUT data bits 335:320 + + */ + unsigned int mssIngressLutData_20 : 16; /* 1E.80B4.F:0 R/W Default = 0x0000 */ + /* LUT data bits 335:320 + */ + } bits_20; + uint16_t word_20; + } u20; + /*! \brief Union for bit and word level access of word 21 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80B5.F:0 R/W MSS Ingress LUT Data 21 [15F:150] + AQ_MssIngressLutDataControlRegister_HHD.u21.bits_21.mssIngressLutData_21 + + Default = 0x0000 + + LUT data bits 351:336 + + */ + unsigned int mssIngressLutData_21 : 16; /* 1E.80B5.F:0 R/W Default = 0x0000 */ + /* LUT data bits 351:336 + */ + } bits_21; + uint16_t word_21; + } u21; + /*! \brief Union for bit and word level access of word 22 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80B6.F:0 R/W MSS Ingress LUT Data 22 [16F:160] + AQ_MssIngressLutDataControlRegister_HHD.u22.bits_22.mssIngressLutData_22 + + Default = 0x0000 + + LUT data bits 367:352 + + */ + unsigned int mssIngressLutData_22 : 16; /* 1E.80B6.F:0 R/W Default = 0x0000 */ + /* LUT data bits 367:352 + */ + } bits_22; + uint16_t word_22; + } u22; + /*! \brief Union for bit and word level access of word 23 of MSS Ingress LUT Data Control Register */ + union + { + struct + { + /*! \brief 1E.80B7.F:0 R/W MSS Ingress LUT Data 23 [17F:170] + AQ_MssIngressLutDataControlRegister_HHD.u23.bits_23.mssIngressLutData_23 + + Default = 0x0000 + + LUT data bits 383:368 + + */ + unsigned int mssIngressLutData_23 : 16; /* 1E.80B7.F:0 R/W Default = 0x0000 */ + /* LUT data bits 383:368 + */ + } bits_23; + uint16_t word_23; + } u23; +} AQ_MssIngressLutDataControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line General Control Register: 1E.9004 */ +/* MSM Line General Control Register: 1E.9004 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line General Control Register */ + union + { + struct + { + /*! \brief 1E.9004.F R/W MSM Line PHY Tx Enable + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLinePhyTxEnable + + Default = 0x0 + + 1 = Enable PHY Tx + + + Notes: + Directly controls the phy_tx_ena pin. */ + unsigned int msmLinePhyTxEnable : 1; /* 1E.9004.F R/W Default = 0x0 */ + /* 1 = Enable PHY Tx + */ + /*! \brief 1E.9004.E R/W MSM Line Rx Error Discard + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLineRxErrorDiscard + + Default = 0x0 + + 1 = Enable discard of received errored frames + + + Notes: + Rx errored frame discard enable. When set to 1, any frame received with an error is discarded and not forwarded to the client interface. When set to 0, errored frames are forwarded to the client interface with ff_rx_err asserted. + Note : It is recommended to set this bit to 1 only when store and forward operation is enabled (RX_SECTION_FULL TBD). */ + unsigned int msmLineRxErrorDiscard : 1; /* 1E.9004.E R/W Default = 0x0 */ + /* 1 = Enable discard of received errored frames + */ + /*! \brief 1E.9004.D R/W MSM Line Control Frame Enable + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLineControlFrameEnable + + Default = 0x0 + + 1 = Control frame enabled + + + Notes: + MAC control frame enable. When set to 1, the MAC control frames with any Opcode other than 0x0001 are accepted and forwarded to the client interface. When set to 0, MAC control frames with any opcode other than 0x0001 are silently discarded. */ + unsigned int msmLineControlFrameEnable : 1; /* 1E.9004.D R/W Default = 0x0 */ + /* 1 = Control frame enabled + */ + /*! \brief 1E.9004.C R/WSC MSM Line Soft Reset + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLineSoftReset + + Default = 0x0 + + 1 = Soft reset + + + Notes: + Software reset. Self clearing bit. When set to 1, resets all statistic counters as well as the Tx and Rx FIFOs. It should be issued after all traffic has been stopped as a result of clearing the Rx/Tx enable bits ( See MAC Rx Enable set to 0 and See MAC Tx Enable set to 0). + Note : Can lead to an Rx interface (ff_rx_xxx) violations to the application if the reset is issued in the middle of a receive frame transfer. Then the end of packet (assertion of ff_rx_eop) is lost and the application should be prepeared to handle this exception. */ + unsigned int msmLineSoftReset : 1; /* 1E.9004.C R/WSC Default = 0x0 */ + /* 1 = Soft reset + */ + /*! \brief 1E.9004.B R/W MSM Line Tx Pad Enable + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLineTxPadEnable + + Default = 0x1 + + 1 = Enable Tx padding + + + Notes: + When set to 1, enable padding of frames in the Tx direction. When set to 0, the MAC will not extend frames from the application to a minimum of 64 bytes, allowing to transmit short frames (violating the Ethernet mimimum size requirements). Must be set to 1 for normal operation. */ + unsigned int msmLineTxPadEnable : 1; /* 1E.9004.B R/W Default = 0x1 */ + /* 1 = Enable Tx padding + */ + /*! \brief 1E.9004.A R/W MSM Line Tx CRC Append + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLineTxCrcAppend + + Default = 0x0 + + 1 = Append Tx CRC + + + Notes: + Permanently enable CRC append on transmit. If set to 1, the Tx will append a CRC to all transmitted frames. If set to 0, CRC append can be controlled on a per frame basis using the pin ff_tx_crc. + This configuration bit is OR'ed with the external ff_tx_crc pin to instruct the Tx to append a CRC to transmitted frames. The ff_tx_crc pin is tied to 0. */ + unsigned int msmLineTxCrcAppend : 1; /* 1E.9004.A R/W Default = 0x0 */ + /* 1 = Append Tx CRC + */ + /*! \brief 1E.9004.9 R/W MSM Line Tx Address Insert Enable + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLineTxAddressInsertEnable + + Default = 0x0 + + 1 = Insert Tx MAC source address + + + Notes: + Set the source MAC address on transmit. If set to 1, the MAC overwrites the source MAC address with the MAC programmed address in all transmitted frames. When set to 0, the source MAC address is transmitted unmodified from the MAC Tx client application. */ + unsigned int msmLineTxAddressInsertEnable : 1; /* 1E.9004.9 R/W Default = 0x0 */ + /* 1 = Insert Tx MAC source address + */ + /*! \brief 1E.9004.8 R/W MSM Line Pause Ignore + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLinePauseIgnore + + Default = 0x0 + + 1 = Ignore pause frames + + + Notes: + Ignore pause frame quanta. If set to 1, received pause frames are ignored by the MAC. When set to 0, the Tx is stopped for the amount of time specified in the pause quanta received within the pause frame. */ + unsigned int msmLinePauseIgnore : 1; /* 1E.9004.8 R/W Default = 0x0 */ + /* 1 = Ignore pause frames + */ + /*! \brief 1E.9004.7 R/W MSM Line Pause Forward + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLinePauseForward + + Default = 0x0 + + 1 = Enable Pause forwarding + + + Notes: + Terminate or forward pause frames. If set to 1, pause frames are forwarded to the user application. In normal mode, when set to 0, pause frames are terminated and discarded within the MAC. */ + unsigned int msmLinePauseForward : 1; /* 1E.9004.7 R/W Default = 0x0 */ + /* 1 = Enable Pause forwarding + */ + /*! \brief 1E.9004.6 R/W MSM Line CRC Forward + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLineCrcForward + + Default = 0x0 + + 1 = Enable CRC forwarding + + + Notes: + When set to 1, the CRC field of the received frames is forwarded with the frame to the user application. If disabled, the CRC field is stripped from the frame. + Note : If padding is enabled ( See MAC PAD Enable set to 1), this bit is ignored. */ + unsigned int msmLineCrcForward : 1; /* 1E.9004.6 R/W Default = 0x0 */ + /* 1 = Enable CRC forwarding + */ + /*! \brief 1E.9004.5 R/W MSM Line PAD Enable + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLinePadEnable + + Default = 0x0 + + 1 = Enable frame padding removal on Rx + + + Notes: + When set to 1, enable frame padding removal on the Rx path. If enabled, padding is removed before the frame is transferred to the MAC client application. If disabled, no padding is removed on the Rx by the MAC. + Note : On Tx, the MAC always adds padding as required. */ + unsigned int msmLinePadEnable : 1; /* 1E.9004.5 R/W Default = 0x0 */ + /* 1 = Enable frame padding removal on Rx + */ + /*! \brief 1E.9004.4 R/W MSM Line Promiscuous Mode + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLinePromiscuousMode + + Default = 0x0 + + 1 = Promiscuous mode + + + Notes: + When set to 1, all frames are received without any MAC address filtering. */ + unsigned int msmLinePromiscuousMode : 1; /* 1E.9004.4 R/W Default = 0x0 */ + /* 1 = Promiscuous mode + */ + /*! \brief 1E.9004.3 R/W MSM Line WAN Mode + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLineWanMode + + Default = 0x0 + + 1 = WAN mode + 0 = LAN mode + + + Notes: + WAN mode enable. Sets WAN mode when set to 1 and LAN mode when set to 0. Note: When changing the mode, verifiy correct setting of the Tx IPG. */ + unsigned int msmLineWanMode : 1; /* 1E.9004.3 R/W Default = 0x0 */ + /* 1 = WAN mode + 0 = LAN mode + */ + unsigned int reserved0 : 1; + /*! \brief 1E.9004.1 R/W MSM Line Rx Enable + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLineRxEnable + + Default = 0x0 + + 1 = Rx enable + + Notes: + MAC Tx path enable. Should be set to 1 to enable the MAC Tx path. Should be set to 0 to disable the MAC Tx path. */ + unsigned int msmLineRxEnable : 1; /* 1E.9004.1 R/W Default = 0x0 */ + /* 1 = Rx enable */ + /*! \brief 1E.9004.0 R/W MSM Line Tx Enable + AQ_MsmLineGeneralControlRegister_HHD.u0.bits_0.msmLineTxEnable + + Default = 0x0 + + 1 = Tx enable + + Notes: + MAC Rx path enable. Should be set to 1 to enable the MAC Rx path. Should be set to 0 to disable the MAC Rx path. */ + unsigned int msmLineTxEnable : 1; /* 1E.9004.0 R/W Default = 0x0 */ + /* 1 = Tx enable */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line General Control Register */ + union + { + struct + { + unsigned int reserved0 : 8; + /*! \brief 1E.9005.7 R/W MSM Line Tx Low Power IDLE Enable + AQ_MsmLineGeneralControlRegister_HHD.u1.bits_1.msmLineTxLowPowerIdleEnable + + Default = 0x0 + + 1 = Transmit LPI enable + + + Notes: + Transmit low power IDLE enable. When set to 1, the MAC completes the transmission of the current frame and generates low power IDLE sequences (LPI) to the XGMII/SGMII. When set to 0, the MAC operates in normal mode. This bit is OR'ed with the reg_lowp_ena pin. */ + unsigned int msmLineTxLowPowerIdleEnable : 1; /* 1E.9005.7 R/W Default = 0x0 */ + /* 1 = Transmit LPI enable + */ + unsigned int reserved1 : 1; + /*! \brief 1E.9005.5 R/W MSM Line SFD Check Disable + AQ_MsmLineGeneralControlRegister_HHD.u1.bits_1.msmLineSfdCheckDisable + + Default = 0x0 + + 1 = Disable SFD check + + + Notes: + Disable check of SFD (0xD5) character at frame start. When set to 1, the frame is accepted even if the SFD byte following the preamble is not 0xD5. When set to 0, a frame is accepted only if the SFD byte is found with the value 0xD5. */ + unsigned int msmLineSfdCheckDisable : 1; /* 1E.9005.5 R/W Default = 0x0 */ + /* 1 = Disable SFD check + */ + unsigned int reserved2 : 1; + /*! \brief 1E.9005.3 R/W MSM Line Priority Flow Control Enable + AQ_MsmLineGeneralControlRegister_HHD.u1.bits_1.msmLinePriorityFlowControlEnable + + Default = 0x0 + + 1 = Enable priority flow control + 0 = Enable link flow control + + + Notes: + Enable priority flow control (PFC) mode of operation. When set to 0, the MAC uses standard link pause frames. When set to 1, the MAC will transmit and accept PFC frames. */ + unsigned int msmLinePriorityFlowControlEnable : 1; /* 1E.9005.3 R/W Default = 0x0 */ + /* 1 = Enable priority flow control + 0 = Enable link flow control + */ + /*! \brief 1E.9005.2 R/W MSM Line IDLE Column Count Extend + AQ_MsmLineGeneralControlRegister_HHD.u1.bits_1.msmLineIdleColumnCountExtend + + Default = 0x0 + + 1 = Extend IDLE column count + + Notes: + When set to 1, extends the RS layer IDLE column counter by 2x. The IEEE 802.3ae defines the fault condition to be cleared after 128 columns of IDLE have been received. If the MAC operates together with a WAN mode PCS (WIS) it may may happen (depending on PCS) that this period is too short to bridge the IDLE stuffing occurring in this mode, leading to a toggling fault indication. In this case, extending the counter helps to aoivd toggling fault indications. */ + unsigned int msmLineIdleColumnCountExtend : 1; /* 1E.9005.2 R/W Default = 0x0 */ + /* 1 = Extend IDLE column count */ + /*! \brief 1E.9005.1 R/W MSM Line Length Check Disable + AQ_MsmLineGeneralControlRegister_HHD.u1.bits_1.msmLineLengthCheckDisable + + Default = 0x0 + + 1 = Disable length check + + Notes: + Payload length check disable. When set to 0, the MAC checks the frames payload length with the frame length/type field. When set to 1, the payload length check is disabled. */ + unsigned int msmLineLengthCheckDisable : 1; /* 1E.9005.1 R/W Default = 0x0 */ + /* 1 = Disable length check */ + /*! \brief 1E.9005.0 R/W MSM Line Force Send IDLE + AQ_MsmLineGeneralControlRegister_HHD.u1.bits_1.msmLineForceSendIdle + + Default = 0x0 + + 1 = Force send idle + + Notes: + When set to 1, suppress any frame transmissions and forces IDLE n the Tx interface instead of frames. This control affects the MAC reconciliation layer (RS) which acts after all MAC datapath has processed the frame. + Note : Does not have an effect on fault handling (i.e. reception of local fault will still cause transmit of remote fault). + Must be 0 for normal operation. */ + unsigned int msmLineForceSendIdle : 1; /* 1E.9005.0 R/W Default = 0x0 */ + /* 1 = Force send idle */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineGeneralControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line FIFO Control Register: 1E.900E */ +/* MSM Line FIFO Control Register: 1E.900E */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line FIFO Control Register */ + union + { + struct + { + unsigned int reserved0 : 8; + /*! \brief 1E.900E.7:0 R/W MSM Line Rx FIFO Full Threshold [7:0] + AQ_MsmLineFifoControlRegister_HHD.u0.bits_0.msmLineRxFifoFullThreshold + + Default = 0x08 + + Rx FIFO full threshold + + Notes: + All threshold values are in steps of FIFO words. */ + unsigned int msmLineRxFifoFullThreshold : 8; /* 1E.900E.7:0 R/W Default = 0x08 */ + /* Rx FIFO full threshold */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line FIFO Control Register */ + union + { + struct + { + unsigned int reserved0 : 8; + /*! \brief 1E.900F.7:0 R/W MSM Line Rx FIFO Empty Threshold [7:0] + AQ_MsmLineFifoControlRegister_HHD.u1.bits_1.msmLineRxFifoEmptyThreshold + + Default = 0x00 + + Rx FIFO empty threshold + + Notes: + All threshold values are in steps of FIFO words. */ + unsigned int msmLineRxFifoEmptyThreshold : 8; /* 1E.900F.7:0 R/W Default = 0x00 */ + /* Rx FIFO empty threshold */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of MSM Line FIFO Control Register */ + union + { + struct + { + unsigned int reserved0 : 10; + /*! \brief 1E.9010.5:0 R/W MSM Line Tx FIFO Full Threshold [5:0] + AQ_MsmLineFifoControlRegister_HHD.u2.bits_2.msmLineTxFifoFullThreshold + + Default = 0x08 + + Tx FIFO full threshold + + Notes: + All threshold values are in steps of FIFO words. */ + unsigned int msmLineTxFifoFullThreshold : 6; /* 1E.9010.5:0 R/W Default = 0x08 */ + /* Tx FIFO full threshold */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of MSM Line FIFO Control Register */ + union + { + struct + { + unsigned int reserved0 : 10; + /*! \brief 1E.9011.5:0 R/W MSM Line Tx FIFO Empty Threshold [5:0] + AQ_MsmLineFifoControlRegister_HHD.u3.bits_3.msmLineTxFifoEmptyThreshold + + Default = 0x00 + + Tx FIFO empty threshold + + Notes: + All threshold values are in steps of FIFO words. */ + unsigned int msmLineTxFifoEmptyThreshold : 6; /* 1E.9011.5:0 R/W Default = 0x00 */ + /* Tx FIFO empty threshold */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of MSM Line FIFO Control Register */ + union + { + struct + { + unsigned int reserved0 : 8; + /*! \brief 1E.9012.7:0 ROS MSM Line Rx FIFO Almost Full Threshold [7:0] + AQ_MsmLineFifoControlRegister_HHD.u4.bits_4.msmLineRxFifoAlmostFullThreshold + + Default = 0x00 + + Rx FIFO almost full threshold + + Notes: + Unused. */ + unsigned int msmLineRxFifoAlmostFullThreshold : 8; /* 1E.9012.7:0 ROS Default = 0x00 */ + /* Rx FIFO almost full threshold */ + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of MSM Line FIFO Control Register */ + union + { + struct + { + unsigned int reserved0 : 8; + /*! \brief 1E.9013.7:0 ROS MSM Line Rx FIFO Almost Empty Threshold [7:0] + AQ_MsmLineFifoControlRegister_HHD.u5.bits_5.msmLineRxFifoAlmostEmptyThreshold + + Default = 0x00 + + Rx FIFO almost empty threshold + + Notes: + Unused. */ + unsigned int msmLineRxFifoAlmostEmptyThreshold : 8; /* 1E.9013.7:0 ROS Default = 0x00 */ + /* Rx FIFO almost empty threshold */ + } bits_5; + uint16_t word_5; + } u5; + /*! \brief Union for bit and word level access of word 6 of MSM Line FIFO Control Register */ + union + { + struct + { + unsigned int reserved0 : 8; + /*! \brief 1E.9014.7:0 ROS MSM Line Tx FIFO Almost Full Threshold [7:0] + AQ_MsmLineFifoControlRegister_HHD.u6.bits_6.msmLineTxFifoAlmostFullThreshold + + Default = 0x00 + + Tx FIFO almost full threshold + + Notes: + Unused. */ + unsigned int msmLineTxFifoAlmostFullThreshold : 8; /* 1E.9014.7:0 ROS Default = 0x00 */ + /* Tx FIFO almost full threshold */ + } bits_6; + uint16_t word_6; + } u6; + /*! \brief Union for bit and word level access of word 7 of MSM Line FIFO Control Register */ + union + { + struct + { + unsigned int reserved0 : 8; + /*! \brief 1E.9015.7:0 ROS MSM Line Tx FIFO Almost Empty Threshold [7:0] + AQ_MsmLineFifoControlRegister_HHD.u7.bits_7.msmLineTxFifoAlmostEmptyThreshold + + Default = 0x00 + + Tx FIFO almost empty threshold + + Notes: + Unused. */ + unsigned int msmLineTxFifoAlmostEmptyThreshold : 8; /* 1E.9015.7:0 ROS Default = 0x00 */ + /* Tx FIFO almost empty threshold */ + } bits_7; + uint16_t word_7; + } u7; +} AQ_MsmLineFifoControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line General Status Register: 1E.9020 */ +/* MSM Line General Status Register: 1E.9020 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line General Status Register */ + union + { + struct + { + unsigned int reserved0 : 10; + /*! \brief 1E.9020.5 RO MSM Line Tx FIFO Empty + AQ_MsmLineGeneralStatusRegister_HHD.u0.bits_0.msmLineTxFifoEmpty + + + + Tx FIFO empty + + Notes: + When set to 1, indicates the Tx FIFO is empty. When set to 0, Tx FIFO is non-empty. */ + unsigned int msmLineTxFifoEmpty : 1; /* 1E.9020.5 RO */ + /* Tx FIFO empty */ + /*! \brief 1E.9020.4 RO MSM Line Rx Low Power IDLE + AQ_MsmLineGeneralStatusRegister_HHD.u0.bits_0.msmLineRxLowPowerIdle + + + + Rx LPI detected + + Notes: + Receive low power IDLE (LPI). Set to 1 when LPI is currently detected on the MAC Rx interface. Set to 0, when the MAC currently operates in normal mode. */ + unsigned int msmLineRxLowPowerIdle : 1; /* 1E.9020.4 RO */ + /* Rx LPI detected */ + /*! \brief 1E.9020.3 R/W MSM Line Timestamp Available + AQ_MsmLineGeneralStatusRegister_HHD.u0.bits_0.msmLineTimestampAvailable + + Default = 0x0 + + Timestamp available + + Notes: + Transmit timestamp available. Indicates that the timestamp of the last transmitted event frame (which had ff_tx_ts_frm=1) is available in the register See MAC Time Stamp Status 0 [F:0] and See MAC Time Stamp Status 1 [F:0] . To clear this bit, the bit must be written with a 1. + */ + unsigned int msmLineTimestampAvailable : 1; /* 1E.9020.3 R/W Default = 0x0 */ + /* Timestamp available */ + /*! \brief 1E.9020.2 RO MSM Line PHY Loss of Signal + AQ_MsmLineGeneralStatusRegister_HHD.u0.bits_0.msmLinePhyLossOfSignal + + + + PHY loss of signal + + Notes: + PHY indicates loss of signal. This is the value of pin phy_los which is tied to 0. */ + unsigned int msmLinePhyLossOfSignal : 1; /* 1E.9020.2 RO */ + /* PHY loss of signal */ + /*! \brief 1E.9020.1 BLH MSM Line Rx Remote Fault + AQ_MsmLineGeneralStatusRegister_HHD.u0.bits_0.msmLineRxRemoteFault + + + + Rx remote fault detected + + Notes: + Latch high local fault status. Set to 1, whent he MAC detects Rx local fault sequences on the Rx interface. Reset to 0 after read and after reset. */ + unsigned int msmLineRxRemoteFault : 1; /* 1E.9020.1 BLH */ + /* Rx remote fault detected */ + /*! \brief 1E.9020.0 BLH MSM Line Rx Local Fault + AQ_MsmLineGeneralStatusRegister_HHD.u0.bits_0.msmLineRxLocalFault + + + + Rx local fault detected + + Notes: + Latch high local fault status. Set to 1, whent he MAC detects Rx local fault sequences on the Rx interface. Reset to 0 after read and after reset. */ + unsigned int msmLineRxLocalFault : 1; /* 1E.9020.0 BLH */ + /* Rx local fault detected */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line General Status Register */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineGeneralStatusRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Tx IPG Control Register: 1E.9022 */ +/* MSM Line Tx IPG Control Register: 1E.9022 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Tx IPG Control Register */ + union + { + struct + { + unsigned int reserved0 : 10; + /*! \brief 1E.9022.5:0 R/W MSM Line Tx IPG Length [5:0] + AQ_MsmLineTxIpgControlRegister_HHD.u0.bits_0.msmLineTxIpgLength + + Default = 0x0C + + Tx IPG length + + Notes: + Tx inter-packet gap (IPG) value. Depending on LAN or WAN mode of operation. + LAN Mode : Number of octets in steps of 4. Valid values are 8, 12, 16,..., 100. DIC is supported for any setting > 8. A default of 12 must be set to conform to IEEE802.3ae. + WAN Mode : Stretch factor. Valid values are 4 ... 15. The stretch factor is calculated as (value+1)*8. A default of 12 must be set to conform to IEEE802.3ae (i.e. 13*8=104). A larger value shrinks the IPG (increasing bandwidth). + The reset value of 12 leads to IEEE802.3ae conformant behavior in both modes. + Note : WAN mode is only available in 10G mode of operation. */ + unsigned int msmLineTxIpgLength : 6; /* 1E.9022.5:0 R/W Default = 0x0C */ + /* Tx IPG length */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Tx IPG Control Register */ + union + { + struct + { + /*! \brief 1E.9023.F:0 MSM Line Tx IPG Reserved + AQ_MsmLineTxIpgControlRegister_HHD.u1.bits_1.msmLineTxIpgReserved + + + + Value always 0, writes ignored + */ + unsigned int msmLineTxIpgReserved : 16; /* 1E.9023.F:0 */ + /* Value always 0, writes ignored */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineTxIpgControlRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Tx Good Frames Counter Register: 1E.9040 */ +/* MSM Line Tx Good Frames Counter Register: 1E.9040 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Tx Good Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9040.F:0 ROS MSM Line Tx Good Frames Counter 0 [F:0] + AQ_MsmLineTxGoodFramesCounterRegister_HHD.u0.bits_0.msmLineTxGoodFramesCounter_0 + + Default = 0x0000 + + Tx good frame counter bits 15:0 + + Notes: + Count of frames transmitted without error (Including pause frames). */ + unsigned int msmLineTxGoodFramesCounter_0 : 16; /* 1E.9040.F:0 ROS Default = 0x0000 */ + /* Tx good frame counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Tx Good Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9041.F:0 ROS MSM Line Tx Good Frames Counter 1 [F:0] + AQ_MsmLineTxGoodFramesCounterRegister_HHD.u1.bits_1.msmLineTxGoodFramesCounter_1 + + Default = 0x0000 + + Tx good frame counter bits 31:16 + + + Notes: + Count of frames transmitted without error (Including pause frames). */ + unsigned int msmLineTxGoodFramesCounter_1 : 16; /* 1E.9041.F:0 ROS Default = 0x0000 */ + /* Tx good frame counter bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineTxGoodFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx Good Frames Counter Register: 1E.9044 */ +/* MSM Line Rx Good Frames Counter Register: 1E.9044 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx Good Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9044.F:0 ROS MSM Line Rx Good Frames Counter 0 [F:0] + AQ_MsmLineRxGoodFramesCounterRegister_HHD.u0.bits_0.msmLineRxGoodFramesCounter_0 + + Default = 0x0000 + + Rx good frame counter bits 15:0 + + Notes: + Count of frames received without error (Including pause frames). */ + unsigned int msmLineRxGoodFramesCounter_0 : 16; /* 1E.9044.F:0 ROS Default = 0x0000 */ + /* Rx good frame counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx Good Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9045.F:0 ROS MSM Line Rx Good Frames Counter 1 [F:0] + AQ_MsmLineRxGoodFramesCounterRegister_HHD.u1.bits_1.msmLineRxGoodFramesCounter_1 + + Default = 0x0000 + + Rx good frame counter bits 31:16 + + Notes: + Count of frames received without error (Including pause frames). */ + unsigned int msmLineRxGoodFramesCounter_1 : 16; /* 1E.9045.F:0 ROS Default = 0x0000 */ + /* Rx good frame counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxGoodFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx FCS Errors Counter Register: 1E.9048 */ +/* MSM Line Rx FCS Errors Counter Register: 1E.9048 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx FCS Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.9048.F:0 ROS MSM Line FCS Error Counter 0 [F:0] + AQ_MsmLineRxFcsErrorsCounterRegister_HHD.u0.bits_0.msmLineFcsErrorCounter_0 + + Default = 0x0000 + + Frame check sequence error counter bits 15:0 + + Notes: + Count of frames for which a CRC-32 Error is detected but the frame is otherwise of correct length. */ + unsigned int msmLineFcsErrorCounter_0 : 16; /* 1E.9048.F:0 ROS Default = 0x0000 */ + /* Frame check sequence error counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx FCS Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.9049.F:0 ROS MSM Line FCS Error Counter 1 [F:0] + AQ_MsmLineRxFcsErrorsCounterRegister_HHD.u1.bits_1.msmLineFcsErrorCounter_1 + + Default = 0x0000 + + Frame check sequence error counter bits 31:16 + + Notes: + Count of frames for which a CRC-32 Error is detected but the frame is otherwise of correct length. */ + unsigned int msmLineFcsErrorCounter_1 : 16; /* 1E.9049.F:0 ROS Default = 0x0000 */ + /* Frame check sequence error counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxFcsErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx Alignment Errors Counter Register: 1E.904C */ +/* MSM Line Rx Alignment Errors Counter Register: 1E.904C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx Alignment Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.904C.F:0 ROS MSM Line Alignment Error Counter 0 [F:0] + AQ_MsmLineRxAlignmentErrorsCounterRegister_HHD.u0.bits_0.msmLineAlignmentErrorCounter_0 + + Default = 0x0000 + + Alignment error counter bits 15:0 + + Notes: + Count of frames received with an alignment error. */ + unsigned int msmLineAlignmentErrorCounter_0 : 16; /* 1E.904C.F:0 ROS Default = 0x0000 */ + /* Alignment error counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx Alignment Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.904D.F:0 ROS MSM Line Alignment Error Counter 1 [F:0] + AQ_MsmLineRxAlignmentErrorsCounterRegister_HHD.u1.bits_1.msmLineAlignmentErrorCounter_1 + + Default = 0x0000 + + Alignment error counter bits 31:16 + + Notes: + Count of frames received with an alignment error. */ + unsigned int msmLineAlignmentErrorCounter_1 : 16; /* 1E.904D.F:0 ROS Default = 0x0000 */ + /* Alignment error counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxAlignmentErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Tx Pause Frames Counter Register: 1E.9050 */ +/* MSM Line Tx Pause Frames Counter Register: 1E.9050 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Tx Pause Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9050.F:0 ROS MSM Line Tx Pause Frames Counter 0 [F:0] + AQ_MsmLineTxPauseFramesCounterRegister_HHD.u0.bits_0.msmLineTxPauseFramesCounter_0 + + Default = 0x0000 + + Tx pause frame counter bits 15:0 + + Notes: + Valid pause frames transmitted. */ + unsigned int msmLineTxPauseFramesCounter_0 : 16; /* 1E.9050.F:0 ROS Default = 0x0000 */ + /* Tx pause frame counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Tx Pause Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9051.F:0 ROS MSM Line Tx Pause Frames Counter 1 [F:0] + AQ_MsmLineTxPauseFramesCounterRegister_HHD.u1.bits_1.msmLineTxPauseFramesCounter_1 + + Default = 0x0000 + + Tx pause frame counter bits 31:16 + + + Notes: + Valid pause frames transmitted. */ + unsigned int msmLineTxPauseFramesCounter_1 : 16; /* 1E.9051.F:0 ROS Default = 0x0000 */ + /* Tx pause frame counter bits 31:16 + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineTxPauseFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx Pause Frames Counter Register: 1E.9054 */ +/* MSM Line Rx Pause Frames Counter Register: 1E.9054 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx Pause Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9054.F:0 ROS MSM Line Rx Pause Frames Counter 0 [F:0] + AQ_MsmLineRxPauseFramesCounterRegister_HHD.u0.bits_0.msmLineRxPauseFramesCounter_0 + + Default = 0x0000 + + Rx pause frame counter bits 15:0 + + Notes: + Valid pause frames received. */ + unsigned int msmLineRxPauseFramesCounter_0 : 16; /* 1E.9054.F:0 ROS Default = 0x0000 */ + /* Rx pause frame counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx Pause Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9055.F:0 ROS MSM Line Rx Pause Frames Counter 1 [F:0] + AQ_MsmLineRxPauseFramesCounterRegister_HHD.u1.bits_1.msmLineRxPauseFramesCounter_1 + + Default = 0x0000 + + Rx pause frame counter bits 31:16 + + Notes: + Valid pause frames received. */ + unsigned int msmLineRxPauseFramesCounter_1 : 16; /* 1E.9055.F:0 ROS Default = 0x0000 */ + /* Rx pause frame counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxPauseFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx Too Long Errors Counter Register: 1E.9058 */ +/* MSM Line Rx Too Long Errors Counter Register: 1E.9058 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx Too Long Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.9058.F:0 ROS MSM Line Rx Too Long Errors Counter 0 [F:0] + AQ_MsmLineRxTooLongErrorsCounterRegister_HHD.u0.bits_0.msmLineRxTooLongErrorsCounter_0 + + Default = 0x0000 + + Too-long errors counter bits 15:0 + + Notes: + Frame received exceeded the maximum length programmed with register FRM_LGTH. */ + unsigned int msmLineRxTooLongErrorsCounter_0 : 16; /* 1E.9058.F:0 ROS Default = 0x0000 */ + /* Too-long errors counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx Too Long Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.9059.F:0 ROS MSM Line Rx Too Long Errors Counter 1 [F:0] + AQ_MsmLineRxTooLongErrorsCounterRegister_HHD.u1.bits_1.msmLineRxTooLongErrorsCounter_1 + + Default = 0x0000 + + Too-long errors counter bits 31:16 + + Notes: + Frame received exceeded the maximum length programmed with register FRM_LGTH. */ + unsigned int msmLineRxTooLongErrorsCounter_1 : 16; /* 1E.9059.F:0 ROS Default = 0x0000 */ + /* Too-long errors counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxTooLongErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx In Range Length Errors Counter Register: 1E.905C */ +/* MSM Line Rx In Range Length Errors Counter Register: 1E.905C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx In Range Length Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.905C.F:0 ROS MSM Line Rx In Range Length Errors Counter 0 [F:0] + AQ_MsmLineRxInRangeLengthErrorsCounterRegister_HHD.u0.bits_0.msmLineRxInRangeLengthErrorsCounter_0 + + Default = 0x0000 + + In-range-length errors counter bits 15:0 + + Notes: + A count of frames with a length/type field value between 46 (VLAN: 42) and less than 0x0600, that does not match the number of payload data octets received. Should count also if length/type field is less than 46 (VLAN: 42) and the frame is longer than 64 bytes. */ + unsigned int msmLineRxInRangeLengthErrorsCounter_0 : 16; /* 1E.905C.F:0 ROS Default = 0x0000 */ + /* In-range-length errors counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx In Range Length Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.905D.F:0 ROS MSM Line Rx In Range Length Errors Counter 1 [F:0] + AQ_MsmLineRxInRangeLengthErrorsCounterRegister_HHD.u1.bits_1.msmLineRxInRangeLengthErrorsCounter_1 + + Default = 0x0000 + + In-range-length errors counter bits 31:16 + + Notes: + A count of frames with a length/type field value between 46 (VLAN: 42) and less than 0x0600, that does not match the number of payload data octets received. Should count also if length/type field is less than 46 (VLAN: 42) and the frame is longer than 64 bytes. */ + unsigned int msmLineRxInRangeLengthErrorsCounter_1 : 16; /* 1E.905D.F:0 ROS Default = 0x0000 */ + /* In-range-length errors counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxInRangeLengthErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Tx VLAN Frames Counter Register: 1E.9060 */ +/* MSM Line Tx VLAN Frames Counter Register: 1E.9060 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Tx VLAN Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9060.F:0 ROS MSM Line Tx VLAN Frames Counter 0 [F:0] + AQ_MsmLineTxVlanFramesCounterRegister_HHD.u0.bits_0.msmLineTxVlanFramesCounter_0 + + Default = 0x0000 + + Tx VLAN frames counter bits 15:0 + + Notes: + Valid VLAN tagged frames transmitted. */ + unsigned int msmLineTxVlanFramesCounter_0 : 16; /* 1E.9060.F:0 ROS Default = 0x0000 */ + /* Tx VLAN frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Tx VLAN Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9061.F:0 ROS MSM Line Tx VLAN Frames Counter 1 [F:0] + AQ_MsmLineTxVlanFramesCounterRegister_HHD.u1.bits_1.msmLineTxVlanFramesCounter_1 + + Default = 0x0000 + + Tx VLAN frames counter bits 31:16 + + Notes: + Valid VLAN tagged frames transmitted. */ + unsigned int msmLineTxVlanFramesCounter_1 : 16; /* 1E.9061.F:0 ROS Default = 0x0000 */ + /* Tx VLAN frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineTxVlanFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx VLAN Frames Counter Register: 1E.9064 */ +/* MSM Line Rx VLAN Frames Counter Register: 1E.9064 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx VLAN Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9064.F:0 ROS MSM Line Rx VLAN Frames Counter 0 [F:0] + AQ_MsmLineRxVlanFramesCounterRegister_HHD.u0.bits_0.msmLineRxVlanFramesCounter_0 + + Default = 0x0000 + + Rx VLAN frames counter bits 15:0 + + Notes: + Valid VLAN tagged frames received. */ + unsigned int msmLineRxVlanFramesCounter_0 : 16; /* 1E.9064.F:0 ROS Default = 0x0000 */ + /* Rx VLAN frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx VLAN Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9065.F:0 ROS MSM Line Rx VLAN Frames Counter 1 [F:0] + AQ_MsmLineRxVlanFramesCounterRegister_HHD.u1.bits_1.msmLineRxVlanFramesCounter_1 + + Default = 0x0000 + + Rx VLAN frames counter bits 31:16 + + Notes: + Valid VLAN tagged frames received. */ + unsigned int msmLineRxVlanFramesCounter_1 : 16; /* 1E.9065.F:0 ROS Default = 0x0000 */ + /* Rx VLAN frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxVlanFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Tx Octets Counter Register: 1E.9068 */ +/* MSM Line Tx Octets Counter Register: 1E.9068 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Tx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.9068.F:0 ROS MSM Line Tx Octets Counter 0 [F:0] + AQ_MsmLineTxOctetsCounterRegister_HHD.u0.bits_0.msmLineTxOctetsCounter_0 + + Default = 0x0000 + + Tx octets counter bits 15:0 + + Notes: + All octets transmitted except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames transmitted. */ + unsigned int msmLineTxOctetsCounter_0 : 16; /* 1E.9068.F:0 ROS Default = 0x0000 */ + /* Tx octets counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Tx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.9069.F:0 ROS MSM Line Tx Octets Counter 1 [F:0] + AQ_MsmLineTxOctetsCounterRegister_HHD.u1.bits_1.msmLineTxOctetsCounter_1 + + Default = 0x0000 + + Tx octets counter bits 31:16 + + Notes: + All octets transmitted except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames transmitted. */ + unsigned int msmLineTxOctetsCounter_1 : 16; /* 1E.9069.F:0 ROS Default = 0x0000 */ + /* Tx octets counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of MSM Line Tx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.906A.F:0 ROS MSM Line Tx Octets Counter 2 [F:0] + AQ_MsmLineTxOctetsCounterRegister_HHD.u2.bits_2.msmLineTxOctetsCounter_2 + + Default = 0x0000 + + Tx octets counter bits 47:32 + + Notes: + All octets transmitted except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames transmitted. */ + unsigned int msmLineTxOctetsCounter_2 : 16; /* 1E.906A.F:0 ROS Default = 0x0000 */ + /* Tx octets counter bits 47:32 */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of MSM Line Tx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.906B.F:0 ROS MSM Line Tx Octets Counter 3 [F:0] + AQ_MsmLineTxOctetsCounterRegister_HHD.u3.bits_3.msmLineTxOctetsCounter_3 + + Default = 0x0000 + + Tx octets counter bits 63:48 + + Notes: + All octets transmitted except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames transmitted. */ + unsigned int msmLineTxOctetsCounter_3 : 16; /* 1E.906B.F:0 ROS Default = 0x0000 */ + /* Tx octets counter bits 63:48 */ + } bits_3; + uint16_t word_3; + } u3; +} AQ_MsmLineTxOctetsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx Octets Counter Register: 1E.906C */ +/* MSM Line Rx Octets Counter Register: 1E.906C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.906C.F:0 ROS MSM Line Rx Octets Counter 0 [F:0] + AQ_MsmLineRxOctetsCounterRegister_HHD.u0.bits_0.msmLineRxOctetsCounter_0 + + Default = 0x0000 + + Rx octets counter bits 15:0 + + Notes: + All octets received except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames received. */ + unsigned int msmLineRxOctetsCounter_0 : 16; /* 1E.906C.F:0 ROS Default = 0x0000 */ + /* Rx octets counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx Octets Counter Register */ + union + { + struct + { + /*! \brief 1E.906D.F:0 ROS MSM Line Rx Octets Counter 1 [F:0] + AQ_MsmLineRxOctetsCounterRegister_HHD.u1.bits_1.msmLineRxOctetsCounter_1 + + Default = 0x0000 + + Rx octets counter bits 31:16 + + Notes: + All octets received except preamble (i.e. Header, Payload, Pad and FCS) for all valid frames and valid pause frames received. */ + unsigned int msmLineRxOctetsCounter_1 : 16; /* 1E.906D.F:0 ROS Default = 0x0000 */ + /* Rx octets counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxOctetsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx Unicast Frames Counter Register: 1E.9070 */ +/* MSM Line Rx Unicast Frames Counter Register: 1E.9070 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx Unicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9070.F:0 ROS MSM Line Rx Unicast Frames Counter 0 [F:0] + AQ_MsmLineRxUnicastFramesCounterRegister_HHD.u0.bits_0.msmLineRxUnicastFramesCounter_0 + + Default = 0x0000 + + Rx unicast frames counter bits 15:0 + + Notes: + Incremented with each valid frame received on the receive FIFO interface and bit 0 of the destination address was '0'. */ + unsigned int msmLineRxUnicastFramesCounter_0 : 16; /* 1E.9070.F:0 ROS Default = 0x0000 */ + /* Rx unicast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx Unicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9071.F:0 ROS MSM Line Rx Unicast Frames Counter 1 [F:0] + AQ_MsmLineRxUnicastFramesCounterRegister_HHD.u1.bits_1.msmLineRxUnicastFramesCounter_1 + + Default = 0x0000 + + Rx unicast frames counter bits 31:16 + + Notes: + Incremented with each valid frame received on the receive FIFO interface and bit 0 of the destination address was '0'. */ + unsigned int msmLineRxUnicastFramesCounter_1 : 16; /* 1E.9071.F:0 ROS Default = 0x0000 */ + /* Rx unicast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxUnicastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx Multicast Frames Counter Register: 1E.9074 */ +/* MSM Line Rx Multicast Frames Counter Register: 1E.9074 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx Multicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9074.F:0 ROS MSM Line Rx Multicast Frames Counter 0 [F:0] + AQ_MsmLineRxMulticastFramesCounterRegister_HHD.u0.bits_0.msmLineRxMulticastFramesCounter_0 + + Default = 0x0000 + + Rx multicast frames counter bits 15:0 + + Notes: + Incremented with each valid frame received on the receive FIFO interface and bit 0 of the destination address was '1' but not the broadcast address (all bits set '1' ). Pause frames are not counted. */ + unsigned int msmLineRxMulticastFramesCounter_0 : 16; /* 1E.9074.F:0 ROS Default = 0x0000 */ + /* Rx multicast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx Multicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9075.F:0 ROS MSM Line Rx Multicast Frames Counter 1 [F:0] + AQ_MsmLineRxMulticastFramesCounterRegister_HHD.u1.bits_1.msmLineRxMulticastFramesCounter_1 + + Default = 0x0000 + + Rx multicast frames counter bits 31:16 + + Notes: + Incremented with each valid frame received on the receive FIFO interface and bit 0 of the destination address was '1' but not the broadcast address (all bits set '1' ). Pause frames are not counted. */ + unsigned int msmLineRxMulticastFramesCounter_1 : 16; /* 1E.9075.F:0 ROS Default = 0x0000 */ + /* Rx multicast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxMulticastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx Broadcast Frames Counter Register: 1E.9078 */ +/* MSM Line Rx Broadcast Frames Counter Register: 1E.9078 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx Broadcast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9078.F:0 ROS MSM Line Rx Broadcast Frames Counter 0 [F:0] + AQ_MsmLineRxBroadcastFramesCounterRegister_HHD.u0.bits_0.msmLineRxBroadcastFramesCounter_0 + + Default = 0x0000 + + Rx broadcast frames counter bits 15:0 + + Notes: + Incremented with each valid frame received on the receive FIFO interface (FIFO) and all bits of the destination address were set '1'. */ + unsigned int msmLineRxBroadcastFramesCounter_0 : 16; /* 1E.9078.F:0 ROS Default = 0x0000 */ + /* Rx broadcast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx Broadcast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9079.F:0 ROS MSM Line Rx Broadcast Frames Counter 1 [F:0] + AQ_MsmLineRxBroadcastFramesCounterRegister_HHD.u1.bits_1.msmLineRxBroadcastFramesCounter_1 + + Default = 0x0000 + + Rx broadcast frames counter bits 31:16 + + Notes: + Incremented with each valid frame received on the receive FIFO interface (FIFO) and all bits of the destination address were set '1'. */ + unsigned int msmLineRxBroadcastFramesCounter_1 : 16; /* 1E.9079.F:0 ROS Default = 0x0000 */ + /* Rx broadcast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxBroadcastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Tx Errors Counter Register: 1E.907C */ +/* MSM Line Tx Errors Counter Register: 1E.907C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Tx Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.907C.F:0 ROS MSM Line Tx Errors Counter 0 [F:0] + AQ_MsmLineTxErrorsCounterRegister_HHD.u0.bits_0.msmLineTxErrorsCounter_0 + + Default = 0x0000 + + Rx errors counter bits 15:0 + + Notes: + Number of frames transmitted with error: + - FIFO Overflow Errors + - FIFO Underflow Errors */ + unsigned int msmLineTxErrorsCounter_0 : 16; /* 1E.907C.F:0 ROS Default = 0x0000 */ + /* Rx errors counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Tx Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.907D.F:0 ROS MSM Line Tx Errors Counter 1 [F:0] + AQ_MsmLineTxErrorsCounterRegister_HHD.u1.bits_1.msmLineTxErrorsCounter_1 + + Default = 0x0000 + + Tx errors counter bits 31:16 + + Notes: + Number of frames transmitted with error: + - FIFO Overflow Errors + - FIFO Underflow Errors */ + unsigned int msmLineTxErrorsCounter_1 : 16; /* 1E.907D.F:0 ROS Default = 0x0000 */ + /* Tx errors counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineTxErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Tx Unicast Frames Counter Register: 1E.9084 */ +/* MSM Line Tx Unicast Frames Counter Register: 1E.9084 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Tx Unicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9084.F:0 ROS MSM Line Tx Unicast Frames Counter 0 [F:0] + AQ_MsmLineTxUnicastFramesCounterRegister_HHD.u0.bits_0.msmLineTxUnicastFramesCounter_0 + + Default = 0x0000 + + Tx unicast frames counter bits 15:0 + + Notes: + Incremented with each frame written to the FIFO interface and bit 0 of the destination address set to '0'. */ + unsigned int msmLineTxUnicastFramesCounter_0 : 16; /* 1E.9084.F:0 ROS Default = 0x0000 */ + /* Tx unicast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Tx Unicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9085.F:0 ROS MSM Line Tx Unicast Frames Counter 1 [F:0] + AQ_MsmLineTxUnicastFramesCounterRegister_HHD.u1.bits_1.msmLineTxUnicastFramesCounter_1 + + Default = 0x0000 + + Tx unicast frames counter bits 31:16 + + Notes: + Incremented with each frame written to the FIFO interface and bit 0 of the destination address set to '0'. */ + unsigned int msmLineTxUnicastFramesCounter_1 : 16; /* 1E.9085.F:0 ROS Default = 0x0000 */ + /* Tx unicast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineTxUnicastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Tx Multicast Frames Counter Register: 1E.9088 */ +/* MSM Line Tx Multicast Frames Counter Register: 1E.9088 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Tx Multicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9088.F:0 ROS MSM Line Tx Multicast Frames Counter 0 [F:0] + AQ_MsmLineTxMulticastFramesCounterRegister_HHD.u0.bits_0.msmLineTxMulticastFramesCounter_0 + + Default = 0x0000 + + Tx multicast frames counter bits 15:0 + + Notes: + Incremented with each frame written to the FIFO interface and bit 0 of the destination address set to '1' but not the broadcast address (all bits '1'). */ + unsigned int msmLineTxMulticastFramesCounter_0 : 16; /* 1E.9088.F:0 ROS Default = 0x0000 */ + /* Tx multicast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Tx Multicast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.9089.F:0 ROS MSM Line Tx Multicast Frames Counter 1 [F:0] + AQ_MsmLineTxMulticastFramesCounterRegister_HHD.u1.bits_1.msmLineTxMulticastFramesCounter_1 + + Default = 0x0000 + + Tx multicast frames counter bits 31:16 + + Notes: + Incremented with each frame written to the FIFO interface and bit 0 of the destination address set to '1' but not the broadcast address (all bits '1'). */ + unsigned int msmLineTxMulticastFramesCounter_1 : 16; /* 1E.9089.F:0 ROS Default = 0x0000 */ + /* Tx multicast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineTxMulticastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Tx Broadcast Frames Counter Register: 1E.908C */ +/* MSM Line Tx Broadcast Frames Counter Register: 1E.908C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Tx Broadcast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.908C.F:0 ROS MSM Line Tx Broadcast Frames Counter 0 [F:0] + AQ_MsmLineTxBroadcastFramesCounterRegister_HHD.u0.bits_0.msmLineTxBroadcastFramesCounter_0 + + Default = 0x0000 + + Tx broadcast frames counter bits 15:0 + + Notes: + Incremented with each frame written to the FIFO interface and all bits of the destination address set to '1'. */ + unsigned int msmLineTxBroadcastFramesCounter_0 : 16; /* 1E.908C.F:0 ROS Default = 0x0000 */ + /* Tx broadcast frames counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Tx Broadcast Frames Counter Register */ + union + { + struct + { + /*! \brief 1E.908D.F:0 ROS MSM Line Tx Broadcast Frames Counter 1 [F:0] + AQ_MsmLineTxBroadcastFramesCounterRegister_HHD.u1.bits_1.msmLineTxBroadcastFramesCounter_1 + + Default = 0x0000 + + Tx broadcast frames counter bits 31:16 + + Notes: + Incremented with each frame written to the FIFO interface and all bits of the destination address set to '1'. */ + unsigned int msmLineTxBroadcastFramesCounter_1 : 16; /* 1E.908D.F:0 ROS Default = 0x0000 */ + /* Tx broadcast frames counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineTxBroadcastFramesCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief MSM Line Rx Errors Counter Register: 1E.90C8 */ +/* MSM Line Rx Errors Counter Register: 1E.90C8 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of MSM Line Rx Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.90C8.F:0 ROS MSM Line Rx Errors Counter 0 [F:0] + AQ_MsmLineRxErrorsCounterRegister_HHD.u0.bits_0.msmLineRxErrorsCounter_0 + + Default = 0x0000 + + Rx errors counter bits 15:0 + + Notes: + Number of frames received with error: + - FIFO Overflow Errors + - CRC Errors + - Payload Length Errors + - Jabber and Oversized Errors + - Alignment Errors + - The dedicated Error Code (0xfe, not a code error) was received */ + unsigned int msmLineRxErrorsCounter_0 : 16; /* 1E.90C8.F:0 ROS Default = 0x0000 */ + /* Rx errors counter bits 15:0 */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of MSM Line Rx Errors Counter Register */ + union + { + struct + { + /*! \brief 1E.90C9.F:0 ROS MSM Line Rx Errors Counter 1 [F:0] + AQ_MsmLineRxErrorsCounterRegister_HHD.u1.bits_1.msmLineRxErrorsCounter_1 + + Default = 0x0000 + + Rx errors counter bits 31:16 + + Notes: + Number of frames received with error: + - FIFO Overflow Errors + - CRC Errors + - Payload Length Errors + - Jabber and Oversized Errors + - Alignment Errors + - The dedicated Error Code (0xfe, not a code error) was received */ + unsigned int msmLineRxErrorsCounter_1 : 16; /* 1E.90C9.F:0 ROS Default = 0x0000 */ + /* Rx errors counter bits 31:16 */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_MsmLineRxErrorsCounterRegister_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Control: 1E.C000 */ +/* Global Control: 1E.C000 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Control */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Control */ + union + { + struct + { + /*! \brief 1E.C001.F R/W uP Reset + AQ_GlobalControl_HHD.u1.bits_1.upReset + + Default = 0x0 + + 1 = Reset + + + Notes: + Resets the uP and the PIF master and slave bus. Will be active for a minimum of 100 microseconds. */ + unsigned int upReset : 1; /* 1E.C001.F R/W Default = 0x0 */ + /* 1 = Reset + */ + unsigned int reserved0 : 8; + /*! \brief 1E.C001.6 R/W uP Run Stall Override + AQ_GlobalControl_HHD.u1.bits_1.upRunStallOverride + + Default = 0x0 + + 0 = uP Run Stall from "MDIO Boot Load" pin. + 1 = uP Run Stall from See MCP Run Stall bit + + + + Notes: + This bit selects the uP Run Stall from either the "MDIO Boot Load" pin or the See MCP Run Stall bit. Pin no longer brought out as deprecated. */ + unsigned int upRunStallOverride : 1; /* 1E.C001.6 R/W Default = 0x0 */ + /* 0 = uP Run Stall from "MDIO Boot Load" pin. + 1 = uP Run Stall from See MCP Run Stall bit + + */ + unsigned int reserved1 : 5; + /*! \brief 1E.C001.0 R/W uP Run Stall + AQ_GlobalControl_HHD.u1.bits_1.upRunStall + + Default = 0x0 + + 1 = uP Run Stall + 0 = uP normal mode + + + Notes: + Deactivates the uP. */ + unsigned int upRunStall : 1; /* 1E.C001.0 R/W Default = 0x0 */ + /* 1 = uP Run Stall + 0 = uP normal mode + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalControl_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Reset Control: 1E.C006 */ +/* Global Reset Control: 1E.C006 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Reset Control */ + union + { + struct + { + unsigned int reserved0 : 1; + /*! \brief 1E.C006.E R/WPD Global MMD Reset Disable + AQ_GlobalResetControl_HHD.u0.bits_0.globalMMD_ResetDisable + + Provisionable Default = 0x0 + + 1 = Disable the S/W reset to the Global MMD registers + 0 = Enable the S/W reset to the Global MMD registers + + + Notes: + Setting this bit prevents a Global S/W reset or Global S/W reset from resetting the Global MMD registers */ + unsigned int globalMMD_ResetDisable : 1; /* 1E.C006.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Disable the S/W reset to the Global MMD registers + 0 = Enable the S/W reset to the Global MMD registers + */ + unsigned int reserved1 : 14; + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalResetControl_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Diagnostic Provisioning: 1E.C400 */ +/* Global Diagnostic Provisioning: 1E.C400 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Diagnostic Provisioning */ + union + { + struct + { + /*! \brief 1E.C400.F R/WPD Enable Diagnostics + AQ_GlobalDiagnosticProvisioning_HHD.u0.bits_0.enableDiagnostics + + Provisionable Default = 0x1 + + 1 = Chip performs diagnostics on power-up + */ + unsigned int enableDiagnostics : 1; /* 1E.C400.F R/WPD Provisionable Default = 0x1 */ + /* 1 = Chip performs diagnostics on power-up */ + unsigned int reserved0 : 15; + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalDiagnosticProvisioning_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Thermal Provisioning: 1E.C420 */ +/* Global Thermal Provisioning: 1E.C420 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Thermal Provisioning */ + union + { + struct + { + /*! \brief 1E.C420.F:0 R/WPD Reserved 0 [F:0] + AQ_GlobalThermalProvisioning_HHD.u0.bits_0.reserved_0 + + Provisionable Default = 0x0000 + + Internal reserved - do not modify + + */ + unsigned int reserved_0 : 16; /* 1E.C420.F:0 R/WPD Provisionable Default = 0x0000 */ + /* Internal reserved - do not modify + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Thermal Provisioning */ + union + { + struct + { + /*! \brief 1E.C421.F:0 R/WPD High Temp Failure Threshold [F:0] + AQ_GlobalThermalProvisioning_HHD.u1.bits_1.highTempFailureThreshold + + Provisionable Default = 0x4600 + + [F:0] of high temperature failure threshold + + Notes: + 2's complement value with the LSB representing 1/256 of a degree Celsius. This corresponds to -40 degreesC = 0xD800. Default is 70 degreesC. + + In XENPAK mode, F/W will use the XENPAK register 1.A000 - 1.A001: instead of this register. + + NOTE! All Thresholds are orthogonal and can be set to any value regardless the value of the other thresholds. i.e. High-Temperature-Warning (1E.C423) could be higher than High-Temperature-Failure (1E.C421). */ + unsigned int highTempFailureThreshold : 16; /* 1E.C421.F:0 R/WPD Provisionable Default = 0x4600 */ + /* [F:0] of high temperature failure threshold */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Thermal Provisioning */ + union + { + struct + { + /*! \brief 1E.C422.F:0 R/WPD Low Temp Failure Threshold [F:0] + AQ_GlobalThermalProvisioning_HHD.u2.bits_2.lowTempFailureThreshold + + Provisionable Default = 0x0000 + + [F:0] of low temperature failure threshold + + Notes: + 2's complement value with the LSB representing 1/256 of a degree Celsius. This corresponds to -40 degreesC = 0xD800. Default is 0 degreesC. + + In XENPAK mode, F/W will use the XENPAK register 1.A002 - 1.A003: instead of this register. + + NOTE! All Thresholds are orthogonal and can be set to any value regardless the value of the other thresholds. i.e. High-Temperature-Warning (1E.C423) could be higher than High-Temperature-Failure (1E.C421). */ + unsigned int lowTempFailureThreshold : 16; /* 1E.C422.F:0 R/WPD Provisionable Default = 0x0000 */ + /* [F:0] of low temperature failure threshold */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global Thermal Provisioning */ + union + { + struct + { + /*! \brief 1E.C423.F:0 R/WPD High Temp Warning Threshold [F:0] + AQ_GlobalThermalProvisioning_HHD.u3.bits_3.highTempWarningThreshold + + Provisionable Default = 0x3C00 + + [F:0] of high temperature warning threshold + + Notes: + 2's complement value with the LSB representing 1/256 of a degree Celsius. This corresponds to -40 degreesC = 0xD008. Default is 60 degreesC. + + In XENPAK mode, F/W will use the XENPAK register 1.A004 - 1.A005: instead of this register. + + NOTE! All Thresholds are orthogonal and can be set to any value regardless the value of the other thresholds. i.e. High-Temperature-Warning (1E.C423) could be higher than High-Temperature-Failure (1E.C421). */ + unsigned int highTempWarningThreshold : 16; /* 1E.C423.F:0 R/WPD Provisionable Default = 0x3C00 */ + /* [F:0] of high temperature warning threshold */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global Thermal Provisioning */ + union + { + struct + { + /*! \brief 1E.C424.F:0 R/WPD Low Temp Warning Threshold [F:0] + AQ_GlobalThermalProvisioning_HHD.u4.bits_4.lowTempWarningThreshold + + Provisionable Default = 0x0A00 + + [F:0] of low temperature warning threshold + + Notes: + 2's complement value with the LSB representing 1/256 of a degree Celsius. This corresponds to -40 degreesC = 0xD800. Default is 10 degreesC. + + In XENPAK mode, F/W will use the XENPAK register 1.A006 - 1.A007: instead of this register. + + NOTE! All Thresholds are orthogonal and can be set to any value regardless the value of the other thresholds. i.e. High-Temperature-Warning (1E.C423) could be higher than High-Temperature-Failure (1E.C421). */ + unsigned int lowTempWarningThreshold : 16; /* 1E.C424.F:0 R/WPD Provisionable Default = 0x0A00 */ + /* [F:0] of low temperature warning threshold */ + } bits_4; + uint16_t word_4; + } u4; +} AQ_GlobalThermalProvisioning_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global LED Provisioning: 1E.C430 */ +/* Global LED Provisioning: 1E.C430 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 2; + /*! \brief 1E.C430.D:9 R/WPD Reserved Provisioning C430 [4:0] + AQ_GlobalLedProvisioning_HHD.u0.bits_0.reservedProvisioningC430 + + Provisionable Default = 0x00 + + Reserved for future use + */ + unsigned int reservedProvisioningC430 : 5; /* 1E.C430.D:9 R/WPD Provisionable Default = 0x00 */ + /* Reserved for future use */ + /*! \brief 1E.C430.8 R/WPD LED #0 Manual Set + AQ_GlobalLedProvisioning_HHD.u0.bits_0.led_0ManualSet + + Provisionable Default = 0x0 + + 1 = LED On + + */ + unsigned int led_0ManualSet : 1; /* 1E.C430.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED On + */ + /*! \brief 1E.C430.7 R/WPD LED #0 10 Gb/s Link Established + AQ_GlobalLedProvisioning_HHD.u0.bits_0.led_0_10Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 10 Gb/s + + */ + unsigned int led_0_10Gb_sLinkEstablished : 1; /* 1E.C430.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 10 Gb/s + */ + /*! \brief 1E.C430.6 R/WPD LED #0 1 Gb/s Link Established + AQ_GlobalLedProvisioning_HHD.u0.bits_0.led_0_1Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 1 Gb/s + + */ + unsigned int led_0_1Gb_sLinkEstablished : 1; /* 1E.C430.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 1 Gb/s + */ + /*! \brief 1E.C430.5 R/WPD LED #0 100 Mb/s Link Established + AQ_GlobalLedProvisioning_HHD.u0.bits_0.led_0_100Mb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 100 Mb/s. + + */ + unsigned int led_0_100Mb_sLinkEstablished : 1; /* 1E.C430.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 100 Mb/s. + */ + /*! \brief 1E.C430.4 R/WPD LED #0 Connecting + AQ_GlobalLedProvisioning_HHD.u0.bits_0.led_0Connecting + + Provisionable Default = 0x0 + + 1 = LED is on when attempting to connect. + + */ + unsigned int led_0Connecting : 1; /* 1E.C430.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when attempting to connect. + */ + /*! \brief 1E.C430.3 R/WPD LED #0 Receive Activity + AQ_GlobalLedProvisioning_HHD.u0.bits_0.led_0ReceiveActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on receive activity + + */ + unsigned int led_0ReceiveActivity : 1; /* 1E.C430.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on receive activity + */ + /*! \brief 1E.C430.2 R/WPD LED #0 Transmit Activity + AQ_GlobalLedProvisioning_HHD.u0.bits_0.led_0TransmitActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on transmit activity + + */ + unsigned int led_0TransmitActivity : 1; /* 1E.C430.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on transmit activity + */ + /*! \brief 1E.C430.1:0 R/WPD LED #0 Activity Stretch [1:0] + AQ_GlobalLedProvisioning_HHD.u0.bits_0.led_0ActivityStretch + + Provisionable Default = 0x3 + + [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + + */ + unsigned int led_0ActivityStretch : 2; /* 1E.C430.1:0 R/WPD Provisionable Default = 0x3 */ + /* [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 2; + /*! \brief 1E.C431.D:9 R/WPD Reserved Provisioning C431 [4:0] + AQ_GlobalLedProvisioning_HHD.u1.bits_1.reservedProvisioningC431 + + Provisionable Default = 0x00 + + Reserved for future use + */ + unsigned int reservedProvisioningC431 : 5; /* 1E.C431.D:9 R/WPD Provisionable Default = 0x00 */ + /* Reserved for future use */ + /*! \brief 1E.C431.8 R/WPD LED #1 Manual Set + AQ_GlobalLedProvisioning_HHD.u1.bits_1.led_1ManualSet + + Provisionable Default = 0x0 + + 1 = LED On + + */ + unsigned int led_1ManualSet : 1; /* 1E.C431.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED On + */ + /*! \brief 1E.C431.7 R/WPD LED #1 10 Gb/s Link Established + AQ_GlobalLedProvisioning_HHD.u1.bits_1.led_1_10Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 10 Gb/s + + */ + unsigned int led_1_10Gb_sLinkEstablished : 1; /* 1E.C431.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 10 Gb/s + */ + /*! \brief 1E.C431.6 R/WPD LED #1 1 Gb/s Link Established + AQ_GlobalLedProvisioning_HHD.u1.bits_1.led_1_1Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 1 Gb/s + + */ + unsigned int led_1_1Gb_sLinkEstablished : 1; /* 1E.C431.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 1 Gb/s + */ + /*! \brief 1E.C431.5 R/WPD LED #1 100 Mb/s Link Established + AQ_GlobalLedProvisioning_HHD.u1.bits_1.led_1_100Mb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 100 Mb/s. + + */ + unsigned int led_1_100Mb_sLinkEstablished : 1; /* 1E.C431.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 100 Mb/s. + */ + /*! \brief 1E.C431.4 R/WPD LED #1 Connecting + AQ_GlobalLedProvisioning_HHD.u1.bits_1.led_1Connecting + + Provisionable Default = 0x0 + + 1 = LED is on when attempting to connect. + + */ + unsigned int led_1Connecting : 1; /* 1E.C431.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when attempting to connect. + */ + /*! \brief 1E.C431.3 R/WPD LED #1 Receive Activity + AQ_GlobalLedProvisioning_HHD.u1.bits_1.led_1ReceiveActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on receive activity + + */ + unsigned int led_1ReceiveActivity : 1; /* 1E.C431.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on receive activity + */ + /*! \brief 1E.C431.2 R/WPD LED #1 Transmit Activity + AQ_GlobalLedProvisioning_HHD.u1.bits_1.led_1TransmitActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on transmit activity + + */ + unsigned int led_1TransmitActivity : 1; /* 1E.C431.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on transmit activity + */ + /*! \brief 1E.C431.1:0 R/WPD LED #1 Activity Stretch [1:0] + AQ_GlobalLedProvisioning_HHD.u1.bits_1.led_1ActivityStretch + + Provisionable Default = 0x3 + + [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + + */ + unsigned int led_1ActivityStretch : 2; /* 1E.C431.1:0 R/WPD Provisionable Default = 0x3 */ + /* [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 2; + /*! \brief 1E.C432.D:9 R/WPD Reserved Provisioning C432 [4:0] + AQ_GlobalLedProvisioning_HHD.u2.bits_2.reservedProvisioningC432 + + Provisionable Default = 0x00 + + Reserved for future use + */ + unsigned int reservedProvisioningC432 : 5; /* 1E.C432.D:9 R/WPD Provisionable Default = 0x00 */ + /* Reserved for future use */ + /*! \brief 1E.C432.8 R/WPD LED #2 Manual Set + AQ_GlobalLedProvisioning_HHD.u2.bits_2.led_2ManualSet + + Provisionable Default = 0x0 + + 1 = LED On + + */ + unsigned int led_2ManualSet : 1; /* 1E.C432.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED On + */ + /*! \brief 1E.C432.7 R/WPD LED #2 10 Gb/s Link Established + AQ_GlobalLedProvisioning_HHD.u2.bits_2.led_2_10Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 10 Gb/s + + */ + unsigned int led_2_10Gb_sLinkEstablished : 1; /* 1E.C432.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 10 Gb/s + */ + /*! \brief 1E.C432.6 R/WPD LED #2 1 Gb/s Link Established + AQ_GlobalLedProvisioning_HHD.u2.bits_2.led_2_1Gb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 1 Gb/s + + */ + unsigned int led_2_1Gb_sLinkEstablished : 1; /* 1E.C432.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 1 Gb/s + */ + /*! \brief 1E.C432.5 R/WPD LED #2 100 Mb/s Link Established + AQ_GlobalLedProvisioning_HHD.u2.bits_2.led_2_100Mb_sLinkEstablished + + Provisionable Default = 0x0 + + 1 = LED is on when link connects at 100 Mb/s. + */ + unsigned int led_2_100Mb_sLinkEstablished : 1; /* 1E.C432.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when link connects at 100 Mb/s. */ + /*! \brief 1E.C432.4 R/WPD LED #2 Connecting + AQ_GlobalLedProvisioning_HHD.u2.bits_2.led_2Connecting + + Provisionable Default = 0x0 + + 1 = LED is on when attempting to connect. + + */ + unsigned int led_2Connecting : 1; /* 1E.C432.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED is on when attempting to connect. + */ + /*! \brief 1E.C432.3 R/WPD LED #2 Receive Activity + AQ_GlobalLedProvisioning_HHD.u2.bits_2.led_2ReceiveActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on receive activity + + */ + unsigned int led_2ReceiveActivity : 1; /* 1E.C432.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on receive activity + */ + /*! \brief 1E.C432.2 R/WPD LED #2 Transmit Activity + AQ_GlobalLedProvisioning_HHD.u2.bits_2.led_2TransmitActivity + + Provisionable Default = 0x0 + + 1 = LED toggles on transmit activity + + */ + unsigned int led_2TransmitActivity : 1; /* 1E.C432.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED toggles on transmit activity + */ + /*! \brief 1E.C432.1:0 R/WPD LED #2 Activity Stretch [1:0] + AQ_GlobalLedProvisioning_HHD.u2.bits_2.led_2ActivityStretch + + Provisionable Default = 0x3 + + [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + + */ + unsigned int led_2ActivityStretch : 2; /* 1E.C432.1:0 R/WPD Provisionable Default = 0x3 */ + /* [1:0] + 0x3 = stretch activity by 100 ms + 0x2 = stretch activity by 60 ms + 0x1 = stretch activity by 28 ms + 0x0 = no stretching + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_5; + uint16_t word_5; + } u5; + /*! \brief Union for bit and word level access of word 6 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_6; + uint16_t word_6; + } u6; + /*! \brief Union for bit and word level access of word 7 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 15; + /*! \brief 1E.C437.0 R/WPD LED Operation Mode + AQ_GlobalLedProvisioning_HHD.u7.bits_7.ledOperationMode + + Provisionable Default = 0x0 + + 1 = LED link activity in Mode #2 + 0 = LED link activity in Aquantia classic mode + + + Notes: + When set to 1, the LED blinking rate is based on Mode #2 algorithm. When set to 0, the LED blinking rate is based on the classic Aquantia algorithm. */ + unsigned int ledOperationMode : 1; /* 1E.C437.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = LED link activity in Mode #2 + 0 = LED link activity in Aquantia classic mode + */ + } bits_7; + uint16_t word_7; + } u7; + /*! \brief Dummy union to fill space in the structure Global LED Provisioning */ + union + { + struct + { + unsigned int reserved : 16; + } bits_8; + uint16_t word_8; + } u8; + /*! \brief Dummy union to fill space in the structure Global LED Provisioning */ + union + { + struct + { + unsigned int reserved : 16; + } bits_9; + uint16_t word_9; + } u9; + /*! \brief Dummy union to fill space in the structure Global LED Provisioning */ + union + { + struct + { + unsigned int reserved : 16; + } bits_10; + uint16_t word_10; + } u10; + /*! \brief Dummy union to fill space in the structure Global LED Provisioning */ + union + { + struct + { + unsigned int reserved : 16; + } bits_11; + uint16_t word_11; + } u11; + /*! \brief Dummy union to fill space in the structure Global LED Provisioning */ + union + { + struct + { + unsigned int reserved : 16; + } bits_12; + uint16_t word_12; + } u12; + /*! \brief Dummy union to fill space in the structure Global LED Provisioning */ + union + { + struct + { + unsigned int reserved : 16; + } bits_13; + uint16_t word_13; + } u13; + /*! \brief Union for bit and word level access of word 14 of Global LED Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_14; + uint16_t word_14; + } u14; +} AQ_GlobalLedProvisioning_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global General Provisioning: 1E.C440 */ +/* Global General Provisioning: 1E.C440 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global General Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global General Provisioning */ + union + { + struct + { + unsigned int reserved0 : 1; + /*! \brief 1E.C441.E R/WPD MDIO Broadcast Mode Enable + AQ_GlobalGeneralProvisioning_HHD.u1.bits_1.mdioBroadcastModeEnable + + Provisionable Default = 0x0 + + 1 = Enable broadcast on address set in 1E.C446 + 0 = Disable broadcast on n address set in 1E.C446 + + + Notes: + When enabled, writes and load MMD address opcodes are supported. Read opcodes are ignored. */ + unsigned int mdioBroadcastModeEnable : 1; /* 1E.C441.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable broadcast on address set in 1E.C446 + 0 = Disable broadcast on n address set in 1E.C446 + */ + /*! \brief 1E.C441.D R/WPD MDIO Read MSW First Enable + AQ_GlobalGeneralProvisioning_HHD.u1.bits_1.mdioReadMSW_FirstEnable + + Provisionable Default = 0x0 + + 1 = MSW of counter must be read first + 0 = LSW of counter must be read first + + + Notes: + This bit configures whether the MSW or LSW must be read first for counters greater than 16 bits. */ + unsigned int mdioReadMSW_FirstEnable : 1; /* 1E.C441.D R/WPD Provisionable Default = 0x0 */ + /* 1 = MSW of counter must be read first + 0 = LSW of counter must be read first + */ + unsigned int reserved1 : 8; + /*! \brief 1E.C441.4 R/WPD MDIO Drive Configuration + AQ_GlobalGeneralProvisioning_HHD.u1.bits_1.mdioDriveConfiguration + + Provisionable Default = 0x0 + + 0 = MDIO driver is in normal mode + 1 = MDIO driver is in open drain mode + + + Notes: + When the MDIO driver is in open drain mode during a read cycle, "0" data will be actively driven out of the MDIO, "1" data will set the MDIO driver in high impedance state and an external pullup will set the MDIO line to "1". The Turn-Around "0" will also be actively driven out of the MDIO, therefore in open drain mode, the Turn-Around is still "Z0". */ + unsigned int mdioDriveConfiguration : 1; /* 1E.C441.4 R/WPD Provisionable Default = 0x0 */ + /* 0 = MDIO driver is in normal mode + 1 = MDIO driver is in open drain mode + */ + /*! \brief 1E.C441.3 R/WPD MDIO Preamble Detection Disable + AQ_GlobalGeneralProvisioning_HHD.u1.bits_1.mdioPreambleDetectionDisable + + Provisionable Default = 0x0 + + 1 = Suppress preamble detection on MDIO + 0 = Enable preamble detection on MDIO + + */ + unsigned int mdioPreambleDetectionDisable : 1; /* 1E.C441.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = Suppress preamble detection on MDIO + 0 = Enable preamble detection on MDIO + */ + unsigned int reserved2 : 1; + unsigned int reserved3 : 2; + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global General Provisioning */ + union + { + struct + { + unsigned int reserved0 : 15; + /*! \brief 1E.C442.0 R/W Daisy Chain Reset + AQ_GlobalGeneralProvisioning_HHD.u2.bits_2.daisyChainReset + + Default = 0x0 + + 1 = Reset the daisy chain + + + Notes: + Toggling this bit from 0 to 1 will reload the IRAM and DRAM and reset the uP. The uP will be in uP run stall during the reload process. After the reload process, uP run stall will be de-asserted and the uP reset will be asserted. Note that before setting this bit, the See Soft Reset bit needs to be de-asserted. */ + unsigned int daisyChainReset : 1; /* 1E.C442.0 R/W Default = 0x0 */ + /* 1 = Reset the daisy chain + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global General Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global General Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of Global General Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_5; + uint16_t word_5; + } u5; + /*! \brief Union for bit and word level access of word 6 of Global General Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_6; + uint16_t word_6; + } u6; + /*! \brief Union for bit and word level access of word 7 of Global General Provisioning */ + union + { + struct + { + unsigned int reserved0 : 11; + /*! \brief 1E.C447.4:0 R/WPD MDIO Broadcast Address Configuration [4:0] + AQ_GlobalGeneralProvisioning_HHD.u7.bits_7.mdioBroadcastAddressConfiguration + + Provisionable Default = 0x1F + + Broadcast address + + + Notes: + Allows setting the broadcast address. By default this is set to 0x1F */ + unsigned int mdioBroadcastAddressConfiguration : 5; /* 1E.C447.4:0 R/WPD Provisionable Default = 0x1F */ + /* Broadcast address + */ + } bits_7; + uint16_t word_7; + } u7; + /*! \brief Union for bit and word level access of word 8 of Global General Provisioning */ + union + { + struct + { + unsigned int reserved0 : 16; + } bits_8; + uint16_t word_8; + } u8; + /*! \brief Union for bit and word level access of word 9 of Global General Provisioning */ + union + { + struct + { + unsigned int reserved0 : 9; + /*! \brief 1E.C449.6:0 R/W MDIO Preamble Length [6:0] + AQ_GlobalGeneralProvisioning_HHD.u9.bits_9.mdioPreambleLength + + Default = 0x02 + + MDIO Preamble Length + + */ + unsigned int mdioPreambleLength : 7; /* 1E.C449.6:0 R/W Default = 0x02 */ + /* MDIO Preamble Length + */ + } bits_9; + uint16_t word_9; + } u9; +} AQ_GlobalGeneralProvisioning_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global NVR Provisioning: 1E.C450 */ +/* Global NVR Provisioning: 1E.C450 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global NVR Provisioning */ + union + { + struct + { + unsigned int reserved0 : 5; + /*! \brief 1E.C450.A:8 R/WPD NVR Data Length [2:0] + AQ_GlobalNvrProvisioning_HHD.u0.bits_0.nvrDataLength + + Provisionable Default = 0x4 + + NVR data length ranges from 0 bytes to 4 bytes + + + Notes: + This sets the length of the data burst used in read and write operations. + */ + unsigned int nvrDataLength : 3; /* 1E.C450.A:8 R/WPD Provisionable Default = 0x4 */ + /* NVR data length ranges from 0 bytes to 4 bytes + */ + unsigned int reserved1 : 1; + /*! \brief 1E.C450.6:4 R/WPD NVR Dummy Length [2:0] + AQ_GlobalNvrProvisioning_HHD.u0.bits_0.nvrDummyLength + + Provisionable Default = 0x0 + + NVR dummy length ranges from 0 bytes to 4 bytes + + + Notes: + This sets the length of the dummy field used in some manufacturer's read status and write status operations. + */ + unsigned int nvrDummyLength : 3; /* 1E.C450.6:4 R/WPD Provisionable Default = 0x0 */ + /* NVR dummy length ranges from 0 bytes to 4 bytes + */ + unsigned int reserved2 : 2; + /*! \brief 1E.C450.1:0 R/WPD NVR Address Length [1:0] + AQ_GlobalNvrProvisioning_HHD.u0.bits_0.nvrAddressLength + + Provisionable Default = 0x2 + + NVR address length ranges from 0 bytes up to 3 bytes + + + Notes: + This sets the length of the address field used in read and write operations. Use of this field is enabled via Bit 8 of See Global NVR Provisioning 2: Address 1E.C451 . + */ + unsigned int nvrAddressLength : 2; /* 1E.C450.1:0 R/WPD Provisionable Default = 0x2 */ + /* NVR address length ranges from 0 bytes up to 3 bytes + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global NVR Provisioning */ + union + { + struct + { + unsigned int reserved0 : 7; + /*! \brief 1E.C451.8 R/WPD NVR Address Length Override + AQ_GlobalNvrProvisioning_HHD.u1.bits_1.nvrAddressLengthOverride + + Provisionable Default = 0x0 + + 0 = NVR address length is based on the "NVR_SIZE" pin. + 1 = NVR address length is based on the See NVR Address Length [1:0] register + + + Notes: + When this bit = 0 and NVR_SIZE pin = 0, the NVR address length is 2 bytes. When this bit = 0 and the NVR_SIZE pin = 1, the NVR address length is 3 bytes. When this bit = 1 the NVR address length is from the See NVR Address Length [1:0] */ + unsigned int nvrAddressLengthOverride : 1; /* 1E.C451.8 R/WPD Provisionable Default = 0x0 */ + /* 0 = NVR address length is based on the "NVR_SIZE" pin. + 1 = NVR address length is based on the See NVR Address Length [1:0] register + */ + /*! \brief 1E.C451.7:0 R/WPD NVR Clock Divide [7:0] + AQ_GlobalNvrProvisioning_HHD.u1.bits_1.nvrClockDivide + + Provisionable Default = 0xA0 + + NVR clock divide. Clock frequency is divided by the NVR clock divide + 1 + + */ + unsigned int nvrClockDivide : 8; /* 1E.C451.7:0 R/WPD Provisionable Default = 0xA0 */ + /* NVR clock divide. Clock frequency is divided by the NVR clock divide + 1 + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global NVR Provisioning */ + union + { + struct + { + unsigned int reserved0 : 14; + /*! \brief 1E.C452.1 R/W NVR Daisy Chain Clock Divide Override + AQ_GlobalNvrProvisioning_HHD.u2.bits_2.nvrDaisyChainClockDivideOverride + + Default = 0x0 + + 1 = Override NVR clock divide when in daisy chain master mode + + + Notes: + When in daisy chain master mode, the clock divide configuration is received from the FLASH. This bit will override the clock divide configuration from the FLASH with the See NVR Clock Divide [7:0] . */ + unsigned int nvrDaisyChainClockDivideOverride : 1; /* 1E.C452.1 R/W Default = 0x0 */ + /* 1 = Override NVR clock divide when in daisy chain master mode + */ + /*! \brief 1E.C452.0 R/W NVR Daisy Chain Disable + AQ_GlobalNvrProvisioning_HHD.u2.bits_2.nvrDaisyChainDisable + + Default = 0x0 + + 1 = Disable the Daisy Chain + + + Notes: + When in daisy chain master mode, the daisy chain and MDIO can both access the SPI. Setting this bit to 1 will disable the daisy chain from accessing the SPI and force it into a reset state. */ + unsigned int nvrDaisyChainDisable : 1; /* 1E.C452.0 R/W Default = 0x0 */ + /* 1 = Disable the Daisy Chain + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global NVR Provisioning */ + union + { + struct + { + unsigned int reserved0 : 11; + /*! \brief 1E.C453.4 R/W NVR Reset + AQ_GlobalNvrProvisioning_HHD.u3.bits_3.nvrReset + + Default = 0x0 + + 1 = Reset SPI + + */ + unsigned int nvrReset : 1; /* 1E.C453.4 R/W Default = 0x0 */ + /* 1 = Reset SPI + */ + unsigned int reserved1 : 4; + } bits_3; + uint16_t word_3; + } u3; +} AQ_GlobalNvrProvisioning_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Reserved Provisioning: 1E.C470 */ +/* Global Reserved Provisioning: 1E.C470 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Reserved Provisioning */ + union + { + struct + { + /*! \brief 1E.C470.F R/WPD Diagnostics Select + AQ_GlobalReservedProvisioning_HHD.u0.bits_0.diagnosticsSelect + + Provisionable Default = 0x0 + + 1 = Provide Extended MDI Diagnostics Information. + 0 = Provide normal cable diagnostics + + + Notes: + These bits select what sort of cable diagnostics to perform. For regular cable diagnostics, Bit F is set to zero, and the diagnostics are triggered by setting Bit 4. For extended diagnostics, Bit F is set to 1, and the desired extended diagnostics are selected by Bits E:D. The routine is then triggered by setting Bit 4. Each of the extended diagnostic routines present data for all for MDI pairs (A, B, C, D) consecutively, and after the data for each channel is gathered Bits F:D are reset. To get the data for the next pair, Bits F:D must be set back to the desired value (which must be the same as the initial channel). This continues until the data for all channels has been gathered. The address in memory where the data is stored is given in 1E.C802 and 1E.C804. + + For the case of PSD, the structure is as follows: + Int32 info + Int16 data[Len] + Info = Len << 16 | TxEnable << 8 | Pair (0 = A, etc.) + + For TDR: + Int32 info + Int16 tdr_A[Len] + Int16 tdr_B[Len] + Int16 tdr_C[Len] + Int16 tdr_D[Len] + + Info = Len << 16 | Channel + + TDR data is from the current pair to all other pairs. + + At the end of retrieving extended MDI diag data, the part will be reset. Conversely the only way to exit this routine once it starts is to issue a PMA reset. */ + unsigned int diagnosticsSelect : 1; /* 1E.C470.F R/WPD Provisionable Default = 0x0 */ + /* 1 = Provide Extended MDI Diagnostics Information. + 0 = Provide normal cable diagnostics + */ + /*! \brief 1E.C470.E:D R/WPD Extended MDI Diagnostics Select [1:0] + AQ_GlobalReservedProvisioning_HHD.u0.bits_0.extendedMdiDiagnosticsSelect + + Provisionable Default = 0x0 + + 0x0 = TDR Data + 0x1 = RFI Channel PSD + 0x2 = Noise PSD while the local Tx is Off + 0x3 = Noise PSD while the local Tx is On + + + Notes: + These bits select what sort of cable diagnostics to perform. For regular cable diagnostics, Bit F is set to zero, and the diagnostics are triggered by setting Bit 4. For extended diagnostics, Bit F is set to 1, and the desired extended diagnostics are selected by Bits E:D. The routine is then triggered by setting Bit 4. Each of the extended diagnostic routines present data for all for MDI pairs (A, B, C, D) consecutively, and after the data for each channel is gathered Bits F:D are reset. To get the data for the next pair, Bits F:D must be set back to the desired value (which must be the same as the initial channel). This continues until the data for all channels has been gathered. The address in memory where the data is stored is given in 1E.C802 and 1E.C804. + + For the case of PSD, the structure is as follows: + Int32 info + Int16 data[Len] + Info = Len << 16 | TxEnable << 8 | Pair (0 = A, etc.) + + For TDR: + Int32 info + Int16 tdr_A[Len] + Int16 tdr_B[Len] + Int16 tdr_C[Len] + Int16 tdr_D[Len] + + Info = Len << 16 | Channel + + TDR data is from the current pair to all other pairs. + + At the end of retrieving extended MDI diag data, the part will be reset. Conversely the only way to exit this routine once it starts is to issue a PMA reset. */ + unsigned int extendedMdiDiagnosticsSelect : 2; /* 1E.C470.E:D R/WPD Provisionable Default = 0x0 */ + /* 0x0 = TDR Data + 0x1 = RFI Channel PSD + 0x2 = Noise PSD while the local Tx is Off + 0x3 = Noise PSD while the local Tx is On + */ + unsigned int reserved0 : 5; + unsigned int reserved1 : 3; + /*! \brief 1E.C470.4 R/WSC Initiate Cable Diagnostics + AQ_GlobalReservedProvisioning_HHD.u0.bits_0.initiateCableDiagnostics + + Default = 0x0 + + 1 = Perform cable diagnostics + + + Notes: + Perform cable diagnostics regardless of link state. If link is up, setting this bit will cause the link to drop while diagnostics are performed. This bit is self-clearing upon completion of the cable diagnostics. + + NOTE!! This is a processor intensive operation. Completion of this operation can also be monitored via 1E.C831.F */ + unsigned int initiateCableDiagnostics : 1; /* 1E.C470.4 R/WSC Default = 0x0 */ + /* 1 = Perform cable diagnostics + */ + unsigned int reserved2 : 4; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Reserved Provisioning */ + union + { + struct + { + unsigned int reserved0 : 9; + /*! \brief 1E.C471.6 R/WuP Enable Daisy-Chain Hop-Count Override + AQ_GlobalReservedProvisioning_HHD.u1.bits_1.enableDaisy_chainHop_countOverride + + Default = 0x0 + + 1 = Hop-count is set by Bits 5:0 + 0 = Hop-count is determined by the daisy-chain + + + Notes: + Daisy-Chain Hop-Count Override should be used during MDIO boot-load operation, as the daisy-chain hop-count does not function when the daisy-chain is disabled (1E.C452.0). Setting this bit tells the processor where in the daisy-chain it is, so that the provisioning operation will function correctly. */ + unsigned int enableDaisy_chainHop_countOverride : 1; /* 1E.C471.6 R/WuP Default = 0x0 */ + /* 1 = Hop-count is set by Bits 5:0 + 0 = Hop-count is determined by the daisy-chain + */ + /*! \brief 1E.C471.5:0 R/WuP Daisy-Chain Hop-Count Override Value [5:0] + AQ_GlobalReservedProvisioning_HHD.u1.bits_1.daisy_chainHop_countOverrideValue + + Default = 0x00 + + The value to use for the PHY's daisy-chain hop-count. Valid values are from 0 -> 47 + + + Notes: + Daisy-Chain Hop-Count Override should be used during MDIO boot-load operation, as the daisy-chain hop-count does not function when the daisy-chain is disabled (1E.C452.0). Setting this bit tells the processor where in the daisy-chain it is, so that the provisioning operation will function correctly. */ + unsigned int daisy_chainHop_countOverrideValue : 6; /* 1E.C471.5:0 R/WuP Default = 0x00 */ + /* The value to use for the PHY's daisy-chain hop-count. Valid values are from 0 -> 47 + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Reserved Provisioning */ + union + { + struct + { + unsigned int reserved0 : 1; + /*! \brief 1E.C472.E R/WPD Enable VDD Power Supply Tuning + AQ_GlobalReservedProvisioning_HHD.u2.bits_2.enableVddPowerSupplyTuning + + Provisionable Default = 0x0 + + 1 = Enable external VDD power supply tuning + 0 = Disable external VDD power supply tuning is disabled + + + Notes: + This bit controls whether the PHY attempts to tune the external VDD power supply via the SMBus. This bit is only operational if the external supply is present. (See 1E.C472.6) */ + unsigned int enableVddPowerSupplyTuning : 1; /* 1E.C472.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable external VDD power supply tuning + 0 = Disable external VDD power supply tuning is disabled + */ + unsigned int reserved1 : 7; + /*! \brief 1E.C472.6 R/WPD Tunable External VDD Power Supply Present + AQ_GlobalReservedProvisioning_HHD.u2.bits_2.tunableExternalVddPowerSupplyPresent + + Provisionable Default = 0x0 + + 1 = Tunable external VDD power supply present + 0 = No tunable external VDD power supply present + + + Notes: + This bit must be set if tuning of external power supply is desired. */ + unsigned int tunableExternalVddPowerSupplyPresent : 1; /* 1E.C472.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = Tunable external VDD power supply present + 0 = No tunable external VDD power supply present + */ + /*! \brief 1E.C472.5:2 R/WPD External VDD Change Request [3:0] + AQ_GlobalReservedProvisioning_HHD.u2.bits_2.externalVddChangeRequest + + Provisionable Default = 0x0 + + The amount of VDD change requested by firmware, in mV (2's complement value). + + */ + unsigned int externalVddChangeRequest : 4; /* 1E.C472.5:2 R/WPD Provisionable Default = 0x0 */ + /* The amount of VDD change requested by firmware, in mV (2's complement value). + */ + /*! \brief 1E.C472.1 R/WPDuP Enable XENPAK Register Space + AQ_GlobalReservedProvisioning_HHD.u2.bits_2.enableXenpakRegisterSpace + + Provisionable Default = 0x0 + + 1 = XENPAK register space enabled + 0 = XENPAK register space disabled + + */ + unsigned int enableXenpakRegisterSpace : 1; /* 1E.C472.1 R/WPDuP Provisionable Default = 0x0 */ + /* 1 = XENPAK register space enabled + 0 = XENPAK register space disabled + */ + /*! \brief 1E.C472.0 R/WPDuP Enable 5th Channel RFI Cancellation + AQ_GlobalReservedProvisioning_HHD.u2.bits_2.enable_5thChannelRfiCancellation + + Provisionable Default = 0x0 + + 1 = 5th channel and RFI cancellers operation enabled + 0 = 5th channel AFE is powered down, 5th channel digital is clock gated, RFI cancellers are disabled + + + Notes: + Note: The value of this bit at the time of Autonegotiation sets the local PHY behavior until the next time Autonegotiation occurs. */ + unsigned int enable_5thChannelRfiCancellation : 1; /* 1E.C472.0 R/WPDuP Provisionable Default = 0x0 */ + /* 1 = 5th channel and RFI cancellers operation enabled + 0 = 5th channel AFE is powered down, 5th channel digital is clock gated, RFI cancellers are disabled + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global Reserved Provisioning */ + union + { + struct + { + unsigned int reserved0 : 5; + /*! \brief 1E.C473.A:8 R/WPD Rate Transition Request [2:0] + AQ_GlobalReservedProvisioning_HHD.u3.bits_3.rateTransitionRequest + + Provisionable Default = 0x0 + + 0 = No Transition + 1 = Reserved + 2 = Reserved + 3 = Retrain at 10G + 4 = Retrain at 5G + 5 = Retrain at 2.5G + 6 = Retrain at 1G + 7 = Reserved + + */ + unsigned int rateTransitionRequest : 3; /* 1E.C473.A:8 R/WPD Provisionable Default = 0x0 */ + /* 0 = No Transition + 1 = Reserved + 2 = Reserved + 3 = Retrain at 10G + 4 = Retrain at 5G + 5 = Retrain at 2.5G + 6 = Retrain at 1G + 7 = Reserved + */ + /*! \brief 1E.C473.7:0 R/WPD Training SNR [7:0] + AQ_GlobalReservedProvisioning_HHD.u3.bits_3.trainingSNR + + Provisionable Default = 0x00 + + SNR during 10G training on the worst channel. SNR is in steps of 0.1dB + + + Notes: + The SNR margin that is enjoyed by the worst channel, over and above the minimum SNR required to operate at a BER of 10-12. It is reported with 0.1 dB of resolution to an accuracy of 0.5 dB within the range of -12.7 dB to 12.7 dB. The number is in offset binary, with 0.0 dB represented by 0x8000. */ + unsigned int trainingSNR : 8; /* 1E.C473.7:0 R/WPD Provisionable Default = 0x00 */ + /* SNR during 10G training on the worst channel. SNR is in steps of 0.1dB + */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global Reserved Provisioning */ + union + { + struct + { + /*! \brief 1E.C474.F:1 R/WPD Reserved Provisioning 5 [F:1] + AQ_GlobalReservedProvisioning_HHD.u4.bits_4.reservedProvisioning_5 + + Provisionable Default = 0x0000 + + Reserved for future use + + */ + unsigned int reservedProvisioning_5 : 15; /* 1E.C474.F:1 R/WPD Provisionable Default = 0x0000 */ + /* Reserved for future use + */ + /*! \brief 1E.C474.0 R/W NVR Daisy Chain Kickstart + AQ_GlobalReservedProvisioning_HHD.u4.bits_4.nvrDaisyChainKickstart + + Default = 0x0 + + 1 = Kickstart the Daisy Chain + + + Notes: + When in daisy chain master mode, the PHY0 can kickstart the daisy chain. The kickstart will not reload the IRAM/DRAM or reset the uP for PHY0. It will just read the FLASH and transfer the FLASH data to the daisy chain. */ + unsigned int nvrDaisyChainKickstart : 1; /* 1E.C474.0 R/W Default = 0x0 */ + /* 1 = Kickstart the Daisy Chain + */ + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of Global Reserved Provisioning */ + union + { + struct + { + unsigned int reserved0 : 2; + /*! \brief 1E.C475.D R/WPD Smart Power-Down Status + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.smartPower_downStatus + + Provisionable Default = 0x0 + + 1 = Smart Power-Down Active + 0 = Smart Power-Down Inactive + + */ + unsigned int smartPower_downStatus : 1; /* 1E.C475.D R/WPD Provisionable Default = 0x0 */ + /* 1 = Smart Power-Down Active + 0 = Smart Power-Down Inactive + */ + /*! \brief 1E.C475.C R/WPD Reserved Provisioning 6 + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.reservedProvisioning_6 + + Provisionable Default = 0x0 + + Internal reserved - do not modify + + */ + unsigned int reservedProvisioning_6 : 1; /* 1E.C475.C R/WPD Provisionable Default = 0x0 */ + /* Internal reserved - do not modify + */ + /*! \brief 1E.C475.B R/WPD CFR LP Disable Timer + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.cfrLpDisableTimer + + Provisionable Default = 0x0 + + 1 = Link partner requires cfr_disable timer + 0 = Link partner does not require cfr_disable timer + + */ + unsigned int cfrLpDisableTimer : 1; /* 1E.C475.B R/WPD Provisionable Default = 0x0 */ + /* 1 = Link partner requires cfr_disable timer + 0 = Link partner does not require cfr_disable timer + */ + /*! \brief 1E.C475.A R/WPD CFR LP Extended Maxwait + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.cfrLpExtendedMaxwait + + Provisionable Default = 0x0 + + 1 = Link partner requires extended maxwait + 0 = Link partner does not require extended maxwait + + */ + unsigned int cfrLpExtendedMaxwait : 1; /* 1E.C475.A R/WPD Provisionable Default = 0x0 */ + /* 1 = Link partner requires extended maxwait + 0 = Link partner does not require extended maxwait + */ + /*! \brief 1E.C475.9 R/WPD CFR LP THP + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.cfrLpTHP + + Provisionable Default = 0x0 + + 1 = Link partner requires local PHY to enable THP + 0 = Link partner does not require local PHY to enable THP + + */ + unsigned int cfrLpTHP : 1; /* 1E.C475.9 R/WPD Provisionable Default = 0x0 */ + /* 1 = Link partner requires local PHY to enable THP + 0 = Link partner does not require local PHY to enable THP + */ + /*! \brief 1E.C475.8 R/WPD CFR LP Support + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.cfrLpSupport + + Provisionable Default = 0x0 + + 1 = Link partner supports Cisco Fast Retrain + 0 = Link partner does support Cisco Fast Retrain + + */ + unsigned int cfrLpSupport : 1; /* 1E.C475.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = Link partner supports Cisco Fast Retrain + 0 = Link partner does support Cisco Fast Retrain + */ + /*! \brief 1E.C475.7 R/WPD CFR Disable Timer + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.cfrDisableTimer + + Provisionable Default = 0x0 + + 1 = Local PHY requires cfr_disable timer + 0 = Local PHY does not require cfr_disable timer + + */ + unsigned int cfrDisableTimer : 1; /* 1E.C475.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = Local PHY requires cfr_disable timer + 0 = Local PHY does not require cfr_disable timer + */ + /*! \brief 1E.C475.6 R/WPD CFR Extended Maxwait + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.cfrExtendedMaxwait + + Provisionable Default = 0x0 + + 1 = Local PHY requires extended maxwait + 0 = Local PHY does not require extended maxwait + + */ + unsigned int cfrExtendedMaxwait : 1; /* 1E.C475.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = Local PHY requires extended maxwait + 0 = Local PHY does not require extended maxwait + */ + /*! \brief 1E.C475.5 R/WPD CFR THP + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.cfrTHP + + Provisionable Default = 0x0 + + 1 = Local PHY requires local PHY to enable THP + 0 = Local PHY does not require local PHY to enable THP + + */ + unsigned int cfrTHP : 1; /* 1E.C475.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = Local PHY requires local PHY to enable THP + 0 = Local PHY does not require local PHY to enable THP + */ + /*! \brief 1E.C475.4 R/WPD CFR Support + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.cfrSupport + + Provisionable Default = 0x0 + + 1 = Local PHY supports Cisco Fast Retrain + 0 = Local PHY does support Cisco Fast Retrain + + */ + unsigned int cfrSupport : 1; /* 1E.C475.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = Local PHY supports Cisco Fast Retrain + 0 = Local PHY does support Cisco Fast Retrain + */ + /*! \brief 1E.C475.3 R/WPD Deadlock Avoidance Enable + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.deadlockAvoidanceEnable + + Provisionable Default = 0x0 + + 1 = SPD with deadlock avoidance: PHY transmits autonegotiation pulses (FLPs) at a slower rate (~ 1 FLP/ 100ms) than specified by autonegotiation standard (~1 FLP / 8.25ms). Receiver is active and able to detect the pulses. + 0 = SPD without deadlock avoidance: PHY transmitter is shut down, no autonegotiation pulses are sent on the line but the receiver is active and able to detect the pulses + + */ + unsigned int deadlockAvoidanceEnable : 1; /* 1E.C475.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = SPD with deadlock avoidance: PHY transmits autonegotiation pulses (FLPs) at a slower rate (~ 1 FLP/ 100ms) than specified by autonegotiation standard (~1 FLP / 8.25ms). Receiver is active and able to detect the pulses. + 0 = SPD without deadlock avoidance: PHY transmitter is shut down, no autonegotiation pulses are sent on the line but the receiver is active and able to detect the pulses + */ + /*! \brief 1E.C475.2 R/WPD Smart Power-Down Enable + AQ_GlobalReservedProvisioning_HHD.u5.bits_5.smartPower_downEnable + + Provisionable Default = 0x0 + + 1 = Enable smart power down mode + 0 = Smart power-down mode disabled + + + Notes: + Smart power down (SPD) is the lowest power mode at which PHY is able to autonegotiate. SPD can be enabled with bit 1E.C475.2 */ + unsigned int smartPower_downEnable : 1; /* 1E.C475.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable smart power down mode + 0 = Smart power-down mode disabled + */ + unsigned int reserved1 : 2; + } bits_5; + uint16_t word_5; + } u5; + /*! \brief Dummy union to fill space in the structure Global Reserved Provisioning */ + union + { + struct + { + unsigned int reserved : 16; + } bits_6; + uint16_t word_6; + } u6; + /*! \brief Dummy union to fill space in the structure Global Reserved Provisioning */ + union + { + struct + { + unsigned int reserved : 16; + } bits_7; + uint16_t word_7; + } u7; + /*! \brief Union for bit and word level access of word 8 of Global Reserved Provisioning */ + union + { + struct + { + /*! \brief 1E.C478.F R/WPD DTE Enable + AQ_GlobalReservedProvisioning_HHD.u8.bits_8.dteEnable + + Provisionable Default = 0x0 + + 1 = Enable DTE + 0 = Disable DTE + + */ + unsigned int dteEnable : 1; /* 1E.C478.F R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable DTE + 0 = Disable DTE + */ + /*! \brief 1E.C478.E:B R/WPD DTE Drop Reporting Timer [3:0] + AQ_GlobalReservedProvisioning_HHD.u8.bits_8.dteDropReportingTimer + + Provisionable Default = 0x0 + + Number of seconds between loss of link partner filter and assertion of no-power-needed state, in 5 second increments (e.g. 0x4 = 20 seconds). + + + Notes: + These bits are used to set how long the PHY waits after it no longer detects the link partner filter before declaring that power is not needed. */ + unsigned int dteDropReportingTimer : 4; /* 1E.C478.E:B R/WPD Provisionable Default = 0x0 */ + /* Number of seconds between loss of link partner filter and assertion of no-power-needed state, in 5 second increments (e.g. 0x4 = 20 seconds). + */ + /*! \brief 1E.C478.A:0 R/WPD Reserved Provisioning 9 [A:0] + AQ_GlobalReservedProvisioning_HHD.u8.bits_8.reservedProvisioning_9 + + Provisionable Default = 0x000 + + Reserved for future use + + */ + unsigned int reservedProvisioning_9 : 11; /* 1E.C478.A:0 R/WPD Provisionable Default = 0x000 */ + /* Reserved for future use + */ + } bits_8; + uint16_t word_8; + } u8; + /*! \brief Union for bit and word level access of word 9 of Global Reserved Provisioning */ + union + { + struct + { + /*! \brief 1E.C479.F R/WPD Power Up Stall + AQ_GlobalReservedProvisioning_HHD.u9.bits_9.powerUpStall + + Provisionable Default = 0x0 + + 1 = Stall FW at Power Up + 0 = Unstall the FW + + + Notes: + This bit needs to be provisioned in Power Up Init for firmware to stall. */ + unsigned int powerUpStall : 1; /* 1E.C479.F R/WPD Provisionable Default = 0x0 */ + /* 1 = Stall FW at Power Up + 0 = Unstall the FW + */ + /*! \brief 1E.C479.E:0 R/WPD Reserved Provisioning 10 [E:0] + AQ_GlobalReservedProvisioning_HHD.u9.bits_9.reservedProvisioning_10 + + Provisionable Default = 0x0000 + + Reserved for future use + + */ + unsigned int reservedProvisioning_10 : 15; /* 1E.C479.E:0 R/WPD Provisionable Default = 0x0000 */ + /* Reserved for future use + */ + } bits_9; + uint16_t word_9; + } u9; + /*! \brief Union for bit and word level access of word 10 of Global Reserved Provisioning */ + union + { + struct + { + /*! \brief 1E.C47A.F:B R/WPD Loopback Control [4:0] + AQ_GlobalReservedProvisioning_HHD.u10.bits_10.loopbackControl + + Provisionable Default = 0x00 + + 0x00 = No loopback + 0x01 = System Interface - System Loopback + 0x02 = System Interface - System Loopback with Passthrough + 0x03 = System Interface - Network Loopback + 0x04 = System Interface - Network Loopback with Passthrough + 0x05 = System Interface - Network Loopback with Passthrough and Merge + 0x06 = System Interface - Peer-to-peer loopback + 0x07 - 0x08 = Reserved + 0x09 = Network Interface - System Loopback + 0x0A = Network Interface - System Loopback with Passthrough + 0x0B = Network Interface - Network Loopback + 0x0C = Network Interface - Network Loopback with Passthrough + 0x0D = Network Interface - Peer-to-peer loopback + 0x0E - 0x0F = Reserved + 0x10 = Cross-connect System Loopback + 0x11 = Cross-connect Network Loopback + 0x12 - 0x13 = Reserved + 0x14 = Network Interface - System Loopback via Loopback Plug + 0x15 - 0x1F = Reserved + + + Notes: + These bits, in conjunction with the chip configuration and the rate (Bits 1:0), select the loopback to configure for the chip. Setting one of these loopbacks provisions the chip for the specified loopback. Upon clearing the loopback, the chip returns to it's configuration prior to entering loopback (irregardless of whether other loopbacks were selected after the initial loopback). + + NOTE!! This is a processor intensive operation. Completion of this operation can be monitored via 1E.C831.F. + + The controls in this register are identical to, and mirrored with, the controls in 4.C444. + */ + unsigned int loopbackControl : 5; /* 1E.C47A.F:B R/WPD Provisionable Default = 0x00 */ + /* 0x00 = No loopback + 0x01 = System Interface - System Loopback + 0x02 = System Interface - System Loopback with Passthrough + 0x03 = System Interface - Network Loopback + 0x04 = System Interface - Network Loopback with Passthrough + 0x05 = System Interface - Network Loopback with Passthrough and Merge + 0x06 = System Interface - Peer-to-peer loopback + 0x07 - 0x08 = Reserved + 0x09 = Network Interface - System Loopback + 0x0A = Network Interface - System Loopback with Passthrough + 0x0B = Network Interface - Network Loopback + 0x0C = Network Interface - Network Loopback with Passthrough + 0x0D = Network Interface - Peer-to-peer loopback + 0x0E - 0x0F = Reserved + 0x10 = Cross-connect System Loopback + 0x11 = Cross-connect Network Loopback + 0x12 - 0x13 = Reserved + 0x14 = Network Interface - System Loopback via Loopback Plug + 0x15 - 0x1F = Reserved + */ + /*! \brief 1E.C47A.A:6 R/WPD Reserved Provisioning 11 [4:0] + AQ_GlobalReservedProvisioning_HHD.u10.bits_10.reservedProvisioning_11 + + Provisionable Default = 0x00 + + Reserved for future use + + */ + unsigned int reservedProvisioning_11 : 5; /* 1E.C47A.A:6 R/WPD Provisionable Default = 0x00 */ + /* Reserved for future use + */ + /*! \brief 1E.C47A.5 R/WPD MDI Packet Generation + AQ_GlobalReservedProvisioning_HHD.u10.bits_10.mdiPacketGeneration + + Provisionable Default = 0x0 + + 1 = CRPAT packet generation out MDI interface + 0 = No CRPAT packet generation out MDI interface + + + Notes: + Selecting this mode of operation causes the CRPAT packet generator in the PHY to output on the MDI interface at the selected rate. + + NOTE!! This is a processor intensive operation. Completion of this operation can be monitored via 1E.C831.F + + The controls in this register are identical to, and mirrored with, the controls in 4.C444. */ + unsigned int mdiPacketGeneration : 1; /* 1E.C47A.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = CRPAT packet generation out MDI interface + 0 = No CRPAT packet generation out MDI interface + */ + /*! \brief 1E.C47A.4 R/WPD Look-Aside Port Packet Generation + AQ_GlobalReservedProvisioning_HHD.u10.bits_10.look_asidePortPacketGeneration + + Provisionable Default = 0x0 + + 1 = CRPAT packet generation out 10G look-aside interface (KR0) + 0 = No CRPAT packet generation out 10G look-aside interface (KR0) + + + Notes: + Selecting this mode of operation causes the CRPAT packet generator in the PHY to output on KR0. + + NOTE!! This only functions if KR1 (SERDES2) is selected as the system interface in (4.C441.F:E). + + NOTE!! This is a processor intensive operation. Completion of this operation can be monitored via 1E.C831.F + + The controls in this register are identical to, and mirrored with, the controls in 4.C444. */ + unsigned int look_asidePortPacketGeneration : 1; /* 1E.C47A.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = CRPAT packet generation out 10G look-aside interface (KR0) + 0 = No CRPAT packet generation out 10G look-aside interface (KR0) + */ + /*! \brief 1E.C47A.3 R/WPD System I/F Packet Generation + AQ_GlobalReservedProvisioning_HHD.u10.bits_10.systemI_fPacketGeneration + + Provisionable Default = 0x0 + + 1 = CRPAT packet generation out 10G system interface + 0 = No CRPAT packet generation out 10G system interface + + + Notes: + Selecting this mode of operation causes the CRPAT packet generator in the PHY to output CRPAT packets on the selected 10G system interface (4.C441.F:E) + + NOTE!! This is a processor intensive operation. Completion of this operation can be monitored via 1E.C831.F + + The controls in this register are identical to, and mirrored with, the controls in 4.C444. */ + unsigned int systemI_fPacketGeneration : 1; /* 1E.C47A.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = CRPAT packet generation out 10G system interface + 0 = No CRPAT packet generation out 10G system interface + */ + /*! \brief 1E.C47A.2 R/WPD Reserved Provisioning 11a + AQ_GlobalReservedProvisioning_HHD.u10.bits_10.reservedProvisioning_11a + + Provisionable Default = 0x0 + + Reserved for future use + + */ + unsigned int reservedProvisioning_11a : 1; /* 1E.C47A.2 R/WPD Provisionable Default = 0x0 */ + /* Reserved for future use + */ + /*! \brief 1E.C47A.1:0 R/WPD Rate [1:0] + AQ_GlobalReservedProvisioning_HHD.u10.bits_10.rate + + Provisionable Default = 0x0 + + 0x3 = 10G + 0x2 = 1G + 0x1 = 100M + 0x0 = reserved + + + Notes: + These bits select the rate for the loopback and packet generation. SERDES configuration, as well autonegotiation is controlled accordingly when a loopback is selected. For instance, if 100M system loopback on the network interface is selected, SGMII on the system interface is enabled to connect at 100M, and if passthrough is enabled 100BASE-TX will be the only advertised rate and will force a re-autonegotiation if not already connected at 100M. + + NOTE!! This is a processor intensive operation. Completion of this operation can be monitored via 1E.C831.F + + The controls in this register are identical to, and mirrored with, the controls in 4.C444. */ + unsigned int rate : 2; /* 1E.C47A.1:0 R/WPD Provisionable Default = 0x0 */ + /* 0x3 = 10G + 0x2 = 1G + 0x1 = 100M + 0x0 = reserved + */ + } bits_10; + uint16_t word_10; + } u10; + /*! \brief Union for bit and word level access of word 11 of Global Reserved Provisioning */ + union + { + struct + { + /*! \brief 1E.C47B.F:2 R/WPD Reserved Provisioning 12 [D:0] + AQ_GlobalReservedProvisioning_HHD.u11.bits_11.reservedProvisioning_12 + + Provisionable Default = 0x0000 + + Reserved for future use + + */ + unsigned int reservedProvisioning_12 : 14; /* 1E.C47B.F:2 R/WPD Provisionable Default = 0x0000 */ + /* Reserved for future use + */ + /*! \brief 1E.C47B.1 R/WPD Enable MACSec + AQ_GlobalReservedProvisioning_HHD.u11.bits_11.enableMacsec + + Provisionable Default = 0x0 + + 1 = MACSec functionality is enabled + 0 = MACSec functionality is disabled + + + Notes: + If this bit is 1, the PTP/SEC block will be included in the data path, regardless of operating mode. */ + unsigned int enableMacsec : 1; /* 1E.C47B.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = MACSec functionality is enabled + 0 = MACSec functionality is disabled + */ + /*! \brief 1E.C47B.0 R/WPD Enable PTP + AQ_GlobalReservedProvisioning_HHD.u11.bits_11.enablePtp + + Provisionable Default = 0x0 + + 1 = PTP functionality is enabled + 0 = PTP functionality is disabled + + + Notes: + If this bit is 1, the PTP/SEC block will be included in the data path, regardless of operating mode. */ + unsigned int enablePtp : 1; /* 1E.C47B.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = PTP functionality is enabled + 0 = PTP functionality is disabled + */ + } bits_11; + uint16_t word_11; + } u11; +} AQ_GlobalReservedProvisioning_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief PIF Mailbox Control: 1E.C47C */ +/* PIF Mailbox Control: 1E.C47C */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of PIF Mailbox Control */ + union + { + struct + { + /*! \brief 1E.C47C.F:0 R/WPDuP PIF Mailbox Address [F:0] + AQ_PifMailboxControl_HHD.u0.bits_0.pifMailboxAddress + + Provisionable Default = 0x0000 + + The least 16 bits of the PIF address to read or write. + + */ + unsigned int pifMailboxAddress : 16; /* 1E.C47C.F:0 R/WPDuP Provisionable Default = 0x0000 */ + /* The least 16 bits of the PIF address to read or write. + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of PIF Mailbox Control */ + union + { + struct + { + /*! \brief 1E.C47D.F:0 R/WPDuP PIF Mailbox Data [F:0] + AQ_PifMailboxControl_HHD.u1.bits_1.pifMailboxData + + Provisionable Default = 0x0000 + + The data to be written, or that had been read. + + */ + unsigned int pifMailboxData : 16; /* 1E.C47D.F:0 R/WPDuP Provisionable Default = 0x0000 */ + /* The data to be written, or that had been read. + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of PIF Mailbox Control */ + union + { + struct + { + /*! \brief 1E.C47E.F:C R/WPD Reserved PIF Mailbox Control 3 [3:0] + AQ_PifMailboxControl_HHD.u2.bits_2.reservedPifMailboxControl_3 + + Provisionable Default = 0x0 + + Reserved for future use + + */ + unsigned int reservedPifMailboxControl_3 : 4; /* 1E.C47E.F:C R/WPD Provisionable Default = 0x0 */ + /* Reserved for future use + */ + /*! \brief 1E.C47E.B:8 R/WPDuP PIF Mailbox Command Type [3:0] + AQ_PifMailboxControl_HHD.u2.bits_2.pifMailboxCommandType + + Provisionable Default = 0x0 + + 0 = No Action + 1 = Read + 2 = Write + + + Notes: + System SW writes non-zero value to start a PIF command. */ + unsigned int pifMailboxCommandType : 4; /* 1E.C47E.B:8 R/WPDuP Provisionable Default = 0x0 */ + /* 0 = No Action + 1 = Read + 2 = Write + */ + /*! \brief 1E.C47E.7:0 R/WPDuP PIF Mailbox MMD [7:0] + AQ_PifMailboxControl_HHD.u2.bits_2.pifMailboxMMD + + Provisionable Default = 0x00 + + MMD (upper 8 bits) of the PID address to read or write. + + */ + unsigned int pifMailboxMMD : 8; /* 1E.C47E.7:0 R/WPDuP Provisionable Default = 0x00 */ + /* MMD (upper 8 bits) of the PID address to read or write. + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of PIF Mailbox Control */ + union + { + struct + { + /*! \brief 1E.C47F.F:4 R/WPD Reserved PIF Mailbox Control 4 [B:0] + AQ_PifMailboxControl_HHD.u3.bits_3.reservedPifMailboxControl_4 + + Provisionable Default = 0x000 + + Reserved for future use + + */ + unsigned int reservedPifMailboxControl_4 : 12; /* 1E.C47F.F:4 R/WPD Provisionable Default = 0x000 */ + /* Reserved for future use + */ + /*! \brief 1E.C47F.3:0 R/WPDuP PIF Mailbox Command Status [3:0] + AQ_PifMailboxControl_HHD.u3.bits_3.pifMailboxCommandStatus + + Provisionable Default = 0x0 + + 0 = Idle + 1 = Command completed + 2 = Command did not complete + + + Notes: + System SW should write 0 before writing Command Type to clear completion status */ + unsigned int pifMailboxCommandStatus : 4; /* 1E.C47F.3:0 R/WPDuP Provisionable Default = 0x0 */ + /* 0 = Idle + 1 = Command completed + 2 = Command did not complete + */ + } bits_3; + uint16_t word_3; + } u3; +} AQ_PifMailboxControl_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global SMBus 0 Provisioning: 1E.C485 */ +/* Global SMBus 0 Provisioning: 1E.C485 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global SMBus 0 Provisioning */ + union + { + struct + { + unsigned int reserved0 : 8; + /*! \brief 1E.C485.7:1 R/W SMB 0 Slave Address [7:1] + AQ_GlobalSmbus_0Provisioning_HHD.u0.bits_0.smb_0SlaveAddress + + Default = 0x00 + + SMB slave address configuration + + */ + unsigned int smb_0SlaveAddress : 7; /* 1E.C485.7:1 R/W Default = 0x00 */ + /* SMB slave address configuration + */ + unsigned int reserved1 : 1; + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalSmbus_0Provisioning_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global SMBus 1 Provisioning: 1E.C495 */ +/* Global SMBus 1 Provisioning: 1E.C495 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global SMBus 1 Provisioning */ + union + { + struct + { + unsigned int reserved0 : 8; + /*! \brief 1E.C495.7:1 R/W SMB 1 Slave Address [7:1] + AQ_GlobalSmbus_1Provisioning_HHD.u0.bits_0.smb_1SlaveAddress + + Default = 0x00 + + SMB slave address configuration + + */ + unsigned int smb_1SlaveAddress : 7; /* 1E.C495.7:1 R/W Default = 0x00 */ + /* SMB slave address configuration + */ + unsigned int reserved1 : 1; + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalSmbus_1Provisioning_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global EEE Provisioning: 1E.C4A0 */ +/* Global EEE Provisioning: 1E.C4A0 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global EEE Provisioning */ + union + { + struct + { + unsigned int reserved0 : 15; + /*! \brief 1E.C4A0.0 R/WPD EEE Mode + AQ_GlobalEeeProvisioning_HHD.u0.bits_0.eeeMode + + Provisionable Default = 0x0 + + 1 = EEE mode of operation + + + Notes: + EEE mode of operation (0=disable, 1=enable, default:0) */ + unsigned int eeeMode : 1; /* 1E.C4A0.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = EEE mode of operation + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalEeeProvisioning_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Cable Diagnostic Status: 1E.C800 */ +/* Global Cable Diagnostic Status: 1E.C800 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Cable Diagnostic Status */ + union + { + struct + { + unsigned int reserved0 : 1; + /*! \brief 1E.C800.E:C RO Pair A Status [2:0] + AQ_GlobalCableDiagnosticStatus_HHD.u0.bits_0.pairAStatus + + + + [F:D] + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair D + 010= Connected to Pair C + 001= Connected to Pair B + 000= OK + + Notes: + This register summarizes the worst impairment on Pair A. */ + unsigned int pairAStatus : 3; /* 1E.C800.E:C RO */ + /* [F:D] + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair D + 010= Connected to Pair C + 001= Connected to Pair B + 000= OK */ + unsigned int reserved1 : 1; + /*! \brief 1E.C800.A:8 RO Pair B Status [2:0] + AQ_GlobalCableDiagnosticStatus_HHD.u0.bits_0.pairBStatus + + + + [C:A] + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair A + 010= Connected to Pair D + 001= Connected to Pair C + 000= OK + + Notes: + This register summarizes the worst impairment on Pair B. */ + unsigned int pairBStatus : 3; /* 1E.C800.A:8 RO */ + /* [C:A] + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair A + 010= Connected to Pair D + 001= Connected to Pair C + 000= OK */ + unsigned int reserved2 : 1; + /*! \brief 1E.C800.6:4 RO Pair C Status [2:0] + AQ_GlobalCableDiagnosticStatus_HHD.u0.bits_0.pairCStatus + + + + [9:7] + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair B + 010= Connected to Pair A + 001= Connected to Pair D + 000= OK + + Notes: + This register summarizes the worst impairment on Pair C. */ + unsigned int pairCStatus : 3; /* 1E.C800.6:4 RO */ + /* [9:7] + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair B + 010= Connected to Pair A + 001= Connected to Pair D + 000= OK */ + unsigned int reserved3 : 1; + /*! \brief 1E.C800.2:0 RO Pair D Status [2:0] + AQ_GlobalCableDiagnosticStatus_HHD.u0.bits_0.pairDStatus + + + + [6:4] + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair C + 010= Connected to Pair B + 001= Connected to Pair A + 000= OK + + Notes: + This register summarizes the worst impairment on Pair D. */ + unsigned int pairDStatus : 3; /* 1E.C800.2:0 RO */ + /* [6:4] + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 011= Connected to Pair C + 010= Connected to Pair B + 001= Connected to Pair A + 000= OK */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C801.F:8 RO Pair A Reflection #1 [7:0] + AQ_GlobalCableDiagnosticStatus_HHD.u1.bits_1.pairAReflection_1 + + + + The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair A + + Notes: + The distance to this reflection is given in See Global Reserved Status 1: Address 1E.C870 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairAReflection_1 : 8; /* 1E.C801.F:8 RO */ + /* The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair A */ + /*! \brief 1E.C801.7:0 RO Pair A Reflection #2 [7:0] + AQ_GlobalCableDiagnosticStatus_HHD.u1.bits_1.pairAReflection_2 + + + + The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair A + + Notes: + The distance to this reflection is given in See Global Reserved Status 1: Address 1E.C870 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairAReflection_2 : 8; /* 1E.C801.7:0 RO */ + /* The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair A */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C802.F:0 RO Impulse Response MSW [F:0] + AQ_GlobalCableDiagnosticStatus_HHD.u2.bits_2.impulseResponseMSW + + + + The MSW of the memory location that contains the start of the impulse response data for the Extended Diagnostic type in 1E.C470.E:D + + Notes: + See 1E.C470 for more information */ + unsigned int impulseResponseMSW : 16; /* 1E.C802.F:0 RO */ + /* The MSW of the memory location that contains the start of the impulse response data for the Extended Diagnostic type in 1E.C470.E:D */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C803.F:8 RO Pair B Reflection #1 [7:0] + AQ_GlobalCableDiagnosticStatus_HHD.u3.bits_3.pairBReflection_1 + + + + The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair B + + Notes: + The distance to this reflection is given in See Global Reserved Status 2: Address 1E.C871 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairBReflection_1 : 8; /* 1E.C803.F:8 RO */ + /* The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair B */ + /*! \brief 1E.C803.7:0 RO Pair B Reflection #2 [7:0] + AQ_GlobalCableDiagnosticStatus_HHD.u3.bits_3.pairBReflection_2 + + + + The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair B + + Notes: + The distance to this reflection is given in See Global Reserved Status 2: Address 1E.C871 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairBReflection_2 : 8; /* 1E.C803.7:0 RO */ + /* The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair B */ + } bits_3; + uint16_t word_3; + } u3; + /*! \brief Union for bit and word level access of word 4 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C804.F:0 RO Impulse Response LSW [F:0] + AQ_GlobalCableDiagnosticStatus_HHD.u4.bits_4.impulseResponseLSW + + + + The LSW of the memory location that contains the start of the impulse response data for the Extended Diagnostic type specified in 1E.C470.E:D + + Notes: + See 1E.C470 for more information */ + unsigned int impulseResponseLSW : 16; /* 1E.C804.F:0 RO */ + /* The LSW of the memory location that contains the start of the impulse response data for the Extended Diagnostic type specified in 1E.C470.E:D */ + } bits_4; + uint16_t word_4; + } u4; + /*! \brief Union for bit and word level access of word 5 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C805.F:8 RO Pair C Reflection #1 [7:0] + AQ_GlobalCableDiagnosticStatus_HHD.u5.bits_5.pairCReflection_1 + + + + The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair C + + Notes: + The distance to this reflection is given in See Global Reserved Status 3: Address 1E.C872 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairCReflection_1 : 8; /* 1E.C805.F:8 RO */ + /* The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair C */ + /*! \brief 1E.C805.7:0 RO Pair C Reflection #2 [7:0] + AQ_GlobalCableDiagnosticStatus_HHD.u5.bits_5.pairCReflection_2 + + + + The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair C + + Notes: + The distance to this reflection is given in See Global Reserved Status 3: Address 1E.C872 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairCReflection_2 : 8; /* 1E.C805.7:0 RO */ + /* The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair C */ + } bits_5; + uint16_t word_5; + } u5; + /*! \brief Union for bit and word level access of word 6 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C806.F:0 RO Reserved 1 [F:0] + AQ_GlobalCableDiagnosticStatus_HHD.u6.bits_6.reserved_1 + + + + Reserved for future use + */ + unsigned int reserved_1 : 16; /* 1E.C806.F:0 RO */ + /* Reserved for future use */ + } bits_6; + uint16_t word_6; + } u6; + /*! \brief Union for bit and word level access of word 7 of Global Cable Diagnostic Status */ + union + { + struct + { + /*! \brief 1E.C807.F:8 RO Pair D Reflection #1 [7:0] + AQ_GlobalCableDiagnosticStatus_HHD.u7.bits_7.pairDReflection_1 + + + + The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair D + + Notes: + The distance to this reflection is given in See Global Reserved Status 4: Address 1E.C873 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairDReflection_1 : 8; /* 1E.C807.F:8 RO */ + /* The distance in meters, accurate to 1m, of the first of the four worst reflections seen by the PHY on Pair D */ + /*! \brief 1E.C807.7:0 RO Pair D Reflection #2 [7:0] + AQ_GlobalCableDiagnosticStatus_HHD.u7.bits_7.pairDReflection_2 + + + + The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair D + + Notes: + The distance to this reflection is given in See Global Reserved Status 4: Address 1E.C873 . A value of zero indicates that this reflection does not exist or was not computed. */ + unsigned int pairDReflection_2 : 8; /* 1E.C807.7:0 RO */ + /* The distance in meters, accurate to 1m, of the second of the four worst reflections seen by the PHY on Pair D */ + } bits_7; + uint16_t word_7; + } u7; +} AQ_GlobalCableDiagnosticStatus_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Thermal Status: 1E.C820 */ +/* Global Thermal Status: 1E.C820 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Thermal Status */ + union + { + struct + { + /*! \brief 1E.C820.F:0 RO Temperature [F:0] + AQ_GlobalThermalStatus_HHD.u0.bits_0.temperature + + + + [F:0] of temperature + + + Notes: + 2's complement value with the LSB representing 1/256 of a degree Celsius. This corresponds to -40 degreesC = 0xD800. Default is 70 degreesC. This is a mirror of the XENPAK register 1.A060 - 1.A061. The mirror is performed in H/W. */ + unsigned int temperature : 16; /* 1E.C820.F:0 RO */ + /* [F:0] of temperature + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Thermal Status */ + union + { + struct + { + unsigned int reserved0 : 15; + /*! \brief 1E.C821.0 RO Temperature Ready + AQ_GlobalThermalStatus_HHD.u1.bits_1.temperatureReady + + + + 1 = Temperature measurement is valid + + + Notes: + This is a mirror of the XENPAK register 1.A06E. */ + unsigned int temperatureReady : 1; /* 1E.C821.0 RO */ + /* 1 = Temperature measurement is valid + */ + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalThermalStatus_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global General Status: 1E.C830 */ +/* Global General Status: 1E.C830 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global General Status */ + union + { + struct + { + unsigned int reserved0 : 1; + /*! \brief 1E.C830.E RO High Temperature Failure State + AQ_GlobalGeneralStatus_HHD.u0.bits_0.highTemperatureFailureState + + + + 1 = High temperature failure threshold has been exceeded + + Notes: + In XENPAK mode, F/W will copy this register to the 1.A070.7 register. + + */ + unsigned int highTemperatureFailureState : 1; /* 1E.C830.E RO */ + /* 1 = High temperature failure threshold has been exceeded */ + /*! \brief 1E.C830.D RO Low Temperature Failure State + AQ_GlobalGeneralStatus_HHD.u0.bits_0.lowTemperatureFailureState + + + + 1 = Low temperature failure threshold has been exceeded + + Notes: + In XENPAK mode, F/W will copy this register to the 1.A070.6 register. + + */ + unsigned int lowTemperatureFailureState : 1; /* 1E.C830.D RO */ + /* 1 = Low temperature failure threshold has been exceeded */ + /*! \brief 1E.C830.C RO High Temperature Warning State + AQ_GlobalGeneralStatus_HHD.u0.bits_0.highTemperatureWarningState + + + + 1 = High temperature warning threshold has been exceeded + + Notes: + In XENPAK mode, F/W will copy this register to the 1.A074.7 register. + + */ + unsigned int highTemperatureWarningState : 1; /* 1E.C830.C RO */ + /* 1 = High temperature warning threshold has been exceeded */ + /*! \brief 1E.C830.B RO Low Temperature Warning State + AQ_GlobalGeneralStatus_HHD.u0.bits_0.lowTemperatureWarningState + + + + 1 = Low temperature warning threshold has been exceeded + + Notes: + In XENPAK mode, F/W will copy this register to the 1.A074.6 register. + + */ + unsigned int lowTemperatureWarningState : 1; /* 1E.C830.B RO */ + /* 1 = Low temperature warning threshold has been exceeded */ + unsigned int reserved1 : 11; + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global General Status */ + union + { + struct + { + /*! \brief 1E.C831.F RO Processor Intensive MDIO Operation In- Progress + AQ_GlobalGeneralStatus_HHD.u1.bits_1.processorIntensiveMdioOperationIn_Progress + + + + 1 = PHY microprocessor is busy with a processor-intensive MDIO operation + 0 = Processor-intensive MDIO operation completed + + + Notes: + This bit should may be used with certain processor-intensive MDIO commands (such as Loopbacks, Test Modes, Low power modes, Tx-Disable, Restart autonegotiation, Cable Diagnostics, etc.) that take longer than an MDIO cycle to complete. Upon receiving an MDIO command that involves the PHY's microprocessor, this bit is set, and when the command is completed, this bit is cleared. + + NOTE!!! This bit should be checked only after 1 ms of issuing a processor-intensive MDIO operation. + + The list of operations that set this bit are as follows: + + 1.0.0, PMA Loopback + 1.0.B, Low power mode + 1.9.4:0, Tx Disable + 1.84, 10G Test modes + 1.8000.5, XENPAK Control + 1.9000, XENPAK Rx Fault Enable + 1.9002, XENPAK Alarm Enable + 1.E400.F, External loopback + 3.0.B, Low power mode + 3.0.E, System PCS loopback + 3.C471.5, PRBS Test + 3.C471.6, PRBS Test + 3.E471.5, PRBS Test + 3.E471.6, PRBS Test + 4.0.B, Low power mode + 4.0.E, PHY-XS network loopback + 4.C440, Output clock control, Load SERDES parameters + 4.F802.E, System loopback + 4.C444.F:B, Loopback Control + 4.C444.4:2, Packet generation + 4.C445.C, SERDES calibration + 7.0.9, Restart autonegotiation + 1D.C280, 1G/100M Network loopback + 1D.C500, 1G System loopback + 1D.C501, 1G / 100M Test modes + 1E.C470.4, Cable diagnostics + 1E.C47A.F:B, Loopback Control + 1E.C47A.4:2, Packet generation */ + unsigned int processorIntensiveMdioOperationIn_Progress : 1; /* 1E.C831.F RO */ + /* 1 = PHY microprocessor is busy with a processor-intensive MDIO operation + 0 = Processor-intensive MDIO operation completed + */ + unsigned int reserved0 : 15; + } bits_1; + uint16_t word_1; + } u1; +} AQ_GlobalGeneralStatus_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Pin Status: 1E.C840 */ +/* Global Pin Status: 1E.C840 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Pin Status */ + union + { + struct + { + unsigned int reserved0 : 1; + unsigned int reserved1 : 1; + /*! \brief 1E.C840.D RO DC_MASTER_N + AQ_GlobalPinStatus_HHD.u0.bits_0.dcMasterN + + + + Value of DC_MASTER_N pin: + + 0x1 = PHY Slave Daisy Chain Boot + 0x0 = PHY Master Daisy Chain Boot from FLASH + */ + unsigned int dcMasterN : 1; /* 1E.C840.D RO */ + /* Value of DC_MASTER_N pin: + + 0x1 = PHY Slave Daisy Chain Boot + 0x0 = PHY Master Daisy Chain Boot from FLASH */ + unsigned int reserved2 : 3; + /*! \brief 1E.C840.9 RO Package Connectivity + AQ_GlobalPinStatus_HHD.u0.bits_0.packageConnectivity + + + + Value of the package connection pin + + */ + unsigned int packageConnectivity : 1; /* 1E.C840.9 RO */ + /* Value of the package connection pin + */ + unsigned int reserved3 : 1; + /*! \brief 1E.C840.7 RO Tx Enable + AQ_GlobalPinStatus_HHD.u0.bits_0.txEnable + + + + Current Value of Tx Enable pin + + + Notes: + 0 = Disable Transmitter */ + unsigned int txEnable : 1; /* 1E.C840.7 RO */ + /* Current Value of Tx Enable pin + */ + unsigned int reserved4 : 1; + /*! \brief 1E.C840.5:0 RO LED Pullup State [5:0] + AQ_GlobalPinStatus_HHD.u0.bits_0.ledPullupState + + + + 1 = LED output pin is pulled high + 0 = LED output pin is pulled low + + */ + unsigned int ledPullupState : 6; /* 1E.C840.5:0 RO */ + /* 1 = LED output pin is pulled high + 0 = LED output pin is pulled low + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalPinStatus_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Daisy Chain Status: 1E.C842 */ +/* Global Daisy Chain Status: 1E.C842 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Daisy Chain Status */ + union + { + struct + { + /*! \brief 1E.C842.F:0 RO Rx Daisy Chain Calculated CRC [F:0] + AQ_GlobalDaisyChainStatus_HHD.u0.bits_0.rxDaisyChainCalculatedCrc + + + + Rx Daisy Chain Calculated CRC + + + Notes: + This is the calculated daisy chain CRC. */ + unsigned int rxDaisyChainCalculatedCrc : 16; /* 1E.C842.F:0 RO */ + /* Rx Daisy Chain Calculated CRC + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalDaisyChainStatus_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Fault Message: 1E.C850 */ +/* Global Fault Message: 1E.C850 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Fault Message */ + union + { + struct + { + /*! \brief 1E.C850.F:0 RO Message [F:0] + AQ_GlobalFaultMessage_HHD.u0.bits_0.message + + + + Error code describing fault + + Notes: + Code 0x8001: Firmware not compatible with chip architecture. This fault occurs when firmware compiled for a different microprocessor core is loaded. + Code 0x8002: VCO calibration failed. This occurs when the main PLLs on chip fail to lock: this is not possible to trigger. + Code 0x8003: XAUI calibration failed. This occurs when the XAUI PLLs fail to lock: this is not possible to trigger. + Code 0x8005: Unexpected device ID. This occurs if the device ID programmed into the internal E-Fuse registers in not valid: this is not possible to trigger. + Code 0x8006: Computed checksum does not match expected checksum. This occurs when the FLASH checksum check performed at boot time fails. This only occurs when the system boots from FLASH. + Code 0x8007: Detected a bit error in static memory. To trigger, corrupt one of the static regions. + Code 0xC001: Illegal Instruction exception. This occurs when the processor attempts to execute an illegal instruction. To trigger this, write an illegal instruction to program memory. It's possible that the bit error check will trigger before the illegal instruction is executed. + Code 0xC002 Instruction Fetch Error. Internal physical address or a data error during instruction fetch: this is not possible to trigger. + Code 0xC003 Load Store Error. Internal physical address or data error during load store operation: this is not possible to trigger.. + Code 0xC004 Privileged Instruction. Attempt to execute a privileged operation without sufficient privilege: this is not possible to trigger. + Code 0xC005 Unaligned Load or Store. Attempt to load or store data at an address which cannot be handled due to alignment: this is not possible to trigger. + Code 0xC006 Instruction fetch from prohibited space: this is not possible to trigger. + Code 0xC007 Data load from prohibited space: this is not possible to trigger. + Code 0xC008 Data store into prohibited space: this is not possible to trigger. */ + unsigned int message : 16; /* 1E.C850.F:0 RO */ + /* Error code describing fault */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalFaultMessage_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Cable Diagnostic Impedance: 1E.C880 */ +/* Global Cable Diagnostic Impedance: 1E.C880 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Cable Diagnostic Impedance */ + union + { + struct + { + /*! \brief 1E.C880.F RO Reserved 1 + AQ_GlobalCableDiagnosticImpedance_HHD.u0.bits_0.reserved_1 + + + + Reserved + + */ + unsigned int reserved_1 : 1; /* 1E.C880.F RO */ + /* Reserved + */ + /*! \brief 1E.C880.E:C RO Pair A Reflection #1 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u0.bits_0.pairAReflection_1 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the first worst reflection on Pair A. The corresponding length of this reflection from the PHY is given in See Global Power Control - Address 1E.21 */ + unsigned int pairAReflection_1 : 3; /* 1E.C880.E:C RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C880.B RO Reserved 2 + AQ_GlobalCableDiagnosticImpedance_HHD.u0.bits_0.reserved_2 + + + + Reserved + + */ + unsigned int reserved_2 : 1; /* 1E.C880.B RO */ + /* Reserved + */ + /*! \brief 1E.C880.A:8 RO Pair A Reflection #2 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u0.bits_0.pairAReflection_2 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the second worst reflection on Pair A. The corresponding length of this reflection from the PHY is given in See Global Power Control - Address 1E.21 */ + unsigned int pairAReflection_2 : 3; /* 1E.C880.A:8 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C880.7 RO Reserved 3 + AQ_GlobalCableDiagnosticImpedance_HHD.u0.bits_0.reserved_3 + + + + Reserved + + */ + unsigned int reserved_3 : 1; /* 1E.C880.7 RO */ + /* Reserved + */ + /*! \brief 1E.C880.6:4 RO Pair A Reflection #3 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u0.bits_0.pairAReflection_3 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the third worst reflection on Pair A. The corresponding length of this reflection from the PHY is given in See Global Power Control - Address 1E.21 */ + unsigned int pairAReflection_3 : 3; /* 1E.C880.6:4 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C880.3 RO Reserved 4 + AQ_GlobalCableDiagnosticImpedance_HHD.u0.bits_0.reserved_4 + + + + Reserved + + */ + unsigned int reserved_4 : 1; /* 1E.C880.3 RO */ + /* Reserved + */ + /*! \brief 1E.C880.2:0 RO Pair A Reflection #4 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u0.bits_0.pairAReflection_4 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the fourth worst reflection on Pair A. The corresponding length of this reflection from the PHY is given in See Global Power Control - Address 1E.21 */ + unsigned int pairAReflection_4 : 3; /* 1E.C880.2:0 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Cable Diagnostic Impedance */ + union + { + struct + { + /*! \brief 1E.C881.F RO Reserved 5 + AQ_GlobalCableDiagnosticImpedance_HHD.u1.bits_1.reserved_5 + + + + Reserved + + */ + unsigned int reserved_5 : 1; /* 1E.C881.F RO */ + /* Reserved + */ + /*! \brief 1E.C881.E:C RO Pair B Reflection #1 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u1.bits_1.pairBReflection_1 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the first worst reflection on Pair B. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 2 - Address 1E.32 - 1E.33 */ + unsigned int pairBReflection_1 : 3; /* 1E.C881.E:C RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C881.B RO Reserved 6 + AQ_GlobalCableDiagnosticImpedance_HHD.u1.bits_1.reserved_6 + + + + Reserved + + */ + unsigned int reserved_6 : 1; /* 1E.C881.B RO */ + /* Reserved + */ + /*! \brief 1E.C881.A:8 RO Pair B Reflection #2 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u1.bits_1.pairBReflection_2 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the second worst reflection on Pair B. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 2 - Address 1E.32 - 1E.33 */ + unsigned int pairBReflection_2 : 3; /* 1E.C881.A:8 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C881.7 RO Reserved 7 + AQ_GlobalCableDiagnosticImpedance_HHD.u1.bits_1.reserved_7 + + + + Reserved + + */ + unsigned int reserved_7 : 1; /* 1E.C881.7 RO */ + /* Reserved + */ + /*! \brief 1E.C881.6:4 RO Pair B Reflection #3 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u1.bits_1.pairBReflection_3 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the third worst reflection on Pair B. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 2 - Address 1E.32 - 1E.33 */ + unsigned int pairBReflection_3 : 3; /* 1E.C881.6:4 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C881.3 RO Reserved 8 + AQ_GlobalCableDiagnosticImpedance_HHD.u1.bits_1.reserved_8 + + + + Reserved + + */ + unsigned int reserved_8 : 1; /* 1E.C881.3 RO */ + /* Reserved + */ + /*! \brief 1E.C881.2:0 RO Pair B Reflection #4 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u1.bits_1.pairBReflection_4 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the fourth worst reflection on Pair B. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 2 - Address 1E.32 - 1E.33 */ + unsigned int pairBReflection_4 : 3; /* 1E.C881.2:0 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Cable Diagnostic Impedance */ + union + { + struct + { + /*! \brief 1E.C882.F RO Reserved 9 + AQ_GlobalCableDiagnosticImpedance_HHD.u2.bits_2.reserved_9 + + + + Reserved + + */ + unsigned int reserved_9 : 1; /* 1E.C882.F RO */ + /* Reserved + */ + /*! \brief 1E.C882.E:C RO Pair C Reflection #1 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u2.bits_2.pairCReflection_1 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the first worst reflection on Pair C. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.33 */ + unsigned int pairCReflection_1 : 3; /* 1E.C882.E:C RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C882.B RO Reserved 10 + AQ_GlobalCableDiagnosticImpedance_HHD.u2.bits_2.reserved_10 + + + + Reserved + + */ + unsigned int reserved_10 : 1; /* 1E.C882.B RO */ + /* Reserved + */ + /*! \brief 1E.C882.A:8 RO Pair C Reflection #2 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u2.bits_2.pairCReflection_2 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the second worst reflection on Pair C. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.33 */ + unsigned int pairCReflection_2 : 3; /* 1E.C882.A:8 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C882.7 RO Reserved 11 + AQ_GlobalCableDiagnosticImpedance_HHD.u2.bits_2.reserved_11 + + + + Reserved + + */ + unsigned int reserved_11 : 1; /* 1E.C882.7 RO */ + /* Reserved + */ + /*! \brief 1E.C882.6:4 RO Pair C Reflection #3 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u2.bits_2.pairCReflection_3 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the third worst reflection on Pair C. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.33 */ + unsigned int pairCReflection_3 : 3; /* 1E.C882.6:4 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C882.3 RO Reserved 12 + AQ_GlobalCableDiagnosticImpedance_HHD.u2.bits_2.reserved_12 + + + + Reserved + + */ + unsigned int reserved_12 : 1; /* 1E.C882.3 RO */ + /* Reserved + */ + /*! \brief 1E.C882.2:0 RO Pair C Reflection #4 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u2.bits_2.pairCReflection_4 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the fourth worst reflection on Pair C. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.33 */ + unsigned int pairCReflection_4 : 3; /* 1E.C882.2:0 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global Cable Diagnostic Impedance */ + union + { + struct + { + /*! \brief 1E.C883.F RO Reserved 13 + AQ_GlobalCableDiagnosticImpedance_HHD.u3.bits_3.reserved_13 + + + + Reserved + + */ + unsigned int reserved_13 : 1; /* 1E.C883.F RO */ + /* Reserved + */ + /*! \brief 1E.C883.E:C RO Pair D Reflection #1 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u3.bits_3.pairDReflection_1 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the first worst reflection on Pair D. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.34 - 1E.35 */ + unsigned int pairDReflection_1 : 3; /* 1E.C883.E:C RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C883.B RO Reserved 14 + AQ_GlobalCableDiagnosticImpedance_HHD.u3.bits_3.reserved_14 + + + + Reserved + + */ + unsigned int reserved_14 : 1; /* 1E.C883.B RO */ + /* Reserved + */ + /*! \brief 1E.C883.A:8 RO Pair D Reflection #2 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u3.bits_3.pairDReflection_2 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the second worst reflection on Pair D. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.34 - 1E.35 */ + unsigned int pairDReflection_2 : 3; /* 1E.C883.A:8 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C883.7 RO Reserved 15 + AQ_GlobalCableDiagnosticImpedance_HHD.u3.bits_3.reserved_15 + + + + Reserved + + */ + unsigned int reserved_15 : 1; /* 1E.C883.7 RO */ + /* Reserved + */ + /*! \brief 1E.C883.6:4 RO Pair D Reflection #3 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u3.bits_3.pairDReflection_3 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the third worst reflection on Pair D. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.34 - 1E.35 */ + unsigned int pairDReflection_3 : 3; /* 1E.C883.6:4 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + /*! \brief 1E.C883.3 RO Reserved 16 + AQ_GlobalCableDiagnosticImpedance_HHD.u3.bits_3.reserved_16 + + + + Reserved + + */ + unsigned int reserved_16 : 1; /* 1E.C883.3 RO */ + /* Reserved + */ + /*! \brief 1E.C883.2:0 RO Pair D Reflection #4 [2:0] + AQ_GlobalCableDiagnosticImpedance_HHD.u3.bits_3.pairDReflection_4 + + + + 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + + + Notes: + The impedance of the fourth worst reflection on Pair D. The corresponding length of this reflection from the PHY is given in See Global Cable Diagnostic Status 3 - Address 1E.34 - 1E.35 */ + unsigned int pairDReflection_4 : 3; /* 1E.C883.2:0 RO */ + /* 111 = Open Circuit (> 300W) + 110 = High Mismatch (> 115W) + 101 = Low Mismatch (< 85W) + 100 = Short Circuit (< 30W) + 0xx= No information available + */ + } bits_3; + uint16_t word_3; + } u3; +} AQ_GlobalCableDiagnosticImpedance_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Status: 1E.C884 */ +/* Global Status: 1E.C884 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Status */ + union + { + struct + { + /*! \brief 1E.C884.F:8 RO Reserved Status 0 [7:0] + AQ_GlobalStatus_HHD.u0.bits_0.reservedStatus_0 + + + + Reserved + + */ + unsigned int reservedStatus_0 : 8; /* 1E.C884.F:8 RO */ + /* Reserved + */ + /*! \brief 1E.C884.7:0 RO Cable Length [7:0] + AQ_GlobalStatus_HHD.u0.bits_0.cableLength + + + + The estimated length of the cable in meters + + + Notes: + The length of the cable shown here is estimated from the cable diagnostic engine and should be accurate to +/-1m. */ + unsigned int cableLength : 8; /* 1E.C884.7:0 RO */ + /* The estimated length of the cable in meters + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalStatus_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Reserved Status: 1E.C885 */ +/* Global Reserved Status: 1E.C885 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Reserved Status */ + union + { + struct + { + /*! \brief 1E.C885.F:A RO Nearly Seconds MSW[5:0] + AQ_GlobalReservedStatus_HHD.u0.bits_0.nearlySecondsMSW + + + + Bits 16 to 21 of the 22 bit "Nearly Seconds" uptime counter. + + + Notes: + The "Nearly Seconds" counter is incremented every 1024 milliseconds. */ + unsigned int nearlySecondsMSW : 6; /* 1E.C885.F:A RO */ + /* Bits 16 to 21 of the 22 bit "Nearly Seconds" uptime counter. + */ + /*! \brief 1E.C885.9:8 ROSPD XENPAK NVR Status [1:0] + AQ_GlobalReservedStatus_HHD.u0.bits_0.xenpakNvrStatus + + Provisionable Default = 0x0 + + Status of XENPAK NVR: + 0: NVR not enabled + 1: Last NVR operation succeeded + 2: Last NVR operation failed + 3: Reserved + + + Notes: + XENPAK register space is mirrored in NVR (SPI ROM). This register indicates the status of the last NVR operation. */ + unsigned int xenpakNvrStatus : 2; /* 1E.C885.9:8 ROSPD Provisionable Default = 0x0 */ + /* Status of XENPAK NVR: + 0: NVR not enabled + 1: Last NVR operation succeeded + 2: Last NVR operation failed + 3: Reserved + */ + /*! \brief 1E.C885.7:4 ROSPD Firmware Build ID [3:0] + AQ_GlobalReservedStatus_HHD.u0.bits_0.firmwareBuildID + + Provisionable Default = 0x0 + + Firmware Build ID + + + Notes: + Customers may receive multiple ROM images that differ only in their provisioning. This field is used to differentiate those images. This field is used in conjunction with the firmware major and minor revision numbers to uniquely identify ROM images. */ + unsigned int firmwareBuildID : 4; /* 1E.C885.7:4 ROSPD Provisionable Default = 0x0 */ + /* Firmware Build ID + */ + /*! \brief 1E.C885.3:0 ROSPD Provisioning ID [3:0] + AQ_GlobalReservedStatus_HHD.u0.bits_0.provisioningID + + Provisionable Default = 0x0 + + Provisioning ID + + + Notes: + Customers may receive multiple ROM images that differ only in their provisioning. This field is used to differentiate those images. This field is used in conjunction with the firmware major and minor revision numbers to uniquely identify ROM images. */ + unsigned int provisioningID : 4; /* 1E.C885.3:0 ROSPD Provisionable Default = 0x0 */ + /* Provisioning ID + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Reserved Status */ + union + { + struct + { + /*! \brief 1E.C886.F:0 RO Nearly Seconds LSW [F:0] + AQ_GlobalReservedStatus_HHD.u1.bits_1.nearlySecondsLSW + + + + Bits 0 to 15 of the 22 bit "Nearly Seconds" uptime counter + + + Notes: + The "Nearly Seconds" counter is incremented every 1024 milliseconds. */ + unsigned int nearlySecondsLSW : 16; /* 1E.C886.F:0 RO */ + /* Bits 0 to 15 of the 22 bit "Nearly Seconds" uptime counter + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Reserved Status */ + union + { + struct + { + /*! \brief 1E.C887.F ROS DTE Status + AQ_GlobalReservedStatus_HHD.u2.bits_2.dteStatus + + Default = 0x0 + + 1 = Need power + 0 = Don't need power + + */ + unsigned int dteStatus : 1; /* 1E.C887.F ROS Default = 0x0 */ + /* 1 = Need power + 0 = Don't need power + */ + /*! \brief 1E.C887.E ROS Power Up Stall Status + AQ_GlobalReservedStatus_HHD.u2.bits_2.powerUpStallStatus + + Default = 0x0 + + 1 = FW is stalled at power up + 0 = Firmware is unstalled + + */ + unsigned int powerUpStallStatus : 1; /* 1E.C887.E ROS Default = 0x0 */ + /* 1 = FW is stalled at power up + 0 = Firmware is unstalled + */ + /*! \brief 1E.C887.D:0 RO Reserved Status 3 [D:0] + AQ_GlobalReservedStatus_HHD.u2.bits_2.reservedStatus_3 + + + + Reserved for future use + + */ + unsigned int reservedStatus_3 : 14; /* 1E.C887.D:0 RO */ + /* Reserved for future use + */ + } bits_2; + uint16_t word_2; + } u2; + /*! \brief Union for bit and word level access of word 3 of Global Reserved Status */ + union + { + struct + { + /*! \brief 1E.C888.F:B RO Loopback Status [4:0] + AQ_GlobalReservedStatus_HHD.u3.bits_3.loopbackStatus + + Default = 0x00 + + 0x00 = No loopback + 0x01 = System Interface - System Loopback + 0x02 = System Interface - System Loopback with Passthrough + 0x03 = System Interface - Network Loopback + 0x04 = System Interface - Network Loopback with Passthrough + 0x05 = System Interface - Network Loopback with Passthrough and Merge + 0x06 = System Interface - Peer-to-peer loopback + 0x07 - 0x08 = Reserved + 0x09 = Network Interface - System Loopback + 0x0A = Network Interface - System Loopback with Passthrough + 0x0B = Network Interface - Network Loopback + 0x0C = Network Interface - Network Loopback with Passthrough + 0x0D = Network Interface - Peer-to-peer loopback + 0x0E - 0x0F = Reserved + 0x10 = Cross-connect System Loopback + 0x11 = Cross-connect Network Loopback + 0x12 - 0x13 = Reserved + 0x14 = Network Interface - System Loopback via Loopback Plug + 0x15 - 0x1F = Reserved + + + Notes: + These bits, in conjunction with the chip configuration and the rate (Bits 1:0), report the selected loopback. + + */ + unsigned int loopbackStatus : 5; /* 1E.C888.F:B RO Default = 0x00 */ + /* 0x00 = No loopback + 0x01 = System Interface - System Loopback + 0x02 = System Interface - System Loopback with Passthrough + 0x03 = System Interface - Network Loopback + 0x04 = System Interface - Network Loopback with Passthrough + 0x05 = System Interface - Network Loopback with Passthrough and Merge + 0x06 = System Interface - Peer-to-peer loopback + 0x07 - 0x08 = Reserved + 0x09 = Network Interface - System Loopback + 0x0A = Network Interface - System Loopback with Passthrough + 0x0B = Network Interface - Network Loopback + 0x0C = Network Interface - Network Loopback with Passthrough + 0x0D = Network Interface - Peer-to-peer loopback + 0x0E - 0x0F = Reserved + 0x10 = Cross-connect System Loopback + 0x11 = Cross-connect Network Loopback + 0x12 - 0x13 = Reserved + 0x14 = Network Interface - System Loopback via Loopback Plug + 0x15 - 0x1F = Reserved + */ + /*! \brief 1E.C888.A:6 RO Reserved Status 4 [4:0] + AQ_GlobalReservedStatus_HHD.u3.bits_3.reservedStatus_4 + + Default = 0x00 + + Reserved for future use + + */ + unsigned int reservedStatus_4 : 5; /* 1E.C888.A:6 RO Default = 0x00 */ + /* Reserved for future use + */ + /*! \brief 1E.C888.5 RO MDI Packet Generation Status + AQ_GlobalReservedStatus_HHD.u3.bits_3.mdiPacketGenerationStatus + + Default = 0x0 + + 1 = CRPAT packet generation out MDI interface + 0 = No CRPAT packet generation out MDI interface + + + Notes: + Reports whether the CRPAT packet generator in the PHY outputs on the MDI interface at the selected rate. */ + unsigned int mdiPacketGenerationStatus : 1; /* 1E.C888.5 RO Default = 0x0 */ + /* 1 = CRPAT packet generation out MDI interface + 0 = No CRPAT packet generation out MDI interface + */ + /*! \brief 1E.C888.4 RO Look-Aside Port Packet Generation Status + AQ_GlobalReservedStatus_HHD.u3.bits_3.look_asidePortPacketGenerationStatus + + Default = 0x0 + + 1 = CRPAT packet generation out 10G look-aside interface (KR0) + 0 = No CRPAT packet generation out 10G look-aside interface (KR0) + + + Notes: + Reports whether the CRPAT packet generator in the PHY outputs on the KR0 interface at the selected rate. */ + unsigned int look_asidePortPacketGenerationStatus : 1; /* 1E.C888.4 RO Default = 0x0 */ + /* 1 = CRPAT packet generation out 10G look-aside interface (KR0) + 0 = No CRPAT packet generation out 10G look-aside interface (KR0) + */ + /*! \brief 1E.C888.3 RO System I/F Packet Generation Status + AQ_GlobalReservedStatus_HHD.u3.bits_3.systemI_fPacketGenerationStatus + + Default = 0x0 + + 1 = CRPAT packet generation out 10G system interface + 0 = No CRPAT packet generation out 10G system interface + + + Notes: + Reports whether the CRPAT packet generator in the PHY outputs on the selected system interface at the selected rate. */ + unsigned int systemI_fPacketGenerationStatus : 1; /* 1E.C888.3 RO Default = 0x0 */ + /* 1 = CRPAT packet generation out 10G system interface + 0 = No CRPAT packet generation out 10G system interface + */ + /*! \brief 1E.C888.2 RO Reserved Status 4a + AQ_GlobalReservedStatus_HHD.u3.bits_3.reservedStatus_4a + + Default = 0x0 + + Reserved for future use + + */ + unsigned int reservedStatus_4a : 1; /* 1E.C888.2 RO Default = 0x0 */ + /* Reserved for future use + */ + /*! \brief 1E.C888.1:0 RO Rate [1:0] + AQ_GlobalReservedStatus_HHD.u3.bits_3.rate + + Default = 0x0 + + 0x3 = 10G + 0x2 = 1G + 0x1 = 100M + 0x0 = invalid + + + Notes: + These bits report the selected rate for the loopback and packet generation. */ + unsigned int rate : 2; /* 1E.C888.1:0 RO Default = 0x0 */ + /* 0x3 = 10G + 0x2 = 1G + 0x1 = 100M + 0x0 = invalid + */ + } bits_3; + uint16_t word_3; + } u3; +} AQ_GlobalReservedStatus_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Alarms: 1E.CC00 */ +/* Global Alarms: 1E.CC00 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Alarms */ + union + { + struct + { + unsigned int reserved0 : 1; + /*! \brief 1E.CC00.E LH High Temperature Failure + AQ_GlobalAlarms_HHD.u0.bits_0.highTemperatureFailure + + + + 1 = High temperature failure threshold has been exceeded + + + Notes: + + + + + These bits mirror the matching bit in 1.A070 and 1.A074. These bits are driven by Bits E:B in See Global General Status 1: Address 1E.C830 . */ + unsigned int highTemperatureFailure : 1; /* 1E.CC00.E LH */ + /* 1 = High temperature failure threshold has been exceeded + */ + /*! \brief 1E.CC00.D LH Low Temperature Failure + AQ_GlobalAlarms_HHD.u0.bits_0.lowTemperatureFailure + + + + 1 = Low temperature failure threshold has been exceeded + + + Notes: + + + + + These bits mirror the matching bit in 1.A070 and 1.A074. These bits are driven by Bits E:B in See Global General Status 1: Address 1E.C830 . */ + unsigned int lowTemperatureFailure : 1; /* 1E.CC00.D LH */ + /* 1 = Low temperature failure threshold has been exceeded + */ + /*! \brief 1E.CC00.C LH High Temperature Warning + AQ_GlobalAlarms_HHD.u0.bits_0.highTemperatureWarning + + + + 1 = High temperature warning threshold has been exceeded + + + Notes: + + + + + These bits mirror the matching bit in 1.A070 and 1.A074. These bits are driven by Bits E:B in See Global General Status 1: Address 1E.C830 . */ + unsigned int highTemperatureWarning : 1; /* 1E.CC00.C LH */ + /* 1 = High temperature warning threshold has been exceeded + */ + /*! \brief 1E.CC00.B LH Low Temperature Warning + AQ_GlobalAlarms_HHD.u0.bits_0.lowTemperatureWarning + + + + 1 = Low temperature warning threshold has been exceeded + + + Notes: + + + + + These bits mirror the matching bit in 1.A070 and 1.A074. These bits are driven by Bits E:B in See Global General Status 1: Address 1E.C830 . */ + unsigned int lowTemperatureWarning : 1; /* 1E.CC00.B LH */ + /* 1 = Low temperature warning threshold has been exceeded + */ + unsigned int reserved1 : 4; + /*! \brief 1E.CC00.6 LH Reset completed + AQ_GlobalAlarms_HHD.u0.bits_0.resetCompleted + + + + 1 = Chip wide reset completed + + Notes: + This bit is set by the microprocessor when it has completed it's initialization sequence. This bit is mirrored in 1.CC02.0 */ + unsigned int resetCompleted : 1; /* 1E.CC00.6 LH */ + /* 1 = Chip wide reset completed */ + unsigned int reserved2 : 1; + /*! \brief 1E.CC00.4 LH Device Fault + AQ_GlobalAlarms_HHD.u0.bits_0.deviceFault + + + + 1 = Fault + + Notes: + When set, a fault has been detected by the uP and the associated 16 bit error code is visible in See Global Configuration Fault Message: Address 1E.C850 */ + unsigned int deviceFault : 1; /* 1E.CC00.4 LH */ + /* 1 = Fault */ + /*! \brief 1E.CC00.3 LH Reserved Alarm A + AQ_GlobalAlarms_HHD.u0.bits_0.reservedAlarmA + + + + Reserved for future use + + */ + unsigned int reservedAlarmA : 1; /* 1E.CC00.3 LH */ + /* Reserved for future use + */ + /*! \brief 1E.CC00.2 LH Reserved Alarm B + AQ_GlobalAlarms_HHD.u0.bits_0.reservedAlarmB + + + + Reserved for future use + + */ + unsigned int reservedAlarmB : 1; /* 1E.CC00.2 LH */ + /* Reserved for future use + */ + /*! \brief 1E.CC00.1 LH Reserved Alarm C + AQ_GlobalAlarms_HHD.u0.bits_0.reservedAlarmC + + + + Reserved for future use + + */ + unsigned int reservedAlarmC : 1; /* 1E.CC00.1 LH */ + /* Reserved for future use + */ + /*! \brief 1E.CC00.0 LH Reserved Alarm D + AQ_GlobalAlarms_HHD.u0.bits_0.reservedAlarmD + + + + Reserved for future use + + */ + unsigned int reservedAlarmD : 1; /* 1E.CC00.0 LH */ + /* Reserved for future use + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Alarms */ + union + { + struct + { + unsigned int reserved0 : 1; + /*! \brief 1E.CC01.E LH Smart Power-Down Entered + AQ_GlobalAlarms_HHD.u1.bits_1.smartPower_downEntered + + + + 1 = Smart Power-Down State Entered + + + Notes: + When this bit is set, it indicates that the Smart Power-Down state was entered */ + unsigned int smartPower_downEntered : 1; /* 1E.CC01.E LH */ + /* 1 = Smart Power-Down State Entered + */ + /*! \brief 1E.CC01.D RO XENPAK Alarm + AQ_GlobalAlarms_HHD.u1.bits_1.xenpakAlarm + + + + 1 = XENPAK Alarm + + */ + unsigned int xenpakAlarm : 1; /* 1E.CC01.D RO */ + /* 1 = XENPAK Alarm + */ + /*! \brief 1E.CC01.C LH IP Phone Detect + AQ_GlobalAlarms_HHD.u1.bits_1.ipPhoneDetect + + + + 1 = IP Phone Detect + + + Notes: + Assertion of this bit means that the presence of an IP Phone has been detected. */ + unsigned int ipPhoneDetect : 1; /* 1E.CC01.C LH */ + /* 1 = IP Phone Detect + */ + /*! \brief 1E.CC01.B LH DTE Status Change + AQ_GlobalAlarms_HHD.u1.bits_1.dteStatusChange + + + + 1 = DTE status change + + + Notes: + Change in 1E.C887[F]. */ + unsigned int dteStatusChange : 1; /* 1E.CC01.B LH */ + /* 1 = DTE status change + */ + /*! \brief 1E.CC01.A:8 LH Reserved Alarms [2:0] + AQ_GlobalAlarms_HHD.u1.bits_1.reservedAlarms + + + + Reserved + + + */ + unsigned int reservedAlarms : 3; /* 1E.CC01.A:8 LH */ + /* Reserved + + */ + /*! \brief 1E.CC01.7 LH MDIO Command Handling Overflow + AQ_GlobalAlarms_HHD.u1.bits_1.mdioCommandHandlingOverflow + + + + 1 = PHY was issued more MDIO requests than it could service in it's request buffer + + + Notes: + Assertion of this bit means that more MDIO commands were issued than FW could handle. */ + unsigned int mdioCommandHandlingOverflow : 1; /* 1E.CC01.7 LH */ + /* 1 = PHY was issued more MDIO requests than it could service in it's request buffer + */ + unsigned int reserved1 : 6; + unsigned int reserved2 : 1; + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Alarms */ + union + { + struct + { + /*! \brief 1E.CC02.F LH NVR Operation Complete + AQ_GlobalAlarms_HHD.u2.bits_2.nvrOperationComplete + + + + 1 = NVR operation is complete + + + Notes: + NVR interface is ready interrupt for registers See Global NVR Interface 1: Address 1E.100 - See Global NVR Provisioning Data MSW - Address 1E.17 . */ + unsigned int nvrOperationComplete : 1; /* 1E.CC02.F LH */ + /* 1 = NVR operation is complete + */ + /*! \brief 1E.CC02.E LH Mailbox Operation: Complete + AQ_GlobalAlarms_HHD.u2.bits_2.mailboxOperation_Complete + + + + 1 = Mailbox operation is complete + + + Notes: + Mailbox interface is ready interrupt for registers See Global Vendor Specific Control - Address 1E.C000 - See Global Vendor Specific Provisioning 5 - Address 1E.C404 */ + unsigned int mailboxOperation_Complete : 1; /* 1E.CC02.E LH */ + /* 1 = Mailbox operation is complete + */ + unsigned int reserved0 : 3; + /*! \brief 1E.CC02.A LH uP DRAM Parity Error + AQ_GlobalAlarms_HHD.u2.bits_2.upDramParityError + + + + 1 = Parity error detected in the uP DRAM + + */ + unsigned int upDramParityError : 1; /* 1E.CC02.A LH */ + /* 1 = Parity error detected in the uP DRAM + */ + /*! \brief 1E.CC02.9:8 LH uP IRAM Parity Error [1:0] + AQ_GlobalAlarms_HHD.u2.bits_2.upIramParityError + + + + 1 = Parity error detected in the uP IRAM + + + Notes: + Bit 0 indicates a parity error was detected in the uP IRAM but was corrected. + Bit 1 indicates a multiple parity errors were detected in the uP IRAM and could not be corrected. + The uP IRAM is protected with ECC. */ + unsigned int upIramParityError : 2; /* 1E.CC02.9:8 LH */ + /* 1 = Parity error detected in the uP IRAM + */ + unsigned int reserved1 : 2; + /*! \brief 1E.CC02.5 LRF Tx Enable State Change + AQ_GlobalAlarms_HHD.u2.bits_2.txEnableStateChange + + + + 1 = TX_EN pin has changed state + + */ + unsigned int txEnableStateChange : 1; /* 1E.CC02.5 LRF */ + /* 1 = TX_EN pin has changed state + */ + unsigned int reserved2 : 2; + /*! \brief 1E.CC02.2 LH MDIO MMD Error + AQ_GlobalAlarms_HHD.u2.bits_2.mdioMMD_Error + + + + 1 = Invalid MMD address detected + + */ + unsigned int mdioMMD_Error : 1; /* 1E.CC02.2 LH */ + /* 1 = Invalid MMD address detected + */ + /*! \brief 1E.CC02.1 LH MDIO Timeout Error + AQ_GlobalAlarms_HHD.u2.bits_2.mdioTimeoutError + + + + 1 = MDIO timeout detected + + */ + unsigned int mdioTimeoutError : 1; /* 1E.CC02.1 LH */ + /* 1 = MDIO timeout detected + */ + /*! \brief 1E.CC02.0 LH Watchdog Timer Alarm + AQ_GlobalAlarms_HHD.u2.bits_2.watchdogTimerAlarm + + + + 1 = Watchdog timer alarm + + */ + unsigned int watchdogTimerAlarm : 1; /* 1E.CC02.0 LH */ + /* 1 = Watchdog timer alarm + */ + } bits_2; + uint16_t word_2; + } u2; +} AQ_GlobalAlarms_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Interrupt Mask: 1E.D400 */ +/* Global Interrupt Mask: 1E.D400 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Interrupt Mask */ + union + { + struct + { + unsigned int reserved0 : 1; + /*! \brief 1E.D400.E R/WPD High Temperature Failure Mask + AQ_GlobalInterruptMask_HHD.u0.bits_0.highTemperatureFailureMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int highTemperatureFailureMask : 1; /* 1E.D400.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D400.D R/WPD Low Temperature Failure Mask + AQ_GlobalInterruptMask_HHD.u0.bits_0.lowTemperatureFailureMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int lowTemperatureFailureMask : 1; /* 1E.D400.D R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D400.C R/WPD High Temperature Warning Mask + AQ_GlobalInterruptMask_HHD.u0.bits_0.highTemperatureWarningMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int highTemperatureWarningMask : 1; /* 1E.D400.C R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D400.B R/WPD Low Temperature Warning Mask + AQ_GlobalInterruptMask_HHD.u0.bits_0.lowTemperatureWarningMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int lowTemperatureWarningMask : 1; /* 1E.D400.B R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved1 : 4; + /*! \brief 1E.D400.6 R/WPD Reset completed Mask + AQ_GlobalInterruptMask_HHD.u0.bits_0.resetCompletedMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int resetCompletedMask : 1; /* 1E.D400.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved2 : 1; + /*! \brief 1E.D400.4 R/WPD Device Fault Mask + AQ_GlobalInterruptMask_HHD.u0.bits_0.deviceFaultMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int deviceFaultMask : 1; /* 1E.D400.4 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D400.3 R/WPD Reserved Alarm A Mask + AQ_GlobalInterruptMask_HHD.u0.bits_0.reservedAlarmAMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int reservedAlarmAMask : 1; /* 1E.D400.3 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D400.2 R/WPD Reserved Alarm B Mask + AQ_GlobalInterruptMask_HHD.u0.bits_0.reservedAlarmBMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int reservedAlarmBMask : 1; /* 1E.D400.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D400.1 R/WPD Reserved Alarm C Mask + AQ_GlobalInterruptMask_HHD.u0.bits_0.reservedAlarmCMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int reservedAlarmCMask : 1; /* 1E.D400.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D400.0 R/WPD Reserved Alarm D Mask + AQ_GlobalInterruptMask_HHD.u0.bits_0.reservedAlarmDMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int reservedAlarmDMask : 1; /* 1E.D400.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + } bits_0; + uint16_t word_0; + } u0; + /*! \brief Union for bit and word level access of word 1 of Global Interrupt Mask */ + union + { + struct + { + unsigned int reserved0 : 1; + /*! \brief 1E.D401.E R/WPD Smart Power-Down Entered Mask + AQ_GlobalInterruptMask_HHD.u1.bits_1.smartPower_downEnteredMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int smartPower_downEnteredMask : 1; /* 1E.D401.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D401.D R/WPD XENPAK Alarm Mask + AQ_GlobalInterruptMask_HHD.u1.bits_1.xenpakAlarmMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int xenpakAlarmMask : 1; /* 1E.D401.D R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D401.C R/WPD IP Phone Detect Mask + AQ_GlobalInterruptMask_HHD.u1.bits_1.ipPhoneDetectMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int ipPhoneDetectMask : 1; /* 1E.D401.C R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D401.B R/WPD DTE Status Change Mask + AQ_GlobalInterruptMask_HHD.u1.bits_1.dteStatusChangeMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int dteStatusChangeMask : 1; /* 1E.D401.B R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D401.A:8 R/WPD Reserved Alarms Mask [2:0] + AQ_GlobalInterruptMask_HHD.u1.bits_1.reservedAlarmsMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int reservedAlarmsMask : 3; /* 1E.D401.A:8 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D401.7 R/WPD MDIO Command Handling Overflow Mask + AQ_GlobalInterruptMask_HHD.u1.bits_1.mdioCommandHandlingOverflowMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int mdioCommandHandlingOverflowMask : 1; /* 1E.D401.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int reserved1 : 6; + /*! \brief 1E.D401.0 R/WPD Diagnostic Alarm Mask + AQ_GlobalInterruptMask_HHD.u1.bits_1.diagnosticAlarmMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int diagnosticAlarmMask : 1; /* 1E.D401.0 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + } bits_1; + uint16_t word_1; + } u1; + /*! \brief Union for bit and word level access of word 2 of Global Interrupt Mask */ + union + { + struct + { + /*! \brief 1E.D402.F R/WPD NVR Operation Complete Mask + AQ_GlobalInterruptMask_HHD.u2.bits_2.nvrOperationCompleteMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + Notes: + NVR interface is ready interrupt for registers See Global NVR Interface 1: Address 1E.100 - See Global NVR Provisioning Data MSW - Address 1E.17 */ + unsigned int nvrOperationCompleteMask : 1; /* 1E.D402.F R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D402.E R/WPD Mailbox Operation Complete Mask + AQ_GlobalInterruptMask_HHD.u2.bits_2.mailboxOperationCompleteMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + Notes: + Mailbox interface is ready interrupt for registers See Global Vendor Specific Control - Address 1E.C000 - See Global Vendor Specific Provisioning 5 - Address 1E.C404 */ + unsigned int mailboxOperationCompleteMask : 1; /* 1E.D402.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved0 : 3; + /*! \brief 1E.D402.A R/WPD uP DRAM Parity Error Mask + AQ_GlobalInterruptMask_HHD.u2.bits_2.upDramParityErrorMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int upDramParityErrorMask : 1; /* 1E.D402.A R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + /*! \brief 1E.D402.9:8 R/WPD uP IRAM Parity Error Mask [1:0] + AQ_GlobalInterruptMask_HHD.u2.bits_2.upIramParityErrorMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + + */ + unsigned int upIramParityErrorMask : 2; /* 1E.D402.9:8 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int reserved1 : 2; + /*! \brief 1E.D402.5 R/WPD Tx Enable State Change Mask + AQ_GlobalInterruptMask_HHD.u2.bits_2.txEnableStateChangeMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int txEnableStateChangeMask : 1; /* 1E.D402.5 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved2 : 2; + /*! \brief 1E.D402.2 R/WPD MDIO MMD Error Mask + AQ_GlobalInterruptMask_HHD.u2.bits_2.mdioMMD_ErrorMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int mdioMMD_ErrorMask : 1; /* 1E.D402.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D402.1 R/WPD MDIO Timeout Error Mask + AQ_GlobalInterruptMask_HHD.u2.bits_2.mdioTimeoutErrorMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int mdioTimeoutErrorMask : 1; /* 1E.D402.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.D402.0 R/WPD Watchdog Timer Alarm Mask + AQ_GlobalInterruptMask_HHD.u2.bits_2.watchdogTimerAlarmMask + + Provisionable Default = 0x1 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int watchdogTimerAlarmMask : 1; /* 1E.D402.0 R/WPD Provisionable Default = 0x1 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + } bits_2; + uint16_t word_2; + } u2; +} AQ_GlobalInterruptMask_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Chip-Wide Standard Interrupt Flags: 1E.FC00 */ +/* Global Chip-Wide Standard Interrupt Flags: 1E.FC00 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Chip-Wide Standard Interrupt Flags */ + union + { + struct + { + /*! \brief 1E.FC00.F RO PMA Standard Alarm 1 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_HHD.u0.bits_0.pmaStandardAlarm_1Interrupt + + + + 1 = Interrupt in PMA standard alarms 1 + + + Notes: + An interrupt was generated from bit 1.1.2. + An interrupt was generated from status register ( See PHY XS Standard Status 1 - Address 4.1 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 2 - Address 4.A001 ) */ + unsigned int pmaStandardAlarm_1Interrupt : 1; /* 1E.FC00.F RO */ + /* 1 = Interrupt in PMA standard alarms 1 + */ + /*! \brief 1E.FC00.E RO PMA Standard Alarm 2 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_HHD.u0.bits_0.pmaStandardAlarm_2Interrupt + + + + 1 = Interrupt in PMA standard alarms 2 + + + Notes: + An interrupt was generated from either bit 1.8.B or 1.8.A. + An interrupt was generated from status register ( See PHY XS Standard Vendor Devices in Package - Address 4.8 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 8 - Address 4.A008 ) */ + unsigned int pmaStandardAlarm_2Interrupt : 1; /* 1E.FC00.E RO */ + /* 1 = Interrupt in PMA standard alarms 2 + */ + /*! \brief 1E.FC00.D RO PCS Standard Alarm 1 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_HHD.u0.bits_0.pcsStandardAlarm_1Interrupt + + + + 1 = Interrupt in PCS standard alarms 1 + + + Notes: + An interrupt was generated from status register ( See PHY XS Standard Status 1 - Address 4.1 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 2 - Address 4.A001 ) */ + unsigned int pcsStandardAlarm_1Interrupt : 1; /* 1E.FC00.D RO */ + /* 1 = Interrupt in PCS standard alarms 1 + */ + /*! \brief 1E.FC00.C RO PCS Standard Alarm 2 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_HHD.u0.bits_0.pcsStandardAlarm_2Interrupt + + + + 1 = Interrupt in PCS standard alarms 2 + + + Notes: + An interrupt was generated from status register ( See PHY XS Standard Vendor Devices in Package - Address 4.8 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 8 - Address 4.A008 ) */ + unsigned int pcsStandardAlarm_2Interrupt : 1; /* 1E.FC00.C RO */ + /* 1 = Interrupt in PCS standard alarms 2 + */ + /*! \brief 1E.FC00.B RO PCS Standard Alarm 3 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_HHD.u0.bits_0.pcsStandardAlarm_3Interrupt + + + + 1 = Interrupt in PCS standard alarms 3 + + + Notes: + An interrupt was generated from status register ( See PCS 10GBASE-T Status 2 - Address 3.21 ) and the corresponding mask register. ( See PCS Standard Interrupt Mask 1 - Address 3.E021 ) */ + unsigned int pcsStandardAlarm_3Interrupt : 1; /* 1E.FC00.B RO */ + /* 1 = Interrupt in PCS standard alarms 3 + */ + /*! \brief 1E.FC00.A RO PHY XS Standard Alarms 1 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_HHD.u0.bits_0.phyXS_StandardAlarms_1Interrupt + + + + 1 = Interrupt in PHY XS standard alarms 1 + + + Notes: + An interrupt was generated from the status register ( See PHY XS Standard Status 1 - Address 4.1 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 2 - Address 4.A001 ) */ + unsigned int phyXS_StandardAlarms_1Interrupt : 1; /* 1E.FC00.A RO */ + /* 1 = Interrupt in PHY XS standard alarms 1 + */ + /*! \brief 1E.FC00.9 RO PHY XS Standard Alarms 2 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_HHD.u0.bits_0.phyXS_StandardAlarms_2Interrupt + + + + 1 = Interrupt in PHY XS standard alarms 2 + + + Notes: + An interrupt was generated from the status register ( See PHY XS Standard Vendor Devices in Package - Address 4.8 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 8 - Address 4.A008 ) */ + unsigned int phyXS_StandardAlarms_2Interrupt : 1; /* 1E.FC00.9 RO */ + /* 1 = Interrupt in PHY XS standard alarms 2 + */ + /*! \brief 1E.FC00.8 RO Autonegotiation Standard Alarms 1 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_HHD.u0.bits_0.autonegotiationStandardAlarms_1Interrupt + + + + 1 = Interrupt in Autonegotiation standard alarms 1 + + + Notes: + An interrupt was generated from status register ( See PHY XS Standard Status 1 - Address 4.1 ) and the corresponding mask register. ( See Autonegotiation Standard LASI Interrupt Mask 1: Address 7.D000 ) */ + unsigned int autonegotiationStandardAlarms_1Interrupt : 1; /* 1E.FC00.8 RO */ + /* 1 = Interrupt in Autonegotiation standard alarms 1 + */ + /*! \brief 1E.FC00.7 RO Autonegotiation Standard Alarms 2 Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_HHD.u0.bits_0.autonegotiationStandardAlarms_2Interrupt + + + + 1 = Interrupt in Autonegotiation standard alarms 2 + + + Notes: + An interrupt was generated from status register ( See Autonegotiation 10GBASE-T Status Register - Address 7.21 ) and the corresponding mask register. ( See PHY XS Standard Transmit XAUI Rx Interrupt Mask 8 - Address 4.A008 ) */ + unsigned int autonegotiationStandardAlarms_2Interrupt : 1; /* 1E.FC00.7 RO */ + /* 1 = Interrupt in Autonegotiation standard alarms 2 + */ + /*! \brief 1E.FC00.6 RO GbE Standard Alarms Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_HHD.u0.bits_0.gbeStandardAlarmsInterrupt + + + + 1 = Interrupt in GbE standard alarms + + + Notes: + An interrupt was generated from the TGE core. */ + unsigned int gbeStandardAlarmsInterrupt : 1; /* 1E.FC00.6 RO */ + /* 1 = Interrupt in GbE standard alarms + */ + unsigned int reserved0 : 5; + /*! \brief 1E.FC00.0 RO All Vendor Alarms Interrupt + AQ_GlobalChip_wideStandardInterruptFlags_HHD.u0.bits_0.allVendorAlarmsInterrupt + + + + 1 = Interrupt in all vendor alarms + + + Notes: + An interrupt was generated from status register ( See Global Chip-Wide LASI Vendor Interrupt Flags: Address 1E.FC01 ) and the corresponding mask register. ( See Global Interrupt LASI Mask: Address 1E.FF01 ) */ + unsigned int allVendorAlarmsInterrupt : 1; /* 1E.FC00.0 RO */ + /* 1 = Interrupt in all vendor alarms + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalChip_wideStandardInterruptFlags_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Chip-Wide Vendor Interrupt Flags: 1E.FC01 */ +/* Global Chip-Wide Vendor Interrupt Flags: 1E.FC01 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Chip-Wide Vendor Interrupt Flags */ + union + { + struct + { + /*! \brief 1E.FC01.F RO PMA Vendor Alarm Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_HHD.u0.bits_0.pmaVendorAlarmInterrupt + + + + 1 = Interrupt in PMA vendor specific alarm + + + Notes: + A PMA alarm was generated. ( See PHY XS Vendor Global Interrupt Flags 1- Address 4.F800 ) */ + unsigned int pmaVendorAlarmInterrupt : 1; /* 1E.FC01.F RO */ + /* 1 = Interrupt in PMA vendor specific alarm + */ + /*! \brief 1E.FC01.E RO PCS Vendor Alarm Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_HHD.u0.bits_0.pcsVendorAlarmInterrupt + + + + 1 = Interrupt in PCS vendor specific alarm + + + Notes: + A PCS alarm was generated. ( See PHY XS Vendor Global Interrupt Flags 1- Address 4.F800 ) */ + unsigned int pcsVendorAlarmInterrupt : 1; /* 1E.FC01.E RO */ + /* 1 = Interrupt in PCS vendor specific alarm + */ + /*! \brief 1E.FC01.D RO PHY XS Vendor Alarm Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_HHD.u0.bits_0.phyXS_VendorAlarmInterrupt + + + + 1 = Interrupt in PHY XS vendor specific alarm + + + Notes: + A PHY XS alarm was generated. ( See PHY XS Vendor Global LASI Interrupt Flags 1: Address 4.FC00 ) */ + unsigned int phyXS_VendorAlarmInterrupt : 1; /* 1E.FC01.D RO */ + /* 1 = Interrupt in PHY XS vendor specific alarm + */ + /*! \brief 1E.FC01.C RO Autonegotiation Vendor Alarm Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_HHD.u0.bits_0.autonegotiationVendorAlarmInterrupt + + + + 1 = Interrupt in Autonegotiation vendor specific alarm + + + Notes: + An Autonegotiation alarm was generated. ( See Autonegotiation Vendor Global LASI Interrupt Flags 1: Address 7.FC00 ) */ + unsigned int autonegotiationVendorAlarmInterrupt : 1; /* 1E.FC01.C RO */ + /* 1 = Interrupt in Autonegotiation vendor specific alarm + */ + /*! \brief 1E.FC01.B RO GbE Vendor Alarm Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_HHD.u0.bits_0.gbeVendorAlarmInterrupt + + + + 1 = Interrupt in GbE vendor specific alarm + + + Notes: + A GbE alarm was generated. ( See GbE PHY Vendor Global LASI Interrupt Flags 1: Address 1D.FC00 ) */ + unsigned int gbeVendorAlarmInterrupt : 1; /* 1E.FC01.B RO */ + /* 1 = Interrupt in GbE vendor specific alarm + */ + unsigned int reserved0 : 8; + /*! \brief 1E.FC01.2 RO Global Alarms 1 Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_HHD.u0.bits_0.globalAlarms_1Interrupt + + + + 1 = Interrupt in Global alarms 1 + + + Notes: + An interrupt was generated from status register ( See Global Vendor Alarms 1 - Address 1E.CC00 ) and the corresponding mask register. ( See Global Vendor Interrupt Mask - Address 1E.D400 ) */ + unsigned int globalAlarms_1Interrupt : 1; /* 1E.FC01.2 RO */ + /* 1 = Interrupt in Global alarms 1 + */ + /*! \brief 1E.FC01.1 RO Global Alarms 2 Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_HHD.u0.bits_0.globalAlarms_2Interrupt + + + + 1 = Interrupt in Global alarms 2 + + + Notes: + An interrupt was generated from status register ( See Global Alarms 2: Address 1E.CC01 ) and the corresponding mask register. ( See Global LASI Interrupt Mask 2: Address 1E.D401 ) */ + unsigned int globalAlarms_2Interrupt : 1; /* 1E.FC01.1 RO */ + /* 1 = Interrupt in Global alarms 2 + */ + /*! \brief 1E.FC01.0 RO Global Alarms 3 Interrupt + AQ_GlobalChip_wideVendorInterruptFlags_HHD.u0.bits_0.globalAlarms_3Interrupt + + + + 1 = Interrupt in Global alarms 3 + + + Notes: + An interrupt was generated from status register ( See Global Vendor Alarms 2: Address 1E.CC01 ) and the corresponding mask register. ( See Global LASI Interrupt Mask 2: Address 1E.D401 ) */ + unsigned int globalAlarms_3Interrupt : 1; /* 1E.FC01.0 RO */ + /* 1 = Interrupt in Global alarms 3 + */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalChip_wideVendorInterruptFlags_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Interrupt Chip-Wide Standard Mask: 1E.FF00 */ +/* Global Interrupt Chip-Wide Standard Mask: 1E.FF00 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Interrupt Chip-Wide Standard Mask */ + union + { + struct + { + /*! \brief 1E.FF00.F R/WPD PMA Standard Alarm 1 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_HHD.u0.bits_0.pmaStandardAlarm_1InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pmaStandardAlarm_1InterruptMask : 1; /* 1E.FF00.F R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.E R/WPD PMA Standard Alarm 2 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_HHD.u0.bits_0.pmaStandardAlarm_2InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pmaStandardAlarm_2InterruptMask : 1; /* 1E.FF00.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.D R/WPD PCS Standard Alarm 1 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_HHD.u0.bits_0.pcsStandardAlarm_1InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pcsStandardAlarm_1InterruptMask : 1; /* 1E.FF00.D R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.C R/WPD PCS Standard Alarm 2 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_HHD.u0.bits_0.pcsStandardAlarm_2InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pcsStandardAlarm_2InterruptMask : 1; /* 1E.FF00.C R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.B R/WPD PCS Standard Alarm 3 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_HHD.u0.bits_0.pcsStandardAlarm_3InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pcsStandardAlarm_3InterruptMask : 1; /* 1E.FF00.B R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.A R/WPD PHY XS Standard Alarms 1 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_HHD.u0.bits_0.phyXS_StandardAlarms_1InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int phyXS_StandardAlarms_1InterruptMask : 1; /* 1E.FF00.A R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.9 R/WPD PHY XS Standard Alarms 2 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_HHD.u0.bits_0.phyXS_StandardAlarms_2InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int phyXS_StandardAlarms_2InterruptMask : 1; /* 1E.FF00.9 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.8 R/WPD Autonegotiation Standard Alarms 1 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_HHD.u0.bits_0.autonegotiationStandardAlarms_1InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int autonegotiationStandardAlarms_1InterruptMask : 1; /* 1E.FF00.8 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.7 R/WPD Autonegotiation Standard Alarms 2 Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_HHD.u0.bits_0.autonegotiationStandardAlarms_2InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int autonegotiationStandardAlarms_2InterruptMask : 1; /* 1E.FF00.7 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF00.6 R/WPD Gbe Standard Alarms Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_HHD.u0.bits_0.gbeStandardAlarmsInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int gbeStandardAlarmsInterruptMask : 1; /* 1E.FF00.6 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved0 : 5; + /*! \brief 1E.FF00.0 R/WPD All Vendor Alarms Interrupt Mask + AQ_GlobalInterruptChip_wideStandardMask_HHD.u0.bits_0.allVendorAlarmsInterruptMask + + Provisionable Default = 0x1 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int allVendorAlarmsInterruptMask : 1; /* 1E.FF00.0 R/WPD Provisionable Default = 0x1 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalInterruptChip_wideStandardMask_HHD; + + +/*---------------------------------------------------------------------------------*/ +/*! \brief Global Interrupt Chip-Wide Vendor Mask: 1E.FF01 */ +/* Global Interrupt Chip-Wide Vendor Mask: 1E.FF01 */ +/*---------------------------------------------------------------------------------*/ +typedef struct +{ + /*! \brief Union for bit and word level access of word 0 of Global Interrupt Chip-Wide Vendor Mask */ + union + { + struct + { + /*! \brief 1E.FF01.F R/WPD PMA Vendor Alarm Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_HHD.u0.bits_0.pmaVendorAlarmInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pmaVendorAlarmInterruptMask : 1; /* 1E.FF01.F R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.E R/WPD PCS Vendor Alarm Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_HHD.u0.bits_0.pcsVendorAlarmInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int pcsVendorAlarmInterruptMask : 1; /* 1E.FF01.E R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.D R/WPD PHY XS Vendor Alarm Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_HHD.u0.bits_0.phyXS_VendorAlarmInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int phyXS_VendorAlarmInterruptMask : 1; /* 1E.FF01.D R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.C R/WPD Autonegotiation Vendor Alarm Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_HHD.u0.bits_0.autonegotiationVendorAlarmInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int autonegotiationVendorAlarmInterruptMask : 1; /* 1E.FF01.C R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.B R/WPD GbE Vendor Alarm Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_HHD.u0.bits_0.gbeVendorAlarmInterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int gbeVendorAlarmInterruptMask : 1; /* 1E.FF01.B R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + unsigned int reserved0 : 8; + /*! \brief 1E.FF01.2 R/WPD Global Alarms 1 Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_HHD.u0.bits_0.globalAlarms_1InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int globalAlarms_1InterruptMask : 1; /* 1E.FF01.2 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.1 R/WPD Global Alarms 2 Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_HHD.u0.bits_0.globalAlarms_2InterruptMask + + Provisionable Default = 0x0 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int globalAlarms_2InterruptMask : 1; /* 1E.FF01.1 R/WPD Provisionable Default = 0x0 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + /*! \brief 1E.FF01.0 R/WPD Global Alarms 3 Interrupt Mask + AQ_GlobalInterruptChip_wideVendorMask_HHD.u0.bits_0.globalAlarms_3InterruptMask + + Provisionable Default = 0x1 + + 1 = Enable interrupt generation + 0 = Disable interrupt generation + */ + unsigned int globalAlarms_3InterruptMask : 1; /* 1E.FF01.0 R/WPD Provisionable Default = 0x1 */ + /* 1 = Enable interrupt generation + 0 = Disable interrupt generation */ + } bits_0; + uint16_t word_0; + } u0; +} AQ_GlobalInterruptChip_wideVendorMask_HHD; + +#endif +/*@}*/ +/*@}*/ diff --git a/feeds/ipq807x/aq-fw-download/src/mdioBootLoadCLD.c b/feeds/ipq807x/aq-fw-download/src/mdioBootLoadCLD.c new file mode 100755 index 000000000..a8e09d8c9 --- /dev/null +++ b/feeds/ipq807x/aq-fw-download/src/mdioBootLoadCLD.c @@ -0,0 +1,193 @@ +/* mdioBootLoadCLD.c */ + +/************************************************************************************ +* Copyright (c) 2015 Aquantia +* +* Permission to use, copy, modify, and/or distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +* +* $File: //depot/icm/proj/Dena/rev1.0/c/Systems/tools/windows/flashUtilities/src/mdioBootLoadCLD.c $ +* +* $Revision: #12 $ +* +* $DateTime: 2014/05/19 15:34:49 $ +* +* $Author: joshd $ +* +* $Label: $ +* +************************************************************************************/ + +/*! \file +This file contains the main (int, char**) file for the mdioBootLoadCLD program, which burns a flash image into a target +Aquantia PHY using the AQ_API. This program calls the API function:

+ + uint8_t AQ_API_WriteBootLoadImage (uint8_t PHY_ID, uint8_t *image, uint16_t *crc16)

+ +to boot load a cld flash image into an Aquantia PHY */ + +/*! \addtogroup mdioBootLoad +@{ +*/ + + + +/*! \def DEBUG +Uncomment this to compile in debug mode. This sets the source to an arbitrary file, defined by DEBUG_FILENAME, +and an arbitrary PHY_ID, defined by DEBUG_PHY_ID. */ +/* #define DEBUG */ + +/*! The debug source file name */ +#define DEBUG_FILENAME "HelloWorld.cld" + +/*! The debug PHY ID */ +#define DEBUG_PHY_ID 0 + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "AQ_API.h" +#include "AQ_PhyInterface.h" + +int sock; +char devname[7]; + +int sock_init() +{ + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + fprintf(stderr, "Error creating socket: %s\n", strerror(errno)); + return -1; + } + + return 0; +} + +int main ( int argc, char **argp) +{ + /* declare local variables */ + FILE *pFile; + uint8_t* image; + uint8_t byte; + unsigned int PHY_ID; + AQ_Retcode resultCode; + AQ_Retcode resultCodes[4]; + uint32_t i; + uint32_t imageSize; + char sourceFileName[1000]; + AQ_API_Port targetPort0; + AQ_API_Port* targetPorts[1]; + AQ_API_Port broadcastPort; + unsigned int provisioningAddresses[1] = {0}; + uint32_t reg1, reg2; + + targetPorts[0] = &targetPort0; + + if(argc < 4) { + fprintf (stderr, "enter file name/netdev name/phy address\n"); + return (101); + } + + /*Copy the file name from command line arg*/ + if (strlcpy (sourceFileName, argp[1], sizeof(sourceFileName)) >= sizeof(sourceFileName)) { + fprintf (stderr, "Filename: %s too long \n", argp[1]); + return (101); + } + /*Copy the interface name from command line arg*/ + strlcpy (devname, argp[2], sizeof(devname)); + /*Get PHY Address from command line arg*/ + PHY_ID = (unsigned int)strtoul(argp[3], NULL, 0); + + /* FIXME: set port and device type */ + targetPort0.device = AQ_DEVICE_HHD; + targetPort0.PHY_ID = PHY_ID; + + broadcastPort.device = AQ_DEVICE_HHD; + broadcastPort.PHY_ID = PHY_ID; + + /* open the source in binary read mode */ + pFile = fopen(sourceFileName, "rb"); + if (pFile == NULL) + { + fprintf (stderr, "Unable to open source file %s\n", sourceFileName); + return (101); + } + fseek (pFile, 0, SEEK_END); + imageSize = ftell (pFile); + + image = (uint8_t*) malloc (imageSize * sizeof(uint8_t)); + fseek (pFile, 0, SEEK_SET); + + /* load the file */ + for (i = 0; i < imageSize; i++) + { + byte = (uint8_t) fgetc (pFile); + image[i] = byte; + } + fclose(pFile); + + + if (sock_init() < 0) + { + fprintf (stderr, "Unable to initialize interface\n"); + return (200); + } + + /* Write in the Auantia phy scratch pad register, + * read back the same reg and match the values written. + */ + AQ_API_MDIO_Write(PHY_ID, 0x1e, 0x300, 0xdead); + AQ_API_MDIO_Write(PHY_ID, 0x1e, 0x301, 0xbeaf); + reg1 = AQ_API_MDIO_Read(PHY_ID, 0x1e, 0x300); + reg2 = AQ_API_MDIO_Read(PHY_ID, 0x1e, 0x301); + if(reg1 != 0xdead && reg2 != 0xbeaf) { + fprintf (stderr, "Scratchpad Read/Write test fail\n"); + return (101); + } + + /* call the boot-load function */ + resultCode = AQ_API_WriteBootLoadImage(targetPorts, 1, provisioningAddresses, resultCodes, &imageSize, image, PHY_ID, &broadcastPort); + + switch (resultCode) + { + case 0: + printf("Image load good - mailbox CRC-16 matches\n"); + free (image); + close(sock); + return 0; + + case 1: + fprintf (stderr, "CRC-16 on file is bad\n"); + free (image); + close(sock); + return 1; + + case 2: + fprintf (stderr, "CRC-16 check on image load failed (mailbox CRC-16 check)\n"); + free (image); + close(sock); + return 2; + + default: + fprintf (stderr, "Invalid return code\n"); + free (image); + close(sock); + } + return 12; +} +/*@}*/ diff --git a/feeds/ipq807x/aq-fw-download/src/src/AQ_API.c b/feeds/ipq807x/aq-fw-download/src/src/AQ_API.c new file mode 100755 index 000000000..89e73344f --- /dev/null +++ b/feeds/ipq807x/aq-fw-download/src/src/AQ_API.c @@ -0,0 +1,1021 @@ +/*AQ_API.c*/ + +/************************************************************************************ +* Copyright (c) 2015, Aquantia +* +* Permission to use, copy, modify, and/or distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +* +* Description: +* +* This file contains the code for all of the API functions defined in AQ_API.h +* +************************************************************************************/ + + +/*! \file +* This file contains the code for all of the API functions defined in AQ_API.h + */ + +#include +#include + +#include "AQ_API.h" +#include "AQ_User.h" +#include "AQ_RegMacro.h" +#include "AQ_PlatformRoutines.h" +#include "AQ_RegMaps.h" +#include "AQ_ReturnCodes.h" + +#ifdef AQ_VERBOSE + #include + #include +#endif + + +#ifndef AQ_TIME_T_EXISTS + #ifndef AQ_MDIO_READS_PER_SECOND + #error AQ_MDIO_READS_PER_SECOND in AQ_User.h must be defined, as AQ_TIME_T_EXISTS is currently undefined! + #endif +#endif + +#ifdef AQ_TIME_T_EXISTS + #include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef AQ_ENABLE_UP_BUSY_CHECKS + #ifdef AQ_VERBOSE + #define AQ_API_UP_BUSY_PRINT_STATEMENT printf("uP-busy check timed out.\n"); + #else + #define AQ_API_UP_BUSY_PRINT_STATEMENT /* nothing */ + #endif + + #ifdef AQ_TIME_T_EXISTS + #define AQ_API_UP_BUSY_TIMEOUT (CLOCKS_PER_SEC / 10) + + #define AQ_API_DECLARE_UP_BUSY_VARS AQ_API_Variable(AQ_GlobalGeneralStatus) \ + uint16_t uPbusy; \ + clock_t startTime; \ + AQ_boolean uPBusyTimeoutOccurred = False; + + #define AQ_API_CHECK_UP_NOT_BUSY AQ_API_Wait(1, port); \ + startTime = clock(); \ + do \ + { \ + AQ_API_Get(port->PHY_ID, AQ_GlobalGeneralStatus, processorIntensiveMdioOperationIn_Progress, uPbusy); \ + if ((clock() - startTime) > AQ_API_UP_BUSY_TIMEOUT) \ + { \ + AQ_API_UP_BUSY_PRINT_STATEMENT \ + uPBusyTimeoutOccurred = True; \ + break; \ + } \ + } while (uPbusy != 0); + #else + #define AQ_API_UP_BUSY_MAX_CHECKS (AQ_MDIO_READS_PER_SECOND * 5) + + #define AQ_API_DECLARE_UP_BUSY_VARS AQ_API_Variable(AQ_GlobalGeneralStatus) \ + uint16_t uPbusy; \ + uint32_t numChecks; \ + AQ_boolean uPBusyTimeoutOccurred = False; + + #define AQ_API_CHECK_UP_NOT_BUSY AQ_API_Wait(1, port); \ + numChecks = 0; \ + do \ + { \ + AQ_API_Get(port->PHY_ID, AQ_GlobalGeneralStatus, processorIntensiveMdioOperationIn_Progress, uPbusy); \ + if (numChecks++ > AQ_API_UP_BUSY_MAX_CHECKS) \ + { \ + AQ_API_UP_BUSY_PRINT_STATEMENT \ + uPBusyTimeoutOccurred = True; \ + break; \ + } \ + } while (uPbusy != 0); + #endif + + /* If a uP busy timeout occurred, return the corresponding return code; otherwise, return + * retval. retval should be a return code defined in AQ_ReturnCodes. */ + #define AQ_API_RETURN_UP_BUSY(retval) return (uPBusyTimeoutOccurred ? AQ_RET_UP_BUSY_TIMEOUT : retval); + +#else + #define AQ_API_DECLARE_UP_BUSY_VARS /* nothing */ + #define AQ_API_CHECK_UP_NOT_BUSY /* nothing */ + #define AQ_API_RETURN_UP_BUSY(retval) return retval; +#endif + + +/*! FW image version string maximum length. */ +#define AQ_VERSION_STRING_SIZE 0x40 + +/*! The byte offset from top of DRAM to the FW image version string. */ +#define AQ_VERSION_STRING_BLOCK_OFFSET 0x0200 + +/*! The byte address, in processor memory, of the start of the IRAM segment. */ +#define AQ_IRAM_BASE_ADDRESS 0x40000000 + +/*! The byte address, in processor memory, of the start of the DRAM segment. */ +#define AQ_DRAM_BASE_ADDRESS 0x3FFE0000 + +/*! The byte offset from the top of the PHY image to the header content (HHD devices). */ +#define AQ_PHY_IMAGE_HEADER_CONTENT_OFFSET_HHD 0x300 + +/*! The byte offset from the top of the PHY image to the header content (APPIA devices). */ +#define AQ_PHY_IMAGE_HEADER_CONTENT_OFFSET_APPIA 0 + +/*! The offset, from the start of DRAM, where the provisioning block begins. */ +#define AQ_PHY_IMAGE_PROVTABLE_OFFSET 0x680 + +/*! The offset, from the start of DRAM, where the provisioning block's ending address is recorded. */ +#define AQ_PHY_IMAGE_PROVTABLE_TERM_OFFSET 0x028C + +/*! The size of the space alloted within the PHY image for the provisioning table. */ +#define AQ_PHY_IMAGE_PROVTABLE_MAXSIZE 0x800 + +/*! The maximum number of polling cycles ever required before the FLASH interface is ready. */ +#define AQ_FLASH_INTERFACE_MAX_POLL_COUNT 20 + +/*! The maximum number of ports that can be MDIO bootloaded at once. */ +#define AQ_MAX_NUM_PHY_IDS 48 + +/*! The maximum allowed number of times to poll for debug-trace-freeze acknowledgement. */ +#define AQ_MAX_FREEZE_CHECKS 2000 + +/*! The maximum size of the debug trace buffer. */ +#define AQ_MAX_TRACE_BUFFER_LENGTH 8192 + +/*! The maximum allowed number of times to poll for SERDES Rx eye measurement done. */ +#define AQ_SERDESEYE_MAX_DONE_CHECKS 50 + +/*! The maximum allowed number of times to poll for PIF mailbox status. */ +#define MAX_NUM_COMMAND_STATUS_POLLS 700 + +/* REGDOC_START */ + + +/********************************************************************************************************************** +* MDIO Boot Load +**********************************************************************************************************************/ + +const uint16_t AQ_CRC16Table[256] = {0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, + 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, + 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, + 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, + 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, + 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, + 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, + 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, + 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0}; + +/*! \addtogroup writingImages + @{ +*/ + +/*! Prepare the specified port for MDIO bootloading. Disables the daisy-chain, + * and explicitly sets the port's provisioningAddress. */ +void AQ_API_EnableMDIO_BootLoadMode +( + /*! The target PHY port.*/ + AQ_API_Port* port, + /*! The provisioning address to use when the FW starts and applies the + * bootloaded image's provisioned values. */ + unsigned int provisioningAddress +) +{ + AQ_API_Variable(AQ_GlobalNvrProvisioning) + + AQ_API_DeclareLocalStruct(AQ_GlobalReservedProvisioning, globalReservedProvisioning) + + + /* disable the daisy-chain */ + /* REGDOC: Read-Modify-Write bitfield (HHD/APPIA: 1E.C452.0) */ + AQ_API_Set(port->PHY_ID, AQ_GlobalNvrProvisioning, nvrDaisyChainDisable, 1); + + /* override the hop-count */ + AQ_API_AssignWordOfLocalStruct(globalReservedProvisioning, 1, + /* REGDOC: Read register (HHD/APPIA: 1E.C470 + 1) */ + AQ_API_ReadRegister(port->PHY_ID, AQ_GlobalReservedProvisioning, 1)); + /* REGDOC: Assign to local representation of bitfield (HHD/APPIA: 1E.C471.5:0) */ + AQ_API_AssignBitfieldOfLocalStruct(AQ_GlobalReservedProvisioning, globalReservedProvisioning, + daisy_chainHop_countOverrideValue, provisioningAddress); + /* REGDOC: Assign to local representation of bitfield (HHD/APPIA: 1E.C471.6) */ + AQ_API_AssignBitfieldOfLocalStruct(AQ_GlobalReservedProvisioning, globalReservedProvisioning, + enableDaisy_chainHop_countOverride, 1); + /* REGDOC: Write register (HHD/APPIA: 1E.C470 + 1) */ + AQ_API_WriteRegister(port->PHY_ID, AQ_GlobalReservedProvisioning, 1, + AQ_API_WordOfLocalStruct(globalReservedProvisioning, 1)); + + return; +} + + +/*! Prepare the specified port for MDIO bootloading, and set the temporary MDIO + * address to be used during the bootload process. Disables the daisy-chain, + * and explicitly sets the port's provisioningAddress. */ +void AQ_API_EnableGangLoadMode +( + /*! The target PHY port.*/ + AQ_API_Port* port, + /*! The provisioning address to use when the FW starts and applies the + * bootloaded image's provisioned values. */ + unsigned int provisioningAddress, + /*! The PHY's MDIO address will be changed to this value during the + * bootload process. */ + unsigned int gangLoadAddress +) +{ + /*AQ_API_Variable_DeviceRestricted(APPIA, AQ_GlobalGeneralProvisioning)*/ + AQ_API_Variable(AQ_GlobalGeneralProvisioning) + + + /* Get ready for MDIO bootloading. */ + AQ_API_EnableMDIO_BootLoadMode(port, provisioningAddress); + + /* Enable gangload mode. After doing this, the PHY will be + * addressable at the MDIO address indicated by gangLoadAddress. + * Now that the PHY is in gangload mode, MDIO reads are prohibited + * until AQ_API_DisableGangLoadMode is called. */ + if (AQ_DEVICE_APPIA == port->device) + { + /* REGDOC: Read-Modify-Write bitfield (APPIA: 1E.C440.8:4) */ + AQ_API_Set_DeviceRestricted(APPIA, port->PHY_ID, AQ_GlobalGeneralProvisioning, + gangLoadMdioAddress, gangLoadAddress); + } + else if (AQ_DEVICE_HHD == port->device) + { + /* REGDOC: Read-Modify-Write bitfield (HHD: 1E.C447.4:0) */ + AQ_API_Set_DeviceRestricted(HHD, port->PHY_ID, AQ_GlobalGeneralProvisioning, + mdioBroadcastAddressConfiguration, gangLoadAddress); + /* REGDOC: Read-Modify-Write bitfield (HHD: 1E.C441.E) */ + AQ_API_Set_DeviceRestricted(HHD, port->PHY_ID, AQ_GlobalGeneralProvisioning, + mdioBroadcastModeEnable, 1); + } + + return; +} + + +/*! Restore the PHY's MDIO address to the pin-specified value. Should be + * called when MDIO bootloading is complete, to return to normal MDIO + * addressing. + * This is a gang-load function, hence write-only! */ +void AQ_API_DisableGangLoadMode +( + /*! The target PHY port.*/ + AQ_API_Port* port, + /*! The value to write to of AQ_GlobalGeneralProvisioning.u1.word_1. */ + uint16_t origVal_GGP1 +) +{ + AQ_API_DeclareLocalStruct(AQ_GlobalGeneralProvisioning, globalGeneralProvisioning) + + + /* Restore the original value of globalGeneralProvisioning.u1, and set + * the MDIO address reset bit. This will cause the MDIO address to be + * reset to the value indicated by the pins. */ + AQ_API_AssignWordOfLocalStruct(globalGeneralProvisioning, 1, origVal_GGP1); + if (AQ_DEVICE_APPIA == port->device) + { + /* REGDOC: Assign to local representation of bitfield (APPIA: 1E.C441.2) */ + AQ_API_AssignBitfieldOfLocalStruct_DeviceRestricted(APPIA, AQ_GlobalGeneralProvisioning, + globalGeneralProvisioning, mdioAddressReset, 1); + } + else if (AQ_DEVICE_HHD == port->device) + { + /* REGDOC: Assign to local representation of bitfield (HHD: 1E.C441.E) */ + AQ_API_AssignBitfieldOfLocalStruct_DeviceRestricted(HHD, AQ_GlobalGeneralProvisioning, + globalGeneralProvisioning, mdioBroadcastModeEnable, 0); + } + /* REGDOC: Write register (HHD/APPIA: 1E.C440 + 1) */ + AQ_API_WriteRegister(port->PHY_ID, AQ_GlobalGeneralProvisioning, 1, + AQ_API_WordOfLocalStruct(globalGeneralProvisioning, 1)); + + /* The PHY has now exited gang-load mode. */ + return; +} + + +AQ_Retcode AQ_API_WriteBootLoadImageWithProvTable +( + AQ_API_Port** ports, + unsigned int numPorts, + unsigned int* provisioningAddresses, + AQ_Retcode* resultCodes, + uint32_t* imageSizePointer, + uint8_t* image, + uint8_t gangload_MDIO_address, + AQ_API_Port* gangloadPort, + uint32_t* provTableSizePointer, + uint8_t* provTableImage +) +{ + /*------------------------------------- NOTE!!!!!!!!!! ----------------------------------------------------------*/ + /* This function uses word level writes here as in gang-load mode we cannot do a read in a read-modify-write */ + /* operation */ + /*---------------------------------------------------------------------------------------------------------------*/ + + AQ_API_Variable_DeviceRestricted(APPIA, AQ_GlobalPinStatus) + + AQ_API_DeclareLocalStruct(AQ_GlobalControl, globalControl) + AQ_API_DeclareLocalStruct(AQ_GlobalMailboxInterface, globalMailboxInterface) + + AQ_API_Port* port; + uint32_t primaryHeaderPtr = 0x00000000; + uint32_t primaryIramPtr = 0x00000000; + uint32_t primaryDramPtr = 0x00000000; + uint32_t primaryIramSize = 0x00000000; + uint32_t primaryDramSize = 0x00000000; + uint32_t terminatorPtr = 0x00000000; + uint32_t phyImageHeaderContentOffset; + uint32_t i; + uint32_t j; + uint32_t imageSize; + uint32_t provTableImageSize = 0; + uint32_t bytePointer; + uint32_t byteSize; + uint32_t dWordSize; +#ifdef AQ_PHY_SUPPORTS_BLOCK_READ_WRITE + uint32_t countPendingOps; /* A count of block MDIO operation pending... necessary to keep a count + in order to ensure we don't exceed the maximum pending operations. */ +#endif + uint16_t msw; + uint16_t lsw; + uint16_t crc16Calculated; + uint16_t provTableCrc16Calculated; + uint16_t fileCRC; + uint16_t provTableFileCRC; + uint16_t mailboxCRC; + uint16_t mailboxWrite; + uint16_t bootLoadMode; + uint16_t recordedGGP1Values[AQ_MAX_NUM_PHY_IDS]; /* When entering/exiting gangload mode, we record and restore + the AQ_GlobalGeneralProvisioning.u1 register values. */ + + + /* store the CRC-16 for the image, which is the last two bytes */ + imageSize = *imageSizePointer; + fileCRC = image[imageSize-2] << 8 | image[imageSize-1]; + + /*------------------------------------- Check the image integrity ------------------------------------------------*/ + crc16Calculated = 0x0000; + for (i = 0; i < imageSize-2; i++) + { + crc16Calculated = ((crc16Calculated & 0xFF) << 8) ^ AQ_CRC16Table[(crc16Calculated >> 8) ^ image[i]]; + } + + if (crc16Calculated != fileCRC) + { + #ifdef AQ_VERBOSE + printf ("CRC check failed on image file (expected 0x%X, found 0x%X)\n", + fileCRC, crc16Calculated); + #endif + for (j = 0; j < numPorts; j++) + { + /* Before returning, set ALL result codes to indicate "bad image". */ + resultCodes[j] = AQ_RET_FLASH_IMAGE_CORRUPT; + } + return AQ_RET_ERROR; + } +#ifdef AQ_VERBOSE + else + { + printf ("CRC check good on image file (0x%04X)\n", crc16Calculated); + } +#endif + + /*-------------------------------- Check the provisioning table image integrity ----------------------------------*/ + if (provTableSizePointer != NULL && provTableImage != NULL) + { + provTableImageSize = (*provTableSizePointer) - 2; + provTableFileCRC = provTableImage[provTableImageSize + 1] << 8 | + provTableImage[provTableImageSize]; + + provTableCrc16Calculated = 0x0000; + for (i = 0; i < provTableImageSize; i++) + { + provTableCrc16Calculated = ((provTableCrc16Calculated & 0xFF) << 8) ^ + AQ_CRC16Table[(provTableCrc16Calculated >> 8) ^ provTableImage[i]]; + } + + if (provTableCrc16Calculated != provTableFileCRC) + { + #ifdef AQ_VERBOSE + printf ("CRC check failed on provisioning table file (expected 0x%X, found 0x%X)\n", + provTableFileCRC, provTableCrc16Calculated); + #endif + for (j = 0; j < numPorts; j++) + { + /* Before returning, set ALL result codes to indicate "bad image". */ + resultCodes[j] = AQ_RET_FLASH_IMAGE_CORRUPT; + } + return AQ_RET_ERROR; + } + #ifdef AQ_VERBOSE + else + { + printf ("CRC check good on provisioning table file (0x%04X)\n", + provTableCrc16Calculated); + } + #endif + } + + /*------------------------ Check that all provisioning addresses are in the proper range. ------------------------*/ + for (j = 0; j < numPorts; j++) + { + if (provisioningAddresses[j] > 47) + { + #ifdef AQ_VERBOSE + printf ("Provisioning address out of range 0-47 (index %u: %d)\n", j, provisioningAddresses[j]); + #endif + for (j = 0; j < numPorts; j++) + { + /* Before returning, set ALL result codes to indicate "provisioning address out-of-range". */ + resultCodes[j] = AQ_RET_BOOTLOAD_PROVADDR_OOR; + } + return AQ_RET_ERROR; + } + } + + /*--------------------------- Store 1E.C441 values for later use. Enforce uniformity. ---------------------------*/ + for (j = 0; j < numPorts; j++) + { + /* Record the original value of AQ_GlobalGeneralProvisioning.u1.word_1, + * so that we can restore it later after exiting gangload mode. */ + port = ports[j]; + /* REGDOC: Read register (HHD/APPIA: 1E.C440 + 1) */ + recordedGGP1Values[j] = AQ_API_ReadRegister(port->PHY_ID, AQ_GlobalGeneralProvisioning, 1); + + /* If any of the PHYs' GGP1 values don't match the others, set the appropriate + * error code and return. */ + if (j > 0 && recordedGGP1Values[j] != recordedGGP1Values[0]) + { + #ifdef AQ_VERBOSE + printf ("Non-uniform value of 1E.C441 found (expected 0x%X, found 0x%X)\n", + recordedGGP1Values[0], recordedGGP1Values[j]); + #endif + for (j = 0; j < numPorts; j++) + { + /* Before returning, set ALL result codes to indicate "non-uniform GGP1 values". */ + resultCodes[j] = AQ_RET_BOOTLOAD_NONUNIFORM_REGVALS; + } + return AQ_RET_ERROR; + } + } + + /*--------------------------- Put each PHY into gangload mode at the specified address ---------------------------*/ + for (j = 0; j < numPorts; j++) + { + AQ_API_EnableGangLoadMode(ports[j], provisioningAddresses[j], gangload_MDIO_address); + } + /* Set up the port context for using device-restricted macros while in + * gangload mode. */ + port = gangloadPort; + + /*------------------------------------- Stall the uP ------------------------------------------------------------*/ + AQ_API_AssignWordOfLocalStruct(globalControl, 1, 0x0000); + /* REGDOC: Assign to local representation of bitfield (HHD/APPIA: 1E.C001.6) */ + AQ_API_AssignBitfieldOfLocalStruct(AQ_GlobalControl, globalControl, upRunStallOverride, 1); + /* REGDOC: Assign to local representation of bitfield (HHD/APPIA: 1E.C001.0) */ + AQ_API_AssignBitfieldOfLocalStruct(AQ_GlobalControl, globalControl, upRunStall, 1); + /* REGDOC: Write register (HHD/APPIA: 1E.C000 + 1) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalControl, 1, + AQ_API_WordOfLocalStruct(globalControl, 1)); + + /*------------------------------------- Initialize the mailbox write command -------------------------------------*/ + AQ_API_AssignWordOfLocalStruct(globalMailboxInterface, 0, 0x0000); + /* REGDOC: Assign to local representation of bitfield (HHD/APPIA: 1E.0200.E) */ + AQ_API_AssignBitfieldOfLocalStruct(AQ_GlobalMailboxInterface, globalMailboxInterface, upMailboxWriteMode, 1); + /* REGDOC: Assign to local representation of bitfield (HHD/APPIA: 1E.0200.F) */ + AQ_API_AssignBitfieldOfLocalStruct(AQ_GlobalMailboxInterface, globalMailboxInterface, upMailboxExecuteOperation, 1); + mailboxWrite = AQ_API_WordOfLocalStruct(globalMailboxInterface, 0); + + /*------------------------------------- Read the segment addresses and sizes -------------------------------------*/ + primaryHeaderPtr = (((image[0x9] & 0x0F) << 8) | image[0x8]) << 12; + + if (AQ_DEVICE_APPIA == port->device) + phyImageHeaderContentOffset = AQ_PHY_IMAGE_HEADER_CONTENT_OFFSET_APPIA; + else /* HHD */ + phyImageHeaderContentOffset = AQ_PHY_IMAGE_HEADER_CONTENT_OFFSET_HHD; + + primaryIramPtr = (image[primaryHeaderPtr + phyImageHeaderContentOffset + 0x4 + 2] << 16) | + (image[primaryHeaderPtr + phyImageHeaderContentOffset + 0x4 + 1] << 8) | + image[primaryHeaderPtr + phyImageHeaderContentOffset + 0x4]; + primaryIramSize = (image[primaryHeaderPtr + phyImageHeaderContentOffset + 0x7 + 2] << 16) | + (image[primaryHeaderPtr + phyImageHeaderContentOffset + 0x7 + 1] << 8) | + image[primaryHeaderPtr + phyImageHeaderContentOffset + 0x7]; + primaryDramPtr = (image[primaryHeaderPtr + phyImageHeaderContentOffset + 0xA + 2] << 16) | + (image[primaryHeaderPtr + phyImageHeaderContentOffset + 0xA + 1] << 8) | + image[primaryHeaderPtr + phyImageHeaderContentOffset + 0xA]; + primaryDramSize = (image[primaryHeaderPtr + phyImageHeaderContentOffset + 0xD + 2] << 16) | + (image[primaryHeaderPtr + phyImageHeaderContentOffset + 0xD + 1] << 8) | + image[primaryHeaderPtr + phyImageHeaderContentOffset + 0xD]; + + if (AQ_DEVICE_HHD == port->device) + { + primaryIramPtr += primaryHeaderPtr; + primaryDramPtr += primaryHeaderPtr; + } + +#ifdef AQ_VERBOSE + printf ("\nSegment Addresses and Sizes as read from the PHY ROM image header:\n\n"); + printf ("Primary Iram Address: 0x%x\n", primaryIramPtr); + printf ("Primary Iram Size: 0x%x\n", primaryIramSize); + printf ("Primary Dram Address: 0x%x\n", primaryDramPtr); + printf ("Primary Dram Size: 0x%x\n\n", primaryDramSize); +#endif + + /*----------------------------- Merge the provisioning table into the main image ---------------------------------*/ + if (provTableSizePointer != NULL && provTableImage != NULL) + { + /* Locate the terminator of the built-in provisioning table */ + terminatorPtr = primaryDramPtr + + ((image[primaryDramPtr + AQ_PHY_IMAGE_PROVTABLE_TERM_OFFSET + 1] << 8) | + image[primaryDramPtr + AQ_PHY_IMAGE_PROVTABLE_TERM_OFFSET]); + + #ifdef AQ_VERBOSE + printf("Supplied Provisioning Table At Address: 0x%x\n\n", terminatorPtr); + #endif + + /* Check that the supplied provisioning table will fit within the alloted + * space. */ + if (terminatorPtr - (primaryDramPtr + AQ_PHY_IMAGE_PROVTABLE_OFFSET) + + provTableImageSize > AQ_PHY_IMAGE_PROVTABLE_MAXSIZE) + { + for (j = 0; j < numPorts; j++) + { + /* Before returning, set ALL result codes to indicate "provisioning + * table too large". */ + resultCodes[j] = AQ_RET_BOOTLOAD_PROVTABLE_TOO_LARGE; + } + return AQ_RET_ERROR; + } + + /* Write the supplied provisioning table into the image, starting at the + * terminator address. */ + for (i = 0; i < provTableImageSize; i++) + { + image[terminatorPtr + i] = provTableImage[i]; + } + } + + /*------------------------------------- Load IRAM and DRAM -------------------------------------------------------*/ + /* clear the mailbox CRC */ + AQ_API_AssignWordOfLocalStruct(globalMailboxInterface, 0, 0x0000); + /* REGDOC: Assign to local representation of bitfield (HHD/APPIA: 1E.0200.C) */ + AQ_API_AssignBitfieldOfLocalStruct(AQ_GlobalMailboxInterface, globalMailboxInterface, resetUpMailboxCrc, 1); + /* REGDOC: Write register (HHD/APPIA: 1E.0200) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 0, + AQ_API_WordOfLocalStruct(globalMailboxInterface, 0)); + /* REGDOC: Write register (HHD/APPIA: 1E.0200) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 0, 0x0000); + + crc16Calculated = 0; /* This is to calculate what was written through the mailbox */ + + /* load the IRAM */ +#ifdef AQ_VERBOSE + printf ("\nLoading IRAM:\n\n"); +#endif + + /* dWord align the address: note the image addressing is byte based, but is properly aligned on dWord + boundaries, so the 2 LSbits of the block start are always zero. */ + msw = (uint16_t) (AQ_IRAM_BASE_ADDRESS >> 16); + AQ_API_AssignWordOfLocalStruct(globalMailboxInterface, 3, 0x0000); + /* REGDOC: Assign to local representation of bitfield (HHD/APPIA: 1E.0203.1:0) */ + AQ_API_AssignBitfieldOfLocalStruct(AQ_GlobalMailboxInterface, globalMailboxInterface, + upMailboxAddressLSW , (AQ_IRAM_BASE_ADDRESS & 0xFFFF) >> 2); + lsw = AQ_API_WordOfLocalStruct(globalMailboxInterface, 3); + /* REGDOC: Write register (HHD/APPIA: 1E.0200 + 2) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 2, msw); /* MSW */ + /* REGDOC: Write register (HHD/APPIA: 1E.0200 + 3) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 3, lsw); /* LSW */ + + + /* set block size so that there are from 0-3 bytes remaining */ + byteSize = primaryIramSize; + dWordSize = byteSize >> 2; + + bytePointer = primaryIramPtr; +#ifdef AQ_PHY_SUPPORTS_BLOCK_READ_WRITE + countPendingOps = 0; +#endif + for (i = 0; i < dWordSize; i++) + { + /* write 4 bytes of data */ + lsw = (image[bytePointer+1] << 8) | image[bytePointer]; + bytePointer += 2; + msw = (image[bytePointer+1] << 8) | image[bytePointer]; + bytePointer += 2; + + #ifdef AQ_PHY_SUPPORTS_BLOCK_READ_WRITE + AQ_API_BlockWriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 4, msw); + AQ_API_BlockWriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 5, lsw); + AQ_API_BlockWriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 0, mailboxWrite); + + countPendingOps += 3; + /* Check if we've filled our output buffer, and if so, flush. */ + if (countPendingOps >= AQ_API_MDIO_MaxBlockOperations() - 3 ) + { + AQ_API_MDIO_BlockOperationExecute (gangloadPort->PHY_ID); + countPendingOps = 0; + } + #else + /* REGDOC: Write register (HHD/APPIA: 1E.0200 + 4) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 4, msw); + /* REGDOC: Write register (HHD/APPIA: 1E.0200 + 5) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 5, lsw); + /* REGDOC: Write register (HHD/APPIA: 1E.0200) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 0, mailboxWrite); + #endif + + /* update the calculated CRC */ + crc16Calculated = ((crc16Calculated & 0xFF) << 8) ^ AQ_CRC16Table[(crc16Calculated >> 8) ^ (msw >> 8)]; + crc16Calculated = ((crc16Calculated & 0xFF) << 8) ^ AQ_CRC16Table[(crc16Calculated >> 8) ^ (msw & 0xFF)]; + crc16Calculated = ((crc16Calculated & 0xFF) << 8) ^ AQ_CRC16Table[(crc16Calculated >> 8) ^ (lsw >> 8)]; + crc16Calculated = ((crc16Calculated & 0xFF) << 8) ^ AQ_CRC16Table[(crc16Calculated >> 8) ^ (lsw & 0xFF)]; + + #ifdef AQ_VERBOSE + if (i && ((i % 512) == 0)) printf(" Byte: %X:\n", i << 2); + #endif + } + +#ifdef AQ_PHY_SUPPORTS_BLOCK_READ_WRITE + /* flush the output buffer one last time. */ + AQ_API_MDIO_BlockOperationExecute(gangloadPort->PHY_ID); + countPendingOps = 0; +#endif + + /* Note: this final write right-justifies non-dWord data in the final dWord */ + switch (byteSize & 0x3) + { + case 0x1: + /* write 1 byte of data */ + lsw = image[bytePointer++]; + msw = 0x0000; + /* REGDOC: Write register (HHD/APPIA: 1E.0200 + 4) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 4, msw); + /* REGDOC: Write register (HHD/APPIA: 1E.0200 + 5) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 5, lsw); + + /* no polling */ + /* REGDOC: Write register (HHD/APPIA: 1E.0200) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 0, mailboxWrite); + break; + + case 0x2: + /* write 2 bytes of data */ + lsw = (image[bytePointer+1] << 8) | image[bytePointer]; + bytePointer += 2; + msw = 0x0000; + /* REGDOC: Write register (HHD/APPIA: 1E.0200 + 4) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 4, msw); + /* REGDOC: Write register (HHD/APPIA: 1E.0200 + 5) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 5, lsw); + + /* no polling */ + /* REGDOC: Write register (HHD/APPIA: 1E.0200) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 0, mailboxWrite); + break; + + case 0x3: + /* write 3 bytes of data */ + lsw = (image[bytePointer+1] << 8) | image[bytePointer]; + bytePointer += 2; + msw = image[bytePointer++]; + /* REGDOC: Write register (HHD/APPIA: 1E.0200 + 4) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 4, msw); + /* REGDOC: Write register (HHD/APPIA: 1E.0200 + 5) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 5, lsw); + + /* no polling */ + /* REGDOC: Write register (HHD/APPIA: 1E.0200) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 0, mailboxWrite); + break; + } + + if (byteSize & 0x3) + { + /* update the calculated CRC */ + crc16Calculated = ((crc16Calculated & 0xFF) << 8) ^ AQ_CRC16Table[(crc16Calculated >> 8) ^ (msw >> 8)]; + crc16Calculated = ((crc16Calculated & 0xFF) << 8) ^ AQ_CRC16Table[(crc16Calculated >> 8) ^ (msw & 0xFF)]; + crc16Calculated = ((crc16Calculated & 0xFF) << 8) ^ AQ_CRC16Table[(crc16Calculated >> 8) ^ (lsw >> 8)]; + crc16Calculated = ((crc16Calculated & 0xFF) << 8) ^ AQ_CRC16Table[(crc16Calculated >> 8) ^ (lsw & 0xFF)]; + } + + /* load the DRAM */ +#ifdef AQ_VERBOSE + printf ("\nCRC-16 after loading IRAM: 0x%X\n", crc16Calculated); + printf ("\nLoading DRAM:\n\n"); +#endif + + /* dWord align the address: note the image addressing is byte based, but is properly aligned on dWord + boundaries, so the 2 LSbits of the block start are always zero. */ + msw = (uint16_t) (AQ_DRAM_BASE_ADDRESS >> 16); + AQ_API_AssignWordOfLocalStruct(globalMailboxInterface, 3, 0x0000); + /* REGDOC: Assign to local representation of bitfield (HHD/APPIA: 1E.0203.1:0) */ + AQ_API_AssignBitfieldOfLocalStruct(AQ_GlobalMailboxInterface, globalMailboxInterface, + upMailboxAddressLSW, (AQ_DRAM_BASE_ADDRESS & 0xFFFF) >> 2); + lsw = AQ_API_WordOfLocalStruct(globalMailboxInterface, 3); + /* REGDOC: Write register (HHD/APPIA: 1E.0200 + 2) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 2, msw); /* MSW */ + /* REGDOC: Write register (HHD/APPIA: 1E.0200 + 3) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 3, lsw); /* LSW */ + + + /* set block size so that there are from 0-3 bytes remaining */ + byteSize = primaryDramSize; + dWordSize = byteSize >> 2; + + bytePointer = primaryDramPtr; + for (i = 0; i < dWordSize; i++) + { + /* write 4 bytes of data */ + lsw = (image[bytePointer+1] << 8) | image[bytePointer]; + bytePointer += 2; + msw = (image[bytePointer+1] << 8) | image[bytePointer]; + bytePointer += 2; + + #ifdef AQ_PHY_SUPPORTS_BLOCK_READ_WRITE + AQ_API_BlockWriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 4, msw); + AQ_API_BlockWriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 5, lsw); + AQ_API_BlockWriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 0, mailboxWrite); + + countPendingOps += 3; + /* Check if we've filled our output buffer, and if so, flush. */ + if (countPendingOps >= AQ_API_MDIO_MaxBlockOperations() - 3 ) + { + AQ_API_MDIO_BlockOperationExecute (gangloadPort->PHY_ID); + countPendingOps = 0; + } + #else + /* REGDOC: Write register (HHD/APPIA: 1E.0200 + 4) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 4, msw); + /* REGDOC: Write register (HHD/APPIA: 1E.0200 + 5) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 5, lsw); + /* REGDOC: Write register (HHD/APPIA: 1E.0200) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 0, mailboxWrite); + #endif + + /* update the calculated CRC */ + crc16Calculated = ((crc16Calculated & 0xFF) << 8) ^ AQ_CRC16Table[(crc16Calculated >> 8) ^ (msw >> 8)]; + crc16Calculated = ((crc16Calculated & 0xFF) << 8) ^ AQ_CRC16Table[(crc16Calculated >> 8) ^ (msw & 0xFF)]; + crc16Calculated = ((crc16Calculated & 0xFF) << 8) ^ AQ_CRC16Table[(crc16Calculated >> 8) ^ (lsw >> 8)]; + crc16Calculated = ((crc16Calculated & 0xFF) << 8) ^ AQ_CRC16Table[(crc16Calculated >> 8) ^ (lsw & 0xFF)]; + + #ifdef AQ_VERBOSE + if (i && ((i % 512) == 0)) printf(" Byte: %X:\n", i << 2); + #endif + } + +#ifdef AQ_PHY_SUPPORTS_BLOCK_READ_WRITE + /* flush the output buffer one last time. */ + AQ_API_MDIO_BlockOperationExecute(gangloadPort->PHY_ID); + countPendingOps = 0; +#endif + + /* Note: this final write right-justifies non-dWord data in the final dWord */ + switch (byteSize & 0x3) + { + case 0x1: + /* write 1 byte of data */ + lsw = image[bytePointer++]; + msw = 0x0000; + /* REGDOC: Write register (HHD/APPIA: 1E.0200 + 4) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 4, msw); + /* REGDOC: Write register (HHD/APPIA: 1E.0200 + 5) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 5, lsw); + + /* no polling */ + /* REGDOC: Write register (HHD/APPIA: 1E.0200) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 0, mailboxWrite); + break; + + case 0x2: + /* write 2 bytes of data */ + lsw = (image[bytePointer+1] << 8) | image[bytePointer]; + bytePointer += 2; + msw = 0x0000; + /* REGDOC: Write register (HHD/APPIA: 1E.0200 + 4) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 4, msw); + /* REGDOC: Write register (HHD/APPIA: 1E.0200 + 5) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 5, lsw); + + /* no polling */ + /* REGDOC: Write register (HHD/APPIA: 1E.0200) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 0, mailboxWrite); + break; + + case 0x3: + /* write 3 bytes of data */ + lsw = (image[bytePointer+1] << 8) | image[bytePointer]; + bytePointer += 2; + msw = image[bytePointer++]; + /* REGDOC: Write register (HHD/APPIA: 1E.0200 + 4) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 4, msw); + /* REGDOC: Write register (HHD/APPIA: 1E.0200 + 5) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 5, lsw); + + /* no polling */ + /* REGDOC: Write register (HHD/APPIA: 1E.0200) */ + AQ_API_WriteRegister(gangloadPort->PHY_ID, AQ_GlobalMailboxInterface, 0, mailboxWrite); + break; + } + + if (byteSize & 0x3) + { + /* update the calculated CRC */ + crc16Calculated = ((crc16Calculated & 0xFF) << 8) ^ AQ_CRC16Table[(crc16Calculated >> 8) ^ (msw >> 8)]; + crc16Calculated = ((crc16Calculated & 0xFF) << 8) ^ AQ_CRC16Table[(crc16Calculated >> 8) ^ (msw & 0xFF)]; + crc16Calculated = ((crc16Calculated & 0xFF) << 8) ^ AQ_CRC16Table[(crc16Calculated >> 8) ^ (lsw >> 8)]; + crc16Calculated = ((crc16Calculated & 0xFF) << 8) ^ AQ_CRC16Table[(crc16Calculated >> 8) ^ (lsw & 0xFF)]; + } + + /*------------------------------------- Exit gangload mode -------------------------------------------------------*/ + AQ_API_DisableGangLoadMode(gangloadPort, recordedGGP1Values[0]); + + /*------------------------------------- Check mailbox CRCs -------------------------------------------------------*/ + /* check to make sure the mailbox CRC matches the calculated CRC */ + /*foundMailboxCRCMismatch = False;*/ + for (j = 0; j < numPorts; j++) + { + /* REGDOC: Read register (HHD/APPIA: 1E.0200 + 1) */ + mailboxCRC = AQ_API_ReadRegister(ports[j]->PHY_ID,AQ_GlobalMailboxInterface, 1); + if (mailboxCRC != crc16Calculated) + { + #ifdef AQ_VERBOSE + printf("\n%uth port: Mailbox CRC-16 (0x%X) does not match calculated CRC-16 (0x%X)\n", + j, mailboxCRC, crc16Calculated); + #endif + /* Note that we can't just return here, because we still need to + * release the uPs for the other PHYs that might have been + * bootloaded successfully. */ + resultCodes[j] = AQ_RET_BOOTLOAD_CRC_MISMATCH; + } + #ifdef AQ_VERBOSE + else + { + printf("\n%uth port: Image load good - mailbox CRC-16 matches (0x%X)\n", + j, mailboxCRC); + resultCodes[j] = AQ_RET_OK; + } + #endif + } + + /*------------------------------------- Clear any resets ---------------------------------------------------------*/ + for (j = 0; j < numPorts; j++) + { + /* REGDOC: Write register (HHD/APPIA: 1E.0000) */ + AQ_API_WriteRegister(ports[j]->PHY_ID,AQ_GlobalStandardControl_1, 0, 0x0000); + } + + /*------------------------------------- Release the uP -----------------------------------------------------------*/ + AQ_API_AssignWordOfLocalStruct(globalControl, 1, 0x0000); + /* REGDOC: Assign to local representation of bitfield (HHD/APPIA: 1E.C001.6) */ + AQ_API_AssignBitfieldOfLocalStruct(AQ_GlobalControl, globalControl, upRunStallOverride, 1); + /* REGDOC: Assign to local representation of bitfield (HHD/APPIA: 1E.C001.0) */ + AQ_API_AssignBitfieldOfLocalStruct(AQ_GlobalControl, globalControl, upRunStall, 1); + for (j = 0; j < numPorts; j++) + { + /* REGDOC: Assign to local representation of bitfield (HHD/APPIA: 1E.C001.F) */ + AQ_API_AssignBitfieldOfLocalStruct(AQ_GlobalControl, globalControl, upReset, 0); + /* REGDOC: Write register (HHD/APPIA: 1E.C000 + 1) */ + AQ_API_WriteRegister(ports[j]->PHY_ID,AQ_GlobalControl, 1, + AQ_API_WordOfLocalStruct(globalControl, 1)); + /* REGDOC: Assign to local representation of bitfield (HHD/APPIA: 1E.C001.F) */ + AQ_API_AssignBitfieldOfLocalStruct(AQ_GlobalControl, globalControl, upReset, 1); + /* REGDOC: Write register (HHD/APPIA: 1E.C000 + 1) */ + AQ_API_WriteRegister(ports[j]->PHY_ID,AQ_GlobalControl, 1, + AQ_API_WordOfLocalStruct(globalControl, 1)); + } + + /* Need to wait at least 100us. */ + AQ_API_Wait(1, ports[0]); + + /* REGDOC: Assign to local representation of bitfield (HHD/APPIA: 1E.C001.F) */ + AQ_API_AssignBitfieldOfLocalStruct(AQ_GlobalControl, globalControl, upReset, 0); + /* REGDOC: Assign to local representation of bitfield (HHD/APPIA: 1E.C001.0) */ + AQ_API_AssignBitfieldOfLocalStruct(AQ_GlobalControl, globalControl, upRunStall, 0); + for (j = 0; j < numPorts; j++) + { + if (AQ_DEVICE_APPIA == port->device) + { + /* If the BOOT_LD pins are set to MDIO boot load mode, we can't clear the + * uP run stall override bit. If we did, the uP would stall. */ + /* REGDOC: Read bitfield (APPIA: 1E.C840.E:D) */ + AQ_API_Get_DeviceRestricted(APPIA, j, AQ_GlobalPinStatus, mdioBootLoad, bootLoadMode); + if (bootLoadMode == 0x1) + { + /* REGDOC: Assign to local representation of bitfield (HHD/APPIA: 1E.C001.6) */ + AQ_API_AssignBitfieldOfLocalStruct(AQ_GlobalControl, globalControl, upRunStallOverride, 1); + } + else + { + /* REGDOC: Assign to local representation of bitfield (HHD/APPIA: 1E.C001.6) */ + AQ_API_AssignBitfieldOfLocalStruct(AQ_GlobalControl, globalControl, upRunStallOverride, 0); + } + } + else + { + /* For post-APPIA devices, always set the uP stall override bit to + * smooth over any packaging differences WRT the boot load pin. */ + /* REGDOC: Assign to local representation of bitfield (HHD/APPIA: 1E.C001.6) */ + AQ_API_AssignBitfieldOfLocalStruct(AQ_GlobalControl, globalControl, upRunStallOverride, 1); + } + + /* REGDOC: Write register (HHD/APPIA: 1E.C000 + 1) */ + AQ_API_WriteRegister(ports[j]->PHY_ID,AQ_GlobalControl, 1, + AQ_API_WordOfLocalStruct(globalControl, 1)); + } + + /* NOTE!!! We can't re-enable the daisy-chain here, as this will overwrite the IRAM and DRAM with the FLASH contents*/ + + /* If any of the ports was not bootloaded successfully, return AQ_RET_ERROR */ + for (j = 0; j < numPorts; j++) + { + if (resultCodes[j] != AQ_RET_OK) + return AQ_RET_ERROR; + } + + /* All ports were bootloaded successfully. */ + return AQ_RET_OK; +} + + +AQ_Retcode AQ_API_WriteBootLoadImage +( + AQ_API_Port** ports, + unsigned int numPorts, + unsigned int* provisioningAddresses, + AQ_Retcode* resultCodes, + uint32_t* imageSizePointer, + uint8_t* image, + uint8_t gangload_MDIO_address, + AQ_API_Port* gangloadPort +) +{ + return AQ_API_WriteBootLoadImageWithProvTable(ports, numPorts, + provisioningAddresses, resultCodes, imageSizePointer, image, + gangload_MDIO_address, gangloadPort, NULL, NULL); +} + + +AQ_Retcode AQ_API_EnableDaisyChain +( + /*! The target PHY port.*/ + AQ_API_Port* port +) +{ + + /* declare local variables */ + AQ_API_Variable(AQ_GlobalNvrProvisioning) + AQ_API_Variable(AQ_GlobalReservedProvisioning) + + /* disable the hop-count override */ + /* REGDOC: Read-Modify-Write bitfield (HHD/APPIA: 1E.C471.6) */ + AQ_API_Set(port->PHY_ID, AQ_GlobalReservedProvisioning, enableDaisy_chainHop_countOverride, 0); + + /* enable the daisy-chain */ + /* REGDOC: Read-Modify-Write bitfield (HHD/APPIA: 1E.C452.0) */ + AQ_API_Set(port->PHY_ID, AQ_GlobalNvrProvisioning, nvrDaisyChainDisable, 0); + + return AQ_RET_OK; +} + +/*@}*/ + + +#ifdef __cplusplus +} +#endif diff --git a/feeds/ipq807x/aq-fw-download/src/src/AQ_PhyInterface.c b/feeds/ipq807x/aq-fw-download/src/src/AQ_PhyInterface.c new file mode 100755 index 000000000..a82c87e99 --- /dev/null +++ b/feeds/ipq807x/aq-fw-download/src/src/AQ_PhyInterface.c @@ -0,0 +1,141 @@ +/* AQ_PhyInterface.c */ + +/************************************************************************************ +* Copyright (c) 2015, Aquantia +* +* Permission to use, copy, modify, and/or distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +* +* $Revision: #12 $ +* +* $DateTime: 2015/02/25 15:34:49 $ +* +* $Label: $ +* +************************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "AQ_PhyInterface.h" +#include "AQ_PlatformRoutines.h" + +#define MII_ADDR_C45 (0x8000) + +extern int sock; +extern char devname[7]; + +static struct ifreq ifr; + +/*! Provides generic synchronous PHY register write functionality. It is the + * responsibility of the system designer to provide the specific MDIO address + * pointer updates, etc. in order to accomplish this write operation. + * It will be assumed that the write has been completed by the time this + * function returns.*/ +void AQ_API_MDIO_Write( + /*! Uniquely identifies the port within the system. AQ_Port must be + * defined to a whatever data type is suitable for the platform.*/ + AQ_Port PHY_ID, + /*! The address of the MMD within the target PHY. */ + unsigned int MMD, + /*! The 16-bit address of the PHY register being written. */ + unsigned int address, + /*! The 16-bits of data to write to the specified PHY register. */ + unsigned int data) +{ + struct mii_ioctl_data mii; + + /* + * Frame the control structures + * and send the ioctl to kernel. + */ + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, devname, sizeof(ifr.ifr_name)); + memset(&mii, 0, sizeof(mii)); + memcpy(&mii, &ifr.ifr_data, sizeof(mii)); + mii.phy_id = MII_ADDR_C45 | PHY_ID << 5 | MMD; + mii.reg_num = address; + mii.val_in = data; + memcpy(&ifr.ifr_data, &mii, sizeof(mii)); + + if (ioctl(sock, SIOCSMIIREG, &ifr) < 0) { + fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name, + strerror(errno)); + } + + return; +} + +/*! Provides generic synchronous PHY register read functionality. It is the + * responsibility of the system designer to provide the specific MDIO address + * pointer updates, etc. in order to accomplish this read operation.*/ +unsigned int AQ_API_MDIO_Read +( + /*! Uniquely identifies the port within the system. AQ_Port must be + * defined to a whatever data type is suitable for the platform.*/ + AQ_Port PHY_ID, + /*! The address of the MMD within the target PHY. */ + unsigned int MMD, + /*! The 16-bit address of the PHY register being read. */ + unsigned int address) +{ + struct mii_ioctl_data mii; + + /* + * Frame the control structures + * and send the ioctl to kernel. + */ + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, devname, sizeof(ifr.ifr_name)); + memset(&mii, 0, sizeof(mii)); + memcpy(&mii, &ifr.ifr_data, sizeof(mii)); + mii.phy_id = MII_ADDR_C45 | PHY_ID << 5 | MMD; + mii.reg_num = address; + memcpy(&ifr.ifr_data, &mii, sizeof(mii)); + + if (ioctl(sock, SIOCGMIIREG, &ifr) < 0) { + fprintf(stderr, "SIOCGMIIREG on %s failed: %s\n", ifr.ifr_name, + strerror(errno)); + return -1; + } else { + memcpy(&mii, &ifr.ifr_data, sizeof(mii)); + } + + + return mii.val_out; +} + +/*! Returns after at least milliseconds have elapsed. This must be implemented + * * in a platform-approriate way. AQ_API functions will call this function to + * * block for the specified period of time. If necessary, PHY register reads + * * may be performed on port to busy-wait. */ +void AQ_API_Wait( + uint32_t milliseconds, /*!< The delay in milliseconds */ + AQ_API_Port* port /*!< The PHY to use if delay reads are necessary*/ ) +{ + unsigned long long mirco = milliseconds *1000; + usleep(mirco); +} diff --git a/feeds/ipq807x/protobuf-c/Makefile b/feeds/ipq807x/protobuf-c/Makefile new file mode 100644 index 000000000..e04483318 --- /dev/null +++ b/feeds/ipq807x/protobuf-c/Makefile @@ -0,0 +1,67 @@ +# +# Copyright (C) 2011 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=libprotobuf-c +PKG_VERSION:=1.3.1 +PKG_RELEASE:=2 + +PKG_SOURCE:=protobuf-c-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://github.com/protobuf-c/protobuf-c/releases/download/v$(PKG_VERSION) +PKG_HASH:=51472d3a191d6d7b425e32b612e477c06f73fe23e07f6a6a839b11808e9d2267 +PKG_BUILD_DIR:=$(BUILD_DIR)/protobuf-c-$(PKG_VERSION) +HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/protobuf-c-$(PKG_VERSION) + +PKG_MAINTAINER:=Rosen Penev +PKG_LICENSE:=BSD-2c + +PKG_BUILD_DEPENDS:=protobuf-c/host +HOST_BUILD_DEPENDS:=protobuf/host + +PKG_INSTALL:=1 +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/host-build.mk + +define Package/libprotobuf-c + TITLE:=Protocol Buffers library + SECTION:=libs + CATEGORY:=Libraries + URL:=https://github.com/protobuf-c/protobuf-c +endef + +define Package/libprotobuf-c/description + Runtime library to use Google Protocol Buffers from C applications. + Protocol Buffers are a way of encoding structured data in an efficient yet + extensible format. Google uses Protocol Buffers for almost all of its + internal RPC protocols and file formats. +endef + +CONFIGURE_ARGS += \ + --enable-shared \ + --enable-static \ + --disable-protoc + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/ + $(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/ + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libprotobuf-c.{a,la,so*} $(1)/usr/lib/ + $(INSTALL_DIR) $(1)/usr/lib/pkgconfig + $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/* $(1)/usr/lib/pkgconfig/ +endef + +define Package/libprotobuf-c/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libprotobuf-c.so.* $(1)/usr/lib/ +endef + +$(eval $(call BuildPackage,libprotobuf-c)) +$(eval $(call HostBuild)) + diff --git a/feeds/ipq807x/protobuf-c/patches/001-t-generated-code2-cxx-generate-packed-data-fix.patch b/feeds/ipq807x/protobuf-c/patches/001-t-generated-code2-cxx-generate-packed-data-fix.patch new file mode 100644 index 000000000..2d83cec59 --- /dev/null +++ b/feeds/ipq807x/protobuf-c/patches/001-t-generated-code2-cxx-generate-packed-data-fix.patch @@ -0,0 +1,13 @@ +Index: protobuf-c-1.3.1/t/generated-code2/cxx-generate-packed-data.cc +=================================================================== +--- protobuf-c-1.3.1.orig/t/generated-code2/cxx-generate-packed-data.cc ++++ protobuf-c-1.3.1/t/generated-code2/cxx-generate-packed-data.cc +@@ -998,7 +998,7 @@ static void dump_test_packed_repeated_en + static void dump_test_unknown_fields (void) + { + EmptyMess mess; +- const google::protobuf::Message::Reflection *reflection = mess.GetReflection(); ++ const google::protobuf::Reflection *reflection = mess.GetReflection(); + google::protobuf::UnknownFieldSet *fs = reflection->MutableUnknownFields(&mess); + + #if GOOGLE_PROTOBUF_VERSION >= 2001000 diff --git a/feeds/ipq807x/protobuf/Makefile b/feeds/ipq807x/protobuf/Makefile new file mode 100644 index 000000000..cd52a5ed4 --- /dev/null +++ b/feeds/ipq807x/protobuf/Makefile @@ -0,0 +1,110 @@ +# +# Copyright (C) 2007-2015 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=protobuf +PKG_VERSION:=3.7.1 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-cpp-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://github.com/google/protobuf/releases/download/v$(PKG_VERSION) +PKG_HASH:=97f6cdaa0724d5a8cd3375d5f5cf4bd253d5ad5291154f533ed0d94a9d501ef3 + +PKG_LICENSE:=BSD-3-Clause +PKG_LICENSE_FILES:=LICENSE +PKG_CPE_ID:=cpe:/a:google:protobuf + +PKG_BUILD_DEPENDS:=protobuf/host + +PKG_BUILD_PARALLEL:=1 +PKG_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/host-build.mk + +define Package/protobuf/Default + SECTION:=libs + CATEGORY:=Libraries + TITLE:=A structured data encoding library + URL:=https://github.com/google/protobuf + DEPENDS:=+zlib +libpthread +libatomic +libstdcpp + MAINTAINER:=Ken Keys +endef + +define Package/protobuf + $(call Package/protobuf/Default) + DEPENDS+=+protobuf-lite +endef + +define Package/protobuf-lite + $(call Package/protobuf/Default) +endef + +define Package/protobuf/description/Default +Protocol Buffers are a way of encoding structured data in an efficient +yet extensible format. Google uses Protocol Buffers for almost all +of its internal RPC protocols and file formats. +endef + +define Package/protobuf/description +$(call Package/protobuf/description/Default) + +This package provides the libprotoc, libprotobuf, and libprotobuf-lite +libraries. For a much smaller protobuf package, see "protobuf-lite". + +endef + +define Package/protobuf-lite/description +$(call Package/protobuf/description/Default) + +This package provides the libprotobuf-lite library. + +endef + +EXTRA_CPPFLAGS+=-std=c++11 +CONFIGURE_ARGS += --with-protoc=$(STAGING_DIR_HOSTPKG)/bin/protoc + +define Build/InstallDev + $(INSTALL_DIR) \ + $(1)/usr/lib \ + $(1)/usr/include + + $(CP) \ + $(PKG_INSTALL_DIR)/usr/include/* \ + $(1)/usr/include/ + + $(CP) \ + $(PKG_INSTALL_DIR)/usr/lib/* \ + $(1)/usr/lib/ +endef + +define Package/protobuf-lite/install + $(INSTALL_DIR) \ + $(1)/usr/lib + + $(CP) \ + $(PKG_INSTALL_DIR)/usr/lib/libprotobuf-lite.so* \ + $(1)/usr/lib/ +endef + +define Package/protobuf/install + $(INSTALL_DIR) \ + $(1)/usr/lib + + $(CP) \ + $(PKG_INSTALL_DIR)/usr/lib/libprotoc.so* \ + $(1)/usr/lib/ + + $(CP) \ + $(PKG_INSTALL_DIR)/usr/lib/libprotobuf.so* \ + $(1)/usr/lib/ +endef + +$(eval $(call BuildPackage,protobuf)) +$(eval $(call BuildPackage,protobuf-lite)) +$(eval $(call HostBuild)) diff --git a/feeds/ipq807x/qca-nss-dp/Makefile b/feeds/ipq807x/qca-nss-dp/Makefile new file mode 100644 index 000000000..60df6dc53 --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/Makefile @@ -0,0 +1,52 @@ +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=qca-nss-dp +PKG_SOURCE_PROTO:=git +PKG_BRANCH:=master +PKG_RELEASE:=1 + +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/qca-nss-dp + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + DEPENDS:=@TARGET_ipq807x +kmod-qca-ssdk + TITLE:=Kernel driver for NSS data plane + FILES:=$(PKG_BUILD_DIR)/qca-nss-dp.ko + AUTOLOAD:=$(call AutoLoad,31,qca-nss-dp) +endef + +define KernelPackage/qca-nss-dp/Description +This package contains a NSS data plane driver for QCA chipset +endef + +define Build/InstallDev + mkdir -p $(1)/usr/include/qca-nss-dp + $(CP) $(PKG_BUILD_DIR)/exports/* $(1)/usr/include/qca-nss-dp/ +endef + +EXTRA_CFLAGS+= \ + -I$(STAGING_DIR)/usr/include/qca-ssdk + +subtarget:=$(SUBTARGET) + +NSS_DP_HAL_DIR:=$(PKG_BUILD_DIR)/hal +hal_arch:=$(subtarget) + +define Build/Configure + $(LN) $(NSS_DP_HAL_DIR)/arch/$(hal_arch)/nss_$(hal_arch).h \ + $(PKG_BUILD_DIR)/exports/nss_dp_arch.h +endef + +define Build/Compile + $(MAKE) -C "$(LINUX_DIR)" \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + ARCH="$(LINUX_KARCH)" \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" SoC="$(subtarget)" \ + modules +endef + +$(eval $(call KernelPackage,qca-nss-dp)) diff --git a/feeds/ipq807x/qca-nss-dp/src/Makefile b/feeds/ipq807x/qca-nss-dp/src/Makefile new file mode 100644 index 000000000..b7ddcc1d4 --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/Makefile @@ -0,0 +1,56 @@ +################################################### +# Makefile for the NSS data plane driver +################################################### + +obj ?= . + +obj-m += qca-nss-dp.o + +qca-nss-dp-objs += nss_dp_attach.o \ + nss_dp_ethtools.o \ + nss_dp_main.o + +ifneq ($(CONFIG_NET_SWITCHDEV),) +qca-nss-dp-objs += nss_dp_switchdev.o +endif + +ifeq ($(SoC),$(filter $(SoC),ipq807x ipq807x_64 ipq60xx ipq60xx_64)) +qca-nss-dp-objs += hal/edma/edma_cfg.o \ + hal/edma/edma_data_plane.o \ + hal/edma/edma_tx_rx.o \ + hal/gmac_hal_ops/qcom/qcom_if.o \ + hal/gmac_hal_ops/syn/xgmac/syn_if.o +endif + +NSS_DP_INCLUDE = -I$(obj)/include -I$(obj)/exports -I$(obj)/gmac_hal_ops/include \ + -I$(obj)/hal/include + +ifeq ($(SoC),$(filter $(SoC),ipq50xx ipq50xx_64)) +NSS_DP_INCLUDE += -I$(obj)/hal/gmac_hal_ops/syn/gmac +endif + +ccflags-y += $(NSS_DP_INCLUDE) +ccflags-y += -Werror + +ifeq ($(SoC),$(filter $(SoC),ipq807x ipq807x_64 ipq60xx ipq60xx_64)) +ccflags-y += -DNSS_DP_PPE_SUPPORT +endif + +ifeq ($(SoC),$(filter $(SoC),ipq60xx ipq60xx_64)) +qca-nss-dp-objs += hal/arch/ipq60xx/nss_ipq60xx.o +ccflags-y += -DNSS_DP_IPQ60XX +endif + +ifeq ($(SoC),$(filter $(SoC),ipq807x ipq807x_64)) +qca-nss-dp-objs += hal/arch/ipq807x/nss_ipq807x.o +ccflags-y += -DNSS_DP_IPQ807X +endif + +ifeq ($(SoC),$(filter $(SoC),ipq50xx ipq50xx_64)) +qca-nss-dp-objs += hal/arch/ipq50xx/nss_ipq50xx.o \ + hal/gmac_hal_ops/syn/gmac/syn_if.o \ + hal/syn_gmac_dp/syn_data_plane.o \ + hal/syn_gmac_dp/syn_dp_tx_rx.o \ + hal/syn_gmac_dp/syn_dp_cfg.o +ccflags-y += -DNSS_DP_IPQ50XX +endif diff --git a/feeds/ipq807x/qca-nss-dp/src/exports/nss_dp_api_if.h b/feeds/ipq807x/qca-nss-dp/src/exports/nss_dp_api_if.h new file mode 100644 index 000000000..2710b790e --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/exports/nss_dp_api_if.h @@ -0,0 +1,219 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_dp_api_if.h + * nss-dp exported structures/apis. + * + * This file declares all the public interfaces + * for NSS data-plane driver. + */ + +#ifndef __NSS_DP_API_IF_H +#define __NSS_DP_API_IF_H + +#include "nss_dp_arch.h" + +/** + * @addtogroup nss_dp_subsystem + * @{ + */ + +/* + * NSS DP status + */ +#define NSS_DP_SUCCESS 0 +#define NSS_DP_FAILURE -1 + +/* + * NSS DP platform specific defines + */ +#define NSS_DP_START_IFNUM NSS_DP_HAL_START_IFNUM + /**< First GMAC interface number (0/1) depending on SoC. */ +#define NSS_DP_MAX_MTU_SIZE NSS_DP_HAL_MAX_MTU_SIZE +#define NSS_DP_MAX_PACKET_LEN NSS_DP_HAL_MAX_PACKET_LEN +#define NSS_DP_MAX_INTERFACES (NSS_DP_HAL_MAX_PORTS + NSS_DP_HAL_START_IFNUM) + /**< Last interface index for the SoC, to be used by qca-nss-drv. */ + +/* + * NSS PTP service code + */ +#define NSS_PTP_EVENT_SERVICE_CODE 0x9 + +/** + * nss_dp_data_plane_ctx + * Data plane context base class. + */ +struct nss_dp_data_plane_ctx { + struct net_device *dev; +}; + +/** + * nss_dp_gmac_stats + * The per-GMAC statistics structure. + */ +struct nss_dp_gmac_stats { + struct nss_dp_hal_gmac_stats stats; +}; + +/** + * nss_dp_data_plane_ops + * Per data-plane ops structure. + * + * Default would be slowpath and can be overridden by nss-drv + */ +struct nss_dp_data_plane_ops { + int (*init)(struct nss_dp_data_plane_ctx *dpc); + int (*open)(struct nss_dp_data_plane_ctx *dpc, uint32_t tx_desc_ring, + uint32_t rx_desc_ring, uint32_t mode); + int (*close)(struct nss_dp_data_plane_ctx *dpc); + int (*link_state)(struct nss_dp_data_plane_ctx *dpc, + uint32_t link_state); + int (*mac_addr)(struct nss_dp_data_plane_ctx *dpc, uint8_t *addr); + int (*change_mtu)(struct nss_dp_data_plane_ctx *dpc, uint32_t mtu); + netdev_tx_t (*xmit)(struct nss_dp_data_plane_ctx *dpc, struct sk_buff *os_buf); + void (*set_features)(struct nss_dp_data_plane_ctx *dpc); + int (*pause_on_off)(struct nss_dp_data_plane_ctx *dpc, + uint32_t pause_on); + int (*vsi_assign)(struct nss_dp_data_plane_ctx *dpc, uint32_t vsi); + int (*vsi_unassign)(struct nss_dp_data_plane_ctx *dpc, uint32_t vsi); + int (*rx_flow_steer)(struct nss_dp_data_plane_ctx *dpc, struct sk_buff *skb, + uint32_t cpu, bool is_add); + void (*get_stats)(struct nss_dp_data_plane_ctx *dpc, struct nss_dp_gmac_stats *stats); + int (*deinit)(struct nss_dp_data_plane_ctx *dpc); +}; + +/** + * nss_dp_receive + * Called by overlay drivers to deliver packets to nss-dp. + * + * @datatypes + * net_device + * sk_buff + * napi_struct + * + * @param[in] netdev Pointer to netdev structure on which packet is received. + * @param[in] skb Pointer to the received packet. + * @param[in] napi Pointer to napi context. + */ +void nss_dp_receive(struct net_device *netdev, struct sk_buff *skb, + struct napi_struct *napi); + +/** + * nss_dp_is_in_open_state + * Returns if a data plane is opened or not. + * + * @datatypes + * net_device + * + * @param[in] netdev Pointer to netdev structure. + * + * @return + * bool + */ +bool nss_dp_is_in_open_state(struct net_device *netdev); + +/** + * nss_dp_override_data_palne + * API to allow overlay drivers to override the data plane. + * + * @datatypes + * net_device + * nss_dp_data_plane_ops + * nss_dp_data_plane_ctx + * + * @param[in] netdev Pointer to netdev structure. + * @param[in] dp_ops Pointer to respective data plane ops structure. + * @param[in] dpc Pointer to data plane context. + * + * @return + * int + */ +int nss_dp_override_data_plane(struct net_device *netdev, + struct nss_dp_data_plane_ops *dp_ops, + struct nss_dp_data_plane_ctx *dpc); + +/** + * nss_dp_start_data_plane + * Dataplane API to inform netdev when it is ready to start. + * + * @datatypes + * net_device + * nss_dp_data_plane_ctx + * + * @param[in] netdev Pointer to netdev structure. + * @param[in] dpc Pointer to data plane context. + */ +void nss_dp_start_data_plane(struct net_device *netdev, + struct nss_dp_data_plane_ctx *dpc); + +/** + * nss_dp_restore_data_plane + * Called by overlay drivers to detach itself from nss-dp. + * + * @datatypes + * net_device + * + * @param[in] netdev Pointer to netdev structure. + */ +void nss_dp_restore_data_plane(struct net_device *netdev); + +/** + * nss_dp_get_netdev_by_nss_if_num + * Returns the net device of the corresponding id if it exists. + * + * @datatypes + * int + * + * @param[in] interface ID of the physical mac port. + * + * @return + * Pointer to netdev structure. + */ +struct net_device *nss_dp_get_netdev_by_nss_if_num(int if_num); + +/** + * nss_phy_tstamp_rx_buf + * Receive timestamp packet. + * + * @datatypes + * sk_buff + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] skb Pointer to the packet. + */ +void nss_phy_tstamp_rx_buf(void *app_data, struct sk_buff *skb); + +/** + * nss_phy_tstamp_tx_buf + * Transmit timestamp packet + * + * @datatypes + * net_device + * sk_buff + * + * @param[in] net_device Pointer to netdev structure. + * @param[in] skb Pointer to the packet. + */ +void nss_phy_tstamp_tx_buf(struct net_device *ndev, struct sk_buff *skb); + +/** + *@} + */ + +#endif /** __NSS_DP_API_IF_H */ diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq50xx/nss_ipq50xx.c b/feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq50xx/nss_ipq50xx.c new file mode 100644 index 000000000..ba32ae85f --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq50xx/nss_ipq50xx.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include "nss_dp_hal.h" + +/* + * nss_dp_hal_tcsr_base_get + * Reads TCSR base address from DTS + */ +static uint32_t nss_dp_hal_tcsr_base_get(void) +{ + uint32_t tcsr_base_addr = 0; + struct device_node *dp_cmn; + + /* + * Get reference to NSS dp common device node + */ + dp_cmn = of_find_node_by_name(NULL, "nss-dp-common"); + if (!dp_cmn) { + pr_info("%s: NSS DP common node not found\n", __func__); + return 0; + } + + if (of_property_read_u32(dp_cmn, "qcom,tcsr-base", &tcsr_base_addr)) { + pr_err("%s: error reading TCSR base\n", __func__); + } + of_node_put(dp_cmn); + + return tcsr_base_addr; +} + +/* + * nss_dp_hal_tcsr_set + * Sets the TCSR axi cache override register + */ +static void nss_dp_hal_tcsr_set(void) +{ + void __iomem *tcsr_addr = NULL; + uint32_t tcsr_base; + int err; + + tcsr_base = nss_dp_hal_tcsr_base_get(); + if (!tcsr_base) { + pr_err("%s: Unable to get TCSR base address\n", __func__); + return; + } + + /* + * Check if Trust Zone is enabled in the system. + * If yes, we need to go through SCM API call to program TCSR register. + * If TZ is not enabled, we can write to the register directly. + */ + if (qcom_scm_is_available()) { + err = qcom_scm_tcsr_reg_write((tcsr_base + TCSR_GMAC_AXI_CACHE_OVERRIDE_OFFSET), + TCSR_GMAC_AXI_CACHE_OVERRIDE_VALUE); + if (err) { + pr_err("%s: SCM TCSR write error: %d\n", __func__, err); + } + } else { + tcsr_addr = ioremap_nocache((tcsr_base + TCSR_GMAC_AXI_CACHE_OVERRIDE_OFFSET), + TCSR_GMAC_AXI_CACHE_OVERRIDE_REG_SIZE); + if (!tcsr_addr) { + pr_err("%s: ioremap failed\n", __func__); + return; + } + writel(TCSR_GMAC_AXI_CACHE_OVERRIDE_VALUE, tcsr_addr); + iounmap(tcsr_addr); + } +} + +/* + * nss_dp_hal_get_data_plane_ops + * Return the data plane ops for GMAC data plane. + */ +struct nss_dp_data_plane_ops *nss_dp_hal_get_data_plane_ops(void) +{ + return &nss_dp_gmac_ops; +} + +/* + * nss_dp_hal_clk_enable + * Function to enable GCC_SNOC_GMAC_AXI_CLK. + * + * These clocks are required for GMAC operations. + */ +void nss_dp_hal_clk_enable(struct nss_dp_dev *dp_priv) +{ + struct platform_device *pdev = dp_priv->pdev; + struct device *dev = &pdev->dev; + struct clk *gmac_clk = NULL; + int err; + + gmac_clk = devm_clk_get(dev, NSS_SNOC_GMAC_AXI_CLK); + if (IS_ERR(gmac_clk)) { + pr_err("%s: cannot get clock: %s\n", __func__, + NSS_SNOC_GMAC_AXI_CLK); + return; + } + + err = clk_prepare_enable(gmac_clk); + if (err) { + pr_err("%s: cannot enable clock: %s, err: %d\n", __func__, + NSS_SNOC_GMAC_AXI_CLK, err); + return; + } +} + +/* + * nss_dp_hal_init + * Sets the gmac ops based on the GMAC type. + */ +bool nss_dp_hal_init(void) +{ + nss_dp_hal_set_gmac_ops(&syn_hal_ops, GMAC_HAL_TYPE_SYN_GMAC); + + /* + * Program the global GMAC AXI Cache override register + * for optimized AXI DMA operation. + */ + nss_dp_hal_tcsr_set(); + return true; +} + +/* + * nss_dp_hal_cleanup + * Sets the gmac ops to NULL. + */ +void nss_dp_hal_cleanup(void) +{ + nss_dp_hal_set_gmac_ops(NULL, GMAC_HAL_TYPE_SYN_GMAC); +} diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq50xx/nss_ipq50xx.h b/feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq50xx/nss_ipq50xx.h new file mode 100644 index 000000000..cae6407ce --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq50xx/nss_ipq50xx.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __NSS_DP_ARCH_H__ +#define __NSS_DP_ARCH_H__ + +#define NSS_DP_HAL_MAX_PORTS 2 +#define NSS_DP_HAL_CPU_NUM 2 +#define NSS_DP_HAL_START_IFNUM 0 +#define NSS_DP_GMAC_NORMAL_FRAME_MTU 1500 +#define NSS_DP_GMAC_MINI_JUMBO_FRAME_MTU 1978 +#define NSS_DP_GMAC_FULL_JUMBO_FRAME_MTU 9000 +#define NSS_DP_HAL_MAX_MTU_SIZE NSS_DP_GMAC_FULL_JUMBO_FRAME_MTU +#define NSS_DP_HAL_MAX_PACKET_LEN 65535 + +/* + * TCSR_GMAC_AXI_CACHE_OVERRIDE register size + */ +#define TCSR_GMAC_AXI_CACHE_OVERRIDE_REG_SIZE 4 + +/* + * TCSR_GMAC_AXI_CACHE_OVERRIDE Register offset + */ +#define TCSR_GMAC_AXI_CACHE_OVERRIDE_OFFSET 0x6224 + +/* + * Value for TCSR_GMAC_AXI_CACHE_OVERRIDE register + */ +#define TCSR_GMAC_AXI_CACHE_OVERRIDE_VALUE 0x05050505 + +/* + * GCC_SNOC_GMAC_AXI_CLOCK + */ +#define NSS_SNOC_GMAC_AXI_CLK "nss-snoc-gmac-axi-clk" + +/** + * nss_dp_hal_gmac_stats + * The per-GMAC statistics structure. + */ +struct nss_dp_hal_gmac_stats { + uint64_t rx_bytes; /**< Number of RX bytes */ + uint64_t rx_packets; /**< Number of RX packets */ + uint64_t rx_errors; /**< Number of RX errors */ + uint64_t rx_receive_errors; /**< Number of RX receive errors */ + uint64_t rx_descriptor_errors; /**< Number of RX descriptor errors */ + uint64_t rx_late_collision_errors; + /**< Number of RX late collision errors */ + uint64_t rx_dribble_bit_errors; /**< Number of RX dribble bit errors */ + uint64_t rx_length_errors; /**< Number of RX length errors */ + uint64_t rx_ip_header_errors; /**< Number of RX IP header errors read from rxdec */ + uint64_t rx_ip_payload_errors; /**< Number of RX IP payload errors */ + uint64_t rx_no_buffer_errors; /**< Number of RX no-buffer errors */ + uint64_t rx_transport_csum_bypassed; + /**< Number of RX packets where the transport checksum was bypassed */ + uint64_t tx_bytes; /**< Number of TX bytes */ + uint64_t tx_packets; /**< Number of TX packets */ + uint64_t tx_collisions; /**< Number of TX collisions */ + uint64_t tx_errors; /**< Number of TX errors */ + uint64_t tx_jabber_timeout_errors; + /**< Number of TX jabber timeout errors */ + uint64_t tx_frame_flushed_errors; + /**< Number of TX frame flushed errors */ + uint64_t tx_loss_of_carrier_errors; + /**< Number of TX loss of carrier errors */ + uint64_t tx_no_carrier_errors; /**< Number of TX no carrier errors */ + uint64_t tx_late_collision_errors; + /**< Number of TX late collision errors */ + uint64_t tx_excessive_collision_errors; + /**< Number of TX excessive collision errors */ + uint64_t tx_excessive_deferral_errors; + /**< Number of TX excessive deferral errors */ + uint64_t tx_underflow_errors; /**< Number of TX underflow errors */ + uint64_t tx_ip_header_errors; /**< Number of TX IP header errors */ + uint64_t tx_ip_payload_errors; /**< Number of TX IP payload errors */ + uint64_t tx_dropped; /**< Number of TX dropped packets */ + uint64_t hw_errs[10]; /**< GMAC DMA error counters */ + uint64_t rx_missed; /**< Number of RX packets missed by the DMA */ + uint64_t fifo_overflows; /**< Number of RX FIFO overflows signalled by the DMA */ + uint64_t rx_scatter_errors; /**< Number of scattered frames received by the DMA */ + uint64_t tx_ts_create_errors; /**< Number of tx timestamp creation errors */ + uint64_t gmac_total_ticks; /**< Total clock ticks spend inside the GMAC */ + uint64_t gmac_worst_case_ticks; /**< Worst case iteration of the GMAC in ticks */ + uint64_t gmac_iterations; /**< Number of iterations around the GMAC */ + uint64_t tx_pause_frames; /**< Number of pause frames sent by the GMAC */ + uint64_t mmc_rx_overflow_errors; + /**< Number of RX overflow errors */ + uint64_t mmc_rx_watchdog_timeout_errors; + /**< Number of RX watchdog timeout errors */ + uint64_t mmc_rx_crc_errors; /**< Number of RX CRC errors */ + uint64_t mmc_rx_ip_header_errors; + /**< Number of RX IP header errors read from MMC counter*/ + uint64_t mmc_rx_octets_g; + /**< Number of good octets received */ + uint64_t mmc_rx_ucast_frames; /**< Number of Unicast frames received */ + uint64_t mmc_rx_bcast_frames; /**< Number of Bcast frames received */ + uint64_t mmc_rx_mcast_frames; /**< Number of Mcast frames received */ + uint64_t mmc_rx_undersize; + /**< Number of RX undersize frames */ + uint64_t mmc_rx_oversize; + /**< Number of RX oversize frames */ + uint64_t mmc_rx_jabber; /**< Number of jabber frames */ + uint64_t mmc_rx_octets_gb; + /**< Number of good/bad octets */ + uint64_t mmc_rx_frag_frames_g; /**< Number of good ipv4 frag frames */ + uint64_t mmc_tx_octets_g; /**< Number of good octets sent */ + uint64_t mmc_tx_ucast_frames; /**< Number of Unicast frames sent*/ + uint64_t mmc_tx_bcast_frames; /**< Number of Broadcast frames sent */ + uint64_t mmc_tx_mcast_frames; /**< Number of Multicast frames sent */ + uint64_t mmc_tx_deferred; /**< Number of Deferred frames sent */ + uint64_t mmc_tx_single_col; /**< Number of single collisions */ + uint64_t mmc_tx_multiple_col; /**< Number of multiple collisions */ + uint64_t mmc_tx_octets_gb; /**< Number of good/bad octets sent*/ +}; + +extern struct nss_dp_data_plane_ops nss_dp_gmac_ops; + +#endif /* __NSS_DP_ARCH_H__ */ diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq60xx/nss_ipq60xx.c b/feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq60xx/nss_ipq60xx.c new file mode 100644 index 000000000..dab4276e4 --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq60xx/nss_ipq60xx.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "nss_dp_hal.h" +#include "edma.h" + +/* + * nss_dp_hal_get_data_plane_ops() + * Return the data plane ops for edma data plane. + */ +struct nss_dp_data_plane_ops *nss_dp_hal_get_data_plane_ops(void) +{ + return &nss_dp_edma_ops; +} + +/* + * nss_dp_hal_init() + * Initialize EDMA and set gmac ops. + */ +bool nss_dp_hal_init(void) +{ + nss_dp_hal_set_gmac_ops(&qcom_hal_ops, GMAC_HAL_TYPE_QCOM); + nss_dp_hal_set_gmac_ops(&syn_hal_ops, GMAC_HAL_TYPE_SYN_XGMAC); + + if (edma_init()) { + return false; + } + return true; +} + +/* + * nss_dp_hal_cleanup() + * Cleanup EDMA and set gmac ops to NULL. + */ +void nss_dp_hal_cleanup(void) +{ + nss_dp_hal_set_gmac_ops(NULL, GMAC_HAL_TYPE_QCOM); + nss_dp_hal_set_gmac_ops(NULL, GMAC_HAL_TYPE_SYN_XGMAC); + edma_cleanup(false); +} diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq60xx/nss_ipq60xx.h b/feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq60xx/nss_ipq60xx.h new file mode 100644 index 000000000..26dc76726 --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq60xx/nss_ipq60xx.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __NSS_DP_ARCH_H__ +#define __NSS_DP_ARCH_H__ + +#define NSS_DP_HAL_MAX_PORTS 5 +#define NSS_DP_HAL_CPU_NUM 4 +#define NSS_DP_HAL_START_IFNUM 1 +#define NSS_DP_HAL_MAX_MTU_SIZE 9216 +#define NSS_DP_HAL_MAX_PACKET_LEN 65535 +#define NSS_DP_PREHEADER_SIZE 32 + +/** + * nss_dp_hal_gmac_stats + * The per-GMAC statistics structure. + */ +struct nss_dp_hal_gmac_stats { +}; + +#endif /* __NSS_DP_ARCH_H__ */ diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq807x/nss_ipq807x.c b/feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq807x/nss_ipq807x.c new file mode 100644 index 000000000..dab4276e4 --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq807x/nss_ipq807x.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "nss_dp_hal.h" +#include "edma.h" + +/* + * nss_dp_hal_get_data_plane_ops() + * Return the data plane ops for edma data plane. + */ +struct nss_dp_data_plane_ops *nss_dp_hal_get_data_plane_ops(void) +{ + return &nss_dp_edma_ops; +} + +/* + * nss_dp_hal_init() + * Initialize EDMA and set gmac ops. + */ +bool nss_dp_hal_init(void) +{ + nss_dp_hal_set_gmac_ops(&qcom_hal_ops, GMAC_HAL_TYPE_QCOM); + nss_dp_hal_set_gmac_ops(&syn_hal_ops, GMAC_HAL_TYPE_SYN_XGMAC); + + if (edma_init()) { + return false; + } + return true; +} + +/* + * nss_dp_hal_cleanup() + * Cleanup EDMA and set gmac ops to NULL. + */ +void nss_dp_hal_cleanup(void) +{ + nss_dp_hal_set_gmac_ops(NULL, GMAC_HAL_TYPE_QCOM); + nss_dp_hal_set_gmac_ops(NULL, GMAC_HAL_TYPE_SYN_XGMAC); + edma_cleanup(false); +} diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq807x/nss_ipq807x.h b/feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq807x/nss_ipq807x.h new file mode 100644 index 000000000..6926e562e --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/arch/ipq807x/nss_ipq807x.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __NSS_DP_ARCH_H__ +#define __NSS_DP_ARCH_H__ + +#define NSS_DP_HAL_MAX_PORTS 6 +#define NSS_DP_HAL_CPU_NUM 4 +#define NSS_DP_HAL_START_IFNUM 1 +#define NSS_DP_HAL_MAX_MTU_SIZE 9216 +#define NSS_DP_HAL_MAX_PACKET_LEN 65535 +#define NSS_DP_PREHEADER_SIZE 32 + +/** + * nss_dp_hal_gmac_stats + * The per-GMAC statistics structure. + */ +struct nss_dp_hal_gmac_stats { +}; + +#endif /* __NSS_DP_ARCH_H__ */ diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/edma/edma_cfg.c b/feeds/ipq807x/qca-nss-dp/src/hal/edma/edma_cfg.c new file mode 100644 index 000000000..d2563c860 --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/edma/edma_cfg.c @@ -0,0 +1,967 @@ +/* + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + * USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include "nss_dp_dev.h" +#include "edma_regs.h" +#include "edma_data_plane.h" + +#define EDMA_HW_RESET_ID "edma_rst" + +/* + * edma_cleanup_rxfill_ring_res() + * Cleanup resources for one RxFill ring + */ +static void edma_cleanup_rxfill_ring_res(struct edma_hw *ehw, + struct edma_rxfill_ring *rxfill_ring) +{ + struct platform_device *pdev = ehw->pdev; + struct sk_buff *skb; + uint16_t cons_idx, curr_idx; + struct edma_rxfill_desc *rxfill_desc; + uint32_t reg_data = 0; + struct edma_rx_preheader *rxph = NULL; + int store_idx; + + /* + * Read RXFILL ring producer index + */ + reg_data = edma_reg_read(EDMA_REG_RXFILL_PROD_IDX(rxfill_ring->id)); + curr_idx = reg_data & EDMA_RXFILL_PROD_IDX_MASK; + + /* + * Read RXFILL ring consumer index + */ + reg_data = edma_reg_read(EDMA_REG_RXFILL_CONS_IDX(rxfill_ring->id)); + cons_idx = reg_data & EDMA_RXFILL_CONS_IDX_MASK; + + while (curr_idx != cons_idx) { + /* + * Get RXFILL descriptor + */ + rxfill_desc = EDMA_RXFILL_DESC(rxfill_ring, cons_idx); + + /* + * Get Rx preheader + */ + rxph = (struct edma_rx_preheader *) + phys_to_virt(rxfill_desc->buffer_addr); + + dma_unmap_single(&pdev->dev, rxfill_desc->buffer_addr, + EDMA_RX_BUFF_SIZE, DMA_FROM_DEVICE); + + /* + * Get sk_buff and free it + */ + store_idx = rxph->opaque; + skb = ehw->rx_skb_store[store_idx]; + ehw->rx_skb_store[store_idx] = NULL; + dev_kfree_skb_any(skb); + cons_idx++; + if (cons_idx == rxfill_ring->count) + cons_idx = 0; + } + + /* + * Free RXFILL ring descriptors + */ + dma_free_coherent(&pdev->dev, + (sizeof(struct edma_rxfill_desc) + * rxfill_ring->count), + rxfill_ring->desc, rxfill_ring->dma); +} + +/* + * edma_setup_rxfill_ring_res() + * Setup resources for one RxFill ring + */ +static int edma_setup_rxfill_ring_res(struct edma_hw *ehw, + struct edma_rxfill_ring *rxfill_ring) +{ + struct platform_device *pdev = ehw->pdev; + + /* + * Allocate RxFill ring descriptors + */ + rxfill_ring->desc = dma_alloc_coherent(&pdev->dev, + (sizeof(struct edma_rxfill_desc) + * rxfill_ring->count), + &rxfill_ring->dma, GFP_KERNEL); + if (!rxfill_ring->desc) { + pr_warn("Descriptor alloc for RXFILL ring %u failed\n", + rxfill_ring->id); + return -ENOMEM; + } + + spin_lock_init(&rxfill_ring->lock); + return 0; +} + +/* + * edma_setup_rxdesc_ring_res() + * Setup resources for one RxDesc ring + */ +static int edma_setup_rxdesc_ring_res(struct edma_hw *ehw, + struct edma_rxdesc_ring *rxdesc_ring) +{ + struct platform_device *pdev = ehw->pdev; + + /* + * Allocate RxDesc ring descriptors + */ + rxdesc_ring->desc = dma_alloc_coherent(&pdev->dev, + (sizeof(struct edma_rxdesc_desc) + * rxdesc_ring->count), + &rxdesc_ring->dma, GFP_KERNEL); + if (!rxdesc_ring->desc) { + pr_warn("Descriptor alloc for RXDESC ring %u failed\n", + rxdesc_ring->id); + return -ENOMEM; + } + + return 0; +} + +/* + * edma_cleanup_rxdesc_ring_res() + * Cleanup resources for RxDesc ring + */ +static void edma_cleanup_rxdesc_ring_res(struct edma_hw *ehw, + struct edma_rxdesc_ring *rxdesc_ring) +{ + struct platform_device *pdev = ehw->pdev; + struct sk_buff *skb; + struct edma_rxdesc_desc *rxdesc_desc; + struct edma_rx_preheader *rxph = NULL; + uint16_t prod_idx = 0; + uint16_t cons_idx = 0; + int store_idx; + + cons_idx = edma_reg_read(EDMA_REG_RXDESC_CONS_IDX(rxdesc_ring->id)) + & EDMA_RXDESC_CONS_IDX_MASK; + + prod_idx = edma_reg_read(EDMA_REG_RXDESC_PROD_IDX(rxdesc_ring->id)) + & EDMA_RXDESC_PROD_IDX_MASK; + + /* + * Free any buffers assigned to any descriptors + */ + while (cons_idx != prod_idx) { + rxdesc_desc = EDMA_RXDESC_DESC(rxdesc_ring, cons_idx); + + rxph = (struct edma_rx_preheader *) + phys_to_virt(rxdesc_desc->buffer_addr); + + dma_unmap_single(&pdev->dev, rxdesc_desc->buffer_addr, + EDMA_RX_BUFF_SIZE, DMA_FROM_DEVICE); + store_idx = rxph->opaque; + skb = ehw->rx_skb_store[store_idx]; + ehw->rx_skb_store[store_idx] = NULL; + dev_kfree_skb_any(skb); + + /* + * Update consumer index + */ + if (++cons_idx == rxdesc_ring->count) + cons_idx = 0; + } + + /* + * Free RXDESC ring descriptors + */ + dma_free_coherent(&pdev->dev, + (sizeof(struct edma_rxdesc_desc) + * rxdesc_ring->count), + rxdesc_ring->desc, rxdesc_ring->dma); +} + +/* + * edma_cleanup_txcmpl_ring_res() + * Cleanup resources for one TxCmpl ring + */ +static void edma_cleanup_txcmpl_ring_res(struct edma_hw *ehw, + struct edma_txcmpl_ring *txcmpl_ring) +{ + struct platform_device *pdev = ehw->pdev; + + /* + * Free any buffers assigned to any descriptors + */ + edma_clean_tx(ehw, txcmpl_ring); + + /* + * Free TxCmpl ring descriptors + */ + dma_free_coherent(&pdev->dev, + (sizeof(struct edma_txcmpl_desc) + * txcmpl_ring->count), + txcmpl_ring->desc, txcmpl_ring->dma); +} + +/* + * edma_setup_txcmpl_ring_res() + * Setup resources for one TxCmpl ring + */ +static int edma_setup_txcmpl_ring_res(struct edma_hw *ehw, + struct edma_txcmpl_ring *txcmpl_ring) +{ + struct platform_device *pdev = ehw->pdev; + + /* + * Allocate TxCmpl ring descriptors + */ + txcmpl_ring->desc = dma_alloc_coherent(&pdev->dev, + (sizeof(struct edma_txcmpl_desc) + * txcmpl_ring->count), + &txcmpl_ring->dma, GFP_KERNEL); + + if (!txcmpl_ring->desc) { + pr_warn("Descriptor alloc for TXCMPL ring %u failed\n", + txcmpl_ring->id); + + return -ENOMEM; + } + + return 0; +} + +/* + * edma_cleanup_txdesc_ring_res() + * Cleanup resources for one TxDesc ring + */ +static void edma_cleanup_txdesc_ring_res(struct edma_hw *ehw, + struct edma_txdesc_ring *txdesc_ring) +{ + struct platform_device *pdev = ehw->pdev; + struct sk_buff *skb = NULL; + struct edma_txdesc_desc *txdesc = NULL; + uint16_t prod_idx, cons_idx; + size_t buf_len; + uint32_t data; + int store_idx; + + /* + * Free any buffers assigned to any descriptors + */ + data = edma_reg_read(EDMA_REG_TXDESC_PROD_IDX(txdesc_ring->id)); + prod_idx = data & EDMA_TXDESC_PROD_IDX_MASK; + + data = edma_reg_read(EDMA_REG_TXDESC_CONS_IDX(txdesc_ring->id)); + cons_idx = data & EDMA_TXDESC_CONS_IDX_MASK; + + while (cons_idx != prod_idx) { + txdesc = EDMA_TXDESC_DESC(txdesc_ring, cons_idx); + store_idx = txdesc->buffer_addr; + skb = ehw->tx_skb_store[store_idx]; + ehw->tx_skb_store[store_idx] = NULL; + + buf_len = (txdesc->word1 & EDMA_TXDESC_DATA_LENGTH_MASK) >> + EDMA_TXDESC_DATA_LENGTH_SHIFT; + + dma_unmap_single(&pdev->dev, (dma_addr_t)skb->data, + buf_len + EDMA_TX_PREHDR_SIZE, DMA_TO_DEVICE); + + dev_kfree_skb_any(skb); + cons_idx = (cons_idx + 1) & (txdesc_ring->count - 1); + cons_idx++; + if (cons_idx == txdesc_ring->count) + cons_idx = 0; + + } + + /* + * Free Tx ring descriptors + */ + dma_free_coherent(&pdev->dev, + (sizeof(struct edma_txdesc_desc) + * txdesc_ring->count), + txdesc_ring->desc, txdesc_ring->dma); + +} + +/* + * edma_setup_txdesc_ring_res() + * Setup resources for one TxDesc ring + */ +static int edma_setup_txdesc_ring_res(struct edma_hw *ehw, + struct edma_txdesc_ring *txdesc_ring) +{ + struct platform_device *pdev = ehw->pdev; + + /* + * Allocate Tx ring descriptors + */ + txdesc_ring->desc = dma_alloc_coherent(&pdev->dev, + (sizeof(struct edma_txdesc_desc) + * txdesc_ring->count), + &txdesc_ring->dma, GFP_KERNEL); + if (!txdesc_ring->desc) { + pr_warn("Descriptor alloc for TXDESC ring %u failed\n", + txdesc_ring->id); + return -ENOMEM; + } + + spin_lock_init(&txdesc_ring->tx_lock); + + return 0; +} + +/* + * edma_setup_ring_resources() + * Allocate/setup resources for EDMA rings + */ +static int edma_setup_ring_resources(struct edma_hw *ehw) +{ + struct edma_txcmpl_ring *txcmpl_ring = NULL; + struct edma_txdesc_ring *txdesc_ring = NULL; + struct edma_rxfill_ring *rxfill_ring = NULL; + struct edma_rxdesc_ring *rxdesc_ring = NULL; + int i; + int ret; + int index; + + /* + * Allocate TxDesc ring descriptors + */ + for (i = 0; i < ehw->txdesc_rings; i++) { + txdesc_ring = &ehw->txdesc_ring[i]; + txdesc_ring->count = EDMA_RING_SIZE; + txdesc_ring->id = ehw->txdesc_ring_start + i; + + ret = edma_setup_txdesc_ring_res(ehw, txdesc_ring); + if (ret != 0) { + while (i-- >= 0) + edma_cleanup_txdesc_ring_res(ehw, + &ehw->txdesc_ring[i]); + + return -ENOMEM; + + } + } + + /* + * Allocate TxCmpl ring descriptors + */ + for (i = 0; i < ehw->txcmpl_rings; i++) { + txcmpl_ring = &ehw->txcmpl_ring[i]; + txcmpl_ring->count = EDMA_RING_SIZE; + txcmpl_ring->id = ehw->txcmpl_ring_start + i; + + ret = edma_setup_txcmpl_ring_res(ehw, txcmpl_ring); + + if (ret != 0) { + while (i-- >= 0) + edma_cleanup_txcmpl_ring_res(ehw, + &ehw->txcmpl_ring[i]); + + goto txcmpl_mem_alloc_fail; + } + } + + /* + * Allocate Rx fill ring descriptors + */ + for (i = 0; i < ehw->rxfill_rings; i++) { + rxfill_ring = &ehw->rxfill_ring[i]; + rxfill_ring->count = EDMA_RING_SIZE; + rxfill_ring->id = ehw->rxfill_ring_start + i; + + ret = edma_setup_rxfill_ring_res(ehw, rxfill_ring); + if (ret != 0) { + while (--i >= 0) + edma_cleanup_rxfill_ring_res(ehw, + &ehw->rxfill_ring[i]); + + goto rxfill_mem_alloc_fail; + } + } + + /* + * Allocate RxDesc ring descriptors + */ + for (i = 0; i < ehw->rxdesc_rings; i++) { + rxdesc_ring = &ehw->rxdesc_ring[i]; + rxdesc_ring->count = EDMA_RING_SIZE; + rxdesc_ring->id = ehw->rxdesc_ring_start + i; + + /* + * Create a mapping between RX Desc ring and Rx fill ring. + * Number of fill rings are lesser than the descriptor rings + * Share the fill rings across descriptor rings. + */ + + index = ehw->rxfill_ring_start + (i % ehw->rxfill_rings); + rxdesc_ring->rxfill = + &ehw->rxfill_ring[index - ehw->rxfill_ring_start]; + + ret = edma_setup_rxdesc_ring_res(ehw, rxdesc_ring); + if (ret != 0) { + while (--i >= 0) + edma_cleanup_rxdesc_ring_res(ehw, + &ehw->rxdesc_ring[i]); + + goto rxdesc_mem_alloc_fail; + } + } + + return 0; + +rxdesc_mem_alloc_fail: + for (i = 0; i < ehw->rxfill_rings; i++) + edma_cleanup_rxfill_ring_res(ehw, &ehw->rxfill_ring[i]); + +rxfill_mem_alloc_fail: + for (i = 0; i < ehw->txcmpl_rings; i++) + edma_cleanup_txcmpl_ring_res(ehw, &ehw->txcmpl_ring[i]); + +txcmpl_mem_alloc_fail: + for (i = 0; i < ehw->txdesc_rings; i++) + edma_cleanup_txdesc_ring_res(ehw, &ehw->txdesc_ring[i]); + + return -ENOMEM; +} + +/* + * edma_free_rings() + * Free EDMA software rings + */ +static void edma_free_rings(struct edma_hw *ehw) +{ + kfree(ehw->rxfill_ring); + kfree(ehw->rxdesc_ring); + kfree(ehw->txdesc_ring); + kfree(ehw->txcmpl_ring); +} + +/* + * edma_alloc_rings() + * Allocate EDMA software rings + */ +static int edma_alloc_rings(struct edma_hw *ehw) +{ + ehw->rxfill_ring = kzalloc((sizeof(struct edma_rxfill_ring) * + ehw->rxfill_rings), GFP_KERNEL); + if (!ehw->rxfill_ring) + return -ENOMEM; + + ehw->rxdesc_ring = kzalloc((sizeof(struct edma_rxdesc_ring) * + ehw->rxdesc_rings), GFP_KERNEL); + if (!ehw->rxdesc_ring) + goto rxdesc_ring_alloc_fail; + + ehw->txdesc_ring = kzalloc((sizeof(struct edma_txdesc_ring) * + ehw->txdesc_rings), GFP_KERNEL); + if (!ehw->txdesc_ring) + goto txdesc_ring_alloc_fail; + + ehw->txcmpl_ring = kzalloc((sizeof(struct edma_txcmpl_ring) * + ehw->txcmpl_rings), GFP_KERNEL); + if (!ehw->txcmpl_ring) + goto txcmpl_ring_alloc_fail; + + pr_info("Num rings - TxDesc:%u (%u-%u) TxCmpl:%u (%u-%u)\n", + ehw->txdesc_rings, ehw->txdesc_ring_start, + (ehw->txdesc_ring_start + ehw->txdesc_rings - 1), + ehw->txcmpl_rings, ehw->txcmpl_ring_start, + (ehw->txcmpl_ring_start + ehw->txcmpl_rings - 1)); + + pr_info("RxDesc:%u (%u-%u) RxFill:%u (%u-%u)\n", + ehw->rxdesc_rings, ehw->rxdesc_ring_start, + (ehw->rxdesc_ring_start + ehw->rxdesc_rings - 1), + ehw->rxfill_rings, ehw->rxfill_ring_start, + (ehw->rxfill_ring_start + ehw->rxfill_rings - 1)); + + return 0; +txcmpl_ring_alloc_fail: + kfree(ehw->txdesc_ring); +txdesc_ring_alloc_fail: + kfree(ehw->rxdesc_ring); +rxdesc_ring_alloc_fail: + kfree(ehw->rxfill_ring); + return -ENOMEM; +} + +/* + * edma_cleanup_rings() + * Cleanup EDMA rings + */ +void edma_cleanup_rings(struct edma_hw *ehw) +{ + int i; + + /* + * Free any buffers assigned to any descriptors + */ + for (i = 0; i < ehw->txdesc_rings; i++) + edma_cleanup_txdesc_ring_res(ehw, &ehw->txdesc_ring[i]); + + /* + * Free Tx completion descriptors + */ + for (i = 0; i < ehw->txcmpl_rings; i++) + edma_cleanup_txcmpl_ring_res(ehw, &ehw->txcmpl_ring[i]); + + /* + * Free Rx fill ring descriptors + */ + for (i = 0; i < ehw->rxfill_rings; i++) + edma_cleanup_rxfill_ring_res(ehw, &ehw->rxfill_ring[i]); + + /* + * Free Rx completion ring descriptors + */ + for (i = 0; i < ehw->rxdesc_rings; i++) + edma_cleanup_rxdesc_ring_res(ehw, &ehw->rxdesc_ring[i]); + + edma_free_rings(ehw); +} + +/* + * edma_init_rings() + * Initialize EDMA rings + */ +static int edma_init_rings(struct edma_hw *ehw) +{ + int ret = 0; + + ret = edma_alloc_rings(ehw); + if (ret) + return ret; + + ret = edma_setup_ring_resources(ehw); + if (ret) + return ret; + + return 0; +} + +/* + * edma_configure_txdesc_ring() + * Configure one TxDesc ring + */ +static void edma_configure_txdesc_ring(struct edma_hw *ehw, + struct edma_txdesc_ring *txdesc_ring) +{ + uint32_t data = 0; + uint16_t hw_cons_idx = 0; + + /* + * Configure TXDESC ring + */ + edma_reg_write(EDMA_REG_TXDESC_BA(txdesc_ring->id), + (uint32_t)(txdesc_ring->dma & + EDMA_RING_DMA_MASK)); + + edma_reg_write(EDMA_REG_TXDESC_RING_SIZE(txdesc_ring->id), + (uint32_t)(txdesc_ring->count & + EDMA_TXDESC_RING_SIZE_MASK)); + + data = edma_reg_read(EDMA_REG_TXDESC_CONS_IDX(txdesc_ring->id)); + data &= ~(EDMA_TXDESC_CONS_IDX_MASK); + hw_cons_idx = data; + + data = edma_reg_read(EDMA_REG_TXDESC_PROD_IDX(txdesc_ring->id)); + data &= ~(EDMA_TXDESC_PROD_IDX_MASK); + data |= hw_cons_idx & EDMA_TXDESC_PROD_IDX_MASK; + edma_reg_write(EDMA_REG_TXDESC_PROD_IDX(txdesc_ring->id), data); +} + +/* + * edma_configure_txcmpl_ring() + * Configure one TxCmpl ring + */ +static void edma_configure_txcmpl_ring(struct edma_hw *ehw, + struct edma_txcmpl_ring *txcmpl_ring) +{ + uint32_t tx_mod_timer; + + /* + * Configure TxCmpl ring base address + */ + edma_reg_write(EDMA_REG_TXCMPL_BA(txcmpl_ring->id), + (uint32_t)(txcmpl_ring->dma & EDMA_RING_DMA_MASK)); + edma_reg_write(EDMA_REG_TXCMPL_RING_SIZE(txcmpl_ring->id), + (uint32_t)(txcmpl_ring->count + & EDMA_TXDESC_RING_SIZE_MASK)); + + /* + * Set TxCmpl ret mode to opaque + */ + edma_reg_write(EDMA_REG_TXCMPL_CTRL(txcmpl_ring->id), + EDMA_TXCMPL_RETMODE_OPAQUE); + + tx_mod_timer = (EDMA_TX_MOD_TIMER & EDMA_TX_MOD_TIMER_INIT_MASK) + << EDMA_TX_MOD_TIMER_INIT_SHIFT; + edma_reg_write(EDMA_REG_TX_MOD_TIMER(txcmpl_ring->id), + tx_mod_timer); + + edma_reg_write(EDMA_REG_TX_INT_CTRL(txcmpl_ring->id), 0x2); +} + +/* + * edma_configure_rxdesc_ring() + * Configure one RxDesc ring + */ +static void edma_configure_rxdesc_ring(struct edma_hw *ehw, + struct edma_rxdesc_ring *rxdesc_ring) +{ + uint32_t data; + + edma_reg_write(EDMA_REG_RXDESC_BA(rxdesc_ring->id), + (uint32_t)(rxdesc_ring->dma & 0xffffffff)); + + data = rxdesc_ring->count & EDMA_RXDESC_RING_SIZE_MASK; + data |= (ehw->rx_payload_offset & EDMA_RXDESC_PL_OFFSET_MASK) + << EDMA_RXDESC_PL_OFFSET_SHIFT; + edma_reg_write(EDMA_REG_RXDESC_RING_SIZE(rxdesc_ring->id), data); + + data = (EDMA_RX_MOD_TIMER_INIT & EDMA_RX_MOD_TIMER_INIT_MASK) + << EDMA_RX_MOD_TIMER_INIT_SHIFT; + edma_reg_write(EDMA_REG_RX_MOD_TIMER(rxdesc_ring->id), data); + + /* + * Enable ring. Set ret mode to 'opaque'. + */ + edma_reg_write(EDMA_REG_RX_INT_CTRL(rxdesc_ring->id), 0x2); +} + +/* + * edma_configure_rxfill_ring() + * Configure one RxFill ring + */ +static void edma_configure_rxfill_ring(struct edma_hw *ehw, + struct edma_rxfill_ring *rxfill_ring) +{ + uint32_t data = 0; + + edma_reg_write(EDMA_REG_RXFILL_BA(rxfill_ring->id), + (uint32_t)(rxfill_ring->dma & EDMA_RING_DMA_MASK)); + + data = rxfill_ring->count & EDMA_RXFILL_RING_SIZE_MASK; + edma_reg_write(EDMA_REG_RXFILL_RING_SIZE(rxfill_ring->id), data); + + /* + * Alloc Rx buffers + */ + edma_alloc_rx_buffer(ehw, rxfill_ring); +} + +/* + * edma_configure_rings() + * Configure EDMA rings + */ +static void edma_configure_rings(struct edma_hw *ehw) +{ + int i = 0; + + /* + * Initialize the store + */ + for (i = 0; i < EDMA_RING_SIZE; i++) { + ehw->tx_skb_store[i] = NULL; + ehw->rx_skb_store[i] = NULL; + } + + /* + * Configure TXDESC ring + */ + for (i = 0; i < ehw->txdesc_rings; i++) + edma_configure_txdesc_ring(ehw, &ehw->txdesc_ring[i]); + + /* + * Configure TXCMPL ring + */ + for (i = 0; i < ehw->txcmpl_rings; i++) + edma_configure_txcmpl_ring(ehw, &ehw->txcmpl_ring[i]); + + /* + * Configure RXFILL rings + */ + for (i = 0; i < ehw->rxfill_rings; i++) + edma_configure_rxfill_ring(ehw, &ehw->rxfill_ring[i]); + + /* + * Configure RXDESC ring + */ + for (i = 0; i < ehw->rxdesc_rings; i++) + edma_configure_rxdesc_ring(ehw, &ehw->rxdesc_ring[i]); +} + +/* + * edma_hw_reset() + * Reset EDMA Hardware during initialization + */ +int edma_hw_reset(struct edma_hw *ehw) +{ + struct reset_control *rst; + struct platform_device *pdev = ehw->pdev; + + rst = devm_reset_control_get(&pdev->dev, EDMA_HW_RESET_ID); + if (IS_ERR(rst)) { + pr_warn("DTS Node: %s does not exist\n", EDMA_HW_RESET_ID); + return -EINVAL; + } + + reset_control_assert(rst); + udelay(100); + + reset_control_deassert(rst); + udelay(100); + + pr_info("EDMA HW Reset completed succesfully\n"); + + return 0; +} + +/* + * edma_hw_init() + * EDMA hw init + */ +int edma_hw_init(struct edma_hw *ehw) +{ + int ret = 0; + int desc_index; + uint32_t i, data, reg = 0; + struct edma_rxdesc_ring *rxdesc_ring = NULL; + + data = edma_reg_read(EDMA_REG_MAS_CTRL); + pr_info("EDMA ver %d hw init\n", data); + + /* + * Setup private data structure + */ + ehw->misc_intr_mask = 0x0; + ehw->rxfill_intr_mask = EDMA_RXFILL_INT_MASK; + ehw->rxdesc_intr_mask = EDMA_RXDESC_INT_MASK_PKT_INT; + ehw->txcmpl_intr_mask = EDMA_TX_INT_MASK_PKT_INT | + EDMA_TX_INT_MASK_UGT_INT; + ehw->rx_payload_offset = EDMA_RX_PREHDR_SIZE; + ehw->active = 0; + ehw->edma_initialized = false; + + /* Reset EDMA */ + ret = edma_hw_reset(ehw); + if (ret) + return ret; + + /* + * Disable interrupts + */ + for (i = 0; i < EDMA_MAX_TXCMPL_RINGS; i++) + edma_reg_write(EDMA_REG_TX_INT_MASK(i), 0); + + for (i = 0; i < EDMA_MAX_RXFILL_RINGS; i++) + edma_reg_write(EDMA_REG_RXFILL_INT_MASK(i), 0); + + for (i = 0; i < EDMA_MAX_RXDESC_RINGS; i++) + edma_reg_write(EDMA_REG_RX_INT_CTRL(i), 0); + + /* + * Disable Rx rings + */ + for (i = 0; i < EDMA_MAX_RXDESC_RINGS; i++) { + data = edma_reg_read(EDMA_REG_RXDESC_CTRL(i)); + data &= ~EDMA_RXDESC_RX_EN; + edma_reg_write(EDMA_REG_RXDESC_CTRL(i), data); + } + + /* + * Disable RxFill Rings + */ + for (i = 0; i < EDMA_MAX_RXFILL_RINGS; i++) { + data = edma_reg_read(EDMA_REG_RXFILL_RING_EN(i)); + data &= ~EDMA_RXFILL_RING_EN; + edma_reg_write(EDMA_REG_RXFILL_RING_EN(i), data); + } + + /* + * Disable Tx rings + */ + for (desc_index = 0; desc_index < EDMA_MAX_TXDESC_RINGS; desc_index++) { + data = edma_reg_read(EDMA_REG_TXDESC_CTRL(desc_index)); + data &= ~EDMA_TXDESC_TX_EN; + edma_reg_write(EDMA_REG_TXDESC_CTRL(desc_index), data); + } + +#if defined(NSS_DP_IPQ807X) + /* + * Clear the TXDESC2CMPL_MAP_xx reg before setting up + * the mapping. This register holds TXDESC to TXFILL ring + * mapping. + */ + edma_reg_write(EDMA_REG_TXDESC2CMPL_MAP_0, 0); + edma_reg_write(EDMA_REG_TXDESC2CMPL_MAP_1, 0); + edma_reg_write(EDMA_REG_TXDESC2CMPL_MAP_2, 0); + desc_index = ehw->txcmpl_ring_start; + + /* + * 3 registers to hold the completion mapping for total 24 + * TX desc rings (0-9,10-19 and rest). In each entry 3 bits hold + * the mapping for a particular TX desc ring. + */ + for (i = ehw->txdesc_ring_start; + i < ehw->txdesc_ring_end; i++) { + if (i >= 0 && i <= 9) + reg = EDMA_REG_TXDESC2CMPL_MAP_0; + else if (i >= 10 && i <= 19) + reg = EDMA_REG_TXDESC2CMPL_MAP_1; + else + reg = EDMA_REG_TXDESC2CMPL_MAP_2; + + pr_debug("Configure TXDESC:%u to use TXCMPL:%u\n", + i, desc_index); + + data = edma_reg_read(reg); + data |= (desc_index & 0x7) << ((i % 10) * 3); + edma_reg_write(reg, data); + + desc_index++; + if (desc_index == ehw->txcmpl_ring_end) + desc_index = ehw->txcmpl_ring_start; + } +#endif + + /* + * Set PPE QID to EDMA Rx ring mapping. + * When coming up use only queue 0. + * HOST EDMA rings. FW EDMA comes up and overwrites as required. + * Each entry can hold mapping for 8 PPE queues and entry size is + * 4 bytes + */ + desc_index = ehw->rxdesc_ring_start; + data = 0; + data |= (desc_index & 0xF); + edma_reg_write(EDMA_QID2RID_TABLE_MEM(0), data); + pr_debug("Configure QID2RID reg:0x%x to 0x%x\n", reg, data); + + ret = edma_init_rings(ehw); + if (ret) + return ret; + + edma_configure_rings(ehw); + + /* + * Set RXDESC2FILL_MAP_xx reg. + * There are two registers RXDESC2FILL_0 and RXDESC2FILL_1 + * 3 bits holds the rx fill ring mapping for each of the + * rx descriptor ring. + */ + edma_reg_write(EDMA_REG_RXDESC2FILL_MAP_0, 0); + edma_reg_write(EDMA_REG_RXDESC2FILL_MAP_1, 0); + for (i = ehw->rxdesc_ring_start; + i < ehw->rxdesc_ring_end; i++) { + if ((i >= 0) && (i <= 9)) + reg = EDMA_REG_RXDESC2FILL_MAP_0; + else + reg = EDMA_REG_RXDESC2FILL_MAP_1; + + rxdesc_ring = &ehw->rxdesc_ring[i - ehw->rxdesc_ring_start]; + + pr_debug("Configure RXDESC:%u to use RXFILL:%u\n", + rxdesc_ring->id, rxdesc_ring->rxfill->id); + + data = edma_reg_read(reg); + data |= (rxdesc_ring->rxfill->id & 0x7) << ((i % 10) * 3); + edma_reg_write(reg, data); + } + + reg = EDMA_REG_RXDESC2FILL_MAP_0; + pr_debug("EDMA_REG_RXDESC2FILL_MAP_0: 0x%x\n", edma_reg_read(reg)); + reg = EDMA_REG_RXDESC2FILL_MAP_1; + pr_debug("EDMA_REG_RXDESC2FILL_MAP_1: 0x%x\n", edma_reg_read(reg)); + +#if defined(NSS_DP_IPQ807X) + reg = EDMA_REG_TXDESC2CMPL_MAP_0; + pr_debug("EDMA_REG_TXDESC2CMPL_MAP_0: 0x%x\n", edma_reg_read(reg)); + reg = EDMA_REG_TXDESC2CMPL_MAP_1; + pr_debug("EDMA_REG_TXDESC2CMPL_MAP_1: 0x%x\n", edma_reg_read(reg)); + reg = EDMA_REG_TXDESC2CMPL_MAP_2; + pr_debug("EDMA_REG_TXDESC2CMPL_MAP_2: 0x%x\n", edma_reg_read(reg)); +#endif + + /* + * Configure DMA request priority, DMA read burst length, + * and AXI write size. + */ + data = EDMA_DMAR_BURST_LEN_SET(EDMA_BURST_LEN_ENABLE) + | EDMA_DMAR_REQ_PRI_SET(0) + | EDMA_DMAR_TXDATA_OUTSTANDING_NUM_SET(31) + | EDMA_DMAR_TXDESC_OUTSTANDING_NUM_SET(7) + | EDMA_DMAR_RXFILL_OUTSTANDING_NUM_SET(7); + edma_reg_write(EDMA_REG_DMAR_CTRL, data); +#if defined(NSS_DP_IPQ60XX) + data = edma_reg_read(EDMA_REG_AXIW_CTRL); + data |= EDMA_AXIW_MAX_WR_SIZE_EN; + edma_reg_write(EDMA_REG_AXIW_CTRL, data); +#endif + + /* + * Misc error mask + */ + data = EDMA_MISC_AXI_RD_ERR_MASK_EN | + EDMA_MISC_AXI_WR_ERR_MASK_EN | + EDMA_MISC_RX_DESC_FIFO_FULL_MASK_EN | + EDMA_MISC_RX_ERR_BUF_SIZE_MASK_EN | + EDMA_MISC_TX_SRAM_FULL_MASK_EN | + EDMA_MISC_TX_CMPL_BUF_FULL_MASK_EN | + EDMA_MISC_DATA_LEN_ERR_MASK_EN; +#if defined(NSS_DP_IPQ807X) + data |= EDMA_MISC_PKT_LEN_LA_64K_MASK_EN | + EDMA_MISC_PKT_LEN_LE_40_MASK_EN; +#else + data |= EDMA_MISC_TX_TIMEOUT_MASK_EN; +#endif + edma_reg_write(EDMA_REG_MISC_INT_MASK, data); + + /* + * Global EDMA enable and padding enable + */ + data = EDMA_PORT_PAD_EN | EDMA_PORT_EDMA_EN; + edma_reg_write(EDMA_REG_PORT_CTRL, data); + + /* + * Enable Rx rings + */ + for (i = ehw->rxdesc_ring_start; i < ehw->rxdesc_ring_end; i++) { + data = edma_reg_read(EDMA_REG_RXDESC_CTRL(i)); + data |= EDMA_RXDESC_RX_EN; + edma_reg_write(EDMA_REG_RXDESC_CTRL(i), data); + } + + for (i = ehw->rxfill_ring_start; i < ehw->rxfill_ring_end; i++) { + data = edma_reg_read(EDMA_REG_RXFILL_RING_EN(i)); + data |= EDMA_RXFILL_RING_EN; + edma_reg_write(EDMA_REG_RXFILL_RING_EN(i), data); + } + + /* + * Enable Tx rings + */ + for (i = ehw->txdesc_ring_start; i < ehw->txdesc_ring_end; i++) { + data = edma_reg_read(EDMA_REG_TXDESC_CTRL(i)); + data |= EDMA_TXDESC_TX_EN; + edma_reg_write(EDMA_REG_TXDESC_CTRL(i), data); + } + + ehw->edma_initialized = true; + + return 0; +} diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/edma/edma_data_plane.c b/feeds/ipq807x/qca-nss-dp/src/hal/edma/edma_data_plane.c new file mode 100644 index 000000000..d51c7f07b --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/edma/edma_data_plane.c @@ -0,0 +1,906 @@ +/* + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + * USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include +#include +#include +#include +#include +#include + +#include "nss_dp_dev.h" +#include "edma_regs.h" +#include "edma_data_plane.h" + +/* + * EDMA hardware instance + */ +struct edma_hw edma_hw; + +/* + * edma_get_port_num_from_netdev() + * Get port number from net device + */ +static int edma_get_port_num_from_netdev(struct net_device *netdev) +{ + int i; + + for (i = 0; i < EDMA_MAX_GMACS; i++) { + /* In the port-id to netdev mapping table, port-id + * starts from 1 and table index starts from 0. + * So we return index + 1 for port-id + */ + if (edma_hw.netdev_arr[i] == netdev) + return i+1; + } + + return -1; +} + +/* + * edma_reg_read() + * Read EDMA register + */ +uint32_t edma_reg_read(uint32_t reg_off) +{ + return (uint32_t)readl(edma_hw.reg_base + reg_off); +} + +/* + * edma_reg_write() + * Write EDMA register + */ +void edma_reg_write(uint32_t reg_off, uint32_t val) +{ + writel(val, edma_hw.reg_base + reg_off); +} + +/* + * nss_dp_edma_if_open() + * Do slow path data plane open + */ +static int edma_if_open(struct nss_dp_data_plane_ctx *dpc, + uint32_t tx_desc_ring, uint32_t rx_desc_ring, + uint32_t mode) +{ + if (!dpc->dev) + return NSS_DP_FAILURE; + + /* + * Enable NAPI + */ + if (edma_hw.active++ != 0) + return NSS_DP_SUCCESS; + + napi_enable(&edma_hw.napi); + return NSS_DP_SUCCESS; +} + +/* + * edma_if_close() + * Do slow path data plane close + */ +static int edma_if_close(struct nss_dp_data_plane_ctx *dpc) +{ + if (--edma_hw.active != 0) + return NSS_DP_SUCCESS; + + /* + * Disable NAPI + */ + napi_disable(&edma_hw.napi); + return NSS_DP_SUCCESS; +} + +/* + * edma_if_link_state() + */ +static int edma_if_link_state(struct nss_dp_data_plane_ctx *dpc, + uint32_t link_state) +{ + return NSS_DP_SUCCESS; +} + +/* + * edma_if_mac_addr() + */ +static int edma_if_mac_addr(struct nss_dp_data_plane_ctx *dpc, uint8_t *addr) +{ + return NSS_DP_SUCCESS; +} + +/* + * edma_if_change_mtu() + */ +static int edma_if_change_mtu(struct nss_dp_data_plane_ctx *dpc, uint32_t mtu) +{ + return NSS_DP_SUCCESS; +} + +/* + * edma_if_xmit() + * Transmit a packet using EDMA + */ +static netdev_tx_t edma_if_xmit(struct nss_dp_data_plane_ctx *dpc, + struct sk_buff *skb) +{ + struct net_device *netdev = dpc->dev; + int ret; + uint32_t tx_ring, skbq, nhead, ntail; + bool expand_skb = false; + + if (skb->len < ETH_HLEN) { + netdev_dbg(netdev, "skb->len < ETH_HLEN\n"); + goto drop; + } + + /* + * Select a Tx ring + */ + skbq = skb_get_queue_mapping(skb); + tx_ring = 0; + if ((edma_hw.txdesc_rings > 1) && (skbq > 0)) + tx_ring = edma_hw.txdesc_rings % skbq; + + /* + * Check for non-linear skb + */ + if (skb_is_nonlinear(skb)) { + netdev_dbg(netdev, "cannot Tx non-linear skb:%px\n", skb); + goto drop; + } + + /* + * Check for headroom/tailroom and clone + */ + nhead = netdev->needed_headroom; + ntail = netdev->needed_tailroom; + + if (skb_cloned(skb) || + (skb_headroom(skb) < nhead) || + (skb_headroom(skb) < ntail)) { + expand_skb = true; + } + + /* + * Expand the skb. This also unclones a cloned skb. + */ + if (expand_skb && pskb_expand_head(skb, nhead, ntail, GFP_ATOMIC)) { + netdev_dbg(netdev, "cannot expand skb:%px\n", skb); + goto drop; + } + + /* + * Transmit the packet + */ + ret = edma_ring_xmit(&edma_hw, netdev, skb, + &edma_hw.txdesc_ring[tx_ring]); + if (ret == EDMA_TX_OK) + return NETDEV_TX_OK; + + /* + * Not enough descriptors. Stop netdev Tx queue. + */ + if (ret == EDMA_TX_DESC) { + netif_stop_queue(netdev); + return NETDEV_TX_BUSY; + } + +drop: + dev_kfree_skb_any(skb); + netdev->stats.tx_dropped++; + + return NETDEV_TX_OK; +} + +/* + * edma_if_set_features() + * Set the supported net_device features + */ +static void edma_if_set_features(struct nss_dp_data_plane_ctx *dpc) +{ + /* + * TODO - add flags to support HIGHMEM/cksum offload VLAN + * the features are enabled. + */ +} + +/* TODO - check if this is needed */ +/* + * edma_if_pause_on_off() + * Set pause frames on or off + * + * No need to send a message if we defaulted to slow path. + */ +static int edma_if_pause_on_off(struct nss_dp_data_plane_ctx *dpc, + uint32_t pause_on) +{ + return NSS_DP_SUCCESS; +} + +/* + * edma_if_vsi_assign() + * assign vsi of the data plane + * + */ +static int edma_if_vsi_assign(struct nss_dp_data_plane_ctx *dpc, uint32_t vsi) +{ + struct net_device *netdev = dpc->dev; + int32_t port_num; + + port_num = edma_get_port_num_from_netdev(netdev); + + if (port_num < 0) + return NSS_DP_FAILURE; + + if (fal_port_vsi_set(0, port_num, vsi) < 0) + return NSS_DP_FAILURE; + + return NSS_DP_SUCCESS; +} + +/* + * edma_if_vsi_unassign() + * unassign vsi of the data plane + * + */ +static int edma_if_vsi_unassign(struct nss_dp_data_plane_ctx *dpc, uint32_t vsi) +{ + struct net_device *netdev = dpc->dev; + uint32_t port_num; + + port_num = edma_get_port_num_from_netdev(netdev); + + if (port_num < 0) + return NSS_DP_FAILURE; + + if (fal_port_vsi_set(0, port_num, 0xffff) < 0) + return NSS_DP_FAILURE; + + return NSS_DP_SUCCESS; +} + +#ifdef CONFIG_RFS_ACCEL +/* + * edma_if_rx_flow_steer() + * Flow steer of the data plane + * + * Initial receive flow steering function for data plane operation. + */ +static int edma_if_rx_flow_steer(struct nss_dp_data_plane_ctx *dpc, struct sk_buff *skb, + uint32_t cpu, bool is_add) +{ + return NSS_DP_SUCCESS; +} +#endif + +/* + * edma_if_deinit() + * Free edma resources + */ +static int edma_if_deinit(struct nss_dp_data_plane_ctx *dpc) +{ + /* + * Free up resources used by EDMA if all the + * interfaces have been overridden + * */ + if (edma_hw.dp_override_cnt == EDMA_MAX_GMACS - 1) { + edma_cleanup(true); + } else { + edma_hw.dp_override_cnt++; + } + + return NSS_DP_SUCCESS; +} + +/* + * edma_irq_init() + * Initialize interrupt handlers for the driver + */ +static int edma_irq_init(void) +{ + struct edma_rxdesc_ring *rxdesc_ring = NULL; + struct edma_rxfill_ring *rxfill_ring = NULL; + struct edma_txcmpl_ring *txcmpl_ring = NULL; + int err; + uint32_t entry_num, i; + + /* + * Get TXCMPL rings IRQ numbers + */ + entry_num = 0; + for (i = 0; i < edma_hw.txcmpl_rings; i++, entry_num++) { + edma_hw.txcmpl_intr[i] = + platform_get_irq(edma_hw.pdev, entry_num); + if (edma_hw.txcmpl_intr[i] < 0) { + pr_warn("%s: txcmpl_intr[%u] irq get failed\n", + (edma_hw.device_node)->name, i); + return -1; + } + + pr_debug("%s: txcmpl_intr[%u] = %u\n", + (edma_hw.device_node)->name, + i, edma_hw.txcmpl_intr[i]); + } + + /* + * Get RXFILL rings IRQ numbers + */ + for (i = 0; i < edma_hw.rxfill_rings; i++, entry_num++) { + edma_hw.rxfill_intr[i] = + platform_get_irq(edma_hw.pdev, entry_num); + if (edma_hw.rxfill_intr[i] < 0) { + pr_warn("%s: rxfill_intr[%u] irq get failed\n", + (edma_hw.device_node)->name, i); + return -1; + } + + pr_debug("%s: rxfill_intr[%u] = %u\n", + (edma_hw.device_node)->name, + i, edma_hw.rxfill_intr[i]); + } + + /* + * Get RXDESC rings IRQ numbers + * + */ + for (i = 0; i < edma_hw.rxdesc_rings; i++, entry_num++) { + edma_hw.rxdesc_intr[i] = + platform_get_irq(edma_hw.pdev, entry_num); + if (edma_hw.rxdesc_intr[i] < 0) { + pr_warn("%s: rxdesc_intr[%u] irq get failed\n", + (edma_hw.device_node)->name, i); + return -1; + } + + pr_debug("%s: rxdesc_intr[%u] = %u\n", + (edma_hw.device_node)->name, + i, edma_hw.rxdesc_intr[i]); + } + + /* + * Get misc IRQ number + */ + edma_hw.misc_intr = platform_get_irq(edma_hw.pdev, entry_num); + pr_debug("%s: misc IRQ:%u\n", + (edma_hw.device_node)->name, + edma_hw.misc_intr); + + /* + * Request IRQ for TXCMPL rings + */ + for (i = 0; i < edma_hw.txcmpl_rings; i++) { + err = request_irq(edma_hw.txcmpl_intr[i], + edma_handle_irq, IRQF_SHARED, + "edma_txcmpl", (void *)edma_hw.pdev); + if (err) { + pr_debug("TXCMPL ring IRQ:%d request failed\n", + edma_hw.txcmpl_intr[i]); + return -1; + + } + } + + /* + * Request IRQ for RXFILL rings + */ + for (i = 0; i < edma_hw.rxfill_rings; i++) { + err = request_irq(edma_hw.rxfill_intr[i], + edma_handle_irq, IRQF_SHARED, + "edma_rxfill", (void *)edma_hw.pdev); + if (err) { + pr_debug("RXFILL ring IRQ:%d request failed\n", + edma_hw.rxfill_intr[i]); + goto rx_fill_ring_intr_req_fail; + } + } + + /* + * Request IRQ for RXDESC rings + */ + for (i = 0; i < edma_hw.rxdesc_rings; i++) { + err = request_irq(edma_hw.rxdesc_intr[i], + edma_handle_irq, IRQF_SHARED, + "edma_rxdesc", (void *)edma_hw.pdev); + if (err) { + pr_debug("RXDESC ring IRQ:%d request failed\n", + edma_hw.rxdesc_intr[i]); + goto rx_desc_ring_intr_req_fail; + } + } + + /* + * Request Misc IRQ + */ + err = request_irq(edma_hw.misc_intr, edma_handle_misc_irq, + IRQF_SHARED, "edma_misc", + (void *)edma_hw.pdev); + if (err) { + pr_debug("MISC IRQ:%d request failed\n", + edma_hw.misc_intr); + goto misc_intr_req_fail; + } + + /* + * Set interrupt mask + */ + for (i = 0; i < edma_hw.rxfill_rings; i++) { + rxfill_ring = &edma_hw.rxfill_ring[i]; + edma_reg_write(EDMA_REG_RXFILL_INT_MASK(rxfill_ring->id), + edma_hw.rxfill_intr_mask); + } + + for (i = 0; i < edma_hw.txcmpl_rings; i++) { + txcmpl_ring = &edma_hw.txcmpl_ring[i]; + edma_reg_write(EDMA_REG_TX_INT_MASK(txcmpl_ring->id), + edma_hw.txcmpl_intr_mask); + } + + for (i = 0; i < edma_hw.rxdesc_rings; i++) { + rxdesc_ring = &edma_hw.rxdesc_ring[i]; + edma_reg_write(EDMA_REG_RXDESC_INT_MASK(rxdesc_ring->id), + edma_hw.rxdesc_intr_mask); + } + + edma_reg_write(EDMA_REG_MISC_INT_MASK, edma_hw.misc_intr_mask); + return 0; + +misc_intr_req_fail: + + /* + * Free IRQ for RXDESC rings + */ + for (i = 0; i < edma_hw.rxdesc_rings; i++) { + synchronize_irq(edma_hw.rxdesc_intr[i]); + free_irq(edma_hw.rxdesc_intr[i], + (void *)&(edma_hw.pdev)->dev); + } + +rx_desc_ring_intr_req_fail: + + /* + * Free IRQ for RXFILL rings + */ + for (i = 0; i < edma_hw.rxfill_rings; i++) { + synchronize_irq(edma_hw.rxfill_intr[i]); + free_irq(edma_hw.rxfill_intr[i], + (void *)&(edma_hw.pdev)->dev); + } + +rx_fill_ring_intr_req_fail: + + /* + * Free IRQ for TXCMPL rings + */ + for (i = 0; i < edma_hw.txcmpl_rings; i++) { + + synchronize_irq(edma_hw.txcmpl_intr[i]); + free_irq(edma_hw.txcmpl_intr[i], + (void *)&(edma_hw.pdev)->dev); + } + + return -1; +} + +/* + * edma_register_netdevice() + * Register netdevice with EDMA + */ +static int edma_register_netdevice(struct net_device *netdev, uint32_t macid) +{ + if (!netdev) { + pr_info("nss_dp_edma: Invalid netdev pointer %px\n", netdev); + return -EINVAL; + } + + if ((macid < EDMA_START_GMACS) || (macid > EDMA_MAX_GMACS)) { + netdev_dbg(netdev, "nss_dp_edma: Invalid macid(%d) for %s\n", + macid, netdev->name); + return -EINVAL; + } + + netdev_info(netdev, "nss_dp_edma: Registering netdev %s(qcom-id:%d) with EDMA\n", + netdev->name, macid); + + /* + * We expect 'macid' to correspond to ports numbers on + * IPQ807x. These begin from '1' and hence we subtract + * one when using it as an array index. + */ + edma_hw.netdev_arr[macid - 1] = netdev; + + /* + * NAPI add + */ + if (!edma_hw.napi_added) { + netif_napi_add(netdev, &edma_hw.napi, edma_napi, + EDMA_NAPI_WORK); + /* + * Register the interrupt handlers and enable interrupts + */ + if (edma_irq_init() < 0) + return -EINVAL; + + edma_hw.napi_added = 1; + } + + return 0; +} + +/* + * edma_if_init() + */ + +static int edma_if_init(struct nss_dp_data_plane_ctx *dpc) +{ + + struct net_device *netdev = dpc->dev; + struct nss_dp_dev *dp_dev = (struct nss_dp_dev *)netdev_priv(netdev); + int ret = 0; + + /* + * Register the netdev + */ + ret = edma_register_netdevice(netdev, dp_dev->macid); + if (ret) { + netdev_dbg(netdev, + "Error registering netdevice with EDMA %s\n", + netdev->name); + return NSS_DP_FAILURE; + } + + /* + * Headroom needed for Tx preheader + */ + netdev->needed_headroom += EDMA_TX_PREHDR_SIZE; + + return NSS_DP_SUCCESS; +} + +/* + * nss_dp_edma_ops + */ +struct nss_dp_data_plane_ops nss_dp_edma_ops = { + .init = edma_if_init, + .open = edma_if_open, + .close = edma_if_close, + .link_state = edma_if_link_state, + .mac_addr = edma_if_mac_addr, + .change_mtu = edma_if_change_mtu, + .xmit = edma_if_xmit, + .set_features = edma_if_set_features, + .pause_on_off = edma_if_pause_on_off, + .vsi_assign = edma_if_vsi_assign, + .vsi_unassign = edma_if_vsi_unassign, +#ifdef CONFIG_RFS_ACCEL + .rx_flow_steer = edma_if_rx_flow_steer, +#endif + .deinit = edma_if_deinit, +}; + +/* + * edma_of_get_pdata() + * Read the device tree details for EDMA + */ +static int edma_of_get_pdata(struct resource *edma_res) +{ + /* + * Find EDMA node in device tree + */ + edma_hw.device_node = of_find_node_by_name(NULL, + EDMA_DEVICE_NODE_NAME); + if (!edma_hw.device_node) { + pr_warn("EDMA device tree node (%s) not found\n", + EDMA_DEVICE_NODE_NAME); + return -EINVAL; + } + + /* + * Get EDMA device node + */ + edma_hw.pdev = of_find_device_by_node(edma_hw.device_node); + if (!edma_hw.pdev) { + pr_warn("Platform device for node %px(%s) not found\n", + edma_hw.device_node, + (edma_hw.device_node)->name); + return -EINVAL; + } + + /* + * Get EDMA register resource + */ + if (of_address_to_resource(edma_hw.device_node, 0, edma_res) != 0) { + pr_warn("Unable to get register address for edma device: " + EDMA_DEVICE_NODE_NAME"\n"); + return -EINVAL; + } + + /* + * Get id of first TXDESC ring + */ + if (of_property_read_u32(edma_hw.device_node, "qcom,txdesc-ring-start", + &edma_hw.txdesc_ring_start) != 0) { + pr_warn("Read error 1st TXDESC ring (txdesc_ring_start)\n"); + return -EINVAL; + } + + /* + * Get number of TXDESC rings + */ + if (of_property_read_u32(edma_hw.device_node, "qcom,txdesc-rings", + &edma_hw.txdesc_rings) != 0) { + pr_warn("Unable to read number of txdesc rings.\n"); + return -EINVAL; + } + edma_hw.txdesc_ring_end = edma_hw.txdesc_ring_start + + edma_hw.txdesc_rings; + + /* + * Get id of first TXCMPL ring + */ + if (of_property_read_u32(edma_hw.device_node, "qcom,txcmpl-ring-start", + &edma_hw.txcmpl_ring_start) != 0) { + pr_warn("Read error 1st TXCMPL ring (txcmpl_ring_start)\n"); + return -EINVAL; + } + + /* + * Get number of TXCMPL rings + */ + if (of_property_read_u32(edma_hw.device_node, "qcom,txcmpl-rings", + &edma_hw.txcmpl_rings) != 0) { + pr_warn("Unable to read number of txcmpl rings.\n"); + return -EINVAL; + } + edma_hw.txcmpl_ring_end = edma_hw.txcmpl_ring_start + + edma_hw.txcmpl_rings; + + /* + * Get id of first RXFILL ring + */ + if (of_property_read_u32(edma_hw.device_node, "qcom,rxfill-ring-start", + &edma_hw.rxfill_ring_start) != 0) { + pr_warn("Read error 1st RXFILL ring (rxfill-ring-start)\n"); + return -EINVAL; + } + + /* + * Get number of RXFILL rings + */ + if (of_property_read_u32(edma_hw.device_node, "qcom,rxfill-rings", + &edma_hw.rxfill_rings) != 0) { + pr_warn("Unable to read number of rxfill rings.\n"); + return -EINVAL; + } + edma_hw.rxfill_ring_end = edma_hw.rxfill_ring_start + + edma_hw.rxfill_rings; + + /* + * Get id of first RXDESC ring + */ + if (of_property_read_u32(edma_hw.device_node, "qcom,rxdesc-ring-start", + &edma_hw.rxdesc_ring_start) != 0) { + pr_warn("Read error 1st RXDESC ring (rxdesc-ring-start)\n"); + return -EINVAL; + } + + /* + * Get number of RXDESC rings + */ + if (of_property_read_u32(edma_hw.device_node, "qcom,rxdesc-rings", + &edma_hw.rxdesc_rings) != 0) { + pr_warn("Unable to read number of rxdesc rings.\n"); + return -EINVAL; + } + edma_hw.rxdesc_ring_end = edma_hw.rxdesc_ring_start + + edma_hw.rxdesc_rings; + + return 0; +} + +/* + * edma_init() + * EDMA init + */ +int edma_init(void) +{ + int ret = 0; + struct resource res_edma; + + /* + * Get all the DTS data needed + */ + if (edma_of_get_pdata(&res_edma) < 0) { + pr_warn("Unable to get EDMA DTS data.\n"); + return -EINVAL; + } + + /* + * Request memory region for EDMA registers + */ + edma_hw.reg_resource = request_mem_region(res_edma.start, + resource_size(&res_edma), + EDMA_DEVICE_NODE_NAME); + if (!edma_hw.reg_resource) { + pr_warn("Unable to request EDMA register memory.\n"); + return -EFAULT; + } + + /* + * Remap register resource + */ + edma_hw.reg_base = ioremap_nocache((edma_hw.reg_resource)->start, + resource_size(edma_hw.reg_resource)); + if (!edma_hw.reg_base) { + pr_warn("Unable to remap EDMA register memory.\n"); + ret = -EFAULT; + goto edma_init_remap_fail; + } + + if (edma_hw_init(&edma_hw) != 0) { + ret = -EFAULT; + goto edma_init_hw_init_fail; + } + + platform_set_drvdata(edma_hw.pdev, (void *)&edma_hw); + + edma_hw.napi_added = 0; + + return 0; + +edma_init_hw_init_fail: + iounmap(edma_hw.reg_base); + +edma_init_remap_fail: + release_mem_region((edma_hw.reg_resource)->start, + resource_size(edma_hw.reg_resource)); + return ret; +} + +/* + * edma_disable_port() + * EDMA disable port + */ +static void edma_disable_port(void) +{ + edma_reg_write(EDMA_REG_PORT_CTRL, EDMA_DISABLE); +} + +/* + * edma_cleanup() + * EDMA cleanup + */ +void edma_cleanup(bool is_dp_override) +{ + int i; + struct edma_txcmpl_ring *txcmpl_ring = NULL; + struct edma_rxdesc_ring *rxdesc_ring = NULL; + + /* + * The cleanup can happen from data plane override + * or from module_exit, we want to cleanup only once + */ + if (!edma_hw.edma_initialized) { + /* + * Disable EDMA only at module exit time, since NSS firmware + * depends on this setting. + */ + if (!is_dp_override) { + edma_disable_port(); + } + return; + } + + /* + * Disable Rx rings used by this driver + */ + for (i = edma_hw.rxdesc_ring_start; i < edma_hw.rxdesc_ring_end; i++) + edma_reg_write(EDMA_REG_RXDESC_CTRL(i), EDMA_RING_DISABLE); + + /* + * Disable Tx rings used by this driver + */ + for (i = edma_hw.txdesc_ring_start; i < edma_hw.txdesc_ring_end; i++) { + txcmpl_ring = &edma_hw.txcmpl_ring[i]; + edma_reg_write(EDMA_REG_TXDESC_CTRL(i), + EDMA_RING_DISABLE); + } + + /* + * Disable RxFill Rings used by this driver + */ + for (i = edma_hw.rxfill_ring_start; i < edma_hw.rxfill_ring_end; i++) + edma_reg_write(EDMA_REG_RXFILL_RING_EN(i), EDMA_RING_DISABLE); + + /* + * Clear interrupt mask + */ + for (i = 0; i < edma_hw.rxdesc_rings; i++) { + rxdesc_ring = &edma_hw.rxdesc_ring[i]; + edma_reg_write(EDMA_REG_RXDESC_INT_MASK(rxdesc_ring->id), + EDMA_MASK_INT_CLEAR); + } + + for (i = 0; i < edma_hw.txcmpl_rings; i++) { + txcmpl_ring = &edma_hw.txcmpl_ring[i]; + edma_reg_write(EDMA_REG_TX_INT_MASK(txcmpl_ring->id), + EDMA_MASK_INT_CLEAR); + } + + edma_reg_write(EDMA_REG_MISC_INT_MASK, EDMA_MASK_INT_CLEAR); + /* + * Remove interrupt handlers and NAPI + */ + if (edma_hw.napi_added) { + + /* + * Free IRQ for TXCMPL rings + */ + for (i = 0; i < edma_hw.txcmpl_rings; i++) { + synchronize_irq(edma_hw.txcmpl_intr[i]); + free_irq(edma_hw.txcmpl_intr[i], + (void *)(edma_hw.pdev)); + } + + /* + * Free IRQ for RXFILL rings + */ + for (i = 0; i < edma_hw.rxfill_rings; i++) { + synchronize_irq(edma_hw.rxfill_intr[i]); + free_irq(edma_hw.rxfill_intr[i], + (void *)(edma_hw.pdev)); + } + + /* + * Free IRQ for RXDESC rings + */ + for (i = 0; i < edma_hw.rxdesc_rings; i++) { + synchronize_irq(edma_hw.rxdesc_intr[i]); + free_irq(edma_hw.rxdesc_intr[i], + (void *)(edma_hw.pdev)); + } + + /* + * Free Misc IRQ + */ + synchronize_irq(edma_hw.misc_intr); + free_irq(edma_hw.misc_intr, (void *)(edma_hw.pdev)); + + netif_napi_del(&edma_hw.napi); + edma_hw.napi_added = 0; + } + + /* + * Disable EDMA only at module exit time, since NSS firmware + * depends on this setting. + */ + if (!is_dp_override) { + edma_disable_port(); + } + + /* + * cleanup rings and free + */ + edma_cleanup_rings(&edma_hw); + iounmap(edma_hw.reg_base); + release_mem_region((edma_hw.reg_resource)->start, + resource_size(edma_hw.reg_resource)); + + /* + * Mark initialize false, so that we do not + * try to cleanup again + */ + edma_hw.edma_initialized = false; +} diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/edma/edma_data_plane.h b/feeds/ipq807x/qca-nss-dp/src/hal/edma/edma_data_plane.h new file mode 100644 index 000000000..226c024fb --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/edma/edma_data_plane.h @@ -0,0 +1,287 @@ +/* + ************************************************************************** + * Copyright (c) 2016, 2018-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** +*/ + +#include "nss_dp_dev.h" + +#ifndef __NSS_DP_EDMA_DATAPLANE__ +#define __NSS_DP_EDMA_DATAPLANE__ + +#define EDMA_BUF_SIZE 2000 +#define EDMA_DEVICE_NODE_NAME "edma" +#define EDMA_RX_BUFF_SIZE (EDMA_BUF_SIZE + EDMA_RX_PREHDR_SIZE) +#define EDMA_RX_PREHDR_SIZE (sizeof(struct edma_rx_preheader)) +#define EDMA_TX_PREHDR_SIZE (sizeof(struct edma_tx_preheader)) +#define EDMA_RING_SIZE 128 +#define EDMA_NAPI_WORK 100 +#define EDMA_START_GMACS NSS_DP_START_IFNUM +#define EDMA_MAX_GMACS NSS_DP_HAL_MAX_PORTS +#define EDMA_TX_PKT_MIN_SIZE 33 +#if defined(NSS_DP_IPQ60XX) +#define EDMA_MAX_TXCMPL_RINGS 24 /* Max TxCmpl rings */ +#else +#define EDMA_MAX_TXCMPL_RINGS 8 /* Max TxCmpl rings */ +#endif +#define EDMA_MAX_RXDESC_RINGS 16 /* Max RxDesc rings */ +#define EDMA_MAX_RXFILL_RINGS 8 /* Max RxFill rings */ +#define EDMA_MAX_TXDESC_RINGS 24 /* Max TxDesc rings */ +#define EDMA_GET_DESC(R, i, type) (&(((type *)((R)->desc))[i])) +#define EDMA_RXFILL_DESC(R, i) EDMA_GET_DESC(R, i, struct edma_rxfill_desc) +#define EDMA_RXDESC_DESC(R, i) EDMA_GET_DESC(R, i, struct edma_rxdesc_desc) +#define EDMA_TXDESC_DESC(R, i) EDMA_GET_DESC(R, i, struct edma_txdesc_desc) +#define EDMA_RXPH_SRC_INFO_TYPE_GET(rxph) (((rxph)->src_info >> 8) & 0xf0) +#define EDMA_RXPH_SERVICE_CODE_GET(rxph) (((rxph)->rx_pre4) & 0xff) + +/* + * Tx descriptor + */ +struct edma_txdesc_desc { + uint32_t buffer_addr; + /* buffer address */ + uint32_t word1; + /* more bit, TSO, preheader, pool, offset and length */ +}; + +/* + * TxCmpl descriptor + */ +struct edma_txcmpl_desc { + uint32_t buffer_addr; /* buffer address/opaque */ + uint32_t status; /* status */ +}; + +/* + * Rx descriptor + */ +struct edma_rxdesc_desc { + uint32_t buffer_addr; /* buffer address */ + uint32_t status; /* status */ +}; + +/* + * RxFill descriptor + */ +struct edma_rxfill_desc { + uint32_t buffer_addr; /* Buffer address */ + uint32_t word1; /* opaque_ind and buffer size */ +}; + +/* + * Tx descriptor ring + */ +struct edma_txdesc_ring { + uint32_t id; /* TXDESC ring number */ + void *desc; /* descriptor ring virtual address */ + dma_addr_t dma; /* descriptor ring physical address */ + spinlock_t tx_lock; /* Tx ring lock */ + uint16_t count; /* number of descriptors */ +}; + +/* + * TxCmpl ring + */ +struct edma_txcmpl_ring { + uint32_t id; /* TXCMPL ring number */ + void *desc; /* descriptor ring virtual address */ + dma_addr_t dma; /* descriptor ring physical address */ + uint16_t count; /* number of descriptors in the ring */ +}; + +/* + * RxFill ring + */ +struct edma_rxfill_ring { + uint32_t id; /* RXFILL ring number */ + void *desc; /* descriptor ring virtual address */ + dma_addr_t dma; /* descriptor ring physical address */ + spinlock_t lock; /* Rx ring lock */ + uint16_t count; /* number of descriptors in the ring */ +}; + +/* + * RxDesc ring + */ +struct edma_rxdesc_ring { + uint32_t id; /* RXDESC ring number */ + struct edma_rxfill_ring *rxfill; /* RXFILL ring used */ + void *desc; /* descriptor ring virtual address */ + dma_addr_t dma; /* descriptor ring physical address */ + uint16_t count; /* number of descriptors in the ring */ +}; + +/* + * EDMA Tx Preheader + */ +struct edma_tx_preheader { + uint32_t opaque; /* Opaque, contains skb pointer */ + uint16_t src_info; /* Src information */ + uint16_t dst_info; /* Dest information */ + uint32_t tx_pre2; /* SVLAN & CVLAN flag, drop prec, hash value */ + uint32_t tx_pre3; /* STAG, CTAG */ + uint32_t tx_pre4; /* CPU code, L3 & L4 offset, service code */ + uint32_t tx_pre5; /* IP addr index, ACL index */ + uint32_t tx_pre6; /* IP payload checksum, copy2cpu, timestamp, dscp */ + uint32_t tx_pre7; /* Timestamp, QoS TAG */ +}; + +/* + * EDMA Rx Preheader + */ +struct edma_rx_preheader { + uint32_t opaque; + /* Opaque, contains skb pointer*/ + uint16_t src_info; + /* Src information */ + uint16_t dst_info; + /* Dest information */ + uint32_t rx_pre2; + /* SVLAN & CVLAN flag, drop prec, hash value */ + uint32_t rx_pre3; + /* STAG, CTAG */ + uint32_t rx_pre4; + /* CPU code, L3 & L4 offset, service code */ + uint32_t rx_pre5; + /* IP addr index, ACL index */ + uint32_t rx_pre6; + /* IP payload checksum, copy2cpu, timestamp, dscp */ + uint32_t rx_pre7; + /* Timestamp, QoS TAG */ +}; + +enum edma_tx { + EDMA_TX_OK = 0, /* Tx success */ + EDMA_TX_DESC = 1, /* Not enough descriptors */ + EDMA_TX_FAIL = 2, /* Tx failure */ +}; + +/* + * EDMA private data structure + */ +struct edma_hw { + struct napi_struct napi; + /* napi structure */ + struct net_device *netdev_arr[EDMA_MAX_GMACS]; + /* netdev for each gmac port */ + struct device_node *device_node; + /* Device tree node */ + struct platform_device *pdev; + /* Platform device */ + void __iomem *reg_base; + /* Base register address */ + struct resource *reg_resource; + /* Memory resource */ + uint16_t rx_payload_offset; + /* start of the payload offset */ + uint32_t flags; + /* internal flags */ + int active; + /* status */ + int napi_added; + /* flag to indicate napi add status */ + + /* + * Debugfs entries + */ + struct dentry *edma_dentry; + struct dentry *txdesc_dentry; + struct dentry *txcmpl_dentry; + struct dentry *rxdesc_dentry; + + /* + * Store for tx and rx skbs + */ + struct sk_buff *rx_skb_store[EDMA_RING_SIZE]; + struct sk_buff *tx_skb_store[EDMA_RING_SIZE]; + + struct edma_rxfill_ring *rxfill_ring; + /* Rx Fill Ring, SW is producer */ + struct edma_rxdesc_ring *rxdesc_ring; + /* Rx Descriptor Ring, SW is consumer */ + struct edma_txdesc_ring *txdesc_ring; + /* Tx Descriptor Ring, SW is producer */ + struct edma_txcmpl_ring *txcmpl_ring; + /* Tx Completion Ring, SW is consumer */ + + uint32_t txdesc_rings; + /* Number of TxDesc rings */ + uint32_t txdesc_ring_start; + /* Id of first TXDESC ring */ + uint32_t txdesc_ring_end; + /* Id of the last TXDESC ring */ + uint32_t txcmpl_rings; + /* Number of TxCmpl rings */ + uint32_t txcmpl_ring_start; + /* Id of first TXCMPL ring */ + uint32_t txcmpl_ring_end; + /* Id of last TXCMPL ring */ + uint32_t rxfill_rings; + /* Number of RxFill rings */ + uint32_t rxfill_ring_start; + /* Id of first RxFill ring */ + uint32_t rxfill_ring_end; + /* Id of last RxFill ring */ + uint32_t rxdesc_rings; + /* Number of RxDesc rings */ + uint32_t rxdesc_ring_start; + /* Id of first RxDesc ring */ + uint32_t rxdesc_ring_end; + /* Id of last RxDesc ring */ + uint32_t txcmpl_intr[EDMA_MAX_TXCMPL_RINGS]; + /* TxCmpl ring IRQ numbers */ + uint32_t rxfill_intr[EDMA_MAX_RXFILL_RINGS]; + /* Rx fill ring IRQ numbers */ + uint32_t rxdesc_intr[EDMA_MAX_RXDESC_RINGS]; + /* Rx desc ring IRQ numbers */ + uint32_t misc_intr; + /* Misc IRQ number */ + + uint32_t tx_intr_mask; + /* Tx interrupt mask */ + uint32_t rxfill_intr_mask; + /* Rx fill ring interrupt mask */ + uint32_t rxdesc_intr_mask; + /* Rx Desc ring interrupt mask */ + uint32_t txcmpl_intr_mask; + /* Tx Cmpl ring interrupt mask */ + uint32_t misc_intr_mask; + /* misc interrupt interrupt mask */ + uint32_t dp_override_cnt; + /* number of interfaces overriden */ + bool edma_initialized; + /* flag to check initialization status */ +}; + +extern struct edma_hw edma_hw; + +uint32_t edma_reg_read(uint32_t reg_off); +void edma_reg_write(uint32_t reg_off, uint32_t val); + +int edma_alloc_rx_buffer(struct edma_hw *ehw, + struct edma_rxfill_ring *rxfill_ring); +enum edma_tx edma_ring_xmit(struct edma_hw *ehw, + struct net_device *netdev, + struct sk_buff *skb, + struct edma_txdesc_ring *txdesc_ring); +uint32_t edma_clean_tx(struct edma_hw *ehw, + struct edma_txcmpl_ring *txcmpl_ring); +irqreturn_t edma_handle_irq(int irq, void *ctx); +irqreturn_t edma_handle_misc_irq(int irq, void *ctx); +int edma_napi(struct napi_struct *napi, int budget); +void edma_cleanup_rings(struct edma_hw *ehw); +void edma_cleanup(bool is_dp_override); +int edma_hw_init(struct edma_hw *ehw); +#endif /* __NSS_DP_EDMA_DATAPLANE__ */ diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/edma/edma_regs.h b/feeds/ipq807x/qca-nss-dp/src/hal/edma/edma_regs.h new file mode 100644 index 000000000..e724cc7cf --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/edma/edma_regs.h @@ -0,0 +1,454 @@ +/* + ************************************************************************** + * Copyright (c) 2016,2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** +*/ + +#ifndef __EDMA_REGS__ +#define __EDMA_REGS__ + +/* + * IPQ807x EDMA register offsets + */ +#define EDMA_REG_MAS_CTRL 0x0 +#define EDMA_REG_PORT_CTRL 0x4 +#define EDMA_REG_VLAN_CTRL 0x8 +#define EDMA_REG_RXDESC2FILL_MAP_0 0x18 +#define EDMA_REG_RXDESC2FILL_MAP_1 0x1c +#define EDMA_REG_TXQ_CTRL 0x20 +#define EDMA_REG_TXQ_CTRL_2 0x24 +#define EDMA_REG_TXQ_FC_0 0x28 +#define EDMA_REG_TXQ_FC_1 0x30 +#define EDMA_REG_TXQ_FC_2 0x34 +#define EDMA_REG_TXQ_FC_3 0x38 +#define EDMA_REG_RXQ_CTRL 0x3c +#define EDMA_REG_RX_TX_FULL_QID 0x40 +#define EDMA_REG_RXQ_FC_THRE 0x44 +#define EDMA_REG_DMAR_CTRL 0x48 +#define EDMA_REG_AXIR_CTRL 0x4c +#define EDMA_REG_AXIW_CTRL 0x50 +#define EDMA_REG_MIN_MSS 0x54 +#define EDMA_REG_LOOPBACK_CTRL 0x58 +#define EDMA_REG_MISC_INT_STAT 0x5c +#define EDMA_REG_MISC_INT_MASK 0x60 +#define EDMA_REG_DBG_CTRL 0x64 +#define EDMA_REG_DBG_DATA 0x68 +#define EDMA_REG_TXDESC_BA(n) (0x1000 + (0x1000 * n)) +#define EDMA_REG_TXDESC_PROD_IDX(n) (0x1004 + (0x1000 * n)) +#define EDMA_REG_TXDESC_CONS_IDX(n) (0x1008 + (0x1000 * n)) +#define EDMA_REG_TXDESC_RING_SIZE(n) (0x100c + (0x1000 * n)) +#define EDMA_REG_TXDESC_CTRL(n) (0x1010 + (0x1000 * n)) +#if defined(NSS_DP_IPQ807X) +#define EDMA_REG_TXDESC2CMPL_MAP_0 0xc +#define EDMA_REG_TXDESC2CMPL_MAP_1 0x10 +#define EDMA_REG_TXDESC2CMPL_MAP_2 0x14 +#define EDMA_REG_TXCMPL_BASE 0x19000 +#define EDMA_REG_TX_BASE 0x21000 +#else +#define EDMA_REG_TXCMPL_BASE 0x79000 +#define EDMA_REG_TX_BASE 0x91000 +#endif +#define EDMA_REG_TXCMPL_BA_OFFSET 0x00000 +#define EDMA_REG_TXCMPL_PROD_IDX_OFFSET 0x00004 +#define EDMA_REG_TXCMPL_CONS_IDX_OFFSET 0x00008 +#define EDMA_REG_TXCMPL_RING_SIZE_OFFSET 0x0000c +#define EDMA_REG_TXCMPL_UGT_THRE_OFFSET 0x00010 +#define EDMA_REG_TXCMPL_CTRL_OFFSET 0x00014 +#define EDMA_REG_TXCMPL_BPC_OFFSET 0x00018 +#define EDMA_REG_TX_INT_STAT_OFFSET 0x00000 +#define EDMA_REG_TX_INT_MASK_OFFSET 0x00004 +#define EDMA_REG_TX_MOD_TIMER_OFFSET 0x00008 +#define EDMA_REG_TX_INT_CTRL_OFFSET 0x0000c +#define EDMA_REG_TXCMPL_BA(n) (EDMA_REG_TXCMPL_BASE + EDMA_REG_TXCMPL_BA_OFFSET + (0x1000 * n)) +#define EDMA_REG_TXCMPL_PROD_IDX(n) (EDMA_REG_TXCMPL_BASE + EDMA_REG_TXCMPL_PROD_IDX_OFFSET + (0x1000 * n)) +#define EDMA_REG_TXCMPL_CONS_IDX(n) (EDMA_REG_TXCMPL_BASE + EDMA_REG_TXCMPL_CONS_IDX_OFFSET + (0x1000 * n)) +#define EDMA_REG_TXCMPL_RING_SIZE(n) (EDMA_REG_TXCMPL_BASE + EDMA_REG_TXCMPL_RING_SIZE_OFFSET + (0x1000 * n)) +#define EDMA_REG_TXCMPL_UGT_THRE(n) (EDMA_REG_TXCMPL_BASE + EDMA_REG_TXCMPL_UGT_THRE_OFFSET + (0x1000 * n)) +#define EDMA_REG_TXCMPL_CTRL(n) (EDMA_REG_TXCMPL_BASE + EDMA_REG_TXCMPL_CTRL_OFFSET + (0x1000 * n)) +#define EDMA_REG_TXCMPL_BPC(n) (EDMA_REG_TXCMPL_BASE + EDMA_REG_TXCMPL_BPC_OFFSET + (0x1000 * n)) +#define EDMA_REG_TX_INT_STAT(n) (EDMA_REG_TX_BASE + EDMA_REG_TX_INT_STAT_OFFSET + (0x1000 * n)) +#define EDMA_REG_TX_INT_MASK(n) (EDMA_REG_TX_BASE + EDMA_REG_TX_INT_MASK_OFFSET + (0x1000 * n)) +#define EDMA_REG_TX_MOD_TIMER(n) (EDMA_REG_TX_BASE + EDMA_REG_TX_MOD_TIMER_OFFSET + (0x1000 * n)) +#define EDMA_REG_TX_INT_CTRL(n) (EDMA_REG_TX_BASE + EDMA_REG_TX_INT_CTRL_OFFSET + (0x1000 * n)) +#define EDMA_REG_RXFILL_BA(n) (0x29000 + (0x1000 * n)) +#define EDMA_REG_RXFILL_PROD_IDX(n) (0x29004 + (0x1000 * n)) +#define EDMA_REG_RXFILL_CONS_IDX(n) (0x29008 + (0x1000 * n)) +#define EDMA_REG_RXFILL_RING_SIZE(n) (0x2900c + (0x1000 * n)) +#define EDMA_REG_RXFILL_BUFFER1_SIZE(n) (0x29010 + (0x1000 * n)) +#define EDMA_REG_RXFILL_FC_THRE(n) (0x29014 + (0x1000 * n)) +#define EDMA_REG_RXFILL_UGT_THRE(n) (0x29018 + (0x1000 * n)) +#define EDMA_REG_RXFILL_RING_EN(n) (0x2901c + (0x1000 * n)) +#define EDMA_REG_RXFILL_DISABLE(n) (0x29020 + (0x1000 * n)) +#define EDMA_REG_RXFILL_DISABLE_DONE(n) (0x29024 + (0x1000 * n)) +#define EDMA_REG_RXFILL_INT_STAT(n) (0x31000 + (0x1000 * n)) +#define EDMA_REG_RXFILL_INT_MASK(n) (0x31004 + (0x1000 * n)) +#define EDMA_REG_RXDESC_BA(n) (0x39000 + (0x1000 * n)) +#define EDMA_REG_RXDESC_PROD_IDX(n) (0x39004 + (0x1000 * n)) +#define EDMA_REG_RXDESC_CONS_IDX(n) (0x39008 + (0x1000 * n)) +#define EDMA_REG_RXDESC_RING_SIZE(n) (0x3900c + (0x1000 * n)) +#define EDMA_REG_RXDESC_FC_THRE(n) (0x39010 + (0x1000 * n)) +#define EDMA_REG_RXDESC_UGT_THRE(n) (0x39014 + (0x1000 * n)) +#define EDMA_REG_RXDESC_CTRL(n) (0x39018 + (0x1000 * n)) +#define EDMA_REG_RXDESC_BPC(n) (0x3901c + (0x1000 * n)) +#define EDMA_REG_RXDESC_INT_STAT(n) (0x49000 + (0x1000 * n)) +#define EDMA_REG_RXDESC_INT_MASK(n) (0x49004 + (0x1000 * n)) +#define EDMA_REG_RX_MOD_TIMER(n) (0x49008 + (0x1000 * n)) +#define EDMA_REG_RX_INT_CTRL(n) (0x4900c + (0x1000 * n)) +#define EDMA_QID2RID_TABLE_MEM(q) (0x5a000 + (0x4 * q)) +#define EDMA_REG_RXRING_PC(n) (0x5A200 + (0x10 * n)) +#define EDMA_REG_RXRING_BC_0(n) (0x5A204 + (0x10 * n)) +#define EDMA_REG_RXRING_BC_1(n) (0x5A208 + (0x10 * n)) +#define EDMA_REG_TXRING_PC(n) (0x74000 + (0x10 * n)) +#define EDMA_REG_TXRING_BC_0(n) (0x74004 + (0x10 * n)) +#define EDMA_REG_TXRING_BC_1(n) (0x74008 + (0x10 * n)) + +/* + * EDMA_REG_PORT_CTRL register + */ +#define EDMA_PORT_PAD_EN 0x1 +#define EDMA_PORT_EDMA_EN 0x2 + +/* + * EDMA_REG_TXQ_CTRL register + */ +#define EDMA_TXDESC_PF_THRE_MASK 0xf +#define EDMA_TXDESC_PF_THRE_SHIFT 0 +#define EDMA_TXCMPL_WB_THRE_MASK 0xf +#define EDMA_TXCMPL_WB_THRE_SHIFT 4 +#define EDMA_TXDESC_PKT_SRAM_THRE_MASK 0xff +#define EDMA_TXDESC_PKT_SRAM_THRE_SHIFT 8 +#define EDMA_TXCMPL_WB_TIMER_MASK 0xffff +#define EDMA_TXCMPL_WB_TIMER_SHIFT 16 + +/* + * EDMA_REG_RXQ_CTRL register + */ +#define EDMA_RXFILL_PF_THRE_MASK 0xf +#define EDMA_RXFILL_PF_THRE_SHIFT 0 +#define EDMA_RXDESC_WB_THRE_MASK 0xf +#define EDMA_RXDESC_WB_THRE_SHIFT 4 +#define EDMA_RXDESC_WB_TIMER_MASK 0xffff +#define EDMA_RXDESC_WB_TIMER_SHIFT 16 + +/* + * EDMA_REG_RX_TX_FULL_QID register + */ +#define EDMA_RX_DESC_FULL_QID_MASK 0xff +#define EDMA_RX_DESC_FULL_QID_SHIFT 0 +#define EDMA_TX_CMPL_BUF_FULL_QID_MASK 0xff +#define EDMA_TX_CMPL_BUF_FULL_QID_SHIFT 8 +#define EDMA_TX_SRAM_FULL_QID_MASK 0x1f +#define EDMA_TX_SRAM_FULL_QID_SHIFT 16 + +/* + * EDMA_REG_RXQ_FC_THRE reister + */ +#define EDMA_RXFILL_FIFO_XOFF_THRE_MASK 0x1f +#define EDMA_RXFILL_FIFO_XOFF_THRE_SHIFT 0 +#define EDMA_DESC_FIFO_XOFF_THRE_MASK 0x3f +#define EDMA_DESC_FIFO_XOFF_THRE_SHIFT 16 + +/* + * EDMA_REG_DMAR_CTRL register + */ +#define EDMA_DMAR_REQ_PRI_MASK 0x7 +#define EDMA_DMAR_REQ_PRI_SHIFT 0 +#define EDMA_DMAR_BURST_LEN_MASK 0x1 +#define EDMA_DMAR_BURST_LEN_SHIFT 3 +#define EDMA_DMAR_TXDATA_OUTSTANDING_NUM_MASK 0x1f +#define EDMA_DMAR_TXDATA_OUTSTANDING_NUM_SHIFT 4 +#define EDMA_DMAR_TXDESC_OUTSTANDING_NUM_MASK 0x7 +#define EDMA_DMAR_TXDESC_OUTSTANDING_NUM_SHIFT 9 +#define EDMA_DMAR_RXFILL_OUTSTANDING_NUM_MASK 0x7 +#define EDMA_DMAR_RXFILL_OUTSTANDING_NUM_SHIFT 12 + +#define EDMA_DMAR_REQ_PRI_SET(x) (((x) & EDMA_DMAR_REQ_PRI_MASK) << EDMA_DMAR_REQ_PRI_SHIFT) +#define EDMA_DMAR_TXDATA_OUTSTANDING_NUM_SET(x) (((x) & EDMA_DMAR_TXDATA_OUTSTANDING_NUM_MASK) << EDMA_DMAR_TXDATA_OUTSTANDING_NUM_SHIFT) +#define EDMA_DMAR_TXDESC_OUTSTANDING_NUM_SET(x) (((x) & EDMA_DMAR_TXDESC_OUTSTANDING_NUM_MASK) << EDMA_DMAR_TXDESC_OUTSTANDING_NUM_SHIFT) +#define EDMA_DMAR_RXFILL_OUTSTANDING_NUM_SET(x) (((x) & EDMA_DMAR_RXFILL_OUTSTANDING_NUM_MASK) << EDMA_DMAR_RXFILL_OUTSTANDING_NUM_SHIFT) +#define EDMA_DMAR_BURST_LEN_SET(x) (((x) & EDMA_DMAR_BURST_LEN_MASK) << EDMA_DMAR_BURST_LEN_SHIFT) + +/* + * Enable 128 byte EDMA burts for IPQ60xx + */ +#if defined(NSS_DP_IPQ60XX) +#define EDMA_BURST_LEN_ENABLE 1 +#else +#define EDMA_BURST_LEN_ENABLE 0 +#endif + +/* + * EDMA_REG_AXIW_CTRL_REG + */ +#define EDMA_AXIW_MAX_WR_SIZE_EN 0x400 + +/* + * EDMA DISABLE + */ +#define EDMA_DISABLE 0 + +/* + * EDMA_REG_TXDESC_PROD_IDX register + */ +#define EDMA_TXDESC_PROD_IDX_MASK 0xffff + +/* + * EDMA_REG_TXDESC_CONS_IDX register + */ +#define EDMA_TXDESC_CONS_IDX_MASK 0xffff + +/* + * EDMA_REG_TXDESC_RING_SIZE register + */ +#define EDMA_TXDESC_RING_SIZE_MASK 0xffff + +/* + * EDMA_REG_TXDESC_CTRL register + */ +#define EDMA_TXDESC_ARB_GRP_ID_MASK 0x3 +#define EDMA_TXDESC_ARB_GRP_ID_SHIFT 4 +#define EDMA_TXDESC_FC_GRP_ID_MASK 0x7 +#define EDMA_TXDESC_FC_GRP_ID_SHIFT 1 +#define EDMA_TXDESC_TX_EN 0x1 + +/* + * EDMA_REG_TXCMPL_PROD_IDX register + */ +#define EDMA_TXCMPL_PROD_IDX_MASK 0xffff + +/* + * EDMA_REG_TXCMPL_CONS_IDX register + */ +#define EDMA_TXCMPL_CONS_IDX_MASK 0xffff + +/* + * EDMA_REG_TXCMPL_RING_SIZE register + */ +#define EDMA_TXCMPL_RING_SIZE_MASK 0xffff + +/* + * EDMA_REG_TXCMPL_UGT_THRE register + */ +#define EDMA_TXCMPL_LOW_THRE_MASK 0xffff +#define EDMA_TXCMPL_LOW_THRE_SHIFT 0 +#define EDMA_TXCMPL_FC_THRE_MASK 0x3f +#define EDMA_TXCMPL_FC_THRE_SHIFT 16 + +/* + * EDMA_REG_TXCMPL_CTRL register + */ +#define EDMA_TXCMPL_RET_MODE_BUFF_ADDR 0x0 +#define EDMA_TXCMPL_RET_MODE_OPAQUE 0x1 + +/* + * EDMA_REG_TX_MOD_TIMER register + */ +#define EDMA_TX_MOD_TIMER_INIT_MASK 0xffff +#define EDMA_TX_MOD_TIMER_INIT_SHIFT 0 + +/* + * EDMA_REG_TX_INT_CTRL register + */ +#define EDMA_TX_INT_MASK 0x3 + +/* + * EDMA_REG_RXFILL_PROD_IDX register + */ +#define EDMA_RXFILL_PROD_IDX_MASK 0xffff + +/* + * EDMA_REG_RXFILL_CONS_IDX register + */ +#define EDMA_RXFILL_CONS_IDX_MASK 0xffff + +/* + * EDMA_REG_RXFILL_RING_SIZE register + */ +#define EDMA_RXFILL_RING_SIZE_MASK 0xffff +#define EDMA_RXFILL_BUF_SIZE_MASK 0x3fff +#define EDMA_RXFILL_BUF_SIZE_SHIFT 16 + +/* + * EDMA_REG_RXFILL_FC_THRE register + */ +#define EDMA_RXFILL_FC_XON_THRE_MASK 0x7ff +#define EDMA_RXFILL_FC_XON_THRE_SHIFT 12 +#define EDMA_RXFILL_FC_XOFF_THRE_MASK 0x7ff +#define EDMA_RXFILL_FC_XOFF_THRE_SHIFT 0 + +/* + * EDMA_REG_RXFILL_UGT_THRE register + */ +#define EDMA_RXFILL_LOW_THRE_MASK 0xffff +#define EDMA_RXFILL_LOW_THRE_SHIFT 0 + +/* + * EDMA_REG_RXFILL_RING_EN register + */ +#define EDMA_RXFILL_RING_EN 0x1 + +/* + * EDMA_REG_RXFILL_INT_MASK register + */ +#define EDMA_RXFILL_INT_MASK 0x1 + +/* + * EDMA_REG_RXDESC_PROD_IDX register + */ +#define EDMA_RXDESC_PROD_IDX_MASK 0xffff + +/* + * EDMA_REG_RXDESC_CONS_IDX register + */ +#define EDMA_RXDESC_CONS_IDX_MASK 0xffff + +/* + * EDMA_REG_RXDESC_RING_SIZE register + */ +#define EDMA_RXDESC_RING_SIZE_MASK 0xffff +#define EDMA_RXDESC_PL_OFFSET_MASK 0x1ff +#define EDMA_RXDESC_PL_OFFSET_SHIFT 16 + +/* + * EDMA_REG_RXDESC_FC_THRE register + */ +#define EDMA_RXDESC_FC_XON_THRE_MASK 0x7ff +#define EDMA_RXDESC_FC_XON_THRE_SHIFT 12 +#define EDMA_RXDESC_FC_XOFF_THRE_MASK 0x7ff +#define EDMA_RXDESC_FC_XOFF_THRE_SHIFT 0 + +/* + * EDMA_REG_RXDESC_UGT_THRE register + */ +#define EDMA_RXDESC_LOW_THRE_MASK 0xffff +#define EDMA_RXDESC_LOW_THRE_SHIFT 0 + +/* + * EDMA_REG_RXDESC_CTRL register + */ +#define EDMA_RXDESC_STAG_REMOVE_EN 0x8 +#define EDMA_RXDESC_CTAG_REMOVE_EN 0x4 +#define EDMA_RXDESC_QDISC_EN 0x2 +#define EDMA_RXDESC_RX_EN 0x1 + +/* + * EDMA_REG_TX_INT_MASK register + */ +#define EDMA_TX_INT_MASK_PKT_INT 0x1 +#define EDMA_TX_INT_MASK_UGT_INT 0x2 + +/* + * EDMA_REG_RXDESC_INT_STAT register + */ +#define EDMA_RXDESC_INT_STAT_PKT_INT 0x1 +#define EDMA_RXDESC_INT_STAT_UGT_INT 0x2 + +/* + * EDMA_REG_RXDESC_INT_MASK register + */ +#define EDMA_RXDESC_INT_MASK_PKT_INT 0x1 +#define EDMA_RXDESC_INT_MASK_TIMER_INT_DIS 0x2 + +#define EDMA_MASK_INT_DISABLE 0x0 +#define EDMA_MASK_INT_CLEAR 0x0 + +/* + * EDMA_REG_RX_MOD_TIMER register + */ +#define EDMA_RX_MOD_TIMER_INIT_MASK 0xffff +#define EDMA_RX_MOD_TIMER_INIT_SHIFT 0 + +/* + * EDMA QID2RID register sizes + */ +#define EDMA_QID2RID_DEPTH 0x40 +#define EDMA_QID2RID_QUEUES_PER_ENTRY 8 + +/* + * TXDESC shift values + */ +#define EDMA_TXDESC_MORE_SHIFT 31 +#define EDMA_TXDESC_TSO_EN_SHIFT 30 +#define EDMA_TXDESC_PREHEADER_SHIFT 29 +#define EDMA_TXDESC_POOL_ID_SHIFT 24 +#define EDMA_TXDESC_POOL_ID_MASK 0x1f +#define EDMA_TXDESC_DATA_OFFSET_SHIFT 16 +#define EDMA_TXDESC_DATA_OFFSET_MASK 0xff +#define EDMA_TXDESC_DATA_LENGTH_SHIFT 0 +#define EDMA_TXDESC_DATA_LENGTH_MASK 0xffff + +#define EDMA_PREHDR_DSTINFO_PORTID_IND 0x20 +#define EDMA_PREHDR_PORTNUM_BITS 0x0fff +#define EDMA_RING_DMA_MASK 0xffffffff +/* + * RXDESC shift values + */ +#define EDMA_RXDESC_RX_RXFILL_CNT_MASK 0x000f +#define EDMA_RXDESC_RX_RXFILL_CNT_SHIFT 16 + +#define EDMA_RXDESC_PKT_SIZE_MASK 0x3fff +#define EDMA_RXDESC_PKT_SIZE_SHIFT 0 + +#define EDMA_RXDESC_RXD_VALID_MASK 0x1 +#define EDMA_RXDESC_RXD_VALID_SHIFT 31 + +#define EDMA_RXDESC_PACKET_LEN_MASK 0x3fff +#define EDMA_RXDESC_RING_INT_STATUS_MASK 0x3 + +#define EDMA_RING_DISABLE 0 +#define EDMA_TXCMPL_RING_INT_STATUS_MASK 0x3 +#define EDMA_TXCMPL_RETMODE_OPAQUE 0x0 +#define EDMA_RXFILL_RING_INT_STATUS_MASK 0x1 + +/* + * TODO tune the timer and threshold values + */ +#define EDMA_RXFILL_FIFO_XOFF_THRE 0x3 +#define EDMA_RXFILL_PF_THRE 0x3 +#define EDMA_RXDESC_WB_THRE 0x0 +#define EDMA_RXDESC_WB_TIMER 0x2 + +#define EDMA_RXDESC_XON_THRE 50 +#define EDMA_RXDESC_XOFF_THRE 30 +#define EDMA_RXDESC_LOW_THRE 0 +#define EDMA_RX_MOD_TIMER_INIT 1000 + +#define EDMA_TXDESC_PF_THRE 0x3 +#define EDMA_TXCMPL_WB_THRE 0X0 +#define EDMA_TXDESC_PKT_SRAM_THRE 0x20 +#define EDMA_TXCMPL_WB_TIMER 0x2 + +#define EDMA_TX_MOD_TIMER 150 + +/* + * EDMA misc error mask + */ +#define EDMA_MISC_AXI_RD_ERR_MASK_EN 0x1 +#define EDMA_MISC_AXI_WR_ERR_MASK_EN 0x2 +#define EDMA_MISC_RX_DESC_FIFO_FULL_MASK_EN 0x4 +#define EDMA_MISC_RX_ERR_BUF_SIZE_MASK_EN 0x8 +#define EDMA_MISC_TX_SRAM_FULL_MASK_EN 0x10 +#define EDMA_MISC_TX_CMPL_BUF_FULL_MASK_EN 0x20 + +#if defined(NSS_DP_IPQ807X) +#define EDMA_MISC_PKT_LEN_LA_64K_MASK_EN 0x40 +#define EDMA_MISC_PKT_LEN_LE_40_MASK_EN 0x80 +#define EDMA_MISC_DATA_LEN_ERR_MASK_EN 0x100 +#else +#define EDMA_MISC_DATA_LEN_ERR_MASK_EN 0x40 +#define EDMA_MISC_TX_TIMEOUT_MASK_EN 0x80 +#endif + +#endif /* __EDMA_REGS__ */ diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/edma/edma_tx_rx.c b/feeds/ipq807x/qca-nss-dp/src/hal/edma/edma_tx_rx.c new file mode 100644 index 000000000..eeae567d1 --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/edma/edma_tx_rx.c @@ -0,0 +1,773 @@ +/* + * Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE + * USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include "nss_dp_dev.h" +#include "edma_regs.h" +#include "edma_data_plane.h" + +/* + * edma_alloc_rx_buffer() + * Alloc Rx buffers for one RxFill ring + */ +int edma_alloc_rx_buffer(struct edma_hw *ehw, + struct edma_rxfill_ring *rxfill_ring) +{ + struct platform_device *pdev = ehw->pdev; + struct sk_buff *skb; + uint16_t num_alloc = 0; + uint16_t cons, next, counter; + struct edma_rxfill_desc *rxfill_desc; + uint32_t reg_data = 0; + uint32_t store_index = 0; + struct edma_rx_preheader *rxph = NULL; + + /* + * Read RXFILL ring producer index + */ + reg_data = edma_reg_read(EDMA_REG_RXFILL_PROD_IDX(rxfill_ring->id)); + next = reg_data & EDMA_RXFILL_PROD_IDX_MASK & (rxfill_ring->count - 1); + + /* + * Read RXFILL ring consumer index + */ + reg_data = edma_reg_read(EDMA_REG_RXFILL_CONS_IDX(rxfill_ring->id)); + cons = reg_data & EDMA_RXFILL_CONS_IDX_MASK; + + while (1) { + counter = next; + if (++counter == rxfill_ring->count) + counter = 0; + + if (counter == cons) + break; + + /* + * Allocate buffer + */ + skb = dev_alloc_skb(EDMA_RX_BUFF_SIZE); + if (unlikely(!skb)) + break; + + /* + * Get RXFILL descriptor + */ + rxfill_desc = EDMA_RXFILL_DESC(rxfill_ring, next); + + /* + * Make room for Rx preheader + */ + rxph = (struct edma_rx_preheader *) + skb_push(skb, EDMA_RX_PREHDR_SIZE); + + /* + * Store the skb in the rx store + */ + store_index = next; + if (ehw->rx_skb_store[store_index] != NULL) { + dev_kfree_skb_any(skb); + break; + } + ehw->rx_skb_store[store_index] = skb; + memcpy((uint8_t *)&rxph->opaque, (uint8_t *)&store_index, 4); + /* + * Save buffer size in RXFILL descriptor + */ + rxfill_desc->word1 = cpu_to_le32(EDMA_RX_BUFF_SIZE + & EDMA_RXFILL_BUF_SIZE_MASK); + + /* + * Map Rx buffer for DMA + */ + rxfill_desc->buffer_addr = cpu_to_le32(dma_map_single( + &pdev->dev, + skb->data, + EDMA_RX_BUFF_SIZE, + DMA_FROM_DEVICE)); + + if (!rxfill_desc->buffer_addr) { + dev_kfree_skb_any(skb); + ehw->rx_skb_store[store_index] = NULL; + break; + } + + num_alloc++; + next = counter; + } + + if (num_alloc) { + /* + * Update RXFILL ring producer index + */ + reg_data = next & EDMA_RXFILL_PROD_IDX_MASK; + + /* + * make sure the producer index updated before + * updating the hardware + */ + wmb(); + + edma_reg_write(EDMA_REG_RXFILL_PROD_IDX(rxfill_ring->id), + reg_data); + } + + return num_alloc; +} + +/* + * edma_clean_tx() + * Reap Tx descriptors + */ +uint32_t edma_clean_tx(struct edma_hw *ehw, + struct edma_txcmpl_ring *txcmpl_ring) +{ + struct platform_device *pdev = ehw->pdev; + struct edma_txcmpl_desc *txcmpl = NULL; + uint16_t prod_idx = 0; + uint16_t cons_idx = 0; + uint32_t data = 0; + uint32_t txcmpl_consumed = 0; + struct sk_buff *skb; + uint32_t len; + int store_index; + dma_addr_t daddr; + + /* + * Get TXCMPL ring producer index + */ + data = edma_reg_read(EDMA_REG_TXCMPL_PROD_IDX(txcmpl_ring->id)); + prod_idx = data & EDMA_TXCMPL_PROD_IDX_MASK; + + /* + * Get TXCMPL ring consumer index + */ + data = edma_reg_read(EDMA_REG_TXCMPL_CONS_IDX(txcmpl_ring->id)); + cons_idx = data & EDMA_TXCMPL_CONS_IDX_MASK; + + while (cons_idx != prod_idx) { + txcmpl = &(((struct edma_txcmpl_desc *) + (txcmpl_ring->desc))[cons_idx]); + + /* + * skb for this is stored in tx store and + * tx header contains the index in the field + * buffer address (opaque) of txcmpl + */ + store_index = txcmpl->buffer_addr; + skb = ehw->tx_skb_store[store_index]; + ehw->tx_skb_store[store_index] = NULL; + + if (unlikely(!skb)) { + pr_warn("Invalid skb: cons_idx:%u prod_idx:%u status %x\n", + cons_idx, prod_idx, txcmpl->status); + goto next_txcmpl_desc; + } + + len = skb_headlen(skb); + daddr = (dma_addr_t)virt_to_phys(skb->data); + + pr_debug("skb:%px cons_idx:%d prod_idx:%d word1:0x%x\n", + skb, cons_idx, prod_idx, txcmpl->status); + + dma_unmap_single(&pdev->dev, daddr, + len, DMA_TO_DEVICE); + dev_kfree_skb_any(skb); + +next_txcmpl_desc: + if (++cons_idx == txcmpl_ring->count) + cons_idx = 0; + + txcmpl_consumed++; + } + + if (txcmpl_consumed == 0) + return 0; + + pr_debug("TXCMPL:%u txcmpl_consumed:%u prod_idx:%u cons_idx:%u\n", + txcmpl_ring->id, txcmpl_consumed, prod_idx, cons_idx); + + /* + * Update TXCMPL ring consumer index + */ + wmb(); + edma_reg_write(EDMA_REG_TXCMPL_CONS_IDX(txcmpl_ring->id), cons_idx); + + return txcmpl_consumed; +} + +/* + * nss_phy_tstamp_rx_buf() + * Receive timestamp packet + */ +void nss_phy_tstamp_rx_buf(__attribute__((unused))void *app_data, struct sk_buff *skb) +{ + struct net_device *ndev = skb->dev; + + /* + * The PTP_CLASS_ value 0 is passed to phy driver, which will be + * set to the correct PTP class value by calling ptp_classify_raw + * in drv->rxtstamp function. + */ + if (ndev && ndev->phydev && ndev->phydev->drv && + ndev->phydev->drv->rxtstamp) + if(ndev->phydev->drv->rxtstamp(ndev->phydev, skb, 0)) + return; + + netif_receive_skb(skb); +} +EXPORT_SYMBOL(nss_phy_tstamp_rx_buf); + +/* + * nss_phy_tstamp_tx_buf() + * Transmit timestamp packet + */ +void nss_phy_tstamp_tx_buf(struct net_device *ndev, struct sk_buff *skb) +{ + /* + * Function drv->txtstamp will create a clone of skb if necessary, + * the PTP_CLASS_ value 0 is passed to phy driver, which will be + * set to the correct PTP class value by calling ptp_classify_raw + * in the drv->txtstamp function. + */ + if (ndev && ndev->phydev && ndev->phydev->drv && + ndev->phydev->drv->txtstamp) + ndev->phydev->drv->txtstamp(ndev->phydev, skb, 0); +} +EXPORT_SYMBOL(nss_phy_tstamp_tx_buf); + +/* + * edma_clean_rx() + * Reap Rx descriptors + */ +static uint32_t edma_clean_rx(struct edma_hw *ehw, + int work_to_do, + struct edma_rxdesc_ring *rxdesc_ring) +{ + struct platform_device *pdev = ehw->pdev; + struct net_device *ndev; + struct sk_buff *skb = NULL; + struct edma_rxdesc_desc *rxdesc_desc; + struct edma_rx_preheader *rxph = NULL; + uint16_t prod_idx = 0; + int src_port_num = 0; + int pkt_length = 0; + uint16_t cons_idx = 0; + uint32_t work_done = 0; + int store_index; + + /* + * Read Rx ring consumer index + */ + cons_idx = edma_reg_read(EDMA_REG_RXDESC_CONS_IDX(rxdesc_ring->id)) + & EDMA_RXDESC_CONS_IDX_MASK; + + while (1) { + /* + * Read Rx ring producer index + */ + prod_idx = edma_reg_read( + EDMA_REG_RXDESC_PROD_IDX(rxdesc_ring->id)) + & EDMA_RXDESC_PROD_IDX_MASK; + + if (cons_idx == prod_idx) + break; + + if (work_done >= work_to_do) + break; + + rxdesc_desc = EDMA_RXDESC_DESC(rxdesc_ring, cons_idx); + + /* + * Get Rx preheader + */ + rxph = (struct edma_rx_preheader *) + phys_to_virt(rxdesc_desc->buffer_addr); + + /* + * DMA unmap Rx buffer + */ + dma_unmap_single(&pdev->dev, + rxdesc_desc->buffer_addr, + EDMA_RX_BUFF_SIZE, + DMA_FROM_DEVICE); + + store_index = rxph->opaque; + skb = ehw->rx_skb_store[store_index]; + ehw->rx_skb_store[store_index] = NULL; + if (unlikely(!skb)) { + pr_warn("WARN: empty skb reference in rx_store:%d\n", + cons_idx); + goto next_rx_desc; + } + + /* + * Check src_info from Rx preheader + */ + if (EDMA_RXPH_SRC_INFO_TYPE_GET(rxph) == + EDMA_PREHDR_DSTINFO_PORTID_IND) { + src_port_num = rxph->src_info & + EDMA_PREHDR_PORTNUM_BITS; + } else { + pr_warn("WARN: src_info_type:0x%x. Drop skb:%px\n", + EDMA_RXPH_SRC_INFO_TYPE_GET(rxph), skb); + dev_kfree_skb_any(skb); + goto next_rx_desc; + } + + /* + * Get packet length + */ + pkt_length = rxdesc_desc->status & EDMA_RXDESC_PACKET_LEN_MASK; + + if (unlikely((src_port_num < NSS_DP_START_IFNUM) || + (src_port_num > NSS_DP_HAL_MAX_PORTS))) { + pr_warn("WARN: Port number error :%d. Drop skb:%px\n", + src_port_num, skb); + dev_kfree_skb_any(skb); + goto next_rx_desc; + } + + /* + * Get netdev for this port using the source port + * number as index into the netdev array. We need to + * subtract one since the indices start form '0' and + * port numbers start from '1'. + */ + ndev = ehw->netdev_arr[src_port_num - 1]; + if (unlikely(!ndev)) { + pr_warn("WARN: netdev Null src_info_type:0x%x. Drop skb:%px\n", + src_port_num, skb); + dev_kfree_skb_any(skb); + goto next_rx_desc; + } + + if (unlikely(!netif_running(ndev))) { + dev_kfree_skb_any(skb); + goto next_rx_desc; + } + + /* + * Remove Rx preheader + */ + skb_pull(skb, EDMA_RX_PREHDR_SIZE); + + /* + * Update skb fields and indicate packet to stack + */ + skb->dev = ndev; + skb->skb_iif = ndev->ifindex; + skb_put(skb, pkt_length); + skb->protocol = eth_type_trans(skb, skb->dev); +#ifdef CONFIG_NET_SWITCHDEV +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) + skb->offload_fwd_mark = ndev->offload_fwd_mark; +#else + /* + * TODO: Implement ndo_get_devlink_port() + */ + skb->offload_fwd_mark = 0; +#endif + pr_debug("skb:%px ring_idx:%u pktlen:%d proto:0x%x mark:%u\n", + skb, cons_idx, pkt_length, skb->protocol, + skb->offload_fwd_mark); +#else + pr_debug("skb:%px ring_idx:%u pktlen:%d proto:0x%x\n", + skb, cons_idx, pkt_length, skb->protocol); +#endif + /* + * Deliver the ptp packet to phy driver for RX timestamping + */ + if (unlikely(EDMA_RXPH_SERVICE_CODE_GET(rxph) == + NSS_PTP_EVENT_SERVICE_CODE)) + nss_phy_tstamp_rx_buf(ndev, skb); + else + netif_receive_skb(skb); + +next_rx_desc: + /* + * Update consumer index + */ + if (++cons_idx == rxdesc_ring->count) + cons_idx = 0; + + /* + * Update work done + */ + work_done++; + } + + edma_alloc_rx_buffer(ehw, rxdesc_ring->rxfill); + + /* + * make sure the consumer index is updated + * before updating the hardware + */ + wmb(); + edma_reg_write(EDMA_REG_RXDESC_CONS_IDX(rxdesc_ring->id), cons_idx); + return work_done; +} + +/* + * edma_napi() + * EDMA NAPI handler + */ +int edma_napi(struct napi_struct *napi, int budget) +{ + struct edma_hw *ehw = container_of(napi, struct edma_hw, napi); + struct edma_txcmpl_ring *txcmpl_ring = NULL; + struct edma_rxdesc_ring *rxdesc_ring = NULL; + struct edma_rxfill_ring *rxfill_ring = NULL; + + struct net_device *ndev; + int work_done = 0; + int i; + + for (i = 0; i < ehw->rxdesc_rings; i++) { + rxdesc_ring = &ehw->rxdesc_ring[i]; + work_done += edma_clean_rx(ehw, budget, rxdesc_ring); + } + + for (i = 0; i < ehw->txcmpl_rings; i++) { + txcmpl_ring = &ehw->txcmpl_ring[i]; + work_done += edma_clean_tx(ehw, txcmpl_ring); + } + + for (i = 0; i < ehw->rxfill_rings; i++) { + rxfill_ring = &ehw->rxfill_ring[i]; + work_done += edma_alloc_rx_buffer(ehw, rxfill_ring); + } + + /* + * Resume netdev Tx queue + */ + /* + * TODO works currently since we have a single queue. + * Need to make sure we have support in place when there is + * support for multiple queues + */ + for (i = 0; i < EDMA_MAX_GMACS; i++) { + ndev = ehw->netdev_arr[i]; + if (!ndev) + continue; + + if (netif_queue_stopped(ndev) && netif_carrier_ok(ndev)) + netif_start_queue(ndev); + } + + /* + * TODO - rework and fix the budget control + */ + if (work_done < budget) { + /* + * TODO per core NAPI + */ + napi_complete(napi); + + /* + * Set RXDESC ring interrupt mask + */ + for (i = 0; i < ehw->rxdesc_rings; i++) { + rxdesc_ring = &ehw->rxdesc_ring[i]; + edma_reg_write( + EDMA_REG_RXDESC_INT_MASK(rxdesc_ring->id), + ehw->rxdesc_intr_mask); + } + + /* + * Set TXCMPL ring interrupt mask + */ + for (i = 0; i < ehw->txcmpl_rings; i++) { + txcmpl_ring = &ehw->txcmpl_ring[i]; + edma_reg_write(EDMA_REG_TX_INT_MASK(txcmpl_ring->id), + ehw->txcmpl_intr_mask); + } + + /* + * Set RXFILL ring interrupt mask + */ + for (i = 0; i < ehw->rxfill_rings; i++) { + rxfill_ring = &ehw->rxfill_ring[i]; + edma_reg_write(EDMA_REG_RXFILL_INT_MASK( + rxfill_ring->id), + edma_hw.rxfill_intr_mask); + } + } + return work_done; +} + +/* + * edma_ring_xmit() + * Transmit a packet using an EDMA ring + */ +enum edma_tx edma_ring_xmit(struct edma_hw *ehw, + struct net_device *netdev, + struct sk_buff *skb, + struct edma_txdesc_ring *txdesc_ring) +{ + struct nss_dp_dev *dp_dev = netdev_priv(netdev); + struct edma_txdesc_desc *txdesc = NULL; + uint16_t buf_len = skb_headlen(skb); + uint16_t hw_next_to_use, hw_next_to_clean, chk_idx; + uint32_t data; + uint32_t store_index = 0; + struct edma_tx_preheader *txph = NULL; + + /* + * TODO - revisit locking + */ + spin_lock_bh(&txdesc_ring->tx_lock); + + /* + * Read TXDESC ring producer index + */ + data = edma_reg_read(EDMA_REG_TXDESC_PROD_IDX(txdesc_ring->id)); + hw_next_to_use = data & EDMA_TXDESC_PROD_IDX_MASK; + + /* + * Read TXDESC ring consumer index + */ + /* + * TODO - read to local variable to optimize uncached access + */ + data = edma_reg_read(EDMA_REG_TXDESC_CONS_IDX(txdesc_ring->id)); + hw_next_to_clean = data & EDMA_TXDESC_CONS_IDX_MASK; + + /* + * Check for available Tx descriptor + */ + chk_idx = (hw_next_to_use + 1) & (txdesc_ring->count-1); + + if (chk_idx == hw_next_to_clean) { + spin_unlock_bh(&txdesc_ring->tx_lock); + return EDMA_TX_DESC; + } + + /* + * Deliver the ptp packet to phy driver for TX timestamping + */ + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) + nss_phy_tstamp_tx_buf(netdev, skb); + + /* + * Make room for Tx preheader + */ + txph = (struct edma_tx_preheader *)skb_push(skb, + EDMA_TX_PREHDR_SIZE); + memset((void *)txph, 0, EDMA_TX_PREHDR_SIZE); + + /* + * Populate Tx preheader dst info, port id is macid in dp_dev + */ + txph->dst_info = (EDMA_PREHDR_DSTINFO_PORTID_IND << 8) | + (dp_dev->macid & 0x0fff); + + /* + * Store the skb in tx_store + */ + store_index = hw_next_to_use & (txdesc_ring->count - 1); + if (unlikely(ehw->tx_skb_store[store_index] != NULL)) { + spin_unlock_bh(&txdesc_ring->tx_lock); + return EDMA_TX_DESC; + } + + ehw->tx_skb_store[store_index] = skb; + memcpy(skb->data, &store_index, 4); + + /* + * Get Tx descriptor + */ + txdesc = EDMA_TXDESC_DESC(txdesc_ring, hw_next_to_use); + memset(txdesc, 0, sizeof(struct edma_txdesc_desc)); + + /* + * Map buffer to DMA address + */ + txdesc->buffer_addr = cpu_to_le32(dma_map_single(&(ehw->pdev)->dev, + skb->data, + buf_len + EDMA_TX_PREHDR_SIZE, + DMA_TO_DEVICE)); + if (!txdesc->buffer_addr) { + /* + * DMA map failed for this address. Drop it + * and make sure does not got to stack again + */ + dev_kfree_skb_any(skb); + + ehw->tx_skb_store[store_index] = NULL; + spin_unlock_bh(&txdesc_ring->tx_lock); + return EDMA_TX_OK; + } + + /* + * Populate Tx descriptor + */ + txdesc->word1 |= (1 << EDMA_TXDESC_PREHEADER_SHIFT) + | ((EDMA_TX_PREHDR_SIZE & EDMA_TXDESC_DATA_OFFSET_MASK) + << EDMA_TXDESC_DATA_OFFSET_SHIFT); + txdesc->word1 |= ((buf_len & EDMA_TXDESC_DATA_LENGTH_MASK) + << EDMA_TXDESC_DATA_LENGTH_SHIFT); + + netdev_dbg(netdev, "skb:%px tx_ring:%u proto:0x%x\n", + skb, txdesc_ring->id, ntohs(skb->protocol)); + netdev_dbg(netdev, "port:%u prod_idx:%u cons_idx:%u\n", + dp_dev->macid, hw_next_to_use, hw_next_to_clean); + + /* + * Update producer index + */ + hw_next_to_use = (hw_next_to_use + 1) & (txdesc_ring->count - 1); + + /* + * make sure the hw_next_to_use is updated before the + * write to hardware + */ + wmb(); + + edma_reg_write(EDMA_REG_TXDESC_PROD_IDX(txdesc_ring->id), + hw_next_to_use & EDMA_TXDESC_PROD_IDX_MASK); + spin_unlock_bh(&txdesc_ring->tx_lock); + return EDMA_TX_OK; +} + +/* + * edma_handle_misc_irq() + * Process IRQ + */ +irqreturn_t edma_handle_misc_irq(int irq, void *ctx) +{ + uint32_t misc_intr_status = 0; + uint32_t reg_data = 0; + struct edma_hw *ehw = NULL; + struct platform_device *pdev = (struct platform_device *)ctx; + + ehw = platform_get_drvdata(pdev); + + /* + * Read Misc intr status + */ + reg_data = edma_reg_read(EDMA_REG_MISC_INT_STAT); + misc_intr_status = reg_data & ehw->misc_intr_mask; + + /* + * TODO - error logging + */ + if (misc_intr_status == 0) + return IRQ_NONE; + else + edma_reg_write(EDMA_REG_MISC_INT_MASK, EDMA_MASK_INT_DISABLE); + + return IRQ_HANDLED; +} + +/* + * edma_handle_irq() + * Process IRQ and schedule napi + */ +irqreturn_t edma_handle_irq(int irq, void *ctx) +{ + uint32_t reg_data = 0; + uint32_t rxdesc_intr_status = 0; + uint32_t txcmpl_intr_status = 0; + uint32_t rxfill_intr_status = 0; + int i; + struct edma_txcmpl_ring *txcmpl_ring = NULL; + struct edma_rxdesc_ring *rxdesc_ring = NULL; + struct edma_rxfill_ring *rxfill_ring = NULL; + struct edma_hw *ehw = NULL; + struct platform_device *pdev = (struct platform_device *)ctx; + + ehw = platform_get_drvdata(pdev); + if (!ehw) { + pr_info("Unable to retrieve platrofm data"); + return IRQ_HANDLED; + } + + /* + * Read RxDesc intr status + */ + for (i = 0; i < ehw->rxdesc_rings; i++) { + rxdesc_ring = &ehw->rxdesc_ring[i]; + reg_data = edma_reg_read( + EDMA_REG_RXDESC_INT_STAT(rxdesc_ring->id)); + rxdesc_intr_status |= reg_data & + EDMA_RXDESC_RING_INT_STATUS_MASK; + + /* + * Disable RxDesc intr + */ + edma_reg_write(EDMA_REG_RXDESC_INT_MASK(rxdesc_ring->id), + EDMA_MASK_INT_DISABLE); + } + + /* + * Read TxCmpl intr status + */ + for (i = 0; i < ehw->txcmpl_rings; i++) { + txcmpl_ring = &ehw->txcmpl_ring[i]; + reg_data = edma_reg_read( + EDMA_REG_TX_INT_STAT(txcmpl_ring->id)); + txcmpl_intr_status |= reg_data & + EDMA_TXCMPL_RING_INT_STATUS_MASK; + + /* + * Disable TxCmpl intr + */ + edma_reg_write(EDMA_REG_TX_INT_MASK(txcmpl_ring->id), + EDMA_MASK_INT_DISABLE); + } + + /* + * Read RxFill intr status + */ + for (i = 0; i < ehw->rxfill_rings; i++) { + rxfill_ring = &ehw->rxfill_ring[i]; + reg_data = edma_reg_read( + EDMA_REG_RXFILL_INT_STAT(rxfill_ring->id)); + rxfill_intr_status |= reg_data & + EDMA_RXFILL_RING_INT_STATUS_MASK; + + /* + * Disable RxFill intr + */ + edma_reg_write(EDMA_REG_RXFILL_INT_MASK(rxfill_ring->id), + EDMA_MASK_INT_DISABLE); + + } + + if ((rxdesc_intr_status == 0) && (txcmpl_intr_status == 0) && + (rxfill_intr_status == 0)) + return IRQ_NONE; + + for (i = 0; i < ehw->rxdesc_rings; i++) { + rxdesc_ring = &ehw->rxdesc_ring[i]; + edma_reg_write(EDMA_REG_RXDESC_INT_MASK(rxdesc_ring->id), + EDMA_MASK_INT_DISABLE); + } + + /* + *TODO - per core NAPI + */ + if (rxdesc_intr_status || txcmpl_intr_status || rxfill_intr_status) + if (likely(napi_schedule_prep(&ehw->napi))) + __napi_schedule(&ehw->napi); + + return IRQ_HANDLED; +} diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/qcom/qcom_dev.h b/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/qcom/qcom_dev.h new file mode 100644 index 000000000..79da08661 --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/qcom/qcom_dev.h @@ -0,0 +1,697 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2017,2020 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF0 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __QCOM_DEV_H__ +#define __QCOM_DEV_H__ + +#include +#include "qcom_reg.h" +#include +#include + +/* + * Subclass for base nss_gmac_haldev + */ +struct qcom_hal_dev { + struct nss_gmac_hal_dev nghd; /* Base class */ + fal_mib_counter_t stats; /* Stats structure */ +}; +/* + * qcom_set_rx_flow_ctrl() + */ +static inline void qcom_set_rx_flow_ctrl(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_ENABLE, QCOM_RX_FLOW_ENABLE); +} + +/* + * qcom_clear_rx_flow_ctrl() + */ +static inline void qcom_clear_rx_flow_ctrl(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_ENABLE, QCOM_RX_FLOW_ENABLE); +} + +/* + * qcom_set_tx_flow_ctrl() + */ +static inline void qcom_set_tx_flow_ctrl(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_ENABLE, QCOM_TX_FLOW_ENABLE); +} + +/* + * qcom_clear_tx_flow_ctrl() + */ +static inline void qcom_clear_tx_flow_ctrl(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_ENABLE, QCOM_TX_FLOW_ENABLE); +} + +/* + * qcom_clear_mac_ctrl0() + */ +static inline void qcom_clear_mac_ctrl0(struct nss_gmac_hal_dev *nghd) +{ + hal_write_reg(nghd->mac_base, QCOM_MAC_CTRL0, 0); +} + +/* + * qcom_rx_enable() + */ +static inline void qcom_rx_enable(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_ENABLE, QCOM_RX_MAC_ENABLE); +} + +/* + * qcom_rx_disable() + * Disable the reception of frames on GMII/MII. + * GMAC receive state machine is disabled after completion of reception of + * current frame. + */ +static inline void qcom_rx_disable(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_ENABLE, QCOM_RX_MAC_ENABLE); +} + +/* + * qcom_tx_enable() + */ +static inline void qcom_tx_enable(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_ENABLE, QCOM_TX_MAC_ENABLE); +} + +/* + * qcom_tx_disable() + * Disable the transmission of frames on GMII/MII. + * GMAC transmit state machine is disabled after completion of + * transmission of current frame. + */ +static inline void qcom_tx_disable(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_ENABLE, QCOM_TX_MAC_ENABLE); +} + +/* + * qcom_set_full_duplex() + */ +static inline void qcom_set_full_duplex(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_ENABLE, QCOM_DUPLEX); +} + +/* + * qcom_set_half_duplex() + */ +static inline void qcom_set_half_duplex(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_ENABLE, QCOM_DUPLEX); +} + +/* + * qcom_set_ipgt() + */ +static inline void qcom_set_ipgt(struct nss_gmac_hal_dev *nghd, uint32_t ipgt) +{ + uint32_t data; + + data = hal_read_reg(nghd->mac_base, QCOM_MAC_CTRL0); + data &= ~QCOM_IPGT_POS; + ipgt = ipgt << QCOM_IPGT_LSB; + data |= ipgt; + hal_write_reg(nghd->mac_base, QCOM_MAC_CTRL0, data); +} + +/* + * qcom_set_ipgr() + */ +static inline void qcom_set_ipgr(struct nss_gmac_hal_dev *nghd, uint32_t ipgr) +{ + uint32_t data; + + data = hal_read_reg(nghd->mac_base, QCOM_MAC_CTRL0); + data &= ~QCOM_IPGR2_POS; + ipgr = ipgr << QCOM_IPGR2_LSB; + data |= ipgr; + hal_write_reg(nghd->mac_base, QCOM_MAC_CTRL0, data); +} + +/* + * qcom_set_half_thdf_ctrl() + */ +static inline void qcom_set_half_thdf_ctrl(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_CTRL0, QCOM_HALF_THDF_CTRL); +} + +/* + * qcom_reset_half_thdf_ctrl() + */ +static inline void qcom_reset_half_thdf_ctrl(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_CTRL0, QCOM_HALF_THDF_CTRL); +} + +/* + * qcom_set_frame_len_chk() + */ +static inline void qcom_set_frame_len_chk(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_CTRL0, QCOM_FLCHK); +} + +/* + * qcom_reset_frame_len_chk() + */ +static inline void qcom_reset_frame_len_chk(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_CTRL0, QCOM_FLCHK); +} + +/* + * qcom_set_abebe() + */ +static inline void qcom_set_abebe(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_CTRL0, QCOM_ABEBE); +} + +/* + * qcom_reset_abebe() + */ +static inline void qcom_reset_abebe(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_CTRL0, QCOM_ABEBE); +} + +/* + * qcom_set_amaxe() + */ +static inline void qcom_set_amaxe(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_CTRL0, QCOM_AMAXE); +} + +/* + * qcom_reset_amaxe() + */ +static inline void qcom_reset_amaxe(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_CTRL0, QCOM_AMAXE); +} + +/* + * qcom_set_bpnb() + */ +static inline void qcom_set_bpnb(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_CTRL0, QCOM_BPNB); +} + +/* + * qcom_reset_bpnb() + */ +static inline void qcom_reset_bpnb(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_CTRL0, QCOM_BPNB); +} + +/* + * qcom_set_nobo() + */ +static inline void qcom_set_nobo(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_CTRL0, QCOM_NOBO); +} + +/* + * qcom_reset_nobo() + */ +static inline void qcom_reset_nobo(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_CTRL0, QCOM_NOBO); +} + +/* + * qcom_set_drbnib_rxok() + */ +static inline void qcom_set_drbnib_rxok(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_CTRL0, QCOM_DRBNIB_RXOK); +} + +/* + * qcom_reset_drbnib_rxok() + */ +static inline void qcom_reset_drbnib_rxok(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_CTRL0, QCOM_DRBNIB_RXOK); +} + +/* + * qcom_set_jam_ipg() + */ +static inline void qcom_set_jam_ipg(struct nss_gmac_hal_dev *nghd, + uint32_t jam_ipg) +{ + uint32_t data; + + data = hal_read_reg(nghd->mac_base, QCOM_MAC_CTRL1); + data &= ~QCOM_JAM_IPG_POS; + jam_ipg = jam_ipg << QCOM_JAM_IPG_LSB; + data |= jam_ipg; + hal_write_reg(nghd->mac_base, QCOM_MAC_CTRL1, data); +} + +/* + * qcom_set_ctrl1_test_pause() + */ +static inline void qcom_set_ctrl1_test_pause(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_CTRL1, QCOM_TPAUSE); +} + +/* + * qcom_reset_ctrl1_test_pause() + */ +static inline void qcom_reset_ctrl1_test_pause(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_CTRL1, QCOM_TPAUSE); +} + +/* + * qcom_reset_ctrl1_test_pause() + */ +static inline void qcom_set_tctl(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_CTRL1, QCOM_TCTL); +} + +/* + * qcom_reset_tctl() + */ +static inline void qcom_reset_tctl(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_CTRL1, QCOM_TCTL); +} + +/* + * qcom_set_sstct() + */ +static inline void qcom_set_sstct(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_CTRL1, QCOM_SSTCT); +} + +/* + * qcom_reset_sstct() + */ +static inline void qcom_reset_sstct(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_CTRL1, QCOM_SSTCT); +} + +/* + * qcom_set_simr() + */ +static inline void qcom_set_simr(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_CTRL1, QCOM_SIMR); +} + +/* + * qcom_reset_simr() + */ +static inline void qcom_reset_simr(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_CTRL1, QCOM_SIMR); +} + +/* + * qcom_set_retry() + */ +static inline void qcom_set_retry(struct nss_gmac_hal_dev *nghd, uint32_t retry) +{ + uint32_t data; + + data = hal_read_reg(nghd->mac_base, QCOM_MAC_CTRL1); + data &= ~QCOM_RETRY_POS; + retry = retry << QCOM_RETRY_LSB; + data |= retry; + hal_write_reg(nghd->mac_base, QCOM_MAC_CTRL1, data); +} + +/* + * qcom_set_prlen() + */ +static inline void qcom_set_prlen(struct nss_gmac_hal_dev *nghd, uint32_t prlen) +{ + uint32_t data; + + data = hal_read_reg(nghd->mac_base, QCOM_MAC_CTRL1); + data &= ~QCOM_PRLEN_POS; + prlen = prlen << QCOM_PRLEN_LSB; + data |= prlen; + hal_write_reg(nghd->mac_base, QCOM_MAC_CTRL1, data); +} + +/* + * qcom_set_ppad() + */ +static inline void qcom_set_ppad(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_CTRL1, QCOM_PPAD); +} + +/* + * qcom_reset_ppad() + */ +static inline void qcom_reset_ppad(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_CTRL1, QCOM_PPAD); +} + +/* + * qcom_set_povr() + */ +static inline void qcom_set_povr(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_CTRL1, QCOM_POVR); +} + +/* + * qcom_reset_povr() + */ +static inline void qcom_reset_povr(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_CTRL1, QCOM_POVR); +} + +/* + * qcom_set_phug() + */ +static inline void qcom_set_phug(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_CTRL1, QCOM_PHUG); +} + +/* + * qcom_reset_phug() + */ +static inline void qcom_reset_phug(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_CTRL1, QCOM_PHUG); +} + +/* + * qcom_set_mbof() + */ +static inline void qcom_set_mbof(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_CTRL1, QCOM_MBOF); +} + +/* + * qcom_reset_mbof() + */ +static inline void qcom_reset_mbof(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_CTRL1, QCOM_MBOF); +} + +/* + * qcom_set_lcol() + */ +static inline void qcom_set_lcol(struct nss_gmac_hal_dev *nghd, uint32_t lcol) +{ + uint32_t data; + + data = hal_read_reg(nghd->mac_base, QCOM_MAC_CTRL1); + data &= ~QCOM_LCOL_POS; + lcol = lcol << QCOM_LCOL_LSB; + data |= lcol; + hal_write_reg(nghd->mac_base, QCOM_MAC_CTRL1, data); +} + +/* + * qcom_set_long_jam() + */ +static inline void qcom_set_long_jam(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_CTRL1, QCOM_LONG_JAM); +} + +/* + * qcom_reset_long_jam() + */ +static inline void qcom_reset_long_jam(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_CTRL1, QCOM_LONG_JAM); +} + +/* + * qcom_set_ipg_dec_len() + */ +static inline void qcom_set_ipg_dec_len(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_CTRL2, QCOM_IPG_DEC_LEN); +} + +/* + * qcom_reset_ipg_dec_len() + */ +static inline void qcom_reset_ipg_dec_len(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_CTRL2, QCOM_IPG_DEC_LEN); +} + +/* + * qcom_set_ctrl2_test_pause() + */ +static inline void qcom_set_ctrl2_test_pause(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_CTRL2, QCOM_TEST_PAUSE); +} + +/* + * qcom_reset_ctrl2_test_pause() + */ +static inline void qcom_reset_ctrl2_test_pause(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_CTRL2, QCOM_TEST_PAUSE); +} + +/* + * qcom_set_mac_loopback() + */ +static inline void qcom_set_mac_loopback(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_CTRL2, QCOM_MAC_LOOPBACK); +} + +/* + * qcom_reset_mac_loopback() + */ +static inline void qcom_reset_mac_loopback(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_CTRL2, QCOM_MAC_LOOPBACK); +} + +/* + * qcom_set_ipg_dec() + */ +static inline void qcom_set_ipg_dec(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_CTRL2, QCOM_IPG_DEC); +} + +/* + * qcom_reset_ipg_dec() + */ +static inline void qcom_reset_ipg_dec(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_CTRL2, QCOM_IPG_DEC); +} + +/* + * qcom_set_crs_sel() + */ +static inline void qcom_set_crs_sel(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_CTRL2, QCOM_SRS_SEL); +} + +/* + * qcom_reset_crs_sel() + */ +static inline void qcom_reset_crs_sel(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_CTRL2, QCOM_SRS_SEL); +} + +/* + * qcom_set_crc_rsv() + */ +static inline void qcom_set_crc_rsv(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_CTRL2, QCOM_CRC_RSV); +} + +/* + * qcom_reset_crc_rsv() + */ +static inline void qcom_reset_crc_rsv(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_CTRL2, QCOM_CRC_RSV); +} + +/* + * qcom_set_ipgr1() + */ +static inline void qcom_set_ipgr1(struct nss_gmac_hal_dev *nghd, uint32_t ipgr1) +{ + uint32_t data; + + data = hal_read_reg(nghd->mac_base, QCOM_MAC_DBG_CTRL); + data &= ~QCOM_DBG_IPGR1_POS; + ipgr1 = ipgr1 << QCOM_DBG_IPGR1_LSB; + data |= ipgr1; + hal_write_reg(nghd->mac_base, QCOM_MAC_DBG_CTRL, data); +} + +/* + * qcom_set_hihg_ipg() + */ +static inline void qcom_set_hihg_ipg(struct nss_gmac_hal_dev *nghd, + uint32_t hihg_ipg) +{ + uint32_t data; + + data = hal_read_reg(nghd->mac_base, QCOM_MAC_DBG_CTRL); + data &= ~QCOM_DBG_HIHG_IPG_POS; + data |= hihg_ipg << QCOM_DBG_HIHG_IPG_LSB; + hal_write_reg(nghd->mac_base, QCOM_MAC_DBG_CTRL, data); +} + +/* + * qcom_set_mac_ipg_ctrl() + */ +static inline void qcom_set_mac_ipg_ctrl(struct nss_gmac_hal_dev *nghd, + uint32_t mac_ipg_ctrl) +{ + uint32_t data; + + data = hal_read_reg(nghd->mac_base, QCOM_MAC_DBG_CTRL); + data &= ~QCOM_DBG_MAC_IPG_CTRL_POS; + data |= mac_ipg_ctrl << QCOM_DBG_MAC_IPG_CTRL_LSB; + hal_write_reg(nghd->mac_base, QCOM_MAC_DBG_CTRL, data); +} + +/* + * qcom_set_mac_len_ctrl() + */ +static inline void qcom_set_mac_len_ctrl(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_DBG_CTRL, QCOM_DBG_MAC_LEN_CTRL); +} + +/* + * qcom_reset_mac_len_ctrl() + */ +static inline void qcom_reset_mac_len_ctrl(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_DBG_CTRL, QCOM_DBG_MAC_LEN_CTRL); +} + +/* + * qcom_set_edxsdfr_transmit() + */ +static inline void qcom_set_edxsdfr_transmit(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, QCOM_MAC_DBG_CTRL, QCOM_DBG_EDxSDFR_TRANS); +} + +/* + * qcom_reset_edxsdfr_transmit() + */ +static inline void qcom_reset_edxsdfr_transmit(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, QCOM_MAC_DBG_CTRL, QCOM_DBG_EDxSDFR_TRANS); +} + +/* + * qcom_set_mac_dbg_addr() + */ +static inline void qcom_set_mac_dbg_addr(struct nss_gmac_hal_dev *nghd, + uint8_t mac_dbg_addr) +{ + hal_write_reg(nghd->mac_base, QCOM_MAC_DBG_ADDR, mac_dbg_addr); +} + +/* + * qcom_set_mac_dbg_data() + */ +static inline void qcom_set_mac_dbg_data(struct nss_gmac_hal_dev *nghd, + uint32_t mac_dbg_data) +{ + hal_write_reg(nghd->mac_base, QCOM_MAC_DBG_DATA, mac_dbg_data); +} + +/* + * qcom_set_mac_jumbosize() + */ +static inline void qcom_set_mac_jumbosize(struct nss_gmac_hal_dev *nghd, + uint16_t mac_jumbo_size) +{ + hal_write_reg(nghd->mac_base, QCOM_MAC_JMB_SIZE, mac_jumbo_size); +} + +/* + * qcom_clear_mib_ctrl() + */ +static inline void qcom_clear_mib_ctrl(struct nss_gmac_hal_dev *nghd) +{ + hal_write_reg(nghd->mac_base, QCOM_MAC_MIB_CTRL, 0); +} + +/* + * qcom_set_mib_ctrl() + */ +static inline void qcom_set_mib_ctrl(struct nss_gmac_hal_dev *nghd, + int mib_settings) +{ + hal_set_reg_bits(nghd, QCOM_MAC_MIB_CTRL, + mib_settings); +} + +/* + * qcom_get_stats() + */ +static int qcom_get_stats(struct nss_gmac_hal_dev *nghd) +{ + struct qcom_hal_dev *qhd = (struct qcom_hal_dev *)nghd; + fal_mib_counter_t *stats = &(qhd->stats); + + if (fal_mib_counter_get(0, nghd->mac_id, stats) < 0) + return -1; + + return 0; +} +#endif /* __QCOM_DEV_H__ */ diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/qcom/qcom_if.c b/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/qcom/qcom_if.c new file mode 100644 index 000000000..b9b5968bf --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/qcom/qcom_if.c @@ -0,0 +1,479 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2018, 2020 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include +#include +#include +#include +#include +#include +#include +#include "qcom_dev.h" + +#define QCOM_STAT(m) offsetof(fal_mib_counter_t, m) + +/* + * Ethtool stats pointer structure + */ +struct qcom_ethtool_stats { + uint8_t stat_string[ETH_GSTRING_LEN]; + uint32_t stat_offset; +}; + +/* + * Array of strings describing statistics + */ +static const struct qcom_ethtool_stats qcom_gstrings_stats[] = { + {"rx_broadcast", QCOM_STAT(RxBroad)}, + {"rx_pause", QCOM_STAT(RxPause)}, + {"rx_unicast", QCOM_STAT(RxUniCast)}, + {"rx_multicast", QCOM_STAT(RxMulti)}, + {"rx_fcserr", QCOM_STAT(RxFcsErr)}, + {"rx_alignerr", QCOM_STAT(RxAllignErr)}, + {"rx_runt", QCOM_STAT(RxRunt)}, + {"rx_frag", QCOM_STAT(RxFragment)}, + {"rx_jmbfcserr", QCOM_STAT(RxJumboFcsErr)}, + {"rx_jmbalignerr", QCOM_STAT(RxJumboAligenErr)}, + {"rx_pkt64", QCOM_STAT(Rx64Byte)}, + {"rx_pkt65to127", QCOM_STAT(Rx128Byte)}, + {"rx_pkt128to255", QCOM_STAT(Rx256Byte)}, + {"rx_pkt256to511", QCOM_STAT(Rx512Byte)}, + {"rx_pkt512to1023", QCOM_STAT(Rx1024Byte)}, + {"rx_pkt1024to1518", QCOM_STAT(Rx1518Byte)}, + {"rx_pkt1519tox", QCOM_STAT(RxMaxByte)}, + {"rx_toolong", QCOM_STAT(RxTooLong)}, + {"rx_pktgoodbyte", QCOM_STAT(RxGoodByte)}, + {"rx_pktbadbyte", QCOM_STAT(RxBadByte)}, + {"rx_overflow", QCOM_STAT(RxOverFlow)}, + {"tx_broadcast", QCOM_STAT(TxBroad)}, + {"tx_pause", QCOM_STAT(TxPause)}, + {"tx_multicast", QCOM_STAT(TxMulti)}, + {"tx_underrun", QCOM_STAT(TxUnderRun)}, + {"tx_pkt64", QCOM_STAT(Tx64Byte)}, + {"tx_pkt65to127", QCOM_STAT(Tx128Byte)}, + {"tx_pkt128to255", QCOM_STAT(Tx256Byte)}, + {"tx_pkt256to511", QCOM_STAT(Tx512Byte)}, + {"tx_pkt512to1023", QCOM_STAT(Tx1024Byte)}, + {"tx_pkt1024to1518", QCOM_STAT(Tx1518Byte)}, + {"tx_pkt1519tox", QCOM_STAT(TxMaxByte)}, + {"tx_oversize", QCOM_STAT(TxOverSize)}, + {"tx_pktbyte_h", QCOM_STAT(TxByte)}, + {"tx_collisions", QCOM_STAT(TxCollision)}, + {"tx_abortcol", QCOM_STAT(TxAbortCol)}, + {"tx_multicol", QCOM_STAT(TxMultiCol)}, + {"tx_singlecol", QCOM_STAT(TxSingalCol)}, + {"tx_exesdeffer", QCOM_STAT(TxExcDefer)}, + {"tx_deffer", QCOM_STAT(TxDefer)}, + {"tx_latecol", QCOM_STAT(TxLateCol)}, + {"tx_unicast", QCOM_STAT(TxUniCast)}, +}; + +/* + * Array of strings describing private flag names + */ +static const char * const qcom_strings_priv_flags[] = { + "linkpoll", + "tstamp", + "tsmode", +}; + +#define QCOM_STATS_LEN ARRAY_SIZE(qcom_gstrings_stats) +#define QCOM_PRIV_FLAGS_LEN ARRAY_SIZE(qcom_strings_priv_flags) + +/* + * qcom_set_mac_speed() + */ +static int32_t qcom_set_mac_speed(struct nss_gmac_hal_dev *nghd, + uint32_t mac_speed) +{ + struct net_device *netdev = nghd->netdev; + + netdev_warn(netdev, "API deprecated\n"); + return 0; +} + +/* + * qcom_get_mac_speed() + */ +static uint32_t qcom_get_mac_speed(struct nss_gmac_hal_dev *nghd) +{ + struct net_device *netdev = nghd->netdev; + + netdev_warn(netdev, "API deprecated\n"); + return 0; +} + +/* + * qcom_set_duplex_mode() + */ +static void qcom_set_duplex_mode(struct nss_gmac_hal_dev *nghd, + uint8_t duplex_mode) +{ + struct net_device *netdev = nghd->netdev; + + netdev_warn(netdev, "This API deprecated\n"); +} + +/* + * qcom_get_duplex_mode() + */ +static uint8_t qcom_get_duplex_mode(struct nss_gmac_hal_dev *nghd) +{ + struct net_device *netdev = nghd->netdev; + + netdev_warn(netdev, "API deprecated\n"); + return 0; +} + +/* + * qcom_rx_flow_control() + */ +static void qcom_rx_flow_control(struct nss_gmac_hal_dev *nghd, bool enabled) +{ + if (enabled) + qcom_set_rx_flow_ctrl(nghd); + else + qcom_clear_rx_flow_ctrl(nghd); +} + +/* + * qcom_tx_flow_control() + */ +static void qcom_tx_flow_control(struct nss_gmac_hal_dev *nghd, bool enabled) +{ + if (enabled) + qcom_set_tx_flow_ctrl(nghd); + else + qcom_clear_tx_flow_ctrl(nghd); +} + +/* + * qcom_get_mib_stats() + */ +static int32_t qcom_get_mib_stats(struct nss_gmac_hal_dev *nghd) +{ + if (qcom_get_stats(nghd)) + return -1; + + return 0; +} + +/* + * qcom_set_maxframe() + */ +static int32_t qcom_set_maxframe(struct nss_gmac_hal_dev *nghd, + uint32_t maxframe) +{ + return fal_port_max_frame_size_set(0, nghd->mac_id, maxframe); +} + +/* + * qcom_get_maxframe() + */ +static int32_t qcom_get_maxframe(struct nss_gmac_hal_dev *nghd) +{ + int ret; + uint32_t mtu; + + ret = fal_port_max_frame_size_get(0, nghd->mac_id, &mtu); + + if (!ret) + return mtu; + + return ret; +} + +/* + * qcom_get_netdev_stats() + */ +static int32_t qcom_get_netdev_stats(struct nss_gmac_hal_dev *nghd, + struct rtnl_link_stats64 *stats) +{ + struct qcom_hal_dev *qhd = (struct qcom_hal_dev *)nghd; + fal_mib_counter_t *hal_stats = &(qhd->stats); + + if (qcom_get_mib_stats(nghd)) + return -1; + + stats->rx_packets = hal_stats->RxUniCast + hal_stats->RxBroad + + hal_stats->RxMulti; + stats->tx_packets = hal_stats->TxUniCast + hal_stats->TxBroad + + hal_stats->TxMulti; + stats->rx_bytes = hal_stats->RxGoodByte; + stats->tx_bytes = hal_stats->TxByte; + + /* RX errors */ + stats->rx_crc_errors = hal_stats->RxFcsErr + hal_stats->RxJumboFcsErr; + stats->rx_frame_errors = hal_stats->RxAllignErr + + hal_stats->RxJumboAligenErr; + stats->rx_fifo_errors = hal_stats->RxRunt; + stats->rx_errors = stats->rx_crc_errors + stats->rx_frame_errors + + stats->rx_fifo_errors; + + stats->rx_dropped = hal_stats->RxTooLong + stats->rx_errors; + + /* TX errors */ + stats->tx_fifo_errors = hal_stats->TxUnderRun; + stats->tx_aborted_errors = hal_stats->TxAbortCol; + stats->tx_errors = stats->tx_fifo_errors + stats->tx_aborted_errors; + + stats->collisions = hal_stats->TxCollision; + stats->multicast = hal_stats->RxMulti; + + return 0; +} + +/* + * qcom_get_strset_count() + * Get string set count for ethtool operations + */ +int32_t qcom_get_strset_count(struct nss_gmac_hal_dev *nghd, int32_t sset) +{ + struct net_device *netdev = nghd->netdev; + + switch (sset) { + case ETH_SS_STATS: + return QCOM_STATS_LEN; + case ETH_SS_PRIV_FLAGS: + return QCOM_PRIV_FLAGS_LEN; + } + + netdev_dbg(netdev, "%s: Invalid string set\n", __func__); + return -EPERM; +} + +/* + * qcom_get_strings() + * Get strings + */ +int32_t qcom_get_strings(struct nss_gmac_hal_dev *nghd, int32_t sset, + uint8_t *data) +{ + struct net_device *netdev = nghd->netdev; + int i; + + switch (sset) { + case ETH_SS_STATS: + for (i = 0; i < QCOM_STATS_LEN; i++) { + memcpy(data, qcom_gstrings_stats[i].stat_string, + strlen(qcom_gstrings_stats[i].stat_string)); + data += ETH_GSTRING_LEN; + } + break; + case ETH_SS_PRIV_FLAGS: + for (i = 0; i < QCOM_PRIV_FLAGS_LEN; i++) { + memcpy(data, qcom_strings_priv_flags[i], + strlen(qcom_strings_priv_flags[i])); + data += ETH_GSTRING_LEN; + } + break; + default: + netdev_dbg(netdev, "%s: Invalid string set\n", __func__); + return -EPERM; + } + + return 0; +} + +/* + * qcom_get_eth_stats() + */ +static int32_t qcom_get_eth_stats(struct nss_gmac_hal_dev *nghd, uint64_t *data) +{ + struct qcom_hal_dev *qhd = (struct qcom_hal_dev *)nghd; + fal_mib_counter_t *stats = &(qhd->stats); + uint8_t *p; + int i; + + if (qcom_get_mib_stats(nghd)) + return -1; + + for (i = 0; i < QCOM_STATS_LEN; i++) { + p = (uint8_t *)stats + qcom_gstrings_stats[i].stat_offset; + data[i] = *(uint32_t *)p; + } + + return 0; +} + +/* + * qcom_send_pause_frame() + */ +static void qcom_send_pause_frame(struct nss_gmac_hal_dev *nghd) +{ + qcom_set_ctrl2_test_pause(nghd); +} + +/* + * qcom_stop_pause_frame() + */ +static void qcom_stop_pause_frame(struct nss_gmac_hal_dev *nghd) +{ + qcom_reset_ctrl2_test_pause(nghd); +} + +/* + * qcom_start() + */ +static int32_t qcom_start(struct nss_gmac_hal_dev *nghd) +{ + qcom_set_full_duplex(nghd); + + /* TODO: Read speed from dts */ + + if (qcom_set_mac_speed(nghd, SPEED_1000)) + return -1; + + qcom_tx_enable(nghd); + qcom_rx_enable(nghd); + + netdev_dbg(nghd->netdev, "%s: mac_base:0x%px mac_enable:0x%x\n", + __func__, nghd->mac_base, + hal_read_reg(nghd->mac_base, QCOM_MAC_ENABLE)); + + return 0; +} + +/* + * qcom_stop() + */ +static int32_t qcom_stop(struct nss_gmac_hal_dev *nghd) +{ + qcom_tx_disable(nghd); + qcom_rx_disable(nghd); + + netdev_dbg(nghd->netdev, "%s: mac_base:0x%px mac_enable:0x%x\n", + __func__, nghd->mac_base, + hal_read_reg(nghd->mac_base, QCOM_MAC_ENABLE)); + return 0; +} + +/* + * qcom_init() + */ +static void *qcom_init(struct gmac_hal_platform_data *gmacpdata) +{ + struct qcom_hal_dev *qhd = NULL; + struct net_device *ndev = NULL; + struct nss_dp_dev *dp_priv = NULL; + struct resource *res; + + ndev = gmacpdata->netdev; + dp_priv = netdev_priv(ndev); + + res = platform_get_resource(dp_priv->pdev, IORESOURCE_MEM, 0); + if (!res) { + netdev_dbg(ndev, "Resource get failed.\n"); + return NULL; + } + + if (!devm_request_mem_region(&dp_priv->pdev->dev, res->start, + resource_size(res), ndev->name)) { + netdev_dbg(ndev, "Request mem region failed. Returning...\n"); + return NULL; + } + + qhd = (struct qcom_hal_dev *)devm_kzalloc(&dp_priv->pdev->dev, + sizeof(struct qcom_hal_dev), GFP_KERNEL); + if (!qhd) { + netdev_dbg(ndev, "kzalloc failed. Returning...\n"); + return NULL; + } + + /* Save netdev context in QCOM HAL context */ + qhd->nghd.netdev = gmacpdata->netdev; + qhd->nghd.mac_id = gmacpdata->macid; + + /* Populate the mac base addresses */ + qhd->nghd.mac_base = devm_ioremap_nocache(&dp_priv->pdev->dev, + res->start, resource_size(res)); + if (!qhd->nghd.mac_base) { + netdev_dbg(ndev, "ioremap fail.\n"); + return NULL; + } + + spin_lock_init(&qhd->nghd.slock); + + netdev_dbg(ndev, "ioremap OK.Size 0x%x Ndev base 0x%lx macbase 0x%px\n", + gmacpdata->reg_len, + ndev->base_addr, + qhd->nghd.mac_base); + + /* Reset MIB Stats */ + if (fal_mib_port_flush_counters(0, qhd->nghd.mac_id)) { + netdev_dbg(ndev, "MIB stats Reset fail.\n"); + } + + return (struct nss_gmac_hal_dev *)qhd; +} + +/* + * qcom_get_mac_address() + */ +static void qcom_get_mac_address(struct nss_gmac_hal_dev *nghd, + uint8_t *macaddr) +{ + uint32_t data = hal_read_reg(nghd->mac_base, QCOM_MAC_ADDR0); + macaddr[5] = (data >> 8) & 0xff; + macaddr[4] = (data) & 0xff; + + data = hal_read_reg(nghd->mac_base, QCOM_MAC_ADDR1); + macaddr[0] = (data >> 24) & 0xff; + macaddr[1] = (data >> 16) & 0xff; + macaddr[2] = (data >> 8) & 0xff; + macaddr[3] = (data) & 0xff; +} + +/* + * qcom_set_mac_address() + */ +static void qcom_set_mac_address(struct nss_gmac_hal_dev *nghd, + uint8_t *macaddr) +{ + uint32_t data = (macaddr[5] << 8) | macaddr[4]; + hal_write_reg(nghd->mac_base, QCOM_MAC_ADDR0, data); + data = (macaddr[0] << 24) | (macaddr[1] << 16) + | (macaddr[2] << 8) | macaddr[3]; + hal_write_reg(nghd->mac_base, QCOM_MAC_ADDR1, data); +} + +/* + * MAC hal_ops base structure + */ +struct nss_gmac_hal_ops qcom_hal_ops = { + .init = &qcom_init, + .start = &qcom_start, + .stop = &qcom_stop, + .setmacaddr = &qcom_set_mac_address, + .getmacaddr = &qcom_get_mac_address, + .rxflowcontrol = &qcom_rx_flow_control, + .txflowcontrol = &qcom_tx_flow_control, + .setspeed = &qcom_set_mac_speed, + .getspeed = &qcom_get_mac_speed, + .setduplex = &qcom_set_duplex_mode, + .getduplex = &qcom_get_duplex_mode, + .getstats = &qcom_get_mib_stats, + .setmaxframe = &qcom_set_maxframe, + .getmaxframe = &qcom_get_maxframe, + .getndostats = &qcom_get_netdev_stats, + .getssetcount = &qcom_get_strset_count, + .getstrings = &qcom_get_strings, + .getethtoolstats = &qcom_get_eth_stats, + .sendpause = &qcom_send_pause_frame, + .stoppause = &qcom_stop_pause_frame, +}; diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/qcom/qcom_reg.h b/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/qcom/qcom_reg.h new file mode 100644 index 000000000..9210c2a50 --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/qcom/qcom_reg.h @@ -0,0 +1,156 @@ +/* + ************************************************************************** + * Copyright (c) 2016,2020 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF0 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __QCOM_REG_H__ +#define __QCOM_REG_H__ + +/* Register Offsets */ +/* Offsets of GMAC config and status registers within NSS_GMAC_QCOM_MAC_BASE */ +#define QCOM_MAC_ENABLE 0x0000 +#define QCOM_MAC_SPEED 0x0004 +#define QCOM_MAC_ADDR0 0x0008 +#define QCOM_MAC_ADDR1 0x000c +#define QCOM_MAC_CTRL0 0x0010 +#define QCOM_MAC_CTRL1 0x0014 +#define QCOM_MAC_CTRL2 0x0018 +#define QCOM_MAC_DBG_CTRL 0x001c +#define QCOM_MAC_DBG_ADDR 0x0020 +#define QCOM_MAC_DBG_DATA 0x0024 +#define QCOM_MAC_JMB_SIZE 0x0030 +#define QCOM_MAC_MIB_CTRL 0x0034 + +/* RX stats */ +#define QCOM_RXBROAD 0x0040 +#define QCOM_RXPAUSE 0x0044 +#define QCOM_RXMULTI 0x0048 +#define QCOM_RXFCSERR 0x004c +#define QCOM_RXALIGNERR 0x0050 +#define QCOM_RXRUNT 0x0054 +#define QCOM_RXFRAG 0x0058 +#define QCOM_RXJMBFCSERR 0x005c +#define QCOM_RXJMBALIGNERR 0x0060 +#define QCOM_RXPKT64 0x0064 +#define QCOM_RXPKT65TO127 0x0068 +#define QCOM_RXPKT128TO255 0x006c +#define QCOM_RXPKT256TO511 0x0070 +#define QCOM_RXPKT512TO1023 0x0074 +#define QCOM_RXPKT1024TO1518 0x0078 +#define QCOM_RXPKT1519TOX 0x007c +#define QCOM_RXPKTTOOLONG 0x0080 +#define QCOM_RXPKTGOODBYTE_L 0x0084 +#define QCOM_RXPKTGOODBYTE_H 0x0088 +#define QCOM_RXPKTBADBYTE_L 0x008c +#define QCOM_RXPKTBADBYTE_H 0x0090 +#define QCOM_RXUNI 0x0094 + +/* TX stats */ +#define QCOM_TXBROAD 0x00a0 +#define QCOM_TXPAUSE 0x00a4 +#define QCOM_TXMULTI 0x00a8 +#define QCOM_TXUNDERUN 0x00aC +#define QCOM_TXPKT64 0x00b0 +#define QCOM_TXPKT65TO127 0x00b4 +#define QCOM_TXPKT128TO255 0x00b8 +#define QCOM_TXPKT256TO511 0x00bc +#define QCOM_TXPKT512TO1023 0x00c0 +#define QCOM_TXPKT1024TO1518 0x00c4 +#define QCOM_TXPKT1519TOX 0x00c8 +#define QCOM_TXPKTBYTE_L 0x00cc +#define QCOM_TXPKTBYTE_H 0x00d0 +#define QCOM_TXCOLLISIONS 0x00d4 +#define QCOM_TXABORTCOL 0x00d8 +#define QCOM_TXMULTICOL 0x00dc +#define QCOM_TXSINGLECOL 0x00e0 +#define QCOM_TXEXCESSIVEDEFER 0x00e4 +#define QCOM_TXDEFER 0x00e8 +#define QCOM_TXLATECOL 0x00ec +#define QCOM_TXUNI 0x00f0 + +/* Bit Masks */ +/* GMAC BITs */ +#define QCOM_RX_MAC_ENABLE 1 +#define QCOM_TX_MAC_ENABLE 0x2 +#define QCOM_DUPLEX 0x10 +#define QCOM_RX_FLOW_ENABLE 0x20 +#define QCOM_TX_FLOW_ENABLE 0x40 + +#define QCOM_MAC_SPEED_10 0 +#define QCOM_MAC_SPEED_100 1 +#define QCOM_MAC_SPEED_1000 2 + +/* MAC CTRL0 */ +#define QCOM_IPGT_POS 0x0000007f +#define QCOM_IPGT_LSB 0 +#define QCOM_IPGR2_POS 0x00007f00 +#define QCOM_IPGR2_LSB 8 +#define QCOM_HALF_THDF_CTRL 0x8000 +#define QCOM_HUGE_RECV 0x10000 +#define QCOM_HUGE_TRANS 0x20000 +#define QCOM_FLCHK 0x40000 +#define QCOM_ABEBE 0x80000 +#define QCOM_AMAXE 0x10000000 +#define QCOM_BPNB 0x20000000 +#define QCOM_NOBO 0x40000000 +#define QCOM_DRBNIB_RXOK 0x80000000 + +/* MAC CTRL1 */ +#define QCOM_JAM_IPG_POS 0x0000000f +#define QCOM_JAM_IPG_LSB 0 +#define QCOM_TPAUSE 0x10 +#define QCOM_TCTL 0x20 +#define QCOM_SSTCT 0x40 +#define QCOM_SIMR 0x80 +#define QCOM_RETRY_POS 0x00000f00 +#define QCOM_RETRY_LSB 8 +#define QCOM_PRLEN_POS 0x0000f000 +#define QCOM_PRLEN_LSB 8 +#define QCOM_PPAD 0x10000 +#define QCOM_POVR 0x20000 +#define QCOM_PHUG 0x40000 +#define QCOM_MBOF 0x80000 +#define QCOM_LCOL_POS 0x0ff00000 +#define QCOM_LCOL_LSB 20 +#define QCOM_LONG_JAM 0x10000000 + +/* MAC CTRL2 */ +#define QCOM_IPG_DEC_LEN 0x2 +#define QCOM_TEST_PAUSE 0x4 +#define QCOM_MAC_LPI_TX_IDLE 0x8 +#define QCOM_MAC_LOOPBACK 0x10 +#define QCOM_IPG_DEC 0x20 +#define QCOM_SRS_SEL 0x40 +#define QCOM_CRC_RSV 0x80 +#define QCOM_MAXFR_POS 0x003fff00 +#define QCOM_MAXFR_LSB 8 + +/* MAC DEBUG_CTRL */ +#define QCOM_DBG_IPGR1_POS 0x0000007f +#define QCOM_DBG_IPGR1_LSB 0 +#define QCOM_DBG_HIHG_IPG_POS 0x0000ff00 +#define QCOM_DBG_HIHG_IPG_LSB 8 +#define QCOM_DBG_MAC_IPG_CTRL_POS 0x0000ff00 +#define QCOM_DBG_MAC_IPG_CTRL_LSB 20 +#define QCOM_DBG_MAC_LEN_CTRL 0x40000000 +#define QCOM_DBG_EDxSDFR_TRANS 0x80000000 + +/* MAC MIB-CTRL*/ +#define QCOM_MIB_ENABLE 1 +#define QCOM_MIB_RESET 0x2 +#define QCOM_MIB_RD_CLR 0x4 + +#endif /*__QCOM_REG_H__*/ diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/gmac/syn_dev.h b/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/gmac/syn_dev.h new file mode 100644 index 000000000..0bfec1b99 --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/gmac/syn_dev.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __SYN_DEV_H__ +#define __SYN_DEV_H__ + +#include + +/* + * Subclass for base nss_gmac_hal_dev + */ +struct syn_hal_dev { + struct nss_gmac_hal_dev nghd; /* Base class */ + struct nss_dp_gmac_stats stats; /* Stats structure */ +}; + +#endif /*__SYN_DEV_H__*/ diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/gmac/syn_if.c b/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/gmac/syn_if.c new file mode 100644 index 000000000..2601ff204 --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/gmac/syn_if.c @@ -0,0 +1,959 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "syn_dev.h" +#include "syn_reg.h" + +#define SYN_STAT(m) offsetof(struct nss_dp_hal_gmac_stats, m) +#define HW_ERR_SIZE sizeof(uint64_t) + +/* + * Array to store ethtool statistics + */ +struct syn_ethtool_stats { + uint8_t stat_string[ETH_GSTRING_LEN]; + uint64_t stat_offset; +}; + +/* + * Array of strings describing statistics + */ +static const struct syn_ethtool_stats syn_gstrings_stats[] = { + {"rx_bytes", SYN_STAT(rx_bytes)}, + {"rx_packets", SYN_STAT(rx_packets)}, + {"rx_errors", SYN_STAT(rx_errors)}, + {"rx_receive_errors", SYN_STAT(rx_receive_errors)}, + {"rx_descriptor_errors", SYN_STAT(rx_descriptor_errors)}, + {"rx_late_collision_errors", SYN_STAT(rx_late_collision_errors)}, + {"rx_dribble_bit_errors", SYN_STAT(rx_dribble_bit_errors)}, + {"rx_length_errors", SYN_STAT(rx_length_errors)}, + {"rx_ip_header_errors", SYN_STAT(rx_ip_header_errors)}, + {"rx_ip_payload_errors", SYN_STAT(rx_ip_payload_errors)}, + {"rx_no_buffer_errors", SYN_STAT(rx_no_buffer_errors)}, + {"rx_transport_csum_bypassed", SYN_STAT(rx_transport_csum_bypassed)}, + {"tx_bytes", SYN_STAT(tx_bytes)}, + {"tx_packets", SYN_STAT(tx_packets)}, + {"tx_collisions", SYN_STAT(tx_collisions)}, + {"tx_errors", SYN_STAT(tx_errors)}, + {"tx_jabber_timeout_errors", SYN_STAT(tx_jabber_timeout_errors)}, + {"tx_frame_flushed_errors", SYN_STAT(tx_frame_flushed_errors)}, + {"tx_loss_of_carrier_errors", SYN_STAT(tx_loss_of_carrier_errors)}, + {"tx_no_carrier_errors", SYN_STAT(tx_no_carrier_errors)}, + {"tx_late_collision_errors", SYN_STAT(tx_late_collision_errors)}, + {"tx_excessive_collision_errors", SYN_STAT(tx_excessive_collision_errors)}, + {"tx_excessive_deferral_errors", SYN_STAT(tx_excessive_deferral_errors)}, + {"tx_underflow_errors", SYN_STAT(tx_underflow_errors)}, + {"tx_ip_header_errors", SYN_STAT(tx_ip_header_errors)}, + {"tx_ip_payload_errors", SYN_STAT(tx_ip_payload_errors)}, + {"tx_dropped", SYN_STAT(tx_dropped)}, + {"rx_missed", SYN_STAT(rx_missed)}, + {"fifo_overflows", SYN_STAT(fifo_overflows)}, + {"rx_scatter_errors", SYN_STAT(rx_scatter_errors)}, + {"tx_ts_create_errors", SYN_STAT(tx_ts_create_errors)}, + {"pmt_interrupts", SYN_STAT(hw_errs[0])}, + {"mmc_interrupts", SYN_STAT(hw_errs[0]) + (1 * HW_ERR_SIZE)}, + {"line_interface_interrupts", SYN_STAT(hw_errs[0]) + (2 * HW_ERR_SIZE)}, + {"fatal_bus_error_interrupts", SYN_STAT(hw_errs[0]) + (3 * HW_ERR_SIZE)}, + {"rx_buffer_unavailable_interrupts", SYN_STAT(hw_errs[0]) + (4 * HW_ERR_SIZE)}, + {"rx_process_stopped_interrupts", SYN_STAT(hw_errs[0]) + (5 * HW_ERR_SIZE)}, + {"tx_underflow_interrupts", SYN_STAT(hw_errs[0]) + (6 * HW_ERR_SIZE)}, + {"rx_overflow_interrupts", SYN_STAT(hw_errs[0]) + (7 * HW_ERR_SIZE)}, + {"tx_jabber_timeout_interrutps", SYN_STAT(hw_errs[0]) + (8 * HW_ERR_SIZE)}, + {"tx_process_stopped_interrutps", SYN_STAT(hw_errs[0]) + (9 * HW_ERR_SIZE)}, + {"gmac_total_ticks", SYN_STAT(gmac_total_ticks)}, + {"gmac_worst_case_ticks", SYN_STAT(gmac_worst_case_ticks)}, + {"gmac_iterations", SYN_STAT(gmac_iterations)}, + {"tx_pause_frames", SYN_STAT(tx_pause_frames)}, + {"mmc_rx_overflow_errors", SYN_STAT(mmc_rx_overflow_errors)}, + {"mmc_rx_watchdog_timeout_errors", SYN_STAT(mmc_rx_watchdog_timeout_errors)}, + {"mmc_rx_crc_errors", SYN_STAT(mmc_rx_crc_errors)}, + {"mmc_rx_ip_header_errors", SYN_STAT(mmc_rx_ip_header_errors)}, + {"mmc_rx_octets_g", SYN_STAT(mmc_rx_octets_g)}, + {"mmc_rx_ucast_frames", SYN_STAT(mmc_rx_ucast_frames)}, + {"mmc_rx_bcast_frames", SYN_STAT(mmc_rx_bcast_frames)}, + {"mmc_rx_mcast_frames", SYN_STAT(mmc_rx_mcast_frames)}, + {"mmc_rx_undersize", SYN_STAT(mmc_rx_undersize)}, + {"mmc_rx_oversize", SYN_STAT(mmc_rx_oversize)}, + {"mmc_rx_jabber", SYN_STAT(mmc_rx_jabber)}, + {"mmc_rx_octets_gb", SYN_STAT(mmc_rx_octets_gb)}, + {"mmc_rx_frag_frames_g", SYN_STAT(mmc_rx_frag_frames_g)}, + {"mmc_tx_octets_g", SYN_STAT(mmc_tx_octets_g)}, + {"mmc_tx_ucast_frames", SYN_STAT(mmc_tx_ucast_frames)}, + {"mmc_tx_bcast_frames", SYN_STAT(mmc_tx_bcast_frames)}, + {"mmc_tx_mcast_frames", SYN_STAT(mmc_tx_mcast_frames)}, + {"mmc_tx_deferred", SYN_STAT(mmc_tx_deferred)}, + {"mmc_tx_single_col", SYN_STAT(mmc_tx_single_col)}, + {"mmc_tx_multiple_col", SYN_STAT(mmc_tx_multiple_col)}, + {"mmc_tx_octets_gb", SYN_STAT(mmc_tx_octets_gb)}, +}; + +#define SYN_STATS_LEN ARRAY_SIZE(syn_gstrings_stats) + +/* + * syn_set_rx_flow_ctrl() + */ +static inline void syn_set_rx_flow_ctrl(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, SYN_MAC_FLOW_CONTROL, + SYN_MAC_FC_RX_FLOW_CONTROL); +} + +/* + * syn_clear_rx_flow_ctrl() + */ +static inline void syn_clear_rx_flow_ctrl(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, SYN_MAC_FLOW_CONTROL, + SYN_MAC_FC_RX_FLOW_CONTROL); + +} + +/* + * syn_set_tx_flow_ctrl() + */ +static inline void syn_set_tx_flow_ctrl(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, SYN_MAC_FLOW_CONTROL, + SYN_MAC_FC_TX_FLOW_CONTROL); +} + +/* + * syn_send_tx_pause_frame() + */ +static inline void syn_send_tx_pause_frame(struct nss_gmac_hal_dev *nghd) +{ + syn_set_tx_flow_ctrl(nghd); + hal_set_reg_bits(nghd, SYN_MAC_FLOW_CONTROL, + SYN_MAC_FC_SEND_PAUSE_FRAME); +} + +/* + * syn_clear_tx_flow_ctrl() + */ +static inline void syn_clear_tx_flow_ctrl(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, SYN_MAC_FLOW_CONTROL, + SYN_MAC_FC_TX_FLOW_CONTROL); +} + +/* + * syn_rx_enable() + */ +static inline void syn_rx_enable(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, SYN_MAC_CONFIGURATION, SYN_MAC_RX); + hal_set_reg_bits(nghd, SYN_MAC_FRAME_FILTER, SYN_MAC_FILTER_OFF); +} + +/* + * syn_tx_enable() + */ +static inline void syn_tx_enable(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, SYN_MAC_CONFIGURATION, SYN_MAC_TX); +} + +/************Ip checksum offloading APIs*************/ + +/* + * syn_enable_rx_chksum_offload() + * Enable IPv4 header and IPv4/IPv6 TCP/UDP checksum calculation by GMAC. + */ +static inline void syn_enable_rx_chksum_offload(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, + SYN_MAC_CONFIGURATION, SYN_MAC_RX_IPC_OFFLOAD); +} + +/* + * syn_disable_rx_chksum_offload() + * Disable the IP checksum offloading in receive path. + */ +static inline void syn_disable_rx_chksum_offload(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, + SYN_MAC_CONFIGURATION, SYN_MAC_RX_IPC_OFFLOAD); +} + +/* + * syn_rx_tcpip_chksum_drop_enable() + * Instruct the DMA to drop the packets that fail TCP/IP checksum. + * + * This is to instruct the receive DMA engine to drop the recevied + * packet if they fails the tcp/ip checksum in hardware. Valid only when + * full checksum offloading is enabled(type-2). + */ +static inline void syn_rx_tcpip_chksum_drop_enable(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, + SYN_DMA_OPERATION_MODE, SYN_DMA_DISABLE_DROP_TCP_CS); +} + +/*******************Ip checksum offloading APIs**********************/ + +/* + * syn_ipc_offload_init() + * Initialize IPC Checksum offloading. + */ +static inline void syn_ipc_offload_init(struct nss_gmac_hal_dev *nghd) +{ + struct nss_dp_dev *dp_priv; + dp_priv = netdev_priv(nghd->netdev); + + if (test_bit(__NSS_DP_RXCSUM, &dp_priv->flags)) { + /* + * Enable the offload engine in the receive path + */ + syn_enable_rx_chksum_offload(nghd); + + /* + * DMA drops the packets if error in encapsulated ethernet + * payload. + */ + syn_rx_tcpip_chksum_drop_enable(nghd); + netdev_dbg(nghd->netdev, "%s: enable Rx checksum\n", __func__); + } else { + syn_disable_rx_chksum_offload(nghd); + netdev_dbg(nghd->netdev, "%s: disable Rx checksum\n", __func__); + } +} + +/* + * syn_disable_mac_interrupt() + * Disable all the interrupts. + */ +static inline void syn_disable_mac_interrupt(struct nss_gmac_hal_dev *nghd) +{ + hal_write_reg(nghd->mac_base, SYN_INTERRUPT_MASK, 0xffffffff); +} + +/* + * syn_disable_mmc_tx_interrupt() + * Disable the MMC Tx interrupt. + * + * The MMC tx interrupts are masked out as per the mask specified. + */ +static inline void syn_disable_mmc_tx_interrupt(struct nss_gmac_hal_dev *nghd, + uint32_t mask) +{ + hal_set_reg_bits(nghd, SYN_MMC_TX_INTERRUPT_MASK, mask); +} + +/* + * syn_disable_mmc_rx_interrupt() + * Disable the MMC Rx interrupt. + * + * The MMC rx interrupts are masked out as per the mask specified. + */ +static inline void syn_disable_mmc_rx_interrupt(struct nss_gmac_hal_dev *nghd, + uint32_t mask) +{ + hal_set_reg_bits(nghd, SYN_MMC_RX_INTERRUPT_MASK, mask); +} + +/* + * syn_disable_mmc_ipc_rx_interrupt() + * Disable the MMC ipc rx checksum offload interrupt. + * + * The MMC ipc rx checksum offload interrupts are masked out as + * per the mask specified. + */ +static inline void syn_disable_mmc_ipc_rx_interrupt(struct nss_gmac_hal_dev *nghd, + uint32_t mask) +{ + hal_set_reg_bits(nghd, SYN_MMC_IPC_RX_INTR_MASK, mask); +} + +/* + * syn_disable_dma_interrupt() + * Disables all DMA interrupts. + */ +void syn_disable_dma_interrupt(struct nss_gmac_hal_dev *nghd) +{ + hal_write_reg(nghd->mac_base, SYN_DMA_INT_ENABLE, SYN_DMA_INT_DISABLE); +} + +/* + * syn_enable_dma_interrupt() + * Enables all DMA interrupts. + */ +void syn_enable_dma_interrupt(struct nss_gmac_hal_dev *nghd) +{ + hal_write_reg(nghd->mac_base, SYN_DMA_INT_ENABLE, SYN_DMA_INT_EN); +} + +/* + * syn_disable_interrupt_all() + * Disable all the interrupts. + */ +static inline void syn_disable_interrupt_all(struct nss_gmac_hal_dev *nghd) +{ + syn_disable_mac_interrupt(nghd); + syn_disable_dma_interrupt(nghd); + syn_disable_mmc_tx_interrupt(nghd, 0xFFFFFFFF); + syn_disable_mmc_rx_interrupt(nghd, 0xFFFFFFFF); + syn_disable_mmc_ipc_rx_interrupt(nghd, 0xFFFFFFFF); +} + +/* + * syn_dma_bus_mode_init() + * Function to program DMA bus mode register. + */ +static inline void syn_dma_bus_mode_init(struct nss_gmac_hal_dev *nghd) +{ + hal_write_reg(nghd->mac_base, SYN_DMA_BUS_MODE, SYN_DMA_BUS_MODE_VAL); +} + +/* + * syn_clear_dma_status() + * Clear all the pending dma interrupts. + */ +void syn_clear_dma_status(struct nss_gmac_hal_dev *nghd) +{ + uint32_t data; + + data = hal_read_reg(nghd->mac_base, SYN_DMA_STATUS); + hal_write_reg(nghd->mac_base, SYN_DMA_STATUS, data); +} + +/* + * syn_enable_dma_rx() + * Enable Rx GMAC operation + */ +void syn_enable_dma_rx(struct nss_gmac_hal_dev *nghd) +{ + uint32_t data; + + data = hal_read_reg(nghd->mac_base, SYN_DMA_OPERATION_MODE); + data |= SYN_DMA_RX_START; + hal_write_reg(nghd->mac_base, SYN_DMA_OPERATION_MODE, data); +} + +/* + * syn_disable_dma_rx() + * Disable Rx GMAC operation + */ +void syn_disable_dma_rx(struct nss_gmac_hal_dev *nghd) +{ + uint32_t data; + + data = hal_read_reg(nghd->mac_base, SYN_DMA_OPERATION_MODE); + data &= ~SYN_DMA_RX_START; + hal_write_reg(nghd->mac_base, SYN_DMA_OPERATION_MODE, data); +} + +/* + * syn_enable_dma_tx() + * Enable Rx GMAC operation + */ +void syn_enable_dma_tx(struct nss_gmac_hal_dev *nghd) +{ + uint32_t data; + + data = hal_read_reg(nghd->mac_base, SYN_DMA_OPERATION_MODE); + data |= SYN_DMA_TX_START; + hal_write_reg(nghd->mac_base, SYN_DMA_OPERATION_MODE, data); +} + +/* + * syn_disable_dma_tx() + * Disable Rx GMAC operation + */ +void syn_disable_dma_tx(struct nss_gmac_hal_dev *nghd) +{ + uint32_t data; + + data = hal_read_reg(nghd->mac_base, SYN_DMA_OPERATION_MODE); + data &= ~SYN_DMA_TX_START; + hal_write_reg(nghd->mac_base, SYN_DMA_OPERATION_MODE, data); +} + +/* + * syn_resume_dma_tx + * Resumes the DMA Transmission. + */ +void syn_resume_dma_tx(struct nss_gmac_hal_dev *nghd) +{ + hal_write_reg(nghd->mac_base, SYN_DMA_TX_POLL_DEMAND, 0); +} + +/* + * syn_get_rx_missed + * Get Rx missed errors + */ +uint32_t syn_get_rx_missed(struct nss_gmac_hal_dev *nghd) +{ + uint32_t missed_frame_buff_overflow; + missed_frame_buff_overflow = hal_read_reg(nghd->mac_base, SYN_DMA_MISSED_FRAME_AND_BUFF_OVERFLOW_COUNTER); + return missed_frame_buff_overflow & 0xFFFF; +} + +/* + * syn_get_fifo_overflows + * Get FIFO overflows + */ +uint32_t syn_get_fifo_overflows(struct nss_gmac_hal_dev *nghd) +{ + uint32_t missed_frame_buff_overflow; + missed_frame_buff_overflow = hal_read_reg(nghd->mac_base, SYN_DMA_MISSED_FRAME_AND_BUFF_OVERFLOW_COUNTER); + return (missed_frame_buff_overflow >> 17) & 0x7ff; +} + +/* + * syn_init_tx_desc_base() + * Programs the Dma Tx Base address with the starting address of the descriptor ring or chain. + */ +void syn_init_tx_desc_base(struct nss_gmac_hal_dev *nghd, uint32_t tx_desc_dma) +{ + hal_write_reg(nghd->mac_base, SYN_DMA_TX_DESCRIPTOR_LIST_ADDRESS, tx_desc_dma); +} + +/* + * syn_init_rx_desc_base() + * Programs the Dma Rx Base address with the starting address of the descriptor ring or chain. + */ +void syn_init_rx_desc_base(struct nss_gmac_hal_dev *nghd, uint32_t rx_desc_dma) +{ + hal_write_reg(nghd->mac_base, SYN_DMA_RX_DESCRIPTOR_LIST_ADDRESS, rx_desc_dma); +} + +/* + * syn_dma_axi_bus_mode_init() + * Function to program DMA AXI bus mode register. + */ +static inline void syn_dma_axi_bus_mode_init(struct nss_gmac_hal_dev *nghd) +{ + hal_write_reg(nghd->mac_base, SYN_DMA_AXI_BUS_MODE, + SYN_DMA_AXI_BUS_MODE_VAL); +} + +/* + * syn_dma_operation_mode_init() + * Function to program DMA Operation Mode register. + */ +static inline void syn_dma_operation_mode_init(struct nss_gmac_hal_dev *nghd) +{ + hal_write_reg(nghd->mac_base, SYN_DMA_OPERATION_MODE, SYN_DMA_OMR); +} + +/* + * syn_broadcast_enable() + * Enables Broadcast frames. + * + * When enabled Address filtering module passes all incoming broadcast frames. + */ +static inline void syn_broadcast_enable(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, SYN_MAC_FRAME_FILTER, SYN_MAC_BROADCAST); +} + +/* + * syn_multicast_enable() + * Enables Multicast frames. + * + * When enabled all multicast frames are passed. + */ +static inline void syn_multicast_enable(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, SYN_MAC_FRAME_FILTER, SYN_MAC_MULTICAST_FILTER); +} + +/* + * syn_promisc_enable() + * Enables promiscous mode. + * + * When enabled Address filter modules pass all incoming frames + * regardless of their Destination and source addresses. + */ +static inline void syn_promisc_enable(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, SYN_MAC_FRAME_FILTER, SYN_MAC_FILTER_OFF); + hal_set_reg_bits(nghd, SYN_MAC_FRAME_FILTER, + SYN_MAC_PROMISCUOUS_MODE_ON); +} + +/* + * syn_get_stats() + */ +static int syn_get_stats(struct nss_gmac_hal_dev *nghd) +{ + struct nss_dp_dev *dp_priv; + struct syn_hal_dev *shd; + struct nss_dp_gmac_stats *stats; + + BUG_ON(nghd == NULL); + + shd = (struct syn_hal_dev *)nghd; + stats = &(shd->stats); + + dp_priv = netdev_priv(nghd->netdev); + if (!dp_priv->data_plane_ops) + return -1; + + dp_priv->data_plane_ops->get_stats(dp_priv->dpc, stats); + + return 0; +} + +/* + * syn_rx_flow_control() + */ +static void syn_rx_flow_control(struct nss_gmac_hal_dev *nghd, + bool enabled) +{ + BUG_ON(nghd == NULL); + + if (enabled) + syn_set_rx_flow_ctrl(nghd); + else + syn_clear_rx_flow_ctrl(nghd); +} + +/* + * syn_tx_flow_control() + */ +static void syn_tx_flow_control(struct nss_gmac_hal_dev *nghd, + bool enabled) +{ + BUG_ON(nghd == NULL); + + if (enabled) + syn_set_tx_flow_ctrl(nghd); + else + syn_clear_tx_flow_ctrl(nghd); +} + +/* + * syn_get_max_frame_size() + */ +static int32_t syn_get_max_frame_size(struct nss_gmac_hal_dev *nghd) +{ + int ret; + uint32_t mtu; + + BUG_ON(nghd == NULL); + + ret = fal_port_max_frame_size_get(0, nghd->mac_id, &mtu); + + if (!ret) + return mtu; + + return ret; +} + +/* + * syn_set_max_frame_size() + */ +static int32_t syn_set_max_frame_size(struct nss_gmac_hal_dev *nghd, + uint32_t val) +{ + BUG_ON(nghd == NULL); + + return fal_port_max_frame_size_set(0, nghd->mac_id, val); +} + +/* + * syn_set_mac_speed() + */ +static int32_t syn_set_mac_speed(struct nss_gmac_hal_dev *nghd, + uint32_t mac_speed) +{ + struct net_device *netdev; + BUG_ON(nghd == NULL); + + netdev = nghd->netdev; + + netdev_warn(netdev, "API deprecated\n"); + return 0; +} + +/* + * syn_get_mac_speed() + */ +static uint32_t syn_get_mac_speed(struct nss_gmac_hal_dev *nghd) +{ + struct net_device *netdev; + BUG_ON(nghd == NULL); + + netdev = nghd->netdev; + + netdev_warn(netdev, "API deprecated\n"); + return 0; +} + +/* + * syn_set_duplex_mode() + */ +static void syn_set_duplex_mode(struct nss_gmac_hal_dev *nghd, + uint8_t duplex_mode) +{ + struct net_device *netdev; + BUG_ON(nghd == NULL); + + netdev = nghd->netdev; + + netdev_warn(netdev, "API deprecated\n"); +} + +/* + * syn_get_duplex_mode() + */ +static uint8_t syn_get_duplex_mode(struct nss_gmac_hal_dev *nghd) +{ + struct net_device *netdev; + BUG_ON(nghd == NULL); + + netdev = nghd->netdev; + + netdev_warn(netdev, "API deprecated\n"); + return 0; +} + +/* + * syn_get_netdev_stats() + */ +static int syn_get_netdev_stats(struct nss_gmac_hal_dev *nghd, + struct rtnl_link_stats64 *stats) +{ + struct syn_hal_dev *shd; + struct nss_dp_hal_gmac_stats *ndo_stats; + + BUG_ON(nghd == NULL); + + shd = (struct syn_hal_dev *)nghd; + ndo_stats = &(shd->stats.stats); + + /* + * Read stats from the registered dataplane. + */ + if (syn_get_stats(nghd)) + return -1; + + stats->rx_packets = ndo_stats->rx_packets; + stats->rx_bytes = ndo_stats->rx_bytes; + stats->rx_errors = ndo_stats->rx_errors; + stats->rx_dropped = ndo_stats->rx_errors; + stats->rx_length_errors = ndo_stats->rx_length_errors; + stats->rx_over_errors = ndo_stats->mmc_rx_overflow_errors; + stats->rx_crc_errors = ndo_stats->mmc_rx_crc_errors; + stats->rx_frame_errors = ndo_stats->rx_dribble_bit_errors; + stats->rx_fifo_errors = ndo_stats->fifo_overflows; + stats->rx_missed_errors = ndo_stats->rx_missed; + stats->collisions = ndo_stats->tx_collisions + ndo_stats->rx_late_collision_errors; + stats->tx_packets = ndo_stats->tx_packets; + stats->tx_bytes = ndo_stats->tx_bytes; + stats->tx_errors = ndo_stats->tx_errors; + stats->tx_dropped = ndo_stats->tx_dropped; + stats->tx_carrier_errors = ndo_stats->tx_loss_of_carrier_errors + ndo_stats->tx_no_carrier_errors; + stats->tx_fifo_errors = ndo_stats->tx_underflow_errors; + stats->tx_window_errors = ndo_stats->tx_late_collision_errors; + + return 0; +} + +/* + * syn_get_eth_stats() + */ +static int32_t syn_get_eth_stats(struct nss_gmac_hal_dev *nghd, + uint64_t *data) +{ + struct syn_hal_dev *shd; + struct nss_dp_gmac_stats *stats; + uint8_t *p = NULL; + int i; + + BUG_ON(nghd == NULL); + + shd = (struct syn_hal_dev *)nghd; + stats = &(shd->stats); + + /* + * Read stats from the registered dataplane. + */ + if (syn_get_stats(nghd)) + return -1; + + for (i = 0; i < SYN_STATS_LEN; i++) { + p = ((uint8_t *)(stats) + + syn_gstrings_stats[i].stat_offset); + data[i] = *(uint32_t *)p; + } + + return 0; +} + +/* + * syn_get_strset_count() + */ +static int32_t syn_get_strset_count(struct nss_gmac_hal_dev *nghd, + int32_t sset) +{ + struct net_device *netdev; + BUG_ON(nghd == NULL); + + netdev = nghd->netdev; + + switch (sset) { + case ETH_SS_STATS: + return SYN_STATS_LEN; + } + + netdev_dbg(netdev, "%s: Invalid string set\n", __func__); + return -EPERM; +} + +/* + * syn_get_strings() + */ +static int32_t syn_get_strings(struct nss_gmac_hal_dev *nghd, + int32_t stringset, uint8_t *data) +{ + struct net_device *netdev; + int i; + + BUG_ON(nghd == NULL); + + netdev = nghd->netdev; + + switch (stringset) { + case ETH_SS_STATS: + for (i = 0; i < SYN_STATS_LEN; i++) { + memcpy(data, syn_gstrings_stats[i].stat_string, + ETH_GSTRING_LEN); + data += ETH_GSTRING_LEN; + } + break; + + default: + netdev_dbg(netdev, "%s: Invalid string set\n", __func__); + return -EPERM; + } + + return 0; +} + +/* + * syn_send_pause_frame() + */ +static void syn_send_pause_frame(struct nss_gmac_hal_dev *nghd) +{ + BUG_ON(nghd == NULL); + + syn_send_tx_pause_frame(nghd); +} + +/* + * syn_set_mac_address() + */ +static void syn_set_mac_address(struct nss_gmac_hal_dev *nghd, + uint8_t *macaddr) +{ + uint32_t data; + + BUG_ON(nghd == NULL); + + if (!macaddr) { + netdev_warn(nghd->netdev, "macaddr is not valid.\n"); + return; + } + + data = (macaddr[5] << 8) | macaddr[4] | SYN_MAC_ADDR_HIGH_AE; + hal_write_reg(nghd->mac_base, SYN_MAC_ADDR0_HIGH, data); + data = (macaddr[3] << 24) | (macaddr[2] << 16) | (macaddr[1] << 8) + | macaddr[0]; + hal_write_reg(nghd->mac_base, SYN_MAC_ADDR0_LOW, data); +} + +/* + * syn_get_mac_address() + */ +static void syn_get_mac_address(struct nss_gmac_hal_dev *nghd, + uint8_t *macaddr) +{ + uint32_t data; + + BUG_ON(nghd == NULL); + + if (!macaddr) { + netdev_warn(nghd->netdev, "macaddr is not valid.\n"); + return; + } + + data = hal_read_reg(nghd->mac_base, SYN_MAC_ADDR0_HIGH); + macaddr[5] = (data >> 8) & 0xff; + macaddr[4] = (data) & 0xff; + + data = hal_read_reg(nghd->mac_base, SYN_MAC_ADDR0_LOW); + macaddr[3] = (data >> 24) & 0xff; + macaddr[2] = (data >> 16) & 0xff; + macaddr[1] = (data >> 8) & 0xff; + macaddr[0] = (data) & 0xff; +} + +/* + * syn_dma_init() + * Initialize settings for GMAC DMA and AXI bus. + */ +static void syn_dma_init(struct nss_gmac_hal_dev *nghd) +{ + struct net_device *ndev = nghd->netdev; + struct nss_dp_dev *dp_priv = netdev_priv(ndev); + + /* + * Enable SoC specific GMAC clocks. + */ + nss_dp_hal_clk_enable(dp_priv); + + /* + * Configure DMA registers. + */ + syn_dma_bus_mode_init(nghd); + syn_dma_axi_bus_mode_init(nghd); + syn_dma_operation_mode_init(nghd); +} + +/* + * syn_init() + */ +static void *syn_init(struct gmac_hal_platform_data *gmacpdata) +{ + struct syn_hal_dev *shd = NULL; + struct net_device *ndev = NULL; + struct nss_dp_dev *dp_priv = NULL; + struct resource *res; + + ndev = gmacpdata->netdev; + dp_priv = netdev_priv(ndev); + + res = platform_get_resource(dp_priv->pdev, IORESOURCE_MEM, 0); + if (!res) { + netdev_dbg(ndev, "Resource get failed.\n"); + return NULL; + } + + shd = (struct syn_hal_dev *)devm_kzalloc(&dp_priv->pdev->dev, + sizeof(struct syn_hal_dev), + GFP_KERNEL); + if (!shd) { + netdev_dbg(ndev, "kzalloc failed. Returning...\n"); + return NULL; + } + + shd->nghd.mac_reg_len = resource_size(res); + shd->nghd.memres = devm_request_mem_region(&dp_priv->pdev->dev, + res->start, + resource_size(res), + ndev->name); + if (!shd->nghd.memres) { + netdev_dbg(ndev, "Request mem region failed. Returning...\n"); + devm_kfree(&dp_priv->pdev->dev, shd); + return NULL; + } + + /* + * Save netdev context in syn HAL context + */ + shd->nghd.netdev = gmacpdata->netdev; + shd->nghd.mac_id = gmacpdata->macid; + shd->nghd.duplex_mode = DUPLEX_FULL; + + set_bit(__NSS_DP_RXCSUM, &dp_priv->flags); + + /* + * Populate the mac base addresses + */ + shd->nghd.mac_base = + devm_ioremap_nocache(&dp_priv->pdev->dev, res->start, + resource_size(res)); + if (!shd->nghd.mac_base) { + netdev_dbg(ndev, "ioremap fail.\n"); + devm_kfree(&dp_priv->pdev->dev, shd); + return NULL; + } + + spin_lock_init(&shd->nghd.slock); + + netdev_dbg(ndev, "ioremap OK.Size 0x%x Ndev base 0x%lx macbase 0x%px\n", + gmacpdata->reg_len, + ndev->base_addr, + shd->nghd.mac_base); + + syn_disable_interrupt_all(&shd->nghd); + syn_dma_init(&shd->nghd); + syn_ipc_offload_init(&shd->nghd); + syn_promisc_enable(&shd->nghd); + syn_broadcast_enable(&shd->nghd); + syn_multicast_enable(&shd->nghd); + syn_rx_enable(&shd->nghd); + syn_tx_enable(&shd->nghd); + + /* + * Reset MIB Stats + */ + if (fal_mib_port_flush_counters(0, shd->nghd.mac_id)) { + netdev_dbg(ndev, "MIB stats Reset fail.\n"); + } + + return (struct nss_gmac_hal_dev *)shd; +} + +/* + * syn_exit() + */ +static void syn_exit(struct nss_gmac_hal_dev *nghd) +{ + struct nss_dp_dev *dp_priv = NULL; + + dp_priv = netdev_priv(nghd->netdev); + devm_iounmap(&dp_priv->pdev->dev, + (void *)nghd->mac_base); + devm_release_mem_region(&dp_priv->pdev->dev, + (nghd->memres)->start, + nghd->mac_reg_len); + + nghd->memres = NULL; + nghd->mac_base = NULL; +} + +struct nss_gmac_hal_ops syn_hal_ops = { + .init = &syn_init, + .start = NULL, + .stop = NULL, + .exit = &syn_exit, + .setmacaddr = &syn_set_mac_address, + .getmacaddr = &syn_get_mac_address, + .rxflowcontrol = &syn_rx_flow_control, + .txflowcontrol = &syn_tx_flow_control, + .setspeed = &syn_set_mac_speed, + .getspeed = &syn_get_mac_speed, + .setduplex = &syn_set_duplex_mode, + .getduplex = &syn_get_duplex_mode, + .setmaxframe = &syn_set_max_frame_size, + .getmaxframe = &syn_get_max_frame_size, + .getndostats = &syn_get_netdev_stats, + .getssetcount = &syn_get_strset_count, + .getstrings = &syn_get_strings, + .getethtoolstats = &syn_get_eth_stats, + .sendpause = &syn_send_pause_frame, +}; diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/gmac/syn_reg.h b/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/gmac/syn_reg.h new file mode 100644 index 000000000..aba916e4e --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/gmac/syn_reg.h @@ -0,0 +1,531 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __SYN_REG_H__ +#define __SYN_REG_H__ + +/* + * MAC register offset + */ +#define SYN_MAC_CONFIGURATION 0x0000 +#define SYN_MAC_FRAME_FILTER 0x0004 +#define SYN_MAC_FLOW_CONTROL 0x0018 +#define SYN_VLAN_TAG 0x001C +#define SYN_VERSION 0x0020 +#define SYN_DEBUG 0x0024 +#define SYN_REMOTE_WAKE_UP_FRAME_FILTER 0x0028 +#define SYN_PMT_CONTROL_STATUS 0x002C +#define SYN_LPI_CONTROL_STATUS 0x0030 +#define SYN_LPI_TIMERS_CONTROL 0x0034 +#define SYN_INTERRUPT_STATUS 0x0038 +#define SYN_INTERRUPT_MASK 0x003C + +/* + * MAC address register offset + */ +#define SYN_MAC_ADDR0_HIGH 0x0040 +#define SYN_MAC_ADDR0_LOW 0x0044 +#define SYN_MAC_ADDR1_HIGH 0x0048 +#define SYN_MAC_ADDR1_LOW 0x004C +#define SYN_MAC_ADDR2_HIGH 0x0050 +#define SYN_MAC_ADDR2_LOW 0x0054 +#define SYN_MAC_ADDR3_HIGH 0x0058 +#define SYN_MAC_ADDR3_LOW 0x005C +#define SYN_MAC_ADDR4_HIGH 0x0060 +#define SYN_MAC_ADDR4_LOW 0x0064 + +/* + * Watchdog timeout register + */ +#define SYN_WDOG_TIMEOUT 0x00DC + +/* + * Mac Management Counters (MMC) register offset + */ +#define SYN_MMC_CONTROL 0x0100 +#define SYN_MMC_RX_INTERRUPT 0x0104 +#define SYN_MMC_TX_INTERRUPT 0x0108 +#define SYN_MMC_RX_INTERRUPT_MASK 0x010C +#define SYN_MMC_TX_INTERRUPT_MASK 0x0110 +#define SYN_MMC_IPC_RX_INTR_MASK 0x0200 + +/* + * DMA Register offset + */ +#define SYN_DMA_BUS_MODE 0x1000 +#define SYN_DMA_TX_POLL_DEMAND 0x1004 +#define SYN_DMA_RX_POLL_DEMAND 0x1008 +#define SYN_DMA_RX_DESCRIPTOR_LIST_ADDRESS 0x100C +#define SYN_DMA_TX_DESCRIPTOR_LIST_ADDRESS 0x1010 +#define SYN_DMA_STATUS 0x1014 +#define SYN_DMA_OPERATION_MODE 0x1018 +#define SYN_DMA_INT_ENABLE 0x101C +#define SYN_DMA_MISSED_FRAME_AND_BUFF_OVERFLOW_COUNTER 0x1020 +#define SYN_DMA_RX_INTERRUPT_WATCHDOG_TIMER 0x1024 +#define SYN_DMA_AXI_BUS_MODE 0x1028 +#define SYN_DMA_AHB_OR_AXI_STATUS 0x102C +#define SYN_DMA_CURRENT_HOST_TX_DESCRIPTOR 0x1048 +#define SYN_DMA_CURRENT_HOST_RX_DESCRIPTOR 0x104C +#define SYN_DMA_CURRENT_HOST_TX_BUFFER_ADDRESS 0x1050 +#define SYN_DMA_CURRENT_HOST_RX_BUFFER_ADDRESS 0x1054 + +/* + * Optional HW feature register + */ +#define SYN_HW_FEATURE 0x1058 + +/* + * Register Bit Definitions + */ + +/* + * SYN_MAC_CONFIGURATION = 0x0000, MAC config Register Layout + */ +enum syn_mac_config_reg { + SYN_MAC_TWOKPE = 0x08000000, /* Support for 2K packets */ + SYN_MAC_TWOKPE_ENABLE = 0x08000000, + SYN_MAC_TWOKPE_DISABLE = 0x00000000, + SYN_MAC_CST = 0x02000000, /* (CST) CRC Stripping for Type Frames */ + SYN_MAC_CST_ENABLE = 0x02000000, + SYN_MAC_CST_DISABLE = 0x02000000, + SYN_MAC_TC = 0x01000000, /* (TC) Transmit configuration */ + SYN_MAC_WATCHDOG = 0x00800000, + SYN_MAC_WATCHDOG_ENABLE = 0x00000000, /* Enable watchdog timer */ + SYN_MAC_WATCHDOG_DISABLE = 0x00800000, /* (WD)Disable watchdog timer on Rx */ + SYN_MAC_JABBER = 0x00400000, + SYN_MAC_JABBER_ENABLE = 0x00000000, /* Enable jabber timer */ + SYN_MAC_JABBER_DISABLE = 0x00400000, /* (JD)Disable jabber timer on Tx */ + SYN_MAC_FRAME_BURST = 0x00200000, + SYN_MAC_FRAME_BURST_ENABLE = 0x00200000, /* (BE)Enable frame bursting + during Tx */ + SYN_MAC_FRAME_BURST_DISABLE = 0x00000000, /* Disable frame bursting */ + SYN_MAC_JUMBO_FRAME = 0x00100000, + SYN_MAC_JUMBO_FRAME_ENABLE = 0x00100000, /* (JE)Enable jumbo frame for Rx */ + SYN_MAC_JUMBO_FRAME_DISABLE = 0x00000000, /* Disable jumbo frame */ + SYN_MAC_INTER_FRAME_GAP7 = 0x000E0000, /* (IFG) Config7 - 40bit times */ + SYN_MAC_INTER_FRAME_GAP6 = 0x000C0000, /* (IFG) Config6 - 48bit times */ + SYN_MAC_INTER_FRAME_GAP5 = 0x000A0000, /* (IFG) Config5 - 56bit times */ + SYN_MAC_INTER_FRAME_GAP4 = 0x00080000, /* (IFG) Config4 - 64bit times */ + SYN_MAC_INTER_FRAME_GAP3 = 0x00060000, /* (IFG) Config3 - 72bit times */ + SYN_MAC_INTER_FRAME_GAP2 = 0x00040000, /* (IFG) Config2 - 80bit times */ + SYN_MAC_INTER_FRAME_GAP1 = 0x00020000, /* (IFG) Config1 - 88bit times */ + SYN_MAC_INTER_FRAME_GAP0 = 0x00000000, /* (IFG) Config0 - 96bit times */ + SYN_MAC_DISABLE_CRS = 0x00010000, /* (DCRS) Disable Carrier Sense During Transmission */ + SYN_MAC_MII_GMII = 0x00008000, + SYN_MAC_SELECT_MII = 0x00008000, /* (PS)Port Select-MII mode */ + SYN_MAC_SELECT_GMII = 0x00000000, /* GMII mode */ + SYN_MAC_FE_SPEED100 = 0x00004000, /* (FES)Fast Ethernet speed 100Mbps */ + SYN_MAC_FE_SPEED = 0x00004000, /* (FES)Fast Ethernet speed 100Mbps */ + SYN_MAC_FE_SPEED10 = 0x00000000, /* (FES)Fast Ethernet speed 10Mbps */ + SYN_MAC_RX_OWN = 0x00002000, + SYN_MAC_DISABLE_RX_OWN = 0x00002000, /* (DO)Disable receive own packets */ + SYN_MAC_ENABLE_RX_OWN = 0x00000000, /* Enable receive own packets */ + SYN_MAC_LOOPBACK = 0x00001000, + SYN_MAC_LOOPBACK_ON = 0x00001000, /* (LM)Loopback mode for GMII/MII */ + SYN_MAC_LOOPBACK_OFF = 0x00000000, /* Normal mode */ + SYN_MAC_DUPLEX = 0x00000800, + SYN_MAC_FULL_DUPLEX = 0x00000800, /* (DM)Full duplex mode */ + SYN_MAC_HALF_DUPLEX = 0x00000000, /* Half duplex mode */ + SYN_MAC_RX_IPC_OFFLOAD = 0x00000400, /* IPC checksum offload */ + SYN_MAC_RX_IPC_OFFLOAD_ENABLE = 0x00000400, + SYN_MAC_RX_IPC_OFFLOAD_DISABLE = 0x00000000, + SYN_MAC_RETRY = 0x00000200, + SYN_MAC_RETRY_DISABLE = 0x00000200, /* (DR)Disable Retry */ + SYN_MAC_RETRY_ENABLE = 0x00000000, /* Enable retransmission as per BL */ + SYN_MAC_LINK_UP = 0x00000100, /* (LUD)Link UP */ + SYN_MAC_LINK_DOWN = 0x00000100, /* Link Down */ + SYN_MAC_PAD_CRC_STRIP = 0x00000080, + SYN_MAC_PAD_CRC_STRIP_ENABLE = 0x00000080, /* (ACS) Automatic Pad/Crc strip enable */ + SYN_MAC_PAD_CRC_STRIP_DISABLE = 0x00000000, /* Automatic Pad/Crc stripping disable */ + SYN_MAC_BACKOFF_LIMIT = 0x00000060, + SYN_MAC_BACKOFF_LIMIT3 = 0x00000060, /* (BL)Back-off limit in HD mode */ + SYN_MAC_BACKOFF_LIMIT2 = 0x00000040, + SYN_MAC_BACKOFF_LIMIT1 = 0x00000020, + SYN_MAC_BACKOFF_LIMIT0 = 0x00000000, + SYN_MAC_DEFERRAL_CHECK = 0x00000010, + SYN_MAC_DEFERRAL_CHECK_ENABLE = 0x00000010, /* (DC)Deferral check enable in HD mode */ + SYN_MAC_DEFERRAL_CHECK_DISABLE = 0x00000000, /* Deferral check disable */ + SYN_MAC_TX = 0x00000008, + SYN_MAC_TX_ENABLE = 0x00000008, /* (TE)Transmitter enable */ + SYN_MAC_TX_DISABLE = 0x00000000, /* Transmitter disable */ + SYN_MAC_RX = 0x00000004, + SYN_MAC_RX_ENABLE = 0x00000004, /* (RE)Receiver enable */ + SYN_MAC_RX_DISABLE = 0x00000000, /* Receiver disable */ + SYN_MAC_PRELEN_RESERVED = 0x00000003, /* Preamble Length for Transmit Frames */ + SYN_MAC_PRELEN_3B = 0x00000002, + SYN_MAC_PRELEN_5B = 0x00000001, + SYN_MAC_PRELEN_7B = 0x00000000, +}; + +/* + * SYN_MAC_FRAME_FILTER = 0x0004, Mac frame filtering controls Register + */ +enum syn_mac_frame_filter_reg { + SYN_MAC_FILTER = 0x80000000, + SYN_MAC_FILTER_OFF = 0x80000000, /* (RA)Receive all incoming packets */ + SYN_MAC_FILTER_ON = 0x00000000, /* Receive filtered pkts only */ + SYN_MAC_HASH_PERFECT_FILTER = 0x00000400, /* Hash or Perfect Filter enable */ + SYN_MAC_SRC_ADDR_FILTER = 0x00000200, + SYN_MAC_SRC_ADDR_FILTER_ENABLE = 0x00000200, /* (SAF)Source Address Filter enable */ + SYN_MAC_SRC_ADDR_FILTER_DISABLE = 0x00000000, + SYN_MAC_SRC_INVA_ADDR_FILTER = 0x00000100, + SYN_MAC_SRC_INV_ADDR_FILTER_EN = 0x00000100, /* (SAIF)Inv Src Addr Filter enable */ + SYN_MAC_SRC_INV_ADDR_FILTER_DIS = 0x00000000, + SYN_MAC_PASS_CONTROL = 0x000000C0, + SYN_MAC_PASS_CONTROL3 = 0x000000C0, /* (PCF)Forwards ctrl frames that pass AF */ + SYN_MAC_PASS_CONTROL2 = 0x00000080, /* Forwards all control frames + even if they fail the AF */ + SYN_MAC_PASS_CONTROL1 = 0x00000040, /* Forwards all control frames except + PAUSE control frames to application + even if they fail the AF */ + SYN_MAC_PASS_CONTROL0 = 0x00000000, /* Don't pass control frames */ + SYN_MAC_BROADCAST = 0x00000020, + SYN_MAC_BROADCAST_DISABLE = 0x00000020, /* (DBF)Disable Rx of broadcast frames */ + SYN_MAC_BROADCAST_ENABLE = 0x00000000, /* Enable broadcast frames */ + SYN_MAC_MULTICAST_FILTER = 0x00000010, + SYN_MAC_MULTICAST_FILTER_OFF = 0x00000010, /* (PM) Pass all multicast packets */ + SYN_MAC_MULTICAST_FILTER_ON = 0x00000000, /* Pass filtered multicast packets */ + SYN_MAC_DEST_ADDR_FILTER = 0x00000008, + SYN_MAC_DEST_ADDR_FILTER_INV = 0x00000008, /* (DAIF)Inverse filtering for DA */ + SYN_MAC_DEST_ADDR_FILTER_NOR = 0x00000000, /* Normal filtering for DA */ + SYN_MAC_MCAST_HASH_FILTER = 0x00000004, + SYN_MAC_MCAST_HASH_FILTER_ON = 0x00000004, /* (HMC)perfom multicast hash filtering */ + SYN_MAC_MCAST_HASH_FILTER_OFF = 0x00000000, /* perfect filtering only */ + SYN_MAC_UCAST_HASH_FILTER = 0x00000002, + SYN_MAC_UCAST_HASH_FILTER_ON = 0x00000002, /* (HUC)Unicast Hash filtering only */ + SYN_MAC_UCAST_HASH_FILTER_OFF = 0x00000000, /* perfect filtering only */ + SYN_MAC_PROMISCUOUS_MODE = 0x00000001, + SYN_MAC_PROMISCUOUS_MODE_ON = 0x00000001, /* Receive all frames */ + SYN_MAC_PROMISCUOUS_MODE_OFF = 0x00000000, /* Receive filtered packets only */ +}; + +/* + * SYN_MAC_FLOW_CONTROL = 0x0018, Flow control Register Layout + */ +enum syn_mac_flow_control_reg { + SYN_MAC_FC_PAUSE_TIME_MASK = 0xFFFF0000, /* (PT) PAUSE TIME field + in the control frame */ + SYN_MAC_FC_PAUSE_TIME_SHIFT = 16, + SYN_MAC_FC_PAUSE_LOW_THRESH = 0x00000030, + SYN_MAC_FC_PAUSE_LOW_THRESH3 = 0x00000030, /* (PLT)thresh for pause + tmr 256 slot time */ + SYN_MAC_FC_PAUSE_LOW_THRESH2 = 0x00000020, /* 144 slot time */ + SYN_MAC_FC_PAUSE_LOW_THRESH1 = 0x00000010, /* 28 slot time */ + SYN_MAC_FC_PAUSE_LOW_THRESH0 = 0x00000000, /* 4 slot time */ + SYN_MAC_FC_UNICAST_PAUSE_FRAME = 0x00000008, + SYN_MAC_FC_UNICAST_PAUSE_FRAME_ON = 0x00000008, /* (UP)Detect pause frame + with unicast addr. */ + SYN_MAC_FC_UNICAST_PAUSE_FRAME_OFF = 0x00000000,/* Detect only pause frame + with multicast addr. */ + SYN_MAC_FC_RX_FLOW_CONTROL = 0x00000004, + SYN_MAC_FC_RX_FLOW_CONTROL_ENABLE = 0x00000004, /* (RFE)Enable Rx flow control */ + SYN_MAC_FC_RX_FLOW_CONTROL_DISABLE = 0x00000000,/* Disable Rx flow control */ + SYN_MAC_FC_TX_FLOW_CONTROL = 0x00000002, + SYN_MAC_FC_TX_FLOW_CONTROL_ENABLE = 0x00000002, /* (TFE)Enable Tx flow control */ + SYN_MAC_FC_TX_FLOW_CONTROL_DISABLE = 0x00000000,/* Disable flow control */ + SYN_MAC_FC_FLOW_CONTROL_BACK_PRESSURE = 0x00000001, + SYN_MAC_FC_SEND_PAUSE_FRAME = 0x00000001, /* (FCB/PBA)send pause frm/Apply + back pressure */ +}; + +/* + * SYN_MAC_ADDR_HIGH Register + */ +enum syn_mac_addr_high { + SYN_MAC_ADDR_HIGH_AE = 0x80000000, +}; + +/* + * SYN_DMA_BUS_MODE = 0x0000, CSR0 - Bus Mode + */ +enum syn_dma_bus_mode_reg { + SYN_DMA_FIXED_BURST_ENABLE = 0x00010000, /* (FB)Fixed Burst SINGLE, INCR4, + INCR8 or INCR16 */ + SYN_DMA_FIXED_BURST_DISABLE = 0x00000000, /* SINGLE, INCR */ + SYN_DMA_TX_PRIORITY_RATIO11 = 0x00000000, /* (PR)TX:RX DMA priority ratio 1:1 */ + SYN_DMA_TX_PRIORITY_RATIO21 = 0x00004000, /* (PR)TX:RX DMA priority ratio 2:1 */ + SYN_DMA_TX_PRIORITY_RATIO31 = 0x00008000, /* (PR)TX:RX DMA priority ratio 3:1 */ + SYN_DMA_TX_PRIORITY_RATIO41 = 0x0000C000, /* (PR)TX:RX DMA priority ratio 4:1 */ + SYN_DMA_ADDRESS_ALIGNED_BEATS = 0x02000000, /* Address Aligned beats */ + SYN_DMA_BURST_LENGTHX8 = 0x01000000, /* When set mutiplies the PBL by 8 */ + SYN_DMA_BURST_LENGTH256 = 0x01002000, /* (dma_burst_lengthx8 | + dma_burst_length32) = 256 */ + SYN_DMA_BURST_LENGTH128 = 0x01001000, /* (dma_burst_lengthx8 | + dma_burst_length16) = 128 */ + SYN_DMA_BURST_LENGTH64 = 0x01000800, /* (dma_burst_lengthx8 | + dma_burst_length8) = 64 */ + /* (PBL) programmable burst length */ + SYN_DMA_BURST_LENGTH32 = 0x00002000, /* Dma burst length = 32 */ + SYN_DMA_BURST_LENGTH16 = 0x00001000, /* Dma burst length = 16 */ + SYN_DMA_BURST_LENGTH8 = 0x00000800, /* Dma burst length = 8 */ + SYN_DMA_BURST_LENGTH4 = 0x00000400, /* Dma burst length = 4 */ + SYN_DMA_BURST_LENGTH2 = 0x00000200, /* Dma burst length = 2 */ + SYN_DMA_BURST_LENGTH1 = 0x00000100, /* Dma burst length = 1 */ + SYN_DMA_BURST_LENGTH0 = 0x00000000, /* Dma burst length = 0 */ + + SYN_DMA_DESCRIPTOR8_WORDS = 0x00000080, /* Enh Descriptor works 1=> + 8 word descriptor */ + SYN_DMA_DESCRIPTOR4_WORDS = 0x00000000, /* Enh Descriptor works 0=> + 4 word descriptor */ + SYN_DMA_DESCRIPTOR_SKIP16 = 0x00000040, /* (DSL)Descriptor skip length (no.of dwords) */ + SYN_DMA_DESCRIPTOR_SKIP8 = 0x00000020, /* between two unchained descriptors */ + SYN_DMA_DESCRIPTOR_SKIP4 = 0x00000010, + SYN_DMA_DESCRIPTOR_SKIP2 = 0x00000008, + SYN_DMA_DESCRIPTOR_SKIP1 = 0x00000004, + SYN_DMA_DESCRIPTOR_SKIP0 = 0x00000000, + SYN_DMA_ARBIT_RR = 0x00000000, /* (DA) DMA RR arbitration */ + SYN_DMA_ARBIT_PR = 0x00000002, /* Rx has priority over Tx */ + SYN_DMA_RESET_ON = 0x00000001, /* (SWR)Software Reset DMA engine */ + SYN_DMA_RESET_OFF = 0x00000000, +}; + +/* + * SYN_DMA_STATUS = 0x0014, CSR5 - Dma status Register + */ +enum syn_dma_status_reg { + SYN_DMA_GMAC_PMT_INTR = 0x10000000, /* (GPI)Gmac subsystem interrupt */ + SYN_DMA_GMAC_MMC_INTR = 0x08000000, /* (GMI)Gmac MMC subsystem interrupt */ + SYN_DMA_GMAC_LINE_INTF_INTR = 0x04000000, /* Line interface interrupt */ + SYN_DMA_ERROR_BIT2 = 0x02000000, /* (EB)Error bits 0-data buffer, 1-desc access */ + SYN_DMA_ERROR_BIT1 = 0x01000000, /* (EB)Error bits 0-write trnsf, 1-read transfer */ + SYN_DMA_ERROR_BIT0 = 0x00800000, /* (EB)Error bits 0-Rx DMA, 1-Tx DMA */ + SYN_DMA_TX_STATE = 0x00700000, /* (TS)Transmit process state */ + SYN_DMA_TX_STOPPED = 0x00000000, /* Stopped - Reset or Stop Tx Command issued */ + SYN_DMA_TX_FETCHING = 0x00100000, /* Running - fetching the Tx descriptor */ + SYN_DMA_TX_WAITING = 0x00200000, /* Running - waiting for status */ + SYN_DMA_TX_READING = 0x00300000, /* Running - reading the data from host memory */ + SYN_DMA_TX_SUSPENDED = 0x00600000, /* Suspended - Tx Descriptor unavailabe */ + SYN_DMA_TX_CLOSING = 0x00700000, /* Running - closing Rx descriptor */ + SYN_DMA_RX_STATE = 0x000E0000, /* (RS)Receive process state */ + SYN_DMA_RX_STOPPED = 0x00000000, /* Stopped - Reset or Stop Rx Command issued */ + SYN_DMA_RX_FETCHING = 0x00020000, /* Running - fetching the Rx descriptor */ + SYN_DMA_RX_WAITING = 0x00060000, /* Running - waiting for packet */ + SYN_DMA_RX_SUSPENDED = 0x00080000, /* Suspended - Rx Descriptor unavailable */ + SYN_DMA_RX_CLOSING = 0x000A0000, /* Running - closing descriptor */ + SYN_DMA_RX_QUEUING = 0x000E0000, /* Running - queuing the receive frame into host memory */ + SYN_DMA_INT_NORMAL = 0x00010000, /* (NIS)Normal interrupt summary */ + SYN_DMA_INT_ABNORMAL = 0x00008000, /* (AIS)Abnormal interrupt summary */ + SYN_DMA_INT_EARLY_RX = 0x00004000, /* Early receive interrupt (Normal) */ + SYN_DMA_INT_BUS_ERROR = 0x00002000, /* Fatal bus error (Abnormal) */ + SYN_DMA_INT_EARLY_TX = 0x00000400, /* Early transmit interrupt (Abnormal) */ + SYN_DMA_INT_RX_WDOG_TO = 0x00000200, /* Receive Watchdog Timeout (Abnormal) */ + SYN_DMA_INT_RX_STOPPED = 0x00000100, /* Receive process stopped (Abnormal) */ + SYN_DMA_INT_RX_NO_BUFFER = 0x00000080, /* RX buffer unavailable (Abnormal) */ + SYN_DMA_INT_RX_COMPLETED = 0x00000040, /* Completion of frame RX (Normal) */ + SYN_DMA_INT_TX_UNDERFLOW = 0x00000020, /* Transmit underflow (Abnormal) */ + SYN_DMA_INT_RCV_OVERFLOW = 0x00000010, /* RX Buffer overflow interrupt */ + SYN_DMA_INT_TX_JABBER_TO = 0x00000008, /* TX Jabber Timeout (Abnormal) */ + SYN_DMA_INT_TX_NO_BUFFER = 0x00000004, /* TX buffer unavailable (Normal) */ + SYN_DMA_INT_TX_STOPPED = 0x00000002, /* TX process stopped (Abnormal) */ + SYN_DMA_INT_TX_COMPLETED = 0x00000001, /* Transmit completed (Normal) */ +}; + +/* + * SYN_DMA_OPERATION_MODE = 0x0018, CSR6 - Dma Operation Mode Register + */ +enum syn_dma_operation_mode_reg { + SYN_DMA_DISABLE_DROP_TCP_CS = 0x04000000, /* (DT) Dis. drop. of tcp/ip + CS error frames */ + SYN_DMA_RX_STORE_AND_FORWARD = 0x02000000, /* Rx (SF)Store and forward */ + SYN_DMA_RX_FRAME_FLUSH = 0x01000000, /* Disable Receive Frame Flush*/ + SYN_DMA_TX_STORE_AND_FORWARD = 0x00200000, /* Tx (SF)Store and forward */ + SYN_DMA_FLUSH_TX_FIFO = 0x00100000, /* (FTF)Tx FIFO controller + is reset to default */ + SYN_DMA_TX_THRESH_CTRL = 0x0001C000, /* (TTC)Controls thre Thresh of + MTL tx Fifo */ + SYN_DMA_TX_THRESH_CTRL16 = 0x0001C000, /* (TTC)Controls thre Thresh of + MTL tx Fifo 16 */ + SYN_DMA_TX_THRESH_CTRL24 = 0x00018000, /* (TTC)Controls thre Thresh of + MTL tx Fifo 24 */ + SYN_DMA_TX_THRESH_CTRL32 = 0x00014000, /* (TTC)Controls thre Thresh of + MTL tx Fifo 32 */ + SYN_DMA_TX_THRESH_CTRL40 = 0x00010000, /* (TTC)Controls thre Thresh of + MTL tx Fifo 40 */ + SYN_DMA_TX_THRESH_CTRL256 = 0x0000c000, /* (TTC)Controls thre Thresh of + MTL tx Fifo 256 */ + SYN_DMA_TX_THRESH_CTRL192 = 0x00008000, /* (TTC)Controls thre Thresh of + MTL tx Fifo 192 */ + SYN_DMA_TX_THRESH_CTRL128 = 0x00004000, /* (TTC)Controls thre Thresh of + MTL tx Fifo 128 */ + SYN_DMA_TX_THRESH_CTRL64 = 0x00000000, /* (TTC)Controls thre Thresh of + MTL tx Fifo 64 */ + SYN_DMA_TX_START = 0x00002000, /* (ST)Start/Stop transmission*/ + SYN_DMA_RX_FLOW_CTRL_DEACT = 0x00401800, /* (RFD)Rx flow control + deact. Threshold */ + SYN_DMA_RX_FLOW_CTRL_DEACT1K = 0x00000000, /* (RFD)Rx flow control + deact. Threshold (1kbytes) */ + SYN_DMA_RX_FLOW_CTRL_DEACT2K = 0x00000800, /* (RFD)Rx flow control + deact. Threshold (2kbytes) */ + SYN_DMA_RX_FLOW_CTRL_DEACT3K = 0x00001000, /* (RFD)Rx flow control + deact. Threshold (3kbytes) */ + SYN_DMA_RX_FLOW_CTRL_DEACT4K = 0x00001800, /* (RFD)Rx flow control + deact. Threshold (4kbytes) */ + SYN_DMA_RX_FLOW_CTRL_DEACT5K = 0x00400000, /* (RFD)Rx flow control + deact. Threshold (4kbytes) */ + SYN_DMA_RX_FLOW_CTRL_DEACT6K = 0x00400800, /* (RFD)Rx flow control + deact. Threshold (4kbytes) */ + SYN_DMA_RX_FLOW_CTRL_DEACT7K = 0x00401000, /* (RFD)Rx flow control + deact. Threshold (4kbytes) */ + SYN_DMA_RX_FLOW_CTRL_ACT = 0x00800600, /* (RFA)Rx flow control + Act. Threshold */ + SYN_DMA_RX_FLOW_CTRL_ACT1K = 0x00000000, /* (RFA)Rx flow control + Act. Threshold (1kbytes) */ + SYN_DMA_RX_FLOW_CTRL_ACT2K = 0x00000200, /* (RFA)Rx flow control + Act. Threshold (2kbytes) */ + SYN_DMA_RX_FLOW_CTRL_ACT3K = 0x00000400, /* (RFA)Rx flow control + Act. Threshold (3kbytes) */ + SYN_DMA_RX_FLOW_CTRL_ACT4K = 0x00000600, /* (RFA)Rx flow control + Act. Threshold (4kbytes) */ + SYN_DMA_RX_FLOW_CTRL_ACT5K = 0x00800000, /* (RFA)Rx flow control + Act. Threshold (5kbytes) */ + SYN_DMA_RX_FLOW_CTRL_ACT6K = 0x00800200, /* (RFA)Rx flow control + Act. Threshold (6kbytes) */ + SYN_DMA_RX_FLOW_CTRL_ACT7K = 0x00800400, /* (RFA)Rx flow control + Act. Threshold (7kbytes) */ + SYN_DMA_RX_THRESH_CTRL = 0x00000018, /* (RTC)Controls thre + Thresh of MTL rx Fifo */ + SYN_DMA_RX_THRESH_CTRL64 = 0x00000000, /* (RTC)Controls thre + Thresh of MTL tx Fifo 64 */ + SYN_DMA_RX_THRESH_CTRL32 = 0x00000008, /* (RTC)Controls thre + Thresh of MTL tx Fifo 32 */ + SYN_DMA_RX_THRESH_CTRL96 = 0x00000010, /* (RTC)Controls thre + Thresh of MTL tx Fifo 96 */ + SYN_DMA_RX_THRESH_CTRL128 = 0x00000018, /* (RTC)Controls thre + Thresh of MTL tx Fifo 128 */ + SYN_DMA_EN_HW_FLOW_CTRL = 0x00000100, /* (EFC)Enable HW flow control*/ + SYN_DMA_DIS_HW_FLOW_CTRL = 0x00000000, /* Disable HW flow control */ + SYN_DMA_FWD_ERROR_FRAMES = 0x00000080, /* (FEF)Forward error frames */ + SYN_DMA_FWD_UNDER_SZ_FRAMES = 0x00000040, /* (FUF)Forward undersize + frames */ + SYN_DMA_TX_SECOND_FRAME = 0x00000004, /* (OSF)Operate on 2nd frame */ + SYN_DMA_RX_START = 0x00000002, /* (SR)Start/Stop reception */ +}; + +/* + * SYN_DMA_INT_ENABLE = 0x101C, CSR7 - Interrupt enable Register Layout + */ +enum syn_dma_interrupt_reg { + SYN_DMA_IE_NORMAL = SYN_DMA_INT_NORMAL, /* Normal interrupt enable */ + SYN_DMA_IE_ABNORMAL = SYN_DMA_INT_ABNORMAL, /* Abnormal interrupt enable */ + SYN_DMA_IE_EARLY_RX = SYN_DMA_INT_EARLY_RX, /* Early RX interrupt enable */ + SYN_DMA_IE_BUS_ERROR = SYN_DMA_INT_BUS_ERROR, /* Fatal bus error enable */ + SYN_DMA_IE_EARLY_TX = SYN_DMA_INT_EARLY_TX, /* Early TX interrupt enable */ + SYN_DMA_IE_RX_WDOG_TO = SYN_DMA_INT_RX_WDOG_TO, /* RX Watchdog Timeout enable */ + SYN_DMA_IE_RX_STOPPED = SYN_DMA_INT_RX_STOPPED, /* RX process stopped enable */ + SYN_DMA_IE_RX_NO_BUFFER = SYN_DMA_INT_RX_NO_BUFFER, + /* Receive buffer unavailable enable */ + SYN_DMA_IE_RX_COMPLETED = SYN_DMA_INT_RX_COMPLETED, + /* Completion of frame reception enable */ + SYN_DMA_IE_TX_UNDERFLOW = SYN_DMA_INT_TX_UNDERFLOW, + /* TX underflow enable */ + SYN_DMA_IE_RX_OVERFLOW = SYN_DMA_INT_RCV_OVERFLOW, + /* RX Buffer overflow interrupt */ + SYN_DMA_IE_TX_JABBER_TO = SYN_DMA_INT_TX_JABBER_TO, + /* TX Jabber Timeout enable */ + SYN_DMA_IE_TX_NO_BUFFER = SYN_DMA_INT_TX_NO_BUFFER, + /* TX buffer unavailable enable */ + SYN_DMA_IE_TX_STOPPED = SYN_DMA_INT_TX_STOPPED, + /* TX process stopped enable */ + SYN_DMA_IE_TX_COMPLETED = SYN_DMA_INT_TX_COMPLETED, + /* TX completed enable */ +}; + +/* + * SYN_DMA_AXI_BUS_MODE = 0x1028 + */ +enum syn_dma_axi_bus_mode_reg { + SYN_DMA_EN_LPI = 0x80000000, + SYN_DMA_LPI_XIT_FRM = 0x40000000, + SYN_DMA_WR_OSR_NUM_REQS16 = 0x00F00000, + SYN_DMA_WR_OSR_NUM_REQS8 = 0x00700000, + SYN_DMA_WR_OSR_NUM_REQS4 = 0x00300000, + SYN_DMA_WR_OSR_NUM_REQS2 = 0x00100000, + SYN_DMA_WR_OSR_NUM_REQS1 = 0x00000000, + SYN_DMA_RD_OSR_NUM_REQS16 = 0x000F0000, + SYN_DMA_RD_OSR_NUM_REQS8 = 0x00070000, + SYN_DMA_RD_OSR_NUM_REQS4 = 0x00030000, + SYN_DMA_RD_OSR_NUM_REQS2 = 0x00010000, + SYN_DMA_RD_OSR_NUM_REQS1 = 0x00000000, + SYN_DMA_ONEKBBE = 0x00002000, + SYN_DMA_AXI_AAL = 0x00001000, + SYN_DMA_AXI_BLEN256 = 0x00000080, + SYN_DMA_AXI_BLEN128 = 0x00000040, + SYN_DMA_AXI_BLEN64 = 0x00000020, + SYN_DMA_AXI_BLEN32 = 0x00000010, + SYN_DMA_AXI_BLEN16 = 0x00000008, + SYN_DMA_AXI_BLEN8 = 0x00000004, + SYN_DMA_AXI_BLEN4 = 0x00000002, + SYN_DMA_UNDEFINED = 0x00000001, +}; + +/* + * Values to initialize DMA registers + */ +enum syn_dma_init_values { + /* + * Interrupt groups + */ + SYN_DMA_INT_ERROR_MASK = SYN_DMA_INT_BUS_ERROR, /* Error */ + SYN_DMA_INT_RX_ABN_MASK = SYN_DMA_INT_RX_NO_BUFFER, /* RX abnormal intr */ + SYN_DMA_INT_RX_NORM_MASK = SYN_DMA_INT_RX_COMPLETED, /* RXnormal intr */ + SYN_DMA_INT_RX_STOPPED_MASK = SYN_DMA_INT_RX_STOPPED, /* RXstopped */ + SYN_DMA_INT_TX_ABN_MASK = SYN_DMA_INT_TX_UNDERFLOW, /* TX abnormal intr */ + SYN_DMA_INT_TX_NORM_MASK = SYN_DMA_INT_TX_COMPLETED, /* TX normal intr */ + SYN_DMA_INT_TX_STOPPED_MASK = SYN_DMA_INT_TX_STOPPED, /* TX stopped */ + + SYN_DMA_BUS_MODE_INIT = SYN_DMA_FIXED_BURST_ENABLE | SYN_DMA_BURST_LENGTH8 + | SYN_DMA_DESCRIPTOR_SKIP2 | SYN_DMA_RESET_OFF, + + SYN_DMA_BUS_MODE_VAL = SYN_DMA_BURST_LENGTH32 + | SYN_DMA_BURST_LENGTHX8 | SYN_DMA_DESCRIPTOR_SKIP0 + | SYN_DMA_DESCRIPTOR8_WORDS | SYN_DMA_ARBIT_PR | SYN_DMA_ADDRESS_ALIGNED_BEATS, + + SYN_DMA_OMR = SYN_DMA_TX_STORE_AND_FORWARD | SYN_DMA_RX_STORE_AND_FORWARD + | SYN_DMA_RX_THRESH_CTRL128 | SYN_DMA_TX_SECOND_FRAME, + + SYN_DMA_INT_EN = SYN_DMA_IE_NORMAL | SYN_DMA_IE_ABNORMAL | SYN_DMA_INT_ERROR_MASK + | SYN_DMA_INT_RX_ABN_MASK | SYN_DMA_INT_RX_NORM_MASK + | SYN_DMA_INT_RX_STOPPED_MASK | SYN_DMA_INT_TX_ABN_MASK + | SYN_DMA_INT_TX_NORM_MASK | SYN_DMA_INT_TX_STOPPED_MASK, + SYN_DMA_INT_DISABLE = 0, + SYN_DMA_AXI_BUS_MODE_VAL = SYN_DMA_AXI_BLEN16 | SYN_DMA_RD_OSR_NUM_REQS8 + | SYN_DMA_WR_OSR_NUM_REQS8, +}; + +/* + * desc_mode + * GMAC descriptors mode + */ +enum desc_mode { + RINGMODE = 0x00000001, + CHAINMODE = 0x00000002, +}; + +extern void syn_disable_dma_interrupt(struct nss_gmac_hal_dev *nghd); +extern void syn_enable_dma_interrupt(struct nss_gmac_hal_dev *nghd); +extern void syn_enable_dma_rx(struct nss_gmac_hal_dev *nghd); +extern void syn_disable_dma_rx(struct nss_gmac_hal_dev *nghd); +extern void syn_enable_dma_tx(struct nss_gmac_hal_dev *nghd); +extern void syn_disable_dma_tx(struct nss_gmac_hal_dev *nghd); +extern void syn_clear_dma_status(struct nss_gmac_hal_dev *nghd); +extern void syn_resume_dma_tx(struct nss_gmac_hal_dev *nghd); +extern uint32_t syn_get_rx_missed(struct nss_gmac_hal_dev *nghd); +extern uint32_t syn_get_fifo_overflows(struct nss_gmac_hal_dev *nghd); + +extern void syn_init_tx_desc_base(struct nss_gmac_hal_dev *nghd, uint32_t tx_desc_dma); +extern void syn_init_rx_desc_base(struct nss_gmac_hal_dev *nghd, uint32_t rx_desc_dma); + +#endif /*__SYN_REG_H__*/ diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/xgmac/syn_dev.h b/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/xgmac/syn_dev.h new file mode 100644 index 000000000..bdccd09eb --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/xgmac/syn_dev.h @@ -0,0 +1,189 @@ +/* + ************************************************************************** + * Copyright (c) 2016,2020 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF0 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __SYN_DEV_H__ +#define __SYN_DEV_H__ + +#include "syn_reg.h" +#include +#include + +/* + * Subclass for base nss_gmac_haldev + */ +struct syn_hal_dev { + struct nss_gmac_hal_dev nghd; /* Base class */ + fal_xgmib_info_t stats; /* Stats structure */ +}; + +/* + * syn_set_rx_flow_ctrl() + */ +static inline void syn_set_rx_flow_ctrl( + struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, SYN_MAC_RX_FLOW_CTL, + SYN_MAC_RX_FLOW_ENABLE); +} + +/* + * syn_clear_rx_flow_ctrl() + */ +static inline void syn_clear_rx_flow_ctrl( + struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, SYN_MAC_RX_FLOW_CTL, + SYN_MAC_RX_FLOW_ENABLE); +} + +/* + * syn_set_tx_flow_ctrl() + */ +static inline void syn_set_tx_flow_ctrl( + struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, SYN_MAC_Q0_TX_FLOW_CTL, + SYN_MAC_TX_FLOW_ENABLE); +} + +/* + * syn_send_tx_pause_frame() + */ +static inline void syn_send_tx_pause_frame( + struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, SYN_MAC_Q0_TX_FLOW_CTL, + SYN_MAC_TX_FLOW_ENABLE); + hal_set_reg_bits(nghd, SYN_MAC_Q0_TX_FLOW_CTL, + SYN_MAC_TX_PAUSE_SEND); +} + +/* + * syn_clear_tx_flow_ctrl() + */ +static inline void syn_clear_tx_flow_ctrl( + struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, SYN_MAC_Q0_TX_FLOW_CTL, + SYN_MAC_TX_FLOW_ENABLE); +} + +/* + * syn_clear_mac_ctrl() + */ +static inline void syn_clear_mac_ctrl( + struct nss_gmac_hal_dev *nghd) +{ + hal_write_reg(nghd->mac_base, SYN_MAC_TX_CONFIG, 0); + hal_write_reg(nghd->mac_base, SYN_MAC_RX_CONFIG, 0); +} + +/* + * syn_rx_enable() + */ +static inline void syn_rx_enable(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, SYN_MAC_RX_CONFIG, SYN_MAC_RX_ENABLE); + hal_set_reg_bits(nghd, SYN_MAC_PACKET_FILTER, SYN_MAC_RX_ENABLE); +} + +/* + * syn_rx_disable() + */ +static inline void syn_rx_disable(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, SYN_MAC_RX_CONFIG, SYN_MAC_RX_ENABLE); +} + +/* + * syn_tx_enable() + */ +static inline void syn_tx_enable(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, SYN_MAC_TX_CONFIG, SYN_MAC_TX_ENABLE); +} + +/* + * syn_tx_disable() + */ +static inline void syn_tx_disable(struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, SYN_MAC_TX_CONFIG, + SYN_MAC_TX_ENABLE); +} + +/* + * syn_set_mmc_stats() + */ +static inline void syn_set_mmc_stats(struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, SYN_MAC_MMC_CTL, + SYN_MAC_MMC_RSTONRD); +} + +/* + * syn_rx_jumbo_frame_enable() + */ +static inline void syn_rx_jumbo_frame_enable( + struct nss_gmac_hal_dev *nghd) +{ + hal_set_reg_bits(nghd, SYN_MAC_RX_CONFIG, + SYN_MAC_JUMBO_FRAME_ENABLE); +} + +/* + * syn_rx_jumbo_frame_disable() + */ +static inline void syn_rx_jumbo_frame_disable( + struct nss_gmac_hal_dev *nghd) +{ + hal_clear_reg_bits(nghd, SYN_MAC_RX_CONFIG, + SYN_MAC_JUMBO_FRAME_ENABLE); +} + +/* + * syn_set_full_duplex() + */ +static inline void syn_set_full_duplex( + struct nss_gmac_hal_dev *nghd) +{ + /* TBD */ + return; +} + +/* + * syn_set_half_duplex() + */ +static inline void syn_set_half_duplex( + struct nss_gmac_hal_dev *nghd) +{ + /* TBD */ + return; +} + +static int syn_get_stats(struct nss_gmac_hal_dev *nghd) +{ + struct syn_hal_dev *shd = (struct syn_hal_dev *)nghd; + fal_xgmib_info_t *stats = &(shd->stats); + + if (fal_get_xgmib_info(0, nghd->mac_id, stats)) + return -1; + + return 0; +} +#endif /*__SYN_DEV_H__*/ diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/xgmac/syn_if.c b/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/xgmac/syn_if.c new file mode 100644 index 000000000..1ab621a6f --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/xgmac/syn_if.c @@ -0,0 +1,505 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ +#include +#include +#include +#include +#include +#include +#include +#include "syn_dev.h" + +#define SYN_STAT(m) offsetof(fal_xgmib_info_t, m) + +struct syn_ethtool_stats { + uint8_t stat_string[ETH_GSTRING_LEN]; + uint64_t stat_offset; +}; + +/* + * Array of strings describing statistics + */ +static const struct syn_ethtool_stats syn_gstrings_stats[] = { + {"rx_frame", SYN_STAT(RxFrame)}, + {"rx_bytes", SYN_STAT(RxByte)}, + {"rx_bytes_g", SYN_STAT(RxByteGood)}, + {"rx_broadcast", SYN_STAT(RxBroadGood)}, + {"rx_multicast", SYN_STAT(RxMultiGood)}, + {"rx_crc_err", SYN_STAT(RxFcsErr)}, + {"rx_runt_err", SYN_STAT(RxRuntErr)}, + {"rx_jabber_err", SYN_STAT(RxJabberError)}, + {"rx_undersize", SYN_STAT(RxUndersizeGood)}, + {"rx_oversize", SYN_STAT(RxOversizeGood)}, + {"rx_pkt64", SYN_STAT(Rx64Byte)}, + {"rx_pkt65to127", SYN_STAT(Rx128Byte)}, + {"rx_pkt128to255", SYN_STAT(Rx256Byte)}, + {"rx_pkt256to511", SYN_STAT(Rx512Byte)}, + {"rx_pkt512to1023", SYN_STAT(Rx1024Byte)}, + {"rx_pkt1024tomax", SYN_STAT(RxMaxByte)}, + {"rx_unicast", SYN_STAT(RxUnicastGood)}, + {"rx_len_err", SYN_STAT(RxLengthError)}, + {"rx_outofrange_err_ctr", SYN_STAT(RxOutOfRangeError)}, + {"rx_pause", SYN_STAT(RxPause)}, + {"rx_fifo_overflow", SYN_STAT(RxOverFlow)}, + {"rx_vlan", SYN_STAT(RxVLANFrameGoodBad)}, + {"rx_wdog", SYN_STAT(RxWatchDogError)}, + {"rx_lpi_usec_ctr", SYN_STAT(RxLPIUsec)}, + {"rx_lpi_tran_ctr", SYN_STAT(RxLPITran)}, + {"rx_drop_frame_ctr", SYN_STAT(RxDropFrameGoodBad)}, + {"rx_drop_byte_ctr", SYN_STAT(RxDropByteGoodBad)}, + {"tx_bytes", SYN_STAT(TxByte)}, + {"tx_frame", SYN_STAT(TxFrame)}, + {"tx_broadcast", SYN_STAT(TxBroadGood)}, + {"tx_broadcast_gb", SYN_STAT(TxBroad)}, + {"tx_multicast", SYN_STAT(TxMultiGood)}, + {"tx_multicast_gb", SYN_STAT(TxMulti)}, + {"tx_pkt64", SYN_STAT(Tx64Byte)}, + {"tx_pkt65to127", SYN_STAT(Tx128Byte)}, + {"tx_pkt128to255", SYN_STAT(Tx256Byte)}, + {"tx_pkt256to511", SYN_STAT(Tx512Byte)}, + {"tx_pkt512to1023", SYN_STAT(Tx1024Byte)}, + {"tx_pkt1024tomax", SYN_STAT(TxMaxByte)}, + {"tx_unicast", SYN_STAT(TxUnicast)}, + {"tx_underflow_err", SYN_STAT(TxUnderFlowError)}, + {"tx_bytes_g", SYN_STAT(TxByteGood)}, + {"tx_frame_g", SYN_STAT(TxFrameGood)}, + {"tx_pause", SYN_STAT(TxPause)}, + {"tx_vlan", SYN_STAT(TxVLANFrameGood)}, + {"tx_lpi_usec_ctr", SYN_STAT(TxLPIUsec)}, + {"tx_lpi_tran_ctr", SYN_STAT(TxLPITran)}, +}; + +/* + * Array of strings describing private flag names + */ +static const char *const syn_strings_priv_flags[] = { + "test", +}; + +#define SYN_STATS_LEN ARRAY_SIZE(syn_gstrings_stats) +#define SYN_PRIV_FLAGS_LEN ARRAY_SIZE(syn_strings_priv_flags) + +/* + * syn_rx_flow_control() + */ +static void syn_rx_flow_control(struct nss_gmac_hal_dev *nghd, + bool enabled) +{ + BUG_ON(nghd == NULL); + + if (enabled) + syn_set_rx_flow_ctrl(nghd); + else + syn_clear_rx_flow_ctrl(nghd); +} + +/* + * syn_tx_flow_control() + */ +static void syn_tx_flow_control(struct nss_gmac_hal_dev *nghd, + bool enabled) +{ + BUG_ON(nghd == NULL); + + if (enabled) + syn_set_tx_flow_ctrl(nghd); + else + syn_clear_tx_flow_ctrl(nghd); +} + +/* + * syn_get_mmc_stats() + */ +static int32_t syn_get_mmc_stats(struct nss_gmac_hal_dev *nghd) +{ + BUG_ON(nghd == NULL); + + if (syn_get_stats(nghd)) + return -1; + + return 0; +} + +/* + * syn_get_max_frame_size() + */ +static int32_t syn_get_max_frame_size(struct nss_gmac_hal_dev *nghd) +{ + int ret; + uint32_t mtu; + + ret = fal_port_max_frame_size_get(0, nghd->mac_id, &mtu); + + if (!ret) + return mtu; + + return ret; +} + +/* + * syn_set_max_frame_size() + */ +static int32_t syn_set_max_frame_size(struct nss_gmac_hal_dev *nghd, + uint32_t val) +{ + return fal_port_max_frame_size_set(0, nghd->mac_id, val); +} + +/* + * syn_set_mac_speed() + */ +static int32_t syn_set_mac_speed(struct nss_gmac_hal_dev *nghd, + uint32_t mac_speed) +{ + struct net_device *netdev = nghd->netdev; + + netdev_warn(netdev, "API deprecated\n"); + return 0; +} + +/* + * syn_get_mac_speed() + */ +static uint32_t syn_get_mac_speed(struct nss_gmac_hal_dev *nghd) +{ + struct net_device *netdev = nghd->netdev; + + netdev_warn(netdev, "API deprecated\n"); + return 0; +} + +/* + * syn_set_duplex_mode() + */ +static void syn_set_duplex_mode(struct nss_gmac_hal_dev *nghd, + uint8_t duplex_mode) +{ + struct net_device *netdev = nghd->netdev; + + netdev_warn(netdev, "API deprecated\n"); +} + +/* + * syn_get_duplex_mode() + */ +static uint8_t syn_get_duplex_mode(struct nss_gmac_hal_dev *nghd) +{ + struct net_device *netdev = nghd->netdev; + + netdev_warn(netdev, "API deprecated\n"); + return 0; +} + +/* + * syn_get_netdev_stats() + */ +static int syn_get_netdev_stats(struct nss_gmac_hal_dev *nghd, + struct rtnl_link_stats64 *stats) +{ + struct syn_hal_dev *shd; + fal_xgmib_info_t *hal_stats; + + BUG_ON(nghd == NULL); + + shd = (struct syn_hal_dev *)nghd; + hal_stats = &(shd->stats); + + if (syn_get_stats(nghd)) + return -1; + + stats->rx_packets = hal_stats->RxUnicastGood + + hal_stats->RxBroadGood + hal_stats->RxMultiGood; + stats->tx_packets = hal_stats->TxUnicast + + hal_stats->TxBroadGood + hal_stats->TxMultiGood; + stats->rx_bytes = hal_stats->RxByte; + stats->tx_bytes = hal_stats->TxByte; + stats->multicast = + hal_stats->RxMultiGood; + stats->rx_dropped = + hal_stats->RxDropFrameGoodBad; + stats->rx_length_errors = + hal_stats->RxLengthError; + stats->rx_crc_errors = + hal_stats->RxFcsErr; + stats->rx_fifo_errors = + hal_stats->RxOverFlow; + + return 0; +} + +/* + * syn_get_eth_stats() + */ +static int32_t syn_get_eth_stats(struct nss_gmac_hal_dev *nghd, + uint64_t *data) +{ + struct syn_hal_dev *shd; + fal_xgmib_info_t *stats; + uint8_t *p = NULL; + int i; + + BUG_ON(nghd == NULL); + + shd = (struct syn_hal_dev *)nghd; + stats = &(shd->stats); + + if (syn_get_stats(nghd)) + return -1; + + for (i = 0; i < SYN_STATS_LEN; i++) { + p = ((uint8_t *)(stats) + + syn_gstrings_stats[i].stat_offset); + data[i] = *(uint32_t *)p; + } + + return 0; +} + +/* + * syn_get_strset_count() + */ +static int32_t syn_get_strset_count(struct nss_gmac_hal_dev *nghd, + int32_t sset) +{ + struct net_device *netdev; + + BUG_ON(nghd == NULL); + + netdev = nghd->netdev; + + switch (sset) { + case ETH_SS_STATS: + return SYN_STATS_LEN; + + case ETH_SS_PRIV_FLAGS: + return SYN_PRIV_FLAGS_LEN; + } + + netdev_dbg(netdev, "%s: Invalid string set\n", __func__); + return -EPERM; +} + +/* + * syn_get_strings() + */ +static int32_t syn_get_strings(struct nss_gmac_hal_dev *nghd, + int32_t stringset, uint8_t *data) +{ + struct net_device *netdev; + int i; + + BUG_ON(nghd == NULL); + + netdev = nghd->netdev; + + switch (stringset) { + case ETH_SS_STATS: + for (i = 0; i < SYN_STATS_LEN; i++) { + memcpy(data, syn_gstrings_stats[i].stat_string, + strlen(syn_gstrings_stats[i].stat_string)); + data += ETH_GSTRING_LEN; + } + break; + + case ETH_SS_PRIV_FLAGS: + for (i = 0; i < SYN_PRIV_FLAGS_LEN; i++) { + memcpy(data, syn_strings_priv_flags[i], + strlen(syn_strings_priv_flags[i])); + data += ETH_GSTRING_LEN; + } + + break; + default: + netdev_dbg(netdev, "%s: Invalid string set\n", __func__); + return -EPERM; + } + + return 0; +} + +/* + * syn_send_pause_frame() + */ +static void syn_send_pause_frame(struct nss_gmac_hal_dev *nghd) +{ + BUG_ON(nghd == NULL); + + syn_send_tx_pause_frame(nghd); +} + +/* + * syn_start + */ +static int32_t syn_start(struct nss_gmac_hal_dev *nghd) +{ + BUG_ON(nghd == NULL); + + syn_tx_enable(nghd); + syn_rx_enable(nghd); + syn_set_full_duplex(nghd); + if (syn_set_mac_speed(nghd, SPEED_10000)) + return -1; + + netdev_dbg(nghd->netdev, + "%s: mac_base:0x%px tx_enable:0x%x rx_enable:0x%x\n", + __func__, + nghd->mac_base, + hal_read_reg(nghd->mac_base, + SYN_MAC_TX_CONFIG), + hal_read_reg(nghd->mac_base, + SYN_MAC_RX_CONFIG)); + + return 0; +} + +/* + * syn_stop + */ +static int32_t syn_stop(struct nss_gmac_hal_dev *nghd) +{ + BUG_ON(nghd == NULL); + + syn_tx_disable(nghd); + syn_rx_disable(nghd); + + netdev_dbg(nghd->netdev, "%s: Stopping mac_base:0x%px\n", __func__, + nghd->mac_base); + + return 0; +} + +/* + * syn_init() + */ +static void *syn_init(struct gmac_hal_platform_data *gmacpdata) +{ + struct syn_hal_dev *shd = NULL; + struct net_device *ndev = NULL; + struct nss_dp_dev *dp_priv = NULL; + struct resource *res; + + ndev = gmacpdata->netdev; + dp_priv = netdev_priv(ndev); + + res = platform_get_resource(dp_priv->pdev, IORESOURCE_MEM, 0); + if (!res) { + netdev_dbg(ndev, "Resource get failed.\n"); + return NULL; + } + + if (!devm_request_mem_region(&dp_priv->pdev->dev, res->start, + resource_size(res), ndev->name)) { + netdev_dbg(ndev, "Request mem region failed. Returning...\n"); + return NULL; + } + + shd = (struct syn_hal_dev *)devm_kzalloc(&dp_priv->pdev->dev, + sizeof(struct syn_hal_dev), + GFP_KERNEL); + if (!shd) { + netdev_dbg(ndev, "kzalloc failed. Returning...\n"); + return NULL; + } + + /* Save netdev context in syn HAL context */ + shd->nghd.netdev = gmacpdata->netdev; + shd->nghd.mac_id = gmacpdata->macid; + + /* Populate the mac base addresses */ + shd->nghd.mac_base = + devm_ioremap_nocache(&dp_priv->pdev->dev, res->start, + resource_size(res)); + if (!shd->nghd.mac_base) { + netdev_dbg(ndev, "ioremap fail.\n"); + return NULL; + } + + spin_lock_init(&shd->nghd.slock); + + netdev_dbg(ndev, "ioremap OK.Size 0x%x Ndev base 0x%lx macbase 0x%px\n", + gmacpdata->reg_len, + ndev->base_addr, + shd->nghd.mac_base); + + /* Reset MIB Stats */ + if (fal_mib_port_flush_counters(0, shd->nghd.mac_id)) { + netdev_dbg(ndev, "MIB stats Reset fail.\n"); + } + + return (struct nss_gmac_hal_dev *)shd; +} + +/* + * syn_set_mac_address() + */ +static void syn_set_mac_address(struct nss_gmac_hal_dev *nghd, + uint8_t *macaddr) +{ + uint32_t data; + + BUG_ON(nghd == NULL); + + data = (macaddr[5] << 8) | macaddr[4] | SYN_MAC_ADDR_RSVD_BIT; + hal_write_reg(nghd->mac_base, SYN_MAC_ADDR0_HIGH, data); + data = (macaddr[3] << 24) | (macaddr[2] << 16) | (macaddr[1] << 8) + | macaddr[0]; + hal_write_reg(nghd->mac_base, SYN_MAC_ADDR0_LOW, data); +} + +/* + * syn_get_mac_address() + */ +static void syn_get_mac_address(struct nss_gmac_hal_dev *nghd, + uint8_t *macaddr) +{ + uint32_t data; + + BUG_ON(nghd == NULL); + + data = hal_read_reg(nghd->mac_base, SYN_MAC_ADDR0_HIGH); + macaddr[5] = (data >> 8) & 0xff; + macaddr[4] = (data) & 0xff; + + data = hal_read_reg(nghd->mac_base, SYN_MAC_ADDR0_LOW); + macaddr[3] = (data >> 24) & 0xff; + macaddr[2] = (data >> 16) & 0xff; + macaddr[1] = (data >> 8) & 0xff; + macaddr[0] = (data) & 0xff; +} + +struct nss_gmac_hal_ops syn_hal_ops = { + .init = &syn_init, + .start = &syn_start, + .stop = &syn_stop, + .setmacaddr = &syn_set_mac_address, + .getmacaddr = &syn_get_mac_address, + .rxflowcontrol = &syn_rx_flow_control, + .txflowcontrol = &syn_tx_flow_control, + .setspeed = &syn_set_mac_speed, + .getspeed = &syn_get_mac_speed, + .setduplex = &syn_set_duplex_mode, + .getduplex = &syn_get_duplex_mode, + .getstats = &syn_get_mmc_stats, + .setmaxframe = &syn_set_max_frame_size, + .getmaxframe = &syn_get_max_frame_size, + .getndostats = &syn_get_netdev_stats, + .getssetcount = &syn_get_strset_count, + .getstrings = &syn_get_strings, + .getethtoolstats = &syn_get_eth_stats, + .sendpause = &syn_send_pause_frame, +}; diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/xgmac/syn_reg.h b/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/xgmac/syn_reg.h new file mode 100644 index 000000000..f76fce1a0 --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/gmac_hal_ops/syn/xgmac/syn_reg.h @@ -0,0 +1,255 @@ +/* + ************************************************************************** + * Copyright (c) 2016,2020 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF0 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __SYN_REG_H__ +#define __SYN_REG_H__ + +/* + * + MAC Register Offset + * + */ +#define SYN_MAC_TX_CONFIG 0x0000 +#define SYN_MAC_RX_CONFIG 0x0004 +#define SYN_MAC_PACKET_FILTER 0x0008 +#define SYN_MAC_WDOG_TIMEOUT 0x000c +#define SYN_MAC_HASH_TBL_REG0 0x0010 +#define SYN_MAC_VLAN_TAG 0x0050 +#define SYN_MAC_VLAN_HASH_TBL 0x0058 +#define SYN_MAC_VLAN_INCL 0x0060 +#define SYN_MAC_INNER_VLAN_INCL 0x0064 +#define SYN_MAC_RX_ETH_TYP_MATCH 0x006c +#define SYN_MAC_Q0_TX_FLOW_CTL 0x0070 +#define SYN_MAC_Q1_TX_FLOW_CTL 0x0074 +#define SYN_MAC_Q2_TX_FLOW_CTL 0x0078 +#define SYN_MAC_Q3_TX_FLOW_CTL 0x007c +#define SYN_MAC_Q4_TX_FLOW_CTL 0x0080 +#define SYN_MAC_Q5_TX_FLOW_CTL 0x0084 +#define SYN_MAC_Q6_TX_FLOW_CTL 0x0088 +#define SYN_MAC_Q7_TX_FLOW_CTL 0x008c +#define SYN_MAC_RX_FLOW_CTL 0x0090 +#define SYN_MAC_RXQ_CTL0 0x00a0 +#define SYN_MAC_RXQ_CTL1 0x00a4 +#define SYN_MAC_RXQ_CTL2 0x00a8 +#define SYN_MAC_RXQ_CTL3 0x00ac +#define SYN_MAC_INT_STATUS 0x00b0 +#define SYN_MAC_INT_ENABLE 0x00b4 +#define SYN_MAC_TX_RX_STATUS 0x00b8 +#define SYN_MAC_PMT_CTL_STATUS 0x00c0 +#define SYN_MAC_RWK_PACKET_FILTER 0x00c4 +#define SYN_MAC_LPI_CTL_STATUS 0x00d0 +#define SYN_MAC_LPI_TIMER_STATUS 0x00d4 +#define SYN_MAC_VERSION 0x0110 +#define SYN_MAC_DEBUG 0x0114 +#define SYN_MAC_FW_FEATURE0 0x011c +#define SYN_MAC_FW_FEATURE1 0x0120 +#define SYN_MAC_FW_FEATURE2 0x0124 +#define SYN_MAC_GPIO_CTL 0x0278 +#define SYN_MAC_GPIO_STATUS 0x027c +#define SYN_MAC_ADDR0_HIGH 0x0300 +#define SYN_MAC_ADDR0_LOW 0x0304 +#define SYN_MAC_ADDR1_HIGH 0x0308 +#define SYN_MAC_ADDR1_LOW 0x030c +#define SYN_MAC_TS_CTL 0x0d00 +#define SYN_MAC_SUB_SEC_INCR 0x0d04 +#define SYN_MAC_SYS_TIME_SECS 0x0d08 +#define SYN_MAC_SYS_TIME_NSECS 0x0d0c +#define SYN_MAC_SYS_TIME_SECS_UPDATE 0x0d10 +#define SYN_MAC_SYS_TIME_NSECS_UPDATE 0x0d14 +#define SYN_MAC_TS_ADDEND 0x0d18 +#define SYN_MAC_TS_STATUS 0x0d20 +#define SYN_MAC_TX_TS_STATUS_NSECS 0x0d30 +#define SYN_MAC_TX_TS_STATUS_SECS 0x0d34 +#define SYN_MAC_PPS_CTL 0x0d70 +#define SYN_MAC_MMC_CTL 0x0800 +#define SYN_MAC_MMC_RX_INT 0x0804 +#define SYN_MAC_MMC_TX_INT 0x0808 +#define SYN_MAC_MMC_RX_INT_EN 0x080c +#define SYN_MAC_MMC_TX_INT_EN 0x0810 + +/* MAC TX MMC Counters */ +#define SYN_MAC_MMC_TX_BCAST_LO 0x0824 +#define SYN_MAC_MMC_TX_BCAST_HI 0x0828 +#define SYN_MAC_MMC_TX_FRAME_LO 0x0894 +#define SYN_MAC_MMC_TX_FRAME_HI 0x0898 +#define SYN_MAC_MMC_TX_MCAST_LO 0x082c +#define SYN_MAC_MMC_TX_MCAST_HI 0x0830 +#define SYN_MAC_MMC_TX_PKT64_LO 0x0834 +#define SYN_MAC_MMC_TX_PKT64_HI 0x0838 +#define SYN_MAC_MMC_TX_PKT65TO127_LO 0x083c +#define SYN_MAC_MMC_TX_PKT65TO127_HI 0x0840 +#define SYN_MAC_MMC_TX_PKT128TO255_LO 0x0844 +#define SYN_MAC_MMC_TX_PKT128TO255_HI 0x0848 +#define SYN_MAC_MMC_TX_PKT256TO511_LO 0x084c +#define SYN_MAC_MMC_TX_PKT256TO511_HI 0x0850 +#define SYN_MAC_MMC_TX_PKT512TO1023_LO 0x0854 +#define SYN_MAC_MMC_TX_PKT512TO1023_HI 0x0858 +#define SYN_MAC_MMC_TX_PKT1024TOMAX_LO 0x085c +#define SYN_MAC_MMC_TX_PKT1024TOMAX_HI 0x0860 +#define SYN_MAC_MMC_TX_UNICAST_LO 0x0864 +#define SYN_MAC_MMC_TX_UNICAST_HI 0x0868 +#define SYN_MAC_MMC_TX_MCAST_GB_LO 0x086c +#define SYN_MAC_MMC_TX_MCAST_GB_HI 0x0870 +#define SYN_MAC_MMC_TX_BCAST_GB_LO 0x0874 +#define SYN_MAC_MMC_TX_BCAST_GB_HI 0x0878 +#define SYN_MAC_MMC_TX_UNDERFLOW_ERR_LO 0x087c +#define SYN_MAC_MMC_TX_UNDERFLOW_ERR_HI 0x0880 +#define SYN_MAC_MMC_TX_BYTES_LO 0x0884 +#define SYN_MAC_MMC_TX_BYTES_HI 0x0888 +#define SYN_MAC_MMC_TX_PAUSE_FRAME_LO 0x0894 +#define SYN_MAC_MMC_TX_PAUSE_FRAME_HI 0x0898 +#define SYN_MAC_MMC_TX_VLAN_LO 0x089c +#define SYN_MAC_MMC_TX_VLAN_HI 0x08a0 +#define SYN_MAC_MMC_TX_LPI_USEC_CTR_LO 0x08a4 +#define SYN_MAC_MMC_TX_LPI_USEC_CTR_HI 0x08a8 + +/* MAC RX MMC Counters */ +#define SYN_MAC_MMC_RX_FRAME_LO 0x0900 +#define SYN_MAC_MMC_RX_FRAME_HI 0x0904 +#define SYN_MAC_MMC_RX_BYTES_LO 0x0910 +#define SYN_MAC_MMC_RX_BYTES_HI 0x0914 +#define SYN_MAC_MMC_RX_BCAST_LO 0x0918 +#define SYN_MAC_MMC_RX_BCAST_HI 0x091c +#define SYN_MAC_MMC_RX_MCAST_LO 0x0920 +#define SYN_MAC_MMC_RX_MCAST_HI 0x0924 +#define SYN_MAC_MMC_RX_CRC_ERR_LO 0x0928 +#define SYN_MAC_MMC_RX_CRC_ERR_HI 0x092c +#define SYN_MAC_MMC_RX_RUNT_ERR 0x0930 +#define SYN_MAC_MMC_RX_JABBER_ERR 0x0934 +#define SYN_MAC_MMC_RX_UNDERSIZE 0x0938 +#define SYN_MAC_MMC_RX_OVERSIZE 0x093c +#define SYN_MAC_MMC_RX_PKT64_LO 0x0940 +#define SYN_MAC_MMC_RX_PKT64_HI 0x0944 +#define SYN_MAC_MMC_RX_PKT65TO127_LO 0x0948 +#define SYN_MAC_MMC_RX_PKT65TO127_HI 0x094c +#define SYN_MAC_MMC_RX_PKT128TO255_LO 0x0950 +#define SYN_MAC_MMC_RX_PKT128TO255_HI 0x0954 +#define SYN_MAC_MMC_RX_PKT256TO511_LO 0x0958 +#define SYN_MAC_MMC_RX_PKT256TO511_HI 0x095c +#define SYN_MAC_MMC_RX_PKT512TO1023_LO 0x0960 +#define SYN_MAC_MMC_RX_PKT512TO1023_HI 0x0964 +#define SYN_MAC_MMC_RX_PKT1024TOMAX_LO 0x0968 +#define SYN_MAC_MMC_RX_PKT1024TOMAX_HI 0x096c +#define SYN_MAC_MMC_RX_UNICAST_LO 0x0970 +#define SYN_MAC_MMC_RX_UNICAST_HI 0x0974 +#define SYN_MAC_MMC_RX_LEN_ERR_LO 0x0978 +#define SYN_MAC_MMC_RX_LEN_ERR_HI 0x097c +#define SYN_MAC_MMC_RX_PAUSE_FRAME_LO 0x0988 +#define SYN_MAC_MMC_RX_PAUSE_FRAME_HI 0x098c +#define SYN_MAC_MMC_RX_FIFO_OVERFLOW_LO 0x0990 +#define SYN_MAC_MMC_RX_FIFO_OVERFLOW_HI 0x0994 +#define SYN_MAC_MMC_RX_VLAN_FRAME_LO 0x0998 +#define SYN_MAC_MMC_RX_VLAN_FRAME_HI 0x099c +#define SYN_MAC_MMC_RX_LPI_USEC_CTR_LO 0x09a4 +#define SYN_MAC_MMC_RX_LPI_USEC_CTR_HI 0x09a8 +#define SYN_MAC_MMC_RX_DISCARD_FRAME_LO 0x09ac +#define SYN_MAC_MMC_RX_DISCARD_FRAME_HI 0x09b0 + +/* MAC Register Bit Definitions*/ + +/* SYN_MAC_Q0_TX_FLOW_CTL Bit definitions */ +#define SYN_MAC_TX_PAUSE_SEND 0x00000001 +#define SYN_MAC_TX_FLOW_ENABLE 0x00000002 +#define SYN_MAC_TX_PAUSE_LOW_THRESHOLD 0x00000070 +#define SYN_MAC_ADDR_RSVD_BIT 0x80000000 + +/* SYN_MAC_RX_FLOW_CTL Bit definitions */ +#define SYN_MAC_RX_FLOW_ENABLE 0x00000001 + +/* SYN_MAC_TX_CONFIG Bit definitions */ +#define SYN_MAC_TX_ENABLE 0x00000001 +#define SYN_MAC_TX_SPEED_SELECT 0x60000000 + +/* SYN_MAC_RX_CONFIG Bit definitions */ +#define SYN_MAC_RX_ENABLE 0x00000001 +#define SYN_MAC_JUMBO_FRAME_ENABLE 0x00000100 + +#define SYN_MAC_SPEED_10G 0x0 +#define SYN_MAC_SPEED_2_5G 0x2 +#define SYN_MAC_SPEED_1G 0x3 +#define SYN_MAC_SPEED_BITPOS 29 +#define SYN_MAC_SPEED_BITMASK 0x3 + +#define SYN_MAC_DEFAULT_MAX_FRAME_SIZE 1518 +#define SYN_MAC_MAX_FRAME_SIZE_BITPOS 16 +#define SYN_MAC_MAX_FRAME_SIZE_BITMASK 0x3fff + +/* SYN_MAC_MMC_CTL Bit definitions */ +#define SYN_MAC_MMC_RSTONRD 0x00000004 + +/* + * + MTL Register Offset + * + */ +#define SYN_MTL_OPER_MODE 0x1000 +#define SYN_MTL_DEBUG_CTL 0x1008 +#define SYN_MTL_DEBUG_STATUS 0x100c +#define SYN_MTL_DEBUG_DATA 0x1010 +#define SYN_MTL_INT_STATUS 0x1020 +#define SYN_MTL_RXQ_DMA_MAP0 0x1030 +#define SYN_MTL_RXQ_DMA_MAP1 0x1034 +#define SYN_MTL_RXQ_DMA_MAP2 0x1038 +#define SYN_MTL_TC_PRIO_MAP0 0x1040 +#define SYN_MTL_TC_PRIO_MAP1 0x1044 +#define SYN_MTL_TXQ0_OPER_MODE 0x1100 +#define SYN_MTL_TXQ0_UNDERFLOW 0x1104 +#define SYN_MTL_TXQ0_DEBUG 0x1108 +#define SYN_MTL_TC0_ETS_CTL 0x1110 +#define SYN_MTL_TC0_ETS_STATUS 0x1114 +#define SYN_MTL_TC0_QUANTUM_WEIGHT 0x1118 +#define SYN_MTL_RXQ0_DEBUG 0x1148 +#define SYN_MTL_RXQ0_CTL 0x114c +#define SYN_MTL_RXQ0_FLOW_CTL 0x1150 +#define SYN_MTL_Q0_INT_ENABLE 0x1170 +#define SYN_MTL_Q0_INT_STATUS 0x1174 + +/* MTL Register Bit definitions */ + +/* + * + DMA Register Offset + * + */ +#define SYN_DMA_MODE 0x3000 +#define SYN_DMA_SYSBUS_MODE 0x3004 +#define SYN_DMA_INT_STATUS 0x3008 +#define SYN_DMA_AXI_TX_AR_ACE_CTL 0x3010 +#define SYN_DMA_AXI_RX_AW_ACE_CTL 0x3018 +#define SYN_DMA_AXI_TXRX_AWAR_ACE_CTL 0x301c +#define SYN_DMA_DEBUG_STATUS0 0x3020 +#define SYN_DMA_DEBUG_STATUS1 0x3024 +#define SYN_DMA_TX_EDMA_CTL 0x3040 +#define SYN_DMA_RX_EDMA_CTL 0x3044 +#define SYN_DMA_CH0_CTL 0x3100 +#define SYN_DMA_CH0_TX_CTL 0x3104 +#define SYN_DMA_CH0_RX_CTL 0x3108 +#define SYN_DMA_CH0_TXDESC_LIST_HADDR 0x3110 +#define SYN_DMA_CH0_TXDESC_LIST_LADDR 0x3114 +#define SYN_DMA_CH0_RXDESC_LIST_HADDR 0x3118 +#define SYN_DMA_CH0_RXDESC_LIST_LADDR 0x311c +#define SYN_DMA_CH0_TXDESC_TAIL_LPTR 0x3124 +#define SYN_DMA_CH0_RXDESC_TAIL_LPTR 0x312c +#define SYN_DMA_CH0_TXDESC_RING_LEN 0x3130 +#define SYN_DMA_CH0_RXDESC_RING_LEN 0x3134 +#define SYN_DMA_INT_ENABLE 0x3138 +#define SYN_DMA_RX_INT_WDOG_TIMER 0x313c + +/* DMA Register Bit definitions */ + +#endif /*__SYN_REG_H__*/ diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/include/edma.h b/feeds/ipq807x/qca-nss-dp/src/hal/include/edma.h new file mode 100644 index 000000000..9ed0c3840 --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/include/edma.h @@ -0,0 +1,31 @@ +/* + ************************************************************************** + * Copyright (c) 2016, 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** +*/ + +/* + * This file includes declarations defined by the EDMA + * dataplane and used by other layers of this driver. + */ + +#ifndef __NSS_DP_EDMA__ +#define __NSS_DP_EDMA__ + +extern int edma_init(void); +extern void edma_cleanup(bool is_dp_override); +extern struct nss_dp_data_plane_ops nss_dp_edma_ops; + +#endif /*__NSS_DP_EDMA__ */ diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/include/nss_dp_hal.h b/feeds/ipq807x/qca-nss-dp/src/hal/include/nss_dp_hal.h new file mode 100644 index 000000000..89cdb1abe --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/include/nss_dp_hal.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __NSS_DP_HAL_H__ +#define __NSS_DP_HAL_H__ + +#include "nss_dp_dev.h" + +/* + * nss_dp_hal_get_gmac_ops() + * Returns gmac hal ops based on the GMAC type. + */ +static inline struct nss_gmac_hal_ops *nss_dp_hal_get_gmac_ops(uint32_t gmac_type) +{ + return dp_global_ctx.gmac_hal_ops[gmac_type]; +} + +/* + * nss_dp_hal_set_gmac_ops() + * Sets dp global gmac hal ops based on the GMAC type. + */ +static inline void nss_dp_hal_set_gmac_ops(struct nss_gmac_hal_ops *hal_ops, uint32_t gmac_type) +{ + dp_global_ctx.gmac_hal_ops[gmac_type] = hal_ops; +} + +/* + * HAL functions implemented by SoC specific source files. + */ +extern bool nss_dp_hal_init(void); +extern void nss_dp_hal_cleanup(void); +extern void nss_dp_hal_clk_enable(struct nss_dp_dev *dp_priv); +extern struct nss_dp_data_plane_ops *nss_dp_hal_get_data_plane_ops(void); + +#endif /* __NSS_DP_HAL_H__ */ diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/include/nss_dp_hal_if.h b/feeds/ipq807x/qca-nss-dp/src/hal/include/nss_dp_hal_if.h new file mode 100644 index 000000000..68fc2da3e --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/include/nss_dp_hal_if.h @@ -0,0 +1,162 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2017,2020 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF0 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_DP_HAL_IF_H__ +#define __NSS_DP_HAL_IF_H__ + +#include +#include +#include + +enum gmac_device_type { + GMAC_HAL_TYPE_QCOM = 0, /* 1G GMAC type */ + GMAC_HAL_TYPE_SYN_XGMAC,/* Synopsys XGMAC type */ + GMAC_HAL_TYPE_SYN_GMAC, /* Synopsys 1G GMAC type */ + GMAC_HAL_TYPE_MAX +}; + +/* + * gmac_hal_platform_data + */ +struct gmac_hal_platform_data { + struct net_device *netdev; /* Net device */ + uint32_t reg_len; /* Register space length */ + uint32_t mactype; /* MAC chip type */ + uint32_t macid; /* MAC sequence id on the Chip */ +}; + +/* + * NSS GMAC HAL device data + */ +struct nss_gmac_hal_dev { + void __iomem *mac_base; /* Base address of MAC registers */ + uint32_t version; /* GMAC Revision version */ + uint32_t drv_flags; /* Driver specific feature flags */ + + /* + * Phy related stuff + */ + uint32_t link_state; /* Link status as reported by the Phy */ + uint32_t duplex_mode; /* Duplex mode of the Phy */ + uint32_t speed; /* Speed of the Phy */ + uint32_t loop_back_mode;/* Loopback status of the Phy */ + uint32_t phy_mii_type; /* RGMII/SGMII/XSGMII */ + + struct net_device *netdev; + struct resource *memres; + uint32_t mac_reg_len; /* MAC Register block length */ + uint32_t mac_id; /* MAC sequence id on the Chip */ + spinlock_t slock; /* lock to protect concurrent reg access */ +}; + +/* + * nss_gmac_hal_ops + */ +struct nss_gmac_hal_ops { + void* (*init)(struct gmac_hal_platform_data *); + void (*exit)(struct nss_gmac_hal_dev *); + int32_t (*start)(struct nss_gmac_hal_dev *); + int32_t (*stop)(struct nss_gmac_hal_dev *); + void (*setmacaddr)(struct nss_gmac_hal_dev *, uint8_t *); + void (*getmacaddr)(struct nss_gmac_hal_dev *, uint8_t *); + void (*promisc)(struct nss_gmac_hal_dev *, bool enabled); + void (*multicast)(struct nss_gmac_hal_dev *, bool enabled); + void (*broadcast)(struct nss_gmac_hal_dev *, bool enabled); + void (*rxcsumoffload)(struct nss_gmac_hal_dev *, bool enabled); + void (*txcsumoffload)(struct nss_gmac_hal_dev *, bool enabled); + void (*rxflowcontrol)(struct nss_gmac_hal_dev *, bool enabled); + void (*txflowcontrol)(struct nss_gmac_hal_dev *, bool enabled); + int32_t (*setspeed)(struct nss_gmac_hal_dev *, uint32_t); + uint32_t (*getspeed)(struct nss_gmac_hal_dev *); + void (*setduplex)(struct nss_gmac_hal_dev *, uint8_t); + uint8_t (*getduplex)(struct nss_gmac_hal_dev *); + int32_t (*getstats)(struct nss_gmac_hal_dev *); + int32_t (*setmaxframe)(struct nss_gmac_hal_dev *, uint32_t); + int32_t (*getmaxframe)(struct nss_gmac_hal_dev *); + int32_t (*getndostats)(struct nss_gmac_hal_dev *, + struct rtnl_link_stats64 *); + void (*sendpause)(struct nss_gmac_hal_dev *); + void (*stoppause)(struct nss_gmac_hal_dev *); + int32_t (*getssetcount)(struct nss_gmac_hal_dev *, int32_t); + int32_t (*getstrings)(struct nss_gmac_hal_dev *, int32_t, uint8_t *); + int32_t (*getethtoolstats)(struct nss_gmac_hal_dev *, uint64_t *); +}; + +extern struct nss_gmac_hal_ops qcom_hal_ops; +extern struct nss_gmac_hal_ops syn_hal_ops; + +/********************************************************** + * Common functions + **********************************************************/ +/* + * hal_read_reg() + */ +static inline uint32_t hal_read_reg(void __iomem *regbase, uint32_t regoffset) +{ + return readl_relaxed(regbase + regoffset); +} + +/* + * hal_write_reg() + */ +static inline void hal_write_reg(void __iomem *regbase, uint32_t regoffset, + uint32_t regdata) +{ + writel_relaxed(regdata, regbase + regoffset); +} + +/* + * hal_set_reg_bits() + */ +static inline void hal_set_reg_bits(struct nss_gmac_hal_dev *nghd, + uint32_t regoffset, + uint32_t bitpos) +{ + uint32_t data; + + spin_lock(&nghd->slock); + data = bitpos | hal_read_reg(nghd->mac_base, regoffset); + hal_write_reg(nghd->mac_base, regoffset, data); + spin_unlock(&nghd->slock); +} + +/* + * hal_clear_reg_bits() + */ +static inline void hal_clear_reg_bits(struct nss_gmac_hal_dev *nghd, + uint32_t regoffset, + uint32_t bitpos) +{ + uint32_t data; + + spin_lock(&nghd->slock); + data = ~bitpos & hal_read_reg(nghd->mac_base, regoffset); + hal_write_reg(nghd->mac_base, regoffset, data); + spin_unlock(&nghd->slock); +} + +/* + * hal_check_reg_bits() + */ +static inline bool hal_check_reg_bits(void __iomem *regbase, + uint32_t regoffset, + uint32_t bitpos) +{ + return (bitpos & hal_read_reg(regbase, regoffset)) != 0; +} +#endif /* __NSS_DP_HAL_IF_H__ */ diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/syn_gmac_dp/syn_data_plane.c b/feeds/ipq807x/qca-nss-dp/src/hal/syn_gmac_dp/syn_data_plane.c new file mode 100644 index 000000000..0b9bdce1f --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/syn_gmac_dp/syn_data_plane.c @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include "syn_data_plane.h" +#include "syn_reg.h" + +#define SYN_DP_NAPI_BUDGET 64 + +/* + * GMAC Ring info + */ +struct syn_dp_info dp_info[NSS_DP_HAL_MAX_PORTS]; + +/* + * syn_dp_napi_poll() + * Scheduled by napi to process RX and TX complete + */ +static int syn_dp_napi_poll(struct napi_struct *napi, int budget) +{ + struct nss_dp_dev *gmac_dev = container_of(napi, struct nss_dp_dev, napi); + struct syn_dp_info *dev_info = &dp_info[gmac_dev->macid - 1]; + int work_done; + + /* + * Update GMAC stats + */ + spin_lock_bh(&dp_info->stats_lock); + dp_info->stats.stats.rx_missed += syn_get_rx_missed(gmac_dev->gmac_hal_ctx); + dp_info->stats.stats.rx_missed += syn_get_fifo_overflows(gmac_dev->gmac_hal_ctx); + spin_unlock_bh(&dp_info->stats_lock); + + syn_dp_process_tx_complete(gmac_dev, dev_info); + work_done = syn_dp_rx(gmac_dev, dev_info, budget); + syn_dp_rx_refill(gmac_dev, dev_info); + + if (work_done < budget) { + napi_complete(napi); + syn_enable_dma_interrupt(gmac_dev->gmac_hal_ctx); + } + + return work_done; +} + +/* + * syn_dp_handle_irq() + * Process IRQ and schedule napi + */ +static irqreturn_t syn_dp_handle_irq(int irq, void *ctx) +{ + struct nss_dp_dev *gmac_dev = (struct nss_dp_dev *)ctx; + struct nss_gmac_hal_dev *nghd = gmac_dev->gmac_hal_ctx; + + syn_clear_dma_status(nghd); + syn_disable_dma_interrupt(nghd); + + /* + * Schedule NAPI + */ + napi_schedule(&gmac_dev->napi); + + return IRQ_HANDLED; +} + +/* + * syn_dp_if_init() + * Initialize the GMAC data plane operations + */ +static int syn_dp_if_init(struct nss_dp_data_plane_ctx *dpc) +{ + struct net_device *netdev = dpc->dev; + struct nss_dp_dev *gmac_dev = (struct nss_dp_dev *)netdev_priv(netdev); + uint32_t macid = gmac_dev->macid; + struct syn_dp_info *dev_info = &dp_info[macid - 1]; + struct device *dev = &gmac_dev->pdev->dev; + int err; + + if (!netdev) { + netdev_dbg(netdev, "nss_dp_gmac: Invalid netdev pointer %px\n", netdev); + return NSS_DP_FAILURE; + } + + netdev_info(netdev, "nss_dp_gmac: Registering netdev %s(qcom-id:%d) with GMAC\n", netdev->name, macid); + + if (!dev_info->napi_added) { + netif_napi_add(netdev, &gmac_dev->napi, syn_dp_napi_poll, SYN_DP_NAPI_BUDGET); + + /* + * Requesting irq + */ + netdev->irq = platform_get_irq(gmac_dev->pdev, 0); + err = request_irq(netdev->irq, syn_dp_handle_irq, 0, "nss-dp-gmac", gmac_dev); + if (err) { + netdev_dbg(netdev, "err_code:%d, Mac %d IRQ %d request failed\n", err, + gmac_dev->macid, netdev->irq); + return NSS_DP_FAILURE; + } + + gmac_dev->drv_flags |= NSS_DP_PRIV_FLAG(IRQ_REQUESTED); + dev_info->napi_added = 1; + } + + /* + * Forcing the kernel to use 32-bit DMA addressing + */ + dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); + + /* + * Initialize the Tx/Rx ring + */ + if (syn_dp_setup_rings(gmac_dev, netdev, dev, dev_info)) { + netdev_dbg(netdev, "nss_dp_gmac: Error initializing GMAC rings %px\n", netdev); + return NSS_DP_FAILURE; + } + + spin_lock_init(&dev_info->data_lock); + spin_lock_init(&dev_info->stats_lock); + + netdev_dbg(netdev,"Synopsys GMAC dataplane initialized\n"); + + return NSS_DP_SUCCESS; +} + +/* + * syn_dp_if_open() + * Open the GMAC data plane operations + */ +static int syn_dp_if_open(struct nss_dp_data_plane_ctx *dpc, uint32_t tx_desc_ring, + uint32_t rx_desc_ring, uint32_t mode) +{ + struct net_device *netdev = dpc->dev; + struct nss_dp_dev *gmac_dev = (struct nss_dp_dev *)netdev_priv(netdev); + struct nss_gmac_hal_dev *nghd = gmac_dev->gmac_hal_ctx; + + syn_enable_dma_rx(nghd); + syn_enable_dma_tx(nghd); + + napi_enable(&gmac_dev->napi); + syn_enable_dma_interrupt(nghd); + + netdev_dbg(netdev, "Synopsys GMAC dataplane opened\n"); + + return NSS_DP_SUCCESS; +} + +/* + * syn_dp_if_close() + * Close the GMAC data plane operations + */ +static int syn_dp_if_close(struct nss_dp_data_plane_ctx *dpc) +{ + struct net_device *netdev = dpc->dev; + struct nss_dp_dev *gmac_dev = (struct nss_dp_dev *)netdev_priv(netdev); + struct nss_gmac_hal_dev *nghd = gmac_dev->gmac_hal_ctx; + + syn_disable_dma_rx(nghd); + syn_disable_dma_tx(nghd); + + syn_disable_dma_interrupt(nghd); + napi_disable(&gmac_dev->napi); + + netdev_dbg(netdev, "Synopsys GMAC dataplane closed\n"); + + return NSS_DP_SUCCESS; +} + +/* + * syn_dp_if_link_state() + * Change of link for the dataplane + */ +static int syn_dp_if_link_state(struct nss_dp_data_plane_ctx *dpc, uint32_t link_state) +{ + struct net_device *netdev = dpc->dev; + + /* + * Switch interrupt based on the link state + */ + if (link_state) { + netdev_dbg(netdev, "Data plane link up\n"); + } else { + netdev_dbg(netdev, "Data plane link down\n"); + } + + return NSS_DP_SUCCESS; +} + +/* + * syn_dp_if_mac_addr() + */ +static int syn_dp_if_mac_addr(struct nss_dp_data_plane_ctx *dpc, uint8_t *addr) +{ + return NSS_DP_SUCCESS; +} + +/* + * syn_dp_if_change_mtu() + */ +static int syn_dp_if_change_mtu(struct nss_dp_data_plane_ctx *dpc, uint32_t mtu) +{ + /* + * TODO: Work on MTU fix along with register update for frame length + */ + return NSS_DP_SUCCESS; +} + +/* + * syn_dp_if_set_features() + * Set the supported net_device features + */ +static void syn_dp_if_set_features(struct nss_dp_data_plane_ctx *dpc) +{ + struct net_device *netdev = dpc->dev; + + netdev->features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM; + netdev->hw_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM; + netdev->vlan_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM; + netdev->wanted_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM; +} + +/* + * syn_dp_if_xmit() + * Dataplane method to transmit the packet + */ +static netdev_tx_t syn_dp_if_xmit(struct nss_dp_data_plane_ctx *dpc, struct sk_buff *skb) +{ + struct net_device *netdev = dpc->dev; + struct nss_dp_dev *gmac_dev = (struct nss_dp_dev *)netdev_priv(netdev); + struct syn_dp_info *dev_info = &dp_info[gmac_dev->macid - 1]; + int nfrags = skb_shinfo(skb)->nr_frags; + + /* + * Most likely, it is not a fragmented pkt, optimize for that + */ + if (likely(nfrags == 0)) { + if (syn_dp_tx(gmac_dev, dev_info, skb)) { + goto drop; + } + + return NETDEV_TX_OK; + } + +drop: + dev_kfree_skb_any(skb); + dev_info->stats.stats.tx_dropped++; + + return NETDEV_TX_BUSY; +} + +/* + * syn_dp_if_pause_on_off() + */ +static int syn_dp_if_pause_on_off(struct nss_dp_data_plane_ctx *dpc, uint32_t pause_on) +{ + return NSS_DP_SUCCESS; +} + +/* + * syn_dp_if_get_stats + * Get Synopsys GMAC data plane stats + */ +static void syn_dp_if_get_stats(struct nss_dp_data_plane_ctx *dpc, struct nss_dp_gmac_stats *stats) +{ + struct net_device *netdev = dpc->dev; + struct nss_dp_dev *gmac_dev = (struct nss_dp_dev *)netdev_priv(netdev); + struct syn_dp_info *dev_info = &dp_info[gmac_dev->macid - 1]; + + spin_lock_bh(&dev_info->stats_lock); + netdev_dbg(netdev, "GETTING stats: rx_packets:%llu rx_bytes:%llu mmc_rx_crc_errors:%llu", dev_info->stats.stats.rx_packets, + dev_info->stats.stats.rx_bytes, dev_info->stats.stats.mmc_rx_crc_errors); + memcpy(stats, &dev_info->stats, sizeof(*stats)); + spin_unlock_bh(&dev_info->stats_lock); +} + +/* + * syn_dp_if_deinit() + * Free all the Synopsys GMAC resources + */ +static int syn_dp_if_deinit(struct nss_dp_data_plane_ctx *dpc) +{ + struct net_device *netdev = dpc->dev; + struct nss_dp_dev *gmac_dev = (struct nss_dp_dev *)netdev_priv(netdev); + struct syn_dp_info *dev_info = &dp_info[gmac_dev->macid - 1]; + + if (dev_info->napi_added) { + /* + * Remove interrupt handlers and NAPI + */ + if (gmac_dev->drv_flags & NSS_DP_PRIV_FLAG(IRQ_REQUESTED)) { + netdev_dbg(netdev, "Freeing IRQ %d for Mac %d\n", netdev->irq, gmac_dev->macid); + synchronize_irq(netdev->irq); + free_irq(netdev->irq, gmac_dev); + gmac_dev->drv_flags &= ~NSS_DP_PRIV_FLAG(IRQ_REQUESTED); + } + + netif_napi_del(&gmac_dev->napi); + dev_info->napi_added = 0; + } + + /* + * Cleanup and free the rings + */ + syn_dp_cleanup_rings(gmac_dev, netdev, dev_info); + + return NSS_DP_SUCCESS; +} + +/* + * nss_dp_gmac_ops + * Data plane operations for Synopsys GMAC + */ +struct nss_dp_data_plane_ops nss_dp_gmac_ops = { + .init = syn_dp_if_init, + .open = syn_dp_if_open, + .close = syn_dp_if_close, + .link_state = syn_dp_if_link_state, + .mac_addr = syn_dp_if_mac_addr, + .change_mtu = syn_dp_if_change_mtu, + .xmit = syn_dp_if_xmit, + .set_features = syn_dp_if_set_features, + .pause_on_off = syn_dp_if_pause_on_off, + .get_stats = syn_dp_if_get_stats, + .deinit = syn_dp_if_deinit, +}; diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/syn_gmac_dp/syn_data_plane.h b/feeds/ipq807x/qca-nss-dp/src/hal/syn_gmac_dp/syn_data_plane.h new file mode 100644 index 000000000..c96309599 --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/syn_gmac_dp/syn_data_plane.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +#ifndef __NSS_DP_SYN_DATAPLANE__ +#define __NSS_DP_SYN_DATAPLANE__ + +#include "nss_dp_dev.h" +#include "syn_dma_desc.h" + +#define SYN_DP_TX_DESC_SIZE 128 /* Tx Descriptors needed in the descriptor pool/queue */ +#define SYN_DP_RX_DESC_SIZE 128 /* Rx Descriptors needed in the descriptor pool/queue */ +#define SYN_DP_MINI_JUMBO_FRAME_MTU 1978 +#define SYN_DP_MAX_DESC_BUFF 0x1FFF /* Max size of buffer that can be programed into one field of desc */ + +/* + * syn_dp_info + * Synopysys GMAC Dataplane information + */ +struct syn_dp_info { + struct nss_dp_gmac_stats stats; /* GMAC driver stats */ + + struct sk_buff *rx_skb_list[SYN_DP_RX_DESC_SIZE]; /* Rx skb pool helping RX DMA descriptors*/ + + dma_addr_t rx_desc_dma; /* Dma-albe address of first rx descriptor + either in ring or chain mode, this is + used by the GMAC device */ + + struct dma_desc *rx_desc; /* start address of RX descriptors ring or + chain, this is used by the driver */ + + uint32_t busy_rx_desc; /* Number of Rx Descriptors owned by + DMA at any given time */ + + uint32_t rx_desc_count; /* number of rx descriptors in the + tx descriptor queue/pool */ + + uint32_t rx_busy; /* index of the rx descriptor owned by DMA, + obtained by nss_gmac_get_rx_qptr() */ + + uint32_t rx_next; /* index of the rx descriptor next available + with driver, given to DMA by + nss_gmac_set_rx_qptr()*/ + + struct dma_desc *rx_busy_desc; /* Rx Descriptor address corresponding + to the index tx_busy */ + + struct dma_desc *rx_next_desc; /* Rx Descriptor address corresponding + to the index rx_next */ + + struct sk_buff *tx_skb_list[SYN_DP_RX_DESC_SIZE]; /* Tx skb pool helping RX DMA descriptors*/ + + dma_addr_t tx_desc_dma; /* Dma-able address of first tx descriptor + either in ring or chain mode, this is used + by the GMAC device */ + + struct dma_desc *tx_desc; /* start address of TX descriptors ring or + chain, this is used by the driver */ + + uint32_t busy_tx_desc; /* Number of Tx Descriptors owned by + DMA at any given time */ + + uint32_t tx_desc_count; /* number of tx descriptors in the + rx descriptor queue/pool */ + + uint32_t tx_busy; /* index of the tx descriptor owned by DMA, + is obtained by nss_gmac_get_tx_qptr() */ + + uint32_t tx_next; /* index of the tx descriptor next available + with driver, given to DMA by + nss_gmac_set_tx_qptr() */ + + struct dma_desc *tx_busy_desc; /* Tx Descriptor address corresponding + to the index tx_busy */ + + struct dma_desc *tx_next_desc; /* Tx Descriptor address corresponding + to the index tx_next */ + + spinlock_t data_lock; /* Lock to protect datapath */ + spinlock_t stats_lock; /* Lock to protect datapath */ + int napi_added; /* flag to indicate napi add status */ +}; + +/* + * GMAC Tx/Tx APIs + */ +int syn_dp_setup_rings(struct nss_dp_dev *gmac_dev, struct net_device *netdev, struct device *dev, struct syn_dp_info *dev_info); +int syn_dp_cleanup_rings(struct nss_dp_dev *gmac_dev, struct net_device *netdev, struct syn_dp_info *dev_info); + +int syn_dp_rx(struct nss_dp_dev *gmac_dev, struct syn_dp_info *dev_info, int budget); +void syn_dp_rx_refill(struct nss_dp_dev *gmac_dev, struct syn_dp_info *dev_info); + +int syn_dp_tx(struct nss_dp_dev *gmac_dev, struct syn_dp_info *dev_info, struct sk_buff *skb); +void syn_dp_process_tx_complete(struct nss_dp_dev *gmac_dev, struct syn_dp_info *dev_info); + +#endif /* __NSS_DP_SYN_DATAPLANE__ */ \ No newline at end of file diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/syn_gmac_dp/syn_dma_desc.h b/feeds/ipq807x/qca-nss-dp/src/hal/syn_gmac_dp/syn_dma_desc.h new file mode 100644 index 000000000..5b50d388f --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/syn_gmac_dp/syn_dma_desc.h @@ -0,0 +1,342 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __SYN_DESC__ +#define __SYN_DESC__ + +/********************************************************** + * DMA Engine descriptors + **********************************************************/ +/* +******Enhanced Descritpor structure to support 8K buffer per buffer ******* + +dma_rx_base_addr = 0x000C, CSR3 - Receive Descriptor list base address +dma_rx_base_addr is the pointer to the first Rx Descriptors. +The Descriptor format in Little endian with a 32 bit Data bus is as shown below. + +Similarly +dma_tx_base_addr = 0x0010, CSR4 - Transmit Descriptor list base address +dma_tx_base_addr is the pointer to the first Tx Descriptors. +The Descriptor format in Little endian with a 32 bit Data bus is as shown below. + ------------------------------------------------------------------------- + RDES0 |OWN (31)| Status | + ------------------------------------------------------------------------- + RDES1 | Ctrl | Res | Byte Count Buffer 2 | Ctrl | Res | Byte Count Buffer 1 | + ------------------------------------------------------------------------- + RDES2 | Buffer 1 Address | + ------------------------------------------------------------------------- + RDES3 | Buffer 2 Address / Next Descriptor Address | + ------------------------------------------------------------------------- + RDES4 | Extended Status | + ------------------------------------------------------------------------- + RDES5 | Reserved | + ------------------------------------------------------------------------- + RDES6 | Receive Timestamp Low | + ------------------------------------------------------------------------- + RDES7 | Receive Timestamp High | + ------------------------------------------------------------------------- + + ------------------------------------------------------------------------ + TDES0 |OWN (31)| Ctrl | Res | Ctrl | Res | Status | + ------------------------------------------------------------------------ + TDES1 | Res | Byte Count Buffer 2 | Res | Byte Count Buffer 1 | + ------------------------------------------------------------------------ + TDES2 | Buffer 1 Address | + ------------------------------------------------------------------------ + TDES3 | Buffer 2 Address / Next Descriptor Address | + ------------------------------------------------------------------------ + TDES4 | Reserved | + ------------------------------------------------------------------------ + TDES5 | Reserved | + ------------------------------------------------------------------------ + TDES6 | Transmit Timestamp Low | + ------------------------------------------------------------------------ + TDES7 | Transmit Timestamp Higher | + ------------------------------------------------------------------------ +*/ + +/* + * dma_descriptor_status + * status word of DMA descriptor + */ +enum dma_descriptor_status { + desc_own_by_dma = 0x80000000, /* (OWN)Descriptor is + owned by DMA engine */ + desc_rx_da_filter_fail = 0x40000000, /* (AFM)Rx - DA Filter + Fail for the rx frame */ + desc_rx_frame_length_mask = 0x3FFF0000, /* (FL)Receive descriptor + frame length */ + desc_rx_frame_length_shift = 16, + desc_rx_error = 0x00008000, /* (ES)Error summary bit + - OR of the following bits: + DE || OE || IPC || GF || LC || RWT + || RE || CE */ + desc_rx_truncated = 0x00004000, /* (DE)Rx - no more descriptors + for receive frame */ + desc_sa_filter_fail = 0x00002000, /* (SAF)Rx - SA Filter Fail for + the received frame */ + desc_rx_length_error = 0x00001000, /* (LE)Rx - frm size not + matching with len field */ + desc_rx_overflow = 0x00000800, /* (OE)Rx - frm was damaged due + to buffer overflow */ + desc_rx_vlan_tag = 0x00000400, /* (VLAN)Rx - received frame + is a VLAN frame */ + desc_rx_first = 0x00000200, /* (FS)Rx - first + descriptor of the frame */ + desc_rx_last = 0x00000100, /* (LS)Rx - last + descriptor of the frame */ + desc_rx_long_frame = 0x00000080, /* (Giant Frame)Rx - frame is + longer than 1518/1522 */ + desc_rx_collision = 0x00000040, /* (LC)Rx - late collision + occurred during reception */ + desc_rx_frame_ether = 0x00000020, /* (FT)Rx - Frame type - Ether, + otherwise 802.3 */ + desc_rx_watchdog = 0x00000010, /* (RWT)Rx - watchdog timer + expired during reception */ + desc_rx_mii_error = 0x00000008, /* (RE)Rx - error reported + by MII interface */ + desc_rx_dribbling = 0x00000004, /* (DE)Rx - frame contains non + int multiple of 8 bits */ + desc_rx_crc = 0x00000002, /* (CE)Rx - CRC error */ + desc_rx_ext_sts = 0x00000001, /* Extended Status Available + in RDES4 */ + desc_tx_error = 0x00008000, /* (ES)Error summary Bits */ + desc_tx_int_enable = 0x40000000, /* (IC)Tx - interrupt on + completion */ + desc_tx_last = 0x20000000, /* (LS)Tx - Last segment of the + frame */ + desc_tx_first = 0x10000000, /* (FS)Tx - First segment of the + frame */ + desc_tx_disable_crc = 0x08000000, /* (DC)Tx - Add CRC disabled + (first segment only) */ + desc_tx_disable_padd = 0x04000000, /* (DP)disable padding, + added by - reyaz */ + desc_tx_cis_mask = 0x00c00000, /* Tx checksum offloading + control mask */ + desc_tx_cis_bypass = 0x00000000, /* Checksum bypass */ + desc_tx_cis_ipv4_hdr_cs = 0x00400000, /* IPv4 header checksum */ + desc_tx_cis_tcp_only_cs = 0x00800000, /* TCP/UDP/ICMP checksum. + Pseudo header checksum + is assumed to be present */ + desc_tx_cis_tcp_pseudo_cs = 0x00c00000, /* TCP/UDP/ICMP checksum fully + in hardware including + pseudo header */ + desc_tx_desc_end_of_ring = 0x00200000, /* (TER)End of descriptor ring*/ + desc_tx_desc_chain = 0x00100000, /* (TCH)Second buffer address + is chain address */ + desc_rx_chk_bit0 = 0x00000001, /* Rx Payload Checksum Error */ + desc_rx_chk_bit7 = 0x00000080, /* (IPC CS ERROR)Rx - Ipv4 + header checksum error */ + desc_rx_chk_bit5 = 0x00000020, /* (FT)Rx - Frame type - Ether, + otherwise 802.3 */ + desc_rx_ts_avail = 0x00000080, /* Time stamp available */ + desc_rx_frame_type = 0x00000020, /* (FT)Rx - Frame type - Ether, + otherwise 802.3 */ + desc_tx_ipv4_chk_error = 0x00010000, /* (IHE) Tx Ip header error */ + desc_tx_timeout = 0x00004000, /* (JT)Tx - Transmit + jabber timeout */ + desc_tx_frame_flushed = 0x00002000, /* (FF)Tx - DMA/MTL flushed + the frame due to SW flush */ + desc_tx_pay_chk_error = 0x00001000, /* (PCE) Tx Payload checksum + Error */ + desc_tx_lost_carrier = 0x00000800, /* (LC)Tx - carrier lost + during tramsmission */ + desc_tx_no_carrier = 0x00000400, /* (NC)Tx - no carrier signal + from the tranceiver */ + desc_tx_late_collision = 0x00000200, /* (LC)Tx - transmission aborted + due to collision */ + desc_tx_exc_collisions = 0x00000100, /* (EC)Tx - transmission aborted + after 16 collisions */ + desc_tx_vlan_frame = 0x00000080, /* (VF)Tx - VLAN-type frame */ + desc_tx_coll_mask = 0x00000078, /* (CC)Tx - Collision count */ + desc_tx_coll_shift = 3, + desc_tx_exc_deferral = 0x00000004, /* (ED)Tx - excessive deferral */ + desc_tx_underflow = 0x00000002, /* (UF)Tx - late data arrival + from the memory */ + desc_tx_deferred = 0x00000001, /* (DB)Tx - frame + transmision deferred */ + + /* + * This explains the RDES1/TDES1 bits layout + * ------------------------------------------------------ + * RDES1/TDES1 | Control Bits | Byte Count Buf 2 | Byte Count Buf 1 | + * ------------------------------------------------------ + */ + + /* dma_descriptor_length */ /* length word of DMA descriptor */ + desc_rx_dis_int_compl = 0x80000000, /* (Disable Rx int on completion) */ + desc_rx_desc_end_of_ring = 0x00008000, /* (RER)End of descriptor ring */ + desc_rx_desc_chain = 0x00004000, /* (RCH)Second buffer address + is chain address */ + desc_size2_mask = 0x1FFF0000, /* (RBS2/TBS2) Buffer 2 size */ + desc_size2_shift = 16, + desc_size1_mask = 0x00001FFF, /* (RBS1/TBS1) Buffer 1 size */ + desc_size1_shift = 0, + + /* + * This explains the RDES4 Extended Status bits layout + * -------------------------------------------------------- + * RDES4 | Extended Status | + * -------------------------------------------------------- + */ + desc_rx_ts_dropped = 0x00004000, /* PTP snapshot available */ + desc_rx_ptp_ver = 0x00002000, /* When set indicates IEEE1584 + Version 2 (else Ver1) */ + desc_rx_ptp_frame_type = 0x00001000, /* PTP frame type Indicates PTP + sent over ethernet */ + desc_rx_ptp_message_type = 0x00000F00, /* Message Type */ + desc_rx_ptp_no = 0x00000000, /* 0000 => No PTP message rcvd */ + desc_rx_ptp_sync = 0x00000100, /* 0001 => Sync (all clock + types) received */ + desc_rx_ptp_follow_up = 0x00000200, /* 0010 => Follow_Up (all clock + types) received */ + desc_rx_ptp_delay_req = 0x00000300, /* 0011 => Delay_Req (all clock + types) received */ + desc_rx_ptp_delay_resp = 0x00000400, /* 0100 => Delay_Resp (all clock + types) received */ + desc_rx_ptp_pdelay_req = 0x00000500, /* 0101 => Pdelay_Req (in P + to P tras clk) or Announce + in Ord and Bound clk */ + desc_rx_ptp_pdelay_resp = 0x00000600, /* 0110 => Pdealy_Resp(in P to + P trans clk) or Management in + Ord and Bound clk */ + desc_rx_ptp_pdelay_resp_fp = 0x00000700,/* 0111 => Pdelay_Resp_Follow_Up + (in P to P trans clk) or + Signaling in Ord and Bound + clk */ + desc_rx_ptp_ipv6 = 0x00000080, /* Received Packet is in IPV6 */ + desc_rx_ptp_ipv4 = 0x00000040, /* Received Packet is in IPV4 */ + desc_rx_chk_sum_bypass = 0x00000020, /* When set indicates checksum + offload engine is bypassed */ + desc_rx_ip_payload_error = 0x00000010, /* When set indicates 16bit IP + payload CS is in error */ + desc_rx_ip_header_error = 0x00000008, /* When set indicates 16bit IPV4 + hdr CS is err or IP datagram + version is not consistent + with Ethernet type value */ + desc_rx_ip_payload_type = 0x00000007, /* Indicate the type of payload + encapsulated in IPdatagram + processed by COE (Rx) */ + desc_rx_ip_payload_unknown = 0x00000000,/* Unknown or didnot process + IP payload */ + desc_rx_ip_payload_udp = 0x00000001, /* UDP */ + desc_rx_ip_payload_tcp = 0x00000002, /* TCP */ + desc_rx_ip_payload_icmp = 0x00000003, /* ICMP */ +}; + +/* + * dma_desc + * DMA Descriptor Structure + * + * The structure is common for both receive and transmit descriptors. + */ +struct dma_desc { + uint32_t status; /* Status */ + uint32_t length; /* Buffer 1 and Buffer 2 length */ + uint32_t buffer1; /* Network Buffer 1 pointer (DMA-able)*/ + uint32_t data1; /* This holds virtual address of + buffer1, not used by DMA */ + + /* This data below is used only by driver */ + uint32_t extstatus; /* Extended status of a Rx Descriptor */ + uint32_t reserved1; /* Reserved word */ + uint32_t timestamplow; /* Lower 32 bits of the 64 + bit timestamp value */ + uint32_t timestamphigh; /* Higher 32 bits of the 64 + bit timestamp value */ +}; + +/* + * syn_dp_gmac_tx_checksum_offload_tcp_pseudo + * The checksum offload engine is enabled to do complete checksum computation. + */ +static inline void syn_dp_gmac_tx_checksum_offload_tcp_pseudo(struct dma_desc *desc) +{ + desc->status = ((desc->status & (~desc_tx_cis_mask)) | desc_tx_cis_tcp_pseudo_cs); +} + +/* + * syn_dp_gmac_tx_desc_init_ring + * Initialize the tx descriptors for ring or chain mode operation. + */ +static inline void syn_dp_gmac_tx_desc_init_ring(struct dma_desc *desc, uint32_t no_of_desc) +{ + struct dma_desc *last_desc = desc + no_of_desc - 1; + memset(desc, 0, no_of_desc * sizeof(struct dma_desc)); + last_desc->status = desc_tx_desc_end_of_ring; +} + +/* + * syn_dp_gmac_rx_desc_init_ring + * Initialize the rx descriptors for ring or chain mode operation. + */ +static inline void syn_dp_gmac_rx_desc_init_ring(struct dma_desc *desc, uint32_t no_of_desc) +{ + struct dma_desc *last_desc = desc + no_of_desc - 1; + memset(desc, 0, no_of_desc * sizeof(struct dma_desc)); + last_desc->length = desc_rx_desc_end_of_ring; +} + +/* + * syn_dp_gmac_is_rx_desc_valid + * Checks whether the rx descriptor is valid. + */ +static inline bool syn_dp_gmac_is_rx_desc_valid(uint32_t status) +{ + return (status & (desc_rx_error | desc_rx_first | desc_rx_last)) == + (desc_rx_first | desc_rx_last); +} + +/* + * syn_dp_gmac_get_rx_desc_frame_length + * Returns the byte length of received frame including CRC. + */ +static inline uint32_t syn_dp_gmac_get_rx_desc_frame_length(uint32_t status) +{ + return (status & desc_rx_frame_length_mask) >> desc_rx_frame_length_shift; +} + +/* + * syn_dp_gmac_is_desc_owned_by_dma + * Checks whether the descriptor is owned by DMA. + */ +static inline bool syn_dp_gmac_is_desc_owned_by_dma(struct dma_desc *desc) +{ + return (desc->status & desc_own_by_dma) == desc_own_by_dma; +} + +/* + * syn_dp_gmac_is_desc_empty + * Checks whether the descriptor is empty. + */ +static inline bool syn_dp_gmac_is_desc_empty(struct dma_desc *desc) +{ + /* + * If length of both buffer1 & buffer2 are zero then desc is empty + */ + return (desc->length & desc_size1_mask) == 0; +} + +/* + * syn_dp_gmac_get_tx_collision_count + * Gives the transmission collision count. + */ +static inline uint32_t syn_dp_gmac_get_tx_collision_count(uint32_t status) +{ + return (status & desc_tx_coll_mask) >> desc_tx_coll_shift; +} + +#endif /* __SYN_DESC__ */ \ No newline at end of file diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/syn_gmac_dp/syn_dp_cfg.c b/feeds/ipq807x/qca-nss-dp/src/hal/syn_gmac_dp/syn_dp_cfg.c new file mode 100644 index 000000000..ff1869990 --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/syn_gmac_dp/syn_dp_cfg.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include "nss_dp_dev.h" +#include "syn_data_plane.h" +#include "syn_reg.h" + +/* + * syn_dp_setup_rx_desc_queue + * This sets up the receive Descriptor queue in ring or chain mode. + */ +static int syn_dp_setup_rx_desc_queue(struct net_device *netdev, struct device *dev, struct syn_dp_info *dev_info, + uint32_t no_of_desc, uint32_t desc_mode) +{ + struct dma_desc *first_desc = NULL; + dma_addr_t dma_addr; + + dev_info->rx_desc_count = 0; + + BUG_ON(desc_mode != RINGMODE); + BUG_ON((no_of_desc & (no_of_desc - 1)) != 0); + + netdev_dbg(netdev, "total size of memory required for Rx Descriptors in Ring Mode = %u\n", (uint32_t)((sizeof(struct dma_desc) * no_of_desc))); + + first_desc = dma_alloc_coherent(dev, sizeof(struct dma_desc) * no_of_desc, &dma_addr, GFP_KERNEL); + if (first_desc == NULL) { + netdev_dbg(netdev, "Error in Rx Descriptor Memory allocation in Ring mode\n"); + return -ENOMEM; + } + + dev_info->rx_desc_count = no_of_desc; + dev_info->rx_desc = first_desc; + dev_info->rx_desc_dma = dma_addr; + + netdev_dbg(netdev, "Rx Descriptors in Ring Mode: No. of descriptors = %d base = 0x%px dma = 0x%px\n", + no_of_desc, first_desc, (void *)dma_addr); + + syn_dp_gmac_rx_desc_init_ring(dev_info->rx_desc, no_of_desc); + + dev_info->rx_next = 0; + dev_info->rx_busy = 0; + dev_info->rx_next_desc = first_desc; + dev_info->rx_busy_desc = first_desc; + dev_info->busy_rx_desc = 0; + + return 0; +} + +/* + * syn_dp_setup_tx_desc_queue + * This sets up the transmit Descriptor queue in ring or chain mode. + */ +static int syn_dp_setup_tx_desc_queue(struct net_device *netdev, struct device *dev, struct syn_dp_info *dev_info, + uint32_t no_of_desc, uint32_t desc_mode) +{ + struct dma_desc *first_desc = NULL; + dma_addr_t dma_addr; + + dev_info->tx_desc_count = 0; + + BUG_ON(desc_mode != RINGMODE); + BUG_ON((no_of_desc & (no_of_desc - 1)) != 0); + + netdev_dbg(netdev, "Total size of memory required for Tx Descriptors in Ring Mode = %u\n", (uint32_t)((sizeof(struct dma_desc) * no_of_desc))); + + first_desc = dma_alloc_coherent(dev, sizeof(struct dma_desc) * no_of_desc, &dma_addr, GFP_KERNEL); + if (first_desc == NULL) { + netdev_dbg(netdev, "Error in Tx Descriptors memory allocation\n"); + return -ENOMEM; + } + + dev_info->tx_desc_count = no_of_desc; + dev_info->tx_desc = first_desc; + dev_info->tx_desc_dma = dma_addr; + netdev_dbg(netdev, "Tx Descriptors in Ring Mode: No. of descriptors = %d base = 0x%px dma = 0x%px\n" + , no_of_desc, first_desc, (void *)dma_addr); + + syn_dp_gmac_tx_desc_init_ring(dev_info->tx_desc, dev_info->tx_desc_count); + + dev_info->tx_next = 0; + dev_info->tx_busy = 0; + dev_info->tx_next_desc = first_desc; + dev_info->tx_busy_desc = first_desc; + dev_info->busy_tx_desc = 0; + + return 0; +} + +/* + * syn_dp_setup_rings + * Perform initial setup of Tx/Rx rings + */ +int syn_dp_setup_rings(struct nss_dp_dev *gmac_dev, struct net_device *netdev, struct device *dev, struct syn_dp_info *dev_info) +{ + struct nss_gmac_hal_dev *nghd = gmac_dev->gmac_hal_ctx; + int err; + + err = syn_dp_setup_rx_desc_queue(netdev, dev, dev_info, SYN_DP_RX_DESC_SIZE, RINGMODE); + if (err) { + netdev_dbg(netdev, "nss_dp_gmac: rx descriptor setup unsuccessfull, err code: %d", err); + return NSS_DP_FAILURE; + } + + err = syn_dp_setup_tx_desc_queue(netdev, dev, dev_info, SYN_DP_TX_DESC_SIZE, RINGMODE); + if (err) { + netdev_dbg(netdev, "nss_dp_gmac: tx descriptor setup unsuccessfull, err code: %d", err); + return NSS_DP_FAILURE; + } + + syn_dp_rx_refill(gmac_dev, dev_info); + + syn_init_tx_desc_base(nghd, dev_info->tx_desc_dma); + syn_init_rx_desc_base(nghd, dev_info->rx_desc_dma); + + return NSS_DP_SUCCESS; +} + +/* + * syn_dp_cleanup_rings + * Cleanup Synopsys GMAC rings + */ +int syn_dp_cleanup_rings(struct nss_dp_dev *gmac_dev, struct net_device *netdev, struct syn_dp_info *dev_info) +{ + uint32_t rx_skb_index; + struct dma_desc *rxdesc; + + uint32_t tx_skb_index; + struct dma_desc *txdesc; + int i; + struct sk_buff *skb; + + /* + * Rx Ring cleaning + * We are assuming that the NAPI poll was already completed. + * No need of a lock here since the NAPI and interrupts have been disabled now + */ + rx_skb_index = dev_info->rx_busy; + for (i = 0; i < dev_info->busy_rx_desc; i++) { + rx_skb_index = rx_skb_index & (dev_info->rx_desc_count - 1); + rxdesc = dev_info->rx_busy_desc; + + dma_unmap_single(&(gmac_dev->netdev->dev), rxdesc->buffer1, + SYN_DP_MINI_JUMBO_FRAME_MTU, DMA_FROM_DEVICE); + + skb = dev_info->rx_skb_list[rx_skb_index]; + if (unlikely(skb != NULL)) { + dev_kfree_skb(skb); + dev_info->rx_skb_list[rx_skb_index] = NULL; + } + } + + dma_free_coherent(&(gmac_dev->netdev->dev), (sizeof(struct dma_desc) * SYN_DP_RX_DESC_SIZE), + dev_info->rx_desc, dev_info->rx_desc_dma); + + /* + * Tx Ring cleaning + */ + spin_lock_bh(&dev_info->data_lock); + + tx_skb_index = dev_info->tx_busy; + for (i = 0; i < dev_info->busy_tx_desc; i++) { + tx_skb_index = tx_skb_index & (dev_info->tx_desc_count - 1); + txdesc = dev_info->tx_busy_desc; + + dma_unmap_single(&(gmac_dev->netdev->dev), txdesc->buffer1, + SYN_DP_MINI_JUMBO_FRAME_MTU, DMA_FROM_DEVICE); + + skb = dev_info->tx_skb_list[tx_skb_index]; + if (unlikely(skb != NULL)) { + dev_kfree_skb(skb); + dev_info->tx_skb_list[tx_skb_index] = NULL; + } + } + + spin_unlock_bh(&dev_info->data_lock); + + dma_free_coherent(&(gmac_dev->netdev->dev), (sizeof(struct dma_desc) * SYN_DP_TX_DESC_SIZE), + dev_info->tx_desc, dev_info->tx_desc_dma); + + return 0; +} \ No newline at end of file diff --git a/feeds/ipq807x/qca-nss-dp/src/hal/syn_gmac_dp/syn_dp_tx_rx.c b/feeds/ipq807x/qca-nss-dp/src/hal/syn_gmac_dp/syn_dp_tx_rx.c new file mode 100644 index 000000000..ea01884d8 --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/hal/syn_gmac_dp/syn_dp_tx_rx.c @@ -0,0 +1,425 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include + +#include "syn_data_plane.h" +#include "syn_reg.h" + +/* + * syn_dp_reset_rx_qptr + * Reset the descriptor after Rx is over. + */ +static inline void syn_dp_reset_rx_qptr(struct nss_dp_dev *gmac_dev, struct syn_dp_info *dev_info) +{ + + /* Index of descriptor the DMA just completed. + * May be useful when data is spread over multiple buffers/descriptors + */ + uint32_t rxnext = dev_info->rx_busy; + struct dma_desc *rxdesc = dev_info->rx_busy_desc; + + BUG_ON(rxdesc != (dev_info->rx_desc + rxnext)); + dev_info->rx_busy = (rxnext + 1) & (dev_info->rx_desc_count - 1); + dev_info->rx_busy_desc = dev_info->rx_desc + dev_info->rx_busy; + + dev_info->rx_skb_list[rxnext] = NULL; + rxdesc->status = 0; + rxdesc->length &= desc_rx_desc_end_of_ring; + rxdesc->buffer1 = 0; + rxdesc->data1 = 0; + rxdesc->reserved1 = 0; + + /* + * This returns one descriptor to processor. So busy count will be decremented by one. + */ + dev_info->busy_rx_desc--; +} + +/* + * syn_dp_set_rx_qptr + * Prepares the descriptor to receive packets. + */ +static inline int32_t syn_dp_set_rx_qptr(struct nss_dp_dev *gmac_dev, struct syn_dp_info *dev_info, + uint32_t Buffer1, uint32_t Length1, struct sk_buff *skb) +{ + uint32_t rxnext = dev_info->rx_next; + struct dma_desc *rxdesc = dev_info->rx_next_desc; + uint32_t rx_skb_index = rxnext; + + BUG_ON(dev_info->busy_rx_desc >= dev_info->rx_desc_count); + BUG_ON(rxdesc != (dev_info->rx_desc + rxnext)); + BUG_ON(!syn_dp_gmac_is_desc_empty(rxdesc)); + BUG_ON(syn_dp_gmac_is_desc_owned_by_dma(rxdesc)); + + if (Length1 > SYN_DP_MAX_DESC_BUFF) { + rxdesc->length |= (SYN_DP_MAX_DESC_BUFF << desc_size1_shift) & desc_size1_mask; + rxdesc->length |= ((Length1 - SYN_DP_MAX_DESC_BUFF) << desc_size2_shift) & desc_size2_mask; + } else { + rxdesc->length |= ((Length1 << desc_size1_shift) & desc_size1_mask); + } + + rxdesc->buffer1 = Buffer1; + dev_info->rx_skb_list[rx_skb_index] = skb; + + /* Program second buffer address if using two buffers. */ + if (Length1 > SYN_DP_MAX_DESC_BUFF) + rxdesc->data1 = Buffer1 + SYN_DP_MAX_DESC_BUFF; + else + rxdesc->data1 = 0; + + rxdesc->extstatus = 0; + rxdesc->timestamplow = 0; + rxdesc->timestamphigh = 0; + + /* + * Ensure all write completed before setting own by dma bit so when gmac + * HW takeover this descriptor, all the fields are filled correctly + */ + wmb(); + rxdesc->status = desc_own_by_dma; + + dev_info->rx_next = (rxnext + 1) & (dev_info->rx_desc_count - 1); + dev_info->rx_next_desc = dev_info->rx_desc + dev_info->rx_next; + + /* + * 1 descriptor will be given to HW. So busy count incremented by 1. + */ + dev_info->busy_rx_desc++; + + return rxnext; +} + +/* + * syn_dp_rx_refill + * Refill the RX descrptor + */ +void syn_dp_rx_refill(struct nss_dp_dev *gmac_dev, struct syn_dp_info *dev_info) +{ + struct net_device *netdev = gmac_dev->netdev; + struct device *dev = &gmac_dev->pdev->dev; + int empty_count = SYN_DP_RX_DESC_SIZE - dev_info->busy_rx_desc; + + dma_addr_t dma_addr; + int i; + struct sk_buff *skb; + + for (i = 0; i < empty_count; i++) { + skb = __netdev_alloc_skb(netdev, SYN_DP_MINI_JUMBO_FRAME_MTU, GFP_ATOMIC); + if (unlikely(skb == NULL)) { + netdev_dbg(netdev, "Unable to allocate skb, will try next time\n"); + break; + } + + skb_reserve(skb, NET_IP_ALIGN); + + dma_addr = dma_map_single(dev, skb->data, SYN_DP_MINI_JUMBO_FRAME_MTU, DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(dev, dma_addr))) { + dev_kfree_skb(skb); + netdev_dbg(netdev, "DMA mapping failed for empty buffer\n"); + break; + } + + syn_dp_set_rx_qptr(gmac_dev, dev_info, dma_addr, SYN_DP_MINI_JUMBO_FRAME_MTU, skb); + } +} + +/* + * syn_dp_rx() + * Process RX packets + */ +int syn_dp_rx(struct nss_dp_dev *gmac_dev, struct syn_dp_info *dev_info, int budget) +{ + struct dma_desc *desc = NULL; + int frame_length, busy; + uint32_t status; + struct sk_buff *rx_skb; + uint32_t rx_skb_index; + + if (!dev_info->busy_rx_desc) { + /* no desc are held by gmac dma, we are done */ + return 0; + } + + busy = dev_info->busy_rx_desc; + if (busy > budget) + busy = budget; + + do { + desc = dev_info->rx_busy_desc; + if (syn_dp_gmac_is_desc_owned_by_dma(desc)) { + /* desc still hold by gmac dma, so we are done */ + break; + } + + status = desc->status; + + rx_skb_index = dev_info->rx_busy; + rx_skb = dev_info->rx_skb_list[rx_skb_index]; + + dma_unmap_single(&(gmac_dev->netdev->dev), desc->buffer1, + SYN_DP_MINI_JUMBO_FRAME_MTU, DMA_FROM_DEVICE); + + spin_lock_bh(&dev_info->stats_lock); + if (likely(syn_dp_gmac_is_rx_desc_valid(status))) { + /* We have a pkt to process get the frame length */ + frame_length = syn_dp_gmac_get_rx_desc_frame_length(status); + /* Get rid of FCS: 4 */ + frame_length -= ETH_FCS_LEN; + + /* Valid packet, collect stats */ + dev_info->stats.stats.rx_packets++; + dev_info->stats.stats.rx_bytes += frame_length; + + /* type_trans and deliver to linux */ + skb_put(rx_skb, frame_length); + rx_skb->protocol = eth_type_trans(rx_skb, gmac_dev->netdev); + rx_skb->ip_summed = CHECKSUM_UNNECESSARY; + napi_gro_receive(&gmac_dev->napi, rx_skb); + + } else { + dev_info->stats.stats.rx_errors++; + dev_kfree_skb(rx_skb); + + if (status & (desc_rx_crc | desc_rx_collision | + desc_rx_overflow | desc_rx_dribbling | + desc_rx_length_error)) { + dev_info->stats.stats.mmc_rx_crc_errors += (status & desc_rx_crc) ? 1 : 0; + dev_info->stats.stats.rx_late_collision_errors += (status & desc_rx_collision) ? 1 : 0; + dev_info->stats.stats.mmc_rx_overflow_errors += (status & desc_rx_overflow) ? 1 : 0; + dev_info->stats.stats.rx_dribble_bit_errors += (status & desc_rx_dribbling) ? 1 : 0; + dev_info->stats.stats.rx_length_errors += (status & desc_rx_length_error) ? 1 : 0; + } + } + + spin_unlock_bh(&dev_info->stats_lock); + + syn_dp_reset_rx_qptr(gmac_dev, dev_info); + busy--; + } while (busy > 0); + return budget - busy; +} + +/* + * syn_dp_reset_tx_qptr + * Reset the descriptor after Tx is over. + */ +static inline void syn_dp_reset_tx_qptr(struct nss_dp_dev *gmac_dev, struct syn_dp_info *dev_info) +{ + uint32_t txover = dev_info->tx_busy; + struct dma_desc *txdesc = dev_info->tx_busy_desc; + + BUG_ON(txdesc != (dev_info->tx_desc + txover)); + dev_info->tx_busy = (txover + 1) & (dev_info->tx_desc_count - 1); + dev_info->tx_busy_desc = dev_info->tx_desc + dev_info->tx_busy; + + dev_info->tx_skb_list[txover] = NULL; + txdesc->status &= desc_tx_desc_end_of_ring; + txdesc->length = 0; + txdesc->buffer1 = 0; + txdesc->data1 = 0; + txdesc->reserved1 = 0; + + /* + * Busy tx descriptor is reduced by one as + * it will be handed over to Processor now. + */ + dev_info->busy_tx_desc--; +} + +/* + * syn_dp_set_tx_qptr + * Populate the tx desc structure with the buffer address. + */ +static inline struct dma_desc *syn_dp_set_tx_qptr(struct nss_dp_dev *gmac_dev, struct syn_dp_info *dev_info, + uint32_t Buffer1, uint32_t Length1, struct sk_buff *skb, uint32_t offload_needed, + uint32_t tx_cntl, uint32_t set_dma) +{ + uint32_t txnext = dev_info->tx_next; + struct dma_desc *txdesc = dev_info->tx_next_desc; + uint32_t tx_skb_index = txnext; + + BUG_ON(dev_info->busy_tx_desc > dev_info->tx_desc_count); + BUG_ON(txdesc != (dev_info->tx_desc + txnext)); + BUG_ON(!syn_dp_gmac_is_desc_empty(txdesc)); + BUG_ON(syn_dp_gmac_is_desc_owned_by_dma(txdesc)); + + if (Length1 > SYN_DP_MAX_DESC_BUFF) { + txdesc->length |= (SYN_DP_MAX_DESC_BUFF << desc_size1_shift) & desc_size1_mask; + txdesc->length |= + ((Length1 - SYN_DP_MAX_DESC_BUFF) << desc_size2_shift) & desc_size2_mask; + } else { + txdesc->length |= ((Length1 << desc_size1_shift) & desc_size1_mask); + } + + txdesc->status |= tx_cntl; + txdesc->buffer1 = Buffer1; + + dev_info->tx_skb_list[tx_skb_index] = skb; + + /* Program second buffer address if using two buffers. */ + if (Length1 > SYN_DP_MAX_DESC_BUFF) + txdesc->data1 = Buffer1 + SYN_DP_MAX_DESC_BUFF; + else + txdesc->data1 = 0; + + if (likely(offload_needed)) { + syn_dp_gmac_tx_checksum_offload_tcp_pseudo(txdesc); + } + + /* + * Ensure all write completed before setting own by dma bit so when gmac + * HW takeover this descriptor, all the fields are filled correctly + */ + wmb(); + txdesc->status |= set_dma; + + dev_info->tx_next = (txnext + 1) & (dev_info->tx_desc_count - 1); + dev_info->tx_next_desc = dev_info->tx_desc + dev_info->tx_next; + + return txdesc; +} + +/* + * syn_dp_tx_queue_desc + * Queue TX descriptor to the TX ring + */ +static void syn_dp_tx_desc_queue(struct nss_dp_dev *gmac_dev, struct syn_dp_info *dev_info, struct sk_buff *skb, dma_addr_t dma_addr) +{ + unsigned int len = skb->len; + + spin_lock_bh(&dev_info->data_lock); + + syn_dp_set_tx_qptr(gmac_dev, dev_info, dma_addr, len, skb, (skb->ip_summed == CHECKSUM_PARTIAL), + (desc_tx_last | desc_tx_first | desc_tx_int_enable), desc_own_by_dma); + dev_info->busy_tx_desc++; + + spin_unlock_bh(&dev_info->data_lock); +} + +/* + * syn_dp_process_tx_complete + * Xmit complete, clear descriptor and free the skb + */ +void syn_dp_process_tx_complete(struct nss_dp_dev *gmac_dev, struct syn_dp_info *dev_info) +{ + int busy, len; + uint32_t status; + struct dma_desc *desc = NULL; + struct sk_buff *skb; + uint32_t tx_skb_index; + + spin_lock_bh(&dev_info->data_lock); + busy = dev_info->busy_tx_desc; + + if (!busy) { + /* No desc are hold by gmac dma, we are done */ + spin_unlock_bh(&dev_info->data_lock); + return; + } + + do { + desc = dev_info->tx_busy_desc; + if (syn_dp_gmac_is_desc_owned_by_dma(desc)) { + /* desc still hold by gmac dma, so we are done */ + break; + } + + len = (desc->length & desc_size1_mask) >> desc_size1_shift; + dma_unmap_single(&(gmac_dev->pdev->dev), desc->buffer1, len, DMA_TO_DEVICE); + + status = desc->status; + if (status & desc_tx_last) { + /* TX is done for this whole skb, we can free it */ + /* Get the skb from the tx skb pool */ + tx_skb_index = dev_info->tx_busy; + skb = dev_info->tx_skb_list[tx_skb_index]; + + BUG_ON(!skb); + dev_kfree_skb(skb); + + spin_lock_bh(&dev_info->stats_lock); + + if (unlikely(status & desc_tx_error)) { + /* Some error happen, collect statistics */ + dev_info->stats.stats.tx_errors++; + dev_info->stats.stats.tx_jabber_timeout_errors += (status & desc_tx_timeout) ? 1 : 0; + dev_info->stats.stats.tx_frame_flushed_errors += (status & desc_tx_frame_flushed) ? 1 : 0; + dev_info->stats.stats.tx_loss_of_carrier_errors += (status & desc_tx_lost_carrier) ? 1 : 0; + dev_info->stats.stats.tx_no_carrier_errors += (status & desc_tx_no_carrier) ? 1 : 0; + dev_info->stats.stats.tx_late_collision_errors += (status & desc_tx_late_collision) ? 1 : 0; + dev_info->stats.stats.tx_excessive_collision_errors += (status & desc_tx_exc_collisions) ? 1 : 0; + dev_info->stats.stats.tx_excessive_deferral_errors += (status & desc_tx_exc_deferral) ? 1 : 0; + dev_info->stats.stats.tx_underflow_errors += (status & desc_tx_underflow) ? 1 : 0; + dev_info->stats.stats.tx_ip_header_errors += (status & desc_tx_ipv4_chk_error) ? 1 : 0; + dev_info->stats.stats.tx_ip_payload_errors += (status & desc_tx_pay_chk_error) ? 1 : 0; + } else { + /* No error, recored tx pkts/bytes and + * collision + */ + dev_info->stats.stats.tx_packets++; + dev_info->stats.stats.tx_collisions += syn_dp_gmac_get_tx_collision_count(status); + dev_info->stats.stats.tx_bytes += len; + } + + spin_unlock_bh(&dev_info->stats_lock); + } + syn_dp_reset_tx_qptr(gmac_dev, dev_info); + busy--; + } while (busy > 0); + + spin_unlock_bh(&dev_info->data_lock); +} + +/* + * syn_dp_tx + * TX routine for Synopsys GMAC + */ +int syn_dp_tx(struct nss_dp_dev *gmac_dev, struct syn_dp_info *dev_info, struct sk_buff *skb) +{ + struct net_device *netdev = gmac_dev->netdev; + struct nss_gmac_hal_dev *nghd = gmac_dev->gmac_hal_ctx; + unsigned len = skb->len; + dma_addr_t dma_addr; + + /* + * If we don't have enough tx descriptor for this pkt, return busy. + */ + if ((SYN_DP_TX_DESC_SIZE - dev_info->busy_tx_desc) < 1) { + netdev_dbg(netdev, "Not enough descriptors available"); + return -1; + } + + dma_addr = dma_map_single(&gmac_dev->pdev->dev, skb->data, len, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(&gmac_dev->pdev->dev, dma_addr))) { + netdev_dbg(netdev, "DMA mapping failed for empty buffer\n"); + return -1; + } + + /* + * Queue packet to the GMAC rings + */ + syn_dp_tx_desc_queue(gmac_dev, dev_info, skb, dma_addr); + + syn_resume_dma_tx(nghd); + + return 0; +} \ No newline at end of file diff --git a/feeds/ipq807x/qca-nss-dp/src/include/nss_dp_dev.h b/feeds/ipq807x/qca-nss-dp/src/include/nss_dp_dev.h new file mode 100644 index 000000000..439777349 --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/include/nss_dp_dev.h @@ -0,0 +1,132 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_DP_DEV_H__ +#define __NSS_DP_DEV_H__ + +#include +#include +#include +#include +#include +#include +#include + +#include "nss_dp_api_if.h" +#include "nss_dp_hal_if.h" + +#define NSS_DP_ACL_DEV_ID 0 + +struct nss_dp_global_ctx; + +/* + * nss data plane device structure + */ +struct nss_dp_dev { + uint32_t macid; /* Sequence# of Mac on the platform */ + uint32_t vsi; /* vsi number */ + unsigned long flags; /* Status flags */ + unsigned long drv_flags; /* Driver specific feature flags */ + + /* Phy related stuff */ + struct phy_device *phydev; /* Phy device */ + struct mii_bus *miibus; /* MII bus */ + uint32_t phy_mii_type; /* RGMII/SGMII/QSGMII */ + uint32_t phy_mdio_addr; /* Mdio address */ + bool link_poll; /* Link polling enable? */ + uint32_t forced_speed; /* Forced speed? */ + uint32_t forced_duplex; /* Forced duplex? */ + uint32_t link_state; /* Current link state */ + uint32_t pause; /* Current flow control settings */ + + struct net_device *netdev; + struct platform_device *pdev; + struct napi_struct napi; + + struct nss_dp_data_plane_ctx *dpc; + /* context when NSS owns GMACs */ + struct nss_dp_data_plane_ops *data_plane_ops; + /* ops for each data plane */ + struct nss_dp_global_ctx *ctx; /* Global NSS DP context */ + struct nss_gmac_hal_dev *gmac_hal_ctx; /* context of gmac hal */ + struct nss_gmac_hal_ops *gmac_hal_ops; /* GMAC HAL OPS */ + + /* switchdev related attributes */ +#ifdef CONFIG_NET_SWITCHDEV + u8 stp_state; /* STP state of this physical port */ + unsigned long brport_flags; /* bridge port flags */ +#endif +}; + +/* + * nss data plane global context + */ +struct nss_dp_global_ctx { + struct nss_dp_dev *nss_dp[NSS_DP_HAL_MAX_PORTS]; + struct nss_gmac_hal_ops *gmac_hal_ops[GMAC_HAL_TYPE_MAX]; + /* GMAC HAL OPS */ + bool common_init_done; /* Flag to hold common init state */ + uint8_t slowproto_acl_bm; /* Port bitmap to allow slow protocol packets */ +}; + +/* Global data */ +extern struct nss_dp_global_ctx dp_global_ctx; +extern struct nss_dp_data_plane_ctx dp_global_data_plane_ctx[NSS_DP_HAL_MAX_PORTS]; + +/* + * nss data plane link state + */ +enum nss_dp_link_state { + __NSS_DP_LINK_UP, /* Indicate link is UP */ + __NSS_DP_LINK_DOWN /* Indicate link is down */ +}; + +/* + * nss data plane status + */ +enum nss_dp_state { + __NSS_DP_UP, /* set to indicate the interface is UP */ + __NSS_DP_RXCSUM, /* Rx checksum enabled */ + __NSS_DP_AUTONEG, /* Autonegotiation Enabled */ + __NSS_DP_LINKPOLL, /* Poll link status */ +}; + +/* + * nss data plane private flags + */ +enum nss_dp_priv_flags { + __NSS_DP_PRIV_FLAG_INIT_DONE, + __NSS_DP_PRIV_FLAG_IRQ_REQUESTED, + __NSS_DP_PRIV_FLAG_MAX, +}; +#define NSS_DP_PRIV_FLAG(x) (1 << __NSS_DP_PRIV_FLAG_ ## x) + +/* + * nss_dp_set_ethtool_ops() + */ +void nss_dp_set_ethtool_ops(struct net_device *netdev); + +/* + * nss data plane switchdev helpers + */ +#ifdef CONFIG_NET_SWITCHDEV +void nss_dp_switchdev_setup(struct net_device *dev); +bool nss_dp_is_phy_dev(struct net_device *dev); +#endif + +#endif /* __NSS_DP_DEV_H__ */ diff --git a/feeds/ipq807x/qca-nss-dp/src/nss_dp_attach.c b/feeds/ipq807x/qca-nss-dp/src/nss_dp_attach.c new file mode 100644 index 000000000..94e8f6900 --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/nss_dp_attach.c @@ -0,0 +1,192 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2017, 2019-2020 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include +#include "nss_dp_hal.h" + +/* + * nss_dp_reset_netdev_features() + * Resets the netdev features + */ +static inline void nss_dp_reset_netdev_features(struct net_device *netdev) +{ + netdev->features = 0; + netdev->hw_features = 0; + netdev->vlan_features = 0; + netdev->wanted_features = 0; +} + +/* + * nss_dp_receive() + * Called by overlay drivers to deliver packets to nss-dp + */ +void nss_dp_receive(struct net_device *netdev, struct sk_buff *skb, + struct napi_struct *napi) +{ + struct nss_dp_dev *dp_dev = netdev_priv(netdev); + + skb->dev = netdev; + skb->protocol = eth_type_trans(skb, netdev); + netdev_dbg(netdev, "Rx on port%d, packet len %d, CSUM %d\n", + dp_dev->macid, skb->len, skb->ip_summed); + +#ifdef CONFIG_NET_SWITCHDEV +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) + skb->offload_fwd_mark = netdev->offload_fwd_mark; +#else + /* + * TODO: Implement ndo_get_devlink_port() + */ + skb->offload_fwd_mark = 0; +#endif +#endif + + napi_gro_receive(napi, skb); +} +EXPORT_SYMBOL(nss_dp_receive); + +/* + * nss_dp_is_in_open_state() + * Return if a data plane is opened or not + */ +bool nss_dp_is_in_open_state(struct net_device *netdev) +{ + struct nss_dp_dev *dp_dev = (struct nss_dp_dev *)netdev_priv(netdev); + + if (test_bit(__NSS_DP_UP, &dp_dev->flags)) + return true; + return false; +} +EXPORT_SYMBOL(nss_dp_is_in_open_state); + +/* + * nss_dp_override_data_plane() + * API to allow overlay drivers to override the data plane + */ +int nss_dp_override_data_plane(struct net_device *netdev, + struct nss_dp_data_plane_ops *dp_ops, + struct nss_dp_data_plane_ctx *dpc) +{ + struct nss_dp_dev *dp_dev = (struct nss_dp_dev *)netdev_priv(netdev); + + if (!dp_ops->open || !dp_ops->close || !dp_ops->link_state + || !dp_ops->mac_addr || !dp_ops->change_mtu || !dp_ops->xmit + || !dp_ops->set_features || !dp_ops->pause_on_off || !dp_ops->deinit) { + netdev_dbg(netdev, "All the op functions must be present, reject this registeration\n"); + return NSS_DP_FAILURE; + } + + /* + * If this data plane is up, close the netdev to force TX/RX stop, and + * also reset the features + */ + if (test_bit(__NSS_DP_UP, &dp_dev->flags)) { + netdev->netdev_ops->ndo_stop(netdev); + nss_dp_reset_netdev_features(netdev); + } + + /* + * Free up the resources used by the data plane + */ + if (dp_dev->drv_flags & NSS_DP_PRIV_FLAG(INIT_DONE)) { + if (dp_dev->data_plane_ops->deinit(dpc)) { + netdev_dbg(netdev, "Data plane init failed\n"); + return -ENOMEM; + } + + dp_dev->drv_flags &= ~NSS_DP_PRIV_FLAG(INIT_DONE); + } + + /* + * Override the data_plane_ctx, data_plane_ops + */ + dp_dev->dpc = dpc; + dp_dev->data_plane_ops = dp_ops; + + return NSS_DP_SUCCESS; +} +EXPORT_SYMBOL(nss_dp_override_data_plane); + +/* + * nss_dp_start_data_plane() + * Data plane to inform netdev it is ready to start + */ +void nss_dp_start_data_plane(struct net_device *netdev, + struct nss_dp_data_plane_ctx *dpc) +{ + struct nss_dp_dev *dp_dev = (struct nss_dp_dev *)netdev_priv(netdev); + + if (test_bit(__NSS_DP_UP, &dp_dev->flags)) { + netdev_dbg(netdev, "This netdev already up, something is wrong\n"); + return; + } + + if (dp_dev->dpc != dpc) { + netdev_dbg(netdev, "Cookie %px does not match, reject\n", dpc); + return; + } + + netdev->netdev_ops->ndo_open(dp_dev->netdev); +} +EXPORT_SYMBOL(nss_dp_start_data_plane); + +/* + * nss_dp_restore_data_plane() + * Called by overlay drivers to detach itself from nss-dp + */ +void nss_dp_restore_data_plane(struct net_device *netdev) +{ + struct nss_dp_dev *dp_dev = (struct nss_dp_dev *)netdev_priv(netdev); + + /* + * If this data plane is up, close the netdev to force TX/RX stop, and + * also reset the features + */ + if (test_bit(__NSS_DP_UP, &dp_dev->flags)) { + netdev->netdev_ops->ndo_stop(netdev); + nss_dp_reset_netdev_features(netdev); + } + + dp_dev->data_plane_ops = nss_dp_hal_get_data_plane_ops(); + dp_dev->dpc = &dp_global_data_plane_ctx[dp_dev->macid - NSS_DP_START_IFNUM]; + + /* + * TODO: Re-initialize EDMA dataplane + */ +} +EXPORT_SYMBOL(nss_dp_restore_data_plane); + +/* + * nss_dp_get_netdev_by_nss_if_num() + * return the net device of the corrsponding id if exist + */ +struct net_device *nss_dp_get_netdev_by_nss_if_num(int if_num) +{ + struct nss_dp_dev *dp_dev; + + if ((if_num > NSS_DP_HAL_MAX_PORTS) || (if_num < NSS_DP_START_IFNUM)) { + pr_err("Invalid if_num %d\n", if_num); + return NULL; + } + + dp_dev = dp_global_ctx.nss_dp[if_num - NSS_DP_START_IFNUM]; + if (!dp_dev) + return NULL; + return dp_dev->netdev; +} +EXPORT_SYMBOL(nss_dp_get_netdev_by_nss_if_num); diff --git a/feeds/ipq807x/qca-nss-dp/src/nss_dp_ethtools.c b/feeds/ipq807x/qca-nss-dp/src/nss_dp_ethtools.c new file mode 100644 index 000000000..289bf87ee --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/nss_dp_ethtools.c @@ -0,0 +1,378 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include +#include +#include +#include +#include "nss_dp_dev.h" +#include "fal/fal_port_ctrl.h" + +/* + * nss_dp_get_ethtool_stats() + */ +static void nss_dp_get_ethtool_stats(struct net_device *netdev, + struct ethtool_stats *stats, uint64_t *data) +{ + struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(netdev); + + dp_priv->gmac_hal_ops->getethtoolstats(dp_priv->gmac_hal_ctx, data); +} + +/* + * nss_dp_get_strset_count() + */ +static int32_t nss_dp_get_strset_count(struct net_device *netdev, int32_t sset) +{ + struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(netdev); + + return dp_priv->gmac_hal_ops->getssetcount(dp_priv->gmac_hal_ctx, sset); +} + +/* + * nss_dp_get_strings() + */ +static void nss_dp_get_strings(struct net_device *netdev, uint32_t stringset, + uint8_t *data) +{ + struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(netdev); + + dp_priv->gmac_hal_ops->getstrings(dp_priv->gmac_hal_ctx, stringset, + data); +} + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) +/* + * nss_dp_get_settings() + */ +static int32_t nss_dp_get_settings(struct net_device *netdev, + struct ethtool_cmd *cmd) +{ + struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(netdev); + + /* + * If there is a PHY attached, get the status from Kernel helper + */ + if (dp_priv->phydev) + return phy_ethtool_gset(dp_priv->phydev, cmd); + + return -EIO; +} + +/* + * nss_dp_set_settings() + */ +static int32_t nss_dp_set_settings(struct net_device *netdev, + struct ethtool_cmd *cmd) +{ + struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(netdev); + + if (!dp_priv->phydev) + return -EIO; + + return phy_ethtool_sset(dp_priv->phydev, cmd); +} +#endif + +/* + * nss_dp_get_pauseparam() + */ +static void nss_dp_get_pauseparam(struct net_device *netdev, + struct ethtool_pauseparam *pause) +{ + struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(netdev); + + pause->rx_pause = dp_priv->pause & FLOW_CTRL_RX ? 1 : 0; + pause->tx_pause = dp_priv->pause & FLOW_CTRL_TX ? 1 : 0; + pause->autoneg = AUTONEG_ENABLE; +} + +/* + * nss_dp_set_pauseparam() + */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) +static int32_t nss_dp_set_pauseparam(struct net_device *netdev, + struct ethtool_pauseparam *pause) +{ + struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(netdev); + + /* set flow control settings */ + dp_priv->pause = 0; + if (pause->rx_pause) + dp_priv->pause |= FLOW_CTRL_RX; + + if (pause->tx_pause) + dp_priv->pause |= FLOW_CTRL_TX; + + if (!dp_priv->phydev) + return 0; + + /* Update flow control advertisment */ + dp_priv->phydev->advertising &= + ~(ADVERTISED_Pause | ADVERTISED_Asym_Pause); + + if (pause->rx_pause) + dp_priv->phydev->advertising |= + (ADVERTISED_Pause | ADVERTISED_Asym_Pause); + + if (pause->tx_pause) + dp_priv->phydev->advertising |= ADVERTISED_Asym_Pause; + + genphy_config_aneg(dp_priv->phydev); + + return 0; +} +#else +static int32_t nss_dp_set_pauseparam(struct net_device *netdev, + struct ethtool_pauseparam *pause) +{ + struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(netdev); + __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising) = { 0, }; + + /* set flow control settings */ + dp_priv->pause = 0; + if (pause->rx_pause) + dp_priv->pause |= FLOW_CTRL_RX; + + if (pause->tx_pause) + dp_priv->pause |= FLOW_CTRL_TX; + + if (!dp_priv->phydev) + return 0; + + /* Update flow control advertisment */ + linkmode_copy(advertising, dp_priv->phydev->advertising); + + linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertising); + linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertising); + + if (pause->rx_pause) { + linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertising); + linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertising); + } + + if (pause->tx_pause) + linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertising); + + linkmode_copy(dp_priv->phydev->advertising, advertising); + genphy_config_aneg(dp_priv->phydev); + + return 0; +} +#endif + +/* + * nss_dp_fal_to_ethtool_linkmode_xlate() + * Translate linkmode from FAL type to ethtool type. + */ +static inline void nss_dp_fal_to_ethtool_linkmode_xlate(uint32_t *xlate_to, uint32_t *xlate_from) +{ + uint32_t pos; + + while (*xlate_from) { + pos = ffs(*xlate_from); + switch (1 << (pos - 1)) { + case FAL_PHY_EEE_10BASE_T: + *xlate_to |= SUPPORTED_10baseT_Full; + break; + + case FAL_PHY_EEE_100BASE_T: + *xlate_to |= SUPPORTED_100baseT_Full; + break; + + case FAL_PHY_EEE_1000BASE_T: + *xlate_to |= SUPPORTED_1000baseT_Full; + break; + + case FAL_PHY_EEE_2500BASE_T: + *xlate_to |= SUPPORTED_2500baseX_Full; + break; + + case FAL_PHY_EEE_5000BASE_T: + /* + * Ethtool does not support enumeration for 5G. + */ + break; + + case FAL_PHY_EEE_10000BASE_T: + *xlate_to |= SUPPORTED_10000baseT_Full; + break; + } + + *xlate_from &= (~(1 << (pos - 1))); + } +} + +/* + * nss_dp_get_eee() + * Get EEE settings. + */ +static int32_t nss_dp_get_eee(struct net_device *netdev, struct ethtool_eee *eee) +{ + struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(netdev); + fal_port_eee_cfg_t port_eee_cfg; + uint32_t port_id; + sw_error_t ret; + + memset(&port_eee_cfg, 0, sizeof(fal_port_eee_cfg_t)); + port_id = dp_priv->macid; + ret = fal_port_interface_eee_cfg_get(NSS_DP_ACL_DEV_ID, port_id, &port_eee_cfg); + if (ret != SW_OK) { + netdev_dbg(netdev, "Could not fetch EEE settings err = %d\n", ret); + return -EIO; + } + + /* + * Translate the FAL linkmode types to ethtool linkmode types. + */ + nss_dp_fal_to_ethtool_linkmode_xlate(&eee->supported, &port_eee_cfg.capability); + nss_dp_fal_to_ethtool_linkmode_xlate(&eee->advertised, &port_eee_cfg.advertisement); + nss_dp_fal_to_ethtool_linkmode_xlate(&eee->lp_advertised, &port_eee_cfg.link_partner_advertisement); + eee->eee_enabled = port_eee_cfg.enable; + eee->eee_active = port_eee_cfg.eee_status; + eee->tx_lpi_enabled = port_eee_cfg.lpi_tx_enable; + eee->tx_lpi_timer = port_eee_cfg.lpi_sleep_timer; + + return 0; +} + +/* + * nss_dp_set_eee() + * Set EEE settings. + */ +static int32_t nss_dp_set_eee(struct net_device *netdev, struct ethtool_eee *eee) +{ + struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(netdev); + fal_port_eee_cfg_t port_eee_cfg, port_eee_cur_cfg; + uint32_t port_id, pos; + sw_error_t ret; + + memset(&port_eee_cfg, 0, sizeof(fal_port_eee_cfg_t)); + memset(&port_eee_cur_cfg, 0, sizeof(fal_port_eee_cfg_t)); + port_id = dp_priv->macid; + + /* + * Get current EEE configuration. + */ + ret = fal_port_interface_eee_cfg_get(NSS_DP_ACL_DEV_ID, port_id, &port_eee_cur_cfg); + if (ret != SW_OK) { + netdev_dbg(netdev, "Could not fetch EEE settings err = %d\n", ret); + return -EIO; + } + + port_eee_cfg.enable = eee->eee_enabled; + + /* + * Translate the ethtool speed types to FAL speed types. + */ + while (eee->advertised) { + pos = ffs(eee->advertised); + switch (1 << (pos - 1)) { + case ADVERTISED_10baseT_Full: + if (port_eee_cur_cfg.capability & FAL_PHY_EEE_10BASE_T) { + port_eee_cfg.advertisement |= FAL_PHY_EEE_10BASE_T; + break; + } + + netdev_dbg(netdev, "Advertised value 10baseT_Full is not supported\n"); + return -EIO; + + case ADVERTISED_100baseT_Full: + if (port_eee_cur_cfg.capability & FAL_PHY_EEE_100BASE_T) { + port_eee_cfg.advertisement |= FAL_PHY_EEE_100BASE_T; + break; + } + + netdev_dbg(netdev, "Advertised value 100baseT_Full is not supported\n"); + return -EIO; + + case ADVERTISED_1000baseT_Full: + if (port_eee_cur_cfg.capability & FAL_PHY_EEE_1000BASE_T) { + port_eee_cfg.advertisement |= FAL_PHY_EEE_1000BASE_T; + break; + } + + netdev_dbg(netdev, "Advertised value 1000baseT_Full is not supported\n"); + return -EIO; + + case ADVERTISED_2500baseX_Full: + if (port_eee_cur_cfg.capability & FAL_PHY_EEE_2500BASE_T) { + port_eee_cfg.advertisement |= FAL_PHY_EEE_2500BASE_T; + break; + } + + netdev_dbg(netdev, "Advertised value 2500baseX_Full is not supported\n"); + return -EIO; + + case ADVERTISED_10000baseT_Full: + if (port_eee_cur_cfg.capability & FAL_PHY_EEE_10000BASE_T) { + port_eee_cfg.advertisement |= FAL_PHY_EEE_10000BASE_T; + break; + } + + netdev_dbg(netdev, "Advertised value 10000baseT_Full is not supported\n"); + return -EIO; + + default: + netdev_dbg(netdev, "Advertised value is not supported\n"); + return -EIO; + } + + eee->advertised &= (~(1 << (pos - 1))); + } + + port_eee_cfg.lpi_tx_enable = eee->tx_lpi_enabled; + port_eee_cfg.lpi_sleep_timer = eee->tx_lpi_timer; + ret = fal_port_interface_eee_cfg_set(NSS_DP_ACL_DEV_ID, port_id, &port_eee_cfg); + if (ret != SW_OK) { + netdev_dbg(netdev, "Could not configure EEE err = %d\n", ret); + return -EIO; + } + + return 0; +} + +/* + * Ethtool operations + */ +struct ethtool_ops nss_dp_ethtool_ops = { + .get_strings = &nss_dp_get_strings, + .get_sset_count = &nss_dp_get_strset_count, + .get_ethtool_stats = &nss_dp_get_ethtool_stats, + .get_link = ðtool_op_get_link, +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) + .get_settings = &nss_dp_get_settings, + .set_settings = &nss_dp_set_settings, +#else + .get_link_ksettings = phy_ethtool_get_link_ksettings, + .set_link_ksettings = phy_ethtool_set_link_ksettings, +#endif + .get_pauseparam = &nss_dp_get_pauseparam, + .set_pauseparam = &nss_dp_set_pauseparam, + .get_eee = &nss_dp_get_eee, + .set_eee = &nss_dp_set_eee, +}; + +/* + * nss_dp_set_ethtool_ops() + * Set ethtool operations + */ +void nss_dp_set_ethtool_ops(struct net_device *netdev) +{ + netdev->ethtool_ops = &nss_dp_ethtool_ops; +} diff --git a/feeds/ipq807x/qca-nss-dp/src/nss_dp_main.c b/feeds/ipq807x/qca-nss-dp/src/nss_dp_main.c new file mode 100644 index 000000000..5580b1331 --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/nss_dp_main.c @@ -0,0 +1,830 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(NSS_DP_PPE_SUPPORT) +#include +#endif +#include + +#include "nss_dp_hal.h" + +/* + * Number of TX/RX queue supported is based on the number of host CPU + */ +#define NSS_DP_NETDEV_TX_QUEUE_NUM NSS_DP_HAL_CPU_NUM +#define NSS_DP_NETDEV_RX_QUEUE_NUM NSS_DP_HAL_CPU_NUM + +/* ipq40xx_mdio_data */ +struct ipq40xx_mdio_data { + struct mii_bus *mii_bus; + void __iomem *membase; + int phy_irq[PHY_MAX_ADDR]; +}; + +/* Global data */ +struct nss_dp_global_ctx dp_global_ctx; +struct nss_dp_data_plane_ctx dp_global_data_plane_ctx[NSS_DP_HAL_MAX_PORTS]; + +/* + * nss_dp_do_ioctl() + */ +static int32_t nss_dp_do_ioctl(struct net_device *netdev, struct ifreq *ifr, + int32_t cmd) +{ + int ret = -EINVAL; + struct nss_dp_dev *dp_priv; + + if (!netdev || !ifr) + return ret; + + dp_priv = (struct nss_dp_dev *)netdev_priv(netdev); + + if (dp_priv->phydev) + return phy_mii_ioctl(dp_priv->phydev, ifr, cmd); + + return ret; +} + +/* + * nss_dp_change_mtu() + */ +static int32_t nss_dp_change_mtu(struct net_device *netdev, int32_t newmtu) +{ + int ret = -EINVAL; + struct nss_dp_dev *dp_priv; + + if (!netdev) + return ret; + + dp_priv = (struct nss_dp_dev *)netdev_priv(netdev); + + /* Let the underlying data plane decide if the newmtu is applicable */ + if (dp_priv->data_plane_ops->change_mtu(dp_priv->dpc, newmtu)) { + netdev_dbg(netdev, "Data plane change mtu failed\n"); + return ret; + } + + netdev->mtu = newmtu; + + return 0; +} + +/* + * nss_dp_set_mac_address() + */ +static int32_t nss_dp_set_mac_address(struct net_device *netdev, void *macaddr) +{ + struct nss_dp_dev *dp_priv; + struct sockaddr *addr = (struct sockaddr *)macaddr; + int ret = 0; + + if (!netdev) + return -EINVAL; + + dp_priv = (struct nss_dp_dev *)netdev_priv(netdev); + + netdev_dbg(netdev, "AddrFamily: %d, %0x:%0x:%0x:%0x:%0x:%0x\n", + addr->sa_family, addr->sa_data[0], addr->sa_data[1], + addr->sa_data[2], addr->sa_data[3], addr->sa_data[4], + addr->sa_data[5]); + + ret = eth_prepare_mac_addr_change(netdev, macaddr); + if (ret) + return ret; + + if (dp_priv->data_plane_ops->mac_addr(dp_priv->dpc, macaddr)) { + netdev_dbg(netdev, "Data plane set MAC address failed\n"); + return -EAGAIN; + } + + eth_commit_mac_addr_change(netdev, macaddr); + + dp_priv->gmac_hal_ops->setmacaddr(dp_priv->gmac_hal_ctx, + (uint8_t *)addr->sa_data); + + return 0; +} + +/* + * nss_dp_get_stats64() + */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) +static struct rtnl_link_stats64 *nss_dp_get_stats64(struct net_device *netdev, + struct rtnl_link_stats64 *stats) +{ + struct nss_dp_dev *dp_priv; + + if (!netdev) + return stats; + + dp_priv = (struct nss_dp_dev *)netdev_priv(netdev); + + dp_priv->gmac_hal_ops->getndostats(dp_priv->gmac_hal_ctx, stats); + + return stats; +} +#else +static void nss_dp_get_stats64(struct net_device *netdev, + struct rtnl_link_stats64 *stats) +{ + struct nss_dp_dev *dp_priv; + + if (!netdev) + return; + + dp_priv = (struct nss_dp_dev *)netdev_priv(netdev); + + dp_priv->gmac_hal_ops->getndostats(dp_priv->gmac_hal_ctx, stats); +} +#endif + +/* + * nss_dp_xmit() + */ +static netdev_tx_t nss_dp_xmit(struct sk_buff *skb, struct net_device *netdev) +{ + struct nss_dp_dev *dp_priv; + + if (!skb || !netdev) + return NETDEV_TX_OK; + + dp_priv = (struct nss_dp_dev *)netdev_priv(netdev); + netdev_dbg(netdev, "Tx packet, len %d\n", skb->len); + + return dp_priv->data_plane_ops->xmit(dp_priv->dpc, skb); +} + +/* + * nss_dp_close() + */ +static int nss_dp_close(struct net_device *netdev) +{ + struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(netdev); + + if (!dp_priv) + return -EINVAL; + + netif_stop_queue(netdev); + netif_carrier_off(netdev); + + /* Notify data plane link is going down */ + if (dp_priv->data_plane_ops->link_state(dp_priv->dpc, 0)) { + netdev_dbg(netdev, "Data plane set link failed\n"); + return -EAGAIN; + } + + if (dp_priv->phydev) + phy_stop(dp_priv->phydev); + dp_priv->link_state = __NSS_DP_LINK_DOWN; + +#if defined(NSS_DP_PPE_SUPPORT) + /* Notify data plane to unassign VSI */ + if (dp_priv->data_plane_ops->vsi_unassign(dp_priv->dpc, dp_priv->vsi)) { + netdev_dbg(netdev, "Data plane vsi unassign failed\n"); + return -EAGAIN; + } +#endif + + /* + * Notify data plane to close + */ + if (dp_priv->data_plane_ops->close(dp_priv->dpc)) { + netdev_dbg(netdev, "Data plane close failed\n"); + return -EAGAIN; + } + + clear_bit(__NSS_DP_UP, &dp_priv->flags); + + return 0; +} + +/* + * nss_dp_open() + */ +static int nss_dp_open(struct net_device *netdev) +{ + struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(netdev); + + if (!dp_priv) + return -EINVAL; + + netif_carrier_off(netdev); + + /* + * Call data plane init if it has not been done yet + */ + if (!(dp_priv->drv_flags & NSS_DP_PRIV_FLAG(INIT_DONE))) { + if (dp_priv->data_plane_ops->init(dp_priv->dpc)) { + netdev_dbg(netdev, "Data plane init failed\n"); + return -ENOMEM; + } + + dp_priv->drv_flags |= NSS_DP_PRIV_FLAG(INIT_DONE); + } + + /* + * Inform the Linux Networking stack about the hardwar capability of + * checksum offloading and other features. Each data_plane is + * responsible to maintain the feature set it supports + */ + dp_priv->data_plane_ops->set_features(dp_priv->dpc); + + set_bit(__NSS_DP_UP, &dp_priv->flags); + +#if defined(NSS_DP_PPE_SUPPORT) + if (dp_priv->data_plane_ops->vsi_assign(dp_priv->dpc, dp_priv->vsi)) { + netdev_dbg(netdev, "Data plane vsi assign failed\n"); + return -EAGAIN; + } +#endif + + if (dp_priv->data_plane_ops->mac_addr(dp_priv->dpc, netdev->dev_addr)) { + netdev_dbg(netdev, "Data plane set MAC address failed\n"); + return -EAGAIN; + } + + if (dp_priv->data_plane_ops->change_mtu(dp_priv->dpc, netdev->mtu)) { + netdev_dbg(netdev, "Data plane change mtu failed\n"); + return -EAGAIN; + } + + if (dp_priv->data_plane_ops->open(dp_priv->dpc, 0, 0, 0)) { + netdev_dbg(netdev, "Data plane open failed\n"); + return -EAGAIN; + } + + netif_start_queue(netdev); + + if (!dp_priv->link_poll) { + /* Notify data plane link is up */ + if (dp_priv->data_plane_ops->link_state(dp_priv->dpc, 1)) { + netdev_dbg(netdev, "Data plane set link failed\n"); + return -EAGAIN; + } + dp_priv->link_state = __NSS_DP_LINK_UP; + netif_carrier_on(netdev); + } else { + dp_priv->link_state = __NSS_DP_LINK_DOWN; + phy_start(dp_priv->phydev); + phy_start_aneg(dp_priv->phydev); + } + + return 0; +} + +#ifdef CONFIG_RFS_ACCEL +/* + * nss_dp_rx_flow_steer() + * Steer the flow rule to NSS + */ +static int nss_dp_rx_flow_steer(struct net_device *netdev, const struct sk_buff *_skb, + uint16_t rxq, uint32_t flow) +{ + struct nss_dp_dev *dp_priv; + struct netdev_rx_queue *rxqueue; + struct rps_sock_flow_table *sock_flow_table; + struct rps_dev_flow_table *flow_table; + struct rps_dev_flow *rxflow; + struct sk_buff *skb = (struct sk_buff *)_skb; + uint16_t index; + uint32_t hash; + uint32_t rfscpu; + uint32_t rxcpu; + + if (!netdev) + return -EINVAL; + + dp_priv = (struct nss_dp_dev *)netdev_priv(netdev); + if (!dp_priv) + return -EINVAL; + + rxqueue = netdev->_rx; + + if (skb_rx_queue_recorded(skb)) { + index = skb_get_rx_queue(skb); + rxqueue += index; + } + + flow_table = rcu_dereference(rxqueue->rps_flow_table); + if (!flow_table) { + netdev_dbg(netdev, "RX queue RPS flow table not found\n"); + return -EINVAL; + } + + hash = skb_get_hash(skb); + rxflow = &flow_table->flows[hash & flow_table->mask]; + rxcpu = (uint32_t)rxflow->cpu; + + sock_flow_table = rcu_dereference(rps_sock_flow_table); + if (!sock_flow_table) { + netdev_dbg(netdev, "Global RPS flow table not found\n"); + return -EINVAL; + } + + rfscpu = sock_flow_table->ents[hash & sock_flow_table->mask]; + rfscpu &= rps_cpu_mask; + + if (rxcpu == rfscpu) + return 0; + + /* + * check rx_flow_steer is defined in data plane ops + */ + if (!dp_priv->data_plane_ops->rx_flow_steer) { + netdev_dbg(netdev, "Data plane ops not defined for flow steer\n"); + return -EINVAL; + } + + /* + * Delete the old flow rule + */ + if (dp_priv->data_plane_ops->rx_flow_steer(dp_priv->dpc, skb, rxcpu, false)) { + netdev_dbg(netdev, "Data plane delete flow rule failed\n"); + return -EAGAIN; + } + + /* + * Add the new flow rule + */ + if (dp_priv->data_plane_ops->rx_flow_steer(dp_priv->dpc, skb, rfscpu, true)) { + netdev_dbg(netdev, "Data plane add flow rule failed\n"); + return -EAGAIN; + } + + return 0; +} +#endif + +/* + * nss_dp_select_queue() + * Select tx queue + */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) +static u16 nss_dp_select_queue(struct net_device *netdev, struct sk_buff *skb, + void *accel_priv, select_queue_fallback_t fallback) +#else +static u16 nss_dp_select_queue(struct net_device *netdev, struct sk_buff *skb, + struct net_device *sb_dev) +#endif +{ + int cpu = get_cpu(); + put_cpu(); + + /* + * The number of queue is matching the number of CPUs so get_cpu will + * always match a valid queue + */ + return cpu; +} + +/* + * Netdevice operations + */ +static const struct net_device_ops nss_dp_netdev_ops = { + .ndo_open = nss_dp_open, + .ndo_stop = nss_dp_close, + .ndo_start_xmit = nss_dp_xmit, + .ndo_get_stats64 = nss_dp_get_stats64, + .ndo_set_mac_address = nss_dp_set_mac_address, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = nss_dp_change_mtu, + .ndo_do_ioctl = nss_dp_do_ioctl, + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) + .ndo_bridge_setlink = switchdev_port_bridge_setlink, + .ndo_bridge_getlink = switchdev_port_bridge_getlink, + .ndo_bridge_dellink = switchdev_port_bridge_dellink, +#endif + .ndo_select_queue = nss_dp_select_queue, + +#ifdef CONFIG_RFS_ACCEL + .ndo_rx_flow_steer = nss_dp_rx_flow_steer, +#endif +}; + +/* + * nss_dp_of_get_pdata() + */ +static int32_t nss_dp_of_get_pdata(struct device_node *np, + struct net_device *netdev, + struct gmac_hal_platform_data *hal_pdata) +{ + uint8_t *maddr; + struct nss_dp_dev *dp_priv; + struct resource memres_devtree = {0}; + + dp_priv = netdev_priv(netdev); + + if (of_property_read_u32(np, "qcom,id", &dp_priv->macid)) { + pr_err("%s: error reading id\n", np->name); + return -EFAULT; + } + + if (dp_priv->macid > NSS_DP_HAL_MAX_PORTS || !dp_priv->macid) { + pr_err("%s: invalid macid %d\n", np->name, dp_priv->macid); + return -EFAULT; + } + + if (of_property_read_u32(np, "qcom,mactype", &hal_pdata->mactype)) { + pr_err("%s: error reading mactype\n", np->name); + return -EFAULT; + } + + if (of_address_to_resource(np, 0, &memres_devtree) != 0) + return -EFAULT; + + netdev->base_addr = memres_devtree.start; + hal_pdata->reg_len = resource_size(&memres_devtree); + hal_pdata->netdev = netdev; + hal_pdata->macid = dp_priv->macid; + + dp_priv->phy_mii_type = of_get_phy_mode(np); + dp_priv->link_poll = of_property_read_bool(np, "qcom,link-poll"); + if (of_property_read_u32(np, "qcom,phy-mdio-addr", + &dp_priv->phy_mdio_addr) && dp_priv->link_poll) { + pr_err("%s: mdio addr required if link polling is enabled\n", + np->name); + return -EFAULT; + } + + of_property_read_u32(np, "qcom,forced-speed", &dp_priv->forced_speed); + of_property_read_u32(np, "qcom,forced-duplex", &dp_priv->forced_duplex); + + maddr = (uint8_t *)of_get_mac_address(np); +#if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 4, 0)) + if (IS_ERR((void *)maddr)) { + maddr = NULL; + } +#endif + + if (maddr && is_valid_ether_addr(maddr)) { + ether_addr_copy(netdev->dev_addr, maddr); + } else { + random_ether_addr(netdev->dev_addr); + pr_info("GMAC%d(%px) Invalid MAC@ - using %pM\n", dp_priv->macid, + dp_priv, netdev->dev_addr); + } + + return 0; +} + +/* + * nss_dp_mdio_attach() + */ +static struct mii_bus *nss_dp_mdio_attach(struct platform_device *pdev) +{ + struct device_node *mdio_node; + struct platform_device *mdio_plat; + struct ipq40xx_mdio_data *mdio_data; + + /* + * Find mii_bus using "mdio-bus" handle. + */ + mdio_node = of_parse_phandle(pdev->dev.of_node, "mdio-bus", 0); + if (mdio_node) { + return of_mdio_find_bus(mdio_node); + } + + mdio_node = of_find_compatible_node(NULL, NULL, "qcom,ipq40xx-mdio"); + if (!mdio_node) { + dev_err(&pdev->dev, "cannot find mdio node by phandle\n"); + return NULL; + } + + mdio_plat = of_find_device_by_node(mdio_node); + if (!mdio_plat) { + dev_err(&pdev->dev, "cannot find platform device from mdio node\n"); + of_node_put(mdio_node); + return NULL; + } + + mdio_data = dev_get_drvdata(&mdio_plat->dev); + if (!mdio_data) { + dev_err(&pdev->dev, "cannot get mii bus reference from device data\n"); + of_node_put(mdio_node); + return NULL; + } + + return mdio_data->mii_bus; +} + +#ifdef CONFIG_NET_SWITCHDEV +/* + * nss_dp_is_phy_dev() + * Check if it is dp device + */ +bool nss_dp_is_phy_dev(struct net_device *dev) +{ + return (dev->netdev_ops == &nss_dp_netdev_ops); +} +#endif + +/* + * nss_dp_adjust_link() + */ +void nss_dp_adjust_link(struct net_device *netdev) +{ + struct nss_dp_dev *dp_priv = netdev_priv(netdev); + int current_state = dp_priv->link_state; + + if (!test_bit(__NSS_DP_UP, &dp_priv->flags)) + return; + + if (dp_priv->phydev->link && (current_state == __NSS_DP_LINK_UP)) + return; + + if (!dp_priv->phydev->link && (current_state == __NSS_DP_LINK_DOWN)) + return; + + if (current_state == __NSS_DP_LINK_DOWN) { + netdev_info(netdev, "PHY Link up speed: %d\n", + dp_priv->phydev->speed); + if (dp_priv->data_plane_ops->link_state(dp_priv->dpc, 1)) { + netdev_dbg(netdev, "Data plane set link up failed\n"); + return; + } + dp_priv->link_state = __NSS_DP_LINK_UP; + netif_carrier_on(netdev); + } else { + netdev_info(netdev, "PHY Link is down\n"); + if (dp_priv->data_plane_ops->link_state(dp_priv->dpc, 0)) { + netdev_dbg(netdev, "Data plane set link down failed\n"); + return; + } + dp_priv->link_state = __NSS_DP_LINK_DOWN; + netif_carrier_off(netdev); + } +} + +/* + * nss_dp_probe() + */ +static int32_t nss_dp_probe(struct platform_device *pdev) +{ + struct net_device *netdev; + struct nss_dp_dev *dp_priv; + struct device_node *np = pdev->dev.of_node; + struct gmac_hal_platform_data gmac_hal_pdata; + int32_t ret = 0; + uint8_t phy_id[MII_BUS_ID_SIZE + 3]; +#if defined(NSS_DP_PPE_SUPPORT) + uint32_t vsi_id; + fal_port_t port_id; +#endif + + /* TODO: See if we need to do some SoC level common init */ + + netdev = alloc_etherdev_mqs(sizeof(struct nss_dp_dev), + NSS_DP_NETDEV_TX_QUEUE_NUM, NSS_DP_NETDEV_RX_QUEUE_NUM); + if (!netdev) { + pr_info("alloc_etherdev() failed\n"); + return -ENOMEM; + } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) + /* max_mtu is set to 1500 in ether_setup() */ + netdev->max_mtu = ETH_MAX_MTU; +#endif + + dp_priv = netdev_priv(netdev); + memset((void *)dp_priv, 0, sizeof(struct nss_dp_dev)); + + dp_priv->pdev = pdev; + dp_priv->netdev = netdev; + netdev->watchdog_timeo = 5 * HZ; + netdev->netdev_ops = &nss_dp_netdev_ops; + nss_dp_set_ethtool_ops(netdev); +#ifdef CONFIG_NET_SWITCHDEV + nss_dp_switchdev_setup(netdev); +#endif + + ret = nss_dp_of_get_pdata(np, netdev, &gmac_hal_pdata); + if (ret != 0) { + goto fail; + } + + /* Use data plane ops as per the configured SoC */ + dp_priv->data_plane_ops = nss_dp_hal_get_data_plane_ops(); + if (!dp_priv->data_plane_ops) { + netdev_dbg(netdev, "Dataplane ops not found.\n"); + goto fail; + } + + dp_priv->dpc = &dp_global_data_plane_ctx[dp_priv->macid-1]; + dp_priv->dpc->dev = netdev; + dp_priv->ctx = &dp_global_ctx; + + /* TODO:locks init */ + + /* + * HAL's init function will return the pointer to the HAL context + * (private to hal), which dp will store in its data structures. + * The subsequent hal_ops calls expect the DP to pass the HAL + * context pointer as an argument + */ + dp_priv->gmac_hal_ops = nss_dp_hal_get_gmac_ops(gmac_hal_pdata.mactype); + if (!dp_priv->gmac_hal_ops) { + netdev_dbg(netdev, "Unsupported Mac type: %d\n", gmac_hal_pdata.mactype); + goto fail; + } + + dp_priv->gmac_hal_ctx = dp_priv->gmac_hal_ops->init(&gmac_hal_pdata); + if (!(dp_priv->gmac_hal_ctx)) { + netdev_dbg(netdev, "gmac hal init failed\n"); + goto fail; + } + + if (dp_priv->link_poll) { + dp_priv->miibus = nss_dp_mdio_attach(pdev); + if (!dp_priv->miibus) { + netdev_dbg(netdev, "failed to find miibus\n"); + goto fail; + } + snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, + dp_priv->miibus->id, dp_priv->phy_mdio_addr); + + SET_NETDEV_DEV(netdev, &pdev->dev); + + dp_priv->phydev = phy_connect(netdev, phy_id, + &nss_dp_adjust_link, + dp_priv->phy_mii_type); + if (IS_ERR(dp_priv->phydev)) { + netdev_dbg(netdev, "failed to connect to phy device\n"); + goto fail; + } + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) + dp_priv->phydev->advertising |= + (ADVERTISED_Pause | ADVERTISED_Asym_Pause); + dp_priv->phydev->supported |= + (SUPPORTED_Pause | SUPPORTED_Asym_Pause); +#else + linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, dp_priv->phydev->advertising); + linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, dp_priv->phydev->advertising); + + linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, dp_priv->phydev->supported); + linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, dp_priv->phydev->supported); +#endif + } + +#if defined(NSS_DP_PPE_SUPPORT) + /* Get port's default VSI */ + port_id = dp_priv->macid; + if (ppe_port_vsi_get(0, port_id, &vsi_id)) { + netdev_dbg(netdev, "failed to get port's default VSI\n"); + goto fail; + } + + dp_priv->vsi = vsi_id; +#endif + + /* TODO: Features: CSUM, tx/rx offload... configure */ + + /* Register the network interface */ + ret = register_netdev(netdev); + if (ret) { + netdev_dbg(netdev, "Error registering netdevice %s\n", + netdev->name); + dp_priv->gmac_hal_ops->exit(dp_priv->gmac_hal_ctx); + goto fail; + } + + dp_global_ctx.nss_dp[dp_priv->macid - 1] = dp_priv; + dp_global_ctx.slowproto_acl_bm = 0; + + netdev_dbg(netdev, "Init NSS DP GMAC%d (base = 0x%lx)\n", dp_priv->macid, netdev->base_addr); + + return 0; + +fail: + free_netdev(netdev); + return -EFAULT; +} + +/* + * nss_dp_remove() + */ +static int nss_dp_remove(struct platform_device *pdev) +{ + uint32_t i; + struct nss_dp_dev *dp_priv; + struct nss_gmac_hal_ops *hal_ops; + + for (i = 0; i < NSS_DP_HAL_MAX_PORTS; i++) { + dp_priv = dp_global_ctx.nss_dp[i]; + if (!dp_priv) + continue; + + hal_ops = dp_priv->gmac_hal_ops; + if (dp_priv->phydev) + phy_disconnect(dp_priv->phydev); + unregister_netdev(dp_priv->netdev); + hal_ops->exit(dp_priv->gmac_hal_ctx); + free_netdev(dp_priv->netdev); + dp_global_ctx.nss_dp[i] = NULL; + } + + return 0; +} + +static struct of_device_id nss_dp_dt_ids[] = { + { .compatible = "qcom,nss-dp" }, + {}, +}; +MODULE_DEVICE_TABLE(of, nss_dp_dt_ids); + +static struct platform_driver nss_dp_drv = { + .probe = nss_dp_probe, + .remove = nss_dp_remove, + .driver = { + .name = "nss-dp", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(nss_dp_dt_ids), + }, +}; + +/* + * nss_dp_init() + */ +int __init nss_dp_init(void) +{ + int ret; + + /* + * Bail out on not supported platform + * TODO: Handle this properly with SoC ops + */ + if (!of_machine_is_compatible("qcom,ipq807x") && + !of_machine_is_compatible("qcom,ipq8074") && + !of_machine_is_compatible("qcom,ipq6018") && + !of_machine_is_compatible("qcom,ipq5018")) + return 0; + + /* + * TODO Move this to soc_ops + */ + dp_global_ctx.common_init_done = false; + if (!nss_dp_hal_init()) { + pr_err("DP hal init failed.\n"); + return -EFAULT; + } + + ret = platform_driver_register(&nss_dp_drv); + if (ret) + pr_info("NSS DP platform drv register failed\n"); + + dp_global_ctx.common_init_done = true; + pr_info("**********************************************************\n"); + pr_info("* NSS Data Plane driver\n"); + pr_info("**********************************************************\n"); + + return ret; +} + +/* + * nss_dp_exit() + */ +void __exit nss_dp_exit(void) +{ + + /* + * TODO Move this to soc_ops + */ + if (dp_global_ctx.common_init_done) { + nss_dp_hal_cleanup(); + dp_global_ctx.common_init_done = false; + } + + platform_driver_unregister(&nss_dp_drv); +} + +module_init(nss_dp_init); +module_exit(nss_dp_exit); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_DESCRIPTION("NSS Data Plane Network Driver"); diff --git a/feeds/ipq807x/qca-nss-dp/src/nss_dp_switchdev.c b/feeds/ipq807x/qca-nss-dp/src/nss_dp_switchdev.c new file mode 100644 index 000000000..8c63a4988 --- /dev/null +++ b/feeds/ipq807x/qca-nss-dp/src/nss_dp_switchdev.c @@ -0,0 +1,337 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include +#include +#include +#include + +#include "nss_dp_dev.h" +#include "fal/fal_stp.h" +#include "fal/fal_ctrlpkt.h" + +#define NSS_DP_SWITCH_ID 0 +#define NSS_DP_SW_ETHTYPE_PID 0 /* PPE ethtype profile ID for slow protocols */ +#define ETH_P_NONE 0 + +/* + * nss_dp_set_slow_proto_filter() + * Enable/Disable filter to allow Ethernet slow-protocol + */ +static void nss_dp_set_slow_proto_filter(struct nss_dp_dev *dp_priv, bool filter_enable) +{ + sw_error_t ret = 0; + fal_ctrlpkt_profile_t profile; + fal_ctrlpkt_action_t action; + + memset(&profile, 0, sizeof(profile)); + + /* + * Action is redirect cpu + */ + action.action = FAL_MAC_RDT_TO_CPU; + action.sg_bypass = A_FALSE; + + /* + * Bypass stp + */ + action.in_stp_bypass = A_TRUE; + action.in_vlan_fltr_bypass = A_FALSE; + action.l2_filter_bypass = A_FALSE; + profile.action = action; + profile.ethtype_profile_bitmap = 0x1; + + /* + * Set port map + */ + profile.port_map = (1 << dp_priv->macid); + if (filter_enable) { + ret = fal_mgmtctrl_ctrlpkt_profile_add(NSS_DP_SWITCH_ID, &profile); + if (ret != SW_OK) { + netdev_dbg(dp_priv->netdev, "failed to add profile for port_map: 0x%x, ret: %d\n", profile.port_map, ret); + return; + } + + /* + * Enable filter to allow ethernet slow-protocol, + * if this is the first port being disabled by STP + */ + if (!dp_priv->ctx->slowproto_acl_bm) { + ret = fal_mgmtctrl_ethtype_profile_set(NSS_DP_SWITCH_ID, NSS_DP_SW_ETHTYPE_PID, ETH_P_SLOW); + if (ret != SW_OK) { + netdev_dbg(dp_priv->netdev, "failed to set ethertype profile: 0x%x, ret: %d\n", ETH_P_SLOW, ret); + ret = fal_mgmtctrl_ctrlpkt_profile_del(NSS_DP_SWITCH_ID, &profile); + if (ret != SW_OK) { + netdev_dbg(dp_priv->netdev, "failed to delete profile for port_map: 0x%x, ret: %d\n", profile.port_map, ret); + } + return; + } + } + + /* + * Add port to port bitmap + */ + dp_priv->ctx->slowproto_acl_bm = dp_priv->ctx->slowproto_acl_bm | (1 << dp_priv->macid); + } else { + + ret = fal_mgmtctrl_ctrlpkt_profile_del(NSS_DP_SWITCH_ID, &profile); + if (ret != SW_OK) { + netdev_dbg(dp_priv->netdev, "failed to delete profile for port_map: 0x%x, ret: %d\n", profile.port_map, ret); + return; + } + + /* + * Delete port from port bitmap + */ + dp_priv->ctx->slowproto_acl_bm = dp_priv->ctx->slowproto_acl_bm & (~(1 << dp_priv->macid)); + + /* + * If all ports are in STP-enabled state, then we do not need + * the filter to allow ethernet slow protocol packets + */ + if (!dp_priv->ctx->slowproto_acl_bm) { + ret = fal_mgmtctrl_ethtype_profile_set(NSS_DP_SWITCH_ID, NSS_DP_SW_ETHTYPE_PID, ETH_P_NONE); + if (ret != SW_OK) { + netdev_dbg(dp_priv->netdev, "failed to reset ethertype profile: 0x%x ret: %d\n", ETH_P_NONE, ret); + } + } + } +} + +/* + * nss_dp_stp_state_set() + * Set bridge port STP state to the port of NSS data plane. + */ +static int nss_dp_stp_state_set(struct nss_dp_dev *dp_priv, u8 state) +{ + sw_error_t err; + fal_stp_state_t stp_state; + + switch (state) { + case BR_STATE_DISABLED: + stp_state = FAL_STP_DISABLED; + + /* + * Dynamic bond interfaces which are bridge slaves need to receive + * ethernet slow protocol packets for LACP protocol even in STP + * disabled state + */ + nss_dp_set_slow_proto_filter(dp_priv, true); + break; + case BR_STATE_LISTENING: + stp_state = FAL_STP_LISTENING; + break; + case BR_STATE_BLOCKING: + stp_state = FAL_STP_BLOCKING; + break; + case BR_STATE_LEARNING: + stp_state = FAL_STP_LEARNING; + break; + case BR_STATE_FORWARDING: + stp_state = FAL_STP_FORWARDING; + + /* + * Remove the filter for allowing ethernet slow protocol packets + * for bond interfaces + */ + nss_dp_set_slow_proto_filter(dp_priv, false); + break; + default: + return -EOPNOTSUPP; + } + + err = fal_stp_port_state_set(NSS_DP_SWITCH_ID, 0, dp_priv->macid, + stp_state); + if (err) { + netdev_dbg(dp_priv->netdev, "failed to set ftp state\n"); + + /* + * Restore the slow proto filters + */ + if (state == BR_STATE_DISABLED) + nss_dp_set_slow_proto_filter(dp_priv, false); + else if (state == BR_STATE_FORWARDING) + nss_dp_set_slow_proto_filter(dp_priv, true); + + return -EINVAL; + } + + return 0; +} + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) +/* + * nss_dp_attr_get() + * Get port information to update switchdev attribute for NSS data plane. + */ +static int nss_dp_attr_get(struct net_device *dev, struct switchdev_attr *attr) +{ + struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(dev); + + switch (attr->id) { + case SWITCHDEV_ATTR_ID_PORT_PARENT_ID: + attr->u.ppid.id_len = 1; + attr->u.ppid.id[0] = NSS_DP_SWITCH_ID; + break; + + case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS: + attr->u.brport_flags = dp_priv->brport_flags; + break; + default: + return -EOPNOTSUPP; + } + + return 0; +} + +/* + * nss_dp_attr_set() + * Get switchdev attribute and set to the device of NSS data plane. + */ +static int nss_dp_attr_set(struct net_device *dev, + const struct switchdev_attr *attr, + struct switchdev_trans *trans) +{ + struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(dev); + + if (switchdev_trans_ph_prepare(trans)) + return 0; + + switch (attr->id) { + case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS: + dp_priv->brport_flags = attr->u.brport_flags; + netdev_dbg(dev, "set brport_flags %lu\n", attr->u.brport_flags); + return 0; + case SWITCHDEV_ATTR_ID_PORT_STP_STATE: + return nss_dp_stp_state_set(dp_priv, attr->u.stp_state); + default: + return -EOPNOTSUPP; + } +} + +/* + * nss_dp_switchdev_ops + * Switchdev operations of NSS data plane. + */ +static const struct switchdev_ops nss_dp_switchdev_ops = { + .switchdev_port_attr_get = nss_dp_attr_get, + .switchdev_port_attr_set = nss_dp_attr_set, +}; + +/* + * nss_dp_switchdev_setup() + * Set up NSS data plane switchdev operations. + */ +void nss_dp_switchdev_setup(struct net_device *dev) +{ + dev->switchdev_ops = &nss_dp_switchdev_ops; + switchdev_port_fwd_mark_set(dev, NULL, false); +} +#else + +/* + * nss_dp_port_attr_set() + * Sets attributes + */ +static int nss_dp_port_attr_set(struct net_device *dev, + const struct switchdev_attr *attr, + struct switchdev_trans *trans) +{ + struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(dev); + + if (switchdev_trans_ph_prepare(trans)) + return 0; + + switch (attr->id) { + case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS: + dp_priv->brport_flags = attr->u.brport_flags; + netdev_dbg(dev, "set brport_flags %lu\n", attr->u.brport_flags); + return 0; + case SWITCHDEV_ATTR_ID_PORT_STP_STATE: + return nss_dp_stp_state_set(dp_priv, attr->u.stp_state); + default: + return -EOPNOTSUPP; + } + +} + +/* + * nss_dp_switchdev_port_attr_set_event() + * Attribute set event + */ +static int nss_dp_switchdev_port_attr_set_event(struct net_device *netdev, + struct switchdev_notifier_port_attr_info *port_attr_info) +{ + int err; + + err = nss_dp_port_attr_set(netdev, port_attr_info->attr, + port_attr_info->trans); + + port_attr_info->handled = true; + return notifier_from_errno(err); +} + +/* + * nss_dp_switchdev_event() + * Switch dev event on netdevice + */ +static int nss_dp_switchdev_event(struct notifier_block *unused, + unsigned long event, void *ptr) +{ + struct net_device *dev = switchdev_notifier_info_to_dev(ptr); + + /* + * Handle switchdev event only for physical devices + */ + if (!nss_dp_is_phy_dev(dev)) { + return NOTIFY_DONE; + } + + if (event == SWITCHDEV_PORT_ATTR_SET) + nss_dp_switchdev_port_attr_set_event(dev, ptr); + + return NOTIFY_DONE; +} + +static struct notifier_block nss_dp_switchdev_notifier = { + .notifier_call = nss_dp_switchdev_event, +}; + +static bool switch_init_done; + +/* + * nss_dp_switchdev_setup() + * Setup switch dev + */ +void nss_dp_switchdev_setup(struct net_device *dev) +{ + int err; + + if (switch_init_done) { + return; + } + + err = register_switchdev_blocking_notifier(&nss_dp_switchdev_notifier); + if (err) { + netdev_dbg(dev, "%px:Failed to register switchdev notifier\n", dev); + } + + switch_init_done = true; + +} +#endif diff --git a/feeds/ipq807x/qca-nss-drv/Makefile b/feeds/ipq807x/qca-nss-drv/Makefile new file mode 100644 index 000000000..7854aa08b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/Makefile @@ -0,0 +1,111 @@ +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=qca-nss-drv +PKG_BRANCH:=master +PKG_RELEASE:=2 + +NSS_CLIENTS_DIR:=$(TOPDIR)/qca/src/qca-nss-clients + +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/qca-nss-drv + SECTION:=kernel + CATEGORY:=Kernel modules + SUBMENU:=Network Devices + DEPENDS:=@TARGET_ipq807x +kmod-qca-nss-dp + TITLE:=Kernel driver for NSS (core driver) + FILES:=$(PKG_BUILD_DIR)/qca-nss-drv.ko + AUTOLOAD:=$(call AutoLoad,32,qca-nss-drv) +endef + +define KernelPackage/qca-nss-drv/install + $(INSTALL_DIR) $(1)/lib/debug + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_DIR) $(1)/etc/sysctl.d + $(INSTALL_DIR) $(1)/etc/config + + $(INSTALL_BIN) ./files/qca-nss-drv.debug $(1)/lib/debug/qca-nss-drv + $(INSTALL_BIN) ./files/qca-nss-drv.init $(1)/etc/init.d/qca-nss-drv + $(INSTALL_BIN) ./files/qca-nss-drv.sysctl $(1)/etc/sysctl.d/qca-nss-drv.conf + $(INSTALL_BIN) ./files/qca-nss-drv.conf $(1)/etc/config/nss + +endef + +define KernelPackage/qca-nss-drv/Description +This package contains a NSS driver for QCA chipset +endef + +define Build/InstallDev + mkdir -p $(1)/usr/include/qca-nss-drv + $(CP) $(PKG_BUILD_DIR)/exports/* $(1)/usr/include/qca-nss-drv/ +ifneq (, $(findstring $(subtarget), "ipq807x" "ipq807x_64" "ipq60xx" "ipq60xx_64" "ipq50xx" "ipq50xx_64")) + $(RM) $(1)/usr/include/qca-nss-drv/nss_ipsecmgr.h + $(INSTALL_DIR) $(1)/usr/include/qca-nss-clients +# $(CP) $(NSS_CLIENTS_DIR)/exports/nss_ipsecmgr.h $(1)/usr/include/qca-nss-clients/. +endif +endef + +EXTRA_CFLAGS+= -I$(STAGING_DIR)/usr/include/qca-nss-gmac -I$(STAGING_DIR)/usr/include/qca-nss-dp + +# Keeping default as ipq806x for branches that does not have subtarget framework +subtarget:=$(SUBTARGET) + +ifeq ($(CONFIG_KERNEL_IPQ_MEM_PROFILE),256) +EXTRA_CFLAGS+= -DNSS_MEM_PROFILE_LOW +endif + +ifeq ($(CONFIG_KERNEL_IPQ_MEM_PROFILE),512) +EXTRA_CFLAGS+= -DNSS_MEM_PROFILE_MEDIUM +endif + +ifeq ($(CONFIG_KERNEL_SKB_FIXED_SIZE_2K),y) +EXTRA_CFLAGS+= -DNSS_SKB_FIXED_SIZE_2K +endif + +DRV_MAKE_OPTS:= +ifeq ($(CONFIG_KERNEL_IPQ_MEM_PROFILE),256) +DRV_MAKE_OPTS+=NSS_DRV_C2C_ENABLE=n \ + NSS_DRV_CAPWAP_ENABLE=n \ + NSS_DRV_CLMAP_ENABLE=n \ + NSS_DRV_CRYPTO_ENABLE=n \ + NSS_DRV_DTLS_ENABLE=n \ + NSS_DRV_GRE_ENABLE=n \ + NSS_DRV_GRE_REDIR_ENABLE=n \ + NSS_DRV_GRE_TUNNEL_ENABLE=n \ + NSS_DRV_IGS_ENABLE=n \ + NSS_DRV_IPSEC_ENABLE=n \ + NSS_DRV_LAG_ENABLE=n \ + NSS_DRV_L2TP_ENABLE=n \ + NSS_DRV_MAPT_ENABLE=n \ + NSS_DRV_OAM_ENABLE=n \ + NSS_DRV_PPTP_ENABLE=n \ + NSS_DRV_PORTID_ENABLE=n \ + NSS_DRV_PVXLAN_ENABLE=n \ + NSS_DRV_QRFS_ENABLE=n \ + NSS_DRV_QVPN_ENABLE=n \ + NSS_DRV_RMNET_ENABLE=n \ + NSS_DRV_SHAPER_ENABLE=n \ + NSS_DRV_SJACK_ENABLE=n \ + NSS_DRV_TLS_ENABLE=n \ + NSS_DRV_TRUSTSEC_ENABLE=n \ + NSS_DRV_TSTAMP_ENABLE=n \ + NSS_DRV_TUN6RD_ENABLE=n \ + NSS_DRV_TUNIPIP6_ENABLE=n \ + NSS_DRV_VXLAN_ENABLE=n +endif + +define Build/Configure + $(LN) arch/nss_$(subtarget).h $(PKG_BUILD_DIR)/exports/nss_arch.h +endef + +define Build/Compile + $(MAKE) -C "$(LINUX_DIR)" $(strip $(DRV_MAKE_OPTS)) \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + ARCH="$(LINUX_KARCH)" \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" SoC="$(subtarget)" \ + modules +endef + +$(eval $(call KernelPackage,qca-nss-drv)) diff --git a/feeds/ipq807x/qca-nss-drv/files/qca-nss-drv.conf b/feeds/ipq807x/qca-nss-drv/files/qca-nss-drv.conf new file mode 100644 index 000000000..a8a1fbf40 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/files/qca-nss-drv.conf @@ -0,0 +1,6 @@ +config nss_firmware 'qca_nss_0' + +config nss_firmware 'qca_nss_1' + +config general + option enable_rps '1' diff --git a/feeds/ipq807x/qca-nss-drv/files/qca-nss-drv.debug b/feeds/ipq807x/qca-nss-drv/files/qca-nss-drv.debug new file mode 100644 index 000000000..5d435c3a7 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/files/qca-nss-drv.debug @@ -0,0 +1,26 @@ +#!/bin/sh /sbin/sysdebug +# +# Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +log cat /sys/kernel/debug/qca-nss-drv/stats/pppoe +log cat /sys/kernel/debug/qca-nss-drv/stats/n2h +log cat /sys/kernel/debug/qca-nss-drv/stats/ipv6 +log cat /sys/kernel/debug/qca-nss-drv/stats/ipv4 +log cat /sys/kernel/debug/qca-nss-drv/stats/gmac +log cat /sys/kernel/debug/qca-nss-drv/stats/drv +log cat /sys/kernel/debug/qca-nss-drv/stats/wifi +log cat /sys/kernel/debug/qca-nss-drv/stats/wifi_if +log cat /sys/kernel/debug/qca-nss-drv/stats/eth_rx diff --git a/feeds/ipq807x/qca-nss-drv/files/qca-nss-drv.hotplug b/feeds/ipq807x/qca-nss-drv/files/qca-nss-drv.hotplug new file mode 100644 index 000000000..1e4813838 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/files/qca-nss-drv.hotplug @@ -0,0 +1,70 @@ +#!/bin/sh +# +# Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +KERNEL=`uname -r` +case "${KERNEL}" in + 3.4*) + select_or_load=load_nss_fw + ;; + *) + select_or_load=select_nss_fw + ;; +esac + +load_nss_fw () { + ls -l $1 | awk ' { print $9,$5 } '> /dev/console + echo 1 > /sys/class/firmware/$DEVICENAME/loading + cat $1 > /sys/class/firmware/$DEVICENAME/data + echo 0 > /sys/class/firmware/$DEVICENAME/loading +} + +select_nss_fw () { + rm -f /lib/firmware/$DEVICENAME + ln -s $1 /lib/firmware/$DEVICENAME + ls -l /lib/firmware/$DEVICENAME | awk ' { print $9,$5 } '> /dev/console +} + +[ "$ACTION" != "add" ] && exit + +# dev name for UCI, since it doesn't let you use . or - +SDEVNAME=$(echo ${DEVICENAME} | sed s/[.-]/_/g) + +SELECTED_FW=$(uci get nss.${SDEVNAME}.firmware 2>/dev/null) +[ -e "${SELECTED_FW}" ] && { + $select_or_load ${SELECTED_FW} + exit +} + +case $DEVICENAME in + qca-nss0* | qca-nss.0*) + if [ -e /lib/firmware/qca-nss0-enterprise.bin ] ; then + $select_or_load /lib/firmware/qca-nss0-enterprise.bin + else + $select_or_load /lib/firmware/qca-nss0-retail.bin + fi + exit + ;; + qca-nss1* | qca-nss.1*) + if [ -e /lib/firmware/qca-nss1-enterprise.bin ] ; then + $select_or_load /lib/firmware/qca-nss1-enterprise.bin + else + $select_or_load /lib/firmware/qca-nss1-retail.bin + fi + exit + ;; +esac + diff --git a/feeds/ipq807x/qca-nss-drv/files/qca-nss-drv.init b/feeds/ipq807x/qca-nss-drv/files/qca-nss-drv.init new file mode 100644 index 000000000..de12cb6d1 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/files/qca-nss-drv.init @@ -0,0 +1,50 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +START=70 + +enable_rps() { + irq_nss_rps=`grep nss_queue1 /proc/interrupts | cut -d ':' -f 1 | tr -d ' '` + for entry in $irq_nss_rps + do + echo 2 > /proc/irq/$entry/smp_affinity + done + + irq_nss_rps=`grep nss_queue2 /proc/interrupts | cut -d ':' -f 1 | tr -d ' '` + for entry in $irq_nss_rps + do + echo 4 > /proc/irq/$entry/smp_affinity + done + + irq_nss_rps=`grep nss_queue3 /proc/interrupts | cut -d ':' -f 1 | tr -d ' '` + for entry in $irq_nss_rps + do + echo 8 > /proc/irq/$entry/smp_affinity + done + + # Enable NSS RPS + sysctl -w dev.nss.rps.enable=1 >/dev/null 2>/dev/null + +} + + +start() { + local rps_enabled="$(uci_get nss @general[0] enable_rps)" + if [ "$rps_enabled" -eq 1 ]; then + enable_rps + fi +} diff --git a/feeds/ipq807x/qca-nss-drv/files/qca-nss-drv.sysctl b/feeds/ipq807x/qca-nss-drv/files/qca-nss-drv.sysctl new file mode 100644 index 000000000..fc36c33eb --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/files/qca-nss-drv.sysctl @@ -0,0 +1,4 @@ +# Default Number of connection configuration +dev.nss.ipv4cfg.ipv4_conn=4096 +dev.nss.ipv6cfg.ipv6_conn=4096 + diff --git a/feeds/ipq807x/qca-nss-drv/patches/100-compile.patch b/feeds/ipq807x/qca-nss-drv/patches/100-compile.patch new file mode 100644 index 000000000..21a7e6b4e --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/patches/100-compile.patch @@ -0,0 +1,15 @@ +Index: qca-nss-drv/nss_dma_log.c +=================================================================== +--- qca-nss-drv.orig/nss_dma_log.c ++++ qca-nss-drv/nss_dma_log.c +@@ -60,8 +60,8 @@ static void nss_dma_configure_msg(struct + */ + static void nss_dma_test_perf_msg(struct nss_dma_msg *ndm) + { +- struct nss_dma_test_cfg *ndtc = &ndm->msg.test_cfg; +- struct nss_cmn_node_stats *ncns = &ndtc->node_stats; ++ //struct nss_dma_test_cfg *ndtc = &ndm->msg.test_cfg; ++ //struct nss_cmn_node_stats *ncns = &ndtc->node_stats; + + nss_trace("%px: NSS DMA test perf message: \n",ndm); + nss_trace("%px: processed (TX: %u, RX:%u, time:%u)\n", ndm, ncns->tx_packets, ncns->rx_packets, ndtc->time_delta); diff --git a/feeds/ipq807x/qca-nss-drv/src/Makefile b/feeds/ipq807x/qca-nss-drv/src/Makefile new file mode 100644 index 000000000..c70fb90d2 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/Makefile @@ -0,0 +1,472 @@ +# ################################################### +# # Makefile for the NSS driver +# ################################################### + +obj-m += qca-nss-drv.o + +# +# List the files that belong to the driver in alphabetical order. +# +qca-nss-drv-objs := \ + nss_bridge.o \ + nss_bridge_log.o \ + nss_cmn.o \ + nss_core.o \ + nss_coredump.o \ + nss_drv_stats.o \ + nss_drv_strings.o \ + nss_dynamic_interface.o \ + nss_dynamic_interface_log.o \ + nss_dynamic_interface_stats.o \ + nss_eth_rx.o \ + nss_eth_rx_stats.o \ + nss_eth_rx_strings.o \ + nss_gmac_stats.o \ + nss_if.o \ + nss_if_log.o \ + nss_init.o \ + nss_ipv4.o \ + nss_ipv4_stats.o \ + nss_ipv4_strings.o \ + nss_ipv4_log.o \ + nss_ipv4_reasm.o \ + nss_ipv4_reasm_stats.o \ + nss_ipv4_reasm_strings.o \ + nss_ipv6.o \ + nss_ipv6_stats.o \ + nss_ipv6_strings.o \ + nss_ipv6_log.o \ + nss_ipv6_reasm.o \ + nss_ipv6_reasm_stats.o \ + nss_ipv6_reasm_strings.o \ + nss_log.o \ + nss_lso_rx.o \ + nss_lso_rx_stats.o \ + nss_lso_rx_strings.o \ + nss_meminfo.o \ + nss_n2h.o \ + nss_n2h_stats.o \ + nss_n2h_strings.o \ + nss_phys_if.o \ + nss_pm.o \ + nss_profiler.o \ + nss_project.o \ + nss_pppoe.o \ + nss_pppoe_log.o \ + nss_pppoe_stats.o \ + nss_pppoe_strings.o \ + nss_rps.o \ + nss_stats.o \ + nss_strings.o \ + nss_tx_msg_sync.o \ + nss_unaligned.o \ + nss_unaligned_log.o \ + nss_unaligned_stats.o \ + nss_virt_if.o \ + nss_virt_if_stats.o \ + nss_vlan.o \ + nss_vlan_log.o \ + nss_wifi.o \ + nss_wifi_log.o \ + nss_wifi_stats.o \ + nss_wifi_vdev.o \ + nss_wifi_if.o \ + nss_wifi_if_stats.o \ + nss_wifili.o \ + nss_wifili_log.o \ + nss_wifili_stats.o \ + nss_wifili_strings.o \ + nss_wifi_mac_db.o \ + nss_wifi_ext_vdev.o \ + nss_wifi_ext_vdev_stats.o \ + nss_wifi_ext_vdev_log.o + +# Base NSS data plane/HAL support +qca-nss-drv-objs += nss_data_plane/nss_data_plane_common.o +qca-nss-drv-objs += nss_hal/nss_hal.o + +ifneq "$(NSS_DRV_L2TP_ENABLE)" "n" +ccflags-y += -DNSS_DRV_L2TP_ENABLE +qca-nss-drv-objs += \ + nss_l2tpv2.o \ + nss_l2tpv2_log.o \ + nss_l2tpv2_stats.o \ + nss_l2tpv2_strings.o +endif + +ifneq "$(NSS_DRV_LAG_ENABLE)" "n" +ccflags-y += -DNSS_DRV_LAG_ENABLE +qca-nss-drv-objs += \ + nss_lag.o \ + nss_lag_log.o +endif + +ifneq "$(NSS_DRV_PVXLAN_ENABLE)" "n" +ccflags-y += -DNSS_DRV_PVXLAN_ENABLE +qca-nss-drv-objs += \ + nss_pvxlan.o \ + nss_pvxlan_log.o \ + nss_pvxlan_stats.o +endif + +ifneq "$(NSS_DRV_TSTAMP_ENABLE)" "n" +ccflags-y += -DNSS_DRV_TSTAMP_ENABLE +qca-nss-drv-objs += \ + nss_tstamp.o \ + nss_tstamp_stats.o +endif + +ifneq "$(NSS_DRV_GRE_ENABLE)" "n" +ccflags-y += -DNSS_DRV_GRE_ENABLE +qca-nss-drv-objs += \ + nss_gre.o \ + nss_gre_log.o \ + nss_gre_stats.o +endif + +ifneq "$(NSS_DRV_GRE_REDIR_ENABLE)" "n" +ccflags-y += -DNSS_DRV_GRE_REDIR_ENABLE +qca-nss-drv-objs += \ + nss_gre_redir.o \ + nss_gre_redir_log.o \ + nss_gre_redir_lag_ds.o \ + nss_gre_redir_lag_ds_log.o \ + nss_gre_redir_lag_ds_stats.o \ + nss_gre_redir_lag_us.o \ + nss_gre_redir_lag_us_log.o \ + nss_gre_redir_lag_us_stats.o \ + nss_gre_redir_stats.o \ + nss_gre_redir_mark.o \ + nss_gre_redir_mark_log.o \ + nss_gre_redir_mark_stats.o +endif + +ifneq "$(NSS_DRV_GRE_TUNNEL_ENABLE)" "n" +ccflags-y += -DNSS_DRV_GRE_TUNNEL_ENABLE +qca-nss-drv-objs += \ + nss_gre_tunnel.o \ + nss_gre_tunnel_log.o \ + nss_gre_tunnel_stats.o +endif + +ifneq "$(NSS_DRV_CAPWAP_ENABLE)" "n" +ccflags-y += -DNSS_DRV_CAPWAP_ENABLE +qca-nss-drv-objs += \ + nss_capwap.o \ + nss_capwap_log.o \ + nss_capwap_stats.o \ + nss_capwap_strings.o +endif + +ifneq "$(NSS_DRV_MAPT_ENABLE)" "n" +ccflags-y += -DNSS_DRV_MAPT_ENABLE +qca-nss-drv-objs += \ + nss_map_t.o \ + nss_map_t_log.o \ + nss_map_t_stats.o \ + nss_map_t_strings.o +endif + +ifneq "$(NSS_DRV_PPTP_ENABLE)" "n" +ccflags-y += -DNSS_DRV_PPTP_ENABLE +qca-nss-drv-objs += \ + nss_pptp.o \ + nss_pptp_log.o \ + nss_pptp_stats.o \ + nss_pptp_strings.o +endif + +ifneq "$(NSS_DRV_SHAPER_ENABLE)" "n" +ccflags-y += -DNSS_DRV_SHAPER_ENABLE +qca-nss-drv-objs += \ + nss_shaper.o +endif + +ifneq "$(NSS_DRV_SJACK_ENABLE)" "n" +ccflags-y += -DNSS_DRV_SJACK_ENABLE +qca-nss-drv-objs += \ + nss_sjack.o \ + nss_sjack_log.o \ + nss_sjack_stats.o +endif + +ifneq "$(NSS_DRV_TUN6RD_ENABLE)" "n" +ccflags-y += -DNSS_DRV_TUN6RD_ENABLE +qca-nss-drv-objs += \ + nss_tun6rd.o \ + nss_tun6rd_log.o +endif + +ifneq "$(NSS_DRV_TRUSTSEC_ENABLE)" "n" +ccflags-y += -DNSS_DRV_TRUSTSEC_ENABLE +qca-nss-drv-objs += \ + nss_trustsec_tx.o \ + nss_trustsec_tx_log.o \ + nss_trustsec_tx_stats.o +endif + +ifneq "$(NSS_DRV_TUNIPIP6_ENABLE)" "n" +ccflags-y += -DNSS_DRV_TUNIPIP6_ENABLE +qca-nss-drv-objs += \ + nss_tunipip6.o \ + nss_tunipip6_log.o \ + nss_tunipip6_stats.o +endif + +ifneq "$(NSS_DRV_QRFS_ENABLE)" "n" +ccflags-y += -DNSS_DRV_QRFS_ENABLE +qca-nss-drv-objs += \ + nss_qrfs.o \ + nss_qrfs_log.o \ + nss_qrfs_stats.o +endif + +ifneq "$(NSS_DRV_RMNET_ENABLE)" "n" +ccflags-y += -DNSS_DRV_RMNET_ENABLE +qca-nss-drv-objs += \ + nss_rmnet_rx.o \ + nss_rmnet_rx_stats.o +endif + +ifneq "$(NSS_DRV_PORTID_ENABLE)" "n" +ccflags-y += -DNSS_DRV_PORTID_ENABLE +qca-nss-drv-objs += \ + nss_portid.o \ + nss_portid_log.o \ + nss_portid_stats.o +endif + +ifneq "$(NSS_DRV_IGS_ENABLE)" "n" +ccflags-y += -DNSS_DRV_IGS_ENABLE +qca-nss-drv-objs += \ + nss_igs.o \ + nss_igs_stats.o +endif + +ifneq "$(NSS_DRV_OAM_ENABLE)" "n" +ccflags-y += -DNSS_DRV_OAM_ENABLE +qca-nss-drv-objs += \ + nss_oam.o \ + nss_oam_log.o +endif + +ifneq "$(NSS_DRV_CLMAP_ENABLE)" "n" +ccflags-y += -DNSS_DRV_CLMAP_ENABLE +qca-nss-drv-objs += \ + nss_clmap.o \ + nss_clmap_log.o \ + nss_clmap_stats.o +endif + + +ifneq "$(NSS_DRV_VXLAN_ENABLE)" "n" +ccflags-y += -DNSS_DRV_VXLAN_ENABLE +qca-nss-drv-objs += \ + nss_vxlan.o \ + nss_vxlan_log.o \ + nss_vxlan_stats.o +endif + +ifneq "$(NSS_DRV_MATCH_ENABLE)" "n" +ccflags-y += -DNSS_DRV_MATCH_ENABLE +qca-nss-drv-objs += \ + nss_match.o \ + nss_match_log.o \ + nss_match_stats.o +endif + +ifneq "$(NSS_DRV_MIRROR_ENABLE)" "n" +ccflags-y += -DNSS_DRV_MIRROR_ENABLE +qca-nss-drv-objs += \ + nss_mirror.o \ + nss_mirror_log.o \ + nss_mirror_stats.o +endif + +ifeq ($(SoC),$(filter $(SoC),ipq806x)) +qca-nss-drv-objs += nss_data_plane/nss_data_plane_gmac.o \ + nss_hal/ipq806x/nss_hal_pvt.o + +ifneq "$(NSS_DRV_C2C_ENABLE)" "n" +ccflags-y += -DNSS_DRV_C2C_ENABLE +qca-nss-drv-objs += \ + nss_c2c_tx.o \ + nss_c2c_tx_log.o \ + nss_c2c_tx_stats.o \ + nss_c2c_tx_strings.o \ + nss_c2c_rx.o \ + nss_c2c_rx_stats.o \ + nss_c2c_rx_strings.o +endif +ifneq "$(NSS_DRV_IPSEC_ENABLE)" "n" +ccflags-y += -DNSS_DRV_IPSEC_ENABLE +qca-nss-drv-objs += \ + nss_ipsec_log.o \ + nss_ipsec.o +endif + +ifneq "$(NSS_DRV_CRYPTO_ENABLE)" "n" +ccflags-y += -DNSS_DRV_CRYPTO_ENABLE +qca-nss-drv-objs += \ + nss_crypto.o \ + nss_crypto_log.o +endif + +ifneq "$(NSS_DRV_DTLS_ENABLE)" "n" +ccflags-y += -DNSS_DRV_DTLS_ENABLE +qca-nss-drv-objs += \ + nss_dtls.o \ + nss_dtls_log.o \ + nss_dtls_stats.o +endif +ccflags-y += -I$(obj)/nss_hal/ipq806x -DNSS_HAL_IPQ806X_SUPPORT +endif + +ifeq ($(SoC),$(filter $(SoC),ipq60xx ipq60xx_64 ipq807x ipq807x_64)) +qca-nss-drv-objs += nss_data_plane/nss_data_plane.o \ + nss_edma.o \ + nss_edma_stats.o \ + nss_edma_strings.o \ + nss_ppe.o \ + nss_ppe_log.o \ + nss_ppe_stats.o \ + nss_ppe_vp.o \ + nss_ppe_vp_log.o \ + nss_ppe_vp_stats.o + +ccflags-y += -DNSS_DRV_PPE_ENABLE +ccflags-y += -DNSS_DRV_EDMA_ENABLE + +ifneq "$(NSS_DRV_IPSEC_ENABLE)" "n" +ccflags-y += -DNSS_DRV_IPSEC_ENABLE +qca-nss-drv-objs += \ + nss_ipsec_cmn_log.o \ + nss_ipsec_cmn.o +endif + +ifneq "$(NSS_DRV_CRYPTO_ENABLE)" "n" +ccflags-y += -DNSS_DRV_CRYPTO_ENABLE +ccflags-y += -DNSS_DRV_DMA_ENABLE + +qca-nss-drv-objs += \ + nss_crypto_cmn.o \ + nss_crypto_cmn_log.o \ + nss_dma.o \ + nss_dma_log.o \ + nss_dma_stats.o \ + nss_dma_strings.o +endif + +ifneq "$(NSS_DRV_DTLS_ENABLE)" "n" +ccflags-y += -DNSS_DRV_DTLS_ENABLE +qca-nss-drv-objs += \ + nss_dtls_cmn.o \ + nss_dtls_cmn_log.o +endif + +ifneq "$(NSS_DRV_QVPN_ENABLE)" "n" +ccflags-y += -DNSS_DRV_QVPN_ENABLE +qca-nss-drv-objs += \ + nss_qvpn.o \ + nss_qvpn_stats.o \ + nss_qvpn_log.o +endif +ifneq "$(NSS_DRV_TLS_ENABLE)" "n" +ccflags-y += -DNSS_DRV_TLS_ENABLE +qca-nss-drv-objs += \ + nss_tls.o \ + nss_tls_log.o +endif +endif + +ifeq ($(SoC),$(filter $(SoC),ipq807x ipq807x_64)) +qca-nss-drv-objs += nss_hal/ipq807x/nss_hal_pvt.o \ + nss_data_plane/hal/nss_ipq807x.o +ifneq "$(NSS_DRV_C2C_ENABLE)" "n" +ccflags-y += -DNSS_DRV_C2C_ENABLE +qca-nss-drv-objs += \ + nss_c2c_tx.o \ + nss_c2c_tx_log.o \ + nss_c2c_tx_stats.o \ + nss_c2c_tx_strings.o \ + nss_c2c_rx.o \ + nss_c2c_rx_stats.o \ + nss_c2c_rx_strings.o +endif +ccflags-y += -I$(obj)/nss_hal/ipq807x -DNSS_HAL_IPQ807x_SUPPORT -DNSS_MULTI_H2N_DATA_RING_SUPPORT +endif + +ifeq ($(SoC),$(filter $(SoC),ipq60xx ipq60xx_64)) +qca-nss-drv-objs += nss_hal/ipq60xx/nss_hal_pvt.o \ + nss_data_plane/hal/nss_ipq60xx.o +ccflags-y += -I$(obj)/nss_hal/ipq60xx -DNSS_HAL_IPQ60XX_SUPPORT -DNSS_MULTI_H2N_DATA_RING_SUPPORT +endif + +ifeq ($(SoC),$(filter $(SoC),ipq50xx ipq50xx_64)) +qca-nss-drv-objs += nss_data_plane/nss_data_plane.o \ + nss_hal/ipq50xx/nss_hal_pvt.o \ + nss_data_plane/hal/nss_ipq50xx.o + +ifneq "$(NSS_DRV_IPSEC_ENABLE)" "n" +ccflags-y += -DNSS_DRV_IPSEC_ENABLE +qca-nss-drv-objs += \ + nss_ipsec_cmn_log.o \ + nss_ipsec_cmn.o +endif + +ifneq "$(NSS_DRV_CRYPTO_ENABLE)" "n" +ccflags-y += -DNSS_DRV_CRYPTO_ENABLE +qca-nss-drv-objs += \ + nss_crypto_cmn.o \ + nss_crypto_cmn_log.o +endif + +ifneq "$(NSS_DRV_DTLS_ENABLE)" "n" +ccflags-y += -DNSS_DRV_DTLS_ENABLE +qca-nss-drv-objs += \ + nss_dtls_cmn.o \ + nss_dtls_cmn_log.o +endif +ccflags-y += -I$(obj)/nss_hal/ipq50xx -DNSS_HAL_IPQ50XX_SUPPORT -DNSS_MULTI_H2N_DATA_RING_SUPPORT +endif + +ccflags-y += -I$(obj)/nss_hal/include -I$(obj)/nss_data_plane/include -I$(obj)/exports -DNSS_DEBUG_LEVEL=0 -DNSS_PKT_STATS_ENABLED=1 +ccflags-y += -I$(obj)/nss_data_plane/hal/include +ccflags-y += -DNSS_PM_DEBUG_LEVEL=0 -DNSS_SKB_REUSE_SUPPORT=1 +ccflags-y += -Werror + +KERNELVERSION := $(word 1, $(subst ., ,$(KERNELVERSION))).$(word 2, $(subst ., ,$(KERNELVERSION))) + +ifneq ($(findstring 3.4, $(KERNELVERSION)),) +NSS_CCFLAGS = -DNSS_DT_SUPPORT=0 -DNSS_FW_DBG_SUPPORT=1 -DNSS_PM_SUPPORT=1 +else +NSS_CCFLAGS = -DNSS_DT_SUPPORT=1 -DNSS_FW_DBG_SUPPORT=0 -DNSS_PM_SUPPORT=0 + +ccflags-y += -I$(obj) +endif + +# Fabric scaling is supported in 3.14 and 4.4 only +ifneq ($(findstring 3.14, $(KERNELVERSION)),) +NSS_CCFLAGS += -DNSS_FABRIC_SCALING_SUPPORT=1 +else ifneq ($(findstring 4.4, $(KERNELVERSION)),) +NSS_CCFLAGS += -DNSS_FABRIC_SCALING_SUPPORT=1 +else +NSS_CCFLAGS += -DNSS_FABRIC_SCALING_SUPPORT=0 +endif + +# Disable Frequency scaling +ifeq "$(NSS_FREQ_SCALE_DISABLE)" "y" +ccflags-y += -DNSS_FREQ_SCALE_SUPPORT=0 +else +qca-nss-drv-objs += \ + nss_freq.o \ + nss_freq_log.o \ + nss_freq_stats.o +ccflags-y += -DNSS_FREQ_SCALE_SUPPORT=1 +endif + +ccflags-y += $(NSS_CCFLAGS) + +export NSS_CCFLAGS + +obj ?= . diff --git a/feeds/ipq807x/qca-nss-drv/src/Makefile.fsm b/feeds/ipq807x/qca-nss-drv/src/Makefile.fsm new file mode 100644 index 000000000..93ca00725 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/Makefile.fsm @@ -0,0 +1,123 @@ +# ################################################### +# # Makefile for the NSS driver +# ################################################### +obj-m += qca-nss-drv.o + +# +# List the files that belong to the driver in alphabetical order. +# +qca-nss-drv-objs := \ + nss_bridge.o \ + nss_bridge_log.o \ + nss_capwap.o \ + nss_capwap_log.o \ + nss_capwap_stats.o \ + nss_cmn.o \ + nss_core.o \ + nss_coredump.o \ + nss_crypto.o \ + nss_crypto_log.o \ + nss_dtls.o \ + nss_dtls_log.o \ + nss_dtls_stats.o \ + nss_dynamic_interface.o \ + nss_dynamic_interface_log.o \ + nss_edma.o \ + nss_edma_stats.o \ + nss_eth_rx.o \ + nss_eth_rx_stats.o \ + nss_gre.o \ + nss_gre_log.o \ + nss_gre_stats.o \ + nss_gre_redir.o \ + nss_gre_redir_log.o \ + nss_gre_redir_stats.o \ + nss_gre_tunnel.o \ + nss_gre_tunnel_log.o \ + nss_gre_tunnel_stats.o \ + nss_if.o \ + nss_if_log.o \ + nss_init.o \ + nss_ipsec.o \ + nss_ipsec_log.o \ + nss_ipv4.o \ + nss_ipv4_stats.o \ + nss_ipv4_log.o \ + nss_ipv4_reasm.o \ + nss_ipv4_reasm_stats.o \ + nss_ipv6.o \ + nss_ipv6_stats.o \ + nss_ipv6_log.o \ + nss_ipv6_reasm.o \ + nss_ipv6_reasm_stats.o \ + nss_l2tpv2.o \ + nss_l2tpv2_log.o \ + nss_l2tpv2_stats.o \ + nss_lag.o \ + nss_lag_log.o \ + nss_log.o \ + nss_lso_rx.o \ + nss_lso_rx_stats.o \ + nss_map_t.o \ + nss_map_t_log.o \ + nss_map_t_stats.o \ + nss_n2h.o \ + nss_n2h_stats.o \ + nss_oam.o \ + nss_oam_log.o \ + nss_phys_if.o \ + nss_pm.o \ + nss_profiler.o \ + nss_portid.o \ + nss_portid_log.o \ + nss_portid_stats.o \ + nss_ppe.o \ + nss_ppe_log.o \ + nss_ppe_stats.o \ + nss_pppoe.o \ + nss_pppoe_log.o \ + nss_pppoe_stats.o \ + nss_pptp.o \ + nss_pptp_log.o \ + nss_pptp_stats.o \ + nss_rps.o \ + nss_shaper.o \ + nss_sjack.o \ + nss_sjack_log.o \ + nss_sjack_stats.o \ + nss_stats.o \ + nss_tstamp.o \ + nss_tstamp_stats.o \ + nss_tun6rd.o \ + nss_tun6rd_log.o \ + nss_trustsec_tx.o \ + nss_trustsec_tx_log.o \ + nss_trustsec_tx_stats.o \ + nss_tunipip6.o \ + nss_tunipip6_log.o \ + nss_unaligned.o \ + nss_unaligned_log.o \ + nss_unaligned_stats.o \ + nss_virt_if.o \ + nss_virt_if_stats.o \ + nss_vlan.o \ + nss_vlan_log.o \ + nss_wifi.o \ + nss_wifi_log.o \ + nss_wifi_stats.o \ + nss_wifi_if.o \ + nss_wifi_if_stats.o \ + nss_wifi_vdev.o + +qca-nss-drv-objs += nss_hal/nss_hal.o +qca-nss-drv-objs += nss_hal/fsm9010/nss_hal_pvt.o +qca-nss-drv-objs += nss_data_plane/nss_data_plane_common.o +qca-nss-drv-objs += nss_data_plane/nss_data_plane_gmac.o + +ccflags-y += -I$(obj)/nss_hal/include +ccflags-y += -I$(obj)/nss_data_plane/include +ccflags-y += -I$(obj)/exports +ccflags-y += -I$(obj)/nss_hal/fsm9010 -DNSS_HAL_FSM9010_SUPPORT +ccflags-y += -DNSS_DEBUG_LEVEL=0 -DNSS_PKT_STATS_ENABLED=1 +ccflags-y += -DNSS_DT_SUPPORT=1 -DNSS_PM_SUPPORT=0 -DNSS_FW_DBG_SUPPORT=0 -DNSS_SKB_REUSE_SUPPORT=0 +ccflags-y += -DNSS_PPP_SUPPORT=0 -DNSS_FREQ_SCALE_SUPPORT=0 -DNSS_FABRIC_SCALING_SUPPORT=0 diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_fsm9010.h b/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_fsm9010.h new file mode 100644 index 000000000..7e472907c --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_fsm9010.h @@ -0,0 +1,43 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_fsm9010.h + * Architecture dependent parameters. + */ +#ifndef __NSS_FSM9010_H +#define __NSS_FSM9010_H + +/** + * @addtogroup nss_arch_macros_fsm9010 + * @{ + */ + +#define NSS_MAX_NUM_PRI 1 /**< Maximum number of priority queues in NSS. */ +#define NSS_HOST_CORES 4 /**< Number of host cores. */ + +#define NSS_N2H_RING_COUNT 3 /**< Number of N2H rings. */ +#define NSS_H2N_RING_COUNT 4 /**< Number of H2N rings. */ +#define NSS_RING_SIZE 128 /**< Ring size. */ + +#define NSS_IMEM_START 0xE4000000 /**< NSS IMEM start address. */ +#define NSS_IMEM_SIZE 0x10000 /**< NSS IMEM size. */ + +/** + * @} + */ + +#endif /** __NSS_FSM9010_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq40xx.h b/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq40xx.h new file mode 100644 index 000000000..d6d335132 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq40xx.h @@ -0,0 +1,43 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_ipq40xx.h + * Architecture dependent parameters. + */ +#ifndef __NSS_IPQ40XX_H +#define __NSS_IPQ40XX_H + +/** + * @addtogroup nss_arch_macros_ipq40xx + * @{ + */ + +#define NSS_MAX_NUM_PRI 1 /**< Maximum number of priority queues in NSS. */ +#define NSS_HOST_CORES 4 /**< Number of host cores. */ + +#define NSS_N2H_RING_COUNT 0 /**< Number of N2H rings. */ +#define NSS_H2N_RING_COUNT 0 /**< Number of H2N rings. */ +#define NSS_RING_SIZE 128 /**< Ring size. */ + +#define NSS_IMEM_START 0x39000000 /**< NSS IMEM start address. */ +#define NSS_IMEM_SIZE 0x10000 /**< NSS IMEM size per core. */ + +/** + * @} + */ + +#endif /** __NSS_IPQ40XX_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq50xx.h b/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq50xx.h new file mode 100644 index 000000000..e83649f81 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq50xx.h @@ -0,0 +1,40 @@ +/* + ************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_ipq50xx.h + * Architecture dependent parameters. + */ +#ifndef __NSS_IPQ50XX_H +#define __NSS_IPQ50XX_H + +/** + * @addtogroup nss_arch_macros_ipq50xx + * @{ + */ + +#define NSS_MAX_NUM_PRI 4 /**< Maximum number of priority queues in NSS. */ +#define NSS_HOST_CORES 2 /**< Number of host cores. */ + +#define NSS_N2H_RING_COUNT 3 /**< Number of N2H rings. */ +#define NSS_H2N_RING_COUNT 7 /**< Number of H2N rings. */ +#define NSS_RING_SIZE 128 /**< Ring size. */ + +/** + * @} + */ + +#endif /** __NSS_IPQ50XX_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq50xx_64.h b/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq50xx_64.h new file mode 100644 index 000000000..b756c5af7 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq50xx_64.h @@ -0,0 +1,40 @@ +/* + ************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_ipq50xx_64.h + * Architecture dependent parameters. + */ +#ifndef __NSS_IPQ50XX_64_H +#define __NSS_IPQ50XX_64_H + +/** + * @addtogroup nss_arch_macros_ipq50xx_64 + * @{ + */ + +#define NSS_MAX_NUM_PRI 4 /**< Maximum number of priority queues in NSS. */ +#define NSS_HOST_CORES 2 /**< Number of host cores. */ + +#define NSS_N2H_RING_COUNT 3 /**< Number of N2H rings. */ +#define NSS_H2N_RING_COUNT 7 /**< Number of H2N rings. */ +#define NSS_RING_SIZE 128 /**< Ring size. */ + +/** + * @} + */ + +#endif /** __NSS_IPQ50XX_64_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq60xx.h b/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq60xx.h new file mode 100644 index 000000000..bc0396a46 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq60xx.h @@ -0,0 +1,41 @@ +/* + ************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_ipq60xx.h + * Architecture dependent parameters. + */ +#ifndef __NSS_IPQ60XX_H +#define __NSS_IPQ60XX_H + +/** + * @addtogroup nss_arch_macros_ipq60xx + * @{ + */ + +#define NSS_MAX_NUM_PRI 4 /**< Maximum number of priority queues in NSS. */ +#define NSS_HOST_CORES 4 /**< Number of host cores. */ +#define NSS_PPE_SUPPORTED /**< PPE supported flag. */ + +#define NSS_N2H_RING_COUNT 5 /**< Number of N2H rings. */ +#define NSS_H2N_RING_COUNT 11 /**< Number of H2N rings. */ +#define NSS_RING_SIZE 128 /**< Ring size. */ + +/** + * @} + */ + +#endif /** __NSS_IPQ60XX_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq60xx_64.h b/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq60xx_64.h new file mode 100644 index 000000000..a0e5e9ea8 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq60xx_64.h @@ -0,0 +1,41 @@ +/* + ************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_ipq60xx_64.h + * Architecture dependent parameters. + */ +#ifndef __NSS_IPQ60XX_64_H +#define __NSS_IPQ60XX_64_H + +/** + * @addtogroup nss_arch_macros_ipq60xx_64 + * @{ + */ + +#define NSS_MAX_NUM_PRI 4 /**< Maximum number of priority queues in NSS. */ +#define NSS_HOST_CORES 4 /**< Number of host cores. */ +#define NSS_PPE_SUPPORTED /**< PPE supported flag. */ + +#define NSS_N2H_RING_COUNT 5 /**< Number of N2H rings. */ +#define NSS_H2N_RING_COUNT 11 /**< Number of H2N rings. */ +#define NSS_RING_SIZE 128 /**< Ring size. */ + +/** + * @} + */ + +#endif /** __NSS_IPQ60XX_64_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq806x.h b/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq806x.h new file mode 100644 index 000000000..216f950ef --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq806x.h @@ -0,0 +1,43 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_ipq806x.h + * Architecture dependent parameters. + */ +#ifndef __NSS_IPQ806X_H +#define __NSS_IPQ806X_H + +/** + * @addtogroup nss_arch_macros_ipq806x + * @{ + */ + +#define NSS_MAX_NUM_PRI 4 /**< Maximum number of priority queues in NSS. */ +#define NSS_HOST_CORES 2 /**< Number of host cores. */ + +#define NSS_N2H_RING_COUNT 3 /**< Number of N2H rings. */ +#define NSS_H2N_RING_COUNT 4 /**< Number of H2N rings. */ +#define NSS_RING_SIZE 128 /**< Ring size. */ + +#define NSS_IMEM_START 0x39000000 /**< NSS IMEM start address. */ +#define NSS_IMEM_SIZE 0x10000 /**< NSS IMEM size per core. */ + +/** + * @} + */ + +#endif /** __NSS_IPQ806X_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq807x.h b/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq807x.h new file mode 100644 index 000000000..c8fc26dc2 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq807x.h @@ -0,0 +1,44 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_ipq807x.h + * Architecture dependent parameters. + */ +#ifndef __NSS_IPQ807X_H +#define __NSS_IPQ807X_H + +/** + * @addtogroup nss_arch_macros_ipq807x + * @{ + */ + +#define NSS_MAX_NUM_PRI 4 /**< Maximum number of priority queues in NSS. */ +#define NSS_HOST_CORES 4 /**< Number of host cores. */ +#define NSS_PPE_SUPPORTED /**< PPE supported flag. */ + +#define NSS_N2H_RING_COUNT 5 /**< Number of N2H rings. */ +#define NSS_H2N_RING_COUNT 11 /**< Number of H2N rings. */ +#define NSS_RING_SIZE 128 /**< Ring size. */ + +#define NSS_IMEM_START 0x38000000 /**< NSS IMEM start address. */ +#define NSS_IMEM_SIZE 0x30000 /**< NSS IMEM size per core. */ + +/** + * @} + */ + +#endif /** __NSS_IPQ807X_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq807x_64.h b/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq807x_64.h new file mode 100644 index 000000000..fec7aa538 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/arch/nss_ipq807x_64.h @@ -0,0 +1,44 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_ipq807x_64.h + * Architecture dependent parameters. + */ +#ifndef __NSS_IPQ807x_64_H +#define __NSS_IPQ807x_64_H + +/** + * @addtogroup nss_arch_macros_ipq807x_64 + * @{ + */ + +#define NSS_MAX_NUM_PRI 4 /**< Maximum number of priority queues in NSS. */ +#define NSS_HOST_CORES 4 /**< Number of host cores. */ +#define NSS_PPE_SUPPORTED /**< PPE supported flag. */ + +#define NSS_N2H_RING_COUNT 5 /**< Number of N2H rings. */ +#define NSS_H2N_RING_COUNT 11 /**< Number of H2N rings. */ +#define NSS_RING_SIZE 128 /**< Ring size. */ + +#define NSS_IMEM_START 0x38000000 /**< NSS IMEM start address. */ +#define NSS_IMEM_SIZE 0x30000 /**< NSS IMEM size per core. */ + +/** + * @} + */ + +#endif /** __NSS_IPQ807x_64_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_api_if.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_api_if.h new file mode 100644 index 000000000..1fa491972 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_api_if.h @@ -0,0 +1,825 @@ +/* + ************************************************************************** + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_api_if.h + * NSS driver APIs and Declarations. + * + * This file declares all the public interfaces for NSS driver. + */ + +#ifndef __NSS_API_IF_H +#define __NSS_API_IF_H + +#ifdef __KERNEL__ /* only kernel will use. */ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS +#include +#include +#include +#include "nss_arch.h" +#include "nss_def.h" +#include "nss_cmn.h" +#include "nss_tun6rd.h" +#include "nss_l2tpv2.h" +#include "nss_pptp.h" +#include "nss_map_t.h" +#include "nss_tunipip6.h" +#include "nss_lag.h" +#include "nss_stats_public.h" +#include "nss_ipv4.h" +#include "nss_ipv6.h" +#include "nss_shaper.h" +#include "nss_if.h" +#include "nss_phy_if.h" +#include "nss_virt_if.h" +#include "nss_pppoe.h" +#include "nss_crypto.h" +#include "nss_crypto_cmn.h" +#include "nss_dma.h" + +#include "nss_profiler.h" +#include "nss_dynamic_interface.h" +#include "nss_ipsec.h" +#include "nss_ipsec_cmn.h" +#include "nss_gre.h" +#include "nss_gre_redir.h" +#include "nss_gre_redir_lag.h" +#include "nss_gre_tunnel.h" +#include "nss_sjack.h" +#include "nss_capwap.h" +#include "nss_wifi.h" +#include "nss_wifi_vdev.h" +#include "nss_n2h.h" +#include "nss_rps.h" +#include "nss_wifi_if.h" +#include "nss_portid.h" +#include "nss_oam.h" +#include "nss_dtls.h" +#include "nss_dtls_cmn.h" +#include "nss_tls.h" +#include "nss_edma.h" +#include "nss_bridge.h" +#include "nss_ppe.h" +#include "nss_trustsec_tx.h" +#include "nss_vlan.h" +#include "nss_igs.h" +#include "nss_mirror.h" +#include "nss_wifili_if.h" +#include "nss_project.h" +#include "nss_qrfs.h" +#include "nss_c2c_tx.h" +#include "nss_qvpn.h" +#include "nss_unaligned.h" +#include "nss_pvxlan.h" +#include "nss_vxlan.h" +#include "nss_pm.h" +#include "nss_freq.h" +#include "nss_tstamp.h" +#include "nss_gre_redir_mark.h" +#include "nss_clmap.h" +#include "nss_rmnet_rx.h" +#include "nss_match.h" +#include "nss_eth_rx.h" +#include "nss_c2c_rx.h" +#include "nss_ipv6_reasm.h" +#include "nss_ipv4_reasm.h" +#include "nss_lso_rx.h" +#include "nss_wifi_mac_db_if.h" +#include "nss_wifi_ext_vdev_if.h" +#endif + +#endif /*__KERNEL__ */ + +/** + * @addtogroup nss_driver_subsystem + * @{ + */ + +#define NSS_MAX_CORES 2 /**< Maximum number of core interfaces. */ + +#define NSS_MAX_DEVICE_INTERFACES (NSS_MAX_PHYSICAL_INTERFACES + NSS_MAX_VIRTUAL_INTERFACES + NSS_MAX_TUNNEL_INTERFACES + NSS_MAX_DYNAMIC_INTERFACES) + /**< Maximum number of device interfaces. */ + +#define NSS_MAX_NET_INTERFACES (NSS_MAX_DEVICE_INTERFACES + NSS_MAX_SPECIAL_INTERFACES) + /**< Maximum number of network interfaces. */ + +#define NSS_MAX_PHYSICAL_INTERFACES 8 /**< Maximum number of physical interfaces. */ +#define NSS_MAX_VIRTUAL_INTERFACES 16 /**< Maximum number of virtual interfaces. */ +#define NSS_MAX_TUNNEL_INTERFACES 4 /**< Maximum number of tunnel interfaces. */ +#define NSS_MAX_SPECIAL_INTERFACES 68 /**< Maximum number of special interfaces. */ +#define NSS_MAX_WIFI_RADIO_INTERFACES 3 /**< Maximum number of radio interfaces. */ + +/* + * Start of individual interface groups + */ +#define NSS_PHYSICAL_IF_START 0 + /**< Beginning of the physical interfaces. */ + +#define NSS_VIRTUAL_IF_START (NSS_PHYSICAL_IF_START + NSS_MAX_PHYSICAL_INTERFACES) + /**< Beginning of the virtual interfaces. */ + +#define NSS_TUNNEL_IF_START (NSS_VIRTUAL_IF_START + NSS_MAX_VIRTUAL_INTERFACES) + /**< Beginning of the tunnel interfaces. */ + +#define NSS_DYNAMIC_IF_START (NSS_TUNNEL_IF_START + NSS_MAX_TUNNEL_INTERFACES) + /**< Beginning of the dynamic interfaces. */ + +#define NSS_SPECIAL_IF_START (NSS_DYNAMIC_IF_START + NSS_MAX_DYNAMIC_INTERFACES) + /**< Beginning of the special interfaces. */ + +/* + * Tunnel interface numbers + */ +#define NSS_IPSEC_ENCAP_IF_NUMBER (NSS_TUNNEL_IF_START + 0) + /**< Tunnel interface number for IPsec encapsulation interfaces. */ +#define NSS_IPSEC_DECAP_IF_NUMBER (NSS_TUNNEL_IF_START + 1) + /**< Tunnel interface number for IPsec decapsulation interfaces. */ +#define NSS_TUN6RD_INTERFACE (NSS_TUNNEL_IF_START + 2) + /**< Tunnel interface number for TUN6RD interfaces. */ +#define NSS_TUNIPIP6_INTERFACE (NSS_TUNNEL_IF_START + 3) + /**< Tunnel interface number for TUNIPIP6 interfaces. */ + +/* + * Special interface numbers + */ +#define NSS_N2H_INTERFACE (NSS_SPECIAL_IF_START + 0) + /**< Special interface number for N2H. */ +#define NSS_ETH_RX_INTERFACE (NSS_SPECIAL_IF_START + 2) + /**< Special interface number for Ethernet Rx. */ +#define NSS_PPPOE_INTERFACE (NSS_SPECIAL_IF_START + 3) + /**< Special interface number for PPPoE. */ +#define NSS_IPV4_RX_INTERFACE (NSS_SPECIAL_IF_START + 5) + /**< Special interface number for IPv4. */ +#define NSS_IPV6_RX_INTERFACE (NSS_SPECIAL_IF_START + 7) + /**< Special interface number for IPv6. */ +#define NSS_PROFILER_INTERFACE (NSS_SPECIAL_IF_START + 8) + /**< Special interface number for profile. */ +#define NSS_CRYPTO_INTERFACE (NSS_SPECIAL_IF_START + 9) + /**< Special interface number for crypto CE5. */ +#define NSS_DTLS_INTERFACE (NSS_SPECIAL_IF_START + 10) + /**< Special interface number for DTLS. */ +#define NSS_CRYPTO_CMN_INTERFACE (NSS_SPECIAL_IF_START + 11) + /**< Special interface number for crypto common. */ +#define NSS_C2C_TX_INTERFACE (NSS_SPECIAL_IF_START + 12) + /**< Virtual interface number for core-to-core transmissions. */ +#define NSS_C2C_RX_INTERFACE (NSS_SPECIAL_IF_START + 13) + /**< Virtual interface number for core-to-core reception. */ +#define NSS_IPSEC_CMN_INTERFACE (NSS_SPECIAL_IF_START + 18) + /**< Virtual interface number for IPSec rule. */ +#define NSS_COREFREQ_INTERFACE (NSS_SPECIAL_IF_START + 19) + /**< Virtual interface number for core frequency. */ +#define NSS_DYNAMIC_INTERFACE (NSS_SPECIAL_IF_START + 20) + /**< Special interface number for dynamic interfaces. */ +#define NSS_GRE_REDIR_INTERFACE (NSS_SPECIAL_IF_START + 21) + /**< Special interface number for GRE redirect base interfaces. */ +#define NSS_LSO_RX_INTERFACE (NSS_SPECIAL_IF_START + 22) + /**< Special interface number for LSO. */ +#define NSS_SJACK_INTERFACE (NSS_SPECIAL_IF_START + 23) + /**< Special interface number for GRE REDIR base interfaces. */ +#define NSS_IPV4_REASM_INTERFACE (NSS_SPECIAL_IF_START + 24) + /**< Special interface number for IPv4 reassembly interfaces. */ +#define NSS_DEBUG_INTERFACE (NSS_SPECIAL_IF_START + 25) + /**< Special interface number for debug. */ +#define NSS_WIFI_INTERFACE0 (NSS_SPECIAL_IF_START + 26) + /**< Special interface number for Wi-Fi radio 0. */ +#define NSS_WIFI_INTERFACE1 (NSS_SPECIAL_IF_START + 27) + /**< Special interface number for Wi-Fi radio 1. */ +#define NSS_WIFI_INTERFACE2 (NSS_SPECIAL_IF_START + 28) + /**< Special interface number for Wi-Fi radio 2. */ +#define NSS_IPV6_REASM_INTERFACE (NSS_SPECIAL_IF_START + 29) + /**< Special interface number for IPv6 reassembly. */ +#define NSS_LAG0_INTERFACE_NUM (NSS_SPECIAL_IF_START + 30) + /**< Special interface number for LAG0. */ +#define NSS_LAG1_INTERFACE_NUM (NSS_SPECIAL_IF_START + 31) + /**< Special interface number for LAG1. */ +#define NSS_LAG2_INTERFACE_NUM (NSS_SPECIAL_IF_START + 32) + /**< Special interface number for LAG2. */ +#define NSS_LAG3_INTERFACE_NUM (NSS_SPECIAL_IF_START + 33) + /**< Special interface number for LAG3. */ +#define NSS_L2TPV2_INTERFACE (NSS_SPECIAL_IF_START + 34) + /**< Special interface number for L2TPv2 UDP encapsulation. */ +#define NSS_PPTP_INTERFACE (NSS_SPECIAL_IF_START + 36) + /**< Special interface number for PPTP-to-decapsulation. */ +#define NSS_PORTID_INTERFACE (NSS_SPECIAL_IF_START + 37) + /**< Special interface number for port ID. */ +#define NSS_OAM_INTERFACE (NSS_SPECIAL_IF_START + 38) + /**< Special interface number for OAM. */ +#define NSS_MAP_T_INTERFACE (NSS_SPECIAL_IF_START + 39) + /**< Special interface number for MAP-T. */ +#define NSS_PPE_INTERFACE (NSS_SPECIAL_IF_START + 40) + /**< Special interface number for PPE. */ +#define NSS_EDMA_INTERFACE (NSS_SPECIAL_IF_START + 41) + /**< Special interface number for EDMA. */ +#define NSS_GRE_TUNNEL_INTERFACE (NSS_SPECIAL_IF_START + 42) + /**< Special interface number for NSS GRE tunnel. */ +#define NSS_TRUSTSEC_TX_INTERFACE (NSS_SPECIAL_IF_START + 43) + /**< Special interface number for TrustSec Tx. */ +#define NSS_VAP_INTERFACE (NSS_SPECIAL_IF_START + 44) + /**< Special interface number for NSS Wi-Fi VAPs base interfaces. */ +#define NSS_VLAN_INTERFACE (NSS_SPECIAL_IF_START + 45) + /**< Special interface number for VLAN. */ +#define NSS_GRE_INTERFACE (NSS_SPECIAL_IF_START + 46) + /**< Special interface number for GRE. */ +#define NSS_WIFILI_INTERNAL_INTERFACE (NSS_SPECIAL_IF_START + 47) + /**< Special interface number for wifili internal instance. */ +#define NSS_PROJECT_INTERFACE (NSS_SPECIAL_IF_START + 48) + /**< Special interface number for project node. */ +#define NSS_PBUF_MGR_FREE_INTERFACE (NSS_SPECIAL_IF_START + 49) + /**< Special interface number for PBUF_MGR_FREE node. */ +#define NSS_REDIR_RX_INTERFACE (NSS_SPECIAL_IF_START + 50) + /**< Special interface number for 802.3 redirect node. */ +#define NSS_QRFS_INTERFACE (NSS_SPECIAL_IF_START + 51) + /**< Special interface number for QRFS. */ +#define NSS_GRE_REDIR_LAG_INTERFACE (NSS_SPECIAL_IF_START + 52) + /**< Special interface number for GRE redirect link aggregation interface. */ +#define NSS_UNALIGNED_INTERFACE (NSS_SPECIAL_IF_START + 53) + /**< Special interface number for unaligned handler. */ +#define NSS_TSTAMP_TX_INTERFACE (NSS_SPECIAL_IF_START + 54) + /**< Special interface number for timestamp transmit. */ +#define NSS_TSTAMP_RX_INTERFACE (NSS_SPECIAL_IF_START + 55) + /**< Special interface number for timestamp receive. */ +#define NSS_GRE_REDIR_MARK_INTERFACE (NSS_SPECIAL_IF_START + 56) + /**< Special interface number for GRE redirect mark. */ +#define NSS_VXLAN_INTERFACE (NSS_SPECIAL_IF_START + 57) + /**< Special interface number for VxLAN handler. */ +#define NSS_RMNET_RX_INTERFACE (NSS_SPECIAL_IF_START + 58) + /**< Special interface number for remote wireless wide area network receive handler. */ +#define NSS_WIFILI_EXTERNAL_INTERFACE0 (NSS_SPECIAL_IF_START + 59) + /**< Special interface number for first external radio instance. */ +#define NSS_WIFILI_EXTERNAL_INTERFACE1 (NSS_SPECIAL_IF_START + 60) + /**< Special interface number for second external radio instance. */ +#define NSS_TLS_INTERFACE (NSS_SPECIAL_IF_START + 61) + /**< Special interface number for TLS. */ +#define NSS_PPE_VP_INTERFACE (NSS_SPECIAL_IF_START + 62) + /**< Special interface number for the virtual port (62, 63, 64) interface. */ +#define NSS_WIFI_MAC_DB_INTERFACE (NSS_SPECIAL_IF_START + 65) + /**< Special interface number for the Wi-Fi MAC database. */ +#define NSS_DMA_INTERFACE (NSS_SPECIAL_IF_START + 66) + /**< Special interface number for the DMA interface. */ +#define NSS_WIFI_EXT_VDEV_INTERFACE (NSS_SPECIAL_IF_START + 67) + /**< Special interface number for WiFi extended virtual interface. */ + + +#ifdef __KERNEL__ /* only kernel will use. */ + +/** + * Wireless Multimedia Extention Access Category to TID. @hideinitializer + */ +#define NSS_WIFILI_WME_AC_TO_TID(_ac) ( \ + ((_ac) == NSS_WIFILI_WME_AC_VO) ? 6 : \ + (((_ac) == NSS_WIFILI_WME_AC_VI) ? 5 : \ + (((_ac) == NSS_WIFILI_WME_AC_BK) ? 1 : \ + 0))) + +/** + * Wireless TID to Wireless Extension Multimedia Access Category. @hideinitializer + */ +#define NSS_WIFILI_TID_TO_WME_AC(_tid) ( \ + (((_tid) == 0) || ((_tid) == 3)) ? NSS_WIFILI_WME_AC_BE : \ + ((((_tid) == 1) || ((_tid) == 2)) ? NSS_WIFILI_WME_AC_BK : \ + ((((_tid) == 4) || ((_tid) == 5)) ? NSS_WIFILI_WME_AC_VI : \ + NSS_WIFILI_WME_AC_VO))) + +/** + * Converts the format of an IPv6 address from Linux to NSS. @hideinitializer + */ +#define IN6_ADDR_TO_IPV6_ADDR(ipv6, in6) \ + { \ + ((uint32_t *)ipv6)[0] = in6.in6_u.u6_addr32[0]; \ + ((uint32_t *)ipv6)[1] = in6.in6_u.u6_addr32[1]; \ + ((uint32_t *)ipv6)[2] = in6.in6_u.u6_addr32[2]; \ + ((uint32_t *)ipv6)[3] = in6.in6_u.u6_addr32[3]; \ + } + +/** + * Converts the format of an IPv6 address from NSS to Linux. @hideinitializer + */ +#define IPV6_ADDR_TO_IN6_ADDR(in6, ipv6) \ + { \ + in6.in6_u.u6_addr32[0] = ((uint32_t *)ipv6)[0]; \ + in6.in6_u.u6_addr32[1] = ((uint32_t *)ipv6)[1]; \ + in6.in6_u.u6_addr32[2] = ((uint32_t *)ipv6)[2]; \ + in6.in6_u.u6_addr32[3] = ((uint32_t *)ipv6)[3]; \ + } + +/** + * Format of an IPv6 address (16 * 8 bits). + */ +#define IPV6_ADDR_OCTAL_FMT "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x" + +/** + * Prints an IPv6 address (16 * 8 bits). + */ +#define IPV6_ADDR_TO_OCTAL(ipv6) ((uint16_t *)ipv6)[0], ((uint16_t *)ipv6)[1], ((uint16_t *)ipv6)[2], ((uint16_t *)ipv6)[3], ((uint16_t *)ipv6)[4], ((uint16_t *)ipv6)[5], ((uint16_t *)ipv6)[6], ((uint16_t *)ipv6)[7] + +/* + * IPv4 rule sync reasons. + */ +#define NSS_IPV4_SYNC_REASON_STATS 0 /**< Rule for synchronizing statistics. */ +#define NSS_IPV4_SYNC_REASON_FLUSH 1 /**< Rule for flushing a cache entry. */ +#define NSS_IPV4_SYNC_REASON_EVICT 2 /**< Rule for evicting a cache entry. */ +#define NSS_IPV4_SYNC_REASON_DESTROY 3 + /**< Rule for destroying a cache entry (requested by the host OS). */ +#define NSS_IPV4_SYNC_REASON_PPPOE_DESTROY 4 + /**< Rule for destroying a cache entry that belongs to a PPPoE session. */ + +/** + * nss_ipv4_create + * Information for an IPv4 flow or connection create rule. + * + * All fields must be passed in host-endian order. + */ +struct nss_ipv4_create { + int32_t src_interface_num; + /**< Source interface number (virtual or physical). */ + int32_t dest_interface_num; + /**< Destination interface number (virtual or physical). */ + int32_t protocol; /**< L4 protocol (e.g., TCP or UDP). */ + uint32_t flags; /**< Flags (if any) associated with this rule. */ + uint32_t from_mtu; /**< MTU of the incoming interface. */ + uint32_t to_mtu; /**< MTU of the outgoing interface. */ + uint32_t src_ip; /**< Source IP address. */ + int32_t src_port; /**< Source L4 port (e.g., TCP or UDP port). */ + uint32_t src_ip_xlate; /**< Translated source IP address (used with SNAT). */ + int32_t src_port_xlate; /**< Translated source L4 port (used with SNAT). */ + uint32_t dest_ip; /**< Destination IP address. */ + int32_t dest_port; /**< Destination L4 port (e.g., TCP or UDP port). */ + uint32_t dest_ip_xlate; + /**< Translated destination IP address (used with DNAT). */ + int32_t dest_port_xlate; + /**< Translated destination L4 port (used with DNAT). */ + uint8_t src_mac[ETH_ALEN]; + /**< Source MAC address. */ + uint8_t dest_mac[ETH_ALEN]; + /**< Destination MAC address. */ + uint8_t src_mac_xlate[ETH_ALEN]; + /**< Translated source MAC address (post-routing). */ + uint8_t dest_mac_xlate[ETH_ALEN]; + /**< Translated destination MAC address (post-routing). */ + uint8_t flow_window_scale; /**< Window scaling factor (TCP). */ + uint32_t flow_max_window; /**< Maximum window size (TCP). */ + uint32_t flow_end; /**< TCP window end. */ + uint32_t flow_max_end; /**< TCP window maximum end. */ + uint32_t flow_pppoe_if_exist; + /**< Flow direction: PPPoE interface exist flag. */ + int32_t flow_pppoe_if_num; + /**< Flow direction: PPPoE interface number. */ + uint16_t ingress_vlan_tag; /**< Ingress VLAN tag expected for this flow. */ + uint8_t return_window_scale; + /**< Window scaling factor of the return direction (TCP). */ + uint32_t return_max_window; + /**< Maximum window size of the return direction. */ + uint32_t return_end; + /**< Flow end for the return direction. */ + uint32_t return_max_end; + /**< Flow maximum end for the return direction. */ + uint32_t return_pppoe_if_exist; + /**< Return direction: PPPoE interface existence flag. */ + int32_t return_pppoe_if_num; + /**< Return direction: PPPoE interface number. */ + uint16_t egress_vlan_tag; /**< Egress VLAN tag expected for this flow. */ + uint8_t spo_needed; /**< Indicates whether SPO is required. */ + uint32_t param_a0; /**< Custom parameter 0. */ + uint32_t param_a1; /**< Custom parameter 1. */ + uint32_t param_a2; /**< Custom parameter 2. */ + uint32_t param_a3; /**< Custom parameter 3. */ + uint32_t param_a4; /**< Custom parameter 4. */ + uint32_t qos_tag; /**< Deprecated, will be removed soon. */ + uint32_t flow_qos_tag; /**< QoS tag value for the flow direction. */ + uint32_t return_qos_tag; /**< QoS tag value for the return direction. */ + uint8_t dscp_itag; /**< DSCP marking tag. */ + uint8_t dscp_imask; /**< DSCP marking input mask. */ + uint8_t dscp_omask; /**< DSCP marking output mask. */ + uint8_t dscp_oval; /**< DSCP marking output value. */ + uint16_t vlan_itag; /**< VLAN marking tag. */ + uint16_t vlan_imask; /**< VLAN marking input mask. */ + uint16_t vlan_omask; /**< VLAN marking output mask. */ + uint16_t vlan_oval; /**< VLAN marking output value. */ + uint32_t in_vlan_tag[MAX_VLAN_DEPTH]; + /**< Ingress VLAN tag expected for this flow. */ + uint32_t out_vlan_tag[MAX_VLAN_DEPTH]; + /**< Egress VLAN tag expected for this flow. */ + uint8_t flow_dscp; /**< IP DSCP value for the flow direction. */ + uint8_t return_dscp; /**< IP DSCP value for the return direction. */ +}; + +/* + * IPv4 connection flags (to be used with nss_ipv4_create::flags). + */ +#define NSS_IPV4_CREATE_FLAG_NO_SEQ_CHECK 0x01 + /**< Rule for not checking sequence numbers. */ +#define NSS_IPV4_CREATE_FLAG_BRIDGE_FLOW 0x02 + /**< Rule that indicates pure bridge flow (no routing is involved). */ +#define NSS_IPV4_CREATE_FLAG_ROUTED 0x04 /**< Rule for a routed connection. */ + +#define NSS_IPV4_CREATE_FLAG_DSCP_MARKING 0x08 /**< Rule for DSCP marking. */ +#define NSS_IPV4_CREATE_FLAG_VLAN_MARKING 0x10 /**< Rule for VLAN marking. */ +#define NSS_IPV4_CREATE_FLAG_QOS_VALID 0x20 /**< Rule for QoS is valid. */ + +/** + * nss_ipv4_destroy + * Information for an IPv4 flow or connection destroy rule. + */ +struct nss_ipv4_destroy { + int32_t protocol; /**< L4 protocol ID. */ + uint32_t src_ip; /**< Source IP address. */ + int32_t src_port; /**< Source L4 port (e.g., TCP or UDP port). */ + uint32_t dest_ip; /**< Destination IP address. */ + int32_t dest_port; /**< Destination L4 port (e.g., TCP or UDP port). */ +}; + +/* + * IPv6 rule sync reasons. + */ +#define NSS_IPV6_SYNC_REASON_STATS 0 /**< Rule for synchronizing statistics. */ +#define NSS_IPV6_SYNC_REASON_FLUSH 1 /**< Rule for flushing a cache entry. */ +#define NSS_IPV6_SYNC_REASON_EVICT 2 /**< Rule for evicting a cache entry. */ +#define NSS_IPV6_SYNC_REASON_DESTROY 3 + /**< Rule for destroying a cache entry (requested by the host OS). */ +#define NSS_IPV6_SYNC_REASON_PPPOE_DESTROY 4 + /**< Rule for destroying a cache entry that belongs to a PPPoE session. */ + +/** + * nss_ipv6_create + * Information for an IPv6 flow or connection create rule. + * + * All fields must be passed in host-endian order. + */ +struct nss_ipv6_create { + int32_t src_interface_num; + /**< Source interface number (virtual or physical). */ + int32_t dest_interface_num; + /**< Destination interface number (virtual or physical). */ + int32_t protocol; /**< L4 protocol (e.g., TCP or UDP). */ + uint32_t flags; /**< Flags (if any) associated with this rule. */ + uint32_t from_mtu; /**< MTU of the incoming interface. */ + uint32_t to_mtu; /**< MTU of the outgoing interface. */ + uint32_t src_ip[4]; /**< Source IP address. */ + int32_t src_port; /**< Source L4 port (e.g., TCP or UDP port). */ + uint32_t dest_ip[4]; /**< Destination IP address. */ + int32_t dest_port; /**< Destination L4 port (e.g., TCP or UDP port). */ + uint8_t src_mac[ETH_ALEN]; /**< Source MAC address. */ + uint8_t dest_mac[ETH_ALEN]; /**< Destination MAC address. */ + uint8_t flow_window_scale; /**< Window scaling factor (TCP). */ + uint32_t flow_max_window; /**< Maximum window size (TCP). */ + uint32_t flow_end; /**< TCP window end. */ + uint32_t flow_max_end; /**< TCP window maximum end. */ + uint32_t flow_pppoe_if_exist; + /**< Flow direction: PPPoE interface existence flag. */ + int32_t flow_pppoe_if_num; + /**< Flow direction: PPPoE interface number. */ + uint16_t ingress_vlan_tag; + /**< Ingress VLAN tag expected for this flow. */ + uint8_t return_window_scale; + /**< Window scaling factor (TCP) for the return direction. */ + uint32_t return_max_window; + /**< Maximum window size (TCP) for the return direction. */ + uint32_t return_end; + /**< End for the return direction. */ + uint32_t return_max_end; + /**< Maximum end for the return direction. */ + uint32_t return_pppoe_if_exist; + /**< Return direction: PPPoE interface exist flag. */ + int32_t return_pppoe_if_num; + /**< Return direction: PPPoE interface number. */ + uint16_t egress_vlan_tag; /**< Egress VLAN tag expected for this flow. */ + uint32_t qos_tag; /**< Deprecated; will be removed soon. */ + uint32_t flow_qos_tag; /**< QoS tag value for flow direction. */ + uint32_t return_qos_tag; /**< QoS tag value for the return direction. */ + uint8_t dscp_itag; /**< DSCP marking tag. */ + uint8_t dscp_imask; /**< DSCP marking input mask. */ + uint8_t dscp_omask; /**< DSCP marking output mask. */ + uint8_t dscp_oval; /**< DSCP marking output value. */ + uint16_t vlan_itag; /**< VLAN marking tag. */ + uint16_t vlan_imask; /**< VLAN marking input mask. */ + uint16_t vlan_omask; /**< VLAN marking output mask. */ + uint16_t vlan_oval; /**< VLAN marking output value. */ + uint32_t in_vlan_tag[MAX_VLAN_DEPTH]; + /**< Ingress VLAN tag expected for this flow. */ + uint32_t out_vlan_tag[MAX_VLAN_DEPTH]; + /**< Egress VLAN tag expected for this flow. */ + uint8_t flow_dscp; /**< IP DSCP value for flow direction. */ + uint8_t return_dscp; /**< IP DSCP value for the return direction. */ +}; + +/* + * IPv6 connection flags (to be used with nss_ipv6_create::flags. + */ +#define NSS_IPV6_CREATE_FLAG_NO_SEQ_CHECK 0x1 + /**< Indicates that sequence numbers are not to be checked. */ +#define NSS_IPV6_CREATE_FLAG_BRIDGE_FLOW 0x02 + /**< Indicates that this is a pure bridge flow (no routing is involved). */ +#define NSS_IPV6_CREATE_FLAG_ROUTED 0x04 /**< Rule is for a routed connection. */ +#define NSS_IPV6_CREATE_FLAG_DSCP_MARKING 0x08 /**< Rule for DSCP marking. */ +#define NSS_IPV6_CREATE_FLAG_VLAN_MARKING 0x10 /**< Rule for VLAN marking. */ +#define NSS_IPV6_CREATE_FLAG_QOS_VALID 0x20 /**< Rule for Valid QoS. */ + +/** + * nss_ipv6_destroy + * Information for an IPv6 flow or connection destroy rule. + */ +struct nss_ipv6_destroy { + int32_t protocol; /**< L4 protocol (e.g., TCP or UDP). */ + uint32_t src_ip[4]; /**< Source IP address. */ + int32_t src_port; /**< Source L4 port (e.g., TCP or UDP port). */ + uint32_t dest_ip[4]; /**< Destination IP address. */ + int32_t dest_port; /**< Destination L4 port (e.g., TCP or UDP port). */ +}; + +/** + * nss_ipv4_sync + * Defines packet statistics for IPv4 and also keeps the connection entry alive. + * + * Statistics are bytes and packets seen over a connection. + * + * The addresses are NON-NAT addresses (i.e., true endpoint + * addressing). + * + * The source (src) creates the connection. + */ +struct nss_ipv4_sync { + uint32_t index; /**< Slot ID for cache statistics to host OS. */ + /*TODO: use an opaque information as host and NSS + may be using a different mechanism to store rules. */ + int32_t protocol; /**< L4 protocol (e.g., TCP or UDP). */ + uint32_t src_ip; /**< Source IP address. */ + int32_t src_port; /**< Source L4 port (e.g., TCP or UDP port). */ + uint32_t src_ip_xlate; /**< Translated source IP address (used with SNAT). */ + int32_t src_port_xlate; /**< Translated source L4 port (used with SNAT). */ + uint32_t dest_ip; /**< Destination IP address. */ + int32_t dest_port; /**< Destination L4 port (e.g., TCP or UDP port). */ + uint32_t dest_ip_xlate; + /**< Translated destination IP address (used with DNAT). */ + int32_t dest_port_xlate; + /**< Translated destination L4 port (used with DNAT). */ + uint32_t flow_max_window; /**< Maximum window size (TCP). */ + uint32_t flow_end; /**< TCP window end. */ + uint32_t flow_max_end; /**< TCP window maximum end. */ + uint32_t flow_rx_packet_count; /**< Rx packet count for the flow interface. */ + uint32_t flow_rx_byte_count; /**< Rx byte count for the flow interface. */ + uint32_t flow_tx_packet_count; /**< Tx packet count for the flow interface. */ + uint32_t flow_tx_byte_count; /**< Tx byte count for the flow interface. */ + uint32_t return_max_window; + /**< Maximum window size (TCP) for the return direction. */ + uint32_t return_end; + /**< End for the return direction. */ + uint32_t return_max_end; + /**< Maximum end for the return direction. */ + uint32_t return_rx_packet_count; + /**< Rx packet count for the return direction. */ + uint32_t return_rx_byte_count; + /**< Rx byte count for the return direction. */ + uint32_t return_tx_packet_count; + /**< Tx packet count for the return direction. */ + uint32_t return_tx_byte_count; + /**< Tx byte count for the return direction. */ + + /** + * Time in Linux jiffies to be added to the current timeout to keep the + * connection alive. + */ + unsigned long int delta_jiffies; + + uint8_t reason; /**< Reason for synchronization. */ + uint32_t param_a0; /**< Custom parameter 0. */ + uint32_t param_a1; /**< Custom parameter 1. */ + uint32_t param_a2; /**< Custom parameter 2. */ + uint32_t param_a3; /**< Custom parameter 3. */ + uint32_t param_a4; /**< Custom parameter 4. */ + + uint8_t flags; /**< Flags indicating the status of the flow. */ + uint32_t qos_tag; /**< QoS value of the flow. */ +}; + +/** + * nss_ipv4_establish + * Defines connection-established message parameters for IPv4. + */ +struct nss_ipv4_establish { + uint32_t index; /**< Slot ID for cache statistics to host OS. */ + /*TODO: use an opaque information as host and NSS + may be using a different mechanism to store rules. */ + uint8_t protocol; /**< Protocol number. */ + uint8_t reserved[3]; /**< Padding for word alignment. */ + int32_t flow_interface; /**< Flow interface number. */ + uint32_t flow_mtu; /**< MTU for the flow interface. */ + uint32_t flow_ip; /**< Flow IP address. */ + uint32_t flow_ip_xlate; /**< Translated flow IP address. */ + uint32_t flow_ident; /**< Flow identifier (e.g., port). */ + uint32_t flow_ident_xlate; /**< Translated flow identifier (e.g., port). */ + uint16_t flow_mac[3]; /**< Source MAC address for the flow direction. */ + uint32_t flow_pppoe_if_exist; /**< Flow direction: PPPoE interface existence flag. */ + int32_t flow_pppoe_if_num; /**< Flow direction: PPPoE interface number. */ + uint16_t ingress_vlan_tag; /**< Ingress VLAN tag. */ + int32_t return_interface; /**< Return interface number. */ + uint32_t return_mtu; /**< MTU for the return interface. */ + uint32_t return_ip; /**< Return IP address. */ + uint32_t return_ip_xlate; /**< Translated return IP address. */ + uint32_t return_ident; /**< Return identier (e.g., port). */ + uint32_t return_ident_xlate; /**< Translated return identifier (e.g., port). */ + uint16_t return_mac[3]; /**< Source MAC address for the return direction. */ + uint32_t return_pppoe_if_exist; /**< Return direction: PPPoE interface existence flag. */ + int32_t return_pppoe_if_num; /**< Return direction: PPPoE interface number. */ + uint16_t egress_vlan_tag; /**< Egress VLAN tag. */ + uint8_t flags; /**< Flags indicating the status of the flow. */ + uint32_t qos_tag; /**< QoS value of the flow. */ +}; + +/** + * nss_ipv4_cb_reason + * Reasons for an IPv4 callback. + */ +enum nss_ipv4_cb_reason { + NSS_IPV4_CB_REASON_ESTABLISH = 0, + NSS_IPV4_CB_REASON_SYNC, + NSS_IPV4_CB_REASON_ESTABLISH_FAIL, +}; + +/** + * nss_ipv4_cb_params + * Message parameters for an IPv4 callback. + */ +struct nss_ipv4_cb_params { + enum nss_ipv4_cb_reason reason; /**< Reason for the callback. */ + + /** + * Message parameters for an IPv4 callback. + */ + union { + struct nss_ipv4_sync sync; + /**< Parameters for synchronization. */ + struct nss_ipv4_establish establish; + /**< Parameters for establishing a connection. */ + } params; /**< Payload of parameters. */ +}; + +/** + * nss_ipv6_sync + * Update packet statistics (bytes and packets seen over a connection) and also keep the connection entry alive. + * + * The addresses are NON-NAT addresses (i.e., true endpoint addressing). + * + * The source (src) creates the connection. + */ +struct nss_ipv6_sync { + uint32_t index; /**< Slot ID for cache statistics to the host OS. */ + int32_t protocol; /**< L4 protocol (e.g., TCP or UDP). */ + uint32_t src_ip[4]; /**< Source IP address. */ + int32_t src_port; /**< Source L4 port (e.g., TCP or UDP port). */ + uint32_t dest_ip[4]; /**< Destination IP address. */ + int32_t dest_port; /**< Destination L4 port (e.g., TCP or UDP port). */ + uint32_t flow_max_window; /**< Maximum window size (TCP). */ + uint32_t flow_end; /**< TCP window end. */ + uint32_t flow_max_end; /**< TCP window maximum end. */ + uint32_t flow_rx_packet_count; /**< Rx packet count for the flow interface. */ + uint32_t flow_rx_byte_count; /**< Rx byte count for the flow interface. */ + uint32_t flow_tx_packet_count; /**< Tx packet count for the flow interface. */ + uint32_t flow_tx_byte_count; /**< Tx byte count for the flow interface. */ + uint32_t return_max_window; + /**< Maximum window size (TCP) for the return direction. */ + uint32_t return_end; + /**< End for the return direction. */ + uint32_t return_max_end; + /**< Maximum end for the return direction. */ + uint32_t return_rx_packet_count; + /**< Rx packet count for the return direction. */ + uint32_t return_rx_byte_count; + /**< Rx byte count for the return direction. */ + uint32_t return_tx_packet_count; + /**< Tx packet count for the return direction. */ + uint32_t return_tx_byte_count; + /**< Tx byte count for the return direction. */ + + /** + * Time in Linux jiffies to be added to the current timeout to keep the + * connection alive. + */ + unsigned long int delta_jiffies; + + /** + * Non-zero when the NA has ceased to accelerate the given connection. + */ + uint8_t final_sync; + + uint8_t evicted; /**< Non-zero if the connection is evicted. */ + + uint8_t flags; /**< Flags indicating the status of the flow. */ + uint32_t qos_tag; /**< QoS value of the flow. */ +}; + +/** + * nss_ipv6_establish + * Defines connection-established message parameters for IPv6. + */ +struct nss_ipv6_establish { + uint32_t index; /**< Slot ID for cache statistics to the host OS. */ + uint8_t protocol; /**< Protocol number. */ + int32_t flow_interface; /**< Flow interface number. */ + uint32_t flow_mtu; /**< MTU for the flow interface. */ + uint32_t flow_ip[4]; /**< Flow IP address. */ + uint32_t flow_ident; /**< Flow identifier (e.g., port). */ + uint16_t flow_mac[3]; /**< Source MAC address for the flow direction. */ + uint32_t flow_pppoe_if_exist; /**< Flow direction: PPPoE interface existence flag. */ + int32_t flow_pppoe_if_num; /**< Flow direction: PPPoE interface number. */ + uint16_t ingress_vlan_tag; /**< Ingress VLAN tag. */ + int32_t return_interface; /**< Return interface number. */ + uint32_t return_mtu; /**< MTU for the return interface. */ + uint32_t return_ip[4]; /**< Return IP address. */ + uint32_t return_ident; /**< Return identier (e.g., port). */ + uint16_t return_mac[3]; /**< Source MAC address for the return direction. */ + uint32_t return_pppoe_if_exist; /**< Return direction: PPPoE interface existence flag. */ + int32_t return_pppoe_if_num; /**< Return direction: PPPoE interface number. */ + uint16_t egress_vlan_tag; /**< VLAN tag to be inserted for egress direction. */ + uint8_t flags; /**< Flags indicating the status of the flow. */ + uint32_t qos_tag; /**< QoS value of the flow. */ +}; + +/** + * nss_ipv6_cb_reason + * Reasons for an IPv6 callback. + */ +enum nss_ipv6_cb_reason { + NSS_IPV6_CB_REASON_ESTABLISH = 0, + NSS_IPV6_CB_REASON_SYNC, + NSS_IPV6_CB_REASON_ESTABLISH_FAIL, +}; + +/** + * nss_ipv6_cb_params + * Message parameters for an IPv6 callback. + */ +struct nss_ipv6_cb_params { + enum nss_ipv6_cb_reason reason; /**< Reason for the callback. */ + + /** + * Message parameters for an IPv6 callback. + */ + union { + struct nss_ipv6_sync sync; + /**< Parameters for synchronization. */ + struct nss_ipv6_establish establish; + /**< Parameters for establishing a connection. */ + } params; /**< Callback parameters. */ +}; + +/* + * General utilities + */ + +/** + * General callback function for all interface messages. + * + * @datatypes + * nss_cmn_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_if_rx_msg_callback_t)(void *app_data, struct nss_cmn_msg *msg); + +/** + * Callback function for IPv4 connection synchronization messages. + * + * @datatypes + * nss_ipv4_cb_params + * + * @param[in] nicb Pointer to the parameter structure for an NSS IPv4 callback. + */ +typedef void (*nss_ipv4_callback_t)(struct nss_ipv4_cb_params *nicb); + +/** + * nss_get_state + * Gets the NSS state. + * + * @param[in] nss_ctx Pointer to the NSS context. + * + * @return + * NSS state. + */ +extern nss_state_t nss_get_state(void *nss_ctx); + +#endif /*__KERNEL__ */ + +/* + * Once Everything is arranged correctly, will be placed at top + */ + +/** + *@} + */ + +#endif /** __NSS_API_IF_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_bridge.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_bridge.h new file mode 100644 index 000000000..783696912 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_bridge.h @@ -0,0 +1,362 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2018,2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_bridge.h + * NSS Bridge interface definitions. + */ + +#ifndef __NSS_BRIDGE_H +#define __NSS_BRIDGE_H + +/** + * @addtogroup nss_bridge_subsystem + * @{ + */ + +/** + * nss_bridge_msg_types + * Message types for the NSS bridge. + */ +enum nss_bridge_msg_types { + NSS_BRIDGE_MSG_JOIN = NSS_IF_MAX_MSG_TYPES + 1, + NSS_BRIDGE_MSG_LEAVE, + NSS_BRIDGE_MSG_SET_FDB_LEARN, + NSS_BRIDGE_MSG_TYPE_MAX, +}; + +/** + * nss_bridge_error_types + * Error types for the NSS bridge. + */ +enum nss_bridge_error_types { + NSS_BRIDGE_ERROR_UNKNOWN_MSG = NSS_IF_ERROR_TYPE_MAX + 1, + NSS_BRIDGE_ERROR_TYPE_MAX, +}; + +/** + * nss_bridge_fdb_learn_mode + * FDB learning mode for the NSS bridge. + */ +enum nss_bridge_fdb_learn_mode { + NSS_BRIDGE_FDB_LEARN_ENABLE, + NSS_BRIDGE_FDB_LEARN_DISABLE, + NSS_BRIDGE_FDB_LEARN_MODE_MAX, +}; + +/** + * nss_bridge_join_msg + * Information for joining the bridge. + */ +struct nss_bridge_join_msg { + uint32_t if_num; /**< NSS interface to add to a bridge. */ +}; + +/** + * nss_bridge_leave_msg + * Information for leaving the bridge. + */ +struct nss_bridge_leave_msg { + uint32_t if_num; /**< NSS interface to remove from a bridge. */ +}; + +/** + * nss_bridge_set_fdb_learn_msg + * Information for FDB learning status on bridge interface. + */ +struct nss_bridge_set_fdb_learn_msg { + uint32_t mode; /**< FDB learning mode of bridge interface. */ +}; + +/** + * nss_bridge_msg + * Data for sending and receiving bridge interface messages. + */ +struct nss_bridge_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a bridge interface message. + */ + union { + union nss_if_msgs if_msg; + /**< NSS interface base message. */ + struct nss_bridge_join_msg br_join; + /**< Join the bridge. */ + struct nss_bridge_leave_msg br_leave; + /**< Leave the bridge. */ + struct nss_bridge_set_fdb_learn_msg fdb_learn; + /**< FDB learning status of bridge. */ + } msg; /**< Message payload. */ +}; + +/** + * nss_bridge_verify_if_num + * Verifies if the interface is type bridge. + * + * @param[in] if_num Interface number to be verified. + * + * @return + * True if if_num is of type bridge. + */ +bool nss_bridge_verify_if_num(uint32_t if_num); + +/** + * nss_bridge_tx_msg + * Sends bridge messages to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_bridge_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_bridge_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_bridge_msg *msg); + +/** + * nss_bridge_tx_msg_sync + * Sends bridge messages synchronously to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_bridge_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in,out] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_bridge_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_bridge_msg *msg); + +/** + * nss_bridge_msg_init + * Initializes a bridge message. + * + * @datatypes + * nss_bridge_msg + * + * @param[in,out] ncm Pointer to the message. + * @param[in] if_num Interface number + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +void nss_bridge_msg_init(struct nss_bridge_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data); + +/** + * nss_bridge_get_context + * Gets the bridge context used in nss_bridge_tx. + * + * @return + * Pointer to the NSS core context. + */ +struct nss_ctx_instance *nss_bridge_get_context(void); + +/** + * Callback function for receiving bridge data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_bridge_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * Callback function for receiving bridge messages. + * + * @datatypes + * nss_bridge_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_bridge_msg_callback_t)(void *app_data, struct nss_bridge_msg *msg); + +/** + * nss_bridge_register + * Registers the bridge interface with the NSS for sending and receiving + * messages. + * + * @param[in] if_num NSS interface number. + * @param[in] netdev Pointer to the associated network device. + * @param[in] bridge_data_cb Callback for the bridge data. + * @param[in] bridge_msg_cb Callback for the bridge message. + * @param[in] features Data socket buffer types supported by this interface. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * Pointer to the NSS core context. + */ +struct nss_ctx_instance *nss_bridge_register(uint32_t if_num, struct net_device *netdev, nss_bridge_callback_t bridge_data_cb, nss_bridge_msg_callback_t bridge_msg_cb, uint32_t features, void *app_data); + +/** + * nss_bridge_unregister + * Deregisters the bridge interface from the NSS. + * + * @param[in] if_num NSS interface number. + * + * @return + * None. + */ +void nss_bridge_unregister(uint32_t if_num); + +/** + * nss_bridge_notify_register + * Registers a notifier callback for bridge messages with the NSS. + * + * @datatypes + * nss_bridge_msg_callback_t + * + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * Pointer to the NSS core context. + */ +struct nss_ctx_instance *nss_bridge_notify_register(nss_bridge_msg_callback_t cb, void *app_data); + +/** + * nss_bridge_notify_unregister + * Deregisters a bridge message notifier callback from the NSS. + * + * @return + * None. + */ +void nss_bridge_notify_unregister(void); + +/** + * nss_bridge_tx_set_mtu_msg + * Sends a message to the bridge to set the MTU. + * + * @param[in] bridge_if_num Interface number of the bridge. + * @param[in] mtu MTU value to set. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_bridge_tx_set_mtu_msg(uint32_t bridge_if_num, uint32_t mtu); + +/** + * nss_bridge_tx_set_mac_addr_msg + * Sends a message to the bridge to set the MAC address. + * + * @param[in] bridge_if_num Interface number of the bridge. + * @param[in] addr Pointer to the MAC address. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_bridge_tx_set_mac_addr_msg(uint32_t bridge_if_num, uint8_t *addr); + +/** + * nss_bridge_tx_join_msg + * Sends the bridge a message to join with a slave interface. + * + * @datatypes + * net_device + * + * @param[in] bridge_if_num Interface number of the bridge. + * @param[in] netdev Pointer to the associated network device (the + * slave interface). + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_bridge_tx_join_msg(uint32_t bridge_if_num, struct net_device *netdev); + +/** + * nss_bridge_tx_leave_msg + * Sends the bridge a message that the slave interface is leaving the bridge. + * + * @datatypes + * net_device + * + * @param[in] bridge_if_num Interface number of the bridge. + * @param[in] netdev Pointer to the associated network device (the + * slave interface). + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_bridge_tx_leave_msg(uint32_t bridge_if_num, struct net_device *netdev); + +/** + * nss_bridge_tx_vsi_assign_msg + * Sends the bridge a message to assign a VSI. + * + * @param[in] if_num Interface number of the bridge. + * @param[in] vsi VSI to assign. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_bridge_tx_vsi_assign_msg(uint32_t if_num, uint32_t vsi); + +/** + * nss_bridge_tx_vsi_unassign_msg + * Sends the bridge a message to unassign a VSI. + * + * @param[in] if_num Interface number of the bridge. + * @param[in] vsi VSI to unassign. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_bridge_tx_vsi_unassign_msg(uint32_t if_num, uint32_t vsi); + +/** + * nss_bridge_tx_set_fdb_learn_msg + * Sends a message to notify NSS about FDB learning enable/disable event. + * + * @datatypes + * nss_bridge_fdb_learn_mode + * + * @param[in] bridge_if_num Interface number of the bridge. + * @param[in] fdb_learn FDB learning disable/enable. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_bridge_tx_set_fdb_learn_msg(uint32_t bridge_if_num, enum nss_bridge_fdb_learn_mode fdb_learn); + +/** + * nss_bridge_init + * Initializes the bridge. + * + * @return + * None. + */ +void nss_bridge_init(void); + +/** + * @} + */ + +#endif /* __NSS_BRIDGE_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_c2c_rx.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_c2c_rx.h new file mode 100644 index 000000000..5605abd99 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_c2c_rx.h @@ -0,0 +1,86 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_c2c_rx.h + * NSS core-to-core reception interface definitions. + */ + +#ifndef __NSS_C2C_RX_H +#define __NSS_C2C_RX_H + +/** + * @addtogroup nss_c2c_rx_subsystem + * @{ + */ + +/** + * nss_c2c_rx_stats_types + * Core-to-core reception node statistics. + */ +enum nss_c2c_rx_stats_types { + NSS_C2C_RX_STATS_PBUF_SIMPLE = NSS_STATS_NODE_MAX, + /**< Number of received simple pbufs. */ + NSS_C2C_RX_STATS_PBUF_SG, /**< Number of scatter-gather pbufs received. */ + NSS_C2C_RX_STATS_PBUF_RETURNING, /**< Number of returning scatter-gather pbufs. */ + NSS_C2C_RX_STATS_INVAL_DEST, /**< Number of pbuf enqueue failures because of destination is invalid. */ + NSS_C2C_RX_STATS_MAX, /**< Maximum message type. */ +}; + +/** + * nss_c2c_rx_stats_notification + * Core-to-core reception statistics structure. + */ +struct nss_c2c_rx_stats_notification { + uint32_t core_id; /**< Core ID. */ + uint64_t stats[NSS_C2C_RX_STATS_MAX]; /**< Core-to-core reception statistics. */ +}; + +#ifdef __KERNEL__ /* only kernel will use. */ +/** + * nss_c2c_rx_stats_register_notifier + * Registers a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_c2c_rx_stats_register_notifier(struct notifier_block *nb); + +/** + * nss_c2c_rx_stats_unregister_notifier + * Deregisters a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_c2c_rx_stats_unregister_notifier(struct notifier_block *nb); +#endif /*__KERNEL__ */ + +/** + * @} + */ + +#endif /* __NSS_C2C_RX_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_c2c_tx.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_c2c_tx.h new file mode 100644 index 000000000..a9ecc8ce0 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_c2c_tx.h @@ -0,0 +1,308 @@ +/* + ************************************************************************** + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_c2c_tx.h + * NSS core-to-core transmission interface definitions. + */ + +#ifndef __NSS_C2C_TX_H +#define __NSS_C2C_TX_H + +/** + * @addtogroup nss_c2c_tx_subsystem + * @{ + */ + +/** + * nss_c2c_tx_msg_type + * Supported message types. + */ +enum nss_c2c_tx_msg_type { + NSS_C2C_TX_MSG_TYPE_STATS, /**< Statistics synchronization. */ + NSS_C2C_TX_MSG_TYPE_TX_MAP, /**< Open engine synchronization. */ + NSS_C2C_TX_MSG_TYPE_PERFORMANCE_TEST, /**< Performance test. */ + NSS_C2C_TX_MSG_TYPE_MAX /**< Maximum message type. */ +}; + +/** + * nss_c2c_tx_msg_error + * Message error types. + */ +enum nss_c2c_tx_msg_error { + NSS_C2C_TX_MSG_ERROR_NONE, /**< No error. */ + NSS_C2C_TX_MSG_ERROR_INVAL_OP, /**< Invalid operation. */ + NSS_C2C_TX_MSG_ERROR_INVALID_TEST_ID, /**< Invalid test ID. */ + NSS_C2C_TX_MSG_ERROR_MAX /**< Maximum error type. */ +}; + +/** + * nss_c2c_tx_test_type + * Supported core-to core transmission tests. + */ +enum nss_c2c_tx_test_type { + NSS_C2C_TX_TEST_TYPE_SIMPLE = 1, + /**< Tests the performance of simple pbufs. */ + NSS_C2C_TX_TEST_TYPE_SG_CHAIN, + /**< Tests the performance of scatter-gather chain pbufs. */ + NSS_C2C_TX_TEST_TYPE_SG_REF, + /**< Tests the performance of scatter-gather pbuf that has references. */ + NSS_C2C_TX_TEST_TYPE_SG_REFED, + /**< Tests the performance of referenced pbuf. */ + NSS_C2C_TX_TEST_TYPE_MAX + /**< Maximum message type. */ +}; + +/** + * nss_c2c_tx_stats_types + * Core-to-core transmission node statistics. + */ +enum nss_c2c_tx_stats_types { + NSS_C2C_TX_STATS_PBUF_SIMPLE = NSS_STATS_NODE_MAX, + /**< Number of received simple pbuf. */ + NSS_C2C_TX_STATS_PBUF_SG, /**< Number of scatter-gather pbuf received. */ + NSS_C2C_TX_STATS_PBUF_RETURNING, /**< Number of returning scatter-gather pbuf. */ + NSS_C2C_TX_STATS_MAX, /**< Maximum message type. */ +}; + +/** + * nss_c2c_tx_stats_notification + * Core-to-core transmission statistics structure. + */ +struct nss_c2c_tx_stats_notification { + uint32_t core_id; /**< Core ID. */ + uint64_t stats[NSS_C2C_TX_STATS_MAX]; /**< Core-to-core transmission statistics. */ +}; + +#ifdef __KERNEL__ /* only kernel will use. */ +/** + * nss_c2c_tx_map + * Core-to-core transmission queue address and interrupt address. + */ +struct nss_c2c_tx_map { + uint32_t tx_map; /**< Peer core core-to-core receiver queue start address. */ + uint32_t c2c_intr_addr; /**< Peer core core-to-core interrupt register address. */ +}; + +/** + * nss_c2c_tx_stats + * The NSS core-to-core transmission node statistics structure. + */ +struct nss_c2c_tx_stats { + struct nss_cmn_node_stats node_stats; + /**< Common node statistics for core-to-core transmissions. */ + uint32_t pbuf_simple; /**< Number of received simple pbuf. */ + uint32_t pbuf_sg; /**< Number of scattered/gathered pbuf received. */ + uint32_t pbuf_returning; /**< Number of returning scattered/gathered pbuf. */ +}; + +/** + * nss_c2c_tx_test + * Start performance test for the given test ID. + */ +struct nss_c2c_tx_test { + uint32_t test_id; /**< ID of the core-to-core communication test. */ +}; + +/** + * nss_c2c_tx_msg + * Message structure to send/receive core-to-core transmission commands. + */ +struct nss_c2c_tx_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a NSS core-to-core transmission rule or statistics message. + */ + union { + struct nss_c2c_tx_map map; /**< Core-to-core transmissions memory map. */ + struct nss_c2c_tx_stats stats; /**< Core-to-core transmissions statistics. */ + struct nss_c2c_tx_test test; /**< Core-to-core performance test. */ + } msg; /**< Message payload. */ +}; + +/** + * nss_c2c_tx_register_handler + * Registers the core-to-core transmissions message handler. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS context. + * + * @return + * None. + */ +void nss_c2c_tx_register_handler(struct nss_ctx_instance *nss_ctx); + +/** + * Callback function for receiving core-to-core transmissions messages. + * + * @datatypes + * nss_c2c_tx_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_c2c_tx_msg_callback_t)(void *app_data, struct nss_c2c_tx_msg *msg); + +/** + * nss_c2c_tx_tx_msg + * Transmits a core-to-core transmissions message to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_c2c_tx_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] nctm Pointer to the message data. + * + * @return + * Status of the transmit operation. + */ +extern nss_tx_status_t nss_c2c_tx_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_c2c_tx_msg *nctm); + +/** + * nss_c2c_tx_msg_init + * Initializes core-to-core transmissions messages. + * + * @datatypes + * nss_c2c_tx_msg \n + * nss_c2c_tx_msg_callback_t + * + * @param[in] nct Pointer to the NSS interface message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_c2c_tx_msg_init(struct nss_c2c_tx_msg *nct, uint16_t if_num, uint32_t type, uint32_t len, + nss_c2c_tx_msg_callback_t cb, void *app_data); + +/** + * nss_c2c_tx_notify_register + * Registers a notifier callback for core-to-core transmission messages with the NSS. + * + * @datatypes + * nss_c2c_tx_msg_callback_t + * + * @param[in] core NSS core number index to the notifier callback table. + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * Pointer to the NSS core context. + */ +struct nss_ctx_instance *nss_c2c_tx_notify_register(int core, nss_c2c_tx_msg_callback_t cb, void *app_data); + +/** + * nss_c2c_tx_notify_unregister + * Deregisters a core-to-core transmission message notifier callback from the NSS. + * + * @param[in] core NSS core number index to the notifier callback table. + * + * @return + * None. + * + * @dependencies + * The notifier callback must have been previously registered. + */ +void nss_c2c_tx_notify_unregister(int core); + +/** + * nss_c2c_tx_msg_cfg_map + * Sends core-to-core transmissions map to NSS + * + * @datatypes + * nss_ctx_instance \n + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] tx_map Peer core core-to-core receiver queue start address. + * @param[in] c2c_addr Peer core core-to-core interrupt register address. + * + * @return + * Status of the transmit operation. + */ +extern nss_tx_status_t nss_c2c_tx_msg_cfg_map(struct nss_ctx_instance *nss_ctx, uint32_t tx_map, uint32_t c2c_addr); + +/** + * nss_c2c_tx_register_sysctl + * Registers the core-to-core transmission sysctl entries to the sysctl tree. + * + * @return + * None. + */ +extern void nss_c2c_tx_register_sysctl(void); + +/** + * nss_c2c_tx_unregister_sysctl + * Deregisters the core-to-core transmission sysctl entries from the sysctl tree. + * + * @return + * None. + * + * @dependencies + * The system control must have been previously registered. + */ +extern void nss_c2c_tx_unregister_sysctl(void); + +/** + * nss_c2c_tx_init + * Initializes the core-to-core transmission. + * + * @return + * None. + */ +void nss_c2c_tx_init(void); + +/** + * nss_c2c_tx_stats_register_notifier + * Registers a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_c2c_tx_stats_register_notifier(struct notifier_block *nb); + +/** + * nss_c2c_tx_stats_unregister_notifier + * Deregisters a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_c2c_tx_stats_unregister_notifier(struct notifier_block *nb); +#endif /*__KERNEL__ */ + +/** + * @} + */ + +#endif /* __NSS_C2C_TX_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_capwap.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_capwap.h new file mode 100644 index 000000000..375b3504f --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_capwap.h @@ -0,0 +1,648 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * @file nss_capwap.h + * NSS CAPWAP interface definitions. + */ + +#ifndef __NSS_CAPWAP_H +#define __NSS_CAPWAP_H + +/** + * @addtogroup nss_capwap_subsystem + * @{ + */ + +/** + * Size of the headroom required for CAPWAP packets. + */ +#define NSS_CAPWAP_HEADROOM 256 + +/** + * nss_capwap_stats_encap_types + * CAPWAP encapsulation statistics. + */ +enum nss_capwap_stats_encap_types { + NSS_CAPWAP_STATS_ENCAP_TX_PKTS, + NSS_CAPWAP_STATS_ENCAP_TX_BYTES, + NSS_CAPWAP_STATS_ENCAP_TX_SEGMENTS, + NSS_CAPWAP_STATS_ENCAP_TX_DROP_SG_REF, + NSS_CAPWAP_STATS_ENCAP_TX_DROP_VER_MISMATCH, + NSS_CAPWAP_STATS_ENCAP_TX_DROP_UNALIGN, + NSS_CAPWAP_STATS_ENCAP_TX_DROP_HEADER_ROOM, + NSS_CAPWAP_STATS_ENCAP_TX_DROP_DTLS, + NSS_CAPWAP_STATS_ENCAP_TX_DROP_NWIRELESS, + NSS_CAPWAP_STATS_ENCAP_TX_DROP_QUEUE_FULL, + NSS_CAPWAP_STATS_ENCAP_TX_DROP_MEM_FAIL, + NSS_CAPWAP_STATS_ENCAP_FAST_MEM, + NSS_CAPWAP_STATS_ENCAP_MAX +}; + +/** + * nss_capwap_stats_decap_types + * CAPWAP decapsulation statistics. + */ +enum nss_capwap_stats_decap_types { + NSS_CAPWAP_STATS_DECAP_RX_PKTS, + NSS_CAPWAP_STATS_DECAP_RX_BYTES, + NSS_CAPWAP_STATS_DECAP_RX_DTLS_PKTS, + NSS_CAPWAP_STATS_DECAP_RX_SEGMENTS, + NSS_CAPWAP_STATS_DECAP_RX_DROP, + NSS_CAPWAP_STATS_DECAP_RX_DROP_OVERSIZE, + NSS_CAPWAP_STATS_DECAP_RX_DROP_FRAG_TIMEOUT, + NSS_CAPWAP_STATS_DECAP_RX_DROP_DUP_FRAG, + NSS_CAPWAP_STATS_DECAP_RX_DROP_FRAG_GAP, + NSS_CAPWAP_STATS_DECAP_RX_DROP_QUEUE_FULL, + NSS_CAPWAP_STATS_DECAP_RX_DROP_N2H_QUEUE_FULL, + NSS_CAPWAP_STATS_DECAP_RX_DROP_MEM_FAIL, + NSS_CAPWAP_STATS_DECAP_RX_DROP_CHECKSUM, + NSS_CAPWAP_STATS_DECAP_RX_MALFORMED, + NSS_CAPWAP_STATS_DECAP_FAST_MEM, + NSS_CAPWAP_STATS_DECAP_MAX +}; + +/** + * nss_capwap_msg_type + * CAPWAP message types. + */ +typedef enum nss_capwap_msg_type { + NSS_CAPWAP_MSG_TYPE_NONE, + NSS_CAPWAP_MSG_TYPE_CFG_RULE, + NSS_CAPWAP_MSG_TYPE_UNCFG_RULE, + NSS_CAPWAP_MSG_TYPE_ENABLE_TUNNEL, + NSS_CAPWAP_MSG_TYPE_DISABLE_TUNNEL, + NSS_CAPWAP_MSG_TYPE_UPDATE_PATH_MTU, + NSS_CAPWAP_MSG_TYPE_SYNC_STATS, + NSS_CAPWAP_MSG_TYPE_VERSION, /**< Default is version 1. */ + NSS_CAPWAP_MSG_TYPE_DTLS, + NSS_CAPWAP_MSG_TYPE_FLOW_RULE_ADD, + NSS_CAPWAP_MSG_TYPE_FLOW_RULE_DEL, + NSS_CAPWAP_MSG_TYPE_MAX, +} nss_capwap_msg_type_t; + +/** + * nss_capwap_msg_response + * Error types for CAPWAP responses to messages from the host. + */ +typedef enum nss_capwap_msg_response { + NSS_CAPWAP_ERROR_MSG_INVALID_REASSEMBLY_TIMEOUT, + NSS_CAPWAP_ERROR_MSG_INVALID_PATH_MTU, + NSS_CAPWAP_ERROR_MSG_INVALID_MAX_FRAGMENT, + NSS_CAPWAP_ERROR_MSG_INVALID_BUFFER_SIZE, + NSS_CAPWAP_ERROR_MSG_INVALID_L3_PROTO, + NSS_CAPWAP_ERROR_MSG_INVALID_UDP_PROTO, + NSS_CAPWAP_ERROR_MSG_INVALID_VERSION, + NSS_CAPWAP_ERROR_MSG_TUNNEL_DISABLED, + NSS_CAPWAP_ERROR_MSG_TUNNEL_ENABLED, + NSS_CAPWAP_ERROR_MSG_TUNNEL_NOT_CFG, + NSS_CAPWAP_ERROR_MSG_INVALID_IP_NODE, + NSS_CAPWAP_ERROR_MSG_INVALID_TYPE_FLAG, + NSS_CAPWAP_ERROR_MSG_INVALID_DTLS_CFG, + NSS_CAPWAP_ERROR_MSG_FLOW_TABLE_FULL, + NSS_CAPWAP_ERROR_MSG_FLOW_EXIST, + NSS_CAPWAP_ERROR_MSG_FLOW_NOT_EXIST, + NSS_CAPWAP_ERROR_MSG_MAX, +} nss_capwap_msg_response_t; + +/** + * nss_capwap_stats_msg + * Per-tunnel statistics messages from the NSS firmware. + */ +struct nss_capwap_stats_msg { + struct nss_cmn_node_stats pnode_stats; /**< Common firmware statistics. */ + uint32_t dtls_pkts; /**< Number of DTLS packets flowing through. */ + + /* + * Rx/decap stats + */ + uint32_t rx_dup_frag; /**< Number of duplicate fragments. */ + uint32_t rx_segments; /**< Number of segments or fragments. */ + + /** + * Packets dropped because they are larger than the payload size. + */ + uint32_t rx_oversize_drops; + + uint32_t rx_frag_timeout_drops; + /**< Packets dropped because of a reassembly timeout. */ + uint32_t rx_queue_full_drops; + /**< Packets dropped because the queue is full. */ + uint32_t rx_n2h_queue_full_drops; + /**< Packets dropped because the NSS-to-host queue is full. */ + uint32_t rx_csum_drops; + /**< Packets dropped because of a checksum mismatch. */ + uint32_t rx_malformed; + /**< Packets dropped because of a malformed packet. */ + uint32_t rx_mem_failure_drops; + /**< Packets dropped because of a memory failure. */ + uint32_t rx_frag_gap_drops; + /**< Packets dropped because of a non-sequential fragment offset. */ + + /* + * Tx/encap stats + */ + uint32_t tx_segments; /**< Number of segments or fragments. */ + uint32_t tx_queue_full_drops; /**< Packets dropped because of a full queue. */ + uint32_t tx_mem_failure_drops; + /**< Packets dropped because of a memory failure. */ + uint32_t tx_dropped_sg_ref; + /**< Packets dropped because of a scatter-gather reference. */ + uint32_t tx_dropped_ver_mis; + /**< Packets dropped because of a version mismatch. */ + uint32_t Reserved; + /**< Reserved. */ + uint32_t tx_dropped_hroom; + /**< Packets dropped because of insufficent headroom. */ + uint32_t tx_dropped_dtls; + /**< Packets dropped because of a DTLS packet. */ + uint32_t tx_dropped_nwireless; + /**< Packets dropped because the nwireless field information is wrong. */ + + uint32_t fast_mem; + /**< Set to 1 when tunnel is operating in fast memory. */ +}; + +/** + * nss_capwap_ip + * IP versions. + */ +struct nss_capwap_ip { + /** + * Union of IPv4 and IPv6 IP addresses. + */ + union { + uint32_t ipv4; /**< IPv4 address. */ + uint32_t ipv6[4]; /**< IPv6 address. */ + } ip; /**< Union of IPv4 and IPv6 IP addresses. */ +}; + +/** + * nss_capwap_encap_rule + * Encapsulation information for a CAPWAP tunnel. + */ +struct nss_capwap_encap_rule { + struct nss_capwap_ip src_ip; /**< Source IP. */ + uint32_t src_port; /**< Source port. */ + struct nss_capwap_ip dest_ip; /**< Destination IP. */ + uint32_t dest_port; /**< Destination port. */ + uint32_t path_mtu; /**< MTU on the path. */ +}; + +/** + * nss_capwap_decap_rule + * Decapsulation information for a CAPWAP tunnel. + */ +struct nss_capwap_decap_rule { + uint32_t reassembly_timeout; /**< Timeout in milliseconds. */ + uint32_t max_fragments; /**< Maximum number of fragments expected. */ + uint32_t max_buffer_size; /**< Maximum size of the payload buffer. */ +}; + +/** + * nss_capwap_rule_msg + * CAPWAP rule message. + * + * The same rule structure applies for both encapsulation and decapsulation + * in a tunnel. + */ +struct nss_capwap_rule_msg { + struct nss_capwap_encap_rule encap; /**< Encapsulation portion of the rule. */ + struct nss_capwap_decap_rule decap; /**< Decapsulation portion of the rule. */ + uint32_t stats_timer; /**< Statistics interval timer in milliseconds. */ + + /** + * Core to choose for receiving packets. + * + * Set to -1 for the NSS firmware to decide. + */ + int8_t rps; + + uint8_t type_flags; /**< VLAN or PPPOE is configured. */ + uint8_t l3_proto; + /**< Prototype is NSS_CAPWAP_TUNNEL_IPV4 or NSS_CAPWAP_TUNNEL_IPV6. */ + uint8_t which_udp; /**< Tunnel uses the UDP or UDPLite protocol. */ + uint32_t mtu_adjust; /**< MTU is reserved for a DTLS process. */ + uint32_t gmac_ifnum; /**< Outgoing physical interface. */ + uint32_t enabled_features; + /**< Tunnel enabled features bit flag. */ + + /* + * Parameters for each features + */ + uint32_t dtls_inner_if_num; /**< Interface number of the associated DTLS node. */ + uint8_t bssid[ETH_ALEN]; /**< BSSID value. */ + uint16_t outer_sgt_value; + /**< Security Group Tag value configured for this tunnel. */ +}; + +/** + * nss_capwap_version_msg + * Message to set the CAPWAP version. + */ +struct nss_capwap_version_msg { + uint32_t version; /**< CAPWAP protocol version. */ +}; + +/** + * nss_capwap_path_mtu_msg + * Message information for the path MTU. + */ +struct nss_capwap_path_mtu_msg { + uint32_t path_mtu; /**< Path MTU value between the controller and access point. */ +}; + +/** + * nss_capwap_dtls_msg + * DTLS message information. + */ +struct nss_capwap_dtls_msg { + uint32_t enable; /**< Enable or disable DTLS. */ + uint32_t dtls_inner_if_num; /**< Interface number of the associated DTLS. */ + uint32_t mtu_adjust; /**< MTU adjustment reported by the DTLS node. */ + uint32_t reserved; /**< Reserved field for future use. */ +}; + +/** + * nss_capwap_flow_rule_msg + * CAPWAP flow rule message structure. + */ +struct nss_capwap_flow_rule_msg { + /* + * 5-tuple info. + */ + uint16_t ip_version; /**< IP version. */ + uint16_t protocol; /**< Layer 4 protocol. */ + uint16_t src_port; /**< Source port. */ + uint16_t dst_port; /**< Destination port. */ + uint32_t src_ip[4]; /**< Source IP address. */ + uint32_t dst_ip[4]; /**< Destination IP address. */ + + /* + * Flow attributes. + */ + uint32_t flow_id; /**< Flow identification. */ +}; + +/** + * nss_capwap_msg + * Data for sending and receiving CAPWAP messages. + */ +struct nss_capwap_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a CAPWAP common message. + */ + union { + struct nss_capwap_rule_msg rule; + /**< Rule information. */ + struct nss_capwap_path_mtu_msg mtu; + /**< New MTU information. */ + struct nss_capwap_stats_msg stats; + /**< CAPWAP statistics. */ + struct nss_capwap_version_msg version; + /**< CAPWAP version to use. */ + struct nss_capwap_dtls_msg dtls; + /**< DTLS configuration. */ + struct nss_capwap_flow_rule_msg flow_rule_add; + /**< Flow rule add message. */ + struct nss_capwap_flow_rule_msg flow_rule_del; + /**< Flow rule delete message. */ + } msg; /**< Message payload. */ +}; + +/** + * nss_capwap_pn_stats + * Pnode statistics (64-bit version). + */ +struct nss_capwap_pn_stats { + uint64_t rx_packets; /**< Number of packets received. */ + uint64_t rx_bytes; /**< Number of bytes received. */ + uint64_t rx_dropped; /**< Number of dropped Rx packets. */ + uint64_t tx_packets; /**< Number of packets transmitted. */ + uint64_t tx_bytes; /**< Number of bytes transmitted. */ +}; + +/** + * nss_capwap_tunnel_stats + * Per-tunnel statistics seen by the HLOS. + */ +struct nss_capwap_tunnel_stats { + struct nss_capwap_pn_stats pnode_stats; /**< Common firmware statistics. */ + uint64_t dtls_pkts; /**< Number of DTLS packets flowing through. */ + + /* + * Rx/decap stats + */ + uint64_t rx_dup_frag; /**< Number of duplicate fragments. */ + uint64_t rx_segments; /**< Number of segments or fragments. */ + + /** + * Packets dropped because they are larger than the payload size. + */ + uint64_t rx_oversize_drops; + + uint64_t rx_frag_timeout_drops; + /**< Packets dropped because of a reassembly timeout. */ + uint64_t rx_queue_full_drops; + /**< Packets dropped because the queue is full. */ + uint64_t rx_n2h_queue_full_drops; + /**< Packets dropped because the NSS-to-host queue is full. */ + uint64_t rx_csum_drops; + /**< Packets dropped because of a checksum mismatch. */ + uint64_t rx_malformed; + /**< Packets dropped because of a malformed packet. */ + uint64_t rx_mem_failure_drops; + /**< Packets dropped because of a memory failure. */ + uint64_t rx_frag_gap_drops; + /**< Packets dropped because of a non-sequential fragment offset. */ + + /* + * Tx/encap stats + */ + uint64_t tx_segments; /**< Number of segments or fragments. */ + uint64_t tx_queue_full_drops; + /**< Packets dropped because the queue is full. */ + uint64_t tx_mem_failure_drops; + /**< Packets dropped because of a memory failure. */ + + uint64_t tx_dropped_sg_ref; + /**< Packets dropped because of a scatter-gather reference. */ + uint64_t tx_dropped_ver_mis; + /**< Packets dropped because of a version mismatch. */ + uint64_t Reserved; + /**< Reserved. */ + uint64_t tx_dropped_hroom; + /**< Packets dropped because of insufficent headroom. */ + uint64_t tx_dropped_dtls; + /**< Packets dropped because of a DTLS packet. */ + uint64_t tx_dropped_nwireless; + /**< Packets dropped because the nwireless field information is wrong. */ + + uint32_t fast_mem; + /**< Set to 1 when tunnel is operating in fast memory. */ +}; + +/** + * nss_capwap_stats_notification + * CAPWAP statistics structure. + */ +struct nss_capwap_stats_notification { + uint32_t core_id; /**< Core ID. */ + uint32_t if_num; /**< Interface number. */ + struct nss_capwap_tunnel_stats stats; /**< Per-tunnel statistics. */ +}; + +#ifdef __KERNEL__ /* only kernel will use. */ + +/** + * Callback function for receiving CAPWAP tunnel data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_capwap_buf_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * Callback function for receiving CAPWAP tunnel messages. + * + * @datatypes + * nss_capwap_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_capwap_msg_callback_t)(void *app_data, struct nss_capwap_msg *msg); + +/** + * nss_capwap_data_register + * Registers the CAPWAP tunnel interface with the NSS for sending and + * receiving tunnel messages. + * + * @datatypes + * nss_capwap_buf_callback_t \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] capwap_callback Callback for the CAPWAP tunnel data. + * @param[in] netdev Pointer to the associated network device. + * @param[in] features Data socket buffer types supported by this interface. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_capwap_data_register(uint32_t if_num, nss_capwap_buf_callback_t capwap_callback, struct net_device *netdev, uint32_t features); + +/** + * nss_capwap_tx_msg + * Sends CAPWAP tunnel messages to the NSS. + * + * Do not call this function from a softirq or interrupt because it + * might sleep if the NSS firmware is busy serving another host thread. + * + * @datatypes + * nss_ctx_instance \n + * nss_capwap_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in,out] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_capwap_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_capwap_msg *msg); + +/** + * nss_capwap_tx_buf + * Sends a CAPWAP tunnel data buffer to the NSS interface. + * + * @datatypes + * nss_ctx_instance \n + * sk_buff + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] os_buf Pointer to the OS data buffer. + * @param[in] if_num NSS interface number. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_capwap_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf, uint32_t if_num); + +/** + * nss_capwap_data_unregister + * Deregisters the CAPWAP tunnel interface from the NSS interface. + * + * @param[in] if_num NSS interface number. + * + * @return + * TRUE or FALSE + * + * @dependencies + * The tunnel interface must have been previously registered. + */ +extern bool nss_capwap_data_unregister(uint32_t if_num); + +/** + * nss_capwap_notify_register + * Registers an event callback handler with the HLOS driver. + * + * @datatypes + * nss_capwap_msg_callback_t + * + * @param[in] if_num NSS interface number. + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_capwap_notify_register(uint32_t if_num, nss_capwap_msg_callback_t cb, void *app_data); + +/** + * nss_capwap_notify_unregister + * Deregisters a message notifier from the HLOS driver. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] ctx Pointer to the context of the HLOS driver. + * @param[in] if_num NSS interface number. + * + * @return + * None. + * + * @dependencies + * The message notifier must have been previously registered. + */ +extern nss_tx_status_t nss_capwap_notify_unregister(struct nss_ctx_instance *ctx, uint32_t if_num); + +/** + * nss_capwap_get_ctx + * Gets the NSS context. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_capwap_get_ctx(void); + +/** + * nss_capwap_ifnum_with_core_id + * Gets the CAPWAP interface number with the core ID. + * + * @param[in] if_num NSS interface number. + * + * @return + * Interface number with the core ID. + */ +extern int nss_capwap_ifnum_with_core_id(int if_num); + +/** + * nss_capwap_get_max_buf_size + * Gets the NSS maximum buffer size. + * + * @param[in] nss_ctx Pointer to the NSS context. + * + * @return + * Maximum buffer size of this NSS core. + */ +extern uint32_t nss_capwap_get_max_buf_size(struct nss_ctx_instance *nss_ctx); + +/** + * nss_capwap_get_stats + * Gets per-tunnel statistics. + * + * @datatypes + * nss_capwap_tunnel_stats + * + * @param[in] if_num NSS interface number. + * @param[out] stats Pointer to the CAPWAP tunnel statistics. + * + * @return + * TRUE or FALSE. + */ +extern bool nss_capwap_get_stats(uint32_t if_num, struct nss_capwap_tunnel_stats *stats); + +/** + * nss_capwap_init + * Initializes the CAPWAP interface. + * + * @return + * None. + */ +extern void nss_capwap_init(void); + +/** + * nss_capwap_msg_init + * Initializes a CAPWAP message. + * + * @datatypes + * nss_capwap_msg \n + * nss_capwap_msg_callback_t + * + * @param[in,out] ncm Pointer to the message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_capwap_msg_init(struct nss_capwap_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, + nss_capwap_msg_callback_t cb, void *app_data); +/** + * nss_capwap_stats_register_notifier + * Registers a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_capwap_stats_register_notifier(struct notifier_block *nb); + +/** + * nss_capwap_stats_unregister_notifier + * Deregisters a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_capwap_stats_unregister_notifier(struct notifier_block *nb); + +/** + * @} + */ + +#endif /* __KERNEL__ */ +#endif /* __NSS_CAPWAP_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_clmap.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_clmap.h new file mode 100644 index 000000000..14d2be8ac --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_clmap.h @@ -0,0 +1,308 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * @file nss_clmap.h + * NSS client map interface definitions. + */ + +#ifndef __NSS_CLMAP_H +#define __NSS_CLMAP_H + + /** + * @addtogroup nss_clmap_subsystem + * @{ + */ + +/** + * Maximum number of supported client map interface. + */ +#define NSS_CLMAP_MAX_INTERFACES 1 + +/** + * nss_clmap_msg_type + * Client map message types. + */ +typedef enum nss_clmap_msg_type { + NSS_CLMAP_MSG_TYPE_SYNC_STATS, /**< Statistics synchronization message. */ + NSS_CLMAP_MSG_TYPE_INTERFACE_ENABLE, /**< Enable the interface. */ + NSS_CLMAP_MSG_TYPE_INTERFACE_DISABLE, /**< Disable the interface. */ + NSS_CLMAP_MSG_TYPE_MAC_ADD, /**< Add MAC rule to the database. */ + NSS_CLMAP_MSG_TYPE_MAC_DEL, /**< Remove MAC rule from the database. */ + NSS_CLMAP_MSG_TYPE_MAC_FLUSH, /**< Flush all the MAC rules for a tunnel. */ + NSS_CLMAP_MSG_TYPE_MAX, /**< Maximum message type. */ +} nss_clmap_msg_type_t; + +/** + * nss_clmap_error_types + * Error types for client map responses to messages from the host. + */ +typedef enum nss_clmap_error_types { + NSS_CLMAP_ERROR_UNKNOWN_TYPE = 1, /**< Unknown type error. */ + NSS_CLMAP_ERROR_INTERFACE_DISABLED, /**< Interface is already disabled. */ + NSS_CLMAP_ERROR_INTERFACE_ENABLED, /**< Interface is already enabled. */ + NSS_CLMAP_ERROR_INVALID_VLAN, /**< Invalid VLAN. */ + NSS_CLMAP_ERROR_INVALID_TUNNEL, /**< Invalid tunnel. */ + NSS_CLMAP_ERROR_MAC_TABLE_FULL, /**< MAC table is full. */ + NSS_CLMAP_ERROR_MAC_EXIST, /**< MAC does already exist in the table. */ + NSS_CLMAP_ERROR_MAC_NOT_EXIST, /**< MAC does not exist in the table. */ + NSS_CLMAP_ERROR_MAC_ENTRY_UNHASHED, /**< MAC entry is not hashed in table. */ + NSS_CLMAP_ERROR_MAC_ENTRY_INSERT_FAILED, + /**< Insertion into MAC table failed. */ + NSS_CLMAP_ERROR_MAC_ENTRY_ALLOC_FAILED, /**< MAC entry allocation failed. */ + NSS_CLMAP_ERROR_MAC_ENTRY_DELETE_FAILED,/**< MAC entry deletion failed. */ + NSS_CLMAP_ERROR_MAX, /**< Maximum error type. */ +} nss_clmap_error_t; + +/** + * nss_clmap_stats_msg + * Per-interface statistics messages from the NSS firmware. + */ +struct nss_clmap_stats_msg { + struct nss_cmn_node_stats node_stats; /**< Common firmware statistics. */ + uint32_t dropped_macdb_lookup_failed; /**< Dropped due to MAC database look up failed. */ + uint32_t dropped_invalid_packet_size; /**< Dropped due to invalid size packets. */ + uint32_t dropped_low_hroom; /**< Dropped due to insufficent headroom. */ + uint32_t dropped_next_node_queue_full; /**< Dropped due to next node queue full. */ + uint32_t dropped_pbuf_alloc_failed; /**< Dropped due to buffer allocation failure. */ + uint32_t dropped_linear_failed; /**< Dropped due to linear copy failure. */ + uint32_t shared_packet_count; /**< Shared packet count. */ + uint32_t ethernet_frame_error; /**< Ethernet frame error count. */ + uint32_t macdb_create_requests; /**< MAC database create requests count. */ + uint32_t macdb_create_mac_exists; /**< MAC database create failures, MAC exist count. */ + uint32_t macdb_create_table_full; /**< MAC database create failures, MAC database full count. */ + uint32_t macdb_destroy_requests; /**< MAC database destroy requests count. */ + uint32_t macdb_destroy_mac_notfound; /**< MAC database destroy failures, MAC not found count. */ + uint32_t macdb_destroy_mac_unhashed; /**< MAC database destroy failures, MAC unhashed count. */ + uint32_t macdb_flush_requests; /**< MAC database flush requests count. */ +}; + +/** + * nss_clmap_mac_msg + * Client map MAC message structure. + */ +struct nss_clmap_mac_msg { + uint32_t vlan_id; /**< VLAN ID. */ + uint32_t nexthop_ifnum; /**< Next hop interface number. */ + uint32_t needed_headroom; /**< Headroom to be added. */ + uint16_t mac_addr[3]; /**< MAC address. */ + uint8_t flags; /**< Flags that carry metadata information. */ + uint8_t reserved; /**< Reserved. */ +}; + +/** + * nss_clmap_flush_mac_msg + * CLient flush map MAC message structure. + */ +struct nss_clmap_flush_mac_msg { + uint32_t nexthop_ifnum; /**< Next hop interface number. */ +}; + +/** + * nss_clmap_msg + * Data for sending and receiving client map messages. + */ +struct nss_clmap_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a client map common message. + */ + union { + struct nss_clmap_stats_msg stats; + /**< Client map statistics. */ + struct nss_clmap_mac_msg mac_add; + /**< MAC rule add message. */ + struct nss_clmap_mac_msg mac_del; + /**< MAC rule delete message. */ + struct nss_clmap_flush_mac_msg mac_flush; + /**< MAC rule flush message. */ + } msg; /**< Message payload. */ +}; + +/** + * Callback function for receiving client map data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_clmap_buf_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * Callback function for receiving client map messages. + * + * @datatypes + * nss_cmn_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_clmap_msg_callback_t)(void *app_data, struct nss_cmn_msg *msg); + +/** + * nss_clmap_tx_msg + * Sends client map messages to the NSS. + * + * Do not call this function from a softirq or interrupt because it + * might sleep if the NSS firmware is busy serving another host thread. + * + * @datatypes + * nss_ctx_instance \n + * nss_clmap_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in,out] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_clmap_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_clmap_msg *msg); + +/** + * nss_clmap_tx_msg_sync + * Sends client map messages to the NSS. + * + * Do not call this function from a softirq or interrupt because it + * might sleep if the NSS firmware is busy serving another host thread. + * + * @datatypes + * nss_ctx_instance \n + * nss_clmap_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in,out] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_clmap_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_clmap_msg *msg); + +/** + * nss_clmap_tx_buf + * Sends a client map data buffer to the NSS interface. + * + * @datatypes + * nss_ctx_instance \n + * sk_buff + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] buf Pointer to the data buffer. + * @param[in] if_num NSS interface number. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_clmap_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *buf, uint32_t if_num); + +/** + * nss_clmap_unregister + * Deregisters the client map interface from the NSS interface. + * + * @param[in] if_num NSS interface number. + * + * @return + * TRUE or FALSE + * + * @dependencies + * The interface must have been previously registered. + */ +extern bool nss_clmap_unregister(uint32_t if_num); + +/** + * nss_clmap_register + * Registers the client map interface with the NSS for sending and + * receiving interface messages. + * + * @datatypes + * nss_clmap_msg_callback_t \n + * nss_clmap_buf_callback_t \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] dynamic_interface_type NSS interface type. + * @param[in] data_cb Data callback for the client map data. + * @param[in] notify_cb Notify callback for the client map data. + * @param[in] netdev Pointer to the associated network device. + * @param[in] features Data socket buffer types supported by this interface. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_clmap_register(uint32_t if_num, uint32_t dynamic_interface_type, + nss_clmap_buf_callback_t data_cb, nss_clmap_msg_callback_t notify_cb, + struct net_device *netdev, uint32_t features); + +/** + * nss_clmap_get_ctx + * Get the NSS context. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_clmap_get_ctx(void); + +/** + * nss_clmap_ifnum_with_core_id + * Gets the client map interface number with the core ID. + * + * @param[in] if_num NSS interface number. + * + * @return + * Interface number with the core ID. + */ +extern int nss_clmap_ifnum_with_core_id(int if_num); + +/** + * nss_clmap_init + * Initializes the client map interface. + * + * @return + * None. + */ +extern void nss_clmap_init(void); + +/** + * nss_clmap_msg_init + * Initializes a client map message. + * + * @datatypes + * nss_clmap_msg \n + * nss_clmap_msg_callback_t + * + * @param[in,out] ncm Pointer to the message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_clmap_msg_init(struct nss_clmap_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, + nss_clmap_msg_callback_t cb, void *app_data); + +/** + * @} + */ + +#endif /* __NSS_CLMAP_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_cmn.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_cmn.h new file mode 100644 index 000000000..a3fc289ab --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_cmn.h @@ -0,0 +1,471 @@ +/* + ************************************************************************** + * Copyright (c) 2014, 2016-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_cmn.h + * NSS Common Message Structure and APIs + */ + +#ifndef __NSS_CMN_H +#define __NSS_CMN_H + +/** + * @addtogroup nss_common_subsystem + * @{ + */ + +/** + * @struct nss_ctx_instance + * Forward declaration for structure that contains instance data for each + * NSS core. Contents of structure are private to the NSS driver. + */ +struct nss_ctx_instance; + +/* + * The first 8 bits of an interfaces number is representing the core_id, + * 0 means local core. + */ + +#define NSS_CORE_ID_SHIFT 24 /**< Number of bits to shift a core local interface number. */ + +/** + * Macro that appends the core identifier to an interface number. + */ +#define NSS_INTERFACE_NUM_APPEND_COREID(nss_ctx, interface) ((interface) | ((nss_ctx->id + 1) << NSS_CORE_ID_SHIFT)) + +/** + * Macro to obtain a core local interface number. + */ +#define NSS_INTERFACE_NUM_GET(interface) ((interface) & 0xffffff) + +/** + * Macro to obtain an interface core number. + */ +#define NSS_INTERFACE_NUM_GET_COREID(interface) ((interface >> NSS_CORE_ID_SHIFT) & 0xff) + +/* + * Common enumerations. + */ + +/** + * nss_tx_status_t + * Tx command failure results. + * + * Types starting with NSS_TX_FAILURE_SYNC_ are only used by synchronous messages. + */ +typedef enum { + NSS_TX_SUCCESS = 0, + NSS_TX_FAILURE, + NSS_TX_FAILURE_QUEUE, + NSS_TX_FAILURE_NOT_READY, + NSS_TX_FAILURE_TOO_LARGE, + NSS_TX_FAILURE_TOO_SHORT, + NSS_TX_FAILURE_NOT_SUPPORTED, + NSS_TX_FAILURE_BAD_PARAM, + NSS_TX_FAILURE_NOT_ENABLED, + NSS_TX_FAILURE_SYNC_BAD_PARAM, + NSS_TX_FAILURE_SYNC_TIMEOUT, + NSS_TX_FAILURE_SYNC_FW_ERR, + NSS_TX_FAILURE_MAX, +} nss_tx_status_t; + +/** + * nss_state_t + * Initialization states. + */ +typedef enum { + NSS_STATE_UNINITIALIZED = 0, + NSS_STATE_INITIALIZED +} nss_state_t; + +/** + * nss_core_id_t + * NSS core IDs. + */ +typedef enum { + NSS_CORE_0 = 0, + NSS_CORE_1, + NSS_CORE_MAX +} nss_core_id_t; + +/** + * nss_cb_register_status_t + * Callback registration states. + */ +typedef enum { + NSS_CB_REGISTER_SUCCESS = 0, + NSS_CB_REGISTER_FAILED, +} nss_cb_register_status_t; + +/** + * nss_cb_unregister_status_t + * Callback deregistration states. + */ +typedef enum { + NSS_CB_UNREGISTER_SUCCESS = 0, + NSS_CB_UNREGISTER_FAILED, +} nss_cb_unregister_status_t; + +/** + * nss_cmn_response + * Responses for a common message. + */ +enum nss_cmn_response { + NSS_CMN_RESPONSE_ACK, + NSS_CMN_RESPONSE_EVERSION, + NSS_CMN_RESPONSE_EINTERFACE, + NSS_CMN_RESPONSE_ELENGTH, + NSS_CMN_RESPONSE_EMSG, + NSS_CMN_RESPONSE_NOTIFY, + NSS_CMN_RESPONSE_LAST +}; + +/** + * Array of log messages for common NSS responses. + */ +extern int8_t *nss_cmn_response_str[NSS_CMN_RESPONSE_LAST]; + +/** + * nss_cmn_msg + * Common message information. + */ +struct nss_cmn_msg { + uint16_t version; /**< Version ID for the main message format. */ + uint16_t len; /**< Length of the message, excluding the header. */ + uint32_t interface; /**< Primary key for all messages. */ + enum nss_cmn_response response; + /**< Primary response. All messages must specify one of these responses. */ + + uint32_t type; /**< Decentralized request number used to match response numbers. */ + uint32_t error; /**< Decentralized specific error message (response == EMSG). */ + + /** + * Padding used to start the callback from a 64-bit boundary. This field can be reused. + */ + uint32_t reserved; + + nss_ptr_t cb; /**< Contains the callback pointer. */ +#ifndef __LP64__ + uint32_t padding1; /**< Padding used to fit 64 bits. Do not reuse. */ +#endif + nss_ptr_t app_data; /**< Contains the application data. */ +#ifndef __LP64__ + uint32_t padding2; /**< Padding used to fit 64 bits. Do not reuse. */ +#endif +}; + +/** + * nss_cmn_node_stats + * Common per-node statistics. + */ +struct nss_cmn_node_stats { + uint32_t rx_packets; /**< Number of packets received. */ + uint32_t rx_bytes; /**< Number of bytes received. */ + uint32_t tx_packets; /**< Number of packets transmitted. */ + uint32_t tx_bytes; /**< Number of bytes transmitted. */ + uint32_t rx_dropped[NSS_MAX_NUM_PRI]; /**< Packets dropped on receive due to queue full. */ +}; + +/** + * nss_cmn_get_msg_len + * Gets the message length of a host-to-NSS message. + * + * @datatypes + * nss_cmn_get_msg_len + * + * @param[in] ncm Pointer to the common message. + * + * @return + * Length of the message specified in the argument to this function. + */ +static inline uint32_t nss_cmn_get_msg_len(struct nss_cmn_msg *ncm) +{ + return ncm->len + sizeof(struct nss_cmn_msg); +} + +#ifdef __KERNEL__ /* only for kernel to use. */ + +/** + * nss_cmn_msg_init + * Initializes the common area of an asynchronous host-to-NSS message. + * + * @datatypes + * nss_cmn_msg + * + * @param[in,out] ncm Pointer to the common message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Pointer to the callback function. + * @param[in] app_data Pointer to the application context for this message. + * + * @return + * None. + */ +extern void nss_cmn_msg_init(struct nss_cmn_msg *ncm, uint32_t if_num, uint32_t type, uint32_t len, + void *cb, void *app_data); + +/** + * nss_cmn_msg_sync_init + * Initializes the common message of a synchronous host-to-NSS message. + * + * @datatypes + * nss_cmn_msg + * + * @param[in,out] ncm Pointer to the common message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * + * @return + * None. + */ +extern void nss_cmn_msg_sync_init(struct nss_cmn_msg *ncm, uint32_t if_num, uint32_t type, uint32_t len); + +/** + * nss_cmn_get_interface_number + * Gets the interface number. + * + * @datatypes + * nss_ctx_instance \n + * net_device + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] dev Pointer to the OS network device pointer. + * + * @return + * Interface number. + */ +extern int32_t nss_cmn_get_interface_number(struct nss_ctx_instance *nss_ctx, struct net_device *dev); + +/** + * nss_cmn_get_interface_number_by_dev + * Gets the interface number of a device. + * + * @datatypes + * net_device + * + * @param[in] dev Pointer to the OS network device pointer. + * + * @return + * Interface number, or -1 on failure. + */ +extern int32_t nss_cmn_get_interface_number_by_dev(struct net_device *dev); + +/** + * nss_cmn_get_interface_number_by_dev_and_type + * Gets the interface number by a device and its type. + * + * @datatypes + * net_device + * + * @param[in] dev Pointer to the OS network device pointer. + * @param[in] type Type of this interface. + * + * @return + * Interface number, or -1 on failure. + */ +extern int32_t nss_cmn_get_interface_number_by_dev_and_type(struct net_device *dev, uint32_t type); + +/** + * nss_cmn_interface_is_redirect + * Determines if the interface number is a redirect interface. + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] interface_num NSS interface number. + * + * @return + * TRUE if the number is a redirect interface. Otherwise FALSE. + */ +extern bool nss_cmn_interface_is_redirect(struct nss_ctx_instance *nss_ctx, int32_t interface_num); + +/** + * nss_cmn_append_core_id + * Append core ID on NSS interface number. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] if_num NSS interface number. + * + * @return + * Interface number with core ID. + */ +extern int nss_cmn_append_core_id(struct nss_ctx_instance *nss_ctx, int if_num); + +/** + * nss_cmn_get_interface_dev + * Gets an interface device pointer. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] if_num NSS interface number. + * + * @return + * Interface device pointer. + */ +extern struct net_device *nss_cmn_get_interface_dev(struct nss_ctx_instance *nss_ctx, uint32_t if_num); + +/** + * nss_cmn_get_state + * Obtains the NSS state. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS context. + * + * @return + * NSS state that indicates whether the NSS core is initialized. For possible values, see nss_state_t. + */ +extern nss_state_t nss_cmn_get_state(struct nss_ctx_instance *nss_ctx); + +/** + * Callback function for queue decongestion messages. + * + * @param[in] app_data Pointer to the application context for this message. + */ +typedef void (*nss_cmn_queue_decongestion_callback_t)(void *app_data); + +/** + * nss_cmn_register_queue_decongestion + * Registers a queue for a decongestion event. + * + * The callback function is called with the spinlock held. The function should avoid deadlocks + * caused by attempting to acquire multiple spinlocks. + + * @datatypes + * nss_ctx_instance \n + * nss_cmn_queue_decongestion_callback_t + * + * @param[in,out] nss_ctx Pointer to the NSS context. + * @param[in] event_callback Callback for the message. + * @param[in] app_data Pointer to the application context to be returned in the + * callback. + * + * @return + * #NSS_CB_REGISTER_SUCCESS if registration is successful. + * @par + * Otherwise, #NSS_CB_REGISTER_FAILED. + */ +extern nss_cb_register_status_t nss_cmn_register_queue_decongestion(struct nss_ctx_instance *nss_ctx, nss_cmn_queue_decongestion_callback_t event_callback, void *app_data); + +/** + * nss_cmn_unregister_queue_decongestion + * Deregisters a queue from receiving a decongestion event. + * + * @datatypes + * nss_ctx_instance \n + * nss_cmn_queue_decongestion_callback_t + * + * @param[in,out] nss_ctx Pointer to the NSS context. + * @param[in] event_callback Callback for the message. + * + * @return + * #NSS_CB_REGISTER_SUCCESS if registration is successful. + * @par + * Otherwise, #NSS_CB_REGISTER_FAILED. + * + * @dependencies + * The callback function must have been previously registered. + */ +extern nss_cb_unregister_status_t nss_cmn_unregister_queue_decongestion(struct nss_ctx_instance *nss_ctx, nss_cmn_queue_decongestion_callback_t event_callback); + +/** + * Callback function for packets with service code. + * + * @param[in] app_data Pointer to the application context for this message. + * @param[in] nbuf Pointer to the socket buffer. + */ +typedef void (*nss_cmn_service_code_callback_t)(void *app_data, struct sk_buff *nbuf); + +/** + * nss_cmn_register_service_code + * Registers a callback for a service code. + * + * @datatypes + * nss_ctx_instance \n + * nss_cmn_service_code_callback_t + * + * @param[in,out] nss_ctx Pointer to the NSS context. + * @param[in] cb Callback for the message. + * @param[in] service_code Service code found attached to the packet. + * @param[in] app_data Pointer to the application context to be returned in the + * callback. + * + * @return + * #NSS_CB_REGISTER_SUCCESS if registration is successful. + * @par + * Otherwise, #NSS_CB_REGISTER_FAILED. + */ +extern nss_cb_register_status_t nss_cmn_register_service_code(struct nss_ctx_instance *nss_ctx, nss_cmn_service_code_callback_t cb, uint8_t service_code, void *app_data); + +/** + * nss_cmn_unregister_service_code + * Deregisters a callback for the given service code. + * + * @datatypes + * nss_ctx_instance \n + * nss_cmn_service_code_callback_t + * + * @param[in,out] nss_ctx Pointer to the NSS context. + * @param[in] cb Callback for the message. + * @param[in] service_code Service code found attached to the packet. + * + * @return + * #NSS_CB_REGISTER_SUCCESS if registration is successful. + * @par + * Otherwise, #NSS_CB_REGISTER_FAILED. + * + * @dependencies + * The callback function must have been previously registered. + */ +extern nss_cb_unregister_status_t nss_cmn_unregister_service_code(struct nss_ctx_instance *nss_ctx, nss_cmn_service_code_callback_t cb, uint8_t service_code); + +/** + * nss_cmn_get_nss_enabled + * Checks whether the NSS mode is supported on the platform. + * + * @return + * TRUE if NSS is supported. \n + * Otherwise, FALSE. + */ +extern bool nss_cmn_get_nss_enabled(void); + +/** + * nss_cmn_rx_dropped_sum + * Sums dropped packet count of all NSS pnode queues. + * + * @datatypes + * nss_cmn_node_stats \n + * + * @param[in] node_stats Pointer to node statistics. + * + * @return + * Total dropped packets count. + */ +extern uint32_t nss_cmn_rx_dropped_sum(struct nss_cmn_node_stats *node_stats); + +#endif /* __KERNEL__ */ + +/** + * @} + */ + +#endif /* __NSS_CMN_MSG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_crypto.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_crypto.h new file mode 100644 index 000000000..5ef514d6e --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_crypto.h @@ -0,0 +1,392 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_crypto.h + * NSS Crypto interface definitions. + */ + +#ifndef __NSS_CRYPTO_H +#define __NSS_CRYPTO_H + +/** + * @addtogroup nss_crypto_subsystem + * @{ + */ + +#define NSS_CRYPTO_MAX_IDXS 64 /**< Maximum number of supported sessions. */ +#define NSS_CRYPTO_MAX_ENGINES 4 /**< Maximum number of engines available. */ +#define NSS_CRYPTO_BAM_PP 2 /**< Bus Access Manager pipe pairs. */ + +/** + * nss_crypto_hash + * Hash sizes supported by the hardware. + */ +enum nss_crypto_hash { + NSS_CRYPTO_HASH_SHA96 = 12, + NSS_CRYPTO_HASH_SHA128 = 16, + NSS_CRYPTO_HASH_SHA160 = 20, + NSS_CRYPTO_HASH_SHA256 = 32 +}; + +/** + * nss_crypto_cipher + * Cipher algorithms. + */ +enum nss_crypto_cipher { + NSS_CRYPTO_CIPHER_NONE = 0, + NSS_CRYPTO_CIPHER_AES_CBC, /**< AES, and CBC for 128-bit and 256-bit key sizes. */ + NSS_CRYPTO_CIPHER_DES, /**< DES, and CBC for 64-bit key size. */ + NSS_CRYPTO_CIPHER_NULL, /**< NULL and CBC. */ + NSS_CRYPTO_CIPHER_AES_CTR, /**< AES, and CTR for 128-bit and 256-bit key sizes. */ + NSS_CRYPTO_CIPHER_MAX +}; + +/** + * nss_crypto_auth + * Authentication algorithms. + */ +enum nss_crypto_auth { + NSS_CRYPTO_AUTH_NONE = 0, + NSS_CRYPTO_AUTH_SHA1_HMAC, + NSS_CRYPTO_AUTH_SHA256_HMAC, + NSS_CRYPTO_AUTH_NULL, + NSS_CRYPTO_AUTH_MAX +}; + +/** + * nss_crypto_msg_type + * Synchronization types. + */ +enum nss_crypto_msg_type { + NSS_CRYPTO_MSG_TYPE_NONE = 0, + NSS_CRYPTO_MSG_TYPE_OPEN_ENG = 1, + NSS_CRYPTO_MSG_TYPE_CLOSE_ENG = 2, + NSS_CRYPTO_MSG_TYPE_UPDATE_SESSION = 3, + NSS_CRYPTO_MSG_TYPE_STATS = 4, + NSS_CRYPTO_MSG_TYPE_MAX +}; + +/** + * nss_crypto_msg_error + * Response types. + */ +enum nss_crypto_msg_error { + NSS_CRYPTO_MSG_ERROR_NONE = 0, + NSS_CRYPTO_MSG_ERROR_INVAL_ENG = 1, + NSS_CRYPTO_MSG_ERROR_UNSUPP_OP = 2, + NSS_CRYPTO_MSG_ERROR_INVAL_OP = 3, + NSS_CRYPTO_MSG_ERROR_INVAL_IDX_RANGE = 4, + NSS_CRYPTO_MSG_ERROR_IDX_ALLOC_FAIL = 5, + NSS_CRYPTO_MSG_ERROR_MAX +}; + +/** + * nss_crypto_session_state + * Session states. + */ +enum nss_crypto_session_state { + NSS_CRYPTO_SESSION_STATE_NONE = 0, + NSS_CRYPTO_SESSION_STATE_ACTIVE = 1, + NSS_CRYPTO_SESSION_STATE_FREE = 2 +}; + +/** + * nss_crypto_buf_origin + * Origins of the crypto session. + */ +enum nss_crypto_buf_origin { + NSS_CRYPTO_BUF_ORIGIN_HOST = 0x001, + NSS_CRYPTO_BUF_ORIGIN_NSS = 0x0002, +}; + +/** + * nss_crypto_idx + * Crypto session index information. + */ +struct nss_crypto_idx { + uint16_t pp_num; /**< Pipe pair index. */ + uint16_t cmd_len; /**< Command block length to program. */ + uint32_t cblk_paddr; /**< Physical address of the command block. */ +}; + +/** + * nss_crypto_config_eng + * Engine configuration information for opening the engine from the host. + * + * This structure is called to initialize the crypto NSS engine-specific data + * structures. Ideally, the host can send a single probe for all engines, but + * the current implementation relies on probes per engine. + */ +struct nss_crypto_config_eng { + uint32_t eng_id; /**< Engine number to open. */ + uint32_t bam_pbase; /**< BAM base address (physical). */ + uint32_t crypto_pbase; /**< Crypto base address (physical). */ + uint32_t desc_paddr[NSS_CRYPTO_BAM_PP]; + /**< Pipe description address (physical). */ + struct nss_crypto_idx idx[NSS_CRYPTO_MAX_IDXS]; + /**< Allocated session indices. */ +}; + +/** + * nss_crypto_config_session + * Session-related state configuration. + */ +struct nss_crypto_config_session { + uint32_t idx; /**< Session index on which the state is reset. */ + uint32_t state; /**< Index state of the session. */ + uint32_t iv_len; /**< Length of the initialization vector. */ +}; + +/** + * nss_crypto_stats + * Crypto statistics. + */ +struct nss_crypto_stats { + uint32_t queued; /**< Number of frames waiting to be processed. */ + uint32_t completed; /**< Number of frames processed. */ + uint32_t dropped; /**< Number of frames dropped or not processed. */ +}; + +/** + * nss_crypto_sync_stats + * Statistics synchronized to the host. + */ +struct nss_crypto_sync_stats { + struct nss_crypto_stats eng_stats[NSS_CRYPTO_MAX_ENGINES]; + /**< Tx or Rx statistics captured per crypto engine. */ + struct nss_crypto_stats idx_stats[NSS_CRYPTO_MAX_IDXS]; + /**< Tx or Rx statistics captured per session. */ + struct nss_crypto_stats total; + /**< Total statistics captured in and out of the engine. */ +}; + +/** + * nss_crypto_msg + * Data for sending and receiving crypto messages. + */ +struct nss_crypto_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a crypto message. + */ + union { + struct nss_crypto_config_eng eng; + /**< Opens an engine. */ + struct nss_crypto_config_session session; + /**< Resets the statistics. */ + struct nss_crypto_sync_stats stats; + /**< Synchronized statistics for crypto. */ + } msg; /**< Message payload. */ +}; + +#ifdef __KERNEL__ /* only kernel will use. */ + +/** + * Message notification callback. + * + * @datatypes + * nss_crypto_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_crypto_msg_callback_t)(void *app_data, struct nss_crypto_msg *msg); + +/** + * Data callback. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_crypto_buf_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * Power management event callback. + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] turbo Turbo mode event. + * @param[in] auto_scale Specifies the auto scaling of the NSS clock frequency. + * + * @return + * TRUE if crypto is scaled to turbo. + */ +typedef bool (*nss_crypto_pm_event_callback_t)(void *app_data, bool turbo, bool auto_scale); + +/** + * nss_crypto_tx_msg + * Sends a crypto message. + * + * @datatypes + * nss_ctx_instance \n + * nss_crypto_msg + * + * @param[in] nss_ctx Pointer to the NSS context of the HLOS driver. + * @param[in] msg Pointer to the message data. + * + * @return + * None. + */ +extern nss_tx_status_t nss_crypto_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_crypto_msg *msg); + +/** + * nss_crypto_tx_buf + * Sends a crypto data packet. + * + * @datatypes + * nss_ctx_instance \n + * sk_buff + * + * @param[in] nss_ctx Pointer to the NSS context of the HLOS driver + * @param[in] if_num NSS interface number. + * @param[in] skb Pointer to the data socket buffer. + * + * @return + * None. + */ +extern nss_tx_status_t nss_crypto_tx_buf(struct nss_ctx_instance *nss_ctx, uint32_t if_num, struct sk_buff *skb); + +/** + * nss_crypto_notify_register + * Registers an event callback handler with the HLOS driver. + * + * @datatypes + * nss_crypto_msg_callback_t + * + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern struct nss_ctx_instance *nss_crypto_notify_register(nss_crypto_msg_callback_t cb, void *app_data); + +/** + * nss_crypto_data_register + * Registers a data callback handler with the HLOS driver. + * + * @datatypes + * nss_crypto_buf_callback_t \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] cb Callback function for the data. + * @param[in] netdev Pointer to the network device. + * @param[in] features Data socket buffer types supported by this interface. + * + * @return + * None. + */ +extern struct nss_ctx_instance *nss_crypto_data_register(uint32_t if_num, nss_crypto_buf_callback_t cb, + struct net_device *netdev, uint32_t features); + +/** + * nss_crypto_pm_notify_register + * Registers a power management event callback handler with the HLOS driver. + * + * @datatypes + * nss_crypto_pm_event_callback_t + * + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_crypto_pm_notify_register(nss_crypto_pm_event_callback_t cb, void *app_data); + +/** + * nss_crypto_notify_unregister + * Deregisters an event callback handler notifier from the HLOS driver. + * + * @datatypes + * nss_ctx_instance + * + * @param[in,out] ctx Pointer to the context of the HLOS driver. + * + * @return + * None. + * + * @dependencies + * The event callback handler must have been previously registered. + */ +extern void nss_crypto_notify_unregister(struct nss_ctx_instance *ctx); + +/** + * nss_crypto_data_unregister + * Deregisters a data callback handler from the HLOS driver. + * + * @datatypes + * nss_ctx_instance + * + * @param[in,out] ctx Pointer to the context of the HLOS driver. + * @param[in] if_num NSS interface number. + * + * @return + * None. + * + * @dependencies + * The callback handler must have been previously registered. + */ +extern void nss_crypto_data_unregister(struct nss_ctx_instance *ctx, uint32_t if_num); + +/** + * nss_crypto_pm_notify_unregister + * Deregisters a power management event callback handler from the HLOS driver. + * + * @return + * None. + * + * @dependencies + * The callback handler must have been previously registered. + */ +extern void nss_crypto_pm_notify_unregister(void); + +/** + * nss_crypto_msg_init + * Initializes a crypto-specific message. + * + * @datatypes + * nss_crypto_msg \n + * nss_crypto_msg_callback_t + * + * @param[in,out] ncm Pointer to the message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_crypto_msg_init(struct nss_crypto_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, + nss_crypto_msg_callback_t cb, void *app_data); + +#endif /*__KERNEL__ */ + +/** + * @} + */ + +#endif /* __NSS_CRYPTO_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_crypto_cmn.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_crypto_cmn.h new file mode 100644 index 000000000..61b97f1a8 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_crypto_cmn.h @@ -0,0 +1,460 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_crypto_cmn.h + * NSS Crypto common interface definitions. + */ +#ifndef __NSS_CRYPTO_CMN_H +#define __NSS_CRYPTO_CMN_H + +/** + * @addtogroup nss_crypto_subsystem + * @{ + */ + +/* + * Context message related array sizes + */ +#define NSS_CRYPTO_CMN_CTX_SPARE 4 /**< Context spare words size. */ +#define NSS_CRYPTO_CMN_VER_WORDS 4 /**< Firmware version words size.*/ +#define NSS_CRYPTO_CIPHER_KEYLEN_MAX 32 /**< Maximum cipher keysize. */ +#define NSS_CRYPTO_AUTH_KEYLEN_MAX 128 /**< Maximum authorization keysize. */ +#define NSS_CRYPTO_NONCE_SIZE_MAX 4 /**< Maximum authorization keysize. */ + +/** + * nss_crypto_cmn_algo + * List of crypto algorithms supported. + */ +enum nss_crypto_cmn_algo { + NSS_CRYPTO_CMN_ALGO_NULL, /**< NULL transform. */ + NSS_CRYPTO_CMN_ALGO_3DES_CBC, /**< Asynchronous block cipher. */ + NSS_CRYPTO_CMN_ALGO_AES128_CBC, /**< Asynchronous block cipher. */ + NSS_CRYPTO_CMN_ALGO_AES192_CBC, /**< Asynchronous block cipher. */ + NSS_CRYPTO_CMN_ALGO_AES256_CBC, /**< Asynchronous block cipher. */ + NSS_CRYPTO_CMN_ALGO_AES128_CTR, /**< Asynchronous block cipher. */ + NSS_CRYPTO_CMN_ALGO_AES192_CTR, /**< Asynchronous block cipher. */ + NSS_CRYPTO_CMN_ALGO_AES256_CTR, /**< Asynchronous block cipher. */ + NSS_CRYPTO_CMN_ALGO_AES128_ECB, /**< Asynchronous block cipher. */ + NSS_CRYPTO_CMN_ALGO_AES192_ECB, /**< Asynchronous block cipher. */ + NSS_CRYPTO_CMN_ALGO_AES256_ECB, /**< Asynchronous block cipher. */ + NSS_CRYPTO_CMN_ALGO_AES128_GCM, /**< Asynchronous block cipher. */ + NSS_CRYPTO_CMN_ALGO_AES192_GCM, /**< Asynchronous block cipher. */ + NSS_CRYPTO_CMN_ALGO_AES256_GCM, /**< Asynchronous block cipher. */ + NSS_CRYPTO_CMN_ALGO_MD5_HASH, /**< Asynchronous digest. */ + NSS_CRYPTO_CMN_ALGO_SHA160_HASH, /**< Asynchronous digest. */ + NSS_CRYPTO_CMN_ALGO_SHA224_HASH, /**< Asynchronous digest. */ + NSS_CRYPTO_CMN_ALGO_SHA256_HASH, /**< Asynchronous digest. */ + NSS_CRYPTO_CMN_ALGO_SHA384_HASH, /**< Asynchronous digest. */ + NSS_CRYPTO_CMN_ALGO_SHA512_HASH, /**< Asynchronous digest. */ + NSS_CRYPTO_CMN_ALGO_MD5_HMAC, /**< Asynchronous digest. */ + NSS_CRYPTO_CMN_ALGO_SHA160_HMAC, /**< Asynchronous digest. */ + NSS_CRYPTO_CMN_ALGO_SHA224_HMAC, /**< Asynchronous digest. */ + NSS_CRYPTO_CMN_ALGO_SHA256_HMAC, /**< Asynchronous digest. */ + NSS_CRYPTO_CMN_ALGO_SHA384_HMAC, /**< Asynchronous digest. */ + NSS_CRYPTO_CMN_ALGO_SHA512_HMAC, /**< Asynchronous digest. */ + NSS_CRYPTO_CMN_ALGO_AES128_GMAC, /**< Asynchronous digest. */ + NSS_CRYPTO_CMN_ALGO_AES192_GMAC, /**< Asynchronous digest. */ + NSS_CRYPTO_CMN_ALGO_AES256_GMAC, /**< Asynchronous digest. */ + NSS_CRYPTO_CMN_ALGO_AES128_GCM_GMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES128_CBC_MD5_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES128_CBC_SHA160_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES128_CBC_SHA256_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES128_CBC_SHA384_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES128_CBC_SHA512_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES192_GCM_GMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES192_CBC_MD5_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES192_CBC_SHA160_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES192_CBC_SHA256_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES192_CBC_SHA384_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES192_CBC_SHA512_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES256_GCM_GMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES256_CBC_MD5_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES256_CBC_SHA160_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES256_CBC_SHA256_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES256_CBC_SHA384_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES256_CBC_SHA512_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES128_CTR_MD5_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES128_CTR_SHA160_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES128_CTR_SHA256_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES128_CTR_SHA384_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES128_CTR_SHA512_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES192_CTR_MD5_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES192_CTR_SHA160_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES192_CTR_SHA256_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES192_CTR_SHA384_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES192_CTR_SHA512_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES256_CTR_MD5_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES256_CTR_SHA160_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES256_CTR_SHA256_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES256_CTR_SHA384_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_AES256_CTR_SHA512_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_3DES_CBC_MD5_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_3DES_CBC_SHA160_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_3DES_CBC_SHA256_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_3DES_CBC_SHA384_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_3DES_CBC_SHA512_HMAC, /**< AEAD transform. */ + NSS_CRYPTO_CMN_ALGO_MAX +}; + +/** + * nss_crypto_cmn_resp_error + * Response errors from crypto hardware + */ +enum nss_crypto_cmn_resp_error { + NSS_CRYPTO_CMN_RESP_ERROR_NONE = 0, /**< No error. */ + NSS_CRYPTO_CMN_RESP_ERROR_HDR_VERSION, /**< Header version mismatch. */ + NSS_CRYPTO_CMN_RESP_ERROR_CTX_RANGE, /**< Crypto index out-of-range. */ + NSS_CRYPTO_CMN_RESP_ERROR_CTX_NOUSE, /**< Crypto index is freed. */ + NSS_CRYPTO_CMN_RESP_ERROR_DATA_EMPTY, /**< Crypto data is empty. */ + NSS_CRYPTO_CMN_RESP_ERROR_DATA_LEN, /**< Crypto data length. */ + NSS_CRYPTO_CMN_RESP_ERROR_DATA_TIMEOUT, /**< Data timeout from hardware. */ + NSS_CRYPTO_CMN_RESP_ERROR_CIPHER_ALGO, /**< Cipher algorithm is not supported. */ + NSS_CRYPTO_CMN_RESP_ERROR_CIPHER_MODE, /**< Cipher mode is not supported. */ + NSS_CRYPTO_CMN_RESP_ERROR_CIPHER_BLK_LEN, /**< Cipher block length is not aligned. */ + NSS_CRYPTO_CMN_RESP_ERROR_HASH_CHECK, /**< Hash check failed. */ + NSS_CRYPTO_CMN_RESP_ERROR_HASH_NOSPACE, /**< No space to write hash. */ + NSS_CRYPTO_CMN_RESP_ERROR_HW_STATUS, /**< More errors in hardware status. */ + NSS_CRYPTO_CMN_RESP_ERROR_MAX +}; + +/** + * nss_crypto_cmn_msg_type + * Message types supported. + */ +enum nss_crypto_cmn_msg_type { + NSS_CRYPTO_CMN_MSG_TYPE_NONE = 0, /**< Invalid message. */ + NSS_CRYPTO_CMN_MSG_TYPE_SETUP_NODE, /**< Initialize node. */ + NSS_CRYPTO_CMN_MSG_TYPE_SETUP_ENG, /**< Initialize engine. */ + NSS_CRYPTO_CMN_MSG_TYPE_SETUP_DMA, /**< Initialize DMA pair. */ + NSS_CRYPTO_CMN_MSG_TYPE_SETUP_CTX, /**< Update context information. */ + NSS_CRYPTO_CMN_MSG_TYPE_CLEAR_CTX, /**< Clear context information. */ + NSS_CRYPTO_CMN_MSG_TYPE_VERIFY_CTX, /**< Verify if context is active. */ + NSS_CRYPTO_CMN_MSG_TYPE_SYNC_NODE_STATS, /**< Synchronous node statistics. */ + NSS_CRYPTO_CMN_MSG_TYPE_SYNC_ENG_STATS, /**< Synchronous engine statistics. */ + NSS_CRYPTO_CMN_MSG_TYPE_SYNC_CTX_STATS, /**< Synchronous context statistics. */ + NSS_CRYPTO_CMN_MSG_TYPE_MAX +}; + +/** + * nss_crypto_cmn_msg_error + * Message error types supported. + */ +enum nss_crypto_cmn_msg_error { + NSS_CRYPTO_CMN_MSG_ERROR_NONE = 0, + NSS_CRYPTO_CMN_MSG_ERROR_HDR_VERSION_NOSUPP, /**< Common header version not supported. */ + NSS_CRYPTO_CMN_MSG_ERROR_NODE_CTX_RANGE, /**< Context index out-of-range for node. */ + NSS_CRYPTO_CMN_MSG_ERROR_DMA_MASK, /**< DMA mask is out-of-range. */ + NSS_CRYPTO_CMN_MSG_ERROR_DMA_POW2, /**< DMA count is not a power-of-two. */ + NSS_CRYPTO_CMN_MSG_ERROR_DMA_MAX_TOKEN, /**< DMA count exceeds token count. */ + NSS_CRYPTO_CMN_MSG_ERROR_DMA_TOKEN_ALLOC, /**< Failed to allocate token. */ + NSS_CRYPTO_CMN_MSG_ERROR_CTX_RANGE, /**< Context index out-of-range. */ + NSS_CRYPTO_CMN_MSG_ERROR_CTX_INUSE, /**< Context has references. */ + NSS_CRYPTO_CMN_MSG_ERROR_CTX_WORDS, /**< Context size is bad. */ + NSS_CRYPTO_CMN_MSG_ERROR_CTX_ALGO, /**< Context algorithm is bad. */ + NSS_CRYPTO_CMN_MSG_ERROR_CTX_ALLOC, /**< Context alloc failed. */ + NSS_CRYPTO_CMN_MSG_ERROR_CTX_NOUSE, /**< Context has no references. */ + NSS_CRYPTO_CMN_MSG_ERROR_CTX_FLAGS, /**< Invalid context flags. */ + NSS_CRYPTO_CMN_MSG_ERROR_MAX +}; + +/** + * nss_crypto_cmn_ctx_flags + * Context message specific flags. + */ +enum nss_crypto_cmn_ctx_flags { + NSS_CRYPTO_CMN_CTX_FLAGS_NONE = 0, /**< Invalid flags. */ + NSS_CRYPTO_CMN_CTX_FLAGS_SEC_OFFSET = 0x01, /**< Secure offset is valid. */ + NSS_CRYPTO_CMN_CTX_FLAGS_SPARE0 = 0x02, /**< Spare word-0 valid. */ + NSS_CRYPTO_CMN_CTX_FLAGS_SPARE1 = 0x04, /**< Spare word-1 valid. */ + NSS_CRYPTO_CMN_CTX_FLAGS_SPARE2 = 0x08, /**< Spare word-2 valid. */ + NSS_CRYPTO_CMN_CTX_FLAGS_SPARE3 = 0x10, /**< Spare word-3 valid. */ + NSS_CRYPTO_CMN_CTX_FLAGS_MAX +}; + +/** + * nss_crypto_cmn_node + * Node message for setting up the crypto node. + * + * Note: Upon boot this is the first message sent by Host to NSS crypto. + * - It notifies the maximum number of crypto context. + * - It notifies the maximum number of DMA rings. + * - It returns the maximum size of crypto context record. + */ +struct nss_crypto_cmn_node { + uint32_t max_dma_rings; /**< Maximum DMA rings supported. */ + uint32_t max_ctx; /**< Maximum contexts. */ + uint32_t max_ctx_size; /**< Maximum context size. */ +}; + +/** + * nss_crypto_cmn_engine + * Engine message for setting up the instance of crypto engine. + * + * Note: This is sent after 'node' message for each engine to + * - Get valid DMA pairs supported by firmware. + * - Get maximum request/token count available in firmware. + */ +struct nss_crypto_cmn_engine { + uint32_t fw_ver[NSS_CRYPTO_CMN_VER_WORDS]; /**< Firmware version. */ + uint32_t dma_mask; /**< Max DMA rings. */ + uint32_t req_count; /**< Token count. */ +}; + +/** + * nss_crypto_cmn_dma + * DMA message for setting up each DMA pair per engine. + */ +struct nss_crypto_cmn_dma { + uint16_t pair_id; /**< DMA pair ID. */ +}; + +/** + * nss_crypto_cmn_ctx + * Context message for setting up a crypto context in firmware. + */ +struct nss_crypto_cmn_ctx { + uint32_t spare[NSS_CRYPTO_CMN_CTX_SPARE]; /**< Context spare words. */ + uint16_t index; /**< Crypto index. */ + uint16_t sec_offset; /**< Secure offset for copying keys. */ + + uint8_t cipher_key[NSS_CRYPTO_CIPHER_KEYLEN_MAX]; /**< Array containing cipher keys. */ + uint8_t auth_key[NSS_CRYPTO_AUTH_KEYLEN_MAX]; /**< Array containing authorization keys. */ + uint8_t nonce[NSS_CRYPTO_NONCE_SIZE_MAX]; /**< Nonce value. */ + + uint16_t auth_keylen; /**< Authorization key length. */ + uint8_t res[2]; /**< Reserved. */ + + enum nss_crypto_cmn_algo algo; /**< Crypto algorithm. */ + enum nss_crypto_cmn_ctx_flags flags; /**< Context specific flags. */ +}; + +/** + * nss_crypto_cmn_stats + * Statistics message applicable for node/engine/context. + */ +struct nss_crypto_cmn_stats { + struct nss_cmn_node_stats nstats; /**< Common node statistics. */ + uint32_t fail_version; /**< Version mismatch failures. */ + uint32_t fail_ctx; /**< Context related failures. */ + uint32_t fail_dma; /**< DMA descriptor full. */ +}; + +/** + * nss_crypto_cmn_msg + * Crypto common configuration message. + */ +struct nss_crypto_cmn_msg { + struct nss_cmn_msg cm; /**< Common header. */ + uint32_t seq_num; /**< Sequence number for messages. */ + uint32_t uid; /**< Unique ID to identify engine and context. */ + + union { + struct nss_crypto_cmn_node node; /**< Node message. */ + struct nss_crypto_cmn_engine eng; /**< Engine message. */ + struct nss_crypto_cmn_dma dma; /**< DMA message. */ + struct nss_crypto_cmn_ctx ctx; /**< Context message. */ + struct nss_crypto_cmn_stats stats; /**< Statistics message. */ + } msg; +}; + +#ifdef __KERNEL__ /* only kernel will use */ + +/** + * Callback function for receiving crypto transformation upon completion. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Networking device registered for callback. + * @param[in] skb Packet buffer. + * @param[in] napi NAPI pointer for Linux NAPI handling. + * + * @return + * None. + */ +typedef void (*nss_crypto_cmn_buf_callback_t)(struct net_device *netdev, struct sk_buff *skb, + struct napi_struct *napi); + +/** + * Callback function for receiving crypto_cmn messages. + * + * @datatypes + * nss_crypto_cmn_msg + * + * @param[in] app_data Context of the callback user. + * @param[in] msg Crypto common message. + * + * @return + * None. + */ +typedef void (*nss_crypto_cmn_msg_callback_t)(void *app_data, struct nss_crypto_cmn_msg *msg); + +/** + * nss_crypto_cmn_tx_buf + * Send crypto payload to firmware for transformation. + * + * @datatypes + * nss_ctx_instance \n + * sk_buff + * + * @param[in] nss_ctx NSS context per NSS core. + * @param[in] if_num Crypto interface to send the buffer. + * @param[in] skb Crypto payload. + * + * @return + * Status of the TX operation. + */ +extern nss_tx_status_t nss_crypto_cmn_tx_buf(struct nss_ctx_instance *nss_ctx, uint32_t if_num, struct sk_buff *skb); + +/** + * nss_crypto_cmn_tx_msg + * Send crypto message to firmware for configuration. + * + * @datatypes + * nss_ctx_instance \n + * nss_crypto_cmn_msg + * + * @param[in] nss_ctx] NSS context per NSS core. + * @param[in] msg Control message. + * + * @return + * Status of the TX operation. + */ +extern nss_tx_status_t nss_crypto_cmn_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_crypto_cmn_msg *msg); + +/** + * nss_crypto_cmn_tx_msg + * Send crypto message to firmware for configuration synchronously. + * + * @datatypes + * nss_ctx_instance \n + * nss_crypto_cmn_msg + * + * @param[in] nss_ctx NSS context per NSS core. + * @param[in,out] msg Crypto message, response data is copied. + * + * @return + * Status of the TX operation. + * + * @note + * Response data for the message is copied into the 'msg'. + * The caller should read the content of the 'msg' to find out errors. + * The caller needs to invoke this from a non-atomic context. + */ +extern nss_tx_status_t nss_crypto_cmn_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_crypto_cmn_msg *msg); + +/** + * nss_crypto_cmn_notify_register + * Register a event callback handler with NSS driver + * + * @datatypes + * nss_crypto_cmn_msg_callback_t + * + * @param[in] cb Event callback function. + * @param[in] app_data Context of the callback user. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_crypto_cmn_notify_register(nss_crypto_cmn_msg_callback_t cb, void *app_data); + +/** + * nss_crypto_cmn_notify_unregister + * De-register the event callback handler with NSS driver. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] ctx Pointer to the NSS context per NSS core. + * + * @return + * None. + */ +extern void nss_crypto_cmn_notify_unregister(struct nss_ctx_instance *ctx); + +/** + * nss_crypto_cmn_data_register + * Crypto data register. + * + * @datatypes + * nss_crypto_cmn_buf_callback_t \n + * net_device + * + * @param[in] if_num Interface number. + * @param[in] cb Callback function. + * @param[in] netdev Net device. + * @param[in] features Features supported. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_crypto_cmn_data_register(uint32_t if_num, + nss_crypto_cmn_buf_callback_t cb, + struct net_device *netdev, + uint32_t features); + +/** + * nss_crypto_cmn_data_unregister + * Crypto data de-register. + * + * @param[in] ctx NSS context per NSS core. + * @param[in] if_num Interface number. + * + * @return + * None. + */ +extern void nss_crypto_cmn_data_unregister(struct nss_ctx_instance *ctx, uint32_t if_num); + +/** + * nss_crypto_cmn_get_context + * Get the per NSS core context enabled for crypto. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_crypto_cmn_get_context(void); + +/** + * nss_crypto_cmn_msg_init + * Crypto common message initialization. + * + * @datatypes + * nss_crypto_cmn_msg \n + * nss_crypto_cmn_msg_callback_t + * + * @param[in] ncm Crypto common message. + * @param[in] if_num Interface number. + * @param[in] type Message type. + * @param[in] len Common message length. + * @param[in] cb Callback function. + * @param[in] app_data Appllication data. + * + * @return + * None. + */ +extern void nss_crypto_cmn_msg_init(struct nss_crypto_cmn_msg *ncm, uint16_t if_num, + uint32_t type, uint32_t len, nss_crypto_cmn_msg_callback_t cb, + void *app_data); + +#endif /*__KERNEL__ */ + +/** + * @} + */ +#endif diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_def.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_def.h new file mode 100644 index 000000000..9bfab7909 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_def.h @@ -0,0 +1,57 @@ +/* + ************************************************************************** + * Copyright (c) 2015, 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_def.h + * NSS definitions + */ + +#ifndef __NSS_DEF_H +#define __NSS_DEF_H + +/** + * @addtogroup nss_common_subsystem + * @{ + */ + +#define NSS_ETH_NORMAL_FRAME_MTU 1500 /**< MTU of a normal frame.*/ +#define NSS_ETH_MINI_JUMBO_FRAME_MTU 1978 /**< MTU of a mini-jumbo frame. */ +#define NSS_ETH_FULL_JUMBO_FRAME_MTU 9600 /**< MTU of a full jumbo frame. */ + +/** + * Number of ingress or egress VLANS supported in a connection entry. + */ +#define MAX_VLAN_DEPTH 2 + +/** + * Number of egress interfaces supported in a multicast connection entry. + */ +#define NSS_MC_IF_MAX 16 + +/** + * Real pointer size of the system. + */ +#ifdef __LP64__ +typedef uint64_t nss_ptr_t; +#else +typedef uint32_t nss_ptr_t; +#endif + +/** + * @} + */ + +#endif /** __NSS_DEF_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_dma.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_dma.h new file mode 100755 index 000000000..ca27d3a69 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_dma.h @@ -0,0 +1,264 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ +/** + * @file nss_dma.h + * NSS DMA for linearization and split interface definitions. + */ + +#ifndef __NSS_DMA_H +#define __NSS_DMA_H + +/** + * @addtogroup nss_dma_subsystem + * @{ + */ + +/** + * nss_dma_msg_type + * Supported message types. + */ +enum nss_dma_msg_type { + NSS_DMA_MSG_TYPE_NONE, /**< Invalid message type. */ + NSS_DMA_MSG_TYPE_CONFIGURE, /**< Configure DMA. */ + NSS_DMA_MSG_TYPE_SYNC_STATS, /**< Statistics synchronization. */ + NSS_DMA_MSG_TYPE_TEST_PERF, /**< Performance test. */ + NSS_DMA_MSG_TYPE_MAX /**< Maximum message type. */ +}; + +/** + * nss_dma_msg_error + * Message error types. + */ +enum nss_dma_msg_error { + NSS_DMA_MSG_ERROR_NONE, /**< No error. */ + NSS_DMA_MSG_ERROR_HW_INIT, /**< Invalid operation. */ + NSS_DMA_MSG_ERROR_UNHANDLED, /**< Invalid test ID. */ + NSS_DMA_MSG_ERROR_TEST, /**< Performance test failed. */ + NSS_DMA_MSG_ERROR_MAX /**< Maximum error type. */ +}; + +/** + * nss_dma_test_type + * DMA Test types. + */ +enum nss_dma_test_type { + NSS_DMA_TEST_TYPE_DEFAULT = 0, /**< Test default segment size. */ + NSS_DMA_TEST_TYPE_SWEEP, /**< Test sweep segment size. */ + NSS_DMA_TEST_TYPE_LARGE, /**< Test large segment size. */ + NSS_DMA_TEST_TYPE_VERIFY, /**< Verify contents at receive processing. */ + NSS_DMA_TEST_TYPE_MAX /**< Maximum test type. */ +}; + +#ifdef __KERNEL__ /* only kernel will use. */ +/* + * Maximum number of HW specific statistics + */ +#define NSS_DMA_HW_ERROR_MAX 16 + +/* + * Test configuration flags + */ +#define NSS_DMA_TEST_FLAGS_LINEARIZE 0x01 /**< Linearize test. */ +#define NSS_DMA_TEST_FLAGS_SPLIT 0x02 /**< Split test. */ + +/** + * nss_dma_test_cfg + * Test configuration. + */ +struct nss_dma_test_cfg { + struct nss_cmn_node_stats node_stats; /**< Common node statistics for DMA interface. */ + uint32_t flags; /**< Test configuration flags. */ + uint32_t time_delta; /**< Difference between start and end. */ + uint16_t packet_count; /**< Number of packets to send. */ + uint16_t type; /**< Type of test to run. */ +}; + +/** + * nss_dma_stats + * DMA statistics. + */ +struct nss_dma_stats { + struct nss_cmn_node_stats node_stats; /**< Common node statistics for DMA interface. */ + uint32_t no_req; /**< Request descriptor not available. */ + uint32_t no_desc; /**< DMA descriptors not available. */ + uint32_t fail_nexthop; /**< Failed to retrive next hop. */ + uint32_t fail_nexthop_queue; /**< Failed to queue next hop. */ + uint32_t fail_linear_sz; /**< Failed to get memory for linearization. */ + uint32_t fail_linear_alloc; /**< Failed to allocate buffer for linearization. */ + uint32_t fail_linear_no_sg; /**< Skip linearization due to non-SG packet. */ + uint32_t fail_split_sz; /**< Failed to spliting buffer into multiple buffers. */ + uint32_t fail_split_alloc; /**< Failed to allocate buffer for split. */ + uint32_t fail_sync_alloc; /**< Failed to allocate buffer for sending statistics. */ + uint32_t fail_ctx_active; /**< Failed to queue as the node is not active. */ + uint32_t fail_hw[NSS_DMA_HW_ERROR_MAX]; /**< Hardware failures. */ +}; + +/** + * nss_dma_msg + * Message structure for configuring the DMA interface. + */ +struct nss_dma_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a NSS core-to-core transmission rule or statistics message. + */ + union { + struct nss_dma_test_cfg test_cfg; + /**< DMA test configuration. */ + struct nss_dma_stats stats; /**< DMA interface statistics. */ + } msg; /**< Message payload. */ +}; + +/** + * nss_dma_register_handler + * Registers the DMA message handler. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS context. + * + * @return + * None. + */ +void nss_dma_register_handler(void); + +/** + * Callback function for receiving DMA messages. + * + * @datatypes + * nss_c2c_tx_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_dma_msg_callback_t)(void *app_data, struct nss_cmn_msg *msg); + +/** + * nss_dma_tx_msg + * Transmits a DMA message to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_dma_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] ndm Pointer to the message data. + * + * @return + * Status of the transmit operation. + */ +extern nss_tx_status_t nss_dma_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_dma_msg *ndm); + +/** + * nss_dma_msg_init + * Initializes DMA messages. + * + * @datatypes + * nss_dma_msg \n + * nss_dma_msg_callback_t + * + * @param[in] ndm Pointer to the NSS interface message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_dma_msg_init(struct nss_dma_msg *ndm, uint16_t if_num, uint32_t type, uint32_t len, + nss_dma_msg_callback_t cb, void *app_data); + +/** + * nss_dma_notify_register + * Registers a notifier callback for DMA messages with the NSS. + * + * @datatypes + * nss_dma_msg_callback_t + * + * @param[in] core NSS core number index to the notifier callback table. + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * Pointer to the NSS core context. + */ +struct nss_ctx_instance *nss_dma_notify_register(int core, nss_dma_msg_callback_t cb, void *app_data); + +/** + * nss_dma_notify_unregister + * Deregisters a DMA message notifier callback from the NSS. + * + * @param[in] core NSS core number index to the notifier callback table. + * + * @return + * None. + * + * @dependencies + * The notifier callback must have been previously registered. + */ +void nss_dma_notify_unregister(int core); + +/** + * nss_dma_register_sysctl + * Registers the DMA interface to Linux system control tree. + * + * @return + * None. + */ +extern void nss_dma_register_sysctl(void); + +/** + * nss_dma_unregister_sysctl + * Deregisters the DMA interface from Linux system control tree. + * + * @return + * None. + * + * @dependencies + * The system control must have been previously registered. + */ +extern void nss_dma_unregister_sysctl(void); + +/** + * nss_dma_init + * Initializes the DMA interface. + * + * @return + * None. + */ +void nss_dma_init(void); + +/** + * nss_dma_get_context + * Get the per NSS core context enabled for DMA. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_dma_get_context(void); +#endif /*__KERNEL__ */ + +/** + * @} + */ + +#endif /* __NSS_C2C_TX_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_dtls.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_dtls.h new file mode 100644 index 000000000..d237bfda2 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_dtls.h @@ -0,0 +1,335 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_dtls.h + * NSS DTLS interface definitions. + */ + +#ifndef _NSS_DTLS_H_ +#define _NSS_DTLS_H_ + +/** + * @addtogroup nss_dtls_subsystem + * @{ + */ + +#define NSS_MAX_DTLS_SESSIONS 8 /**< Maximum number of supported DTLS sessions. */ + +/** + * nss_dtls_metadata_types + * Message types for DTLS requests and responses. + */ +enum nss_dtls_metadata_types { + NSS_DTLS_MSG_SESSION_CONFIGURE, + NSS_DTLS_MSG_SESSION_DESTROY, + NSS_DTLS_MSG_SESSION_STATS, + NSS_DTLS_MSG_REKEY_ENCAP_CIPHER_UPDATE, + NSS_DTLS_MSG_REKEY_ENCAP_CIPHER_SWITCH, + NSS_DTLS_MSG_REKEY_DECAP_CIPHER_UPDATE, + NSS_DTLS_MSG_REKEY_DECAP_CIPHER_SWITCH, + NSS_DTLS_MSG_MAX +}; + +/** + * nss_dtls_error_response_types + * Error types for DTLS responses. + */ +enum nss_dtls_error_response_types { + NSS_DTLS_ERR_UNKNOWN_MSG = 1, + NSS_DTLS_ERR_INVALID_APP_IF = 2, + NSS_DTLS_ERR_INVALID_CPARAM = 3, + NSS_DTLS_ERR_INVALID_VER = 4, + NSS_DTLS_ERR_NOMEM = 5, + NSS_DTLS_ERR_MAX, +}; + +/** + * nss_dtls_session_stats + * DTLS session statistics. + */ +struct nss_dtls_session_stats { + struct nss_cmn_node_stats node_stats; /**< Common node statistics. */ + uint32_t tx_auth_done; /**< Tx authentication is done. */ + uint32_t rx_auth_done; /**< Rx authentication is successful. */ + uint32_t tx_cipher_done; /**< Tx cipher is complete. */ + uint32_t rx_cipher_done; /**< Rx cipher is complete. */ + uint32_t tx_cbuf_alloc_fail; /**< Tx crypto buffer allocation failure. */ + uint32_t rx_cbuf_alloc_fail; /**< Rx crypto buffer allocation failure. */ + uint32_t tx_cenqueue_fail; /**< Tx enqueue-to-crypto failure. */ + uint32_t rx_cenqueue_fail; /**< Rx enqueue-to-crypto failure. */ + uint32_t tx_dropped_hroom; + /**< Tx packets dropped because of insufficent headroom. */ + uint32_t tx_dropped_troom; + /**< Tx packets dropped because of insufficent tailroom. */ + uint32_t tx_forward_enqueue_fail; + /**< Tx enqueue failed to forward a node after encapsulation. */ + uint32_t rx_forward_enqueue_fail; + /**< Rx enqueue failed to receive a node after decapsulation. */ + uint32_t rx_invalid_version; /**< Rx invalid DTLS version. */ + uint32_t rx_invalid_epoch; /**< Rx invalid DTLS epoch. */ + uint32_t rx_malformed; /**< Rx malformed DTLS record. */ + uint32_t rx_cipher_fail; /**< Rx cipher failure. */ + uint32_t rx_auth_fail; /**< Rx authentication failure. */ + uint32_t rx_capwap_classify_fail; /**< Rx CAPWAP classification failure. */ + uint32_t rx_single_rec_dgram; /**< Rx single record datagrams processed. */ + uint32_t rx_multi_rec_dgram; /**< Rx multi-record datagrams processed. */ + uint32_t rx_replay_fail; /**< Rx anti-replay failures. */ + uint32_t rx_replay_duplicate; + /**< Rx anti-replay failed because of a duplicate record. */ + uint32_t rx_replay_out_of_window; + /**< Rx anti-replay failed because of an out-of-window record. */ + uint32_t outflow_queue_full; + /**< Tx packets dropped because the encapsulation queue is full. */ + uint32_t decap_queue_full; + /**< Rx packets dropped because the decapsulation queue is full. */ + uint32_t pbuf_alloc_fail; + /**< Packets dropped because of a buffer allocation failure. */ + uint32_t pbuf_copy_fail; + /**< Packets dropped because of a buffer copy failure. */ + uint16_t epoch; /**< Current epoch. */ + uint16_t tx_seq_high; /**< Upper 16 bits of the current sequence number. */ + uint32_t tx_seq_low; /**< Lower 32 bits of the current sequence number. */ +}; + +/** + * nss_dtls_session_cipher_update + * Information for a cipher update message in a DTLS session. + */ +struct nss_dtls_session_cipher_update { + uint32_t crypto_idx; /**< Crypto index for encapsulation. */ + uint32_t hash_len; /**< Authentication hash length for encapsulation. */ + uint32_t iv_len; /**< Crypto IV length for encapsulation. */ + uint32_t cipher_algo; /**< Encapsulation cipher. */ + uint32_t auth_algo; /**< Encapsulation authentication algorithm. */ + uint16_t epoch; /**< Epoch indicator. */ + uint16_t reserved; /**< Reserved for message alignment.*/ +}; + +/** + * nss_dtls_session_configure + * Configuration message for a DTLS session. + */ +struct nss_dtls_session_configure { + uint32_t ver; /**< DTLS version. */ + uint32_t flags; /**< DTLS flags. */ + uint32_t crypto_idx_encap; /**< Crypto index for encapsulation. */ + uint32_t crypto_idx_decap; /**< Crypto index for decapsulation. */ + uint32_t iv_len_encap; /**< Crypto IV length for encapsulation. */ + uint32_t iv_len_decap; /**< Crypto IV length for decapsulation. */ + uint32_t hash_len_encap; + /**< Authentication hash length for encapsulation. */ + uint32_t hash_len_decap; + /**< Authentication hash length for decapsulation. */ + uint32_t cipher_algo_encap; /**< Cipher algorithm for encapsulation. */ + uint32_t auth_algo_encap; /**< Authentication algorithm encapsulation. */ + uint32_t cipher_algo_decap; /**< Cipher algorithm for decapsulation. */ + uint32_t auth_algo_decap; /**< Authentication algorithm decapsulation. */ + uint32_t nss_app_if; + /**< Interface of the node that receives decapsulated packets. */ + uint16_t sport; /**< Source UDP/UDPLite port. */ + uint16_t dport; /**< Destination UDP/UDPLite port. */ + uint32_t sip[4]; /**< Source IPv4/IPv6 address. */ + uint32_t dip[4]; /**< Destination IPv4/IPv6 address. */ + uint16_t window_size; /**< Anti-replay window size. */ + uint16_t epoch; /**< Epoch indicator. */ + uint8_t oip_ttl; /**< Maximum outer IP time-to-live value. */ + uint8_t reserved1; /**< Reserved for message alignment. */ + uint16_t reserved2; /**< Reserved for message alignment. */ +}; + +/** + * nss_dtls_msg + * Data for sending and receiving DTLS messages. + */ +struct nss_dtls_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a DTLS message. + */ + union { + struct nss_dtls_session_configure cfg; + /**< Session configuration. */ + struct nss_dtls_session_cipher_update cipher_update; + /**< Cipher update information. */ + struct nss_dtls_session_stats stats; + /**< Session statistics. */ + } msg; /**< Message payload for DTLS session messages exchanged with NSS core. */ +}; + +/** + * nss_dtls_tx_buf + * Sends a DTLS data packet to the NSS. + * + * @datatypes + * sk_buff \n + * nss_ctx_instance + * + * @param[in] os_buf Pointer to the OS data buffer. + * @param[in] if_num NSS interface number. + * @param[in] nss_ctx Pointer to the NSS core context. + * + * @return + * Status of Tx buffer forwarded to NSS for DTLS operation. + */ +nss_tx_status_t nss_dtls_tx_buf(struct sk_buff *os_buf, uint32_t if_num, + struct nss_ctx_instance *nss_ctx); + +/** + * nss_dtls_tx_msg + * Sends DTLS messages. + * + * @param[in] nss_ctx Pointer to the NSS core context. + * @param[in,out] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_dtls_tx_msg(struct nss_ctx_instance *nss_ctx, + struct nss_dtls_msg *msg); + +/** + * nss_dtls_tx_msg_sync + * Sends DTLS messages synchronously. + * + * @datatypes + * nss_ctx_instance \n + * nss_dtls_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in,out] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_dtls_tx_msg_sync(struct nss_ctx_instance *nss_ctx, + struct nss_dtls_msg *msg); + +/** + * Callback function for receiving DTLS messages. + * + * @datatypes + * nss_dtls_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_dtls_msg_callback_t)(void *app_data, + struct nss_dtls_msg *msg); + +/** + * Callback function for receiving DTLS session data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_dtls_data_callback_t)(struct net_device *netdev, + struct sk_buff *skb, + struct napi_struct *napi); + +/** + * nss_dtls_register_if + * Registers a DTLS session interface with the NSS for sending and receiving + * messages. + * + * @datatypes + * nss_dtls_data_callback_t \n + * nss_dtls_msg_callback_t + * + * @param[in] if_num NSS interface number. + * @param[in] cb Callback function for the message. + * @param[in] msg_callback Callback for DTLS tunnel message. + * @param[in] netdev Pointer to the associated network device. + * @param[in] features Data socket buffer types supported by this interface. + * @param[in] app_ctx Pointer to the application context. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_dtls_register_if(uint32_t if_num, + nss_dtls_data_callback_t cb, + nss_dtls_msg_callback_t msg_callback, + struct net_device *netdev, + uint32_t features, + void *app_ctx); + +/** + * nss_dtls_unregister_if + * Deregisters a DTLS session interface from the NSS. + * + * @param[in] if_num NSS interface number. + * + * @return + * None. + * + * @dependencies + * The DTLS session interface must have been previously registered. + */ +extern void nss_dtls_unregister_if(uint32_t if_num); + +/** + * nss_dtls_msg_init + * Initializes a DTLS message. + * + * @datatypes + * nss_dtls_msg + * + * @param[in,out] ncm Pointer to the message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Pointer to the message callback. + * @param[in] app_data Pointer to the application context. + * + * @return + * None. + */ +extern void nss_dtls_msg_init(struct nss_dtls_msg *ncm, uint16_t if_num, + uint32_t type, uint32_t len, void *cb, + void *app_data); + +/** + * nss_dtls_get_context + * Gets the NSS core context for the DTLS session. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_dtls_get_context(void); + +/** + * nss_dtls_get_ifnum_with_coreid + * Gets the DTLS interface number with a core ID. + * + * @param[in] if_num NSS interface number. + * + * @return + * Interface number with the core ID. + */ +extern int32_t nss_dtls_get_ifnum_with_coreid(int32_t if_num); + +/** + * @} + */ + +#endif /* _NSS_DTLS_H_. */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_dtls_cmn.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_dtls_cmn.h new file mode 100644 index 000000000..f4b2bda4b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_dtls_cmn.h @@ -0,0 +1,395 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_dtls_cmn.h + * NSS DTLS common interface definitions, supports inner/outer interface split. + */ + +#ifndef _NSS_DTLS_CMN_H_ +#define _NSS_DTLS_CMN_H_ + +/** + * @addtogroup nss_dtls_subsystem + * @{ + */ + +#define NSS_DTLS_CMN_CTX_HDR_IPV6 0x0001 /**< DTLS with IPv6. */ +#define NSS_DTLS_CMN_CTX_HDR_UDPLITE 0x0002 /**< DTLS with UDPLite. */ +#define NSS_DTLS_CMN_CTX_HDR_CAPWAP 0x0004 /**< DTLS with CAPWAP. */ +#define NSS_DTLS_CMN_CTX_CIPHER_MODE_GCM 0x0008 /**< DTLS with GCM cipher mode. */ +#define NSS_DTLS_CMN_CTX_ENCAP_UDPLITE_CSUM 0x10000 /**< Checksum only UDPLite header. */ +#define NSS_DTLS_CMN_CTX_ENCAP_METADATA 0x20000 /**< Valid metadata in encapsulation direction. */ +#define NSS_DTLS_CMN_CTX_DECAP_ACCEPT_ALL 0x40000 /**< Exception all error packets to host. */ + +#define NSS_DTLS_CMN_CLE_MAX 32 /**< Max classification error. */ + +/** + * nss_dtls_cmn_metadata_types + * Message types for DTLS requests and responses. + */ +enum nss_dtls_cmn_msg_type { + NSS_DTLS_CMN_MSG_TYPE_CONFIGURE_NODE, /**< Configure DTLS firmware node. */ + NSS_DTLS_CMN_MSG_TYPE_CONFIGURE_HDR, /**< Configure the base context parameter. */ + NSS_DTLS_CMN_MSG_TYPE_CONFIGURE_DTLS, /**< Configure DTLS parameters. */ + NSS_DTLS_CMN_MSG_TYPE_SWITCH_DTLS, /**< Switch to new DTLS transform. */ + NSS_DTLS_CMN_MSG_TYPE_DECONFIGURE, /**< Deconfigure context. */ + NSS_DTLS_CMN_MSG_TYPE_SYNC_STATS, /**< Synchronize statistics. */ + NSS_DTLS_CMN_MSG_TYPE_NODE_STATS, /**< Node statistics. */ + NSS_DTLS_CMN_MSG_MAX +}; + +/** + * nss_dtls_cmn_error_response_types + * Error types for DTLS responses. + */ +enum nss_dtls_cmn_error { + NSS_DTLS_CMN_ERROR_NONE = 0, + NSS_DTLS_CMN_ERROR_UNKNOWN_MSG, + NSS_DTLS_CMN_ERROR_INVALID_DESTIF, + NSS_DTLS_CMN_ERROR_INVALID_SRCIF, + NSS_DTLS_CMN_ERROR_INVALID_CRYPTO, + NSS_DTLS_CMN_ERROR_INVALID_VER, + NSS_DTLS_CMN_ERROR_INVALID_CTX_TYPE, + NSS_DTLS_CMN_ERROR_INVALID_CTX_WORDS, + NSS_DTLS_CMN_ERROR_FAIL_ALLOC_HWCTX, + NSS_DTLS_CMN_ERROR_FAIL_COPY_CTX, + NSS_DTLS_CMN_ERROR_FAIL_SWITCH_HWCTX, + NSS_DTLS_CMN_ERROR_ALREADY_CONFIGURED, + NSS_DTLS_CMN_ERROR_FAIL_NOMEM, + NSS_DTLS_CMN_ERROR_FAIL_COPY_NONCE, + NSS_DTLS_CMN_ERROR_MAX, +}; + +/** + * nss_dtls_cmn_node_stats + * DTLS node statistics. + */ +struct nss_dtls_cmn_node_stats { + uint32_t fail_ctx_alloc; /**< Failure in allocating a context. */ + uint32_t fail_ctx_free; /**< Failure in freeing up the context. */ + uint32_t fail_pbuf_stats; /**< Failure in pbuf allocation for statistics. */ +}; + +/** + * nss_dtls_cmn_hw_stats + * DTLS hardware statistics. + */ +struct nss_dtls_cmn_hw_stats { + uint32_t len_error; /**< Length error. */ + uint32_t token_error; /**< Token error, unknown token command/instruction. */ + uint32_t bypass_error; /**< Token contains too much bypass data. */ + uint32_t config_error; /**< Invalid command/algorithm/mode/combination. */ + uint32_t algo_error; /**< Unsupported algorithm. */ + uint32_t hash_ovf_error; /**< Hash input overflow. */ + uint32_t ttl_error; /**< TTL or HOP-Limit underflow. */ + uint32_t csum_error; /**< Checksum error. */ + uint32_t timeout_error; /**< Data timed-out. */ +}; + +/** + * nss_dtls_cmn_ctx_stats + * DTLS session statistics. + */ +struct nss_dtls_cmn_ctx_stats { + struct nss_cmn_node_stats pkt; /**< Common node statistics. */ + uint32_t rx_single_rec; /**< Received single DTLS record datagrams. */ + uint32_t rx_multi_rec; /**< Received multiple DTLS record datagrams. */ + uint32_t fail_crypto_resource; /**< Failure in allocation of crypto resource. */ + uint32_t fail_crypto_enqueue; /**< Failure due to queue full in crypto or hardware. */ + uint32_t fail_headroom; /**< Failure in headroom check. */ + uint32_t fail_tailroom; /**< Failure in tailroom check. */ + uint32_t fail_ver; /**< Failure in DTLS version check. */ + uint32_t fail_epoch; /**< Failure in DTLS epoch check. */ + uint32_t fail_dtls_record; /**< Failure in reading DTLS record. */ + uint32_t fail_capwap; /**< Failure in CAPWAP classification. */ + uint32_t fail_replay; /**< Failure in anti-replay check. */ + uint32_t fail_replay_dup; /**< Failure in anti-replay; duplicate records. */ + uint32_t fail_replay_win; /**< Failure in anti-replay; packet outside the window. */ + uint32_t fail_queue; /**< Failure due to queue full in DTLS. */ + uint32_t fail_queue_nexthop; /**< Failure due to queue full in next_hop. */ + uint32_t fail_pbuf_alloc; /**< Failure in pbuf allocation. */ + uint32_t fail_pbuf_linear; /**< Failure in pbuf linearization. */ + uint32_t fail_pbuf_stats; /**< Failure in pbuf allocation for statistics. */ + uint32_t fail_pbuf_align; /**< Failure in pbuf alignment. */ + uint32_t fail_ctx_active; /**< Failure in enqueue due to inactive context. */ + uint32_t fail_hwctx_active; /**< Failure in enqueue due to inactive hardware context. */ + uint32_t fail_cipher; /**< Failure in decrypting the data. */ + uint32_t fail_auth; /**< Failure in authenticating the data. */ + uint32_t fail_seq_ovf; /**< Failure due to sequence number overflow. */ + uint32_t fail_blk_len; /**< Failure in decapsulation due to bad cipher block length. */ + uint32_t fail_hash_len; /**< Failure in decapsulation due to bad hash block length. */ + + struct nss_dtls_cmn_hw_stats fail_hw; /**< Hardware failure statistics. */ + + uint32_t fail_cle[NSS_DTLS_CMN_CLE_MAX];/**< Classification errors. */ + + uint32_t seq_low; /**< Lower 32 bits of current Tx sequence number. */ + uint32_t seq_high; /**< Upper 16 bits of current Tx sequence number. */ + + uint16_t epoch; /**< Current epoch value. */ + uint8_t res1[2]; /**< Reserved for future use. */ + + uint8_t res2[16]; /**< Reserved for future use. */ +}; + +/** + * nss_dtls_cmn_ctx_config_hdr + * Parameters for outer header transform. + */ +struct nss_dtls_cmn_ctx_config_hdr { + uint32_t flags; /**< Context flags. */ + uint32_t dest_ifnum; /**< Destination interface for packets. */ + uint32_t src_ifnum; /**< Source interface of packets. */ + uint32_t sip[4]; /**< Source IPv4/v6 address. */ + uint32_t dip[4]; /**< Destination IPv4/v6 address. */ + + uint16_t sport; /**< Source UDP/UDPLite port. */ + uint16_t dport; /**< Destination UDP/UDPLite port. */ + + uint8_t hop_limit_ttl; /**< IP header TTL field. */ + uint8_t dscp; /**< DSCP value. */ + uint8_t dscp_copy; /**< Copy DSCP value. */ + uint8_t df; /**< Do not fragment DTLS over IPv4. */ +}; + +/** + * nss_dtls_cmn_ctx_config_dtls + * Parameters for DTLS transform. + */ +struct nss_dtls_cmn_ctx_config_dtls { + uint32_t ver; /**< Version (enum dtls_cmn_ver). */ + uint32_t crypto_idx; /**< Crypto index for cipher context. */ + + uint16_t window_size; /**< Anti-replay window size. */ + uint16_t epoch; /**< Initial epoch value. */ + + uint8_t iv_len; /**< Crypto IV length for encapsulation. */ + uint8_t hash_len; /**< Auth hash length for encapsulation. */ + uint8_t blk_len; /**< Cipher block length. */ + uint8_t res1; /**< Reserved for alignment. */ +}; + +/** + * nss_dtls_cmn_msg + * Data for sending and receiving DTLS messages. + */ +struct nss_dtls_cmn_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a DTLS message. + */ + union { + struct nss_dtls_cmn_ctx_config_hdr hdr_cfg; /**< Session configuration. */ + struct nss_dtls_cmn_ctx_config_dtls dtls_cfg; /**< Cipher update information. */ + struct nss_dtls_cmn_ctx_stats stats; /**< Session statistics. */ + struct nss_dtls_cmn_node_stats node_stats; /**< Node statistics. */ + } msg; /**< Message payload for DTLS session messages exchanged with NSS core. */ +}; + +#ifdef __KERNEL__ /* only for kernel use. */ +/** + * Callback function for receiving DTLS messages. + * + * @datatypes + * nss_dtls_cmn_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_dtls_cmn_msg_callback_t)(void *app_data, struct nss_cmn_msg *msg); + +/** + * Callback function for receiving DTLS session data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_dtls_cmn_data_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * nss_dtls_cmn_tx_buf + * Sends a DTLS data packet to the NSS. + * + * @datatypes + * sk_buff \n + * nss_ctx_instance + * + * @param[in] os_buf Pointer to the OS data buffer. + * @param[in] if_num NSS interface number. + * @param[in] nss_ctx Pointer to the NSS core context. + * + * @return + * Status of Tx buffer forwarded to NSS for DTLS operation. + */ +nss_tx_status_t nss_dtls_cmn_tx_buf(struct sk_buff *os_buf, uint32_t if_num, struct nss_ctx_instance *nss_ctx); + +/** + * nss_dtls_cmn_tx_msg + * Sends DTLS messages. + * + * @param[in] nss_ctx Pointer to the NSS core context. + * @param[in,out] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_dtls_cmn_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_dtls_cmn_msg *msg); + +/** + * nss_dtls_cmn_tx_msg_sync + * Sends DTLS messages synchronously. + * + * @datatypes + * nss_ctx_instance \n + * nss_dtls_cmn_msg_type \n + * nss_dtls_cmn_msg \n + * nss_dtls_cmn_error + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] ndcm Pointer to the message data. + * @param[in,out] resp Response for the configuration. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_dtls_cmn_tx_msg_sync(struct nss_ctx_instance *nss_ctx, uint32_t if_num, + enum nss_dtls_cmn_msg_type type, uint16_t len, + struct nss_dtls_cmn_msg *ndcm, enum nss_dtls_cmn_error *resp); + +/** + * nss_dtls_cmn_register_if + * Registers a DTLS session interface with the NSS for sending and receiving + * messages. + * + * @datatypes + * nss_dtls_cmn_data_callback_t \n + * nss_dtls_cmn_msg_callback_t + * + * @param[in] if_num NSS interface number. + * @param[in] data_cb Callback function for the message. + * @param[in] msg_cb Callback for DTLS tunnel message. + * @param[in] netdev Pointer to the associated network device. + * @param[in] features Data socket buffer types supported by this interface. + * @param[in] type Type of message. + * @param[in] app_ctx Pointer to the application context. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_dtls_cmn_register_if(uint32_t if_num, + nss_dtls_cmn_data_callback_t data_cb, + nss_dtls_cmn_msg_callback_t msg_cb, + struct net_device *netdev, + uint32_t features, + uint32_t type, + void *app_ctx); + +/** + * nss_dtls_cmn_unregister_if + * Deregisters a DTLS session interface from the NSS. + * + * @param[in] if_num NSS interface number. + * + * @return + * None. + * + * @dependencies + * The DTLS session interface must have been previously registered. + */ +extern void nss_dtls_cmn_unregister_if(uint32_t if_num); + +/** + * nss_dtls_cmn_notify_register + * Register an event callback to handle notification from DTLS firmware package. + * + * @param[in] ifnum NSS interface number. + * @param[in] ev_cb Callback for DTLS tunnel message. + * @param[in] app_data Pointer to the application context. + * + * @return + * Pointer to NSS core context. + */ +extern struct nss_ctx_instance *nss_dtls_cmn_notify_register(uint32_t ifnum, nss_dtls_cmn_msg_callback_t ev_cb, + void *app_data); + +/** + * nss_dtls_cmn_notify_unregister + * Unregister an event callback. + * + * @param[in] ifnum NSS interface number. + * + * @return + * None. + */ +extern void nss_dtls_cmn_notify_unregister(uint32_t ifnum); + +/** + * nss_dtls_cmn_msg_init + * Initializes a DTLS message. + * + * @datatypes + * nss_dtls_cmn_msg + * + * @param[in,out] ncm Pointer to the message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Pointer to the message callback. + * @param[in] app_data Pointer to the application context. + * + * @return + * None. + */ +extern void nss_dtls_cmn_msg_init(struct nss_dtls_cmn_msg *ncm, uint32_t if_num, uint32_t type, uint32_t len, void *cb, + void *app_data); + +/** + * nss_dtls_cmn_get_context + * Gets the NSS core context for the DTLS session. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_dtls_cmn_get_context(void); + +/** + * nss_dtls_cmn_get_ifnum + * Gets the DTLS interface number with a core ID. + * + * @param[in] if_num NSS interface number. + * + * @return + * Interface number with the core ID. + */ +extern int32_t nss_dtls_cmn_get_ifnum(int32_t if_num); + +/** + * @} + */ + +#endif /* __KERNEL__ */ +#endif /* _NSS_DTLS_CMN_H_. */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_dynamic_interface.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_dynamic_interface.h new file mode 100644 index 000000000..198bc9101 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_dynamic_interface.h @@ -0,0 +1,338 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * @file nss_dynamic_interface.h + * NSS Dynamic interface definitions. + */ + +#ifndef __NSS_DYNAMIC_INTERFACE_H +#define __NSS_DYNAMIC_INTERFACE_H + +/** + * @addtogroup nss_dynamic_interface_subsystem + * @{ + */ + +#define NSS_MAX_DYNAMIC_INTERFACES 128 /**< Maximum number of dynamic interfaces. */ + +/** + * nss_dynamic_interface_type + * Dynamic interface types. + * + * @note + * Every time a new dynamic interface type is added to an enumeration in the following list, + * a corresponding type name string should be added in the dynamic interface type string array. + */ +enum nss_dynamic_interface_type { + NSS_DYNAMIC_INTERFACE_TYPE_NONE, + NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR, + NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP, + NSS_DYNAMIC_INTERFACE_TYPE_TUNIPIP6_INNER, + NSS_DYNAMIC_INTERFACE_TYPE_TUNIPIP6_OUTER, + NSS_DYNAMIC_INTERFACE_TYPE_WIFI, + NSS_DYNAMIC_INTERFACE_TYPE_VAP, + NSS_DYNAMIC_INTERFACE_TYPE_RESERVED_0, + NSS_DYNAMIC_INTERFACE_TYPE_PPPOE, + NSS_DYNAMIC_INTERFACE_TYPE_VIRTIF_DEPRECATED, + NSS_DYNAMIC_INTERFACE_TYPE_L2TPV2, + NSS_DYNAMIC_INTERFACE_TYPE_RESERVED_4, + NSS_DYNAMIC_INTERFACE_TYPE_PORTID, + NSS_DYNAMIC_INTERFACE_TYPE_DTLS, + NSS_DYNAMIC_INTERFACE_TYPE_QVPN_INNER, + NSS_DYNAMIC_INTERFACE_TYPE_QVPN_OUTER, + NSS_DYNAMIC_INTERFACE_TYPE_BRIDGE, + NSS_DYNAMIC_INTERFACE_TYPE_VLAN, + NSS_DYNAMIC_INTERFACE_TYPE_RESERVED_3, + NSS_DYNAMIC_INTERFACE_TYPE_WIFILI_INTERNAL, + NSS_DYNAMIC_INTERFACE_TYPE_MAP_T_INNER, + NSS_DYNAMIC_INTERFACE_TYPE_MAP_T_OUTER, + NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL_INNER, + NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL_OUTER, + NSS_DYNAMIC_INTERFACE_TYPE_DTLS_CMN_INNER, + NSS_DYNAMIC_INTERFACE_TYPE_DTLS_CMN_OUTER, + NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_WIFI_HOST_INNER, + NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_WIFI_OFFL_INNER, + NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_SJACK_INNER, + NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_OUTER, + NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL_INLINE_INNER, + NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL_INLINE_OUTER, + NSS_DYNAMIC_INTERFACE_TYPE_GENERIC_REDIR_N2H, + NSS_DYNAMIC_INTERFACE_TYPE_GENERIC_REDIR_H2N, + NSS_DYNAMIC_INTERFACE_TYPE_TUN6RD_INNER, + NSS_DYNAMIC_INTERFACE_TYPE_TUN6RD_OUTER, + NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_US, + NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_DS, + NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL_INNER_EXCEPTION, + NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_EXCEPTION_US, + NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_EXCEPTION_DS, + NSS_DYNAMIC_INTERFACE_TYPE_GRE_INNER, + NSS_DYNAMIC_INTERFACE_TYPE_GRE_OUTER, + NSS_DYNAMIC_INTERFACE_TYPE_PPTP_INNER, + NSS_DYNAMIC_INTERFACE_TYPE_PPTP_OUTER, + NSS_DYNAMIC_INTERFACE_TYPE_PPTP_HOST_INNER, + NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_INNER, + NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_MDATA_INNER, + NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_OUTER, + NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_MDATA_OUTER, + NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_REDIRECT, + NSS_DYNAMIC_INTERFACE_TYPE_PVXLAN_HOST_INNER, + NSS_DYNAMIC_INTERFACE_TYPE_PVXLAN_OUTER, + NSS_DYNAMIC_INTERFACE_TYPE_IGS, + NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_US, + NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_DS, + NSS_DYNAMIC_INTERFACE_TYPE_VXLAN_INNER, + NSS_DYNAMIC_INTERFACE_TYPE_VXLAN_OUTER, + NSS_DYNAMIC_INTERFACE_TYPE_MATCH, + NSS_DYNAMIC_INTERFACE_TYPE_RMNET_RX_N2H, + NSS_DYNAMIC_INTERFACE_TYPE_RMNET_RX_H2N, + NSS_DYNAMIC_INTERFACE_TYPE_WIFILI_EXTERNAL0, + NSS_DYNAMIC_INTERFACE_TYPE_WIFILI_EXTERNAL1, + NSS_DYNAMIC_INTERFACE_TYPE_TLS_INNER, + NSS_DYNAMIC_INTERFACE_TYPE_TLS_OUTER, + NSS_DYNAMIC_INTERFACE_TYPE_MIRROR, + NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_WDS, + NSS_DYNAMIC_INTERFACE_TYPE_MAX +}; + +typedef enum nss_dynamic_interface_type nss_dynamic_interface_assigned; + +/** + * nss_dynamic_interface_message_types + * Message types for dynamic interface requests. + */ +enum nss_dynamic_interface_message_types { + NSS_DYNAMIC_INTERFACE_ALLOC_NODE, + NSS_DYNAMIC_INTERFACE_DEALLOC_NODE, + NSS_DYNAMIC_INTERFACE_MAX, +}; + +/** + * nss_dynamic_interface_error_types + * Error types for dynamic interface requests. + */ +enum nss_dynamic_interface_error_types { + NSS_DYNAMIC_INTERFACE_ERR_EUNKNOWN = 1, + NSS_DYNAMIC_INTERFACE_ERR_EUNAVAIL, + NSS_DYNAMIC_INTERFACE_ERR_INVALID_TYPE, + NSS_DYNAMIC_INTERFACE_ERR_INVALID_INTERFACE_NUM, + NSS_DYNAMIC_INTERFACE_ERR_ALLOC_FUNC_UNAVAILABLE, + NSS_DYNAMIC_INTERFACE_ERR_DEALLOC_FUNC_UNAVAILABLE, + NSS_DYNAMIC_INTERFACE_ERR_EALLOC, + NSS_DYNAMIC_INTERFACE_ERR_IFNUM_TYPE_MISMATCH, + NSS_DYNAMIC_INTERFACE_ERR_MAX, +}; + +/** + * nss_dynamic_interface_stats_notification + * Dynamic interface statistics structure. + */ +struct nss_dynamic_interface_notification { + uint32_t core_id; /**< Core ID. */ + uint32_t if_num; /**< Dynamic interface number. */ +}; + +#ifdef __KERNEL__ /* only kernel will use. */ +/** + * nss_dynamic_interface_alloc_node_msg + * Message information for a dynamic interface allocation node. + */ +struct nss_dynamic_interface_alloc_node_msg { + enum nss_dynamic_interface_type type; /**< Type of dynamic interface. */ + + /* + * Response. + */ + int if_num; /**< Dynamic interface number. */ +}; + +/** + * nss_dynamic_interface_dealloc_node_msg + * Message information for dynamic interface deallocation node. + */ +struct nss_dynamic_interface_dealloc_node_msg { + enum nss_dynamic_interface_type type; + /**< Type of dynamic interface. */ + int if_num; /**< Dynamic interface number. */ +}; + +/** + * nss_dynamic_interface_msg + * Data for sending and receiving dynamic interface messages. + */ +struct nss_dynamic_interface_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a dynamic interface message. + */ + union { + struct nss_dynamic_interface_alloc_node_msg alloc_node; + /**< Allocates a dynamic node. */ + struct nss_dynamic_interface_dealloc_node_msg dealloc_node; + /**< Deallocates a dynamic node. */ + } msg; /**< Message payload. */ +}; + +/** + * nss_dynamic_interface_alloc_node + * Allocates a node for a dynamic interface. + * + * @datatypes + * nss_dynamic_interface_type + * + * @param[in] type Type of dynamic interface. + * + * @return + * Number for the dynamic interface created. + * @par + * Otherwise, -1 for a failure. + */ +extern int nss_dynamic_interface_alloc_node(enum nss_dynamic_interface_type type); + +/** + * nss_dynamic_interface_dealloc_node + * Deallocates a node created for a dynamic interface on the NSS. + * + * @datatypes + * nss_dynamic_interface_type + * + * @param[in] if_num Dynamic interface number. + * @param[in] type Type of dynamic interface. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_dynamic_interface_dealloc_node(int if_num, enum nss_dynamic_interface_type type); + +/** + * nss_is_dynamic_interface + * Specifies whether the interface number belongs to the dynamic interface. + * + * @param[in] if_num Dynamic interface number. + * + * @return + * TRUE or FALSE + */ +extern bool nss_is_dynamic_interface(int if_num); + +/** + * nss_dynamic_interface_get_nss_ctx_by_type + * Returns NSS context corresponding to the dynamic interface type. + * + * @datatypes + * nss_dynamic_interface_type + * + * @param[in] type Type of dynamic interface. + * + * @return + * Pointer to the NSS context. + */ +extern struct nss_ctx_instance *nss_dynamic_interface_get_nss_ctx_by_type(enum nss_dynamic_interface_type type); + +/** + * nss_dynamic_interface_get_type + * Returns the type of dynamic interface. + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] if_num Interface number of dynamic interface. + * + * @return + * Type of dynamic interface per the dynamic interface number. + */ +extern enum nss_dynamic_interface_type nss_dynamic_interface_get_type(struct nss_ctx_instance *nss_ctx, int if_num); + +/** + * nss_dynamic_interface_tx + * Transmits an asynchronous message to the firmware. + * + * @datatypes + * nss_ctx_instance \n + * nss_dynamic_interface_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the transmit operation. + */ +extern nss_tx_status_t nss_dynamic_interface_tx(struct nss_ctx_instance *nss_ctx, struct nss_dynamic_interface_msg *msg); + +/** + * Callback function for dynamic interface messages. + * + * @datatypes + * nss_cmn_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_dynamic_interface_msg_callback_t)(void *app_data, struct nss_cmn_msg *msg); + +/** + * nss_dynamic_interface_msg_init + * Initializes a dynamic interface message. + * + * @datatypes + * nss_dynamic_interface_msg + * + * @param[in] ndm Pointer to the dynamic interface message. + * @param[in] if_num Dynamic interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Pointer to the message callback. + * @param[in] app_data Pointer to the application context that is passed to the callback function. + * + * @return + * None. + */ +void nss_dynamic_interface_msg_init(struct nss_dynamic_interface_msg *ndm, uint16_t if_num, uint32_t type, uint32_t len, + void *cb, void *app_data); + +/** + * nss_dynamic_interface_stats_register_notifier + * Registers a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_dynamic_interface_stats_register_notifier(struct notifier_block *nb); + +/** + * nss_dynamic_interface_stats_unregister_notifier + * Deregisters a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_dynamic_interface_stats_unregister_notifier(struct notifier_block *nb); +#endif /*__KERNEL__ */ + +/** + * @} + */ + +#endif /* __NSS_DYNAMIC_INTERFACE_H*/ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_edma.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_edma.h new file mode 100644 index 000000000..4c0d556ec --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_edma.h @@ -0,0 +1,373 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_edma.h + * NSS EDMA interface definitions. + */ + +#ifndef __NSS_EDMA_H +#define __NSS_EDMA_H + +/** + * @addtogroup nss_edma_subsystem + * @{ + */ + +/* + * NSS EDMA port and ring defines + */ +#define NSS_EDMA_NUM_PORTS_MAX 256 + /**< Maximum number of EDMA ports. */ +#define NSS_EDMA_NUM_RX_RING_MAX 16 + /**< Maximum number of physical EDMA Rx rings. */ +#define NSS_EDMA_NUM_RXFILL_RING_MAX 8 + /**< Maximum number of physical EDMA Rx fill rings. */ +#define NSS_EDMA_NUM_TX_RING_MAX 24 + /**< Maximum number of physical EDMA Tx rings. */ +#define NSS_EDMA_NUM_TXCMPL_RING_MAX 8 + /**< Maximum number of physical EDMA Tx complete rings. */ +#define NSS_EDMA_STATS_MSG_MAX_PORTS 16 + /**< Maximum ports processed per statistics message. */ + +/** + * nss_edma_metadata_types + * Message types for EDMA requests and responses. + */ +enum nss_edma_metadata_types { + NSS_METADATA_TYPE_EDMA_PORT_STATS_SYNC, + NSS_METADATA_TYPE_EDMA_RING_STATS_SYNC, + NSS_METADATA_TYPE_EDMA_ERR_STATS_SYNC, + NSS_METADATA_TYPE_EDMA_MAX +}; + +/** + * nss_edma_port_t + * EDMA port types. + */ +enum nss_edma_port_t { + NSS_EDMA_PORT_PHYSICAL, + NSS_EDMA_PORT_VIRTUAL, + NSS_EDMA_PORT_TYPE_MAX +}; + +/** + * nss_edma_stats_tx_t + * Types of EDMA Tx ring statistics. + */ +enum nss_edma_stats_tx_t { + NSS_EDMA_STATS_TX_ERR, + NSS_EDMA_STATS_TX_DROPPED, + NSS_EDMA_STATS_TX_DESC, + NSS_EDMA_STATS_TX_MAX +}; + +/** + * nss_edma_stats_rx_t + * Types of EDMA Rx ring statistics. + */ +enum nss_edma_stats_rx_t { + NSS_EDMA_STATS_RX_CSUM_ERR, + NSS_EDMA_STATS_RX_DESC, + NSS_EDMA_STATS_RX_QOS_ERR, + NSS_EDMA_STATS_RX_SRC_PORT_INVALID, + NSS_EDMA_STATS_RX_MAX +}; + +/** + * nss_edma_stats_txcmpl_t + * Types of EDMA Tx complete statistics. + */ +enum nss_edma_stats_txcmpl_t { + NSS_EDMA_STATS_TXCMPL_DESC, + NSS_EDMA_STATS_TXCMPL_MAX +}; + +/** + * nss_edma_stats_rxfill_t + * Types of EDMA Rx fill statistics. + */ +enum nss_edma_stats_rxfill_t { + NSS_EDMA_STATS_RXFILL_DESC, + NSS_EDMA_STATS_RXFILL_MAX +}; + +/** + * nss_edma_port_ring_map_t + * Port to EDMA ring map. + */ +enum nss_edma_port_ring_map_t { + NSS_EDMA_PORT_RX_RING, + NSS_EDMA_PORT_TX_RING, + NSS_EDMA_PORT_RING_MAP_MAX +}; + +/** + * nss_edma_err_t + * Types of EDMA error statistics. + */ +enum nss_edma_err_t { + NSS_EDMA_AXI_RD_ERR, + NSS_EDMA_AXI_WR_ERR, + NSS_EDMA_RX_DESC_FIFO_FULL_ERR, + NSS_EDMA_RX_BUF_SIZE_ERR, + NSS_EDMA_TX_SRAM_FULL_ERR, + NSS_EDMA_TX_CMPL_BUF_FULL_ERR, + NSS_EDMA_PKT_LEN_LA64K_ERR, + NSS_EDMA_PKT_LEN_LE33_ERR, + NSS_EDMA_DATA_LEN_ERR, + NSS_EDMA_ALLOC_FAIL_CNT, + NSS_EDMA_QOS_INVAL_DST_DROPS, + NSS_EDMA_ERR_STATS_MAX +}; + +/** + * nss_edma_rx_ring_stats + * EDMA Rx ring statistics. + */ +struct nss_edma_rx_ring_stats { + uint32_t rx_csum_err; /**< Number of Rx checksum errors. */ + uint32_t desc_cnt; /**< Number of descriptors processed. */ + uint32_t qos_err; /**< Number of QoS errors. */ + uint32_t rx_src_port_invalid; /**< Number of source port invalid errors. */ +}; + +/** + * nss_edma_tx_ring_stats + * EDMA Tx ring statistics. + */ +struct nss_edma_tx_ring_stats { + uint32_t tx_err; /**< Number of Tx errors. */ + uint32_t tx_dropped; /**< Number of Tx dropped packets. */ + uint32_t desc_cnt; /**< Number of descriptors processed. */ +}; + +/** + * nss_edma_rxfill_ring_stats + * EDMA Rx fill ring statistics. + */ +struct nss_edma_rxfill_ring_stats { + uint32_t desc_cnt; /**< Number of descriptors processed. */ +}; + +/** + * nss_edma_txcmpl_ring_stats + * EDMA Tx complete ring statistics. + */ +struct nss_edma_txcmpl_ring_stats { + uint32_t desc_cnt; /**< Number of descriptors processed. */ +}; + +/** + * nss_edma_port_stats + * Statistics for each EDMA port. + */ +struct nss_edma_port_stats { + struct nss_cmn_node_stats node_stats; /**< Common node statistics. */ + enum nss_edma_port_t port_type; /**< Type of port. */ + uint16_t edma_rx_ring; /**< Rx ring statistics. */ + uint16_t edma_tx_ring; /**< Tx ring statistics. */ +}; + +/** + * nss_edma_port_stats_sync + * Statistics for a group of EDMA ports. + */ +struct nss_edma_port_stats_sync { + uint16_t start_port; /**< Starting index of the subset. */ + uint16_t end_port; /**< Ending index of the subset. */ + struct nss_edma_port_stats port_stats[]; + /**< Subset of EDMA port statistics. */ +}; + +/** + * nss_edma_ring_stats_sync + * EDMA ring statistics. + */ +struct nss_edma_ring_stats_sync { + struct nss_edma_tx_ring_stats tx_ring[NSS_EDMA_NUM_TX_RING_MAX]; + /**< EDMA Tx ring statistics. */ + struct nss_edma_rx_ring_stats rx_ring[NSS_EDMA_NUM_RX_RING_MAX]; + /**< EDMA Rx ring statistics. */ + struct nss_edma_txcmpl_ring_stats txcmpl_ring[NSS_EDMA_NUM_TXCMPL_RING_MAX]; + /**< EDMA Tx complete ring statistics. */ + struct nss_edma_rxfill_ring_stats rxfill_ring[NSS_EDMA_NUM_RXFILL_RING_MAX]; + /**< EDMA Rx fill ring statistics. */ +}; + +/** + * nss_edma_misc_err_stats + * EDMA error statistics. + */ +struct nss_edma_misc_err_stats { + uint32_t axi_rd_err; /**< EDMA AXI read error. */ + uint32_t axi_wr_err; /**< EDMA AXI write error. */ + uint32_t rx_desc_fifo_full_err; /**< EDMA receive descriptor FIFO full error. */ + uint32_t rx_buf_size_err; /**< EDMA receive buffer size error. */ + uint32_t tx_sram_full_err; /**< EDMA transmit SRAM full error. */ + uint32_t tx_cmpl_buf_full_err; /**< EDMA transmit completion buffer full error. */ + uint32_t pkt_len_la64k_err; /**< EDMA packet length greater than 64k error. */ + uint32_t pkt_len_le33_err; /**< EDMA packet length smaller than 33b error. */ + uint32_t data_len_err; /**< EDMA data length error. */ + uint32_t alloc_fail_cnt; /**< EDMA number of times the allocation of pbuf for statistics failed. */ + uint32_t qos_inval_dst_drops; /**< EDMA number of QoS packet dropped due to invalid destination. */ +}; + +/** + * nss_edma_err_stats_sync + * Message for error statistics. + */ +struct nss_edma_err_stats_sync { + struct nss_edma_misc_err_stats msg_err_stats; /**< Message for error statistics. */ +}; + +/** + * nss_edma_msg + * Data for sending and receiving EDMA messages (to synchronize with + * the firmware EDMA). + */ +struct nss_edma_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of an EDMA message. + */ + union { + struct nss_edma_port_stats_sync port_stats; + /**< EDMA port statistics message payload. */ + struct nss_edma_ring_stats_sync ring_stats; + /**< EDMA ring statistics message payload. */ + struct nss_edma_err_stats_sync err_stats; + /**< EDMA error statistics message payload. */ + } msg; /**< EDMA message payload. */ +}; + +/** + * nss_edma_port_info + * NSS EDMA port statistics. + */ +struct nss_edma_port_info { + uint64_t port_stats[NSS_STATS_NODE_MAX]; /**< EDMA port statistics. */ + uint64_t port_type; /**< EDMA port type. */ + uint64_t port_ring_map[NSS_EDMA_PORT_RING_MAP_MAX]; /**< EDMA ring statistics. */ +}; + +/** + * nss_edma_stats + * NSS EDMA node statistics. + */ +struct nss_edma_stats { + struct nss_edma_port_info port[NSS_EDMA_NUM_PORTS_MAX]; + /**< EDMA port statistics. */ + uint64_t tx_stats[NSS_EDMA_NUM_TX_RING_MAX][NSS_EDMA_STATS_TX_MAX]; + /**< Physical EDMA Tx ring statistics. */ + uint64_t rx_stats[NSS_EDMA_NUM_RX_RING_MAX][NSS_EDMA_STATS_RX_MAX]; + /**< Physical EDMA Rx ring statistics. */ + uint64_t txcmpl_stats[NSS_EDMA_NUM_TXCMPL_RING_MAX][NSS_EDMA_STATS_TXCMPL_MAX]; + /**< Physical EDMA Tx complete statistics. */ + uint64_t rxfill_stats[NSS_EDMA_NUM_RXFILL_RING_MAX][NSS_EDMA_STATS_RXFILL_MAX]; + /**< Physical EDMA Rx fill statistics. */ + uint64_t misc_err[NSS_EDMA_ERR_STATS_MAX]; + /**< EDMA error complete statistics. */ +}; + +#ifdef __KERNEL__ + +/** + * Callback function for receiving EDMA messages. + * + * @datatypes + * nss_edma_msg + * + * @param[in] app_data Pointer to the application context for this message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_edma_msg_callback_t)(void *app_data, struct nss_edma_msg *msg); + +/** + * nss_edma_notify_register + * Registers a callback notifier with the NSS for sending and receiving messages. + * + * @datatypes + * nss_edma_msg_callback_t + * + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context for this message. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_edma_notify_register(nss_edma_msg_callback_t cb, void *app_data); + +/** + * nss_edma_notify_unregister + * Deregisters a callback notifier from the NSS. + * + * @return + * None. + * + * @dependencies + * The callback notifier must have been previously registered. + */ +extern void nss_edma_notify_unregister(void); + +/** + * nss_edma_get_stats + * Sends EDMA statistics to NSS clients. + * + * @param[in] stats EDMA statistics to be sent to Netlink. + * @param[in] port_id EDMA port ID. + * + * @return + * None. + */ +void nss_edma_get_stats(uint64_t *stats, int port_id); + +/** + * nss_edma_stats_register_notifier + * Registers a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_edma_stats_register_notifier(struct notifier_block *nb); + +/** + * nss_edma_stats_unregister_notifier + * Deregisters a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_edma_stats_unregister_notifier(struct notifier_block *nb); + +#endif /* __KERNEL__ */ + +/** + * @} + */ + +#endif /* __NSS_EDMA_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_eth_rx.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_eth_rx.h new file mode 100644 index 000000000..90f5a5381 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_eth_rx.h @@ -0,0 +1,100 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_eth_rx.h + * NSS Ethernet interface definitions. + */ + +#ifndef __NSS_ETH_RX_H +#define __NSS_ETH_RX_H + +/** + * @addtogroup nss_eth_rx_subsystem + * @{ + */ + +/** + * nss_eth_rx_stats + * Ethernet node statistics. + */ +enum nss_eth_rx_stats { + NSS_ETH_RX_STATS_TOTAL_TICKS, /**< Total clock ticks spent inside the Ethernet package. */ + NSS_ETH_RX_STATS_WORST_CASE_TICKS, /**< Worst case iteration of the Ethernet in ticks. */ + NSS_ETH_RX_STATS_ITERATIONS, /**< Number of iterations around Ethernet. */ + NSS_ETH_RX_STATS_MAX, /**< Maximum message type. */ +}; + +/** + * nss_eth_rx_exception_events + * Exception events from bridge or route handler. + */ +enum nss_eth_rx_exception_events { + NSS_ETH_RX_EXCEPTION_EVENT_UNKNOWN_L3_PROTOCOL, + NSS_ETH_RX_EXCEPTION_EVENT_ETH_HDR_MISSING, + NSS_ETH_RX_EXCEPTION_EVENT_VLAN_MISSING, + NSS_ETH_RX_EXCEPTION_EVENT_TRUSTSEC_HDR_MISSING, + NSS_ETH_RX_EXCEPTION_EVENT_MAX, +}; + +/** + * nss_eth_rx_stats_notification + * Data for sending Ethernet statistics. + */ +struct nss_eth_rx_stats_notification { + uint32_t core_id; /**< Core ID. */ + uint64_t cmn_node_stats[NSS_STATS_NODE_MAX]; /**< Node statistics. */ + uint64_t special_stats[NSS_ETH_RX_STATS_MAX]; /**< Special statistics. */ + uint64_t exception_stats[NSS_ETH_RX_EXCEPTION_EVENT_MAX]; /**< Exception statistics. */ +}; + +#ifdef __KERNEL__ /* only kernel will use. */ +/** + * nss_eth_rx_stats_register_notifier + * Registers a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_eth_rx_stats_register_notifier(struct notifier_block *nb); + +/** + * nss_eth_rx_stats_unregister_notifier + * Deregisters a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_eth_rx_stats_unregister_notifier(struct notifier_block *nb); +#endif /*__KERNEL__ */ + +/** + *@} + */ + +#endif /* __NSS_ETH_RX_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_freq.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_freq.h new file mode 100644 index 000000000..6ce11b1b8 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_freq.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * @file nss_freq.h + * NSS frequency definitions. + */ + +#ifndef __NSS_FREQ_H +#define __NSS_FREQ_H + +/** + * @addtogroup nss_freq_subsystem + * @{ + */ + +/** + * nss_freq_change + * Changes the frequency of the NSS cores. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] eng Frequency value in Hz. + * @param[in] stats_enable Enable NSS to send scaling statistics. + * @param[in] start_or_end Start or end of the frequency change. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_freq_change(struct nss_ctx_instance *nss_ctx, uint32_t eng, uint32_t stats_enable, uint32_t start_or_end); + +/** + * nss_freq_get_cpu_usage + * Returns the CPU usage value in percentage at any instance for a required core. Range of usage is 0-100. + * + * @param[in] core_id NSS Core ID. + * + * @return + * CPU usage value in percentage averaged over 1 second. -1 in case of error. + * @note + * This API does not support gathering CPU usage data for core 1. + */ +extern int8_t nss_freq_get_cpu_usage(uint32_t core_id); + +/** + * @} + */ + +#endif /* __NSS_FREQ_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_gre.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_gre.h new file mode 100644 index 000000000..dc3b339d8 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_gre.h @@ -0,0 +1,445 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_gre.h + * NSS GRE interface definitions. + */ +#ifndef _NSS_GRE_H_ +#define _NSS_GRE_H_ + +#include +#include + +/** + * @addtogroup nss_gre_subsystem + * @{ + */ + +/** + * Maximum number of session debug statistics + */ +#define NSS_GRE_MAX_DEBUG_SESSION_STATS 16 + +/** + * GRE flags + */ +#define NSS_GRE_CONFIG_IKEY_VALID 0x00000001 /**< Incoming key of GRE header. */ +#define NSS_GRE_CONFIG_OKEY_VALID 0x00000002 /**< Key for outgoing GRE header. */ +#define NSS_GRE_CONFIG_ISEQ_VALID 0x00000004 /**< Enable sequence checking for incoming GRE traffic. */ +#define NSS_GRE_CONFIG_OSEQ_VALID 0x00000008 /**< Add sequence number for out going GRE packets. */ +#define NSS_GRE_CONFIG_ICSUM_VALID 0x00000010 /**< Validate incoming GRE header checksum. */ +#define NSS_GRE_CONFIG_OCSUM_VALID 0x00000020 /**< Add checksum header to GRE header. */ +#define NSS_GRE_CONFIG_TOS_INHERIT 0x00000040 /**< Inherit inner IP TOS to tunnel header, if not set configure provided TOS. */ +#define NSS_GRE_CONFIG_TTL_INHERIT 0x00000080 /**< Inherit inner IP TTL to tunnel header, if not set configure provided TTL. */ +#define NSS_GRE_CONFIG_SET_DF 0x00000100 /**< Enable DF bit on tunnel IP header. */ +#define NSS_GRE_CONFIG_SET_MAC 0x00000200 /**< Add MAC header to GRE+IP tunnel header. */ +#define NSS_GRE_CONFIG_SET_PADDING 0x00000400 /**< Add PADDING to align tunnel IP/GRE header. */ +#define NSS_GRE_CONFIG_NEXT_NODE_AVAILABLE 0x00000800 /**< Use provided next node instead of existing next node. */ +#define NSS_GRE_CONFIG_COPY_METADATA 0x00001000 /**< Enable metadata copy in NSS during alignment. */ +#define NSS_GRE_CONFIG_USE_UNALIGNED 0x00002000 /**< Use unaligned infrastructure in NSS. */ +#define NSS_GRE_CONFIG_DSCP_VALID 0x00004000 /**< Add DSCP per packet. */ + +/** + * nss_gre_error_types. + * Error types for GRE configuration messages. + */ +enum nss_gre_error_types { + NSS_GRE_ERR_UNKNOWN_MSG = 1, /**< Unknown message. */ + NSS_GRE_ERR_IF_INVALID = 2, /**< Invalid interface. */ + NSS_GRE_ERR_MODE_INVALID = 3, /**< Invalid mode type. */ + NSS_GRE_ERR_IP_INVALID = 4, /**< Invalid IP type. */ + NSS_GRE_ERR_GRE_SESSION_PARAMS_INVALID = 5, /**< Invalid GRE session parameters provided. */ + NSS_GRE_ERR_DSCP_CFG_INVALID = 6, /**< Both TOS and DSCP flags are enabled. */ + NSS_GRE_ERR_MAX, /**< Maximum GRE error. */ +}; + +/** + * nss_gre_info + * GRE private information. + */ +struct nss_gre_info { + /** + * Union of IPv4/IPv6 tunnel. + */ + union { + struct ip_tunnel t4; /**< IPv4 tunnel. */ + struct ip6_tnl t6; /**< IPv6 tunnel. */ + } t; /**< IPv4 and IPv6 tunnel. */ + int nss_if_number_inner; /**< NSS interface number for GRE inner. */ + struct net_device *next_dev_inner; /**< Next network device for inner flow. */ + struct net_device *next_dev_outer; /**< Next network device for outer flow. */ + uint8_t gre_hlen; /**< GRE header length. */ + uint8_t pad_len; /**< Pad length. */ +}; + +/** + * nss_gre_msg_types + * Message types for GRE requests and responses. + */ +enum nss_gre_msg_types { + NSS_GRE_MSG_ENCAP_CONFIGURE = NSS_IF_MAX_MSG_TYPES + 1, + NSS_GRE_MSG_DECAP_CONFIGURE, + NSS_GRE_MSG_ENCAP_DECONFIGURE, + NSS_GRE_MSG_DECAP_DECONFIGURE, + NSS_GRE_MSG_SESSION_STATS, + NSS_GRE_MSG_BASE_STATS, + NSS_GRE_MSG_MAX +}; + +/** + * GRE Mode Types + */ +enum nss_gre_mode { + NSS_GRE_MODE_TUN, /**< GRE Tunnel interface. */ + NSS_GRE_MODE_TAP, /**< GRE Tap interface. */ + NSS_GRE_MODE_MAX /**< Maxmum GRE mode. */ +}; + +/** + * GRE IP Types + */ +enum nss_gre_ip_types { + NSS_GRE_IP_IPV4, /**< Outer Tunnel is IPV4. */ + NSS_GRE_IP_IPV6, /**< Outer Tunnel is IPV6. */ + NSS_GRE_IP_MAX, /**< Maximum IP Types. */ +}; + +/** + * GRE Base debug statistics + */ +enum nss_gre_base_debug_types { + GRE_BASE_RX_PACKETS, /**< Rx packet count. */ + GRE_BASE_RX_DROPPED, /**< Number of packet dropped at Rx. */ + GRE_BASE_EXP_ETH_HDR_MISSING, /**< Ethernet header missing. */ + GRE_BASE_EXP_ETH_TYPE_NON_IP, /**< Packet is not IPV4 or IPV6. */ + GRE_BASE_EXP_IP_UNKNOWN_PROTOCOL, /**< Packet protocol is unknown. */ + GRE_BASE_EXP_IP_HEADER_INCOMPLETE, /**< Bad IP header. */ + GRE_BASE_EXP_IP_BAD_TOTAL_LENGTH, /**< IP total lenghth is invalid. */ + GRE_BASE_EXP_IP_BAD_CHECKSUM, /**< IP checksum is bad. */ + GRE_BASE_EXP_IP_DATAGRAM_INCOMPLETE, /**< Bad packet. */ + GRE_BASE_EXP_IP_FRAGMENT, /**< IP packet is a fragment. */ + GRE_BASE_EXP_IP_OPTIONS_INCOMPLETE, /**< IP option is invalid. */ + GRE_BASE_EXP_IP_WITH_OPTIONS, /**< IP packet with options. */ + GRE_BASE_EXP_IPV6_UNKNOWN_PROTOCOL, /**< Protocol is unknown. */ + GRE_BASE_EXP_IPV6_HEADER_INCOMPLETE, /**< Incomplete ipv6 header. */ + GRE_BASE_EXP_GRE_UNKNOWN_SESSION, /**< Unknown GRE session. */ + GRE_BASE_EXP_GRE_NODE_INACTIVE, /**< GRE node is inactive. */ + GRE_BASE_DEBUG_MAX, /**< GRE base debug max. */ +}; + +/* + * GRE session Packet drop and exception events. + */ +enum gre_session_debug_types { + GRE_SESSION_PBUF_ALLOC_FAIL, /**< Pbuf allocation failure. */ + GRE_SESSION_DECAP_FORWARD_ENQUEUE_FAIL, /**< Rx forward enqueue failure. */ + GRE_SESSION_ENCAP_FORWARD_ENQUEUE_FAIL, /**< Tx forward enqueue failure. */ + GRE_SESSION_DECAP_TX_FORWARDED, /**< Number of packets forwarded after decap. */ + GRE_SESSION_ENCAP_RX_RECEIVED, /**< Number of packets received for encap. */ + GRE_SESSION_ENCAP_RX_DROPPED, /**< Packets dropped while enqueuing for encap. */ + GRE_SESSION_ENCAP_RX_LINEAR_FAIL, /**< Packets dropped during encap linearization. */ + GRE_SESSION_EXP_RX_KEY_ERROR, /**< Rx KEY error. */ + GRE_SESSION_EXP_RX_SEQ_ERROR, /**< Rx Sequence number error. */ + GRE_SESSION_EXP_RX_CS_ERROR, /**< Rx checksum error */ + GRE_SESSION_EXP_RX_FLAG_MISMATCH, /**< Rx flag mismatch. */ + GRE_SESSION_EXP_RX_MALFORMED, /**< Rx packet is malformed. */ + GRE_SESSION_EXP_RX_INVALID_PROTOCOL, /**< Rx packet protocol is invalid. */ + GRE_SESSION_EXP_RX_NO_HEADROOM, /**< Packet does not have enough headroom. */ + GRE_SESSION_DEBUG_MAX, /**< Session debug max. */ +}; + +/** + * GRE create message structure. + */ +struct nss_gre_config_msg { + uint32_t src_ip[4]; /**< Source IPv4 or IPv6 Adddress. */ + uint32_t dest_ip[4]; /**< Destination IPv4 or IPv6 Adddress. */ + uint32_t flags; /**< GRE Flags. */ + uint32_t ikey; /**< GRE rx KEY.*/ + uint32_t okey; /**< GRE tx KEY. */ + uint32_t mode; /**< GRE TUN or TAP. */ + uint32_t ip_type; /**< IPv4 or IPv6 type. */ + uint32_t next_node_if_num; /**< To whom to forward packets. */ + uint32_t sibling_if_num; /**< Sibling interface number. */ + uint16_t src_mac[3]; /**< Source MAC address. */ + uint16_t dest_mac[3]; /**< Destination MAC address. */ + uint8_t ttl; /**< TTL or HOPLIMIT. */ + uint8_t tos; /**< Type of service. */ + uint16_t metadata_size; /**< Metadata copy size. */ +}; + +/** + * GRE link up message structure + */ +struct nss_gre_linkup_msg { + int if_number; /**< Interface number. */ +}; + +/** + * GRE link down message structure + */ +struct nss_gre_linkdown_msg { + int if_number; /**< Interface number. */ +}; + +/** + * GRE deconfig message structure + */ +struct nss_gre_deconfig_msg { + int if_number; /**< Interface number */ +}; + +/** + * GRE session statistics message + */ +struct nss_gre_session_stats_msg { + struct nss_cmn_node_stats node_stats; /**< Common node statistics. */ + uint32_t stats[GRE_SESSION_DEBUG_MAX]; /**< Session debug statistics. */ +}; + +/** + * GRE base statistics message + */ +struct nss_gre_base_stats_msg { + uint32_t stats[GRE_BASE_DEBUG_MAX]; /**< Base debug statistics. */ +}; + +/** + * nss_gre_msg + * Message structure to send/receive GRE messages + */ +struct nss_gre_msg { + struct nss_cmn_msg cm; /**< Common message header */ + + /** + * Payload of a GRE message. + */ + union { + struct nss_gre_config_msg cmsg; /**< GRE session config message. */ + struct nss_gre_deconfig_msg dmsg; /**< GRE session deconfig message. */ + struct nss_gre_linkup_msg linkup; /**< GRE link up message. */ + struct nss_gre_linkdown_msg linkdown; /**< GRE link down message. */ + struct nss_gre_session_stats_msg sstats; /**< GRE session statistics message. */ + struct nss_gre_base_stats_msg bstats; /**< Base statistics message. */ + } msg; /**< Message payload. */ +}; + +/** + * Callback function to receive GRE messages + * + * @datatypes + * nss_gre_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_gre_msg_callback_t)(void *app_data, struct nss_gre_msg *msg); + +/** + * nss_gre_tx_msg + * Sends GRE messages to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_gre_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_gre_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_gre_msg *msg); + +/** + * nss_gre_tx_msg_sync + * Sends GRE messages to the NSS synchronously. + * + * @datatypes + * nss_ctx_instance \n + * nss_gre_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_gre_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_msg *msg); + +/** + * nss_gre_tx_buf + * Sends packet to the NSS + * + * @datatypes + * nss_ctx_instance \n + * sk_buff + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] if_num Nss interface number. + * @param[in] skb Pointer to sk_buff. + * + * @return Tx status + */ +extern nss_tx_status_t nss_gre_tx_buf(struct nss_ctx_instance *nss_ctx, uint32_t if_num, struct sk_buff *skb); + +/** + * nss_gre_get_context. + * Gets the GRE context used in nss_gre_tx. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_gre_get_context(void); + +/** + * + * nss_gre_ifnum_with_core_id + * Append core ID on GRE interface. + * + * @param[in] if_num NSS interface number. + * + * @return + * GRE interface number with core ID. + */ +extern int nss_gre_ifnum_with_core_id(int if_num); + +/** + * Callback function for receiving GRE session data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_gre_data_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * nss_gre_register_if + * Registers the GRE interface with the NSS for sending and + * receiving messages. + * + * @datatypes + * nss_gre_data_callback_t \n + * nss_gre_msg_callback_t \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] type NSS interface type. + * @param[in] gre_callback Callback for the data. + * @param[in] msg_callback Callback for the message. + * @param[in] netdev Pointer to the associated network device. + * @param[in] features Socket buffer types supported by this interface. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_gre_register_if(uint32_t if_num, uint32_t type, nss_gre_data_callback_t gre_callback, + nss_gre_msg_callback_t msg_callback, struct net_device *netdev, uint32_t features); + +/** + * nss_gre_unregister_if + * Deregisters the GRE interface from the NSS. + * + * @param[in] if_num NSS interface number. +. * + * @return + * None. + * + * @dependencies + * The tunnel interface must have been previously registered. + */ +extern void nss_gre_unregister_if(uint32_t if_num); + +/** + * nss_gre_msg_init + * Initializes a GRE message. + * + * @datatypes + * nss_gre_msg + * + * @param[in,out] ncm Pointer to the message. + * @param[in] if_num Interface number + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Pointer to the message callback. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_gre_msg_init(struct nss_gre_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data); + +/** + * nss_gre_register_handler + * Registers the GRE interface with the NSS debug statistics handler. + * + * @return + * None. + */ +extern void nss_gre_register_handler(void); + +/** + * Callback function for updating stats. + * + * @datatypes + * net_device \n + * sk_buff \n + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * + * @return + * None. + */ +typedef void (*nss_gre_pkt_callback_t)(struct net_device *netdev, struct sk_buff *skb); + +/** + * nss_gre_register_pkt_callback + * Register for rx packet call back. + * + * @datatypes + * nss_gre_pkt_callback_t + * + * @param[in] cb Call back function which needs to be registered. + * + * @return + * None. + */ +extern void nss_gre_register_pkt_callback(nss_gre_pkt_callback_t cb); + +/** + * nss_gre_unregister_pkt_callback + * Unregister for rx packet call back. + * + * @datatypes + * nss_gre_pkt_callback_t + * + * @return + * None. + */ +extern void nss_gre_unregister_pkt_callback(void); + +/** + * @} + */ + +#endif /* _NSS_GRE_H_ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_gre_redir.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_gre_redir.h new file mode 100644 index 000000000..1a4db197f --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_gre_redir.h @@ -0,0 +1,601 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2015, 2017-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_gre_redir.h + * NSS GRE Redirect interface definitions. + */ + +#ifndef __NSS_GRE_REDIR_H +#define __NSS_GRE_REDIR_H + +/** + * @addtogroup nss_gre_redirect_subsystem + * @{ + */ + +#define NSS_GRE_REDIR_MAX_INTERFACES 24 /**< Maximum number of redirect interfaces. */ +#define NSS_GRE_REDIR_IP_DF_OVERRIDE_FLAG 0x80 /**< Override Do not Fragment bit in IPv4 flags. */ +#define NSS_GRE_REDIR_PER_PACKET_METADATA_OFFSET 4 /**< Offset of per packet metadata from start of packet. */ +#define NSS_GRE_REDIR_MAX_RADIO 5 /**< Maximum number of radios. */ +#define NSS_GRE_REDIR_HEADER_VERSION 0 /**< Version for GRE header. */ + +/** + * nss_gre_redir_ip_hdr_type + * IP header types. + */ +enum nss_gre_redir_ip_hdr_type { + NSS_GRE_REDIR_IP_HDR_TYPE_IPV4 = 1, + NSS_GRE_REDIR_IP_HDR_TYPE_IPV6 = 2, +}; + +/** + * nss_gre_redir_message_types + * Message types for GRE redirect requests and responses. + */ +enum nss_gre_redir_message_types { + NSS_GRE_REDIR_TX_TUNNEL_INNER_CONFIGURE_MSG, /**< Configure message for inner node. */ + NSS_GRE_REDIR_TX_TUNNEL_OUTER_CONFIGURE_MSG, /**< Configure message for outer node. */ + NSS_GRE_REDIR_TX_INTERFACE_MAP_MSG, /**< Interface map message. */ + NSS_GRE_REDIR_TX_INTERFACE_UNMAP_MSG, /**< Interface unmap message. */ + NSS_GRE_REDIR_TX_SJACK_MAP_MSG, /**< SJACK map message. */ + NSS_GRE_REDIR_TX_SJACK_UNMAP_MSG, /**< SJACK unmap message. */ + NSS_GRE_REDIR_RX_STATS_SYNC_MSG, /**< Statistics synchronization message. */ + NSS_GRE_REDIR_EXCEPTION_DS_REG_CB_MSG, /**< Configure message to register callback. */ + NSS_GRE_REDIR_MAX_MSG_TYPES, /**< Maximum message type. */ +}; + +/** + * nss_gre_redir_error_types + * Error types for GRE redirect configuration messages. + */ +enum nss_gre_redir_error_types { + NSS_GRE_REDIR_ERROR_NONE, /**< Configuration successful. */ + NSS_GRE_REDIR_ERROR_UNKNOWN_MSG_TYPE, /**< Unknown configuration message type error. */ + NSS_GRE_REDIR_ERROR_INVALID_IP_HDR_TYPE, /**< Invalid IP header type error. */ + NSS_GRE_REDIR_ERROR_MAP_TABLE_FULL, /**< Map table full error. */ + NSS_GRE_REDIR_ERROR_MAP_INVALID_PARAM, /**< Invalid parameter with map message error. */ + NSS_GRE_REDIR_ERROR_UNMAP_INVALID_PARAM, /**< Invalid parameter with unmap message error. */ + NSS_GRE_REDIR_ERROR_ENCAP_MAP_EXIST, /**< Encapsulation map entry already exist. */ + NSS_GRE_REDIR_ERROR_DECAP_MAP_EXIST, /**< Decapsulation map entry already exist. */ + NSS_GRE_REDIR_ERROR_ENCAP_MAP_ALLOC_FAIL, /**< Encapsulation map entry allocation failure error. */ + NSS_GRE_REDIR_ERROR_DECAP_MAP_ALLOC_FAIL, /**< Decapsulation map entry allocation failure error. */ + NSS_GRE_REDIR_ERROR_ENCAP_ENTRY_UNMAPPED, /**< Encapsulation map entry already unmapped. */ + NSS_GRE_REDIR_ERROR_DECAP_ENTRY_UNMAPPED, /**< Decapsulation map entry already unmapped. */ + NSS_GRE_REDIR_ERROR_INVALID_ETH_IF, /**< Invalid Ethernet NSS interface. */ + NSS_GRE_REDIR_ERROR_INVALID_VAP_NEXTHOP_IF, /**< Invalid nexthop NSS interface. */ + NSS_GRE_REDIR_ERROR_INVALID_PEER_INTERFACE, /**< Invalid peer interface during tunnel configuration. */ +}; + +/** + * nss_gre_redir_tunnel_types + * GRE tunnel types. + */ +enum nss_gre_redir_tunnel_types { + NSS_GRE_REDIR_TUNNEL_TYPE_UNKNOWN, /**< Reserved. */ + NSS_GRE_REDIR_TUNNEL_TYPE_TUN, /**< Tunnel mode. */ + NSS_GRE_REDIR_TUNNEL_TYPE_DTUN, /**< D-tunnel mode. */ + NSS_GRE_REDIR_TUNNEL_TYPE_SPLIT, /**< Split mode. */ + NSS_GRE_REDIR_TUNNEL_TYPE_MAX, /**< Maximum tunnel type. */ +}; + +/** + * nss_gre_redir_inner_configure_msg + * Message information for configuring GRE inner node. + */ +struct nss_gre_redir_inner_configure_msg { + uint32_t ip_hdr_type; /**< IP header type (IPv4 or IPv6). */ + + /** + * IPv4 or IPv6 source address (lower 4 bytes are applicable for IPv4). + */ + uint32_t ip_src_addr[4]; + + /** + * IPv4 or IPv6 destination address (lower 4 bytes are applicable for IPv4). + */ + uint32_t ip_dest_addr[4]; + + /** + * The host outer-interface which handles post-encapsulation exception packets + * originating from this inner interface. + */ + uint32_t except_outerif; + + uint8_t ip_df_policy; /**< Default Do Not Fragment policy for the IP header. */ + uint8_t ip_ttl; /**< Time-to-live value for the IP header. */ + uint8_t gre_version; /**< Header version. */ +}; + +/** + * nss_gre_redir_outer_configure_msg + * Message information for configuring GRE outer node. + */ +struct nss_gre_redir_outer_configure_msg { + uint32_t ip_hdr_type; /**< IP header type (IPv4 or IPv6). */ + + /** + * The host inner-interface which handles post-decapsulation exception packets + * originating from this outer interface, for flows destined to a VAP handled + * by host. + */ + uint32_t except_hostif; + + /** + * The host inner-interface which handles post-decapsulation exception packets + * originating from this outer interface, for flows destined to a VAP handled + * by NSS. + */ + uint32_t except_offlif; + + /** + * The host inner-interface which handles post-decapsulation exception packets + * originating from this outer interface, for flows destined to SJACK. + */ + uint32_t except_sjackif; + + /** + * CPU core to which these packets should be steered. + * - 0 -- Use core 0 + * - 1 -- Use core 1 + * - 2 -- Use core 2 + * - 3 -- Use core 3 + */ + uint8_t rps_hint; + + /** + * Flag to indicate validity of RPS hint. + */ + uint8_t rps_hint_valid; + +}; + +/** + * nss_gre_redir_exception_ds_reg_cb_msg + * Message information to register callback on VAP for GRE exception downstream. + */ +struct nss_gre_redir_exception_ds_reg_cb_msg { + uint32_t dst_vap_nssif; /**< NSS VAP interface on which the callback is registered. */ +}; + +/** + * nss_gre_redir_interface_map_msg + * Message information for adding a VAP interface-to-tunnel ID mapping. + */ +struct nss_gre_redir_interface_map_msg { + uint32_t vap_nssif; /**< NSS VAP interface. */ + uint32_t nexthop_nssif; /**< Next hop NSS interface number. */ + uint16_t radio_id; /**< Radio ID to derive tunnel ID. */ + uint16_t vap_id; /**< VAP ID to derive tunnel ID. */ + uint16_t lag_en; /**< Flag for LAG mode. */ + uint16_t tunnel_type; /**< Type of tunnel. */ + + /** + * IPsec security association pattern. Pattern + * 0x5A is supported only. + */ + uint8_t ipsec_pattern; +}; + +/** + * nss_gre_redir_interface_unmap_msg + * Message information for deleting a VAP interface-to-tunnel ID mapping. + */ +struct nss_gre_redir_interface_unmap_msg { + uint32_t vap_nssif; /**< NSS VAP interface. */ + uint16_t radio_id; /**< Radio ID to derive tunnel ID. */ + uint16_t vap_id; /**< VAP ID to derive tunnel ID. */ +}; + +/** + * nss_gre_redir_sjack_map_msg + * Message information for adding an Ethernet interface-to-tunnel ID mapping. + */ +struct nss_gre_redir_sjack_map_msg { + uint32_t eth_nssif; /**< NSS Ethernet interface number. */ + uint32_t eth_id; /**< Ethernet interface ID. */ + + /** + * IPsec security association pattern. Pattern + * 0x5A is supported only. + */ + uint8_t ipsec_pattern; +}; + +/** + * nss_gre_redir_sjack_unmap_msg + * Message information for deleting an Ethernet interface-to-tunnel ID mapping. + */ +struct nss_gre_redir_sjack_unmap_msg { + uint32_t eth_nssif; /**< NSS Ethernet interface number. */ + uint32_t eth_id; /**< Ethernet interface ID. */ +}; + +/** + * nss_gre_redir_stats_sync_msg + * Message information for synchronized GRE redirect statistics. + */ +struct nss_gre_redir_stats_sync_msg { + struct nss_cmn_node_stats node_stats; /**< Common node statistics. */ + uint32_t sjack_rx_packets; /**< SJACK packet counter. */ + uint32_t offl_rx_pkts[NSS_GRE_REDIR_MAX_RADIO]; /**< Offload packet counter. */ + uint32_t encap_sg_alloc_drop; /**< Encapsulation drop counters due to scatter gather buffer allocation failure. */ + uint32_t decap_fail_drop; /**< Decapsulation drop counters due to invalid IP header. */ + uint32_t decap_split_drop; /**< Decapsulation drop counters due to split flow processing. */ + uint32_t split_sg_alloc_fail; /**< Split processing fail counter due to scatter gather buffer allocation failure. */ + uint32_t split_linear_copy_fail; /**< Split processing fail counter due to linear copy fail. */ + uint32_t split_not_enough_tailroom; /**< Split processing fail counter due to insufficient tailroom. */ + uint32_t exception_ds_invalid_dst_drop; /**< Downstream exception handling fail counter due to invalid destination. */ + uint32_t decap_eapol_frames; /**< Decapsulation EAPoL frame counters. */ + uint32_t exception_ds_inv_appid; /**< Invalid application ID for the Tx completion packets on exception downstream node. */ + uint32_t headroom_unavail; /**< Packet headroom unavailable to write metadata. */ + uint32_t tx_completion_success; /**< Host enqueue success count for the Tx completion packets. */ + uint32_t tx_completion_drop; /**< Host enqueue drop count for the Tx completion packets. */ +}; + +/** + * nss_gre_redir_tunnel_stats + * GRE redirect statistics as seen by the HLOS. + */ +struct nss_gre_redir_tunnel_stats { + struct net_device *dev; /**< Net device. */ + struct nss_cmn_node_stats node_stats; /**< Common node statistics. */ + uint64_t tx_dropped; /**< Dropped Tx packets. */ + uint64_t sjack_rx_packets; /**< SJACK Rx packet counter. */ + uint64_t sjack_tx_packets; /**< SJACK Tx packet counter. */ + uint64_t offl_rx_pkts[NSS_GRE_REDIR_MAX_RADIO]; /**< Offload Rx packet counter per radio. */ + uint64_t offl_tx_pkts[NSS_GRE_REDIR_MAX_RADIO]; /**< Offload Tx packet counter per radio. */ + uint64_t exception_us_rx; /**< Upstream exception Rx packet counter. */ + uint64_t exception_us_tx; /**< Upstream exception Tx packet counter. */ + uint64_t exception_ds_rx; /**< Downstream exception Rx packet counter. */ + uint64_t exception_ds_tx; /**< Downstream exception Tx packet counter. */ + uint64_t encap_sg_alloc_drop; /**< Encapsulation drop counters due to scatter gather buffer allocation failure. */ + uint64_t decap_fail_drop; /**< Decapsulation drop counters due to invalid IP header. */ + uint64_t decap_split_drop; /**< Decapsulation drop counters due to split flow processing. */ + uint64_t split_sg_alloc_fail; /**< Split processing fail counter due to scatter gather buffer allocation failure. */ + uint64_t split_linear_copy_fail; /**< Split processing fail counter due to linear copy fail. */ + uint64_t split_not_enough_tailroom; /**< Split processing fail counter due to insufficient tailroom. */ + uint64_t exception_ds_invalid_dst_drop; /**< Downstream exception handling fail counter due to invalid destination. */ + uint64_t decap_eapol_frames; /**< Decapsulation EAPoL frame counters. */ + uint64_t exception_ds_inv_appid; /**< Invalid application ID for the Tx completion packets on exception downstream node. */ + uint64_t headroom_unavail; /**< Packet headroom unavailable to write metadata. */ + uint64_t tx_completion_success; /**< Host enqueue success count for the Tx completion packets. */ + uint64_t tx_completion_drop; /**< Host enqueue drop count for the Tx completion packets. */ + uint32_t ref_count; /**< Reference count for statistics. */ +}; + +/** + * nss_gre_redir_msg + * Data for sending and receiving GRE tunnel redirect messages. + */ +struct nss_gre_redir_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a GRE tunnel redirect message. + */ + union { + struct nss_gre_redir_inner_configure_msg inner_configure; + /**< Configure a GRE inner node. */ + struct nss_gre_redir_outer_configure_msg outer_configure; + /**< Configure a GRE outer node. */ + struct nss_gre_redir_interface_map_msg interface_map; + /**< Add a VAP interface-to-tunnel ID mapping. */ + struct nss_gre_redir_interface_unmap_msg interface_unmap; + /**< Delete a VAP interafce-to-tunnel ID mapping. */ + struct nss_gre_redir_sjack_map_msg sjack_map; + /**< Add an Ethernet interface-to-tunnel ID mapping for SJACK. */ + struct nss_gre_redir_sjack_unmap_msg sjack_unmap; + /**< Delete an Ethernet interface-to-tunnel ID mapping for SJACK. */ + struct nss_gre_redir_stats_sync_msg stats_sync; + /**< Synchronized tunnel statistics. */ + struct nss_gre_redir_exception_ds_reg_cb_msg exception_ds_configure; + /**< Registering callback on VAP for the GRE downstream flows. */ + } msg; /**< Message payload for GRE redirect messages exchanged with NSS core. */ + +}; + +/** + * nss_gre_redir_encap_per_pkt_metadata + * Metadata information for an HLOS-to-NSS packet. + */ +struct nss_gre_redir_encap_per_pkt_metadata { + uint16_t gre_tunnel_id; /**< ID of the tunnel. */ + uint8_t gre_flags; /**< Flags field from GRE header. */ + uint8_t gre_prio; /**< Priority field from GRE header. */ + uint8_t gre_seq; /**< Sequence number. */ + uint8_t ip_dscp; /**< DSCP values. */ + + /** + * Override the default DF policy for the packet by setting bit 8. + * The lower 7 bits provide the DF value to be used for this packet. + */ + uint8_t ip_df_override; + + /** + * IPsec security association pattern. Pattern + * 0x5A is supported only. + */ + uint8_t ipsec_pattern; +}; + +/** + * nss_gre_redir_decap_per_pkt_metadata + * Metadata information for an NSS-to-HLOS packet. + */ +struct nss_gre_redir_decap_per_pkt_metadata { + uint32_t src_if_num; /**< Number of the source Ethernet interface. */ + uint16_t gre_tunnel_id; /**< ID of the tunnel. */ + uint8_t gre_flags; /**< Flags from GRE header. */ + uint8_t gre_prio; /**< Priority from GRE header. */ + uint8_t gre_seq; /**< Sequence number. */ +}; + +/** + * nss_gre_redir_exception_us_metadata + * Metadata information for upstream exception packet. + * + * Note: Additional fields need to be added by customer as required. + */ +struct nss_gre_redir_exception_us_metadata { + uint8_t tid; /**< TID value. */ +}; + +/** + * nss_gre_redir_exception_ds_metadata + * Metadata information for downstream exception packet. + * + * Note: Additional fields need to be added by customer as required. + */ +struct nss_gre_redir_exception_ds_metadata { + uint32_t dst_vap_nssif; /**< Destination VAP interface number. */ + uint8_t tid; /**< TID value. */ + uint8_t app_id; /**< Application ID. */ + uint16_t hw_hash_idx; /**< Hardware AST hash index value. */ + uint32_t tx_status; /**< Tx status. */ +}; + +/** + * Callback function for receiving GRE tunnel data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_gre_redir_data_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * Callback function for receiving GRE tunnel messages. + * + * @datatypes + * nss_cmn_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_gre_redir_msg_callback_t)(void *app_data, struct nss_cmn_msg *msg); + +/** + * nss_gre_redir_unregister_if + * Deregisters a GRE tunnel interface from the NSS. + * + * @param[in] if_num NSS interface number. +. * + * @return + * None. + * + * @dependencies + * The tunnel interface must have been previously registered. + * + * @return + * True if successful, else false. + */ +extern bool nss_gre_redir_unregister_if(uint32_t if_num); + +/** + * nss_gre_redir_tx_msg + * Sends GRE redirect tunnel messages. + * + * @datatypes + * nss_ctx_instance \n + * nss_gre_redir_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_gre_redir_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_gre_redir_msg *msg); + +/** + * nss_gre_redir_tx_buf + * Sends GRE redirect tunnel packets. + * + * @datatypes + * nss_ctx_instance \n + * sk_buff + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] os_buf Pointer to the OS buffer (e.g., skbuff). + * @param[in] if_num Tunnel interface number. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_gre_redir_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf, + uint32_t if_num); + +/** + * nss_gre_redir_tx_buf_noreuse + * Sends GRE redirect tunnel packets. + * + * Note: The buffers will be not be reused or + * kept in the accelerator. + * + * @datatypes + * nss_ctx_instance \n + * sk_buff + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] os_buf Pointer to the OS buffer (e.g., skbuff). + * @param[in] if_num Tunnel interface number. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_gre_redir_tx_buf_noreuse(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf, + uint32_t if_num); + +/** + * nss_gre_redir_get_stats + * Gets GRE redirect tunnel statistics. + * + * @datatypes + * nss_gre_redir_tunnel_stats + * + * @param[in] index Index in the tunnel statistics array. + * @param[out] stats Pointer to the tunnel statistics. + * + * @return + * TRUE or FALSE. + */ +extern bool nss_gre_redir_get_stats(int index, struct nss_gre_redir_tunnel_stats *stats); + +/** + * nss_gre_redir_alloc_and_register_node + * Allocates and registers GRE redirect dynamic node with NSS. + * + * @datatypes + * net_device \n + * nss_gre_redir_data_callback_t \n + * nss_gre_redir_msg_callback_t \n + * + * @param[in] dev Pointer to the associated network device. + * @param[in] data_cb Callback for the data. + * @param[in] msg_cb Callback for the message. + * @param[in] type Type of dynamic node. + * @param[in] app_ctx Application context for notify callback. + * + * @return + * NSS interface number allocated. + */ +extern int nss_gre_redir_alloc_and_register_node(struct net_device *dev, + nss_gre_redir_data_callback_t data_cb, + nss_gre_redir_msg_callback_t msg_cb, + uint32_t type, void *app_ctx); + +/** + * nss_gre_redir_configure_inner_node + * Configures inner GRE redirect node. + * + * @datatypes + * nss_gre_redir_inner_configure_msg + * + * @param[in] ifnum NSS interface number. + * @param[in] ngrcm Inner node configuration message. + * + * @return + * Status of Tx operation. + */ +extern nss_tx_status_t nss_gre_redir_configure_inner_node(int ifnum, + struct nss_gre_redir_inner_configure_msg *ngrcm); + +/** + * nss_gre_redir_configure_outer_node + * Configures outer GRE redirect node. + * + * @datatypes + * nss_gre_redir_outer_configure_msg + * + * @param[in] ifnum NSS interface number. + * @param[in] ngrcm Outer node configuration message. + * + * @return + * Status of Tx operation. + */ +extern nss_tx_status_t nss_gre_redir_configure_outer_node(int ifnum, + struct nss_gre_redir_outer_configure_msg *ngrcm); + +/** + * nss_gre_redir_exception_ds_reg_cb + * Configure a callback on VAP for downstream GRE exception flows. + * + * @datatypes + * nss_gre_redir_exception_ds_reg_cb_msg + * + * @param[in] ifnum NSS interface number. + * @param[in] ngrcm Downstream exception callback registration message. + * + * @return + * Status of Tx operation. + */ +extern nss_tx_status_t nss_gre_redir_exception_ds_reg_cb(int ifnum, + struct nss_gre_redir_exception_ds_reg_cb_msg *ngrcm); + +/** + * nss_gre_redir_tx_msg_sync + * Sends messages to NSS firmware synchronously. + * + * @datatypes + * nss_ctx_instance \n + * nss_gre_redir_msg + * + * @param[in] nss_ctx NSS core context. + * @param[in] ngrm Pointer to GRE redirect message data. + * + * @return + * Status of Tx operation. + */ +extern nss_tx_status_t nss_gre_redir_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_redir_msg *ngrm); + +/** + * nss_gre_redir_get_context + * Gets the GRE redirect context. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_gre_redir_get_context(void); + +/** + * nss_gre_redir_get_dentry + * Returns directory entry created in debugfs for statistics. + * + * @return + * Pointer to created directory entry for GRE redirect. + */ +extern struct dentry *nss_gre_redir_get_dentry(void); + +/** + * nss_gre_redir_get_device + * Gets the original device from probe. + * + * @return + * Pointer to the device. + */ +extern struct device *nss_gre_redir_get_device(void); + +/** + * @} + */ + +#endif /* __NSS_GRE_REDIR_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_gre_redir_lag.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_gre_redir_lag.h new file mode 100644 index 000000000..d2c64fddb --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_gre_redir_lag.h @@ -0,0 +1,622 @@ +/* + ************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_gre_redir_lag.h + * NSS GRE redirect LAG interface definitions. + */ + +#ifndef __NSS_GRE_REDIR_LAG_H +#define __NSS_GRE_REDIR_LAG_H + +/** + * @addtogroup nss_gre_redirect_subsystem + * @{ + */ + +#define NSS_GRE_REDIR_LAG_MAX_NODE 12 /**< Maximum number of LAG nodes. */ +#define NSS_GRE_REDIR_LAG_MAX_SLAVE 8 /**< Maximum number of GRE redirect nodes per LAG node. */ +#define NSS_GRE_REDIR_LAG_MIN_SLAVE 2 /**< Minimum required GRE redirect nodes per LAG node. */ +#define NSS_GRE_REDIR_LAG_US_STATS_SYNC_RETRY 3 /**< Number of retries for sending query hash messages. */ +#define NSS_GRE_REDIR_LAG_US_MAX_HASH_PER_MSG 80 /**< Maximum hash entries per message. */ + +/* + * nss_gre_redir_lag_err_types + * GRE redirect LAG error types. + */ +enum nss_gre_redir_lag_err_types { + NSS_GRE_REDIR_LAG_SUCCESS, + NSS_GRE_REDIR_LAG_ERR_INCORRECT_IFNUM, + NSS_GRE_REDIR_LAG_ERR_CORE_UNREGISTER_FAILED, + NSS_GRE_REDIR_LAG_ERR_STATS_INDEX_NOT_FOUND, + NSS_GRE_REDIR_LAG_ERR_DEALLOC_FAILED, + NSS_GRE_REDIR_LAG_ERR_MAX, +}; + +/** + * nss_gre_redir_lag_us_message_types + * GRE redirect LAG upstream message types. + */ +enum nss_gre_redir_lag_us_message_types { + NSS_GRE_REDIR_LAG_US_CONFIG_MSG, + NSS_GRE_REDIR_LAG_US_ADD_HASH_NODE_MSG, + NSS_GRE_REDIR_LAG_US_DEL_HASH_NODE_MSG, + NSS_GRE_REDIR_LAG_US_QUERY_HASH_NODE_MSG, + NSS_GRE_REDIR_LAG_US_CMN_STATS_SYNC_MSG, + NSS_GRE_REDIR_LAG_US_DB_HASH_NODE_MSG, + NSS_GRE_REDIR_LAG_US_MAX_MSG_TYPES, +}; + +/** + * nss_gre_redir_lag_ds_message_types + * GRE redirect LAG downstream message types. + */ +enum nss_gre_redir_lag_ds_message_types { + NSS_GRE_REDIR_LAG_DS_ADD_STA_MSG, + NSS_GRE_REDIR_LAG_DS_DEL_STA_MSG, + NSS_GRE_REDIR_LAG_DS_UPDATE_STA_MSG, + NSS_GRE_REDIR_LAG_DS_STATS_SYNC_MSG, + NSS_GRE_REDIR_LAG_DS_MAX_MSG_TYPES, +}; + +/** + * nss_gre_redir_lag_us_hash_mode + * GRE redirect LAG upstream hash modes. + */ +enum nss_gre_redir_lag_us_hash_mode { + NSS_GRE_REDIR_LAG_US_HASH_MODE_SRC_AND_DEST, + NSS_GRE_REDIR_LAG_US_HASH_MODE_SRC, + NSS_GRE_REDIR_LAG_US_HASH_MODE_DEST, + NSS_GRE_REDIR_LAG_US_HASH_MODE_MAX, +}; + +/** + * nss_gre_redir_lag_us_config_msg + * Upstream configure message. + */ +struct nss_gre_redir_lag_us_config_msg { + uint32_t hash_mode; /**< Hash operating mode. */ + uint32_t num_slaves; /**< Number of slaves. */ + uint32_t if_num[NSS_GRE_REDIR_LAG_MAX_SLAVE]; /**< NSS interface numbers of GRE redirect tunnels. */ +}; + +/** + * nss_gre_redir_lag_us_add_hash_node_msg + * Message to add hash entry. + */ +struct nss_gre_redir_lag_us_add_hash_node_msg { + uint32_t if_num; /**< NSS interface number of GRE redirect. */ + uint16_t src_mac[ETH_ALEN / 2]; /**< Source MAC address. */ + uint16_t dest_mac[ETH_ALEN / 2]; /**< Destination MAC address. */ +}; + +/** + * nss_gre_redir_lag_us_del_hash_node_msg + * Message to delete hash entry. + */ +struct nss_gre_redir_lag_us_del_hash_node_msg { + uint16_t src_mac[ETH_ALEN / 2]; /**< Source MAC address. */ + uint16_t dest_mac[ETH_ALEN / 2]; /**< Destination MAC address. */ +}; + +/** + * nss_gre_redir_lag_us_query_hash_node_msg + * Message to query if a hash entry is present. + */ +struct nss_gre_redir_lag_us_query_hash_node_msg { + uint16_t src_mac[ETH_ALEN / 2]; /**< Source MAC address. */ + uint16_t dest_mac[ETH_ALEN / 2]; /**< Destination MAC address. */ + uint32_t ifnum; /**< NSS interface number of GRE redirect. */ +}; + +/** + * nss_gre_redir_lag_us_cmn_sync_stats + * GRE redirect LAG upstream statistics. + */ +struct nss_gre_redir_lag_us_cmn_sync_stats { + uint32_t amsdu_pkts; /**< Number of AMSDU packets seen. */ + uint32_t amsdu_pkts_enqueued; /**< Number of AMSDU packets enqueued. */ + uint32_t amsdu_pkts_exceptioned; /**< Number of AMSDU packets exceptioned. */ + uint32_t exceptioned; /**< Number of exceptioned packets. */ + uint32_t freed; /**< Number of freed packets. */ +}; + +/** + * nss_gre_redir_lag_us_cmn_db_sync_stats + * Upstream database statistics. + */ +struct nss_gre_redir_lag_us_cmn_db_sync_stats { + uint32_t add_attempt; /**< Add hash attempts. */ + uint32_t add_success; /**< Add hash success. */ + uint32_t add_fail_table_full; /**< Add hash failed due to full table. */ + uint32_t add_fail_exists; /**< Add hash failed as entry already exists. */ + uint32_t del_attempt; /**< Delete hash attempts. */ + uint32_t del_success; /**< Delete hash success. */ + uint32_t del_fail_not_found; /**< Delete hash failed as entry not found in hash table. */ +}; + +/** + * nss_gre_redir_lag_us_tunnel_hash_node_stats + * Hash statistics for GRE redirect LAG. + */ +struct nss_gre_redir_lag_us_tunnel_hash_node_stats { + uint64_t hits; /**< Number of hits on this hash entry. */ + uint32_t if_num; /**< GRE redirect interface number. */ + uint16_t src_mac[ETH_ALEN / 2]; /**< Source MAC address. */ + uint16_t dest_mac[ETH_ALEN / 2]; /**< Destination MAC address. */ +}; + +/** + * nss_gre_redir_lag_us_hash_stats_query_msg + * Hash statistics synchronization message. + */ +struct nss_gre_redir_lag_us_hash_stats_query_msg { + /* + * Request. + * Hash stats request has starting index of hash entry. + * Request is initiated by driver periodically. + */ + uint16_t db_entry_idx; /**< Starting index of request. */ + + /* + * Response. + * Response contains count of hash entries. It also has next field + * which used as the request index in subsequent request by caller. + */ + uint16_t db_entry_next; /**< Next index to be requested. */ + uint16_t count; /**< Number of hash entries in the message. */ + uint16_t reserved; /**< Reserved. */ + struct nss_gre_redir_lag_us_tunnel_hash_node_stats hstats[NSS_GRE_REDIR_LAG_US_MAX_HASH_PER_MSG]; + /**< Array of hash table entries. */ +}; + +/** + * nss_gre_redir_lag_us_cmn_sync_stats_msg + * Upstream statistics synchronization message. + */ +struct nss_gre_redir_lag_us_cmn_sync_stats_msg { + struct nss_cmn_node_stats node_stats; /**< Common node statistics. */ + struct nss_gre_redir_lag_us_cmn_sync_stats us_stats; /**< Upstream statistics. */ + struct nss_gre_redir_lag_us_cmn_db_sync_stats db_stats; /**< Common hash statistics. */ +}; + +/** + *nss_gre_redir_lag_us_msg + * GRE redirect LAG upstream messages. + */ +struct nss_gre_redir_lag_us_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /* + * Payload of a GRE redirect LAG message. + */ + union { + struct nss_gre_redir_lag_us_config_msg config_us; /**< Upstream configuration message. */ + struct nss_gre_redir_lag_us_add_hash_node_msg add_hash; /**< Add hash entry. */ + struct nss_gre_redir_lag_us_del_hash_node_msg del_hash; /**< Delete hash entry. */ + struct nss_gre_redir_lag_us_query_hash_node_msg query_hash; /**< Hash entry query message. */ + struct nss_gre_redir_lag_us_cmn_sync_stats_msg us_sync_stats; /**< Upstream statistics. */ + struct nss_gre_redir_lag_us_hash_stats_query_msg hash_stats; /**< Hash statistics message. */ + } msg; /**< GRE redirect LAG upstream message payload. */ +}; + +/** + * nss_gre_redir_lag_us_cmn_stats + * GRE redirect LAG upstream statistics. + */ +struct nss_gre_redir_lag_us_cmn_stats { + uint64_t amsdu_pkts; /**< Number of AMSDU packets seen. */ + uint64_t amsdu_pkts_enqueued; /**< Number of AMSDU packets enqueued. */ + uint64_t amsdu_pkts_exceptioned; /**< Number of AMSDU packets exceptioned. */ + uint64_t exceptioned; /**< Number of exceptioned packets. */ + uint64_t freed; /**< Freed packets when equeue to NSS to host fails. */ +}; + +/** + * nss_gre_redir_lag_us_cmn_db_stats + * Upstream database statistics. + */ +struct nss_gre_redir_lag_us_cmn_db_stats { + uint64_t add_attempt; /**< Add hash attempts. */ + uint64_t add_success; /**< Add hash success. */ + uint64_t add_fail_table_full; /**< Add hash failed due to full table. */ + uint64_t add_fail_exists; /**< Add hash failed as entry already exists. */ + uint64_t del_attempt; /**< Delete hash attempts. */ + uint64_t del_success; /**< Delete hash success. */ + uint64_t del_fail_not_found; /**< Delete hash failed as entry not found in hash table. */ +}; + +/** + * nss_gre_redir_lag_us_tunnel_stats + * Upstream tunnel node statistics. + */ +struct nss_gre_redir_lag_us_tunnel_stats { + uint64_t rx_packets; /**< Received packets. */ + uint64_t rx_bytes; /**< Received bytes. */ + uint64_t tx_packets; /**< Transmit packets. */ + uint64_t tx_bytes; /**< Transmit bytes. */ + uint64_t rx_dropped[NSS_MAX_NUM_PRI]; /**< Packets dropped on receive due to queue full. */ + struct nss_gre_redir_lag_us_cmn_stats us_stats; /**< Common node statistics. */ + struct nss_gre_redir_lag_us_cmn_db_stats db_stats; /**< Common hash statistics. */ +}; + +/** + * nss_gre_redir_lag_ds_add_sta_msg + * Message to add station in LAG deployment. + */ +struct nss_gre_redir_lag_ds_add_sta_msg { + uint16_t mac[ETH_ALEN / 2]; /**< Station MAC address. */ + uint8_t reorder_type; /**< Reorder type for downstream. */ +}; + +/** + * nss_gre_redir_lag_ds_delete_sta_msg + * Message to delete station in LAG deployment. + */ +struct nss_gre_redir_lag_ds_delete_sta_msg { + uint16_t mac[ETH_ALEN / 2]; /**< Station MAC address. */ +}; + +/** + * nss_gre_redir_lag_ds_update_sta_msg + * Message to update station. + */ +struct nss_gre_redir_lag_ds_update_sta_msg { + uint16_t mac[ETH_ALEN / 2]; /**< Station MAC address. */ + uint8_t reorder_type; /**< Reorder type for downstream. */ +}; + +/** + * nss_gre_redir_lag_ds_stats + * GRE redirect link aggregation downstream statistics structure. + */ +struct nss_gre_redir_lag_ds_stats { + uint32_t dst_invalid; /**< Invalid destination packets. */ + uint32_t exception_cnt; /**< Exception count. */ +}; + +/** + * nss_gre_redir_lag_ds_sync_stats_msg + * Downstream statistics synchronization message. + */ +struct nss_gre_redir_lag_ds_sync_stats_msg { + struct nss_cmn_node_stats node_stats; /**< Common node statistics. */ + struct nss_gre_redir_lag_ds_stats ds_stats; /**< GRE redirect LAG downstream statistics. */ +}; + +/** + *nss_gre_redir_lag_ds_msg + * GRE redirect LAG downstream messages. + */ +struct nss_gre_redir_lag_ds_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a GRE redirect LAG downstream message. + */ + union { + struct nss_gre_redir_lag_ds_add_sta_msg add_sta; /**< Add station entry. */ + struct nss_gre_redir_lag_ds_delete_sta_msg del_sta; /**< Delete station entry. */ + struct nss_gre_redir_lag_ds_update_sta_msg update_sta; /**< Station entry update message. */ + struct nss_gre_redir_lag_ds_sync_stats_msg ds_sync_stats; /**< Downstream statistics. */ + } msg; /**< GRE redirect LAG downstream message payload. */ +}; + +/** + * nss_gre_redir_lag_ds_tun_stats + * Downstream statistics. + */ +struct nss_gre_redir_lag_ds_tun_stats { + uint64_t rx_packets; /**< Received packets. */ + uint64_t rx_bytes; /**< Received bytes. */ + uint64_t tx_packets; /**< Transmit packets. */ + uint64_t tx_bytes; /**< Transmit bytes. */ + uint64_t rx_dropped[NSS_MAX_NUM_PRI]; /**< Packets dropped on receive due to queue full. */ + uint64_t dst_invalid; /**< Packets that do not have a valid destination. */ + uint64_t exception_cnt; /**< Packets that are exceptioned to host. */ + uint32_t ifnum; /**< NSS interface number. */ + bool valid; /**< Valid flag. */ +}; + +/** + * Callback function for receiving GRE redirect LAG upstream data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_gre_redir_lag_us_data_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * Callback function for receiving GRE redirect LAG downstream data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_gre_redir_lag_ds_data_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + + /** + * Callback function for receiving GRE redirect LAG upstream messages. + * + * @datatypes + * nss_cmn_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_gre_redir_lag_us_msg_callback_t)(void *app_data, struct nss_cmn_msg *msg); + + /** + * Callback function for receiving GRE redirect LAG downstream messages. + * + * @datatypes + * nss_cmn_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_gre_redir_lag_ds_msg_callback_t)(void *app_data, struct nss_cmn_msg *msg); + +/** + * nss_gre_redir_lag_us_alloc_and_register_node + * Allocates and registers GRE redirect upstream LAG node. + * + * @datatypes + * net_device \n + * nss_gre_redir_lag_us_data_callback_t \n + * nss_gre_redir_lag_us_msg_callback_t + * + * @param[in] dev Net device pointer. + * @param[in] cb_func_data Data callback function. + * @param[in] cb_func_msg Message callback function. + * @param[in] app_ctx Application context for notify callback. + * + * @return + * Interface number if allocation and registration is succesful, else -1. + */ +extern int nss_gre_redir_lag_us_alloc_and_register_node(struct net_device *dev, + nss_gre_redir_lag_us_data_callback_t cb_func_data, + nss_gre_redir_lag_us_msg_callback_t cb_func_msg, void *app_ctx); + +/** + * nss_gre_redir_lag_ds_alloc_and_register_node + * Allocates and registers GRE redirect downstream LAG node. + * + * @datatypes + * net_device \n + * nss_gre_redir_lag_ds_data_callback_t \n + * nss_gre_redir_lag_ds_msg_callback_t + * + * @param[in] dev Net device pointer. + * @param[in] cb_func_data Data callback function. + * @param[in] cb_func_msg Message callback function. + * @param[in] app_ctx Application context for notify callback. + * + * @return + * Interface number if allocation and registration is succesful, else -1. + */ +extern int nss_gre_redir_lag_ds_alloc_and_register_node(struct net_device *dev, + nss_gre_redir_lag_ds_data_callback_t cb_func_data, + nss_gre_redir_lag_ds_msg_callback_t cb_func_msg, void *app_data); + +/** + * nss_gre_redir_lag_us_configure_node + * Configures LAG upstream node. + * + * @datatypes + * nss_gre_redir_lag_us_config_msg + * + * @param[in] ifnum NSS interface number. + * @param[in] ngluc Pointer to LAG upstream node configuration message. + * + * @return + * True if successful, else false. + */ +extern bool nss_gre_redir_lag_us_configure_node(uint32_t ifnum, + struct nss_gre_redir_lag_us_config_msg *ngluc); + +/** + * nss_gre_redir_lag_us_unregister_and_dealloc + * Deregister and deallocate GRE redirect upstream node. + * + * @param[in] if_num NSS interface number. + * + * @return + * Error code. + * + * @dependencies + * The GRE redirect LAG interface must have been previously registered. + */ +extern enum nss_gre_redir_lag_err_types nss_gre_redir_lag_us_unregister_and_dealloc(uint32_t if_num); + +/** + * nss_gre_redir_lag_ds_unregister_and_dealloc + * Deregisters and dealloc GRE redirect LAG downstream interface from the NSS. + * + * @param[in] if_num NSS interface number. + * + * @return + * Error code. + * + * @dependencies + * The GRE redirect LAG interface must have been previously registered. + */ +extern enum nss_gre_redir_lag_err_types nss_gre_redir_lag_ds_unregister_and_dealloc(uint32_t if_num); + +/** + * nss_gre_redir_lag_us_tx_msg + * Sends GRE redirect upstream LAG messages asynchronously. + * + * @datatypes + * nss_ctx_instance \n + * nss_gre_redir_lag_us_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_gre_redir_lag_us_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_gre_redir_lag_us_msg *msg); + +/** + * nss_gre_redir_lag_ds_tx_msg + * Sends GRE redirect downstream LAG messages asynchronously. + * + * @datatypes + * nss_ctx_instance \n + * nss_gre_redir_lag_ds_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_gre_redir_lag_ds_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_gre_redir_lag_ds_msg *msg); + +/** + * nss_gre_redir_lag_us_tx_buf + * Sends packets to GRE Redirect LAG upstream node. + * + * @datatypes + * nss_ctx_instance \n + * sk_buff + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] os_buf Pointer to the OS buffer (e.g., skbuff). + * @param[in] if_num Tunnel interface number. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_gre_redir_lag_us_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf, + uint32_t if_num); + +/** + * nss_gre_redir_lag_ds_tx_buf + * Sends packets to GRE Redirect LAG downstream node. + * + * @datatypes + * nss_ctx_instance \n + * sk_buff + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] os_buf Pointer to the OS buffer (e.g., skbuff). + * @param[in] if_num Tunnel interface number. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_gre_redir_lag_ds_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf, + uint32_t if_num); + +/** + * nss_gre_redir_lag_us_tx_msg_sync + * Sends upstream LAG messages to NSS firmware synchronously. + * + * @datatypes + * nss_ctx_instance \n + * nss_gre_redir_lag_us_msg + * + * @param[in] nss_ctx NSS core context. + * @param[in] ngrm Pointer to GRE redirect upstream LAG message data. + * + * @return + * Status of Tx operation. + */ +extern nss_tx_status_t nss_gre_redir_lag_us_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_redir_lag_us_msg *ngrm); + +/** + * nss_gre_redir_lag_ds_tx_msg_sync + * Sends downstream LAG messages to NSS firmware synchronously. + * + * @datatypes + * nss_ctx_instance \n + * nss_gre_redir_lag_ds_msg + * + * @param[in] nss_ctx NSS core context. + * @param[in] ngrm Pointer to GRE redirect downstream LAG message data. + * + * @return + * Status of Tx operation. + */ +extern nss_tx_status_t nss_gre_redir_lag_ds_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_redir_lag_ds_msg *ngrm); + +/** + * nss_gre_redir_lag_us_get_cmn_stats + * Fetches common node statistics for upstream GRE Redir LAG. + * + * @datatypes + * nss_gre_redir_lag_us_tunnel_stats + * + * @param[out] cmn_stats Pointer to common node statistics structure. + * @param[in] index Index to fetch statistics from. + * + * @return + * True if successful, else false. + */ +extern bool nss_gre_redir_lag_us_get_cmn_stats(struct nss_gre_redir_lag_us_tunnel_stats *cmn_stats, uint32_t index); + +/** + * nss_gre_redir_lag_ds_get_stats + * Fetches common node statistics for downstream GRE Redir LAG. + * + * @datatypes + * nss_gre_redir_lag_ds_tun_stats + * + * @param[out] cmn_stats Pointer to common node statistics structure. + * @param[in] index Index to fetch statistics from. + * + * @return + * True if successful, else false. + */ +extern bool nss_gre_redir_lag_ds_get_cmn_stats(struct nss_gre_redir_lag_ds_tun_stats *cmn_stats, uint32_t index); + +/** + * nss_gre_redir_lag_us_get_context + * Gets the GRE redirect LAG upstream context. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_gre_redir_lag_us_get_context(void); + +/** + * nss_gre_redir_lag_ds_get_context + * Gets the GRE redirect LAG downstream context. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_gre_redir_lag_ds_get_context(void); + +/** + * @} + */ + +#endif /* __NSS_GRE_REDIR_LAG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_gre_redir_mark.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_gre_redir_mark.h new file mode 100644 index 000000000..a627523ad --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_gre_redir_mark.h @@ -0,0 +1,281 @@ +/* + ************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_gre_redir_mark.h + * NSS GRE Redirect mark interface definitions. + */ + +#ifndef __NSS_GRE_REDIR_MARK_H +#define __NSS_GRE_REDIR_MARK_H + +#define NSS_GRE_REDIR_MARK_HLOS_MAGIC 0xaade /**< Metadata magic set by HLOS. */ +#define NSS_GRE_REDIR_MARK_NSS_MAGIC 0xaadf /**< Metadata magic set by NSS. */ + +/** + * nss_gre_redir_mark messages + * Message types for GRE redirect mark requests and responses. + */ +enum nss_gre_redir_mark_msg_types { + NSS_GRE_REDIR_MARK_REG_CB_MSG, /**< Register callback configuration message. */ + NSS_GRE_REDIR_MARK_STATS_SYNC_MSG, /**< Statistics synchronization message. */ + NSS_GRE_REDIR_MARK_MSG_MAX, /**< Maximum message type. */ +}; + +/** + * nss_gre_redir_mark errors + * Error codes for GRE redirect mark configuration message. + */ +enum nss_gre_redir_mark_error_types { + NSS_GRE_REDIR_MARK_ERROR_NONE, /**< Configuration successful. */ + NSS_GRE_REDIR_MARK_ERROR_INV_IF_NUM, /**< Invalid interface number for callback registration. */ + NSS_GRE_REDIR_MARK_ERROR_INV_ETH_TYPE, /**< Invalid Ethernet type for the destination interface. */ + NSS_GRE_REDIR_MARK_ERROR_TYPE_MAX +}; + +/** + * nss_gre_redir_mark_metadata + * HLOS to NSS per packet downstream metadata. + */ +struct nss_gre_redir_mark_metadata { + uint32_t dst_ifnum; /**< Destination Tx interface number. */ + uint8_t wifi_tid; /**< TID value. */ + uint8_t app_id; /**< Application ID. */ + uint16_t hw_hash_idx; /**< Hardware AST hash index value. */ + uint32_t tx_status; /**< Tx status. */ + uint16_t offset; /**< Buffer offset from the metadata. */ + uint16_t magic; /**< Metadata magic. */ +}; + +/** + * nss_gre_redir_mark_stats + * GRE redirect mark statistics. + */ +struct nss_gre_redir_mark_stats_sync_msg { + struct nss_cmn_node_stats node_stats; /**< Common node statistics. */ + uint32_t hlos_magic_fail; /**< HLOS magic fail count. */ + uint32_t invalid_dst_drop; /**< Invalid Tx interface drop count. */ + uint32_t dst_enqueue_success; /**< Next egress interface enqueue success count. */ + uint32_t dst_enqueue_drop; /**< Next egress interface enqueue drop count. */ + uint32_t inv_appid; /**< Invalid application ID for the Tx completion packets. */ + uint32_t headroom_unavail; /**< Packet headroom unavailable to write metadata. */ + uint32_t tx_completion_success; /**< Tx completion host enqueue success count. */ + uint32_t tx_completion_drop; /**< Tx completion host enqueue drop count. */ +}; + +/** + * nss_gre_redir_mark_register_cb_msg + * Tx completion function register configuration message. + */ +struct nss_gre_redir_mark_register_cb_msg { + uint32_t nss_if_num; /**< NSS Tx interface number on which callback needs to be registered. */ +}; + +/** + * nss_gre_redir_mark_msg + * Structure that describes the interface message. + */ +struct nss_gre_redir_mark_msg { + struct nss_cmn_msg cm; /**< Common message. */ + + /** + * Payload of a GRE redirect mark message. + */ + union { + struct nss_gre_redir_mark_register_cb_msg reg_cb_msg; + /**< Configuration message to register for callback on completion. */ + struct nss_gre_redir_mark_stats_sync_msg stats_sync; + /**< Mark node statistics synchronization. */ + } msg; /**< Message payload for GRE redirect mark messages exchanged with NSS core. */ +}; + +/** + * Callback function for receiving GRE redirect mark data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_gre_redir_mark_data_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * Callback function for receiving GRE redirect mark messages. + * + * @datatypes + * nss_cmn_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_gre_redir_mark_msg_callback_t)(void *app_data, struct nss_cmn_msg *msg); + +/** + * nss_gre_redir_mark_unregister_if + * Deregisters a GRE redirect mark interface from the NSS. + * + * @param[in] if_num GRE redirect mark interface number. + * + * @return + * None. + * + * @dependencies + * The GRE redirect mark interface must have been previously registered. + * + * @return + * True if successful, else false. + */ +extern bool nss_gre_redir_mark_unregister_if(uint32_t if_num); + +/** + * nss_gre_redir_mark_tx_buf + * Sends data buffers to NSS firmware asynchronously. + * + * @datatypes + * nss_ctx_instance \n + * sk_buff + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] os_buf Pointer to the OS buffer (e.g. skbuff). + * @param[in] if_num GRE redirect mark interface number. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_gre_redir_mark_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf, + uint32_t if_num); + +/** + * nss_gre_redir_mark_reg_cb + * Configure a callback on VAP for downstream application flows. + * + * @datatypes + * nss_gre_redir_mark_register_cb_msg + * + * @param[in] ifnum NSS interface number. + * @param[in] ngrcm Downstream application callback registration message. + * + * @return + * Status of Tx operation. + */ +extern nss_tx_status_t nss_gre_redir_mark_reg_cb(int ifnum, + struct nss_gre_redir_mark_register_cb_msg *ngrcm); + +/** + * nss_gre_redir_mark_tx_msg + * Sends GRE redirect mark messages. + * + * @datatypes + * nss_ctx_instance \n + * nss_gre_redir_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_gre_redir_mark_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_gre_redir_mark_msg *msg); + +/** + * nss_gre_redir_mark_tx_msg_sync + * Sends messages to NSS firmware synchronously. + * + * @datatypes + * nss_ctx_instance \n + * nss_gre_redir_mark_msg + * + * @param[in] nss_ctx NSS core context. + * @param[in] ngrm Pointer to GRE redirect mark message data. + * + * @return + * Status of Tx operation. + */ +extern nss_tx_status_t nss_gre_redir_mark_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_redir_mark_msg *ngrm); + +/** + * nss_gre_redir_mark_get_stats + * Gets GRE redirect mark statistics. + * + * @datatypes + * nss_gre_redir_mark_stats + * + * @param[out] stats Pointer to the memory address, which must be large enough to + * hold all the statistics. + * + * @return + * TRUE or FALSE. + */ +extern bool nss_gre_redir_mark_get_stats(void *stats); + +/** + * nss_gre_redir_alloc_and_register_node + * Registers GRE redirect mark static node with NSS. + * + * @datatypes + * net_device \n + * nss_gre_redir_mark_data_callback_t \n + * nss_gre_redir_mark_msg_callback_t + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] if_num NSS interface number. + * @param[in] cb_func_data Callback for the data. + * @param[in] cb_func_msg Callback for the message. + * @param[in] features Data socket buffer types supported by this interface. + * + * @return + * NSS interface number allocated. + */ +extern struct nss_ctx_instance *nss_gre_redir_mark_register_if(struct net_device *netdev, uint32_t if_num, + nss_gre_redir_mark_data_callback_t cb_func_data, nss_gre_redir_mark_msg_callback_t cb_func_msg, + uint32_t features); + +/** + * nss_gre_redir_mark_get_context + * Gets the GRE redirect mark context. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_gre_redir_mark_get_context(void); + +/** + * nss_gre_redir_mark_get_dentry + * Returns directory entry created in debug filesystem for statistics. + * + * @return + * Pointer to created directory entry for GRE redirect mark. + */ +extern struct dentry *nss_gre_redir_mark_get_dentry(void); + +/* + * nss_gre_redir_mark_get_device + * Gets the original device from probe. + * + * @return + * Pointer to the device. + */ +extern struct device *nss_gre_redir_mark_get_device(void); + +/** + * @} + */ + +#endif /* __NSS_GRE_REDIR_MARK_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_gre_tunnel.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_gre_tunnel.h new file mode 100644 index 000000000..2f4ee1849 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_gre_tunnel.h @@ -0,0 +1,354 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2018,2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_gre_tunnel.h + * NSS GRE Tunnel interface definitions. + */ + +#ifndef __NSS_GRE_TUNNEL_H +#define __NSS_GRE_TUNNEL_H + +/** + * @addtogroup nss_gre_tunnel_subsystem + * @{ + */ + +/** + * Maximum number of supported GRE tunnel sessions. + */ +#define NSS_MAX_GRE_TUNNEL_SESSIONS 16 + +/** + * nss_gre_tunnel_message_types + * Message types for a GRE tunnel rule. + */ +enum nss_gre_tunnel_message_types { + NSS_GRE_TUNNEL_MSG_CONFIGURE, + NSS_GRE_TUNNEL_MSG_SESSION_DESTROY, + NSS_GRE_TUNNEL_MSG_STATS, + NSS_GRE_TUNNEL_MSG_CONFIGURE_DI_TO_WLAN_ID, + NSS_GRE_TUNNEL_MSG_INQUIRY, + NSS_GRE_TUNNEL_MSG_MAX, +}; + +/** + * nss_gre_tunnel_encrypt_types + * Encryption types for a GRE tunnel. + */ +enum nss_gre_tunnel_encrypt_types { + NSS_GRE_TUNNEL_ENCRYPT_NONE, + NSS_GRE_TUNNEL_ENCRYPT_AES128_CBC, + NSS_GRE_TUNNEL_ENCRYPT_AES256_CBC, + NSS_GRE_TUNNEL_ENCRYPT_MAX, +}; + +/** + * nss_gre_tunnel_mode_types + * Mode types for a GRE tunnel. + */ +enum nss_gre_tunnel_mode_types { + NSS_GRE_TUNNEL_MODE_GRE, + NSS_GRE_TUNNEL_MODE_GRE_UDP, + NSS_GRE_TUNNEL_MODE_MAX, +}; + +/** + * nss_gre_tunnel_ip_types + * IP types for a GRE tunnel. + */ +enum nss_gre_tunnel_ip_types { + NSS_GRE_TUNNEL_IP_IPV4, + NSS_GRE_TUNNEL_IP_IPV6, + NSS_GRE_TUNNEL_IP_MAX, +}; + +/** + * nss_gre_tunnel_error_types + * Error types for a GRE tunnel. + */ +enum nss_gre_tunnel_error_types { + NSS_GRE_TUNNEL_ERR_UNKNOWN_MSG = 1, + NSS_GRE_TUNNEL_ERR_IF_INVALID = 2, + NSS_GRE_TUNNEL_ERR_CPARAM_INVALID = 3, + NSS_GRE_TUNNEL_ERR_MODE_INVALID = 4, + NSS_GRE_TUNNEL_ERR_ENCRYPT_INVALID = 5, + NSS_GRE_TUNNEL_ERR_IP_INVALID = 6, + NSS_GRE_TUNNEL_ERR_ENCRYPT_IDX_INVALID = 7, + NSS_GRE_TUNNEL_ERR_NOMEM = 8, + NSS_GRE_TUNNEL_ERR_PROTO_TEB_INVALID = 9, + NSS_GRE_TUNNEL_ERR_SIBLING_IF = 10, + NSS_GRE_TUNNEL_ERR_CRYPTO_NODE_ID = 11, + NSS_GRE_TUNNEL_ERR_RPS = 12, + NSS_GRE_TUNNEL_ERR_DI_INVALID = 13, + NSS_GRE_TUNNEL_ERR_MAX, +}; + +/** + * nss_gre_tunnel_di_to_wlan_id + * Dynamic interface to WLAN ID message structure. + */ +struct nss_gre_tunnel_di_to_wlan_id { + uint32_t dynamic_interface_num; /**< Dynamic interface number. */ + uint16_t wlan_id; /**< WLAN ID number. */ + uint16_t fwd_policy; /**< Forward policy bits. */ +}; + +/** + * nss_gre_tunnel_configure + * Message information for configuring a GRE tunnel. + */ +struct nss_gre_tunnel_configure { + uint32_t mh_version; /**< Meta header version. */ + uint8_t gre_mode; /**< GRE or GRE plus UDP. */ + uint8_t ip_type; /**< IPv4 or IPv6. */ + uint16_t encrypt_type; /**< Encryption type. */ + uint32_t src_ip[4]; /**< Source IPv4 or IPv6 address. */ + uint32_t dest_ip[4]; /**< Destination IPv4 or IPv6 address. */ + uint16_t src_port; /**< GRE plus UDP only for the source. */ + uint16_t dest_port; /**< GRE plus UDP only for the destination. */ + uint32_t crypto_node_id; /**< Cryto node identifier. */ + uint32_t crypto_idx_encrypt; /**< Crypto index for encryption. */ + uint32_t crypto_idx_decrypt; /**< Crypto index for decryption. */ + uint32_t word0; /**< Word0 header. */ + uint8_t iv_val[16]; /**< Initialization vector value. */ + uint32_t sibling_if; /**< Sibling interface number. */ + uint8_t ttl; /**< Time-to-live value of the IP header. */ + int8_t rps; /**< Steer packets to host core. */ + uint16_t reserved; /**< Reserved space. */ + uint32_t word1; /**< Word1 header. */ + uint32_t word2; /**< Word2 header. */ + uint32_t word3; /**< Word3 header. */ +}; + +/** + * nss_gre_tunnel_stats + * Message statistics for a GRE tunnel. + */ +struct nss_gre_tunnel_stats { + struct nss_cmn_node_stats node_stats; /**< Common node statistics. */ + uint32_t rx_malformed; /**< Malformed packet was received. */ + uint32_t rx_invalid_prot; /**< Invalid protocol was received. */ + uint32_t decap_queue_full; /**< Decapsulation queue is full. */ + uint32_t rx_single_rec_dgram; /**< Single fragment was received. */ + uint32_t rx_invalid_rec_dgram; /**< Invalid fragment was received. */ + uint32_t buffer_alloc_fail; /**< Buffer memory allocation failed. */ + uint32_t buffer_copy_fail; /**< Buffer memory copy failed. */ + uint32_t outflow_queue_full; /**< Outflow queue is full. */ + uint32_t rx_dropped_hroom; + /**< Packets dropped because of insufficent headroom. */ + uint32_t rx_cbuf_alloc_fail; + /**< Rx crypto buffer allocation failed. */ + uint32_t rx_cenqueue_fail; /**< Rx enqueue-to-crypto failed. */ + uint32_t rx_decrypt_done; /**< Rx decryption is complete. */ + uint32_t rx_forward_enqueue_fail; /**< Rx forward enqueue failed. */ + uint32_t tx_cbuf_alloc_fail; + /**< Rx crypto buffer allocation failed. */ + uint32_t tx_cenqueue_fail; /**< Tx enqueue-to-crypto failed. */ + uint32_t rx_dropped_troom; + /**< Packets dropped because of insufficent tailroom. */ + uint32_t tx_forward_enqueue_fail; /**< Tx forward enqueue failed. */ + uint32_t tx_cipher_done; /**< Tx cipher is complete. */ + uint32_t crypto_nosupp; + /**< Error count for non-supported crypto packets. */ + uint32_t rx_dropped_mh_ver; /**< Rx drop: bad meta header. */ + uint32_t rx_unaligned_pkt; /**< Counter for unaligned packets. */ +#if defined(NSS_HAL_IPQ807x_SUPPORT) + uint32_t crypto_resp_error[NSS_CRYPTO_CMN_RESP_ERROR_MAX]; + /** Crypto response errors. */ +#endif +}; + +/** + * nss_gre_tunnel_msg + * Data for sending and receiving GRE tunnel messages. + */ +struct nss_gre_tunnel_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a GRE tunnel message. + */ + union { + struct nss_gre_tunnel_configure configure; /**< Tunnel configuration data. */ + struct nss_gre_tunnel_stats stats; /**< Tunnel statistics. */ + struct nss_gre_tunnel_di_to_wlan_id dtwi; /**< Tunnel dynamic interface number to WLAN ID mapping. */ + } msg; /**< Message payload. */ +}; + +/** + * Callback function for receiving GRE tunnel messages. + * + * @datatypes + * nss_gre_tunnel_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_gre_tunnel_msg_callback_t)(void *app_data, struct nss_gre_tunnel_msg *msg); + +/** + * Callback function for receiving GRE tunnel session data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_gre_tunnel_data_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * nss_gre_tunnel_tx_buf + * Sends a GRE tunnel packet. + * + * @datatypes + * sk_buff \n + * nss_ctx_instance + * + * @param[in] skb Pointer to the data socket buffer. + * @param[in] if_num Tunnel interface number. + * @param[in] nss_ctx Pointer to the NSS context. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_gre_tunnel_tx_buf(struct sk_buff *skb, uint32_t if_num, struct nss_ctx_instance *nss_ctx); + +/** + * nss_gre_tunnel_tx_msg + * Sends a GRE tunnel message. + * + * @datatypes + * nss_ctx_instance \n + * nss_gre_tunnel_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_gre_tunnel_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_gre_tunnel_msg *msg); + +/** + * nss_gre_tunnel_tx_msg_sync + * Sends a GRE tunnel message synchronously. + * + * @datatypes + * nss_ctx_instance \n + * nss_gre_tunnel_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_gre_tunnel_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_tunnel_msg *msg); + +/** + * nss_gre_tunnel_msg_init + * Initalizes a GRE tunnel message. + * + * @datatypes + * nss_gre_tunnel_msg + * + * @param[in] ngtm Pointer to the tunnel message. + * @param[in] if_num Tunnel interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Pointer to the message callback. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_gre_tunnel_msg_init(struct nss_gre_tunnel_msg *ngtm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data); + +/** + * nss_gre_tunnel_get_ctx + * Returns the NSS context. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_gre_tunnel_get_ctx(void); + +/** + * nss_gre_tunnel_register_if + * Registers a network device with the NSS for sending and receiving tunnel + * messages. + * + * @datatypes + * nss_gre_tunnel_data_callback_t \n + * nss_gre_tunnel_msg_callback_t \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] cb Callback function for the message. + * @param[in] ev_cb Callback for the GRE tunnel message. + * @param[in] netdev Pointer to the associated network device. + * @param[in] features Data socket buffer types supported by this interface. + * @param[in] app_ctx Pointer to the application context. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_gre_tunnel_register_if(uint32_t if_num, + nss_gre_tunnel_data_callback_t cb, + nss_gre_tunnel_msg_callback_t ev_cb, + struct net_device *netdev, + uint32_t features, + void *app_ctx); + +/** + * nss_gre_tunnel_unregister_if + * Deregisters a network device from the NSS. + * + * @param[in] if_num NSS interface number. + * + * @return + * None. + * + * @dependencies + * The network device must have been previously registered. + */ +extern void nss_gre_tunnel_unregister_if(uint32_t if_num); + +/** + * nss_gre_tunnel_inquiry() + * Inquiry if a GRE tunnel has been established in NSS FW. + * + * @param[in] inquiry_info Query parameters similar to creation parameters. + * @param[in] cb Pointer to the message callback. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * Status of the Tx operation + */ +extern nss_tx_status_t nss_gre_tunnel_inquiry( + struct nss_gre_tunnel_configure *inquiry_info, + nss_gre_tunnel_msg_callback_t cb, void *app_data); + +/** + * @} + */ + +#endif /* __NSS_GRE_TUNNEL_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_if.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_if.h new file mode 100644 index 000000000..bba721df3 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_if.h @@ -0,0 +1,378 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_if.h + * NSS interface definitions. + */ + +#ifndef __NSS_IF_H +#define __NSS_IF_H + +#define NSS_IF_TX_TIMEOUT 3000 /* 3 Seconds */ + +/** + * @addtogroup nss_driver_subsystem + * @{ + */ + +/** + * nss_if_message_types + * Message types for the NSS interface. + */ +enum nss_if_message_types { + NSS_IF_OPEN, + NSS_IF_CLOSE, + NSS_IF_LINK_STATE_NOTIFY, + NSS_IF_MTU_CHANGE, + NSS_IF_MAC_ADDR_SET, + NSS_IF_STATS, + NSS_IF_ISHAPER_ASSIGN, + NSS_IF_BSHAPER_ASSIGN, + NSS_IF_ISHAPER_UNASSIGN, + NSS_IF_BSHAPER_UNASSIGN, + NSS_IF_ISHAPER_CONFIG, + NSS_IF_BSHAPER_CONFIG, + NSS_IF_PAUSE_ON_OFF, + NSS_IF_VSI_ASSIGN, + NSS_IF_VSI_UNASSIGN, + NSS_IF_SET_NEXTHOP, + NSS_IF_SET_IGS_NODE, + NSS_IF_CLEAR_IGS_NODE, + NSS_IF_RESET_NEXTHOP, + NSS_IF_MAX_MSG_TYPES = 9999, +}; + +/** + * nss_if_error_types + * Error types for the NSS interface. + */ +enum nss_if_error_types { + NSS_IF_ERROR_NO_ISHAPERS, + NSS_IF_ERROR_NO_BSHAPERS, + NSS_IF_ERROR_NO_ISHAPER, + NSS_IF_ERROR_NO_BSHAPER, + NSS_IF_ERROR_ISHAPER_OLD, + NSS_IF_ERROR_BSHAPER_OLD, + NSS_IF_ERROR_ISHAPER_CONFIG_FAILED, + NSS_IF_ERROR_BSHAPER_CONFIG_FAILED, + NSS_IF_ERROR_TYPE_UNKNOWN, + NSS_IF_ERROR_TYPE_EOPEN, + NSS_IF_ERROR_TYPE_INVALID_MTU, + NSS_IF_ERROR_TYPE_INVALID_MAC_ADDR, + NSS_IF_ERROR_TYPE_VSI_NOT_MATCH, + NSS_IF_ERROR_TYPE_VSI_REASSIGN, + NSS_IF_ERROR_TYPE_VSI_INVALID, + NSS_IF_ERROR_TYPE_MAX = 9999, +}; + +/** + * nss_if_data_align + * Data alignment modes for the NSS interface. + */ +enum nss_if_data_align { + NSS_IF_DATA_ALIGN_2BYTE = 0, + NSS_IF_DATA_ALIGN_4BYTE = 2, +}; + +/** + * nss_if_open + * Message information for opening the NSS interface. + */ +struct nss_if_open { + uint32_t tx_desc_ring; /**< Tx descriptor ring address. */ + uint32_t rx_desc_ring; /**< Rx descriptor ring address. */ + uint32_t rx_forward_if; /**< Forward received packets to this interface. */ + uint32_t alignment_mode;/**< Header alignment mode. */ +}; + +/** + * nss_if_close + * Message information for closing the NSS interface. + */ +struct nss_if_close { + uint32_t reserved; /**< Placeholder for the structure. */ +}; + +/** + * nss_if_link_state_notify + * Link state notification sent to the NSS interface. + */ +struct nss_if_link_state_notify { + uint32_t state; + /**< Link state UP is bit 0 set. Other bits are as defined by Linux to indicate speed and duplex. */ +}; + +/** + * nss_if_mtu_change + * MTU change for the NSS interface. + */ +struct nss_if_mtu_change { + uint16_t min_buf_size; /**< Changed value for the minimum buffer size. */ +}; + +/** + * nss_if_pause_on_off + * Enables or disables a pause frame for the NSS interface. + */ +struct nss_if_pause_on_off { + uint32_t pause_on; /**< Turn the pause frame ON or OFF. */ +}; + +/** + * nss_if_mac_address_set + * MAC address setting. + */ +struct nss_if_mac_address_set { + uint8_t mac_addr[ETH_ALEN]; /**< MAC address. */ +}; + +/** + * nss_if_shaper_assign + * Shaper assignment message. + */ +struct nss_if_shaper_assign { + uint32_t shaper_id; /**< ID of the request. */ + uint32_t new_shaper_id; /**< ID of the response. */ +}; + +/** + * nss_if_shaper_unassign + * Shaper unassign message. + */ +struct nss_if_shaper_unassign { + uint32_t shaper_id; /**< ID of the request. */ +}; + +/** + * nss_if_shaper_configure + * Shaper configuration message. + */ +struct nss_if_shaper_configure { + struct nss_shaper_configure config; /**< Specific shaper message for a particular interface. */ +}; + +/** + * nss_if_vsi_assign + * VSI assignment message. + */ +struct nss_if_vsi_assign { + uint32_t vsi; /**< Virtual interface number. */ +}; + +/** + * nss_if_vsi_unassign + * VSI unassign message. + */ +struct nss_if_vsi_unassign { + uint32_t vsi; /**< Virtual interface number. */ +}; + +/** + * nss_if_set_nexthop + * Message to set nexthop for an interface. + */ +struct nss_if_set_nexthop { + uint32_t nexthop; /**< Nexthop interface number. */ +}; + +/** + * nss_if_igs_config + * Ingress shaper set/clear configure message structure. + */ +struct nss_if_igs_config { + int32_t igs_num; /**< Ingress shaper interface number. */ +}; + +/** + * nss_if_msgs + * Information for physical NSS interface command messages. + */ +union nss_if_msgs { + struct nss_if_link_state_notify link_state_notify; + /**< Link status notification. */ + struct nss_if_open open; + /**< Open the NSS interface. */ + struct nss_if_close close; + /**< Close the NSS interface. */ + struct nss_if_mtu_change mtu_change; + /**< MTU change notification. */ + struct nss_if_mac_address_set mac_address_set; + /**< MAC address setting. */ + struct nss_cmn_node_stats stats; + /**< Synchronize the satistics. */ + struct nss_if_shaper_assign shaper_assign; + /**< Assign the shaper. */ + struct nss_if_shaper_unassign shaper_unassign; + /**< Unassign the shaper. */ + struct nss_if_shaper_configure shaper_configure; + /**< Configure the shaper. */ + struct nss_if_pause_on_off pause_on_off; + /**< ON or OFF notification for a Pause frame. */ + struct nss_if_vsi_assign vsi_assign; + /**< Assign the VSI. */ + struct nss_if_vsi_unassign vsi_unassign; + /**< Remove the VSI assignment. */ + struct nss_if_set_nexthop set_nexthop; + /**< Set nexthop of interface. */ + struct nss_if_igs_config config_igs; + /**< Configure an ingress shaper interface. */ +}; + +/** + * nss_if_msg + * Data for sending and receiving base class messages for all interface types. + */ +struct nss_if_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + union nss_if_msgs msg; /**< Message payload. */ +}; + +/** + * Callback function for receiving NSS interface messages. + * + * @datatypes + * nss_if_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_if_msg_callback_t)(void *app_data, struct nss_if_msg *msg); + +/** + * Callback function for receiving NSS interface data. + * + * TODO: Adjust to pass app_data as unknown to the + * list layer and netdev/sk as known. + * + * @datatypes + * net_device \n + * sk_buff + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + */ +typedef void (*nss_if_rx_callback_t)(struct net_device *netdev, struct sk_buff *skb); + +/** + * nss_if_register + * Registers the NSS interface for sending and receiving GMAC packets and messages. + * + * @datatypes + * nss_if_rx_callback_t \n + * nss_if_msg_callback_t \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] rx_callback Receive callback for the packet. + * @param[in] msg_callback Receive callback for message. + * @param[in] if_ctx Pointer to the interface context provided in the + callback. This context must be the OS network + device context pointer (net_device in Linux). + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_if_register(uint32_t if_num, + nss_if_rx_callback_t rx_callback, + nss_if_msg_callback_t msg_callback, + struct net_device *if_ctx); + +/** + * nss_if_tx_buf + * Sends GMAC packets to a specific physical or virtual network interface. + * + * @datatypes + * nss_ctx_instance \n + * sk_buff + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] os_buf Pointer to the OS buffer (e.g., skbuff). + * @param[in] if_num Network physical or virtual interface number. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_if_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf, uint32_t if_num); + +/** + * nss_if_tx_msg + * Sends a message to the NSS interface. + * + * @datatypes + * nss_ctx_instance \n + * nss_if_msg + * + * @param[in,out] nss_ctx Pointer to the NSS context. + * @param[in] nim Pointer to the NSS interface message. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_if_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_if_msg *nim); + +/** + * nss_if_msg_sync + * Sends a message to the NSS interface and wait for the response. + * + * @datatypes + * nss_ctx_instance \n + * nss_if_msg + * + * @param[in,out] nss_ctx Pointer to the NSS context. + * @param[in] nim Pointer to the NSS interface message. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_if_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_if_msg *nim); + +/** + * nss_if_set_nexthop + * Configure the next hop for an interface. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] if_num NSS interface number. + * @param[in] nexthop NSS interface number for next hop node. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_if_set_nexthop(struct nss_ctx_instance *nss_ctx, uint32_t if_num, uint32_t nexthop); + +/** + * nss_if_reset_nexthop + * De-configure the next hop for an interface. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] if_num NSS interface number. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_if_reset_nexthop(struct nss_ctx_instance *nss_ctx, uint32_t if_num); + +/** + * @} + */ + +#endif /* __NSS_IF_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_igs.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_igs.h new file mode 100644 index 000000000..651fea4e9 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_igs.h @@ -0,0 +1,213 @@ +/* + ************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_igs.h + * NSS ingress shaper interface definitions. + */ + +#ifndef _NSS_IGS_H_ +#define _NSS_IGS_H_ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS +#ifdef CONFIG_NET_CLS_ACT +#include +#endif +#endif + +/** + * @addtogroup nss_ingress_shaper_subsystem + * @{ + */ + +/** + * Maximum number of supported ingress shaping interfaces. + */ +#define NSS_MAX_IGS_DYNAMIC_INTERFACES 8 + +/** + * nss_igs_msg_types + * Message types for ingress shaper requests and responses. + */ +enum nss_igs_msg_types { + NSS_IGS_MSG_SYNC_STATS = NSS_IF_MAX_MSG_TYPES + 1, + NSS_IGS_MSG_MAX +}; + +/** + * nss_igs_node_stats + * Ingress shaping node debug statistics structure. + */ +struct nss_igs_node_stats { + uint32_t tx_dropped; /**< Dropped post shaping. */ + uint32_t shaper_drop; /**< Dropped during shaper enqueue. */ + uint32_t ipv4_parse_fail; /**< IPv4 parse fail. */ + uint32_t ipv4_unknown_gre_type; /**< IPv4 unknown GRE type. */ + uint32_t ipv4_unknown_l4; /**< IPv4 unknown L4 type. */ + uint32_t ipv4_no_cme; /**< IPv4 connection match entry not found. */ + uint32_t ipv4_frag_initial; /**< IPv4 initial fragment. */ + uint32_t ipv4_frag_non_initial; /**< Ipv4 subsequent fragment. */ + uint32_t ipv4_malformed_udp; /**< Incomplete IPv4 UDP packet. */ + uint32_t ipv4_malformed_tcp; /**< Incomplete IPv4 TCP packet. */ + uint32_t ipv4_malformed_udpl; /**< Incomplete IPv4 UDP-Lite packet. */ + uint32_t ipv4_malformed_gre; /**< Incomplete IPv4 GRE packet. */ + uint32_t ipv6_parse_fail; /**< IPv6 parse fail. */ + uint32_t ipv6_unknown_l4; /**< IPv6 unknown L4 type. */ + uint32_t ipv6_no_cme; /**< IPv6 connection match entry not found. */ + uint32_t ipv6_frag_initial; /**< IPv6 initial fragment. */ + uint32_t ipv6_frag_non_initial; /**< Ipv6 subsequent fragment. */ + uint32_t ipv6_malformed_udp; /**< Incomplete IPv6 UDP packet. */ + uint32_t ipv6_malformed_tcp; /**< Incomplete IPv6 TCP packet. */ + uint32_t ipv6_malformed_udpl; /**< Incomplete IPv6 UDP-Lite packet. */ + uint32_t ipv6_malformed_frag; /**< Incomplete IPv6 fragment. */ + uint32_t event_no_si; /**< No shaper configured. */ + uint32_t eth_parse_fail; /**< Ethernet header parse failed. */ + uint32_t eth_unknown_type; /**< Non-IP/PPPoE ether type. */ + uint32_t pppoe_non_ip; /**< Non-IP PPPoE packet. */ + uint32_t pppoe_malformed; /**< Incomplete PPPoE packet. */ +}; + +/** + * nss_igs_stats_sync_msg + * Message information for ingress shaping synchronization statistics. + */ +struct nss_igs_stats_sync_msg { + struct nss_cmn_node_stats node_stats; /**< Common node statistics. */ + struct nss_igs_node_stats igs_stats; /**< Debug statistics for ingress shaping. */ +}; + +/** + * nss_igs_msg + * Data for sending and receiving ingress shaper messages. + */ +struct nss_igs_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a ingress shaper message. + */ + union { + union nss_if_msgs if_msg; + /**< NSS interface base message. */ + struct nss_igs_stats_sync_msg stats; + /**< Statistics message to host. */ + } msg; /**< Message payload. */ +}; + +/** + * Callback function for receiving ingress shaper messages. + * + * @datatypes + * nss_cmn_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_igs_msg_callback_t)(void *app_data, struct nss_cmn_msg *msg); + +/** + * nss_igs_get_context + * Gets the ingress shaper context. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_igs_get_context(void); + +/** + * nss_igs_register_if + * Registers a ingress shaper interface with the NSS for sending and receiving messages. + * + * @datatypes + * nss_igs_msg_callback_t \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] type NSS interface type. + * @param[in] msg_callback Callback for the ingress shaper message. + * @param[in] netdev Pointer to the associated network device. + * @param[in] features Data socket buffer types supported by this interface. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_igs_register_if(uint32_t if_num, uint32_t type, + nss_igs_msg_callback_t msg_callback, struct net_device *netdev, uint32_t features); + +/** + * nss_igs_unregister_if + * Deregisters a ingress shaper interface from the NSS. + * + * @param[in] if_num NSS interface number. + * + * @return + * None. + */ +extern void nss_igs_unregister_if(uint32_t if_num); + +/** + * nss_igs_verify_if_num + * Verify whether interface is an ingress shaper interface or not. + * + * @param[in] if_num NSS interface number. + * + * @return + * True if interface is an ingress shaper interface. + */ +extern bool nss_igs_verify_if_num(uint32_t if_num); + + +#ifdef CONFIG_NET_CLS_ACT +/* + * nss_igs_module_save() + * Save the ingress shaping module reference. + * + * @datatypes + * tc_action_ops \n + * module + * + * @param[in] act Operation structure for ingress shaping action. + * @param[in] module Module structure of ingress shaping module. + * + * @return + * None. + */ +extern void nss_igs_module_save(struct tc_action_ops *act, struct module *module); +#endif + +/* + * nss_igs_module_get() + * Get the ingress shaping module reference. + * + * @return + * False if not able to take the ingress shaping module reference, otherwise true. + * + */ +extern bool nss_igs_module_get(void); + +/* + * nss_igs_module_put() + * Release the ingress shaping module reference. + * + * @return + * None. + */ +extern void nss_igs_module_put(void); + +/** + * @} + */ +#endif diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_ipsec.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_ipsec.h new file mode 100644 index 000000000..3a9de9339 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_ipsec.h @@ -0,0 +1,550 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_ipsec.h + * NSS IPSec interface definitions. + */ + +#ifndef __NSS_IPSEC_H +#define __NSS_IPSEC_H + +/* + * For some reason Linux doesn't define this in if_arp.h, + * refer http://www.iana.org/assignments/arp-parameters/arp-parameters.xhtml + * for the full list + */ + +/** + * @addtogroup nss_ipsec_subsystem + * @{ + */ + +#define NSS_IPSEC_ARPHRD_IPSEC 31 + /**< ARP (iana.org) hardware type for an IPsec tunnel. */ +#define NSS_IPSEC_MAX_RULES 256 + /**< Maximum number of rules supported. */ +#define NSS_IPSEC_MAX_SA NSS_CRYPTO_MAX_IDXS + /**< Maximum number of SAs supported. */ + +#if (~(NSS_IPSEC_MAX_RULES - 1) & (NSS_IPSEC_MAX_RULES >> 1)) +#error "NSS Max SA should be a power of 2" +#endif + +/** + * Size of an IPsec message. + */ +#define NSS_IPSEC_MSG_LEN (sizeof(struct nss_ipsec_msg) - sizeof(struct nss_cmn_msg)) + +/** + * nss_ipsec_msg_type + * Rules for the IPsec interface. + */ +enum nss_ipsec_msg_type { + NSS_IPSEC_MSG_TYPE_NONE = 0, + NSS_IPSEC_MSG_TYPE_ADD_RULE = 1, + NSS_IPSEC_MSG_TYPE_DEL_RULE = 2, + NSS_IPSEC_MSG_TYPE_FLUSH_TUN = 3, + NSS_IPSEC_MSG_TYPE_SYNC_SA_STATS = 4, + NSS_IPSEC_MSG_TYPE_SYNC_FLOW_STATS = 5, + NSS_IPSEC_MSG_TYPE_SYNC_NODE_STATS = 6, + NSS_IPSEC_MSG_TYPE_CONFIGURE_NODE = 7, + NSS_IPSEC_MSG_TYPE_MAX +}; + +/** + * nss_ipsec_status + * Status types for the IPsec interface. + */ +typedef enum nss_ipsec_status { + NSS_IPSEC_STATUS_OK = 0, + NSS_IPSEC_STATUS_ENOMEM = 1, + NSS_IPSEC_STATUS_ENOENT = 2, + NSS_IPSEC_STATUS_MAX +} nss_ipsec_status_t; + +/** + * nss_ipsec_error_type + * Error types for the IPsec interface. + */ +enum nss_ipsec_error_type { + NSS_IPSEC_ERROR_TYPE_NONE = 0, + NSS_IPSEC_ERROR_TYPE_HASH_DUPLICATE = 1, + NSS_IPSEC_ERROR_TYPE_HASH_COLLISION = 2, + NSS_IPSEC_ERROR_TYPE_UNHANDLED_MSG = 3, + NSS_IPSEC_ERROR_TYPE_INVALID_RULE = 4, + NSS_IPSEC_ERROR_TYPE_MAX_SA = 5, + NSS_IPSEC_ERROR_TYPE_MAX_FLOW = 6, + NSS_IPSEC_ERROR_TYPE_INVALID_CINDEX = 7, + NSS_IPSEC_ERROR_TYPE_INVALID_IPVER = 8, + NSS_IPSEC_ERROR_TYPE_MAX +}; + +/** + * nss_ipsec_type + * Operation types for the IPsec interface. + */ +enum nss_ipsec_type { + NSS_IPSEC_TYPE_NONE = 0, + NSS_IPSEC_TYPE_ENCAP = 1, + NSS_IPSEC_TYPE_DECAP = 2, + NSS_IPSEC_TYPE_MAX +}; + +/** + * nss_ipsec_tuple + * Common IPsec rule selector tuple for encapsulation and decapsulation. + * + * This selector is used for preparing a lookup tuple for incoming packets. + * The tuple is used to derive the index into the rule table. + * + * Choosing the selector fields depends on the IPsec encapsulation or decapsulation + * package. The host has no understanding of the index derived from the selector fields, + * and thus it provides information for all entries in the structure. + * + * The encapsulation and decapsulation packages return the index in their respective + * tables to the host. The host stores the rule for future reference purposes. + */ +struct nss_ipsec_tuple { + uint32_t dst_addr[4]; /**< Destination IP address. */ + uint32_t src_addr[4]; /**< Source IP address. */ + + uint32_t esp_spi; /**< SPI index. */ + + uint16_t dst_port; /**< Destination port (UDP or TCP). */ + uint16_t src_port; /**< Source port (UDP or TCP). */ + + uint8_t proto_next_hdr; /**< IP header type. */ + uint8_t ip_ver; /**< IP version. */ + uint8_t res[2]; /**< Reserved for 4-byte alignment. */ +}; + +/** + * nss_ipsec_rule_oip + * Common information about the IPsec rule outer IP header. + */ +struct nss_ipsec_rule_oip { + uint32_t dst_addr[4]; /**< IPv4 destination address to apply. */ + uint32_t src_addr[4]; /**< IPv4 source address to apply. */ + + uint32_t esp_spi; /**< ESP SPI index to apply. */ + + uint16_t dst_port; /**< Destination port (UDP or TCP). */ + uint16_t src_port; /**< Source port (UDP or TCP). */ + + uint8_t ttl_hop_limit; /**< IPv4 time-to-live value to apply. */ + uint8_t ip_ver; /**< IP version. */ + uint8_t proto_next_hdr; /**< IP header type. */ + uint8_t res; /**< Reserved for 4-byte alignment. */ +}; + +/** + * nss_ipsec_rule_data + * IPsec rule data used for per-packet transformation. + */ +struct nss_ipsec_rule_data { + + uint16_t crypto_index; /**< Crypto index for the security association. */ + uint16_t window_size; /**< ESP sequence number window. */ + + uint8_t cipher_blk_len; /**< Size of the cipher block. */ + uint8_t iv_len; /**< Size of the initialization vector. */ + uint8_t nat_t_req; /**< NAT-T required. */ + uint8_t esp_icv_len; /**< Size of the ICV to be produced as a result of authentication. */ + + uint8_t esp_seq_skip; /**< Skip an ESP sequence number. */ + uint8_t esp_tail_skip; /**< Skip an ESP trailer. */ + uint8_t use_pattern; /**< Use random pattern in a hash calculation. */ + uint8_t enable_esn; /**< Enable extended sequence number. */ + + uint8_t dscp; /**< Default DSCP value of the SA. */ + uint8_t df; /**< Default dont fragment value of the SA. */ + uint8_t copy_dscp; /**< The flag tells whether to copy DSCP from inner header. */ + uint8_t copy_df; /**< The flag tells Whether to copy DF from inner header. */ + + uint32_t res2[4]; /**< Reserved 16 bytes for future use. */ +}; + +/** + * nss_ipsec_rule + * Push message for IPsec rules. + * + * This message is sent from the host to the NSS for performing an operation + * on NSS rule tables. + */ +struct nss_ipsec_rule { + struct nss_ipsec_rule_oip oip; /**< Per rule outer IP information. */ + struct nss_ipsec_rule_data data;/**< Per rule data. */ + + uint32_t index; /**< Index provided by the NSS. */ + uint32_t sa_idx; /**< Rule index for the security association table. */ +}; + +/** + * nss_ipsec_configure_node + * Push message for setting IPsec inline mode and initializing DMA rings. + */ +struct nss_ipsec_configure_node { + bool dma_redirect; /**< Program redirect DMA ring. */ + bool dma_lookaside; /**< Program lookaside DMA ring. */ +}; + +/** + * nss_ipsec_sa_stats + * Packet statistics per security association. + */ +struct nss_ipsec_sa_stats { + uint32_t count; /**< Packets processed. */ + uint32_t bytes; /**< Bytes processed. */ + uint32_t no_headroom; /**< Insufficient headroom. */ + uint32_t no_tailroom; /**< Insufficient tailroom. */ + uint32_t no_resource; /**< No crypto buffer. */ + uint32_t fail_queue; /**< Failed to enqueue. */ + uint32_t fail_hash; /**< Hash mismatch. */ + uint32_t fail_replay; /**< Replay check failure. */ + uint64_t seq_num; /**< Current sequence number. */ + uint64_t window_max; /**< Maximum size of the window. */ + uint32_t window_size; /**< Current window size. */ + uint32_t fail_hash_cont; /**< Consecutive hash fail count. */ + uint8_t esn_enabled; /**< Indicates whether ESN is enabled. */ + uint8_t res[3]; /**< Reserved for future use. */ +} /** @cond */ __attribute__((packed))/** @endcond */; + +/** + * nss_ipsec_flow_stats + * Per-flow statistics. + */ +struct nss_ipsec_flow_stats { + uint32_t processed; /**< Packets processed for this flow. */ + + uint8_t use_pattern; /**< Use random pattern. */ + uint8_t res[3]; /**< Reserved for 4-byte alignment padding. */ +}; + +/** + * nss_ipsec_node_stats + * Per-node statistics. + */ +struct nss_ipsec_node_stats { + uint32_t enqueued; /**< Packets enqueued to the node. */ + uint32_t completed; /**< Packets processed by the node. */ + uint32_t linearized; /**< Packet is linear. */ + uint32_t exceptioned; /**< Packets exception from the NSS. */ + uint32_t fail_enqueue; /**< Packets failed to enqueue. */ + uint32_t redir_rx; /**< Packets received in redirect ring. */ + uint32_t fail_redir; /**< Packets dropped in redirect ring. */ +}; + +/** + * nss_ipsec_stats + * Common statistics structure. + */ +union nss_ipsec_stats { + struct nss_ipsec_sa_stats sa; /**< Security association statistics. */ + struct nss_ipsec_flow_stats flow; /**< Flow statistics. */ + struct nss_ipsec_node_stats node; /**< Node statistics. */ +}; + +/** + * nss_ipsec_msg + * Data for sending and receiving IPsec messages. + */ +struct nss_ipsec_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + uint32_t tunnel_id; /**< ID of the tunnel associated with the message. */ + struct nss_ipsec_tuple tuple; + /**< Tuple to look up the SA table for encapsulation or decapsulation. */ + enum nss_ipsec_type type; /**< Encapsulation or decapsulation operation. */ + + /** + * Payload of an IPsec message. + */ + union { + struct nss_ipsec_rule rule; + /**< IPsec rule message. */ + struct nss_ipsec_configure_node node; + /**< IPsec node message. */ + union nss_ipsec_stats stats; + /**< Retrieve statistics for the tunnel. */ + } msg; /**< Message payload. */ +}; + +/** + * Callback function for receiving message notifications. + * + * @datatypes + * nss_ipsec_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_ipsec_msg_callback_t)(void *app_data, struct nss_ipsec_msg *msg); + +/** + * Callback function for receiving data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the message data. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_ipsec_buf_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * nss_ipsec_tx_msg + * Sends an IPsec message to the NSS HLOS driver. + * + * @datatypes + * nss_ctx_instance \n + * nss_ipsec_msg + * + * @param[in] nss_ctx Pointer to the NSS HLOS driver context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_ipsec_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_ipsec_msg *msg); + +/** + * nss_ipsec_tx_msg_sync + * Sends IPsec messages synchronously. + * + * @datatypes + * nss_ctx_instance \n + * nss_ipsec_msg_type \n + * nss_ipsec_msg \n + * nss_ipsec_error_type + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] if_num Configuration interface number. + * @param[in] type Type of the message. + * @param[in] len Size of the payload. + * @param[in] nim Pointer to the message data. + * @param[in,out] resp Response for the configuration. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_ipsec_tx_msg_sync(struct nss_ctx_instance *nss_ctx, uint32_t if_num, + enum nss_ipsec_msg_type type, uint16_t len, + struct nss_ipsec_msg *nim, enum nss_ipsec_error_type *resp); + +/** + * nss_ipsec_tx_buf + * Sends a plain text packet to NSS for IPsec encapsulation or decapsulation. + * + * @datatypes + * sk_buff + * + * @param[in] skb Pointer to the message data. + * @param[in] if_num Pointer to the NSS interface number. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_ipsec_tx_buf(struct sk_buff *skb, uint32_t if_num); + +/** + * nss_ipsec_notify_register + * Registers an event callback handler with the HLOS driver. + * + * When registered, the message callback is called when the NSS + * sends a response to the message sent by the host. + * + * @datatypes + * nss_ipsec_msg_callback_t + * + * @param[in] if_num NSS interface number. + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the context of the message. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_ipsec_notify_register(uint32_t if_num, nss_ipsec_msg_callback_t cb, void *app_data); + +/** + * nss_ipsec_data_register + * Registers a data callback handler with the HLOS driver. + * + * The HLOS driver calls the registered data callback to return + * the packet to the OS. + * + * @datatypes + * nss_ipsec_buf_callback_t \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] cb Callback function for the data. + * @param[in] netdev Pointer to the associated network device. + * @param[in] features Data socket buffer types supported by this interface. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_ipsec_data_register(uint32_t if_num, nss_ipsec_buf_callback_t cb, struct net_device *netdev, uint32_t features); + +/** + * nss_ipsec_notify_unregister + * Deregisters the message notifier from the HLOS driver. + * + * @datatypes + * nss_ctx_instance + * + * @param[in,out] ctx Pointer to the context of the HLOS driver. + * @param[in] if_num NSS interface number. + * + * @return + * None. + * + * @dependencies + * The message notifier must have been previously registered. + */ +extern void nss_ipsec_notify_unregister(struct nss_ctx_instance *ctx, uint32_t if_num); + +/** + * nss_ipsec_data_unregister + * Deregisters the data notifier from the HLOS driver. + * + * @datatypes + * nss_ctx_instance + * + * @param[in,out] ctx Pointer to the context of the HLOS driver. + * @param[in] if_num NSS interface number. + * + * @return + * None. + * + * @dependencies + * The data notifier must have been previously registered. + */ +extern void nss_ipsec_data_unregister(struct nss_ctx_instance *ctx, uint32_t if_num); + +/** + * nss_ipsec_get_context + * Gets the NSS context for the IPsec handle. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_ipsec_get_context(void); + +/** + * nss_ipsec_get_ifnum + * Gets the IPsec interface number with a core ID. + * + * @param[in] if_num NSS interface number. + * + * @return + * Interface number with the core ID. + */ +extern int32_t nss_ipsec_get_ifnum(int32_t if_num); + +/** + * nss_ipsec_msg_init + * Initializes an IPsec message. + * + * @datatypes + * nss_ipsec_msg \n + * nss_ipsec_msg_callback_t + * + * @param[in,out] nim Pointer to the NSS interface message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_ipsec_msg_init(struct nss_ipsec_msg *nim, uint16_t if_num, uint32_t type, uint32_t len, + nss_ipsec_msg_callback_t cb, void *app_data); + +/** + * nss_ipsec_get_encap_interface + * Gets the NSS interface number to be used for IPsec encapsulation message. + * + * @return + * Encapsulation interface number. + */ +extern int32_t nss_ipsec_get_encap_interface(void); + +/** + * nss_ipsec_get_decap_interface + * Gets the NSS interface number to be used for an IPsec decapsulation message. + * + * @return + * Decapsulation interface number. + */ +extern int32_t nss_ipsec_get_decap_interface(void); + +/** + * nss_ipsec_get_data_interface + * Gets the NSS interface number to be used for an IPsec data transfer. + * + * @return + * NSS interface number. + */ +extern int32_t nss_ipsec_get_data_interface(void); + +/** + * nss_ipsec_ppe_port_config + * Configure Packet Processing Engine IPsec port. + * + * @datatypes + * nss_ctx_instance \n + * net_device + * + * @param[in] ctx Pointer to the context of the HLOS driver. + * @param[in] netdev Pointer to the associated network device. + * @param[in] if_num Data interface number. + * @param[in] vsi_num Virtual switch instance number. + * + * @return + * True if successful, else false. + */ +extern bool nss_ipsec_ppe_port_config(struct nss_ctx_instance *ctx, struct net_device *netdev, + uint32_t if_num, uint32_t vsi_num); + +/** + * nss_ipsec_ppe_mtu_update() + * Configure Packet Processing Engine MTU for IPsec in-line. + * + * @datatypes + * nss_ctx_instance \n + * + * @param[in] ctx Pointer to the context of the HLOS driver. + * @param[in] if_num Data interface number. + * @param[in] mtu Maximum transmission unit of Interface number. + * @param[in] mru Maximum Receive unit of Interface number. + * + * @return + * True if successful, else false. + */ +bool nss_ipsec_ppe_mtu_update(struct nss_ctx_instance *ctx, uint32_t if_num, uint16_t mtu, uint16_t mru); + +/** + * @} + */ + +#endif /* __NSS_IPSEC_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_ipsec_cmn.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_ipsec_cmn.h new file mode 100644 index 000000000..3c0f190f9 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_ipsec_cmn.h @@ -0,0 +1,622 @@ +/* + ************************************************************************** + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_ipsec_cmn.h + * NSS IPsec interface definitions. + */ + +#ifndef __NSS_IPSEC_CMN_H_ +#define __NSS_IPSEC_CMN_H_ + +/** + * @addtogroup nss_ipsec_subsystem + * @{ + */ + +#define NSS_IPSEC_CMN_ARPHRD_IPSEC 31 /**< ARP (iana.org) hardware type for an IPsec tunnel. */ + +/** + * Flags for SA configuration. + */ +#define NSS_IPSEC_CMN_FLAG_IPV6 (0x1 << 0) /**< IPv6 header. */ +#define NSS_IPSEC_CMN_FLAG_IPV4_NATT (0x1 << 1) /**< IPv4 NAT traversal. */ +#define NSS_IPSEC_CMN_FLAG_IPV4_UDP (0x1 << 2) /**< IPv4 UDP traversal. */ +#define NSS_IPSEC_CMN_FLAG_ESP_ESN (0x1 << 3) /**< Enable ESP extended sequence number. */ +#define NSS_IPSEC_CMN_FLAG_ESP_SKIP (0x1 << 4) /**< Skip ESP sequence number and ICV. */ +#define NSS_IPSEC_CMN_FLAG_ESP_REPLAY (0x1 << 5) /**< Check ESP replay counter. */ +#define NSS_IPSEC_CMN_FLAG_CIPHER_NULL (0x1 << 6) /**< NULL cipher mode. */ +#define NSS_IPSEC_CMN_FLAG_CIPHER_GCM (0x1 << 7) /**< Galios counter mode. */ +#define NSS_IPSEC_CMN_FLAG_COPY_DSCP (0x1 << 8) /**< Copy DSCP from inner to outer header. */ +#define NSS_IPSEC_CMN_FLAG_COPY_DF (0x1 << 9) /**< Copy DF from inner node to outer node. */ +#define NSS_IPSEC_CMN_FLAG_MODE_TRANS (0x1 << 10) /**< Encapsulate or decapsulate in transport mode (default is tunnel mode). */ + +#define NSS_IPSEC_CMN_FLAG_HDR_MASK \ + (NSS_IPSEC_CMN_FLAG_IPV6 | NSS_IPSEC_CMN_FLAG_IPV4_NATT | NSS_IPSEC_CMN_FLAG_IPV4_UDP) + /**< Flag header mask. */ + +#define NSS_IPSEC_CMN_FEATURE_INLINE_ACCEL 0x1 /**< Interface enabled for inline exception. */ + +#define NSS_IPSEC_CMN_MDATA_VERSION 0x01 /**< Metadata version. */ +#define NSS_IPSEC_CMN_MDATA_MAGIC 0x8893 /**< Metadata magic. */ +#define NSS_IPSEC_CMN_MDATA_ORIGIN_HOST 0x01 /**< Metadata originates at the host. */ +#define NSS_IPSEC_CMN_MDATA_ALIGN_SZ sizeof(uint32_t) /**< Metadata alignment size. */ +/** + * nss_ipsec_cmn_msg_type + * IPsec message types. + */ +enum nss_ipsec_cmn_msg_type { + NSS_IPSEC_CMN_MSG_TYPE_NONE = 0, /**< Nothing to do. */ + NSS_IPSEC_CMN_MSG_TYPE_NODE_CONFIG = 1, /**< Configure IPsec node. */ + NSS_IPSEC_CMN_MSG_TYPE_CTX_CONFIG = 2, /**< Configure IPsec dynamic node. */ + NSS_IPSEC_CMN_MSG_TYPE_CTX_SYNC = 3, /**< Synchronize context statistics to host. */ + NSS_IPSEC_CMN_MSG_TYPE_SA_CREATE = 4, /**< Create SA. */ + NSS_IPSEC_CMN_MSG_TYPE_SA_DESTROY = 5, /**< Destroy SA. */ + NSS_IPSEC_CMN_MSG_TYPE_SA_SYNC = 6, /**< Synchronize SA statistics to host. */ + NSS_IPSEC_CMN_MSG_TYPE_FLOW_CREATE = 7, /**< Create flow. */ + NSS_IPSEC_CMN_MSG_TYPE_FLOW_DESTROY = 8, /**< Delete flow. */ + NSS_IPSEC_CMN_MSG_TYPE_MAX +}; + +/** + * nss_ipsec_cmn_msg_error + * IPsec message error types. + */ +enum nss_ipsec_cmn_msg_error { + NSS_IPSEC_CMN_MSG_ERROR_NONE = 0, /**< No error. */ + NSS_IPSEC_CMN_MSG_ERROR_CTX_INVAL = 1, /**< Invalid context. */ + NSS_IPSEC_CMN_MSG_ERROR_SA_ALLOC = 2, /**< Failed to allocate SA. */ + NSS_IPSEC_CMN_MSG_ERROR_SA_INVAL = 3, /**< Invalid SA. */ + NSS_IPSEC_CMN_MSG_ERROR_SA_DUP = 4, /**< SA exists. */ + NSS_IPSEC_CMN_MSG_ERROR_SA_INUSE = 5, /**< SA is in use. */ + NSS_IPSEC_CMN_MSG_ERROR_FLOW_ALLOC = 6, /**< Failed to allocate flow. */ + NSS_IPSEC_CMN_MSG_ERROR_FLOW_INVAL = 7, /**< Flow not found. */ + NSS_IPSEC_CMN_MSG_ERROR_FLOW_DUP = 8, /**< Duplicate flow. */ + NSS_IPSEC_CMN_MSG_ERROR_FLOW_SA = 9, /**< Failed to find SA for the flow. */ + NSS_IPSEC_CMN_MSG_ERROR_NODE_REG_DYNIF = 10, + /**< Error registering dynamic interface. */ + NSS_IPSEC_CMN_MSG_ERROR_UNHANDLED_MSG= 11, /**< Unhandled message type. */ + NSS_IPSEC_CMN_MSG_ERROR_MAX /**< Maximum error message. */ +}; + +/** + * nss_ipsec_cmn_ctx_type + * IPsec context type. + */ +enum nss_ipsec_cmn_ctx_type { + NSS_IPSEC_CMN_CTX_TYPE_NONE = 0, /**< Invalid direction. */ + NSS_IPSEC_CMN_CTX_TYPE_INNER, /**< Encapsulation. */ + NSS_IPSEC_CMN_CTX_TYPE_MDATA_INNER, /**< Metadata for encapsulation. */ + NSS_IPSEC_CMN_CTX_TYPE_OUTER, /**< Decapsulation. */ + NSS_IPSEC_CMN_CTX_TYPE_MDATA_OUTER, /**< Metadata for decapsulation. */ + NSS_IPSEC_CMN_CTX_TYPE_REDIR, /**< Redirect. */ + NSS_IPSEC_CMN_CTX_TYPE_MAX +}; + +/** + * nss_ipsec_cmn_flow_tuple + * IPsec tuple for creating flow entries. + * + * Note: This is a common selector which is used for preparing + * a lookup tuple for incoming packets. The tuple is used + * for computing the hash index in the flow table. There are multiple + * fields in the tuple and the recipient node decides which fields + * it must use from the tuple to calculate the hash index. The host + * has no view of the hash index and hence must compute its own index + * based on the tuple. + */ +struct nss_ipsec_cmn_flow_tuple { + uint32_t dest_ip[4]; /**< Destination IP. */ + uint32_t src_ip[4]; /**< Source IP. */ + uint32_t spi_index; /**< ESP SPI index. */ + + uint16_t dst_port; /**< Destination L4 port. */ + uint16_t src_port; /**< Source L4 port. */ + + uint8_t user_pattern; /**< User defined field. */ + uint8_t protocol; /**< IP protocol types. */ + uint8_t ip_ver; /**< IP version. */ +}; + +/** + *nss_ipsec_cmn_sa_tuple + * IPsec outer header configuration. + */ +struct nss_ipsec_cmn_sa_tuple { + uint32_t dest_ip[4]; /**< Destination IP. */ + uint32_t src_ip[4]; /**< Source IP. */ + uint32_t spi_index; /**< ESP SPI index. */ + + uint16_t dest_port; /* Destination L4 port. */ + uint16_t src_port; /* Source L4 port. */ + + uint16_t crypto_index; /**< Crypto index for the SA. */ + uint8_t protocol; /**< Outer protocol. */ + uint8_t ip_ver; /**< IP version. */ + + uint8_t hop_limit; /**< Time-to-Live or next hop limit. */ + uint8_t res[3]; /**< Reserved. */ +}; + +/** + *nss_ipsec_cmn_sa_data + * IPsec SA data used for transformation. + */ +struct nss_ipsec_cmn_sa_data { + uint32_t seq_start; /**< Starting sequence number. */ + uint32_t flags; /**< Configuration flags. */ + + uint16_t window_size; /**< ESP sequence number window. */ + uint8_t dscp; /**< Default DSCP value of the SA. */ + uint8_t df; /**< Default do not fragment value of the SA. */ + + uint8_t blk_len; /**< Cipher block length. */ + uint8_t iv_len; /**< IV length. */ + uint8_t icv_len; /**< ESP trailers ICV length to apply. */ + uint8_t res1; /**< Reserved. */ + + uint32_t res2[4]; /**< Reserved for future use. */ +}; + +/** + * nss_ipsec_cmn_flow + * IPsec flow configuration message. + */ +struct nss_ipsec_cmn_flow { + struct nss_ipsec_cmn_flow_tuple flow_tuple; /**< Flow tuple. */ + struct nss_ipsec_cmn_sa_tuple sa_tuple; /**< SA tuple. */ +}; + +/** + * nss_ipsec_cmn_sa + * IPsec SA configuration message. + */ +struct nss_ipsec_cmn_sa { + struct nss_ipsec_cmn_sa_tuple sa_tuple; /**< SA tuple. */ + struct nss_ipsec_cmn_sa_data sa_data; /**< SA data. */ +}; + +/** + * nss_ipsec_cmn_ctx + * IPsec context configuration. + */ +struct nss_ipsec_cmn_ctx { + enum nss_ipsec_cmn_ctx_type type; /**< Node type. */ + uint32_t except_ifnum; /**< Exception interface for egress. */ + uint32_t sibling_ifnum; /**< Sibling interface. */ +}; + +/** + * nss_ipsec_cmn_node + * IPsec node configuration. + */ +struct nss_ipsec_cmn_node { + bool dma_redirect; /**< Enable redirect DMA ring. */ + bool dma_lookaside; /**< Enable lookaside DMA ring. */ + uint16_t max_sa; /**< Maximum number of SA(s) supported. */ +}; + +/** + * nss_ipsec_cmn_sa_replay + * IPsec replay statistics + */ +struct nss_ipsec_cmn_sa_replay { + uint64_t seq_start; /**< Start of replay window. */ + uint64_t seq_cur; /**< Current sequence number. */ + uint16_t window_size; /**< Window size. */ + uint8_t res[6]; /**< Reserved for future use. */ +}; + +/** + * nss_ipsec_cmn_sa_stats + * IPsec SA statistics. + */ +struct nss_ipsec_cmn_sa_stats { + struct nss_cmn_node_stats cmn_stats; /**< Packet statistics. */ + uint32_t fail_headroom; /**< Failed headroom check. */ + uint32_t fail_tailroom; /**< Failed tailroom check. */ + uint32_t fail_replay; /**< Failure in anti-replay check. */ + uint32_t fail_replay_dup; /**< Failure in anti-replay; duplicate records. */ + uint32_t fail_replay_win; /**< Failure in anti-replay; packet outside the window. */ + uint32_t fail_pbuf_crypto; /**< Failed to allocate crypto pbuf. */ + uint32_t fail_queue; /**< Failure due to queue full in IPsec. */ + uint32_t fail_queue_crypto; /**< Failure due to queue full in crypto. */ + uint32_t fail_queue_nexthop; /**< Failure due to queue full in next hop. */ + uint32_t fail_pbuf_alloc; /**< Failure in pbuf allocation. */ + uint32_t fail_pbuf_linear; /**< Failure in pbuf linearization. */ + uint32_t fail_pbuf_stats; /**< Failure in pbuf allocation for statistics. */ + uint32_t fail_pbuf_align; /**< Failure in pbuf access due to non-word alignment. */ + uint32_t fail_cipher; /**< Failure in decrypting the data. */ + uint32_t fail_auth; /**< Failure in authenticating the data. */ + uint32_t fail_seq_ovf; /**< Failure due to sequence number rollover. */ + uint32_t fail_blk_len; /**< Failure in decapsulation due to bad cipher block length. */ + uint32_t fail_hash_len; /**< Failure in decapsulation due to bad hash block length. */ + uint32_t fail_transform; /**< Failure in transformation; general error. */ + uint32_t fail_crypto; /**< Failure in crypto transformation. */ + uint32_t fail_cle; /**< Failure in classification; general failure. */ + uint32_t is_stopped; /**< Indicates if SA is stopped; for example, seq overflow. */ +}; + +/** + * nss_ipsec_cmn_sa_sync + * IPsec SA sync message. + */ +struct nss_ipsec_cmn_sa_sync { + struct nss_ipsec_cmn_sa_replay replay; /**< Replay statistics. */ + struct nss_ipsec_cmn_sa_tuple sa_tuple; /**< SA tuple. */ + struct nss_ipsec_cmn_sa_stats stats; /**< Packet and failure statistics. */ +}; + +/** + * nss_ipsec_cmn_ctx_stats + * IPsec context statistics. + */ +struct nss_ipsec_cmn_ctx_stats { + struct nss_cmn_node_stats cmn_stats; + /**< Packet statistics. */ + uint32_t exceptioned; /**< Exceptioned to host. */ + uint32_t linearized; /**< Linearized packets. */ + uint32_t redirected; /**< Redirected from inline. */ + uint32_t dropped; /**< Total dropped packets. */ + uint32_t fail_sa; /**< Failed to find SA. */ + uint32_t fail_flow; /**< Failed to find flow. */ + uint32_t fail_stats; /**< Failed to send statistics. */ + uint32_t fail_exception; /**< Failed to exception. */ + uint32_t fail_transform; /**< Failed to produce output. */ + uint32_t fail_linearized; /**< Failed to linearize. */ + uint32_t fail_mdata_ver; /**< Invalid metadata version. */ + uint32_t fail_ctx_active; /**< Failed to queue as context is not active. */ + uint32_t fail_pbuf_crypto; /**< Failed to allocate pbuf for crypto operation. */ + uint32_t fail_queue_crypto; /**< Failed to queue pbuf to crypto pnode. */ +}; + +/** + * nss_ipsec_cmn_ctx_sync + * IPsec context synchronous message. + */ +struct nss_ipsec_cmn_ctx_sync { + enum nss_ipsec_cmn_ctx_type type; /**< IPsec context type. */ + struct nss_ipsec_cmn_ctx_stats stats; /**< Context statistics. */ +}; + +/** + * nss_ipsec_cmn_mdata_cmn + * IPsec common metadata information. + */ +struct nss_ipsec_cmn_mdata_cmn { + uint8_t version; /**< Metadata version. */ + uint8_t origin; /**< Metadata origin (host or NSS). */ + uint16_t len; /**< Metadata length including extra bytes. */ + uint8_t res[2]; /**< Reserved for future. */ + uint16_t magic; /**< Metadata magic. */ +}; + +/** + * nss_ipsec_cmn_mdata_encap + * IPsec encapsulation metadata information. + */ +struct nss_ipsec_cmn_mdata_encap { + struct nss_ipsec_cmn_sa_tuple sa; /**< SA tuple. */ + uint32_t seq_num; /**< Sequence number for encapsulation (zero disables it). */ + uint16_t data_len; /**< Length of data to encapsulate. */ + uint16_t flags; /**< Encapsulation metadata flags. */ +}; + +/** + * nss_ipsec_cmn_mdata_decap + * IPsec decapsulation metadata information. + */ +struct nss_ipsec_cmn_mdata_decap { + struct nss_ipsec_cmn_sa_tuple sa; /**< SA tuple. */ +}; + +/** + * nss_ipsec_cmn_mdata + * IPsec metadata for host originated packets. + */ +struct nss_ipsec_cmn_mdata { + struct nss_ipsec_cmn_mdata_cmn cm; /**< Common metadata. */ + + union { + struct nss_ipsec_cmn_mdata_encap encap; /**< Encapsulation metadata. */ + struct nss_ipsec_cmn_mdata_decap decap; /**< Decapsulation metadata. */ + } data; /**< Metadata payload. */ +}; + +/** + * nss_ipsec_cmn_msg + * Message structure for NSS IPsec messages. + */ +struct nss_ipsec_cmn_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of IPsec interface message. + */ + union { + struct nss_ipsec_cmn_node node; /**< Node configuration message. */ + struct nss_ipsec_cmn_ctx ctx; /**< Context configuration message. */ + struct nss_ipsec_cmn_sa sa; /**< SA configuration message. */ + struct nss_ipsec_cmn_flow flow; /**< Flow configuration message. */ + struct nss_ipsec_cmn_sa_sync sa_sync; /**< SA statistics message. */ + struct nss_ipsec_cmn_ctx_sync ctx_sync; /**< Context statistics message. */ + } msg; /**< Message payload. */ +}; + +/** + * nss_ipsec_cmn_mdata_init + * Initialize the metadata common fields. + * + * @datatypes + * nss_ipsec_cmn_mdata + * + * @param[in] mdata Metadata pointer. + * @param[in] len Metadata length including extra bytes. + * + * @return + * Pointer to metadata payload. + */ +static inline void *nss_ipsec_cmn_mdata_init(struct nss_ipsec_cmn_mdata *mdata, uint16_t len) +{ + mdata->cm.len = len; + mdata->cm.magic = NSS_IPSEC_CMN_MDATA_MAGIC; + mdata->cm.version = NSS_IPSEC_CMN_MDATA_VERSION; + mdata->cm.origin = NSS_IPSEC_CMN_MDATA_ORIGIN_HOST; + + return &mdata->data; +} + +/** + * Callback function for receiving message notifications. + * + * @datatypes + * nss_ipsec_cmn_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_ipsec_cmn_msg_callback_t)(void *app_data, struct nss_cmn_msg *msg); + +/** + * Callback function for receiving data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the message data. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_ipsec_cmn_data_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * nss_ipsec_cmn_get_context + * Gets the NSS context for the IPsec handle. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_ipsec_cmn_get_context(void); + +/** + * nss_ipsec_cmn_get_ifnum_with_coreid + * Gets the IPsec interface number with a core ID. + * + * @param[in] ifnum NSS interface number. + * + * @return + * Interface number with the core ID. + */ +extern uint32_t nss_ipsec_cmn_get_ifnum_with_coreid(int32_t ifnum); + +/** + * nss_ipsec_cmn_register_if + * Registers the IPsec interface with the NSS for sending and + * receiving messages. + * + * @datatypes + * nss_ipsec_cmn_data_callback_t \n + * nss_ipsec_cmn_msg_callback_t \n + * nss_dynamic_interface_type \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] netdev Pointer to the associated network device. + * @param[in] cb_data Callback for the data. + * @param[in] cb_msg Callback for the message. + * @param[in] features Socket buffer types supported by this interface. + * @param[in] type Dynamic interface type. + * @param[in] app_data Application context. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_ipsec_cmn_register_if(uint32_t if_num, struct net_device *netdev, + nss_ipsec_cmn_data_callback_t cb_data, + nss_ipsec_cmn_msg_callback_t cb_msg, + uint32_t features, enum nss_dynamic_interface_type type, void *app_data); + +/** + * nss_ipsec_cmn_unregister_if + * Deregisters a IPSEC tunnel interface from the NSS. + * + * @param[in] if_num NSS interface number. +. * + * @return + * None. + * + * @dependencies + * The tunnel interface must have been previously registered. + * + * @return + * True if successful, else false. + */ +extern bool nss_ipsec_cmn_unregister_if(uint32_t if_num); + +/** + * nss_ipsec_cmn_notify_register + * Register an event callback to handle notification from IPsec firmware package. + * + * @datatypes + * nss_ipsec_cmn_msg_callback_t \n + * + * @param[in] ifnum NSS interface number. + * @param[in] cb Callback for IPsec message. + * @param[in] app_data Pointer to the application context. + * + * @return + * Pointer to NSS core context. + */ +extern struct nss_ctx_instance *nss_ipsec_cmn_notify_register(uint32_t ifnum, nss_ipsec_cmn_msg_callback_t cb, void *app_data); + +/** + * nss_ipsec_cmn_notify_unregister + * Deregisters the message notifier from the HLOS driver. + * + * @datatypes + * nss_ctx_instance + * + * @param[in,out] ctx Pointer to the context of the HLOS driver. + * @param[in] if_num NSS interface number. + * + * @return + * None. + * + * @dependencies + * The message notifier must have been previously registered. + */ +extern void nss_ipsec_cmn_notify_unregister(struct nss_ctx_instance *ctx, uint32_t if_num); + +/** + * nss_ipsec_cmn_msg_init + * Initializes an IPsec message. + * + * @datatypes + * nss_ipsec_cmn_msg \n + * nss_ipsec_cmn_msg_type \n + * nss_ipsec_cmn_msg_callback_t + * + * @param[in,out] nim Pointer to the NSS interface message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_ipsec_cmn_msg_init(struct nss_ipsec_cmn_msg *nim, uint16_t if_num, enum nss_ipsec_cmn_msg_type type, + uint16_t len, nss_ipsec_cmn_msg_callback_t cb, void *app_data); + +/** + * nss_ipsec_cmn_tx_msg + * Sends an asynchronous IPsec message to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_ipsec_cmn_msg + * + * @param[in] nss_ctx Pointer to the NSS HLOS driver context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_ipsec_cmn_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_ipsec_cmn_msg *msg); + +/** + * nss_ipsec_cmn_tx_msg_sync + * Sends a synchronous IPsec message to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_ipsec_cmn_msg_type \n + * nss_ipsec_cmn_msg + * + * @param[in] nss_ctx Pointer to the NSS HLOS driver context. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] nicm Pointer to the NSS IPsec message. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_ipsec_cmn_tx_msg_sync(struct nss_ctx_instance *nss_ctx, uint32_t if_num, + enum nss_ipsec_cmn_msg_type type, uint16_t len, + struct nss_ipsec_cmn_msg *nicm); + +/** + * nss_ipsec_cmn_tx_buf + * Sends a buffer to NSS for IPsec encapsulation or de-capsulation. + * + * @datatypes + * sk_buff \n + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS HLOS driver context. + * @param[in] skb Pointer to the message data. + * @param[in] if_num Pointer to the NSS interface number. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_ipsec_cmn_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *skb, uint32_t if_num); + +/** + * nss_ipsec_cmn_ppe_port_config + * Configure Packet Processing Engine IPsec port. + * + * @datatypes + * nss_ctx_instance \n + * net_device + * + * @param[in] ctx Pointer to the context of the HLOS driver. + * @param[in] netdev Pointer to the associated network device. + * @param[in] if_num Data interface number. + * @param[in] vsi_num Virtual switch instance number. + * + * @return + * True if successful, else false. + */ +extern bool nss_ipsec_cmn_ppe_port_config(struct nss_ctx_instance *ctx, struct net_device *netdev, + uint32_t if_num, uint32_t vsi_num); + +/** + * nss_ipsec_cmn_ppe_mtu_update() + * Configure Packet Processing Engine MTU for IPsec inline. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] ctx Pointer to the context of the HLOS driver. + * @param[in] if_num Data interface number. + * @param[in] mtu Maximum transmission unit of interface number. + * @param[in] mru Maximum receive unit of interface number. + * + * @return + * True if successful, else false. + */ +bool nss_ipsec_cmn_ppe_mtu_update(struct nss_ctx_instance *ctx, uint32_t if_num, uint16_t mtu, uint16_t mru); + +/** + * @} + */ + +#endif /* !__NSS_IPSEC_CMN_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_ipsecmgr.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_ipsecmgr.h new file mode 100644 index 000000000..3fe3460f9 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_ipsecmgr.h @@ -0,0 +1,443 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_ipsecmgr.h + * NSS IPSec Manager interface definitions. + */ + +#ifndef __NSS_IPSECMGR_H +#define __NSS_IPSECMGR_H + +/** + * @addtogroup nss_ipsec_subsystem + * @{ + */ + +#define NSS_IPSECMGR_DEBUG_LVL_ERROR 1 /**< Turn on debug for an error. */ +#define NSS_IPSECMGR_DEBUG_LVL_WARN 2 /**< Turn on debug for a warning. */ +#define NSS_IPSECMGR_DEBUG_LVL_INFO 3 /**< Turn on debug for information. */ +#define NSS_IPSECMGR_DEBUG_LVL_TRACE 4 /**< Turn on debug for trace. */ + +#define NSS_IPSECMGR_TUN_NAME "ipsectun%d" + /**< IPsec tunnel name. */ +#define NSS_IPSECMGR_MAX_TUNNELS (NSS_CRYPTO_MAX_IDXS/2) + /**< Maximum number of IPsec tunnels. */ + +/** + * Length of the header added after encapsulation. + * + * This estimate must be accurate but large enough to accomodate most use cases. + */ +#define NSS_IPSECMGR_TUN_MAX_HDR_LEN 96 + +/* + * Space required in the head and tail of the buffer + */ +#define NSS_IPSECMGR_TUN_HEADROOM 128 /**< Size of the buffer headroom. */ +#define NSS_IPSECMGR_TUN_TAILROOM 192 /**< Size of the buffer tailroom. */ + +#define NSS_IPSECMGR_TUN_MTU(x) (x - NSS_IPSECMGR_TUN_MAX_HDR_LEN) + /**< MTU of the IPsec tunnel. */ + +#define NSS_IPSECMGR_NATT_PORT_DATA 4500 /**< Number of the NATT port. */ + +#define NSS_IPSECMGR_MIN_REPLAY_WIN 32 /**< Minimum size of the replay window. */ +#define NSS_IPSECMGR_MAX_REPLAY_WIN 1024 /**< Maximum size of the replay window. */ +#define NSS_IPSECMGR_MAX_ICV_LEN 32 /**< Maximum size of the ICV. */ +#define NSS_IPSECMGR_MAX_DSCP 63 /**< Maximum size of the descriptor. */ + +/** + * nss_ipsecmgr_flow_type + * Flow types for the IPsec manager. + */ +enum nss_ipsecmgr_flow_type { + NSS_IPSECMGR_FLOW_TYPE_NONE = 0, + NSS_IPSECMGR_FLOW_TYPE_V4_TUPLE = 1, + NSS_IPSECMGR_FLOW_TYPE_V6_TUPLE = 2, + NSS_IPSECMGR_FLOW_TYPE_V4_SUBNET = 3, + NSS_IPSECMGR_FLOW_TYPE_V6_SUBNET = 4, + NSS_IPSECMGR_FLOW_TYPE_MAX +}; + +/** + * nss_ipsecmgr_sa_type + * Security association types for the IPsec manager. + */ +enum nss_ipsecmgr_sa_type { + NSS_IPSECMGR_SA_TYPE_NONE = 0, + NSS_IPSECMGR_SA_TYPE_V4 = 1, + NSS_IPSECMGR_SA_TYPE_V6 = 2, + NSS_IPSECMGR_SA_TYPE_MAX +}; + +/** + * nss_ipsecmgr_event_type + * Event types for the IPsec manager. + */ +enum nss_ipsecmgr_event_type { + NSS_IPSECMGR_EVENT_NONE = 0, + NSS_IPSECMGR_EVENT_SA_STATS, + NSS_IPSECMGR_EVENT_MAX +}; + +/** + * nss_ipsecmgr_sa_v4 + * IPv4 security associations for the IPsec manager. + */ +struct nss_ipsecmgr_sa_v4 { + uint32_t src_ip; /**< IPv4 source IP. */ + uint32_t dst_ip; /**< IPv4 destination IP. */ + uint32_t ttl; /**< IPv4 time-to-live. */ + uint32_t spi_index; /**< ESP SPI index. */ +}; + +/** + * nss_ipsecmgr_sa_v6 + * IPv6 security associations for the IPsec manager. + */ +struct nss_ipsecmgr_sa_v6 { + uint32_t src_ip[4]; /**< IPv6 source IP. */ + uint32_t dst_ip[4]; /**< IPv6 destination IP. */ + uint32_t hop_limit; /**< IPv6 hop limit. */ + uint32_t spi_index; /**< SPI index of the encapsulating security payload (ESP). */ +}; + +/** + * nss_ipsecmgr_sa_data + * Security association data for the IPsec manager. + * + * For DSCP marking, use the following settings: + * - Copy inner header to outer header: + * - dscp_copy = 1 + * - dscp = 0 + * - Fixed mark on outer header: + * - dscp_copy = 0 + * - dscp = <0 to 63> + */ +struct nss_ipsecmgr_sa_data { + uint32_t crypto_index; /**< Crypto session index returned by the driver. */ + + /** + * Security association data for the IPsec manager. + */ + struct { + uint16_t replay_win; + /**< Sequence number window size for anti-replay. */ + uint8_t icv_len; + /**< Hash length. */ + uint8_t dscp; + /**< Default DSCP value of the security association. */ + + bool dscp_copy; + /**< Copy DSCP from the inner header to the outer header. */ + bool nat_t_req; + /**< NAT-T is required. */ + bool seq_skip; + /**< Skip the ESP sequence for encapsulation. */ + bool trailer_skip; + /**< Skip the ESP trailer for encapsulation. */ + bool df_copy; + /**< Copy DF from the inner header to the outer header. */ + uint8_t df; + /**< DF value for the outer header, if nocopy is selected. */ + } esp; /**< Payload of security association data. */ + + bool enable_esn; /**< Enable the extended sequence number. */ + bool use_pattern; /**< Use a random pattern in a hash calculation. */ + uint32_t fail_hash_thresh; /**< Threshold for consecutive hash failure. */ +}; + +/** + * nss_ipsecmgr_encap_v4_tuple + * IPv4 encapsulation flow tuple for the IPsec manager. + */ +struct nss_ipsecmgr_encap_v4_tuple { + uint32_t src_ip; /**< Source IP. */ + uint32_t dst_ip; /**< Destination IP. */ + uint32_t protocol; /**< Protocol. */ +}; + +/** + * nss_ipsecmgr_encap_v6_tuple + * IPv6 encapsulation flow tuple for the IPsec manager. + */ +struct nss_ipsecmgr_encap_v6_tuple { + uint32_t src_ip[4]; /**< Source IP. */ + uint32_t dst_ip[4]; /**< Destination IP. */ + uint32_t next_hdr; /**< Transport layer protocol. */ +}; + +/** + * nss_ipsecmgr_encap_v4_subnet + * IPv4 encapsulation flow subnet for the IPsec manager. + */ +struct nss_ipsecmgr_encap_v4_subnet { + uint32_t dst_subnet; /**< Destination subnet. */ + uint32_t dst_mask; /**< Destination subnet mask. */ + uint32_t protocol; /**< IPv4 or IPv6 protocol. */ +}; + +/** + * nss_ipsecmgr_encap_v6_subnet + * IPv6 encapsulation flow subnet for the IPsec manager. + * + * Store least significant word in dst_subnet[0] and the most significant word + * in dst_subnet[3]. + */ +struct nss_ipsecmgr_encap_v6_subnet { + uint32_t dst_subnet[4]; /**< Destination subnet. */ + uint32_t dst_mask[4]; /**< Destination subnet mask. */ + uint32_t next_hdr; /**< Transport layer protocol. */ +}; + +/** + * nss_ipsecmgr_sa + * Security association information for the IPsec manager. + */ +struct nss_ipsecmgr_sa { + enum nss_ipsecmgr_sa_type type; /**< Security association type. */ + + /** + * IPsec manager security association data. + */ + union { + struct nss_ipsecmgr_sa_v4 v4; /**< IPv4 security association. */ + struct nss_ipsecmgr_sa_v6 v6; /**< IPv6 security association. */ + } data; /**< IPsec manager security association data. */ +}; + +/** + * nss_ipsecmgr_sa_stats + * Security association statistics exported by the IPsec manager. + */ +struct nss_ipsecmgr_sa_stats { + struct nss_ipsecmgr_sa sa; /**< Security association information. */ + uint32_t crypto_index; /**< Crypto session index. */ + + /** + * Security association statistics used by the IPsec manager. + */ + struct { + uint32_t bytes; /**< Number of bytes processed. */ + uint32_t count; /**< Number of packets processed. */ + } pkts; /**< Processing statistics. */ + + uint64_t seq_num; /**< Current sequence number. */ + uint64_t window_max; /**< Maximum size of the window. */ + uint32_t window_size; /**< Current size of the window. */ + + bool fail_hash_alarm; + /**< Alarm for consecutive hash fail. */ + bool esn_enabled; + /**< Specifies whether ESN is enabled. */ +}; + +/** + * nss_ipsecmgr_event + * Event information for the IPsec manager. + */ +struct nss_ipsecmgr_event { + enum nss_ipsecmgr_event_type type; /**< Event type. */ + + /** + * Event information statistics for the IPsec manager. + */ + union { + struct nss_ipsecmgr_sa_stats stats; + /**< Security association statistics. */ + } data; /**< Event information. */ +}; + +/** + * nss_ipsecmgr_encap_flow + * Encapsulation flow information for the IPsec manager. + */ +struct nss_ipsecmgr_encap_flow { + enum nss_ipsecmgr_flow_type type; /**< Flow type. */ + + /** + * Payload of encapsulation flow data for the IPsec manager. + */ + union { + struct nss_ipsecmgr_encap_v4_tuple v4_tuple; + /**< IPv4 tuple. */ + struct nss_ipsecmgr_encap_v4_subnet v4_subnet; + /**< IPv4 subnet. */ + struct nss_ipsecmgr_encap_v6_tuple v6_tuple; + /**< IPv6 tuple. */ + struct nss_ipsecmgr_encap_v6_subnet v6_subnet; + /**< IPv6 subnet. */ + } data; /**< Encapsulation flow information. */ +}; + +#ifdef __KERNEL__ /* only kernel will use. */ + +/** + * Callback function for receiving IPsec data. + * + * @datatypes + * sk_buff + * + * @param[in] ctx Pointer to the context of the data. + * @param[in] skb Pointer to the data socket buffer. + */ +typedef void (*nss_ipsecmgr_data_cb_t) (void *ctx, struct sk_buff *skb); + +/** + * Callback function for receiving IPsec events. + * + * @datatypes + * nss_ipsecmgr_event + * + * @param[in] ctx Pointer to the context of the event. + * @param[in] ev Pointer to the event. + */ +typedef void (*nss_ipsecmgr_event_cb_t) (void *ctx, struct nss_ipsecmgr_event *ev); + +/** + * nss_ipsecmgr_callback + * Callback information. + */ +struct nss_ipsecmgr_callback { + void *ctx; /**< Context of the caller. */ + nss_ipsecmgr_data_cb_t data_fn; /**< Data callback function. */ + nss_ipsecmgr_event_cb_t event_fn; /**< Event callback function. */ +}; + +/** + * nss_ipsecmgr_tunnel_add + * Adds a new IPsec tunnel. + * + * @datatypes + * nss_ipsecmgr_callback + * + * @param[in] cb Pointer to the message callback. + * + * @return + * Linux NETDEVICE or NULL. + */ +struct net_device *nss_ipsecmgr_tunnel_add(struct nss_ipsecmgr_callback *cb); + +/** + * nss_ipsecmgr_tunnel_del + * Deletes an existing IPsec tunnel. + * + * @datatypes + * net_device + * + * @param[in] tun Pointer to the network device associated with the tunnel. + * + * @return + * Success or failure. + */ +bool nss_ipsecmgr_tunnel_del(struct net_device *tun); + +/** + * nss_ipsecmgr_tunnel_update_callback + * Updates the binding of netdevice and callback. + * + * @datatypes + * net_device + * + * @param[in] tun Pointer to IPsec tunnel. + * @param[in] cur Pointer to Linux netdevice. + * + * @return + * None. + */ +void nss_ipsecmgr_tunnel_update_callback(struct net_device *tun, struct net_device *cur); + +/** + * nss_ipsecmgr_encap_add + * Adds an encapsulation flow rule to the IPsec offload database. + * + * @datatypes + * net_device \n + * nss_ipsecmgr_encap_flow \n + * nss_ipsecmgr_sa \n + * nss_ipsecmgr_sa_data + * + * @param[in] tun Pointer to the network device associated with the tunnel. + * @param[in] flow Pointer to the flow or subnet to add. + * @param[in] sa Pointer to the security association for the flow. + * @param[in] data Pointer to additional security association data. + * + * @return + * Success or failure. + */ +bool nss_ipsecmgr_encap_add(struct net_device *tun, struct nss_ipsecmgr_encap_flow *flow, struct nss_ipsecmgr_sa *sa, + struct nss_ipsecmgr_sa_data *data); + +/** + * nss_ipsecmgr_encap_del + * Deletes an encapsulation flow rule from the IPsec offload database. + * + * @datatypes + * net_device \n + * nss_ipsecmgr_encap_flow \n + * nss_ipsecmgr_sa + * + * @param[in] tun Pointer to the network device associated with the tunnel. + * @param[in] flow Pointer to the flow or subnet to delete. + * @param[in] sa Pointer to the security association for the flow. + * + * @return + * Success or failure. + */ +bool nss_ipsecmgr_encap_del(struct net_device *tun, struct nss_ipsecmgr_encap_flow *flow, struct nss_ipsecmgr_sa *sa); + +/** + * nss_ipsecmgr_decap_add + * Adds a decapsulation security association to the offload database. + * + * @datatypes + * net_device \n + * nss_ipsecmgr_sa \n + * nss_ipsenss_ipsecmgr_sa_datacmgr_sa + * + * @param[in] tun Pointer to the network device associated with the tunnel. + * @param[in] sa Pointer to the security association for the decapsulation. + * @param[in] data Pointer to additional security association data. + * + * @return + * Success or failure. + */ +bool nss_ipsecmgr_decap_add(struct net_device *tun, struct nss_ipsecmgr_sa *sa, struct nss_ipsecmgr_sa_data *data); + +/** + * nss_ipsecmgr_sa_flush + * Flushes the security association and all associated flows and subnets. + * + * @datatypes + * net_device \n + * nss_ipsecmgr_sa + * + * @param[in] tun Pointer to the network device associated with the tunnel. + * @param[in] sa Pointer to the security association to flush. + * + * @return + * Success or failure. + */ +bool nss_ipsecmgr_sa_flush(struct net_device *tun, struct nss_ipsecmgr_sa *sa); + +#endif /* __KERNEL__ */ + +/** + * @} + */ + +#endif /* __NSS_IPSECMGR_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_ipv4.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_ipv4.h new file mode 100644 index 000000000..a85f59eeb --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_ipv4.h @@ -0,0 +1,1167 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_ipv4.h + * NSS IPv4 interface definitions. + */ + +#ifndef __NSS_IPV4_H +#define __NSS_IPV4_H + +#ifndef DOXYGEN_SHOULD_SKIP_THIS +#include "nss_stats_public.h" +#endif + +/** + * @addtogroup nss_ipv4_subsystem + * @{ + */ + +/** + * nss_ipv4_message_types + * IPv4 bridge and routing rule message types. + * + * NSS_IPV4_RX_DEPRECATED0 is a deprecated type. It is kept for backward compatibility. + */ +enum nss_ipv4_message_types { + NSS_IPV4_TX_CREATE_RULE_MSG, + NSS_IPV4_TX_DESTROY_RULE_MSG, + NSS_IPV4_RX_DEPRECATED0, + NSS_IPV4_RX_CONN_STATS_SYNC_MSG, + NSS_IPV4_RX_NODE_STATS_SYNC_MSG, + NSS_IPV4_TX_CONN_CFG_RULE_MSG, + NSS_IPV4_TX_CREATE_MC_RULE_MSG, + NSS_IPV4_TX_CONN_STATS_SYNC_MANY_MSG, + NSS_IPV4_TX_ACCEL_MODE_CFG_MSG, + NSS_IPV4_TX_CONN_CFG_INQUIRY_MSG, + NSS_IPV4_TX_CONN_TABLE_SIZE_MSG, + NSS_IPV4_TX_DSCP2PRI_CFG_MSG, + NSS_IPV4_TX_RPS_HASH_BITMAP_CFG_MSG, + NSS_IPV4_MAX_MSG_TYPES, +}; + +/** + * nss_ipv4_dscp_map_actions + * Action types mapped to DSCP values. + */ +enum nss_ipv4_dscp_map_actions { + NSS_IPV4_DSCP_MAP_ACTION_ACCEL, + NSS_IPV4_DSCP_MAP_ACTION_DONT_ACCEL, + NSS_IPV4_DSCP_MAP_ACTION_MAX, +}; + +/** + * nss_ipv4_stats_types + * IPv4 node statistics. + */ +enum nss_ipv4_stats_types { + NSS_IPV4_STATS_ACCELERATED_RX_PKTS = 0, + /**< Accelerated IPv4 Rx packets. */ + NSS_IPV4_STATS_ACCELERATED_RX_BYTES, + /**< Accelerated IPv4 Rx bytes. */ + NSS_IPV4_STATS_ACCELERATED_TX_PKTS, + /**< Accelerated IPv4 Tx packets. */ + NSS_IPV4_STATS_ACCELERATED_TX_BYTES, + /**< Accelerated IPv4 Tx bytes. */ + NSS_IPV4_STATS_CONNECTION_CREATE_REQUESTS, + /**< Number of IPv4 connection create requests. */ + NSS_IPV4_STATS_CONNECTION_CREATE_COLLISIONS, + /**< Number of IPv4 connection create requests that collided with existing entries. */ + NSS_IPV4_STATS_CONNECTION_CREATE_INVALID_INTERFACE, + /**< Number of IPv4 connection create requests that had invalid interface. */ + NSS_IPV4_STATS_CONNECTION_DESTROY_REQUESTS, + /**< Number of IPv4 connection destroy requests. */ + NSS_IPV4_STATS_CONNECTION_DESTROY_MISSES, + /**< Number of IPv4 connection destroy requests that missed the cache. */ + NSS_IPV4_STATS_CONNECTION_HASH_HITS, + /**< Number of IPv4 connection hash hits. */ + NSS_IPV4_STATS_CONNECTION_HASH_REORDERS, + /**< Number of IPv4 connection hash reorders. */ + NSS_IPV4_STATS_CONNECTION_FLUSHES, + /**< Number of IPv4 connection flushes. */ + NSS_IPV4_STATS_CONNECTION_EVICTIONS, + /**< Number of IPv4 connection evictions. */ + NSS_IPV4_STATS_FRAGMENTATIONS, + /**< Number of successful IPv4 fragmentations performed. */ + NSS_IPV4_STATS_DROPPED_BY_RULE, + /**< Number of IPv4 packets dropped because of a drop rule.*/ + NSS_IPV4_STATS_MC_CONNECTION_CREATE_REQUESTS, + /**< Number of successful IPv4 multicast create requests. */ + NSS_IPV4_STATS_MC_CONNECTION_UPDATE_REQUESTS, + /**< Number of successful IPv4 multicast update requests. */ + NSS_IPV4_STATS_MC_CONNECTION_CREATE_INVALID_INTERFACE, + /**< Number of IPv4 multicast connection create requests that had invalid interface. */ + NSS_IPV4_STATS_MC_CONNECTION_DESTROY_REQUESTS, + /**< Number of IPv4 multicast connection destroy requests. */ + NSS_IPV4_STATS_MC_CONNECTION_DESTROY_MISSES, + /**< Number of IPv4 multicast connection destroy requests that missed the cache. */ + NSS_IPV4_STATS_MC_CONNECTION_FLUSHES, + /**< Number of IPv4 multicast connection flushes. */ + NSS_IPV4_STATS_MAX, + /**< Maximum message type. */ +}; + +/* + * NSS IPv4 rule creation & rule update flags. + */ +#define NSS_IPV4_RULE_CREATE_FLAG_NO_SEQ_CHECK 0x01 + /**< Do not perform TCP sequence number checks. */ +#define NSS_IPV4_RULE_CREATE_FLAG_BRIDGE_FLOW 0x02 + /**< Pure bridge forwarding flow. */ +#define NSS_IPV4_RULE_CREATE_FLAG_ROUTED 0x04 + /**< Rule for a routed connection. */ +#define NSS_IPV4_RULE_CREATE_FLAG_DSCP_MARKING 0x08 + /**< Rule for configuring DSCP marking. */ +#define NSS_IPV4_RULE_CREATE_FLAG_VLAN_MARKING 0x10 + /**< Rule for configuring VLAN marking. */ +#define NSS_IPV4_RULE_UPDATE_FLAG_CHANGE_MTU 0x20 + /**< Update MTU of the connection interfaces. */ +#define NSS_IPV4_RULE_CREATE_FLAG_ICMP_NO_CME_FLUSH 0x40 + /**< Rule for not flushing connection match entry on an ICMP packet. */ + +/** + * L2 payload is not IPv4, but it consists of an encapsulating protocol that + * carries an IPv4 payload within it. + */ +#define NSS_IPV4_RULE_CREATE_FLAG_L2_ENCAP 0x80 +#define NSS_IPV4_RULE_CREATE_FLAG_DROP 0x100 + /**< Rule to drop packets. */ +#define NSS_IPV4_RULE_CREATE_FLAG_EXCEPTION 0x200 + /**< Rule to except packets. */ +#define NSS_IPV4_RULE_CREATE_FLAG_SRC_INTERFACE_CHECK 0x400 + /**< Check the source interface for the rule. */ +#define NSS_IPV4_RULE_CREATE_FLAG_NO_SRC_IDENT 0x800 + /**< Zero out the source identifier for the rule. */ +#define NSS_IPV4_RULE_CREATE_FLAG_NO_MAC 0x1000 + /**< Flag to bypass writing MAC addresses. */ +#define NSS_IPV4_RULE_CREATE_FLAG_EMESH_SP 0x2000 + /**< Mark rule as E-MESH Service Prioritization valid. */ + +/* + * Validity flags for rule creation. + */ +#define NSS_IPV4_RULE_CREATE_CONN_VALID 0x01 /**< Connection is valid. */ +#define NSS_IPV4_RULE_CREATE_TCP_VALID 0x02 /**< TCP protocol fields are valid. */ +#define NSS_IPV4_RULE_CREATE_PPPOE_VALID 0x04 /**< PPPoE fields are valid. */ +#define NSS_IPV4_RULE_CREATE_QOS_VALID 0x08 /**< QoS fields are valid. */ +#define NSS_IPV4_RULE_CREATE_VLAN_VALID 0x10 /**< VLAN fields are valid. */ +#define NSS_IPV4_RULE_CREATE_DSCP_MARKING_VALID 0x20 + /**< DSCP marking fields are valid. */ +#define NSS_IPV4_RULE_CREATE_VLAN_MARKING_VALID 0x40 + /**< VLAN marking fields are valid. */ +#define NSS_IPV4_RULE_CREATE_SRC_MAC_VALID 0x80 + /**< Source MAC address fields are valid. */ +#define NSS_IPV4_RULE_CREATE_NEXTHOP_VALID 0x100 + /**< Next hop interface number fields are valid. */ +#define NSS_IPV4_RULE_CREATE_RPS_VALID 0x200 + /**< RPS for core selection is valid. */ +#define NSS_IPV4_RULE_CREATE_DEST_MAC_VALID 0x400 + /**< Destination MAC address fields are valid. */ +#define NSS_IPV4_RULE_CREATE_IGS_VALID 0x800 + /**< Ingress shaping fields are valid. */ +#define NSS_IPV4_RULE_CREATE_IDENTIFIER_VALID 0x1000 + /**< Identifier is valid. */ + +/* + * Multicast command rule flags + */ +#define NSS_IPV4_MC_RULE_CREATE_FLAG_MC_UPDATE 0x01 /**< Multicast rule update. */ +#define NSS_IPV4_MC_RULE_CREATE_FLAG_MC_EMESH_SP 0x02 + /**< Mark multicast rule as E-MESH Service Prioritization valid. */ + +/* + * Multicast command validity flags + */ +#define NSS_IPV4_MC_RULE_CREATE_FLAG_QOS_VALID 0x01 + /**< QoS fields are valid. */ +#define NSS_IPV4_MC_RULE_CREATE_FLAG_DSCP_MARKING_VALID 0x02 + /**< DSCP fields are valid. */ +#define NSS_IPV4_MC_RULE_CREATE_FLAG_INGRESS_VLAN_VALID 0x04 + /**< Ingress VLAN fields are valid. */ +#define NSS_IPV4_MC_RULE_CREATE_FLAG_INGRESS_PPPOE 0x08 + /**< Ingress PPPoE fields are valid. */ +#define NSS_IPV4_MC_RULE_CREATE_FLAG_IGS_VALID 0x10 + /**< Ingress shaping fields are valid. */ + +/* + * Per-interface rule flags for a multicast connection (to be used with the rule_flags + * field of nss_ipv4_mc_if_rule structure). + */ +#define NSS_IPV4_MC_RULE_CREATE_IF_FLAG_BRIDGE_FLOW 0x01 + /**< Multicast connection rule is created for a bridge flow. */ +#define NSS_IPV4_MC_RULE_CREATE_IF_FLAG_ROUTED_FLOW 0x02 + /**< Multicast connection rule is created for a routed flow. */ +#define NSS_IPV4_MC_RULE_CREATE_IF_FLAG_JOIN 0x04 + /**< Interface has joined the flow. */ +#define NSS_IPV4_MC_RULE_CREATE_IF_FLAG_LEAVE 0x08 + /**< Interface has left the flow. */ + +/* + * Per-interface valid flags for a multicast connection (to be used with the valid_flags + * field of nss_ipv4_mc_if_rule structure). + */ +#define NSS_IPV4_MC_RULE_CREATE_IF_FLAG_VLAN_VALID 0x01 + /**< VLAN fields are valid. */ +#define NSS_IPV4_MC_RULE_CREATE_IF_FLAG_PPPOE_VALID 0x02 + /**< PPPoE fields are valid. */ +#define NSS_IPV4_MC_RULE_CREATE_IF_FLAG_NAT_VALID 0x4 + /**< Interface is configured with the source NAT. */ + +/* + * Source MAC address valid flags (to be used with mac_valid_flags field of nss_ipv4_src_mac_rule structure) + */ +#define NSS_IPV4_SRC_MAC_FLOW_VALID 0x01 + /**< MAC address for the flow interface is valid. */ +#define NSS_IPV4_SRC_MAC_RETURN_VALID 0x02 + /**< MAC address for the return interface is valid. */ + +/* + * Identifier valid flags (to be used with identifier_valid_flags field of nss_ipv4_identifier_rule structure) + */ +#define NSS_IPV4_FLOW_IDENTIFIER_VALID 0x01 + /**< Identifier for flow direction is valid. */ +#define NSS_IPV4_RETURN_IDENTIFIER_VALID 0x02 + /**< Identifier for return direction is valid. */ + +/** + * nss_ipv4_5tuple + * Common 5-tuple information. + */ +struct nss_ipv4_5tuple { + uint32_t flow_ip; /**< Flow IP address. */ + uint32_t flow_ident; /**< Flow identifier (e.g., TCP or UDP port). */ + uint32_t return_ip; /**< Return IP address. */ + uint32_t return_ident; /**< Return identier (e.g., TCP or UDP port). */ + uint8_t protocol; /**< Protocol number. */ + uint8_t reserved[3]; /**< Padded for alignment. */ +}; + +/** + * nss_ipv4_connection_rule + * Information for creating a connection. + */ +struct nss_ipv4_connection_rule { + uint16_t flow_mac[3]; /**< Flow MAC address. */ + uint16_t return_mac[3]; /**< Return MAC address. */ + int32_t flow_interface_num; /**< Flow interface number. */ + int32_t return_interface_num; /**< Return interface number. */ + uint32_t flow_mtu; /**< MTU for the flow interface. */ + uint32_t return_mtu; /**< MTU for the return interface. */ + uint32_t flow_ip_xlate; /**< Translated flow IP address. */ + uint32_t return_ip_xlate; /**< Translated return IP address. */ + uint32_t flow_ident_xlate; /**< Translated flow identifier (e.g., port). */ + uint32_t return_ident_xlate; /**< Translated return identifier (e.g., port). */ +}; + +/** + * nss_ipv4_pppoe_rule + * Information for PPPoE connection rules. + */ +struct nss_ipv4_pppoe_rule { + uint32_t flow_if_exist; + /**< PPPoE interface existence flag for the flow direction. */ + int32_t flow_if_num; + /**< PPPoE interface number for the flow direction. */ + uint32_t return_if_exist; + /**< PPPoE interface existence flag for the return direction. */ + int32_t return_if_num; + /**< PPPoE interface number for the return direction. */ +}; + +/** + * nss_ipv4_dscp_rule + * Information for DSCP connection rules. + */ +struct nss_ipv4_dscp_rule { + uint8_t flow_dscp; /**< Egress DSCP value for the flow direction. */ + uint8_t return_dscp; /**< Egress DSCP value for the return direction. */ + uint8_t reserved[2]; /**< Padded for alignment. */ +}; + +/** + * nss_ipv4_vlan_rule + * Information for VLAN connection rules. + */ +struct nss_ipv4_vlan_rule { + uint32_t ingress_vlan_tag; /**< VLAN tag for the ingress packets. */ + uint32_t egress_vlan_tag; /**< VLAN tag for egress packets. */ +}; + +/** + * nss_ipv4_nexthop + * Information for next hop interface numbers. + * + * A next hop is the next interface that will receive the packet (as opposed to + * the final interface when the packet leaves the device. + */ +struct nss_ipv4_nexthop { + /** + * Next hop interface number of the flow direction (from which the connection + * originated). + */ + int32_t flow_nexthop; + /** + * Next hop interface number of the return direction (to which the connection + * is destined). + */ + int32_t return_nexthop; +}; + +/** + * nss_ipv4_protocol_tcp_rule + * Information for TCP connection rules. + */ +struct nss_ipv4_protocol_tcp_rule { + uint32_t flow_max_window; + /**< Largest seen window for the flow direction. */ + uint32_t return_max_window; + /**< Largest seen window for the return direction. */ + + /** + * Largest seen sequence + segment length for the flow direction. + */ + uint32_t flow_end; + + /** + * Largest seen sequence + segment length for the return direction. + */ + uint32_t return_end; + + uint32_t flow_max_end; + /**< Largest seen ack + max(1, win) for the flow direction. */ + uint32_t return_max_end; + /**< Largest seen ack + max(1, win) for the return direction. */ + uint8_t flow_window_scale; + /**< Window scaling factor for the flow direction. */ + uint8_t return_window_scale; + /**< Window scaling factor for the return direction. */ + uint16_t reserved; /**< Alignment padding. */ +}; + +/** + * nss_ipv4_igs_rule + * Information for ingress shaping connection rules. + */ +struct nss_ipv4_igs_rule { + uint16_t igs_flow_qos_tag; + /**< Ingress shaping QoS tag associated with this rule for the flow direction. */ + uint16_t igs_return_qos_tag; + /**< Ingress shaping QoS tag associated with this rule for the return direction. */ +}; + +/** + * nss_ipv4_qos_rule + * Information for QoS connection rules. + */ +struct nss_ipv4_qos_rule { + uint32_t flow_qos_tag; + /**< QoS tag associated with this rule for the flow direction. */ + uint32_t return_qos_tag; + /**< QoS tag associated with this rule for the return direction. */ +}; + +/** + * nss_ipv4_src_mac_rule + * Information for source MAC address rules. + */ +struct nss_ipv4_src_mac_rule { + uint32_t mac_valid_flags; /**< MAC address validity flags. */ + uint16_t flow_src_mac[3]; /**< Source MAC address for the flow direction. */ + uint16_t return_src_mac[3]; /**< Source MAC address for the return direction. */ +}; + +/** + * nss_ipv4_rps_rule + * RPS rule structure. + */ +struct nss_ipv4_rps_rule { + uint8_t flow_rps; + /**< RPS for core selection for flow direction. */ + uint8_t return_rps; + /**< RPS for core selection for return direction. */ + uint8_t reserved[2]; + /**< Padded for alignment. */ +}; + +/** + * nss_ipv4_identifier_rule + * Identifier rule structure. + */ +struct nss_ipv4_identifier_rule { + uint32_t identifier_valid_flags; + /**< Identifier validity flags. */ + uint32_t flow_identifier; + /**< Identifier for flow direction. */ + uint32_t return_identifier; + /**< Identifier for return direction. */ +}; + +/** + * nss_ipv4_error_response_types + * Error types for IPv4 messages. + */ +enum nss_ipv4_error_response_types { + NSS_IPV4_UNKNOWN_MSG_TYPE = 1, + NSS_IPV4_CR_INVALID_PNODE_ERROR, + NSS_IPV4_CR_MISSING_CONNECTION_RULE_ERROR, + NSS_IPV4_CR_BUFFER_ALLOC_FAIL_ERROR, + NSS_IPV4_DR_NO_CONNECTION_ENTRY_ERROR, + NSS_IPV4_CR_CONN_CFG_ALREADY_CONFIGURED_ERROR, + NSS_IPV4_CR_CONN_CFG_NOT_MULTIPLE_OF_QUANTA_ERROR, + NSS_IPV4_CR_CONN_CFG_EXCEEDS_LIMIT_ERROR, + NSS_IPV4_CR_CONN_CFG_MEM_ALLOC_FAIL_ERROR, + NSS_IPV4_CR_MULTICAST_INVALID_PROTOCOL, + NSS_IPV4_CR_MULTICAST_UPDATE_INVALID_FLAGS, + NSS_IPV4_CR_MULTICAST_UPDATE_INVALID_IF, + NSS_IPV4_CR_ACCEL_MODE_CONFIG_INVALID, + NSS_IPV4_CR_INVALID_MSG_ERROR, + NSS_IPV4_CR_DSCP2PRI_PRI_INVALID, + NSS_IPV4_CR_DSCP2PRI_CONFIG_INVALID, + NSS_IPV4_CR_INVALID_RPS, + NSS_IPV4_CR_HASH_BITMAP_INVALID, + NSS_IPV4_DR_HW_DECEL_FAIL_ERROR, + NSS_IPV4_CR_RETURN_EXIST_ERROR, + NSS_IPV4_CR_INVALID_IDENTIFIER, + NSS_IPV4_CR_EMESH_SP_CONFIG_INVALID, + NSS_IPV4_LAST +}; + +/** + * nss_ipv4_rule_create_msg + * IPv4 rule for creating sub-messages. + */ +struct nss_ipv4_rule_create_msg { + /* + * Request + */ + uint16_t valid_flags; + /**< Bit flags associated with the validity of parameters. */ + uint16_t rule_flags; + /**< Bit flags associated with the rule. */ + struct nss_ipv4_5tuple tuple; + /**< Holds values of the 5 tuple. */ + struct nss_ipv4_connection_rule conn_rule; + /**< Basic connection-specific data. */ + struct nss_ipv4_protocol_tcp_rule tcp_rule; + /**< TCP-related accleration parameters. */ + struct nss_ipv4_pppoe_rule pppoe_rule; + /**< PPPoE-related accleration parameters. */ + struct nss_ipv4_qos_rule qos_rule; + /**< QoS-related accleration parameters. */ + struct nss_ipv4_dscp_rule dscp_rule; + /**< DSCP-related accleration parameters. */ + struct nss_ipv4_vlan_rule vlan_primary_rule; + /**< Primary VLAN-related accleration parameters. */ + struct nss_ipv4_vlan_rule vlan_secondary_rule; + /**< Secondary VLAN-related accleration parameters. */ + struct nss_ipv4_src_mac_rule src_mac_rule; + /**< Source MAC address-related acceleration parameters. */ + struct nss_ipv4_nexthop nexthop_rule; + /**< Parameters related to the next hop. */ + struct nss_ipv4_rps_rule rps_rule; + /**< RPS parameter. */ + struct nss_ipv4_igs_rule igs_rule; + /**< Ingress shaping related accleration parameters. */ + struct nss_ipv4_identifier_rule identifier; + /**< Rule for adding identifier. */ +}; + +/** + * nss_ipv4_inquiry_msg + * IPv4 connection inquiry naming structure. + */ +struct nss_ipv4_inquiry_msg { + /** + * Request by its 5-tuple and get response for other items. + */ + struct nss_ipv4_rule_create_msg rr; +}; + +/** + * nss_ipv4_mc_if_rule + * IPv4 multicast rule for creating per-interface information. + */ +struct nss_ipv4_mc_if_rule { + uint16_t rule_flags; /**< Bit flags associated with the rule. */ + uint16_t valid_flags; + /**< Bit flags associated with the validity of parameters. */ + uint32_t xlate_src_ip; /**< Translated flow IP address. */ + uint32_t xlate_src_ident; /**< Translated flow identifier (e.g., port). */ + uint32_t egress_vlan_tag[MAX_VLAN_DEPTH]; + /**< VLAN tag stack for the egress packets. */ + int32_t pppoe_if_num; /**< PPPoE interface number. */ + uint32_t if_num; /**< Interface number. */ + uint32_t if_mtu; /**< Interface MTU. */ + uint16_t if_mac[3]; /**< Interface MAC address. */ + uint8_t reserved[2]; /**< Reserved 2 bytes for alignment. */ +}; + +/** + * nss_ipv4_mc_rule_create_msg + * IPv4 multicast rule for creating sub-messages. + */ +struct nss_ipv4_mc_rule_create_msg { + struct nss_ipv4_5tuple tuple; /**< Holds values of the 5 tuple. */ + + uint32_t rule_flags; /**< Multicast command rule flags. */ + uint32_t valid_flags; /**< Multicast command validity flags. */ + uint32_t src_interface_num; + /**< Source interface number (virtual or physical). */ + uint32_t ingress_vlan_tag[MAX_VLAN_DEPTH]; + /**< VLAN tag stack for the ingress packets. */ + uint32_t qos_tag; /**< QoS tag for the rule. */ + uint16_t dest_mac[3]; /**< Destination multicast MAC address. */ + uint16_t if_count; /**< Number of destination interfaces. */ + uint8_t egress_dscp; /**< Egress DSCP value for the flow. */ + uint8_t reserved[1]; /**< Reserved 1 byte for alignment. */ + uint16_t igs_qos_tag; /**< Ingress shaping QoS tag for the rule. */ + + struct nss_ipv4_mc_if_rule if_rule[NSS_MC_IF_MAX]; + /**< Per-interface information. */ +}; + +/** + * nss_ipv4_rule_destroy_msg + * IPv4 rule for destroying sub-messages. + */ +struct nss_ipv4_rule_destroy_msg { + struct nss_ipv4_5tuple tuple; /**< Holds values of the 5 tuple. */ +}; + +/** + * nss_ipv4_rule_conn_get_table_size_msg + * IPv4 rule for fetching connection tables size. + */ +struct nss_ipv4_rule_conn_get_table_size_msg { + uint32_t num_conn; /**< Number of supported IPv4 connections. */ + uint32_t ce_table_size; /**< Size of the connection entry table in NSS firmware. */ + uint32_t cme_table_size; /**< Size of the connection match entry table in NSS firmware. */ +}; + +/** + * nss_ipv4_rule_conn_cfg_msg + * IPv4 rule for connection configuration sub-messages. + */ +struct nss_ipv4_rule_conn_cfg_msg { + uint32_t num_conn; /**< Number of supported IPv4 connections. */ + uint32_t ce_mem; /**< Memory allocated by host for connection entries table. */ + uint32_t cme_mem; /**< Memory allocated by host for connection match entries table. */ +}; + +/* + * IPv4 rule synchronization reasons. + */ +#define NSS_IPV4_RULE_SYNC_REASON_STATS 0 + /**< Rule for synchronizing statistics. */ +#define NSS_IPV4_RULE_SYNC_REASON_FLUSH 1 + /**< Rule for flushing a cache entry. */ +#define NSS_IPV4_RULE_SYNC_REASON_EVICT 2 + /**< Rule for evicting a cache entry. */ +#define NSS_IPV4_RULE_SYNC_REASON_DESTROY 3 + /**< Rule for destroying a cache entry (requested by the host OS). */ + +/** + * nss_ipv4_conn_sync + * IPv4 connection synchronization message. + */ +struct nss_ipv4_conn_sync { + uint32_t reserved; /**< Reserved field for backward compatibility. */ + uint8_t protocol; /**< Protocol number. */ + uint32_t flow_ip; /**< Flow IP address. */ + uint32_t flow_ip_xlate; /**< Translated flow IP address. */ + uint32_t flow_ident; /**< Flow identifier (e.g., port). */ + uint32_t flow_ident_xlate; /**< Translated flow identifier (e.g., port). */ + uint32_t flow_max_window; /**< Largest seen window for the flow direction. */ + + /** + * Largest seen sequence + segment length for the flow direction. + */ + uint32_t flow_end; + + uint32_t flow_max_end; + /**< Largest seen ack + max(1, win) for the flow direction. */ + uint32_t flow_rx_packet_count; + /**< Rx packet count for the flow interface. */ + uint32_t flow_rx_byte_count; + /**< Rx byte count for the flow interface. */ + uint32_t flow_tx_packet_count; + /**< Tx packet count for the flow interface. */ + uint32_t flow_tx_byte_count; + /**< Tx byte count for the flow interface. */ + uint32_t return_ip; /**< Return IP address. */ + uint32_t return_ip_xlate; /**< Translated return IP address. */ + uint32_t return_ident; /**< Return identier (e.g., port). */ + uint32_t return_ident_xlate; /**< Translated return identifier (e.g., port). */ + uint32_t return_max_window; + /**< Largest seen window for the return direction. */ + + /** + * Largest seen sequence + segment length for the return direction. + */ + uint32_t return_end; + + uint32_t return_max_end; + /**< Largest seen ack + max(1, win) for the return direction. */ + uint32_t return_rx_packet_count; + /**< Rx packet count for the return interface. */ + uint32_t return_rx_byte_count; + /**< Rx byte count for the return interface. */ + uint32_t return_tx_packet_count; + /**< Tx packet count for the return interface. */ + uint32_t return_tx_byte_count; + /**< Tx byte count for the return interface. */ + uint32_t inc_ticks; /**< Number of ticks since the last synchronization. */ + uint32_t reason; /**< Reason for the synchronization. */ + + uint8_t flags; /**< Bit flags associated with the rule. */ + uint32_t qos_tag; /**< QoS tag. */ + uint32_t cause; /**< Flush cause associated with the rule. */ +}; + +/** + * nss_ipv4_conn_sync_many_msg + * Information for a multiple IPv4 connection statistics synchronization message. + */ +struct nss_ipv4_conn_sync_many_msg { + /* + * Request + */ + uint16_t index; /**< Request connection statistics from the index. */ + uint16_t size; /**< Buffer size of this message. */ + + /* + * Response + */ + uint16_t next; /**< Firmware response for the next connection to be requested. */ + uint16_t count; /**< Number of synchronized connections included in this message. */ + struct nss_ipv4_conn_sync conn_sync[]; /**< Array for the statistics. */ +}; + +/** + * nss_ipv4_accel_mode_cfg_msg + * IPv4 acceleration mode configuration. + */ +struct nss_ipv4_accel_mode_cfg_msg { + uint32_t mode; /**< Type of acceleration mode. */ +}; + +/** + * nss_ipv4_dscp2pri_cfg_msg + * IPv4 dscp2pri configuration msg. + */ +struct nss_ipv4_dscp2pri_cfg_msg { + uint8_t dscp; /**< Value of DSCP. */ + uint8_t priority; /**< Corresponding priority. */ +}; + +/** + * nss_ipv4_rps_hash_bitmap_cfg_msg + * RPS hash mask configuration. + * + * The bitmap represents the host cores to which NSS firmware can steer + * packets based on packet hash. The least significant bit represents core0. + */ +struct nss_ipv4_rps_hash_bitmap_cfg_msg { + uint32_t hash_bitmap; /**< Hash mask. */ +}; + +/** + * nss_ipv4_exception_events + * Exception events from the bridge or route handler. + */ +enum nss_ipv4_exception_events { + NSS_IPV4_EXCEPTION_EVENT_ICMP_HEADER_INCOMPLETE, + NSS_IPV4_EXCEPTION_EVENT_ICMP_UNHANDLED_TYPE, + NSS_IPV4_EXCEPTION_EVENT_ICMP_IPV4_HEADER_INCOMPLETE, + NSS_IPV4_EXCEPTION_EVENT_ICMP_IPV4_UDP_HEADER_INCOMPLETE, + NSS_IPV4_EXCEPTION_EVENT_ICMP_IPV4_TCP_HEADER_INCOMPLETE, + NSS_IPV4_EXCEPTION_EVENT_ICMP_IPV4_UNKNOWN_PROTOCOL, + NSS_IPV4_EXCEPTION_EVENT_ICMP_NO_ICME, + NSS_IPV4_EXCEPTION_EVENT_ICMP_FLUSH_TO_HOST, + NSS_IPV4_EXCEPTION_EVENT_TCP_HEADER_INCOMPLETE, + NSS_IPV4_EXCEPTION_EVENT_TCP_NO_ICME, + NSS_IPV4_EXCEPTION_EVENT_TCP_IP_OPTION, + NSS_IPV4_EXCEPTION_EVENT_TCP_IP_FRAGMENT, + NSS_IPV4_EXCEPTION_EVENT_TCP_SMALL_TTL, + NSS_IPV4_EXCEPTION_EVENT_TCP_NEEDS_FRAGMENTATION, + NSS_IPV4_EXCEPTION_EVENT_TCP_FLAGS, + NSS_IPV4_EXCEPTION_EVENT_TCP_SEQ_EXCEEDS_RIGHT_EDGE, + NSS_IPV4_EXCEPTION_EVENT_TCP_SMALL_DATA_OFFS, + NSS_IPV4_EXCEPTION_EVENT_TCP_BAD_SACK, + NSS_IPV4_EXCEPTION_EVENT_TCP_BIG_DATA_OFFS, + NSS_IPV4_EXCEPTION_EVENT_TCP_SEQ_BEFORE_LEFT_EDGE, + NSS_IPV4_EXCEPTION_EVENT_TCP_ACK_EXCEEDS_RIGHT_EDGE, + NSS_IPV4_EXCEPTION_EVENT_TCP_ACK_BEFORE_LEFT_EDGE, + NSS_IPV4_EXCEPTION_EVENT_UDP_HEADER_INCOMPLETE, + NSS_IPV4_EXCEPTION_EVENT_UDP_NO_ICME, + NSS_IPV4_EXCEPTION_EVENT_UDP_IP_OPTION, + NSS_IPV4_EXCEPTION_EVENT_UDP_IP_FRAGMENT, + NSS_IPV4_EXCEPTION_EVENT_UDP_SMALL_TTL, + NSS_IPV4_EXCEPTION_EVENT_UDP_NEEDS_FRAGMENTATION, + NSS_IPV4_EXCEPTION_EVENT_WRONG_TARGET_MAC, + NSS_IPV4_EXCEPTION_EVENT_HEADER_INCOMPLETE, + NSS_IPV4_EXCEPTION_EVENT_BAD_TOTAL_LENGTH, + NSS_IPV4_EXCEPTION_EVENT_BAD_CHECKSUM, + NSS_IPV4_EXCEPTION_EVENT_NON_INITIAL_FRAGMENT, + NSS_IPV4_EXCEPTION_EVENT_DATAGRAM_INCOMPLETE, + NSS_IPV4_EXCEPTION_EVENT_OPTIONS_INCOMPLETE, + NSS_IPV4_EXCEPTION_EVENT_UNKNOWN_PROTOCOL, + NSS_IPV4_EXCEPTION_EVENT_ESP_HEADER_INCOMPLETE, + NSS_IPV4_EXCEPTION_EVENT_ESP_NO_ICME, + NSS_IPV4_EXCEPTION_EVENT_ESP_IP_OPTION, + NSS_IPV4_EXCEPTION_EVENT_ESP_IP_FRAGMENT, + NSS_IPV4_EXCEPTION_EVENT_ESP_SMALL_TTL, + NSS_IPV4_EXCEPTION_EVENT_ESP_NEEDS_FRAGMENTATION, + NSS_IPV4_EXCEPTION_EVENT_IVID_MISMATCH, + NSS_IPV4_EXCEPTION_EVENT_IVID_MISSING, + NSS_IPV4_EXCEPTION_EVENT_6RD_NO_ICME, + NSS_IPV4_EXCEPTION_EVENT_6RD_IP_OPTION, + NSS_IPV4_EXCEPTION_EVENT_6RD_IP_FRAGMENT, + NSS_IPV4_EXCEPTION_EVENT_6RD_NEEDS_FRAGMENTATION, + NSS_IPV4_EXCEPTION_EVENT_DSCP_MARKING_MISMATCH, + NSS_IPV4_EXCEPTION_EVENT_VLAN_MARKING_MISMATCH, + NSS_IPV4_EXCEPTION_EVENT_INTERFACE_MISMATCH, + NSS_IPV4_EXCEPTION_EVENT_GRE_HEADER_INCOMPLETE, + NSS_IPV4_EXCEPTION_EVENT_GRE_NO_ICME, + NSS_IPV4_EXCEPTION_EVENT_GRE_IP_OPTION, + NSS_IPV4_EXCEPTION_EVENT_GRE_IP_FRAGMENT, + NSS_IPV4_EXCEPTION_EVENT_GRE_SMALL_TTL, + NSS_IPV4_EXCEPTION_EVENT_GRE_NEEDS_FRAGMENTATION, + NSS_IPV4_EXCEPTION_EVENT_PPTP_GRE_SESSION_MATCH_FAIL, + NSS_IPV4_EXCEPTION_EVENT_PPTP_GRE_INVALID_PROTO, + NSS_IPV4_EXCEPTION_EVENT_PPTP_GRE_NO_CME, + NSS_IPV4_EXCEPTION_EVENT_PPTP_GRE_IP_OPTION, + NSS_IPV4_EXCEPTION_EVENT_PPTP_GRE_IP_FRAGMENT, + NSS_IPV4_EXCEPTION_EVENT_PPTP_GRE_SMALL_TTL, + NSS_IPV4_EXCEPTION_EVENT_PPTP_GRE_NEEDS_FRAGMENTATION, + NSS_IPV4_EXCEPTION_EVENT_DESTROY, + NSS_IPV4_EXCEPTION_EVENT_FRAG_DF_SET, + NSS_IPV4_EXCEPTION_EVENT_FRAG_FAIL, + NSS_IPV4_EXCEPTION_EVENT_ICMP_IPV4_UDPLITE_HEADER_INCOMPLETE, + NSS_IPV4_EXCEPTION_EVENT_UDPLITE_HEADER_INCOMPLETE, + NSS_IPV4_EXCEPTION_EVENT_UDPLITE_NO_ICME, + NSS_IPV4_EXCEPTION_EVENT_UDPLITE_IP_OPTION, + NSS_IPV4_EXCEPTION_EVENT_UDPLITE_IP_FRAGMENT, + NSS_IPV4_EXCEPTION_EVENT_UDPLITE_SMALL_TTL, + NSS_IPV4_EXCEPTION_EVENT_UDPLITE_NEEDS_FRAGMENTATION, + NSS_IPV4_EXCEPTION_EVENT_MC_UDP_NO_ICME, + NSS_IPV4_EXCEPTION_EVENT_MC_MEM_ALLOC_FAILURE, + NSS_IPV4_EXCEPTION_EVENT_MC_UPDATE_FAILURE, + NSS_IPV4_EXCEPTION_EVENT_MC_PBUF_ALLOC_FAILURE, + NSS_IPV4_EXCEPTION_EVENT_PPPOE_BRIDGE_NO_ICME, + NSS_IPV4_EXCEPTION_EVENT_PPPOE_NO_SESSION, + NSS_IPV4_EXCEPTION_EVENT_ICMP_IPV4_GRE_HEADER_INCOMPLETE, + NSS_IPV4_EXCEPTION_EVENT_ICMP_IPV4_ESP_HEADER_INCOMPLETE, + NSS_IPV4_EXCEPTION_EVENT_EMESH_PRIO_MISMATCH, + NSS_IPV4_EXCEPTION_EVENT_MAX +}; + +/** + * nss_ipv4_node_sync + * IPv4 node synchronization statistics. + */ +struct nss_ipv4_node_sync { + struct nss_cmn_node_stats node_stats; /**< Common node statistics. */ + uint32_t ipv4_connection_create_requests; + /**< Number of connection create requests. */ + + /** + * Number of connection create requests that collided with existing entries. + */ + uint32_t ipv4_connection_create_collisions; + + /** + * Number of connection create requests that had invalid interfaces. + */ + uint32_t ipv4_connection_create_invalid_interface; + + uint32_t ipv4_connection_destroy_requests; + /**< Number of connection destroy requests. */ + uint32_t ipv4_connection_destroy_misses; + /**< Number of connection destroy requests that missed the cache. */ + uint32_t ipv4_connection_hash_hits; /**< Number of connection hash hits. */ + uint32_t ipv4_connection_hash_reorders; /**< Number of connection hash reorders. */ + uint32_t ipv4_connection_flushes; /**< Number of connection flushes. */ + uint32_t ipv4_connection_evictions; /**< Number of connection evictions. */ + uint32_t ipv4_fragmentations; + /**< Number of successful IPv4 fragmentations performed. */ + uint32_t ipv4_dropped_by_rule; + /**< Number of IPv4 packets dropped because of a drop rule. */ + uint32_t ipv4_mc_connection_create_requests; + /**< Number of multicast connection create requests. */ + uint32_t ipv4_mc_connection_update_requests; + /**< Number of multicast connection update requests. */ + + /** + * Number of multicast connection create requests that had invalid interfaces. + */ + uint32_t ipv4_mc_connection_create_invalid_interface; + + uint32_t ipv4_mc_connection_destroy_requests; + /**< Number of multicast connection destroy requests. */ + + /** + * Number of multicast connection destroy requests that missed the cache. + */ + uint32_t ipv4_mc_connection_destroy_misses; + + uint32_t ipv4_mc_connection_flushes; + /**< Number of multicast connection flushes. */ + uint32_t exception_events[NSS_IPV4_EXCEPTION_EVENT_MAX]; + /**< Number of exception events. */ +}; + +/** + * nss_ipv4_msg + * Data for sending and receiving IPv4 bridge or routing messages. + */ +struct nss_ipv4_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of an IPv4 bridge or routing message. + */ + union { + struct nss_ipv4_rule_create_msg rule_create; + /**< Create a rule. */ + struct nss_ipv4_rule_destroy_msg rule_destroy; + /**< Destroy a rule. */ + struct nss_ipv4_conn_sync conn_stats; + /**< Synchronize connection statistics. */ + struct nss_ipv4_node_sync node_stats; + /**< Synchronize node statistics. */ + struct nss_ipv4_rule_conn_get_table_size_msg size; + /**< Get the size for connection tables. */ + struct nss_ipv4_rule_conn_cfg_msg rule_conn_cfg; + /**< Configure a rule connection. */ + struct nss_ipv4_mc_rule_create_msg mc_rule_create; + /**< Create a multicast rule. */ + struct nss_ipv4_conn_sync_many_msg conn_stats_many; + /**< Synchronize multiple connection statistics. */ + struct nss_ipv4_accel_mode_cfg_msg accel_mode_cfg; + /**< Acceleration mode. */ + struct nss_ipv4_inquiry_msg inquiry; + /**< Inquiry if a connection has created. */ + struct nss_ipv4_dscp2pri_cfg_msg dscp2pri_cfg; + /**< Configure dscp2pri mapping. */ + struct nss_ipv4_rps_hash_bitmap_cfg_msg rps_hash_bitmap; + /**< Configure rps_hash_bitmap. */ + } msg; /**< Message payload. */ +}; + +/** + * nss_ipv4_stats_notification + * Data for sending IPv4 statistics. + */ +struct nss_ipv4_stats_notification { + uint32_t core_id; /**< Core ID. */ + uint64_t cmn_node_stats[NSS_STATS_NODE_MAX]; /**< Node statistics. */ + uint64_t special_stats[NSS_IPV4_STATS_MAX]; /**< IPv4 special statistics. */ + uint64_t exception_stats[NSS_IPV4_EXCEPTION_EVENT_MAX]; /**< IPv4 exception statistics. */ +}; + +/** + * Configured IPv4 connection number to use for calculating the total number of + * connections. + */ +extern int nss_ipv4_conn_cfg; + +#ifdef __KERNEL__ /* only kernel will use. */ + +/** + * nss_ipv4_max_conn_count + * Returns the maximum number of IPv4 connections that the NSS acceleration + * engine supports. + * + * @return + * Number of connections that can be accelerated. + */ +int nss_ipv4_max_conn_count(void); + +/** + * Callback function for receiving IPv4 messages. + * + * @datatypes + * nss_ipv4_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_ipv4_msg_callback_t)(void *app_data, struct nss_ipv4_msg *msg); + +/** + * nss_ipv4_tx + * Transmits an IPv4 message to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_ipv4_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_ipv4_tx(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_msg *msg); + +/** + * nss_ipv4_tx_sync + * Transmits a synchronous IPv4 message to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_ipv4_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_ipv4_tx_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_msg *msg); + +/** + * nss_ipv4_tx_with_size + * Transmits an IPv4 message with a specified size to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_ipv4_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * @param[in] size Actual size of this message. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_ipv4_tx_with_size(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_msg *msg, uint32_t size); + +/** + * nss_ipv4_notify_register + * Registers a notifier callback to forward the IPv4 messages received from the NSS + * firmware to the registered subsystem. + * + * @datatypes + * nss_ipv4_msg_callback_t + * + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_ipv4_notify_register(nss_ipv4_msg_callback_t cb, void *app_data); + +/** + * nss_ipv4_notify_unregister + * Degisters an IPv4 message notifier callback from the NSS. + * + * @return + * None. + * + * @dependencies + * The notifier callback must have been previously registered. + */ +extern void nss_ipv4_notify_unregister(void); + +/** + * nss_ipv4_conn_sync_many_notify_register + * Registers a notifier callback with the NSS for connection synchronization + * message responses. + * + * @datatypes + * nss_ipv4_msg_callback_t + * + * @param[in] cb Callback function for the message. + * + * @return + * None. + */ +extern void nss_ipv4_conn_sync_many_notify_register(nss_ipv4_msg_callback_t cb); + +/** + * nss_ipv4_conn_sync_many_notify_unregister + * Degisters a connection synchronization notifier callback from the NSS. + * + * @return + * None. + * + * @dependencies + * The notifier callback must have been previously registered. + */ +extern void nss_ipv4_conn_sync_many_notify_unregister(void); + +/** + * nss_ipv4_get_mgr + * Gets the NSS context that is managing IPv4 processes. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_ipv4_get_mgr(void); + +/** + * nss_ipv4_register_handler + * Registers the IPv4 message handler. + * + * @return + * None. + */ +void nss_ipv4_register_handler(void); + +/** + * nss_ipv4_register_sysctl + * Registers the IPv4 system control table. + * + * @return + * None. + */ +void nss_ipv4_register_sysctl(void); + +/** + * nss_ipv4_unregister_sysctl + * Deregisters the IPv4 system control table. + * + * @return + * None. + * + * @dependencies + * The system control table must have been previously registered. + */ +void nss_ipv4_unregister_sysctl(void); + +/** + * nss_ipv4_msg_init + * Initializes IPv4 messages. + * + * @datatypes + * nss_ipv4_msg \n + * nss_ipv4_msg_callback_t + * + * @param[in,out] nim Pointer to the NSS interface message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_ipv4_msg_init(struct nss_ipv4_msg *nim, uint16_t if_num, uint32_t type, uint32_t len, + nss_ipv4_msg_callback_t cb, void *app_data); + +/** + * nss_ipv4_update_conn_count + * Sets the maximum number of IPv4 connections. + * + * @param[in] ipv4_max_conn Maximum number. + * + * @return + * 0 -- Success + */ +int nss_ipv4_update_conn_count(int ipv4_max_conn); + +/** + * nss_ipv4_free_conn_tables + * Frees memory allocated for connection tables. + * + * @return + * None. + */ +extern void nss_ipv4_free_conn_tables(void); + +/** + * nss_ipv4_dscp_action_get + * Gets the action value of the DSCP. + * + * @param[in] dscp Value of the DSCP field. + * + * @return + * Action value of the DSCP field. + */ +enum nss_ipv4_dscp_map_actions nss_ipv4_dscp_action_get(uint8_t dscp); + +/* + * Logger APIs + */ + +/** + * nss_ipv4_log_tx_msg + * Logs an IPv4 message that is sent to the NSS firmware. + * + * @datatypes + * nss_ipv4_msg + * + * @param[in] nim Pointer to the NSS interface message. + * + * @return + * None. + */ +void nss_ipv4_log_tx_msg(struct nss_ipv4_msg *nim); + +/** + * nss_ipv4_log_rx_msg + * Logs an IPv4 message that is received from the NSS firmware. + * + * @datatypes + * nss_ipv4_msg + * + * @param[in] nim Pointer to the NSS interface message. + * + * @return + * None. + */ +void nss_ipv4_log_rx_msg(struct nss_ipv4_msg *nim); + +/** + * nss_ipv4_stats_register_notifier + * Registers a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_ipv4_stats_register_notifier(struct notifier_block *nb); + +/** + * nss_ipv4_stats_unregister_notifier + * Deregisters a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_ipv4_stats_unregister_notifier(struct notifier_block *nb); + +#endif /*__KERNEL__ */ + +/** + * @} + */ + +#endif /* __NSS_IPV4_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_ipv4_reasm.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_ipv4_reasm.h new file mode 100644 index 000000000..f7785cfe1 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_ipv4_reasm.h @@ -0,0 +1,89 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_ipv4_reasm.h + * NSS IPv4 reassembly interface definitions. + */ + +#ifndef __NSS_IPV4_REASM_H +#define __NSS_IPV4_REASM_H + +/** + * @addtogroup nss_ipv4_reasm_subsystem + * @{ + */ + +/* + * nss_ipv4_reasm_stats_types + * IPv4 reassembly node statistics. + */ +enum nss_ipv4_reasm_stats_types { + NSS_IPV4_REASM_STATS_EVICTIONS, /**< Number of evicted fragment queues due to set memory threshold. */ + NSS_IPV4_REASM_STATS_ALLOC_FAILS, /**< Number of fragment queue allocation failures. */ + NSS_IPV4_REASM_STATS_TIMEOUTS, /**< Number of expired fragment queues. */ + NSS_IPV4_REASM_STATS_MAX, /**< Maximum message type. */ +}; + +/** + * nss_ipv4_reasm_stats_notification + * Data for sending IPv4 reassembly statistics. + */ +struct nss_ipv4_reasm_stats_notification { + uint32_t core_id; /**< Core ID. */ + uint64_t cmn_node_stats[NSS_STATS_NODE_MAX]; /**< Common node statistics. */ + uint64_t ipv4_reasm_stats[NSS_IPV4_REASM_STATS_MAX]; /**< IPv4 reassembly statistics. */ +}; + +#ifdef __KERNEL__ /* only kernel will use. */ + +/** + * nss_ipv4_reasm_stats_register_notifier + * Registers a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_ipv4_reasm_stats_register_notifier(struct notifier_block *nb); + +/** + * nss_ipv4_reasm_stats_unregister_notifier + * Deregisters a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_ipv4_reasm_stats_unregister_notifier(struct notifier_block *nb); + +#endif /*__KERNEL__ */ + +/** + * @} + */ + +#endif /* __NSS_IPV4_REASM_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_ipv6.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_ipv6.h new file mode 100644 index 000000000..900a4886d --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_ipv6.h @@ -0,0 +1,1146 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_ipv6.h + * NSS IPv6 interface definitions. + */ + +#ifndef __NSS_IPV6_H +#define __NSS_IPV6_H + +/** + * @addtogroup nss_ipv6_subsystem + * @{ + */ + +/** + * nss_ipv6_stats_types + * IPv6 node statistics. + */ +enum nss_ipv6_stats_types { + NSS_IPV6_STATS_ACCELERATED_RX_PKTS, + /**< Accelerated IPv6 Rx packets. */ + NSS_IPV6_STATS_ACCELERATED_RX_BYTES, + /**< Accelerated IPv6 Rx bytes. */ + NSS_IPV6_STATS_ACCELERATED_TX_PKTS, + /**< Accelerated IPv6 Tx packets. */ + NSS_IPV6_STATS_ACCELERATED_TX_BYTES, + /**< Accelerated IPv6 Tx bytes. */ + NSS_IPV6_STATS_CONNECTION_CREATE_REQUESTS, + /**< Number of IPv6 connection create requests. */ + NSS_IPV6_STATS_CONNECTION_CREATE_COLLISIONS, + /**< Number of IPv6 connection create requests that collided with existing entries. */ + NSS_IPV6_STATS_CONNECTION_CREATE_INVALID_INTERFACE, + /**< Number of IPv6 connection create requests that had invalid interface. */ + NSS_IPV6_STATS_CONNECTION_DESTROY_REQUESTS, + /**< Number of IPv6 connection destroy requests. */ + NSS_IPV6_STATS_CONNECTION_DESTROY_MISSES, + /**< Number of IPv6 connection destroy requests that missed the cache. */ + NSS_IPV6_STATS_CONNECTION_HASH_HITS, + /**< Number of IPv6 connection hash hits. */ + NSS_IPV6_STATS_CONNECTION_HASH_REORDERS, + /**< Number of IPv6 connection hash reorders. */ + NSS_IPV6_STATS_CONNECTION_FLUSHES, + /**< Number of IPv6 connection flushes. */ + NSS_IPV6_STATS_CONNECTION_EVICTIONS, + /**< Number of IPv6 connection evictions. */ + NSS_IPV6_STATS_FRAGMENTATIONS, + /**< Number of successful IPv6 fragmentations performed. */ + NSS_IPV6_STATS_FRAG_FAILS, + /**< Number of IPv6 fragmentation fails. */ + NSS_IPV6_STATS_DROPPED_BY_RULE, + /**< Number of IPv6 packets dropped by a drop rule. */ + NSS_IPV6_STATS_MC_CONNECTION_CREATE_REQUESTS, + /**< Number of successful IPv6 multicast create requests. */ + NSS_IPV6_STATS_MC_CONNECTION_UPDATE_REQUESTS, + /**< Number of successful IPv6 multicast update requests. */ + NSS_IPV6_STATS_MC_CONNECTION_CREATE_INVALID_INTERFACE, + /**< Number of IPv6 multicast connection create requests that had invalid interface. */ + NSS_IPV6_STATS_MC_CONNECTION_DESTROY_REQUESTS, + /**< Number of IPv6 multicast connection destroy requests. */ + NSS_IPV6_STATS_MC_CONNECTION_DESTROY_MISSES, + /**< Number of IPv6 multicast connection destroy requests that missed the cache. */ + NSS_IPV6_STATS_MC_CONNECTION_FLUSHES, + /**< Number of IPv6 multicast connection flushes. */ + NSS_IPV6_STATS_MAX, + /**< Maximum message type. */ +}; + +/** + * nss_ipv6_message_types + * IPv6 bridge and routing rule message types. + * + * NSS_IPV6_RX_DEPRECATED0 is a deprecated type. It is kept for backward compatibility. + */ +enum nss_ipv6_message_types { + NSS_IPV6_TX_CREATE_RULE_MSG, + NSS_IPV6_TX_DESTROY_RULE_MSG, + NSS_IPV6_RX_DEPRECATED0, + NSS_IPV6_RX_CONN_STATS_SYNC_MSG, + NSS_IPV6_RX_NODE_STATS_SYNC_MSG, + NSS_IPV6_TX_CONN_CFG_RULE_MSG, + NSS_IPV6_TX_CREATE_MC_RULE_MSG, + NSS_IPV6_TX_CONN_STATS_SYNC_MANY_MSG, + NSS_IPV6_TX_ACCEL_MODE_CFG_MSG, + NSS_IPV6_TX_CONN_CFG_INQUIRY_MSG, + NSS_IPV6_TX_CONN_TABLE_SIZE_MSG, + NSS_IPV6_TX_DSCP2PRI_CFG_MSG, + NSS_IPV6_TX_RPS_HASH_BITMAP_CFG_MSG, + NSS_IPV6_MAX_MSG_TYPES, +}; + +/** + * nss_ipv6_dscp_map_actions + * Action types mapped to DSCP values. + */ +enum nss_ipv6_dscp_map_actions { + NSS_IPV6_DSCP_MAP_ACTION_ACCEL, + NSS_IPV6_DSCP_MAP_ACTION_DONT_ACCEL, + NSS_IPV6_DSCP_MAP_ACTION_MAX, +}; + +/* + * NSS IPv6 rule creation flags. + */ +#define NSS_IPV6_RULE_CREATE_FLAG_NO_SEQ_CHECK 0x01 + /**< Do not perform TCP sequence number checks. */ +#define NSS_IPV6_RULE_CREATE_FLAG_BRIDGE_FLOW 0x02 + /**< This is a pure bridge forwarding flow. */ +#define NSS_IPV6_RULE_CREATE_FLAG_ROUTED 0x04 + /**< Rule is for a routed connection. */ +#define NSS_IPV6_RULE_CREATE_FLAG_DSCP_MARKING 0x08 + /**< Rule has for a DSCP marking configured. */ +#define NSS_IPV6_RULE_CREATE_FLAG_VLAN_MARKING 0x10 + /**< Rule has for a VLAN marking configured. */ +#define NSS_IPV6_RULE_CREATE_FLAG_ICMP_NO_CME_FLUSH 0x20 + /**< Rule for not flushing connection match entry on ICMP packet. */ +#define NSS_IPV6_RULE_UPDATE_FLAG_CHANGE_MTU 0x40 + /**< Rule updation for MTU change. */ + +/** The L2 payload is not IPv6 but consists of an encapsulating protocol that carries an IPv6 payload within it. + */ +#define NSS_IPV6_RULE_CREATE_FLAG_L2_ENCAP 0x80 + +#define NSS_IPV6_RULE_CREATE_FLAG_DROP 0x100 + /**< Drop packets. */ +#define NSS_IPV6_RULE_CREATE_FLAG_EXCEPTION 0x200 + /**< Rule to except packets. */ +#define NSS_IPV6_RULE_CREATE_FLAG_SRC_INTERFACE_CHECK 0x400 + /**< Check the source interface for the rule. */ +#define NSS_IPV6_RULE_CREATE_FLAG_NO_SRC_IDENT 0x800 + /**< Flag to indicate NSS to ignore src_ident and use value 0 for it during rule addition. */ +#define NSS_IPV6_RULE_CREATE_FLAG_NO_MAC 0x1000 + /**< Flag to bypass writing MAC addresses. */ +#define NSS_IPV6_RULE_CREATE_FLAG_EMESH_SP 0x2000 + /**< Mark rule as E-MESH Service Prioritization valid. */ + +/* + * IPv6 rule creation validity flags. + */ +#define NSS_IPV6_RULE_CREATE_CONN_VALID 0x01 /**< Connection is valid. */ +#define NSS_IPV6_RULE_CREATE_TCP_VALID 0x02 /**< TCP protocol fields are valid. */ +#define NSS_IPV6_RULE_CREATE_PPPOE_VALID 0x04 /**< PPPoE fields are valid. */ +#define NSS_IPV6_RULE_CREATE_QOS_VALID 0x08 /**< QoS fields are valid. */ +#define NSS_IPV6_RULE_CREATE_VLAN_VALID 0x10 /**< VLAN fields are valid. */ +#define NSS_IPV6_RULE_CREATE_DSCP_MARKING_VALID 0x20 + /**< DSCP marking fields are valid. */ +#define NSS_IPV6_RULE_CREATE_VLAN_MARKING_VALID 0x40 + /**< VLAN marking fields are valid. */ +#define NSS_IPV6_RULE_CREATE_SRC_MAC_VALID 0x80 + /**< Source MAC address fields are valid. */ +#define NSS_IPV6_RULE_CREATE_NEXTHOP_VALID 0x100 + /**< Next hop interface number fields are valid. */ +#define NSS_IPV6_RULE_CREATE_RPS_VALID 0x200 /**< RPS for core selection is valid. */ +#define NSS_IPV6_RULE_CREATE_DEST_MAC_VALID 0x400 + /**< Destination MAC address fields are valid. */ +#define NSS_IPV6_RULE_CREATE_IGS_VALID 0x800 /**< Ingress shaping fields are valid. */ +#define NSS_IPV6_RULE_CREATE_IDENTIFIER_VALID 0x1000 /**< Identifier is valid. */ + +/* + * Multicast command rule flags + */ +#define NSS_IPV6_MC_RULE_CREATE_FLAG_MC_UPDATE 0x01 /**< Multicast rule update. */ +#define NSS_IPV6_MC_RULE_CREATE_FLAG_MC_EMESH_SP 0x02 + /**< Mark multicast rule as E-MESH Service Prioritization valid. */ + +/* + * Multicast command validity flags + */ +#define NSS_IPV6_MC_RULE_CREATE_FLAG_QOS_VALID 0x01 + /**< QoS fields are valid. */ +#define NSS_IPV6_MC_RULE_CREATE_FLAG_DSCP_MARKING_VALID 0x02 + /**< DSCP fields are valid. */ +#define NSS_IPV6_MC_RULE_CREATE_FLAG_INGRESS_VLAN_VALID 0x04 + /**< Ingress VLAN fields are valid. */ +#define NSS_IPV6_MC_RULE_CREATE_FLAG_INGRESS_PPPOE 0x08 + /**< Ingress PPPoE fields are valid. */ +#define NSS_IPV6_MC_RULE_CREATE_FLAG_IGS_VALID 0x10 + /**< Ingress shaping fields are valid. */ + +/* + * Per-interface rule flags for a multicast connection (to be used with the rule_flags + * field of nss_ipv6_mc_if_rule structure). + */ +#define NSS_IPV6_MC_RULE_CREATE_IF_FLAG_BRIDGE_FLOW 0x01 + /**< Bridge flow. */ +#define NSS_IPV6_MC_RULE_CREATE_IF_FLAG_ROUTED_FLOW 0x02 + /**< Routed flow. */ +#define NSS_IPV6_MC_RULE_CREATE_IF_FLAG_JOIN 0x04 + /**< Interface has joined the flow. */ +#define NSS_IPV6_MC_RULE_CREATE_IF_FLAG_LEAVE 0x08 + /**< Interface has left the flow. */ + +/* + * Per-interface valid flags for a multicast connection (to be used with the valid_flags + * field of nss_ipv6_mc_if_rule structure). + */ +#define NSS_IPV6_MC_RULE_CREATE_IF_FLAG_VLAN_VALID 0x01 + /**< VLAN fields are valid. */ +#define NSS_IPV6_MC_RULE_CREATE_IF_FLAG_PPPOE_VALID 0x02 + /**< PPPoE fields are valid. */ + +/* + * Source MAC address valid flags (to be used with mac_valid_flags field of nss_ipv6_src_mac_rule structure) + */ +#define NSS_IPV6_SRC_MAC_FLOW_VALID 0x01 + /**< MAC address for the flow interface is valid. */ +#define NSS_IPV6_SRC_MAC_RETURN_VALID 0x02 + /**< MAC address for the return interface is valid. */ + +/* + * Identifier valid flags (to be used with identifier_valid_flags field of nss_ipv6_identifier_rule structure) + */ +#define NSS_IPV6_FLOW_IDENTIFIER_VALID 0x01 + /**< Identifier for flow direction is valid. */ +#define NSS_IPV6_RETURN_IDENTIFIER_VALID 0x02 + /**< Identifier for return direction is valid. */ + +/** + * nss_ipv6_exception_events + * Exception events from an IPv6 bridge or route handler. + */ +enum nss_ipv6_exception_events { + NSS_IPV6_EXCEPTION_EVENT_ICMP_HEADER_INCOMPLETE, + NSS_IPV6_EXCEPTION_EVENT_ICMP_UNHANDLED_TYPE, + NSS_IPV6_EXCEPTION_EVENT_ICMP_IPV6_HEADER_INCOMPLETE, + NSS_IPV6_EXCEPTION_EVENT_ICMP_IPV6_UDP_HEADER_INCOMPLETE, + NSS_IPV6_EXCEPTION_EVENT_ICMP_IPV6_TCP_HEADER_INCOMPLETE, + NSS_IPV6_EXCEPTION_EVENT_ICMP_IPV6_UNKNOWN_PROTOCOL, + NSS_IPV6_EXCEPTION_EVENT_ICMP_NO_ICME, + NSS_IPV6_EXCEPTION_EVENT_ICMP_FLUSH_TO_HOST, + NSS_IPV6_EXCEPTION_EVENT_TCP_HEADER_INCOMPLETE, + NSS_IPV6_EXCEPTION_EVENT_TCP_NO_ICME, + NSS_IPV6_EXCEPTION_EVENT_TCP_SMALL_HOP_LIMIT, + NSS_IPV6_EXCEPTION_EVENT_TCP_NEEDS_FRAGMENTATION, + NSS_IPV6_EXCEPTION_EVENT_TCP_FLAGS, + NSS_IPV6_EXCEPTION_EVENT_TCP_SEQ_EXCEEDS_RIGHT_EDGE, + NSS_IPV6_EXCEPTION_EVENT_TCP_SMALL_DATA_OFFS, + NSS_IPV6_EXCEPTION_EVENT_TCP_BAD_SACK, + NSS_IPV6_EXCEPTION_EVENT_TCP_BIG_DATA_OFFS, + NSS_IPV6_EXCEPTION_EVENT_TCP_SEQ_BEFORE_LEFT_EDGE, + NSS_IPV6_EXCEPTION_EVENT_TCP_ACK_EXCEEDS_RIGHT_EDGE, + NSS_IPV6_EXCEPTION_EVENT_TCP_ACK_BEFORE_LEFT_EDGE, + NSS_IPV6_EXCEPTION_EVENT_UDP_HEADER_INCOMPLETE, + NSS_IPV6_EXCEPTION_EVENT_UDP_NO_ICME, + NSS_IPV6_EXCEPTION_EVENT_UDP_SMALL_HOP_LIMIT, + NSS_IPV6_EXCEPTION_EVENT_UDP_NEEDS_FRAGMENTATION, + NSS_IPV6_EXCEPTION_EVENT_WRONG_TARGET_MAC, + NSS_IPV6_EXCEPTION_EVENT_HEADER_INCOMPLETE, + NSS_IPV6_EXCEPTION_EVENT_UNKNOWN_PROTOCOL, + NSS_IPV6_EXCEPTION_EVENT_IVID_MISMATCH, + NSS_IPV6_EXCEPTION_EVENT_IVID_MISSING, + NSS_IPV6_EXCEPTION_EVENT_DSCP_MARKING_MISMATCH, + NSS_IPV6_EXCEPTION_EVENT_VLAN_MARKING_MISMATCH, + NSS_IPV6_EXCEPTION_EVENT_INTERFACE_MISMATCH, + NSS_IPV6_EXCEPTION_EVENT_GRE_NO_ICME, + NSS_IPV6_EXCEPTION_EVENT_GRE_NEEDS_FRAGMENTATION, + NSS_IPV6_EXCEPTION_EVENT_GRE_SMALL_HOP_LIMIT, + NSS_IPV6_EXCEPTION_EVENT_DESTROY, + NSS_IPV6_EXCEPTION_EVENT_ICMP_IPV6_UDPLITE_HEADER_INCOMPLETE, + NSS_IPV6_EXCEPTION_EVENT_UDPLITE_HEADER_INCOMPLETE, + NSS_IPV6_EXCEPTION_EVENT_UDPLITE_NO_ICME, + NSS_IPV6_EXCEPTION_EVENT_UDPLITE_SMALL_HOP_LIMIT, + NSS_IPV6_EXCEPTION_EVENT_UDPLITE_NEEDS_FRAGMENTATION, + NSS_IPV6_EXCEPTION_EVENT_MC_UDP_NO_ICME, + NSS_IPV6_EXCEPTION_EVENT_MC_MEM_ALLOC_FAILURE, + NSS_IPV6_EXCEPTION_EVENT_MC_UPDATE_FAILURE, + NSS_IPV6_EXCEPTION_EVENT_MC_PBUF_ALLOC_FAILURE, + NSS_IPV6_EXCEPTION_EVENT_ESP_HEADER_INCOMPLETE, + NSS_IPV6_EXCEPTION_EVENT_ESP_NO_ICME, + NSS_IPV6_EXCEPTION_EVENT_ESP_IP_FRAGMENT, + NSS_IPV6_EXCEPTION_EVENT_ESP_SMALL_HOP_LIMIT, + NSS_IPV6_EXCEPTION_EVENT_ESP_NEEDS_FRAGMENTATION, + NSS_IPV6_EXCEPTION_EVENT_TUNIPIP6_NO_ICME, + NSS_IPV6_EXCEPTION_EVENT_TUNIPIP6_SMALL_HOP_LIMIT, + NSS_IPV6_EXCEPTION_EVENT_TUNIPIP6_NEEDS_FRAGMENTATION, + NSS_IPV6_EXCEPTION_EVENT_PPPOE_BRIDGE_NO_ICME, + NSS_IPV6_EXCEPTION_EVENT_DONT_FRAG_SET, + NSS_IPV6_EXCEPTION_EVENT_REASSEMBLY_NOT_SUPPORTED, + NSS_IPV6_EXCEPTION_EVENT_PPPOE_NO_SESSION, + NSS_IPV6_EXCEPTION_EVENT_ICMP_IPV6_GRE_HEADER_INCOMPLETE, + NSS_IPV6_EXCEPTION_EVENT_ICMP_IPV6_ESP_HEADER_INCOMPLETE, + NSS_IPV6_EXCEPTION_EVENT_EMESH_PRIO_MISMATCH, + NSS_IPV6_EXCEPTION_EVENT_MAX +}; + +/** + * nss_ipv6_5tuple + * Common 5-tuple information. + */ +struct nss_ipv6_5tuple { + uint32_t flow_ip[4]; /**< Flow IP address. */ + uint32_t flow_ident; /**< Flow identifier (e.g., TCP or UDP port). */ + uint32_t return_ip[4]; /**< Return IP address. */ + uint32_t return_ident; /**< Return identier (e.g., TCP or UDP port). */ + uint8_t protocol; /**< Protocol number. */ + uint8_t reserved[3]; /**< Padded for alignment. */ +}; + +/** + * nss_ipv6_connection_rule + * Information for creating a connection. + */ +struct nss_ipv6_connection_rule { + uint16_t flow_mac[3]; /**< Flow MAC address. */ + uint16_t return_mac[3]; /**< Return MAC address. */ + int32_t flow_interface_num; /**< Flow interface number. */ + int32_t return_interface_num; /**< Return interface number. */ + uint32_t flow_mtu; /**< MTU for the flow interface. */ + uint32_t return_mtu; /**< MTU for the return interface. */ +}; + +/** + * nss_ipv6_pppoe_rule + * Information for PPPoE connection rules. + */ +struct nss_ipv6_pppoe_rule { + uint32_t flow_if_exist; + /**< PPPoE interface existence flag for the flow direction. */ + int32_t flow_if_num; + /**< PPPoE interface number for the flow direction. */ + uint32_t return_if_exist; + /**< PPPoE interface existence flag for the return direction. */ + int32_t return_if_num; + /**< PPPoE interface number for the return direction. */ +}; + +/** + * nss_ipv6_dscp_rule + * Information for DSCP connection rules. + */ +struct nss_ipv6_dscp_rule { + uint8_t flow_dscp; /**< Egress DSCP value for the flow direction. */ + uint8_t return_dscp; /**< Egress DSCP value for the return direction. */ + uint8_t reserved[2]; /**< Padded for alignment. */ +}; + +/** + * nss_ipv6_vlan_rule + * Information for VLAN connection rules. + */ +struct nss_ipv6_vlan_rule { + uint32_t ingress_vlan_tag; /**< VLAN tag for the ingress packets. */ + uint32_t egress_vlan_tag; /**< VLAN tag for egress packets. */ +}; + +/** + * nss_ipv6_nexthop + * Information for the next hop interface numbers. + * + * A next hop is the next interface that will receive the packet as opposed to + * the final interface when the packet leaves the device. + */ +struct nss_ipv6_nexthop { + /** + * Next hop interface number of the flow direction (from which the connection + * originated). + */ + int32_t flow_nexthop; + /** + * Next hop interface number of the return direction (to which the connection + * is destined). + */ + int32_t return_nexthop; +}; + +/** + * nss_ipv6_protocol_tcp_rule + * Information for TCP connection rules. + */ +struct nss_ipv6_protocol_tcp_rule { + uint32_t flow_max_window; + /**< Largest seen window for the flow direction. */ + uint32_t flow_end; + /**< Largest seen sequence + segment length for the flow direction. */ + uint32_t flow_max_end; + /**< Largest seen ack + max(1, win) for the flow direction. */ + uint32_t return_max_window; + /**< Largest seen window for the return direction. */ + uint32_t return_end; + /**< Largest seen sequence + segment length for the return direction. */ + uint32_t return_max_end; + /**< Largest seen ack + max(1, win) for the return direction. */ + uint8_t flow_window_scale; + /**< Window scaling factor for the flow direction. */ + uint8_t return_window_scale; + /**< Window scaling factor for the return direction. */ + uint16_t reserved; + /**< Alignment padding. */ +}; + +/** + * nss_ipv6_igs_rule + * Information for ingress shaping connection rules. + */ +struct nss_ipv6_igs_rule { + uint16_t igs_flow_qos_tag; + /**< Ingress shaping QoS tag associated with this rule for the flow direction. */ + uint16_t igs_return_qos_tag; + /**< Ingress shaping QoS tag associated with this rule for the return direction. */ +}; + +/** + * nss_ipv6_qos_rule + * Information for QoS connection rules. + */ +struct nss_ipv6_qos_rule { + uint32_t flow_qos_tag; + /**< QoS tag associated with this rule for the flow direction. */ + uint32_t return_qos_tag; + /**< QoS tag associated with this rule for the return direction. */ +}; + +/** + * nss_ipv6_src_mac_rule + * Information for source MAC address rules. + */ +struct nss_ipv6_src_mac_rule { + uint32_t mac_valid_flags; /**< MAC address validity flags. */ + uint16_t flow_src_mac[3]; /**< Source MAC address for the flow direction. */ + uint16_t return_src_mac[3]; /**< Source MAC address for the return direction. */ +}; + +/** + * nss_ipv6_rps_rule + * RPS rule structure. + */ +struct nss_ipv6_rps_rule { + uint8_t flow_rps; + /**< RPS for core selection for flow direction. */ + uint8_t return_rps; + /**< RPS for core selection for return direction. */ + uint8_t reserved[2]; + /**< Padded for alignment. */ +}; + +/** + * nss_ipv6_identifier_rule + * Identifier rule structure. + */ +struct nss_ipv6_identifier_rule { + uint32_t identifier_valid_flags; + /**< Identifier validity flags. */ + uint32_t flow_identifier; + /**< Identifier for flow direction. */ + uint32_t return_identifier; + /**< Identifier for return direction. */ +}; + +/** + * nss_ipv6_error_response_types + * Error types for IPv6 messages. + */ +enum nss_ipv6_error_response_types { + NSS_IPV6_UNKNOWN_MSG_TYPE = 1, /**< Unknown error. */ + NSS_IPV6_CR_INVALID_PNODE_ERROR, /**< Invalid interface number. */ + NSS_IPV6_CR_MISSING_CONNECTION_RULE_ERROR, /**< Missing connection rule. */ + NSS_IPV6_CR_BUFFER_ALLOC_FAIL_ERROR, /**< Buffer allocation failed. */ + NSS_IPV6_DR_NO_CONNECTION_ENTRY_ERROR, + /**< No connection was found to delete. */ + NSS_IPV6_CR_CONN_CFG_ALREADY_CONFIGURED_ERROR, + /**< Connection configuration was already done once. */ + + NSS_IPV6_CR_CONN_CFG_NOT_MULTIPLE_OF_QUANTA_ERROR, + /**< Input for connection configuration is not a multiple of quanta. */ + + /** + * Input for connection configuration exceeds the maximum number of supported + * connections. + */ + NSS_IPV6_CR_CONN_CFG_EXCEEDS_LIMIT_ERROR, + + /** + * Memory allocation for connection configuration failed at the NSS firmware. + */ + NSS_IPV6_CR_CONN_CFG_MEM_ALLOC_FAIL_ERROR, + + NSS_IPV6_CR_MULTICAST_INVALID_PROTOCOL, + /**< Invalid L4 protocol for creating a multicast rule. */ + NSS_IPV6_CR_MULTICAST_UPDATE_INVALID_FLAGS, + /**< Invalid multicast flags for updating multicast. */ + NSS_IPV6_CR_MULTICAST_UPDATE_INVALID_IF, + /**< Invalid interface for updating multicast. */ + NSS_IPV6_CR_ACCEL_MODE_CONFIG_INVALID, + /**< Invalid config value for acceleration mode. */ + NSS_IPV6_CR_INVALID_MSG_ERROR, + /**< Invalid message size error. */ + NSS_IPV6_CR_DSCP2PRI_PRI_INVALID, + /**< Priority value out of range error. */ + NSS_IPV6_CR_DSCP2PRI_CONFIG_INVALID, + /**< Invalid DSCP value. */ + NSS_IPV6_CR_INVALID_RPS, + /**< Invalid RPS Value. */ + NSS_IPV6_HASH_BITMAP_INVALID, + /**< Invalid hash bitmap. */ + NSS_IPV6_DR_HW_DECEL_FAIL_ERROR, + /**< Hardware deceleration fail error. */ + NSS_IPV6_CR_RETURN_EXIST_ERROR, + /**< Rule creation failed because a 5-tuple return already exists. */ + NSS_IPV6_CR_INVALID_IDENTIFIER, + /**< Invalid identifier value. */ + NSS_IPV6_CR_EMESH_SP_CONFIG_INVALID, + /**< Rule creation failed because Qos tag was not set for a Emesh SP rule. */ + NSS_IPV6_LAST + /**< Maximum number of error responses. */ +}; + +/** + * nss_ipv6_rule_create_msg + * IPv6 rule for creating sub-messages. + */ +struct nss_ipv6_rule_create_msg { + /* + * Request + */ + uint16_t valid_flags; + /**< Bit flags associated with the validity of parameters. */ + uint16_t rule_flags; + /**< Bit flags associated with the rule. */ + struct nss_ipv6_5tuple tuple; + /**< Holds values of the 5 tuple. */ + struct nss_ipv6_connection_rule conn_rule; + /**< Basic connection-specific data. */ + struct nss_ipv6_protocol_tcp_rule tcp_rule; + /**< Protocol-related accleration parameters. */ + struct nss_ipv6_pppoe_rule pppoe_rule; + /**< PPPoE-related accleration parameters. */ + struct nss_ipv6_qos_rule qos_rule; + /**< QoS-related accleration parameters. */ + struct nss_ipv6_dscp_rule dscp_rule; + /**< DSCP-related accleration parameters. */ + struct nss_ipv6_vlan_rule vlan_primary_rule; + /**< VLAN-related accleration parameters. */ + struct nss_ipv6_vlan_rule vlan_secondary_rule; + /**< VLAN-related accleration parameters. */ + struct nss_ipv6_src_mac_rule src_mac_rule; + /**< Source MAC address-related acceleration parameters. */ + struct nss_ipv6_nexthop nexthop_rule; + /**< Parameters related to the next hop. */ + struct nss_ipv6_rps_rule rps_rule; + /**< RPS parameter. */ + struct nss_ipv6_igs_rule igs_rule; + /**< Ingress shaping related accleration parameters. */ + struct nss_ipv6_identifier_rule identifier; + /**< Rule for adding identifier. */ +}; + +/** + * nss_ipv6_inquiry_msg + * IPv6 connection inquiry sub-messages. + */ +struct nss_ipv6_inquiry_msg { + /** + * Request by 5-tuple and response in other items. + */ + struct nss_ipv6_rule_create_msg rr; +}; + +/** + * nss_ipv6_mc_if_rule + * IPv6 multicast rule for creating a per-interface payload. + */ +struct nss_ipv6_mc_if_rule { + uint16_t rule_flags; + /**< Bit flags associated with the rule for this interface. */ + + /** + * Bit flags associated with the validity of parameters for this interface. + */ + uint16_t valid_flags; + + uint32_t egress_vlan_tag[MAX_VLAN_DEPTH]; + /**< VLAN tag stack for the egress packets. */ + int32_t pppoe_if_num; /**< PPPoE interface number. */ + uint32_t if_num; /**< Interface number. */ + uint32_t if_mtu; /**< MTU of the interface. */ + uint16_t if_mac[3]; /**< Interface MAC address. */ + uint8_t reserved[2]; /**< Reserved 2 bytes for alignment. */ +}; + +/** + * nss_ipv6_mc_rule_create_msg + * IPv6 multicast rule for creating sub-messages. + */ +struct nss_ipv6_mc_rule_create_msg { + struct nss_ipv6_5tuple tuple; /**< Holds values of the 5 tuple. */ + + uint32_t rule_flags; /**< Multicast command rule flags. */ + uint32_t valid_flags; /**< Multicast command validity flags. */ + uint32_t src_interface_num; + /**< Source interface number (virtual or physical). */ + uint32_t ingress_vlan_tag[MAX_VLAN_DEPTH]; + /**< VLAN tag stack for the ingress packets. */ + uint32_t qos_tag; /**< QoS tag for the flow. */ + uint16_t dest_mac[3]; /**< Destination multicast MAC address. */ + uint16_t if_count; /**< Number of destination interfaces. */ + uint8_t egress_dscp; /**< Egress DSCP value for the flow. */ + uint8_t reserved[1]; /**< Reserved 1 byte for alignment. */ + uint16_t igs_qos_tag; /**< Ingress shaping QoS tag for the flow. */ + + struct nss_ipv6_mc_if_rule if_rule[NSS_MC_IF_MAX]; + /**< Per-interface information. */ +}; + +/** + * nss_ipv6_rule_destroy_msg + * IPv6 rule for deleting sub-messages. + */ +struct nss_ipv6_rule_destroy_msg { + struct nss_ipv6_5tuple tuple; /**< Holds values of the 5 tuple. */ +}; + +/** + * nss_ipv6_rule_conn_get_table_size_msg + * IPv6 rule for fetching connection tables size. + */ +struct nss_ipv6_rule_conn_get_table_size_msg { + uint32_t num_conn; + /**< Number of supported IPv6 connections. */ + uint32_t ce_table_size; + /**< Size of the connection entry table in NSS firmware. */ + uint32_t cme_table_size; + /**< Size of the connection match entry table in NSS firmware. */ +}; + +/** + * nss_ipv6_rule_conn_cfg_msg + * IPv6 rule for connection configuration sub-messages. + */ +struct nss_ipv6_rule_conn_cfg_msg { + uint32_t num_conn; /**< Number of supported IPv6 connections. */ + uint32_t ce_mem; /**< Memory allocated by host for connection entries table. */ + uint32_t cme_mem; /**< Memory allocated by host for connection match entries table. */ +}; + +/* + * IPv6 rule synchronization reasons. + */ +#define NSS_IPV6_RULE_SYNC_REASON_STATS 0 + /**< Rule for synchronizing statistics. */ +#define NSS_IPV6_RULE_SYNC_REASON_FLUSH 1 + /**< Rule for flushing a cache entry. */ +#define NSS_IPV6_RULE_SYNC_REASON_EVICT 2 + /**< Rule for evicting a cache entry. */ +#define NSS_IPV6_RULE_SYNC_REASON_DESTROY 3 + /**< Rule for destroying a cache entry (requested by the host OS). */ + +/** + * nss_ipv6_conn_sync + * IPv6 connection synchronization message. + */ +struct nss_ipv6_conn_sync { + uint32_t reserved; /**< Reserved field for backward compatibility. */ + uint8_t protocol; /**< Protocol number. */ + uint32_t flow_ip[4]; /**< Flow IP address. */ + uint32_t flow_ident; /**< Flow identifier (e.g., port). */ + uint32_t flow_max_window; /**< Largest seen window for the flow direction. */ + + /** + * Largest seen sequence + segment length for the flow direction. + */ + uint32_t flow_end; + + uint32_t flow_max_end; + /**< Largest seen ack + max(1, win) for the flow direction. */ + uint32_t flow_rx_packet_count; /**< Rx packet count for the flow interface. */ + uint32_t flow_rx_byte_count; /**< Rx byte count for the flow interface. */ + uint32_t flow_tx_packet_count; /**< Tx packet count for the flow interface. */ + uint32_t flow_tx_byte_count; /**< Tx byte count for the flow interface. */ + uint32_t return_ip[4]; /**< Return IP address. */ + uint32_t return_ident; /**< Return identier (e.g., port). */ + uint32_t return_max_window; + /**< Largest seen window for the return direction. */ + + /** + * Largest seen sequence + segment length for the return direction. + */ + uint32_t return_end; + + uint32_t return_max_end; + /**< Largest seen ack + max(1, win) for the return direction. */ + uint32_t return_rx_packet_count; + /**< Rx packet count for the return interface. */ + uint32_t return_rx_byte_count; + /**< Rx byte count for the return interface. */ + uint32_t return_tx_packet_count; + /**< Tx packet count for the return interface. */ + uint32_t return_tx_byte_count; + /**< Tx byte count for the return interface. */ + uint32_t inc_ticks; /**< Number of ticks since the last synchronization. */ + uint32_t reason; /**< Reason for the synchronization. */ + uint8_t flags; /**< Bit flags associated with the rule. */ + uint32_t qos_tag; /**< QoS tag. */ + uint32_t cause; /**< Flush cause associated with the rule. */ +}; + +/** + * nss_ipv6_conn_sync_many_msg + * Information for a multiple IPv6 connection statistics synchronization message. + */ +struct nss_ipv6_conn_sync_many_msg { + /* Request. */ + uint16_t index; /**< Request connection statistics from the index. */ + uint16_t size; /**< Buffer size of this message. */ + + /* Response. */ + uint16_t next; /**< Firmware response for the next connection to be requested. */ + uint16_t count; /**< Number of synchronized connections included in this message. */ + + struct nss_ipv6_conn_sync conn_sync[]; /**< Array for the statistics. */ +}; + +/** + * nss_ipv6_accel_mode_cfg_msg + * IPv6 acceleration mode configuration. + */ +struct nss_ipv6_accel_mode_cfg_msg { + uint32_t mode; /**< Type of acceleration mode. */ +}; + +/** + * nss_ipv6_dscp2pri_cfg_msg + * IPv6 dscp2pri configuration msg. + */ +struct nss_ipv6_dscp2pri_cfg_msg { + uint8_t dscp; /**< Value of DSCP. */ + uint8_t priority; /**< Corresponding priority. */ +}; + +/** + * nss_ipv6_rps_hash_bitmap_cfg_msg + * RPS hash mask configuration. + * + * The bitmap represents the host cores to which NSS firmware can steer + * packets based on packet hash. The least significant bit represents core0. + */ +struct nss_ipv6_rps_hash_bitmap_cfg_msg { + uint32_t hash_bitmap; /**< Hash mask. */ +}; + +/** + * nss_ipv6_node_sync + * IPv6 node synchronization statistics. + */ +struct nss_ipv6_node_sync { + struct nss_cmn_node_stats node_stats; /**< Common node statistics. */ + uint32_t ipv6_connection_create_requests; + /**< Number of connection create requests. */ + + /** + * Number of connection create requests that collided with the existing entries. + */ + uint32_t ipv6_connection_create_collisions; + + /** + * Number of connection create requests that had invalid interfaces. + */ + uint32_t ipv6_connection_create_invalid_interface; + + uint32_t ipv6_connection_destroy_requests; + /**< Number of connection destroy requests. */ + uint32_t ipv6_connection_destroy_misses; + /**< Number of connection destroy requests that missed the cache. */ + uint32_t ipv6_connection_hash_hits; /**< Number of connection hash hits. */ + uint32_t ipv6_connection_hash_reorders; /**< Number of connection hash reorders. */ + uint32_t ipv6_connection_flushes; /**< Number of connection flushes. */ + uint32_t ipv6_connection_evictions; /**< Number of connection evictions. */ + uint32_t ipv6_fragmentations; /**< Number of successful fragmentations. */ + uint32_t ipv6_frag_fails; /**< Number of fragmentation fails. */ + uint32_t ipv6_dropped_by_rule; /**< Number of packets dropped by a drop rule.*/ + uint32_t ipv6_mc_connection_create_requests; + /**< Number of multicast connection create requests. */ + uint32_t ipv6_mc_connection_update_requests; + /**< Number of multicast connection update requests. */ + + /** + * Number of multicast connection create requests that had invalid interfaces. + */ + uint32_t ipv6_mc_connection_create_invalid_interface; + + uint32_t ipv6_mc_connection_destroy_requests; + /**< Number of multicast connection destroy requests. */ + + /** + * Number of multicast connection destroy requests that missed the cache. + */ + uint32_t ipv6_mc_connection_destroy_misses; + + uint32_t ipv6_mc_connection_flushes; + /**< Number of multicast connection flushes. */ + uint32_t exception_events[NSS_IPV6_EXCEPTION_EVENT_MAX]; + /**< Number of exception events. */ +}; + +/** + * nss_ipv6_msg + * Data for sending and receiving IPv6 bridge or routing messages. + */ +struct nss_ipv6_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of an IPv6 bridge or routing message. + */ + union { + struct nss_ipv6_rule_create_msg rule_create; + /**< Create a rule. */ + struct nss_ipv6_rule_destroy_msg rule_destroy; + /**< Destroy a rule. */ + struct nss_ipv6_conn_sync conn_stats; + /**< Synchronize statistics. */ + struct nss_ipv6_node_sync node_stats; + /**< Synchronize node statistics. */ + struct nss_ipv6_rule_conn_get_table_size_msg size; + /**< Get the size for connection tables. */ + struct nss_ipv6_rule_conn_cfg_msg rule_conn_cfg; + /**< Configure a rule connection. */ + struct nss_ipv6_mc_rule_create_msg mc_rule_create; + /**< Create a multicast rule. */ + struct nss_ipv6_conn_sync_many_msg conn_stats_many; + /**< Synchronize multiple connection statistics. */ + struct nss_ipv6_accel_mode_cfg_msg accel_mode_cfg; + /**< Configure acceleration mode. */ + struct nss_ipv6_inquiry_msg inquiry; + /**< Inquiry if a connection has been created. */ + struct nss_ipv6_dscp2pri_cfg_msg dscp2pri_cfg; + /**< Configure DSCP-to-priority mapping. */ + struct nss_ipv6_rps_hash_bitmap_cfg_msg rps_hash_bitmap; + /**< Configure rps_hash_bitmap. */ + } msg; /**< Message payload. */ +}; + +/** + * nss_ipv6_stats_notification + * Data for sending IPv6 statistics. + */ +struct nss_ipv6_stats_notification { + uint32_t core_id; /**< Core ID. */ + uint64_t cmn_node_stats[NSS_STATS_NODE_MAX]; /**< Common node statistics. */ + uint64_t special_stats[NSS_IPV6_STATS_MAX]; /**< IPv6 special statistics. */ + uint64_t exception_stats[NSS_IPV6_EXCEPTION_EVENT_MAX]; /**< IPv6 exception statistics. */ +}; + +/** + * Configured IPv6 connection number to use for calculating the total number of + * connections. + */ +extern int nss_ipv6_conn_cfg; + +#ifdef __KERNEL__ + +/** + * nss_ipv6_max_conn_count + * Returns the maximum number of IPv6 connections that the NSS acceleration + * engine supports. + * + * @return + * Number of connections that can be accelerated. + */ +extern int nss_ipv6_max_conn_count(void); + +/** + * Callback function for receiving IPv6 messages. + * + * @datatypes + * nss_ipv6_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_ipv6_msg_callback_t)(void *app_data, struct nss_ipv6_msg *msg); + +/** + * nss_ipv6_tx + * Transmits an IPv6 message to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_ipv6_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_ipv6_tx(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_msg *msg); + +/** + * nss_ipv6_tx_sync + * Transmits a synchronous IPv6 message to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_ipv6_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_ipv6_tx_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_msg *msg); + +/** + * nss_ipv6_tx_with_size + * Transmits an IPv6 message with a specified size to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_ipv6_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * @param[in] size Actual size of this message. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_ipv6_tx_with_size(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_msg *msg, uint32_t size); + +/** + * nss_ipv6_notify_register + * Registers a notifier callback to forward the IPv6 messages received from the NSS + * firmware to the registered subsystem. + * + * @datatypes + * nss_ipv6_msg_callback_t + * + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_ipv6_notify_register(nss_ipv6_msg_callback_t cb, void *app_data); + +/** + * nss_ipv6_notify_unregister + * Deregisters a notifier callback from the NSS. + * + * @return + * None. + * + * @dependencies + * The notifier callback must have been previously registered. + */ +extern void nss_ipv6_notify_unregister(void); + +/** + * nss_ipv6_conn_sync_many_notify_register + * Registers a notifier callback with the NSS for connection synchronization + * message responses. + * + * @datatypes + * nss_ipv6_msg_callback_t + * + * @param[in] cb Callback function for the message. + * + * @return + * None. + */ +extern void nss_ipv6_conn_sync_many_notify_register(nss_ipv6_msg_callback_t cb); + +/** + * nss_ipv6_conn_sync_many_notify_unregister + * Degisters a notifier callback from the NSS. + * + * @return + * None. + * + * @dependencies + * The notifier callback must have been previously registered. + */ +extern void nss_ipv6_conn_sync_many_notify_unregister(void); + +/** + * nss_ipv6_get_mgr + * Gets the NSS context that is managing the IPv6 processes. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_ipv6_get_mgr(void); + +/** + * nss_ipv6_msg_init + * Initializes IPv6-specific messages. + * + * @datatypes + * nss_ipv6_msg \n + * nss_ipv6_msg_callback_t + * + * @param[in,out] nim Pointer to the NSS interface message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_ipv6_msg_init(struct nss_ipv6_msg *nim, uint16_t if_num, uint32_t type, uint32_t len, + nss_ipv6_msg_callback_t cb, void *app_data); + +/** + * nss_ipv6_register_handler + * Registers the IPv6 message handler. + * + * @return + * None. + */ +void nss_ipv6_register_handler(void); + +/** + * nss_ipv6_register_sysctl + * Registers the IPv6 system control table. + * + * @return + * None. + */ +void nss_ipv6_register_sysctl(void); + +/** + * nss_ipv6_unregister_sysctl + * Deregisters the IPv6 system control table. + * + * @return + * None. + * + * @dependencies + * The system control table must have been previously registered. + */ +void nss_ipv6_unregister_sysctl(void); + +/** + * nss_ipv6_update_conn_count + * Sets the maximum number of IPv6 connections. + * + * @param[in] ipv6_num_conn Maximum number. + * + * @return + * 0 -- Success + */ +int nss_ipv6_update_conn_count(int ipv6_num_conn); + +/** + * nss_ipv6_free_conn_tables + * Frees memory allocated for connection tables. + * + * @return + * None. + */ +void nss_ipv6_free_conn_tables(void); + +/** + * nss_ipv6_dscp_action_get + * Gets the action value of the DSCP. + * + * @param[in] dscp Value of the DSCP field. + * + * @return + * Action value of the DSCP field. + */ +enum nss_ipv6_dscp_map_actions nss_ipv6_dscp_action_get(uint8_t dscp); + +/* + * Logger APIs + */ + +/** + * nss_ipv6_log_tx_msg + * Logs an IPv6 message that is sent to the NSS firmware. + * + * @datatypes + * nss_ipv6_msg + * + * @param[in] nim Pointer to the NSS interface message. + * + * @return + * None. + */ +void nss_ipv6_log_tx_msg(struct nss_ipv6_msg *nim); + +/** + * nss_ipv6_log_rx_msg + * Logs an IPv6 message that is received from the NSS firmware. + * + * @datatypes + * nss_ipv6_msg + * + * @param[in] nim Pointer to the NSS interface message. + * + * @return + * None. + */ +void nss_ipv6_log_rx_msg(struct nss_ipv6_msg *nim); + +/** + * nss_ipv6_stats_register_notifier + * Registers a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_ipv6_stats_register_notifier(struct notifier_block *nb); + +/** + * nss_ipv6_stats_unregister_notifier + * Deregisters a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_ipv6_stats_unregister_notifier(struct notifier_block *nb); +#endif + +/** + * @} + */ + +#endif /* __NSS_IPV6_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_ipv6_reasm.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_ipv6_reasm.h new file mode 100644 index 000000000..806bf0041 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_ipv6_reasm.h @@ -0,0 +1,92 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_ipv6_reasm.h + * NSS IPv6 reassembly interface definitions. + */ + +#ifndef __NSS_IPV6_REASM_H +#define __NSS_IPV6_REASM_H + +/** + * @addtogroup nss_ipv6_reasm_subsystem + * @{ + */ + +/** + * nss_ipv6_reasm_stats + * IPv6 reassembly node statistics. + */ +enum nss_ipv6_reasm_stats { + NSS_IPV6_REASM_STATS_ALLOC_FAILS, + /**< Number of fragment queue allocation failures. */ + NSS_IPV6_REASM_STATS_TIMEOUTS, + /**< Number of expired fragment queues. */ + NSS_IPV6_REASM_STATS_DISCARDS, + /**< Number of fragment queues discarded due to malformed fragments. */ + NSS_IPV6_REASM_STATS_MAX, + /**< Maximum message type. */ +}; + +/** + * nss_ipv6_reasm_stats_notification + * Data for sending IPv6 reassembly statistics. + */ +struct nss_ipv6_reasm_stats_notification { + uint32_t core_id; /**< Core ID. */ + uint64_t cmn_node_stats[NSS_STATS_NODE_MAX]; /**< Common node statistics. */ + uint64_t ipv6_reasm_stats[NSS_IPV6_REASM_STATS_MAX]; /**< IPv6 reassembly statistics. */ +}; + +#ifdef __KERNEL__ + +/** + * nss_ipv6_reasm_stats_register_notifier + * Registers a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_ipv6_reasm_stats_register_notifier(struct notifier_block *nb); + +/** + * nss_ipv6_reasm_stats_unregister_notifier + * Deregisters a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_ipv6_reasm_stats_unregister_notifier(struct notifier_block *nb); +#endif + +/** + * @} + */ + +#endif /* __NSS_IPV6_REASM_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_l2tpv2.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_l2tpv2.h new file mode 100644 index 000000000..e36c8504f --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_l2tpv2.h @@ -0,0 +1,327 @@ +/* + ************************************************************************** + * Copyright (c) 2015, 2017-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_l2tpv2.h + * NSS L2TPv2 interface definitions. + */ + +#ifndef _NSS_L2TP_V2_H_ +#define _NSS_L2TP_V2_H_ + +/** + * @addtogroup nss_l2tpv2_subsystem + * @{ + */ + +/** + * Maximum number of supported L2TPv2 sessions. + */ +#define NSS_MAX_L2TPV2_DYNAMIC_INTERFACES 4 + +/** + * nss_l2tpv2_metadata_types + * Message types for L2TPv2 requests and responses. + */ +enum nss_l2tpv2_metadata_types { + NSS_L2TPV2_MSG_SESSION_CREATE, + NSS_L2TPV2_MSG_SESSION_DESTROY, + NSS_L2TPV2_MSG_SYNC_STATS, + NSS_L2TPV2_MSG_BIND_IPSEC_IF, + NSS_L2TPV2_MSG_MAX +}; + +/** + * nss_l2tpv2_stats_session + * L2TPv2 debug statistics. + */ +enum nss_l2tpv2_stats_session { + NSS_L2TPV2_STATS_SESSION_RX_PPP_LCP_PKTS, /**< Number of PPP LCP packets received. */ + NSS_L2TPV2_STATS_SESSION_RX_EXP_DATA_PKTS, /**< Number of Rx exceptioned packets. */ + NSS_L2TPV2_STATS_SESSION_ENCAP_PBUF_ALLOC_FAIL_PKTS, /**< Number of times packet buffer allocation failed during encapsulation. */ + NSS_L2TPV2_STATS_SESSION_DECAP_PBUF_ALLOC_FAIL_PKTS, /*< Number of times packet buffer allocation failed during decapsulation. */ + NSS_L2TPV2_STATS_SESSION_DECAP_L2TPOIPSEC_SRC_ERR, + /**< Number of packets dropped due to source error in L2TP over IPsec flow in decapsulation. */ + NSS_L2TPV2_STATS_SESSION_MAX /**< Maximum message type. */ +}; + +/** + * nss_l2tpv2_stats_notification + * L2TPv2 statistics structure. + */ +struct nss_l2tpv2_stats_notification { + uint32_t core_id; /**< Core ID. */ + uint32_t if_num; /**< Interface number. */ + uint64_t stats[NSS_L2TPV2_STATS_SESSION_MAX]; /**< L2TPv2 statistics. */ +}; + +#ifdef __KERNEL__ /* only kernel will use. */ +/** + * nss_l2tpv2_session_create_msg + * Payload for creating an L2TPv2 session. + */ +struct nss_l2tpv2_session_create_msg { + uint16_t local_tunnel_id; /**< Local identifier for the control connection. */ + uint16_t local_session_id; /**< Local identifier of session inside a tunnel. */ + uint16_t peer_tunnel_id; /**< Remote identifier for the control connection. */ + uint16_t peer_session_id; /**< Remote identifier of session inside a tunnel. */ + + uint32_t sip; /**< Local tunnel endpoint IP address. */ + uint32_t dip; /**< Remote tunnel endpoint IP address. */ + uint32_t reorder_timeout; /**< Reorder timeout for out of order packets */ + + uint16_t sport; /**< Local source port. */ + uint16_t dport; /**< Remote source port. */ + + uint8_t recv_seq; /**< Sequence number received. */ + uint8_t oip_ttl; /**< Maximum time-to-live value for outer IP packet. */ + uint8_t udp_csum; /**< UDP checksum. */ + uint8_t reserved; /**< Alignment padding. */ +}; + +/** + * nss_l2tpv2_session_destroy_msg + * Payload for deletion an L2TPv2 session. + */ +struct nss_l2tpv2_session_destroy_msg { + uint16_t local_tunnel_id; /**< ID of the local tunnel. */ + uint16_t local_session_id; /**< ID of the local session. */ +}; + +/** + * nss_l2tpv2_bind_ipsec_if_msg + * Message for binding the IPsec interface with L2TP. + * + * Message for configuring the L2TP session with an + * IPsec inner interface number. This is used when + * L2TP tunnel is enabled with IPsec. + */ +struct nss_l2tpv2_bind_ipsec_if_msg { + uint32_t ipsec_ifnum; /**< Inner IPSec interface number. */ +}; + +/** + * nss_l2tpv2_sync_session_stats_msg + * Message information for L2TPv2 synchronization statistics. + */ +struct nss_l2tpv2_sync_session_stats_msg { + struct nss_cmn_node_stats node_stats; /**< Common node statistics. */ + uint32_t rx_errors; /**< Not used. Reserved for backward compatibility. */ + uint32_t rx_seq_discards; + /**< Rx packets discarded because of a sequence number check. */ + uint32_t rx_oos_packets; /**< Number of out of sequence packets received. */ + uint32_t tx_errors; /**< Not used. Reserved for backward compatibility. */ + uint32_t tx_dropped; /**< Tx packets dropped because of encapsulation failure or next node's queue is full. */ + + /** + * Debug statistics for L2tp v2. + */ + struct { + uint32_t rx_ppp_lcp_pkts; + /**< Number of PPP LCP packets received. */ + uint32_t rx_exception_data_pkts; + /**< Data packet exceptions sent to the host. */ + uint32_t encap_pbuf_alloc_fail; + /**< Buffer allocation failure during encapsulation. */ + uint32_t decap_pbuf_alloc_fail; + /**< Buffer allocation failure during decapsulation. */ + uint32_t decap_l2tpoipsec_src_error; + /**< Packets dropped due to the wrong source for the L2TPoIPsec flow. */ + } debug_stats; /**< Debug statistics object for l2tp v2. */ +}; + +/** + * nss_l2tpv2_msg + * Data for sending and receiving L2TPv2 messages. + */ +struct nss_l2tpv2_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of an L2TPv2 message. + */ + union { + struct nss_l2tpv2_session_create_msg session_create_msg; + /**< Session create message. */ + struct nss_l2tpv2_session_destroy_msg session_destroy_msg; + /**< Session delete message. */ + struct nss_l2tpv2_sync_session_stats_msg stats; + /**< Session statistics. */ + struct nss_l2tpv2_bind_ipsec_if_msg bind_ipsec_if_msg; + /**< Bind IPsec interface message. */ + } msg; /**< Message payload. */ +}; + +/** + * Callback function for receiving L2TPv2 messages. + * + * @datatypes + * nss_l2tpv2_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_l2tpv2_msg_callback_t)(void *app_data, struct nss_l2tpv2_msg *msg); + +/** + * nss_l2tpv2_tx + * Sends L2TPv2 messages to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_l2tpv2_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_l2tpv2_tx(struct nss_ctx_instance *nss_ctx, struct nss_l2tpv2_msg *msg); + +/** + * nss_l2tpv2_get_context. + * Gets the L2TPv2 context used in L2TPv2 messages sent to the NSS. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_l2tpv2_get_context(void); + +/** + * Callback function for receiving L2TPv2 tunnel data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_l2tpv2_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * nss_register_l2tpv2_if + * Registers the L2TPv2 tunnel interface with the NSS for sending and + * receiving messages. + * + * @datatypes + * nss_l2tpv2_callback_t \n + * nss_l2tpv2_msg_callback_t \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] l2tpv2_callback Callback for the L2TP tunnel data. + * @param[in] msg_callback Callback for the L2TP tunnel message. + * @param[in] netdev Pointer to the associated network device. + * @param[in] features SKB types supported by this interface. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_register_l2tpv2_if(uint32_t if_num, nss_l2tpv2_callback_t l2tpv2_callback, + nss_l2tpv2_msg_callback_t msg_callback, struct net_device *netdev, uint32_t features); + +/** + * nss_unregister_l2tpv2_if + * Deregisters the L2TPv2 tunnel interface from the NSS. + * + * @param[in] if_num NSS interface number. + * + * @return + * None. + * + * @dependencies + * The tunnel interface must have been previously registered. + */ +extern void nss_unregister_l2tpv2_if(uint32_t if_num); + +/** + * nss_l2tpv2_msg_init + * Initializes an L2TPv2 message. + * + * @datatypes + * nss_l2tpv2_msg + * + * @param[in,out] ncm Pointer to the message. + * @param[in] if_num Interface number + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Pointer to the message callback. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_l2tpv2_msg_init(struct nss_l2tpv2_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data); + +/** + * nss_l2tpv2_register_handler + * Registers the L2TPv2 interface with the NSS debug statistics handler. + * + * @return + * None. + */ +extern void nss_l2tpv2_register_handler(void); + +/** + * nss_l2tpv2_session_debug_stats_get + * Gets L2TPv2 NSS session debug statistics. + * + * @param[out] stats_mem Pointer to the memory address, which must be large + * enough to hold all the statistics. + * + * @return + * None. + */ +extern void nss_l2tpv2_session_debug_stats_get(void *stats_mem); + +/** + * nss_l2tpv2_stats_register_notifier + * Registers a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_l2tpv2_stats_register_notifier(struct notifier_block *nb); + +/** + * nss_l2tpv2_stats_unregister_notifier + * Deregisters a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_l2tpv2_stats_unregister_notifier(struct notifier_block *nb); +#endif /*__KERNEL__ */ + +/** + * @} + */ + +#endif /* _NSS_L2TP_V2_H_ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_lag.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_lag.h new file mode 100644 index 000000000..4e7e7ea25 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_lag.h @@ -0,0 +1,211 @@ +/* + ************************************************************************** + * Copyright (c) 2014, 2015, 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_lag.h + * NSS LAG APIs + */ + +/** + * @addtogroup nss_lag_subsystem + * @{ + */ + +/** + * nss_lag_metadata_types + * Types of LAG metadata. + */ +enum nss_lag_metadata_types { + NSS_TX_METADATA_LAG_STATE_CHANGE = 0, + NSS_TX_METADATA_LAG_MAX, +}; + +/** + * nss_lag_state_change_ev + * LAG change events. + */ +enum nss_lag_state_change_ev { + NSS_LAG_RELEASE = 0, + NSS_LAG_ENSLAVE = 1, +}; + +/** + * nss_lag_error_types + * LAG return values. + */ +enum nss_lag_error_types { + NSS_LAG_ERROR_EINTERFACE = 1, + NSS_LAG_ERROR_EMSG = 2, +}; + +/** + * nss_lag_state_change + * Link aggregation (LAG) state changes. + */ +struct nss_lag_state_change { + uint32_t lagid; /**< ID of the link aggregation group. */ + uint32_t interface; + /**< Physical interface on which the state change occurred. */ + enum nss_lag_state_change_ev event; /**< Type of state change event. */ +}; + +/** + * nss_lag_msg + * Data for sending and receiving LAG messages. + */ +struct nss_lag_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a LAG message. + */ + union { + struct nss_lag_state_change state; + /**< State change message. */ + } msg; /**< Message payload for LAG configuration messages exchanged with NSS core. */ +}; + +/** + * nss_lag_tx + * Sends a LAG message to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_lag_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_lag_tx(struct nss_ctx_instance *nss_ctx, struct nss_lag_msg *msg); + +/** + * Callback function for receiving LAG data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] dev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_lag_callback_t)(struct net_device *dev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * Callback function for receiving a LAG message. + * + * @datatypes + * nss_lag_msg + * + * @param[in] ctx Pointer to the application context for this message. + * @param[in] nm Pointer to the message data. + */ +typedef void (*nss_lag_msg_callback_t)(void *ctx, struct nss_lag_msg *nm); + +/** + * Callback function for receiving a LAG event. + * + * @datatypes + * nss_lag_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_lag_event_callback_t)(void *app_data, struct nss_lag_msg *msg); + +/** + * nss_register_lag_if + * Registers the LAG interface with the NSS for sending and receiving data + * and messages. + * + * @datatypes + * nss_lag_callback_t \n + * nss_lag_event_callback_t \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] lag_cb Callback to receive LAG data. + * @param[in] lag_ev_cb Callback to receive LAG events. + * @param[in] netdev Pointer to the associated network device. + * + * @return + * Pointer to the NSS core context. + */ +extern void *nss_register_lag_if(uint32_t if_num, + nss_lag_callback_t lag_cb, + nss_lag_event_callback_t lag_ev_cb, + struct net_device *netdev); + +/** + * nss_unregister_lag_if + * Deregisters the LAG interface from the NSS. + * + * @param[in] if_num LAG interface number + * + * @return + * None. + * + * @dependencies + * The LAG interface must have been previously registered. + */ +extern void nss_unregister_lag_if(uint32_t if_num); + +/** + * nss_lag_msg_init + * Initializes a LAG message. + * + * @datatypes + * nss_lag_msg \n + * nss_lag_msg_callback_t + * + * @param[in,out] nlm Pointer to the message. + * @param[in] lag_num LAG interface number. + * @param[in] type Type of buffer. + * @param[in] len Length of the buffer. + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_lag_msg_init(struct nss_lag_msg *nlm, uint16_t lag_num, uint32_t type, uint32_t len, + nss_lag_msg_callback_t cb, void *app_data); + +/** + * nss_lag_tx_slave_state + * Sends LAG slave state. + * + * @datatypes + * nss_lag_state_change_ev + * + * @param[in] lagid LAG Group ID. + * @param[in] slave_ifnum Slave interface number. + * @param[in] slave_state Slave state. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_lag_tx_slave_state(uint16_t lagid, + int32_t slave_ifnum, + enum nss_lag_state_change_ev slave_state); + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_lso_rx.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_lso_rx.h new file mode 100644 index 000000000..e8f4babae --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_lso_rx.h @@ -0,0 +1,88 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_lso_rx.h + * NSS driver LSO (Large Send Offload) Rx header file. + */ + +#ifndef __NSS_LSO_RX_H +#define __NSS_LSO_RX_H + +/** + * @addtogroup nss_lso_rx_subsystem + * @{ + */ + +/** + * nss_lso_rx_stats_types + * LSO Rx driver statistics. + */ +enum nss_lso_rx_stats_types { + NSS_LSO_RX_STATS_TX_DROPPED, /**< Number of packets dropped because transmit queue is full. */ + NSS_LSO_RX_STATS_DROPPED, /**< Number of packets dropped because of node internal errors. */ + NSS_LSO_RX_STATS_PBUF_ALLOC_FAIL, /**< Number of pbuf allocation failures. */ + NSS_LSO_RX_STATS_PBUF_REFERENCE_FAIL, /**< Number of pbuf reference failures. */ + NSS_LSO_RX_STATS_MAX, /**< Maximum message type. */ +}; + +/** + * nss_lso_rx_stats_notification + * Data for sending LSO Rx statistics. + */ +struct nss_lso_rx_stats_notification { + uint32_t core_id; /**< Core ID. */ + uint64_t cmn_node_stats[NSS_STATS_NODE_MAX]; /**< Common node statistics. */ + uint64_t node_stats[NSS_LSO_RX_STATS_MAX]; /**< LSO Rx special statistics. */ +}; + +#ifdef __KERNEL__ /* only kernel will use. */ +/** + * nss_lso_rx_stats_register_notifier + * Registers a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_lso_rx_stats_register_notifier(struct notifier_block *nb); + +/** + * nss_lso_rx_stats_unregister_notifier + * Deregisters a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_lso_rx_stats_unregister_notifier(struct notifier_block *nb); +#endif /*__KERNEL__ */ + +/** + * @} + */ + +#endif /* __NSS_LSO_RX_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_map_t.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_map_t.h new file mode 100644 index 000000000..428fc5060 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_map_t.h @@ -0,0 +1,372 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_map_t.h + * NSS MAP-T interface definitions. + */ + +#ifndef _NSS_MAP_T_H_ +#define _NSS_MAP_T_H_ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS +#include "nss_dynamic_interface.h" +#endif + +/** + * @addtogroup nss_map_t_subsystem + * @{ + */ + +/** + * Maximum number of supported MAP-T instances. + */ +#define NSS_MAX_MAP_T_DYNAMIC_INTERFACES 4 + +/** + * nss_map_t_msg_types + * Message types for MAP-T requests and responses. + */ +enum nss_map_t_msg_types { + NSS_MAP_T_MSG_INSTANCE_RULE_CONFIGURE, + NSS_MAP_T_MSG_INSTANCE_RULE_DECONFIGURE, + NSS_MAP_T_MSG_SYNC_STATS, + NSS_MAP_T_MSG_MAX +}; + +/** + * nss_map_t_stats_instance + * MAP-T debug error types. + */ +enum nss_map_t_stats_instance { + NSS_MAP_T_STATS_V4_TO_V6_PBUF_EXCEPTION, + NSS_MAP_T_STATS_V4_TO_V6_PBUF_NO_MATCHING_RULE, + NSS_MAP_T_STATS_V4_TO_V6_PBUF_NOT_TCP_OR_UDP, + NSS_MAP_T_STATS_V4_TO_V6_RULE_ERR_LOCAL_PSID, + NSS_MAP_T_STATS_V4_TO_V6_RULE_ERR_LOCAL_IPV6, + NSS_MAP_T_STATS_V4_TO_V6_RULE_ERR_REMOTE_PSID, + NSS_MAP_T_STATS_V4_TO_V6_RULE_ERR_REMOTE_EA_BITS, + NSS_MAP_T_STATS_V4_TO_V6_RULE_ERR_REMOTE_IPV6, + NSS_MAP_T_STATS_V6_TO_V4_PBUF_EXCEPTION, + NSS_MAP_T_STATS_V6_TO_V4_PBUF_NO_MATCHING_RULE, + NSS_MAP_T_STATS_V6_TO_V4_PBUF_NOT_TCP_OR_UDP, + NSS_MAP_T_STATS_V6_TO_V4_RULE_ERR_LOCAL_IPV4, + NSS_MAP_T_STATS_V6_TO_V4_RULE_ERR_REMOTE_IPV4, + NSS_MAP_T_STATS_MAX +}; + +/** + * nss_map_t_stats_notification + * MAP-T statistics structure. + */ +struct nss_map_t_stats_notification { + uint32_t core_id; /**< Core ID. */ + uint32_t if_num; /**< Interface number. */ + enum nss_dynamic_interface_type if_type; /**< Dynamic interface type. */ + uint64_t stats[NSS_MAP_T_STATS_MAX]; /**< MAP-T statistics. */ +}; + +#ifdef __KERNEL__ /* only kernel will use. */ +/** + * nss_map_t_instance_rule_config_msg + * Message information for configuring a MAP-T instance. + */ +struct nss_map_t_instance_rule_config_msg { + uint32_t rule_num; /**< Rule sequence number */ + uint32_t total_rules; /**< Total number of NAT64 rules configured. */ + uint32_t local_ipv6_prefix_len; /**< Local IPv6 prefix length. */ + uint32_t local_ipv4_prefix; /**< Local IPv4 prefix. */ + uint32_t local_ipv4_prefix_len; /**< Local IPv4 prefix length. */ + uint32_t local_ea_len; /**< Local EA bits length. */ + uint32_t local_psid_offset; /**< Local PSID offset. */ + + uint32_t reserve_a; /**< Reserved for backward compatibility. */ + + uint32_t remote_ipv6_prefix_len; /**< Remote IPv6 prefix length. */ + uint32_t remote_ipv4_prefix; /**< Remote IPv4 prefix. */ + uint32_t remote_ipv4_prefix_len; /**< Remote IPv4 prefix length. */ + uint32_t remote_ea_len; /**< Remote EA bits length. */ + uint32_t remote_psid_offset; /**< Remote PSID offset. */ + + uint32_t local_map_style; /**< Local MAP style. */ + uint32_t remote_map_style; /**< Remote MAP style. */ + + uint32_t sibling_if; /**< Sibling interface number. */ + + uint8_t local_ipv6_prefix[16]; /**< Local IPv6 prefix. */ + uint8_t reserve_b[16]; /**< Reserved for backward compatibility. */ + uint8_t remote_ipv6_prefix[16]; /**< Remote IPv6 prefix. */ + + uint8_t valid_rule; /**< MAP-T rule validity. */ + uint8_t flags; /**< MAP-T flags. */ + uint8_t reserved[2]; /**< Reserved for byte alignment. */ +}; + +/** + * nss_map_t_instance_rule_deconfig_msg + * Message information for deleting a MAP-T instance. + */ +struct nss_map_t_instance_rule_deconfig_msg { + int32_t if_number; /**< Interface number. */ +}; + +/** + * nss_map_t_sync_stats_msg + * Message information for MAP-T synchronization statistics. + */ +struct nss_map_t_sync_stats_msg { + struct nss_cmn_node_stats node_stats; /**< Common node statistics. */ + uint32_t tx_dropped; /**< Dropped Tx packets. */ + + /** + * Debug statistics for MAP-T. + */ + union { + + /** + * IPv4 to IPv6 path debug statistics. + */ + struct { + uint32_t exception_pkts; + /**< Number of packets exceptioned to host in IPv4 to IPv6 fast path. */ + uint32_t no_matching_rule; + /**< No matching of any rule. */ + uint32_t not_tcp_or_udp; + /**< Number of packets which are neither UDP nor TCP. */ + uint32_t rule_err_local_psid; + /**< Calculate the local PSID error. */ + uint32_t rule_err_local_ipv6; + /**< Calculate local IPv6 error. */ + uint32_t rule_err_remote_psid; + /**< Calculate remote PSID error. */ + uint32_t rule_err_remote_ea_bits; + /**< Calculate remote EA bits error. */ + uint32_t rule_err_remote_ipv6; + /**< Calculate remote IPv6 error. */ + } v4_to_v6; /**< IPv4 to IPv6 debug statistics object. */ + + /** + * IPv6 to IPv4 path debug statistics. + */ + struct { + uint32_t exception_pkts; + /**< Number of packets exception to host in IPv6 to IPv4 fast path. */ + uint32_t no_matching_rule; + /**< No matching of any rule. */ + uint32_t not_tcp_or_udp; + /**< Number of packets which are neither UDP nor TCP. */ + uint32_t rule_err_local_ipv4; + /**< Calculate local IPv4 error. */ + uint32_t rule_err_remote_ipv4; + /**< Calculate remote IPv4 error. */ + } v6_to_v4; /**< IPv6 to IPv4 debug statistics object */ + + } debug_stats; /**< Payload of debug statistics. */ +}; + +/** + * nss_map_t_msg + * Data for sending and receiving MAP-T messages. + */ +struct nss_map_t_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a MAP-T message. + */ + union { + struct nss_map_t_instance_rule_config_msg create_msg; + /**< Create message. */ + struct nss_map_t_instance_rule_deconfig_msg destroy_msg; + /**< Destroy message. */ + struct nss_map_t_sync_stats_msg stats; + /**< Statistics message to host. */ + } msg; /**< Message payload. */ +}; + +/** + * Callback function for receiving MAP-T messages. + * + * @datatypes + * nss_map_t_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_map_t_msg_callback_t)(void *app_data, struct nss_map_t_msg *msg); + +/** + * nss_map_t_tx + * Sends a MAP-T message to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_map_t_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_map_t_tx(struct nss_ctx_instance *nss_ctx, struct nss_map_t_msg *msg); + +/** + * nss_map_t_tx_sync + * Sends a MAP-T message synchronously to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_map_t_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_map_t_tx_sync(struct nss_ctx_instance *nss_ctx, struct nss_map_t_msg *msg); + +/** + * nss_map_t_get_context + * Gets the MAP-T context used in nss_map_t_tx. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_map_t_get_context(void); + +/** + * Callback function for receiving MAP-T tunnel data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_map_t_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * nss_map_t_register_if + * Registers a MAP-T interface with the NSS for sending and receiving tunnel messages. + * + * @datatypes + * nss_map_t_callback_t \n + * nss_map_t_msg_callback_t \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] type NSS interface type. + * @param[in] map_t_callback Callback for the MAP-T data. + * @param[in] msg_callback Callback for the MAP-T message. + * @param[in] netdev Pointer to the associated network device. + * @param[in] features Data socket buffer types supported by this interface. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_map_t_register_if(uint32_t if_num, uint32_t type, nss_map_t_callback_t map_t_callback, + nss_map_t_msg_callback_t msg_callback, struct net_device *netdev, uint32_t features); + +/** + * nss_map_t_unregister_if + * Deregisters a MAP-T tunnel interface from the NSS. + * + * @param[in] if_num NSS interface number + * + * @return + * None. + */ +extern void nss_map_t_unregister_if(uint32_t if_num); + +/** + * nss_map_t_msg_init + * Initializes a MAP-T message. + * + * @datatypes + * nss_map_t_msg_init + * + * @param[in,out] ncm Pointer to the message. + * @param[in] if_num Interface number + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Pointer to the message callback. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_map_t_msg_init(struct nss_map_t_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data); + +/** + * nss_map_t_register_handler + * Registers the MAP-T debug statistics handler with the NSS. + * + * @return + * None. + */ +extern void nss_map_t_register_handler(void); + +/** + * nss_map_t_instance_debug_stats_get + * Gets debug statistics for a MAP-T instance. + * + * @param[out] stats_mem Pointer to the memory address, which must be large enough to + hold all the statistics. + * + * @return + * None. + */ +extern void nss_map_t_instance_debug_stats_get(void *stats_mem); + +/** + * nss_map_t_stats_register_notifier + * Registers a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_map_t_stats_register_notifier(struct notifier_block *nb); + +/** + * nss_map_t_stats_unregister_notifier + * Deregisters a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_map_t_stats_unregister_notifier(struct notifier_block *nb); +#endif /*__KERNEL__ */ + +/** + * @} + */ + +#endif /* _NSS_MAP_T_H_ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_match.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_match.h new file mode 100644 index 000000000..ae1e30855 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_match.h @@ -0,0 +1,296 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_match.h + * NSS match interface definitions. + */ + +#ifndef _NSS_MATCH_H_ +#define _NSS_MATCH_H_ + + +/** + * @addtogroup nss_match_subsystem + * @{ + */ + +/** + * Maximum number of supported match instances. + */ +#define NSS_MATCH_INSTANCE_MAX 4 + +/** + * Maximum number of rules supported per instance. + */ +#define NSS_MATCH_INSTANCE_RULE_MAX 32 + +/** + * Maximum number of masksets. + */ +#define NSS_MATCH_MASK_MAX 2 + +/** + * Maximum number of words per maskset. + */ +#define NSS_MATCH_MASK_WORDS_MAX 4 + +/** + * nss_match_error_type + * Match message error types. + */ +typedef enum nss_match_error_type { + NSS_MATCH_SUCCESS, /**< No error. */ + NSS_MATCH_ERROR_UNKNOWN_MSG, /**< Message unknown. */ + NSS_MATCH_ERROR_DSCP_OUTOFBOUND, /**< DSCP out of bound. */ + NSS_MATCH_ERROR_OUTER_8021P_OUTOFBOUND, /**< Outer 802.1p out of bound. */ + NSS_MATCH_ERROR_INNER_8021P_OUTOFBOUND, /**< Inner 802.1p out of bound. */ + NSS_MATCH_ERROR_RULE_ID_OUTOFBOUND, /**< Rule ID is out of bound. */ + NSS_MATCH_ERROR_ACTION_TYPE_INVALID, /**< Invalid action type. */ + NSS_MATCH_ERROR_RULE_EXISTS, /**< Rule ID already in use. */ + NSS_MATCH_ERROR_RULE_DOES_NOT_EXIST, /**< Rule does not exist. */ + NSS_MATCH_ERROR_INSTANCE_CONFIGURED, /**< Error in instance configuration. */ + NSS_MATCH_ERROR_PROFILE_CONFIG_INVALID, /**< Invalid profile configuration message. */ + NSS_MATCH_ERROR_DB_INIT_FAILED, /**< Database initialization failed. */ + NSS_MATCH_ERROR_TABLE_ID_OUTOFBOUND, /**< Table ID is out of bound. */ + NSS_MATCH_ERROR_RULE_ADD, /**< Error in adding rule. */ + NSS_MATCH_ERROR_RULE_DELETE, /**< Error in deleting rule. */ + NSS_MATCH_ERROR_TABLE_ADD, /**< Error in adding table. */ + NSS_MATCH_ERROR_TABLE_DELETE, /**< Error in deleting table. */ + NSS_MATCH_ERROR_MASK_ID_OUTOFBOUND, /**< Mask ID is out of bound. */ + NSS_MATCH_ERROR_IFNUM_INVALID, /**< Next node interface number is invalid. */ + NSS_MATCH_ERROR_MAX, /**< Maximum error. */ +} nss_match_status_t; + +/** + * nss_match_action_type + * Bit positions for possible actions that can be taken. + */ +enum nss_match_action_type { + NSS_MATCH_ACTION_NONE, /**< No action. */ + NSS_MATCH_ACTION_SETPRIO = 1, /**< Set given priority to the packet. */ + NSS_MATCH_ACTION_FORWARD = 2, /**< Forward the packet to a given node. */ + NSS_MATCH_ACTION_DROP = 4, /**< Drop the packet. */ + NSS_MATCH_ACTION_MAX, /**< Maximum action type. */ +}; + +/** + * nss_match_profile_type + * Different profile types. + */ +enum nss_match_profile_type { + NSS_MATCH_PROFILE_TYPE_NONE, + NSS_MATCH_PROFILE_TYPE_VOW, /**< Matches on interface number/DSCP/802.1P. */ + NSS_MATCH_PROFILE_TYPE_L2, /**< Matches on interface number/destination MAC/source MAC/Ether type. */ + NSS_MATCH_PROFILE_TYPE_MAX, /**< Maximum profile type. */ +}; + +/** + * nss_match_msg_types. + * Message types for match requests and responses. + */ +enum nss_match_msg_types { + NSS_MATCH_INSTANCE_NONE, /**< Invalid message. */ + NSS_MATCH_TABLE_CONFIGURE_MSG, /**< Instance configure. */ + NSS_MATCH_ADD_VOW_RULE_MSG, /**< Insert VoW rule. */ + NSS_MATCH_ADD_L2_RULE_MSG, /**< Insert l2 rule. */ + NSS_MATCH_DELETE_VOW_RULE_MSG, /**< Delete VoW rule. */ + NSS_MATCH_DELETE_L2_RULE_MSG, /**< Delete l2 rule. */ + NSS_MATCH_STATS_SYNC, /**< Instance statistics. */ + NSS_MATCH_MSG_MAX, /**< Maximum instance messages. */ +}; + +/** + * nss_match_stats_sync + * Synchronization message structure. + */ +struct nss_match_stats_sync { + struct nss_cmn_node_stats p_stats; /**< Pnode statistics. */ + uint32_t hit_count[NSS_MATCH_INSTANCE_RULE_MAX]; /**< Exception events. */ +}; + +/** + * nss_match_profile_configure_msg + * Message for configuring the profile for a match instance. + */ +struct nss_match_profile_configure_msg { + uint32_t profile_type; /**< Profile type. */ + uint32_t valid_mask_flag; /**< Valid maskset flag. */ + uint32_t maskset[NSS_MATCH_MASK_MAX][NSS_MATCH_MASK_WORDS_MAX]; /**< Maskset. */ +}; + +/* + * nss_match_rule_action + * Message information for action. + */ +struct nss_match_rule_action { + uint32_t action_flag; /**< Action bit map. */ + uint32_t forward_ifnum; /**< Next node interface number. */ + uint16_t setprio; /**< Priority number to be set in packet. */ + uint16_t reserved; /**< Reserved 2 bytes. */ +}; + +/** + * nss_match_rule_vow_msg + * Rule message for VoW profile. + */ +struct nss_match_rule_vow_msg { + uint16_t rule_id; /**< Rule ID for the rule. */ + uint16_t mask_id; /**< Mask number used for the rule. */ + struct nss_match_rule_action action; /**< Action related with the rule. */ + uint32_t if_num; /**< Interface number. */ + uint8_t dscp; /**< DSCP. */ + uint8_t outer_8021p; /**< Outer 802.1p. */ + uint8_t inner_8021p; /**< Inner 802.1p. */ + uint8_t reserved; /**< Reserved byte. */ +}; + +/** + * nss_match_rule_l2_msg + * Rule message for L2 profile. + */ +struct nss_match_rule_l2_msg { + uint16_t rule_id; /**< Rule ID for the rule. */ + uint16_t mask_id; /**< Mask number used for the rule. */ + struct nss_match_rule_action action; /**< Action related with the rule. */ + uint32_t if_num; /**< Interface number. */ + uint16_t dmac[3]; /**< Destination MAC address. */ + uint16_t smac[3]; /**< Source MAC address. */ + uint16_t ethertype; /**< Ethernet type. */ +}; + +/** + * nss_match_msg + * Data for sending and receiving match messages. + */ +struct nss_match_msg { + struct nss_cmn_msg cm; /**< Message header. */ + + /** + * Payload of a match message. + */ + union { + struct nss_match_profile_configure_msg configure_msg; /**< Configure message. */ + struct nss_match_rule_vow_msg vow_rule; /**< Insertion or deletion message for VoW profile. */ + struct nss_match_rule_l2_msg l2_rule; /**< Insertion or deletion message for l2 profile. */ + struct nss_match_stats_sync stats; /**< Instance synchronization statistics. */ + } msg; /**< Message payload. */ +}; + +/** + * nss_match_msg_tx_sync + * Sends proxy match messages to the NSS. + * + * Do not call this function from a softirq or interrupt because it + * might sleep if the NSS firmware is busy serving another host thread. + * + * @datatypes + * nss_ctx_instance \n + * nss_match_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_match_msg_tx_sync(struct nss_ctx_instance *nss_ctx, struct nss_match_msg *msg); + +/** + * Callback function for receiving match messages. + * + * @datatypes + * nss_match_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_match_msg_sync_callback_t)(void *app_data, struct nss_match_msg *msg); + +/** + * nss_match_get_context + * Returns NSS context of match. + * + * @datatypes + * nss_ctx_instance + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_match_get_context(void); + +/** + * nss_match_register_instance + * Registers match dynamic node to NSS. + * + * @datatypes + * nss_match_msg_sync_callback_t + * + * @param[in] if_num Interface number of match instance. + * @param[in] notify_cb Notify callback function for the message. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_match_register_instance(int if_num, nss_match_msg_sync_callback_t notify_cb); + +/** + * nss_match_unregister_instance + * Unregisters match dynamic node to NSS. + * + * @param[in] if_num Interface number of match instance. + * + * @return + * True if successful, else false. + */ +extern bool nss_match_unregister_instance(int if_num); + +/** + * nss_match_msg_init + * Initializes a match message. + * + * @datatypes + * nss_match_msg \n + * nss_match_msg_sync_callback_t + * + * @param[in,out] nmm Pointer to the message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_match_msg_init(struct nss_match_msg *nmm, uint16_t if_num, uint32_t type, uint32_t len, + nss_match_msg_sync_callback_t cb, void *app_data); + +/** + * nss_match_init + * Initializes match. + * + * @return + * None. + */ +extern void nss_match_init(void); +/** + * @} + */ + +#endif /* _NSS_MATCH_H_ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_mirror.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_mirror.h new file mode 100644 index 000000000..68d32b94a --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_mirror.h @@ -0,0 +1,265 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_mirror.h + * NSS mirror interface definitions. + */ + +#ifndef _NSS_MIRROR_H_ +#define _NSS_MIRROR_H_ + +/** + * @addtogroup nss_mirror_subsystem + * @{ + */ + +/** + * Maximum number of supported mirror interfaces. + */ +#define NSS_MAX_MIRROR_DYNAMIC_INTERFACES 8 + +/** + * nss_mirror_msg_types + * Message types for mirror interface requests and responses. + */ +enum nss_mirror_msg_types { + NSS_MIRROR_MSG_CONFIGURE, /**< Configure message type. */ + NSS_MIRROR_MSG_ENABLE, /**< Enable message type. */ + NSS_MIRROR_MSG_DISABLE, /**< Disable message type. */ + NSS_MIRROR_MSG_SET_NEXTHOP, /**< Set nexthop message type. */ + NSS_MIRROR_MSG_RESET_NEXTHOP, /**< Reset nexthop message type. */ + NSS_MIRROR_MSG_SYNC_STATS, /**< Statistics synchronization message type. */ + NSS_MIRROR_MSG_MAX /**< Maximum message type. */ +}; + +/** + * nss_mirror_pkt_clone_point + * Clone point to use for mirroring the packet. + */ +enum nss_mirror_pkt_clone_point { + NSS_MIRROR_PKT_CLONE_POINT_DEFAULT = 1, /**< Clone the packet from the start. */ + NSS_MIRROR_PKT_CLONE_POINT_BEFORE_PACKET_START, /**< Clone n-bytes before packet start. */ + NSS_MIRROR_PKT_CLONE_POINT_AFTER_PACKET_START, /**< Clone n-bytes after packet start. */ + NSS_MIRROR_PKT_CLONE_POINT_MAX +}; + +/** + * nss_mirror_error_type + * Error types for mirror responses to messages from the host. + */ +enum nss_mirror_error_type { + NSS_MIRROR_ERROR_TYPE_NONE, /**< No error. */ + NSS_MIRROR_ERROR_TYPE_NO_MEMORY, /**< No memory to copy. */ + NSS_MIRROR_ERROR_TYPE_TX_FAILURE, /**< Transmit failure. */ + NSS_MIRROR_ERROR_TYPE_BAD_PARAM, /**< Bad parameter. */ + NSS_MIRROR_ERROR_TYPE_BAD_CLONE_POINT, /**< Bad packet clone point. */ + NSS_MIRROR_ERROR_TYPE_INSTANCE_CONFIGURED, /**< Instance already active. */ + NSS_MIRROR_ERROR_TYPE_INSTANCE_DISABLED, /**< Instance already disabled. */ + NSS_MIRROR_ERROR_TYPE_BAD_NEXTHOP, /**< Incorrect nexthop interface. */ + NSS_MIRROR_ERROR_TYPE_NEXTHOP_CONFIGURED, /**< Nexthop already interface. */ + NSS_MIRROR_ERROR_TYPE_NEXTHOP_RESET, /**< Nexthop already reset. */ + NSS_MIRROR_ERROR_TYPE_UNKNOWN_MSG, /**< Unknown message. */ + NSS_MIRROR_ERROR_TYPE_MAX, /**< Maximum message type. */ +}; + +/** + * nss_mirror_configure_msg + * Mirror interface configuration information. + */ +struct nss_mirror_configure_msg { + uint32_t pkt_clone_point; /**< Point in the packet to copy from. */ + uint16_t pkt_clone_size; /**< Number of bytes to copy. */ + uint16_t pkt_clone_offset; /**< Copy offset. */ +}; + +/** + * nss_mirror_set_nexthop_msg + * Mirror interface set nexthop information. + */ +struct nss_mirror_set_nexthop_msg { + uint32_t if_num; /**< Nexthop interface number. */ +}; + +/** + * nss_mirror_node_stats + * Mirror interface debug statistics structure. + */ +struct nss_mirror_node_stats { + uint32_t mirror_pkts; /**< Number of packets exceptioned to host. */ + uint32_t mirror_bytes; /**< Number of bytes exceptioned to host. */ + uint32_t tx_send_fail; /**< Transmit send failures. */ + uint32_t dest_lookup_fail; /**< Destination lookup failures. */ + uint32_t mem_alloc_fail; /**< Memory allocation failures. */ + uint32_t copy_fail; /**< Copy failures. */ + uint32_t bad_param; /**< Bad parameter. */ +}; + +/** + * nss_mirror_stats_sync_msg + * Message information for mirror interface synchronization statistics. + */ +struct nss_mirror_stats_sync_msg { + struct nss_cmn_node_stats node_stats; /**< Common node statistics. */ + struct nss_mirror_node_stats mirror_stats; /**< Debug statistics for mirror. */ +}; + +/** + * nss_mirror_msg + * Data for sending and receiving mirror interface messages. + */ +struct nss_mirror_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a mirror interface message. + */ + union { + struct nss_mirror_configure_msg config; + /**< Mirror interface configure message. */ + struct nss_mirror_set_nexthop_msg nexthop; + /**< Mirror interface set nexthop message. */ + struct nss_mirror_stats_sync_msg stats; + /**< Statistics message to host. */ + } msg; /**< Message payload. */ +}; + +/** + * Callback function for receiving mirror instance data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_mirror_data_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * Callback function for receiving mirror interface messages. + * + * @datatypes + * nss_cmn_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_mirror_msg_callback_t)(void *app_data, struct nss_cmn_msg *msg); + +/** + * nss_mirror_get_context + * Gets the mirror interface context. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_mirror_get_context(void); + +/** + * nss_mirror_tx_msg + * Sends mirror interface messages to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_mirror_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_mirror_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_mirror_msg *msg); + +/** + * nss_mirror_tx_msg_sync + * Sends a mirror interface message to the NSS synchronously. + * + * @datatypes + * nss_ctx_instance \n + * nss_mirror_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_mirror_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_mirror_msg *msg); + +/** + * nss_mirror_register_if + * Registers a mirror interface with the NSS for sending and receiving messages. + * + * @datatypes + * nss_mirror_data_callback_t \n + * nss_mirror_msg_callback_t \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] data_callback Callback for the mirror interface data. + * @param[in] event_callback Callback for the mirror interface message. + * @param[in] netdev Pointer to the associated network device. + * @param[in] features Data socket buffer types supported by this interface. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_mirror_register_if(uint32_t if_num, + nss_mirror_data_callback_t data_callback, + nss_mirror_msg_callback_t event_callback, + struct net_device *netdev, uint32_t features); + +/** + * nss_mirror_unregister_if + * Deregisters a mirror interface from the NSS. + * + * @param[in] if_num NSS interface number. + * + * @return + * None. + */ +extern void nss_mirror_unregister_if(uint32_t if_num); + +/** + * nss_mirror_verify_if_num + * Verify whether the interface is an mirror interface or not. + * + * @param[in] if_num NSS interface number. + * + * @return + * True if the interface is an mirror interface. + */ +extern bool nss_mirror_verify_if_num(uint32_t if_num); + +/** + * nss_mirror_register_handler + * Registers the mirror interface debug statistics handler with the NSS. + * + * @return + * None. + */ +extern void nss_mirror_register_handler(void); + +/** + * @} + */ +#endif diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_n2h.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_n2h.h new file mode 100644 index 000000000..1613f41c0 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_n2h.h @@ -0,0 +1,572 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_n2h.h + * NSS to HLOS interface definitions. + */ + +#ifndef __NSS_N2H_H +#define __NSS_N2H_H + +/** + * @addtogroup nss_n2h_subsystem + * @{ + */ + +#define MAX_PAGES_PER_MSG 32 /**< Maximum number of pages per message. */ +#define NSS_N2H_RPS_PRI_DEFAULT -1 /**< Default RPS priority mapping. */ + +/** + * nss_n2h_payload_info + * Payload configuration based on the watermark. + */ +struct nss_n2h_payload_info { + uint32_t pool_size; /**< Empty buffer pool size. */ + + /** + * Low watermark. + * Set this field to 0 for the system to automatically determine the watermark. + */ + uint32_t low_water; + + /** + * High watermark. + * Set this field to 0 for the system to automatically determine the watermark. + */ + uint32_t high_water; +}; + +#ifdef __KERNEL__ /* only kernel will use. */ + +/** + * nss_n2h_cfg_pvt + * N2H private data configuration. + */ +struct nss_n2h_cfg_pvt { + struct semaphore sem; /**< Semaphore for SMP synchronization. */ + struct completion complete; /**< Waits for the NSS to process the message. */ + struct nss_n2h_payload_info empty_buf_pool_info; /**< Empty buffer pool information. */ + struct nss_n2h_payload_info empty_paged_buf_pool_info; /**< Paged buffer pool information. */ + int wifi_pool; /**< Size of the empty Wi-Fi buffer pool. */ + int response; /**< Response from the firmware. */ +}; + +#endif /*__KERNEL__ */ + +/** + * nss_n2h_stats_types + * N2H node statistics. + */ +enum nss_n2h_stats_types { + NSS_N2H_STATS_QUEUE_DROPPED = NSS_STATS_NODE_MAX, + /**< Number of packets dropped because the exception queue is too full. */ + NSS_N2H_STATS_TOTAL_TICKS, /**< Total clock ticks spend inside the N2H. */ + NSS_N2H_STATS_WORST_CASE_TICKS, /**< Worst case iteration of the exception path in ticks. */ + NSS_N2H_STATS_ITERATIONS, /**< Number of iterations around the N2H. */ + NSS_N2H_STATS_PBUF_OCM_TOTAL_COUNT, /**< Number of pbuf OCM total count. */ + NSS_N2H_STATS_PBUF_OCM_FREE_COUNT, /**< Number of pbuf OCM free count. */ + NSS_N2H_STATS_PBUF_OCM_ALLOC_FAILS_WITH_PAYLOAD, + /**< Number of pbuf OCM allocations that have failed with payload. */ + NSS_N2H_STATS_PBUF_OCM_ALLOC_FAILS_NO_PAYLOAD, + /**< Number of pbuf OCM allocations that have failed without payload. */ + NSS_N2H_STATS_PBUF_DEFAULT_TOTAL_COUNT, /**< Number of pbuf default total count. */ + NSS_N2H_STATS_PBUF_DEFAULT_FREE_COUNT, /**< Number of pbuf default free count. */ + NSS_N2H_STATS_PBUF_DEFAULT_ALLOC_FAILS_WITH_PAYLOAD, + /**< Number of pbuf default allocations that have failed with payload. */ + NSS_N2H_STATS_PBUF_DEFAULT_ALLOC_FAILS_NO_PAYLOAD, + /**< Number of pbuf default allocations that have failed without payload. */ + + NSS_N2H_STATS_PAYLOAD_ALLOC_FAILS, /**< Number of pbuf allocations that have failed because there were no free payloads. */ + NSS_N2H_STATS_PAYLOAD_FREE_COUNT, /**< Number of free payloads that exist. */ + + NSS_N2H_STATS_H2N_CONTROL_PACKETS, /**< Control packets received from HLOS. */ + NSS_N2H_STATS_H2N_CONTROL_BYTES, /**< Control bytes received from HLOS. */ + NSS_N2H_STATS_N2H_CONTROL_PACKETS, /**< Control packets sent to HLOS. */ + NSS_N2H_STATS_N2H_CONTROL_BYTES, /**< Control bytes sent to HLOS. */ + + NSS_N2H_STATS_H2N_DATA_PACKETS, /**< Data packets received from HLOS. */ + NSS_N2H_STATS_H2N_DATA_BYTES, /**< Data bytes received from HLOS. */ + NSS_N2H_STATS_N2H_DATA_PACKETS, /**< Data packets sent to HLOS. */ + NSS_N2H_STATS_N2H_DATA_BYTES, /**< Data bytes sent to HLOS. */ + NSS_N2H_STATS_N2H_TOT_PAYLOADS, /**< Number of payloads in NSS. */ + NSS_N2H_STATS_N2H_INTERFACE_INVALID, /**< Number of bad interface access. */ + NSS_N2H_STATS_ENQUEUE_RETRIES, /**< Number of enqueue retries by N2H. */ + + NSS_N2H_STATS_MAX, /**< Maximum message type. */ +}; + +/** + * nss_n2h_metadata_types + * Message types for N2H requests and responses. + */ +enum nss_n2h_metadata_types { + NSS_RX_METADATA_TYPE_N2H_STATS_SYNC = 0, + NSS_TX_METADATA_TYPE_N2H_RPS_CFG, + NSS_TX_METADATA_TYPE_N2H_EMPTY_POOL_BUF_CFG, + NSS_TX_METADATA_TYPE_N2H_FLUSH_PAYLOADS, + NSS_TX_METADATA_TYPE_N2H_MITIGATION_CFG, + NSS_METADATA_TYPE_N2H_ADD_BUF_POOL, + NSS_TX_METADATA_TYPE_SET_WATER_MARK, + NSS_TX_METADATA_TYPE_GET_WATER_MARK, + NSS_TX_METADATA_TYPE_N2H_WIFI_POOL_BUF_CFG, + NSS_TX_DDR_INFO_VIA_N2H_CFG, + NSS_TX_METADATA_TYPE_N2H_SET_PNODE_QUEUE_CFG, + NSS_TX_METADATA_TYPE_N2H_EMPTY_PAGED_POOL_BUF_CFG, + NSS_TX_METADATA_TYPE_SET_PAGED_WATER_MARK, + NSS_TX_METADATA_TYPE_GET_PAGED_WATER_MARK, + NSS_TX_METADATA_TYPE_N2H_RPS_PRI_MAP_CFG, + NSS_TX_METADATA_TYPE_N2H_QUEUE_LIMIT_CFG, + NSS_TX_METADATA_TYPE_N2H_PAGED_BUFFER_POOL_INIT, + NSS_TX_METADATA_TYPE_N2H_HOST_BACK_PRESSURE_CFG, + NSS_METADATA_TYPE_N2H_MAX, +}; + +/* + * nss_n2h_error_types + * N2H error types. + */ +enum nss_n2h_error_types { + N2H_EUNKNOWN = 1, + N2H_ALREADY_CFG, + N2H_LOW_WATER_MIN_INVALID, + N2H_HIGH_WATER_LESS_THAN_LOW, + N2H_HIGH_WATER_LIMIT_INVALID, + N2H_LOW_WATER_LIMIT_INVALID, + N2H_WATER_MARK_INVALID, + N2H_EMPTY_BUFFER_TOO_HIGH, + N2H_EMPTY_BUFFER_TOO_LOW, + N2H_MMU_ENTRY_IS_INVALID, + N2H_PN_QUEUE_SET_FAILED, + N2H_PAGES_PER_MSG_EXCEEDED, + N2H_RPS_PRI_MAP_TOO_HIGH, +}; + +/** + * nss_n2h_stats_notification + * N2H statistics structure. + */ +struct nss_n2h_stats_notification { + uint32_t core_id; /**< Core ID. */ + uint64_t n2h_stats[NSS_N2H_STATS_MAX]; /**< N2H statistics. */ + uint64_t drv_stats[NSS_STATS_DRV_MAX]; /**< Driver statistics. */ +}; + +/** + * nss_n2h_rps + * N2H RPS configuration. + */ +struct nss_n2h_rps { + uint32_t enable; /**< Enable RPS. */ +}; + +/** + * nss_n2h_rps_pri_map + * N2H priority configuration. + * + * This is used to direct packets with a given priority to a specific host CPU. + * A value of -1 in pri_map[pri] is treated as invalid and will not override + * RPS for that priority. + */ +struct nss_n2h_rps_pri_map { + int32_t pri_map[NSS_MAX_NUM_PRI]; /**< Priority to RPS map. */ +}; + +/** + * nss_n2h_mitigation + * N2H mitigation configuration. + */ +struct nss_n2h_mitigation { + uint32_t enable; /**< Enable NSS mitigation. */ +}; + +/** + * nss_n2h_buf_pool + * N2H buffer pool configuration. + */ +struct nss_n2h_buf_pool { + uint32_t nss_buf_page_size; /**< Size of the buffer page. */ + uint32_t nss_buf_num_pages; /**< Number of buffer pages. */ + + uint32_t nss_buf_pool_addr[MAX_PAGES_PER_MSG]; + /**< Buffer addresses. */ + nss_ptr_t nss_buf_pool_vaddr[MAX_PAGES_PER_MSG]; + /**< Virtual addresses of the buffers. */ +#ifndef __LP64__ + uint32_t padding[MAX_PAGES_PER_MSG]; + /**< Pad to fit 64 bits, do not reuse. */ +#endif +}; + +/** + * nss_n2h_pnode_queue_config + * Queue configuration command for pnodes in NSS. + */ +struct nss_n2h_pnode_queue_config { + uint8_t mq_en; /**< Enable multiple queues. */ + uint8_t reserved[3]; /**< Reserved for alignment. */ + uint16_t qlimits[NSS_MAX_NUM_PRI]; + /**< Limits of each queue. */ +#if (NSS_MAX_NUM_PRI & 1) + uint16_t reserved2; +#endif +}; + +/** + * nss_n2h_empty_pool_buf + * Old way of setting the number of empty pool buffers (payloads). + * + * The NSS firmware sets the low watermark to n -- ring_size, and the high + * watermark to n + ring_size. + */ +struct nss_n2h_empty_pool_buf { + uint32_t pool_size; /**< Size of the empty buffer pool. */ +}; + +/** + * nss_n2h_water_mark + * New way of setting the low and high watermarks in the NSS firmware. + */ +struct nss_n2h_water_mark { + /** + * Low watermark. + * Lower threshold for the number of payloads that can be held by NSS firmware. + * Setting this value to 0 gets the system to automatically determine the watermark. + */ + uint32_t low_water; + + /** + * High watermark. + * Upper threshold for the number of paylods that be held by the NSS firmware. + * Setting this value to 0 gets the system to automatically determine the watermark. + */ + uint32_t high_water; +}; + +/** + * nss_n2h_flush_payloads + * Flush payload configuration. + */ +struct nss_n2h_flush_payloads { + uint32_t reserved; /**< Reserved for future use. */ +}; + +/** + * nss_n2h_wifi_payloads + * Payloads required for Wi-Fi offloading. + */ +struct nss_n2h_wifi_payloads { + uint32_t payloads; /**< Number of payloads for Wi-Fi use. */ +}; + +/** + * nss_n2h_pbuf_mgr_stats + * Payload buffer manager statistics. + */ +struct nss_n2h_pbuf_mgr_stats { + uint32_t pbuf_total_count; /**< Total number of buffers, free or in use. */ + uint32_t pbuf_free_count; /**< Number of currently free buffers. */ + uint32_t pbuf_alloc_fails_with_payload; + /**< Number of buffer allocation failures. */ + uint32_t pbuf_alloc_fails_no_payload; + /**< Number of buffer allocation failures without payload. */ +}; + +/** + * nss_n2h_paged_buffer_pool_init + * Paged buffer configuration initialization. + */ +struct nss_n2h_paged_buffer_pool_init { + uint32_t reserved; /**< Reserved for future use. */ +}; + +/** + * nss_n2h_stats_sync + * N2H synchronization statistics. + */ +struct nss_n2h_stats_sync { + struct nss_cmn_node_stats node_stats; /**< Common node statistics. */ + uint32_t queue_dropped; + /**< Number of packets dropped because the N2H queue is too full. */ + uint32_t total_ticks; /**< Total clock ticks spent inside the N2H handler. */ + uint32_t worst_case_ticks; /**< Worst case iteration of the N2H handler in ticks. */ + uint32_t iterations; /**< Number of iterations around the N2H handler. */ + + struct nss_n2h_pbuf_mgr_stats pbuf_ocm_stats; + /**< Statistics for on-chip memory payload buffers. */ + struct nss_n2h_pbuf_mgr_stats pbuf_default_stats; + /**< Statistics for DDR memory payload buffers. */ + + uint32_t payload_alloc_fails; /**< Number of payload allocation failures. */ + uint32_t payload_free_count; /**< Number of free payloads. */ + + uint32_t h2n_ctrl_pkts; /**< Control packets received from the HLOS. */ + uint32_t h2n_ctrl_bytes; /**< Control bytes received from the HLOS. */ + uint32_t n2h_ctrl_pkts; /**< Control packets sent to the HLOS. */ + uint32_t n2h_ctrl_bytes; /**< Control bytes sent to the HLOS. */ + + uint32_t h2n_data_pkts; /**< Data packets received from the HLOS. */ + uint32_t h2n_data_bytes; /**< Data bytes received from the HLOS. */ + uint32_t n2h_data_pkts; /**< Data packets sent to the HLOS. */ + uint32_t n2h_data_bytes; /**< Data bytes sent to the HLOS. */ + uint32_t tot_payloads; /**< Total number of payloads in the NSS firmware. */ + + /** + * Number of data packets with invalid interface received from the host. + */ + uint32_t data_interface_invalid; + uint32_t enqueue_retries; /**< Number of times N2H retried enqueue to next node. */ +}; + +/** + * nss_mmu_ddr_info + * System DDR memory information required by the firmware MMU to set range guards. + */ +struct nss_mmu_ddr_info { + uint32_t ddr_size; /**< Total size of the DDR. */ + uint32_t start_address; /**< System start address. */ + uint32_t num_active_cores; + /**< Number of active cores. */ + uint32_t nss_ddr_size; /**< Total memory for NSS SoC. */ +}; + +/** + * nss_n2h_queue_limit_config + * Queue length limit for N2H node. + */ +struct nss_n2h_queue_limit_config { + uint32_t qlimit; /**< Queue length size. */ +}; + +/** + * nss_n2h_host_back_pressure + * Host back pressure configuration. + */ +struct nss_n2h_host_back_pressure { + uint32_t enable; /**< Enable host back pressure. */ +}; + +/** + * nss_n2h_msg + * Data for sending and receiving N2H messages. + */ +struct nss_n2h_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of an N2H message. + */ + union { + struct nss_n2h_stats_sync stats_sync; + /**< N2H statistics synchronization. */ + struct nss_n2h_rps rps_cfg; + /**< RPS configuration. */ + struct nss_n2h_rps_pri_map rps_pri_map; + /**< RPS priority map. */ + struct nss_n2h_empty_pool_buf empty_pool_buf_cfg; + /**< Empty pool buffer configuration. */ + struct nss_n2h_empty_pool_buf empty_paged_pool_buf_cfg; + /**< Empty paged pool buffer configuration. */ + struct nss_n2h_flush_payloads flush_payloads; + /**< Flush payloads present in the NSS. */ + struct nss_n2h_mitigation mitigation_cfg; + /**< Mitigation configuration. */ + struct nss_n2h_buf_pool buf_pool; + /**< Pool buffer coniguration. */ + struct nss_n2h_water_mark wm; + /**< Sets low and high watermarks. */ + struct nss_n2h_water_mark wm_paged; + /**< Sets low and high watermarks for paged pool. */ + struct nss_n2h_payload_info payload_info; + /**< Gets the payload information. */ + struct nss_n2h_payload_info paged_payload_info; + /**< Gets the paged payload information. */ + struct nss_n2h_wifi_payloads wp; + /**< Sets the number of Wi-Fi payloads. */ + struct nss_mmu_ddr_info mmu; + /**< Gets the DDR size and start address to configure the MMU. */ + struct nss_n2h_pnode_queue_config pn_q_cfg; + /**< Pnode queueing configuration. */ + struct nss_n2h_queue_limit_config ql_cfg; + /**< Queue limit configuration. */ + struct nss_n2h_paged_buffer_pool_init paged_buffer_pool_init; + /**< Paged buffer pool initialization. */ + struct nss_n2h_host_back_pressure host_bp_cfg; + /**< Host back pressure configuration. */ + } msg; /**< Message payload. */ +}; + +/** + * Callback function for receiving N2H messages. + * + * @datatypes + * nss_n2h_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the N2H message. + */ +typedef void (*nss_n2h_msg_callback_t)(void *app_data, struct nss_n2h_msg *msg); + +/** + * nss_n2h_tx_msg + * Sends messages to the N2H package. + * + * @datatypes + * nss_ctx_instance \n + * nss_n2h_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] nnm Pointer to the N2H message. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_n2h_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_n2h_msg *nnm); + +/** + * nss_n2h_single_core_register_sysctl + * Registers the N2H sysctl entry to the sysctl tree for a single-core system. + * + * @return + * None. + */ +extern void nss_n2h_single_core_register_sysctl(void); + +/** + * nss_n2h_multi_core_register_sysctl + * Registers the N2H sysctl entry to the sysctl tree for a multi-core system. + * + * @return + * None. + */ +extern void nss_n2h_multi_core_register_sysctl(void); + +/** + * nss_n2h_unregister_sysctl + * Deregisters the N2H sysctl entry from the sysctl tree. + * + * @return + * None. + * + * @dependencies + * The system control must have been previously registered. + */ +extern void nss_n2h_unregister_sysctl(void); + +/** + * nss_n2h_flush_payloads + * Sends flush payloads message to NSS + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS context. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_n2h_flush_payloads(struct nss_ctx_instance *nss_ctx); + +/** + * nss_n2h_msg_init + * Initializes messages from the host to the NSS. + * + * @datatypes + * nss_n2h_msg \n + * nss_n2h_msg_callback_t + * + * @param[in,out] nim Pointer to the NSS interface message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_n2h_msg_init(struct nss_n2h_msg *nim, uint16_t if_num, uint32_t type, uint32_t len, + nss_n2h_msg_callback_t cb, void *app_data); + +/** + * nss_n2h_update_queue_config_sync + * Synchrounous method to update pnode queue configuration to NSS. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] mq_en Enable multiple pnode queues. + * @param[in] qlimits Maximum number of packets in each queues. + * + * @return + * Status of the configuration update operation. + */ +extern nss_tx_status_t nss_n2h_update_queue_config_sync(struct nss_ctx_instance *nss_ctx, bool mq_en, uint16_t *qlimits); + +/** + * nss_n2h_update_queue_config_async + * Asynchrounous method to update pnode queue configuration to NSS. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] mq_en Enable multiple pnode queues. + * @param[in] qlimits Maximum number of packets in each queues. + * + * @return + * Status of the configuration update operation. + */ +extern nss_tx_status_t nss_n2h_update_queue_config_async(struct nss_ctx_instance *nss_ctx, bool mq_en, uint16_t *qlimits); + +#ifdef __KERNEL__ /* only kernel will use. */ + +/** + * nss_n2h_stats_register_notifier + * Registers a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_n2h_stats_register_notifier(struct notifier_block *nb); + +/** + * nss_n2h_stats_unregister_notifier + * Deregisters a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_n2h_stats_unregister_notifier(struct notifier_block *nb); + +#endif /*__KERNEL__ */ + +/** + * @} + */ + +#endif /* __NSS_N2H_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_oam.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_oam.h new file mode 100644 index 000000000..af25e3703 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_oam.h @@ -0,0 +1,145 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_oam.h + * NSS OAM - Operations, Administration and Maintenance Service + */ + +#ifndef __NSS_OAM_H +#define __NSS_OAM_H + +/** + * @addtogroup nss_oam_subsystem + * @{ + */ + +#define NSS_OAM_FW_VERSION_LEN 132 /**< Size of the OAM firmware version. */ + +/** + * nss_oam_msg_types + * OAM command types. + * + * The OAM proxy sends these command messages to the NSS OAM server via the OAM adapter. + */ +enum nss_oam_msg_types { + NSS_OAM_MSG_TYPE_NONE, + NSS_OAM_MSG_TYPE_GET_FW_VER, + NSS_OAM_MSG_TYPE_MAX, +}; + +/** + * nss_oam_error + * OAM error responses. + */ +enum nss_oam_error { + NSS_OAM_ERROR_NONE, + NSS_OAM_ERROR_INVAL_MSG_TYPE, + NSS_OAM_ERROR_INVAL_MSG_LEN, + NSS_OAM_ERROR_MAX, +}; + +/** + * nss_oam_fw_ver + * OAM firmware version. + */ +struct nss_oam_fw_ver { + uint8_t string[NSS_OAM_FW_VERSION_LEN]; /**< OAM firmware version. */ +}; + +/** + * nss_oam_msg + * Data for sending and receiving OAM messages. + */ +struct nss_oam_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of an OAM message. + */ + union { + struct nss_oam_fw_ver fw_ver; + /**< Firmware version. */ + } msg; /**< Message payload. */ +}; + +/** + * Callback function for receiving OAM messages. + * + * @datatypes + * nss_oam_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_oam_msg_callback_t)(void *app_data, struct nss_oam_msg *msg); + +/** + * nss_oam_tx_msg + * Transmits an OAM message to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_oam_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation + */ +extern nss_tx_status_t nss_oam_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_oam_msg *msg); + +/** + * nss_oam_notify_register + * Registers a notifier callback with the NSS for sending and receiving OAM messages. + * + * @datatypes + * nss_oam_msg_callback_t + * + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_oam_notify_register(nss_oam_msg_callback_t cb, void *app_data); + +/** + * nss_oam_notify_unregister + * Deregisters an OAM message notifier callback from the NSS. + * + * @return + * None. + */ +extern void nss_oam_notify_unregister(void); + +/** + * nss_register_oam_if + * Registers the OAM interface handler with the NSS. + * + * @param[in] if_number Interface number of the OAM interface. + * + * @return + * Boolean status of handler registration + */ +extern bool nss_register_oam_if(uint16_t if_number); + +/** + * @} + */ + +#endif /* __NSS_OAM_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_phy_if.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_phy_if.h new file mode 100644 index 000000000..cc52d86f0 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_phy_if.h @@ -0,0 +1,67 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_phy_if.h.h + * NSS physical interface definitions. + */ + +#ifndef __NSS_PHY_IF_H +#define __NSS_PHY_IF_H + +/** + * @addtogroup nss_driver_subsystem + * @{ + */ + +/** + * nss_phys_if_reset_nexthop + * De-configure nexthop for an interface. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] if_num Network physical interface number. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_phys_if_reset_nexthop(struct nss_ctx_instance *nss_ctx, uint32_t if_num); + +/** + * nss_phys_if_set_nexthop + * Configure nexthop for an interface. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] if_num Network physical interface number. + * @param[in] nexthop Network physical or virtual interface number. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_phys_if_set_nexthop(struct nss_ctx_instance *nss_ctx, uint32_t if_num, uint32_t nexthop); + +/** + * @} + */ + +#endif /* __NSS_PHY_IF_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_pm.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_pm.h new file mode 100644 index 000000000..8e0cce88d --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_pm.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * @file nss_pm.h + * NSS power management definitions. + */ + +#ifndef __NSS_PM_H +#define __NSS_PM_H + +/** + * @addtogroup nss_pm_subsystem + * @{ + */ + +/** + * nss_pm_client + * Power management (PM) clients. + * + * These clients can query for bus or clock performance levels. + */ +typedef enum nss_pm_client { + NSS_PM_CLIENT_GMAC, + NSS_PM_CLIENT_CRYPTO, + NSS_PM_CLIENT_NETAP, + NSS_PM_MAX_CLIENTS, +} nss_pm_client_t; + +/** + * nss_pm_perf_level + * Performance levels. + * + * This enumeration is passed as a parameter to NSS PM performance-level + * requests. + */ +typedef enum nss_pm_perf_level { + NSS_PM_PERF_LEVEL_SUSPEND = 0, + NSS_PM_PERF_LEVEL_IDLE, + NSS_PM_PERF_LEVEL_NOMINAL, + NSS_PM_PERF_LEVEL_TURBO, + NSS_PM_PERF_MAX_LEVELS, +} nss_pm_perf_level_t; + +/** + * nss_pm_interface_status_t + * Status of the PM client interface. + */ +typedef enum { + NSS_PM_API_SUCCESS = 0, + NSS_PM_API_FAILED, +} nss_pm_interface_status_t; + +/** + * nss_pm_client_register + * Registers a power management driver client. + * + * @datatypes + * nss_pm_client_t + * + * @param[in] client_id ID of the client driver. + * + * @return + * None. + */ +extern void *nss_pm_client_register(nss_pm_client_t client_id); + +/** + * nss_pm_client_unregister + * Deregisters a power management driver client. + * + * @datatypes + * nss_pm_client_t + * + * @param[in] client_id ID of the client driver. + * + * @return + * None. + */ +int nss_pm_client_unregister(nss_pm_client_t client_id); + +/** + * nss_pm_set_perf_level + * Updates the bus bandwidth level for a client. + * + * @datatypes + * nss_pm_perf_level_t + * + * @param[in,out] handle Handle of the client. + * @param[in,out] lvl Performance level. + * + * @return + * None. + */ +extern nss_pm_interface_status_t nss_pm_set_perf_level(void *handle, nss_pm_perf_level_t lvl); + +/** + * @} + */ + +#endif /* __NSS_PM_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_portid.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_portid.h new file mode 100644 index 000000000..61e8ac6d8 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_portid.h @@ -0,0 +1,284 @@ +/* + ************************************************************************** + * Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_portid.h + * NSS Port ID interface definitions. + */ + +#ifndef __NSS_PORTID_H +#define __NSS_PORTID_H + +/** + * @addtogroup nss_portid_subsystem + * @{ + */ + +/** + * Maximum number of ports on the S17c switch chip. + * + * If a new switch has more ports than S17c, this value must be updated. + */ +#define NSS_PORTID_MAX_SWITCH_PORT 7 + +/** + * nss_portid_msg_types + * Message types for port ID requests and responses. + */ +enum nss_portid_msg_types { + NSS_PORTID_CONFIGURE_MSG, + NSS_PORTID_UNCONFIGURE_MSG, + NSS_PORTID_STATS_SYNC_MSG, + NSS_PORTID_MAX_MSG_TYPE +}; + +/** + * nss_portid_configure_msg + * Message information for configuring a port ID. + */ +struct nss_portid_configure_msg { + uint32_t port_if_num; + /**< Interface number corresponding to the port ID of the device. */ + uint8_t port_id; /**< ID of the mapped switch port. */ + uint8_t gmac_id; /**< ID of the mapped GMAC interface. */ + uint8_t reserved[2]; /**< Reserved for word alignment. */ +}; + +/** + * nss_portid_unconfigure_msg + * Message information for deleting a port ID. + */ +struct nss_portid_unconfigure_msg { + uint32_t port_if_num; + /**< Interface number corresponding to the port ID of the device. */ + uint8_t port_id; /**< ID of the mapped switch port. */ + uint8_t reserved[3]; /**< Reserved for word alignment. */ +}; + +/** + * nss_portid_stats_sync_msg + * Message information for port ID synchronization statistics. + */ +struct nss_portid_stats_sync_msg { + struct nss_cmn_node_stats node_stats; /**< Common node statistics. */ + uint32_t rx_invalid_header; /**< Rx with an invalid header. */ + uint8_t port_id; /**< ID of the mapped switch port. */ + uint8_t reserved[3]; /**< Reserved for word alignment. */ +}; + +/** + * nss_portid_msg + * Data for sending and receiving port ID messages. + */ +struct nss_portid_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a port ID message. + */ + union { + struct nss_portid_configure_msg configure; + /**< Port ID configuration information. */ + struct nss_portid_unconfigure_msg unconfigure; + /**< Port ID de-configuration information. */ + struct nss_portid_stats_sync_msg stats_sync; + /**< Synchronization statistics for the port ID. */ + } msg; /**< Message payload. */ +}; + +/** + * Callback function for receiving port ID messages. + * + * @datatypes + * nss_portid_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] npm Pointer to the NSS Profiler message. + */ +typedef void (*nss_portid_msg_callback_t)(void *app_data, struct nss_portid_msg *npm); + +/** + * Callback function for receiving port ID interface data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_portid_buf_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * nss_portid_get_stats + * Gets statistics from a port interface. + * + * @datatypes + * rtnl_link_stats64 + * + * @param[in] if_num NSS interface number. + * @param[out] stats Container for the statistic counters. + * + * @return + * TRUE or FALSE. + */ +bool nss_portid_get_stats(uint32_t if_num, struct rtnl_link_stats64 *stats); + +/** + * nss_portid_msg_init + * Initializes a port ID message. + * + * @datatypes + * nss_portid_msg \n + * nss_portid_msg_callback_t + * + * @param[in,out] npm Pointer to the NSS port ID message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_portid_msg_init(struct nss_portid_msg *npm, uint16_t if_num, uint32_t type, uint32_t len, + nss_portid_msg_callback_t cb, void *app_data); + +/** + * nss_portid_if_tx_data + * Transmits a data packet to the NSS port ID interface. + * + * @datatypes + * nss_ctx_instance \n + * sk_buff + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] os_buf Pointer to the OS data buffer. + * @param[in] if_num NSS interface number. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_portid_if_tx_data(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf, uint32_t if_num); + +/** + * nss_portid_tx_msg + * Sends a port ID message to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_portid_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_portid_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_portid_msg *msg); + +/** + * nss_portid_tx_msg_sync + * Sends a port ID message to the NSS and waits for a response. + * + * @datatypes + * nss_ctx_instance \n + * nss_portid_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in,out] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_portid_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_portid_msg *msg); + +/** + * nss_portid_register_port_if + * Registers the port interface with the NSS. + * + * @datatypes + * net_device \n + * nss_portid_buf_callback_t + * + * @param[in] if_num NSS interface number. + * @param[in] port_id Physical port ID of this interface. + * @param[in] ndev Pointer to the associated network device. + * @param[in] buf_cb Callback for the data. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_portid_register_port_if(uint32_t if_num, uint32_t port_id, struct net_device *ndev, nss_portid_buf_callback_t buf_cb); + +/** + * nss_portid_unregister_port_if + * Deregisters the port interface from the NSS. + * + * @param[in] if_num NSS interface number. + * + * @return + * TRUE or FALSE. + * + * @dependencies + * The interface must have been previously registered. + */ +extern bool nss_portid_unregister_port_if(uint32_t if_num); + +/** + * nss_portid_tx_configure_port_if_msg + * Sends a port interface configuration message to the NSS. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] port_if_num Interface number of the port node. + * @param[in] port_id ID of the mapped switch port. + * @param[in] gmac_id ID of the mapped GMAC interface. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_portid_tx_configure_port_if_msg(struct nss_ctx_instance *nss_ctx, uint32_t port_if_num, uint8_t port_id, uint8_t gmac_id); + +/** + * nss_portid_tx_unconfigure_port_if_msg + * Sends a port interface de-configuration message to the NSS. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] port_if_num Interface number of the port node. + * @param[in] port_id ID of the mapped switch port. + * + * @return + * Status of the Tx operation. + * + * @dependencies + * The interface must have been previously configured. + */ +extern nss_tx_status_t nss_portid_tx_unconfigure_port_if_msg(struct nss_ctx_instance *nss_ctx, uint32_t port_if_num, uint8_t port_id); + +/** + * @} + */ + +#endif /* __NSS_PORTID_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_ppe.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_ppe.h new file mode 100644 index 000000000..6fd646e19 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_ppe.h @@ -0,0 +1,61 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_ppe.h + * NSS PPE interface definitions. + */ + +#ifndef _NSS_PPE_H_ +#define _NSS_PPE_H_ + +/** + * @addtogroup nss_ppe_subsystem + * @{ + */ + +/* + * NSS PORT defines + */ +#define NSS_PPE_NUM_PHY_PORTS_MAX 8 + /**< Maximum number of PPE physical ports. */ +#define NSS_PPE_PORT_IPSEC 7 + /**< Port number of PPE inline IPsec port. */ + +/** + * nss_ppe_sc_type + * PPE service code types. + */ +enum nss_ppe_sc_type { + NSS_PPE_SC_NONE, /**< Normal PPE processing. */ + NSS_PPE_SC_BYPASS_ALL, /**< Bypasses all stages in PPE. */ + NSS_PPE_SC_ADV_QOS_BRIDGED, /**< Advance QoS redirection for bridged flow. */ + NSS_PPE_SC_BR_QOS, /**< Bridge QoS redirection. */ + NSS_PPE_SC_BNC_0, /**< QoS bounce. */ + NSS_PPE_SC_BNC_CMPL_0, /**< QoS bounce complete. */ + NSS_PPE_SC_ADV_QOS_ROUTED, /**< Advance QoS redirection for routed flow. */ + NSS_PPE_SC_IPSEC_PPE2EIP, /**< Inline IPsec redirection from PPE-to-EIP. */ + NSS_PPE_SC_IPSEC_EIP2PPE, /**< Inline IPsec redirection from EIP-to-PPE. */ + NSS_PPE_SC_PTP, /**< Service code for PTP packets. */ + NSS_PPE_SC_VLAN_FILTER_BYPASS, /**< VLAN filter bypass for bridge flows between 2 different VSIs. */ + NSS_PPE_SC_L3_EXCEPT, /**< Indicate exception post tunnel/TAP operation. */ + NSS_PPE_SC_SPF_BYPASS, /**< Source port filtering bypass in PPE. */ + NSS_PPE_SC_MAX, /**< Maximum service code. */ +}; + +/** @} */ /* end_addtogroup nss_ppe_subsystem */ + +#endif /* _NSS_PPE_H_ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_pppoe.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_pppoe.h new file mode 100644 index 000000000..f082d3067 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_pppoe.h @@ -0,0 +1,384 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_pppoe.h + * NSS PPPoE interface definitions. + */ + +#ifndef __NSS_PPPOE_H +#define __NSS_PPPOE_H + +/** + * @addtogroup nss_pppoe_subsystem + * @{ + */ + +/** + * Maximum number of supported PPPoE sessions. + */ +#define NSS_MAX_PPPOE_DYNAMIC_INTERFACES 8 + +/** + * nss_pppoe_metadata_types + * Message types for PPPoE requests and responses. + */ +enum nss_pppoe_metadata_types { + NSS_PPPOE_MSG_SESSION_CREATE, + NSS_PPPOE_MSG_SESSION_DESTROY, + NSS_PPPOE_MSG_SYNC_STATS, + NSS_PPPOE_MSG_BR_ACCEL_CFG, + NSS_PPPOE_MSG_MAX +}; + +/** + * nss_pppoe_session_exception_events + * Session exception events from the PPPoE handler. + */ +enum nss_pppoe_session_exception_events { + NSS_PPPOE_SESSION_EXCEPTION_EVENT_WRONG_VERSION_OR_TYPE, + NSS_PPPOE_SESSION_EXCEPTION_EVENT_WRONG_CODE, + NSS_PPPOE_SESSION_EXCEPTION_EVENT_UNSUPPORTED_PPP_PROTOCOL, + NSS_PPPOE_SESSION_EXCEPTION_EVENT_MAX +}; + +/** + * pppoe_base_exception_events + * Base node exception events from the PPPoE handler. + */ +enum nss_pppoe_base_exception_events { + NSS_PPPOE_BASE_EXCEPTION_EVENT_SHORT_PPPOE_HDR_LENGTH, + NSS_PPPOE_BASE_EXCEPTION_EVENT_SHORT_PACKET_LENGTH, + NSS_PPPOE_BASE_EXCEPTION_EVENT_WRONG_VERSION_OR_TYPE, + NSS_PPPOE_BASE_EXCEPTION_EVENT_WRONG_CODE, + NSS_PPPOE_BASE_EXCEPTION_EVENT_UNSUPPORTED_PPP_PROTOCOL, + NSS_PPPOE_BASE_EXCEPTION_EVENT_DISABLED_BRIDGE_PACKET, + NSS_PPPOE_BASE_EXCEPTION_EVENT_MAX +}; + +/** + * nss_pppoe_br_accel_mode + * PPPoE bridge acceleration modes. + */ +enum nss_pppoe_br_accel_modes { + NSS_PPPOE_BR_ACCEL_MODE_DIS, + NSS_PPPOE_BR_ACCEL_MODE_EN_5T, + NSS_PPPOE_BR_ACCEL_MODE_EN_3T, + NSS_PPPOE_BR_ACCEL_MODE_MAX +}; + +/** + * nss_pppoe_base_stats + * PPPoE base node synchronization statistics. + */ +struct nss_pppoe_base_stats { + struct nss_cmn_node_stats node; /**< Common node statistics. */ + uint32_t exception[NSS_PPPOE_BASE_EXCEPTION_EVENT_MAX]; + /**< PPPoE base node exception events. */ +}; + +/** + * nss_pppoe_session_stats + * PPPoE synchronization statistics per session. + */ +struct nss_pppoe_session_stats { + struct nss_cmn_node_stats node; /**< Common node statistics. */ + uint32_t exception[NSS_PPPOE_SESSION_EXCEPTION_EVENT_MAX]; + /**< PPPoE session exception events. */ +}; + +/** + * nss_pppoe_stats_session + * PPPoE session statistics. + */ +enum nss_pppoe_stats_session { + NSS_PPPOE_STATS_SESSION_RX_PACKETS, + NSS_PPPOE_STATS_SESSION_RX_BYTES, + NSS_PPPOE_STATS_SESSION_TX_PACKETS, + NSS_PPPOE_STATS_SESSION_TX_BYTES, + NSS_PPPOE_STATS_SESSION_WRONG_VERSION_OR_TYPE, + NSS_PPPOE_STATS_SESSION_WRONG_CODE, + NSS_PPPOE_STATS_SESSION_UNSUPPORTED_PPP_PROTOCOL, + NSS_PPPOE_STATS_SESSION_MAX +}; + +/** + * nss_pppoe_stats_base + * PPPoE base node statistics. + */ +enum nss_pppoe_stats_base { + NSS_PPPOE_STATS_BASE_RX_PACKETS, + NSS_PPPOE_STATS_BASE_RX_BYTES, + NSS_PPPOE_STATS_BASE_TX_PACKETS, + NSS_PPPOE_STATS_BASE_TX_BYTES, + NSS_PPPOE_STATS_BASE_RX_QUEUE_0_DROPPED, + NSS_PPPOE_STATS_BASE_RX_QUEUE_1_DROPPED, + NSS_PPPOE_STATS_BASE_RX_QUEUE_2_DROPPED, + NSS_PPPOE_STATS_BASE_RX_QUEUE_3_DROPPED, + NSS_PPPOE_STATS_BASE_SHORT_PPPOE_HDR_LENGTH, + NSS_PPPOE_STATS_BASE_SHORT_PACKET_LENGTH, + NSS_PPPOE_STATS_BASE_WRONG_VERSION_OR_TYPE, + NSS_PPPOE_STATS_BASE_WRONG_CODE, + NSS_PPPOE_STATS_BASE_UNSUPPORTED_PPP_PROTOCOL, + NSS_PPPOE_STATS_BASE_DISABLED_BRIDGE_PACKET, + NSS_PPPOE_STATS_BASE_MAX +}; + +/** + * nss_pppoe_stats_notification + * PPPoE statistics structure. + */ +struct nss_pppoe_stats_notification { + uint32_t core_id; /**< Core ID. */ + uint32_t if_num; /**< Interface number. */ + uint64_t session_stats[NSS_PPPOE_STATS_SESSION_MAX]; /**< PPPoE statistics. */ + uint64_t base_stats[NSS_PPPOE_STATS_BASE_MAX]; /**< PPPoE base node statistics. */ +}; + +#ifdef __KERNEL__ /* only kernel will use. */ + +/** + * nss_pppoe_sync_stats_msg + * PPPoE synchronization statistics. + */ +struct nss_pppoe_sync_stats_msg { + struct nss_pppoe_session_stats session_stats; /**< Session statistics. */ + struct nss_pppoe_base_stats base_stats; /**< Base node statistics. */ +}; + +/** + * nss_pppoe_destroy_msg + * PPPoE session destroy message. + */ +struct nss_pppoe_destroy_msg { + uint16_t session_id; /**< PPPoE session identification number. */ + uint8_t server_mac[ETH_ALEN]; /**< PPPoE server MAC address. */ + uint8_t local_mac[ETH_ALEN]; /**< Local physical interface MAC address. */ +}; + +/** + * nss_pppoe_create_msg + * PPPoE session create message. + */ +struct nss_pppoe_create_msg { + int32_t base_if_num; /**< Base NSS interface number which PPPoE session created on. */ + uint32_t mtu; /**< PPPoE interface MTU value. */ + uint8_t server_mac[ETH_ALEN]; /**< PPPoE server MAC address. */ + uint8_t local_mac[ETH_ALEN]; /**< Local physical interface MAC address. */ + uint16_t session_id; /**< PPPoE session identification number. */ +}; + +/** + * nss_pppoe_br_accel_cfg_msg + * PPPoE bridge acceleration configuration message. + */ +struct nss_pppoe_br_accel_cfg_msg { + uint32_t br_accel_cfg; /**< PPPoE bridge acceleration configuration. */ +}; + +/** + * nss_pppoe_msg + * Data for sending and receiving PPPoE messages. + */ +struct nss_pppoe_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a PPPoE message. + */ + union { + struct nss_pppoe_create_msg create; + /**< Session create message. */ + struct nss_pppoe_destroy_msg destroy; + /**< Session destroy message. */ + struct nss_pppoe_sync_stats_msg sync_stats; + /**< Session statistics message. */ + struct nss_pppoe_br_accel_cfg_msg br_accel; + /**< PPPoE bridge acceleration configuration message. */ + } msg; /**< Message payload. */ +}; + +/** + * Callback function for receiving PPPoE messages. + * + * @datatypes + * nss_pppoe_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_pppoe_msg_callback_t)(void *app_data, struct nss_pppoe_msg *msg); + +/** + * nss_pppoe_tx_msg_sync + * Sends a PPPoE message synchronously to NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_pppoe_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_pppoe_tx_msg_sync(struct nss_ctx_instance *nss_ctx, + struct nss_pppoe_msg *msg); + +/** + * nss_register_pppoe_session_if + * Registers the PPPoE session interface with the NSS for sending and + * receiving messages. + * + * @datatypes + * nss_pppoe_msg_callback_t \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] notification_callback Callback for the message. + * @param[in] netdev Pointer to the associated network device. + * @param[in] features Socket buffer types supported by this interface. + * @param[in] app_ctx Pointer to the application context of the message. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_register_pppoe_session_if(uint32_t if_num, + nss_pppoe_msg_callback_t notification_callback, + struct net_device *netdev, uint32_t features, void *app_ctx); + +/** + * nss_unregister_pppoe_session_if + * Deregisters the PPPoE session interface from the NSS. + * + * @param[in] if_num NSS interface number. +. * + * @return + * None. + * + * @dependencies + * The tunnel interface must have been previously registered. + */ +extern void nss_unregister_pppoe_session_if(uint32_t if_num); + +/** + * nss_pppoe_get_context + * Gets the PPPoE context used in PPPoE transmit message. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_pppoe_get_context(void); + +/** + * nss_pppoe_debug_stats_get + * Gets NSS session debug statistics. + * + * @param[out] stats_mem Pointer to the memory address, which must be large + * enough to hold all the statistics. + * + * @return + * None. + */ +extern void nss_pppoe_debug_stats_get(void *stats_mem); + +/** + * nss_pppoe_get_bridge_accel_mode + * Gets the PPPoE bridge acceleration mode. + * + * @return + * Current PPPoE bridge acceleration mode. + */ +extern enum nss_pppoe_br_accel_modes nss_pppoe_get_br_accel_mode(void); + +/** + * nss_pppoe_register_sysctl + * Registers the PPPoE system control table. + * + * @return + * None. + */ +void nss_pppoe_register_sysctl(void); + +/** + * nss_pppoe_unregister_sysctl + * Deregisters the PPPoE system control table. + * + * @return + * None. + * + * @dependencies + * The system control table must have been previously registered. + */ +void nss_pppoe_unregister_sysctl(void); + +/** + * nss_pppoe_msg_init + * Initializes a PPPoE message. + * + * @datatypes + * nss_pppoe_msg + * + * @param[in,out] ncm Pointer to the message. + * @param[in] if_num Interface number + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Pointer to the message callback. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_pppoe_msg_init(struct nss_pppoe_msg *ncm, + uint16_t if_num, uint32_t type, uint32_t len, + void *cb, void *app_data); + +/** + * nss_pppoe_stats_register_notifier + * Registers a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_pppoe_stats_register_notifier(struct notifier_block *nb); + +/** + * nss_pppoe_stats_unregister_notifier + * Deregisters a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_pppoe_stats_unregister_notifier(struct notifier_block *nb); + +#endif /*__KERNEL__ */ + +/** + * @} + */ + +#endif /* __NSS_PPPOE_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_pptp.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_pptp.h new file mode 100644 index 000000000..6478684b9 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_pptp.h @@ -0,0 +1,345 @@ +/* + ************************************************************************** + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_pptp.h + * NSS PPTP interface definitions. + */ + +#ifndef _NSS_PPTP_H_ +#define _NSS_PPTP_H_ + +#include "nss_dynamic_interface.h" + +/** + * @addtogroup nss_pptp_subsystem + * @{ + */ + +/** + * Maximum number of supported PPTP sessions is 4. + * Number of dynamic intefaces per session is 3. + * Total 4 * 3 = 12 + */ +#define NSS_MAX_PPTP_DYNAMIC_INTERFACES 12 + +/** + * nss_pptp_metadata_types + * Message types for PPTP requests and responses. + */ +enum nss_pptp_metadata_types { + NSS_PPTP_MSG_SESSION_CONFIGURE, + NSS_PPTP_MSG_SESSION_DECONFIGURE, + NSS_PPTP_MSG_SYNC_STATS, + NSS_PPTP_MSG_MAX +}; + +/** + * nss_pptp_exception_events + * Exception events for PPTP encapsulation and decapsulation packets. + */ +enum nss_pptp_exception_events { + PPTP_EXCEPTION_EVENT_ENCAP_HEADROOM_ERR, + PPTP_EXCEPTION_EVENT_ENCAP_SMALL_SIZE, + PPTP_EXCEPTION_EVENT_ENCAP_PNODE_ENQUEUE_FAIL, + PPTP_EXCEPTION_EVENT_DECAP_NO_SEQ_NOR_ACK, + PPTP_EXCEPTION_EVENT_DECAP_INVAL_GRE_FLAGS, + PPTP_EXCEPTION_EVENT_DECAP_INVAL_GRE_PROTO, + PPTP_EXCEPTION_EVENT_DECAP_WRONG_SEQ, + PPTP_EXCEPTION_EVENT_DECAP_INVAL_PPP_HDR, + PPTP_EXCEPTION_EVENT_DECAP_PPP_LCP, + PPTP_EXCEPTION_EVENT_DECAP_UNSUPPORTED_PPP_PROTO, + PPTP_EXCEPTION_EVENT_DECAP_PNODE_ENQUEUE_FAIL, + PPTP_EXCEPTION_EVENT_MAX, +}; + +/** + * nss_pptp_stats_session + * PPTP debug statistics. + */ +enum nss_pptp_stats_session { + NSS_PPTP_STATS_ENCAP_RX_PACKETS, + NSS_PPTP_STATS_ENCAP_RX_BYTES, + NSS_PPTP_STATS_ENCAP_TX_PACKETS, + NSS_PPTP_STATS_ENCAP_TX_BYTES, + NSS_PPTP_STATS_ENCAP_RX_QUEUE_0_DROP, + NSS_PPTP_STATS_ENCAP_RX_QUEUE_1_DROP, + NSS_PPTP_STATS_ENCAP_RX_QUEUE_2_DROP, + NSS_PPTP_STATS_ENCAP_RX_QUEUE_3_DROP, + NSS_PPTP_STATS_DECAP_RX_PACKETS, + NSS_PPTP_STATS_DECAP_RX_BYTES, + NSS_PPTP_STATS_DECAP_TX_PACKETS, + NSS_PPTP_STATS_DECAP_TX_BYTES, + NSS_PPTP_STATS_DECAP_RX_QUEUE_0_DROP, + NSS_PPTP_STATS_DECAP_RX_QUEUE_1_DROP, + NSS_PPTP_STATS_DECAP_RX_QUEUE_2_DROP, + NSS_PPTP_STATS_DECAP_RX_QUEUE_3_DROP, + NSS_PPTP_STATS_SESSION_ENCAP_HEADROOM_ERR, + NSS_PPTP_STATS_SESSION_ENCAP_SMALL_SIZE, + NSS_PPTP_STATS_SESSION_ENCAP_PNODE_ENQUEUE_FAIL, + NSS_PPTP_STATS_SESSION_DECAP_NO_SEQ_NOR_ACK, + NSS_PPTP_STATS_SESSION_DECAP_INVAL_GRE_FLAGS, + NSS_PPTP_STATS_SESSION_DECAP_INVAL_GRE_PROTO, + NSS_PPTP_STATS_SESSION_DECAP_WRONG_SEQ, + NSS_PPTP_STATS_SESSION_DECAP_INVAL_PPP_HDR, + NSS_PPTP_STATS_SESSION_DECAP_PPP_LCP, + NSS_PPTP_STATS_SESSION_DECAP_UNSUPPORTED_PPP_PROTO, + NSS_PPTP_STATS_SESSION_DECAP_PNODE_ENQUEUE_FAIL, + NSS_PPTP_STATS_SESSION_MAX +}; + +/** + * nss_pptp_stats_notification + * PPTP statistics structure. + */ +struct nss_pptp_stats_notification { + uint32_t core_id; /**< Core ID. */ + uint32_t if_num; /**< Interface number. */ + enum nss_dynamic_interface_type if_type; /**< Dynamic interface type. */ + uint64_t stats[NSS_PPTP_STATS_SESSION_MAX]; /**< PPTP statistics. */ +}; + +/** + * nss_pptp_session_configure_msg + * Message information for configuring a PPTP session. + */ +struct nss_pptp_session_configure_msg { + uint16_t src_call_id; /**< Local call ID for caller or callee. */ + uint16_t dst_call_id; /**< Peer call ID for caller or callee. */ + uint32_t sip; /**< Local tunnel endpoint. */ + uint32_t dip; /**< Remote tunnel endpoint. */ + uint32_t sibling_ifnum_pri; /**< Primary sibling interface. */ + uint32_t sibling_ifnum_aux; /**< Auxiliary sibling interface. */ +}; + +/** + * nss_pptp_session_deconfigure_msg + * Message information for deleting a PPTP session. + */ +struct nss_pptp_session_deconfigure_msg { + uint16_t src_call_id; /**< Local call ID */ +}; + +/** + * nss_pptp_sync_session_stats_msg + * Message information for PPTP synchronization statistics. + */ +struct nss_pptp_sync_session_stats_msg { + struct nss_cmn_node_stats node_stats; + /**< Common node statistics for the encapsulation direction. */ + uint32_t exception_events[PPTP_EXCEPTION_EVENT_MAX]; + /**< Statistics of events which casued packets to exception to host. */ +}; + +/** + * nss_pptp_msg + * Data for sending and receiving PPTP messages. + */ +struct nss_pptp_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a PPTP message. + */ + union { + struct nss_pptp_session_configure_msg session_configure_msg; + /**< Session configuration message. */ + struct nss_pptp_session_deconfigure_msg session_deconfigure_msg; + /**< Session de-configuration message. */ + struct nss_pptp_sync_session_stats_msg stats; + /**< Session statistics message. */ + } msg; /**< Message payload. */ +}; + +/** + * Callback function for receiving PPTP messages. + * + * @datatypes + * nss_pptp_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_pptp_msg_callback_t)(void *app_data, struct nss_pptp_msg *msg); + +/** + * nss_pptp_tx_msg_sync + * Sends a PPTP message synchronously to NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_pptp_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_pptp_tx_msg_sync(struct nss_ctx_instance *nss_ctx, + struct nss_pptp_msg *msg); + +/** + * nss_pptp_tx_buf + * Sends a data packet to the firmware. + * + * @datatypes + * nss_ctx_instance \n + * sk_buff + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] if_num NSS interface number. + * @param[in] skb Pointer to the data socket buffer. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_pptp_tx_buf(struct nss_ctx_instance *nss_ctx, uint32_t if_num, struct sk_buff *skb); + +/** + * nss_pptp_get_context + * Gets the PPTP context used in nss_pptp_tx. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_pptp_get_context(void); + +/** + * Callback function for receiving PPTP tunnel data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_pptp_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * nss_register_pptp_if + * Registers the PPTP tunnel interface with the NSS for sending and + * receiving messages. + * + * @datatypes + * nss_pptp_callback_t \n + * nss_pptp_msg_callback_t \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] type Dynamic interface type. + * @param[in] pptp_data_callback Callback for the data. + * @param[in] notification_callback Callback for the message. + * @param[in] netdev Pointer to the associated network device. + * @param[in] features Socket buffer types supported by this interface. + * @param[in] app_ctx Pointer to the application context of the message. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_register_pptp_if(uint32_t if_num, uint32_t type, nss_pptp_callback_t pptp_data_callback, + nss_pptp_msg_callback_t notification_callback, struct net_device *netdev, uint32_t features, void *app_ctx); + +/** + * nss_unregister_pptp_if + * Deregisters the PPTP tunnel interface from the NSS. + * + * @param[in] if_num NSS interface number. +. * + * @return + * None. + * + * @dependencies + * The tunnel interface must have been previously registered. + */ +extern void nss_unregister_pptp_if(uint32_t if_num); + +/** + * nss_pptp_msg_init + * Initializes a PPTP message. + * + * @datatypes + * nss_pptp_msg + * + * @param[in,out] ncm Pointer to the message. + * @param[in] if_num Interface number + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Pointer to the message callback. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_pptp_msg_init(struct nss_pptp_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data); + +/** + * nss_pptp_register_handler + * Registers the PPTP interface with the NSS debug statistics handler. + * + * @return + * None. + */ +extern void nss_pptp_register_handler(void); + +/** + * nss_pptp_session_debug_stats_get + * Gets NSS session debug statistics. + * + * @param[out] stats_mem Pointer to the memory address, which must be large + * enough to hold all the statistics. + * + * @return + * None. + */ +extern void nss_pptp_session_debug_stats_get(void *stats_mem); + +/** + * nss_pptp_stats_register_notifier + * Registers a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_pptp_stats_register_notifier(struct notifier_block *nb); + +/** + * nss_pptp_stats_unregister_notifier + * Deregisters a statistics notifier. + * + * @datatypes + * notifier_block + * + * @param[in] nb Notifier block. + * + * @return + * 0 on success or -2 on failure. + */ +extern int nss_pptp_stats_unregister_notifier(struct notifier_block *nb); + +/** + * @} + */ + +#endif /* _NSS_PPTP_H_ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_profiler.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_profiler.h new file mode 100644 index 000000000..89ddf6586 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_profiler.h @@ -0,0 +1,406 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2015, 2017, 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_profiler.h + * NSS Profiler APIs + */ + +#ifndef __NSS_PROFILER_H +#define __NSS_PROFILER_H + +/** + * @addtogroup nss_profiler_subsystem + * @{ + */ + +/** + * Length of the counter name. + * + * This value allows all counter values to fit in a single 1400-byte UDP packet. + */ +#define PROFILE_COUNTER_NAME_LENGTH 20 + +#define PROFILE_MAX_APP_COUNTERS 24 /**< Maximum number of application counters. */ + +/** + * nss_profile_counter + * Counter statistics. + */ +struct nss_profile_counter { + char name[PROFILE_COUNTER_NAME_LENGTH]; /**< Counter name. */ + uint32_t value; /**< Current value. */ +}; + +/** + * nss_profiler_message_types + * Message types for the Profiler. + * + * Do not alter this enumeration. However, adding more types is allowed. + */ +enum nss_profiler_message_types { + NSS_PROFILER_CHANGE_SAMPLING_RATE_MSG, /**< Host-to-NSS: ask to do a rate change. */ + NSS_PROFILER_START_MSG, /**< Host-to-NSS: start the NSS Profiler. */ + NSS_PROFILER_STOP_MSG, /**< Host-to-NSS: stop the NSS Profiler. */ + NSS_PROFILER_FLOWCTRL_MSG, /**< Host-to-NSS: do flow control on sampling. */ + NSS_PROFILER_DEBUG_RD_MSG, /**< Host-to-NSS: debug the output. */ + NSS_PROFILER_DEBUG_WR_MSG, /**< Host-to-NSS: debug the input. */ + NSS_PROFILER_DEBUG_REPLY_MSG, /**< NSS-to-host: debug response. */ + NSS_PROFILER_REPLY_MSG, /**< Check the response. */ + NSS_PROFILER_FIXED_INFO_MSG, /**< NSS-to-host: constant data. */ + NSS_PROFILER_COUNTERS_MSG, /**< NSS-to-host: counter information. */ + NSS_PROFILER_SAMPLES_MSG, /**< NSS-to-host: main sample data. */ + NSS_PROFILER_START_CAL, /**< Not for the host to use. */ + NSS_PROFILER_GET_SYS_STAT_EVENT, /**< Get the system status event. */ + NSS_PROFILER_SET_SYS_STAT_EVENT, /**< Set the system status event. */ + NSS_PROFILER_MAX_MSG_TYPES, /**< Maximum number of message types. */ +}; + +/** + * nss_profile_errors + * Profiler error types returned from the NSS. + */ +enum nss_profile_errors { + PROFILE_ERROR_NO_PROF_INIT = 1, + PROFILE_ERROR_EMEM, + PROFILE_ERROR_BAD_PKT, + PROFILE_ERROR_UNKNOWN_CMD, + PROFILE_ERROR_NO_DMA, + PROFILE_ERROR_MAX +}; + +/** + * nss_profiler_cmd_param + * Parameter information for the Profiler. + * + * Use this structure for per-session commands: START, STOP, FLOWCTRL, RATE. + */ +struct nss_profiler_cmd_param { + uint32_t hd_magic; /**< Common overlay in all headers. */ + uint32_t num_counters; + /**< Number of registered performance (application) counters. */ + uint32_t ocm_size; /**< Size of the on-chip-memory. */ + uint32_t sram_start; /**< DDR starting address. */ + uint32_t rate; /**< Sampling rate. */ + uint32_t cpu_id; /**< ID of the chip register. */ + uint32_t cpu_freq; /**< Chip clock frequency. */ + uint32_t ddr_freq; /**< DDR memory speed. */ + + struct nss_profile_counter counters[PROFILE_MAX_APP_COUNTERS]; + /**< Application profiling counters. */ +}; + +/** + * nss_profiler_data_msg + * Message information for the Profiler. + */ +struct nss_profiler_data_msg { + uint32_t hd_magic; /**< Magic header for verification. */ + uint32_t msg_data[1]; /**< Variable length private data. */ +}; + +/** + * nss_profiler_debug_msg + * Message information for Profiler debugging. + */ +struct nss_profiler_debug_msg { + uint32_t hd_magic; /**< Magic header for verification. */ + uint32_t debug_data[256]; /**< Fixed length debug data. */ +}; + +/** + * nss_profiler_msg + * Data for sending and receiving Profiler messages. + */ +struct nss_profiler_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a Profiler message. + */ + union npm_body { + struct nss_profiler_cmd_param pcmdp; /**< Command parameters. */ + struct nss_profiler_debug_msg pdm; /**< Debug packet. */ + struct nss_profiler_data_msg msg; /**< Sampling data. */ + } payload; /**< Message payload. The data length is set in common message header. */ +}; + +/** + * nss_profile_sdma_producer + * DMA descriptor of producer. + */ +struct nss_profile_sdma_producer { + uint32_t intr_num; /**< Interrupt number. */ + uint32_t pkg_id; /**< Package ID that registered this entry. */ + uint32_t buf_size; /**< DMA buffer size. */ + uint32_t num_bufs; /**< Number of ring buffers. */ + uint32_t desc_ring; /**< Ring address (physical 32-bit). */ + uint32_t pad3w[3]; /**< Pad 32-byte alignment. */ +}; + +/** + * nss_u64_32_data + * 64-bit union for both 32/64 bits data aligned at 64-bit boundary. + */ +union nss_u64_32_data { + uint64_t d64; /**< 64-bit space holder: may not be used. */ + uint32_t d32; /**< 32-bit direct data. */ + void *kp; /**< Kernel data pointer either 32 or 64 bits. */ +}; + +/** + * nss_u64_32_func + * 64-bit union for both 32/64 bits function aligned at 64-bit boundary. + */ +union nss_u64_32_func { + uint64_t f64; /**< 64-bit space holder: do not use. */ + void (*fp)(void*); /**< Function pointer: either 32 or 64 bits. */ +}; + +/** + * nss_profile_sdma_consumer + * DMA descriptor of consumer. + */ +struct nss_profile_sdma_consumer { + union nss_u64_32_data arg; /**< Dispatch function argument. */ + union nss_u64_32_func dispatch; /**< Dispatch function pointer. */ + union nss_u64_32_data ring; /**< DMA descriptor ring kernel address. */ + int64_t unused_lw; /**< Extra room in a Ubi32 cache line. */ +}; + +#define ARM_CACHE_LINE_SIZE 128 /**< ARM CPU cache line size in bytes. */ +#define NSS_CACHE_LINE_WORDS 8 /**< Ubi32 CPU cache line size in words. */ + +/** + * Number of DMA per control block. + */ +#define NSS_PROFILE_MAX_DMA_DESCRIPTORS (ARM_CACHE_LINE_SIZE / sizeof(struct nss_profile_sdma_producer) - 1) + +/** + * nss_profile_sdma_ctrl + * Soft DMA control block. + */ +struct nss_profile_sdma_ctrl { + int32_t num_rings; /**< Number of descriptor rings allocated, maximum is 3. */ + int32_t cur_ring; /**< Which ring is in use: Default 0. */ + int32_t pidx[NSS_PROFILE_MAX_DMA_DESCRIPTORS]; /**< Producer index. */ + + /** + * Pad for the first Ubi32 cache line in the first ARM cache line: Unused. + */ + int32_t pad_for_1st_cl_in_1st_arm_cl[NSS_CACHE_LINE_WORDS - 2 - NSS_PROFILE_MAX_DMA_DESCRIPTORS]; + struct nss_profile_sdma_producer producer[NSS_PROFILE_MAX_DMA_DESCRIPTORS]; /**< DMA producer structure. */ + + int32_t cidx[NSS_PROFILE_MAX_DMA_DESCRIPTORS]; /**< Consumer index. */ + + /** + * Pad for the first Ubi32 cache line in the second ARM cache line: Unused. + */ + int32_t pad_for_1st_cl_in_2nd_arm_cl[NSS_CACHE_LINE_WORDS - NSS_PROFILE_MAX_DMA_DESCRIPTORS]; + struct nss_profile_sdma_consumer consumer[NSS_PROFILE_MAX_DMA_DESCRIPTORS]; /**< DMA consumer structure. */ +}; + +/** + * Callback function for receiving Profiler messages. + * + * @note: Memory (buffer) pointed by npm is owned by caller, that is, NSS driver. + * + * @datatypes + * nss_profiler_msg + * + * @param[in] ctx Pointer to the context of the NSS process (core). + * @param[in] npm Pointer to the NSS Profiler message. + */ +typedef void (*nss_profiler_callback_t)(void *ctx, struct nss_profiler_msg *npm); + +/** + * nss_profiler_notify_register + * Registers the Profiler interface with the NSS driver for sending and receiving messages. + * + * This function must be called once for each core. + * + * @datatypes + * nss_core_id_t \n + * nss_profiler_callback_t + * + * @param[in] profiler_callback Callback for the data. + * @param[in] core_id NSS core ID. + * @param[in] ctx Pointer to the context of the NSS core. The context is + provided to caller in the registered callback function. + * + * @return + * Pointer to the NSS core context. + * + * @dependencies + * The caller must provide the valid core ID that is being profiled. + */ +extern void *nss_profiler_notify_register(nss_core_id_t core_id, nss_profiler_callback_t profiler_callback, void *ctx); + +/** + * nss_profiler_notify_unregister + * Deregisters the Profiler interface from the NSS driver. + * + * @datatypes + * nss_core_id_t + * + * @param[in] core_id NSS core ID. + * + * @return + * None. + * + * @dependencies + * The interface must have been previously registered. + */ +extern void nss_profiler_notify_unregister(nss_core_id_t core_id); + +/** + * nss_profiler_if_tx_buf + * Sends a Profiler command to the NSS firmware. + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] buf Buffer to send to NSS firmware. + * @param[in] len Length of the buffer. + * @param[in] cb Pointer to the message callback. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * Status of the Tx operation. + * + * @dependencies + * A valid context must be provided (for the right core). + * This context was returned during registration. + */ +extern nss_tx_status_t nss_profiler_if_tx_buf(void *nss_ctx, + void *buf, uint32_t len, void *cb, void *app_data); + +/** + * nss_profiler_alloc_dma + * Allocate profiler DMA for transmitting samples. + * + * @datatypes + * nss_ctx_instance \n + * nss_profile_sdma_producer + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] dma_p Pointer to return DMA control. + * + * @return + * Buffer adddress. + */ +extern void *nss_profiler_alloc_dma(struct nss_ctx_instance *nss_ctx, struct nss_profile_sdma_producer **dma_p); + +/** + * nss_profiler_release_dma() + * Free profiler DMA. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS context. + * + * @return + * None. + */ +extern void nss_profiler_release_dma(struct nss_ctx_instance *nss_ctx); + +/* + * nss_profile_dma_register_cb + * Register a handler for profile DMA. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] id DMA ID; typical value is 0. + * @param[in] cb Callback function pointer. + * @param[in] arg Callback function argument pointer. + * + * @return + * True on success; or false on failure. + */ +extern bool nss_profile_dma_register_cb(struct nss_ctx_instance *nss_ctx, int id, + void (*cb)(void*), void *arg); + +/** + * nss_profile_dma_deregister_cb() + * Deregister callback for profile DMA. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] id DMA ID; typical value is 0. + * + * @return + * True on success; or false on failure. + */ +extern bool nss_profile_dma_deregister_cb(struct nss_ctx_instance *nss_ctx, int id); + +/** + * nss_profile_dma_get_ctrl() + * API to get profile DMA control. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS context. + * + * @return + * DMA controller. + */ +extern struct nss_profile_sdma_ctrl *nss_profile_dma_get_ctrl(struct nss_ctx_instance *nss_ctx); + +/** + * profile_register_performance_counter + * Registers a Linux counter with the profiler for any variables. + * + * @param[in] counter Pointer to the variable address. + * @param[in] name Pointer to the variable name: if name is longer than + 23 characters, then only the first 23 bytes are used. + * + * @return + * 0 if counter array is full -- too many registered counters. + * 1 on success + */ +extern int profile_register_performance_counter(volatile unsigned int *counter, char *name); + +/** + * nss_profiler_msg_init + * Initializes a Profiler-specific message. + * + * @datatypes + * nss_profiler_msg \n + * nss_profiler_callback_t + * + * @param[in,out] npm Pointer to the NSS Profiler message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the message. + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_profiler_msg_init(struct nss_profiler_msg *npm, uint16_t if_num, + uint32_t type, uint32_t len, + nss_profiler_callback_t cb, void *app_data); + +/** + * @} + */ + +#endif diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_project.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_project.h new file mode 100644 index 000000000..4b1b7119b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_project.h @@ -0,0 +1,176 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * @file nss_project.h + * NSS project interface definitions. + */ + +#ifndef __NSS_PROJECT_H +#define __NSS_PROJECT_H + +/** + * @addtogroup nss_project_subsystem + * @{ + */ + + /** + * Maximum number of IRQs for which a message will have statistics. + * + * Must be defined on firmware and host such that NSS_PROJECT_IRQS_PER_MESSAGE * + * sizeof(struct nss_project_irq_stats) + 8 + sizeof(struct nss_cmn_msg) is smaller + * than the maximum payload size of an sk_buff (1792), 8 being the number of + * bytes needed to store the thread number and number of statistics written. + */ +#define NSS_PROJECT_IRQS_PER_MESSAGE 32 + +/** + * nss_project_message_types + * Project message types. + */ +enum nss_project_message_types { + NSS_PROJECT_MSG_WT_STATS_ENABLE, + /**< Message to enable or disable worker thread statistics. */ + NSS_PROJECT_MSG_WT_STATS_NOTIFY, + /**< NSS to HLOS message containing worker thread statistics. */ + NSS_PROJECT_MSG_MAX, +}; + +/** + * nss_project_error_types + * Project error types. + */ +enum nss_project_error_types { + NSS_PROJECT_ERROR_UNKNOWN_MSG, + /**< Unrecognized message type. */ + NSS_PROJECT_ERROR_WT_STATS_UNSUPPORTED, + /**< The firmware does not support worker thread statistics. */ + NSS_PROJECT_ERROR_WT_STATS_REDUNDANT_ENABLE, + /**< The firmware received a redundant request to enable worker thread statistics. */ + NSS_PROJECT_ERROR_MAX, +}; + +/** + * nss_project_msg_wt_stats_enable + * Enables or disables worker thread statistics collection. + */ +struct nss_project_msg_wt_stats_enable { + + /* + * NSS to HLOS + */ + uint32_t worker_thread_count; + /**< Number of worker threads supported by this core. */ + uint32_t irq_count; + /**< Number of IRQs supported by this core. */ + + /* + * HLOS to NSS + */ + bool enable; /**< True to enable, false to disable. */ +}; + +/** + * nss_project_irq_stats + * Statistics for an individual IRQ on a worker thread. + */ +struct nss_project_irq_stats { + uint64_t count; /**< Number of times callback has been executed */ + uint32_t callback; /**< Address of the callback function */ + uint32_t irq; /**< IRQ number to which callback function is bound */ + uint32_t ticks_min; /**< Fewest ticks taken in callback function */ + uint32_t ticks_avg; /**< Exponential moving average of ticks */ + uint32_t ticks_max; /**< Maximum ticks */ + uint32_t insn_min; /**< Fewest instructions executed in callback function */ + uint32_t insn_avg; /**< Exponential moving average of instruction count */ + uint32_t insn_max; /**< Maximum instructions */ +}; + +/** + * nss_project_msg_wt_stats_notify + * Message containing statistics for active worker_thread IRQs. + */ +struct nss_project_msg_wt_stats_notify { + uint32_t threadno; /**< The thread whose stats are contained. */ + uint32_t stats_written; /**< The number of statistics written to the array. */ + struct nss_project_irq_stats stats[NSS_PROJECT_IRQS_PER_MESSAGE]; + /**< The per-IRQ statistics for the worker thread */ +}; + +/** + * nss_project_msg + * General message structure for project messages. + */ +struct nss_project_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a message to or from the project code. + */ + union { + struct nss_project_msg_wt_stats_enable wt_stats_enable; + /**< Enable or disable worker thread statistics. */ + struct nss_project_msg_wt_stats_notify wt_stats_notify; + /**< One-way worker thread statistics message. */ + } msg; /**< Message payload. */ +}; + +/** + * Callback function for receiving project messages. + * + * @datatypes + * nss_project_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the project message. + */ +typedef void (*nss_project_msg_callback_t)(void *app_data, struct nss_project_msg *msg); + +/** + * nss_project_register_sysctl + * Registers the project sysctl table to the sysctl tree. + * + * @return + * None. + */ +void nss_project_register_sysctl(void); + +/** + * nss_project_unregister_sysctl + * De-registers the project sysctl table from the sysctl tree. + * + * @return + * None. + * + * @dependencies + * The system control must have been previously registered. + */ +void nss_project_unregister_sysctl(void); + +/** + * nss_project_register_handler + * Registers the project message handler. + * + * @return + * None. + */ +void nss_project_register_handler(struct nss_ctx_instance *nss_ctx); + +/** + * @} + */ + +#endif /* __NSS_PROJECT_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_pvxlan.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_pvxlan.h new file mode 100644 index 000000000..2de0da2b5 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_pvxlan.h @@ -0,0 +1,371 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * @file nss_pvxlan.h + * NSS proxy VxLAN interface definitions. + */ + +#ifndef __NSS_PVXLAN_H +#define __NSS_PVXLAN_H + +/** + * @addtogroup nss_pvxlan_subsystem + * @{ + */ + +/** + * Size of the headroom required for proxy VxLAN packets. + */ +#define NSS_PVXLAN_HEADROOM 256 + +/** + * Maximum number of supported proxy VxLAN tunnel sessions. + */ +#define NSS_PVXLAN_MAX_INTERFACES 32 + +/* + * Proxy VxLAN Rule configure message flags + */ +#define NSS_PVXLAN_TUNNEL_IPV4 0x0001 /**< IPv4 tunnel. */ +#define NSS_PVXLAN_TUNNEL_IPV6 0x0002 /**< IPv6 tunnel. */ +#define NSS_PVXLAN_TUNNEL_UDP 0x0010 /**< UDP tunnel. */ +#define NSS_PVXLAN_TUNNEL_UDPLite 0x0020 /**< UDPLite tunnel. */ +#define NSS_PVXLAN_TUNNEL_ENCAP_UDPLITE_HDR_CSUM 0x0100 + /**< Generate only UDPLite header checksum. Otherwise whole UDPLite payload. */ + +/** + * nss_pvxlan_msg_type + * Proxy VxLAN message types. + */ +typedef enum nss_pvxlan_msg_type { + NSS_PVXLAN_MSG_TYPE_SYNC_STATS, /**< Statistics synchronization message. */ + NSS_PVXLAN_MSG_TYPE_TUNNEL_CREATE_RULE, /**< Creating tunnel rule. */ + NSS_PVXLAN_MSG_TYPE_TUNNEL_DESTROY_RULE, + /**< Destroying tunnel rule. */ + NSS_PVXLAN_MSG_TYPE_TUNNEL_ENABLE, /**< Enable the tunnel. */ + NSS_PVXLAN_MSG_TYPE_TUNNEL_DISABLE, /**< Disable the tunnel. */ + NSS_PVXLAN_MSG_TYPE_MAC_ADD, /**< Add MAC rule to the database. */ + NSS_PVXLAN_MSG_TYPE_MAC_DEL, /**< Remove MAC rule from the database. */ + NSS_PVXLAN_MSG_TYPE_MAX, /**< Maximum message type. */ +} nss_pvxlan_msg_type_t; + +/** + * nss_pvxlan_error_response_types + * Error types for proxy VxLAN responses to messages from the host. + */ +typedef enum nss_pvxlan_error_response_types { + NSS_PVXLAN_ERROR_UNKNOWN_TYPE = 1, /**< Unknown type error. */ + NSS_PVXLAN_ERROR_INVALID_L3_PROTO, /**< L3 Protocol is invalid error. */ + NSS_PVXLAN_ERROR_INVALID_UDP_PROTO, /**< UDP Protocol is invalid error. */ + NSS_PVXLAN_ERROR_TUNNEL_DISABLED, /**< Tunnel is already disabled error. */ + NSS_PVXLAN_ERROR_TUNNEL_ENABLED, /**< Tunnel is already enabled error. */ + NSS_PVXLAN_ERROR_TUNNEL_ENTRY_EXIST, + /**< Tunnel is already exist error. */ + NSS_PVXLAN_ERROR_TUNNEL_TABLE_FULL, + /**< Tunnel table is full error. */ + NSS_PVXLAN_ERROR_INVALID_TUNNEL_ID, /**< Tunnel ID is invalid error. */ + NSS_PVXLAN_ERROR_MAC_TABLE_FULL, /**< MAC table is full error. */ + NSS_PVXLAN_ERROR_MAC_EXIST, /**< MAC does already exist in the table error. */ + NSS_PVXLAN_ERROR_MAC_NOT_EXIST, /**< MAC does not exist in the table error. */ + NSS_PVXLAN_ERROR_MAC_ENTRY_UNHASHED, + /**< MAC entry is not hashed in table. */ + NSS_PVXLAN_ERROR_MAC_ENTRY_INSERT_FAILED, + /**< Insertion to MAC table is failed. */ + NSS_PVXLAN_ERROR_UDP_ENCAP_TUNNEL_ID_IN_USE, + /**< Given tunnel ID is currently used. */ + PVXLAN_ERROR_MSG_TUNNEL_ADD_FAILED, /**< Tunnel add information failed. */ + PVXLAN_ERROR_MSG_MAC_ENTRY_ALLOC_FAILED, + /**< MAC entry allocation failed. */ + PVXLAN_ERROR_MSG_MAC_ENTRY_DELETE_FAILED, + /**< MAC entry deletion failed. */ + NSS_PVXLAN_ERROR_MAX, /**< Maximum error type. */ +} nss_pvxlan_error_response_t; + +/** + * nss_pvxlan_stats_msg + * Per-tunnel statistics messages from the NSS firmware. + */ +struct nss_pvxlan_stats_msg { + struct nss_cmn_node_stats node_stats; /**< Common firmware statistics. */ + uint32_t mac_db_lookup_failed; /**< MAC Database look up failed. */ + uint32_t udp_encap_lookup_failed; /**< MAC Database look up failed. */ + uint32_t dropped_malformed; /**< Packet is malformed. */ + uint32_t dropped_next_node_queue_full; /**< Next node dropped the packet. */ + uint32_t dropped_hroom; /**< Transmit dropped due to insufficent headroom. */ + uint32_t dropped_ver_mis; /**< Transmit dropped due to version mismatch. */ + uint32_t dropped_zero_sized_packet; /**< Transmit dropped due to zero sized packet. */ + uint32_t dropped_pbuf_alloc_failed; /**< Receive side pbuf allocation failed. */ + uint32_t dropped_linear_failed; /**< Receive side linearization failed. */ +}; + +/** + * nss_pvxlan_ip + * IP versions. + */ +struct nss_pvxlan_ip { + /** + * Union of IPv4 and IPv6 IP addresses. + */ + union { + uint32_t ipv4; /**< IPv4 address. */ + uint32_t ipv6[4]; /**< IPv6 address. */ + } ip; /**< Union of IPv4 and IPv6 IP addresses. */ +}; + +/** + * nss_pvxlan_encap_rule + * Encapsulation information for a proxy VxLAN tunnel. + */ +struct nss_pvxlan_encap_rule { + struct nss_pvxlan_ip src; /**< Source IP. */ + uint32_t src_port; /**< Source port. */ + struct nss_pvxlan_ip dest; /**< Destination IP. */ + uint32_t dest_port; /**< Destination port. */ +}; + +/** + * nss_pvxlan_rule_msg + * Proxy VxLAN rule message. + * + * The same rule structure applies for both encapsulation and decapsulation + * in a tunnel. + */ +struct nss_pvxlan_rule_msg { + struct nss_pvxlan_encap_rule encap; /**< Encapsulation portion of the rule. */ + uint32_t tunnel_id; /**< Tunnel ID. */ + uint16_t flags; /**< Tunnel type flags. */ + int8_t rps; + /**< Receive packet steering number. Set -1 to let NSS firmware decide. */ +}; + +/** + * nss_pvxlan_tunnel_state_msg + * To enable/disable the tunnel. + */ +struct nss_pvxlan_tunnel_state_msg { + uint32_t sibling_if_num; /**< Sibling interface number. */ +}; + +/** + * nss_pvxlan_mac_msg + * Proxy VxLAN MAC message structure. + */ +struct nss_pvxlan_mac_msg { + uint16_t mac_addr[3]; /**< MAC address. */ + uint16_t flags; /**< Flags. */ + uint32_t vnet_id; /**< Virtual net ID. */ + uint32_t tunnel_id; /**< Tunnel ID. */ + uint16_t policy_id; /**< Policy ID. */ +}; + +/** + * nss_pvxlan_msg + * Data for sending and receiving proxy VxLAN messages. + */ +struct nss_pvxlan_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a proxy VxLAN common message. + */ + union { + struct nss_pvxlan_stats_msg stats; + /**< Proxy VxLAN statistics. */ + struct nss_pvxlan_rule_msg rule_cfg; + /**< Rule information. */ + struct nss_pvxlan_rule_msg rule_uncfg; + /**< Rule information. */ + struct nss_pvxlan_tunnel_state_msg enable; + /**< Enable the tunnel. */ + struct nss_pvxlan_mac_msg mac_add; + /**< MAC rule add message. */ + struct nss_pvxlan_mac_msg mac_del; + /**< MAC rule delete message. */ + } msg; /**< Message payload. */ +}; + +/** + * Callback function for receiving proxy VxLAN tunnel data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_pvxlan_buf_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * Callback function for receiving proxy VxLAN tunnel messages. + * + * @datatypes + * nss_pvxlan_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_pvxlan_msg_callback_t)(void *app_data, struct nss_pvxlan_msg *msg); + +/** + * nss_pvxlan_tx_msg + * Sends proxy VxLAN tunnel messages to the NSS. + * + * Do not call this function from a softirq or interrupt because it + * might sleep if the NSS firmware is busy serving another host thread. + * + * @datatypes + * nss_ctx_instance \n + * nss_pvxlan_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in,out] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_pvxlan_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_pvxlan_msg *msg); + +/** + * nss_pvxlan_tx_msg_sync + * Sends proxy VxLAN tunnel messages to the NSS. + * + * Do not call this function from a softirq or interrupt because it + * might sleep if the NSS firmware is busy serving another host thread. + * + * @datatypes + * nss_ctx_instance \n + * nss_pvxlan_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in,out] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_pvxlan_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_pvxlan_msg *msg); + +/** + * nss_pvxlan_tx_buf + * Sends a proxy VXLAN tunnel data buffer to the NSS interface. + * + * @datatypes + * nss_ctx_instance \n + * sk_buff + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] buf Pointer to the data buffer. + * @param[in] if_num NSS interface number. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_pvxlan_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *buf, uint32_t if_num); + +/** + * nss_pvxlan_unregister + * Deregisters the proxy VxLAN tunnel interface from the NSS interface. + * + * @param[in] if_num NSS interface number. + * + * @return + * TRUE or FALSE + * + * @dependencies + * The tunnel interface must have been previously registered. + */ +extern bool nss_pvxlan_unregister(uint32_t if_num); + +/** + * nss_pvxlan_register + * Registers the proxy VxLAN tunnel interface with the NSS for sending and + * receiving tunnel messages. + * + * @datatypes + * nss_pvxlan_msg_callback_t \n + * nss_pvxlan_buf_callback_t \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] data_cb Data callback for the proxy VXLAN tunnel data. + * @param[in] notify_cb Notify callback for the proxy VXLAN tunnel data. + * @param[in] netdev Pointer to the associated network device. + * @param[in] features Data socket buffer types supported by this interface. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_pvxlan_register(uint32_t if_num, nss_pvxlan_buf_callback_t data_cb, + nss_pvxlan_msg_callback_t notify_cb, struct net_device *netdev, uint32_t features); + +/** + * nss_pvxlan_get_ctx + * Gets the NSS context. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_pvxlan_get_ctx(void); + +/** + * nss_pvxlan_ifnum_with_core_id + * Gets the proxy VxLAN interface number with the core ID. + * + * @param[in] if_num NSS interface number. + * + * @return + * Interface number with the core ID. + */ +extern int nss_pvxlan_ifnum_with_core_id(int if_num); + +/** + * nss_pvxlan_init + * Initializes the proxy VXLAN interface. + * + * @return + * None. + */ +extern void nss_pvxlan_init(void); + +/** + * nss_pvxlan_msg_init + * Initializes a proxy VxLAN message. + * + * @datatypes + * nss_pvxlan_msg \n + * nss_pvxlan_msg_callback_t + * + * @param[in,out] ncm Pointer to the message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_pvxlan_msg_init(struct nss_pvxlan_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, + nss_pvxlan_msg_callback_t cb, void *app_data); + +/** + * @} + */ + +#endif /* __NSS_PVXLAN_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_qrfs.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_qrfs.h new file mode 100644 index 000000000..486baf9d4 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_qrfs.h @@ -0,0 +1,193 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * @file nss_qrfs.h + * NSS QRFS interface definitions. + */ + +#ifndef __NSS_QRFS_H +#define __NSS_QRFS_H + +/** + * @addtogroup nss_qrfs_subsystem + * @{ + */ + +/** + * nss_qrfs_msg_types + * Message types for the NSS QRFS. + */ +enum nss_qrfs_msg_types { + NSS_QRFS_MSG_FLOW_ADD, + NSS_QRFS_MSG_FLOW_DELETE, + NSS_QRFS_MSG_MAC_ADD, + NSS_QRFS_MSG_MAC_DELETE, + NSS_QRFS_MSG_STATS_SYNC, + NSS_QRFS_MSG_MAX, +}; + +/** + * nss_qrfs_error_types + * Error types for the NSS QRFS. + */ +enum nss_qrfs_error_types { + NSS_QRFS_ERROR_INVALID_MSG_TYPE, + NSS_QRFS_ERROR_INVALID_MSG_SIZE, + NSS_QRFS_ERROR_INVALID_IP_VERSION, + NSS_QRFS_ERROR_V4_FLOW_TABLE_FULL, + NSS_QRFS_ERROR_V6_FLOW_TABLE_FULL, + NSS_QRFS_ERROR_MAC_TABLE_FULL, + NSS_QRFS_ERROR_MAX, +}; + +/** + * nss_qrfs_flow_rule_msg + * Information for the NSS QRFS flow rule message. + */ +struct nss_qrfs_flow_rule_msg { + uint16_t src_port; /**< Source port. */ + uint16_t dst_port; /**< Destination port. */ + uint32_t ip_version; /**< IPv4:4 IPv6:6. */ + uint32_t src_addr[4]; /**< Source IP address. */ + uint32_t dst_addr[4]; /**< Destination IP address. */ + uint16_t protocol; /**< IP protocol. */ + uint16_t cpu; /**< CPU core ID. */ + uint32_t if_num; /**< Physical interface number. */ +}; + +/** + * nss_qrfs_mac_rule_msg + * Information for the NSS QRFS MAC rule message. + */ +struct nss_qrfs_mac_rule_msg { + uint8_t mac[ETH_ALEN]; /**< Ethernet address. */ + uint16_t cpu; /**< CPU core ID. */ + uint32_t if_num; /**< Physical interface number. */ +}; + +/** + * nss_qrfs_stats_sync_msg + * Information for the NSS QRFS statistics message. + */ +struct nss_qrfs_stats_sync_msg { + struct nss_cmn_node_stats node_stats; /**< Common pnode statistics. */ + uint32_t invalid_offset; /**< Packets with invalid offset. */ + uint32_t unknown_protocol; /**< Protocol other than TCP, UDP. */ + uint32_t ipv4_flow_rule_hits; /**< Number of IPv4 flow rule hits. */ + uint32_t ipv6_flow_rule_hits; /**< Number of IPv6 flow rule hits. */ +}; + +/** + * nss_qrfs_msg + * Data for sending and receiving NSS QRFS rule or statistics messages. + */ +struct nss_qrfs_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a NSS QRFS rule or statistics message. + */ + union { + struct nss_qrfs_flow_rule_msg flow_add; /**< Add flow rule. */ + struct nss_qrfs_flow_rule_msg flow_delete; /**< Delete flow rule. */ + struct nss_qrfs_mac_rule_msg mac_add; /**< Add MAC rule. */ + struct nss_qrfs_mac_rule_msg mac_delete; /**< Delete MAC rule. */ + struct nss_qrfs_stats_sync_msg stats_sync; /**< Synchronize statistics. */ + } msg; /**< Message payload. */ +}; + +/** + * Callback function for receiving QRFS messages. + * + * @datatypes + * nss_qrfs_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_qrfs_msg_callback_t)(void *app_data, struct nss_qrfs_msg *msg); + +/** + * nss_qrfs_register_handler + * Registers the QRFS interface with the NSS for sending and receiving + * messages. + * + * @datatypes + * nss_ctx_instance + * + * @return + * None. + */ +void nss_qrfs_register_handler(struct nss_ctx_instance *nss_ctx); + +/** + * nss_qrfs_notify_register + * Registers a notifier callback for QRFS messages with the NSS. + * + * @datatypes + * nss_qrfs_msg_callback_t + * + * @param[in] core NSS core number index to the notifier callback table. + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * Pointer to the NSS core context. + */ +struct nss_ctx_instance *nss_qrfs_notify_register(int core, nss_qrfs_msg_callback_t cb, void *app_data); + +/** + * nss_qrfs_notify_unregister + * Deregisters a QRFS message notifier callback from the NSS. + * + * @param[in] core NSS core number index to the notifier callback table. + * + * @return + * None. + */ +void nss_qrfs_notify_unregister(int core); + +/** + * nss_qrfs_set_flow_rule + * Sends a QRFS message to the NSS core to set the flow rule. + * + * @datatypes + * sk_buff + * + * @param[in] skb Pointer to the SKB buffer. + * @param[in] cpu CPU number to set in the flow table. + * @param[in] action Action to perform on the flow table. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_qrfs_set_flow_rule(struct sk_buff *skb, uint32_t cpu, uint32_t action); + +/** + * nss_qrfs_init + * Initializes the QRFS. + * + * @return + * None. + */ +void nss_qrfs_init(void); + +/** + * @} + */ + +#endif /* __NSS_QRFS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_qvpn.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_qvpn.h new file mode 100644 index 000000000..f4be40a93 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_qvpn.h @@ -0,0 +1,488 @@ +/* + ************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_qvpn.h + * NSS QVPN interface definitions. + */ + +#ifndef _NSS_QVPN_H_ +#define _NSS_QVPN_H_ + +/** + * @addtogroup nss_qvpn_subsystem + * @{ + */ + +#define NSS_QVPN_INTERFACE_MAX_LONG BITS_TO_LONGS(NSS_MAX_NET_INTERFACES) /**< QVPN interface mapping bits. */ +#define NSS_QVPN_STATS_MAX_LINES (NSS_STATS_NODE_MAX + 32) /**< Maxminum number of lines for QVPN statistics dump. */ +#define NSS_QVPN_STATS_SIZE_PER_IF (NSS_STATS_MAX_STR_LENGTH * NSS_QVPN_STATS_MAX_LINES) /**< Total number of statistics per QVPN interface. */ + +#define NSS_QVPN_CMDS_MAX 10 /**< Maximum number of QVPN commands supported. */ +#define NSS_QVPN_VPN_HDR_HEAD_SIZE_MAX 64 /**< Maximum size of QVPN header. */ +#define NSS_QVPN_VPN_HDR_TAIL_SIZE_MAX 32 /**< Maximum size of QVPN tail. */ +#define NSS_QVPN_IV_SIZE_MAX 16 /**< Maximum size of IV supported. */ +#define NSS_QVPN_SESS_ID_SIZE_MAX 8 /**< Maximum size of session ID. */ + +/* + * QVPN L3/L4 header flags. + */ +#define NSS_QVPN_HDR_FLAG_IPV6 0x0001 /**< Outer L3 header is IPv6. */ +#define NSS_QVPN_HDR_FLAG_L4_UDP 0x0002 /**< L4 is UDP. */ + +/** + * nss_qvpn_msg_type + * Message types for QVPN NSS firmware. + */ +enum nss_qvpn_msg_type { + NSS_QVPN_MSG_TYPE_TUNNEL_CONFIGURE, /**< Configure QVPN tunnel instance. */ + NSS_QVPN_MSG_TYPE_TUNNEL_DECONFIGURE, /**< Deconfigure QVPN tunnel instance. */ + NSS_QVPN_MSG_TYPE_CRYPTO_KEY_ADD, /**< Add a new crypto key. */ + NSS_QVPN_MSG_TYPE_CRYPTO_KEY_DEL, /**< Delete crypto key. */ + NSS_QVPN_MSG_TYPE_CRYPTO_KEY_ACTIVATE, /**< Activate crypto key. */ + NSS_QVPN_MSG_TYPE_CRYPTO_KEY_DEACTIVATE,/**< Deactivate crypto key. */ + NSS_QVPN_MSG_TYPE_SYNC_STATS, /**< Statistics synchronization. */ + NSS_QVPN_MSG_TYPE_MAX /**< Maximum QVPN message type. */ +}; + +/** + * nss_qvpn_cmds_type + * Processing commands for QVPN. + */ +enum nss_qvpn_cmds_type { + NSS_QVPN_CMDS_TYPE_NONE, /**< Add VPN header to packet. */ + NSS_QVPN_CMDS_TYPE_ADD_VPN_HDR, /**< Add VPN header to packet. */ + NSS_QVPN_CMDS_TYPE_REMOVE_VPN_HDR, /**< Remove VPN header from packet. */ + NSS_QVPN_CMDS_TYPE_ADD_L3_L4_HDR, /**< Add L3/L4 header to packet. */ + NSS_QVPN_CMDS_TYPE_REMOVE_L3_L4_HDR, /**< Remove L3/L4 header from packet. */ + NSS_QVPN_CMDS_TYPE_ENCRYPT, /**< Send packet for encryption. */ + NSS_QVPN_CMDS_TYPE_DECRYPT, /**< Send packet for decryption. */ + NSS_QVPN_CMDS_TYPE_ANTI_REPLAY, /**< Sequence number processing. */ + NSS_QVPN_CMDS_TYPE_MAX /**< Maximum command supported. */ +}; + +/** + * nss_qvpn_profile + * QVPN profiles supported. + */ +enum nss_qvpn_profile { + NSS_QVPN_PROFILE_NONE, /**< No profile supported. */ + NSS_QVPN_PROFILE_CRYPTO_ENCAP, /**< Encapsulation profile with crypto enabled. */ + NSS_QVPN_PROFILE_CRYPTO_DECAP, /**< Decapsulation profile with crypto enabled. */ + NSS_QVPN_PROFILE_ENCAP, /**< Encapsulation Profile with crypto disabled. */ + NSS_QVPN_PROFILE_DECAP, /**< Decapsulation Profile with crypto disabled. */ + NSS_QVPN_PROFILE_MAX, /**< Maximum profile. */ +}; + +/** + * nss_qvpn_pkt_drop_event + * Packets drop statistics from QVPN node. + */ +enum nss_qvpn_pkt_drop_event { + NSS_QVPN_PKT_DROP_EVENT_NO_TAILROOM, /**< Packet tail room not enough to copy HMAC to tail. */ + NSS_QVPN_PKT_DROP_EVENT_NO_HEADROOM, /**< Packet head room not enough to add QVPN headers. */ + NSS_QVPN_PKT_DROP_EVENT_CBUF_ALLOC_FAIL, /**< Received packet dropped as crypto buffer allocation failed. */ + NSS_QVPN_PKT_DROP_EVENT_PBUF_ALLOC_FAIL, /**< Received packet dropped as associated pbuf allocation failed. */ + NSS_QVPN_PKT_DROP_EVENT_SYNC_ALLOC_FAIL, /**< Pbuf dropped while doing statistics synchronization. */ + NSS_QVPN_PKT_DROP_EVENT_PBUF_UNALIGN, /**< Received packet dropped as unaligned buffer. */ + NSS_QVPN_PKT_DROP_EVENT_CRYPTO_ENQ_FAIL, /**< Received packet dropped as crypto enqueue failed. */ + NSS_QVPN_PKT_DROP_EVENT_LINEAR_COPY_FAIL, /**< Received packet dropped as scatter-gather linear copy failed. */ + NSS_QVPN_PKT_DROP_EVENT_FWD_ENQ_FAIL, /**< Received packet dropped as enqueue to next node failed. */ + NSS_QVPN_PKT_DROP_EVENT_POST_CRYPTO_Q_FULL, /**< Post crypto queue is full dropping pbuf. */ + NSS_QVPN_PKT_DROP_EVENT_NODE_INACTIVE, /**< Node is inactive dropping crypto processed packet. */ + NSS_QVPN_PKT_DROP_EVENT_NON_CRYPTO_PB, /**< Non crypto processed packet enqueued to post crypto queue. */ + NSS_QVPN_PKT_DROP_EVENT_PAD_INVALID, /**< Packet received with invalid padding. */ + NSS_QVPN_PKT_DROP_EVENT_BLK_UNALIGNED, /**< Received pbuf length is not cipher block aligned. */ + NSS_QVPN_PKT_DROP_EVENT_MAX /**< End of packet drop event list. */ +}; + +/** + * nss_qvpn_exception_event + * Exception events from QVPN node. + */ +enum nss_qvpn_exception_event { + NSS_QVPN_EXCEPTION_EVENT_RX_CONTROL_PKT, /**< QVPN control packet received. */ + NSS_QVPN_EXCEPTION_EVENT_RX_TAIL_NOSUPP, /**< Protocol with tail not supported. */ + QVPN_TUN_EXCEPTION_EVENT_RX__HR_INSUFF, /**< Insufficient headroom. */ + NSS_QVPN_EXCEPTION_EVENT_RX_SESS_ID_INVALID, /**< Invalid session ID. */ + NSS_QVPN_EXCEPTION_EVENT_RX_DATA_PKT, /**< Data packets exceptioned to host. */ + NSS_QVPN_EXCEPTION_EVENT_RX_MALFORMED, /**< Malformed packet received. */ + NSS_QVPN_EXCEPTION_EVENT_MAX /**< End of exception event list. */ +}; + +/** + * nss_qvpn_error_type + * Error types for the QVPN interface. + */ +enum nss_qvpn_error_type { + NSS_QVPN_ERROR_TYPE_NONE, /**< No error. */ + NSS_QVPN_ERROR_TYPE_UNKNOWN_MSG, /**< Unknown message. */ + NSS_QVPN_ERROR_TUN_ALREADY_CONFIGURED, /**< Tunnel already configured. */ + NSS_QVPN_ERROR_TYPE_IF_INVALID, /**< Invalid interface. */ + NSS_QVPN_ERROR_TYPE_SIBLING_IF, /**< Invalid sibling interface number. */ + NSS_QVPN_ERROR_TYPE_IV_SIZE_INVALID, /**< Invalid IV size. */ + NSS_QVPN_ERROR_TYPE_HMAC_SIZE_INVALID, /**< Invalid HMAC size. */ + NSS_QVPN_ERROR_TYPE_CRYPTO_BLK_SIZE_INVALID, /**< Invalid crypto block size. */ + NSS_QVPN_ERROR_TYPE_SESSION_IDX_SIZE_INVALID, /**< Invalid session index size. */ + NSS_QVPN_ERROR_TYPE_CMD_NOT_SUPPORTED, /**< Command not supported. */ + NSS_QVPN_ERROR_TYPE_L4_PROTO_INVALID, /**< L4 protocol encapsulation is not supported. */ + NSS_QVPN_ERROR_TYPE_SIBLING_IF_TYPE, /**< Invalid sibling interface type. */ + NSS_QVPN_ERROR_TYPE_CMDS_COUNT_INVALID, /**< Total number of commands is invalid. */ + NSS_QVPN_ERROR_TYPE_ENTRY_NOT_FOUND, /**< Entry not found. */ + NSS_QVPN_ERROR_TYPE_ENTRY_NOT_ACTIVE, /**< Entry not active. */ + NSS_QVPN_ERROR_TYPE_ENTRY_ALREADY_ACTIVE, /**< Entry already active. */ + NSS_QVPN_ERROR_TYPE_CRYPTO_IDX_MISMATCH, /**< Invalid crypto index. */ + NSS_QVPN_ERROR_TYPE_KI_ALLOC_FAIL, /**< Key information allocation failure. */ + NSS_QVPN_ERROR_TYPE_PROFILE_INVALID, /**< Invalid command profile. */ + NSS_QVPN_ERROR_TYPE_RX_TAIL_NOSUPP, /**< VPN with tail not supported. */ + NSS_QVPN_ERROR_TYPE_MAX /**< End of error list. */ +}; + +/** + * nss_qvpn_iv_type + * IV type for generating and copying in packet. + */ +enum nss_qvpn_iv_type { + NSS_QVPN_IV_TYPE_NONE, /**< No IV. */ + NSS_QVPN_IV_TYPE_STATIC, /**< Use static IV configured. */ + NSS_QVPN_IV_TYPE_DYNAMIC_RAND, /**< Generate IV randomly. */ + NSS_QVPN_IV_TYPE_MAX /**< End of IV type list. */ +}; + +/** + * nss_qvpn_pad_type + * Pad type for generating and copying in packet. + */ +enum nss_qvpn_pad_type { + NSS_QVPN_PAD_TYPE_NONE, /**< No padding. */ + NSS_QVPN_PAD_TYPE_PKCS7, /**< Generate pad buffer using PKCS7. */ + NSS_QVPN_PAD_TYPE_INC, /**< Generate pad buffer monotonically increasing sequence. */ + NSS_QVPN_PAD_TYPE_MAX /**< End of pad type. */ +}; + +/** + * nss_qvpn_anti_replay_alg + * Anti-replay algorithms supported. + */ +enum nss_qvpn_anti_replay_alg { + NSS_QVPN_ANTI_REPLAY_ALG_NONE, /**< No anti-replay. */ + NSS_QVPN_ANTI_REPLAY_ALG_REPLAY_WINDOW, /**< Generate pad buffer monotonically increasing sequence. */ + NSS_QVPN_ANTI_REPLAY_ALG_MAX /**< End of anti-replay algorithm. */ +}; + +/** + * nss_qvpn_crypto_mode + * Crypto modes supported. + */ +enum nss_qvpn_crypto_mode { + NSS_QVPN_CRYPTO_MODE_NONE, /**< NULL cipher and NULL authentication. */ + NSS_QVPN_CRYPTO_MODE_ENC, /**< Encryption only. */ + NSS_QVPN_CRYPTO_MODE_DEC, /**< Decryption only. */ + NSS_QVPN_CRYPTO_MODE_AUTH, /**< Authentication only. */ + NSS_QVPN_CRYPTO_MODE_ENC_AUTH, /**< Encryption and then authentication. */ + NSS_QVPN_CRYPTO_MODE_AUTH_DEC, /**< Authentication and then decryption. */ + NSS_QVPN_CRYPTO_MODE_AUTH_ENC, /**< Authentication and then encryption. */ + NSS_QVPN_CRYPTO_MODE_DEC_AUTH, /**< Decryption and then authentication. */ + NSS_QVPN_CRYPTO_MODE_MAX /**< End of crypto mode. */ +}; + +/** + * nss_qvpn_hdr_configure_msg + * QVPN header configuration. + */ +struct nss_qvpn_hdr_configure_msg { + uint32_t src_ip[4]; /**< Source IP address. */ + uint32_t dst_ip[4]; /**< Destination IP address. */ + uint16_t src_port; /**< Source port. */ + uint16_t dst_port; /**< Destination port. */ + uint16_t hdr_flags; /**< Header flags. */ + uint16_t seqnum_size; /**< Size of sequence number. */ + uint16_t seqnum_offset; /**< Sequence number offset. */ + uint16_t anti_replay_alg; /**< Anti-replay algorithm. */ + uint16_t session_id_size; /**< Session ID size. */ + uint16_t session_id_offset; /**< Session ID offset. */ + uint16_t vpn_hdr_head_size; /**< VPN header size. */ + uint16_t vpn_hdr_head_offset; /**< VPN header offset. */ + uint16_t vpn_hdr_tail_size; /**< Size of tail. */ + uint16_t res; /**< Reserved for alignment. */ + uint8_t vpn_hdr_head[NSS_QVPN_VPN_HDR_HEAD_SIZE_MAX]; /**< Content of VPN header. */ + uint8_t vpn_hdr_tail[NSS_QVPN_VPN_HDR_TAIL_SIZE_MAX]; /**< VPN header tail content. */ + uint8_t hop_limit; /**< TTL or hop limit. */ + uint8_t res1[3]; /**< Reserved for alignment. */ +}; + +/** + * nss_qvpn_crypto_configure_msg + * QVPN crypto configuration message. + */ +struct nss_qvpn_crypto_configure_msg { + uint16_t hmac_len; /**< Length of HMAC to copy. */ + uint16_t hmac_offset; /**< Offset to copy HMAC. */ + uint16_t auth_offset; /**< Data offset to start authentication. */ + uint16_t cipher_op_offset; /**< Start of cipher data. */ + uint16_t cipher_blk_size; /**< Cipher block size. */ + uint16_t pad_type; /**< Pad algorithm. */ + uint16_t crypto_mode; /**< Crypto mode. */ + uint16_t iv_len; /**< Length of IV. */ + uint16_t iv_offset; /**< IV offset. */ + uint16_t iv_type; /**< IV generation algorithm. */ + uint8_t iv_val[NSS_QVPN_IV_SIZE_MAX]; /**< IV to be used. */ +}; + +/** + * nss_qvpn_crypto_key_add_msg + * QVPN key add message. + */ +struct nss_qvpn_crypto_key_add_msg { + uint32_t crypto_idx; /**< Crypto session ID. */ + uint8_t session_id[NSS_QVPN_SESS_ID_SIZE_MAX]; /**< Session ID. */ +}; + +/** + * nss_qvpn_crypto_key_del_msg + * Delete/Deactivate key message. + */ +struct nss_qvpn_crypto_key_del_msg { + uint32_t crypto_idx; /**< Crypto index to delete/deactivate. */ +}; + +/** + * nss_qvpn_tunnel_config_msg + * QVPN tunnel configure message. + */ +struct nss_qvpn_tunnel_config_msg { + uint32_t sibling_if; /**< Sibling interface number. */ + uint16_t total_cmds; /**< Total number of commands. */ + uint16_t cmd_profile; /**< Command processing profile. */ + uint16_t cmd[NSS_QVPN_CMDS_MAX]; /**< Commands to execute. */ + struct nss_qvpn_crypto_key_add_msg crypto_key; /**< Initial crypto key. */ + struct nss_qvpn_hdr_configure_msg hdr_cfg; /**< VPN header configuration. */ + struct nss_qvpn_crypto_configure_msg crypto_cfg; /**< Crypto configuration. */ +}; + +/** + * nss_qvpn_crypto_key_activate_msg + * Activate key message. + */ +struct nss_qvpn_crypto_key_activate_msg { + uint32_t crypto_idx; /**< Crypto session ID. */ + uint8_t vpn_hdr_head[NSS_QVPN_VPN_HDR_HEAD_SIZE_MAX]; /**< Content of VPN header. */ +}; + +/** + * nss_qvpn_stats_sync_msg + * Message information for QVPN synchronization statistics. + */ +struct nss_qvpn_stats_sync_msg { + struct nss_cmn_node_stats node_stats; /**< Common node statistics. */ + uint32_t crypto_resp_error[NSS_CRYPTO_CMN_RESP_ERROR_MAX]; /**< Crypto response errors. */ + uint32_t pkt_drop_event[NSS_QVPN_PKT_DROP_EVENT_MAX]; /**< Packet drop events. */ + uint32_t exception_event[NSS_QVPN_EXCEPTION_EVENT_MAX]; /**< QVPN exception events. */ +}; + +/** + * nss_qvpn_msg + * QVPN message structure for configuration and statistics. + */ +struct nss_qvpn_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /**< QVPN configuration messages. */ + union { + struct nss_qvpn_tunnel_config_msg tunnel_config; /**< QVPN tunnel configure message. */ + struct nss_qvpn_crypto_key_add_msg key_add; /**< Crypto key add message. */ + struct nss_qvpn_crypto_key_del_msg key_del; /**< Crypto key delete message. */ + struct nss_qvpn_crypto_key_activate_msg key_activate; /**< Crypto key active message. */ + struct nss_qvpn_stats_sync_msg stats; /**< QVPN statistics synchronization message. */ + } msg; /**< QVPN configuration message. */ +}; + +/** + * nss_qvpn_tx_msg + * Sends an QVPN message to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_qvpn_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_qvpn_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_qvpn_msg *msg); + +/** + * nss_qvpn_tx_msg_sync + * Sends an QVPN message to the NSS synchronously. + * + * @datatypes + * nss_ctx_instance \n + * nss_qvpn_msg \n + * nss_qvpn_msg_type \n + * nss_qvpn_error_type + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] nvm Pointer to the message data. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in,out] resp Response for the configuration. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_qvpn_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_qvpn_msg *nvm, + uint32_t if_num, enum nss_qvpn_msg_type type, uint16_t len, + enum nss_qvpn_error_type *resp); + +/** + * nss_qvpn_tx_buf + * Sends data packet for QVPN encapsulation/decapsulation. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] if_num NSS interface number. + * @param[in] skb Pointer to sk_buff. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_qvpn_tx_buf(struct nss_ctx_instance *nss_ctx, uint32_t if_num, struct sk_buff *skb); + +/** + * nss_qvpn_msg_init + * Initializes an QVPN message. + * + * @datatypes + * nss_qvpn_msg + * + * @param[in,out] ncm Pointer to the message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Pointer to the message callback. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +void nss_qvpn_msg_init(struct nss_qvpn_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data); + +/** + * nss_qvpn_get_context + * Gets the QVPN context used in nss_qvpn_tx. + * + * @return + * Pointer to the NSS core context. + */ +struct nss_ctx_instance *nss_qvpn_get_context(void); + +/** + * Callback when QVPN data is received. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_qvpn_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * Callback to receive QVPN messages. + * + * @datatypes + * nss_cmn_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_qvpn_msg_callback_t)(void *app_data, struct nss_cmn_msg *msg); + +/** + * nss_qvpn_register_if + * Register to send/receive QVPN messages to NSS. + * + * @datatypes + * nss_qvpn_callback_t \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] qvpn_data_callback Callback for the data. + * @param[in] qvpn_event_callback Callback for receiving events. + * @param[in] netdev Pointer to the associated network device. + * @param[in] features Data socket buffer types supported by this interface. + * @param[in] app_ctx Pointer to the application context of the message. + * + * @return + * Pointer to the NSS core context. + */ +struct nss_ctx_instance *nss_qvpn_register_if(uint32_t if_num, nss_qvpn_callback_t qvpn_data_callback, + nss_qvpn_msg_callback_t qvpn_event_callback, struct net_device *netdev, + uint32_t features, void *app_ctx); + +/** + * nss_qvpn_unregister_if + * Deregisters the QVPN interface from the NSS. + * + * @param[in] if_num NSS interface number. + * + * @return + * None. + */ +void nss_qvpn_unregister_if(uint32_t if_num); + +/** + * nss_qvpn_ifnum_with_core_id + * Gets the QVPN interface number with the core ID. + * + * @param[in] if_num NSS interface number. + * + * @return + * Interface number with the core ID. + */ +int nss_qvpn_ifnum_with_core_id(int if_num); + +/** + * nss_qvpn_register_handler + * Registers the QVPN handler with the NSS. + * + * @return + * None. + */ +void nss_qvpn_register_handler(void); + +/** + * nss_qvpn_ifmap_get + * Returns active QVPN interfaces. + * + * @return + * Pointer to interface map. + */ +unsigned long *nss_qvpn_ifmap_get(void); + +/** + * @} + */ + +#endif /* _NSS_QVPN_H_ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_rmnet_rx.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_rmnet_rx.h new file mode 100644 index 000000000..ec585e99a --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_rmnet_rx.h @@ -0,0 +1,378 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * @file nss_rmnet_rx.h + * NSS Virtual interface message Structure and APIs + */ + +#ifndef __NSS_RMNET_RX_H +#define __NSS_RMNET_RX_H + +#include "nss_if.h" + +/** + * @addtogroup nss_rmnet_subsystem + * @{ + */ + +/** + * Maximum number of DMA channel. + */ +#define NSS_RMNET_RX_CHANNEL_MAX 12 + +/** + * nss_rmnet_rx_dp_type + * Interface datapath types. NSS-to-host path will be seen by ECM for rules. + */ +enum nss_rmnet_rx_dp_type { + NSS_RMNET_RX_DP_N2H, /**< Interface on NSS-to-host path has zero value. */ + NSS_RMNET_RX_DP_H2N, /**< Interface on host-to-NSS path has non-zero value. */ +}; + +/** + * nss_rmnet_rx_msg_types + * Message types for interface requests and responses. + */ +enum nss_rmnet_rx_msg_types { + NSS_RMNET_RX_TX_CONFIG_MSG = NSS_IF_MAX_MSG_TYPES + 1, + /**< Configuration message. */ + NSS_RMNET_RX_STATS_SYNC_MSG, /**< Statistic synchronization message. */ + NSS_RMNET_RX_MAX_MSG_TYPES, /**< Maximum message type. */ +}; + +/** + * nss_rmnet_rx_error_types + * Error types for the virtual interface. + */ +enum nss_rmnet_rx_error_types { + NSS_RMNET_RX_SUCCESS, /**< No error. */ + NSS_RMNET_RX_ERROR_TYPE_MSG_UNKNOWN, /**< Unknown message type. */ + NSS_RMNET_RX_ERROR_TYPE_ALREADY_CONFIGURED, /**< Tunnel is already configured. */ + NSS_RMNET_RX_ERROR_TYPE_SIBLING_NOTFOUND, /**< Sibling interface is not found. */ + NSS_RMNET_RX_ERROR_TYPE_NEXTHOP_NOTFOUND, /**< Next hop is not found. */ + NSS_RMNET_RX_ERROR_TYPE_SIBLING_MISMATCH, /**< Sibling interface type mismatches. */ + NSS_RMNET_RX_ERROR_TYPE_DMA_CHANNEL_FAIL, /**< DMA Channel allocation failed. */ + NSS_RMNET_RX_ERROR_TYPE_RMNET_INVALID, /**< Interface type is invalid. */ + NSS_RMNET_RX_ERROR_TYPE_SHAPER_INVALID, /**< Shaper is invalid. */ + NSS_RMNET_RX_REG_FAILURE, /**< Registration failed. */ + NSS_RMNET_RX_ALLOC_FAILURE, /**< Memory allocation failed. */ + NSS_RMNET_RX_ERROR_MAX, /**< Maximum error type. */ +}; + +/** + * nss_rmnet_rx_pvt + * Private data information for the interface. + */ +struct nss_rmnet_rx_pvt { + struct semaphore sem; + /**< Semaphore to ensure that only one instance of a message is sent to the NSS. */ + struct completion complete; + /**< Waits for message completion or time out. */ + int response; /**< Message process response from the NSS firmware. */ + int sem_init_done; /**< Semaphore initialization is done. */ +}; + +/** + * nss_rmnet_rx_config_msg + * Message information for configuring the interface. + */ +struct nss_rmnet_rx_config_msg { + uint32_t flags; /**< Interface flags. */ + uint32_t sibling; /**< Sibling interface number. */ + uint32_t nexthop; /**< Next hop interface number. */ + uint32_t no_channel; /**< Number of channels. */ +}; + +/** + * nss_rmnet_rx_stats + * Interface statistics received from the NSS. + */ +struct nss_rmnet_rx_stats { + struct nss_cmn_node_stats node_stats; + /**< Common statistics. */ + uint32_t enqueue_failed; /**< Enqueue to next node is failed. */ + uint32_t no_avail_channel; /**< No available DMA channel. */ + uint32_t num_linear_pbuf; /**< Number of linear pbufs. */ + uint32_t no_pbuf_to_linear; /**< No pbuf to linearize. */ + uint32_t no_enough_room; /**< Not enough headroom to linearize the pbuf. */ + uint32_t using_channel[NSS_RMNET_RX_CHANNEL_MAX]; + /**< How many times a channel is used. */ + uint32_t dma_failed; /**< DMA copy call failed. */ +}; + + +/** + * nss_rmnet_rx_msg + * Data for sending and receiving interface messages. + */ +struct nss_rmnet_rx_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a virtual interface message. + */ + union { + struct nss_rmnet_rx_config_msg if_config; + /**< Rule for creating a virtual interface. */ + struct nss_rmnet_rx_stats stats; + /**< Virtual interface statistics. */ + } msg; /**< Message payload. */ +}; + +/** + * Callback to transmit interface data received from NSS + * to the transmit path of the virtual interface. + * + * @datatypes + * net_device \n + * sk_buff + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + */ +typedef void (*nss_rmnet_rx_xmit_callback_t)(struct net_device *netdev, struct sk_buff *skb); + +/** + * Callback function for interface data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_rmnet_rx_data_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * Callback function for interface messages. + * + * @datatypes + * nss_cmn_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_rmnet_rx_msg_callback_t)(void *app_data, struct nss_cmn_msg *msg); + +/** + * nss_rmnet_rx_handle + * Context information for NSS communication. + */ +struct nss_rmnet_rx_handle { + struct nss_ctx_instance *nss_ctx; /**< NSS context. */ + int32_t if_num_n2h; /**< Redirect interface number on NSS-to-host path. */ + int32_t if_num_h2n; /**< Redirect interface number on host-to-NSS path. */ + struct net_device *ndev; /**< Associated network device. */ + struct nss_rmnet_rx_pvt *pvt; /**< Private data structure. */ + uint64_t *stats_n2h; /**< Virtual interface statistics from NSS-to-host. */ + uint64_t *stats_h2n; /**< Virtual interface statistics from host-to-NSS. */ + atomic_t refcnt; /**< Reference count. */ + nss_rmnet_rx_msg_callback_t cb; /**< Message callback. */ + void *app_data; /**< Application data to be passed to the callback. */ +}; + +/** + * nss_rmnet_rx_destroy_sync + * Destroys the virtual interface synchronously. + * + * @datatypes + * nss_rmnet_rx_handle + * + * @param[in,out] handle Pointer to the virtual interface handle (provided during + * dynamic interface allocation). + * + * @return + * Status of the Tx operation. + * + * @dependencies + * The interface must have been previously created. + */ +extern nss_tx_status_t nss_rmnet_rx_destroy_sync(struct nss_rmnet_rx_handle *handle); + +/** + * nss_rmnet_rx_create_sync_nexthop + * Creates a virtual interface synchronously with specified nexthops. + * + * @datatypes + * net_device + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] nexthop_n2h Nexthop interface number of NSS-to-host dynamic interface. + * @param[in] nexthop_h2n Nexthop interface number of host-to-NSS dynamic interface. + * + * @return + * Pointer to NSS virtual interface handle. + */ +extern struct nss_rmnet_rx_handle *nss_rmnet_rx_create_sync_nexthop(struct net_device *netdev, uint32_t nexthop_n2h, uint32_t nexthop_h2n); + +/** + * nss_rmnet_rx_tx_buf + * Forwards virtual interface packets to the NSS. + * + * @datatypes + * nss_rmnet_rx_handle \n + * sk_buff + * + * @param[in,out] handle Pointer to the virtual interface handle (provided during + * registration). + * @param[in] skb Pointer to the data socket buffer. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_rmnet_rx_tx_buf(struct nss_rmnet_rx_handle *handle, + struct sk_buff *skb); + +/** + * nss_rmnet_rx_tx_msg + * Sends a message to the virtual interface. + * + * @datatypes + * nss_ctx_instance \n + * nss_rmnet_rx_msg + * + * @param[in] nss_ctx Pointer to the NSS context (provided during registration). + * @param[in] nvim Pointer to the virtual interface message. + * + * @return + * Command Tx status. + */ +extern nss_tx_status_t nss_rmnet_rx_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_rmnet_rx_msg *nvim); + +/** + * nss_rmnet_rx_xmit_callback_unregister + * Deregisters the transmit callback from the virtual interface. + * + * @datatypes + * nss_rmnet_rx_handle + * + * @param[in,out] handle Pointer to the virtual interface handle. + * + * @return + * None. + */ +extern void nss_rmnet_rx_xmit_callback_unregister(struct nss_rmnet_rx_handle *handle); + +/** + * nss_rmnet_rx_xmit_callback_register + * Registers a transmit callback to a virtual interface. + * + * @datatypes + * nss_rmnet_rx_handle \n + * nss_rmnet_rx_xmit_callback_t + * + * @param[in,out] handle Pointer to the virtual interface handle (provided during + * dynamic interface allocation). + * @param[in] cb Callback handler for virtual data packets. + * + * @return + * None. + */ +extern void nss_rmnet_rx_xmit_callback_register(struct nss_rmnet_rx_handle *handle, + nss_rmnet_rx_xmit_callback_t cb); + +/** + * nss_rmnet_rx_unregister + * Deregisters a virtual interface from the NSS driver. + * + * @datatypes + * nss_rmnet_rx_handle + * + * @param[in,out] handle Pointer to the virtual interface handle. + * + * @return + * None. + */ +extern void nss_rmnet_rx_unregister(struct nss_rmnet_rx_handle *handle); + +/** + * nss_rmnet_rx_register + * Registers a virtual Interface with NSS driver. + * + * @datatypes + * nss_rmnet_rx_handle \n + * nss_rmnet_rx_data_callback_t \n + * net_device + * + * @param[in,out] handle Pointer to the virtual interface handle (provided during + * dynamic interface allocation). + * @param[in] data_callback Callback handler for virtual data packets. + * @param[in] netdev Pointer to the associated network device. + * + * @return + * Status of the Tx operation. + */ +extern void nss_rmnet_rx_register(struct nss_rmnet_rx_handle *handle, + nss_rmnet_rx_data_callback_t data_callback, + struct net_device *netdev); + +/** + * nss_rmnet_rx_get_ifnum_with_coreid + * Returns the interface number with the core ID. + * + * @param[in] if_num NSS interface number + * + * @return + * Interface number with the core ID. + */ +extern int32_t nss_rmnet_rx_get_ifnum_with_core_id(int32_t if_num); + +/** + * nss_rmnet_rx_get_ifnum + * Returns the interface number with appending core ID. + * + * @param[in] dev Net device + * + * @return + * Interface number with the core ID. + */ +extern int32_t nss_rmnet_rx_get_ifnum(struct net_device *dev); + +/** + * nss_rmnet_rx_get_interface_num + * Returns the virtual interface number associated with the handle. + * + * @datatypes + * nss_rmnet_rx_handle + * + * @param[in] handle Pointer to the virtual interface handle (provided during + dynamic interface allocation). + * + * @return + * Virtual interface number. + */ +extern int32_t nss_rmnet_rx_get_interface_num(struct nss_rmnet_rx_handle *handle); + +/** + * nss_rmnet_rx_get_context + * Gets the virtual interface context. + * + * @return + * Pointer to the NSS core context. + */ +struct nss_ctx_instance *nss_rmnet_rx_get_context(void); + +/** + * @} + */ + +#endif /* __NSS_RMNET_RX_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_rps.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_rps.h new file mode 100644 index 000000000..213604ea3 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_rps.h @@ -0,0 +1,55 @@ +/* + ************************************************************************** + * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_rps.h + * RPS related definitions. + */ + +#ifndef __NSS_RPS_H +#define __NSS_RPS_H + +/** + * @addtogroup nss_rps_subsystem + * @{ + */ + +/** + * nss_rps_register_sysctl + * Registers the RPS sysctl entries to the sysctl tree. + * + * @return + * None. + */ +extern void nss_rps_register_sysctl(void); + +/** + * nss_rps_unregister_sysctl + * Deregisters the RPS sysctl entries from the sysctl tree. + * + * @return + * None. + * + * @dependencies + * The system control must have been previously registered. + */ +extern void nss_rps_unregister_sysctl(void); + +/** + * @} + */ + +#endif /* __NSS_RPS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_shaper.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_shaper.h new file mode 100644 index 000000000..fbb0415ae --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_shaper.h @@ -0,0 +1,901 @@ +/* + ************************************************************************** + * Copyright (c) 2014, 2017-2018 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_shaper.h + * NSS Shaper definitions + */ + +#ifndef __NSS_SHAPER_H +#define __NSS_SHAPER_H + +/** + * @addtogroup nss_shaper_subsystem + * @{ + */ + +/** + * nss_shaper_node_types + * Types of shaper nodes that are exported to the HLOS. + */ +enum nss_shaper_node_types { + NSS_SHAPER_NODE_TYPE_CODEL = 1, + NSS_SHAPER_NODE_TYPE_PRIO = 3, + NSS_SHAPER_NODE_TYPE_FIFO = 4, + NSS_SHAPER_NODE_TYPE_TBL = 5, + NSS_SHAPER_NODE_TYPE_BF = 6, + NSS_SHAPER_NODE_TYPE_BF_GROUP = 7, + NSS_SHAPER_NODE_TYPE_WRR = 9, + NSS_SHAPER_NODE_TYPE_WRR_GROUP = 10, + NSS_SHAPER_NODE_TYPE_HTB = 11, + NSS_SHAPER_NODE_TYPE_HTB_GROUP = 12, + NSS_SHAPER_NODE_TYPE_WRED = 13, + NSS_SHAPER_NODE_TYPE_PPE_SN = 14, + NSS_SHAPER_NODE_TYPE_MAX, +}; + +typedef enum nss_shaper_node_types nss_shaper_node_type_t; + /**< Types of shaper nodes that are exported to the HLOS. */ + +/** + * nss_shaper_config_types + * Types of shaper configuration messages. + */ +enum nss_shaper_config_types { + NSS_SHAPER_CONFIG_TYPE_ALLOC_SHAPER_NODE, + NSS_SHAPER_CONFIG_TYPE_FREE_SHAPER_NODE, + NSS_SHAPER_CONFIG_TYPE_SET_DEFAULT, + NSS_SHAPER_CONFIG_TYPE_SET_ROOT, + NSS_SHAPER_CONFIG_TYPE_SHAPER_NODE_BASIC_STATS_GET, + NSS_SHAPER_CONFIG_TYPE_SHAPER_NODE_ATTACH, + NSS_SHAPER_CONFIG_TYPE_SHAPER_NODE_DETACH, + NSS_SHAPER_CONFIG_TYPE_SHAPER_NODE_CHANGE_PARAM, + NSS_SHAPER_CONFIG_TYPE_HYBRID_MODE_ENABLE, + NSS_SHAPER_CONFIG_TYPE_HYBRID_MODE_DISABLE, + NSS_SHAPER_CONFIG_TYPE_SHAPER_NODE_MEM_REQ, +}; + +typedef enum nss_shaper_config_types nss_shaper_config_type_t; + /**< Types of shaper configuration messages. */ + +/** + * nss_shaper_response_types + * Types of shaper configuration responses. + */ +enum nss_shaper_response_types { + NSS_SHAPER_RESPONSE_TYPE_SUCCESS, + NSS_SHAPER_RESPONSE_TYPE_NO_SHAPER_NODE, + NSS_SHAPER_RESPONSE_TYPE_NO_SHAPER_NODES, + NSS_SHAPER_RESPONSE_TYPE_OLD, + NSS_SHAPER_RESPONSE_TYPE_UNRECOGNISED, + NSS_SHAPER_RESPONSE_TYPE_BAD_DEFAULT_CHOICE, + NSS_SHAPER_RESPONSE_TYPE_DUPLICATE_QOS_TAG, + NSS_SHAPER_RESPONSE_TYPE_TBL_CIR_RATE_AND_BURST_REQUIRED, + NSS_SHAPER_RESPONSE_TYPE_TBL_CIR_BURST_LESS_THAN_MTU, + NSS_SHAPER_RESPONSE_TYPE_CODEL_ALL_PARAMS_REQUIRED, + NSS_SHAPER_RESPONSE_TYPE_BF_GROUP_RATE_AND_BURST_REQUIRED, + NSS_SHAPER_RESPONSE_TYPE_BF_GROUP_BURST_LESS_THAN_MTU, + NSS_SHAPER_RESPONSE_TYPE_CHILD_NOT_BF_GROUP, + NSS_SHAPER_RESPONSE_TYPE_WRR_GROUP_INVALID_QUANTUM, + NSS_SHAPER_RESPONSE_TYPE_CHILD_NOT_WRR_GROUP, + NSS_SHAPER_RESPONSE_TYPE_WRR_INVALID_OPERATION_MODE, + NSS_SHAPER_RESPONSE_TYPE_HTB_GROUP_BURST_LESS_THAN_MTU, + NSS_SHAPER_RESPONSE_TYPE_HTB_GROUP_PRIORITY_OUT_OF_RANGE, + NSS_SHAPER_RESPONSE_TYPE_CHILDREN_BELONG_TO_MIXED_TYPES, + NSS_SHAPER_RESPONSE_TYPE_CHILD_ALREADY_PRESENT, + NSS_SHAPER_RESPONSE_TYPE_CHILD_MISMATCH, + NSS_SHAPER_RESPONSE_TYPE_CHILD_UNSUPPORTED, + NSS_SHAPER_RESPONSE_TYPE_CHILD_NOT_FOUND, + NSS_SHAPER_RESPONSE_TYPE_ATTACH_FAIL, + NSS_SHAPER_RESPONSE_TYPE_WRED_WEIGHT_MODE_INVALID, + NSS_SHAPER_RESPONSE_TYPE_PPE_SN_UCAST_BASE_OFFSET_INVALID, + NSS_SHAPER_RESPONSE_TYPE_PPE_SN_MCAST_BASE_OFFSET_INVALID, + NSS_SHAPER_RESPONSE_TYPE_PPE_SN_UCAST_QUEUE_ALLOC_FAILED, + NSS_SHAPER_RESPONSE_TYPE_PPE_SN_MCAST_QUEUE_ALLOC_FAILED, + NSS_SHAPER_RESPONSE_TYPE_PPE_SN_INVALID_LIMIT, + NSS_SHAPER_RESPONSE_TYPE_PPE_SN_UCAST_QUEUE_CHANGED, + NSS_SHAPER_RESPONSE_TYPE_PPE_SN_MCAST_QUEUE_CHANGED, + NSS_SHAPER_RESPONSE_TYPE_CODEL_FQ_MEM_INSUFFICIENT, + NSS_SHAPER_RESPONSE_TYPE_CODEL_FQ_COUNT_CHANGE_NOT_ALLOWED, + NSS_SHAPER_RESPONSE_TYPE_CODEL_FQ_COUNT_INVALID, + NSS_SHAPER_RESPONSE_TYPE_CODEL_MODE_CHANGE_NOT_ALLOWED, +}; + +typedef enum nss_shaper_response_types nss_shaper_response_type_t; + /**< Types of shaper configuration responses. */ + +/** + * nss_shaper_config_alloc_shaper_node + * Message information for allocating a shaper node for a NSS interface. + */ +struct nss_shaper_config_alloc_shaper_node { + nss_shaper_node_type_t node_type; /**< Type of shaper node. */ + uint32_t qos_tag; /**< QoS tag of the node. */ +}; + +/** + * nss_shaper_config_free_shaper_node + * Message information for freeing a shaper node from a NSS interface. + */ +struct nss_shaper_config_free_shaper_node { + uint32_t qos_tag; /**< QoS tag of the node. */ +}; + +/** + * nss_shaper_config_set_root_node + * Message information for setting a shaper node as the root. + */ +struct nss_shaper_config_set_root_node { + uint32_t qos_tag; /**< QoS tag of the node. */ +}; + +/** + * nss_shaper_config_set_default_node + * Message information for setting a shaper node as the default node for enqueueing. + */ +struct nss_shaper_config_set_default_node { + uint32_t qos_tag; /**< QoS tag of the node. */ +}; + +/** + * nss_shaper_config_set_hybrid_mode + * Message information for setting a shaper to operate in hybrid mode. + */ +struct nss_shaper_config_set_hybrid_mode { + uint32_t offset; /**< Queue offset for packets sent to the hardware. */ +}; + +/** + * nss_shaper_config_prio_attach + * Message information for attaching a shaper node to a PRIO shaper node. + */ +struct nss_shaper_config_prio_attach { + uint32_t child_qos_tag; /**< QoS tag of the child shaper node. */ + uint32_t priority; /**< Priority of the child shaper node. */ +}; + +/** + * nss_shaper_config_prio_detach + * Message information for detaching a shaper node from a PRIO shaper node. + */ +struct nss_shaper_config_prio_detach { + uint32_t priority; /**< Priority of the child shaper node. */ +}; + +/** + * nss_shaper_config_codel_alg_param + * Message information for configuring a CoDel algorithm. + */ +struct nss_shaper_config_codel_alg_param { + uint16_t interval; /**< Buffer time to smooth a state transition. */ + uint16_t target; /**< Acceptable delay associated with a queue. */ + uint16_t mtu; /**< MTU for the associated interface. */ + uint16_t reserved; /**< Alignment padding. */ +}; + +/** + * nss_shaper_config_codel_param + * Message information for configuring a CoDel shaper node. + */ +struct nss_shaper_config_codel_param { + int32_t qlen_max; /**< Maximum number of packets that can be enqueued. */ + struct nss_shaper_config_codel_alg_param cap; + /**< Configuration for the CoDel algorithm. */ + uint32_t flows; /**< Number of flow hash buckets. */ + uint32_t flows_mem; /**< Host allocated memory for flow queues. */ + uint32_t flows_mem_sz; /**< Memory size allocated for flow queues. */ + uint32_t quantum; /**< Quantum (in bytes) to round-robin the flow buckets. */ + uint32_t ecn; /**< 0 - ECN disabled, 1 - ECN enabled. */ +}; + +/** + * nss_shaper_config_codel_mem_req + * Message to get CoDel memory requirement per flow queue (needed for fq_codel). + */ +struct nss_shaper_config_codel_mem_req { + uint32_t mem_req; /**< Memory needed per flow queue (in bytes). */ +}; + +/** + * nss_shaper_config_rate_param + * Message information for configuring the rate limiter algorithm. + */ +struct nss_shaper_config_rate_param { + uint32_t rate; + /**< Allowed traffic rate measured in bytes per second. */ + uint32_t burst; + /**< Maximum bytes that can be sent in a burst. */ + uint32_t max_size; + /**< Maximum size of the supported packets (in bytes). */ + + /** + * Specifies whether the rate limiter will be bypassed (short circuited). + */ + bool short_circuit; +}; + +/** + * nss_shaper_configure_tbl_attach + * Message information for attaching a shaper node to a TBL shaper node. + */ +struct nss_shaper_config_tbl_attach { + uint32_t child_qos_tag; /**< QoS tag of the child shaper node. */ +}; + +/** + * nss_shaper_configure_tbl_param + * Message information for detaching a shaper node from a TBL shaper node. + */ +struct nss_shaper_config_tbl_param { + struct nss_shaper_config_rate_param lap_cir; + /**< Configuration parameters for the committed information rate. */ + struct nss_shaper_config_rate_param lap_pir; + /**< Configuration parameters for the peak information rate. */ +}; + +/** + * nss_shaper_config_bf_attach + * Message information for attaching a shaper node to a BF shaper node. + */ +struct nss_shaper_config_bf_attach { + uint32_t child_qos_tag; /**< QoS tag of the child shaper node. */ +}; + +/** + * nss_shaper_config_bf_detach + * Message information for detaching a shaper node from a BF shaper node. + */ +struct nss_shaper_config_bf_detach { + uint32_t child_qos_tag; /**< QoS tag of the child shaper node. */ +}; + +/** + * nss_shaper_config_bf_group_attach + * Message information for attaching a shaper node to a BF group shaper node. + */ +struct nss_shaper_config_bf_group_attach { + uint32_t child_qos_tag; /**< QoS tag of the child shaper node. */ +}; + +/** + * nss_shaper_config_bf_group_param + * Configuration parameters for a BF group shaper node. + */ +struct nss_shaper_config_bf_group_param { + uint32_t quantum; + /**< Smallest increment value for the DRRs. */ + struct nss_shaper_config_rate_param lap; + /**< Configuration of the rate control algorithm. */ +}; + +/** + * nss_shaper_config_fifo_limit_set + * Drop modes for the FIFO shaper in the NSS interface. + */ +enum nss_shaper_config_fifo_drop_modes { + NSS_SHAPER_FIFO_DROP_MODE_HEAD = 0, + NSS_SHAPER_FIFO_DROP_MODE_TAIL, + NSS_SHAPER_FIFO_DROP_MODES, +}; + +typedef enum nss_shaper_config_fifo_drop_modes nss_shaper_config_fifo_drop_mode_t; + /**< Drop modes for the FIFO shaper in the NSS interface. */ + +/** + * nss_shaper_config_fifo_param + * Message information for configuring a FIFO shaper node. + */ +struct nss_shaper_config_fifo_param { + uint32_t limit; /**< Queue limit in packets. */ + nss_shaper_config_fifo_drop_mode_t drop_mode; + /**< FIFO drop mode when a queue is full. */ +}; + +/** + * nss_shaper_config_wred_weight_modes + * Supported weight modes. + */ +enum nss_shaper_config_wred_weight_modes { + NSS_SHAPER_WRED_WEIGHT_MODE_DSCP = 0, + NSS_SHAPER_WRED_WEIGHT_MODES, +}; + +typedef enum nss_shaper_config_wred_weight_modes nss_shaper_config_wred_weight_mode_t; + /**< Supported weight modes. */ + +/** + * nss_shaper_red_alg_param + * Message information for configuring the RED algorithm. + */ +struct nss_shaper_red_alg_param { + uint32_t min; /**< Minimum size of the queue. */ + uint32_t max; /**< Maximum size of the queue. */ + + /** + * Probability of dropped packets when the average queue size (qlen_avg) = max. + */ + uint32_t probability; + + /** + * Exponential weight factor to calculate the average queue size. + */ + uint32_t exp_weight_factor; +}; + +/** + * nss_shaper_config_wred_param + * Message information for configuring the WRED algorithm. + */ +struct nss_shaper_config_wred_param { + uint32_t limit; /**< Queue limit in bytes. */ + nss_shaper_config_wred_weight_mode_t weight_mode; + /**< WRED weight mode. */ + uint32_t traffic_classes; /**< Number of traffic classes (drop probability). */ + uint32_t def_traffic_class; /**< Default traffic class used when there is no match. */ + uint32_t traffic_id; /**< Traffic class to configure. */ + uint32_t weight_mode_value; /**< Value to match the selected header field against. */ + struct nss_shaper_red_alg_param rap; + /**< Configuration parameters for the RED algorithm. */ + uint8_t ecn; /**< Mark an ECN bit or drop packet. */ +}; + +/** + * nss_shaper_config_wrr_attach + * Message information for attaching a shaper node to a WRR shaper node. + */ +struct nss_shaper_config_wrr_attach { + uint32_t child_qos_tag; /**< QoS tag of the child shaper node. */ +}; + +/** + * nss_shaper_config_wrr_detach + * Message information for detaching a child node from a WRR shaper node. + */ +struct nss_shaper_config_wrr_detach { + uint32_t child_qos_tag; /**< QoS tag of the child shaper node. */ +}; + +/** + * nss_shaper_config_wrr_group_attach + * Message information for attaching a shaper node to a WRR group. + */ +struct nss_shaper_config_wrr_group_attach { + uint32_t child_qos_tag; /**< QoS tag of the child shaper node. */ +}; + +/** + * nss_shaper_wrr_operation_modes + * Modes of WRR operation. + */ +enum nss_shaper_wrr_operation_modes { + NSS_SHAPER_WRR_MODE_ROUND_ROBIN = 0, + NSS_SHAPER_WRR_MODE_FAIR_QUEUEING = 1, + NSS_SHAPER_WRR_MODE_TYPE_MAX, +}; + +/** + * nss_shaper_config_wrr_param + * Message information for configuring the operation mode of a WRR shaper node. + */ +struct nss_shaper_config_wrr_param { + uint32_t operation_mode; /**< Mode in which to operate. */ +}; + +/** + * nss_shaper_config_wrr_group_param + * Message information for configuring a quantum value of a WRR group shaper node. + */ +struct nss_shaper_config_wrr_group_param { + uint32_t quantum; /**< Smallest increment value for the DRRs. */ +}; + +/** + * nss_shaper_config_htb_attach + * Message information for attaching a shaper node to an HTB shaper node. + */ +struct nss_shaper_config_htb_attach { + uint32_t child_qos_tag; /**< QoS tag of the child shaper node. */ +}; + +/** + * nss_shaper_config_htb_group_attach + * Message information for attaching a shaper node to an HTB group. + */ +struct nss_shaper_config_htb_group_attach { + uint32_t child_qos_tag; /**< QoS tag of the child shaper node. */ +}; + +/** + * nss_shaper_config_htb_group_detach + * Message information for detaching a shaper node from an HTB group. + */ +struct nss_shaper_config_htb_group_detach { + uint32_t child_qos_tag; /**< QoS tag of the child shaper node. */ +}; + +/** + * nss_shaper_config_htb_group_param + * Message information for configuring an HTB group shaper node. + */ +struct nss_shaper_config_htb_group_param { + uint32_t quantum; /**< Smallest increment value for the DRRs. */ + uint32_t priority; /**< Value of the priority for this group. */ + uint32_t overhead; /**< Overhead in bytes to be added per packet. */ + struct nss_shaper_config_rate_param rate_police; + /**< Configuration parameters for the policing rate. */ + struct nss_shaper_config_rate_param rate_ceil; + /**< Configuration parameters for the ceiling rate. */ +}; + +/** + * nss_shaper_config_ppe_sn_attach + * Message information for attaching a shaper node to a PPE shaper node. + */ +struct nss_shaper_config_ppe_sn_attach { + uint32_t child_qos_tag; /**< QoS tag of the child shaper node. */ +}; + +/** + * nss_shaper_config_ppe_sn_detach + * Message information for detaching a shaper node from a PPE shaper node. + */ +struct nss_shaper_config_ppe_sn_detach { + uint32_t child_qos_tag; /**< QoS tag of the child shaper node. */ +}; + +/** + * nss_shaper_config_ppe_sn_type + * Types of PPE shaper nodes. + */ +enum nss_shaper_config_ppe_sn_type { + /* + * Scheduler types. + */ + NSS_SHAPER_CONFIG_PPE_SN_TYPE_HTB, + NSS_SHAPER_CONFIG_PPE_SN_TYPE_HTB_GROUP, + NSS_SHAPER_CONFIG_PPE_SN_TYPE_TBL, + NSS_SHAPER_CONFIG_PPE_SN_TYPE_WRR, + NSS_SHAPER_CONFIG_PPE_SN_TYPE_WRR_GROUP, + NSS_SHAPER_CONFIG_PPE_SN_TYPE_PRIO, + NSS_SHAPER_CONFIG_PPE_SN_SCH_MAX = 0xFF, + + /* + * Queue types. + */ + NSS_SHAPER_CONFIG_PPE_SN_TYPE_FIFO, + NSS_SHAPER_CONFIG_PPE_SN_TYPE_RED, + NSS_SHAPER_CONFIG_PPE_SN_TYPE_MAX, +}; + +/** + * nss_shaper_config_ppe_sn_param + * Message information for configuring a PPE shaper node. + */ +struct nss_shaper_config_ppe_sn_param { + enum nss_shaper_config_ppe_sn_type type; + /**< Type of PPE shaper node. */ + uint16_t ucast_base; /**< Resource ID of the base hardware for unicast queue. */ + uint16_t ucast_offset; /**< Offset from the base resource ID for unicast queue. */ + uint16_t mcast_base; /**< Resource ID of the base hardware for multicast queue. */ + uint16_t mcast_offset; /**< Offset from the base resource ID for multicast queue. */ + uint8_t port; /**< PPE port on which this shaper node is configured. */ + uint8_t reserved; /**< Reserved for padding. */ + uint16_t limit; /**< Limit of the queue. */ +}; + +/* + * nss_shaper_node_config + * Configuration messages for all types of shaper nodes. + */ +struct nss_shaper_node_config { + uint32_t qos_tag; /**< ID of the shaper node to be configured. */ + + /** + * Configuration messages for all types of shaper nodes. + */ + union { + struct nss_shaper_config_prio_attach prio_attach; + /**< Attach a shaper node to a PRIO shaper node. */ + struct nss_shaper_config_prio_detach prio_detach; + /**< Detach a shaper node from a PRIO shaper node. */ + + struct nss_shaper_config_codel_param codel_param; + /**< Configure a CoDel shaper node. */ + + struct nss_shaper_config_codel_mem_req codel_mem_req; + /**< Get CoDel memory requirement. */ + + struct nss_shaper_config_tbl_attach tbl_attach; + /**< Attach a shaper node to a TBL shaper node. */ + struct nss_shaper_config_tbl_param tbl_param; + /**< Configuration parameters for a TBL shaper node. */ + + struct nss_shaper_config_bf_attach bf_attach; + /**< Attach a shaper node to a BF shaper node. */ + struct nss_shaper_config_bf_detach bf_detach; + /**< Detach a child shaper node from BF shaper node. */ + struct nss_shaper_config_bf_group_attach bf_group_attach; + /**< Attach a shaper node to a BF group shaper node. */ + struct nss_shaper_config_bf_group_param bf_group_param; + /**< Configure parameters for a BF group shaper node. */ + + struct nss_shaper_config_fifo_param fifo_param; + /**< Configure a FIFO shaper node. */ + + struct nss_shaper_config_wrr_attach wrr_attach; + /**< Attach a shaper node to a WRR shaper node. */ + struct nss_shaper_config_wrr_detach wrr_detach; + /**< Detach a shaper node from a WRR shaper node. */ + struct nss_shaper_config_wrr_param wrr_param; + /**< Configuration parameters for a WRR shaper node . */ + struct nss_shaper_config_wrr_group_attach wrr_group_attach; + /**< Attach a shaper node to a WRR group shaper node. */ + struct nss_shaper_config_wrr_group_param wrr_group_param; + /**< Configure a WRR group shaper node with a quantum value. */ + struct nss_shaper_config_htb_attach htb_attach; + /**< Attach a shaper node to an HTB shaper node. */ + struct nss_shaper_config_htb_group_attach htb_group_attach; + /**< Attach a shaper node to an HTB group shaper node. */ + struct nss_shaper_config_htb_group_detach htb_group_detach; + /**< Detach a shaper node from an HTB group shaper node. */ + struct nss_shaper_config_htb_group_param htb_group_param; + /**< Configuration parameters for an HTB group shaper node. */ + struct nss_shaper_config_wred_param wred_param; + /**< Configuration parameters for a WRED shaper node. */ + struct nss_shaper_config_ppe_sn_attach ppe_sn_attach; + /**< Attach a shaper node to a PPE shaper node. */ + struct nss_shaper_config_ppe_sn_detach ppe_sn_detach; + /**< Detach a shaper node from a PPE shaper node. */ + struct nss_shaper_config_ppe_sn_param ppe_sn_param; + /**< Configuration parameters for a PPE shaper node. */ + } snc; /**< Types of shaper node configuration messages. */ +}; + +/** + * nss_shaper_node_codel_fq_stats_delta + * CoDel flow queue mode statistics sent as deltas. + */ +struct nss_shaper_node_codel_fq_stats_delta { + uint32_t new_flow_cnt; /**< Total number of new flows seen. */ + uint32_t ecn_mark_cnt; /**< Number of packets marked with ECN. */ +}; + +/** + * nss_shaper_node_codel_fq_stats + * CoDel flow queue mode statistics. + */ +struct nss_shaper_node_codel_fq_stats { + struct nss_shaper_node_codel_fq_stats_delta delta; + /**< CoDel flow queue statistics sent as deltas. */ + uint32_t new_flows_len; /**< Current number of new flows. */ + uint32_t old_flows_len; /**< Current number of old flows. */ + uint32_t maxpacket; /**< Largest packet seen so far. */ +}; + +/** + * nss_shaper_node_codel_sq_stats + * CoDel single queue mode statistics. + */ +struct nss_shaper_node_codel_sq_stats { + /** + * Maximum amount of time (in milliseconds) that a packet was in this shaper + * node before being dequeued. + */ + uint32_t packet_latency_peak_msec_dequeued; + + /** + * Maximum amount of time (in milliseconds) that a packet was in this shaper + * node before being dropped. + */ + uint32_t packet_latency_peak_msec_dropped; +}; + +/** + * nss_shaper_node_codel_stats + * CoDel shaper node statistics. + */ +struct nss_shaper_node_codel_stats { + struct nss_shaper_node_codel_sq_stats sq; /**< Single queue mode statistics. */ + struct nss_shaper_node_codel_fq_stats fq; /**< Flow queue mode statistics. */ +}; + +/** + * nss_shaper_node_stats_delta + * Statistics that are sent as deltas. + */ +struct nss_shaper_node_stats_delta { + uint32_t enqueued_bytes; /**< Bytes enqueued successfully. */ + uint32_t enqueued_packets; /**< Packets enqueued successfully. */ + + /** + * Bytes dropped during an enqueue operation because of node limits. + */ + uint32_t enqueued_bytes_dropped; + + /** + * Packets dropped during an enqueue operation because of node limits. + */ + uint32_t enqueued_packets_dropped; + + uint32_t dequeued_bytes; + /**< Bytes dequeued successfully from a shaper node. */ + uint32_t dequeued_packets; + /**< Packets dequeued successfully from a shaper node. */ + + /** + * Bytes dropped by this node during dequeuing (some nodes drop packets during + * dequeuing rather than enqueuing). + */ + uint32_t dequeued_bytes_dropped; + + /** + * Packets dropped by this node during dequeuing (some nodes drop packets during + * dequeuing rather than enqueuing). + */ + uint32_t dequeued_packets_dropped; + + /** + * Number of times any queue limit was overrun, leading to packet drops. + */ + uint32_t queue_overrun; + + uint32_t unused[4]; /**< Reserved for future statistics expansion. */ +}; + +/** + * nss_shaper_node_stats + * Common shaper node statistics. + */ +struct nss_shaper_node_stats { + uint32_t qlen_bytes; /**< Total size of packets waiting in the queue. */ + uint32_t qlen_packets; /**< Number of packets waiting in the queue. */ + uint32_t unused[4]; /**< Reserved for future statistics expansion. */ + struct nss_shaper_node_stats_delta delta; + /**< Statistics that are sent as deltas. */ +}; + +/** + * nss_shaper_node_stats_response + * Statistics response for shaper nodes. + */ +struct nss_shaper_node_stats_response { + struct nss_shaper_node_stats sn_stats; /**< Common shaper node statistics. */ + + /** + * All shaper nodes that need to maintain unique statistics need + * to add their statistics structure here. + */ + union { + struct nss_shaper_node_codel_stats codel; + /**< CoDel specific statistics. */ + } per_sn_stats; /**< Shaper specific statistics. */ +}; + +/** + * nss_shaper_node_stats_get + * Statistics of a shaper node. + */ +struct nss_shaper_node_stats_get { + + /* + * Request + */ + uint32_t qos_tag; /**< QoS tag of the shaper node. */ + + /* + * Response + */ + struct nss_shaper_node_stats_response response; + /**< Shaper node statistics response */ +}; + +/** + * nss_shaper_configure + * Configuration message for a shaper node. + */ +struct nss_shaper_configure { + nss_shaper_config_type_t request_type; /**< Message is a request. */ + nss_shaper_response_type_t response_type; /**< Message is a response. */ + + /** + * Types of configuration messages for a shaper node. + */ + union { + struct nss_shaper_config_alloc_shaper_node alloc_shaper_node; + /**< Allocate a shaper node in the NSS interface. */ + struct nss_shaper_config_free_shaper_node free_shaper_node; + /**< Free a shaper node from the NSS interface. */ + struct nss_shaper_config_set_default_node set_default_node; + /**< Set a shaper node as the default node for a queue. */ + struct nss_shaper_config_set_root_node set_root_node; + /**< Set a shaper node as the root shaper nod. */ + struct nss_shaper_config_set_hybrid_mode set_hybrid_mode; + /**< Set a shaper to operate in Hybrid mode. */ + struct nss_shaper_node_config shaper_node_config; + /**< Configuration message for any type of shaper node. */ + struct nss_shaper_node_stats_get shaper_node_stats_get; + /**< Statistics for a shaper node. */ + } msg; /**< Types of configuration messages. */ +}; + +/** + * Registrant callback to receive shaper bounced packets + * + * @datatypes + * sk_buff + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] skb Pointer to the data socket buffer. + */ +typedef void (*nss_shaper_bounced_callback_t)(void *app_data, struct sk_buff *skb); + +/** + * nss_shaper_register_shaping + * Registers a shaper node with the NSS interface for basic shaping operations. + * + * @return + * Pointer to the NSS core context. + */ +extern void *nss_shaper_register_shaping(void); + +/** + * nss_shaper_unregister_shaping + * Deregisters a shaper node from the NSS interface. + * + * @param[in] ctx Pointer to the NSS context. + * + * @dependencies + * The shaper node must have been previously registered. + */ +extern void nss_shaper_unregister_shaping(void *ctx); + +/** + * nss_shaper_register_shaper_bounce_interface + * Registers a shaper bounce interface with the NSS interface for receiving + * shaper-bounced packets. + * + * @datatypes + * nss_shaper_bounced_callback_t \n + * module + * + * @param[in] if_num NSS interface number. + * @param[in] cb Callback function for the message. This callback is + * invoked when the NSS returns a sk_buff after shaping. + * @param[in] app_data Pointer to the application context of the message. + * This context is passed to the callback together with the + * sk_buff to provide context to the registrant (state). + * @param[in] owner Pointer to the kernel module. The module is held until it deregisters. + * + * @return + * Pointer to the NSS core context. + */ +extern void *nss_shaper_register_shaper_bounce_interface(uint32_t if_num, nss_shaper_bounced_callback_t cb, void *app_data, struct module *owner); + +/** + * nss_shaper_unregister_shaper_bounce_interface + * Deregisters a shaper bounce interface from the NSS interface. + * + * @param[in] if_num NSS interface number. + * + * @return + * None. + * + * @dependencies + * The shaper bounce interface must have been previously registered. + */ +extern void nss_shaper_unregister_shaper_bounce_interface(uint32_t if_num); + +/** + * nss_shaper_register_shaper_bounce_bridge + * Registers a shaper bounce bridge with the NSS interface for receiving + * shaper-bounced packets. + * + * @datatypes + * nss_shaper_bounced_callback_t \n + * module + * + * @param[in] if_num NSS interface number. + * @param[in] cb Callback function for the message. This callback is + * invoked when the NSS returns a sk_buff after shaping. + * @param[in] app_data Pointer to the application context of the message. + * This context is passed to the callback together with the + * sk_buff to provide context to the registrant (state). + * @param[in] owner Pointer to the kernel module. + * + * @return + * Pointer to the NSS core context. + */ +extern void *nss_shaper_register_shaper_bounce_bridge(uint32_t if_num, nss_shaper_bounced_callback_t cb, void *app_data, struct module *owner); + +/** + * nss_shaper_unregister_shaper_bounce_bridge + * Deregisters a shaper bounce bridge from the NSS interface. + * + * @param[in] if_num NSS interface number. + * + * @return + * None. + * + * @dependencies + * The shaper bounce bridge must have been previously registered. + */ +extern void nss_shaper_unregister_shaper_bounce_bridge(uint32_t if_num); + +/** + * nss_shaper_bounce_interface_packet + * Issues a packet for shaping via a bounce operation. + * + * @datatypes + * sk_buff + * + * @param[in] ctx Pointer to the NSS context provided during registration. + * @param[in] if_num NSS interface number. + * @param[in] skb Pointer to the data socket buffer. + * + * @return + * Success or failure. + */ +extern nss_tx_status_t nss_shaper_bounce_interface_packet(void *ctx, uint32_t if_num, struct sk_buff *skb); + +/** + * nss_shaper_bounce_bridge_packet + * Issues a packet for shaping via a bounce bridge. + * + * @datatypes + * sk_buff + * + * @param[in] ctx Pointer to the NSS context provided during registration. + * @param[in] if_num NSS interface number. + * @param[in] skb Pointer to the data socket buffer. + * + * @return + * Success or failure. + */ +extern nss_tx_status_t nss_shaper_bounce_bridge_packet(void *ctx, uint32_t if_num, struct sk_buff *skb); + +/** + * nss_shaper_config_send + * Sends a shaping configuration message. + * + * @datatypes + * nss_shaper_configure + * + * @param[in] ctx Pointer to the NSS context. + * @param[in] config Pointer to the configuration message. + * + * @return + * Indication if the configuration message was issued. + * @par + * This indication does not mean the configuration message was successfully + * processed. Success or failure is provided in the response issued to the + * given callback function as specified in nss_shaper_configure. + */ +nss_tx_status_t nss_shaper_config_send(void *ctx, struct nss_shaper_configure *config); + +/** + * nss_shaper_get_device + * Gets the original device from probe. + * + * @return + * Pointer to the device. + */ +extern struct device *nss_shaper_get_dev(void); + +/** + * @} + */ + +#endif diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_sjack.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_sjack.h new file mode 100644 index 000000000..32ef356b0 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_sjack.h @@ -0,0 +1,154 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2015, 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_sjack.h + * NSS SJACK interface definitions. + */ + +#ifndef __NSS_SJACK_H +#define __NSS_SJACK_H + +/** + * @addtogroup nss_sjack_subsystem + * @{ + */ + +/** + * nss_sjack_msg_types + * Message types for SJACK requests and responses. + */ +enum nss_sjack_msg_types { + NSS_SJACK_CONFIGURE_MSG, + NSS_SJACK_UNCONFIGURE_MSG, + NSS_SJACK_STATS_SYNC_MSG, + NSS_SJACK_MAX_MSG_TYPE +}; + +/** + * nss_sjack_configure_msg + * Message information for configuring the SJACK interface. + */ +struct nss_sjack_configure_msg { + uint32_t ingress_if_num; + /**< Ingress interface number corresponding to the SJACK device. */ + uint32_t egress_if_num; + /**< Egress interface number corresponding to the SJACK device. */ + uint16_t tunnel_id; /**< SJACK tunnel ID. */ + uint8_t ip_dscp; /**< Differentiated services code point value. */ + uint8_t gre_prio; /**< GRE priority information. */ + uint8_t gre_flags; /**< GRE flags. */ + uint8_t use_ipsec_sa_pattern; /**< IPsec security association pattern flag. */ +}; + +/** + * nss_sjack_unconfigure_msg + * Message information for de-configuring the SJACK interface. + */ +struct nss_sjack_unconfigure_msg { + uint32_t ingress_if_num; + /**< Ingress interface number corresponding to the SJACK device. */ +}; + +/** + * nss_sjack_stats_sync_msg + * Message information for SJACK synchronization statistics. + */ +struct nss_sjack_stats_sync_msg { + struct nss_cmn_node_stats node_stats; /**< Common node statistics. */ +}; + +/** + * nss_sjack_msg + * Data for sending and receiving SJACK messages. + */ +struct nss_sjack_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of an SJACK message. + */ + union { + struct nss_sjack_configure_msg configure; + /**< Configure SJACK. */ + struct nss_sjack_unconfigure_msg unconfigure; + /**< De-configure SJACK. */ + struct nss_sjack_stats_sync_msg stats_sync; + /**< Synchronized statistics for SJACK. */ + } msg; /**< Message payload for SJACK interface messages exchanged with NSS core. */ +}; + +/** + * Callback function for receiving SJACK messages. + * + * @datatypes + * nss_cmn_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_sjack_msg_callback_t)(void *app_data, struct nss_cmn_msg *msg); + +/** + * nss_sjack_register_if + * Registers with the NSS for sending and receiving SJACK messages. + * + * @datatypes + * net_device \n + * nss_sjack_msg_callback_t + * + * @param[in] dev Pointer to the associated network device. + * @param[in] if_num NSS interface number. + * @param[in] event_callback Callback for the message. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_sjack_register_if(uint32_t if_num, struct net_device *dev, nss_sjack_msg_callback_t event_callback); + +/** + * nss_sjack_unregister_if + * Deregisters the SJACK interface from the NSS. + * + * @param[in] if_num NSS interface number. + * + * @return + * None. + * + * @dependencies + * The interface must have been previously registered. + */ +extern void nss_sjack_unregister_if(uint32_t if_num); + +/** + * nss_sjack_tx_msg + * Send SJACK messages to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_sjack_msg + * + * @param[in,out] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_sjack_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_sjack_msg *msg); + +/** @} */ /* end_addtogroup nss_sjack_subsystem */ + +#endif /* __NSS_SJACK_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_stats_public.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_stats_public.h new file mode 100644 index 000000000..f282ffdf3 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_stats_public.h @@ -0,0 +1,131 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_stats_public.h + * NSS statistics Structure and APIs + */ + +#ifndef __NSS_STATS_PUBLIC_H +#define __NSS_STATS_PUBLIC_H + +/** + * @addtogroup nss_stats_public_subsystem + * @{ + */ + +/** + * Maximum string length. + * + * This should be equal to maximum string size of any statistics + * inclusive of statistics value. + */ +#define NSS_STATS_MAX_STR_LENGTH 96 + +/** + * nss_stats_node + * Node statistics. + */ +enum nss_stats_node { + NSS_STATS_NODE_RX_PKTS, /**< Accelerated node Rx packets. */ + NSS_STATS_NODE_RX_BYTES, /**< Accelerated node Rx bytes. */ + NSS_STATS_NODE_TX_PKTS, /**< Accelerated node Tx packets. */ + NSS_STATS_NODE_TX_BYTES, /**< Accelerated node Tx bytes. */ + NSS_STATS_NODE_RX_QUEUE_0_DROPPED, /**< Accelerated node Rx Queue 0 dropped. */ + NSS_STATS_NODE_RX_QUEUE_1_DROPPED, /**< Accelerated node Rx Queue 1 dropped. */ + NSS_STATS_NODE_RX_QUEUE_2_DROPPED, /**< Accelerated node Rx Queue 2 dropped. */ + NSS_STATS_NODE_RX_QUEUE_3_DROPPED, /**< Accelerated node Rx Queue 3 dropped. */ + NSS_STATS_NODE_MAX, /**< Maximum message type. */ +}; + +/* + * WARNING: There is a 1:1 mapping between values of enum nss_stats_drv and corresponding + * statistics string array in nss_drv_strings.c. + */ +/** + * nss_stats_drv + * HLOS driver statistics. + */ +enum nss_stats_drv { + NSS_STATS_DRV_NBUF_ALLOC_FAILS = 0, /**< Networking buffer allocation errors. */ + NSS_STATS_DRV_PAGED_BUF_ALLOC_FAILS, /**< Paged buffer allocation errors. */ + NSS_STATS_DRV_TX_QUEUE_FULL_0, /**< Tx queue full for Core 0. */ + NSS_STATS_DRV_TX_QUEUE_FULL_1, /**< Tx queue full for Core 1. */ + NSS_STATS_DRV_TX_EMPTY, /**< Host-to-network empty buffers. */ + NSS_STATS_DRV_PAGED_TX_EMPTY, /**< Host-to-network paged empty buffers. */ + NSS_STATS_DRV_TX_PACKET, /**< Host-to-network data packets. */ + NSS_STATS_DRV_TX_CMD_REQ, /**< Host-to-network control packets. */ + NSS_STATS_DRV_TX_CRYPTO_REQ, /**< Host-to-network crypto requests. */ + NSS_STATS_DRV_TX_BUFFER_REUSE, /**< Host-to-network reuse buffer count. */ + NSS_STATS_DRV_RX_EMPTY, /**< Network-to-host empty buffers. */ + NSS_STATS_DRV_RX_PACKET, /**< Network-to-host data packets. */ + NSS_STATS_DRV_RX_CMD_RESP, /**< Network-to-host command responses. */ + NSS_STATS_DRV_RX_STATUS, /**< Network-to-host status packets. */ + NSS_STATS_DRV_RX_CRYPTO_RESP, /**< Network-to-host crypto responses. */ + NSS_STATS_DRV_RX_VIRTUAL, /**< Network-to-host virtual packets. */ + NSS_STATS_DRV_TX_SIMPLE, /**< Host-to-network simple SKB packets. */ + NSS_STATS_DRV_TX_NR_FRAGS, /**< Host-to-network number of fragmented SKB packets. */ + NSS_STATS_DRV_TX_FRAGLIST, /**< Host-to-network fragmentation list of SKB packets. */ + NSS_STATS_DRV_RX_SIMPLE, /**< Network-to-host simple SKB packets. */ + NSS_STATS_DRV_RX_NR_FRAGS, /**< Network-to-host number of fragmented SKB packets. */ + NSS_STATS_DRV_RX_SKB_FRAGLIST, /**< Network-to-host fragmentation list of SKB packets. */ + NSS_STATS_DRV_RX_BAD_DESCRIPTOR, /**< Network-to-host bad descriptor reads. */ + NSS_STATS_DRV_NSS_SKB_COUNT, /**< NSS SKB pool count. */ + NSS_STATS_DRV_CHAIN_SEG_PROCESSED, /**< Network-to-host SKB chain processed count. */ + NSS_STATS_DRV_FRAG_SEG_PROCESSED, /**< Network-to-host fragments processed count. */ + NSS_STATS_DRV_TX_CMD_QUEUE_FULL, /**< Tx host-to-network control packets fail due to queue full. */ +#ifdef NSS_MULTI_H2N_DATA_RING_SUPPORT + NSS_STATS_DRV_TX_PACKET_QUEUE_0, /**< Host-to-network data packets on queue0. */ + NSS_STATS_DRV_TX_PACKET_QUEUE_1, /**< Host-to-network data packets on queue1. */ + NSS_STATS_DRV_TX_PACKET_QUEUE_2, /**< Host-to-network data packets on queue2. */ + NSS_STATS_DRV_TX_PACKET_QUEUE_3, /**< Host-to-network data packets on queue3. */ + NSS_STATS_DRV_TX_PACKET_QUEUE_4, /**< Host-to-network data packets on queue4. */ + NSS_STATS_DRV_TX_PACKET_QUEUE_5, /**< Host-to-network data packets on queue5. */ + NSS_STATS_DRV_TX_PACKET_QUEUE_6, /**< Host-to-network data packets on queue6. */ + NSS_STATS_DRV_TX_PACKET_QUEUE_7, /**< Host-to-network data packets on queue7. */ +#endif + NSS_STATS_DRV_MAX, /**< Maximum message type. */ +}; + +/** + * nss_stats_types + * List of statistics categories. + */ +enum nss_stats_types { + NSS_STATS_TYPE_COMMON, /**< Common pnode statistics. */ + NSS_STATS_TYPE_DROP, /**< Packet drop statistics. */ + NSS_STATS_TYPE_ERROR, /**< Hardware or software errors different from drop or exception statistics. */ + NSS_STATS_TYPE_EXCEPTION, /**< Packet exception (to host) statistics. */ + NSS_STATS_TYPE_SPECIAL, /**< Statistics that do not fall into the above types. */ + NSS_STATS_TYPE_MAX /**< Maximum message type. */ +}; + +/** + * nss_stats_notifier_action + * Statistics notification types. + */ +enum nss_stats_notifier_action { + NSS_STATS_EVENT_NOTIFY, + NSS_STATS_EVENT_MAX +}; + +/** + * @} + */ + +#endif /* __NSS_STATS_PUBLIC_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_tls.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_tls.h new file mode 100644 index 000000000..431d7b812 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_tls.h @@ -0,0 +1,384 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE + ************************************************************************** + */ + +/** + * @file nss_tls.h + * NSS TLS common interface definitions, supports inner/outer interface split. + */ + +#ifndef _NSS_TLS_H_ +#define _NSS_TLS_H_ + +/** + * @addtogroup nss_tls_subsystem + * @{ + */ +#define NSS_TLS_VER_TLS_1_1 0x0301 /**< TLS version 1.1, major and minor version. */ +#define NSS_TLS_VER_TLS_1_2 0x0302 /**< TLS version 1.2, major and minor version. */ +#define NSS_TLS_CLE_MAX 32 /**< Maximum classification error. */ + +/** + * tls_msg_types + * Message types for TLS requests and responses. + */ +enum nss_tls_msg_type { + NSS_TLS_MSG_TYPE_NODE_CONFIG, /**< Configure TLS firmware node. */ + NSS_TLS_MSG_TYPE_NODE_SYNC, /**< Node statistics. */ + NSS_TLS_MSG_TYPE_CTX_CONFIG, /**< Send exception interface number. */ + NSS_TLS_MSG_TYPE_CTX_DECONFIG, /**< Context deconfigure message. */ + NSS_TLS_MSG_TYPE_CTX_SYNC, /**< Synchronize statistics. */ + NSS_TLS_MSG_TYPE_CIPHER_UPDATE, /**< Context session update. */ + NSS_TLS_MSG_MAX, /**< Maximum message. */ +}; + +/** + * nss_tls_error + * TLS error. + */ +enum nss_tls_error { + NSS_TLS_ERROR_NONE = 0, /**< No error. */ + NSS_TLS_ERROR_UNKNOWN_MSG, /**< Unknown message. */ + NSS_TLS_ERROR_ALREADY_CONFIGURE, /**< Node already configured. */ + NSS_TLS_ERROR_FAIL_REG_INNER_CTX, /**< Register inner context error. */ + NSS_TLS_ERROR_FAIL_REG_OUTER_CTX, /**< Register outer context error. */ + NSS_TLS_ERROR_FAIL_REQ_POOL_ALLOC, /**< Request pool allocation failed. */ + NSS_TLS_ERROR_INVALID_BLK_LEN, /**< Invalid block length. */ + NSS_TLS_ERROR_INVALID_HASH_LEN, /**< Invalid hash length. */ + NSS_TLS_ERROR_INVALID_VER, /**< Invalid TLS version. */ + NSS_TLS_ERROR_INVALID_CTX_WORDS, /**< Context words size mismatch with TLS. */ + NSS_TLS_ERROR_FAIL_ALLOC_HWCTX, /**< Failed to allocate hardware context. */ + NSS_TLS_ERROR_FAIL_COPY_CTX, /**< Failed to copy context. */ + NSS_TLS_ERROR_FAIL_NOMEM, /**< Failed memory allocation. */ + NSS_TLS_ERROR_FAIL_INVAL_ALGO, /**< Invalid algorithm. */ + NSS_TLS_ERROR_MAX, /**< Maximum TLS error. */ +}; + +/** + * nss_tls_hw_stats + * TLS HW statistics. + */ +struct nss_tls_hw_stats { + /* + * Dont change the order below + */ + uint32_t hw_len_error; /**< Length error. */ + uint32_t hw_token_error; /**< Token error, unknown token command/instruction. */ + uint32_t hw_bypass_error; /**< Token contains too much bypass data. */ + uint32_t hw_crypto_error; /**< Cryptograhic block size error. */ + uint32_t hw_hash_error; /**< Hash block size error. */ + uint32_t hw_config_error; /**< Invalid command/algorithm/mode/combination. */ + uint32_t hw_algo_error; /**< Unsupported algorithm. */ + uint32_t hw_hash_ovf_error; /**< Hash input overflow. */ + uint32_t hw_auth_error; /**< Hash input overflow. */ + uint32_t hw_pad_verify_error; /**< Pad verification error. */ + uint32_t hw_timeout_error; /**< Data timed out. */ +}; + +/** + * nss_tls_ctx_perf_stats + * TLS performance statistics. + */ +struct nss_tls_ctx_perf_stats { + uint32_t no_desc_in; /**< Ingress DMA descriptor not available. */ + uint32_t no_desc_out; /**< Egress DMA descriptor not available. */ + uint32_t no_reqs; /**< Not enough requests available for records. */ +}; + +/** + * nss_tls_ctx_stats + * TLS session statistics. + */ +struct nss_tls_ctx_stats { + struct nss_cmn_node_stats pkt; /**< Common node statistics. */ + uint32_t single_rec; /**< Number of Tx single record datagrams. */ + uint32_t multi_rec; /**< Number of multiple Tx record datagrams. */ + uint32_t tx_inval_reqs; /**< Number of Tx invalidation successfully requested. */ + uint32_t rx_ccs_rec; /**< Number of change cipher spec records received. */ + uint32_t fail_ccs; /**< Failed to switch to new crypto. */ + uint32_t eth_node_deactive; /**< Ethernet node deactivated as no crypto available. */ + uint32_t crypto_alloc_success; /**< Number of crypto allocation succeeded. */ + uint32_t crypto_free_req; /**< Number of crypto free request. */ + uint32_t crypto_free_success; /**< Number of crypto free succeeded. */ + uint32_t fail_crypto_alloc; /**< Number of crypto allocation failed. */ + uint32_t fail_crypto_lookup; /**< Failed to find active crypto session. */ + uint32_t fail_req_alloc; /**< Failure to allocate request memory pool. */ + uint32_t fail_pbuf_stats; /**< Failure in pbuf allocation for statistics. */ + uint32_t fail_ctx_active; /**< Failure in enqueue due to inactive context. */ + + struct nss_tls_hw_stats fail_hw; /**< Hardware failure. */ + struct nss_tls_ctx_perf_stats perf; /**< Performance related statistics. */ +}; + +/** + * nss_tls_node_stats + * TLS node statistics. + */ +struct nss_tls_node_stats { + uint32_t fail_ctx_alloc; /**< Failure in allocating a context. */ + uint32_t fail_ctx_free; /**< Failure in freeing up the context. */ + uint32_t fail_pbuf_stats; /**< Failure in pbuf allocation for statistics. */ +}; + +/** + * nss_tls_ctx_config + * TLS context configuration. + */ +struct nss_tls_ctx_config { + uint32_t except_ifnum; /**< Exception interface number. */ + uint32_t headroom; /**< Headroom required for encapsulation. */ + uint32_t tailroom; /**< Tailroom required for encapsulation. */ +}; + +/** + * nss_tls_cipher_update + * TLS cipher update message. + * + */ +struct nss_tls_cipher_update { + uint32_t crypto_idx; /**< Crypto index for cipher context. */ + uint16_t ver; /**< Version (TLS minor and major versions). */ + uint8_t skip; /**< Skip hardware processing. */ + uint8_t reserved; /**< Reserved for future use. */ +}; + +/** + * nss_tls_msg + * Data for sending and receiving TLS messages. + */ +struct nss_tls_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a TLS message. + */ + union { + struct nss_tls_cipher_update cipher_update; /**< Crypto configuration. */ + struct nss_tls_ctx_config ctx_cfg; /**< Context configuration. */ + struct nss_tls_ctx_stats stats; /**< Context statistics. */ + struct nss_tls_node_stats node_stats; /**< Node statistics. */ + } msg; /**< Message payload for TLS session messages exchanged with NSS core. */ +}; + +/** + * Callback function for receiving TLS messages. + * + * @datatypes + * nss_cmn_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_tls_msg_callback_t)(void *app_data, struct nss_cmn_msg *msg); + +/** + * Callback function for receiving TLS session data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_tls_data_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * nss_tls_tx_buf + * Sends a TLS data packet to the NSS. + * + * @datatypes + * sk_buff \n + * nss_ctx_instance + * + * @param[in] os_buf Pointer to the OS data buffer. + * @param[in] if_num NSS interface number. + * @param[in] nss_ctx Pointer to the NSS core context. + * + * @return + * Status of Tx buffer forwarded to NSS for TLS operation. + */ +nss_tx_status_t nss_tls_tx_buf(struct sk_buff *os_buf, uint32_t if_num, struct nss_ctx_instance *nss_ctx); + +/** + * nss_tls_tx_msg + * Sends an asynchronous IPsec message to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_tls_msg + * + * @param[in] nss_ctx Pointer to the NSS HLOS driver context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_tls_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_tls_msg *msg); + +/** + * nss_tls_tx_msg_sync + * Sends a synchronous IPsec message to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_tls_msg_type \n + * nss_tls_msg + * + * @param[in] nss_ctx Pointer to the NSS HLOS driver context. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] nicm Pointer to the NSS IPsec message. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_tls_tx_msg_sync(struct nss_ctx_instance *nss_ctx, uint32_t if_num, + enum nss_tls_msg_type type, uint16_t len, + struct nss_tls_msg *ntcm); + +/** + * nss_tls_register_if + * Registers a TLS session interface with the NSS for sending and receiving + * messages. + * + * @datatypes + * nss_tls_data_callback_t \n + * nss_tls_msg_callback_t \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] data_cb Callback function for the message. + * @param[in] msg_cb Callback for TLS tunnel message. + * @param[in] netdev Pointer to the associated network device. + * @param[in] features Data socket buffer types supported by this interface. + * @param[in] type Type of message. + * @param[in] app_ctx Pointer to the application context. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_tls_register_if(uint32_t if_num, + nss_tls_data_callback_t data_cb, + nss_tls_msg_callback_t msg_cb, + struct net_device *netdev, + uint32_t features, + uint32_t type, + void *app_ctx); + +/** + * nss_tls_unregister_if + * Deregisters a TLS session interface from the NSS. + * + * @param[in] if_num NSS interface number. + * + * @return + * None. + * + * @dependencies + * The TLS session interface must have been previously registered. + */ +extern void nss_tls_unregister_if(uint32_t if_num); + +/** + * nss_tls_notify_register + * Register an event callback to handle notification from TLS firmware package. + * + * @datatypes + * nss_tls_msg_callback_t + * + * @param[in] ifnum NSS interface number. + * @param[in] ev_cb Callback for TLS tunnel message. + * @param[in] app_data Pointer to the application context. + * + * @return + * Pointer to NSS core context. + */ +extern struct nss_ctx_instance *nss_tls_notify_register(uint32_t ifnum, nss_tls_msg_callback_t ev_cb, void *app_data); + +/** + * nss_tls_notify_unregister + * Unregister an event callback. + * + * @param[in] ifnum NSS interface number. + * + * @return + * None. + */ +extern void nss_tls_notify_unregister(uint32_t ifnum); + +/** + * nss_tls_msg_init + * Initializes a TLS message sent asynchronously. + * + * @datatypes + * nss_tls_msg + * + * @param[in,out] ncm Pointer to the message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Pointer to the message callback. + * @param[in] app_data Pointer to the application context. + * + * @return + * None. + */ +extern void nss_tls_msg_init(struct nss_tls_msg *ncm, uint32_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data); + +/** + * nss_tls_msg_sync_init + * Initializes a TLS message. + * + * @datatypes + * nss_tls_msg + * + * @param[in,out] ncm Pointer to the message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * + * @return + * None. + */ +extern void nss_tls_msg_sync_init(struct nss_tls_msg *ncm, uint32_t if_num, uint32_t type, uint32_t len); + +/** + * nss_tls_get_context + * Gets the NSS core context for the TLS session. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_tls_get_context(void); + +/** + * nss_tls_get_device + * Gets the original device from probe. + * + * @return + * Pointer to the device. + */ +extern struct device *nss_tls_get_dev(struct nss_ctx_instance *nss_ctx); +/** + * @} + */ + +#endif /* _NSS_TLS_H_. */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_trustsec_tx.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_trustsec_tx.h new file mode 100644 index 000000000..b71fac54d --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_trustsec_tx.h @@ -0,0 +1,234 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2017, 2020 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_trustsec_tx.h + * NSS TrustSec interface definitions. + */ + +#ifndef __NSS_TRUSTSEC_TX_H +#define __NSS_TRUSTSEC_TX_H + +/** + * @addtogroup nss_trustsec_tx_subsystem + * @{ + */ + +/** + * nss_trustsec_tx_msg_types + * Message types for TrustSec Tx requests and responses. + */ +enum nss_trustsec_tx_msg_types { + NSS_TRUSTSEC_TX_MSG_CONFIGURE, /** Configure the TrustSec node. */ + NSS_TRUSTSEC_TX_MSG_UNCONFIGURE, /** Unconfigure the TrustSec node. */ + NSS_TRUSTSEC_TX_MSG_STATS_SYNC, /** Statistics sychronization. */ + NSS_TRUSTSEC_TX_MSG_UPDATE_NEXTHOP, /** Update next hop. */ + NSS_TRUSTSEC_TX_MSG_MAX /** Maximum message type. */ +}; + +/** + * nss_trustsec_tx_error_types + * Error types for the TrustSec Tx interface. + */ +enum nss_trustsec_tx_error_types { + NSS_TRUSTSEC_TX_ERR_NONE, /** No error */ + NSS_TRUSTSEC_TX_ERR_INVAL_SRC_IF, /** Source interface is invalid. */ + NSS_TRUSTSEC_TX_ERR_RECONFIGURE_SRC_IF, /** Source interface is already configured. */ + NSS_TRUSTSEC_TX_ERR_DEST_IF_NOT_FOUND, /** Destination interface is not found. */ + NSS_TRUSTSEC_TX_ERR_NOT_CONFIGURED, /** Source interface is not configured. */ + NSS_TRUSTSEC_TX_ERR_SGT_MISMATCH, /** SGT mismatches. */ + NSS_TRUSTSEC_TX_ERR_UNKNOWN, /** Error is unknown. */ + NSS_TRUSTSEC_TX_ERR_MAX, /** Maximum error message. */ +}; + +/** + * nss_trustsec_tx_configure_msg + * Message information for configuring a TrustSec Tx interface. + */ +struct nss_trustsec_tx_configure_msg { + uint32_t src; /**< Interface number of the source tunnel. */ + uint32_t dest; /**< Outgoing interface number. */ + uint16_t sgt; /**< Security Group Tag value to embed in the TrustSec header. */ + uint8_t reserved[2]; /**< Reserved for word alignment. */ +}; + +/** + * nss_trustsec_tx_unconfigure_msg + * Message information for de-configuring a TrustSec Tx interface. + */ +struct nss_trustsec_tx_unconfigure_msg { + uint32_t src; /**< Interface number of the source tunnel. */ + uint16_t sgt; /**< Security Group Tag value configured for this interface. */ + uint8_t reserved[2]; /**< Reserved for word alignment. */ +}; + +/** + * nss_trustsec_tx_stats_sync_msg + * Statistics synchronization message for the TrustSec Tx interface. + */ +struct nss_trustsec_tx_stats_sync_msg { + struct nss_cmn_node_stats node_stats; /**< Common node statistics. */ + uint32_t invalid_src; /**< Received packets with an invalid source interface. */ + uint32_t unconfigured_src; /**< Received packets with a de-configured source interface. */ + uint32_t headroom_not_enough; /**< Not enough headroom to insert a TrustSec header. */ +}; + +/** + * nss_trustsec_tx_update_nexthop_msg + * Message information for updating the next hop for a TrustSec Tx interface. + */ +struct nss_trustsec_tx_update_nexthop_msg { + uint32_t src; /**< Interface number of the source tunnel. */ + uint32_t dest; /**< Outgoing interface number. */ + uint16_t sgt; /**< Security Group Tag value to embed in the TrustSec header. */ + uint8_t reserved[2]; /**< Reserved for word alignment. */ +}; + +/** + * nss_trustsec_tx_msg + * Data for sending and receiving TrustSec Tx messages. + */ +struct nss_trustsec_tx_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a TrustSec Tx message. + */ + union { + struct nss_trustsec_tx_configure_msg configure; + /**< Configure TrustSec Tx. */ + struct nss_trustsec_tx_unconfigure_msg unconfigure; + /**< De-configure TrustSec Tx. */ + struct nss_trustsec_tx_stats_sync_msg stats_sync; + /**< Synchronize TrustSec Tx statistics. */ + struct nss_trustsec_tx_update_nexthop_msg upd_nexthop; + /**< Update next hop of TrustSec Tx. */ + } msg; /**< Message payload. */ +}; + +/** + * Callback function for receiving TrustSec Tx messages. + * + * @datatypes + * nss_trustsec_tx_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_trustsec_tx_msg_callback_t)(void *app_data, struct nss_trustsec_tx_msg *npm); + +/** + * nss_trustsec_tx_msg_init + * Initializes a TrustSec Tx message. + * + * @datatypes + * nss_trustsec_tx_msg + * + * @param[in,out] npm Pointer to the NSS Profiler message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the message. + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * TRUE or FALSE. + */ +extern void nss_trustsec_tx_msg_init(struct nss_trustsec_tx_msg *npm, uint16_t if_num, uint32_t type, uint32_t len, + nss_trustsec_tx_msg_callback_t cb, void *app_data); + +/** + * nss_trustsec_tx_msg + * Sends a TrustSec Tx message to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_trustsec_tx_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_trustsec_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_trustsec_tx_msg *msg); + +/** + * nss_trustsec_tx_msg_sync + * Sends a TrustSec Tx message to the NSS and waits for a response. + * + * @datatypes + * nss_ctx_instance \n + * nss_trustsec_tx_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_trustsec_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_trustsec_tx_msg *msg); + +/** + * nss_trustsec_tx_update_nexthop + * Updates the next hop of the TrustSec. + * + * @param[in] src Source interface number. + * @param[in] dest Destination interface number. + * @param[in] sgt Security Group Tag value. + * + * @return + * Pointer to the NSS core context. + */ +extern nss_tx_status_t nss_trustsec_tx_update_nexthop(uint32_t src, uint32_t dest, uint16_t sgt); + +/** + * nss_trustsec_tx_get_ctx + * Gets the NSS context. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_trustsec_tx_get_ctx(void); + +/** + * nss_trustsec_tx_configure_sgt + * Configures the Security Group Tag value for a source interface. + * + * @param[in] src Source interface number. + * @param[in] dest Destination interface number. + * @param[in] sgt Security Group Tag value. + * + * @return + * Pointer to the NSS core context. + */ +extern nss_tx_status_t nss_trustsec_tx_configure_sgt(uint32_t src, uint32_t dest, uint16_t sgt); + +/** + * nss_trustsec_tx_unconfigure_sgt + * De-configures the Security Group Tag value for a source interface. + * + * @param[in] src Source interface number. + * @param[in] sgt Security Group Tag value. + * + * @return + * Pointer to the NSS core context. + */ +extern nss_tx_status_t nss_trustsec_tx_unconfigure_sgt(uint32_t src, uint16_t sgt); + +/** @} */ /* end_addtogroup nss_trustsec_tx_subsystem */ + +#endif /* __NSS_TRUSTSEC_TX_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_tstamp.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_tstamp.h new file mode 100644 index 000000000..3c23e4eed --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_tstamp.h @@ -0,0 +1,125 @@ +/* + ************************************************************************** + * Copyright (c) 2017, 2019 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_tstamp.h + * NSS to HLOS Tstamp interface definitions. + */ + +#ifndef __NSS_TSTAMP_H +#define __NSS_TSTAMP_H + +/** + * nss_tstamp_msg_type + * Time stamp message types. + */ +enum nss_tstamp_msg_type { + NSS_TSTAMP_MSG_TYPE_SYNC_STATS, /**< Statistic synchronization message. */ + NSS_TSTAMP_MSG_TYPE_MAX, /**< Maximum message type. */ +}; + +/** + * nss_tstamp_h2n_pre_hdr + * Metadata added by the time stamp HLOS driver. + * + * It is used while sending the packet to the NSS time stamp module. + */ +struct nss_tstamp_h2n_pre_hdr { + uint32_t ts_ifnum; /**< Time stamp interface number. */ + uint32_t ts_tx_hdr_sz; /**< Total header size. */ +}; + +/* + * nss_tstamp_n2h_pre_hdr + * Metadata added by the NSS time stamp module. + * + * It is added before sending the packet to host. + */ +struct nss_tstamp_n2h_pre_hdr { + uint32_t ts_ifnum; /**< Time stamp interface number. */ + uint32_t ts_data_lo; /**< Time stamp lower order bits. */ + uint32_t ts_data_hi; /**< Time stamp higher order bits. */ + + uint32_t ts_tx; /**< Time stamp direction. */ + uint32_t ts_hdr_sz; /**< Size of the header including the skb data alignment padding. */ + uint32_t reserved; /**< Reserved for cache alignment. */ +}; + +/** + * nss_tstamp_stats_msg + * Statistics messages from the NSS firmware. + */ +struct nss_tstamp_stats_msg { + struct nss_cmn_node_stats node_stats; + /**< Common node statistics for time stamp. */ + uint32_t boomeranged; /**< Boomeranged packets. */ + uint32_t dropped_fail_enqueue; /**< Enqueue failed. */ + uint32_t dropped_fail_alloc; /**< Allocation for copy failed. */ + uint32_t dropped_fail_copy; /**< Copy failed. */ + uint32_t dropped_no_interface; /**< Next interface not found. */ + uint32_t dropped_no_headroom; /**< Packet does not have enough headroom. */ +}; + +/** + * nss_tstamp_msg + * Data for sending and receiving time stamp messages. + */ +struct nss_tstamp_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a time stamp common message. + */ + union { + struct nss_tstamp_stats_msg stats; + /**< Time stamp statistics. */ + } msg; /**< Message payload. */ +}; + +/** + * Callback function for receiving core-to-core transmissions messages. + * + * @datatypes + * nss_tstamp_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_tstamp_msg_callback_t)(void *app_data, struct nss_tstamp_msg *msg); + +/** + * nss_tstamp_notify_register + * Registers a notifier callback for time stamp messages with the NSS. + * + * @datatypes + * nss_tstamp_msg_callback_t + * + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * Pointer to the NSS core context. + */ +struct nss_ctx_instance *nss_tstamp_notify_register(nss_tstamp_msg_callback_t cb, void *app_data); + +/** + * @brief Transfer the packet to time stamp NSS module. + * + * @return nss_tx_status + */ +nss_tx_status_t nss_tstamp_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *skb, uint32_t if_num); + +#endif /* __NSS_TSTAMP_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_tun6rd.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_tun6rd.h new file mode 100644 index 000000000..b0675e86d --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_tun6rd.h @@ -0,0 +1,198 @@ +/* + ************************************************************************** + * Copyright (c) 2014, 2017-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_tun6rd.h + * NSS TUN6RD interface definitions. + */ + +#ifndef __NSS_TUN6RD_H +#define __NSS_TUN6RD_H + +/** + * @addtogroup nss_tun6rd_subsystem + * @{ + */ + +/** + * nss_tun6rd_metadata_types + * Message types for 6RD (IPv6 in IPv4) tunnel requests and responses. + */ +enum nss_tun6rd_metadata_types { + NSS_TUN6RD_ATTACH_PNODE, + NSS_TUN6RD_RX_STATS_SYNC, + NSS_TUN6RD_ADD_UPDATE_PEER, + NSS_TUN6RD_MAX, +}; + +/** + * nss_tun6rd_attach_tunnel_msg + * Message information for configuring the 6RD tunnel. + */ +struct nss_tun6rd_attach_tunnel_msg { + uint32_t saddr; /**< Source address of the tunnel. */ + uint32_t daddr; /**< Destination address of the tunnel. */ + uint8_t tos; /**< Type Of Service field added to the outer header. */ + uint8_t ttl; /**< Time-to-live value for the tunnel. */ + uint32_t sibling_if_num; /**< Sibling interface number. */ + uint16_t reserved; /**< Reserved field added for alignment. */ +}; + +/** + * nss_tun6rd_sync_stats_msg + * Message information for 6RD tunnel synchronization statistics. + */ +struct nss_tun6rd_sync_stats_msg { + struct nss_cmn_node_stats node_stats; /**< Common node statistics. */ +}; + +/** + * nss_tun6rd_set_peer_msg + * Message information for the 6RD tunnel peer address. + */ +struct nss_tun6rd_set_peer_msg { + uint32_t ipv6_address[4]; /**< IPv6 address. */ + uint32_t dest; /**< IPv4 address. */ +}; + +/** + * nss_tun6rd_msg + * Data for sending and receiving 6RD tunnel messages. + */ +struct nss_tun6rd_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a 6RD tunnel message. + */ + union { + struct nss_tun6rd_attach_tunnel_msg tunnel; + /**< Attach a 6RD tunnel. */ + struct nss_tun6rd_sync_stats_msg stats; + /**< Synchronized statistics for the interface. */ + struct nss_tun6rd_set_peer_msg peer; + /**< Add or update the peer. */ + } msg; /**< Message payload for 6RD tunnel messages exchanged with NSS core. */ +}; + +/** + * Callback function for receiving 6RD tunnel messages. + * + * @datatypes + * nss_tun6rd_msg + * + * @param[in] app_data Pointer to the application context of the message + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_tun6rd_msg_callback_t)(void *app_data, struct nss_tun6rd_msg *msg); + +/** + * nss_tun6rd_tx + * Sends a 6RD tunnel message. + * + * @datatypes + * nss_ctx_instance \n + * nss_tun6rd_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_tun6rd_tx(struct nss_ctx_instance *nss_ctx, struct nss_tun6rd_msg *msg); + +/** + * nss_tun6rd_get_context + * Gets the TUN6RD context used in nss_tun6rd_tx(). + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_tun6rd_get_context(void); + +/** + * Callback function for receiving 6RD tunnel data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_tun6rd_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * nss_register_tun6rd_if + * Registers the TUN6RD interface with the NSS for sending and receiving messages. + * + * @datatypes + * nss_tun6rd_callback_t \n + * nss_tun6rd_msg_callback_t \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] type NSS interface type. + * @param[in] tun6rd_callback Callback for the data. + * @param[in] msg_callback Callback for the message. + * @param[in] netdev Pointer to the associated network device. + * @param[in] features Data socket buffer types supported by this interface. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_register_tun6rd_if(uint32_t if_num, uint32_t type, nss_tun6rd_callback_t tun6rd_callback, + nss_tun6rd_msg_callback_t msg_callback, struct net_device *netdev, uint32_t features); + +/** + * nss_unregister_tun6rd_if + * Deregisters the TUN6RD interface from the NSS. + * + * @param[in] if_num NSS interface number. +. * + * @return + * None. + * + * @dependencies + * The 6RD tunnel interface must have been previously registered. + */ +extern void nss_unregister_tun6rd_if(uint32_t if_num); + +/** + * nss_tun6rd_msg_init + * Initializes a TUN6RD message. + * + * @datatypes + * nss_tun6rd_msg + * + * @param[in,out] ncm Pointer to the message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Pointer to the message callback. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_tun6rd_msg_init(struct nss_tun6rd_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data); + +/** @} */ /* end_addtogroup nss_tun6rd_subsystem */ + +#endif /* __NSS_TUN6RD_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_tunipip6.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_tunipip6.h new file mode 100644 index 000000000..6edc73ba7 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_tunipip6.h @@ -0,0 +1,293 @@ +/* + ************************************************************************** + * Copyright (c) 2014, 2017-2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_tunipip6.h + * NSS TUNIPIP6 interface definitions. + */ + +#ifndef __NSS_TUNIPIP6_H +#define __NSS_TUNIPIP6_H + +/** + * Maximum number of supported TUNIPIP6 tunnels. + */ +#define NSS_TUNIPIP6_TUNNEL_MAX 32 + +/** + * @addtogroup nss_tunipip6_subsystem + * @{ + */ + +/** + * nss_tunipip6_map_rule + * Mapping rule (FMR/BMR) for forwarding traffic to the node in the same domain. + */ +struct nss_tunipip6_map_rule { + uint32_t ip6_prefix[4]; /**< An IPv6 prefix assigned by a mapping rule. */ + uint32_t ip4_prefix; /**< An IPv4 prefix assigned by a mapping rule. */ + uint32_t ip6_prefix_len; /**< IPv6 prefix length. */ + uint32_t ip4_prefix_len; /**< IPv4 prefix length. */ + uint32_t ip6_suffix[4]; /**< IPv6 suffix. */ + uint32_t ip6_suffix_len; /**< IPv6 suffix length. */ + uint32_t ea_len; /**< Embedded Address (EA) bits. */ + uint32_t psid_offset; /**< PSID offset default 6. */ +}; + +/* + * nss_tunipip6_err_types + * Error types for response to messages from the host. + */ +enum nss_tunipip6_err_types { + NSS_TUNIPIP6_ERR_TYPE_MAX_TUNNELS, /**< Maximum number of tunnel reached. */ + NSS_TUNIPIP6_ERR_TYPE_TUNNEL_EXIST, /**< Tunnel already exists. */ + NSS_TUNIPIP6_ERR_TYPE_ENCAP_BAD_PARAM, /**< Bad configuration. */ + NSS_TUNIPIP6_ERR_TYPE_ENCAP_FMR_EXIST, /**< FMR already exists. */ + NSS_TUNIPIP6_ERR_TYPE_ENCAP_NO_FMR, /**< No FMR configured.*/ + NSS_TUNIPIP6_ERR_TYPE_ENCAP_FMR_FULL, /**< FMR table is full. */ + NSS_TUNIPIP6_ERR_TYPE_ENCAP_INVALID_FMR, /**< Invalid FMR configured.*/ + NSS_TUNIPIP6_ERR_TYPE_ENCAP_BMR_EXIST, /**< BMR already exists. */ + NSS_TUNIPIP6_ERR_TYPE_ENCAP_NO_BMR, /**< No BMR configured. */ + NSS_TUNIPIP6_ERR_TYPE_ENCAP_FMR_MEM_ALLOC_FAILED, /**< Pool allocation for FMR failed. */ + NSS_TUNIPIP6_ERR_TYPE_UNKNOWN, /**< Unknown message type. */ + NSS_TUNIPIP6_ERROR_MAX, /**< Maximum number of errors. */ +}; + +/** + * nss_tunipip6_metadata_types + * Message types for TUNIPIP6 (IPv4 in IPv6) tunnel requests and responses. + */ +enum nss_tunipip6_metadata_types { + NSS_TUNIPIP6_TX_ENCAP_IF_CREATE, + NSS_TUNIPIP6_TX_DECAP_IF_CREATE, + NSS_TUNIPIP6_STATS_SYNC, + NSS_TUNIPIP6_FMR_RULE_ADD, + NSS_TUNIPIP6_FMR_RULE_DEL, + NSS_TUNIPIP6_FMR_RULE_FLUSH, + NSS_TUNIPIP6_BMR_RULE_ADD, + NSS_TUNIPIP6_BMR_RULE_DEL, + NSS_TUNIPIP6_MAX, +}; + +/** + * nss_tunipip6_create_msg + * Payload for configuring the TUNIPIP6 interface. + */ +struct nss_tunipip6_create_msg { + uint32_t saddr[4]; /**< Tunnel source address. */ + uint32_t daddr[4]; /**< Tunnel destination address. */ + uint32_t flowlabel; /**< Tunnel IPv6 flow label. */ + uint32_t flags; /**< Tunnel additional flags. */ + uint32_t sibling_if_num; /**< Sibling interface number. */ + uint8_t hop_limit; /**< Tunnel IPv6 hop limit. */ + uint8_t draft03; /**< Use MAP-E draft03 specification. */ + uint8_t ttl_inherit; /**< Inherit IPv4 TTL to hoplimit. */ + uint8_t tos_inherit; /**< Inherit IPv4 ToS. */ + uint8_t frag_id_update; /**< Enable update of fragment identifier of IPv4. */ + uint8_t reserved[3]; /**< Reserved bytes. */ + uint32_t fmr_max; /**< Maximum number of FMRs that can be configured. */ +}; + +/** + * nss_tunipip6_debug_stats + * TUNIPIP6 debug statistics. + */ +struct nss_tunipip6_debug_stats { + struct { + struct { + uint32_t low_headroom; /**< Low headroom for encapsulation. */ + uint32_t unhandled_proto; /**< Unhandled protocol for encapsulation. */ + } exp; + + struct { + uint32_t enqueue_fail; /**< Encapsulation enqueue fail. */ + } drop; + + struct { + uint32_t err_tunnel_cfg; /**< Tunnel configuration error. */ + uint32_t total_fmr; /**< Total number of existing FMRs. */ + uint32_t fmr_add_req; /**< FMR add requests. */ + uint32_t fmr_del_req; /**< FMR delete requests. */ + uint32_t fmr_flush_req; /**< FMR flush requests. */ + uint32_t fmr_update_req; /**< FMR update requests. */ + uint32_t fmr_add_fail; /**< FMR addition failed. */ + uint32_t fmr_del_fail; /**< FMR deletion failed. */ + uint32_t err_no_fmr; /**< No FMR configured. */ + uint32_t bmr_add_req; /**< BMR add requests. */ + uint32_t bmr_del_req; /**< BMR delete requests. */ + uint32_t err_bmr_exist; /**< BMR already configured. */ + uint32_t err_no_bmr; /**< No BMR configured. */ + } cfg; + } encap; + + struct { + struct { + uint32_t enqueue_fail; /**< Decapsulation enqueue fail. */ + } drop; + } decap; +}; + +/** + * nss_tunipip6_stats_sync_msg + * Message information for TUNIPIP6 synchronization statistics. + */ +struct nss_tunipip6_stats_sync_msg { + struct nss_cmn_node_stats node_stats; /**< Common node statistics. */ + struct nss_tunipip6_debug_stats tun_stats; /**< TUNIPIP6 debug statistics. */ +}; + +/** + * nss_tunipip6_msg + * Data for sending and receiving TUNIPIP6 messages. + */ +struct nss_tunipip6_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a TUNIPIP6 message. + */ + union { + struct nss_tunipip6_create_msg tunipip6_create; + /**< Create a TUNIPIP6 tunnel. */ + struct nss_tunipip6_stats_sync_msg stats; + /**< Synchronized statistics for the TUNIPIP6 interface. */ + struct nss_tunipip6_map_rule map_rule; + /**< BMR/FMR rule to add/delete, new or existing rules. */ + } msg; /**< Message payload for TUNIPIP6 messages exchanged with NSS core. */ +}; + +/** + * Callback function for receiving TUNIPIP6 messages. + * + * @datatypes + * nss_tunipip6_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_tunipip6_msg_callback_t)(void *app_data, struct nss_tunipip6_msg *msg); + +/** + * nss_tunipip6_tx + * Sends a TUNIPIP6 message to NSS core. + * + * @datatypes + * nss_ctx_instance \n + * nss_tunipip6_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_tunipip6_tx(struct nss_ctx_instance *nss_ctx, struct nss_tunipip6_msg *msg); + +/** + * nss_tunipip6_tx_sync + * Sends a TUNIPIP6 message to NSS core synchronously. + * + * @datatypes + * nss_ctx_instance \n + * nss_tunipip6_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_tunipip6_tx_sync(struct nss_ctx_instance *nss_ctx, struct nss_tunipip6_msg *msg); + +/** + * Callback function for receiving TUNIPIP6 data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_tunipip6_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * nss_register_tunipip6_if + * Registers the TUNIPIP6 interface with the NSS for sending and receiving + * TUNIPIP6 messages. + * + * @datatypes + * nss_tunipip6_callback_t \n + * nss_tunipip6_msg_callback_t \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] type Dynamic interface type. + * @param[in] tunipip6_callback Callback for the data. + * @param[in] event_callback Callback for the message. + * @param[in] netdev Pointer to the associated network device. + * @param[in] features Data socket buffer types supported by this interface. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_register_tunipip6_if(uint32_t if_num, uint32_t type, nss_tunipip6_callback_t tunipip6_callback, + nss_tunipip6_msg_callback_t event_callback, struct net_device *netdev, uint32_t features); + +/** + * nss_unregister_tunipip6_if + * Deregisters the TUNIPIP6 interface from the NSS. + * + * @param[in] if_num NSS interface number. + * + * @return + * None. + */ +extern void nss_unregister_tunipip6_if(uint32_t if_num); + +/** + * nss_tunipip6_msg_init + * Initializes a TUNIPIP6 message. + * + * @datatypes + * nss_tunipip6_msg + * + * @param[in,out] ntm Pointer to the IPIP6 tunnel message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the message. + * @param[in] cb Pointer to the message callback. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_tunipip6_msg_init(struct nss_tunipip6_msg *ntm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data); + +/** + * nss_tunipip6_get_context() + * Get TUNIPIP6 context. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_tunipip6_get_context(void); + +/** @} */ /* end_addtogroup nss_tunipip6_subsystem */ + +#endif /* __NSS_TUN6RD_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_unaligned.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_unaligned.h new file mode 100644 index 000000000..2eb6e1a4a --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_unaligned.h @@ -0,0 +1,121 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_unaligned.h + * NSS unaligned interface definitions. + */ + +#ifndef __NSS_UNALIGNED_H +#define __NSS_UNALIGNED_H + +/** + * @addtogroup nss_unaligned_subsystem + * @{ + */ + +#define NSS_UNALIGNED_OPS_PER_MSG 54 + /**< The number of operations whose statistics are included in a message. */ +#define NSS_UNALIGNED_EMULATED_OPS 64 + /**< The number of operations that are emulated. */ + +/** + * nss_unaligned_msg_types + * Unaligned message types. + */ +enum nss_unaligned_msg_types { + NSS_UNALIGNED_MSG_STATS, /**< Performance statistics message. */ + NSS_UNALIGNED_MSG_MAX, /**< Maximum unaligned message type. */ +}; + +/** + * nss_unaligned_stats_op + * Performance statistics for emulating a single operation. + */ +struct nss_unaligned_stats_op { + uint32_t opcode_primary; + /**< Primary operation code. */ + uint32_t opcode_extension; + /**< Extension operation code, if applicable. */ + uint64_t count; + /**< Number of times operation was emulated. */ + uint32_t ticks_min; + /**< Minimum number of ticks spent emulating operation. */ + uint32_t ticks_avg; + /**< Average number of ticks spent emulating operation. */ + uint32_t ticks_max; + /**< Maximum number of ticks spent emulating operation. */ + uint32_t padding; + /**< Used for consistent alignment, can be re-used. */ +}; + +/** + * nss_unaligned_stats + * Message containing all non-zero operation statistics. + */ +struct nss_unaligned_stats { + uint64_t trap_count; + /**< Number of unaligned traps encountered. */ + struct nss_unaligned_stats_op ops[NSS_UNALIGNED_EMULATED_OPS]; + /**< Statistics for each operation. */ +}; + +/** + * nss_unaligned_stats_msg + * Message containing all non-zero operation statistics. + */ +struct nss_unaligned_stats_msg { + uint64_t trap_count; /**< Number of unaligned traps encountered. */ + struct nss_unaligned_stats_op ops[NSS_UNALIGNED_OPS_PER_MSG]; + /**< Statistics for each operation. */ + uint32_t current_iteration; /**< Number of full statistics messages sent without reaching the end. */ +}; + +/** + * nss_unaligned_msg + * Message from unaligned handler node. + */ +struct nss_unaligned_msg { + struct nss_cmn_msg cm; /**< Message header. */ + + /** + * Unaligned message payload. + */ + union { + struct nss_unaligned_stats_msg stats_msg; + /**< Message containing statistics. */ + } msg; /**< Message payload. */ +}; + +/** + * nss_unaligned_register_handler() + * Registers message handler on the NSS unaligned interface and + * statistics dentry. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS context. + * + * @return + * None. + */ +void nss_unaligned_register_handler(struct nss_ctx_instance *nss_ctx); + +/** + * @} + */ +#endif diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_virt_if.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_virt_if.h new file mode 100644 index 000000000..443e6cf86 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_virt_if.h @@ -0,0 +1,436 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2017, 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * @file nss_virt_if.h + * NSS Virtual interface message Structure and APIs + */ + +#ifndef __NSS_VIRT_IF_H +#define __NSS_VIRT_IF_H + +#include "nss_if.h" + +/** + * @addtogroup nss_virtual_if_subsystem + * @{ + */ + +/** + * nss_virt_if_msg_types + * Message types for virtual interface requests and responses. + */ +enum nss_virt_if_msg_types { + NSS_VIRT_IF_OPEN = NSS_IF_OPEN, + NSS_VIRT_IF_CLOSE = NSS_IF_CLOSE, + NSS_VIRT_IF_LINK_STATE_NOTIFY = NSS_IF_LINK_STATE_NOTIFY, + NSS_VIRT_IF_MTU_CHANGE = NSS_IF_MTU_CHANGE, + NSS_VIRT_IF_MAC_ADDR_SET = NSS_IF_MAC_ADDR_SET, + NSS_VIRT_IF_STATS_SYNC = NSS_IF_STATS, + NSS_VIRT_IF_ISHAPER_ASSIGN = NSS_IF_ISHAPER_ASSIGN, + NSS_VIRT_IF_BSHAPER_ASSIGN = NSS_IF_BSHAPER_ASSIGN, + NSS_VIRT_IF_ISHAPER_UNASSIGN = NSS_IF_ISHAPER_UNASSIGN, + NSS_VIRT_IF_BSHAPER_UNASSIGN = NSS_IF_BSHAPER_UNASSIGN, + NSS_VIRT_IF_ISHAPER_CONFIG = NSS_IF_ISHAPER_CONFIG, + NSS_VIRT_IF_BSHAPER_CONFIG = NSS_IF_BSHAPER_CONFIG, + NSS_VIRT_IF_VSI_ASSIGN = NSS_IF_VSI_ASSIGN, + NSS_VIRT_IF_VSI_UNASSIGN = NSS_IF_VSI_UNASSIGN, + NSS_VIRT_IF_TX_CONFIG_MSG = NSS_IF_MAX_MSG_TYPES + 1, + NSS_VIRT_IF_STATS_SYNC_MSG, + NSS_VIRT_IF_MAX_MSG_TYPES, +}; + +/** + * nss_virt_if_error_types + * Error types for the virtual interface. + */ +enum nss_virt_if_error_types { + NSS_VIRT_IF_SUCCESS, + NSS_VIRT_IF_CORE_FAILURE, + NSS_VIRT_IF_ALLOC_FAILURE, + NSS_VIRT_IF_DYNAMIC_IF_FAILURE, + NSS_VIRT_IF_MSG_TX_FAILURE, + NSS_VIRT_IF_REG_FAILURE, + NSS_VIRT_IF_CORE_NOT_INITIALIZED, +}; + +/** + * nss_virt_if_base_node_stats + * Virtual interface statistics of NSS base node. + */ +struct nss_virt_if_base_node_stats { + uint32_t active_interfaces; /**< Number of active virtual interfaces. */ + uint32_t ocm_alloc_failed; /**< Number of interface allocation failure on OCM. */ + uint32_t ddr_alloc_failed; /**< Number of interface allocation failure on DDR. */ +}; + +/** + * nss_virt_if_interface_stats + * Virtual interface statistics of each pair of interfaces. + */ +struct nss_virt_if_interface_stats { + struct nss_cmn_node_stats node_stats; /**< Common statistics. */ + uint32_t tx_enqueue_failed; /**< Tx enqueue failures in the firmware. */ + uint32_t shaper_enqueue_failed; /**< Shaper enqueue failures in the firmware. */ + uint32_t ocm_alloc_failed; /**< Number of allocation failure on OCM. */ +}; + +/** + * nss_virt_if_stats + * Virtual interface statistics received from the NSS. + */ +struct nss_virt_if_stats { + struct nss_virt_if_base_node_stats base_stats; + struct nss_virt_if_interface_stats if_stats; +}; + +/** + * nss_virt_if_config_msg + * Message information for configuring the virtual interface. + */ +struct nss_virt_if_config_msg { + uint32_t flags; /**< Interface flags. */ + uint32_t sibling; /**< Sibling interface number. */ + uint32_t nexthop; /**< Next hop interface number. */ + uint8_t mac_addr[ETH_ALEN]; /**< MAC address. */ +}; + +/** + * nss_virt_if_msg + * Data for sending and receiving virtual interface messages. + */ +struct nss_virt_if_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a virtual interface message. + */ + union { + union nss_if_msgs if_msgs; + /**< NSS interface base message. */ + struct nss_virt_if_config_msg if_config; + /**< Rule for creating a virtual interface. */ + struct nss_virt_if_stats stats; + /**< Virtual interface statistics. */ + } msg; /**< Message payload. */ +}; + +/* + * nss_virt_if_pvt + * Private data information for the virtual interface. + */ +struct nss_virt_if_pvt { + struct semaphore sem; + /**< Semaphore to ensure that only one instance of a message is sent to the NSS. */ + struct completion complete; + /**< Waits for message completion or time out. */ + int response; /**< Message process response from the NSS firmware. */ + int sem_init_done; /**< Semaphore initialization is done. */ +}; + +/** + * Callback to transmit virtual interface data received from NSS + * to the transmit path of the virtual interface. + * + * @datatypes + * net_device \n + * sk_buff + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + */ +typedef void (*nss_virt_if_xmit_callback_t)(struct net_device *netdev, struct sk_buff *skb); + +/** + * Callback function for virtual interface data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_virt_if_data_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * Callback function for virtual interface messages. + * + * @datatypes + * nss_cmn_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_virt_if_msg_callback_t)(void *app_data, struct nss_cmn_msg *msg); + +/** + * nss_virt_if_handle + * Context information for WLAN-to-NSS communication. + */ +struct nss_virt_if_handle { + struct nss_ctx_instance *nss_ctx; /**< NSS context. */ + int32_t if_num_n2h; /**< Redirect interface number on NSS-to-host path. */ + int32_t if_num_h2n; /**< Redirect interface number on host-to-NSS path. */ + struct net_device *ndev; /**< Associated network device. */ + struct nss_virt_if_pvt *pvt; /**< Private data structure. */ + struct nss_virt_if_stats stats; /**< Virtual interface statistics. */ + atomic_t refcnt; /**< Reference count. */ + nss_virt_if_msg_callback_t cb; /**< Message callback. */ + void *app_data; /**< Application data to be passed to the callback. */ +}; + +/** + * nss_virt_if_dp_type + * Virtual interface datapath types. Redirect interface on NSS-to-host path will be seen by ECM for rules. + */ +enum nss_virt_if_dp_type { + NSS_VIRT_IF_DP_REDIR_N2H, /**< Redirect interface on NSS-to-host path has zero value. */ + NSS_VIRT_IF_DP_REDIR_H2N, /**< Redirect interface on host-to-NSS path has non-zero value. */ +}; + +/** + * nss_virt_if_create + * Creates a virtual interface asynchronously. + * + * @datatypes + * net_device \n + * nss_virt_if_msg_callback_t + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] cb Callback function for the message. This callback is + invoked when the response from the firmware is received. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * Status of the Tx operation. + */ +extern int nss_virt_if_create(struct net_device *netdev, nss_virt_if_msg_callback_t cb, void *app_data); + +/** + * nss_virt_if_create_sync + * Creates a virtual interface synchronously with the default nexthop values + * NSS_N2H_INTERFACE and NSS_ETH_RX_INTERFACE. + * + * @datatypes + * net_device + * + * @param[in] netdev Pointer to the associated network device. + * + * @return + * Pointer to nss_virt_if_handle. + */ +extern struct nss_virt_if_handle *nss_virt_if_create_sync(struct net_device *netdev); + +/** + * nss_virt_if_create_sync_nexthop + * Creates a virtual interface synchronously with specified nexthops. + * + * @datatypes + * net_device + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] nexthop_n2h Nexthop interface number of network-to-host dynamic interface. + * @param[in] nexthop_h2n Nexthop interface number of host-to-network dynamic interface. + * + * @return + * Pointer to NSS virtual interface handle. + */ +extern struct nss_virt_if_handle *nss_virt_if_create_sync_nexthop(struct net_device *netdev, uint32_t nexthop_n2h, uint32_t nexthop_h2n); + +/** + * nss_virt_if_destroy + * Destroys the virtual interface asynchronously. + * + * @datatypes + * nss_virt_if_handle \n + * nss_virt_if_msg_callback_t + * + * @param[in,out] handle Pointer to the virtual interface handle (provided during + * dynamic interface allocation). + * @param[in] cb Callback function for the message. This callback is + * invoked when the response from the firmware is received. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * Status of the Tx operation. + * + * @dependencies + * The interface must have been previously created. + */ +extern nss_tx_status_t nss_virt_if_destroy(struct nss_virt_if_handle *handle, nss_virt_if_msg_callback_t cb, void *app_data); + +/** + * nss_virt_if_destroy_sync + * Destroys the virtual interface synchronously. + * + * @datatypes + * nss_virt_if_handle + * + * @param[in,out] handle Pointer to the virtual interface handle (provided during + * dynamic interface allocation). + * + * @return + * Status of the Tx operation. + * + * @dependencies + * The interface must have been previously created. + */ +extern nss_tx_status_t nss_virt_if_destroy_sync(struct nss_virt_if_handle *handle); + +/** + * nss_virt_if_tx_msg + * Sends a message to the virtual interface. + * + * @datatypes + * nss_ctx_instance \n + * nss_virt_if_msg + * + * @param[in] nss_ctx Pointer to the NSS context (provided during registration). + * @param[in] nvim Pointer to the virtual interface message. + * + * @return + * Command Tx status. + */ +extern nss_tx_status_t nss_virt_if_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_virt_if_msg *nvim); + +/** + * nss_virt_if_tx_buf + * Forwards virtual interface packets to the NSS. + * + * @datatypes + * nss_virt_if_handle \n + * sk_buff + * + * @param[in,out] handle Pointer to the virtual interface handle (provided during + * registration). + * @param[in] skb Pointer to the data socket buffer. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_virt_if_tx_buf(struct nss_virt_if_handle *handle, + struct sk_buff *skb); + +/** + * nss_virt_if_xmit_callback_register + * Registers a transmit callback to a virtual interface. + * + * @datatypes + * nss_virt_if_handle \n + * nss_virt_if_xmit_callback_t + * + * @param[in,out] handle Pointer to the virtual interface handle (provided during + * dynamic interface allocation). + * @param[in] cb Callback handler for virtual data packets. + * + * @return + * None. + */ +extern void nss_virt_if_xmit_callback_register(struct nss_virt_if_handle *handle, + nss_virt_if_xmit_callback_t cb); + +/** + * nss_virt_if_xmit_callback_unregister + * Deregisters the transmit callback from the virtual interface. + * + * @datatypes + * nss_virt_if_handle + * + * @param[in,out] handle Pointer to the virtual interface handle. + * + * @return + * None. + */ +extern void nss_virt_if_xmit_callback_unregister(struct nss_virt_if_handle *handle); + +/** + * nss_virt_if_register + * Registers a virtual Interface with NSS driver. + * + * @datatypes + * nss_virt_if_handle \n + * nss_virt_if_data_callback_t \n + * net_device + * + * @param[in,out] handle Pointer to the virtual interface handle(provided during + * dynamic interface allocation). + * @param[in] data_callback Callback handler for virtual data packets + * @param[in] netdev Pointer to the associated network device. + * + * @return + * Status of the Tx operation. + */ +extern void nss_virt_if_register(struct nss_virt_if_handle *handle, + nss_virt_if_data_callback_t data_callback, + struct net_device *netdev); + +/** + * nss_virt_if_unregister + * Deregisters a virtual interface from the NSS driver. + * + * @datatypes + * nss_virt_if_handle + * + * @param[in,out] handle Pointer to the virtual interface handle. + * + * @return + * None. + */ +extern void nss_virt_if_unregister(struct nss_virt_if_handle *handle); + +/** + * nss_virt_if_get_interface_num + * Returns the virtual interface number associated with the handle. + * + * @datatypes + * nss_virt_if_handle + * + * @param[in] handle Pointer to the virtual interface handle(provided during + dynamic interface allocation). + * + * @return + * Virtual interface number. + */ +extern int32_t nss_virt_if_get_interface_num(struct nss_virt_if_handle *handle); + +/** + * nss_virt_if_verify_if_num + * Verifies if the interface is 802.3 redirect type. + * + * @param[in] if_num Interface number to be verified. + * + * @return + * True if if_num is 802.3 redirect type. + */ +bool nss_virt_if_verify_if_num(uint32_t if_num); + +/** + * nss_virt_if_get_context + * Gets the virtual interface context. + * + * @return + * Pointer to the NSS core context. + */ +struct nss_ctx_instance *nss_virt_if_get_context(void); + +/** + * @} + */ + +#endif /* __NSS_VIRT_IF_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_vlan.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_vlan.h new file mode 100644 index 000000000..872d2e042 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_vlan.h @@ -0,0 +1,265 @@ +/* + ************************************************************************** + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_vlan.h + * NSS VLAN interface definitions. + */ + +#ifndef __NSS_VLAN_H +#define __NSS_VLAN_H + +/** + * @addtogroup nss_vlan_subsystem + * @{ + */ + +/** + * nss_vlan_msg_types + * VLAN message types. + */ +enum nss_vlan_msg_types { + NSS_VLAN_MSG_ADD_TAG = NSS_IF_MAX_MSG_TYPES + 1, + NSS_VLAN_MSG_TYPE_MAX, +}; + +/** + * nss_vlan_error_types + * VLAN error types + */ +enum nss_vlan_error_types { + NSS_VLAN_ERROR_UNKNOWN_MSG = NSS_IF_ERROR_TYPE_MAX + 1, + NSS_VLAN_ERROR_TYPE_MAX, +}; + +#define NSS_VLAN_TYPE_SINGLE 0 /**< Single VLAN tag in message. */ +#define NSS_VLAN_TYPE_DOUBLE 1 /**< Double VLAN tag in message. */ + +/** + * nss_vlan_msg_add_tag + * VLAN message data for adding a VLAN tag. + */ +struct nss_vlan_msg_add_tag { + uint32_t vlan_tag; /**< VLAN tag information. */ + uint32_t next_hop; /**< Parent interface. */ + uint32_t if_num; /**< Actual physical interface. */ +}; + +/** + * nss_vlan_msg + * Data for sending and receiving VLAN messages. + */ +struct nss_vlan_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a VLAN message. + */ + union { + union nss_if_msgs if_msg; + /**< NSS interface base messages. */ + struct nss_vlan_msg_add_tag add_tag; + /**< VLAN add-a-tag message. */ + } msg; /**< Message payload. */ +}; + +/** + * nss_vlan_tx_msg + * Sends a VLAN message to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_vlan_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_vlan_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_vlan_msg *msg); + +/** + * nss_vlan_tx_msg_sync + * Sends a VLAN message to the NSS synchronously. + * + * @datatypes + * nss_ctx_instance \n + * nss_vlan_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_vlan_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_vlan_msg *msg); + +/** + * Initializes a VLAN message. + * + * @datatypes + * nss_vlan_msg + * + * @param[in,out] ncm Pointer to the message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Pointer to the message callback. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +void nss_vlan_msg_init(struct nss_vlan_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data); + +/** + * nss_vlan_get_context + * Gets the VLAN context used in nss_vlan_tx. + * + * @return + * Pointer to the NSS core context. + */ +struct nss_ctx_instance *nss_vlan_get_context(void); + +/** + * Callback when VLAN data is received + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_vlan_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * Callback to receive VLAN messages + * + * @datatypes + * nss_vlan_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_vlan_msg_callback_t)(void *app_data, struct nss_vlan_msg *msg); + +/** + * nss_register_vlan_if + * Register to send/receive VLAN messages to NSS + * + * @datatypes + * nss_vlan_callback_t \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] vlan_data_callback Callback for the data. + * @param[in] netdev Pointer to the associated network device. + * @param[in] features Data socket buffer types supported by this interface. + * @param[in] app_ctx Pointer to the application context of the message. + * + * @return + * Pointer to the NSS core context. + */ +struct nss_ctx_instance *nss_register_vlan_if(uint32_t if_num, nss_vlan_callback_t vlan_data_callback, + struct net_device *netdev, uint32_t features, void *app_ctx); + +/** + * Deregisters the VLAN interface from the NSS. + * + * @return + * None. + */ +void nss_unregister_vlan_if(uint32_t if_num); + +/** + * nss_vlan_tx_set_mtu_msg + * Sends a VLAN message to set the MTU. + * + * @param[in] vlan_if_num VLAN interface number. + * @param[in] mtu MTU value to set. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_vlan_tx_set_mtu_msg(uint32_t vlan_if_num, uint32_t mtu); + +/** + * nss_vlan_tx_set_mac_addr_msg + * Sends a VLAN message to set the MAC address. + * + * @param[in] vlan_if_num VLAN interface number. + * @param[in] addr Pointer to the MAC address. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_vlan_tx_set_mac_addr_msg(uint32_t vlan_if_num, uint8_t *addr); + +/** + * nss_vlan_tx_vsi_attach_msg + * Send a VLAN message to attach a VSI. + * + * @param[in] vlan_if_num VLAN interface number. + * @param[in] vsi PPE VSI to attach. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_vlan_tx_vsi_attach_msg(uint32_t vlan_if_num, uint32_t vsi); + +/** + * nss_vlan_tx_vsi_detach_msg + * Sends a VLAN message to detach VSI. + * + * @param[in] vlan_if_num VLAN interface number. + * @param[in] vsi VSI to detach. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_vlan_tx_vsi_detach_msg(uint32_t vlan_if_num, uint32_t vsi); + +/** + * nss_vlan_tx_add_tag_msg + * Sends a VLAN add tag message. + * + * @param[in] vlan_if_num VLAN interface number. + * @param[in] vlan_tag VLAN tag information. + * @param[in] next_hop Parent interface. + * @param[in] physical_dev Physical port to which to add the VLAN tag. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_vlan_tx_add_tag_msg(uint32_t vlan_if_num, uint32_t vlan_tag, uint32_t next_hop, uint32_t physical_dev); + +/** + * Registers the VLAN handler with the NSS. + * + * @return + * None. + */ +void nss_vlan_register_handler(void); + +/** + * @} + */ + +#endif /* __NSS_VLAN_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_vxlan.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_vxlan.h new file mode 100644 index 000000000..c90faebf9 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_vxlan.h @@ -0,0 +1,349 @@ +/* + ************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_vxlan.h + * NSS VxLAN interface definitions. + */ + +#ifndef __NSS_VXLAN_H +#define __NSS_VXLAN_H + +/** + * @addtogroup nss_vxlan_subsystem + * @{ + */ + +/** + * Maximum number of supported VxLAN tunnel sessions. + */ +#define NSS_VXLAN_MAX_TUNNELS 64 + +/** + * Maximum number of supported VxLAN FDB entries. + */ +#define NSS_VXLAN_MACDB_ENTRIES_MAX 1024 + +/** + * MAC database entries per message. + */ +#define NSS_VXLAN_MACDB_ENTRIES_PER_MSG 20 + +/* + * VxLAN Rule configure message flags + */ +#define NSS_VXLAN_RULE_FLAG_GBP_ENABLED 0x0001 /**< Group Policy ID is eanbled. */ +#define NSS_VXLAN_RULE_FLAG_INHERIT_TOS 0x0002 /**< Use inner TOS for encapsulation. */ +#define NSS_VXLAN_RULE_FLAG_ENCAP_L4_CSUM_REQUIRED 0x0004 /**< Generate transmit checksum. */ +#define NSS_VXLAN_RULE_FLAG_IPV4 0x0010 /**< IPv4 tunnel. */ +#define NSS_VXLAN_RULE_FLAG_IPV6 0x0020 /**< IPv6 tunnel. */ +#define NSS_VXLAN_RULE_FLAG_UDP 0x0100 /**< UDP tunnel. */ + +/** + * nss_vxlan_msg_type + * Message types for VxLAN tunnel. + */ +enum nss_vxlan_msg_type { + NSS_VXLAN_MSG_TYPE_STATS_SYNC, /**< Statistics synchronization message. */ + NSS_VXLAN_MSG_TYPE_TUN_CONFIGURE, /**< Creating tunnel rule. */ + NSS_VXLAN_MSG_TYPE_TUN_UNCONFIGURE, /**< Destroying tunnel rule. */ + NSS_VXLAN_MSG_TYPE_TUN_ENABLE, /**< Enable the tunnel. */ + NSS_VXLAN_MSG_TYPE_TUN_DISABLE, /**< Disable the tunnel. */ + NSS_VXLAN_MSG_TYPE_MAC_ADD, /**< Add MAC rule to the database. */ + NSS_VXLAN_MSG_TYPE_MAC_DEL, /**< Remove MAC rule from the database. */ + NSS_VXLAN_MSG_TYPE_MACDB_STATS, /**< MAC database statistics synchronization message. */ + NSS_VXLAN_MSG_TYPE_MAX, /**< Maximum message type. */ +}; + +/** + * nss_vxlan_error_response_types + * Error types for VxLAN responses to messages from the host. + */ +enum nss_vxlan_error_type { + NSS_VXLAN_ERROR_TYPE_NONE = 1, /**< Unknown type error. */ + NSS_VXLAN_ERROR_TYPE_DECAP_REGISTER_FAIL, /**< Decapsulation node registration failed. */ + NSS_VXLAN_ERROR_TYPE_DEST_IP_MISMATCH, /**< Destination IP address mismatch. */ + NSS_VXLAN_ERROR_TYPE_INVALID_VNI, /**< Invalid virtual network ID. */ + NSS_VXLAN_ERROR_TYPE_INVALID_L3_PROTO, /**< L3 Protocol is invalid error. */ + NSS_VXLAN_ERROR_TYPE_INVALID_UDP_PROTO, /**< UDP Protocol is invalid error. */ + NSS_VXLAN_ERROR_TYPE_INVALID_SRC_PORT, /**< Source port range is invalid. */ + NSS_VXLAN_ERROR_TYPE_MAC_BAD_ENTRY, /**< MAC table has a bad entry. */ + NSS_VXLAN_ERROR_TYPE_MAC_EXISTS, /**< MAC entry exists in the table error. */ + NSS_VXLAN_ERROR_TYPE_MAC_NOT_EXIST, /**< MAC does not exist in the table error. */ + NSS_VXLAN_ERROR_TYPE_MAC_ENTRY_UNHASHED, /**< MAC entry is not hashed in table. */ + NSS_VXLAN_ERROR_TYPE_MAC_ENTRY_ALLOC_FAILED, /**< MAC entry allocation failed. */ + NSS_VXLAN_ERROR_TYPE_MAC_ENTRY_DELETE_FAILED, /**< MAC entry deletion failed. */ + NSS_VXLAN_ERROR_TYPE_MAC_TABLE_FULL, /**< MAC table is full error. */ + NSS_VXLAN_ERROR_TYPE_SIBLING_NODE_NOT_EXIST, /**< Sibling node does not exist. */ + NSS_VXLAN_ERROR_TYPE_TUNNEL_CONFIGURED, /**< Tunnel is already configured. */ + NSS_VXLAN_ERROR_TYPE_TUNNEL_UNCONFIGURED, /**< Tunnel is not configured. */ + NSS_VXLAN_ERROR_TYPE_TUNNEL_ADD_FAILED, /**< Adding tunnel information failed. */ + NSS_VXLAN_ERROR_TYPE_TUNNEL_DISABLED, /**< Tunnel is already disabled error. */ + NSS_VXLAN_ERROR_TYPE_TUNNEL_ENABLED, /**< Tunnel is already enabled error. */ + NSS_VXLAN_ERROR_TYPE_TUNNEL_ENTRY_EXISTS, /**< Tunnel already exists. */ + NSS_VXLAN_ERROR_TYPE_MAX, /**< Maximum error type. */ +}; + +/** + * nss_vxlan_stats_msg + * Per-tunnel statistics messages from the NSS firmware. + */ +struct nss_vxlan_stats_msg { + struct nss_cmn_node_stats node_stats; /**< Common firmware statistics. */ + uint32_t except_mac_db_lookup_failed; /**< MAC database look up failed. */ + uint32_t except_mac_move; /**< User is moved. */ + uint32_t except_low_hroom; /**< Transmit exception due to insufficient headroom. */ + uint32_t except_no_policy_id; /**< Policy ID does not exist. */ + uint32_t except_extra_vxlan_hdr_flags; /**< More flags are set than NSS can process. */ + uint32_t except_vni_lookup_failed; /**< Virtual network ID look up failed. */ + uint32_t dropped_malformed; /**< Packet is malformed. */ + uint32_t dropped_next_node_queue_full; /**< Next node dropped the packet. */ +}; + +/** + * nss_vxlan_rule_msg + * VxLAN rule message. + * + * The same rule structure applies for both encapsulation and decapsulation + * in a tunnel. + */ +struct nss_vxlan_rule_msg { + /* + * VxLAN Rules + */ + uint32_t sibling_if_num; /**< Sibling node interface number. */ + uint32_t vni; /**< Virtual network ID. */ + uint16_t tunnel_flags; /**< VxLAN tunnel flags. */ + + /* + * IP rules + */ + uint16_t flow_label; /**< Flow label. */ + uint8_t tos; /**< Type of service/traffic class. */ + uint8_t ttl; /**< TTL/Hop Limit. */ + + /* + * L4 rules + */ + uint16_t src_port_min; /**< Minimum permissible port number. */ + uint16_t src_port_max; /**< Maximum permissible port number. */ + uint16_t dest_port; /**< UDP destination port. */ +}; + +/** + * nss_vxlan_encap_rule + * Encapsulation information for a VxLAN tunnel. + */ +struct nss_vxlan_encap_rule { + uint32_t src_ip[4]; /**< Source IP. */ + uint32_t dest_ip[4]; /**< Destination IP. */ +}; + +/** + * nss_vxlan_mac_msg + * VxLAN MAC message structure. + */ +struct nss_vxlan_mac_msg { + struct nss_vxlan_encap_rule encap; + /**< Tunnel encapsulation header. */ + uint32_t vni; /**< VxLAN network identifier. */ + uint16_t mac_addr[3]; /**< MAC address. */ +}; + +/** + * nss_vxlan_macdb_stats_entry + * MAC database statistics entry. + */ +struct nss_vxlan_macdb_stats_entry { + uint32_t hits; /**< Total hash hits on this hash entry. */ + uint16_t mac[3]; /**< MAC address. */ +}; + +/** + * nss_vxlan_macdb_stats_msg + * VxLAN MAC database statistics. + */ +struct nss_vxlan_macdb_stats_msg { + uint16_t cnt; /**< Number of MAC database entries copied. */ + uint16_t reserved; /**< Reserved for future use. */ + struct nss_vxlan_macdb_stats_entry entry[NSS_VXLAN_MACDB_ENTRIES_PER_MSG]; + /**< MAC database entries. */ +}; + +/** + * nss_vxlan_msg + * Data structure for sending and receiving VxLAN messages. + */ +struct nss_vxlan_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a VxLAN message. + */ + union { + struct nss_vxlan_stats_msg stats; + /**< Synchronized statistics for the VxLAN interface. */ + struct nss_vxlan_rule_msg vxlan_create; + /**< Allocate VxLAN tunnel node. */ + struct nss_vxlan_rule_msg vxlan_destroy; + /**< Destroy VxLAN tunnel node. */ + struct nss_vxlan_mac_msg mac_add; + /**< MAC add message for UDP encapsulation. */ + struct nss_vxlan_mac_msg mac_del; + /**< MAC delete message. */ + struct nss_vxlan_macdb_stats_msg db_stats; + /**< MAC database statistics. */ + } msg; /**< Payload for VxLAN tunnel messages exchanged with the NSS core. */ +}; + +/** + * Callback function for receiving VxLAN tunnel data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_vxlan_buf_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * Callback function for receiving VxLAN messages. + * + * @datatypes + * nss_cmn_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_vxlan_msg_callback_t)(void *app_data, struct nss_cmn_msg *msg); + +/** + * nss_vxlan_tx_msg + * Sends VxLAN tunnel messages to the NSS. + * + * Do not call this function from a softirq or interrupt because it + * might sleep if the NSS firmware is busy serving another host thread. + * + * @datatypes + * nss_ctx_instance \n + * nss_vxlan_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] nvm Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_vxlan_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_vxlan_msg *nvm); + +/** + * nss_vxlan_tx_msg_sync + * Sends a VxLAN message to the NSS synchronously. + * + * @datatypes + * nss_ctx_instance \n + * nss_vxlan_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] nvm Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_vxlan_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_vxlan_msg *nvm); + +/** + * nss_vxlan_unregister_if + * Deregisters the VxLAN interface from the NSS. + * + * @param[in] if_num NSS interface number. + * + * @return + * None. + */ +extern bool nss_vxlan_unregister_if(uint32_t if_num); + +/** + * nss_vxlan_register_if + * Registers the VxLAN interface with the NSS. + * + * @datatypes + * nss_vxlan_buf_callback_t \n + * nss_vxlan_msg_callback_t \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] type Dynamic interface type. + * @param[in] data_cb Callback for the data. + * @param[in] notify_cb Callback for the message. + * @param[in] netdev Pointer to the associated network device. + * @param[in] features Data socket buffer types supported by this interface. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_vxlan_register_if(uint32_t if_num, uint32_t type, nss_vxlan_buf_callback_t data_cb, + nss_vxlan_msg_callback_t notify_cb, struct net_device *netdev, uint32_t features); + +/** + * nss_vxlan_register_handler + * Initializes VxLAN module in NSS + * + * @return + * None. + */ +extern void nss_vxlan_init(void); + +/** + * nss_vxlan_msg_init + * Initializes a VxLAN message. + * + * @datatypes + * nss_vxlan_msg \n + * nss_vxlan_msg_callback_t + * + * @param[in,out] nvm Pointer to the VxLAN tunnel message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Size of the message. + * @param[in] cb Pointer to the message callback. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +extern void nss_vxlan_msg_init(struct nss_vxlan_msg *nvm, uint16_t if_num, uint32_t type, uint32_t len, + nss_vxlan_msg_callback_t cb, void *app_data); + +/** + * nss_vxlan_get_ctx() + * Get VxLAN context. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_vxlan_get_ctx(void); + +/** + * @} + */ + +#endif +/* __NSS_VXLAN_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_wifi.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_wifi.h new file mode 100644 index 000000000..e0456a11a --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_wifi.h @@ -0,0 +1,1011 @@ +/* + ************************************************************************** + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_wifi.h + * NSS TO HLOS Wi-Fi interface definitions. + */ + +#ifndef __NSS_WIFI_H +#define __NSS_WIFI_H + +/** + * @addtogroup nss_wifi_subsystem + * @{ + */ + +#define NSS_WIFI_MGMT_DATA_LEN 128 /**< Size of the Wi-Fi management data. */ +#define NSS_WIFI_FW_STATS_DATA_LEN 480 /**< Size of the firmware statictics data. */ +#define NSS_WIFI_RAWDATA_MAX_LEN 64 /**< Maximum size of the raw Wi-Fi data. */ +#define NSS_WIFI_TX_NUM_TOS_TIDS 8 /**< Number of TIDs. */ +#define NSS_WIFI_PEER_STATS_DATA_LEN 232 /**< Size of the peer statistics data. */ +#define NSS_WIFI_IPV6_ADDR_LEN 16 /**< Size of the IPv6 address. */ +#define NSS_WIFI_MAX_RSSI_CHAINS 4 /**< Maximum number of RSSI chains. */ +#define NSS_WIFI_WME_NUM_AC 4 /**< Number of ACs. */ + +/** + * Maximum number of Wi-Fi peers per radio as a sum of + * maximum number of station peers (513), + * maximum numbero of AP VAP peers (16), and + * maximum number of monitor VAP peers (1). + */ +#define NSS_WIFI_MAX_PEER 530 + +/** + * nss_wifi_metadata_types + * Wi-Fi interface request and response message types. + */ +enum nss_wifi_metadata_types { + NSS_WIFI_INIT_MSG, + NSS_WIFI_POST_RECV_MSG, + NSS_WIFI_HTT_INIT_MSG, + NSS_WIFI_TX_INIT_MSG, + NSS_WIFI_RAW_SEND_MSG, + NSS_WIFI_MGMT_SEND_MSG, + NSS_WIFI_WDS_PEER_ADD_MSG, + NSS_WIFI_WDS_PEER_DEL_MSG, + NSS_WIFI_STOP_MSG, + NSS_WIFI_RESET_MSG, + NSS_WIFI_STATS_MSG, + NSS_WIFI_PEER_FREELIST_APPEND_MSG, + NSS_WIFI_RX_REORDER_ARRAY_FREELIST_APPEND_MSG, + NSS_WIFI_SEND_PEER_MEMORY_REQUEST_MSG, + NSS_WIFI_SEND_RRA_MEMORY_REQUEST_MSG, + NSS_WIFI_FW_STATS_MSG, + NSS_WIFI_MONITOR_FILTER_SET_MSG, + NSS_WIFI_PEER_BS_STATE_MSG, + NSS_WIFI_MSDU_TTL_SET_MSG, + NSS_WIFI_RX_VOW_EXTSTATS_SET_MSG, + NSS_WIFI_PKTLOG_CFG_MSG, + NSS_WIFI_ENABLE_PERPKT_TXSTATS_MSG, + NSS_WIFI_IGMP_MLD_TOS_OVERRIDE_MSG, + NSS_WIFI_OL_STATS_CFG_MSG, + NSS_WIFI_OL_STATS_MSG, + NSS_WIFI_TX_QUEUE_CFG_MSG, + NSS_WIFI_TX_MIN_THRESHOLD_CFG_MSG, + NSS_WIFI_DBDC_PROCESS_ENABLE_MSG, + NSS_WIFI_PRIMARY_RADIO_SET_MSG, + NSS_WIFI_FORCE_CLIENT_MCAST_TRAFFIC_SET_MSG, + NSS_WIFI_STORE_OTHER_PDEV_STAVAP_MSG, + NSS_WIFI_STA_KICKOUT_MSG, + NSS_WIFI_WNM_PEER_RX_ACTIVITY_MSG, + NSS_WIFI_PEER_STATS_MSG, + NSS_WIFI_WDS_VENDOR_MSG, + NSS_WIFI_TX_CAPTURE_SET_MSG, + NSS_WIFI_ALWAYS_PRIMARY_SET_MSG, + NSS_WIFI_FLUSH_HTT_CMD_MSG, + NSS_WIFI_CMD_MSG, + NSS_WIFI_ENABLE_OL_STATSV2_MSG, + NSS_WIFI_OL_PEER_TIME_MSG, + NSS_WIFI_PEER_SET_VLAN_ID_MSG, + NSS_WIFI_PEER_ISOLATION_MSG, + NSS_WIFI_MAX_MSG +}; + +/* + * wifi_error_types + * Wi-Fi error types. + */ +enum wifi_error_types { + NSS_WIFI_EMSG_NONE = 0, + NSS_WIFI_EMSG_UNKNOWN, + NSS_WIFI_EMSG_MGMT_DLEN, + NSS_WIFI_EMSG_MGMT_SEND, + NSS_WIFI_EMSG_CE_INIT_FAIL, + NSS_WIFI_EMSG_PDEV_INIT_FAIL, + NSS_WIFI_EMSG_HTT_INIT_FAIL, + NSS_WIFI_EMSG_PEER_ADD, + NSS_WIFI_EMSG_WIFI_START_FAIL, + NSS_WIFI_EMSG_STATE_NOT_RESET, + NSS_WIFI_EMSG_STATE_NOT_INIT_DONE, + NSS_WIFI_EMSG_STATE_NULL_CE_HANDLE, + NSS_WIFI_EMSG_STATE_NOT_CE_READY, + NSS_WIFI_EMSG_STATE_NOT_HTT_READY, + NSS_WIFI_EMSG_FW_STATS_DLEN, + NSS_WIFI_EMSG_FW_STATS_SEND, + NSS_WIFI_EMSG_STATE_TX_INIT_FAILED, + NSS_WIFI_EMSG_IGMP_MLD_TOS_OVERRIDE_CFG, + NSS_WIFI_EMSG_PDEV_INVALID, + NSS_WIFI_EMSG_OTHER_PDEV_STAVAP_INVALID, + NSS_WIFI_EMSG_HTT_SEND_FAIL, + NSS_WIFI_EMSG_CE_RING_INIT, + NSS_WIFI_EMSG_NOTIFY_CB, + NSS_WIFI_EMSG_PEERID_INVALID, + NSS_WIFI_EMSG_PEER_INVALID, + NSS_WIFI_EMSG_UNKNOWN_CMD, + NSS_WIFI_EMSG_MAX, +}; + +/** + * nss_wifi_ext_data_pkt_type + * Exception types for Wi-Fi extended data. + */ +enum nss_wifi_ext_data_pkt_type { + NSS_WIFI_RX_EXT_INV_PEER_TYPE, + NSS_WIFI_RX_EXT_PKTLOG_TYPE, + NSS_WIFI_RX_STATS_V2_EXCEPTION, + NSS_WIFI_RX_MGMT_NULL_TYPE, + NSS_WIFI_RX_EXT_MAX_TYPE, +}; + +/** + * nss_wifi_cmd + * Wi-Fi commands. + */ +enum nss_wifi_cmd { + NSS_WIFI_FILTER_NEIGH_PEERS_CMD, + NSS_WIFI_MAX_CMD +}; + +/** + * nss_wifi_ce_ring_state_msg + * Internal state information for the copy engine ring. + */ +struct nss_wifi_ce_ring_state_msg { + uint32_t nentries; /**< Number of entries in the copy engine ring. */ + uint32_t nentries_mask; /**< Number of entry masks. */ + uint32_t sw_index; /**< Initial software index. */ + uint32_t write_index; /**< Initial write index. */ + uint32_t hw_index; /**< Initial hardware index. */ + uint32_t base_addr_CE_space; + /**< Physical address of the copy engine hardware ring. */ + uint32_t base_addr_owner_space; + /**< Virtual address of the copy engine hardware ring. */ +}; + +/** + * nss_wifi_ce_state_msg + * Internal state information for the copy engine. + */ +struct nss_wifi_ce_state_msg { + struct nss_wifi_ce_ring_state_msg src_ring; + /**< Source ring information. */ + struct nss_wifi_ce_ring_state_msg dest_ring; + /**< Destination ring information. */ + uint32_t ctrl_addr; + /**< Control address relative to PCIe BAR. */ +}; + +/** + * nss_wifi_init_msg + * Wi-Fi initialization data. + */ +struct nss_wifi_init_msg { + uint32_t radio_id ; /**< Radio index. */ + uint32_t pci_mem; /**< PCI memory address. */ + uint32_t target_type; /**< Wi-Fi target type. */ + uint32_t mu_mimo_enhancement_en; + /**< Enable MU-MIMO enhancement. */ + struct nss_wifi_ce_state_msg ce_tx_state; + /**< Transmit copy engine information. */ + struct nss_wifi_ce_state_msg ce_rx_state; + /**< Receive copy engine information. */ + + /** + * Indicates whether network processing is bypassed for this radio. + */ + uint32_t bypass_nw_process; +}; + +/** + * nss_wifi_htt_init_msg + * Wi-Fi Host-to-Target (HTT) initialization data. + */ +struct nss_wifi_htt_init_msg { + uint32_t radio_id; /**< Radio index. */ + uint32_t ringsize; /**< WLAN hardware MAC ring size. */ + uint32_t fill_level; /**< Initial fill level. */ + uint32_t paddrs_ringptr; + /**< Physical address of the WLAN MAC hardware ring. */ + uint32_t paddrs_ringpaddr; + /**< Virtual address of the WLAN MAC hardware ring. */ + uint32_t alloc_idx_vaddr; + /**< Virtual address of the hardware ring index. */ + uint32_t alloc_idx_paddr; + /**< Physical address of the hardware ring index. */ +}; + +/** + * nss_wifi_tx_init_msg + * Wi-Fi Tx initialization data. + */ +struct nss_wifi_tx_init_msg { + uint32_t radio_id; /**< Radio index. */ + uint32_t desc_pool_size; /**< Number of descriptor pools allocated. */ + uint32_t tx_desc_array; + /**< Host-initialized software WLAN descriptor pool memory. */ + uint32_t wlanextdesc_addr; + /**< Starting address of the WLAN MAC extenstion descriptor pool. */ + uint32_t wlanextdesc_size; + /**< Descriptor size of the WLAN MAC extenstion. */ + + /** + * Starting virtual address, as shared by the Wi-Fi firmware, for HTT Tx descriptor memory. + */ + uint32_t htt_tx_desc_base_vaddr; + + /** + * HTT Tx descriptor memory start physical address as shared by Wi-Fi firmware. + */ + uint32_t htt_tx_desc_base_paddr; + + uint32_t htt_tx_desc_offset; + /**< Descriptor size of the firmware shared HTT Tx. */ + uint32_t pmap_addr; + /**< Firmware shared peer or TID map. */ +}; + +/** + * nss_wifi_tx_queue_cfg_msg + * Wi-Fi Tx queue configuration. + */ +struct nss_wifi_tx_queue_cfg_msg { + uint32_t size; /**< Size of the Tx queue. */ + uint32_t range; /**< Peer range. */ +}; + +/** + * nss_wifi_tx_min_threshold_cfg_msg + * Minimum threshold configuration data for the Wi-Fi Tx queue. + */ +struct nss_wifi_tx_min_threshold_cfg_msg { + uint32_t min_threshold; /**< Minimum threshold value of Tx queue. */ +}; + +/** + * nss_wifi_rawsend_msg + * Information for Wi-Fi raw data. + */ +struct nss_wifi_rawsend_msg { + uint32_t radio_id ; /**< Radio index. */ + uint32_t len; /**< Size of the raw data. */ + uint32_t array[NSS_WIFI_RAWDATA_MAX_LEN]; + /**< Array of raw data. */ +}; + +/** + * nss_wifi_mgmtsend_msg + * Information for Wi-Fi management data. + */ +struct nss_wifi_mgmtsend_msg { + uint32_t desc_id; /**< Descriptor index. */ + uint32_t len; /**< Size of the management data. */ + uint8_t array[NSS_WIFI_MGMT_DATA_LEN]; + /**< Array of management data. */ +}; + +/** + * nss_wifi_fw_stats_msg + * Information for Wi-Fi firmware statistics. + */ +struct nss_wifi_fw_stats_msg { + uint32_t len; /**< Size of the statistics data. */ + uint8_t array[NSS_WIFI_FW_STATS_DATA_LEN]; + /**< Array of statistics data. */ +}; + +/** + * nss_wifi_monitor_set_filter_msg + * Wi-Fi Monitor mode for setting filter messages. + */ +struct nss_wifi_monitor_set_filter_msg { + uint32_t filter_type; /**< Type of Monitor mode filter. */ +}; + +/** + * nss_wifi_wds_peer_msg + * Wi-Fi WDS peer-specific message. + */ +struct nss_wifi_wds_peer_msg { + uint8_t dest_mac[ETH_ALEN]; /**< MAC address of the destination. */ + uint8_t reserved[2]; /**< Reserved for 4-byte alignment padding. */ + uint8_t peer_mac[ETH_ALEN]; /**< MAC address of the base peer. */ + uint8_t reserved1[2]; /**< Reserved for 4-byte alignment padding. */ +}; + +/** + * nss_wifi_tx_capture_msg + * Wi-Fi Tx data capture configuration. + */ +struct nss_wifi_tx_capture_msg { + uint32_t tx_capture_enable; /**< Enable or disable Tx data capture. */ +}; + +/** + * nss_wifi_reset_msg + * Message to reset the Wi-Fi Radio. + */ +struct nss_wifi_reset_msg { + uint32_t radio_id; /**< Radio index. */ +}; + +/** + * nss_wifi_stop_msg + * Message to stop the Wi-Fi Radio. + */ +struct nss_wifi_stop_msg { + uint32_t radio_id; /**< Radio index. */ +}; + +/** + * nss_wifi_pktlog_cfg_msg + * Configuration information for a Wi-Fi packet log. + */ +struct nss_wifi_pktlog_cfg_msg { + uint32_t enable; /**< Enables or disables a packet log. */ + uint32_t bufsize; /**< Size of the packet log buffer. */ + uint32_t hdrsize; /**< Size of the packet log header. */ + uint32_t msdu_id_offset; /**< Offset for the MSDU ID in the message. */ +}; + +/** + * nss_wifi_ol_stats_cfg_msg + * Wi-Fi offload statistics configuration. + */ +struct nss_wifi_ol_stats_cfg_msg { + uint32_t stats_cfg; /**< Enable or disable offload statistics configuration. */ +}; + +/** + * nss_wifi_enable_perpkt_txstats_msg + * Wi-Fi per-packet Tx statistics configuration. + */ +struct nss_wifi_enable_perpkt_txstats_msg { + uint32_t perpkt_txstats_flag; /**< Enable or disable Tx statistics. */ +}; + +/** + * nss_wifi_peer_txtime_stats + * Peer Tx timestamp statistics per TID. + */ +struct nss_wifi_peer_txtime_stats { + uint32_t sum_tx; /**< Sum of sojourn for each packet. */ + uint32_t sum_msdus; /**< Number of MSDU per peer per TID. */ +}; + +/** + * nss_wifi_peer_tstamp_stats + * Peer ID and timestamp statistics per TID. + */ +struct nss_wifi_peer_tstamp_stats { + uint32_t peer_id; /**< TID value. */ + struct nss_wifi_peer_txtime_stats sum[NSS_WIFI_TX_NUM_TOS_TIDS]; + /**< Timestamps. */ + uint32_t avg[NSS_WIFI_TX_NUM_TOS_TIDS]; /**< Exponential weighted average. */ +}; + +/** + * nss_wifi_ol_peer_time_msg + * NSS Wi-Fi Tx timestamp message for n number of peers. + */ +struct nss_wifi_ol_peer_time_msg { + uint32_t npeers; /**< Number of peers. */ + struct nss_wifi_peer_tstamp_stats tstats[1]; + /**< One instance of struct. */ +}; + +/** + * nss_wifi_enable_ol_statsv2 + * Wi-Fi enable/disable send packet to host. + */ +struct nss_wifi_enable_ol_statsv2 { + uint32_t enable_ol_statsv2; /**< Flag to send packet to host. */ +}; + +/** + * nss_wifi_dbdc_process_enable_msg + * Wi-Fi DBDC repeater process configuration. + */ +struct nss_wifi_dbdc_process_enable_msg { + uint32_t dbdc_process_enable; /**< Enable or disable the DBDC process. */ +}; + +/** + * nss_wifi_primary_radio_set_msg + * Wi-Fi primary radio configuration message. + */ +struct nss_wifi_primary_radio_set_msg { + /** + * Enable/Disable Flag to set the current radio as primary. + */ + uint32_t flag; +}; + +/** + * nss_wifi_always_primary_set_msg + * Always set the Wi-Fi primary radio. + * + * The primary radio is set using the nss_wifi_primary_radio_set_msg flag. + * When the nss_wifi_always_primary_set_msg flag is set: + * - Tx -- Do not drop a unicast packet on the secondary station the VAP. Instead, give that + * packet to the primary station the VAP. + * - Rx -- Do not drop a received unicast packet on the secondary station the VAP. Instead, + * give that packet to the bridge by changing the SKB device as the primary station + * VAP. + * + * Primary usage of this feature is to avoid a loopback. + */ +struct nss_wifi_always_primary_set_msg { + /** + * Always use the primary radio for Tx and Rx in the DBDC repeater process. + */ + uint32_t flag; +}; + +/** + * nss_wifi_force_client_mcast_traffic_set_msg + * Wi-Fi message to set the client multi-cast traffic for a radio. + */ +struct nss_wifi_force_client_mcast_traffic_set_msg { + uint32_t flag; /**< Flag to force set the multi-cast traffic in a radio. */ +}; + +/** + * wifi_store_other_pdev_stavap_msg + * Store the other radio's station vap. + */ +struct nss_wifi_store_other_pdev_stavap_msg { + int stavap_ifnum; /**< Station VAP interface number of the other radio. */ +}; + +/** + * nss_wifi_pl_metadata + * Wi-Fi packet log metadata. + */ +struct nss_wifi_pl_metadata { + uint32_t len; /**< Length of single buffer in MSDU. */ + uint32_t msdu_len; /**< Total MSDU length. */ + uint16_t da_tail; /**< Destination address tail bytes. */ + uint16_t sa_tail; /**< Source address tail bytes. */ + uint8_t vdev_id; /**< Virtual device ID. */ + uint8_t res1; /**< Reserved for alignment. */ + uint16_t res2; /**< Reserved for alignment. */ +}; + +/** + * nss_wifi_rx_ext_metadata + * Wi-Fi Rx extended data plane metadata. + */ +struct nss_wifi_rx_ext_metadata{ + uint16_t peer_id; /**< ID of associated Peer. */ + uint8_t htt_rx_status; /**< Rx status of the HTT. */ + uint8_t type; /**< Reserved for 4 byte alignment. */ +}; + +/** + * nss_wifi_mc_enhance_stats + * Wi-Fi multicast enhancement statistics. + */ +struct nss_wifi_mc_enhance_stats { + uint32_t rcvd; /**< Number of multicast frames received for conversion. */ + + /** + * Number of unicast frames sent as part of multicast enhancement conversion. + */ + uint32_t ucast_converted; + + /** + * Number of multicast enhancement frames dropped because of an allocation + * failure. + */ + uint32_t alloc_fail; + + /** + * Number of multicast enhancement frames dropped because of an enqueue failure. + */ + uint32_t enqueue_fail; + + /** + * Number of multicast enhancement frames dropped because of a copy failure. + */ + uint32_t copy_fail; + + /** + * Number of multicast enhancement frames dropped because of a peer flow control + * send failure. + */ + uint32_t peer_flow_ctrl_send_fail; + + /** + * Number of multicast enhancement frames dropped when the destination MAC + * address is the same as the source MAC address. + */ + uint32_t loopback_err; + + /** + * Number of multicast enhancement buffer frames dropped because of an empty + * destination MAC address. + */ + uint32_t dst_addr_err; +}; + +/** + * nss_wifi_stats_sync_msg + * Wi-Fi synchronization statistics. + */ +struct nss_wifi_stats_sync_msg { + struct nss_cmn_node_stats node_stats; /**< Common node statistics. */ + uint32_t tx_transmit_dropped; + /**< Number of packets dropped during transmission. */ + uint32_t tx_transmit_completions; + /**< Number of packets for which Tx completions are received. */ + uint32_t tx_mgmt_rcv_cnt; + /**< Number of management packets received from the host for Tx. */ + uint32_t tx_mgmt_pkts; + /**< Number of management packets transmitted over Wi-Fi. */ + + /** + * Number of management packets dropped because of a Tx failure. + */ + uint32_t tx_mgmt_dropped; + + /** + * Number of management packets for which Tx completions are received. + */ + uint32_t tx_mgmt_completions; + + /** + * Number of packets for which an Tx enqueue failed because of an invalid peer. + */ + uint32_t tx_inv_peer_enq_cnt; + + /** + * Number of packets with an invalid peer ID received from Wi-Fi. + */ + uint32_t rx_inv_peer_rcv_cnt; + + uint32_t rx_pn_check_failed; + /**< Number of Rx packets that failed a packet number check. */ + + /** + * Number of Rx packets that the Wi-Fi driver successfully processed. + */ + uint32_t rx_pkts_deliverd; + + /** + * Number of Rx bytes that the Wi-Fi driver successfully processed. + */ + uint32_t rx_bytes_deliverd; + + uint32_t tx_bytes_transmit_completions; + /**< Number of bytes for which Tx completions are received. */ + + /** + * Number of unaligned data packets that were received from Wi-Fi and dropped. + */ + uint32_t rx_deliver_unaligned_drop_cnt; + + uint32_t tidq_enqueue_cnt[NSS_WIFI_TX_NUM_TOS_TIDS]; + /**< Number of packets enqueued to TID Queue (TIDQ). */ + uint32_t tidq_dequeue_cnt[NSS_WIFI_TX_NUM_TOS_TIDS]; + /**< Number of packets dequeued from TIDQ. */ + uint32_t tidq_enqueue_fail_cnt[NSS_WIFI_TX_NUM_TOS_TIDS]; + /**< Number of enqueue failures. */ + uint32_t tidq_ttl_expire_cnt[NSS_WIFI_TX_NUM_TOS_TIDS]; + /**< Number of packets expired from TIDQ. */ + uint32_t tidq_dequeue_req_cnt[NSS_WIFI_TX_NUM_TOS_TIDS]; + /**< Number of dequeue requests from the Wi-Fi firmware. */ + uint32_t total_tidq_depth; + /**< Current queue Depth. */ + + /** + * Total number of HTT fetch messages received from the Wi-Fi firmware. + */ + uint32_t rx_htt_fetch_cnt; + + /** + * Total number of packets that bypassed TIDQ and are sent to the Wi-Fi + * firmware. + */ + uint32_t total_tidq_bypass_cnt; + + /** + * Total number of packets dropped because of a global queue full condition. + */ + uint32_t global_q_full_cnt; + + /** + * Total number of packets dropped because of a TID queue full condition. + */ + uint32_t tidq_full_cnt; + + struct nss_wifi_mc_enhance_stats mc_enhance_stats; + /**< Multicast enhancement statistics. */ + + /** + * Number of times a group entry was not present for multicast enhancement. + */ + uint32_t mc_enhance_group_entry_miss; + + /** + * Number of times a deny list was hit during multicast enhancement. + */ + uint32_t mc_enhance_denylist_hit; +}; + +/** + * nss_wifi_peer_freelist_append_msg + * Information for creating a Wi-Fi peer freelist. + */ +struct nss_wifi_peer_freelist_append_msg { + uint32_t addr; /**< Starting address of peer freelist pool. */ + uint32_t length; /**< Size of peer freelist pool. */ + uint32_t num_peers; /**< Maximum peer entries supported in the pool. */ +}; + +/** + * nss_wifi_rx_reorder_array_freelist_append_msg + * Information for creating a Wi-Fi TIDQ peer freelist array. + */ +struct nss_wifi_rx_reorder_array_freelist_append_msg { + uint32_t addr; /**< Starting address of the TIDQ freelist pool. */ + uint32_t length; /**< Size of the TIDQ freelist pool. */ + + /** + * Maximum number of Rx reorder array entries supported in the freelist pool. + */ + uint32_t num_rra; +}; + +/** + * wifi_bs_peer_inactivity + * Active state information of the peer. + */ +struct nss_wifi_bs_peer_activity { + uint16_t nentries; /**< Number of entries in the peer ID array. */ + uint16_t peer_id[1]; /**< Array holding the peer IDs. */ +}; + +/** + * nss_wifi_msdu_ttl_set_msg + * Information for setting the Wi-Fi MSDU time-to-live value. + */ +struct nss_wifi_msdu_ttl_set_msg { + uint32_t msdu_ttl; /**< TTL value to be set. */ +}; + +/** + * nss_wifi_rx_vow_extstats_set_msg + * VoW extended statitics set. + */ +struct nss_wifi_rx_vow_extstats_set_msg { + uint32_t vow_extstats_en; /**< VoW extended statistics enable. */ +}; + +/** + * nss_wifi_igmp_mld_override_tos_msg + * Information for overriding TOS. + */ +struct nss_wifi_igmp_mld_override_tos_msg { + uint8_t igmp_mld_ovride_tid_en; + /**< Flag to enable TID override feature for IGMP/MLD configuration. */ + uint8_t igmp_mld_ovride_tid_val; + /**< Value of TID to be overriden for IGMP/MLD. */ + uint8_t res[2]; /**< Reserved for 4-byte alignment. */ +}; + +/** + * nss_wifi_peer_ol_stats + * Wi-Fi offload statistics. + */ +struct nss_wifi_peer_ol_stats { + uint32_t peer_id; /**< ID of associated peer. */ + uint32_t seq_num; /**< Sequence number of the PPDU. */ + uint32_t tx_unaggr; /**< Number of unaggregated packets transmitted. */ + uint32_t tx_aggr; /**< Number of aggregated packets transmitted. */ + uint32_t tx_mcast; /**< Number of multicast packets sent. */ + uint32_t tx_ucast; /**< Number of unicast packets sent. */ + uint32_t tx_data; /**< Number data packets sent. */ + uint32_t tx_bytes; /**< Number of bytes sent. */ + uint32_t tx_fail; /**< Number of failed Tx packets. */ + uint32_t thrup_bytes; /**< Number of throughput bytes. */ + uint32_t tx_bcast_pkts; /**< Number of broadcast packets sent. */ + uint32_t tx_bcast_bytes;/**< Number of broadcast bytes sent. */ + uint32_t tx_mgmt; /**< Number of Tx management frames. */ + uint32_t tx_wme[NSS_WIFI_WME_NUM_AC]; + /**< Data frames transmitted per AC. */ + uint32_t rx_wme[NSS_WIFI_WME_NUM_AC]; + /**< Data frames received per AC. */ + uint32_t ppdu_retries; /**< Number of PPDU retries. */ + uint32_t rssi_chains[NSS_WIFI_MAX_RSSI_CHAINS]; + /**< Acknowledgment RSSI per chain. */ +}; + +/** + * nss_wifi_ol_stats_msg + * Wi-Fi offload statistics. + */ +struct nss_wifi_ol_stats_msg { + uint32_t bawadv_cnt; /**< Number of block-acknowledgment window advancements. */ + uint32_t bcn_cnt; /**< Number of beacons. */ + uint32_t npeers; /**< Number of peer statistics entries. */ + struct nss_wifi_peer_ol_stats peer_ol_stats[1]; + /**< Array to hold the peer statistics. */ +}; + +/** + * nss_wifi_sta_kickout_msg + * Station kickout message from NSS Firmware + */ +struct nss_wifi_sta_kickout_msg { + uint32_t peer_id; /**< Peer ID. */ +}; + +/** + * nss_wifi_peer_isolation_msg + * Peer isolation message + */ +struct nss_wifi_peer_isolation_msg { + uint16_t peer_id; /**< Peer ID. */ + uint16_t isolation; /**< Isolation enabled/disabled. */ +}; + +/** + * nss_wifi_wnm_peer_rx_activity_msg + * Rx active state information for the peer. + */ +struct nss_wifi_wnm_peer_rx_activity_msg { + uint16_t nentries; /**< Number of entries. */ + + /** + * Array to hold the peer IDs for which the activity is reported. + */ + uint16_t peer_id[NSS_WIFI_MAX_PEER]; +}; + +/** + * nss_wifi_append_metaheader + * Append metaheader after pbuf->data for stats_v2. + */ +struct nss_wifi_append_statsv2_metahdr { + uint32_t rxstatsmagic; /**< Magic to be verified on host. */ + uint32_t seq_number; /**< Sequence number of packets sent from NSS. */ + uint16_t peer_id; /**< Peer ID of peer. */ + uint16_t num_msdus; /**< Number of MSDU in PPDU. */ + uint16_t num_retries; /**< Number of retries in PPDU. */ + uint16_t num_mpdus; /**< Number of MPDU in PPDU. */ + uint32_t num_bytes; /**< Number of bytes in PPDU. */ +}; + +/** + * nss_wifi_peer_stats_msg + * Wi-Fi peer statistics. + */ +struct nss_wifi_peer_stats_msg { + uint32_t peer_id; /**< Peer ID. */ + uint32_t tidq_byte_cnt[NSS_WIFI_TX_NUM_TOS_TIDS]; + /**< Number of bytes in each TIDQ. */ + uint32_t tidq_queue_max[NSS_WIFI_TX_NUM_TOS_TIDS]; + /**< Maximum depth for the TID queue. */ + uint32_t tidq_enqueue_cnt[NSS_WIFI_TX_NUM_TOS_TIDS]; + /**< Number of packets enqueued to the TIDQ. */ + uint32_t tidq_dequeue_cnt[NSS_WIFI_TX_NUM_TOS_TIDS]; + /**< Number of packets dequeued from the TIDQ. */ + uint32_t tidq_ttl_expire_cnt[NSS_WIFI_TX_NUM_TOS_TIDS]; + /**< Number of expired packets from the TIDQ. */ + uint32_t tidq_dequeue_req_cnt[NSS_WIFI_TX_NUM_TOS_TIDS]; + /**< Number of dequeue requests from the Wi-Fi firmware. */ + + /** + * Total number of packets dropped because the TID queue is full. + */ + uint32_t tidq_full_cnt[NSS_WIFI_TX_NUM_TOS_TIDS]; +}; + +/** + * nss_wifi_wds_extn_peer_cfg_msg + * Configuration information when the WDS extension is enabled. + */ +struct nss_wifi_wds_extn_peer_cfg_msg { + uint8_t mac_addr[ETH_ALEN]; /**< Mac address of the peer. */ + uint8_t wds_flags; /**< WDS flags populated from the host. */ + uint8_t reserved; /**< Alignment padding. */ + uint16_t peer_id; /**< ID of the peer. */ +}; + +/** + * nss_wifi_cmd_msg + * Wi-Fi radio specific special commands to NSS Firmware + */ +struct nss_wifi_cmd_msg { + uint32_t cmd; /**< Type of command message. */ + uint32_t value; /**< Value of the command. */ +}; + +/** + * nss_wifi_msg + * Data for sending and receiving Wi-Fi messages. + */ +struct nss_wifi_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Message Payload. + */ + union { + struct nss_wifi_init_msg initmsg; + /**< Wi-Fi Radio initialization message. */ + struct nss_wifi_stop_msg stopmsg; + /**< Wi-Fi Radio stop message. */ + struct nss_wifi_reset_msg resetmsg; + /**< Wi-Fi Radio reset message. */ + struct nss_wifi_htt_init_msg httinitmsg; + /**< HTT initialization message. */ + struct nss_wifi_tx_init_msg pdevtxinitmsg; + /**< Tx initialization message. */ + struct nss_wifi_rawsend_msg rawmsg; + /**< Wi-Fi raw data send message. */ + struct nss_wifi_mgmtsend_msg mgmtmsg; + /**< Wi-Fi management data send message. */ + struct nss_wifi_wds_peer_msg pdevwdspeermsg; + /**< WDS peer-specific message. */ + struct nss_wifi_stats_sync_msg statsmsg; + /**< Synchronization statistics. */ + struct nss_wifi_peer_freelist_append_msg peer_freelist_append; + /**< Message for creating/appending peer freelist memory. */ + + /** + * Message for creating/appending a reorder array for Wi-Fi Receive Defragmentation. + */ + struct nss_wifi_rx_reorder_array_freelist_append_msg rx_reorder_array_freelist_append; + + struct nss_wifi_fw_stats_msg fwstatsmsg; + /**< Wi-Fi firmware statistics information message. */ + struct nss_wifi_monitor_set_filter_msg monitor_filter_msg; + /**< Set the filter message for Monitor mode. */ + struct nss_wifi_bs_peer_activity peer_activity; + /**< Message to get the active peer for a radio. */ + struct nss_wifi_msdu_ttl_set_msg msdu_ttl_set_msg; + /**< Set MSDU time-to-live. */ + struct nss_wifi_rx_vow_extstats_set_msg vow_extstats_msg; + /**< Enable VoW extended statistics message. */ + struct nss_wifi_pktlog_cfg_msg pcm_msg; + /**< Packet log configuration message. */ + struct nss_wifi_enable_perpkt_txstats_msg ept_msg; + /**< Enable or disable per-packet Tx statistics. */ + struct nss_wifi_igmp_mld_override_tos_msg wigmpmldtm_msg; + /**< Message to enable TID override for IGMP/MLD. */ + struct nss_wifi_ol_stats_cfg_msg scm_msg; + /**< Enable or disable offload statistics configuration. */ + struct nss_wifi_ol_stats_msg ol_stats_msg; + /**< Offload statistics. */ + struct nss_wifi_tx_queue_cfg_msg wtxqcm; + /**< Tx queue configuration. */ + + /** + * Minimum threshold configuration data for the Tx queue. + */ + struct nss_wifi_tx_min_threshold_cfg_msg wtx_min_threshold_cm; + + struct nss_wifi_dbdc_process_enable_msg dbdcpe_msg; + /**< Enable or disable the DBDC repeater process. */ + struct nss_wifi_primary_radio_set_msg wprs_msg; + /**< Set the current radio as the primary radio. */ + struct nss_wifi_force_client_mcast_traffic_set_msg wfcmts_msg; + /**< Message to force multicast traffic for a radio. */ + struct nss_wifi_store_other_pdev_stavap_msg wsops_msg; + /**< Message to store the other radio's station vap. */ + struct nss_wifi_sta_kickout_msg sta_kickout_msg; + /**< Station kickout message from NSS firmware. */ + struct nss_wifi_wnm_peer_rx_activity_msg wprm; + /**< Rx activity for the peer. */ + struct nss_wifi_peer_stats_msg peer_stats_msg; + /**< Peer statistics message. */ + struct nss_wifi_wds_extn_peer_cfg_msg wpeercfg; + /**< Configuartion information message when the WDS extension is enabled. */ + struct nss_wifi_tx_capture_msg tx_capture_msg; + /**< Enable or disable Tx data capture. */ + struct nss_wifi_always_primary_set_msg waps_msg; + /**< Message to always set the current radio as primary radio. */ + struct nss_wifi_cmd_msg wcmdm; + /**< Pdev command information. */ + struct nss_wifi_enable_ol_statsv2 wesh_msg; + /**< Enable version 2 tx/rx stats. */ + struct nss_wifi_ol_peer_time_msg wopt_msg; + /**< Send per peer/TID timestamp statistics to host. */ + struct nss_wifi_peer_isolation_msg isolation_msg; + /**< Enable or disable peer isolation. */ + } msg; /**< Message Payload. */ +}; + +/** + * nss_wifi_get_context + * Gets the Wi-Fi context used in nss_gre_tx. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_wifi_get_context(void); + +/** + * nss_wifi_tx_msg + * Sends a Wi-Fi message to the NSS firmware. + * + * @datatypes + * nss_ctx_instance \n + * nss_wifi_if_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_wifi_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_wifi_msg *msg); + +/** + * Callback function for receiving Wi-Fi messages. + * + * @datatypes + * nss_wifi_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_wifi_msg_callback_t)(void *app_data, struct nss_wifi_msg *msg); + +/** + * Callback function for receiving Wi-Fi data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_wifi_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * nss_register_wifi_if + * Registers the Wi-Fi interface with the NSS for sending and receiving messages. + * + * @datatypes + * nss_wifi_callback_t \n + * nss_wifi_msg_callback_t \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] wifi_callback Callback for the data. + * @param[in] wifi_ext_callback Callback for the extended data. + * @param[in] event_callback Callback for the message. + * @param[in] netdev Pointer to the associated network device. + * @param[in] features Data socket buffer types supported by this interface. + * + * @return + * Pointer to the NSS core context. + */ +struct nss_ctx_instance *nss_register_wifi_if(uint32_t if_num, nss_wifi_callback_t wifi_callback, + nss_wifi_callback_t wifi_ext_callback, nss_wifi_msg_callback_t event_callback, struct net_device *netdev, uint32_t features); + +/** + * nss_unregister_wifi_if + * Deregisters the Wi-Fi interface from the NSS. + * + * @param[in] if_num NSS interface number. + * + * @return + * None. + */ +void nss_unregister_wifi_if(uint32_t if_num); + +/** + * @} + */ + +#endif /* __NSS_WIFI_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_wifi_ext_vdev_if.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_wifi_ext_vdev_if.h new file mode 100644 index 000000000..4684c6b33 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_wifi_ext_vdev_if.h @@ -0,0 +1,283 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_wifi_ext_vdev_if.h + * NSS Wi-Fi extended virtual device interface definitions. + */ + +#ifndef __NSS_WIFI_EXT_VDEV_IF_H +#define __NSS_WIFI_EXT_VDEV_IF_H + +#define NSS_WIFI_EXT_VDEV_MAX 16 + +/* + * nss_wifi_ext_vdev_msg_types + * WiFi extension virtual device mesage types. + */ +enum nss_wifi_ext_vdev_msg_types { + NSS_WIFI_EXT_VDEV_MSG_CONFIGURE_IF = NSS_IF_MAX_MSG_TYPES + 1, + NSS_WIFI_EXT_VDEV_MSG_CONFIGURE_WDS, + NSS_WIFI_EXT_VDEV_SET_NEXT_HOP, + NSS_WIFI_EXT_VDEV_MSG_STATS_SYNC, + NSS_WIFI_EXT_VDEV_MSG_MAX +}; + +/** + * nss_wifi_ext_vdev_error_tyes + * WiFi extension error types. + */ +enum nss_wifi_ext_vdev_error_types { + NSS_WIFI_EXT_VDEV_ERROR_NONE = NSS_IF_ERROR_TYPE_MAX + 1, + /** Configuration successful. */ + NSS_WIFI_EXT_VDEV_ERROR_NULL_MAC, /**< NULL MAC received. */ + NSS_WIFI_EXT_VDEV_ERROR_INV_RADIO_ID, /**< Invalid radio interface number. */ + NSS_WIFI_EXT_VDEV_ERROR_INV_PVAP_ID, /**< Invalid parent virtual device interface number. */ + NSS_WIFI_EXT_VDEV_ERROR_RADIO_NOT_PRESENT, /**< Radio node is not present. */ + NSS_WIFI_EXT_VDEV_ERROR_INV_IF, /**< Message sent on invalid interface number. */ + NSS_WIFI_EXT_VDEV_ERROR_MAX, /**< Maxiumum error types. */ +}; + +/** + * nss_wifi_ext_vdev_wds_msg + * Extended WDS config message. + */ +struct nss_wifi_ext_vdev_wds_msg { + uint16_t wds_peer_id; /**< WDS station peer ID. */ + uint16_t mac_addr[3]; /**< Remote MAC address. */ +}; + +/** + * nss_wifi_ext_vdev_stats + * Statistics message structure. + */ +struct nss_wifi_ext_vdev_stats { + struct nss_cmn_node_stats node_stats; /**< Ethernet node statistics. */ + uint32_t mc_count; /**< Number of mulitcast counts. */ + uint32_t nxt_hop_drp; /**< Next hop drop. */ +}; + +/** + * nss_wifi_vdev_config_msg + * NSS Wi-Fi virtual device configuration message. + */ +struct nss_wifi_ext_vdev_configure_if_msg { + uint8_t mac_addr[ETH_ALEN]; /**< MAC address. */ + uint16_t radio_ifnum; /**< Radio interface corresponding to virtual AP. */ + uint16_t pvap_ifnum; /**< Parent virtual device interface number. */ +}; + +/** + * nss_wifi_ext_vdev_set_next_hop_msg + * Message to set the next hop. + */ +struct nss_wifi_ext_vdev_set_next_hop_msg { + uint32_t if_num; /**< Interface number. */ +}; + +/** + * nss_wifi_ext_vdev_msg + * Message structure to Send/Receive commands. + */ +struct nss_wifi_ext_vdev_msg { + struct nss_cmn_msg cm; /**< Cnode message. */ + union { + union nss_if_msgs if_msg; /**< NSS interface base message. */ + struct nss_wifi_ext_vdev_configure_if_msg cmsg; /**< Interface configuration message. */ + struct nss_wifi_ext_vdev_wds_msg wmsg; /**< WDS configure message. */ + struct nss_wifi_ext_vdev_set_next_hop_msg wnhm; /**< Next hop set message. */ + struct nss_wifi_ext_vdev_stats stats; /**< Statistics messasge. */ + } msg; +}; + +/** + * Callback function for receiving Wi-Fi extended virtual device data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_wifi_ext_vdev_data_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * Callback function for receiving Wi-Fi extended virtual device messages. + * + * @datatypes + * nss_wifi_ext_vdev_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in]wevm Pointer to the message data. + */ +typedef void (*nss_wifi_ext_vdev_msg_callback_t)(void *app_data, struct nss_cmn_msg *ncm); + +/** + * Callback function for receiving extended data from the Wi-Fi extended virtual device interface. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + * @param[in] netdev Pointer to the associated network device. + */ +typedef void (*nss_wifi_ext_vdev_ext_data_callback_t)(struct net_device *netdev, + struct sk_buff *skb, struct napi_struct *napi); +/** + * nss_wifi_ext_vdev_msg_init + * Initializes a Wi-Fi extended virtual device message. + * + * @datatypes + * nss_wifi_vdev_msg \n + * nss_wifi_vdev_msg_callback_t + * + * @param[in] nim Pointer to the NSS interface message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Length of message. + * @param[in] cb Message callback. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +void nss_wifi_ext_vdev_msg_init(struct nss_wifi_ext_vdev_msg *nim, uint32_t if_num, uint32_t type, uint32_t len, + nss_wifi_ext_vdev_msg_callback_t cb, void *app_data); + +/** + * nss_wifi_ext_vdev_unregister_if + * Deregisters a Wi-Fi extended virtual interface from the NSS. + * + * @param[in] if_num Wi-Fi extended virtual interface number. + * + * @return + * None. + * + * @dependencies + * The Wi-Fi extended virtual interface must have been previously registered. + * + * @return + * True if successful, else false. + */ +extern bool nss_wifi_ext_vdev_unregister_if(uint32_t if_num); + +/** + * nss_wifi_ext_vdev_tx_buf + * Sends data buffers to NSS firmware asynchronously. + * + * @datatypes + * nss_ctx_instance \n + * sk_buff + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] os_buf Pointer to the OS buffer (e.g. skbuff). + * @param[in] if_num Wi-Fi extended virtual interface number. + * + * @return + * Status of the transmit operation. + */ +extern nss_tx_status_t nss_wifi_ext_vdev_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf, + uint32_t if_num); + +/** + * nss_wifi_ext_vdev_tx_msg + * Sends Wi-Fi extended virtual interface messages. + * + * @datatypes + * nss_ctx_instance \n + * nss_wifi_ext_vdev_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] wevm Pointer to the message data. + * + * @return + * Status of the transmit operation. + */ +extern nss_tx_status_t nss_wifi_ext_vdev_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_wifi_ext_vdev_msg *wevm); + +/** + * nss_wifi_ext_vdev_tx_msg_sync + * Sends messages to NSS firmware synchronously. + * + * @datatypes + * nss_ctx_instance \n + * nss_wifi_ext_vdev_msg + * + * @param[in] nss_ctx NSS core context. + * @param[in] nwevm Pointer to Wi-Fi extended virtual interface message data. + * + * @return + * Status of the transmit operation. + */ +extern nss_tx_status_t nss_wifi_ext_vdev_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_wifi_ext_vdev_msg *nwevm); + +/** + * nss_wifi_ext_vdev_set_next_hop + * Sets the extended virtual interface next hop. + * + * @datatypes + * nss_ctx_instance \n + * + * @param[in] nss_ctx NSS core context. + * @param[in] ifnum NSS interface number. + * @param[in] next_hop Next hop interface number. + */ +extern nss_tx_status_t nss_wifi_ext_vdev_set_next_hop(struct nss_ctx_instance *ctx, int if_num, int next_hop); + +/** + * nss_wifi_ext_vdev_get_ctx + * Gets the NSS Wi-Fi extended virtual interface context. + * + * @return + * Pointer to the NSS core context. + */ +extern struct nss_ctx_instance *nss_wifi_ext_vdev_get_ctx(void); + +/** + * nss_wifi_ext_vdev_register_if + * Registers Wi-Fi extended virtual interface with NSS. + * + * @datatypes + * net_device \n + * nss_wifi_ext_vdev_data_callback_t \n + * nss_wifi_ext_vdev_ext_data_callback_t \n + * nss_wifi_ext_vdev_msg_callback_t + * + * @param[in] if_num NSS interface number. + * @param[in] cb_func_data Callback for the data. + * @param[in] cb_func_msg Callback for the message. + * @param[in] cb_func_event Callback for the event message. + * @param[in] features Data socket buffer types supported by this interface. + * @param[in] netdev Pointer to the associated network device. + * @param[in] app_ctx Pointer to the application context. + * + * @return + * NSS interface number allocated. + */ +extern struct nss_ctx_instance *nss_wifi_ext_vdev_register_if(uint32_t if_num, + nss_wifi_ext_vdev_data_callback_t cb_func_data, nss_wifi_ext_vdev_ext_data_callback_t cb_func_ext, + nss_wifi_ext_vdev_msg_callback_t cb_func_msg, struct net_device *netdev, uint32_t features, + void *app_ctx); +#endif diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_wifi_if.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_wifi_if.h new file mode 100644 index 000000000..3ef2b13bc --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_wifi_if.h @@ -0,0 +1,292 @@ +/* + ************************************************************************** + * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_wifi_if.h + * NSS Wi-Fi interface message Structure and APIs. + */ + +#ifndef __NSS_WIFI_IF_H +#define __NSS_WIFI_IF_H + +/** + * @addtogroup nss_wifi_subsystem + * @{ + */ + +/** + * nss_wifi_if_msg_types + * Message types for Wi-Fi interface requests and responses. + */ +enum nss_wifi_if_msg_types { + NSS_WIFI_IF_OPEN = NSS_IF_OPEN, + NSS_WIFI_IF_CLOSE = NSS_IF_CLOSE, + NSS_WIFI_IF_LINK_STATE_NOTIFY = NSS_IF_LINK_STATE_NOTIFY, + NSS_WIFI_IF_MTU_CHANGE = NSS_IF_MTU_CHANGE, + NSS_WIFI_IF_MAC_ADDR_SET = NSS_IF_MAC_ADDR_SET, + NSS_WIFI_IF_STATS_SYNC = NSS_IF_STATS, + NSS_WIFI_IF_ISHAPER_ASSIGN = NSS_IF_ISHAPER_ASSIGN, + NSS_WIFI_IF_BSHAPER_ASSIGN = NSS_IF_BSHAPER_ASSIGN, + NSS_WIFI_IF_ISHAPER_UNASSIGN = NSS_IF_ISHAPER_UNASSIGN, + NSS_WIFI_IF_BSHAPER_UNASSIGN = NSS_IF_BSHAPER_UNASSIGN, + NSS_WIFI_IF_ISHAPER_CONFIG = NSS_IF_ISHAPER_CONFIG, + NSS_WIFI_IF_BSHAPER_CONFIG = NSS_IF_BSHAPER_CONFIG, + NSS_WIFI_IF_VSI_ASSIGN = NSS_IF_VSI_ASSIGN, + NSS_WIFI_IF_VSI_UNASSIGN = NSS_IF_VSI_UNASSIGN, + NSS_WIFI_IF_TX_CREATE_MSG = NSS_IF_MAX_MSG_TYPES + 1, + NSS_WIFI_IF_TX_DESTROY_MSG, + NSS_WIFI_IF_STATS_SYNC_MSG, + NSS_WIFI_IF_MAX_MSG_TYPES +}; + +/** + * nss_wifi_if_error_types + * Error types for the Wi-Fi interface. + */ +enum nss_wifi_if_error_types { + NSS_WIFI_IF_SUCCESS, + NSS_WIFI_IF_CORE_FAILURE, + NSS_WIFI_IF_ALLOC_FAILURE, + NSS_WIFI_IF_DYNAMIC_IF_FAILURE, + NSS_WIFI_IF_MSG_TX_FAILURE, + NSS_WIFI_IF_REG_FAILURE, + NSS_WIFI_IF_CORE_NOT_INITIALIZED +}; + +/** + * nss_wifi_if_create_msg + * Payload for configuring the Wi-Fi interface. + */ +struct nss_wifi_if_create_msg { + uint32_t flags; /**< Interface flags. */ + uint8_t mac_addr[ETH_ALEN]; /**< MAC address. */ +}; + +/** + * nss_wifi_if_destroy_msg + * Payload for destroying the Wi-Fi interface. + */ +struct nss_wifi_if_destroy_msg { + int32_t reserved; /**< Placeholder. */ +}; + +/** + * nss_wifi_if_stats + * Wi-Fi interface statistics received from the NSS. + */ +struct nss_wifi_if_stats { + struct nss_cmn_node_stats node_stats; + /**< Common statistics. */ + uint32_t tx_enqueue_failed; + /**< Number of packets dropped when queuing to the next node in a network graph. */ + uint32_t shaper_enqueue_failed; + /**< Number of packets dropped when queuing to the shaper node. */ +}; + +/** + * nss_wifi_if_msg + * Data for sending and receiving Wi-Fi interface messages. + */ +struct nss_wifi_if_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a Wi-Fi interface message. + */ + union { + union nss_if_msgs if_msgs; + /**< NSS interface messages. */ + struct nss_wifi_if_create_msg create; + /**< Creates a Wi-Fi interface rule. */ + struct nss_wifi_if_destroy_msg destroy; + /**< Destroys a Wi-Fi interface rule. */ + struct nss_wifi_if_stats stats; + /**< Interface statistics. */ + } msg; /**< Message payload. */ +}; + +/** + * nss_wifi_if_pvt + * Private data information for the Wi-Fi interface. + */ +struct nss_wifi_if_pvt { + struct semaphore sem; + /**< Semaphore for a specified Wi-Fi interface number. */ + struct completion complete; + /**< Waits for the NSS to process a message on the specified Wi-Fi interface. */ + int response; /**< Response received on a Wi-Fi interface number. */ + int sem_init_done; + /**< Indicates whether the semaphore is initialized. */ +}; + +/** + * Callback function for receiving Wi-Fi data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_wifi_if_data_callback_t)(struct net_device *netdev, + struct sk_buff *skb, struct napi_struct *napi); + +/** + * Callback function for receiving Wi-Fi messages. + * + * @datatypes + * nss_cmn_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_wifi_if_msg_callback_t)(void *app_data, + struct nss_cmn_msg *msg); + +/** + * nss_wifi_if_handle + * Context for WLAN-to-NSS communication. + */ +struct nss_wifi_if_handle { + struct nss_ctx_instance *nss_ctx; /**< NSS context. */ + int32_t if_num; /**< Interface number. */ + struct nss_wifi_if_pvt *pvt; /**< Private data structure. */ + struct nss_wifi_if_stats stats; + /**< Statistics corresponding to this handle. */ + nss_wifi_if_msg_callback_t cb; + /**< Callback registered by other modules. */ + void *app_data; + /**< Application context to be passed to that callback. */ +}; + +/** + * nss_wifi_if_tx_msg + * Sends a message to the Wi-Fi interface. + * + * @datatypes + * nss_ctx_instance \n + * nss_wifi_if_msg + * + * @param[in] nss_ctx Pointer to the NSS context (provided during registration). + * @param[in] nwim Pointer to the Wi-Fi interface message. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_wifi_if_tx_msg(struct nss_ctx_instance *nss_ctx, + struct nss_wifi_if_msg *nwim); + +/** + * nss_wifi_if_register + * Registers a Wi-Fi interface with the NSS driver. + * + * @datatypes + * nss_wifi_if_handle \n + * nss_wifi_if_data_callback_t \n + * net_device + * + * @param[in] handle Pointer to the Wi-Fi context (provided during Wi-Fi + * interface allocation). + * @param[in] rx_callback Callback handler for Wi-Fi data packets. + * @param[in] netdev Pointer to the associated network device. + * + * @return + * None. + */ +extern void nss_wifi_if_register(struct nss_wifi_if_handle *handle, + nss_wifi_if_data_callback_t rx_callback, + struct net_device *netdev); + +/** + * nss_wifi_if_unregister + * Deregisters a Wi-Fi interface from the NSS driver. + * + * @datatypes + * nss_wifi_if_handle + * + * @param[in] handle Pointer to the Wi-Fi context. + * + * @return + * None. + */ +extern void nss_wifi_if_unregister(struct nss_wifi_if_handle *handle); + +/** + * nss_wifi_if_create_sync + * Creates a Wi-Fi interface. + * + * @datatypes + * net_device + * + * @param[in] netdev Pointer to the associated network device. + * + * @return + * Pointer to the Wi-Fi handle. + */ +extern struct nss_wifi_if_handle *nss_wifi_if_create_sync(struct net_device *netdev); + +/** + * nss_wifi_if_destroy_sync + * Destroys the Wi-Fi interface associated with the interface number. + * + * @datatypes + * nss_wifi_if_handle + * + * @param[in] handle Pointer to the Wi-Fi handle. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_wifi_if_destroy_sync(struct nss_wifi_if_handle *handle); + +/** + * nss_wifi_if_tx_buf + * Sends a data packet or buffer to the NSS. + * + * @datatypes + * nss_wifi_if_handle \n + * sk_buff + * + * @param[in] handle Context associated with the interface. + * @param[in] skb Pointer to the data socket buffer. + * + * @return + * Status of the Tx operation. + */ +extern nss_tx_status_t nss_wifi_if_tx_buf(struct nss_wifi_if_handle *handle, + struct sk_buff *skb); + +/** + * nss_wifi_if_copy_stats + * Copies Wi-Fi interface statistics for display. + * + * @param[in] if_num NSS interface number. + * @param[in] index Index in the statistics array. + * @param[out] line Pointer to the buffer into which the statistics are copied. + * + * @return + * Number of bytes copied. + */ +int32_t nss_wifi_if_copy_stats(int32_t if_num, int index, char *line); + +/** + * @} + */ + +#endif /* __NSS_WIFI_IF_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_wifi_mac_db_if.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_wifi_mac_db_if.h new file mode 100644 index 000000000..0161f5a61 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_wifi_mac_db_if.h @@ -0,0 +1,242 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + + /** + * @file nss_wifi_mac_db_if.h + * NSS-to-HLOS interface definitions. + */ +#ifndef __NSS_WIFI_MAC_DB_H +#define __NSS_WIFI_MAC_DB_H + +#define NSS_WIFI_MAC_DB_ENTRY_IF_LOCAL 0x1 + +/* + * MAX Wi-Fi MAC database entries sent in group + * is chosen considering the entry size and + * maximum entries a smallest buffer could accomodate. + */ +#define NSS_WIFI_MAC_DB_GROUP_ENTRIES_MAX 48 + +/** + * nss_wifi_mac_db_msg_types + * Wi-Fi MAC database messages. + */ +enum nss_wifi_mac_db_msg_types { + NSS_WIFI_MAC_DB_INIT_MSG, /**< Wi-Fi MAC database initialization message. */ + NSS_WIFI_MAC_DB_ADD_ENTRY_MSG, /**< Wi-Fi MAC database add entry message. */ + NSS_WIFI_MAC_DB_DEL_ENTRY_MSG, /**< Wi-Fi MAC database delete entry message. */ + NSS_WIFI_MAC_DB_UPDATE_ENTRY_MSG, /**< Wi-Fi MAC database update entry message. */ + NSS_WIFI_MAC_DB_DEINIT_MSG, /**< Wi-Fi MAC database deinitialization message. */ + NSS_WIFI_MAC_DB_GROUP_ENTRIES_ADD_MSG, /**< Wi-Fi MAC database group entries add message. */ + NSS_WIFI_MAC_DB_MAX_MSG +}; + +/** + * nss_wifi_mac_db_iftype + * Wi-Fi MAC database interface type. + */ +enum nss_wifi_mac_db_iftype { + NSS_WIFI_MAC_DB_ENTRY_IFTYPE_NONE, + NSS_WIFI_MAC_DB_ENTRY_IFTYPE_VAP, /**< Wi-Fi MAC database VAP entry interface. */ + NSS_WIFI_MAC_DB_ENTRY_IFTYPE_NON_VAP, /**< Wi-Fi MAC database non-VAP entry interface. */ + NSS_WIFI_MAC_DB_ENTRY_IFTYPE_MAX /**< Wi-Fi MAC database maximum interface. */ +}; + +/** + * nss_wifi_mac_db_if_opmode + * Wi-Fi MAC database interface operation mode. + */ +enum nss_wifi_mac_db_if_opmode { + NSS_WIFI_MAC_DB_ENTRY_IF_OPMODE_NONE, /**< No entry database interface operation mode. */ + NSS_WIFI_MAC_DB_ENTRY_IF_OPMODE_ETH, /**< Ethernet entry database interface operation mode. */ + NSS_WIFI_MAC_DB_ENTRY_IF_OPMODE_WIFI_AP, /**< Wi-Fi AP entry database interface operation mode. */ + NSS_WIFI_MAC_DB_ENTRY_IF_OPMODE_WIFI_STA, /**< Wi-Fi station entry database interface operation mode. */ + NSS_WIFI_MAC_DB_ENTRY_IF_OPMODE_MAX /**< Maximum entry database interface operation mode. */ +}; + +/* + * nss_wifi_mac_db_err_types + * Wi-Fi MAC database erros. + */ +enum nss_wifi_mac_db_err_types { + NSS_WIFI_MAC_DB_ERROR_NONE, + /**< Wi-Fi MAC database error none. */ + NSS_WIFI_MAC_DB_ERROR_ENTRY_ALLOC_FAIL, + /**< Error used to report a Wi-Fi MAC database entry pool allocation failure. */ + NSS_WIFI_MAC_DB_ERROR_MAC_EXISTS, + /**< Error used to report that a Wi-Fi MAC database entry already exists. */ + NSS_WIFI_MAC_DB_ERROR_MAC_TABLE_FULL, + /**< Error used to report that a Wi-Fi MAC table is full. */ + NSS_WIFI_MAC_DB_ERROR_MAC_ENTRY_ALLOC_FAILED, + /**< Error used to report a Wi-Fi MAC database entry allocation failure. */ + NSS_WIFI_MAC_DB_ERROR_ENTRY_NOT_FOUND, + /**< Error used to report that a Wi-Fi MAC database entry is not present. */ + NSS_WIFI_MAC_DB_ERROR_MAC_ENTRY_UNHASHED, + /**< Error used to report that a Wi-Fi MAC database entry is unhashed. */ + NSS_WIFI_MAC_DB_ERROR_MAC_ENTRY_DELETE_FAILED, + /**< Error used to report a Wi-Fi MAC database entry delete failure. */ + NSS_WIFI_MAC_DB_ERROR_INVALID_NUM_ENTRIES_FAIL, + /**< Error used to report the number of invalid Wi-Fi MAC database entries. */ + NSS_WIFI_MAC_DB_ERROR_NOT_ALLOCATED_FAIL, + /**< Error used to report that a Wi-Fi MAC database is not allocated. */ + NSS_WIFI_MAC_DB_ERROR_INV_IF_RECVD_FAIL, + /**< Error used to report that a Wi-Fi MAC database entry interface is invalid. */ + NSS_WIFI_MAC_DB_ERROR_INVALID_EVENT, + /**< Error used to report that a Wi-Fi MAC database event is invalid. */ + NSS_WIFI_MAC_DB_ERROR_PN_INVALID, + /**< Error used to report that a Wi-Fi MAC database entry pnode is invalid. */ + NSS_WIFI_MAC_DB_ERROR_PHY_PN_INVALID, + /**< Error used to report that a Wi-Fi MAC database entry radio pnode is invalid. */ + NSS_WIFI_MAC_DB_ERROR_ENTRY_POOL_INVALID, + /**< Error used to report that a Wi-Fi MAC database entry pool is invalid. */ + NSS_WIFI_MAC_DB_ERROR_ENTRY_POOL_ALREADY_ALLOCATED, + /**< Error used to report that a Wi-Fi MAC database entry pool exists. */ + NSS_WIFI_MAC_DB_ERROR_GROUP_ENTRY_ADD_FAIL, + /**< Error used to report that a Wi-Fi MAC database group entry add failure. */ + NSS_WIFI_MAC_DB_ERROR_MAX, + /**< Wi-Fi MAC database error maximum. */ +}; + +/** + * nss_wifi_mac_db_entry_info_msg + * Wi-Fi MAC database entry information. + */ +struct nss_wifi_mac_db_entry_info_msg { + uint8_t mac_addr[6]; /**< MAC address. */ + uint16_t flag; /**< Flag information about NSS interface. */ + int32_t nss_if; /**< NSS interface number. */ + uint32_t iftype; /**< NSS interface type. */ + uint32_t opmode; /**< NSS interface operation mode. */ + uint32_t wiphy_ifnum; /**< NSS interface for wireless physical device. */ +}; + +/** + * nss_wifi_mac_db_entry_group_info_msg + * Wi-Fi MAC database group of entries information. + */ +struct nss_wifi_mac_db_entry_group_info_msg { + uint32_t num_entries; + /**< Number of entries in group information message. */ + struct nss_wifi_mac_db_entry_info_msg entry[NSS_WIFI_MAC_DB_GROUP_ENTRIES_MAX]; + /**< Wi-Fi MAC database information specific message. */ +}; + +/** + * nss_wifi_mac_db_msg + * Structure that describes Wi-Fi MAC database messages. + */ +struct nss_wifi_mac_db_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of Wi-Fi MAC database message. + */ + union { + struct nss_wifi_mac_db_entry_info_msg nmfdbeimsg; + /**< Wi-Fi MAC database information specific message. */ + struct nss_wifi_mac_db_entry_group_info_msg nmfdbegimsg; + /**< Wi-Fi MAC database information specific message. */ + } msg; /**< Message payload. */ +}; + +/** + * nss_wifi_mac_db_msg_callback_t + * Callback to receive Wi-Fi MAC database messages. + * + * @datatypes + * nss_wifi_mac_db_msg + * + * @param[in] app_data Application context of the message. + * @param[in] msg Message data. + * + * @return + * void + */ +typedef void (*nss_wifi_mac_db_msg_callback_t)(void *app_data, struct nss_wifi_mac_db_msg *msg); + +/** + * nss_wifi_mac_db_callback_t + * Callback to receive Wi-Fi MAC database messages. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + * + * @return + * void + */ +typedef void (*nss_wifi_mac_db_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + + +/** + * nss_wifi_mac_db_tx_msg + * Send Wi-Fi MAC database messages. + * + * @datatypes + * nss_ctx_instance \n + * nss_wifi_mac_db_msg + * + * @param[in] nss_ctx NSS context. + * @param[in] msg NSS Wi-Fi MAC database message. + * + * @return + * nss_tx_status_t Tx status + */ +extern nss_tx_status_t nss_wifi_mac_db_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_wifi_mac_db_msg *msg); + +/** + * nss_register_wifi_mac_db_if + * Register to send/receive Wi-Fi MAC database messages to NSS. + * + * @datatypes + * nss_wifi_mac_db_callback_t \n + * nss_wifi_mac_db_msg_callback_t \n + * net_device + * + * @param[in] if_num NSS interface number. + * @param[in] mfdb_callback Callback for the Wi-Fi MAC database device data. + * @param[in] mfdb_ext_callback Callback for the extended data. + * @param[in] event_callback Callback for the message. + * @param[in] netdev Pointer to the associated network device. + * @param[in] features Data socket buffer types supported by this + * interface. + * + * @return + * nss_ctx_instance* NSS context + */ +struct nss_ctx_instance *nss_register_wifi_mac_db_if(uint32_t if_num, nss_wifi_mac_db_callback_t wifi_mac_db_callback, + nss_wifi_mac_db_callback_t wifi_mac_db_ext_callback, nss_wifi_mac_db_msg_callback_t event_callback, struct net_device *netdev, uint32_t features); + +/** + * nss_unregister_wifi_mac_db_if + * Deregister Wi-Fi MAC database SoC interface with NSS. + * + * @param[in] if_num NSS interface number. + * + * @return + * void + */ +void nss_unregister_wifi_mac_db_if(uint32_t if_num); +struct nss_ctx_instance *nss_wifi_mac_db_get_context(void); +#endif /* __NSS_WIFI_MAC_DB_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_wifi_vdev.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_wifi_vdev.h new file mode 100644 index 000000000..f682f387c --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_wifi_vdev.h @@ -0,0 +1,1263 @@ +/* + ************************************************************************** + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * @file nss_wifi_vdev.h + * NSS TO HLOS Wi-Fi virtual device interface definitions. + */ + +#ifndef __NSS_WIFI_VDEV_H +#define __NSS_WIFI_VDEV_H + +/** + * @addtogroup nss_wifi_vdev_subsystem + * @{ + */ +#define NSS_WIFI_HTT_TRANSFER_HDRSIZE_WORD 6 /**< Size of the Host-To-Target (HTT) message transfer header. */ +#define NSS_WIFI_VDEV_PER_PACKET_METADATA_OFFSET 4 +/**< Offset of the metadata in a virtual device message. */ +#define NSS_WIFI_VDEV_DSCP_MAP_LEN 64 /**< Length of the DSCP MAP field. */ +#define NSS_WIFI_VDEV_IPV6_ADDR_LENGTH 16 /**< Size of the IPv6 address field. */ +#define NSS_WIFI_MAX_SRCS 4 /**< Maximum number of multicast sources. */ +#define NSS_WIFI_VDEV_MAX_ME_ENTRIES 32 /**< Maximum number of multicast enhancement entries. */ + +/** + * nss_wifi_vdev_msg_types + * Wi-Fi virtual device messages. + */ +enum nss_wifi_vdev_msg_types { + NSS_WIFI_VDEV_INTERFACE_CONFIGURE_MSG = NSS_IF_MAX_MSG_TYPES + 1, + NSS_WIFI_VDEV_INTERFACE_UP_MSG, + NSS_WIFI_VDEV_INTERFACE_DOWN_MSG, + NSS_WIFI_VDEV_INTERFACE_CMD_MSG, + NSS_WIFI_VDEV_SNOOPLIST_GRP_LIST_CREATE_MSG, + NSS_WIFI_VDEV_SNOOPLIST_GRP_LIST_DELETE_MSG, + NSS_WIFI_VDEV_SNOOPLIST_GRP_MEMBER_ADD_MSG, + NSS_WIFI_VDEV_SNOOPLIST_GRP_MEMBER_REMOVE_MSG, + NSS_WIFI_VDEV_SNOOPLIST_GRP_MEMBER_UPDATE_MSG, + NSS_WIFI_VDEV_SNOOPLIST_DENY_MEMBER_ADD_MSG, + NSS_WIFI_VDEV_SNOOPLIST_DENY_LIST_DELETE_MSG, + NSS_WIFI_VDEV_SNOOPLIST_DENY_LIST_DUMP_MSG, + NSS_WIFI_VDEV_SNOOPLIST_DUMP_MSG, + NSS_WIFI_VDEV_SNOOPLIST_RESET_MSG, + NSS_WIFI_VDEV_SPECIAL_DATA_TX_MSG, + NSS_WIFI_VDEV_VOW_DBG_CFG_MSG, + NSS_WIFI_VDEV_VOW_DBG_STATS_REQ_MSG, + NSS_WIFI_VDEV_DSCP_TID_MAP_MSG, + NSS_WIFI_VDEV_SNOOPLIST_TOGGLE_MSG, + NSS_WIFI_VDEV_UPDATECHDR_MSG, + NSS_WIFI_VDEV_ME_SYNC_MSG, + NSS_WIFI_VDEV_STATS_MSG, + NSS_WIFI_VDEV_SET_NEXT_HOP, + NSS_WIFI_VDEV_DSCP_TID_MAP_ID_MSG, + NSS_WIFI_VDEV_EXTAP_ADD_ENTRY, + NSS_WIFI_VDEV_EXTAP_REMOVE_ENTRY, + NSS_WIFI_VDEV_QWRAP_PSTA_DELETE_ENTRY, + NSS_WIFI_VDEV_QWRAP_PSTA_ADD_ENTRY, + NSS_WIFI_VDEV_QWRAP_ISOLATION_ENABLE, + NSS_WIFI_VDEV_SET_PEER_NEXT_HOP, + NSS_WIFI_VDEV_CONFIG_VLAN_ID_MSG, + NSS_WIFI_VDEV_CONFIG_VLAN_MODE_MSG, + NSS_WIFI_VDEV_INTERFACE_RECOVERY_RESET_MSG, + NSS_WIFI_VDEV_INTERFACE_RECOVERY_RECONF_MSG, + NSS_WIFI_VDEV_SET_GROUP_KEY, + NSS_WIFI_VDEV_MAX_MSG +}; + +/** + * nss_wifi_vdev_err_types + * Error types for a Wi-Fi virtual device. + */ +enum nss_wifi_vdev_err_types { + NSS_WIFI_VDEV_ENONE, + NSS_WIFI_VDEV_EUNKNOWN_MSG, + NSS_WIFI_VDEV_EINV_VID_CONFIG, + NSS_WIFI_VDEV_EINV_EPID_CONFIG, + NSS_WIFI_VDEV_EINV_DL_CONFIG, + NSS_WIFI_VDEV_EINV_CMD, + NSS_WIFI_VDEV_EINV_ENCAP, + NSS_WIFI_VDEV_EINV_DECAP, + NSS_WIFI_VDEV_EINV_RX_NXTN, + NSS_WIFI_VDEV_EINV_VID_INDEX, + NSS_WIFI_VDEV_EINV_MC_CFG, + NSS_WIFI_VDEV_SNOOPTABLE_FULL, + NSS_WIFI_VDEV_SNOOPTABLE_ENOMEM, + NSS_WIFI_VDEV_SNOOPTABLE_GRP_LIST_UNAVAILABLE, + NSS_WIFI_VDEV_SNOOPTABLE_GRP_MEMBER_UNAVAILABLE, + NSS_WIFI_VDEV_SNOOPTABLE_PEER_UNAVAILABLE, + NSS_WIFI_VDEV_SNOOPTABLE_GRP_LIST_ENOMEM, + NSS_WIFI_VDEV_SNOOPTABLE_GRP_LIST_EXIST, + NSS_WIFI_VDEV_ME_ENOMEM, + NSS_WIFI_VDEV_EINV_NAWDS_CFG, + NSS_WIFI_VDEV_EINV_EXTAP_CFG, + NSS_WIFI_VDEV_EINV_VOW_DBG_CFG, + NSS_WIFI_VDEV_EINV_DSCP_TID_MAP, + NSS_WIFI_VDEV_INVALID_ETHER_TYPE, + NSS_WIFI_VDEV_SNOOPTABLE_GRP_MEMBER_EXIST, + NSS_WIFI_VDEV_ME_INVALID_NSRCS, + NSS_WIFI_VDEV_EINV_RADIO_ID, + NSS_WIFI_VDEV_RADIO_NOT_PRESENT, + NSS_WIFI_VDEV_CHDRUPD_FAIL, + NSS_WIFI_VDEV_ME_DENY_GRP_MAX_RCHD, + NSS_WIFI_VDEV_EINV_NEXT_HOP, + NSS_WIFI_VDEV_EINV_DSCP_TID_MAP_ID, + NSS_WIFI_VDEV_EINV_TID_VALUE, + NSS_WIFI_VDEV_EINV_EXTAP_TABLE, + NSS_WIFI_VDEV_EXTAP_ENTRY_UPDATE_FAIL, + NSS_WIFI_VDEV_QWRAP_PSTA_ADD_FAIL, + NSS_WIFI_VDEV_QWRAP_PSTA_DEL_FAIL, + NSS_WIFI_VDEV_QWRAP_ISOLATION_EN_FAIL, + NSS_WIFI_VDEV_QWRAP_ALLOC_FAIL, + NSS_WIFI_VDEV_PEER_NOT_FOUND_BY_MAC, + NSS_WIFI_VDEV_PEER_NEXT_HOP_NOT_FOUND, + NSS_VDEV_EUNKNOWN_NEXT_HOP, + NSS_WIFI_VDEV_VLAN_ID_CONFIG_FAIL, + NSS_WIFI_VDEV_VLAN_MODE_CONFIG_FAIL, + NSS_WIFI_VDEV_RECOVERY_RESET_FAIL, + NSS_WIFI_VDEV_RECOVERY_RECONF_FAIL, + NSS_WIFI_VDEV_EINV_MAX_CFG +}; + +/** + * nss_wifi_vdev_ext_data_pkt_type + * Types of extended data plane packets sent from the NSS to the host. + */ +enum nss_wifi_vdev_ext_data_pkt_type { + NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_NONE = 0, + NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_IGMP = 1, /**< IGMP packets. */ + NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_MESH = 2, /**< MESH packets. */ + NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_INSPECT = 3, /**< Host inspect packets. */ + NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_TXINFO = 4, /**< Tx completion information packets. */ + NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_MPSTA_TX = 5, /**< MP station Tx metadata. */ + NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_MPSTA_RX = 6, /**< MP station Rx metadata. */ + NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_RX_ERR = 7, /**< Rx error packets metadata. */ + NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_EXTAP_TX = 8, /**< ExtAP Tx metadata. */ + NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_EXTAP_RX = 9, /**< ExtAP Rx metadata. */ + NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_WNM_TFS = 10, /**< WNM TFS related metadata. */ + NSS_WIFI_VDEV_EXT_TX_COMPL_PKT_TYPE = 11, /**< Tx completion. */ + NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_WDS_LEARN = 12, /**< WDS source port learning command. */ + NSS_WIFI_VDEV_EXT_DATA_PPDU_INFO = 13, /**< PPDU metadata information. */ + NSS_WIFI_VDEV_EXT_DATA_PKT_TYPE_MAX +}; + +/** + * nss_wifi_vdev_cmd + * Commands for the Wi-Fi virtual device. + */ +enum nss_wifi_vdev_cmd { + NSS_WIFI_VDEV_DROP_UNENC_CMD, /**< Configuration to drop unencrypted frames on VAP. */ + NSS_WIFI_VDEV_ENCAP_TYPE_CMD, /**< Configuration to set encapsulation type on VAP. */ + NSS_WIFI_VDEV_DECAP_TYPE_CMD, /**< Configuration to set decapsulation type on VAP. */ + NSS_WIFI_VDEV_ENABLE_ME_CMD, /**< Configuration to set multicast enhancement on VAP. */ + NSS_WIFI_VDEV_NAWDS_MODE_CMD, /**< Configuration to set NAWDS mode on VAP. */ + NSS_WIFI_VDEV_EXTAP_CONFIG_CMD, /**< Configuration to set extended AP mode on VAP. */ + NSS_WIFI_VDEV_CFG_BSTEER_CMD, /**< Configuration to set bandsteering on VAP. */ + NSS_WIFI_VDEV_VOW_DBG_MODE_CMD, /**< Configuration to set video over wireless (VOW) debug mode on VAP. */ + NSS_WIFI_VDEV_VOW_DBG_RST_STATS_CMD, + /**< Configuration to reset video over wireless (VOW) debug mode on VAP. */ + NSS_WIFI_VDEV_CFG_DSCP_OVERRIDE_CMD, + /**< Configuration to set DSCP/TID value override on VAP. */ + NSS_WIFI_VDEV_CFG_WNM_CAP_CMD, /**< Configuration to set wireless network management (WNM) capability on VAP. */ + NSS_WIFI_VDEV_CFG_WNM_TFS_CMD, /**< Configuration to set WNM traffic filtering and sleep mode (TFS) capability on VAP. */ + NSS_WIFI_VDEV_CFG_WDS_EXT_ENABLE_CMD, + /**< Configuration to set WDS extention capability on VAP. */ + NSS_WIFI_VDEV_CFG_WDS_CMD, /**< Configuration to set WDS on VAP. */ + NSS_WIFI_VDEV_CFG_AP_BRIDGE_CMD, /**< Configuration to enable/disable client isolation. */ + NSS_WIFI_VDEV_SECURITY_TYPE_CMD, /**< Configuration to set security type per VAP. */ + NSS_WIFI_VDEV_CFG_AST_OVERRIDE_CMD, /**< Configuration to set AST (Address Search Table) override on VAP. */ + NSS_WIFI_VDEV_CFG_SON_CAP_CMD, /**< Configuration to set software defined network capability on VAP. */ + NSS_WIFI_VDEV_CFG_MULTIPASS_CMD, /**< Configuration to enable multipass phrase capability on VAP. */ + NSS_WIFI_VDEV_CFG_HLOS_TID_OVERRIDE_CMD, + /**< Configuration to enable HLOS TID override on VAP. */ + NSS_WIFI_VDEV_ENABLE_IGMP_ME_CMD, /**< Configuration to set IGMP multicast enhancement on VAP. */ + NSS_WIFI_VDEV_CFG_WDS_BACKHAUL_CMD, + /**< Configuration to set WDS backhaul extension on VAP. */ + NSS_WIFI_VDEV_MAX_CMD +}; + +/** + * nss_wifi_vdev_dp_type + * Virtual device datapath types. + */ +enum nss_wifi_vdev_dp_type { + NSS_WIFI_VDEV_DP_ACCELERATED, /**< Wi-Fi accelerated VAP type. */ + NSS_WIFI_VDEV_DP_NON_ACCELERATED, /**< Wi-Fi non-acclerated VAP type. */ + NSS_WIFI_VDEV_DP_TYPE_MAX /**< Wi-Fi maximum VAP type. */ +}; + +/** + * nss_wifi_vdev_vlan_tagging_mode + * Supported VLAN tagging modes. + */ +enum nss_wifi_vdev_vlan_tagging_mode { + NSS_WIFI_VDEV_VLAN_NONE, /**< VLAN support disabled. */ + + /** + * Default VLAN mode to add VLAN tag in Rx path and + * remove VLAN tag only when matching with configured + * VLAN tag in Tx path. + */ + NSS_WIFI_VDEV_VLAN_INGRESS_ADD_EGRESS_STRIP_ON_ID_MATCH, + + /** + * Port-based VLAN mode to add VLAN tag in Rx path + * and remove any VLAN tag in Tx path. + */ + NSS_WIFI_VDEV_VLAN_INGRESS_ADD_EGRESS_STRIP_ALWAYS, + NSS_WIFI_VDEV_VLAN_MAX /**< Wi-Fi maximum VLAN support type. */ +}; + +/** + * nss_wifi_vdev_config_msg + * Virtual device configuration. + */ +struct nss_wifi_vdev_config_msg { + uint8_t mac_addr[ETH_ALEN]; /**< MAC address. */ + uint16_t radio_ifnum; /**< Corresponding radio interface number. */ + uint32_t vdev_id; /**< Virtual device ID. */ + uint32_t epid; /**< Endpoint ID of the copy engine. */ + uint32_t downloadlen; /**< Size of the header download length. */ + uint32_t hdrcachelen; /**< Size of the header cache. */ + uint32_t hdrcache[NSS_WIFI_HTT_TRANSFER_HDRSIZE_WORD]; + /**< Cached per descriptor metedata shared with NSS Firmware. */ + uint32_t opmode; /**< VAP operating mode: Access-Point (AP) or Station (STA). */ + uint32_t mesh_mode_en; /**< Mesh mode is enabled. */ + uint8_t is_mpsta; + /**< Specifies whether the station is a VAP Master-Proxy (MP) station. */ + uint8_t is_psta; + /**< Specifies whether the station is a proxy station. */ + uint8_t special_vap_mode; + /**< Special VAP for monitoring received management packets. */ + uint8_t smartmesh_mode_en; + /**< VAP is configured as a smart monitor VAP. */ + uint8_t is_wrap; /**< Specifies whether the VAP is a WRAP-AP. */ + uint8_t is_nss_qwrap_en; /**< VAP is configured for NSS firmware QWRAP logic. */ + uint8_t tx_per_pkt_vdev_id_check; /**< Transmit per-packet virtual device ID check. */ + uint8_t reserved; /**< Reserved for 4-byte alignment padding. */ +}; + +/** + * nss_wifi_vdev_enable_msg + * Enable a message for a virtual device. + */ +struct nss_wifi_vdev_enable_msg { + uint8_t mac_addr[ETH_ALEN]; /**< MAC address. */ + uint8_t reserved[2]; /**< Reserved for 4-byte alignment padding. */ +}; + +/** + * nss_wifi_vdev_disable_msg + * Disable message for a virtual device. + */ +struct nss_wifi_vdev_disable_msg { + uint32_t reserved; /**< Placeholder for future enhancement. */ +}; + +/** + * nss_wifi_vdev_recovery_msg + * Recovery message for a virtual device. + */ +struct nss_wifi_vdev_recovery_msg { + uint32_t reserved; /**< Placeholder for future enhancement. */ +}; + +/** + * nss_wifi_vdev_set_next_hop_msg + * Set next hop for Wi-Fi virtual device. + */ +struct nss_wifi_vdev_set_next_hop_msg { + uint32_t ifnumber; /**< Next hop interface number. */ +}; + +/** + * nss_wifi_vdev_extap_map + * Wi-Fi EXTAP map for IPv4/IPv6 addresses. + */ +struct nss_wifi_vdev_extap_map { + uint16_t ip_version; /**< IPv4 or IPv6 address. */ + uint8_t h_dest[ETH_ALEN]; /**< MAC address of original backend. */ + union { + uint8_t IPv4[4]; /**< IPv4 address of the backend. */ + uint8_t IPv6[NSS_WIFI_VDEV_IPV6_ADDR_LENGTH]; /**< IPv6 group IP address. */ + } u; +}; + +/** + * nss_wifi_vdev_cmd_msg + * Virtual device commands. + */ +struct nss_wifi_vdev_cmd_msg { + uint32_t cmd; /**< Command type. */ + uint32_t value; /**< Command value. */ +}; + +/** + * nss_wifi_vdev_me_snptbl_grp_create_msg + * Information for creating the snooptable group of a virtual device. + */ +struct nss_wifi_vdev_me_snptbl_grp_create_msg { + uint32_t ether_type; /**< Ether type of the multicast group. */ + + /** + * IP address of a multicast group. + */ + union { + uint32_t grpaddr_ip4; + /**< IPv4 address. */ + uint8_t grpaddr_ip6[NSS_WIFI_VDEV_IPV6_ADDR_LENGTH]; + /**< IPv6 address. */ + } u; /**< IP address of the multicast group. */ + + uint8_t grp_addr[ETH_ALEN]; + /**< MAC address of the multicast group. */ +}; + +/** + * nss_wifi_vdev_me_snptbl_grp_delete_msg + * Information for deleting a snooplist group list. + */ +struct nss_wifi_vdev_me_snptbl_grp_delete_msg { + uint32_t ether_type; /**< Ether type of the multicast group. */ + + /** + * IP address of the multicast group. + */ + union { + uint32_t grpaddr_ip4; + /**< IPv4 address. */ + uint8_t grpaddr_ip6[NSS_WIFI_VDEV_IPV6_ADDR_LENGTH]; + /**< IPv6 address. */ + } u; /**< IP address of the multicast group. */ + + uint8_t grp_addr[ETH_ALEN]; /**< MAC address of the multicast group. */ +}; + +/** + * struct nss_wifi_vdev_me_mbr_ra_info + * Address details of receiver members. + */ +struct nss_wifi_vdev_me_mbr_ra_info { + bool dup; + /**< Duplicate bit to identify if next hop address is present. */ + uint8_t ramac[ETH_ALEN]; + /**< MAC address of receiver. */ +}; + +/** + * nss_wifi_vdev_me_snptbl_grp_mbr_add_msg + * Information for adding a snooplist group member. + */ +struct nss_wifi_vdev_me_snptbl_grp_mbr_add_msg { + uint32_t ether_type; /**< Ether type of the multicast group. */ + + /** + * IP address of the multicast group. + */ + union { + uint32_t grpaddr_ip4; + /**< IPv4 address. */ + uint8_t grpaddr_ip6[NSS_WIFI_VDEV_IPV6_ADDR_LENGTH]; + /**< IPv6 address. */ + } u; /**< IP address of the multicast group. */ + + uint32_t peer_id; /**< Peer ID. */ + uint8_t grp_addr[ETH_ALEN]; + /**< MAC address of the multicast group. */ + uint8_t grp_member_addr[ETH_ALEN]; + /**< MAC address of the multicast group member. */ + uint8_t mode; /**< Multicast enhancement mode - mode 2 and mode 5. */ + uint8_t nsrcs; /**< Number of source IP addresses for selective source multicast. */ + uint8_t src_ip_addr[NSS_WIFI_VDEV_IPV6_ADDR_LENGTH * NSS_WIFI_MAX_SRCS]; + /**< Source IP address. */ + struct nss_wifi_vdev_me_mbr_ra_info ra_entry; + /**< Receiver address entry corresponding to the member. */ +}; + +/** + * nss_wifi_vdev_me_snptbl_grp_mbr_delete_msg + * Information for removing a snooplist group member. + */ +struct nss_wifi_vdev_me_snptbl_grp_mbr_delete_msg { + uint32_t ether_type; /**< Ether type of the multicast group. */ + + /** + * IP address of the multicast group. + */ + union { + uint32_t grpaddr_ip4; + /**< IPv4 address. */ + uint8_t grpaddr_ip6[NSS_WIFI_VDEV_IPV6_ADDR_LENGTH]; + /**< IPv6 address. */ + }u; /**< IP address of the multicast group. */ + uint8_t grp_addr[ETH_ALEN]; + /**< MAC address of the multicast group. */ + uint8_t grp_member_addr[ETH_ALEN]; + /**< MAC address of the multicast group member. */ +}; + +/** + * nss_wifi_vdev_me_snptbl_grp_mbr_update_msg + * Information for updating a snooplist group member. + */ +struct nss_wifi_vdev_me_snptbl_grp_mbr_update_msg { + uint32_t ether_type; /**< Ether type of the multicast group. */ + + /** + * IP address of the multicast group. + */ + union { + uint32_t grpaddr_ip4; + /**< IPv4 address. */ + uint8_t grpaddr_ip6[NSS_WIFI_VDEV_IPV6_ADDR_LENGTH]; + /**< IPv6 address. */ + }u; /**< IP address of the multicast group. */ + + uint8_t grp_addr[ETH_ALEN]; + /**< MAC address of the multicast group. */ + uint8_t grp_member_addr[ETH_ALEN]; + /**< MAC address of the multicast group member. */ + uint8_t mode; /**< Multicast enhancement mode - mode 2 and mode 5. */ + uint8_t nsrcs; /**< Number of source IP addresses for selective source multicast. */ + uint8_t src_ip_addr[NSS_WIFI_VDEV_IPV6_ADDR_LENGTH * NSS_WIFI_MAX_SRCS]; + /**< Source IP address. */ +}; + +/** + * nss_wifi_vdev_me_snptbl_deny_grp_add_msg + * Information for adding a snooplist member to a deny list. + */ +struct nss_wifi_vdev_me_snptbl_deny_grp_add_msg { + uint32_t grpaddr; /**< IP address of the multicast group. */ +}; + +/** + * nss_wifi_vdev_txmsg + * Information for transmitting special data. + */ +struct nss_wifi_vdev_txmsg { + uint16_t peer_id; /**< Peer ID. */ + uint16_t tid; /**< Traffic ID. */ +}; + +/** + * nss_wifi_vdev_vow_dbg_stats + * Types of VoW debug statistics. + */ +struct nss_wifi_vdev_vow_dbg_stats { + uint32_t rx_vow_dbg_counters; /**< VoW Rx debug counter. */ + uint32_t tx_vow_dbg_counters[8]; /**< VoW Tx debug counter. */ +}; + +/** + * nss_wifi_vdev_vow_dbg_cfg_msg + * Information for configuring VoW debug statistics. + */ +struct nss_wifi_vdev_vow_dbg_cfg_msg { + uint8_t vow_peer_list_idx; /**< Index of the peer list. */ + uint8_t tx_dbg_vow_peer_mac4; /**< MAC address 4 for the peer. */ + uint8_t tx_dbg_vow_peer_mac5; /**< MAC address 5 for the peer. */ +}; + +/** + * nss_wifi_vdev_dscp_tid_map + * DSCP-to-TID mapping. + */ +struct nss_wifi_vdev_dscp_tid_map { + uint32_t dscp_tid_map[NSS_WIFI_VDEV_DSCP_MAP_LEN]; + /**< Array holding the DSCP-to-TID mapping. */ +}; + +/** + * nss_wifi_vdev_dscptid_map_id + * DSCP-to-TID map ID. + */ +struct nss_wifi_vdev_dscptid_map_id { + uint8_t dscp_tid_map_id; + /**< DSCP-to-TID mapping ID to be used. */ +}; + +/** + * nss_wifi_vdev_set_peer_next_hop + * Set per peer next hop. + */ +struct nss_wifi_vdev_set_peer_next_hop_msg { + uint8_t peer_mac_addr[ETH_ALEN]; /**< MAC peer address. */ + uint16_t reserved; /**< Reserved. */ + uint32_t if_num; /**< Next hop interface number. */ +}; + +/** + * nss_wifi_vdev_qwrap_psta_msg + * PSTA VAP entry map in QWRAP mode. + */ +struct nss_wifi_vdev_qwrap_psta_msg { + uint8_t oma[ETH_ALEN]; /**< Original MAC address of PSTA VAP. */ + uint8_t vma[ETH_ALEN]; /**< Virtual MAC address of PSTA VAP. */ + uint8_t vdev_id; /**< ID of PSTA VAP. */ + uint8_t is_wired; /**< Is the entry for wired PSTA VAP. */ + uint8_t reserved[2]; /**< Reserved for 4-byte alignment. */ +}; + +/** + * nss_wifi_vdev_qwrap_isolation_en_msg + * Qwrap isolation mode enable. + */ +struct nss_wifi_vdev_qwrap_isolation_en_msg { + uint8_t isolation_enable; /**< QWRAP isolation mode enable. */ + uint8_t reserved[3]; /**< Reserved for 4-byte alignment. */ +}; + +/** + * nss_wifi_vdev_igmp_per_packet_metadata + * Per-packet metadata for IGMP packets. + */ +struct nss_wifi_vdev_igmp_per_packet_metadata { + uint32_t tid; /**< TID. */ + uint32_t tsf32; /**< TSF value. */ + uint8_t peer_mac_addr[ETH_ALEN]; + /**< Peer MAC address. */ + uint8_t reserved[2]; /**< Reserved for 4-byte alignment. */ +}; + +/** + * nss_wifi_vdev_mesh_per_packet_metadata + * Per-packet metadata for Mesh packets. + */ +struct nss_wifi_vdev_mesh_per_packet_metadata { + uint32_t status; /**< Meshmode Status. */ + uint32_t rssi; /**< Received signal strength indication. */ + uint32_t tsf; /**< Tx expiry time. */ + uint16_t tx_retries; /**< Retry count. */ +}; + +/** + * nss_wifi_vdev_vlan_config_msg + * Enable special handling on this VAP where VLAN tagging is added in Rx and removed in Tx. + */ +struct nss_wifi_vdev_vlan_config_msg { + uint16_t vlan_id; /**< VLAN ID configured. */ + uint8_t reserved[2]; /**< Reserved for 4-byte alignment. */ +}; + +/** + * nss_wifi_vdev_vlan_enable_msg + * Enable VLAN tagging mode on this VAP. + */ +struct nss_wifi_vdev_vlan_enable_msg { + uint8_t vlan_tagging_mode; /**< Flag to enable default or port-based VLAN tagging mode. */ + uint8_t reserved[3]; /**< Reserved for 4-byte alignment. */ +}; + +/** + * nss_wifi_vdev_set_vlan_group_key + * Set VLAN ID for special peer. + */ +struct nss_wifi_vdev_set_vlan_group_key { + uint16_t vlan_id; /**< VLAN ID. */ + uint16_t group_key; /**< Group key. */ +}; + +/** + * nss_wifi_vdev_txinfo_per_packet_metadata + * Per-packet metadata for Tx completion information packets. + */ +struct nss_wifi_vdev_txinfo_per_packet_metadata { + uint32_t status; /**< Tx completion status. */ + uint16_t msdu_count; /**< Count of MSDUs in the MSDU list. */ + uint16_t num_msdu; /**< Sequence Number of MSDU in the MSDU list. */ + uint32_t msdu_q_time; /**< Time spent by an MSDU in the Wi-Fi firmware. */ + uint32_t ppdu_rate; /**< PPDU rate in code rate. */ + uint8_t ppdu_num_mpdus_success; + /**< Number of successful MPDUs. */ + uint8_t ppdu_num_mpdus_fail; + /**< Number of failed MPDUs. */ + uint16_t ppdu_num_msdus_success; + /**< Number of successful MSDUs. */ + uint32_t ppdu_bytes_success; + /**< Number of successful bytes. */ + uint32_t ppdu_duration; /**< Estimated air time. */ + uint8_t ppdu_retries; /**< Number of times a PPDU is retried. */ + uint8_t ppdu_is_aggregate; + /**< Flag to check whether a PPDU is aggregated. */ + uint16_t start_seq_num; /**< Starting MSDU ID for this PPDU. */ + uint16_t version; /**< PPDU statistics version. */ + uint32_t ppdu_ack_timestamp; + /**< Timestamp (in ms) when an acknowledgement was received. */ + uint32_t ppdu_bmap_enqueued_lo; + /**< Bitmap of packets enqueued to the hardware (LSB). */ + uint32_t ppdu_bmap_enqueued_hi; + /**< Bitmap of packets enqueued to the hardware (MSB). */ + uint32_t ppdu_bmap_tried_lo; + /**< Bitmap of packets sent over the air (LSB). */ + uint32_t ppdu_bmap_tried_hi; + /**< Bitmap of packets sent over the air (MSB). */ + uint32_t ppdu_bmap_failed_lo; + /**< Bitmap of packets that failed to be acknowledged (LSB). */ + uint32_t ppdu_bmap_failed_hi; + /**< Bitmap of packets that failed to be acknowledged (MSB). */ +}; + +/** + * nss_wifi_vdev_qwrap_tx_metadata_types + * Per-packet metadata types for Qwrap Tx packets. + */ +enum nss_wifi_vdev_qwrap_tx_metadata_types { + NSS_WIFI_VDEV_QWRAP_TYPE_NONE = 0, + NSS_WIFI_VDEV_QWRAP_TYPE_TX = 1, + NSS_WIFI_VDEV_QWRAP_TYPE_RX_TO_TX = 2 +}; + +/** + * nss_wifi_vdev_extap_pkt_types + * Per-packet metadata types for ExtAP Tx packets. + */ +enum nss_wifi_vdev_extap_pkt_types { + NSS_WIFI_VDEV_EXTAP_PKT_TYPE_NONE = 0, + NSS_WIFI_VDEV_EXTAP_PKT_TYPE_TX = 1, + NSS_WIFI_VDEV_EXTAP_PKT_TYPE_RX_TO_TX = 2 +}; + +/** + * nss_wifi_vdev_mpsta_per_packet_tx_metadata + * Per-packet metadata for transmitting packets to an MP station. + */ +struct nss_wifi_vdev_mpsta_per_packet_tx_metadata { + uint16_t vdev_id; /**< Virtual device ID. */ + uint16_t metadata_type; /**< Tx metadata type. */ +}; + +/** + * nss_wifi_vdev_mpsta_per_packet_rx_metadata + * Per-packet metadata for receiving packets from an MP station. + */ +struct nss_wifi_vdev_mpsta_per_packet_rx_metadata { + uint16_t vdev_id; /**< Virtual device ID. */ + uint16_t peer_id; /**< Peer ID. */ +}; + +/** + * nss_wifi_vdev_rx_err_per_packet_metadata + * Per-packet metadata for error packets received. + */ +struct nss_wifi_vdev_rx_err_per_packet_metadata { + uint8_t peer_mac_addr[ETH_ALEN]; + /**< Peer MAC address. */ + uint8_t tid; /**< TID. */ + uint8_t vdev_id; /**< Virtual device ID. */ + uint8_t err_type; /**< Error type. */ + uint8_t rsvd[3]; /**< Reserved for future enhancement. */ +}; + +/** + * nss_wifi_vdev_extap_per_packet_metadata + * Per-packet metadata for ExtAP. + */ +struct nss_wifi_vdev_extap_per_packet_metadata { + uint16_t pkt_type; /**< ExtAP packet type. */ + uint8_t res[2]; /**< Reserved for 4-byte alignment. */ +}; + +/** + * nss_wifi_vdev_tx_compl_metadata + * Per-packet metadata for Tx completion message. + */ +struct nss_wifi_vdev_tx_compl_metadata { + uint8_t ta[ETH_ALEN]; /**< Transmitter MAC address. */ + uint8_t ra[ETH_ALEN]; /**< Receiver MAC address. */ + uint16_t ppdu_id; /**< PPDU ID. */ + uint16_t peer_id; /**< Peer ID. */ +}; + +/** + * nss_wifi_vdev_wds_info_type + * Specifies the type of WDS notification information. + */ +enum wifi_vdev_ext_wds_info_type { + NSS_WIFI_VDEV_WDS_TYPE_NONE = 0, + NSS_WIFI_VDEV_WDS_TYPE_RX, /**< Rx WDS entry. */ + NSS_WIFI_VDEV_WDS_TYPE_MEC, /**< Multicast Tx WDS entry. */ + NSS_WIFI_VDEV_WDS_TYPE_DA /**< Rx WDS entry for destination address. */ +}; + +/** + * nss_wifi_vdev_per_packet_metadata + * Payload of per-packet metadata. + */ +struct nss_wifi_vdev_wds_per_packet_metadata { + uint16_t peer_id; /**< Peer ID. */ + uint8_t is_sa_valid; /**< Specifies whether source address is valid. */ + uint8_t reserved; /**< Reserve bytes for alignment. */ + enum wifi_vdev_ext_wds_info_type wds_type; + /**< WDS message type. */ + uint8_t addr4_valid; /**< 802.11 4th address valid flag. */ + uint8_t rsvd; /**< Reserve bytes for alignment. */ + uint16_t sa_idx; /**< Source address index. */ + uint16_t sa_sw_peer_id; /**< Software/Address-Search-Table peer ID. */ +}; + +/** + * nss_wifi_vdev_ppdu_mdata_dir + * Physical layer protocol data unit (PPDU) metadata direction. + */ +enum nss_wifi_vdev_ppdu_mdata_dir { + WIFI_VDEV_PPDU_MDATA_TX, /**< PPDU metadata for transmit direction. */ + WIFI_VDEV_PPDU_MDATA_RX /**< PPDU metadata for receive direction. */ +}; + +/** + * nss_wifi_vdev_ppdu_metadata + * PPDU metadata. + */ +struct nss_wifi_vdev_ppdu_metadata { + uint32_t dir; /**< Data direction for metadata. */ + uint32_t ppdu_id; /**< PPDU ID. */ + uint16_t peer_id; /**< Peer ID. */ + uint8_t first_msdu; /**< First MSDU. */ + uint8_t last_msdu; /**< Last MSDU. */ +}; + +/** + * nss_wifi_vdev_per_packet_metadata + * Wi-Fi per packet metadata content. + */ +struct nss_wifi_vdev_per_packet_metadata { + uint32_t pkt_type; /**< Type of packet. */ + + /** + * Metadata payload for special data receive messages. + */ + union { + struct nss_wifi_vdev_igmp_per_packet_metadata igmp_metadata; + /**< Per packet metadata structure for IGMP. */ + struct nss_wifi_vdev_mesh_per_packet_metadata mesh_metadata; + /**< Per packet metadata structure for mesh mode. */ + struct nss_wifi_vdev_txinfo_per_packet_metadata txinfo_metadata; + /**< Per packet metadata structure for Tx information. */ + struct nss_wifi_vdev_mpsta_per_packet_tx_metadata mpsta_tx_metadata; + /**< Per packet Tx metadata structure for master-proxy station. */ + struct nss_wifi_vdev_mpsta_per_packet_rx_metadata mpsta_rx_metadata; + /**< Per packet Rx metadata structure for master-proxy station. */ + struct nss_wifi_vdev_rx_err_per_packet_metadata rx_err_metadata; + /**< Per packet metadata structure for Rx error. */ + struct nss_wifi_vdev_tx_compl_metadata tx_compl_metadata; + /**< Per packet Tx metadata structure for Tx completion. */ + struct nss_wifi_vdev_wds_per_packet_metadata wds_metadata; + /**< Per packet Tx metadata structure for wireless distribution system mode. */ + struct nss_wifi_vdev_ppdu_metadata ppdu_metadata; + /**< Per packet PPDU metadata needed for per PPDU copy mode. */ + } metadata; + /**< Metadata payload for special data receive message. */ +}; + +/** + * nss_wifi_vdev_meshmode_rx_metadata + * Metadata payload for Mesh mode receive. + */ +struct nss_wifi_vdev_meshmode_rx_metadata { + uint16_t rs_ratephy_lo; /**< PHY rate lower order bytes. */ + uint16_t rs_ratephy_hi; /**< PHY rate higher order bytes. */ + uint16_t cntr_chan_freq; /** Center channel frequency. */ + uint16_t vdev_id; /**< Virtual device ID. */ + uint16_t peer_id; /**< Peer ID. */ + uint16_t rs_rssi; /**< Received signal strength indication (noise floor adjusted). */ + uint8_t rs_flags; /**< First/last MSDU flags. */ + uint8_t rs_channel; /**< Operational channel. */ + uint8_t rs_keyix; /**< Key index. */ + uint8_t padd; /**< Padding to ensure alignment. */ +}; + +/** + * nss_wifi_vdev_rawmode_rx_metadata + * Metadata payload for Raw Mode receive. + */ +struct nss_wifi_vdev_rawmode_rx_metadata { + uint16_t vdev_id; /**< Virtual device ID. */ + uint16_t peer_id; /**< Peer ID. */ +}; + +/** + * nss_wifi_vdev_updchdr_msg + * Information for updating a cache header. + */ +struct nss_wifi_vdev_updchdr_msg { + uint32_t hdrcache[NSS_WIFI_HTT_TRANSFER_HDRSIZE_WORD]; + /**< Updated header cache. */ + uint32_t vdev_id; /**< Virtual device ID. */ +}; + +/** + * nss_wifi_vdev_me_host_sync_grp_entry + * Multicast enhancement host synchronization group table. + */ +struct nss_wifi_vdev_me_host_sync_grp_entry { + uint8_t group_addr[ETH_ALEN]; /**< Group address for this list. */ + uint8_t grp_member_addr[ETH_ALEN]; /**< MAC address of the multicast group member. */ + + /** + * Type of group addresses. + */ + union { + uint32_t grpaddr_ip4; + /**< IPv4 group address. */ + uint8_t grpaddr_ip6[NSS_WIFI_VDEV_IPV6_ADDR_LENGTH]; + /**< IPv6 group address. */ + } u; /**< Type of group addresses. */ + + uint32_t src_ip_addr; + /**< Source IP address. */ +}; + +/** + * wifi_vdev_me_host_sync_msg + * Synchronization message for a multicast enhancement host group. + */ +struct nss_wifi_vdev_me_host_sync_msg { + uint16_t vdev_id; /**< Virtual device ID. */ + uint8_t nentries; /**< Number of group entries carried by this message. */ + uint8_t radio_ifnum; /**< Interface number of the Wi-Fi radio. */ + struct nss_wifi_vdev_me_host_sync_grp_entry grp_entry[NSS_WIFI_VDEV_MAX_ME_ENTRIES]; + /**< Array for multicast group entries. */ +}; + +/** + * nss_wifi_vdev_mcast_enhance_stats + * Multicast enhancement-related statistics. + */ +struct nss_wifi_vdev_mcast_enhance_stats { + + /** + * Number of multicast packets recieved for multicast enhancement conversion. + */ + uint32_t mcast_rcvd; + + /** + * Number of unicast packets sent as part of multicast enhancement conversion. + */ + uint32_t mcast_ucast_converted; + + /** + * Number of multicast enhancement frames dropped because of a + * buffer allocation failure. + */ + uint32_t mcast_alloc_fail; + + /** + * Number of multicast enhancement frames dropped because of a + * buffer enqueue failure. + */ + uint32_t mcast_pbuf_enq_fail; + + /** + * Number of multicast enhancement frames dropped because of a + * buffer copy failure. + */ + uint32_t mcast_pbuf_copy_fail; + + /** + * Number of multicast enhancement frames dropped because of a + * failure in sending flow control to a peer. + */ + uint32_t mcast_peer_flow_ctrl_send_fail; + + /** + * Number of multicast enhancement buffer frames dropped when + * destination MAC is the same as source MAC. + */ + uint32_t mcast_loopback_err; + + /** + * Number of multicast enhancement buffer frames dropped + * because of an empty destination MAC. + */ + uint32_t mcast_dst_address_err; + + /** + * Number of multicast enhancement buffer frames dropped + * because no member is listening on the group. + */ + uint32_t mcast_no_enhance_drop_cnt; + + /** + * Number of multicast bytes received for multicast enhancement. + */ + uint32_t mcast_rcvd_bytes; + + /** + * Number of IGMP packets received for conversion to unicast. + */ + uint32_t igmp_rcvd; + + /** + * Number of IGMP packets converted to unicast as a part of + * VoW IGMP improvements. + */ + uint32_t igmp_ucast_converted; +}; + +/** + * nss_wifi_vdev_stats_sync_msg + * Message to get virtual device statistics from NSS Firmware to Host. + */ +struct nss_wifi_vdev_stats_sync_msg { + uint32_t dropped; /**< Number of dropped packets. */ + uint32_t tx_enqueue_cnt; /**< Transmit pnode enqueue count. */ + uint32_t tx_enqueue_fail_cnt; /**< Transmit pnode enqueue count. */ + uint32_t tx_intra_bss_enqueue_cnt; /**< Intra BSS enqueue count. */ + uint32_t tx_intra_bss_enqueue_fail_cnt; + /**< Intra BSS enqueue fail count. */ + uint32_t tx_intra_bss_mcast_send_cnt; + /**< Virual device multicast/broadcast packet count in AP mode. */ + uint32_t tx_intra_bss_mcast_send_fail_cnt; + /**< Virtual device multicast/broadcast packet count in AP mode. */ + uint32_t tx_enqueue_bytes; /**< Transmit enqueue bytes count. */ + uint32_t rx_enqueue_cnt; /**< Ethernet node enqueue count. */ + uint32_t rx_enqueue_fail_cnt; /**< Ethernet node enqueue fail count. */ + uint32_t rx_except_enqueue_cnt; /**< N2H (NSS to Host) node enqueue count. */ + uint32_t rx_except_enqueue_fail_cnt; /**< N2H (NSS to Host) node enqueue fail count. */ + uint32_t rx_enqueue_bytes; /**< Receive enqueue bytes count. */ + uint32_t rx_wds_learn_send_cnt; /**< Virtual device WDS source port learn count. */ + uint32_t rx_wds_learn_send_fail_cnt; /**< Virtual device WDS source count fail. */ + struct nss_wifi_vdev_mcast_enhance_stats wvmes; + /**< Multicast enhancement statistics. */ + uint32_t num_tx_exception; /**< Number of Tx exception to firmware. */ + uint32_t tx_dma_map_fail; /**< DMA map failure. */ + uint32_t tx_desc_alloc_fail; /**< Descriptor allocation failure. */ + uint32_t tx_hw_ring_full; /**< Hardware ring is full. */ + uint32_t tx_tso_pkt; /**< Number of TSO packets. */ + uint32_t tx_num_seg; /**< Number of segments in TSO packets. */ + uint32_t tx_rcvd; /**< Number of packets received from host. */ + uint32_t tx_rcvd_bytes; /**< Number of bytes received from host. */ + uint32_t cce_classified; + /**< Number of packets that are classified and sent to firmware as an exception. */ + uint32_t cce_classified_raw; + /**< Number of raw packets that are classified and sent to firmware as an exception. */ + uint32_t tx_eapol_cnt; /**< Number of EAPoL frames in transmit direction. */ + uint32_t nawds_tx_mcast_cnt; /**< Number of NAWDS packets sent. */ + uint32_t nawds_tx_mcast_bytes; /**< Number of NAWDS bytes sent. */ + uint32_t per_pkt_vdev_check_fail; /**< Number of packets that failed vdev id check in Tx. */ + uint32_t rx_mcast_cnt; /**< Receive multicast packet count. */ + uint32_t rx_mcast_bytes; /**< Receive multicast bytes count. */ + uint32_t rx_decrypt_err; /**< Receive decryption error */ + uint32_t rx_mic_err; /**< Receive MIC error */ +}; + +/** + * nss_wifi_vdev_msg + * Data for sending and receiving virtual device specific messages. + */ +struct nss_wifi_vdev_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a virtual device specific message. + */ + union { + struct nss_wifi_vdev_config_msg vdev_config; + /**< Virtual device configuration. */ + struct nss_wifi_vdev_enable_msg vdev_enable; + /**< Enable a message for a virtual device. */ + struct nss_wifi_vdev_cmd_msg vdev_cmd; + /**< Command message for a virtual device. */ + struct nss_wifi_vdev_me_snptbl_grp_create_msg vdev_grp_list_create; + /**< Creates the snooptable group of a virtual device. */ + struct nss_wifi_vdev_me_snptbl_grp_delete_msg vdev_grp_list_delete; + /**< Deletes a snooplist group list. */ + struct nss_wifi_vdev_me_snptbl_grp_mbr_add_msg vdev_grp_member_add; + /**< Adds a snooplist group member. */ + struct nss_wifi_vdev_me_snptbl_grp_mbr_delete_msg vdev_grp_member_remove; + /**< Removes a snooplist group member. */ + struct nss_wifi_vdev_me_snptbl_grp_mbr_update_msg vdev_grp_member_update; + /**< Updates a snooplist group member. */ + struct nss_wifi_vdev_me_snptbl_deny_grp_add_msg vdev_deny_member_add; + /**< Adds a snooplist member to a deny list. */ + struct nss_wifi_vdev_txmsg vdev_txmsgext; + /**< Transmits special data. */ + struct nss_wifi_vdev_vow_dbg_cfg_msg vdev_vow_dbg_cfg; + /**< Configures VoW debug statistics. */ + struct nss_wifi_vdev_vow_dbg_stats vdev_vow_dbg_stats; + /**< Types of VoW debug statistics. */ + struct nss_wifi_vdev_dscp_tid_map vdev_dscp_tid_map; + /**< DSCP-to-TID mapping. */ + struct nss_wifi_vdev_updchdr_msg vdev_updchdr; + /**< Updates a cache header. */ + struct nss_wifi_vdev_me_host_sync_msg vdev_me_sync; + /**< Message for a multicast enhancement host group table synchronization. */ + struct nss_wifi_vdev_stats_sync_msg vdev_stats; + /**< Message to get virtual device statistics from NSS firmware to host. */ + struct nss_wifi_vdev_set_next_hop_msg next_hop; + /**< Next hop message for virtual device. */ + struct nss_wifi_vdev_dscptid_map_id vdev_dscp_tid_map_id; + /**< Message to get DSCP-to-TID mapping id to be used on virtual device. */ + struct nss_wifi_vdev_extap_map vdev_extap_map; + /**< Message to add entry in EXTAP table on virtual device. */ + struct nss_wifi_vdev_qwrap_psta_msg vdev_qwrap_psta_map; + /**< Message to get PSTA VAP details in QWRAP mode. */ + struct nss_wifi_vdev_qwrap_isolation_en_msg vdev_qwrap_isolation_en; + /**< Message to enable QWRAP isolation mode. */ + struct nss_wifi_vdev_set_peer_next_hop_msg vdev_set_peer_next_hp; + /**< Message to set next hop per peer. */ + struct nss_wifi_vdev_vlan_config_msg vdev_vlan_config; + /**< Message to set VLAN configured on a particular virtual device. */ + struct nss_wifi_vdev_vlan_enable_msg vdev_vlan_enable; + /**< Message to enable VLAN tagging support on a particular virtual device. */ + struct nss_wifi_vdev_set_vlan_group_key vlan_group_key; + /**< Message to set group key for peer. */ + } msg; /**< Virtual device message payload. */ +}; + +/** + * nss_wifi_vdev_tx_msg + * Sends a Wi-Fi message to the NSS interface. + * + * @datatypes + * nss_ctx_instance \n + * nss_wifi_vdev_msg + * + * @param[in] nss_ctx Pointer to the NSS core context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_wifi_vdev_tx_msg(struct nss_ctx_instance *nss_ctx, + struct nss_wifi_vdev_msg *msg); + +/** + * nss_wifi_vdev_base_tx_msg + * Sends a Wi-Fi message to the NSS VAP interface. + * + * @datatypes + * nss_ctx_instance \n + * nss_wifi_vdev_msg + * + * @param[in] nss_ctx Pointer to the NSS core context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_wifi_vdev_base_tx_msg(struct nss_ctx_instance *nss_ctx, + struct nss_wifi_vdev_msg *msg); + +/** + * nss_wifi_vdev_tx_buf + * Sends a Wi-Fi data packet to the NSS interface. + * + * @datatypes + * nss_ctx_instance \n + * sk_buff + * + * @param[in] nss_ctx Pointer to the NSS core context. + * @param[in] os_buf Pointer to the OS data buffer. + * @param[in] if_num NSS interface number. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_wifi_vdev_tx_buf(struct nss_ctx_instance *nss_ctx, + struct sk_buff *os_buf, uint32_t if_num); + +/** + * Callback function for receiving Wi-Fi virtual device messages. + * + * @datatypes + * nss_cmn_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_wifi_vdev_msg_callback_t)(void *app_data, + struct nss_cmn_msg *msg); + +/** + * Callback function for receiving Wi-Fi virtual device data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + */ +typedef void (*nss_wifi_vdev_callback_t)(struct net_device *netdev, + struct sk_buff *skb, struct napi_struct *napi); + +/** + * Callback function for receiving extended data plane Wi-Fi virtual device data. + * + * @datatypes + * net_device \n + * sk_buff \n + * napi_struct + * + * @param[in] netdev Pointer to the associated network device. + * @param[in] skb Pointer to the data socket buffer. + * @param[in] napi Pointer to the NAPI structure. + * @param[in] netdev Pointer to the associated network device. + */ +typedef void (*nss_wifi_vdev_ext_data_callback_t)(struct net_device *netdev, + struct sk_buff *skb, struct napi_struct *napi); + +/** + * nss_wifi_vdev_msg_init + * Initializes a Wi-Fi virtual device message. + * + * @datatypes + * nss_wifi_vdev_msg \n + * nss_wifi_vdev_msg_callback_t + * + * @param[in] nim Pointer to the NSS interface message. + * @param[in] if_num NSS interface number. + * @param[in] type Type of message. + * @param[in] len Length of message. + * @param[in] cb Message callback. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +void nss_wifi_vdev_msg_init(struct nss_wifi_vdev_msg *nim, uint32_t if_num, uint32_t type, uint32_t len, + nss_wifi_vdev_msg_callback_t *cb, void *app_data); + +/** + * nss_register_wifi_vdev_if + * Registers a Wi-Fi virtual device interface with the NSS interface. + * + * @datatypes + * nss_ctx_instance \n + * nss_wifi_vdev_callback_t \n + * nss_wifi_vdev_ext_data_callback_t \n + * nss_wifi_vdev_msg_callback_t \n + * net_device + * + * @param[in,out] nss_ctx Pointer to the NSS core context. + * @param[in] if_num NSS interface number. + * @param[in] wifi_data_callback Callback for the Wi-Fi virtual device data. + * @param[in] vdev_ext_data_callback Callback for the extended data. + * @param[in] wifi_event_callback Callback for the message. + * @param[in] netdev Pointer to the associated network device. + * @param[in] features Data socket buffer types supported by this + * interface. + * + * @return + * None. + */ +uint32_t nss_register_wifi_vdev_if(struct nss_ctx_instance *nss_ctx, int32_t if_num, nss_wifi_vdev_callback_t wifi_data_callback, + nss_wifi_vdev_ext_data_callback_t vdev_ext_data_callback, nss_wifi_vdev_msg_callback_t wifi_event_callback, + struct net_device *netdev, uint32_t features); + +/** + * nss_unregister_wifi_vdev_if + * Deregisters a Wi-Fi virtual device interface from the NSS interface. + * + * @param[in] if_num NSS interface number. + * + * @return + * None. + */ +void nss_unregister_wifi_vdev_if(uint32_t if_num); + +/** + * nss_wifi_vdev_tx_msg_ext + * Sends Wi-Fi data packet along with metadata as message to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * sk_buff + * + * @param[in,out] nss_ctx Pointer to the NSS core context. + * @param[in] os_buf Pointer to the OS data buffer. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_wifi_vdev_tx_msg_ext(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf); + +/** + * nss_wifi_vdev_set_next_hop + * Send next hop message to Wi-Fi virtual device. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS core context. + * @param[in] if_num NSS interface number. + * @param[in] next_hop Next hop interface number. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_wifi_vdev_set_next_hop(struct nss_ctx_instance *nss_ctx, int if_num, int next_hop); + +/** + * nss_wifi_vdev_base_set_next_hop + * Sends the next hop message to Wi-Fi virtual access point. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS core context. + * @param[in] next_hop Next hop interface number. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_wifi_vdev_base_set_next_hop(struct nss_ctx_instance *nss_ctx, int next_hop); + +/** + * nss_wifi_vdev_set_peer_next_hop + * Sends the peer next hop message to Wi-Fi virtual device. + * + * @datatypes + * nss_ctx_instance + * + * @param[in] nss_ctx Pointer to the NSS core context. + * @param[in] nss_if NSS interface number. + * @param[in] addr Peer MAC address. + * @param[in] next_hop_if Next hop interface number. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_wifi_vdev_set_peer_next_hop(struct nss_ctx_instance *nss_ctx, uint32_t nss_if, uint8_t *addr, uint32_t next_hop_if); + +/* + * nss_wifi_vdev_set_dp_type + * Sets the datapath type for virtual device. + * + * @datatypes + * nss_ctx_instance \n + * net_device \n + * uint32_t \n + * enum nss_wifi_vdev_dp_type + * + * @param[in] nss_ctx Pointer to the NSS core context. + * @param[in] netdev Pointer to the associated network device. + * @param[in] if_num Interface number of the VAP. + * @param[in] dp_type Datapath type of the VAP. + * + * @return + * True if a success, or false if a failure. + */ +bool nss_wifi_vdev_set_dp_type(struct nss_ctx_instance *nss_ctx, struct net_device *netdev, + uint32_t if_num, enum nss_wifi_vdev_dp_type dp_type); +/** + * @} + */ + +#endif /* __NSS_WIFI_VDEV_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/exports/nss_wifili_if.h b/feeds/ipq807x/qca-nss-drv/src/exports/nss_wifili_if.h new file mode 100644 index 000000000..bffa04f93 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/exports/nss_wifili_if.h @@ -0,0 +1,1978 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + + /** + * @file nss_wifili_if.h + * NSS TO HLOS interface definitions. + * NOTE: Here we will use wifili as a reference to + * the IPQ807x Wi-Fi object. + */ +#ifndef __NSS_WIFILI_H +#define __NSS_WIFILI_H + + /** + * @addtogroup nss_wifili_subsystem + * @{ + */ + +#define NSS_WIFILI_MAX_SRNG_REG_GROUPS_MSG 2 + /**< Maximum srng (ring) register groups. */ +#define NSS_WIFILI_MAX_NUMBER_OF_PAGE_MSG 32 + /**< Maximum number of pages allocated from host. */ +#define NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG 4 + /**< Maximum number of Transmit Classifier data ring for NSS. */ +#define NSS_WIFILI_MAX_REO_DATA_RINGS_MSG 4 + /**< Maximum number of Rx reorder data ring for NSS. */ +#define NSS_WIFILI_SOC_PER_PACKET_METADATA_OFFSET 4 + /**< Metadata area for storing Rx statistics. */ +#define NSS_WIFILI_MAX_TXDESC_POOLS_MSG 4 + /**< Maximum number of Tx Descriptor software pools. */ +#define NSS_WIFILI_MAX_TX_EXT_DESC_POOLS_MSG 4 + /**< Maximum number of Tx Descriptor Extended software pools. */ +#define NSS_WIFILI_MAX_SOC_NUM 3 + /**< Maximum number of SoC devices. */ +#define NSS_WIFILI_MAX_PDEV_NUM_MSG 3 + /**< Maximum number of pdev devices. */ +#define NSS_WIFILI_MAX_MCS 12 + /**< Maximum Modulaton And Coding Scheme (MCS) count. */ +#define NSS_WIFILI_MAX_MCS_11A 8 + /**< Maximum MCS for 11a mode. */ +#define NSS_WIFILI_MAX_MCS_11B 7 + /**< Maximum MCS for 11b mode. */ +#define NSS_WIFILI_MAX_MCS_11AC 10 + /**< Maximum MCS for 11ac mode. */ +#define NSS_WIFILI_MAX_MCS_11AX 10 + /**< Maximum MCS for 11ax mode. */ +#define NSS_WIFILI_SS_COUNT 8 + /**< Maximum spatial streams count. */ +#define NSS_WIFILI_SUPPORTED_BW 4 + /**< Maximum number of bandwidth supported. */ +#define NSS_WIFILI_REPT_MU_MIMO 1 +#define NSS_WIFILI_REPT_MU_OFDMA_MIMO 3 +#define NSS_WIFILI_MAX_RESERVED_TYPE 3 + /**< Maximum reserved type. */ +#define NSS_WIFILI_SOC_PER_PACKET_METADATA_SIZE 60 + /**< Metadata area total size. */ +#define NSS_WIFILI_MEC_PEER_ID 0xDEAD + /**< MEC (Multicast echo check) peer ID. */ +#define NSS_WIFILI_DA_PEER_ID 0xDAAD + /**< Destination address peer ID. */ +#define NSS_WIFILI_MIC_KEY_LEN 8 + /**< MIC (Message integrity code) key length. */ +#define NSS_WIFILI_TQM_RR_MAX 7 + /**< Maximum transmit queue release reasons. */ +#define NSS_WIFILI_HTT_STATUS_MAX 7 + /**< Maximum HTT completion status. */ +#define NSS_WIFILI_TQM_STATUS_MAX 9 + /**< Maximum TQM completion status. */ +#define NSS_WIFILI_REO_CODE_MAX 15 + /**< Maximum Rx reorder error codes. */ +#define NSS_WIFILI_DMA_CODE_MAX 14 + /**< Maximum DMA error codes. */ +#define NSS_WIFILI_MAX_TID 8 + /**< Maximum TID values. */ +#define NSS_WIFILI_DELAY_INDEX_MAX 10 + /**< Maximum software enqueue delay buckets. */ +#define NSS_WIFILI_MAX_NUMBER_OF_ADDTNL_SEG 64 + /**< Maximum number of additional pages allocated from host. */ +#define NSS_WIFILI_SOC_ATTACHED_MAX_PDEV_NUM 1 + /**< Maximum number of physical devices on the external SoC. */ +#define NSS_WIFILI_PEER_AST_FLOWQ_MAX 4 + /**< Maximum number of flow queues. */ +#define NSS_WIFILI_WBM_INTERNAL_ERR_MAX 5 + /**< WBM internal maximum errors. */ + +/* + * Radio specific flags + */ +#define NSS_WIFILI_PDEV_FLAG_V3_STATS_ENABLED 0x00000008 + /**< Flag to enable version 3 statistics. */ +/** + * Peer message flags. + */ +#define NSS_WIFILI_PEER_MSG_DISABLE_4ADDR 0x01 + +/** + * nss_wifili_thread_scheme_id + * List of thread scheme IDs. + */ +enum nss_wifili_thread_scheme_id { + NSS_WIFILI_THREAD_SCHEME_ID_0, /**< High priority scheme index. */ + NSS_WIFILI_THREAD_SCHEME_ID_1, /**< Low priority scheme index. */ + NSS_WIFILI_THREAD_SCHEME_ID_2, /**< High priority scheme index. */ + NSS_WIFILI_THREAD_SCHEME_ID_MAX /**< Maximum value of scheme index. */ +}; + +/* + * nss_wifili_thread_scheme_priority + * List of wifili thread scheme priority. + */ +enum nss_wifili_thread_scheme_priority { + NSS_WIFILI_LOW_PRIORITY_SCHEME, /**< Low priority scheme. */ + NSS_WIFILI_HIGH_PRIORITY_SCHEME, /**< High priority scheme. */ +}; + +/** + * nss_wifili_wme_stream_classes + * WME stream classes. + */ +enum nss_wifili_wme_stream_classes { + NSS_WIFILI_WME_AC_BE, /**< Best effort. */ + NSS_WIFILI_WME_AC_BK, /**< Background. */ + NSS_WIFILI_WME_AC_VI, /**< Video. */ + NSS_WIFILI_WME_AC_VO, /**< Voice. */ + NSS_WIFILI_WME_AC_MAX /**< Maximum AC Value. */ +}; + +/** + * nss_wifili_packet_type + * Different Packet Types. + */ +enum nss_wifili_packet_type { + NSS_WIFILI_DOT11_A, /**< 802.11a packet type. */ + NSS_WIFILI_DOT11_B, /**< 802.11b packet type. */ + NSS_WIFILI_DOT11_N, /**< 802.11n packet type. */ + NSS_WIFILI_DOT11_AC, /**< 802.11ac packet type. */ + NSS_WIFILI_DOT11_AX , /**< 802.11ax packet type. */ + NSS_WIFILI_DOT11_MAX /**< Maximum 802.11 packet types. */ +}; + +/* + * nss_wifili_decap_pkt_type + * Different Decapsulation packet types + */ +enum wifili_decap_pkt_type { + NSS_WIFILI_DECAP_TYPE_RAW, /**< Raw packet type. */ + NSS_WIFILI_DECAP_TYPE_NATIVE_WIFI, /**< Native Wi-Fi packet type. */ + NSS_WIFILI_DECAP_TYPE_ETHERNET, /**< Ethernet packet type. */ + NSS_WIFILI_DECAP_TYPE_MAX, /**< Maximum packet type. */ +}; + +/** + * nss_wifili_msg_types + * NSS wifili messages. + */ +enum nss_wifili_msg_types { + NSS_WIFILI_INIT_MSG, + NSS_WIFILI_SOC_RESET_MSG, + NSS_WIFILI_PDEV_INIT_MSG, + NSS_WIFILI_PDEV_DEINIT_MSG, + NSS_WIFILI_START_MSG, + NSS_WIFILI_STOP_MSG, + NSS_WIFILI_PEER_CREATE_MSG, + NSS_WIFILI_PEER_DELETE_MSG, + NSS_WIFILI_SEND_PEER_MEMORY_REQUEST_MSG, + NSS_WIFILI_PEER_FREELIST_APPEND_MSG, + NSS_WIFILI_STATS_MSG, + NSS_WIFILI_WDS_VENDOR_MSG, + NSS_WIFILI_PEER_STATS_MSG, + NSS_WIFILI_WDS_PEER_ADD_MSG, + NSS_WIFILI_WDS_PEER_DEL_MSG, + NSS_WIFILI_WDS_PEER_MAP_MSG, + NSS_WIFILI_WDS_ACTIVE_INFO_MSG, + NSS_WIFILI_STATS_CFG_MSG, + NSS_WIFILI_TID_REOQ_SETUP_MSG, + NSS_WIFILI_RADIO_CMD_MSG, + NSS_WIFILI_LINK_DESC_INFO_MSG, + NSS_WIFILI_PEER_SECURITY_TYPE_MSG, + NSS_WIFILI_PEER_NAWDS_ENABLE_MSG, + NSS_WIFILI_RADIO_BUF_CFG, + NSS_WIFILI_DBDC_REPEATER_SET_MSG, + NSS_DBDC_REPEATER_AST_FLUSH_MSG, + NSS_WIFILI_SET_HMMC_DSCP_OVERRIDE_MSG, + NSS_WIFILI_SET_HMMC_DSCP_TID_MSG, + NSS_WIFILI_PDEV_STATS_V3_TXRX_SYNC_MSG, + NSS_WIFILI_PDEV_STATS_V3_DELAY_SYNC_MSG, + NSS_WIFILI_ENABLE_V3_STATS_MSG, + NSS_WIFILI_WDS_PEER_UPDATE_MSG, + NSS_WIFILI_STATS_V2_CFG_MSG, + NSS_WIFILI_SOJOURN_STATS_MSG, + NSS_WIFILI_PEER_SET_VLAN_ID, + NSS_WIFILI_UPDATE_PDEV_LMAC_ID_MSG, + NSS_WIFILI_PEER_AST_FLOWID_MAP_MSG, + NSS_WIFILI_PEER_MEC_AGEOUT_MSG, + NSS_WIFILI_JITTER_STATS_MSG, + NSS_WIFILI_ISOLATION_MSG, + NSS_WIFILI_PEER_EXT_STATS_MSG, + NSS_WIFILI_CLR_STATS, + NSS_WIFILI_PEER_4ADDR_EVENT_MSG, + NSS_WIFILI_MAX_MSG +}; + +/** + * nss_wifili_error_types + * Wifili error message types for functions. + */ +enum nss_wifili_error_types { + NSS_WIFILI_EMSG_NONE, + /**< No error. */ + NSS_WIFILI_EMSG_INIT_FAIL_IMPROPER_STATE, + /**< Device initialization failure due to improper state of device. */ + NSS_WIFILI_EMSG_RINGS_INIT_FAIL, + /**< Device ring initialization failure. */ + NSS_WIFILI_EMSG_PDEV_INIT_IMPROPER_STATE_FAIL, + /**< Radio initialization failure due to improper state of device. */ + NSS_WIFILI_EMSG_PDEV_INIT_INVALID_RADIOID_FAIL, + /**< Radio initialization failed due to invalid radio ID. */ + WIFILI_EMSG_PDEV_INIT_INVALID_TARGETPDEVID_FAIL, + /**< Radio initialization failed due to invalid target physical device ID. */ + NSS_WIFILI_EMSG_PDEV_TX_IRQ_ALLOC_FAIL, + /**< IRQ line allocation for radio transmission failed. */ + NSS_WIFILI_EMSG_PDEV_RESET_INVALID_RADIOID_FAIL, + /**< Radio reset failed due to invalid radio ID. */ + NSS_WIFILI_EMSG_PDEV_RESET_PDEV_NULL_FAIL, + /**< Radio reset failed due to NULL physical device. */ + NSS_WIFILI_EMSG_PDEV_RESET_IMPROPER_STATE_FAIL, + /**< Radio reset failed due to improper state of pdev. */ + NSS_WIFILI_EMSG_START_IMPROPER_STATE_FAIL, + /**< Device start fail due to improper state */ + NSS_WIFILI_EMSG_PEER_CREATE_FAIL, + /**< Peer creation failed. */ + NSS_WIFILI_EMSG_PEER_DELETE_FAIL, + /**< Peer deletion failed. */ + NSS_WIFILI_EMSG_HASHMEM_INIT_FAIL, + /**< Peer hash memory allocation failed. */ + NSS_WIFILI_EMSG_PEER_FREELIST_APPEND_FAIL, + /**< Appending peer to freelist failed. */ + NSS_WIFILI_EMSG_PEER_CREATE_INVALID_VDEVID_FAIL, + /**< Peer creation failure due to invalid virtual device ID. */ + NSS_WIFILI_EMSG_PEER_CREATE_INVALID_PEER_ID_FAIL, + /**< Peer creation failure due to invalid peer ID. */ + NSS_WIFILI_EMSG_PEER_CREATE_VDEV_NULL_FAIL, + /**< Peer creation failure due to NULL virtual device. */ + NSS_WIFILI_EMSG_PEER_CREATE_PDEV_NULL_FAIL, + /**< Peer creation failure due to NULL physical device. */ + NSS_WIFILI_EMSG_PEER_CREATE_ALLOC_FAIL, + /**< Peer creation failure due to memory allocation failure. */ + NSS_WIFILI_EMSG_PEER_DELETE_VAPID_INVALID_FAIL, + /**< Peer deletion failure due to invalid virtual device ID. */ + NSS_WIFILI_EMSG_PEER_DELETE_INVALID_PEERID_FAIL, + /**< Peer deletion failed due to invalid peer ID. */ + NSS_WIFILI_EMSG_PEER_DELETE_VDEV_NULL_FAIL, + /**< Peer deletion failure due to NULL virtual device. */ + NSS_WIFILI_EMSG_PEER_DELETE_PDEV_NULL_FAIL, + /**< Peer deletion failure due to NULL physical device. */ + NSS_WIFILI_EMSG_PEER_DELETE_PEER_NULL_FAIL, + /**< Peer deletion failure due to NULL peer. */ + NSS_WIFILI_EMSG_PEER_DELETE_PEER_CORRUPTED_FAIL, + /**< Peer creation failure due to corrupted peer. */ + NSS_WIFILI_EMSG_PEER_DUPLICATE_AST_INDEX_PEER_ID_FAIL, + /**< AST index provided is duplicate. */ + NSS_WIFILI_EMSG_GROUP0_TIMER_ALLOC_FAIL, + /**< Timer allocation failure. */ + NSS_WIFILI_EMSG_INSUFFICIENT_WT_FAIL, + /**< Insufficient worker thread error. */ + NSS_WIFILI_EMSG_INVALID_NUM_TCL_RING_FAIL, + /**< Invalid number of Transmit Classifier rings provided in initialization message. */ + NSS_WIFILI_EMSG_INVALID_NUM_REO_DST_RING_FAIL, + /**< Invalid number of Rx reorder destination ring in initialization message. */ + NSS_WIFILI_EMSG_HAL_SRNG_SOC_ALLOC_FAIL, + /**< Srng SoC memory allocation failure. */ + NSS_WIFILI_EMSG_HAL_SRNG_INVALID_RING_INFO_FAIL, + /**< Device ring information is invalid. */ + NSS_WIFILI_EMSG_HAL_SRNG_TCL_ALLOC_FAIL, + /**< Transmit Classifier srng ring allocation failure. */ + NSS_WIFILI_EMSG_HAL_SRNG_TXCOMP_ALLOC_FAIL, + /**< Txcomp srng ring allocation failure. */ + NSS_WIFILI_EMSG_HAL_SRNG_REODST_ALLOC_FAIL, + /**< Rx reorder destination srng ring allocation failure. */ + NSS_WIFILI_EMSG_HAL_SRNG_REOREINJECT_ALLOC_FAIL, + /**< Rx reorder reinject srng ring allocation failure. */ + NSS_WIFILI_EMSG_HAL_SRNG_RXRELEASE_ALLOC_FAIL, + /**< Rx release srng ring allocation failure. */ + NSS_WIFILI_EMSG_HAL_SRNG_RXEXCP_ALLOC_FAIL, + /**< Rx exception srng ring allocation failure. */ + NSS_WIFILI_EMSG_HAL_TX_MEMALLOC_FAIL, + /**< Tx HAL (hardware abstraction layer) srng ring allocation failure. */ + NSS_WIFILI_EMSG_HAL_TX_INVLID_POOL_NUM_FAIL, + /**< Invalid pool number in initialization message. */ + NSS_WIFILI_EMSG_HAL_TX_INVALID_PAGE_NUM_FAIL, + /**< Invalid page numner in initialization message. */ + NSS_WIFILI_EMSG_HAL_TX_DESC_MEM_ALLOC_FAIL, + /**< Tx descriptor memory allocation failure. */ + NSS_WIFILI_EMSG_HAL_RX_MEMALLOC_FAIL, + /**< Rx memory allocation failure. */ + NSS_WIFILI_EMSG_PDEV_RXDMA_RING_ALLOC_FAIL, + /**< Rx DMA ring allocation failed. */ + NSS_WIFILI_EMSG_NAWDSEN_PEERID_INVALID, + /**< Peer NAWDS enable failure due to invalid peer ID. */ + NSS_WIFILI_EMSG_NAWDSEN_PEER_NULL, + /**< Peer NAWDS enable failure due to peer being NULL. */ + NSS_WIFILI_EMSG_NAWDSEN_PEER_CORRUPTED, + /**< Peer NAWDS enable failure due to corrupted peer. */ + NSS_WIFILI_EMSG_WDS_PEER_CFG_FAIL, + /**< WDS peer configuration failure. */ + NSS_WIFILI_EMSG_RESET_NO_STOP, + /**< Reset issued without stopping the device. */ + NSS_WIFILI_EMSG_HAL_SRNG_INVALID_RING_BASE_FAIL, + /**< Ring base address is invalid. */ + NSS_WIFILI_EMSG_PDEV_RX_INIT_FAIL, + /**< Pdev Rx initialization failure. */ + NSS_WIFILI_EMESG_AST_ADD_FAIL, + /**< AST entry addition failure for connected peer. */ + NSS_WIFILI_EMESG_AST_REMOVE_FAIL, + /**< AST entry removal failure for connected peer. */ + NSS_WIFILI_EMESG_WDS_ADD_FAIL, + /**< WDS peer AST entry addition failure. */ + NSS_WIFILI_EMESG_WDS_REMOVE_FAIL, + /**< WDS peer AST entry removal failure. */ + NSS_WIFILI_EMESG_WDS_MAP_FAIL, + /**< WDS peer AST entry hardware index mapping failure. */ + NSS_WIFILI_EMSG_WDS_INVALID_PEERID_FAIL, + /**< Invalid peer id passed in WDS messages. */ + NSS_WIFILI_EMSG_WDS_DUPLICATE_AST_INDEX_PEER_ID_FAIL, + /**< AST entry index is already filled. */ + NSS_WIFILI_EMSG_INVALID_RADIO_CMD, + /**< Radio command is invalid. */ + NSS_WIFILI_EMSG_INVALID_RADIO_IFNUM, + /**< Radio interface number is invalid. */ + NSS_WIFILI_EMSG_PEER_SECURITY_PEER_NULL_FAIL, + /**< Security message failed as peer is NULL for a peer ID. */ + NSS_WIFILI_EMSG_PEER_SECURITY_PEER_CORRUPTED_FAIL, + /**< Security message failed as peer is corrupted. */ + NSS_WIFILI_EMSG_RADIO_INVALID_BUF_CFG, + /**< Buffer configuration message failed as invalid range value is provided. */ + NSS_WIFILI_EMSG_INIT_FAIL_INVALID_TARGET, + /**< Invalid target SoC type from host. */ + NSS_WIFILI_EMSG_PDEV_INIT_FAIL_INVALID_LMAC_ID, + /**< Invalid lower MAC ID from host. */ + NSS_WIFILI_EMSG_STATE_PDEV_NOT_INITIALIZED, + /**< Configured message issued when radio is not initialized. */ + NSS_WIFILI_EMESG_RX_TLV_INVALID, + /**< Invalid TLV length. */ + NSS_WIFILI_EMESG_RX_BUF_LEN_INVALID, + /**< Invalid Rx buffer length. */ + NSS_WIFILI_EMSG_UNKNOWN + /**< Unknown error message. */ +}; + +/** + * nss_wifili_soc_extended_data_types + * Enumeration of extended data type to host. + */ +enum nss_wifili_soc_extended_data_types { + NSS_WIFILI_SOC_EXT_DATA_PKT_TYPE_NONE, /**< Packet type is none. */ + NSS_WIFILI_SOC_EXT_DATA_PKT_MSDU_LINK_DESC, /**< Packet type is MSDU link descriptor. */ + NSS_WIFILI_SOC_EXT_DATA_PKT_INVALID_PEER, /**< Packet type is invalid peer. */ + NSS_WIFILI_SOC_EXT_DATA_PKT_MIC_ERROR, /**< Packet received with MIC error. */ + NSS_WIFILI_SOC_EXT_DATA_PKT_2K_JUMP_ERROR, /**< Packet received with 2K jump in sequence number. */ + NSS_WIFILI_SOC_EXT_DATA_PKT_WIFI_PARSE_ERROR, /**< Packet received with Wi-Fi parse error. */ + NSS_WIFILI_SOC_EXT_DATA_PKT_TYPE_MAX /**< Maximum extended data types. */ +}; + +/** + * nss_wifili_radio_cmd + * Wi-Fi radio commands for wifili. + */ +enum nss_wifili_radio_cmd { + NSS_WIFILI_RADIO_TX_CAPTURE_CMD, /**< Enable Tx capture. */ + NSS_WIFILI_SET_PRIMARY_RADIO, /**< Set current radio as primary. */ + NSS_WIFILI_SET_ALWAYS_PRIMARY, /**< Set always primary flag. */ + NSS_WIFILI_SET_FORCE_CLIENT_MCAST_TRAFFIC, /**< Flag to force multicast traffic for a radio. */ + NSS_WIFILI_SET_DROP_SECONDARY_MCAST, /**< Flag to drop multicast traffic on secondary radio. */ + NSS_WIFILI_SET_DBDC_FASTLANE, /**< Flag to set DBDC fast-lane mode. */ + NSS_WIFILI_RADIO_MAX_CMD /**< Maximum radio command index. */ +}; + +/* + * WARNING: There is a 1:1 mapping between values of enum nss_wifili_stats_txrx and corresponding + * statistics string array in nss_stats.c. + */ + +/** + * nss_wifili_stats_txrx + * Wifili Tx or Rx statistics. + */ +enum nss_wifili_stats_txrx { + NSS_WIFILI_STATS_RX_MSDU_ERROR, + /**< Number of Rx packets received from ring with MSDU error. */ + NSS_WIFILI_STATS_RX_INV_PEER_RCV, + /**< Number of Rx packets with invalid peer ID. */ + NSS_WIFILI_STATS_RX_WDS_SRCPORT_EXCEPTION, + /**< Number of Rx packets exceptioned to host because of source port learn fail. */ + NSS_WIFILI_STATS_RX_WDS_SRCPORT_EXCEPTION_FAIL, + /**< Number of Rx source port learn fail packets failed to get enqueued to host. */ + NSS_WIFILI_STATS_RX_DELIVERD, + /**< Number of packets wifili has given to next node. */ + NSS_WIFILI_STATS_RX_DELIVER_DROPPED, + /**< Number of packets which wifili failed to enqueue to next node. */ + NSS_WIFILI_STATS_RX_INTRA_BSS_UCAST, + /**< Number of packets that wifili sent for intra-BSS unicast packet. */ + NSS_WIFILI_STATS_RX_INTRA_BSS_UCAST_FAIL, + /**< Number of packets that wifili sent for intra-BSS unicast packet failed. */ + NSS_WIFILI_STATS_RX_INTRA_BSS_MCAST, + /**< Number of packets that wifili sent for intra-BSS multicast packet. */ + NSS_WIFILI_STATS_RX_INTRA_BSS_MCAST_FAIL, + /**< Number of packets that wifili sent for intra-BSS multicast packet failed. */ + NSS_WIFILI_STATS_RX_SG_RCV_SEND, + /**< Number of packets scatter-gather sent. */ + NSS_WIFILI_STATS_RX_SG_RCV_FAIL, + /**< Number of packets scatter-gather received failure. */ + NSS_STATS_WIFILI_RX_MCAST_ECHO, + /**< Number of multicast echo packets received. */ + NSS_STATS_WIFILI_RX_INV_TID, + /**< Number of invalid TID. */ + + /* + * TODO: Move per TID based + */ + NSS_WIFILI_STATS_RX_FRAG_INV_SC, + /**< Number of fragments with invalid sequence control. */ + NSS_WIFILI_STATS_RX_FRAG_INV_FC, + /**< Number of fragments with invalid frame control. */ + NSS_WIFILI_STATS_RX_FRAG_NON_FRAG, + /**< Number of non-fragments received in fragments. */ + NSS_WIFILI_STATS_RX_FRAG_RETRY, + /**< Number of retries for fragments. */ + NSS_WIFILI_STATS_RX_FRAG_OOO, + /**< Number of out-of-order fragments. */ + NSS_WIFILI_STATS_RX_FRAG_OOO_SEQ, + /**< Number of out-of-order sequence. */ + NSS_WIFILI_STATS_RX_FRAG_ALL_FRAG_RCV, + /**< Number of times all fragments for a sequence has been received. */ + NSS_WIFILI_STATS_RX_FRAG_DELIVER, + /**< Number of fragments delivered to host. */ + NSS_WIFILI_STATS_TX_ENQUEUE, + /**< Number of packets that got enqueued to wifili. */ + NSS_WIFILI_STATS_TX_ENQUEUE_DROP, + /**< Number of packets that dropped during enqueue to wifili. */ + NSS_WIFILI_STATS_TX_DEQUEUE, + /**< Number of packets that are dequeued by wifili. */ + NSS_WIFILI_STATS_TX_HW_ENQUEUE_FAIL, + /**< Number of Rx packets that NSS Wi-Fi offload path could successfully process. */ + NSS_WIFILI_STATS_TX_SENT_COUNT, + /**< Number of Tx packets sent to hardware. */ + NSS_WIFILI_STATS_TXRX_MAX, + /**< Number of maximum Tx or Rx statistics. */ +}; + +/* + * WARNING: There is a 1:1 mapping between values of enum nss_wifili_stats_tcl and corresponding + * statistics string array in nss_stats.c. + */ + +/** + * nss_wifili_stats_tcl + * Wifili transmit classifier statistics. + */ +enum nss_wifili_stats_tcl { + NSS_WIFILI_STATS_TCL_NO_HW_DESC, /**< Number of transmit classifier hardware descriptor. */ + NSS_WIFILI_STATS_TCL_RING_FULL, /**< Number of times transmit classifier ring was full. */ + NSS_WIFILI_STATS_TCL_RING_SENT, /**< Number of times transmit classifier descriptor sent. */ + NSS_WIFILI_STATS_TCL_MAX, /**< Number of maximum transmit classifier statistics. */ +}; + +/* + * WARNING: There is a 1:1 mapping between values of enum nss_wifili_stats_tx_comp and corresponding + * statistics string array in nss_stats.c. + */ + +/** + * nss_wifili_stats_tx_comp + * Wifili Tx completion statistics. + */ +enum nss_wifili_stats_tx_comp { + NSS_WIFILI_STATS_TX_DESC_FREE_INV_BUFSRC, /**< Number of invalid buffer source packets. */ + NSS_WIFILI_STATS_TX_DESC_FREE_INV_COOKIE, /**< Number of invalid cookie packets. */ + NSS_WIFILI_STATS_TX_DESC_FREE_HW_RING_EMPTY, /**< Number of times hardware ring empty found. */ + NSS_WIFILI_STATS_TX_DESC_FREE_REAPED, /**< Number of Tx packets that are reaped out of the Tx completion ring. */ + NSS_WIFILI_STATS_TX_DESC_FREE_MAX, /**< Number of Tx completion statistics. */ +}; + +/* + * WARNING: There is a 1:1 mapping between values of enum nss_wifili_stats_reo and corresponding + * statistics string array in nss_stats.c. + */ + +/** + * nss_wifili_stats_reo + * Wifili Rx reorder statistics. + */ +enum nss_wifili_stats_reo { + NSS_WIFILI_STATS_REO_ERROR, /**< Number of reorder error. */ + NSS_WIFILI_STATS_REO_REAPED, /**< Number of reorder reaped. */ + NSS_WIFILI_STATS_REO_INV_COOKIE, /**< Number of invalid cookie. */ + NSS_WIFILI_STATS_REO_FRAG_RCV, /**< Number of fragmented packets received. */ + NSS_WIFILI_STATS_REO_MAX, /**< Number of reorder statistics. */ +}; + +/* + * WARNING: There is a 1:1 mapping between values of enum nss_wifili_stats_txsw_pool and corresponding + * statistics string array in nss_stats.c. + */ + +/** + * nss_wifili_stats_txsw_pool + * Wifili Tx descriptor statistics. + */ +enum nss_wifili_stats_txsw_pool { + NSS_WIFILI_STATS_TX_DESC_IN_USE, /**< Number of Tx packets that are currently in flight. */ + NSS_WIFILI_STATS_TX_DESC_ALLOC_FAIL, /**< Number of Tx software descriptor allocation failures. */ + NSS_WIFILI_STATS_TX_DESC_ALREADY_ALLOCATED, /**< Number of Tx software descriptor already allocated. */ + NSS_WIFILI_STATS_TX_DESC_INVALID_FREE, /**< Number of Tx software descriptor invalid free. */ + NSS_WIFILI_STATS_TX_DESC_FREE_SRC_FW, /**< Number of Tx descriptor for which release source is firmware. */ + NSS_WIFILI_STATS_TX_DESC_FREE_COMPLETION, /**< Number of Tx descriptor completion. */ + NSS_WIFILI_STATS_TX_DESC_NO_PB, /**< Number of Tx descriptor pbuf is NULL. */ + NSS_WIFILI_STATS_TX_QUEUELIMIT_DROP, /**< Number of Tx dropped because of queue limit. */ + NSS_WIFILI_STATS_TX_DESC_MAX, /**< Number of Tx descriptor statistics. */ +}; + +/* + * WARNING: There is a 1:1 mapping between values of enum nss_wifili_stats_ext_txsw_pool and corresponding + * statistics string array in nss_stats.c + */ + +/** + * nss_wifili_stats_ext_txsw_pool + * Wifili Rx extended descriptor statistics. + */ +enum nss_wifili_stats_ext_txsw_pool { + NSS_WIFILI_STATS_EXT_TX_DESC_IN_USE, /**< Number of extended Tx packets that are currently in flight. */ + NSS_WIFILI_STATS_EXT_TX_DESC_ALLOC_FAIL, /**< Number of extended Tx software descriptor allocation failures. */ + NSS_WIFILI_STATS_EXT_TX_DESC_ALREADY_ALLOCATED, /**< Number of extended Tx software descriptor already allocated. */ + NSS_WIFILI_STATS_EXT_TX_DESC_INVALID_FREE, /**< Number of extended Tx software descriptor invalid free. */ + NSS_WIFILI_STATS_EXT_TX_DESC_MAX, /**< Number of extended Tx descriptor statistics. */ +}; + +/* + * WARNING: There is a 1:1 mapping between values of enum nss_wifili_stats_rxdma_pool and corresponding + * statistics string array in nss_stats.c + */ + +/** + * nss_wifili_stats_rxdma_pool + * Wifili Rx descriptor statistics. + */ +enum nss_wifili_stats_rxdma_pool { + NSS_WIFILI_STATS_RX_DESC_NO_PB, /**< Number of Rx descriptors that have no pbufs. */ + NSS_WIFILI_STATS_RX_DESC_ALLOC_FAIL, /**< Number of Rx descriptor allocation failures. */ + NSS_WIFILI_STATS_RX_DESC_IN_USE, /**< Number of Rx descriptor allocations in use. */ + NSS_WIFILI_STATS_RX_DESC_MAX, /**< Maximum number of Rx descriptor statistics. */ +}; + +/* + * WARNING: There is a 1:1 mapping between values of enum nss_wifili_stats_rxdma_ring and corresponding + * statistics string array in nss_stats.c. + */ + +/** + * nss_wifili_stats_rxdma_ring + * Wifili Rx DMA(Direct Memory Access) ring statistics. + */ +enum nss_wifili_stats_rxdma_ring { + NSS_WIFILI_STATS_RXDMA_DESC_UNAVAILABLE, /**< Number of Rx DMA descriptor unavailable. */ + NSS_WIFILI_STATS_RXDMA_BUF_REPLENISHED, /**< Number of Rx DMA buffer replenished. */ + NSS_WIFILI_STATS_RXDMA_DESC_MAX, /**< Number of Rx DMA descriptor statistics. */ +}; + +/* + * WARNING: There is a 1:1 mapping between values of enum nss_wifili_stats_wbm and corresponding + * statistics string array in nss_stats.c. + */ + +/** + * nss_wifili_stats_wbm + * Wifili WBM(Wireless Buffer Manager) ring statistics. + */ +enum nss_wifili_stats_wbm { + NSS_WIFILI_STATS_WBM_IE_LOCAL_ALLOC_FAIL, /**< Number of Wireless Buffer Manager internal local allocation failures. */ + NSS_WIFILI_STATS_WBM_SRC_DMA, /**< Number of receive invalid source DMA. */ + NSS_WIFILI_STATS_WBM_SRC_DMA_CODE_INV, /**< Number of receive invalid source DMA. */ + NSS_WIFILI_STATS_WBM_SRC_REO, /**< Number of receive invalid source reorder. */ + NSS_WIFILI_STATS_WBM_SRC_REO_CODE_NULLQ, /**< Number of receive invalid reorder error with NULL queue. */ + NSS_WIFILI_STATS_WBM_SRC_REO_CODE_INV, /**< Number of receive invalid reorder code invalid. */ + NSS_WIFILI_STATS_WBM_SRC_INV, /**< Number of receive invalid source invalid. */ + NSS_WIFILI_STATS_WBM_MAX, /**< Number of receive Wireless Buffer Manager statistics. */ +}; + +/** + * nss_wifili_stats + * NSS wifili statistics. + */ +struct nss_wifili_stats { + uint64_t stats_txrx[NSS_WIFILI_MAX_PDEV_NUM_MSG][NSS_WIFILI_STATS_TXRX_MAX]; + /**< Number of Tx or Rx statistics. */ + uint64_t stats_tcl_ring[NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG][NSS_WIFILI_STATS_TCL_MAX]; + /**< TCL statistics for each ring. */ + uint64_t stats_tx_comp[NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG][NSS_WIFILI_STATS_TX_DESC_FREE_MAX]; + /**< Tx completion ring statistics. */ + uint64_t stats_tx_desc[NSS_WIFILI_MAX_TXDESC_POOLS_MSG][NSS_WIFILI_STATS_TX_DESC_MAX]; + /**< Tx descriptor pool statistics. */ + uint64_t stats_ext_tx_desc[NSS_WIFILI_MAX_TX_EXT_DESC_POOLS_MSG][NSS_WIFILI_STATS_EXT_TX_DESC_MAX]; + /**< Tx extended descriptor pool statistics. */ + uint64_t stats_reo[NSS_WIFILI_MAX_REO_DATA_RINGS_MSG][NSS_WIFILI_STATS_REO_MAX]; + /**< Rx reorder ring statistics. */ + uint64_t stats_rx_desc[NSS_WIFILI_MAX_PDEV_NUM_MSG][NSS_WIFILI_STATS_RX_DESC_MAX]; + /**< Rx software pool statistics. */ + uint64_t stats_rxdma[NSS_WIFILI_MAX_PDEV_NUM_MSG][NSS_WIFILI_STATS_RXDMA_DESC_MAX]; + /**< Rx DMA ring statistics. */ + uint64_t stats_wbm[NSS_WIFILI_STATS_WBM_MAX]; + /**< Wireless Buffer Manager error ring statistics. */ +}; + +/* + * NSS wifili soc stats + */ +struct nss_wifili_soc_stats { + uint32_t soc_maxpdev; /**< Maximum number of radios per SoC. */ + struct nss_wifili_stats stats_wifili; + /**< Per-SoC statistics. */ +}; + +/** + * nss_wifili_stats_notification + * Data for sending wifili statistics. + */ +struct nss_wifili_stats_notification { + uint32_t core_id; /**< Core ID. */ + uint32_t if_num; /**< Interface number for this wifili. */ + struct nss_wifili_stats stats; /**< Wifili statistics. */ +}; + +#ifdef __KERNEL__ /* only kernel will use. */ + +/** + * nss_wifili_hal_srng_info + * Wifili HAL srng information. + */ +struct nss_wifili_hal_srng_info{ + uint8_t ring_id; + /**< Ring ID. */ + uint8_t mac_id; + /**< Pdev ID. */ + uint8_t resv[2]; + uint32_t ring_base_paddr; + /**< Physical base address of the ring. */ + uint32_t num_entries; + /**< Number of entries in ring. */ + uint32_t flags; /**< Miscellaneous flags. */ + uint32_t ring_dir; + /**< Ring direction: source or destination. */ + uint32_t entry_size; + /**< Ring entry size. */ + uint32_t low_threshold; + /**< Low threshold – in number of ring entries (valid for source rings only). */ + uint32_t hwreg_base[NSS_WIFILI_MAX_SRNG_REG_GROUPS_MSG]; + /**< Hardware ring base address. */ +}; + +/** + * nss_wifili_hal_srng_soc_msg + * Wifili hal srng message. + */ +struct nss_wifili_hal_srng_soc_msg { + uint32_t dev_base_addr; + /**< Base address of WLAN device. */ + uint32_t shadow_rdptr_mem_addr; + /**< Shadow read pointer address. */ + uint32_t shadow_wrptr_mem_addr; + /**< Shadow write pointer address. */ +}; + +/** + * struct wifili_tx_desc_addtnl_mem_msg + * Wifili additional host memory message for increeased descriptors + */ +struct nss_wifili_tx_desc_addtnl_mem_msg { + uint32_t num_addtnl_addr; + /**< Number of additional memory pages provided. */ + uint32_t addtnl_memory_addr[NSS_WIFILI_MAX_NUMBER_OF_ADDTNL_SEG]; + /**< Physical memory addresse of each additional page. */ + uint32_t addtnl_memory_size[NSS_WIFILI_MAX_NUMBER_OF_ADDTNL_SEG]; + /**< Size of each additional page. */ +}; + +/** + * nss_wifili_tx_desc_init_msg + * Wifili software descriptor pool initialization message. + */ +struct nss_wifili_tx_desc_init_msg { + uint32_t num_tx_desc; + /**< Count of the software descriptors. */ + uint32_t num_tx_desc_ext; + /**< Count of software extented descriptors. */ + uint32_t num_pool; + /**< Number of descriptor pools. */ + uint32_t memory_addr[NSS_WIFILI_MAX_NUMBER_OF_PAGE_MSG]; + /**< Memory start address of each page. */ + uint32_t memory_size[NSS_WIFILI_MAX_NUMBER_OF_PAGE_MSG]; + /**< Memory size. */ + uint32_t num_memaddr; + /**< Number of memory address. */ + uint32_t ext_desc_page_num; + /**< Extended descriptor page number. */ + uint32_t num_tx_desc_2; + /**< Count of the software descriptors for second radio. */ + uint32_t num_tx_desc_ext_2; + /**< Count of software extended descriptors for second radio. */ + uint32_t num_tx_desc_3; + /**< Count of the software descriptors for third radio. */ + uint32_t num_tx_desc_ext_3; + /**< Count of software extended descriptors for third radio. */ + uint32_t num_tx_device_limit; + /**< Count of software Tx descriptors for the device. */ +}; + +/** + * nss_wifili_rx_init_param + * Rx initialization parameters. + */ +struct nss_wifili_rx_init_param { + uint16_t tlv_size; /**< Size of Rx TLV structure. */ + uint16_t rx_buf_len; /**< Rx buffer length programmed to hardware. */ +}; + +/** + * nss_wifili_init_msg + * Wifili SoC initialization message. + */ +struct nss_wifili_init_msg { + struct nss_wifili_hal_srng_soc_msg hssm; + uint8_t num_tcl_data_rings; + /**< Number of Transmit Classifier data rings. */ + uint8_t num_reo_dest_rings; + /**< Number of Rx reorder rings. */ + uint8_t flags; + /**< Flags for SoC initialization */ + uint8_t soc_mem_profile; + /**< SoC memory profile (256M/512M/1G). */ + struct nss_wifili_hal_srng_info tcl_ring_info[NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG]; + /**< Transmit Classifier data ring configuration information. */ + struct nss_wifili_hal_srng_info tx_comp_ring[NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG]; + /**< Tx completion ring configuration information. */ + struct nss_wifili_hal_srng_info reo_dest_ring[NSS_WIFILI_MAX_REO_DATA_RINGS_MSG]; + /**< Rx reorder destination ring configuration information. */ + struct nss_wifili_hal_srng_info reo_exception_ring; + /**< Rx reorder exception ring configuration information. */ + struct nss_wifili_hal_srng_info rx_rel_ring; + /**< Wireless Buffer Manager release ring configuration information. */ + struct nss_wifili_hal_srng_info reo_reinject_ring; + /**< Reinject ring configuration information. */ + struct nss_wifili_tx_desc_init_msg wtdim; + /**< Tx descriptor initialization message. */ + uint32_t target_type; + /**< Target type based on SoC. */ + struct nss_wifili_rx_init_param wrip; + /**< Rx parameters to initialize Rx context. */ + struct nss_wifili_tx_desc_addtnl_mem_msg wtdam; + /**< Tx descriptor additional memory message. */ + uint32_t tx_sw_internode_queue_size; + /**< Tx software internode queue size. */ +}; + +/** + * nss_wifili_pdev_deinit_msg + * Wifili pdev deinit message. + */ +struct nss_wifili_pdev_deinit_msg { + uint32_t ifnum; /**< NSS interface number of pdev. */ +}; + +/** + * nss_wifili_pdev_init_msg + * Wifili pdev initialization message. + */ +struct nss_wifili_pdev_init_msg { + struct nss_wifili_hal_srng_info rxdma_ring; + /**< MAC (Media Access Control) ring configuration. */ + uint32_t radio_id; + /**< MAC radio ID. */ + uint32_t hwmode; + /**< MAC hardware mode. */ + uint32_t lmac_id; + /**< Lower MAC ID. */ + uint32_t num_rx_swdesc; + /**< Number of descriptors per Rx pool. */ + uint32_t target_pdev_id; + /**< Target physical device ID. */ + uint8_t scheme_id; + /**< Radio scheme ID. */ + uint8_t reserved[3]; + /**< Padding for alignment. */ +}; + +/** + * nss_wifili_peer_ast_flowid_map_msg + * Wifili peer AST flow ID map message. + */ +struct nss_wifili_peer_ast_flowid_map_msg { + uint8_t peer_mac_addr[ETH_ALEN]; + /**< Peer MAC address. */ + uint16_t vdev_id; + /**< VAP ID. */ + uint16_t ast_idx[NSS_WIFILI_PEER_AST_FLOWQ_MAX]; + /**< Address search table index. */ + uint8_t tid_valid_mask[NSS_WIFILI_PEER_AST_FLOWQ_MAX]; + /**< TID valid mask for a flow. */ + uint8_t is_valid[NSS_WIFILI_PEER_AST_FLOWQ_MAX]; + /**< Valid bit. */ + uint8_t flowQ[NSS_WIFILI_PEER_AST_FLOWQ_MAX]; + /**< Flow queue. */ + uint16_t peer_id; + /**< Peer ID. */ + uint8_t reserved[2]; + /**< Padding for alignment. */ +}; + +/** + * nss_wifili_peer_ast + * Wifili peer creation message. + */ +struct nss_wifili_peer_msg { + uint8_t peer_mac_addr[6]; + /**< Peer MAC address. */ + uint16_t vdev_id; + /**< VAP ID. */ + uint16_t peer_id; + /**< Peer ID. */ + uint16_t hw_ast_idx; + /**< Hardware address search table index. */ + uint8_t is_nawds; + /**< NAWDS enabled for peer. */ + uint8_t pext_stats_valid; + /**< Peer extended statistics valid. */ + uint16_t psta_vdev_id; + /**< Proxy station VAP ID. */ + uint32_t nss_peer_mem; + /**< Holds peer memory adderss for NSS. */ + uint32_t tx_ast_hash; + /**< AST hash to be used during packet transmission. */ + uint32_t pext_stats_mem; + /**< Peer extended statistics memory. */ + uint32_t flags; + /**< Peer flags. */ +}; + +/** + * nss_wifili_peer_freelist_append_msg + * Peer memory request. + */ +struct nss_wifili_peer_freelist_append_msg { + uint32_t addr; + /**< Starting address of peer_freelist pool. */ + uint32_t length; + /**< Length of peer freelist pool. */ + uint32_t num_peers; + /**< Maximum number of peer entries supported in pool. */ +}; + +/** + * nss_wifili_wds_extn_peer_cfg_msg + * Configuration information when the WDS vendor extension is enabled. + */ +struct nss_wifili_wds_extn_peer_cfg_msg { + uint8_t peer_mac_addr[ETH_ALEN]; /**< Peer MAC address. */ + uint8_t wds_flags; /**< WDS flags populated from the host. */ + uint8_t reserved; /**< Alignment padding. */ + uint16_t peer_id; /**< Peer ID. */ +}; + +/** + * nss_wifili_tx_stats + * Tx statistics. + */ +struct nss_wifili_tx_stats { + uint32_t tx_enqueue_dropped; + /**< Tx enqueue drop count. */ + uint32_t tx_enqueue_cnt; + /**< Tx enqueue succesful count. */ + uint32_t tx_dequeue_cnt; + /**< Tx dequeue count. */ + uint32_t tx_send_fail_cnt; + /**< Hardware send failure count. */ + uint32_t inv_peer; + /**< Invalid peer enqueue count. */ + uint32_t inv_peer_drop_byte_cnt; + /**< Invalid peer drop byte count. */ + uint32_t tx_input_pkt; + /**< Tx packets ready to sent. */ + uint32_t tx_processed_pkt; + /**< Tx numner of packets sent. */ + uint32_t tx_processed_bytes; + /**< Tx number of bytes processed. */ +}; + +/** + * nss_wifili_rx_stats + * Rx statistics. + */ +struct nss_wifili_rx_stats { + uint32_t rx_msdu_err; + /**< Rx msdu error count. */ + uint32_t rx_inv_peer; + /**< Rx invalid peer count. */ + uint32_t rx_scatter_inv_peer; + /**< Rx scatter invalid peer count. */ + uint32_t rx_wds_learn_send; + /**< WDS source port learn packet. */ + uint32_t rx_wds_learn_send_fail; + /**< WDS source port learn exception send failure count. */ + uint32_t rx_send_dropped; + /**< Rx send dropped count. */ + uint32_t rx_deliver_cnt; + /**< Rx deliver count to next node. */ + uint32_t rx_deliver_cnt_fail; + /**< Rx deliver count failure. */ + uint32_t rx_intra_bss_ucast_send; + /**< Intra-BSS unicast sent count. */ + uint32_t rx_intra_bss_ucast_send_fail; + /**< Intra-BSS unicast send failure count. */ + uint32_t rx_intra_bss_mcast_send; + /**< Intra-BSS multicast send count. */ + uint32_t rx_intra_bss_mcast_send_fail; + /**< Intra-BSS multicast send failure count. */ + uint32_t rx_sg_recv_send; + /**< Rx scatter-gather receive send count. */ + uint32_t rx_sg_recv_fail; + /**< Rx scatter-gather receive failure count. */ + uint32_t rx_me_pkts; /**< Rx multicast echo packets count. */ + uint32_t rx_inv_tid; /**< Rx invalid TID. */ + + /* + * TODO: Move per tid based. + */ + uint32_t rx_frag_inv_sc; /**< Rx invalid frame sequence control. */ + uint32_t rx_frag_inv_fc; /**< Rx invalid frame control count. */ + uint32_t rx_non_frag_err; /**< Rx non-fragment received in fragmention. */ + uint32_t rx_repeat_fragno; /**< Rx fragment retry counters. */ + uint32_t rx_ooo_frag; /**< Rx out-of-order fragments count. */ + uint32_t rx_ooo_frag_seq; /**< Rx out-of-order sequence count. */ + uint32_t rx_all_frag_rcv; /**< Rx all fragments received count. */ + uint32_t rx_frag_deliver; /**< Rx fragment deliver counters. */ +}; + +/** + * nss_wifili_tx_tcl_ring_stats + * Transmit Classifier ring specific statistics. + */ +struct nss_wifili_tx_tcl_ring_stats { + uint32_t tcl_no_hw_desc; /**< Number of Transmit Classifier hardware descriptors. */ + uint32_t tcl_ring_full; /**< Number of times Transmit Classifier ring full. */ + uint32_t tcl_ring_sent; /**< Total number of ring sent. */ +}; + +/** + * nss_wifili_tx_comp_ring_stats + * Tx completion ring statistics. + */ +struct nss_wifili_tx_comp_ring_stats { + uint32_t invalid_bufsrc; /**< Tx comp (Completion) ring descriptor invalid buffer source. */ + uint32_t invalid_cookie; /**< Tx comletion ring descriptor has invalid cookies. */ + uint32_t hw_ring_empty; /**< Tx completion hardware ring empty. */ + uint32_t ring_reaped; /**< Tx completion successfull ring reaped. */ +}; + +/** + * nss_wifili_tx_sw_pool_stats + * Tx completion sw statistics. + */ +struct nss_wifili_tx_sw_pool_stats { + uint32_t desc_alloc; /**< Tx descriptor software pool descriptor in use. */ + uint32_t desc_alloc_fail; /**< Tx descriptor software pool allocation failure . */ + uint32_t desc_already_allocated; /**< Tx descriptor re-allocation for allocated descriptor. */ + uint32_t desc_invalid_free; /**< Tx descriptor freeing of allocated descriptor. */ + uint32_t tx_rel_src_fw; /**< Tx descriptor source is firmware. */ + uint32_t tx_rel_ext_desc; /**< Tx descriptor scatter-gather. */ + uint32_t tx_rel_tx_desc; /**< Tx descriptor source is hardware*/ + uint32_t tx_rel_no_pb; /**< Tx descriptor has pbuf present. */ + uint32_t tx_queue_limit_drop; /**< Tx number of packets dropped because of queueing limits. */ +}; + +/** + * wifili_tx_ext_sw_pool_stats + * Tx extended descriptor pool. + */ +struct nss_wifili_tx_ext_sw_pool_stats { + uint32_t desc_alloc; /**< Tx extend (scatter gather) descriptor in use. */ + uint32_t desc_alloc_fail; /**< Tx extend descriptor allocation failure. */ + uint32_t desc_already_allocated; /**< Tx extend descriptor already allocated. */ + uint32_t desc_invalid_free; /**< Tx descriptor invalid source. */ + +}; + +/** + * nss_wifili_rx_wbm_ring_stats + * WBM (Wireless Buffer Manager) release ring statistics. + */ +struct nss_wifili_rx_wbm_ring_stats { + uint32_t invalid_buf_mgr; /**< Invalid buffer manager. */ + uint32_t err_src_rxdma; /**< Wireless Buffer Manager source is Rx DMA ring. */ + uint32_t err_src_rxdma_code_inv; /**< Wireless Buffer Manager source DMA reason unknown. */ + uint32_t err_src_reo; /**< Wireless Buffer Manager source is receive reorder ring. */ + uint32_t err_src_reo_code_nullq; /**< Wireless Buffer Manager source receive reorder ring because of NULL TLV. */ + uint32_t err_src_reo_code_inv; /**< Wireless Buffer Manager source receive reorder ring reason unknown. */ + uint32_t err_src_invalid; /**< Wireless Buffer Manager source is unknown. */ + uint32_t err_reo_codes[NSS_WIFILI_REO_CODE_MAX]; + /**< Receive reoder error codes. */ + uint32_t err_dma_codes[NSS_WIFILI_DMA_CODE_MAX]; + /**< DMA error codes. */ + uint32_t err_internal_codes[NSS_WIFILI_WBM_INTERNAL_ERR_MAX]; + /**< Wireless Buffer Manager error codes. */ +}; + +/** + * nss_wifili_rx_reo_ring_stats + * Rx reorder error statistics. + */ +struct nss_wifili_rx_reo_ring_stats { + uint32_t ring_error; /**< Rx reorder ring error. */ + uint32_t ring_reaped; /**< Number of ring descriptor reaped. */ + uint32_t invalid_cookie; /**< Number of invalid cookie. */ + uint32_t defrag_reaped; /**< Rx defragment receive count. */ +}; + +/** + * nss_wifili_rx sw_pool_stats + * Wifili DMA sw pool statistics. + */ +struct nss_wifili_rx_sw_pool_stats { + uint32_t rx_no_pb; /**< Rx software descriptor number of buffer available. */ + uint32_t desc_alloc; /**< Number of descriptor in use. */ + uint32_t desc_alloc_fail; /**< Number of descriptor allocation failure. */ +}; + +/** + * nss_wifili_rx_dma_ring_stats + * Wifili Rx DMA ring statistics. + */ +struct nss_wifili_rx_dma_ring_stats { + uint32_t rx_hw_desc_unavailable; /**< Number of times hardware descriptor is unavailable. */ + uint32_t rx_buf_replenished; /**< Number of buffers replenished. */ +}; + +/** + * nss_wifili_dbdc_mode_stats + * Wifili DBDC mode statistics. + */ +struct nss_wifili_dbdc_mode_stats { + uint32_t dbdc_flush_ast_failed; + /**< Number of times DBDC AST flush message send has failed. */ + uint32_t dbdc_drop_rx_secmcast; + /**< Number of packets dropped in DBDC Rx for secondary multicast. */ + uint32_t dbdc_drop_tx_secmcast; + /**< Number of packets dropped in DBDC Tx for secondary multicast. */ + uint32_t dbdc_drop_rx_alwaysprimary; + /**< Number of packets dropped in DBDC Rx for always primary. */ + uint32_t dbdc_drop_tx_alwaysprimary; + /**< Number of packets dropped in DBDC Tx for always primary. */ + uint32_t dbdc_drop_loop_rx; + /**< Number of packets dropped in DBDC Rx for DBDC loop. */ + uint32_t dbdc_drop_loop_tx; + /**< Number of packets dropped in DBDC Tx for DBDC loop. */ +}; + +/** + * nss_wifili_delay_stats + * Wifili delay statistics. + */ +struct nss_wifili_delay_stats { + uint32_t delay_bucket[NSS_WIFILI_DELAY_INDEX_MAX]; + /**< Delay buckets for histogram. */ + uint32_t min_delay; + /**< Minimum delay. */ + uint32_t avg_delay; + /**< Average delay. */ + uint32_t max_delay; + /**< Maximum delay. */ +}; + +/** + * nss_wifili_v3_delay_per_tid_stats + * Wifili version 3 delay per TID statistics. + */ +struct nss_wifili_v3_delay_per_tid_stats { + struct nss_wifili_delay_stats swq_delay; + /**< Software enqueue delay. */ + struct nss_wifili_delay_stats hwtx_delay; + /**< Hardware transmit delay. */ + struct nss_wifili_delay_stats tx_intfrm_delay; + /**< Transmit interframe delay at radio entry. */ + struct nss_wifili_delay_stats rx_intfrm_delay; + /**< Receive interframe delay. */ +}; + +/** + * nss_wifili_v3_per_tid_tx_rx_stats + * Wifili version 3 Tx and Rx statistics per TID. + */ +struct nss_wifili_v3_tx_rx_per_tid_stats { + uint32_t radio_ingress_enq_drop_cnt; + /**< Ingress enqueue drop count. */ + uint32_t transmit_succes_cnt; + /**< Total successful transmit count. */ + uint32_t transmit_fwdrop_cnt; + /**< Firmware drop count. */ + uint32_t transmit_hwdrop_cnt; + /**< Hardware drop count. */ + uint32_t transmit_desc_fail_cnt; + /**< Transmit descriptor fail count. */ + uint32_t transmit_complete_cnt; + /**< Total transmit count. */ + uint32_t rx_delivered_cnt; + /**< Total Rx packets delivered to next node. */ + uint32_t rx_deliver_fail_cnt; + /**< Rx deliver fail count. */ + uint32_t rx_intrabss_cnt; + /**< Intra-BSS Rx count. */ + uint32_t rx_intrabss_fail_cnt; + /**< Intra-BSS Rx fail count. */ + uint32_t num_msdu_recived; + /**< Number of MSDU received from hardware. */ + uint32_t num_mcast_msdu_recived; + /**< Number of broadcast MSDU received. */ + uint32_t num_bcast_msdu_recived; + /**< Number of multicast MSDU received. */ + uint32_t transmit_tqm_status_cnt[NSS_WIFILI_TQM_STATUS_MAX]; + /**< Number of frames with this TQM completion status. */ + uint32_t transmit_htt_status_cnt[NSS_WIFILI_HTT_STATUS_MAX]; + /**< Number of frames with this HTT completion status. */ +}; + +/** + * nss_wifili_v3_tx_rx_per_ac_stats + * Wifili version 3 Tx and Rx statistics per AC. + */ +struct nss_wifili_v3_tx_rx_per_ac_stats { + uint32_t radio_ingress_enq_cnt; + /**< Ingress enqueue packet count. */ + uint32_t radio_ingress_deq_cnt; + /**< Ingress dequeue count. */ + uint32_t transmit_enq_cnt; + /**< Transmit enqueue count. */ +}; + +/** + * nss_wifili_radio_tx_rx_stats_v3 + * Wifili version 3 radio Tx and Rx statistics. + */ +struct nss_wifili_radio_tx_rx_stats_v3 { + struct nss_wifili_v3_tx_rx_per_tid_stats tid_stats[NSS_WIFILI_MAX_TID]; + /**< Per-TID Tx and Rx statistics. */ + struct nss_wifili_v3_tx_rx_per_ac_stats ac_stats[NSS_WIFILI_WME_AC_MAX]; + /**< Per-Access Category Tx and Rx statistics. */ +}; + +/** + * nss_wifili_radio_delay_stats_v3 + * Wifili version 3 radio delay statistics. + */ +struct nss_wifili_radio_delay_stats_v3 { + struct nss_wifili_v3_delay_per_tid_stats v3_delay_stats[NSS_WIFILI_MAX_TID]; + /**< Per-TID delay statistics. */ +}; + +/** + * nss_wifili_pdev_v3_tx_rx_stats_sync_msg + * Wifili message to synchronize version 3 Tx and Rx statistics to HLOS. + */ +struct nss_wifili_pdev_v3_tx_rx_stats_sync_msg { + uint32_t radio_id; + /**< Radio ID. */ + struct nss_wifili_radio_tx_rx_stats_v3 wlpv3_txrx_stats; + /**< Wifli version 3 Tx and Rx statistics. */ +}; + +/** + * nss_wifili_pdev_v3_delay_stats_sync_msg + * Wifili message to synchronize version 3 delay statistics to HLOS. + */ +struct nss_wifili_pdev_v3_delay_stats_sync_msg { + uint32_t radio_id; + /**< Radio ID. */ + struct nss_wifili_radio_delay_stats_v3 wlpv3_delay_stats; + /**< Wifli version 3 delay statistics. */ +}; + +/** + * nss_wifili_device_stats + * Wifili specific statistics. + */ +struct nss_wifili_device_stats { + struct nss_wifili_tx_tcl_ring_stats tcl_stats[NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG]; + /**< Transmit Classifier ring statistics. */ + struct nss_wifili_tx_comp_ring_stats txcomp_stats[NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG]; + /**< Tx completion ring statistics. */ + struct nss_wifili_tx_sw_pool_stats tx_sw_pool_stats[NSS_WIFILI_MAX_TXDESC_POOLS_MSG]; + /**< Tx software pool statistics. */ + struct nss_wifili_tx_ext_sw_pool_stats tx_ext_sw_pool_stats[NSS_WIFILI_MAX_TX_EXT_DESC_POOLS_MSG]; + /**< Tx extended software pool statistics. */ + struct nss_wifili_tx_stats tx_data_stats[NSS_WIFILI_MAX_PDEV_NUM_MSG]; + /**< Tx data statistics for each pdev. */ + struct nss_wifili_rx_reo_ring_stats rxreo_stats[NSS_WIFILI_MAX_REO_DATA_RINGS_MSG]; + /**< Rx reorder ring statistics. */ + struct nss_wifili_rx_sw_pool_stats rx_sw_pool_stats[NSS_WIFILI_MAX_PDEV_NUM_MSG]; + /**< Rx DMA software pool statistics. */ + struct nss_wifili_rx_stats rx_data_stats[NSS_WIFILI_MAX_PDEV_NUM_MSG]; + /**< Rx data statistics for each pdev. */ + struct nss_wifili_rx_dma_ring_stats rxdma_stats[NSS_WIFILI_MAX_PDEV_NUM_MSG]; + /**< Rx DMA ring statistics. */ + struct nss_wifili_rx_wbm_ring_stats rxwbm_stats; + /**< Wireless Buffer Manager ring statistics. */ + struct nss_wifili_dbdc_mode_stats dbdc_stats; + /**< DBDC mode statistics. */ +}; + +/** + * nss_wifili_stats_sync_msg + * Wifili SoC statistics synchronization message. + */ +struct nss_wifili_stats_sync_msg { + struct nss_wifili_device_stats stats; + /**< Device statistics. */ +}; + +/** + * nss_wifili_soc_linkdesc_per_packet_metadata + * Link descriptor per packet metadata. + */ +struct nss_wifili_soc_linkdesc_per_packet_metadata +{ + uint32_t desc_addr; /**< Link descriptor address. */ +}; + +/** + * nss_wifili_soc_per_packet_metadata + * Per packet special data that has to be sent to host. + */ +struct nss_wifili_soc_per_packet_metadata { + uint16_t pkt_type; /**< Packet type. */ + uint8_t pool_id; /**< Pool ID of invalid peer packets. */ + uint8_t reserved; /**< Alignment padding. */ + + /** + * Link descriptor per packet metadata. + */ + union { + struct nss_wifili_soc_linkdesc_per_packet_metadata linkdesc_metadata; + } metadata; /**< Per packet link descriptor metadata. */ +}; + +/** + * nss_wifili_tx_dropped + * Tx peer dropped packets. + */ +struct nss_wifili_tx_dropped { + uint32_t drop_stats[NSS_WIFILI_TQM_RR_MAX]; /**< Discarded by firmware. */ + uint32_t tx_nawds_mcast_drop_cnt; /**< Total number of NAWDS multicast packets dropped. */ +}; + +/** + * nss_wifili_tx_ctrl_stats + * Tx peer statistics. + */ +struct nss_wifili_tx_ctrl_stats { + uint32_t ofdma; /**< Number of orthogonal frequency-division multiple + access packets. */ + uint32_t non_amsdu_cnt; /**< Number of MSDUs with no MSDU level aggregation. */ + uint32_t amsdu_cnt; /**< Number of MSDUs part of AMSDU. */ + uint32_t tx_mcast_cnt; /**< Total number of multicast packets sent. */ + uint32_t tx_mcast_bytes; /**< Total number of multicast bytes sent. */ + uint32_t tx_ucast_cnt; /**< Total number of unicast packets sent. */ + uint32_t tx_ucast_bytes; /**< Total number of unicast bytes sent. */ + uint32_t tx_bcast_bytes; /**< Total number of broadcast bytes sent. */ + uint32_t tx_bcast_cnt; /**< Total number of broadcast packets sent. */ + struct nss_wifili_tx_dropped dropped; /**< Tx peer dropped. */ + uint32_t tx_success_cnt; /**< Total number of packets sent successfully. */ + uint32_t tx_success_bytes; /**< Total number of bytes sent successfully. */ + uint32_t tx_nawds_mcast_cnt; /**< Total number of NAWDS multicast packets sent. */ + uint32_t tx_nawds_mcast_bytes; /**< Total number of NAWDS multicast bytes sent. */ + uint32_t retries; /**< Total number of retries. */ +}; + +/** + * nss_wifili_peer_rx_err + * Rx peer errors. + */ +struct nss_wifili_rx_err { + uint32_t mic_err; /**< Rx MIC errors. */ + uint32_t decrypt_err; /**< Rx Decryption errors. */ +}; + +/** + * nss_wifili_rx_ctrl_stats + * Peer Rx statistics. + */ +struct nss_wifili_rx_ctrl_stats { + struct nss_wifili_rx_err err; /**< Rx peer errors. */ + uint32_t multipass_rx_pkt_drop; /**< Total number of multipass packets without a VLAN header. */ + uint32_t reserved_type[NSS_WIFILI_MAX_RESERVED_TYPE]; /**< Reserved type for future use. */ + uint32_t non_amsdu_cnt; /**< Number of MSDUs with no MSDU level aggregation. */ + uint32_t amsdu_cnt; /**< Number of MSDUs part of AMSDU. */ + uint32_t mcast_rcv_cnt; /**< Total number of multicast packets received. */ + uint32_t mcast_rcv_bytes; /**< Total number of multicast bytes received. */ + uint32_t rx_recvd; /**< Total Rx received count. */ + uint32_t rx_recvd_bytes; /**< Total Rx received count. */ + uint32_t nawds_mcast_drop; /**< Total NAWDS drop count. */ + uint32_t nawds_mcast_drop_bytes; /**< Total NAWDS drop count. */ + uint32_t rx_intra_bss_pkts_num; /**< Total Intra-BSS packets received. */ + uint32_t rx_intra_bss_pkts_bytes; /**< Total Intra-BSS bytes received. */ + uint32_t rx_intra_bss_fail_num; /**< Total Intra-BSS packets failed. */ + uint32_t rx_intra_bss_fail_bytes; /**< Total Intra-BSS bytes received. */ + uint32_t bcast_rcv_cnt; /**< Total number of broadcast packets received. */ + uint32_t bcast_rcv_bytes; /**< Total number of broadcast bytes received. */ +}; + +/** + * nss_wifili_peer_ctrl_stats + * Wifili peer control statistics. + */ +struct nss_wifili_peer_ctrl_stats { + uint32_t peer_id; /**< Peer ID. */ + struct nss_wifili_tx_ctrl_stats tx; + /**< Peer Tx control statistics. */ + struct nss_wifili_rx_ctrl_stats rx; + /**< Peer Rx control statistics. */ +}; + +/** + * nss_wifili peer_stats + * Wifili peer statistics. + */ +struct nss_wifili_peer_stats { + uint32_t npeers; /**< Number of entries of peer statistics. */ + struct nss_wifili_peer_ctrl_stats wpcs[1]; + /**< Wifili peer control statistics. */ +}; + +/** + * nss_wifili_peer_stats_msg + * Wifili peer statistics message. + */ +struct nss_wifili_peer_stats_msg { + struct nss_wifili_peer_stats stats; + /**< Wifili peer statistics. */ +}; + +/** + * nss_wifili_sojourn_per_tid_stats + * Wifili sojourn per TID statistics. + */ +struct nss_wifili_sojourn_per_tid_stats { + uint32_t avg_sojourn_msdu; /**< Average per-TID of all time difference. */ + uint32_t sum_sojourn_msdu; /**< Sum per-TID of all time difference. */ + uint32_t num_msdus; /**< MSDUs per TID. */ +}; + +/** + * nss_wifili_sojourn_peer_stats + * Wifili sojourn peer statistics. + */ +struct nss_wifili_sojourn_peer_stats { + uint32_t peer_id; /**< Peer ID. **/ + struct nss_wifili_sojourn_per_tid_stats stats[NSS_WIFILI_MAX_TID]; /**< Statistics per TID. **/ +}; + +/** + * nss_wifili_sojourn_stats_msg + * Wifili sojourn statistics message. + */ +struct nss_wifili_sojourn_stats_msg { + uint32_t npeers; /**< Number of peers. */ + struct nss_wifili_sojourn_peer_stats sj_peer_stats[1]; /**< Per-peer sojourn statistics. */ +}; + +/* + * nss_wifili_jitter_tid_stats + * Per TID jitter statistics. + */ +struct nss_wifili_jitter_tid_stats { + uint32_t avg_jitter; /**< Average jitter. */ + uint32_t avg_delay; /**< Average delay. */ + uint32_t avg_err; /**< Average count error. */ + uint32_t success; /**< Transmit success count. */ + uint32_t drop; /**< Transmit drop count. */ +}; + +/* + * nss_wifili_jitter_stats + * Wifili jitter statistics. + */ +struct nss_wifili_jitter_stats { + uint32_t peer_id; /**< Peer ID. */ + struct nss_wifili_jitter_tid_stats stats[NSS_WIFILI_MAX_TID]; /**< Per-TID jitter statistics. */ +}; + +/* + * nss_wifili_jitter_stats_msg + * Wifili jitter message. + */ +struct nss_wifili_jitter_stats_msg { + uint32_t npeers; /**< Number of peers. */ + struct nss_wifili_jitter_stats jitter_stats[1]; /**< Jitter statistics. */ +}; + +/** + * nss_wifili_wds_peer_msg + * Wi-Fi Wireless distribution system (WDS) peer-specific message. + */ +struct nss_wifili_wds_peer_msg { + uint8_t dest_mac[ETH_ALEN]; /**< MAC address of the destination. */ + uint8_t peer_mac[ETH_ALEN]; /**< MAC address of the base peer. */ + uint8_t ast_type; /**< AST (Address Search Table) type for this peer. */ + uint8_t pdev_id; /**< Radio ID for next hop peer. */ + uint16_t peer_id; /**< Peer ID of next hop peer. */ +}; + +/** + * nss_wifili_peer_delay_stats + * Per-peer delay statistics. + */ +struct nss_wifili_peer_delay_stats { + struct nss_wifili_delay_stats swq_delay; /**< Software enqueue delay. */ + struct nss_wifili_delay_stats hwtx_delay; /**< Hardware transmit delay. */ +}; + +/** + * nss_wifili_peer_ext_stats + * Peer extended statistics. + */ +struct nss_wifili_peer_ext_stats { + uint32_t peer_id; /**< Peer ID. */ + struct nss_wifili_peer_delay_stats delay_stats[NSS_WIFILI_MAX_TID]; + /**< Delay statistics. */ +}; + +/** + * nss_wifili_peer_ext_stats_msg + * Peer extended statistics message. + */ +struct nss_wifili_peer_ext_stats_msg { + uint32_t npeers; /**< Number of peers. */ + struct nss_wifili_peer_ext_stats ext_stats[1]; /**< Extended statistics. */ +}; + +/** + * nss_wifili_stats_cfg_msg + * Wifili stats enable/disable configuration message. + */ +struct nss_wifili_stats_cfg_msg { + uint32_t cfg; /**< Enable or disable configuration. */ +}; + +/** + * nss_wifili_wds_peer_map_msg + * Wi-Fi Wireless distribution system(WDS) peer-specific message. + */ +struct nss_wifili_wds_peer_map_msg { + uint8_t dest_mac[ETH_ALEN]; /**< MAC address of the destination. */ + uint16_t peer_id; /**< Connected peer ID for this WDS peer. */ + uint16_t ast_idx; /**< AST (address search table) index for this peer in host. */ + uint16_t vdev_id;; /**< VAP ID. */ +}; + +/** + * nss_wifili_wds_active_info + * Wi-Fi WDS active information. + */ +struct nss_wifili_wds_active_info { + uint16_t ast_idx; /**< Hardware AST index. */ +}; + +/** + * nss_wifili_wds_active_info_msg + * Wi-Fi Wireless distribution system active information message. + */ +struct nss_wifili_wds_active_info_msg { + uint16_t nentries; /**< Number of WDS entries. */ + struct nss_wifili_wds_active_info info[1]; + /**< WDS active information. */ +}; + +/** + * nss_wifili_mec_ageout_info + * Wi-Fi multicast echo check ageout information. + */ +struct nss_wifili_mec_ageout_info { + uint8_t mac_addr[6]; /**< MAC address. */ + uint8_t radio_id; /**< Radio ID. */ + uint8_t pad; /**< Pad for word align structure. */ + +}; + +/** + * nss_wifili_mec_ageout_info_msg + * Wi-Fi multicast echo check ageout information message. + */ +struct nss_wifili_mec_ageout_info_msg { + uint16_t nentries; /**< Number of entries. */ + struct nss_wifili_mec_ageout_info info[1]; + /**< Multicast echo check active information. */ +}; + +/** + * nss_wifili_soc_linkdesc_buf_info_msg + * Link descriptor buffer addresss information. + */ +struct nss_wifili_soc_linkdesc_buf_info_msg { + uint32_t buffer_addr_low; /**< Link descriptor low address. */ + uint32_t buffer_addr_high; /**< Link descriptor high address. */ +}; + +/** + * nss_wifili_peer_security_type_msg + * Wifili security type message. + */ +struct nss_wifili_peer_security_type_msg { + uint16_t peer_id; /**< Peer ID. */ + uint8_t pkt_type; /**< Unicast or broadcast packet type. */ + uint8_t security_type; /**< Security type. */ + uint8_t mic_key[NSS_WIFILI_MIC_KEY_LEN]; + /**< MIC key. */ +}; + +/** + * nss_wifili_peer_nawds_enable_msg + * Wifili NAWDS enable for this peer. + */ +struct nss_wifili_peer_nawds_enable_msg { + uint16_t peer_id; /**< Peer ID. */ + uint16_t is_nawds; /**< Enable NAWDS on this peer. */ +}; + +/** + * nss_wifili_peer_vlan_id_msg + * Wifili peer VLAN ID message. + */ +struct nss_wifili_peer_vlan_id_msg { + uint16_t peer_id; /**< Peer ID. */ + uint16_t vlan_id; /**< VLAN ID. */ +}; + +/** + * nss_wifili_peer_isolation_msg + * Wifili peer isolation message. + */ +struct nss_wifili_peer_isolation_msg { + uint16_t peer_id; /**< Peer ID. */ + uint16_t isolation; /**< Isolation enabled/disabled. */ +}; + +/** + * nss_wifili_dbdc_repeater_set_msg + * Wifili DBDC repeater set message. + */ +struct nss_wifili_dbdc_repeater_set_msg { + uint32_t is_dbdc_en; /**< DBDC enable flag. */ +}; + +/** + * nss_wifili_hmmc_dscp_tid_set_msg + * Wifili Hy-Fi managed multicast DSCP TID set message. + */ +struct nss_wifili_hmmc_dscp_tid_set_msg { + uint16_t radio_id; /**< Radio ID. */ + uint16_t value; /**< Hy-Fi managed multicast TID value. */ +}; + +/** + * nss_wifili_hmmc_dscp_override_set_msg + * Wifili Hy-Fi managed multicast DSCP override set message. + */ +struct nss_wifili_hmmc_dscp_override_set_msg { + uint16_t radio_id; /**< Radio ID. */ + uint16_t value; /**< Hy-Fi managed multicast DSCP override value. */ +}; + +/** + * nss_wifili_reo_tidq_msg + * Rx reorder TID queue setup message. + */ +struct nss_wifili_reo_tidq_msg { + uint32_t tid; /**< TID (traffic identification) value. */ + uint16_t peer_id; /**< Peer ID. */ +}; + +/** + * nss_wifili_enable_v3_stats_msg + * Version 3 statistics enable message. + */ +struct nss_wifili_enable_v3_stats_msg { + uint32_t radio_id; /**< Radio ID. */ + uint32_t flag; /**< Flag to enable version 3 statistics. */ +}; + +/** + * nss_wifili_clr_stats_msg + * NSS firmware statistics clear message. + */ +struct nss_wifili_clr_stats_msg { + uint8_t vdev_id;; /**< VAP ID. */ +}; + +/** + * nss_wifili_update_pdev_lmac_id_msg + * Physical device ID and lower MAC ID update message. + */ +struct nss_wifili_update_pdev_lmac_id_msg { + uint32_t pdev_id; /**< Physical device ID. */ + uint32_t lmac_id; /**< Lower MAC ID. */ + uint32_t target_pdev_id; /**< Target physical device ID. */ +}; + +/** + * nss_wifili_radio_cmd_msg + * Wi-Fi radio specific special commands. + */ +struct nss_wifili_radio_cmd_msg { + enum nss_wifili_radio_cmd cmd; + /**< Type of command message. */ + uint32_t value; /**< Value of the command. */ +}; + +/** + * nss_wifili_radio_buf_cfg_msg + * Wi-Fi Radio buffer requirement configuration. + * + * Number of payloads needed in NSS for multi-client scenarios are configured + * from Wi-Fi driver as per following ranges: + * 0-64 peers range 1. + * 64-128 peers range 2. + * 128-256 peers range 3. + * >256 peers range 4. + * Number of payloads needed in for each peer range is configured by Wi-Fi driver + * for flexibility. + */ +struct nss_wifili_radio_buf_cfg_msg { + uint32_t buf_cnt; /**< Number of buffers required. */ + uint32_t range; /**< Peer range. */ +}; + +/** + * nss_wifili_radio_cfg_msg + * Wi-Fi radio specific special configurations. + */ +struct nss_wifili_radio_cfg_msg { + uint32_t radio_if_num; /**< NSS assigned interface number for radio. */ + + /** + * Wi-Fi radio specific special command message. + */ + union { + struct nss_wifili_radio_cmd_msg radiocmdmsg; + /**< Radio specific commands. */ + struct nss_wifili_radio_buf_cfg_msg radiobufcfgmsg; + /**< Radio specific buffer configurations. */ + } radiomsg; /**< Wi-Fi radio command message. */ +}; + +/** + * struct wifili_peer_wds_4addr_allow_msg + * Per peer four address configuration message. + */ +struct nss_wifili_peer_wds_4addr_allow_msg { + uint32_t peer_id; /**< Peer ID. */ + uint32_t if_num; /**< Associate virtual interface number. */ + bool enable; /**< Boolean flag to enable/disable four address frames. */ +}; + +/** + * nss_wifili_msg + * Structure that describes wifili messages. + */ +struct nss_wifili_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of wifili message. + */ + union { + struct nss_wifili_init_msg init; + /**< Wi-Fi initialization data. */ + struct nss_wifili_pdev_init_msg pdevmsg; + /**< Tx initialization data. */ + struct nss_wifili_pdev_deinit_msg pdevdeinit; + /**< Tx de-initialization data. */ + struct nss_wifili_peer_msg peermsg; + /**< Peer-specific data for the physical device. */ + struct nss_wifili_peer_freelist_append_msg peer_freelist_append; + /**< Information for creating a peer freelist. */ + struct nss_wifili_stats_sync_msg wlsoc_stats; + /**< Synchronization statistics. */ + struct nss_wifili_peer_stats_msg peer_stats; + /**< Wifili peer statistics. */ + struct nss_wifili_wds_peer_msg wdspeermsg; + /**< WDS peer-specific message. */ + struct nss_wifili_wds_peer_map_msg wdspeermapmsg; + /**< WDS peer-mapping specific message. */ + struct nss_wifili_wds_active_info_msg wdsinfomsg; + /**< WDS active information specific message. */ + struct nss_wifili_stats_cfg_msg scm; + /**< Wifili peer statistics configuration message. */ + struct nss_wifili_reo_tidq_msg reotidqmsg; + /**< Rx reorder TID queue setup message. */ + struct nss_wifili_radio_cfg_msg radiocfgmsg; + /**< Radio command message. */ + struct nss_wifili_wds_extn_peer_cfg_msg wpeercfg; + /**< WDS vendor configuration message. */ + struct nss_wifili_soc_linkdesc_buf_info_msg linkdescinfomsg; + /**< Link descriptor buffer address information. */ + struct nss_wifili_peer_security_type_msg securitymsg; + /**< Wifili peer security message. */ + struct nss_wifili_peer_nawds_enable_msg nawdsmsg; + /**< Wifili peer enable NAWDS message. */ + struct nss_wifili_dbdc_repeater_set_msg dbdcrptrmsg; + /**< Wifili DBDC repeater enable message. */ + struct nss_wifili_hmmc_dscp_override_set_msg shmmcdscpmsg; + /**< Wifili Hy-Fi managed multicast DSCP override set message. */ + struct nss_wifili_hmmc_dscp_tid_set_msg shmmcdcptidmsg; + /**< Wifili Hy-Fi managed multicast DSCP TID map set message. */ + struct nss_wifili_pdev_v3_tx_rx_stats_sync_msg v3_txrx_stats_msg; + /**< Wifili version 3 Tx and Rx statistics message. */ + struct nss_wifili_pdev_v3_delay_stats_sync_msg v3_delay_stats_msg; + /**< Wifili version 3 delay statistics message. */ + struct nss_wifili_enable_v3_stats_msg enablev3statsmsg; + /**< Wifili version 3 statistics enable message. */ + struct nss_wifili_sojourn_stats_msg sj_stats_msg; + /**< Wifili sojourn statistics message. */ + struct nss_wifili_peer_vlan_id_msg peervlan; + /**< Wifili peer VLAN ID message. */ + struct nss_wifili_update_pdev_lmac_id_msg update_pdev_lmac_id_msg; + /**< Wifili peer update lower MAC ID message. */ + struct nss_wifili_peer_ast_flowid_map_msg peer_ast_flowid_msg; + /**< Wifili peer AST index flow ID map message. */ + struct nss_wifili_mec_ageout_info_msg mecagemsg; + /**< Multicast echo check active information specific message. */ + struct nss_wifili_jitter_stats_msg jt_stats_msg; + /** HLOS messages for bridge + */ +static void nss_bridge_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, void *app_data) +{ + struct nss_bridge_msg *nbm = (struct nss_bridge_msg *)ncm; + nss_bridge_msg_callback_t cb; + + BUG_ON(!nss_is_dynamic_interface(ncm->interface)); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_BRIDGE_MSG_TYPE_MAX) { + nss_warning("%px: received invalid message %d for bridge interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_bridge_msg)) { + nss_warning("%px: length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Trace Messages + */ + nss_bridge_log_rx_msg(nbm); + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Update the callback and app_data for NOTIFY messages, IPv4 sends all notify messages + * to the same callback/app_data. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_ctx->nss_top->bridge_callback; + ncm->app_data = (nss_ptr_t)nss_ctx->nss_top->bridge_ctx; + } + + /* + * Do we have a call back + */ + if (!ncm->cb) { + return; + } + + /* + * callback + */ + cb = (nss_bridge_msg_callback_t)ncm->cb; + cb((void *)ncm->app_data, nbm); +} + +/* + * nss_bridge_get_context() + */ +struct nss_ctx_instance *nss_bridge_get_context(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.bridge_handler_id]; +} +EXPORT_SYMBOL(nss_bridge_get_context); + +/* + * nss_bridge_callback() + * Callback to handle the completion of NSS->HLOS messages. + */ +static void nss_bridge_callback(void *app_data, struct nss_bridge_msg *nbm) +{ + nss_bridge_msg_callback_t callback = (nss_bridge_msg_callback_t)bridge_pvt.cb; + void *data = bridge_pvt.app_data; + + bridge_pvt.response = NSS_TX_SUCCESS; + bridge_pvt.cb = NULL; + bridge_pvt.app_data = NULL; + + if (nbm->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("bridge error response %d\n", nbm->cm.response); + bridge_pvt.response = nbm->cm.response; + } + + if (callback) { + callback(data, nbm); + } + complete(&bridge_pvt.complete); +} + +/* + * nss_bridge_verify_if_num() + * Verify if_num passed to us. + */ +bool nss_bridge_verify_if_num(uint32_t if_num) +{ + if (nss_is_dynamic_interface(if_num) == false) { + return false; + } + + if (nss_dynamic_interface_get_type(nss_bridge_get_context(), if_num) != NSS_DYNAMIC_INTERFACE_TYPE_BRIDGE) { + return false; + } + + return true; +} +EXPORT_SYMBOL(nss_bridge_verify_if_num); + +/* + * nss_bridge_tx_msg() + * Transmit a bridge message to NSSFW + */ +nss_tx_status_t nss_bridge_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_bridge_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Sanity check the message + */ + if (!nss_is_dynamic_interface(ncm->interface)) { + nss_warning("%px: tx request for interface that is not a bridge: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type >= NSS_BRIDGE_MSG_TYPE_MAX) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + /* + * Trace Messages + */ + nss_bridge_log_tx_msg(msg); + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_bridge_tx_msg); + +/* + * nss_bridge_tx_msg_sync() + * Transmit a bridge message to NSS firmware synchronously. + */ +nss_tx_status_t nss_bridge_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_bridge_msg *nbm) +{ + nss_tx_status_t status; + int ret = 0; + + down(&bridge_pvt.sem); + bridge_pvt.cb = (void *)nbm->cm.cb; + bridge_pvt.app_data = (void *)nbm->cm.app_data; + + nbm->cm.cb = (nss_ptr_t)nss_bridge_callback; + nbm->cm.app_data = (nss_ptr_t)NULL; + + status = nss_bridge_tx_msg(nss_ctx, nbm); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: bridge_tx_msg failed\n", nss_ctx); + up(&bridge_pvt.sem); + return status; + } + + ret = wait_for_completion_timeout(&bridge_pvt.complete, msecs_to_jiffies(NSS_BRIDGE_TX_TIMEOUT)); + + if (!ret) { + nss_warning("%px: bridge msg tx failed due to timeout\n", nss_ctx); + bridge_pvt.response = NSS_TX_FAILURE; + } + + status = bridge_pvt.response; + up(&bridge_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_bridge_tx_msg_sync); + +/* + * nss_bridge_msg_init() + * Initialize nss_bridge_msg. + */ +void nss_bridge_msg_init(struct nss_bridge_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data) +{ + nss_cmn_msg_init(&ncm->cm, if_num, type, len, cb, app_data); +} +EXPORT_SYMBOL(nss_bridge_msg_init); + +/* + * nss_bridge_tx_vsi_assign_msg + * API to send vsi assign message to NSS FW + */ +nss_tx_status_t nss_bridge_tx_vsi_assign_msg(uint32_t if_num, uint32_t vsi) +{ + struct nss_ctx_instance *nss_ctx = nss_bridge_get_context(); + struct nss_bridge_msg nbm; + + if (!nss_ctx) { + nss_warning("Can't get nss context\n"); + return NSS_TX_FAILURE; + } + + if (nss_bridge_verify_if_num(if_num) == false) { + nss_warning("%px: invalid interface %d", nss_ctx, if_num); + return NSS_TX_FAILURE; + } + + nss_bridge_msg_init(&nbm, if_num, NSS_IF_VSI_ASSIGN, + sizeof(struct nss_if_vsi_assign), NULL, NULL); + + nbm.msg.if_msg.vsi_assign.vsi = vsi; + + return nss_bridge_tx_msg_sync(nss_ctx, &nbm); +} +EXPORT_SYMBOL(nss_bridge_tx_vsi_assign_msg); + +/* + * nss_bridge_tx_vsi_unassign_msg + * API to send vsi unassign message to NSS FW + */ +nss_tx_status_t nss_bridge_tx_vsi_unassign_msg(uint32_t if_num, uint32_t vsi) +{ + struct nss_ctx_instance *nss_ctx = nss_bridge_get_context(); + struct nss_bridge_msg nbm; + + if (!nss_ctx) { + nss_warning("Can't get nss context\n"); + return NSS_TX_FAILURE; + } + + if (nss_bridge_verify_if_num(if_num) == false) { + nss_warning("%px: invalid interface %d", nss_ctx, if_num); + return NSS_TX_FAILURE; + } + + nss_bridge_msg_init(&nbm, if_num, NSS_IF_VSI_UNASSIGN, + sizeof(struct nss_if_vsi_unassign), NULL, NULL); + + nbm.msg.if_msg.vsi_unassign.vsi = vsi; + + return nss_bridge_tx_msg_sync(nss_ctx, &nbm); +} +EXPORT_SYMBOL(nss_bridge_tx_vsi_unassign_msg); + +/* + * nss_bridge_tx_change_mtu_msg + * API to send change mtu message to NSS FW + */ +nss_tx_status_t nss_bridge_tx_set_mtu_msg(uint32_t bridge_if_num, uint32_t mtu) +{ + struct nss_ctx_instance *nss_ctx = nss_bridge_get_context(); + struct nss_bridge_msg nbm; + struct nss_if_mtu_change *nimc; + + if (!nss_ctx) { + nss_warning("Can't get nss context\n"); + return NSS_TX_FAILURE; + } + + if (nss_bridge_verify_if_num(bridge_if_num) == false) { + nss_warning("%px: received invalid interface %d", nss_ctx, bridge_if_num); + return NSS_TX_FAILURE; + } + + nss_bridge_msg_init(&nbm, bridge_if_num, NSS_IF_MTU_CHANGE, + sizeof(struct nss_if_mtu_change), NULL, NULL); + + nimc = &nbm.msg.if_msg.mtu_change; + nimc->min_buf_size = (uint16_t)mtu; + + return nss_bridge_tx_msg_sync(nss_ctx, &nbm); +} +EXPORT_SYMBOL(nss_bridge_tx_set_mtu_msg); + +/* + * nss_bridge_tx_set_mac_addr_msg + * API to send change mac addr message to NSS FW + */ +nss_tx_status_t nss_bridge_tx_set_mac_addr_msg(uint32_t bridge_if_num, uint8_t *addr) +{ + struct nss_ctx_instance *nss_ctx = nss_bridge_get_context(); + struct nss_bridge_msg nbm; + struct nss_if_mac_address_set *nmas; + + if (!nss_ctx) { + nss_warning("Can't get nss context\n"); + return NSS_TX_FAILURE; + } + + if (nss_bridge_verify_if_num(bridge_if_num) == false) { + nss_warning("%px: received invalid interface %d", nss_ctx, bridge_if_num); + return NSS_TX_FAILURE; + } + + nss_bridge_msg_init(&nbm, bridge_if_num, NSS_IF_MAC_ADDR_SET, + sizeof(struct nss_if_mac_address_set), NULL, NULL); + + nmas = &nbm.msg.if_msg.mac_address_set; + memcpy(nmas->mac_addr, addr, ETH_ALEN); + return nss_bridge_tx_msg_sync(nss_ctx, &nbm); +} +EXPORT_SYMBOL(nss_bridge_tx_set_mac_addr_msg); + +/* + * nss_bridge_tx_join_msg + * API to send slave join message to NSS FW + */ +nss_tx_status_t nss_bridge_tx_join_msg(uint32_t bridge_if_num, struct net_device *netdev) +{ + struct nss_ctx_instance *nss_ctx = nss_bridge_get_context(); + struct nss_bridge_msg nbm; + uint32_t slave_if_num; + + if (!nss_ctx) { + nss_warning("Can't get nss context\n"); + return NSS_TX_FAILURE; + } + + if (nss_bridge_verify_if_num(bridge_if_num) == false) { + nss_warning("%px: received invalid interface %d\n", nss_ctx, bridge_if_num); + return NSS_TX_FAILURE; + } + + slave_if_num = nss_cmn_get_interface_number_by_dev(netdev); + if (slave_if_num < 0) { + nss_warning("%px: invalid slave device %px\n", nss_ctx, netdev); + return NSS_TX_FAILURE; + } + + nbm.msg.br_join.if_num = slave_if_num; + nss_bridge_msg_init(&nbm, bridge_if_num, NSS_BRIDGE_MSG_JOIN, + sizeof(struct nss_bridge_join_msg), NULL, NULL); + + return nss_bridge_tx_msg_sync(nss_ctx, &nbm); +} +EXPORT_SYMBOL(nss_bridge_tx_join_msg); + +/* + * nss_bridge_tx_leave_msg + * API to send slave leave message to NSS FW + */ +nss_tx_status_t nss_bridge_tx_leave_msg(uint32_t bridge_if_num, struct net_device *netdev) +{ + struct nss_ctx_instance *nss_ctx = nss_bridge_get_context(); + struct nss_bridge_msg nbm; + uint32_t slave_if_num; + + if (!nss_ctx) { + nss_warning("Can't get nss context\n"); + return NSS_TX_FAILURE; + } + + if (nss_bridge_verify_if_num(bridge_if_num) == false) { + nss_warning("%px: received invalid interface %d\n", nss_ctx, bridge_if_num); + return NSS_TX_FAILURE; + } + + slave_if_num = nss_cmn_get_interface_number_by_dev(netdev); + if (slave_if_num < 0) { + nss_warning("%px: invalid slave device %px\n", nss_ctx, netdev); + return NSS_TX_FAILURE; + } + + nbm.msg.br_leave.if_num = slave_if_num; + nss_bridge_msg_init(&nbm, bridge_if_num, NSS_BRIDGE_MSG_LEAVE, + sizeof(struct nss_bridge_leave_msg), NULL, NULL); + + return nss_bridge_tx_msg_sync(nss_ctx, &nbm); +} +EXPORT_SYMBOL(nss_bridge_tx_leave_msg); + +/* + * nss_bridge_tx_set_fdb_learn_msg + * API to send FDB learn message to NSS FW + */ +nss_tx_status_t nss_bridge_tx_set_fdb_learn_msg(uint32_t bridge_if_num, enum nss_bridge_fdb_learn_mode fdb_learn) +{ + struct nss_ctx_instance *nss_ctx = nss_bridge_get_context(); + struct nss_bridge_msg nbm; + + if (!nss_ctx) { + nss_warning("Can't get nss context\n"); + return NSS_TX_FAILURE; + } + + if (nss_bridge_verify_if_num(bridge_if_num) == false) { + nss_warning("%px: received invalid interface %d\n", nss_ctx, bridge_if_num); + return NSS_TX_FAILURE; + } + + if (fdb_learn >= NSS_BRIDGE_FDB_LEARN_MODE_MAX) { + nss_warning("%px: received invalid fdb learn mode %d\n", nss_ctx, fdb_learn); + return NSS_TX_FAILURE; + } + + nss_bridge_msg_init(&nbm, bridge_if_num, NSS_BRIDGE_MSG_SET_FDB_LEARN, + sizeof(struct nss_bridge_set_fdb_learn_msg), NULL, NULL); + + nbm.msg.fdb_learn.mode = fdb_learn; + + return nss_bridge_tx_msg_sync(nss_ctx, &nbm); +} +EXPORT_SYMBOL(nss_bridge_tx_set_fdb_learn_msg); + +/* + * nss_bridge_init() + */ +void nss_bridge_init(void) +{ + sema_init(&bridge_pvt.sem, 1); + init_completion(&bridge_pvt.complete); +} + +/* + * nss_bridge_unregister() + */ +void nss_bridge_unregister(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = nss_bridge_get_context(); + + nss_assert(nss_bridge_verify_if_num(if_num)); + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + + nss_top_main.bridge_callback = NULL; + + nss_core_unregister_handler(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_bridge_unregister); + +/* + * nss_bridge_register() + */ +struct nss_ctx_instance *nss_bridge_register(uint32_t if_num, struct net_device *netdev, + nss_bridge_callback_t bridge_data_cb, + nss_bridge_msg_callback_t bridge_msg_cb, + uint32_t features, + void *app_data) +{ + struct nss_ctx_instance *nss_ctx = nss_bridge_get_context(); + + nss_assert(nss_bridge_verify_if_num(if_num)); + + nss_core_register_subsys_dp(nss_ctx, if_num, bridge_data_cb, NULL, app_data, netdev, features); + + nss_top_main.bridge_callback = bridge_msg_cb; + + nss_core_register_handler(nss_ctx, if_num, nss_bridge_handler, app_data); + return nss_ctx; +} +EXPORT_SYMBOL(nss_bridge_register); + +/* + * nss_bridge_notify_register() + * Register to receive bridge notify messages. + */ +struct nss_ctx_instance *nss_bridge_notify_register(nss_bridge_msg_callback_t cb, void *app_data) +{ + nss_top_main.bridge_callback = cb; + nss_top_main.bridge_ctx = app_data; + return nss_bridge_get_context(); +} +EXPORT_SYMBOL(nss_bridge_notify_register); + +/* + * nss_bridge_notify_unregister() + * Unregister to receive bridge notify messages. + */ +void nss_bridge_notify_unregister(void) +{ + nss_top_main.bridge_callback = NULL; +} +EXPORT_SYMBOL(nss_bridge_notify_unregister); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_bridge_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_bridge_log.c new file mode 100644 index 000000000..3b0cf1e39 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_bridge_log.c @@ -0,0 +1,135 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_bridge_log.c + * NSS Bridge logger file. + */ + +#include "nss_core.h" + +/* + * nss_bridge_log_message_types_str + * NSS Bridge message strings + */ +static int8_t *nss_bridge_log_message_types_str[NSS_BRIDGE_MSG_TYPE_MAX] __maybe_unused = { + "Bridge Join message", + "Bridge Leave message", + "Bridge Set FDB Learn message" +}; + +/* + * nss_bridge_join_msg() + * Log NSS Bridge Join message. + */ +static void nss_bridge_join_msg(struct nss_bridge_msg *nbm) +{ + struct nss_bridge_join_msg *nbjm __maybe_unused = &nbm->msg.br_join; + nss_trace("%px: NSS Bridge Join message \n" + "Interface Number: %d\n", + nbm, nbjm->if_num); +} + +/* + * nss_bridge_leave_msg() + * Log NSS Bridge Leave message. + */ +static void nss_bridge_leave_msg(struct nss_bridge_msg *nbm) +{ + struct nss_bridge_leave_msg *nblm __maybe_unused = &nbm->msg.br_leave; + nss_trace("%px: NSS Bridge Leave message: \n" + "Interface Number: %d\n", + nbm, nblm->if_num); +} + +/* + * nss_bridge_fdb_learn_msg() + * Log NSS Set Bridge FDB Learn message. + */ +static void nss_bridge_fdb_learn_msg(struct nss_bridge_msg *nbm) +{ + struct nss_bridge_set_fdb_learn_msg *nbflm __maybe_unused = + &nbm->msg.fdb_learn; + nss_trace("%px: NSS Bridge Set FDB Learn message: \n" + "Mode: %d\n", + nbm, nbflm->mode); +} + +/* + * nss_bridge_log_verbose() + * Log message contents. + */ +static void nss_bridge_log_verbose(struct nss_bridge_msg *nbm) +{ + switch (nbm->cm.type) { + case NSS_BRIDGE_MSG_JOIN: + nss_bridge_join_msg(nbm); + break; + + case NSS_BRIDGE_MSG_LEAVE: + nss_bridge_leave_msg(nbm); + break; + + case NSS_BRIDGE_MSG_SET_FDB_LEARN: + nss_bridge_fdb_learn_msg(nbm); + break; + + default: + nss_trace("%px: Invalid message type\n", nbm); + break; + } +} + +/* + * nss_bridge_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_bridge_log_tx_msg(struct nss_bridge_msg *nbm) +{ + if (nbm->cm.type >= NSS_BRIDGE_MSG_TYPE_MAX) { + nss_warning("%px: Invalid message type\n", nbm); + return; + } + + nss_info("%px: type[%d]:%s\n", nbm, nbm->cm.type, nss_bridge_log_message_types_str[nbm->cm.type - NSS_IF_MAX_MSG_TYPES - 1]); + nss_bridge_log_verbose(nbm); +} + +/* + * nss_bridge_log_rx_msg() + * Log messages received from FW. + */ +void nss_bridge_log_rx_msg(struct nss_bridge_msg *nbm) +{ + if (nbm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", nbm); + return; + } + + if (nbm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (nbm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", nbm, nbm->cm.type, + nss_bridge_log_message_types_str[nbm->cm.type - NSS_IF_MAX_MSG_TYPES - 1], + nbm->cm.response, nss_cmn_response_str[nbm->cm.response]); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s\n", + nbm, nbm->cm.type, nss_bridge_log_message_types_str[nbm->cm.type - NSS_IF_MAX_MSG_TYPES - 1], + nbm->cm.response, nss_cmn_response_str[nbm->cm.response]); + +verbose: + nss_bridge_log_verbose(nbm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_bridge_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_bridge_log.h new file mode 100644 index 000000000..af9a5f787 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_bridge_log.h @@ -0,0 +1,41 @@ +/* + ************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_BRIDGE_LOG_H +#define __NSS_BRIDGE_LOG_H + +/* + * nss_bridge.h + * NSS Bridge header file. + */ + +/* + * Logger APIs + */ + +/* + * nss_bridge_log_tx_msg + * Logs a bridge message that is sent to the NSS firmware. + */ +void nss_bridge_log_tx_msg(struct nss_bridge_msg *nbm); + +/* + * nss_bridge_log_rx_msg + * Logs a bridge message that is received from the NSS firmware. + */ +void nss_bridge_log_rx_msg(struct nss_bridge_msg *nbm); + +#endif /* __NSS_BRIDGE_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_c2c_rx.c b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_rx.c new file mode 100644 index 000000000..4a1d5f8c2 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_rx.c @@ -0,0 +1,113 @@ +/* + ************************************************************************** + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_c2c_rx.c + * NSS C2C_RX APIs + */ + +#include +#include "nss_c2c_rx_stats.h" +#include "nss_c2c_rx_strings.h" + +/* + * nss_c2c_rx_verify_if_num() + * Verify if_num passed to us. + */ +static bool nss_c2c_rx_verify_if_num(uint32_t if_num) +{ + return if_num == NSS_C2C_RX_INTERFACE; +} + +/* + * nss_c2c_rx_interface_handler() + * Handle NSS -> HLOS messages for C2C_RX Statistics + */ +static void nss_c2c_rx_interface_handler(struct nss_ctx_instance *nss_ctx, + struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_c2c_rx_msg *ncrm = (struct nss_c2c_rx_msg *)ncm; + nss_c2c_rx_msg_callback_t cb; + + if (!nss_c2c_rx_verify_if_num(ncm->interface)) { + nss_warning("%px: invalid interface %d for c2c_tx\n", nss_ctx, ncm->interface); + return; + } + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_C2C_RX_MSG_TYPE_MAX) { + nss_warning("%px: received invalid message %d for c2c_rx", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_c2c_rx_msg)) { + nss_warning("%px: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + switch (ncrm->cm.type) { + case NSS_C2C_RX_MSG_TYPE_STATS: + /* + * Update driver statistics and send statistics notifications to the registered modules. + */ + nss_c2c_rx_stats_sync(nss_ctx, &ncrm->msg.stats); + nss_c2c_rx_stats_notify(nss_ctx); + break; + } + + /* + * Update the callback and app_data for NOTIFY messages + * TODO: Add notify callbacks for c2c_rx + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + return; + } + + /* + * Do we have a callback? + */ + if (!ncm->cb) { + return; + } + + /* + * callback + */ + cb = (nss_c2c_rx_msg_callback_t)ncm->cb; + cb((void *)ncm->app_data, ncrm); +} + +/* + * nss_c2c_rx_register_handler() + * Register handler for messaging + */ +void nss_c2c_rx_register_handler(struct nss_ctx_instance *nss_ctx) +{ + nss_core_register_handler(nss_ctx, NSS_C2C_RX_INTERFACE, nss_c2c_rx_interface_handler, NULL); + + if (nss_ctx->id == NSS_CORE_0) { + nss_c2c_rx_stats_dentry_create(); + } + nss_c2c_rx_strings_dentry_create(); +} +EXPORT_SYMBOL(nss_c2c_rx_register_handler); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_c2c_rx_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_rx_stats.c new file mode 100644 index 000000000..d9ea31656 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_rx_stats.c @@ -0,0 +1,173 @@ +/* + ************************************************************************** + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_c2c_rx_stats.h" +#include "nss_c2c_rx_strings.h" + +/* + * Declare atomic notifier data structure for statistics. + */ +ATOMIC_NOTIFIER_HEAD(nss_c2c_rx_stats_notifier); + +/* + * Spinlock to protect C2C_RX statistics update/read + */ +DEFINE_SPINLOCK(nss_c2c_rx_stats_lock); + +/* + * nss_c2c_rx_stats + * c2c_rx statistics + */ +uint64_t nss_c2c_rx_stats[NSS_MAX_CORES][NSS_C2C_RX_STATS_MAX]; + +/* + * nss_c2c_rx_stats_read() + * Read C2C_RX statistics + */ +static ssize_t nss_c2c_rx_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i, core; + + /* + * Max output lines = #stats * NSS_MAX_CORES + + * few blank lines for banner printing + Number of Extra outputlines for future reference to add new stats + */ + uint32_t max_output_lines = NSS_C2C_RX_STATS_MAX * NSS_MAX_CORES + NSS_STATS_EXTRA_OUTPUT_LINES; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return -ENOMEM; + } + + stats_shadow = kzalloc(NSS_C2C_RX_STATS_MAX * 8, GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return -ENOMEM; + } + + /* + * C2C_RX statistics + */ + for (core = 0; core < NSS_MAX_CORES; core++) { + spin_lock_bh(&nss_c2c_rx_stats_lock); + for (i = 0; i < NSS_C2C_RX_STATS_MAX; i++) { + stats_shadow[i] = nss_c2c_rx_stats[core][i]; + } + spin_unlock_bh(&nss_c2c_rx_stats_lock); + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "c2c_rx", core); + size_wr += nss_stats_print("c2c_rx", NULL, NSS_STATS_SINGLE_INSTANCE + , nss_c2c_rx_strings_stats + , stats_shadow + , NSS_C2C_RX_STATS_MAX + , lbuf, size_wr, size_al); + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * nss_c2c_rx_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(c2c_rx); + +/* + * nss_c2c_rx_stats_dentry_create() + * Create C2C_RX statistics debug entry. + */ +void nss_c2c_rx_stats_dentry_create(void) +{ + nss_stats_create_dentry("c2c_rx", &nss_c2c_rx_stats_ops); +} + +/* + * nss_c2c_rx_stats_sync() + * Handle the syncing of NSS C2C_RX statistics. + */ +void nss_c2c_rx_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_c2c_rx_stats *ncrs) +{ + int id = nss_ctx->id; + int j; + + spin_lock_bh(&nss_c2c_rx_stats_lock); + + /* + * Common node stats + */ + nss_c2c_rx_stats[id][NSS_STATS_NODE_RX_PKTS] += (ncrs->pbuf_simple + ncrs->pbuf_sg + ncrs->pbuf_returning); + nss_c2c_rx_stats[id][NSS_STATS_NODE_RX_BYTES] += ncrs->node_stats.rx_bytes; + nss_c2c_rx_stats[id][NSS_STATS_NODE_TX_PKTS] += ncrs->node_stats.tx_packets; + nss_c2c_rx_stats[id][NSS_STATS_NODE_TX_BYTES] += ncrs->node_stats.tx_bytes; + + for (j = 0; j < NSS_MAX_NUM_PRI; j++) { + nss_c2c_rx_stats[id][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + j] += ncrs->node_stats.rx_dropped[j]; + } + + /* + * C2C_RX statistics + */ + nss_c2c_rx_stats[id][NSS_C2C_RX_STATS_PBUF_SIMPLE] += ncrs->pbuf_simple; + nss_c2c_rx_stats[id][NSS_C2C_RX_STATS_PBUF_SG] += ncrs->pbuf_sg; + nss_c2c_rx_stats[id][NSS_C2C_RX_STATS_PBUF_RETURNING] += ncrs->pbuf_returning; + nss_c2c_rx_stats[id][NSS_C2C_RX_STATS_INVAL_DEST] += ncrs->inval_dest; + + spin_unlock_bh(&nss_c2c_rx_stats_lock); +} + +/* + * nss_c2c_rx_stats_notify() + * Sends notifications to all the registered modules. + * + * Leverage NSS-FW statistics timing to update Netlink. + */ +void nss_c2c_rx_stats_notify(struct nss_ctx_instance *nss_ctx) +{ + struct nss_c2c_rx_stats_notification c2c_rx_stats; + + c2c_rx_stats.core_id = nss_ctx->id; + memcpy(c2c_rx_stats.stats, nss_c2c_rx_stats[c2c_rx_stats.core_id], sizeof(c2c_rx_stats.stats)); + atomic_notifier_call_chain(&nss_c2c_rx_stats_notifier, NSS_STATS_EVENT_NOTIFY, (void *)&c2c_rx_stats); +} + +/* + * nss_c2c_rx_stats_register_notifier() + * Registers statistics notifier. + */ +int nss_c2c_rx_stats_register_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&nss_c2c_rx_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_c2c_rx_stats_register_notifier); + +/* + * nss_c2c_rx_stats_unregister_notifier() + * Deregisters statistics notifier. + */ +int nss_c2c_rx_stats_unregister_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&nss_c2c_rx_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_c2c_rx_stats_unregister_notifier); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_c2c_rx_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_rx_stats.h new file mode 100644 index 000000000..c53d08071 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_rx_stats.h @@ -0,0 +1,63 @@ +/* + ****************************************************************************** + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_C2C_RX_STATS_H +#define __NSS_C2C_RX_STATS_H + +#include + +/* + * c2c_rx_msg_type + * Message types supported + */ +enum c2c_rx_msg_type { + NSS_C2C_RX_MSG_TYPE_STATS, /* Statistics synchronization */ + NSS_C2C_RX_MSG_TYPE_MAX +}; + +/* + * nss_c2c_rx_stats + * The NSS c2c_rx node stats structure. + */ +struct nss_c2c_rx_stats { + struct nss_cmn_node_stats node_stats; + /* Common node stats for core-to-core reception. */ + uint32_t pbuf_simple; /* Number of received simple pbuf. */ + uint32_t pbuf_sg; /* Number of S/G pbuf received. */ + uint32_t pbuf_returning; /* Number of returning S/G pbuf. */ + uint32_t inval_dest; /* Number of pbuf enqueue failure because of dest is invalid. */ +}; + +/* + * nss_c2c_rx_msg + * Message structure to send/receive c2c_rx commands + */ +struct nss_c2c_rx_msg { + struct nss_cmn_msg cm; /* Message Header */ + union { + struct nss_c2c_rx_stats stats; /* c2c_rx statistics */ + } msg; +}; + +/* + * C2C_RX statistics APIs + */ +extern void nss_c2c_rx_stats_notify(struct nss_ctx_instance *nss_ctx); +typedef void (*nss_c2c_rx_msg_callback_t)(void *app_data, struct nss_c2c_rx_msg *msg); +extern void nss_c2c_rx_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_c2c_rx_stats *ncrs); +extern void nss_c2c_rx_stats_dentry_create(void); + +#endif /* __NSS_C2C_RX_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_c2c_rx_strings.c b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_rx_strings.c new file mode 100644 index 000000000..c20754d12 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_rx_strings.c @@ -0,0 +1,61 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_stats.h" +#include "nss_core.h" +#include "nss_strings.h" + +/* + * nss_c2c_rx_strings_stats + * Core-to-core Rx statistics strings. + */ +struct nss_stats_info nss_c2c_rx_strings_stats[NSS_C2C_RX_STATS_MAX] = { + {"rx_pkts" , NSS_STATS_TYPE_COMMON}, + {"rx_byts" , NSS_STATS_TYPE_COMMON}, + {"tx_pkts" , NSS_STATS_TYPE_COMMON}, + {"tx_byts" , NSS_STATS_TYPE_COMMON}, + {"rx_queue[0]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[1]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[2]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[3]_drops" , NSS_STATS_TYPE_DROP}, + {"pbuf_simple" , NSS_STATS_TYPE_SPECIAL}, + {"pbuf_sg" , NSS_STATS_TYPE_SPECIAL}, + {"pbuf_returning" , NSS_STATS_TYPE_SPECIAL}, + {"inval_dest" , NSS_STATS_TYPE_DROP} +}; + +/* + * nss_c2c_rx_strings_read() + * Read C2C Rx node statistics names. + */ +static ssize_t nss_c2c_rx_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_c2c_rx_strings_stats, NSS_C2C_RX_STATS_MAX); +} + +/* + * nss_c2c_rx_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(c2c_rx); + +/* + * nss_c2c_rx_strings_dentry_create() + * Create C2C Rx statistics strings debug entry. + */ +void nss_c2c_rx_strings_dentry_create(void) +{ + nss_strings_create_dentry("c2c_rx", &nss_c2c_rx_strings_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_c2c_rx_strings.h b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_rx_strings.h new file mode 100644 index 000000000..3810f11fa --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_rx_strings.h @@ -0,0 +1,23 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_C2C_RX_STRINGS_H +#define __NSS_C2C_RX_STRINGS_H + +extern struct nss_stats_info nss_c2c_rx_strings_stats[NSS_C2C_RX_STATS_MAX]; +extern void nss_c2c_rx_strings_dentry_create(void); + +#endif /* __NSS_C2C_RX_STRINGS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx.c b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx.c new file mode 100644 index 000000000..244f4598a --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx.c @@ -0,0 +1,439 @@ +/* + ************************************************************************** + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_c2c_tx.c + * NSS C2C_TX APIs + */ + +#include +#include "nss_c2c_tx_stats.h" +#include "nss_c2c_tx_log.h" +#include "nss_c2c_tx_strings.h" + +int nss_c2c_tx_test_id = -1; + +/* + * Private data structure. + */ +struct nss_c2c_tx_pvt { + struct semaphore sem; /* Semaphore structure. */ + struct completion complete; /* Completion structure. */ + int response; /* Response from FW. */ + void *cb; /* Original cb for sync msgs. */ + void *app_data; /* Original app_data for sync msgs. */ +}; + +/* + * Notify data structure + */ +struct nss_c2c_tx_notify_data { + nss_c2c_tx_msg_callback_t c2c_tx_callback; + void *app_data; +}; + +static struct nss_c2c_tx_notify_data nss_c2c_tx_notify[NSS_CORE_MAX]; +static struct nss_c2c_tx_pvt nss_c2c_tx_cfg_pvt; + +/* + * nss_c2c_tx_verify_if_num() + * Verify if_num passed to us. + */ +static inline bool nss_c2c_tx_verify_if_num(uint32_t if_num) +{ + return if_num == NSS_C2C_TX_INTERFACE; +} + +/* + * nss_c2c_tx_interface_handler() + * Handle NSS -> HLOS messages for C2C_TX Statistics + */ +static void nss_c2c_tx_msg_handler(struct nss_ctx_instance *nss_ctx, + struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_c2c_tx_msg *nctm = (struct nss_c2c_tx_msg *)ncm; + nss_c2c_tx_msg_callback_t cb; + + if (!nss_c2c_tx_verify_if_num(ncm->interface)) { + nss_warning("%px: invalid interface %d for c2c_tx\n", nss_ctx, ncm->interface); + return; + } + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_C2C_TX_MSG_TYPE_MAX) { + nss_warning("%px: received invalid message %d for c2c_tx", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_c2c_tx_msg)) { + nss_warning("%px: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Trace messages. + */ + nss_c2c_tx_log_rx_msg(nctm); + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + switch (nctm->cm.type) { + case NSS_C2C_TX_MSG_TYPE_TX_MAP: + case NSS_C2C_TX_MSG_TYPE_PERFORMANCE_TEST: + break; + + case NSS_C2C_TX_MSG_TYPE_STATS: + /* + * Update driver statistics and send statistics notifications to the registered modules. + */ + nss_c2c_tx_stats_sync(nss_ctx, &nctm->msg.stats); + nss_c2c_tx_stats_notify(nss_ctx); + break; + } + + /* + * Update the callback and app_data for NOTIFY messages + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_c2c_tx_notify[nss_ctx->id].c2c_tx_callback; + ncm->app_data = (nss_ptr_t)nss_c2c_tx_notify[nss_ctx->id].app_data; + } + + /* + * Do we have a callback? + */ + if (!ncm->cb) { + return; + } + + /* + * callback + */ + cb = (nss_c2c_tx_msg_callback_t)ncm->cb; + cb((void *)ncm->app_data, nctm); +} + +/* + * nss_c2c_tx_register_handler() + * Register handler for messaging + */ +void nss_c2c_tx_register_handler(struct nss_ctx_instance *nss_ctx) +{ + nss_info("%px: nss_c2c_tx_register_handler", nss_ctx); + nss_core_register_handler(nss_ctx, NSS_C2C_TX_INTERFACE, nss_c2c_tx_msg_handler, NULL); + + if (nss_ctx->id == NSS_CORE_0) { + nss_c2c_tx_stats_dentry_create(); + } + nss_c2c_tx_strings_dentry_create(); +} +EXPORT_SYMBOL(nss_c2c_tx_register_handler); + +/* + * nss_c2c_tx_tx_msg() + * Transmit an c2c_tx message to the FW with a specified size. + */ +nss_tx_status_t nss_c2c_tx_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_c2c_tx_msg *nctm) +{ + struct nss_cmn_msg *ncm = &nctm->cm; + + /* + * Sanity check the message + */ + if (!nss_c2c_tx_verify_if_num(ncm->interface)) { + nss_warning("%px: tx request for another interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type >= NSS_C2C_TX_MSG_TYPE_MAX) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + /* + * Trace messages. + */ + nss_c2c_tx_log_tx_msg(nctm); + + return nss_core_send_cmd(nss_ctx, nctm, sizeof(*nctm), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_c2c_tx_tx_msg); + +/* + * nss_c2c_tx_msg_cfg_map_callback() + * Callback function for tx_map configuration + */ +static void nss_c2c_tx_msg_cfg_map_callback(void *app_data, struct nss_c2c_tx_msg *nctm) +{ + struct nss_ctx_instance *nss_ctx __attribute__((unused)) = (struct nss_ctx_instance *)app_data; + if (nctm->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("%px: nss c2c_tx_map configuration failed: %d for NSS core %d\n", + nss_ctx, nctm->cm.error, nss_ctx->id); + } + + nss_info("%px: nss c2c_tx_map configuration succeeded for NSS core %d\n", + nss_ctx, nss_ctx->id); +} + +/* + * nss_c2c_tx_msg_performance_test_start_callback() + * Callback function for c2c_tx test start configuration + */ +static void nss_c2c_tx_msg_performance_test_callback(void *app_data, struct nss_c2c_tx_msg *nctm) +{ + struct nss_ctx_instance *nss_ctx __attribute__((unused)) = (struct nss_ctx_instance *)app_data; + + /* + * Test start has been failed. Restore the value to initial state. + */ + if (nctm->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("%px: nss c2c_tx test start failed: %d for NSS core %d\n", + nss_ctx, nctm->cm.error, nss_ctx->id); + nss_c2c_tx_test_id = -1; + return; + } + + nss_info("%px: nss c2c_tx test successfully initialized for NSS core %d\n", + nss_ctx, nss_ctx->id); +} + +/* + * nss_c2c_tx_msg_cfg_map() + * Send NSS to c2c_map + */ +nss_tx_status_t nss_c2c_tx_msg_cfg_map(struct nss_ctx_instance *nss_ctx, uint32_t tx_map, uint32_t c2c_intr_addr) +{ + int32_t status; + struct nss_c2c_tx_msg nctm; + struct nss_c2c_tx_map *cfg_map; + + nss_info("%px: C2C map:%x\n", nss_ctx, tx_map); + nss_c2c_tx_msg_init(&nctm, NSS_C2C_TX_INTERFACE, NSS_C2C_TX_MSG_TYPE_TX_MAP, + sizeof(struct nss_c2c_tx_map), nss_c2c_tx_msg_cfg_map_callback, (void *)nss_ctx); + + cfg_map = &nctm.msg.map; + cfg_map->tx_map = tx_map; + cfg_map->c2c_intr_addr = c2c_intr_addr; + + status = nss_c2c_tx_tx_msg(nss_ctx, &nctm); + if (unlikely(status != NSS_TX_SUCCESS)) { + return status; + } + + return NSS_TX_SUCCESS; +} + +/* + * nss_c2c_tx_msg_performance_test() + * Send NSS c2c peformance test start message. + */ +nss_tx_status_t nss_c2c_tx_msg_performance_test(struct nss_ctx_instance *nss_ctx, uint32_t test_id) +{ + int32_t status; + struct nss_c2c_tx_msg nctm; + struct nss_c2c_tx_test *test; + + nss_info("%px: C2C test message:%x\n", nss_ctx, test_id); + nss_c2c_tx_msg_init(&nctm, NSS_C2C_TX_INTERFACE, NSS_C2C_TX_MSG_TYPE_PERFORMANCE_TEST, + sizeof(struct nss_c2c_tx_test), nss_c2c_tx_msg_performance_test_callback, (void *)nss_ctx); + + test = &nctm.msg.test; + test->test_id = test_id; + + status = nss_c2c_tx_tx_msg(nss_ctx, &nctm); + if (unlikely(status != NSS_TX_SUCCESS)) { + return status; + } + + return NSS_TX_SUCCESS; +} + +/* + * nss_c2c_tx_msg_init() + * Initialize C2C_TX message. + */ +void nss_c2c_tx_msg_init(struct nss_c2c_tx_msg *nctm, uint16_t if_num, uint32_t type, uint32_t len, + nss_c2c_tx_msg_callback_t cb, void *app_data) +{ + nss_cmn_msg_init(&nctm->cm, if_num, type, len, (void *)cb, app_data); +} +EXPORT_SYMBOL(nss_c2c_tx_msg_init); + +/* + * nss_c2c_tx_performance_test_handler() + * Handles the performance test. + */ +static int nss_c2c_tx_performance_test_handler(struct ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[0]; + int ret, ret_c2c_tx, current_state; + current_state = nss_c2c_tx_test_id; + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + + if (ret != NSS_SUCCESS) { + return ret; + } + + if (!write) { + return ret; + } + + if (current_state != -1) { + nss_warning("%px: Another test is running.\n", nss_ctx); + return -EINVAL; + } + + if (nss_c2c_tx_test_id >= NSS_C2C_TX_TEST_TYPE_MAX || nss_c2c_tx_test_id <= 0) { + nss_warning("%px: Invalid test ID.\n", nss_ctx); + nss_c2c_tx_test_id = current_state; + return -EINVAL; + } + + nss_info("Starting the c2c_tx performance test\n"); + ret_c2c_tx = nss_c2c_tx_msg_performance_test(nss_ctx, nss_c2c_tx_test_id); + + if (ret_c2c_tx != NSS_SUCCESS) { + nss_warning("%px: Starting the test has failed.\n", nss_ctx); + nss_c2c_tx_test_id = -1; + } + + return ret_c2c_tx; +} + +static struct ctl_table nss_c2c_tx_table[] = { + { + .procname = "test_code", + .data = &nss_c2c_tx_test_id, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_c2c_tx_performance_test_handler, + }, + { } +}; + +static struct ctl_table nss_c2c_tx_dir[] = { + { + .procname = "c2c_tx", + .mode = 0555, + .child = nss_c2c_tx_table, + }, + { } +}; + +static struct ctl_table nss_c2c_tx_root_dir[] = { + { + .procname = "nss", + .mode = 0555, + .child = nss_c2c_tx_dir, + }, + { } +}; + +static struct ctl_table nss_c2c_tx_root[] = { + { + .procname = "dev", + .mode = 0555, + .child = nss_c2c_tx_root_dir, + }, + { } +}; + +static struct ctl_table_header *nss_c2c_tx_header; + +/* + * nss_c2c_tx_register_sysctl() + */ +void nss_c2c_tx_register_sysctl(void) +{ + + /* + * c2c_tx sema init. + */ + sema_init(&nss_c2c_tx_cfg_pvt.sem, 1); + init_completion(&nss_c2c_tx_cfg_pvt.complete); + + /* + * Register sysctl table. + */ + nss_c2c_tx_header = register_sysctl_table(nss_c2c_tx_root); +} + +/* + * nss_c2c_tx_unregister_sysctl() + * Unregister sysctl specific to c2c_tx + */ +void nss_c2c_tx_unregister_sysctl(void) +{ + /* + * Unregister sysctl table. + */ + if (nss_c2c_tx_header) { + unregister_sysctl_table(nss_c2c_tx_header); + } +} + +/* + * nss_c2c_tx_notify_register() + * Register to receive c2c_tx notify messages. + */ +struct nss_ctx_instance *nss_c2c_tx_notify_register(int core, nss_c2c_tx_msg_callback_t cb, void *app_data) +{ + if (core >= NSS_CORE_MAX) { + nss_warning("Input core number %d is wrong\n", core); + return NULL; + } + + nss_c2c_tx_notify[core].c2c_tx_callback = cb; + nss_c2c_tx_notify[core].app_data = app_data; + + return (struct nss_ctx_instance *)&nss_top_main.nss[core]; +} +EXPORT_SYMBOL(nss_c2c_tx_notify_register); + +/* + * nss_c2c_tx_notify_unregister() + * Unregister to receive c2c_tx notify messages. + */ +void nss_c2c_tx_notify_unregister(int core) +{ + if (core >= NSS_CORE_MAX) { + nss_warning("Input core number %d is wrong\n", core); + return; + } + + nss_c2c_tx_notify[core].c2c_tx_callback = NULL; + nss_c2c_tx_notify[core].app_data = NULL; +} +EXPORT_SYMBOL(nss_c2c_tx_notify_unregister); + +/* + * nss_c2c_tx_init() + */ +void nss_c2c_tx_init(void) +{ + int core; + + for (core = 0; core < NSS_CORE_MAX; core++) { + nss_c2c_tx_notify_register(core, NULL, NULL); + } +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_log.c new file mode 100644 index 000000000..088cef353 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_log.c @@ -0,0 +1,121 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_c2c_tx_log.c + * NSS C2C TX logger file. + */ + +#include "nss_core.h" + +/* + * nss_c2c_tx_log_message_types_str + * C2C TX message strings + */ +static int8_t *nss_c2c_tx_log_message_types_str[NSS_C2C_TX_MSG_TYPE_MAX] __maybe_unused = { + "C2C TX Stats message", + "C2C TX Map Message", +}; + +/* + * nss_c2c_tx_log_error_response_types_str + * Strings for error types for c2c_tx messages + */ +static int8_t *nss_c2c_tx_log_error_response_types_str[NSS_C2C_TX_MSG_ERROR_MAX] __maybe_unused = { + "No error", + "Invalid Operation" +}; + +/* + * nss_c2c_tx_map_msg()() + * Log NSS C2C TX Map message. + */ +static void nss_c2c_tx_map_msg(struct nss_c2c_tx_msg *nctm) +{ + struct nss_c2c_tx_map *nctmm __maybe_unused = &nctm->msg.map; + nss_trace("%px: NSS C2C TX Map message: \n" + "C2C Receiver Queue Start Address: %d\n" + "C2C Interrupt Register Address: %d\n", + nctm, + nctmm->tx_map, nctmm->c2c_intr_addr); +} + +/* + * nss_c2c_tx_log_verbose() + * Log message contents. + */ +static void nss_c2c_tx_log_verbose(struct nss_c2c_tx_msg *nctm) +{ + switch (nctm->cm.type) { + case NSS_C2C_TX_MSG_TYPE_TX_MAP: + nss_c2c_tx_map_msg(nctm); + break; + + default: + nss_trace("%px: Invalid message type\n", nctm); + break; + } +} + +/* + * nss_c2c_tx_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_c2c_tx_log_tx_msg(struct nss_c2c_tx_msg *nctm) +{ + if (nctm->cm.type >= NSS_C2C_TX_MSG_TYPE_MAX) { + nss_info("%px: Invalid message type\n", nctm); + return; + } + + nss_info("%px: type[%d]:%s\n", nctm, nctm->cm.type, nss_c2c_tx_log_message_types_str[nctm->cm.type]); + nss_c2c_tx_log_verbose(nctm); +} + +/* + * nss_c2c_tx_log_rx_msg() + * Log messages received from FW. + */ +void nss_c2c_tx_log_rx_msg(struct nss_c2c_tx_msg *nctm) +{ + if (nctm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", nctm); + return; + } + + if (nctm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (nctm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", nctm, nctm->cm.type, + nss_c2c_tx_log_message_types_str[nctm->cm.type], + nctm->cm.response, nss_cmn_response_str[nctm->cm.response]); + goto verbose; + } + + if (nctm->cm.error >= NSS_C2C_TX_MSG_ERROR_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + nctm, nctm->cm.type, nss_c2c_tx_log_message_types_str[nctm->cm.type], + nctm->cm.response, nss_cmn_response_str[nctm->cm.response], + nctm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + nctm, nctm->cm.type, nss_c2c_tx_log_message_types_str[nctm->cm.type], + nctm->cm.response, nss_cmn_response_str[nctm->cm.response], + nctm->cm.error, nss_c2c_tx_log_error_response_types_str[nctm->cm.error]); + +verbose: + nss_c2c_tx_log_verbose(nctm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_log.h new file mode 100644 index 000000000..e6ec47e77 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_log.h @@ -0,0 +1,36 @@ +/* + ****************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_C2C_TX_LOG_H +#define __NSS_C2C_TX_LOG_H +/* + * nss_c2c_tx_log.h + * NSS C2C TX Log Header File + */ + +/* + * nss_c2c_tx_log_tx_msg + * Logs an C2C TX message that is sent to the NSS firmware. + */ +void nss_c2c_tx_log_tx_msg(struct nss_c2c_tx_msg *nctm); + +/* + * nss_c2c_tx_log_rx_msg + * Logs an IPv4 message that is received from the NSS firmware. + */ +void nss_c2c_tx_log_rx_msg(struct nss_c2c_tx_msg *nctm); + +#endif /* __NSS_C2C_TX_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_stats.c new file mode 100644 index 000000000..7983f3f8c --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_stats.c @@ -0,0 +1,168 @@ +/* + ************************************************************************** + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_c2c_tx_stats.h" +#include "nss_c2c_tx_strings.h" + +/* + * Declare atomic notifier data structure for statistics. + */ +ATOMIC_NOTIFIER_HEAD(nss_c2c_tx_stats_notifier); + +/* + * Spinlock to protect C2C_TX statistics update/read + */ +DEFINE_SPINLOCK(nss_c2c_tx_stats_lock); + +/* + * nss_c2c_tx_stats + * c2c_tx statistics + */ +uint64_t nss_c2c_tx_stats[NSS_MAX_CORES][NSS_C2C_TX_STATS_MAX]; + +/* + * nss_c2c_tx_stats_read() + * Read c2c_tx statistics + */ +static ssize_t nss_c2c_tx_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i, core; + + /* + * Max output lines = #stats * NSS_MAX_CORES + + * few blank lines for banner printing + Number of Extra outputlines for future reference to add new stats + */ + uint32_t max_output_lines = NSS_C2C_TX_STATS_MAX * NSS_MAX_CORES + NSS_STATS_EXTRA_OUTPUT_LINES; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return -ENOMEM; + } + + stats_shadow = kzalloc(NSS_C2C_TX_STATS_MAX * 8, GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return -ENOMEM; + } + + /* + * C2C_TX statistics + */ + for (core = 0; core < NSS_MAX_CORES; core++) { + spin_lock_bh(&nss_c2c_tx_stats_lock); + for (i = 0; i < NSS_C2C_TX_STATS_MAX; i++) { + stats_shadow[i] = nss_c2c_tx_stats[core][i]; + } + spin_unlock_bh(&nss_c2c_tx_stats_lock); + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "c2c_tx", core); + size_wr += nss_stats_print("c2c_tx", NULL, NSS_STATS_SINGLE_INSTANCE, nss_c2c_tx_strings_stats, stats_shadow, NSS_C2C_TX_STATS_MAX, lbuf, size_wr, size_al); + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * nss_c2c_tx_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(c2c_tx); + +/* + * nss_c2c_tx_stats_dentry_create() + * Create c2c_tx statistics debug entry. + */ +void nss_c2c_tx_stats_dentry_create(void) +{ + nss_stats_create_dentry("c2c_tx", &nss_c2c_tx_stats_ops); +} + +/* + * nss_c2c_tx_stats_sync() + * Handle the syncing of NSS C2C_TX statistics. + */ +void nss_c2c_tx_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_c2c_tx_stats *nct) +{ + int id = nss_ctx->id; + int j; + + spin_lock_bh(&nss_c2c_tx_stats_lock); + + /* + * Common node stats + */ + nss_c2c_tx_stats[id][NSS_STATS_NODE_RX_PKTS] += (nct->pbuf_simple + nct->pbuf_sg + nct->pbuf_returning); + nss_c2c_tx_stats[id][NSS_STATS_NODE_RX_BYTES] += nct->node_stats.rx_bytes; + nss_c2c_tx_stats[id][NSS_STATS_NODE_TX_PKTS] += nct->node_stats.tx_packets; + nss_c2c_tx_stats[id][NSS_STATS_NODE_TX_BYTES] += nct->node_stats.tx_bytes; + + for (j = 0; j < NSS_MAX_NUM_PRI; j++) { + nss_c2c_tx_stats[id][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + j] += nct->node_stats.rx_dropped[j]; + } + + /* + * C2C_TX statistics + */ + nss_c2c_tx_stats[id][NSS_C2C_TX_STATS_PBUF_SIMPLE] += nct->pbuf_simple; + nss_c2c_tx_stats[id][NSS_C2C_TX_STATS_PBUF_SG] += nct->pbuf_sg; + nss_c2c_tx_stats[id][NSS_C2C_TX_STATS_PBUF_RETURNING] += nct->pbuf_returning; + + spin_unlock_bh(&nss_c2c_tx_stats_lock); +} + +/* + * nss_c2c_tx_stats_notify() + * Sends notifications to all the registered modules. + * + * Leverage NSS-FW statistics timing to update Netlink. + */ +void nss_c2c_tx_stats_notify(struct nss_ctx_instance *nss_ctx) +{ + struct nss_c2c_tx_stats_notification c2c_tx_stats; + + c2c_tx_stats.core_id = nss_ctx->id; + memcpy(c2c_tx_stats.stats, nss_c2c_tx_stats[c2c_tx_stats.core_id], sizeof(c2c_tx_stats.stats)); + atomic_notifier_call_chain(&nss_c2c_tx_stats_notifier, NSS_STATS_EVENT_NOTIFY, (void *)&c2c_tx_stats); +} + +/* + * nss_c2c_tx_stats_register_notifier() + * Registers statistics notifier. + */ +int nss_c2c_tx_stats_register_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&nss_c2c_tx_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_c2c_tx_stats_register_notifier); + +/* + * nss_c2c_tx_stats_unregister_notifier() + * Deregisters statistics notifier. + */ +int nss_c2c_tx_stats_unregister_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&nss_c2c_tx_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_c2c_tx_stats_unregister_notifier); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_stats.h new file mode 100644 index 000000000..f77a3b4d6 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_stats.h @@ -0,0 +1,29 @@ +/* + ****************************************************************************** + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_C2C_TX_STATS_H +#define __NSS_C2C_TX_STATS_H + +#include + +/* + * C2C Tx statistics APIs + */ +extern void nss_c2c_tx_stats_notify(struct nss_ctx_instance *nss_ctx); +extern void nss_c2c_tx_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_c2c_tx_stats *nct); +extern void nss_c2c_tx_stats_dentry_create(void); + +#endif /* __NSS_C2C_TX_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_strings.c b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_strings.c new file mode 100644 index 000000000..8272e8466 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_strings.c @@ -0,0 +1,61 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_stats.h" +#include "nss_core.h" +#include "nss_strings.h" + +/* + * nss_c2c_tx_strings_stats + * C2C Tx statistics strings. + */ +struct nss_stats_info nss_c2c_tx_strings_stats[NSS_C2C_TX_STATS_MAX] = { + {"rx_pkts" , NSS_STATS_TYPE_COMMON}, + {"rx_byts" , NSS_STATS_TYPE_COMMON}, + {"tx_pkts" , NSS_STATS_TYPE_COMMON}, + {"tx_byts" , NSS_STATS_TYPE_COMMON}, + {"rx_queue[0]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[1]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[2]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[3]_drops" , NSS_STATS_TYPE_DROP}, + {"pbuf_simple" , NSS_STATS_TYPE_SPECIAL}, + {"pbuf_sg" , NSS_STATS_TYPE_SPECIAL}, + {"pbuf_returning" , NSS_STATS_TYPE_SPECIAL} +}; + + +/* + * nss_c2c_tx_strings_read() + * Read c2c Tx node statistics names + */ +static ssize_t nss_c2c_tx_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_c2c_tx_strings_stats, NSS_C2C_TX_STATS_MAX); +} + +/* + * nss_c2c_tx_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(c2c_tx); + +/* + * nss_c2c_tx_strings_dentry_create() + * Create C2C Tx statistics strings debug entry. + */ +void nss_c2c_tx_strings_dentry_create(void) +{ + nss_strings_create_dentry("c2c_tx", &nss_c2c_tx_strings_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_strings.h b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_strings.h new file mode 100644 index 000000000..483177de5 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_c2c_tx_strings.h @@ -0,0 +1,23 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_C2C_TX_STRINGS_H +#define __NSS_C2C_TX_STRINGS_H + +extern struct nss_stats_info nss_c2c_tx_strings_stats[NSS_C2C_TX_STATS_MAX]; +extern void nss_c2c_tx_strings_dentry_create(void); + +#endif /* __NSS_C2C_TX_STRINGS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_capwap.c b/feeds/ipq807x/qca-nss-drv/src/nss_capwap.c new file mode 100644 index 000000000..d848be241 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_capwap.c @@ -0,0 +1,573 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + + /* + * nss_capwap.c + * NSS CAPWAP driver interface APIs + */ +#include "nss_core.h" +#include "nss_capwap.h" +#include "nss_cmn.h" +#include "nss_tx_rx_common.h" +#include "nss_capwap_stats.h" +#include "nss_capwap_log.h" +#include "nss_capwap_strings.h" + +/* + * Spinlock for protecting tunnel operations colliding with a tunnel destroy + */ +DEFINE_SPINLOCK(nss_capwap_spinlock); + +/* + * Array of pointer for NSS CAPWAP handles. Each handle has per-tunnel + * stats based on the if_num which is an index. + * + * Per CAPWAP tunnel/interface number instance. + */ +struct nss_capwap_handle { + atomic_t refcnt; /**< Reference count on the tunnel */ + uint32_t if_num; /**< Interface number */ + uint32_t tunnel_status; /**< 0=disable, 1=enabled */ + struct nss_ctx_instance *ctx; /**< Pointer to context */ + nss_capwap_msg_callback_t msg_callback; /**< Msg callback */ + void *app_data; /**< App data (argument) */ + struct nss_capwap_tunnel_stats stats; /**< Stats per-interface number */ +}; +static struct nss_capwap_handle *nss_capwap_hdl[NSS_MAX_DYNAMIC_INTERFACES]; + +/* + * nss_capwap_verify_if_num() + * Verify if_num passed to us. + */ +static bool nss_capwap_verify_if_num(uint32_t if_num) +{ + if (nss_is_dynamic_interface(if_num) == false) { + return false; + } + + if (nss_dynamic_interface_get_type(nss_capwap_get_ctx(), if_num) != NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP) { + return false; + } + + return true; +} + +/* + * nss_capwap_refcnt_inc() + * Increments refcnt on the tunnel. + */ +static void nss_capwap_refcnt_inc(int32_t if_num) +{ + if_num = if_num - NSS_DYNAMIC_IF_START; + atomic_inc(&nss_capwap_hdl[if_num]->refcnt); + nss_assert(atomic_read(&nss_capwap_hdl[if_num]->refcnt) > 0); +} + +/* + * nss_capwap_refcnt_dec() + * Decrements refcnt on the tunnel. + */ +static void nss_capwap_refcnt_dec(int32_t if_num) +{ + if_num = if_num - NSS_DYNAMIC_IF_START; + nss_assert(atomic_read(&nss_capwap_hdl[if_num]->refcnt) > 0); + atomic_dec(&nss_capwap_hdl[if_num]->refcnt); +} + +/* + * nss_capwap_refcnt() + * Get refcnt on the tunnel. + */ +static uint32_t nss_capwap_refcnt(int32_t if_num) +{ + if_num = if_num - NSS_DYNAMIC_IF_START; + return atomic_read(&nss_capwap_hdl[if_num]->refcnt); +} + +/* + * nss_capwap_set_msg_callback() + * This sets the message callback handler and its associated context + */ +static void nss_capwap_set_msg_callback(int32_t if_num, nss_capwap_msg_callback_t cb, void *app_data) +{ + struct nss_capwap_handle *h; + + h = nss_capwap_hdl[if_num - NSS_DYNAMIC_IF_START]; + if (!h) { + return; + } + + h->app_data = app_data; + h->msg_callback = cb; +} + +/* + * nss_capwap_get_msg_callback() + * This gets the message callback handler and its associated context + */ +static nss_capwap_msg_callback_t nss_capwap_get_msg_callback(int32_t if_num, void **app_data) +{ + struct nss_capwap_handle *h; + + h = nss_capwap_hdl[if_num - NSS_DYNAMIC_IF_START]; + if (!h) { + *app_data = NULL; + return NULL; + } + + *app_data = h->app_data; + return h->msg_callback; +} + +/* + * nss_capwapmgr_update_stats() + * Update per-tunnel stats for each CAPWAP interface. + */ +static void nss_capwapmgr_update_stats(struct nss_capwap_handle *handle, struct nss_capwap_stats_msg *fstats) +{ + struct nss_capwap_tunnel_stats *stats; + + stats = &handle->stats; + + stats->rx_segments += fstats->rx_segments; + stats->dtls_pkts += fstats->dtls_pkts; + + stats->rx_dup_frag += fstats->rx_dup_frag; + stats->rx_oversize_drops += fstats->rx_oversize_drops; + stats->rx_frag_timeout_drops += fstats->rx_frag_timeout_drops; + stats->rx_queue_full_drops += fstats->rx_queue_full_drops; + stats->rx_n2h_queue_full_drops += fstats->rx_n2h_queue_full_drops; + stats->rx_mem_failure_drops += fstats->rx_mem_failure_drops; + stats->rx_csum_drops += fstats->rx_csum_drops; + stats->rx_malformed += fstats->rx_malformed; + stats->rx_frag_gap_drops += fstats->rx_frag_gap_drops; + + stats->tx_segments += fstats->tx_segments; + stats->tx_queue_full_drops += fstats->tx_queue_full_drops; + stats->tx_mem_failure_drops += fstats->tx_mem_failure_drops; + stats->tx_dropped_sg_ref += fstats->tx_dropped_sg_ref; + stats->tx_dropped_ver_mis += fstats->tx_dropped_ver_mis; + stats->tx_dropped_hroom += fstats->tx_dropped_hroom; + stats->tx_dropped_dtls += fstats->tx_dropped_dtls; + stats->tx_dropped_nwireless += fstats->tx_dropped_nwireless; + + /* + * add pnode stats now. + */ + stats->pnode_stats.rx_packets += fstats->pnode_stats.rx_packets; + stats->pnode_stats.rx_bytes += fstats->pnode_stats.rx_bytes; + stats->pnode_stats.rx_dropped += nss_cmn_rx_dropped_sum(&fstats->pnode_stats); + stats->pnode_stats.tx_packets += fstats->pnode_stats.tx_packets; + stats->pnode_stats.tx_bytes += fstats->pnode_stats.tx_bytes; + + /* + * Set to 1 when the tunnel is operating in fast memory. + */ + stats->fast_mem = fstats->fast_mem; +} + +/* + * nss_capwap_handler() + * Handle NSS -> HLOS messages for CAPWAP + */ +static void nss_capwap_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_capwap_msg *ntm = (struct nss_capwap_msg *)ncm; + nss_capwap_msg_callback_t cb; + + /* + * Is this a valid request/response packet? + */ + if (ncm->type > NSS_CAPWAP_MSG_TYPE_MAX) { + nss_warning("%px: received invalid message %d for CAPWAP interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_capwap_msg)) { + nss_warning("%px: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Trace messages. + */ + nss_capwap_log_rx_msg(ntm); + + switch (ntm->cm.type) { + case NSS_CAPWAP_MSG_TYPE_SYNC_STATS: { + uint32_t if_num; + + if_num = ncm->interface - NSS_DYNAMIC_IF_START; + if (nss_capwap_hdl[if_num] != NULL) { + /* + * Update driver statistics and send statistics notifications to the registered modules. + */ + nss_capwapmgr_update_stats(nss_capwap_hdl[if_num], &ntm->msg.stats); + nss_capwap_stats_notify(ncm->interface, nss_ctx->id); + } + } + } + + /* + * Update the callback and app_data for NOTIFY messages. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_capwap_get_msg_callback(ncm->interface, (void **)&ncm->app_data); + } + + /* + * Do we have a callback + */ + if (!ncm->cb) { + nss_trace("%px: cb is null for interface %d", nss_ctx, ncm->interface); + return; + } + + cb = (nss_capwap_msg_callback_t)ncm->cb; + cb((void *)ncm->app_data, ntm); +} + +/* + * nss_capwap_instance_alloc() + * Allocate CAPWAP tunnel instance + */ +static bool nss_capwap_instance_alloc(struct nss_ctx_instance *nss_ctx, uint32_t if_num) +{ + struct nss_capwap_handle *h; + + /* + * Allocate a handle + */ + h = kmalloc(sizeof(struct nss_capwap_handle), GFP_ATOMIC); + if (h == NULL) { + nss_warning("%px: no memory for allocating CAPWAP instance for interface : %d", nss_ctx, if_num); + return false; + } + + memset(h, 0, sizeof(struct nss_capwap_handle)); + h->if_num = if_num; + + spin_lock(&nss_capwap_spinlock); + if (nss_capwap_hdl[if_num - NSS_DYNAMIC_IF_START] != NULL) { + spin_unlock(&nss_capwap_spinlock); + kfree(h); + nss_warning("%px: Another thread is already allocated instance for :%d", nss_ctx, if_num); + return false; + } + + nss_capwap_hdl[if_num - NSS_DYNAMIC_IF_START] = h; + spin_unlock(&nss_capwap_spinlock); + + return true; +} + +/* + * nss_capwap_tx_msg() + * Transmit a CAPWAP message to NSS FW. Don't call this from softirq/interrupts. + */ +nss_tx_status_t nss_capwap_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_capwap_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + int32_t status; + int32_t if_num; + + BUG_ON(in_interrupt()); + BUG_ON(in_softirq()); + BUG_ON(in_serving_softirq()); + + if (nss_capwap_verify_if_num(msg->cm.interface) == false) { + return NSS_TX_FAILURE_BAD_PARAM; + } + + if (ncm->type >= NSS_CAPWAP_MSG_TYPE_MAX) { + return NSS_TX_FAILURE_BAD_PARAM; + } + + if_num = msg->cm.interface - NSS_DYNAMIC_IF_START; + spin_lock(&nss_capwap_spinlock); + if (!nss_capwap_hdl[if_num]) { + spin_unlock(&nss_capwap_spinlock); + nss_warning("%px: capwap tunnel if_num is not there: %d", nss_ctx, msg->cm.interface); + return NSS_TX_FAILURE_BAD_PARAM; + } + nss_capwap_refcnt_inc(msg->cm.interface); + spin_unlock(&nss_capwap_spinlock); + + /* + * Trace messages. + */ + nss_capwap_log_tx_msg(msg); + + status = nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); + nss_capwap_refcnt_dec(msg->cm.interface); + return status; +} +EXPORT_SYMBOL(nss_capwap_tx_msg); + +/* + * nss_capwap_tx_buf() + * Transmit data buffer (skb) to a NSS interface number + */ +nss_tx_status_t nss_capwap_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf, uint32_t if_num) +{ + BUG_ON(!nss_capwap_verify_if_num(if_num)); + + return nss_core_send_packet(nss_ctx, os_buf, if_num, H2N_BIT_FLAG_VIRTUAL_BUFFER | H2N_BIT_FLAG_BUFFER_REUSABLE); +} +EXPORT_SYMBOL(nss_capwap_tx_buf); + +/* + *********************************** + * Register/Unregister/Miscellaneous APIs + *********************************** + */ + +/* + * nss_capwap_get_stats() + * API for getting stats from a CAPWAP tunnel interface stats + */ +bool nss_capwap_get_stats(uint32_t if_num, struct nss_capwap_tunnel_stats *stats) +{ + if (nss_capwap_verify_if_num(if_num) == false) { + return false; + } + + if_num = if_num - NSS_DYNAMIC_IF_START; + spin_lock(&nss_capwap_spinlock); + if (nss_capwap_hdl[if_num] == NULL) { + spin_unlock(&nss_capwap_spinlock); + return false; + } + + memcpy(stats, &nss_capwap_hdl[if_num]->stats, sizeof(struct nss_capwap_tunnel_stats)); + spin_unlock(&nss_capwap_spinlock); + return true; +} +EXPORT_SYMBOL(nss_capwap_get_stats); + +/* + * nss_capwap_notify_register() + * Registers a message notifier with NSS FW. It should not be called from + * softirq or interrupts. + */ +struct nss_ctx_instance *nss_capwap_notify_register(uint32_t if_num, nss_capwap_msg_callback_t cb, void *app_data) +{ + struct nss_ctx_instance *nss_ctx; + + nss_ctx = &nss_top_main.nss[nss_top_main.capwap_handler_id]; + + if (nss_capwap_verify_if_num(if_num) == false) { + nss_warning("%px: notfiy register received for invalid interface %d", nss_ctx, if_num); + return NULL; + } + + spin_lock(&nss_capwap_spinlock); + if (nss_capwap_hdl[if_num - NSS_DYNAMIC_IF_START] != NULL) { + spin_unlock(&nss_capwap_spinlock); + nss_warning("%px: notfiy register tunnel already exists for interface %d", nss_ctx, if_num); + return NULL; + } + spin_unlock(&nss_capwap_spinlock); + + return nss_ctx; +} +EXPORT_SYMBOL(nss_capwap_notify_register); + +/* + * nss_capwap_notify_unregister() + * unregister the CAPWAP notifier for the given interface number (if_num). + * It shouldn't be called from softirq or interrupts. + */ +nss_tx_status_t nss_capwap_notify_unregister(struct nss_ctx_instance *nss_ctx, uint32_t if_num) +{ + struct nss_top_instance *nss_top; + int index; + + if (nss_capwap_verify_if_num(if_num) == false) { + nss_warning("%px: notify unregister received for invalid interface %d", nss_ctx, if_num); + return NSS_TX_FAILURE_BAD_PARAM; + } + + nss_top = nss_ctx->nss_top; + if (nss_top == NULL) { + nss_warning("%px: notify unregister received for invalid nss_top %d", nss_ctx, if_num); + return NSS_TX_FAILURE_BAD_PARAM; + } + + index = if_num - NSS_DYNAMIC_IF_START; + spin_lock(&nss_capwap_spinlock); + if (nss_capwap_hdl[index] == NULL) { + spin_unlock(&nss_capwap_spinlock); + nss_warning("%px: notify unregister received for unallocated if_num: %d", nss_ctx, if_num); + return NSS_TX_FAILURE_BAD_PARAM; + } + + /* + * It's the responsibility of caller to wait and call us again. We return failure saying + * that we can't remove msg handler now. + */ + if (nss_capwap_refcnt(if_num) != 0) { + spin_unlock(&nss_capwap_spinlock); + nss_warning("%px: notify unregister tunnel %d: has reference", nss_ctx, if_num); + return NSS_TX_FAILURE_QUEUE; + } + + nss_capwap_set_msg_callback(if_num, NULL, NULL); + spin_unlock(&nss_capwap_spinlock); + + return NSS_TX_SUCCESS; +} +EXPORT_SYMBOL(nss_capwap_notify_unregister); + +/* + * nss_capwap_data_register() + * Registers a data packet notifier with NSS FW. + */ +struct nss_ctx_instance *nss_capwap_data_register(uint32_t if_num, nss_capwap_buf_callback_t cb, struct net_device *netdev, uint32_t features) +{ + struct nss_ctx_instance *nss_ctx; + int core_status; + + nss_ctx = nss_capwap_get_ctx(); + if (nss_capwap_verify_if_num(if_num) == false) { + nss_warning("%px: data register received for invalid interface %d", nss_ctx, if_num); + return NULL; + } + + spin_lock(&nss_capwap_spinlock); + if (nss_ctx->subsys_dp_register[if_num].ndev != NULL) { + spin_unlock(&nss_capwap_spinlock); + return NULL; + } + spin_unlock(&nss_capwap_spinlock); + + core_status = nss_core_register_handler(nss_ctx, if_num, nss_capwap_msg_handler, NULL); + if (core_status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: nss core register handler failed for if_num:%d with error :%d", nss_ctx, if_num, core_status); + return NULL; + } + + if (nss_capwap_instance_alloc(nss_ctx, if_num) == false) { + nss_warning("%px: couldn't allocate tunnel instance for if_num:%d", nss_ctx, if_num); + return NULL; + } + + nss_core_register_subsys_dp(nss_ctx, if_num, cb, NULL, NULL, netdev, features); + + return nss_ctx; +} +EXPORT_SYMBOL(nss_capwap_data_register); + +/* + * nss_capwap_data_unregister() + * Unregister a data packet notifier with NSS FW + */ +bool nss_capwap_data_unregister(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx; + struct nss_capwap_handle *h; + + nss_ctx = nss_capwap_get_ctx(); + if (nss_capwap_verify_if_num(if_num) == false) { + nss_warning("%px: data unregister received for invalid interface %d", nss_ctx, if_num); + return false; + } + + spin_lock(&nss_capwap_spinlock); + /* + * It's the responsibility of caller to wait and call us again. + */ + if (nss_capwap_refcnt(if_num) != 0) { + spin_unlock(&nss_capwap_spinlock); + nss_warning("%px: notify unregister tunnel %d: has reference", nss_ctx, if_num); + return false; + } + h = nss_capwap_hdl[if_num - NSS_DYNAMIC_IF_START]; + nss_capwap_hdl[if_num - NSS_DYNAMIC_IF_START] = NULL; + spin_unlock(&nss_capwap_spinlock); + + (void) nss_core_unregister_handler(nss_ctx, if_num); + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + + kfree(h); + return true; +} +EXPORT_SYMBOL(nss_capwap_data_unregister); + +/* + * nss_capwap_get_ctx() + * Return a CAPWAP NSS context. + */ +struct nss_ctx_instance *nss_capwap_get_ctx() +{ + struct nss_ctx_instance *nss_ctx; + + nss_ctx = &nss_top_main.nss[nss_top_main.capwap_handler_id]; + return nss_ctx; +} +EXPORT_SYMBOL(nss_capwap_get_ctx); + +/* + * nss_capwap_ifnum_with_core_id() + * Append core id to capwap interface num + */ +int nss_capwap_ifnum_with_core_id(int if_num) +{ + struct nss_ctx_instance *nss_ctx = nss_capwap_get_ctx(); + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + if (nss_is_dynamic_interface(if_num) == false) { + nss_info("%px: Invalid if_num: %d, must be a dynamic interface\n", nss_ctx, if_num); + return 0; + } + return NSS_INTERFACE_NUM_APPEND_COREID(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_capwap_ifnum_with_core_id); + +/* + * nss_capwap_get_max_buf_size() + * Return a CAPWAP NSS max_buf_size. + */ +uint32_t nss_capwap_get_max_buf_size(struct nss_ctx_instance *nss_ctx) +{ + return nss_core_get_max_buf_size(nss_ctx); +} +EXPORT_SYMBOL(nss_capwap_get_max_buf_size); + +/* + * nss_capwap_init() + * Initializes CAPWAP. Gets called from nss_init.c + */ +void nss_capwap_init() +{ + memset(&nss_capwap_hdl, 0, sizeof(nss_capwap_hdl)); + nss_capwap_stats_dentry_create(); + nss_capwap_strings_dentry_create(); +} + +/* + * nss_capwap_msg_init() + * Initialize capwap message. + */ +void nss_capwap_msg_init(struct nss_capwap_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, + nss_capwap_msg_callback_t cb, void *app_data) +{ + nss_cmn_msg_init(&ncm->cm, if_num, type, len, (void*)cb, app_data); +} +EXPORT_SYMBOL(nss_capwap_msg_init); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_capwap_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_capwap_log.c new file mode 100644 index 000000000..b0b8564ac --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_capwap_log.c @@ -0,0 +1,282 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_capwap_log.c + * NSS CAPWAP logger file. + */ + +#include "nss_core.h" + +/* + * nss_capwap_log_message_types_str + * CAPWAP message strings + */ +static int8_t *nss_capwap_log_message_types_str[NSS_CAPWAP_MSG_TYPE_MAX] __maybe_unused = { + "No Message", + "CAPWAP config Rule", + "CAPWAP unconfig Rule", + "CAPWAP Enable Tunnel", + "CAPWAP Disable Tunnel", + "CAPWAP Update Path MTU", + "CAPWAP Sync Stats", + "CAPWAP Version", + "CAPWAP DTLS", + "CAPWAP Add Flow Rule", + "CAPWAP Delete Flow Rule" +}; + +/* + * nss_capwap_log_error_response_types_str + * Strings for error types for CAPWAP messages + */ +static int8_t *nss_capwap_log_error_response_types_str[NSS_CAPWAP_ERROR_MSG_MAX] __maybe_unused = { + "CAPWAP Invalid Reassembly Timeout", + "CAPWAP Invalid PAth MTU", + "CAPWAP Invalid Max Fragment", + "CAPWAP Invalid Buffer Size", + "CAPWAP Invalid L3 Protocool", + "CAPWAP Invalid UDP Protocol", + "CAPWAP Invalid Version", + "CAPWAP Tunnel Disabled", + "CAPWAP Tunnel Enabled", + "CAPWAP Tunnel Not Configured", + "CAPWAP Invalid IP Node", + "CAPWAP Invalid Type Flag", + "CAPWAP Inavlid DTLS Config", + "CAPWAP Flow Table Full", + "CAPWAP Flow Exists", + "CAPWAP Flow Does Not Exist" +}; + +/* + * nss_capwap_rule_msg() + * Log NSS CAPWAP stats message. + */ +static void nss_capwap_rule_msg(struct nss_capwap_msg *ncm) +{ + struct nss_capwap_rule_msg *ncrm __maybe_unused = &ncm->msg.rule; + nss_trace("%px: NSS CAPWAP Rule message \n" + "Encap Rule Src IP: %px\n" + "Encap Rule Src Port: %d\n" + "Encap Rule Dst Ip: %px\n" + "Encap Rule Dst Port: %d\n" + "Encap Rule Path MTU: %d\n" + "Decap Rule Reassembly Timeout: %d\n" + "Decap Rule Max Fragments: %d\n" + "Decap Rule Max Buffer Size: %d\n" + "Stats Timer: %d\n" + "RPS: %d\n" + "Type Flags: %x\n" + "L3 Protocol: %d\n" + "UDP Protocol: %d\n" + "MTU: %d\n" + "GMAC Interface Number: %d\n" + "Enabled Features: %x\n" + "DTLS Interface Number: %d\n" + "BSSID: %px\n" + "Outer Segment Value: %x\n", + ncrm, + &ncrm->encap.src_ip.ip, + ncrm->encap.src_port, + &ncrm->encap.dest_ip.ip, + ncrm->encap.dest_port, + ncrm->encap.path_mtu, + ncrm->decap.reassembly_timeout, + ncrm->decap.max_fragments, + ncrm->decap.max_buffer_size, + ncrm->stats_timer, + ncrm->rps, ncrm->type_flags, + ncrm->l3_proto, ncrm->which_udp, + ncrm->mtu_adjust, ncrm->gmac_ifnum, + ncrm->enabled_features, + ncrm->dtls_inner_if_num, + &ncrm->bssid, ncrm->outer_sgt_value); +} + +/* + * nss_capwap_path_mtu_msg() + * Log NSS CAPWAP path MTU message. + */ +static void nss_capwap_path_mtu_msg(struct nss_capwap_msg *ncm) +{ + struct nss_capwap_path_mtu_msg *ncpmm __maybe_unused = &ncm->msg.mtu; + nss_trace("%px: NSS CAPWAP Path MTU message \n" + "CAPWAP Path MTU: %d\n", + ncpmm, + ncpmm->path_mtu); +} + +/* + * nss_capwap_version_msg() + * Log NSS CAPWAP version message. + */ +static void nss_capwap_version_msg(struct nss_capwap_msg *ncm) +{ + struct nss_capwap_version_msg *ncvm __maybe_unused = &ncm->msg.version; + nss_trace("%px: NSS CAPWAP Version message \n" + "CAPWAP Version: %d\n", + ncvm, + ncvm->version); +} + +/* + * nss_capwap_dtls_msg() + * Log NSS CAPWAP dtls message. + */ +static void nss_capwap_dtls_msg(struct nss_capwap_msg *ncm) +{ + struct nss_capwap_dtls_msg *ncdm __maybe_unused = &ncm->msg.dtls; + nss_trace("%px: NSS CAPWAP dtls message \n" + "CAPWAP DTLS Enable: %d\n" + "CAPWAP DTLS Inner Interface Number: %d\n" + "CAPWAP MTU Adjust: %d\n" + "CAPWAP Reserved: %x\n", + ncdm, + ncdm->enable, ncdm->dtls_inner_if_num, + ncdm->mtu_adjust, ncdm->reserved); +} + +/* + * nss_capwap_flow_rule_msg() + * Log NSS CAPWAP flow rule message. + */ +static void nss_capwap_flow_rule_msg(struct nss_capwap_flow_rule_msg *ncfrm) +{ + nss_trace("%px: NSS CAPWAP Flow Rule message \n" + "CAPWAP IP Version: %d\n" + "CAPWAP Layer 4 Protocol: %d\n" + "CAPWAP Source Port: %d\n" + "CAPWAP Destination Port: %d\n" + "CAPWAP Source IP: %x %x %x %x\n" + "CAPWAP Destination IP: %x %x %x %x" + "CAPWAP Flow ID: %d", + ncfrm, + ncfrm->ip_version, ncfrm->protocol, + ncfrm->src_port, ncfrm->dst_port, + ncfrm->src_ip[0], ncfrm->src_ip[1], + ncfrm->src_ip[2], ncfrm->src_ip[3], + ncfrm->dst_ip[0], ncfrm->dst_ip[1], + ncfrm->dst_ip[2], ncfrm->dst_ip[3], + ncfrm->flow_id); +} + +/* + * nss_capwap_flow_rule_add_msg() + * Log NSS CAPWAP flow rule add message. + */ +static void nss_capwap_flow_rule_add_msg(struct nss_capwap_msg *ncm) +{ + struct nss_capwap_flow_rule_msg *ncfrm __maybe_unused = &ncm->msg.flow_rule_add; + nss_capwap_flow_rule_msg(ncfrm); +} + +/* + * nss_capwap_flow_rule_del_msg() + * Log NSS CAPWAP flow rule del message. + */ +static void nss_capwap_flow_rule_del_msg(struct nss_capwap_msg *ncm) +{ + struct nss_capwap_flow_rule_msg *ncfrm __maybe_unused = &ncm->msg.flow_rule_del; + nss_capwap_flow_rule_msg(ncfrm); +} + +/* + * nss_capwap_log_verbose() + * Log message contents. + */ +static void nss_capwap_log_verbose(struct nss_capwap_msg *ncm) +{ + switch (ncm->cm.type) { + case NSS_CAPWAP_MSG_TYPE_CFG_RULE: + nss_capwap_rule_msg(ncm); + break; + + case NSS_CAPWAP_MSG_TYPE_UPDATE_PATH_MTU: + nss_capwap_path_mtu_msg(ncm); + break; + + case NSS_CAPWAP_MSG_TYPE_VERSION: + nss_capwap_version_msg(ncm); + break; + + case NSS_CAPWAP_MSG_TYPE_DTLS: + nss_capwap_dtls_msg(ncm); + break; + + case NSS_CAPWAP_MSG_TYPE_FLOW_RULE_ADD: + nss_capwap_flow_rule_add_msg(ncm); + break; + + case NSS_CAPWAP_MSG_TYPE_FLOW_RULE_DEL: + nss_capwap_flow_rule_del_msg(ncm); + break; + + default: + nss_trace("%px: Invalid message type\n", ncm); + break; + } +} + +/* + * nss_capwap_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_capwap_log_tx_msg(struct nss_capwap_msg *ncm) +{ + if (ncm->cm.type >= NSS_CAPWAP_MSG_TYPE_MAX) { + nss_warning("%px: Invalid message type\n", ncm); + return; + } + + nss_info("%px: type[%d]:%s\n", ncm, ncm->cm.type, nss_capwap_log_message_types_str[ncm->cm.type]); + nss_capwap_log_verbose(ncm); +} + +/* + * nss_capwap_log_rx_msg() + * Log messages received from FW. + */ +void nss_capwap_log_rx_msg(struct nss_capwap_msg *ncm) +{ + if (ncm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", ncm); + return; + } + + if (ncm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ncm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", ncm, ncm->cm.type, + nss_capwap_log_message_types_str[ncm->cm.type], + ncm->cm.response, nss_cmn_response_str[ncm->cm.response]); + goto verbose; + } + + if (ncm->cm.error >= NSS_CAPWAP_ERROR_MSG_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + ncm, ncm->cm.type, nss_capwap_log_message_types_str[ncm->cm.type], + ncm->cm.response, nss_cmn_response_str[ncm->cm.response], + ncm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + ncm, ncm->cm.type, nss_capwap_log_message_types_str[ncm->cm.type], + ncm->cm.response, nss_cmn_response_str[ncm->cm.response], + ncm->cm.error, nss_capwap_log_error_response_types_str[ncm->cm.error]); + +verbose: + nss_capwap_log_verbose(ncm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_capwap_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_capwap_log.h new file mode 100644 index 000000000..f62098979 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_capwap_log.h @@ -0,0 +1,37 @@ +/* + ****************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_CAPWAP_LOG_H__ +#define __NSS_CAPWAP_LOG_H__ + +/* + * nss_capwap_log.h + * NSS CAPWAP Log Header File. + */ + +/* + * nss_capwap_log_tx_msg + * Logs a CAPWAP message that is sent to the NSS firmware. + */ +void nss_capwap_log_tx_msg(struct nss_capwap_msg *ncm); + +/* + * nss_capwap_log_rx_msg + * Logs a CAPWAP message that is received from the NSS firmware. + */ +void nss_capwap_log_rx_msg(struct nss_capwap_msg *ncm); + +#endif /* __NSS_CAPWAP_LOG_H__ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_capwap_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_capwap_stats.c new file mode 100644 index 000000000..af8d3671e --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_capwap_stats.c @@ -0,0 +1,303 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_drv_stats.h" +#include "nss_core.h" +#include "nss_capwap.h" +#include "nss_capwap_stats.h" +#include "nss_capwap_strings.h" + +/* + * Declare atomic notifier data structure for statistics. + */ +ATOMIC_NOTIFIER_HEAD(nss_capwap_stats_notifier); + +/* + * nss_capwap_stats_encap() + * Make a row for CAPWAP encap stats. + */ +static ssize_t nss_capwap_stats_encap(char *line, int len, int i, struct nss_capwap_tunnel_stats *s) +{ + uint64_t tcnt = 0; + + switch (i) { + case 0: + tcnt = s->pnode_stats.tx_packets; + break; + case 1: + tcnt = s->pnode_stats.tx_bytes; + break; + case 2: + tcnt = s->tx_segments; + break; + case 3: + tcnt = s->tx_dropped_sg_ref; + break; + case 4: + tcnt = s->tx_dropped_ver_mis; + break; + case 5: + tcnt = 0; + break; + case 6: + tcnt = s->tx_dropped_hroom; + break; + case 7: + tcnt = s->tx_dropped_dtls; + break; + case 8: + tcnt = s->tx_dropped_nwireless; + break; + case 9: + tcnt = s->tx_queue_full_drops; + break; + case 10: + tcnt = s->tx_mem_failure_drops; + break; + case 11: + tcnt = s->fast_mem; + break; + default: + return 0; + } + + return snprintf(line, len, "%s = %llu\n", nss_capwap_strings_encap_stats[i].stats_name, tcnt); +} + +/* + * nss_capwap_stats_decap() + * Make a row for CAPWAP decap stats. + */ +static ssize_t nss_capwap_stats_decap(char *line, int len, int i, struct nss_capwap_tunnel_stats *s) +{ + uint64_t tcnt = 0; + + switch (i) { + case 0: + tcnt = s->pnode_stats.rx_packets; + break; + case 1: + tcnt = s->pnode_stats.rx_bytes; + break; + case 2: + tcnt = s->dtls_pkts; + break; + case 3: + tcnt = s->rx_segments; + break; + case 4: + tcnt = s->pnode_stats.rx_dropped; + break; + case 5: + tcnt = s->rx_oversize_drops; + break; + case 6: + tcnt = s->rx_frag_timeout_drops; + break; + case 7: + tcnt = s->rx_dup_frag; + break; + case 8: + tcnt = s->rx_frag_gap_drops; + break; + case 9: + tcnt = s->rx_queue_full_drops; + return snprintf(line, len, "%s = %llu (n2h = %llu)\n", nss_capwap_strings_decap_stats[i].stats_name, tcnt, s->rx_n2h_queue_full_drops); + case 10: + tcnt = s->rx_n2h_queue_full_drops; + break; + case 11: + tcnt = s->rx_mem_failure_drops; + break; + case 12: + tcnt = s->rx_csum_drops; + break; + case 13: + tcnt = s->rx_malformed; + break; + case 14: + tcnt = s->fast_mem; + break; + default: + return 0; + } + + return snprintf(line, len, "%s = %llu\n", nss_capwap_strings_decap_stats[i].stats_name, tcnt); +} + +/* + * nss_capwap_stats_read() + * Read CAPWAP stats + */ +static ssize_t nss_capwap_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos, uint16_t type) +{ + struct nss_stats_data *data = fp->private_data; + ssize_t bytes_read = 0; + struct nss_capwap_tunnel_stats stats; + size_t bytes; + char line[80]; + int start; + uint32_t if_num = NSS_DYNAMIC_IF_START; + uint32_t max_if_num = NSS_DYNAMIC_IF_START + NSS_MAX_DYNAMIC_INTERFACES; + + if (data) { + if_num = data->if_num; + } + + /* + * If we are done accomodating all the CAPWAP tunnels. + */ + if (if_num > max_if_num) { + return 0; + } + + for (; if_num <= max_if_num; if_num++) { + bool isthere; + + if (nss_is_dynamic_interface(if_num) == false) { + continue; + } + + if (nss_dynamic_interface_get_type(nss_capwap_get_ctx(), if_num) != NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP) { + continue; + } + + /* + * If CAPWAP tunnel does not exists, then isthere will be false. + */ + isthere = nss_capwap_get_stats(if_num, &stats); + if (!isthere) { + continue; + } + + bytes = snprintf(line, sizeof(line), "----if_num : %2d----\n", if_num); + if ((bytes_read + bytes) > sz) { + break; + } + + if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) { + bytes_read = -EFAULT; + goto fail; + } + bytes_read += bytes; + start = 0; + while (bytes_read < sz) { + if (type == 1) { + bytes = nss_capwap_stats_encap(line, sizeof(line), start, &stats); + } else { + bytes = nss_capwap_stats_decap(line, sizeof(line), start, &stats); + } + + /* + * If we don't have any more lines in decap/encap. + */ + if (bytes == 0) { + break; + } + + if ((bytes_read + bytes) > sz) + break; + + if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) { + bytes_read = -EFAULT; + goto fail; + } + + bytes_read += bytes; + start++; + } + } + + if (bytes_read > 0) { + *ppos = bytes_read; + } + + if (data) { + data->if_num = if_num; + } +fail: + return bytes_read; +} + +/* + * nss_capwap_decap_stats_read() + * Read CAPWAP decap stats + */ +static ssize_t nss_capwap_decap_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_capwap_stats_read(fp, ubuf, sz, ppos, 0); +} + +/* + * nss_capwap_encap_stats_read() + * Read CAPWAP encap stats + */ +static ssize_t nss_capwap_encap_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_capwap_stats_read(fp, ubuf, sz, ppos, 1); +} + +/* + * nss_capwap_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(capwap_encap); +NSS_STATS_DECLARE_FILE_OPERATIONS(capwap_decap); + +/* + * nss_capwap_stats_dentry_create() + * Create CAPWAP statistics debug entry + */ +void nss_capwap_stats_dentry_create(void) +{ + nss_stats_create_dentry("capwap_encap", &nss_capwap_encap_stats_ops); + nss_stats_create_dentry("capwap_decap", &nss_capwap_decap_stats_ops); +} + +/* + * nss_capwap_stats_notify() + * Sends notifications to the registered modules. + * + * Leverage NSS-FW statistics timing to update Netlink. + */ +void nss_capwap_stats_notify(uint32_t if_num, uint32_t core_id) +{ + struct nss_capwap_stats_notification capwap_stats; + + capwap_stats.core_id = core_id; + capwap_stats.if_num = if_num; + nss_capwap_get_stats(if_num, &capwap_stats.stats); + atomic_notifier_call_chain(&nss_capwap_stats_notifier, NSS_STATS_EVENT_NOTIFY, (void *)&capwap_stats); +} + +/* + * nss_capwap_stats_register_notifier() + * Registers statistics notifier. + */ +int nss_capwap_stats_register_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&nss_capwap_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_capwap_stats_register_notifier); + +/* + * nss_capwap_stats_unregister_notifier() + * Deregisters statistics notifier. + */ +int nss_capwap_stats_unregister_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&nss_capwap_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_capwap_stats_unregister_notifier); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_capwap_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_capwap_stats.h new file mode 100644 index 000000000..c1033ec15 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_capwap_stats.h @@ -0,0 +1,26 @@ +/* + ****************************************************************************** + * Copyright (c) 2017,2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_CAPWAP_STATS_H__ +#define __NSS_CAPWAP_STATS_H__ + +/* + * CAPWAP statistics APIs + */ +extern void nss_capwap_stats_notify(uint32_t if_num, uint32_t core_id); +extern void nss_capwap_stats_dentry_create(void); + +#endif /* __NSS_CAPWAP_STATS_H__ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_capwap_strings.c b/feeds/ipq807x/qca-nss-drv/src/nss_capwap_strings.c new file mode 100644 index 000000000..6ed5b2a01 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_capwap_strings.c @@ -0,0 +1,102 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_stats.h" +#include "nss_core.h" +#include +#include "nss_strings.h" +#include "nss_capwap_strings.h" + +/* + * nss_capwap_strings_encap_stats + * CAPWAP encap statistics string. + */ +struct nss_stats_info nss_capwap_strings_encap_stats[NSS_CAPWAP_STATS_ENCAP_MAX] = { + {"tx_packets", NSS_STATS_TYPE_COMMON}, + {"tx_bytes", NSS_STATS_TYPE_COMMON}, + {"tx_segments", NSS_STATS_TYPE_SPECIAL}, + {"tx_drop_seg_ref", NSS_STATS_TYPE_DROP}, + {"tx_drop_ver_mismatch",NSS_STATS_TYPE_DROP}, + {"tx_drop_unalign", NSS_STATS_TYPE_DROP}, + {"tx_drop_hroom", NSS_STATS_TYPE_DROP}, + {"tx_drop_DTLS", NSS_STATS_TYPE_DROP}, + {"tx_drop_nwireless", NSS_STATS_TYPE_DROP}, + {"tx_drop_qfull", NSS_STATS_TYPE_DROP}, + {"tx_drop_mem_fail", NSS_STATS_TYPE_DROP}, + {"fast_mem", NSS_STATS_TYPE_SPECIAL} +}; + +/* + * nss_capwap_encap_strings_read() + * Read CAPWAP encap statistics names. + */ +static ssize_t nss_capwap_encap_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_capwap_strings_encap_stats, NSS_CAPWAP_STATS_ENCAP_MAX); +} + +/* + * nss_capwap_encap_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(capwap_encap); + +/* + * nss_capwap_strings_decap_stats + * CAPWAP decap statistics string. + */ +struct nss_stats_info nss_capwap_strings_decap_stats[NSS_CAPWAP_STATS_DECAP_MAX] = { + {"rx_packets", NSS_STATS_TYPE_COMMON}, + {"rx_bytes", NSS_STATS_TYPE_COMMON}, + {"rx_DTLS_pkts", NSS_STATS_TYPE_SPECIAL}, + {"rx_segments", NSS_STATS_TYPE_SPECIAL}, + {"rx_dropped", NSS_STATS_TYPE_DROP}, + {"rx_drop_oversize", NSS_STATS_TYPE_DROP}, + {"rx_drop_frag_timeout",NSS_STATS_TYPE_DROP}, + {"rx_drop_frag_dup", NSS_STATS_TYPE_DROP}, + {"rx_drop_frag_gap", NSS_STATS_TYPE_DROP}, + {"rx_drop_qfull", NSS_STATS_TYPE_DROP}, + {"rx_drop_n2h_qfull", NSS_STATS_TYPE_DROP}, + {"rx_drop_mem_fail", NSS_STATS_TYPE_DROP}, + {"rx_drop_csum", NSS_STATS_TYPE_DROP}, + {"rx_drop_malformed", NSS_STATS_TYPE_DROP}, + {"fast_mem", NSS_STATS_TYPE_SPECIAL} +}; + +/* + * nss_capwap_decap_strings_read() + * Read CAPWAP decap statistics names. + */ +static ssize_t nss_capwap_decap_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_capwap_strings_decap_stats, NSS_CAPWAP_STATS_DECAP_MAX); +} + +/* + * nss_capwap_decap_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(capwap_decap); + +/* + * nss_capwap_strings_dentry_create() + * Create CAPWAP statistics strings debug entry. + */ +void nss_capwap_strings_dentry_create(void) +{ + nss_strings_create_dentry("capwap_encap", &nss_capwap_encap_strings_ops); + nss_strings_create_dentry("capwap_decap", &nss_capwap_decap_strings_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_capwap_strings.h b/feeds/ipq807x/qca-nss-drv/src/nss_capwap_strings.h new file mode 100644 index 000000000..96f89cdce --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_capwap_strings.h @@ -0,0 +1,28 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_CAPWAP_STRINGS_H +#define __NSS_CAPWAP_STRINGS_H + +#include "nss_capwap_stats.h" + +extern struct nss_stats_info nss_capwap_strings_encap_stats[NSS_CAPWAP_STATS_ENCAP_MAX]; +extern struct nss_stats_info nss_capwap_strings_decap_stats[NSS_CAPWAP_STATS_DECAP_MAX]; +extern void nss_capwap_strings_dentry_create(void); + +#endif /* __NSS_CAPWAP_STRINGS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_clmap.c b/feeds/ipq807x/qca-nss-drv/src/nss_clmap.c new file mode 100644 index 000000000..0d78a719a --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_clmap.c @@ -0,0 +1,342 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + + /* + * nss_clmap.c + * NSS clmap driver interface APIs + */ +#include "nss_core.h" +#include "nss_clmap.h" +#include "nss_cmn.h" +#include "nss_tx_rx_common.h" +#include "nss_clmap_stats.h" +#include "nss_clmap_log.h" + +#define NSS_CLMAP_TX_TIMEOUT 3000 + +/* + * Private data structure + */ +static struct nss_clmap_pvt { + struct semaphore sem; /* Semaphore structure. */ + struct completion complete; /* Completion structure. */ + int response; /* Response from FW. */ + void *cb; /* Original cb for msgs. */ + void *app_data; /* Original app_data for msgs. */ +} clmap_pvt; + +/* + * nss_clmap_verify_if_num() + * Verify if_num passed to us. + */ +static bool nss_clmap_verify_if_num(uint32_t if_num) +{ + uint32_t type = nss_dynamic_interface_get_type(nss_clmap_get_ctx(), if_num); + + return ((type == NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_US) || + (type == NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_DS)); +} + +/* + * nss_clmap_callback() + * Callback to handle the completion of NSS->HLOS messages. + */ +static void nss_clmap_callback(void *app_data, struct nss_clmap_msg *nclm) +{ + clmap_pvt.response = NSS_TX_SUCCESS; + clmap_pvt.cb = NULL; + clmap_pvt.app_data = NULL; + + if (nclm->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("clmap Error response %d\n", nclm->cm.response); + clmap_pvt.response = nclm->cm.response; + } + + /* + * Write memory barrier. + */ + smp_wmb(); + complete(&clmap_pvt.complete); +} + +/* + * nss_clmap_handler() + * Handle NSS -> HLOS messages for clmap. + */ +static void nss_clmap_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_clmap_msg *nclm = (struct nss_clmap_msg *)ncm; + nss_clmap_msg_callback_t cb; + + BUG_ON(!nss_clmap_verify_if_num(ncm->interface)); + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_CLMAP_MSG_TYPE_MAX) { + nss_warning("%px: received invalid message %d for clmap interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_clmap_msg)) { + nss_warning("%px: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Trace messages. + */ + nss_core_log_msg_failures(nss_ctx, ncm); + nss_clmap_log_rx_msg(nclm); + + switch (nclm->cm.type) { + case NSS_CLMAP_MSG_TYPE_SYNC_STATS: + nss_clmap_stats_sync(nss_ctx, &nclm->msg.stats, ncm->interface); + break; + } + + /* + * Update the callback and app_data for NOTIFY messages. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_core_get_msg_handler(nss_ctx, ncm->interface); + ncm->app_data = (nss_ptr_t)nss_ctx->nss_rx_interface_handlers[ncm->interface].app_data; + } + + /* + * Do we have a callback + */ + cb = (nss_clmap_msg_callback_t)ncm->cb; + if (!cb) { + nss_trace("%px: cb is null for interface %d", nss_ctx, ncm->interface); + return; + } + + cb((void *)ncm->app_data, ncm); +} + +/* + * nss_clmap_tx_msg() + * Transmit a clmap message to NSS FW. Don't call this from softirq/interrupts. + */ +nss_tx_status_t nss_clmap_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_clmap_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + if (!nss_clmap_verify_if_num(msg->cm.interface)) { + return NSS_TX_FAILURE_BAD_PARAM; + } + + if (ncm->type >= NSS_CLMAP_MSG_TYPE_MAX) { + return NSS_TX_FAILURE_BAD_PARAM; + } + + /* + * Trace messages. + */ + nss_clmap_log_tx_msg(msg); + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_clmap_tx_msg); + +/* + * nss_clmap_tx_msg_sync() + * Transmit a clmap message to NSS firmware synchronously. + */ +nss_tx_status_t nss_clmap_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_clmap_msg *nclm) +{ + nss_tx_status_t status; + int ret; + + down(&clmap_pvt.sem); + nclm->cm.cb = (nss_ptr_t)nss_clmap_callback; + nclm->cm.app_data = (nss_ptr_t)NULL; + + status = nss_clmap_tx_msg(nss_ctx, nclm); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: clmap_tx_msg failed\n", nss_ctx); + up(&clmap_pvt.sem); + return status; + } + + ret = wait_for_completion_timeout(&clmap_pvt.complete, msecs_to_jiffies(NSS_CLMAP_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: clmap tx sync failed due to timeout\n", nss_ctx); + clmap_pvt.response = NSS_TX_FAILURE; + } + + status = clmap_pvt.response; + up(&clmap_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_clmap_tx_msg_sync); + +/* + * nss_clmap_tx_buf() + * Transmit data buffer (skb) to a NSS interface number + */ +nss_tx_status_t nss_clmap_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *buf, uint32_t if_num) +{ + BUG_ON(!nss_clmap_verify_if_num(if_num)); + + return nss_core_send_packet(nss_ctx, buf, if_num, H2N_BIT_FLAG_VIRTUAL_BUFFER); +} +EXPORT_SYMBOL(nss_clmap_tx_buf); + +/* + * nss_clmap_unregister() + * Un-register a clmap interface from NSS. + */ +bool nss_clmap_unregister(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx; + int status; + + nss_ctx = nss_clmap_get_ctx(); + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (!nss_clmap_verify_if_num(if_num)) { + nss_warning("%px: clmap unregister request received for invalid interface %d", nss_ctx, if_num); + return false; + } + + status = nss_core_unregister_msg_handler(nss_ctx, if_num); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Failed to unregister handler for clmap NSS I/F:%u\n", nss_ctx, if_num); + return false; + } + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + nss_core_unregister_handler(nss_ctx, if_num); + nss_clmap_stats_session_unregister(if_num); + + return true; +} +EXPORT_SYMBOL(nss_clmap_unregister); + +/* + * nss_clmap_register() + * Registers a clmap interface with the NSS. + */ +struct nss_ctx_instance *nss_clmap_register(uint32_t if_num, + uint32_t di_type, + nss_clmap_buf_callback_t data_cb, + nss_clmap_msg_callback_t notify_cb, + struct net_device *netdev, + uint32_t features) +{ + struct nss_ctx_instance *nss_ctx; + int core_status; + bool stats_status = false; + + nss_ctx = nss_clmap_get_ctx(); + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (!nss_clmap_verify_if_num(if_num)) { + nss_warning("%px: clmap register request received for invalid interface %d", nss_ctx, if_num); + goto fail; + } + + if (di_type == NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_US) { + stats_status = nss_clmap_stats_session_register(if_num, NSS_CLMAP_INTERFACE_TYPE_US, netdev); + } else { + stats_status = nss_clmap_stats_session_register(if_num, NSS_CLMAP_INTERFACE_TYPE_DS, netdev); + } + + if (!stats_status) { + nss_warning("%px: statistics registration failed for interface: %d\n", nss_ctx, if_num); + goto fail; + } + + core_status = nss_core_register_handler(nss_ctx, if_num, nss_clmap_msg_handler, (void *)netdev); + if (core_status != NSS_CORE_STATUS_SUCCESS) { + goto core_reg_fail; + } + + core_status = nss_core_register_msg_handler(nss_ctx, if_num, notify_cb); + if (core_status != NSS_CORE_STATUS_SUCCESS) { + goto msg_reg_fail; + } + + nss_core_register_subsys_dp(nss_ctx, if_num, data_cb, NULL, (void *)netdev, netdev, features); + nss_core_set_subsys_dp_type(nss_ctx, netdev, if_num, di_type); + + return nss_ctx; + +msg_reg_fail: + nss_core_unregister_handler(nss_ctx, if_num); +core_reg_fail: + nss_clmap_stats_session_unregister(if_num); + nss_warning("%px: NSS core register handler failed for if_num:%d with error :%d", nss_ctx, if_num, core_status); +fail: + return NULL; + +} +EXPORT_SYMBOL(nss_clmap_register); + +/* + * nss_clmap_ifnum_with_core_id() + * Append core ID to clmap interface num. + */ +int nss_clmap_ifnum_with_core_id(int if_num) +{ + struct nss_ctx_instance *nss_ctx = nss_clmap_get_ctx(); + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + if (!nss_is_dynamic_interface(if_num)) { + nss_warning("%px: Invalid if_num: %d, must be a dynamic interface\n", nss_ctx, if_num); + return 0; + } + return NSS_INTERFACE_NUM_APPEND_COREID(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_clmap_ifnum_with_core_id); + +/* + * nss_clmap_msg_init() + * Initialize clmap message. + */ +void nss_clmap_msg_init(struct nss_clmap_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, + nss_clmap_msg_callback_t cb, void *app_data) +{ + nss_cmn_msg_init(&ncm->cm, if_num, type, len, (void*)cb, app_data); +} +EXPORT_SYMBOL(nss_clmap_msg_init); + +/* + * nss_clmap_get_ctx() + * Return a clmap NSS context. + */ +struct nss_ctx_instance *nss_clmap_get_ctx() +{ + struct nss_ctx_instance *nss_ctx; + + nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.clmap_handler_id]; + return nss_ctx; +} +EXPORT_SYMBOL(nss_clmap_get_ctx); + +/* + * nss_clmap_init() + * Initializes clmap. Gets called from nss_init.c. + */ +void nss_clmap_init() +{ + nss_clmap_stats_dentry_create(); + sema_init(&clmap_pvt.sem, 1); + init_completion(&clmap_pvt.complete); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_clmap_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_clmap_log.c new file mode 100644 index 000000000..45cb0a734 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_clmap_log.c @@ -0,0 +1,207 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_clmap_log.c + * NSS clmap logger file. + */ + +#include "nss_core.h" + +/* + * nss_clmap_log_message_types_str + * clmap message strings + */ +static char *nss_clmap_log_message_types_str[NSS_CLMAP_MSG_TYPE_MAX] __maybe_unused = { + "Clmap sync stats", + "Clmap enable interface", + "Clmap disable interface", + "Clmap add MAC rule", + "Clmap delete MAC rule", + "Clmap flush MAC rule" +}; + +/* + * nss_clmap_log_error_types_str + * Strings for error types for clmap messages + */ +static char *nss_clmap_log_error_types_str[NSS_CLMAP_ERROR_MAX] __maybe_unused = { + "Clmap unknown error", + "Clmap interface disabled", + "Clmap interface enabled", + "Clmap invalid VLAN", + "Clmap invalid tunnel ID", + "Clmap MAC table full", + "Clmap MAC exists", + "Clmap MAC does not exist", + "Clmap MAC entry unhashed", + "Clmap MAC entry insert failed", + "Clmap MAC entry alloc failed", + "Clmap MAC entry delete failed" +}; + +/* + * nss_clmap_log_mac_msg() + * Log NSS clmap MAC rule message. + */ +static void nss_clmap_log_mac_msg(struct nss_clmap_mac_msg *npvcm) +{ + nss_trace("%px: NSS clmap MAC message \n" + "Clmap Mac Addr: %x : %x : %x" + "Clmap Flags: %u\n" + "Clmap VLAN ID: %u\n" + "Clmap Next-hop Interface Number: %d\n", + npvcm, + npvcm->mac_addr[0], npvcm->mac_addr[1], + npvcm->mac_addr[2], npvcm->flags, + npvcm->vlan_id, npvcm->nexthop_ifnum); +} + +/* + * nss_clmap_log_interface_enable_msg() + * Log NSS clmap rule enable message. + */ +static void nss_clmap_log_interface_enable_msg(struct nss_clmap_msg *npvm) +{ + nss_trace("%px: NSS clmap interface state message: Enable \n", npvm); +} + +/* + * nss_clmap_log_interface_disable_msg() + * Log NSS clmap rule disable message. + */ +static void nss_clmap_log_interface_disable_msg(struct nss_clmap_msg *npvm) +{ + nss_trace("%px: NSS clmap interface state message: Disable \n", npvm); +} + +/* + * nss_clmap_log_mac_add_msg() + * Log NSS clmap mac rule add message. + */ +static void nss_clmap_log_mac_add_msg(struct nss_clmap_msg *npvm) +{ + struct nss_clmap_mac_msg *npvcm __maybe_unused = &npvm->msg.mac_add; + nss_clmap_log_mac_msg(npvcm); +} + +/* + * nss_clmap_log_mac_del_msg() + * Log NSS clmap mac rule del message. + */ +static void nss_clmap_log_mac_del_msg(struct nss_clmap_msg *npvm) +{ + struct nss_clmap_mac_msg *npvcm __maybe_unused = &npvm->msg.mac_del; + nss_clmap_log_mac_msg(npvcm); +} + +/* + * nss_clmap_log_mac_flush_msg() + * Log NSS clmap mac rule flush message. + */ +static void nss_clmap_log_mac_flush_msg(struct nss_clmap_msg *npvm) +{ + struct nss_clmap_flush_mac_msg *npvcm __maybe_unused = &npvm->msg.mac_flush; + nss_trace("%px: NSS clmap MAC flush message \n" + "Clmap Next-hop Interface Number: %d\n", + npvcm, npvcm->nexthop_ifnum); +} + +/* + * nss_clmap_log_verbose() + * Log message contents. + */ +static void nss_clmap_log_verbose(struct nss_clmap_msg *npvm) +{ + switch (npvm->cm.type) { + case NSS_CLMAP_MSG_TYPE_INTERFACE_ENABLE: + nss_clmap_log_interface_enable_msg(npvm); + break; + + case NSS_CLMAP_MSG_TYPE_INTERFACE_DISABLE: + nss_clmap_log_interface_disable_msg(npvm); + break; + + case NSS_CLMAP_MSG_TYPE_MAC_ADD: + nss_clmap_log_mac_add_msg(npvm); + break; + + case NSS_CLMAP_MSG_TYPE_MAC_DEL: + nss_clmap_log_mac_del_msg(npvm); + break; + + case NSS_CLMAP_MSG_TYPE_MAC_FLUSH: + nss_clmap_log_mac_flush_msg(npvm); + break; + + case NSS_CLMAP_MSG_TYPE_SYNC_STATS: + break; + + default: + nss_trace("%px: Invalid message type\n", npvm); + break; + } +} + +/* + * nss_clmap_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_clmap_log_tx_msg(struct nss_clmap_msg *npvm) +{ + if (npvm->cm.type >= NSS_CLMAP_MSG_TYPE_MAX) { + nss_warning("%px: Invalid message type\n", npvm); + return; + } + + nss_info("%px: type[%d]:%s\n", npvm, npvm->cm.type, nss_clmap_log_message_types_str[npvm->cm.type]); + nss_clmap_log_verbose(npvm); +} + +/* + * nss_clmap_log_rx_msg() + * Log messages received from FW. + */ +void nss_clmap_log_rx_msg(struct nss_clmap_msg *npvm) +{ + if (npvm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", npvm); + return; + } + + if (npvm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (npvm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", npvm, npvm->cm.type, + nss_clmap_log_message_types_str[npvm->cm.type], + npvm->cm.response, nss_cmn_response_str[npvm->cm.response]); + goto verbose; + } + + if (npvm->cm.error >= NSS_CLMAP_ERROR_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + npvm, npvm->cm.type, nss_clmap_log_message_types_str[npvm->cm.type], + npvm->cm.response, nss_cmn_response_str[npvm->cm.response], + npvm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + npvm, npvm->cm.type, nss_clmap_log_message_types_str[npvm->cm.type], + npvm->cm.response, nss_cmn_response_str[npvm->cm.response], + npvm->cm.error, nss_clmap_log_error_types_str[npvm->cm.error]); + +verbose: + nss_clmap_log_verbose(npvm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_clmap_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_clmap_log.h new file mode 100644 index 000000000..6d193d315 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_clmap_log.h @@ -0,0 +1,37 @@ +/* + ****************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_CLMAP_LOG_H__ +#define __NSS_CLMAP_LOG_H__ + +/* + * nss_clmap_log.h + * NSS clmap Log Header File. + */ + +/* + * nss_clmap_log_tx_msg + * Logs a clmap message that is sent to the NSS firmware. + */ +void nss_clmap_log_tx_msg(struct nss_clmap_msg *ncm); + +/* + * nss_clmap_log_rx_msg + * Logs a clmap message that is received from the NSS firmware. + */ +void nss_clmap_log_rx_msg(struct nss_clmap_msg *ncm); + +#endif /* __NSS_CLMAP_LOG_H__ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_clmap_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_clmap_stats.c new file mode 100644 index 000000000..717e697f0 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_clmap_stats.c @@ -0,0 +1,274 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_clmap_stats.h" + +DEFINE_SPINLOCK(nss_clmap_stats_lock); + +struct nss_clmap_stats *stats_db[NSS_CLMAP_MAX_DEBUG_INTERFACES] = {NULL}; + +/* + * nss_clmap_interface_type_str + * Clmap interface type string. + */ +static char *nss_clmap_interface_type_str[NSS_CLMAP_INTERFACE_TYPE_MAX] = { + "Upstream", + "Downstream" +}; + +/* + * nss_clmap_stats_str + * Clmap statistics strings for nss tunnel stats + */ +static char *nss_clmap_stats_str[NSS_CLMAP_INTERFACE_STATS_MAX] = { + "rx_pkts", + "rx_bytes", + "tx_pkts", + "tx_bytes", + "rx_queue_0_dropped", + "rx_queue_1_dropped", + "rx_queue_2_dropped", + "rx_queue_3_dropped", + "MAC DB look up failed", + "Invalid packet count", + "Headroom drop", + "Next node queue full drop", + "Pbuf alloc failed drop", + "Linear failed drop", + "Shared packet count", + "Ethernet frame error", + "Macdb create requests count", + "Macdb create failures MAC exists count", + "Macdb create failures MAC table full count", + "Macdb destroy requests count", + "Macdb destroy failures MAC not found count", + "Macdb destroy failures MAC unhashed count", + "Macdb flush requests count" +}; + +/* + * nss_clmap_stats_session_register + * Register debug statistic for clmap session. + */ +bool nss_clmap_stats_session_register(uint32_t if_num, uint32_t if_type, struct net_device *netdev) +{ + uint32_t i; + bool stats_status = false; + + if (!netdev) { + nss_warning("Could not allocate statistics memory as the net device is NULL!\n"); + return stats_status; + } + + spin_lock_bh(&nss_clmap_stats_lock); + for (i = 0; i < NSS_CLMAP_MAX_DEBUG_INTERFACES; i++) { + if (!stats_db[i]) { + stats_db[i] = (struct nss_clmap_stats *)kzalloc(sizeof(struct nss_clmap_stats), GFP_KERNEL); + if (!stats_db[i]) { + nss_warning("%px: could not allocate memory for statistics database for interface id: %d\n", netdev, if_num); + break; + } + stats_db[i]->valid = true; + stats_db[i]->nss_if_num = if_num; + stats_db[i]->nss_if_type = if_type; + stats_db[i]->if_index = netdev->ifindex; + stats_status = true; + break; + } + } + spin_unlock_bh(&nss_clmap_stats_lock); + return stats_status; +} + +/* + * nss_clmap_stats_session_unregister + * Unregister debug statistic for clmap session. + */ +void nss_clmap_stats_session_unregister(uint32_t if_num) +{ + uint32_t i; + + spin_lock_bh(&nss_clmap_stats_lock); + for (i = 0; i < NSS_CLMAP_MAX_DEBUG_INTERFACES; i++) { + if (stats_db[i] && (stats_db[i]->nss_if_num == if_num)) { + kfree(stats_db[i]); + stats_db[i] = NULL; + break; + } + } + spin_unlock_bh(&nss_clmap_stats_lock); +} + +/* + * nss_clmap_get_debug_stats() + * Get clmap debug statistics. + */ +static int nss_clmap_get_debug_stats(struct nss_clmap_stats *stats) +{ + uint32_t i; + int interface_cnt = 0; + + spin_lock_bh(&nss_clmap_stats_lock); + for (i = 0; i < NSS_CLMAP_MAX_DEBUG_INTERFACES; i++) { + if (stats_db[i]) { + memcpy(stats, stats_db[i], sizeof(struct nss_clmap_stats)); + stats++; + interface_cnt++; + } + } + spin_unlock_bh(&nss_clmap_stats_lock); + + return interface_cnt; +} + +/* + * nss_clmap_stats_read() + * Read clmap statistics + */ +static ssize_t nss_clmap_stats_read(struct file *fp, char __user *ubuf, + size_t sz, loff_t *ppos) +{ + uint32_t max_output_lines = 2 + (NSS_CLMAP_INTERFACE_STATS_MAX * NSS_CLMAP_MAX_DEBUG_INTERFACES + 2) + 2; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + struct net_device *dev; + uint32_t id, i; + struct nss_clmap_stats *clmap_stats = NULL; + int interface_cnt; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(!lbuf)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + /* + * Allocate statistics memory only for all interfaces. + */ + clmap_stats = kzalloc((NSS_CLMAP_MAX_DEBUG_INTERFACES * sizeof(struct nss_clmap_stats)), GFP_KERNEL); + if (unlikely(!clmap_stats)) { + nss_warning("Could not allocate memory for populating clmap statistics\n"); + kfree(lbuf); + return 0; + } + + /* + * Get clmap statistics. + */ + interface_cnt = nss_clmap_get_debug_stats(clmap_stats); + size_wr = scnprintf(lbuf + size_wr, size_al - size_wr, + "\n clmap Interface statistics start:\n\n"); + for (id = 0; id < interface_cnt; id++) { + struct nss_clmap_stats *clmsp = clmap_stats + id; + + if (unlikely(!clmsp->valid)) { + continue; + } + + dev = dev_get_by_index(&init_net, clmsp->if_index); + if (unlikely(!dev)) { + nss_warning("No netdev available for nss interface id:%d\n", clmsp->nss_if_num); + continue; + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d, interface type=%s, netdevice=%s\n", id, + clmsp->nss_if_num, nss_clmap_interface_type_str[clmsp->nss_if_type], dev->name); + dev_put(dev); + + for (i = 0; i < NSS_CLMAP_INTERFACE_STATS_MAX; i++) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "\t%s = %llu\n", nss_clmap_stats_str[i], + clmsp->stats[i]); + } + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n"); + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "\n clmap Interface statistics end\n"); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr); + + kfree(clmap_stats); + kfree(lbuf); + return bytes_read; +} + +/* + * nss_clmap_stats_sync() + * Sync function for clmap statistics + */ +void nss_clmap_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_clmap_stats_msg *stats_msg, uint32_t if_num) +{ + uint32_t i; + struct nss_clmap_stats *s = NULL; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + spin_lock_bh(&nss_clmap_stats_lock); + for (i = 0; i < NSS_CLMAP_MAX_DEBUG_INTERFACES; i++) { + if (stats_db[i] && (stats_db[i]->nss_if_num == if_num)) { + s = stats_db[i]; + break; + } + } + + if (!s) { + spin_unlock_bh(&nss_clmap_stats_lock); + nss_warning("%px: Interface not found: %u", nss_ctx, if_num); + return; + } + + s->stats[NSS_CLMAP_INTERFACE_STATS_RX_PKTS] += stats_msg->node_stats.rx_packets; + s->stats[NSS_CLMAP_INTERFACE_STATS_RX_BYTES] += stats_msg->node_stats.rx_bytes; + s->stats[NSS_CLMAP_INTERFACE_STATS_TX_PKTS] += stats_msg->node_stats.tx_packets; + s->stats[NSS_CLMAP_INTERFACE_STATS_TX_BYTES] += stats_msg->node_stats.tx_bytes; + + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + s->stats[NSS_CLMAP_INTERFACE_STATS_RX_QUEUE_0_DROPPED + i] += stats_msg->node_stats.rx_dropped[i]; + } + + s->stats[NSS_CLMAP_INTERFACE_STATS_DROPPED_MACDB_LOOKUP_FAILED] += stats_msg->dropped_macdb_lookup_failed; + s->stats[NSS_CLMAP_INTERFACE_STATS_DROPPED_INVALID_PACKET_SIZE] += stats_msg->dropped_invalid_packet_size; + s->stats[NSS_CLMAP_INTERFACE_STATS_DROPPED_LOW_HEADROOM] += stats_msg->dropped_low_hroom; + s->stats[NSS_CLMAP_INTERFACE_STATS_DROPPED_NEXT_NODE_QUEUE_FULL] += stats_msg->dropped_next_node_queue_full; + s->stats[NSS_CLMAP_INTERFACE_STATS_DROPPED_PBUF_ALLOC_FAILED] += stats_msg->dropped_pbuf_alloc_failed; + s->stats[NSS_CLMAP_INTERFACE_STATS_DROPPED_LINEAR_FAILED] += stats_msg->dropped_linear_failed; + s->stats[NSS_CLMAP_INTERFACE_STATS_SHARED_PACKET_CNT] += stats_msg->shared_packet_count; + s->stats[NSS_CLMAP_INTERFACE_STATS_ETHERNET_FRAME_ERROR] += stats_msg->ethernet_frame_error; + s->stats[NSS_CLMAP_INTERFACE_STATS_MACDB_CREATE_REQUESTS_CNT] += stats_msg->macdb_create_requests; + s->stats[NSS_CLMAP_INTERFACE_STATS_MACDB_CREATE_MAC_EXISTS_CNT] += stats_msg->macdb_create_mac_exists; + s->stats[NSS_CLMAP_INTERFACE_STATS_MACDB_CREATE_MAC_TABLE_FULL_CNT] += stats_msg->macdb_create_table_full; + s->stats[NSS_CLMAP_INTERFACE_STATS_MACDB_DESTROY_REQUESTS_CNT] += stats_msg->macdb_destroy_requests; + s->stats[NSS_CLMAP_INTERFACE_STATS_MACDB_DESTROY_MAC_NOT_FOUND_CNT] += stats_msg->macdb_destroy_mac_notfound; + s->stats[NSS_CLMAP_INTERFACE_STATS_MACDB_DESTROY_MAC_UNHASHED_CNT] += stats_msg->macdb_destroy_mac_unhashed; + s->stats[NSS_CLMAP_INTERFACE_STATS_MACDB_FLUSH_REQUESTS_CNT] += stats_msg->macdb_flush_requests; + spin_unlock_bh(&nss_clmap_stats_lock); +} + +/* + * nss_clmap_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(clmap) + +/* + * nss_clmap_stats_dentry_create() + * Create client map statistics debug entry. + */ +void nss_clmap_stats_dentry_create(void) +{ + nss_stats_create_dentry("clmap", &nss_clmap_stats_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_clmap_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_clmap_stats.h new file mode 100644 index 000000000..4a1e1a33c --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_clmap_stats.h @@ -0,0 +1,80 @@ +/* + ****************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_CLMAP_STATS_H +#define __NSS_CLMAP_STATS_H + +#define NSS_CLMAP_MAX_DEBUG_INTERFACES 2 * NSS_CLMAP_MAX_INTERFACES + +/* + * Clmap NSS interface type. + */ +enum nss_clmap_interface_type { + NSS_CLMAP_INTERFACE_TYPE_US, + NSS_CLMAP_INTERFACE_TYPE_DS, + NSS_CLMAP_INTERFACE_TYPE_MAX +}; + +/* + * Clmap statistic counters. + */ +enum nss_clmap_stats_type { + NSS_CLMAP_INTERFACE_STATS_RX_PKTS, + NSS_CLMAP_INTERFACE_STATS_RX_BYTES, + NSS_CLMAP_INTERFACE_STATS_TX_PKTS, + NSS_CLMAP_INTERFACE_STATS_TX_BYTES, + NSS_CLMAP_INTERFACE_STATS_RX_QUEUE_0_DROPPED, + NSS_CLMAP_INTERFACE_STATS_RX_QUEUE_1_DROPPED, + NSS_CLMAP_INTERFACE_STATS_RX_QUEUE_2_DROPPED, + NSS_CLMAP_INTERFACE_STATS_RX_QUEUE_3_DROPPED, + NSS_CLMAP_INTERFACE_STATS_DROPPED_MACDB_LOOKUP_FAILED, + NSS_CLMAP_INTERFACE_STATS_DROPPED_INVALID_PACKET_SIZE, + NSS_CLMAP_INTERFACE_STATS_DROPPED_LOW_HEADROOM, + NSS_CLMAP_INTERFACE_STATS_DROPPED_NEXT_NODE_QUEUE_FULL, + NSS_CLMAP_INTERFACE_STATS_DROPPED_PBUF_ALLOC_FAILED, + NSS_CLMAP_INTERFACE_STATS_DROPPED_LINEAR_FAILED, + NSS_CLMAP_INTERFACE_STATS_SHARED_PACKET_CNT, + NSS_CLMAP_INTERFACE_STATS_ETHERNET_FRAME_ERROR, + NSS_CLMAP_INTERFACE_STATS_MACDB_CREATE_REQUESTS_CNT, + NSS_CLMAP_INTERFACE_STATS_MACDB_CREATE_MAC_EXISTS_CNT, + NSS_CLMAP_INTERFACE_STATS_MACDB_CREATE_MAC_TABLE_FULL_CNT, + NSS_CLMAP_INTERFACE_STATS_MACDB_DESTROY_REQUESTS_CNT, + NSS_CLMAP_INTERFACE_STATS_MACDB_DESTROY_MAC_NOT_FOUND_CNT, + NSS_CLMAP_INTERFACE_STATS_MACDB_DESTROY_MAC_UNHASHED_CNT, + NSS_CLMAP_INTERFACE_STATS_MACDB_FLUSH_REQUESTS_CNT, + NSS_CLMAP_INTERFACE_STATS_MAX, +}; + +/* + * Clmap session debug statistics. + */ +struct nss_clmap_stats { + uint64_t stats[NSS_CLMAP_INTERFACE_STATS_MAX]; + int32_t if_index; + uint32_t nss_if_num; /* NSS interface number. */ + enum nss_clmap_interface_type nss_if_type; /* NSS interface type. */ + bool valid; +}; + +/* + * Clmap statistics APIs. + */ +extern bool nss_clmap_stats_session_register(uint32_t if_num, enum nss_clmap_interface_type if_type, struct net_device *netdev); +extern void nss_clmap_stats_session_unregister(uint32_t if_num); +extern void nss_clmap_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_clmap_stats_msg *stats_msg, uint32_t if_num); +extern void nss_clmap_stats_dentry_create(void); + +#endif /* __NSS_CLMAP_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_cmn.c b/feeds/ipq807x/qca-nss-drv/src/nss_cmn.c new file mode 100644 index 000000000..920a0e56f --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_cmn.c @@ -0,0 +1,346 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_cmn.c + * NSS generic APIs + */ + +#if (NSS_DT_SUPPORT == 1) +#include +#endif + +#include "nss_tx_rx_common.h" + +/* + * nss_cmn_response_str + * Common response structure string + */ +int8_t *nss_cmn_response_str[NSS_CMN_RESPONSE_LAST] = { + "Message Acknowledge without errors", + "Common message version not supported", + "Unknown Interface", + "Length Error", + "Message Error", + "FW Notification Message", +}; + +/* + * nss_cmn_msg_init() + * Initialize the common message of an ASYNC message. + */ +void nss_cmn_msg_init(struct nss_cmn_msg *ncm, uint32_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data) +{ + ncm->interface = if_num; + ncm->version = NSS_HLOS_MESSAGE_VERSION; + ncm->type = type; + ncm->len = len; + ncm->cb = (nss_ptr_t)cb; + ncm->app_data = (nss_ptr_t)app_data; +} +EXPORT_SYMBOL(nss_cmn_msg_init); + +/* + * nss_cmn_msg_sync_init() + * Initialize the common message of a SYNC message. + */ +void nss_cmn_msg_sync_init(struct nss_cmn_msg *ncm, uint32_t if_num, uint32_t type, uint32_t len) +{ + nss_cmn_msg_init(ncm, if_num, type, len, NULL, NULL); +} +EXPORT_SYMBOL(nss_cmn_msg_sync_init); + +/* + * nss_cmn_get_interface_number() + * Return the interface number of the NSS net_device. + * + * Returns -1 on failure or the interface number of dev is an NSS net_device. + */ +int32_t nss_cmn_get_interface_number(struct nss_ctx_instance *nss_ctx, struct net_device *dev) +{ + int i; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) { + nss_warning("%px: Interface number could not be found as core not ready\n", nss_ctx); + return -1; + } + + nss_assert(dev != 0); + + /* + * Check physical interface table + */ + for (i = 0; i < NSS_MAX_NET_INTERFACES; i++) { + if (dev == nss_ctx->subsys_dp_register[i].ndev) { + return i; + } + } + + nss_warning("%px: Interface number could not be found as interface has not registered yet\n", nss_ctx); + return -1; +} +EXPORT_SYMBOL(nss_cmn_get_interface_number); + +/* + * nss_cmn_append_core_id() + * Return the NSS interface number with core ID. + */ +int nss_cmn_append_core_id(struct nss_ctx_instance *nss_ctx, int if_num) +{ + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + return NSS_INTERFACE_NUM_APPEND_COREID(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_cmn_append_core_id); + +/* + * nss_cmn_get_interface_dev() + * Return the net_device for NSS interface id. + * + * Returns NULL on failure or the net_device for NSS interface id. + */ +struct net_device *nss_cmn_get_interface_dev(struct nss_ctx_instance *ctx, uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)ctx; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) { + nss_warning("%px: Interface device could not be found as core not ready\n", nss_ctx); + return NULL; + } + + if (unlikely(if_num >= NSS_MAX_NET_INTERFACES)) { + return NULL; + } + + return nss_ctx->subsys_dp_register[if_num].ndev; +} +EXPORT_SYMBOL(nss_cmn_get_interface_dev); + +/* + * nss_cmn_get_interface_number_by_dev_and_type() + * Return the NSS interface id for the net_device. + * + * Returns < 0 on failure or the NSS interface id for the given device and type. + */ +int32_t nss_cmn_get_interface_number_by_dev_and_type(struct net_device *dev, uint32_t type) +{ + int i, core; + struct nss_subsystem_dataplane_register *nsdr; + + nss_assert(dev != 0); + for (core = 0; core < nss_top_main.num_nss; core++) { + for (i = 0; i < NSS_MAX_NET_INTERFACES; i++) { + nsdr = &nss_top_main.nss[core].subsys_dp_register[i]; + if (dev == nsdr->ndev && type == nsdr->type) { + return i; + } + } + } + + nss_warning("Interface number could not be found for %px (%s) as interface has not registered yet\n", dev, dev->name); + return -1; +} +EXPORT_SYMBOL(nss_cmn_get_interface_number_by_dev_and_type); + +/* + * nss_cmn_get_interface_number_by_dev() + * Return the NSS interface id for the net_device. + * + * Returns < 0 on failure or the NSS interface id for the given device. + */ +int32_t nss_cmn_get_interface_number_by_dev(struct net_device *dev) +{ + return nss_cmn_get_interface_number_by_dev_and_type(dev, 0); +} +EXPORT_SYMBOL(nss_cmn_get_interface_number_by_dev); + +/* + * nss_cmn_get_state() + * return the NSS initialization state + */ +nss_state_t nss_cmn_get_state(struct nss_ctx_instance *ctx) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)ctx; + nss_state_t state = NSS_STATE_UNINITIALIZED; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + spin_lock_bh(&nss_top_main.lock); + if (nss_ctx->state == NSS_CORE_STATE_INITIALIZED) { + state = NSS_STATE_INITIALIZED; + } + spin_unlock_bh(&nss_top_main.lock); + + return state; +} +EXPORT_SYMBOL(nss_cmn_get_state); + +/* + * nss_cmn_interface_is_redirect() + * Return true if the interface is a redirect interface. + */ +bool nss_cmn_interface_is_redirect(struct nss_ctx_instance *nss_ctx, int32_t interface_num) +{ + enum nss_dynamic_interface_type type = nss_dynamic_interface_get_type(nss_ctx, interface_num); + + return type == NSS_DYNAMIC_INTERFACE_TYPE_WIFI + || type == NSS_DYNAMIC_INTERFACE_TYPE_GENERIC_REDIR_N2H + || type == NSS_DYNAMIC_INTERFACE_TYPE_GENERIC_REDIR_H2N + || type == NSS_DYNAMIC_INTERFACE_TYPE_VIRTIF_DEPRECATED; +} +EXPORT_SYMBOL(nss_cmn_interface_is_redirect); + +/* + * nss_cmn_rx_dropped_sum() + * Sum rx_dropped count. + */ +uint32_t nss_cmn_rx_dropped_sum(struct nss_cmn_node_stats *node_stats) +{ + uint32_t sum = 0; + int i; + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + sum += node_stats->rx_dropped[i]; + } + return sum; +} +EXPORT_SYMBOL(nss_cmn_rx_dropped_sum); + +/* + * nss_cmn_register_queue_decongestion() + * Register for queue decongestion event + */ +nss_cb_register_status_t nss_cmn_register_queue_decongestion(struct nss_ctx_instance *nss_ctx, nss_cmn_queue_decongestion_callback_t event_callback, void *app_ctx) +{ + uint32_t i; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + spin_lock_bh(&nss_ctx->decongest_cb_lock); + + /* + * Find vacant location in callback table + */ + for (i = 0; i< NSS_MAX_CLIENTS; i++) { + if (nss_ctx->queue_decongestion_callback[i] == NULL) { + nss_ctx->queue_decongestion_callback[i] = event_callback; + nss_ctx->queue_decongestion_ctx[i] = app_ctx; + spin_unlock_bh(&nss_ctx->decongest_cb_lock); + return NSS_CB_REGISTER_SUCCESS; + } + } + + spin_unlock_bh(&nss_ctx->decongest_cb_lock); + return NSS_CB_REGISTER_FAILED; +} +EXPORT_SYMBOL(nss_cmn_register_queue_decongestion); + +/* + * nss_cmn_unregister_queue_decongestion() + * Unregister for queue decongestion event + */ +nss_cb_unregister_status_t nss_cmn_unregister_queue_decongestion(struct nss_ctx_instance *nss_ctx, nss_cmn_queue_decongestion_callback_t event_callback) +{ + uint32_t i; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + spin_lock_bh(&nss_ctx->decongest_cb_lock); + + /* + * Find actual location in callback table + */ + for (i = 0; i< NSS_MAX_CLIENTS; i++) { + if (nss_ctx->queue_decongestion_callback[i] == event_callback) { + nss_ctx->queue_decongestion_callback[i] = NULL; + nss_ctx->queue_decongestion_ctx[i] = NULL; + spin_unlock_bh(&nss_ctx->decongest_cb_lock); + return NSS_CB_UNREGISTER_SUCCESS; + } + } + + spin_unlock_bh(&nss_ctx->decongest_cb_lock); + return NSS_CB_UNREGISTER_FAILED; +} +EXPORT_SYMBOL(nss_cmn_unregister_queue_decongestion); + +/* + * nss_cmn_register_service_code() + * Register for service code event + */ +nss_cb_register_status_t nss_cmn_register_service_code(struct nss_ctx_instance *nss_ctx, nss_cmn_service_code_callback_t cb, uint8_t service_code, void *app_data) +{ + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (nss_ctx->service_code_callback[service_code]) { + /* + * We already have a callback registered for this service code. + */ + nss_warning("%px: a callback is registered already for this service code %d\n", nss_ctx, service_code); + + return NSS_CB_REGISTER_FAILED; + } + + nss_ctx->service_code_callback[service_code] = cb; + nss_ctx->service_code_ctx[service_code] = app_data; + return NSS_CB_REGISTER_SUCCESS; +} +EXPORT_SYMBOL(nss_cmn_register_service_code); + +/* + * nss_cmn_unregister_service_code() + * Unregister for service code event + */ +nss_cb_unregister_status_t nss_cmn_unregister_service_code(struct nss_ctx_instance *nss_ctx, nss_cmn_service_code_callback_t cb, uint8_t service_code) +{ + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (!nss_ctx->service_code_callback[service_code]) { + /* + * No callback was registered for this service code. + */ + nss_warning("%px: no callback is registered for this service code %d\n", nss_ctx, service_code); + return NSS_CB_UNREGISTER_FAILED; + } + + nss_ctx->service_code_callback[service_code] = NULL; + nss_ctx->service_code_ctx[service_code] = NULL; + return NSS_CB_UNREGISTER_SUCCESS; +} +EXPORT_SYMBOL(nss_cmn_unregister_service_code); + +/* + * nss_cmn_get_nss_enabled() + * Check if NSS mode is supported on platform + * + * This API checks the device tree parameter to decide on whether + * NSS mode is enabled. On older kernels this will always return true + */ +bool nss_cmn_get_nss_enabled(void) +{ +#if (NSS_DT_SUPPORT == 1) + struct device_node *cmn = NULL; + + /* + * Get reference to NSS common device node + */ + cmn = of_find_node_by_name(NULL, "nss-common"); + if (!cmn) { + nss_info_always("nss is not enabled on this platform\n"); + return false; + } +#endif + return true; +} +EXPORT_SYMBOL(nss_cmn_get_nss_enabled); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_core.c b/feeds/ipq807x/qca-nss-drv/src/nss_core.c new file mode 100644 index 000000000..758004c17 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_core.c @@ -0,0 +1,3253 @@ +/* + ************************************************************************** + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_core.c + * NSS driver core APIs source file. + */ + +#include "nss_core.h" +#include +#include +#include +#include +#include +#ifdef CONFIG_BRIDGE_NETFILTER +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(5, 0, 0)) +#include +#else +#include +#endif +#endif +#include +#include "nss_tx_rx_common.h" +#include "nss_data_plane.h" + +#define NSS_CORE_JUMBO_LINEAR_BUF_SIZE 128 + +#if (NSS_SKB_REUSE_SUPPORT == 1) +/* + * We have validated the skb recycling code within the NSS for the + * following kernel versions. Before enabling the driver in new kernels, + * the skb recycle code must be checked against Linux skb handling. + * + * Tested on: 3.4, 3.10, 3.14, 3.18, 4.4 and 5.4 + */ +#if (!( \ +(((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0)))) || \ +(((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0)))) || \ +(((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0)))) || \ +(((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)))) || \ +(((LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)))) || \ +(((LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)))))) +#error "Check skb recycle code in this file to match Linux version" +#endif + +static atomic_t max_reuse = ATOMIC_INIT(PAGE_SIZE); + +#endif /* NSS_SKB_REUSE_SUPPORT */ + +static int max_ipv4_conn = NSS_DEFAULT_NUM_CONN; +module_param(max_ipv4_conn, int, S_IRUGO); +MODULE_PARM_DESC(max_ipv4_conn, "Max number of IPv4 connections"); + +static int max_ipv6_conn = NSS_DEFAULT_NUM_CONN; +module_param(max_ipv6_conn, int, S_IRUGO); +MODULE_PARM_DESC(max_ipv6_conn, "Max number of IPv6 connections"); + +bool pn_mq_en = false; +module_param(pn_mq_en, bool, S_IRUGO); +MODULE_PARM_DESC(pn_mq_en, "Enable pnode ingress QoS"); + +uint16_t pn_qlimits[NSS_MAX_NUM_PRI] = {[0 ... NSS_MAX_NUM_PRI - 1] = NSS_DEFAULT_QUEUE_LIMIT}; +module_param_array(pn_qlimits, short, NULL, 0); +MODULE_PARM_DESC(pn_qlimits, "Queue limit per queue"); + +/* + * Atomic variables to control jumbo_mru & paged_mode + */ +static atomic_t jumbo_mru; +static atomic_t paged_mode; + +/* + * nss_core_update_max_ipv4_conn() + * Update the maximum number of configured IPv4 connections + */ +void nss_core_update_max_ipv4_conn(int conn) +{ + max_ipv4_conn = conn; +} + +/* + * nss_core_update_max_ipv6_conn() + * Update the maximum number of configured IPv6 connections + */ +void nss_core_update_max_ipv6_conn(int conn) +{ + max_ipv6_conn = conn; +} + +#if (NSS_SKB_REUSE_SUPPORT == 1) +/* + * nss_core_set_max_reuse() + * Set the max_reuse to the specified value + */ +void nss_core_set_max_reuse(int max) +{ + atomic_set(&max_reuse, max); +} + +/* + * nss_core_get_max_reuse() + * Does an atomic read of max_reuse + */ +int nss_core_get_max_reuse(void) +{ + return atomic_read(&max_reuse); +} + +/* + * nss_core_get_min_reuse() + * Return min reuse size + */ +uint32_t nss_core_get_min_reuse(struct nss_ctx_instance *nss_ctx) +{ + NSS_VERIFY_CTX_MAGIC(nss_ctx); + return nss_ctx->max_buf_size; +} +#endif /* NSS_SKB_REUSE_SUPPORT */ + +/* + * nss_core_set_jumbo_mru() + * Set the jumbo_mru to the specified value + */ +void nss_core_set_jumbo_mru(int jumbo) +{ + atomic_set(&jumbo_mru, jumbo); + +#if (NSS_SKB_REUSE_SUPPORT == 1) + if (jumbo > nss_core_get_max_reuse()) + nss_core_set_max_reuse(ALIGN(jumbo * 2, PAGE_SIZE)); +#endif +} + +/* + * nss_core_get_jumbo_mru() + * Does an atomic read of jumbo_mru + */ +int nss_core_get_jumbo_mru(void) +{ + return atomic_read(&jumbo_mru); +} + +/* + * nss_core_set_paged_mode() + * Set the paged_mode to the specified value + */ +void nss_core_set_paged_mode(int mode) +{ + atomic_set(&paged_mode, mode); +} + +/* + * nss_core_get_paged_mode() + * Does an atomic read of paged_mode + */ +int nss_core_get_paged_mode(void) +{ + return atomic_read(&paged_mode); +} + +/* + * nss_core_register_msg_handler() + * Register a msg callback per interface number. One per interface. + */ +uint32_t nss_core_register_msg_handler(struct nss_ctx_instance *nss_ctx, uint32_t interface, nss_if_rx_msg_callback_t msg_cb) +{ + nss_assert(msg_cb != NULL); + + /* + * Validate interface id + */ + if (interface >= NSS_MAX_NET_INTERFACES) { + nss_warning("Error - Interface %d not Supported\n", interface); + return NSS_CORE_STATUS_FAILURE; + } + + /* + * Check if already registered + */ + if (nss_ctx->nss_rx_interface_handlers[interface].msg_cb) { + nss_warning("Error - Duplicate Interface CB Registered for interface %d\n", interface); + return NSS_CORE_STATUS_FAILURE; + } + + nss_ctx->nss_rx_interface_handlers[interface].msg_cb = msg_cb; + + return NSS_CORE_STATUS_SUCCESS; +} + +/* + * nss_core_unregister_msg_handler() + * Unregister a msg callback per interface number. + */ +uint32_t nss_core_unregister_msg_handler(struct nss_ctx_instance *nss_ctx, uint32_t interface) +{ + /* + * Validate interface id + */ + if (interface >= NSS_MAX_NET_INTERFACES) { + nss_warning("Error - Interface %d not Supported\n", interface); + return NSS_CORE_STATUS_FAILURE; + } + + nss_ctx->nss_rx_interface_handlers[interface].msg_cb = NULL; + + return NSS_CORE_STATUS_SUCCESS; +} + +/* + * nss_core_register_handler() + +-- Register a callback per interface code. Only one per interface. + */ +uint32_t nss_core_register_handler(struct nss_ctx_instance *nss_ctx, uint32_t interface, nss_core_rx_callback_t cb, void *app_data) +{ + nss_assert(cb != NULL); + + /* + * Validate interface id + */ + if (interface >= NSS_MAX_NET_INTERFACES) { + nss_warning("Error - Interface %d not Supported\n", interface); + return NSS_CORE_STATUS_FAILURE; + } + + /* + * Check if already registered + */ + if (nss_ctx->nss_rx_interface_handlers[interface].cb != NULL) { + nss_warning("Error - Duplicate Interface CB Registered for interface %d\n", interface); + return NSS_CORE_STATUS_FAILURE; + } + + nss_ctx->nss_rx_interface_handlers[interface].cb = cb; + nss_ctx->nss_rx_interface_handlers[interface].app_data = app_data; + + return NSS_CORE_STATUS_SUCCESS; +} + +/* + * nss_core_unregister_handler() + * Unegister a callback per interface code. + */ +uint32_t nss_core_unregister_handler(struct nss_ctx_instance *nss_ctx, uint32_t interface) +{ + /* + * Validate interface id + */ + if (interface >= NSS_MAX_NET_INTERFACES) { + nss_warning("Error - Interface %d not Supported\n", interface); + return NSS_CORE_STATUS_FAILURE; + } + + nss_ctx->nss_rx_interface_handlers[interface].cb = NULL; + nss_ctx->nss_rx_interface_handlers[interface].app_data = NULL; + + return NSS_CORE_STATUS_SUCCESS; +} + +/* + * nss_core_set_subsys_dp_type() + * Set the type for the datapath subsystem + */ +void nss_core_set_subsys_dp_type(struct nss_ctx_instance *nss_ctx, struct net_device *ndev, uint32_t if_num, uint32_t type) +{ + struct nss_subsystem_dataplane_register *reg; + + /* + * Check that interface number is in range. + */ + BUG_ON(if_num >= NSS_MAX_NET_INTERFACES); + + reg = &nss_ctx->subsys_dp_register[if_num]; + + /* + * Check if there is already a subsystem registered at this interface number. + */ + BUG_ON(reg->ndev && reg->ndev != ndev); + + reg->type = type; +} + +/* + * nss_core_register_subsys_dp() + * Registers a netdevice and associated information at a given interface. + * + * Can also be used to update an existing registry if the provided net_device + * is equal to the one already registered. Will fail if there is already + * a net_device registered to the interface not equal to the one provided, + * or if the interface number is out of range. + */ +void nss_core_register_subsys_dp(struct nss_ctx_instance *nss_ctx, uint32_t if_num, + nss_phys_if_rx_callback_t cb, + nss_phys_if_rx_ext_data_callback_t ext_cb, + void *app_data, struct net_device *ndev, + uint32_t features) +{ + struct nss_subsystem_dataplane_register *reg; + + /* + * Check that interface number is in range. + */ + BUG_ON(if_num >= NSS_MAX_NET_INTERFACES); + + reg = &nss_ctx->subsys_dp_register[if_num]; + + /* + * Check if there is already a subsystem registered at this interface number. + */ + BUG_ON(reg->ndev && reg->ndev != ndev); + + reg->cb = cb; + reg->ext_cb = ext_cb; + reg->app_data = app_data; + reg->ndev = ndev; + reg->features = features; +} + +/* + * nss_core_unregister_subsys_dp() + * Unregisters the netdevice at the given interface. + * + * Fails if the interface number is not valid. + */ +void nss_core_unregister_subsys_dp(struct nss_ctx_instance *nss_ctx, uint32_t if_num) +{ + struct nss_subsystem_dataplane_register *reg; + + /* + * Check that interface number is in range. + */ + BUG_ON(if_num >= NSS_MAX_NET_INTERFACES); + + reg = &nss_ctx->subsys_dp_register[if_num]; + + reg->cb = NULL; + reg->ext_cb = NULL; + reg->app_data = NULL; + reg->ndev = NULL; + reg->features = 0; + reg->type = 0; +} + +/* + * nss_core_handle_nss_status_pkt() + * Handle the metadata/status packet. + */ +void nss_core_handle_nss_status_pkt(struct nss_ctx_instance *nss_ctx, struct sk_buff *nbuf) +{ + struct nss_cmn_msg *ncm; + uint32_t expected_version = NSS_HLOS_MESSAGE_VERSION; + nss_core_rx_callback_t cb; + void *app_data; + uint16_t nss_if; + + if (skb_shinfo(nbuf)->nr_frags > 0) { + ncm = (struct nss_cmn_msg *)skb_frag_address(&skb_shinfo(nbuf)->frags[0]); + } else { + ncm = (struct nss_cmn_msg *)nbuf->data; + } + + /* + * Save NSS interface number in local variable + */ + nss_if = ncm->interface; + + /* + * Check for version number + */ + if (ncm->version != expected_version) { + nss_warning("%px: Message %d for interface %d received with invalid version %d, expected version %d", + nss_ctx, ncm->type, nss_if, ncm->version, expected_version); + return; + } + + /* + * Validate message size + */ + if (ncm->len > nbuf->len) { + nss_warning("%px: Message %d for interface %d received with invalid length %d, expected length %d", + nss_ctx, ncm->type, nss_if, nbuf->len, ncm->len); + return; + } + + /* + * Check for validity of interface number + */ + if (nss_if >= NSS_MAX_NET_INTERFACES) { + nss_warning("%px: Message %d received with invalid interface number %d", nss_ctx, ncm->type, nss_if); + return; + } + + cb = nss_ctx->nss_rx_interface_handlers[nss_if].cb; + app_data = nss_ctx->nss_rx_interface_handlers[nss_if].app_data; + + if (!cb) { + nss_warning("%px: Callback not registered for interface %d", nss_ctx, nss_if); + return; + } + + cb(nss_ctx, ncm, app_data); + + if (ncm->interface != nss_if) { + nss_warning("%px: Invalid NSS I/F %d expected %d", nss_ctx, ncm->interface, nss_if); + } + + return; +} + +/* + * nss_core_handle_nss_crypto_pkt() + * Handles crypto packet. + */ +static void nss_core_handle_crypto_pkt(struct nss_ctx_instance *nss_ctx, unsigned int interface_num, + struct sk_buff *nbuf, struct napi_struct *napi) +{ + struct nss_subsystem_dataplane_register *subsys_dp_reg = &nss_ctx->subsys_dp_register[interface_num]; + nss_phys_if_rx_callback_t cb; + struct net_device *ndev; + + ndev = subsys_dp_reg->ndev; + cb = subsys_dp_reg->cb; + if (likely(cb)) { + cb(ndev, nbuf, napi); + return; + } + + dev_kfree_skb_any(nbuf); + return; +} + +/* + * nss_soc_mem_info() + * Getting DDR information for NSS SoC + */ +static uint32_t nss_soc_mem_info(void) +{ + struct device_node *node; + struct device_node *snode; + int addr_cells; + int size_cells; + int n_items; + uint32_t nss_msize = 8 << 20; /* default: 8MB */ + const __be32 *ppp; + + node = of_find_node_by_name(NULL, "reserved-memory"); + if (!node) { + nss_info_always("reserved-memory not found\n"); + return nss_msize; + } + + ppp = (__be32 *)of_get_property(node, "#address-cells", NULL); + addr_cells = ppp ? be32_to_cpup(ppp) : 2; + nss_info("%px addr cells %d\n", ppp, addr_cells); + ppp = (__be32 *)of_get_property(node, "#size-cells", NULL); + size_cells = ppp ? be32_to_cpup(ppp) : 2; + nss_info("%px size cells %d\n", ppp, size_cells); + + for_each_child_of_node(node, snode) { + /* + * compare (snode->full_name, "/reserved-memory/nss@40000000") may be safer + */ + nss_info("%px snode %s fn %s\n", snode, snode->name, snode->full_name); + if (strcmp(snode->name, "nss") == 0) + break; + } + of_node_put(node); + if (!snode) { + nss_info_always("nss@node not found: needed to determine NSS reserved DDR\n"); + return nss_msize; + } + + ppp = (__be32 *)of_get_property(snode, "reg", &n_items); + if (ppp) { + n_items /= sizeof(ppp[0]); + nss_msize = be32_to_cpup(ppp + addr_cells + size_cells - 1); + nss_info_always("addr/size storage words %d %d # words %d in DTS, ddr size %x\n", + addr_cells, size_cells, n_items, nss_msize); + } + of_node_put(snode); + return nss_msize; +} + +/* + * nss_get_ddr_info() + * get DDR start address and size from device tree. + */ +static void nss_get_ddr_info(struct nss_mmu_ddr_info *mmu, char *name) +{ + __be32 avail_ddr; + long cached; + struct sysinfo vals; + struct device_node *node; + + si_meminfo(&vals); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) + cached = global_page_state(NR_FILE_PAGES); +#else + cached = global_node_page_state(NR_FILE_PAGES); +#endif + + avail_ddr = (vals.totalram + cached + vals.sharedram) * vals.mem_unit; + mmu->num_active_cores = nss_top_main.num_nss; + + /* + * Since "memory" has not been used by anyone, the format is not final. + * Three (3) possible formats available: one of 1 or 2 will be final. + * 1) item_size stating_address DDR_size : odd # items + * 2) stating_address DDR_size # 32-bit each; total 2 words + * 3) stating_address DDR_size # 64-bit each; total 4 words + */ + node = of_find_node_by_name(NULL, name); + if (node) { + int isize = 0; + int n_items; + const __be32 *ppp = (__be32 *)of_get_property(node, "reg", &n_items); + + n_items /= sizeof(ppp[0]); + nss_info_always("node size %d # items %d\n", + of_n_size_cells(node), n_items); + if (ppp) { + if (n_items & 1) { /* case 1 */ + isize = be32_to_cpup(ppp); + if (isize == 1) + goto case2; + if (isize == 2) + goto case3; + n_items = 0; + } else if (n_items == 2) { +case2: + mmu->start_address = be32_to_cpup(ppp + isize); + mmu->ddr_size = be32_to_cpup(&ppp[isize + 1]); + } else if (n_items == 4) { +case3: + if (!ppp[isize] && !ppp[isize * 2]) { + if (isize) + isize = 1; + mmu->start_address = be32_to_cpup(ppp + isize + 1); + mmu->ddr_size = be32_to_cpup(ppp + isize + 3); + } else + n_items = 0; + } else + n_items = 0; + if (n_items) { + of_node_put(node); + nss_info_always("%s: %x %u (avl %u) items %d active_cores %d\n", + name, mmu->start_address, mmu->ddr_size, + avail_ddr, n_items, mmu->num_active_cores); + /* + * if DTS mechanism goes wrong, use available + * DDR and round it up to 64MB for maximum DDR. + */ + if (avail_ddr > mmu->ddr_size) + mmu->ddr_size = (avail_ddr + (63 << 20)) + & (~63 << 20); + return; + } + } + of_node_put(node); + nss_info_always("incorrect memory info %px items %d\n", + ppp, n_items); + } + + /* + * boilerplate for setting customer values; + * start_address = 0 will not change default start address + * set in NSS FW (likely 0x4000_0000) + * total available RAM + 16 MB NSS FW DDR + ~31 MB kernel mem + * we round it up by 128MB to cover potential NSS DDR increase + * and a slightly large holes. + * The size can be changed to a fixed value as DTS, but simplier. + * mmu->ddr_size = 1024 << 20 + */ + mmu->start_address = 0; + mmu->ddr_size = (avail_ddr + (127 << 20)) & (~127 << 20); + nss_info_always("RAM pages fr %lu buf %lu cached %lu %lu : %lu %u\n", + vals.freeram, vals.bufferram, cached, vals.sharedram, + vals.totalram, mmu->ddr_size); +} + +/* + * nss_send_ddr_info() + * Send DDR info to NSS + */ +static void nss_send_ddr_info(struct nss_ctx_instance *nss_own) +{ + struct nss_n2h_msg nnm; + struct nss_cmn_msg *ncm = &nnm.cm; + uint32_t ret; + nss_info("%px: send DDR info\n", nss_own); + + nss_cmn_msg_init(ncm, NSS_N2H_INTERFACE, NSS_TX_DDR_INFO_VIA_N2H_CFG, + sizeof(struct nss_mmu_ddr_info), NULL, NULL); + + nss_get_ddr_info(&nnm.msg.mmu, "memory"); + nnm.msg.mmu.nss_ddr_size = nss_soc_mem_info(); + + ret = nss_core_send_cmd(nss_own, &nnm, sizeof(nnm), NSS_NBUF_PAYLOAD_SIZE); + if (ret != NSS_TX_SUCCESS) { + nss_info_always("%px: Failed to send DDR info for core %d\n", nss_own, nss_own->id); + } +} + +/* + * nss_core_cause_to_queue() + * Map interrupt cause to queue id + */ +static inline uint16_t nss_core_cause_to_queue(uint16_t cause) +{ + if (likely(cause == NSS_N2H_INTR_DATA_QUEUE_0)) { + return NSS_IF_N2H_DATA_QUEUE_0; + } + + if (likely(cause == NSS_N2H_INTR_DATA_QUEUE_1)) { + return NSS_IF_N2H_DATA_QUEUE_1; + } + + if (likely(cause == NSS_N2H_INTR_DATA_QUEUE_2)) { + return NSS_IF_N2H_DATA_QUEUE_2; + } + + if (likely(cause == NSS_N2H_INTR_DATA_QUEUE_3)) { + return NSS_IF_N2H_DATA_QUEUE_3; + } + + if (likely(cause == NSS_N2H_INTR_EMPTY_BUFFER_QUEUE)) { + return NSS_IF_N2H_EMPTY_BUFFER_RETURN_QUEUE; + } + + /* + * There is no way we can reach here as cause was already identified to be related to valid queue + */ + nss_assert(0); + return 0; +} + +/* + * nss_dump_desc() + * Prints descriptor data + */ +static inline void nss_dump_desc(struct nss_ctx_instance *nss_ctx, struct n2h_descriptor *desc) +{ + printk("bad descriptor dump for nss core = %d\n", nss_ctx->id); + printk("\topaque = %px\n", (void *)desc->opaque); + printk("\tinterface = %d\n", desc->interface_num); + printk("\tbuffer_type = %d\n", desc->buffer_type); + printk("\tbit_flags = %x\n", desc->bit_flags); + printk("\tbuffer_addr = %x\n", desc->buffer); + printk("\tbuffer_len = %d\n", desc->buffer_len); + printk("\tpayload_offs = %d\n", desc->payload_offs); + printk("\tpayload_len = %d\n", desc->payload_len); + printk("\tpri = %d\n", desc->pri); +} + +/* + * nss_core_skb_needs_linearize() + * Looks at if this skb needs to be linearized or not. + */ +static inline int nss_core_skb_needs_linearize(struct sk_buff *skb, uint32_t features) +{ + return ((skb_has_frag_list(skb) && + !(features & NETIF_F_FRAGLIST)) || + (skb_shinfo(skb)->nr_frags && + !(features & NETIF_F_SG))); +} + +/* + * nss_core_handle_bounced_pkt() + * Bounced packet is returned from an interface/bridge bounce operation. + * + * Return the skb to the registrant. + */ +static inline void nss_core_handle_bounced_pkt(struct nss_ctx_instance *nss_ctx, + struct nss_shaper_bounce_registrant *reg, + struct sk_buff *nbuf) +{ + void *app_data; + struct module *owner; + nss_shaper_bounced_callback_t bounced_callback; + struct nss_top_instance *nss_top = nss_ctx->nss_top; + + spin_lock_bh(&nss_top->lock); + + /* + * Do we have a registrant? + */ + if (!reg->registered) { + spin_unlock_bh(&nss_top->lock); + dev_kfree_skb_any(nbuf); + return; + } + + /* + * Get handle to the owning registrant + */ + bounced_callback = reg->bounced_callback; + app_data = reg->app_data; + owner = reg->owner; + + /* + * Callback is active, unregistration is not permitted while this is in progress + */ + reg->callback_active = true; + spin_unlock_bh(&nss_top->lock); + if (!try_module_get(owner)) { + spin_lock_bh(&nss_top->lock); + reg->callback_active = false; + spin_unlock_bh(&nss_top->lock); + dev_kfree_skb_any(nbuf); + return; + } + + /* + * Pass bounced packet back to registrant + */ + bounced_callback(app_data, nbuf); + spin_lock_bh(&nss_top->lock); + reg->callback_active = false; + spin_unlock_bh(&nss_top->lock); + module_put(owner); +} + +/* + * nss_core_handle_virt_if_pkt() + * Handle packet destined to virtual interface. + */ +static inline void nss_core_handle_virt_if_pkt(struct nss_ctx_instance *nss_ctx, + unsigned int interface_num, + struct sk_buff *nbuf) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + struct nss_subsystem_dataplane_register *subsys_dp_reg = &nss_ctx->subsys_dp_register[interface_num]; + struct net_device *ndev = NULL; + + uint32_t xmit_ret; + uint16_t queue_offset = 0; + + NSS_PKT_STATS_INC(&nss_top->stats_drv[NSS_DRV_STATS_RX_VIRTUAL]); + + /* + * Checksum is already done by NSS for packets forwarded to virtual interfaces + */ + nbuf->ip_summed = CHECKSUM_NONE; + + /* + * Obtain net_device pointer + */ + ndev = subsys_dp_reg->ndev; + if (unlikely(!ndev)) { + nss_warning("%px: Received packet for unregistered virtual interface %d", + nss_ctx, interface_num); + + /* + * NOTE: The assumption is that gather support is not + * implemented in fast path and hence we can not receive + * fragmented packets and so we do not need to take care + * of freeing a fragmented packet + */ + dev_kfree_skb_any(nbuf); + return; + } + + /* + * TODO: Need to ensure the ndev is not removed before we take dev_hold(). + */ + dev_hold(ndev); + nbuf->dev = ndev; + + /* + * Linearize the skb if needed + * + * Mixing up non linear check with in nss_core_skb_needs_linearize causes + * unencessary performance impact because of netif_skb_features() API call unconditionally + * Hence moved skb_is_nonlinear call outside. + */ + if (unlikely(skb_is_nonlinear(nbuf))) { + if (nss_core_skb_needs_linearize(nbuf, (uint32_t)netif_skb_features(nbuf)) && + __skb_linearize(nbuf)) { + /* + * We needed to linearize, but __skb_linearize() failed. Therefore + * we free the nbuf. + */ + dev_put(ndev); + dev_kfree_skb_any(nbuf); + return; + } + } + + /* + * Check to see if there is a xmit callback is registered + * in this path. The callback will decide the queue mapping. + */ + if (unlikely((subsys_dp_reg->xmit_cb))) { + skb_set_queue_mapping(nbuf, 0); + subsys_dp_reg->xmit_cb(ndev, nbuf); + dev_put(ndev); + return; + } + + /* + * Mimic Linux behavior to allow multi-queue netdev choose which queue to use + */ + if (ndev->netdev_ops->ndo_select_queue) { +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) + queue_offset = ndev->netdev_ops->ndo_select_queue(ndev, nbuf, NULL, NULL); +#else + queue_offset = ndev->netdev_ops->ndo_select_queue(ndev, nbuf, NULL); +#endif + } + + skb_set_queue_mapping(nbuf, queue_offset); + + /* + * Send the packet to virtual interface + * NOTE: Invoking this will BYPASS any assigned QDisc - this is OKAY + * as TX packets out of the NSS will have been shaped inside the NSS. + */ + xmit_ret = ndev->netdev_ops->ndo_start_xmit(nbuf, ndev); + if (unlikely(xmit_ret == NETDEV_TX_BUSY)) { + dev_kfree_skb_any(nbuf); + nss_info("%px: Congestion at virtual interface %d, %px", nss_ctx, interface_num, ndev); + } + dev_put(ndev); +} + +/* + * nss_core_handle_buffer_pkt() + * Handle data packet received on physical or virtual interface. + */ +static inline void nss_core_handle_buffer_pkt(struct nss_ctx_instance *nss_ctx, + unsigned int interface_num, + struct sk_buff *nbuf, + struct napi_struct *napi, + uint16_t flags, uint16_t qid, uint8_t service_code) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + struct nss_subsystem_dataplane_register *subsys_dp_reg = &nss_ctx->subsys_dp_register[interface_num]; + struct net_device *ndev = NULL; + nss_phys_if_rx_callback_t cb; + uint16_t queue_offset = qid - NSS_IF_N2H_DATA_QUEUE_0; + + NSS_PKT_STATS_INC(&nss_top->stats_drv[NSS_DRV_STATS_RX_PACKET]); + + /* + * Check if NSS was able to obtain checksum + */ + nbuf->ip_summed = CHECKSUM_UNNECESSARY; + if (unlikely(!(flags & N2H_BIT_FLAG_IP_TRANSPORT_CHECKSUM_VALID))) { + nbuf->ip_summed = CHECKSUM_NONE; + } + + ndev = subsys_dp_reg->ndev; + if (!ndev) { + dev_kfree_skb_any(nbuf); + return; + } + + /* + * If we have a non-zero service code, call the corresponding service code + * callback. The callback will consume the skb. + * For service code, we provide the raw packet as it was received. + */ + if (unlikely(service_code)) { + nss_cmn_service_code_callback_t cb = nss_ctx->service_code_callback[service_code]; + if (likely(cb)) { + dev_hold(ndev); + nbuf->dev = ndev; + nbuf->protocol = eth_type_trans(nbuf, ndev); + cb(nss_ctx->service_code_ctx[service_code], nbuf); + dev_put(ndev); + return; + } + } + + /* + * Deliver nbuf to the interface through callback if there is one. + */ + cb = subsys_dp_reg->cb; + if (likely(cb)) { + /* + * linearize or free if requested. + */ + if (unlikely(skb_is_nonlinear(nbuf))) { + if (nss_core_skb_needs_linearize(nbuf, ndev->features) && __skb_linearize(nbuf)) { + dev_kfree_skb_any(nbuf); + return; + } + } + + /* + * Record RX queue if the netdev has that many RX queues + */ + if (queue_offset < ndev->real_num_rx_queues) { + skb_record_rx_queue(nbuf, queue_offset); + } + + cb(ndev, (void *)nbuf, napi); + return; + } + + /* + * Deliver to the stack directly. Ex. there is no rule matched for + * redirect interface. + */ + dev_hold(ndev); + nbuf->dev = ndev; + nbuf->protocol = eth_type_trans(nbuf, ndev); + netif_receive_skb(nbuf); + dev_put(ndev); +} + +/* + * nss_core_handle_ext_buffer_pkt() + * Handle Extended data plane packet received on physical or virtual interface. + */ +static inline void nss_core_handle_ext_buffer_pkt(struct nss_ctx_instance *nss_ctx, + unsigned int interface_num, + struct sk_buff *nbuf, + struct napi_struct *napi, + uint16_t flags) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + struct nss_subsystem_dataplane_register *subsys_dp_reg = &nss_ctx->subsys_dp_register[interface_num]; + struct net_device *ndev = NULL; + nss_phys_if_rx_ext_data_callback_t ext_cb; + + NSS_PKT_STATS_INC(&nss_top->stats_drv[NSS_DRV_STATS_RX_EXT_PACKET]); + + /* + * Check if NSS was able to obtain checksum + */ + nbuf->ip_summed = CHECKSUM_UNNECESSARY; + if (unlikely(!(flags & N2H_BIT_FLAG_IP_TRANSPORT_CHECKSUM_VALID))) { + nbuf->ip_summed = CHECKSUM_NONE; + } + + ndev = subsys_dp_reg->ndev; + ext_cb = subsys_dp_reg->ext_cb; + if (likely(ext_cb) && likely(ndev)) { + + if (unlikely(skb_is_nonlinear(nbuf))) { + if (nss_core_skb_needs_linearize(nbuf, ndev->features) && __skb_linearize(nbuf)) { + /* + * We needed to linearize, but __skb_linearize() failed. So free the nbuf. + */ + dev_kfree_skb_any(nbuf); + return; + } + } + + ext_cb(ndev, (void *)nbuf, napi); + } else { + dev_kfree_skb_any(nbuf); + } +} + +/* + * nss_core_rx_pbuf() + * Receive a pbuf from the NSS into Linux. + */ +static inline void nss_core_rx_pbuf(struct nss_ctx_instance *nss_ctx, struct n2h_descriptor *desc, struct napi_struct *napi, + uint8_t buffer_type, struct sk_buff *nbuf, uint16_t qid) +{ + unsigned int interface_num = NSS_INTERFACE_NUM_GET(desc->interface_num); + unsigned int core_id = NSS_INTERFACE_NUM_GET_COREID(desc->interface_num); + struct nss_shaper_bounce_registrant *reg = NULL; + int32_t status; + + NSS_PKT_STATS_DEC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_NSS_SKB_COUNT]); + + if (interface_num >= NSS_MAX_NET_INTERFACES) { + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_RX_INVALID_INTERFACE]); + nss_warning("%px: Invalid interface_num: %d", nss_ctx, interface_num); + dev_kfree_skb_any(nbuf); + return; + } + + /* + * Check if core_id value is valid. + */ + if (core_id > nss_top_main.num_nss) { + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_RX_INVALID_CORE_ID]); + nss_warning("%px: Invalid core id: %d", nss_ctx, core_id); + dev_kfree_skb_any(nbuf); + return; + } + + /* + * Check if need to convert to local core value. + */ + if (core_id) { + nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[core_id - 1]; + } + + switch (buffer_type) { + case N2H_BUFFER_PACKET: + nss_core_handle_buffer_pkt(nss_ctx, interface_num, nbuf, napi, desc->bit_flags, qid, desc->service_code); + break; + + case N2H_BUFFER_PACKET_VIRTUAL: + nss_core_handle_virt_if_pkt(nss_ctx, interface_num, nbuf); + break; + + case N2H_BUFFER_SHAPER_BOUNCED_INTERFACE: + reg = &nss_ctx->nss_top->bounce_interface_registrants[interface_num]; + nss_core_handle_bounced_pkt(nss_ctx, reg, nbuf); + break; + + case N2H_BUFFER_SHAPER_BOUNCED_BRIDGE: + reg = &nss_ctx->nss_top->bounce_bridge_registrants[interface_num]; + nss_core_handle_bounced_pkt(nss_ctx, reg, nbuf); + break; + + case N2H_BUFFER_PACKET_EXT: + nss_core_handle_ext_buffer_pkt(nss_ctx, interface_num, nbuf, napi, desc->bit_flags); + break; + + case N2H_BUFFER_STATUS: + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_RX_STATUS]); + nss_core_handle_nss_status_pkt(nss_ctx, nbuf); + dev_kfree_skb_any(nbuf); + break; + + case N2H_BUFFER_CRYPTO_RESP: + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_RX_CRYPTO_RESP]); + nss_core_handle_crypto_pkt(nss_ctx, interface_num, nbuf, napi); + break; + + case N2H_BUFFER_RATE_TEST: + + /* + * This is a packet NSS sent for packet rate testing. The test measures the + * maximum PPS we can achieve between the host and NSS. After we process + * the descriptor, we directly send these test packets back to NSS without further process. + * They are again marked with H2N_BUFFER_RATE_TEST buffer type so NSS can process + * and count the test packets properly. + */ + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_RX_STATUS]); + status = nss_core_send_buffer(nss_ctx, 0, nbuf, NSS_IF_H2N_DATA_QUEUE, H2N_BUFFER_RATE_TEST, H2N_BIT_FLAG_BUFFER_REUSABLE); + if (unlikely(status != NSS_CORE_STATUS_SUCCESS)) { + dev_kfree_skb_any(nbuf); + nss_warning("%px: Unable to enqueue\n", nss_ctx); + } + nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_DATA_COMMAND_QUEUE); + break; + + default: + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_RX_INVALID_BUFFER_TYPE]); + nss_warning("%px: Invalid buffer type %d received from NSS", nss_ctx, buffer_type); + dev_kfree_skb_any(nbuf); + } +} + +/* + * nss_core_handle_nrfrag_skb() + * Handled the processing of fragmented skb's + */ +static inline bool nss_core_handle_nr_frag_skb(struct nss_ctx_instance *nss_ctx, struct sk_buff **nbuf_ptr, struct sk_buff **jumbo_start_ptr, struct n2h_descriptor *desc, unsigned int buffer_type) +{ + struct sk_buff *nbuf = *nbuf_ptr; + struct sk_buff *jumbo_start = *jumbo_start_ptr; + + uint16_t payload_len = desc->payload_len; + uint16_t payload_offs = desc->payload_offs; + uint16_t bit_flags = desc->bit_flags; + + nss_assert(desc->payload_offs + desc->payload_len <= PAGE_SIZE); + + dma_unmap_page(nss_ctx->dev, (desc->buffer + desc->payload_offs), desc->payload_len, DMA_FROM_DEVICE); + + /* + * The first and last bits are both set. Hence the received frame can't have + * chains (or it's not a scattered one). + */ + if (likely(bit_flags & N2H_BIT_FLAG_FIRST_SEGMENT) && likely(bit_flags & N2H_BIT_FLAG_LAST_SEGMENT)) { + + /* + * We have received another head before we saw the last segment. + * Free the old head as the frag list is corrupt. + */ + if (unlikely(jumbo_start)) { + nss_warning("%px: received a full frame before a last", jumbo_start); + dev_kfree_skb_any(jumbo_start); + *jumbo_start_ptr = NULL; + } + + /* + * NOTE: Need to use __skb_fill since we do not want to + * increment nr_frags again. We just want to adjust the offset + * and the length. + */ + __skb_fill_page_desc(nbuf, 0, skb_frag_page(&skb_shinfo(nbuf)->frags[0]), payload_offs, payload_len); + + /* + * We do not update truesize. We just keep the initial set value. + */ + nbuf->data_len = payload_len; + nbuf->len = payload_len; + nbuf->priority = desc->pri; + +/* + * TODO: Remove kernel version check when IGS is ported + */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)) +#ifdef CONFIG_NET_CLS_ACT + /* + * Skip the ingress QoS for the packet if the descriptor has + * ingress shaped flag set. + */ + if (unlikely(desc->bit_flags & N2H_BIT_FLAG_INGRESS_SHAPED)) { + nbuf->tc_verd = SET_TC_NCLS_NSS(nbuf->tc_verd); + } +#endif +#endif + goto pull; + } + + /* + * Track Number of Fragments processed. First && Last is not true fragment + */ + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_FRAG_SEG_PROCESSED]); + + /* + * NSS sent us an SG chain. + * Build a frags[] out of segments. + */ + if (unlikely((bit_flags & N2H_BIT_FLAG_FIRST_SEGMENT))) { + + /* + * We have received another head before we saw the last segment. + * Free the old head as the frag list is corrupt. + */ + if (unlikely(jumbo_start)) { + nss_warning("%px: received the second head before a last", jumbo_start); + dev_kfree_skb_any(jumbo_start); + } + + /* + * We do not update truesize. We just keep the initial set value. + */ + __skb_fill_page_desc(nbuf, 0, skb_frag_page(&skb_shinfo(nbuf)->frags[0]), payload_offs, payload_len); + nbuf->data_len = payload_len; + nbuf->len = payload_len; + nbuf->priority = desc->pri; + +/* + * TODO: Remove kernel version check when IGS is ported + */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)) +#ifdef CONFIG_NET_CLS_ACT + /* + * Skip the ingress QoS for the packet if the descriptor has + * ingress shaped flag set. + */ + if (unlikely(desc->bit_flags & N2H_BIT_FLAG_INGRESS_SHAPED)) { + nbuf->tc_verd = SET_TC_NCLS_NSS(nbuf->tc_verd); + } +#endif +#endif + + /* + * Set jumbo pointer to nbuf + */ + *jumbo_start_ptr = nbuf; + + /* + * Skip sending until last is received. + */ + return false; + } + + NSS_PKT_STATS_DEC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_NSS_SKB_COUNT]); + + /* + * We've received a middle or a last segment. + * Check that we have received a head first to avoid null deferencing. + */ + if (unlikely(jumbo_start == NULL)) { + /* + * Middle before first! Free the middle. + */ + nss_warning("%px: saw a middle skb before head", nbuf); + dev_kfree_skb_any(nbuf); + return false; + } + + /* + * Free the skb after attaching the frag to the head skb. + * Our page is safe although we are freeing it because we + * just took a reference to it. + */ + skb_add_rx_frag(jumbo_start, skb_shinfo(jumbo_start)->nr_frags, skb_frag_page(&skb_shinfo(nbuf)->frags[0]), payload_offs, payload_len, PAGE_SIZE); + skb_frag_ref(jumbo_start, skb_shinfo(jumbo_start)->nr_frags - 1); + dev_kfree_skb_any(nbuf); + + if (!(bit_flags & N2H_BIT_FLAG_LAST_SEGMENT)) { + /* + * Skip sending until last is received. + */ + return false; + } + + /* + * Last is received. Set nbuf pointer to point to + * the jumbo skb so that it continues to get processed. + */ + nbuf = jumbo_start; + *nbuf_ptr = nbuf; + *jumbo_start_ptr = NULL; + prefetch((void *)(nbuf->data)); + +pull: + /* + * We need eth hdr to be in the linear part of the skb + * for data packets. Otherwise eth_type_trans fails. + */ + if (buffer_type != N2H_BUFFER_STATUS) { + if (!pskb_may_pull(nbuf, ETH_HLEN)) { + dev_kfree_skb(nbuf); + nss_warning("%px: could not pull eth header", nbuf); + return false; + } + } + + return true; +} + +/* + * nss_core_handle_linear_skb() + * Handler for processing linear skbs. + */ +static inline bool nss_core_handle_linear_skb(struct nss_ctx_instance *nss_ctx, struct sk_buff **nbuf_ptr, struct sk_buff **head_ptr, + struct sk_buff **tail_ptr, struct n2h_descriptor *desc) +{ + uint16_t bit_flags = desc->bit_flags; + struct sk_buff *nbuf = *nbuf_ptr; + struct sk_buff *head = *head_ptr; + struct sk_buff *tail = *tail_ptr; + + /* + * We are in linear SKB mode. + */ + nbuf->data = nbuf->head + desc->payload_offs; + nbuf->len = desc->payload_len; + skb_set_tail_pointer(nbuf, nbuf->len); + + dma_unmap_single(nss_ctx->dev, (desc->buffer + desc->payload_offs), desc->payload_len, + DMA_FROM_DEVICE); + + prefetch((void *)(nbuf->data)); + + if (likely(bit_flags & N2H_BIT_FLAG_FIRST_SEGMENT) && likely(bit_flags & N2H_BIT_FLAG_LAST_SEGMENT)) { + + /* + * We have received another head before we saw the last segment. + * Free the old head as the frag list is corrupt. + */ + if (unlikely(head)) { + nss_warning("%px: received a full frame before a last", head); + dev_kfree_skb_any(head); + *head_ptr = NULL; + } + + nbuf->priority = desc->pri; + +/* + * TODO: Remove kernel version check when IGS is ported + */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)) +#ifdef CONFIG_NET_CLS_ACT + /* + * Skip the ingress QoS for the packet if the descriptor has + * ingress shaped flag set. + */ + if (unlikely(desc->bit_flags & N2H_BIT_FLAG_INGRESS_SHAPED)) { + nbuf->tc_verd = SET_TC_NCLS_NSS(nbuf->tc_verd); + } +#endif +#endif + + /* + * TODO: Check if there is any issue wrt map and unmap, + * NSS should playaround with data area and should not + * touch HEADROOM area + */ + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_RX_SIMPLE]); + return true; + } + + /* + * Track number of skb chain processed. First && Last is not true segment. + */ + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_CHAIN_SEG_PROCESSED]); + + /* + * NSS sent us an SG chain. + * Build a frag list out of segments. + */ + if (unlikely((bit_flags & N2H_BIT_FLAG_FIRST_SEGMENT))) { + + /* + * We have received another head before we saw the last segment. + * Free the old head as the frag list is corrupt. + */ + if (unlikely(head)) { + nss_warning("%px: received the second head before a last", head); + NSS_PKT_STATS_DEC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_NSS_SKB_COUNT]); + dev_kfree_skb_any(head); + } + + /* + * Found head. + */ + if (unlikely(skb_has_frag_list(nbuf))) { + /* + * We don't support chain in a chain. + */ + nss_warning("%px: skb already has a fraglist", nbuf); + NSS_PKT_STATS_DEC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_NSS_SKB_COUNT]); + dev_kfree_skb_any(nbuf); + return false; + } + + skb_frag_list_init(nbuf); + nbuf->data_len = 0; + nbuf->truesize = desc->payload_len; + nbuf->priority = desc->pri; + +/* + * TODO: Remove kernel version check when IGS is ported + */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)) +#ifdef CONFIG_NET_CLS_ACT + /* + * Skip the ingress QoS for the packet if the descriptor has + * ingress shaped flag set. + */ + if (unlikely(desc->bit_flags & N2H_BIT_FLAG_INGRESS_SHAPED)) { + nbuf->tc_verd = SET_TC_NCLS_NSS(nbuf->tc_verd); + } +#endif +#endif + + *head_ptr = nbuf; + + /* + * Skip sending until last is received. + */ + return false; + } + + NSS_PKT_STATS_DEC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_NSS_SKB_COUNT]); + + /* + * We've received a middle segment. + * Check that we have received a head first to avoid null deferencing. + */ + if (unlikely(head == NULL)) { + + /* + * Middle before first! Free the middle. + */ + nss_warning("%px: saw a middle skb before head", nbuf); + dev_kfree_skb_any(nbuf); + + return false; + } + + if (!skb_has_frag_list(head)) { + /* + * 2nd skb in the chain. head's frag_list should point to him. + */ + nbuf->next = skb_shinfo(head)->frag_list; + skb_shinfo(head)->frag_list = nbuf; + } else { + /* + * 3rd, 4th... skb in the chain. The chain's previous tail's + * next should point to him. + */ + tail->next = nbuf; + nbuf->next = NULL; + } + *tail_ptr = nbuf; + + /* + * Now we've added a new nbuf to the chain. + * Update the chain length. + */ + head->data_len += desc->payload_len; + head->len += desc->payload_len; + head->truesize += desc->payload_len; + + if (!(bit_flags & N2H_BIT_FLAG_LAST_SEGMENT)) { + /* + * Skip sending until last is received. + */ + return false; + } + + /* + * Last is received. Send the frag_list. + */ + *nbuf_ptr = head; + *head_ptr = NULL; + *tail_ptr = NULL; + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_RX_SKB_FRAGLIST]); + return true; +} + +/* + * nss_core_handle_empty_buffers() + * Handle empty buffer returns. + */ +static inline void nss_core_handle_empty_buffers(struct nss_ctx_instance *nss_ctx, + struct nss_if_mem_map *if_map, + struct hlos_n2h_desc_ring *n2h_desc_ring, + struct n2h_descriptor *desc_ring, + struct n2h_descriptor *desc, + uint32_t count, uint32_t hlos_index, + uint16_t mask) +{ + while (count) { + /* + * Since we only return the primary skb, we have no way to unmap + * properly. Simple skb's are properly mapped but page data skbs + * have the payload mapped (and not the skb->data slab payload). + * + * Warning: On non-Krait HW, we need to unmap fragments. + * + * This only unmaps the first segment either slab payload or + * skb page data. Eventually, we need to unmap all of a frag_list + * or all of page_data however this is not a big concern as of now + * since on Kriats dma_map_single() does not allocate any resource + * and hence dma_unmap_single() is sort off a nop. + * + * No need to invalidate for Tx Completions, so set dma direction = DMA_TO_DEVICE; + * Similarly prefetch is not needed for an empty buffer. + */ + struct sk_buff *nbuf; + + /* + * Prefetch the next cache line of descriptors. + */ + if (((hlos_index & 1) == 0) && likely(count > 2)) { + struct n2h_descriptor *next_cache_desc = &desc_ring[(hlos_index + 2) & mask]; + prefetch(next_cache_desc); + } + + nbuf = (struct sk_buff *)desc->opaque; + + if (unlikely(nbuf < (struct sk_buff *)PAGE_OFFSET)) { + /* + * Invalid opaque pointer + */ + nss_dump_desc(nss_ctx, desc); + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_RX_BAD_DESCRIPTOR]); + goto next; + } + + dma_unmap_single(nss_ctx->dev, (desc->buffer + desc->payload_offs), desc->payload_len, DMA_TO_DEVICE); + dev_kfree_skb_any(nbuf); + + NSS_PKT_STATS_DEC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_NSS_SKB_COUNT]); + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_RX_EMPTY]); + +next: + hlos_index = (hlos_index + 1) & (mask); + desc = &desc_ring[hlos_index]; + count--; + } + + n2h_desc_ring->hlos_index = hlos_index; + if_map->n2h_hlos_index[NSS_IF_N2H_EMPTY_BUFFER_RETURN_QUEUE] = hlos_index; + + NSS_CORE_DMA_CACHE_MAINT((void *)&if_map->n2h_hlos_index[NSS_IF_N2H_EMPTY_BUFFER_RETURN_QUEUE], sizeof(uint32_t), DMA_TO_DEVICE); + NSS_CORE_DSB(); +} + +/* + * nss_core_handle_cause_queue() + * Handle interrupt cause related to N2H/H2N queues + */ +static int32_t nss_core_handle_cause_queue(struct int_ctx_instance *int_ctx, uint16_t cause, int16_t weight) +{ + int16_t count, count_temp; + uint16_t size, mask, qid; + uint32_t nss_index, hlos_index, start, end; + struct sk_buff *nbuf; + struct hlos_n2h_desc_ring *n2h_desc_ring; + struct n2h_desc_if_instance *desc_if; + struct n2h_descriptor *desc_ring; + struct n2h_descriptor *desc; + struct n2h_descriptor *next_cache_desc; + struct nss_ctx_instance *nss_ctx = int_ctx->nss_ctx; + struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; + struct nss_if_mem_map *if_map = mem_ctx->if_map; + + qid = nss_core_cause_to_queue(cause); + + /* + * Make sure qid < num_rings + */ + nss_assert(qid < if_map->n2h_rings); + + n2h_desc_ring = &nss_ctx->n2h_desc_ring[qid]; + desc_if = &n2h_desc_ring->desc_ring; + desc_ring = desc_if->desc; + NSS_CORE_DMA_CACHE_MAINT((void *)&if_map->n2h_nss_index[qid], sizeof(uint32_t), DMA_FROM_DEVICE); + NSS_CORE_DSB(); + nss_index = if_map->n2h_nss_index[qid]; + + hlos_index = n2h_desc_ring->hlos_index; + size = desc_if->size; + mask = size - 1; + + /* + * Check if there is work to be done for this queue + */ + count = ((nss_index - hlos_index) + size) & (mask); + if (unlikely(count == 0)) { + return 0; + } + + /* + * Restrict ourselves to suggested weight + */ + if (count > weight) { + count = weight; + } + + /* + * Invalidate all the descriptors we are going to read + */ + start = hlos_index; + end = (hlos_index + count) & mask; + if (end > start) { + dmac_inv_range((void *)&desc_ring[start], (void *)&desc_ring[end] + sizeof(struct n2h_descriptor)); + } else { + /* + * We have wrapped around + */ + dmac_inv_range((void *)&desc_ring[start], (void *)&desc_ring[mask] + sizeof(struct n2h_descriptor)); + dmac_inv_range((void *)&desc_ring[0], (void *)&desc_ring[end] + sizeof(struct n2h_descriptor)); + } + + /* + * Prefetch the first descriptor + */ + desc = &desc_ring[hlos_index]; + prefetch(desc); + + /* + * Prefetch the next cache line of descriptors if we are starting with + * the second descriptor in the cache line. If it is the first in the cache line, + * this will be done inside the loop. + */ + if (((hlos_index & 1) == 1) && likely((count > 1))) { + next_cache_desc = &desc_ring[(hlos_index + 2) & mask]; + prefetch(next_cache_desc); + } + + if (qid == NSS_IF_N2H_EMPTY_BUFFER_RETURN_QUEUE) { + nss_core_handle_empty_buffers(nss_ctx, if_map, n2h_desc_ring, desc_ring, desc, count, hlos_index, mask); + return count; + } + + count_temp = count; + while (count_temp) { + unsigned int buffer_type; + nss_ptr_t opaque; + + /* + * Prefetch the next cache line of descriptors. + */ + if (((hlos_index & 1) == 0) && likely(count_temp > 2)) { + next_cache_desc = &desc_ring[(hlos_index + 2) & mask]; + prefetch(next_cache_desc); + } + + buffer_type = desc->buffer_type; + opaque = desc->opaque; + + /* + * Obtain nbuf + */ + nbuf = (struct sk_buff *)opaque; + if (unlikely(nbuf < (struct sk_buff *)PAGE_OFFSET)) { + /* + * Invalid opaque pointer + */ + nss_dump_desc(nss_ctx, desc); + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_RX_BAD_DESCRIPTOR]); + goto next; + } + + /* + * Shaping uses the singleton approach as well. No need to unmap all the segments since only + * one of them is actually looked at. + */ + if ((unlikely(buffer_type == N2H_BUFFER_SHAPER_BOUNCED_INTERFACE)) || (unlikely(buffer_type == N2H_BUFFER_SHAPER_BOUNCED_BRIDGE))) { + dma_unmap_page(nss_ctx->dev, (desc->buffer + desc->payload_offs), desc->payload_len, DMA_TO_DEVICE); + goto consume; + } + + /* + * crypto buffer + * + */ + if (unlikely((buffer_type == N2H_BUFFER_CRYPTO_RESP))) { + dma_unmap_single(NULL, (desc->buffer + desc->payload_offs), desc->payload_len, DMA_FROM_DEVICE); + goto consume; + } + + /* + * Check if we received a paged skb. + */ + if (skb_shinfo(nbuf)->nr_frags > 0) { + /* + * Check if we received paged skb while constructing + * a linear skb chain. If so we need to free. + */ + if (unlikely(n2h_desc_ring->head)) { + nss_warning("%px: we should not have an incomplete paged skb while" + " constructing a linear skb %px", nbuf, n2h_desc_ring->head); + + NSS_PKT_STATS_DEC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_NSS_SKB_COUNT]); + dev_kfree_skb_any(n2h_desc_ring->head); + n2h_desc_ring->head = NULL; + } + + if (!nss_core_handle_nr_frag_skb(nss_ctx, &nbuf, &n2h_desc_ring->jumbo_start, desc, buffer_type)) { + goto next; + } + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_RX_NR_FRAGS]); + goto consume; + } + + /* + * Check if we received a linear skb while constructing + * a paged skb. If so we need to free the paged_skb and handle the linear skb. + */ + if (unlikely(n2h_desc_ring->jumbo_start)) { + nss_warning("%px: we should not have an incomplete linear skb while" + " constructing a paged skb %px", nbuf, n2h_desc_ring->jumbo_start); + + NSS_PKT_STATS_DEC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_NSS_SKB_COUNT]); + dev_kfree_skb_any(n2h_desc_ring->jumbo_start); + n2h_desc_ring->jumbo_start = NULL; + } + + /* + * This is a simple linear skb. Use the the linear skb + * handler to process it. + */ + if (!nss_core_handle_linear_skb(nss_ctx, &nbuf, &n2h_desc_ring->head, &n2h_desc_ring->tail, desc)) { + goto next; + } + +consume: + nss_core_rx_pbuf(nss_ctx, desc, &(int_ctx->napi), buffer_type, nbuf, qid); + +next: + + hlos_index = (hlos_index + 1) & (mask); + desc = &desc_ring[hlos_index]; + count_temp--; + } + + n2h_desc_ring->hlos_index = hlos_index; + if_map->n2h_hlos_index[qid] = hlos_index; + + NSS_CORE_DMA_CACHE_MAINT((void *)&if_map->n2h_hlos_index[qid], sizeof(uint32_t), DMA_TO_DEVICE); + NSS_CORE_DSB(); + + return count; +} + +/* + * nss_core_init_nss() + * Initialize NSS core state + */ +static void nss_core_init_nss(struct nss_ctx_instance *nss_ctx, struct nss_if_mem_map *if_map) +{ + struct nss_top_instance *nss_top; + int ret; + + NSS_CORE_DMA_CACHE_MAINT((void *)if_map, sizeof(*if_map), DMA_FROM_DEVICE); + NSS_CORE_DSB(); + + /* + * NOTE: A commonly found error is that sizes and start address of per core + * virtual register map do not match in NSS and HLOS builds. This will lead + * to some hard to trace issues such as spinlock magic check failure etc. + * Following checks verify that proper virtual map has been initialized + */ + nss_assert(if_map->magic == DEV_MAGIC); + +#ifdef NSS_DRV_C2C_ENABLE + nss_ctx->c2c_start = nss_ctx->meminfo_ctx.c2c_start_dma; +#endif + + nss_top = nss_ctx->nss_top; + spin_lock_bh(&nss_top->lock); + nss_ctx->state = NSS_CORE_STATE_INITIALIZED; + spin_unlock_bh(&nss_top->lock); + + if (nss_ctx->id) { + ret = nss_n2h_update_queue_config_async(nss_ctx, pn_mq_en, pn_qlimits); + if (ret != NSS_TX_SUCCESS) { + nss_warning("Failed to send pnode queue config to core 1\n"); + } + return; + } + + /* + * If nss core0 is up, then we are ready to hook to nss-gmac + */ + if (nss_data_plane_schedule_registration()) { + + /* + * Configure the maximum number of IPv4/IPv6 + * connections supported by the accelerator. + */ + nss_ipv4_conn_cfg = max_ipv4_conn; + nss_ipv6_conn_cfg = max_ipv6_conn; + nss_ipv4_update_conn_count(max_ipv4_conn); + nss_ipv6_update_conn_count(max_ipv6_conn); + +#ifdef NSS_MEM_PROFILE_LOW + /* + * For low memory profiles, restrict the number of empty buffer pool + * size to NSS_LOW_MEM_EMPTY_POOL_BUF_SZ. Overwrite the default number + * of empty buffer pool size configured during NSS initialization. + */ + ret = nss_n2h_cfg_empty_pool_size(nss_ctx, NSS_LOW_MEM_EMPTY_POOL_BUF_SZ); + if (ret != NSS_TX_SUCCESS) { + nss_warning("%px: Failed to update empty buffer pool config\n", nss_ctx); + } +#endif + } else { + spin_lock_bh(&nss_top->lock); + nss_ctx->state = NSS_CORE_STATE_UNINITIALIZED; + spin_unlock_bh(&nss_top->lock); + } +} + +/* + * nss_core_alloc_paged_buffers() + * Allocate paged buffers for SOS. + */ +static void nss_core_alloc_paged_buffers(struct nss_ctx_instance *nss_ctx, struct nss_if_mem_map *if_map, + uint16_t count, int16_t mask, int32_t hlos_index, uint32_t alloc_fail_count, + uint32_t buffer_type, uint32_t buffer_queue, uint32_t stats_index) +{ + struct sk_buff *nbuf; + struct page *npage; + struct hlos_h2n_desc_rings *h2n_desc_ring = &nss_ctx->h2n_desc_rings[buffer_queue]; + struct h2n_desc_if_instance *desc_if = &h2n_desc_ring->desc_ring; + struct h2n_descriptor *desc_ring = desc_if->desc; + struct nss_top_instance *nss_top = nss_ctx->nss_top; + + while (count) { + struct h2n_descriptor *desc = &desc_ring[hlos_index]; + dma_addr_t buffer; + + /* + * Alloc an skb AND a page. + */ + nbuf = dev_alloc_skb(NSS_CORE_JUMBO_LINEAR_BUF_SIZE); + if (unlikely(!nbuf)) { + /* + * ERR: + */ + NSS_PKT_STATS_INC(&nss_top->stats_drv[alloc_fail_count]); + nss_warning("%px: Could not obtain empty paged buffer", nss_ctx); + break; + } + + npage = alloc_page(GFP_ATOMIC); + if (unlikely(!npage)) { + /* + * ERR: + */ + dev_kfree_skb_any(nbuf); + NSS_PKT_STATS_INC(&nss_top->stats_drv[alloc_fail_count]); + nss_warning("%px: Could not obtain empty page", nss_ctx); + break; + } + + /* + * When we alloc an skb, initially head = data = tail and len = 0. + * So nobody will try to read the linear part of the skb. + */ + skb_fill_page_desc(nbuf, 0, npage, 0, PAGE_SIZE); + nbuf->data_len += PAGE_SIZE; + nbuf->len += PAGE_SIZE; + nbuf->truesize += PAGE_SIZE; + + /* Map the page for jumbo */ + buffer = dma_map_page(nss_ctx->dev, npage, 0, PAGE_SIZE, DMA_FROM_DEVICE); + desc->buffer_len = PAGE_SIZE; + desc->payload_offs = 0; + + if (unlikely(dma_mapping_error(nss_ctx->dev, buffer))) { + /* + * ERR: + */ + dev_kfree_skb_any(nbuf); + nss_warning("%px: DMA mapping failed for empty buffer", nss_ctx); + break; + } + /* + * We are holding this skb in NSS FW, let kmemleak know about it + */ + kmemleak_not_leak(nbuf); + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_NSS_SKB_COUNT]); + desc->opaque = (nss_ptr_t)nbuf; + desc->buffer = buffer; + desc->buffer_type = buffer_type; + + /* + * Flush the descriptor + */ + NSS_CORE_DMA_CACHE_MAINT((void *)desc, sizeof(*desc), DMA_TO_DEVICE); + + hlos_index = (hlos_index + 1) & (mask); + count--; + } + + /* + * Wait for the flushes to be synced before writing the index + */ + NSS_CORE_DSB(); + + h2n_desc_ring->hlos_index = hlos_index; + if_map->h2n_hlos_index[buffer_queue] = hlos_index; + + NSS_CORE_DMA_CACHE_MAINT(&if_map->h2n_hlos_index[buffer_queue], sizeof(uint32_t), DMA_TO_DEVICE); + NSS_CORE_DSB(); + + NSS_PKT_STATS_INC(&nss_top->stats_drv[stats_index]); +} + +/* + * nss_core_alloc_jumbo_mru_buffers() + * Allocate jumbo mru buffers. + */ +static void nss_core_alloc_jumbo_mru_buffers(struct nss_ctx_instance *nss_ctx, struct nss_if_mem_map *if_map, + int jumbo_mru, uint16_t count, int16_t mask, int32_t hlos_index) +{ + + struct sk_buff *nbuf; + struct hlos_h2n_desc_rings *h2n_desc_ring = &nss_ctx->h2n_desc_rings[NSS_IF_H2N_EMPTY_BUFFER_QUEUE]; + struct h2n_desc_if_instance *desc_if = &h2n_desc_ring->desc_ring; + struct h2n_descriptor *desc_ring = desc_if->desc; + struct nss_top_instance *nss_top = nss_ctx->nss_top; + + while (count) { + struct h2n_descriptor *desc = &desc_ring[hlos_index]; + dma_addr_t buffer; + nbuf = dev_alloc_skb(jumbo_mru); + if (unlikely(!nbuf)) { + /* + * ERR: + */ + NSS_PKT_STATS_INC(&nss_top->stats_drv[NSS_DRV_STATS_NBUF_ALLOC_FAILS]); + nss_warning("%px: Could not obtain empty jumbo mru buffer", nss_ctx); + break; + } + + /* + * Map the skb + */ + buffer = dma_map_single(nss_ctx->dev, nbuf->head, jumbo_mru, DMA_FROM_DEVICE); + desc->buffer_len = jumbo_mru; + desc->payload_offs = (uint16_t) (nbuf->data - nbuf->head); + if (unlikely(dma_mapping_error(nss_ctx->dev, buffer))) { + /* + * ERR: + */ + dev_kfree_skb_any(nbuf); + nss_warning("%px: DMA mapping failed for empty buffer", nss_ctx); + break; + } + + /* + * We are holding this skb in NSS FW, let kmemleak know about it + */ + kmemleak_not_leak(nbuf); + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_NSS_SKB_COUNT]); + desc->opaque = (nss_ptr_t)nbuf; + desc->buffer = buffer; + desc->buffer_type = H2N_BUFFER_EMPTY; + + /* + * Flush the descriptor + */ + NSS_CORE_DMA_CACHE_MAINT((void *)desc, sizeof(*desc), DMA_TO_DEVICE); + + hlos_index = (hlos_index + 1) & (mask); + count--; + } + + /* + * Wait for the flushes to be synced before writing the index + */ + NSS_CORE_DSB(); + + h2n_desc_ring->hlos_index = hlos_index; + if_map->h2n_hlos_index[NSS_IF_H2N_EMPTY_BUFFER_QUEUE] = hlos_index; + + NSS_CORE_DMA_CACHE_MAINT(&if_map->h2n_hlos_index[NSS_IF_H2N_EMPTY_BUFFER_QUEUE], sizeof(uint32_t), DMA_TO_DEVICE); + NSS_CORE_DSB(); + + NSS_PKT_STATS_INC(&nss_top->stats_drv[NSS_DRV_STATS_TX_EMPTY]); +} + +/* + * nss_core_alloc_max_avail_size_buffers() + * Allocate maximum available sized buffers. + */ +static void nss_core_alloc_max_avail_size_buffers(struct nss_ctx_instance *nss_ctx, struct nss_if_mem_map *if_map, + uint16_t max_buf_size, uint16_t count, int16_t mask, int32_t hlos_index) +{ + struct hlos_h2n_desc_rings *h2n_desc_ring = &nss_ctx->h2n_desc_rings[NSS_IF_H2N_EMPTY_BUFFER_QUEUE]; + struct h2n_desc_if_instance *desc_if = &h2n_desc_ring->desc_ring; + struct h2n_descriptor *desc_ring = desc_if->desc; + struct nss_top_instance *nss_top = nss_ctx->nss_top; + uint16_t payload_len = max_buf_size + NET_SKB_PAD; + uint16_t start = hlos_index; + uint16_t prev_hlos_index; + + while (count) { + dma_addr_t buffer; + struct h2n_descriptor *desc = &desc_ring[hlos_index]; + + struct sk_buff *nbuf = dev_alloc_skb(max_buf_size); + if (unlikely(!nbuf)) { + /* + * ERR: + */ + NSS_PKT_STATS_INC(&nss_top->stats_drv[NSS_DRV_STATS_NBUF_ALLOC_FAILS]); + nss_warning("%px: Could not obtain empty buffer", nss_ctx); + break; + } + + /* + * Map the skb + */ + buffer = dma_map_single(nss_ctx->dev, nbuf->head, payload_len, DMA_FROM_DEVICE); + + if (unlikely(dma_mapping_error(nss_ctx->dev, buffer))) { + /* + * ERR: + */ + dev_kfree_skb_any(nbuf); + nss_warning("%px: DMA mapping failed for empty buffer", nss_ctx); + break; + } + + /* + * We are holding this skb in NSS FW, let kmemleak know about it + */ + kmemleak_not_leak(nbuf); + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_NSS_SKB_COUNT]); + + desc->opaque = (nss_ptr_t)nbuf; + desc->buffer = buffer; + desc->buffer_len = payload_len; + + hlos_index = (hlos_index + 1) & (mask); + count--; + } + + /* + * Find the last descriptor we need to flush. + */ + prev_hlos_index = (hlos_index - 1) & mask; + + /* + * Flush the descriptors, including the descriptor at prev_hlos_index. + */ + if (prev_hlos_index > start) { + dmac_clean_range((void *)&desc_ring[start], (void *)&desc_ring[prev_hlos_index] + sizeof(struct h2n_descriptor)); + } else { + /* + * We have wrapped around + */ + dmac_clean_range((void *)&desc_ring[start], (void *)&desc_ring[mask] + sizeof(struct h2n_descriptor)); + dmac_clean_range((void *)&desc_ring[0], (void *)&desc_ring[prev_hlos_index] + sizeof(struct h2n_descriptor)); + } + + /* + * Wait for the flushes to be synced before writing the index + */ + NSS_CORE_DSB(); + + h2n_desc_ring->hlos_index = hlos_index; + if_map->h2n_hlos_index[NSS_IF_H2N_EMPTY_BUFFER_QUEUE] = hlos_index; + + NSS_CORE_DMA_CACHE_MAINT(&if_map->h2n_hlos_index[NSS_IF_H2N_EMPTY_BUFFER_QUEUE], sizeof(uint32_t), DMA_TO_DEVICE); + NSS_CORE_DSB(); + + NSS_PKT_STATS_INC(&nss_top->stats_drv[NSS_DRV_STATS_TX_EMPTY]); +} + +/* + * nss_core_handle_empty_buffer_sos() + * Handle empty buffer SOS interrupt. + */ +static inline void nss_core_handle_empty_buffer_sos(struct nss_ctx_instance *nss_ctx, + struct nss_if_mem_map *if_map, uint16_t max_buf_size) +{ + uint16_t count, size, mask; + int32_t nss_index, hlos_index; + struct hlos_h2n_desc_rings *h2n_desc_ring = &nss_ctx->h2n_desc_rings[NSS_IF_H2N_EMPTY_BUFFER_QUEUE]; + + int paged_mode = nss_core_get_paged_mode(); + int jumbo_mru = nss_core_get_jumbo_mru(); + + /* + * Check how many empty buffers could be filled in queue + */ + NSS_CORE_DMA_CACHE_MAINT(&if_map->h2n_nss_index[NSS_IF_H2N_EMPTY_BUFFER_QUEUE], sizeof(uint32_t), DMA_FROM_DEVICE); + NSS_CORE_DSB(); + nss_index = if_map->h2n_nss_index[NSS_IF_H2N_EMPTY_BUFFER_QUEUE]; + + hlos_index = h2n_desc_ring->hlos_index; + size = h2n_desc_ring->desc_ring.size; + + mask = size - 1; + count = ((nss_index - hlos_index - 1) + size) & (mask); + + nss_trace("%px: Adding %d buffers to empty queue\n", nss_ctx, count); + + /* + * Fill empty buffer queue with buffers leaving one empty descriptor + * Note that total number of descriptors in queue cannot be more than (size - 1) + */ + if (!count) { + return; + } + + if (paged_mode) { + nss_core_alloc_paged_buffers(nss_ctx, if_map, count, mask, hlos_index, + NSS_DRV_STATS_NBUF_ALLOC_FAILS, H2N_BUFFER_EMPTY, + NSS_IF_H2N_EMPTY_BUFFER_QUEUE, NSS_DRV_STATS_TX_EMPTY); + } else if (jumbo_mru) { + nss_core_alloc_jumbo_mru_buffers(nss_ctx, if_map, jumbo_mru, count, + mask, hlos_index); + } else { + nss_core_alloc_max_avail_size_buffers(nss_ctx, if_map, max_buf_size, + count, mask, hlos_index); + } + + /* + * Inform NSS that new buffers are available + */ + nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_EMPTY_BUFFER_QUEUE); +} + +/* + * nss_core_handle_paged_empty_buffer_sos() + * Handle paged empty buffer SOS. + */ +static inline void nss_core_handle_paged_empty_buffer_sos(struct nss_ctx_instance *nss_ctx, + struct nss_if_mem_map *if_map, uint16_t max_buf_size) +{ + uint16_t count, size, mask; + int32_t nss_index, hlos_index; + struct hlos_h2n_desc_rings *h2n_desc_ring = &nss_ctx->h2n_desc_rings[NSS_IF_H2N_EMPTY_PAGED_BUFFER_QUEUE]; + + /* + * Check how many empty buffers could be filled in queue + */ + NSS_CORE_DMA_CACHE_MAINT((void *)&if_map->h2n_nss_index[NSS_IF_H2N_EMPTY_PAGED_BUFFER_QUEUE], sizeof(uint32_t), DMA_FROM_DEVICE); + NSS_CORE_DSB(); + nss_index = if_map->h2n_nss_index[NSS_IF_H2N_EMPTY_PAGED_BUFFER_QUEUE]; + + hlos_index = h2n_desc_ring->hlos_index; + size = h2n_desc_ring->desc_ring.size; + + mask = size - 1; + count = ((nss_index - hlos_index - 1) + size) & (mask); + nss_trace("%px: Adding %d buffers to paged buffer queue", nss_ctx, count); + + /* + * Fill empty buffer queue with buffers leaving one empty descriptor + * Note that total number of descriptors in queue cannot be more than (size - 1) + */ + if (!count) { + return; + } + + nss_core_alloc_paged_buffers(nss_ctx, if_map, count, mask, hlos_index, + NSS_DRV_STATS_PAGED_BUF_ALLOC_FAILS, H2N_PAGED_BUFFER_EMPTY, + NSS_IF_H2N_EMPTY_PAGED_BUFFER_QUEUE, NSS_DRV_STATS_PAGED_TX_EMPTY); + + /* + * Inform NSS that new buffers are available + */ + nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_EMPTY_PAGED_BUFFER_QUEUE); +} + +/* + * nss_core_handle_tx_unblocked() + * Handle TX Unblocked. + */ +static inline void nss_core_handle_tx_unblocked(struct nss_ctx_instance *nss_ctx) +{ + int32_t i; + nss_trace("%px: Data queue unblocked", nss_ctx); + + /* + * Call callback functions of drivers that have registered with us + */ + spin_lock_bh(&nss_ctx->decongest_cb_lock); + + for (i = 0; i < NSS_MAX_CLIENTS; i++) { + if (nss_ctx->queue_decongestion_callback[i]) { + nss_ctx->queue_decongestion_callback[i](nss_ctx->queue_decongestion_ctx[i]); + } + } + + spin_unlock_bh(&nss_ctx->decongest_cb_lock); + nss_ctx->h2n_desc_rings[NSS_IF_H2N_DATA_QUEUE].flags &= ~NSS_H2N_DESC_RING_FLAGS_TX_STOPPED; + + /* + * Mask Tx unblocked interrupt and unmask it again when queue full condition is reached + */ + nss_hal_disable_interrupt(nss_ctx, nss_ctx->int_ctx[0].shift_factor, NSS_N2H_INTR_TX_UNBLOCKED); +} + +/* + * nss_core_handle_cause_nonqueue() + * Handle non-queue interrupt causes (e.g. empty buffer SOS, Tx unblocked) + */ +static void nss_core_handle_cause_nonqueue(struct int_ctx_instance *int_ctx, uint32_t cause, int16_t weight) +{ + struct nss_ctx_instance *nss_ctx = int_ctx->nss_ctx; + struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; + struct nss_if_mem_map *if_map = mem_ctx->if_map; + uint16_t max_buf_size = (uint16_t) nss_ctx->max_buf_size; +#ifdef NSS_DRV_C2C_ENABLE + uint32_t c2c_intr_addr1, c2c_intr_addr2; + int32_t i; +#endif + + nss_assert((cause == NSS_N2H_INTR_EMPTY_BUFFERS_SOS) + || (cause == NSS_N2H_INTR_TX_UNBLOCKED) + || cause == NSS_N2H_INTR_PAGED_EMPTY_BUFFERS_SOS); + + /* + * If this is the first time we are receiving this interrupt then + * we need to initialize local state of NSS core. This helps us save an + * interrupt cause bit. Hopefully, unlikley and branch prediction algorithm + * of processor will prevent any excessive penalties. + */ + if (unlikely(nss_ctx->state == NSS_CORE_STATE_UNINITIALIZED)) { + struct nss_top_instance *nss_top = NULL; + nss_core_init_nss(nss_ctx, if_map); + nss_send_ddr_info(nss_ctx); + + nss_info_always("%px: nss core %d booted successfully\n", nss_ctx, nss_ctx->id); + nss_top = nss_ctx->nss_top; + +#ifdef NSS_DRV_C2C_ENABLE +#if (NSS_MAX_CORES > 1) + /* + * Pass C2C addresses of already brought up cores to the recently brought + * up core. No NSS core knows the state of other other cores in system so + * NSS driver needs to mediate and kick start C2C between them + */ + for (i = 0; i < nss_top_main.num_nss; i++) { + /* + * Loop through all NSS cores and send exchange C2C addresses + * TODO: Current implementation utilizes the fact that there are + * only two cores in current design. And ofcourse ignore + * the core that we are trying to initialize. + */ + if (&nss_top->nss[i] != nss_ctx) { + /* + * Block initialization routine of any other NSS cores running on other + * processors. We do not want them to mess around with their initialization + * state and C2C addresses while we check their state. + */ + spin_lock_bh(&nss_top->lock); + if (nss_top->nss[i].state == NSS_CORE_STATE_INITIALIZED) { + spin_unlock_bh(&nss_top->lock); + c2c_intr_addr1 = (uint32_t)(nss_ctx->nphys) + NSS_REGS_C2C_INTR_SET_OFFSET; + nss_c2c_tx_msg_cfg_map(&nss_top->nss[i], nss_ctx->c2c_start, c2c_intr_addr1); + c2c_intr_addr2 = (uint32_t)(nss_top->nss[i].nphys) + NSS_REGS_C2C_INTR_SET_OFFSET; + nss_c2c_tx_msg_cfg_map(nss_ctx, nss_top->nss[i].c2c_start, c2c_intr_addr2); + continue; + } + spin_unlock_bh(&nss_top->lock); + } + } +#endif +#endif + } + + /* + * TODO: find better mechanism to handle empty buffers + */ + if (likely(cause == NSS_N2H_INTR_EMPTY_BUFFERS_SOS)) { + nss_core_handle_empty_buffer_sos(nss_ctx, if_map, max_buf_size); + } else if (cause == NSS_N2H_INTR_PAGED_EMPTY_BUFFERS_SOS) { + nss_core_handle_paged_empty_buffer_sos(nss_ctx, if_map, max_buf_size); + } else if (cause == NSS_N2H_INTR_TX_UNBLOCKED) { + nss_core_handle_tx_unblocked(nss_ctx); + } +} + +/* + * nss_core_get_prioritized_cause() + * Obtain proritized cause (from multiple interrupt causes) that + * must be handled by NSS driver before other causes + */ +static uint32_t nss_core_get_prioritized_cause(uint32_t cause, uint32_t *type, int16_t *weight) +{ + *type = NSS_INTR_CAUSE_INVALID; + *weight = 0; + + /* + * NOTE: This is a very simple algorithm with fixed weight and strict priority + * + * TODO: Modify the algorithm later with proper weights and Round Robin + */ + + if (cause & NSS_N2H_INTR_EMPTY_BUFFERS_SOS) { + *type = NSS_INTR_CAUSE_NON_QUEUE; + *weight = NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT; + return NSS_N2H_INTR_EMPTY_BUFFERS_SOS; + } + + if (cause & NSS_N2H_INTR_PAGED_EMPTY_BUFFERS_SOS) { + *type = NSS_INTR_CAUSE_NON_QUEUE; + *weight = NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT; + return NSS_N2H_INTR_PAGED_EMPTY_BUFFERS_SOS; + } + + if (cause & NSS_N2H_INTR_EMPTY_BUFFER_QUEUE) { + *type = NSS_INTR_CAUSE_QUEUE; + *weight = NSS_EMPTY_BUFFER_RETURN_PROCESSING_WEIGHT; + return NSS_N2H_INTR_EMPTY_BUFFER_QUEUE; + } + + if (cause & NSS_N2H_INTR_TX_UNBLOCKED) { + *type = NSS_INTR_CAUSE_NON_QUEUE; + *weight = NSS_TX_UNBLOCKED_PROCESSING_WEIGHT; + return NSS_N2H_INTR_TX_UNBLOCKED; + } + + if (cause & NSS_N2H_INTR_DATA_QUEUE_0) { + *type = NSS_INTR_CAUSE_QUEUE; + *weight = NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT; + return NSS_N2H_INTR_DATA_QUEUE_0; + } + + if (cause & NSS_N2H_INTR_DATA_QUEUE_1) { + *type = NSS_INTR_CAUSE_QUEUE; + *weight = NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT; + return NSS_N2H_INTR_DATA_QUEUE_1; + } + + if (cause & NSS_N2H_INTR_DATA_QUEUE_2) { + *type = NSS_INTR_CAUSE_QUEUE; + *weight = NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT; + return NSS_N2H_INTR_DATA_QUEUE_2; + } + + if (cause & NSS_N2H_INTR_DATA_QUEUE_3) { + *type = NSS_INTR_CAUSE_QUEUE; + *weight = NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT; + return NSS_N2H_INTR_DATA_QUEUE_3; + } + + if (cause & NSS_N2H_INTR_COREDUMP_COMPLETE) { + *type = NSS_INTR_CAUSE_EMERGENCY; + return NSS_N2H_INTR_COREDUMP_COMPLETE; + } + + if (cause & NSS_N2H_INTR_PROFILE_DMA) { + *type = NSS_INTR_CAUSE_SDMA; + return NSS_N2H_INTR_PROFILE_DMA; + } + + return 0; +} + +/* + * nss_core_handle_napi() + * NAPI handler for NSS + */ +int nss_core_handle_napi(struct napi_struct *napi, int budget) +{ + int16_t processed, weight, count = 0; + uint32_t prio_cause, int_cause = 0, cause_type; + struct int_ctx_instance *int_ctx = container_of(napi, struct int_ctx_instance, napi); + struct nss_ctx_instance *nss_ctx = int_ctx->nss_ctx; + + /* + * Read cause of interrupt + */ + nss_hal_read_interrupt_cause(nss_ctx, int_ctx->shift_factor, &int_cause); + nss_hal_clear_interrupt_cause(nss_ctx, int_ctx->shift_factor, int_cause); + int_ctx->cause |= int_cause; + + do { + while ((int_ctx->cause) && (budget)) { + + /* + * Obtain the cause as per priority. Also obtain the weight + * + * NOTE: The idea is that all causes are processed as per priority and weight + * so that no single cause can overwhelm the system. + */ + prio_cause = nss_core_get_prioritized_cause(int_ctx->cause, &cause_type, &weight); + if (budget < weight) { + weight = budget; + } + + processed = 0; + switch (cause_type) { + case NSS_INTR_CAUSE_QUEUE: + processed = nss_core_handle_cause_queue(int_ctx, prio_cause, weight); + + count += processed; + budget -= processed; + + /* + * If #packets processed were lesser than weight then processing for this queue/cause is + * complete and we can clear this interrupt cause from interrupt context structure + */ + if (processed < weight) { + int_ctx->cause &= ~prio_cause; + } + break; + + case NSS_INTR_CAUSE_NON_QUEUE: + nss_core_handle_cause_nonqueue(int_ctx, prio_cause, weight); + int_ctx->cause &= ~prio_cause; + break; + + case NSS_INTR_CAUSE_SDMA: + nss_core_handle_napi_sdma(napi, budget); + int_ctx->cause &= ~prio_cause; + break; + + case NSS_INTR_CAUSE_EMERGENCY: + nss_info_always("NSS core %d signal COREDUMP COMPLETE %x\n", + nss_ctx->id, int_ctx->cause); + nss_fw_coredump_notify(nss_ctx, prio_cause); + int_ctx->cause &= ~prio_cause; + break; + + default: + nss_warning("%px: Invalid cause %x received from nss", nss_ctx, int_cause); + nss_assert(0); + break; + } + } + + nss_hal_read_interrupt_cause(nss_ctx, int_ctx->shift_factor, &int_cause); + nss_hal_clear_interrupt_cause(nss_ctx, int_ctx->shift_factor, int_cause); + int_ctx->cause |= int_cause; + } while ((int_ctx->cause) && (budget)); + + if (int_ctx->cause == 0) { + napi_complete(napi); + + /* + * Re-enable any further interrupt from this IRQ + */ + nss_hal_enable_interrupt(nss_ctx, int_ctx->shift_factor, NSS_HAL_SUPPORTED_INTERRUPTS); + } + + return count; +} + +/* + * nss_core_handle_napi_emergency() + * NAPI handler for NSS crash + */ +int nss_core_handle_napi_emergency(struct napi_struct *napi, int budget) +{ + struct int_ctx_instance *int_ctx = container_of(napi, struct int_ctx_instance, napi); + + nss_info_always("NSS core %d signal COREDUMP COMPLETE %x\n", + int_ctx->nss_ctx->id, int_ctx->cause); + nss_fw_coredump_notify(int_ctx->nss_ctx, 0); + + return 0; +} + +/* + * nss_core_handle_napi_sdma() + * NAPI handler for NSS soft DMA + */ +int nss_core_handle_napi_sdma(struct napi_struct *napi, int budget) +{ + struct int_ctx_instance *int_ctx = container_of(napi, struct int_ctx_instance, napi); + struct nss_ctx_instance *nss_ctx = int_ctx->nss_ctx; + struct nss_profile_sdma_ctrl *ctrl = (struct nss_profile_sdma_ctrl *)nss_ctx->meminfo_ctx.sdma_ctrl; + + if (ctrl->consumer[0].dispatch.fp) + ctrl->consumer[0].dispatch.fp(ctrl->consumer[0].arg.kp); + +#if !defined(NSS_HAL_IPQ806X_SUPPORT) + napi_complete(napi); + enable_irq(int_ctx->irq); +#endif + return 0; +} + +/* + * nss_core_handle_napi_queue() + * NAPI handler for NSS queue cause + */ +int nss_core_handle_napi_queue(struct napi_struct *napi, int budget) +{ + int processed; + struct int_ctx_instance *int_ctx = container_of(napi, struct int_ctx_instance, napi); + + processed = nss_core_handle_cause_queue(int_ctx, int_ctx->cause, budget); + if (processed < budget) { + napi_complete(napi); + enable_irq(int_ctx->irq); + } + + return processed; +} + +/* + * nss_core_handle_napi_non_queue() + * NAPI handler for NSS non queue cause + */ +int nss_core_handle_napi_non_queue(struct napi_struct *napi, int budget) +{ + struct int_ctx_instance *int_ctx = container_of(napi, struct int_ctx_instance, napi); + + nss_core_handle_cause_nonqueue(int_ctx, int_ctx->cause, 0); + napi_complete(napi); + enable_irq(int_ctx->irq); + return 0; +} + +/* + * nss_core_write_one_descriptor() + * Fills-up a descriptor with required fields. + */ +static inline void nss_core_write_one_descriptor(struct h2n_descriptor *desc, + uint16_t buffer_type, uint32_t buffer, uint32_t if_num, + nss_ptr_t opaque, uint16_t payload_off, uint16_t payload_len, uint16_t buffer_len, + uint32_t qos_tag, uint16_t mss, uint16_t bit_flags) +{ + desc->buffer_type = buffer_type; + desc->buffer = buffer; + desc->interface_num = if_num; + desc->opaque = opaque; + desc->payload_offs = payload_off; + desc->payload_len = payload_len; + desc->buffer_len = buffer_len; + desc->qos_tag = qos_tag; + desc->mss = mss; + desc->bit_flags = bit_flags; +} + +/* +* nss_core_send_unwind_dma() +* It unwinds (or unmap) DMA from descriptors +*/ +static inline void nss_core_send_unwind_dma(struct device *dev, struct h2n_desc_if_instance *desc_if, + uint16_t hlos_index, int16_t count, bool is_fraglist) +{ + struct h2n_descriptor *desc_ring = desc_if->desc; + struct h2n_descriptor *desc; + int16_t i, mask; + + mask = desc_if->size - 1; + for (i = 0; i < count; i++) { + desc = &desc_ring[hlos_index]; + if (is_fraglist) { + dma_unmap_single(dev, desc->buffer, desc->buffer_len, DMA_TO_DEVICE); + } else { + dma_unmap_page(dev, desc->buffer, desc->buffer_len, DMA_TO_DEVICE); + } + hlos_index = (hlos_index - 1) & mask; + } +} + +/* + * nss_core_skb_tail_offset() + */ +static inline uint32_t nss_core_skb_tail_offset(struct sk_buff *skb) +{ +#ifdef NET_SKBUFF_DATA_USES_OFFSET + return skb->tail; +#else + return skb->tail - skb->head; +#endif +} + +/* + * nss_core_dma_map_single() + */ +static inline uint32_t nss_core_dma_map_single(struct device *dev, struct sk_buff *skb) +{ + return (uint32_t)dma_map_single(dev, skb->head, nss_core_skb_tail_offset(skb), DMA_TO_DEVICE); +} + +#if (NSS_SKB_REUSE_SUPPORT == 1) +/* + * nss_core_skb_can_reuse + * check if skb can be reuse + */ +static inline bool nss_core_skb_can_reuse(struct nss_ctx_instance *nss_ctx, + uint32_t if_num, struct sk_buff *nbuf, int min_skb_size) +{ + /* + * If we have to call a destructor, we can't re-use the buffer? + */ + if (unlikely(nbuf->destructor != NULL)) { + return false; + } + + /* + * Check if skb has more than single user. + */ + if (unlikely(skb_shared(nbuf))) { + return false; + } + +#if IS_ENABLED(CONFIG_NF_CONNTRACK) + /* + * This check is added to avoid deadlock from nf_conntrack + * when ecm is trying to flush a rule. + */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) + if (unlikely(nbuf->nfct)) { + return false; + } +#else + if (unlikely(nbuf->_nfct)) { + return false; + } +#endif +#endif + +#ifdef CONFIG_BRIDGE_NETFILTER + /* + * This check is added to avoid deadlock from nf_bridge + * when ecm is trying to flush a rule. + */ + if (unlikely(nf_bridge_info_get(nbuf))) { + return false; + } +#endif + + /* + * If skb has security parameters set do not reuse + */ + if (unlikely(skb_sec_path(nbuf))) { + return false; + } + + if (unlikely(irqs_disabled())) + return false; + + if (unlikely(skb_shinfo(nbuf)->tx_flags & SKBTX_DEV_ZEROCOPY)) + return false; + + if (unlikely(skb_is_nonlinear(nbuf))) + return false; + + if (unlikely(skb_has_frag_list(nbuf))) + return false; + + if (unlikely(skb_shinfo(nbuf)->nr_frags)) + return false; + + if (unlikely(nbuf->fclone != SKB_FCLONE_UNAVAILABLE)) + return false; + + min_skb_size = SKB_DATA_ALIGN(min_skb_size + NET_SKB_PAD); + if (unlikely(skb_end_pointer(nbuf) - nbuf->head < min_skb_size)) + return false; + + if (unlikely(skb_end_pointer(nbuf) - nbuf->head >= nss_core_get_max_reuse())) + return false; + + if (unlikely(skb_cloned(nbuf))) + return false; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) + if (unlikely(skb_pfmemalloc(nbuf))) + return false; +#endif + + return true; +} + +/* + * nss_skb_reuse - clean up an skb + * Clears the skb to be reused as a receive buffer. + * + * NOTE: This function does any necessary reference count dropping, and + * cleans up the skbuff as if its allocated fresh. + */ +void nss_skb_reuse(struct sk_buff *nbuf) +{ + struct skb_shared_info *shinfo; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) + u8 head_frag = nbuf->head_frag; +#endif + + /* + * Reset all the necessary head state information from skb which + * we found can be recycled for NSS. + */ + skb_dst_drop(nbuf); + + shinfo = skb_shinfo(nbuf); + memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); + atomic_set(&shinfo->dataref, 1); + + memset(nbuf, 0, offsetof(struct sk_buff, tail)); + nbuf->data = nbuf->head + NET_SKB_PAD; + skb_reset_tail_pointer(nbuf); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) + nbuf->head_frag = head_frag; +#endif +} +#endif + +/* + * nss_core_send_buffer_simple_skb() + * Sends one skb to NSS FW + */ +static inline int32_t nss_core_send_buffer_simple_skb(struct nss_ctx_instance *nss_ctx, + struct h2n_desc_if_instance *desc_if, uint32_t if_num, + struct sk_buff *nbuf, uint16_t hlos_index, uint16_t flags, uint8_t buffer_type, uint16_t mss) +{ + struct h2n_descriptor *desc_ring = desc_if->desc; + struct h2n_descriptor *desc; + uint16_t bit_flags; + uint16_t mask; + uint32_t frag0phyaddr; + +#if (NSS_SKB_REUSE_SUPPORT == 1) + uint16_t sz; +#endif + + bit_flags = flags | H2N_BIT_FLAG_FIRST_SEGMENT | H2N_BIT_FLAG_LAST_SEGMENT; + if (likely(nbuf->ip_summed == CHECKSUM_PARTIAL)) { + bit_flags |= H2N_BIT_FLAG_GEN_IP_TRANSPORT_CHECKSUM; + bit_flags |= H2N_BIT_FLAG_GEN_IPV4_IP_CHECKSUM; + } else if (nbuf->ip_summed == CHECKSUM_UNNECESSARY) { + bit_flags |= H2N_BIT_FLAG_GEN_IP_TRANSPORT_CHECKSUM_NONE; + } + + mask = desc_if->size - 1; + desc = &desc_ring[hlos_index]; + +#if (NSS_SKB_REUSE_SUPPORT == 1) + /* + * Check if the caller indicates that the buffer is not to be re-used (kept in the accelerator). + */ + if (unlikely(!(bit_flags & H2N_BIT_FLAG_BUFFER_REUSABLE))) { + goto no_reuse; + } + + /* + * Since the caller is allowing re-use, we now check if the skb meets the criteria. + */ + if (unlikely(!nss_core_skb_can_reuse(nss_ctx, if_num, nbuf, nss_ctx->max_buf_size))) { + goto no_reuse; + } + + /* + * We are going to do both Tx and then Rx on this buffer, unmap the Tx + * and then map Rx over the entire buffer. + */ + sz = max((uint16_t)nss_core_skb_tail_offset(nbuf), (uint16_t)(nss_ctx->max_buf_size + NET_SKB_PAD)); + frag0phyaddr = (uint32_t)dma_map_single(nss_ctx->dev, nbuf->head, sz, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(nss_ctx->dev, frag0phyaddr))) { + goto no_reuse; + } + + /* + * We are allowed to re-use the packet + */ + nss_core_write_one_descriptor(desc, buffer_type, frag0phyaddr, if_num, + (nss_ptr_t)nbuf, (uint16_t)(nbuf->data - nbuf->head), nbuf->len, + sz, (uint32_t)nbuf->priority, mss, bit_flags); + + NSS_CORE_DMA_CACHE_MAINT((void *)desc, sizeof(*desc), DMA_TO_DEVICE); + + /* + * We are done using the skb fields and can reuse it now + */ + nss_skb_reuse(nbuf); + + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_TX_BUFFER_REUSE]); + return 1; + +no_reuse: +#endif + + bit_flags &= ~H2N_BIT_FLAG_BUFFER_REUSABLE; + frag0phyaddr = nss_core_dma_map_single(nss_ctx->dev, nbuf); + if (unlikely(dma_mapping_error(nss_ctx->dev, frag0phyaddr))) { + nss_warning("%px: DMA mapping failed for virtual address = %px", nss_ctx, nbuf->head); + return 0; + } + + nss_core_write_one_descriptor(desc, buffer_type, frag0phyaddr, if_num, + (nss_ptr_t)nbuf, (uint16_t)(nbuf->data - nbuf->head), nbuf->len, + (uint16_t)skb_end_offset(nbuf), (uint32_t)nbuf->priority, mss, bit_flags); + + NSS_CORE_DMA_CACHE_MAINT((void *)desc, sizeof(*desc), DMA_TO_DEVICE); + + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_TX_SIMPLE]); + return 1; +} + +/* + * nss_core_send_buffer_nr_frags() + * Sends frags array (NETIF_F_SG) to NSS FW + * + * Note - Opaque is set only on LAST fragment, and DISCARD is set for the rest of segments + * Used to differentiate from FRAGLIST + */ +static inline int32_t nss_core_send_buffer_nr_frags(struct nss_ctx_instance *nss_ctx, + struct h2n_desc_if_instance *desc_if, uint32_t if_num, + struct sk_buff *nbuf, uint16_t hlos_index, uint16_t flags, uint8_t buffer_type, uint16_t mss) +{ + struct h2n_descriptor *desc_ring = desc_if->desc; + struct h2n_descriptor *desc; + const skb_frag_t *frag; + dma_addr_t buffer; + uint32_t nr_frags; + uint16_t bit_flags; + int16_t i; + uint16_t mask; + + uint32_t frag0phyaddr = nss_core_dma_map_single(nss_ctx->dev, nbuf); + if (unlikely(dma_mapping_error(nss_ctx->dev, frag0phyaddr))) { + nss_warning("%px: DMA mapping failed for virtual address = %px", nss_ctx, nbuf->head); + return 0; + } + + /* + * Set the appropriate flags. + */ + bit_flags = (flags | H2N_BIT_FLAG_DISCARD); + + /* + * Reset the reuse flag for non-linear buffers. + */ + bit_flags &= ~H2N_BIT_FLAG_BUFFER_REUSABLE; + if (likely(nbuf->ip_summed == CHECKSUM_PARTIAL)) { + bit_flags |= H2N_BIT_FLAG_GEN_IP_TRANSPORT_CHECKSUM; + bit_flags |= H2N_BIT_FLAG_GEN_IPV4_IP_CHECKSUM; + } + + mask = desc_if->size - 1; + desc = &desc_ring[hlos_index]; + + /* + * First fragment/descriptor is special + */ + nss_core_write_one_descriptor(desc, buffer_type, frag0phyaddr, if_num, + (nss_ptr_t)NULL, nbuf->data - nbuf->head, nbuf->len - nbuf->data_len, + skb_end_offset(nbuf), (uint32_t)nbuf->priority, mss, bit_flags | H2N_BIT_FLAG_FIRST_SEGMENT); + + NSS_CORE_DMA_CACHE_MAINT((void *)desc, sizeof(*desc), DMA_TO_DEVICE); + + /* + * Now handle rest of the fragments. + */ + nr_frags = skb_shinfo(nbuf)->nr_frags; + BUG_ON(nr_frags > MAX_SKB_FRAGS); + for (i = 0; i < nr_frags; i++) { + frag = &skb_shinfo(nbuf)->frags[i]; + + buffer = skb_frag_dma_map(nss_ctx->dev, frag, 0, skb_frag_size(frag), DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(nss_ctx->dev, buffer))) { + nss_warning("%px: DMA mapping failed for fragment", nss_ctx); + nss_core_send_unwind_dma(nss_ctx->dev, desc_if, hlos_index, i + 1, false); + return -(i + 1); + } + + hlos_index = (hlos_index + 1) & (mask); + desc = &(desc_if->desc[hlos_index]); + + nss_core_write_one_descriptor(desc, buffer_type, buffer, if_num, + (nss_ptr_t)NULL, 0, skb_frag_size(frag), skb_frag_size(frag), + nbuf->priority, mss, bit_flags); + + NSS_CORE_DMA_CACHE_MAINT((void *)desc, sizeof(*desc), DMA_TO_DEVICE); + } + + /* + * Update bit flag for last descriptor. + * The discard flag shall be set for all fragments except the + * the last one.The NSS returns the last fragment to HLOS + * after the packet processing is done.We do need to send the + * packet buffer address (skb) in the descriptor of last segment + * when the decriptor returns from NSS the HLOS uses the + * opaque field to free the memory allocated. + */ + desc->bit_flags |= H2N_BIT_FLAG_LAST_SEGMENT; + desc->bit_flags &= ~(H2N_BIT_FLAG_DISCARD); + desc->opaque = (nss_ptr_t)nbuf; + + NSS_CORE_DMA_CACHE_MAINT((void *)desc, sizeof(*desc), DMA_TO_DEVICE); + + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_TX_NR_FRAGS]); + return i+1; +} + +/* + * nss_core_send_buffer_fraglist() + * Sends fraglist (NETIF_F_FRAGLIST) to NSS FW + * + * Note - Opaque will be set on all fragments, and DISCARD is set for the rest of segments + * Used to differentiate from FRAGS + */ +static inline int32_t nss_core_send_buffer_fraglist(struct nss_ctx_instance *nss_ctx, + struct h2n_desc_if_instance *desc_if, uint32_t if_num, + struct sk_buff *nbuf, uint16_t hlos_index, uint16_t flags, uint8_t buffer_type, uint16_t mss) +{ + struct h2n_descriptor *desc_ring = desc_if->desc; + struct h2n_descriptor *desc; + dma_addr_t buffer; + uint16_t mask; + struct sk_buff *iter; + uint16_t bit_flags; + int16_t i; + + uint32_t frag0phyaddr = nss_core_dma_map_single(nss_ctx->dev, nbuf); + if (unlikely(dma_mapping_error(nss_ctx->dev, frag0phyaddr))) { + nss_warning("%px: DMA mapping failed for virtual address = %px", nss_ctx, nbuf->head); + return 0; + } + + /* + * Copy and Set bit flags + */ + bit_flags = flags; + + /* + * Reset the reuse flag for non-linear buffers. + */ + bit_flags &= ~H2N_BIT_FLAG_BUFFER_REUSABLE; + if (likely(nbuf->ip_summed == CHECKSUM_PARTIAL)) { + bit_flags |= H2N_BIT_FLAG_GEN_IP_TRANSPORT_CHECKSUM; + bit_flags |= H2N_BIT_FLAG_GEN_IPV4_IP_CHECKSUM; + } + + mask = desc_if->size - 1; + desc = &desc_ring[hlos_index]; + + /* + * First fragment/descriptor is special. Will hold the Opaque + */ + nss_core_write_one_descriptor(desc, buffer_type, frag0phyaddr, if_num, + (nss_ptr_t)nbuf, nbuf->data - nbuf->head, nbuf->len - nbuf->data_len, + skb_end_offset(nbuf), (uint32_t)nbuf->priority, mss, bit_flags | H2N_BIT_FLAG_FIRST_SEGMENT); + + NSS_CORE_DMA_CACHE_MAINT((void *)desc, sizeof(*desc), DMA_TO_DEVICE); + + /* + * Walk the frag_list in nbuf + */ + i = 0; + skb_walk_frags(nbuf, iter) { + uint32_t nr_frags; + + buffer = nss_core_dma_map_single(nss_ctx->dev, iter); + if (unlikely(dma_mapping_error(nss_ctx->dev, buffer))) { + nss_warning("%px: DMA mapping failed for virtual address = %px", nss_ctx, iter->head); + nss_core_send_unwind_dma(nss_ctx->dev, desc_if, hlos_index, i + 1, true); + return -(i+1); + } + + /* + * We currently don't support frags[] array inside a + * fraglist. + */ + nr_frags = skb_shinfo(iter)->nr_frags; + if (unlikely(nr_frags > 0)) { + nss_warning("%px: fraglist with page data are not supported: %px\n", nss_ctx, iter); + nss_core_send_unwind_dma(nss_ctx->dev, desc_if, hlos_index, i + 1, true); + return -(i+1); + } + + /* + * Update index. + */ + hlos_index = (hlos_index + 1) & (mask); + desc = &(desc_if->desc[hlos_index]); + +#ifdef CONFIG_DEBUG_KMEMLEAK + /* + * We are holding this skb in NSS FW, let kmemleak know about it. + * + * If the skb is a fast clone (FCLONE), then nbuf is pointing to the + * cloned skb which is at the middle of the allocated block and kmemleak API + * would backtrace if passed such a pointer. We will need to get to the original + * skb pointer which kmemleak is aware of. + */ + if (iter->fclone == SKB_FCLONE_CLONE) { + kmemleak_not_leak(iter - 1); + } else { + kmemleak_not_leak(iter); + } +#endif + + nss_core_write_one_descriptor(desc, buffer_type, buffer, if_num, + (nss_ptr_t)iter, iter->data - iter->head, iter->len - iter->data_len, + skb_end_offset(iter), iter->priority, mss, bit_flags); + + NSS_CORE_DMA_CACHE_MAINT((void *)desc, sizeof(*desc), DMA_TO_DEVICE); + + i++; + } + + /* + * We need to defrag the frag_list, otherwise, if this structure is + * received back we don't know how we can reconstruct the frag_list. + * Therefore, we are clearing skb_has_fraglist. This is safe because all + * information about the segments are already sent to NSS-FW. + * So, the information will be in the NSS-FW. + */ + skb_shinfo(nbuf)->frag_list = NULL; + NSS_PKT_STATS_ADD(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_NSS_SKB_COUNT], i); + + /* + * Update bit flag for last descriptor. + */ + desc->bit_flags |= H2N_BIT_FLAG_LAST_SEGMENT; + NSS_CORE_DMA_CACHE_MAINT((void *)desc, sizeof(*desc), DMA_TO_DEVICE); + + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_TX_FRAGLIST]); + return i+1; +} + +/* + * nss_core_init_handlers() + * Initialize the handlers for all interfaces associated with core + */ +void nss_core_init_handlers(struct nss_ctx_instance *nss_ctx) +{ + struct nss_rx_cb_list *cb_list = nss_ctx->nss_rx_interface_handlers; + memset(cb_list, 0, sizeof(*cb_list) * NSS_MAX_NET_INTERFACES); +} + +/* + * nss_core_send_buffer() + * Send network buffer to NSS + */ +int32_t nss_core_send_buffer(struct nss_ctx_instance *nss_ctx, uint32_t if_num, + struct sk_buff *nbuf, uint16_t qid, + uint8_t buffer_type, uint16_t flags) +{ + int16_t count, hlos_index, nss_index, size, mask; + uint32_t segments; + struct hlos_h2n_desc_rings *h2n_desc_ring = &nss_ctx->h2n_desc_rings[qid]; + struct h2n_desc_if_instance *desc_if = &h2n_desc_ring->desc_ring; + struct h2n_descriptor *desc_ring; + struct h2n_descriptor *desc; + struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; + struct nss_if_mem_map *if_map = mem_ctx->if_map; + uint16_t mss = 0; + bool is_bounce = ((buffer_type == H2N_BUFFER_SHAPER_BOUNCE_INTERFACE) || (buffer_type == H2N_BUFFER_SHAPER_BOUNCE_BRIDGE)); + + desc_ring = desc_if->desc; + size = desc_if->size; + mask = size - 1; + + /* + * If nbuf does not have fraglist, then update nr_frags + * from frags[] array. Otherwise walk the frag_list. + */ + if (!skb_has_frag_list(nbuf)) { + segments = skb_shinfo(nbuf)->nr_frags; + BUG_ON(segments > MAX_SKB_FRAGS); + } else { + struct sk_buff *iter; + segments = 0; + skb_walk_frags(nbuf, iter) { + segments++; + } + + /* + * Check that segments do not overflow the number of descriptors + */ + if (unlikely(segments > size)) { + nss_warning("%px: Unable to fit in skb - %d segments in our descriptors", nss_ctx, segments); + return NSS_CORE_STATUS_FAILURE; + } + } + + /* + * Take a lock for queue + */ + spin_lock_bh(&h2n_desc_ring->lock); + + /* + * We need to work out if there's sufficent space in our transmit descriptor + * ring to place all the segments of a nbuf. + */ + NSS_CORE_DMA_CACHE_MAINT((void *)&if_map->h2n_nss_index[qid], sizeof(uint32_t), DMA_FROM_DEVICE); + NSS_CORE_DSB(); + nss_index = if_map->h2n_nss_index[qid]; + + hlos_index = h2n_desc_ring->hlos_index; + + count = ((nss_index - hlos_index - 1) + size) & (mask); + + if (unlikely(count < (segments + 1))) { + /* + * NOTE: tx_q_full_cnt and TX_STOPPED flags will be used + * when we will add support for DESC Q congestion management + * in future + */ + h2n_desc_ring->tx_q_full_cnt++; + h2n_desc_ring->flags |= NSS_H2N_DESC_RING_FLAGS_TX_STOPPED; + spin_unlock_bh(&h2n_desc_ring->lock); + nss_warning("%px: Data/Command Queue full reached", nss_ctx); + +#if (NSS_PKT_STATS_ENABLED == 1) + if (nss_ctx->id == NSS_CORE_0) { + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_TX_QUEUE_FULL_0]); + } else if (nss_ctx->id == NSS_CORE_1) { + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_TX_QUEUE_FULL_1]); + } else { + nss_warning("%px: Invalid nss core: %d\n", nss_ctx, nss_ctx->id); + } +#endif + + /* + * Enable de-congestion interrupt from NSS + */ + nss_hal_enable_interrupt(nss_ctx, nss_ctx->int_ctx[0].shift_factor, NSS_N2H_INTR_TX_UNBLOCKED); + + return NSS_CORE_STATUS_FAILURE_QUEUE; + } + + desc = &desc_ring[hlos_index]; + + /* + * Check if segmentation enabled. + * Configure descriptor bit flags accordingly + */ + + /* + * When CONFIG_HIGHMEM is enabled OS is giving a single big chunk buffer without + * any scattered frames. + * + * NOTE: We dont have to perform segmentation offload for packets that are being + * bounced. These packets WILL return to the HLOS for freeing or further processing. + * They will NOT be transmitted by the NSS. + */ + if (skb_is_gso(nbuf) && !is_bounce) { + mss = skb_shinfo(nbuf)->gso_size; + flags |= H2N_BIT_FLAG_SEGMENTATION_ENABLE; + } + + /* + * WARNING! : The following "is_bounce" check has a potential to cause corruption + * if things change in the NSS. This check allows fragmented packets to be sent down + * with incomplete payload information since NSS does not care about the payload content + * when packets are bounced for shaping. If it starts caring in future, then this code + * will have to change. + * + * WHY WE ARE DOING THIS - Skipping S/G processing helps with performance. + * + */ + count = 0; + if (likely((segments == 0) || is_bounce)) { + count = nss_core_send_buffer_simple_skb(nss_ctx, desc_if, if_num, + nbuf, hlos_index, flags, buffer_type, mss); + } else if (skb_has_frag_list(nbuf)) { + count = nss_core_send_buffer_fraglist(nss_ctx, desc_if, if_num, + nbuf, hlos_index, flags, buffer_type, mss); + } else { + count = nss_core_send_buffer_nr_frags(nss_ctx, desc_if, if_num, + nbuf, hlos_index, flags, buffer_type, mss); + } + + if (unlikely(count <= 0)) { + /* + * We failed and hence we need to unmap dma regions + */ + nss_warning("%px: failed to map DMA regions:%d", nss_ctx, -count); + spin_unlock_bh(&h2n_desc_ring->lock); + return NSS_CORE_STATUS_FAILURE; + } + + /* + * Sync to ensure all flushing of the descriptors are complete + */ + NSS_CORE_DSB(); + + /* + * Update our host index so the NSS sees we've written a new descriptor. + */ + hlos_index = (hlos_index + count) & mask; + h2n_desc_ring->hlos_index = hlos_index; + if_map->h2n_hlos_index[qid] = hlos_index; + + NSS_CORE_DMA_CACHE_MAINT(&if_map->h2n_hlos_index[qid], sizeof(uint32_t), DMA_TO_DEVICE); + NSS_CORE_DSB(); + +#ifdef CONFIG_DEBUG_KMEMLEAK + /* + * We are holding this skb in NSS FW, let kmemleak know about it. + * + * If the skb is a fast clone (FCLONE), then nbuf is pointing to the + * cloned skb which is at the middle of the allocated block and kmemleak API + * would backtrace if passed such a pointer. We will need to get to the original + * skb pointer which kmemleak is aware of. + */ + if (nbuf->fclone == SKB_FCLONE_CLONE) { + kmemleak_not_leak(nbuf - 1); + } else { + kmemleak_not_leak(nbuf); + } +#endif + + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_NSS_SKB_COUNT]); + + spin_unlock_bh(&h2n_desc_ring->lock); + return NSS_CORE_STATUS_SUCCESS; +} + +/* + * nss_core_send_cmd() + * Send command message to NSS + */ +int32_t nss_core_send_cmd(struct nss_ctx_instance *nss_ctx, void *msg, int size, int buf_size) +{ + struct nss_cmn_msg *ncm = (struct nss_cmn_msg *)msg; + int32_t status; + struct sk_buff *nbuf; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) { + nss_warning("%px: interface: %d type: %d message dropped as core not ready\n", nss_ctx, ncm->interface, ncm->type); + return NSS_TX_FAILURE_NOT_READY; + } + + if (nss_cmn_get_msg_len(ncm) > size) { + nss_warning("%px: interface: %d type: %d message length %d is invalid, size = %d\n", + nss_ctx, ncm->interface, ncm->type, nss_cmn_get_msg_len(ncm), size); + return NSS_TX_FAILURE_TOO_LARGE; + } + + if (buf_size > PAGE_SIZE) { + nss_warning("%px: interface: %d type: %d tx request size too large: %u", + nss_ctx, ncm->interface, ncm->type, buf_size); + return NSS_TX_FAILURE_BAD_PARAM; + } + + nbuf = dev_alloc_skb(buf_size); + if (unlikely(!nbuf)) { + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_NBUF_ALLOC_FAILS]); + nss_warning("%px: interface: %d type: %d msg dropped as command allocation failed", nss_ctx, ncm->interface, ncm->type); + return NSS_TX_FAILURE; + } + + memcpy(skb_put(nbuf, buf_size), (void *)ncm, size); + + status = nss_core_send_buffer(nss_ctx, 0, nbuf, NSS_IF_H2N_CMD_QUEUE, H2N_BUFFER_CTRL, H2N_BIT_FLAG_BUFFER_REUSABLE); + if (status != NSS_CORE_STATUS_SUCCESS) { + dev_kfree_skb_any(nbuf); + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_TX_CMD_QUEUE_FULL]); + nss_warning("%px: interface: %d type: %d unable to enqueue message status %d\n", nss_ctx, ncm->interface, ncm->type, status); + return status; + } + + nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_DATA_COMMAND_QUEUE); + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_TX_CMD_REQ]); + return status; +} + +/* + * nss_core_send_packet() + * Send data packet to NSS + */ +int32_t nss_core_send_packet(struct nss_ctx_instance *nss_ctx, struct sk_buff *nbuf, uint32_t if_num, uint32_t flag) +{ + int32_t status; + int32_t queue_id = 0; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) { + nss_warning("%px: interface: %d packet dropped as core not ready\n", nss_ctx, if_num); + return NSS_TX_FAILURE_NOT_READY; + } + +#ifdef NSS_MULTI_H2N_DATA_RING_SUPPORT + queue_id = (skb_get_queue_mapping(nbuf) & (NSS_HOST_CORES - 1)) << 1; + if (nbuf->priority) { + queue_id++; + } +#endif + status = nss_core_send_buffer(nss_ctx, if_num, nbuf, NSS_IF_H2N_DATA_QUEUE + queue_id, H2N_BUFFER_PACKET, flag); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: interface: %d unable to enqueue packet status %d\n", nss_ctx, if_num, status); + return status; + } + + nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_DATA_COMMAND_QUEUE); + +#ifdef NSS_MULTI_H2N_DATA_RING_SUPPORT + /* + * Count per queue and aggregate packet count + */ + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_TX_PACKET_QUEUE_0 + queue_id]); +#endif + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_TX_PACKET]); + return status; +} + +/* + * nss_core_ddr_info() + * Getting DDR information for NSS core + */ +uint32_t nss_core_ddr_info(struct nss_mmu_ddr_info *mmu) +{ + nss_get_ddr_info(mmu, "memory"); + return nss_soc_mem_info(); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_core.h b/feeds/ipq807x/qca-nss-drv/src/nss_core.h new file mode 100644 index 000000000..4c39bdaa7 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_core.h @@ -0,0 +1,1035 @@ +/* + ************************************************************************** + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * na_core.h + * NSS driver core header file. + */ + +#ifndef __NSS_CORE_H +#define __NSS_CORE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "nss_phys_if.h" +#include "nss_hlos_if.h" +#include "nss_oam.h" +#include "nss_data_plane.h" +#include "nss_gmac_stats.h" +#include "nss_meminfo.h" +#include "nss_stats.h" + +/* + * NSS debug macros + */ +#define nss_info_always(s, ...) pr_alert(s, ##__VA_ARGS__) + +#if (NSS_DEBUG_LEVEL < 1) +#define nss_assert(fmt, args...) +#else +#define nss_assert(c) if (!(c)) { BUG_ON(!(c)); } +#endif + +#if defined(CONFIG_DYNAMIC_DEBUG) +/* + * Compile messages for dynamic enable/disable + */ +#define nss_warning(s, ...) pr_debug("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define nss_info(s, ...) pr_debug("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define nss_trace(s, ...) pr_debug("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#else + +/* + * Statically compile messages at different levels + */ +#if (NSS_DEBUG_LEVEL < 2) +#define nss_warning(s, ...) +#else +#define nss_warning(s, ...) pr_warn("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#endif + +#if (NSS_DEBUG_LEVEL < 3) +#define nss_info(s, ...) +#else +#define nss_info(s, ...) pr_notice("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#endif + +#if (NSS_DEBUG_LEVEL < 4) +#define nss_trace(s, ...) +#else +#define nss_trace(s, ...) pr_info("%s[%d]:" s, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#endif +#endif + +#if (NSS_PKT_STATS_ENABLED == 1) +#define NSS_PKT_STATS_INC(x) nss_pkt_stats_inc((x)) +#define NSS_PKT_STATS_DEC(x) nss_pkt_stats_dec((x)) +#define NSS_PKT_STATS_ADD(x, i) nss_pkt_stats_add((x), (i)) +#define NSS_PKT_STATS_SUB(x, i) nss_pkt_stats_sub((x), (i)) +#define NSS_PKT_STATS_READ(x) nss_pkt_stats_read(x) +#else +#define NSS_PKT_STATS_INC(x) +#define NSS_PKT_STATS_DEC(x) +#define NSS_PKT_STATS_ADD(x, i) +#define NSS_PKT_STATS_SUB(x, i) +#define NSS_PKT_STATS_READ(x) +#endif + +/* + * Cache operation + */ +#define NSS_CORE_DSB() dsb(sy) +#define NSS_CORE_DMA_CACHE_MAINT(start, size, dir) nss_core_dma_cache_maint(start, size, dir) + +/* + * nss_core_dma_cache_maint() + * Perform the appropriate cache op based on direction + */ +static inline void nss_core_dma_cache_maint(void *start, uint32_t size, int direction) +{ + switch (direction) { + case DMA_FROM_DEVICE:/* invalidate only */ + dmac_inv_range(start, start + size); + break; + case DMA_TO_DEVICE:/* writeback only */ + dmac_clean_range(start, start + size); + break; + case DMA_BIDIRECTIONAL:/* writeback and invalidate */ + dmac_flush_range(start, start + size); + break; + default: + BUG(); + } +} + +#define NSS_DEVICE_IF_START NSS_PHYSICAL_IF_START + +#define NSS_IS_IF_TYPE(type, if_num) ((if_num >= NSS_##type##_IF_START) && (if_num < (NSS_##type##_IF_START + NSS_MAX_##type##_INTERFACES))) + +/* + * Default payload size for NSS buffers + */ +#define NSS_NBUF_PAYLOAD_SIZE NSS_EMPTY_BUFFER_SIZE +#define NSS_NBUF_PAD_EXTRA 256 +#define NSS_NBUF_ETH_EXTRA 192 + +/* + * N2H/H2N Queue IDs + */ +#define NSS_IF_N2H_EMPTY_BUFFER_RETURN_QUEUE 0 +#define NSS_IF_N2H_DATA_QUEUE_0 1 +#define NSS_IF_N2H_DATA_QUEUE_1 2 +#define NSS_IF_N2H_DATA_QUEUE_2 3 +#define NSS_IF_N2H_DATA_QUEUE_3 4 + +#define NSS_IF_H2N_EMPTY_BUFFER_QUEUE 0 +#define NSS_IF_H2N_CMD_QUEUE 1 +#define NSS_IF_H2N_EMPTY_PAGED_BUFFER_QUEUE 2 +#define NSS_IF_H2N_DATA_QUEUE 3 + +/* + * NSS Interrupt Causes + */ +#define NSS_INTR_CAUSE_INVALID 0 +#define NSS_INTR_CAUSE_QUEUE 1 +#define NSS_INTR_CAUSE_NON_QUEUE 2 +#define NSS_INTR_CAUSE_EMERGENCY 3 +#define NSS_INTR_CAUSE_SDMA 4 + +/* + * NSS Core Status + */ +#define NSS_CORE_STATUS_SUCCESS 0 +#define NSS_CORE_STATUS_FAILURE 1 +#define NSS_CORE_STATUS_FAILURE_QUEUE 2 + +/* + * NSS context magic + */ +#define NSS_CTX_MAGIC 0xDEDEDEDE + +/* + * Number of n2h descriptor rings + */ +#define NSS_N2H_DESC_RING_NUM 15 +#define NSS_H2N_DESC_RING_NUM 16 + +/* + * NSS maximum data queue per core + */ +#define NSS_MAX_DATA_QUEUE 4 + +/* + * NSS maximum IRQ per interrupt instance/core + */ +#if defined(NSS_HAL_IPQ807x_SUPPORT) || defined(NSS_HAL_IPQ60XX_SUPPORT) +#define NSS_MAX_IRQ_PER_INSTANCE 6 +#define NSS_MAX_IRQ_PER_CORE 10 /* must match with NSS_HAL_N2H_INTR_PURPOSE_MAX */ +#elif defined(NSS_HAL_IPQ50XX_SUPPORT) +#define NSS_MAX_IRQ_PER_CORE 8 +#else +#define NSS_MAX_IRQ_PER_INSTANCE 1 +#define NSS_MAX_IRQ_PER_CORE 2 +#endif + +/* + * NSS maximum clients + */ +#define NSS_MAX_CLIENTS 12 + +/* + * Maximum number of service code NSS supports + */ +#define NSS_MAX_SERVICE_CODE 256 + +/* + * Interrupt cause processing weights + */ +#define NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT 64 +#define NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT 64 +#define NSS_EMPTY_BUFFER_RETURN_PROCESSING_WEIGHT 64 +#define NSS_TX_UNBLOCKED_PROCESSING_WEIGHT 1 + +/* + * Cache line size of the NSS. + */ +#define NSS_CACHE_LINE_SIZE 32 + +/* + * Statistics struct + * + * INFO: These numbers are based on previous generation chip + * These may change in future + */ + +/* + * NSS Frequency Defines and Values + * + * INFO: The LOW and MAX value together describe the "performance" band that we should operate the frequency at. + * + */ +#define NSS_FREQ_SCALE_NA 0xFAADFAAD /* Frequency scale not supported */ +#define NSS_FREQ_NA 0x0 /* Instructions Per ms Min */ + +#define NSS_FREQ_110 110000000 /* Frequency in hz */ +#define NSS_FREQ_110_MIN 0x03000 /* Instructions Per ms Min */ +#define NSS_FREQ_110_MAX 0x07000 /* Instructions Per ms Max */ + +#define NSS_FREQ_187 187200000 /* Frequency in hz */ +#if defined(NSS_HAL_IPQ60XX_SUPPORT) +#define NSS_FREQ_187_MIN 0x03000 /* Instructions Per ms Min */ +#define NSS_FREQ_187_MAX 0x10000 /* Instructions Per ms Max */ +#else +#define NSS_FREQ_187_MIN 0x03000 /* Instructions Per ms Min */ +#define NSS_FREQ_187_MAX 0x07000 /* Instructions Per ms Max */ +#endif + +#define NSS_FREQ_275 275000000 /* Frequency in hz */ +#define NSS_FREQ_275_MIN 0x03000 /* Instructions Per ms Min */ +#define NSS_FREQ_275_MAX 0x07000 /* Instructions Per ms Max */ + +#define NSS_FREQ_550 550000000 /* Frequency in hz */ +#define NSS_FREQ_550_MIN 0x07000 /* Instructions Per ms Min */ +#define NSS_FREQ_550_MAX 0x08000 /* Instructions Per ms Max */ + +#define NSS_FREQ_600 600000000 /* Frequency in hz */ +#define NSS_FREQ_600_MIN 0x07000 /* Instructions Per ms Min */ +#define NSS_FREQ_600_MAX 0x08000 /* Instructions Per ms Max */ + +#define NSS_FREQ_733 733000000 /* Frequency in hz */ +#define NSS_FREQ_733_MIN 0x07000 /* Instructions Per ms Min */ +#define NSS_FREQ_733_MAX 0x25000 /* Instructions Per ms Max */ + +#define NSS_FREQ_748 748800000 /* Frequency in hz */ +#if defined(NSS_HAL_IPQ60XX_SUPPORT) +#define NSS_FREQ_748_MIN 0x10000 /* Instructions Per ms Min */ +#define NSS_FREQ_748_MAX 0x18000 /* Instructions Per ms Max */ +#else +#define NSS_FREQ_748_MIN 0x07000 /* Instructions Per ms Min */ +#define NSS_FREQ_748_MAX 0x14000 /* Instructions Per ms Max */ +#endif + +#define NSS_FREQ_800 800000000 /* Frequency in hz */ +#define NSS_FREQ_800_MIN 0x07000 /* Instructions Per ms Min */ +#define NSS_FREQ_800_MAX 0x25000 /* Instructions Per ms Max */ + +#define NSS_FREQ_850 850000000 /* Frequency in hz */ +#define NSS_FREQ_850_MIN 0x07000 /* Instructions Per ms Min */ +#define NSS_FREQ_850_MAX 0x0c000 /* Instructions Per ms Max */ + +#define NSS_FREQ_1000 1000000000 /* Frequency in hz */ +#define NSS_FREQ_1000_MIN 0x0c000 /* Instructions Per ms Min */ +#define NSS_FREQ_1000_MAX 0x25000 /* Instructions Per ms Max */ + +#define NSS_FREQ_1497 1497600000 /* Frequency in hz */ +#if defined(NSS_HAL_IPQ60XX_SUPPORT) +#define NSS_FREQ_1497_MIN 0x18000 /* Instructions Per ms Min */ +#define NSS_FREQ_1497_MAX 0x25000 /* Instructions Per ms Max */ +#else +#define NSS_FREQ_1497_MIN 0x14000 /* Instructions Per ms Min */ +#define NSS_FREQ_1497_MAX 0x25000 /* Instructions Per ms Max */ +#endif + +#define NSS_FREQ_1689 1689600000 /* Frequency in hz */ +#define NSS_FREQ_1689_MIN 0x14000 /* Instructions Per ms Min */ +#define NSS_FREQ_1689_MAX 0x25000 /* Instructions Per ms Max */ + +#if (NSS_DT_SUPPORT == 1) +#define NSSTCM_FREQ 400000000 /* NSS TCM Frequency in Hz */ + +/* + * NSS Clock names + */ +#define NSS_CORE_CLK "nss-core-clk" +#define NSS_TCM_SRC_CLK "nss-tcm-src" +#define NSS_TCM_CLK "nss-tcm-clk" +#define NSS_FABRIC0_CLK "nss-fab0-clk" +#define NSS_FABRIC1_CLK "nss-fab1-clk" + +/* + * NSS Fabric speeds + */ +#define NSS_FABRIC0_TURBO 533000000 +#define NSS_FABRIC1_TURBO 266500000 +#define NSS_FABRIC0_NOMINAL 400000000 +#define NSS_FABRIC1_NOMINAL 200000000 +#define NSS_FABRIC0_IDLE 133333000 +#define NSS_FABRIC1_IDLE 133333000 +#endif + +/* Default NSS packet queue limit. */ +#define NSS_DEFAULT_QUEUE_LIMIT 256 + +/* + * Gives us important data from NSS platform data + */ +extern struct nss_top_instance nss_top_main; + +/* + * NSS core state + */ +enum nss_core_state { + NSS_CORE_STATE_UNINITIALIZED = 0, + NSS_CORE_STATE_INITIALIZED, + /* + * in following cases, only interrupts work + */ + NSS_CORE_STATE_FW_DEAD = 2, + NSS_CORE_STATE_FW_DUMP = 4, + NSS_CORE_STATE_PANIC = 8, +}; + +/* + * Forward declarations + */ +struct nss_top_instance; +struct nss_ctx_instance; +struct int_ctx_instance; +struct net_dev_priv_instance; + +/* + * Network device private data instance + */ +struct netdev_priv_instance { + struct int_ctx_instance *int_ctx; /* Back pointer to interrupt context */ +}; + +/* + * Interrupt context instance (one per queue per NSS core) + */ +struct int_ctx_instance { + struct nss_ctx_instance *nss_ctx; + /* Back pointer to NSS context of core that + owns this interrupt */ + uint32_t irq; /* HLOS IRQ numbers bind to this instance */ + uint32_t shift_factor; /* Shift factor for this IRQ queue */ + uint32_t cause; /* Interrupt cause carried forward to BH */ + struct napi_struct napi;/* NAPI handler */ +}; + +/* + * N2H descriptor ring information + */ +struct hlos_n2h_desc_ring { + struct n2h_desc_if_instance desc_ring; + /* Descriptor ring */ + uint32_t hlos_index; /* Current HLOS index for this ring */ + struct sk_buff *head; /* First segment of an skb fraglist */ + struct sk_buff *tail; /* Last segment received of an skb fraglist */ + struct sk_buff *jumbo_start; /* First segment of an skb with frags[] */ +}; + +/* + * H2N descriptor ring information + */ +struct hlos_h2n_desc_rings { + struct h2n_desc_if_instance desc_ring; /* Descriptor ring */ + uint32_t hlos_index; + spinlock_t lock; /* Lock to save from simultaneous access */ + uint32_t flags; /* Flags */ + uint64_t tx_q_full_cnt; /* Descriptor queue full count */ +}; + +#define NSS_H2N_DESC_RING_FLAGS_TX_STOPPED 0x1 /* Tx has been stopped for this queue */ + +/* + * struct nss_shaper_bounce_registrant + * Registrant detail for shaper bounce operations + */ +struct nss_shaper_bounce_registrant { + nss_shaper_bounced_callback_t bounced_callback; /* Invoked for each shaper bounced packet returned from the NSS */ + void *app_data; /* Argument given to the callback */ + struct module *owner; /* Owning module of the callback + arg */ + bool registered; + volatile bool callback_active; /* true when the bounce callback is being called */ +}; + +/* + * CB function declarations + */ +typedef void (*nss_core_rx_callback_t)(struct nss_ctx_instance *, struct nss_cmn_msg *, void *); + +/* + * NSS Rx per interface callback structure + */ +struct nss_rx_cb_list { + nss_if_rx_msg_callback_t msg_cb; + nss_core_rx_callback_t cb; + void *app_data; +}; + +/* + * NSS core <-> subsystem data plane registration related paramaters. + * This struct is filled with if_register/data_plane register APIs and + * retrieved when handling a data packet/skb destined to that subsystem. + */ +struct nss_subsystem_dataplane_register { + nss_phys_if_rx_callback_t cb; /* callback to be invoked */ + nss_phys_if_xmit_callback_t xmit_cb; + /* Callback to be invoked for sending the packets to the transmit path */ + nss_phys_if_rx_ext_data_callback_t ext_cb; + /* Extended data plane callback to be invoked. + This is needed if driver needs extended handling + of data packet before giving to stack */ + void *app_data; /* additional info passed during callback(for future use) */ + struct net_device *ndev; /* Netdevice associated with the interface */ + uint32_t features; /* skb types supported by this subsystem */ + uint32_t type; /* Indicates the type of this data plane */ +}; + +/* + * Holds statistics for every worker thread on a core + */ +struct nss_worker_thread_stats { + struct nss_project_irq_stats *irq_stats; +}; + +/* + * NSS context instance (one per NSS core) + */ +struct nss_ctx_instance { + struct nss_top_instance *nss_top; + /* Back pointer to NSS Top */ + struct device *dev; /* Pointer to the original device from probe */ + struct net_device napi_ndev; /* Dummy_netdev for NAPI */ + uint32_t id; /* Core ID for this instance */ + void __iomem *nmap; /* Pointer to NSS CSM registers */ + void __iomem *vmap; /* Virt mem pointer to virtual register map */ + void __iomem *qgic_map; /* Virt mem pointer to QGIC register */ + uint32_t nphys; /* Phys mem pointer to CSM register map */ + uint32_t vphys; /* Phys mem pointer to virtual register map */ + uint32_t qgic_phys; /* Phys mem pointer to QGIC register map */ + uint32_t load; /* Load address for this core */ + struct nss_meminfo_ctx meminfo_ctx; /* Meminfo context */ + enum nss_core_state state; /* State of NSS core */ + uint32_t c2c_start; /* C2C start address */ + uint32_t num_irq; /* IRQ numbers per queue */ + struct int_ctx_instance int_ctx[NSS_MAX_IRQ_PER_CORE]; + /* Interrupt context instances for each queue */ + struct hlos_h2n_desc_rings h2n_desc_rings[NSS_H2N_DESC_RING_NUM]; + /* Host to NSS descriptor rings */ + struct hlos_n2h_desc_ring n2h_desc_ring[NSS_N2H_DESC_RING_NUM]; + /* NSS to Host descriptor rings */ + uint16_t rps_en; /* N2H Enable Multiple queues for Data Packets */ + uint16_t n2h_mitigate_en; /* N2H mitigation */ + uint32_t max_buf_size; /* Maximum buffer size */ + uint32_t buf_sz_allocated; /* size of bufs allocated from host */ + nss_cmn_queue_decongestion_callback_t queue_decongestion_callback[NSS_MAX_CLIENTS]; + /* Queue decongestion callbacks */ + void *queue_decongestion_ctx[NSS_MAX_CLIENTS]; + /* Queue decongestion callback contexts */ + nss_cmn_service_code_callback_t service_code_callback[NSS_MAX_SERVICE_CODE]; + /* Service code callbacks */ + void *service_code_ctx[NSS_MAX_SERVICE_CODE]; + /* Service code callback contexts */ + spinlock_t decongest_cb_lock; /* Lock to protect queue decongestion cb table */ + uint16_t phys_if_mtu[NSS_MAX_PHYSICAL_INTERFACES]; + /* Current MTU value of physical interface */ + uint32_t worker_thread_count; /* Number of NSS core worker threads for statistics */ + uint32_t irq_count; /* Number of NSS core IRQs for statistics */ + struct nss_worker_thread_stats *wt_stats; + /* Worker thread statistics */ + struct nss_unaligned_stats unaligned_stats; + /* Unaligned emulation performance statistics */ + struct nss_rx_cb_list nss_rx_interface_handlers[NSS_MAX_NET_INTERFACES]; + /* NSS interface callback handlers */ + struct nss_subsystem_dataplane_register subsys_dp_register[NSS_MAX_NET_INTERFACES]; + /* Subsystem registration data */ + uint32_t magic; + /* Magic protection */ +}; + +/* + * Main NSS context structure (singleton) + */ +struct nss_top_instance { + uint8_t num_nss; /* Number of NSS cores supported */ + uint8_t num_phys_ports; /* Number of physical ports supported */ + uint32_t clk_src; /* Clock source: default/alternate */ + spinlock_t lock; /* Big lock for NSS driver */ + spinlock_t stats_lock; /* Statistics lock */ + struct mutex wq_lock; /* Mutex for NSS Work queue function */ + struct dentry *top_dentry; /* Top dentry for nss */ + struct dentry *stats_dentry; /* Top dentry for nss stats */ + struct dentry *strings_dentry; /* Top dentry for nss stats strings */ + struct dentry *project_dentry; /* per-project stats dentry */ + struct nss_ctx_instance nss[NSS_MAX_CORES]; + /* NSS contexts */ + /* + * Network processing handler core ids (CORE0/CORE1) for various interfaces + */ + uint8_t phys_if_handler_id[NSS_MAX_PHYSICAL_INTERFACES]; + uint8_t virt_if_handler_id; + uint8_t gre_redir_handler_id; + uint8_t gre_redir_lag_us_handler_id; + uint8_t gre_redir_lag_ds_handler_id; + uint8_t gre_tunnel_handler_id; + uint8_t shaping_handler_id; + uint8_t ipv4_handler_id; + uint8_t ipv4_reasm_handler_id; + uint8_t ipv6_handler_id; + uint8_t ipv6_reasm_handler_id; + uint8_t crypto_handler_id; + uint8_t ipsec_handler_id; + uint8_t wlan_handler_id; + uint8_t tun6rd_handler_id; + uint8_t wifi_handler_id; + uint8_t ppe_handler_id; + uint8_t pptp_handler_id; + uint8_t pppoe_handler_id; + uint8_t l2tpv2_handler_id; + uint8_t dtls_handler_id; + uint8_t gre_handler_id; + uint8_t map_t_handler_id; + uint8_t tunipip6_handler_id; + uint8_t frequency_handler_id; + uint8_t sjack_handler_id; + uint8_t capwap_handler_id; + uint8_t tstamp_handler_id; + uint8_t portid_handler_id; + uint8_t oam_handler_id; + uint8_t edma_handler_id; + uint8_t bridge_handler_id; + uint8_t trustsec_tx_handler_id; + uint8_t vlan_handler_id; + uint8_t qvpn_handler_id; + uint8_t pvxlan_handler_id; + uint8_t igs_handler_id; + uint8_t gre_redir_mark_handler_id; + uint8_t clmap_handler_id; + uint8_t vxlan_handler_id; + uint8_t rmnet_rx_handler_id; + uint8_t match_handler_id; + uint8_t tls_handler_id; + uint8_t mirror_handler_id; + uint8_t wmdb_handler_id; + uint8_t dma_handler_id; + + /* + * Data/Message callbacks for various interfaces + */ + nss_phys_if_msg_callback_t phys_if_msg_callback[NSS_MAX_PHYSICAL_INTERFACES]; + /* Physical interface event callback functions */ + nss_virt_if_msg_callback_t virt_if_msg_callback[NSS_MAX_VIRTUAL_INTERFACES]; + /* Virtual interface messsage callback functions */ + nss_ipv4_msg_callback_t ipv4_callback; + /* IPv4 sync/establish callback function */ + nss_ipv6_msg_callback_t ipv6_callback; + /* IPv6 sync/establish callback function */ + nss_ipsec_msg_callback_t ipsec_encap_callback; + nss_ipsec_msg_callback_t ipsec_decap_callback; + /* IPsec event callback function */ + nss_crypto_msg_callback_t crypto_msg_callback; + nss_crypto_cmn_msg_callback_t crypto_cmn_msg_callback; + nss_crypto_buf_callback_t crypto_buf_callback; + nss_crypto_pm_event_callback_t crypto_pm_callback; + /* crypto interface callback functions */ + nss_profiler_callback_t profiler_callback[NSS_MAX_CORES]; + /* Profiler interface callback function */ + nss_tun6rd_msg_callback_t tun6rd_msg_callback; + /* 6rd tunnel interface event callback function */ + nss_wifi_msg_callback_t wifi_msg_callback; + /* wifi interface event callback function */ + nss_l2tpv2_msg_callback_t l2tpv2_msg_callback; + /* l2tP tunnel interface event callback function */ + nss_dtls_msg_callback_t dtls_msg_callback; /* dtls interface event callback */ + + nss_gre_tunnel_msg_callback_t gre_tunnel_msg_callback; /* gre tunnel interface event callback */ + + nss_map_t_msg_callback_t map_t_msg_callback; + /* map-t interface event callback function */ + nss_gre_msg_callback_t gre_msg_callback; + /* gre interface event callback function */ + nss_gre_data_callback_t gre_inner_data_callback; + /* gre inner data callback function */ + nss_gre_data_callback_t gre_outer_data_callback; + /* gre outer data callback function */ + nss_tunipip6_msg_callback_t tunipip6_msg_callback; + /* ipip6 tunnel interface event callback function */ + nss_pptp_msg_callback_t pptp_msg_callback; + /* PPTP tunnel interface event callback function */ + nss_pppoe_msg_callback_t pppoe_msg_callback; + /* PPPoE interface event callback function */ + struct nss_shaper_bounce_registrant bounce_interface_registrants[NSS_MAX_NET_INTERFACES]; + /* Registrants for interface shaper bounce operations */ + struct nss_shaper_bounce_registrant bounce_bridge_registrants[NSS_MAX_NET_INTERFACES]; + /* Registrants for bridge shaper bounce operations */ + nss_lag_event_callback_t lag_event_callback; + /* Registrants for lag operations */ + nss_oam_msg_callback_t oam_callback; + /* OAM call back */ + nss_edma_msg_callback_t edma_callback; + /* EDMA callback */ + nss_bridge_msg_callback_t bridge_callback; + /* Bridge callback */ + nss_vlan_msg_callback_t vlan_callback; + /* Vlan callback */ + nss_wifili_msg_callback_t wifili_msg_callback; + /* wifili interface event callback function */ + nss_ipsec_cmn_msg_callback_t ipsec_cmn_msg_callback; + /* IPSEC common interface event callback function */ + nss_qvpn_msg_callback_t qvpn_msg_callback; + /* QVPN interface event callback function */ + nss_rmnet_rx_msg_callback_t rmnet_rx_msg_callback[NSS_MAX_VIRTUAL_INTERFACES]; + /* Virtual interface messsage callback functions */ + nss_wifi_mac_db_msg_callback_t wifi_mac_db_msg_callback; + /* wifi mac database event callback function */ + + uint32_t dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_MAX]; + + /* + * Interface contexts (non network device) + */ + void *ipv4_ctx; /* IPv4 connection manager context */ + void *ipv6_ctx; /* IPv6 connection manager context */ + void *crypto_ctx; /* Crypto interface context */ + void *crypto_pm_ctx; /* Crypto PM context */ + void *profiler_ctx[NSS_MAX_CORES]; + /* Profiler interface context */ + void *ipsec_encap_ctx; /* IPsec encap context */ + void *ipsec_decap_ctx; /* IPsec decap context */ + void *oam_ctx; /* oam context */ + void *edma_ctx; /* edma context */ + void *bridge_ctx; /* Bridge context */ + void *vlan_ctx; /* Vlan context */ + + /* + * Statistics for various interfaces + */ + atomic64_t stats_drv[NSS_DRV_STATS_MAX]; + /* Hlos driver statistics */ + uint64_t stats_gmac[NSS_MAX_PHYSICAL_INTERFACES][NSS_GMAC_STATS_MAX]; + /* GMAC statistics */ + uint64_t stats_node[NSS_MAX_NET_INTERFACES][NSS_STATS_NODE_MAX]; + /* IPv4 statistics per interface */ + bool nss_hal_common_init_done; + + uint16_t prev_mtu_sz; /* mtu sz needed as of now */ + uint16_t crypto_enabled; /* check if crypto is enabled on the platform */ + + /* + * TODO: Review and update following fields + */ + uint64_t last_rx_jiffies; /* Time of the last RX message from the NA in jiffies */ + struct nss_hal_ops *hal_ops; /* nss_hal ops for this target platform */ + struct nss_data_plane_ops *data_plane_ops; + /* nss_data_plane ops for this target platform */ +}; + +#if (NSS_PKT_STATS_ENABLED == 1) +/* + * nss_pkt_stats_inc() + */ +static inline void nss_pkt_stats_inc(atomic64_t *stat) +{ + atomic64_inc(stat); +} + +/* + * nss_pkt_stats_dec() + */ +static inline void nss_pkt_stats_dec(atomic64_t *stat) +{ + atomic64_dec(stat); +} + +/* + * nss_pkt_stats_add() + */ +static inline void nss_pkt_stats_add(atomic64_t *stat, uint32_t pkt) +{ + atomic64_add(pkt, stat); +} + +/* + * nss_pkt_stats_sub() + */ +static inline void nss_pkt_stats_sub(atomic64_t *stat, uint32_t pkt) +{ + atomic64_sub(pkt, stat); +} + +/* + * nss_pkt_stats_read() + */ +static inline uint64_t nss_pkt_stats_read(atomic64_t *stat) +{ + return atomic64_read(stat); +} + +#endif + +/* + * NSS Statistics and Data for User Space + */ +struct nss_cmd_buffer { + uint32_t current_freq; /* Current Running Freq of NSS */ + int32_t auto_scale; /* Enable or Disable auto_scale */ + int32_t max_freq; /* Maximum supported frequency index value */ + uint32_t register_addr; /* register addr buffer */ + uint32_t register_data; /* register data buffer */ + uint32_t average_inst; /* average of inst for nss core */ + uint32_t coredump; /* cmd coredump buffer */ +}; +extern struct nss_cmd_buffer nss_cmd_buf; + +/* + * The scales for NSS + */ +typedef enum nss_freq_scales { + NSS_FREQ_LOW_SCALE = 0, + NSS_FREQ_MID_SCALE = 1, + NSS_FREQ_HIGH_SCALE = 2, + NSS_FREQ_MAX_SCALE = 3, +} nss_freq_scales_t; + +/* + * NSS Core Statistics and Frequencies + */ +#define NSS_SAMPLE_BUFFER_SIZE 4 /* Ring Buffer should be a Size of two */ +#define NSS_SAMPLE_BUFFER_MASK (NSS_SAMPLE_BUFFER_SIZE - 1) +#define NSS_FREQUENCY_SCALE_RATE_LIMIT_UP 2 /* Adjust the Rate of Frequency Switching Up */ +#define NSS_FREQUENCY_SCALE_RATE_LIMIT_DOWN 60000 /* Adjust the Rate of Frequency Switching Down */ +#define NSS_MESSAGE_RATE_LIMIT 15000 /* Adjust the Rate of Displaying Statistic Messages */ + +/* + * NSS Frequency Scale Info + * + * INFO: Contains the Scale information per Frequency + * Per Scale information needed to Program PLL and make switching decisions + */ +struct nss_scale_info { + uint32_t frequency; /* Frequency in Mhz */ + uint32_t minimum; /* Minimum INST_CNT per Sec */ + uint32_t maximum; /* Maximum INST_CNT per Sec */ +}; + +/* + * NSS Runtime Sample Structure + * + * INFO: Contains the runtime statistic of the NSS core + * Also contains the per frequency scale array + */ +struct nss_runtime_sampling { + struct nss_scale_info freq_scale[NSS_FREQ_MAX_SCALE]; /* NSS Max Scale Per Freq */ + nss_freq_scales_t freq_scale_index; /* Current Freq Index */ + uint32_t freq_scale_ready; /* Allow Freq Scaling */ + uint32_t freq_scale_rate_limit_up; /* Scaling Change Rate Limit */ + uint32_t freq_scale_rate_limit_down; /* Scaling Change Rate Limit */ + uint32_t buffer[NSS_SAMPLE_BUFFER_SIZE]; /* Sample Ring Buffer */ + uint32_t buffer_index; /* Running Buffer Index */ + uint32_t sum; /* Total INST_CNT SUM */ + uint32_t sample_count; /* Number of Samples stored in Ring Buffer */ + uint32_t average; /* Average of INST_CNT */ + uint32_t message_rate_limit; /* Debug Message Rate Limit */ + uint32_t initialized; /* Flag to check for adequate initial samples */ +}; + +/* + * cpu_utilization + */ +struct nss_freq_cpu_usage { + uint32_t used; /* CPU utilization at a certain frequency percentage */ + uint32_t max_ins; /* Maximum instructions that can be executed in 1ms at the current frequency + This value is calculated by diving frequency by 1000. */ + uint32_t total; /* Total usage added over a time of NSS_FREQ_USG_AVG_FREQUENCY milliseconds*/ + uint32_t max; /* Maximum CPU usage since the boot (%) */ + uint32_t min; /* Minimum CPU usage since the boot (%) */ + uint32_t avg_up; /* Actual upper bound of the CPU USAGE (%)*/ + uint16_t avg_ctr; /* Averaging counter */ +}; + +#if (NSS_DT_SUPPORT == 1) +/* + * nss_feature_enabled + */ +enum nss_feature_enabled { + NSS_FEATURE_NOT_ENABLED = 0, /* Feature is not enabled on this core */ + NSS_FEATURE_ENABLED, /* Feature is enabled on this core */ +}; + +/* + * nss_platform_data + * Platform data per core + */ +struct nss_platform_data { + uint32_t id; /* NSS core ID */ + uint32_t num_queue; /* No. of queues supported per core */ + uint32_t num_irq; /* No. of irq binded per queue */ + uint32_t irq[NSS_MAX_IRQ_PER_CORE]; /* IRQ numbers per queue */ + void __iomem *nmap; /* Virtual addr of NSS CSM space */ + void __iomem *vmap; /* Virtual addr of NSS virtual register map */ + void __iomem *qgic_map; /* Virtual addr of QGIC interrupt register */ + uint32_t nphys; /* Physical addr of NSS CSM space */ + uint32_t vphys; /* Physical addr of NSS virtual register map */ + uint32_t qgic_phys; /* Physical addr of QGIC virtual register map */ + uint32_t load_addr; /* Load address of NSS firmware */ + + enum nss_feature_enabled capwap_enabled; + /* Does this core handle capwap? */ + enum nss_feature_enabled crypto_enabled; + /* Does this core handle crypto? */ + enum nss_feature_enabled dtls_enabled; + /* Does this core handle DTLS sessions ? */ + enum nss_feature_enabled gre_redir_enabled; + /* Does this core handle gre_redir Tunnel ? */ + enum nss_feature_enabled gre_tunnel_enabled; + /* Does this core handle gre_tunnel Tunnel ? */ + enum nss_feature_enabled ipsec_enabled; + /* Does this core handle IPsec? */ + enum nss_feature_enabled ipv4_enabled; + /* Does this core handle IPv4? */ + enum nss_feature_enabled ipv4_reasm_enabled; + /* Does this core handle IPv4 reassembly? */ + enum nss_feature_enabled ipv6_enabled; + /* Does this core handle IPv6? */ + enum nss_feature_enabled ipv6_reasm_enabled; + /* Does this core handle IPv6 reassembly? */ + enum nss_feature_enabled l2tpv2_enabled; + /* Does this core handle l2tpv2 Tunnel ? */ + enum nss_feature_enabled map_t_enabled; + /* Does this core handle map-t */ + enum nss_feature_enabled gre_enabled; + /* Does this core handle GRE */ + enum nss_feature_enabled oam_enabled; + /* Does this core handle oam? */ + enum nss_feature_enabled ppe_enabled; + /* Does this core handle ppe ? */ + enum nss_feature_enabled pppoe_enabled; + /* Does this core handle pppoe? */ + enum nss_feature_enabled pptp_enabled; + /* Does this core handle pptp Tunnel ? */ + enum nss_feature_enabled portid_enabled; + /* Does this core handle portid? */ + enum nss_feature_enabled shaping_enabled; + /* Does this core handle shaping ? */ + enum nss_feature_enabled tstamp_enabled; + /* Does this core handle timestamping? */ + enum nss_feature_enabled turbo_frequency; + /* Does this core support turbo frequencies */ + enum nss_feature_enabled tun6rd_enabled; + /* Does this core handle 6rd Tunnel ? */ + enum nss_feature_enabled tunipip6_enabled; + /* Does this core handle ipip6 Tunnel ? */ + enum nss_feature_enabled wlanredirect_enabled; + /* Does this core handle WLAN redirect? */ + enum nss_feature_enabled wifioffload_enabled; + /* Does this core handle WIFI OFFLOAD? */ + enum nss_feature_enabled bridge_enabled; + /* Does this core handle bridge configuration */ + enum nss_feature_enabled vlan_enabled; + /* Does this core handle vlan configuration */ + enum nss_feature_enabled qvpn_enabled; + /* Does this core handle QVPN Tunnel ? */ + enum nss_feature_enabled pvxlan_enabled; + /* Does this core handle pvxlan? */ + enum nss_feature_enabled igs_enabled; + /* Does this core handle igs? */ + enum nss_feature_enabled gre_redir_mark_enabled; + /* Does this core handle GRE redir mark? */ + enum nss_feature_enabled clmap_enabled; + /* Does this core handle clmap? */ + enum nss_feature_enabled vxlan_enabled; + /* Does this core handle vxlan tunnel? */ + enum nss_feature_enabled rmnet_rx_enabled; + /* Does this core handle rmnet rx? */ + enum nss_feature_enabled match_enabled; + /* Does this core handle match node? */ + enum nss_feature_enabled tls_enabled; + /* Does this core handle TLS Tunnel ? */ + enum nss_feature_enabled mirror_enabled; + /* Does this core handle mirror? */ +}; +#endif + +/* + * nss_core_log_msg_failures() + * Driver function for logging failed messages. + */ +static inline void nss_core_log_msg_failures(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm) +{ + if ((ncm->response == NSS_CMN_RESPONSE_ACK) || (ncm->response == NSS_CMN_RESPONSE_NOTIFY)) { + return; + } + + /* + * TODO: Is it worth doing value to name on these values? + */ + nss_warning("%px: msg failure - interface: %d, type: %d, response: %d, error: %d", + nss_ctx, ncm->interface, ncm->type, ncm->response, ncm->error); +} + +/* + * NSS workqueue to change frequencies + */ +typedef struct { + struct work_struct my_work; /* Work Structure */ + uint32_t frequency; /* Frequency To Change */ + uint32_t stats_enable; /* Auto scale on/off */ +} nss_work_t; + +/* + * APIs provided by nss_core.c + */ +extern int nss_core_handle_napi(struct napi_struct *napi, int budget); +extern int nss_core_handle_napi_queue(struct napi_struct *napi, int budget); +extern int nss_core_handle_napi_non_queue(struct napi_struct *napi, int budget); +extern int nss_core_handle_napi_emergency(struct napi_struct *napi, int budget); +extern int nss_core_handle_napi_sdma(struct napi_struct *napi, int budget); +extern int32_t nss_core_send_buffer(struct nss_ctx_instance *nss_ctx, uint32_t if_num, + struct sk_buff *nbuf, uint16_t qid, + uint8_t buffer_type, uint16_t flags); +extern int32_t nss_core_send_cmd(struct nss_ctx_instance *nss_ctx, void *msg, int size, int buf_size); +extern int32_t nss_core_send_packet(struct nss_ctx_instance *nss_ctx, struct sk_buff *nbuf, uint32_t if_num, uint32_t flag); +extern uint32_t nss_core_ddr_info(struct nss_mmu_ddr_info *coreinfo); +extern uint32_t nss_core_register_msg_handler(struct nss_ctx_instance *nss_ctx, uint32_t interface, nss_if_rx_msg_callback_t msg_cb); +extern uint32_t nss_core_unregister_msg_handler(struct nss_ctx_instance *nss_ctx, uint32_t interface); +extern uint32_t nss_core_register_handler(struct nss_ctx_instance *nss_ctx, uint32_t interface, nss_core_rx_callback_t cb, void *app_data); +extern uint32_t nss_core_unregister_handler(struct nss_ctx_instance *nss_ctx, uint32_t interface); +extern void nss_core_init_handlers(struct nss_ctx_instance *nss_ctx); +void nss_core_update_max_ipv4_conn(int conn); +void nss_core_update_max_ipv6_conn(int conn); +extern void nss_core_register_subsys_dp(struct nss_ctx_instance *nss_ctx, uint32_t if_num, + nss_phys_if_rx_callback_t cb, + nss_phys_if_rx_ext_data_callback_t ext_cb, + void *app_data, struct net_device *ndev, + uint32_t features); +extern void nss_core_unregister_subsys_dp(struct nss_ctx_instance *nss_ctx, uint32_t if_num); +void nss_core_set_subsys_dp_type(struct nss_ctx_instance *nss_ctx, struct net_device *ndev, uint32_t if_num, uint32_t type); + +static inline nss_if_rx_msg_callback_t nss_core_get_msg_handler(struct nss_ctx_instance *nss_ctx, uint32_t interface) +{ + return nss_ctx->nss_rx_interface_handlers[interface].msg_cb; +} + +static inline uint32_t nss_core_get_max_buf_size(struct nss_ctx_instance *nss_ctx) +{ + return nss_ctx->max_buf_size; +} + +/* + * APIs provided by nss_tx_rx.c + */ +extern void nss_rx_handle_status_pkt(struct nss_ctx_instance *nss_ctx, struct sk_buff *nbuf); + +/* + * APIs provided by nss_stats.c + */ +extern void nss_stats_init(void); +extern void nss_stats_clean(void); + +/* + * APIs provided by nss_log.c + */ +extern void nss_log_init(void); +extern bool nss_debug_log_buffer_alloc(uint8_t nss_id, uint32_t nentry); +extern int nss_logbuffer_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos); + +/* + * APIs to set jumbo_mru & paged_mode + */ +extern void nss_core_set_jumbo_mru(int jumbo_mru); +extern int nss_core_get_jumbo_mru(void); +extern void nss_core_set_paged_mode(int mode); +extern int nss_core_get_paged_mode(void); +#if (NSS_SKB_REUSE_SUPPORT == 1) +extern void nss_core_set_max_reuse(int max); +extern int nss_core_get_max_reuse(void); +extern uint32_t nss_core_get_min_reuse(struct nss_ctx_instance *nss_ctx); +#endif + +/* + * APIs for coredump + */ +extern void nss_coredump_notify_register(void); +extern void nss_fw_coredump_notify(struct nss_ctx_instance *nss_own, int intr); +extern int nss_coredump_init_delay_work(void); + +/* + * APIs provided by nss_freq.c + */ +extern bool nss_freq_sched_change(nss_freq_scales_t index, bool auto_scale); + +/* + * nss_freq_init_cpu_usage + * Initializes the cpu usage computation. + */ +extern void nss_freq_init_cpu_usage(void); + +/* + * APIs for PPE + */ +extern void nss_ppe_init(void); +extern void nss_ppe_free(void); + +/* + * APIs for N2H + */ +extern nss_tx_status_t nss_n2h_cfg_empty_pool_size(struct nss_ctx_instance *nss_ctx, uint32_t pool_sz); +extern nss_tx_status_t nss_n2h_paged_buf_pool_init(struct nss_ctx_instance *nss_ctx); + +#endif /* __NSS_CORE_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_coredump.c b/feeds/ipq807x/qca-nss-drv/src/nss_coredump.c new file mode 100644 index 000000000..691a9a712 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_coredump.c @@ -0,0 +1,257 @@ +/* + ************************************************************************** + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_core.c + * NSS driver core APIs source file. + */ + +#include "nss_core.h" +#include "nss_hal.h" +#include "nss_log.h" +#include +#include /* for panic_notifier_list */ +#include /* for time */ +#include "nss_tx_rx_common.h" + +#if NSS_MAX_CORES > 2 /* see comment in nss_fw_coredump_notify */ +#error too many NSS Cores: should be 1 or 2 +#endif + +static struct delayed_work coredump_queuewait; +static struct workqueue_struct *coredump_workqueue; + +/* + * nss_coredump_wait() + * reboot (panic) if all finished coredump interrupts will not come. + * N2H (C2C) interrupt may get lost during trap, as well NSS may start + * only one core; so timeout if less than desird core sends back finished + * coredump interrupt. + */ +static void nss_coredump_wait(struct work_struct *work) +{ + panic("did not get all coredump finished signals\n"); +} + +/* + * nss_coredump_init_delay_work() + * set a wait function in case coredump finish interrupt lost or + * only one NSS core is up. + */ +int nss_coredump_init_delay_work(void) +{ + coredump_workqueue = create_singlethread_workqueue("coredump_wait"); + if (!coredump_workqueue) { + nss_warning("can't set wait: hopefully all int will come\n"); + return -ENOMEM; + } + + INIT_DELAYED_WORK(&coredump_queuewait, nss_coredump_wait); + return 0; +} + +/* + * nss_panic_handler() + * notification callback register to panic chain + */ +static int nss_panic_handler(struct notifier_block *nb, + unsigned long action, void *data) +{ + int dumped, timed; + int i; + + for (i = 0; i < nss_top_main.num_nss; i++) { + struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[i]; + if (nss_ctx->state & NSS_CORE_STATE_FW_DEAD || !nss_ctx->nmap) + continue; + nss_ctx->state |= NSS_CORE_STATE_PANIC; + nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_TRIGGER_COREDUMP); + nss_warning("panic call NSS FW %px to dump %x\n", + nss_ctx->nmap, nss_ctx->state); + } + + /* + * wait for FW coredump done: maximum 2 rounds for each core + * 200ms per round -- 16MB * 10 over 200MHz 32-bit memory bus + * panic will take another 3-5 seconds to reboot, so longer enough. + */ + dumped = timed = 0; + do { + mdelay(200); + for (i = 0; i < nss_top_main.num_nss; i++) { + struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[i]; + if ((nss_ctx->state & NSS_CORE_STATE_FW_DEAD || + !nss_ctx->nmap) && + !(nss_ctx->state & NSS_CORE_STATE_FW_DUMP)) { + nss_ctx->state |= NSS_CORE_STATE_FW_DUMP; + dumped++; + } + } + if (dumped >= nss_top_main.num_nss) { + nss_warning("NSS FW dump completed\n"); + break; + } + } while (timed++ < nss_top_main.num_nss * 2); + + if (timed >= nss_top_main.num_nss * 2) + nss_warning("might get %d FW dumped", dumped); + + return NOTIFY_DONE; +} + +static struct notifier_block nss_panic_nb = { + .notifier_call = nss_panic_handler, +}; + +/* + * nss_coredump_notify_register() + * API for nss_init to register coredump notifier to panic chain + */ +void nss_coredump_notify_register(void) +{ + atomic_notifier_chain_register(&panic_notifier_list, &nss_panic_nb); +} + +/* + * nss_fw_coredump_notify() + * handler for coredump notification from NSS FW + */ +void nss_fw_coredump_notify(struct nss_ctx_instance *nss_own, + int intr __attribute__ ((unused))) +{ + int i, j, curr_index, useful_entries, num_cores_wait; + struct nss_log_descriptor *nld; + struct nss_log_entry *nle_init, *nle_print; + dma_addr_t dma_addr; + uint32_t offset, index; + + nss_warning("%px: COREDUMP %x Baddr %px stat %x", + nss_own, intr, nss_own->nmap, nss_own->state); + nss_own->state |= NSS_CORE_STATE_FW_DEAD; + queue_delayed_work(coredump_workqueue, &coredump_queuewait, + msecs_to_jiffies(3456)); + + /* + * If external log buffer is not set, use the nss initial log buffer. + */ + nld = (struct nss_log_descriptor *)(nss_rbe[nss_own->id].addr); + dma_addr = nss_rbe[nss_own->id].dma_addr; + if (!nld) { + nld = nss_own->meminfo_ctx.logbuffer; + dma_addr = nss_own->meminfo_ctx.logbuffer_dma; + } + + dma_sync_single_for_cpu(NULL, dma_addr, sizeof(struct nss_log_descriptor), DMA_FROM_DEVICE); + + /* + * If the current entry is smaller than or equal to the number of NSS_LOG_COREDUMP_LINE_NUM, + * only print whatever is in the buffer. Otherwise, dump last NSS_LOG_COREDUMP_LINE_NUM + * to the dmessage. + */ + nss_info_always("%px: Starting NSS-FW logbuffer dump for core %u\n", + nss_own, nss_own->id); + nle_init = nld->log_ring_buffer; + if (nld->current_entry <= NSS_LOG_COREDUMP_LINE_NUM) { + curr_index = 0; + useful_entries = nld->current_entry; + } else { + curr_index = ((nld->current_entry - NSS_LOG_COREDUMP_LINE_NUM) % nld->log_nentries); + useful_entries = NSS_LOG_COREDUMP_LINE_NUM; + } + + nle_print = nle_init + curr_index; + for (j = index = curr_index; j < (curr_index + useful_entries); j++, index++) { + if (j == nld->log_nentries) { + nle_print = nle_init; + index = 0; + } + + offset = (index * sizeof(struct nss_log_entry)) + + offsetof(struct nss_log_descriptor, log_ring_buffer); + dma_sync_single_for_cpu(NULL, dma_addr + offset, + sizeof(struct nss_log_entry), DMA_FROM_DEVICE); + nss_info_always("%px: %s\n", nss_own, nle_print->message); + nle_print++; + } + + if (nss_own->state & NSS_CORE_STATE_PANIC) + return; + + /* + * We need to wait until all other cores finish their dump. + */ + num_cores_wait = (nss_top_main.num_nss - 1); + if (!num_cores_wait) { + /* + * nss_cmd_buf.coredump values: + * 0 == normal coredump and panic + * non-zero value is for debug purpose: + * 1 == force coredump and panic + * otherwise coredump but do not panic. + */ + if (!(nss_cmd_buf.coredump & 0xFFFFFFFE)) { + panic("NSS FW coredump: bringing system down\n"); + } + nss_info_always("NSS core dump completed & use mdump to collect dump to debug\n"); + return; + } + + for (i = 0; i < nss_top_main.num_nss; i++) { + struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[i]; + + /* + * Skip waiting for ourselves to coredump, we already have. + */ + if (nss_ctx == nss_own) { + continue; + } + + /* + * Notify any live core to dump. + */ + if (!(nss_ctx->state & NSS_CORE_STATE_FW_DEAD) && nss_ctx->nmap) { + nss_warning("notify NSS FW %px for coredump\n", nss_ctx->nmap); + nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_TRIGGER_COREDUMP); + continue; + } + + /* + * bit 1 is used for testing coredump. Any other + * bit(s) (value other than 0/1) disable panic + * in order to use mdump utility: see mdump/src/README + * for more info. + */ + if (nss_cmd_buf.coredump & 0xFFFFFFFE) { + nss_info_always("NSS core dump completed and please use mdump to collect dump data\n"); + continue; + } + + /* + * Ideally we need to unregister ourselves from the panic + * notifier list before calling the panic to prevent infinite calling. + * However, When we tried, we couldn't make it work. Therefore, We just leave the corresponding call here + * if it will be needed in the future. + * + * atomic_notifier_chain_unregister(&panic_notifier_list, &nss_panic_nb); + */ + num_cores_wait--; + if (!num_cores_wait) { + panic("NSS FW coredump: bringing system down\n"); + return; + } + + } +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_crypto.c b/feeds/ipq807x/qca-nss-drv/src/nss_crypto.c new file mode 100644 index 000000000..96d8c5b2c --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_crypto.c @@ -0,0 +1,302 @@ +/* + ************************************************************************** + * Copyright (c) 2013,2015-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_crypto.c + * NSS Crypto APIs + */ + +#include "nss_tx_rx_common.h" +#include "nss_crypto.h" +#include "nss_crypto_log.h" + +/* + ********************************** + General APIs + ********************************** + */ + +/* + * nss_crypto_set_msg_callback() + * this sets the message callback handler and its associated context + */ +static inline void nss_crypto_set_msg_callback(struct nss_ctx_instance *nss_ctx, nss_crypto_msg_callback_t cb, void *crypto_ctx) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + + nss_top->crypto_ctx = crypto_ctx; + nss_top->crypto_msg_callback = cb; +} + +/* + * nss_crypto_get_msg_callback() + * this gets the message callback handler and its associated context + */ +static inline nss_crypto_msg_callback_t nss_crypto_get_msg_callback(struct nss_ctx_instance *nss_ctx, void **crypto_ctx) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + + *crypto_ctx = nss_top->crypto_ctx; + return nss_top->crypto_msg_callback; +} + +/* + * nss_crypto_msg_handler() + * this handles all the IPsec events and responses + */ +static void nss_crypto_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, void *app_data __attribute((unused))) +{ + struct nss_crypto_msg *nim = (struct nss_crypto_msg *)ncm; + nss_crypto_msg_callback_t cb = NULL; + void *crypto_ctx = NULL; + + /* + * Sanity check the message type + */ + if (ncm->type > NSS_CRYPTO_MSG_TYPE_MAX) { + nss_warning("%px: rx message type out of range: %d", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_crypto_msg)) { + nss_warning("%px: rx message length is invalid: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + if (ncm->interface != NSS_CRYPTO_INTERFACE) { + nss_warning("%px: rx message request for another interface: %d", nss_ctx, ncm->interface); + return; + } + + if (ncm->response == NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: rx message response for if %d, type %d, is invalid: %d", nss_ctx, ncm->interface, + ncm->type, ncm->response); + return; + } + + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_crypto_get_msg_callback(nss_ctx, &crypto_ctx); + ncm->app_data = (nss_ptr_t)crypto_ctx; + } + + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Trace messages. + */ + nss_crypto_log_rx_msg(nim); + + /* + * Load, Test & call + */ + cb = (nss_crypto_msg_callback_t)ncm->cb; + if (unlikely(!cb)) { + nss_trace("%px: rx handler has been unregistered for i/f: %d", nss_ctx, ncm->interface); + return; + } + cb((void *)ncm->app_data, nim); +} +/* + ********************************** + Tx APIs + ********************************** + */ + +/* + * nss_crypto_tx_msg + * Send crypto config to NSS. + */ +nss_tx_status_t nss_crypto_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_crypto_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + nss_info("%px: tx message %d for if %d\n", nss_ctx, ncm->type, ncm->interface); + + BUILD_BUG_ON(NSS_NBUF_PAYLOAD_SIZE < sizeof(struct nss_crypto_msg)); + + if (ncm->interface != NSS_CRYPTO_INTERFACE) { + nss_warning("%px: tx message request for another interface: %d", nss_ctx, ncm->interface); + } + + if (ncm->type > NSS_CRYPTO_MSG_TYPE_MAX) { + nss_warning("%px: tx message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + nss_info("msg params version:%d, interface:%d, type:%d, cb:%px, app_data:%px, len:%d\n", + ncm->version, ncm->interface, ncm->type, (void *)ncm->cb, (void *)ncm->app_data, ncm->len); + + /* + * Trace messages. + */ + nss_crypto_log_tx_msg(msg); + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} + +/* + * nss_crypto_tx_data() + * NSS crypto TX data API. Sends a crypto buffer to NSS. + */ +nss_tx_status_t nss_crypto_tx_buf(struct nss_ctx_instance *nss_ctx, uint32_t if_num, struct sk_buff *skb) +{ + int32_t status; + + nss_trace("%px: tx_data buf=%px", nss_ctx, skb); + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) { + nss_warning("%px: tx_data packet dropped as core not ready", nss_ctx); + return NSS_TX_FAILURE_NOT_READY; + } + + status = nss_core_send_buffer(nss_ctx, if_num, skb, NSS_IF_H2N_DATA_QUEUE, H2N_BUFFER_PACKET, H2N_BIT_FLAG_BUFFER_REUSABLE); + if (unlikely(status != NSS_CORE_STATUS_SUCCESS)) { + nss_warning("%px: tx_data Unable to enqueue packet", nss_ctx); + if (status == NSS_CORE_STATUS_FAILURE_QUEUE) { + return NSS_TX_FAILURE_QUEUE; + } + + return NSS_TX_FAILURE; + } + + /* + * Kick the NSS awake so it can process our new entry. + */ + nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_DATA_COMMAND_QUEUE); + + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_TX_CRYPTO_REQ]); + + return NSS_TX_SUCCESS; +} + +/* + ********************************** + Register APIs + ********************************** + */ + +/* + * nss_crypto_notify_register() + * register message notifier for crypto interface + */ +struct nss_ctx_instance *nss_crypto_notify_register(nss_crypto_msg_callback_t cb, void *app_data) +{ + struct nss_ctx_instance *nss_ctx; + + nss_ctx = &nss_top_main.nss[nss_top_main.crypto_handler_id]; + + nss_crypto_set_msg_callback(nss_ctx, cb, app_data); + + return nss_ctx; +} + +/* + * nss_crypto_notify_unregister() + * unregister message notifier for crypto interface + */ +void nss_crypto_notify_unregister(struct nss_ctx_instance *nss_ctx) +{ + nss_crypto_set_msg_callback(nss_ctx, NULL, NULL); +} + +/* + * nss_crypto_data_register() + * register a data callback routine + */ +struct nss_ctx_instance *nss_crypto_data_register(uint32_t if_num, nss_crypto_buf_callback_t cb, + struct net_device *netdev, uint32_t features) +{ + struct nss_ctx_instance *nss_ctx; + + nss_ctx = &nss_top_main.nss[nss_top_main.crypto_handler_id]; + + if ((if_num >= NSS_MAX_NET_INTERFACES) && (if_num < NSS_MAX_PHYSICAL_INTERFACES)) { + nss_warning("%px: data register received for invalid interface %d", nss_ctx, if_num); + return NULL; + } + + /* + * Register subsystem, ensuring that no duplicate registrations occur. + */ + nss_core_register_subsys_dp(nss_ctx, if_num, cb, NULL, NULL, netdev, features); + + return nss_ctx; +} + +/* + * nss_crypto_data_unregister() + * unregister a data callback routine + */ +void nss_crypto_data_unregister(struct nss_ctx_instance *nss_ctx, uint32_t if_num) +{ + if ((if_num >= NSS_MAX_NET_INTERFACES) && (if_num < NSS_MAX_PHYSICAL_INTERFACES)) { + nss_warning("%px: data unregister received for invalid interface %d", nss_ctx, if_num); + return; + } + + nss_core_unregister_subsys_dp(nss_ctx, if_num); +} + +/* + * nss_crypto_pm_notify_register() + * register a PM notify callback routine + */ +void nss_crypto_pm_notify_register(nss_crypto_pm_event_callback_t cb, void *app_data) +{ + nss_top_main.crypto_pm_ctx = app_data; + nss_top_main.crypto_pm_callback = cb; +} + +/* + * nss_crypto_pm_notify_unregister() + * unregister a PM notify callback routine + */ +void nss_crypto_pm_notify_unregister(void) +{ + nss_top_main.crypto_pm_ctx = NULL; + nss_top_main.crypto_pm_callback = NULL; +} + +/* + * nss_crypto_register_handler() + */ +void nss_crypto_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[nss_top_main.crypto_handler_id]; + + nss_core_register_handler(nss_ctx, NSS_CRYPTO_INTERFACE, nss_crypto_msg_handler, NULL); +} + +/* + * nss_crypto_msg_init() + * Initialize crypto message + */ +void nss_crypto_msg_init(struct nss_crypto_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, + nss_crypto_msg_callback_t cb, void *app_data) +{ + nss_cmn_msg_init(&ncm->cm, if_num, type, len, (void *)cb, app_data); +} + +EXPORT_SYMBOL(nss_crypto_notify_register); +EXPORT_SYMBOL(nss_crypto_notify_unregister); +EXPORT_SYMBOL(nss_crypto_data_register); +EXPORT_SYMBOL(nss_crypto_data_unregister); +EXPORT_SYMBOL(nss_crypto_pm_notify_register); +EXPORT_SYMBOL(nss_crypto_pm_notify_unregister); +EXPORT_SYMBOL(nss_crypto_tx_msg); +EXPORT_SYMBOL(nss_crypto_tx_buf); +EXPORT_SYMBOL(nss_crypto_msg_init); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_crypto_cmn.c b/feeds/ipq807x/qca-nss-drv/src/nss_crypto_cmn.c new file mode 100644 index 000000000..4e6196983 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_crypto_cmn.c @@ -0,0 +1,371 @@ +/* + ************************************************************************** + * Copyright (c) 2013,2015-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_crypto_cmn.c + * NSS Crypto common API implementation + */ + +#include "nss_tx_rx_common.h" +#include "nss_crypto_cmn.h" +#include "nss_crypto_cmn_log.h" + +/* + * Amount time the synchronous message should wait for response from + * NSS before the timeout happens. After the timeout the message + * response even if it arrives has to be discarded. Typically, the + * time needs to be selected based on the worst case time in case of + * peak throughput between host & NSS. + */ +#define NSS_CRYPTO_CMN_TX_TIMEO_TICKS msecs_to_jiffies(3000) /* milliseconds */ + +/* + * Private data structure to hold state for + * the crypto specific NSS interaction + */ +struct nss_crypto_cmn_pvt { + struct semaphore sem; /* used for synchronizing 'tx_msg_sync' */ + struct completion complete; /* completion callback */ + atomic_t seq_no; /* used for tracking tx_msg_sync requests */ +}; + +/* + * This is a single instance applicable for all crypto synchronous + * messaging interaction with NSS. + */ +static struct nss_crypto_cmn_pvt g_nss_crypto_cmn; + +/* + * nss_crypto_cmn_msg_handler() + * this handles all the IPsec events and responses + */ +static void nss_crypto_cmn_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, + void *app_data __attribute((unused))) +{ + struct nss_crypto_cmn_msg *nim = (struct nss_crypto_cmn_msg *)ncm; + nss_crypto_cmn_msg_callback_t cb = NULL; + + /* + * Sanity check the message type + */ + if (ncm->type > NSS_CRYPTO_CMN_MSG_TYPE_MAX) { + nss_warning("%px: rx message type out of range: %d", nss_ctx, ncm->type); + return; + } + + /* + * Check if the message structure length matches that of Host side. In case + * of failure this indicates ether the structure is different or this is not + * the intended interface. + */ + if (nss_cmn_get_msg_len(ncm) > sizeof(*nim)) { + nss_warning("%px: rx message length is invalid: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + if (ncm->response == NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: rx message response for if %d, type %d, is invalid: %d", nss_ctx, + ncm->interface, ncm->type, ncm->response); + return; + } + + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_ctx->nss_top->crypto_cmn_msg_callback; + ncm->app_data = (nss_ptr_t)nss_ctx->nss_top->crypto_ctx; + } + + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Trace messages. + */ + nss_crypto_cmn_log_rx_msg(nim); + + /* + * Load, Test & call + */ + cb = (nss_crypto_cmn_msg_callback_t)ncm->cb; + if (unlikely(!cb)) { + nss_warning("%px: rx handler has been unregistered for i/f: %d", nss_ctx, ncm->interface); + return; + } + + cb((void *)ncm->app_data, nim); +} + +/* + * nss_crypto_cmn_tx_msg + * Send crypto config to NSS. + */ +nss_tx_status_t nss_crypto_cmn_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_crypto_cmn_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + uint16_t msg_len = nss_cmn_get_msg_len(ncm); + + nss_info("%px: tx message %d for if %d", nss_ctx, ncm->type, ncm->interface); + + BUILD_BUG_ON(NSS_NBUF_PAYLOAD_SIZE < sizeof(*msg)); + + if (ncm->type > NSS_CRYPTO_CMN_MSG_TYPE_MAX) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + /* + * Check if the message structure length matches the structure length. Otherwise + * the sender accidentally programmed a incorrect length into the message. + */ + if (msg_len != sizeof(*msg)) { + nss_warning("%px: message request len bad: %d", nss_ctx, msg_len); + return NSS_TX_FAILURE_BAD_PARAM; + } + + nss_trace("%px: msg params version:%d, interface:%d, type:%d, cb:%px, app_data:%px, len:%d", + nss_ctx, ncm->version, ncm->interface, ncm->type, + (void *)ncm->cb, (void *)ncm->app_data, ncm->len); + + /* + * Trace messages. + */ + nss_crypto_cmn_log_tx_msg(msg); + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_crypto_cmn_tx_msg); + +/* + * nss_crypto_cmn_tx_msg_cb() + * Callback to handle the synchronous completion of messages. + */ +static void nss_crypto_cmn_tx_msg_cb(void *app_data, struct nss_crypto_cmn_msg *nim) +{ + struct nss_crypto_cmn_pvt *pvt = &g_nss_crypto_cmn; + struct nss_crypto_cmn_msg *resp = (struct nss_crypto_cmn_msg *)nim->cm.app_data; + + /* + * Only update the message structure if the sequence no. matches + * Otherwise, a timeout might have happened in between and we + * are probably receiving the completion for an older message + */ + if (atomic_read(&pvt->seq_no) == nim->seq_num) { + memcpy(resp, nim, sizeof(struct nss_crypto_cmn_msg)); + complete(&pvt->complete); + } +} + +/* + * nss_crypto_cmn_tx_msg_sync() + * Transmit a crypto message to NSS firmware synchronously. + */ +nss_tx_status_t nss_crypto_cmn_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_crypto_cmn_msg *msg) +{ + struct nss_crypto_cmn_pvt *pvt = &g_nss_crypto_cmn; + nss_tx_status_t status; + int ret = 0; + + down(&pvt->sem); + atomic_inc(&pvt->seq_no); + + /* + * this is a synchronous message; overload the callback + * and app_data + */ + msg->cm.cb = (nss_ptr_t)nss_crypto_cmn_tx_msg_cb; + msg->cm.app_data = (nss_ptr_t)msg; + msg->seq_num = atomic_read(&pvt->seq_no); + + status = nss_crypto_cmn_tx_msg(nss_ctx, msg); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: tx_msg failed", nss_ctx); + up(&pvt->sem); + return status; + } + + /* + * Note: This cannot be called in atomic context + */ + ret = wait_for_completion_timeout(&pvt->complete, NSS_CRYPTO_CMN_TX_TIMEO_TICKS); + if (!ret) { + atomic_inc(&pvt->seq_no); + nss_warning("%px: tx_msg_sync timed out", nss_ctx); + up(&pvt->sem); + return NSS_TX_FAILURE; + } + + /* + * This ensures that the even if the response arrives on a different + * CPU core the data copied by the response callback will be visible + * to the caller which is sleeping for it on a different core. For + * further details read Linux/Documentation/memory-barrier.txt + */ + smp_rmb(); + up(&pvt->sem); + + return NSS_TX_SUCCESS; +} +EXPORT_SYMBOL(nss_crypto_cmn_tx_msg_sync); + +/* + * nss_crypto_cmn_tx_buf() + * NSS crypto TX data API. Sends a crypto buffer to NSS. + */ +nss_tx_status_t nss_crypto_cmn_tx_buf(struct nss_ctx_instance *nss_ctx, uint32_t if_num, + struct sk_buff *skb) +{ + int32_t status; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) { + nss_warning("%px: tx_data packet dropped as core not ready", nss_ctx); + return NSS_TX_FAILURE_NOT_READY; + } + + status = nss_core_send_packet(nss_ctx, skb, if_num, H2N_BIT_FLAG_BUFFER_REUSABLE); + switch (status) { + case NSS_CORE_STATUS_SUCCESS: + break; + + case NSS_CORE_STATUS_FAILURE_QUEUE: /* queue full condition */ + nss_warning("%px: H2N queue full for tx_buf", nss_ctx); + return NSS_TX_FAILURE_QUEUE; + + default: + nss_warning("%px: general failure for tx_buf", nss_ctx); + return NSS_TX_FAILURE; + } + + /* + * Kick the NSS awake so it can process our new entry. + */ + nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_DATA_COMMAND_QUEUE); + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_TX_CRYPTO_REQ]); + + return NSS_TX_SUCCESS; +} +EXPORT_SYMBOL(nss_crypto_cmn_tx_buf); + +/* + * nss_crypto_cmn_notify_register() + * register message notifier for crypto interface + */ +struct nss_ctx_instance *nss_crypto_cmn_notify_register(nss_crypto_cmn_msg_callback_t cb, void *app_data) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[nss_top->crypto_handler_id]; + + nss_top->crypto_ctx = app_data; + nss_top->crypto_cmn_msg_callback = cb; + + return nss_ctx; +} +EXPORT_SYMBOL(nss_crypto_cmn_notify_register); + +/* + * nss_crypto_cmn_notify_unregister() + * De-register the message notifier for crypto interface + */ +void nss_crypto_cmn_notify_unregister(struct nss_ctx_instance *nss_ctx) +{ + struct nss_top_instance *nss_top = &nss_top_main; + + nss_top->crypto_ctx = NULL; + nss_top->crypto_cmn_msg_callback = NULL; +} +EXPORT_SYMBOL(nss_crypto_cmn_notify_unregister); + +/* + * nss_crypto_cmn_data_register() + * Register the data callback routine + */ +struct nss_ctx_instance *nss_crypto_cmn_data_register(uint32_t if_num, nss_crypto_cmn_buf_callback_t cb, + struct net_device *netdev, uint32_t features) +{ + struct nss_ctx_instance *nss_ctx; + + nss_ctx = &nss_top_main.nss[nss_top_main.crypto_handler_id]; + + if (if_num < NSS_SPECIAL_IF_START) { + nss_warning("%px: interface number is not special interface %d", nss_ctx, if_num); + return NULL; + } + + /* + * avoid multiple registration for same interface number + */ + if (nss_ctx->subsys_dp_register[if_num].cb) + return nss_ctx; + + /* + * Note: no locking is required for updating this as + * the registration is only a module load time operation. + */ + nss_core_register_subsys_dp(nss_ctx, if_num, cb, NULL, NULL, netdev, features); + + return nss_ctx; +} +EXPORT_SYMBOL(nss_crypto_cmn_data_register); + +/* + * nss_crypto_cmn_data_unregister() + * De-register the data callback routine + */ +void nss_crypto_cmn_data_unregister(struct nss_ctx_instance *nss_ctx, uint32_t if_num) +{ + if (if_num < NSS_SPECIAL_IF_START) { + nss_warning("%px: interface number is not special interface %d", nss_ctx, if_num); + return; + } + + /* + * Note: no locking is required for updating this as + * the registration is only a module load time operation. + */ + nss_core_unregister_subsys_dp(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_crypto_cmn_data_unregister); + +/* + * nss_crypto_cmn_get_context() + * get NSS context instance for crypto handle + */ +struct nss_ctx_instance *nss_crypto_cmn_get_context(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.crypto_handler_id]; +} +EXPORT_SYMBOL(nss_crypto_cmn_get_context); + +/* + * nss_crypto_cmn_register_handler() + */ +void nss_crypto_cmn_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx = nss_crypto_cmn_get_context(); + + sema_init(&g_nss_crypto_cmn.sem, 1); + init_completion(&g_nss_crypto_cmn.complete); + nss_core_register_handler(nss_ctx, NSS_CRYPTO_CMN_INTERFACE, nss_crypto_cmn_msg_handler, NULL); +} + +/* + * nss_crypto_cmn_msg_init() + * Initialize crypto message + */ +void nss_crypto_cmn_msg_init(struct nss_crypto_cmn_msg *ncm, uint16_t if_num, uint32_t type, + uint32_t len, nss_crypto_cmn_msg_callback_t cb, void *app_data) +{ + nss_cmn_msg_init(&ncm->cm, if_num, type, len, (void *)cb, app_data); +} +EXPORT_SYMBOL(nss_crypto_cmn_msg_init); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_crypto_cmn_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_crypto_cmn_log.c new file mode 100644 index 000000000..04cd66c47 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_crypto_cmn_log.c @@ -0,0 +1,210 @@ +/* + ************************************************************************** + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_crypto_cmn_log.c + * NSS Crypto Common logger file. + */ + +#include "nss_core.h" + +/* + * nss_crypto_cmn_log_message_types_str + * Crypto Common message strings + */ +static int8_t *nss_crypto_cmn_log_message_types_str[NSS_CRYPTO_CMN_MSG_TYPE_MAX] __maybe_unused = { + "Crypto Common Invalid Message", + "Crypto Common CRYPTO CMN Initialize Node", + "Crypto Common Initialize Engine", + "Crypto Common Initialize DMA Pair", + "Crypto Common Update Context Information", + "Crypto Common Clear Context Information", + "Crypto Common Verify Context Active", + "Crypto Common Synchronous Node Statistics" + "Crypto Common Synchronouts Engine Statistics", + "Crypto Common Synchronous Context Statistics" +}; + +/* + * nss_crypto_cmn_log_error_response_types_str + * Strings for error types for crypto common messages + */ +static int8_t *nss_crypto_cmn_log_error_response_types_str[NSS_CRYPTO_CMN_MSG_ERROR_MAX] __maybe_unused = { + "Crypto Common No Error", + "Crypto Common Header Version Not Supported", + "Crypto Common Context Index out-of-range for node", + "Crypto Common DMA mask out-of-range", + "Crypto Common DMA count exceeds Token", + "Crypto Common Token Allocation failed", + "Crypto Common Context Index out-of-range", + "Crypto Common Context has references", + "Crypto Common Bad Context Size", + "Crypto Common Bad Algorithm", + "Crypto Common Context Allocation failed", + "Crypto Common Context has no references", + "Crypto Common Invalid Context Flags" +}; + +/* + * nss_crypto_cmn_node_msg() + * Log NSS crypto common node message. + */ +static void nss_crypto_cmn_node_msg(struct nss_crypto_cmn_msg *ncm) +{ + struct nss_crypto_cmn_node *ncnm __maybe_unused = &ncm->msg.node; + nss_trace("%px: NSS crypto common node message:\n" + "Crypto Common Max DMA Rings: %d\n" + "Crypto Common Max Contex: %d\n" + "Crypto Common Max Context Size: %d\n", + ncnm, ncnm->max_dma_rings, + ncnm->max_ctx, ncnm->max_ctx_size); +} + +/* + * nss_crypto_cmn_engine_msg() + * Log NSS crypto cmn engine message. + */ +static void nss_crypto_cmn_engine_msg(struct nss_crypto_cmn_msg *ncm) +{ + struct nss_crypto_cmn_engine *ncem __maybe_unused = &ncm->msg.eng; + nss_trace("%px: NSS crypto common engine message \n" + "Crypto Common Firmware Version: %px\n" + "Crypto Common DMA Mask: %x\n" + "Crypto Common Token Count: %d\n", + ncem, &ncem->fw_ver, + ncem->dma_mask, ncem->req_count); +} + +/* + * nss_crypto_cmn_dma_msg() + * Log NSS crypto cmn dma message. + */ +static void nss_crypto_cmn_dma_msg(struct nss_crypto_cmn_msg *ncm) +{ + struct nss_crypto_cmn_dma *ncdm __maybe_unused = &ncm->msg.dma; + nss_trace("%px: NSS crypto common dma message \n" + "Crypto Common DMA Pair ID: %d\n", + ncdm, ncdm->pair_id); +} + +/* + * nss_crypto_cmn_ctx_msg() + * Log NSS crypto cmn context message. + */ +static void nss_crypto_cmn_ctx_msg(struct nss_crypto_cmn_msg *ncm) +{ + struct nss_crypto_cmn_ctx *nccm __maybe_unused = &ncm->msg.ctx; + nss_trace("%px: NSS crypto common context message \n" + "Crypto Common Context Spare Words: %px\n" + "Crypto Common Index: %d\n" + "Crypto Common Secure Offset: %d\n" + "Crypto Common Cipher Key: %px\n" + "Crypto Common Authorization Key: %px\n" + "Crypto Common Nonce Value: %px\n" + "Crypto Common Algorithm: %x\n" + "Crypto Common Context Specific Flags: %x\n", + nccm, &nccm->spare, + nccm->index, nccm->sec_offset, + &nccm->cipher_key, &nccm->auth_key, + &nccm->nonce, nccm->algo, nccm->flags); +} + +/* + * nss_crypto_cmn_log_verbose() + * Log message contents. + */ +static void nss_crypto_cmn_log_verbose(struct nss_crypto_cmn_msg *ncm) +{ + switch (ncm->cm.type) { + case NSS_CRYPTO_CMN_MSG_TYPE_SETUP_NODE: + nss_crypto_cmn_node_msg(ncm); + break; + + case NSS_CRYPTO_CMN_MSG_TYPE_SETUP_ENG: + nss_crypto_cmn_engine_msg(ncm); + break; + + case NSS_CRYPTO_CMN_MSG_TYPE_SETUP_DMA: + nss_crypto_cmn_dma_msg(ncm); + break; + + case NSS_CRYPTO_CMN_MSG_TYPE_SETUP_CTX: + case NSS_CRYPTO_CMN_MSG_TYPE_CLEAR_CTX: + case NSS_CRYPTO_CMN_MSG_TYPE_VERIFY_CTX: + nss_crypto_cmn_ctx_msg(ncm); + break; + + case NSS_CRYPTO_CMN_MSG_TYPE_SYNC_NODE_STATS: + case NSS_CRYPTO_CMN_MSG_TYPE_SYNC_ENG_STATS: + case NSS_CRYPTO_CMN_MSG_TYPE_SYNC_CTX_STATS: + /* Getting logged in stats */ + break; + + default: + nss_warning("%px: Invalid message type\n", ncm); + break; + } +} + +/* + * nss_crypto_cmn_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_crypto_cmn_log_tx_msg(struct nss_crypto_cmn_msg *ncm) +{ + if (ncm->cm.type >= NSS_CRYPTO_CMN_MSG_TYPE_MAX) { + nss_warning("%px: Invalid message type\n", ncm); + return; + } + + nss_info("%px: type[%d]:%s\n", ncm, ncm->cm.type, nss_crypto_cmn_log_message_types_str[ncm->cm.type]); + nss_crypto_cmn_log_verbose(ncm); +} + +/* + * nss_crypto_cmn_log_rx_msg() + * Log messages received from FW. + */ +void nss_crypto_cmn_log_rx_msg(struct nss_crypto_cmn_msg *ncm) +{ + if (ncm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", ncm); + return; + } + + if (ncm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ncm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", ncm, ncm->cm.type, + nss_crypto_cmn_log_message_types_str[ncm->cm.type], + ncm->cm.response, nss_cmn_response_str[ncm->cm.response]); + goto verbose; + } + + if (ncm->cm.error >= NSS_CRYPTO_CMN_MSG_ERROR_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + ncm, ncm->cm.type, nss_crypto_cmn_log_message_types_str[ncm->cm.type], + ncm->cm.response, nss_cmn_response_str[ncm->cm.response], + ncm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + ncm, ncm->cm.type, nss_crypto_cmn_log_message_types_str[ncm->cm.type], + ncm->cm.response, nss_cmn_response_str[ncm->cm.response], + ncm->cm.error, nss_crypto_cmn_log_error_response_types_str[ncm->cm.error]); + +verbose: + nss_crypto_cmn_log_verbose(ncm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_crypto_cmn_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_crypto_cmn_log.h new file mode 100644 index 000000000..f78a8ecf7 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_crypto_cmn_log.h @@ -0,0 +1,37 @@ +/* + ****************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_CRYPTO_CMN_LOG_H__ +#define __NSS_CRYPTO_CMN_LOG_H__ + +/* + * nss_crypto_cmn_log.h + * NSS Crypto Common Log header file. + */ + +/* + * nss_crypto_cmn_log_tx_msg + * Logs a crypto common message that is sent to the NSS firmware. + */ +void nss_crypto_cmn_log_tx_msg(struct nss_crypto_cmn_msg *ncm); + +/* + * nss_crypto_cmn_log_rx_msg + * Logs a crypto common message that is received from the NSS firmware. + */ +void nss_crypto_cmn_log_rx_msg(struct nss_crypto_cmn_msg *ncm); + +#endif /* __NSS_CRYPTO_CMN_LOG_H__ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_crypto_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_crypto_log.c new file mode 100644 index 000000000..b5569973b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_crypto_log.c @@ -0,0 +1,151 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_crypto_log.c + * NSS Crypto logger file. + */ + +#include "nss_core.h" + +/* + * nss_crypto_log_message_types_str + * Crypto message strings + */ +static int8_t *nss_crypto_log_message_types_str[NSS_CRYPTO_MSG_TYPE_MAX] __maybe_unused = { + "Crypto Invalid Message", + "Crypto Open Engine Message", + "Crypto Close Engine Message", + "Crypto Update Session", + "Crypto Stats Sync", +}; + +/* + * nss_crypto_log_error_response_types_str + * Strings for error types for CRYPTO messages + */ +static int8_t *nss_crypto_log_error_response_types_str[NSS_CRYPTO_MSG_ERROR_MAX] __maybe_unused = { + "Crypto No Error", + "Crypto Invalid Engine", + "Crypto Unsupported Operation", + "Crypto Invalid Operation", + "Crypto Invalid Index Range", + "Crypto Index Alloc Failure", +}; + +/* + * nss_crypto_config_eng_msg() + * Log NSS Crypto config engine message. + */ +static void nss_crypto_config_eng_msg(struct nss_crypto_msg *ncm) +{ + struct nss_crypto_config_eng *nccem __maybe_unused = &ncm->msg.eng; + nss_trace("%px: NSS Crypto Config Engine Message:\n" + "Crypto Engine Number: %d\n" + "Crypto BAM Physical Base Address: %x\n" + "Crypto Physical Base Address: %x\n" + "Crypto Pipe Description Address: %px\n" + "Crypto Session Indices: %px\n", + nccem, nccem->eng_id, + nccem->bam_pbase, nccem->crypto_pbase, + &nccem->desc_paddr, &nccem->idx); +} + +/* + * nss_crypto_config_session_msg() + * Log NSS Crypto config session message. + */ +static void nss_crypto_config_session_msg(struct nss_crypto_msg *ncm) +{ + struct nss_crypto_config_session *nccsm __maybe_unused = &ncm->msg.session; + nss_trace("%px: NSS Crypto Config Session message \n" + "Crypto Session Index: %d\n" + "Crypto Session State: %d\n" + "Crypto Session Initialization Vector Length: %d\n", + nccsm, nccsm->idx, + nccsm->state, nccsm->iv_len); +} + +/* + * nss_crypto_log_verbose() + * Log message contents. + */ +static void nss_crypto_log_verbose(struct nss_crypto_msg *ncm) +{ + switch (ncm->cm.type) { + case NSS_CRYPTO_MSG_TYPE_OPEN_ENG: + nss_crypto_config_eng_msg(ncm); + break; + + case NSS_CRYPTO_MSG_TYPE_UPDATE_SESSION: + nss_crypto_config_session_msg(ncm); + break; + + default: + nss_warning("%px: Invalid message type\n", ncm); + break; + } +} + +/* + * nss_crypto_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_crypto_log_tx_msg(struct nss_crypto_msg *ncm) +{ + if (ncm->cm.type >= NSS_CRYPTO_MSG_TYPE_MAX) { + nss_warning("%px: Invalid message type\n", ncm); + return; + } + + nss_info("%px: type[%d]:%s\n", ncm, ncm->cm.type, nss_crypto_log_message_types_str[ncm->cm.type]); + nss_crypto_log_verbose(ncm); +} + +/* + * nss_crypto_log_rx_msg() + * Log messages received from FW. + */ +void nss_crypto_log_rx_msg(struct nss_crypto_msg *ncm) +{ + if (ncm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", ncm); + return; + } + + if (ncm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ncm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", ncm, ncm->cm.type, + nss_crypto_log_message_types_str[ncm->cm.type], + ncm->cm.response, nss_cmn_response_str[ncm->cm.response]); + goto verbose; + } + + if (ncm->cm.error >= NSS_CRYPTO_MSG_ERROR_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + ncm, ncm->cm.type, nss_crypto_log_message_types_str[ncm->cm.type], + ncm->cm.response, nss_cmn_response_str[ncm->cm.response], + ncm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + ncm, ncm->cm.type, nss_crypto_log_message_types_str[ncm->cm.type], + ncm->cm.response, nss_cmn_response_str[ncm->cm.response], + ncm->cm.error, nss_crypto_log_error_response_types_str[ncm->cm.error]); + +verbose: + nss_crypto_log_verbose(ncm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_crypto_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_crypto_log.h new file mode 100644 index 000000000..c0d53ddae --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_crypto_log.h @@ -0,0 +1,37 @@ +/* + ****************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_CRYPTO_LOG_H__ +#define __NSS_CRYPTO_LOG_H__ + +/* + * nss_crypto_log.h + * NSS Crypto Log Header File + */ + +/* + * nss_crypto_log_tx_msg + * Logs a crypto message that is sent to the NSS firmware. + */ +void nss_crypto_log_tx_msg(struct nss_crypto_msg *ncm); + +/* + * nss_crypto_log_rx_msg + * Logs a crypto message that is received from the NSS firmware. + */ +void nss_crypto_log_rx_msg(struct nss_crypto_msg *ncm); + +#endif /* __NSS_CRYPTO_LOG_H__ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/hal/include/nss_data_plane_hal.h b/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/hal/include/nss_data_plane_hal.h new file mode 100644 index 000000000..05bd6b5ad --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/hal/include/nss_data_plane_hal.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "nss_phys_if.h" +#include + +/* + * nss_data_plane_param + */ +struct nss_data_plane_param { + struct nss_dp_data_plane_ctx dpc; /* data plane ctx base class */ + int if_num; /* physical interface number */ + struct nss_ctx_instance *nss_ctx; /* which nss core */ + struct nss_dp_gmac_stats gmac_stats; /* SoC specific stats for GMAC */ + int notify_open; /* This data plane interface has been opened or not */ + uint32_t features; /* skb types supported by this interface */ + uint32_t bypass_nw_process; /* Do we want to bypass NW processing in NSS for this data plane? */ +}; + +void nss_data_plane_hal_add_dp_ops(struct nss_dp_data_plane_ops *dp_ops); +void nss_data_plane_hal_register(struct nss_ctx_instance *nss_ctx); +void nss_data_plane_hal_unregister(struct nss_ctx_instance *nss_ctx); +uint16_t nss_data_plane_hal_get_mtu_sz(uint16_t mtu); +void nss_data_plane_hal_stats_sync(struct nss_data_plane_param *ndpp, struct nss_phys_if_stats *stats); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/hal/nss_ipq50xx.c b/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/hal/nss_ipq50xx.c new file mode 100644 index 000000000..1a07e8bde --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/hal/nss_ipq50xx.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "nss_core.h" +#include "nss_data_plane_hal.h" + +static DEFINE_SPINLOCK(nss_data_plane_hal_gmac_stats_lock); + +/* + * nss_data_plane_hal_get_stats() + * Called by nss-dp to get GMAC stats + */ +static void nss_data_plane_hal_get_stats(struct nss_dp_data_plane_ctx *dpc, + struct nss_dp_gmac_stats *stats) +{ + struct nss_data_plane_param *dp = (struct nss_data_plane_param *)dpc; + + spin_lock_bh(&nss_data_plane_hal_gmac_stats_lock); + memcpy(stats, &dp->gmac_stats, sizeof(*stats)); + spin_unlock_bh(&nss_data_plane_hal_gmac_stats_lock); +} + +/* + * nss_data_plane_hal_add_dp_ops() + */ +void nss_data_plane_hal_add_dp_ops(struct nss_dp_data_plane_ops *dp_ops) +{ + dp_ops->get_stats = nss_data_plane_hal_get_stats; +} + +/* + * nss_data_plane_hal_register() + */ +void nss_data_plane_hal_register(struct nss_ctx_instance *nss_ctx) +{ +} + +/* + * nss_data_plane_hal_unregister() + */ +void nss_data_plane_hal_unregister(struct nss_ctx_instance *nss_ctx) +{ +} + +/* + * nss_data_plane_hal_stats_sync() + */ +void nss_data_plane_hal_stats_sync(struct nss_data_plane_param *ndpp, + struct nss_phys_if_stats *stats) +{ + struct nss_dp_hal_gmac_stats *gmac_stats = &ndpp->gmac_stats.stats; + + spin_lock_bh(&nss_data_plane_hal_gmac_stats_lock); + + gmac_stats->rx_bytes += stats->if_stats.rx_bytes; + gmac_stats->rx_packets += stats->if_stats.rx_packets; + gmac_stats->rx_errors += stats->estats.rx_errors; + gmac_stats->rx_receive_errors += stats->estats.rx_receive_errors; + gmac_stats->rx_descriptor_errors += stats->estats.rx_descriptor_errors; + gmac_stats->rx_late_collision_errors += stats->estats.rx_late_collision_errors; + gmac_stats->rx_dribble_bit_errors += stats->estats.rx_dribble_bit_errors; + gmac_stats->rx_length_errors += stats->estats.rx_length_errors; + gmac_stats->rx_ip_header_errors += stats->estats.rx_ip_header_errors; + gmac_stats->rx_ip_payload_errors += stats->estats.rx_ip_payload_errors; + gmac_stats->rx_no_buffer_errors += stats->estats.rx_no_buffer_errors; + gmac_stats->rx_transport_csum_bypassed += stats->estats.rx_transport_csum_bypassed; + + gmac_stats->tx_bytes += stats->if_stats.tx_bytes; + gmac_stats->tx_packets += stats->if_stats.tx_packets; + gmac_stats->tx_collisions += stats->estats.tx_collisions; + gmac_stats->tx_errors += stats->estats.tx_errors; + gmac_stats->tx_jabber_timeout_errors += stats->estats.tx_jabber_timeout_errors; + gmac_stats->tx_frame_flushed_errors += stats->estats.tx_frame_flushed_errors; + gmac_stats->tx_loss_of_carrier_errors += stats->estats.tx_loss_of_carrier_errors; + gmac_stats->tx_no_carrier_errors += stats->estats.tx_no_carrier_errors; + gmac_stats->tx_late_collision_errors += stats->estats.tx_late_collision_errors; + gmac_stats->tx_excessive_collision_errors += stats->estats.tx_excessive_collision_errors; + gmac_stats->tx_excessive_deferral_errors += stats->estats.tx_excessive_deferral_errors; + gmac_stats->tx_underflow_errors += stats->estats.tx_underflow_errors; + gmac_stats->tx_ip_header_errors += stats->estats.tx_ip_header_errors; + gmac_stats->tx_ip_payload_errors += stats->estats.tx_ip_payload_errors; + gmac_stats->tx_dropped += stats->estats.tx_dropped; + + gmac_stats->hw_errs[0] += stats->estats.hw_errs[0]; + gmac_stats->hw_errs[1] += stats->estats.hw_errs[1]; + gmac_stats->hw_errs[2] += stats->estats.hw_errs[2]; + gmac_stats->hw_errs[3] += stats->estats.hw_errs[3]; + gmac_stats->hw_errs[4] += stats->estats.hw_errs[4]; + gmac_stats->hw_errs[5] += stats->estats.hw_errs[5]; + gmac_stats->hw_errs[6] += stats->estats.hw_errs[6]; + gmac_stats->hw_errs[7] += stats->estats.hw_errs[7]; + gmac_stats->hw_errs[8] += stats->estats.hw_errs[8]; + gmac_stats->hw_errs[9] += stats->estats.hw_errs[9]; + gmac_stats->rx_missed += stats->estats.rx_missed; + + gmac_stats->fifo_overflows += stats->estats.fifo_overflows; + gmac_stats->rx_scatter_errors += stats->estats.rx_scatter_errors; + gmac_stats->tx_ts_create_errors += stats->estats.tx_ts_create_errors; + gmac_stats->gmac_total_ticks += stats->estats.gmac_total_ticks; + gmac_stats->gmac_worst_case_ticks += stats->estats.gmac_worst_case_ticks; + gmac_stats->gmac_iterations += stats->estats.gmac_iterations; + gmac_stats->tx_pause_frames += stats->estats.tx_pause_frames; + gmac_stats->mmc_rx_overflow_errors += stats->estats.mmc_rx_overflow_errors; + gmac_stats->mmc_rx_watchdog_timeout_errors += stats->estats.mmc_rx_watchdog_timeout_errors; + gmac_stats->mmc_rx_crc_errors += stats->estats.mmc_rx_crc_errors; + gmac_stats->mmc_rx_ip_header_errors += stats->estats.mmc_rx_ip_header_errors; + gmac_stats->mmc_rx_octets_g += stats->estats.mmc_rx_octets_g; + gmac_stats->mmc_rx_ucast_frames += stats->estats.mmc_rx_ucast_frames; + gmac_stats->mmc_rx_bcast_frames += stats->estats.mmc_rx_bcast_frames; + gmac_stats->mmc_rx_mcast_frames += stats->estats.mmc_rx_mcast_frames; + gmac_stats->mmc_rx_undersize += stats->estats.mmc_rx_undersize; + gmac_stats->mmc_rx_oversize += stats->estats.mmc_rx_oversize; + gmac_stats->mmc_rx_jabber += stats->estats.mmc_rx_jabber; + gmac_stats->mmc_rx_octets_gb += stats->estats.mmc_rx_octets_gb; + gmac_stats->mmc_rx_frag_frames_g += stats->estats.mmc_rx_frag_frames_g; + gmac_stats->mmc_tx_octets_g += stats->estats.mmc_tx_octets_g; + gmac_stats->mmc_tx_ucast_frames += stats->estats.mmc_tx_ucast_frames; + gmac_stats->mmc_tx_bcast_frames += stats->estats.mmc_tx_bcast_frames; + gmac_stats->mmc_tx_mcast_frames += stats->estats.mmc_tx_mcast_frames; + gmac_stats->mmc_tx_deferred += stats->estats.mmc_tx_deferred; + gmac_stats->mmc_tx_single_col += stats->estats.mmc_tx_single_col; + gmac_stats->mmc_tx_multiple_col += stats->estats.mmc_tx_multiple_col; + gmac_stats->mmc_tx_octets_gb += stats->estats.mmc_tx_octets_gb; + + spin_unlock_bh(&nss_data_plane_hal_gmac_stats_lock); +} + +/* + * nss_data_plane_hal_get_mtu_sz() + */ +uint16_t nss_data_plane_hal_get_mtu_sz(uint16_t mtu) +{ + /* + * GMACs support 3 Modes + * Normal Mode Payloads upto 1522 Bytes ( 1500 + 14 + 4(Vlan) + 4(CRC)) + * Mini Jumbo Mode Payloads upto 2000 Bytes (1978 + 14 + 4(Vlan) + 4 (CRC)) + * Full Jumbo Mode payloads upto 9022 Bytes (9000 + 14 + 4(Vlan) + 4 (CRC)) + */ + + /* + * The configured MTU value on a GMAC interface should be one of these + * cases. Finding the Needed MTU size that is required for GMAC to + * successfully receive the frame. + */ + if (mtu <= NSS_DP_GMAC_NORMAL_FRAME_MTU) { + return NSS_DP_GMAC_NORMAL_FRAME_MTU; + } + if (mtu <= NSS_DP_GMAC_MINI_JUMBO_FRAME_MTU) { + return NSS_DP_GMAC_MINI_JUMBO_FRAME_MTU; + } + if (mtu <= NSS_DP_GMAC_FULL_JUMBO_FRAME_MTU) { + return NSS_DP_GMAC_FULL_JUMBO_FRAME_MTU; + } + return 0; +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/hal/nss_ipq60xx.c b/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/hal/nss_ipq60xx.c new file mode 100644 index 000000000..2e2c3ea1b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/hal/nss_ipq60xx.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "nss_core.h" +#include "nss_data_plane_hal.h" + +/* + * nss_data_plane_hal_vsi_assign() + * Called by nss-dp to assign vsi of a data plane + */ +static int nss_data_plane_hal_vsi_assign(struct nss_dp_data_plane_ctx *dpc, uint32_t vsi) +{ + struct nss_data_plane_param *dp = (struct nss_data_plane_param *)dpc; + + return nss_phys_if_vsi_assign(dp->nss_ctx, vsi, dp->if_num); +} + +/* + * nss_data_plane_hal_vsi_unassign() + * Called by nss-dp to unassign vsi of a data plane + */ +static int nss_data_plane_hal_vsi_unassign(struct nss_dp_data_plane_ctx *dpc, uint32_t vsi) +{ + struct nss_data_plane_param *dp = (struct nss_data_plane_param *)dpc; + + return nss_phys_if_vsi_unassign(dp->nss_ctx, vsi, dp->if_num); +} + +/* + * nss_data_plane_hal_get_stats() + * Called by nss-dp to get GMAC stats + */ +static void nss_data_plane_hal_get_stats(struct nss_dp_data_plane_ctx *dpc, + struct nss_dp_gmac_stats *stats) +{ + /* + * EDMA doesn't send extended statistics. + */ +} + +/* + * nss_data_plane_hal_add_dp_ops() + */ +void nss_data_plane_hal_add_dp_ops(struct nss_dp_data_plane_ops *dp_ops) +{ + dp_ops->vsi_assign = nss_data_plane_hal_vsi_assign; + dp_ops->vsi_unassign = nss_data_plane_hal_vsi_unassign; + dp_ops->get_stats = nss_data_plane_hal_get_stats; +} + +/* + * nss_data_plane_hal_register() + */ +void nss_data_plane_hal_register(struct nss_ctx_instance *nss_ctx) +{ + /* + * Packets with the ptp service code should be delivered to + * PHY driver for timestamping. + */ + nss_cmn_register_service_code(nss_ctx, nss_phy_tstamp_rx_buf, + NSS_PTP_EVENT_SERVICE_CODE, nss_ctx); +} + +/* + * nss_data_plane_hal_unregister() + */ +void nss_data_plane_hal_unregister(struct nss_ctx_instance *nss_ctx) +{ + nss_cmn_unregister_service_code(nss_ctx, nss_phy_tstamp_rx_buf, + NSS_PTP_EVENT_SERVICE_CODE); +} + +/* + * nss_data_plane_hal_stats_sync() + */ +void nss_data_plane_hal_stats_sync(struct nss_data_plane_param *ndpp, + struct nss_phys_if_stats *stats) +{ + /* + * EDMA does not pass sync interface stats through phys_if_stats + */ +} + +/* + * nss_data_plane_hal_get_mtu_sz() + */ +uint16_t nss_data_plane_hal_get_mtu_sz(uint16_t mtu) +{ + /* + * Reserve space for preheader + */ + return mtu + NSS_DP_PREHEADER_SIZE; +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/hal/nss_ipq807x.c b/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/hal/nss_ipq807x.c new file mode 100644 index 000000000..1f97cbc0d --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/hal/nss_ipq807x.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "nss_core.h" +#include "nss_data_plane_hal.h" + +/* + * nss_data_plane_hal_vsi_assign() + * Called by nss-dp to assign vsi of a data plane + */ +static int nss_data_plane_hal_vsi_assign(struct nss_dp_data_plane_ctx *dpc, uint32_t vsi) +{ + struct nss_data_plane_param *dp = (struct nss_data_plane_param *)dpc; + + return nss_phys_if_vsi_assign(dp->nss_ctx, vsi, dp->if_num); +} + +/* + * nss_data_plane_hal_vsi_unassign() + * Called by nss-dp to unassign vsi of a data plane + */ +static int nss_data_plane_hal_vsi_unassign(struct nss_dp_data_plane_ctx *dpc, uint32_t vsi) +{ + struct nss_data_plane_param *dp = (struct nss_data_plane_param *)dpc; + + return nss_phys_if_vsi_unassign(dp->nss_ctx, vsi, dp->if_num); +} + +/* + * nss_data_plane_hal_get_stats() + * Called by nss-dp to get GMAC stats + */ +static void nss_data_plane_hal_get_stats(struct nss_dp_data_plane_ctx *dpc, + struct nss_dp_gmac_stats *stats) +{ + /* + * EDMA doesn't send extended statistics. + */ +} + +/* + * nss_data_plane_hal_add_dp_ops() + */ +void nss_data_plane_hal_add_dp_ops(struct nss_dp_data_plane_ops *dp_ops) +{ + dp_ops->vsi_assign = nss_data_plane_hal_vsi_assign; + dp_ops->vsi_unassign = nss_data_plane_hal_vsi_unassign; + dp_ops->get_stats = nss_data_plane_hal_get_stats; +} + +/* + * nss_data_plane_hal_register() + */ +void nss_data_plane_hal_register(struct nss_ctx_instance *nss_ctx) +{ + /* + * Packets with the ptp service code should be delivered to + * PHY driver for timestamping. + */ + nss_cmn_register_service_code(nss_ctx, nss_phy_tstamp_rx_buf, + NSS_PTP_EVENT_SERVICE_CODE, nss_ctx); +} + +/* + * nss_data_plane_hal_unregister() + */ +void nss_data_plane_hal_unregister(struct nss_ctx_instance *nss_ctx) +{ + nss_cmn_unregister_service_code(nss_ctx, nss_phy_tstamp_rx_buf, + NSS_PTP_EVENT_SERVICE_CODE); +} + +/* + * nss_data_plane_hal_stats_sync() + */ +void nss_data_plane_hal_stats_sync(struct nss_data_plane_param *ndpp, + struct nss_phys_if_stats *stats) +{ + /* + * EDMA does not pass sync interface stats through phys_if_stats + */ +} + +/* + * nss_data_plane_hal_get_mtu_sz() + */ +uint16_t nss_data_plane_hal_get_mtu_sz(uint16_t mtu) +{ + /* + * Reserve space for preheader + */ + return mtu + NSS_DP_PREHEADER_SIZE; +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/include/nss_data_plane.h b/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/include/nss_data_plane.h new file mode 100644 index 000000000..503a20a40 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/include/nss_data_plane.h @@ -0,0 +1,60 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2017,2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * nss_data_plane + * Data plane used for communication between qca-nss-drv & data plane host + */ + +#ifndef __NSS_DATA_PLANE_H +#define __NSS_DATA_PLANE_H + +#include +#include "nss_phys_if.h" + +/* + * nss_data_plane_schedule_registration() + * Called from nss_init to schedule a work to do data_plane register to data plane host driver + */ +bool nss_data_plane_schedule_registration(void); + +/* + * nss_data_plane_init_delay_work() + * Initialize data_plane workqueue + */ +int nss_data_plane_init_delay_work(void); + +/* + * nss_data_plane_destroy_delay_work() + * Destroy data_plane workqueue + */ +void nss_data_plane_destroy_delay_work(void); + +/* + * nss_data_plane_ops defines the API required to support multiple data plane targets + */ +struct nss_data_plane_ops { + void (*data_plane_register)(struct nss_ctx_instance *nss_ctx); + void (*data_plane_unregister)(void); + void (*data_plane_stats_sync)(struct nss_phys_if_stats *stats, uint16_t interface); + uint16_t (*data_plane_get_mtu_sz)(uint16_t max_mtu); +}; + +extern struct nss_data_plane_ops nss_data_plane_gmac_ops; +extern struct nss_data_plane_ops nss_data_plane_ops; + +extern int nss_skip_nw_process; +#endif diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/nss_data_plane.c b/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/nss_data_plane.c new file mode 100644 index 000000000..da116435b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/nss_data_plane.c @@ -0,0 +1,405 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_data_plane.h" +#include "nss_core.h" +#include "nss_tx_rx_common.h" +#include "nss_data_plane_hal.h" + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)) +#define NSS_DATA_PLANE_SUPPORTED_FEATURES (NETIF_F_HIGHDMA \ + | NETIF_F_HW_CSUM \ + | NETIF_F_RXCSUM \ + | NETIF_F_SG \ + | NETIF_F_FRAGLIST \ + | (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO)) +#else +#define NSS_DATA_PLANE_SUPPORTED_FEATURES (NETIF_F_HIGHDMA \ + | NETIF_F_HW_CSUM \ + | NETIF_F_RXCSUM \ + | NETIF_F_SG \ + | NETIF_F_FRAGLIST \ + | (NETIF_F_TSO | NETIF_F_TSO6)) +#endif + +/* + * nss_data_plane_param + */ +struct nss_data_plane_param nss_data_plane_params[NSS_DP_MAX_INTERFACES]; + +/* + * __nss_data_plane_init() + */ +static int __nss_data_plane_init(struct nss_dp_data_plane_ctx *dpc) +{ + struct net_device *netdev = dpc->dev; + netdev->needed_headroom += 32; + return NSS_DP_SUCCESS; +} + +/* + * __nss_data_plane_open() + * Called by nss-dp to notify open to nss-fw + */ +static int __nss_data_plane_open(struct nss_dp_data_plane_ctx *dpc, uint32_t tx_desc_ring, uint32_t rx_desc_ring, uint32_t mode) +{ + struct nss_data_plane_param *dp = (struct nss_data_plane_param *)dpc; + + if (dp->notify_open) { + return NSS_DP_SUCCESS; + } + + if (nss_phys_if_open(dp->nss_ctx, tx_desc_ring, rx_desc_ring, mode, dp->if_num, dp->bypass_nw_process) == NSS_TX_SUCCESS) { + dp->notify_open = 1; + return NSS_DP_SUCCESS; + } + return NSS_DP_FAILURE; +} + +/* + * __nss_data_plane_close() + * Called by nss-dp to notify close to nss-fw + */ +static int __nss_data_plane_close(struct nss_dp_data_plane_ctx *dpc) +{ + struct nss_data_plane_param *dp = (struct nss_data_plane_param *)dpc; + + if (!dp->notify_open) { + return NSS_DP_SUCCESS; + } + + if (nss_phys_if_close(dp->nss_ctx, dp->if_num) == NSS_TX_SUCCESS) { + dp->notify_open = 0; + return NSS_DP_SUCCESS; + } + return NSS_DP_FAILURE; +} + +/* + * __nss_data_plane_link_state() + * Called by nss-dp to notify link state change to nss-fw + */ +static int __nss_data_plane_link_state(struct nss_dp_data_plane_ctx *dpc, uint32_t link_state) +{ + struct nss_data_plane_param *dp = (struct nss_data_plane_param *)dpc; + + return nss_phys_if_link_state(dp->nss_ctx, link_state, dp->if_num); +} + +/* + * __nss_data_plane_mac_addr() + * Called by nss-dp to set mac address + */ +static int __nss_data_plane_mac_addr(struct nss_dp_data_plane_ctx *dpc, uint8_t *addr) +{ + struct nss_data_plane_param *dp = (struct nss_data_plane_param *)dpc; + + return nss_phys_if_mac_addr(dp->nss_ctx, addr, dp->if_num); +} + +/* + * __nss_data_plane_change_mtu() + * Called by nss-dp to change mtu of a data plane + */ +static int __nss_data_plane_change_mtu(struct nss_dp_data_plane_ctx *dpc, uint32_t mtu) +{ + struct nss_data_plane_param *dp = (struct nss_data_plane_param *)dpc; + + if (mtu > NSS_DP_MAX_MTU_SIZE) { + nss_warning("%px: MTU exceeds MAX size %d\n", dp, mtu); + return NSS_DP_FAILURE; + } + + return nss_phys_if_change_mtu(dp->nss_ctx, mtu, dp->if_num); +} + +/* + * __nss_data_plane_pause_on_off() + * Called by nss-dp to enable/disable pause frames + */ +static int __nss_data_plane_pause_on_off(struct nss_dp_data_plane_ctx *dpc, uint32_t pause_on) +{ + struct nss_data_plane_param *dp = (struct nss_data_plane_param *)dpc; + + return nss_phys_if_pause_on_off(dp->nss_ctx, pause_on, dp->if_num); +} + +#ifdef NSS_DRV_QRFS_ENABLE +/* + * __nss_data_plane_rx_flow_steer() + * Called by nss-dp to set flow rule of a data plane + */ +static int __nss_data_plane_rx_flow_steer(struct nss_dp_data_plane_ctx *dpc, struct sk_buff *skb, + uint32_t cpu, bool is_add) +{ + if (is_add) { + return nss_qrfs_set_flow_rule(skb, cpu, NSS_QRFS_MSG_FLOW_ADD); + } + + return nss_qrfs_set_flow_rule(skb, cpu, NSS_QRFS_MSG_FLOW_DELETE); +} +#endif + +/* + * __nss_data_plane_deinit() + * Place holder for nss-dp ops to free NSS data plane resources + */ +static int __nss_data_plane_deinit(struct nss_dp_data_plane_ctx *dpc) +{ + /* + * TODO: Implement free up of NSS data plane resources + */ + return NSS_TX_SUCCESS; +} + +/* + * __nss_data_plane_buf() + * Called by nss-dp to pass a sk_buff for xmit + */ +static netdev_tx_t __nss_data_plane_buf(struct nss_dp_data_plane_ctx *dpc, struct sk_buff *skb) +{ + struct nss_data_plane_param *dp = (struct nss_data_plane_param *)dpc; + int extra_head = dpc->dev->needed_headroom - skb_headroom(skb); + int extra_tail = 0; + nss_tx_status_t status; + struct net_device *dev = dpc->dev; + + if (skb->len < ETH_HLEN) { + nss_warning("skb->len ( %u ) < ETH_HLEN ( %u ) \n", skb->len, ETH_HLEN); + goto drop; + } + + if (skb->len > NSS_DP_MAX_PACKET_LEN) { + nss_warning("skb->len ( %u ) > Maximum packet length ( %u ) \n", skb->len, NSS_DP_MAX_PACKET_LEN); + goto drop; + } + + if (skb_cloned(skb) || extra_head > 0) { + /* + * If it is a clone and headroom is already enough, + * We just make a copy and clear the clone flag. + */ + if (extra_head <= 0) + extra_head = extra_tail = 0; + /* + * If tailroom is enough to accommodate the added headroom, + * then allocate a buffer of same size and do relocations. + * It might help kmalloc_reserve() not double the size. + */ + if (skb->end - skb->tail >= extra_head) + extra_tail = -extra_head; + + if (pskb_expand_head(skb, extra_head, extra_tail, GFP_ATOMIC)) { + nss_warning("%px: Unable to expand skb for headroom\n", dp); + goto drop; + } + } + + status = nss_phys_if_buf(dp->nss_ctx, skb, dp->if_num); + if (likely(status == NSS_TX_SUCCESS)) { + return NETDEV_TX_OK; + } else if (status == NSS_TX_FAILURE_QUEUE) { + return NETDEV_TX_BUSY; + } + +drop: + dev_kfree_skb_any(skb); + dev->stats.tx_dropped++; + + return NETDEV_TX_OK; +} + +/* + * __nss_data_plane_set_features() + * Called by nss-dp to allow data plane to modify the set of features it supports + */ +static void __nss_data_plane_set_features(struct nss_dp_data_plane_ctx *dpc) +{ + dpc->dev->features |= NSS_DATA_PLANE_SUPPORTED_FEATURES; + dpc->dev->hw_features |= NSS_DATA_PLANE_SUPPORTED_FEATURES; + dpc->dev->vlan_features |= NSS_DATA_PLANE_SUPPORTED_FEATURES; + dpc->dev->wanted_features |= NSS_DATA_PLANE_SUPPORTED_FEATURES; +} + +/* + * nss offload data plane ops + */ +static struct nss_dp_data_plane_ops dp_ops = { + .init = __nss_data_plane_init, + .open = __nss_data_plane_open, + .close = __nss_data_plane_close, + .link_state = __nss_data_plane_link_state, + .mac_addr = __nss_data_plane_mac_addr, + .change_mtu = __nss_data_plane_change_mtu, + .xmit = __nss_data_plane_buf, + .set_features = __nss_data_plane_set_features, + .pause_on_off = __nss_data_plane_pause_on_off, +#ifdef NSS_DRV_QRFS_ENABLE + .rx_flow_steer = __nss_data_plane_rx_flow_steer, +#endif + .deinit = __nss_data_plane_deinit, +}; + +/* + * nss_data_plane_register_to_nss_dp() + */ +static bool nss_data_plane_register_to_nss_dp(struct nss_ctx_instance *nss_ctx, int if_num) +{ + struct nss_data_plane_param *ndpp = &nss_data_plane_params[if_num]; + struct nss_top_instance *nss_top = nss_ctx->nss_top; + struct net_device *netdev; + bool is_open; + int core; + + netdev = nss_dp_get_netdev_by_nss_if_num(if_num); + if (!netdev) { + nss_info("%px: Platform don't have data plane%d enabled, \ + don't bring up nss_phys_if and don't register to nss-dp\n", + nss_ctx, if_num); + return false; + } + + is_open = nss_dp_is_in_open_state(netdev); + ndpp->dpc.dev = netdev; + ndpp->nss_ctx = nss_ctx; + ndpp->if_num = if_num; + ndpp->notify_open = 0; + ndpp->features = 0; + + /* + * Add data plane ops applicable to this SoC. + */ + nss_data_plane_hal_add_dp_ops(&dp_ops); + + /* + * Check if NSS NW processing to be bypassed for this data plane + */ + if (nss_skip_nw_process) { + ndpp->bypass_nw_process = 1; + } else { + ndpp->bypass_nw_process = 0; + } + + if (nss_dp_override_data_plane(netdev, &dp_ops, (struct nss_dp_data_plane_ctx *)ndpp) != NSS_DP_SUCCESS) { + nss_info("%px: Override nss-dp data plane for port %dfailed\n", nss_ctx, if_num); + return false; + } + + /* + * Setup the receive callback so that data pkts received form NSS-FW will + * be redirected to the nss-dp driver as we are overriding the data plane + */ + nss_top->phys_if_handler_id[if_num] = nss_ctx->id; + nss_phys_if_register_handler(nss_ctx, if_num); + + /* + * Packets recieved on physical interface can be exceptioned to HLOS + * from any NSS core so we need to register data plane for all + */ + for (core = 0; core < nss_top->num_nss; core++) { + nss_core_register_subsys_dp(&nss_top->nss[core], if_num, nss_dp_receive, NULL, NULL, netdev, ndpp->features); + } + + /* + * Now we are registered and our side is ready, if the data plane was opened, ask it to start again + */ + if (is_open) { + nss_dp_start_data_plane(netdev, (struct nss_dp_data_plane_ctx *)ndpp); + } + return true; +} + +/* + * nss_data_plane_unregister_from_nss_dp() + */ +static void nss_data_plane_unregister_from_nss_dp(int if_num) +{ + /* + * Do any SoC specific un-registrations. + */ + nss_data_plane_hal_unregister(nss_data_plane_params[if_num].nss_ctx); + + nss_dp_restore_data_plane(nss_data_plane_params[if_num].dpc.dev); + nss_data_plane_params[if_num].dpc.dev = NULL; + nss_data_plane_params[if_num].nss_ctx = NULL; + nss_data_plane_params[if_num].if_num = 0; + nss_data_plane_params[if_num].notify_open = 0; + nss_data_plane_params[if_num].bypass_nw_process = 0; +} + +/* + * __nss_data_plane_register() + */ +static void __nss_data_plane_register(struct nss_ctx_instance *nss_ctx) +{ + int i; + + for (i = NSS_DP_START_IFNUM; i < NSS_DP_MAX_INTERFACES; i++) { + if (!nss_data_plane_register_to_nss_dp(nss_ctx, i)) { + nss_warning("%px: Register data plane failed for data plane %d\n", nss_ctx, i); + } else { + nss_info("%px: Register data plan to data plane %d success\n", nss_ctx, i); + } + } + + /* + * Do any SoC specific registrations. + */ + nss_data_plane_hal_register(nss_ctx); +} + +/* + * __nss_data_plane_unregister() + */ +static void __nss_data_plane_unregister(void) +{ + int i, core; + + for (core = 0; core < nss_top_main.num_nss; core++) { + for (i = NSS_DP_START_IFNUM; i < NSS_DP_MAX_INTERFACES; i++) { + if (nss_top_main.nss[core].subsys_dp_register[i].ndev) { + nss_data_plane_unregister_from_nss_dp(i); + nss_core_unregister_subsys_dp(&nss_top_main.nss[core], i); + } + } + } +} + +/* + * __nss_data_plane_stats_sync() + */ +static void __nss_data_plane_stats_sync(struct nss_phys_if_stats *stats, uint16_t interface) +{ + nss_data_plane_hal_stats_sync(&nss_data_plane_params[interface], stats); +} + +/* + * __nss_data_plane_get_mtu_sz() + */ +static uint16_t __nss_data_plane_get_mtu_sz(uint16_t mtu) +{ + return nss_data_plane_hal_get_mtu_sz(mtu); +} + +/* + * nss_data_plane_ops + */ +struct nss_data_plane_ops nss_data_plane_ops = { + .data_plane_register = &__nss_data_plane_register, + .data_plane_unregister = &__nss_data_plane_unregister, + .data_plane_stats_sync = &__nss_data_plane_stats_sync, + .data_plane_get_mtu_sz = &__nss_data_plane_get_mtu_sz, +}; diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/nss_data_plane_common.c b/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/nss_data_plane_common.c new file mode 100644 index 000000000..4ffaa9ce4 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/nss_data_plane_common.c @@ -0,0 +1,84 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2016,2020 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_data_plane.h" +#include "nss_core.h" + +static struct delayed_work nss_data_plane_work; +static struct workqueue_struct *nss_data_plane_workqueue; + +extern bool pn_mq_en; +extern uint16_t pn_qlimits[NSS_MAX_NUM_PRI]; + +/* + * nss_data_plane_work_function() + * Work function that gets queued to "install" the data plane overlays + */ +static void nss_data_plane_work_function(struct work_struct *work) +{ + int ret; + struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[NSS_CORE_0]; + struct nss_top_instance *nss_top = nss_ctx->nss_top; + + /* + * The queue config command is a synchronous command and needs to be issued + * in process context, before NSS data plane switch. + */ + ret = nss_n2h_update_queue_config_sync(nss_ctx, pn_mq_en, pn_qlimits); + if (ret != NSS_TX_SUCCESS) { + nss_warning("Failed to send pnode queue config to core 0\n"); + } + + nss_top->data_plane_ops->data_plane_register(nss_ctx); +} + +/* + * nss_data_plane_schedule_registration() + * Called from nss_init to schedule a work to do data_plane register to data plane host + */ +bool nss_data_plane_schedule_registration(void) +{ + if (!queue_work_on(1, nss_data_plane_workqueue, &nss_data_plane_work.work)) { + nss_warning("Failed to register data plane workqueue on core 1\n"); + return false; + } + + nss_info("Register data plane workqueue on core 1\n"); + return true; +} + +/* + * nss_data_plane_init_delay_work() + */ +int nss_data_plane_init_delay_work(void) +{ + nss_data_plane_workqueue = create_singlethread_workqueue("nss_data_plane_workqueue"); + if (!nss_data_plane_workqueue) { + nss_warning("Can't allocate workqueue\n"); + return -ENOMEM; + } + + INIT_DELAYED_WORK(&nss_data_plane_work, nss_data_plane_work_function); + return 0; +} + +/* + * nss_data_plane_destroy_delay_work() + */ +void nss_data_plane_destroy_delay_work(void) +{ + destroy_workqueue(nss_data_plane_workqueue); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/nss_data_plane_gmac.c b/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/nss_data_plane_gmac.c new file mode 100644 index 000000000..42e10a91c --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_data_plane/nss_data_plane_gmac.c @@ -0,0 +1,396 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_data_plane.h" +#include "nss_phys_if.h" +#include "nss_core.h" +#include "nss_tx_rx_common.h" +#include + +#define NSS_DP_GMAC_SUPPORTED_FEATURES (NETIF_F_HIGHDMA | NETIF_F_HW_CSUM | NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_FRAGLIST | (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO)) +#define NSS_DATA_PLANE_GMAC_MAX_INTERFACES 4 + +static DEFINE_SPINLOCK(nss_data_plane_gmac_stats_lock); + +/* + * nss_data_plane_gmac_param + * Holds the information that is going to pass to data plane host as a cookie + */ +struct nss_data_plane_gmac_param { + int if_num; /* physical interface number */ + struct net_device *dev; /* net_device instance of this data plane */ + struct nss_ctx_instance *nss_ctx; /* which nss core */ + struct nss_gmac_stats gmac_stats; /* gmac stats */ + int notify_open; /* This data plane interface has been opened or not */ + uint32_t features; /* skb types supported by this interface */ + uint32_t bypass_nw_process; /* Do we want to bypass NW processing in NSS for this data plane? */ +} nss_data_plane_gmac_params[NSS_DATA_PLANE_GMAC_MAX_INTERFACES]; + +/* + * __nss_data_plane_open() + * Called by gmac to notify open to nss-fw + */ +static int __nss_data_plane_open(void *arg, uint32_t tx_desc_ring, uint32_t rx_desc_ring, uint32_t mode) +{ + struct nss_data_plane_gmac_param *dp = (struct nss_data_plane_gmac_param *)arg; + + if (dp->notify_open) { + return NSS_GMAC_SUCCESS; + } + if (nss_phys_if_open(dp->nss_ctx, tx_desc_ring, rx_desc_ring, mode, dp->if_num, dp->bypass_nw_process) == NSS_TX_SUCCESS) { + dp->notify_open = 1; + return NSS_GMAC_SUCCESS; + } + return NSS_GMAC_FAILURE; +} + +/* + * __nss_data_plane_close() + * Called by gmac to notify close to nss-fw + */ +static int __nss_data_plane_close(void *arg) +{ + /* + * We don't actually do synopsys gmac close in fw, just return success + */ + return NSS_GMAC_SUCCESS; +} + +/* + * __nss_data_plane_link_state() + * Called by gmac to notify link state change to nss-fw + */ +static int __nss_data_plane_link_state(void *arg, uint32_t link_state) +{ + struct nss_data_plane_gmac_param *dp = (struct nss_data_plane_gmac_param *)arg; + + return nss_phys_if_link_state(dp->nss_ctx, link_state, dp->if_num); +} + +/* + * __nss_data_plane_mac_addr() + * Called by gmac to set mac address + */ +static int __nss_data_plane_mac_addr(void *arg, uint8_t *addr) +{ + struct nss_data_plane_gmac_param *dp = (struct nss_data_plane_gmac_param *)arg; + + return nss_phys_if_mac_addr(dp->nss_ctx, addr, dp->if_num); +} + +/* + * __nss_data_plane_change_mtu() + * Called by gmac to change mtu of a gmac + */ +static int __nss_data_plane_change_mtu(void *arg, uint32_t mtu) +{ + struct nss_data_plane_gmac_param *dp = (struct nss_data_plane_gmac_param *)arg; + + /* + * MTU size check is already done in nss-gmac driver, just pass to phys_if + */ + return nss_phys_if_change_mtu(dp->nss_ctx, mtu, dp->if_num); +} + +/* + * __nss_data_plane_pause_on_off() + * Called by gmac to enable/disable pause frames + */ +static int __nss_data_plane_pause_on_off(void *arg, uint32_t pause_on) +{ + struct nss_data_plane_gmac_param *dp = (struct nss_data_plane_gmac_param *)arg; + + return nss_phys_if_pause_on_off(dp->nss_ctx, pause_on, dp->if_num); +} + +/* + * __nss_data_plane_buf() + * Called by gmac to pass a sk_buff for xmit + */ +static int __nss_data_plane_buf(void *arg, struct sk_buff *os_buf) +{ + struct nss_data_plane_gmac_param *dp = (struct nss_data_plane_gmac_param *)arg; + + return nss_phys_if_buf(dp->nss_ctx, os_buf, dp->if_num); +} + +/* + * __nss_data_plane_set_features() + * Called by gmac to allow data plane to modify the set of features it supports + */ +static void __nss_data_plane_set_features(struct net_device *netdev) +{ + netdev->features |= NSS_DP_GMAC_SUPPORTED_FEATURES; + netdev->hw_features |= NSS_DP_GMAC_SUPPORTED_FEATURES; + netdev->vlan_features |= NSS_DP_GMAC_SUPPORTED_FEATURES; + netdev->wanted_features |= NSS_DP_GMAC_SUPPORTED_FEATURES; +} + +/* + * __nss_data_plane_get_stats() + */ +static void __nss_data_plane_get_stats(void *arg, struct nss_gmac_stats *stats) +{ + struct nss_data_plane_gmac_param *dp = (struct nss_data_plane_gmac_param *)arg; + + spin_lock_bh(&nss_data_plane_gmac_stats_lock); + memcpy(stats, &dp->gmac_stats, sizeof(*stats)); + spin_unlock_bh(&nss_data_plane_gmac_stats_lock); +} + +/* + * nss offload data plane ops + */ +static struct nss_gmac_data_plane_ops dp_ops = { + .open = __nss_data_plane_open, + .close = __nss_data_plane_close, + .link_state = __nss_data_plane_link_state, + .mac_addr = __nss_data_plane_mac_addr, + .change_mtu = __nss_data_plane_change_mtu, + .xmit = __nss_data_plane_buf, + .set_features = __nss_data_plane_set_features, + .pause_on_off = __nss_data_plane_pause_on_off, + .get_stats = __nss_data_plane_get_stats, +}; + +/* + * nss_data_plane_register_to_nss_gmac() + */ +static bool nss_data_plane_register_to_nss_gmac(struct nss_ctx_instance *nss_ctx, int if_num) +{ + struct nss_data_plane_gmac_param *ndpp = &nss_data_plane_gmac_params[if_num]; + struct nss_top_instance *nss_top = nss_ctx->nss_top; + struct net_device *netdev; + bool is_open; + int core; + + netdev = nss_gmac_get_netdev_by_macid(if_num); + if (!netdev) { + nss_info("Platform don't have gmac%d enabled, don't bring up nss_phys_if and don't register to nss-gmac", if_num); + return false; + } + + is_open = nss_gmac_is_in_open_state(netdev); + ndpp->dev = netdev; + ndpp->nss_ctx = nss_ctx; + ndpp->if_num = if_num; + ndpp->notify_open = 0; + ndpp->features = 0; + + /* + * Check if NSS NW processing to be bypassed for this GMAC + */ + if (nss_skip_nw_process) { + ndpp->bypass_nw_process = 1; + } else { + ndpp->bypass_nw_process = 0; + } + + if (nss_gmac_override_data_plane(netdev, &dp_ops, ndpp) != NSS_GMAC_SUCCESS) { + nss_info("Override nss-gmac data plane failed\n"); + return false; + } + + /* + * Setup the receive callback so that data pkts received form NSS-FW will + * be redirected to the gmac driver as we are overriding the data plane + */ + nss_top->phys_if_handler_id[if_num] = nss_ctx->id; + nss_phys_if_register_handler(nss_ctx, if_num); + + /* + * Packets recieved on physical interface can be exceptioned to HLOS + * from any NSS core so we need to register data plane for all + */ + for (core = 0; core < nss_top->num_nss; core++) { + nss_core_register_subsys_dp(&nss_top->nss[core], if_num, nss_gmac_receive, NULL, NULL, netdev, ndpp->features); + } + + /* + * Now we are registered and our side is ready, if the gmac was opened, ask it to start again + */ + if (is_open) { + nss_gmac_start_data_plane(netdev, ndpp); + } + return true; +} + +/* + * nss_data_plane_unregister_from_nss_gmac() + */ +static void nss_data_plane_unregister_from_nss_gmac(int if_num) +{ + nss_gmac_restore_data_plane(nss_data_plane_gmac_params[if_num].dev); + nss_data_plane_gmac_params[if_num].dev = NULL; + nss_data_plane_gmac_params[if_num].nss_ctx = NULL; + nss_data_plane_gmac_params[if_num].if_num = 0; + nss_data_plane_gmac_params[if_num].notify_open = 0; + nss_data_plane_gmac_params[if_num].bypass_nw_process = 0; +} + +/* + * __nss_data_plane_register() + */ +static void __nss_data_plane_register(struct nss_ctx_instance *nss_ctx) +{ + int i; + + for (i = 0; i < NSS_DATA_PLANE_GMAC_MAX_INTERFACES; i++) { + if (!nss_data_plane_register_to_nss_gmac(nss_ctx, i)) { + nss_warning("%px: Register data plane failed for gmac:%d\n", nss_ctx, i); + } else { + nss_info("%px: Register data plan to gmac:%d success\n", nss_ctx, i); + } + } +} + +/* + * __nss_data_plane_unregister() + */ +static void __nss_data_plane_unregister(void) +{ + int i, core; + + for (core = 0; core < nss_top_main.num_nss; core++) { + for (i = 0; i < NSS_DATA_PLANE_GMAC_MAX_INTERFACES; i++) { + if (nss_top_main.nss[core].subsys_dp_register[i].ndev) { + nss_data_plane_unregister_from_nss_gmac(i); + nss_core_unregister_subsys_dp(&nss_top_main.nss[core], i); + } + } + } +} + +/* + * __nss_data_plane_stats_sync() + * Handle the syncing of gmac data plane stats. + */ +static void __nss_data_plane_stats_sync(struct nss_phys_if_stats *stats, uint16_t interface) +{ + struct nss_gmac_stats *gmac_stats = &nss_data_plane_gmac_params[interface].gmac_stats; + + spin_lock_bh(&nss_data_plane_gmac_stats_lock); + gmac_stats->rx_bytes += stats->if_stats.rx_bytes; + gmac_stats->rx_packets += stats->if_stats.rx_packets; + gmac_stats->rx_errors += stats->estats.rx_errors; + gmac_stats->rx_receive_errors += stats->estats.rx_receive_errors; + gmac_stats->rx_descriptor_errors += stats->estats.rx_descriptor_errors; + gmac_stats->rx_late_collision_errors += stats->estats.rx_late_collision_errors; + gmac_stats->rx_dribble_bit_errors += stats->estats.rx_dribble_bit_errors; + gmac_stats->rx_length_errors += stats->estats.rx_length_errors; + gmac_stats->rx_ip_header_errors += stats->estats.rx_ip_header_errors; + gmac_stats->rx_ip_payload_errors += stats->estats.rx_ip_payload_errors; + gmac_stats->rx_no_buffer_errors += stats->estats.rx_no_buffer_errors; + gmac_stats->rx_transport_csum_bypassed += stats->estats.rx_transport_csum_bypassed; + + gmac_stats->tx_bytes += stats->if_stats.tx_bytes; + gmac_stats->tx_packets += stats->if_stats.tx_packets; + gmac_stats->tx_collisions += stats->estats.tx_collisions; + gmac_stats->tx_errors += stats->estats.tx_errors; + gmac_stats->tx_jabber_timeout_errors += stats->estats.tx_jabber_timeout_errors; + gmac_stats->tx_frame_flushed_errors += stats->estats.tx_frame_flushed_errors; + gmac_stats->tx_loss_of_carrier_errors += stats->estats.tx_loss_of_carrier_errors; + gmac_stats->tx_no_carrier_errors += stats->estats.tx_no_carrier_errors; + gmac_stats->tx_late_collision_errors += stats->estats.tx_late_collision_errors; + gmac_stats->tx_excessive_collision_errors += stats->estats.tx_excessive_collision_errors; + gmac_stats->tx_excessive_deferral_errors += stats->estats.tx_excessive_deferral_errors; + gmac_stats->tx_underflow_errors += stats->estats.tx_underflow_errors; + gmac_stats->tx_ip_header_errors += stats->estats.tx_ip_header_errors; + gmac_stats->tx_ip_payload_errors += stats->estats.tx_ip_payload_errors; + gmac_stats->tx_dropped += stats->estats.tx_dropped; + + gmac_stats->hw_errs[0] += stats->estats.hw_errs[0]; + gmac_stats->hw_errs[1] += stats->estats.hw_errs[1]; + gmac_stats->hw_errs[2] += stats->estats.hw_errs[2]; + gmac_stats->hw_errs[3] += stats->estats.hw_errs[3]; + gmac_stats->hw_errs[4] += stats->estats.hw_errs[4]; + gmac_stats->hw_errs[5] += stats->estats.hw_errs[5]; + gmac_stats->hw_errs[6] += stats->estats.hw_errs[6]; + gmac_stats->hw_errs[7] += stats->estats.hw_errs[7]; + gmac_stats->hw_errs[8] += stats->estats.hw_errs[8]; + gmac_stats->hw_errs[9] += stats->estats.hw_errs[9]; + gmac_stats->rx_missed += stats->estats.rx_missed; + + gmac_stats->fifo_overflows += stats->estats.fifo_overflows; + gmac_stats->rx_scatter_errors += stats->estats.rx_scatter_errors; + gmac_stats->tx_ts_create_errors += stats->estats.tx_ts_create_errors; + gmac_stats->gmac_total_ticks += stats->estats.gmac_total_ticks; + gmac_stats->gmac_worst_case_ticks += stats->estats.gmac_worst_case_ticks; + gmac_stats->gmac_iterations += stats->estats.gmac_iterations; + gmac_stats->tx_pause_frames += stats->estats.tx_pause_frames; + gmac_stats->mmc_rx_overflow_errors += stats->estats.mmc_rx_overflow_errors; + gmac_stats->mmc_rx_watchdog_timeout_errors += stats->estats.mmc_rx_watchdog_timeout_errors; + gmac_stats->mmc_rx_crc_errors += stats->estats.mmc_rx_crc_errors; + gmac_stats->mmc_rx_ip_header_errors += stats->estats.mmc_rx_ip_header_errors; + gmac_stats->mmc_rx_octets_g += stats->estats.mmc_rx_octets_g; + gmac_stats->mmc_rx_ucast_frames += stats->estats.mmc_rx_ucast_frames; + gmac_stats->mmc_rx_bcast_frames += stats->estats.mmc_rx_bcast_frames; + gmac_stats->mmc_rx_mcast_frames += stats->estats.mmc_rx_mcast_frames; + gmac_stats->mmc_rx_undersize += stats->estats.mmc_rx_undersize; + gmac_stats->mmc_rx_oversize += stats->estats.mmc_rx_oversize; + gmac_stats->mmc_rx_jabber += stats->estats.mmc_rx_jabber; + gmac_stats->mmc_rx_octets_gb += stats->estats.mmc_rx_octets_gb; + gmac_stats->mmc_rx_frag_frames_g += stats->estats.mmc_rx_frag_frames_g; + gmac_stats->mmc_tx_octets_g += stats->estats.mmc_tx_octets_g; + gmac_stats->mmc_tx_ucast_frames += stats->estats.mmc_tx_ucast_frames; + gmac_stats->mmc_tx_bcast_frames += stats->estats.mmc_tx_bcast_frames; + gmac_stats->mmc_tx_mcast_frames += stats->estats.mmc_tx_mcast_frames; + gmac_stats->mmc_tx_deferred += stats->estats.mmc_tx_deferred; + gmac_stats->mmc_tx_single_col += stats->estats.mmc_tx_single_col; + gmac_stats->mmc_tx_multiple_col += stats->estats.mmc_tx_multiple_col; + gmac_stats->mmc_tx_octets_gb += stats->estats.mmc_tx_octets_gb; + + spin_unlock_bh(&nss_data_plane_gmac_stats_lock); +} + +/* + * __nss_data_plane_get_mtu_sz() + */ +static uint16_t __nss_data_plane_get_mtu_sz(uint16_t max_mtu) +{ + /* + * GMACs support 3 Modes + * Normal Mode Payloads upto 1522 Bytes ( 1500 + 14 + 4(Vlan) + 4(CRC)) + * Mini Jumbo Mode Payloads upto 2000 Bytes (1978 + 14 + 4(Vlan) + 4 (CRC)) + * Full Jumbo Mode payloads upto 9622 Bytes (9600 + 14 + 4(Vlan) + 4 (CRC)) + */ + + /* + * The configured MTU value on a gmac interface should be one of these + * cases. Finding the Needed MTU size that is required for GMAC to + * successfully receive the frame. + */ + if (max_mtu <= NSS_GMAC_NORMAL_FRAME_MTU) { + return NSS_GMAC_NORMAL_FRAME_MTU; + } + if (max_mtu <= NSS_GMAC_MINI_JUMBO_FRAME_MTU) { + return NSS_GMAC_MINI_JUMBO_FRAME_MTU; + } + if (max_mtu <= NSS_GMAC_FULL_JUMBO_FRAME_MTU) { + return NSS_GMAC_FULL_JUMBO_FRAME_MTU; + } + return 0; +} + +/* + * nss_data_plane_gmac_ops + */ +struct nss_data_plane_ops nss_data_plane_gmac_ops = { + .data_plane_register = &__nss_data_plane_register, + .data_plane_unregister = &__nss_data_plane_unregister, + .data_plane_stats_sync = &__nss_data_plane_stats_sync, + .data_plane_get_mtu_sz = &__nss_data_plane_get_mtu_sz, +}; diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_dma.c b/feeds/ipq807x/qca-nss-drv/src/nss_dma.c new file mode 100755 index 000000000..a3c36f80b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_dma.c @@ -0,0 +1,501 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_dma.c + * NSS DMA APIs + */ + +#include +#include "nss_dma_stats.h" +#include "nss_dma_log.h" +#include "nss_dma_strings.h" + +/* + * Test configuration value + */ +struct nss_dma_test_cfg_val { + int val; /* field value */ + int min; /* Minimum value */ + int max; /* Maximum value */ +}; + +/* + * Test configuration for user + */ +struct nss_dma_test_cfg_user { + struct nss_dma_test_cfg_val run; /* test run state */ + struct nss_dma_test_cfg_val code; /* test run code */ + struct nss_dma_test_cfg_val type; /* test type code */ + struct nss_dma_test_cfg_val packets; /* packet count per loop */ + int result_tx_packets; /* test results TX packets */ + int result_rx_packets; /* test result RX packets */ + int result_time; /* test time */ +}; + +static struct nss_dma_test_cfg_user test_cfg = { + .run = {.val = 0, .min = 0 /* stopped */, .max = 1 /* running */}, + .code = {.val = 1, .min = 1 /* linearize */, .max = 2 /* split */}, + .type = {.val = NSS_DMA_TEST_TYPE_DEFAULT, .min = NSS_DMA_TEST_TYPE_DEFAULT, .max = NSS_DMA_TEST_TYPE_MAX}, + .packets = {.val = 1, .min = 1, .max = 65536}, +}; + +/* + * Private data structure. + */ +struct nss_dma_pvt { + struct semaphore sem; /* Semaphore structure. */ + struct completion complete; /* Completion structure. */ + int response; /* Response from FW. */ + void *cb; /* Original cb for sync msgs. */ + void *app_data; /* Original app_data for sync msgs. */ +}; + +static struct nss_dma_pvt nss_dma_cfg_pvt; + +/* + * nss_dma_verify_if_num() + * Verify if_num passed to us. + */ +static inline bool nss_dma_verify_if_num(uint32_t if_num) +{ + return if_num == NSS_DMA_INTERFACE; +} + +/* + * nss_dma_interface_handler() + * Handle NSS -> HLOS messages for DMA Statistics + */ +static void nss_dma_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, + __attribute__((unused))void *app_data) +{ + struct nss_dma_msg *ndm = (struct nss_dma_msg *)ncm; + nss_dma_msg_callback_t cb; + + if (!nss_dma_verify_if_num(ncm->interface)) { + nss_warning("%px: invalid interface %d for dma\n", nss_ctx, ncm->interface); + return; + } + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_DMA_MSG_TYPE_MAX) { + nss_warning("%px: received invalid message %d for dma", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_dma_msg)) { + nss_warning("%px: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Trace messages. + */ + nss_dma_log_rx_msg(ndm); + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Update driver statistics and send statistics notifications to the registered modules. + */ + if (ndm->cm.type == NSS_DMA_MSG_TYPE_SYNC_STATS) { + nss_dma_stats_sync(nss_ctx, &ndm->msg.stats); + + } + + /* + * Update the callback and app_data for NOTIFY messages + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_core_get_msg_handler(nss_ctx, ncm->interface); + ncm->app_data = (nss_ptr_t)nss_ctx->nss_rx_interface_handlers[ncm->interface].app_data; + } + + /* + * Do we have a callback? + */ + if (!ncm->cb) { + return; + } + + /* + * callback + */ + cb = (nss_dma_msg_callback_t)ncm->cb; + cb((void *)ncm->app_data, ncm); +} + +/* + * nss_dma_register_handler() + * Register handler for messaging + */ +void nss_dma_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx = nss_dma_get_context(); + + nss_info("%px: nss_dma_register_handler", nss_ctx); + nss_core_register_handler(nss_ctx, NSS_DMA_INTERFACE, nss_dma_msg_handler, NULL); + + nss_dma_stats_dentry_create(); + nss_dma_strings_dentry_create(); +} +EXPORT_SYMBOL(nss_dma_register_handler); + +/* + * nss_dma_tx_msg() + * Transmit an dma message to the FW with a specified size. + */ +nss_tx_status_t nss_dma_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_dma_msg *ndm) +{ + struct nss_cmn_msg *ncm = &ndm->cm; + + /* + * Sanity check the message + */ + if (!nss_dma_verify_if_num(ncm->interface)) { + nss_warning("%px: tx request for another interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type >= NSS_DMA_MSG_TYPE_MAX) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + /* + * Trace messages. + */ + nss_dma_log_tx_msg(ndm); + + return nss_core_send_cmd(nss_ctx, ndm, sizeof(*ndm), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_dma_tx_msg); + +/* + * nss_dma_msg_test_callback() + * Callback function for dma test start configuration + */ +static void nss_dma_msg_test_callback(void *app_data, struct nss_cmn_msg *ncm) +{ + struct nss_ctx_instance *nss_ctx __attribute__((unused)) = (struct nss_ctx_instance *)app_data; + struct nss_dma_msg *ndm = (struct nss_dma_msg *)ncm; + struct nss_dma_test_cfg *ndtc = &ndm->msg.test_cfg; + struct nss_cmn_node_stats *ncns = &ndtc->node_stats; + + test_cfg.run.val = 0; /* test completed */ + + /* + * Test start has been failed. Restore the value to initial state. + */ + if (ndm->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("%px: nss dma test failed: %d \n", nss_ctx, ndm->cm.error); + test_cfg.result_tx_packets = 0; + test_cfg.result_rx_packets = 0; + test_cfg.result_time = 0; + return; + } + + test_cfg.result_tx_packets = ncns->tx_packets; + test_cfg.result_rx_packets = ncns->rx_packets; + test_cfg.result_time = ndtc->time_delta; + + nss_info("%px: nss dma test complete\n", nss_ctx); + nss_info("%px: results tx=%u, rx=%u, time=%u\n", ndm, ncns->tx_packets, ncns->rx_packets, ndtc->time_delta); +} + +/* + * nss_dma_msg_test() + * Send NSS DMA test start message. + */ +static nss_tx_status_t nss_dma_msg_test(struct nss_ctx_instance *nss_ctx) +{ + struct nss_dma_msg ndm; + uint32_t flags = 0; + int32_t status; + size_t len; + + len = sizeof(struct nss_cmn_msg) + sizeof(struct nss_dma_test_cfg); + + nss_info("%px: DMA test message:%x\n", nss_ctx, test_cfg.run.val); + if (test_cfg.code.val == 1) { + flags = NSS_DMA_TEST_FLAGS_LINEARIZE; + } + + nss_dma_msg_init(&ndm, NSS_DMA_INTERFACE, NSS_DMA_MSG_TYPE_TEST_PERF, len, nss_dma_msg_test_callback, nss_ctx); + + ndm.msg.test_cfg.packet_count = test_cfg.packets.val; + ndm.msg.test_cfg.type = test_cfg.type.val; + ndm.msg.test_cfg.flags = flags; + + status = nss_dma_tx_msg(nss_ctx, &ndm); + if (unlikely(status != NSS_TX_SUCCESS)) { + return status; + } + + /* + * Test is now running + */ + test_cfg.run.val = 1; + return NSS_TX_SUCCESS; +} + +/* + * nss_dma_msg_init() + * Initialize DMA message. + */ +void nss_dma_msg_init(struct nss_dma_msg *ndm, uint16_t if_num, uint32_t type, uint32_t len, nss_dma_msg_callback_t cb, + void *app_data) +{ + nss_cmn_msg_init(&ndm->cm, if_num, type, len, (void *)cb, app_data); +} +EXPORT_SYMBOL(nss_dma_msg_init); + +/* + * nss_crypto_cmn_get_context() + * get NSS context instance for crypto handle + */ +struct nss_ctx_instance *nss_dma_get_context(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.dma_handler_id]; +} +EXPORT_SYMBOL(nss_dma_get_context); + +/* + * nss_dma_test_handler() + * Handles the performance test. + */ +static int nss_dma_test_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + struct nss_ctx_instance *nss_ctx = nss_dma_get_context(); + int cur_state = test_cfg.run.val; + int ret; + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + if (ret != NSS_SUCCESS) { + return ret; + } + + if (!write) { + return ret; + } + + /* + * Check any tests are already scheduled + */ + if (cur_state > 0) { + nss_info("%px: Test is already running, stopping it.\n", nss_ctx); + } else { + nss_info("%px: Test is not running, starting it.\n", nss_ctx); + } + + ret = nss_dma_msg_test(nss_ctx); + if (ret != NSS_SUCCESS) { + nss_warning("%px: Test configuration has failed.\n", nss_ctx); + test_cfg.run.val = 0; + } + + return ret; +} + +static struct ctl_table nss_dma_table[] = { + { + .procname = "test_run", + .data = &test_cfg.run.val, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = nss_dma_test_handler, + .extra1 = &test_cfg.run.min, + .extra2 = &test_cfg.run.max, + }, + { + .procname = "test_code", + .data = &test_cfg.code.val, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = &test_cfg.code.min, + .extra2 = &test_cfg.code.max, + }, + { + .procname = "test_type", + .data = &test_cfg.type.val, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = &test_cfg.type.min, + .extra2 = &test_cfg.type.max, + }, + { + .procname = "test_packets", + .data = &test_cfg.packets.val, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = &test_cfg.packets.min, + .extra2 = &test_cfg.packets.max, + }, + { + .procname = "result_tx", + .data = &test_cfg.result_tx_packets, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + { + .procname = "result_rx", + .data = &test_cfg.result_rx_packets, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + { + .procname = "result_time", + .data = &test_cfg.result_time, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, + { } +}; + +static struct ctl_table nss_dma_dir[] = { + { + .procname = "dma", + .mode = 0555, + .child = nss_dma_table, + }, + { } +}; + +static struct ctl_table nss_dma_root_dir[] = { + { + .procname = "nss", + .mode = 0555, + .child = nss_dma_dir, + }, + { } +}; + +static struct ctl_table nss_dma_root[] = { + { + .procname = "dev", + .mode = 0555, + .child = nss_dma_root_dir, + }, + { } +}; + +static struct ctl_table_header *nss_dma_header; + +/* + * nss_dma_register_sysctl() + */ +void nss_dma_register_sysctl(void) +{ + + /* + * dma sema init. + */ + sema_init(&nss_dma_cfg_pvt.sem, 1); + init_completion(&nss_dma_cfg_pvt.complete); + + /* + * Register sysctl table. + */ + nss_dma_header = register_sysctl_table(nss_dma_root); +} + +/* + * nss_dma_unregister_sysctl() + * Unregister sysctl specific to dma + */ +void nss_dma_unregister_sysctl(void) +{ + /* + * Unregister sysctl table. + */ + if (nss_dma_header) { + unregister_sysctl_table(nss_dma_header); + } +} + +/* + * nss_dma_notify_register() + * Register to receive dma notify messages. + */ +struct nss_ctx_instance *nss_dma_notify_register(int core, nss_dma_msg_callback_t cb, void *app_data) +{ + struct nss_ctx_instance *nss_ctx = nss_dma_get_context(); + uint32_t ret; + + ret = nss_core_register_handler(nss_ctx, NSS_DMA_INTERFACE, nss_dma_msg_handler, app_data); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: unable to register event handler for DMA interface", nss_ctx); + return NULL; + } + + ret = nss_core_register_msg_handler(nss_ctx, NSS_DMA_INTERFACE, cb); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_core_unregister_handler(nss_ctx, NSS_DMA_INTERFACE); + nss_warning("%px: unable to register event handler for DMA interface", nss_ctx); + return NULL; + } + + return nss_ctx; +} +EXPORT_SYMBOL(nss_dma_notify_register); + +/* + * nss_dma_notify_unregister() + * Unregister to receive dma notify messages. + */ +void nss_dma_notify_unregister(int core) +{ + struct nss_ctx_instance *nss_ctx = nss_dma_get_context(); + uint32_t ret; + + BUG_ON(!nss_ctx); + + ret = nss_core_unregister_msg_handler(nss_ctx, NSS_DMA_INTERFACE); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: unable to unregister event handler for DMA interface", nss_ctx); + return; + } + + ret = nss_core_unregister_handler(nss_ctx, NSS_DMA_INTERFACE); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: unable to unregister event handler for DMA interface", nss_ctx); + return; + } + + return; +} +EXPORT_SYMBOL(nss_dma_notify_unregister); + +/* + * nss_dma_init() + */ +void nss_dma_init(void) +{ + nss_dma_register_sysctl(); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_dma_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_dma_log.c new file mode 100755 index 000000000..7f367c8ca --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_dma_log.c @@ -0,0 +1,140 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_dma_log.c + * NSS DMA logger file. + */ + +#include "nss_core.h" + +/* + * nss_dma_log_message_types_str + * DMA message strings + */ +static int8_t *nss_dma_log_message_types_str[NSS_DMA_MSG_TYPE_MAX] __maybe_unused = { + "DMA invalid message", + "DMA Configure message", + "DMA Statistics sync message", + "DMA Test linearization performance", +}; + +/* + * nss_dma_log_error_response_types_str + * Strings for error types for DMA messages + */ +static int8_t *nss_dma_log_error_response_types_str[NSS_DMA_MSG_ERROR_MAX] __maybe_unused = { + "No error", + "HW initialization failed", + "Unhandled message type for node", + "Error performing the test", +}; + +/* + * nss_dma_map_msg() + * Log NSS DMA configure message. + */ +static void nss_dma_configure_msg(struct nss_dma_msg *ndm) +{ + nss_trace("%px: NSS DMA configure message: \n",ndm); +} + +/* + * nss_dma_test_perf_msg() + * Log NSS DMA performace test message. + */ +static void nss_dma_test_perf_msg(struct nss_dma_msg *ndm) +{ + struct nss_dma_test_cfg *ndtc = &ndm->msg.test_cfg; + struct nss_cmn_node_stats *ncns = &ndtc->node_stats; + + nss_trace("%px: NSS DMA test perf message: \n",ndm); + nss_trace("%px: processed (TX: %u, RX:%u, time:%u)\n", ndm, ncns->tx_packets, ncns->rx_packets, ndtc->time_delta); + nss_trace("%px: test parameters (type:%u, packet_cnt:%u)\n", ndm, ndtc->type, ndtc->packet_count); +} + +/* + * nss_dma_log_verbose() + * Log message contents. + */ +static void nss_dma_log_verbose(struct nss_dma_msg *ndm) +{ + switch (ndm->cm.type) { + case NSS_DMA_MSG_TYPE_CONFIGURE: + nss_dma_configure_msg(ndm); + break; + + case NSS_DMA_MSG_TYPE_TEST_PERF: + nss_dma_test_perf_msg(ndm); + break; + + default: + nss_trace("%px: Invalid message type\n", ndm); + break; + } +} + +/* + * nss_dma_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_dma_log_tx_msg(struct nss_dma_msg *ndm) +{ + if (ndm->cm.type >= NSS_DMA_MSG_TYPE_MAX) { + nss_info("%px: Invalid message type\n", ndm); + return; + } + + nss_info("%px: type[%d]:%s\n", ndm, ndm->cm.type, nss_dma_log_message_types_str[ndm->cm.type]); + nss_dma_log_verbose(ndm); +} + +/* + * nss_dma_log_rx_msg() + * Log messages received from FW. + */ +void nss_dma_log_rx_msg(struct nss_dma_msg *ndm) +{ + if (ndm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", ndm); + return; + } + + if (ndm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ndm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", ndm, ndm->cm.type, + nss_dma_log_message_types_str[ndm->cm.type], + ndm->cm.response, nss_cmn_response_str[ndm->cm.response]); + goto verbose; + } + + if (ndm->cm.error >= NSS_DMA_MSG_ERROR_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + ndm, ndm->cm.type, nss_dma_log_message_types_str[ndm->cm.type], + ndm->cm.response, nss_cmn_response_str[ndm->cm.response], + ndm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + ndm, ndm->cm.type, nss_dma_log_message_types_str[ndm->cm.type], + ndm->cm.response, nss_cmn_response_str[ndm->cm.response], + ndm->cm.error, nss_dma_log_error_response_types_str[ndm->cm.error]); + +verbose: + nss_dma_log_verbose(ndm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_dma_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_dma_log.h new file mode 100755 index 000000000..4a9b9c3ad --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_dma_log.h @@ -0,0 +1,38 @@ +/* + ****************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_DMA_LOG_H +#define __NSS_DMA_LOG_H +/* + * nss_dma_log.h + * NSS DMA Log Header File + */ + +/* + * nss_dma_log_tx_msg + * Logs an DMA message that is sent to the NSS firmware. + */ +void nss_dma_log_tx_msg(struct nss_dma_msg *ndm); + +/* + * nss_dma_log_rx_msg + * Logs an DMA message that is received from the NSS firmware. + */ +void nss_dma_log_rx_msg(struct nss_dma_msg *ndm); + +#endif /* __NSS_DMA_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_dma_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_dma_stats.c new file mode 100755 index 000000000..b38b4d2c5 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_dma_stats.c @@ -0,0 +1,119 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_dma_stats.h" +#include "nss_dma_strings.h" + +/* + * Spinlock to protect DMA statistics update/read + */ +DEFINE_SPINLOCK(nss_dma_stats_lock); + +/* + * nss_dma_stats + * DMA statistics + */ +uint64_t nss_dma_stats[NSS_DMA_STATS_MAX]; + +/* + * nss_dma_stats_read() + * Read DMA statistics + */ +static ssize_t nss_dma_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + /* + * Max output lines = #stats * NSS_MAX_CORES + + * few blank lines for banner printing + Number of Extra outputlines for future reference to add new stats + */ + uint32_t max_output_lines = NSS_DMA_STATS_MAX + NSS_STATS_EXTRA_OUTPUT_LINES; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + uint64_t *stats_shadow; + ssize_t bytes_read = 0; + size_t size_wr = 0; + char *lbuf; + int32_t i; + + lbuf = vzalloc(size_al); + if (!lbuf) { + nss_warning("Could not allocate memory for local statistics buffer"); + return -ENOMEM; + } + + stats_shadow = vzalloc(NSS_DMA_STATS_MAX * 8); + if (!stats_shadow) { + nss_warning("Could not allocate memory for local shadow buffer"); + vfree(lbuf); + return -ENOMEM; + } + + /* + * DMA statistics + */ + spin_lock_bh(&nss_dma_stats_lock); + for (i = 0; i < NSS_DMA_STATS_MAX; i++) { + stats_shadow[i] = nss_dma_stats[i]; + } + spin_unlock_bh(&nss_dma_stats_lock); + + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "dma", nss_top_main.dma_handler_id); + size_wr += nss_stats_print("dma", NULL, NSS_STATS_SINGLE_INSTANCE, nss_dma_strings_stats, + stats_shadow, NSS_DMA_STATS_MAX, lbuf, size_wr, size_al); + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + + vfree(lbuf); + vfree(stats_shadow); + return bytes_read; +} + +/* + * nss_dma_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(dma); + +/* + * nss_dma_stats_dentry_create() + * Create DMA statistics debug entry. + */ +void nss_dma_stats_dentry_create(void) +{ + nss_stats_create_dentry("dma", &nss_dma_stats_ops); +} + +/* + * nss_dma_stats_sync() + * Handle the syncing of NSS DMA statistics. + */ +void nss_dma_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_dma_stats *nds) +{ + uint64_t *dma_stats; + uint32_t *msg_stats; + uint16_t i = 0; + + spin_lock_bh(&nss_dma_stats_lock); + + msg_stats = (uint32_t *)nds; + dma_stats = nss_dma_stats; + + for (i = 0; i < NSS_DMA_STATS_MAX; i++, dma_stats++, msg_stats++) { + *dma_stats += *msg_stats; + } + + spin_unlock_bh(&nss_dma_stats_lock); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_dma_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_dma_stats.h new file mode 100755 index 000000000..548108e0f --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_dma_stats.h @@ -0,0 +1,65 @@ +/* + ****************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_DMA_STATS_H +#define __NSS_DMA_STATS_H + +#include + +/** + * nss_dma_stats_types + * DMA node statistics. + */ +enum nss_dma_stats_types { + NSS_DMA_STATS_NO_REQ = NSS_STATS_NODE_MAX, /**< Request descriptor not available. */ + NSS_DMA_STATS_NO_DESC, /**< DMA descriptors not available. */ + NSS_DMA_STATS_NEXTHOP, /**< Failed to retrive next hop. */ + NSS_DMA_STATS_FAIL_NEXTHOP_QUEUE, /**< Failed to queue next hop. */ + NSS_DMA_STATS_FAIL_LINEAR_SZ, /**< Failed to get memory for linearization. */ + NSS_DMA_STATS_FAIL_LINEAR_ALLOC, /**< Failed to allocate buffer for linearization. */ + NSS_DMA_STATS_FAIL_LINEAR_NO_SG, /**< Skip linearization due to non-SG packet. */ + NSS_DMA_STATS_FAIL_SPLIT_SZ, /**< Failed to spliting buffer into multiple buffers. */ + NSS_DMA_STATS_FAIL_SPLIT_ALLOC, /**< Failed to allocate buffer for split. */ + NSS_DMA_STATS_FAIL_SYNC_ALLOC, /**< Failed to allocate buffer for sending statistics. */ + NSS_DMA_STATS_FAIL_CTX_ACTIVE, /**< Failed to queue as the node is not active. */ + NSS_DMA_STATS_FAIL_HW_E0, /**< Failed to process in HW, error code E0. */ + NSS_DMA_STATS_FAIL_HW_E1, /**< Failed to process in HW, error code E1. */ + NSS_DMA_STATS_FAIL_HW_E2, /**< Failed to process in HW, error code E2. */ + NSS_DMA_STATS_FAIL_HW_E3, /**< Failed to process in HW, error code E3. */ + NSS_DMA_STATS_FAIL_HW_E4, /**< Failed to process in HW, error code E4. */ + NSS_DMA_STATS_FAIL_HW_E5, /**< Failed to process in HW, error code E5. */ + NSS_DMA_STATS_FAIL_HW_E6, /**< Failed to process in HW, error code E6. */ + NSS_DMA_STATS_FAIL_HW_E7, /**< Failed to process in HW, error code E7. */ + NSS_DMA_STATS_FAIL_HW_E8, /**< Failed to process in HW, error code E8. */ + NSS_DMA_STATS_FAIL_HW_E9, /**< Failed to process in HW, error code E9. */ + NSS_DMA_STATS_FAIL_HW_E10, /**< Failed to process in HW, error code E10. */ + NSS_DMA_STATS_FAIL_HW_E11, /**< Failed to process in HW, error code E11. */ + NSS_DMA_STATS_FAIL_HW_E12, /**< Failed to process in HW, error code E12. */ + NSS_DMA_STATS_FAIL_HW_E13, /**< Failed to process in HW, error code E13. */ + NSS_DMA_STATS_FAIL_HW_E14, /**< Failed to process in HW, error code E14. */ + NSS_DMA_STATS_FAIL_HW_E15, /**< Failed to process in HW, error code E15. */ + NSS_DMA_STATS_MAX, /**< Maximum message type. */ +}; + +/* + * DMA statistics APIs + */ +extern void nss_dma_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_dma_stats *nds); +extern void nss_dma_stats_dentry_create(void); + +#endif /* __NSS_DMA_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_dma_strings.c b/feeds/ipq807x/qca-nss-drv/src/nss_dma_strings.c new file mode 100755 index 000000000..402afc7be --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_dma_strings.c @@ -0,0 +1,88 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_stats.h" +#include "nss_core.h" +#include "nss_strings.h" +#include "nss_dma_stats.h" + +/* + * nss_dma_strings_stats + * DMA statistics strings. + */ +struct nss_stats_info nss_dma_strings_stats[NSS_DMA_STATS_MAX] = { + {"rx_pkts" , NSS_STATS_TYPE_COMMON}, + {"rx_byts" , NSS_STATS_TYPE_COMMON}, + {"tx_pkts" , NSS_STATS_TYPE_COMMON}, + {"tx_byts" , NSS_STATS_TYPE_COMMON}, + {"rx_queue[0]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[1]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[2]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[3]_drops" , NSS_STATS_TYPE_DROP}, + {"no_req" , NSS_STATS_TYPE_SPECIAL}, + {"no_desc" , NSS_STATS_TYPE_SPECIAL}, + {"fail_nexthop" , NSS_STATS_TYPE_SPECIAL}, + {"fail_nexthop_queue" , NSS_STATS_TYPE_SPECIAL}, + {"fail_linear_sz" , NSS_STATS_TYPE_SPECIAL}, + {"fail_linear_alloc" , NSS_STATS_TYPE_SPECIAL}, + {"fail_linear_no_sg" , NSS_STATS_TYPE_SPECIAL}, + {"fail_split_sz" , NSS_STATS_TYPE_SPECIAL}, + {"fail_split_alloc" , NSS_STATS_TYPE_SPECIAL}, + {"fail_sync_alloc" , NSS_STATS_TYPE_SPECIAL}, + {"fail_ctx_active" , NSS_STATS_TYPE_SPECIAL}, + {"fail_hw[0]" , NSS_STATS_TYPE_SPECIAL}, + {"fail_hw[1]" , NSS_STATS_TYPE_SPECIAL}, + {"fail_hw[2]" , NSS_STATS_TYPE_SPECIAL}, + {"fail_hw[3]" , NSS_STATS_TYPE_SPECIAL}, + {"fail_hw[4]" , NSS_STATS_TYPE_SPECIAL}, + {"fail_hw[5]" , NSS_STATS_TYPE_SPECIAL}, + {"fail_hw[6]" , NSS_STATS_TYPE_SPECIAL}, + {"fail_hw[7]" , NSS_STATS_TYPE_SPECIAL}, + {"fail_hw[8]" , NSS_STATS_TYPE_SPECIAL}, + {"fail_hw[9]" , NSS_STATS_TYPE_SPECIAL}, + {"fail_hw[10]" , NSS_STATS_TYPE_SPECIAL}, + {"fail_hw[11]" , NSS_STATS_TYPE_SPECIAL}, + {"fail_hw[12]" , NSS_STATS_TYPE_SPECIAL}, + {"fail_hw[13]" , NSS_STATS_TYPE_SPECIAL}, + {"fail_hw[14]" , NSS_STATS_TYPE_SPECIAL}, + {"fail_hw[15]" , NSS_STATS_TYPE_SPECIAL}, +}; + + +/* + * nss_dma_strings_read() + * Read DMA node statistics names + */ +static ssize_t nss_dma_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_dma_strings_stats, NSS_DMA_STATS_MAX); +} + +/* + * nss_dma_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(dma); + +/* + * nss_dma_strings_dentry_create() + * Create DMA statistics strings debug entry. + */ +void nss_dma_strings_dentry_create(void) +{ + nss_strings_create_dentry("dma", &nss_dma_strings_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_dma_strings.h b/feeds/ipq807x/qca-nss-drv/src/nss_dma_strings.h new file mode 100755 index 000000000..145021627 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_dma_strings.h @@ -0,0 +1,25 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_DMA_STRINGS_H +#define __NSS_DMA_STRINGS_H + +extern struct nss_stats_info nss_dma_strings_stats[NSS_DMA_STATS_MAX]; +extern void nss_dma_strings_dentry_create(void); + +#endif /* __NSS_DMA_STRINGS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_drv_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_drv_stats.c new file mode 100644 index 000000000..30b8cb5f7 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_drv_stats.c @@ -0,0 +1,166 @@ +/* + ************************************************************************** + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_drv_strings.h" +#include "nss_drv_stats.h" + +/* + * nss_drv_stats_read() + * Read HLOS driver stats. + */ +static ssize_t nss_drv_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i; + + /* + * Max output lines = #stats * NSS_MAX_CORES + + * few blank lines for banner printing + Number of Extra outputlines for future reference to add new stats + */ + uint32_t max_output_lines = NSS_DRV_STATS_MAX * NSS_MAX_CORES + NSS_STATS_EXTRA_OUTPUT_LINES; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + stats_shadow = kzalloc(NSS_DRV_STATS_MAX * 8, GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return 0; + } + + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "drv", NSS_STATS_SINGLE_CORE); + for (i = 0; (i < NSS_DRV_STATS_MAX); i++) { + stats_shadow[i] = NSS_PKT_STATS_READ(&nss_top_main.stats_drv[i]); + } + + size_wr += nss_stats_print("drv", NULL, NSS_STATS_SINGLE_INSTANCE, nss_drv_strings_stats, stats_shadow, NSS_DRV_STATS_MAX, lbuf, size_wr, size_al); + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * drv_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(drv); + +/* + * nss_drv_stats_dentry_create() + * Create DRV statistics debug entry. + */ +void nss_drv_stats_dentry_create(void) +{ + nss_stats_create_dentry("drv", &nss_drv_stats_ops); +} + +/* + * TODO: Move this (nss_wt_stats_read) function to new file (nss_wt_stats.c) + */ + +/* + * nss_wt_stats_read() + * Reads and formats worker thread statistics and outputs them to ubuf + */ +ssize_t nss_wt_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + struct nss_stats_data *data = fp->private_data; + struct nss_ctx_instance *nss_ctx = data->nss_ctx; + struct nss_project_irq_stats *shadow; + uint32_t thread_count = nss_ctx->worker_thread_count; + uint32_t irq_count = nss_ctx->irq_count; + + /* + * Three lines for each IRQ + */ + uint32_t max_output_lines = thread_count * 3 * irq_count; + size_t size_al = max_output_lines * NSS_STATS_MAX_STR_LENGTH; + size_t size_wr = 0; + ssize_t bytes_read = 0; + char *lbuf; + int i; + int j; + + lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(!lbuf)) { + nss_warning("Could not allocate memory for local statistics buffer\n"); + return 0; + } + + shadow = kzalloc(thread_count * irq_count * sizeof(struct nss_project_irq_stats), GFP_KERNEL); + if (unlikely(!shadow)) { + nss_warning("Could not allocate memory for stats shadow\n"); + kfree(lbuf); + return 0; + } + + spin_lock_bh(&nss_top_main.stats_lock); + if (unlikely(!nss_ctx->wt_stats)) { + spin_unlock_bh(&nss_top_main.stats_lock); + nss_warning("Worker thread statistics not allocated\n"); + kfree(lbuf); + kfree(shadow); + return 0; + } + for (i = 0; i < thread_count; ++i) { + + /* + * The statistics shadow is an array with thread_count * irq_count + * items in it. Each item is located at the index: + * (thread number) * (irq_count) + (irq number) + * thus simulating a two-dimensional array. + */ + for (j = 0; j < irq_count; ++j) { + shadow[i * irq_count + j] = nss_ctx->wt_stats[i].irq_stats[j]; + } + } + spin_unlock_bh(&nss_top_main.stats_lock); + + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "worker thread", NSS_STATS_SINGLE_CORE); + for (i = 0; i < thread_count; ++i) { + for (j = 0; j < irq_count; ++j) { + struct nss_project_irq_stats *is = &(shadow[i * irq_count + j]); + if (!(is->count)) { + continue; + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "t-%d:irq-%d callback: 0x%x, count: %llu\n", + i, j, is->callback, is->count); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "t-%d:irq-%d tick min: %10u avg: %10u max:%10u\n", + i, j, is->ticks_min, is->ticks_avg, is->ticks_max); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "t-%d:irq-%d insn min: %10u avg: %10u max:%10u\n\n", + i, j, is->insn_min, is->insn_avg, is->insn_max); + } + } + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(shadow); + + return bytes_read; +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_drv_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_drv_stats.h new file mode 100644 index 000000000..543dd5c89 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_drv_stats.h @@ -0,0 +1,80 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2017, 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_drv_stats.h + * NSS driver stats header file. + */ + +#ifndef __NSS_DRV_STATS_H +#define __NSS_DRV_STATS_H + +#include + +/* + * HLOS driver statistics + * + * WARNING: There is a 1:1 mapping between values below and corresponding + * stats string array in nss_stats.c. + */ +enum NSS_DRV_STATS { + NSS_DRV_STATS_NBUF_ALLOC_FAILS = 0, /* NBUF allocation errors */ + NSS_DRV_STATS_PAGED_BUF_ALLOC_FAILS, /* Paged buf allocation errors */ + NSS_DRV_STATS_TX_QUEUE_FULL_0, /* Tx queue full for Core 0*/ + NSS_DRV_STATS_TX_QUEUE_FULL_1, /* Tx queue full for Core 1*/ + NSS_DRV_STATS_TX_EMPTY, /* H2N Empty buffers */ + NSS_DRV_STATS_PAGED_TX_EMPTY, /* H2N Paged Empty buffers */ + NSS_DRV_STATS_TX_PACKET, /* H2N Data packets */ + NSS_DRV_STATS_TX_CMD_REQ, /* H2N Control packets */ + NSS_DRV_STATS_TX_CRYPTO_REQ, /* H2N Crypto requests */ + NSS_DRV_STATS_TX_BUFFER_REUSE, /* H2N Reuse buffer count */ + NSS_DRV_STATS_RX_EMPTY, /* N2H Empty buffers */ + NSS_DRV_STATS_RX_PACKET, /* N2H Data packets */ + NSS_DRV_STATS_RX_EXT_PACKET, /* N2H EXT type packets */ + NSS_DRV_STATS_RX_CMD_RESP, /* N2H Command responses */ + NSS_DRV_STATS_RX_STATUS, /* N2H Status packets */ + NSS_DRV_STATS_RX_CRYPTO_RESP, /* N2H Crypto responses */ + NSS_DRV_STATS_RX_VIRTUAL, /* N2H Virtual packets */ + NSS_DRV_STATS_TX_SIMPLE, /* H2N Simple SKB Packets */ + NSS_DRV_STATS_TX_NR_FRAGS, /* H2N NR Frags SKB Packets */ + NSS_DRV_STATS_TX_FRAGLIST, /* H2N Fraglist SKB Packets */ + NSS_DRV_STATS_RX_SIMPLE, /* N2H Simple SKB Packets */ + NSS_DRV_STATS_RX_NR_FRAGS, /* N2H NR Frags SKB Packets */ + NSS_DRV_STATS_RX_SKB_FRAGLIST, /* N2H Fraglist SKB Packets */ + NSS_DRV_STATS_RX_BAD_DESCRIPTOR, /* N2H Bad descriptor reads */ + NSS_DRV_STATS_RX_INVALID_INTERFACE, /* N2H Received descriptor for invalid interface */ + NSS_DRV_STATS_RX_INVALID_CORE_ID, /* N2H Received packet for invalid core_id */ + NSS_DRV_STATS_RX_INVALID_BUFFER_TYPE, /* N2H Received packet for invalid buffer type */ + NSS_DRV_STATS_NSS_SKB_COUNT, /* NSS SKB Pool Count */ + NSS_DRV_STATS_CHAIN_SEG_PROCESSED, /* N2H SKB Chain Processed Count */ + NSS_DRV_STATS_FRAG_SEG_PROCESSED, /* N2H Frag Processed Count */ + NSS_DRV_STATS_TX_CMD_QUEUE_FULL, /* Tx H2N Control packets fail due to queue full */ +#ifdef NSS_MULTI_H2N_DATA_RING_SUPPORT + NSS_DRV_STATS_TX_PACKET_QUEUE_0, /* H2N Data packets on queue0 */ + NSS_DRV_STATS_TX_PACKET_QUEUE_1, /* H2N Data packets on queue1 */ + NSS_DRV_STATS_TX_PACKET_QUEUE_2, /* H2N Data packets on queue2 */ + NSS_DRV_STATS_TX_PACKET_QUEUE_3, /* H2N Data packets on queue3 */ + NSS_DRV_STATS_TX_PACKET_QUEUE_4, /* H2N Data packets on queue4 */ + NSS_DRV_STATS_TX_PACKET_QUEUE_5, /* H2N Data packets on queue5 */ + NSS_DRV_STATS_TX_PACKET_QUEUE_6, /* H2N Data packets on queue6 */ + NSS_DRV_STATS_TX_PACKET_QUEUE_7, /* H2N Data packets on queue7 */ +#endif + NSS_DRV_STATS_MAX, +}; + +extern void nss_drv_stats_dentry_create(void); +extern ssize_t nss_wt_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos); +#endif /* __NSS_DRV_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_drv_strings.c b/feeds/ipq807x/qca-nss-drv/src/nss_drv_strings.c new file mode 100644 index 000000000..259561525 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_drv_strings.c @@ -0,0 +1,92 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_stats.h" +#include "nss_core.h" +#include "nss_strings.h" + +/* + * nss_drv_strings_stats + * Host driver stats names. + */ +struct nss_stats_info nss_drv_strings_stats[NSS_DRV_STATS_MAX] = { + {"nbuf_alloc_errors" , NSS_STATS_TYPE_ERROR}, + {"paged_buf_alloc_errors" , NSS_STATS_TYPE_ERROR}, + {"tx_queue_full[0]" , NSS_STATS_TYPE_ERROR}, + {"tx_queue_full[1]" , NSS_STATS_TYPE_ERROR}, + {"tx_buffers_empty" , NSS_STATS_TYPE_SPECIAL}, + {"tx_paged_buffers_empty" , NSS_STATS_TYPE_SPECIAL}, + {"tx_buffer_pkt" , NSS_STATS_TYPE_SPECIAL}, + {"tx_buffers_cmd" , NSS_STATS_TYPE_SPECIAL}, + {"tx_buffers_crypto" , NSS_STATS_TYPE_SPECIAL}, + {"tx_buffers_reuse" , NSS_STATS_TYPE_SPECIAL}, + {"rx_buffers_empty" , NSS_STATS_TYPE_SPECIAL}, + {"rx_buffers_pkt" , NSS_STATS_TYPE_SPECIAL}, + {"rx_buffers_ext_pkt" , NSS_STATS_TYPE_SPECIAL}, + {"rx_buffers_cmd_resp" , NSS_STATS_TYPE_SPECIAL}, + {"rx_buffers_status_sync" , NSS_STATS_TYPE_SPECIAL}, + {"rx_buffers_crypto" , NSS_STATS_TYPE_SPECIAL}, + {"rx_buffers_virtual" , NSS_STATS_TYPE_SPECIAL}, + {"tx_skb_simple" , NSS_STATS_TYPE_SPECIAL}, + {"tx_skb_nr_frags" , NSS_STATS_TYPE_SPECIAL}, + {"tx_skb_fraglist" , NSS_STATS_TYPE_SPECIAL}, + {"rx_skb_simple" , NSS_STATS_TYPE_SPECIAL}, + {"rx_skb_nr_frags" , NSS_STATS_TYPE_SPECIAL}, + {"rx_skb_fraglist" , NSS_STATS_TYPE_SPECIAL}, + {"rx_bad_desciptor" , NSS_STATS_TYPE_ERROR}, + {"invalid_interface" , NSS_STATS_TYPE_ERROR}, + {"invalid_core_id" , NSS_STATS_TYPE_ERROR}, + {"invalid_buffer_type" , NSS_STATS_TYPE_ERROR}, + {"nss_skb_count" , NSS_STATS_TYPE_SPECIAL}, + {"rx_chain_seg_processed" , NSS_STATS_TYPE_SPECIAL}, + {"rx_frag_seg_processed" , NSS_STATS_TYPE_SPECIAL}, + {"tx_buffers_cmd_queue_full" , NSS_STATS_TYPE_ERROR}, +#ifdef NSS_MULTI_H2N_DATA_RING_SUPPORT + {"tx_buffers_data_queue[0]" , NSS_STATS_TYPE_SPECIAL}, + {"tx_buffers_data_queue[1]" , NSS_STATS_TYPE_SPECIAL}, + {"tx_buffers_data_queue[2]" , NSS_STATS_TYPE_SPECIAL}, + {"tx_buffers_data_queue[3]" , NSS_STATS_TYPE_SPECIAL}, + {"tx_buffers_data_queue[4]" , NSS_STATS_TYPE_SPECIAL}, + {"tx_buffers_data_queue[5]" , NSS_STATS_TYPE_SPECIAL}, + {"tx_buffers_data_queue[6]" , NSS_STATS_TYPE_SPECIAL}, + {"tx_buffers_data_queue[7]" , NSS_STATS_TYPE_SPECIAL}, +#endif +}; + +/* + * nss_drv_strings_read() + * Read drv node statistics names. + */ +static ssize_t nss_drv_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_drv_strings_stats, NSS_DRV_STATS_MAX); +} + +/* + * nss_drv_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(drv); + +/* + * nss_drv_strings_dentry_create() + * Create drv statistics strings debug entry. + */ +void nss_drv_strings_dentry_create(void) +{ + nss_strings_create_dentry("drv", &nss_drv_strings_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_drv_strings.h b/feeds/ipq807x/qca-nss-drv/src/nss_drv_strings.h new file mode 100644 index 000000000..72a1fd7a0 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_drv_strings.h @@ -0,0 +1,26 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_DRV_STRINGS_H +#define __NSS_DRV_STRINGS_H + +extern struct nss_stats_info nss_drv_strings_stats[NSS_DRV_STATS_MAX]; + +extern void nss_drv_strings_dentry_create(void); + +#endif /* __NSS_DRV_STRINGS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_dscp_map.h b/feeds/ipq807x/qca-nss-drv/src/nss_dscp_map.h new file mode 100644 index 000000000..441dc11ac --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_dscp_map.h @@ -0,0 +1,212 @@ +/* + ************************************************************************** + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_dscp_map.h + * NSS dscp map parse APIs + */ + +#include "nss_tx_rx_common.h" + +#define NSS_DSCP_MAP_PARAM_FIELD_COUNT 3 +#define NSS_DSCP_MAP_ARRAY_SIZE 64 +#define NSS_DSCP_MAP_PRIORITY_MAX NSS_MAX_NUM_PRI + +/* + * nss dscp map entry structure. + */ +struct nss_dscp_map_entry { + uint8_t action; /* Action associated with the DSCP value.*/ + uint8_t priority; /* Priority associated with the DSCP value. */ +}; + +/* + * nss dscp map parse output. + */ +struct nss_dscp_map_parse { + uint8_t dscp; /* Parsed dscp value */ + uint8_t action; /* Parsed action value */ + uint8_t priority; /* Parsed priority value */ +}; + +/* + * nss_dscp_map_print() + * Sysctl handler for printing dscp/pri mapping. + */ +static int nss_dscp_map_print(struct ctl_table *ctl, void __user *buffer, size_t *lenp, + loff_t *ppos, struct nss_dscp_map_entry *mapping) +{ + char *r_buf; + int i, len; + size_t cp_bytes = 0; + + /* + * (64 * 8) + 22 bytes for the buffer size is sufficient to write + * the table including the spaces and new line characters. + */ + r_buf = kzalloc(((NSS_DSCP_MAP_ARRAY_SIZE * 8) + 22) * sizeof(char), GFP_KERNEL); + if (!r_buf) { + nss_warning("Failed to alloc buffer to print dscp map table\n"); + return -EFAULT; + } + + /* + * Write the priority values to the first line of the output. + */ + len = scnprintf(r_buf + cp_bytes, 11, "%s: ", "priority"); + cp_bytes += len; + for (i = 0; i < NSS_DSCP_MAP_ARRAY_SIZE; i++) { + len = scnprintf(r_buf + cp_bytes, 4, "%d ", mapping[i].priority); + if (!len) { + nss_warning("failed to read from buffer %d\n", mapping[i].priority); + kfree(r_buf); + return -EFAULT; + } + cp_bytes += len; + } + + /* + * Add new line character at the end. + */ + len = scnprintf(r_buf + cp_bytes, 4, "\n"); + cp_bytes += len; + + /* + * Write the action values to the second line of the output. + */ + len = scnprintf(r_buf + cp_bytes, 11, "%s: ", "action"); + cp_bytes += len; + for (i = 0; i < NSS_DSCP_MAP_ARRAY_SIZE; i++) { + len = scnprintf(r_buf + cp_bytes, 4, "%d ", mapping[i].action); + if (!len) { + nss_warning("failed to read from buffer %d\n", mapping[i].action); + kfree(r_buf); + return -EFAULT; + } + cp_bytes += len; + } + + /* + * Add new line character at the end. + */ + len = scnprintf(r_buf + cp_bytes, 4, "\n"); + cp_bytes += len; + + cp_bytes = simple_read_from_buffer(buffer, *lenp, ppos, r_buf, cp_bytes); + *lenp = cp_bytes; + kfree(r_buf); + return 0; +} + +/* + * nss_dscp_map_parse() + * Sysctl handler for dscp/pri mappings. + */ +static int nss_dscp_map_parse(struct ctl_table *ctl, void __user *buffer, size_t *lenp, + loff_t *ppos, struct nss_dscp_map_parse *out) +{ + int count; + size_t cp_bytes = 0; + char w_buf[7]; + loff_t w_offset = 0; + char *str; + char *tokens[NSS_DSCP_MAP_PARAM_FIELD_COUNT]; + unsigned int dscp, priority, action; + int ret; + + /* + * Buffer length cannot be more than 7 and less than 6. + */ + if (*lenp < 6 || *lenp > 7) { + nss_warning("Buffer is not correct. Invalid lenght: %d\n", (int)*lenp); + return -EINVAL; + } + + /* + * It's a write operation + */ + cp_bytes = simple_write_to_buffer(w_buf, *lenp, &w_offset, buffer, 7); + if (cp_bytes != *lenp) { + nss_warning("failed to write to buffer\n"); + return -EFAULT; + } + + count = 0; + str = w_buf; + tokens[count] = strsep(&str, " "); + while (tokens[count] != NULL) { + count++; + if (count == NSS_DSCP_MAP_PARAM_FIELD_COUNT) { + nss_warning("maximum allowed field count is %d\n", NSS_DSCP_MAP_PARAM_FIELD_COUNT); + break; + } + tokens[count] = strsep(&str, " "); + } + + /* + * Did we read enough number of parameters from the command line. + * There must be 2 parameters. + */ + if (count != NSS_DSCP_MAP_PARAM_FIELD_COUNT) { + nss_warning("param fields are less than expected: %d\n", count); + return -EINVAL; + } + + /* + * Write the tokens to integers. + */ + ret = sscanf(tokens[0], "%u", &dscp); + if (ret != 1) { + nss_warning("failed to write the dscp token to integer\n"); + return -EFAULT; + } + + ret = sscanf(tokens[1], "%u", &action); + if (ret != 1) { + nss_warning("failed to write the action token to integer\n"); + return -EFAULT; + } + + ret = sscanf(tokens[2], "%u", &priority); + if (ret != 1) { + nss_warning("failed to write the priority token to integer\n"); + return -EFAULT; + } + + /* + * dscp value cannot be higher than 63. + */ + if (dscp >= NSS_DSCP_MAP_ARRAY_SIZE) { + nss_warning("invalid dscp value: %d\n", dscp); + return -EINVAL; + } + + /* + * Priority must be less than NSS_DSCP_MAP_PRIORITY_MAX which is 4. + */ + if (priority >= NSS_DSCP_MAP_PRIORITY_MAX) { + nss_warning("invalid priority value: %d\n", priority); + return -EINVAL; + } + + nss_info("dscp: %d action: %d priority: %d\n", dscp, action, priority); + + out->dscp = dscp; + out->action = action; + out->priority = priority; + + return 0; +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_dtls.c b/feeds/ipq807x/qca-nss-drv/src/nss_dtls.c new file mode 100644 index 000000000..6d7c1a1ce --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_dtls.c @@ -0,0 +1,468 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_dtls_stats.h" +#include "nss_dtls_log.h" + +#define NSS_DTLS_TX_TIMEOUT 3000 /* 3 Seconds */ + +/* + * Data structures to store DTLS nss debug stats + */ +static DEFINE_SPINLOCK(nss_dtls_session_stats_lock); +static struct nss_dtls_stats_session session_stats[NSS_MAX_DTLS_SESSIONS]; + +/* + * Private data structure + */ +static struct nss_dtls_pvt { + struct semaphore sem; + struct completion complete; + int response; + void *cb; + void *app_data; +} dtls_pvt; + +/* + * nss_dtls_verify_if_num() + * Verify if_num passed to us. + */ +static bool nss_dtls_verify_if_num(uint32_t if_num) +{ + if (nss_is_dynamic_interface(if_num) == false) + return false; + + if (nss_dynamic_interface_get_type(nss_dtls_get_context(), if_num) + != NSS_DYNAMIC_INTERFACE_TYPE_DTLS) + return false; + + return true; +} + +/* + * nss_dtls_session_stats_sync + * Per DTLS session debug stats + */ +static void nss_dtls_session_stats_sync(struct nss_ctx_instance *nss_ctx, + struct nss_dtls_session_stats *stats_msg, + uint16_t if_num) +{ + int i; + struct nss_dtls_stats_session *s = NULL; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + spin_lock_bh(&nss_dtls_session_stats_lock); + for (i = 0; i < NSS_MAX_DTLS_SESSIONS; i++) { + if (session_stats[i].if_num != if_num) { + continue; + } + + s = &session_stats[i]; + break; + } + + if (!s) { + spin_unlock_bh(&nss_dtls_session_stats_lock); + return; + } + + s->stats[NSS_DTLS_STATS_SESSION_RX_PKTS] += stats_msg->node_stats.rx_packets; + s->stats[NSS_DTLS_STATS_SESSION_TX_PKTS] += stats_msg->node_stats.tx_packets; + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + s->stats[NSS_DTLS_STATS_SESSION_RX_QUEUE_0_DROPPED + i] += stats_msg->node_stats.rx_dropped[i]; + } + s->stats[NSS_DTLS_STATS_SESSION_RX_AUTH_DONE] += stats_msg->rx_auth_done; + s->stats[NSS_DTLS_STATS_SESSION_TX_AUTH_DONE] += stats_msg->tx_auth_done; + s->stats[NSS_DTLS_STATS_SESSION_RX_CIPHER_DONE] += stats_msg->rx_cipher_done; + s->stats[NSS_DTLS_STATS_SESSION_TX_CIPHER_DONE] += stats_msg->tx_cipher_done; + s->stats[NSS_DTLS_STATS_SESSION_RX_CBUF_ALLOC_FAIL] += stats_msg->rx_cbuf_alloc_fail; + s->stats[NSS_DTLS_STATS_SESSION_TX_CBUF_ALLOC_FAIL] += stats_msg->tx_cbuf_alloc_fail; + s->stats[NSS_DTLS_STATS_SESSION_TX_CENQUEUE_FAIL] += stats_msg->tx_cenqueue_fail; + s->stats[NSS_DTLS_STATS_SESSION_RX_CENQUEUE_FAIL] += stats_msg->rx_cenqueue_fail; + s->stats[NSS_DTLS_STATS_SESSION_TX_DROPPED_HROOM] += stats_msg->tx_dropped_hroom; + s->stats[NSS_DTLS_STATS_SESSION_TX_DROPPED_TROOM] += stats_msg->tx_dropped_troom; + s->stats[NSS_DTLS_STATS_SESSION_TX_FORWARD_ENQUEUE_FAIL] += stats_msg->tx_forward_enqueue_fail; + s->stats[NSS_DTLS_STATS_SESSION_RX_FORWARD_ENQUEUE_FAIL] += stats_msg->rx_forward_enqueue_fail; + s->stats[NSS_DTLS_STATS_SESSION_RX_INVALID_VERSION] += stats_msg->rx_invalid_version; + s->stats[NSS_DTLS_STATS_SESSION_RX_INVALID_EPOCH] += stats_msg->rx_invalid_epoch; + s->stats[NSS_DTLS_STATS_SESSION_RX_MALFORMED] += stats_msg->rx_malformed; + s->stats[NSS_DTLS_STATS_SESSION_RX_CIPHER_FAIL] += stats_msg->rx_cipher_fail; + s->stats[NSS_DTLS_STATS_SESSION_RX_AUTH_FAIL] += stats_msg->rx_auth_fail; + s->stats[NSS_DTLS_STATS_SESSION_RX_CAPWAP_CLASSIFY_FAIL] += stats_msg->rx_capwap_classify_fail; + s->stats[NSS_DTLS_STATS_SESSION_RX_SINGLE_REC_DGRAM] += stats_msg->rx_single_rec_dgram; + s->stats[NSS_DTLS_STATS_SESSION_RX_MULTI_REC_DGRAM] += stats_msg->rx_multi_rec_dgram; + s->stats[NSS_DTLS_STATS_SESSION_RX_REPLAY_FAIL] += stats_msg->rx_replay_fail; + s->stats[NSS_DTLS_STATS_SESSION_RX_REPLAY_DUPLICATE] += stats_msg->rx_replay_duplicate; + s->stats[NSS_DTLS_STATS_SESSION_RX_REPLAY_OUT_OF_WINDOW] += stats_msg->rx_replay_out_of_window; + s->stats[NSS_DTLS_STATS_SESSION_OUTFLOW_QUEUE_FULL] += stats_msg->outflow_queue_full; + s->stats[NSS_DTLS_STATS_SESSION_DECAP_QUEUE_FULL] += stats_msg->decap_queue_full; + s->stats[NSS_DTLS_STATS_SESSION_PBUF_ALLOC_FAIL] += stats_msg->pbuf_alloc_fail; + s->stats[NSS_DTLS_STATS_SESSION_PBUF_COPY_FAIL] += stats_msg->pbuf_copy_fail; + s->stats[NSS_DTLS_STATS_SESSION_EPOCH] = stats_msg->epoch; + s->stats[NSS_DTLS_STATS_SESSION_TX_SEQ_HIGH] = stats_msg->tx_seq_high; + s->stats[NSS_DTLS_STATS_SESSION_TX_SEQ_LOW] = stats_msg->tx_seq_low; + spin_unlock_bh(&nss_dtls_session_stats_lock); +} + +/* + * nss_dtls_session_stats_get() + * Get session DTLS statitics. + */ +void nss_dtls_session_stats_get(struct nss_dtls_stats_session *stats) +{ + int i; + + if (!stats) { + nss_warning("No memory to copy dtls session stats"); + return; + } + + spin_lock_bh(&nss_dtls_session_stats_lock); + for (i = 0; i < NSS_MAX_DTLS_SESSIONS; i++) { + if (session_stats[i].valid) { + memcpy(stats, &session_stats[i], + sizeof(struct nss_dtls_stats_session)); + stats++; + } + } + spin_unlock_bh(&nss_dtls_session_stats_lock); +} + +/* + * nss_dtls_handler() + * Handle NSS -> HLOS messages for dtls tunnel + */ +static void nss_dtls_handler(struct nss_ctx_instance *nss_ctx, + struct nss_cmn_msg *ncm, + __attribute__((unused))void *app_data) +{ + struct nss_dtls_msg *ntm = (struct nss_dtls_msg *)ncm; + void *ctx; + + nss_dtls_msg_callback_t cb; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + BUG_ON(!nss_dtls_verify_if_num(ncm->interface)); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_DTLS_MSG_MAX) { + nss_warning("%px: received invalid message %d " + "for DTLS interface %d", + nss_ctx, ncm->type, ncm->interface); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_dtls_msg)) { + nss_warning("%px: dtls message length is invalid: %d", + nss_ctx, ncm->len); + return; + } + + switch (ntm->cm.type) { + case NSS_DTLS_MSG_SESSION_STATS: + nss_dtls_session_stats_sync(nss_ctx, + &ntm->msg.stats, + ncm->interface); + break; + } + + /* + * Update the callback and app_data for NOTIFY messages + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_ctx->nss_top->dtls_msg_callback; + ncm->app_data = (nss_ptr_t)nss_ctx->subsys_dp_register[ncm->interface].app_data; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Trace messages. + */ + nss_dtls_log_rx_msg(ntm); + + /* + * callback + */ + cb = (nss_dtls_msg_callback_t)ncm->cb; + ctx = (void *)ncm->app_data; + + /* + * call dtls session callback + */ + if (!cb) { + nss_warning("%px: No callback for dtls session interface %d", + nss_ctx, ncm->interface); + return; + } + + cb(ctx, ntm); +} + +/* + * nss_dtls_callback() + * Callback to handle the completion of NSS->HLOS messages. + */ +static void nss_dtls_callback(void *app_data, struct nss_dtls_msg *nim) +{ + nss_dtls_msg_callback_t callback = (nss_dtls_msg_callback_t)dtls_pvt.cb; + void *data = dtls_pvt.app_data; + + dtls_pvt.cb = NULL; + dtls_pvt.app_data = NULL; + + if (nim->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("dtls Error response %d\n", nim->cm.response); + + dtls_pvt.response = NSS_TX_FAILURE; + if (callback) { + callback(data, nim); + } + + complete(&dtls_pvt.complete); + return; + } + + dtls_pvt.response = NSS_TX_SUCCESS; + if (callback) { + callback(data, nim); + } + + complete(&dtls_pvt.complete); +} + +/* + * nss_dtls_tx_buf() + * Transmit buffer over DTLS interface + */ +nss_tx_status_t nss_dtls_tx_buf(struct sk_buff *skb, uint32_t if_num, + struct nss_ctx_instance *nss_ctx) +{ + BUG_ON(!nss_dtls_verify_if_num(if_num)); + + return nss_core_send_packet(nss_ctx, skb, if_num, H2N_BIT_FLAG_VIRTUAL_BUFFER | H2N_BIT_FLAG_BUFFER_REUSABLE); +} +EXPORT_SYMBOL(nss_dtls_tx_buf); + +/* + * nss_dtls_tx_msg() + * Transmit a DTLS message to NSS firmware + */ +nss_tx_status_t nss_dtls_tx_msg(struct nss_ctx_instance *nss_ctx, + struct nss_dtls_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Sanity check the message + */ + BUG_ON(!nss_dtls_verify_if_num(ncm->interface)); + + if (ncm->type > NSS_DTLS_MSG_MAX) { + nss_warning("%px: dtls message type out of range: %d", + nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + /* + * Trace messages. + */ + nss_dtls_log_tx_msg(msg); + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_dtls_tx_msg); + +/* + * nss_dtls_tx_msg() + * Transmit a DTLS message to NSS firmware synchronously. + */ +nss_tx_status_t nss_dtls_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_dtls_msg *msg) +{ + + nss_tx_status_t status; + int ret = 0; + + down(&dtls_pvt.sem); + dtls_pvt.cb = (void *)msg->cm.cb; + dtls_pvt.app_data = (void *)msg->cm.app_data; + + msg->cm.cb = (nss_ptr_t)nss_dtls_callback; + msg->cm.app_data = (nss_ptr_t)NULL; + + status = nss_dtls_tx_msg(nss_ctx, msg); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: dtls_tx_msg failed\n", nss_ctx); + up(&dtls_pvt.sem); + return status; + } + + ret = wait_for_completion_timeout(&dtls_pvt.complete, msecs_to_jiffies(NSS_DTLS_TX_TIMEOUT)); + + if (!ret) { + nss_warning("%px: DTLS msg tx failed due to timeout\n", nss_ctx); + dtls_pvt.response = NSS_TX_FAILURE; + } + + status = dtls_pvt.response; + up(&dtls_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_dtls_tx_msg_sync); + +/* + *********************************** + * Register/Unregister/Miscellaneous APIs + *********************************** + */ + +/* + * nss_dtls_register_if() + */ +struct nss_ctx_instance *nss_dtls_register_if(uint32_t if_num, + nss_dtls_data_callback_t cb, + nss_dtls_msg_callback_t ev_cb, + struct net_device *netdev, + uint32_t features, + void *app_ctx) +{ + int32_t i; + + struct nss_ctx_instance *nss_ctx = nss_dtls_get_context(); + + BUG_ON(!nss_dtls_verify_if_num(if_num)); + + spin_lock_bh(&nss_dtls_session_stats_lock); + for (i = 0; i < NSS_MAX_DTLS_SESSIONS; i++) { + if (!session_stats[i].valid) { + session_stats[i].valid = true; + session_stats[i].if_num = if_num; + session_stats[i].if_index = netdev->ifindex; + break; + } + } + spin_unlock_bh(&nss_dtls_session_stats_lock); + + if (i == NSS_MAX_DTLS_SESSIONS) { + nss_warning("%px: Cannot find free slot for " + "DTLS session stats, I/F:%u\n", nss_ctx, if_num); + return NULL; + } + + if (nss_ctx->subsys_dp_register[if_num].ndev) { + nss_warning("%px: Cannot find free slot for " + "DTLS NSS I/F:%u\n", nss_ctx, if_num); + + return NULL; + } + + nss_core_register_subsys_dp(nss_ctx, if_num, cb, NULL, app_ctx, netdev, features); + nss_ctx->subsys_dp_register[if_num].type = NSS_DYNAMIC_INTERFACE_TYPE_DTLS; + + nss_top_main.dtls_msg_callback = ev_cb; + nss_core_register_handler(nss_ctx, if_num, nss_dtls_handler, app_ctx); + + return nss_ctx; +} +EXPORT_SYMBOL(nss_dtls_register_if); + +/* + * nss_dtls_unregister_if() + */ +void nss_dtls_unregister_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = nss_dtls_get_context(); + int32_t i; + + BUG_ON(!nss_dtls_verify_if_num(if_num)); + + spin_lock_bh(&nss_dtls_session_stats_lock); + for (i = 0; i < NSS_MAX_DTLS_SESSIONS; i++) { + if (session_stats[i].if_num == if_num) { + memset(&session_stats[i], 0, + sizeof(struct nss_dtls_stats_session)); + break; + } + } + spin_unlock_bh(&nss_dtls_session_stats_lock); + + if (i == NSS_MAX_DTLS_SESSIONS) { + nss_warning("%px: Cannot find debug stats for DTLS session %d\n", nss_ctx, if_num); + return; + } + + if (!nss_ctx->subsys_dp_register[if_num].ndev) { + nss_warning("%px: Cannot find registered netdev for DTLS NSS I/F:%u\n", nss_ctx, if_num); + + return; + } + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + + nss_top_main.dtls_msg_callback = NULL; + nss_core_unregister_handler(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_dtls_unregister_if); + +/* + * nss_get_dtls_context() + */ +struct nss_ctx_instance *nss_dtls_get_context(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.dtls_handler_id]; +} +EXPORT_SYMBOL(nss_dtls_get_context); + +/* + * nss_dtls_msg_init() + * Initialize nss_dtls msg. + */ +void nss_dtls_msg_init(struct nss_dtls_msg *ncm, uint16_t if_num, + uint32_t type, uint32_t len, void *cb, void *app_data) +{ + nss_cmn_msg_init(&ncm->cm, if_num, type, len, cb, app_data); +} +EXPORT_SYMBOL(nss_dtls_msg_init); + +/* + * nss_dtls_get_ifnum_with_coreid() + */ +int32_t nss_dtls_get_ifnum_with_coreid(int32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = nss_dtls_get_context(); + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + return NSS_INTERFACE_NUM_APPEND_COREID(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_dtls_get_ifnum_with_coreid); + +/* + * nss_dtls_register_handler() + */ +void nss_dtls_register_handler(void) +{ + sema_init(&dtls_pvt.sem, 1); + init_completion(&dtls_pvt.complete); + + nss_dtls_stats_dentry_create(); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_dtls_cmn.c b/feeds/ipq807x/qca-nss-drv/src/nss_dtls_cmn.c new file mode 100644 index 000000000..a70f23332 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_dtls_cmn.c @@ -0,0 +1,523 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_dtls_cmn_log.h" + +#define NSS_DTLS_CMN_TX_TIMEOUT 3000 /* 3 Seconds */ +#define NSS_DTLS_CMN_INTERFACE_MAX_LONG BITS_TO_LONGS(NSS_MAX_NET_INTERFACES) +#define NSS_DTLS_CMN_STATS_MAX_LINES (NSS_STATS_NODE_MAX + 32) +#define NSS_DTLS_CMN_STATS_SIZE_PER_IF (NSS_STATS_MAX_STR_LENGTH * NSS_DTLS_CMN_STATS_MAX_LINES) +/* + * Private data structure. + */ +static struct nss_dtls_cmn_cmn_pvt { + struct semaphore sem; + struct completion complete; + enum nss_dtls_cmn_error resp; + unsigned long if_map[NSS_DTLS_CMN_INTERFACE_MAX_LONG]; +} dtls_cmn_pvt; + +/* + * nss_dtls_cmn_stats_sync() + * Update dtls_cmn node statistics. + */ +static void nss_dtls_cmn_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm) +{ + struct nss_dtls_cmn_msg *ndcm = (struct nss_dtls_cmn_msg *)ncm; + struct nss_top_instance *nss_top = nss_ctx->nss_top; + struct nss_dtls_cmn_ctx_stats *msg_stats = &ndcm->msg.stats; + uint64_t *if_stats; + + spin_lock_bh(&nss_top->stats_lock); + + /* + * Update common node stats, + * Note: DTLS only supports a single queue for RX. + */ + if_stats = nss_top->stats_node[ncm->interface]; + if_stats[NSS_STATS_NODE_RX_PKTS] += msg_stats->pkt.rx_packets; + if_stats[NSS_STATS_NODE_RX_BYTES] += msg_stats->pkt.rx_bytes; + if_stats[NSS_STATS_NODE_RX_QUEUE_0_DROPPED] += msg_stats->pkt.rx_dropped[0]; + + if_stats[NSS_STATS_NODE_TX_PKTS] += msg_stats->pkt.tx_packets; + if_stats[NSS_STATS_NODE_TX_BYTES] += msg_stats->pkt.tx_bytes; + + spin_unlock_bh(&nss_top->stats_lock); +} + +/* + * nss_dtls_cmn_stats_read() + * Read dtls_cmn node statiistics. + */ +static ssize_t nss_dtls_cmn_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + struct nss_ctx_instance *nss_ctx = nss_dtls_cmn_get_context(); + enum nss_dynamic_interface_type type; + ssize_t bytes_read = 0; + size_t len = 0, size; + uint32_t if_num; + char *buf; + + size = NSS_DTLS_CMN_STATS_SIZE_PER_IF * bitmap_weight(dtls_cmn_pvt.if_map, NSS_MAX_NET_INTERFACES); + + buf = kzalloc(size, GFP_KERNEL); + if (!buf) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + /* + * Common node stats for each DTLS dynamic interface. + */ + for_each_set_bit(if_num, dtls_cmn_pvt.if_map, NSS_MAX_NET_INTERFACES) { + + type = nss_dynamic_interface_get_type(nss_ctx, if_num); + + switch (type) { + case NSS_DYNAMIC_INTERFACE_TYPE_DTLS_CMN_INNER: + len += scnprintf(buf + len, size - len, "\nInner if_num:%03u", if_num); + break; + + case NSS_DYNAMIC_INTERFACE_TYPE_DTLS_CMN_OUTER: + len += scnprintf(buf + len, size - len, "\nOuter if_num:%03u", if_num); + break; + + default: + len += scnprintf(buf + len, size - len, "\nUnknown(%d) if_num:%03u", type, if_num); + break; + } + + len += scnprintf(buf + len, size - len, "\n-------------------\n"); + len += nss_stats_fill_common_stats(if_num, NSS_STATS_SINGLE_INSTANCE, buf, len, size - len, "dtls_cmn"); + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, buf, len); + kfree(buf); + + return bytes_read; +} + +/* + * nss_dtls_cmn_stats_ops. + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(dtls_cmn) + +/* + * nss_dtls_cmn_verify_ifnum() + * Verify if the interface number is a DTLS interface. + */ +static bool nss_dtls_cmn_verify_ifnum(struct nss_ctx_instance *nss_ctx, uint32_t if_num) +{ + enum nss_dynamic_interface_type type = nss_dynamic_interface_get_type(nss_ctx, if_num); + + if (type == NSS_DYNAMIC_INTERFACE_TYPE_DTLS_CMN_INNER) + return true; + + if (type == NSS_DYNAMIC_INTERFACE_TYPE_DTLS_CMN_OUTER) + return true; + + if (if_num == NSS_DTLS_INTERFACE) + return true; + + return false; +} + +/* + * nss_dtls_cmn_handler() + * Handle NSS -> HLOS messages for dtls tunnel. + */ +static void nss_dtls_cmn_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, void *data) +{ + nss_dtls_cmn_msg_callback_t cb; + void *app_data; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + nss_trace("%px: handle event for interface num :%u", nss_ctx, ncm->interface); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_DTLS_CMN_MSG_MAX) { + nss_warning("%px:Bad message type(%d) for DTLS interface %d", nss_ctx, ncm->type, ncm->interface); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_dtls_cmn_msg)) { + nss_warning("%px:Bad message length(%d)", nss_ctx, ncm->len); + return; + } + + if (ncm->type == NSS_DTLS_CMN_MSG_TYPE_SYNC_STATS) + nss_dtls_cmn_stats_sync(nss_ctx, ncm); + + /* + * Update the callback and app_data for NOTIFY messages. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_core_get_msg_handler(nss_ctx, ncm->interface); + ncm->app_data = (nss_ptr_t)nss_ctx->nss_rx_interface_handlers[ncm->interface].app_data; + } + + /* + * Log failures. + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Trace messages. + */ + nss_dtls_cmn_log_rx_msg((struct nss_dtls_cmn_msg *)ncm); + + /* + * Callback. + */ + cb = (nss_dtls_cmn_msg_callback_t)ncm->cb; + app_data = (void *)ncm->app_data; + + /* + * Call DTLS session callback. + */ + if (!cb) { + nss_warning("%px: No callback for dtls session interface %d", nss_ctx, ncm->interface); + return; + } + + nss_trace("%px: calling dtlsmgr event handler(%u)", nss_ctx, ncm->interface); + cb(app_data, ncm); +} + +/* + * nss_dtls_cmn_callback() + * Callback to handle the completion of NSS->HLOS messages. + */ +static void nss_dtls_cmn_callback(void *app_data, struct nss_cmn_msg *ncm) +{ + /* + * This callback is for synchronous operation. The caller sends its + * response pointer which needs to be loaded with the response + * data arriving from the NSS. + */ + enum nss_dtls_cmn_error *resp = (enum nss_dtls_cmn_error *)app_data; + + *resp = (ncm->response == NSS_CMN_RESPONSE_ACK) ? NSS_DTLS_CMN_ERROR_NONE : ncm->error; + complete(&dtls_cmn_pvt.complete); + + return; +} + +/* + * nss_dtls_cmn_tx_buf() + * Transmit buffer over DTLS interface. + */ +nss_tx_status_t nss_dtls_cmn_tx_buf(struct sk_buff *skb, uint32_t if_num, struct nss_ctx_instance *nss_ctx) +{ + if (!nss_dtls_cmn_verify_ifnum(nss_ctx, if_num)) + return NSS_TX_FAILURE; + + return nss_core_send_packet(nss_ctx, skb, if_num, H2N_BIT_FLAG_VIRTUAL_BUFFER | H2N_BIT_FLAG_BUFFER_REUSABLE); +} +EXPORT_SYMBOL(nss_dtls_cmn_tx_buf); + +/* + * nss_dtls_cmn_tx_msg() + * Transmit a DTLS message to NSS firmware. + */ +nss_tx_status_t nss_dtls_cmn_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_dtls_cmn_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + if (ncm->type >= NSS_DTLS_CMN_MSG_MAX) { + nss_warning("%px: dtls message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + if (!nss_dtls_cmn_verify_ifnum(nss_ctx, ncm->interface)) { + nss_warning("%px: dtls message interface is bad: %u", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + /* + * Trace messages. + */ + nss_dtls_cmn_log_tx_msg(msg); + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_dtls_cmn_tx_msg); + +/* + * nss_dtls_cmn_tx_msg_sync() + * Transmit a DTLS message to NSS firmware synchronously. + */ +nss_tx_status_t nss_dtls_cmn_tx_msg_sync(struct nss_ctx_instance *nss_ctx, uint32_t if_num, + enum nss_dtls_cmn_msg_type type, uint16_t len, + struct nss_dtls_cmn_msg *ndcm, enum nss_dtls_cmn_error *resp) +{ + struct nss_dtls_cmn_msg ndcm_local; + nss_tx_status_t status; + int ret; + + /* + * Length of the message should be the based on type. + */ + if (len > sizeof(ndcm_local.msg)) { + nss_warning("%px: (%u)Bad message length(%u) for type (%d)", nss_ctx, if_num, len, type); + return NSS_TX_FAILURE_TOO_LARGE; + } + + /* + * Response buffer is a required for copying the response for message. + */ + if (!resp) { + nss_warning("%px: (%u)Response buffer is empty, type(%d)", nss_ctx, if_num, type); + return NSS_TX_FAILURE_BAD_PARAM; + } + + /* + * TODO: this can be removed in future as we need to ensure that the response + * memory is only updated when the current outstanding request is waiting. + * This can be solved by introducing sequence no. in messages and only completing + * the message if the sequence no. matches. For now this is solved by passing + * a known memory dtls_cmn_pvt.resp. + */ + down(&dtls_cmn_pvt.sem); + + /* + * We need to copy the message content into the actual message + * to be sent to NSS. + */ + nss_dtls_cmn_msg_init(&ndcm_local, if_num, type, len, nss_dtls_cmn_callback, &dtls_cmn_pvt.resp); + memcpy(&ndcm_local.msg, &ndcm->msg, len); + + status = nss_dtls_cmn_tx_msg(nss_ctx, &ndcm_local); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: dtls_tx_msg failed", nss_ctx); + goto done; + } + + ret = wait_for_completion_timeout(&dtls_cmn_pvt.complete, msecs_to_jiffies(NSS_DTLS_CMN_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: DTLS msg tx failed due to timeout", nss_ctx); + status = NSS_TX_FAILURE_NOT_READY; + goto done; + } + + /* + * Read memory barrier. + */ + smp_rmb(); + + /* + * Copy the response received. + */ + *resp = dtls_cmn_pvt.resp; + + /* + * Only in case of non-error response we will + * indicate success. + */ + if (dtls_cmn_pvt.resp != NSS_DTLS_CMN_ERROR_NONE) + status = NSS_TX_FAILURE; + +done: + up(&dtls_cmn_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_dtls_cmn_tx_msg_sync); + +/* + * nss_dtls_cmn_notify_register() + * Register a handler for notification from NSS firmware. + */ +struct nss_ctx_instance *nss_dtls_cmn_notify_register(uint32_t if_num, nss_dtls_cmn_msg_callback_t ev_cb, + void *app_data) +{ + struct nss_ctx_instance *nss_ctx = nss_dtls_cmn_get_context(); + uint32_t ret; + + BUG_ON(!nss_ctx); + + ret = nss_core_register_handler(nss_ctx, if_num, nss_dtls_cmn_handler, app_data); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: unable to register event handler for interface(%u)", nss_ctx, if_num); + return NULL; + } + + ret = nss_core_register_msg_handler(nss_ctx, if_num, ev_cb); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_core_unregister_handler(nss_ctx, if_num); + nss_warning("%px: unable to register event handler for interface(%u)", nss_ctx, if_num); + return NULL; + } + + return nss_ctx; +} +EXPORT_SYMBOL(nss_dtls_cmn_notify_register); + +/* + * nss_dtls_cmn_notify_unregister() + * Unregister notification callback handler. + */ +void nss_dtls_cmn_notify_unregister(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = nss_dtls_cmn_get_context(); + uint32_t ret; + + BUG_ON(!nss_ctx); + + ret = nss_core_unregister_msg_handler(nss_ctx, if_num); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: unable to unregister event handler for interface(%u)", nss_ctx, if_num); + return; + } + + ret = nss_core_unregister_handler(nss_ctx, if_num); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: unable to unregister event handler for interface(%u)", nss_ctx, if_num); + return; + } + + return; +} +EXPORT_SYMBOL(nss_dtls_cmn_notify_unregister); + +/* + * nss_dtls_cmn_register_if() + * Register data and event callback handlers for dynamic interface. + */ +struct nss_ctx_instance *nss_dtls_cmn_register_if(uint32_t if_num, + nss_dtls_cmn_data_callback_t data_cb, + nss_dtls_cmn_msg_callback_t ev_cb, + struct net_device *netdev, + uint32_t features, + uint32_t type, + void *app_data) +{ + struct nss_ctx_instance *nss_ctx = nss_dtls_cmn_get_context(); + uint32_t ret; + + if (!nss_dtls_cmn_verify_ifnum(nss_ctx, if_num)) { + nss_warning("%px: DTLS Interface is not dynamic:%u", nss_ctx, if_num); + return NULL; + } + + if (nss_ctx->subsys_dp_register[if_num].ndev) { + nss_warning("%px: Cannot find free slot for DTLS NSS I/F:%u", nss_ctx, if_num); + return NULL; + } + + nss_core_register_subsys_dp(nss_ctx, if_num, data_cb, NULL, app_data, netdev, features); + nss_ctx->subsys_dp_register[if_num].type = type; + + ret = nss_core_register_handler(nss_ctx, if_num, nss_dtls_cmn_handler, app_data); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: unable to register event handler for interface(%u)", nss_ctx, if_num); + return NULL; + } + + ret = nss_core_register_msg_handler(nss_ctx, if_num, ev_cb); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_core_unregister_handler(nss_ctx, if_num); + nss_warning("%px: unable to register event handler for interface(%u)", nss_ctx, if_num); + return NULL; + } + + /* + * Atomically set the bitmap for the interface number. + */ + set_bit(if_num, dtls_cmn_pvt.if_map); + return nss_ctx; +} +EXPORT_SYMBOL(nss_dtls_cmn_register_if); + +/* + * nss_dtls_cmn_unregister_if() + * Unregister data and event callback handlers for the interface. + */ +void nss_dtls_cmn_unregister_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = nss_dtls_cmn_get_context(); + uint32_t ret; + + if (!nss_ctx->subsys_dp_register[if_num].ndev) { + nss_warning("%px: Cannot find registered netdev for DTLS NSS I/F:%u", nss_ctx, if_num); + return; + } + + /* + * Atomically clear the bitmap for the interface number. + */ + clear_bit(if_num, dtls_cmn_pvt.if_map); + + ret = nss_core_unregister_msg_handler(nss_ctx, if_num); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: unable to unregister event handler for interface(%u)", nss_ctx, if_num); + return; + } + + nss_core_unregister_handler(nss_ctx, if_num); + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + nss_ctx->subsys_dp_register[if_num].type = 0; +} +EXPORT_SYMBOL(nss_dtls_cmn_unregister_if); + +/* + * nss_dtls_get_context() + * Return DTLS NSS context. + */ +struct nss_ctx_instance *nss_dtls_cmn_get_context(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.dtls_handler_id]; +} +EXPORT_SYMBOL(nss_dtls_cmn_get_context); + +/* + * nss_dtls_cmn_msg_init() + * Initialize nss_dtls_cmn msg. + */ +void nss_dtls_cmn_msg_init(struct nss_dtls_cmn_msg *ncm, uint32_t if_num, + uint32_t type, uint32_t len, void *cb, void *app_data) +{ + nss_cmn_msg_init(&ncm->cm, if_num, type, len, cb, app_data); +} +EXPORT_SYMBOL(nss_dtls_cmn_msg_init); + +/* + * nss_dtls_cmn_get_ifnum() + * Return DTLS interface number with coreid. + */ +int32_t nss_dtls_cmn_get_ifnum(int32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = nss_dtls_cmn_get_context(); + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + return NSS_INTERFACE_NUM_APPEND_COREID(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_dtls_cmn_get_ifnum); + +/* + * nss_dtls_cmn_register_handler() + * DTLS initialization. + */ +void nss_dtls_cmn_register_handler(void) +{ + sema_init(&dtls_cmn_pvt.sem, 1); + init_completion(&dtls_cmn_pvt.complete); + nss_stats_create_dentry("dtls_cmn", &nss_dtls_cmn_stats_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_dtls_cmn_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_dtls_cmn_log.c new file mode 100644 index 000000000..41ad37c44 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_dtls_cmn_log.c @@ -0,0 +1,178 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_dtls_cmn_log.c + * NSS DTLS common logger file. + */ + +#include "nss_core.h" + +/* + * nss_dtls_cmn_log_message_types_str + * DTLS common message strings + */ +static int8_t *nss_dtls_cmn_log_message_types_str[NSS_DTLS_CMN_MSG_MAX] __maybe_unused = { + "DTLS_CMN Configure Node", + "DTLS_CMN Configure Base Context Parameter", + "DTLS_CMN Configure DTLS Parameters", + "DTLS_CMN Switch DTLS Transform", + "DTLS_CMN Deconfigure Context", + "DTLS_CMN Synchronize Stats", + "DTLS_CMN Node Statistics" +}; + +/* + * nss_dtls_cmn_log_error_response_types_str + * Strings for error types for DTLS common messages + */ +static int8_t *nss_dtls_cmn_log_error_response_types_str[NSS_DTLS_CMN_ERROR_MAX] __maybe_unused = { + "DTLS_CMN No Error", + "DTLS_CMN Unknown MEssage", + "DTLS_CMN Invalid Destination Interface", + "DTLS_CMN Invalid Source Interface", + "DTLS_CMN Invalid Crypto", + "DTLS_CMN Invalid Version", + "DTLS_CMN Invalid Context Type", + "DTLS_CMN Invalid Context Words", + "DTLS_CMN Hardware Context Alloc Fail", + "DTLS_CMN Copy Context Failure", + "DTLS_CMN Switch Hardware Context Fail", + "DTLS_CMN Already Configured", + "DTLS_CMN No Memory", + "DTLS_CMN Copy Nonce Failure" +}; + +/* + * nss_dtls_cmn_hdr_config_msg() + * Log DTLS common header configure message. + */ +static void nss_dtls_cmn_hdr_config_msg(struct nss_dtls_cmn_msg *ndm) +{ + struct nss_dtls_cmn_ctx_config_hdr *ndchm __maybe_unused = &ndm->msg.hdr_cfg; + nss_trace("%px: NSS DTLS_CMN Header Configure Message:\n" + "DTLS_CMN flags: %x\n" + "DTLS_CMN destination interface number: %d\n" + "DTLS_CMN source interface number: %d\n" + "DTLS_CMN source ip: %px\n" + "DTLS_CMN destination ip: %px\n" + "DTLS_CMN source port: %d\n" + "DTLS_CMN destination port: %d\n" + "DTLS_CMN time to live: %d\n" + "DTLS_CMN dscp value: %x\n" + "DTLS_CMN dscp copy value: %x\n" + "DTLS_CMN DF flag: %x\n", + ndchm, ndchm->flags, + ndchm->dest_ifnum, ndchm->src_ifnum, + &ndchm->sip, &ndchm->dip, + ndchm->sport, ndchm->dport, + ndchm->hop_limit_ttl, ndchm->dscp, + ndchm->dscp_copy, ndchm->df); +}; + +/* + * nss_dtls_cmn_dtls_config_msg() + * Log DTLS common dtls configure message. + */ +static void nss_dtls_cmn_dtls_config_msg(struct nss_dtls_cmn_msg *ndm) +{ + struct nss_dtls_cmn_ctx_config_dtls *ndcdm __maybe_unused = &ndm->msg.dtls_cfg; + nss_trace("%px: NSS DTLS_CMN DTLS Configure Message:\n" + "DTLS_CMN version: %d\n" + "DTLS_CMN crypto Index: %d\n" + "DTLS_CMN window size: %d\n" + "DTLS_CMN initial epoch: %d\n" + "DTLS_CMN IV length for encapsulation: %d\n" + "DTLS_CMN authentication hash length for encapsulation: %d\n" + "DTLS_CMN cipher block length: %d\n" + "DTLS_CMN reserved: %x\n", + ndcdm, ndcdm->ver, + ndcdm->crypto_idx, ndcdm->window_size, + ndcdm->epoch, ndcdm->iv_len, + ndcdm->hash_len, ndcdm->blk_len, + ndcdm->res1); +}; + +/* + * nss_dtls_cmn_log_verbose() + * Log message contents. + */ +static void nss_dtls_cmn_log_verbose(struct nss_dtls_cmn_msg *ndm) +{ + switch (ndm->cm.type) { + case NSS_DTLS_CMN_MSG_TYPE_CONFIGURE_HDR: + nss_dtls_cmn_hdr_config_msg(ndm); + break; + + case NSS_DTLS_CMN_MSG_TYPE_CONFIGURE_DTLS: + nss_dtls_cmn_dtls_config_msg(ndm); + break; + + default: + nss_warning("%px: Invalid message type\n", ndm); + break; + } +} + +/* + * nss_dtls_cmn_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_dtls_cmn_log_tx_msg(struct nss_dtls_cmn_msg *ndm) +{ + if (ndm->cm.type >= NSS_DTLS_CMN_MSG_MAX) { + nss_warning("%px: Invalid message type\n", ndm); + return; + } + + nss_info("%px: type[%d]:%s\n", ndm, ndm->cm.type, nss_dtls_cmn_log_message_types_str[ndm->cm.type]); + nss_dtls_cmn_log_verbose(ndm); +} + +/* + * nss_dtls_cmn_log_rx_msg() + * Log messages received from FW. + */ +void nss_dtls_cmn_log_rx_msg(struct nss_dtls_cmn_msg *ndm) +{ + if (ndm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", ndm); + return; + } + + if (ndm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ndm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", ndm, ndm->cm.type, + nss_dtls_cmn_log_message_types_str[ndm->cm.type], + ndm->cm.response, nss_cmn_response_str[ndm->cm.response]); + goto verbose; + } + + if (ndm->cm.error >= NSS_DTLS_CMN_ERROR_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + ndm, ndm->cm.type, nss_dtls_cmn_log_message_types_str[ndm->cm.type], + ndm->cm.response, nss_cmn_response_str[ndm->cm.response], + ndm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + ndm, ndm->cm.type, nss_dtls_cmn_log_message_types_str[ndm->cm.type], + ndm->cm.response, nss_cmn_response_str[ndm->cm.response], + ndm->cm.error, nss_dtls_cmn_log_error_response_types_str[ndm->cm.error]); + +verbose: + nss_dtls_cmn_log_verbose(ndm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_dtls_cmn_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_dtls_cmn_log.h new file mode 100644 index 000000000..3a5f75566 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_dtls_cmn_log.h @@ -0,0 +1,37 @@ +/* + ****************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_DTLS_CMN_LOG_H +#define __NSS_DTLS_CMN_LOG_H + +/* + * nss_dtls_cmn_log.h + * NSS DTLS Commn Log Header File. + */ + +/* + * nss_dtls_cmn_log_tx_msg + * Logs a DTLS common message that is sent to the NSS firmware. + */ +void nss_dtls_cmn_log_tx_msg(struct nss_dtls_cmn_msg *ndm); + +/* + * nss_dtls_cmn_log_rx_msg + * Logs a DTLS common message that is received from the NSS firmware. + */ +void nss_dtls_cmn_log_rx_msg(struct nss_dtls_cmn_msg *ndm); + +#endif /* __NSS_DTLS_CMN_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_dtls_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_dtls_log.c new file mode 100644 index 000000000..5e1e33e7a --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_dtls_log.c @@ -0,0 +1,185 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_dtls_log.c + * NSS DTLS logger file. + */ + +#include "nss_core.h" + +/* + * nss_dtls_log_message_types_str + * DTLS message strings + */ +static int8_t *nss_dtls_log_message_types_str[NSS_DTLS_MSG_MAX] __maybe_unused = { + "DTLS Session Configure", + "DTLS Session Destroy", + "DTLS Session Stats", + "DTLS Encap Cipher Update", + "DTLS Encap Cipher Switch", + "DTLS Decap Cipher Update", + "DTLS Decap Cipher Switch" +}; + +/* + * nss_dtls_log_error_response_types_str + * Strings for error types for DTLS messages + */ +static int8_t *nss_dtls_log_error_response_types_str[NSS_DTLS_ERR_MAX] __maybe_unused = { + "DTLS Unknown Message", + "DTLS Invalid APP Interface", + "DTLS Invalid Parameter", + "DTLS Invalid Version", + "DTLS No Memory" +}; + +/* + * nss_dtls_session_config_msg() + * Log DTLS session configure message. + */ +static void nss_dtls_session_config_msg(struct nss_dtls_msg *ndm) +{ + struct nss_dtls_session_configure *ndscm __maybe_unused = &ndm->msg.cfg; + nss_trace("%px: NSS DTLS Session Configure Message:\n" + "DTLS Version: %d\n" + "DTLS Flags: %x\n" + "DTLS crypto index encap: %d\n" + "DTLS crypto index decap: %d\n" + "DTLS IV length for encapsulation: %d\n" + "DTLS IV length for decapsulation: %d\n" + "DTLS authentication hash length for encapsulation: %d\n" + "DTLS authentication hash length for decapsulation: %d\n" + "DTLS cipher algorithm for encapsulation: %x\n" + "DTLS authentication algorithm for encapsulation: %x\n" + "DTLS cipher algorithm for decapsulation: %x\n" + "DTLS authentication algorithm for decapsulation: %x\n" + "DTLS NSS interface: %x\n" + "DTLS source port: %d\n" + "DTLS destination port: %d\n" + "DTLS source ip: %px\n" + "DTLS destination ip: %px\n" + "DTLS window size: %d\n" + "DTLS epoch: %d\n" + "DTLS outer IP TTL: %d\n" + "DTLS reserved1 padding: %x\n" + "DTLS reserved2 padding: %x\n", + ndscm, ndscm->ver, + ndscm->flags, ndscm->crypto_idx_encap, + ndscm->crypto_idx_decap, ndscm->iv_len_encap, + ndscm->iv_len_decap, ndscm->hash_len_encap, + ndscm->hash_len_decap, ndscm->cipher_algo_encap, + ndscm->auth_algo_encap, ndscm->cipher_algo_decap, + ndscm->auth_algo_decap, ndscm->nss_app_if, + ndscm->sport, ndscm->dport, + &ndscm->sip, &ndscm->dip, + ndscm->window_size, ndscm->epoch, + ndscm->oip_ttl, ndscm->reserved1, + ndscm->reserved2); +} + +/* + * nss_dtls_session_cipher_upddate_msg() + * Log DTLS Session Cipher Update message. + */ +static void nss_dtls_session_cipher_update_msg(struct nss_dtls_msg *ndm) +{ + struct nss_dtls_session_cipher_update *ndscum __maybe_unused = &ndm->msg.cipher_update; + nss_trace("%px: NSS DTLS Session Cipher Update message\n" + "DTLS crypto index: %d\n" + "DTLS hash length: %d\n" + "DTLS crypto IV length for encapsulation: %d\n" + "DTLS encapsulation cipher: %x\n" + "DTLS encapsulation authentication algorigthm: %x\n" + "DTLS epoch: %d\n" + "DTLS reserved: %x\n", + ndscum, ndscum->crypto_idx, + ndscum->hash_len, ndscum->iv_len, + ndscum->cipher_algo, ndscum->auth_algo, + ndscum->epoch, ndscum->reserved); +} + +/* + * nss_dtls_log_verbose() + * Log message contents. + */ +static void nss_dtls_log_verbose(struct nss_dtls_msg *ndm) +{ + switch (ndm->cm.type) { + case NSS_DTLS_MSG_REKEY_DECAP_CIPHER_UPDATE: + case NSS_DTLS_MSG_REKEY_ENCAP_CIPHER_UPDATE: + nss_dtls_session_cipher_update_msg(ndm); + break; + + case NSS_DTLS_MSG_SESSION_CONFIGURE: + nss_dtls_session_config_msg(ndm); + break; + + default: + nss_warning("%px: Invalid message type\n", ndm); + break; + } +} + +/* + * nss_dtls_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_dtls_log_tx_msg(struct nss_dtls_msg *ndm) +{ + if (ndm->cm.type >= NSS_DTLS_MSG_MAX) { + nss_warning("%px: Invalid message type\n", ndm); + return; + } + + nss_info("%px: type[%d]:%s\n", ndm, ndm->cm.type, nss_dtls_log_message_types_str[ndm->cm.type]); + nss_dtls_log_verbose(ndm); +} + +/* + * nss_dtls_log_rx_msg() + * Log messages received from FW. + */ +void nss_dtls_log_rx_msg(struct nss_dtls_msg *ndm) +{ + if (ndm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", ndm); + return; + } + + if (ndm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ndm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", ndm, ndm->cm.type, + nss_dtls_log_message_types_str[ndm->cm.type], + ndm->cm.response, nss_cmn_response_str[ndm->cm.response]); + goto verbose; + } + + if (ndm->cm.error >= NSS_DTLS_ERR_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + ndm, ndm->cm.type, nss_dtls_log_message_types_str[ndm->cm.type], + ndm->cm.response, nss_cmn_response_str[ndm->cm.response], + ndm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + ndm, ndm->cm.type, nss_dtls_log_message_types_str[ndm->cm.type], + ndm->cm.response, nss_cmn_response_str[ndm->cm.response], + ndm->cm.error, nss_dtls_log_error_response_types_str[ndm->cm.error]); + +verbose: + nss_dtls_log_verbose(ndm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_dtls_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_dtls_log.h new file mode 100644 index 000000000..99fca71a8 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_dtls_log.h @@ -0,0 +1,37 @@ +/* + ****************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_DTLS_LOG_H +#define __NSS_DTLS_LOG_H + +/* + * nss_dtls_log.h + * NSS DTLS Log Header File + */ + +/* + * nss_dtls_log_tx_msg + * Logs a DTLS message that is sent to the NSS firmware. + */ +void nss_dtls_log_tx_msg(struct nss_dtls_msg *ndm); + +/* + * nss_dtls_log_rx_msg + * Logs a DTLS message that is received from the NSS firmware. + */ +void nss_dtls_log_rx_msg(struct nss_dtls_msg *ndm); + +#endif /* __NSS_DTLS_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_dtls_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_dtls_stats.c new file mode 100644 index 000000000..0aeff87b0 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_dtls_stats.c @@ -0,0 +1,143 @@ +/* + ************************************************************************** + * Copyright (c) 2017, 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_dtls_stats.h" + +/* + * nss_dtls_stats_session_str + * DTLS statistics strings for nss session stats. + */ +struct nss_stats_info nss_dtls_stats_session_str[NSS_DTLS_STATS_SESSION_MAX] = { + {"rx_pkts" , NSS_STATS_TYPE_COMMON}, + {"tx_pkts" , NSS_STATS_TYPE_COMMON}, + {"rx_drops[0]" , NSS_STATS_TYPE_DROP}, + {"rx_drops[1]" , NSS_STATS_TYPE_DROP}, + {"rx_drops[2]" , NSS_STATS_TYPE_DROP}, + {"rx_drops[3]" , NSS_STATS_TYPE_DROP}, + {"rx_auth_done" , NSS_STATS_TYPE_SPECIAL}, + {"tx_auth_done" , NSS_STATS_TYPE_SPECIAL}, + {"rx_cipher_done" , NSS_STATS_TYPE_SPECIAL}, + {"tx_cipher_done" , NSS_STATS_TYPE_SPECIAL}, + {"rx_cbuf_alloc_fail" , NSS_STATS_TYPE_DROP}, + {"tx_cbuf_alloc_fail" , NSS_STATS_TYPE_DROP}, + {"tx_cenqueue_fail" , NSS_STATS_TYPE_DROP}, + {"rx_cenqueue_fail" , NSS_STATS_TYPE_DROP}, + {"tx_drops_hroom" , NSS_STATS_TYPE_DROP}, + {"tx_drops_troom" , NSS_STATS_TYPE_DROP}, + {"tx_forward_enqueue_fail" , NSS_STATS_TYPE_DROP}, + {"rx_forward_enqueue_fail" , NSS_STATS_TYPE_DROP}, + {"rx_invalid_version" , NSS_STATS_TYPE_DROP}, + {"rx_invalid_epoch" , NSS_STATS_TYPE_DROP}, + {"rx_malformed" , NSS_STATS_TYPE_DROP}, + {"rx_cipher_fail" , NSS_STATS_TYPE_EXCEPTION}, + {"rx_auth_fail" , NSS_STATS_TYPE_EXCEPTION}, + {"rx_capwap_classify_fail" , NSS_STATS_TYPE_DROP}, + {"rx_single_rec_dgram" , NSS_STATS_TYPE_SPECIAL}, + {"rx_multi_rec_dgram" , NSS_STATS_TYPE_SPECIAL}, + {"rx_replay_fail" , NSS_STATS_TYPE_DROP}, + {"rx_replay_duplicate" , NSS_STATS_TYPE_SPECIAL}, + {"rx_replay_out_of_window" , NSS_STATS_TYPE_SPECIAL}, + {"outflow_queue_full" , NSS_STATS_TYPE_DROP}, + {"decap_queue_full" , NSS_STATS_TYPE_DROP}, + {"pbuf_alloc_fail" , NSS_STATS_TYPE_DROP}, + {"pbuf_copy_fail" , NSS_STATS_TYPE_DROP}, + {"epoch" , NSS_STATS_TYPE_DROP}, + {"tx_seq_high" , NSS_STATS_TYPE_SPECIAL}, + {"tx_seq_low" , NSS_STATS_TYPE_SPECIAL} +}; + +/* + * nss_dtls_stats_read() + * Read DTLS session statistics. + */ +static ssize_t nss_dtls_stats_read(struct file *fp, char __user *ubuf, + size_t sz, loff_t *ppos) +{ + uint32_t max_output_lines = 2 + (NSS_MAX_DTLS_SESSIONS + * (NSS_DTLS_STATS_SESSION_MAX + 2)) + 2; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + struct net_device *dev; + int id; + struct nss_dtls_stats_session *dtls_session_stats = NULL; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + dtls_session_stats = kzalloc((sizeof(struct nss_dtls_stats_session) + * NSS_MAX_DTLS_SESSIONS), GFP_KERNEL); + if (unlikely(dtls_session_stats == NULL)) { + nss_warning("Could not allocate memory for populating DTLS stats"); + kfree(lbuf); + return 0; + } + + /* + * Get all stats. + */ + nss_dtls_session_stats_get(dtls_session_stats); + + /* + * Session stats. + */ + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "dtls", NSS_STATS_SINGLE_CORE); + + for (id = 0; id < NSS_MAX_DTLS_SESSIONS; id++) { + if (!dtls_session_stats[id].valid) + break; + + dev = dev_get_by_index(&init_net, dtls_session_stats[id].if_index); + if (likely(dev)) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "%d. nss interface id=%d, netdevice=%s\n", + id, dtls_session_stats[id].if_num, + dev->name); + dev_put(dev); + } else { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "%d. nss interface id=%d\n", id, + dtls_session_stats[id].if_num); + } + + size_wr += nss_stats_print("dtls_cmn", NULL, id, nss_dtls_stats_session_str, dtls_session_stats[id].stats, NSS_DTLS_STATS_SESSION_MAX, lbuf, size_wr, size_al); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n"); + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr); + + kfree(dtls_session_stats); + kfree(lbuf); + return bytes_read; +} + +/* + * nss_dtls_stats_ops. + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(dtls) + +/* + * nss_dtls_stats_dentry_create() + * Create DTLS statistics debug entry. + */ +void nss_dtls_stats_dentry_create(void) +{ + nss_stats_create_dentry("dtls", &nss_dtls_stats_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_dtls_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_dtls_stats.h new file mode 100644 index 000000000..bf6a148b7 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_dtls_stats.h @@ -0,0 +1,115 @@ +/* + ****************************************************************************** + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_DTLS_STATS_H +#define __NSS_DTLS_STATS_H + +/* + * DTLS session debug statistic counters + */ +enum nss_dtls_stats_session_types { + NSS_DTLS_STATS_SESSION_RX_PKTS, + /* Rx packets */ + NSS_DTLS_STATS_SESSION_TX_PKTS, + /* Tx packets */ + NSS_DTLS_STATS_SESSION_RX_QUEUE_0_DROPPED, + NSS_DTLS_STATS_SESSION_RX_QUEUE_1_DROPPED, + NSS_DTLS_STATS_SESSION_RX_QUEUE_2_DROPPED, + NSS_DTLS_STATS_SESSION_RX_QUEUE_3_DROPPED, + NSS_DTLS_STATS_SESSION_RX_AUTH_DONE, + /* Rx successful authentication */ + NSS_DTLS_STATS_SESSION_TX_AUTH_DONE, + /* Tx authentication done */ + NSS_DTLS_STATS_SESSION_RX_CIPHER_DONE, + /* Rx cipher done */ + NSS_DTLS_STATS_SESSION_TX_CIPHER_DONE, + /* Tx cipher done */ + NSS_DTLS_STATS_SESSION_RX_CBUF_ALLOC_FAIL, + /* Rx crypto buffer alloc fail */ + NSS_DTLS_STATS_SESSION_TX_CBUF_ALLOC_FAIL, + /* Tx crypto buffer alloc fail */ + NSS_DTLS_STATS_SESSION_TX_CENQUEUE_FAIL, + /* Tx enqueue to crypto fail */ + NSS_DTLS_STATS_SESSION_RX_CENQUEUE_FAIL, + /* Rx enqueue to crypto fail */ + NSS_DTLS_STATS_SESSION_TX_DROPPED_HROOM, + /* Tx drop due to insufficient headroom */ + NSS_DTLS_STATS_SESSION_TX_DROPPED_TROOM, + /* Tx drop due to insufficient tailroom */ + NSS_DTLS_STATS_SESSION_TX_FORWARD_ENQUEUE_FAIL, + /* Enqueue failed to Tx node after encap */ + NSS_DTLS_STATS_SESSION_RX_FORWARD_ENQUEUE_FAIL, + /* Enqueue failed to Rx node after decap */ + NSS_DTLS_STATS_SESSION_RX_INVALID_VERSION, + /* Rx invalid DTLS version */ + NSS_DTLS_STATS_SESSION_RX_INVALID_EPOCH, + /* Rx invalid DTLS epoch */ + NSS_DTLS_STATS_SESSION_RX_MALFORMED, + /* Rx malformed DTLS record */ + NSS_DTLS_STATS_SESSION_RX_CIPHER_FAIL, + /* Rx cipher fail */ + NSS_DTLS_STATS_SESSION_RX_AUTH_FAIL, + /* Rx authentication fail */ + NSS_DTLS_STATS_SESSION_RX_CAPWAP_CLASSIFY_FAIL, + /* Rx CAPWAP classification fail */ + NSS_DTLS_STATS_SESSION_RX_SINGLE_REC_DGRAM, + /* Rx single record datagrams processed */ + NSS_DTLS_STATS_SESSION_RX_MULTI_REC_DGRAM, + /* Rx multi record datagrams processed */ + NSS_DTLS_STATS_SESSION_RX_REPLAY_FAIL, + /* Rx anti-replay failures */ + NSS_DTLS_STATS_SESSION_RX_REPLAY_DUPLICATE, + /* Rx anti-replay fail due to duplicate record */ + NSS_DTLS_STATS_SESSION_RX_REPLAY_OUT_OF_WINDOW, + /* Rx anti-replay fail due to out of window record */ + NSS_DTLS_STATS_SESSION_OUTFLOW_QUEUE_FULL, + /* Tx drop due to encap queue full */ + NSS_DTLS_STATS_SESSION_DECAP_QUEUE_FULL, + /* Rx drop due to decap queue full */ + NSS_DTLS_STATS_SESSION_PBUF_ALLOC_FAIL, + /* Drops due to buffer allocation failure */ + NSS_DTLS_STATS_SESSION_PBUF_COPY_FAIL, + /* Drops due to buffer copy failure */ + NSS_DTLS_STATS_SESSION_EPOCH, + /* Current Epoch */ + NSS_DTLS_STATS_SESSION_TX_SEQ_HIGH, + /* Upper 16-bits of current sequence number */ + NSS_DTLS_STATS_SESSION_TX_SEQ_LOW, + /* Lower 32-bits of current sequence number */ + NSS_DTLS_STATS_SESSION_MAX, +}; + +/* + * DTLS session statistics + */ +struct nss_dtls_stats_session { + uint64_t stats[NSS_DTLS_STATS_SESSION_MAX]; + int32_t if_index; + uint32_t if_num; /* nss interface number */ + bool valid; +}; + +/* + * Stats APIs provided by nss_dtls.c + */ +extern void nss_dtls_session_stats_get(struct nss_dtls_stats_session *s); + +/* + * DTLS statistics APIs + */ +extern void nss_dtls_stats_dentry_create(void); + +#endif /* __NSS_DTLS_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_dynamic_interface.c b/feeds/ipq807x/qca-nss-drv/src/nss_dynamic_interface.c new file mode 100644 index 000000000..a7286bfd0 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_dynamic_interface.c @@ -0,0 +1,420 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_dynamic_interface_log.h" +#include "nss_dynamic_interface_stats.h" + +#define NSS_DYNAMIC_INTERFACE_COMP_TIMEOUT 60000 /* 60 Sec */ + +/* + * Declare atomic notifier data structure for statistics. + */ +ATOMIC_NOTIFIER_HEAD(nss_dynamic_interface_stats_notifier); + +void nss_dynamic_interface_stats_notify(uint32_t if_num, uint32_t core_id); + +/* + * Message data structure to store the message result + */ +struct nss_dynamic_interface_msg_data { + struct completion complete; /* completion structure */ + int if_num; /* Interface number */ + enum nss_cmn_response response; /* Message response */ +}; + +static nss_dynamic_interface_assigned nss_dynamic_interface_assigned_types[NSS_CORE_MAX][NSS_MAX_DYNAMIC_INTERFACES]; /* Array of assigned interface types */ + +/* + * nss_dynamic_interface_handler() + * Handle NSS -> HLOS messages for dynamic interfaces + */ +static void nss_dynamic_interface_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + nss_dynamic_interface_msg_callback_t cb; + struct nss_dynamic_interface_msg *ndim = (struct nss_dynamic_interface_msg *)ncm; + int32_t if_num; + + BUG_ON(ncm->interface != NSS_DYNAMIC_INTERFACE); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_DYNAMIC_INTERFACE_MAX) { + nss_warning("%px: received invalid message %d for dynamic interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_dynamic_interface_msg)) { + nss_warning("%px: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Trace messages. + */ + nss_dynamic_interface_log_rx_msg(ndim); + + /* + * Handling dynamic interface messages coming from NSS fw. + */ + switch (ndim->cm.type) { + case NSS_DYNAMIC_INTERFACE_ALLOC_NODE: + if (ncm->response == NSS_CMN_RESPONSE_ACK) { + nss_info("%px alloc_node response ack if_num %d\n", nss_ctx, ndim->msg.alloc_node.if_num); + if_num = ndim->msg.alloc_node.if_num; + if (if_num > 0) { + nss_dynamic_interface_assigned_types[nss_ctx->id][if_num - NSS_DYNAMIC_IF_START] = ndim->msg.alloc_node.type; + } else { + nss_warning("%px: if_num < 0\n", nss_ctx); + } + } + + break; + + case NSS_DYNAMIC_INTERFACE_DEALLOC_NODE: + if (ncm->response == NSS_CMN_RESPONSE_ACK) { + nss_info("%px dealloc_node response ack if_num %d\n", nss_ctx, ndim->msg.dealloc_node.if_num); + if_num = ndim->msg.dealloc_node.if_num; + nss_dynamic_interface_assigned_types[nss_ctx->id][if_num - NSS_DYNAMIC_IF_START] = NSS_DYNAMIC_INTERFACE_TYPE_NONE; + /* + * Send dynamic interface dealloc notifications to the registered modules. + */ + nss_dynamic_interface_stats_notify(ndim->msg.dealloc_node.if_num, nss_ctx->id); + } + + break; + + default: + nss_warning("%px: Received response %d for type %d, interface %d", + nss_ctx, ncm->response, ncm->type, ncm->interface); + return; + } + + /* + * Do we have a callback? + */ + if (!ncm->cb) { + nss_warning("%px: nss_dynamic_interface_handler cb is NULL\n", nss_ctx); + return; + } + + /* + * Callback + */ + cb = (nss_dynamic_interface_msg_callback_t)ncm->cb; + cb((void *)ncm->app_data, ncm); +} + +/* + * nss_dynamic_interface_callback + * Callback to handle the message response from NSS FW. + */ +static void nss_dynamic_interface_callback(void *app_data, struct nss_cmn_msg *ncm) +{ + struct nss_dynamic_interface_msg_data *di_data = (struct nss_dynamic_interface_msg_data *)app_data; + struct nss_dynamic_interface_msg *ndim = (struct nss_dynamic_interface_msg *)ncm; + + di_data->response = ncm->response; + di_data->if_num = ndim->msg.alloc_node.if_num; + + /* + * Unblock the sleeping function. + */ + complete(&di_data->complete); +} + +/* + * nss_dynamic_interface_tx() + * Transmit a dynamic interface message to NSSFW, asynchronously. + */ +nss_tx_status_t nss_dynamic_interface_tx(struct nss_ctx_instance *nss_ctx, struct nss_dynamic_interface_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Sanity check the message + */ + if (ncm->interface != NSS_DYNAMIC_INTERFACE) { + nss_warning("%px: tx request for another interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type > NSS_DYNAMIC_INTERFACE_MAX) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + /* + * Trace messages. + */ + nss_dynamic_interface_log_tx_msg(msg); + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} + +/* + * nss_dynamic_interface_tx_sync() + * Send the message to NSS and wait till we get an ACK or NACK for this msg. + */ +static nss_tx_status_t nss_dynamic_interface_tx_sync(struct nss_ctx_instance *nss_ctx, struct nss_dynamic_interface_msg_data *di_data, + struct nss_dynamic_interface_msg *ndim) +{ + nss_tx_status_t status; + int ret; + + status = nss_dynamic_interface_tx(nss_ctx, ndim); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: not able to transmit msg successfully\n", nss_ctx); + return status; + } + + /* + * Blocking call, wait till we get ACK for this msg. + */ + ret = wait_for_completion_timeout(&di_data->complete, msecs_to_jiffies(NSS_DYNAMIC_INTERFACE_COMP_TIMEOUT)); + if (ret == 0) { + nss_warning("%px: Waiting for ack timed out\n", nss_ctx); + return NSS_TX_FAILURE; + } + + return status; +} + +/* + * nss_dynamic_interface_alloc_node() + * Allocates node of perticular type on NSS and returns interface_num for this node or -1 in case of failure. + * + * Note: This function should not be called from soft_irq or interrupt context because it blocks till ACK/NACK is + * received for the message sent to NSS. + */ +int nss_dynamic_interface_alloc_node(enum nss_dynamic_interface_type type) +{ + struct nss_ctx_instance *nss_ctx = NULL; + struct nss_dynamic_interface_msg ndim; + struct nss_dynamic_interface_alloc_node_msg *ndia; + struct nss_dynamic_interface_msg_data di_data; + uint32_t core_id; + nss_tx_status_t status; + + if (type >= NSS_DYNAMIC_INTERFACE_TYPE_MAX) { + nss_warning("Dynamic if msg drooped as type is wrong %d\n", type); + return -1; + } + + core_id = nss_top_main.dynamic_interface_table[type]; + nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[core_id]; + di_data.if_num = -1; + di_data.response = false; + init_completion(&di_data.complete); + + nss_dynamic_interface_msg_init(&ndim, NSS_DYNAMIC_INTERFACE, NSS_DYNAMIC_INTERFACE_ALLOC_NODE, + sizeof(struct nss_dynamic_interface_alloc_node_msg), nss_dynamic_interface_callback, (void *)&di_data); + + ndia = &ndim.msg.alloc_node; + ndia->type = type; + + /* + * Initialize if_num to -1. The allocated if_num is returned by the firmware + * in the response message. + */ + ndia->if_num = -1; + + /* + * Calling synchronous transmit function. + */ + status = nss_dynamic_interface_tx_sync(nss_ctx, &di_data, &ndim); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px not able to transmit alloc node msg\n", nss_ctx); + return -1; + } + + /* + * Check response and return -1 if its a NACK else proceed. + */ + if (di_data.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("%px Received NACK from NSS - Response:%d\n", nss_ctx, di_data.response); + return -1; + } + + return di_data.if_num; +} + +/* + * nss_dynamic_interface_dealloc_node() + * Deallocate node of particular type and if_num in NSS. + * + * Note: This will just mark the state of node as not active, actual memory will be freed when reference count of that node becomes 0. + * This function should not be called from soft_irq or interrupt context because it blocks till ACK/NACK is received for the message + * sent to NSS. + */ +nss_tx_status_t nss_dynamic_interface_dealloc_node(int if_num, enum nss_dynamic_interface_type type) +{ + struct nss_ctx_instance *nss_ctx = NULL; + struct nss_dynamic_interface_msg ndim; + struct nss_dynamic_interface_dealloc_node_msg *ndid; + struct nss_dynamic_interface_msg_data di_data; + uint32_t core_id; + nss_tx_status_t status; + + if (type >= NSS_DYNAMIC_INTERFACE_TYPE_MAX) { + nss_warning("Dynamic if msg dropped as type is wrong type %d if_num %d\n", type, if_num); + return NSS_TX_FAILURE_BAD_PARAM; + } + + core_id = nss_top_main.dynamic_interface_table[type]; + nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[core_id]; + di_data.response = false; + init_completion(&di_data.complete); + + if (nss_is_dynamic_interface(if_num) == false) { + nss_warning("%px: nss_dynamic_interface if_num is not in range %d\n", nss_ctx, if_num); + return NSS_TX_FAILURE_BAD_PARAM; + } + + nss_dynamic_interface_msg_init(&ndim, NSS_DYNAMIC_INTERFACE, NSS_DYNAMIC_INTERFACE_DEALLOC_NODE, + sizeof(struct nss_dynamic_interface_dealloc_node_msg), nss_dynamic_interface_callback, (void *)&di_data); + + ndid = &ndim.msg.dealloc_node; + ndid->type = type; + ndid->if_num = if_num; + + /* + * Calling synchronous transmit function. + */ + status = nss_dynamic_interface_tx_sync(nss_ctx, &di_data, &ndim); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px not able to transmit alloc node msg\n", nss_ctx); + return status; + } + + if (di_data.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("%px Received NACK from NSS\n", nss_ctx); + return -1; + } + + return status; +} + +/* + * nss_dynamic_interface_register_handler() + */ +void nss_dynamic_interface_register_handler(struct nss_ctx_instance *nss_ctx) +{ + nss_core_register_handler(nss_ctx, NSS_DYNAMIC_INTERFACE, nss_dynamic_interface_handler, NULL); + nss_dynamic_interface_stats_dentry_create(); +} + +/* + * nss_is_dynamic_interface() + * Judge it is a valid dynamic interface + */ +bool nss_is_dynamic_interface(int if_num) +{ + return (if_num >= NSS_DYNAMIC_IF_START && if_num < NSS_SPECIAL_IF_START); +} + +/* + * nss_dynamic_interface_get_nss_ctx_by_type() + * Gets the NSS context using NSS dynamic interface type. + */ +struct nss_ctx_instance *nss_dynamic_interface_get_nss_ctx_by_type(enum nss_dynamic_interface_type type) +{ + struct nss_ctx_instance *nss_ctx = NULL; + uint32_t core_id; + + if (type >= NSS_DYNAMIC_INTERFACE_TYPE_MAX) { + nss_warning("Invalid param: Type is wrong %d\n", type); + return NULL; + } + + core_id = nss_top_main.dynamic_interface_table[type]; + nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[core_id]; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + return nss_ctx; +} + +/* + * nss_dynamic_interface_get_type() + * Gets the type of dynamic interface + */ +enum nss_dynamic_interface_type nss_dynamic_interface_get_type(struct nss_ctx_instance *nss_ctx, int if_num) +{ + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (nss_is_dynamic_interface(if_num) == false) { + return NSS_DYNAMIC_INTERFACE_TYPE_NONE; + } + + return nss_dynamic_interface_assigned_types[nss_ctx->id][if_num - NSS_DYNAMIC_IF_START]; +} + +/* + * nss_dynamic_interface_msg_init() + * Initialize dynamic interface message. + */ +void nss_dynamic_interface_msg_init(struct nss_dynamic_interface_msg *ndm, uint16_t if_num, uint32_t type, uint32_t len, + void *cb, void *app_data) +{ + nss_cmn_msg_init(&ndm->cm, if_num, type, len, cb, app_data); +} + +/* + * nss_dynamic_interface_stats_notify() + * Sends notifications to all the registered modules. + */ +void nss_dynamic_interface_stats_notify(uint32_t if_num, uint32_t core_id) +{ + struct nss_dynamic_interface_notification stats; + + stats.core_id = core_id; + stats.if_num = if_num; + atomic_notifier_call_chain(&nss_dynamic_interface_stats_notifier, NSS_STATS_EVENT_NOTIFY, (void *)&stats); +} +EXPORT_SYMBOL(nss_dynamic_interface_stats_notify); + +/* + * nss_dynamic_interface_stats_register_notifier() + * Registers statistics notifier. + */ +int nss_dynamic_interface_stats_register_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&nss_dynamic_interface_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_dynamic_interface_stats_register_notifier); + +/* + * nss_dynamic_interface_stats_unregister_notifier() + * Deregisters statistics notifier. + */ +int nss_dynamic_interface_stats_unregister_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&nss_dynamic_interface_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_dynamic_interface_stats_unregister_notifier); + +EXPORT_SYMBOL(nss_dynamic_interface_alloc_node); +EXPORT_SYMBOL(nss_dynamic_interface_dealloc_node); +EXPORT_SYMBOL(nss_is_dynamic_interface); +EXPORT_SYMBOL(nss_dynamic_interface_get_type); +EXPORT_SYMBOL(nss_dynamic_interface_get_nss_ctx_by_type); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_dynamic_interface_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_dynamic_interface_log.c new file mode 100644 index 000000000..0c49aeb7e --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_dynamic_interface_log.c @@ -0,0 +1,145 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_dynamic_interface_log.c + * NSS Dynamic Interface logger file. + */ + +#include "nss_core.h" + +/* + * nss_dynamic_interface_log_message_types_str + * Dynamic Interface message strings + */ +static int8_t *nss_dynamic_interface_log_message_types_str[NSS_DYNAMIC_INTERFACE_MAX] __maybe_unused = { + "Dynamic Interface Alloc Node", + "Dynamic Interface Dealloc Node" +}; + +/* + * nss_dynamic_interface_log_error_response_types_str + * Strings for error types for dynamic interface messages + */ +static int8_t *nss_dynamic_interface_log_error_response_types_str[NSS_DYNAMIC_INTERFACE_ERR_MAX] __maybe_unused = { + "Dynamic Interface Error Unknown Interface", + "Dynamic Interface Error Unavailable Interface", + "Dynamic Interface Error Invalid Interface Type", + "Dynamic Interface Error Invalid Interface Number", + "Dynamic Interface Error Alloc Function Unavailable", + "Dynamic Interface Error Dealloc Funciton Unavailable", + "Dynamic Interface Error Allocation Error", + "Dynamic Interface Error Interface Number Mismatch" +}; + +/* + * nss_dynamic_interface_alloc_node_msg() + * Log Dynamic Interface alloc node message. + */ +static void nss_dynamic_interface_alloc_node_log_msg(struct nss_dynamic_interface_msg *ndm) +{ + struct nss_dynamic_interface_alloc_node_msg *ndanm __maybe_unused = &ndm->msg.alloc_node; + nss_trace("%px: NSS Dynamic Interface Alloc Node Message:\n" + "Dynamic Interface Type: %d\n" + "Dynamic Interface Number: %d\n", + ndanm, ndanm->type, + ndanm->if_num); +} + +/* + * nss_dynamic_interface_dealloc_node_msg() + * Log Dynamic Interface dealloc node message. + */ +static void nss_dynamic_interface_dealloc_node_log_msg(struct nss_dynamic_interface_msg *ndm) +{ + struct nss_dynamic_interface_dealloc_node_msg *nddnm __maybe_unused = &ndm->msg.dealloc_node; + nss_trace("%px: NSS Dynamic Interface Alloc Node Message:\n" + "Dynamic Interface Type: %d\n" + "Dynamic Interface Number: %d\n", + nddnm, nddnm->type, + nddnm->if_num); +} + +/* + * nss_dynamic_interface_log_verbose() + * Log message contents. + */ +static void nss_dynamic_interface_log_verbose(struct nss_dynamic_interface_msg *ndm) +{ + switch (ndm->cm.type) { + case NSS_DYNAMIC_INTERFACE_ALLOC_NODE: + nss_dynamic_interface_alloc_node_log_msg(ndm); + break; + + case NSS_DYNAMIC_INTERFACE_DEALLOC_NODE: + nss_dynamic_interface_dealloc_node_log_msg(ndm); + break; + + default: + nss_warning("%px: Invalid message type\n", ndm); + break; + } +} + +/* + * nss_dynamic_interface_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_dynamic_interface_log_tx_msg(struct nss_dynamic_interface_msg *ndm) +{ + if (ndm->cm.type >= NSS_DYNAMIC_INTERFACE_MAX) { + nss_warning("%px: Invalid message type\n", ndm); + return; + } + + nss_info("%px: type[%d]:%s\n", ndm, ndm->cm.type, nss_dynamic_interface_log_message_types_str[ndm->cm.type]); + nss_dynamic_interface_log_verbose(ndm); +} + +/* + * nss_dynamic_interface_log_rx_msg() + * Log messages received from FW. + */ +void nss_dynamic_interface_log_rx_msg(struct nss_dynamic_interface_msg *ndm) +{ + if (ndm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", ndm); + return; + } + + if (ndm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ndm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", ndm, ndm->cm.type, + nss_dynamic_interface_log_message_types_str[ndm->cm.type], + ndm->cm.response, nss_cmn_response_str[ndm->cm.response]); + goto verbose; + } + + if (ndm->cm.error >= NSS_DYNAMIC_INTERFACE_ERR_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + ndm, ndm->cm.type, nss_dynamic_interface_log_message_types_str[ndm->cm.type], + ndm->cm.response, nss_cmn_response_str[ndm->cm.response], + ndm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s\n, error[%d]:%s\n", + ndm, ndm->cm.type, nss_dynamic_interface_log_message_types_str[ndm->cm.type], + ndm->cm.response, nss_cmn_response_str[ndm->cm.response], + ndm->cm.error, nss_dynamic_interface_log_error_response_types_str[ndm->cm.error]); + +verbose: + nss_dynamic_interface_log_verbose(ndm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_dynamic_interface_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_dynamic_interface_log.h new file mode 100644 index 000000000..266b909c9 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_dynamic_interface_log.h @@ -0,0 +1,37 @@ +/* + ****************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_DYNAMIC_INTERFACE_LOG_H +#define __NSS_DYNAMIC_INTERFACE_LOG_H + +/* + * nss_dynamic_interface.h + * NSS Dynamic Interface private header file. + */ + +/* + * nss_dynamic_interface_log_tx_msg + * Logs a dynamic interface message that is sent to the NSS firmware. + */ +void nss_dynamic_interface_log_tx_msg(struct nss_dynamic_interface_msg *ndm); + +/* + * nss_dynamic_interface_log_rx_msg + * Logs a dynamic interface message that is received from the NSS firmware. + */ +void nss_dynamic_interface_log_rx_msg(struct nss_dynamic_interface_msg *ndm); + +#endif /* __NSS_DYNAMIC_INTERFACE_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_dynamic_interface_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_dynamic_interface_stats.c new file mode 100644 index 000000000..b905a0576 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_dynamic_interface_stats.c @@ -0,0 +1,158 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_dynamic_interface.h" + +/* + * nss_dynamic_interface_type_names + * Name strings for dynamic interface types + */ +const char *nss_dynamic_interface_type_names[NSS_DYNAMIC_INTERFACE_TYPE_MAX] = { + "NSS_DYNAMIC_INTERFACE_TYPE_NONE", + "NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR", + "NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP", + "NSS_DYNAMIC_INTERFACE_TYPE_TUNIPIP6_INNER", + "NSS_DYNAMIC_INTERFACE_TYPE_TUNIPIP6_OUTER", + "NSS_DYNAMIC_INTERFACE_TYPE_WIFI", + "NSS_DYNAMIC_INTERFACE_TYPE_VAP", + "NSS_DYNAMIC_INTERFACE_TYPE_RESERVED_0", + "NSS_DYNAMIC_INTERFACE_TYPE_PPPOE", + "NSS_DYNAMIC_INTERFACE_TYPE_VIRTIF_DEPRECATED", + "NSS_DYNAMIC_INTERFACE_TYPE_L2TPV2", + "NSS_DYNAMIC_INTERFACE_TYPE_RESERVED_4", + "NSS_DYNAMIC_INTERFACE_TYPE_PORTID", + "NSS_DYNAMIC_INTERFACE_TYPE_DTLS", + "NSS_DYNAMIC_INTERFACE_TYPE_QVPN_INNER", + "NSS_DYNAMIC_INTERFACE_TYPE_QVPN_OUTER", + "NSS_DYNAMIC_INTERFACE_TYPE_BRIDGE", + "NSS_DYNAMIC_INTERFACE_TYPE_VLAN", + "NSS_DYNAMIC_INTERFACE_TYPE_RESERVED_3", + "NSS_DYNAMIC_INTERFACE_TYPE_WIFILI_INTERNAL", + "NSS_DYNAMIC_INTERFACE_TYPE_MAP_T_INNER", + "NSS_DYNAMIC_INTERFACE_TYPE_MAP_T_OUTER", + "NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL_INNER", + "NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL_OUTER", + "NSS_DYNAMIC_INTERFACE_TYPE_DTLS_CMN_INNER", + "NSS_DYNAMIC_INTERFACE_TYPE_DTLS_CMN_OUTER", + "NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_WIFI_HOST_INNER", + "NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_WIFI_OFFL_INNER", + "NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_SJACK_INNER", + "NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_OUTER", + "NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL_INLINE_INNER", + "NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL_INLINE_OUTER", + "NSS_DYNAMIC_INTERFACE_TYPE_GENERIC_REDIR_N2H", + "NSS_DYNAMIC_INTERFACE_TYPE_GENERIC_REDIR_H2N", + "NSS_DYNAMIC_INTERFACE_TYPE_TUN6RD_INNER", + "NSS_DYNAMIC_INTERFACE_TYPE_TUN6RD_OUTER", + "NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_US", + "NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_DS", + "NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL_INNER_EXCEPTION", + "NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_EXCEPTION_US", + "NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_EXCEPTION_DS", + "NSS_DYNAMIC_INTERFACE_TYPE_GRE_INNER", + "NSS_DYNAMIC_INTERFACE_TYPE_GRE_OUTER", + "NSS_DYNAMIC_INTERFACE_TYPE_PPTP_INNER", + "NSS_DYNAMIC_INTERFACE_TYPE_PPTP_OUTER", + "NSS_DYNAMIC_INTERFACE_TYPE_PPTP_HOST_INNER", + "NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_INNER", + "NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_MDATA_INNER", + "NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_OUTER", + "NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_MDATA_OUTER", + "NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_REDIRECT", + "NSS_DYNAMIC_INTERFACE_TYPE_PVXLAN_HOST_INNER", + "NSS_DYNAMIC_INTERFACE_TYPE_PVXLAN_OUTER", + "NSS_DYNAMIC_INTERFACE_TYPE_IGS", + "NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_US", + "NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_DS", + "NSS_DYNAMIC_INTERFACE_TYPE_VXLAN_INNER", + "NSS_DYNAMIC_INTERFACE_TYPE_VXLAN_OUTER", + "NSS_DYNAMIC_INTERFACE_TYPE_MATCH", + "NSS_DYNAMIC_INTERFACE_TYPE_RMNET_RX_N2H", + "NSS_DYNAMIC_INTERFACE_TYPE_RMNET_RX_H2N", + "NSS_DYNAMIC_INTERFACE_TYPE_WIFILI_EXTERNAL0", + "NSS_DYNAMIC_INTERFACE_TYPE_WIFILI_EXTERNAL1", +}; + +/* + * nss_dynamic_interface_type_names_stats_read() + * Read and display dynamic interface types names + */ +static ssize_t nss_dynamic_interface_type_names_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int i; + char *lbuf = NULL; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint32_t max_output_lines = 2 /* header & footer for stats */ + + NSS_DYNAMIC_INTERFACE_TYPE_MAX /* maximum number of dynamic interface types */ + + 2; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + + lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + /* + * name strings + */ + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n dynamic interface type names start:\n\n"); + + for (i = 0; i < NSS_DYNAMIC_INTERFACE_TYPE_MAX; i++) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "\t%u : %s\n", i, nss_dynamic_interface_type_names[i]); + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n"); + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n dynamic interface type names end\n"); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr); + + kfree(lbuf); + return bytes_read; +} + +/* + * nss_dynamic_interface_type_names_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(dynamic_interface_type_names) + +/* + * nss_dynamic_interface_stats_dentry_create() + * Create dynamic-interface statistics debug entry. + */ +void nss_dynamic_interface_stats_dentry_create(void) +{ + struct dentry *di_dentry = NULL; + struct dentry *di_type_name_d = NULL; + + di_dentry = debugfs_create_dir("dynamic_if", nss_top_main.stats_dentry); + if (unlikely(di_dentry == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/dynamic_if directory"); + return; + } + + di_type_name_d = debugfs_create_file("type_names", 0400, di_dentry, + &nss_top_main, &nss_dynamic_interface_type_names_stats_ops); + if (unlikely(di_type_name_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/dynamic_if/type_names file"); + return; + } +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_dynamic_interface_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_dynamic_interface_stats.h new file mode 100644 index 000000000..ef16162bc --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_dynamic_interface_stats.h @@ -0,0 +1,33 @@ +/* + ****************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_DYNAMIC_INTERFACE_STATS_H +#define __NSS_DYNAMIC_INTERFACE_STATS_H + +/* + * nss_dynamic_interface.h + * NSS Dynamic Interface private header file. + */ + +/* + * nss_dynamic_interface_stats_dentry_create + * Create dynamic interface debugfs entry. + */ +void nss_dynamic_interface_stats_dentry_create(void); + +#endif /* __NSS_DYNAMIC_INTERFACE_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_edma.c b/feeds/ipq807x/qca-nss-drv/src/nss_edma.c new file mode 100644 index 000000000..f03772689 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_edma.c @@ -0,0 +1,139 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_edma.c + * NSS EDMA APIs + */ +#include "nss_edma_stats.h" +#include "nss_edma_strings.h" + +/* + ********************************** + Rx APIs + ********************************** + */ + +/* + * nss_edma_interface_handler() + * Handle NSS -> HLOS messages for EDMA node + */ +static void nss_edma_interface_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_edma_msg *nem = (struct nss_edma_msg *)ncm; + nss_edma_msg_callback_t cb; + + /* + * Is this a valid request/response packet? + */ + if (nem->cm.type >= NSS_METADATA_TYPE_EDMA_MAX) { + nss_warning("%px: received invalid message %d for edma interface", nss_ctx, nem->cm.type); + return; + } + + /* + * Handle different types of messages + */ + switch (nem->cm.type) { + case NSS_METADATA_TYPE_EDMA_PORT_STATS_SYNC: + /* + * Update driver statistics and send statistics notifications to the registered modules. + */ + nss_edma_metadata_port_stats_sync(nss_ctx, &nem->msg.port_stats); + nss_edma_stats_notify(nss_ctx); + + break; + case NSS_METADATA_TYPE_EDMA_RING_STATS_SYNC: + nss_edma_metadata_ring_stats_sync(nss_ctx, &nem->msg.ring_stats); + break; + case NSS_METADATA_TYPE_EDMA_ERR_STATS_SYNC: + nss_edma_metadata_err_stats_sync(nss_ctx, &nem->msg.err_stats); + break; + default: + if (ncm->response != NSS_CMN_RESPONSE_ACK) { + /* + * Check response + */ + nss_info("%px: Received response %d for type %d, interface %d", + nss_ctx, ncm->response, ncm->type, ncm->interface); + } + } + /* + * Update the callback and app_data for NOTIFY messages, edma sends all notify messages + * to the same callback/app_data. + */ + if (nem->cm.response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_ctx->nss_top->edma_callback; + ncm->app_data = (nss_ptr_t)nss_ctx->nss_top->edma_ctx; + } + + /* + * Do we have a callback? + */ + if (!ncm->cb) { + return; + } + + /* + * Callback + */ + cb = (nss_edma_msg_callback_t)ncm->cb; + cb((void *)ncm->app_data, nem); +} + +/* + * nss_edma_notify_register() + * Register to received EDMA events. + */ +struct nss_ctx_instance *nss_edma_notify_register(nss_edma_msg_callback_t cb, void *app_data) +{ + nss_top_main.edma_callback = cb; + nss_top_main.edma_ctx = app_data; + return &nss_top_main.nss[nss_top_main.edma_handler_id]; +} +EXPORT_SYMBOL(nss_edma_notify_register); + +/* + * nss_edma_notify_unregister() + * Unregister to received EDMA events. + */ +void nss_edma_notify_unregister(void) +{ + nss_top_main.edma_callback = NULL; +} +EXPORT_SYMBOL(nss_edma_notify_unregister); + +/* + * nss_get_edma_context() + */ +struct nss_ctx_instance *nss_edma_get_context(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.edma_handler_id]; +} +EXPORT_SYMBOL(nss_edma_get_context); + +/* + * nss_edma_register_handler() + */ +void nss_edma_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx = nss_edma_get_context(); + + nss_core_register_handler(nss_ctx, NSS_EDMA_INTERFACE, nss_edma_interface_handler, NULL); + + nss_edma_stats_dentry_create(); + nss_edma_strings_dentry_create(); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_edma_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_edma_stats.c new file mode 100644 index 000000000..bff4e5ccb --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_edma_stats.c @@ -0,0 +1,821 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_edma_stats.c + * NSS EDMA statistics APIs + */ + +#include "nss_edma_stats.h" +#include "nss_edma_strings.h" + +/* + * Declare atomic notifier data structure for statistics. + */ +ATOMIC_NOTIFIER_HEAD(nss_edma_stats_notifier); + +struct nss_edma_stats edma_stats; + +/* + ********************************** + EDMA statistics APIs + ********************************** + */ + +/* + * nss_edma_port_stats_read() + * Read EDMA port statistics + */ +static ssize_t nss_edma_port_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i; + + /* + * Max output lines = #stats * NSS_MAX_CORES + + * few blank lines for banner printing + Number of Extra outputlines for future reference to add new stats + */ + uint32_t max_output_lines = NSS_STATS_NODE_MAX + NSS_STATS_EXTRA_OUTPUT_LINES; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + struct nss_stats_data *data = fp->private_data; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + stats_shadow = kzalloc(NSS_STATS_NODE_MAX * sizeof(uint64_t), GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return 0; + } + + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "edma", NSS_STATS_SINGLE_CORE); + + /* + * Common node stats + */ + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "edma port %d stats:\n\n", data->edma_id); + + spin_lock_bh(&nss_top_main.stats_lock); + for (i = 0; (i < NSS_STATS_NODE_MAX); i++) { + stats_shadow[i] = edma_stats.port[data->edma_id].port_stats[i]; + } + + spin_unlock_bh(&nss_top_main.stats_lock); + size_wr += nss_stats_print("edma_port", NULL, data->edma_id + , nss_edma_strings_stats_node + , stats_shadow + , NSS_STATS_NODE_MAX + , lbuf, size_wr, size_al); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * nss_edma_port_type_stats_read() + * Read EDMA port type + */ +static ssize_t nss_edma_port_type_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + /* + * max output lines = #stats + start tag line + end tag line + three blank lines + */ + uint32_t max_output_lines = (1 + 2) + 3; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t port_type; + struct nss_stats_data *data = fp->private_data; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + size_wr = scnprintf(lbuf, size_al, "edma port type start:\n\n"); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "edma port %d type:\n\n", data->edma_id); + + /* + * Port type + */ + spin_lock_bh(&nss_top_main.stats_lock); + port_type = edma_stats.port[data->edma_id].port_type; + spin_unlock_bh(&nss_top_main.stats_lock); + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "port_type = %s\n", nss_edma_strings_stats_port_type[port_type].stats_name); + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nedma stats end\n"); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + + return bytes_read; +} + +/* + * nss_edma_port_ring_map_stats_read() + * Read EDMA port ring map + */ +static ssize_t nss_edma_port_ring_map_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i; + + /* + * max output lines = #stats + start tag line + end tag line + three blank lines + */ + uint32_t max_output_lines = (4 + 2) + 3; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + struct nss_stats_data *data = fp->private_data; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + stats_shadow = kzalloc(NSS_EDMA_PORT_RING_MAP_MAX * sizeof(uint64_t), GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return 0; + } + + size_wr = scnprintf(lbuf, size_al, "edma port ring map start:\n\n"); + + /* + * Port ring map + */ + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "edma port %d ring map:\n\n", data->edma_id); + spin_lock_bh(&nss_top_main.stats_lock); + for (i = 0; i < NSS_EDMA_PORT_RING_MAP_MAX; i++) { + stats_shadow[i] = edma_stats.port[data->edma_id].port_ring_map[i]; + } + + spin_unlock_bh(&nss_top_main.stats_lock); + + size_wr += nss_stats_print("edma_port_ring", NULL, data->edma_id + , nss_edma_strings_stats_port_ring_map + , stats_shadow + , NSS_EDMA_PORT_RING_MAP_MAX + , lbuf, size_wr, size_al); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * nss_edma_txring_stats_read() + * Read EDMA Tx ring stats + */ +static ssize_t nss_edma_txring_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i; + + /* + * max output lines = #stats + start tag line + end tag line + three blank lines + */ + uint32_t max_output_lines = (NSS_EDMA_STATS_TX_MAX + 2) + 3; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + struct nss_stats_data *data = fp->private_data; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + stats_shadow = kzalloc(NSS_EDMA_STATS_TX_MAX * sizeof(uint64_t), GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return 0; + } + + size_wr = scnprintf(lbuf, size_al, "edma Tx ring stats start:\n\n"); + + /* + * Tx ring stats + */ + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "Tx ring %d stats:\n\n", data->edma_id); + spin_lock_bh(&nss_top_main.stats_lock); + for (i = 0; i < NSS_EDMA_STATS_TX_MAX; i++) { + stats_shadow[i] = edma_stats.tx_stats[data->edma_id][i]; + } + + spin_unlock_bh(&nss_top_main.stats_lock); + + size_wr += nss_stats_print("edma_tx_ring", NULL, data->edma_id + , nss_edma_strings_stats_tx + , stats_shadow + , NSS_EDMA_STATS_TX_MAX + , lbuf, size_wr, size_al); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * nss_edma_rxring_stats_read() + * Read EDMA rxring stats + */ +static ssize_t nss_edma_rxring_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i; + + /* + * max output lines = #stats + start tag line + end tag line + three blank lines + */ + uint32_t max_output_lines = (NSS_EDMA_STATS_RX_MAX + 2) + 3; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + struct nss_stats_data *data = fp->private_data; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + stats_shadow = kzalloc(NSS_EDMA_STATS_RX_MAX * sizeof(uint64_t), GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return 0; + } + + /* + * RX ring stats + */ + spin_lock_bh(&nss_top_main.stats_lock); + for (i = 0; i < NSS_EDMA_STATS_RX_MAX; i++) { + stats_shadow[i] = edma_stats.rx_stats[data->edma_id][i]; + } + + spin_unlock_bh(&nss_top_main.stats_lock); + size_wr += nss_stats_print("edma_rx_ring", NULL, data->edma_id + , nss_edma_strings_stats_rx + , stats_shadow + , NSS_EDMA_STATS_RX_MAX + , lbuf, size_wr, size_al); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * nss_edma_txcmplring_stats_read() + * Read EDMA txcmplring stats + */ +static ssize_t nss_edma_txcmplring_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i; + + /* + * max output lines = #stats + start tag line + end tag line + three blank lines + */ + uint32_t max_output_lines = (NSS_EDMA_STATS_TXCMPL_MAX + 2) + 3; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + struct nss_stats_data *data = fp->private_data; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + stats_shadow = kzalloc(NSS_EDMA_STATS_TXCMPL_MAX * sizeof(uint64_t), GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return 0; + } + + size_wr = scnprintf(lbuf, size_al, "edma Tx cmpl ring stats start:\n\n"); + + /* + * Tx cmpl ring stats + */ + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "Tx cmpl ring %d stats:\n\n", data->edma_id); + spin_lock_bh(&nss_top_main.stats_lock); + for (i = 0; i < NSS_EDMA_STATS_TXCMPL_MAX; i++) { + stats_shadow[i] = edma_stats.txcmpl_stats[data->edma_id][i]; + } + + spin_unlock_bh(&nss_top_main.stats_lock); + size_wr += nss_stats_print("edma_tx_cmpl_ring", NULL, data->edma_id + , nss_edma_strings_stats_txcmpl + , stats_shadow + , NSS_EDMA_STATS_TXCMPL_MAX + , lbuf, size_wr, size_al); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nedma Tx cmpl ring stats end\n\n"); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * nss_edma_rxfillring_stats_read() + * Read EDMA rxfillring stats + */ +static ssize_t nss_edma_rxfillring_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i; + + /* + * max output lines = #stats + start tag line + end tag line + three blank lines + */ + uint32_t max_output_lines = (NSS_EDMA_STATS_RXFILL_MAX + 2) + 3; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + struct nss_stats_data *data = fp->private_data; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + stats_shadow = kzalloc(NSS_EDMA_STATS_RXFILL_MAX * sizeof(uint64_t), GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return 0; + } + + size_wr = scnprintf(lbuf, size_al, "edma Rx fill ring stats start:\n\n"); + + /* + * Rx fill ring stats + */ + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "Rx fill ring %d stats:\n\n", data->edma_id); + spin_lock_bh(&nss_top_main.stats_lock); + for (i = 0; i < NSS_EDMA_STATS_RXFILL_MAX; i++) { + stats_shadow[i] = edma_stats.rxfill_stats[data->edma_id][i]; + } + + spin_unlock_bh(&nss_top_main.stats_lock); + size_wr += nss_stats_print("edma_rx_fill_ring", NULL + , NSS_STATS_SINGLE_INSTANCE + , nss_edma_strings_stats_rxfill + , stats_shadow + , NSS_EDMA_STATS_RXFILL_MAX + , lbuf, size_wr, size_al); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * nss_edma_err_stats_read() + * Read EDMA err stats + */ +static ssize_t nss_edma_err_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i; + + /* + * max output lines = #stats + start tag line + end tag line + three blank lines + */ + uint32_t max_output_lines = (NSS_EDMA_ERR_STATS_MAX + 2) + 3; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + stats_shadow = kzalloc(NSS_EDMA_ERR_STATS_MAX * sizeof(uint64_t), GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return 0; + } + + size_wr = scnprintf(lbuf, size_al, "edma error stats start:\n\n"); + + /* + * Common node stats + */ + spin_lock_bh(&nss_top_main.stats_lock); + + for (i = 0; (i < NSS_EDMA_ERR_STATS_MAX); i++) + stats_shadow[i] = edma_stats.misc_err[i]; + + spin_unlock_bh(&nss_top_main.stats_lock); + size_wr += nss_stats_print("edma_err", NULL, NSS_STATS_SINGLE_INSTANCE + , nss_edma_strings_stats_err_map + , stats_shadow + , NSS_EDMA_ERR_STATS_MAX + , lbuf, size_wr, size_al); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * edma_port_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(edma_port); + +/* + * edma_port_type_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(edma_port_type); + +/* + * edma_port_ring_map_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(edma_port_ring_map); + +/* + * edma_txring_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(edma_txring); + +/* + * edma_rxring_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(edma_rxring); + +/* + * edma_txcmplring_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(edma_txcmplring); + +/* + * edma_rxfillring_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(edma_rxfillring); + +/* + * edma_err_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(edma_err); + +/* + * nss_edma_stats_dentry_create() + * Create edma statistics debug entry. + */ +void nss_edma_stats_dentry_create(void) +{ + int i; + struct dentry *edma_d = NULL; + struct dentry *edma_port_dir_d = NULL; + struct dentry *edma_port_d = NULL; + struct dentry *edma_port_type_d = NULL; + struct dentry *edma_port_stats_d = NULL; + struct dentry *edma_port_ring_map_d = NULL; + struct dentry *edma_rings_dir_d = NULL; + struct dentry *edma_tx_dir_d = NULL; + struct dentry *edma_tx_d = NULL; + struct dentry *edma_rx_dir_d = NULL; + struct dentry *edma_rx_d = NULL; + struct dentry *edma_txcmpl_dir_d = NULL; + struct dentry *edma_txcmpl_d = NULL; + struct dentry *edma_rxfill_dir_d = NULL; + struct dentry *edma_rxfill_d = NULL; + struct dentry *edma_err_stats_d = NULL; + char file_name[10]; + + edma_d = debugfs_create_dir("edma", nss_top_main.stats_dentry); + if (unlikely(edma_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/edma directory"); + return; + } + + /* + * edma port stats + */ + edma_port_dir_d = debugfs_create_dir("ports", edma_d); + if (unlikely(edma_port_dir_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/edma/ports directory"); + return; + } + + for (i = 0; i < NSS_EDMA_NUM_PORTS_MAX; i++) { + memset(file_name, 0, sizeof(file_name)); + snprintf(file_name, sizeof(file_name), "%d", i); + + edma_port_d = debugfs_create_dir(file_name, edma_port_dir_d); + if (unlikely(edma_port_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/edma/ports/%d directory", i); + return; + } + + edma_port_stats_d = debugfs_create_file("stats", 0400, edma_port_d, (void *)(nss_ptr_t)i, &nss_edma_port_stats_ops); + if (unlikely(edma_port_stats_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/edma/ports/%d/stats file", i); + return; + } + + edma_port_type_d = debugfs_create_file("type", 0400, edma_port_d, (void *)(nss_ptr_t)i, &nss_edma_port_type_stats_ops); + if (unlikely(edma_port_type_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/edma/ports/%d/type file", i); + return; + } + + edma_port_ring_map_d = debugfs_create_file("ring_map", 0400, edma_port_d, (void *)(nss_ptr_t)i, &nss_edma_port_ring_map_stats_ops); + if (unlikely(edma_port_ring_map_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/edma/ports/%d/ring_map file", i); + return; + } + } + + /* + * edma error stats + */ + edma_err_stats_d = NULL; + edma_err_stats_d = debugfs_create_file("err_stats", 0400, edma_d, &nss_top_main, &nss_edma_err_stats_ops); + if (unlikely(edma_port_stats_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/edma/%d/err_stats file", 0); + return; + } + + /* + * edma ring stats + */ + edma_rings_dir_d = debugfs_create_dir("rings", edma_d); + if (unlikely(edma_rings_dir_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/edma/rings directory"); + return; + } + + /* + * edma tx ring stats + */ + edma_tx_dir_d = debugfs_create_dir("tx", edma_rings_dir_d); + if (unlikely(edma_tx_dir_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/edma/rings/tx directory"); + return; + } + + for (i = 0; i < NSS_EDMA_NUM_TX_RING_MAX; i++) { + memset(file_name, 0, sizeof(file_name)); + scnprintf(file_name, sizeof(file_name), "%d", i); + edma_tx_d = debugfs_create_file(file_name, 0400, edma_tx_dir_d, (void *)(nss_ptr_t)i, &nss_edma_txring_stats_ops); + if (unlikely(edma_tx_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/edma/rings/tx/%d file", i); + return; + } + } + + /* + * edma rx ring stats + */ + edma_rx_dir_d = debugfs_create_dir("rx", edma_rings_dir_d); + if (unlikely(edma_rx_dir_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/edma/rings/rx directory"); + return; + } + + for (i = 0; i < NSS_EDMA_NUM_RX_RING_MAX; i++) { + memset(file_name, 0, sizeof(file_name)); + scnprintf(file_name, sizeof(file_name), "%d", i); + edma_rx_d = debugfs_create_file(file_name, 0400, edma_rx_dir_d, (void *)(nss_ptr_t)i, &nss_edma_rxring_stats_ops); + if (unlikely(edma_rx_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/edma/rings/rx/%d file", i); + return; + } + } + + /* + * edma tx cmpl ring stats + */ + edma_txcmpl_dir_d = debugfs_create_dir("txcmpl", edma_rings_dir_d); + if (unlikely(edma_txcmpl_dir_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/edma/rings/txcmpl directory"); + return; + } + + for (i = 0; i < NSS_EDMA_NUM_TXCMPL_RING_MAX; i++) { + memset(file_name, 0, sizeof(file_name)); + scnprintf(file_name, sizeof(file_name), "%d", i); + edma_txcmpl_d = debugfs_create_file(file_name, 0400, edma_txcmpl_dir_d, (void *)(nss_ptr_t)i, &nss_edma_txcmplring_stats_ops); + if (unlikely(edma_txcmpl_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/edma/rings/txcmpl/%d file", i); + return; + } + } + + /* + * edma rx fill ring stats + */ + edma_rxfill_dir_d = debugfs_create_dir("rxfill", edma_rings_dir_d); + if (unlikely(edma_rxfill_dir_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/edma/rings/rxfill directory"); + return; + } + + for (i = 0; i < NSS_EDMA_NUM_RXFILL_RING_MAX; i++) { + memset(file_name, 0, sizeof(file_name)); + scnprintf(file_name, sizeof(file_name), "%d", i); + edma_rxfill_d = debugfs_create_file(file_name, 0400, edma_rxfill_dir_d, (void *)(nss_ptr_t)i, &nss_edma_rxfillring_stats_ops); + if (unlikely(edma_rxfill_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/edma/rings/rxfill/%d file", i); + return; + } + } +} + +/* + * nss_edma_metadata_port_stats_sync() + * Handle the syncing of EDMA port statistics. + */ +void nss_edma_metadata_port_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_edma_port_stats_sync *nepss) +{ + uint16_t i, j = 0; + struct nss_top_instance *nss_top = nss_ctx->nss_top; + + spin_lock_bh(&nss_top->stats_lock); + + /* + * edma port stats + * We process a subset of port stats since msg payload is not enough to hold all ports at once. + */ + for (i = nepss->start_port; i < nepss->end_port; i++) { + int k; + + edma_stats.port[i].port_stats[NSS_STATS_NODE_RX_PKTS] += nepss->port_stats[j].node_stats.rx_packets; + edma_stats.port[i].port_stats[NSS_STATS_NODE_RX_BYTES] += nepss->port_stats[j].node_stats.rx_bytes; + edma_stats.port[i].port_stats[NSS_STATS_NODE_TX_PKTS] += nepss->port_stats[j].node_stats.tx_packets; + edma_stats.port[i].port_stats[NSS_STATS_NODE_TX_BYTES] += nepss->port_stats[j].node_stats.tx_bytes; + + for (k = 0; k < NSS_MAX_NUM_PRI; k++) { + edma_stats.port[i].port_stats[NSS_STATS_NODE_RX_QUEUE_0_DROPPED + k] += nepss->port_stats[j].node_stats.rx_dropped[k]; + } + + edma_stats.port[i].port_type = nepss->port_stats[j].port_type; + edma_stats.port[i].port_ring_map[NSS_EDMA_PORT_RX_RING] = nepss->port_stats[j].edma_rx_ring; + edma_stats.port[i].port_ring_map[NSS_EDMA_PORT_TX_RING] = nepss->port_stats[j].edma_tx_ring; + j++; + } + + spin_unlock_bh(&nss_top->stats_lock); +} + +/* + * nss_edma_metadata_ring_stats_sync() + * Handle the syncing of EDMA ring statistics. + */ +void nss_edma_metadata_ring_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_edma_ring_stats_sync *nerss) +{ + int32_t i; + struct nss_top_instance *nss_top = nss_ctx->nss_top; + + spin_lock_bh(&nss_top->stats_lock); + + /* + * edma tx ring stats + */ + for (i = 0; i < NSS_EDMA_NUM_TX_RING_MAX; i++) { + edma_stats.tx_stats[i][NSS_EDMA_STATS_TX_ERR] += nerss->tx_ring[i].tx_err; + edma_stats.tx_stats[i][NSS_EDMA_STATS_TX_DROPPED] += nerss->tx_ring[i].tx_dropped; + edma_stats.tx_stats[i][NSS_EDMA_STATS_TX_DESC] += nerss->tx_ring[i].desc_cnt; + } + + /* + * edma rx ring stats + */ + for (i = 0; i < NSS_EDMA_NUM_RX_RING_MAX; i++) { + edma_stats.rx_stats[i][NSS_EDMA_STATS_RX_CSUM_ERR] += nerss->rx_ring[i].rx_csum_err; + edma_stats.rx_stats[i][NSS_EDMA_STATS_RX_DESC] += nerss->rx_ring[i].desc_cnt; + edma_stats.rx_stats[i][NSS_EDMA_STATS_RX_QOS_ERR] += nerss->rx_ring[i].qos_err; + edma_stats.rx_stats[i][NSS_EDMA_STATS_RX_SRC_PORT_INVALID] += nerss->rx_ring[i].rx_src_port_invalid; + } + + /* + * edma tx cmpl ring stats + */ + for (i = 0; i < NSS_EDMA_NUM_TXCMPL_RING_MAX; i++) { + edma_stats.txcmpl_stats[i][NSS_EDMA_STATS_TXCMPL_DESC] += nerss->txcmpl_ring[i].desc_cnt; + } + + /* + * edma rx fill ring stats + */ + for (i = 0; i < NSS_EDMA_NUM_RXFILL_RING_MAX; i++) { + edma_stats.rxfill_stats[i][NSS_EDMA_STATS_RXFILL_DESC] += nerss->rxfill_ring[i].desc_cnt; + } + + spin_unlock_bh(&nss_top->stats_lock); +} + +/* + * nss_edma_metadata_err_stats_sync() + * Handle the syncing of EDMA error statistics. + */ +void nss_edma_metadata_err_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_edma_err_stats_sync *nerss) +{ + + struct nss_top_instance *nss_top = nss_ctx->nss_top; + + spin_lock_bh(&nss_top->stats_lock); + + edma_stats.misc_err[NSS_EDMA_AXI_RD_ERR] += nerss->msg_err_stats.axi_rd_err; + edma_stats.misc_err[NSS_EDMA_AXI_WR_ERR] += nerss->msg_err_stats.axi_wr_err; + edma_stats.misc_err[NSS_EDMA_RX_DESC_FIFO_FULL_ERR] += nerss->msg_err_stats.rx_desc_fifo_full_err; + edma_stats.misc_err[NSS_EDMA_RX_BUF_SIZE_ERR] += nerss->msg_err_stats.rx_buf_size_err; + edma_stats.misc_err[NSS_EDMA_TX_SRAM_FULL_ERR] += nerss->msg_err_stats.tx_sram_full_err; + edma_stats.misc_err[NSS_EDMA_TX_CMPL_BUF_FULL_ERR] += nerss->msg_err_stats.tx_cmpl_buf_full_err; + edma_stats.misc_err[NSS_EDMA_PKT_LEN_LA64K_ERR] += nerss->msg_err_stats.pkt_len_la64k_err; + edma_stats.misc_err[NSS_EDMA_PKT_LEN_LE33_ERR] += nerss->msg_err_stats.pkt_len_le33_err; + edma_stats.misc_err[NSS_EDMA_DATA_LEN_ERR] += nerss->msg_err_stats.data_len_err; + edma_stats.misc_err[NSS_EDMA_ALLOC_FAIL_CNT] += nerss->msg_err_stats.alloc_fail_cnt; + edma_stats.misc_err[NSS_EDMA_QOS_INVAL_DST_DROPS] += nerss->msg_err_stats.qos_inval_dst_drops; + + spin_unlock_bh(&nss_top->stats_lock); +} + +/* + * nss_edma_stats_notify() + * Calls statistics notifier. + * + * Leverage NSS-FW statistics timing to update Netlink. + */ +void nss_edma_stats_notify(struct nss_ctx_instance *nss_ctx) +{ + uint32_t core_id = nss_ctx->id; + + atomic_notifier_call_chain(&nss_edma_stats_notifier, NSS_STATS_EVENT_NOTIFY, (void *)&core_id); +} + +/* + * nss_edma_stats_register_notifier() + * Registers statistics notifier. + */ +int nss_edma_stats_register_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&nss_edma_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_edma_stats_register_notifier); + +/* + * nss_edma_stats_unregister_notifier() + * Deregisters stats notifier. + */ +int nss_edma_stats_unregister_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&nss_edma_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_edma_stats_unregister_notifier); + +/* + * nss_edma_get_stats + * Sends EDMA statistics to NSS clients. + */ +void nss_edma_get_stats(uint64_t *stats, int port_id) +{ + memcpy(stats, edma_stats.port[port_id].port_stats, sizeof(uint64_t) * NSS_STATS_NODE_MAX); +} +EXPORT_SYMBOL(nss_edma_get_stats); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_edma_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_edma_stats.h new file mode 100644 index 000000000..305582b84 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_edma_stats.h @@ -0,0 +1,36 @@ +/* + ****************************************************************************** + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +/* + * nss_edma_stats.h + * NSS EDMA statistics header file. + */ + +#ifndef __NSS_EDMA_STATS_H +#define __NSS_EDMA_STATS_H + +#include "nss_core.h" + +/* + * NSS EDMA statistics APIs + */ +extern void nss_edma_stats_notify(struct nss_ctx_instance *nss_ctx); +extern void nss_edma_metadata_port_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_edma_port_stats_sync *nepss); +extern void nss_edma_metadata_ring_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_edma_ring_stats_sync *nerss); +extern void nss_edma_metadata_err_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_edma_err_stats_sync *nerss); +extern void nss_edma_stats_dentry_create(void); + +#endif /* __NSS_EDMA_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_edma_strings.c b/feeds/ipq807x/qca-nss-drv/src/nss_edma_strings.c new file mode 100644 index 000000000..c441114e7 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_edma_strings.c @@ -0,0 +1,349 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_stats.h" +#include "nss_core.h" +#include +#include "nss_strings.h" + +/* + * nss_edma_strings_stats_node + * EDMA statistics strings. + */ +struct nss_stats_info nss_edma_strings_stats_node[NSS_STATS_NODE_MAX] = { + {"rx_pkts" , NSS_STATS_TYPE_COMMON}, + {"rx_byts" , NSS_STATS_TYPE_COMMON}, + {"tx_pkts" , NSS_STATS_TYPE_COMMON}, + {"tx_byts" , NSS_STATS_TYPE_COMMON}, + {"rx_queue[0]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[1]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[2]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[3]_drops" , NSS_STATS_TYPE_DROP} +}; + +/* + * nss_edma_common_stats_strings_read() + * Read EDMA common node statistics names. + */ +static ssize_t nss_edma_common_stats_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_edma_strings_stats_node, NSS_STATS_NODE_MAX); +} + +/* + * nss_edma_common_stats_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(edma_common_stats); + +/* + * nss_edma_strings_stats_tx + */ +struct nss_stats_info nss_edma_strings_stats_tx[NSS_EDMA_STATS_TX_MAX] = { + {"tx_err" , NSS_STATS_TYPE_ERROR}, + {"tx_drops" , NSS_STATS_TYPE_DROP}, + {"desc_cnt" , NSS_STATS_TYPE_SPECIAL} +}; + +/* + * nss_edma_txring_strings_read() + * Read EDMA txring names. + */ +static ssize_t nss_edma_txring_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_edma_strings_stats_tx, NSS_EDMA_STATS_TX_MAX); +} + +/* + * edma_txring_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(edma_txring); + +/* + * nss_edma_strings_stats_rx + */ +struct nss_stats_info nss_edma_strings_stats_rx[NSS_EDMA_STATS_RX_MAX] = { + {"rx_csum_err" , NSS_STATS_TYPE_ERROR}, + {"desc_cnt" , NSS_STATS_TYPE_SPECIAL}, + {"qos_err" , NSS_STATS_TYPE_DROP}, + {"rx_src_port_invalid" , NSS_STATS_TYPE_DROP} +}; + +/* + * nss_edma_rxring_strings_read() + * Read EDMA rxring names. + */ +static ssize_t nss_edma_rxring_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_edma_strings_stats_rx, NSS_EDMA_STATS_RX_MAX); +} + +/* + * edma_rxring_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(edma_rxring); + +/* + * nss_edma_strings_stats_txcmpl + */ +struct nss_stats_info nss_edma_strings_stats_txcmpl[NSS_EDMA_STATS_TXCMPL_MAX] = { + {"desc_cnt" , NSS_STATS_TYPE_SPECIAL} +}; + +/* + * nss_edma_txcmplring_strings_read() + * Read EDMA txcmplring names. + */ +static ssize_t nss_edma_txcmplring_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_edma_strings_stats_txcmpl, NSS_EDMA_STATS_TXCMPL_MAX); +} + +/* + * edma_txcmplring_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(edma_txcmplring); + +/* + * nss_edma_strings_stats_rxfill + */ +struct nss_stats_info nss_edma_strings_stats_rxfill[NSS_EDMA_STATS_RXFILL_MAX] = { + {"desc_cnt" , NSS_STATS_TYPE_SPECIAL} +}; + +/* + * nss_edma_rxfillring_strings_read() + * Read EDMA rxfillring names. + */ +static ssize_t nss_edma_rxfillring_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_edma_strings_stats_rxfill, NSS_EDMA_STATS_RXFILL_MAX); +} + +/* + * edma_rxfillring_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(edma_rxfillring); + +/* + * nss_edma_strings_stats_port_type + */ +struct nss_stats_info nss_edma_strings_stats_port_type[NSS_EDMA_PORT_TYPE_MAX] = { + {"physical_port", NSS_STATS_TYPE_SPECIAL}, + {"virtual_port" , NSS_STATS_TYPE_SPECIAL} +}; + +/* + * nss_edma_port_type_strings_read() + * Read EDMA port type names. + */ +static ssize_t nss_edma_port_type_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_edma_strings_stats_port_type, NSS_EDMA_PORT_TYPE_MAX); +} + +/* + * edma_port_type_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(edma_port_type); + +/* + * nss_edma_strings_stats_port_ring_map + */ +struct nss_stats_info nss_edma_strings_stats_port_ring_map[NSS_EDMA_PORT_RING_MAP_MAX] = { + {"rx_ring" , NSS_STATS_TYPE_SPECIAL}, + {"tx_ring" , NSS_STATS_TYPE_SPECIAL} +}; + +/* + * nss_edma_port_ring_map_strings_read() + * Read EDMA port ring map names. + */ +static ssize_t nss_edma_port_ring_map_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_edma_strings_stats_port_ring_map, NSS_EDMA_PORT_RING_MAP_MAX); +} + +/* + * edma_port_ring_map_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(edma_port_ring_map); + +/* + * nss_edma_strings_stats_err_map + */ +struct nss_stats_info nss_edma_strings_stats_err_map[NSS_EDMA_ERR_STATS_MAX] = { + {"axi_rd_err" , NSS_STATS_TYPE_ERROR}, + {"axi_wr_err" , NSS_STATS_TYPE_ERROR}, + {"rx_desc_fifo_full_err", NSS_STATS_TYPE_ERROR}, + {"rx_buf_size_err" , NSS_STATS_TYPE_ERROR}, + {"tx_sram_full_err" , NSS_STATS_TYPE_ERROR}, + {"tx_cmpl_buf_full_err" , NSS_STATS_TYPE_ERROR}, + {"pkt_len_la64k_err" , NSS_STATS_TYPE_ERROR}, + {"pkt_len_le33_err" , NSS_STATS_TYPE_ERROR}, + {"data_len_err" , NSS_STATS_TYPE_ERROR}, + {"alloc_fail_cnt" , NSS_STATS_TYPE_ERROR}, + {"qos_inval_dst_drops" , NSS_STATS_TYPE_DROP} +}; + +/* + * nss_edma_err_strings_read() + * Read EDMA error names. + */ +static ssize_t nss_edma_err_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_edma_strings_stats_err_map, NSS_EDMA_ERR_STATS_MAX); +} + +/* + * edma_err_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(edma_err); + +/* + * nss_edma_strings_dentry_create() + * Create EDMA statistics strings debug entry. + */ +void nss_edma_strings_dentry_create(void) +{ + struct dentry *edma_d; + struct dentry *edma_port_dir_d; + struct dentry *edma_rings_dir_d; + struct dentry *edma_rx_dir_d; + struct dentry *edma_tx_dir_d; + struct dentry *edma_rxfill_dir_d; + struct dentry *edma_txcmpl_dir_d; + struct dentry *file_d; + + if (!nss_top_main.strings_dentry) { + nss_warning("qca-nss-drv/strings is not present"); + return; + } + + edma_d = debugfs_create_dir("edma", nss_top_main.strings_dentry); + if (!edma_d) { + nss_warning("Failed to create qca-nss-drv/strings/edma directory"); + return; + } + + /* + * EDMA port stats. + */ + edma_port_dir_d = debugfs_create_dir("ports", edma_d); + if (!edma_port_dir_d) { + nss_warning("Failed to create qca-nss-drv/strings/edma/ports directory"); + goto fail; + } + + file_d = debugfs_create_file("common_stats_str", 0400, edma_port_dir_d, &nss_top_main, &nss_edma_common_stats_strings_ops); + if (!file_d) { + nss_warning("Failed to create qca-nss-drv/strings/edma/ports/common_stats_str file"); + goto fail; + } + + file_d = debugfs_create_file("type", 0400, edma_port_dir_d, &nss_top_main, &nss_edma_port_type_strings_ops); + if (!file_d) { + nss_warning("Failed to create qca-nss-drv/strings/edma/ports/type file"); + goto fail; + } + + file_d = debugfs_create_file("ring_map", 0400, edma_port_dir_d, &nss_top_main, &nss_edma_port_ring_map_strings_ops); + if (!file_d) { + nss_warning("Failed to create qca-nss-drv/strings/edma/ports/ring_map file"); + goto fail; + } + + /* + * edma error stats + */ + file_d = debugfs_create_file("err_stats", 0400, edma_d, &nss_top_main, &nss_edma_err_strings_ops); + if (!file_d) { + nss_warning("Failed to create qca-nss-drv/strings/edma/err_stats file"); + goto fail; + } + + /* + * edma ring stats + */ + edma_rings_dir_d = debugfs_create_dir("rings", edma_d); + if (!edma_rings_dir_d) { + nss_warning("Failed to create qca-nss-drv/strings/edma/rings directory"); + goto fail; + } + + /* + * edma tx ring stats + */ + edma_tx_dir_d = debugfs_create_dir("tx", edma_rings_dir_d); + if (!edma_tx_dir_d) { + nss_warning("Failed to create qca-nss-drv/strings/edma/rings/tx directory"); + goto fail; + } + + file_d = debugfs_create_file("tx_str", 0400, edma_tx_dir_d, &nss_top_main, &nss_edma_txring_strings_ops); + if (!file_d) { + nss_warning("Failed to create qca-nss-drv/strings/edma/rings/tx file"); + goto fail; + } + + /* + * edma rx ring stats + */ + edma_rx_dir_d = debugfs_create_dir("rx", edma_rings_dir_d); + if (!edma_rx_dir_d) { + nss_warning("Failed to create qca-nss-drv/strings/edma/rings/rx directory"); + goto fail; + } + + file_d = debugfs_create_file("rx_str", 0400, edma_rx_dir_d, &nss_top_main, &nss_edma_rxring_strings_ops); + if (!file_d) { + nss_warning("Failed to create qca-nss-drv/strings/edma/rings/rx file"); + goto fail; + } + + /* + * edma tx cmpl ring stats + */ + edma_txcmpl_dir_d = debugfs_create_dir("txcmpl", edma_rings_dir_d); + if (!edma_txcmpl_dir_d) { + nss_warning("Failed to create qca-nss-drv/strings/edma/rings/txcmpl directory"); + goto fail; + } + + file_d = debugfs_create_file("txcmpl_str", 0400, edma_txcmpl_dir_d, &nss_top_main, &nss_edma_txcmplring_strings_ops); + if (!file_d) { + nss_warning("Failed to create qca-nss-drv/strings/edma/rings/txcmpl file"); + goto fail; + } + + /* + * edma rx fill ring stats + */ + edma_rxfill_dir_d = debugfs_create_dir("rxfill", edma_rings_dir_d); + if (!edma_rxfill_dir_d) { + nss_warning("Failed to create qca-nss-drv/strings/edma/rings/rxfill directory"); + goto fail; + } + + file_d = debugfs_create_file("rxfill_str", 0400, edma_rxfill_dir_d, &nss_top_main, &nss_edma_rxfillring_strings_ops); + if (!file_d) { + nss_warning("Failed to create qca-nss-drv/strings/edma/rings/rxfill file"); + goto fail; + } + + return; +fail: + debugfs_remove_recursive(edma_d); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_edma_strings.h b/feeds/ipq807x/qca-nss-drv/src/nss_edma_strings.h new file mode 100644 index 000000000..b211975ff --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_edma_strings.h @@ -0,0 +1,30 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_EDMA_STRINGS_H +#define __NSS_EDMA_STRINGS_H + +extern struct nss_stats_info nss_edma_strings_stats_node[NSS_STATS_NODE_MAX]; +extern struct nss_stats_info nss_edma_strings_stats_tx[NSS_EDMA_STATS_TX_MAX]; +extern struct nss_stats_info nss_edma_strings_stats_rx[NSS_EDMA_STATS_RX_MAX]; +extern struct nss_stats_info nss_edma_strings_stats_txcmpl[NSS_EDMA_STATS_TXCMPL_MAX]; +extern struct nss_stats_info nss_edma_strings_stats_rxfill[NSS_EDMA_STATS_RXFILL_MAX]; +extern struct nss_stats_info nss_edma_strings_stats_port_type[NSS_EDMA_PORT_TYPE_MAX]; +extern struct nss_stats_info nss_edma_strings_stats_port_ring_map[NSS_EDMA_PORT_RING_MAP_MAX]; +extern struct nss_stats_info nss_edma_strings_stats_err_map[NSS_EDMA_ERR_STATS_MAX]; +extern void nss_edma_strings_dentry_create(void); + +#endif /* __NSS_EDMA_STRINGS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_eth_rx.c b/feeds/ipq807x/qca-nss-drv/src/nss_eth_rx.c new file mode 100644 index 000000000..eba62afae --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_eth_rx.c @@ -0,0 +1,77 @@ +/* + ************************************************************************** + * Copyright (c) 2013-2017, 2019-2020 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_eth_rx.c + * NSS ETH_RX APIs + */ + +#include +#include "nss_eth_rx_stats.h" +#include "nss_eth_rx_strings.h" + +/* + ********************************** + Rx APIs + ********************************** + */ + +/* + * nss_eth_rx_interface_handler() + * Handle NSS -> HLOS messages for ETH_RX node + */ +static void nss_eth_rx_interface_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_eth_rx_msg *nem = (struct nss_eth_rx_msg *)ncm; + + /* + * Is this a valid request/response packet? + */ + if (nem->cm.type >= NSS_METADATA_TYPE_ETH_RX_MAX) { + nss_warning("%px: received invalid message %d for eth_rx interface", nss_ctx, nem->cm.type); + return; + } + + switch (nem->cm.type) { + case NSS_RX_METADATA_TYPE_ETH_RX_STATS_SYNC: + /* + * Update driver statistics and send stats notifications to the registered modules. + */ + nss_eth_rx_metadata_stats_sync(nss_ctx, &nem->msg.node_sync); + nss_eth_rx_stats_notify(nss_ctx); + break; + + default: + if (ncm->response != NSS_CMN_RESPONSE_ACK) { + /* + * Check response + */ + nss_info("%px: Received response %d for type %d, interface %d", + nss_ctx, ncm->response, ncm->type, ncm->interface); + } + } +} + +/* + * nss_eth_rx_register_handler() + */ +void nss_eth_rx_register_handler(struct nss_ctx_instance *nss_ctx) +{ + nss_core_register_handler(nss_ctx, NSS_ETH_RX_INTERFACE, nss_eth_rx_interface_handler, NULL); + + nss_eth_rx_stats_dentry_create(); + nss_eth_rx_strings_dentry_create(); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_eth_rx_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_eth_rx_stats.c new file mode 100644 index 000000000..cfc705773 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_eth_rx_stats.c @@ -0,0 +1,187 @@ +/* + ************************************************************************** + * Copyright (c) 2017, 2019-2020 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_eth_rx_stats.h" +#include "nss_eth_rx_strings.h" + +/* + * Declare atomic notifier data structure for statistics. + */ +ATOMIC_NOTIFIER_HEAD(nss_eth_rx_stats_notifier); + +uint64_t nss_eth_rx_stats[NSS_ETH_RX_STATS_MAX]; /* ETH_RX statistics */ +uint64_t nss_eth_rx_exception_stats[NSS_ETH_RX_EXCEPTION_EVENT_MAX]; /* Unknown protocol exception events per interface */ + +/* + * nss_eth_rx_stats_read() + * Read ETH_RX stats. + */ +static ssize_t nss_eth_rx_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i; + + /* + * Max output lines = #stats * NSS_MAX_CORES + + * few blank lines for banner printing + Number of Extra outputlines for future reference to add new stats + */ + uint32_t max_output_lines = NSS_STATS_NODE_MAX + NSS_ETH_RX_STATS_MAX + NSS_ETH_RX_EXCEPTION_EVENT_MAX + NSS_STATS_EXTRA_OUTPUT_LINES; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + /* + * Note: The assumption here is that we do not have more than 64 stats. + */ + stats_shadow = kzalloc(64 * 8, GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return 0; + } + + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "eth_rx", NSS_STATS_SINGLE_CORE); + + size_wr += nss_stats_fill_common_stats(NSS_ETH_RX_INTERFACE, NSS_STATS_SINGLE_INSTANCE, lbuf, size_wr, size_al, "eth_rx"); + + /* + * eth_rx node stats. + */ + spin_lock_bh(&nss_top_main.stats_lock); + for (i = 0; (i < NSS_ETH_RX_STATS_MAX); i++) { + stats_shadow[i] = nss_eth_rx_stats[i]; + } + + spin_unlock_bh(&nss_top_main.stats_lock); + + size_wr += nss_stats_print("eth_rx", "eth_rx node stats" + , NSS_STATS_SINGLE_INSTANCE + , nss_eth_rx_strings_stats + , stats_shadow + , NSS_ETH_RX_STATS_MAX + , lbuf, size_wr, size_al); + + /* + * Exception stats. + */ + spin_lock_bh(&nss_top_main.stats_lock); + for (i = 0; (i < NSS_ETH_RX_EXCEPTION_EVENT_MAX); i++) { + stats_shadow[i] = nss_eth_rx_exception_stats[i]; + } + + spin_unlock_bh(&nss_top_main.stats_lock); + + size_wr += nss_stats_print("eth_rx", "eth_rx exception stats" + , NSS_STATS_SINGLE_INSTANCE + , nss_eth_rx_strings_exception_stats + , stats_shadow + , NSS_ETH_RX_EXCEPTION_EVENT_MAX + , lbuf, size_wr, size_al); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * nss_eth_rx_stats_ops. + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(eth_rx); + +/* + * nss_eth_rx_stats_dentry_create() + * Create eth_rx statistics debug entry. + */ +void nss_eth_rx_stats_dentry_create(void) +{ + nss_stats_create_dentry("eth_rx", &nss_eth_rx_stats_ops); +} + +/* + * nss_eth_rx_metadata_stats_sync() + * Handle the syncing of ETH_RX node statistics. + */ +void nss_eth_rx_metadata_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_eth_rx_node_sync *nens) +{ + int32_t i; + struct nss_top_instance *nss_top = nss_ctx->nss_top; + + spin_lock_bh(&nss_top->stats_lock); + + nss_top->stats_node[NSS_ETH_RX_INTERFACE][NSS_STATS_NODE_RX_PKTS] += nens->node_stats.rx_packets; + nss_top->stats_node[NSS_ETH_RX_INTERFACE][NSS_STATS_NODE_RX_BYTES] += nens->node_stats.rx_bytes; + nss_top->stats_node[NSS_ETH_RX_INTERFACE][NSS_STATS_NODE_TX_PKTS] += nens->node_stats.tx_packets; + nss_top->stats_node[NSS_ETH_RX_INTERFACE][NSS_STATS_NODE_TX_BYTES] += nens->node_stats.tx_bytes; + + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + nss_top->stats_node[NSS_ETH_RX_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + i] += nens->node_stats.rx_dropped[i]; + } + + nss_eth_rx_stats[NSS_ETH_RX_STATS_TOTAL_TICKS] += nens->total_ticks; + nss_eth_rx_stats[NSS_ETH_RX_STATS_WORST_CASE_TICKS] += nens->worst_case_ticks; + nss_eth_rx_stats[NSS_ETH_RX_STATS_ITERATIONS] += nens->iterations; + + for (i = 0; i < NSS_ETH_RX_EXCEPTION_EVENT_MAX; i++) { + nss_eth_rx_exception_stats[i] += nens->exception_events[i]; + } + + spin_unlock_bh(&nss_top->stats_lock); +} + +/* + * nss_eth_rx_stats_notify() + * Sends notifications to the registered modules. + * + * Leverage NSS-FW statistics timing to update Netlink. + */ +void nss_eth_rx_stats_notify(struct nss_ctx_instance *nss_ctx) +{ + struct nss_eth_rx_stats_notification eth_rx_stats; + + eth_rx_stats.core_id = nss_ctx->id; + memcpy(eth_rx_stats.cmn_node_stats, nss_top_main.stats_node[NSS_ETH_RX_INTERFACE], sizeof(eth_rx_stats.cmn_node_stats)); + memcpy(eth_rx_stats.special_stats, nss_eth_rx_stats, sizeof(eth_rx_stats.special_stats)); + memcpy(eth_rx_stats.exception_stats, nss_eth_rx_exception_stats, sizeof(eth_rx_stats.exception_stats)); + atomic_notifier_call_chain(&nss_eth_rx_stats_notifier, NSS_STATS_EVENT_NOTIFY, (void *)ð_rx_stats); +} + +/* + * nss_eth_rx_stats_register_notifier() + * Registers statistics notifier. + */ +int nss_eth_rx_stats_register_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&nss_eth_rx_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_eth_rx_stats_register_notifier); + +/* + * nss_eth_rx_stats_unregister_notifier() + * Deregisters statistics notifier. + */ +int nss_eth_rx_stats_unregister_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&nss_eth_rx_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_eth_rx_stats_unregister_notifier); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_eth_rx_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_eth_rx_stats.h new file mode 100644 index 000000000..c5470ba9c --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_eth_rx_stats.h @@ -0,0 +1,65 @@ +/* + ************************************************************************** + * Copyright (c) 2017, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_ETH_RX_STATS_H +#define __NSS_ETH_RX_STATS_H + +#include + +/* + * nss_eth_rx_stats.h + * NSS driver ETH_RX statistics header file. + */ + +/* + * Request/Response types + */ +enum nss_eth_rx_metadata_types { + NSS_RX_METADATA_TYPE_ETH_RX_STATS_SYNC, + NSS_METADATA_TYPE_ETH_RX_MAX, +}; + +/* + * The NSS eth_rx node stats structure. + */ +struct nss_eth_rx_node_sync { + struct nss_cmn_node_stats node_stats; + /* Common node stats for ETH_RX */ + uint32_t total_ticks; /* Total clock ticks spend inside the eth_rx */ + uint32_t worst_case_ticks; /* Worst case iteration of the eth_rx in ticks */ + uint32_t iterations; /* Number of iterations around the eth_rx */ + uint32_t exception_events[NSS_ETH_RX_EXCEPTION_EVENT_MAX]; + /* Number of ETH_RX exception events */ +}; + +/* + * Message structure to send/receive eth_rx commands + */ +struct nss_eth_rx_msg { + struct nss_cmn_msg cm; /* Message Header */ + union { + struct nss_eth_rx_node_sync node_sync; /* Message: node statistics sync */ + } msg; +}; + +/* + * eth_rx statistics APIs + */ +extern void nss_eth_rx_stats_notify(struct nss_ctx_instance *nss_ctx); +extern void nss_eth_rx_metadata_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_eth_rx_node_sync *nens); +extern void nss_eth_rx_stats_dentry_create(void); + +#endif /* __NSS_ETH_RX_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_eth_rx_strings.c b/feeds/ipq807x/qca-nss-drv/src/nss_eth_rx_strings.c new file mode 100644 index 000000000..8412b444d --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_eth_rx_strings.c @@ -0,0 +1,106 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_stats.h" +#include "nss_core.h" +#include "nss_strings.h" + +/* + * nss_eth_rx_strings_stats + * Ethernet Rx statistics strings. + */ +struct nss_stats_info nss_eth_rx_strings_stats[NSS_ETH_RX_STATS_MAX] = { + {"ticks" , NSS_STATS_TYPE_SPECIAL}, + {"worst_ticks" , NSS_STATS_TYPE_SPECIAL}, + {"iterations" , NSS_STATS_TYPE_SPECIAL} +}; + +/* + * nss_eth_rx_strings_exception_stats + * Interface statistics strings for unknown exceptions. + */ +struct nss_stats_info nss_eth_rx_strings_exception_stats[NSS_ETH_RX_EXCEPTION_EVENT_MAX] = { + {"unknown_l3_protocol" , NSS_STATS_TYPE_EXCEPTION}, + {"eth_hdr_missing" , NSS_STATS_TYPE_EXCEPTION}, + {"vlan_missing" , NSS_STATS_TYPE_EXCEPTION}, + {"trustsec_hdr_missing" , NSS_STATS_TYPE_EXCEPTION} +}; + +/* + * nss_eth_rx_special_stats_strings_read() + * Read Ethernet Rx special node statistics names. + */ +static ssize_t nss_eth_rx_special_stats_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_eth_rx_strings_stats, NSS_ETH_RX_STATS_MAX); +} + +/* + * nss_eth_rx_exception_stats_strings_read() + * Read Ethernet Rx exception statistics names. + */ +static ssize_t nss_eth_rx_exception_stats_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_eth_rx_strings_exception_stats, NSS_ETH_RX_EXCEPTION_EVENT_MAX); +} + +/* + * nss_eth_rx_special_stats_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(eth_rx_special_stats); + +/* + * nss_eth_rx_exception_stats_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(eth_rx_exception_stats); + +/* + * nss_eth_rx_strings_dentry_create() + * Create Ethernet Rx statistics strings debug entry. + */ +void nss_eth_rx_strings_dentry_create(void) +{ + struct dentry *eth_rx_d = NULL; + struct dentry *eth_rx_spcl_stats_d = NULL; + struct dentry *eth_rx_excp_stats_d = NULL; + + if (!nss_top_main.strings_dentry) { + nss_warning("qca-nss-drv/strings is not present"); + return; + } + + eth_rx_d = debugfs_create_dir("eth_rx", nss_top_main.strings_dentry); + if (!eth_rx_d) { + nss_warning("Failed to create qca-nss-drv/strings/eth_rx directory"); + return; + } + + eth_rx_spcl_stats_d = debugfs_create_file("special_stats_str", 0400, eth_rx_d, &nss_top_main, &nss_eth_rx_special_stats_strings_ops); + if (!eth_rx_spcl_stats_d) { + nss_warning("Failed to create qca-nss-drv/stats/eth_rx/special_stats_str file"); + debugfs_remove_recursive(eth_rx_d); + return; + } + + eth_rx_excp_stats_d = debugfs_create_file("exception_stats_str", 0400, eth_rx_d, &nss_top_main, &nss_eth_rx_exception_stats_strings_ops); + if (!eth_rx_excp_stats_d) { + nss_warning("Failed to create qca-nss-drv/stats/eth_rx/exception_stats_str file"); + debugfs_remove_recursive(eth_rx_d); + return; + } +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_eth_rx_strings.h b/feeds/ipq807x/qca-nss-drv/src/nss_eth_rx_strings.h new file mode 100644 index 000000000..2f40440f3 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_eth_rx_strings.h @@ -0,0 +1,26 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_ETH_RX_STRINGS_H +#define __NSS_ETH_RX_STRINGS_H + +extern struct nss_stats_info nss_eth_rx_strings_stats[NSS_ETH_RX_STATS_MAX]; +extern struct nss_stats_info nss_eth_rx_strings_exception_stats[NSS_ETH_RX_EXCEPTION_EVENT_MAX]; +extern void nss_eth_rx_strings_dentry_create(void); + +#endif /* __NSS_ETH_RX_STRINGS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_freq.c b/feeds/ipq807x/qca-nss-drv/src/nss_freq.c new file mode 100644 index 000000000..d55bd63b6 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_freq.c @@ -0,0 +1,467 @@ +/* + ************************************************************************** + * Copyright (c) 2013, 2015-2020 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_freq.c + * NSS frequency change APIs + */ + +#include "nss_stats.h" +#include "nss_tx_rx_common.h" +#include "nss_freq_log.h" +#include "nss_freq_stats.h" + +#define NSS_ACK_STARTED 0 +#define NSS_ACK_FINISHED 1 + +#define NSS_FREQ_USG_AVG_FREQUENCY 1000 /* Time in ms over which CPU Usage is averaged */ +#define NSS_FREQ_CPU_USAGE_MAX_BOUND 75 /* MAX CPU usage equivalent to running max instructions excluding all the hazards */ +#define NSS_FREQ_CPU_USAGE_MAX 100 /* MAX CPU usage equivalent to running max instructions including all the hazards. + This is also the ideal maximum usage value. */ + +/* + * Spinlock to protect the global data structure nss_freq_cpu_status + */ +DEFINE_SPINLOCK(nss_freq_cpu_usage_lock); + +/* + * At any point, this object has the latest data about CPU utilization. + */ +struct nss_freq_cpu_usage nss_freq_cpu_status; + +extern struct nss_runtime_sampling nss_runtime_samples; +extern struct workqueue_struct *nss_wq; +extern nss_work_t *nss_work; + +/* + * nss_freq_msg_init() + * Initialize the freq message + */ +static void nss_freq_msg_init(struct nss_corefreq_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, + void *cb, void *app_data) +{ + nss_cmn_msg_init(&ncm->cm, if_num, type, len, cb, app_data); +} + +/* + * nss_freq_handle_ack() + * Handle the nss ack of frequency change. + */ +static void nss_freq_handle_ack(struct nss_ctx_instance *nss_ctx, struct nss_freq_msg *nfa) +{ + if (nfa->ack == NSS_ACK_STARTED) { + /* + * NSS finished start noficiation - HW change clocks and send end notification + */ + nss_info("%px: NSS ACK Received: %d - Change HW CLK/Send Finish to NSS\n", nss_ctx, nfa->ack); + + return; + } + + if (nfa->ack == NSS_ACK_FINISHED) { + /* + * NSS finished end notification - Done + */ + nss_info("%px: NSS ACK Received: %d - End Notification ACK - Running: %dmhz\n", nss_ctx, nfa->ack, nfa->freq_current); + nss_runtime_samples.freq_scale_ready = 1; + return; + } + + nss_info("%px: NSS had an error - Running: %dmhz\n", nss_ctx, nfa->freq_current); +} + +/* + * nss_freq_queue_work() + * Queue Work to the NSS Workqueue based on Current index. + */ +static bool nss_freq_queue_work(void) +{ + nss_freq_scales_t index = nss_runtime_samples.freq_scale_index; + + BUG_ON(!nss_wq); + + nss_info("frequency:%d index:%d sample count:%x\n", nss_runtime_samples.freq_scale[index].frequency, + index, nss_runtime_samples.average); + + /* + * schedule freq change with autoscale ON + */ + return nss_freq_sched_change(index, true); +} + +/* + * nss_freq_get_cpu_usage() + * Returns the CPU usage value in percentage at any instance for a required core. Returns -1 in case of an error. + * + * Calculation frequency is 1 second. Range of usage is 0-100. This API returns -1 if CPU usage is requested for core 1. + * TODO: Extend this API to get CPU usage for core 1. + */ +int8_t nss_freq_get_cpu_usage(uint32_t core_id) +{ + int8_t usage; + + if (core_id == 0) { + spin_lock_bh(&nss_freq_cpu_usage_lock); + usage = nss_freq_cpu_status.used; + spin_unlock_bh(&nss_freq_cpu_usage_lock); + + return usage; + } + + nss_warning("CPU usage functionality is not supported for core %u\n", core_id); + return -1; +} + +/* + * nss_freq_compute_cpu_usage() + * Computes the CPU utilization and maximum-minumun cpu utilization since boot. + */ +static void nss_freq_compute_cpu_usage(struct nss_ctx_instance *nss_ctx, uint32_t inst_cnt) +{ + uint32_t estimated_ins_capacity; + uint8_t actual_usage; + uint8_t usage; + + spin_lock_bh(&nss_freq_cpu_usage_lock); + + /* + * If actual CPU usage turns up higher than 100, there is something wrong with the received data. + * Upper bound average varies between 80% usage to 100% usage. + * + * TODO: To improve estimation algorithm for calculating how many actual instructions are executed. + */ + actual_usage = (inst_cnt * 100) / nss_freq_cpu_status.max_ins; + if ((actual_usage > NSS_FREQ_CPU_USAGE_MAX) || (actual_usage == 0)) { + spin_unlock_bh(&nss_freq_cpu_usage_lock); + return; + } + + /* + * Simpler version of below math: This is calculating the reduced number of maximum instructions + * estimated_ins_capacity = nss_freq_cpu_status.avg_up% of nss_freq_cpu_status.max_ins + * Calculating usage percentage: usage = (inst_cnt/estimated_ins_capacity) * 100 + */ + estimated_ins_capacity = ((NSS_FREQ_CPU_USAGE_MAX_BOUND * nss_freq_cpu_status.max_ins) / 100); + if (estimated_ins_capacity == 0) { + spin_unlock_bh(&nss_freq_cpu_usage_lock); + return; + } + usage = (inst_cnt * 100) / estimated_ins_capacity; + + /* + * Average the instructions over NSS_FREQ_USG_AVG_FREQUENCY ms + */ + if (nss_freq_cpu_status.avg_ctr == NSS_FREQ_USG_AVG_FREQUENCY) { + nss_freq_cpu_status.used = nss_freq_cpu_status.total / NSS_FREQ_USG_AVG_FREQUENCY; + + /* + * Due to our estimation, this could go beyond the end limit of 100% + */ + if (nss_freq_cpu_status.used > NSS_FREQ_CPU_USAGE_MAX) { + nss_freq_cpu_status.used = NSS_FREQ_CPU_USAGE_MAX; + } + + /* + * Getting the all time max and min usage + */ + if (nss_freq_cpu_status.used > nss_freq_cpu_status.max) { + nss_freq_cpu_status.max = nss_freq_cpu_status.used; + } + + if (nss_freq_cpu_status.used < nss_freq_cpu_status.min) { + nss_freq_cpu_status.min = nss_freq_cpu_status.used; + } + + nss_trace("%px: max_instructions:%d cpu_usage:%d max_usage:%d min_usage:%d\n", nss_ctx, + nss_freq_cpu_status.max_ins, nss_freq_cpu_status.used, nss_freq_cpu_status.max, nss_freq_cpu_status.min); + + nss_freq_cpu_status.total = 0; + nss_freq_cpu_status.avg_ctr = 0; + } + + nss_freq_cpu_status.total += usage; + nss_freq_cpu_status.avg_ctr++; + + spin_unlock_bh(&nss_freq_cpu_usage_lock); +} + +/* + * nss_freq_scale_frequency() + * Frequency scaling algorithm to scale frequency. + */ +void nss_freq_scale_frequency(struct nss_ctx_instance *nss_ctx, uint32_t inst_cnt) +{ + uint32_t b_index; + uint32_t minimum; + uint32_t maximum; + uint32_t index = nss_runtime_samples.freq_scale_index; + + /* + * We do not accept any statistics if auto scaling is off, + * we start with a fresh sample set when scaling is + * eventually turned on. + */ + if (!nss_cmd_buf.auto_scale && nss_runtime_samples.initialized) { + return; + } + + /* + * Delete Current Index Value, Add New Value, Recalculate new Sum, Shift Index + */ + b_index = nss_runtime_samples.buffer_index; + + nss_runtime_samples.sum = nss_runtime_samples.sum - nss_runtime_samples.buffer[b_index]; + nss_runtime_samples.buffer[b_index] = inst_cnt; + nss_runtime_samples.sum = nss_runtime_samples.sum + nss_runtime_samples.buffer[b_index]; + nss_runtime_samples.buffer_index = (b_index + 1) & NSS_SAMPLE_BUFFER_MASK; + + if (nss_runtime_samples.sample_count < NSS_SAMPLE_BUFFER_SIZE) { + nss_runtime_samples.sample_count++; + + /* + * Samples Are All Ready, Start Auto Scale + */ + if (nss_runtime_samples.sample_count == NSS_SAMPLE_BUFFER_SIZE ) { + nss_cmd_buf.auto_scale = 1; + nss_runtime_samples.freq_scale_ready = 1; + nss_runtime_samples.initialized = 1; + } + + return; + } + + nss_runtime_samples.average = nss_runtime_samples.sum / nss_runtime_samples.sample_count; + + /* + * Print out statistics every 10 samples + */ + if (nss_runtime_samples.message_rate_limit++ >= NSS_MESSAGE_RATE_LIMIT) { + nss_trace("%px: Running AVG:%x Sample:%x Divider:%d\n", nss_ctx, nss_runtime_samples.average, inst_cnt, nss_runtime_samples.sample_count); + nss_trace("%px: Current Frequency Index:%d\n", nss_ctx, index); + nss_trace("%px: Auto Scale Ready:%d Auto Scale:%d\n", nss_ctx, nss_runtime_samples.freq_scale_ready, nss_cmd_buf.auto_scale); + nss_trace("%px: Current Rate:%x\n", nss_ctx, nss_runtime_samples.average); + + nss_runtime_samples.message_rate_limit = 0; + } + + /* + * Don't scale if we are not ready or auto scale is disabled. + */ + if ((nss_runtime_samples.freq_scale_ready != 1) || (nss_cmd_buf.auto_scale != 1)) { + return; + } + + /* + * Scale Algorithmn + * Algorithmn will limit how fast it will transition each scale, by the number of samples seen. + * If any sample is out of scale during the idle count, the rate_limit will reset to 0. + * Scales are limited to the max number of cpu scales we support. + */ + if (nss_runtime_samples.freq_scale_rate_limit_up++ >= NSS_FREQUENCY_SCALE_RATE_LIMIT_UP) { + maximum = nss_runtime_samples.freq_scale[index].maximum; + if ((nss_runtime_samples.average > maximum) && (index < (NSS_FREQ_MAX_SCALE - 1))) { + nss_runtime_samples.freq_scale_index++; + nss_runtime_samples.freq_scale_ready = 0; + + /* + * If fail to increase frequency, decrease index + */ + nss_trace("frequency increase to %d inst:%x > maximum:%x\n", nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency, inst_cnt, maximum); + if (!nss_freq_queue_work()) { + nss_runtime_samples.freq_scale_index--; + } + } + + /* + * Reset the down scale counter based on running average, so can idle properly + */ + if (nss_runtime_samples.average > maximum) { + nss_trace("down scale timeout reset running average:%x\n", nss_runtime_samples.average); + nss_runtime_samples.freq_scale_rate_limit_down = 0; + } + + nss_runtime_samples.freq_scale_rate_limit_up = 0; + return; + } + + if (nss_runtime_samples.freq_scale_rate_limit_down++ >= NSS_FREQUENCY_SCALE_RATE_LIMIT_DOWN) { + minimum = nss_runtime_samples.freq_scale[index].minimum; + + /* + * Check if we need to lower the frequency. For some SoC like IPQ50xx, low frequency + * is not supported. So check if the next lower frequency is configured before shifting down + */ + if ((nss_runtime_samples.average < minimum) && (index > 0) && nss_runtime_samples.freq_scale[index - 1].maximum) { + nss_runtime_samples.freq_scale_index--; + nss_runtime_samples.freq_scale_ready = 0; + + /* + * If fail to decrease frequency, increase index + */ + nss_trace("frequency decrease to %d inst:%x < minumum:%x\n", nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency, nss_runtime_samples.average, minimum); + if (!nss_freq_queue_work()) { + nss_runtime_samples.freq_scale_index++; + } + } + nss_runtime_samples.freq_scale_rate_limit_down = 0; + return; + } +} + +/* + * nss_freq_handle_core_stats() + * Handle the core stats. + */ +static void nss_freq_handle_core_stats(struct nss_ctx_instance *nss_ctx, struct nss_core_stats *core_stats) +{ + uint32_t inst_cnt = core_stats->inst_cnt_total; + + /* + * compute CPU utilization by using the instruction count + */ + nss_freq_compute_cpu_usage(nss_ctx, inst_cnt); + + /* + * Perform frequency scaling + */ + nss_freq_scale_frequency(nss_ctx, inst_cnt); +} + +/* + * nss_freq_interface_handler() + * Handle NSS -> HLOS messages for Frequency Changes and Statistics. + */ +static void nss_freq_interface_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) { + + struct nss_corefreq_msg *ncfm = (struct nss_corefreq_msg *)ncm; + + /* + * Trace Messages + */ + nss_freq_log_rx_msg(ncfm); + + switch (ncfm->cm.type) { + case COREFREQ_METADATA_TYPE_TX_FREQ_ACK: + nss_freq_handle_ack(nss_ctx, &ncfm->msg.nfc); + break; + case COREFREQ_METADATA_TYPE_TX_CORE_STATS: + nss_freq_handle_core_stats(nss_ctx, &ncfm->msg.ncs); + break; + + default: + if (ncm->response != NSS_CMN_RESPONSE_ACK) { + /* + * Check response + */ + nss_info("%px: Received response %d for type %d, interface %d", nss_ctx, ncm->response, ncm->type, ncm->interface); + } + } +} + +/* + * nss_freq_change() + * NSS frequency change API. + */ +nss_tx_status_t nss_freq_change(struct nss_ctx_instance *nss_ctx, uint32_t eng, uint32_t stats_enable, uint32_t start_or_end) +{ + struct nss_corefreq_msg ncm; + struct nss_freq_msg *nfc; + + nss_info("%px: frequency changing to: %d\n", nss_ctx, eng); + + /* + * Update the max instruction count for a frequency during down scaling. + * Better to update this as late as possible in the frequency update call. + */ + spin_lock_bh(&nss_freq_cpu_usage_lock); + nss_freq_cpu_status.max_ins = eng / 1000; + spin_unlock_bh(&nss_freq_cpu_usage_lock); + + nss_freq_msg_init(&ncm, NSS_COREFREQ_INTERFACE, NSS_TX_METADATA_TYPE_NSS_FREQ_CHANGE, + sizeof(struct nss_freq_msg), NULL, NULL); + nfc = &ncm.msg.nfc; + nfc->frequency = eng; + nfc->start_or_end = start_or_end; + nfc->stats_enable = stats_enable; + + return nss_core_send_cmd(nss_ctx, &ncm, sizeof(ncm), NSS_NBUF_PAYLOAD_SIZE); +} + +/* + * nss_freq_sched_change() + * Schedule a frequency work. + */ +bool nss_freq_sched_change(nss_freq_scales_t index, bool auto_scale) +{ + if (index >= NSS_FREQ_MAX_SCALE) { + nss_info("NSS freq scale beyond limit\n"); + return false; + } + + nss_work = (nss_work_t *)kmalloc(sizeof(nss_work_t), GFP_ATOMIC); + if (!nss_work) { + nss_info("NSS Freq WQ kmalloc fail"); + return false; + } + + INIT_WORK((struct work_struct *)nss_work, nss_hal_wq_function); + + nss_work->frequency = nss_runtime_samples.freq_scale[index].frequency; + + nss_work->stats_enable = auto_scale; + nss_cmd_buf.current_freq = nss_work->frequency; + queue_work(nss_wq, (struct work_struct *)nss_work); + + return true; +} + +/* + * nss_freq_get_context() + * Get NSS context instance for frequency. + */ +struct nss_ctx_instance *nss_freq_get_context(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.frequency_handler_id]; +} +EXPORT_SYMBOL(nss_freq_get_context); + +/* + * nss_freq_register_handler() + */ +void nss_freq_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx = nss_freq_get_context(); + nss_core_register_handler(nss_ctx, NSS_COREFREQ_INTERFACE, nss_freq_interface_handler, NULL); +} + +/* + * nss_freq_cpu_usage_init() + * Initialize cpu usage computing. + * + * TODO: Add support to retrieve CPU usage even if frequency scaling is disabled. + */ +void nss_freq_init_cpu_usage(void) +{ + nss_freq_cpu_status.used = 0; + nss_freq_cpu_status.max_ins = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency / 1000; + nss_freq_cpu_status.total = 0; + nss_freq_cpu_status.max = 0; /* Initial value is 0 to capture the highest most value during the run */ + nss_freq_cpu_status.min = NSS_FREQ_CPU_USAGE_MAX; /* Initial value is 100 to capture the lowest most value during the run */ + nss_freq_cpu_status.avg_up = NSS_FREQ_CPU_USAGE_MAX_BOUND; + nss_freq_cpu_status.avg_ctr = 0; + + nss_freq_stats_dentry_create(); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_freq_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_freq_log.c new file mode 100644 index 000000000..9b96184cd --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_freq_log.c @@ -0,0 +1,100 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_freq_log.c + * NSS Freq logger file. + */ + +#include "nss_core.h" + +/* + * nss_freq_log_message_types_str + * Freq message strings + */ +static int8_t *nss_freq_log_message_types_str[COREFREQ_METADATA_TYPE_MAX] __maybe_unused = { + "Freq Error Message", + "Freq Change", + "Freq ACK", + "TX Core Stats", +}; + +/* + * nss_freq_log_msg() + * Log NSS Freq message. + */ +static void nss_freq_log_msg(struct nss_corefreq_msg *ncm) +{ + struct nss_freq_msg *nfm __maybe_unused = &ncm->msg.nfc; + nss_trace("%px: NSS Freq Message:\n" + "Frequency request: %d\n" + "Frequency start/end: %d\n" + "Frequency stats enable: %d\n" + "Current Frequency: %d\n" + "Frequency ACK: %d\n", + nfm, nfm->frequency, nfm->start_or_end, + nfm->stats_enable, nfm->freq_current, + nfm->ack); +} + +/* + * nss_freq_log_verbose() + * Log message contents. + */ +static void nss_freq_log_verbose(struct nss_corefreq_msg *ncm) +{ + switch (ncm->cm.type) { + case COREFREQ_METADATA_TYPE_RX_FREQ_CHANGE: + case COREFREQ_METADATA_TYPE_TX_FREQ_ACK: + nss_freq_log_msg(ncm); + break; + + case COREFREQ_METADATA_TYPE_TX_CORE_STATS: + /* + * No log for a valid stats message. + */ + break; + + default: + nss_warning("%px: Invalid message type\n", ncm); + break; + } +} + +/* + * nss_freq_log_rx_msg() + * Log messages received from FW. + */ +void nss_freq_log_rx_msg(struct nss_corefreq_msg *ncm) +{ + if (ncm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", ncm); + return; + } + + if (ncm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ncm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d], response[%d]:%s\n", ncm, ncm->cm.type, + ncm->cm.response, nss_cmn_response_str[ncm->cm.response]); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s\n", + ncm, ncm->cm.type, nss_freq_log_message_types_str[ncm->cm.type], + ncm->cm.response, nss_cmn_response_str[ncm->cm.response]); + +verbose: + nss_freq_log_verbose(ncm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_freq_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_freq_log.h new file mode 100644 index 000000000..ab7d7d4f6 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_freq_log.h @@ -0,0 +1,35 @@ +/* + ************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_FREQ_LOG_H +#define __NSS_FREQ_LOG_H + +/* + * nss_freq_log.h + * NSS frequency log header file. + */ + +/* + * Logger APIs + */ + +/* + * nss_freq_log_rx_msg + * Logs a frequency message that is received from the NSS firmware. + */ +void nss_freq_log_rx_msg(struct nss_corefreq_msg *nbm); + +#endif /* __NSS_FREQ_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_freq_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_freq_stats.c new file mode 100644 index 000000000..32e62c3c6 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_freq_stats.c @@ -0,0 +1,86 @@ +/* + ************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_freq_stats.c + * NSS Frequency statistics APIs. + */ + +#include "nss_stats.h" +#include "nss_tx_rx_common.h" + +/* + * At any point, this object has the latest data about CPU utilization. + */ +extern struct nss_freq_cpu_usage nss_freq_cpu_status; + +/* + * Spinlock to protect the global data structure nss_freq_cpu_status + */ +extern spinlock_t nss_freq_cpu_usage_lock; + +/* + * nss_freq_stats_read() + * Read frequency stats and display CPU information. + */ +static ssize_t nss_freq_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + /* + * max output lines = Should change in case of number of lines below. + */ + uint32_t max_output_lines = (2 + 3) + 5; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint32_t avg, max, min; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(!lbuf)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + size_wr = scnprintf(lbuf, size_al, "CPU Utilization:\n"); + + spin_lock_bh(&nss_freq_cpu_usage_lock); + avg = nss_freq_cpu_status.used; + max = nss_freq_cpu_status.max; + min = nss_freq_cpu_status.min; + spin_unlock_bh(&nss_freq_cpu_usage_lock); + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "Note: Averaged over 1 second\n\n"); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "Core 0:\n"); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "Min\tAvg\tMax\n"); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, " %u%%\t %u%%\t %u%%\n\n", min, avg, max); + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + + return bytes_read; +} + +/* + * nss_freq_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(freq) + +/* + * nss_freq_dentry_create() + */ +void nss_freq_stats_dentry_create(void) +{ + nss_stats_create_dentry("cpu_load_ubi", &nss_freq_stats_ops); +} \ No newline at end of file diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_freq_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_freq_stats.h new file mode 100644 index 000000000..72e00cc86 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_freq_stats.h @@ -0,0 +1,29 @@ +/* + ****************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +/* + * nss_freq_stats.h + * NSS Frequency statistics header file. + */ + +#ifndef __NSS_FREQ_STATS_H +#define __NSS_FREQ_STATS_H + +#include "nss_core.h" + +extern void nss_freq_stats_dentry_create(void); + +#endif /* __NSS_FREQ_STATS_H */ \ No newline at end of file diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gmac_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_gmac_stats.c new file mode 100644 index 000000000..23f5924e2 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gmac_stats.c @@ -0,0 +1,83 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2017, 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_gmac_stats.h" + +/* + * nss_gmac_stats_str + * GMAC stats strings. + */ +struct nss_stats_info nss_gmac_stats_str[NSS_GMAC_STATS_MAX] = { + {"ticks" , NSS_STATS_TYPE_SPECIAL}, + {"worst_ticks" , NSS_STATS_TYPE_SPECIAL}, + {"iterations" , NSS_STATS_TYPE_SPECIAL} +}; + +/* + * nss_gmac_stats_read() + * Read GMAC stats. + */ +ssize_t nss_gmac_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + uint32_t i, id; + + /* + * max output lines = ((#stats + start tag + one blank) * #GMACs) Number of Extra outputlines for future + * reference to add new stats + start/end tag + 3 blank + */ + uint32_t max_output_lines = NSS_GMAC_STATS_MAX * NSS_MAX_PHYSICAL_INTERFACES + NSS_STATS_EXTRA_OUTPUT_LINES; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + stats_shadow = kzalloc(NSS_GMAC_STATS_MAX * 8, GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return 0; + } + + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "gmac", NSS_STATS_SINGLE_CORE); + + for (id = 0; id < NSS_MAX_PHYSICAL_INTERFACES; id++) { + spin_lock_bh(&nss_top_main.stats_lock); + for (i = 0; (i < NSS_GMAC_STATS_MAX); i++) { + stats_shadow[i] = nss_top_main.stats_gmac[id][i]; + } + + spin_unlock_bh(&nss_top_main.stats_lock); + size_wr += nss_stats_print("gmac", "gmac stats", id + , nss_gmac_stats_str + , stats_shadow + , NSS_GMAC_STATS_MAX + , lbuf, size_wr, size_al); + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ngmac stats end\n\n"); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gmac_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_gmac_stats.h new file mode 100644 index 000000000..646143ed0 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gmac_stats.h @@ -0,0 +1,33 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2017, 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_GMAC_STATS_H +#define __NSS_GMAC_STATS_H + +#include + +/* + * GMAC node statistics + */ +enum nss_stats_gmac { + NSS_GMAC_STATS_TOTAL_TICKS, /* Total clock ticks spend inside the GMAC */ + NSS_GMAC_STATS_WORST_CASE_TICKS, /* Worst case iteration of the GMAC in ticks */ + NSS_GMAC_STATS_ITERATIONS, /* Number of iterations around the GMAC */ + NSS_GMAC_STATS_MAX, +}; + +extern ssize_t nss_gmac_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos); +#endif /* __NSS_GMAC_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre.c b/feeds/ipq807x/qca-nss-drv/src/nss_gre.c new file mode 100644 index 000000000..0ab55c29f --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre.c @@ -0,0 +1,407 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_gre_stats.h" +#include "nss_gre_log.h" + +#define NSS_GRE_TX_TIMEOUT 3000 /* 3 Seconds */ + +/* + * Private data structure + */ +static struct { + struct semaphore sem; + struct completion complete; + int response; + void *cb; + void *app_data; +} nss_gre_pvt; + +/* + * TODO: Register separate callbacks for inner and outer GRE nodes. + */ +static atomic64_t pkt_cb_addr = ATOMIC64_INIT(0); + +/* + * nss_gre_inner_rx_handler() + * GRE inner rx handler. + */ +static void nss_gre_inner_rx_handler(struct net_device *dev, struct sk_buff *skb, + __attribute__((unused)) struct napi_struct *napi) +{ + nss_gre_data_callback_t cb; + + nss_gre_pkt_callback_t scb = (nss_gre_pkt_callback_t)(unsigned long)atomic64_read(&pkt_cb_addr); + if (unlikely(scb)) { + struct nss_gre_info *info = (struct nss_gre_info *)netdev_priv(dev); + if (likely(info->next_dev_inner)) { + scb(info->next_dev_inner, skb); + } + } + + cb = nss_top_main.gre_inner_data_callback; + cb(dev, skb, 0); +} + +/* + * nss_gre_outer_rx_handler() + * GRE outer rx handler. + */ +static void nss_gre_outer_rx_handler(struct net_device *dev, struct sk_buff *skb, + __attribute__((unused)) struct napi_struct *napi) +{ + nss_gre_data_callback_t cb; + + nss_gre_pkt_callback_t scb = (nss_gre_pkt_callback_t)(unsigned long)atomic64_read(&pkt_cb_addr); + if (unlikely(scb)) { + struct nss_gre_info *info = (struct nss_gre_info *)netdev_priv(dev); + if (likely(info->next_dev_outer)) { + scb(info->next_dev_outer, skb); + } + } + + cb = nss_top_main.gre_outer_data_callback; + cb(dev, skb, 0); +} + +/* + * nss_gre_msg_handler() + * Handle NSS -> HLOS messages for GRE + */ +static void nss_gre_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_gre_msg *ntm = (struct nss_gre_msg *)ncm; + void *ctx; + + nss_gre_msg_callback_t cb; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + BUG_ON(!(nss_is_dynamic_interface(ncm->interface) || ncm->interface == NSS_GRE_INTERFACE)); + + /* + * Trace Messages + */ + nss_gre_log_rx_msg(ntm); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_GRE_MSG_MAX) { + nss_warning("%px: received invalid message %d for GRE STD interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_gre_msg)) { + nss_warning("%px: tx request for another interface: %d", nss_ctx, ncm->interface); + return; + } + + switch (ntm->cm.type) { + case NSS_GRE_MSG_SESSION_STATS: + /* + * debug stats embedded in stats msg + */ + nss_gre_stats_session_debug_sync(nss_ctx, &ntm->msg.sstats, ncm->interface); + break; + + case NSS_GRE_MSG_BASE_STATS: + nss_gre_stats_base_debug_sync(nss_ctx, &ntm->msg.bstats); + break; + + default: + break; + + } + + /* + * Update the callback and app_data for NOTIFY messages, gre sends all notify messages + * to the same callback/app_data. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_ctx->nss_top->gre_msg_callback; + ncm->app_data = (nss_ptr_t)nss_ctx->subsys_dp_register[ncm->interface].app_data; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * callback + */ + cb = (nss_gre_msg_callback_t)ncm->cb; + ctx = (void *)ncm->app_data; + + /* + * call gre-std callback + */ + if (!cb) { + nss_warning("%px: No callback for gre-std interface %d", + nss_ctx, ncm->interface); + return; + } + + cb(ctx, ntm); +} + +/* + * nss_gre_callback() + * Callback to handle the completion of HLOS-->NSS messages. + */ +static void nss_gre_callback(void *app_data, struct nss_gre_msg *nim) +{ + nss_gre_msg_callback_t callback = (nss_gre_msg_callback_t)nss_gre_pvt.cb; + void *data = nss_gre_pvt.app_data; + + nss_gre_pvt.cb = NULL; + nss_gre_pvt.app_data = NULL; + + if (nim->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("gre Error response %d\n", nim->cm.response); + nss_gre_pvt.response = NSS_TX_FAILURE; + } else { + nss_gre_pvt.response = NSS_TX_SUCCESS; + } + + if (callback) { + callback(data, nim); + } + + complete(&nss_gre_pvt.complete); +} + +/* + * nss_gre_register_pkt_callback() + * Register for data callback. + */ +void nss_gre_register_pkt_callback(nss_gre_pkt_callback_t cb) +{ + atomic64_set(&pkt_cb_addr, (unsigned long)cb); +} +EXPORT_SYMBOL(nss_gre_register_pkt_callback); + +/* + * nss_gre_unregister_pkt_callback() + * Unregister for data callback. + */ +void nss_gre_unregister_pkt_callback() +{ + atomic64_set(&pkt_cb_addr, 0); +} +EXPORT_SYMBOL(nss_gre_unregister_pkt_callback); + +/* + * nss_gre_tx_msg() + * Transmit a GRE message to NSS firmware + */ +nss_tx_status_t nss_gre_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_gre_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Sanity check the message + */ + if (!nss_is_dynamic_interface(ncm->interface)) { + nss_warning("%px: tx request for non dynamic interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type > NSS_GRE_MSG_MAX) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + /* + * Trace Messages + */ + nss_gre_log_tx_msg(msg); + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_gre_tx_msg); + +/* + * nss_gre_tx_msg_sync() + * Transmit a GRE message to NSS firmware synchronously. + */ +nss_tx_status_t nss_gre_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_msg *msg) +{ + nss_tx_status_t status; + int ret = 0; + + down(&nss_gre_pvt.sem); + nss_gre_pvt.cb = (void *)msg->cm.cb; + nss_gre_pvt.app_data = (void *)msg->cm.app_data; + + msg->cm.cb = (nss_ptr_t)nss_gre_callback; + msg->cm.app_data = (nss_ptr_t)NULL; + + status = nss_gre_tx_msg(nss_ctx, msg); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: gre_tx_msg failed\n", nss_ctx); + up(&nss_gre_pvt.sem); + return status; + } + ret = wait_for_completion_timeout(&nss_gre_pvt.complete, msecs_to_jiffies(NSS_GRE_TX_TIMEOUT)); + + if (!ret) { + nss_warning("%px: GRE STD tx sync failed due to timeout\n", nss_ctx); + nss_gre_pvt.response = NSS_TX_FAILURE; + } + + status = nss_gre_pvt.response; + up(&nss_gre_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_gre_tx_msg_sync); + +/* + * nss_gre_tx_buf() + * Send packet to GRE interface owned by NSS + */ +nss_tx_status_t nss_gre_tx_buf(struct nss_ctx_instance *nss_ctx, uint32_t if_num, struct sk_buff *skb) +{ + return nss_core_send_packet(nss_ctx, skb, if_num, H2N_BIT_FLAG_VIRTUAL_BUFFER | H2N_BIT_FLAG_BUFFER_REUSABLE); +} +EXPORT_SYMBOL(nss_gre_tx_buf); + +/* + *********************************** + * Register/Unregister/Miscellaneous APIs + *********************************** + */ + +/* + * nss_gre_register_if() + * Register data and message handlers for GRE. + */ +struct nss_ctx_instance *nss_gre_register_if(uint32_t if_num, uint32_t type, nss_gre_data_callback_t data_callback, + nss_gre_msg_callback_t event_callback, struct net_device *netdev, uint32_t features) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.gre_handler_id]; + + nss_assert(nss_ctx); + nss_assert(nss_is_dynamic_interface(if_num)); + + switch (type) { + case NSS_DYNAMIC_INTERFACE_TYPE_GRE_INNER: + nss_core_register_subsys_dp(nss_ctx, if_num, nss_gre_inner_rx_handler, NULL, netdev, netdev, features); + nss_top_main.gre_inner_data_callback = data_callback; + break; + + case NSS_DYNAMIC_INTERFACE_TYPE_GRE_OUTER: + nss_core_register_subsys_dp(nss_ctx, if_num, nss_gre_outer_rx_handler, NULL, netdev, netdev, features); + nss_top_main.gre_outer_data_callback = data_callback; + break; + + default: + nss_warning("%px: Unable to register. Wrong interface type %d\n", nss_ctx, type); + return NULL; + } + + nss_core_set_subsys_dp_type(nss_ctx, netdev, if_num, type); + + nss_top_main.gre_msg_callback = event_callback; + + nss_core_register_handler(nss_ctx, if_num, nss_gre_msg_handler, NULL); + + nss_gre_stats_session_register(if_num, netdev); + + return nss_ctx; +} +EXPORT_SYMBOL(nss_gre_register_if); + +/* + * nss_gre_unregister_if() + * Unregister data and message handler. + */ +void nss_gre_unregister_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.gre_handler_id]; + struct net_device *dev; + + nss_assert(nss_ctx); + nss_assert(nss_is_dynamic_interface(if_num)); + + dev = nss_cmn_get_interface_dev(nss_ctx, if_num); + if (!dev) { + nss_warning("%px: Unable to find net device for the interface %d\n", nss_ctx, if_num); + return; + } + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + nss_core_set_subsys_dp_type(nss_ctx, dev, if_num, NSS_DYNAMIC_INTERFACE_TYPE_NONE); + nss_top_main.gre_msg_callback = NULL; + + nss_core_unregister_handler(nss_ctx, if_num); + + nss_gre_stats_session_unregister(if_num); +} +EXPORT_SYMBOL(nss_gre_unregister_if); + +/* + * nss_get_gre_context() + */ +struct nss_ctx_instance *nss_gre_get_context(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.gre_handler_id]; +} +EXPORT_SYMBOL(nss_gre_get_context); + +/* + * nss_gre_ifnum_with_core_id() + * Append core id to GRE interface num. + */ +int nss_gre_ifnum_with_core_id(int if_num) +{ + struct nss_ctx_instance *nss_ctx = nss_gre_get_context(); + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + if (!nss_is_dynamic_interface(if_num)) { + nss_warning("%px: Invalid if_num: %d, must be a dynamic interface\n", nss_ctx, if_num); + return 0; + } + + return NSS_INTERFACE_NUM_APPEND_COREID(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_gre_ifnum_with_core_id); + +/* + * nss_gre_msg_init() + * Initialize nss_gre msg. + */ +void nss_gre_msg_init(struct nss_gre_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data) +{ + nss_cmn_msg_init(&ncm->cm, if_num, type, len, cb, app_data); +} +EXPORT_SYMBOL(nss_gre_msg_init); + +/* + * nss_gre_register_handler() + * debugfs stats msg handler received on static gre interface + */ +void nss_gre_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx = nss_gre_get_context(); + + nss_info("nss_gre_register_handler"); + sema_init(&nss_gre_pvt.sem, 1); + init_completion(&nss_gre_pvt.complete); + nss_core_register_handler(nss_ctx, NSS_GRE_INTERFACE, nss_gre_msg_handler, NULL); + nss_gre_stats_dentry_create(); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_gre_log.c new file mode 100644 index 000000000..c2f752ba5 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_log.c @@ -0,0 +1,187 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_gre_log.c + * NSS GRE logger file. + */ + +#include "nss_core.h" + +#define NSS_GRE_LOG_MESSAGE_TYPE_INDEX(type) ((type) - NSS_IF_MAX_MSG_TYPES - 1) + +/* + * nss_gre_log_message_types_str + * NSS GRE message strings + */ +static int8_t *nss_gre_log_message_types_str[NSS_GRE_MSG_MAX] __maybe_unused = { + "GRE Message Configure", + "GRE Message Deconfigure", + "GRE Session Stats", + "GRE Base Stats" +}; + +/* + * nss_gre_log_config_msg() + * Log NSS GRE Config message. + */ +static void nss_gre_log_config_msg(struct nss_gre_msg *ngm) +{ + struct nss_gre_config_msg *ngcm __maybe_unused = &ngm->msg.cmsg; + nss_trace("%px: NSS GRE Config message\n" + "GRE flags: %d\n" + "GRE ikey: %d\n" + "GRE okey: %d\n" + "GRE mode: %d\n" + "GRE ip type: %d\n" + "GRE interface number: %d\n" + "GRE Src MAC: %pM\n" + "GRE Dst MAC: %pM\n" + "GRE ttl: %d\n" + "GRE tos: %d\n" + "GRE metadata size: %d\n", + ngcm, ngcm->flags, ngcm->ikey, ngcm->okey, + ngcm->mode, ngcm->ip_type, ngcm->next_node_if_num, + ngcm->src_mac, ngcm->dest_mac, ngcm->ttl, ngcm->tos, + ngcm->metadata_size); + /* + * Continuation of the log message. Different identifiers based on IP type. + */ + if (ngcm->ip_type == NSS_GRE_IP_IPV6) { + nss_trace("GRE Source IP: %pI6\n" + "GRE Dest IP: %pI6\n", + ngcm->src_ip, ngcm->dest_ip); + } else { + nss_trace("GRE Source IP: %pI4\n" + "GRE Dest IP: %pI4\n", + ngcm->src_ip, ngcm->dest_ip); + } +} + +/* + * nss_gre_log_deconfig_msg() + * Log NSS GRE deconfig message. + */ +static void nss_gre_log_deconfig_msg(struct nss_gre_msg *ngm) +{ + struct nss_gre_deconfig_msg *ngdm __maybe_unused = &ngm->msg.dmsg; + nss_trace("%px: NSS GRE deconfig message\n" + "GRE interface number: %d\n", + ngdm, ngdm->if_number); +} + +/* + * nss_gre_log_linkup_msg() + * Log NSS GRE linkup message. + */ +static void nss_gre_log_linkup_msg(struct nss_gre_msg *ngm) +{ + struct nss_gre_linkup_msg *nglm __maybe_unused = &ngm->msg.linkup; + nss_trace("%px: NSS GRE linkup message\n" + "GRE interface number: %d\n", + nglm, nglm->if_number); +} + +/* + * nss_gre_log_linkdown_msg() + * Log NSS GRE linkdown message. + */ +static void nss_gre_log_linkdown_msg(struct nss_gre_msg *ngm) +{ + struct nss_gre_linkdown_msg *ngdm __maybe_unused = &ngm->msg.linkdown; + nss_trace("%px: NSS GRE linkdown message\n" + "GRE interface number: %d\n", + ngdm, ngdm->if_number); +} + +/* + * nss_gre_log_verbose() + * Log message contents. + */ +static void nss_gre_log_verbose(struct nss_gre_msg *ngm) +{ + switch (ngm->cm.type) { + case NSS_GRE_MSG_ENCAP_CONFIGURE: + case NSS_GRE_MSG_DECAP_CONFIGURE: + nss_gre_log_config_msg(ngm); + break; + + case NSS_GRE_MSG_ENCAP_DECONFIGURE: + case NSS_GRE_MSG_DECAP_DECONFIGURE: + nss_gre_log_deconfig_msg(ngm); + break; + + case NSS_IF_OPEN: + nss_gre_log_linkup_msg(ngm); + break; + + case NSS_IF_CLOSE: + nss_gre_log_linkdown_msg(ngm); + break; + + case NSS_GRE_MSG_SESSION_STATS: + case NSS_GRE_MSG_BASE_STATS: + /* + * No log for valid stats messages. + */ + break; + + default: + nss_trace("%px: Invalid message type\n", ngm); + break; + } +} + +/* + * nss_gre_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_gre_log_tx_msg(struct nss_gre_msg *ngm) +{ + if (ngm->cm.type >= NSS_GRE_MSG_MAX) { + nss_warning("%px: Invalid message type\n", ngm); + return; + } + + nss_info("%px: type[%d]:%s\n", ngm, ngm->cm.type, nss_gre_log_message_types_str[NSS_GRE_LOG_MESSAGE_TYPE_INDEX(ngm->cm.type)]); + nss_gre_log_verbose(ngm); +} + +/* + * nss_gre_log_rx_msg() + * Log messages received from FW. + */ +void nss_gre_log_rx_msg(struct nss_gre_msg *ngm) +{ + if (ngm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", ngm); + return; + } + + if (ngm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ngm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", ngm, ngm->cm.type, + nss_gre_log_message_types_str[NSS_GRE_LOG_MESSAGE_TYPE_INDEX(ngm->cm.type)], + ngm->cm.response, nss_cmn_response_str[ngm->cm.response]); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s\n", + ngm, ngm->cm.type, nss_gre_log_message_types_str[NSS_GRE_LOG_MESSAGE_TYPE_INDEX(ngm->cm.type)], + ngm->cm.response, nss_cmn_response_str[ngm->cm.response]); + +verbose: + nss_gre_log_verbose(ngm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_gre_log.h new file mode 100644 index 000000000..2a2111785 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_log.h @@ -0,0 +1,41 @@ +/* + ************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_GRE_LOG_H +#define __NSS_GRE_LOG_H + +/* + * nss_gre_log.h + * NSS GRE header file. + */ + +/* + * Logger APIs + */ + +/* + * nss_gre_log_tx_msg + * Logs a gre message that is sent to the NSS firmware. + */ +void nss_gre_log_tx_msg(struct nss_gre_msg *ngm); + +/* + * nss_gre_log_rx_msg + * Logs a gre message that is received from the NSS firmware. + */ +void nss_gre_log_rx_msg(struct nss_gre_msg *ngm); + +#endif /* __NSS_GRE_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir.c b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir.c new file mode 100644 index 000000000..20bb69645 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir.c @@ -0,0 +1,778 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_gre_redir_stats.h" +#include "nss_gre_redir_log.h" +#define NSS_GRE_REDIR_TX_TIMEOUT 3000 /* 3 Seconds */ + +static struct dentry *gre_redir_dentry; + +/* + * Private data structure for handling synchronous messaging. + */ +static struct { + struct semaphore sem; + struct completion complete; + int response; +} nss_gre_redir_pvt; + +/* + * Spinlock to update tunnel stats. + */ +static DEFINE_SPINLOCK(nss_gre_redir_stats_lock); + +/* + * Array to hold tunnel stats along with if_num + */ +static struct nss_gre_redir_tunnel_stats tun_stats[NSS_GRE_REDIR_MAX_INTERFACES]; + +/* + * nss_gre_callback() + * Callback to handle the completion of HLOS-->NSS messages. + */ +static void nss_gre_redir_msg_sync_callback(void *app_data, struct nss_gre_redir_msg *nim) +{ + nss_gre_redir_pvt.response = NSS_TX_SUCCESS; + if (nim->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("gre Error response %d\n", nim->cm.response); + nss_gre_redir_pvt.response = NSS_TX_FAILURE; + } + + complete(&nss_gre_redir_pvt.complete); +} + +/* + * nss_gre_redir_verify_ifnum() + * Verify interface type. + */ +static bool nss_gre_redir_verify_ifnum(uint32_t if_num) +{ + uint32_t type; + + type = nss_dynamic_interface_get_type(nss_gre_redir_get_context(), if_num); + return type == NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_WIFI_HOST_INNER || + type == NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_WIFI_OFFL_INNER || + type == NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_SJACK_INNER || + type == NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_OUTER || + type == NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_EXCEPTION_US || + type == NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_EXCEPTION_DS; +} + +/* + * nss_gre_redir_tunnel_update_stats() + * Update gre_redir tunnel stats. + */ +static void nss_gre_redir_tunnel_update_stats(struct nss_ctx_instance *nss_ctx, int if_num, struct nss_gre_redir_stats_sync_msg *ngss) +{ + int i, j; + uint32_t type; + struct net_device *dev; + + type = nss_dynamic_interface_get_type(nss_ctx, if_num); + dev = nss_cmn_get_interface_dev(nss_ctx, if_num); + if (!dev) { + nss_warning("%px: Unable to find net device for the interface %d\n", nss_ctx, if_num); + return; + } + + if (!nss_gre_redir_verify_ifnum(if_num)) { + nss_warning("%px: Unknown type for interface %d\n", nss_ctx, if_num); + return; + } + + spin_lock_bh(&nss_gre_redir_stats_lock); + for (i = 0; i < NSS_GRE_REDIR_MAX_INTERFACES; i++) { + if (tun_stats[i].dev == dev) { + break; + } + } + + if (i == NSS_GRE_REDIR_MAX_INTERFACES) { + nss_warning("%px: Unable to find tunnel stats instance for interface %d\n", nss_ctx, if_num); + return; + } + + nss_assert(tun_stats[i].ref_count); + switch (type) { + case NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_WIFI_HOST_INNER: + case NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_WIFI_OFFL_INNER: + case NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_SJACK_INNER: + tun_stats[i].node_stats.tx_packets += ngss->node_stats.tx_packets; + tun_stats[i].node_stats.tx_bytes += ngss->node_stats.tx_bytes; + tun_stats[i].sjack_tx_packets += ngss->sjack_rx_packets; + tun_stats[i].encap_sg_alloc_drop += ngss->encap_sg_alloc_drop; + tun_stats[i].tx_dropped += nss_cmn_rx_dropped_sum(&(ngss->node_stats)); + for (j = 0; j < NSS_GRE_REDIR_MAX_RADIO; j++) { + tun_stats[i].offl_tx_pkts[j] += ngss->offl_rx_pkts[j]; + } + + break; + + case NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_OUTER: + tun_stats[i].node_stats.rx_packets += ngss->node_stats.rx_packets; + tun_stats[i].node_stats.rx_bytes += ngss->node_stats.rx_bytes; + tun_stats[i].sjack_rx_packets += ngss->sjack_rx_packets; + tun_stats[i].decap_fail_drop += ngss->decap_fail_drop; + tun_stats[i].decap_split_drop += ngss->decap_split_drop; + tun_stats[i].split_sg_alloc_fail += ngss->split_sg_alloc_fail; + tun_stats[i].split_linear_copy_fail += ngss->split_linear_copy_fail; + tun_stats[i].split_not_enough_tailroom += ngss->split_not_enough_tailroom; + tun_stats[i].decap_eapol_frames += ngss->decap_eapol_frames; + tun_stats[i].node_stats.rx_dropped[0] += nss_cmn_rx_dropped_sum(&(ngss->node_stats)); + for (j = 0; j < NSS_GRE_REDIR_MAX_RADIO; j++) { + tun_stats[i].offl_rx_pkts[j] += ngss->offl_rx_pkts[j]; + } + + break; + + case NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_EXCEPTION_US: + tun_stats[i].exception_us_rx += ngss->node_stats.rx_packets; + tun_stats[i].exception_us_tx += ngss->node_stats.tx_packets; + break; + + case NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_EXCEPTION_DS: + tun_stats[i].exception_ds_rx += ngss->node_stats.rx_packets; + tun_stats[i].exception_ds_tx += ngss->node_stats.tx_packets; + tun_stats[i].exception_ds_invalid_dst_drop += ngss->exception_ds_invalid_dst_drop; + tun_stats[i].exception_ds_inv_appid += ngss->exception_ds_inv_appid; + tun_stats[i].headroom_unavail += ngss->headroom_unavail; + tun_stats[i].tx_completion_success += ngss->tx_completion_success; + tun_stats[i].tx_completion_drop += ngss->tx_completion_drop; + break; + } + + spin_unlock_bh(&nss_gre_redir_stats_lock); +} + +/* + * nss_gre_redir_handler() + * Handle NSS -> HLOS messages for GRE tunnel. + */ +static void nss_gre_redir_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_gre_redir_msg *ngrm = (struct nss_gre_redir_msg *)ncm; + void *ctx; + nss_gre_redir_msg_callback_t cb; + + /* + * interface should either be dynamic interface for receiving tunnel msg or GRE_REDIR interface for + * receiving base node messages. + */ + BUG_ON(((ncm->interface < NSS_DYNAMIC_IF_START) || (ncm->interface >= (NSS_DYNAMIC_IF_START + NSS_MAX_DYNAMIC_INTERFACES))) && + ncm->interface != NSS_GRE_REDIR_INTERFACE); + + /* + * Trace Messages + */ + nss_gre_redir_log_rx_msg(ngrm); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_GRE_REDIR_MAX_MSG_TYPES) { + nss_warning("%px: Received invalid message %d for gre interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_gre_redir_msg)) { + nss_warning("%px: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Update the callback and app_data for NOTIFY messages, gre sends all notify messages + * to the same callback/app_data. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_core_get_msg_handler(nss_ctx, ncm->interface); + ncm->app_data = (nss_ptr_t)nss_ctx->nss_rx_interface_handlers[ncm->interface].app_data; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + switch (ncm->type) { + case NSS_GRE_REDIR_RX_STATS_SYNC_MSG: + nss_gre_redir_tunnel_update_stats(nss_ctx, ncm->interface, &ngrm->msg.stats_sync); + break; + } + + /* + * Do we have a call back + */ + if (!ncm->cb) { + return; + } + + /* + * callback + */ + cb = (nss_gre_redir_msg_callback_t)ncm->cb; + ctx = (void *)ncm->app_data; + + /* + * call gre tunnel callback + */ + cb(ctx, ncm); +} + +/* + * nss_gre_redir_register_if() + * Register dynamic node for GRE redir. + */ +static struct nss_ctx_instance *nss_gre_redir_register_if(uint32_t if_num, struct net_device *netdev, + nss_gre_redir_data_callback_t cb_func_data, nss_gre_redir_msg_callback_t cb_func_msg, uint32_t features, + uint32_t type, void *app_ctx) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.gre_redir_handler_id]; + uint32_t status; + int i, idx = -1; + + nss_assert(nss_ctx); + nss_assert((if_num >= NSS_DYNAMIC_IF_START) && (if_num < (NSS_DYNAMIC_IF_START + NSS_MAX_DYNAMIC_INTERFACES))); + + spin_lock_bh(&nss_gre_redir_stats_lock); + for (i = 0; i < NSS_GRE_REDIR_MAX_INTERFACES; i++) { + if (tun_stats[i].dev == netdev) { + idx = i; + break; + } + + if ((idx == -1) && (tun_stats[i].ref_count == 0)) { + idx = i; + } + } + + if (idx == -1) { + spin_unlock_bh(&nss_gre_redir_stats_lock); + nss_warning("%px: Maximum number of gre_redir tunnel_stats instances are already allocated\n", nss_ctx); + return NULL; + } + + if (!tun_stats[idx].ref_count) { + tun_stats[idx].dev = netdev; + } + tun_stats[idx].ref_count++; + + spin_unlock_bh(&nss_gre_redir_stats_lock); + + /* + * Registering handler for sending tunnel interface msgs to NSS. + */ + status = nss_core_register_handler(nss_ctx, if_num, nss_gre_redir_msg_handler, app_ctx); + if (status != NSS_CORE_STATUS_SUCCESS) { + spin_lock_bh(&nss_gre_redir_stats_lock); + tun_stats[idx].ref_count--; + if (!tun_stats[idx].ref_count) { + tun_stats[idx].dev = NULL; + } + spin_unlock_bh(&nss_gre_redir_stats_lock); + + nss_warning("%px: Not able to register handler for gre_redir interface %d with NSS core\n", nss_ctx, if_num); + return NULL; + } + + /* + * Registering handler for sending tunnel interface msgs to NSS. + */ + status = nss_core_register_msg_handler(nss_ctx, if_num, cb_func_msg); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_core_unregister_handler(nss_ctx, if_num); + spin_lock_bh(&nss_gre_redir_stats_lock); + tun_stats[idx].ref_count--; + if (!tun_stats[idx].ref_count) { + tun_stats[idx].dev = NULL; + } + spin_unlock_bh(&nss_gre_redir_stats_lock); + + nss_warning("%px: Not able to register handler for gre_redir interface %d with NSS core\n", nss_ctx, if_num); + return NULL; + } + + nss_core_register_subsys_dp(nss_ctx, if_num, cb_func_data, NULL, NULL, netdev, features); + nss_core_set_subsys_dp_type(nss_ctx, netdev, if_num, type); + return nss_ctx; +} + +/* + * nss_gre_redir_get_context() + * Retrieve context for GRE redir. + */ +struct nss_ctx_instance *nss_gre_redir_get_context(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.gre_redir_handler_id]; +} +EXPORT_SYMBOL(nss_gre_redir_get_context); + +/* + * nss_gre_redir_alloc_and_register_node() + * Allocates and registers GRE Inner/Outer type dynamic nodes with NSS. + */ +int nss_gre_redir_alloc_and_register_node(struct net_device *dev, + nss_gre_redir_data_callback_t data_cb, + nss_gre_redir_msg_callback_t msg_cb, + uint32_t type, void *app_ctx) +{ + int ifnum; + nss_tx_status_t status; + struct nss_ctx_instance *nss_ctx; + + if ((type != NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_WIFI_HOST_INNER) && + (type != NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_WIFI_OFFL_INNER) && + (type != NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_SJACK_INNER) && + (type != NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_OUTER) && + (type != NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_EXCEPTION_US) && + (type != NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_EXCEPTION_DS)) { + + nss_warning("%px: Unknown type %u\n", dev, type); + return -1; + } + + ifnum = nss_dynamic_interface_alloc_node(type); + if (ifnum == -1) { + nss_warning("%px: Unable to allocate GRE_REDIR node of type = %u\n", dev, type); + return -1; + } + + nss_ctx = nss_gre_redir_register_if(ifnum, dev, data_cb, + msg_cb, 0, type, app_ctx); + if (!nss_ctx) { + nss_warning("Unable to register GRE_REDIR node of type = %u\n", type); + status = nss_dynamic_interface_dealloc_node(ifnum, type); + if (status != NSS_TX_SUCCESS) { + nss_warning("Unable to deallocate node.\n"); + } + + return -1; + } + + return ifnum; +} +EXPORT_SYMBOL(nss_gre_redir_alloc_and_register_node); + +/* + * nss_gre_redir_configure_inner_node() + * Configure an inner type gre_redir dynamic node. + */ +nss_tx_status_t nss_gre_redir_configure_inner_node(int ifnum, + struct nss_gre_redir_inner_configure_msg *ngrcm) +{ + struct nss_gre_redir_msg config; + uint32_t len, iftype, outerif_type; + nss_tx_status_t status; + + struct nss_ctx_instance *nss_ctx __maybe_unused = nss_gre_redir_get_context(); + if (!nss_ctx) { + nss_warning("Unable to retrieve NSS context.\n"); + return NSS_TX_FAILURE_BAD_PARAM; + } + + if (ngrcm->ip_hdr_type != NSS_GRE_REDIR_IP_HDR_TYPE_IPV4 && + ngrcm->ip_hdr_type != NSS_GRE_REDIR_IP_HDR_TYPE_IPV6) { + nss_warning("%px: Unknown IP header type %u\n", nss_ctx, ngrcm->ip_hdr_type); + return NSS_TX_FAILURE_BAD_PARAM; + } + + if (ngrcm->gre_version != NSS_GRE_REDIR_HEADER_VERSION) { + nss_warning("%px: Incorrect header version %u\n", nss_ctx, ngrcm->gre_version); + return NSS_TX_FAILURE_BAD_PARAM; + } + + iftype = nss_dynamic_interface_get_type(nss_ctx, ifnum); + if (!((iftype == NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_WIFI_HOST_INNER) || + (iftype == NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_WIFI_OFFL_INNER) || + (iftype == NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_SJACK_INNER))) { + + nss_warning("%px: Incorrect interface type %u\n", nss_ctx, iftype); + return NSS_TX_FAILURE_BAD_PARAM; + } + + outerif_type = nss_dynamic_interface_get_type(nss_ctx, ngrcm->except_outerif); + if (outerif_type != NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_OUTER) { + nss_warning("%px: Incorrect type for exception interface %u\n", nss_ctx, outerif_type); + return NSS_TX_FAILURE_BAD_PARAM; + } + + len = sizeof(struct nss_gre_redir_inner_configure_msg); + + /* + * Configure the node + */ + nss_cmn_msg_init(&config.cm, ifnum, NSS_GRE_REDIR_TX_TUNNEL_INNER_CONFIGURE_MSG, len, NULL, NULL); + config.msg.inner_configure.ip_hdr_type = ngrcm->ip_hdr_type; + config.msg.inner_configure.ip_df_policy = ngrcm->ip_df_policy; + config.msg.inner_configure.gre_version = ngrcm->gre_version; + config.msg.inner_configure.ip_ttl = ngrcm->ip_ttl; + config.msg.inner_configure.except_outerif = ngrcm->except_outerif; + memcpy((void *)config.msg.inner_configure.ip_src_addr, (void *)(ngrcm->ip_src_addr), sizeof(ngrcm->ip_src_addr)); + memcpy((void *)config.msg.inner_configure.ip_dest_addr, (void *)(ngrcm->ip_dest_addr), sizeof(ngrcm->ip_dest_addr)); + + status = nss_gre_redir_tx_msg_sync(nss_ctx, &config); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: Unable to configure inner node %d.\n", nss_ctx, ifnum); + } + + return status; +} +EXPORT_SYMBOL(nss_gre_redir_configure_inner_node); + +/* + * nss_gre_redir_exception_ds_reg_cb() + * Configure a callback on VAP for downstream exception tunnel flows. + */ +nss_tx_status_t nss_gre_redir_exception_ds_reg_cb(int ifnum, + struct nss_gre_redir_exception_ds_reg_cb_msg *ngrcm) +{ + struct nss_gre_redir_msg config; + struct nss_ctx_instance *nss_ctx __maybe_unused = nss_gre_redir_get_context(); + nss_tx_status_t status; + uint32_t vap_type, iftype; + uint32_t len = sizeof(struct nss_gre_redir_exception_ds_reg_cb_msg); + + if (!nss_ctx) { + nss_warning("Unable to retrieve NSS context.\n"); + return NSS_TX_FAILURE_BAD_PARAM; + } + + iftype = nss_dynamic_interface_get_type(nss_ctx, ifnum); + if (iftype != NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_EXCEPTION_DS) { + nss_warning("%px: Incorrect interface type %u\n", nss_ctx, iftype); + return NSS_TX_FAILURE_BAD_PARAM; + } + + vap_type = nss_dynamic_interface_get_type(nss_ctx, ngrcm->dst_vap_nssif); + if ((vap_type != NSS_DYNAMIC_INTERFACE_TYPE_VAP)) { + nss_warning("%px: Incorrect type for vap interface type = %u", nss_ctx, vap_type); + return NSS_TX_FAILURE_BAD_PARAM; + } + + /* + * Configure the node + */ + nss_cmn_msg_init(&config.cm, ifnum, NSS_GRE_REDIR_EXCEPTION_DS_REG_CB_MSG, len, NULL, NULL); + config.msg.exception_ds_configure.dst_vap_nssif = ngrcm->dst_vap_nssif; + + status = nss_gre_redir_tx_msg_sync(nss_ctx, &config); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: Unable to register callback from gre redir exception ds %d\n", nss_ctx, ifnum); + } + + return status; +} +EXPORT_SYMBOL(nss_gre_redir_exception_ds_reg_cb); + +/* + * nss_gre_redir_configure_outer_node() + * Configure an outer type gre_redir dynamic node. + */ +nss_tx_status_t nss_gre_redir_configure_outer_node(int ifnum, + struct nss_gre_redir_outer_configure_msg *ngrcm) +{ + struct nss_gre_redir_msg config; + struct nss_ctx_instance *nss_ctx __maybe_unused = nss_gre_redir_get_context(); + nss_tx_status_t status; + uint32_t hostif_type, offlif_type, sjackif_type, iftype; + uint32_t len = sizeof(struct nss_gre_redir_outer_configure_msg); + + if (!nss_ctx) { + nss_warning("Unable to retrieve NSS context.\n"); + return NSS_TX_FAILURE_BAD_PARAM; + } + + if (ngrcm->ip_hdr_type != NSS_GRE_REDIR_IP_HDR_TYPE_IPV4 && + ngrcm->ip_hdr_type != NSS_GRE_REDIR_IP_HDR_TYPE_IPV6) { + nss_warning("%px: Unknown IP header type %u\n", nss_ctx, ngrcm->ip_hdr_type); + return NSS_TX_FAILURE_BAD_PARAM; + } + + iftype = nss_dynamic_interface_get_type(nss_ctx, ifnum); + if (iftype != NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_OUTER) { + nss_warning("%px: Incorrect interface type %u\n", nss_ctx, iftype); + return NSS_TX_FAILURE_BAD_PARAM; + } + + hostif_type = nss_dynamic_interface_get_type(nss_ctx, ngrcm->except_hostif); + offlif_type = nss_dynamic_interface_get_type(nss_ctx, ngrcm->except_offlif); + sjackif_type = nss_dynamic_interface_get_type(nss_ctx, ngrcm->except_sjackif); + if ((hostif_type != NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_WIFI_HOST_INNER) || + (offlif_type != NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_WIFI_OFFL_INNER) || + (ngrcm->except_sjackif + && sjackif_type != NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_SJACK_INNER)) { + + nss_warning("%px: Incorrect type for exception interface hostif_type = %u" + "offlif_type = %u sjackif_type = %u\n", nss_ctx, hostif_type, + offlif_type, sjackif_type); + return NSS_TX_FAILURE_BAD_PARAM; + } + + /* + * Configure the node + */ + nss_cmn_msg_init(&config.cm, ifnum, NSS_GRE_REDIR_TX_TUNNEL_OUTER_CONFIGURE_MSG, len, NULL, NULL); + config.msg.outer_configure.ip_hdr_type = ngrcm->ip_hdr_type; + config.msg.outer_configure.rps_hint = ngrcm->rps_hint; + config.msg.outer_configure.except_hostif = ngrcm->except_hostif; + config.msg.outer_configure.except_offlif = ngrcm->except_offlif; + config.msg.outer_configure.except_sjackif = ngrcm->except_sjackif; + + status = nss_gre_redir_tx_msg_sync(nss_ctx, &config); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: Unable to configure outer node %d\n", nss_ctx, ifnum); + } + + return status; +} +EXPORT_SYMBOL(nss_gre_redir_configure_outer_node); + +/* + * nss_gre_redir_get_stats() + * Get gre_redir tunnel stats. + */ +bool nss_gre_redir_get_stats(int index, struct nss_gre_redir_tunnel_stats *stats) +{ + spin_lock_bh(&nss_gre_redir_stats_lock); + if (tun_stats[index].ref_count == 0) { + spin_unlock_bh(&nss_gre_redir_stats_lock); + return false; + } + + memcpy(stats, &tun_stats[index], sizeof(struct nss_gre_redir_tunnel_stats)); + spin_unlock_bh(&nss_gre_redir_stats_lock); + return true; +} +EXPORT_SYMBOL(nss_gre_redir_get_stats); + +/* + * nss_gre_redir_tx_msg() + * Transmit a GRE message to NSS FW. + */ +nss_tx_status_t nss_gre_redir_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_gre_redir_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Trace Messages + */ + nss_gre_redir_log_tx_msg(msg); + + /* + * Sanity check the message + */ + + /* + * interface should either be dynamic interface to transmit tunnel msg or GRE_REDIR interface to transmit + * base node messages. + */ + if (((ncm->interface < NSS_DYNAMIC_IF_START) || (ncm->interface >= (NSS_DYNAMIC_IF_START + NSS_MAX_DYNAMIC_INTERFACES))) && + ncm->interface != NSS_GRE_REDIR_INTERFACE) { + nss_warning("%px: tx request for another interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type >= NSS_GRE_REDIR_MAX_MSG_TYPES) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_gre_redir_tx_msg); + +/* + * nss_gre_redir_tx_msg_sync() + * Transmit a GRE redir message to NSS firmware synchronously. + */ +nss_tx_status_t nss_gre_redir_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_redir_msg *ngrm) +{ + nss_tx_status_t status; + int ret = 0; + + down(&nss_gre_redir_pvt.sem); + ngrm->cm.cb = (nss_ptr_t)nss_gre_redir_msg_sync_callback; + ngrm->cm.app_data = (nss_ptr_t)NULL; + status = nss_gre_redir_tx_msg(nss_ctx, ngrm); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: gre_tx_msg failed\n", nss_ctx); + up(&nss_gre_redir_pvt.sem); + return status; + } + + ret = wait_for_completion_timeout(&nss_gre_redir_pvt.complete, msecs_to_jiffies(NSS_GRE_REDIR_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: GRE tx sync failed due to timeout\n", nss_ctx); + nss_gre_redir_pvt.response = NSS_TX_FAILURE; + } + + status = nss_gre_redir_pvt.response; + up(&nss_gre_redir_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_gre_redir_tx_msg_sync); + +/* + * nss_gre_redir_tx_buf() + * Send packet to gre_redir interface owned by NSS. + */ +nss_tx_status_t nss_gre_redir_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf, uint32_t if_num) +{ + uint32_t type; + + nss_trace("%px: gre_redir If Tx packet, id:%d, data=%px", nss_ctx, if_num, os_buf->data); + + /* + * We expect Tx packets to the tunnel only from an interface of + * type GRE_REDIR_WIFI_HOST_INNER. + */ + type = nss_dynamic_interface_get_type(nss_ctx, if_num); + if (!((type == NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_WIFI_HOST_INNER) + || (type == NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_EXCEPTION_DS))) { + nss_warning("%px: Unknown type for interface %u\n", nss_ctx, type); + return NSS_TX_FAILURE_BAD_PARAM; + } + + return nss_core_send_packet(nss_ctx, os_buf, if_num, H2N_BIT_FLAG_BUFFER_REUSABLE); +} +EXPORT_SYMBOL(nss_gre_redir_tx_buf); + +/* + * nss_gre_redir_tx_buf_noreuse() + * Send packet to gre_redir interface owned by NSS. + */ +nss_tx_status_t nss_gre_redir_tx_buf_noreuse(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf, uint32_t if_num) +{ + uint32_t type; + + nss_trace("%px: gre_redir If Tx packet, id:%d, data=%px", nss_ctx, if_num, os_buf->data); + + /* + * We expect Tx packets to the tunnel only from an interface of + * type GRE_REDIR_WIFI_HOST_INNER. + */ + type = nss_dynamic_interface_get_type(nss_ctx, if_num); + if (!((type == NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_WIFI_HOST_INNER) + || (type == NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_EXCEPTION_DS))) { + nss_warning("%px: Unknown type for interface %u\n", nss_ctx, type); + return NSS_TX_FAILURE_BAD_PARAM; + } + + return nss_core_send_packet(nss_ctx, os_buf, if_num, 0); +} +EXPORT_SYMBOL(nss_gre_redir_tx_buf_noreuse); + +/* + * nss_gre_redir_unregister_if() + * Unregister dynamic node for GRE redir. + */ +bool nss_gre_redir_unregister_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx __maybe_unused = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.gre_redir_handler_id]; + uint32_t status; + struct net_device *dev; + int i; + + nss_assert(nss_ctx); + nss_assert((if_num >= NSS_DYNAMIC_IF_START) && (if_num < (NSS_DYNAMIC_IF_START + NSS_MAX_DYNAMIC_INTERFACES))); + + dev = nss_cmn_get_interface_dev(nss_ctx, if_num); + if (!dev) { + nss_warning("%px: Unable to find net device for the interface %d\n", nss_ctx, if_num); + return false; + } + + status = nss_core_unregister_msg_handler(nss_ctx, if_num); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Not able to unregister handler for gre_redir interface %d with NSS core\n", nss_ctx, if_num); + return false; + } + + status = nss_core_unregister_handler(nss_ctx, if_num); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Not able to unregister handler for gre_redir interface %d with NSS core\n", nss_ctx, if_num); + return false; + } + + nss_core_set_subsys_dp_type(nss_ctx, dev, if_num, NSS_DYNAMIC_INTERFACE_TYPE_NONE); + nss_core_unregister_subsys_dp(nss_ctx, if_num); + spin_lock_bh(&nss_gre_redir_stats_lock); + + /* + * Update/Clear the tunnel stats entry for this tunnel. + */ + for (i = 0; i < NSS_GRE_REDIR_MAX_INTERFACES; i++) { + if (tun_stats[i].dev == dev) { + tun_stats[i].ref_count--; + if (!tun_stats[i].ref_count) { + tun_stats[i].dev = NULL; + } + + break; + } + } + + spin_unlock_bh(&nss_gre_redir_stats_lock); + return true; +} +EXPORT_SYMBOL(nss_gre_redir_unregister_if); + +/* + * nss_gre_redir_get_device() + * Gets the original device from probe. + */ +struct device *nss_gre_redir_get_device(void) +{ + struct nss_ctx_instance *nss_ctx = nss_gre_redir_get_context(); + return nss_ctx->dev; +} +EXPORT_SYMBOL(nss_gre_redir_get_device); + +/* + * nss_gre_redir_get_dentry() + * Returns directory entry created in debugfs for statistics. + */ +struct dentry *nss_gre_redir_get_dentry(void) +{ + return gre_redir_dentry; +} + +/* + * nss_gre_redir_register_handler() + * Registering handler for sending msg to base gre_redir node on NSS. + */ +void nss_gre_redir_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx __maybe_unused = nss_gre_redir_get_context(); + uint32_t status; + + gre_redir_dentry = nss_gre_redir_stats_dentry_create(); + if (!gre_redir_dentry) { + nss_warning("%px: Not able to create debugfs entry\n", nss_ctx); + return; + } + + sema_init(&nss_gre_redir_pvt.sem, 1); + init_completion(&nss_gre_redir_pvt.complete); + memset(tun_stats, 0, sizeof(struct nss_gre_redir_tunnel_stats) * NSS_GRE_REDIR_MAX_INTERFACES); + status = nss_core_register_handler(nss_ctx, NSS_GRE_REDIR_INTERFACE, nss_gre_redir_msg_handler, NULL); + if (status != NSS_CORE_STATUS_SUCCESS) { + debugfs_remove_recursive(gre_redir_dentry); + gre_redir_dentry = NULL; + nss_warning("%px: Not able to register handler for gre_redir base interface with NSS core\n", nss_ctx); + return; + } +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_ds.c b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_ds.c new file mode 100644 index 000000000..2dc6b687b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_ds.c @@ -0,0 +1,448 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_gre_redir_lag_ds_stats.h" +#include "nss_gre_redir_lag_ds_log.h" + +#define NSS_GRE_REDIR_LAG_DS_TX_TIMEOUT 3000 /* 3 Seconds */ + +static struct nss_gre_redir_lag_ds_tun_stats tun_stats[NSS_GRE_REDIR_LAG_MAX_NODE]; +static DEFINE_SPINLOCK(nss_gre_redir_lag_ds_stats_lock); + +/* + * Private data structure + */ +static struct { + struct semaphore sem; + struct completion complete; + int response; + nss_gre_redir_lag_ds_msg_callback_t *cb; + void *app_data; +} nss_gre_redir_lag_ds_pvt; + +/* + * nss_gre_redir_lag_ds_callback() + * Callback to handle the completion of HLOS-->NSS messages. + */ +static void nss_gre_redir_lag_ds_callback(void *app_data, struct nss_gre_redir_lag_ds_msg *nim) +{ + nss_gre_redir_lag_ds_msg_callback_t callback = (nss_gre_redir_lag_ds_msg_callback_t)nss_gre_redir_lag_ds_pvt.cb; + void *data = nss_gre_redir_lag_ds_pvt.app_data; + + nss_gre_redir_lag_ds_pvt.cb = NULL; + nss_gre_redir_lag_ds_pvt.app_data = NULL; + + if (nim->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("GRE LAG DS: error response %d\n", nim->cm.response); + nss_gre_redir_lag_ds_pvt.response = NSS_TX_FAILURE; + } else { + nss_gre_redir_lag_ds_pvt.response = NSS_TX_SUCCESS; + } + + if (callback) { + callback(data, &nim->cm); + } + + complete(&nss_gre_redir_lag_ds_pvt.complete); +} + +/* + * nss_gre_redir_lag_ds_get_node_idx() + * Returns index of statistics context. + */ +static inline bool nss_gre_redir_lag_ds_get_node_idx(uint32_t ifnum, uint32_t *idx) +{ + uint32_t node_idx; + for (node_idx = 0; node_idx < NSS_GRE_REDIR_LAG_MAX_NODE; node_idx++) { + if ((tun_stats[node_idx].valid) && (tun_stats[node_idx].ifnum == ifnum)) { + *idx = node_idx; + return true; + } + } + + return false; +} + +/* + * nss_gre_redir_lag_ds_update_sync_stats() + * Update synchonized statistics. + */ +static void nss_gre_redir_lag_ds_update_sync_stats(struct nss_ctx_instance *nss_ctx, struct nss_gre_redir_lag_ds_sync_stats_msg *ngss, uint32_t ifnum) +{ + int idx, j; + + spin_lock_bh(&nss_gre_redir_lag_ds_stats_lock); + if (!nss_gre_redir_lag_ds_get_node_idx(ifnum, &idx)) { + spin_unlock_bh(&nss_gre_redir_lag_ds_stats_lock); + nss_warning("%px: Unable to update hash stats msg. Stats context not found.\n", nss_ctx); + return; + } + + tun_stats[idx].tx_packets += ngss->node_stats.tx_packets; + tun_stats[idx].tx_bytes += ngss->node_stats.tx_bytes; + tun_stats[idx].rx_packets += ngss->node_stats.rx_packets; + tun_stats[idx].rx_bytes += ngss->node_stats.rx_bytes; + for (j = 0; j < NSS_MAX_NUM_PRI; j++) { + tun_stats[idx].rx_dropped[j] += ngss->node_stats.rx_dropped[j]; + } + tun_stats[idx].dst_invalid += ngss->ds_stats.dst_invalid; + tun_stats[idx].exception_cnt += ngss->ds_stats.exception_cnt; + spin_unlock_bh(&nss_gre_redir_lag_ds_stats_lock); +} + +/* + * nss_gre_redir_lag_ds_verify_ifnum() + * Verify interface type. + */ +static bool nss_gre_redir_lag_ds_verify_ifnum(uint32_t if_num) +{ + return nss_dynamic_interface_get_type(nss_gre_redir_lag_ds_get_context(), if_num) == NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_DS; +} + +/* + * nss_gre_redir_lag_ds_handler() + * Handle NSS -> HLOS messages for gre tunnel + */ +static void nss_gre_redir_lag_ds_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + void *ctx; + struct nss_gre_redir_lag_ds_msg *ngrm = (struct nss_gre_redir_lag_ds_msg *)ncm; + nss_gre_redir_lag_ds_msg_callback_t cb; + + /* + * Interface should be a dynamic interface of type NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_DS. + */ + BUG_ON(!nss_gre_redir_lag_ds_verify_ifnum(ncm->interface)); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_GRE_REDIR_LAG_DS_MAX_MSG_TYPES) { + nss_warning("%px: received invalid message %d for gre interface\n", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_gre_redir_lag_ds_msg)) { + nss_warning("%px: Length of message is greater than required: %d\n", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Update the callback and app_data for NOTIFY messages, gre sends all notify messages + * to the same callback/app_data. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_core_get_msg_handler(nss_ctx, ncm->interface); + ncm->app_data = (nss_ptr_t)nss_ctx->nss_rx_interface_handlers[ncm->interface].app_data; + } + + /* + * Trace messages. + */ + nss_gre_redir_lag_ds_log_rx_msg(ngrm); + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + switch (ncm->type) { + case NSS_GRE_REDIR_LAG_DS_STATS_SYNC_MSG: + nss_gre_redir_lag_ds_update_sync_stats(nss_ctx, &ngrm->msg.ds_sync_stats, ncm->interface); + break; + } + + /* + * Do we have a call back + */ + if (!ncm->cb) { + return; + } + + /* + * callback + */ + cb = (nss_gre_redir_lag_ds_msg_callback_t)ncm->cb; + ctx = (void *)ncm->app_data; + + /* + * call gre tunnel callback + */ + cb(ctx, ncm); +} + +/* + * nss_gre_redir_lag_ds_unregister_if() + * Unregister GRE redirect LAG downstream node. + */ +static enum nss_gre_redir_lag_err_types nss_gre_redir_lag_ds_unregister_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx __maybe_unused = nss_gre_redir_lag_ds_get_context(); + uint32_t idx, status; + + nss_assert(nss_ctx); + nss_assert(!nss_gre_redir_lag_ds_verify_ifnum(if_num)); + + status = nss_core_unregister_msg_handler(nss_ctx, if_num); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Not able to unregister handler for gre_lag interface %d with NSS core\n", nss_ctx, if_num); + return NSS_GRE_REDIR_LAG_ERR_CORE_UNREGISTER_FAILED; + } + + status = nss_core_unregister_handler(nss_ctx, if_num); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Not able to unregister handler for gre_lag interface %d with NSS core\n", nss_ctx, if_num); + return NSS_GRE_REDIR_LAG_ERR_CORE_UNREGISTER_FAILED; + } + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + spin_lock_bh(&nss_gre_redir_lag_ds_stats_lock); + if (!nss_gre_redir_lag_ds_get_node_idx(if_num, &idx)) { + spin_unlock_bh(&nss_gre_redir_lag_ds_stats_lock); + nss_warning("%px: Stats context not found.\n", nss_ctx); + return NSS_GRE_REDIR_LAG_ERR_STATS_INDEX_NOT_FOUND; + } + + tun_stats[idx].valid = false; + spin_unlock_bh(&nss_gre_redir_lag_ds_stats_lock); + return NSS_GRE_REDIR_LAG_SUCCESS; +} + +/* + * nss_gre_redir_lag_ds_register_if() + * Register GRE redirect LAG downstream node. + */ +static struct nss_ctx_instance *nss_gre_redir_lag_ds_register_if(uint32_t if_num, struct net_device *netdev, + nss_gre_redir_lag_ds_data_callback_t cb_func_data, + nss_gre_redir_lag_ds_msg_callback_t cb_func_msg, uint32_t features, uint32_t type, void *app_ctx) +{ + struct nss_ctx_instance *nss_ctx = nss_gre_redir_lag_ds_get_context(); + uint32_t status, i; + nss_assert(nss_ctx); + nss_assert(!nss_gre_redir_lag_ds_verify_ifnum(if_num)); + + /* + * Registering handler for sending tunnel interface msgs to NSS. + */ + status = nss_core_register_handler(nss_ctx, if_num, nss_gre_redir_lag_ds_msg_handler, app_ctx); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Not able to register handler for gre_lag interface %d with NSS core\n", nss_ctx, if_num); + return NULL; + } + + /* + * Registering handler for sending tunnel interface msgs to NSS. + */ + status = nss_core_register_msg_handler(nss_ctx, if_num, cb_func_msg); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_core_unregister_handler(nss_ctx, if_num); + nss_warning("%px: Not able to register handler for gre_lag interface %d with NSS core\n", nss_ctx, if_num); + return NULL; + } + + nss_core_register_subsys_dp(nss_ctx, if_num, cb_func_data, NULL, NULL, netdev, features); + nss_core_set_subsys_dp_type(nss_ctx, netdev, if_num, type); + spin_lock_bh(&nss_gre_redir_lag_ds_stats_lock); + for (i = 0; i < NSS_GRE_REDIR_LAG_MAX_NODE; i++) { + if (!tun_stats[i].valid) { + tun_stats[i].ifnum = if_num; + tun_stats[i].valid = true; + break; + } + } + + spin_unlock_bh(&nss_gre_redir_lag_ds_stats_lock); + + return nss_ctx; +} + +/* + * nss_gre_redir_lag_ds_get_context() + * Retrieves context GRE redirect LAG downstream node. + */ +struct nss_ctx_instance *nss_gre_redir_lag_ds_get_context(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.gre_redir_lag_ds_handler_id]; +} +EXPORT_SYMBOL(nss_gre_redir_lag_ds_get_context); + +/* + * nss_gre_redir_lag_ds_get_cmn_stats() + * Get statistics for downstream LAG node. + */ +bool nss_gre_redir_lag_ds_get_cmn_stats(struct nss_gre_redir_lag_ds_tun_stats *cmn_stats, uint32_t index) +{ + if (index >= NSS_GRE_REDIR_LAG_MAX_NODE) { + return false; + } + + spin_lock_bh(&nss_gre_redir_lag_ds_stats_lock); + if (!tun_stats[index].valid) { + spin_unlock_bh(&nss_gre_redir_lag_ds_stats_lock); + return false; + } + memcpy((void *)cmn_stats, (void *)&tun_stats[index], sizeof(*cmn_stats)); + spin_unlock_bh(&nss_gre_redir_lag_ds_stats_lock); + return true; +} + +/* + * nss_gre_redir_lag_ds_tx_msg() + * Transmit a gre message to NSS. + */ +nss_tx_status_t nss_gre_redir_lag_ds_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_gre_redir_lag_ds_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Trace messages. + */ + nss_gre_redir_lag_ds_log_tx_msg(msg); + + /* + * Sanity check the message. Interface should be a dynamic interface + * of type NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_DS. + */ + if (!nss_gre_redir_lag_ds_verify_ifnum(ncm->interface)) { + nss_warning("%px: tx request for another interface: %d\n", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type >= NSS_GRE_REDIR_LAG_DS_MAX_MSG_TYPES) { + nss_warning("%px: message type out of range: %d\n", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_gre_redir_lag_ds_tx_msg); + +/* + * nss_gre_redir_lag_ds_tx_msg_sync() + * Transmit a GRE lag message to NSS firmware synchronously. + */ +nss_tx_status_t nss_gre_redir_lag_ds_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_redir_lag_ds_msg *ngrm) +{ + nss_tx_status_t status; + int ret = 0; + + down(&nss_gre_redir_lag_ds_pvt.sem); + nss_gre_redir_lag_ds_pvt.cb = (void *)ngrm->cm.cb; + nss_gre_redir_lag_ds_pvt.app_data = (void *)ngrm->cm.app_data; + ngrm->cm.cb = (nss_ptr_t)nss_gre_redir_lag_ds_callback; + ngrm->cm.app_data = (nss_ptr_t)NULL; + + status = nss_gre_redir_lag_ds_tx_msg(nss_ctx, ngrm); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: GRE LAG DS msg tx failed\n", nss_ctx); + up(&nss_gre_redir_lag_ds_pvt.sem); + return status; + } + + ret = wait_for_completion_timeout(&nss_gre_redir_lag_ds_pvt.complete, msecs_to_jiffies(NSS_GRE_REDIR_LAG_DS_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: GRE LAG DS tx sync failed due to timeout\n", nss_ctx); + nss_gre_redir_lag_ds_pvt.response = NSS_TX_FAILURE; + } + + status = nss_gre_redir_lag_ds_pvt.response; + up(&nss_gre_redir_lag_ds_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_gre_redir_lag_ds_tx_msg_sync); + +/* + * nss_gre_redir_lag_ds_unregister_and_dealloc() + * Unregister and deallocate nss gre redirect LAG DS node. + */ +enum nss_gre_redir_lag_err_types nss_gre_redir_lag_ds_unregister_and_dealloc(uint32_t ifnum) +{ + uint32_t ret; + struct nss_ctx_instance *nss_ctx __maybe_unused = nss_gre_redir_lag_ds_get_context(); + nss_tx_status_t status; + + if (!nss_gre_redir_lag_ds_verify_ifnum(ifnum)) { + nss_warning("%px: Unknown interface type %u.\n", nss_ctx, ifnum); + return NSS_GRE_REDIR_LAG_ERR_INCORRECT_IFNUM; + } + + ret = nss_gre_redir_lag_ds_unregister_if(ifnum); + if (ret) { + nss_warning("%px: Unable to unregister interface %u.\n", nss_ctx, ifnum); + return ret; + } + + status = nss_dynamic_interface_dealloc_node(ifnum, NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_DS); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: Unable to deallocate node %u\n", nss_ctx, ifnum); + return NSS_GRE_REDIR_LAG_ERR_DEALLOC_FAILED; + } + + return NSS_GRE_REDIR_LAG_SUCCESS; +} +EXPORT_SYMBOL(nss_gre_redir_lag_ds_unregister_and_dealloc); + +/* + * nss_gre_redir_lag_ds_alloc_and_register_node() + * Allocates and registers GRE downstream type dynamic nodes with NSS. + */ +int nss_gre_redir_lag_ds_alloc_and_register_node(struct net_device *dev, + nss_gre_redir_lag_ds_data_callback_t cb_func_data, + nss_gre_redir_lag_ds_msg_callback_t cb_func_msg, void *app_ctx) +{ + int ifnum; + nss_tx_status_t status; + struct nss_ctx_instance *nss_ctx; + + ifnum = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_DS); + if (ifnum == -1) { + nss_warning("%px: Unable to allocate GRE_LAG node of type = %u\n", dev, NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_DS); + return -1; + } + + nss_ctx = nss_gre_redir_lag_ds_register_if(ifnum, dev, cb_func_data, + cb_func_msg, 0, NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_DS, app_ctx); + if (!nss_ctx) { + nss_warning("%px: Unable to register GRE_LAG node of type = %u\n", dev, NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_DS); + status = nss_dynamic_interface_dealloc_node(ifnum, NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_DS); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: Unable to deallocate node of type = %u.\n", dev, NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_DS); + } + + return -1; + } + + return ifnum; +} +EXPORT_SYMBOL(nss_gre_redir_lag_ds_alloc_and_register_node); + +/* + * nss_gre_redir_lag_ds_register_handler() + * Registering handler for sending msg to base gre_lag node on NSS. + */ +void nss_gre_redir_lag_ds_register_handler(void) +{ + if (!nss_gre_redir_lag_ds_stats_dentry_create()) { + nss_warning(" Unable to create debugfs entry for LAG DS node.\n"); + return; + } + + nss_gre_redir_lag_ds_pvt.cb = NULL; + nss_gre_redir_lag_ds_pvt.app_data = NULL; + sema_init(&nss_gre_redir_lag_ds_pvt.sem, 1); + init_completion(&nss_gre_redir_lag_ds_pvt.complete); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_ds_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_ds_log.c new file mode 100644 index 000000000..158cb9d44 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_ds_log.c @@ -0,0 +1,164 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_gre_redir_lag_ds_log.c + * NSS GRE REDIR LAG DS logger file. + */ + +#include "nss_core.h" + +/* + * nss_gre_redir_lag_ds_log_message_types_str + * GRE REDIR LAG DS message strings + */ +static int8_t *nss_gre_redir_lag_ds_log_message_types_str[NSS_GRE_REDIR_LAG_DS_MAX_MSG_TYPES] __maybe_unused = { + "GRE REDIR LAG DS add station Message", + "GRE REDIR LAG DS delete station message", + "GRE REDIR LAG DS update station message", + "GRE REDIR LAG DS stats sync message", +}; + +/* + * nss_gre_redir_lag_ds_log_error_response_types_str + * Strings for error types for GRE REDIR LAG DS messages + */ +static int8_t *nss_gre_redir_lag_ds_log_error_response_types_str[NSS_GRE_REDIR_LAG_ERR_MAX] __maybe_unused = { + "GRE REDIR LAG Success", + "GRE REDIR LAG Incorrect Interface", + "GRE REDIR LAG DS Core Unregister Failed", + "GRE REDIR LAG DS STats Index Not Found", + "GRE REDIR LAG Dealloc Failed", +}; + +/* + * nss_gre_redir_lag_ds_log_add_sta_msg() + * Log NSS GRE REDIR LAG DS add STA message. + */ +static void nss_gre_redir_lag_ds_log_add_sta_msg(struct nss_gre_redir_lag_ds_msg *ngm) +{ + struct nss_gre_redir_lag_ds_add_sta_msg *ngasm __maybe_unused = &ngm->msg.add_sta; + nss_trace("%px: NSS GRE REDIR LAG DS Add STA Message:\n" + "GRE REDIR LAG DS Station MAC Address: %px\n" + "GRE REDIR LAG DS Reorder Type: %d\n", + ngasm, ngasm->mac, ngasm->reorder_type); +} + +/* + * nss_gre_redir_lag_ds_log_del_sta_msg() + * Log NSS GRE REDIR LAG DS del STA message. + */ +static void nss_gre_redir_lag_ds_log_del_sta_msg(struct nss_gre_redir_lag_ds_msg *ngm) +{ + struct nss_gre_redir_lag_ds_delete_sta_msg *ngdsm __maybe_unused = &ngm->msg.del_sta; + nss_trace("%px: NSS GRE REDIR LAG DS Del STA Message:\n" + "GRE REDIR LAG DS Station MAC Address: %px\n", + ngdsm, ngdsm->mac); +} + +/* + * nss_gre_redir_lag_ds_log_add_sta_msg() + * Log NSS GRE REDIR LAG DS add STA message. + */ +static void nss_gre_redir_lag_ds_log_update_sta_msg(struct nss_gre_redir_lag_ds_msg *ngm) +{ + struct nss_gre_redir_lag_ds_update_sta_msg *ngusm __maybe_unused = &ngm->msg.update_sta; + nss_trace("%px: NSS GRE REDIR LAG DS Update STA Message:\n" + "GRE REDIR LAG DS Station MAC Address: %px\n" + "GRE REDIR LAG DS Reorder Type: %d\n", + ngusm, ngusm->mac, ngusm->reorder_type); +} + +/* + * nss_gre_redir_lag_ds_log_verbose() + * Log message contents. + */ +static void nss_gre_redir_lag_ds_log_verbose(struct nss_gre_redir_lag_ds_msg *ngm) +{ + switch (ngm->cm.type) { + case NSS_GRE_REDIR_LAG_DS_ADD_STA_MSG: + nss_gre_redir_lag_ds_log_add_sta_msg(ngm); + break; + + case NSS_GRE_REDIR_LAG_DS_DEL_STA_MSG: + nss_gre_redir_lag_ds_log_del_sta_msg(ngm); + break; + + case NSS_GRE_REDIR_LAG_DS_UPDATE_STA_MSG: + nss_gre_redir_lag_ds_log_update_sta_msg(ngm); + break; + + case NSS_GRE_REDIR_LAG_DS_STATS_SYNC_MSG: + /* + * No log for valid stats message. + */ + break; + + default: + nss_warning("%px: Invalid message type\n", ngm); + break; + } +} + +/* + * nss_gre_redir_lag_ds_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_gre_redir_lag_ds_log_tx_msg(struct nss_gre_redir_lag_ds_msg *ngm) +{ + if (ngm->cm.type >= NSS_GRE_REDIR_LAG_DS_MAX_MSG_TYPES) { + nss_warning("%px: Invalid message type\n", ngm); + return; + } + + nss_info("%px: type[%d]:%s\n", ngm, ngm->cm.type, nss_gre_redir_lag_ds_log_message_types_str[ngm->cm.type]); + nss_gre_redir_lag_ds_log_verbose(ngm); +} + +/* + * nss_gre_redir_lag_ds_log_rx_msg() + * Log messages received from FW. + */ +void nss_gre_redir_lag_ds_log_rx_msg(struct nss_gre_redir_lag_ds_msg *ngm) +{ + if (ngm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", ngm); + return; + } + + if (ngm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ngm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", ngm, ngm->cm.type, + nss_gre_redir_lag_ds_log_message_types_str[ngm->cm.type], + ngm->cm.response, nss_cmn_response_str[ngm->cm.response]); + goto verbose; + } + + if (ngm->cm.error >= NSS_GRE_REDIR_LAG_ERR_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + ngm, ngm->cm.type, nss_gre_redir_lag_ds_log_message_types_str[ngm->cm.type], + ngm->cm.response, nss_cmn_response_str[ngm->cm.response], + ngm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + ngm, ngm->cm.type, nss_gre_redir_lag_ds_log_message_types_str[ngm->cm.type], + ngm->cm.response, nss_cmn_response_str[ngm->cm.response], + ngm->cm.error, nss_gre_redir_lag_ds_log_error_response_types_str[ngm->cm.error]); + +verbose: + nss_gre_redir_lag_ds_log_verbose(ngm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_ds_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_ds_log.h new file mode 100644 index 000000000..b0918760e --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_ds_log.h @@ -0,0 +1,37 @@ +/* + ****************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_GRE_REDIR_LAG_DS_LOG_H__ +#define __NSS_GRE_REDIR_LAG_DS_LOG_H__ + +/* + * nss_gre_redir_lag_ds_log.h + * NSS GRE REDIR LAG DS Log Header File + */ + +/* + * nss_gre_redir_lag_ds_log_tx_msg + * Logs a gre redir lag ds message that is sent to the NSS firmware. + */ +void nss_gre_redir_lag_ds_log_tx_msg(struct nss_gre_redir_lag_ds_msg *ngm); + +/* + * nss_gre_redir_lag_ds_log_rx_msg + * Logs a gre redir lag ds message that is received from the NSS firmware. + */ +void nss_gre_redir_lag_ds_log_rx_msg(struct nss_gre_redir_lag_ds_msg *ngm); + +#endif /* __NSS_GRE_REDIR_LAG_DS_LOG_H__ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_ds_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_ds_stats.c new file mode 100644 index 000000000..edba01527 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_ds_stats.c @@ -0,0 +1,163 @@ +/* + ************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_gre_redir_lag.h" +#include "nss_gre_redir_lag_ds_stats.h" + +/* + * nss_gre_redir_lag_ds_stats_str + * GRE REDIR LAG DS common statistics strings. + */ +static uint8_t *nss_gre_redir_lag_ds_stats_str[NSS_GRE_REDIR_LAG_DS_STATS_MAX] = { + "rx_packets", + "rx_bytes", + "tx_packets", + "tx_bytes", + "rx_queue_0_dropped", + "rx_queue_1_dropped", + "rx_queue_2_dropped", + "rx_queue_3_dropped", + "dst_invalid", + "exception_packets" +}; + +/* + * nss_gre_redir_lag_ds_tunnel_stats() + * Make a row for GRE_REDIR LAG DS stats. + */ +static ssize_t nss_gre_redir_lag_ds_cmn_stats_read_entry(char *line, int len, int type, struct nss_gre_redir_lag_ds_tun_stats *s) +{ + uint64_t tcnt = 0; + + switch (type) { + case NSS_STATS_NODE_RX_PKTS: + tcnt = s->rx_packets; + return snprintf(line, len, "Common node stats start:\n\n%s = %llu\n", nss_gre_redir_lag_ds_stats_str[type], tcnt); + case NSS_STATS_NODE_RX_BYTES: + tcnt = s->rx_bytes; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_ds_stats_str[type], tcnt); + case NSS_STATS_NODE_TX_PKTS: + tcnt = s->tx_packets; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_ds_stats_str[type], tcnt); + case NSS_STATS_NODE_TX_BYTES: + tcnt = s->tx_bytes; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_ds_stats_str[type], tcnt); + case NSS_STATS_NODE_RX_QUEUE_0_DROPPED: + tcnt = s->rx_dropped[0]; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_ds_stats_str[type], tcnt); +#if (NSS_MAX_NUM_PRI > 1) + case NSS_STATS_NODE_RX_QUEUE_1_DROPPED: + tcnt = s->rx_dropped[1]; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_ds_stats_str[type], tcnt); + case NSS_STATS_NODE_RX_QUEUE_2_DROPPED: + tcnt = s->rx_dropped[2]; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_ds_stats_str[type], tcnt); + case NSS_STATS_NODE_RX_QUEUE_3_DROPPED: + tcnt = s->rx_dropped[3]; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_ds_stats_str[type], tcnt); +#endif + case NSS_GRE_REDIR_LAG_DS_STATS_DST_INVALID: + tcnt = s->dst_invalid; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_ds_stats_str[type], tcnt); + case NSS_GRE_REDIR_LAG_DS_STATS_EXCEPTION_PKT: + tcnt = s->exception_cnt; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_ds_stats_str[type], tcnt); + + default: + return 0; + } +} + +/* + * nss_gre_redir_lag_ds_stats_read() + * Read gre_redir_lag_ds tunnel stats. + */ +static ssize_t nss_gre_redir_lag_ds_cmn_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + ssize_t bytes_read = 0; + struct nss_stats_data *data = fp->private_data; + struct nss_gre_redir_lag_ds_tun_stats stats; + size_t bytes; + char line[80]; + int start; + + while (data->index < NSS_GRE_REDIR_LAG_MAX_NODE) { + if (nss_gre_redir_lag_ds_get_cmn_stats(&stats, data->index)) { + break; + } + + data->index++; + } + + if (data->index == NSS_GRE_REDIR_LAG_MAX_NODE) { + return 0; + } + + bytes = snprintf(line, sizeof(line), "\nTunnel stats for \n"); + if (copy_to_user(ubuf, line, bytes) != 0) { + return -EFAULT; + } + + bytes_read += bytes; + start = NSS_STATS_NODE_RX_PKTS; + while (bytes_read < sz && start < NSS_GRE_REDIR_LAG_DS_STATS_MAX) { + bytes = nss_gre_redir_lag_ds_cmn_stats_read_entry(line, sizeof(line), start, &stats); + + if ((bytes_read + bytes) > sz) + break; + + if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) { + return -EFAULT; + } + + bytes_read += bytes; + start++; + } + + data->index++; + return bytes_read; +} + +/* + * nss_gre_redir_lag_ds_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(gre_redir_lag_ds_cmn) + +/* + * nss_gre_redir_lag_ds_stats_dentry_create() + * Create debugfs directory entry. + */ +struct dentry *nss_gre_redir_lag_ds_stats_dentry_create(void) +{ + struct dentry *gre_redir; + struct dentry *cmn_stats; + + gre_redir = nss_gre_redir_get_dentry(); + if (unlikely(!gre_redir)) { + nss_warning("Failed to retrieve directory entry qca-nss-drv/stats/gre_redir/\n"); + return NULL; + } + + cmn_stats = debugfs_create_file("lag_ds_cmn_stats", 0400, gre_redir, + &nss_top_main, &nss_gre_redir_lag_ds_cmn_stats_ops); + if (unlikely(!cmn_stats)) { + nss_warning("Failed to create qca-nss-drv/stats/gre_redir/lag_ds_cmn_stats file\n"); + return NULL; + } + + return cmn_stats; +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_ds_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_ds_stats.h new file mode 100644 index 000000000..fe79016cc --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_ds_stats.h @@ -0,0 +1,30 @@ +/* + ****************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_GRE_REDIR_LAG_DS_STATS_H__ +#define __NSS_GRE_REDIR_LAG_DS_STATS_H__ + +/* + * GRE redirect LAG downstream statistics + */ +enum nss_gre_redir_lag_ds_stats_types { + NSS_GRE_REDIR_LAG_DS_STATS_DST_INVALID = NSS_STATS_NODE_MAX, + NSS_GRE_REDIR_LAG_DS_STATS_EXCEPTION_PKT, + NSS_GRE_REDIR_LAG_DS_STATS_MAX, +}; + +extern struct dentry *nss_gre_redir_lag_ds_stats_dentry_create(void); +#endif diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_us.c b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_us.c new file mode 100644 index 000000000..63a63adac --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_us.c @@ -0,0 +1,746 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_gre_redir_lag_us_stats.h" +#include "nss_gre_redir_lag_us_log.h" + +#define NSS_GRE_REDIR_LAG_US_TX_TIMEOUT 3000 /* 3 Seconds */ +#define NSS_GRE_REDIR_LAG_US_STATS_SYNC_PERIOD msecs_to_jiffies(4000) +#define NSS_GRE_REDIR_LAG_US_STATS_SYNC_UDELAY 4000 + +/* + * nss_gre_redir_lag_us_pvt_sync_stats + * Hash statistics synchronization context. + */ +struct nss_gre_redir_lag_us_pvt_sync_stats { + struct delayed_work nss_gre_redir_lag_us_work; /**< Delayed work per LAG US node. */ + struct nss_gre_redir_lag_us_msg db_sync_msg; /**< Hash statistics message. */ + struct nss_gre_redir_lag_us_tunnel_stats tun_stats; /**< GRE redirect LAG common statistics. */ + nss_gre_redir_lag_us_msg_callback_t cb; /**< Callback for hash query message. */ + void *app_data; /**< app_data for hash query message. */ + uint32_t ifnum; /**< NSS interface number. */ + bool valid; /**< Valid flag. */ +}; + +/* + * Common context for stats update. + */ +static struct nss_gre_redir_lag_us_cmn_ctx { + spinlock_t nss_gre_redir_lag_us_stats_lock; /**< Spin lock. */ + struct workqueue_struct *nss_gre_redir_lag_us_wq; /**< Work queue. */ + struct nss_gre_redir_lag_us_pvt_sync_stats stats_ctx[NSS_GRE_REDIR_LAG_MAX_NODE]; +} cmn_ctx; + +/* + * Sync response context. + */ +static struct { + struct semaphore sem; + struct completion complete; + int response; + nss_gre_redir_lag_us_msg_callback_t *cb; + void *app_data; +} nss_gre_redir_lag_us_sync_ctx; + +/* + * nss_gre_redir_lag_us_callback() + * Callback to handle the completion of HLOS-->NSS messages. + */ +static void nss_gre_redir_lag_us_callback(void *app_data, struct nss_gre_redir_lag_us_msg *nim) +{ + nss_gre_redir_lag_us_msg_callback_t callback = (nss_gre_redir_lag_us_msg_callback_t)nss_gre_redir_lag_us_sync_ctx.cb; + void *data = nss_gre_redir_lag_us_sync_ctx.app_data; + + nss_gre_redir_lag_us_sync_ctx.cb = NULL; + nss_gre_redir_lag_us_sync_ctx.app_data = NULL; + + if (nim->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("GRE redir LAG US Error response %d\n", nim->cm.response); + nss_gre_redir_lag_us_sync_ctx.response = NSS_TX_FAILURE; + } else { + nss_gre_redir_lag_us_sync_ctx.response = NSS_TX_SUCCESS; + } + + if (callback) { + callback(data, &nim->cm); + } + + complete(&nss_gre_redir_lag_us_sync_ctx.complete); +} + +/* + * nss_gre_redir_lag_us_get_node_idx() + * Returns index of statistics context. + */ +static bool nss_gre_redir_lag_us_get_node_idx(uint32_t ifnum, uint32_t *idx) +{ + uint32_t node_idx; + for (node_idx = 0; node_idx < NSS_GRE_REDIR_LAG_MAX_NODE; node_idx++) { + if ((cmn_ctx.stats_ctx[node_idx].valid) && (cmn_ctx.stats_ctx[node_idx].ifnum == ifnum)) { + *idx = node_idx; + return true; + } + } + + return false; +} + +/* + * nss_gre_redir_lag_us_update_sync_stats() + * Update synchonized statistics. + */ +static void nss_gre_redir_lag_us_update_sync_stats(struct nss_ctx_instance *nss_ctx, struct nss_gre_redir_lag_us_cmn_sync_stats_msg *ngss, + uint32_t ifnum) +{ + int idx, j; + + spin_lock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + if (!nss_gre_redir_lag_us_get_node_idx(ifnum, &idx)) { + spin_unlock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + nss_warning("%px: Unable to update hash stats msg. Stats context not found.\n", nss_ctx); + return; + } + + cmn_ctx.stats_ctx[idx].tun_stats.tx_packets += ngss->node_stats.tx_packets; + cmn_ctx.stats_ctx[idx].tun_stats.tx_bytes += ngss->node_stats.tx_bytes; + cmn_ctx.stats_ctx[idx].tun_stats.rx_packets += ngss->node_stats.rx_packets; + cmn_ctx.stats_ctx[idx].tun_stats.rx_bytes += ngss->node_stats.rx_bytes; + for (j = 0; j < NSS_MAX_NUM_PRI; j++) { + cmn_ctx.stats_ctx[idx].tun_stats.rx_dropped[j] += ngss->node_stats.rx_dropped[j]; + } + cmn_ctx.stats_ctx[idx].tun_stats.us_stats.amsdu_pkts += ngss->us_stats.amsdu_pkts; + cmn_ctx.stats_ctx[idx].tun_stats.us_stats.amsdu_pkts_enqueued += ngss->us_stats.amsdu_pkts_enqueued; + cmn_ctx.stats_ctx[idx].tun_stats.us_stats.amsdu_pkts_exceptioned += ngss->us_stats.amsdu_pkts_exceptioned; + cmn_ctx.stats_ctx[idx].tun_stats.us_stats.exceptioned += ngss->us_stats.exceptioned; + cmn_ctx.stats_ctx[idx].tun_stats.us_stats.freed += ngss->us_stats.freed; + cmn_ctx.stats_ctx[idx].tun_stats.db_stats.add_attempt += ngss->db_stats.add_attempt; + cmn_ctx.stats_ctx[idx].tun_stats.db_stats.add_success += ngss->db_stats.add_success; + cmn_ctx.stats_ctx[idx].tun_stats.db_stats.add_fail_table_full += ngss->db_stats.add_fail_table_full; + cmn_ctx.stats_ctx[idx].tun_stats.db_stats.add_fail_exists += ngss->db_stats.add_fail_exists; + cmn_ctx.stats_ctx[idx].tun_stats.db_stats.del_attempt += ngss->db_stats.del_attempt; + cmn_ctx.stats_ctx[idx].tun_stats.db_stats.del_success += ngss->db_stats.del_success; + cmn_ctx.stats_ctx[idx].tun_stats.db_stats.del_fail_not_found += ngss->db_stats.del_fail_not_found; + spin_unlock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); +} + +/* + * nss_gre_redir_lag_us_hash_update_stats_req() + * Update query hash message's index for next request. + */ +static void nss_gre_redir_lag_us_hash_update_stats_req(struct nss_ctx_instance *nss_ctx, struct nss_gre_redir_lag_us_msg *ngrm) +{ + uint32_t ifnum = ngrm->cm.interface; + uint32_t idx, sync_delay = NSS_GRE_REDIR_LAG_US_STATS_SYNC_PERIOD; + struct nss_gre_redir_lag_us_hash_stats_query_msg *nim = &ngrm->msg.hash_stats; + + spin_lock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + if (!nss_gre_redir_lag_us_get_node_idx(ifnum, &idx)) { + spin_unlock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + nss_warning("%px: Unable to update hash stats msg. Stats context not found.\n", nss_ctx); + return; + } + + /* + * Update start index for next iteration of the query. + */ + if (ngrm->cm.response == NSS_CMN_RESPONSE_ACK) { + cmn_ctx.stats_ctx[idx].db_sync_msg.msg.hash_stats.db_entry_idx = nim->db_entry_next; + } else { + cmn_ctx.stats_ctx[idx].db_sync_msg.msg.hash_stats.db_entry_idx = 0; + } + + /* + * If more hash entries are to be fetched from FW, queue work with delay of one eighth of + * the polling period. Else, schedule work with a delay of polling period. + */ + if (cmn_ctx.stats_ctx[idx].db_sync_msg.msg.hash_stats.db_entry_idx) { + sync_delay = NSS_GRE_REDIR_LAG_US_STATS_SYNC_PERIOD / 8; + } + + queue_delayed_work(cmn_ctx.nss_gre_redir_lag_us_wq, &(cmn_ctx.stats_ctx[idx].nss_gre_redir_lag_us_work), + sync_delay); + spin_unlock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); +} + +/* + * nss_gre_redir_lag_us_verify_ifnum() + * Verify interface type. + */ +static bool nss_gre_redir_lag_us_verify_ifnum(uint32_t if_num) +{ + return nss_dynamic_interface_get_type(nss_gre_redir_lag_us_get_context(), if_num) == NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_US; +} + +/* + * nss_gre_redir_lag_us_handler() + * Handle NSS -> HLOS messages for gre tunnel + */ +static void nss_gre_redir_lag_us_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + void *ctx; + struct nss_gre_redir_lag_us_msg *ngrm = (struct nss_gre_redir_lag_us_msg *)ncm; + nss_gre_redir_lag_us_msg_callback_t cb; + + /* + * Interface should be a dynamic interface of type NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_US. + */ + BUG_ON(!nss_gre_redir_lag_us_verify_ifnum(ncm->interface)); + + /* + * Trace messages. + */ + nss_gre_redir_lag_us_log_rx_msg(ngrm); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_GRE_REDIR_LAG_US_MAX_MSG_TYPES) { + nss_warning("%px: received invalid message %d for gre interface\n", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_gre_redir_lag_us_msg)) { + nss_warning("%px: Length of message is greater than required: %d\n", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Update the callback and app_data for NOTIFY messages, GRE sends all notify messages + * to the same callback/app_data. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_core_get_msg_handler(nss_ctx, ncm->interface); + ncm->app_data = (nss_ptr_t)nss_ctx->nss_rx_interface_handlers[ncm->interface].app_data; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + switch (ncm->type) { + case NSS_GRE_REDIR_LAG_US_CMN_STATS_SYNC_MSG: + nss_gre_redir_lag_us_update_sync_stats(nss_ctx, &ngrm->msg.us_sync_stats, ncm->interface); + break; + + case NSS_GRE_REDIR_LAG_US_DB_HASH_NODE_MSG: + nss_gre_redir_lag_us_hash_update_stats_req(nss_ctx, ngrm); + break; + } + + /* + * Do we have a call back + */ + if (!ncm->cb) { + return; + } + + /* + * callback + */ + cb = (nss_gre_redir_lag_us_msg_callback_t)ncm->cb; + ctx = (void *)ncm->app_data; + + /* + * call gre tunnel callback + */ + cb(ctx, ncm); +} + +/* + * nss_gre_redir_lag_us_tx_msg_with_size() + * Transmit a GRE message to NSSFW with size. + */ +static nss_tx_status_t nss_gre_redir_lag_us_tx_msg_with_size(struct nss_ctx_instance *nss_ctx, struct nss_gre_redir_lag_us_msg *msg, uint32_t size) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Sanity check the message. Interface should be a dynamic + * interface of type NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_US. + */ + if (!nss_gre_redir_lag_us_verify_ifnum(ncm->interface)) { + nss_warning("%px: tx request for another interface: %d\n", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type >= NSS_GRE_REDIR_LAG_US_MAX_MSG_TYPES) { + nss_warning("%px: message type out of range: %d\n", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), size); +} + +/* + * nss_gre_redir_lag_us_tx_msg_sync_with_size() + * Transmit a GRE LAG message to NSS firmware synchronously with size. + */ +static nss_tx_status_t nss_gre_redir_lag_us_tx_msg_sync_with_size(struct nss_ctx_instance *nss_ctx, + struct nss_gre_redir_lag_us_msg *ngrm, uint32_t size) +{ + nss_tx_status_t status; + int ret = 0; + + down(&nss_gre_redir_lag_us_sync_ctx.sem); + + /* + * Save the client's callback, and initialize the message + * with the callback which releases the semaphore after message + * response is received, This callback will inturn call the client's + * callback. + */ + nss_gre_redir_lag_us_sync_ctx.cb = (void *)ngrm->cm.cb; + nss_gre_redir_lag_us_sync_ctx.app_data = (void *)ngrm->cm.app_data; + ngrm->cm.cb = (nss_ptr_t)nss_gre_redir_lag_us_callback; + ngrm->cm.app_data = (nss_ptr_t)NULL; + + status = nss_gre_redir_lag_us_tx_msg_with_size(nss_ctx, ngrm, size); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: gre_tx_msg failed\n", nss_ctx); + up(&nss_gre_redir_lag_us_sync_ctx.sem); + return status; + } + + ret = wait_for_completion_timeout(&nss_gre_redir_lag_us_sync_ctx.complete, msecs_to_jiffies(NSS_GRE_REDIR_LAG_US_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: GRE LAG US tx sync failed due to timeout\n", nss_ctx); + nss_gre_redir_lag_us_sync_ctx.response = NSS_TX_FAILURE; + } + + status = nss_gre_redir_lag_us_sync_ctx.response; + up(&nss_gre_redir_lag_us_sync_ctx.sem); + return status; +} + +/* + * nss_gre_redir_lag_us_stats_sync_req_work() + * Work function for hash statistics synchronization. + */ +static void nss_gre_redir_lag_us_stats_sync_req_work(struct work_struct *work) +{ + struct delayed_work *d_work = container_of(work, struct delayed_work, work); + struct nss_gre_redir_lag_us_pvt_sync_stats *sync_ctx = container_of(d_work, struct nss_gre_redir_lag_us_pvt_sync_stats, + nss_gre_redir_lag_us_work); + struct nss_gre_redir_lag_us_hash_stats_query_msg *nicsm_req = &(sync_ctx->db_sync_msg.msg.hash_stats); + nss_tx_status_t nss_tx_status; + nss_gre_redir_lag_us_msg_callback_t cb; + void *app_data; + struct nss_ctx_instance *nss_ctx __maybe_unused = nss_gre_redir_lag_us_get_context(); + int retry = NSS_GRE_REDIR_LAG_US_STATS_SYNC_RETRY; + + spin_lock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + cb = sync_ctx->cb; + app_data = sync_ctx->app_data; + spin_unlock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + + nss_cmn_msg_init(&(sync_ctx->db_sync_msg.cm), sync_ctx->ifnum, + NSS_GRE_REDIR_LAG_US_DB_HASH_NODE_MSG, sizeof(struct nss_gre_redir_lag_us_hash_stats_query_msg), + cb, app_data); + while (retry) { + nss_tx_status = nss_gre_redir_lag_us_tx_msg_sync_with_size(nss_ctx, &(sync_ctx->db_sync_msg), PAGE_SIZE); + if (nss_tx_status == NSS_TX_SUCCESS) { + return; + } + + retry--; + nss_warning("%px: TX_NOT_OKAY, try again later\n", nss_ctx); + usleep_range(100, 200); + } + + /* + * TX failed after retries, take fresh start. + */ + nicsm_req->count = 0; + nicsm_req->db_entry_idx = 0; + queue_delayed_work(cmn_ctx.nss_gre_redir_lag_us_wq, &(sync_ctx->nss_gre_redir_lag_us_work), NSS_GRE_REDIR_LAG_US_STATS_SYNC_PERIOD); +} + +/* + * nss_gre_redir_lag_us_sync_work_init() + * Initialize work. + */ +static bool nss_gre_redir_lag_us_sync_work_init(uint32_t ifnum) +{ + struct nss_gre_redir_lag_us_hash_stats_query_msg *hash_stats_msg; + struct nss_ctx_instance __maybe_unused *nss_ctx = nss_gre_redir_lag_us_get_context(); + int ret, idx; + + spin_lock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + if (!nss_gre_redir_lag_us_get_node_idx(ifnum, &idx)) { + spin_unlock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + nss_warning("%px: Unable to init work. Stats context not found.\n", nss_ctx); + return false; + } + + hash_stats_msg = &(cmn_ctx.stats_ctx[idx].db_sync_msg.msg.hash_stats); + hash_stats_msg->db_entry_idx = 0; + INIT_DELAYED_WORK(&(cmn_ctx.stats_ctx[idx].nss_gre_redir_lag_us_work), nss_gre_redir_lag_us_stats_sync_req_work); + ret = queue_delayed_work(cmn_ctx.nss_gre_redir_lag_us_wq, + &(cmn_ctx.stats_ctx[idx].nss_gre_redir_lag_us_work), NSS_GRE_REDIR_LAG_US_STATS_SYNC_PERIOD); + if (!ret) { + spin_unlock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + nss_warning("%px: Unable to queue work function to work queue\n", nss_ctx); + return false; + } + + spin_unlock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + return true; +} + +/* + * nss_gre_redir_lag_us_unregister_if() + * Unregister GRE redirect LAG upstream node. + */ +static enum nss_gre_redir_lag_err_types nss_gre_redir_lag_us_unregister_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx __maybe_unused = nss_gre_redir_lag_us_get_context(); + uint32_t status; + int idx; + + nss_assert(nss_ctx); + nss_assert(!nss_gre_redir_lag_us_verify_ifnum(if_num)); + + status = nss_core_unregister_msg_handler(nss_ctx, if_num); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Not able to unregister handler for gre_lag interface %d with NSS core\n", nss_ctx, if_num); + return NSS_GRE_REDIR_LAG_ERR_CORE_UNREGISTER_FAILED; + } + + status = nss_core_unregister_handler(nss_ctx, if_num); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Not able to unregister handler for gre_lag interface %d with NSS core\n", nss_ctx, if_num); + return NSS_GRE_REDIR_LAG_ERR_CORE_UNREGISTER_FAILED; + } + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + + spin_lock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + if (!nss_gre_redir_lag_us_get_node_idx(if_num, &idx)) { + spin_unlock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + nss_warning("Stats context not found.\n"); + return NSS_GRE_REDIR_LAG_ERR_STATS_INDEX_NOT_FOUND; + } + + cmn_ctx.stats_ctx[idx].cb = NULL; + cmn_ctx.stats_ctx[idx].app_data = NULL; + cmn_ctx.stats_ctx[idx].valid = false; + spin_unlock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + + /* + * Work is per LAG US node. Cancel works for this node. + */ + cancel_delayed_work_sync(&(cmn_ctx.stats_ctx[idx].nss_gre_redir_lag_us_work)); + return NSS_GRE_REDIR_LAG_SUCCESS; +} + +/* + * nss_gre_redir_lag_us_register_if() + * Register GRE redirect LAG upstream node. + */ +static struct nss_ctx_instance *nss_gre_redir_lag_us_register_if(uint32_t if_num, struct net_device *netdev, + nss_gre_redir_lag_us_data_callback_t cb_func_data, + nss_gre_redir_lag_us_msg_callback_t cb_func_msg, uint32_t features, uint32_t type, void *app_ctx) +{ + struct nss_ctx_instance *nss_ctx = nss_gre_redir_lag_us_get_context(); + uint32_t status; + int i; + nss_assert(nss_ctx); + nss_assert(!nss_gre_redir_lag_us_verify_ifnum(if_num)); + + spin_lock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + for (i = 0; i < NSS_GRE_REDIR_LAG_MAX_NODE; i++) { + if (!cmn_ctx.stats_ctx[i].valid) { + cmn_ctx.stats_ctx[i].ifnum = if_num; + cmn_ctx.stats_ctx[i].valid = true; + cmn_ctx.stats_ctx[i].cb = cb_func_msg; + cmn_ctx.stats_ctx[i].app_data = app_ctx; + break; + } + } + + spin_unlock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + if (i == NSS_GRE_REDIR_LAG_MAX_NODE) { + nss_warning("Maximum number of LAG nodes are already present.\n"); + return NULL; + } + + /* + * Registering handler for sending tunnel interface msgs to NSS. + */ + status = nss_core_register_handler(nss_ctx, if_num, nss_gre_redir_lag_us_msg_handler, app_ctx); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Not able to register handler for gre_lag interface %d with NSS core\n", nss_ctx, if_num); + spin_lock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + cmn_ctx.stats_ctx[i].valid = false; + cmn_ctx.stats_ctx[i].cb = NULL; + cmn_ctx.stats_ctx[i].app_data = NULL; + spin_unlock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + return NULL; + } + + /* + * Registering handler for sending tunnel interface msgs to NSS. + */ + status = nss_core_register_msg_handler(nss_ctx, if_num, cb_func_msg); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_core_unregister_handler(nss_ctx, if_num); + nss_warning("%px: Not able to register handler for gre_lag interface %d with NSS core\n", nss_ctx, if_num); + spin_lock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + cmn_ctx.stats_ctx[i].valid = false; + cmn_ctx.stats_ctx[i].cb = NULL; + cmn_ctx.stats_ctx[i].app_data = NULL; + spin_unlock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + return NULL; + } + + nss_core_register_subsys_dp(nss_ctx, if_num, cb_func_data, NULL, NULL, netdev, features); + nss_core_set_subsys_dp_type(nss_ctx, netdev, if_num, type); + return nss_ctx; +} + +/* + * nss_gre_redir_lag_us_get_context() + * Retrieve context for GRE redirect LAG upstream node. + */ +struct nss_ctx_instance *nss_gre_redir_lag_us_get_context(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.gre_redir_lag_us_handler_id]; +} +EXPORT_SYMBOL(nss_gre_redir_lag_us_get_context); + +/* + * nss_gre_redir_lag_us_configure_node() + * Configure upstream lag node. + */ +bool nss_gre_redir_lag_us_configure_node(uint32_t ifnum, + struct nss_gre_redir_lag_us_config_msg *ngluc) +{ + struct nss_gre_redir_lag_us_msg *config; + uint32_t len, iftype, idx = 0, i; + bool ret; + nss_tx_status_t status; + struct nss_ctx_instance *nss_ctx __maybe_unused = nss_ctx = nss_gre_redir_lag_us_get_context(); + + if (!nss_ctx) { + nss_warning("Unable to retrieve NSS context.\n"); + return false; + } + + config = (struct nss_gre_redir_lag_us_msg *) kzalloc(sizeof(struct nss_gre_redir_lag_us_msg), GFP_KERNEL); + if (!config) { + nss_warning("%px: Unable to allocate memory to send configure message.\n", nss_ctx); + return false; + } + + iftype = nss_dynamic_interface_get_type(nss_ctx, ifnum); + if (iftype != NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_US) { + nss_warning("%px: Incorrect interface type %u\n", nss_ctx, iftype); + kfree(config); + return false; + } + + if (!ngluc) { + nss_warning("%px: Pointer to GRE redir LAG US message is NULL.\n", nss_ctx); + kfree(config); + return false; + } + + if ((ngluc->num_slaves < NSS_GRE_REDIR_LAG_MIN_SLAVE) || (ngluc->num_slaves > NSS_GRE_REDIR_LAG_MAX_SLAVE)) { + nss_warning("%px: Number of slaves is not in reange\n", nss_ctx); + kfree(config); + return false; + } + + ret = nss_gre_redir_lag_us_sync_work_init(ifnum); + if (!ret) { + nss_warning("%px: Unable to initialize work queue\n", nss_ctx); + kfree(config); + return false; + } + + len = sizeof(struct nss_gre_redir_lag_us_msg) - sizeof(struct nss_cmn_msg); + nss_cmn_msg_init(&config->cm, ifnum, NSS_GRE_REDIR_LAG_US_CONFIG_MSG, len, NULL, NULL); + config->msg.config_us.hash_mode = ngluc->hash_mode; + config->msg.config_us.num_slaves = ngluc->num_slaves; + for (i = 0; i < ngluc->num_slaves; i++) { + config->msg.config_us.if_num[i] = ngluc->if_num[i]; + } + + status = nss_gre_redir_lag_us_tx_msg_sync(nss_ctx, config); + kfree(config); + if (status == NSS_TX_SUCCESS) { + return true; + } + + spin_lock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + if (nss_gre_redir_lag_us_get_node_idx(ifnum, &idx)) { + spin_unlock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + nss_warning("%px: Stats context not found.\n", nss_ctx); + return false; + } + + spin_unlock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + + /* + * Work is per LAG US node. Cancel work as configuration failed. + */ + cancel_delayed_work_sync(&(cmn_ctx.stats_ctx[idx].nss_gre_redir_lag_us_work)); + nss_warning("%px: Unable to configure upstream lag node %d.\n", nss_ctx, ifnum); + return false; +} +EXPORT_SYMBOL(nss_gre_redir_lag_us_configure_node); + +/* + * nss_gre_redir_lag_us_get_cmn_stats() + * Common upstream statistics. + */ +bool nss_gre_redir_lag_us_get_cmn_stats(struct nss_gre_redir_lag_us_tunnel_stats *cmn_stats, uint32_t index) +{ + if (index >= NSS_GRE_REDIR_LAG_MAX_NODE) { + nss_warning("Index is out of valid range %u\n", index); + return false; + } + + spin_lock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + if (!cmn_ctx.stats_ctx[index].valid) { + spin_unlock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + nss_warning("Common context not found for the index %u\n", index); + return false; + } + + memcpy((void *)cmn_stats, (void *)&(cmn_ctx.stats_ctx[index].tun_stats), sizeof(*cmn_stats)); + spin_unlock_bh(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); + return true; +} + +/* + * nss_gre_redir_lag_us_tx_msg() + * Transmit a GRE LAG message to NSS firmware asynchronously. + */ +nss_tx_status_t nss_gre_redir_lag_us_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_gre_redir_lag_us_msg *ngrm) +{ + /* + * Trace messages. + */ + nss_gre_redir_lag_us_log_tx_msg(ngrm); + + return nss_gre_redir_lag_us_tx_msg_with_size(nss_ctx, ngrm, NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_gre_redir_lag_us_tx_msg); + +/* + * nss_gre_redir_lag_us_tx_msg_sync() + * Transmit a GRE lag message to NSS firmware synchronously. + */ +nss_tx_status_t nss_gre_redir_lag_us_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_redir_lag_us_msg *ngrm) +{ + return nss_gre_redir_lag_us_tx_msg_sync_with_size(nss_ctx, ngrm, NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_gre_redir_lag_us_tx_msg_sync); + +/* + * nss_gre_redir_lag_us_unregister_and_dealloc() + * Unregister and deallocate nss gre redirect LAG US node. + */ +enum nss_gre_redir_lag_err_types nss_gre_redir_lag_us_unregister_and_dealloc(uint32_t ifnum) +{ + uint32_t ret; + struct nss_ctx_instance *nss_ctx __maybe_unused = nss_gre_redir_lag_us_get_context(); + nss_tx_status_t status; + + if (!nss_gre_redir_lag_us_verify_ifnum(ifnum)) { + nss_warning("%px: Unknown interface type %u.\n", nss_ctx, ifnum); + return NSS_GRE_REDIR_LAG_ERR_INCORRECT_IFNUM; + } + + ret = nss_gre_redir_lag_us_unregister_if(ifnum); + if (ret) { + nss_warning("%px: Unable to unregister interface %u.\n", nss_ctx, ifnum); + return ret; + } + + status = nss_dynamic_interface_dealloc_node(ifnum, NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_US); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: Unable to deallocate node %u\n", nss_ctx, ifnum); + return NSS_GRE_REDIR_LAG_ERR_DEALLOC_FAILED; + } + + return NSS_GRE_REDIR_LAG_SUCCESS; +} +EXPORT_SYMBOL(nss_gre_redir_lag_us_unregister_and_dealloc); + +/* + * nss_gre_redir_lag_us_alloc_and_register_node() + * Allocates and registers GRE upstream type dynamic nodes with NSS. + */ +int nss_gre_redir_lag_us_alloc_and_register_node(struct net_device *dev, + nss_gre_redir_lag_us_data_callback_t cb_func_data, + nss_gre_redir_lag_us_msg_callback_t cb_func_msg, void *app_ctx) +{ + int ifnum; + nss_tx_status_t status; + struct nss_ctx_instance *nss_ctx; + + ifnum = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_US); + if (ifnum == -1) { + nss_warning("%px: Unable to allocate GRE_LAG node of type = %u\n", dev, NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_US); + return -1; + } + + nss_ctx = nss_gre_redir_lag_us_register_if(ifnum, dev, cb_func_data, + cb_func_msg, 0, NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_US, app_ctx); + if (!nss_ctx) { + nss_warning("%px: Unable to register GRE_LAG node of type = %u\n", dev, NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_US); + status = nss_dynamic_interface_dealloc_node(ifnum, NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_LAG_US); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: Unable to deallocate node.\n", dev); + } + + return -1; + } + + return ifnum; +} +EXPORT_SYMBOL(nss_gre_redir_lag_us_alloc_and_register_node); + +/* + * nss_gre_redir_lag_us_register_handler() + * Registering handler for sending msg to base gre_lag node on NSS. + */ +void nss_gre_redir_lag_us_register_handler(void) +{ + struct dentry *d_entry = nss_gre_redir_lag_us_stats_dentry_create(); + + if (!d_entry) { + nss_warning(" Unable to create debugfs entry for LAG US node.\n"); + return; + } + + cmn_ctx.nss_gre_redir_lag_us_wq = create_singlethread_workqueue("nss_gre_redir_lag_us_workqueue"); + if (!cmn_ctx.nss_gre_redir_lag_us_wq) { + debugfs_remove_recursive(d_entry); + nss_warning("Unable to create workqueue for LAG US node.\n"); + return; + } + + nss_gre_redir_lag_us_sync_ctx.cb = NULL; + nss_gre_redir_lag_us_sync_ctx.app_data = NULL; + sema_init(&nss_gre_redir_lag_us_sync_ctx.sem, 1); + init_completion(&nss_gre_redir_lag_us_sync_ctx.complete); + spin_lock_init(&cmn_ctx.nss_gre_redir_lag_us_stats_lock); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_us_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_us_log.c new file mode 100644 index 000000000..8601979d4 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_us_log.c @@ -0,0 +1,191 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_gre_redir_lag_us_log.c + * NSS GRE REDIR LAG US logger file. + */ + +#include "nss_core.h" + +/* + * nss_gre_redir_lag_us_log_message_types_str + * GRE REDIR LAG US message strings + */ +static int8_t *nss_gre_redir_lag_us_log_message_types_str[NSS_GRE_REDIR_LAG_US_MAX_MSG_TYPES] __maybe_unused = { + "GRE REDIR LAG US config Message", + "GRE REDIR LAG US add hash node message", + "GRE REDIR LAG US delete hash node message", + "GRE REDIR LAG US query hash node message", + "GRE REDIR LAG US stats sync message", + "GRE REDIR LAG US DB hash node message", +}; + +/* + * nss_gre_redir_lag_us_log_error_response_types_str + * Strings for error types for GRE REDIR LAG US messages + */ +static int8_t *nss_gre_redir_lag_us_log_error_response_types_str[NSS_GRE_REDIR_LAG_ERR_MAX] __maybe_unused = { + "GRE REDIR LAG Success", + "GRE REDIR LAG Incorrect Interface", + "GRE REDIR LAG US Core Unregister Failed", + "GRE REDIR LAG US STats Index Not Found", + "GRE REDIR LAG Dealloc Failed", +}; + +/* + * nss_gre_redir_lag_us_log_config_msg() + * Log NSS GRE REDIR LAG US config message. + */ +static void nss_gre_redir_lag_us_log_config_msg(struct nss_gre_redir_lag_us_msg *ngm) +{ + struct nss_gre_redir_lag_us_config_msg *ngcm __maybe_unused = &ngm->msg.config_us; + nss_trace("%px: NSS GRE REDIR LAG Config Message:\n" + "GRE REDIR LAG US Hash Mode: %d\n" + "GRE REDIR LAG US Number of Slaves: %d\n" + "GRE REDIR LAG US Interface Number: %px\n", + ngcm, ngcm->hash_mode, ngcm->num_slaves, + ngcm->if_num); +} + +/* + * nss_gre_redir_lag_us_log_add_hash_node_msg() + * Log NSS GRE REDIR LAG US add hash node message. + */ +static void nss_gre_redir_lag_us_log_add_hash_node_msg(struct nss_gre_redir_lag_us_msg *ngm) +{ + struct nss_gre_redir_lag_us_add_hash_node_msg *ngam __maybe_unused = &ngm->msg.add_hash; + nss_trace("%px: NSS GRE REDIR LAG Add Hash Node Message:\n" + "GRE REDIR LAG US Interface Number: %d\n" + "GRE REDIR LAG US Source MAC: %px\n" + "GRE REDIR LAG US Destination MAC: %px\n", + ngam, ngam->if_num, ngam->src_mac, + ngam->dest_mac); +} + +/* + * nss_gre_redir_lag_us_log_del_hash_node_msg() + * Log NSS GRE REDIR LAG US del hash node message. + */ +static void nss_gre_redir_lag_us_log_del_hash_node_msg(struct nss_gre_redir_lag_us_msg *ngm) +{ + struct nss_gre_redir_lag_us_del_hash_node_msg *ngdm __maybe_unused = &ngm->msg.del_hash; + nss_trace("%px: NSS GRE REDIR LAG Del Hash Node Message:\n" + "GRE REDIR LAG US Source MAC: %px\n" + "GRE REDIR LAG US Destination MAC: %px\n", + ngdm, ngdm->src_mac,ngdm->dest_mac); +} + +/* + * nss_gre_redir_lag_us_log_query_hash_node_msg() + * Log NSS GRE REDIR LAG US query hash node message. + */ +static void nss_gre_redir_lag_us_log_query_hash_node_msg(struct nss_gre_redir_lag_us_msg *ngm) +{ + struct nss_gre_redir_lag_us_query_hash_node_msg *ngqm __maybe_unused = &ngm->msg.query_hash; + nss_trace("%px: NSS GRE REDIR LAG Query Hash Node Message:\n" + "GRE REDIR LAG US Source MAC: %px\n" + "GRE REDIR LAG US Destination MAC: %px\n" + "GRE REDIR LAG US Interface Number: %d\n", + ngqm, ngqm->src_mac, ngqm->dest_mac, + ngqm->ifnum); +} + +/* + * nss_gre_redir_lag_us_log_verbose() + * Log message contents. + */ +static void nss_gre_redir_lag_us_log_verbose(struct nss_gre_redir_lag_us_msg *ngm) +{ + switch (ngm->cm.type) { + case NSS_GRE_REDIR_LAG_US_CONFIG_MSG: + nss_gre_redir_lag_us_log_config_msg(ngm); + break; + + case NSS_GRE_REDIR_LAG_US_ADD_HASH_NODE_MSG: + nss_gre_redir_lag_us_log_add_hash_node_msg(ngm); + break; + + case NSS_GRE_REDIR_LAG_US_DEL_HASH_NODE_MSG: + nss_gre_redir_lag_us_log_del_hash_node_msg(ngm); + break; + + case NSS_GRE_REDIR_LAG_US_QUERY_HASH_NODE_MSG: + nss_gre_redir_lag_us_log_query_hash_node_msg(ngm); + break; + + case NSS_GRE_REDIR_LAG_US_CMN_STATS_SYNC_MSG: + case NSS_GRE_REDIR_LAG_US_DB_HASH_NODE_MSG: + /* + * No log for valid stats message. + */ + break; + + default: + nss_warning("%px: Invalid message type\n", ngm); + break; + } +} + +/* + * nss_gre_redir_lag_us_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_gre_redir_lag_us_log_tx_msg(struct nss_gre_redir_lag_us_msg *ngm) +{ + if (ngm->cm.type >= NSS_GRE_REDIR_LAG_US_MAX_MSG_TYPES) { + nss_warning("%px: Invalid message type\n", ngm); + return; + } + + nss_info("%px: type[%d]:%s\n", ngm, ngm->cm.type, nss_gre_redir_lag_us_log_message_types_str[ngm->cm.type]); + nss_gre_redir_lag_us_log_verbose(ngm); +} + +/* + * nss_gre_redir_lag_us_log_rx_msg() + * Log messages received from FW. + */ +void nss_gre_redir_lag_us_log_rx_msg(struct nss_gre_redir_lag_us_msg *ngm) +{ + if (ngm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", ngm); + return; + } + + if (ngm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ngm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", ngm, ngm->cm.type, + nss_gre_redir_lag_us_log_message_types_str[ngm->cm.type], + ngm->cm.response, nss_cmn_response_str[ngm->cm.response]); + goto verbose; + } + + if (ngm->cm.error >= NSS_GRE_REDIR_LAG_ERR_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + ngm, ngm->cm.type, nss_gre_redir_lag_us_log_message_types_str[ngm->cm.type], + ngm->cm.response, nss_cmn_response_str[ngm->cm.response], + ngm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + ngm, ngm->cm.type, nss_gre_redir_lag_us_log_message_types_str[ngm->cm.type], + ngm->cm.response, nss_cmn_response_str[ngm->cm.response], + ngm->cm.error, nss_gre_redir_lag_us_log_error_response_types_str[ngm->cm.error]); + +verbose: + nss_gre_redir_lag_us_log_verbose(ngm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_us_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_us_log.h new file mode 100644 index 000000000..cbda8d93a --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_us_log.h @@ -0,0 +1,37 @@ +/* + ****************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_GRE_REDIR_LAG_US_LOG_H__ +#define __NSS_GRE_REDIR_LAG_US_LOG_H__ + +/* + * nss_gre_redir_lag_us_log.h + * NSS GRE REDIR LAG US Log Header File + */ + +/* + * nss_gre_redir_lag_us_log_tx_msg + * Logs a gre redir lag us message that is sent to the NSS firmware. + */ +void nss_gre_redir_lag_us_log_tx_msg(struct nss_gre_redir_lag_us_msg *ngm); + +/* + * nss_gre_redir_lag_us_log_rx_msg + * Logs a gre redir lag us message that is received from the NSS firmware. + */ +void nss_gre_redir_lag_us_log_rx_msg(struct nss_gre_redir_lag_us_msg *ngm); + +#endif /* __NSS_GRE_REDIR_LAG_US_LOG_H__ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_us_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_us_stats.c new file mode 100644 index 000000000..68ef37bf7 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_us_stats.c @@ -0,0 +1,203 @@ +/* + ************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_gre_redir_lag.h" +#include "nss_gre_redir_lag_us_stats.h" + +/* + * nss_gre_redir_lag_us_stats_str + * GRE REDIR LAG US common statistics strings. + */ +static uint8_t *nss_gre_redir_lag_us_stats_str[NSS_GRE_REDIR_LAG_US_STATS_MAX] = { + "rx_packets", + "rx_bytes", + "tx_packets", + "tx_bytes", + "rx_queue_0_dropped", + "rx_queue_1_dropped", + "rx_queue_2_dropped", + "rx_queue_3_dropped", + "Amsdu pkts", + "Amsdu pkts enqueued", + "Amsdu pkts exceptioned", + "Exceptioned", + "Freed", + "add attempt", + "add success", + "add fail table full", + "add fail exists", + "del attempt", + "del success", + "del fail not found", +}; + +/* + * nss_gre_redir_lag_us_tunnel_stats() + * Make a row for GRE_REDIR LAG US stats. + */ +static ssize_t nss_gre_redir_lag_us_cmn_stats_read_entry(char *line, int len, int type, struct nss_gre_redir_lag_us_tunnel_stats *s) +{ + uint64_t tcnt = 0; + + switch (type) { + case NSS_STATS_NODE_RX_PKTS: + tcnt = s->rx_packets; + return snprintf(line, len, "Common node stats start:\n\n%s = %llu\n", nss_gre_redir_lag_us_stats_str[type], tcnt); + case NSS_STATS_NODE_RX_BYTES: + tcnt = s->rx_bytes; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_us_stats_str[type], tcnt); + case NSS_STATS_NODE_TX_PKTS: + tcnt = s->tx_packets; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_us_stats_str[type], tcnt); + case NSS_STATS_NODE_TX_BYTES: + tcnt = s->tx_bytes; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_us_stats_str[type], tcnt); + case NSS_STATS_NODE_RX_QUEUE_0_DROPPED: + tcnt = s->rx_dropped[0]; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_us_stats_str[type], tcnt); +#if (NSS_MAX_NUM_PRI > 1) + case NSS_STATS_NODE_RX_QUEUE_1_DROPPED: + tcnt = s->rx_dropped[1]; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_us_stats_str[type], tcnt); + case NSS_STATS_NODE_RX_QUEUE_2_DROPPED: + tcnt = s->rx_dropped[2]; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_us_stats_str[type], tcnt); + case NSS_STATS_NODE_RX_QUEUE_3_DROPPED: + tcnt = s->rx_dropped[3]; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_us_stats_str[type], tcnt); +#endif + case NSS_GRE_REDIR_LAG_US_STATS_AMSDU_PKTS: + tcnt = s->us_stats.amsdu_pkts; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_us_stats_str[type], tcnt); + case NSS_GRE_REDIR_LAG_US_STATS_AMSDU_PKTS_ENQUEUED: + tcnt = s->us_stats.amsdu_pkts_enqueued; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_us_stats_str[type], tcnt); + case NSS_GRE_REDIR_LAG_US_STATS_AMSDU_PKTS_EXCEPTIONED: + tcnt = s->us_stats.amsdu_pkts_exceptioned; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_us_stats_str[type], tcnt); + case NSS_GRE_REDIR_LAG_US_STATS_EXCEPTIONED: + tcnt = s->us_stats.exceptioned; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_us_stats_str[type], tcnt); + case NSS_GRE_REDIR_LAG_US_STATS_FREED: + tcnt = s->us_stats.freed; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_us_stats_str[type], tcnt); + case NSS_GRE_REDIR_LAG_US_STATS_ADD_ATTEMPT: + tcnt = s->db_stats.add_attempt; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_us_stats_str[type], tcnt); + case NSS_GRE_REDIR_LAG_US_STATS_ADD_SUCCESS: + tcnt = s->db_stats.add_success; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_us_stats_str[type], tcnt); + case NSS_GRE_REDIR_LAG_US_STATS_ADD_FAIL_TABLE_FULL: + tcnt = s->db_stats.add_fail_table_full; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_us_stats_str[type], tcnt); + case NSS_GRE_REDIR_LAG_US_STATS_ADD_FAIL_EXISTS: + tcnt = s->db_stats.add_fail_exists; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_us_stats_str[type], tcnt); + case NSS_GRE_REDIR_LAG_US_STATS_DEL_ATTEMPT: + tcnt = s->db_stats.del_attempt; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_us_stats_str[type], tcnt); + case NSS_GRE_REDIR_LAG_US_STATS_DEL_SUCCESS: + tcnt = s->db_stats.del_success; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_us_stats_str[type], tcnt); + case NSS_GRE_REDIR_LAG_US_STATS_DEL_FAIL_NOT_FOUND: + tcnt = s->db_stats.del_fail_not_found; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_lag_us_stats_str[type], tcnt); + default: + nss_warning("Unknown tunnel stats type.\n"); + return 0; + } +} + +/* + * nss_gre_redir_lag_us_cmn_stats_read() + * Read and copy stats to user buffer. + */ +static ssize_t nss_gre_redir_lag_us_cmn_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + ssize_t bytes_read = 0; + struct nss_stats_data *data = fp->private_data; + struct nss_gre_redir_lag_us_tunnel_stats stats; + size_t bytes; + char line[80]; + int start; + + while (data->index < NSS_GRE_REDIR_LAG_MAX_NODE) { + if (nss_gre_redir_lag_us_get_cmn_stats(&stats, data->index)) { + break; + } + + data->index++; + } + + if (data->index == NSS_GRE_REDIR_LAG_MAX_NODE) { + return 0; + } + + bytes = snprintf(line, sizeof(line), "\nTunnel stats"); + if (copy_to_user(ubuf, line, bytes) != 0) { + return -EFAULT; + } + + bytes_read += bytes; + start = NSS_STATS_NODE_RX_PKTS; + while (bytes_read < sz && start <= NSS_GRE_REDIR_LAG_US_STATS_DEL_FAIL_NOT_FOUND) { + bytes = nss_gre_redir_lag_us_cmn_stats_read_entry(line, sizeof(line), start, &stats); + if ((bytes_read + bytes) > sz) { + break; + } + + if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) { + return -EFAULT; + } + + bytes_read += bytes; + start++; + } + + data->index++; + return bytes_read; +} + +/* + * nss_gre_redir_lag_us_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(gre_redir_lag_us_cmn) + +/* + * nss_gre_redir_lag_us_stats_dentry_create() + * Create debugfs directory for stats. + */ +struct dentry *nss_gre_redir_lag_us_stats_dentry_create(void) +{ + struct dentry *gre_redir; + struct dentry *cmn_stats; + + gre_redir = nss_gre_redir_get_dentry(); + if (unlikely(!gre_redir)) { + nss_warning("Failed to retrieve directory entry qca-nss-drv/stats/gre_redir/\n"); + return NULL; + } + + cmn_stats = debugfs_create_file("lag_us_cmn_stats", 0400, gre_redir, + &nss_top_main, &nss_gre_redir_lag_us_cmn_stats_ops); + if (unlikely(!cmn_stats)) { + nss_warning("Failed to create qca-nss-drv/stats/gre_redir/lag_us_cmn_stats file\n"); + return NULL; + } + + return cmn_stats; +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_us_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_us_stats.h new file mode 100644 index 000000000..c0e4a9d45 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_lag_us_stats.h @@ -0,0 +1,40 @@ +/* + ****************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_GRE_REDIR_LAG_US_STATS_H__ +#define __NSS_GRE_REDIR_LAG_US_STATS_H__ + +/* + * GRE redirect LAG upstream statistics + */ +enum nss_gre_redir_lag_us_stats_types { + NSS_GRE_REDIR_LAG_US_STATS_AMSDU_PKTS = NSS_STATS_NODE_MAX, + NSS_GRE_REDIR_LAG_US_STATS_AMSDU_PKTS_ENQUEUED, + NSS_GRE_REDIR_LAG_US_STATS_AMSDU_PKTS_EXCEPTIONED, + NSS_GRE_REDIR_LAG_US_STATS_EXCEPTIONED, + NSS_GRE_REDIR_LAG_US_STATS_FREED, + NSS_GRE_REDIR_LAG_US_STATS_ADD_ATTEMPT, + NSS_GRE_REDIR_LAG_US_STATS_ADD_SUCCESS, + NSS_GRE_REDIR_LAG_US_STATS_ADD_FAIL_TABLE_FULL, + NSS_GRE_REDIR_LAG_US_STATS_ADD_FAIL_EXISTS, + NSS_GRE_REDIR_LAG_US_STATS_DEL_ATTEMPT, + NSS_GRE_REDIR_LAG_US_STATS_DEL_SUCCESS, + NSS_GRE_REDIR_LAG_US_STATS_DEL_FAIL_NOT_FOUND, + NSS_GRE_REDIR_LAG_US_STATS_MAX, +}; + +extern struct dentry *nss_gre_redir_lag_us_stats_dentry_create(void); +#endif diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_log.c new file mode 100644 index 000000000..1ac6afbd2 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_log.c @@ -0,0 +1,242 @@ +/* + ************************************************************************** + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_gre_redir_log.c + * NSS GRE REDIR logger file. + */ + +#include "nss_core.h" + +/* + * nss_gre_redir_log_message_types_str + * NSS GRE REDIR message strings + */ +static int8_t *nss_gre_redir_log_message_types_str[NSS_GRE_REDIR_MAX_MSG_TYPES] __maybe_unused = { + "GRE REDIR Tunnel Inner Configure", + "GRE REDIR Tunnel Outer Configure", + "GRE REDIR Interface Map", + "GRE REDIR Interface Unmap", + "GRE REDIR SJACK Map", + "GRE REDIR SJACK Unmap", + "GRE REDIR Stats Sync", + "GRE REDIR Exception DS register cb" +}; + +/* + * nss_gre_redir_log_inner_configure_msg() + * Log NSS GRE Redir inner configure message. + */ +static void nss_gre_redir_log_inner_configure_msg(struct nss_gre_redir_msg *ngm) +{ + struct nss_gre_redir_inner_configure_msg *ngicm __maybe_unused = &ngm->msg.inner_configure; + nss_trace("%px: NSS GRE Redir Inner Configure message" + "GRE REDIR IP Header Type: %d\n" + "GRE REDIR Source IP: %px\n" + "GRE REDIR Destination IP: %px\n" + "GRE REDIR Outer Interface: %d\n" + "GRE REDIR Do not Fragment: %d\n" + "GRE REDIR IP TTL: %d\n" + "GRE REDIR Version: %d\n", + ngicm, ngicm->ip_hdr_type, + ngicm->ip_src_addr, ngicm->ip_dest_addr, + ngicm->except_outerif, ngicm->ip_df_policy, + ngicm->ip_ttl, ngicm->gre_version); +} + +/* + * nss_gre_redir_log_interface_map_msg() + * Log NSS GRE Redir interface map message. + */ +static void nss_gre_redir_log_interface_map_msg(struct nss_gre_redir_msg *ngm) +{ + struct nss_gre_redir_interface_map_msg *ngicm __maybe_unused = &ngm->msg.interface_map; + nss_trace("%px: NSS GRE Redir Interface Map message" + "GRE REDIR NSS VAP Interface: %d\n" + "GRE REDIR Next Hop NSS Interface: %d\n" + "GRE REDIR Radio ID: %d\n" + "GRE REDIR VAP ID: %d\n" + "GRE REDIR LAG Flags: %x\n" + "GRE REDIR Tunnel Type: %d\n" + "GRE REDIR IPsec pattern: %d\n", + ngicm, ngicm->vap_nssif, + ngicm->nexthop_nssif, ngicm->radio_id, + ngicm->vap_id, ngicm->lag_en, + ngicm->tunnel_type, ngicm->ipsec_pattern); +} + +/* + * nss_gre_redir_log_interface_unmap_msg() + * Log NSS GRE Redir interface unmap message. + */ +static void nss_gre_redir_log_interface_unmap_msg(struct nss_gre_redir_msg *ngm) +{ + struct nss_gre_redir_interface_unmap_msg *ngicm __maybe_unused = &ngm->msg.interface_unmap; + nss_trace("%px: NSS GRE Redir Interface Map message" + "GRE REDIR NSS VAP Interface: %d\n" + "GRE REDIR Radio ID: %d\n" + "GRE REDIR VAP ID: %d\n", + ngicm, ngicm->vap_nssif, + ngicm->radio_id, ngicm->vap_id); +} + +/* + * nss_gre_redir_log_sjack_map_msg() + * Log NSS GRE Redir interface map message. + */ +static void nss_gre_redir_log_sjack_map_msg(struct nss_gre_redir_msg *ngm) +{ + struct nss_gre_redir_sjack_map_msg *ngscm __maybe_unused = &ngm->msg.sjack_map; + nss_trace("%px: NSS GRE Redir SJACK Map message" + "GRE REDIR Eth NSS Interface: %d\n" + "GRE REDIR Eth Interface ID: %d\n" + "GRE REDIR IPSec pattern: %x\n", + ngscm, ngscm->eth_nssif, + ngscm->eth_id, ngscm->ipsec_pattern); +} + +/* + * nss_gre_redir_log_sjack_unmap_msg() + * Log NSS GRE Redir interface unmap message. + */ +static void nss_gre_redir_log_sjack_unmap_msg(struct nss_gre_redir_msg *ngm) +{ + struct nss_gre_redir_sjack_unmap_msg *ngscm __maybe_unused = &ngm->msg.sjack_unmap; + nss_trace("%px: NSS GRE Redir SJACK Map message" + "GRE REDIR Eth NSS Interface: %d\n" + "GRE REDIR Eth Interface ID: %d\n", + ngscm, ngscm->eth_nssif, + ngscm->eth_id); +} + +/* + * nss_gre_redir_log_outer_configure_msg() + * Log NSS GRE Redir outer configure message. + */ +static void nss_gre_redir_log_outer_configure_msg(struct nss_gre_redir_msg *ngm) +{ + struct nss_gre_redir_outer_configure_msg *ngocm __maybe_unused = &ngm->msg.outer_configure; + nss_trace("%px: NSS GRE Redir Outer Configure message" + "GRE REDIR IP Header Type: %d\n" + "GRE REDIR Host Inner Interface: %d\n" + "GRE REDIR NSS Inner Interface: %d\n" + "GRE REDIR SJACK Inner Interface: %d\n" + "GRE REDIR RPS: %d\n" + "GRE REDIR RPS Valid: %d\n", + ngocm, ngocm->ip_hdr_type, + ngocm->except_hostif, ngocm->except_offlif, + ngocm->except_sjackif, ngocm->rps_hint, + ngocm->rps_hint_valid); +} + +/* + * nss_gre_redir_log_exception_ds_reg_cb_msg() + * Log GRE exception downstream callback registration message. + */ +static void nss_gre_redir_log_exception_ds_reg_cb_msg(struct nss_gre_redir_msg *ngm) +{ + struct nss_gre_redir_exception_ds_reg_cb_msg *exception_ds_configure __maybe_unused = &ngm->msg.exception_ds_configure; + nss_trace("%px: NSS GRE redir exception completion callback registration message\n" + "vap_if_num: %d\n", ngm, exception_ds_configure->dst_vap_nssif); +} + +/* + * nss_gre_redir_log_verbose() + * Log message contents. + */ +static void nss_gre_redir_log_verbose(struct nss_gre_redir_msg *ngm) +{ + switch (ngm->cm.type) { + case NSS_GRE_REDIR_TX_TUNNEL_INNER_CONFIGURE_MSG: + nss_gre_redir_log_inner_configure_msg(ngm); + break; + + case NSS_GRE_REDIR_TX_TUNNEL_OUTER_CONFIGURE_MSG: + nss_gre_redir_log_outer_configure_msg(ngm); + break; + + case NSS_GRE_REDIR_TX_INTERFACE_MAP_MSG: + nss_gre_redir_log_interface_map_msg(ngm); + break; + + case NSS_GRE_REDIR_TX_INTERFACE_UNMAP_MSG: + nss_gre_redir_log_interface_unmap_msg(ngm); + break; + + case NSS_GRE_REDIR_TX_SJACK_MAP_MSG: + nss_gre_redir_log_sjack_map_msg(ngm); + break; + + case NSS_GRE_REDIR_TX_SJACK_UNMAP_MSG: + nss_gre_redir_log_sjack_unmap_msg(ngm); + break; + + case NSS_GRE_REDIR_RX_STATS_SYNC_MSG: + /* + * No log for valid stats message. + */ + break; + + case NSS_GRE_REDIR_EXCEPTION_DS_REG_CB_MSG: + nss_gre_redir_log_exception_ds_reg_cb_msg(ngm); + break; + + default: + nss_warning("%px: Invalid message type\n", ngm); + break; + } +} + +/* + * nss_gre_redir_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_gre_redir_log_tx_msg(struct nss_gre_redir_msg *ngm) +{ + if (ngm->cm.type >= NSS_GRE_REDIR_MAX_MSG_TYPES) { + nss_warning("%px: Invalid message type\n", ngm); + return; + } + + nss_info("%px: type[%d]:%s\n", ngm, ngm->cm.type, nss_gre_redir_log_message_types_str[ngm->cm.type]); + nss_gre_redir_log_verbose(ngm); +} + +/* + * nss_gre_redir_log_rx_msg() + * Log messages received from FW. + */ +void nss_gre_redir_log_rx_msg(struct nss_gre_redir_msg *ngm) +{ + if (ngm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", ngm); + return; + } + + if (ngm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ngm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", ngm, ngm->cm.type, + nss_gre_redir_log_message_types_str[ngm->cm.type], + ngm->cm.response, nss_cmn_response_str[ngm->cm.response]); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s\n", + ngm, ngm->cm.type, nss_gre_redir_log_message_types_str[ngm->cm.type], + ngm->cm.response, nss_cmn_response_str[ngm->cm.response]); + +verbose: + nss_gre_redir_log_verbose(ngm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_log.h new file mode 100644 index 000000000..7e1fb793e --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_log.h @@ -0,0 +1,41 @@ +/* + ************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_GRE_REDIR_LOG_H +#define __NSS_GRE_REDIR_LOG_H + +/* + * nss_gre_redir_log.h + * NSS GRE REDIR Log header file. + */ + +/* + * Logger APIs + */ + +/* + * nss_gre_redir_log_tx_msg + * Logs a gre_redir message that is sent to the NSS firmware. + */ +void nss_gre_redir_log_tx_msg(struct nss_gre_redir_msg *ngm); + +/* + * nss_gre_redir_log_rx_msg + * Logs a gre_redir message that is received from the NSS firmware. + */ +void nss_gre_redir_log_rx_msg(struct nss_gre_redir_msg *ngm); + +#endif /* __NSS_GRE_REDIR_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_mark.c b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_mark.c new file mode 100644 index 000000000..4a79b55fc --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_mark.c @@ -0,0 +1,418 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_gre_redir_mark_stats.h" +#include "nss_gre_redir_mark_log.h" +#define NSS_GRE_REDIR_MARK_TX_TIMEOUT 3000 /* 3 Seconds */ + +/* + * Private data structure for handling synchronous messaging. + */ +static struct { + struct semaphore sem; + struct completion complete; + int response; +} nss_gre_redir_mark_pvt; + +/* + * Spinlock to update GRE redir mark stats. + */ +static DEFINE_SPINLOCK(nss_gre_redir_mark_stats_lock); + +/* + * Global GRE redir mark stats structure. + */ +static struct nss_gre_redir_mark_stats gre_mark_stats; + +/* + * nss_gre_redir_mark_msg_sync_callback() + * Callback to handle the completion of HLOS-->NSS messages. + */ +static void nss_gre_redir_mark_msg_sync_callback(void *app_data, struct nss_gre_redir_mark_msg *nim) +{ + nss_gre_redir_mark_pvt.response = NSS_TX_SUCCESS; + if (nim->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("GRE mark Error response %d\n", nim->cm.response); + nss_gre_redir_mark_pvt.response = NSS_TX_FAILURE; + } + + complete(&nss_gre_redir_mark_pvt.complete); +} + +/* + * nss_gre_redir_mark_stats_sync() + * Update GRE redir mark stats. + */ +static void nss_gre_redir_mark_stats_sync(struct nss_ctx_instance *nss_ctx, int if_num, struct nss_gre_redir_mark_stats_sync_msg *ngss) +{ + struct net_device *dev; + dev = nss_cmn_get_interface_dev(nss_ctx, if_num); + if (!dev) { + nss_warning("%px: Unable to find net device for the interface %d\n", nss_ctx, if_num); + return; + } + + if (if_num != NSS_GRE_REDIR_MARK_INTERFACE) { + nss_warning("%px: Unknown type for interface %d\n", nss_ctx, if_num); + return; + } + + /* + * Update the stats in exclusive mode to prevent the read from the process + * context through debug fs. + */ + spin_lock_bh(&nss_gre_redir_mark_stats_lock); + + /* + * Update the common node stats + */ + gre_mark_stats.stats[NSS_GRE_REDIR_MARK_STATS_TX_PKTS] += ngss->node_stats.tx_packets; + gre_mark_stats.stats[NSS_GRE_REDIR_MARK_STATS_TX_BYTES] += ngss->node_stats.tx_bytes; + gre_mark_stats.stats[NSS_GRE_REDIR_MARK_STATS_RX_PKTS] += ngss->node_stats.rx_packets; + gre_mark_stats.stats[NSS_GRE_REDIR_MARK_STATS_RX_BYTES] += ngss->node_stats.rx_bytes; + gre_mark_stats.stats[NSS_GRE_REDIR_MARK_STATS_RX_DROPS] += nss_cmn_rx_dropped_sum(&(ngss->node_stats)); + + /* + * Update the GRE redir mark specific stats + */ + gre_mark_stats.stats[NSS_GRE_REDIR_MARK_STATS_HLOS_MAGIC_FAILED] += ngss->hlos_magic_fail; + gre_mark_stats.stats[NSS_GRE_REDIR_MARK_STATS_INV_DST_IF_DROPS] += ngss->invalid_dst_drop; + gre_mark_stats.stats[NSS_GRE_REDIR_MARK_STATS_DST_IF_ENQUEUE] += ngss->dst_enqueue_success; + gre_mark_stats.stats[NSS_GRE_REDIR_MARK_STATS_DST_IF_ENQUEUE_DROPS] += ngss->dst_enqueue_drop; + gre_mark_stats.stats[NSS_GRE_REDIR_MARK_STATS_INV_APPID] += ngss->inv_appid; + gre_mark_stats.stats[NSS_GRE_REDIR_MARK_STATS_HEADROOM_UNAVAILABLE] += ngss->headroom_unavail; + gre_mark_stats.stats[NSS_GRE_REDIR_MARK_STATS_TX_COMPLETION_SUCCESS] += ngss->tx_completion_success; + gre_mark_stats.stats[NSS_GRE_REDIR_MARK_STATS_TX_COMPLETION_DROPS] += ngss->tx_completion_drop; + + spin_unlock_bh(&nss_gre_redir_mark_stats_lock); +} + +/* + * nss_gre_redir_mark_handler() + * Handle NSS to HLOS messages for GRE redir mark + */ +static void nss_gre_redir_mark_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, void *app_data) +{ + struct nss_gre_redir_mark_msg *ngrm = (struct nss_gre_redir_mark_msg *)ncm; + nss_gre_redir_mark_msg_callback_t cb; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_GRE_REDIR_MARK_MSG_MAX) { + nss_warning("%px: received invalid message %d for GRE redir mark interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_gre_redir_mark_msg)) { + nss_warning("%px: length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Trace messages. + */ + nss_gre_redir_mark_log_rx_msg((struct nss_gre_redir_mark_msg *)ncm); + + if (ncm->type == NSS_GRE_REDIR_MARK_STATS_SYNC_MSG) { + nss_gre_redir_mark_stats_sync(nss_ctx, ncm->interface, &ngrm->msg.stats_sync); + } + + /* + * Update the callback and app_data for NOTIFY messages, GRE redir mark sends all notify messages + * to the same callback/app_data. The app data here represent the netdevice of the GRE redir mark + * interface. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_core_get_msg_handler(nss_ctx, ncm->interface); + ncm->app_data = (nss_ptr_t)nss_ctx->subsys_dp_register[ncm->interface].ndev; + } + + /* + * load and call the registered synchronous message callback. + */ + cb = (nss_gre_redir_mark_msg_callback_t)ncm->cb; + if (unlikely(!cb)) { + return; + } + + cb((void *)ncm->app_data, ncm); +} + +/* + * nss_gre_redir_mark_get_stats() + * Get gre_redir tunnel stats. + */ +bool nss_gre_redir_mark_get_stats(void *stats_mem) +{ + struct nss_gre_redir_mark_stats *stats = (struct nss_gre_redir_mark_stats *)stats_mem; + if (!stats) { + nss_warning("No memory to copy GRE redir mark stats"); + return false; + } + + /* + * Copy the GRE redir mark stats in the memory. + */ + spin_lock_bh(&nss_gre_redir_mark_stats_lock); + memcpy(stats, &gre_mark_stats, sizeof(struct nss_gre_redir_mark_stats)); + spin_unlock_bh(&nss_gre_redir_mark_stats_lock); + return true; +} +EXPORT_SYMBOL(nss_gre_redir_mark_get_stats); + +/* + * nss_gre_redir_mark_reg_cb() + * Configure a callback on VAP. + */ +nss_tx_status_t nss_gre_redir_mark_reg_cb(int ifnum, + struct nss_gre_redir_mark_register_cb_msg *ngrcm) +{ + struct nss_gre_redir_mark_msg config; + struct nss_ctx_instance *nss_ctx __maybe_unused = nss_gre_redir_mark_get_context(); + nss_tx_status_t status; + uint32_t vap_type; + uint32_t len = sizeof(struct nss_gre_redir_mark_register_cb_msg); + + if (!nss_ctx) { + nss_warning("Unable to retrieve NSS context.\n"); + return NSS_TX_FAILURE_BAD_PARAM; + } + + vap_type = nss_dynamic_interface_get_type(nss_ctx, ngrcm->nss_if_num); + if ((vap_type != NSS_DYNAMIC_INTERFACE_TYPE_VAP)) { + nss_warning("%px: Incorrect type for vap interface type = %u", nss_ctx, vap_type); + return NSS_TX_FAILURE_BAD_PARAM; + } + + /* + * Configure the node + */ + nss_cmn_msg_init(&config.cm, NSS_GRE_REDIR_MARK_INTERFACE, NSS_GRE_REDIR_MARK_REG_CB_MSG, len, NULL, NULL); + config.msg.reg_cb_msg.nss_if_num = ngrcm->nss_if_num; + + status = nss_gre_redir_mark_tx_msg_sync(nss_ctx, &config); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: Unable to register callback from GRE redir mark interface %d\n", nss_ctx, ifnum); + } + + return status; +} +EXPORT_SYMBOL(nss_gre_redir_mark_reg_cb); + +/* + * nss_gre_redir_mark_tx_msg() + * Transmit a GRE MARK configuration message to NSS FW. + */ +nss_tx_status_t nss_gre_redir_mark_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_gre_redir_mark_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Trace Messages + */ + nss_gre_redir_mark_log_tx_msg(msg); + + /* + * interface should be of type of redir mark + */ + if (ncm->interface != NSS_GRE_REDIR_MARK_INTERFACE) { + nss_warning("%px: tx request for another interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type >= NSS_GRE_REDIR_MARK_MSG_MAX) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_gre_redir_mark_tx_msg); + +/* + * nss_gre_redir_mark_tx_msg_sync() + * Transmit a GRE redir mark message to NSS firmware synchronously. + */ +nss_tx_status_t nss_gre_redir_mark_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_redir_mark_msg *ngrm) +{ + nss_tx_status_t status; + int ret = 0; + + /* + * Decrease the semaphore count to send the message exclusively. + */ + down(&nss_gre_redir_mark_pvt.sem); + ngrm->cm.cb = (nss_ptr_t)nss_gre_redir_mark_msg_sync_callback; + ngrm->cm.app_data = (nss_ptr_t)NULL; + status = nss_gre_redir_mark_tx_msg(nss_ctx, ngrm); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: GRE redir mark tx_msg failed\n", nss_ctx); + up(&nss_gre_redir_mark_pvt.sem); + return status; + } + + ret = wait_for_completion_timeout(&nss_gre_redir_mark_pvt.complete, msecs_to_jiffies(NSS_GRE_REDIR_MARK_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: GRE redir mark message tx sync failed due to timeout\n", nss_ctx); + nss_gre_redir_mark_pvt.response = NSS_TX_FAILURE; + } + + status = nss_gre_redir_mark_pvt.response; + up(&nss_gre_redir_mark_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_gre_redir_mark_tx_msg_sync); + +/* + * nss_gre_redir_mark_tx_buf() + * Send packet to GRE redir mark interface owned by NSS. + */ +nss_tx_status_t nss_gre_redir_mark_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf, uint32_t if_num) +{ + nss_trace("%px: GRE redir mark If Tx packet, interface id:%d, data=%px", nss_ctx, if_num, os_buf->data); + + /* + * We expect Tx packets to the GRE redir mark interface only. + */ + if (if_num != NSS_GRE_REDIR_MARK_INTERFACE) { + nss_warning("%px: Invalid interface:%d for GRE redir mark packets\n", nss_ctx, if_num); + return NSS_TX_FAILURE_BAD_PARAM; + } + + return nss_core_send_packet(nss_ctx, os_buf, if_num, 0); +} +EXPORT_SYMBOL(nss_gre_redir_mark_tx_buf); + +/* + * nss_gre_redir_mark_get_context() + * Return NSS GRE redir mark context. + */ +struct nss_ctx_instance *nss_gre_redir_mark_get_context(void) +{ + return &nss_top_main.nss[nss_top_main.gre_redir_mark_handler_id]; +} +EXPORT_SYMBOL(nss_gre_redir_mark_get_context); + +/* + * nss_gre_redir_mark_unregister_if() + * Unregister dynamic node for GRE_REDIR_MARK redir. + */ +bool nss_gre_redir_mark_unregister_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx __maybe_unused = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.gre_redir_handler_id]; + struct net_device *dev; + uint32_t status; + + nss_assert(nss_ctx); + nss_assert(if_num == NSS_GRE_REDIR_MARK_INTERFACE); + + dev = nss_cmn_get_interface_dev(nss_ctx, if_num); + + BUG_ON(!dev); + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + status = nss_core_unregister_msg_handler(nss_ctx, if_num); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Not able to unregister handler for gre_redir_mark interface %d with NSS core\n", + nss_ctx, if_num); + return false; + } + + nss_ctx->nss_rx_interface_handlers[if_num].msg_cb = NULL; + return true; +} +EXPORT_SYMBOL(nss_gre_redir_mark_unregister_if); + +/* + * nss_gre_redir_mark_register_if() + * Register staticr GRE redir mark interface with data-plane. + */ +struct nss_ctx_instance *nss_gre_redir_mark_register_if(struct net_device *netdev, uint32_t if_num, + nss_gre_redir_mark_data_callback_t cb_func_data, nss_gre_redir_mark_msg_callback_t cb_func_msg, + uint32_t features) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.gre_redir_handler_id]; + uint32_t status; + + nss_assert(nss_ctx); + nss_assert(if_num == NSS_GRE_REDIR_MARK_INTERFACE); + + /* + * Registering the interface with network data path. + */ + nss_core_register_subsys_dp(nss_ctx, if_num, cb_func_data, NULL, NULL, netdev, features); + status = nss_core_register_msg_handler(nss_ctx, NSS_GRE_REDIR_MARK_INTERFACE, cb_func_msg); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Not able to register handler for gre_redir_mark interface %d with NSS core\n", + nss_ctx, if_num); + return NULL; + } + + return nss_ctx; +} +EXPORT_SYMBOL(nss_gre_redir_mark_register_if); + +/* + * nss_gre_redir_mark_get_device() + * Gets the original device from probe. + */ +struct device *nss_gre_redir_mark_get_device(void) +{ + struct nss_ctx_instance *nss_ctx = nss_gre_redir_mark_get_context(); + return nss_ctx->dev; +} +EXPORT_SYMBOL(nss_gre_redir_mark_get_device); + +/* + * nss_gre_redir_mark_register_handler() + * Register GRE redir mark and register handler + */ +void nss_gre_redir_mark_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx = nss_gre_redir_mark_get_context(); + struct dentry *gre_redir_mark_dentry = NULL; + uint32_t status = NSS_CORE_STATUS_FAILURE; + + /* + * Create the debug fs entry for the stats. + */ + gre_redir_mark_dentry = nss_gre_redir_mark_stats_dentry_create(); + if (!gre_redir_mark_dentry) { + nss_warning("%px: Not able to create debugfs entry\n", nss_ctx); + return; + } + + sema_init(&nss_gre_redir_mark_pvt.sem, 1); + init_completion(&nss_gre_redir_mark_pvt.complete); + + nss_info("nss_gre_redir_mark_register_handler\n"); + status = nss_core_register_handler(nss_ctx, NSS_GRE_REDIR_MARK_INTERFACE, nss_gre_redir_mark_handler, NULL); + if (status != NSS_CORE_STATUS_SUCCESS) { + debugfs_remove_recursive(gre_redir_mark_dentry); + gre_redir_mark_dentry = NULL; + nss_warning("%px: Not able to register handler for GRE redir mark with NSS core\n", nss_ctx); + return; + } +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_mark_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_mark_log.c new file mode 100644 index 000000000..580c5a851 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_mark_log.c @@ -0,0 +1,119 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" + +/* + * nss_gre_redir_mark_log_message_types_str + * GRE redir mark message strings + */ +static int8_t *nss_gre_redir_mark_log_message_types_str[NSS_GRE_REDIR_MARK_MSG_MAX] __maybe_unused = { + "GRE redir mark register callback message", + "GRE redir mark statistics synchronization" +}; + +/* + * nss_gre_redir_mark_log_error_response_types_str + * Strings for error types for GRE redir mark messages + */ +static int8_t *nss_gre_redir_mark_log_error_response_types_str[NSS_GRE_REDIR_MARK_ERROR_TYPE_MAX] __maybe_unused = { + "GRE redir mark No error", + "GRE redir mark Invalid interface for callback registration", + "GRE redir mark Invalid ethertype for Tx interface" +}; + +/* + * nss_gre_redir_mark_log_reg_cb_msg() + * Log NSS GRE redir mark configuration message + */ +static void nss_gre_redir_mark_log_reg_cb_msg(struct nss_gre_redir_mark_msg *ncm) +{ + struct nss_gre_redir_mark_register_cb_msg *reg_cb_msg __maybe_unused = &ncm->msg.reg_cb_msg; + nss_trace("%px: NSS GRE redir mark callback registration message \n" + "nss_if_num: %d\n", ncm, reg_cb_msg->nss_if_num); +} + +/* + * nss_gre_redir_mark_log_verbose() + * Log message contents. + */ +static void nss_gre_redir_mark_log_verbose(struct nss_gre_redir_mark_msg *ncm) +{ + switch (ncm->cm.type) { + case NSS_GRE_REDIR_MARK_REG_CB_MSG: + nss_gre_redir_mark_log_reg_cb_msg(ncm); + break; + + case NSS_GRE_REDIR_MARK_STATS_SYNC_MSG: + /* + * No log for valid stats message. + */ + break; + + default: + nss_trace("%px: Invalid message type\n", ncm); + break; + } +} + +/* + * nss_gre_redir_mark_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_gre_redir_mark_log_tx_msg(struct nss_gre_redir_mark_msg *ngm) +{ + if (ngm->cm.type >= NSS_GRE_REDIR_MARK_MSG_MAX) { + nss_warning("%px: Invalid message type\n", ngm); + return; + } + + nss_info("%px: type[%d]:%s\n", ngm, ngm->cm.type, nss_gre_redir_mark_log_message_types_str[ngm->cm.type]); + nss_gre_redir_mark_log_verbose(ngm); +} +/* + * nss_gre_redir_mark_log_rx_msg() + * Log messages received from FW. + */ +void nss_gre_redir_mark_log_rx_msg(struct nss_gre_redir_mark_msg *ncm) +{ + if (ncm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", ncm); + return; + } + + if (ncm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ncm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", ncm, ncm->cm.type, + nss_gre_redir_mark_log_message_types_str[ncm->cm.type], + ncm->cm.response, nss_cmn_response_str[ncm->cm.response]); + goto verbose; + } + + if (ncm->cm.error >= NSS_GRE_REDIR_MARK_ERROR_TYPE_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + ncm, ncm->cm.type, nss_gre_redir_mark_log_message_types_str[ncm->cm.type], + ncm->cm.response, nss_cmn_response_str[ncm->cm.response], + ncm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + ncm, ncm->cm.type, nss_gre_redir_mark_log_message_types_str[ncm->cm.type], + ncm->cm.response, nss_cmn_response_str[ncm->cm.response], + ncm->cm.error, nss_gre_redir_mark_log_error_response_types_str[ncm->cm.error]); + +verbose: + nss_gre_redir_mark_log_verbose(ncm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_mark_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_mark_log.h new file mode 100644 index 000000000..27e2ffb16 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_mark_log.h @@ -0,0 +1,37 @@ +/* + ****************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_GRE_REDIR_MARK_LOG_H__ +#define __NSS_GRE_REDIR_MARK_LOG_H__ + +/* + * nss_gre_redir_mark_log.h + * NSS GRE_REDIR_MARK Log Header File. + */ + +/* + * nss_gre_redir_mark_log_tx_msg + * Logs GRE_REDIR_MARK message that is sent to the NSS firmware. + */ +void nss_gre_redir_mark_log_tx_msg(struct nss_gre_redir_mark_msg *ncm); + +/* + * nss_gre_redir_mark_log_rx_msg + * Logs GRE_REDIR_MARK message that is received from the NSS firmware. + */ +void nss_gre_redir_mark_log_rx_msg(struct nss_gre_redir_mark_msg *ncm); + +#endif /* __NSS_GRE_REDIR_MARK_LOG_H__ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_mark_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_mark_stats.c new file mode 100644 index 000000000..c9b2a9dc8 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_mark_stats.c @@ -0,0 +1,163 @@ +/* + ************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_stats.h" +#include "nss_gre_redir_mark.h" +#include "nss_gre_redir_mark_stats.h" + +#define NSS_GRE_REDIR_MARK_STATS_STR_LEN 50 +#define NSS_GRE_REDIR_MARK_STATS_LEN ((NSS_GRE_REDIR_MARK_STATS_MAX + 7 ) * NSS_GRE_REDIR_MARK_STATS_STR_LEN) +/* + * nss_gre_redir_mark_stats_str + * GRE redir mark statistics string + */ +static int8_t *nss_gre_redir_mark_stats_str[NSS_GRE_REDIR_MARK_STATS_MAX] = { + "TX Packets", + "TX Bytes", + "RX Packets", + "RX Bytes", + "RX Drops", + "HLOS Magic Failed", + "Tx Inv_dst_if Drops", + "Tx Dst_if Enqueue", + "Tx Dst_if Enqueue Drops", + "Invalid Appid", + "Headroom Unavailable", + "Tx Completion Host Enqueue Success", + "Tx Completion Host Enqueue Drops", +}; + +/* + * nss_gre_redir_mark_stats_cpy() + * Fill the stats. + */ +static ssize_t nss_gre_redir_mark_stats_cpy(char *lbuf, int len, int i, struct nss_gre_redir_mark_stats *s) +{ + uint64_t tcnt = 0; + + switch (i) { + case NSS_GRE_REDIR_MARK_STATS_TX_PKTS: + tcnt = s->stats[NSS_GRE_REDIR_MARK_STATS_TX_PKTS]; + return scnprintf(lbuf, len, "Common node stats start:\n\n%s = %llu\n", nss_gre_redir_mark_stats_str[i], tcnt); + case NSS_GRE_REDIR_MARK_STATS_TX_BYTES: + tcnt = s->stats[NSS_GRE_REDIR_MARK_STATS_TX_BYTES]; + return scnprintf(lbuf, len, "%s = %llu\n", nss_gre_redir_mark_stats_str[i], tcnt); + case NSS_GRE_REDIR_MARK_STATS_RX_PKTS: + tcnt = s->stats[NSS_GRE_REDIR_MARK_STATS_RX_PKTS]; + return scnprintf(lbuf, len, "%s = %llu\n", nss_gre_redir_mark_stats_str[i], tcnt); + case NSS_GRE_REDIR_MARK_STATS_RX_BYTES: + tcnt = s->stats[NSS_GRE_REDIR_MARK_STATS_RX_BYTES]; + return scnprintf(lbuf, len, "%s = %llu\n", nss_gre_redir_mark_stats_str[i], tcnt); + case NSS_GRE_REDIR_MARK_STATS_RX_DROPS: + tcnt = s->stats[NSS_GRE_REDIR_MARK_STATS_RX_DROPS]; + return scnprintf(lbuf, len, "%s = %llu\nCommon node stats end.\n", nss_gre_redir_mark_stats_str[i], tcnt); + case NSS_GRE_REDIR_MARK_STATS_HLOS_MAGIC_FAILED: + tcnt = s->stats[NSS_GRE_REDIR_MARK_STATS_HLOS_MAGIC_FAILED]; + return scnprintf(lbuf, len, "Offload stats start:\n\n%s = %llu\n", nss_gre_redir_mark_stats_str[i], tcnt); + case NSS_GRE_REDIR_MARK_STATS_INV_DST_IF_DROPS: + tcnt = s->stats[NSS_GRE_REDIR_MARK_STATS_INV_DST_IF_DROPS]; + return scnprintf(lbuf, len, "%s = %llu\n", nss_gre_redir_mark_stats_str[i], tcnt); + case NSS_GRE_REDIR_MARK_STATS_DST_IF_ENQUEUE: + tcnt = s->stats[NSS_GRE_REDIR_MARK_STATS_DST_IF_ENQUEUE]; + return scnprintf(lbuf, len, "%s = %llu\n", nss_gre_redir_mark_stats_str[i], tcnt); + case NSS_GRE_REDIR_MARK_STATS_DST_IF_ENQUEUE_DROPS: + tcnt = s->stats[NSS_GRE_REDIR_MARK_STATS_DST_IF_ENQUEUE_DROPS]; + return scnprintf(lbuf, len, "%s = %llu\n", nss_gre_redir_mark_stats_str[i], tcnt); + case NSS_GRE_REDIR_MARK_STATS_INV_APPID: + tcnt = s->stats[NSS_GRE_REDIR_MARK_STATS_INV_APPID]; + return scnprintf(lbuf, len, "%s = %llu\n", nss_gre_redir_mark_stats_str[i], tcnt); + case NSS_GRE_REDIR_MARK_STATS_HEADROOM_UNAVAILABLE: + tcnt = s->stats[NSS_GRE_REDIR_MARK_STATS_HEADROOM_UNAVAILABLE]; + return scnprintf(lbuf, len, "%s = %llu\n", nss_gre_redir_mark_stats_str[i], tcnt); + case NSS_GRE_REDIR_MARK_STATS_TX_COMPLETION_SUCCESS: + tcnt = s->stats[NSS_GRE_REDIR_MARK_STATS_TX_COMPLETION_SUCCESS]; + return scnprintf(lbuf, len, "%s = %llu\n", nss_gre_redir_mark_stats_str[i], tcnt); + case NSS_GRE_REDIR_MARK_STATS_TX_COMPLETION_DROPS: + tcnt = s->stats[NSS_GRE_REDIR_MARK_STATS_TX_COMPLETION_DROPS]; + return scnprintf(lbuf, len, "%s = %llu\nOffload stats end.\n", nss_gre_redir_mark_stats_str[i], tcnt); + default: + nss_warning("Unknown stats type %d.\n", i); + return 0; + } +} + +/* + * nss_gre_redir_mark_stats_read() + * READ GRE redir mark stats. + */ +static ssize_t nss_gre_redir_mark_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + struct nss_gre_redir_mark_stats stats; + size_t size_wr = 0; + int start, end; + ssize_t bytes_read = 0; + bool isthere; + size_t size_al = ((NSS_GRE_REDIR_MARK_STATS_MAX + 7 ) * NSS_GRE_REDIR_MARK_STATS_STR_LEN); + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(!lbuf)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + /* + * If GRE redir mark does not exists, then (isthere) will be false. + */ + isthere = nss_gre_redir_mark_get_stats((void*)&stats); + if (!isthere) { + nss_warning("Could not get GRE redirect stats"); + kfree(lbuf); + return 0; + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nGRE redir mark stats\n"); + + start = NSS_GRE_REDIR_MARK_STATS_TX_PKTS; + end = NSS_GRE_REDIR_MARK_STATS_MAX; + while (start < end) { + size_wr += nss_gre_redir_mark_stats_cpy(lbuf + size_wr, size_al - size_wr, start, &stats); + start++; + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr); + + kfree(lbuf); + return bytes_read; +} + +/* + * nss_gre_redir_mark_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(gre_redir_mark) + +/* + * nss_gre_redir_mark_stats_dentry_create() + * Create debugfs directory entry for stats. + */ +struct dentry *nss_gre_redir_mark_stats_dentry_create(void) +{ + struct dentry *gre_redir_mark; + + gre_redir_mark = debugfs_create_file("gre_redir_mark", 0400, nss_top_main.stats_dentry, + &nss_top_main, &nss_gre_redir_mark_stats_ops); + if (unlikely(!gre_redir_mark)) { + nss_warning("Failed to create file entry qca-nss-drv/stats/gre_redir_mark/\n"); + return NULL; + } + + return gre_redir_mark; +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_mark_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_mark_stats.h new file mode 100644 index 000000000..8017f6d20 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_mark_stats.h @@ -0,0 +1,52 @@ +/* + ****************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_GRE_REDIR_MARK_STATS_H__ +#define __NSS_GRE_REDIR_MARK_STATS_H__ + +/* + * GRE REDIR statistics types + */ +enum nss_gre_redir_mark_stats_types { + NSS_GRE_REDIR_MARK_STATS_TX_PKTS, + NSS_GRE_REDIR_MARK_STATS_TX_BYTES, + NSS_GRE_REDIR_MARK_STATS_RX_PKTS, + NSS_GRE_REDIR_MARK_STATS_RX_BYTES, + NSS_GRE_REDIR_MARK_STATS_RX_DROPS, + NSS_GRE_REDIR_MARK_STATS_HLOS_MAGIC_FAILED, + NSS_GRE_REDIR_MARK_STATS_INV_DST_IF_DROPS, + NSS_GRE_REDIR_MARK_STATS_DST_IF_ENQUEUE, + NSS_GRE_REDIR_MARK_STATS_DST_IF_ENQUEUE_DROPS, + NSS_GRE_REDIR_MARK_STATS_INV_APPID, + NSS_GRE_REDIR_MARK_STATS_HEADROOM_UNAVAILABLE, + NSS_GRE_REDIR_MARK_STATS_TX_COMPLETION_SUCCESS, + NSS_GRE_REDIR_MARK_STATS_TX_COMPLETION_DROPS, + NSS_GRE_REDIR_MARK_STATS_MAX +}; + +/* + * NSS core stats -- for H2N/N2H gre_redir_mark debug stats + */ +struct nss_gre_redir_mark_stats { + uint64_t stats[NSS_GRE_REDIR_MARK_STATS_MAX]; +}; + +/* + * NSS GRE REDIR Mark statistics APIs + */ +extern struct dentry *nss_gre_redir_mark_stats_dentry_create(void); + +#endif /* __NSS_GRE_REDIR_MARK_STATS_H__ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_stats.c new file mode 100644 index 000000000..4b83cee73 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_stats.c @@ -0,0 +1,260 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_gre_redir.h" +#include "nss_gre_redir_stats.h" + +/* + * nss_gre_redir_stats_str + * GRE REDIR statistics string + */ +static int8_t *nss_gre_redir_stats_str[NSS_GRE_REDIR_STATS_MAX] = { + "TX Packets", + "TX Bytes", + "TX Drops", + "RX Packets", + "RX Bytes", + "RX Drops", + "TX Sjack Packets", + "RX Sjack packets", + "TX Offload Packets", + "RX Offload Packets", + "US exception RX Packets", + "US exception TX Packets", + "DS exception RX Packets", + "DS exception TX Packets", + "Encap SG alloc drop", + "Decap fail drop", + "Decap split drop", + "Split SG alloc fail", + "Split linear copy fail", + "Split not enough tailroom", + "Exception ds invalid dst", + "Decap eapol frames", + "Exception ds invalid appid", + "Headroom Unavailable", + "Exception ds Tx completion Success", + "Exception ds Tx completion drop" +}; + +/* + * nss_gre_redir_stats() + * Make a row for GRE_REDIR stats. + */ +static ssize_t nss_gre_redir_stats(char *line, int len, int i, struct nss_gre_redir_tunnel_stats *s) +{ + char name[40]; + uint64_t tcnt = 0; + int j = 0; + + switch (i) { + case NSS_GRE_REDIR_STATS_TX_PKTS: + tcnt = s->node_stats.tx_packets; + return snprintf(line, len, "Common node stats start:\n\n%s = %llu\n", nss_gre_redir_stats_str[i], tcnt); + case NSS_GRE_REDIR_STATS_TX_BYTES: + tcnt = s->node_stats.tx_bytes; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt); + case NSS_GRE_REDIR_STATS_TX_DROPS: + tcnt = s->tx_dropped; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt); + case NSS_GRE_REDIR_STATS_RX_PKTS: + tcnt = s->node_stats.rx_packets; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt); + case NSS_GRE_REDIR_STATS_RX_BYTES: + tcnt = s->node_stats.rx_bytes; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt); + case NSS_GRE_REDIR_STATS_RX_DROPS: + tcnt = s->node_stats.rx_dropped[0]; + return snprintf(line, len, "%s = %llu\nCommon node stats end.\n", nss_gre_redir_stats_str[i], tcnt); + case NSS_GRE_REDIR_STATS_SJACK_TX_PKTS: + tcnt = s->sjack_tx_packets; + return snprintf(line, len, "Offload stats start:\n\n%s = %llu\n", nss_gre_redir_stats_str[i], tcnt); + case NSS_GRE_REDIR_STATS_OFFLOAD_TX_PKTS: + for (j = 0; j < NSS_GRE_REDIR_MAX_RADIO; j++) { + scnprintf(name, sizeof(name), "TX offload pkts for radio %d", j); + tcnt += snprintf(line + tcnt, len - tcnt, "%s = %llu\n", name, s->offl_tx_pkts[j]); + } + return tcnt; + case NSS_GRE_REDIR_STATS_SJACK_RX_PKTS: + tcnt = s->sjack_rx_packets; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt); + case NSS_GRE_REDIR_STATS_OFFLOAD_RX_PKTS: + for (j = 0; j < NSS_GRE_REDIR_MAX_RADIO; j++) { + scnprintf(name, sizeof(name), "RX offload pkts for radio %d", j); + tcnt += snprintf(line + tcnt, len - tcnt, "%s = %llu\n", name, s->offl_rx_pkts[j]); + } + return tcnt; + case NSS_GRE_REDIR_STATS_EXCEPTION_US_RX_PKTS: + tcnt = s->exception_us_rx; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt); + case NSS_GRE_REDIR_STATS_EXCEPTION_US_TX_PKTS: + tcnt = s->exception_us_tx; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt); + case NSS_GRE_REDIR_STATS_EXCEPTION_DS_RX_PKTS: + tcnt = s->exception_ds_rx; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt); + case NSS_GRE_REDIR_STATS_EXCEPTION_DS_TX_PKTS: + tcnt = s->exception_ds_tx; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt); + case NSS_GRE_REDIR_STATS_ENCAP_SG_ALLOC_DROP: + tcnt = s->encap_sg_alloc_drop; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt); + case NSS_GRE_REDIR_STATS_DECAP_FAIL_DROP: + tcnt = s->decap_fail_drop; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt); + case NSS_GRE_REDIR_STATS_DECAP_SPLIT_DROP: + tcnt = s->decap_split_drop; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt); + case NSS_GRE_REDIR_STATS_SPLIT_SG_ALLOC_FAIL: + tcnt = s->split_sg_alloc_fail; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt); + case NSS_GRE_REDIR_STATS_SPLIT_LINEAR_COPY_FAIL: + tcnt = s->split_linear_copy_fail; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt); + case NSS_GRE_REDIR_STATS_SPLIT_NOT_ENOUGH_TAILROOM: + tcnt = s->split_not_enough_tailroom; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt); + case NSS_GRE_REDIR_STATS_EXCEPTION_DS_INVALID_DST_DROP: + tcnt = s->exception_ds_invalid_dst_drop; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt); + case NSS_GRE_REDIR_STATS_DECAP_EAPOL_FRAMES: + tcnt = s->decap_eapol_frames; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt); + case NSS_GRE_REDIR_STATS_EXCEPTION_DS_INV_APPID: + tcnt = s->exception_ds_inv_appid; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt); + case NSS_GRE_REDIR_STATS_HEADROOM_UNAVAILABLE: + tcnt = s->headroom_unavail; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt); + case NSS_GRE_REDIR_STATS_TX_COMPLETION_SUCCESS: + tcnt = s->tx_completion_success; + return snprintf(line, len, "%s = %llu\n", nss_gre_redir_stats_str[i], tcnt); + case NSS_GRE_REDIR_STATS_TX_COMPLETION_DROP: + tcnt = s->tx_completion_drop; + return snprintf(line, len, "%s = %llu\nOffload stats end.\n", nss_gre_redir_stats_str[i], tcnt); + default: + nss_warning("Unknown stats type %d.\n", i); + return 0; + } +} + +/* + * nss_gre_redir_stats_read() + * READ gre_redir tunnel stats. + */ +static ssize_t nss_gre_redir_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + struct nss_stats_data *data = fp->private_data; + ssize_t bytes_read = 0; + struct nss_gre_redir_tunnel_stats stats; + size_t bytes; + char line[80 * NSS_GRE_REDIR_MAX_RADIO]; + int start, end; + int index = 0; + + if (data) { + index = data->index; + } + + /* + * If we are done accomodating all the GRE_REDIR tunnels. + */ + if (index >= NSS_GRE_REDIR_MAX_INTERFACES) { + return 0; + } + + for (; index < NSS_GRE_REDIR_MAX_INTERFACES; index++) { + bool isthere; + + /* + * If gre_redir tunnel does not exists, then isthere will be false. + */ + isthere = nss_gre_redir_get_stats(index, &stats); + if (!isthere) { + continue; + } + + bytes = snprintf(line, sizeof(line), "\nTunnel stats for %s\n", stats.dev->name); + if ((bytes_read + bytes) > sz) { + break; + } + + if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) { + bytes_read = -EFAULT; + goto fail; + } + bytes_read += bytes; + start = NSS_GRE_REDIR_STATS_TX_PKTS; + end = NSS_GRE_REDIR_STATS_MAX; + while (bytes_read < sz && start < end) { + bytes = nss_gre_redir_stats(line, sizeof(line), start, &stats); + + if ((bytes_read + bytes) > sz) + break; + + if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) { + bytes_read = -EFAULT; + goto fail; + } + + bytes_read += bytes; + start++; + } + } + + if (bytes_read > 0) { + *ppos = bytes_read; + } + + if (data) { + data->index = index; + } + +fail: + return bytes_read; +} + +/* + * nss_gre_redir_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(gre_redir) + +/* + * nss_gre_redir_stats_dentry_create() + * Create debugfs directory entry for stats. + */ +struct dentry *nss_gre_redir_stats_dentry_create(void) +{ + struct dentry *gre_redir; + struct dentry *tun_stats; + + gre_redir = debugfs_create_dir("gre_redir", nss_top_main.stats_dentry); + if (unlikely(!gre_redir)) { + nss_warning("Failed to create directory entry qca-nss-drv/stats/gre_redir/\n"); + return NULL; + } + + tun_stats = debugfs_create_file("tun_stats", 0400, gre_redir, + &nss_top_main, &nss_gre_redir_stats_ops); + if (unlikely(!tun_stats)) { + debugfs_remove_recursive(gre_redir); + nss_warning("Failed to create file entry qca-nss-drv/stats/gre_redir/tun_stats\n"); + return NULL; + } + + return gre_redir; +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_stats.h new file mode 100644 index 000000000..d7a96aed2 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_redir_stats.h @@ -0,0 +1,58 @@ +/* + ****************************************************************************** + * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_GRE_REDIR_STATS_H__ +#define __NSS_GRE_REDIR_STATS_H__ + +/* + * GRE REDIR statistics + */ +enum nss_gre_redir_stats_types { + NSS_GRE_REDIR_STATS_TX_PKTS, + NSS_GRE_REDIR_STATS_TX_BYTES, + NSS_GRE_REDIR_STATS_TX_DROPS, + NSS_GRE_REDIR_STATS_RX_PKTS, + NSS_GRE_REDIR_STATS_RX_BYTES, + NSS_GRE_REDIR_STATS_RX_DROPS, + NSS_GRE_REDIR_STATS_SJACK_TX_PKTS, + NSS_GRE_REDIR_STATS_SJACK_RX_PKTS, + NSS_GRE_REDIR_STATS_OFFLOAD_TX_PKTS, + NSS_GRE_REDIR_STATS_OFFLOAD_RX_PKTS, + NSS_GRE_REDIR_STATS_EXCEPTION_US_RX_PKTS, + NSS_GRE_REDIR_STATS_EXCEPTION_US_TX_PKTS, + NSS_GRE_REDIR_STATS_EXCEPTION_DS_RX_PKTS, + NSS_GRE_REDIR_STATS_EXCEPTION_DS_TX_PKTS, + NSS_GRE_REDIR_STATS_ENCAP_SG_ALLOC_DROP, + NSS_GRE_REDIR_STATS_DECAP_FAIL_DROP, + NSS_GRE_REDIR_STATS_DECAP_SPLIT_DROP, + NSS_GRE_REDIR_STATS_SPLIT_SG_ALLOC_FAIL, + NSS_GRE_REDIR_STATS_SPLIT_LINEAR_COPY_FAIL, + NSS_GRE_REDIR_STATS_SPLIT_NOT_ENOUGH_TAILROOM, + NSS_GRE_REDIR_STATS_EXCEPTION_DS_INVALID_DST_DROP, + NSS_GRE_REDIR_STATS_DECAP_EAPOL_FRAMES, + NSS_GRE_REDIR_STATS_EXCEPTION_DS_INV_APPID, + NSS_GRE_REDIR_STATS_HEADROOM_UNAVAILABLE, + NSS_GRE_REDIR_STATS_TX_COMPLETION_SUCCESS, + NSS_GRE_REDIR_STATS_TX_COMPLETION_DROP, + NSS_GRE_REDIR_STATS_MAX +}; + +/* + * NSS GRE REDIR statistics APIs + */ +extern struct dentry *nss_gre_redir_stats_dentry_create(void); + +#endif /* __NSS_GRE_REDIR_STATS_H__ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_gre_stats.c new file mode 100644 index 000000000..08a9279dc --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_stats.c @@ -0,0 +1,311 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_gre_stats.c + * NSS GRE statistics APIs + * + */ + +#include "nss_tx_rx_common.h" +#include "nss_gre_stats.h" + +/* + * Data structures to store GRE nss debug stats + */ +static DEFINE_SPINLOCK(nss_gre_stats_lock); +static struct nss_gre_stats_session_debug session_debug_stats[NSS_GRE_MAX_DEBUG_SESSION_STATS]; +static struct nss_gre_stats_base_debug base_debug_stats; + +/* + * nss_gre_stats_base_debug_str + * GRE debug statistics strings for base types + */ +struct nss_stats_info nss_gre_stats_base_debug_str[NSS_GRE_STATS_BASE_DEBUG_MAX] = { + {"base_rx_pkts" ,NSS_STATS_TYPE_COMMON}, + {"base_rx_drops" ,NSS_STATS_TYPE_DROP}, + {"base_exp_eth_hdr_missing" ,NSS_STATS_TYPE_EXCEPTION}, + {"base_exp_eth_type_non_ip" ,NSS_STATS_TYPE_EXCEPTION}, + {"base_exp_ip_unknown_protocol" ,NSS_STATS_TYPE_EXCEPTION}, + {"base_exp_ip_header_incomplete" ,NSS_STATS_TYPE_EXCEPTION}, + {"base_exp_ip_bad_total_length" ,NSS_STATS_TYPE_EXCEPTION}, + {"base_exp_ip_bad_checksum" ,NSS_STATS_TYPE_EXCEPTION}, + {"base_exp_ip_datagram_incomplete" ,NSS_STATS_TYPE_EXCEPTION}, + {"base_exp_ip_fragment" ,NSS_STATS_TYPE_EXCEPTION}, + {"base_exp_ip_options_incomplete" ,NSS_STATS_TYPE_EXCEPTION}, + {"base_exp_ip_with_options" ,NSS_STATS_TYPE_EXCEPTION}, + {"base_exp_ipv6_unknown_protocol" ,NSS_STATS_TYPE_EXCEPTION}, + {"base_exp_ipv6_header_incomplete" ,NSS_STATS_TYPE_EXCEPTION}, + {"base_exp_unknown_session" ,NSS_STATS_TYPE_EXCEPTION}, + {"base_exp_node_inactive" ,NSS_STATS_TYPE_EXCEPTION} +}; + +/* + * nss_gre_stats_session_debug_str + * GRE debug statistics strings for sessions + */ +struct nss_stats_info nss_gre_stats_session_debug_str[NSS_GRE_STATS_SESSION_DEBUG_MAX] = { + {"session_pbuf_alloc_fail" , NSS_STATS_TYPE_ERROR}, + {"session_decap_forward_enqueue_fail" , NSS_STATS_TYPE_DROP}, + {"session_encap_forward_enqueue_fail" , NSS_STATS_TYPE_DROP}, + {"session_decap_tx_forwarded" , NSS_STATS_TYPE_SPECIAL}, + {"session_encap_rx_received" , NSS_STATS_TYPE_SPECIAL}, + {"session_encap_rx_drops" , NSS_STATS_TYPE_DROP}, + {"session_encap_rx_linear_fail" , NSS_STATS_TYPE_DROP}, + {"session_exp_rx_key_error" , NSS_STATS_TYPE_EXCEPTION}, + {"session_exp_rx_seq_error" , NSS_STATS_TYPE_EXCEPTION}, + {"session_exp_rx_cs_error" , NSS_STATS_TYPE_EXCEPTION}, + {"session_exp_rx_flag_mismatch" , NSS_STATS_TYPE_EXCEPTION}, + {"session_exp_rx_malformed" , NSS_STATS_TYPE_EXCEPTION}, + {"session_exp_rx_invalid_protocol" , NSS_STATS_TYPE_EXCEPTION}, + {"session_exp_rx_no_headroom" , NSS_STATS_TYPE_EXCEPTION} +}; + +/* + * GRE statistics APIs + */ + +/* + * nss_gre_stats_session_register() + * Register debug statistic for GRE session. + */ +void nss_gre_stats_session_register(uint32_t if_num, struct net_device *netdev) +{ + int i; + + spin_lock_bh(&nss_gre_stats_lock); + for (i = 0; i < NSS_GRE_MAX_DEBUG_SESSION_STATS; i++) { + if (!session_debug_stats[i].valid) { + session_debug_stats[i].valid = true; + session_debug_stats[i].if_num = if_num; + session_debug_stats[i].if_index = netdev->ifindex; + break; + } + } + spin_unlock_bh(&nss_gre_stats_lock); +} + +/* + * nss_gre_stats_session_unregister() + * Unregister debug statistic for GRE session. + */ +void nss_gre_stats_session_unregister(uint32_t if_num) +{ + int i; + + spin_lock_bh(&nss_gre_stats_lock); + for (i = 0; i < NSS_GRE_MAX_DEBUG_SESSION_STATS; i++) { + if (session_debug_stats[i].if_num == if_num) { + memset(&session_debug_stats[i], 0, sizeof(struct nss_gre_stats_session_debug)); + break; + } + } + spin_unlock_bh(&nss_gre_stats_lock); +} + +/* + * nss_gre_stats_session_debug_sync() + * debug statistics sync for GRE session. + */ +void nss_gre_stats_session_debug_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_session_stats_msg *sstats, uint16_t if_num) +{ + int i, j; + enum nss_dynamic_interface_type interface_type = nss_dynamic_interface_get_type(nss_ctx, if_num); + + spin_lock_bh(&nss_gre_stats_lock); + for (i = 0; i < NSS_GRE_MAX_DEBUG_SESSION_STATS; i++) { + if (session_debug_stats[i].if_num == if_num) { + for (j = 0; j < NSS_GRE_STATS_SESSION_DEBUG_MAX; j++) { + session_debug_stats[i].stats[j] += sstats->stats[j]; + } + + if (interface_type == NSS_DYNAMIC_INTERFACE_TYPE_GRE_INNER) { + session_debug_stats[i].stats[NSS_GRE_STATS_SESSION_ENCAP_RX_RECEIVED] += sstats->node_stats.rx_packets; + } else if (interface_type == NSS_DYNAMIC_INTERFACE_TYPE_GRE_OUTER) { + session_debug_stats[i].stats[NSS_GRE_STATS_SESSION_DECAP_TX_FORWARDED] += sstats->node_stats.tx_packets; + } + break; + } + } + spin_unlock_bh(&nss_gre_stats_lock); +} + +/* + * nss_gre_stats_base_debug_sync() + * Debug statistics sync for GRE base node. + */ +void nss_gre_stats_base_debug_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_base_stats_msg *bstats) +{ + int i; + + spin_lock_bh(&nss_gre_stats_lock); + for (i = 0; i < NSS_GRE_STATS_BASE_DEBUG_MAX; i++) { + base_debug_stats.stats[i] += bstats->stats[i]; + } + spin_unlock_bh(&nss_gre_stats_lock); +} + +/* + * nss_gre_stats_session_debug_get() + * Get GRE session debug statistics. + */ +static void nss_gre_stats_session_debug_get(void *stats_mem, int size) +{ + struct nss_gre_stats_session_debug *stats = (struct nss_gre_stats_session_debug *)stats_mem; + int i; + + if (!stats || (size < (sizeof(struct nss_gre_stats_session_debug) * NSS_GRE_MAX_DEBUG_SESSION_STATS))) { + nss_warning("No memory to copy gre stats"); + return; + } + + spin_lock_bh(&nss_gre_stats_lock); + for (i = 0; i < NSS_GRE_MAX_DEBUG_SESSION_STATS; i++) { + if (session_debug_stats[i].valid) { + memcpy(stats, &session_debug_stats[i], sizeof(struct nss_gre_stats_session_debug)); + stats++; + } + } + spin_unlock_bh(&nss_gre_stats_lock); +} + +/* + * nss_gre_stats_base_debug_get() + * Get GRE debug base statistics. + */ +static void nss_gre_stats_base_debug_get(void *stats_mem, int size) +{ + struct nss_gre_stats_base_debug *stats = (struct nss_gre_stats_base_debug *)stats_mem; + + if (!stats) { + nss_warning("No memory to copy GRE base stats\n"); + return; + } + + if (size < sizeof(struct nss_gre_stats_base_debug)) { + nss_warning("Not enough memory to copy GRE base stats\n"); + return; + } + + spin_lock_bh(&nss_gre_stats_lock); + memcpy(stats, &base_debug_stats, sizeof(struct nss_gre_stats_base_debug)); + spin_unlock_bh(&nss_gre_stats_lock); +} + +/* + * nss_gre_stats_read() + * Read GRE statistics + */ +static ssize_t nss_gre_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + uint32_t max_output_lines = 2 /* header & footer for base debug stats */ + + 2 /* header & footer for session debug stats */ + + NSS_GRE_STATS_BASE_DEBUG_MAX /* Base debug */ + + NSS_GRE_MAX_DEBUG_SESSION_STATS * (NSS_GRE_STATS_SESSION_DEBUG_MAX + 2) /*session stats */ + + 2; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + struct net_device *dev; + struct nss_gre_stats_session_debug *sstats; + struct nss_gre_stats_base_debug *bstats; + int id; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(!lbuf)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + bstats = kzalloc(sizeof(struct nss_gre_stats_base_debug), GFP_KERNEL); + if (unlikely(!bstats)) { + nss_warning("Could not allocate memory for base debug statistics buffer"); + kfree(lbuf); + return 0; + } + + sstats = kzalloc(sizeof(struct nss_gre_stats_session_debug) * NSS_GRE_MAX_DEBUG_SESSION_STATS, GFP_KERNEL); + if (unlikely(!sstats)) { + nss_warning("Could not allocate memory for base debug statistics buffer"); + kfree(lbuf); + kfree(bstats); + return 0; + } + + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "gre", NSS_STATS_SINGLE_CORE); + + /* + * Get all base stats + */ + nss_gre_stats_base_debug_get((void *)bstats, sizeof(struct nss_gre_stats_base_debug)); + + size_wr += nss_stats_print("gre", NULL, NSS_STATS_SINGLE_INSTANCE + , nss_gre_stats_base_debug_str + , bstats->stats + , NSS_GRE_STATS_BASE_DEBUG_MAX + , lbuf, size_wr, size_al); + + /* + * Get all session stats + */ + nss_gre_stats_session_debug_get(sstats, sizeof(struct nss_gre_stats_session_debug) * NSS_GRE_MAX_DEBUG_SESSION_STATS); + + for (id = 0; id < NSS_GRE_MAX_DEBUG_SESSION_STATS; id++) { + + if (!((sstats + id)->valid)) { + continue; + } + + dev = dev_get_by_index(&init_net, (sstats + id)->if_index); + if (likely(dev)) { + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d, netdevice=%s\n", id, + (sstats + id)->if_num, dev->name); + dev_put(dev); + } else { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d\n", id, + (sstats + id)->if_num); + } + size_wr += nss_stats_print("gre_session", NULL, id + , nss_gre_stats_session_debug_str + , (sstats + id)->stats + , NSS_GRE_STATS_SESSION_DEBUG_MAX + , lbuf, size_wr, size_al); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n"); + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr); + + kfree(sstats); + kfree(bstats); + kfree(lbuf); + return bytes_read; +} + +/* + * nss_gre_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(gre) + +/* + * nss_gre_stats_dentry_create() + * Create gre statistics debug entry. + */ +void nss_gre_stats_dentry_create(void) +{ + nss_stats_create_dentry("gre", &nss_gre_stats_ops); +} + diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_gre_stats.h new file mode 100644 index 000000000..a16bd3454 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_stats.h @@ -0,0 +1,95 @@ +/* + ************************************************************************** + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_gre_stats.h + * NSS GRE statistics header file. + */ + +#ifndef __NSS_GRE_STATS_H +#define __NSS_GRE_STATS_H + +/* + * GRE base debug statistics types + */ +enum nss_gre_stats_base_debug_types { + NSS_GRE_STATS_BASE_RX_PACKETS, /**< Rx packet count. */ + NSS_GRE_STATS_BASE_RX_DROPPED, /**< Rx dropped count. */ + NSS_GRE_STATS_BASE_EXP_ETH_HDR_MISSING, /**< Ethernet header missing. */ + NSS_GRE_STATS_BASE_EXP_ETH_TYPE_NON_IP, /**< Not IPV4 or IPV6 packet. */ + NSS_GRE_STATS_BASE_EXP_IP_UNKNOWN_PROTOCOL, /**< Unknown protocol. */ + NSS_GRE_STATS_BASE_EXP_IP_HEADER_INCOMPLETE, /**< Bad IP header. */ + NSS_GRE_STATS_BASE_EXP_IP_BAD_TOTAL_LENGTH, /**< Invalid IP packet length. */ + NSS_GRE_STATS_BASE_EXP_IP_BAD_CHECKSUM, /**< Bad packet checksum. */ + NSS_GRE_STATS_BASE_EXP_IP_DATAGRAM_INCOMPLETE, /**< Bad packet. */ + NSS_GRE_STATS_BASE_EXP_IP_FRAGMENT, /**< IP fragment. */ + NSS_GRE_STATS_BASE_EXP_IP_OPTIONS_INCOMPLETE, /**< Invalid IP options. */ + NSS_GRE_STATS_BASE_EXP_IP_WITH_OPTIONS, /**< IP packet with options. */ + NSS_GRE_STATS_BASE_EXP_IPV6_UNKNOWN_PROTOCOL, /**< Unknown protocol. */ + NSS_GRE_STATS_BASE_EXP_IPV6_HEADER_INCOMPLETE, /**< Incomplete IPV6 header. */ + NSS_GRE_STATS_BASE_EXP_GRE_UNKNOWN_SESSION, /**< Unknown GRE session. */ + NSS_GRE_STATS_BASE_EXP_GRE_NODE_INACTIVE, /**< GRE node inactive. */ + NSS_GRE_STATS_BASE_DEBUG_MAX, /**< GRE base error max. */ +}; + +/* + * GRE base debug statistics + */ +struct nss_gre_stats_base_debug { + uint64_t stats[NSS_GRE_STATS_BASE_DEBUG_MAX]; /**< GRE debug statistics. */ +}; + +/* + * GRE session debug statistics types + */ +enum nss_gre_stats_session_debug_types { + NSS_GRE_STATS_SESSION_PBUF_ALLOC_FAIL, /**< Pbuf alloc failure. */ + NSS_GRE_STATS_SESSION_DECAP_FORWARD_ENQUEUE_FAIL, /**< Rx forward enqueue failure. */ + NSS_GRE_STATS_SESSION_ENCAP_FORWARD_ENQUEUE_FAIL, /**< Tx forward enqueue failure. */ + NSS_GRE_STATS_SESSION_DECAP_TX_FORWARDED, /**< Packets forwarded after decap. */ + NSS_GRE_STATS_SESSION_ENCAP_RX_RECEIVED, /**< Packets received for encap. */ + NSS_GRE_STATS_SESSION_ENCAP_RX_DROPPED, /**< Packets dropped while enqueue for encap. */ + NSS_GRE_STATS_SESSION_ENCAP_RX_LINEAR_FAIL, /**< Packets dropped during encap linearization. */ + NSS_GRE_STATS_SESSION_EXP_RX_KEY_ERROR, /**< Rx KEY error. */ + NSS_GRE_STATS_SESSION_EXP_RX_SEQ_ERROR, /**< Rx sequence number error. */ + NSS_GRE_STATS_SESSION_EXP_RX_CS_ERROR, /**< Rx checksum error. */ + NSS_GRE_STATS_SESSION_EXP_RX_FLAG_MISMATCH, /**< Rx flag mismatch. */ + NSS_GRE_STATS_SESSION_EXP_RX_MALFORMED, /**< Rx malformed packet. */ + NSS_GRE_STATS_SESSION_EXP_RX_INVALID_PROTOCOL, /**< Rx invalid protocol. */ + NSS_GRE_STATS_SESSION_EXP_RX_NO_HEADROOM, /**< Rx no headroom. */ + NSS_GRE_STATS_SESSION_DEBUG_MAX, /**< Session debug max. */ +}; + +/* + * GRE session debug statistics + */ +struct nss_gre_stats_session_debug { + uint64_t stats[NSS_GRE_STATS_SESSION_DEBUG_MAX]; /**< Session debug statistics. */ + int32_t if_index; /**< Netdevice's ifindex. */ + uint32_t if_num; /**< NSS interface number. */ + bool valid; /**< Is node valid ? */ +}; + +/* + * GRE statistics APIs + */ +extern void nss_gre_stats_session_debug_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_session_stats_msg *sstats, uint16_t if_num); +extern void nss_gre_stats_base_debug_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_base_stats_msg *bstats); +extern void nss_gre_stats_session_register(uint32_t if_num, struct net_device *netdev); +extern void nss_gre_stats_session_unregister(uint32_t if_num); +extern void nss_gre_stats_dentry_create(void); + +#endif /* __NSS_GRE_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_tunnel.c b/feeds/ipq807x/qca-nss-drv/src/nss_gre_tunnel.c new file mode 100644 index 000000000..07e7860af --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_tunnel.c @@ -0,0 +1,392 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_gre_tunnel_stats.h" +#include "nss_gre_tunnel_log.h" + +#define NSS_GRE_TUNNEL_TX_TIMEOUT 3000 /* 3 Seconds */ + +/* + * Private data structure + */ +static struct nss_gre_tunnel_pvt { + struct semaphore sem; + struct completion complete; + int response; + void *cb; + void *app_data; +} gre_tunnel_pvt; + +/* + * nss_gre_tunnel_verify_if_num() + * Verify if_num passed to us. + */ +static bool nss_gre_tunnel_verify_if_num(uint32_t if_num) +{ + uint32_t type = nss_dynamic_interface_get_type(nss_gre_tunnel_get_ctx(), if_num); + + switch (type) { + case NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL_INNER: + case NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL_INLINE_INNER: + case NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL_OUTER: + case NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL_INLINE_OUTER: + case NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL_INNER_EXCEPTION: + return true; + default: + return false; + } +} + +/* + * nss_gre_tunnel_handler() + * Handle NSS to HLOS messages for gre_tunnel + */ +static void nss_gre_tunnel_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_gre_tunnel_msg *ngtm = (struct nss_gre_tunnel_msg *)ncm; + void *ctx; + + nss_gre_tunnel_msg_callback_t cb; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + BUG_ON(!nss_gre_tunnel_verify_if_num(ncm->interface)); + + /* + * Trace Messages + */ + nss_gre_tunnel_log_rx_msg(ngtm); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_GRE_TUNNEL_MSG_MAX) { + nss_warning("%px: received invalid message %d for GRE_TUNNEL interface %d", nss_ctx, ncm->type, ncm->interface); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_gre_tunnel_msg)) { + nss_warning("%px: gre_tunnel message length is invalid: %d", nss_ctx, ncm->len); + return; + } + + /* + * Check messages + */ + switch (ngtm->cm.type) { + case NSS_GRE_TUNNEL_MSG_STATS: + nss_gre_tunnel_stats_session_sync(nss_ctx, &ngtm->msg.stats, ncm->interface); + break; + } + + /* + * Update the callback and app_data for NOTIFY messages + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_ctx->nss_top->gre_tunnel_msg_callback; + ncm->app_data = (nss_ptr_t)nss_ctx->subsys_dp_register[ncm->interface].app_data; + } + + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * callback + */ + cb = (nss_gre_tunnel_msg_callback_t)ncm->cb; + ctx = (void *)ncm->app_data; + + /* + * call GRE Tunnel session callback + */ + if (!cb) { + return; + } + + cb(ctx, ngtm); +} + +/* + * nss_gre_tunnel_inquiry() + * Inquiry if a GRE tunnel has been established in NSS FW. + * + * Input parameters: + * inquiry_info->ip_type + * inquiry_info->src_ip + * inquiry_info->dest_ip + * inquiry_info->gre_mode + * if (gre_mode == NSS_GRE_TUNNEL_MODE_GRE_UDP) + * inquiry_info->src_port + * inquiry_info->dest_port + * inquiry_info->encrypt_type -- currently not checked in FW, + */ +nss_tx_status_t nss_gre_tunnel_inquiry( + struct nss_gre_tunnel_configure *inquiry_info, + nss_gre_tunnel_msg_callback_t cb, void *app_data) +{ + nss_tx_status_t nss_tx_status; + struct nss_gre_tunnel_msg nim; + struct nss_ctx_instance *nss_ctx = nss_gre_tunnel_get_ctx(); + + /* + * Initialize inquiry message structure. + * This is async message and the result will be returned + * to the caller by the msg_callback passed in. + */ + memset(&nim, 0, sizeof(nim)); + nss_gre_tunnel_msg_init(&nim, NSS_GRE_TUNNEL_INTERFACE, + NSS_GRE_TUNNEL_MSG_INQUIRY, + sizeof(struct nss_gre_tunnel_configure), + cb, app_data); + nim.msg.configure = *inquiry_info; + nss_tx_status = nss_gre_tunnel_tx_msg(nss_ctx, &nim); + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: Send GT inquiry message failed\n", inquiry_info); + } + + return nss_tx_status; +} +EXPORT_SYMBOL(nss_gre_tunnel_inquiry); + +/* + * nss_get_gre_tunnel_context() + * Return the core ctx which the feature is on + */ +struct nss_ctx_instance *nss_gre_tunnel_get_ctx(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.gre_tunnel_handler_id]; +} +EXPORT_SYMBOL(nss_gre_tunnel_get_ctx); + +/* + * nss_gre_tunnel_ifnum_with_core_id() + * Append core id to GRE tunnel interface num + */ +int nss_gre_tunnel_ifnum_with_core_id(int if_num) +{ + struct nss_ctx_instance *nss_ctx = nss_gre_tunnel_get_ctx(); + BUG_ON(!nss_gre_tunnel_verify_if_num(if_num)); + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (nss_is_dynamic_interface(if_num) == false) { + nss_info("%px: Invalid if_num: %d, must be a dynamic interface\n", nss_ctx, if_num); + return 0; + } + + return NSS_INTERFACE_NUM_APPEND_COREID(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_gre_tunnel_ifnum_with_core_id); + +/* + * nss_gre_tunnel_tx_buf() + * Transmit buffer over GRE Tunnel interface + */ +nss_tx_status_t nss_gre_tunnel_tx_buf(struct sk_buff *skb, uint32_t if_num, + struct nss_ctx_instance *nss_ctx) +{ + BUG_ON(!nss_gre_tunnel_verify_if_num(if_num)); + + return nss_core_send_packet(nss_ctx, skb, if_num, H2N_BIT_FLAG_VIRTUAL_BUFFER | H2N_BIT_FLAG_BUFFER_REUSABLE); +} +EXPORT_SYMBOL(nss_gre_tunnel_tx_buf); + +/* + * nss_gre_tunnel_tx_msg() + * Transmit a gre_tunnel message to NSS firmware + */ +nss_tx_status_t nss_gre_tunnel_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_gre_tunnel_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Trace Messages + */ + nss_gre_tunnel_log_tx_msg(msg); + + /* + * Sanity check message + */ + if (ncm->type >= NSS_GRE_TUNNEL_MSG_MAX) { + nss_warning("%px: gre_tunnel message type out of range: %d", + nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + BUG_ON(!nss_gre_tunnel_verify_if_num(ncm->interface)); + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_gre_tunnel_tx_msg); + +/* + * nss_gre_tunnel_callback() + * Callback to handle the completion of NSS->HLOS messages. + */ +static void nss_gre_tunnel_callback(void *app_data, struct nss_gre_tunnel_msg *ngtm) +{ + nss_gre_tunnel_msg_callback_t callback = (nss_gre_tunnel_msg_callback_t)gre_tunnel_pvt.cb; + void *data = gre_tunnel_pvt.app_data; + + gre_tunnel_pvt.response = NSS_TX_SUCCESS; + gre_tunnel_pvt.cb = NULL; + gre_tunnel_pvt.app_data = NULL; + + if (ngtm->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("gre tunnel Error response %d\n", ngtm->cm.response); + gre_tunnel_pvt.response = ngtm->cm.response; + } + + if (callback) { + callback(data, ngtm); + } + complete(&gre_tunnel_pvt.complete); +} + +/* + * nss_gre_tunnel_tx_msg() + * Transmit a GRE Tunnel message to NSS firmware synchronously. + */ +nss_tx_status_t nss_gre_tunnel_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_tunnel_msg *ngtm) +{ + nss_tx_status_t status; + int ret = 0; + + down(&gre_tunnel_pvt.sem); + gre_tunnel_pvt.cb = (void *)ngtm->cm.cb; + gre_tunnel_pvt.app_data = (void *)ngtm->cm.app_data; + + ngtm->cm.cb = (nss_ptr_t)nss_gre_tunnel_callback; + ngtm->cm.app_data = (nss_ptr_t)NULL; + + status = nss_gre_tunnel_tx_msg(nss_ctx, ngtm); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: gre_tunnel_tx_msg failed\n", nss_ctx); + up(&gre_tunnel_pvt.sem); + return status; + } + + ret = wait_for_completion_timeout(&gre_tunnel_pvt.complete, msecs_to_jiffies(NSS_GRE_TUNNEL_TX_TIMEOUT)); + + if (!ret) { + nss_warning("%px: GRE Tunnel msg tx failed due to timeout\n", nss_ctx); + gre_tunnel_pvt.response = NSS_TX_FAILURE; + } + + status = gre_tunnel_pvt.response; + up(&gre_tunnel_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_gre_tunnel_tx_msg_sync); + +/* + * nss_gre_tunnel_msg_init() + * Initialize gre_tunnel msg. + */ +void nss_gre_tunnel_msg_init(struct nss_gre_tunnel_msg *ngtm, uint16_t if_num, + uint32_t type, uint32_t len, void *cb, void *app_data) +{ + nss_cmn_msg_init(&ngtm->cm, if_num, type, len, cb, app_data); +} +EXPORT_SYMBOL(nss_gre_tunnel_msg_init); + +/* + * nss_gre_tunnel_register_if() + * Register netdev + */ +struct nss_ctx_instance *nss_gre_tunnel_register_if(uint32_t if_num, + nss_gre_tunnel_data_callback_t cb, + nss_gre_tunnel_msg_callback_t ev_cb, + struct net_device *netdev, + uint32_t features, + void *app_ctx) +{ + int32_t i; + + struct nss_ctx_instance *nss_ctx = nss_gre_tunnel_get_ctx(); + + BUG_ON(!nss_gre_tunnel_verify_if_num(if_num)); + + spin_lock_bh(&nss_gre_tunnel_stats_session_debug_lock); + for (i = 0; i < NSS_MAX_GRE_TUNNEL_SESSIONS; i++) { + if (!nss_gre_tunnel_session_debug_stats[i].valid) { + nss_gre_tunnel_session_debug_stats[i].valid = true; + nss_gre_tunnel_session_debug_stats[i].if_num = if_num; + nss_gre_tunnel_session_debug_stats[i].if_index = netdev->ifindex; + break; + } + } + spin_unlock_bh(&nss_gre_tunnel_stats_session_debug_lock); + + if (i == NSS_MAX_GRE_TUNNEL_SESSIONS) { + nss_warning("%px: Cannot find free slot for GRE Tunnel session stats, I/F:%u\n", nss_ctx, if_num); + return NULL; + } + + if (nss_ctx->subsys_dp_register[if_num].ndev) { + nss_warning("%px: Cannot find free slot for GRE Tunnel NSS I/F:%u\n", nss_ctx, if_num); + nss_gre_tunnel_session_debug_stats[i].valid = false; + nss_gre_tunnel_session_debug_stats[i].if_num = 0; + nss_gre_tunnel_session_debug_stats[i].if_index = 0; + return NULL; + } + + nss_core_register_subsys_dp(nss_ctx, if_num, cb, NULL, app_ctx, netdev, features); + + nss_top_main.gre_tunnel_msg_callback = ev_cb; + nss_core_register_handler(nss_ctx, if_num, nss_gre_tunnel_handler, app_ctx); + nss_gre_tunnel_stats_dentry_create(); + + return nss_ctx; +} +EXPORT_SYMBOL(nss_gre_tunnel_register_if); + +/* + * nss_gre_tunnel_unregister_if() + * Unregister netdev + */ +void nss_gre_tunnel_unregister_if(uint32_t if_num) +{ + int32_t i; + struct nss_ctx_instance *nss_ctx = nss_gre_tunnel_get_ctx(); + + BUG_ON(!nss_gre_tunnel_verify_if_num(if_num)); + + spin_lock_bh(&nss_gre_tunnel_stats_session_debug_lock); + for (i = 0; i < NSS_MAX_GRE_TUNNEL_SESSIONS; i++) { + if (nss_gre_tunnel_session_debug_stats[i].if_num == if_num) { + memset(&nss_gre_tunnel_session_debug_stats[i], 0, + sizeof(struct nss_gre_tunnel_stats_session_debug)); + break; + } + } + spin_unlock_bh(&nss_gre_tunnel_stats_session_debug_lock); + + if (i == NSS_MAX_GRE_TUNNEL_SESSIONS) { + nss_warning("%px: Cannot find debug stats for GRE Tunnel session: %d\n", nss_ctx, if_num); + return; + } + + if (!nss_ctx->subsys_dp_register[if_num].ndev) { + nss_warning("%px: Cannot find registered netdev for GRE Tunnel NSS I/F: %d\n", nss_ctx, if_num); + + return; + } + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + + nss_top_main.gre_tunnel_msg_callback = NULL; + nss_core_unregister_handler(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_gre_tunnel_unregister_if); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_tunnel_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_gre_tunnel_log.c new file mode 100644 index 000000000..6af7b56b9 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_tunnel_log.c @@ -0,0 +1,168 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_gre_tunnel_log.c + * NSS GRE Tunnel logger file. + */ + +#include "nss_core.h" + +/* + * nss_gre_tunnel_log_message_types_str + * NSS GRE Tunnel message strings + */ +static int8_t *nss_gre_tunnel_log_message_types_str[NSS_GRE_TUNNEL_MSG_MAX] __maybe_unused = { + "GRE Tunnel configure", + "GRE Tunnel session destroy", + "GRE Tunnel stats", + "GRE Tunnel configure DI to WLAN ID", + "GRE Tunnel message inquiry" +}; + +/* + * nss_gre_tunnel_log_configure_msg() + * Log NSS GRE Tunnel configure message. + */ +static void nss_gre_tunnel_log_configure_msg(struct nss_gre_tunnel_msg *ngm) +{ + struct nss_gre_tunnel_configure *ngcm __maybe_unused = &ngm->msg.configure; + nss_trace("%px: NSS GRE Tunnel configure message \n" + "Meta Header Version: %d\n" + "GRE Mode: %x\n" + "IP Type: %x\n" + "Encryption Type: %d\n" + "Source Port: %d\n" + "Destination Port: %d\n" + "Crypto Node Identifier: %d\n" + "Encryption Crypto Index: %d\n" + "Decryption Crypto Index: %d\n" + "Word0 header: %d\n" + "Initialization Vector: %px\n" + "Sibling Interface Number: %d\n" + "TTL: %d\n" + "RPS: %d\n" + "Reserved: %x\n" + "Word1 Header: %x\n" + "Word2 Header: %x\n" + "Word3 Header: %x\n", + ngcm, ngcm->mh_version, ngcm->gre_mode, + ngcm->ip_type, ngcm->encrypt_type, + ngcm->src_port, ngcm->dest_port, + ngcm->crypto_node_id, ngcm->crypto_idx_encrypt, + ngcm->crypto_idx_decrypt, ngcm->word0, + ngcm->iv_val, ngcm->sibling_if, + ngcm->ttl, ngcm->rps, + ngcm->reserved, ngcm->word1, + ngcm->word2, ngcm->word3); + + /* + * Continuation of log message. Different identifiers based on ip_type + */ + if (ngcm->ip_type == NSS_GRE_TUNNEL_IP_IPV6) { + nss_trace("Source IP: %pI6\n" + "Destination IP: %pI6\n", + ngcm->src_ip, ngcm->dest_ip); + } else if (ngcm->ip_type == NSS_GRE_TUNNEL_IP_IPV4) { + nss_trace("Source IP: %pI4\n" + "Destination IP: %pI4\n", + ngcm->src_ip, ngcm->dest_ip); + } +} + +/* + * nss_gre_tunnel_log_di_to_wlan_id_msg() + * Log NSS GRE Tunnel Dynamic Interface to WLAN ID message. + */ +static void nss_gre_tunnel_log_di_to_wlan_id_msg(struct nss_gre_tunnel_msg *ngm) +{ + struct nss_gre_tunnel_di_to_wlan_id *ngdm __maybe_unused = &ngm->msg.dtwi; + nss_trace("%px: NSS GRE Dynamic Interface to WLAN ID message: \n" + "Dynamic Interface Number: %d\n" + "WLAN ID: %x\n", + ngdm, ngdm->dynamic_interface_num, + ngdm->wlan_id); +} + +/* + * nss_gre_tunnel_log_verbose() + * Log message contents. + */ +static void nss_gre_tunnel_log_verbose(struct nss_gre_tunnel_msg *ngm) +{ + switch (ngm->cm.type) { + case NSS_GRE_TUNNEL_MSG_CONFIGURE: + case NSS_GRE_TUNNEL_MSG_INQUIRY: + nss_gre_tunnel_log_configure_msg(ngm); + break; + + case NSS_GRE_TUNNEL_MSG_CONFIGURE_DI_TO_WLAN_ID: + nss_gre_tunnel_log_di_to_wlan_id_msg(ngm); + break; + + case NSS_GRE_TUNNEL_MSG_SESSION_DESTROY: + case NSS_GRE_TUNNEL_MSG_STATS: + /* + * No log for these valid messages. + */ + break; + + default: + nss_trace("%px: Invalid message type\n", ngm); + break; + } +} + +/* + * nss_gre_tunnel_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_gre_tunnel_log_tx_msg(struct nss_gre_tunnel_msg *ngm) +{ + if (ngm->cm.type >= NSS_GRE_TUNNEL_MSG_MAX) { + nss_warning("%px: Invalid message type\n", ngm); + return; + } + + nss_info("%px: type[%d]:%s\n", ngm, ngm->cm.type, nss_gre_tunnel_log_message_types_str[ngm->cm.type]); + nss_gre_tunnel_log_verbose(ngm); +} + +/* + * nss_gre_tunnel_log_rx_msg() + * Log messages received from FW. + */ +void nss_gre_tunnel_log_rx_msg(struct nss_gre_tunnel_msg *ngm) +{ + if (ngm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", ngm); + return; + } + + if (ngm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ngm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", ngm, ngm->cm.type, + nss_gre_tunnel_log_message_types_str[ngm->cm.type], + ngm->cm.response, nss_cmn_response_str[ngm->cm.response]); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s\n", + ngm, ngm->cm.type, nss_gre_tunnel_log_message_types_str[ngm->cm.type], + ngm->cm.response, nss_cmn_response_str[ngm->cm.response]); + +verbose: + nss_gre_tunnel_log_verbose(ngm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_tunnel_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_gre_tunnel_log.h new file mode 100644 index 000000000..be0751301 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_tunnel_log.h @@ -0,0 +1,41 @@ +/* + ************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_GRE_TUNNEL_LOG_H +#define __NSS_GRE_TUNNEL_LOG_H + +/* + * nss_gre_tunnel.h + * NSS GRE Tunnel header file. + */ + +/* + * Logger APIs + */ + +/* + * nss_gre_tunnel_log_tx_msg + * Logs a gre_tunnel message that is sent to the NSS firmware. + */ +void nss_gre_tunnel_log_tx_msg(struct nss_gre_tunnel_msg *ngm); + +/* + * nss_gre_tunnel_log_rx_msg + * Logs a gre_tunnel message that is received from the NSS firmware. + */ +void nss_gre_tunnel_log_rx_msg(struct nss_gre_tunnel_msg *ngm); + +#endif /* __NSS_GRE_TUNNEL_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_tunnel_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_gre_tunnel_stats.c new file mode 100644 index 000000000..8a957f26e --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_tunnel_stats.c @@ -0,0 +1,249 @@ +/* + ************************************************************************** + * Copyright (c) 2017, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_gre_tunnel_stats.h" + +DEFINE_SPINLOCK(nss_gre_tunnel_stats_session_debug_lock); +struct nss_gre_tunnel_stats_session_debug nss_gre_tunnel_session_debug_stats[NSS_MAX_GRE_TUNNEL_SESSIONS]; + +/* + * nss_gre_tunnel_stats_session_debug_str + * GRE Tunnel statistics strings for nss session stats + */ +static int8_t *nss_gre_tunnel_stats_session_debug_str[NSS_GRE_TUNNEL_STATS_SESSION_MAX] = { + "RX_PKTS", + "TX_PKTS", + "RX_QUEUE_0_DROPPED", + "RX_QUEUE_1_DROPPED", + "RX_QUEUE_2_DROPPED", + "RX_QUEUE_3_DROPPED", + "RX_MALFORMED", + "RX_INVALID_PROT", + "DECAP_QUEUE_FULL", + "RX_SINGLE_REC_DGRAM", + "RX_INVALID_REC_DGRAM", + "BUFFER_ALLOC_FAIL", + "BUFFER_COPY_FAIL", + "OUTFLOW_QUEUE_FULL", + "TX_DROPPED_HROOM", + "RX_CBUFFER_ALLOC_FAIL", + "RX_CENQUEUE_FAIL", + "RX_DECRYPT_DONE", + "RX_FORWARD_ENQUEUE_FAIL", + "TX_CBUFFER_ALLOC_FAIL", + "TX_CENQUEUE_FAIL", + "TX_DROPPED_TROOM", + "TX_FORWARD_ENQUEUE_FAIL", + "TX_CIPHER_DONE", + "CRYPTO_NOSUPP", + "RX_DROPPED_MH_VERSION", + "RX_UNALIGNED_PKT", +}; + +/* + * nss_gre_tunnel_stats_session_sync() + * Sync function for GRE Tunnel statistics + */ +void nss_gre_tunnel_stats_session_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_tunnel_stats *stats_msg, + uint16_t if_num) +{ + int i; + struct nss_gre_tunnel_stats_session_debug *s = NULL; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + spin_lock_bh(&nss_gre_tunnel_stats_session_debug_lock); + for (i = 0; i < NSS_MAX_GRE_TUNNEL_SESSIONS; i++) { + if (nss_gre_tunnel_session_debug_stats[i].if_num == if_num) { + s = &nss_gre_tunnel_session_debug_stats[i]; + break; + } + } + + if (!s) { + spin_unlock_bh(&nss_gre_tunnel_stats_session_debug_lock); + nss_warning("%px: Session not found: %u", nss_ctx, if_num); + return; + } + + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_PKTS] += stats_msg->node_stats.rx_packets; + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_TX_PKTS] += stats_msg->node_stats.tx_packets; + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_QUEUE_0_DROPPED + i] += stats_msg->node_stats.rx_dropped[i]; + } + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_MALFORMED] += stats_msg->rx_malformed; + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_INVALID_PROT] += stats_msg->rx_invalid_prot; + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_DECAP_QUEUE_FULL] += stats_msg->decap_queue_full; + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_SINGLE_REC_DGRAM] += stats_msg->rx_single_rec_dgram; + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_INVALID_REC_DGRAM] += stats_msg->rx_invalid_rec_dgram; + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_BUFFER_ALLOC_FAIL] += stats_msg->buffer_alloc_fail; + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_BUFFER_COPY_FAIL] += stats_msg->buffer_copy_fail; + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_OUTFLOW_QUEUE_FULL] += stats_msg->outflow_queue_full; + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_DROPPED_HROOM] += stats_msg->rx_dropped_hroom; + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_CBUFFER_ALLOC_FAIL] += stats_msg->rx_cbuf_alloc_fail; + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_CENQUEUE_FAIL] += stats_msg->rx_cenqueue_fail; + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_DECRYPT_DONE] += stats_msg->rx_decrypt_done; + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_FORWARD_ENQUEUE_FAIL] += stats_msg->rx_forward_enqueue_fail; + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_TX_CBUFFER_ALLOC_FAIL] += stats_msg->tx_cbuf_alloc_fail; + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_TX_CENQUEUE_FAIL] += stats_msg->tx_cenqueue_fail; + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_DROPPED_TROOM] += stats_msg->rx_dropped_troom; + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_TX_FORWARD_ENQUEUE_FAIL] += stats_msg->tx_forward_enqueue_fail; + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_TX_CIPHER_DONE] += stats_msg->tx_cipher_done; + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_CRYPTO_NOSUPP] += stats_msg->crypto_nosupp; + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_DROPPED_MH_VERSION] += stats_msg->rx_dropped_mh_ver; + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_RX_UNALIGNED_PKT] += stats_msg->rx_unaligned_pkt; + + /* + * Copy crypto resp err stats. + */ + for (i = 0; i < NSS_CRYPTO_CMN_RESP_ERROR_MAX; i++) { +#if defined(NSS_HAL_IPQ807x_SUPPORT) + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_MAX + i] += stats_msg->crypto_resp_error[i]; +#else + s->stats[NSS_GRE_TUNNEL_STATS_SESSION_MAX + i] = 0; +#endif + } + + spin_unlock_bh(&nss_gre_tunnel_stats_session_debug_lock); +} + +/* + * nss_gre_tunnel_stats_session_debug_get() + * Get session GRE Tunnel statitics. + */ +static void nss_gre_tunnel_stats_session_debug_get(struct nss_gre_tunnel_stats_session_debug *stats) +{ + int i; + + if (!stats) { + nss_warning("No memory to copy gre_tunnel session stats"); + return; + } + + spin_lock_bh(&nss_gre_tunnel_stats_session_debug_lock); + for (i = 0; i < NSS_MAX_GRE_TUNNEL_SESSIONS; i++) { + if (nss_gre_tunnel_session_debug_stats[i].valid) { + memcpy(stats, &nss_gre_tunnel_session_debug_stats[i], + sizeof(struct nss_gre_tunnel_stats_session_debug)); + stats++; + } + } + spin_unlock_bh(&nss_gre_tunnel_stats_session_debug_lock); +} + +/* + * nss_gre_tunnel_stats_read() + * Read GRE Tunnel session statistics + */ +static ssize_t nss_gre_tunnel_stats_read(struct file *fp, char __user *ubuf, + size_t sz, loff_t *ppos) +{ + uint32_t max_output_lines = 2 + (NSS_MAX_GRE_TUNNEL_SESSIONS + * (NSS_GRE_TUNNEL_STATS_SESSION_MAX + 2)) + 2; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + struct net_device *dev; + int id, i; + struct nss_gre_tunnel_stats_session_debug *gre_tunnel_session_stats = NULL; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + gre_tunnel_session_stats = kzalloc((sizeof(struct nss_gre_tunnel_stats_session_debug) + * NSS_MAX_GRE_TUNNEL_SESSIONS), GFP_KERNEL); + if (unlikely(gre_tunnel_session_stats == NULL)) { + nss_warning("Could not allocate memory for populating GRE Tunnel stats"); + kfree(lbuf); + return 0; + } + + /* + * Get all stats + */ + nss_gre_tunnel_stats_session_debug_get(gre_tunnel_session_stats); + + /* + * Session stats + */ + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "\nGRE Tunnel session stats start:\n\n"); + + for (id = 0; id < NSS_MAX_GRE_TUNNEL_SESSIONS; id++) { + if (!gre_tunnel_session_stats[id].valid) + break; + + dev = dev_get_by_index(&init_net, gre_tunnel_session_stats[id].if_index); + if (likely(dev)) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "%d. nss interface id=%d, netdevice=%s\n", + id, gre_tunnel_session_stats[id].if_num, + dev->name); + dev_put(dev); + } else { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "%d. nss interface id=%d\n", id, + gre_tunnel_session_stats[id].if_num); + } + + for (i = 0; i < NSS_GRE_TUNNEL_STATS_SESSION_MAX; i++) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "\t%s = %llu\n", + nss_gre_tunnel_stats_session_debug_str[i], + gre_tunnel_session_stats[id].stats[i]); + } + + /* + * Print crypto resp err stats. + * TODO: We are not printing with the right enum string for crypto. This + * is intentional since we atleast want to see some stats for now. + */ + for (i = 0; i < NSS_CRYPTO_CMN_RESP_ERROR_MAX; i++) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "\t%s = %llu\n", + nss_gre_tunnel_stats_session_debug_str[i], + gre_tunnel_session_stats[id].stats[NSS_GRE_TUNNEL_STATS_SESSION_MAX + i]); + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n"); + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "\nGRE Tunnel session stats end\n"); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr); + + kfree(gre_tunnel_session_stats); + kfree(lbuf); + return bytes_read; +} + +/* + * nss_gre_tunnel_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(gre_tunnel) + +/* + * nss_gre_tunnel_stats_dentry_create() + * Create gre tunnel statistics debug entry. + */ +void nss_gre_tunnel_stats_dentry_create(void) +{ + nss_stats_create_dentry("gre_tunnel", &nss_gre_tunnel_stats_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_gre_tunnel_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_gre_tunnel_stats.h new file mode 100644 index 000000000..c20ed930c --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_gre_tunnel_stats.h @@ -0,0 +1,76 @@ +/* + ****************************************************************************** + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_GRE_TUNNEL_STATS_H +#define __NSS_GRE_TUNNEL_STATS_H + +/* + * GRE Tunnel session debug statistic counters + */ +enum nss_gre_tunnel_stats_session { + NSS_GRE_TUNNEL_STATS_SESSION_RX_PKTS, + NSS_GRE_TUNNEL_STATS_SESSION_TX_PKTS, + NSS_GRE_TUNNEL_STATS_SESSION_RX_QUEUE_0_DROPPED, + NSS_GRE_TUNNEL_STATS_SESSION_RX_QUEUE_1_DROPPED, + NSS_GRE_TUNNEL_STATS_SESSION_RX_QUEUE_2_DROPPED, + NSS_GRE_TUNNEL_STATS_SESSION_RX_QUEUE_3_DROPPED, + NSS_GRE_TUNNEL_STATS_SESSION_RX_MALFORMED, + NSS_GRE_TUNNEL_STATS_SESSION_RX_INVALID_PROT, + NSS_GRE_TUNNEL_STATS_SESSION_DECAP_QUEUE_FULL, + NSS_GRE_TUNNEL_STATS_SESSION_RX_SINGLE_REC_DGRAM, + NSS_GRE_TUNNEL_STATS_SESSION_RX_INVALID_REC_DGRAM, + NSS_GRE_TUNNEL_STATS_SESSION_BUFFER_ALLOC_FAIL, + NSS_GRE_TUNNEL_STATS_SESSION_BUFFER_COPY_FAIL, + NSS_GRE_TUNNEL_STATS_SESSION_OUTFLOW_QUEUE_FULL, + NSS_GRE_TUNNEL_STATS_SESSION_RX_DROPPED_HROOM, + NSS_GRE_TUNNEL_STATS_SESSION_RX_CBUFFER_ALLOC_FAIL, + NSS_GRE_TUNNEL_STATS_SESSION_RX_CENQUEUE_FAIL, + NSS_GRE_TUNNEL_STATS_SESSION_RX_DECRYPT_DONE, + NSS_GRE_TUNNEL_STATS_SESSION_RX_FORWARD_ENQUEUE_FAIL, + NSS_GRE_TUNNEL_STATS_SESSION_TX_CBUFFER_ALLOC_FAIL, + NSS_GRE_TUNNEL_STATS_SESSION_TX_CENQUEUE_FAIL, + NSS_GRE_TUNNEL_STATS_SESSION_RX_DROPPED_TROOM, + NSS_GRE_TUNNEL_STATS_SESSION_TX_FORWARD_ENQUEUE_FAIL, + NSS_GRE_TUNNEL_STATS_SESSION_TX_CIPHER_DONE, + NSS_GRE_TUNNEL_STATS_SESSION_CRYPTO_NOSUPP, + NSS_GRE_TUNNEL_STATS_SESSION_RX_DROPPED_MH_VERSION, + NSS_GRE_TUNNEL_STATS_SESSION_RX_UNALIGNED_PKT, + NSS_GRE_TUNNEL_STATS_SESSION_MAX, +}; + +/* + * GRE Tunnel session debug statistics + */ +struct nss_gre_tunnel_stats_session_debug { + uint64_t stats[NSS_GRE_TUNNEL_STATS_SESSION_MAX + NSS_CRYPTO_CMN_RESP_ERROR_MAX]; + int32_t if_index; + uint32_t if_num; /* nss interface number */ + bool valid; +}; + +/* + * Data structures to store GRE Tunnel nss debug stats + */ +extern spinlock_t nss_gre_tunnel_stats_session_debug_lock; +extern struct nss_gre_tunnel_stats_session_debug nss_gre_tunnel_session_debug_stats[NSS_MAX_GRE_TUNNEL_SESSIONS]; + +/* + * GRE Tunnel statistics APIs + */ +extern void nss_gre_tunnel_stats_session_sync(struct nss_ctx_instance *nss_ctx, struct nss_gre_tunnel_stats *stats_msg, uint16_t if_num); +extern void nss_gre_tunnel_stats_dentry_create(void); + +#endif /* __NSS_GRE_TUNNEL_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_hal/fsm9010/nss_hal_pvt.c b/feeds/ipq807x/qca-nss-drv/src/nss_hal/fsm9010/nss_hal_pvt.c new file mode 100644 index 000000000..ab3b8ec6d --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_hal/fsm9010/nss_hal_pvt.c @@ -0,0 +1,341 @@ +/* + ************************************************************************** + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * nss_hal_pvt.c + * NSS HAL private APIs. + */ + +#include +#include +#include +#include +#include +#include "nss_hal.h" +#include "nss_core.h" + +#define NSS_H2N_INTR_EMPTY_BUFFER_QUEUE_BIT 0 +#define NSS_H2N_INTR_DATA_COMMAND_QUEUE_BIT 1 +#define NSS_H2N_INTR_TX_UNBLOCKED_BIT 11 +#define NSS_H2N_INTR_TRIGGER_COREDUMP_BIT 15 + +/* + * Interrupt type to cause vector. + */ +static uint32_t intr_cause[] = {(1 << NSS_H2N_INTR_EMPTY_BUFFER_QUEUE_BIT), + (1 << NSS_H2N_INTR_DATA_COMMAND_QUEUE_BIT), + (1 << NSS_H2N_INTR_TX_UNBLOCKED_BIT), + (1 << NSS_H2N_INTR_TRIGGER_COREDUMP_BIT)}; + +/* + * nss_hal_wq_function() + * Added to Handle BH requests to kernel + */ +void nss_hal_wq_function(struct work_struct *work) +{ + /* + * Not supported in FSM9010 + */ + kfree((void *)work); +} + +/* + * nss_hal_get_num_irqs() + * get number of irqs from interrupt resource of device tree + */ +static inline int nss_hal_get_num_irqs(struct device_node *np) +{ + int num_irqs = 0; + + while (of_irq_to_resource(np, num_irqs, NULL)) { + num_irqs++; + } + + return num_irqs; +} + +/* + * nss_hal_handle_irq() + * HLOS interrupt handler for nss interrupts + */ +static irqreturn_t nss_hal_handle_irq(int irq, void *ctx) +{ + struct int_ctx_instance *int_ctx = (struct int_ctx_instance *) ctx; + struct nss_ctx_instance *nss_ctx = int_ctx->nss_ctx; + + /* + * Mask interrupt until our bottom half re-enables it + */ + nss_hal_disable_interrupt(nss_ctx, int_ctx->shift_factor, NSS_HAL_SUPPORTED_INTERRUPTS); + + /* + * Schedule tasklet to process interrupt cause + */ + napi_schedule(&int_ctx->napi); + return IRQ_HANDLED; +} + +/* + * nss_hal_of_get_pdata() + * Retrieve platform data from device node. + */ +static struct nss_platform_data *__nss_hal_of_get_pdata(struct platform_device *pdev) +{ + struct device_node *np = of_node_get(pdev->dev.of_node); + struct nss_platform_data *npd = NULL; + struct nss_ctx_instance *nss_ctx = NULL; + struct nss_top_instance *nss_top = &nss_top_main; + struct resource res_nphys, res_vphys; + int32_t i; + + npd = devm_kzalloc(&pdev->dev, sizeof(struct nss_platform_data), GFP_KERNEL); + if (!npd) { + return NULL; + } + + if (of_property_read_u32(np, "qcom,id", &npd->id) + || of_property_read_u32(np, "qcom,num-queue", &npd->num_queue)) { + pr_err("%s: error reading critical device node properties\n", np->name); + goto out; + } + + if (of_property_read_u32(np, "qcom,num-irq", &npd->num_irq)) { + npd->num_irq = nss_hal_get_num_irqs(np); + } + + if (npd->num_irq < npd->num_queue) { + pr_err("%s: not enough interrupts configured for all the queues\n", np->name); + goto out; + } + + if (npd->num_irq > NSS_MAX_IRQ_PER_CORE) { + pr_err("%s: exceeds maximum interrupt numbers per core\n", np->name); + goto out; + } + + nss_ctx = &nss_top->nss[npd->id]; + nss_ctx->id = npd->id; + + if (of_address_to_resource(np, 0, &res_nphys) != 0) { + nss_info_always("%px: nss%d: of_address_to_resource() fail for nphys\n", nss_ctx, nss_ctx->id); + goto out; + } + + if (of_address_to_resource(np, 1, &res_vphys) != 0) { + nss_info_always("%px: nss%d: of_address_to_resource() fail for vphys\n", nss_ctx, nss_ctx->id); + goto out; + } + + /* + * Save physical addresses + */ + npd->nphys = res_nphys.start; + npd->vphys = res_vphys.start; + + npd->nmap = ioremap_nocache(npd->nphys, resource_size(&res_nphys)); + if (!npd->nmap) { + nss_info_always("%px: nss%d: ioremap() fail for nphys\n", nss_ctx, nss_ctx->id); + goto out; + } + + npd->vmap = ioremap_cache(npd->vphys, resource_size(&res_vphys)); + if (!npd->vmap) { + nss_info_always("%px: nss%d: ioremap() fail for vphys\n", nss_ctx, nss_ctx->id); + goto out; + } + + /* + * Get IRQ numbers + */ + for (i = 0 ; i < npd->num_irq; i++) { + npd->irq[i] = irq_of_parse_and_map(np, i); + if (!npd->irq[i]) { + nss_info_always("%px: nss%d: irq_of_parse_and_map() fail for irq %d\n", nss_ctx, nss_ctx->id, i); + goto out; + } + } + + nss_hal_dt_parse_features(np, npd); + + of_node_put(np); + return npd; + +out: + if (npd->nmap) { + iounmap((void *)npd->nmap); + } + + if (npd->vmap) { + iounmap((void *)npd->vmap); + } + + devm_kfree(&pdev->dev, npd); + of_node_put(np); + return NULL; +} + +/* + * __nss_hal_debug_enable() + * Enable NSS debug + */ +static void __nss_hal_debug_enable(void) +{ + return; +} + +/* + * __nss_hal_common_reset() + */ +static int __nss_hal_common_reset(struct platform_device *nss_dev) +{ + return 0; +} + +/* + * __nss_hal_core_reset() + */ +static int __nss_hal_core_reset(struct platform_device *nss_dev, void __iomem *map, uint32_t addr, uint32_t clk_src) +{ + return 0; +} + +/* + * __nss_hal_firmware_load() + */ +static int __nss_hal_firmware_load(struct nss_ctx_instance *nss_ctx, struct platform_device *nss_dev, struct nss_platform_data *npd) +{ + return 0; +} + +/* + * __nss_hal_clock_configure() + */ +static int __nss_hal_clock_configure(struct nss_ctx_instance *nss_ctx, struct platform_device *nss_dev, struct nss_platform_data *npd) +{ + return 0; +} + +/* + * __nss_hal_read_interrupt_cause() + */ +static void __nss_hal_read_interrupt_cause(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t *cause) +{ + uint32_t value = nss_read_32(nss_ctx->nmap, NSS_REGS_N2H_INTR_STATUS_OFFSET); + *cause = (((value) >> shift_factor) & 0x7FFF); +} + +/* + * __nss_hal_clear_interrupt_cause() + */ +static void __nss_hal_clear_interrupt_cause(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause) +{ + nss_write_32(nss_ctx->nmap, NSS_REGS_N2H_INTR_CLR_OFFSET, (cause << shift_factor)); +} + +/* + * __nss_hal_disable_interrupt() + */ +static void __nss_hal_disable_interrupt(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause) +{ + nss_write_32(nss_ctx->nmap, NSS_REGS_N2H_INTR_MASK_CLR_OFFSET, (cause << shift_factor)); +} + +/* + * __nss_hal_enable_interrupt() + */ +static void __nss_hal_enable_interrupt(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause) +{ + nss_write_32(nss_ctx->nmap, NSS_REGS_N2H_INTR_MASK_SET_OFFSET, (cause << shift_factor)); +} + +/* + * __nss_hal_send_interrupt() + */ +static void __nss_hal_send_interrupt(struct nss_ctx_instance *nss_ctx, uint32_t type) +{ + nss_write_32(nss_ctx->nmap, NSS_REGS_C2C_INTR_SET_OFFSET, intr_cause[type]); +} + +/* + * __nss_hal_request_irq() + */ +static int __nss_hal_request_irq(struct nss_ctx_instance *nss_ctx, struct nss_platform_data *npd, int irq_num) +{ + struct int_ctx_instance *int_ctx = &nss_ctx->int_ctx[irq_num]; + int err; + + if (irq_num == 1) { + int_ctx->shift_factor = 15; + err = request_irq(npd->irq[irq_num], nss_hal_handle_irq, 0, "nss_queue1", int_ctx); + } else { + int_ctx->shift_factor = 0; + err = request_irq(npd->irq[irq_num], nss_hal_handle_irq, 0, "nss", int_ctx); + } + if (err) { + nss_warning("%px: IRQ%d request failed", nss_ctx, npd->irq[irq_num]); + return err; + } + + int_ctx->irq = npd->irq[irq_num]; + netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi, 64); + return 0; +} + +/* + * __nss_hal_init_imem + */ +void __nss_hal_init_imem(struct nss_ctx_instance *nss_ctx) +{ + struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; + + mem_ctx->imem_head = NSS_IMEM_START + NSS_IMEM_SIZE * nss_ctx->id; + mem_ctx->imem_end = mem_ctx->imem_head + NSS_IMEM_SIZE; + mem_ctx->imem_tail = mem_ctx->imem_head; + + nss_info("%px: IMEM init: head: 0x%x end: 0x%x tail: 0x%x\n", nss_ctx, + mem_ctx->imem_head, mem_ctx->imem_end, mem_ctx->imem_tail); +} + +/* + * __nss_hal_init_utcm_shared + */ +bool __nss_hal_init_utcm_shared(struct nss_ctx_instance *nss_ctx, uint32_t *meminfo_start) +{ + /* + * Nothing to be done as there are no UTCM_SHARED defined for fsm9010 + */ + return true; +} + +/* + * nss_hal_fsm9010_ops + */ +struct nss_hal_ops nss_hal_fsm9010_ops = { + .common_reset = __nss_hal_common_reset, + .core_reset = __nss_hal_core_reset, + .clock_configure = __nss_hal_clock_configure, + .firmware_load = __nss_hal_firmware_load, + .debug_enable = __nss_hal_debug_enable, + .of_get_pdata = __nss_hal_of_get_pdata, + .request_irq = __nss_hal_request_irq, + .send_interrupt = __nss_hal_send_interrupt, + .enable_interrupt = __nss_hal_enable_interrupt, + .disable_interrupt = __nss_hal_disable_interrupt, + .clear_interrupt_cause = __nss_hal_clear_interrupt_cause, + .read_interrupt_cause = __nss_hal_read_interrupt_cause, + .init_imem = __nss_hal_init_imem, + .init_utcm_shared = __nss_hal_init_utcm_shared, +}; diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_hal/include/nss_hal.h b/feeds/ipq807x/qca-nss-drv/src/nss_hal/include/nss_hal.h new file mode 100644 index 000000000..d9591a781 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_hal/include/nss_hal.h @@ -0,0 +1,129 @@ +/* + ************************************************************************** + * Copyright (c) 2013, 2016-2020 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * nss_hal.h + * NSS HAL public declarations. + */ + +#ifndef __NSS_HAL_H +#define __NSS_HAL_H + +#include +#include +#include +#include + +extern struct clk *nss_core0_clk; +extern struct clk *nss_core1_clk; +extern struct nss_runtime_sampling nss_runtime_samples; +extern struct clk *nss_fab0_clk; +extern struct clk *nss_fab1_clk; +extern void nss_hal_wq_function(struct work_struct *work); + +#if defined(NSS_HAL_IPQ806X_SUPPORT) +extern struct nss_hal_ops nss_hal_ipq806x_ops; +#endif +#if defined(NSS_HAL_IPQ807x_SUPPORT) +extern struct nss_hal_ops nss_hal_ipq807x_ops; +#endif +#if defined(NSS_HAL_IPQ60XX_SUPPORT) +extern struct nss_hal_ops nss_hal_ipq60xx_ops; +#endif +#if defined(NSS_HAL_IPQ50XX_SUPPORT) +extern struct nss_hal_ops nss_hal_ipq50xx_ops; +#endif +#if defined(NSS_HAL_FSM9010_SUPPORT) +extern struct nss_hal_ops nss_hal_fsm9010_ops; +#endif + +#define NSS_HAL_SUPPORTED_INTERRUPTS (NSS_N2H_INTR_EMPTY_BUFFER_QUEUE | \ + NSS_N2H_INTR_DATA_QUEUE_0 | \ + NSS_N2H_INTR_DATA_QUEUE_1 | \ + NSS_N2H_INTR_EMPTY_BUFFERS_SOS | \ + NSS_N2H_INTR_TX_UNBLOCKED | \ + NSS_N2H_INTR_COREDUMP_COMPLETE | \ + NSS_N2H_INTR_PROFILE_DMA | \ + NSS_N2H_INTR_PAGED_EMPTY_BUFFERS_SOS) + +/* + * nss_hal_read_interrupt_cause() + */ +static inline void nss_hal_read_interrupt_cause(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t *cause) +{ + nss_top_main.hal_ops->read_interrupt_cause(nss_ctx, shift_factor, cause); +} + +/* + * nss_hal_clear_interrupt_cause() + */ +static inline void nss_hal_clear_interrupt_cause(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause) +{ + nss_top_main.hal_ops->clear_interrupt_cause(nss_ctx, shift_factor, cause); +} + +/* + * nss_hal_disable_interrupt() + */ +static inline void nss_hal_disable_interrupt(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause) +{ + nss_top_main.hal_ops->disable_interrupt(nss_ctx, shift_factor, cause); +} + +/* + * nss_hal_enable_interrupt() + */ +static inline void nss_hal_enable_interrupt(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause) +{ + nss_top_main.hal_ops->enable_interrupt(nss_ctx, shift_factor, cause); +} + +/* + * nss_hal_send_interrupt() + */ +static inline void nss_hal_send_interrupt(struct nss_ctx_instance *nss_ctx, uint32_t cause) +{ + nss_top_main.hal_ops->send_interrupt(nss_ctx, cause); +} + +/* + * nss_hal_debug_enable() + */ +static inline void nss_hal_debug_enable(void) +{ + nss_top_main.hal_ops->debug_enable(); +} + +/* + * nss_hal_probe() + */ +int nss_hal_probe(struct platform_device *nss_dev); + +/* + * nss_hal_remove() + */ +int nss_hal_remove(struct platform_device *nss_dev); + +/* + * nss_hal_firmware_load() + */ +int nss_hal_firmware_load(struct nss_ctx_instance *nss_ctx, struct platform_device *nss_dev, struct nss_platform_data *npd); + +/* + * nss_hal_dt_parse_features() + */ +void nss_hal_dt_parse_features(struct device_node *np, struct nss_platform_data *npd); +#endif /* __NSS_HAL_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_hal/include/nss_hal_ops.h b/feeds/ipq807x/qca-nss-drv/src/nss_hal/include/nss_hal_ops.h new file mode 100644 index 000000000..736d37e6c --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_hal/include/nss_hal_ops.h @@ -0,0 +1,49 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * nss_hal_ops.h + * NSS HAL ops structure declaration. + */ + +#ifndef __NSS_HAL_OPS_H +#define __NSS_HAL_OPS_H + +#if (NSS_DT_SUPPORT != 1) +#include +#include +#endif + +/* + * nss_hal_ops defines the HAL layer API required to support multiple targets + */ +struct nss_hal_ops { + int (*common_reset)(struct platform_device *pdev); + int (*core_reset)(struct platform_device *nss_dev, void __iomem *map, uint32_t addr, uint32_t clk_src); + int (*clock_configure)(struct nss_ctx_instance *nss_ctx, struct platform_device *nss_dev, struct nss_platform_data *npd); + void (*debug_enable)(void); + struct nss_platform_data * (*of_get_pdata)(struct platform_device *pdev); + int (*firmware_load)(struct nss_ctx_instance *nss_ctx, struct platform_device *nss_dev, struct nss_platform_data *npd); + void (*read_interrupt_cause)(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t *cause); + int (*request_irq)(struct nss_ctx_instance *nss_ctx, struct nss_platform_data *npd, int irq_num); + void (*clear_interrupt_cause)(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause); + void (*send_interrupt)(struct nss_ctx_instance *nss_ctx, uint32_t type); + void (*enable_interrupt)(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause); + void (*disable_interrupt)(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause); + void (*init_imem)(struct nss_ctx_instance *nss_ctx); + bool (*init_utcm_shared)(struct nss_ctx_instance *nss_ctx, uint32_t *meminfo_start); +}; +#endif /* __NSS_HAL_OPS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_hal/include/nss_regs.h b/feeds/ipq807x/qca-nss-drv/src/nss_hal/include/nss_regs.h new file mode 100644 index 000000000..765e8a197 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_hal/include/nss_regs.h @@ -0,0 +1,108 @@ +/* + ************************************************************************** + * Copyright (c) 2013, 2015-2017, 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * nss_regs.h + * NSS register definitions. + */ + +#ifndef __NSS_REGS_H +#define __NSS_REGS_H + +#include +#include + +/* + * CSM register offsets + */ +#define NSS_REGS_CORE_ID_OFFSET 0x0000 +#define NSS_REGS_RESET_CTRL_OFFSET 0x0004 +#define NSS_REGS_CORE_BAR_OFFSET 0x0008 +#define NSS_REGS_CORE_AMC_OFFSET 0x000c +#define NSS_REGS_CORE_BOOT_ADDR_OFFSET 0x0010 +#define NSS_REGS_C2C_INTR_STATUS_OFFSET 0x0014 +#define NSS_REGS_C2C_INTR_SET_OFFSET 0x0018 +#define NSS_REGS_C2C_INTR_CLR_OFFSET 0x001c +#define NSS_REGS_N2H_INTR_STATUS_OFFSET 0x0020 +#define NSS_REGS_N2H_INTR_SET_OFFSET 0x0024 +#define NSS_REGS_N2H_INTR_CLR_OFFSET 0x0028 +#define NSS_REGS_N2H_INTR_MASK_OFFSET 0x002c +#define NSS_REGS_N2H_INTR_MASK_SET_OFFSET 0x0030 +#define NSS_REGS_N2H_INTR_MASK_CLR_OFFSET 0x0034 +#define NSS_REGS_CORE_INT_STAT0_TYPE_OFFSET 0x0038 +#define NSS_REGS_CORE_INT_STAT1_TYPE_OFFSET 0x003c +#define NSS_REGS_CORE_INT_STAT2_TYPE_OFFSET 0x0040 +#define NSS_REGS_CORE_INT_STAT3_TYPE_OFFSET 0x0044 +#define NSS_REGS_CORE_IFETCH_RANGE_OFFSET 0x0048 + +/* + * FPB register offsets + */ +#define NSS_REGS_FPB_CSR_CFG_OFFSET 0x0004 + +/* + * Defines for N2H interrupts + */ +#define NSS_N2H_INTR_EMPTY_BUFFER_QUEUE (1 << 0) +#define NSS_N2H_INTR_DATA_QUEUE_0 (1 << 1) +#define NSS_N2H_INTR_DATA_QUEUE_1 (1 << 2) +#define NSS_N2H_INTR_DATA_QUEUE_2 (1 << 3) +#define NSS_N2H_INTR_DATA_QUEUE_3 (1 << 4) +#define NSS_N2H_INTR_EMPTY_BUFFERS_SOS (1 << 10) +#define NSS_N2H_INTR_TX_UNBLOCKED (1 << 11) +#define NSS_N2H_INTR_PAGED_EMPTY_BUFFERS_SOS (1 << 12) +#define NSS_N2H_INTR_PROFILE_DMA (1 << 13) +#define NSS_N2H_INTR_COREDUMP_COMPLETE (1 << 14) + +/* + * Types of H2N interrupts + */ +enum nss_h2n_intr_type { + NSS_H2N_INTR_EMPTY_BUFFER_QUEUE = 0, + NSS_H2N_INTR_DATA_COMMAND_QUEUE = 1, + NSS_H2N_INTR_TX_UNBLOCKED = 2, + NSS_H2N_INTR_TRIGGER_COREDUMP = 3, + NSS_H2N_INTR_EMPTY_PAGED_BUFFER_QUEUE = 4, + NSS_H2N_INTR_TYPE_MAX = 5, +}; + +/* + * clock source for NSS cores + */ +enum nss_regs_clk_src_select { + NSS_REGS_CLK_SRC_DEFAULT, + NSS_REGS_CLK_SRC_ALTERNATE +}; + +/* + * nss_read_32() + * Read NSS register + */ +static inline uint32_t nss_read_32(void __iomem *addr, uint32_t offs) +{ + return readl(addr + offs); +} + +/* + * nss_write_32() + * Write NSS register + */ +static inline void nss_write_32(void __iomem *addr, uint32_t offs, uint32_t val) +{ + writel(val, addr + offs); +} + +#endif /* __NSS_REGS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_hal/ipq50xx/nss_hal_pvt.c b/feeds/ipq807x/qca-nss-drv/src/nss_hal/ipq50xx/nss_hal_pvt.c new file mode 100644 index 000000000..3d6dfd02d --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_hal/ipq50xx/nss_hal_pvt.c @@ -0,0 +1,667 @@ +/* + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * nss_hal_pvt.c + * NSS HAL private APIs. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "nss_hal.h" +#include "nss_core.h" + +#define NSS_QGIC_IPC_REG_OFFSET 0x8 + +#define NSS0_H2N_INTR_BASE 13 + +/* + * N2H interrupts + */ +#define NSS_IRQ_NAME_EMPTY_BUF_SOS "nss_empty_buf_sos" +#define NSS_IRQ_NAME_EMPTY_BUF_QUEUE "nss_empty_buf_queue" +#define NSS_IRQ_NAME_TX_UNBLOCK "nss-tx-unblock" +#define NSS_IRQ_NAME_QUEUE0 "nss_queue0" +#define NSS_IRQ_NAME_QUEUE1 "nss_queue1" +#define NSS_IRQ_NAME_COREDUMP_COMPLETE "nss_coredump_complete" +#define NSS_IRQ_NAME_PAGED_EMPTY_BUF_SOS "nss_paged_empty_buf_sos" +#define NSS_IRQ_NAME_PROFILE_DMA "nss_profile_dma" + +/* + * CLKs + */ +#define NSS_CFG_CLK "nss-cfg-clk" +#define NSS_DBG_CLK "nss-dbg-clk" +#define NSS_CORE_CLK "nss-core-clk" +#define NSS_AXI_CLK "nss-axi-clk" +#define NSS_SNOC_AXI_CLK "nss-snoc-axi-clk" +#define NSS_NC_AXI_CLK "nss-nc-axi-clk" +#define NSS_UTCM_CLK "nss-utcm-clk" + +/* + * Core GCC reset + */ +#define NSS_CORE_GCC_RESET 0x00000007 + +/* + * GCC reset + */ +void __iomem *nss_misc_reset; +void __iomem *nss_misc_reset_flag; + +/* + * Purpose of each interrupt index: This should match the order defined in the NSS firmware + */ +enum nss_hal_n2h_intr_purpose { + NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_SOS = 0, + NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_QUEUE = 1, + NSS_HAL_N2H_INTR_PURPOSE_TX_UNBLOCKED = 2, + NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_0 = 3, + NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_1 = 4, + NSS_HAL_N2H_INTR_PURPOSE_COREDUMP_COMPLETE = 5, + NSS_HAL_N2H_INTR_PURPOSE_PAGED_EMPTY_BUFFER_SOS = 6, + NSS_HAL_N2H_INTR_PURPOSE_PROFILE_DMA = 7, + NSS_HAL_N2H_INTR_PURPOSE_MAX +}; + +/* + * Interrupt type to cause vector. + */ +static uint32_t intr_cause[NSS_MAX_CORES][NSS_H2N_INTR_TYPE_MAX] = { + /* core0 */ + {(1 << (NSS0_H2N_INTR_BASE + NSS_H2N_INTR_EMPTY_BUFFER_QUEUE)), + (1 << (NSS0_H2N_INTR_BASE + NSS_H2N_INTR_DATA_COMMAND_QUEUE)), + (1 << (NSS0_H2N_INTR_BASE + NSS_H2N_INTR_TX_UNBLOCKED)), + (1 << (NSS0_H2N_INTR_BASE + NSS_H2N_INTR_TRIGGER_COREDUMP)), + (1 << (NSS0_H2N_INTR_BASE + NSS_H2N_INTR_EMPTY_PAGED_BUFFER_QUEUE))} +}; + +/* + * nss_hal_wq_function() + * Added to Handle BH requests to kernel + */ +void nss_hal_wq_function(struct work_struct *work) +{ + nss_work_t *my_work = (nss_work_t *)work; + + mutex_lock(&nss_top_main.wq_lock); + + nss_freq_change(&nss_top_main.nss[NSS_CORE_0], my_work->frequency, my_work->stats_enable, 0); + clk_set_rate(nss_core0_clk, my_work->frequency); + + nss_freq_change(&nss_top_main.nss[NSS_CORE_0], my_work->frequency, my_work->stats_enable, 1); + + mutex_unlock(&nss_top_main.wq_lock); + kfree((void *)work); +} + +/* + * nss_hal_handle_irq() + */ +static irqreturn_t nss_hal_handle_irq(int irq, void *ctx) +{ + struct int_ctx_instance *int_ctx = (struct int_ctx_instance *) ctx; + + disable_irq_nosync(irq); + napi_schedule(&int_ctx->napi); + + return IRQ_HANDLED; +} + +/* + * __nss_hal_of_get_pdata() + * Retrieve platform data from device node. + */ +static struct nss_platform_data *__nss_hal_of_get_pdata(struct platform_device *pdev) +{ + struct device_node *np = of_node_get(pdev->dev.of_node); + struct nss_platform_data *npd; + struct nss_ctx_instance *nss_ctx = NULL; + struct nss_top_instance *nss_top = &nss_top_main; + struct resource res_nphys, res_qgic_phys; + int32_t i; + + npd = devm_kzalloc(&pdev->dev, sizeof(struct nss_platform_data), GFP_KERNEL); + if (!npd) { + return NULL; + } + + if (of_property_read_u32(np, "qcom,id", &npd->id) + || of_property_read_u32(np, "qcom,load-addr", &npd->load_addr) + || of_property_read_u32(np, "qcom,num-queue", &npd->num_queue) + || of_property_read_u32(np, "qcom,num-irq", &npd->num_irq)) { + pr_err("%s: error reading critical device node properties\n", np->name); + goto out; + } + + /* + * Read frequencies. If failure, load default values. + */ + of_property_read_u32(np, "qcom,mid-frequency", &nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency); + of_property_read_u32(np, "qcom,max-frequency", &nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency); + + if (npd->num_irq > NSS_MAX_IRQ_PER_CORE) { + pr_err("%s: exceeds maximum interrupt numbers per core\n", np->name); + goto out; + } + + nss_ctx = &nss_top->nss[npd->id]; + nss_ctx->id = npd->id; + + if (of_address_to_resource(np, 0, &res_nphys) != 0) { + nss_info_always("%px: nss%d: of_address_to_resource() fail for nphys\n", nss_ctx, nss_ctx->id); + goto out; + } + + if (of_address_to_resource(np, 1, &res_qgic_phys) != 0) { + nss_info_always("%px: nss%d: of_address_to_resource() fail for qgic_phys\n", nss_ctx, nss_ctx->id); + goto out; + } + + /* + * Save physical addresses + */ + npd->nphys = res_nphys.start; + npd->qgic_phys = res_qgic_phys.start; + + npd->nmap = ioremap_nocache(npd->nphys, resource_size(&res_nphys)); + if (!npd->nmap) { + nss_info_always("%px: nss%d: ioremap() fail for nphys\n", nss_ctx, nss_ctx->id); + goto out; + } + + npd->qgic_map = ioremap_nocache(npd->qgic_phys, resource_size(&res_qgic_phys)); + if (!npd->qgic_map) { + nss_info_always("%px: nss%d: ioremap() fail for qgic map\n", nss_ctx, nss_ctx->id); + goto out; + } + + NSS_CORE_DSB(); + + /* + * Get IRQ numbers + */ + for (i = 0 ; i < npd->num_irq; i++) { + npd->irq[i] = irq_of_parse_and_map(np, i); + if (!npd->irq[i]) { + nss_info_always("%px: nss%d: irq_of_parse_and_map() fail for irq %d\n", nss_ctx, nss_ctx->id, i); + goto out; + } + } + + nss_hal_dt_parse_features(np, npd); + + of_node_put(np); + return npd; + +out: + if (npd->nmap) { + iounmap(npd->nmap); + } + + if (npd->vmap) { + iounmap(npd->vmap); + } + + devm_kfree(&pdev->dev, npd); + of_node_put(np); + return NULL; +} + +/* + * nss_hal_clock_set_and_enable() + */ +static int nss_hal_clock_set_and_enable(struct device *dev, const char *id, unsigned long rate) +{ + struct clk *nss_clk = NULL; + int err; + + nss_clk = devm_clk_get(dev, id); + if (IS_ERR(nss_clk)) { + pr_err("%px: cannot get clock: %s\n", dev, id); + return -EFAULT; + } + + if (rate) { + err = clk_set_rate(nss_clk, rate); + if (err) { + pr_err("%px: cannot set %s freq\n", dev, id); + return -EFAULT; + } + } + + err = clk_prepare_enable(nss_clk); + if (err) { + pr_err("%px: cannot enable clock: %s\n", dev, id); + return -EFAULT; + } + + return 0; +} + +/* + * __nss_hal_core_reset() + */ +static int __nss_hal_core_reset(struct platform_device *nss_dev, void __iomem *map, uint32_t addr, uint32_t clk_src) +{ + uint32_t value; + + /* + * Apply ubi32 core reset + */ + nss_write_32(map, NSS_REGS_RESET_CTRL_OFFSET, 0x1); + + /* + * De-assert reset + */ + value = nss_read_32(nss_misc_reset, 0x0); + value &= ~NSS_CORE_GCC_RESET; + nss_write_32(nss_misc_reset, 0x0, value); + + /* + * Program address configuration + */ + nss_write_32(map, NSS_REGS_CORE_AMC_OFFSET, 0x1); + nss_write_32(map, NSS_REGS_CORE_BAR_OFFSET, 0x3C000000); + nss_write_32(map, NSS_REGS_CORE_BOOT_ADDR_OFFSET, addr); + + /* + * Set crypto interrupt as level sensitive + */ + nss_write_32(map, NSS_REGS_CORE_INT_STAT2_TYPE_OFFSET, 0x80000000); + nss_write_32(map, NSS_REGS_CORE_INT_STAT3_TYPE_OFFSET, 0x00200000); + + /* + * Enable Instruction Fetch range checking between 0x4000 0000 to 0xBFFF FFFF. + */ + nss_write_32(map, NSS_REGS_CORE_IFETCH_RANGE_OFFSET, 0xBF004001); + + /* + * De-assert ubi32 core reset + */ + nss_write_32(map, NSS_REGS_RESET_CTRL_OFFSET, 0x0); + + /* + * Set values only once for core0. Grab the proper clock. + */ + nss_core0_clk = clk_get(&nss_dev->dev, NSS_CORE_CLK); + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency)) { + return -EFAULT; + } + + return 0; +} + +/* + * __nss_hal_debug_enable() + * Enable NSS debug + */ +static void __nss_hal_debug_enable(void) +{ + +} + +/* + * __nss_hal_common_reset + * Do reset/clock configuration common to all cores + */ +static int __nss_hal_common_reset(struct platform_device *nss_dev) +{ + struct device_node *cmn = NULL; + struct resource res_nss_misc_reset; + + /* + * Get reference to NSS common device node + */ + cmn = of_find_node_by_name(NULL, "nss-common"); + if (!cmn) { + pr_err("%px: Unable to find nss-common node\n", nss_dev); + return -EFAULT; + } + + if (of_address_to_resource(cmn, 0, &res_nss_misc_reset) != 0) { + pr_err("%px: of_address_to_resource() return error for nss_misc_reset\n", nss_dev); + of_node_put(cmn); + return -EFAULT; + } + + of_node_put(cmn); + + nss_misc_reset = ioremap_nocache(res_nss_misc_reset.start, resource_size(&res_nss_misc_reset)); + if (!nss_misc_reset) { + pr_err("%px: ioremap fail for nss_misc_reset\n", nss_dev); + return -EFAULT; + } + + nss_top_main.nss_hal_common_init_done = true; + nss_info("nss_hal_common_reset Done\n"); + + return 0; +} + +/* + * __nss_hal_clock_configure() + */ +static int __nss_hal_clock_configure(struct nss_ctx_instance *nss_ctx, struct platform_device *nss_dev, struct nss_platform_data *npd) +{ + int32_t i; + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_DBG_CLK, 150000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CFG_CLK, 100000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_AXI_CLK, 400000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_SNOC_AXI_CLK, 400000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NC_AXI_CLK, 266670000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_UTCM_CLK, 266670000)) { + return -EFAULT; + } + + /* + * No entries, then just load default + */ + if ((nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency == 0) || + (nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency == 0)) { + nss_runtime_samples.freq_scale[NSS_FREQ_LOW_SCALE].frequency = NSS_FREQ_SCALE_NA; + nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency = NSS_FREQ_850; + nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency = NSS_FREQ_1000; + nss_info_always("%px: Running default frequencies\n", nss_ctx); + } + + /* + * Maple low frequency not applicable, set it accordingly + */ + nss_runtime_samples.freq_scale[NSS_FREQ_LOW_SCALE].frequency = NSS_FREQ_SCALE_NA; + + /* + * Test frequency from dtsi, if fail, try to set default frequency. + */ + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency)) { + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, NSS_FREQ_1000)) { + return -EFAULT; + } + } + + /* + * Setup ranges, test frequency, and display. + */ + for (i = 0; i < NSS_FREQ_MAX_SCALE; i++) { + switch (nss_runtime_samples.freq_scale[i].frequency) { + case NSS_FREQ_850: + nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_850_MIN; + nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_850_MAX; + break; + + case NSS_FREQ_1000: + nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_1000_MIN; + nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_1000_MAX; + break; + + case NSS_FREQ_SCALE_NA: + nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_NA; + nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_NA; + continue; + + default: + nss_info_always("%px: Frequency not found %d\n", nss_ctx, nss_runtime_samples.freq_scale[i].frequency); + return -EFAULT; + } + + /* + * Test the frequency, if fail, then default to safe frequency and abort + */ + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, nss_runtime_samples.freq_scale[i].frequency)) { + return -EFAULT; + } + } + + nss_info_always("Supported Frequencies - "); + for (i = 0; i < NSS_FREQ_MAX_SCALE; i++) { + switch (nss_runtime_samples.freq_scale[i].frequency) { + case NSS_FREQ_850: + nss_info_always("850 MHz "); + break; + + case NSS_FREQ_1000: + nss_info_always("1 GHz "); + break; + + case NSS_FREQ_SCALE_NA: + continue; + + default: + nss_info_always("%px: Error\nNo Table/Invalid Frequency Found\n", nss_ctx); + return -EFAULT; + } + } + nss_info_always("\n"); + + /* + * Set values only once for core0. Grab the proper clock. + */ + nss_core0_clk = clk_get(&nss_dev->dev, NSS_CORE_CLK); + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency)) { + return -EFAULT; + } + return 0; +} + +/* + * __nss_hal_read_interrupt_cause() + */ +static void __nss_hal_read_interrupt_cause(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t *cause) +{ +} + +/* + * __nss_hal_clear_interrupt_cause() + */ +static void __nss_hal_clear_interrupt_cause(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause) +{ +} + +/* + * __nss_hal_disable_interrupt() + */ +static void __nss_hal_disable_interrupt(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause) +{ +} + +/* + * __nss_hal_enable_interrupt() + */ +static void __nss_hal_enable_interrupt(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause) +{ +} + +/* + * __nss_hal_send_interrupt() + */ +static void __nss_hal_send_interrupt(struct nss_ctx_instance *nss_ctx, uint32_t type) +{ + /* + * Check if core and type is Valid + */ + nss_assert(nss_ctx->id < nss_top_main.num_nss); + nss_assert(type < NSS_H2N_INTR_TYPE_MAX); + + nss_write_32(nss_ctx->qgic_map, NSS_QGIC_IPC_REG_OFFSET, intr_cause[nss_ctx->id][type]); +} + +/* + * __nss_hal_request_irq() + */ +static int __nss_hal_request_irq(struct nss_ctx_instance *nss_ctx, struct nss_platform_data *npd, int irq_num) +{ + struct int_ctx_instance *int_ctx = &nss_ctx->int_ctx[irq_num]; + uint32_t cause, napi_wgt; + int err = -1, irq = npd->irq[irq_num]; + int (*napi_poll_cb)(struct napi_struct *, int) = NULL; + const char *irq_name; + + irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY); + + switch (irq_num) { + case NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_SOS: + napi_poll_cb = nss_core_handle_napi_non_queue; + napi_wgt = NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT; + cause = NSS_N2H_INTR_EMPTY_BUFFERS_SOS; + irq_name = NSS_IRQ_NAME_EMPTY_BUF_SOS; + break; + + case NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_QUEUE: + napi_poll_cb = nss_core_handle_napi_queue; + napi_wgt = NSS_EMPTY_BUFFER_RETURN_PROCESSING_WEIGHT; + cause = NSS_N2H_INTR_EMPTY_BUFFER_QUEUE; + irq_name = NSS_IRQ_NAME_EMPTY_BUF_QUEUE; + break; + + case NSS_HAL_N2H_INTR_PURPOSE_TX_UNBLOCKED: + napi_poll_cb = nss_core_handle_napi_non_queue; + napi_wgt = NSS_TX_UNBLOCKED_PROCESSING_WEIGHT; + cause = NSS_N2H_INTR_TX_UNBLOCKED; + irq_name = NSS_IRQ_NAME_TX_UNBLOCK; + break; + + case NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_0: + napi_poll_cb = nss_core_handle_napi_queue; + napi_wgt = NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT; + cause = NSS_N2H_INTR_DATA_QUEUE_0; + irq_name = NSS_IRQ_NAME_QUEUE0; + break; + + case NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_1: + napi_poll_cb = nss_core_handle_napi_queue; + napi_wgt = NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT; + cause = NSS_N2H_INTR_DATA_QUEUE_1; + irq_name = NSS_IRQ_NAME_QUEUE1; + break; + + case NSS_HAL_N2H_INTR_PURPOSE_COREDUMP_COMPLETE: + napi_poll_cb = nss_core_handle_napi_emergency; + napi_wgt = NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT; + cause = NSS_N2H_INTR_COREDUMP_COMPLETE; + irq_name = NSS_IRQ_NAME_COREDUMP_COMPLETE; + break; + + case NSS_HAL_N2H_INTR_PURPOSE_PAGED_EMPTY_BUFFER_SOS: + napi_poll_cb = nss_core_handle_napi_non_queue; + napi_wgt = NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT; + cause = NSS_N2H_INTR_PAGED_EMPTY_BUFFERS_SOS; + irq_name = NSS_IRQ_NAME_PAGED_EMPTY_BUF_SOS; + break; + + case NSS_HAL_N2H_INTR_PURPOSE_PROFILE_DMA: + napi_poll_cb = nss_core_handle_napi_sdma; + napi_wgt = NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT; + cause = NSS_N2H_INTR_PROFILE_DMA; + irq_name = NSS_IRQ_NAME_PROFILE_DMA; + break; + + default: + nss_warning("%px: nss%d: unsupported irq# %d\n", nss_ctx, nss_ctx->id, irq_num); + return err; + } + + netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, napi_poll_cb, napi_wgt); + int_ctx->cause = cause; + err = request_irq(irq, nss_hal_handle_irq, 0, irq_name, int_ctx); + if (err) { + nss_warning("%px: nss%d: request_irq failed for irq# %d\n", nss_ctx, nss_ctx->id, irq_num); + return err; + } + int_ctx->irq = irq; + return 0; +} + +/* + * __nss_hal_init_imem + */ +void __nss_hal_init_imem(struct nss_ctx_instance *nss_ctx) +{ + /* + * Nothing to be done as there are no TCM in ipq50xx + */ +} + +/* + * __nss_hal_init_utcm_shared + */ +bool __nss_hal_init_utcm_shared(struct nss_ctx_instance *nss_ctx, uint32_t *meminfo_start) +{ + struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; + uint32_t utcm_shared_map_magic = meminfo_start[2]; + uint32_t utcm_shared_start = meminfo_start[3]; + uint32_t utcm_shared_size = meminfo_start[4]; + + /* + * Check meminfo utcm_shared map magic + */ + if ((uint16_t)utcm_shared_map_magic != NSS_MEMINFO_RESERVE_AREA_UTCM_SHARED_MAP_MAGIC) { + nss_info_always("%px: failed to verify UTCM_SHARED map magic\n", nss_ctx); + return false; + } + + mem_ctx->utcm_shared_head = utcm_shared_start; + mem_ctx->utcm_shared_end = mem_ctx->utcm_shared_head + utcm_shared_size; + mem_ctx->utcm_shared_tail = mem_ctx->utcm_shared_head; + + nss_info("%px: UTCM_SHARED init: head: 0x%x end: 0x%x tail: 0x%x\n", nss_ctx, + mem_ctx->utcm_shared_head, mem_ctx->utcm_shared_end, mem_ctx->utcm_shared_tail); + return true; +} + +/* + * nss_hal_ipq50xx_ops + */ +struct nss_hal_ops nss_hal_ipq50xx_ops = { + .common_reset = __nss_hal_common_reset, + .core_reset = __nss_hal_core_reset, + .clock_configure = __nss_hal_clock_configure, + .firmware_load = nss_hal_firmware_load, + .debug_enable = __nss_hal_debug_enable, + .of_get_pdata = __nss_hal_of_get_pdata, + .request_irq = __nss_hal_request_irq, + .send_interrupt = __nss_hal_send_interrupt, + .enable_interrupt = __nss_hal_enable_interrupt, + .disable_interrupt = __nss_hal_disable_interrupt, + .clear_interrupt_cause = __nss_hal_clear_interrupt_cause, + .read_interrupt_cause = __nss_hal_read_interrupt_cause, + .init_imem = __nss_hal_init_imem, + .init_utcm_shared = __nss_hal_init_utcm_shared, +}; diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_hal/ipq60xx/nss_hal_pvt.c b/feeds/ipq807x/qca-nss-drv/src/nss_hal/ipq60xx/nss_hal_pvt.c new file mode 100644 index 000000000..4c84cb958 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_hal/ipq60xx/nss_hal_pvt.c @@ -0,0 +1,739 @@ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * nss_hal_pvt.c + * NSS HAL private APIs. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "nss_hal.h" +#include "nss_core.h" + +#define NSS_QGIC_IPC_REG_OFFSET 0x8 + +#define NSS0_H2N_INTR_BASE 13 + +/* + * Common CLKs + */ +#define NSS_NOC_CLK "nss-noc-clk" +#define NSS_PTP_REF_CLK "nss-ptp-ref-clk" +#define NSS_CSR_CLK "nss-csr-clk" +#define NSS_CFG_CLK "nss-cfg-clk" +#define NSS_NSSNOC_QOSGEN_REF_CLK "nss-nssnoc-qosgen-ref-clk" +#define NSS_NSSNOC_SNOC_CLK "nss-nssnoc-snoc-clk" +#define NSS_NSSNOC_TIMEOUT_REF_CLK "nss-nssnoc-timeout-ref-clk" +#define NSS_CE_AXI_CLK "nss-ce-axi-clk" +#define NSS_CE_APB_CLK "nss-ce-apb-clk" +#define NSS_NSSNOC_CE_AXI_CLK "nss-nssnoc-ce-axi-clk" +#define NSS_NSSNOC_CE_APB_CLK "nss-nssnoc-ce-apb-clk" +#define NSS_MEM_NOC_UBI32_CLK "nss-mem-noc-ubi32-clk" +#define NSS_SNOC_NSSNOC_CLK "nss-snoc-nssnoc-clk" + +/* + * Per-core CLKS + */ +#define NSS_NSSNOC_AHB_CLK "nss-nssnoc-ahb-clk" +#define NSS_CORE_CLK "nss-core-clk" +#define NSS_AHB_CLK "nss-ahb-clk" +#define NSS_AXI_CLK "nss-axi-clk" +#define NSS_NC_AXI_CLK "nss-nc-axi-clk" +#define NSS_UTCM_CLK "nss-utcm-clk" + +/* + * Voltage values + */ +#define NOMINAL_VOLTAGE 1 +#define TURBO_VOLTAGE 2 + +/* + * Core reset part 1 + */ +#define NSS_CORE_GCC_RESET_1 0x00000020 + +/* + * Core reset part 2 + */ +#define NSS_CORE_GCC_RESET_2 0x00000017 + +/* + * Voltage regulator + */ +struct regulator *npu_reg; + +/* + * GCC reset + */ +void __iomem *nss_misc_reset; +void __iomem *nss_misc_reset_flag; + +/* + * Purpose of each interrupt index: This should match the order defined in the NSS firmware + */ +enum nss_hal_n2h_intr_purpose { + NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_SOS = 0, + NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_QUEUE = 1, + NSS_HAL_N2H_INTR_PURPOSE_TX_UNBLOCKED = 2, + NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_0 = 3, + NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_1 = 4, + NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_2 = 5, + NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_3 = 6, + NSS_HAL_N2H_INTR_PURPOSE_COREDUMP_COMPLETE = 7, + NSS_HAL_N2H_INTR_PURPOSE_PAGED_EMPTY_BUFFER_SOS = 8, + NSS_HAL_N2H_INTR_PURPOSE_PROFILE_DMA = 9, + NSS_HAL_N2H_INTR_PURPOSE_MAX +}; + +/* + * Interrupt type to cause vector. + */ +static uint32_t intr_cause[NSS_MAX_CORES][NSS_H2N_INTR_TYPE_MAX] = { + /* core0 */ + {(1 << (NSS0_H2N_INTR_BASE + NSS_H2N_INTR_EMPTY_BUFFER_QUEUE)), + (1 << (NSS0_H2N_INTR_BASE + NSS_H2N_INTR_DATA_COMMAND_QUEUE)), + (1 << (NSS0_H2N_INTR_BASE + NSS_H2N_INTR_TX_UNBLOCKED)), + (1 << (NSS0_H2N_INTR_BASE + NSS_H2N_INTR_TRIGGER_COREDUMP)), + (1 << (NSS0_H2N_INTR_BASE + NSS_H2N_INTR_EMPTY_PAGED_BUFFER_QUEUE))} +}; + +/* + * nss_hal_wq_function() + * Added to Handle BH requests to kernel + */ +void nss_hal_wq_function(struct work_struct *work) +{ + nss_work_t *my_work = (nss_work_t *)work; + + mutex_lock(&nss_top_main.wq_lock); + + nss_freq_change(&nss_top_main.nss[NSS_CORE_0], my_work->frequency, my_work->stats_enable, 0); + clk_set_rate(nss_core0_clk, my_work->frequency); + + nss_freq_change(&nss_top_main.nss[NSS_CORE_0], my_work->frequency, my_work->stats_enable, 1); + + mutex_unlock(&nss_top_main.wq_lock); + kfree((void *)work); +} + +/* + * nss_hal_handle_irq() + */ +static irqreturn_t nss_hal_handle_irq(int irq, void *ctx) +{ + struct int_ctx_instance *int_ctx = (struct int_ctx_instance *) ctx; + + disable_irq_nosync(irq); + napi_schedule(&int_ctx->napi); + + return IRQ_HANDLED; +} + +/* + * __nss_hal_of_get_pdata() + * Retrieve platform data from device node. + */ +static struct nss_platform_data *__nss_hal_of_get_pdata(struct platform_device *pdev) +{ + struct device_node *np = of_node_get(pdev->dev.of_node); + struct nss_platform_data *npd; + struct nss_ctx_instance *nss_ctx = NULL; + struct nss_top_instance *nss_top = &nss_top_main; + struct resource res_nphys, res_qgic_phys; + int32_t i; + + npd = devm_kzalloc(&pdev->dev, sizeof(struct nss_platform_data), GFP_KERNEL); + if (!npd) { + return NULL; + } + + if (of_property_read_u32(np, "qcom,id", &npd->id) + || of_property_read_u32(np, "qcom,load-addr", &npd->load_addr) + || of_property_read_u32(np, "qcom,num-queue", &npd->num_queue) + || of_property_read_u32(np, "qcom,num-irq", &npd->num_irq)) { + pr_err("%s: error reading critical device node properties\n", np->name); + goto out; + } + + /* + * Read frequencies. If failure, load default values. + */ + of_property_read_u32(np, "qcom,low-frequency", &nss_runtime_samples.freq_scale[NSS_FREQ_LOW_SCALE].frequency); + of_property_read_u32(np, "qcom,mid-frequency", &nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency); + of_property_read_u32(np, "qcom,max-frequency", &nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency); + + if (npd->num_irq > NSS_MAX_IRQ_PER_CORE) { + pr_err("%s: exceeds maximum interrupt numbers per core\n", np->name); + goto out; + } + + nss_ctx = &nss_top->nss[npd->id]; + nss_ctx->id = npd->id; + + if (of_address_to_resource(np, 0, &res_nphys) != 0) { + nss_info_always("%px: nss%d: of_address_to_resource() fail for nphys\n", nss_ctx, nss_ctx->id); + goto out; + } + + if (of_address_to_resource(np, 1, &res_qgic_phys) != 0) { + nss_info_always("%px: nss%d: of_address_to_resource() fail for qgic_phys\n", nss_ctx, nss_ctx->id); + goto out; + } + + /* + * Save physical addresses + */ + npd->nphys = res_nphys.start; + npd->qgic_phys = res_qgic_phys.start; + + npd->nmap = ioremap_nocache(npd->nphys, resource_size(&res_nphys)); + if (!npd->nmap) { + nss_info_always("%px: nss%d: ioremap() fail for nphys\n", nss_ctx, nss_ctx->id); + goto out; + } + + npd->qgic_map = ioremap_nocache(npd->qgic_phys, resource_size(&res_qgic_phys)); + if (!npd->qgic_map) { + nss_info_always("%px: nss%d: ioremap() fail for qgic map\n", nss_ctx, nss_ctx->id); + goto out; + } + + NSS_CORE_DSB(); + + /* + * Get IRQ numbers + */ + for (i = 0 ; i < npd->num_irq; i++) { + npd->irq[i] = irq_of_parse_and_map(np, i); + if (!npd->irq[i]) { + nss_info_always("%px: nss%d: irq_of_parse_and_map() fail for irq %d\n", nss_ctx, nss_ctx->id, i); + goto out; + } + } + + nss_hal_dt_parse_features(np, npd); + + of_node_put(np); + return npd; + +out: + if (npd->nmap) { + iounmap(npd->nmap); + } + + if (npd->vmap) { + iounmap(npd->vmap); + } + + devm_kfree(&pdev->dev, npd); + of_node_put(np); + return NULL; +} + +/* + * nss_hal_clock_set_and_enable() + */ +static int nss_hal_clock_set_and_enable(struct device *dev, const char *id, unsigned long rate) +{ + struct clk *nss_clk = NULL; + int err; + + nss_clk = devm_clk_get(dev, id); + if (IS_ERR(nss_clk)) { + pr_err("%px: cannot get clock: %s\n", dev, id); + return -EFAULT; + } + + if (rate) { + err = clk_set_rate(nss_clk, rate); + if (err) { + pr_err("%px: cannot set %s freq\n", dev, id); + return -EFAULT; + } + } + + err = clk_prepare_enable(nss_clk); + if (err) { + pr_err("%px: cannot enable clock: %s\n", dev, id); + return -EFAULT; + } + + return 0; +} + +/* + * __nss_hal_core_reset() + */ +static int __nss_hal_core_reset(struct platform_device *nss_dev, void __iomem *map, uint32_t addr, uint32_t clk_src) +{ + uint32_t value; + + /* + * Apply ubi32 core reset + */ + nss_write_32(map, NSS_REGS_RESET_CTRL_OFFSET, 0x1); + + /* + * De-assert reset for first set + */ + value = nss_read_32(nss_misc_reset, 0x0); + value &= ~NSS_CORE_GCC_RESET_1; + nss_write_32(nss_misc_reset, 0x0, value); + + /* + * Minimum 10 - 20 cycles delay is required after + * de-asserting NSS reset clamp + */ + usleep_range(10, 20); + + /* + * De-assert reset for second set + */ + value &= ~NSS_CORE_GCC_RESET_2; + nss_write_32(nss_misc_reset, 0x0, value); + + /* + * Program address configuration + */ + nss_write_32(map, NSS_REGS_CORE_AMC_OFFSET, 0x1); + nss_write_32(map, NSS_REGS_CORE_BAR_OFFSET, 0x3C000000); + nss_write_32(map, NSS_REGS_CORE_BOOT_ADDR_OFFSET, addr); + + /* + * Enable Instruction Fetch range checking between 0x4000 0000 to 0xBFFF FFFF. + */ + nss_write_32(map, NSS_REGS_CORE_IFETCH_RANGE_OFFSET, 0xBF004001); + + /* + * De-assert ubi32 core reset + */ + nss_write_32(map, NSS_REGS_RESET_CTRL_OFFSET, 0x0); + + /* + * Set values only once for core0. Grab the proper clock. + */ + nss_core0_clk = clk_get(&nss_dev->dev, NSS_CORE_CLK); + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency)) { + return -EFAULT; + } + + return 0; +} + +/* + * __nss_hal_debug_enable() + * Enable NSS debug + */ +static void __nss_hal_debug_enable(void) +{ + +} + +/* + * __nss_hal_common_reset + * Do reset/clock configuration common to all cores + */ +static int __nss_hal_common_reset(struct platform_device *nss_dev) +{ + + struct device_node *cmn = NULL; + struct resource res_nss_misc_reset; + struct resource res_nss_misc_reset_flag; + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NOC_CLK, 266670000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_PTP_REF_CLK, 150000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CSR_CLK, 200000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CFG_CLK, 100000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NSSNOC_QOSGEN_REF_CLK, 24000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NSSNOC_SNOC_CLK, 266600000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_SNOC_NSSNOC_CLK, 266670000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NSSNOC_TIMEOUT_REF_CLK, 6000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CE_AXI_CLK, 200000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CE_APB_CLK, 200000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NSSNOC_CE_AXI_CLK, 200000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NSSNOC_CE_APB_CLK, 200000000)) { + return -EFAULT; + } + + /* + * Get reference to NSS common device node + */ + cmn = of_find_node_by_name(NULL, "nss-common"); + if (!cmn) { + pr_err("%px: Unable to find nss-common node\n", nss_dev); + return -EFAULT; + } + + if (of_address_to_resource(cmn, 0, &res_nss_misc_reset) != 0) { + pr_err("%px: of_address_to_resource() return error for nss_misc_reset\n", nss_dev); + of_node_put(cmn); + return -EFAULT; + } + + if (of_address_to_resource(cmn, 1, &res_nss_misc_reset_flag) != 0) { + pr_err("%px: of_address_to_resource() return error for nss_misc_reset_flag\n", nss_dev); + of_node_put(cmn); + return -EFAULT; + } + + of_node_put(cmn); + + nss_misc_reset = ioremap_nocache(res_nss_misc_reset.start, resource_size(&res_nss_misc_reset)); + if (!nss_misc_reset) { + pr_err("%px: ioremap fail for nss_misc_reset\n", nss_dev); + return -EFAULT; + } + + nss_misc_reset_flag = ioremap_nocache(res_nss_misc_reset_flag.start, resource_size(&res_nss_misc_reset_flag)); + if (!nss_misc_reset_flag) { + pr_err("%px: ioremap fail for nss_misc_reset_flag\n", nss_dev); + return -EFAULT; + } + + nss_top_main.nss_hal_common_init_done = true; + nss_info("nss_hal_common_reset Done\n"); + + return 0; +} + +/* + * __nss_hal_clock_configure() + */ +static int __nss_hal_clock_configure(struct nss_ctx_instance *nss_ctx, struct platform_device *nss_dev, struct nss_platform_data *npd) +{ + uint32_t i; + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NSSNOC_AHB_CLK, 200000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_AHB_CLK, 200000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_AXI_CLK, 533330000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NC_AXI_CLK, 266670000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_UTCM_CLK, 266670000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_MEM_NOC_UBI32_CLK, 533330000)) { + return -EFAULT; + } + + /* + * No entries, then just load default + */ + if ((nss_runtime_samples.freq_scale[NSS_FREQ_LOW_SCALE].frequency == 0) || + (nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency == 0) || + (nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency == 0)) { + nss_runtime_samples.freq_scale[NSS_FREQ_LOW_SCALE].frequency = NSS_FREQ_187; + nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency = NSS_FREQ_748; + nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency = NSS_FREQ_1497; + nss_info_always("Running default frequencies\n"); + } + + /* + * Test frequency from dtsi, if fail, try to set default frequency. + */ + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency)) { + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, NSS_FREQ_1497)) { + return -EFAULT; + } + } + + /* + * Setup ranges, test frequency, and display. + */ + for (i = 0; i < NSS_FREQ_MAX_SCALE; i++) { + if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_187) { + nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_187_MIN; + nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_187_MAX; + } else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_748) { + nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_748_MIN; + nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_748_MAX; + } else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_1497) { + nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_1497_MIN; + nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_1497_MAX; + } else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_1689) { + nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_1689_MIN; + nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_1689_MAX; + } else { + nss_info_always("Frequency not found %d\n", nss_runtime_samples.freq_scale[i].frequency); + return -EFAULT; + } + + /* + * Test the frequency, if fail, then default to safe frequency and abort + */ + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, nss_runtime_samples.freq_scale[i].frequency)) { + return -EFAULT; + } + } + + nss_info_always("Supported Frequencies - "); + for (i = 0; i < NSS_FREQ_MAX_SCALE; i++) { + if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_187) { + nss_info_always("187.2 MHz "); + } else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_748) { + nss_info_always("748.8 MHz "); + } else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_1497) { + nss_info_always("1.4976 GHz "); + } else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_1689) { + nss_info_always("1.6896 GHz "); + } else { + nss_info_always("Error\nNo Table/Invalid Frequency Found\n"); + return -EFAULT; + } + } + nss_info_always("\n"); + + /* + * Set values only once for core0. Grab the proper clock. + */ + nss_core0_clk = clk_get(&nss_dev->dev, NSS_CORE_CLK); + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency)) { + return -EFAULT; + } + + return 0; +} + +/* + * __nss_hal_read_interrupt_cause() + */ +static void __nss_hal_read_interrupt_cause(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t *cause) +{ +} + +/* + * __nss_hal_clear_interrupt_cause() + */ +static void __nss_hal_clear_interrupt_cause(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause) +{ +} + +/* + * __nss_hal_disable_interrupt() + */ +static void __nss_hal_disable_interrupt(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause) +{ +} + +/* + * __nss_hal_enable_interrupt() + */ +static void __nss_hal_enable_interrupt(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause) +{ +} + +/* + * __nss_hal_send_interrupt() + */ +static void __nss_hal_send_interrupt(struct nss_ctx_instance *nss_ctx, uint32_t type) +{ + /* + * Check if core and type is Valid + */ + nss_assert(nss_ctx->id < nss_top_main.num_nss); + nss_assert(type < NSS_H2N_INTR_TYPE_MAX); + + nss_write_32(nss_ctx->qgic_map, NSS_QGIC_IPC_REG_OFFSET, intr_cause[nss_ctx->id][type]); +} + +/* + * __nss_hal_request_irq() + */ +static int __nss_hal_request_irq(struct nss_ctx_instance *nss_ctx, struct nss_platform_data *npd, int irq_num) +{ + struct int_ctx_instance *int_ctx = &nss_ctx->int_ctx[irq_num]; + int err = -1, irq = npd->irq[irq_num]; + + irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY); + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_SOS) { + netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT); + int_ctx->cause = NSS_N2H_INTR_EMPTY_BUFFERS_SOS; + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_empty_buf_sos", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_QUEUE) { + netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_EMPTY_BUFFER_RETURN_PROCESSING_WEIGHT); + int_ctx->cause = NSS_N2H_INTR_EMPTY_BUFFER_QUEUE; + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_empty_buf_queue", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_TX_UNBLOCKED) { + netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_TX_UNBLOCKED_PROCESSING_WEIGHT); + int_ctx->cause = NSS_N2H_INTR_TX_UNBLOCKED; + err = request_irq(irq, nss_hal_handle_irq, 0, "nss-tx-unblock", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_0) { + netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); + int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_0; + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue0", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_1) { + int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_1; + netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue1", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_2) { + int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_2; + netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue2", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_3) { + int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_3; + netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue3", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_COREDUMP_COMPLETE) { + int_ctx->cause = NSS_N2H_INTR_COREDUMP_COMPLETE; + netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_emergency, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_coredump_complete", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_PAGED_EMPTY_BUFFER_SOS) { + netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT); + int_ctx->cause = NSS_N2H_INTR_PAGED_EMPTY_BUFFERS_SOS; + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_paged_empty_buf_sos", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_PROFILE_DMA) { + int_ctx->cause = NSS_N2H_INTR_PROFILE_DMA; + netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_sdma, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_profile_dma", int_ctx); + } + + if (err) { + return err; + } + + int_ctx->irq = irq; + return 0; +} + +/* + * __nss_hal_init_imem + */ +void __nss_hal_init_imem(struct nss_ctx_instance *nss_ctx) +{ + /* + * Nothing to be done as there are no TCM in ipq60xx + */ +} + +/* + * __nss_hal_init_utcm_shared + */ +bool __nss_hal_init_utcm_shared(struct nss_ctx_instance *nss_ctx, uint32_t *meminfo_start) +{ + struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; + uint32_t utcm_shared_map_magic = meminfo_start[2]; + uint32_t utcm_shared_start = meminfo_start[3]; + uint32_t utcm_shared_size = meminfo_start[4]; + + /* + * Check meminfo utcm_shared map magic + */ + if ((uint16_t)utcm_shared_map_magic != NSS_MEMINFO_RESERVE_AREA_UTCM_SHARED_MAP_MAGIC) { + nss_info_always("%px: failed to verify UTCM_SHARED map magic\n", nss_ctx); + return false; + } + + mem_ctx->utcm_shared_head = utcm_shared_start; + mem_ctx->utcm_shared_end = mem_ctx->utcm_shared_head + utcm_shared_size; + mem_ctx->utcm_shared_tail = mem_ctx->utcm_shared_head; + + nss_info("%px: UTCM_SHARED init: head: 0x%x end: 0x%x tail: 0x%x\n", nss_ctx, + mem_ctx->utcm_shared_head, mem_ctx->utcm_shared_end, mem_ctx->utcm_shared_tail); + return true; +} + +/* + * nss_hal_ipq60xx_ops + */ +struct nss_hal_ops nss_hal_ipq60xx_ops = { + .common_reset = __nss_hal_common_reset, + .core_reset = __nss_hal_core_reset, + .clock_configure = __nss_hal_clock_configure, + .firmware_load = nss_hal_firmware_load, + .debug_enable = __nss_hal_debug_enable, + .of_get_pdata = __nss_hal_of_get_pdata, + .request_irq = __nss_hal_request_irq, + .send_interrupt = __nss_hal_send_interrupt, + .enable_interrupt = __nss_hal_enable_interrupt, + .disable_interrupt = __nss_hal_disable_interrupt, + .clear_interrupt_cause = __nss_hal_clear_interrupt_cause, + .read_interrupt_cause = __nss_hal_read_interrupt_cause, + .init_imem = __nss_hal_init_imem, + .init_utcm_shared = __nss_hal_init_utcm_shared, +}; diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_hal/ipq806x/nss_clocks.h b/feeds/ipq807x/qca-nss-drv/src/nss_hal/ipq806x/nss_clocks.h new file mode 100644 index 000000000..1e7af1a4d --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_hal/ipq806x/nss_clocks.h @@ -0,0 +1,131 @@ +/* * Copyright (c) 2013 The Linux Foundation. All rights reserved.* */ +/* + * Copyright (c) 2013 The Linux Foundation. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __NSS_CLOCKS_H +#define __NSS_CLOCKS_H + +#if (NSS_DT_SUPPORT != 1) +#include +#include + +#define REG(off) (MSM_CLK_CTL_BASE + (off)) +#define REG_GCC(off) (MSM_APCS_GCC_BASE + (off)) + +/* Peripheral clock registers. */ +#define PLL18_ACR REG(0x1234) +#define PLL18_MODE REG(0x31A0) +#define PLL18_L_VAL REG(0x31A4) +#define PLL18_M_VAL REG(0x31A8) +#define PLL18_N_VAL REG(0x31AC) +#define PLL18_TEST_CTL REG(0x31B0) +#define PLL18_CONFIG REG(0x31B4) +#define PLL18_STATUS REG(0x31B8) +#define PLL_LOCK_DET_STATUS REG(0x3420) +#define PLL_LOCK_DET_MASK REG(0x3424) +#define CE5_CORE_CLK_SRC_CTL REG(0x36C0) +#define CE5_CORE_CLK_SRC0_NS REG(0x36C4) +#define NSS_ACC_REG REG(0x28EC) +#define NSS_RESET_SPARE REG(0x3B60) +#define NSSFB0_CLK_SRC_CTL REG(0x3B80) +#define NSSFB0_CLK_SRC0_NS REG(0x3B84) +#define NSSFB0_CLK_SRC1_NS REG(0x3B88) +#define NSSFB0_CLK_CTL REG(0x3BA0) +#define NSSFAB_GLOBAL_BUS_NS REG(0x3BC0) +#define NSSFB1_CLK_SRC_CTL REG(0x3BE0) +#define NSSFB1_CLK_SRC0_NS REG(0x3BE4) +#define NSSFB1_CLK_SRC1_NS REG(0x3BE8) +#define NSSFB1_CLK_CTL REG(0x3C00) +#define CLK_HALT_NSSFAB0_NSSFAB1_STATEA REG(0x3C20) +#define UBI32_MPT0_CLK_CTL REG(0x3C40) +#define UBI32_MPT1_CLK_CTL REG(0x3C44) +#define CE5_HCLK_SRC_CTL REG(0x3C60) +#define CE5_HCLK_SRC0_NS REG(0x3C64) +#define CE5_HCLK_SRC1_NS REG(0x3C68) +#define CE5_HCLK_CTL REG(0x3C6C) +#define NSSFPB_CLK_CTL REG(0x3C80) +#define NSSFPB_CLK_SRC_CTL REG(0x3C84) +#define NSSFPB_CLK_SRC0_NS REG(0x3C88) +#define NSSFPB_CLK_SRC1_NS REG(0x3C8C) +#define GMAC_COREn_CLK_SRC_CTL(n) REG(0x3CA0+32*(n)) +#define GMAC_CORE1_CLK_SRC_CTL REG(0x3CA0) +#define GMAC_COREn_CLK_SRC0_MD(n) REG(0x3CA4+32*(n)) +#define GMAC_CORE1_CLK_SRC0_MD REG(0x3CA4) +#define GMAC_COREn_CLK_SRC1_MD(n) REG(0x3CA8+32*(n)) +#define GMAC_CORE1_CLK_SRC1_MD REG(0x3CA8) +#define GMAC_COREn_CLK_SRC0_NS(n) REG(0x3CAC+32*(n)) +#define GMAC_CORE1_CLK_SRC0_NS REG(0x3CAC) +#define GMAC_COREn_CLK_SRC1_NS(n) REG(0x3CB0+32*(n)) +#define GMAC_CORE1_CLK_SRC1_NS REG(0x3CB0) +#define GMAC_COREn_CLK_CTL(n) REG(0x3CB4+32*(n)) +#define GMAC_CORE1_CLK_CTL REG(0x3CB4) +#define GMAC_COREn_CLK_FS(n) REG(0x3CB8+32*(n)) +#define GMAC_CORE1_CLK_FS REG(0x3CB8) +#define GMAC_COREn_RESET(n) REG(0x3CBC+32*(n)) +#define GMAC_CORE1_RESET REG(0x3CBC) +#define UBI32_COREn_CLK_SRC_CTL(n) REG(0x3D20+32*(n)) +#define UBI32_CORE1_CLK_SRC_CTL REG(0x3D20) +#define UBI32_COREn_CLK_SRC0_MD(n) REG(0x3D24+32*(n)) +#define UBI32_CORE1_CLK_SRC0_MD REG(0x3D24) +#define UBI32_COREn_CLK_SRC1_MD(n) REG(0x3D28+32*(n)) +#define UBI32_CORE1_CLK_SRC1_MD REG(0x3D28) +#define UBI32_COREn_CLK_SRC0_NS(n) REG(0x3D2C+32*(n)) +#define UBI32_CORE1_CLK_SRC0_NS REG(0x3D2C) +#define UBI32_COREn_CLK_SRC1_NS(n) REG(0x3D30+32*(n)) +#define UBI32_CORE1_CLK_SRC1_NS REG(0x3D30) +#define UBI32_COREn_CLK_CTL(n) REG(0x3D34+32*(n)) +#define UBI32_CORE1_CLK_CTL REG(0x3D34) +#define UBI32_COREn_CLK_FS(n) REG(0x3D38+32*(n)) +#define UBI32_CORE1_CLK_FS REG(0x3D38) +#define UBI32_COREn_RESET_CLAMP(n) REG(0x3D3C+32*(n)) +#define UBI32_CORE1_RESET_CLAMP REG(0x3D3C) +#define NSS_250MHZ_CLK_SRC_CTL REG(0x3D60) +#define NSS_250MHZ_CLK_SRC0_NS REG(0x3D64) +#define NSS_250MHZ_CLK_SRC1_NS REG(0x3D68) +#define NSS_250MHZ_CLK_SRC0_MD REG(0x3D6C) +#define NSS_250MHZ_CLK_SRC1_MD REG(0x3D70) +#define NSS_250MHZ_CLK_CTL REG(0x3D74) +#define CE5_ACLK_SRC_CTL REG(0x3D80) +#define CE5_ACLK_SRC0_NS REG(0x3D84) +#define CE5_ACLK_SRC1_NS REG(0x3D88) +#define CE5_ACLK_CTL REG(0x3D8C) +#define PLL_ENA_NSS REG(0x3DA0) +#define NSSTCM_CLK_SRC_CTL REG(0x3DC0) +#define NSSTCM_CLK_SRC0_NS REG(0x3DC4) +#define NSSTCM_CLK_SRC1_NS REG(0x3DC8) +#define NSSTCM_CLK_FS REG(0x3DCC) +#define NSSTCM_CLK_CTL REG(0x3DD0) +#define CE5_CORE_0_RESET REG(0x3E00) +#define CE5_CORE_1_RESET REG(0x3E04) +#define CE5_CORE_2_RESET REG(0x3E08) +#define CE5_CORE_3_RESET REG(0x3E0C) +#define CE5_AHB_RESET REG(0x3E10) +#define NSS_RESET REG(0x3E20) +#define GMAC_AHB_RESET REG(0x3E24) +#define MACSEC_CORE1_RESET REG(0x3E28) +#define MACSEC_CORE2_RESET REG(0x3E2C) +#define MACSEC_CORE3_RESET REG(0x3E30) +#define NSS_TCM_RESET REG(0x3E40) + +enum nss_hal_pvt_pll_status { + PLL_NOT_LOCKED, + PLL_LOCKED +}; + +#endif +#endif /* __NSS_CLOCKS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_hal/ipq806x/nss_hal_pvt.c b/feeds/ipq807x/qca-nss-drv/src/nss_hal/ipq806x/nss_hal_pvt.c new file mode 100644 index 000000000..d49fdfaf5 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_hal/ipq806x/nss_hal_pvt.c @@ -0,0 +1,1236 @@ +/* + ************************************************************************** + * Copyright (c) 2013, 2015-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * nss_hal_pvt.c + * NSS HAL private APIs. + */ + +#include +#include +#include +#include +#include +#if (NSS_DT_SUPPORT != 1) +#include +#include +#else +#include +#include +#include +#include +#include +#endif +#include "nss_hal.h" +#include "nss_clocks.h" +#include "nss_core.h" +#if (NSS_PM_SUPPORT == 1) +#include "nss_pm.h" +#endif +#if (NSS_FABRIC_SCALING_SUPPORT == 1) +#include +#endif + +#define NSS_H2N_INTR_EMPTY_BUFFER_QUEUE_BIT 0 +#define NSS_H2N_INTR_DATA_COMMAND_QUEUE_BIT 1 +#define NSS_H2N_INTR_TX_UNBLOCKED_BIT 11 +#define NSS_H2N_INTR_EMPTY_PAGED_BUFFER_QUEUE_BIT 12 +#define NSS_H2N_INTR_TRIGGER_COREDUMP_BIT 15 + +/* + * Interrupt type to cause vector. + */ +static uint32_t intr_cause[] = {(1 << NSS_H2N_INTR_EMPTY_BUFFER_QUEUE_BIT), + (1 << NSS_H2N_INTR_DATA_COMMAND_QUEUE_BIT), + (1 << NSS_H2N_INTR_TX_UNBLOCKED_BIT), + (1 << NSS_H2N_INTR_TRIGGER_COREDUMP_BIT), + (1 << NSS_H2N_INTR_EMPTY_PAGED_BUFFER_QUEUE_BIT)}; + +#if (NSS_DT_SUPPORT == 1) +bool nss_crypto_is_scaled = false; +#endif + +#if (NSS_FW_DBG_SUPPORT == 1) +/* + * NSS debug pins configuration + */ + +/* + * Core 0, Data + * No pull up, Function 2 + */ +static struct gpiomux_setting nss_spi_data_0 = { + .func = GPIOMUX_FUNC_2, + .drv = GPIOMUX_DRV_8MA, + .pull = GPIOMUX_PULL_NONE, + .dir = GPIOMUX_IN, +}; + +/* + * Core 0, CLK, CS + * Pull up high, Function 2 + */ +static struct gpiomux_setting nss_spi_cs_clk_0 = { + .func = GPIOMUX_FUNC_2, + .drv = GPIOMUX_DRV_8MA, + .pull = GPIOMUX_PULL_UP, + .dir = GPIOMUX_IN, +}; + +/* + * Core 1, CS + * Pull up high, Function 4 + */ +static struct gpiomux_setting nss_spi_cs_1 = { + .func = GPIOMUX_FUNC_4, + .drv = GPIOMUX_DRV_8MA, + .pull = GPIOMUX_PULL_UP, + .dir = GPIOMUX_IN, +}; + +/* + * Core 1, CLK + * Pull up high, Function 5 + */ +static struct gpiomux_setting nss_spi_clk_1 = { + .func = GPIOMUX_FUNC_5, + .drv = GPIOMUX_DRV_8MA, + .pull = GPIOMUX_PULL_UP, + .dir = GPIOMUX_IN, +}; + +/* + * Core 1, Data + * Pull up none, Function 5 + */ +static struct gpiomux_setting nss_spi_data_1 = { + .func = GPIOMUX_FUNC_5, + .drv = GPIOMUX_DRV_8MA, + .pull = GPIOMUX_PULL_NONE, + .dir = GPIOMUX_IN, +}; + +static struct msm_gpiomux_config nss_spi_gpiomux[] = { + { + .gpio = 14, + .settings = { + [GPIOMUX_ACTIVE] = &nss_spi_data_0, + [GPIOMUX_SUSPENDED] = &nss_spi_data_0, + }, + }, + { + .gpio = 15, + .settings = { + [GPIOMUX_ACTIVE] = &nss_spi_data_0, + [GPIOMUX_SUSPENDED] = &nss_spi_data_0, + }, + }, + { + .gpio = 16, + .settings = { + [GPIOMUX_ACTIVE] = &nss_spi_cs_clk_0, + [GPIOMUX_SUSPENDED] = &nss_spi_cs_clk_0, + }, + }, + { + .gpio = 17, + .settings = { + [GPIOMUX_ACTIVE] = &nss_spi_cs_clk_0, + [GPIOMUX_SUSPENDED] = &nss_spi_cs_clk_0, + }, + }, + { + .gpio = 55, + .settings = { + [GPIOMUX_ACTIVE] = &nss_spi_data_1, + [GPIOMUX_SUSPENDED] = &nss_spi_data_1, + }, + }, + { + .gpio = 56, + .settings = { + [GPIOMUX_ACTIVE] = &nss_spi_data_1, + [GPIOMUX_SUSPENDED] = &nss_spi_data_1, + }, + }, + { + .gpio = 57, + .settings = { + [GPIOMUX_ACTIVE] = &nss_spi_cs_1, + [GPIOMUX_SUSPENDED] = &nss_spi_cs_1, + }, + }, + { + .gpio = 58, + .settings = { + [GPIOMUX_ACTIVE] = &nss_spi_clk_1, + [GPIOMUX_SUSPENDED] = &nss_spi_clk_1, + }, + }, +}; +#endif /* NSS_FW_DBG_SUPPORT */ + +/* + * nss_hal_scale_fabric() + * DT supported fabric scaling + */ +void nss_hal_scale_fabric(uint32_t work_frequency) +{ +#if (NSS_DT_SUPPORT == 1) + nss_crypto_pm_event_callback_t crypto_pm_cb; + bool auto_scale; + bool turbo; + +#if (NSS_FABRIC_SCALING_SUPPORT == 1) + /* + * PM framework + */ + scale_fabrics(); +#endif + if ((nss_fab0_clk != NULL) && (nss_fab1_clk != NULL)) { + if (work_frequency >= NSS_FREQ_733) { + clk_set_rate(nss_fab0_clk, NSS_FABRIC0_TURBO); + clk_set_rate(nss_fab1_clk, NSS_FABRIC1_TURBO); + } else if (work_frequency > NSS_FREQ_110) { + clk_set_rate(nss_fab0_clk, NSS_FABRIC0_NOMINAL); + clk_set_rate(nss_fab1_clk, NSS_FABRIC1_NOMINAL); + } else { + clk_set_rate(nss_fab0_clk, NSS_FABRIC0_IDLE); + clk_set_rate(nss_fab1_clk, NSS_FABRIC1_IDLE); + } + + /* + * notify crypto about the clock change + */ + crypto_pm_cb = nss_top_main.crypto_pm_callback; + if (crypto_pm_cb) { + turbo = (work_frequency >= NSS_FREQ_733); + auto_scale = nss_cmd_buf.auto_scale; + nss_crypto_is_scaled = crypto_pm_cb(nss_top_main.crypto_pm_ctx, turbo, auto_scale); + } + } +#endif +} + +/* + * nss_hal_pm_support() + * Supported in 3.4 + */ +void nss_hal_pm_support(uint32_t work_frequency) +{ +#if (NSS_PM_SUPPORT == 1) + if (!pm_client) { + return; + } + + if (work_frequency >= NSS_FREQ_733) { + nss_pm_set_perf_level(pm_client, NSS_PM_PERF_LEVEL_TURBO); + } else if (work_frequency > NSS_FREQ_110) { + nss_pm_set_perf_level(pm_client, NSS_PM_PERF_LEVEL_NOMINAL); + } else { + nss_pm_set_perf_level(pm_client, NSS_PM_PERF_LEVEL_IDLE); + } +#endif +} + +/* + * nss_hal_freq_change() + * Send frequency change message, and clock adjustment + */ +void nss_hal_freq_change(nss_work_t *my_work) +{ + nss_freq_change(&nss_top_main.nss[NSS_CORE_0], my_work->frequency, my_work->stats_enable, 0); + if (nss_top_main.nss[NSS_CORE_1].state == NSS_CORE_STATE_INITIALIZED) { + nss_freq_change(&nss_top_main.nss[NSS_CORE_1], my_work->frequency, my_work->stats_enable, 0); + } + clk_set_rate(nss_core0_clk, my_work->frequency); + + nss_freq_change(&nss_top_main.nss[NSS_CORE_0], my_work->frequency, my_work->stats_enable, 1); + if (nss_top_main.nss[NSS_CORE_1].state == NSS_CORE_STATE_INITIALIZED) { + nss_freq_change(&nss_top_main.nss[NSS_CORE_1], my_work->frequency, my_work->stats_enable, 1); + } +} + +/* + * nss_hal_wq_function() + * Added to Handle BH requests to kernel + */ +void nss_hal_wq_function(struct work_struct *work) +{ + nss_work_t *my_work = (nss_work_t *)work; + + mutex_lock(&nss_top_main.wq_lock); +#if (NSS_DT_SUPPORT == 1) + /* + * If crypto clock is in Turbo, disable scaling for other + * NSS subsystem components and retain them at turbo + */ + if (nss_crypto_is_scaled) { + nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency; + mutex_unlock(&nss_top_main.wq_lock); + return; + } +#endif + + nss_hal_freq_change(my_work); + + /* + * Supported in 3.4 + */ + nss_hal_pm_support(my_work->frequency); + + nss_hal_scale_fabric(my_work->frequency); + + mutex_unlock(&nss_top_main.wq_lock); + kfree((void *)work); +} + +/* + * nss_hal_handle_irq() + * HLOS interrupt handler for nss interrupts + */ +static irqreturn_t nss_hal_handle_irq(int irq, void *ctx) +{ + struct int_ctx_instance *int_ctx = (struct int_ctx_instance *) ctx; + struct nss_ctx_instance *nss_ctx = int_ctx->nss_ctx; + + /* + * Mask interrupt until our bottom half re-enables it + */ + nss_hal_disable_interrupt(nss_ctx, int_ctx->shift_factor, NSS_HAL_SUPPORTED_INTERRUPTS); + + /* + * Schedule tasklet to process interrupt cause + */ + napi_schedule(&int_ctx->napi); + return IRQ_HANDLED; +} + +#if (NSS_DT_SUPPORT != 1) +#if defined(NSS_ENABLE_CLK) +/* + * nss_hal_pvt_enable_pll18() + * Enable PLL18 + */ +static uint32_t nss_hal_pvt_enable_pll18(uint32_t speed) +{ + uint32_t retries = 100; + + /* + * Prevent Compiler from commenting out the loop. + */ + uint32_t value; + uint32_t mask = (1 << 2); + + /* + * Start with clean slate + */ + writel(0, PLL18_MODE); + + /* + * Effective VCO Frequency = 1100 MHz Post Divide 2 + */ + if (speed == 1100) { + writel(0x4000042C, PLL18_L_VAL); + writel(0x0, PLL18_M_VAL); + writel(0x1, PLL18_N_VAL); + + /* + * PLL configuration (as provided by HW team) + */ + writel(0x01495625, PLL18_CONFIG); + writel(0x00003080, PLL18_TEST_CTL); + } else if (speed == 1466) { + /* + * Effective VCO Frequency = 1466 MHz Post Divide 2 + */ + + writel(0x4000043A, PLL18_L_VAL); + writel(0x10, PLL18_M_VAL); + writel(0x19, PLL18_N_VAL); + + /* + * PLL configuration (as provided by HW team) + */ + writel(0x014B5625, PLL18_CONFIG); + writel(0x00003080, PLL18_TEST_CTL); + } else { + BUG_ON(1); + } + + /* + * Enable PLL18 output (sequence provided by HW team) + */ + writel(0x2, PLL18_MODE); + mdelay(1); + writel(0x6, PLL18_MODE); + writel(0x7, PLL18_MODE); + + /* + * Enable NSS Vote for PLL18. + */ + writel(mask, PLL_ENA_NSS); + do { + value = readl(PLL_LOCK_DET_STATUS); + if (value & mask) { + return PLL_LOCKED; + } + + mdelay(1); + } while (retries-- > 0); + + return PLL_NOT_LOCKED; +} +#endif +#else +/* + * __nss_hal_of_get_pdata() + * Retrieve platform data from device node. + */ +static struct nss_platform_data *__nss_hal_of_get_pdata(struct platform_device *pdev) +{ + struct device_node *np = of_node_get(pdev->dev.of_node); + struct nss_platform_data *npd; + struct nss_ctx_instance *nss_ctx = NULL; + struct nss_top_instance *nss_top = &nss_top_main; + struct resource res_nphys, res_vphys; + int32_t i; + + npd = devm_kzalloc(&pdev->dev, sizeof(struct nss_platform_data), GFP_KERNEL); + if (!npd) { + return NULL; + } + + if (of_property_read_u32(np, "qcom,id", &npd->id) + || of_property_read_u32(np, "qcom,load-addr", &npd->load_addr) + || of_property_read_u32(np, "qcom,num-queue", &npd->num_queue) + || of_property_read_u32(np, "qcom,num-irq", &npd->num_irq)) { + pr_err("%s: error reading critical device node properties\n", np->name); + goto out; + } + + /* + * Read frequencies. If failure, load default values. + */ + of_property_read_u32(np, "qcom,low-frequency", &nss_runtime_samples.freq_scale[NSS_FREQ_LOW_SCALE].frequency); + of_property_read_u32(np, "qcom,mid-frequency", &nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency); + of_property_read_u32(np, "qcom,max-frequency", &nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency); + + if (npd->num_irq < npd->num_queue) { + pr_err("%s: not enough interrupts configured for all the queues\n", np->name); + goto out; + } + + if (npd->num_irq > NSS_MAX_IRQ_PER_CORE) { + pr_err("%s: exceeds maximum interrupt numbers per core\n", np->name); + goto out; + } + + nss_ctx = &nss_top->nss[npd->id]; + nss_ctx->id = npd->id; + + if (of_address_to_resource(np, 0, &res_nphys) != 0) { + nss_info_always("%px: nss%d: of_address_to_resource() fail for nphys\n", nss_ctx, nss_ctx->id); + goto out; + } + + if (of_address_to_resource(np, 1, &res_vphys) != 0) { + nss_info_always("%px: nss%d: of_address_to_resource() fail for vphys\n", nss_ctx, nss_ctx->id); + goto out; + } + + /* + * Save physical addresses + */ + npd->nphys = res_nphys.start; + npd->vphys = res_vphys.start; + + npd->nmap = ioremap_nocache(npd->nphys, resource_size(&res_nphys)); + if (!npd->nmap) { + nss_info_always("%px: nss%d: ioremap() fail for nphys\n", nss_ctx, nss_ctx->id); + goto out; + } + + npd->vmap = ioremap_cache(npd->vphys, resource_size(&res_vphys)); + if (!npd->vmap) { + nss_info_always("%px: nss%d: ioremap() fail for vphys\n", nss_ctx, nss_ctx->id); + goto out; + } + + /* + * Clear TCM memory used by this core + */ + for (i = 0; i < resource_size(&res_vphys) ; i += 4) { + nss_write_32(npd->vmap, i, 0); + NSS_CORE_DMA_CACHE_MAINT((npd->vmap + i), 4, DMA_TO_DEVICE); + } + NSS_CORE_DSB(); + + /* + * Get IRQ numbers + */ + for (i = 0 ; i < npd->num_irq; i++) { + npd->irq[i] = irq_of_parse_and_map(np, i); + if (!npd->irq[i]) { + nss_info_always("%px: nss%d: irq_of_parse_and_map() fail for irq %d\n", nss_ctx, nss_ctx->id, i); + goto out; + } + } + + nss_hal_dt_parse_features(np, npd); + + of_node_put(np); + return npd; + +out: + if (npd->nmap) { + iounmap(npd->nmap); + } + + if (npd->vmap) { + iounmap(npd->vmap); + } + + devm_kfree(&pdev->dev, npd); + of_node_put(np); + return NULL; +} +#endif + +/* + * __nss_hal_core_reset() + */ +static int __nss_hal_core_reset(struct platform_device *nss_dev, void __iomem *map, uint32_t addr, uint32_t clk_src) +{ +#if (NSS_DT_SUPPORT == 1) + struct reset_control *rstctl = NULL; + + /* + * Remove UBI32 reset clamp + */ + rstctl = devm_reset_control_get(&nss_dev->dev, "clkrst-clamp"); + if (IS_ERR(rstctl)) { + nss_info_always("%px: Deassert UBI32 core%d reset clamp failed", nss_dev, nss_dev->id); + return -EFAULT; + } + reset_control_deassert(rstctl); + + /* + * Remove UBI32 core clamp + */ + rstctl = devm_reset_control_get(&nss_dev->dev, "clamp"); + if (IS_ERR(rstctl)) { + nss_info_always("%px: Deassert UBI32 core%d clamp failed", nss_dev, nss_dev->id); + return -EFAULT; + } + reset_control_deassert(rstctl); + + /* + * Remove UBI32 AHB reset + */ + rstctl = devm_reset_control_get(&nss_dev->dev, "ahb"); + if (IS_ERR(rstctl)) { + nss_info_always("%px: Deassert AHB core%d reset failed", nss_dev, nss_dev->id); + return -EFAULT; + } + reset_control_deassert(rstctl); + + /* + * Remove UBI32 AXI reset + */ + rstctl = devm_reset_control_get(&nss_dev->dev, "axi"); + if (IS_ERR(rstctl)) { + nss_info_always("%px: Deassert core%d AXI reset failed", nss_dev, nss_dev->id); + return -EFAULT; + } + reset_control_deassert(rstctl); +#else +#if defined(NSS_ENABLE_CLOCK) + /* + * Enable mpt clock + */ + writel(0x10, UBI32_MPT0_CLK_CTL); + + /* + * UBI coren clock root enable + */ + if (clk_src == NSS_REGS_CLK_SRC_DEFAULT) { + /* select Src0 */ + writel(0x02, UBI32_COREn_CLK_SRC_CTL(nss_dev->id)); + } else { + /* select Src1 */ + writel(0x03, UBI32_COREn_CLK_SRC_CTL(nss_dev->id)); + } + + /* + * Src0: Bypass M value configuration. + */ + + /* + * Src1: M val is 0x01 and NOT_2D value is 0xfd, 400 MHz with PLL0. + */ + writel(0x100fd, UBI32_COREn_CLK_SRC1_MD(nss_dev->id)); + + /* + * Bypass, pll18 + * Effective frequency = 550 MHz + */ + writel(0x00000001, UBI32_COREn_CLK_SRC0_NS(nss_dev->id)); + + /* + * Dual edge, pll0, NOT(N_M) = 0xfe. + * Effective frequency = 400 MHz + */ + writel(0x00fe0142, UBI32_COREn_CLK_SRC1_NS(nss_dev->id)); + + /* + * UBI32 coren clock control branch. + */ + writel(0x4f, UBI32_COREn_CLK_FS(nss_dev->id)); + + /* + * UBI32 coren clock control branch. + */ + writel(0x10, UBI32_COREn_CLK_CTL(nss_dev->id)); +#endif + /* + * Remove UBI32 reset clamp + */ + writel(0xB, UBI32_COREn_RESET_CLAMP(nss_dev->id)); + + /* + * Busy wait for few cycles + */ + mdelay(1); + + /* + * Remove UBI32 core clamp + */ + writel(0x3, UBI32_COREn_RESET_CLAMP(nss_dev->id)); + + mdelay(1); + + /* + * Remove UBI32 AHB reset + */ + writel(0x1, UBI32_COREn_RESET_CLAMP(nss_dev->id)); + + mdelay(1); + + /* + * Remove UBI32 AXI reset + */ + writel(0x0, UBI32_COREn_RESET_CLAMP(nss_dev->id)); + + mdelay(1); +#endif /* NSS_DT_SUPPORT */ + + /* + * Apply ubi32 core reset + */ + nss_write_32(map, NSS_REGS_RESET_CTRL_OFFSET, 1); + + /* + * Program address configuration + */ + nss_write_32(map, NSS_REGS_CORE_AMC_OFFSET, 1); + nss_write_32(map, NSS_REGS_CORE_BAR_OFFSET, 0x3c000000); + nss_write_32(map, NSS_REGS_CORE_BOOT_ADDR_OFFSET, addr); + + /* + * C2C interrupts are level sensitive + */ + nss_write_32(map, NSS_REGS_CORE_INT_STAT2_TYPE_OFFSET, 0xFFFF); + + /* + * Enable Instruction Fetch range checking between 0x4000 0000 to 0xBFFF FFFF. + */ + nss_write_32(map, NSS_REGS_CORE_IFETCH_RANGE_OFFSET, 0xBF004001); + + /* + * De-assert ubi32 core reset + */ + nss_write_32(map, NSS_REGS_RESET_CTRL_OFFSET, 0); + + return 0; +} + +/* + * __nss_hal_debug_enable() + * Enable NSS debug + */ +static void __nss_hal_debug_enable(void) +{ +#if (NSS_FW_DBG_SUPPORT == 1) + msm_gpiomux_install(nss_spi_gpiomux, + ARRAY_SIZE(nss_spi_gpiomux)); +#endif +} + +/* + * __nss_hal_common_reset + * Do reset/clock configuration common to all cores + */ +static int __nss_hal_common_reset(struct platform_device *nss_dev) +{ +#if (NSS_DT_SUPPORT == 1) + struct device_node *cmn = NULL; + struct resource res_nss_fpb_base; + struct clk *nss_tcm_src = NULL; + struct clk *nss_tcm_clk = NULL; + void __iomem *fpb_base; + int err; + + /* + * Get reference to NSS common device node + */ + cmn = of_find_node_by_name(NULL, "nss-common"); + if (!cmn) { + pr_err("%px: Unable to find nss-common node\n", nss_dev); + return -EFAULT; + } + + if (of_address_to_resource(cmn, 0, &res_nss_fpb_base) != 0) { + pr_err("%px: of_address_to_resource() return error for nss_fpb_base\n", nss_dev); + of_node_put(cmn); + return -EFAULT; + } + of_node_put(cmn); + + fpb_base = ioremap_nocache(res_nss_fpb_base.start, resource_size(&res_nss_fpb_base)); + if (!fpb_base) { + pr_err("%px: ioremap fail for nss_fpb_base\n", nss_dev); + return -EFAULT; + } + + /* + * Attach debug interface to TLMM + */ + nss_write_32(fpb_base, NSS_REGS_FPB_CSR_CFG_OFFSET, 0x360); + + /* + * NSS TCM CLOCK + */ + nss_tcm_src = clk_get(&nss_dev->dev, NSS_TCM_SRC_CLK); + if (IS_ERR(nss_tcm_src)) { + pr_err("%px: cannot get clock: %s\n", nss_dev, NSS_TCM_SRC_CLK); + return -EFAULT; + } + + err = clk_set_rate(nss_tcm_src, NSSTCM_FREQ); + if (err) { + pr_err("%px: cannot set NSSTCM freq\n", nss_dev); + return -EFAULT; + } + + err = clk_prepare_enable(nss_tcm_src); + if (err) { + pr_err("%px: cannot enable NSSTCM clock source\n", nss_dev); + return -EFAULT; + } + + nss_tcm_clk = clk_get(&nss_dev->dev, NSS_TCM_CLK); + if (IS_ERR(nss_tcm_clk)) { + pr_err("%px: cannot get clock: %s\n", nss_dev, NSS_TCM_CLK); + return -EFAULT; + } + + err = clk_prepare_enable(nss_tcm_clk); + if (err) { + pr_err("%px: cannot enable NSSTCM clock\n", nss_dev); + return -EFAULT; + } + + /* + * NSS Fabric Clocks. + */ + nss_fab0_clk = clk_get(&nss_dev->dev, NSS_FABRIC0_CLK); + if (IS_ERR(nss_fab0_clk)) { + pr_err("%px: cannot get clock: %s\n", nss_dev, NSS_FABRIC0_CLK); + nss_fab0_clk = NULL; + } else { + err = clk_prepare_enable(nss_fab0_clk); + if (err) { + pr_err("%px: cannot enable clock: %s\n", nss_dev, NSS_FABRIC0_CLK); + return -EFAULT; + } + } + + nss_fab1_clk = clk_get(&nss_dev->dev, NSS_FABRIC1_CLK); + if (IS_ERR(nss_fab1_clk)) { + pr_err("%px: cannot get clock: %s\n", nss_dev, NSS_FABRIC1_CLK); + nss_fab1_clk = NULL; + } else { + err = clk_prepare_enable(nss_fab1_clk); + if (err) { + pr_err("%px: cannot enable clock: %s\n", nss_dev, NSS_FABRIC1_CLK); + return -EFAULT; + } + } + + nss_top_main.nss_hal_common_init_done = true; + nss_info("nss_hal_common_reset Done\n"); + return 0; +} +#else + uint32_t i; + uint32_t value; + uint32_t status_mask = 0x1; + uint32_t wait_cycles = 100; + +#if defined(NSS_ENABLE_CLK) + /* + * NSS FPB CLOCK + */ + + /* + * Enable clock root and Divider 0 + * NOTE: Default value is good so no work here + */ + + /* + * PLL0 (800 MHZ). SRC_SEL is 2 (3'b010) + * src_div selected is Div-6 (4'b0101). + * + * Effective frequency (Divider 0) = 133 MHz + */ + writel(0x2a, NSSFPB_CLK_SRC0_NS); + + /* + * Enable clock branch + */ + writel(0x50, NSSFPB_CLK_CTL); + + /* + * NSS FABRIC0 CLOCK + */ + + /* + * Enable clock root and Divider 0 + * NOTE: Default value is good so no work here + */ + + /* + * PLL0 (800 MHZ) and div is set to 2. + * Effective frequency = 400 MHZ. + */ + writel(0x0a, NSSFB0_CLK_SRC0_NS); + + /* + * NSS Fabric0 Branch and dynamic clock gating enabled. + */ + writel(0x50, NSSFB0_CLK_CTL); + + /* + * Enable clock root and Divider 0 + * NOTE: Default value is good so no work here + */ + + /* + * PLL0 (800 MHZ) and div is set to 4. + * Effective frequency = 200 MHZ. + */ + writel(0x1a, NSSFB1_CLK_SRC0_NS); + + /* + * NSS Fabric1 Branch enable and fabric clock gating enabled. + */ + writel(0x50, NSSFB1_CLK_CTL); + + /* + * NSS TCM CLOCK + */ + + /* + * Enable NSS TCM clock root source and select divider 0. + * + * NOTE: Default value is not good here + */ + writel(0x2, NSSTCM_CLK_SRC_CTL); + + /* + * PLL0 (800 MHZ) and div is set to 2. + * Effective frequency = 400 MHZ + */ + writel(0xa, NSSTCM_CLK_SRC0_NS); + + /* + * NSS TCM Branch enable and fabric clock gating enabled. + */ + writel(0x50, NSSTCM_CLK_CTL); + + /* + * Enable global NSS clock branches. + * NSS global Fab Branch enable and fabric clock gating enabled. + */ + writel(0xf, NSSFAB_GLOBAL_BUS_NS); + + /* + * Send reset interrupt to NSS + */ + writel(0x0, NSS_RESET); + + /* + * Enable PLL18 + */ + pll18_status = nss_hal_pvt_enable_pll18(); + if (!pll18_status) { + /* + * Select alternate good source (Src1/pll0) + */ + nss_top->clk_src = NSS_REGS_CLK_SRC_ALTERNATE; + return; + } + + /* + * Select default source (Src0/pll18) + */ + nss_top->clk_src = NSS_REGS_CLK_SRC_DEFAULT; +#endif + + /* + * Attach debug interface to TLMM + */ + nss_write_32((uint32_t)MSM_NSS_FPB_BASE, NSS_REGS_FPB_CSR_CFG_OFFSET, 0x360); + + /* + * NSS TCM CLOCK + */ + + /* + * Enable NSS TCM clock root source - SRC1. + * + */ + writel(0x3, NSSTCM_CLK_SRC_CTL); + + /* Enable PLL Voting for 0 */ + writel((readl(PLL_ENA_NSS) | 0x1), PLL_ENA_NSS); + do { + value = readl(PLL_LOCK_DET_STATUS); + if (value & status_mask) { + break; + } + mdelay(1); + } while (wait_cycles-- > 0); + + /* + * PLL0 (800 MHZ) and div is set to 3/4. + * Effective frequency = 266/400 Mhz for SRC0/1 + */ + writel(0x12, NSSTCM_CLK_SRC0_NS); + writel(0xa, NSSTCM_CLK_SRC1_NS); + + /* + * NSS TCM Branch enable and fabric clock gating enabled. + */ + writel(0x50, NSSTCM_CLK_CTL); + + /* + * Clear TCM memory + */ + for (i = 0; i < IPQ806X_NSS_TCM_SIZE; i += 4) { + nss_write_32((uint32_t)MSM_NSS_TCM_BASE, i, 0); + } + + return 0; +} +#endif /* NSS_DT_SUPPORT */ + +/* + * __nss_hal_clock_configure() + */ +static int __nss_hal_clock_configure(struct nss_ctx_instance *nss_ctx, struct platform_device *nss_dev, struct nss_platform_data *npd) +{ +#if (NSS_FABRIC_SCALING_SUPPORT == 1) + struct fab_scaling_info fab_data; +#endif + int i, err; + + /* + * Both ubi core on ipq806x attach to the same clock, configure just the core0 + */ + if (nss_ctx->id) { + return 0; + } + + nss_core0_clk = clk_get(&nss_dev->dev, NSS_CORE_CLK); + if (IS_ERR(nss_core0_clk)) { + err = PTR_ERR(nss_core0_clk); + nss_info_always("%px: Regulator %s get failed, err=%d\n", nss_ctx, dev_name(&nss_dev->dev), err); + return err; + } + + /* + * Check if turbo is supported + */ + if (npd->turbo_frequency) { + nss_info_always("nss_driver - Turbo Support %d\n", npd->turbo_frequency); +#if (NSS_PM_SUPPORT == 1) + nss_pm_set_turbo(); +#endif + } else { + nss_info_always("nss_driver - Turbo No Support %d\n", npd->turbo_frequency); + } + + /* + * If valid entries - from dtsi - then just init clks. + * Otherwise query for clocks. + */ + if ((nss_runtime_samples.freq_scale[NSS_FREQ_LOW_SCALE].frequency != 0) && + (nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency != 0) && + (nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency != 0)) { + goto clk_complete; + } + + /* + * Load default scales, then query for higher. + * If basic set cannot be set, then go to error, and abort + * Two set of defaults, 110, 550, 733 or 110, 275 and 550 + */ + if (clk_set_rate(nss_core0_clk, NSS_FREQ_110) != 0) { + return -EFAULT; + } + nss_runtime_samples.freq_scale[NSS_FREQ_LOW_SCALE].frequency = NSS_FREQ_110; + + if (npd->turbo_frequency) { + /* + * Figure out the middle scale + */ + if (clk_set_rate(nss_core0_clk, NSS_FREQ_600) == 0) { + nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency = NSS_FREQ_600; + } else if (clk_set_rate(nss_core0_clk, NSS_FREQ_550) == 0) { + nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency = NSS_FREQ_550; + } else { + return -EFAULT; + } + + /* + * Figure out the max scale + */ + if (clk_set_rate(nss_core0_clk, NSS_FREQ_800) == 0) { + nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency = NSS_FREQ_800; + } else if (clk_set_rate(nss_core0_clk, NSS_FREQ_733) == 0) { + nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency = NSS_FREQ_733; + } else { + return -EFAULT; + } + + } else { + if (clk_set_rate(nss_core0_clk, NSS_FREQ_275) != 0) { + return -EFAULT; + } + nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency = NSS_FREQ_275; + + if (clk_set_rate(nss_core0_clk, NSS_FREQ_550) != 0) { + return -EFAULT; + } + nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency = NSS_FREQ_550; + } + +clk_complete: +#if (NSS_FABRIC_SCALING_SUPPORT == 1) + if (npd->turbo_frequency) { + fab_data.idle_freq = nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency; + } else { + fab_data.idle_freq = nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency; + } + fab_data.clk = nss_core0_clk; + fab_scaling_register(&fab_data); +#endif + + /* + * Setup Ranges + */ + for (i = 0; i < NSS_FREQ_MAX_SCALE; i++) { + if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_110) { + nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_110_MIN; + nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_110_MAX; + } + if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_275) { + nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_275_MIN; + nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_275_MAX; + } + if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_550) { + nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_550_MIN; + nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_550_MAX; + } + if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_600) { + nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_600_MIN; + nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_600_MAX; + } + if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_733) { + nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_733_MIN; + nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_733_MAX; + } + if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_800) { + nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_800_MIN; + nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_800_MAX; + } + } + + nss_info_always("Supported Frequencies - "); + for (i = 0; i < NSS_FREQ_MAX_SCALE; i++) { + if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_110) { + nss_info_always("110Mhz "); + } else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_275) { + nss_info_always("275Mhz "); + } else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_550) { + nss_info_always("550Mhz "); + } else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_600) { + nss_info_always("600Mhz "); + } else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_733) { + nss_info_always("733Mhz "); + } else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_800) { + nss_info_always("800Mhz "); + } else { + nss_info_always("Error\nNo Table/Invalid Frequency Found - Loading Old Tables -"); + return -EFAULT; + } + } + nss_info_always("\n"); + + /* + * Set default frequency + */ + err = clk_set_rate(nss_core0_clk, nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency); + if (err) { + nss_info_always("%px: cannot set nss core0 clock\n", nss_ctx); + return -EFAULT; + } + + err = clk_prepare_enable(nss_core0_clk); + if (err) { + nss_info_always("%px: cannot enable nss core0 clock\n", nss_ctx); + return -EFAULT; + } + + return 0; +} + +/* + * __nss_hal_read_interrupt_cause() + */ +static void __nss_hal_read_interrupt_cause(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t *cause) +{ + uint32_t value = nss_read_32(nss_ctx->nmap, NSS_REGS_N2H_INTR_STATUS_OFFSET); + *cause = (((value) >> shift_factor) & 0x7FFF); +} + +/* + * __nss_hal_clear_interrupt_cause() + */ +static void __nss_hal_clear_interrupt_cause(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause) +{ + nss_write_32(nss_ctx->nmap, NSS_REGS_N2H_INTR_CLR_OFFSET, (cause << shift_factor)); +} + +/* + * __nss_hal_disable_interrupt() + */ +static void __nss_hal_disable_interrupt(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause) +{ + nss_write_32(nss_ctx->nmap, NSS_REGS_N2H_INTR_MASK_CLR_OFFSET, (cause << shift_factor)); +} + +/* + * __nss_hal_enable_interrupt() + */ +static void __nss_hal_enable_interrupt(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause) +{ + nss_write_32(nss_ctx->nmap, NSS_REGS_N2H_INTR_MASK_SET_OFFSET, (cause << shift_factor)); +} + +/* + * __nss_hal_send_interrupt() + */ +static void __nss_hal_send_interrupt(struct nss_ctx_instance *nss_ctx, uint32_t type) +{ + nss_write_32(nss_ctx->nmap, NSS_REGS_C2C_INTR_SET_OFFSET, intr_cause[type]); +} + +/* + * __nss_hal_request_irq() + */ +static int __nss_hal_request_irq(struct nss_ctx_instance *nss_ctx, struct nss_platform_data *npd, int irq_num) +{ + struct int_ctx_instance *int_ctx = &nss_ctx->int_ctx[irq_num]; + int err; + + if (irq_num == 1) { + int_ctx->shift_factor = 15; + err = request_irq(npd->irq[irq_num], nss_hal_handle_irq, 0, "nss_queue1", int_ctx); + } else { + int_ctx->shift_factor = 0; + err = request_irq(npd->irq[irq_num], nss_hal_handle_irq, 0, "nss", int_ctx); + } + if (err) { + nss_info_always("%px: IRQ%d request failed", nss_ctx, npd->irq[irq_num]); + return err; + } + + int_ctx->irq = npd->irq[irq_num]; + netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi, 64); + + return 0; +} + +/* + * __nss_hal_init_imem + */ +void __nss_hal_init_imem(struct nss_ctx_instance *nss_ctx) +{ + struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; + + mem_ctx->imem_head = NSS_IMEM_START + NSS_IMEM_SIZE * nss_ctx->id; + mem_ctx->imem_end = mem_ctx->imem_head + NSS_IMEM_SIZE; + mem_ctx->imem_tail = mem_ctx->imem_head; + + nss_info("%px: IMEM init: head: 0x%x end: 0x%x tail: 0x%x\n", nss_ctx, + mem_ctx->imem_head, mem_ctx->imem_end, mem_ctx->imem_tail); +} + +/* + * __nss_hal_init_utcm_shared + */ +bool __nss_hal_init_utcm_shared(struct nss_ctx_instance *nss_ctx, uint32_t *meminfo_start) +{ + /* + * Nothing to be done as there are no UTCM_SHARED defined for ipq806x + */ + return true; +} + +/* + * nss_hal_ipq806x_ops + */ +struct nss_hal_ops nss_hal_ipq806x_ops = { + .common_reset = __nss_hal_common_reset, + .core_reset = __nss_hal_core_reset, + .clock_configure = __nss_hal_clock_configure, + .firmware_load = nss_hal_firmware_load, + .debug_enable = __nss_hal_debug_enable, +#if (NSS_DT_SUPPORT == 1) + .of_get_pdata = __nss_hal_of_get_pdata, +#endif + .request_irq = __nss_hal_request_irq, + .send_interrupt = __nss_hal_send_interrupt, + .enable_interrupt = __nss_hal_enable_interrupt, + .disable_interrupt = __nss_hal_disable_interrupt, + .clear_interrupt_cause = __nss_hal_clear_interrupt_cause, + .read_interrupt_cause = __nss_hal_read_interrupt_cause, + .init_imem = __nss_hal_init_imem, + .init_utcm_shared = __nss_hal_init_utcm_shared, +}; diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_hal/ipq807x/nss_hal_pvt.c b/feeds/ipq807x/qca-nss-drv/src/nss_hal/ipq807x/nss_hal_pvt.c new file mode 100644 index 000000000..e5cf1b94b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_hal/ipq807x/nss_hal_pvt.c @@ -0,0 +1,770 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * nss_hal_pvt.c + * NSS HAL private APIs. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "nss_hal.h" +#include "nss_core.h" + +#define NSS_QGIC_IPC_REG_OFFSET 0x8 + +#define NSS0_H2N_INTR_BASE 13 +#define NSS1_H2N_INTR_BASE 19 + +/* + * Common CLKs + */ +#define NSS_NOC_CLK "nss-noc-clk" +#define NSS_PTP_REF_CLK "nss-ptp-ref-clk" +#define NSS_CSR_CLK "nss-csr-clk" +#define NSS_CFG_CLK "nss-cfg-clk" +#define NSS_IMEM_CLK "nss-imem-clk" +#define NSS_NSSNOC_QOSGEN_REF_CLK "nss-nssnoc-qosgen-ref-clk" +#define NSS_MEM_NOC_NSS_AXI_CLK "nss-mem-noc-nss-axi-clk" +#define NSS_NSSNOC_SNOC_CLK "nss-nssnoc-snoc-clk" +#define NSS_NSSNOC_TIMEOUT_REF_CLK "nss-nssnoc-timeout-ref-clk" +#define NSS_CE_AXI_CLK "nss-ce-axi-clk" +#define NSS_CE_APB_CLK "nss-ce-apb-clk" +#define NSS_NSSNOC_CE_AXI_CLK "nss-nssnoc-ce-axi-clk" +#define NSS_NSSNOC_CE_APB_CLK "nss-nssnoc-ce-apb-clk" + +/* + * Per-core CLKS + */ +#define NSS_NSSNOC_AHB_CLK "nss-nssnoc-ahb-clk" +#define NSS_CORE_CLK "nss-core-clk" +#define NSS_AHB_CLK "nss-ahb-clk" +#define NSS_AXI_CLK "nss-axi-clk" +#define NSS_MPT_CLK "nss-mpt-clk" +#define NSS_NC_AXI_CLK "nss-nc-axi-clk" + +/* + * Voltage values + */ +#define NOMINAL_VOLTAGE 1 +#define TURBO_VOLTAGE 2 + +/* + * Core reset part 1 + */ +#define NSS_CORE_GCC_RESET_1 0x00000020 + +/* + * Core reset part 2 + */ +#define NSS_CORE_GCC_RESET_2 0x00000017 + +/* + * Voltage regulator + */ +struct regulator *npu_reg; + +/* + * GCC reset + */ +void __iomem *nss_misc_reset; + +/* + * Purpose of each interrupt index: This should match the order defined in the NSS firmware + */ +enum nss_hal_n2h_intr_purpose { + NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_SOS = 0, + NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_QUEUE = 1, + NSS_HAL_N2H_INTR_PURPOSE_TX_UNBLOCKED = 2, + NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_0 = 3, + NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_1 = 4, + NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_2 = 5, + NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_3 = 6, + NSS_HAL_N2H_INTR_PURPOSE_COREDUMP_COMPLETE = 7, + NSS_HAL_N2H_INTR_PURPOSE_PAGED_EMPTY_BUFFER_SOS = 8, + NSS_HAL_N2H_INTR_PURPOSE_PROFILE_DMA = 9, + NSS_HAL_N2H_INTR_PURPOSE_MAX +}; + +/* + * Interrupt type to cause vector. + */ +static uint32_t intr_cause[NSS_MAX_CORES][NSS_H2N_INTR_TYPE_MAX] = { + /* core0 */ + {(1 << (NSS0_H2N_INTR_BASE + NSS_H2N_INTR_EMPTY_BUFFER_QUEUE)), + (1 << (NSS0_H2N_INTR_BASE + NSS_H2N_INTR_DATA_COMMAND_QUEUE)), + (1 << (NSS0_H2N_INTR_BASE + NSS_H2N_INTR_TX_UNBLOCKED)), + (1 << (NSS0_H2N_INTR_BASE + NSS_H2N_INTR_TRIGGER_COREDUMP)), + (1 << (NSS0_H2N_INTR_BASE + NSS_H2N_INTR_EMPTY_PAGED_BUFFER_QUEUE))}, + /* core 1 */ + {(1 << (NSS1_H2N_INTR_BASE + NSS_H2N_INTR_EMPTY_BUFFER_QUEUE)), + (1 << (NSS1_H2N_INTR_BASE + NSS_H2N_INTR_DATA_COMMAND_QUEUE)), + (1 << (NSS1_H2N_INTR_BASE + NSS_H2N_INTR_TX_UNBLOCKED)), + (1 << (NSS1_H2N_INTR_BASE + NSS_H2N_INTR_TRIGGER_COREDUMP)), + (1 << (NSS1_H2N_INTR_BASE + NSS_H2N_INTR_EMPTY_PAGED_BUFFER_QUEUE))} +}; + +/* + * nss_hal_wq_function() + * Added to Handle BH requests to kernel + */ +void nss_hal_wq_function(struct work_struct *work) +{ + nss_work_t *my_work = (nss_work_t *)work; + + mutex_lock(&nss_top_main.wq_lock); + + if (my_work->frequency > NSS_FREQ_1497) { + regulator_set_voltage(npu_reg, TURBO_VOLTAGE, TURBO_VOLTAGE); + } + + nss_freq_change(&nss_top_main.nss[NSS_CORE_0], my_work->frequency, my_work->stats_enable, 0); + if (nss_top_main.nss[NSS_CORE_1].state == NSS_CORE_STATE_INITIALIZED) { + nss_freq_change(&nss_top_main.nss[NSS_CORE_1], my_work->frequency, my_work->stats_enable, 0); + } + clk_set_rate(nss_core0_clk, my_work->frequency); + + nss_freq_change(&nss_top_main.nss[NSS_CORE_0], my_work->frequency, my_work->stats_enable, 1); + if (nss_top_main.nss[NSS_CORE_1].state == NSS_CORE_STATE_INITIALIZED) { + nss_freq_change(&nss_top_main.nss[NSS_CORE_1], my_work->frequency, my_work->stats_enable, 1); + } + + clk_set_rate(nss_core1_clk, my_work->frequency); + if (my_work->frequency <= NSS_FREQ_1497) { + regulator_set_voltage(npu_reg, NOMINAL_VOLTAGE, NOMINAL_VOLTAGE); + } + + mutex_unlock(&nss_top_main.wq_lock); + kfree((void *)work); +} + +/* + * nss_hal_handle_irq() + */ +static irqreturn_t nss_hal_handle_irq(int irq, void *ctx) +{ + struct int_ctx_instance *int_ctx = (struct int_ctx_instance *) ctx; + + disable_irq_nosync(irq); + napi_schedule(&int_ctx->napi); + + return IRQ_HANDLED; +} + +/* + * __nss_hal_of_get_pdata() + * Retrieve platform data from device node. + */ +static struct nss_platform_data *__nss_hal_of_get_pdata(struct platform_device *pdev) +{ + struct device_node *np = of_node_get(pdev->dev.of_node); + struct nss_platform_data *npd; + struct nss_ctx_instance *nss_ctx = NULL; + struct nss_top_instance *nss_top = &nss_top_main; + struct resource res_nphys, res_vphys, res_qgic_phys; + int32_t i; + + npd = devm_kzalloc(&pdev->dev, sizeof(struct nss_platform_data), GFP_KERNEL); + if (!npd) { + return NULL; + } + + if (of_property_read_u32(np, "qcom,id", &npd->id) + || of_property_read_u32(np, "qcom,load-addr", &npd->load_addr) + || of_property_read_u32(np, "qcom,num-queue", &npd->num_queue) + || of_property_read_u32(np, "qcom,num-irq", &npd->num_irq)) { + pr_err("%s: error reading critical device node properties\n", np->name); + goto out; + } + + /* + * Read frequencies. If failure, load default values. + */ + of_property_read_u32(np, "qcom,low-frequency", &nss_runtime_samples.freq_scale[NSS_FREQ_LOW_SCALE].frequency); + of_property_read_u32(np, "qcom,mid-frequency", &nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency); + of_property_read_u32(np, "qcom,max-frequency", &nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency); + + if (npd->num_irq > NSS_MAX_IRQ_PER_CORE) { + pr_err("%s: exceeds maximum interrupt numbers per core\n", np->name); + goto out; + } + + nss_ctx = &nss_top->nss[npd->id]; + nss_ctx->id = npd->id; + + if (of_address_to_resource(np, 0, &res_nphys) != 0) { + nss_info_always("%px: nss%d: of_address_to_resource() fail for nphys\n", nss_ctx, nss_ctx->id); + goto out; + } + + if (of_address_to_resource(np, 1, &res_vphys) != 0) { + nss_info_always("%px: nss%d: of_address_to_resource() fail for vphys\n", nss_ctx, nss_ctx->id); + goto out; + } + + if (of_address_to_resource(np, 2, &res_qgic_phys) != 0) { + nss_info_always("%px: nss%d: of_address_to_resource() fail for qgic_phys\n", nss_ctx, nss_ctx->id); + goto out; + } + + /* + * Save physical addresses + */ + npd->nphys = res_nphys.start; + npd->vphys = res_vphys.start; + npd->qgic_phys = res_qgic_phys.start; + + npd->nmap = ioremap_nocache(npd->nphys, resource_size(&res_nphys)); + if (!npd->nmap) { + nss_info_always("%px: nss%d: ioremap() fail for nphys\n", nss_ctx, nss_ctx->id); + goto out; + } + + npd->vmap = ioremap_cache(npd->vphys, resource_size(&res_vphys)); + if (!npd->vmap) { + nss_info_always("%px: nss%d: ioremap() fail for vphys\n", nss_ctx, nss_ctx->id); + goto out; + } + + npd->qgic_map = ioremap_nocache(npd->qgic_phys, resource_size(&res_qgic_phys)); + if (!npd->qgic_map) { + nss_info_always("%px: nss%d: ioremap() fail for qgic map\n", nss_ctx, nss_ctx->id); + goto out; + } + + /* + * Clear TCM memory used by this core + */ + for (i = 0; i < resource_size(&res_vphys) ; i += 4) { + nss_write_32(npd->vmap, i, 0); + NSS_CORE_DMA_CACHE_MAINT((npd->vmap + i), 4, DMA_TO_DEVICE); + } + NSS_CORE_DSB(); + + /* + * Get IRQ numbers + */ + for (i = 0 ; i < npd->num_irq; i++) { + npd->irq[i] = irq_of_parse_and_map(np, i); + if (!npd->irq[i]) { + nss_info_always("%px: nss%d: irq_of_parse_and_map() fail for irq %d\n", nss_ctx, nss_ctx->id, i); + goto out; + } + } + + nss_hal_dt_parse_features(np, npd); + + of_node_put(np); + return npd; + +out: + if (npd->nmap) { + iounmap(npd->nmap); + } + + if (npd->vmap) { + iounmap(npd->vmap); + } + + devm_kfree(&pdev->dev, npd); + of_node_put(np); + return NULL; +} + +/* + * __nss_hal_core_reset() + */ +static int __nss_hal_core_reset(struct platform_device *nss_dev, void __iomem *map, uint32_t addr, uint32_t clk_src) +{ + uint32_t value; + + /* + * De-assert reset for first set + */ + value = nss_read_32(nss_misc_reset, 0x0); + value &= ~(NSS_CORE_GCC_RESET_1 << (nss_dev->id << 3)); + nss_write_32(nss_misc_reset, 0x0, value); + + /* + * Minimum 10 - 20 cycles delay is required after + * de-asserting UBI reset clamp + */ + usleep_range(10, 20); + + /* + * De-assert reset for second set + */ + value &= ~(NSS_CORE_GCC_RESET_2 << (nss_dev->id << 3)); + nss_write_32(nss_misc_reset, 0x0, value); + + /* + * Apply ubi32 core reset + */ + nss_write_32(map, NSS_REGS_RESET_CTRL_OFFSET, 1); + + /* + * Program address configuration + */ + nss_write_32(map, NSS_REGS_CORE_AMC_OFFSET, 1); + nss_write_32(map, NSS_REGS_CORE_BAR_OFFSET, 0x3c000000); + nss_write_32(map, NSS_REGS_CORE_BOOT_ADDR_OFFSET, addr); + + /* + * C2C interrupts are level sensitive + * Copy engine interrupts are level sensitive + */ + nss_write_32(map, NSS_REGS_CORE_INT_STAT2_TYPE_OFFSET, 0xFFFF); + nss_write_32(map, NSS_REGS_CORE_INT_STAT3_TYPE_OFFSET, 0xFF); + + /* + * Enable Instruction Fetch range checking between 0x4000 0000 to 0xBFFF FFFF. + */ + nss_write_32(map, NSS_REGS_CORE_IFETCH_RANGE_OFFSET, 0xBF004001); + + /* + * De-assert ubi32 core reset + */ + nss_write_32(map, NSS_REGS_RESET_CTRL_OFFSET, 0); + + return 0; +} + +/* + * __nss_hal_debug_enable() + * Enable NSS debug + */ +static void __nss_hal_debug_enable(void) +{ + +} + +/* + * nss_hal_clock_set_and_enable() + */ +static int nss_hal_clock_set_and_enable(struct device *dev, const char *id, unsigned long rate) +{ + struct clk *nss_clk = NULL; + int err; + + nss_clk = devm_clk_get(dev, id); + if (IS_ERR(nss_clk)) { + pr_err("%px: cannot get clock: %s\n", dev, id); + return -EFAULT; + } + + if (rate) { + err = clk_set_rate(nss_clk, rate); + if (err) { + pr_err("%px: cannot set %s freq\n", dev, id); + return -EFAULT; + } + } + + err = clk_prepare_enable(nss_clk); + if (err) { + pr_err("%px: cannot enable clock: %s\n", dev, id); + return -EFAULT; + } + + return 0; +} + +/* + * __nss_hal_common_reset + * Do reset/clock configuration common to all cores + */ +static int __nss_hal_common_reset(struct platform_device *nss_dev) +{ + struct device_node *cmn = NULL; + struct resource res_nss_misc_reset; + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NOC_CLK, 461500000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_PTP_REF_CLK, 150000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CSR_CLK, 200000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CFG_CLK, 100000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_IMEM_CLK, 400000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NSSNOC_QOSGEN_REF_CLK, 19200000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_MEM_NOC_NSS_AXI_CLK, 461500000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NSSNOC_SNOC_CLK, 266600000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NSSNOC_TIMEOUT_REF_CLK, 4800000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CE_AXI_CLK, 200000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CE_APB_CLK, 200000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NSSNOC_CE_AXI_CLK, 200000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NSSNOC_CE_APB_CLK, 200000000)) { + return -EFAULT; + } + + /* + * Get reference to NSS common device node + */ + cmn = of_find_node_by_name(NULL, "nss-common"); + if (!cmn) { + pr_err("%px: Unable to find nss-common node\n", nss_dev); + return -EFAULT; + } + + if (of_address_to_resource(cmn, 0, &res_nss_misc_reset) != 0) { + pr_err("%px: of_address_to_resource() return error for nss_misc_reset\n", nss_dev); + of_node_put(cmn); + return -EFAULT; + } + of_node_put(cmn); + + nss_misc_reset = ioremap_nocache(res_nss_misc_reset.start, resource_size(&res_nss_misc_reset)); + if (!nss_misc_reset) { + pr_err("%px: ioremap fail for nss_misc_reset\n", nss_dev); + return -EFAULT; + } + + nss_top_main.nss_hal_common_init_done = true; + nss_info("nss_hal_common_reset Done\n"); + return 0; +} + +/* + * __nss_hal_clock_configure() + */ +static int __nss_hal_clock_configure(struct nss_ctx_instance *nss_ctx, struct platform_device *nss_dev, struct nss_platform_data *npd) +{ + uint32_t i; + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NSSNOC_AHB_CLK, 200000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_AHB_CLK, 200000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_AXI_CLK, 461500000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_MPT_CLK, 25000000)) { + return -EFAULT; + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_NC_AXI_CLK, 461500000)) { + return -EFAULT; + } + + /* + * For IPQ807x, any rate above 1497 is Turbo Voltage + * Temporary set the voltage to turbo till we start scaling frequenices. + * This is to ensure probing is safe and autoscaling will correct the voltage. + */ + if (!nss_ctx->id) { + npu_reg = devm_regulator_get(&nss_dev->dev, "npu"); + if (IS_ERR(npu_reg)) { + return PTR_ERR(npu_reg); + } + if (regulator_enable(npu_reg)) { + return -EFAULT; + } + regulator_set_voltage(npu_reg, TURBO_VOLTAGE, TURBO_VOLTAGE); + } + + /* + * No entries, then just load default + */ + if ((nss_runtime_samples.freq_scale[NSS_FREQ_LOW_SCALE].frequency == 0) || + (nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency == 0) || + (nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency == 0)) { + nss_runtime_samples.freq_scale[NSS_FREQ_LOW_SCALE].frequency = NSS_FREQ_187; + nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency = NSS_FREQ_748; + nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency = NSS_FREQ_1497; + nss_info_always("Running default frequencies\n"); + } + + /* + * Test frequency from dtsi, if fail, try to set default frequency. + */ + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, nss_runtime_samples.freq_scale[NSS_FREQ_HIGH_SCALE].frequency)) { + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, NSS_FREQ_1497)) { + return -EFAULT; + } + } + + /* + * Setup ranges, test frequency, and display. + */ + for (i = 0; i < NSS_FREQ_MAX_SCALE; i++) { + if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_187) { + nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_187_MIN; + nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_187_MAX; + } else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_748) { + nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_748_MIN; + nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_748_MAX; + } else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_1497) { + nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_1497_MIN; + nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_1497_MAX; + } else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_1689) { + nss_runtime_samples.freq_scale[i].minimum = NSS_FREQ_1689_MIN; + nss_runtime_samples.freq_scale[i].maximum = NSS_FREQ_1689_MAX; + } else { + nss_info_always("Frequency not found %d\n", nss_runtime_samples.freq_scale[i].frequency); + return -EFAULT; + } + + /* + * Test the frequency, if fail, then default to safe frequency and abort + */ + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, nss_runtime_samples.freq_scale[i].frequency)) { + return -EFAULT; + } + } + + nss_info_always("Supported Frequencies - "); + for (i = 0; i < NSS_FREQ_MAX_SCALE; i++) { + if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_187) { + nss_info_always("187.2 MHz "); + } else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_748) { + nss_info_always("748.8 MHz "); + } else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_1497) { + nss_info_always("1.4976 GHz "); + } else if (nss_runtime_samples.freq_scale[i].frequency == NSS_FREQ_1689) { + nss_info_always("1.6896 GHz "); + } else { + nss_info_always("Error\nNo Table/Invalid Frequency Found\n"); + return -EFAULT; + } + } + nss_info_always("\n"); + + /* + * Set values only once for core0. Grab the proper clock. + */ + if (nss_ctx->id) { + nss_core1_clk = clk_get(&nss_dev->dev, NSS_CORE_CLK); + } else { + nss_core0_clk = clk_get(&nss_dev->dev, NSS_CORE_CLK); + } + + if (nss_hal_clock_set_and_enable(&nss_dev->dev, NSS_CORE_CLK, nss_runtime_samples.freq_scale[NSS_FREQ_MID_SCALE].frequency)) { + return -EFAULT; + } + + return 0; +} + +/* + * __nss_hal_read_interrupt_cause() + */ +static void __nss_hal_read_interrupt_cause(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t *cause) +{ +} + +/* + * __nss_hal_clear_interrupt_cause() + */ +static void __nss_hal_clear_interrupt_cause(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause) +{ +} + +/* + * __nss_hal_disable_interrupt() + */ +static void __nss_hal_disable_interrupt(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause) +{ +} + +/* + * __nss_hal_enable_interrupt() + */ +static void __nss_hal_enable_interrupt(struct nss_ctx_instance *nss_ctx, uint32_t shift_factor, uint32_t cause) +{ +} + +/* + * __nss_hal_send_interrupt() + */ +static void __nss_hal_send_interrupt(struct nss_ctx_instance *nss_ctx, uint32_t type) +{ + /* + * Check if core and type is Valid + */ + nss_assert(nss_ctx->id < nss_top_main.num_nss); + nss_assert(type < NSS_H2N_INTR_TYPE_MAX); + + nss_write_32(nss_ctx->qgic_map, NSS_QGIC_IPC_REG_OFFSET, intr_cause[nss_ctx->id][type]); +} + +/* + * __nss_hal_request_irq() + */ +static int __nss_hal_request_irq(struct nss_ctx_instance *nss_ctx, struct nss_platform_data *npd, int irq_num) +{ + struct int_ctx_instance *int_ctx = &nss_ctx->int_ctx[irq_num]; + int err = -1, irq = npd->irq[irq_num]; + + irq_set_status_flags(irq, IRQ_DISABLE_UNLAZY); + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_SOS) { + netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT); + int_ctx->cause = NSS_N2H_INTR_EMPTY_BUFFERS_SOS; + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_empty_buf_sos", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_EMPTY_BUFFER_QUEUE) { + netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_EMPTY_BUFFER_RETURN_PROCESSING_WEIGHT); + int_ctx->cause = NSS_N2H_INTR_EMPTY_BUFFER_QUEUE; + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_empty_buf_queue", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_TX_UNBLOCKED) { + netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_TX_UNBLOCKED_PROCESSING_WEIGHT); + int_ctx->cause = NSS_N2H_INTR_TX_UNBLOCKED; + err = request_irq(irq, nss_hal_handle_irq, 0, "nss-tx-unblock", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_0) { + netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); + int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_0; + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue0", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_1) { + int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_1; + netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue1", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_2) { + int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_2; + netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue2", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_DATA_QUEUE_3) { + int_ctx->cause = NSS_N2H_INTR_DATA_QUEUE_3; + netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_queue, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_queue3", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_COREDUMP_COMPLETE) { + int_ctx->cause = NSS_N2H_INTR_COREDUMP_COMPLETE; + netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_emergency, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_coredump_complete", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_PAGED_EMPTY_BUFFER_SOS) { + netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_non_queue, NSS_EMPTY_BUFFER_SOS_PROCESSING_WEIGHT); + int_ctx->cause = NSS_N2H_INTR_PAGED_EMPTY_BUFFERS_SOS; + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_paged_empty_buf_sos", int_ctx); + } + + if (irq_num == NSS_HAL_N2H_INTR_PURPOSE_PROFILE_DMA) { + int_ctx->cause = NSS_N2H_INTR_PROFILE_DMA; + netif_napi_add(&nss_ctx->napi_ndev, &int_ctx->napi, nss_core_handle_napi_sdma, NSS_DATA_COMMAND_BUFFER_PROCESSING_WEIGHT); + err = request_irq(irq, nss_hal_handle_irq, 0, "nss_profile_dma", int_ctx); + } + + if (err) { + return err; + } + + int_ctx->irq = irq; + return 0; +} + +/* + * __nss_hal_init_imem + */ +void __nss_hal_init_imem(struct nss_ctx_instance *nss_ctx) +{ + struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; + + mem_ctx->imem_head = NSS_IMEM_START + NSS_IMEM_SIZE * nss_ctx->id; + mem_ctx->imem_end = mem_ctx->imem_head + NSS_IMEM_SIZE; + mem_ctx->imem_tail = mem_ctx->imem_head; + + nss_info("%px: IMEM init: head: 0x%x end: 0x%x tail: 0x%x\n", nss_ctx, + mem_ctx->imem_head, mem_ctx->imem_end, mem_ctx->imem_tail); +} + +/* + * __nss_hal_init_utcm_shared + */ +bool __nss_hal_init_utcm_shared(struct nss_ctx_instance *nss_ctx, uint32_t *meminfo_start) +{ + /* + * Nothing to be done as there are no TCM in ipq807x + */ + return true; +} + +/* + * nss_hal_ipq807x_ops + */ +struct nss_hal_ops nss_hal_ipq807x_ops = { + .common_reset = __nss_hal_common_reset, + .core_reset = __nss_hal_core_reset, + .clock_configure = __nss_hal_clock_configure, + .firmware_load = nss_hal_firmware_load, + .debug_enable = __nss_hal_debug_enable, + .of_get_pdata = __nss_hal_of_get_pdata, + .request_irq = __nss_hal_request_irq, + .send_interrupt = __nss_hal_send_interrupt, + .enable_interrupt = __nss_hal_enable_interrupt, + .disable_interrupt = __nss_hal_disable_interrupt, + .clear_interrupt_cause = __nss_hal_clear_interrupt_cause, + .read_interrupt_cause = __nss_hal_read_interrupt_cause, + .init_imem = __nss_hal_init_imem, + .init_utcm_shared = __nss_hal_init_utcm_shared, +}; diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_hal/nss_hal.c b/feeds/ipq807x/qca-nss-drv/src/nss_hal/nss_hal.c new file mode 100644 index 000000000..7172e2a77 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_hal/nss_hal.c @@ -0,0 +1,813 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * nss_hal.c + * NSS HAL general APIs. + */ + +#include +#include +#include +#include +#include + +#include "nss_hal.h" +#include "nss_arch.h" +#include "nss_core.h" +#include "nss_tx_rx_common.h" +#include "nss_data_plane.h" +#if (NSS_PM_SUPPORT == 1) +#include "nss_pm.h" +#endif +#if (NSS_FABRIC_SCALING_SUPPORT == 1) +#include +#endif + +/* + * Macros + */ +#define MIN_IMG_SIZE (64*1024) +#define NSS_AP0_IMAGE "qca-nss0.bin" +#define NSS_AP1_IMAGE "qca-nss1.bin" + +/* + * File local/Static variables/functions + */ +static const struct net_device_ops nss_netdev_ops; +static const struct ethtool_ops nss_ethtool_ops; + +int nss_hal_firmware_load(struct nss_ctx_instance *nss_ctx, struct platform_device *nss_dev, struct nss_platform_data *npd) +{ + const struct firmware *nss_fw; + void __iomem *load_mem; + int rc; + + if (nss_ctx->id == 0) { + rc = request_firmware(&nss_fw, NSS_AP0_IMAGE, &(nss_dev->dev)); + } else if (nss_ctx->id == 1) { + rc = request_firmware(&nss_fw, NSS_AP1_IMAGE, &(nss_dev->dev)); + } else { + nss_warning("%px: Invalid nss dev: %d\n", nss_ctx, nss_ctx->id); + return -EINVAL; + } + + /* + * Check if the file read is successful + */ + if (rc) { + nss_info_always("%px: request_firmware failed with err code: %d", nss_ctx, rc); + return rc; + } + + if (nss_fw->size < MIN_IMG_SIZE) { + nss_info_always("%px: nss firmware is truncated, size:%d", nss_ctx, (int)nss_fw->size); + return rc; + } + + load_mem = ioremap_nocache(npd->load_addr, nss_fw->size); + if (!load_mem) { + nss_info_always("%px: ioremap_nocache failed: %x", nss_ctx, npd->load_addr); + release_firmware(nss_fw); + return rc; + } + + nss_info_always("nss_driver - fw of size %d bytes copied to load addr: %x, nss_id : %d\n", (int)nss_fw->size, npd->load_addr, nss_dev->id); + memcpy_toio(load_mem, nss_fw->data, nss_fw->size); + release_firmware(nss_fw); + iounmap(load_mem); + return 0; +} + +/* + * nss_hal_dt_parse_features() + */ +void nss_hal_dt_parse_features(struct device_node *np, struct nss_platform_data *npd) +{ + /* + * Read the features in + */ + npd->bridge_enabled = of_property_read_bool(np, "qcom,bridge-enabled"); + npd->capwap_enabled = of_property_read_bool(np, "qcom,capwap-enabled"); + npd->clmap_enabled = of_property_read_bool(np, "qcom,clmap-enabled"); + npd->crypto_enabled = of_property_read_bool(np, "qcom,crypto-enabled"); + npd->dtls_enabled = of_property_read_bool(np, "qcom,dtls-enabled"); + npd->gre_enabled = of_property_read_bool(np, "qcom,gre-enabled"); + npd->gre_redir_enabled = of_property_read_bool(np, "qcom,gre-redir-enabled"); + npd->gre_tunnel_enabled = of_property_read_bool(np, "qcom,gre_tunnel_enabled"); + npd->gre_redir_mark_enabled = of_property_read_bool(np, "qcom,gre-redir-mark-enabled"); + npd->igs_enabled = of_property_read_bool(np, "qcom,igs-enabled"); + npd->ipsec_enabled = of_property_read_bool(np, "qcom,ipsec-enabled"); + npd->ipv4_enabled = of_property_read_bool(np, "qcom,ipv4-enabled"); + npd->ipv4_reasm_enabled = of_property_read_bool(np, "qcom,ipv4-reasm-enabled"); + npd->ipv6_enabled = of_property_read_bool(np, "qcom,ipv6-enabled"); + npd->ipv6_reasm_enabled = of_property_read_bool(np, "qcom,ipv6-reasm-enabled"); + npd->l2tpv2_enabled = of_property_read_bool(np, "qcom,l2tpv2-enabled"); + npd->map_t_enabled = of_property_read_bool(np, "qcom,map-t-enabled"); + npd->oam_enabled = of_property_read_bool(np, "qcom,oam-enabled"); + npd->ppe_enabled = of_property_read_bool(np, "qcom,ppe-enabled"); + npd->pppoe_enabled = of_property_read_bool(np, "qcom,pppoe-enabled"); + npd->pptp_enabled = of_property_read_bool(np, "qcom,pptp-enabled"); + npd->portid_enabled = of_property_read_bool(np, "qcom,portid-enabled"); + npd->pvxlan_enabled = of_property_read_bool(np, "qcom,pvxlan-enabled"); + npd->qvpn_enabled = of_property_read_bool(np, "qcom,qvpn-enabled"); + npd->rmnet_rx_enabled = of_property_read_bool(np, "qcom,rmnet_rx-enabled"); + npd->shaping_enabled = of_property_read_bool(np, "qcom,shaping-enabled"); + npd->tls_enabled = of_property_read_bool(np, "qcom,tls-enabled"); + npd->tstamp_enabled = of_property_read_bool(np, "qcom,tstamp-enabled"); + npd->turbo_frequency = of_property_read_bool(np, "qcom,turbo-frequency"); + npd->tun6rd_enabled = of_property_read_bool(np, "qcom,tun6rd-enabled"); + npd->tunipip6_enabled = of_property_read_bool(np, "qcom,tunipip6-enabled"); + npd->vlan_enabled = of_property_read_bool(np, "qcom,vlan-enabled"); + npd->vxlan_enabled = of_property_read_bool(np, "qcom,vxlan-enabled"); + npd->wlanredirect_enabled = of_property_read_bool(np, "qcom,wlanredirect-enabled"); + npd->wifioffload_enabled = of_property_read_bool(np, "qcom,wlan-dataplane-offload-enabled"); + npd->match_enabled = of_property_read_bool(np, "qcom,match-enabled"); + npd->mirror_enabled = of_property_read_bool(np, "qcom,mirror-enabled"); +} +/* + * nss_hal_clean_up_irq() + */ +static void nss_hal_clean_up_irq(struct int_ctx_instance *int_ctx) +{ + if (!int_ctx->irq) { + return; + } + + /* + * Wait here till the poll is complete. + */ + napi_disable(&int_ctx->napi); + + /* + * Interrupt can be raised here before free_irq() but as napi is + * already disabled, it will be never sheduled from hard_irq + * context. + */ + irq_clear_status_flags(int_ctx->irq, IRQ_DISABLE_UNLAZY); + free_irq(int_ctx->irq, int_ctx); + int_ctx->irq = 0; + + netif_napi_del(&int_ctx->napi); +} + +/* + * nss_hal_register_irq() + */ +static int nss_hal_register_irq(struct nss_ctx_instance *nss_ctx, struct nss_platform_data *npd, + struct net_device *netdev, int irq_num) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct int_ctx_instance *int_ctx = &nss_ctx->int_ctx[irq_num]; + int err = 0; + + /* + * request for IRQs + */ + int_ctx->nss_ctx = nss_ctx; + err = nss_top->hal_ops->request_irq(nss_ctx, npd, irq_num); + if (err) { + nss_warning("%px: IRQ request for queue %d failed", nss_ctx, irq_num); + return err; + } + + /* + * Register NAPI for NSS core interrupt + */ + napi_enable(&int_ctx->napi); + return 0; +} + +/* + * nss_hal_probe() + * HLOS device probe callback + */ +int nss_hal_probe(struct platform_device *nss_dev) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = NULL; + struct nss_platform_data *npd = NULL; + int i, err = 0; +#ifdef NSS_DRV_TSTAMP_ENABLE + struct net_device *tstamp_ndev = NULL; +#endif + + if (nss_top_main.nss_hal_common_init_done == false) { + err = nss_top->hal_ops->common_reset(nss_dev); + if (err) { + nss_info_always("NSS HAL common init failed\n"); + return -EFAULT; + } + } + +#if (NSS_DT_SUPPORT == 1) + if (!nss_dev->dev.of_node) { + pr_err("nss-driver: Device tree not available\n"); + return -ENODEV; + } + + npd = nss_top->hal_ops->of_get_pdata(nss_dev); + if (!npd) { + return -EFAULT; + } + + nss_ctx = &nss_top->nss[npd->id]; + nss_ctx->id = npd->id; + nss_dev->id = nss_ctx->id; +#else + npd = (struct nss_platform_data *) nss_dev->dev.platform_data; + nss_ctx = &nss_top->nss[nss_dev->id]; + nss_ctx->id = nss_dev->id; +#endif + nss_ctx->num_irq = npd->num_irq; + nss_ctx->nss_top = nss_top; + + /* + * dev is required for dma map/unmap + */ + nss_ctx->dev = &nss_dev->dev; + + nss_info("%px: NSS_DEV_ID %s\n", nss_ctx, dev_name(&nss_dev->dev)); + + /* + * Do firmware load from nss-drv if required + */ + err = nss_top->hal_ops->firmware_load(nss_ctx, nss_dev, npd); + if (err) { + nss_info_always("%px: firmware load from driver failed\n", nss_ctx); + goto err_init; + } + + err = nss_top->hal_ops->clock_configure(nss_ctx, nss_dev, npd); + if (err) { + nss_info_always("%px: clock configure failed\n", nss_ctx); + goto err_init; + } + + /* + * Get load address of NSS firmware + */ + nss_info("%px: Setting NSS%d Firmware load address to %x\n", nss_ctx, nss_ctx->id, npd->load_addr); + nss_top->nss[nss_ctx->id].load = npd->load_addr; + + /* + * Get virtual and physical memory addresses for nss logical/hardware address maps + */ + + /* + * Virtual address of CSM space + */ + nss_ctx->nmap = npd->nmap; + + /* + * Physical address of CSM space + */ + nss_ctx->nphys = npd->nphys; + nss_assert(nss_ctx->nphys); + + /* + * Virtual address of logical registers space + */ + nss_ctx->vmap = npd->vmap; + + /* + * Virtual address of QGIC interrupt space + */ + nss_ctx->qgic_map = npd->qgic_map; + + /* + * Physical address of logical registers space + */ + nss_ctx->vphys = npd->vphys; + nss_assert(nss_ctx->vphys); + nss_info("%d:ctx=%px, vphys=%x, vmap=%px, nphys=%x, nmap=%px", nss_ctx->id, + nss_ctx, nss_ctx->vphys, nss_ctx->vmap, nss_ctx->nphys, nss_ctx->nmap); + + if (!nss_meminfo_init(nss_ctx)) { + nss_info_always("%px: meminfo init failed\n", nss_ctx); + err = -EFAULT; + goto err_init; + } + + /* + * Initialize the dummy netdevice. + */ + init_dummy_netdev(&nss_ctx->napi_ndev); + + for (i = 0; i < npd->num_irq; i++) { + err = nss_hal_register_irq(nss_ctx, npd, &nss_ctx->napi_ndev, i); + if (err) { + goto err_register_irq; + } + } + +#ifdef NSS_DRV_TSTAMP_ENABLE + /* + * Allocate tstamp net_device and register the net_device + */ + if (npd->tstamp_enabled == NSS_FEATURE_ENABLED) { + tstamp_ndev = nss_tstamp_register_netdev(); + if (!tstamp_ndev) { + nss_warning("%px: Unable to register the TSTAMP net_device", nss_ctx); + npd->tstamp_enabled = NSS_FEATURE_NOT_ENABLED; + } + nss_top->tstamp_handler_id = nss_dev->id; + nss_tstamp_register_handler(tstamp_ndev); + } +#endif + /* + * Initialize the handlers for all interfaces associated with core + */ + nss_core_init_handlers(nss_ctx); + + /* + * Features that will always be enabled on both cores + */ + nss_dynamic_interface_register_handler(nss_ctx); + nss_n2h_register_handler(nss_ctx); + nss_project_register_handler(nss_ctx); +#ifdef NSS_DRV_QRFS_ENABLE + nss_qrfs_register_handler(nss_ctx); +#endif + +#ifdef NSS_DRV_C2C_ENABLE + nss_c2c_tx_register_handler(nss_ctx); + nss_c2c_rx_register_handler(nss_ctx); +#endif + nss_unaligned_register_handler(nss_ctx); + + /* + * Check functionalities are supported by this NSS core + */ +#ifdef NSS_DRV_SHAPER_ENABLE + if (npd->shaping_enabled == NSS_FEATURE_ENABLED) { + nss_top->shaping_handler_id = nss_dev->id; + nss_info("%d: NSS shaping is enabled", nss_dev->id); + } +#endif + + if (npd->ipv4_enabled == NSS_FEATURE_ENABLED) { + nss_top->ipv4_handler_id = nss_dev->id; + nss_ipv4_register_handler(); + +#ifdef NSS_DRV_EDMA_ENABLE + nss_top->edma_handler_id = nss_dev->id; + nss_edma_register_handler(); +#endif + nss_eth_rx_register_handler(nss_ctx); +#ifdef NSS_DRV_LAG_ENABLE + nss_lag_register_handler(); +#endif +#ifdef NSS_DRV_TRUSTSEC_ENABLE + nss_top->trustsec_tx_handler_id = nss_dev->id; + nss_trustsec_tx_register_handler(); +#endif + + nss_top->virt_if_handler_id = nss_dev->id; + + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_GENERIC_REDIR_N2H] = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_GENERIC_REDIR_H2N] = nss_dev->id; + } + +#ifdef NSS_DRV_CAPWAP_ENABLE + if (npd->capwap_enabled == NSS_FEATURE_ENABLED) { + nss_top->capwap_handler_id = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_CAPWAP] = nss_dev->id; + } +#endif + + if (npd->ipv4_reasm_enabled == NSS_FEATURE_ENABLED) { + nss_top->ipv4_reasm_handler_id = nss_dev->id; + nss_ipv4_reasm_register_handler(); + } + + if (npd->ipv6_enabled == NSS_FEATURE_ENABLED) { + nss_top->ipv6_handler_id = nss_dev->id; + nss_ipv6_register_handler(); + } + + if (npd->ipv6_reasm_enabled == NSS_FEATURE_ENABLED) { + nss_top->ipv6_reasm_handler_id = nss_dev->id; + nss_ipv6_reasm_register_handler(); + } + +#ifdef NSS_DRV_CRYPTO_ENABLE + /* + * TODO: when Crypto is moved to Core-1 it needs to + * flush based on nss_top->crypto_enabled + */ + if (npd->crypto_enabled == NSS_FEATURE_ENABLED) { + nss_top->crypto_handler_id = nss_dev->id; +#if defined(NSS_HAL_IPQ807x_SUPPORT) || defined(NSS_HAL_IPQ60XX_SUPPORT) || defined(NSS_HAL_IPQ50XX_SUPPORT) + nss_crypto_cmn_register_handler(); +#else + nss_top->crypto_enabled = 1; + nss_crypto_register_handler(); +#endif + +#if defined(NSS_HAL_IPQ807x_SUPPORT) || defined(NSS_HAL_IPQ60XX_SUPPORT) + nss_top->dma_handler_id = nss_dev->id; + nss_dma_register_handler(); +#endif + } +#endif + +#ifdef NSS_DRV_IPSEC_ENABLE + if (npd->ipsec_enabled == NSS_FEATURE_ENABLED) { + nss_top->ipsec_handler_id = nss_dev->id; +#if defined(NSS_HAL_IPQ807x_SUPPORT) || defined(NSS_HAL_IPQ60XX_SUPPORT) || defined(NSS_HAL_IPQ50XX_SUPPORT) + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_INNER] = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_OUTER] = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_MDATA_INNER] = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_MDATA_OUTER] = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_REDIRECT] = nss_dev->id; + nss_ipsec_cmn_register_handler(); +#else + nss_ipsec_register_handler(); +#endif + } +#endif + + if (npd->wlanredirect_enabled == NSS_FEATURE_ENABLED) { + nss_top->wlan_handler_id = nss_dev->id; + } + +#ifdef NSS_DRV_TUN6RD_ENABLE + if (npd->tun6rd_enabled == NSS_FEATURE_ENABLED) { + nss_top->tun6rd_handler_id = nss_dev->id; + } +#endif + +#ifdef NSS_DRV_PPTP_ENABLE + if (npd->pptp_enabled == NSS_FEATURE_ENABLED) { + nss_top->pptp_handler_id = nss_dev->id; + nss_pptp_register_handler(); + } +#endif + + if (npd->pppoe_enabled == NSS_FEATURE_ENABLED) { + nss_top->pppoe_handler_id = nss_dev->id; + nss_pppoe_register_handler(); + } + +#ifdef NSS_DRV_PPE_ENABLE + if (npd->ppe_enabled == NSS_FEATURE_ENABLED) { + nss_top->ppe_handler_id = nss_dev->id; + nss_ppe_register_handler(); + nss_ppe_vp_register_handler(); + } +#endif + +#ifdef NSS_DRV_L2TP_ENABLE + if (npd->l2tpv2_enabled == NSS_FEATURE_ENABLED) { + nss_top->l2tpv2_handler_id = nss_dev->id; + nss_l2tpv2_register_handler(); + } +#endif + +#ifdef NSS_DRV_DTLS_ENABLE + if (npd->dtls_enabled == NSS_FEATURE_ENABLED) { + nss_top->dtls_handler_id = nss_dev->id; +#if defined(NSS_HAL_IPQ807x_SUPPORT) || defined(NSS_HAL_IPQ60XX_SUPPORT) || defined(NSS_HAL_IPQ50XX_SUPPORT) + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_DTLS_CMN_INNER] = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_DTLS_CMN_OUTER] = nss_dev->id; + nss_dtls_cmn_register_handler(); +#else + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_DTLS] = nss_dev->id; + nss_dtls_register_handler(); +#endif + } +#endif + +#ifdef NSS_DRV_MAPT_ENABLE + if (npd->map_t_enabled == NSS_FEATURE_ENABLED) { + nss_top->map_t_handler_id = nss_dev->id; + nss_map_t_register_handler(); + } +#endif + +#ifdef NSS_DRV_TUNIPIP6_ENABLE + if (npd->tunipip6_enabled == NSS_FEATURE_ENABLED) { + nss_top->tunipip6_handler_id = nss_dev->id; + nss_tunipip6_register_handler(); + } +#endif + +#ifdef NSS_DRV_GRE_ENABLE + if (npd->gre_enabled == NSS_FEATURE_ENABLED) { + nss_top->gre_handler_id = nss_dev->id; + nss_gre_register_handler(); + } +#endif + +#ifdef NSS_DRV_GRE_REDIR_ENABLE + if (npd->gre_redir_enabled == NSS_FEATURE_ENABLED) { + nss_top->gre_redir_handler_id = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR] = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_WIFI_HOST_INNER] = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_WIFI_OFFL_INNER] = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_SJACK_INNER] = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_GRE_REDIR_OUTER] = nss_dev->id; + nss_gre_redir_register_handler(); + nss_gre_redir_lag_us_register_handler(); + nss_gre_redir_lag_ds_register_handler(); +#ifdef NSS_DRV_SJACK_ENABLE + nss_top->sjack_handler_id = nss_dev->id; + nss_sjack_register_handler(); +#endif + + } + + if (npd->gre_redir_mark_enabled == NSS_FEATURE_ENABLED) { + nss_top->gre_redir_mark_handler_id = nss_dev->id; + nss_gre_redir_mark_register_handler(); + } +#endif + +#ifdef NSS_DRV_GRE_TUNNEL_ENABLE + if (npd->gre_tunnel_enabled == NSS_FEATURE_ENABLED) { + nss_top->gre_tunnel_handler_id = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL_INNER] = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL_OUTER] = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL_INLINE_INNER] = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL_INLINE_OUTER] = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_GRE_TUNNEL_INNER_EXCEPTION] = nss_dev->id; + } +#endif + +#ifdef NSS_DRV_PORTID_ENABLE + if (npd->portid_enabled == NSS_FEATURE_ENABLED) { + nss_top->portid_handler_id = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_PORTID] = nss_dev->id; + nss_portid_register_handler(); + } +#endif + + if (npd->wifioffload_enabled == NSS_FEATURE_ENABLED) { + nss_top->wifi_handler_id = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_VAP] = nss_dev->id; + nss_wifi_register_handler(); + nss_wifili_register_handler(); + nss_wifi_ext_vdev_register_handler(); + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_WIFILI_INTERNAL] = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_WIFILI_EXTERNAL0] = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_WIFILI_EXTERNAL1] = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_WDS] = nss_dev->id; + + /* + * Register wifi mac database when offload enabled + */ + nss_top->wmdb_handler_id = nss_dev->id; + nss_wifi_mac_db_register_handler(); + + /* + * Initialize wifili thread scheme database + */ + nss_wifili_thread_scheme_db_init(nss_dev->id); + } + +#ifdef NSS_DRV_OAM_ENABLE + if (npd->oam_enabled == NSS_FEATURE_ENABLED) { + nss_top->oam_handler_id = nss_dev->id; + nss_oam_register_handler(); + } +#endif + + if (npd->bridge_enabled == NSS_FEATURE_ENABLED) { + nss_top->bridge_handler_id = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_BRIDGE] = nss_dev->id; + nss_bridge_init(); + } + + if (npd->vlan_enabled == NSS_FEATURE_ENABLED) { + nss_top->vlan_handler_id = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_VLAN] = nss_dev->id; + nss_vlan_register_handler(); + } + +#ifdef NSS_DRV_QVPN_ENABLE +#if defined(NSS_HAL_IPQ807x_SUPPORT) || defined(NSS_HAL_IPQ60XX_SUPPORT) + if (npd->qvpn_enabled == NSS_FEATURE_ENABLED) { + nss_top->qvpn_handler_id = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_QVPN_OUTER] = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_QVPN_INNER] = nss_dev->id; + nss_qvpn_register_handler(); + } +#endif +#endif + +#ifdef NSS_DRV_PVXLAN_ENABLE + if (npd->pvxlan_enabled == NSS_FEATURE_ENABLED) { + nss_top->pvxlan_handler_id = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_PVXLAN_HOST_INNER] = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_PVXLAN_OUTER] = nss_dev->id; + } +#endif + +#ifdef NSS_DRV_RMNET_ENABLE + if (npd->rmnet_rx_enabled == NSS_FEATURE_ENABLED) { + nss_top->rmnet_rx_handler_id = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_RMNET_RX_N2H] = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_RMNET_RX_H2N] = nss_dev->id; + } +#endif + +#ifdef NSS_DRV_IGS_ENABLE + if (npd->igs_enabled == NSS_FEATURE_ENABLED) { + nss_top->igs_handler_id = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_IGS] = nss_dev->id; + nss_info("%d: NSS IGS is enabled", nss_dev->id); + } +#endif + +#ifdef NSS_DRV_CLMAP_ENABLE + if (npd->clmap_enabled == NSS_FEATURE_ENABLED) { + nss_top->clmap_handler_id = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_US] = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_DS] = nss_dev->id; + } +#endif + +#ifdef NSS_DRV_VXLAN_ENABLE + if (npd->vxlan_enabled == NSS_FEATURE_ENABLED) { + nss_top->vxlan_handler_id = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_VXLAN_INNER] = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_VXLAN_OUTER] = nss_dev->id; + nss_vxlan_init(); + } +#endif + +#ifdef NSS_DRV_MATCH_ENABLE + if (npd->match_enabled == NSS_FEATURE_ENABLED) { + nss_top->match_handler_id = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_MATCH] = nss_dev->id; + nss_match_init(); + } +#endif + +#ifdef NSS_DRV_TLS_ENABLE +#if defined(NSS_HAL_IPQ807x_SUPPORT) || defined(NSS_HAL_IPQ60XX_SUPPORT) + if (npd->tls_enabled == NSS_FEATURE_ENABLED) { + nss_top->tls_handler_id = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_TLS_INNER] = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_TLS_OUTER] = nss_dev->id; + nss_tls_register_handler(); + } +#endif +#endif + +#ifdef NSS_DRV_MIRROR_ENABLE + if (npd->mirror_enabled == NSS_FEATURE_ENABLED) { + nss_top->mirror_handler_id = nss_dev->id; + nss_top->dynamic_interface_table[NSS_DYNAMIC_INTERFACE_TYPE_MIRROR] = nss_dev->id; + nss_mirror_register_handler(); + nss_info("%d: NSS mirror is enabled", nss_dev->id); + } + +#endif + + if (nss_ctx->id == 0) { +#if (NSS_FREQ_SCALE_SUPPORT == 1) + nss_freq_register_handler(); + + /* + * Init CPU usage detail + * Note: As of now, ubi cpu usage is supported only for core0 + */ + nss_freq_init_cpu_usage(); +#endif + + nss_lso_rx_register_handler(nss_ctx); + } + + nss_top->frequency_handler_id = nss_dev->id; + + /* + * Initialize decongestion callbacks to NULL + */ + for (i = 0; i < NSS_MAX_CLIENTS; i++) { + nss_ctx->queue_decongestion_callback[i] = 0; + nss_ctx->queue_decongestion_ctx[i] = 0; + } + + spin_lock_init(&(nss_ctx->decongest_cb_lock)); + nss_ctx->magic = NSS_CTX_MAGIC; + + nss_info("%px: Reseting NSS core %d now", nss_ctx, nss_ctx->id); + + /* + * Enable clocks and bring NSS core out of reset + */ + err = nss_top->hal_ops->core_reset(nss_dev, nss_ctx->nmap, nss_ctx->load, nss_top->clk_src); + if (err) { + goto err_register_irq; + } + + /* + * Initialize max buffer size for NSS core + */ + nss_ctx->max_buf_size = NSS_NBUF_PAYLOAD_SIZE; + + /* + * Initialize S/G status pointers to NULL + */ + for (i = 0; i < NSS_N2H_DESC_RING_NUM; i++) { + nss_ctx->n2h_desc_ring[i].head = NULL; + nss_ctx->n2h_desc_ring[i].tail = NULL; + nss_ctx->n2h_desc_ring[i].jumbo_start = NULL; + } + + /* + * Enable interrupts for NSS core. + */ + for (i = 0; i < npd->num_irq; i++) { + nss_hal_enable_interrupt(nss_ctx, nss_ctx->int_ctx[i].shift_factor, NSS_HAL_SUPPORTED_INTERRUPTS); + } + + nss_info("%px: All resources initialized and nss core%d has been brought out of reset", nss_ctx, nss_dev->id); + goto out; + +err_register_irq: + for (i = 0; i < npd->num_irq; i++) { + nss_hal_clean_up_irq(&nss_ctx->int_ctx[i]); + } + +err_init: + if (nss_dev->dev.of_node) { + if (npd->nmap) { + iounmap(npd->nmap); + } + + if (npd->vmap) { + iounmap(npd->vmap); + } + } + +out: + if (nss_dev->dev.of_node) { + devm_kfree(&nss_dev->dev, npd); + } + return err; +} + +/* + * nss_hal_remove() + * HLOS device remove callback + */ +int nss_hal_remove(struct platform_device *nss_dev) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[nss_dev->id]; + int i; + + /* + * Clean up debugfs + */ + nss_stats_clean(); + + /* + * Clear up the resources associated with the interrupt + */ + for (i = 0; i < nss_ctx->num_irq; i++) { + nss_hal_disable_interrupt(nss_ctx, nss_ctx->int_ctx[i].shift_factor, + NSS_HAL_SUPPORTED_INTERRUPTS); + nss_hal_clean_up_irq(&nss_ctx->int_ctx[i]); + } + + /* + * nss-drv is exiting, unregister and restore host data plane + */ + nss_top->data_plane_ops->data_plane_unregister(); + +#if (NSS_FABRIC_SCALING_SUPPORT == 1) + fab_scaling_unregister(nss_core0_clk); +#endif + + if (nss_dev->dev.of_node) { + if (nss_ctx->nmap) { + iounmap(nss_ctx->nmap); + nss_ctx->nmap = 0; + } + + if (nss_ctx->vmap) { + iounmap(nss_ctx->vmap); + nss_ctx->vmap = 0; + } + } + + nss_info("%px: All resources freed for nss core%d", nss_ctx, nss_dev->id); + return 0; +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_hlos_if.h b/feeds/ipq807x/qca-nss-drv/src/nss_hlos_if.h new file mode 100644 index 000000000..d8ffbe332 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_hlos_if.h @@ -0,0 +1,377 @@ +/* + ************************************************************************** + * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_hlos_if.h + * NSS to HLOS interface definitions. + */ + +#ifndef __NSS_HLOS_IF_H +#define __NSS_HLOS_IF_H + +#define NSS_MIN_NUM_CONN 256 /* MIN Connection shared between IPv4 and IPv6 */ +#define NSS_FW_DEFAULT_NUM_CONN 1024 /* Firmware default number of connections for IPv4 and IPv6 */ +#define NSS_NUM_CONN_QUANTA_MASK (1024 - 1) /* Quanta of number of connections 1024 */ +#define NSS_CONN_CFG_TIMEOUT 6000 /* 6 sec timeout for connection cfg message */ + +/* + * The following definitions sets the maximum number of connections + * based on the type of memory profile that the system is operating with + */ +#if defined (NSS_MEM_PROFILE_LOW) +#define NSS_DEFAULT_NUM_CONN 512 /* Default number of connections for IPv4 and IPv6 each, for low memory profile */ +#define NSS_MAX_TOTAL_NUM_CONN_IPV4_IPV6 1024 /* MAX Connection shared between IPv4 and IPv6 for low memory profile */ +#define NSS_LOW_MEM_EMPTY_POOL_BUF_SZ 4096 /* Default empty buffer pool size for low profile */ +#elif defined (NSS_MEM_PROFILE_MEDIUM) +#define NSS_DEFAULT_NUM_CONN 2048 /* Default number of connections for IPv4 and IPv6 each, for medium memory profile */ +#define NSS_MAX_TOTAL_NUM_CONN_IPV4_IPV6 4096 /* MAX Connection shared between IPv4 and IPv6 for medium memory profile */ +#else +#define NSS_DEFAULT_NUM_CONN 4096 /* Default number of connections for each IPv4 and IPv6 */ +#define NSS_MAX_TOTAL_NUM_CONN_IPV4_IPV6 8192 /* MAX Connection shared between IPv4 and IPv6 */ +#endif + +#if defined(NSS_SKB_FIXED_SIZE_2K) && !defined(__LP64__) +#define NSS_EMPTY_BUFFER_SIZE 1792 /* Default buffer size for reduced memory profiles. */ +#define NSS_FIXED_BUFFER_SIZE /* For low memory profiles, maximum buffer size/MTU is fixed */ +#else +#define NSS_EMPTY_BUFFER_SIZE 1984 /* Default buffer size for regular memory profiles. */ +#undef NSS_FIXED_BUFFER_SIZE +#endif + +enum { + NSS_SUCCESS = 0, + NSS_FAILURE = 1, +}; + +/* + * Request/Response types + */ +enum nss_if_metadata_types { + NSS_TX_METADATA_TYPE_INTERFACE_OPEN, + NSS_TX_METADATA_TYPE_INTERFACE_CLOSE, + NSS_TX_METADATA_TYPE_INTERFACE_LINK_STATE_NOTIFY, + NSS_TX_METADATA_TYPE_INTERFACE_MTU_CHANGE, + NSS_TX_METADATA_TYPE_INTERFACE_MAC_ADDR_SET, + NSS_TX_METADATA_TYPE_INTERFACE_MSS_SET, + NSS_RX_METADATA_TYPE_INTERFACE_STATS_SYNC, + NSS_METADATA_TYPE_INTERFACE_MAX, +}; + +/* + * General statistics messages + */ + +/* + * IPv4 reasm node stats + */ +struct nss_ipv4_reasm_stats_sync { + struct nss_cmn_node_stats node_stats; + /* Common node stats for ipv4_reasm */ + uint32_t ipv4_reasm_evictions; + uint32_t ipv4_reasm_alloc_fails; + uint32_t ipv4_reasm_timeouts; +}; + +/* + * IPv4 reasm message types + */ +enum nss_ipv4_reasm_message_types { + NSS_IPV4_REASM_STATS_SYNC_MSG, +}; + +/* + * IPv4 reassembly message structure + */ +struct nss_ipv4_reasm_msg { + struct nss_cmn_msg cm; + union { + struct nss_ipv4_reasm_stats_sync stats_sync; + } msg; +}; + +/* + * IPv6 reasm node stats + */ +struct nss_ipv6_reasm_stats_sync { + struct nss_cmn_node_stats node_stats; + /* Common node stats for ipv6_reasm */ + uint32_t ipv6_reasm_alloc_fails; + uint32_t ipv6_reasm_timeouts; + uint32_t ipv6_reasm_discards; +}; + +/* + * IPv6 reasm message types + */ +enum nss_ipv6_reasm_message_types { + NSS_IPV6_REASM_STATS_SYNC_MSG, +}; + +/* + * IPv6 reassembly message structure + */ +struct nss_ipv6_reasm_msg { + struct nss_cmn_msg cm; + union { + struct nss_ipv6_reasm_stats_sync stats_sync; + } msg; +}; + +/* + * Generic interface messages + */ +enum nss_generic_metadata_types { + NSS_TX_METADATA_TYPE_GENERIC_IF_PARAMS, + NSS_METADATA_TYPE_GENERIC_IF_MAX +}; + +/* + * Interface params command + */ +struct nss_generic_if_params { + uint8_t buf[1]; /* Buffer */ +}; + +/* + * Message structure to send/receive ipsec messages + */ +struct nss_generic_msg { + struct nss_cmn_msg cm; /* Message Header */ + union { + struct nss_generic_if_params rule; /* Message: generic rule */ + } msg; +}; + +/* + * NSS frequency scaling messages + */ +enum nss_freq_stats_metadata_types { + COREFREQ_METADATA_TYPE_ERROR, + COREFREQ_METADATA_TYPE_RX_FREQ_CHANGE, + COREFREQ_METADATA_TYPE_TX_FREQ_ACK, + COREFREQ_METADATA_TYPE_TX_CORE_STATS, + COREFREQ_METADATA_TYPE_MAX, +}; + + /* + * Types of TX metadata -- legacy code needs to be removed + */ +enum nss_tx_metadata_types { + NSS_TX_METADATA_TYPE_LEGACY_0, + NSS_TX_METADATA_TYPE_NSS_FREQ_CHANGE, + NSS_TX_METADATA_TYPE_SHAPER_CONFIGURE, +}; + +/* + * The NSS freq start or stop strcture + */ +struct nss_freq_msg { + /* Request */ + uint32_t frequency; + uint32_t start_or_end; + uint32_t stats_enable; + + /* Response */ + uint32_t freq_current; + int32_t ack; +}; + +/* + * NSS core stats + */ +struct nss_core_stats { + uint32_t inst_cnt_total; +}; + +/* + * Message structure to send/receive NSS Freq commands + */ +struct nss_corefreq_msg { + struct nss_cmn_msg cm; /* Message Header */ + union { + struct nss_freq_msg nfc; /* Message: freq stats */ + struct nss_core_stats ncs; /* Message: NSS stats sync */ + } msg; +}; + +/* + * H2N Buffer Types + */ +#define H2N_BUFFER_EMPTY 0 +#define H2N_PAGED_BUFFER_EMPTY 1 +#define H2N_BUFFER_PACKET 2 +#define H2N_BUFFER_CTRL 4 +#define H2N_BUFFER_NATIVE_WIFI 8 +#define H2N_BUFFER_SHAPER_BOUNCE_INTERFACE 9 +#define H2N_BUFFER_SHAPER_BOUNCE_BRIDGE 10 +#define H2N_BUFFER_RATE_TEST 14 +#define H2N_BUFFER_MAX 16 + +/* + * H2N Bit Flag Definitions + */ +#define H2N_BIT_FLAG_GEN_IPV4_IP_CHECKSUM 0x0001 +#define H2N_BIT_FLAG_GEN_IP_TRANSPORT_CHECKSUM 0x0002 +#define H2N_BIT_FLAG_FIRST_SEGMENT 0x0004 +#define H2N_BIT_FLAG_LAST_SEGMENT 0x0008 + +#define H2N_BIT_FLAG_GEN_IP_TRANSPORT_CHECKSUM_NONE 0x0010 +#define H2N_BIT_FLAG_TX_TS_REQUIRED 0x0040 +#define H2N_BIT_FLAG_DISCARD 0x0080 +#define H2N_BIT_FLAG_SEGMENTATION_ENABLE 0x0100 + +#define H2N_BIT_FLAG_VIRTUAL_BUFFER 0x2000 +#define H2N_BIT_FLAG_BUFFER_REUSABLE 0x8000 + +/* + * HLOS to NSS descriptor structure. + */ +struct h2n_descriptor { + uint32_t interface_num; /* Interface number to which the buffer is to be sent (where appropriate) */ + uint32_t buffer; /* Physical buffer address. This is the address of the start of the usable buffer being provided by the HLOS */ + uint32_t qos_tag; /* QoS tag information of the buffer (where appropriate) */ + uint16_t buffer_len; /* Length of the buffer (in bytes) */ + uint16_t payload_len; /* Length of the active payload of the buffer (in bytes) */ + uint16_t mss; /* MSS to be used with TSO/UFO */ + uint16_t payload_offs; /* Offset from the start of the buffer to the start of the payload (in bytes) */ + uint16_t bit_flags; /* Bit flags associated with the buffer */ + uint8_t buffer_type; /* Type of buffer */ + uint8_t reserved; /* Reserved for future use */ + nss_ptr_t opaque; /* 32 or 64-bit value provided by the HLOS to associate with the buffer. The cookie has no meaning to the NSS */ +#ifndef __LP64__ + uint32_t padding; /* Pad to fit 64bits, do not reuse */ +#endif +}; + +/* + * N2H Buffer Types + */ +#define N2H_BUFFER_EMPTY 1 +#define N2H_BUFFER_PACKET 3 +#define N2H_BUFFER_COMMAND_RESP 5 +#define N2H_BUFFER_STATUS 6 +#define N2H_BUFFER_CRYPTO_RESP 8 +#define N2H_BUFFER_PACKET_VIRTUAL 10 +#define N2H_BUFFER_SHAPER_BOUNCED_INTERFACE 11 +#define N2H_BUFFER_SHAPER_BOUNCED_BRIDGE 12 +#define N2H_BUFFER_PACKET_EXT 13 +#define N2H_BUFFER_RATE_TEST 14 +#define N2H_BUFFER_MAX 16 + +/* + * Command Response Types + */ +#define N2H_COMMAND_RESP_OK 0 +#define N2H_COMMAND_RESP_BUFFER_TOO_SMALL 1 +#define N2H_COMMAND_RESP_BUFFER_NOT_WRITEABLE 2 +#define N2H_COMMAND_RESP_UNSUPPORTED_COMMAND 3 +#define N2H_COMMAND_RESP_INVALID_PARAMETERS 4 +#define N2H_COMMAND_RESP_INACTIVE_SUBSYSTEM 5 + +/* + * N2H Bit Flag Definitions + */ +#define N2H_BIT_FLAG_IPV4_IP_CHECKSUM_VALID 0x0001 +#define N2H_BIT_FLAG_IP_TRANSPORT_CHECKSUM_VALID 0x0002 +#define N2H_BIT_FLAG_FIRST_SEGMENT 0x0004 +#define N2H_BIT_FLAG_LAST_SEGMENT 0x0008 +#define N2H_BIT_FLAG_INGRESS_SHAPED 0x0010 + +/* + * NSS to HLOS descriptor structure + */ +struct n2h_descriptor { + uint32_t interface_num; /* Interface number to which the buffer is to be sent (where appropriate) */ + uint32_t buffer; /* Physical buffer address. This is the address of the start of the usable buffer being provided by the HLOS */ + uint16_t buffer_len; /* Length of the buffer (in bytes) */ + uint16_t payload_len; /* Length of the active payload of the buffer (in bytes) */ + uint16_t payload_offs; /* Offset from the start of the buffer to the start of the payload (in bytes) */ + uint16_t bit_flags; /* Bit flags associated with the buffer */ + uint8_t buffer_type; /* Type of buffer */ + uint8_t response_type; /* Response type if the buffer is a command response */ + uint8_t pri; /* Packet priority */ + uint8_t service_code; /* Service code */ + uint32_t reserved; /* Reserved for future use */ + nss_ptr_t opaque; /* 32 or 64-bit value provided by the HLOS to associate with the buffer. The cookie has no meaning to the NSS */ +#ifndef __LP64__ + uint32_t padding; /* Pad to fit 64 bits, do not reuse */ +#endif +}; + +/* + * Device Memory Map Definitions + */ +#define DEV_MAGIC 0x4e52522e +#define DEV_INTERFACE_VERSION 1 +#define DEV_DESCRIPTORS 256 /* Do we need it here? */ + +/** + * H2N descriptor METADATA + */ +struct h2n_desc_if_meta { + uint32_t desc_addr; + uint16_t size; + uint16_t padding; +}; + +/** + * H2N descriptor ring + */ +struct h2n_desc_if_instance { + struct h2n_descriptor *desc; + uint16_t size; /* Size in entries of the H2N0 descriptor ring */ +}; + +/** + * N2H descriptor METADATA + */ +struct n2h_desc_if_meta { + uint32_t desc_addr; + uint16_t size; + uint16_t padding; +}; + +/** + * N2H descriptor ring + */ +struct n2h_desc_if_instance { + struct n2h_descriptor *desc; + uint16_t size; /* Size in entries of the H2N0 descriptor ring */ +}; + +/** + * NSS virtual interface map + */ +struct nss_if_mem_map { + struct h2n_desc_if_meta h2n_desc_if[16];/* Base address of H2N0 descriptor ring */ + struct n2h_desc_if_meta n2h_desc_if[15];/* Base address of N2H0 descriptor ring */ + uint32_t magic; /* Magic value used to identify NSS implementations (must be 0x4e52522e) */ + uint16_t if_version; /* Interface version number (must be 1 for this version) */ + uint8_t h2n_rings; /* Number of descriptor rings in the H2N direction */ + uint8_t n2h_rings; /* Number of descriptor rings in the N2H direction */ + uint32_t h2n_nss_index[16]; + /* Index number for the next descriptor that will be read by the NSS in the H2N0 descriptor ring (NSS owned) */ + volatile uint32_t n2h_nss_index[15]; + /* Index number for the next descriptor that will be written by the NSS in the N2H0 descriptor ring (NSS owned) */ + uint8_t num_phys_ports; + uint8_t reserved1[3]; /* Reserved for future use */ + uint32_t h2n_hlos_index[16]; + /* Index number for the next descriptor that will be written by the HLOS in the H2N0 descriptor ring (HLOS owned) */ + volatile uint32_t n2h_hlos_index[15]; + /* Index number for the next descriptor that will be read by the HLOS in the N2H0 descriptor ring (HLOS owned) */ + uint32_t reserved; /* Reserved for future use */ +}; +#endif /* __NSS_HLOS_IF_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_if.c b/feeds/ipq807x/qca-nss-drv/src/nss_if.c new file mode 100644 index 000000000..9747fb73b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_if.c @@ -0,0 +1,270 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2016, 2018-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_if.c + * NSS base interfaces + */ + +#include "nss_tx_rx_common.h" +#include "nss_if_log.h" + +/* + * nss_if_pvt + * NSS private structure to handle the completion of NSS -> HLOS messages. + */ +static struct nss_if_pvt { + struct semaphore sem; + struct completion complete; + int response; +} nss_if; + +static bool nss_if_sem_init_done; + +/* + * nss_if_callback + * Callback to handle the completion of NSS ->HLOS messages. + */ +static void nss_if_callback(void *app_data, struct nss_if_msg *nim) +{ + if (nim->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("nss_if Error response %d\n", nim->cm.response); + nss_if.response = NSS_TX_FAILURE; + complete(&nss_if.complete); + return; + } + + nss_if.response = NSS_TX_SUCCESS; + complete(&nss_if.complete); +} + +/* + * nss_if_msg_sync() + * Send a message to an interface and wait for the response. + */ +nss_tx_status_t nss_if_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_if_msg *nim) +{ + nss_tx_status_t status; + int ret = 0; + + if (!nss_if_sem_init_done) { + sema_init(&nss_if.sem, 1); + init_completion(&nss_if.complete); + nss_if_sem_init_done = 1; + } + + down(&nss_if.sem); + + status = nss_if_tx_msg(nss_ctx, nim); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: nss_if_msg failed\n", nss_ctx); + up(&nss_if.sem); + return status; + } + + ret = wait_for_completion_timeout(&nss_if.complete, msecs_to_jiffies(NSS_IF_TX_TIMEOUT)); + + if (!ret) { + nss_warning("%px: nss_if tx failed due to timeout\n", nss_ctx); + nss_if.response = NSS_TX_FAILURE; + } + + status = nss_if.response; + up(&nss_if.sem); + + return status; +} +EXPORT_SYMBOL(nss_if_msg_sync); + +/* + * nss_if_msg_handler() + * Handle NSS -> HLOS messages for base class interfaces + */ +void nss_if_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, + __attribute__((unused))void *app_data) +{ + struct nss_if_msg *nim = (struct nss_if_msg *)ncm; + nss_if_msg_callback_t cb; + + /* + * We only support base class messages with this interface + */ + if (ncm->type > NSS_IF_MAX_MSG_TYPES) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return; + } + + if (!nss_is_dynamic_interface(ncm->interface) && + !((ncm->interface >= NSS_PHYSICAL_IF_START) && (ncm->interface < NSS_VIRTUAL_IF_START))) { + nss_warning("%px: interface %d not in physical or dynamic if range\n", nss_ctx, ncm->interface); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_if_msg)) { + nss_warning("%px: message length too big: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Trace messages. + */ + nss_if_log_rx_msg(nim); + + /* + * Do we have a callback? + */ + if (!ncm->cb) { + return; + } + + /* + * Callback + */ + cb = (nss_if_msg_callback_t)ncm->cb; + cb((void *)ncm->app_data, nim); +} + +/* + * nss_if_tx_buf() + * Send packet to interface owned by NSS + */ +nss_tx_status_t nss_if_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf, uint32_t if_num) +{ + nss_trace("%px: If Tx packet, id:%d, data=%px", nss_ctx, if_num, os_buf->data); + + if (!nss_is_dynamic_interface(if_num) && + !((if_num >= NSS_PHYSICAL_IF_START) && (if_num < NSS_VIRTUAL_IF_START))) { + nss_warning("%px: interface %d not in physical or dynamic if range\n", nss_ctx, if_num); + return NSS_TX_FAILURE_BAD_PARAM; + } + + return nss_core_send_packet(nss_ctx, os_buf, if_num, H2N_BIT_FLAG_BUFFER_REUSABLE); +} + +/* + * nss_if_tx_msg() + * Transmit a message to the specific interface on this core. + */ +nss_tx_status_t nss_if_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_if_msg *nim) +{ + struct nss_cmn_msg *ncm = &nim->cm; + struct net_device *dev; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + /* + * Sanity check the message + */ + if (ncm->type >= NSS_IF_MAX_MSG_TYPES) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + /* + * Sanity check the message for valid interfaces. + */ + if (ncm->interface < NSS_PHYSICAL_IF_START || + ncm->interface >= NSS_MAX_NET_INTERFACES ) { + nss_warning("%px: Tx request for invalid interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE_BAD_PARAM; + } + + /* + * Trace messages. + */ + nss_if_log_tx_msg(nim); + + dev = nss_ctx->subsys_dp_register[ncm->interface].ndev; + if (!dev) { + nss_warning("%px: Unregister interface %d: no context", nss_ctx, ncm->interface); + return NSS_TX_FAILURE_BAD_PARAM; + } + + return nss_core_send_cmd(nss_ctx, nim, sizeof(*nim), NSS_NBUF_PAYLOAD_SIZE); +} + +/* + * nss_if_register() + * Primary registration for receiving data and msgs from an interface. + */ +struct nss_ctx_instance *nss_if_register(uint32_t if_num, + nss_if_rx_callback_t rx_callback, + nss_if_msg_callback_t msg_callback, + struct net_device *if_ctx) +{ + return NULL; +} + +/* + * nss_if_unregister() + * Unregisteer the callback for this interface + */ +void nss_if_unregister(uint32_t if_num) +{ +} + +/* + * nss_if_reset_nexthop() + * De-configures the nexthop for an interface + */ +nss_tx_status_t nss_if_reset_nexthop(struct nss_ctx_instance *nss_ctx, uint32_t if_num) +{ + struct nss_if_msg nim; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + nss_trace("Resetting Nexthop. nss_ctx: %px ifnum: %u", nss_ctx, if_num); + + nss_cmn_msg_init(&nim.cm, if_num, NSS_IF_RESET_NEXTHOP, 0, nss_if_callback, NULL); + + return nss_if_msg_sync(nss_ctx, &nim); +} +EXPORT_SYMBOL(nss_if_reset_nexthop); + +/* + * nss_if_set_nexthop() + * Configures the nexthop for an interface + */ +nss_tx_status_t nss_if_set_nexthop(struct nss_ctx_instance *nss_ctx, uint32_t if_num, uint32_t nexthop) +{ + struct nss_if_msg nim; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (nexthop >= NSS_MAX_NET_INTERFACES) { + nss_warning("%px: Invalid nexthop interface number: %d", nss_ctx, nexthop); + return NSS_TX_FAILURE_BAD_PARAM; + } + + nss_trace("%px: NSS If nexthop will be set to %d, id:%d\n", nss_ctx, nexthop, if_num); + + nss_cmn_msg_init(&nim.cm, if_num, NSS_IF_SET_NEXTHOP, + sizeof(struct nss_if_set_nexthop), nss_if_callback, NULL); + + nim.msg.set_nexthop.nexthop = nexthop; + + return nss_if_msg_sync(nss_ctx, &nim); +} +EXPORT_SYMBOL(nss_if_set_nexthop); + +EXPORT_SYMBOL(nss_if_tx_msg); +EXPORT_SYMBOL(nss_if_register); +EXPORT_SYMBOL(nss_if_unregister); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_if_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_if_log.c new file mode 100644 index 000000000..a551a4205 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_if_log.c @@ -0,0 +1,429 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_if_log.c + * NSS Interface logger file. + */ + +#include "nss_core.h" + +/* + * nss_if_log_message_types_str + * NSS interface rule message strings + */ +static int8_t *nss_if_log_message_types_str[NSS_IF_MAX_MSG_TYPES] __maybe_unused = { + "NSS interface Open message", + "NSS interface close message", + "NSS interface link state notify message", + "NSS interface MTU change message", + "NSS interface MAC address set message", + "NSS interface stats message", + "NSS interface ishaper assign message", + "NSS interface bshaper assign message", + "NSS interface ishaper unassign message", + "NSS interface bshaper unassign message", + "NSS interface ishaper config message", + "NSS interface bshaper config message", + "NSS interface pause on off message", + "NSS interface VSI assign message", + "NSS interface VSI unassign message", + "NSS interface set next hop message", + "NSS interface set IGS node message", + "NSS interface clear IGS node message", + "NSS interface reset next hop message", +}; + +/* + * nss_if_log_error_response_types_str + * Strings for error types for NSS interface messages + */ +static int8_t *nss_if_log_error_response_types_str[NSS_IF_ERROR_TYPE_MAX] __maybe_unused = { + "No Ishapers", + "No Bshapers", + "No Ishaper", + "No Bshaper", + "No Old Ishaper", + "No Old Bshaper", + "Ishaper config failed", + "Bshaper config failed", + "Unknown error", + "Interface open error", + "Interface invalid MTU error", + "Invalid MAC address error", + "VSI no match error", + "VSI reassign error", + "Invalid VSI error", + "Max error", +}; + +/* + * nss_if_log_rule_open() + * Log NSS open interface message. + */ +static void nss_if_log_rule_open(struct nss_if_msg *nim) +{ + struct nss_if_open *niom __maybe_unused = &nim->msg.open; + nss_trace("%px: NSS open interface message \n" + "tx_desc_ring: %X\n" + "rx_desc_ring: %X\n" + "rx_forward_if: %u\n" + "alignment_mode: %u\n", + nim, + niom->tx_desc_ring, + niom->rx_desc_ring, + niom->rx_forward_if, + niom->alignment_mode); +} + +/* + * nss_if_log_rule_close() + * Log NSS close interface message. + */ +static void nss_if_log_rule_close(struct nss_if_msg *nim) +{ + nss_trace("%px: NSS close interface message \n", nim); +} + +/* + * nss_if_log_rule_link_state_notify() + * Log NSS interface link state notify message. + */ +static void nss_if_log_rule_link_state_notify(struct nss_if_msg *nim) +{ + struct nss_if_link_state_notify *nilstm __maybe_unused = &nim->msg.link_state_notify; + nss_trace("%px: NSS interface link state notify interface message \n" + "state: %u\n", + nim, + nilstm->state); +} + +/* + * nss_if_log_rule_mtu_change() + * Log NSS interface MTU change message. + */ +static void nss_if_log_rule_mtu_change(struct nss_if_msg *nim) +{ + struct nss_if_mtu_change *nimcm __maybe_unused = &nim->msg.mtu_change; + nss_trace("%px: NSS interface MTU change message \n" + "min_buf_size: %u\n", + nim, + nimcm->min_buf_size); +} + +/* + * nss_if_log_rule_mac_addr_set() + * Log NSS interface MAC address set message. + */ +static void nss_if_log_rule_mac_addr_set(struct nss_if_msg *nim) +{ + struct nss_if_mac_address_set *nimasm __maybe_unused = &nim->msg.mac_address_set; + nss_trace("%px: NSS interface MAC address set message \n" + "MAC address: %X:%X:%X:%X:%X:%X\n", + nim, + nimasm->mac_addr[0], nimasm->mac_addr[1], nimasm->mac_addr[2], + nimasm->mac_addr[3], nimasm->mac_addr[4], nimasm->mac_addr[5]); +} + +/* + * nss_if_log_rule_stats() + * Log NSS interface stats message. + */ +static void nss_if_log_rule_stats(struct nss_if_msg *nim) +{ + uint16_t i; + struct nss_cmn_node_stats *nism __maybe_unused = &nim->msg.stats; + + nss_trace("%px: NSS interface stats message \n" + "rx_packets: %u\n" + "rx_bytes: %u\n" + "tx_packets: %u\n" + "tx_bytes: %u\n", + nim, + nism->rx_packets, + nism->rx_bytes, + nism->tx_packets, + nism->tx_bytes); + + for(i=0; i < NSS_MAX_NUM_PRI; i++) + { + nss_trace("rx_dropped[%u]: %u\n", i, nism->rx_dropped[i]); + } +} + +/* + * nss_if_log_rule_shaper_assign() + * Log NSS interface shaper assignment message. + */ +static void nss_if_log_rule_shaper_assign(struct nss_if_msg *nim) +{ + struct nss_if_shaper_assign *shaper_assign_msg __maybe_unused = &nim->msg.shaper_assign; + nss_trace("%px: NSS interface shaper assign message \n" + "shaper_id: %u\n" + "new_shaper_id: %u\n", + nim, + shaper_assign_msg->shaper_id, + shaper_assign_msg->new_shaper_id); +} + +/* + * nss_if_log_rule_shaper_unassign() + * Log NSS interface shaper unassignment message. + */ +static void nss_if_log_rule_shaper_unassign(struct nss_if_msg *nim) +{ + struct nss_if_shaper_unassign *shaper_unassign_msg __maybe_unused = &nim->msg.shaper_unassign; + nss_trace("%px: NSS interface shaper unassign message \n" + "shaper_id: %u\n", + nim, + shaper_unassign_msg->shaper_id); +} + +/* + * nss_if_log_rule_shaper_config() + * Log NSS interface shaper configuration message. + */ +static void nss_if_log_rule_shaper_config(struct nss_if_msg *nim) +{ + struct nss_if_shaper_configure *shaper_configure_msg __maybe_unused = &nim->msg.shaper_configure; + nss_trace("%px: NSS interface shaper configuration message \n" + "request_type: %u\n" + "response_type: %u\n", + nim, + shaper_configure_msg->config.request_type, + shaper_configure_msg->config.response_type); +} + +/* + * nss_if_log_rule_pause_on_off() + * Log NSS interface pause on off message. + */ +static void nss_if_log_rule_pause_on_off(struct nss_if_msg *nim) +{ + struct nss_if_pause_on_off *pause_on_off_msg __maybe_unused = &nim->msg.pause_on_off; + nss_trace("%px: NSS interface pause ON/OFF message \n" + "pause_on: %u\n", + nim, + pause_on_off_msg->pause_on); +} + +/* + * nss_if_log_rule_vsi_assign() + * Log NSS interface VSI assignment message. + */ +static void nss_if_log_rule_vsi_assign(struct nss_if_msg *nim) +{ + struct nss_if_vsi_assign *vsi_assign_msg __maybe_unused = &nim->msg.vsi_assign; + nss_trace("%px: NSS interface VSI assignment message \n" + "VSI: %u\n", + nim, + vsi_assign_msg->vsi); +} + +/* + * nss_if_log_rule_vsi_unassign() + * Log NSS interface VSI unassignment message. + */ +static void nss_if_log_rule_vsi_unassign(struct nss_if_msg *nim) +{ + struct nss_if_vsi_unassign *vsi_unassign_msg __maybe_unused = &nim->msg.vsi_unassign; + nss_trace("%px: NSS interface VSI unassignment message \n" + "VSI: %u\n", + nim, + vsi_unassign_msg->vsi); +} + +/* + * nss_if_log_rule_set_nexthop() + * Log NSS interface set nexthop message. + */ +static void nss_if_log_rule_set_nexthop(struct nss_if_msg *nim) +{ + struct nss_if_set_nexthop *nisn __maybe_unused = &nim->msg.set_nexthop; + nss_trace("%px: NSS interface set nethop message \n" + "Nexthop: %u\n", + nim, + nisn->nexthop); +} + +/* + * nss_if_log_rule_set_igs_node() + * Log NSS interface set IGS node message. + */ +static void nss_if_log_rule_set_igs_node(struct nss_if_msg *nim) +{ + struct nss_if_igs_config *igs_config_msg __maybe_unused = &nim->msg.config_igs; + nss_trace("%px: NSS interface set IGS node message \n" + "igs_num: %d\n", + nim, + igs_config_msg->igs_num); +} + +/* + * nss_if_log_rule_clear_igs_node() + * Log NSS interface clear IGS node message. + */ +static void nss_if_log_rule_clear_igs_node(struct nss_if_msg *nim) +{ + struct nss_if_igs_config *igs_config_msg __maybe_unused = &nim->msg.config_igs; + nss_trace("%px: NSS interface clear IGS node message \n" + "igs_num: %d\n", + nim, + igs_config_msg->igs_num); +} + +/* + * nss_if_log_rule_reset_nexthop() + * Log NSS interface reset nexthop message. + */ +static void nss_if_log_rule_reset_nexthop(struct nss_if_msg *nim) +{ + nss_trace("%px: NSS interface reset nexthop message \n", nim); +} + +/* + * nss_if_log_verbose() + * Log message contents. + */ +static void nss_if_log_verbose(struct nss_if_msg *nim) +{ + nss_trace("NSS interface number: %u\n", nim->cm.interface); + + switch (nim->cm.type) { + case NSS_IF_OPEN: + nss_if_log_rule_open(nim); + break; + + case NSS_IF_CLOSE: + nss_if_log_rule_close(nim); + break; + + case NSS_IF_LINK_STATE_NOTIFY: + nss_if_log_rule_link_state_notify(nim); + break; + + case NSS_IF_MTU_CHANGE: + nss_if_log_rule_mtu_change(nim); + break; + + case NSS_IF_MAC_ADDR_SET: + nss_if_log_rule_mac_addr_set(nim); + break; + + case NSS_IF_STATS: + nss_if_log_rule_stats(nim); + break; + + case NSS_IF_ISHAPER_ASSIGN: + case NSS_IF_BSHAPER_ASSIGN: + nss_if_log_rule_shaper_assign(nim); + break; + + case NSS_IF_ISHAPER_UNASSIGN: + case NSS_IF_BSHAPER_UNASSIGN: + nss_if_log_rule_shaper_unassign(nim); + break; + + case NSS_IF_ISHAPER_CONFIG: + case NSS_IF_BSHAPER_CONFIG: + nss_if_log_rule_shaper_config(nim); + break; + + case NSS_IF_PAUSE_ON_OFF: + nss_if_log_rule_pause_on_off(nim); + break; + + case NSS_IF_VSI_ASSIGN: + nss_if_log_rule_vsi_assign(nim); + break; + + case NSS_IF_VSI_UNASSIGN: + nss_if_log_rule_vsi_unassign(nim); + break; + + case NSS_IF_SET_NEXTHOP: + nss_if_log_rule_set_nexthop(nim); + break; + + case NSS_IF_SET_IGS_NODE: + nss_if_log_rule_set_igs_node(nim); + break; + + case NSS_IF_CLEAR_IGS_NODE: + nss_if_log_rule_clear_igs_node(nim); + break; + + case NSS_IF_RESET_NEXTHOP: + nss_if_log_rule_reset_nexthop(nim); + break; + + default: + nss_trace("%px: Invalid message type\n", nim); + break; + } +} + +/* + * nss_if_log_rx_msg() + * Log messages received from FW. + */ +void nss_if_log_rx_msg(struct nss_if_msg *nim) +{ + if (nim->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_info("%px: Invalid response\n", nim); + return; + } + + if (nim->cm.response == NSS_CMN_RESPONSE_NOTIFY || (nim->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", nim, nim->cm.type, + nss_if_log_message_types_str[nim->cm.type], + nim->cm.response, nss_cmn_response_str[nim->cm.response]); + goto verbose; + } + + if (nim->cm.error >= NSS_IF_ERROR_TYPE_MAX) { + nss_info("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + nim, nim->cm.type, nss_if_log_message_types_str[nim->cm.type], + nim->cm.response, nss_cmn_response_str[nim->cm.response], + nim->cm.error); + goto verbose; + } + + nss_info("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + nim, nim->cm.type, nss_if_log_message_types_str[nim->cm.type], + nim->cm.response, nss_cmn_response_str[nim->cm.response], + nim->cm.error, nss_if_log_error_response_types_str[nim->cm.error]); + +verbose: + nss_if_log_verbose(nim); +} + +/* + * nss_if_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_if_log_tx_msg(struct nss_if_msg *nim) +{ + if (nim->cm.type >= NSS_IF_MAX_MSG_TYPES) { + nss_info("%px: Invalid message type\n", nim); + return; + } + + nss_info("%px: type[%d]:%s\n", nim, nim->cm.type, nss_if_log_message_types_str[nim->cm.type]); + nss_if_log_verbose(nim); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_if_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_if_log.h new file mode 100644 index 000000000..0f2a7d27b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_if_log.h @@ -0,0 +1,40 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_IF_LOG_H +#define __NSS_IF_LOG_H + +/* + * nss_if_log.h + * NSS Interface header file. + */ + +/* + * nss_if_log_tx_msg + * Logs an NSS interface message that is sent to the NSS firmware. + */ +void nss_if_log_tx_msg(struct nss_if_msg *nim); + +/* + * nss_if_log_rx_msg + * Logs an NSS interface message that is received from the NSS firmware. + */ +void nss_if_log_rx_msg(struct nss_if_msg *nim); + + +#endif /* __NSS_IF_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_igs.c b/feeds/ipq807x/qca-nss-drv/src/nss_igs.c new file mode 100644 index 000000000..8153a4653 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_igs.c @@ -0,0 +1,207 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_igs_stats.h" + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)) +#ifdef CONFIG_NET_CLS_ACT +#include +#endif +#endif + +static struct module *nss_igs_module; + +/* + * nss_igs_verify_if_num() + * Verify interface number passed to us. + */ +bool nss_igs_verify_if_num(uint32_t if_num) +{ + enum nss_dynamic_interface_type if_type; + + if_type = nss_dynamic_interface_get_type(nss_igs_get_context(), if_num); + + if (if_type == NSS_DYNAMIC_INTERFACE_TYPE_IGS) { + return true; + } + return false; +} +EXPORT_SYMBOL(nss_igs_verify_if_num); + +/* + * nss_igs_handler() + * Handle NSS -> HLOS messages for igs device + */ +static void nss_igs_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, + void *app_data) +{ + void *ctx; + nss_igs_msg_callback_t cb; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + BUG_ON(!nss_igs_verify_if_num(ncm->interface)); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_IGS_MSG_MAX) { + nss_warning("%px: received invalid message %d for IGS interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_igs_msg)) { + nss_warning("%px: tx request for another interface: %d", nss_ctx, ncm->interface); + return; + } + + switch (ncm->type) { + case NSS_IGS_MSG_SYNC_STATS: + /* + * Debug stats embedded in stats msg. + */ + nss_igs_stats_sync(nss_ctx, ncm, ncm->interface); + break; + } + + /* + * Update the callback and app_data for NOTIFY messages + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_core_get_msg_handler(nss_ctx, ncm->interface); + ncm->app_data = (nss_ptr_t)app_data; + } + + /* + * callback + */ + cb = (nss_igs_msg_callback_t)ncm->cb; + ctx = (void *)ncm->app_data; + + /* + * call igs callback + */ + if (!cb) { + nss_warning("%px: No callback for igs interface %d", + nss_ctx, ncm->interface); + return; + } + + cb(ctx, ncm); +} + +/* + * nss_igs_unregister_if() + * Un-registers IGS interface from the NSS firmware. + */ +void nss_igs_unregister_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.igs_handler_id]; + uint32_t status; + + nss_assert(nss_ctx); + nss_assert(nss_igs_verify_if_num(if_num)); + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + + nss_core_unregister_handler(nss_ctx, if_num); + status = nss_core_unregister_msg_handler(nss_ctx, if_num); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Not able to unregister handler for interface %d with NSS core\n", nss_ctx, if_num); + } + + nss_igs_stats_reset(if_num); +} +EXPORT_SYMBOL(nss_igs_unregister_if); + +/* + * nss_igs_register_if() + * Registers the IGS interface with NSS FW. + */ +struct nss_ctx_instance *nss_igs_register_if(uint32_t if_num, uint32_t type, + nss_igs_msg_callback_t event_callback, struct net_device *netdev, + uint32_t features) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.igs_handler_id]; + uint32_t status; + + nss_assert(nss_ctx); + nss_assert(nss_igs_verify_if_num(if_num)); + + nss_core_register_handler(nss_ctx, if_num, nss_igs_handler, netdev); + status = nss_core_register_msg_handler(nss_ctx, if_num, event_callback); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_core_unregister_handler(nss_ctx, if_num); + nss_warning("%px: Not able to register handler for interface %d with NSS core\n", nss_ctx, if_num); + return NULL; + } + + nss_core_register_subsys_dp(nss_ctx, if_num, NULL, 0, netdev, netdev, features); + nss_core_set_subsys_dp_type(nss_ctx, netdev, if_num, type); + + nss_igs_stats_dentry_create(); + nss_igs_stats_init(if_num, netdev); + + return nss_ctx; +} +EXPORT_SYMBOL(nss_igs_register_if); + +/* + * nss_igs_get_context() + * Get the IGS context. + */ +struct nss_ctx_instance *nss_igs_get_context() +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.igs_handler_id]; +} +EXPORT_SYMBOL(nss_igs_get_context); + +#ifdef CONFIG_NET_CLS_ACT +/* + * nss_igs_module_save() + * Save the ingress shaping module reference. + */ +void nss_igs_module_save(struct tc_action_ops *act, struct module *module) +{ + nss_assert(act); + nss_assert(act->type == TCA_ACT_MIRRED_NSS); + + nss_igs_module = module; +} +EXPORT_SYMBOL(nss_igs_module_save); +#endif + +/* + * nss_igs_module_get() + * Get the ingress shaping module reference. + */ +bool nss_igs_module_get() +{ + nss_assert(nss_igs_module); + return try_module_get(nss_igs_module); +} +EXPORT_SYMBOL(nss_igs_module_get); + +/* + * nss_igs_module_put() + * Release the ingress shaping module reference. + */ +void nss_igs_module_put() +{ + nss_assert(nss_igs_module); + module_put(nss_igs_module); +} +EXPORT_SYMBOL(nss_igs_module_put); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_igs_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_igs_stats.c new file mode 100644 index 000000000..a6b511a28 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_igs_stats.c @@ -0,0 +1,307 @@ +/* + ************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_igs_stats.h" + +/* + * nss_igs_stats + * IGS debug statistics. + */ +enum nss_igs_stats { + NSS_IGS_STATS_TX_DROP, + NSS_IGS_STATS_SHAPER_DROP, + NSS_IGS_STATS_IPV4_PARSE_FAIL, + NSS_IGS_STATS_IPV4_UNKNOWN_GRE_TYPE, + NSS_IGS_STATS_IPV4_UNKNOWN_L4, + NSS_IGS_STATS_IPV4_NO_CME, + NSS_IGS_STATS_IPV4_FRAG_INITIAL, + NSS_IGS_STATS_IPV4_FRAG_NON_INITIAL, + NSS_IGS_STATS_IPV4_MALFORMED_UDP, + NSS_IGS_STATS_IPV4_MALFORMED_TCP, + NSS_IGS_STATS_IPV4_MALFORMED_UDPL, + NSS_IGS_STATS_IPV4_MALFORMED_GRE, + NSS_IGS_STATS_IPV6_PARSE_FAIL, + NSS_IGS_STATS_IPV6_UNKNOWN_L4, + NSS_IGS_STATS_IPV6_NO_CME, + NSS_IGS_STATS_IPV6_FRAG_INITIAL, + NSS_IGS_STATS_IPV6_FRAG_NON_INITIAL, + NSS_IGS_STATS_IPV6_MALFORMED_UDP, + NSS_IGS_STATS_IPV6_MALFORMED_TCP, + NSS_IGS_STATS_IPV6_MALFORMED_UDPL, + NSS_IGS_STATS_IPV6_MALFORMED_FRAG, + NSS_IGS_STATS_EVENT_NO_SI, + NSS_IGS_STATS_ETH_PARSE_FAIL, + NSS_IGS_STATS_ETH_UNKNOWN_TYPE, + NSS_IGS_STATS_PPPOE_NON_IP, + NSS_IGS_STATS_PPPOE_MALFORMED, + NSS_IGS_STATS_MAX +}; + +/* + * nss_igs_stats_debug_instance + * Stucture for H2N/N2H IGS debug stats + */ +static struct nss_igs_stats_debug_instance { + uint64_t stats[NSS_IGS_STATS_MAX]; /* IGS statistics for each instance. */ + int32_t if_index; /* IFB instance netdev index. */ + uint32_t if_num; /* IFB instance NSS interface number */ + bool valid; /* IFB statistics valid bit. */ +} nss_igs_stats_debug[NSS_MAX_IGS_DYNAMIC_INTERFACES]; + +/* + * Data structures to store IGS interface stats. + */ +static DEFINE_SPINLOCK(nss_igs_stats_debug_lock); + +/* + * nss_igs_stats_str + * IGS statistics strings for nss session stats + */ +struct nss_stats_info nss_igs_stats_str[NSS_IGS_STATS_MAX] = { + {"IGS_SHAPER_TX_DROP" , NSS_STATS_TYPE_DROP}, + {"IGS_SHAPER_DROP" , NSS_STATS_TYPE_DROP}, + {"IGS_EXCEPTION_IPV4_PARSE_FAIL" , NSS_STATS_TYPE_EXCEPTION}, + {"IGS_EXCEPTION_IPV4_UNKNOWN_GRE_TYPE" , NSS_STATS_TYPE_EXCEPTION}, + {"IGS_EXCEPTION_IPV4_UNKNOWN_L4" , NSS_STATS_TYPE_EXCEPTION}, + {"IGS_EXCEPTION_IPV4_NO_CME" , NSS_STATS_TYPE_EXCEPTION}, + {"IGS_EXCEPTION_IPV4_FRAG_INITIAL" , NSS_STATS_TYPE_EXCEPTION}, + {"IGS_EXCEPTION_IPV4_FRAG_NON_INITIAL" , NSS_STATS_TYPE_EXCEPTION}, + {"IGS_EXCEPTION_IPV4_MALFORMED_UDP" , NSS_STATS_TYPE_EXCEPTION}, + {"IGS_EXCEPTION_IPV4_MALFORMED_TCP" , NSS_STATS_TYPE_EXCEPTION}, + {"IGS_EXCEPTION_IPV4_MALFORMED_UDPL" , NSS_STATS_TYPE_EXCEPTION}, + {"IGS_EXCEPTION_IPV4_MALFORMED_GRE" , NSS_STATS_TYPE_EXCEPTION}, + {"IGS_EXCEPTION_IPV6_PARSE_FAIL" , NSS_STATS_TYPE_EXCEPTION}, + {"IGS_EXCEPTION_IPV6_UNKNOWN_L4" , NSS_STATS_TYPE_EXCEPTION}, + {"IGS_EXCEPTION_IPV6_NO_CME" , NSS_STATS_TYPE_EXCEPTION}, + {"IGS_EXCEPTION_IPV6_FRAG_INITIAL" , NSS_STATS_TYPE_EXCEPTION}, + {"IGS_EXCEPTION_IPV6_FRAG_NON_INITIAL" , NSS_STATS_TYPE_EXCEPTION}, + {"IGS_EXCEPTION_IPV6_MALFORMED_UDP" , NSS_STATS_TYPE_EXCEPTION}, + {"IGS_EXCEPTION_IPV6_MALFORMED_TCP" , NSS_STATS_TYPE_EXCEPTION}, + {"IGS_EXCEPTION_IPV6_MALFORMED_UDPL" , NSS_STATS_TYPE_EXCEPTION}, + {"IGS_EXCEPTION_IPV6_MALFORMED_FRAG" , NSS_STATS_TYPE_EXCEPTION}, + {"IGS_EXCEPTION_EVENT_NO_SI" , NSS_STATS_TYPE_EXCEPTION}, + {"IGS_EXCEPTION_ETH_PARSE_FAIL" , NSS_STATS_TYPE_EXCEPTION}, + {"IGS_EXCEPTION_ETH_UNKNOWN_TYPE" , NSS_STATS_TYPE_EXCEPTION}, + {"IGS_EXCEPTION_PPPOE_NON_IP" , NSS_STATS_TYPE_EXCEPTION}, + {"IGS_EXCEPTION_PPPOE_MALFORMED" , NSS_STATS_TYPE_EXCEPTION} +}; + +/* + * nss_igs_stats_get() + * Get IGS statistics. + */ +static void nss_igs_stats_get(void *stats_mem) +{ + struct nss_igs_stats_debug_instance *stats = (struct nss_igs_stats_debug_instance *)stats_mem; + int i; + + if (!stats) { + nss_warning("No memory to copy IGS stats"); + return; + } + + spin_lock_bh(&nss_igs_stats_debug_lock); + for (i = 0; i < NSS_MAX_IGS_DYNAMIC_INTERFACES; i++) { + if (nss_igs_stats_debug[i].valid) { + memcpy(stats, &nss_igs_stats_debug[i], sizeof(struct nss_igs_stats_debug_instance)); + stats++; + } + } + spin_unlock_bh(&nss_igs_stats_debug_lock); +} + +/* + * nss_igs_stats_read() + * Read IGS statistics + */ +static ssize_t nss_igs_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + + uint32_t max_output_lines = 2 /* header & footer for instance stats */ + + NSS_MAX_IGS_DYNAMIC_INTERFACES * + ((NSS_STATS_NODE_MAX + 3 ) + (NSS_IGS_STATS_MAX + 3)) /*instance stats */ + + 2; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + struct net_device *dev; + struct nss_igs_stats_debug_instance *igs_shadow_stats; + int id; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(!lbuf)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + igs_shadow_stats = kzalloc(sizeof(struct nss_igs_stats_debug_instance) * + NSS_MAX_IGS_DYNAMIC_INTERFACES, GFP_KERNEL); + if (unlikely(!igs_shadow_stats)) { + nss_warning("Could not allocate memory for base debug statistics buffer"); + kfree(lbuf); + return 0; + } + + /* + * Get all stats + */ + nss_igs_stats_get((void *)igs_shadow_stats); + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "igs", NSS_STATS_SINGLE_CORE); + + /* + * Session stats + */ + for (id = 0; id < NSS_MAX_IGS_DYNAMIC_INTERFACES; id++) { + + if (!igs_shadow_stats[id].valid) { + continue; + } + + dev = dev_get_by_index(&init_net, igs_shadow_stats[id].if_index); + if (likely(dev)) { + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d, netdevice=%s\n", id, + igs_shadow_stats[id].if_num, dev->name); + dev_put(dev); + } else { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d\n", id, + igs_shadow_stats[id].if_num); + } + size_wr += nss_stats_fill_common_stats(igs_shadow_stats[id].if_num, id, lbuf, size_wr, size_al, "igs"); + + /* + * IGS exception stats. + */ + size_wr += nss_stats_print("igs", "igs exception stats start" + , id + , nss_igs_stats_str + , igs_shadow_stats[id].stats + , NSS_IGS_STATS_MAX + , lbuf, size_wr, size_al); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n"); + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr); + + kfree(igs_shadow_stats); + kfree(lbuf); + return bytes_read; +} + +/* + * nss_igs_stats_sync + * API to sync statistics for IGS + */ +void nss_igs_stats_sync(struct nss_ctx_instance *nss_ctx, + struct nss_cmn_msg *ncm, uint16_t if_num) +{ + uint8_t i, j; + struct nss_top_instance *nss_top = nss_ctx->nss_top; + struct nss_igs_msg *nim = (struct nss_igs_msg *)ncm; + struct nss_igs_stats_sync_msg *stats_msg = &nim->msg.stats; + struct nss_cmn_node_stats *node_stats_ptr = &stats_msg->node_stats; + uint32_t *igs_stats_ptr = (uint32_t *)&stats_msg->igs_stats; + + spin_lock_bh(&nss_igs_stats_debug_lock); + for (i = 0; i < NSS_MAX_IGS_DYNAMIC_INTERFACES; i++) { + if (nss_igs_stats_debug[i].if_num != if_num) { + continue; + } + + for (j = 0; j < NSS_IGS_STATS_MAX; j++) { + /* + * sync stats. + */ + nss_igs_stats_debug[i].stats[j] += igs_stats_ptr[j]; + } + spin_unlock_bh(&nss_igs_stats_debug_lock); + goto sync_cmn_stats; + } + + spin_unlock_bh(&nss_igs_stats_debug_lock); + return; + +sync_cmn_stats: + spin_lock_bh(&nss_top->stats_lock); + + /* + * sync common stats. + */ + nss_top->stats_node[if_num][NSS_STATS_NODE_RX_PKTS] += node_stats_ptr->rx_packets; + nss_top->stats_node[if_num][NSS_STATS_NODE_RX_BYTES] += node_stats_ptr->rx_bytes; + nss_top->stats_node[if_num][NSS_STATS_NODE_TX_PKTS] += node_stats_ptr->tx_packets; + nss_top->stats_node[if_num][NSS_STATS_NODE_TX_BYTES] += node_stats_ptr->tx_bytes; + + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + nss_top->stats_node[if_num][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + i] += + node_stats_ptr->rx_dropped[i]; + } + + spin_unlock_bh(&nss_top->stats_lock); +} + +/* + * nss_igs_stats_reset() + * API to reset the IGS stats. + */ +void nss_igs_stats_reset(uint32_t if_num) +{ + uint8_t i; + + spin_lock_bh(&nss_igs_stats_debug_lock); + for (i = 0; i < NSS_MAX_IGS_DYNAMIC_INTERFACES; i++) { + if (nss_igs_stats_debug[i].if_num == if_num) { + memset(&nss_igs_stats_debug[i], 0, sizeof(struct nss_igs_stats_debug_instance)); + break; + } + } + spin_unlock_bh(&nss_igs_stats_debug_lock); +} + +/* + * nss_igs_stats_init() + * API to initialize IGS debug instance statistics. + */ +void nss_igs_stats_init(uint32_t if_num, struct net_device *netdev) +{ + uint8_t i; + + spin_lock_bh(&nss_igs_stats_debug_lock); + for (i = 0; i < NSS_MAX_IGS_DYNAMIC_INTERFACES; i++) { + if (!nss_igs_stats_debug[i].valid) { + nss_igs_stats_debug[i].valid = true; + nss_igs_stats_debug[i].if_num = if_num; + nss_igs_stats_debug[i].if_index = netdev->ifindex; + break; + } + } + spin_unlock_bh(&nss_igs_stats_debug_lock); +} + +/* + * nss_igs_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(igs) + +/* + * nss_igs_stats_dentry_create() + * Create igs statistics debug entry. + */ +void nss_igs_stats_dentry_create(void) +{ + nss_stats_create_dentry("igs", &nss_igs_stats_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_igs_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_igs_stats.h new file mode 100644 index 000000000..08f9c79f7 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_igs_stats.h @@ -0,0 +1,45 @@ +/* + ****************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_IGS_STATS_H +#define __NSS_IGS_STATS_H + +/* + * nss_igs_stats_sync + * API to sync statistics for IGS + */ +extern void nss_igs_stats_sync(struct nss_ctx_instance *nss_ctx, + struct nss_cmn_msg *ncm, uint16_t if_num); + +/* + * nss_igs_stats_reset() + * API to reset the IGS stats. + */ +extern void nss_igs_stats_reset(uint32_t if_num); + +/* + * nss_igs_stats_init() + * API to initialize IGS debug instance statistics. + */ +extern void nss_igs_stats_init(uint32_t if_num, struct net_device *netdev); + + +/* + * IGS statistics APIs + */ +extern void nss_igs_stats_dentry_create(void); + +#endif /* __NSS_IGS_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_init.c b/feeds/ipq807x/qca-nss-drv/src/nss_init.c new file mode 100644 index 000000000..4f569a254 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_init.c @@ -0,0 +1,942 @@ +/* + ************************************************************************** + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_init.c + * NSS init APIs + * + */ +#include "nss_core.h" +#if (NSS_PM_SUPPORT == 1) +#include "nss_pm.h" +#endif +#include "nss_tx_rx_common.h" +#include "nss_data_plane.h" +#include "nss_capwap.h" +#include "nss_strings.h" + +#include + +#include +#include +#include +#include + +#if (NSS_DT_SUPPORT == 1) +#if (NSS_FABRIC_SCALING_SUPPORT == 1) +#include +#endif +#include +#include +#include +#include +#include +#else +#include +#endif + +#include +#include +#include + +/* + * Global declarations + */ +int nss_ctl_redirect __read_mostly = 0; +int nss_ctl_debug __read_mostly = 0; +int nss_ctl_logbuf __read_mostly = 0; +int nss_jumbo_mru __read_mostly = 0; +int nss_paged_mode __read_mostly = 0; +#if (NSS_SKB_REUSE_SUPPORT == 1) +int nss_max_reuse __read_mostly = PAGE_SIZE; +#endif +int nss_skip_nw_process = 0x0; +module_param(nss_skip_nw_process, int, S_IRUGO); + +/* + * PM client handle + */ +#if (NSS_PM_SUPPORT == 1) +static void *pm_client; +#endif + +/* + * Handler to send NSS messages + */ +struct clk *nss_core0_clk; +struct clk *nss_core1_clk; + +/* + * Handle fabric requests - only on new kernel + */ +#if (NSS_DT_SUPPORT == 1) +struct clk *nss_fab0_clk; +struct clk *nss_fab1_clk; +#endif + +/* + * Top level nss context structure + */ +struct nss_top_instance nss_top_main; +struct nss_cmd_buffer nss_cmd_buf; +struct nss_runtime_sampling nss_runtime_samples; +struct workqueue_struct *nss_wq; + +/* + * Work Queue to handle messages to Kernel + */ +nss_work_t *nss_work; + +extern struct of_device_id nss_dt_ids[]; + +/* + * nss_probe() + * HLOS device probe callback + */ +static inline int nss_probe(struct platform_device *nss_dev) +{ + return nss_hal_probe(nss_dev); +} + +/* + * nss_remove() + * HLOS device remove callback + */ +static inline int nss_remove(struct platform_device *nss_dev) +{ + return nss_hal_remove(nss_dev); +} + +#if (NSS_DT_SUPPORT == 1) +/* + * Platform Device ID for NSS core. + */ +struct of_device_id nss_dt_ids[] = { + { .compatible = "qcom,nss" }, + { .compatible = "qcom,nss0" }, + { .compatible = "qcom,nss1" }, + {}, +}; +MODULE_DEVICE_TABLE(of, nss_dt_ids); +#endif + +/* + * nss_driver + * Platform driver structure for NSS + */ +struct platform_driver nss_driver = { + .probe = nss_probe, + .remove = nss_remove, + .driver = { + .name = "qca-nss", + .owner = THIS_MODULE, +#if (NSS_DT_SUPPORT == 1) + .of_match_table = of_match_ptr(nss_dt_ids), +#endif + }, +}; + +#if (NSS_FREQ_SCALE_SUPPORT == 1) +/* + * nss_reset_frequency_stats_samples() + * Reset all frequency sampling state when auto scaling is turned off. + */ +static void nss_reset_frequency_stats_samples(void) +{ + nss_runtime_samples.buffer_index = 0; + nss_runtime_samples.sum = 0; + nss_runtime_samples.average = 0; + nss_runtime_samples.sample_count = 0; + nss_runtime_samples.message_rate_limit = 0; + nss_runtime_samples.freq_scale_rate_limit_down = 0; +} + +/* + * nss_current_freq_handler() + * Handle Userspace Frequency Change Requests + */ +static int nss_current_freq_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + int ret, i; + + BUG_ON(!nss_wq); + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + + if (!*lenp || (*ppos && !write)) { + printk("Frequency Set to %d\n", nss_cmd_buf.current_freq); + *lenp = 0; + return ret; + } + + /* + * Check if frequency exists in frequency Table + */ + i = 0; + while (i < NSS_FREQ_MAX_SCALE) { + if (nss_runtime_samples.freq_scale[i].frequency == nss_cmd_buf.current_freq) { + break; + } + i++; + } + if (i == NSS_FREQ_MAX_SCALE) { + printk("Frequency not found. Please check Frequency Table\n"); + nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency; + return ret; + } + + /* + * Turn off Auto Scale + */ + nss_cmd_buf.auto_scale = 0; + nss_runtime_samples.freq_scale_ready = 0; + nss_runtime_samples.freq_scale_index = i; + + nss_work = (nss_work_t *)kmalloc(sizeof(nss_work_t), GFP_ATOMIC); + if (!nss_work) { + nss_info("NSS Freq WQ kmalloc fail"); + return ret; + } + INIT_WORK((struct work_struct *)nss_work, nss_hal_wq_function); + nss_work->frequency = nss_cmd_buf.current_freq; + nss_work->stats_enable = 0; + + /* + * Ensure we start with a fresh set of samples later + */ + nss_reset_frequency_stats_samples(); + + queue_work(nss_wq, (struct work_struct *)nss_work); + + return ret; +} + +/* + * nss_auto_scale_handler() + * Enables or Disable Auto Scaling + */ +static int nss_auto_scale_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + int ret; + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + + if (!*lenp || (*ppos && !write)) { + return ret; + } + + if (nss_cmd_buf.auto_scale != 1) { + /* + * Is auto scaling currently enabled? If so, send the command to + * disable stats reporting to NSS + */ + if (nss_runtime_samples.freq_scale_ready != 0) { + nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency; + nss_work = (nss_work_t *)kmalloc(sizeof(nss_work_t), GFP_ATOMIC); + if (!nss_work) { + nss_info("NSS Freq WQ kmalloc fail"); + return ret; + } + INIT_WORK((struct work_struct *)nss_work, nss_hal_wq_function); + nss_work->frequency = nss_cmd_buf.current_freq; + nss_work->stats_enable = 0; + queue_work(nss_wq, (struct work_struct *)nss_work); + nss_runtime_samples.freq_scale_ready = 0; + + /* + * The current samples would be stale later when scaling is + * enabled again, hence reset them + */ + nss_reset_frequency_stats_samples(); + } + return ret; + } + + /* + * Setup default values - Middle of Freq Scale Band + */ + nss_runtime_samples.freq_scale_index = 1; + nss_runtime_samples.sample_count = 0; + nss_runtime_samples.initialized = 0; + nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency; + + nss_work = (nss_work_t *)kmalloc(sizeof(nss_work_t), GFP_ATOMIC); + if (!nss_work) { + nss_info("NSS Freq WQ kmalloc fail"); + return ret; + } + INIT_WORK((struct work_struct *)nss_work, nss_hal_wq_function); + nss_work->frequency = nss_cmd_buf.current_freq; + nss_work->stats_enable = 1; + queue_work(nss_wq, (struct work_struct *)nss_work); + + nss_cmd_buf.auto_scale = 0; + nss_runtime_samples.freq_scale_ready = 1; + + return ret; +} + +/* + * nss_get_freq_table_handler() + * Display Support Freq and Ex how to Change. + */ +static int nss_get_freq_table_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + int ret, i; + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + + if (write) { + return ret; + } + + printk("Frequency Supported - "); + + i = 0; + while (i < NSS_FREQ_MAX_SCALE) { + if (nss_runtime_samples.freq_scale[i].frequency != NSS_FREQ_SCALE_NA) { + printk("%d Hz ", nss_runtime_samples.freq_scale[i].frequency); + } + i++; + } + printk("\n"); + + *lenp = 0; + return ret; +} + +/* + * nss_get_average_inst_handler() + * Display AVG Inst Per Ms. + */ +static int nss_get_average_inst_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + int ret; + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + + if (write) { + return ret; + } + + printk("Current Inst Per Ms %x\n", nss_runtime_samples.average); + + *lenp = 0; + return ret; +} +#endif + +#if (NSS_FW_DBG_SUPPORT == 1) +/* + * nss_debug_handler() + * Enable NSS debug output + */ +static int nss_debug_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + int ret; + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + if (!ret) { + if ((write) && (nss_ctl_debug != 0)) { + printk("Enabling NSS SPI Debug\n"); + nss_hal_debug_enable(); + } + } + + return ret; +} +#endif + +/* + * nss_coredump_handler() + * Send Signal To Coredump NSS Cores + */ +static int nss_coredump_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[NSS_CORE_0]; + int ret; + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + if (!ret) { + /* + * if nss_cmd_buf.coredump is not 0 or 1, panic will be disabled + * when NSS FW crashes, so OEM/ODM have a chance to use mdump + * to dump crash dump (coredump) and send dump to us for analysis. + */ + if ((write) && (nss_ctl_debug != 0) && nss_cmd_buf.coredump == 1) { + printk("Coredumping to DDR\n"); + nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_TRIGGER_COREDUMP); + } + } + + return ret; +} + +/* + * nss_jumbo_mru_handler() + * Sysctl to modify nss_jumbo_mru + */ +static int nss_jumbo_mru_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + int ret; + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + if (ret) { + return ret; + } + + if (write) { + nss_core_set_jumbo_mru(nss_jumbo_mru); + nss_info("jumbo_mru set to %d\n", nss_jumbo_mru); + } + + return ret; +} + +/* nss_paged_mode_handler() + * Sysctl to modify nss_paged_mode. + */ + +static int nss_paged_mode_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + int ret; + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + if (ret) { + return ret; + } + + if (write) { + nss_core_set_paged_mode(nss_paged_mode); + nss_info("paged_mode set to %d\n", nss_paged_mode); + } + + return ret; +} + +#if (NSS_SKB_REUSE_SUPPORT == 1) +/* + * nss_get_min_reuse_handler() + * Sysctl to get min reuse sizes + */ +static int nss_get_min_reuse_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + int ret; + struct nss_ctx_instance *nss_ctx = NULL; + uint32_t core_id; + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + if (ret) { + return ret; + } + + printk("Min SKB reuse sizes - "); + + for (core_id = 0; core_id < NSS_CORE_MAX; core_id++) { + nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[core_id]; + printk("core %d: %d ", core_id, nss_core_get_min_reuse(nss_ctx)); + } + + printk("\n"); + *lenp = 0; + return ret; +} + +/* + * nss_max_reuse_handler() + * Sysctl to modify nss_max_reuse + */ +static int nss_max_reuse_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + int ret; + + nss_max_reuse = nss_core_get_max_reuse(); + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + if (ret) { + return ret; + } + + if (write) { + nss_core_set_max_reuse(nss_max_reuse); + nss_info("max_reuse set to %d\n", nss_max_reuse); + } + + return ret; +} + +/* + * sysctl-tuning for NSS driver SKB reuse + */ +static struct ctl_table nss_skb_reuse_table[] = { + { + .procname = "min_sizes", + .data = NULL, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_get_min_reuse_handler, + }, + { + .procname = "max_size", + .data = &nss_max_reuse, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_max_reuse_handler, + }, + { } +}; +#endif + +#if (NSS_FREQ_SCALE_SUPPORT == 1) +/* + * sysctl-tuning infrastructure. + */ +static struct ctl_table nss_freq_table[] = { + { + .procname = "current_freq", + .data = &nss_cmd_buf.current_freq, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_current_freq_handler, + }, + { + .procname = "freq_table", + .data = &nss_cmd_buf.max_freq, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_get_freq_table_handler, + }, + { + .procname = "auto_scale", + .data = &nss_cmd_buf.auto_scale, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_auto_scale_handler, + }, + { + .procname = "inst_per_sec", + .data = &nss_cmd_buf.average_inst, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_get_average_inst_handler, + }, + { } +}; +#endif + +static struct ctl_table nss_general_table[] = { + { + .procname = "redirect", + .data = &nss_ctl_redirect, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, +#if (NSS_FW_DBG_SUPPORT == 1) + { + .procname = "debug", + .data = &nss_ctl_debug, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_debug_handler, + }, +#endif + { + .procname = "coredump", + .data = &nss_cmd_buf.coredump, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_coredump_handler, + }, + { + .procname = "logbuf", + .data = &nss_ctl_logbuf, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_logbuffer_handler, + }, + { + .procname = "jumbo_mru", + .data = &nss_jumbo_mru, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_jumbo_mru_handler, + }, + { + .procname = "paged_mode", + .data = &nss_paged_mode, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_paged_mode_handler, + }, + { } +}; + +static struct ctl_table nss_init_dir[] = { +#if (NSS_FREQ_SCALE_SUPPORT == 1) + { + .procname = "clock", + .mode = 0555, + .child = nss_freq_table, + }, +#endif + { + .procname = "general", + .mode = 0555, + .child = nss_general_table, + }, +#if (NSS_SKB_REUSE_SUPPORT == 1) + { + .procname = "skb_reuse", + .mode = 0555, + .child = nss_skb_reuse_table, + }, +#endif + { } +}; + +static struct ctl_table nss_root_dir[] = { + { + .procname = "nss", + .mode = 0555, + .child = nss_init_dir, + }, + { } +}; + +static struct ctl_table nss_root[] = { + { + .procname = "dev", + .mode = 0555, + .child = nss_root_dir, + }, + { } +}; + +static struct ctl_table_header *nss_dev_header; + +/* + * nss_init() + * Registers nss driver + */ +static int __init nss_init(void) +{ +#if (NSS_DT_SUPPORT == 1) + struct device_node *cmn = NULL; +#endif + nss_info("Init NSS driver"); + +#if (NSS_DT_SUPPORT == 1) + /* + * Get reference to NSS common device node + */ + cmn = of_find_node_by_name(NULL, "nss-common"); + if (!cmn) { + nss_info_always("qca-nss-drv.ko is loaded for symbol link\n"); + return 0; + } + of_node_put(cmn); + + /* + * Pick up HAL by target information + */ +#if defined(NSS_HAL_IPQ806X_SUPPORT) + if (of_machine_is_compatible("qcom,ipq8064") || of_machine_is_compatible("qcom,ipq8062")) { + nss_top_main.hal_ops = &nss_hal_ipq806x_ops; + nss_top_main.data_plane_ops = &nss_data_plane_gmac_ops; + nss_top_main.num_nss = 2; + } +#endif +#if defined(NSS_HAL_IPQ807x_SUPPORT) + if (of_machine_is_compatible("qcom,ipq807x") || of_machine_is_compatible("qcom,ipq8074")) { + nss_top_main.hal_ops = &nss_hal_ipq807x_ops; + nss_top_main.data_plane_ops = &nss_data_plane_ops; +#if defined(NSS_MEM_PROFILE_LOW) + nss_top_main.num_nss = 1; +#else + nss_top_main.num_nss = 2; +#endif + } +#endif +#if defined(NSS_HAL_IPQ60XX_SUPPORT) + if (of_machine_is_compatible("qcom,ipq6018")) { + nss_top_main.hal_ops = &nss_hal_ipq60xx_ops; + nss_top_main.data_plane_ops = &nss_data_plane_ops; + nss_top_main.num_nss = 1; + } +#endif +#if defined(NSS_HAL_IPQ50XX_SUPPORT) + if (of_machine_is_compatible("qcom,ipq5018")) { + nss_top_main.hal_ops = &nss_hal_ipq50xx_ops; + nss_top_main.data_plane_ops = &nss_data_plane_ops; + nss_top_main.num_nss = 1; + } +#endif +#if defined(NSS_HAL_FSM9010_SUPPORT) + if (of_machine_is_compatible("qcom,fsm9010")) { + nss_top_main.hal_ops = &nss_hal_fsm9010_ops; + nss_top_main.data_plane_ops = &nss_data_plane_gmac_ops; + nss_top_main.num_nss = 1; + } +#endif + if (!nss_top_main.hal_ops) { + nss_info_always("No supported HAL compiled on this platform\n"); + return -EFAULT; + } +#else + /* + * For banana, only ipq806x is supported + */ + nss_top_main.hal_ops = &nss_hal_ipq806x_ops; + nss_top_main.data_plane_ops = &nss_data_plane_gmac_ops; + nss_top_main.num_nss = 2; + +#endif /* NSS_DT_SUPPORT */ + nss_top_main.nss_hal_common_init_done = false; + + /* + * Initialize data_plane workqueue + */ + if (nss_data_plane_init_delay_work()) { + nss_warning("Error initializing nss_data_plane_workqueue\n"); + return -EFAULT; + } + + /* + * Enable spin locks + */ + spin_lock_init(&(nss_top_main.lock)); + spin_lock_init(&(nss_top_main.stats_lock)); + mutex_init(&(nss_top_main.wq_lock)); + + /* + * Enable NSS statistics + */ + nss_stats_init(); + + /* + * Enable NSS statistics names. + */ + nss_strings_init(); + + /* + * Register sysctl table. + */ + nss_dev_header = register_sysctl_table(nss_root); + + /* + * Registering sysctl for ipv4/6 specific config. + */ + nss_ipv4_register_sysctl(); + nss_ipv6_register_sysctl(); + + /* + * Registering sysctl for n2h specific config. + */ + if (nss_top_main.num_nss == 1) { + nss_n2h_single_core_register_sysctl(); + } else { + nss_n2h_multi_core_register_sysctl(); + } + + /* + * Registering sysctl for rps specific config. + */ + nss_rps_register_sysctl(); + +#ifdef NSS_DRV_C2C_ENABLE + /* + * Registering sysctl for c2c_tx specific config. + */ + nss_c2c_tx_register_sysctl(); +#endif + + /* + * Registering sysctl for for printing non zero stats. + */ + nss_stats_register_sysctl(); + + /* + * Register sysctl for project config + */ + nss_project_register_sysctl(); + + /* + * Registering sysctl for pppoe specific config. + */ + nss_pppoe_register_sysctl(); + + /* + * Setup Runtime Sample values + */ + nss_runtime_samples.freq_scale_index = 1; + nss_runtime_samples.freq_scale_ready = 0; + nss_runtime_samples.freq_scale_rate_limit_down = 0; + nss_runtime_samples.buffer_index = 0; + nss_runtime_samples.sum = 0; + nss_runtime_samples.sample_count = 0; + nss_runtime_samples.average = 0; + nss_runtime_samples.message_rate_limit = 0; + nss_runtime_samples.initialized = 0; + + nss_cmd_buf.current_freq = nss_runtime_samples.freq_scale[nss_runtime_samples.freq_scale_index].frequency; + + /* + * Initial Workqueue + */ + nss_wq = create_workqueue("nss_freq_queue"); + +#if (NSS_PM_SUPPORT == 1) + /* + * Initialize NSS Bus PM module + */ + nss_pm_init(); + + /* + * Register with Bus driver + */ + pm_client = nss_pm_client_register(NSS_PM_CLIENT_NETAP); + if (!pm_client) { + nss_warning("Error registering with PM driver"); + } +#endif + + /* + * Initialize mtu size needed as start + */ + nss_top_main.prev_mtu_sz = ETH_DATA_LEN; + + /* + * register panic handler and timeout control + */ + nss_coredump_notify_register(); + nss_coredump_init_delay_work(); + +#ifdef NSS_DRV_CAPWAP_ENABLE + /* + * Init capwap + */ + nss_capwap_init(); +#endif + +#ifdef NSS_DRV_QRFS_ENABLE + /* + * Init QRFS + */ + nss_qrfs_init(); +#endif + +#ifdef NSS_DRV_C2C_ENABLE + /* + * Init c2c_tx + */ + nss_c2c_tx_init(); +#endif + +#ifdef NSS_DRV_PVXLAN_ENABLE + /* + * Init pvxlan + */ + nss_pvxlan_init(); +#endif + +#ifdef NSS_DRV_CLMAP_ENABLE + /* + * Init clmap + */ + nss_clmap_init(); +#endif + + /* + * INIT ppe on supported platform + */ +#ifdef NSS_DRV_PPE_ENABLE + nss_ppe_init(); +#endif + +#ifdef NSS_DRV_DMA_ENABLE + nss_dma_init(); +#endif + + /* + * Register platform_driver + */ + return platform_driver_register(&nss_driver); +} + +/* + * nss_cleanup() + * Unregisters nss driver + */ +static void __exit nss_cleanup(void) +{ + nss_info("Exit NSS driver"); + + if (nss_dev_header) + unregister_sysctl_table(nss_dev_header); + + /* + * Unregister n2h specific sysctl + */ + nss_n2h_unregister_sysctl(); + + /* + * Unregister rps specific sysctl + */ + nss_rps_unregister_sysctl(); + +#ifdef NSS_DRV_C2C_ENABLE + /* + * Unregister c2c_tx specific sysctl + */ + nss_c2c_tx_unregister_sysctl(); +#endif + + /* + * Unregister pppoe specific sysctl + */ + nss_pppoe_unregister_sysctl(); + + /* + * Unregister ipv4/6 specific sysctl + */ + nss_ipv4_unregister_sysctl(); + nss_ipv6_unregister_sysctl(); + + /* + * Free Memory allocated for connection tables + */ + nss_ipv4_free_conn_tables(); + nss_ipv6_free_conn_tables(); + + nss_project_unregister_sysctl(); + nss_data_plane_destroy_delay_work(); + + /* + * cleanup ppe on supported platform + */ +#ifdef NSS_DRV_PPE_ENABLE + nss_ppe_free(); +#endif + + platform_driver_unregister(&nss_driver); +} + +module_init(nss_init); +module_exit(nss_cleanup); + +MODULE_DESCRIPTION("QCA NSS Driver"); +MODULE_AUTHOR("Qualcomm Atheros Inc"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipsec.c b/feeds/ipq807x/qca-nss-drv/src/nss_ipsec.c new file mode 100644 index 000000000..49c7805f3 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipsec.c @@ -0,0 +1,597 @@ +/* + ************************************************************************** + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_ipsec.c + * NSS IPsec APIs + */ + +#include "nss_tx_rx_common.h" +#include "nss_ipsec.h" +#include "nss_ppe.h" +#include "nss_ipsec_log.h" + +#if defined(NSS_HAL_IPQ806X_SUPPORT) +#define NSS_IPSEC_ENCAP_INTERFACE_NUM NSS_IPSEC_ENCAP_IF_NUMBER +#define NSS_IPSEC_DECAP_INTERFACE_NUM NSS_IPSEC_DECAP_IF_NUMBER +#define NSS_IPSEC_DATA_INTERFACE_NUM NSS_C2C_TX_INTERFACE + +#elif defined(NSS_HAL_FSM9010_SUPPORT) +#define NSS_IPSEC_ENCAP_INTERFACE_NUM NSS_IPSEC_ENCAP_IF_NUMBER +#define NSS_IPSEC_DECAP_INTERFACE_NUM NSS_IPSEC_DECAP_IF_NUMBER +#define NSS_IPSEC_DATA_INTERFACE_NUM NSS_IPSEC_CMN_INTERFACE + +#elif defined(NSS_HAL_IPQ807x_SUPPORT) +#define NSS_IPSEC_ENCAP_INTERFACE_NUM NSS_IPSEC_CMN_INTERFACE +#define NSS_IPSEC_DECAP_INTERFACE_NUM NSS_IPSEC_CMN_INTERFACE +#define NSS_IPSEC_DATA_INTERFACE_NUM NSS_IPSEC_CMN_INTERFACE + +#elif defined(NSS_HAL_IPQ60XX_SUPPORT) +#define NSS_IPSEC_ENCAP_INTERFACE_NUM NSS_IPSEC_CMN_INTERFACE +#define NSS_IPSEC_DECAP_INTERFACE_NUM NSS_IPSEC_CMN_INTERFACE +#define NSS_IPSEC_DATA_INTERFACE_NUM NSS_IPSEC_CMN_INTERFACE + +#elif defined(NSS_HAL_IPQ50XX_SUPPORT) +#define NSS_IPSEC_ENCAP_INTERFACE_NUM NSS_IPSEC_CMN_INTERFACE +#define NSS_IPSEC_DECAP_INTERFACE_NUM NSS_IPSEC_CMN_INTERFACE +#define NSS_IPSEC_DATA_INTERFACE_NUM NSS_IPSEC_CMN_INTERFACE + +#else +#define NSS_IPSEC_ENCAP_INTERFACE_NUM -1 +#define NSS_IPSEC_DECAP_INTERFACE_NUM -1 +#define NSS_IPSEC_DATA_INTERFACE_NUM -1 + +#endif + +/* + * Amount time the synchronous message should wait for response from + * NSS before the timeout happens. After the timeout the message + * response even if it arrives has to be discarded. Typically, the + * time needs to be selected based on the worst case time in case of + * peak throughput between host & NSS. + */ +#define NSS_IPSEC_TX_TIMEO_TICKS msecs_to_jiffies(3000) /* 3 Seconds */ + +/* + * Private data structure to hold state for + * the ipsec specific NSS interaction + */ +struct nss_ipsec_pvt { + struct semaphore sem; /* used for synchronizing 'tx_msg_sync' */ + struct completion complete; /* completion callback */ + atomic_t resp; /* Response error type */ +} nss_ipsec; + +/* + * nss_ipsec_get_msg_ctx() + * return ipsec message context assoicated with the callback + * + * Note: certain SOC the decap interface specially programmed + */ +static inline nss_ptr_t nss_ipsec_get_msg_ctx(struct nss_ctx_instance *nss_ctx, uint32_t interface_num) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + + /* + * the encap is primary interface + */ + if (interface_num == NSS_IPSEC_ENCAP_INTERFACE_NUM) + return (nss_ptr_t)nss_top->ipsec_encap_ctx; + + return (nss_ptr_t)nss_top->ipsec_decap_ctx; +} + +/* + * nss_ipsec_get_msg_callback() + * this gets the message callback handler + */ +static inline nss_ptr_t nss_ipsec_get_msg_callback(struct nss_ctx_instance *nss_ctx, uint32_t interface_num) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + + /* + * the encap is primary interface + */ + if (interface_num == NSS_IPSEC_ENCAP_INTERFACE_NUM) + return (nss_ptr_t)nss_top->ipsec_encap_callback; + + return (nss_ptr_t)nss_top->ipsec_decap_callback; +} + +/* + ********************************** + Rx APIs + ********************************** + */ + +/* + * nss_ipsec_msg_handler() + * this handles all the IPsec events and responses + */ +static void nss_ipsec_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, void *app_data __attribute((unused))) +{ + struct nss_ipsec_msg *nim = (struct nss_ipsec_msg *)ncm; + nss_ipsec_msg_callback_t cb = NULL; + uint32_t if_num = ncm->interface; + + /* + * Trace messages. + */ + nss_ipsec_log_rx_msg(nim); + + /* + * Sanity check the message type + */ + if (ncm->type > NSS_IPSEC_MSG_TYPE_MAX) { + nss_warning("%px: rx message type out of range: %d", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_ipsec_msg)) { + nss_warning("%px: rx message length is invalid: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + BUG_ON((if_num != NSS_IPSEC_ENCAP_INTERFACE_NUM) && (if_num != NSS_IPSEC_DECAP_INTERFACE_NUM)); + + if (ncm->response == NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: rx message response for if %d, type %d, is invalid: %d", nss_ctx, ncm->interface, + ncm->type, ncm->response); + return; + } + + /* + * Is this a notification? if, yes then fill up the callback and app_data from + * locally stored state + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = nss_ipsec_get_msg_callback(nss_ctx, if_num); + ncm->app_data = nss_ipsec_get_msg_ctx(nss_ctx, if_num); + } + + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * load, test & call + */ + cb = (nss_ipsec_msg_callback_t)ncm->cb; + if (unlikely(!cb)) { + nss_trace("%px: rx handler has been unregistered for i/f: %d", nss_ctx, ncm->interface); + return; + } + + cb((void *)ncm->app_data, nim); +} + +/* + ********************************** + Tx APIs + ********************************** + */ + +/* + * nss_ipsec_callback() + * Callback to handle the completion of NSS->HLOS messages. + */ +static void nss_ipsec_callback(void *app_data, struct nss_ipsec_msg *nim) +{ + struct nss_cmn_msg *ncm = &nim->cm; + + /* + * This callback is for synchronous operation. The caller sends its + * response pointer which needs to be loaded with the response + * data arriving from the NSS + */ + atomic_t *resp = (atomic_t *)app_data; + + if (ncm->response == NSS_CMN_RESPONSE_ACK) { + atomic_set(resp, NSS_IPSEC_ERROR_TYPE_NONE); + complete(&nss_ipsec.complete); + return; + } + + atomic_set(resp, ncm->error); + complete(&nss_ipsec.complete); +} + +/* + * nss_ipsec_tx_msg + * Send ipsec rule to NSS. + */ +nss_tx_status_t nss_ipsec_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_ipsec_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + nss_info("%px: message %d for if %d\n", nss_ctx, ncm->type, ncm->interface); + + BUILD_BUG_ON(NSS_NBUF_PAYLOAD_SIZE < sizeof(struct nss_ipsec_msg)); + + /* + * Trace messages. + */ + nss_ipsec_log_tx_msg(msg); + + if ((ncm->interface != NSS_IPSEC_ENCAP_INTERFACE_NUM) && (ncm->interface != NSS_IPSEC_DECAP_INTERFACE_NUM)) { + nss_warning("%px: tx message request for another interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type > NSS_IPSEC_MSG_TYPE_MAX) { + nss_warning("%px: tx message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + nss_info("msg params version:%d, interface:%d, type:%d, cb:%px, app_data:%px, len:%d\n", + ncm->version, ncm->interface, ncm->type, (void *)ncm->cb, (void *)ncm->app_data, ncm->len); + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_ipsec_tx_msg); + +/* + * nss_ipsec_tx_msg_sync() + * Transmit a ipsec message to NSS firmware synchronously. + */ +nss_tx_status_t nss_ipsec_tx_msg_sync(struct nss_ctx_instance *nss_ctx, uint32_t if_num, + enum nss_ipsec_msg_type type, uint16_t len, + struct nss_ipsec_msg *nim, enum nss_ipsec_error_type *resp) +{ + struct nss_ipsec_msg nim_local = { {0} }; + nss_tx_status_t status; + int ret; + + /* + * Length of the message should be the based on type + */ + if (len > sizeof(nim_local.msg)) { + nss_warning("%px: (%u)Bad message length(%u) for type (%d)", nss_ctx, if_num, len, type); + return NSS_TX_FAILURE_TOO_LARGE; + } + + /* + * Response buffer is a required for copying the response for message + */ + if (!resp) { + nss_warning("%px: (%u)Response buffer is empty, type(%d)", nss_ctx, if_num, type); + return NSS_TX_FAILURE_BAD_PARAM; + } + + /* + * TODO: this can be removed in future as we need to ensure that the response + * memory is only updated when the current outstanding request is waiting. + * This can be solved by introducing sequence no. in messages and only completing + * the message if the sequence no. matches. For now this is solved by passing + * a known memory nss_ipsec.resp + */ + down(&nss_ipsec.sem); + + /* + * Initializing it to a fail error type + */ + atomic_set(&nss_ipsec.resp, NSS_IPSEC_ERROR_TYPE_UNHANDLED_MSG); + + /* + * We need to copy the message content into the actual message + * to be sent to NSS + * + * Note: Here pass the nss_ipsec.resp as the pointer. Since, the caller + * provided pointer is not allocated by us and may go away when this function + * returns with failure. The callback is not aware of this and may try to + * access the pointer incorrectly potentially resulting in a crash. + */ + nss_ipsec_msg_init(&nim_local, if_num, type, len, nss_ipsec_callback, &nss_ipsec.resp); + memcpy(&nim_local.msg, &nim->msg, len); + + status = nss_ipsec_tx_msg(nss_ctx, &nim_local); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: ipsec_tx_msg failed", nss_ctx); + goto done; + } + + ret = wait_for_completion_timeout(&nss_ipsec.complete, NSS_IPSEC_TX_TIMEO_TICKS); + if (!ret) { + nss_warning("%px: IPsec msg tx failed due to timeout", nss_ctx); + status = NSS_TX_FAILURE_NOT_ENABLED; + goto done; + } + + /* + * Read memory barrier + */ + smp_rmb(); + + /* + * Copy the response received + */ + *resp = atomic_read(&nss_ipsec.resp); + + /* + * Only in case of non-error response we will + * indicate success + */ + if (*resp != NSS_IPSEC_ERROR_TYPE_NONE) + status = NSS_TX_FAILURE; + +done: + up(&nss_ipsec.sem); + return status; +} +EXPORT_SYMBOL(nss_ipsec_tx_msg_sync); + +/* + * nss_ipsec_tx_buf + * Send data packet for ipsec processing + */ +nss_tx_status_t nss_ipsec_tx_buf(struct sk_buff *skb, uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[nss_top_main.ipsec_handler_id]; + + nss_trace("%px: IPsec If Tx packet, id:%d, data=%px", nss_ctx, if_num, skb->data); + + return nss_core_send_packet(nss_ctx, skb, if_num, H2N_BIT_FLAG_BUFFER_REUSABLE); +} +EXPORT_SYMBOL(nss_ipsec_tx_buf); + +/* + ********************************** + Register APIs + ********************************** + */ + +/* + * nss_ipsec_notify_register() + * register message notifier for the given interface (if_num) + */ +struct nss_ctx_instance *nss_ipsec_notify_register(uint32_t if_num, nss_ipsec_msg_callback_t cb, void *app_data) +{ + struct nss_top_instance *nss_top = &nss_top_main; + uint8_t core_id = nss_top->ipsec_handler_id; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_id]; + + if (if_num >= NSS_MAX_NET_INTERFACES) { + nss_warning("%px: notfiy register received for invalid interface %d", nss_ctx, if_num); + return NULL; + } + + /* + * the encap is primary interface + */ + if (if_num == NSS_IPSEC_ENCAP_INTERFACE_NUM) { + nss_top->ipsec_encap_callback = cb; + nss_top->ipsec_encap_ctx = app_data; + return nss_ctx; + } + + nss_top->ipsec_decap_callback = cb; + nss_top->ipsec_decap_ctx = app_data; + return nss_ctx; +} +EXPORT_SYMBOL(nss_ipsec_notify_register); + +/* + * nss_ipsec_notify_unregister() + * unregister the IPsec notifier for the given interface number (if_num) + */ +void nss_ipsec_notify_unregister(struct nss_ctx_instance *nss_ctx, uint32_t if_num) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + + if (if_num >= NSS_MAX_NET_INTERFACES) { + nss_warning("%px: notify unregister received for invalid interface %d", nss_ctx, if_num); + return; + } + + /* + * the encap is primary interface + */ + if (if_num == NSS_IPSEC_ENCAP_INTERFACE_NUM) { + nss_top->ipsec_encap_callback = NULL; + nss_top->ipsec_encap_ctx = NULL; + return; + } + + nss_top->ipsec_decap_callback = NULL; + nss_top->ipsec_decap_ctx = NULL; +} +EXPORT_SYMBOL(nss_ipsec_notify_unregister); + +/* + * nss_ipsec_data_register() + * register a data callback routine + */ +struct nss_ctx_instance *nss_ipsec_data_register(uint32_t if_num, nss_ipsec_buf_callback_t cb, struct net_device *netdev, uint32_t features) +{ + struct nss_ctx_instance *nss_ctx, *nss_ctx0; + + nss_ctx = &nss_top_main.nss[nss_top_main.ipsec_handler_id]; + + if ((if_num >= NSS_MAX_NET_INTERFACES) && (if_num < NSS_MAX_PHYSICAL_INTERFACES)){ + nss_warning("%px: data register received for invalid interface %d", nss_ctx, if_num); + return NULL; + } + + /* + * avoid multiple registeration for multiple tunnels + */ + if (nss_ctx->subsys_dp_register[if_num].cb) { + return nss_ctx; + } + + nss_core_register_subsys_dp(nss_ctx, if_num, cb, NULL, NULL, netdev, features); + + if (nss_top_main.ipsec_handler_id == 1) { + nss_ctx0 = &nss_top_main.nss[0]; + + nss_core_register_subsys_dp(nss_ctx0, if_num, cb, NULL, NULL, netdev, features); + } + + return nss_ctx; +} +EXPORT_SYMBOL(nss_ipsec_data_register); + +/* + * nss_ipsec_data_unregister() + * unregister a data callback routine + */ +void nss_ipsec_data_unregister(struct nss_ctx_instance *nss_ctx, uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx0; + + if ((if_num >= NSS_MAX_NET_INTERFACES) && (if_num < NSS_MAX_PHYSICAL_INTERFACES)){ + nss_warning("%px: data unregister received for invalid interface %d", nss_ctx, if_num); + return; + } + + if (nss_top_main.ipsec_handler_id == 1) { + nss_ctx0 = &nss_top_main.nss[0]; + + nss_core_unregister_subsys_dp(nss_ctx0, if_num); + } + + nss_core_unregister_subsys_dp(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_ipsec_data_unregister); + +/* + * nss_ipsec_get_encap_interface() + * Get the NSS interface number for encap message + */ +int32_t nss_ipsec_get_encap_interface(void) +{ + return NSS_IPSEC_ENCAP_INTERFACE_NUM; +} +EXPORT_SYMBOL(nss_ipsec_get_encap_interface); + +/* + * nss_ipsec_get_decap_interface() + * Get the NSS interface number for decap message + */ +int32_t nss_ipsec_get_decap_interface(void) +{ + return NSS_IPSEC_DECAP_INTERFACE_NUM; +} +EXPORT_SYMBOL(nss_ipsec_get_decap_interface); + +/* + * nss_ipsec_get_data_interface() + * Get the NSS interface number used for data path + */ +int32_t nss_ipsec_get_data_interface(void) +{ + return NSS_IPSEC_DATA_INTERFACE_NUM; +} +EXPORT_SYMBOL(nss_ipsec_get_data_interface); + +/* + * nss_ipsec_get_context() + * Get NSS context instance for IPsec handle + */ +struct nss_ctx_instance *nss_ipsec_get_context(void) +{ + return &nss_top_main.nss[nss_top_main.ipsec_handler_id]; +} +EXPORT_SYMBOL(nss_ipsec_get_context); + +/* + * nss_ipsec_get_ifnum() + * Return IPsec interface number with coreid. + */ +int32_t nss_ipsec_get_ifnum(int32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = nss_ipsec_get_context(); + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + return NSS_INTERFACE_NUM_APPEND_COREID(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_ipsec_get_ifnum); + +/* + * nss_ipsec_ppe_port_config() + * Configure PPE port for IPsec inline + */ +bool nss_ipsec_ppe_port_config(struct nss_ctx_instance *nss_ctx, struct net_device *netdev, + uint32_t if_num, uint32_t vsi_num) +{ +#ifdef NSS_PPE_SUPPORTED + if_num = NSS_INTERFACE_NUM_APPEND_COREID(nss_ctx, if_num); + + if (nss_ppe_tx_ipsec_config_msg(if_num, vsi_num, netdev->mtu, netdev->mtu) != NSS_TX_SUCCESS) { + nss_warning("%px: Failed to configure PPE IPsec port", nss_ctx); + return false; + } + + return true; +#else + return false; +#endif +} +EXPORT_SYMBOL(nss_ipsec_ppe_port_config); + +/* + * nss_ipsec_ppe_mtu_update() + * Update PPE MTU for IPsec inline + */ +bool nss_ipsec_ppe_mtu_update(struct nss_ctx_instance *nss_ctx, uint32_t if_num, uint16_t mtu, uint16_t mru) +{ +#ifdef NSS_PPE_SUPPORTED + if_num = NSS_INTERFACE_NUM_APPEND_COREID(nss_ctx, if_num); + + if (nss_ppe_tx_ipsec_mtu_msg(if_num, mtu, mru) != NSS_TX_SUCCESS) { + nss_warning("%px: Failed to update PPE MTU for IPsec port", nss_ctx); + return false; + } + + return true; +#else + return false; +#endif +} +EXPORT_SYMBOL(nss_ipsec_ppe_mtu_update); + +/* + * nss_ipsec_register_handler() + */ +void nss_ipsec_register_handler() +{ + struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[nss_top_main.ipsec_handler_id]; + + BUILD_BUG_ON(NSS_IPSEC_ENCAP_INTERFACE_NUM < 0); + BUILD_BUG_ON(NSS_IPSEC_DECAP_INTERFACE_NUM < 0); + + sema_init(&nss_ipsec.sem, 1); + init_completion(&nss_ipsec.complete); + atomic_set(&nss_ipsec.resp, NSS_IPSEC_ERROR_TYPE_NONE); + + nss_ctx->nss_top->ipsec_encap_callback = NULL; + nss_ctx->nss_top->ipsec_decap_callback = NULL; + + nss_ctx->nss_top->ipsec_encap_ctx = NULL; + nss_ctx->nss_top->ipsec_decap_ctx = NULL; + + nss_core_register_handler(nss_ctx, NSS_IPSEC_ENCAP_INTERFACE_NUM, nss_ipsec_msg_handler, NULL); + nss_core_register_handler(nss_ctx, NSS_IPSEC_DECAP_INTERFACE_NUM, nss_ipsec_msg_handler, NULL); +} + +/* + * nss_ipsec_msg_init() + * Initialize ipsec message. + */ +void nss_ipsec_msg_init(struct nss_ipsec_msg *nim, uint16_t if_num, uint32_t type, uint32_t len, + nss_ipsec_msg_callback_t cb, void *app_data) +{ + nss_cmn_msg_init(&nim->cm, if_num, type, len, (void *)cb, app_data); +} +EXPORT_SYMBOL(nss_ipsec_msg_init); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipsec_cmn.c b/feeds/ipq807x/qca-nss-drv/src/nss_ipsec_cmn.c new file mode 100644 index 000000000..0b6185776 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipsec_cmn.c @@ -0,0 +1,611 @@ +/* + ************************************************************************** + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_dynamic_interface.h" +#include "nss_ipsec_cmn.h" +#include "nss_ppe.h" +#include "nss_ipsec_cmn_log.h" + +#define NSS_IPSEC_CMN_TX_TIMEOUT 3000 /* 3 Seconds */ +#define NSS_IPSEC_CMN_INTERFACE_MAX_LONG BITS_TO_LONGS(NSS_MAX_NET_INTERFACES) +#define NSS_IPSEC_CMN_STATS_MAX_LINES (NSS_STATS_NODE_MAX + 32) +#define NSS_IPSEC_CMN_STATS_SIZE_PER_IF (NSS_STATS_MAX_STR_LENGTH * NSS_IPSEC_CMN_STATS_MAX_LINES) + +/* + * Private data structure for handling synchronous messaging. + */ +static struct nss_ipsec_cmn_pvt { + struct semaphore sem; + struct completion complete; + struct nss_ipsec_cmn_msg nicm; + unsigned long if_map[NSS_IPSEC_CMN_INTERFACE_MAX_LONG]; +} ipsec_cmn_pvt; + +/* + * nss_ipsec_cmn_stats_sync() + * Update ipsec_cmn node statistics. + */ +static void nss_ipsec_cmn_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm) +{ + struct nss_ipsec_cmn_msg *nicm = (struct nss_ipsec_cmn_msg *)ncm; + struct nss_top_instance *nss_top = nss_ctx->nss_top; + struct nss_cmn_node_stats *msg_stats = &nicm->msg.ctx_sync.stats.cmn_stats; + uint64_t *if_stats; + int8_t i; + + spin_lock_bh(&nss_top->stats_lock); + + /* + * Update common node stats, + * Note: DTLS only supports a single queue for RX + */ + if_stats = nss_top->stats_node[ncm->interface]; + if_stats[NSS_STATS_NODE_RX_PKTS] += msg_stats->rx_packets; + if_stats[NSS_STATS_NODE_RX_BYTES] += msg_stats->rx_bytes; + + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + if_stats[NSS_STATS_NODE_RX_QUEUE_0_DROPPED + i] += msg_stats->rx_dropped[i]; + } + + if_stats[NSS_STATS_NODE_TX_PKTS] += msg_stats->tx_packets; + if_stats[NSS_STATS_NODE_TX_BYTES] += msg_stats->tx_bytes; + + spin_unlock_bh(&nss_top->stats_lock); +} + +/* + * nss_ipsec_cmn_stats_read() + * Read ipsec_cmn node statistics. + */ +static ssize_t nss_ipsec_cmn_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + struct nss_ctx_instance *nss_ctx = nss_ipsec_cmn_get_context(); + enum nss_dynamic_interface_type type; + ssize_t bytes_read = 0; + size_t len = 0, size; + uint32_t if_num; + char *buf; + + size = NSS_IPSEC_CMN_STATS_SIZE_PER_IF * bitmap_weight(ipsec_cmn_pvt.if_map, NSS_MAX_NET_INTERFACES); + + buf = kzalloc(size, GFP_KERNEL); + if (!buf) { + nss_warning("Could not allocate memory for local statistics buffer\n"); + return 0; + } + + len += nss_stats_banner(buf, len, size, "ipsec_cmn", NSS_STATS_SINGLE_CORE); + + /* + * Common node stats for each IPSEC dynamic interface. + */ + for_each_set_bit(if_num, ipsec_cmn_pvt.if_map, NSS_MAX_NET_INTERFACES) { + + type = nss_dynamic_interface_get_type(nss_ctx, if_num); + switch (type) { + case NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_INNER: + len += scnprintf(buf + len, size - len, "\nInner if_num:%03u", if_num); + break; + + case NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_MDATA_INNER: + len += scnprintf(buf + len, size - len, "\nMetadata inner if_num:%03u", if_num); + break; + + case NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_OUTER: + len += scnprintf(buf + len, size - len, "\nOuter if_num:%03u", if_num); + break; + + case NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_MDATA_OUTER: + len += scnprintf(buf + len, size - len, "\nMetadata outer if_num:%03u", if_num); + break; + + default: + len += scnprintf(buf + len, size - len, "\nUnknown(%d) if_num:%03u", type, if_num); + break; + } + + len += scnprintf(buf + len, size - len, "\n-------------------\n"); + len += nss_stats_fill_common_stats(if_num, NSS_STATS_SINGLE_INSTANCE, buf, len, size - len, "ipsec_cmn"); + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, buf, len); + kfree(buf); + + return bytes_read; +} + +/* + * nss_ipsec_cmn_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(ipsec_cmn) + +/* + * nss_ipsec_cmn_verify_ifnum() + * Verify if the interface number is a IPsec interface. + */ +static bool nss_ipsec_cmn_verify_ifnum(struct nss_ctx_instance *nss_ctx, uint32_t if_num) +{ + enum nss_dynamic_interface_type type = nss_dynamic_interface_get_type(nss_ctx, if_num); + + if (if_num == NSS_IPSEC_CMN_INTERFACE) + return true; + + switch (type) { + case NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_INNER: + case NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_OUTER: + case NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_MDATA_INNER: + case NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_MDATA_OUTER: + case NSS_DYNAMIC_INTERFACE_TYPE_IPSEC_CMN_REDIRECT: + return true; + + default: + return false; + } + + return false; +} + +/* + * nss_ipsec_cmn_msg_handler() + * Handle NSS -> HLOS messages for IPSEC tunnel. + */ +static void nss_ipsec_cmn_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, void *app_data) +{ + nss_ipsec_cmn_msg_callback_t cb; + struct nss_ipsec_cmn_msg *nim; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + /* + * Trace messages. + */ + nim = (struct nss_ipsec_cmn_msg *)ncm; + nss_ipsec_cmn_log_rx_msg(nim); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_IPSEC_CMN_MSG_TYPE_MAX) { + nss_warning("%px: Invalid message type(%u) for interface(%u)\n", nss_ctx, ncm->type, ncm->interface); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_ipsec_cmn_msg)) { + nss_warning("%px: Invalid message length(%d)\n", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + if (ncm->type == NSS_IPSEC_CMN_MSG_TYPE_CTX_SYNC) + nss_ipsec_cmn_stats_sync(nss_ctx, ncm); + + /* + * Update the callback and app_data for NOTIFY messages, ipsec_cmn sends all notify messages + * to the same callback/app_data. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_core_get_msg_handler(nss_ctx, ncm->interface); + ncm->app_data = (nss_ptr_t)nss_ctx->nss_rx_interface_handlers[ncm->interface].app_data; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Callback + */ + cb = (nss_ipsec_cmn_msg_callback_t)ncm->cb; + app_data = (void *)ncm->app_data; + + /* + * Call IPsec message callback + */ + if (!cb) { + nss_warning("%px: No callback for IPsec interface %d\n", nss_ctx, ncm->interface); + return; + } + + nss_trace("%px: calling ipsecsmgr message handler(%u)\n", nss_ctx, ncm->interface); + cb(app_data, ncm); +} + +/* + * nss_ipsec_cmn_sync_resp() + * Callback to handle the completion of HLOS-->NSS messages. + */ +static void nss_ipsec_cmn_sync_resp(void *app_data, struct nss_cmn_msg *ncm) +{ + struct nss_ipsec_cmn_msg *pvt_msg = app_data; + struct nss_ipsec_cmn_msg *resp_msg = container_of(ncm, struct nss_ipsec_cmn_msg, cm); + + /* + * Copy response message to pvt message + */ + memcpy(pvt_msg, resp_msg, sizeof(*resp_msg)); + + /* + * Write memory barrier + */ + smp_wmb(); + + complete(&ipsec_cmn_pvt.complete); +} + +/* + * nss_ipsec_cmn_get_context() + * Retrieve context for IPSEC redir. + */ +struct nss_ctx_instance *nss_ipsec_cmn_get_context(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.ipsec_handler_id]; +} +EXPORT_SYMBOL(nss_ipsec_cmn_get_context); + +/* + * nss_ipsec_cmn_get_ifnum_with_coreid() + * Return IPsec interface number with coreid. + */ +uint32_t nss_ipsec_cmn_get_ifnum_with_coreid(int32_t ifnum) +{ + struct nss_ctx_instance *nss_ctx = nss_ipsec_cmn_get_context(); + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + return NSS_INTERFACE_NUM_APPEND_COREID(nss_ctx, ifnum); +} +EXPORT_SYMBOL(nss_ipsec_cmn_get_ifnum_with_coreid); + +/* + * nss_ipsec_cmn_msg_init() + * Initialize message + */ +void nss_ipsec_cmn_msg_init(struct nss_ipsec_cmn_msg *nim, uint16_t if_num, enum nss_ipsec_cmn_msg_type type, + uint16_t len, nss_ipsec_cmn_msg_callback_t cb, void *app_data) +{ + nss_cmn_msg_init(&nim->cm, if_num, type, len, cb, app_data); +} +EXPORT_SYMBOL(nss_ipsec_cmn_msg_init); + +/* + * nss_ipsec_cmn_tx_msg() + * Transmit a IPSEC message to NSS FW. + */ +nss_tx_status_t nss_ipsec_cmn_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_ipsec_cmn_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Trace messages. + */ + nss_ipsec_cmn_log_tx_msg(msg); + + /* + * Sanity check the message + */ + if (ncm->type >= NSS_IPSEC_CMN_MSG_TYPE_MAX) { + nss_warning("%px: Invalid message type(%u)\n", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + if (!nss_ipsec_cmn_verify_ifnum(nss_ctx, ncm->interface)) { + nss_warning("%px: Invalid message interface(%u)\n", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_ipsec_cmn_msg)) { + nss_warning("%px: Invalid message length(%u)\n", nss_ctx, nss_cmn_get_msg_len(ncm)); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_ipsec_cmn_tx_msg); + +/* + * nss_ipsec_cmn_tx_msg_sync() + * Transmit a IPSEC redir message to NSS firmware synchronously. + */ +nss_tx_status_t nss_ipsec_cmn_tx_msg_sync(struct nss_ctx_instance *nss_ctx, uint32_t if_num, + enum nss_ipsec_cmn_msg_type type, uint16_t len, + struct nss_ipsec_cmn_msg *nicm) +{ + struct nss_ipsec_cmn_msg *local_nicm = &ipsec_cmn_pvt.nicm; + nss_tx_status_t status; + int ret = 0; + + /* + * Length of the message should be the based on type + */ + if (len > sizeof(struct nss_ipsec_cmn_msg)) { + nss_warning("%px: Invalid message length(%u), type (%d), I/F(%u)\n", nss_ctx, len, type, if_num); + return NSS_TX_FAILURE; + } + + down(&ipsec_cmn_pvt.sem); + + /* + * We need to copy the message content into the actual message + * to be sent to NSS + */ + memset(local_nicm, 0, sizeof(*local_nicm)); + + nss_ipsec_cmn_msg_init(local_nicm, if_num, type, len, nss_ipsec_cmn_sync_resp, local_nicm); + memcpy(&local_nicm->msg, &nicm->msg, len); + + status = nss_ipsec_cmn_tx_msg(nss_ctx, local_nicm); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: Failed to send message\n", nss_ctx); + goto done; + } + + ret = wait_for_completion_timeout(&ipsec_cmn_pvt.complete, msecs_to_jiffies(NSS_IPSEC_CMN_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: Failed to receive response, timeout(%d)\n", nss_ctx, ret); + status = NSS_TX_FAILURE_NOT_READY; + goto done; + } + + /* + * Read memory barrier + */ + smp_rmb(); + + if (local_nicm->cm.response != NSS_CMN_RESPONSE_ACK) { + status = NSS_TX_FAILURE; + nicm->cm.response = local_nicm->cm.response; + nicm->cm.error = local_nicm->cm.error; + goto done; + } + + /* + * Copy the message received + */ + memcpy(&nicm->msg, &local_nicm->msg, len); + +done: + up(&ipsec_cmn_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_ipsec_cmn_tx_msg_sync); + +/* + * nss_ipsec_cmn_tx_buf() + * Send packet to IPsec interface in NSS. + */ +nss_tx_status_t nss_ipsec_cmn_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf, uint32_t if_num) +{ + nss_trace("%px: Send to IPsec I/F(%u), skb(%px)\n", nss_ctx, if_num, os_buf); + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (!nss_ipsec_cmn_verify_ifnum(nss_ctx, if_num)) { + nss_warning("%px: Interface number(%d) is not IPSec type\n", nss_ctx, if_num); + return NSS_TX_FAILURE; + } + + return nss_core_send_packet(nss_ctx, os_buf, if_num, H2N_BIT_FLAG_BUFFER_REUSABLE); +} +EXPORT_SYMBOL(nss_ipsec_cmn_tx_buf); + +/* + * nss_ipsec_cmn_register_if() + * Register dynamic node for IPSEC redir. + */ +struct nss_ctx_instance *nss_ipsec_cmn_register_if(uint32_t if_num, struct net_device *netdev, + nss_ipsec_cmn_data_callback_t cb_data, + nss_ipsec_cmn_msg_callback_t cb_msg, + uint32_t features, enum nss_dynamic_interface_type type, void *app_ctx) +{ + struct nss_ctx_instance *nss_ctx = nss_ipsec_cmn_get_context(); + uint32_t status; + + if (!nss_ipsec_cmn_verify_ifnum(nss_ctx, if_num)) { + nss_warning("%px: Invalid IPsec interface(%u)\n", nss_ctx, if_num); + return NULL; + } + + if (nss_ctx->subsys_dp_register[if_num].ndev) { + nss_warning("%px: Failed find free slot for IPsec NSS I/F:%u\n", nss_ctx, if_num); + return NULL; + } + +#ifdef NSS_DRV_PPE_ENABLE + if (features & NSS_IPSEC_CMN_FEATURE_INLINE_ACCEL) + nss_ppe_tx_ipsec_add_intf_msg(nss_ipsec_cmn_get_ifnum_with_coreid(if_num)); +#endif + + /* + * Registering handler for sending tunnel interface msgs to NSS. + */ + status = nss_core_register_handler(nss_ctx, if_num, nss_ipsec_cmn_msg_handler, app_ctx); + if (status != NSS_CORE_STATUS_SUCCESS){ + nss_warning("%px: Failed to register message handler for IPsec NSS I/F:%u\n", nss_ctx, if_num); + return NULL; + } + + status = nss_core_register_msg_handler(nss_ctx, if_num, cb_msg); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_core_unregister_handler(nss_ctx, if_num); + nss_warning("%px: Failed to register message handler for IPsec NSS I/F:%u\n", nss_ctx, if_num); + return NULL; + } + + nss_core_register_subsys_dp(nss_ctx, if_num, cb_data, NULL, app_ctx, netdev, features); + nss_core_set_subsys_dp_type(nss_ctx, netdev, if_num, type); + + /* + * Atomically set the bitmap for the interface number + */ + set_bit(if_num, ipsec_cmn_pvt.if_map); + + return nss_ctx; +} +EXPORT_SYMBOL(nss_ipsec_cmn_register_if); + +/* + * nss_ipsec_cmn_unregister_if() + * Unregister dynamic node for IPSEC redir. + */ +bool nss_ipsec_cmn_unregister_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = nss_ipsec_cmn_get_context(); + struct net_device *dev; + uint32_t status; + + nss_assert(nss_ctx); + + if (!nss_ipsec_cmn_verify_ifnum(nss_ctx, if_num)) { + nss_warning("%px: Invalid IPsec interface(%u)\n", nss_ctx, if_num); + return false; + } + + dev = nss_cmn_get_interface_dev(nss_ctx, if_num); + if (!dev) { + nss_warning("%px: Failed to find registered netdev for IPsec NSS I/F:%u\n", nss_ctx, if_num); + return false; + } + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + + /* + * Atomically clear the bitmap for the interface number + */ + clear_bit(if_num, ipsec_cmn_pvt.if_map); + + status = nss_core_unregister_msg_handler(nss_ctx, if_num); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Failed to unregister handler for IPsec NSS I/F:%u\n", nss_ctx, if_num); + return false; + } + + status = nss_core_unregister_handler(nss_ctx, if_num); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Failed to unregister handler for IPsec NSS I/F:%u\n", nss_ctx, if_num); + return false; + } + + return true; +} +EXPORT_SYMBOL(nss_ipsec_cmn_unregister_if); + +/* + * nss_ipsec_cmn_notify_register() + * Register a handler for notification from NSS firmware. + */ +struct nss_ctx_instance *nss_ipsec_cmn_notify_register(uint32_t if_num, nss_ipsec_cmn_msg_callback_t cb, void *app_data) +{ + struct nss_ctx_instance *nss_ctx = nss_ipsec_cmn_get_context(); + uint32_t ret; + + BUG_ON(!nss_ctx); + + ret = nss_core_register_handler(nss_ctx, if_num, nss_ipsec_cmn_msg_handler, app_data); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: unable to register event handler for interface(%u)\n", nss_ctx, if_num); + return NULL; + } + + ret = nss_core_register_msg_handler(nss_ctx, if_num, cb); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_core_unregister_handler(nss_ctx, if_num); + nss_warning("%px: Failed to register message handler for IPsec NSS I/F:%u\n", nss_ctx, if_num); + return NULL; + } + + return nss_ctx; +} +EXPORT_SYMBOL(nss_ipsec_cmn_notify_register); + +/* + * nss_ipsec_cmn_notify_unregister() + * unregister the IPsec notifier for the given interface number (if_num) + */ +void nss_ipsec_cmn_notify_unregister(struct nss_ctx_instance *nss_ctx, uint32_t if_num) +{ + uint32_t ret; + + if (if_num >= NSS_MAX_NET_INTERFACES) { + nss_warning("%px: notify unregister received for invalid interface %d\n", nss_ctx, if_num); + return; + } + + ret = nss_core_unregister_msg_handler(nss_ctx, if_num); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: unable to unregister event handler for interface(%u)\n", nss_ctx, if_num); + return; + } + + ret = nss_core_unregister_handler(nss_ctx, if_num); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: unable to unregister event handler for interface(%u)\n", nss_ctx, if_num); + return; + } +} +EXPORT_SYMBOL(nss_ipsec_cmn_notify_unregister); + +/* + * nss_ipsec_cmn_ppe_port_config() + * Configure PPE port for IPsec inline + */ +bool nss_ipsec_cmn_ppe_port_config(struct nss_ctx_instance *nss_ctx, struct net_device *netdev, + uint32_t if_num, uint32_t vsi_num) +{ +#ifdef NSS_PPE_SUPPORTED + if_num = NSS_INTERFACE_NUM_APPEND_COREID(nss_ctx, if_num); + + if (nss_ppe_tx_ipsec_config_msg(if_num, vsi_num, netdev->mtu, netdev->mtu) != NSS_TX_SUCCESS) { + nss_warning("%px: Failed to configure PPE IPsec port\n", nss_ctx); + return false; + } + + return true; +#else + return false; +#endif +} +EXPORT_SYMBOL(nss_ipsec_cmn_ppe_port_config); + +/* + * nss_ipsec_cmn_ppe_mtu_update() + * Update PPE MTU for IPsec inline + */ +bool nss_ipsec_cmn_ppe_mtu_update(struct nss_ctx_instance *nss_ctx, uint32_t if_num, uint16_t mtu, uint16_t mru) +{ +#ifdef NSS_PPE_SUPPORTED + if_num = NSS_INTERFACE_NUM_APPEND_COREID(nss_ctx, if_num); + + if (nss_ppe_tx_ipsec_mtu_msg(if_num, mtu, mru) != NSS_TX_SUCCESS) { + nss_warning("%px: Failed to update PPE MTU for IPsec port\n", nss_ctx); + return false; + } + + return true; +#else + return false; +#endif +} +EXPORT_SYMBOL(nss_ipsec_cmn_ppe_mtu_update); + +/* + * nss_ipsec_cmn_register_handler() + * Registering handler for sending msg to base ipsec_cmn node on NSS. + */ +void nss_ipsec_cmn_register_handler(void) +{ + sema_init(&ipsec_cmn_pvt.sem, 1); + init_completion(&ipsec_cmn_pvt.complete); + nss_stats_create_dentry("ipsec_cmn", &nss_ipsec_cmn_stats_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipsec_cmn_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_ipsec_cmn_log.c new file mode 100644 index 000000000..8ae7928f9 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipsec_cmn_log.c @@ -0,0 +1,354 @@ +/* + ************************************************************************** + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_ipsec_cmn_log.c + * NSS IPSEC logger file. + */ + +#include "nss_core.h" + +#define NSS_IPSEC_LOG_IPV4 4 +#define NSS_IPSEC_LOG_IPV6 6 + +/* + * nss_ipsec_cmn_log_msg_types_str + * IPSEC message strings + */ +static int8_t *nss_ipsec_cmn_log_msg_types_str[NSS_IPSEC_CMN_MSG_TYPE_MAX] __maybe_unused = { + "IPSEC CMN Msg None", + "IPSEC CMN Node Config", + "IPSEC CMN CTX Config", + "IPSEC CMN CTX Sync", + "IPSEC CMN SA Create", + "IPSEC CMN SA Destroy", + "IPSEC CMN SA Sync", + "IPSEC CMN Flow Create", + "IPSEC CMN Flow Destroy", +}; + +/* + * nss_ipsec_cmn_log_node_msg_types_str + * IPSEC cmn node message strings + */ +static int8_t *nss_ipsec_cmn_log_node_str[] __maybe_unused = { + "IPSEC CMN Node DMA Redirect", + "IPSEC CMN Node DMA Lookaside", + "IPSEC CMN Node Maximum SA", +}; + +/* + * nss_ipsec_cmn_log_ctx_msg_types_str + * IPSEC cmn ctx message strings + */ +static int8_t *nss_ipsec_cmn_log_ctx_str[] __maybe_unused = { + "IPSEC CMN CTX Type", + "IPSEC CMN CTX Exception Interface", +}; + +/* + * nss_ipsec_cmn_log_ctx_types_str + * IPSEC cmn context strings + */ +static int8_t *nss_ipsec_cmn_ctx_types_str[] __maybe_unused = { + "IPSEC CMN CTX NONE", + "IPSEC CMN CTX INNER", + "IPSEC CMN CTX INNER BOUNCE", + "IPSEC CMN CTX OUTER", + "IPSEC CMN CTX OUTER BOUNCE", + "IPSEC CMN CTX REDIRECT", +}; + +/* + * nss_ipsec_cmn_log_flow_tuple_str + * IPSEC cmn flow tuple strings + */ +static int8_t *nss_ipsec_cmn_log_flow_tuple_str[] __maybe_unused = { + "Dest IP", + "Src IP", + "Spi Index", + "Dest Port", + "Src Port", + "User Pattern", + "User Protocol", + "IP Version", +}; + +/* + * nss_ipsec_cmn_log_sa_tuple_str + * IPSEC cmn SA tuple strings + */ +static int8_t *nss_ipsec_cmn_log_sa_tuple_str[] __maybe_unused = { + "Dest IP", + "Src IP", + "Spi Index", + "Dest Port", + "Src Port", + "Crypto Index", + "Protocol", + "IP Version", + "Hop Limit", +}; + +/* + * nss_ipsec_cmn_log_sa_data_str + * IPSEC cmn SA tuple strings + */ +static int8_t *nss_ipsec_cmn_log_sa_data_str[] __maybe_unused = { + "Sequence Start", + "Flags", + "Window Size", + "DSCP", + "DF", + "Block Length", + "IV length", + "ICV length", +}; + +/* + * nss_ipsec_cmn_log_error_str + * Strings for error types for IPSEC messages + */ +static int8_t *nss_ipsec_cmn_log_error_str[NSS_IPSEC_CMN_MSG_ERROR_MAX] __maybe_unused = { + "IPSEC No Error", + "IPSEC Invalid Context", + "IPSEC SA allocation Error", + "IPSEC Invalid SA", + "IPSEC Duplicate SA", + "IPSEC SA is in Use", + "IPSEC Error in Flow Allocation", + "IPSEC Invalid Flow", + "IPSEC Duplicate Flow", + "IPSEC Failure to find SA for Flow", + "IPSEC Failed to Register Dynamic Interface", + "IPSEC Unhandled Message", +}; + +/* + * nss_ipsec_cmn_log_node_msg() + * Log NSS IPSEC node message. + */ +static void nss_ipsec_cmn_log_node_msg(struct nss_ipsec_cmn_msg *nim) +{ + struct nss_ipsec_cmn_node *node_msg __maybe_unused = &nim->msg.node; + + nss_trace("%px: NSS IPSEC Node Message:\n" + "%s: %d\n" + "%s: %d\n" + "%s: %d\n", nim, + nss_ipsec_cmn_log_node_str[0], node_msg->dma_redirect, + nss_ipsec_cmn_log_node_str[1], node_msg->dma_lookaside, + nss_ipsec_cmn_log_node_str[2], node_msg->max_sa); +} + +/* + * nss_ipsec_cmn_log_ctx_msg() + * Log NSS IPSEC ctx message. + */ +static void nss_ipsec_cmn_log_ctx_msg(struct nss_ipsec_cmn_msg *nim) +{ + struct nss_ipsec_cmn_ctx *ctx_msg __maybe_unused = &nim->msg.ctx; + + nss_trace("%px: NSS IPSEC CTX Message:\n" + "%s: %s\n" + "%s: %d\n", nim, + nss_ipsec_cmn_log_ctx_str[0], nss_ipsec_cmn_ctx_types_str[ctx_msg->type], + nss_ipsec_cmn_log_ctx_str[1], ctx_msg->except_ifnum); +} + +/* + * nss_ipsec_cmn_log_sa_msg() + * Log NSS IPSEC SA message. + */ +static void nss_ipsec_cmn_log_sa_msg(struct nss_ipsec_cmn_msg *nim) +{ + struct nss_ipsec_cmn_sa *sa_msg __maybe_unused = &nim->msg.sa; + struct nss_ipsec_cmn_sa_tuple *tuple = &sa_msg->sa_tuple; + struct nss_ipsec_cmn_sa_data *data __maybe_unused = &sa_msg->sa_data; + + nss_trace("%px: NSS IPSEC SA Message:\n", nim); + + if (tuple->ip_ver == 4) { + nss_trace("%s: %pI4\n%s: %pI4\n", + nss_ipsec_cmn_log_sa_tuple_str[0], tuple->dest_ip, + nss_ipsec_cmn_log_sa_tuple_str[1], tuple->src_ip); + } else { + nss_trace("%s: %pI6\n%s: %pI6\n", + nss_ipsec_cmn_log_sa_tuple_str[0], tuple->dest_ip, + nss_ipsec_cmn_log_sa_tuple_str[1], tuple->src_ip); + } + + nss_trace( "%s: %x\n%s: %d\n%s: %d\n%s: %d\n" + "%s: %d\n%s: %d\n%s: %d\n" + "%s: %d\n%s: %x\n%s: %d\n%s: %d\n" + "%s: %d\n%s: %d\n%s: %d\n%s: %d\n", + nss_ipsec_cmn_log_sa_tuple_str[2], tuple->spi_index, + nss_ipsec_cmn_log_sa_tuple_str[3], tuple->dest_port, + nss_ipsec_cmn_log_sa_tuple_str[4], tuple->src_port, + nss_ipsec_cmn_log_sa_tuple_str[5], tuple->crypto_index, + nss_ipsec_cmn_log_sa_tuple_str[6], tuple->protocol, + nss_ipsec_cmn_log_sa_tuple_str[7], tuple->ip_ver, + nss_ipsec_cmn_log_sa_tuple_str[8], tuple->hop_limit, + + nss_ipsec_cmn_log_sa_data_str[0], data->seq_start, + nss_ipsec_cmn_log_sa_data_str[1], data->flags, + nss_ipsec_cmn_log_sa_data_str[2], data->window_size, + nss_ipsec_cmn_log_sa_data_str[3], data->dscp, + nss_ipsec_cmn_log_sa_data_str[4], data->df, + nss_ipsec_cmn_log_sa_data_str[5], data->blk_len, + nss_ipsec_cmn_log_sa_data_str[6], data->iv_len, + nss_ipsec_cmn_log_sa_data_str[7], data->icv_len); + +} + +/* + * nss_ipsec_cmn_log_flow_msg() + * Log NSS IPSEC Flow message. + */ +static void nss_ipsec_cmn_log_flow_msg(struct nss_ipsec_cmn_msg *nim) +{ + struct nss_ipsec_cmn_flow *flow_msg __maybe_unused = &nim->msg.flow; + struct nss_ipsec_cmn_flow_tuple *flow = &flow_msg->flow_tuple; + struct nss_ipsec_cmn_sa_tuple *sa = &flow_msg->sa_tuple; + + nss_trace("%px: NSS IPSEC Flow Message:\n", nim); + + if (sa->ip_ver == 4) { + nss_trace("%s: %pI4\n%s: %pI4\n", + nss_ipsec_cmn_log_sa_tuple_str[0], sa->dest_ip, + nss_ipsec_cmn_log_sa_tuple_str[1], sa->src_ip); + } else { + nss_trace("%s: %pI6\n%s: %pI6\n", + nss_ipsec_cmn_log_sa_tuple_str[0], sa->dest_ip, + nss_ipsec_cmn_log_sa_tuple_str[1], sa->src_ip); + } + + if (flow->ip_ver == 4) { + nss_trace("%s: %pI4\n%s: %pI4\n", + nss_ipsec_cmn_log_sa_tuple_str[0], flow->dest_ip, + nss_ipsec_cmn_log_sa_tuple_str[1], flow->src_ip); + } else { + nss_trace("%s: %pI6\n%s: %pI6\n", + nss_ipsec_cmn_log_sa_tuple_str[0], flow->dest_ip, + nss_ipsec_cmn_log_sa_tuple_str[1], flow->src_ip); + } + + nss_trace( "%s: %x\n%s: %d\n%s: %d\n%s: %d\n" + "%s: %d\n", + nss_ipsec_cmn_log_flow_tuple_str[2], flow->spi_index, + nss_ipsec_cmn_log_flow_tuple_str[3], flow->dst_port, + nss_ipsec_cmn_log_flow_tuple_str[4], flow->src_port, + nss_ipsec_cmn_log_flow_tuple_str[5], flow->user_pattern, + nss_ipsec_cmn_log_flow_tuple_str[6], flow->protocol); + + nss_trace( "%s: %x\n%s: %d\n%s: %d\n%s: %d\n" + "%s: %d\n%s: %d\n%s: %d\n", + nss_ipsec_cmn_log_sa_tuple_str[2], sa->spi_index, + nss_ipsec_cmn_log_sa_tuple_str[3], sa->dest_port, + nss_ipsec_cmn_log_sa_tuple_str[4], sa->src_port, + nss_ipsec_cmn_log_sa_tuple_str[5], sa->crypto_index, + nss_ipsec_cmn_log_sa_tuple_str[6], sa->protocol, + nss_ipsec_cmn_log_sa_tuple_str[7], sa->ip_ver, + nss_ipsec_cmn_log_sa_tuple_str[8], sa->hop_limit); +} + +/* + * nss_ipsec_cmn_log_verbose() + * Log message contents. + */ +static void nss_ipsec_cmn_log_verbose(struct nss_ipsec_cmn_msg *nim) +{ + switch (nim->cm.type) { + case NSS_IPSEC_CMN_MSG_TYPE_NODE_CONFIG: + nss_ipsec_cmn_log_node_msg(nim); + break; + + case NSS_IPSEC_CMN_MSG_TYPE_CTX_CONFIG: + nss_ipsec_cmn_log_ctx_msg(nim); + break; + + case NSS_IPSEC_CMN_MSG_TYPE_SA_CREATE: + case NSS_IPSEC_CMN_MSG_TYPE_SA_DESTROY: + nss_ipsec_cmn_log_sa_msg(nim); + break; + + case NSS_IPSEC_CMN_MSG_TYPE_FLOW_CREATE: + case NSS_IPSEC_CMN_MSG_TYPE_FLOW_DESTROY: + nss_ipsec_cmn_log_flow_msg(nim); + break; + + case NSS_IPSEC_CMN_MSG_TYPE_CTX_SYNC: + case NSS_IPSEC_CMN_MSG_TYPE_SA_SYNC: + /* + * No log for these valid messages. + */ + break; + + default: + nss_warning("%px: Invalid message type\n", nim); + break; + } +} + +/* + * nss_ipsec_cmn_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_ipsec_cmn_log_tx_msg(struct nss_ipsec_cmn_msg *nim) +{ + if (nim->cm.type >= NSS_IPSEC_CMN_MSG_TYPE_MAX) { + nss_warning("%px: Invalid message type\n", nim); + return; + } + + nss_info("%px: type[%d]:%s\n", nim, nim->cm.type, nss_ipsec_cmn_log_msg_types_str[nim->cm.type]); + nss_ipsec_cmn_log_verbose(nim); +} + +/* + * nss_ipsec_cmn_log_rx_msg() + * Log messages received from FW. + */ +void nss_ipsec_cmn_log_rx_msg(struct nss_ipsec_cmn_msg *nim) +{ + if (nim->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", nim); + return; + } + + if (nim->cm.response == NSS_CMN_RESPONSE_NOTIFY || (nim->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", nim, nim->cm.type, + nss_ipsec_cmn_log_msg_types_str[nim->cm.type], + nim->cm.response, nss_cmn_response_str[nim->cm.response]); + goto verbose; + } + + if (nim->cm.error >= NSS_IPSEC_CMN_MSG_ERROR_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + nim, nim->cm.type, nss_ipsec_cmn_log_msg_types_str[nim->cm.type], + nim->cm.response, nss_cmn_response_str[nim->cm.response], + nim->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + nim, nim->cm.type, nss_ipsec_cmn_log_msg_types_str[nim->cm.type], + nim->cm.response, nss_cmn_response_str[nim->cm.response], + nim->cm.error, nss_ipsec_cmn_log_error_str[nim->cm.error]); + +verbose: + nss_ipsec_cmn_log_verbose(nim); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipsec_cmn_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_ipsec_cmn_log.h new file mode 100644 index 000000000..d99c8be4c --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipsec_cmn_log.h @@ -0,0 +1,37 @@ +/* + ****************************************************************************** + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_IPSEC_CMN_LOG_H__ +#define __NSS_IPSEC_CMN_LOG_H__ + +/* + * nss_ipsec_cmn_log.h + * NSS Crypto Log Header File + */ + +/* + * nss_ipsec_cmn_log_tx_msg + * Logs a ipsec message that is sent to the NSS firmware. + */ +void nss_ipsec_cmn_log_tx_msg(struct nss_ipsec_cmn_msg *nim); + +/* + * nss_ipsec_cmn_log_rx_msg + * Logs a ipsec message that is received from the NSS firmware. + */ +void nss_ipsec_cmn_log_rx_msg(struct nss_ipsec_cmn_msg *nim); + +#endif /* __NSS_IPSEC_CMN_LOG_H__ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipsec_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_ipsec_log.c new file mode 100644 index 000000000..2f1570efb --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipsec_log.c @@ -0,0 +1,205 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_ipsec_log.c + * NSS IPSEC logger file. + */ + +#include "nss_core.h" + +#define NSS_IPSEC_LOG_IPV4 4 +#define NSS_IPSEC_LOG_IPV6 6 + +/* + * nss_ipsec_log_message_types_str + * IPSEC message strings + */ +static int8_t *nss_ipsec_log_message_types_str[NSS_IPSEC_MSG_TYPE_MAX] __maybe_unused = { + "IPSEC Msg None", + "IPSEC ADD Rule", + "IPSEC DEL Rule", + "IPSEC Flush Tunnel", + "IPSEC SA Stats", + "IPSEC Flow Stats", + "IPSEC Node Stats", + "IPSEC Configure Node", +}; + +/* + * nss_ipsec_log_error_response_types_str + * Strings for error types for IPSEC messages + */ +static int8_t *nss_ipsec_log_error_response_types_str[NSS_IPSEC_ERROR_TYPE_MAX] __maybe_unused = { + "IPSEC No Error", + "IPSEC Hash Duplicate", + "IPSEC Hash Collision", + "IPSEC Unhandled Message", + "IPSEC Invalid Rule", + "IPSEC MAX SA", + "IPSEC MAX Flow", + "IPSEC Invalid CINDEX", + "IPSEC Invalid IP Version", +}; + +/* + * nss_ipsec_log_rule_msg() + * Log NSS IPSEC rule message. + */ +static void nss_ipsec_log_rule_msg(struct nss_ipsec_msg *nim) +{ + struct nss_ipsec_rule *nir __maybe_unused = &nim->msg.rule; + + nss_trace("%px: NSS IPSEC Rule Message:\n" + "IPSEC ESP SPI Index: %dn" + "IPSEC TTL Hop Limit: %dn" + "IPSEC IP Version: %x\n" + "IPSEC Crypto Index: %d\n" + "IPSEC Window Size: %d\n" + "IPSEC Cipher Block Len: %d\n" + "IPSEC Initialization Vector Length: %d\n" + "IPSEC NAT-T Required: %d\n" + "IPSEC ICV Length: %d\n" + "IPSEC Skip Seq Number: %d\n" + "IPSEC Skip ESP Trailer: %d\n" + "IPSEC Use Pattern: %d\n" + "IPSEC Enable Extended Sequence Number: %d\n" + "IPSEC DSCP Value: %d\n" + "IPSEC Don't Fragment Flag: %d\n" + "IPSEC DSCP Copy %d\n" + "IPSEC DF Copy: %d\n" + "IPSEC NSS Index: %d\n" + "IPSEC SA Index: %d\n", + nir, nir->oip.esp_spi, + nir->oip.ttl_hop_limit, nir->oip.ip_ver, + nir->data.crypto_index, nir->data.window_size, + nir->data.cipher_blk_len, nir->data.iv_len, + nir->data.nat_t_req, nir->data.esp_icv_len, + nir->data.esp_seq_skip, nir->data.esp_tail_skip, + nir->data.use_pattern, nir->data.enable_esn, + nir->data.dscp, nir->data.df, + nir->data.copy_dscp, nir->data.copy_df, + nir->index, nir->sa_idx); + + /* + * Continuation of previous log. Different identifiers based on ip_ver + */ + if (nir->oip.ip_ver == NSS_IPSEC_LOG_IPV6) { + nss_trace("IPSEC Destination Address: %pI6\n" + "IPSEC Source Address: %pI6\n", + nir->oip.dst_addr, nir->oip.src_addr); + } else if (nir->oip.ip_ver == NSS_IPSEC_LOG_IPV4) { + nss_trace("IPSEC Destination Address: %pI4\n" + "IPSEC Source Address: %pI4\n", + nir->oip.dst_addr, nir->oip.src_addr); + } +} + +/* + * nss_ipsec_log_configure_node_msg() + * Log NSS IPSEC configure node message. + */ +static void nss_ipsec_log_configure_node_msg(struct nss_ipsec_msg *nim) +{ + struct nss_ipsec_configure_node *nicn __maybe_unused = &nim->msg.node; + nss_trace("%px: NSS IPSEC Configure Node\n" + "IPSEC DMA Redirect: %d\n" + "IPSEC DMA Lookaside: %d\n", + nicn, nicn->dma_redirect, + nicn->dma_lookaside); +} + +/* + * nss_ipsec_log_verbose() + * Log message contents. + */ +static void nss_ipsec_log_verbose(struct nss_ipsec_msg *nim) +{ + switch (nim->cm.type) { + case NSS_IPSEC_MSG_TYPE_ADD_RULE: + case NSS_IPSEC_MSG_TYPE_DEL_RULE: + nss_ipsec_log_rule_msg(nim); + break; + + case NSS_IPSEC_MSG_TYPE_CONFIGURE_NODE: + nss_ipsec_log_configure_node_msg(nim); + break; + + case NSS_IPSEC_MSG_TYPE_NONE: + case NSS_IPSEC_MSG_TYPE_FLUSH_TUN: + case NSS_IPSEC_MSG_TYPE_SYNC_SA_STATS: + case NSS_IPSEC_MSG_TYPE_SYNC_FLOW_STATS: + case NSS_IPSEC_MSG_TYPE_SYNC_NODE_STATS: + /* + * No log for these valid messages. + */ + break; + + default: + nss_warning("%px: Invalid message type\n", nim); + break; + } +} + +/* + * nss_ipsec_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_ipsec_log_tx_msg(struct nss_ipsec_msg *nim) +{ + if (nim->cm.type >= NSS_IPSEC_MSG_TYPE_MAX) { + nss_warning("%px: Invalid message type\n", nim); + return; + } + + nss_info("%px: type[%d]:%s\n", nim, nim->cm.type, nss_ipsec_log_message_types_str[nim->cm.type]); + nss_ipsec_log_verbose(nim); +} + +/* + * nss_ipsec_log_rx_msg() + * Log messages received from FW. + */ +void nss_ipsec_log_rx_msg(struct nss_ipsec_msg *nim) +{ + if (nim->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", nim); + return; + } + + if (nim->cm.response == NSS_CMN_RESPONSE_NOTIFY || (nim->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", nim, nim->cm.type, + nss_ipsec_log_message_types_str[nim->cm.type], + nim->cm.response, nss_cmn_response_str[nim->cm.response]); + goto verbose; + } + + if (nim->cm.error >= NSS_IPSEC_ERROR_TYPE_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + nim, nim->cm.type, nss_ipsec_log_message_types_str[nim->cm.type], + nim->cm.response, nss_cmn_response_str[nim->cm.response], + nim->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + nim, nim->cm.type, nss_ipsec_log_message_types_str[nim->cm.type], + nim->cm.response, nss_cmn_response_str[nim->cm.response], + nim->cm.error, nss_ipsec_log_error_response_types_str[nim->cm.error]); + +verbose: + nss_ipsec_log_verbose(nim); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipsec_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_ipsec_log.h new file mode 100644 index 000000000..5342c208f --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipsec_log.h @@ -0,0 +1,37 @@ +/* + ****************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_IPSEC_LOG_H__ +#define __NSS_IPSEC_LOG_H__ + +/* + * nss_ipsec_log.h + * NSS Crypto Log Header File + */ + +/* + * nss_ipsec_log_tx_msg + * Logs a ipsec message that is sent to the NSS firmware. + */ +void nss_ipsec_log_tx_msg(struct nss_ipsec_msg *nim); + +/* + * nss_ipsec_log_rx_msg + * Logs a ipsec message that is received from the NSS firmware. + */ +void nss_ipsec_log_rx_msg(struct nss_ipsec_msg *nim); + +#endif /* __NSS_IPSEC_LOG_H__ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipv4.c b/feeds/ipq807x/qca-nss-drv/src/nss_ipv4.c new file mode 100644 index 000000000..579bc4449 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipv4.c @@ -0,0 +1,767 @@ +/* + ************************************************************************** + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_ipv4.c + * NSS IPv4 APIs + */ +#include +#include "nss_dscp_map.h" +#include "nss_ipv4_stats.h" +#include "nss_ipv4_strings.h" + +#define NSS_IPV4_TX_MSG_TIMEOUT 1000 /* 1 sec timeout for IPv4 messages */ + +/* + * Private data structure for ipv4 configuration + */ +struct nss_ipv4_pvt { + struct semaphore sem; /* Semaphore structure */ + struct completion complete; /* completion structure */ + int response; /* Response from FW */ + void *cb; /* Original cb for sync msgs */ + void *app_data; /* Original app_data for sync msgs */ +} nss_ipv4_pvt; + +/* + * Private data structure for ipv4 connection information. + */ +struct nss_ipv4_conn_table_info { + uint32_t ce_table_size; /* Size of connection table entry in NSS FW */ + uint32_t cme_table_size; /* Size of connection match table entry in NSS FW */ + unsigned long ce_mem; /* Start address for connection entry table */ + unsigned long cme_mem; /* Start address for connection match entry table */ +} nss_ipv4_ct_info; + +int nss_ipv4_conn_cfg = NSS_DEFAULT_NUM_CONN; +int nss_ipv4_accel_mode_cfg __read_mostly = 1; + +static struct nss_dscp_map_entry mapping[NSS_DSCP_MAP_ARRAY_SIZE]; + +/* + * Callback for conn_sync_many request message. + */ +nss_ipv4_msg_callback_t nss_ipv4_conn_sync_many_msg_cb = NULL; + +/* + * nss_ipv4_dscp_map_usage() + * Help function shows the usage of the command. + */ +static inline void nss_ipv4_dscp_map_usage(void) +{ + nss_info_always("\nUsage:\n"); + nss_info_always("echo > /proc/sys/dev/nss/ipv4cfg/ipv4_dscp_map\n\n"); + nss_info_always("dscp[0-63] action[0-%u] prio[0-%u]:\n\n", + NSS_IPV4_DSCP_MAP_ACTION_MAX - 1, + NSS_DSCP_MAP_PRIORITY_MAX - 1); +} + +/* + * nss_ipv4_rx_msg_handler() + * Handle NSS -> HLOS messages for IPv4 bridge/route + */ +static void nss_ipv4_rx_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_ipv4_msg *nim = (struct nss_ipv4_msg *)ncm; + nss_ipv4_msg_callback_t cb; + + BUG_ON(ncm->interface != NSS_IPV4_RX_INTERFACE); + + /* + * Sanity check the message type + */ + if (ncm->type >= NSS_IPV4_MAX_MSG_TYPES) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_ipv4_msg)) { + nss_warning("%px: message length is invalid: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Trace messages. + */ + nss_ipv4_log_rx_msg(nim); + + switch (nim->cm.type) { + case NSS_IPV4_RX_NODE_STATS_SYNC_MSG: + /* + * Update driver statistics on node sync and send statistics notifications to the registered modules. + */ + nss_ipv4_stats_node_sync(nss_ctx, &nim->msg.node_stats); + nss_ipv4_stats_notify(nss_ctx); + break; + + case NSS_IPV4_RX_CONN_STATS_SYNC_MSG: + /* + * Update driver statistics on connection sync. + */ + nss_ipv4_stats_conn_sync(nss_ctx, &nim->msg.conn_stats); + break; + + case NSS_IPV4_TX_CONN_STATS_SYNC_MANY_MSG: + /* + * Update driver statistics on connection sync many. + */ + nss_ipv4_stats_conn_sync_many(nss_ctx, &nim->msg.conn_stats_many); + ncm->cb = (nss_ptr_t)nss_ipv4_conn_sync_many_msg_cb; + break; + } + + /* + * Update the callback and app_data for NOTIFY messages, IPv4 sends all notify messages + * to the same callback/app_data. + */ + if (nim->cm.response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_ctx->nss_top->ipv4_callback; + ncm->app_data = (nss_ptr_t)nss_ctx->nss_top->ipv4_ctx; + } + + /* + * Do we have a callback? + */ + if (!ncm->cb) { + return; + } + + /* + * Callback + */ + cb = (nss_ipv4_msg_callback_t)ncm->cb; + cb((void *)ncm->app_data, nim); +} + +/* + * nss_ipv4_tx_sync_callback() + * Callback to handle the completion of synchronous tx messages. + */ +static void nss_ipv4_tx_sync_callback(void *app_data, struct nss_ipv4_msg *nim) +{ + nss_ipv4_msg_callback_t callback = (nss_ipv4_msg_callback_t)nss_ipv4_pvt.cb; + void *data = nss_ipv4_pvt.app_data; + + nss_ipv4_pvt.cb = NULL; + nss_ipv4_pvt.app_data = NULL; + + if (nim->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("ipv4 error response %d\n", nim->cm.response); + nss_ipv4_pvt.response = NSS_TX_FAILURE; + } else { + nss_ipv4_pvt.response = NSS_TX_SUCCESS; + } + + if (callback) { + callback(data, nim); + } + + complete(&nss_ipv4_pvt.complete); +} + +/* + * nss_ipv4_dscp_action_get() + * Gets the action mapped to dscp. + */ +enum nss_ipv4_dscp_map_actions nss_ipv4_dscp_action_get(uint8_t dscp) +{ + if (dscp >= NSS_DSCP_MAP_ARRAY_SIZE) { + nss_warning("dscp:%u invalid\n", dscp); + return NSS_IPV4_DSCP_MAP_ACTION_MAX; + } + + return mapping[dscp].action; +} +EXPORT_SYMBOL(nss_ipv4_dscp_action_get); + +/* + * nss_ipv4_max_conn_count() + * Return the maximum number of IPv4 connections that the NSS acceleration engine supports. + */ +int nss_ipv4_max_conn_count(void) +{ + return nss_ipv4_conn_cfg; +} +EXPORT_SYMBOL(nss_ipv4_max_conn_count); + +/* + * nss_ipv4_conn_inquiry() + * Inquiry if a connection has been established in NSS FW + */ +nss_tx_status_t nss_ipv4_conn_inquiry(struct nss_ipv4_5tuple *ipv4_5t_p, + nss_ipv4_msg_callback_t cb) +{ + nss_tx_status_t nss_tx_status; + struct nss_ipv4_msg nim; + struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[0]; + + /* + * Initialize inquiry message structure. + * This is async message and the result will be returned + * to the caller by the msg_callback passed in. + */ + memset(&nim, 0, sizeof(nim)); + nss_ipv4_msg_init(&nim, NSS_IPV4_RX_INTERFACE, + NSS_IPV4_TX_CONN_CFG_INQUIRY_MSG, + sizeof(struct nss_ipv4_inquiry_msg), + cb, NULL); + nim.msg.inquiry.rr.tuple = *ipv4_5t_p; + nss_tx_status = nss_ipv4_tx(nss_ctx, &nim); + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: Send inquiry message failed\n", ipv4_5t_p); + } + + return nss_tx_status; +} +EXPORT_SYMBOL(nss_ipv4_conn_inquiry); + +/* + * nss_ipv4_tx_with_size() + * Transmit an ipv4 message to the FW with a specified size. + */ +nss_tx_status_t nss_ipv4_tx_with_size(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_msg *nim, uint32_t size) +{ + struct nss_cmn_msg *ncm = &nim->cm; + + /* + * Sanity check the message + */ + if (ncm->interface != NSS_IPV4_RX_INTERFACE) { + nss_warning("%px: tx request for another interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type >= NSS_IPV4_MAX_MSG_TYPES) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + /* + * Trace messages. + */ + nss_ipv4_log_tx_msg(nim); + + return nss_core_send_cmd(nss_ctx, nim, sizeof(*nim), size); +} +EXPORT_SYMBOL(nss_ipv4_tx_with_size); + +/* + * nss_ipv4_tx() + * Transmit an ipv4 message to the FW. + */ +nss_tx_status_t nss_ipv4_tx(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_msg *nim) +{ + return nss_ipv4_tx_with_size(nss_ctx, nim, NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_ipv4_tx); + +/* + * nss_ipv4_tx_sync() + * Transmit a synchronous ipv4 message to the FW. + */ +nss_tx_status_t nss_ipv4_tx_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_msg *nim) +{ + nss_tx_status_t status; + int ret = 0; + + down(&nss_ipv4_pvt.sem); + nss_ipv4_pvt.cb = (void *)nim->cm.cb; + nss_ipv4_pvt.app_data = (void *)nim->cm.app_data; + + nim->cm.cb = (nss_ptr_t)nss_ipv4_tx_sync_callback; + nim->cm.app_data = (nss_ptr_t)NULL; + + status = nss_ipv4_tx(nss_ctx, nim); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: nss ipv4 msg tx failed\n", nss_ctx); + up(&nss_ipv4_pvt.sem); + return status; + } + + ret = wait_for_completion_timeout(&nss_ipv4_pvt.complete, msecs_to_jiffies(NSS_IPV4_TX_MSG_TIMEOUT)); + if (!ret) { + nss_warning("%px: IPv4 tx sync failed due to timeout\n", nss_ctx); + nss_ipv4_pvt.response = NSS_TX_FAILURE; + } + + status = nss_ipv4_pvt.response; + up(&nss_ipv4_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_ipv4_tx_sync); + +/* + ********************************** + Register/Unregister/Miscellaneous APIs + ********************************** + */ + +/* + * nss_ipv4_notify_register() + * Register to received IPv4 events. + * + * NOTE: Do we want to pass an nss_ctx here so that we can register for ipv4 on any core? + */ +struct nss_ctx_instance *nss_ipv4_notify_register(nss_ipv4_msg_callback_t cb, void *app_data) +{ + /* + * TODO: We need to have a new array in support of the new API + * TODO: If we use a per-context array, we would move the array into nss_ctx based. + */ + nss_top_main.ipv4_callback = cb; + nss_top_main.ipv4_ctx = app_data; + return &nss_top_main.nss[nss_top_main.ipv4_handler_id]; +} +EXPORT_SYMBOL(nss_ipv4_notify_register); + +/* + * nss_ipv4_notify_unregister() + * Unregister to received IPv4 events. + * + * NOTE: Do we want to pass an nss_ctx here so that we can register for ipv4 on any core? + */ +void nss_ipv4_notify_unregister(void) +{ + nss_top_main.ipv4_callback = NULL; +} +EXPORT_SYMBOL(nss_ipv4_notify_unregister); + +/* + * nss_ipv4_conn_sync_many_notify_register() + * Register to receive IPv4 conn_sync_many message response. + */ +void nss_ipv4_conn_sync_many_notify_register(nss_ipv4_msg_callback_t cb) +{ + nss_ipv4_conn_sync_many_msg_cb = cb; +} +EXPORT_SYMBOL(nss_ipv4_conn_sync_many_notify_register); + +/* + * nss_ipv4_conn_sync_many_notify_unregister() + * Unregister to receive IPv4 conn_sync_many message response. + */ +void nss_ipv4_conn_sync_many_notify_unregister(void) +{ + nss_ipv4_conn_sync_many_msg_cb = NULL; +} +EXPORT_SYMBOL(nss_ipv4_conn_sync_many_notify_unregister); + +/* + * nss_ipv4_get_mgr() + * + * TODO: This only suppports a single ipv4, do we ever want to support more? + */ +struct nss_ctx_instance *nss_ipv4_get_mgr(void) +{ + return (void *)&nss_top_main.nss[nss_top_main.ipv4_handler_id]; +} +EXPORT_SYMBOL(nss_ipv4_get_mgr); + +/* + * nss_ipv4_register_handler() + * Register our handler to receive messages for this interface + */ +void nss_ipv4_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx = nss_ipv4_get_mgr(); + + if (nss_core_register_handler(nss_ctx, NSS_IPV4_RX_INTERFACE, nss_ipv4_rx_msg_handler, NULL) != NSS_CORE_STATUS_SUCCESS) { + nss_warning("IPv4 handler failed to register"); + } + + nss_ipv4_stats_dentry_create(); + nss_ipv4_strings_dentry_create(); +} + +/* + * nss_ipv4_conn_cfg_process_callback() + * Call back function for the ipv4 connection configure process + */ +static void nss_ipv4_conn_cfg_process_callback(void *app_data, struct nss_ipv4_msg *nim) +{ + struct nss_ipv4_rule_conn_cfg_msg *nirccm = &nim->msg.rule_conn_cfg; + struct nss_ctx_instance *nss_ctx __maybe_unused = nss_ipv4_get_mgr(); + + if (nim->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("%px: IPv4 connection configuration failed with error: %d\n", nss_ctx, nim->cm.error); + nss_core_update_max_ipv4_conn(NSS_FW_DEFAULT_NUM_CONN); + nss_ipv4_free_conn_tables(); + return; + } + + nss_ipv4_conn_cfg = ntohl(nirccm->num_conn); + nss_info("%px: IPv4 connection configuration success: %d\n", nss_ctx, nim->cm.error); +} + +/* + * nss_ipv4_conn_cfg_process() + * Process request to configure number of ipv4 connections + */ +static int nss_ipv4_conn_cfg_process(struct nss_ctx_instance *nss_ctx, int conn) +{ + struct nss_ipv4_msg nim; + struct nss_ipv4_rule_conn_cfg_msg *nirccm; + nss_tx_status_t nss_tx_status; + + if ((!nss_ipv4_ct_info.ce_table_size) || (!nss_ipv4_ct_info.cme_table_size)) { + nss_warning("%px: connection entry or connection match entry table size not available\n", + nss_ctx); + return -EINVAL; + } + + nss_info("%px: IPv4 supported connections: %d\n", nss_ctx, conn); + + nss_ipv4_ct_info.ce_mem = __get_free_pages(GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO, + get_order(nss_ipv4_ct_info.ce_table_size)); + if (!nss_ipv4_ct_info.ce_mem) { + nss_warning("%px: Memory allocation failed for IPv4 Connections: %d\n", + nss_ctx, + conn); + goto fail; + } + + nss_ipv4_ct_info.cme_mem = __get_free_pages(GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO, + get_order(nss_ipv4_ct_info.cme_table_size)); + if (!nss_ipv4_ct_info.ce_mem) { + nss_warning("%px: Memory allocation failed for IPv4 Connections: %d\n", + nss_ctx, + conn); + goto fail; + } + + memset(&nim, 0, sizeof(struct nss_ipv4_msg)); + nss_ipv4_msg_init(&nim, NSS_IPV4_RX_INTERFACE, NSS_IPV4_TX_CONN_CFG_RULE_MSG, + sizeof(struct nss_ipv4_rule_conn_cfg_msg), nss_ipv4_conn_cfg_process_callback, NULL); + + nirccm = &nim.msg.rule_conn_cfg; + nirccm->num_conn = htonl(conn); + nirccm->ce_mem = dma_map_single(nss_ctx->dev, (void *)nss_ipv4_ct_info.ce_mem, nss_ipv4_ct_info.ce_table_size, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(nss_ctx->dev, nirccm->ce_mem))) { + nss_warning("%px: DMA mapping failed for virtual address = %px", nss_ctx, (void *)nss_ipv4_ct_info.ce_mem); + goto fail; + } + + nirccm->cme_mem = dma_map_single(nss_ctx->dev, (void *)nss_ipv4_ct_info.cme_mem, nss_ipv4_ct_info.cme_table_size, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(nss_ctx->dev, nirccm->cme_mem))) { + nss_warning("%px: DMA mapping failed for virtual address = %px", nss_ctx, (void *)nss_ipv4_ct_info.cme_mem); + goto fail; + } + + nss_tx_status = nss_ipv4_tx(nss_ctx, &nim); + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: nss_tx error setting IPv4 Connections: %d\n", + nss_ctx, + conn); + goto fail; + } + + return 0; + +fail: + nss_ipv4_free_conn_tables(); + return -EINVAL;; +} + +/* + * nss_ipv4_update_conn_count_callback() + * Callback function for the ipv4 get connection info message. + */ +static void nss_ipv4_update_conn_count_callback(void *app_data, struct nss_ipv4_msg *nim) +{ + struct nss_ipv4_rule_conn_get_table_size_msg *nircgts = &nim->msg.size; + struct nss_ctx_instance *nss_ctx = nss_ipv4_get_mgr(); + + if (nim->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("%px: IPv4 fetch connection info failed with error: %d\n", nss_ctx, nim->cm.error); + nss_core_update_max_ipv4_conn(NSS_FW_DEFAULT_NUM_CONN); + return; + } + + nss_info("IPv4 get connection info success\n"); + + nss_ipv4_ct_info.ce_table_size = ntohl(nircgts->ce_table_size); + nss_ipv4_ct_info.cme_table_size = ntohl(nircgts->cme_table_size); + + if (nss_ipv4_conn_cfg_process(nss_ctx, ntohl(nircgts->num_conn)) != 0) { + nss_warning("%px: IPv4 connection entry or connection match entry table size\ + not available\n", nss_ctx); + } + + return; +} + +/* + * nss_ipv4_update_conn_count() + * Sets the maximum number of IPv4 connections. + * + * It first gets the connection tables size information from NSS FW + * and then configures the connections in NSS FW. + */ +int nss_ipv4_update_conn_count(int ipv4_num_conn) +{ + struct nss_ctx_instance *nss_ctx = nss_ipv4_get_mgr(); + struct nss_ipv4_msg nim; + struct nss_ipv4_rule_conn_get_table_size_msg *nircgts; + nss_tx_status_t nss_tx_status; + uint32_t sum_of_conn; + + /* + * By default, NSS FW is configured with default number of connections. + */ + if (ipv4_num_conn == NSS_FW_DEFAULT_NUM_CONN) { + nss_info("%px: Default number of connections (%d) already configured\n", nss_ctx, ipv4_num_conn); + return 0; + } + + /* + * The input should be multiple of 1024. + * Input for ipv4 and ipv6 sum together should not exceed 8k + * Min. value should be at least 256 connections. This is the + * minimum connections we will support for each of them. + */ + sum_of_conn = ipv4_num_conn + nss_ipv6_conn_cfg; + if ((ipv4_num_conn & NSS_NUM_CONN_QUANTA_MASK) || + (sum_of_conn > NSS_MAX_TOTAL_NUM_CONN_IPV4_IPV6) || + (ipv4_num_conn < NSS_MIN_NUM_CONN)) { + nss_warning("%px: input supported connections (%d) does not adhere\ + specifications\n1) not multiple of 1024,\n2) is less than \ + min val: %d, OR\n IPv4/6 total exceeds %d\n", + nss_ctx, + ipv4_num_conn, + NSS_MIN_NUM_CONN, + NSS_MAX_TOTAL_NUM_CONN_IPV4_IPV6); + return -EINVAL; + } + + memset(&nim, 0, sizeof(struct nss_ipv4_msg)); + nss_ipv4_msg_init(&nim, NSS_IPV4_RX_INTERFACE, NSS_IPV4_TX_CONN_TABLE_SIZE_MSG, + sizeof(struct nss_ipv4_rule_conn_get_table_size_msg), nss_ipv4_update_conn_count_callback, NULL); + + nircgts = &nim.msg.size; + nircgts->num_conn = htonl(ipv4_num_conn); + nss_tx_status = nss_ipv4_tx(nss_ctx, &nim); + + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: Send fetch connection info message failed\n", nss_ctx); + return -EINVAL; + } + + return 0; +} + +/* + * nss_ipv4_free_conn_tables() + * Frees memory allocated for connection tables + */ +void nss_ipv4_free_conn_tables(void) +{ + if (nss_ipv4_ct_info.ce_mem) { + free_pages(nss_ipv4_ct_info.ce_mem, get_order(nss_ipv4_ct_info.ce_table_size)); + } + + if (nss_ipv4_ct_info.cme_mem) { + free_pages(nss_ipv4_ct_info.cme_mem, get_order(nss_ipv4_ct_info.cme_table_size)); + } + + memset(&nss_ipv4_ct_info, 0, sizeof(struct nss_ipv4_conn_table_info)); + return; +} + +/* + * nss_ipv4_accel_mode_cfg_handler() + * Configure acceleration mode for IPv4 + */ +static int nss_ipv4_accel_mode_cfg_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[0]; + struct nss_ipv4_msg nim; + struct nss_ipv4_accel_mode_cfg_msg *nipcm; + nss_tx_status_t nss_tx_status; + int ret = NSS_FAILURE; + int current_value; + + /* + * Take snap shot of current value + */ + current_value = nss_ipv4_accel_mode_cfg; + + /* + * Write the variable with user input + */ + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + if (ret || (!write)) { + return ret; + } + + memset(&nim, 0, sizeof(struct nss_ipv4_msg)); + nss_ipv4_msg_init(&nim, NSS_IPV4_RX_INTERFACE, NSS_IPV4_TX_ACCEL_MODE_CFG_MSG, + sizeof(struct nss_ipv4_accel_mode_cfg_msg), NULL, NULL); + + nipcm = &nim.msg.accel_mode_cfg; + nipcm->mode = htonl(nss_ipv4_accel_mode_cfg); + + nss_tx_status = nss_ipv4_tx_sync(nss_ctx, &nim); + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: Send acceleration mode message failed\n", nss_ctx); + nss_ipv4_accel_mode_cfg = current_value; + return -EIO; + } + + return 0; +} + +/* + * nss_ipv4_dscp_map_cfg_handler() + * Sysctl handler for dscp/pri mappings. + */ +static int nss_ipv4_dscp_map_cfg_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[0]; + struct nss_dscp_map_parse out; + struct nss_ipv4_msg nim; + struct nss_ipv4_dscp2pri_cfg_msg *nipd2p; + nss_tx_status_t status; + int ret; + + if (!write) { + return nss_dscp_map_print(ctl, buffer, lenp, ppos, mapping); + } + + ret = nss_dscp_map_parse(ctl, buffer, lenp, ppos, &out); + if (ret) { + nss_warning("failed to parse dscp mapping:%d\n", ret); + nss_ipv4_dscp_map_usage(); + return ret; + } + + if (out.action >= NSS_IPV4_DSCP_MAP_ACTION_MAX) { + nss_warning("invalid action value: %d\n", out.action); + nss_ipv4_dscp_map_usage(); + return -EINVAL; + } + + memset(&nim, 0, sizeof(struct nss_ipv4_msg)); + nss_ipv4_msg_init(&nim, NSS_IPV4_RX_INTERFACE, NSS_IPV4_TX_DSCP2PRI_CFG_MSG, + sizeof(struct nss_ipv4_dscp2pri_cfg_msg), NULL, NULL); + + nipd2p = &nim.msg.dscp2pri_cfg; + nipd2p->dscp = out.dscp; + nipd2p->priority = out.priority; + + status = nss_ipv4_tx_sync(nss_ctx, &nim); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: ipv4 dscp2pri config message failed\n", nss_ctx); + return -EFAULT; + } + + /* + * NSS firmware acknowleged the configuration, so update the mapping + * table on HOST side as well. + */ + mapping[out.dscp].action = out.action; + mapping[out.dscp].priority = out.priority; + + return 0; +} + +static struct ctl_table nss_ipv4_table[] = { + { + .procname = "ipv4_accel_mode", + .data = &nss_ipv4_accel_mode_cfg, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_ipv4_accel_mode_cfg_handler, + }, + { + .procname = "ipv4_dscp_map", + .data = &mapping[NSS_DSCP_MAP_ARRAY_SIZE], + .maxlen = sizeof(struct nss_dscp_map_entry), + .mode = 0644, + .proc_handler = &nss_ipv4_dscp_map_cfg_handler, + }, + { } +}; + +static struct ctl_table nss_ipv4_dir[] = { + { + .procname = "ipv4cfg", + .mode = 0555, + .child = nss_ipv4_table, + }, + { } +}; + +static struct ctl_table nss_ipv4_root_dir[] = { + { + .procname = "nss", + .mode = 0555, + .child = nss_ipv4_dir, + }, + { } +}; + +static struct ctl_table nss_ipv4_root[] = { + { + .procname = "dev", + .mode = 0555, + .child = nss_ipv4_root_dir, + }, + { } +}; + +static struct ctl_table_header *nss_ipv4_header; + +/* + * nss_ipv4_register_sysctl() + * Register sysctl specific to ipv4 + */ +void nss_ipv4_register_sysctl(void) +{ + sema_init(&nss_ipv4_pvt.sem, 1); + init_completion(&nss_ipv4_pvt.complete); + + /* + * Register sysctl table. + */ + nss_ipv4_header = register_sysctl_table(nss_ipv4_root); +} + +/* + * nss_ipv4_unregister_sysctl() + * Unregister sysctl specific to ipv4 + */ +void nss_ipv4_unregister_sysctl(void) +{ + /* + * Unregister sysctl table. + */ + if (nss_ipv4_header) { + unregister_sysctl_table(nss_ipv4_header); + } +} + +/* + * nss_ipv4_msg_init() + * Initialize IPv4 message. + */ +void nss_ipv4_msg_init(struct nss_ipv4_msg *nim, uint16_t if_num, uint32_t type, uint32_t len, + nss_ipv4_msg_callback_t cb, void *app_data) +{ + nss_cmn_msg_init(&nim->cm, if_num, type, len, (void *)cb, app_data); +} +EXPORT_SYMBOL(nss_ipv4_msg_init); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_log.c new file mode 100644 index 000000000..f32235bc7 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_log.c @@ -0,0 +1,351 @@ +/* + ************************************************************************** + * Copyright (c) 2016, 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_ipv4_log.c + * NSS IPv4 logger file. + */ + +#include "nss_core.h" + +/* + * nss_ipv4_log_message_types_str + * IPv4 bridge/route rule message strings + */ +static int8_t *nss_ipv4_log_message_types_str[NSS_IPV4_MAX_MSG_TYPES] __maybe_unused = { + "IPv4 create rule message", + "IPv4 destroy rule message", + "Deprecated: NSS_IPV4_RX_ESTABLISH_RULE_MSG", + "IPv4 connection stats sync message", + "IPv4 generic statistics sync message", + "IPv4 number of connections supported rule message", + "IPv4 multicast create rule message", + "IPv4 request FW to send many conn sync message", +}; + +/* + * nss_ipv4_log_error_response_types_str + * Strings for error types for ipv4 messages + */ +static int8_t *nss_ipv4_log_error_response_types_str[NSS_IPV4_LAST] __maybe_unused = { + "No error", + "Unknown error", + "Invalid interface number", + "Missing connection rule", + "Buffer allocation failure", + "No connection found to delete", + "Conn cfg already done once", + "Conn cfg input is not multiple of quanta", + "Conn cfg input exceeds max supported connections", + "Conn cfg mem alloc fail at NSS FW", + "Invalid L4 protocol for multicast rule create", + "Invalid multicast flags for multicast update", + "Invalid interface for multicast update", +}; + +/* + * nss_ipv4_log_rule_create_msg() + * Log IPv4 create rule message. + */ +static void nss_ipv4_log_rule_create_msg(struct nss_ipv4_msg *nim) +{ + struct nss_ipv4_rule_create_msg *nircm __maybe_unused = &nim->msg.rule_create; + nss_trace("%px: IPv4 create rule message \n" + "Protocol: %d\n" + "from_mtu: %u\n" + "to_mtu: %u\n" + "from_ip: %pI4h:%d\n" + "to_ip: %pI4h:%d\n" + "from_ip_xlate: %pI4h:%d\n" + "to_ip_xlate: %pI4h:%d\n" + "from_mac: %pM\n" + "to_mac: %pM\n" + "src_iface_num: %u\n" + "dest_iface_num: %u\n" + "ingress_inner_vlan_tag: %u\n" + "egress_inner_vlan_tag: %u\n" + "ingress_outer_vlan_tag: %u\n" + "egress_outer_vlan_tag: %u\n" + "rule_flags: %x\n" + "valid_flags: %x\n" + "return_pppoe_if_exist: %u\n" + "return_pppoe_if_num: %u\n" + "flow_pppoe_if_exist: %u\n" + "flow_pppoe_if_num: %u\n" + "flow_qos_tag: %x (%u)\n" + "return_qos_tag: %x (%u)\n" + "flow_dscp: %x\n" + "return_dscp: %x\n", + nim, + nircm->tuple.protocol, + nircm->conn_rule.flow_mtu, + nircm->conn_rule.return_mtu, + &nircm->tuple.flow_ip, nircm->tuple.flow_ident, + &nircm->tuple.return_ip, nircm->tuple.return_ident, + &nircm->conn_rule.flow_ip_xlate, nircm->conn_rule.flow_ident_xlate, + &nircm->conn_rule.return_ip_xlate, nircm->conn_rule.return_ident_xlate, + nircm->conn_rule.flow_mac, + nircm->conn_rule.return_mac, + nircm->conn_rule.flow_interface_num, + nircm->conn_rule.return_interface_num, + nircm->vlan_primary_rule.ingress_vlan_tag, + nircm->vlan_primary_rule.egress_vlan_tag, + nircm->vlan_secondary_rule.ingress_vlan_tag, + nircm->vlan_secondary_rule.egress_vlan_tag, + nircm->rule_flags, + nircm->valid_flags, + nircm->pppoe_rule.return_if_exist, + nircm->pppoe_rule.return_if_num, + nircm->pppoe_rule.flow_if_exist, + nircm->pppoe_rule.flow_if_num, + nircm->qos_rule.flow_qos_tag, nircm->qos_rule.flow_qos_tag, + nircm->qos_rule.return_qos_tag, nircm->qos_rule.return_qos_tag, + nircm->dscp_rule.flow_dscp, + nircm->dscp_rule.return_dscp); +} + +/* + * nss_ipv4_log_destroy_rule_msg() + * Log IPv4 destroy rule message. + */ +static void nss_ipv4_log_destroy_rule_msg(struct nss_ipv4_msg *nim) +{ + struct nss_ipv4_rule_destroy_msg *nirdm __maybe_unused = &nim->msg.rule_destroy; + nss_trace("%px: IPv4 destroy rule message: \n" + "flow_ip: %pI4h:%d\n" + "return_ip: %pI4h:%d\n" + "protocol: %d\n", + nim, + &nirdm->tuple.flow_ip, nirdm->tuple.flow_ident, + &nirdm->tuple.return_ip, nirdm->tuple.return_ident, + nirdm->tuple.protocol); +} + +/* + * nss_ipv4_log_conn_sync() + * Log IPv4 connection stats sync message. + */ +static void nss_ipv4_log_conn_sync(struct nss_ipv4_msg *nim) +{ + struct nss_ipv4_conn_sync *sync = &nim->msg.conn_stats; + if (sync->flow_tx_packet_count || sync->return_tx_packet_count) { + nss_trace("%px: IPv4 connection stats sync message: \n" + "Protocol: %d\n" + "src_addr: %pI4h:%d\n" + "dest_addr: %pI4h:%d\n" + "flow_rx_packet_count: %u\n" + "flow_rx_byte_count: %u\n" + "return_rx_packet_count: %u\n" + "return_rx_byte_count: %u\n" + "flow_tx_packet_count: %u\n" + "flow_tx_byte_count: %u\n" + "return_tx_packet_count: %u\n" + "return_tx_byte_count: %u\n", + nim, + (int)sync->protocol, + &sync->flow_ip, (int)sync->flow_ident, + &sync->return_ip_xlate, (int)sync->return_ident_xlate, + sync->flow_rx_packet_count, + sync->flow_rx_byte_count, + sync->return_rx_packet_count, + sync->return_rx_byte_count, + sync->flow_tx_packet_count, + sync->flow_tx_byte_count, + sync->return_tx_packet_count, + sync->return_tx_byte_count); + } +} + +/* + * nss_ipv4_log_conn_cfg_msg() + * Log IPv4 number of connections supported rule message. + */ +static void nss_ipv4_log_conn_cfg_msg(struct nss_ipv4_msg *nim) +{ + struct nss_ipv4_rule_conn_cfg_msg *nirccm __maybe_unused = &nim->msg.rule_conn_cfg; + nss_trace("%px: IPv4 number of connections supported rule message: \n" + "num_conn: %d\n", + nim, + nirccm->num_conn); +} + +/* + * nss_ipv4_log_mc_rule_create_msg() + * Log IPv4 multicast create rule message. + */ +static void nss_ipv4_log_mc_rule_create_msg(struct nss_ipv4_msg *nim) +{ + uint16_t vif; + struct nss_ipv4_mc_rule_create_msg *nimrcm = &nim->msg.mc_rule_create; + for (vif = 0; vif < nimrcm->if_count ; vif++) { + nss_trace("%px: IPv4 multicast create rule message \n" + "Rule flag: %x\n" + "Vif: %d\n" + "Protocol: %d\n" + "to_mtu: %u\n" + "from_ip: %pI4h:%d\n" + "to_ip: %pI4h:%d\n" + "to_mac: %pM\n" + "dest_iface_num: %u\n" + "out_vlan[0] %x\n" + "out_vlan[1] %x\n", + nim, + nimrcm->if_rule[vif].rule_flags, + vif, + nimrcm->tuple.protocol, + nimrcm->if_rule[vif].if_mtu, + &nimrcm->tuple.flow_ip, nimrcm->tuple.flow_ident, + &nimrcm->tuple.return_ip, nimrcm->tuple.return_ident, + nimrcm->if_rule[vif].if_mac, + nimrcm->if_rule[vif].if_num, + nimrcm->if_rule[vif].egress_vlan_tag[0], + nimrcm->if_rule[vif].egress_vlan_tag[1]); + } +} + +/* + * nss_ipv4_log_conn_sync_many_msg() + * Log IPv4 many conn sync message. + */ +static void nss_ipv4_log_conn_sync_many_msg(struct nss_ipv4_msg *nim) +{ + uint16_t i; + struct nss_ipv4_conn_sync_many_msg *nicsm = &nim->msg.conn_stats_many; + for (i = 0; i < nicsm->count; i++) { + struct nss_ipv4_conn_sync *sync = &nicsm->conn_sync[i]; + if (sync->flow_tx_packet_count || sync->return_tx_packet_count) { + nss_trace("%px: IPv4 many conn sync message \n" + "count: %d\n" + "i: %d\n" + "Protocol: %d\n" + "src_addr: %pI4h:%d\n" + "dest_addr: %pI4h:%d\n" + "flow_rx_packet_count: %u\n" + "flow_rx_byte_count: %u\n" + "return_rx_packet_count: %u\n" + "return_rx_byte_count: %u\n" + "flow_tx_packet_count: %u\n" + "flow_tx_byte_count: %u\n" + "return_tx_packet_count: %u\n" + "return_tx_byte_count: %u\n", + nim, + nicsm->count, + i, + (int)sync->protocol, + &sync->flow_ip, (int)sync->flow_ident, + &sync->return_ip_xlate, (int)sync->return_ident_xlate, + sync->flow_rx_packet_count, + sync->flow_rx_byte_count, + sync->return_rx_packet_count, + sync->return_rx_byte_count, + sync->flow_tx_packet_count, + sync->flow_tx_byte_count, + sync->return_tx_packet_count, + sync->return_tx_byte_count); + } + } +} + +/* + * nss_ipv4_log_verbose() + * Log message contents. + */ +static void nss_ipv4_log_verbose(struct nss_ipv4_msg *nim) +{ + switch (nim->cm.type) { + case NSS_IPV4_TX_CREATE_RULE_MSG: + nss_ipv4_log_rule_create_msg(nim); + break; + + case NSS_IPV4_TX_DESTROY_RULE_MSG: + nss_ipv4_log_destroy_rule_msg(nim); + break; + + case NSS_IPV4_RX_CONN_STATS_SYNC_MSG: + nss_ipv4_log_conn_sync(nim); + break; + + case NSS_IPV4_RX_NODE_STATS_SYNC_MSG: + /* Getting logged in stats */ + break; + + case NSS_IPV4_TX_CONN_CFG_RULE_MSG: + nss_ipv4_log_conn_cfg_msg(nim); + break; + + case NSS_IPV4_TX_CREATE_MC_RULE_MSG: + nss_ipv4_log_mc_rule_create_msg(nim); + break; + + case NSS_IPV4_TX_CONN_STATS_SYNC_MANY_MSG: + nss_ipv4_log_conn_sync_many_msg(nim); + break; + + default: + nss_trace("%px: Invalid message type\n", nim); + break; + } +} + +/* + * nss_ipv4_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_ipv4_log_tx_msg(struct nss_ipv4_msg *nim) +{ + if (nim->cm.type >= NSS_IPV4_MAX_MSG_TYPES) { + nss_info("%px: Invalid message type\n", nim); + return; + } + + nss_info("%px: type[%d]:%s\n", nim, nim->cm.type, nss_ipv4_log_message_types_str[nim->cm.type]); + nss_ipv4_log_verbose(nim); +} + +/* + * nss_ipv4_log_rx_msg() + * Log messages received from FW. + */ +void nss_ipv4_log_rx_msg(struct nss_ipv4_msg *nim) +{ + if (nim->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_info("%px: Invalid response\n", nim); + return; + } + + if (nim->cm.response == NSS_CMN_RESPONSE_NOTIFY || (nim->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", nim, nim->cm.type, + nss_ipv4_log_message_types_str[nim->cm.type], + nim->cm.response, nss_cmn_response_str[nim->cm.response]); + goto verbose; + } + + if (nim->cm.error >= NSS_IPV4_LAST) { + nss_info("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + nim, nim->cm.type, nss_ipv4_log_message_types_str[nim->cm.type], + nim->cm.response, nss_cmn_response_str[nim->cm.response], + nim->cm.error); + goto verbose; + } + + nss_info("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + nim, nim->cm.type, nss_ipv4_log_message_types_str[nim->cm.type], + nim->cm.response, nss_cmn_response_str[nim->cm.response], + nim->cm.error, nss_ipv4_log_error_response_types_str[nim->cm.error]); + +verbose: + nss_ipv4_log_verbose(nim); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_reasm.c b/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_reasm.c new file mode 100644 index 000000000..402a46c4a --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_reasm.c @@ -0,0 +1,76 @@ +/* + ************************************************************************** + * Copyright (c) 2014,2017,2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_ipv4_reasm.c + * NSS IPv4 Reassembly APIs + */ +#include +#include "nss_ipv4_reasm_stats.h" +#include "nss_ipv4_reasm_strings.h" + +/* + * nss_ipv4_reasm_msg_handler() + * Handle NSS -> HLOS messages for IPv4 reasm + */ +static void nss_ipv4_reasm_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_ipv4_reasm_msg *nim = (struct nss_ipv4_reasm_msg *)ncm; + + BUG_ON(ncm->interface != NSS_IPV4_REASM_INTERFACE); + + /* + * Handle deprecated messages. Eventually these messages should be removed. + */ + switch (nim->cm.type) { + case NSS_IPV4_REASM_STATS_SYNC_MSG: + /* + * Update Ipv4 reasm driver statistics and send statistics notifications to the registered modules. + */ + nss_ipv4_reasm_stats_sync(nss_ctx, &nim->msg.stats_sync); + nss_ipv4_reasm_stats_notify(nss_ctx); + + break; + default: + nss_warning("IPv4 reasm received an unknown message type"); + } +} + +/* + * nss_ipv4_reasm_get_context() + * get NSS context instance for ipv4 reassembly + */ +struct nss_ctx_instance *nss_ipv4_reasm_get_context(void) +{ + return &nss_top_main.nss[nss_top_main.ipv4_reasm_handler_id]; +} +EXPORT_SYMBOL(nss_ipv4_reasm_get_context); + +/* + * nss_ipv4_reasm_register_handler() + * Register our handler to receive messages for this interface + */ +void nss_ipv4_reasm_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx = nss_ipv4_reasm_get_context(); + + if (nss_core_register_handler(nss_ctx, NSS_IPV4_REASM_INTERFACE, nss_ipv4_reasm_msg_handler, NULL) != NSS_CORE_STATUS_SUCCESS) { + nss_warning("IPv4 reasm handler failed to register"); + } + + nss_ipv4_reasm_stats_dentry_create(); + nss_ipv4_reasm_strings_dentry_create(); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_reasm_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_reasm_stats.c new file mode 100644 index 000000000..350e61962 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_reasm_stats.c @@ -0,0 +1,167 @@ +/* + ************************************************************************** + * Copyright (c) 2017,2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_stats.h" +#include "nss_core.h" +#include "nss_ipv4_reasm_stats.h" +#include "nss_ipv4_reasm.h" +#include "nss_ipv4_reasm_strings.h" + +/* + * Declare atomic notifier data structure for statistics. + */ +ATOMIC_NOTIFIER_HEAD(nss_ipv4_reasm_stats_notifier); + +uint64_t nss_ipv4_reasm_stats[NSS_IPV4_REASM_STATS_MAX]; /* IPv4 reasm statistics */ + +/* + * nss_ipv4_reasm_stats_read() + * Read IPV4 reassembly stats + */ +static ssize_t nss_ipv4_reasm_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i; + + /* + * Max output lines = #stats + few blank lines for banner printing + + * Number of Extra outputlines for future reference to add new stats + */ + uint32_t max_output_lines = NSS_STATS_NODE_MAX + NSS_IPV4_REASM_STATS_MAX + NSS_STATS_EXTRA_OUTPUT_LINES; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + stats_shadow = kzalloc(NSS_IPV4_REASM_STATS_MAX * 8, GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return 0; + } + + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "ipv4_reasm", NSS_STATS_SINGLE_CORE); + + size_wr += nss_stats_fill_common_stats(NSS_IPV4_REASM_INTERFACE, NSS_STATS_SINGLE_INSTANCE, lbuf, size_wr, size_al, "ipv4_reasm"); + + /* + * IPv4 reasm node stats + */ + spin_lock_bh(&nss_top_main.stats_lock); + for (i = 0; (i < NSS_IPV4_REASM_STATS_MAX); i++) { + stats_shadow[i] = nss_ipv4_reasm_stats[i]; + } + + spin_unlock_bh(&nss_top_main.stats_lock); + size_wr += nss_stats_print("ipv4_reasm", NULL, NSS_STATS_SINGLE_INSTANCE + , nss_ipv4_reasm_strings_stats + , stats_shadow + , NSS_IPV4_REASM_STATS_MAX + , lbuf, size_wr, size_al); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * nss_ipv4_reasm_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(ipv4_reasm); + +/* + * nss_ipv4_reasm_stats_dentry_create() + * Create the IPv4 reasm statistics debug entry + */ +void nss_ipv4_reasm_stats_dentry_create(void) +{ + nss_stats_create_dentry("ipv4_reasm", &nss_ipv4_reasm_stats_ops); +} + +/* + * nss_ipv4_reasm_stats_sync() + * Update driver specific information from the messsage. + */ +void nss_ipv4_reasm_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_reasm_stats_sync *nirs) +{ + int i; + struct nss_top_instance *nss_top = nss_ctx->nss_top; + + spin_lock_bh(&nss_top->stats_lock); + + /* + * Common node stats + */ + nss_top->stats_node[NSS_IPV4_REASM_INTERFACE][NSS_STATS_NODE_RX_PKTS] += nirs->node_stats.rx_packets; + nss_top->stats_node[NSS_IPV4_REASM_INTERFACE][NSS_STATS_NODE_RX_BYTES] += nirs->node_stats.rx_bytes; + nss_top->stats_node[NSS_IPV4_REASM_INTERFACE][NSS_STATS_NODE_TX_PKTS] += nirs->node_stats.tx_packets; + nss_top->stats_node[NSS_IPV4_REASM_INTERFACE][NSS_STATS_NODE_TX_BYTES] += nirs->node_stats.tx_bytes; + + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + nss_top->stats_node[NSS_IPV4_REASM_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + i] += nirs->node_stats.rx_dropped[i]; + } + + /* + * IPv4 reasm node stats + */ + nss_ipv4_reasm_stats[NSS_IPV4_REASM_STATS_EVICTIONS] += nirs->ipv4_reasm_evictions; + nss_ipv4_reasm_stats[NSS_IPV4_REASM_STATS_ALLOC_FAILS] += nirs->ipv4_reasm_alloc_fails; + nss_ipv4_reasm_stats[NSS_IPV4_REASM_STATS_TIMEOUTS] += nirs->ipv4_reasm_timeouts; + + spin_unlock_bh(&nss_top->stats_lock); +} + +/* + * nss_ipv4_reasm_stats_notify() + * Sends notifications to all the registered modules. + * + * Leverage NSS-FW statistics timing to update Netlink. + */ +void nss_ipv4_reasm_stats_notify(struct nss_ctx_instance *nss_ctx) +{ + struct nss_ipv4_reasm_stats_notification ipv4_reasm_stats; + + ipv4_reasm_stats.core_id = nss_ctx->id; + memcpy(ipv4_reasm_stats.cmn_node_stats, nss_top_main.stats_node[NSS_IPV4_REASM_INTERFACE], sizeof(ipv4_reasm_stats.cmn_node_stats)); + memcpy(ipv4_reasm_stats.ipv4_reasm_stats, nss_ipv4_reasm_stats, sizeof(ipv4_reasm_stats.ipv4_reasm_stats)); + atomic_notifier_call_chain(&nss_ipv4_reasm_stats_notifier, NSS_STATS_EVENT_NOTIFY, (void *)&ipv4_reasm_stats); +} + +/* + * nss_ipv4_reasm_stats_register_notifier() + * Registers statistics notifier. + */ +int nss_ipv4_reasm_stats_register_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&nss_ipv4_reasm_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_ipv4_reasm_stats_register_notifier); + +/* + * nss_ipv4_reasm_stats_unregister_notifier() + * Deregisters statistics notifier. + */ +int nss_ipv4_reasm_stats_unregister_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&nss_ipv4_reasm_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_ipv4_reasm_stats_unregister_notifier); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_reasm_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_reasm_stats.h new file mode 100644 index 000000000..f8c5f39f3 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_reasm_stats.h @@ -0,0 +1,27 @@ +/* + ************************************************************************** + * Copyright (c) 2017,2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_IPV4_REASM_STATS_H +#define __NSS_IPV4_REASM_STATS_H + +/* + * IPV4 reasm statistics APIs + */ +extern void nss_ipv4_reasm_stats_notify(struct nss_ctx_instance *nss_ctx); +extern void nss_ipv4_reasm_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_reasm_stats_sync *nirs); +extern void nss_ipv4_reasm_stats_dentry_create(void); + +#endif /* __NSS_IPV4_REASM_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_reasm_strings.c b/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_reasm_strings.c new file mode 100644 index 000000000..445d1349d --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_reasm_strings.c @@ -0,0 +1,55 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_stats.h" +#include "nss_core.h" +#include +#include "nss_strings.h" + +/* + * nss_ipv4_reasm_strings_stats + * IPv4 reassembly statistics strings. + */ +struct nss_stats_info nss_ipv4_reasm_strings_stats[NSS_IPV4_REASM_STATS_MAX] = { + {"evictions" , NSS_STATS_TYPE_DROP}, + {"alloc_fails" , NSS_STATS_TYPE_DROP}, + {"timeouts" , NSS_STATS_TYPE_DROP} +}; + +/* + * nss_ipv4_reasm_strings_read() + * Read IPv4 reassembly node statistics names. + */ +static ssize_t nss_ipv4_reasm_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_ipv4_reasm_strings_stats, NSS_IPV4_REASM_STATS_MAX); +} + +/* + * nss_ipv4_reasm_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(ipv4_reasm); + +/* + * nss_ipv4_reasm_strings_dentry_create() + * Create IPv4 reassembly statistics strings debug entry. + */ +void nss_ipv4_reasm_strings_dentry_create(void) +{ + nss_strings_create_dentry("ipv4_reasm", &nss_ipv4_reasm_strings_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_reasm_strings.h b/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_reasm_strings.h new file mode 100644 index 000000000..9a0b362c2 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_reasm_strings.h @@ -0,0 +1,25 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_IPV4_REASM_STRINGS_H +#define __NSS_IPV4_REASM_STRINGS_H + +extern struct nss_stats_info nss_ipv4_reasm_strings_stats[NSS_IPV4_REASM_STATS_MAX]; +extern void nss_ipv4_reasm_strings_dentry_create(void); + +#endif /* __NSS_IPV4_REASM_STRINGS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_stats.c new file mode 100644 index 000000000..08def22c4 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_stats.c @@ -0,0 +1,236 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2017, 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include +#include "nss_ipv4_stats.h" +#include "nss_ipv4_strings.h" + +/* + * Declare atomic notifier data structure for statistics. + */ +ATOMIC_NOTIFIER_HEAD(nss_ipv4_stats_notifier); + +uint64_t nss_ipv4_stats[NSS_IPV4_STATS_MAX]; +uint64_t nss_ipv4_exception_stats[NSS_IPV4_EXCEPTION_EVENT_MAX]; + +/* + * nss_ipv4_stats_read() + * Read IPV4 stats + */ +static ssize_t nss_ipv4_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i; + + /* + * max output lines = #stats + Number of Extra outputlines for future reference to add new stats + + * start tag line + end tag line + three blank lines + */ + uint32_t max_output_lines = NSS_STATS_NODE_MAX + NSS_IPV4_STATS_MAX + NSS_IPV4_EXCEPTION_EVENT_MAX + NSS_STATS_EXTRA_OUTPUT_LINES; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + /* + * Note: The assumption here is that exception event count is larger than other statistics count for IPv4 + */ + stats_shadow = kzalloc(NSS_IPV4_EXCEPTION_EVENT_MAX * 8, GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return 0; + } + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "ipv4", NSS_STATS_SINGLE_CORE); + size_wr += nss_stats_fill_common_stats(NSS_IPV4_RX_INTERFACE, NSS_STATS_SINGLE_INSTANCE, lbuf, size_wr, size_al, "ipv4"); + + /* + * IPv4 node stats + */ + spin_lock_bh(&nss_top_main.stats_lock); + for (i = 0; i < NSS_IPV4_STATS_MAX; i++) { + stats_shadow[i] = nss_ipv4_stats[i]; + } + spin_unlock_bh(&nss_top_main.stats_lock); + size_wr += nss_stats_print("ipv4", "ipv4 special stats" + , NSS_STATS_SINGLE_INSTANCE + , nss_ipv4_strings_stats + , stats_shadow + , NSS_IPV4_STATS_MAX + , lbuf, size_wr, size_al); + + /* + * Exception stats + */ + spin_lock_bh(&nss_top_main.stats_lock); + for (i = 0; (i < NSS_IPV4_EXCEPTION_EVENT_MAX); i++) { + stats_shadow[i] = nss_ipv4_exception_stats[i]; + } + spin_unlock_bh(&nss_top_main.stats_lock); + size_wr += nss_stats_print("ipv4", "ipv4 exception stats" + , NSS_STATS_SINGLE_INSTANCE + , nss_ipv4_strings_exception_stats + , stats_shadow + , NSS_IPV4_EXCEPTION_EVENT_MAX + , lbuf, size_wr, size_al); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * nss_ipv4_stats_conn_sync() + * Update driver specific information from the messsage. + */ +void nss_ipv4_stats_conn_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_conn_sync *nirs) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + + /* + * Update statistics maintained by NSS driver + */ + spin_lock_bh(&nss_top->stats_lock); + nss_ipv4_stats[NSS_IPV4_STATS_ACCELERATED_RX_PKTS] += nirs->flow_rx_packet_count + nirs->return_rx_packet_count; + nss_ipv4_stats[NSS_IPV4_STATS_ACCELERATED_RX_BYTES] += nirs->flow_rx_byte_count + nirs->return_rx_byte_count; + nss_ipv4_stats[NSS_IPV4_STATS_ACCELERATED_TX_PKTS] += nirs->flow_tx_packet_count + nirs->return_tx_packet_count; + nss_ipv4_stats[NSS_IPV4_STATS_ACCELERATED_TX_BYTES] += nirs->flow_tx_byte_count + nirs->return_tx_byte_count; + spin_unlock_bh(&nss_top->stats_lock); +} + +/* + * nss_ipv4_stats_conn_sync_many() + * Update driver specific information from the conn_sync_many messsage. + */ +void nss_ipv4_stats_conn_sync_many(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_conn_sync_many_msg *nicsm) +{ + int i; + + /* + * Sanity check for the stats count + */ + if (nicsm->count * sizeof(struct nss_ipv4_conn_sync) >= nicsm->size) { + nss_warning("%px: stats sync count %u exceeds the size of this msg %u", nss_ctx, nicsm->count, nicsm->size); + return; + } + + for (i = 0; i < nicsm->count; i++) { + nss_ipv4_stats_conn_sync(nss_ctx, &nicsm->conn_sync[i]); + } +} + +/* + * nss_ipv4_stats_node_sync() + * Update driver specific information from the messsage. + */ +void nss_ipv4_stats_node_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_node_sync *nins) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + uint32_t i; + + /* + * Update statistics maintained by NSS driver + */ + spin_lock_bh(&nss_top->stats_lock); + nss_top->stats_node[NSS_IPV4_RX_INTERFACE][NSS_STATS_NODE_RX_PKTS] += nins->node_stats.rx_packets; + nss_top->stats_node[NSS_IPV4_RX_INTERFACE][NSS_STATS_NODE_RX_BYTES] += nins->node_stats.rx_bytes; + nss_top->stats_node[NSS_IPV4_RX_INTERFACE][NSS_STATS_NODE_TX_PKTS] += nins->node_stats.tx_packets; + nss_top->stats_node[NSS_IPV4_RX_INTERFACE][NSS_STATS_NODE_TX_BYTES] += nins->node_stats.tx_bytes; + + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + nss_top->stats_node[NSS_IPV4_RX_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + i] += nins->node_stats.rx_dropped[i]; + } + + nss_ipv4_stats[NSS_IPV4_STATS_CONNECTION_CREATE_REQUESTS] += nins->ipv4_connection_create_requests; + nss_ipv4_stats[NSS_IPV4_STATS_CONNECTION_CREATE_COLLISIONS] += nins->ipv4_connection_create_collisions; + nss_ipv4_stats[NSS_IPV4_STATS_CONNECTION_CREATE_INVALID_INTERFACE] += nins->ipv4_connection_create_invalid_interface; + nss_ipv4_stats[NSS_IPV4_STATS_CONNECTION_DESTROY_REQUESTS] += nins->ipv4_connection_destroy_requests; + nss_ipv4_stats[NSS_IPV4_STATS_CONNECTION_DESTROY_MISSES] += nins->ipv4_connection_destroy_misses; + nss_ipv4_stats[NSS_IPV4_STATS_CONNECTION_HASH_HITS] += nins->ipv4_connection_hash_hits; + nss_ipv4_stats[NSS_IPV4_STATS_CONNECTION_HASH_REORDERS] += nins->ipv4_connection_hash_reorders; + nss_ipv4_stats[NSS_IPV4_STATS_CONNECTION_FLUSHES] += nins->ipv4_connection_flushes; + nss_ipv4_stats[NSS_IPV4_STATS_CONNECTION_EVICTIONS] += nins->ipv4_connection_evictions; + nss_ipv4_stats[NSS_IPV4_STATS_FRAGMENTATIONS] += nins->ipv4_fragmentations; + nss_ipv4_stats[NSS_IPV4_STATS_MC_CONNECTION_CREATE_REQUESTS] += nins->ipv4_mc_connection_create_requests; + nss_ipv4_stats[NSS_IPV4_STATS_MC_CONNECTION_UPDATE_REQUESTS] += nins->ipv4_mc_connection_update_requests; + nss_ipv4_stats[NSS_IPV4_STATS_MC_CONNECTION_CREATE_INVALID_INTERFACE] += nins->ipv4_mc_connection_create_invalid_interface; + nss_ipv4_stats[NSS_IPV4_STATS_MC_CONNECTION_DESTROY_REQUESTS] += nins->ipv4_mc_connection_destroy_requests; + nss_ipv4_stats[NSS_IPV4_STATS_MC_CONNECTION_DESTROY_MISSES] += nins->ipv4_mc_connection_destroy_misses; + nss_ipv4_stats[NSS_IPV4_STATS_MC_CONNECTION_FLUSHES] += nins->ipv4_mc_connection_flushes; + + for (i = 0; i < NSS_IPV4_EXCEPTION_EVENT_MAX; i++) { + nss_ipv4_exception_stats[i] += nins->exception_events[i]; + } + spin_unlock_bh(&nss_top->stats_lock); +} + +/* + * nss_ipv4_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(ipv4); + +/* + * nss_ipv4_stats_dentry_create() + * Create IPv4 statistics debug entry. + */ +void nss_ipv4_stats_dentry_create(void) +{ + nss_stats_create_dentry("ipv4", &nss_ipv4_stats_ops); +} + +/* + * nss_ipv4_stats_notify() + * Sends notifications to the registered modules. + * + * Leverage NSS-FW statistics timing to update Netlink. + */ +void nss_ipv4_stats_notify(struct nss_ctx_instance *nss_ctx) +{ + struct nss_ipv4_stats_notification ipv4_stats; + + ipv4_stats.core_id = nss_ctx->id; + memcpy(ipv4_stats.cmn_node_stats, nss_top_main.stats_node[NSS_IPV4_RX_INTERFACE], sizeof(ipv4_stats.cmn_node_stats)); + memcpy(ipv4_stats.special_stats, nss_ipv4_stats, sizeof(ipv4_stats.special_stats)); + memcpy(ipv4_stats.exception_stats, nss_ipv4_exception_stats, sizeof(ipv4_stats.exception_stats)); + atomic_notifier_call_chain(&nss_ipv4_stats_notifier, NSS_STATS_EVENT_NOTIFY, (void *)&ipv4_stats); +} + +/* + * nss_ipv4_stats_register_notifier() + * Registers statistics notifier. + */ +int nss_ipv4_stats_register_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&nss_ipv4_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_ipv4_stats_register_notifier); + +/* + * nss_ipv4_stats_unregister_notifier() + * Deregisters statistics notifier. + */ +int nss_ipv4_stats_unregister_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&nss_ipv4_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_ipv4_stats_unregister_notifier); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_stats.h new file mode 100644 index 000000000..ad85c35a2 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_stats.h @@ -0,0 +1,29 @@ +/* + ************************************************************************** + * Copyright (c) 2017, 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_IPV4_STATS_H +#define __NSS_IPV4_STATS_H + +/* + * NSS IPV4 statistics APIs + */ +extern void nss_ipv4_stats_notify(struct nss_ctx_instance *nss_ctx); +extern void nss_ipv4_stats_node_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_node_sync *nins); +extern void nss_ipv4_stats_conn_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_conn_sync *nirs); +extern void nss_ipv4_stats_conn_sync_many(struct nss_ctx_instance *nss_ctx, struct nss_ipv4_conn_sync_many_msg *nicsm); +extern void nss_ipv4_stats_dentry_create(void); + +#endif /* __NSS_IPV4_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_strings.c b/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_strings.c new file mode 100644 index 000000000..434a4e054 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_strings.c @@ -0,0 +1,205 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_stats.h" +#include "nss_core.h" +#include +#include "nss_strings.h" + +/* + * nss_ipv4_strings_exception_stats + * Interface statistics strings for ipv4 exceptions. + */ +struct nss_stats_info nss_ipv4_strings_exception_stats[NSS_IPV4_EXCEPTION_EVENT_MAX] = { + {"icmp_hdr_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"icmp_unhandled_type" , NSS_STATS_TYPE_EXCEPTION}, + {"icmp_ipv4_hdr_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"icmp_ipv4_udp_hdr_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"icmp_ipv4_tcp_header_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"icmp_sipv4_unknown_protocol" , NSS_STATS_TYPE_EXCEPTION}, + {"icmp_no_icme" , NSS_STATS_TYPE_EXCEPTION}, + {"icmp_flush_to_host" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_header_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_no_icme" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_ip_option" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_ip_fragment" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_small_ttl" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_needs_fragmentation" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_flags" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_seq_exceeds_right_edge" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_small_data_offs" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_bad_sack" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_big_data_offs" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_seq_before_left_edge" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_ack_exceeds_right_edge" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_ack_before_left_edge" , NSS_STATS_TYPE_EXCEPTION}, + {"udp_header_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"udp_no_icme" , NSS_STATS_TYPE_EXCEPTION}, + {"udp_ip_option" , NSS_STATS_TYPE_EXCEPTION}, + {"udp_ip_fragment" , NSS_STATS_TYPE_EXCEPTION}, + {"udp_small_ttl" , NSS_STATS_TYPE_EXCEPTION}, + {"udp_needs_fragmentation" , NSS_STATS_TYPE_EXCEPTION}, + {"wrong_target_mac" , NSS_STATS_TYPE_EXCEPTION}, + {"header_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"bad_total_length" , NSS_STATS_TYPE_EXCEPTION}, + {"bad_checksum" , NSS_STATS_TYPE_EXCEPTION}, + {"non_initial_fragment" , NSS_STATS_TYPE_EXCEPTION}, + {"datagram_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"options_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"unknown_protocol" , NSS_STATS_TYPE_EXCEPTION}, + {"esp_header_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"esp_no_icme" , NSS_STATS_TYPE_EXCEPTION}, + {"esp_ip_option" , NSS_STATS_TYPE_EXCEPTION}, + {"esp_ip_fragment" , NSS_STATS_TYPE_EXCEPTION}, + {"esp_small_ttl" , NSS_STATS_TYPE_EXCEPTION}, + {"esp_needs_fragmentation" , NSS_STATS_TYPE_EXCEPTION}, + {"ingress_vid_mismatch" , NSS_STATS_TYPE_EXCEPTION}, + {"ingress_vid_missing" , NSS_STATS_TYPE_EXCEPTION}, + {"6rd_no_icme" , NSS_STATS_TYPE_EXCEPTION}, + {"6rd_ip_option" , NSS_STATS_TYPE_EXCEPTION}, + {"6rd_ip_fragment" , NSS_STATS_TYPE_EXCEPTION}, + {"6rd_needs_fragmentation" , NSS_STATS_TYPE_EXCEPTION}, + {"dscp_marking_mismatch" , NSS_STATS_TYPE_EXCEPTION}, + {"vlan_marking_mismatch" , NSS_STATS_TYPE_EXCEPTION}, + {"interface_mismatch" , NSS_STATS_TYPE_EXCEPTION}, + {"gre_header_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"gre_no_icme" , NSS_STATS_TYPE_EXCEPTION}, + {"gre_ip_option" , NSS_STATS_TYPE_EXCEPTION}, + {"gre_ip_fragment" , NSS_STATS_TYPE_EXCEPTION}, + {"gre_small_ttl" , NSS_STATS_TYPE_EXCEPTION}, + {"gre_needs_fragmentation" , NSS_STATS_TYPE_EXCEPTION}, + {"pptp_gre_session_match_fail" , NSS_STATS_TYPE_EXCEPTION}, + {"pptp_gre_invalid_proto" , NSS_STATS_TYPE_EXCEPTION}, + {"pptp_gre_no_cme" , NSS_STATS_TYPE_EXCEPTION}, + {"pptp_gre_ip_option" , NSS_STATS_TYPE_EXCEPTION}, + {"pptp_gre_ip_fragment" , NSS_STATS_TYPE_EXCEPTION}, + {"pptp_gre_small_ttl" , NSS_STATS_TYPE_EXCEPTION}, + {"pptp_gre_needs_fragmentation" , NSS_STATS_TYPE_EXCEPTION}, + {"destroy" , NSS_STATS_TYPE_EXCEPTION}, + {"frag_df_set" , NSS_STATS_TYPE_EXCEPTION}, + {"frag_fail" , NSS_STATS_TYPE_EXCEPTION}, + {"icmp_ipv4_udplite_header_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"udplite_header_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"udplite_no_icme" , NSS_STATS_TYPE_EXCEPTION}, + {"udplite_ip_option" , NSS_STATS_TYPE_EXCEPTION}, + {"udplite_ip_fragment" , NSS_STATS_TYPE_EXCEPTION}, + {"udplite_small_ttl" , NSS_STATS_TYPE_EXCEPTION}, + {"udplite_needs_fragmentation" , NSS_STATS_TYPE_EXCEPTION}, + {"mc_udp_no_icme" , NSS_STATS_TYPE_EXCEPTION}, + {"mc_mem_alloc_failure" , NSS_STATS_TYPE_EXCEPTION}, + {"mc_update_failure" , NSS_STATS_TYPE_EXCEPTION}, + {"mc_pbuf_alloc_failure" , NSS_STATS_TYPE_EXCEPTION}, + {"pppoe_bridge_no_icme" , NSS_STATS_TYPE_EXCEPTION}, + {"pppoe_no_session" , NSS_STATS_TYPE_DROP}, + {"icmp_ipv4_gre_hdr_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"icmp_ipv4_esp_hdr_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"emesh_prio_mismatch" , NSS_STATS_TYPE_EXCEPTION}, +}; + +/* + * nss_ipv4_strings_stats + * IPv4 statistics strings. + */ +struct nss_stats_info nss_ipv4_strings_stats[NSS_IPV4_STATS_MAX] = { + {"rx_pkts" , NSS_STATS_TYPE_SPECIAL}, + {"rx_bytes" , NSS_STATS_TYPE_SPECIAL}, + {"tx_pkts" , NSS_STATS_TYPE_SPECIAL}, + {"tx_bytes" , NSS_STATS_TYPE_SPECIAL}, + {"create_requests" , NSS_STATS_TYPE_SPECIAL}, + {"create_collisions" , NSS_STATS_TYPE_SPECIAL}, + {"create_invalid_interface" , NSS_STATS_TYPE_SPECIAL}, + {"destroy_requests" , NSS_STATS_TYPE_SPECIAL}, + {"destroy_misses" , NSS_STATS_TYPE_SPECIAL}, + {"hash_hits" , NSS_STATS_TYPE_SPECIAL}, + {"hash_reorders" , NSS_STATS_TYPE_SPECIAL}, + {"flushes" , NSS_STATS_TYPE_SPECIAL}, + {"evictions" , NSS_STATS_TYPE_SPECIAL}, + {"fragmentations" , NSS_STATS_TYPE_SPECIAL}, + {"by_rule_drops" , NSS_STATS_TYPE_DROP}, + {"mc_create_requests" , NSS_STATS_TYPE_SPECIAL}, + {"mc_update_requests" , NSS_STATS_TYPE_SPECIAL}, + {"mc_create_invalid_interface" , NSS_STATS_TYPE_SPECIAL}, + {"mc_destroy_requests" , NSS_STATS_TYPE_SPECIAL}, + {"mc_destroy_misses" , NSS_STATS_TYPE_SPECIAL}, + {"mc_flushes" , NSS_STATS_TYPE_SPECIAL} +}; + +/* + * nss_ipv4_special_stats_strings_read() + * Read IPV4 special node statistics names. + */ +static ssize_t nss_ipv4_special_stats_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_ipv4_strings_stats, NSS_IPV4_STATS_MAX); +} + +/* + * nss_ipv4_exception_stats_strings_read() + * Read IPV4 exception statistics names. + */ +static ssize_t nss_ipv4_exception_stats_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_ipv4_strings_exception_stats, NSS_IPV4_EXCEPTION_EVENT_MAX); +} + +/* + * nss_ipv4_special_stats_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(ipv4_special_stats); + +/* + * nss_ipv4_exception_stats_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(ipv4_exception_stats); + +/* + * nss_ipv4_strings_dentry_create() + * Create IPv4 statistics strings debug entry. + */ +void nss_ipv4_strings_dentry_create(void) +{ + struct dentry *dir_d; + struct dentry *file_d; + + if (!nss_top_main.strings_dentry) { + nss_warning("qca-nss-drv/strings is not present"); + return; + } + + dir_d = debugfs_create_dir("ipv4", nss_top_main.strings_dentry); + if (!dir_d) { + nss_warning("Failed to create qca-nss-drv/strings/ipv4 directory"); + return; + } + + file_d = debugfs_create_file("special_stats_str", 0400, dir_d, &nss_top_main, &nss_ipv4_special_stats_strings_ops); + if (!file_d) { + nss_warning("Failed to create qca-nss-drv/stats/ipv4/special_stats_str file"); + goto fail; + } + + file_d = debugfs_create_file("exception_stats_str", 0400, dir_d, &nss_top_main, &nss_ipv4_exception_stats_strings_ops); + if (!file_d) { + nss_warning("Failed to create qca-nss-drv/stats/ipv4/exception_stats_str file"); + goto fail; + } + + return; +fail: + debugfs_remove_recursive(dir_d); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_strings.h b/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_strings.h new file mode 100644 index 000000000..fd819c769 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipv4_strings.h @@ -0,0 +1,26 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_IPV4_STRINGS_H +#define __NSS_IPV4_STRINGS_H + +extern struct nss_stats_info nss_ipv4_strings_stats[NSS_IPV4_STATS_MAX]; +extern struct nss_stats_info nss_ipv4_strings_exception_stats[NSS_IPV4_EXCEPTION_EVENT_MAX]; +extern void nss_ipv4_strings_dentry_create(void); + +#endif /* __NSS_IPV4_STRINGS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipv6.c b/feeds/ipq807x/qca-nss-drv/src/nss_ipv6.c new file mode 100644 index 000000000..4ee3f69d9 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipv6.c @@ -0,0 +1,776 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_ipv6.c + * NSS IPv6 APIs + */ +#include +#include "nss_dscp_map.h" +#include "nss_ipv6_stats.h" +#include "nss_ipv6_strings.h" + +#define NSS_IPV6_TX_MSG_TIMEOUT 1000 /* 1 sec timeout for IPv6 messages */ + +/* + * Private data structure for ipv6 configure messages + */ +struct nss_ipv6_cfg_pvt { + struct semaphore sem; /* Semaphore structure */ + struct completion complete; /* Completion structure */ + int response; /* Response from FW */ + void *cb; /* Original cb for sync msgs */ + void *app_data; /* Original app_data for sync msgs */ +} nss_ipv6_pvt; + +/* + * Private data structure for ipv6 connection information. + */ +struct nss_ipv6_conn_table_info { + uint32_t ce_table_size; /* Size of connection entry table in NSS FW */ + uint32_t cme_table_size; /* Size of connection match entry table in NSS FW */ + unsigned long ce_mem; /* Start address for connection entry table */ + unsigned long cme_mem; /* Start address for connection match entry table */ +} nss_ipv6_ct_info; + +int nss_ipv6_conn_cfg = NSS_DEFAULT_NUM_CONN; +int nss_ipv6_accel_mode_cfg __read_mostly = 1; + +static struct nss_dscp_map_entry mapping[NSS_DSCP_MAP_ARRAY_SIZE]; + +/* + * Callback for conn_sync_many request message. + */ +nss_ipv6_msg_callback_t nss_ipv6_conn_sync_many_msg_cb = NULL; + +/* + * nss_ipv6_dscp_map_usage() + * Help function shows the usage of the command. + */ +static inline void nss_ipv6_dscp_map_usage(void) +{ + nss_info_always("\nUsage:\n"); + nss_info_always("echo > /proc/sys/dev/nss/ipv6cfg/ipv6_dscp_map\n\n"); + nss_info_always("dscp[0-63] action[0-%u] prio[0-%u]:\n\n", + NSS_IPV6_DSCP_MAP_ACTION_MAX - 1, + NSS_DSCP_MAP_PRIORITY_MAX - 1); +} + +/* + * nss_ipv6_rx_msg_handler() + * Handle NSS -> HLOS messages for IPv6 bridge/route + */ +static void nss_ipv6_rx_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_ipv6_msg *nim = (struct nss_ipv6_msg *)ncm; + nss_ipv6_msg_callback_t cb; + + BUG_ON(ncm->interface != NSS_IPV6_RX_INTERFACE); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_IPV6_MAX_MSG_TYPES) { + nss_warning("%px: received invalid message %d for IPv6 interface", nss_ctx, nim->cm.type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_ipv6_msg)) { + nss_warning("%px: message length is invalid: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Trace messages. + */ + nss_ipv6_log_rx_msg(nim); + + /* + * Handle deprecated messages. Eventually these messages should be removed. + */ + switch (nim->cm.type) { + case NSS_IPV6_RX_NODE_STATS_SYNC_MSG: + /* + * Update driver statistics on node sync and send statistics notifications to the registered modules. + */ + nss_ipv6_stats_node_sync(nss_ctx, &nim->msg.node_stats); + nss_ipv6_stats_notify(nss_ctx); + break; + + case NSS_IPV6_RX_CONN_STATS_SYNC_MSG: + /* + * Update driver statistics on connection sync. + */ + nss_ipv6_stats_conn_sync(nss_ctx, &nim->msg.conn_stats); + break; + + case NSS_IPV6_TX_CONN_STATS_SYNC_MANY_MSG: + /* + * Update driver statistics on connection sync many. + */ + nss_ipv6_stats_conn_sync_many(nss_ctx, &nim->msg.conn_stats_many); + ncm->cb = (nss_ptr_t)nss_ipv6_conn_sync_many_msg_cb; + break; + } + + /* + * Update the callback and app_data for NOTIFY messages, IPv6 sends all notify messages + * to the same callback/app_data. + */ + if (nim->cm.response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_ctx->nss_top->ipv6_callback; + ncm->app_data = (nss_ptr_t)nss_ctx->nss_top->ipv6_ctx; + } + + /* + * Do we have a callback? + */ + if (!ncm->cb) { + return; + } + + /* + * Callback + */ + cb = (nss_ipv6_msg_callback_t)ncm->cb; + cb((void *)ncm->app_data, nim); +} + +/* + * nss_ipv6_tx_sync_callback() + * Callback to handle the completion of synchronous tx messages. + */ +static void nss_ipv6_tx_sync_callback(void *app_data, struct nss_ipv6_msg *nim) +{ + nss_ipv6_msg_callback_t callback = (nss_ipv6_msg_callback_t)nss_ipv6_pvt.cb; + void *data = nss_ipv6_pvt.app_data; + + nss_ipv6_pvt.cb = NULL; + nss_ipv6_pvt.app_data = NULL; + + if (nim->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("ipv6 error response %d\n", nim->cm.response); + nss_ipv6_pvt.response = NSS_TX_FAILURE; + } else { + nss_ipv6_pvt.response = NSS_TX_SUCCESS; + } + + if (callback) { + callback(data, nim); + } + + complete(&nss_ipv6_pvt.complete); +} + +/* + * nss_ipv6_dscp_action_get() + * Gets the action mapped to dscp. + */ +enum nss_ipv6_dscp_map_actions nss_ipv6_dscp_action_get(uint8_t dscp) +{ + if (dscp >= NSS_DSCP_MAP_ARRAY_SIZE) { + nss_warning("dscp:%u invalid\n", dscp); + return NSS_IPV6_DSCP_MAP_ACTION_MAX; + } + + return mapping[dscp].action; +} +EXPORT_SYMBOL(nss_ipv6_dscp_action_get); + +/* + * nss_ipv6_max_conn_count() + * Return the maximum number of IPv6 connections that the NSS acceleration engine supports. + */ +int nss_ipv6_max_conn_count(void) +{ + return nss_ipv6_conn_cfg; +} +EXPORT_SYMBOL(nss_ipv6_max_conn_count); + +/* + * nss_ipv6_conn_inquiry() + * Inquiry if a connection has been established in NSS FW + */ +nss_tx_status_t nss_ipv6_conn_inquiry(struct nss_ipv6_5tuple *ipv6_5t_p, + nss_ipv6_msg_callback_t cb) +{ + nss_tx_status_t nss_tx_status; + struct nss_ipv6_msg nim; + struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[0]; + + /* + * Initialize inquiry message structure. + * This is async message and the result will be returned + * to the caller by the msg_callback passed in. + */ + memset(&nim, 0, sizeof(nim)); + nss_ipv6_msg_init(&nim, NSS_IPV6_RX_INTERFACE, + NSS_IPV6_TX_CONN_CFG_INQUIRY_MSG, + sizeof(struct nss_ipv6_inquiry_msg), + cb, NULL); + nim.msg.inquiry.rr.tuple = *ipv6_5t_p; + nss_tx_status = nss_ipv6_tx(nss_ctx, &nim); + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: Send inquiry message failed\n", ipv6_5t_p); + } + + return nss_tx_status; +} +EXPORT_SYMBOL(nss_ipv6_conn_inquiry); + +/* + * nss_ipv6_tx_with_size() + * Transmit an ipv6 message to the FW with a specified size. + */ +nss_tx_status_t nss_ipv6_tx_with_size(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_msg *nim, uint32_t size) +{ + struct nss_cmn_msg *ncm = &nim->cm; + + /* + * Sanity check the message + */ + if (ncm->interface != NSS_IPV6_RX_INTERFACE) { + nss_warning("%px: tx request for another interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type >= NSS_IPV6_MAX_MSG_TYPES) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + /* + * Trace messages. + */ + nss_ipv6_log_tx_msg(nim); + + return nss_core_send_cmd(nss_ctx, nim, sizeof(*nim), size); +} +EXPORT_SYMBOL(nss_ipv6_tx_with_size); + +/* + * nss_ipv6_tx() + * Transmit an ipv6 message to the FW. + */ +nss_tx_status_t nss_ipv6_tx(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_msg *nim) +{ + return nss_ipv6_tx_with_size(nss_ctx, nim, NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_ipv6_tx); + +/* + * nss_ipv6_tx_sync() + * Transmit a synchronous ipv6 message to the FW. + */ +nss_tx_status_t nss_ipv6_tx_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_msg *nim) +{ + nss_tx_status_t status; + int ret = 0; + + down(&nss_ipv6_pvt.sem); + nss_ipv6_pvt.cb = (void *)nim->cm.cb; + nss_ipv6_pvt.app_data = (void *)nim->cm.app_data; + + nim->cm.cb = (nss_ptr_t)nss_ipv6_tx_sync_callback; + nim->cm.app_data = (nss_ptr_t)NULL; + + status = nss_ipv6_tx(nss_ctx, nim); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: nss ipv6 msg tx failed\n", nss_ctx); + up(&nss_ipv6_pvt.sem); + return status; + } + + ret = wait_for_completion_timeout(&nss_ipv6_pvt.complete, msecs_to_jiffies(NSS_IPV6_TX_MSG_TIMEOUT)); + if (!ret) { + nss_warning("%px: IPv6 tx sync failed due to timeout\n", nss_ctx); + nss_ipv6_pvt.response = NSS_TX_FAILURE; + } + + status = nss_ipv6_pvt.response; + up(&nss_ipv6_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_ipv6_tx_sync); + +/* + ********************************** + Register/Unregister/Miscellaneous APIs + ********************************** + */ + +/* + * nss_ipv6_notify_register() + * Register to received IPv6 events. + * + * NOTE: Do we want to pass an nss_ctx here so that we can register for ipv6 on any core? + */ +struct nss_ctx_instance *nss_ipv6_notify_register(nss_ipv6_msg_callback_t cb, void *app_data) +{ + /* + * TODO: We need to have a new array in support of the new API + * TODO: If we use a per-context array, we would move the array into nss_ctx based. + */ + nss_top_main.ipv6_callback = cb; + nss_top_main.ipv6_ctx = app_data; + return &nss_top_main.nss[nss_top_main.ipv6_handler_id]; +} +EXPORT_SYMBOL(nss_ipv6_notify_register); + +/* + * nss_ipv6_notify_unregister() + * Unregister to received IPv6 events. + * + * NOTE: Do we want to pass an nss_ctx here so that we can register for ipv6 on any core? + */ +void nss_ipv6_notify_unregister(void) +{ + nss_top_main.ipv6_callback = NULL; +} +EXPORT_SYMBOL(nss_ipv6_notify_unregister); + +/* + * nss_ipv6_conn_sync_many_notify_register() + * Register to receive IPv6 conn_sync_many message response. + */ +void nss_ipv6_conn_sync_many_notify_register(nss_ipv6_msg_callback_t cb) +{ + nss_ipv6_conn_sync_many_msg_cb = cb; +} +EXPORT_SYMBOL(nss_ipv6_conn_sync_many_notify_register); + +/* + * nss_ipv6_conn_sync_many_notify_unregister() + * Unregister to receive IPv6 conn_sync_many message response. + */ +void nss_ipv6_conn_sync_many_notify_unregister(void) +{ + nss_ipv6_conn_sync_many_msg_cb = NULL; +} +EXPORT_SYMBOL(nss_ipv6_conn_sync_many_notify_unregister); + +/* + * nss_ipv6_get_mgr() + * + * TODO: This only suppports a single ipv6, do we ever want to support more? + */ +struct nss_ctx_instance *nss_ipv6_get_mgr(void) +{ + return (void *)&nss_top_main.nss[nss_top_main.ipv6_handler_id]; +} +EXPORT_SYMBOL(nss_ipv6_get_mgr); + +/* + * nss_ipv6_register_handler() + * Register our handler to receive messages for this interface + */ +void nss_ipv6_register_handler() +{ + struct nss_ctx_instance *nss_ctx = nss_ipv6_get_mgr(); + + if (nss_core_register_handler(nss_ctx, NSS_IPV6_RX_INTERFACE, nss_ipv6_rx_msg_handler, NULL) != NSS_CORE_STATUS_SUCCESS) { + nss_warning("IPv6 handler failed to register"); + } + + nss_ipv6_stats_dentry_create(); + nss_ipv6_strings_dentry_create(); +} + +/* + * nss_ipv6_conn_cfg_process_callback() + * Call back function for the ipv6 connection configuration process. + */ +static void nss_ipv6_conn_cfg_process_callback(void *app_data, struct nss_ipv6_msg *nim) +{ + struct nss_ipv6_rule_conn_cfg_msg *nirccm = &nim->msg.rule_conn_cfg; + struct nss_ctx_instance *nss_ctx __maybe_unused = nss_ipv6_get_mgr(); + + if (nim->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("%px: IPv6 connection configuration failed with error: %d\n", nss_ctx, nim->cm.error); + nss_core_update_max_ipv6_conn(NSS_FW_DEFAULT_NUM_CONN); + nss_ipv6_free_conn_tables(); + return; + } + + nss_ipv6_conn_cfg = ntohl(nirccm->num_conn); + + nss_info("%px: IPv6 connection configuration success: %d\n", nss_ctx, nim->cm.error); +} + +/* + * nss_ipv6_conn_cfg_process() + * Process request to configure number of ipv6 connections + */ +static int nss_ipv6_conn_cfg_process(struct nss_ctx_instance *nss_ctx, int conn) +{ + struct nss_ipv6_msg nim; + struct nss_ipv6_rule_conn_cfg_msg *nirccm; + nss_tx_status_t nss_tx_status; + + if ((!nss_ipv6_ct_info.ce_table_size) || (!nss_ipv6_ct_info.cme_table_size)) { + nss_warning("%px: connection entry or connection match entry table size not available\n", + nss_ctx); + return -EINVAL; + } + + nss_info("%px: IPv6 supported connections: %d\n", nss_ctx, conn); + + nss_ipv6_ct_info.ce_mem = __get_free_pages(GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO, + get_order(nss_ipv6_ct_info.ce_table_size)); + if (!nss_ipv6_ct_info.ce_mem) { + nss_warning("%px: Memory allocation failed for IPv6 Connections: %d\n", + nss_ctx, + conn); + goto fail; + } + nss_info("%px: CE Memory allocated for IPv6 Connections: %d\n", + nss_ctx, + conn); + + nss_ipv6_ct_info.cme_mem = __get_free_pages(GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO, + get_order(nss_ipv6_ct_info.cme_table_size)); + if (!nss_ipv6_ct_info.cme_mem) { + nss_warning("%px: Memory allocation failed for IPv6 Connections: %d\n", + nss_ctx, + conn); + goto fail; + } + nss_info("%px: CME Memory allocated for IPv6 Connections: %d\n", + nss_ctx, + conn); + + memset(&nim, 0, sizeof(struct nss_ipv6_msg)); + nss_ipv6_msg_init(&nim, NSS_IPV6_RX_INTERFACE, NSS_IPV6_TX_CONN_CFG_RULE_MSG, + sizeof(struct nss_ipv6_rule_conn_cfg_msg), nss_ipv6_conn_cfg_process_callback, NULL); + + nirccm = &nim.msg.rule_conn_cfg; + nirccm->num_conn = htonl(conn); + nirccm->ce_mem = dma_map_single(nss_ctx->dev, (void *)nss_ipv6_ct_info.ce_mem, nss_ipv6_ct_info.ce_table_size, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(nss_ctx->dev, nirccm->ce_mem))) { + nss_warning("%px: DMA mapping failed for virtual address = %px", nss_ctx, (void *)nss_ipv6_ct_info.ce_mem); + goto fail; + } + + nirccm->cme_mem = dma_map_single(nss_ctx->dev, (void *)nss_ipv6_ct_info.cme_mem, nss_ipv6_ct_info.cme_table_size, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(nss_ctx->dev, nirccm->cme_mem))) { + nss_warning("%px: DMA mapping failed for virtual address = %px", nss_ctx, (void *)nss_ipv6_ct_info.cme_mem); + goto fail; + } + + nss_tx_status = nss_ipv6_tx(nss_ctx, &nim); + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: nss_tx error setting IPv6 Connections: %d\n", + nss_ctx, + conn); + goto fail; + } + + return 0; + +fail: + nss_ipv6_free_conn_tables(); + return -EINVAL; +} + +/* + * nss_ipv6_update_conn_count_callback() + * Call back function for the ipv6 get connection info message. + */ +static void nss_ipv6_update_conn_count_callback(void *app_data, struct nss_ipv6_msg *nim) +{ + struct nss_ipv6_rule_conn_get_table_size_msg *nircgts = &nim->msg.size; + struct nss_ctx_instance *nss_ctx = nss_ipv6_get_mgr(); + + if (nim->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("%px: IPv6 fetch connection info failed with error: %d\n", nss_ctx, nim->cm.error); + nss_core_update_max_ipv6_conn(NSS_FW_DEFAULT_NUM_CONN); + return; + } + + nss_info("IPv6 get connection info success\n"); + + nss_ipv6_ct_info.ce_table_size = ntohl(nircgts->ce_table_size); + nss_ipv6_ct_info.cme_table_size = ntohl(nircgts->cme_table_size); + + if (nss_ipv6_conn_cfg_process(nss_ctx, ntohl(nircgts->num_conn)) != 0) { + nss_warning("%px: IPv6 connection entry or connection match entry table size\ + not available\n", nss_ctx); + } + + return; +} + +/* + * nss_ipv6_update_conn_count() + * Sets the maximum number of IPv6 connections. + * + * It first gets the connection tables size information from NSS FW + * and then configures the connections in NSS FW. + */ +int nss_ipv6_update_conn_count(int ipv6_num_conn) +{ + struct nss_ctx_instance *nss_ctx = nss_ipv6_get_mgr(); + struct nss_ipv6_msg nim; + struct nss_ipv6_rule_conn_get_table_size_msg *nircgts; + nss_tx_status_t nss_tx_status; + uint32_t sum_of_conn; + + /* + * By default, NSS FW is configured with default number of connections. + */ + if (ipv6_num_conn == NSS_FW_DEFAULT_NUM_CONN) { + nss_info("%px: Default number of connections (%d) already configured\n", nss_ctx, ipv6_num_conn); + return 0; + } + + /* + * Specifications for input + * 1) The input should be power of 2. + * 2) Input for ipv4 and ipv6 sum togther should not exceed 8k + * 3) Min. value should be at leat 256 connections. This is the + * minimum connections we will support for each of them. + */ + sum_of_conn = nss_ipv4_conn_cfg + ipv6_num_conn; + if ((ipv6_num_conn & NSS_NUM_CONN_QUANTA_MASK) || + (sum_of_conn > NSS_MAX_TOTAL_NUM_CONN_IPV4_IPV6) || + (ipv6_num_conn < NSS_MIN_NUM_CONN)) { + nss_warning("%px: input supported connections (%d) does not adhere\ + specifications\n1) not power of 2,\n2) is less than \ + min val: %d, OR\n IPv4/6 total exceeds %d\n", + nss_ctx, + ipv6_num_conn, + NSS_MIN_NUM_CONN, + NSS_MAX_TOTAL_NUM_CONN_IPV4_IPV6); + return -EINVAL; + } + + memset(&nim, 0, sizeof(struct nss_ipv6_msg)); + nss_ipv6_msg_init(&nim, NSS_IPV6_RX_INTERFACE, NSS_IPV6_TX_CONN_TABLE_SIZE_MSG, + sizeof(struct nss_ipv6_rule_conn_get_table_size_msg), nss_ipv6_update_conn_count_callback, NULL); + + nircgts = &nim.msg.size; + nircgts->num_conn = htonl(ipv6_num_conn); + nss_tx_status = nss_ipv6_tx(nss_ctx, &nim); + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: Send acceleration mode message failed\n", nss_ctx); + return -EINVAL; + } + + return 0; +} + +/* + * nss_ipv6_free_conn_tables() + * Frees memory allocated for connection tables + */ +void nss_ipv6_free_conn_tables(void) +{ + if (nss_ipv6_ct_info.ce_mem) { + free_pages(nss_ipv6_ct_info.ce_mem, get_order(nss_ipv6_ct_info.ce_table_size)); + } + + if (nss_ipv6_ct_info.cme_mem) { + free_pages(nss_ipv6_ct_info.cme_mem, get_order(nss_ipv6_ct_info.cme_table_size)); + } + + memset(&nss_ipv6_ct_info, 0, sizeof(struct nss_ipv6_conn_table_info)); + return; +} + +/* + * nss_ipv6_accel_mode_cfg_handler() + * Configure acceleration mode for IPv6 + */ +static int nss_ipv6_accel_mode_cfg_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[0]; + struct nss_ipv6_msg nim; + struct nss_ipv6_accel_mode_cfg_msg *nipcm; + nss_tx_status_t nss_tx_status; + int ret = NSS_FAILURE; + int current_value; + + /* + * Take snap shot of current value + */ + current_value = nss_ipv6_accel_mode_cfg; + + /* + * Write the variable with user input + */ + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + if (ret || (!write)) { + return ret; + } + + memset(&nim, 0, sizeof(struct nss_ipv6_msg)); + nss_ipv6_msg_init(&nim, NSS_IPV6_RX_INTERFACE, NSS_IPV6_TX_ACCEL_MODE_CFG_MSG, + sizeof(struct nss_ipv6_accel_mode_cfg_msg), NULL, NULL); + + nipcm = &nim.msg.accel_mode_cfg; + nipcm->mode = htonl(nss_ipv6_accel_mode_cfg); + + nss_tx_status = nss_ipv6_tx_sync(nss_ctx, &nim); + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: Send acceleration mode message failed\n", nss_ctx); + nss_ipv6_accel_mode_cfg = current_value; + return -EIO; + } + + return 0; +} + +/* + * nss_ipv6_dscp_map_cfg_handler() + * Sysctl handler for dscp/pri mappings. + */ +static int nss_ipv6_dscp_map_cfg_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[0]; + struct nss_dscp_map_parse out; + struct nss_ipv6_msg nim; + struct nss_ipv6_dscp2pri_cfg_msg *nipd2p; + nss_tx_status_t status; + int ret; + + if (!write) { + return nss_dscp_map_print(ctl, buffer, lenp, ppos, mapping); + } + + ret = nss_dscp_map_parse(ctl, buffer, lenp, ppos, &out); + if (ret) { + nss_warning("failed to parse dscp mapping:%d\n", ret); + return ret; + } + + if (out.action >= NSS_IPV6_DSCP_MAP_ACTION_MAX) { + nss_warning("invalid action value: %d\n", out.action); + nss_ipv6_dscp_map_usage(); + return -EINVAL; + } + + memset(&nim, 0, sizeof(struct nss_ipv6_msg)); + nss_ipv6_msg_init(&nim, NSS_IPV6_RX_INTERFACE, NSS_IPV6_TX_DSCP2PRI_CFG_MSG, + sizeof(struct nss_ipv6_dscp2pri_cfg_msg), NULL, NULL); + + nipd2p = &nim.msg.dscp2pri_cfg; + nipd2p->dscp = out.dscp; + nipd2p->priority = out.priority; + + status = nss_ipv6_tx_sync(nss_ctx, &nim); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: ipv6 dscp2pri config message failed\n", nss_ctx); + return -EFAULT; + } + + /* + * NSS firmware acknowleged the configuration, so update the mapping + * table on HOST side as well. + */ + mapping[out.dscp].action = out.action; + mapping[out.dscp].priority = out.priority; + + return 0; +} + +static struct ctl_table nss_ipv6_table[] = { + { + .procname = "ipv6_accel_mode", + .data = &nss_ipv6_accel_mode_cfg, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_ipv6_accel_mode_cfg_handler, + }, + { + .procname = "ipv6_dscp_map", + .data = &mapping[NSS_DSCP_MAP_ARRAY_SIZE], + .maxlen = sizeof(struct nss_dscp_map_entry), + .mode = 0644, + .proc_handler = &nss_ipv6_dscp_map_cfg_handler, + }, + { } +}; + +static struct ctl_table nss_ipv6_dir[] = { + { + .procname = "ipv6cfg", + .mode = 0555, + .child = nss_ipv6_table, + }, + { } +}; + +static struct ctl_table nss_ipv6_root_dir[] = { + { + .procname = "nss", + .mode = 0555, + .child = nss_ipv6_dir, + }, + { } +}; + +static struct ctl_table nss_ipv6_root[] = { + { + .procname = "dev", + .mode = 0555, + .child = nss_ipv6_root_dir, + }, + { } +}; + +static struct ctl_table_header *nss_ipv6_header; + +/* + * nss_ipv6_register_sysctl() + * Register sysctl specific to ipv6 + */ +void nss_ipv6_register_sysctl(void) +{ + sema_init(&nss_ipv6_pvt.sem, 1); + init_completion(&nss_ipv6_pvt.complete); + + /* + * Register sysctl table. + */ + nss_ipv6_header = register_sysctl_table(nss_ipv6_root); +} + +/* + * nss_ipv6_unregister_sysctl() + * Unregister sysctl specific to ipv6 + */ +void nss_ipv6_unregister_sysctl(void) +{ + /* + * Unregister sysctl table. + */ + if (nss_ipv6_header) { + unregister_sysctl_table(nss_ipv6_header); + } +} + +/* + * nss_ipv6_msg_init() + * Initialize IPv6 message. + */ +void nss_ipv6_msg_init(struct nss_ipv6_msg *nim, uint16_t if_num, uint32_t type, uint32_t len, + nss_ipv6_msg_callback_t cb, void *app_data) +{ + nss_cmn_msg_init(&nim->cm, if_num, type, len, (void *)cb, app_data); +} +EXPORT_SYMBOL(nss_ipv6_msg_init); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_log.c new file mode 100644 index 000000000..f04d1db39 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_log.c @@ -0,0 +1,383 @@ +/* + ************************************************************************** + * Copyright (c) 2016, 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_ipv6_log.c + * NSS IPv6 logger file. + */ + +#include "nss_core.h" + +/* + * This macro converts IPv6 address to network format + */ +#define NSS_IPV6_ADDR_TO_NW(nss6, nw) \ + { \ + nw[0] = htonl(nss6[0]); \ + nw[1] = htonl(nss6[1]); \ + nw[2] = htonl(nss6[2]); \ + nw[3] = htonl(nss6[3]); \ + } + +/* + * nss_ipv6_log_message_types_str + * IPv6 bridge/route rule messages strings + */ +static int8_t *nss_ipv6_log_message_types_str[NSS_IPV6_MAX_MSG_TYPES] __maybe_unused = { + "IPv6 create rule message", + "IPv6 destroy rule message", + "Deprecated: NSS_IPV4_RX_ESTABLISH_RULE_MSG", + "IPv6 connection stats sync message", + "IPv6 generic statistics sync message", + "IPv6 number of connections supported rule message", + "IPv6 multicast create rule message", + "IPv6 request FW to send many conn sync message", +}; + +/* + * nss_ipv6_log_error_response_types_str + * Strings for error types for ipv6 messages + */ +static int8_t *nss_ipv6_log_error_response_types_str[] __maybe_unused = { + "No error", + "Unknown error", + "Invalid interface number", + "Missing connection rule", + "Buffer allocation failure", + "No connection found to delete", + "Conn cfg already done once", + "Conn cfg input is not multiple of quanta", + "Conn cfg input exceeds max supported connections", + "Conn cfg mem alloc fail at NSS FW", + "Invalid L4 protocol for multicast rule create", + "Invalid multicast flags for multicast update", + "Invalid interface for multicast update", +}; + +/* + * nss_ipv6_log_rule_create_msg() + * Log IPv6 create rule message. + */ +static void nss_ipv6_log_rule_create_msg(struct nss_ipv6_msg *nim) +{ + uint32_t src_ip[4]; + uint32_t dest_ip[4]; + struct nss_ipv6_rule_create_msg *nircm = &nim->msg.rule_create; + + NSS_IPV6_ADDR_TO_NW(nircm->tuple.flow_ip, src_ip); + NSS_IPV6_ADDR_TO_NW(nircm->tuple.return_ip, dest_ip); + + nss_trace("%px: IPv6 create rule message \n" + "Protocol: %d\n" + "from_mtu: %u\n" + "to_mtu: %u\n" + "from_ip: %pI6:%d\n" + "to_ip: %pI6:%d\n" + "from_mac: %pM\n" + "to_mac: %pM\n" + "src_iface_num: %u\n" + "dest_iface_num: %u\n" + "ingress_inner_vlan_tag: %u\n" + "egress_inner_vlan_tag: %u\n" + "ingress_outer_vlan_tag: %u\n" + "egress_outer_vlan_tag: %u\n" + "rule_flags: %x\n" + "valid_flags: %x\n" + "return_pppoe_if_exist: %u\n" + "return_pppoe_if_num: %u\n" + "flow_pppoe_if_exist: %u\n" + "flow_pppoe_if_num: %u\n" + "flow_qos_tag: %x (%u)\n" + "return_qos_tag: %x (%u)\n" + "flow_dscp: %x\n" + "return_dscp: %x\n", + nim, + nircm->tuple.protocol, + nircm->conn_rule.flow_mtu, + nircm->conn_rule.return_mtu, + src_ip, nircm->tuple.flow_ident, + dest_ip, nircm->tuple.return_ident, + nircm->conn_rule.flow_mac, + nircm->conn_rule.return_mac, + nircm->conn_rule.flow_interface_num, + nircm->conn_rule.return_interface_num, + nircm->vlan_primary_rule.ingress_vlan_tag, + nircm->vlan_primary_rule.egress_vlan_tag, + nircm->vlan_secondary_rule.ingress_vlan_tag, + nircm->vlan_secondary_rule.egress_vlan_tag, + nircm->rule_flags, + nircm->valid_flags, + nircm->pppoe_rule.return_if_exist, + nircm->pppoe_rule.return_if_num, + nircm->pppoe_rule.flow_if_exist, + nircm->pppoe_rule.flow_if_num, + nircm->qos_rule.flow_qos_tag, nircm->qos_rule.flow_qos_tag, + nircm->qos_rule.return_qos_tag, nircm->qos_rule.return_qos_tag, + nircm->dscp_rule.flow_dscp, + nircm->dscp_rule.return_dscp); +} + +/* + * nss_ipv6_log_destroy_rule_msg() + * Log IPv6 destroy rule message. + */ +static void nss_ipv6_log_destroy_rule_msg(struct nss_ipv6_msg *nim) +{ + uint32_t src_ip[4]; + uint32_t dest_ip[4]; + struct nss_ipv6_rule_destroy_msg *nirdm = &nim->msg.rule_destroy; + + NSS_IPV6_ADDR_TO_NW(nirdm->tuple.flow_ip, src_ip); + NSS_IPV6_ADDR_TO_NW(nirdm->tuple.return_ip, dest_ip); + + nss_trace("%px: IPv6 destroy rule message: \n" + "flow_ip: %pI6:%d\n" + "return_ip: %pI6:%d\n" + "protocol: %d\n", + nim, + src_ip, nirdm->tuple.flow_ident, + dest_ip, nirdm->tuple.return_ident, + nirdm->tuple.protocol); +} + +/* + * nss_ipv6_log_conn_sync() + * Log IPv6 connection stats sync message. + */ +static void nss_ipv6_log_conn_sync(struct nss_ipv6_msg *nim) +{ + struct nss_ipv6_conn_sync *sync = &nim->msg.conn_stats; + if (sync->flow_tx_packet_count || sync->return_tx_packet_count) { + uint32_t src_ip[4]; + uint32_t dest_ip[4]; + + NSS_IPV6_ADDR_TO_NW(sync->flow_ip, src_ip); + NSS_IPV6_ADDR_TO_NW(sync->return_ip, dest_ip); + + nss_trace("%px: IPv6 connection stats sync message: \n" + "Protocol: %d\n" + "src_addr: %pI6:%d\n" + "dest_addr: %pI6:%d\n" + "flow_rx_packet_count: %u\n" + "flow_rx_byte_count: %u\n" + "return_rx_packet_count: %u\n" + "return_rx_byte_count: %u\n" + "flow_tx_packet_count: %u\n" + "flow_tx_byte_count: %u\n" + "return_tx_packet_count: %u\n" + "return_tx_byte_count: %u\n", + nim, + (int)sync->protocol, + src_ip, (int)sync->flow_ident, + dest_ip, (int)sync->return_ident, + sync->flow_rx_packet_count, + sync->flow_rx_byte_count, + sync->return_rx_packet_count, + sync->return_rx_byte_count, + sync->flow_tx_packet_count, + sync->flow_tx_byte_count, + sync->return_tx_packet_count, + sync->return_tx_byte_count); + } +} + +/* + * nss_ipv6_log_conn_cfg_msg() + * Log IPv6 number of connections supported rule message. + */ +static void nss_ipv6_log_conn_cfg_msg(struct nss_ipv6_msg *nim) +{ + struct nss_ipv6_rule_conn_cfg_msg *nirccm __maybe_unused = &nim->msg.rule_conn_cfg; + nss_trace("%px: IPv6 number of connections supported rule message: \n" + "num_conn: %d\n", + nim, + nirccm->num_conn); +} + +/* + * nss_ipv6_log_mc_rule_create_msg() + * Log IPv6 multicast create rule message. + */ +static void nss_ipv6_log_mc_rule_create_msg(struct nss_ipv6_msg *nim) +{ + uint16_t vif; + uint32_t src_ip[4]; + uint32_t dest_ip[4]; + struct nss_ipv6_mc_rule_create_msg *nimrcm = &nim->msg.mc_rule_create; + + NSS_IPV6_ADDR_TO_NW(nimrcm->tuple.flow_ip, src_ip); + NSS_IPV6_ADDR_TO_NW(nimrcm->tuple.return_ip, dest_ip); + + for (vif = 0; vif < nimrcm->if_count ; vif++) { + nss_trace("%px: IPv6 multicast create rule message \n" + "Rule flag: %x\n" + "Vif: %d\n" + "Protocol: %d\n" + "to_mtu: %u\n" + "from_ip: %pI6:%d\n" + "to_ip: %pI6:%d\n" + "to_mac: %pM\n" + "dest_iface_num: %u\n" + "out_vlan[0] %x\n" + "out_vlan[1] %x\n", + nim, + nimrcm->if_rule[vif].rule_flags, + vif, + nimrcm->tuple.protocol, + nimrcm->if_rule[vif].if_mtu, + src_ip, nimrcm->tuple.flow_ident, + dest_ip, nimrcm->tuple.return_ident, + nimrcm->if_rule[vif].if_mac, + nimrcm->if_rule[vif].if_num, + nimrcm->if_rule[vif].egress_vlan_tag[0], + nimrcm->if_rule[vif].egress_vlan_tag[1]); + } +} + +/* + * nss_ipv6_log_conn_sync_many_msg() + * Log IPv6 many conn sync message. + */ +static void nss_ipv6_log_conn_sync_many_msg(struct nss_ipv6_msg *nim) +{ + uint16_t i; + struct nss_ipv6_conn_sync_many_msg *nicsm = &nim->msg.conn_stats_many; + for (i = 0; i < nicsm->count; i++) { + struct nss_ipv6_conn_sync *sync = &nicsm->conn_sync[i]; + if (sync->flow_tx_packet_count || sync->return_tx_packet_count) { + uint32_t src_ip[4]; + uint32_t dest_ip[4]; + + NSS_IPV6_ADDR_TO_NW(sync->flow_ip, src_ip); + NSS_IPV6_ADDR_TO_NW(sync->return_ip, dest_ip); + + nss_trace("%px: IPv6 many conn sync message \n" + "count: %d\n" + "i: %d\n" + "Protocol: %d\n" + "src_addr: %pI6:%d\n" + "dest_addr: %pI6:%d\n" + "flow_rx_packet_count: %u\n" + "flow_rx_byte_count: %u\n" + "return_rx_packet_count: %u\n" + "return_rx_byte_count: %u\n" + "flow_tx_packet_count: %u\n" + "flow_tx_byte_count: %u\n" + "return_tx_packet_count: %u\n" + "return_tx_byte_count: %u\n", + nim, + nicsm->count, + i, + (int)sync->protocol, + src_ip, (int)sync->flow_ident, + dest_ip, (int)sync->return_ident, + sync->flow_rx_packet_count, + sync->flow_rx_byte_count, + sync->return_rx_packet_count, + sync->return_rx_byte_count, + sync->flow_tx_packet_count, + sync->flow_tx_byte_count, + sync->return_tx_packet_count, + sync->return_tx_byte_count); + } + } +} + +/* + * nss_ipv6_log_verbose() + * Log message contents. + */ +static void nss_ipv6_log_verbose(struct nss_ipv6_msg *nim) +{ + switch (nim->cm.type) { + case NSS_IPV6_TX_CREATE_RULE_MSG: + nss_ipv6_log_rule_create_msg(nim); + break; + + case NSS_IPV6_TX_DESTROY_RULE_MSG: + nss_ipv6_log_destroy_rule_msg(nim); + break; + + case NSS_IPV6_RX_CONN_STATS_SYNC_MSG: + nss_ipv6_log_conn_sync(nim); + break; + + case NSS_IPV6_RX_NODE_STATS_SYNC_MSG: + /* Getting logged in stats */ + break; + + case NSS_IPV6_TX_CONN_CFG_RULE_MSG: + nss_ipv6_log_conn_cfg_msg(nim); + break; + + case NSS_IPV6_TX_CREATE_MC_RULE_MSG: + nss_ipv6_log_mc_rule_create_msg(nim); + break; + + case NSS_IPV6_TX_CONN_STATS_SYNC_MANY_MSG: + nss_ipv6_log_conn_sync_many_msg(nim); + break; + + default: + nss_trace("%px: Invalid message type\n", nim); + break; + } +} + +/* + * nss_ipv6_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_ipv6_log_tx_msg(struct nss_ipv6_msg *nim) +{ + nss_info("%px: type[%d]: %s\n", nim, nim->cm.type, nss_ipv6_log_message_types_str[nim->cm.type]); + nss_ipv6_log_verbose(nim); +} + +/* + * nss_ipv6_log_rx_msg() + * Log messages received from FW. + */ +void nss_ipv6_log_rx_msg(struct nss_ipv6_msg *nim) +{ + if (nim->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_info("%px: Invalid response\n", nim); + return; + } + + if (nim->cm.response == NSS_CMN_RESPONSE_NOTIFY || (nim->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]: %s, response[%d]: %s\n", nim, nim->cm.type, + nss_ipv6_log_message_types_str[nim->cm.type], + nim->cm.response, nss_cmn_response_str[nim->cm.response]); + goto verbose; + } + + if (nim->cm.error > NSS_IPV6_CR_MULTICAST_UPDATE_INVALID_IF) { + nss_info("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + nim, nim->cm.type, nss_ipv6_log_message_types_str[nim->cm.type], + nim->cm.response, nss_cmn_response_str[nim->cm.response], + nim->cm.error); + goto verbose; + } + + nss_info("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + nim, nim->cm.type, nss_ipv6_log_message_types_str[nim->cm.type], + nim->cm.response, nss_cmn_response_str[nim->cm.response], + nim->cm.error, nss_ipv6_log_error_response_types_str[nim->cm.error]); + +verbose: + nss_ipv6_log_verbose(nim); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_reasm.c b/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_reasm.c new file mode 100644 index 000000000..4ad8a7c24 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_reasm.c @@ -0,0 +1,72 @@ +/* + ************************************************************************** + * Copyright (c) 2015,2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_ipv6_reasm.c + * NSS IPv6 Reassembly APIs + */ +#include +#include "nss_ipv6_reasm_stats.h" +#include "nss_ipv6_reasm_strings.h" + +/* + * nss_ipv6_reasm_msg_handler() + * Handle NSS -> HLOS messages for IPv6 reasm + */ +static void nss_ipv6_reasm_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_ipv6_reasm_msg *nim = (struct nss_ipv6_reasm_msg *)ncm; + + BUG_ON(ncm->interface != NSS_IPV6_REASM_INTERFACE); + + switch (nim->cm.type) { + case NSS_IPV6_REASM_STATS_SYNC_MSG: + /* + * Update driver statistics on node sync and send statistics notifications to the registered modules. + */ + nss_ipv6_reasm_stats_sync(nss_ctx, &nim->msg.stats_sync); + nss_ipv6_reasm_stats_notify(nss_ctx); + break; + default: + nss_warning("IPv6 reasm received an unknown message type"); + } +} + +/* + * nss_ipv6_reasm_get_context() + * get NSS context instance for ipv6 reassembly + */ +struct nss_ctx_instance *nss_ipv6_reasm_get_context(void) +{ + return &nss_top_main.nss[nss_top_main.ipv6_reasm_handler_id]; +} +EXPORT_SYMBOL(nss_ipv6_reasm_get_context); + +/* + * nss_ipv6_reasm_register_handler() + * Register our handler to receive messages for this interface + */ +void nss_ipv6_reasm_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx = nss_ipv6_reasm_get_context(); + + if (nss_core_register_handler(nss_ctx, NSS_IPV6_REASM_INTERFACE, nss_ipv6_reasm_msg_handler, NULL) != NSS_CORE_STATUS_SUCCESS) { + nss_warning("IPv6 reasm handler failed to register"); + } + + nss_ipv6_reasm_stats_dentry_create(); + nss_ipv6_reasm_strings_dentry_create(); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_reasm_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_reasm_stats.c new file mode 100644 index 000000000..d376f5af9 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_reasm_stats.c @@ -0,0 +1,167 @@ +/* + ************************************************************************** + * Copyright (c) 2017,2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_ipv6_reasm_stats.h" +#include "nss_ipv6_reasm.h" +#include "nss_ipv6_reasm_strings.h" + +/* + * Declare atomic notifier data structure for statistics. + */ +ATOMIC_NOTIFIER_HEAD(nss_ipv6_reasm_stats_notifier); + +uint64_t nss_ipv6_reasm_stats[NSS_IPV6_REASM_STATS_MAX]; /* IPv6 reasm statistics */ + +/* + * nss_ipv6_reasm_stats_read() + * Read IPV6 reassembly stats + */ +static ssize_t nss_ipv6_reasm_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i; + /* + * Max output lines = #stats + few blank lines for banner printing + + * Number of Extra outputlines for future reference to add new stats + */ + uint32_t max_output_lines = NSS_STATS_NODE_MAX + NSS_IPV6_REASM_STATS_MAX + NSS_STATS_EXTRA_OUTPUT_LINES; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + stats_shadow = kzalloc(NSS_IPV6_REASM_STATS_MAX * 8, GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return 0; + } + + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "ipv6_reasm", NSS_STATS_SINGLE_CORE); + + size_wr += nss_stats_fill_common_stats(NSS_IPV6_REASM_INTERFACE, NSS_STATS_SINGLE_INSTANCE, lbuf, size_wr, size_al, "ipv6_reasm"); + + /* + * Ipv6 reasm node stats + */ + + spin_lock_bh(&nss_top_main.stats_lock); + for (i = 0; (i < NSS_IPV6_REASM_STATS_MAX); i++) { + stats_shadow[i] = nss_ipv6_reasm_stats[i]; + } + + spin_unlock_bh(&nss_top_main.stats_lock); + + size_wr += nss_stats_print("ipv6_reasm", NULL, NSS_STATS_SINGLE_INSTANCE + , nss_ipv6_reasm_strings_stats + , stats_shadow + , NSS_IPV6_REASM_STATS_MAX + , lbuf, size_wr, size_al); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * nss_ipv6_reasm_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(ipv6_reasm); + +/* + * nss_ipv6_reasm_stats_dentry_create() + * Create IPv6 reasm statistics debug entry. + */ +void nss_ipv6_reasm_stats_dentry_create(void) +{ + nss_stats_create_dentry("ipv6_reasm", &nss_ipv6_reasm_stats_ops); +} + +/* + * nss_ipv6_reasm_stats_sync() + * Update driver specific information from the messsage. + */ +void nss_ipv6_reasm_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_reasm_stats_sync *nirs) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + int j; + + spin_lock_bh(&nss_top->stats_lock); + + /* + * Common node stats + */ + nss_top->stats_node[NSS_IPV6_REASM_INTERFACE][NSS_STATS_NODE_RX_PKTS] += nirs->node_stats.rx_packets; + nss_top->stats_node[NSS_IPV6_REASM_INTERFACE][NSS_STATS_NODE_RX_BYTES] += nirs->node_stats.rx_bytes; + nss_top->stats_node[NSS_IPV6_REASM_INTERFACE][NSS_STATS_NODE_TX_PKTS] += nirs->node_stats.tx_packets; + nss_top->stats_node[NSS_IPV6_REASM_INTERFACE][NSS_STATS_NODE_TX_BYTES] += nirs->node_stats.tx_bytes; + + for (j = 0; j < NSS_MAX_NUM_PRI; j++) { + nss_top->stats_node[NSS_IPV6_REASM_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + j] += nirs->node_stats.rx_dropped[j]; + } + + /* + * IPv6 reasm node stats + */ + nss_ipv6_reasm_stats[NSS_IPV6_REASM_STATS_ALLOC_FAILS] += nirs->ipv6_reasm_alloc_fails; + nss_ipv6_reasm_stats[NSS_IPV6_REASM_STATS_TIMEOUTS] += nirs->ipv6_reasm_timeouts; + nss_ipv6_reasm_stats[NSS_IPV6_REASM_STATS_DISCARDS] += nirs->ipv6_reasm_discards; + + spin_unlock_bh(&nss_top->stats_lock); +} + +/* + * nss_ipv6_reasm_stats_notify() + * Sends notifications to the registered modules. + * + * Leverage NSS-FW statistics timing to update Netlink. + */ +void nss_ipv6_reasm_stats_notify(struct nss_ctx_instance *nss_ctx) +{ + struct nss_ipv6_reasm_stats_notification ipv6_reasm_stats; + + ipv6_reasm_stats.core_id = nss_ctx->id; + memcpy(ipv6_reasm_stats.cmn_node_stats, nss_top_main.stats_node[NSS_IPV6_REASM_INTERFACE], sizeof(ipv6_reasm_stats.cmn_node_stats)); + memcpy(ipv6_reasm_stats.ipv6_reasm_stats, nss_ipv6_reasm_stats, sizeof(ipv6_reasm_stats.ipv6_reasm_stats)); + atomic_notifier_call_chain(&nss_ipv6_reasm_stats_notifier, NSS_STATS_EVENT_NOTIFY, (void *)&ipv6_reasm_stats); +} + +/* + * nss_ipv6_reasm_stats_register_notifier() + * Registers statistics notifier. + */ +int nss_ipv6_reasm_stats_register_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&nss_ipv6_reasm_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_ipv6_reasm_stats_register_notifier); + +/* + * nss_ipv6_reasm_stats_unregister_notifier() + * Deregisters statistics notifier. + */ +int nss_ipv6_reasm_stats_unregister_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&nss_ipv6_reasm_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_ipv6_reasm_stats_unregister_notifier); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_reasm_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_reasm_stats.h new file mode 100644 index 000000000..cdae31405 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_reasm_stats.h @@ -0,0 +1,27 @@ +/* + ************************************************************************** + * Copyright (c) 2017,2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_IPV6_REASM_STATS_H +#define __NSS_IPV6_REASM_STATS_H + +/* + * NSS IPv6 reasm statistics APIs + */ +extern void nss_ipv6_reasm_stats_notify(struct nss_ctx_instance *nss_ctx); +extern void nss_ipv6_reasm_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_reasm_stats_sync *nirs); +extern void nss_ipv6_reasm_stats_dentry_create(void); + +#endif /* __NSS_IPV6_REASM_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_reasm_strings.c b/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_reasm_strings.c new file mode 100644 index 000000000..7b6436ab5 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_reasm_strings.c @@ -0,0 +1,55 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_stats.h" +#include "nss_core.h" +#include +#include "nss_strings.h" + +/* + * nss_ipv6_reasm_strings_stats + * IPv6 reassembly statistics strings. + */ +struct nss_stats_info nss_ipv6_reasm_strings_stats[NSS_IPV6_REASM_STATS_MAX] = { + {"alloc_fails" , NSS_STATS_TYPE_DROP}, + {"timeouts" , NSS_STATS_TYPE_DROP}, + {"discards" , NSS_STATS_TYPE_DROP} +}; + +/* + * nss_ipv6_reasm_strings_read() + * Read IPv6 reassembly node statistics names. + */ +static ssize_t nss_ipv6_reasm_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_ipv6_reasm_strings_stats, NSS_IPV6_REASM_STATS_MAX); +} + +/* + * nss_ipv6_reasm_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(ipv6_reasm); + +/* + * nss_ipv6_reasm_strings_dentry_create() + * Create IPv6 reassembly statistics strings debug entry. + */ +void nss_ipv6_reasm_strings_dentry_create(void) +{ + nss_strings_create_dentry("ipv6_reasm", &nss_ipv6_reasm_strings_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_reasm_strings.h b/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_reasm_strings.h new file mode 100644 index 000000000..6cac544d0 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_reasm_strings.h @@ -0,0 +1,25 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_IPV6_REASM_STRINGS_H +#define __NSS_IPV6_REASM_STRINGS_H + +extern struct nss_stats_info nss_ipv6_reasm_strings_stats[NSS_IPV6_REASM_STATS_MAX]; +extern void nss_ipv6_reasm_strings_dentry_create(void); + +#endif /* __NSS_IPV6_REASM_STRINGS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_stats.c new file mode 100644 index 000000000..5f59ec8e6 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_stats.c @@ -0,0 +1,240 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2017, 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include +#include "nss_ipv6_stats.h" +#include "nss_ipv6_strings.h" + +/* + * Declare atomic notifier data structure for statistics. + */ +ATOMIC_NOTIFIER_HEAD(nss_ipv6_stats_notifier); + +uint64_t nss_ipv6_stats[NSS_IPV6_STATS_MAX]; +uint64_t nss_ipv6_exception_stats[NSS_IPV6_EXCEPTION_EVENT_MAX]; + +/* + * nss_ipv6_stats_read() + * Read IPV6 stats. + */ +static ssize_t nss_ipv6_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i; + + /* + * max output lines = #stats + Number of Extra outputlines for future reference to add new stats + + * start tag line + end tag line + three blank lines. + */ + uint32_t max_output_lines = NSS_STATS_NODE_MAX + NSS_IPV6_STATS_MAX + NSS_IPV6_EXCEPTION_EVENT_MAX + NSS_STATS_EXTRA_OUTPUT_LINES; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + /* + * Note: The assumption here is that exception event count is larger than other statistics count for IPv6. + */ + stats_shadow = kzalloc(NSS_IPV6_EXCEPTION_EVENT_MAX * 8, GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return 0; + } + + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "ipv6", NSS_STATS_SINGLE_CORE); + size_wr += nss_stats_fill_common_stats(NSS_IPV6_RX_INTERFACE, NSS_STATS_SINGLE_INSTANCE, lbuf, size_wr, size_al, "ipv6"); + + /* + * IPv6 node stats + */ + spin_lock_bh(&nss_top_main.stats_lock); + for (i = 0; (i < NSS_IPV6_STATS_MAX); i++) { + stats_shadow[i] = nss_ipv6_stats[i]; + } + + spin_unlock_bh(&nss_top_main.stats_lock); + + size_wr += nss_stats_print("ipv6", "ipv6 node stats", NSS_STATS_SINGLE_INSTANCE + , nss_ipv6_strings_stats + , stats_shadow + , NSS_IPV6_STATS_MAX + , lbuf, size_wr, size_al); + + /* + * Exception stats + */ + spin_lock_bh(&nss_top_main.stats_lock); + for (i = 0; (i < NSS_IPV6_EXCEPTION_EVENT_MAX); i++) { + stats_shadow[i] = nss_ipv6_exception_stats[i]; + } + spin_unlock_bh(&nss_top_main.stats_lock); + + size_wr += nss_stats_print("ipv6", "ipv6 exception stats", NSS_STATS_SINGLE_INSTANCE + , nss_ipv6_strings_exception_stats + , stats_shadow + , NSS_IPV6_EXCEPTION_EVENT_MAX + , lbuf, size_wr, size_al); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * nss_ipv6_stats_conn_sync() + * Update driver specific information from the messsage. + */ +void nss_ipv6_stats_conn_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_conn_sync *nics) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + + /* + * Update statistics maintained by NSS driver + */ + spin_lock_bh(&nss_top->stats_lock); + nss_ipv6_stats[NSS_IPV6_STATS_ACCELERATED_RX_PKTS] += nics->flow_rx_packet_count + nics->return_rx_packet_count; + nss_ipv6_stats[NSS_IPV6_STATS_ACCELERATED_RX_BYTES] += nics->flow_rx_byte_count + nics->return_rx_byte_count; + nss_ipv6_stats[NSS_IPV6_STATS_ACCELERATED_TX_PKTS] += nics->flow_tx_packet_count + nics->return_tx_packet_count; + nss_ipv6_stats[NSS_IPV6_STATS_ACCELERATED_TX_BYTES] += nics->flow_tx_byte_count + nics->return_tx_byte_count; + spin_unlock_bh(&nss_top->stats_lock); +} + +/* + * nss_ipv6_stats_conn_sync_many() + * Update driver specific information from the conn_sync_many messsage. + */ +void nss_ipv6_stats_conn_sync_many(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_conn_sync_many_msg *nicsm) +{ + uint32_t i; + + /* + * Sanity check for the stats count + */ + if (nicsm->count * sizeof(struct nss_ipv6_conn_sync) >= nicsm->size) { + nss_warning("%px: stats sync count %u exceeds the size of this msg %u", nss_ctx, nicsm->count, nicsm->size); + return; + } + + for (i = 0; i < nicsm->count; i++) { + nss_ipv6_stats_conn_sync(nss_ctx, &nicsm->conn_sync[i]); + } +} + +/* + * nss_ipv6_stats_node_sync() + * Update driver specific information from the messsage. + */ +void nss_ipv6_stats_node_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_node_sync *nins) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + uint32_t i; + + /* + * Update statistics maintained by NSS driver + */ + spin_lock_bh(&nss_top->stats_lock); + nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_RX_PKTS] += nins->node_stats.rx_packets; + nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_RX_BYTES] += nins->node_stats.rx_bytes; + nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_TX_PKTS] += nins->node_stats.tx_packets; + nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_TX_BYTES] += nins->node_stats.tx_bytes; + + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + nss_top->stats_node[NSS_IPV6_RX_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + i] += nins->node_stats.rx_dropped[i]; + } + + nss_ipv6_stats[NSS_IPV6_STATS_CONNECTION_CREATE_REQUESTS] += nins->ipv6_connection_create_requests; + nss_ipv6_stats[NSS_IPV6_STATS_CONNECTION_CREATE_COLLISIONS] += nins->ipv6_connection_create_collisions; + nss_ipv6_stats[NSS_IPV6_STATS_CONNECTION_CREATE_INVALID_INTERFACE] += nins->ipv6_connection_create_invalid_interface; + nss_ipv6_stats[NSS_IPV6_STATS_CONNECTION_DESTROY_REQUESTS] += nins->ipv6_connection_destroy_requests; + nss_ipv6_stats[NSS_IPV6_STATS_CONNECTION_DESTROY_MISSES] += nins->ipv6_connection_destroy_misses; + nss_ipv6_stats[NSS_IPV6_STATS_CONNECTION_HASH_HITS] += nins->ipv6_connection_hash_hits; + nss_ipv6_stats[NSS_IPV6_STATS_CONNECTION_HASH_REORDERS] += nins->ipv6_connection_hash_reorders; + nss_ipv6_stats[NSS_IPV6_STATS_CONNECTION_FLUSHES] += nins->ipv6_connection_flushes; + nss_ipv6_stats[NSS_IPV6_STATS_CONNECTION_EVICTIONS] += nins->ipv6_connection_evictions; + nss_ipv6_stats[NSS_IPV6_STATS_FRAGMENTATIONS] += nins->ipv6_fragmentations; + nss_ipv6_stats[NSS_IPV6_STATS_FRAG_FAILS] += nins->ipv6_frag_fails; + nss_ipv6_stats[NSS_IPV6_STATS_MC_CONNECTION_CREATE_REQUESTS] += nins->ipv6_mc_connection_create_requests; + nss_ipv6_stats[NSS_IPV6_STATS_MC_CONNECTION_UPDATE_REQUESTS] += nins->ipv6_mc_connection_update_requests; + nss_ipv6_stats[NSS_IPV6_STATS_MC_CONNECTION_CREATE_INVALID_INTERFACE] += nins->ipv6_mc_connection_create_invalid_interface; + nss_ipv6_stats[NSS_IPV6_STATS_MC_CONNECTION_DESTROY_REQUESTS] += nins->ipv6_mc_connection_destroy_requests; + nss_ipv6_stats[NSS_IPV6_STATS_MC_CONNECTION_DESTROY_MISSES] += nins->ipv6_mc_connection_destroy_misses; + nss_ipv6_stats[NSS_IPV6_STATS_MC_CONNECTION_FLUSHES] += nins->ipv6_mc_connection_flushes; + + for (i = 0; i < NSS_IPV6_EXCEPTION_EVENT_MAX; i++) { + nss_ipv6_exception_stats[i] += nins->exception_events[i]; + } + spin_unlock_bh(&nss_top->stats_lock); +} + +/* + * nss_ipv6_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(ipv6); + +/* + * nss_ipv6_stats_dentry_create() + * Create IPv6 statistics debug entry. + */ +void nss_ipv6_stats_dentry_create(void) +{ + nss_stats_create_dentry("ipv6", &nss_ipv6_stats_ops); +} + +/* + * nss_ipv6_stats_notify() + * Sends notifications to all the registered modules. + * + * Leverage NSS-FW statistics timing to update Netlink. + */ +void nss_ipv6_stats_notify(struct nss_ctx_instance *nss_ctx) +{ + struct nss_ipv6_stats_notification ipv6_stats; + + ipv6_stats.core_id = nss_ctx->id; + memcpy(ipv6_stats.cmn_node_stats, nss_top_main.stats_node[NSS_IPV6_RX_INTERFACE], sizeof(ipv6_stats.cmn_node_stats)); + memcpy(ipv6_stats.special_stats, nss_ipv6_stats, sizeof(ipv6_stats.special_stats)); + memcpy(ipv6_stats.exception_stats, nss_ipv6_exception_stats, sizeof(ipv6_stats.exception_stats)); + + atomic_notifier_call_chain(&nss_ipv6_stats_notifier, NSS_STATS_EVENT_NOTIFY, (void *)&ipv6_stats); +} + +/* + * nss_ipv6_stats_register_notifier() + * Registers statistics notifier. + */ +int nss_ipv6_stats_register_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&nss_ipv6_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_ipv6_stats_register_notifier); + +/* + * nss_ipv6_stats_unregister_notifier() + * Deregisters statistics notifier. + */ +int nss_ipv6_stats_unregister_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&nss_ipv6_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_ipv6_stats_unregister_notifier); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_stats.h new file mode 100644 index 000000000..1eaff5e2b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_stats.h @@ -0,0 +1,29 @@ +/* + ************************************************************************** + * Copyright (c) 2017,2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_IPV6_STATS_H +#define __NSS_IPV6_STATS_H + +/* + * IPV6 statistics APIs + */ +extern void nss_ipv6_stats_notify(struct nss_ctx_instance *nss_ctx); +extern void nss_ipv6_stats_node_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_node_sync *nins); +extern void nss_ipv6_stats_conn_sync(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_conn_sync *nics); +extern void nss_ipv6_stats_conn_sync_many(struct nss_ctx_instance *nss_ctx, struct nss_ipv6_conn_sync_many_msg *nicsm); +extern void nss_ipv6_stats_dentry_create(void); + +#endif /* __NSS_IPV6_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_strings.c b/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_strings.c new file mode 100644 index 000000000..00751dc4b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_strings.c @@ -0,0 +1,182 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_stats.h" +#include "nss_core.h" +#include +#include "nss_strings.h" + +/* + * nss_ipv6_strings_exception_stats + * Interface statistics strings for IPv6 exceptions. + */ +struct nss_stats_info nss_ipv6_strings_exception_stats[NSS_IPV6_EXCEPTION_EVENT_MAX] = { + {"icmp_header_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"icmp_unhandled_type" , NSS_STATS_TYPE_EXCEPTION}, + {"icmp_header_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"icmp_udp_header_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"icmp_tcp_header_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"icmp_unknown_protocol" , NSS_STATS_TYPE_EXCEPTION}, + {"icmp_no_icme" , NSS_STATS_TYPE_EXCEPTION}, + {"icmp_flush_to_host" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_header_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_no_icme" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_small_hop_limit" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_needs_fragmentation" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_flags" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_seq_exceeds_right_edge" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_small_data_offs" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_bad_sack" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_big_data_offs" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_seq_before_left_edge" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_ack_exceeds_right_edge" , NSS_STATS_TYPE_EXCEPTION}, + {"tcp_ack_before_left_edge" , NSS_STATS_TYPE_EXCEPTION}, + {"udp_header_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"udp_no_icme" , NSS_STATS_TYPE_EXCEPTION}, + {"udp_small_hop_limit" , NSS_STATS_TYPE_EXCEPTION}, + {"udp_needs_fragmentation" , NSS_STATS_TYPE_EXCEPTION}, + {"wrong_target_mac" , NSS_STATS_TYPE_EXCEPTION}, + {"header_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"unknown_protocol" , NSS_STATS_TYPE_EXCEPTION}, + {"ingress_vid_mismatch" , NSS_STATS_TYPE_EXCEPTION}, + {"ingress_vid_missing" , NSS_STATS_TYPE_EXCEPTION}, + {"dscp_marking_mismatch" , NSS_STATS_TYPE_EXCEPTION}, + {"vlan_marking_mismatch" , NSS_STATS_TYPE_EXCEPTION}, + {"interface_mismatch" , NSS_STATS_TYPE_EXCEPTION}, + {"gre_no_icme" , NSS_STATS_TYPE_EXCEPTION}, + {"gre_needs_fragmentation" , NSS_STATS_TYPE_EXCEPTION}, + {"gre_small_hop_limit" , NSS_STATS_TYPE_EXCEPTION}, + {"destroy" , NSS_STATS_TYPE_EXCEPTION}, + {"icmp_udplite_header_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"udplite_header_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"udplite_no_icme" , NSS_STATS_TYPE_EXCEPTION}, + {"udplite_small_hop_limit" , NSS_STATS_TYPE_EXCEPTION}, + {"udplite_needs_fragmentation" , NSS_STATS_TYPE_EXCEPTION}, + {"mc_udp_no_icme" , NSS_STATS_TYPE_EXCEPTION}, + {"mc_mem_alloc_failure" , NSS_STATS_TYPE_EXCEPTION}, + {"mc_update_failure" , NSS_STATS_TYPE_EXCEPTION}, + {"mc_pbuf_alloc_failure" , NSS_STATS_TYPE_EXCEPTION}, + {"esp_header_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"esp_no_icme" , NSS_STATS_TYPE_EXCEPTION}, + {"esp_ip_fragment" , NSS_STATS_TYPE_EXCEPTION}, + {"esp_small_hop_limit" , NSS_STATS_TYPE_EXCEPTION}, + {"esp_needs_fragmentation" , NSS_STATS_TYPE_EXCEPTION}, + {"tunipip6_no_icme" , NSS_STATS_TYPE_EXCEPTION}, + {"tunipip6_small_hop_limit" , NSS_STATS_TYPE_EXCEPTION}, + {"tunipip6_needs_fragmentation" , NSS_STATS_TYPE_EXCEPTION}, + {"pppoe_bridge_no_icme" , NSS_STATS_TYPE_EXCEPTION}, + {"dont_frag_set" , NSS_STATS_TYPE_EXCEPTION}, + {"reassembly_not_supported" , NSS_STATS_TYPE_EXCEPTION}, + {"pppoe_no_session" , NSS_STATS_TYPE_DROP}, + {"icmp_gre_header_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"icmp_esp_header_incomplete" , NSS_STATS_TYPE_EXCEPTION}, + {"emesh_prio_mismatch" , NSS_STATS_TYPE_EXCEPTION}, +}; + +/* + * nss_ipv6_strings_stats + * IPv6 stats strings. + */ +struct nss_stats_info nss_ipv6_strings_stats[NSS_IPV6_STATS_MAX] = { + {"rx_pkts" ,NSS_STATS_TYPE_SPECIAL}, + {"rx_bytes" ,NSS_STATS_TYPE_SPECIAL}, + {"tx_pkts" ,NSS_STATS_TYPE_SPECIAL}, + {"tx_bytes" ,NSS_STATS_TYPE_SPECIAL}, + {"create_requests" ,NSS_STATS_TYPE_SPECIAL}, + {"create_collisions" ,NSS_STATS_TYPE_SPECIAL}, + {"create_invalid_interface" ,NSS_STATS_TYPE_SPECIAL}, + {"destroy_requests" ,NSS_STATS_TYPE_SPECIAL}, + {"destroy_misses" ,NSS_STATS_TYPE_SPECIAL}, + {"hash_hits" ,NSS_STATS_TYPE_SPECIAL}, + {"hash_reorders" ,NSS_STATS_TYPE_SPECIAL}, + {"flushes" ,NSS_STATS_TYPE_SPECIAL}, + {"evictions" ,NSS_STATS_TYPE_SPECIAL}, + {"fragmentations" ,NSS_STATS_TYPE_SPECIAL}, + {"frag_fails" ,NSS_STATS_TYPE_SPECIAL}, + {"by_rule_drops" ,NSS_STATS_TYPE_DROP}, + {"mc_create_requests" ,NSS_STATS_TYPE_SPECIAL}, + {"mc_update_requests" ,NSS_STATS_TYPE_SPECIAL}, + {"mc_create_invalid_interface" ,NSS_STATS_TYPE_SPECIAL}, + {"mc_destroy_requests" ,NSS_STATS_TYPE_SPECIAL}, + {"mc_destroy_misses" ,NSS_STATS_TYPE_SPECIAL}, + {"mc_flushes" ,NSS_STATS_TYPE_SPECIAL} +}; + +/* + * nss_ipv6_special_stats_strings_read() + * Read IPv6 special node statistics names. + */ +static ssize_t nss_ipv6_special_stats_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_ipv6_strings_stats, NSS_IPV6_STATS_MAX); +} + +/* + * nss_ipv6_exception_stats_strings_read() + * Read IPv6 exception statistics names. + */ +static ssize_t nss_ipv6_exception_stats_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_ipv6_strings_exception_stats, NSS_IPV6_EXCEPTION_EVENT_MAX); +} + +/* + * nss_ipv6_special_stats_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(ipv6_special_stats); + +/* + * nss_ipv6_exception_stats_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(ipv6_exception_stats); + +/* + * nss_ipv6_strings_dentry_create() + * Create IPv6 statistics strings debug entry. + */ +void nss_ipv6_strings_dentry_create(void) +{ + struct dentry *ipv6_d = NULL; + struct dentry *ipv6_spcl_stats_d = NULL; + struct dentry *ipv6_excp_stats_d = NULL; + + if (!nss_top_main.strings_dentry) { + nss_warning("qca-nss-drv/strings is not present"); + return; + } + + ipv6_d = debugfs_create_dir("ipv6", nss_top_main.strings_dentry); + if (!ipv6_d) { + nss_warning("Failed to create qca-nss-drv/strings/ipv6 directory"); + return; + } + + ipv6_spcl_stats_d = debugfs_create_file("special_stats_str", 0400, ipv6_d, &nss_top_main, &nss_ipv6_special_stats_strings_ops); + if (!ipv6_spcl_stats_d) { + nss_warning("Failed to create qca-nss-drv/stats/ipv6/special_stats_str file"); + debugfs_remove_recursive(ipv6_d); + return; + } + + ipv6_excp_stats_d = debugfs_create_file("exception_stats_str", 0400, ipv6_d, &nss_top_main, &nss_ipv6_exception_stats_strings_ops); + if (!ipv6_excp_stats_d) { + nss_warning("Failed to create qca-nss-drv/stats/ipv6/exception_stats_str file"); + debugfs_remove_recursive(ipv6_d); + return; + } +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_strings.h b/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_strings.h new file mode 100644 index 000000000..4f582e581 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ipv6_strings.h @@ -0,0 +1,26 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_IPV6_STRINGS_H +#define __NSS_IPV6_STRINGS_H + +extern struct nss_stats_info nss_ipv6_strings_stats[NSS_IPV6_STATS_MAX]; +extern struct nss_stats_info nss_ipv6_strings_exception_stats[NSS_IPV6_EXCEPTION_EVENT_MAX]; +extern void nss_ipv6_strings_dentry_create(void); + +#endif /* __NSS_IPV6_STRINGS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2.c b/feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2.c new file mode 100644 index 000000000..2c73b4860 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2.c @@ -0,0 +1,284 @@ +/* + ************************************************************************** + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include +#include +#include "nss_tx_rx_common.h" +#include "nss_l2tpv2_stats.h" +#include "nss_l2tpv2_log.h" +#include "nss_l2tpv2_strings.h" + +/* + * Data structures to store l2tpv2 nss debug stats + */ +static DEFINE_SPINLOCK(nss_l2tpv2_session_debug_stats_lock); +static struct nss_l2tpv2_stats_session_debug nss_l2tpv2_session_debug_stats[NSS_MAX_L2TPV2_DYNAMIC_INTERFACES]; + +/* + * nss_l2tpv2_session_debug_stats_sync + * Per session debug stats for l2tpv2 + */ +void nss_l2tpv2_session_debug_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_l2tpv2_sync_session_stats_msg *stats_msg, uint16_t if_num) +{ + int i; + spin_lock_bh(&nss_l2tpv2_session_debug_stats_lock); + for (i = 0; i < NSS_MAX_L2TPV2_DYNAMIC_INTERFACES; i++) { + if (nss_l2tpv2_session_debug_stats[i].if_num == if_num) { + nss_l2tpv2_session_debug_stats[i].stats[NSS_L2TPV2_STATS_SESSION_RX_PPP_LCP_PKTS] += stats_msg->debug_stats.rx_ppp_lcp_pkts; + nss_l2tpv2_session_debug_stats[i].stats[NSS_L2TPV2_STATS_SESSION_RX_EXP_DATA_PKTS] += stats_msg->debug_stats.rx_exception_data_pkts; + nss_l2tpv2_session_debug_stats[i].stats[NSS_L2TPV2_STATS_SESSION_ENCAP_PBUF_ALLOC_FAIL_PKTS] += stats_msg->debug_stats.encap_pbuf_alloc_fail; + nss_l2tpv2_session_debug_stats[i].stats[NSS_L2TPV2_STATS_SESSION_DECAP_PBUF_ALLOC_FAIL_PKTS] += stats_msg->debug_stats.decap_pbuf_alloc_fail; + nss_l2tpv2_session_debug_stats[i].stats[NSS_L2TPV2_STATS_SESSION_DECAP_L2TPOIPSEC_SRC_ERR] += stats_msg->debug_stats.decap_l2tpoipsec_src_error; + break; + } + } + spin_unlock_bh(&nss_l2tpv2_session_debug_stats_lock); +} + +/* + * nss_l2tpv2_global_session_stats_get() + * Get session l2tpv2 statitics. + */ +void nss_l2tpv2_session_debug_stats_get(void *stats_mem) +{ + struct nss_l2tpv2_stats_session_debug *stats = (struct nss_l2tpv2_stats_session_debug *)stats_mem; + int i; + + if (!stats) { + nss_warning("No memory to copy l2tpv2 session stats"); + return; + } + + spin_lock_bh(&nss_l2tpv2_session_debug_stats_lock); + for (i = 0; i < NSS_MAX_L2TPV2_DYNAMIC_INTERFACES; i++) { + if (nss_l2tpv2_session_debug_stats[i].valid) { + memcpy(stats, &nss_l2tpv2_session_debug_stats[i], sizeof(struct nss_l2tpv2_stats_session_debug)); + stats++; + } + } + spin_unlock_bh(&nss_l2tpv2_session_debug_stats_lock); +} + +/* + * nss_l2tpv2_handler() + * Handle NSS -> HLOS messages for l2tpv2 tunnel + */ + +static void nss_l2tpv2_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_l2tpv2_msg *ntm = (struct nss_l2tpv2_msg *)ncm; + void *ctx; + + nss_l2tpv2_msg_callback_t cb; + + BUG_ON(!(nss_is_dynamic_interface(ncm->interface) || ncm->interface == NSS_L2TPV2_INTERFACE)); + + /* + * Trace Messages + */ + nss_l2tpv2_log_rx_msg(ntm); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_L2TPV2_MSG_MAX) { + nss_warning("%px: received invalid message %d for L2TP interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_l2tpv2_msg)) { + nss_warning("%px: message length is invalid: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + switch (ntm->cm.type) { + + case NSS_L2TPV2_MSG_SYNC_STATS: + /* + * Update session debug stats in session stats msg and send statistics notifications to the registered modules + */ + nss_l2tpv2_session_debug_stats_sync(nss_ctx, &ntm->msg.stats, ncm->interface); + nss_l2tpv2_stats_notify(nss_ctx, ncm->interface); + break; + } + + /* + * Update the callback and app_data for NOTIFY messages, l2tpv2 sends all notify messages + * to the same callback/app_data. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_ctx->nss_top->l2tpv2_msg_callback; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Do we have a call back + */ + if (!ncm->cb) { + return; + } + + /* + * callback + */ + cb = (nss_l2tpv2_msg_callback_t)ncm->cb; + ctx = nss_ctx->subsys_dp_register[ncm->interface].ndev; + + /* + * call l2tpv2 tunnel callback + */ + if (!ctx) { + nss_warning("%px: Event received for l2tpv2 tunnel interface %d before registration", nss_ctx, ncm->interface); + return; + } + + cb(ctx, ntm); +} + +/* + * nss_l2tpv2_tx() + * Transmit a l2tpv2 message to NSS firmware + */ +nss_tx_status_t nss_l2tpv2_tx(struct nss_ctx_instance *nss_ctx, struct nss_l2tpv2_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Trace Messages + */ + nss_l2tpv2_log_tx_msg(msg); + + /* + * Sanity check the message + */ + if (!nss_is_dynamic_interface(ncm->interface)) { + nss_warning("%px: tx request for non dynamic interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type > NSS_L2TPV2_MSG_MAX) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} + +/* + *********************************** + * Register/Unregister/Miscellaneous APIs + *********************************** + */ + +/* + * nss_register_l2tpv2_if() + */ +struct nss_ctx_instance *nss_register_l2tpv2_if(uint32_t if_num, nss_l2tpv2_callback_t l2tpv2_callback, + nss_l2tpv2_msg_callback_t event_callback, struct net_device *netdev, uint32_t features) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.l2tpv2_handler_id]; + int i = 0; + + nss_assert(nss_ctx); + nss_assert(nss_is_dynamic_interface(if_num)); + + nss_core_register_subsys_dp(nss_ctx, if_num, l2tpv2_callback, NULL, NULL, netdev, features); + + nss_top_main.l2tpv2_msg_callback = event_callback; + + nss_core_register_handler(nss_ctx, if_num, nss_l2tpv2_handler, NULL); + + spin_lock_bh(&nss_l2tpv2_session_debug_stats_lock); + for (i = 0; i < NSS_MAX_L2TPV2_DYNAMIC_INTERFACES; i++) { + if (!nss_l2tpv2_session_debug_stats[i].valid) { + nss_l2tpv2_session_debug_stats[i].valid = true; + nss_l2tpv2_session_debug_stats[i].if_num = if_num; + nss_l2tpv2_session_debug_stats[i].if_index = netdev->ifindex; + break; + } + } + spin_unlock_bh(&nss_l2tpv2_session_debug_stats_lock); + + return nss_ctx; +} + +/* + * nss_unregister_l2tpv2_if() + */ +void nss_unregister_l2tpv2_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.l2tpv2_handler_id]; + int i; + + nss_assert(nss_ctx); + nss_assert(nss_is_dynamic_interface(if_num)); + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + + nss_top_main.l2tpv2_msg_callback = NULL; + + nss_core_unregister_handler(nss_ctx, if_num); + + spin_lock_bh(&nss_l2tpv2_session_debug_stats_lock); + for (i = 0; i < NSS_MAX_L2TPV2_DYNAMIC_INTERFACES; i++) { + if (nss_l2tpv2_session_debug_stats[i].if_num == if_num) { + memset(&nss_l2tpv2_session_debug_stats[i], 0, sizeof(struct nss_l2tpv2_stats_session_debug)); + break; + } + } + spin_unlock_bh(&nss_l2tpv2_session_debug_stats_lock); +} + +/* + * nss_get_l2tpv2_context() + */ +struct nss_ctx_instance *nss_l2tpv2_get_context() +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.l2tpv2_handler_id]; +} + +/* + * nss_l2tpv2_msg_init() + * Initialize nss_l2tpv2 msg. + */ +void nss_l2tpv2_msg_init(struct nss_l2tpv2_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data) +{ + nss_cmn_msg_init(&ncm->cm, if_num, type, len, cb, app_data); +} + +/* nss_l2tpv2_register_handler() + * debugfs stats msg handler received on static l2tpv2 interface + */ +void nss_l2tpv2_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx = nss_l2tpv2_get_context(); + + nss_info("nss_l2tpv2_register_handler"); + nss_core_register_handler(nss_ctx, NSS_L2TPV2_INTERFACE, nss_l2tpv2_handler, NULL); + + nss_l2tpv2_stats_dentry_create(); + nss_l2tpv2_strings_dentry_create(); +} + +EXPORT_SYMBOL(nss_l2tpv2_get_context); +EXPORT_SYMBOL(nss_l2tpv2_tx); +EXPORT_SYMBOL(nss_unregister_l2tpv2_if); +EXPORT_SYMBOL(nss_l2tpv2_msg_init); +EXPORT_SYMBOL(nss_register_l2tpv2_if); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_log.c new file mode 100644 index 000000000..fc1b31fc5 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_log.c @@ -0,0 +1,143 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_l2tpv2_log.c + * NSS L2TPV2 logger file. + */ + +#include "nss_core.h" + +/* + * nss_l2tpv2_log_message_types_str + * NSS L2TPV2 message strings + */ +static int8_t *nss_l2tpv2_log_message_types_str[NSS_L2TPV2_MSG_MAX] __maybe_unused = { + "L2TPV2 Sesstion Create", + "L2TPV2 Session Destroy", + "L2TPV2 Stats", +}; + +/* + * nss_l2tpv2_log_session_create_msg() + * Log NSS L2TPV2 Session Create. + */ +static void nss_l2tpv2_log_session_create_msg(struct nss_l2tpv2_msg *nlm) +{ + struct nss_l2tpv2_session_create_msg *nlcm __maybe_unused = &nlm->msg.session_create_msg; + nss_trace("%px: NSS L2TPV2 Session Create message \n" + "L2TPV2 Local Tunnel ID: %x\n" + "L2TPV2 Local Session ID: %x\n" + "L2TPV2 Peer Tunnel ID: %x\n" + "L2TPV2 Peer Session ID: %x\n" + "L2TPV2 Source IP: %x\n" + "L2TPV2 Destnation IP: %x\n" + "L2TPV2 Reorder Timeout: %d\n" + "L2TPV2 Source Port: %d\n" + "L2TPV2 Destination Port: %d\n" + "L2TPV2 Received Sequence Number: %d\n" + "L2TPV2 Outer IP Packet TTL: %d\n" + "L2TPV2 UDP Checksum: %d\n", + nlcm, nlcm->local_tunnel_id, + nlcm->local_session_id, nlcm->peer_tunnel_id, + nlcm->peer_session_id, nlcm->sip, + nlcm->dip, nlcm->reorder_timeout, + nlcm->sport, nlcm->dport, + nlcm->recv_seq, nlcm->oip_ttl, + nlcm->udp_csum); +} + +/* + * nss_l2tpv2_log_session_destroy_msg() + * Log NSS L2TPV2 Session Create. + */ +static void nss_l2tpv2_log_session_destroy_msg(struct nss_l2tpv2_msg *nlm) +{ + struct nss_l2tpv2_session_destroy_msg *nldm __maybe_unused = &nlm->msg.session_destroy_msg; + nss_trace("%px: NSS L2TPV2 Session Destroy message \n" + "L2TPV2 Local Tunnel ID: %x\n" + "L2TPV2 Local Session ID: %x\n", + nldm, nldm->local_tunnel_id, + nldm->local_session_id); +} + +/* + * nss_l2tpv2_log_verbose() + * Log message contents. + */ +static void nss_l2tpv2_log_verbose(struct nss_l2tpv2_msg *nlm) +{ + switch (nlm->cm.type) { + case NSS_L2TPV2_MSG_SESSION_CREATE: + nss_l2tpv2_log_session_create_msg(nlm); + break; + + case NSS_L2TPV2_MSG_SESSION_DESTROY: + nss_l2tpv2_log_session_destroy_msg(nlm); + break; + + case NSS_L2TPV2_MSG_SYNC_STATS: + /* + * No log for valid stats message. + */ + break; + + default: + nss_trace("%px: Invalid message type\n", nlm); + break; + } +} + +/* + * nss_l2tpv2_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_l2tpv2_log_tx_msg(struct nss_l2tpv2_msg *nlm) +{ + if (nlm->cm.type >= NSS_L2TPV2_MSG_MAX) { + nss_warning("%px: Invalid message type\n", nlm); + return; + } + + nss_info("%px: type[%d]:%s\n", nlm, nlm->cm.type, nss_l2tpv2_log_message_types_str[nlm->cm.type]); + nss_l2tpv2_log_verbose(nlm); +} + +/* + * nss_l2tpv2_log_rx_msg() + * Log messages received from FW. + */ +void nss_l2tpv2_log_rx_msg(struct nss_l2tpv2_msg *nlm) +{ + if (nlm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", nlm); + return; + } + + if (nlm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (nlm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", nlm, nlm->cm.type, + nss_l2tpv2_log_message_types_str[nlm->cm.type], + nlm->cm.response, nss_cmn_response_str[nlm->cm.response]); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s\n", + nlm, nlm->cm.type, nss_l2tpv2_log_message_types_str[nlm->cm.type], + nlm->cm.response, nss_cmn_response_str[nlm->cm.response]); + +verbose: + nss_l2tpv2_log_verbose(nlm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_log.h new file mode 100644 index 000000000..56cc9dee3 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_log.h @@ -0,0 +1,41 @@ +/* + ************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_L2TPV2_LOG_H +#define __NSS_L2TPV2_LOG_H + +/* + * nss_l2tpv2.h + * NSS L2TPV2 header file. + */ + +/* + * Logger APIs + */ + +/* + * nss_l2tpv2_log_tx_msg + * Logs a l2tpv2 message that is sent to the NSS firmware. + */ +void nss_l2tpv2_log_tx_msg(struct nss_l2tpv2_msg *ntm); + +/* + * nss_l2tpv2_log_rx_msg + * Logs a l2tpv2 message that is received from the NSS firmware. + */ +void nss_l2tpv2_log_rx_msg(struct nss_l2tpv2_msg *ntm); + +#endif /* __NSS_L2TPV2_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_stats.c new file mode 100644 index 000000000..0784b54b8 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_stats.c @@ -0,0 +1,156 @@ +/* + ************************************************************************** + * Copyright (c) 2017,2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_l2tpv2_stats.h" +#include "nss_l2tpv2_strings.h" + +/* + * Declare atomic notifier data structure for statistics. + */ +ATOMIC_NOTIFIER_HEAD(nss_l2tpv2_stats_notifier); + +/* + * nss_l2tpv2_stats_read() + * Read l2tpv2 statistics. + */ +static ssize_t nss_l2tpv2_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + /* + * Max output lines = #stats * NSS_MAX_CORES + + * Few output lines for banner printing + Number of Extra outputlines for future reference to add new stats. + */ + uint32_t max_output_lines = NSS_MAX_L2TPV2_DYNAMIC_INTERFACES * (NSS_L2TPV2_STATS_SESSION_MAX + 2) /*session stats */ + + NSS_STATS_EXTRA_OUTPUT_LINES; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines ; + size_t size_wr = 0; + ssize_t bytes_read = 0; + struct net_device *dev; + struct nss_l2tpv2_stats_session_debug l2tpv2_session_stats[NSS_MAX_L2TPV2_DYNAMIC_INTERFACES]; + int id; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + memset(&l2tpv2_session_stats, 0, sizeof(struct nss_l2tpv2_stats_session_debug) * NSS_MAX_L2TPV2_DYNAMIC_INTERFACES); + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "l2tpv2", NSS_STATS_SINGLE_CORE); + + /* + * Get all stats + */ + nss_l2tpv2_session_debug_stats_get((void *)&l2tpv2_session_stats); + + /* + * Session stats + */ + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nl2tp v2 session stats start:\n\n"); + for (id = 0; id < NSS_MAX_L2TPV2_DYNAMIC_INTERFACES; id++) { + + if (!l2tpv2_session_stats[id].valid) { + break; + } + + dev = dev_get_by_index(&init_net, l2tpv2_session_stats[id].if_index); + if (likely(dev)) { + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d, netdevice=%s\n", id, + l2tpv2_session_stats[id].if_num, dev->name); + dev_put(dev); + } else { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d\n", id, + l2tpv2_session_stats[id].if_num); + } + + size_wr += nss_stats_print("l2tpv2", "l2tp v2 session stats" + , id + , nss_l2tpv2_strings_session_stats + , l2tpv2_session_stats[id].stats + , NSS_L2TPV2_STATS_SESSION_MAX + , lbuf, size_wr, size_al); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n"); + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr); + + kfree(lbuf); + return bytes_read; +} + +/* + * nss_l2tpv2_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(l2tpv2); + +/* + * nss_l2tpv2_stats_dentry_create() + * Create l2tpv2 statistics debug entry. + */ +void nss_l2tpv2_stats_dentry_create(void) +{ + nss_stats_create_dentry("l2tpv2", &nss_l2tpv2_stats_ops); +} + +/* + * nss_l2tpv2_stats_notify() + * Sends notifications to all the registered modules. + * + * Leverage NSS-FW statistics timing to update Netlink. + */ +void nss_l2tpv2_stats_notify(struct nss_ctx_instance *nss_ctx, uint32_t if_num) +{ + struct nss_l2tpv2_stats_notification l2tpv2_stats; + struct nss_l2tpv2_stats_session_debug l2tpv2_session_stats[NSS_MAX_L2TPV2_DYNAMIC_INTERFACES]; + int id; + + memset(&l2tpv2_session_stats, 0, sizeof(l2tpv2_session_stats)); + + /* + * Get all stats + */ + nss_l2tpv2_session_debug_stats_get((void *)&l2tpv2_session_stats); + + for (id = 0; id < NSS_MAX_L2TPV2_DYNAMIC_INTERFACES; id++) { + if (l2tpv2_session_stats[id].if_num == if_num) { + memcpy(&l2tpv2_stats.stats, &l2tpv2_session_stats[id].stats, sizeof(l2tpv2_stats.stats)); + } + } + l2tpv2_stats.core_id = nss_ctx->id; + l2tpv2_stats.if_num = if_num; + atomic_notifier_call_chain(&nss_l2tpv2_stats_notifier, NSS_STATS_EVENT_NOTIFY, (void *)&l2tpv2_stats); +} + +/* + * nss_l2tpv2_stats_register_notifier() + * Registers statistics notifier. + */ +int nss_l2tpv2_stats_register_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&nss_l2tpv2_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_l2tpv2_stats_register_notifier); + +/* + * nss_l2tpv2_stats_unregister_notifier() + * Deregisters statistics notifier. + */ +int nss_l2tpv2_stats_unregister_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&nss_l2tpv2_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_l2tpv2_stats_unregister_notifier); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_stats.h new file mode 100644 index 000000000..0c8ecda4d --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_stats.h @@ -0,0 +1,33 @@ +/* + ****************************************************************************** + * Copyright (c) 2017,2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_L2TPV2_STATS_H +#define __NSS_L2TPV2_STATS_H + +struct nss_l2tpv2_stats_session_debug { + uint64_t stats[NSS_L2TPV2_STATS_SESSION_MAX]; + int32_t if_index; + uint32_t if_num; /* nss interface number */ + bool valid; +}; + +/* + * l2tpv2 statistics APIs + */ +extern void nss_l2tpv2_stats_notify(struct nss_ctx_instance *nss_ctx, uint32_t if_num); +extern void nss_l2tpv2_stats_dentry_create(void); + +#endif /* __NSS_L2TPV2_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_strings.c b/feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_strings.c new file mode 100644 index 000000000..d5db00c0b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_strings.c @@ -0,0 +1,57 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_stats.h" +#include "nss_core.h" +#include +#include "nss_strings.h" + +/* + * nss_l2tpv2_strings_session_stats + * L2TPv2 statistics strings for NSS session statistics. + */ +struct nss_stats_info nss_l2tpv2_strings_session_stats[NSS_L2TPV2_STATS_SESSION_MAX] = { + {"rx_ppp_lcp_pkts" , NSS_STATS_TYPE_EXCEPTION}, + {"rx_exp_pkts" , NSS_STATS_TYPE_EXCEPTION}, + {"encap_pbuf_alloc_fails" , NSS_STATS_TYPE_SPECIAL}, + {"decap_pbuf_alloc_fails" , NSS_STATS_TYPE_SPECIAL}, + {"decap_l2tpoipsec_src_err" , NSS_STATS_TYPE_SPECIAL} +}; + +/* + * nss_l2tpv2_strings_read() + * Read L2TPv2 node statistics names. + */ +static ssize_t nss_l2tpv2_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_l2tpv2_strings_session_stats, NSS_L2TPV2_STATS_SESSION_MAX); +} + +/* + * nss_l2tpv2_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(l2tpv2); + +/* + * nss_l2tpv2_strings_dentry_create() + * Create L2TPv2 statistics strings debug entry. + */ +void nss_l2tpv2_strings_dentry_create(void) +{ + nss_strings_create_dentry("l2tpv2", &nss_l2tpv2_strings_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_strings.h b/feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_strings.h new file mode 100644 index 000000000..2e8f871c1 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_l2tpv2_strings.h @@ -0,0 +1,25 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_L2TPV2_STRINGS_H +#define __NSS_L2TPV2_STRINGS_H + +extern struct nss_stats_info nss_l2tpv2_strings_session_stats[NSS_L2TPV2_STATS_SESSION_MAX]; +extern void nss_l2tpv2_strings_dentry_create(void); + +#endif /* __NSS_L2TPV2_STRINGS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_lag.c b/feeds/ipq807x/qca-nss-drv/src/nss_lag.c new file mode 100644 index 000000000..02362e173 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_lag.c @@ -0,0 +1,273 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_tx_rx_lag.c + * NSS LAG Tx APIs + */ + +#include + +#include "nss_tx_rx_common.h" +#include "nss_lag_log.h" + +#define NSS_LAG_RESP_TIMEOUT 60000 /* 60 Sec */ + +/* + * Private data structure of dynamic interface + */ +struct nss_lag_pvt { + struct completion complete; /* completion structure */ + enum nss_cmn_response response; /* Message response */ +}; + +/* + * nss_lag_state_callback() + * Call back function for nss LAG State + */ +void nss_lag_state_callback(void *arg, struct nss_lag_msg *nm) +{ + struct nss_lag_pvt *lag_msg_state = arg; + + /* + * Unblock the sleeping function. + */ + lag_msg_state->response = nm->cm.response; + complete(&lag_msg_state->complete); +} + +/* + * nss_lag_verify_ifnum() + * + */ +static void nss_lag_verify_ifnum(uint32_t if_num) +{ + nss_assert((if_num == NSS_LAG0_INTERFACE_NUM) || + (if_num == NSS_LAG1_INTERFACE_NUM) || + (if_num == NSS_LAG2_INTERFACE_NUM) || + (if_num == NSS_LAG3_INTERFACE_NUM)); +} + +/* + * nss_lag_get_context() + */ +static struct nss_ctx_instance *nss_lag_get_context(void) +{ + uint8_t ipv4_handler_id = nss_top_main.ipv4_handler_id; + + return (struct nss_ctx_instance *)&nss_top_main.nss[ipv4_handler_id]; +} + +/* + * nss_lag_tx() + * Transmit a LAG msg to the firmware. + */ +nss_tx_status_t nss_lag_tx(struct nss_ctx_instance *nss_ctx, struct nss_lag_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Trace Messages + */ + nss_lag_log_tx_msg(msg); + + /* + * Sanity check the message + */ + nss_lag_verify_ifnum(ncm->interface); + + if (ncm->type > NSS_TX_METADATA_LAG_MAX) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_lag_tx); + +/** + * nss_register_lag_if() + */ +void *nss_register_lag_if(uint32_t if_num, + nss_lag_callback_t lag_cb, + nss_lag_event_callback_t lag_ev_cb, + struct net_device *netdev) +{ + struct nss_ctx_instance *nss_ctx = nss_lag_get_context(); + uint32_t features = 0; + + nss_assert(nss_ctx); + nss_lag_verify_ifnum(if_num); + + nss_core_register_subsys_dp(nss_ctx, if_num, lag_cb, NULL, NULL, netdev, features); + + nss_top_main.lag_event_callback = lag_ev_cb; + + /* + * Return the NSS driver context for LAG (same as for ipv4 functions) + */ + return (void *)nss_ctx; +} +EXPORT_SYMBOL(nss_register_lag_if); + +/** + * nss_unregister_lag_if() + */ +void nss_unregister_lag_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = nss_lag_get_context(); + + nss_assert(nss_ctx); + nss_lag_verify_ifnum(if_num); + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + + nss_top_main.lag_event_callback = NULL; +} +EXPORT_SYMBOL(nss_unregister_lag_if); + +/** + * nss_lag_handler() + */ +void nss_lag_handler(struct nss_ctx_instance *nss_ctx, + struct nss_cmn_msg *ncm, + void *app_data) +{ + struct nss_lag_msg *lm = (struct nss_lag_msg *)ncm; + void *ctx = NULL; + nss_lag_event_callback_t cb; + + BUG_ON(ncm->interface != NSS_LAG0_INTERFACE_NUM + && ncm->interface != NSS_LAG1_INTERFACE_NUM + && ncm->interface != NSS_LAG2_INTERFACE_NUM + && ncm->interface != NSS_LAG3_INTERFACE_NUM); + + /* + * Trace Messages + */ + nss_lag_log_rx_msg(lm); + + if (ncm->type >= NSS_TX_METADATA_LAG_MAX) { + nss_warning("%px: received invalid message %d for LAG interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_lag_msg)) { + nss_warning("%px: invalid length for LAG message: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /** + * Update the callback and app_data for NOTIFY messages. + * LAG sends all notify messages to the same callback. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_ctx->nss_top->lag_event_callback; + } + + /** + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /** + * Do we have a call back + */ + if (!ncm->cb) { + return; + } + + /** + * callback + */ + cb = (nss_lag_event_callback_t)ncm->cb; + ctx = (void *)ncm->app_data; + + cb(ctx, lm); +} + +/** + * nss_lag_register_handler() + */ +void nss_lag_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx = nss_lag_get_context(); + + nss_core_register_handler(nss_ctx, NSS_LAG0_INTERFACE_NUM, nss_lag_handler, NULL); + nss_core_register_handler(nss_ctx, NSS_LAG1_INTERFACE_NUM, nss_lag_handler, NULL); + nss_core_register_handler(nss_ctx, NSS_LAG2_INTERFACE_NUM, nss_lag_handler, NULL); + nss_core_register_handler(nss_ctx, NSS_LAG3_INTERFACE_NUM, nss_lag_handler, NULL); +} + +/** + * nss_lag_msg_init() + * Initialize lag message + */ +void nss_lag_msg_init(struct nss_lag_msg *nlm, uint16_t lag_num, uint32_t type, uint32_t len, + nss_lag_msg_callback_t cb, void *app_data) +{ + nss_cmn_msg_init(&nlm->cm, lag_num, type, len, (void *)cb, app_data); +} +EXPORT_SYMBOL(nss_lag_msg_init); + +/** + * nss_lag_tx_slave_state() + */ +nss_tx_status_t nss_lag_tx_slave_state(uint16_t lagid, int32_t slave_ifnum, + enum nss_lag_state_change_ev slave_state) +{ + struct nss_lag_msg nm; + struct nss_lag_state_change *nlsc = NULL; + nss_tx_status_t status; + int ret; + struct nss_ctx_instance *nss_ctx = nss_lag_get_context(); + struct nss_lag_pvt lag_msg_state; + + init_completion(&lag_msg_state.complete); + lag_msg_state.response = false; + + /* + * Construct a message to the NSS to update it + */ + nss_lag_msg_init(&nm, lagid, + NSS_TX_METADATA_LAG_STATE_CHANGE, + sizeof(struct nss_lag_state_change), + nss_lag_state_callback, &lag_msg_state); + + nlsc = &nm.msg.state; + nlsc->event = slave_state; + nlsc->interface = slave_ifnum; + + status = nss_lag_tx(nss_ctx, &nm); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: Send LAG update failed, status: %d\n", nss_ctx, + status); + return NSS_TX_FAILURE; + } + + /* + * Blocking call, wait till we get ACK for this msg. + */ + ret = wait_for_completion_timeout(&lag_msg_state.complete, + msecs_to_jiffies(NSS_LAG_RESP_TIMEOUT)); + if (!ret) { + nss_warning("%px: Waiting for ack timed out\n", nss_ctx); + return NSS_TX_FAILURE; + } + + return lag_msg_state.response; +} +EXPORT_SYMBOL(nss_lag_tx_slave_state); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_lag_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_lag_log.c new file mode 100644 index 000000000..da83df0c6 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_lag_log.c @@ -0,0 +1,103 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_lag_log.c + * NSS LAG logger file. + */ + +#include "nss_core.h" + +/* + * nss_lag_log_message_types_str + * NSS LAG message strings + */ +static int8_t *nss_lag_log_message_types_str[NSS_TX_METADATA_LAG_MAX] __maybe_unused = { + "LAG State Change", +}; + +/* + * nss_lag_log_state_change_msg() + * Log NSS LAG State Change. + */ +static void nss_lag_log_state_change_msg(struct nss_lag_msg *nlm) +{ + struct nss_lag_state_change *nlcm __maybe_unused = &nlm->msg.state; + nss_trace("%px: NSS LAG State Change message \n" + "LAG ID: %x\n" + "LAG Interface: %x\n" + "LAG Event: %d\n", + nlcm, nlcm->lagid, + nlcm->interface, nlcm->event); +} + +/* + * nss_lag_log_verbose() + * Log message contents. + */ +static void nss_lag_log_verbose(struct nss_lag_msg *nlm) +{ + switch (nlm->cm.type) { + case NSS_TX_METADATA_LAG_STATE_CHANGE: + nss_lag_log_state_change_msg(nlm); + break; + + default: + nss_trace("%px: Invalid message type\n", nlm); + break; + } +} + +/* + * nss_lag_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_lag_log_tx_msg(struct nss_lag_msg *nlm) +{ + if (nlm->cm.type >= NSS_TX_METADATA_LAG_MAX) { + nss_warning("%px: Invalid message type\n", nlm); + return; + } + + nss_info("%px: type[%d]:%s\n", nlm, nlm->cm.type, nss_lag_log_message_types_str[nlm->cm.type]); + nss_lag_log_verbose(nlm); +} + +/* + * nss_lag_log_rx_msg() + * Log messages received from FW. + */ +void nss_lag_log_rx_msg(struct nss_lag_msg *nlm) +{ + if (nlm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", nlm); + return; + } + + if (nlm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (nlm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", nlm, nlm->cm.type, + nss_lag_log_message_types_str[nlm->cm.type], + nlm->cm.response, nss_cmn_response_str[nlm->cm.response]); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s\n", + nlm, nlm->cm.type, nss_lag_log_message_types_str[nlm->cm.type], + nlm->cm.response, nss_cmn_response_str[nlm->cm.response]); + +verbose: + nss_lag_log_verbose(nlm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_lag_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_lag_log.h new file mode 100644 index 000000000..4efe393fc --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_lag_log.h @@ -0,0 +1,41 @@ +/* + ************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_LAG_LOG_H +#define __NSS_LAG_LOG_H + +/* + * nss_lag.h + * NSS LAG header file. + */ + +/* + * Logger APIs + */ + +/* + * nss_lag_log_tx_msg + * Logs a lag message that is sent to the NSS firmware. + */ +void nss_lag_log_tx_msg(struct nss_lag_msg *nlm); + +/* + * nss_lag_log_rx_msg + * Logs a lag message that is received from the NSS firmware. + */ +void nss_lag_log_rx_msg(struct nss_lag_msg *nlm); + +#endif /* __NSS_LAG_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_log.c new file mode 100644 index 000000000..bfdca6575 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_log.c @@ -0,0 +1,602 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ +/* + * nss_log.c + * NSS FW debug logger retrieval from DDR (memory) + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "nss_core.h" +#include "nss_log.h" + +/* + * Private data for each device file open instance + */ +struct nss_log_data { + void *load_mem; /* Pointer to struct nss_log_descriptor - descriptor data */ + dma_addr_t dma_addr; /* Handle to DMA */ + uint32_t last_entry; /* Last known sampled entry (or index) */ + uint32_t nentries; /* Caches the total number of entries of log buffer */ + int nss_id; /* NSS Core id being used */ + struct nss_ctx_instance *nss_ctx; + /* NSS ctx instance */ +}; + +struct nss_log_ring_buffer_addr nss_rbe[NSS_MAX_CORES]; + +static DEFINE_MUTEX(nss_log_mutex); +static wait_queue_head_t nss_log_wq; +static nss_log_msg_callback_t nss_debug_interface_cb; +static void *nss_debug_interface_app_data = NULL; + +static wait_queue_head_t msg_wq; +enum nss_cmn_response msg_response; +static bool msg_event; + +/* + * nss_log_llseek() + * Seek operation. + */ +static loff_t nss_log_llseek(struct file *file, loff_t offset, int origin) +{ + struct nss_log_data *data = file->private_data; + + switch (origin) { + case SEEK_SET: + break; + case SEEK_CUR: + offset += file->f_pos; + break; + case SEEK_END: + offset = ((data->nentries * sizeof(struct nss_log_entry)) + sizeof(struct nss_log_descriptor)) - offset; + break; + default: + return -EINVAL; + } + + return (offset >= 0) ? (file->f_pos = offset) : -EINVAL; +} + +/* + * nss_log_open() + * Open operation for our device. We let as many instance run together + */ +static int nss_log_open(struct inode *inode, struct file *filp) +{ + struct nss_log_data *data = NULL; + struct nss_top_instance *nss_top; + struct nss_ctx_instance *nss_ctx; + int nss_id; + + /* + * i_private is passed to us by debug_fs_create() + */ + nss_id = (int)(nss_ptr_t)inode->i_private; + if (nss_id < 0 || nss_id >= nss_top_main.num_nss) { + nss_warning("nss_id is not valid :%d\n", nss_id); + return -ENODEV; + } + + nss_top = &nss_top_main; + nss_ctx = &nss_top->nss[nss_id]; + + data = kzalloc(sizeof(struct nss_log_data), GFP_KERNEL); + if (!data) { + nss_warning("%px: Failed to allocate memory for log_data", nss_ctx); + return -ENOMEM; + } + + mutex_lock(&nss_log_mutex); + if (!nss_rbe[nss_id].addr) { + mutex_unlock(&nss_log_mutex); + kfree(data); + nss_warning("%px: Ring buffer not configured yet for nss_id:%d", nss_ctx, nss_id); + return -EIO; + } + + /* + * Actual ring buffer. + */ + data->load_mem = nss_rbe[nss_id].addr; + data->last_entry = 0; + data->nentries = nss_rbe[nss_id].nentries; + data->dma_addr = nss_rbe[nss_id].dma_addr; + data->nss_ctx = nss_ctx; + + /* + * Increment the reference count so that we don't free + * the memory + */ + nss_rbe[nss_id].ref_cnt++; + data->nss_id = nss_id; + filp->private_data = data; + mutex_unlock(&nss_log_mutex); + + return 0; +} + +/* + * nss_log_release() + * release gets called when close() is called on the file + * descriptor. We unmap the IO region. + */ +static int nss_log_release(struct inode *inode, struct file *filp) +{ + struct nss_log_data *data = filp->private_data; + + if (!data) { + return -EINVAL; + } + + mutex_lock(&nss_log_mutex); + nss_rbe[data->nss_id].ref_cnt--; + BUG_ON(nss_rbe[data->nss_id].ref_cnt < 0); + if (!nss_rbe[data->nss_id].ref_cnt) { + wake_up(&nss_log_wq); + } + mutex_unlock(&nss_log_mutex); + kfree(data); + return 0; +} + +/* + * nss_log_current_entry() + * Reads current entry index from NSS log descriptor. + */ +static uint32_t nss_log_current_entry(struct nss_log_descriptor *desc) +{ + rmb(); + return desc->current_entry; +} + +/* + * nss_log_read() + * Read operation lets command like cat and tail read our memory log buffer data. + */ +static ssize_t nss_log_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos) +{ + struct nss_log_data *data = filp->private_data; + struct nss_log_descriptor *desc; + size_t bytes = 0; + size_t b; + struct nss_log_entry *rb; + uint32_t entry; + uint32_t offset, index; + char msg[NSS_LOG_OUTPUT_LINE_SIZE]; + + if (!data) { + return -EINVAL; + } + + desc = data->load_mem; + if (!desc) { + nss_warning("%px: load_mem is NULL", data); + return -EINVAL; + } + + /* + * If buffer is too small to fit even one entry. + */ + if (size < NSS_LOG_OUTPUT_LINE_SIZE) { + return 0; + } + + /* + * Get the current index + */ + dma_sync_single_for_cpu(data->nss_ctx->dev, data->dma_addr, sizeof(struct nss_log_descriptor), DMA_FROM_DEVICE); + + entry = nss_log_current_entry(desc); + + /* + * If the current and last sampled indexes are same then bail out. + */ + if (unlikely(data->last_entry == entry)) { + return 0; + } + + /* + * If this is the first read (after open) on our device file. + */ + if (unlikely(!(*ppos))) { + /* + * If log buffer has rolled over. Almost all the time + * it will be true. + */ + if (likely(entry > data->nentries)) { + /* + * Determine how much we can stuff in one + * buffer passed to us and accordingly + * reduce our index. + */ + data->last_entry = entry - data->nentries; + } else { + data->last_entry = 0; + } + } else if (unlikely(entry > data->nentries && ((entry - data->nentries) > data->last_entry))) { + /* + * If FW is producing debug buffer at a pace faster than + * we can consume, then we restrict our iteration. + */ + data->last_entry = entry - data->nentries; + } + + /* + * Iterate over indexes. + */ + while (entry > data->last_entry) { + index = offset = (data->last_entry % data->nentries); + offset = (offset * sizeof(struct nss_log_entry)) + + offsetof(struct nss_log_descriptor, log_ring_buffer); + + dma_sync_single_for_cpu(data->nss_ctx->dev, data->dma_addr + offset, + sizeof(struct nss_log_entry), DMA_FROM_DEVICE); + rb = &desc->log_ring_buffer[index]; + + b = scnprintf(msg, sizeof(msg), NSS_LOG_LINE_FORMAT, + rb->thread_num, rb->timestamp, rb->message); + + data->last_entry++; + + /* + * Copy to user buffer and if we fail then we return + * failure. + */ + if (copy_to_user(buf + bytes, msg, b)) { + return -EFAULT; + } + + bytes += b; + + /* + * If we ran out of space in the buffer. + */ + if ((bytes + NSS_LOG_OUTPUT_LINE_SIZE) >= size) + break; + } + + if (bytes > 0) + *ppos = bytes; + + return bytes; +} + +struct file_operations nss_logs_core_ops = { + .owner = THIS_MODULE, + .open = nss_log_open, + .read = nss_log_read, + .release = nss_log_release, + .llseek = nss_log_llseek, +}; + +/* + * nss_debug_interface_set_callback() + * Sets the callback + */ +void nss_debug_interface_set_callback(nss_log_msg_callback_t cb, void *app_data) +{ + nss_debug_interface_cb = cb; + nss_debug_interface_app_data = app_data; +} + +/* + * nss_debug_interface_event() + * Received an event from NSS FW + */ +static void nss_debug_interface_event(void *app_data, struct nss_log_debug_interface_msg *nim) +{ + struct nss_cmn_msg *ncm = (struct nss_cmn_msg *)nim; + + msg_response = ncm->response; + msg_event = true; + wake_up(&msg_wq); +} + +/* + * nss_debug_interface_handler() + * handle NSS -> HLOS messages for debug interfaces + */ +static void nss_debug_interface_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_log_debug_interface_msg *ntm = (struct nss_log_debug_interface_msg *)ncm; + nss_log_msg_callback_t cb; + + BUG_ON(ncm->interface != NSS_DEBUG_INTERFACE); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type > NSS_DEBUG_INTERFACE_TYPE_MAX) { + nss_warning("%px: received invalid message %d for CAPWAP interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_log_debug_interface_msg)) { + nss_warning("%px: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Update the callback and app_data for NOTIFY messages. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_debug_interface_cb; + ncm->app_data = (nss_ptr_t)nss_debug_interface_app_data; + } + + /* + * Do we have a callback + */ + if (!ncm->cb) { + nss_trace("%px: cb is null for interface %d", nss_ctx, ncm->interface); + return; + } + + cb = (nss_log_msg_callback_t)ncm->cb; + cb((void *)ncm->app_data, ntm); +} + +/* + * nss_debug_interface_tx() + * Transmit a debug interface message to NSS FW + */ +static nss_tx_status_t nss_debug_interface_tx(struct nss_ctx_instance *nss_ctx, struct nss_log_debug_interface_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Sanity check the message + */ + if (ncm->interface != NSS_DEBUG_INTERFACE) { + nss_warning("%px: tx request for another interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type > NSS_DEBUG_INTERFACE_TYPE_MAX) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} + +/* + * nss_debug_log_buffer_alloc() + * Allocates and Initializes log buffer for the use in NSS FW (logging) + */ +bool nss_debug_log_buffer_alloc(uint8_t nss_id, uint32_t nentry) +{ + struct nss_log_debug_interface_msg msg; + struct nss_log_debug_memory_msg *dbg; + struct nss_top_instance *nss_top; + struct nss_ctx_instance *nss_ctx; + dma_addr_t dma_addr; + uint32_t size; + void *addr = NULL; + nss_tx_status_t status; + + if (nss_id >= nss_top_main.num_nss) { + return false; + } + + nss_top = &nss_top_main; + nss_ctx = &nss_top->nss[nss_id]; + + if (nss_ctx->state != NSS_CORE_STATE_INITIALIZED) { + nss_warning("%px: NSS Core:%d is not initialized yet\n", nss_ctx, nss_id); + return false; + } + + size = sizeof(struct nss_log_descriptor) + (sizeof(struct nss_log_entry) * nentry); + addr = kmalloc(size, GFP_ATOMIC); + if (!addr) { + nss_warning("%px: Failed to allocate memory for logging (size:%d)\n", nss_ctx, size); + return false; + } + + memset(addr, 0, size); + dma_addr = (uint32_t)dma_map_single(nss_ctx->dev, addr, size, DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(nss_ctx->dev, dma_addr))) { + nss_warning("%px: Failed to map address in DMA", nss_ctx); + kfree(addr); + return false; + } + + /* + * If we already have ring buffer associated with nss_id, then + * we must wait before we attach a new ring buffer. + */ + mutex_lock(&nss_log_mutex); + if (nss_rbe[nss_id].addr) { + mutex_unlock(&nss_log_mutex); + + /* + * Someone is using the current logbuffer. Wait until ref count become 0. + * We have to return mutex here, because the current user requires it to + * release the reference. + */ + if (!wait_event_timeout(nss_log_wq, !nss_rbe[nss_id].ref_cnt, 5 * HZ)) { + nss_warning("%px: Timeout waiting for refcnt to become 0\n", nss_ctx); + goto fail; + } + + mutex_lock(&nss_log_mutex); + if (!nss_rbe[nss_id].addr) { + mutex_unlock(&nss_log_mutex); + goto fail; + } + if (nss_rbe[nss_id].ref_cnt > 0) { + mutex_unlock(&nss_log_mutex); + nss_warning("%px: Some other thread is contending..opting out\n", nss_ctx); + goto fail; + } + } + + memset(&msg, 0, sizeof(struct nss_log_debug_interface_msg)); + nss_cmn_msg_init(&msg.cm, NSS_DEBUG_INTERFACE, NSS_DEBUG_INTERFACE_TYPE_LOG_BUF_INIT, + sizeof(struct nss_log_debug_memory_msg), nss_debug_interface_event, NULL); + + dbg = &msg.msg.addr; + dbg->nentry = nentry; + dbg->version = NSS_DEBUG_LOG_VERSION; + dbg->phy_addr = dma_addr; + + msg_event = false; + status = nss_debug_interface_tx(nss_ctx, &msg); + if (status != NSS_TX_SUCCESS) { + mutex_unlock(&nss_log_mutex); + nss_warning("%px: Failed to send message to debug interface:%d\n", nss_ctx, status); + goto fail; + } + + /* + * Wait for 5 seconds since this is a critical operation. + * Mutex is not unlocked here because we do not want someone to acquire the mutex and use the logbuffer + * while we are waiting message from NSS. + */ + if (!wait_event_timeout(msg_wq, msg_event, 5 * HZ)) { + mutex_unlock(&nss_log_mutex); + nss_warning("%px: Timeout send message to debug interface\n", nss_ctx); + goto fail; + } + + if (msg_response != NSS_CMN_RESPONSE_ACK) { + mutex_unlock(&nss_log_mutex); + nss_warning("%px: Response error for send message to debug interface:%d\n", nss_ctx, msg_response); + goto fail; + } + + /* + * If we had to free the previous allocation for ring buffer. + */ + if (nss_rbe[nss_id].addr) { + uint32_t old_size; + old_size = sizeof(struct nss_log_descriptor) + + (sizeof(struct nss_log_entry) * nss_rbe[nss_id].nentries); + dma_unmap_single(nss_ctx->dev, nss_rbe[nss_id].dma_addr, old_size, DMA_FROM_DEVICE); + kfree(nss_rbe[nss_id].addr); + } + + nss_rbe[nss_id].addr = addr; + nss_rbe[nss_id].nentries = nentry; + nss_rbe[nss_id].ref_cnt = 0; + nss_rbe[nss_id].dma_addr = dma_addr; + mutex_unlock(&nss_log_mutex); + wake_up(&nss_log_wq); + return true; + +fail: + dma_unmap_single(nss_ctx->dev, dma_addr, size, DMA_FROM_DEVICE); + kfree(addr); + wake_up(&nss_log_wq); + return false; +} + +/* + * nss_logbuffer_handler() + * Enable NSS debug output + */ +int nss_logbuffer_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + int ret; + int core_status; + int i; + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + if (ret) { + return ret; + } + + if (!write) { + return ret; + } + + if (nss_ctl_logbuf < 32) { + nss_warning("Invalid NSS FW logbuffer size:%d (must be > 32)\n", nss_ctl_logbuf); + nss_ctl_logbuf = 0; + return ret; + } + + for (i = 0; i < nss_top_main.num_nss; i++) { + /* + * Register the callback handler and allocate the debug log buffers + */ + core_status = nss_core_register_handler(&nss_top_main.nss[i], NSS_DEBUG_INTERFACE, nss_debug_interface_handler, NULL); + if (core_status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("NSS logbuffer init failed with register handler:%d\n", core_status); + } + + if (!nss_debug_log_buffer_alloc(i, nss_ctl_logbuf)) { + nss_warning("%d: Failed to set debug log buffer on NSS core", i); + } + } + + return ret; +} + +/* + * nss_log_init() + * Initializes NSS FW logs retrieval logic from /sys + */ +void nss_log_init(void) +{ + int i; + struct dentry *logs_dentry; + struct dentry *core_log_dentry; + + memset(nss_rbe, 0, sizeof(nss_rbe)); + init_waitqueue_head(&nss_log_wq); + init_waitqueue_head(&msg_wq); + + /* + * Create directory for obtaining NSS FW logs from each core + */ + logs_dentry = debugfs_create_dir("logs", nss_top_main.top_dentry); + if (unlikely(!logs_dentry)) { + nss_warning("Failed to create qca-nss-drv/logs directory in debugfs"); + return; + } + + for (i = 0; i < nss_top_main.num_nss; i++) { + char file[16]; + extern struct file_operations nss_logs_core_ops; + + snprintf(file, sizeof(file), "core%d", i); + core_log_dentry = debugfs_create_file(file, 0400, + logs_dentry, (void *)(nss_ptr_t)i, &nss_logs_core_ops); + if (unlikely(!core_log_dentry)) { + nss_warning("Failed to create qca-nss-drv/logs/%s file in debugfs", file); + return; + } + } + + nss_debug_interface_set_callback(nss_debug_interface_event, NULL); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_log.h new file mode 100644 index 000000000..1d27e9498 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_log.h @@ -0,0 +1,115 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2015, 2018, 2020 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ +/* + * nss_log.h + * NSS FW debug log memory header file + */ + +#ifndef __NSS_LOG_H +#define __NSS_LOG_H + +#define NSS_DEBUG_LOG_VERSION 0x1 + +/** + * Dynamic Interface types + */ +enum nss_debug_interface_msg_type { + NSS_DEBUG_INTERFACE_TYPE_NONE = 0, + NSS_DEBUG_INTERFACE_TYPE_LOG_BUF_INIT = 1, + NSS_DEBUG_INTERFACE_TYPE_MAX, +}; + +/* + * The size of each log entry to be displayed. + */ +#define NSS_LOG_OUTPUT_LINE_SIZE 151 /* 5 + 12 + 132 + '\n' + '\0' (see below) */ +#define NSS_LOG_LINE_FORMAT "%3d: %010u: %s\n" +#define NSS_LOG_LINE_WIDTH 132 +#define NSS_LOG_COOKIE 0xFF785634 + +/* + * Dump last N entry during the coredump. + * This number should be lower than the minimum size of the logbuf + * which 32 right now. + */ +#define NSS_LOG_COREDUMP_LINE_NUM 25 + +/* + * Saves the ring buffer address for logging per NSS core + */ +struct nss_log_ring_buffer_addr { + void *addr; /* Pointer to struct nss_log_descriptor */ + dma_addr_t dma_addr; /* DMA Handle */ + uint32_t nentries; /* Number of entries in the ring buffer */ + int ref_cnt; /* Reference count */ +}; + +/* + * nss_log_entry is shared between Host and NSS FW + */ +struct nss_log_entry { + uint64_t sequence_num; /* Sequence number */ + uint32_t cookie; /* Magic for verification */ + uint32_t thread_num; /* thread-id */ + uint32_t timestamp; /* timestamp in ticks */ + char message[NSS_LOG_LINE_WIDTH]; /* actual debug message */ +} __attribute__((aligned(NSS_CACHE_LINE_SIZE))); + +/* + * The NSS log descripts holds ring-buffer along with other variables and + * it is shared between NSS FW and Host. + * + * NSS FW writes to ring buffer and current_entry but read by only Host. + */ +struct nss_log_descriptor { + uint32_t cookie; /* Magic for verification */ + uint32_t log_nentries; /* No.of log entries */ + uint32_t current_entry; /* pointer to current log entry */ + uint8_t pad[20]; /* pad to align ring buffer at cacheline boundary */ + struct nss_log_entry log_ring_buffer[0]; /* The actual log entry ring buffer */ +} __attribute__((aligned(NSS_CACHE_LINE_SIZE))); + +struct nss_log_debug_memory_msg { + uint32_t version; + uint32_t nentry; + uint32_t phy_addr; +}; + +struct nss_log_debug_interface_msg { + struct nss_cmn_msg cm; + union { + struct nss_log_debug_memory_msg addr; + } msg; +}; + +/** + * @brief Callback to receive debug interface messages + * + * @param app_data Application context of the message + * @param msg Message data + * + * @return void + */ +typedef void (*nss_log_msg_callback_t)(void *app_data, struct nss_log_debug_interface_msg *msg); + +/* + * Exported by nss_init.c and used in nss_log.c + */ +extern int nss_ctl_logbuf; + +extern struct nss_log_ring_buffer_addr nss_rbe[NSS_MAX_CORES]; + +#endif /* __NSS_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_lso_rx.c b/feeds/ipq807x/qca-nss-drv/src/nss_lso_rx.c new file mode 100644 index 000000000..3abda0101 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_lso_rx.c @@ -0,0 +1,62 @@ +/* + ************************************************************************** + * Copyright (c) 2014,2017,2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_lso_rx.c + * NSS LSO_RX APIs + */ + +#include +#include "nss_lso_rx_stats.h" +#include "nss_lso_rx_strings.h" + +/* + * nss_rx_lso_rx_interface_handler() + * Handle NSS -> HLOS messages for LSO_RX Changes and Statistics + */ +static void nss_rx_lso_rx_interface_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) { + + struct nss_lso_rx_msg *nlrm = (struct nss_lso_rx_msg *)ncm; + + switch (nlrm->cm.type) { + case NSS_LSO_RX_STATS_SYNC_MSG: + /* + * Update LSO_RX driver statistics and send statistics notifications to the registered modules + */ + nss_lso_rx_stats_sync(nss_ctx, &nlrm->msg.stats_sync); + nss_lso_rx_stats_notify(nss_ctx); + break; + + default: + if (ncm->response != NSS_CMN_RESPONSE_ACK) { + /* + * Check response + */ + nss_info("%px: Received response %d for type %d, interface %d", nss_ctx, ncm->response, ncm->type, ncm->interface); + } + } +} + +/* + * nss_lso_rx_register_handler() + * Register handler for messaging + */ +void nss_lso_rx_register_handler(struct nss_ctx_instance *nss_ctx) +{ + nss_core_register_handler(nss_ctx, NSS_LSO_RX_INTERFACE, nss_rx_lso_rx_interface_handler, NULL); + nss_lso_rx_stats_dentry_create(); + nss_lso_rx_strings_dentry_create(); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_lso_rx_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_lso_rx_stats.c new file mode 100644 index 000000000..2763a2a8c --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_lso_rx_stats.c @@ -0,0 +1,172 @@ +/* + ************************************************************************** + * Copyright (c) 2017,2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_stats.h" +#include "nss_core.h" +#include "nss_lso_rx_stats.h" +#include "nss_lso_rx_strings.h" + +/* + * Declare atomic notifier data structure for statistics. + */ +ATOMIC_NOTIFIER_HEAD(nss_lso_rx_stats_notifier); + +uint64_t nss_lso_rx_stats[NSS_LSO_RX_STATS_MAX]; /* LSO_RX statistics */ + +/* + * nss_lso_rx_stats_read() + * Read LSO_RX stats + */ +static ssize_t nss_lso_rx_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i; + + /* + * Max output lines = #stats + few blank lines for banner printing + + * Number of Extra outputlines for future reference to add new stats + */ + uint32_t max_output_lines = NSS_STATS_NODE_MAX + NSS_LSO_RX_STATS_MAX + NSS_STATS_EXTRA_OUTPUT_LINES; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + stats_shadow = kzalloc(NSS_LSO_RX_STATS_MAX * 8, GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return 0; + } + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "lso_rx", NSS_STATS_SINGLE_CORE); + size_wr += nss_stats_fill_common_stats(NSS_LSO_RX_INTERFACE, NSS_STATS_SINGLE_INSTANCE, lbuf, size_wr, size_al, "lso_rx"); + + /* + * lso_rx node stats + */ + + spin_lock_bh(&nss_top_main.stats_lock); + for (i = 0; (i < NSS_LSO_RX_STATS_MAX); i++) { + stats_shadow[i] = nss_lso_rx_stats[i]; + } + + spin_unlock_bh(&nss_top_main.stats_lock); + size_wr += nss_stats_print("lso_rx", "lso_rx node stats" + , NSS_STATS_SINGLE_INSTANCE + , nss_lso_rx_strings_stats + , stats_shadow + , NSS_LSO_RX_STATS_MAX + , lbuf, size_wr, size_al); + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * nss_lso_rx_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(lso_rx); + +/* + * nss_lso_rx_stats_dentry_create() + * Create lso_rx statistics debug entry. + */ +void nss_lso_rx_stats_dentry_create(void) +{ + nss_stats_create_dentry("lso_rx", &nss_lso_rx_stats_ops); +} + +/* + * nss_lso_rx_stats_sync() + * Handle the syncing of lso_rx node statistics. + */ +void nss_lso_rx_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_lso_rx_stats_sync *nlrss) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + int j; + + spin_lock_bh(&nss_top->stats_lock); + + /* + * common node stats + */ + nss_top->stats_node[NSS_LSO_RX_INTERFACE][NSS_STATS_NODE_RX_PKTS] += nlrss->node_stats.rx_packets; + nss_top->stats_node[NSS_LSO_RX_INTERFACE][NSS_STATS_NODE_RX_BYTES] += nlrss->node_stats.rx_bytes; + nss_top->stats_node[NSS_LSO_RX_INTERFACE][NSS_STATS_NODE_TX_PKTS] += nlrss->node_stats.tx_packets; + nss_top->stats_node[NSS_LSO_RX_INTERFACE][NSS_STATS_NODE_TX_BYTES] += nlrss->node_stats.tx_bytes; + + for (j = 0; j < NSS_MAX_NUM_PRI; j++) { + nss_top->stats_node[NSS_LSO_RX_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + j] += nlrss->node_stats.rx_dropped[j]; + } + + /* + * General LSO_RX stats + */ + nss_lso_rx_stats[NSS_LSO_RX_STATS_TX_DROPPED] += nlrss->tx_dropped; + nss_lso_rx_stats[NSS_LSO_RX_STATS_DROPPED] += nlrss->dropped; + + /* + * pbuf + */ + nss_lso_rx_stats[NSS_LSO_RX_STATS_PBUF_ALLOC_FAIL] += nlrss->pbuf_alloc_fail; + nss_lso_rx_stats[NSS_LSO_RX_STATS_PBUF_REFERENCE_FAIL] += nlrss->pbuf_reference_fail; + + spin_unlock_bh(&nss_top->stats_lock); +} + +/* + * nss_lso_rx_stats_notify() + * Sends notifications to all the registered modules. + * + * Leverage NSS-FW statistics timing to update Netlink. + */ +void nss_lso_rx_stats_notify(struct nss_ctx_instance *nss_ctx) +{ + struct nss_lso_rx_stats_notification lso_rx_stats; + + lso_rx_stats.core_id = nss_ctx->id; + memcpy(lso_rx_stats.cmn_node_stats, nss_top_main.stats_node[NSS_LSO_RX_INTERFACE], sizeof(lso_rx_stats.cmn_node_stats)); + memcpy(lso_rx_stats.node_stats, nss_lso_rx_stats, sizeof(lso_rx_stats.node_stats)); + atomic_notifier_call_chain(&nss_lso_rx_stats_notifier, NSS_STATS_EVENT_NOTIFY, (void *)&lso_rx_stats); +} + +/* + * nss_lso_rx_stats_register_notifier() + * Registers statistics notifier. + */ +int nss_lso_rx_stats_register_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&nss_lso_rx_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_lso_rx_stats_register_notifier); + +/* + * nss_lso_rx_stats_unregister_notifier() + * Deregisters statistics notifier. + */ +int nss_lso_rx_stats_unregister_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&nss_lso_rx_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_lso_rx_stats_unregister_notifier); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_lso_rx_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_lso_rx_stats.h new file mode 100644 index 000000000..54ab6dc51 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_lso_rx_stats.h @@ -0,0 +1,67 @@ +/* + ************************************************************************** + * Copyright (c) 2017,2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_LSO_RX_STATS_H +#define __NSS_LSO_RX_STATS_H + +#include + +/* + * lso_rx_node statistics. + */ +struct nss_lso_rx_stats_sync { + struct nss_cmn_node_stats node_stats; + + uint32_t tx_dropped; /* Number of packets dropped because lso_rx transmit queue is full */ + uint32_t dropped; /* Total of packets dropped by the node internally */ + uint32_t pbuf_alloc_fail; /* Count number of pbuf alloc fails */ + uint32_t pbuf_reference_fail; /* Count number of pbuf ref fails */ + + /* + * If we're generating per-packet statistics then we count total lso_rx processing ticks + * worst-case ticks and the number of iterations around the lso_rx handler that we take. + */ + uint32_t total_ticks; /* Total clock ticks spend inside the lso_rx handler */ + uint32_t worst_case_ticks; + /* Worst case iteration of the lso_rx handler in ticks */ + uint32_t iterations; /* Number of iterations around the lso_rx handler */ +}; + +/* + * Message types for lso_rx + */ +enum nss_lso_rx_metadata_types { + NSS_LSO_RX_STATS_SYNC_MSG, /* Message type - stats sync message */ +}; + +/* + * Message structure to send receive LSO_RX commands + */ +struct nss_lso_rx_msg { + struct nss_cmn_msg cm; /* Message header */ + union { + struct nss_lso_rx_stats_sync stats_sync; /* Stats sub-message */ + } msg; +}; + +/* + * lso_rx statistics APIs + */ +extern void nss_lso_rx_stats_notify(struct nss_ctx_instance *nss_ctx); +extern void nss_lso_rx_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_lso_rx_stats_sync *nlrss); +extern void nss_lso_rx_stats_dentry_create(void); + +#endif /* __NSS_LSO_RX_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_lso_rx_strings.c b/feeds/ipq807x/qca-nss-drv/src/nss_lso_rx_strings.c new file mode 100644 index 000000000..627f1de08 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_lso_rx_strings.c @@ -0,0 +1,57 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_stats.h" +#include "nss_core.h" +#include +#include "nss_strings.h" +#include "nss_lso_rx_strings.h" + +/* + * nss_lso_rx_strings_stats + * LSO Rx statistics strings. + */ +struct nss_stats_info nss_lso_rx_strings_stats[NSS_LSO_RX_STATS_MAX] = { + {"tx_drops" ,NSS_STATS_TYPE_DROP}, + {"drops" ,NSS_STATS_TYPE_DROP}, + {"pbuf_alloc_fail" ,NSS_STATS_TYPE_ERROR}, + {"pbuf_reference_fail" ,NSS_STATS_TYPE_ERROR} +}; + +/* + * nss_lso_rx_strings_read() + * Read LSO Rx node statistics names. + */ +static ssize_t nss_lso_rx_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_lso_rx_strings_stats, NSS_LSO_RX_STATS_MAX); +} + +/* + * nss_lso_rx_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(lso_rx); + +/* + * nss_lso_rx_strings_dentry_create() + * Create LSO Rx statistics strings debug entry. + */ +void nss_lso_rx_strings_dentry_create(void) +{ + nss_strings_create_dentry("lso_rx", &nss_lso_rx_strings_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_lso_rx_strings.h b/feeds/ipq807x/qca-nss-drv/src/nss_lso_rx_strings.h new file mode 100644 index 000000000..901ed3073 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_lso_rx_strings.h @@ -0,0 +1,25 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_LSO_RX_STRINGS_H +#define __NSS_LSO_RX_STRINGS_H + +extern struct nss_stats_info nss_lso_rx_strings_stats[NSS_LSO_RX_STATS_MAX]; +extern void nss_lso_rx_strings_dentry_create(void); + +#endif /* __NSS_LSO_RX_STRINGS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_map_t.c b/feeds/ipq807x/qca-nss-drv/src/nss_map_t.c new file mode 100644 index 000000000..cfa7ab967 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_map_t.c @@ -0,0 +1,412 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_map_t_stats.h" +#include "nss_map_t_log.h" +#include "nss_map_t_strings.h" + +#define NSS_MAP_T_TX_TIMEOUT 3000 /* 3 Seconds */ + +/* + * Private data structure + */ +static struct { + struct semaphore sem; + struct completion complete; + int response; + void *cb; + void *app_data; +} nss_map_t_pvt; + +/* + * Data structures to store map_t nss debug stats + */ +static DEFINE_SPINLOCK(nss_map_t_debug_stats_lock); +static struct nss_map_t_stats_instance_debug nss_map_t_debug_stats[NSS_MAX_MAP_T_DYNAMIC_INTERFACES]; + +/* + * nss_map_t_verify_if_num() + * Verify if_num passed to us. + */ +static bool nss_map_t_verify_if_num(uint32_t if_num) +{ + enum nss_dynamic_interface_type if_type; + + if (nss_is_dynamic_interface(if_num) == false) { + return false; + } + + if_type = nss_dynamic_interface_get_type(nss_map_t_get_context(), if_num); + switch (if_type) { + case NSS_DYNAMIC_INTERFACE_TYPE_MAP_T_INNER: + case NSS_DYNAMIC_INTERFACE_TYPE_MAP_T_OUTER: + return true; + + default: + return false; + } +} + +/* + * nss_map_t_instance_debug_stats_sync + * debug stats for map_t + */ +void nss_map_t_instance_debug_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_map_t_sync_stats_msg *stats_msg, uint16_t if_num) +{ + int i; + enum nss_dynamic_interface_type if_type; + + if_type = nss_dynamic_interface_get_type(nss_ctx, if_num); + + spin_lock_bh(&nss_map_t_debug_stats_lock); + for (i = 0; i < NSS_MAX_MAP_T_DYNAMIC_INTERFACES; i++) { + if (nss_map_t_debug_stats[i].if_num != if_num) { + continue; + } + switch (if_type) { + case NSS_DYNAMIC_INTERFACE_TYPE_MAP_T_INNER: + nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V4_TO_V6_PBUF_EXCEPTION] += + stats_msg->debug_stats.v4_to_v6.exception_pkts; + nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V4_TO_V6_PBUF_NO_MATCHING_RULE] += + stats_msg->debug_stats.v4_to_v6.no_matching_rule; + nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V4_TO_V6_PBUF_NOT_TCP_OR_UDP] += + stats_msg->debug_stats.v4_to_v6.not_tcp_or_udp; + nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V4_TO_V6_RULE_ERR_LOCAL_PSID] += + stats_msg->debug_stats.v4_to_v6.rule_err_local_psid; + nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V4_TO_V6_RULE_ERR_LOCAL_IPV6] += + stats_msg->debug_stats.v4_to_v6.rule_err_local_ipv6; + nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V4_TO_V6_RULE_ERR_REMOTE_PSID] += + stats_msg->debug_stats.v4_to_v6.rule_err_remote_psid; + nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V4_TO_V6_RULE_ERR_REMOTE_EA_BITS] += + stats_msg->debug_stats.v4_to_v6.rule_err_remote_ea_bits; + nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V4_TO_V6_RULE_ERR_REMOTE_IPV6] += + stats_msg->debug_stats.v4_to_v6.rule_err_remote_ipv6; + break; + + case NSS_DYNAMIC_INTERFACE_TYPE_MAP_T_OUTER: + nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V6_TO_V4_PBUF_EXCEPTION] += + stats_msg->debug_stats.v6_to_v4.exception_pkts; + nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V6_TO_V4_PBUF_NO_MATCHING_RULE] += + stats_msg->debug_stats.v6_to_v4.no_matching_rule; + nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V6_TO_V4_PBUF_NOT_TCP_OR_UDP] += + stats_msg->debug_stats.v6_to_v4.not_tcp_or_udp; + nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V6_TO_V4_RULE_ERR_LOCAL_IPV4] += + stats_msg->debug_stats.v6_to_v4.rule_err_local_ipv4; + nss_map_t_debug_stats[i].stats[NSS_MAP_T_STATS_V6_TO_V4_RULE_ERR_REMOTE_IPV4] += + stats_msg->debug_stats.v6_to_v4.rule_err_remote_ipv4; + break; + + default: + nss_warning("Invalid MAP-T interface encountered: %u\n", if_type); + break; + } + } + spin_unlock_bh(&nss_map_t_debug_stats_lock); +} + +/* + * nss_map_t_instance_debug_stats_get() + * Get map_t statitics. + */ +void nss_map_t_instance_debug_stats_get(void *stats_mem) +{ + struct nss_map_t_stats_instance_debug *stats = (struct nss_map_t_stats_instance_debug *)stats_mem; + int i; + + if (!stats) { + nss_warning("No memory to copy map_t stats"); + return; + } + + spin_lock_bh(&nss_map_t_debug_stats_lock); + for (i = 0; i < NSS_MAX_MAP_T_DYNAMIC_INTERFACES; i++) { + if (nss_map_t_debug_stats[i].valid) { + memcpy(stats, &nss_map_t_debug_stats[i], sizeof(struct nss_map_t_stats_instance_debug)); + stats++; + } + } + spin_unlock_bh(&nss_map_t_debug_stats_lock); +} + +/* + * nss_map_t_handler() + * Handle NSS -> HLOS messages for map_t tunnel + */ +static void nss_map_t_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_map_t_msg *ntm = (struct nss_map_t_msg *)ncm; + void *ctx; + + nss_map_t_msg_callback_t cb; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + BUG_ON(!nss_map_t_verify_if_num(ncm->interface)); + + /* + * Trace Messages + */ + nss_map_t_log_rx_msg(ntm); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_MAP_T_MSG_MAX) { + nss_warning("%px: received invalid message %d for MAP-T interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_map_t_msg)) { + nss_warning("%px: tx request for another interface: %d", nss_ctx, ncm->interface); + return; + } + + switch (ntm->cm.type) { + case NSS_MAP_T_MSG_SYNC_STATS: + /* + * Update debug stats in stats msg and send statistics notifications to the registered modules + */ + nss_map_t_instance_debug_stats_sync(nss_ctx, &ntm->msg.stats, ncm->interface); + nss_map_t_stats_notify(nss_ctx, ncm->interface); + break; + } + + /* + * Update the callback and app_data for NOTIFY messages, map_t sends all notify messages + * to the same callback/app_data. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_ctx->nss_top->map_t_msg_callback; + ncm->app_data = (nss_ptr_t)nss_ctx->subsys_dp_register[ncm->interface].app_data; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * callback + */ + cb = (nss_map_t_msg_callback_t)ncm->cb; + ctx = (void *)ncm->app_data; + + /* + * call map-t callback + */ + if (!cb) { + nss_warning("%px: No callback for map-t interface %d", + nss_ctx, ncm->interface); + return; + } + + cb(ctx, ntm); +} + +/* + * nss_map_t_callback() + * Callback to handle the completion of NSS->HLOS messages. + */ +static void nss_map_t_callback(void *app_data, struct nss_map_t_msg *nim) +{ + nss_map_t_msg_callback_t callback = (nss_map_t_msg_callback_t)nss_map_t_pvt.cb; + void *data = nss_map_t_pvt.app_data; + + nss_map_t_pvt.cb = NULL; + nss_map_t_pvt.app_data = NULL; + + if (nim->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("map_t Error response %d\n", nim->cm.response); + nss_map_t_pvt.response = NSS_TX_FAILURE; + } else { + nss_map_t_pvt.response = NSS_TX_SUCCESS; + } + + if (callback) { + callback(data, nim); + } + + complete(&nss_map_t_pvt.complete); +} + +/* + * nss_map_t_tx() + * Transmit a map_t message to NSS firmware + */ +nss_tx_status_t nss_map_t_tx(struct nss_ctx_instance *nss_ctx, struct nss_map_t_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Trace Messages + */ + nss_map_t_log_tx_msg(msg); + + /* + * Sanity check the message + */ + if (!nss_map_t_verify_if_num(ncm->interface)) { + nss_warning("%px: tx request is not for a MAP-T dynamic interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type > NSS_MAP_T_MSG_MAX) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_map_t_tx); + +/* + * nss_map_t_tx_sync() + * Transmit a MAP-T message to NSS firmware synchronously. + */ +nss_tx_status_t nss_map_t_tx_sync(struct nss_ctx_instance *nss_ctx, struct nss_map_t_msg *msg) +{ + nss_tx_status_t status; + int ret = 0; + + down(&nss_map_t_pvt.sem); + nss_map_t_pvt.cb = (void *)msg->cm.cb; + nss_map_t_pvt.app_data = (void *)msg->cm.app_data; + + msg->cm.cb = (nss_ptr_t)nss_map_t_callback; + msg->cm.app_data = (nss_ptr_t)NULL; + + status = nss_map_t_tx(nss_ctx, msg); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: map_t_tx_msg failed\n", nss_ctx); + up(&nss_map_t_pvt.sem); + return status; + } + ret = wait_for_completion_timeout(&nss_map_t_pvt.complete, msecs_to_jiffies(NSS_MAP_T_TX_TIMEOUT)); + + if (!ret) { + nss_warning("%px: MAP-T tx sync failed due to timeout\n", nss_ctx); + nss_map_t_pvt.response = NSS_TX_FAILURE; + } + + status = nss_map_t_pvt.response; + up(&nss_map_t_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_map_t_tx_sync); + +/* + *********************************** + * Register/Unregister/Miscellaneous APIs + *********************************** + */ + +/* + * nss_map_t_register_if() + */ +struct nss_ctx_instance *nss_map_t_register_if(uint32_t if_num, uint32_t type, nss_map_t_callback_t map_t_callback, + nss_map_t_msg_callback_t event_callback, struct net_device *netdev, uint32_t features) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.map_t_handler_id]; + int i = 0; + + nss_assert(nss_ctx); + nss_assert(nss_map_t_verify_if_num(if_num)); + + nss_core_register_subsys_dp(nss_ctx, if_num, map_t_callback, 0, netdev, netdev, features); + nss_ctx->subsys_dp_register[if_num].type = type; + + nss_top_main.map_t_msg_callback = event_callback; + + nss_core_register_handler(nss_ctx, if_num, nss_map_t_handler, NULL); + + spin_lock_bh(&nss_map_t_debug_stats_lock); + for (i = 0; i < NSS_MAX_MAP_T_DYNAMIC_INTERFACES; i++) { + if (!nss_map_t_debug_stats[i].valid) { + nss_map_t_debug_stats[i].valid = true; + nss_map_t_debug_stats[i].if_num = if_num; + nss_map_t_debug_stats[i].if_index = netdev->ifindex; + break; + } + } + spin_unlock_bh(&nss_map_t_debug_stats_lock); + + return nss_ctx; +} +EXPORT_SYMBOL(nss_map_t_register_if); + +/* + * nss_map_t_unregister_if() + */ +void nss_map_t_unregister_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.map_t_handler_id]; + int i; + + nss_assert(nss_ctx); + nss_assert(nss_map_t_verify_if_num(if_num)); + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + + nss_top_main.map_t_msg_callback = NULL; + + nss_core_unregister_handler(nss_ctx, if_num); + + spin_lock_bh(&nss_map_t_debug_stats_lock); + for (i = 0; i < NSS_MAX_MAP_T_DYNAMIC_INTERFACES; i++) { + if (nss_map_t_debug_stats[i].if_num == if_num) { + memset(&nss_map_t_debug_stats[i], 0, sizeof(struct nss_map_t_stats_instance_debug)); + break; + } + } + spin_unlock_bh(&nss_map_t_debug_stats_lock); +} +EXPORT_SYMBOL(nss_map_t_unregister_if); + +/* + * nss_get_map_t_context() + */ +struct nss_ctx_instance *nss_map_t_get_context() +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.map_t_handler_id]; +} +EXPORT_SYMBOL(nss_map_t_get_context); + +/* + * nss_map_t_msg_init() + * Initialize nss_map_t msg. + */ +void nss_map_t_msg_init(struct nss_map_t_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data) +{ + nss_cmn_msg_init(&ncm->cm, if_num, type, len, cb, app_data); +} +EXPORT_SYMBOL(nss_map_t_msg_init); + +/* + * nss_map_t_register_handler() + * debugfs stats msg handler received on static map_t interface + */ +void nss_map_t_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx = nss_map_t_get_context(); + + nss_info("nss_map_t_register_handler"); + sema_init(&nss_map_t_pvt.sem, 1); + init_completion(&nss_map_t_pvt.complete); + nss_core_register_handler(nss_ctx, NSS_MAP_T_INTERFACE, nss_map_t_handler, NULL); + + nss_map_t_stats_dentry_create(); + nss_map_t_strings_dentry_create(); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_map_t_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_map_t_log.c new file mode 100644 index 000000000..5f1ef397b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_map_t_log.c @@ -0,0 +1,151 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_map_t_log.c + * NSS MAP_T logger file. + */ + +#include "nss_core.h" + +/* + * nss_map_t_log_message_types_str + * NSS MAP_T message strings + */ +static int8_t *nss_map_t_log_message_types_str[NSS_MAP_T_MSG_MAX] __maybe_unused = { + "MAP_T Rule Configure", + "MAP_T Rule Deconfigure", + "MAP_T Stats", +}; + +/* + * nss_map_t_log_rule_configure_msg() + * Log NSS MAP_T Rule Configure. + */ +static void nss_map_t_log_rule_configure_msg(struct nss_map_t_msg *ntm) +{ + struct nss_map_t_instance_rule_config_msg *ntcm __maybe_unused = &ntm->msg.create_msg; + nss_trace("%px: NSS MAP_T Rule Configure message \n" + "MAP_T Rule Seq Number: %d\n" + "MAP_T Total Number of Rules: %d\n" + "MAP_T Local IPv6 Prefix Length: %d\n" + "MAP_T Local IPv4 Prefix: %d\n" + "MAP_T Local IPv4 Prefix Length: %d\n" + "MAP_T Local EA Bits Length: %d\n" + "MAP_T Local PSID Offset: %d\n" + "MAP_T Reserved A: %d\n" + "MAP_T Remote IPv6 Prefix Length: %d\n" + "MAP_T Remote IPv4 Prefix: %d\n" + "MAP_T Remote IPv4 Prefix Length: %d\n" + "MAP_T Remote EA Bits Length: %d\n" + "MAP_T Remote PSID Offset: %d\n" + "MAP_T Local MAP Style: %d\n" + "MAP_T Remote Map Style: %d\n" + "MAP_T Local IPv6 Prefix: %px\n" + "MAP_T Reserved B: %px\n" + "MAP_T Remote IPv6 Prefix: %px\n" + "MAP_T Valid Rule: %d\n", + ntcm, ntcm->rule_num, ntcm->total_rules, + ntcm->local_ipv6_prefix_len, ntcm->local_ipv4_prefix, + ntcm->local_ipv4_prefix_len, ntcm->local_ea_len, + ntcm->local_psid_offset, ntcm->reserve_a, + ntcm->remote_ipv6_prefix_len, + ntcm->remote_ipv4_prefix, ntcm->remote_ipv4_prefix_len, + ntcm->remote_ea_len, ntcm->remote_psid_offset, + ntcm->local_map_style, ntcm->remote_map_style, + ntcm->local_ipv6_prefix, ntcm->reserve_b, + ntcm->remote_ipv6_prefix, ntcm->valid_rule); +} + +/* + * nss_map_t_log_rule_deconfig_msg() + * Log NSS MAP_T Rule Deconfigure. + */ +static void nss_map_t_log_rule_deconfig_msg(struct nss_map_t_msg *ntm) +{ + struct nss_map_t_instance_rule_deconfig_msg *ntdm __maybe_unused = &ntm->msg.destroy_msg; + nss_trace("%px: NSS MAP_T Rule Deconfigure message \n" + "MAP_T Interface Number: %d\n", + ntdm, ntdm->if_number); +} + +/* + * nss_map_t_log_verbose() + * Log message contents. + */ +static void nss_map_t_log_verbose(struct nss_map_t_msg *ntm) +{ + switch (ntm->cm.type) { + case NSS_MAP_T_MSG_INSTANCE_RULE_CONFIGURE: + nss_map_t_log_rule_configure_msg(ntm); + break; + + case NSS_MAP_T_MSG_INSTANCE_RULE_DECONFIGURE: + nss_map_t_log_rule_deconfig_msg(ntm); + break; + + case NSS_MAP_T_MSG_SYNC_STATS: + /* + * No log for valid stats message. + */ + break; + + default: + nss_trace("%px: Invalid message type\n", ntm); + break; + } +} + +/* + * nss_map_t_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_map_t_log_tx_msg(struct nss_map_t_msg *ntm) +{ + if (ntm->cm.type >= NSS_MAP_T_MSG_MAX) { + nss_warning("%px: Invalid message type\n", ntm); + return; + } + + nss_info("%px: type[%d]:%s\n", ntm, ntm->cm.type, nss_map_t_log_message_types_str[ntm->cm.type]); + nss_map_t_log_verbose(ntm); +} + +/* + * nss_map_t_log_rx_msg() + * Log messages received from FW. + */ +void nss_map_t_log_rx_msg(struct nss_map_t_msg *ntm) +{ + if (ntm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", ntm); + return; + } + + if (ntm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ntm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", ntm, ntm->cm.type, + nss_map_t_log_message_types_str[ntm->cm.type], + ntm->cm.response, nss_cmn_response_str[ntm->cm.response]); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s\n", + ntm, ntm->cm.type, nss_map_t_log_message_types_str[ntm->cm.type], + ntm->cm.response, nss_cmn_response_str[ntm->cm.response]); + +verbose: + nss_map_t_log_verbose(ntm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_map_t_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_map_t_log.h new file mode 100644 index 000000000..39448898d --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_map_t_log.h @@ -0,0 +1,41 @@ +/* + ************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_MAP_T_LOG_H +#define __NSS_MAP_T_LOG_H + +/* + * nss_map_t.h + * NSS MAP_T header file. + */ + +/* + * Logger APIs + */ + +/* + * nss_map_t_log_tx_msg + * Logs a map_t message that is sent to the NSS firmware. + */ +void nss_map_t_log_tx_msg(struct nss_map_t_msg *ntm); + +/* + * nss_map_t_log_rx_msg + * Logs a map_t message that is received from the NSS firmware. + */ +void nss_map_t_log_rx_msg(struct nss_map_t_msg *ntm); + +#endif /* __NSS_MAP_T_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_map_t_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_map_t_stats.c new file mode 100644 index 000000000..9b213441d --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_map_t_stats.c @@ -0,0 +1,154 @@ +/* + ************************************************************************** + * Copyright (c) 2017,2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_map_t_stats.h" +#include "nss_map_t_strings.h" + +/* + * Declare atomic notifier data structure for statistics. + */ +ATOMIC_NOTIFIER_HEAD(nss_map_t_stats_notifier); + +/* + * nss_map_t_stats_read() + * Read map_t statistics + */ +static ssize_t nss_map_t_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + + uint32_t max_output_lines = 2 /* header & footer for instance stats */ + + NSS_MAX_MAP_T_DYNAMIC_INTERFACES * (NSS_MAP_T_STATS_MAX + 2) /*instance stats */ + + 2; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + struct net_device *dev; + struct nss_map_t_stats_instance_debug map_t_instance_stats[NSS_MAX_MAP_T_DYNAMIC_INTERFACES]; + int id, i; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(!lbuf)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + memset(&map_t_instance_stats, 0, sizeof(struct nss_map_t_stats_instance_debug) * NSS_MAX_MAP_T_DYNAMIC_INTERFACES); + + /* + * Get all stats + */ + nss_map_t_instance_debug_stats_get((void *)&map_t_instance_stats); + + /* + * Session stats + */ + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nmap_t instance stats start:\n\n"); + for (id = 0; id < NSS_MAX_MAP_T_DYNAMIC_INTERFACES; id++) { + + if (!map_t_instance_stats[id].valid) { + break; + } + + dev = dev_get_by_index(&init_net, map_t_instance_stats[id].if_index); + if (likely(dev)) { + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d, netdevice=%s\n", id, + map_t_instance_stats[id].if_num, dev->name); + dev_put(dev); + } else { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d\n", id, + map_t_instance_stats[id].if_num); + } + + for (i = 0; i < NSS_MAP_T_STATS_MAX; i++) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "\t%s = %llu\n", nss_map_t_strings_instance_stats[i].stats_name, + map_t_instance_stats[id].stats[i]); + } + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n"); + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nmap_t instance stats end\n"); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr); + + kfree(lbuf); + return bytes_read; +} + +/* + * nss_map_t_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(map_t); + +/* + * nss_map_t_stats_dentry_create() + * Create map_t statistics debug entry. + */ +void nss_map_t_stats_dentry_create(void) +{ + nss_stats_create_dentry("map_t", &nss_map_t_stats_ops); +} + +/* + * nss_map_t_stats_notify() + * Sends notifications to the registered modules. + * + * Leverage NSS-FW statistics timing to update Netlink. + */ +void nss_map_t_stats_notify(struct nss_ctx_instance *nss_ctx, uint32_t if_num) +{ + struct nss_map_t_stats_notification map_t_stats; + struct nss_map_t_stats_instance_debug map_t_instance_stats[NSS_MAX_MAP_T_DYNAMIC_INTERFACES]; + int id; + + memset(&map_t_instance_stats, 0, sizeof(map_t_instance_stats)); + + /* + * Get all stats + */ + nss_map_t_instance_debug_stats_get((void *)&map_t_instance_stats); + + for (id = 0; id < NSS_MAX_MAP_T_DYNAMIC_INTERFACES; id++) { + if (map_t_instance_stats[id].if_num == if_num) { + memcpy(&map_t_stats.stats, &map_t_instance_stats[id].stats, sizeof(map_t_stats.stats)); + } + } + map_t_stats.if_type = nss_dynamic_interface_get_type(nss_ctx, if_num); + map_t_stats.core_id = nss_ctx->id; + map_t_stats.if_num = if_num; + atomic_notifier_call_chain(&nss_map_t_stats_notifier, NSS_STATS_EVENT_NOTIFY, (void *)&map_t_stats); +} + +/* + * nss_map_t_stats_register_notifier() + * Registers statistics notifier. + */ +int nss_map_t_stats_register_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&nss_map_t_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_map_t_stats_register_notifier); + +/* + * nss_map_t_stats_unregister_notifier() + * Deregisters statistics notifier. + */ +int nss_map_t_stats_unregister_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&nss_map_t_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_map_t_stats_unregister_notifier); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_map_t_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_map_t_stats.h new file mode 100644 index 000000000..8fa623afc --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_map_t_stats.h @@ -0,0 +1,36 @@ +/* + ****************************************************************************** + * Copyright (c) 2017,2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_MAP_T_STATS_H +#define __NSS_MAP_T_STATS_H + +/* + * NSS core stats -- for H2N/N2H map_t debug stats + */ +struct nss_map_t_stats_instance_debug { + uint64_t stats[NSS_MAP_T_STATS_MAX]; + int32_t if_index; + uint32_t if_num; /* nss interface number */ + bool valid; +}; + +/* + * MAP-T statistics APIs + */ +extern void nss_map_t_stats_notify(struct nss_ctx_instance *nss_ctx, uint32_t if_num); +extern void nss_map_t_stats_dentry_create(void); + +#endif /* __NSS_MAP_T_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_map_t_strings.c b/feeds/ipq807x/qca-nss-drv/src/nss_map_t_strings.c new file mode 100644 index 000000000..90fbf7ec3 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_map_t_strings.c @@ -0,0 +1,65 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_stats.h" +#include "nss_core.h" +#include +#include "nss_strings.h" + +/* + * nss_map_t_strings_instance_stats + * MAP-T statistics strings for NSS session statistics. + */ +struct nss_stats_info nss_map_t_strings_instance_stats[NSS_MAP_T_STATS_MAX] = { + {"V4_TO_V6_PBUF_EXCEPTION_PKTS", NSS_STATS_TYPE_EXCEPTION}, + {"V4_TO_V6_PBUF_NO_MATCHING_RULE", NSS_STATS_TYPE_SPECIAL}, + {"V4_TO_V6_PBUF_NOT_TCP_OR_UDP", NSS_STATS_TYPE_SPECIAL}, + {"V4_TO_V6_RULE_ERR_LOCAL_PSID", NSS_STATS_TYPE_ERROR}, + {"V4_TO_V6_RULE_ERR_LOCAL_IPV6", NSS_STATS_TYPE_ERROR}, + {"V4_TO_V6_RULE_ERR_REMOTE_PSID", NSS_STATS_TYPE_ERROR}, + {"V4_TO_V6_RULE_ERR_REMOTE_EA_BITS", NSS_STATS_TYPE_ERROR}, + {"V4_TO_V6_RULE_ERR_REMOTE_IPV6", NSS_STATS_TYPE_ERROR}, + {"V6_TO_V4_PBUF_EXCEPTION_PKTS", NSS_STATS_TYPE_EXCEPTION}, + {"V6_TO_V4_PBUF_NO_MATCHING_RULE", NSS_STATS_TYPE_SPECIAL}, + {"V6_TO_V4_PBUF_NOT_TCP_OR_UDP", NSS_STATS_TYPE_SPECIAL}, + {"V6_TO_V4_RULE_ERR_LOCAL_IPV4", NSS_STATS_TYPE_ERROR}, + {"V6_TO_V4_RULE_ERR_REMOTE_IPV4", NSS_STATS_TYPE_ERROR} +}; + +/* + * nss_map_t_strings_read() + * Read MAP-T node statistics names. + */ +static ssize_t nss_map_t_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_map_t_strings_instance_stats, NSS_MAP_T_STATS_MAX); +} + +/* + * nss_map_t_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(map_t); + +/* + * nss_map_t_strings_dentry_create() + * Create MAP-T statistics strings debug entry. + */ +void nss_map_t_strings_dentry_create(void) +{ + nss_strings_create_dentry("map_t", &nss_map_t_strings_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_map_t_strings.h b/feeds/ipq807x/qca-nss-drv/src/nss_map_t_strings.h new file mode 100644 index 000000000..acf2cd0b2 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_map_t_strings.h @@ -0,0 +1,25 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_MAP_T_STRINGS_H +#define __NSS_MAP_T_STRINGS_H + +extern struct nss_stats_info nss_map_t_strings_instance_stats[NSS_MAP_T_STATS_MAX]; +extern void nss_map_t_strings_dentry_create(void); + +#endif /* __NSS_MAP_T_STRINGS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_match.c b/feeds/ipq807x/qca-nss-drv/src/nss_match.c new file mode 100644 index 000000000..74f30a25a --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_match.c @@ -0,0 +1,296 @@ +/* + *************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + *************************************************************************** + */ + +/* + * nss_match.c + */ + +#include "nss_tx_rx_common.h" +#include "nss_match_log.h" +#include "nss_match_stats.h" + +#define NSS_MATCH_TX_TIMEOUT 1000 /* 1 Seconds */ + +/* + * Private data structure for match interface + */ +static struct nss_match_pvt { + struct semaphore sem; + struct completion complete; + int32_t response; +} match_pvt; + +/* + * nss_get_match_context() + */ +struct nss_ctx_instance *nss_match_get_context(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.match_handler_id]; +} +EXPORT_SYMBOL(nss_match_get_context); + +/* + * nss_match_verify_if_num() + */ +static bool nss_match_verify_if_num(uint32_t if_num) +{ + if (nss_is_dynamic_interface(if_num) == false) { + return false; + } + + if (nss_dynamic_interface_get_type(nss_match_get_context(), if_num) + != NSS_DYNAMIC_INTERFACE_TYPE_MATCH) { + return false; + } + + return true; +} + +/* + * nss_match_msg_sync_callback + * Callback to handle the completion of NSS to HLOS messages. + */ +static void nss_match_msg_sync_callback(void *app_data, struct nss_match_msg *matchm) +{ + match_pvt.response = NSS_TX_SUCCESS; + + if (matchm->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("Match Error response %d\n", matchm->cm.response); + match_pvt.response = NSS_TX_FAILURE; + } + + complete(&match_pvt.complete); +} + +/* + * nss_match_msg_tx() + * Sends message to NSS. + */ +static nss_tx_status_t nss_match_msg_tx(struct nss_ctx_instance *nss_ctx, struct nss_match_msg *matchm) +{ + struct nss_cmn_msg *ncm = &matchm->cm; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + /* + * Trace Messages + */ + nss_match_log_tx_msg(matchm); + + /* + * Sanity check the message + */ + if (!nss_match_verify_if_num(ncm->interface)) { + nss_warning("%px: Tx request for non dynamic interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type > NSS_MATCH_MSG_MAX) { + nss_warning("%px: Message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, matchm, sizeof(*matchm), NSS_NBUF_PAYLOAD_SIZE); +} + +/* + * nss_match_handler() + * Handle NSS to HLOS messages for Match node + */ +static void nss_match_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_match_msg *nem = (struct nss_match_msg *)ncm; + + nss_match_msg_sync_callback_t cb; + void *ctx; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + BUG_ON(!nss_match_verify_if_num(ncm->interface)); + + /* + * Trace Messages + */ + nss_match_log_rx_msg(nem); + + /* + * Is this a valid request/response packet? + */ + if (nem->cm.type >= NSS_MATCH_MSG_MAX) { + nss_warning("%px: Received invalid message %d for MATCH interface", nss_ctx, nem->cm.type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_match_msg)) { + nss_warning("%px: Unexpected message length: %d, on interface: %d", + nss_ctx, nss_cmn_get_msg_len(ncm), ncm->interface); + return; + } + + switch (nem->cm.type) { + case NSS_MATCH_STATS_SYNC: + + /* + * Update common node statistics + */ + nss_match_stats_sync(nss_ctx, nem); + } + + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_core_get_msg_handler(nss_ctx, ncm->interface); + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Do we have a call back + */ + if (!ncm->cb) { + return; + } + + /* + * callback + */ + cb = (nss_match_msg_sync_callback_t)ncm->cb; + ctx = (void *)ncm->app_data; + + cb(ctx, nem); +} + +/* + * nss_match_msg_tx_sync() + * Send a message to match node and wait for the response. + */ +nss_tx_status_t nss_match_msg_tx_sync(struct nss_ctx_instance *nss_ctx, struct nss_match_msg *matchm) +{ + nss_tx_status_t status; + int ret = 0; + down(&match_pvt.sem); + + matchm->cm.cb = (nss_ptr_t)nss_match_msg_sync_callback; + matchm->cm.app_data = (nss_ptr_t)NULL; + + status = nss_match_msg_tx(nss_ctx, matchm); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: nss_match_msg_tx failed\n", nss_ctx); + up(&match_pvt.sem); + return status; + } + + ret = wait_for_completion_timeout(&match_pvt.complete, msecs_to_jiffies(NSS_MATCH_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: MATCH tx failed due to timeout\n", nss_ctx); + match_pvt.response = NSS_TX_FAILURE; + } + + status = match_pvt.response; + up(&match_pvt.sem); + + return status; +} +EXPORT_SYMBOL(nss_match_msg_tx_sync); + +/* + * nss_match_register_instance() + * Registers match instance. + */ +struct nss_ctx_instance *nss_match_register_instance(int if_num, nss_match_msg_sync_callback_t notify_cb) +{ + struct nss_ctx_instance *nss_ctx; + uint32_t status; + + nss_ctx = nss_match_get_context(); + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (!nss_match_verify_if_num(if_num)) { + nss_warning("%px: Incorrect interface number: %d", nss_ctx, if_num); + return NULL; + } + + nss_core_register_handler(nss_ctx, if_num, nss_match_handler, NULL); + status = nss_core_register_msg_handler(nss_ctx, if_num, (nss_if_rx_msg_callback_t)notify_cb); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Not able to register handler for interface %d with NSS core\n", nss_ctx, if_num); + return NULL; + } + + if (!nss_match_ifnum_add(if_num)) { + nss_warning("%px: Unable to add match inteface : %u\n", nss_ctx, if_num); + nss_core_unregister_handler(nss_ctx, if_num); + nss_core_unregister_msg_handler(nss_ctx, if_num); + return NULL; + } + + return nss_ctx; +} +EXPORT_SYMBOL(nss_match_register_instance); + +/* + * nss_match_unregister_instance() + * Unregisters match instance. + */ +bool nss_match_unregister_instance(int if_num) +{ + struct nss_ctx_instance *nss_ctx; + uint32_t status; + + nss_ctx = nss_match_get_context(); + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (!nss_match_verify_if_num(if_num)) { + nss_warning("%px: Incorrect interface number: %d", nss_ctx, if_num); + return false; + } + + nss_core_unregister_handler(nss_ctx, if_num); + status = nss_core_unregister_msg_handler(nss_ctx, if_num); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Not able to unregister handler for interface %d with NSS core\n", nss_ctx, if_num); + return false; + } + + nss_match_ifnum_delete(if_num); + + return true; +} +EXPORT_SYMBOL(nss_match_unregister_instance); + +/* + * nss_match_msg_init() + * Initialize match message. + */ +void nss_match_msg_init(struct nss_match_msg *nmm, uint16_t if_num, uint32_t type, uint32_t len, + nss_match_msg_sync_callback_t cb, void *app_data) +{ + nss_cmn_msg_init(&nmm->cm, if_num, type, len, (void*)cb, app_data); +} +EXPORT_SYMBOL(nss_match_msg_init); + +/* + * nss_match_init() + * Initialize match. + */ +void nss_match_init() +{ + nss_match_stats_dentry_create(); + sema_init(&match_pvt.sem, 1); + init_completion(&match_pvt.complete); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_match_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_match_log.c new file mode 100644 index 000000000..2afdf6425 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_match_log.c @@ -0,0 +1,225 @@ +/* + *************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + *************************************************************************** + */ + +/* + * nss_match_log.c + * NSS match logger file. + */ + +#include "nss_core.h" + +/* + * nss_match_log_message_types_str + * Match message strings. + */ +static char *nss_match_log_message_types_str[NSS_MATCH_MSG_MAX] __maybe_unused = { + "Match no message", + "Match profile configure", + "Match add VoW rule", + "Match add L2 rule", + "Match delete VoW rule", + "Match delete L2 rule", + "Match sync stats" +}; + +/* + * nss_match_log_error_types_str + * Strings for error types for match messages + */ +static char *nss_match_log_error_types_str[NSS_MATCH_ERROR_MAX] __maybe_unused = { + "Match success", + "Match unknown message", + "Match DSCP is not in the range", + "Match 802.1p outer is not in the range", + "Match 802.1p inner is not in the range", + "Match rule ID is not in the range", + "Match action type is not in the range", + "Match rule ID already exists", + "Match rule ID doesn't exists", + "Match instance already configured", + "Match profile configuration message is invalid", + "Match database initialzation failed", + "Match table ID is not in the range", + "Match error in adding rule", + "Match error in deleting rule", + "Match error in adding table", + "Match error in deleting table", + "Match error mask ID is not in the range", + "Match error next node interface number is invalid", +}; + +/* + * nss_match_log_profile_configure_msg() + * Log NSS match profile configuration message. + */ +static void nss_match_log_profile_configure_msg(struct nss_match_msg *nmm) +{ + struct nss_match_profile_configure_msg *nmcm __maybe_unused = &nmm->msg.configure_msg; + int mask_num, mask_word; + + nss_trace("%px: NSS match configuration message \n" + "Match profile type: %u \n" + "Match mask flag: %u \n", + nmcm, + nmcm->profile_type, + nmcm->valid_mask_flag); + + for (mask_num = 0; mask_num < NSS_MATCH_MASK_MAX; mask_num++) { + nss_trace("Match mask number %d\n", mask_num + 1); + for (mask_word = 0; mask_word < NSS_MATCH_MASK_WORDS_MAX; mask_word++) { + nss_trace("%x ", nmcm->maskset[mask_num][mask_word]); + } + } +} + +/* + * nss_match_log_vow_rule_msg() + * Log NSS match VoW rule message. + */ +static void nss_match_log_vow_rule_msg(struct nss_match_msg *nmm) +{ + struct nss_match_rule_vow_msg *nmvrm __maybe_unused = &nmm->msg.vow_rule; + nss_trace("%px: NSS match VoW rule message \n" + "Match rule id: %hu \n" + "Match mask id: %hu \n" + "Match action: action flag = %u, next node = %u, priority = %hu \n" + "Match interface number: %u \n" + "Match DSCP: %hu \n" + "Match outer_8021p: %hu \n" + "Match inner_8021p: %hu \n", + nmvrm, + nmvrm->rule_id, + nmvrm->mask_id, + nmvrm->action.action_flag, nmvrm->action.forward_ifnum, nmvrm->action.setprio, + nmvrm->if_num, + nmvrm->dscp, + nmvrm->outer_8021p, + nmvrm->inner_8021p); +} + +/* + * nss_match_log_l2_rule_msg() + * Log NSS match L2 rule message. + */ +static void nss_match_log_l2_rule_msg(struct nss_match_msg *nmm) +{ + struct nss_match_rule_l2_msg *nmlrm __maybe_unused = &nmm->msg.l2_rule; + nss_trace("%px: NSS match L2 rule message \n" + "Match rule id: %hu \n" + "Match mask id: %hu \n" + "Match action: action flag = %u, next node = %u, priority = %hu \n" + "Match interface number: %u \n" + "Match destination mac address: %x :%x :%x \n" + "Match source mac address: %x :%x :%x \n" + "Match ether type: %x \n", + nmlrm, + nmlrm->rule_id, + nmlrm->mask_id, + nmlrm->action.action_flag, nmlrm->action.forward_ifnum, nmlrm->action.setprio, + nmlrm->if_num, + nmlrm->dmac[0], nmlrm->dmac[1], nmlrm->dmac[2], + nmlrm->smac[0], nmlrm->smac[1], nmlrm->smac[2], + nmlrm->ethertype); + +} + +/* + * nss_clmap_log_verbose() + * Log message contents. + */ +static void nss_match_log_verbose(struct nss_match_msg *nmm) +{ + switch (nmm->cm.type) { + case NSS_MATCH_TABLE_CONFIGURE_MSG: + nss_match_log_profile_configure_msg(nmm); + break; + + case NSS_MATCH_ADD_VOW_RULE_MSG: + nss_match_log_vow_rule_msg(nmm); + break; + + case NSS_MATCH_ADD_L2_RULE_MSG: + nss_match_log_l2_rule_msg(nmm); + break; + + case NSS_MATCH_DELETE_VOW_RULE_MSG: + nss_match_log_vow_rule_msg(nmm); + break; + + case NSS_MATCH_DELETE_L2_RULE_MSG: + nss_match_log_l2_rule_msg(nmm); + break; + + case NSS_MATCH_STATS_SYNC: + break; + + default: + nss_trace("%px: Invalid message type\n", nmm); + break; + } +} + +/* + * nss_match_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_match_log_tx_msg(struct nss_match_msg *nmm) +{ + if (nmm->cm.type >= NSS_MATCH_MSG_MAX) { + nss_warning("%px: Invalid message type\n", nmm); + return; + } + + nss_info("%px: type[%d]:%s\n", nmm, nmm->cm.type, nss_match_log_message_types_str[nmm->cm.type]); + nss_match_log_verbose(nmm); +} + +/* + * nss_match_log_rx_msg() + * Log messages received from FW. + */ +void nss_match_log_rx_msg(struct nss_match_msg *nmm) +{ + if (nmm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", nmm); + return; + } + + if (nmm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (nmm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", nmm, nmm->cm.type, + nss_match_log_message_types_str[nmm->cm.type], + nmm->cm.response, nss_cmn_response_str[nmm->cm.response]); + goto verbose; + } + + if (nmm->cm.error >= NSS_MATCH_ERROR_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + nmm, nmm->cm.type, nss_match_log_message_types_str[nmm->cm.type], + nmm->cm.response, nss_cmn_response_str[nmm->cm.response], + nmm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + nmm, nmm->cm.type, nss_match_log_message_types_str[nmm->cm.type], + nmm->cm.response, nss_cmn_response_str[nmm->cm.response], + nmm->cm.error, nss_match_log_error_types_str[nmm->cm.error]); + +verbose: + nss_match_log_verbose(nmm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_match_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_match_log.h new file mode 100644 index 000000000..df5b8a9e3 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_match_log.h @@ -0,0 +1,39 @@ +/* + ****************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_MATCH_LOG_H__ +#define __NSS_MATCH_LOG_H__ + +/** + * nss_match_log.h + * NSS match Log Header File. + */ + +/* + * nss_match_log_tx_msg + * Logs a match message that is sent to the NSS firmware. + */ +void nss_match_log_tx_msg(struct nss_match_msg *nmm); + +/* + * nss_match_log_rx_msg + * Logs a match message that is received from the NSS firmware. + */ +void nss_match_log_rx_msg(struct nss_match_msg *nmm); + +#endif /* __NSS_MATCH_LOG_H__ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_match_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_match_stats.c new file mode 100644 index 000000000..f599ea941 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_match_stats.c @@ -0,0 +1,166 @@ +/* + *************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + *************************************************************************** + */ + +/* + * nss_match_stats.c + */ +#include "nss_core.h" +#include "nss_stats.h" +#include +#include "nss_match_stats.h" + +#define NSS_MATCH_STATS_SIZE_PER_IF (NSS_STATS_MAX_STR_LENGTH * NSS_STATS_NODE_MAX) + /* Total number of statistics per match interface. */ + +int match_ifnum[NSS_MATCH_INSTANCE_MAX] = {0}; +static DEFINE_SPINLOCK(nss_match_stats_lock); + +/* + * nss_match_ifnum_add() + */ +bool nss_match_ifnum_add(int if_num) +{ + int index = 0; + + spin_lock(&nss_match_stats_lock); + + for (index = 0; index < NSS_MATCH_INSTANCE_MAX; index++) { + if (match_ifnum[index]) { + continue; + } + + match_ifnum[index] = if_num; + + spin_unlock(&nss_match_stats_lock); + return true; + } + + spin_unlock(&nss_match_stats_lock); + return false; +} + +/* + * nss_match_ifnum_delete() + */ +bool nss_match_ifnum_delete(int if_num) +{ + int index = 0; + + spin_lock(&nss_match_stats_lock); + + for (index = 0; index < NSS_MATCH_INSTANCE_MAX; index++) { + if (match_ifnum[index] != if_num) { + continue; + } + + match_ifnum[index] = 0; + + spin_unlock(&nss_match_stats_lock); + return true; + } + + spin_unlock(&nss_match_stats_lock); + return false; +} + + +/* + * nss_match_stats_read() + * Read match node statiistics. + */ +static ssize_t nss_match_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + ssize_t bytes_read = 0; + uint32_t index, if_num; + char *lbuf; + size_t size_al = NSS_MATCH_STATS_SIZE_PER_IF * NSS_MATCH_INSTANCE_MAX; + size_t size_wr = 0; + + lbuf = kzalloc(size_al, GFP_KERNEL); + if (!lbuf) { + nss_warning("Could not allocate memory for local statistics buffer\n"); + return 0; + } + + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "match", NSS_STATS_SINGLE_CORE); + + /* + * Common node stats for each match dynamic interface. + */ + for (index = 0; index < NSS_MATCH_INSTANCE_MAX; index++) { + + spin_lock_bh(&nss_match_stats_lock); + if_num = match_ifnum[index]; + spin_unlock_bh(&nss_match_stats_lock); + + if (if_num) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nMatch node if_num:%03u", if_num); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n ---------------------- \n"); + size_wr += nss_stats_fill_common_stats(if_num, NSS_STATS_SINGLE_INSTANCE, lbuf, size_wr, size_al, "match"); + continue; + } + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + return bytes_read; +} + + +/* + * nss_match_stats_sync() + * Update match common node statistics. + */ +void nss_match_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_match_msg *nmm) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + struct nss_match_stats_sync *msg_stats = &nmm->msg.stats; + uint64_t *if_stats; + int index; + + spin_lock_bh(&nss_top->stats_lock); + + /* + * Update common node stats + */ + if_stats = nss_top->stats_node[nmm->cm.interface]; + if_stats[NSS_STATS_NODE_RX_PKTS] += msg_stats->p_stats.rx_packets; + if_stats[NSS_STATS_NODE_RX_BYTES] += msg_stats->p_stats.rx_bytes; + if_stats[NSS_STATS_NODE_TX_PKTS] += msg_stats->p_stats.tx_packets; + if_stats[NSS_STATS_NODE_TX_BYTES] += msg_stats->p_stats.tx_bytes; + + for (index = 0; index < NSS_MAX_NUM_PRI; index++) { + if_stats[NSS_STATS_NODE_RX_QUEUE_0_DROPPED + index] += msg_stats->p_stats.rx_dropped[index]; + } + + spin_unlock_bh(&nss_top->stats_lock); +} + +/* + * nss_match_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(match) + +/* + * nss_match_stats_dentry_create() + * Create match statistics debug entry. + */ +void nss_match_stats_dentry_create(void) +{ + nss_stats_create_dentry("match", &nss_match_stats_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_match_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_match_stats.h new file mode 100644 index 000000000..23e9d47d1 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_match_stats.h @@ -0,0 +1,27 @@ +/* + *************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + *************************************************************************** + */ + +#ifndef __NSS_MATCH_STATS_H__ +#define __NSS_MATCH_STATS_H__ + +extern bool nss_match_ifnum_add(int if_num); +extern bool nss_match_ifnum_delete(int if_num); +extern void nss_match_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_match_msg *nmm); +extern void nss_match_stats_dentry_create(void); + +#endif /* __NSS_MATCH_STATS_H__ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_meminfo.c b/feeds/ipq807x/qca-nss-drv/src/nss_meminfo.c new file mode 100644 index 000000000..de550ce18 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_meminfo.c @@ -0,0 +1,781 @@ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * nss_meminfo.c + * NSS meminfo subsystem + */ + +#include +#include "nss_tx_rx_common.h" +#include "nss_core.h" +#include "nss_arch.h" +#include "nss_meminfo.h" + +/* + * Store user configuration + */ +static char nss_meminfo_user_config[NSS_MEMINFO_USER_CONFIG_MAXLEN]; +module_param_string(meminfo_user_config, nss_meminfo_user_config, + NSS_MEMINFO_USER_CONFIG_MAXLEN, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); +MODULE_PARM_DESC(nss_meminfo_user_config, "meminfo user configuration"); + +static bool nss_meminfo_debugfs_exist; + +/* + * Name table of memory type presented to user. + */ +char *nss_meminfo_memtype_table[NSS_MEMINFO_MEMTYPE_MAX] = {"IMEM", "SDRAM", "UTCM_SHARED"}; + +/* + * nss_meminfo_alloc_sdram() + * Allocate a SDRAM block. + */ +static void *nss_meminfo_alloc_sdram(struct nss_ctx_instance *nss_ctx, uint32_t size) +{ + void *addr = 0; + + /* + * kmalloc() return cache line aligned buffer. + */ + addr = kmalloc(size, GFP_KERNEL | __GFP_ZERO); + if (!addr) + nss_info_always("%px: failed to alloc a sdram block of size %u\n", nss_ctx, size); + + kmemleak_not_leak((void *)addr); + return addr; +} + +/* + * nss_meminfo_free_sdram() + * Free SDRAM memory. + */ +static inline void nss_meminfo_free_sdram(struct nss_ctx_instance *nss_ctx, uint32_t dma_addr, + void *kern_addr, uint32_t size) +{ + /* + * Unmap it since every SDRAM memory had been mapped. + */ + dma_unmap_single(nss_ctx->dev, dma_addr, size, DMA_FROM_DEVICE); + kfree(kern_addr); +} + +/* + * nss_meminfo_alloc_imem() + * Allocate an IMEM block in a sequential way. + */ +static uint32_t nss_meminfo_alloc_imem(struct nss_ctx_instance *nss_ctx, uint32_t size, int alignment) +{ + struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; + uint32_t new_tail; + uint32_t addr = 0; + int mask; + + mask = alignment - 1; + + /* + * Alignment has to be a power of 2. + */ + nss_assert(!(alignment & mask)); + + new_tail = mem_ctx->imem_tail; + + /* + * Align up the address if it not aligned. + */ + if (new_tail & mask) + new_tail = (new_tail + mask) & ~mask; + + if (size > (mem_ctx->imem_end - new_tail)) { + nss_info_always("%px: failed to alloc an IMEM block of size %u\n", nss_ctx, size); + return addr; + } + + addr = new_tail; + mem_ctx->imem_tail = new_tail + size; + + return addr; +} + +/* + * nss_meminfo_free_imem() + * Free an IMEM block. Ignore the padding bytes for alignment requirement. + */ +static void nss_meminfo_free_imem(struct nss_ctx_instance *nss_ctx, uint32_t addr, uint32_t size) +{ + struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; + mem_ctx->imem_tail -= size; +} + +/* + * nss_meminfo_alloc_utcm_shared() + * Allocate an UTCM_SHARED block in a sequential way. + */ +static uint32_t nss_meminfo_alloc_utcm_shared(struct nss_ctx_instance *nss_ctx, uint32_t size, int alignment) +{ + struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; + uint32_t new_tail; + uint32_t addr = 0; + int mask; + + mask = alignment - 1; + + /* + * Alignment has to be a power of 2. + */ + nss_assert(!(alignment & mask)); + + new_tail = mem_ctx->utcm_shared_tail; + + /* + * Align up the address if it not aligned. + */ + if (new_tail & mask) + new_tail = (new_tail + mask) & ~mask; + + if (size > (mem_ctx->utcm_shared_end - new_tail)) { + nss_info_always("%px: failed to alloc an UTCM_SHARED block of size %u\n", nss_ctx, size); + return addr; + } + + addr = new_tail; + mem_ctx->utcm_shared_tail = new_tail + size; + + return addr; +} + +/* + * nss_meminfo_free_utcm_shared() + * Free an UTCM_SHARED block. Ignore the padding bytes for alignment requirement. + */ +static void nss_meminfo_free_utcm_shared(struct nss_ctx_instance *nss_ctx, uint32_t addr, uint32_t size) +{ + struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; + mem_ctx->utcm_shared_tail -= size; +} + +/* + * nss_meminfo_if_user_overwrite() + * Return user configured memory type. Otherwise, return -1. + */ +static int nss_meminfo_if_user_overwrite(struct nss_ctx_instance *nss_ctx, const char *name) +{ + char *user_config; + char **mtype_table; + char needle[NSS_MEMINFO_BLOCK_NAME_MAXLEN + 6]; + char user_choice[NSS_MEMINFO_MEMTYPE_NAME_MAXLEN]; + int i; + char *p; + + user_config = nss_meminfo_user_config; + mtype_table = nss_meminfo_memtype_table; + + snprintf(needle, sizeof(needle), "<%1d, %s, ", nss_ctx->id, name); + + p = strstr(user_config, needle); + if (!p) + return -1; + + p += strlen(needle); + + for (i = 0; i < NSS_MEMINFO_MEMTYPE_NAME_MAXLEN - 1; i++) { + /* + * Each user config is like , + * it starts with '<' and ends with '>'. + */ + if (*p == '>' || *p == '\0') + break; + user_choice[i] = *p; + p++; + } + + user_choice[i] = '\0'; + + for (i = 0; i < NSS_MEMINFO_MEMTYPE_MAX; i++) + if (!strcmp(mtype_table[i], user_choice)) + return i; + + return -1; +} + +/* + * nss_meminfo_free_block_lists() + * Free block node and memory associated with each each memory object. + */ +static void nss_meminfo_free_block_lists(struct nss_ctx_instance *nss_ctx) +{ + struct nss_meminfo_ctx *mem_ctx; + struct nss_meminfo_block_list *l; + int i; + + mem_ctx = &nss_ctx->meminfo_ctx; + for (i = 0; i < NSS_MEMINFO_MEMTYPE_MAX; i++) { + struct nss_meminfo_block *b; + l = &mem_ctx->block_lists[i]; + b = l->head; + while (b) { + struct nss_meminfo_block *tmp; + /* + * Free IMEM/SDRAM/UTCM_SHARED memory. + */ + switch (i) { + case NSS_MEMINFO_MEMTYPE_IMEM: + nss_meminfo_free_imem(nss_ctx, b->dma_addr, b->size); + break; + case NSS_MEMINFO_MEMTYPE_SDRAM: + nss_meminfo_free_sdram(nss_ctx, b->dma_addr, b->kern_addr, b->size); + break; + case NSS_MEMINFO_MEMTYPE_UTCM_SHARED: + nss_meminfo_free_utcm_shared(nss_ctx, b->dma_addr, b->size); + break; + } + + /* + * Free the struct nss_meminfo_block itself. + */ + tmp = b; + b = b->next; + kfree(tmp); + } + } +} + +/* + * nss_meminfo_init_block_lists() + * Initialize block lists and allocate memory for each block. + */ +static bool nss_meminfo_init_block_lists(struct nss_ctx_instance *nss_ctx) +{ + /* + * There is no corresponding mapped address in kernel for UTCM_SHARED. + * UTCM_SHARED access from kernel is not allowed. Mem Objects requesting + * UTCM_SHARED are not expected to use any kernel mapped address. + * Was for UTCM_SHARED, but move to here as default especially for KW scan. + * Thus, NSS_MEMINFO_POISON is the default value for non-mappable memory request. + */ + void *kern_addr = (void *)NSS_MEMINFO_POISON; + uint32_t dma_addr = 0; + struct nss_meminfo_ctx *mem_ctx; + struct nss_meminfo_block_list *l; + struct nss_meminfo_request *r; + struct nss_meminfo_map *map; + int mtype; + int i; + + mem_ctx = &nss_ctx->meminfo_ctx; + + /* + * Fill memory type for each block list. + */ + for (i = 0; i < NSS_MEMINFO_MEMTYPE_MAX; i++) + mem_ctx->block_lists[i].memtype = i; + + map = &mem_ctx->meminfo_map; + + /* + * Loop through all meminfo requests by checking the per-request magic. + */ + for (r = map->requests; r->magic == NSS_MEMINFO_REQUEST_MAGIC; r++) { + struct nss_meminfo_block *b = (struct nss_meminfo_block *) + kmalloc(sizeof(struct nss_meminfo_block), GFP_KERNEL); + if (!b) { + nss_info_always("%px: failed to allocate meminfo block\n", nss_ctx); + goto cleanup; + } + + b->index = map->num_requests++; + b->size = r->size; + + /* + * Look up the user-defined memory type. + * Return user-defined memory type if exists. Otherwise, return -1. + */ + mtype = nss_meminfo_if_user_overwrite(nss_ctx, r->name); + if (mtype == -1) + mtype = r->memtype_default; + r->memtype_user = mtype; + + switch (mtype) { + case NSS_MEMINFO_MEMTYPE_IMEM: + /* + * Return SoC real address for IMEM as DMA address. + */ + dma_addr = nss_meminfo_alloc_imem(nss_ctx, r->size, r->alignment); + if (!dma_addr) { + nss_info_always("%px: failed to alloc IMEM block\n", nss_ctx); + goto cleanup; + } + + /* + * Calulate offset to the kernel address (vmap) where the + * whole IMEM is mapped onto instead of calling ioremap(). + */ + kern_addr = nss_ctx->vmap + dma_addr - nss_ctx->vphys; + break; + case NSS_MEMINFO_MEMTYPE_SDRAM: + kern_addr = nss_meminfo_alloc_sdram(nss_ctx, r->size); + if (!kern_addr) { + nss_info_always("%px: failed to alloc SDRAM block\n", nss_ctx); + goto cleanup; + } + + dma_addr = dma_map_single(nss_ctx->dev, kern_addr, r->size, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(nss_ctx->dev, dma_addr))) { + nss_info_always("%px: failed to map SDRAM block\n", nss_ctx); + goto cleanup; + } + break; + case NSS_MEMINFO_MEMTYPE_UTCM_SHARED: + /* + * Return SoC real address for UTCM_SHARED as DMA address. + */ + dma_addr = nss_meminfo_alloc_utcm_shared(nss_ctx, r->size, r->alignment); + if (!dma_addr) { + nss_info_always("%px: failed to alloc UTCM_SHARED block\n", nss_ctx); + goto cleanup; + } + break; + case NSS_MEMINFO_MEMTYPE_INFO: + /* + * if FW request heap_ddr_size, fill it in from DTS values. + */ + if (!strcmp(r->name, "heap_ddr_size")) { + struct nss_mmu_ddr_info coreinfo; + r->size = nss_core_ddr_info(&coreinfo); + + /* + * split memory among the number of cores + */ + r->size /= coreinfo.num_active_cores; + dma_addr = coreinfo.start_address + nss_ctx->id * r->size; + nss_info_always("%px: NSS core %d DDR from %x to %x\n", nss_ctx, + nss_ctx->id, dma_addr, dma_addr + r->size); + } + break; + default: + nss_info_always("%px: %d unsupported memory type\n", nss_ctx, mtype); + goto cleanup; + } + + /* + * Update the request with DMA address for the memory that only be used by FW. + */ + r->addr = dma_addr; + + /* + * nss_if_mem_map settings + */ + if (!strcmp(r->name, "nss_if_mem_map_inst")) { + BUG_ON(mtype == NSS_MEMINFO_MEMTYPE_UTCM_SHARED); + mem_ctx->if_map_memtype = mtype; + mem_ctx->if_map_dma = dma_addr; + mem_ctx->if_map = (struct nss_if_mem_map *)kern_addr; + } + + if (!strcmp(r->name, "debug_boot_log_desc")) { + BUG_ON(mtype == NSS_MEMINFO_MEMTYPE_UTCM_SHARED); + mem_ctx->logbuffer_memtype = mtype; + mem_ctx->logbuffer_dma = dma_addr; + mem_ctx->logbuffer = (struct nss_log_descriptor *)kern_addr; + } + + if (!strcmp(r->name, "c2c_descs_if_mem_map")) { + mem_ctx->c2c_start_memtype = mtype; + mem_ctx->c2c_start_dma = dma_addr; + } + + if (strcmp(r->name, "profile_dma_ctrl") == 0) { + mem_ctx->sdma_ctrl = kern_addr; + nss_info_always("%px: set sdma %px\n", nss_ctx, kern_addr); + } + + /* + * Flush the updated meminfo request. + */ + NSS_CORE_DMA_CACHE_MAINT(r, sizeof(struct nss_meminfo_request), DMA_TO_DEVICE); + NSS_CORE_DSB(); + + /* + * Update the list + */ + l = &mem_ctx->block_lists[mtype]; + l->num_blks++; + l->total_size += r->size; + + b->next = l->head; + l->head = b; + } + + /* + * Verify memory map end magic + */ + if (*((uint16_t *)r) != NSS_MEMINFO_MAP_END_MAGIC) + goto cleanup; + + return true; + +cleanup: + nss_meminfo_free_block_lists(nss_ctx); + return false; +} + +/* + * nss_meminfo_allocate_n2h_h2n_rings() + * Allocate N2H/H2N rings. + */ +static bool nss_meminfo_allocate_n2h_h2n_rings(struct nss_ctx_instance *nss_ctx, + struct nss_meminfo_n2h_h2n_info *info) +{ + switch (info->memtype) { + case NSS_MEMINFO_MEMTYPE_SDRAM: + info->kern_addr = nss_meminfo_alloc_sdram(nss_ctx, info->total_size); + if (!info->kern_addr) + return false; + + info->dma_addr = dma_map_single(nss_ctx->dev, (void *)info->kern_addr, + info->total_size, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(nss_ctx->dev, info->dma_addr))) { + kfree((void *)info->kern_addr); + return false; + } + break; + case NSS_MEMINFO_MEMTYPE_IMEM: + info->dma_addr = nss_meminfo_alloc_imem(nss_ctx, info->total_size, L1_CACHE_BYTES); + if (!info->dma_addr) + return false; + + info->kern_addr = nss_ctx->vmap + info->dma_addr - nss_ctx->vphys; + break; + default: + return false; + } + + return true; +} + +/* + * nss_meminfo_configure_n2h_h2n_rings() + * Configure N2H/H2N rings and if_map. + */ +static bool nss_meminfo_configure_n2h_h2n_rings(struct nss_ctx_instance *nss_ctx) +{ + struct nss_meminfo_ctx *mem_ctx = &nss_ctx->meminfo_ctx; + struct nss_meminfo_n2h_h2n_info *h2n_info; + struct nss_meminfo_n2h_h2n_info *n2h_info; + struct nss_if_mem_map *if_map; + int i; + int mtype; + + h2n_info = &mem_ctx->h2n_info; + n2h_info = &mem_ctx->n2h_info; + + /* + * Check memory type. SDRAM is the default option. + */ + mtype = nss_meminfo_if_user_overwrite(nss_ctx, "h2n_rings"); + if (mtype == -1) + mtype = NSS_MEMINFO_MEMTYPE_SDRAM; + + h2n_info->memtype = mtype; + + mtype = nss_meminfo_if_user_overwrite(nss_ctx, "n2h_rings"); + if (mtype == -1) + mtype = NSS_MEMINFO_MEMTYPE_SDRAM; + + n2h_info->memtype = mtype; + + n2h_info->total_size = sizeof(struct n2h_descriptor) * NSS_N2H_RING_COUNT * (NSS_RING_SIZE + 2); + h2n_info->total_size = sizeof(struct h2n_descriptor) * NSS_H2N_RING_COUNT * (NSS_RING_SIZE + 2); + + /* + * N2H ring allocations + */ + if (!(nss_meminfo_allocate_n2h_h2n_rings(nss_ctx, n2h_info))) { + nss_info_always("%px: failed to allocate/map n2h rings\n", nss_ctx); + return false; + } + + /* + * H2N ring allocations + */ + if (!(nss_meminfo_allocate_n2h_h2n_rings(nss_ctx, h2n_info))) { + nss_info_always("%px: failed to allocate/map h2n_rings\n", nss_ctx); + goto cleanup; + } + + /* + * Bring a fresh copy of if_map from memory in order to read it correctly. + */ + if_map = mem_ctx->if_map; + NSS_CORE_DMA_CACHE_MAINT((void *)if_map, sizeof(struct nss_if_mem_map), DMA_FROM_DEVICE); + NSS_CORE_DSB(); + + if_map->n2h_rings = NSS_N2H_RING_COUNT; + if_map->h2n_rings = NSS_H2N_RING_COUNT; + + /* + * N2H ring settings + */ + for (i = 0; i < NSS_N2H_RING_COUNT; i++) { + struct hlos_n2h_desc_ring *n2h_desc_ring = &nss_ctx->n2h_desc_ring[i]; + n2h_desc_ring->desc_ring.desc = (struct n2h_descriptor *)(n2h_info->kern_addr + i * sizeof(struct n2h_descriptor) * (NSS_RING_SIZE + 2)); + n2h_desc_ring->desc_ring.size = NSS_RING_SIZE; + n2h_desc_ring->hlos_index = if_map->n2h_hlos_index[i]; + + if_map->n2h_desc_if[i].size = NSS_RING_SIZE; + if_map->n2h_desc_if[i].desc_addr = n2h_info->dma_addr + i * sizeof(struct n2h_descriptor) * (NSS_RING_SIZE + 2); + nss_info("%px: N2H ring %d, size %d, addr = %x\n", nss_ctx, i, if_map->n2h_desc_if[i].size, if_map->n2h_desc_if[i].desc_addr); + } + + /* + * H2N ring settings + */ + for (i = 0; i < NSS_H2N_RING_COUNT; i++) { + struct hlos_h2n_desc_rings *h2n_desc_ring = &nss_ctx->h2n_desc_rings[i]; + h2n_desc_ring->desc_ring.desc = (struct h2n_descriptor *)(h2n_info->kern_addr + i * sizeof(struct h2n_descriptor) * (NSS_RING_SIZE + 2)); + h2n_desc_ring->desc_ring.size = NSS_RING_SIZE; + h2n_desc_ring->hlos_index = if_map->h2n_hlos_index[i]; + spin_lock_init(&h2n_desc_ring->lock); + + if_map->h2n_desc_if[i].size = NSS_RING_SIZE; + if_map->h2n_desc_if[i].desc_addr = h2n_info->dma_addr + i * sizeof(struct h2n_descriptor) * (NSS_RING_SIZE + 2); + nss_info("%px: H2N ring %d, size %d, addr = %x\n", nss_ctx, i, if_map->h2n_desc_if[i].size, if_map->h2n_desc_if[i].desc_addr); + } + + /* + * Flush the updated nss_if_mem_map. + */ + NSS_CORE_DMA_CACHE_MAINT((void *)if_map, sizeof(struct nss_if_mem_map), DMA_TO_DEVICE); + NSS_CORE_DSB(); + + return true; + +cleanup: + if (n2h_info->memtype == NSS_MEMINFO_MEMTYPE_SDRAM) + nss_meminfo_free_sdram(nss_ctx, n2h_info->dma_addr, n2h_info->kern_addr, n2h_info->total_size); + else + nss_meminfo_free_imem(nss_ctx, n2h_info->dma_addr, n2h_info->total_size); + + nss_meminfo_free_block_lists(nss_ctx); + return false; +} + +/* + * nss_meminfo_config_show() + * function to show meinfo configuration per core. + */ +static int nss_meminfo_config_show(struct seq_file *seq, void *v) +{ + struct nss_ctx_instance *nss_ctx; + struct nss_meminfo_ctx *mem_ctx; + struct nss_meminfo_n2h_h2n_info *n2h_info; + struct nss_meminfo_n2h_h2n_info *h2n_info; + struct nss_meminfo_map *map; + struct nss_meminfo_request *r; + int nss_id; + int i; + + /* + * i_private is passed to us by debug_fs_create() + */ + nss_id = (int)(nss_ptr_t)seq->private; + if (nss_id < 0 || nss_id >= nss_top_main.num_nss) { + nss_warning("nss_id: %d is not valid\n", nss_id); + return -ENODEV; + } + + nss_ctx = &nss_top_main.nss[nss_id]; + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + mem_ctx = &nss_ctx->meminfo_ctx; + map = &mem_ctx->meminfo_map; + n2h_info = &mem_ctx->n2h_info; + h2n_info = &mem_ctx->h2n_info; + + seq_printf(seq, "%-5s %-32s %-7s %-7s %-10s %-10s\n", + "Index", "Name", "Default", "User", "Size", "DMA Addr"); + seq_printf(seq, "%-5s %-32s %-7s %-7s 0x%-8x 0x%-8x\n", + "N/A", "n2h_rings", "SDRAM", + nss_meminfo_memtype_table[n2h_info->memtype], + n2h_info->total_size, n2h_info->dma_addr); + seq_printf(seq, "%-5s %-32s %-7s %-7s 0x%-8x 0x%-8x\n", + "N/A", "h2n_rings", "SDRAM", + nss_meminfo_memtype_table[h2n_info->memtype], + h2n_info->total_size, h2n_info->dma_addr); + + r = map->requests; + for (i = 0; i < map->num_requests; i++) { + seq_printf(seq, "%-5d %-32s %-7s %-7s 0x%-8x 0x%-8x\n", + i, r[i].name, + nss_meminfo_memtype_table[r[i].memtype_default], + nss_meminfo_memtype_table[r[i].memtype_user], + r[i].size, r[i].addr); + } + + seq_printf(seq, "Available IMEM: 0x%x\n", mem_ctx->imem_end - mem_ctx->imem_tail); + seq_printf(seq, "How to configure? \n"); + seq_printf(seq, "Overwrite the /etc/modules.d/32-qca-nss-drv with following contents then reboot\n\n"); + seq_printf(seq, "qca-nss-drv meminfo_user_config=\", ..\"\n\n"); + seq_printf(seq, "For example, <1, h2n_rings, IMEM> stands for: h2n_rings of core 1 is on IMEM\n"); + seq_printf(seq, "Note:UTCM_SHARED cannot be used for n2h_rings, h2n_rings and debug_log_boot_desc.\n"); + + return 0; +} + +/* + * nss_meminfo_debugfs_file_open() + * function to open meminfo debugfs. + */ +static int nss_meminfo_debugfs_file_open(struct inode *inode, struct file *file) +{ + return single_open(file, nss_meminfo_config_show, inode->i_private); +} + +static struct file_operations nss_meminfo_debugfs_ops = { + .owner = THIS_MODULE, + .open = nss_meminfo_debugfs_file_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +/* + * nss_meminfo_init_debugfs() + * Init meminfo debugfs. + */ +static void nss_meminfo_init_debugfs(struct nss_ctx_instance *nss_ctx) +{ + int i; + struct dentry *meminfo_main_dentry; + struct dentry *meminfo_core_dentries[NSS_MAX_CORES]; + + if (nss_meminfo_debugfs_exist) + return; + + /* + * Create directory for showing meminfo configuration of each core. + */ + meminfo_main_dentry = debugfs_create_dir("meminfo", nss_top_main.top_dentry); + if (unlikely(!meminfo_main_dentry)) { + nss_warning("Failed to create qca-nss-drv/meminfo directory in debugfs\n"); + return; + } + + for (i = 0; i < nss_top_main.num_nss; i++) { + char file[10]; + snprintf(file, sizeof(file), "core%d", i); + meminfo_core_dentries[i] = debugfs_create_file(file, 0400, meminfo_main_dentry, + (void *)(nss_ptr_t)i, &nss_meminfo_debugfs_ops); + if (unlikely(!meminfo_core_dentries[i])) { + int j; + for (j = 0; j < i; j++) + debugfs_remove(meminfo_core_dentries[j]); + debugfs_remove(meminfo_main_dentry); + nss_warning("Failed to create qca-nss-drv/meminfo/%s file in debugfs", file); + return; + } + } + + nss_meminfo_debugfs_exist = true; + nss_info("nss meminfo user config: %s\n", nss_meminfo_user_config); +} + +/* + * nss_meminfo_init + * Initilization + * + */ +bool nss_meminfo_init(struct nss_ctx_instance *nss_ctx) +{ + struct nss_meminfo_ctx *mem_ctx; + uint32_t *meminfo_start; + struct nss_meminfo_map *map; + struct nss_top_instance *nss_top = &nss_top_main; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + mem_ctx = &nss_ctx->meminfo_ctx; + + /* + * meminfo_start is the label where the start address of meminfo map is stored. + */ + meminfo_start = (uint32_t *)ioremap_nocache(nss_ctx->load + NSS_MEMINFO_MAP_START_OFFSET, + NSS_MEMINFO_RESERVE_AREA_SIZE); + if (!meminfo_start) { + nss_info_always("%px: cannot remap meminfo start\n", nss_ctx); + return false; + } + + /* + * Check meminfo start magic + */ + if ((uint16_t)meminfo_start[0] != NSS_MEMINFO_RESERVE_AREA_MAGIC) { + nss_info_always("%px: failed to verify meminfo start magic\n", nss_ctx); + return false; + } + + map = &mem_ctx->meminfo_map; + map->start = (uint32_t *)ioremap_cache(meminfo_start[1], NSS_MEMINFO_MAP_SIZE); + if (!map->start) { + nss_info_always("%px: failed to remap meminfo map\n", nss_ctx); + return false; + } + + /* + * Check meminfo map magic + */ + if ((uint16_t)map->start[0] != NSS_MEMINFO_MAP_START_MAGIC) { + nss_info_always("%px: failed to verify meminfo map magic\n", nss_ctx); + return false; + } + + /* + * Meminfo map settings + */ + map->num_requests = 0; + map->requests = (struct nss_meminfo_request *)(map->start + 1); + + /* + * Init IMEM + */ + nss_top->hal_ops->init_imem(nss_ctx); + + /* + * Init UTCM_SHARED if supported + */ + if (!nss_top->hal_ops->init_utcm_shared(nss_ctx, meminfo_start)) { + nss_info_always("%px: failed to initialize UTCM_SHARED meminfo\n", nss_ctx); + return false; + } + + /* + * Init meminfo block lists + */ + if (!nss_meminfo_init_block_lists(nss_ctx)) { + nss_info_always("%px: failed to initialize meminfo block lists\n", nss_ctx); + return false; + } + + /* + * Configure N2H/H2N rings and nss_if_mem_map + */ + if (!nss_meminfo_configure_n2h_h2n_rings(nss_ctx)) + return false; + + nss_meminfo_init_debugfs(nss_ctx); + + nss_info_always("%px: meminfo init succeed\n", nss_ctx); + return true; +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_meminfo.h b/feeds/ipq807x/qca-nss-drv/src/nss_meminfo.h new file mode 100644 index 000000000..5c006cc54 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_meminfo.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * nss_meminfo.h + * nss meminfo header file. + */ + +#ifndef __NSS_MEMINFO_H +#define __NSS_MEMINFO_H + +#define NSS_MEMINFO_RESERVE_AREA_SIZE 0x1000 /* Size of reserved space in firmware start code aligned to one page */ +#define NSS_MEMINFO_RESERVE_AREA_MAGIC 0x9526 /* Magic at the beginning of reserved space */ +#define NSS_MEMINFO_MAP_START_OFFSET 8 /* Offset of memory map start address in reserved space */ +#define NSS_MEMINFO_MAP_SIZE 0x1000 /* Size of memory map per core aligned to one page */ +#define NSS_MEMINFO_MAP_START_MAGIC 0x9527 +#define NSS_MEMINFO_REQUEST_MAGIC 0X9528 +#define NSS_MEMINFO_MAP_END_MAGIC 0x9529 +#define NSS_MEMINFO_RESERVE_AREA_UTCM_SHARED_MAP_MAGIC 0x9530 /* Magic at the beginning of UTCM_SHARED reserved space */ +#define NSS_MEMINFO_BLOCK_NAME_MAXLEN 48 +#define NSS_MEMINFO_MEMTYPE_NAME_MAXLEN 32 +#define NSS_MEMINFO_USER_CONFIG_MAXLEN 1024 +#define NSS_MEMINFO_POISON 0x95 /* Invalid kernel memory address assigned for non mapable mem types */ + +/* + * Memory types available + */ +enum nss_meminfo_memtype { + NSS_MEMINFO_MEMTYPE_IMEM, /* NSS-IMEM also called TCM */ + NSS_MEMINFO_MEMTYPE_SDRAM, /* SDRAM also called DDR */ + NSS_MEMINFO_MEMTYPE_UTCM_SHARED, /* UTCM memory allocated for DMA objects */ + NSS_MEMINFO_MEMTYPE_INFO, /* Exchange information during boot up */ + NSS_MEMINFO_MEMTYPE_MAX +}; + +/* + * Memory request + * Firmware package defines each request asking host to feed the request. + */ +struct nss_meminfo_request { + uint16_t magic; /* Request magic */ + char name[NSS_MEMINFO_BLOCK_NAME_MAXLEN]; /* Memory block name */ + uint16_t memtype_default; /* Memory type requested */ + uint16_t memtype_user; /* User-defined memory type */ + uint32_t alignment; /* Alignment requirement */ + uint32_t size; /* Size requested */ + uint32_t addr; /* Memory block address got from host */ +}; + +/* + * Memory map + * It starts with a magic then an array of memory request and end with a checksum. + * Firmware creates the map for host to parse. + */ +struct nss_meminfo_map { + uint32_t *start; /* Start address */ + uint32_t num_requests; /* Number of requests */ + struct nss_meminfo_request *requests; /* Start of Request array */ +}; + +/* + * Memory block + * Block node for each request. + */ +struct nss_meminfo_block { + struct nss_meminfo_block *next; /* Next block in the same list */ + uint32_t index; /* Index to request array */ + uint32_t size; /* Size of memory block */ + uint32_t dma_addr; /* DMA address */ + void *kern_addr; /* Kernel address */ +}; + +/* + * Memory block list + * List of block node of same memory type. + */ +struct nss_meminfo_block_list { + enum nss_meminfo_memtype memtype; /* memory type */ + uint32_t num_blks; /* Number of blocks */ + uint32_t total_size; /* Size of all memory blocks in this list */ + struct nss_meminfo_block *head; /* list head */ +}; + +/* + * H2N/N2H rings information + */ +struct nss_meminfo_n2h_h2n_info { + enum nss_meminfo_memtype memtype; /* Memory type */ + uint32_t total_size; /* Total size */ + uint32_t dma_addr; /* DMA address */ + void *kern_addr; /* Kernel address */ +}; + +/* + * Memory context + */ +struct nss_meminfo_ctx { + struct nss_meminfo_n2h_h2n_info n2h_info; /* N2H rings info*/ + struct nss_meminfo_n2h_h2n_info h2n_info; /* H2N rings info */ + uint32_t imem_head; /* IMEM start address */ + uint32_t imem_end; /* IMEM end address */ + uint32_t imem_tail; /* IMEM data end */ + uint32_t utcm_shared_head; /* UTCM_SHARED start address */ + uint32_t utcm_shared_end; /* UTCM_SHARED end address */ + uint32_t utcm_shared_tail; /* UTCM_SHARED data end */ + struct nss_if_mem_map *if_map; /* nss_if_mem_map_inst virtual address */ + uint32_t if_map_dma; /* nss_if_mem_map_inst physical address */ + enum nss_meminfo_memtype if_map_memtype; /* Memory type for nss_if_mem_map */ + struct nss_log_descriptor *logbuffer; /* nss_logbuffer virtual address */ + uint32_t logbuffer_dma; /* nss_logbuffer physical address */ + enum nss_meminfo_memtype logbuffer_memtype; /* Memory type for logbuffer */ + uint32_t c2c_start_dma; /* nss_c2c start physical address */ + enum nss_meminfo_memtype c2c_start_memtype; /* Memory type for c2c_start */ + void *sdma_ctrl; /* Soft DMA controller */ + + struct nss_meminfo_map meminfo_map; /* Meminfo map */ + struct nss_meminfo_block_list block_lists[NSS_MEMINFO_MEMTYPE_MAX]; + /* Block lists for each memory type */ +}; + +bool nss_meminfo_init(struct nss_ctx_instance *nss_ctx); +#endif diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_mirror.c b/feeds/ipq807x/qca-nss-drv/src/nss_mirror.c new file mode 100644 index 000000000..b27f10e4f --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_mirror.c @@ -0,0 +1,293 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_mirror_stats.h" +#include "nss_mirror_log.h" + +#define NSS_MIRROR_TX_TIMEOUT 3000 /* 3 Seconds */ + +/* + * Private data structure + */ +static struct { + struct semaphore sem; + struct completion complete; + int response; +} nss_mirror_pvt; + +atomic_t nss_mirror_num_instances; /* Number of active mirror stats instances. */ + +/* + * nss_mirror_verify_if_num() + * Verify interface number passed to us. + */ +bool nss_mirror_verify_if_num(uint32_t if_num) +{ + enum nss_dynamic_interface_type if_type; + + if_type = nss_dynamic_interface_get_type(nss_mirror_get_context(), if_num); + if (if_type == NSS_DYNAMIC_INTERFACE_TYPE_MIRROR) { + return true; + } + + return false; +} +EXPORT_SYMBOL(nss_mirror_verify_if_num); + +/* + * nss_mirror_handler() + * Handle NSS -> HLOS messages for mirror device. + */ +static void nss_mirror_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, + void *app_data) +{ + struct nss_mirror_msg *nmm = (struct nss_mirror_msg *)ncm; + void *ctx; + nss_mirror_msg_callback_t cb; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + nss_assert(nss_mirror_verify_if_num(ncm->interface)); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_MIRROR_MSG_MAX) { + nss_warning("%px: received invalid message %d for mirror interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_mirror_msg)) { + nss_warning("%px: Length of message is greater than expected.", nss_ctx); + return; + } + + /* + * Log messages. + */ + nss_core_log_msg_failures(nss_ctx, ncm); + nss_mirror_log_rx_msg(nmm); + + switch (ncm->type) { + case NSS_MIRROR_MSG_SYNC_STATS: + /* + * Debug stats embedded in stats msg. + */ + nss_mirror_stats_sync(nss_ctx, nmm, ncm->interface); + break; + } + + /* + * Update the callback and app_data for NOTIFY messages. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_core_get_msg_handler(nss_ctx, ncm->interface); + ncm->app_data = (nss_ptr_t)app_data; + } + + /* + * Callback. + */ + cb = (nss_mirror_msg_callback_t)ncm->cb; + ctx = (void *)ncm->app_data; + + /* + * Call mirror interface callback. + */ + if (!cb) { + nss_warning("%px: No callback for mirror interface %d", + nss_ctx, ncm->interface); + return; + } + + cb(ctx, ncm); +} + +/* + * nss_mirror_callback() + * Callback to handle the completion of NSS->HLOS messages. + */ +static void nss_mirror_callback(void *app_data, struct nss_cmn_msg *ncm) +{ + nss_mirror_pvt.response = NSS_TX_SUCCESS; + + if (ncm->response != NSS_CMN_RESPONSE_ACK) { + nss_warning("mirror interface error response %d\n", ncm->response); + nss_mirror_pvt.response = NSS_TX_FAILURE; + } + + /* + * Write memory barrier. + */ + smp_wmb(); + complete(&nss_mirror_pvt.complete); +} + +/* + * nss_mirror_tx_msg() + * Transmit a mirror interface message to NSS firmware. + */ +nss_tx_status_t nss_mirror_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_mirror_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Sanity check the message. + */ + if (!nss_mirror_verify_if_num(ncm->interface)) { + nss_warning("%px: tx request for non mirror interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type > NSS_MIRROR_MSG_MAX) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + /* + * Trace messages. + */ + nss_mirror_log_tx_msg(msg); + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_mirror_tx_msg); + +/* + * nss_mirror_tx_msg_sync() + * Transmit a mirror interface message to NSS firmware synchronously. + */ +nss_tx_status_t nss_mirror_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_mirror_msg *msg) +{ + nss_tx_status_t status; + int ret = 0; + + down(&nss_mirror_pvt.sem); + msg->cm.cb = (nss_ptr_t)nss_mirror_callback; + msg->cm.app_data = (nss_ptr_t)NULL; + + status = nss_mirror_tx_msg(nss_ctx, msg); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: mirror_tx_msg failed\n", nss_ctx); + up(&nss_mirror_pvt.sem); + return status; + } + + ret = wait_for_completion_timeout(&nss_mirror_pvt.complete, msecs_to_jiffies(NSS_MIRROR_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: Mirror interface tx sync failed due to timeout\n", nss_ctx); + nss_mirror_pvt.response = NSS_TX_FAILURE; + } + + status = nss_mirror_pvt.response; + up(&nss_mirror_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_mirror_tx_msg_sync); + +/* + * nss_mirror_unregister_if() + * Un-registers mirror interface from the NSS. + */ +void nss_mirror_unregister_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.mirror_handler_id]; + uint32_t status; + + nss_assert(nss_ctx); + nss_assert(nss_mirror_verify_if_num(if_num)); + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + + nss_core_unregister_handler(nss_ctx, if_num); + + status = nss_core_unregister_msg_handler(nss_ctx, if_num); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Not able to unregister handler for interface %d with NSS core\n", nss_ctx, if_num); + } + + atomic_dec(&nss_mirror_num_instances); + nss_mirror_stats_reset(if_num); +} +EXPORT_SYMBOL(nss_mirror_unregister_if); + +/* + * nss_mirror_register_if() + * Registers the mirror interface with NSS. + */ +struct nss_ctx_instance *nss_mirror_register_if(uint32_t if_num, + nss_mirror_data_callback_t data_callback, + nss_mirror_msg_callback_t event_callback, + struct net_device *netdev, uint32_t features) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.mirror_handler_id]; + int ret; + + nss_assert(nss_ctx); + nss_assert(netdev); + nss_assert(nss_mirror_verify_if_num(if_num)); + + if (atomic_read(&nss_mirror_num_instances) == NSS_MAX_MIRROR_DYNAMIC_INTERFACES) { + nss_warning("%px: Maximum number of mirror interfaces are already allocated\n", nss_ctx); + return NULL; + } + + ret = nss_mirror_stats_init(if_num, netdev); + if (ret < 0) { + nss_warning("%px: Error in initializaing mirror stats.\n", nss_ctx); + return NULL; + } + + nss_core_register_handler(nss_ctx, if_num, nss_mirror_handler, netdev); + ret = nss_core_register_msg_handler(nss_ctx, if_num, event_callback); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_core_unregister_handler(nss_ctx, if_num); + nss_warning("%px: Not able to register handler for mirror interface %d with NSS core\n", nss_ctx, if_num); + return NULL; + } + + nss_core_register_subsys_dp(nss_ctx, if_num, data_callback, NULL, NULL, netdev, features); + nss_core_set_subsys_dp_type(nss_ctx, netdev, if_num, NSS_DYNAMIC_INTERFACE_TYPE_MIRROR); + + atomic_inc(&nss_mirror_num_instances); + return nss_ctx; +} +EXPORT_SYMBOL(nss_mirror_register_if); + +/* + * nss_mirror_get_context() + * Get the mirror instance context. + */ +struct nss_ctx_instance *nss_mirror_get_context(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.mirror_handler_id]; +} +EXPORT_SYMBOL(nss_mirror_get_context); + +/* + * nss_mirror_register_handler() + * Initialize and register mirror instance handler. + */ +void nss_mirror_register_handler(void) +{ + nss_info("nss_mirror_register_handler"); + sema_init(&nss_mirror_pvt.sem, 1); + init_completion(&nss_mirror_pvt.complete); + + nss_mirror_stats_dentry_create(); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_mirror_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_mirror_log.c new file mode 100644 index 000000000..5fb8858f3 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_mirror_log.c @@ -0,0 +1,198 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_mirror_log.c + * NSS Mirror logger file. + */ + +#include "nss_core.h" + +/* + * nss_mirror_log_message_types_str + * MIRROR message strings + */ +static int8_t *nss_mirror_log_message_types_str[NSS_MIRROR_MSG_MAX] __maybe_unused = { + "Mirror Configure Msg", + "Mirror Enable Msg", + "Mirror Disable Msg", + "Mirror Set Nexthop Msg", + "Mirror Reset Nexthop Msg", + "Mirror Stats Sync Msg", +}; + +/* + * nss_mirror_log_error_response_types_str + * Strings for error types for Mirror messages + */ +static int8_t *nss_mirror_log_error_response_types_str[NSS_MIRROR_ERROR_TYPE_MAX] __maybe_unused = { + "Mirror no error", + "Mirror No Memory", + "Mirror Transmit Failure", + "Mirror Bad Parameter", + "Mirror Bad Clone Point", + "Mirror Intance Configured", + "Mirror Intance Disabled", + "Mirror Bad Nexthop", + "Mirror Nexthop Configured", + "Mirror Nexthop Reset", + "Mirror Unknown Message", +}; + +/* + * nss_mirror_log_configure_msg() + * Log NSS Mirror Configure message. + */ +static void nss_mirror_log_configure_msg(struct nss_mirror_msg *nmm) +{ + struct nss_mirror_configure_msg *config_msg __maybe_unused = &nmm->msg.config; + + nss_trace("%px: NSS Mirror Config message \n" + "Packet clone size: %u\n" + "Packet clone point: %hu\n", + config_msg, + config_msg->pkt_clone_size, + config_msg->pkt_clone_point); +} + +/* + * nss_mirror_log_set_nexthop_msg() + * Log NSS Mirror Set Nexthop message. + */ +static void nss_mirror_log_set_nexthop_msg(struct nss_mirror_msg *nmm) +{ + struct nss_mirror_set_nexthop_msg *nexthop_msg __maybe_unused = &nmm->msg.nexthop; + + nss_trace("%px: NSS Mirror Nexthop message \n" + "Nexthop interface number: %u\n", + nexthop_msg, + nexthop_msg->if_num); +} + +/* + * nss_mirror_log_enable_msg() + * Log NSS Mirror Enable message. + */ +static void nss_mirror_log_enable_msg(struct nss_mirror_msg *nmm) +{ + nss_trace("%px: NSS Mirror message: Enable \n", nmm); +} + +/* + * nss_mirror_log_disable_msg() + * Log NSS Mirror Disable message. + */ +static void nss_mirror_log_disable_msg(struct nss_mirror_msg *nmm) +{ + nss_trace("%px: NSS Mirror message: Disable \n", nmm); +} + +/* + * nss_mirror_log_reset_nexthop_msg() + * Log NSS Mirror Reset Nexthop message. + */ +static void nss_mirror_log_reset_nexthop_msg(struct nss_mirror_msg *nmm) +{ + nss_trace("%px: NSS Mirror message: Reset Nexthop \n", nmm); +} + +/* + * nss_mirror_log_verbose() + * Log message contents. + */ +static void nss_mirror_log_verbose(struct nss_mirror_msg *nmm) +{ + switch (nmm->cm.type) { + case NSS_MIRROR_MSG_CONFIGURE: + nss_mirror_log_configure_msg(nmm); + break; + + case NSS_MIRROR_MSG_ENABLE: + nss_mirror_log_enable_msg(nmm); + break; + + case NSS_MIRROR_MSG_DISABLE: + nss_mirror_log_disable_msg(nmm); + break; + + case NSS_MIRROR_MSG_SET_NEXTHOP: + nss_mirror_log_set_nexthop_msg(nmm); + break; + + case NSS_MIRROR_MSG_RESET_NEXTHOP: + nss_mirror_log_reset_nexthop_msg(nmm); + break; + + case NSS_MIRROR_MSG_SYNC_STATS: + break; + + default: + nss_trace("%px: Invalid message type\n", nmm); + break; + } +} + +/* + * nss_mirror_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_mirror_log_tx_msg(struct nss_mirror_msg *nmm) +{ + if (nmm->cm.type >= NSS_MIRROR_MSG_MAX) { + nss_warning("%px: Invalid message type\n", nmm); + return; + } + + nss_info("%px: type[%d]:%s\n", nmm, nmm->cm.type, nss_mirror_log_message_types_str[nmm->cm.type]); + nss_mirror_log_verbose(nmm); +} + +/* + * nss_mirror_log_rx_msg() + * Log messages received from FW. + */ +void nss_mirror_log_rx_msg(struct nss_mirror_msg *nmm) +{ + if (nmm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", nmm); + return; + } + + if (nmm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (nmm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", nmm, nmm->cm.type, + nss_mirror_log_message_types_str[nmm->cm.type], + nmm->cm.response, nss_cmn_response_str[nmm->cm.response]); + goto verbose; + } + + if (nmm->cm.error >= NSS_MIRROR_ERROR_TYPE_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + nmm, nmm->cm.type, nss_mirror_log_message_types_str[nmm->cm.type], + nmm->cm.response, nss_cmn_response_str[nmm->cm.response], + nmm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + nmm, nmm->cm.type, nss_mirror_log_message_types_str[nmm->cm.type], + nmm->cm.response, nss_cmn_response_str[nmm->cm.response], + nmm->cm.error, nss_mirror_log_error_response_types_str[nmm->cm.error]); + +verbose: + nss_mirror_log_verbose(nmm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_mirror_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_mirror_log.h new file mode 100644 index 000000000..a81a4a022 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_mirror_log.h @@ -0,0 +1,39 @@ +/* + ****************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_MIRROR_LOG_H__ +#define __NSS_MIRROR_LOG_H__ + +/* + * nss_mirror_log.h + * NSS Mirror Log Header File. + */ + +/* + * nss_mirror_log_tx_msg + * Logs a Mirror message that is sent to the NSS firmware. + */ +void nss_mirror_log_tx_msg(struct nss_mirror_msg *nmm); + +/* + * nss_mirror_log_rx_msg + * Logs a Mirror message that is received from the NSS firmware. + */ +void nss_mirror_log_rx_msg(struct nss_mirror_msg *nmm); + +#endif /* __NSS_MIRROR_LOG_H__*/ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_mirror_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_mirror_stats.c new file mode 100644 index 000000000..574312bac --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_mirror_stats.c @@ -0,0 +1,287 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_stats.h" +#include "nss_core.h" +#include "nss_mirror_stats.h" + +static struct nss_mirror_stats_debug_instance *stats_db[NSS_MAX_MIRROR_DYNAMIC_INTERFACES]; + /* Mirror stats data structure. */ + +/* + * Data structures to store mirror interface stats. + */ +static DEFINE_SPINLOCK(nss_mirror_stats_debug_lock); + +/* + * nss_mirror_stats_str + * Mirror statistics strings for nss session stats. + */ +struct nss_stats_info nss_mirror_stats_str[NSS_MIRROR_STATS_MAX] = { + {"MIRROR_STATS_PKTS" , NSS_STATS_TYPE_SPECIAL}, + {"MIRROR_STATS_BYTES" , NSS_STATS_TYPE_SPECIAL}, + {"MIRROR_STATS_TX_FAIL" , NSS_STATS_TYPE_DROP}, + {"MIRROR_STATS_DEST_LOOKUP_FAIL" , NSS_STATS_TYPE_DROP}, + {"MIRROR_STATS_MEM_ALLOC_FAIL" , NSS_STATS_TYPE_ERROR}, + {"MIRROR_STATS_COPY_FAIL" , NSS_STATS_TYPE_ERROR}, +}; + +/* + * nss_mirror_stats_get() + * Get mirror interface statistics. + */ +static void nss_mirror_stats_get(void *stats_mem, uint32_t stats_num) +{ + struct nss_mirror_stats_debug_instance *stats = (struct nss_mirror_stats_debug_instance *)stats_mem; + int i; + + if (!stats) { + nss_warning("No memory to copy mirror interface stats"); + return; + } + + spin_lock_bh(&nss_mirror_stats_debug_lock); + for (i = 0; i < NSS_MAX_MIRROR_DYNAMIC_INTERFACES; i++) { + + /* + * Copy maximum for given number of instances only. + */ + if (likely(stats_db[i])) { + if (likely(stats_num)) { + memcpy(stats, stats_db[i], sizeof(struct nss_mirror_stats_debug_instance)); + stats++; + stats_num--; + } else { + break; + } + } + } + spin_unlock_bh(&nss_mirror_stats_debug_lock); +} + +/* + * nss_mirror_stats_read() + * Read mirror interface statistics. + */ +static ssize_t nss_mirror_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + + uint32_t max_output_lines = 2 /* header & footer for instance stats */ + + NSS_MAX_MIRROR_DYNAMIC_INTERFACES * + ((NSS_STATS_NODE_MAX + 3 ) + (NSS_MIRROR_STATS_MAX + 3)) /*instance stats */ + + 2; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + struct net_device *dev; + struct nss_mirror_stats_debug_instance *mirror_shadow_stats; + uint32_t id, mirror_active_instances = atomic_read(&nss_mirror_num_instances); + char *lbuf; + + if (!mirror_active_instances) { + return 0; + } + + lbuf = vzalloc(size_al); + if (unlikely(!lbuf)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + mirror_shadow_stats = vzalloc(sizeof(struct nss_mirror_stats_debug_instance) * + mirror_active_instances); + if (unlikely(!mirror_shadow_stats)) { + nss_warning("Could not allocate memory for base debug statistics buffer"); + vfree(lbuf); + return 0; + } + + /* + * Get all stats + */ + nss_mirror_stats_get((void *)mirror_shadow_stats, mirror_active_instances); + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "mirror", NSS_STATS_SINGLE_CORE); + + /* + * Session stats + */ + for (id = 0; id < mirror_active_instances; id++) { + dev = dev_get_by_index(&init_net, mirror_shadow_stats[id].if_index); + if (likely(dev)) { + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d, netdevice=%s\n", id, + mirror_shadow_stats[id].if_num, dev->name); + dev_put(dev); + } else { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d\n", id, + mirror_shadow_stats[id].if_num); + } + + size_wr += nss_stats_fill_common_stats(mirror_shadow_stats[id].if_num, id, lbuf, size_wr, size_al, "mirror"); + + /* + * Mirror interface exception stats. + */ + size_wr += nss_stats_print("mirror", "mirror exception stats start", + id, + nss_mirror_stats_str, + mirror_shadow_stats[id].stats, + NSS_MIRROR_STATS_MAX, + lbuf, size_wr, size_al); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n"); + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr); + + vfree(mirror_shadow_stats); + vfree(lbuf); + return bytes_read; +} + +/* + * nss_mirror_stats_sync() + * API to sync statistics for mirror interface. + */ +void nss_mirror_stats_sync(struct nss_ctx_instance *nss_ctx, + struct nss_mirror_msg *nmm, uint16_t if_num) +{ + uint8_t i, j; + struct nss_top_instance *nss_top = nss_ctx->nss_top; + struct nss_mirror_stats_sync_msg *stats_msg = &nmm->msg.stats; + struct nss_cmn_node_stats *node_stats_ptr = &stats_msg->node_stats; + uint32_t *mirror_stats_ptr = (uint32_t *)&stats_msg->mirror_stats; + + spin_lock_bh(&nss_mirror_stats_debug_lock); + for (i = 0; i < NSS_MAX_MIRROR_DYNAMIC_INTERFACES; i++) { + if (!stats_db[i] || (stats_db[i]->if_num != if_num)) { + continue; + } + + for (j = 0; j < NSS_MIRROR_STATS_MAX; j++) { + /* + * Sync stats. + */ + stats_db[i]->stats[j] += mirror_stats_ptr[j]; + } + spin_unlock_bh(&nss_mirror_stats_debug_lock); + goto sync_cmn_stats; + } + + nss_warning("Invalid mirror stats sync message received for %d interface\n", if_num); + spin_unlock_bh(&nss_mirror_stats_debug_lock); + return; + +sync_cmn_stats: + spin_lock_bh(&nss_top->stats_lock); + + /* + * Sync common stats. + */ + nss_top->stats_node[if_num][NSS_STATS_NODE_RX_PKTS] += node_stats_ptr->rx_packets; + nss_top->stats_node[if_num][NSS_STATS_NODE_RX_BYTES] += node_stats_ptr->rx_bytes; + nss_top->stats_node[if_num][NSS_STATS_NODE_TX_PKTS] += node_stats_ptr->tx_packets; + nss_top->stats_node[if_num][NSS_STATS_NODE_TX_BYTES] += node_stats_ptr->tx_bytes; + + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + nss_top->stats_node[if_num][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + i] += + node_stats_ptr->rx_dropped[i]; + } + + spin_unlock_bh(&nss_top->stats_lock); +} + +/* + * nss_mirror_stats_reset() + * API to reset the mirror interface stats. + */ +void nss_mirror_stats_reset(uint32_t if_num) +{ + struct nss_mirror_stats_debug_instance *mirror_debug_instance = NULL; + uint8_t i; + + /* + * Reset common node stats. + */ + nss_stats_reset_common_stats(if_num); + + /* + * Reset mirror stats. + */ + spin_lock_bh(&nss_mirror_stats_debug_lock); + for (i = 0; i < NSS_MAX_MIRROR_DYNAMIC_INTERFACES; i++) { + if (!stats_db[i] || (stats_db[i]->if_num != if_num)) { + continue; + } + + mirror_debug_instance = stats_db[i]; + stats_db[i] = NULL; + break; + } + spin_unlock_bh(&nss_mirror_stats_debug_lock); + + if (mirror_debug_instance) { + vfree(mirror_debug_instance); + } +} + +/* + * nss_mirror_stats_init() + * API to initialize mirror debug instance statistics. + */ +int nss_mirror_stats_init(uint32_t if_num, struct net_device *netdev) +{ + struct nss_mirror_stats_debug_instance *mirror_debug_instance = NULL; + uint8_t i; + + mirror_debug_instance = + (struct nss_mirror_stats_debug_instance *)vzalloc(sizeof(struct nss_mirror_stats_debug_instance)); + if (!mirror_debug_instance) { + nss_warning("Memory alloc failed for mirror stats instance.\n"); + return -1; + } + + spin_lock_bh(&nss_mirror_stats_debug_lock); + for (i = 0; i < NSS_MAX_MIRROR_DYNAMIC_INTERFACES; i++) { + if (stats_db[i] != NULL) { + continue; + } + + stats_db[i] = mirror_debug_instance; + stats_db[i]->if_num = if_num; + stats_db[i]->if_index = netdev->ifindex; + spin_unlock_bh(&nss_mirror_stats_debug_lock); + return 0; + } + spin_unlock_bh(&nss_mirror_stats_debug_lock); + vfree(mirror_debug_instance); + return -1; +} + +/* + * nss_mirror_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(mirror) + +/* + * nss_mirror_stats_dentry_create() + * Create mirror interface statistics debug entry. + */ +void nss_mirror_stats_dentry_create(void) +{ + nss_stats_create_dentry("mirror", &nss_mirror_stats_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_mirror_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_mirror_stats.h new file mode 100644 index 000000000..477b31ca6 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_mirror_stats.h @@ -0,0 +1,76 @@ +/* + ****************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_MIRROR_STATS_H +#define __NSS_MIRROR_STATS_H + +/* + * Number of active mirror stats instances. + */ +extern atomic_t nss_mirror_num_instances; + +/* + * nss_mirror_stats + * Mirror interface debug statistics. + */ +enum nss_mirror_stats { + NSS_MIRROR_STATS_PKTS, /* Number of packets exceptioned to host. */ + NSS_MIRROR_STATS_BYTES, /* Number of bytes exceptioned to host. */ + NSS_MIRROR_STATS_TX_SEND_FAIL, /* Transmit send failures. */ + NSS_MIRROR_STATS_DEST_LOOKUP_FAIL, /* Destination lookup failures. */ + NSS_MIRROR_STATS_MEM_ALLOC_FAIL, /* Memory allocation failures. */ + NSS_MIRROR_STATS_COPY_FAIL, /* Copy failures. */ + NSS_MIRROR_STATS_MAX /* Maximum statistics count. */ +}; + +/* + * nss_mirror_stats_debug_instance + * Stucture for H2N/N2H mirror interface debug stats. + */ +struct nss_mirror_stats_debug_instance { + uint64_t stats[NSS_MIRROR_STATS_MAX]; /* Mirror statistics for each instance. */ + int32_t if_index; /* Mirror instance netdev index. */ + uint32_t if_num; /* Mirror instance NSS interface number */ +}; + +/* + * nss_mirror_stats_sync() + * API to sync statistics for mirror interface. + */ +extern void nss_mirror_stats_sync(struct nss_ctx_instance *nss_ctx, + struct nss_mirror_msg *nmm, uint16_t if_num); + +/* + * nss_mirror_stats_reset() + * API to reset the mirror interface stats. + */ +extern void nss_mirror_stats_reset(uint32_t if_num); + +/* + * nss_mirror_stats_init() + * API to initialize mirror debug instance statistics. + */ +extern int nss_mirror_stats_init(uint32_t if_num, struct net_device *netdev); + +/* + * nss_mirror_stats_dentry_create() + * Create mirror interface statistics debug entry. + */ +extern void nss_mirror_stats_dentry_create(void); + +#endif /* __NSS_MIRROR_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_n2h.c b/feeds/ipq807x/qca-nss-drv/src/nss_n2h.c new file mode 100644 index 000000000..ea5c2d04b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_n2h.c @@ -0,0 +1,2250 @@ +/* + ************************************************************************** + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_n2h.c + * NSS N2H node APIs + */ + +#include "nss_tx_rx_common.h" +#include "nss_n2h_stats.h" +#include "nss_n2h_strings.h" +#include "nss_drv_strings.h" + +#define NSS_N2H_MAX_BUF_POOL_SIZE (1024 * 1024 * 20) /* 20MB */ +#define NSS_N2H_MIN_EMPTY_POOL_BUF_SZ 32 +#define NSS_N2H_MAX_EMPTY_POOL_BUF_SZ 131072 +#define NSS_N2H_DEFAULT_EMPTY_POOL_BUF_SZ 8192 +#define NSS_N2H_TX_TIMEOUT 3000 /* 3 Seconds */ + +int nss_n2h_empty_pool_buf_cfg[NSS_MAX_CORES] __read_mostly = {-1, -1}; +int nss_n2h_empty_paged_pool_buf_cfg[NSS_MAX_CORES] __read_mostly = {-1, -1}; +int nss_n2h_water_mark[NSS_MAX_CORES][2] __read_mostly = {{-1, -1}, {-1, -1} }; +int nss_n2h_paged_water_mark[NSS_MAX_CORES][2] __read_mostly = {{-1, -1}, {-1, -1} }; +int nss_n2h_wifi_pool_buf_cfg __read_mostly = -1; +int nss_n2h_core0_mitigation_cfg __read_mostly = 1; +int nss_n2h_core1_mitigation_cfg __read_mostly = 1; +int nss_n2h_core0_add_buf_pool_size __read_mostly; +int nss_n2h_core1_add_buf_pool_size __read_mostly; +int nss_n2h_queue_limit[NSS_MAX_CORES] __read_mostly = {NSS_DEFAULT_QUEUE_LIMIT, NSS_DEFAULT_QUEUE_LIMIT}; +int nss_n2h_host_bp_config[NSS_MAX_CORES] __read_mostly; + +struct nss_n2h_registered_data { + nss_n2h_msg_callback_t n2h_callback; + void *app_data; +}; + +static struct nss_n2h_cfg_pvt nss_n2h_nepbcfgp[NSS_MAX_CORES]; +static struct nss_n2h_registered_data nss_n2h_rd[NSS_MAX_CORES]; +static struct nss_n2h_cfg_pvt nss_n2h_rcp; +static struct nss_n2h_cfg_pvt nss_n2h_mitigationcp[NSS_CORE_MAX]; +static struct nss_n2h_cfg_pvt nss_n2h_bufcp[NSS_CORE_MAX]; +static struct nss_n2h_cfg_pvt nss_n2h_wp; +static struct nss_n2h_cfg_pvt nss_n2h_q_cfg_pvt; +static struct nss_n2h_cfg_pvt nss_n2h_q_lim_pvt; +static struct nss_n2h_cfg_pvt nss_n2h_host_bp_cfg_pvt; + +/* + * nss_n2h_interface_handler() + * Handle NSS -> HLOS messages for N2H node + */ +static void nss_n2h_interface_handler(struct nss_ctx_instance *nss_ctx, + struct nss_cmn_msg *ncm, + void *app_data) +{ + struct nss_n2h_msg *nnm = (struct nss_n2h_msg *)ncm; + nss_n2h_msg_callback_t cb; + + BUG_ON(ncm->interface != NSS_N2H_INTERFACE); + + /* + * Is this a valid request/response packet? + */ + if (nnm->cm.type >= NSS_METADATA_TYPE_N2H_MAX) { + nss_warning("%px: received invalid message %d for Offload stats interface", nss_ctx, nnm->cm.type); + return; + } + + switch (nnm->cm.type) { + case NSS_TX_METADATA_TYPE_N2H_RPS_CFG: + nss_info("NSS N2H rps_en %d \n",nnm->msg.rps_cfg.enable); + break; + + case NSS_TX_METADATA_TYPE_N2H_MITIGATION_CFG: + nss_info("NSS N2H mitigation_dis %d \n",nnm->msg.mitigation_cfg.enable); + break; + + case NSS_TX_METADATA_TYPE_N2H_EMPTY_POOL_BUF_CFG: + nss_info("%px: empty pool buf cfg response from FW", nss_ctx); + break; + + case NSS_TX_METADATA_TYPE_N2H_FLUSH_PAYLOADS: + nss_info("%px: flush payloads cmd response from FW", nss_ctx); + break; + + case NSS_RX_METADATA_TYPE_N2H_STATS_SYNC: + /* + * Update driver statistics and send statistics notifications to the registered modules. + */ + nss_n2h_stats_sync(nss_ctx, &nnm->msg.stats_sync); + nss_n2h_stats_notify(nss_ctx); + break; + + default: + if (ncm->response != NSS_CMN_RESPONSE_ACK) { + /* + * Check response + */ + nss_info("%px: Received response %d for type %d, interface %d", + nss_ctx, ncm->response, ncm->type, ncm->interface); + } + } + + /* + * Update the callback and app_data for NOTIFY messages, n2h sends all notify messages + * to the same callback/app_data. + */ + if (nnm->cm.response == NSS_CMN_RESPONSE_NOTIFY) { + /* + * Place holder for the user to create right call + * back and app data when response is NSS_CMN_RESPONSE_NOTIFY + */ + ncm->cb = (nss_ptr_t)nss_n2h_rd[nss_ctx->id].n2h_callback; + ncm->app_data = (nss_ptr_t)nss_n2h_rd[nss_ctx->id].app_data; + } + + /* + * Do we have a callback? + */ + if (!ncm->cb) { + return; + } + + /* + * Callback + */ + cb = (nss_n2h_msg_callback_t)ncm->cb; + cb((void *)ncm->app_data, nnm); +} + +/* + * nss_n2h_mitigation_cfg_callback() + * call back function for mitigation configuration + */ +static void nss_n2h_mitigation_cfg_callback(void *app_data, struct nss_n2h_msg *nnm) +{ + uint32_t core_num = (uint32_t)(nss_ptr_t)app_data; + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num]; + + if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) { + + /* + * Error, hence we are not updating the nss_n2h_mitigate_en + */ + nss_n2h_mitigationcp[core_num].response = NSS_FAILURE; + complete(&nss_n2h_mitigationcp[core_num].complete); + nss_warning("core%d: MITIGATION configuration failed : %d\n", core_num, nnm->cm.error); + return; + } + + nss_info("core%d: MITIGATION configuration succeeded: %d\n", core_num, nnm->cm.error); + + nss_ctx->n2h_mitigate_en = nnm->msg.mitigation_cfg.enable; + nss_n2h_mitigationcp[core_num].response = NSS_SUCCESS; + complete(&nss_n2h_mitigationcp[core_num].complete); +} + +/* + * nss_n2h_buf_cfg_callback() + * call back function for pbuf configuration + */ +static void nss_n2h_bufs_cfg_callback(void *app_data, struct nss_n2h_msg *nnm) +{ + uint32_t core_num = (uint32_t)(nss_ptr_t)app_data; + unsigned int allocated_sz; + + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num]; + + if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_n2h_bufcp[core_num].response = NSS_FAILURE; + nss_warning("core%d: buf configuration failed : %d\n", core_num, nnm->cm.error); + goto done; + } + + nss_info("core%d: buf configuration succeeded: %d\n", core_num, nnm->cm.error); + + allocated_sz = nnm->msg.buf_pool.nss_buf_page_size * nnm->msg.buf_pool.nss_buf_num_pages; + nss_ctx->buf_sz_allocated += allocated_sz; + + nss_n2h_bufcp[core_num].response = NSS_SUCCESS; + +done: + complete(&nss_n2h_bufcp[core_num].complete); +} + +/* + * nss_n2h_payload_stats_callback() + * It gets called response to payload accounting. + */ +static void nss_n2h_payload_stats_callback(void *app_data, + struct nss_n2h_msg *nnm) +{ + uint32_t core_num = (uint32_t)(nss_ptr_t)app_data; + + if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) { + struct nss_n2h_empty_pool_buf *nnepbcm; + nnepbcm = &nnm->msg.empty_pool_buf_cfg; + + nss_warning("%d: core empty pool buf set failure: %d\n", + core_num, nnm->cm.error); + nss_n2h_nepbcfgp[core_num].response = NSS_FAILURE; + complete(&nss_n2h_nepbcfgp[core_num].complete); + return; + } + + if (nnm->cm.type == NSS_TX_METADATA_TYPE_GET_WATER_MARK) { + nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.pool_size = + ntohl(nnm->msg.payload_info.pool_size); + nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.low_water = + ntohl(nnm->msg.payload_info.low_water); + nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.high_water = + ntohl(nnm->msg.payload_info.high_water); + } + + if (nnm->cm.type == NSS_TX_METADATA_TYPE_GET_PAGED_WATER_MARK) { + nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.pool_size = + ntohl(nnm->msg.paged_payload_info.pool_size); + nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.low_water = + ntohl(nnm->msg.paged_payload_info.low_water); + nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.high_water = + ntohl(nnm->msg.paged_payload_info.high_water); + } + + nss_n2h_nepbcfgp[core_num].response = NSS_SUCCESS; + complete(&nss_n2h_nepbcfgp[core_num].complete); +} + +/* + * nss_n2h_set_wifi_payloads_callback() + * call back function for response to wifi pool configuration + * + */ +static void nss_n2h_set_wifi_payloads_callback(void *app_data, + struct nss_n2h_msg *nnm) +{ + struct nss_ctx_instance *nss_ctx __maybe_unused = (struct nss_ctx_instance *)app_data; + if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) { + + nss_n2h_wp.response = NSS_FAILURE; + complete(&nss_n2h_wp.complete); + nss_warning("%px: wifi pool configuration failed : %d\n", nss_ctx, + nnm->cm.error); + return; + } + + nss_info("%px: wifi payload configuration succeeded: %d\n", nss_ctx, + nnm->cm.error); + nss_n2h_wp.response = NSS_SUCCESS; + nss_n2h_wp.wifi_pool = ntohl(nnm->msg.wp.payloads); + complete(&nss_n2h_wp.complete); +} + +/* + * nss_n2h_get_payload_info() + * Gets Payload information. + */ +static int nss_n2h_get_payload_info(nss_ptr_t core_num, struct nss_n2h_msg *nnm, struct nss_n2h_payload_info *nnepbcm) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num]; + nss_tx_status_t nss_tx_status; + int ret = NSS_FAILURE; + + /* + * Note that semaphore should be already held. + */ + + nss_tx_status = nss_n2h_tx_msg(nss_ctx, nnm); + + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: core %d nss_tx error errorn", nss_ctx, (int)core_num); + return NSS_FAILURE; + } + + /* + * Blocking call, wait till we get ACK for this msg. + */ + ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete, + msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT)); + if (ret == 0) { + nss_warning("%px: core %d waiting for ack timed out\n", nss_ctx, (int)core_num); + return NSS_FAILURE; + } + + if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response) { + nss_warning("%px: core %d response returned failure\n", nss_ctx, (int)core_num); + return NSS_FAILURE; + } + + return NSS_SUCCESS; +} + +/* + * nss_n2h_get_default_payload_info() + * Gets the default payload information. + */ +static int nss_n2h_get_default_payload_info(nss_ptr_t core_num) +{ + struct nss_n2h_msg nnm; + + nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, + NSS_TX_METADATA_TYPE_GET_WATER_MARK, + sizeof(struct nss_n2h_payload_info), + nss_n2h_payload_stats_callback, + (void *)core_num); + + return nss_n2h_get_payload_info(core_num, &nnm, + &nnm.msg.payload_info); +} + +/* + * nss_n2h_get_paged_payload_info() + * Gets the paged payload information. + */ +static int nss_n2h_get_paged_payload_info(nss_ptr_t core_num) +{ + struct nss_n2h_msg nnm; + + nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, + NSS_TX_METADATA_TYPE_GET_PAGED_WATER_MARK, + sizeof(struct nss_n2h_payload_info), + nss_n2h_payload_stats_callback, + (void *)core_num); + + return nss_n2h_get_payload_info(core_num, &nnm, + &nnm.msg.paged_payload_info); +} + +/* + * nss_n2h_set_empty_buf_pool() + * Sets empty pool buffer + */ +static int nss_n2h_set_empty_buf_pool(struct ctl_table *ctl, int write, + void __user *buffer, + size_t *lenp, loff_t *ppos, + nss_ptr_t core_num, int *new_val) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num]; + struct nss_n2h_msg nnm; + struct nss_n2h_empty_pool_buf *nnepbcm; + nss_tx_status_t nss_tx_status; + int ret = NSS_FAILURE; + + /* + * Acquiring semaphore + */ + down(&nss_n2h_nepbcfgp[core_num].sem); + + /* + * Take snap shot of current value + */ + nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.pool_size = *new_val; + + if (!write) { + ret = nss_n2h_get_default_payload_info(core_num); + *new_val = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.pool_size; + if (ret == NSS_FAILURE) { + up(&nss_n2h_nepbcfgp[core_num].sem); + return -EBUSY; + } + + up(&nss_n2h_nepbcfgp[core_num].sem); + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + return ret; + } + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + if (ret) { + up(&nss_n2h_nepbcfgp[core_num].sem); + return ret; + } + + if ((*new_val < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) { + nss_warning("%px: core %d setting %d < min number of buffer", + nss_ctx, (int)core_num, *new_val); + goto failure; + } + + nss_info("%px: core %d number of empty pool buffer is : %d\n", + nss_ctx, (int)core_num, *new_val); + + nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, + NSS_TX_METADATA_TYPE_N2H_EMPTY_POOL_BUF_CFG, + sizeof(struct nss_n2h_empty_pool_buf), + nss_n2h_payload_stats_callback, + (nss_ptr_t *)core_num); + + nnepbcm = &nnm.msg.empty_pool_buf_cfg; + nnepbcm->pool_size = htonl(*new_val); + nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm); + + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: core %d nss_tx error empty pool buffer: %d\n", + nss_ctx, (int)core_num, *new_val); + goto failure; + } + + /* + * Blocking call, wait till we get ACK for this msg. + */ + ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete, + msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT)); + if (ret == 0) { + nss_warning("%px: core %d Waiting for ack timed out\n", nss_ctx, (int)core_num); + goto failure; + } + + /* + * ACK/NACK received from NSS FW + * If ACK: Callback function will update nss_n2h_empty_pool_buf with + * nss_n2h_nepbcfgp.num_conn_valid, which holds the user input + */ + if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response) { + goto failure; + } + + up(&nss_n2h_nepbcfgp[core_num].sem); + return 0; + +failure: + /* + * Restore the current_value to its previous state + */ + *new_val = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.pool_size; + up(&nss_n2h_nepbcfgp[core_num].sem); + return NSS_FAILURE; +} + +/* + * nss_n2h_set_empty_paged_pool_buf() + * Sets empty paged pool buffer + */ +static int nss_n2h_set_empty_paged_pool_buf(struct ctl_table *ctl, int write, + void __user *buffer, + size_t *lenp, loff_t *ppos, + nss_ptr_t core_num, int *new_val) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num]; + struct nss_n2h_msg nnm; + struct nss_n2h_empty_pool_buf *nneppbcm; + nss_tx_status_t nss_tx_status; + int ret = NSS_FAILURE; + + /* + * Acquiring semaphore + */ + down(&nss_n2h_nepbcfgp[core_num].sem); + + /* + * Take snap shot of current value + */ + nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.pool_size = *new_val; + + if (!write) { + ret = nss_n2h_get_paged_payload_info(core_num); + *new_val = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.pool_size; + if (ret == NSS_FAILURE) { + up(&nss_n2h_nepbcfgp[core_num].sem); + return -EBUSY; + } + + up(&nss_n2h_nepbcfgp[core_num].sem); + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + return ret; + } + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + if (ret) { + up(&nss_n2h_nepbcfgp[core_num].sem); + return ret; + } + + if ((*new_val < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) { + nss_warning("%px: core %d setting %d < min number of buffer", + nss_ctx, (int)core_num, *new_val); + goto failure; + } + + nss_info("%px: core %d number of empty paged pool buffer is : %d\n", + nss_ctx, (int)core_num, *new_val); + + nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, + NSS_TX_METADATA_TYPE_N2H_EMPTY_PAGED_POOL_BUF_CFG, + sizeof(struct nss_n2h_empty_pool_buf), + nss_n2h_payload_stats_callback, + (nss_ptr_t *)core_num); + + nneppbcm = &nnm.msg.empty_pool_buf_cfg; + nneppbcm->pool_size = htonl(*new_val); + nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm); + + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: core %d nss_tx error empty paged pool buffer: %d\n", + nss_ctx, (int)core_num, *new_val); + goto failure; + } + + /* + * Blocking call, wait till we get ACK for this msg. + */ + ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete, + msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT)); + if (ret == 0) { + nss_warning("%px: core %d Waiting for ack timed out\n", nss_ctx, (int)core_num); + goto failure; + } + + /* + * ACK/NACK received from NSS FW + * If ACK: Callback function will update nss_n2h_empty_pool_buf with + * nss_n2h_nepbcfgp.num_conn_valid, which holds the user input + */ + if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response) { + goto failure; + } + + up(&nss_n2h_nepbcfgp[core_num].sem); + return 0; + +failure: + /* + * Restore the current_value to its previous state + */ + *new_val = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.pool_size; + up(&nss_n2h_nepbcfgp[core_num].sem); + return NSS_FAILURE; +} + +/* + * nss_n2h_set_water_mark() + * Sets water mark for N2H SOS + */ +static int nss_n2h_set_water_mark(struct ctl_table *ctl, int write, + void __user *buffer, + size_t *lenp, loff_t *ppos, + uint32_t core_num, int *low, int *high) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num]; + struct nss_n2h_msg nnm; + struct nss_n2h_water_mark *wm; + nss_tx_status_t nss_tx_status; + int ret = NSS_FAILURE; + + /* + * Acquiring semaphore + */ + down(&nss_n2h_nepbcfgp[core_num].sem); + + /* + * Take snap shot of current value + */ + nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.low_water = *low; + nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.high_water = *high; + + if (!write || *low == -1 || *high == -1) { + ret = nss_n2h_get_default_payload_info(core_num); + if (ret == NSS_FAILURE) { + up(&nss_n2h_nepbcfgp[core_num].sem); + return -EBUSY; + } + + *low = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.low_water; + *high = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.high_water; + } + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + if (!write || ret) { + up(&nss_n2h_nepbcfgp[core_num].sem); + return ret; + } + + if ((*low < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ) || + (*high < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) { + nss_warning("%px: core %d setting %d, %d < min number of buffer", + nss_ctx, core_num, *low, *high); + goto failure; + } + + if ((*low > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ) || + (*high > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ)) { + nss_warning("%px: core %d setting %d, %d is > upper limit", + nss_ctx, core_num, *low, *high); + goto failure; + } + + if (*low > *high) { + nss_warning("%px: core %d setting low %d is more than high %d", + nss_ctx, core_num, *low, *high); + goto failure; + } + + nss_info("%px: core %d number of low : %d and high : %d\n", + nss_ctx, core_num, *low, *high); + + nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, + NSS_TX_METADATA_TYPE_SET_WATER_MARK, + sizeof(struct nss_n2h_water_mark), + nss_n2h_payload_stats_callback, + (void *)(nss_ptr_t)core_num); + + wm = &nnm.msg.wm; + wm->low_water = htonl(*low); + wm->high_water = htonl(*high); + nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm); + + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: core %d nss_tx error setting : %d, %d\n", + nss_ctx, core_num, *low, *high); + goto failure; + } + + /* + * Blocking call, wait till we get ACK for this msg. + */ + ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete, + msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT)); + if (ret == 0) { + nss_warning("%px: core %d Waiting for ack timed out\n", nss_ctx, + core_num); + goto failure; + } + + /* + * ACK/NACK received from NSS FW + */ + if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response) + goto failure; + + up(&nss_n2h_nepbcfgp[core_num].sem); + return NSS_SUCCESS; + +failure: + /* + * Restore the current_value to its previous state + */ + *low = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.low_water; + *high = nss_n2h_nepbcfgp[core_num].empty_buf_pool_info.high_water; + up(&nss_n2h_nepbcfgp[core_num].sem); + return -EINVAL; +} + +/* + * nss_n2h_set_paged_water_mark() + * Sets water mark for paged pool N2H SOS + */ +static int nss_n2h_set_paged_water_mark(struct ctl_table *ctl, int write, + void __user *buffer, + size_t *lenp, loff_t *ppos, + uint32_t core_num, int *low, int *high) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_num]; + struct nss_n2h_msg nnm; + struct nss_n2h_water_mark *pwm; + nss_tx_status_t nss_tx_status; + int ret = NSS_FAILURE; + + /* + * Acquiring semaphore + */ + down(&nss_n2h_nepbcfgp[core_num].sem); + + /* + * Take snap shot of current value + */ + nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.low_water = *low; + nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.high_water = *high; + + if (!write || *low == -1 || *high == -1) { + ret = nss_n2h_get_paged_payload_info(core_num); + if (ret == NSS_FAILURE) { + up(&nss_n2h_nepbcfgp[core_num].sem); + return -EBUSY; + } + + *low = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.low_water; + *high = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.high_water; + } + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + if (!write || ret) { + up(&nss_n2h_nepbcfgp[core_num].sem); + return ret; + } + + if ((*low < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ) || + (*high < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) { + nss_warning("%px: core %d setting %d, %d < min number of buffer", + nss_ctx, core_num, *low, *high); + goto failure; + } + + if ((*low > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ) || + (*high > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ)) { + nss_warning("%px: core %d setting %d, %d is > upper limit", + nss_ctx, core_num, *low, *high); + goto failure; + } + + if (*low > *high) { + nss_warning("%px: core %d setting low %d is more than high %d", + nss_ctx, core_num, *low, *high); + goto failure; + } + + nss_info("%px: core %d number of low : %d and high : %d\n", + nss_ctx, core_num, *low, *high); + + nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, + NSS_TX_METADATA_TYPE_SET_PAGED_WATER_MARK, + sizeof(struct nss_n2h_water_mark), + nss_n2h_payload_stats_callback, + (void *)(nss_ptr_t)core_num); + + pwm = &nnm.msg.wm_paged; + pwm->low_water = htonl(*low); + pwm->high_water = htonl(*high); + nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm); + + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: core %d nss_tx error setting : %d, %d\n", + nss_ctx, core_num, *low, *high); + goto failure; + } + + /* + * Blocking call, wait till we get ACK for this msg. + */ + ret = wait_for_completion_timeout(&nss_n2h_nepbcfgp[core_num].complete, + msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT)); + if (ret == 0) { + nss_warning("%px: core %d Waiting for ack timed out\n", nss_ctx, + core_num); + goto failure; + } + + /* + * ACK/NACK received from NSS FW + */ + if (NSS_FAILURE == nss_n2h_nepbcfgp[core_num].response) + goto failure; + + up(&nss_n2h_nepbcfgp[core_num].sem); + return NSS_SUCCESS; + +failure: + /* + * Restore the current_value to its previous state + */ + *low = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.low_water; + *high = nss_n2h_nepbcfgp[core_num].empty_paged_buf_pool_info.high_water; + up(&nss_n2h_nepbcfgp[core_num].sem); + return -EINVAL; +} + +/* + * nss_n2h_cfg_wifi_pool() + * Sets number of wifi payloads to adjust high water mark for N2H SoS + */ +static int nss_n2h_cfg_wifi_pool(struct ctl_table *ctl, int write, + void __user *buffer, + size_t *lenp, loff_t *ppos, + int *payloads) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[0]; + struct nss_n2h_msg nnm; + struct nss_n2h_wifi_payloads *wp; + nss_tx_status_t nss_tx_status; + int ret = NSS_FAILURE; + + /* + * Acquiring semaphore + */ + down(&nss_n2h_wp.sem); + + if (!write) { + *payloads = nss_n2h_wp.wifi_pool; + + up(&nss_n2h_wp.sem); + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + return ret; + } + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + if (ret) { + up(&nss_n2h_wp.sem); + return ret; + } + + /* + * If payloads parameter is not set, we do + * nothing. + */ + if (*payloads == -1) + goto failure; + + if ((*payloads < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ)) { + nss_warning("%px: wifi setting %d < min number of buffer", + nss_ctx, *payloads); + goto failure; + } + + if ((*payloads > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ)) { + nss_warning("%px: wifi setting %d > max number of buffer", + nss_ctx, *payloads); + goto failure; + } + + nss_info("%px: wifi payloads : %d\n", + nss_ctx, *payloads); + + nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, + NSS_TX_METADATA_TYPE_N2H_WIFI_POOL_BUF_CFG, + sizeof(struct nss_n2h_wifi_payloads), + nss_n2h_set_wifi_payloads_callback, + (void *)nss_ctx); + + wp = &nnm.msg.wp; + wp->payloads = htonl(*payloads); + nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm); + + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: wifi setting %d nss_tx error", + nss_ctx, *payloads); + goto failure; + } + + /* + * Blocking call, wait till we get ACK for this msg. + */ + ret = wait_for_completion_timeout(&nss_n2h_wp.complete, + msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT)); + if (ret == 0) { + nss_warning("%px: Waiting for ack timed out\n", nss_ctx); + goto failure; + } + + /* + * ACK/NACK received from NSS FW + */ + if (NSS_FAILURE == nss_n2h_wp.response) + goto failure; + + up(&nss_n2h_wp.sem); + return NSS_SUCCESS; + +failure: + up(&nss_n2h_wp.sem); + return -EINVAL; +} + +/* + * nss_n2h_empty_pool_buf_core1_handler() + * Sets the number of empty buffer for core 1 + */ +static int nss_n2h_empty_pool_buf_cfg_core1_handler(struct ctl_table *ctl, + int write, void __user *buffer, + size_t *lenp, loff_t *ppos) +{ + return nss_n2h_set_empty_buf_pool(ctl, write, buffer, lenp, ppos, + NSS_CORE_1, &nss_n2h_empty_pool_buf_cfg[NSS_CORE_1]); +} + +/* + * nss_n2h_empty_pool_buf_core0_handler() + * Sets the number of empty buffer for core 0 + */ +static int nss_n2h_empty_pool_buf_cfg_core0_handler(struct ctl_table *ctl, + int write, void __user *buffer, + size_t *lenp, loff_t *ppos) +{ + return nss_n2h_set_empty_buf_pool(ctl, write, buffer, lenp, ppos, + NSS_CORE_0, &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0]); +} + +/* + * nss_n2h_empty_paged_pool_buf_cfg_core1_handler() + * Sets the number of empty paged buffer for core 1 + */ +static int nss_n2h_empty_paged_pool_buf_cfg_core1_handler(struct ctl_table *ctl, + int write, void __user *buffer, + size_t *lenp, loff_t *ppos) +{ + return nss_n2h_set_empty_paged_pool_buf(ctl, write, buffer, lenp, ppos, + NSS_CORE_1, &nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_1]); +} + +/* + * nss_n2h_empty_paged_pool_buf_cfg_core0_handler() + * Sets the number of empty paged buffer for core 0 + */ +static int nss_n2h_empty_paged_pool_buf_cfg_core0_handler(struct ctl_table *ctl, + int write, void __user *buffer, + size_t *lenp, loff_t *ppos) +{ + return nss_n2h_set_empty_paged_pool_buf(ctl, write, buffer, lenp, ppos, + NSS_CORE_0, &nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_0]); +} + +/* + * nss_n2h_water_mark_core1_handler() + * Sets water mark for core 1 + */ +static int nss_n2h_water_mark_core1_handler(struct ctl_table *ctl, + int write, void __user *buffer, + size_t *lenp, loff_t *ppos) +{ + return nss_n2h_set_water_mark(ctl, write, buffer, lenp, ppos, + NSS_CORE_1, &nss_n2h_water_mark[NSS_CORE_1][0], + &nss_n2h_water_mark[NSS_CORE_1][1]); +} + +/* + * nss_n2h_water_mark_core0_handler() + * Sets water mark for core 0 + */ +static int nss_n2h_water_mark_core0_handler(struct ctl_table *ctl, + int write, void __user *buffer, + size_t *lenp, loff_t *ppos) +{ + return nss_n2h_set_water_mark(ctl, write, buffer, lenp, ppos, + NSS_CORE_0, &nss_n2h_water_mark[NSS_CORE_0][0], + &nss_n2h_water_mark[NSS_CORE_0][1]); +} + +/* + * nss_n2h_paged_water_mark_core1_handler() + * Sets paged water mark for core 1 + */ +static int nss_n2h_paged_water_mark_core1_handler(struct ctl_table *ctl, + int write, void __user *buffer, + size_t *lenp, loff_t *ppos) +{ + return nss_n2h_set_paged_water_mark(ctl, write, buffer, lenp, ppos, + NSS_CORE_1, &nss_n2h_paged_water_mark[NSS_CORE_1][0], + &nss_n2h_paged_water_mark[NSS_CORE_1][1]); +} + +/* + * nss_n2h_paged_water_mark_core0_handler() + * Sets paged water mark for core 0 + */ +static int nss_n2h_paged_water_mark_core0_handler(struct ctl_table *ctl, + int write, void __user *buffer, + size_t *lenp, loff_t *ppos) +{ + return nss_n2h_set_paged_water_mark(ctl, write, buffer, lenp, ppos, + NSS_CORE_0, &nss_n2h_paged_water_mark[NSS_CORE_0][0], + &nss_n2h_paged_water_mark[NSS_CORE_0][1]); +} + +/* + * nss_n2h_wifi_payloads_handler() + * Sets number of wifi payloads + */ +static int nss_n2h_wifi_payloads_handler(struct ctl_table *ctl, + int write, void __user *buffer, + size_t *lenp, loff_t *ppos) +{ + return nss_n2h_cfg_wifi_pool(ctl, write, buffer, lenp, ppos, + &nss_n2h_wifi_pool_buf_cfg); +} + +/* + * nss_n2h_update_queue_config_callback() + * Callback to handle the completion of queue config command + */ +static void nss_n2h_update_queue_config_callback(void *app_data, struct nss_n2h_msg *nim) +{ + if (nim->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("n2h Error response %d\n", nim->cm.response); + nss_n2h_q_cfg_pvt.response = NSS_TX_FAILURE; + } else { + nss_n2h_q_cfg_pvt.response = NSS_TX_SUCCESS; + } + + complete(&nss_n2h_q_cfg_pvt.complete); +} + +/* + * nss_n2h_update_queue_config_async() + * Asynchronous call to send pnode queue configuration. + */ +nss_tx_status_t nss_n2h_update_queue_config_async(struct nss_ctx_instance *nss_ctx, bool mq_en, uint16_t *qlimits) +{ + + struct nss_n2h_msg nnm; + struct nss_n2h_pnode_queue_config *cfg; + nss_tx_status_t status; + int i; + + if (!mq_en) { + return NSS_TX_SUCCESS; + } + + /* + * MQ mode doesnot make any sense if number of priority queues in NSS + * is 1 + */ + if (NSS_MAX_NUM_PRI <= 1) { + return NSS_TX_SUCCESS; + } + + memset(&nnm, 0, sizeof(struct nss_n2h_msg)); + + nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, + NSS_TX_METADATA_TYPE_N2H_SET_PNODE_QUEUE_CFG, + sizeof(struct nss_n2h_pnode_queue_config), NULL, 0); + + cfg = &nnm.msg.pn_q_cfg; + + /* + * Update limits + */ + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + cfg->qlimits[i] = qlimits[i]; + } + cfg->mq_en = true; + + status = nss_n2h_tx_msg(nss_ctx, &nnm); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: nss_tx error to send pnode queue config\n", nss_ctx); + return status; + } + + return NSS_TX_SUCCESS; +} +EXPORT_SYMBOL(nss_n2h_update_queue_config_async); + +/* + * nss_n2h_update_queue_config_sync() + * Synchronous call to send pnode queue configuration. + */ +nss_tx_status_t nss_n2h_update_queue_config_sync(struct nss_ctx_instance *nss_ctx, bool mq_en, uint16_t *qlimits) +{ + + struct nss_n2h_msg nnm; + struct nss_n2h_pnode_queue_config *cfg; + nss_tx_status_t status; + int ret, i; + + if (!mq_en) { + return NSS_TX_SUCCESS; + } + + /* + * MQ mode doesnot make any sense if number of priority queues in NSS + * is 1 + */ + if (NSS_MAX_NUM_PRI <= 1) { + return NSS_TX_SUCCESS; + } + + memset(&nnm, 0, sizeof(struct nss_n2h_msg)); + + nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, + NSS_TX_METADATA_TYPE_N2H_SET_PNODE_QUEUE_CFG, + sizeof(struct nss_n2h_pnode_queue_config), nss_n2h_update_queue_config_callback, 0); + + cfg = &nnm.msg.pn_q_cfg; + + /* + * Update limits + */ + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + cfg->qlimits[i] = qlimits[i]; + } + cfg->mq_en = true; + + down(&nss_n2h_q_cfg_pvt.sem); + + status = nss_n2h_tx_msg(nss_ctx, &nnm); + + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: n2h_tx_msg failed\n", nss_ctx); + up(&nss_n2h_q_cfg_pvt.sem); + return status; + } + ret = wait_for_completion_timeout(&nss_n2h_q_cfg_pvt.complete, msecs_to_jiffies(NSS_N2H_TX_TIMEOUT)); + + if (!ret) { + nss_warning("%px: Timeout expired for pnode queue config sync message\n", nss_ctx); + nss_n2h_q_cfg_pvt.response = NSS_TX_FAILURE; + } + + status = nss_n2h_q_cfg_pvt.response; + up(&nss_n2h_q_cfg_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_n2h_update_queue_config_sync); + +/* + * nss_n2h_mitigation_cfg() + * Send Message to NSS to disable MITIGATION. + */ +static nss_tx_status_t nss_n2h_mitigation_cfg(struct nss_ctx_instance *nss_ctx, int enable_mitigation, nss_core_id_t core_num) +{ + struct nss_n2h_msg nnm; + struct nss_n2h_mitigation *mitigation_cfg; + nss_tx_status_t nss_tx_status; + int ret; + + nss_assert(core_num < NSS_CORE_MAX); + + down(&nss_n2h_mitigationcp[core_num].sem); + nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_TX_METADATA_TYPE_N2H_MITIGATION_CFG, + sizeof(struct nss_n2h_mitigation), + nss_n2h_mitigation_cfg_callback, + (void *)core_num); + + mitigation_cfg = &nnm.msg.mitigation_cfg; + mitigation_cfg->enable = enable_mitigation; + + nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm); + + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: nss_tx error setting mitigation\n", nss_ctx); + goto failure; + } + + /* + * Blocking call, wait till we get ACK for this msg. + */ + ret = wait_for_completion_timeout(&nss_n2h_mitigationcp[core_num].complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT)); + if (ret == 0) { + nss_warning("%px: Waiting for ack timed out\n", nss_ctx); + goto failure; + } + + /* + * ACK/NACK received from NSS FW + */ + if (NSS_FAILURE == nss_n2h_mitigationcp[core_num].response) { + goto failure; + } + + up(&nss_n2h_mitigationcp[core_num].sem); + return NSS_SUCCESS; + +failure: + up(&nss_n2h_mitigationcp[core_num].sem); + return NSS_FAILURE; +} + +static inline void nss_n2h_buf_pool_free(struct nss_n2h_buf_pool *buf_pool) +{ + int page_count; + for (page_count = 0; page_count < buf_pool->nss_buf_num_pages; page_count++) { + kfree((void *)buf_pool->nss_buf_pool_vaddr[page_count]); + } +} + +/* + * nss_n2h_buf_cfg() + * Send Message to NSS to enable pbufs. + */ +static nss_tx_status_t nss_n2h_buf_pool_cfg(struct nss_ctx_instance *nss_ctx, + int buf_pool_size, nss_core_id_t core_num) +{ + static struct nss_n2h_msg nnm; + struct nss_n2h_buf_pool *buf_pool; + nss_tx_status_t nss_tx_status; + int ret; + int page_count; + int num_pages = ALIGN(buf_pool_size, PAGE_SIZE)/PAGE_SIZE; + + nss_assert(core_num < NSS_CORE_MAX); + + nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_METADATA_TYPE_N2H_ADD_BUF_POOL, + sizeof(struct nss_n2h_buf_pool), + nss_n2h_bufs_cfg_callback, + (void *)core_num); + + do { + + down(&nss_n2h_bufcp[core_num].sem); + + buf_pool = &nnm.msg.buf_pool; + buf_pool->nss_buf_page_size = PAGE_SIZE; + + for (page_count = 0; page_count < MAX_PAGES_PER_MSG && num_pages; page_count++, num_pages--) { + void *kern_addr = kzalloc(PAGE_SIZE, GFP_ATOMIC); + if (!kern_addr) { + BUG_ON(!page_count); + break; + } + + kmemleak_not_leak(kern_addr); + buf_pool->nss_buf_pool_vaddr[page_count] = (nss_ptr_t)kern_addr; + buf_pool->nss_buf_pool_addr[page_count] = dma_map_single(nss_ctx->dev, kern_addr, PAGE_SIZE, DMA_TO_DEVICE); + } + + buf_pool->nss_buf_num_pages = page_count; + nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm); + if (nss_tx_status != NSS_TX_SUCCESS) { + + nss_n2h_buf_pool_free(buf_pool); + nss_warning("%px: nss_tx error setting pbuf\n", nss_ctx); + goto failure; + } + + /* + * Blocking call, wait till we get ACK for this msg. + */ + ret = wait_for_completion_timeout(&nss_n2h_bufcp[core_num].complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT)); + if (ret == 0) { + nss_warning("%px: Waiting for ack timed out\n", nss_ctx); + goto failure; + } + + /* + * ACK/NACK received from NSS FW + */ + if (NSS_FAILURE == nss_n2h_bufcp[core_num].response) { + + nss_n2h_buf_pool_free(buf_pool); + goto failure; + } + + up(&nss_n2h_bufcp[core_num].sem); + } while(num_pages); + + return NSS_SUCCESS; +failure: + up(&nss_n2h_bufcp[core_num].sem); + return NSS_FAILURE; +} + +/* + * nss_mitigation_handler() + * Enable NSS MITIGATION + */ +static int nss_n2h_mitigationcfg_core0_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_0]; + int ret; + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + if (ret) { + return ret; + } + + /* + * It's a read operation + */ + if (!write) { + return ret; + } + + if (!nss_n2h_core0_mitigation_cfg) { + printk(KERN_INFO "Disabling NSS MITIGATION\n"); + nss_n2h_mitigation_cfg(nss_ctx, 0, NSS_CORE_0); + return 0; + } + printk(KERN_INFO "Invalid input value.Valid value is 0, Runtime re-enabling not supported\n"); + return -EINVAL; +} + +/* + * nss_mitigation_handler() + * Enable NSS MITIGATION + */ +static int nss_n2h_mitigationcfg_core1_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_1]; + int ret; + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + if (ret) { + return ret; + } + + /* + * It's a read operation + */ + if (!write) { + return ret; + } + + if (!nss_n2h_core1_mitigation_cfg) { + printk(KERN_INFO "Disabling NSS MITIGATION\n"); + nss_n2h_mitigation_cfg(nss_ctx, 0, NSS_CORE_1); + return 0; + } + printk(KERN_INFO "Invalid input value.Valid value is 0, Runtime re-enabling not supported\n"); + return -EINVAL; +} + +/* + * nss_buf_handler() + * Add extra NSS bufs from host memory + */ +static int nss_n2h_buf_cfg_core0_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_0]; + int ret; + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + if (ret) { + return ret; + } + + /* + * It's a read operation + */ + if (!write) { + return ret; + } + + if (nss_ctx->buf_sz_allocated) { + nss_n2h_core0_add_buf_pool_size = nss_ctx->buf_sz_allocated; + return -EPERM; + } + + if ((nss_n2h_core0_add_buf_pool_size >= 1) && (nss_n2h_core0_add_buf_pool_size <= NSS_N2H_MAX_BUF_POOL_SIZE)) { + printk(KERN_INFO "configuring additional NSS pbufs\n"); + ret = nss_n2h_buf_pool_cfg(nss_ctx, nss_n2h_core0_add_buf_pool_size, NSS_CORE_0); + nss_n2h_core0_add_buf_pool_size = nss_ctx->buf_sz_allocated; + printk(KERN_INFO "additional pbufs of size %d got added to NSS\n", nss_ctx->buf_sz_allocated); + return ret; + } + + printk(KERN_INFO "Invalid input value. should be greater than 1 and less than %d\n", NSS_N2H_MAX_BUF_POOL_SIZE); + return -EINVAL; +} + +/* + * nss_n2h_buf_handler() + * Add extra NSS bufs from host memory + */ +static int nss_n2h_buf_cfg_core1_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[NSS_CORE_1]; + int ret; + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + if (ret) { + return ret; + } + + /* + * It's a read operation + */ + if (!write) { + return ret; + } + + if (nss_ctx->buf_sz_allocated) { + nss_n2h_core1_add_buf_pool_size = nss_ctx->buf_sz_allocated; + return -EPERM; + } + + if ((nss_n2h_core1_add_buf_pool_size >= 1) && (nss_n2h_core1_add_buf_pool_size <= NSS_N2H_MAX_BUF_POOL_SIZE)) { + printk(KERN_INFO "configuring additional NSS pbufs\n"); + ret = nss_n2h_buf_pool_cfg(nss_ctx, nss_n2h_core1_add_buf_pool_size, NSS_CORE_1); + nss_n2h_core1_add_buf_pool_size = nss_ctx->buf_sz_allocated; + printk(KERN_INFO "additional pbufs of size %d got added to NSS\n", nss_ctx->buf_sz_allocated); + return ret; + } + + printk(KERN_INFO "Invalid input value. should be greater than 1 and less than %d\n", NSS_N2H_MAX_BUF_POOL_SIZE); + return -EINVAL; +} + +/* + * nss_n2h_queue_limit_callback() + * Callback to handle the completion of queue limit command. + */ +static void nss_n2h_queue_limit_callback(void *app_data, struct nss_n2h_msg *nim) +{ + if (nim->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("n2h error response %d\n", nim->cm.response); + } + + nss_n2h_q_lim_pvt.response = nim->cm.response; + complete(&nss_n2h_q_lim_pvt.complete); +} + +/* + * nss_n2h_set_queue_limit_sync() + * Sets the n2h queue size limit synchronously. + */ +static int nss_n2h_set_queue_limit_sync(struct ctl_table *ctl, int write, void __user *buffer, + size_t *lenp, loff_t *ppos, uint32_t core_id) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_id]; + struct nss_n2h_msg nim; + struct nss_n2h_queue_limit_config *nnqlc = NULL; + int ret, current_val; + nss_tx_status_t nss_tx_status; + + /* + * Take a snap shot of current value + */ + current_val = nss_n2h_queue_limit[core_id]; + + /* + * Write the variable with user input + */ + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + if (ret || (!write)) { + return ret; + } + + /* + * We dont allow shortening of the queue size at run-time + */ + if (nss_n2h_queue_limit[core_id] < current_val) { + nss_warning("%px: New queue limit %d less than previous value %d. Cant allow shortening\n", + nss_ctx, nss_n2h_queue_limit[core_id], current_val); + nss_n2h_queue_limit[core_id] = current_val; + return NSS_TX_FAILURE; + } + + memset(&nim, 0, sizeof(struct nss_n2h_msg)); + nss_n2h_msg_init(&nim, NSS_N2H_INTERFACE, + NSS_TX_METADATA_TYPE_N2H_QUEUE_LIMIT_CFG, + sizeof(struct nss_n2h_queue_limit_config), nss_n2h_queue_limit_callback, NULL); + + nnqlc = &nim.msg.ql_cfg; + nnqlc->qlimit = nss_n2h_queue_limit[core_id]; + + /* + * Send synchronous message to firmware + */ + down(&nss_n2h_q_lim_pvt.sem); + + nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nim); + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: n2h queue limit message send failed\n", nss_ctx); + nss_n2h_queue_limit[core_id] = current_val; + up(&nss_n2h_q_lim_pvt.sem); + return nss_tx_status; + } + + ret = wait_for_completion_timeout(&nss_n2h_q_lim_pvt.complete, msecs_to_jiffies(NSS_N2H_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: Timeout expired for queue limit sync message\n", nss_ctx); + nss_n2h_queue_limit[core_id] = current_val; + up(&nss_n2h_q_lim_pvt.sem); + return NSS_TX_FAILURE; + } + + /* + * If setting the queue limit failed, reset the value to original value + */ + if (nss_n2h_q_lim_pvt.response != NSS_CMN_RESPONSE_ACK) { + nss_n2h_queue_limit[core_id] = current_val; + } + + up(&nss_n2h_q_lim_pvt.sem); + return NSS_TX_SUCCESS; +} + +/* + * nss_n2h_queue_limit_core0_handler() + * Sets the n2h queue size limit for core0 + */ +static int nss_n2h_queue_limit_core0_handler(struct ctl_table *ctl, + int write, void __user *buffer, + size_t *lenp, loff_t *ppos) +{ + return nss_n2h_set_queue_limit_sync(ctl, write, buffer, lenp, ppos, + NSS_CORE_0); +} + +/* + * nss_n2h_queue_limit_core1_handler() + * Sets the n2h queue size limit for core1 + */ +static int nss_n2h_queue_limit_core1_handler(struct ctl_table *ctl, + int write, void __user *buffer, + size_t *lenp, loff_t *ppos) +{ + return nss_n2h_set_queue_limit_sync(ctl, write, buffer, lenp, ppos, + NSS_CORE_1); +} + +/* + * nss_n2h_host_bp_cfg_callback() + * Callback function for back pressure configuration. + */ +static void nss_n2h_host_bp_cfg_callback(void *app_data, struct nss_n2h_msg *nnm) +{ + struct nss_ctx_instance *nss_ctx __maybe_unused = (struct nss_ctx_instance *)app_data; + if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_n2h_host_bp_cfg_pvt.response = NSS_FAILURE; + complete(&nss_n2h_host_bp_cfg_pvt.complete); + nss_warning("%px: n2h back pressure configuration failed : %d\n", nss_ctx, nnm->cm.error); + return; + } + + nss_info("%px: n2h back pressure configuration succeeded: %d\n", nss_ctx, nnm->cm.error); + nss_n2h_host_bp_cfg_pvt.response = NSS_SUCCESS; + complete(&nss_n2h_host_bp_cfg_pvt.complete); +} + +/* + * nss_n2h_host_bp_cfg() + * Send Message to n2h to enable back pressure. + */ +static nss_tx_status_t nss_n2h_host_bp_cfg_sync(struct nss_ctx_instance *nss_ctx, int enable_bp) +{ + struct nss_n2h_msg nnm; + nss_tx_status_t nss_tx_status; + int ret; + + down(&nss_n2h_host_bp_cfg_pvt.sem); + nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_TX_METADATA_TYPE_N2H_HOST_BACK_PRESSURE_CFG, + sizeof(struct nss_n2h_host_back_pressure), + nss_n2h_host_bp_cfg_callback, + (void *)nss_ctx); + + nnm.msg.host_bp_cfg.enable = enable_bp; + + nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm); + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: nss_tx error setting back pressure\n", nss_ctx); + up(&nss_n2h_host_bp_cfg_pvt.sem); + return NSS_FAILURE; + } + + /* + * Blocking call, wait till we get ACK for this msg. + */ + ret = wait_for_completion_timeout(&nss_n2h_host_bp_cfg_pvt.complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT)); + if (ret == 0) { + nss_warning("%px: Waiting for ack timed out\n", nss_ctx); + up(&nss_n2h_host_bp_cfg_pvt.sem); + return NSS_FAILURE; + } + + /* + * Response received from NSS FW + */ + if (nss_n2h_host_bp_cfg_pvt.response == NSS_FAILURE) { + up(&nss_n2h_host_bp_cfg_pvt.sem); + return NSS_FAILURE; + } + + up(&nss_n2h_host_bp_cfg_pvt.sem); + return NSS_SUCCESS; +} + +/* + * nss_n2h_host_bp_cfg_handler() + * Enable n2h back pressure. + */ +static int nss_n2h_host_bp_cfg_handler(struct ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos, uint32_t core_id) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[core_id]; + int ret, ret_bp, current_state; + current_state = nss_n2h_host_bp_config[core_id]; + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + + if (ret != NSS_SUCCESS) { + return ret; + } + + if (!write) { + return ret; + } + + if ((nss_n2h_host_bp_config[core_id] != 0) && (nss_n2h_host_bp_config[core_id] != 1)) { + nss_info_always("Invalid input value. Valid values are 0 and 1\n"); + nss_n2h_host_bp_config[core_id] = current_state; + return ret; + } + + nss_info("Configuring n2h back pressure\n"); + ret_bp = nss_n2h_host_bp_cfg_sync(nss_ctx, nss_n2h_host_bp_config[core_id]); + + if (ret_bp != NSS_SUCCESS) { + nss_warning("%px: n2h back pressure config failed\n", nss_ctx); + nss_n2h_host_bp_config[core_id] = current_state; + } + + return ret_bp; +} + +/* + * nss_n2h_host_bp_cfg_core0_handler() + * Enable n2h back pressure in core 0. + */ +static int nss_n2h_host_bp_cfg_core0_handler(struct ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + return nss_n2h_host_bp_cfg_handler(ctl, write, buffer, lenp, ppos, NSS_CORE_0); +} + +/* + * nss_n2h_host_bp_cfg_core1_handler() + * Enable n2h back pressure in core 1. + */ +static int nss_n2h_host_bp_cfg_core1_handler(struct ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + return nss_n2h_host_bp_cfg_handler(ctl, write, buffer, lenp, ppos, NSS_CORE_1); +} + +static struct ctl_table nss_n2h_table_single_core[] = { + { + .procname = "n2h_empty_pool_buf_core0", + .data = &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_empty_pool_buf_cfg_core0_handler, + }, + { + .procname = "n2h_empty_paged_pool_buf_core0", + .data = &nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_0], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_empty_paged_pool_buf_cfg_core0_handler, + }, + { + .procname = "n2h_low_water_core0", + .data = &nss_n2h_water_mark[NSS_CORE_0][0], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_water_mark_core0_handler, + }, + { + .procname = "n2h_high_water_core0", + .data = &nss_n2h_water_mark[NSS_CORE_0][1], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_water_mark_core0_handler, + }, + { + .procname = "n2h_paged_low_water_core0", + .data = &nss_n2h_paged_water_mark[NSS_CORE_0][0], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_paged_water_mark_core0_handler, + }, + { + .procname = "n2h_paged_high_water_core0", + .data = &nss_n2h_paged_water_mark[NSS_CORE_0][1], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_paged_water_mark_core0_handler, + }, + { + .procname = "n2h_wifi_pool_buf", + .data = &nss_n2h_wifi_pool_buf_cfg, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_wifi_payloads_handler, + }, + { + .procname = "mitigation_core0", + .data = &nss_n2h_core0_mitigation_cfg, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_mitigationcfg_core0_handler, + }, + { + .procname = "extra_pbuf_core0", + .data = &nss_n2h_core0_add_buf_pool_size, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_buf_cfg_core0_handler, + }, + { + .procname = "n2h_queue_limit_core0", + .data = &nss_n2h_queue_limit[NSS_CORE_0], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_queue_limit_core0_handler, + }, + { + .procname = "host_bp_enable0", + .data = &nss_n2h_host_bp_config[NSS_CORE_0], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_host_bp_cfg_core0_handler, + }, + + { } +}; + +static struct ctl_table nss_n2h_table_multi_core[] = { + { + .procname = "n2h_empty_pool_buf_core0", + .data = &nss_n2h_empty_pool_buf_cfg[NSS_CORE_0], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_empty_pool_buf_cfg_core0_handler, + }, + { + .procname = "n2h_empty_pool_buf_core1", + .data = &nss_n2h_empty_pool_buf_cfg[NSS_CORE_1], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_empty_pool_buf_cfg_core1_handler, + }, + { + .procname = "n2h_empty_paged_pool_buf_core0", + .data = &nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_0], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_empty_paged_pool_buf_cfg_core0_handler, + }, + { + .procname = "n2h_empty_paged_pool_buf_core1", + .data = &nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_1], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_empty_paged_pool_buf_cfg_core1_handler, + }, + + { + .procname = "n2h_low_water_core0", + .data = &nss_n2h_water_mark[NSS_CORE_0][0], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_water_mark_core0_handler, + }, + { + .procname = "n2h_low_water_core1", + .data = &nss_n2h_water_mark[NSS_CORE_1][0], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_water_mark_core1_handler, + }, + { + .procname = "n2h_high_water_core0", + .data = &nss_n2h_water_mark[NSS_CORE_0][1], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_water_mark_core0_handler, + }, + { + .procname = "n2h_high_water_core1", + .data = &nss_n2h_water_mark[NSS_CORE_1][1], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_water_mark_core1_handler, + }, + { + .procname = "n2h_paged_low_water_core0", + .data = &nss_n2h_paged_water_mark[NSS_CORE_0][0], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_paged_water_mark_core0_handler, + }, + { + .procname = "n2h_paged_low_water_core1", + .data = &nss_n2h_paged_water_mark[NSS_CORE_1][0], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_paged_water_mark_core1_handler, + }, + { + .procname = "n2h_paged_high_water_core0", + .data = &nss_n2h_paged_water_mark[NSS_CORE_0][1], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_paged_water_mark_core0_handler, + }, + { + .procname = "n2h_paged_high_water_core1", + .data = &nss_n2h_paged_water_mark[NSS_CORE_1][1], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_paged_water_mark_core1_handler, + }, + { + .procname = "n2h_wifi_pool_buf", + .data = &nss_n2h_wifi_pool_buf_cfg, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_wifi_payloads_handler, + }, + { + .procname = "mitigation_core0", + .data = &nss_n2h_core0_mitigation_cfg, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_mitigationcfg_core0_handler, + }, + { + .procname = "mitigation_core1", + .data = &nss_n2h_core1_mitigation_cfg, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_mitigationcfg_core1_handler, + }, + { + .procname = "extra_pbuf_core0", + .data = &nss_n2h_core0_add_buf_pool_size, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_buf_cfg_core0_handler, + }, + { + .procname = "extra_pbuf_core1", + .data = &nss_n2h_core1_add_buf_pool_size, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_buf_cfg_core1_handler, + }, + { + .procname = "n2h_queue_limit_core0", + .data = &nss_n2h_queue_limit[NSS_CORE_0], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_queue_limit_core0_handler, + }, + { + .procname = "n2h_queue_limit_core1", + .data = &nss_n2h_queue_limit[NSS_CORE_1], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_queue_limit_core1_handler, + }, + { + .procname = "host_bp_enable0", + .data = &nss_n2h_host_bp_config[NSS_CORE_0], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_host_bp_cfg_core0_handler, + }, + { + .procname = "host_bp_enable1", + .data = &nss_n2h_host_bp_config[NSS_CORE_1], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_n2h_host_bp_cfg_core1_handler, + }, + { } +}; + +/* + * This table will be overwritten during single-core registration + */ +static struct ctl_table nss_n2h_dir[] = { + { + .procname = "n2hcfg", + .mode = 0555, + .child = nss_n2h_table_multi_core, + }, + { } +}; + +static struct ctl_table nss_n2h_root_dir[] = { + { + .procname = "nss", + .mode = 0555, + .child = nss_n2h_dir, + }, + { } +}; + +static struct ctl_table nss_n2h_root[] = { + { + .procname = "dev", + .mode = 0555, + .child = nss_n2h_root_dir, + }, + { } +}; + +static struct ctl_table_header *nss_n2h_header; + +/* + * nss_n2h_cfg_empty_pool_size() + * Config empty buffer pool + */ +nss_tx_status_t nss_n2h_cfg_empty_pool_size(struct nss_ctx_instance *nss_ctx, uint32_t pool_sz) +{ + struct nss_n2h_msg nnm; + struct nss_n2h_empty_pool_buf *nnepbcm; + nss_tx_status_t nss_tx_status; + + if (pool_sz < NSS_N2H_MIN_EMPTY_POOL_BUF_SZ) { + nss_warning("%px: setting pool size %d < min number of buffer", + nss_ctx, pool_sz); + return NSS_TX_FAILURE; + } + + if (pool_sz > NSS_N2H_MAX_EMPTY_POOL_BUF_SZ) { + nss_warning("%px: setting pool size %d > max number of buffer", + nss_ctx, pool_sz); + return NSS_TX_FAILURE; + } + + nss_info("%px: update number of empty buffer pool size: %d\n", + nss_ctx, pool_sz); + + nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, + NSS_TX_METADATA_TYPE_N2H_EMPTY_POOL_BUF_CFG, + sizeof(struct nss_n2h_empty_pool_buf), NULL, 0); + + nnepbcm = &nnm.msg.empty_pool_buf_cfg; + nnepbcm->pool_size = htonl(pool_sz); + nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm); + + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: nss_tx error empty buffer pool: %d\n", nss_ctx, pool_sz); + return nss_tx_status; + } + + return nss_tx_status; +} + +/* + * nss_n2h_paged_buf_pool_init() + * Sends a command down to NSS to initialize paged buffer pool + */ +nss_tx_status_t nss_n2h_paged_buf_pool_init(struct nss_ctx_instance *nss_ctx) +{ + struct nss_n2h_msg nnm; + nss_tx_status_t nss_tx_status; + + /* + * No additional information needed at this point + */ + nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, + NSS_TX_METADATA_TYPE_N2H_PAGED_BUFFER_POOL_INIT, + sizeof(struct nss_n2h_paged_buffer_pool_init), + NULL, + NULL); + + nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm); + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: failed to send paged buf configuration init command to NSS\n", + nss_ctx); + return NSS_TX_FAILURE; + } + + return NSS_TX_SUCCESS; +} + +/* + * nss_n2h_flush_payloads() + * Sends a command down to NSS for flushing all payloads + */ +nss_tx_status_t nss_n2h_flush_payloads(struct nss_ctx_instance *nss_ctx) +{ + struct nss_n2h_msg nnm; + struct nss_n2h_flush_payloads *nnflshpl; + nss_tx_status_t nss_tx_status; + + nnflshpl = &nnm.msg.flush_payloads; + + /* + * TODO: No additional information sent in message + * as of now. Need to initialize message content accordingly + * if needed. + */ + nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, + NSS_TX_METADATA_TYPE_N2H_FLUSH_PAYLOADS, + sizeof(struct nss_n2h_flush_payloads), + NULL, + NULL); + + nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm); + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: failed to send flush payloads command to NSS\n", + nss_ctx); + + return NSS_TX_FAILURE; + } + + return NSS_TX_SUCCESS; +} + +/* + * nss_n2h_msg_init() + * Initialize n2h message. + */ +void nss_n2h_msg_init(struct nss_n2h_msg *nim, uint16_t if_num, uint32_t type, + uint32_t len, nss_n2h_msg_callback_t cb, void *app_data) +{ + nss_cmn_msg_init(&nim->cm, if_num, type, len, (void *)cb, app_data); +} + +/* + * nss_n2h_tx_msg() + * Send messages to NSS n2h package. + */ +nss_tx_status_t nss_n2h_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_n2h_msg *nnm) +{ + struct nss_cmn_msg *ncm = &nnm->cm; + + /* + * Sanity check the message + */ + if (ncm->interface != NSS_N2H_INTERFACE) { + nss_warning("%px: tx request for another interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type >= NSS_METADATA_TYPE_N2H_MAX) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, nnm, sizeof(*nnm), NSS_NBUF_PAYLOAD_SIZE); +} + +/* + * nss_n2h_notify_register() + * Register to received N2H events. + * + * NOTE: Do we want to pass an nss_ctx here so that we can register for n2h on any core? + */ +struct nss_ctx_instance *nss_n2h_notify_register(int core, nss_n2h_msg_callback_t cb, void *app_data) +{ + if (core >= nss_top_main.num_nss) { + nss_warning("Input core number %d is wrong \n", core); + return NULL; + } + /* + * TODO: We need to have a new array in support of the new API + * TODO: If we use a per-context array, we would move the array into nss_ctx based. + */ + nss_n2h_rd[core].n2h_callback = cb; + nss_n2h_rd[core].app_data = app_data; + return &nss_top_main.nss[core]; +} + +/* + * nss_n2h_register_handler() + */ +void nss_n2h_register_handler(struct nss_ctx_instance *nss_ctx) +{ + sema_init(&nss_n2h_q_cfg_pvt.sem, 1); + init_completion(&nss_n2h_q_cfg_pvt.complete); + + nss_core_register_handler(nss_ctx, NSS_N2H_INTERFACE, nss_n2h_interface_handler, NULL); + + if (nss_ctx->id == NSS_CORE_0) { + nss_n2h_stats_dentry_create(); + } + nss_n2h_strings_dentry_create(); + + nss_drv_strings_dentry_create(); +} + +/* + * nss_n2h_single_core_register_sysctl() + */ +void nss_n2h_single_core_register_sysctl(void) +{ + /* + * RPS sema init + */ + sema_init(&nss_n2h_rcp.sem, 1); + init_completion(&nss_n2h_rcp.complete); + + /* + * MITIGATION sema init for core0 + */ + sema_init(&nss_n2h_mitigationcp[NSS_CORE_0].sem, 1); + init_completion(&nss_n2h_mitigationcp[NSS_CORE_0].complete); + + /* + * PBUF addition sema init for core0 + */ + sema_init(&nss_n2h_bufcp[NSS_CORE_0].sem, 1); + init_completion(&nss_n2h_bufcp[NSS_CORE_0].complete); + + /* + * Core0 + */ + sema_init(&nss_n2h_nepbcfgp[NSS_CORE_0].sem, 1); + init_completion(&nss_n2h_nepbcfgp[NSS_CORE_0].complete); + nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.pool_size = + nss_n2h_empty_pool_buf_cfg[NSS_CORE_0]; + nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.low_water = + nss_n2h_water_mark[NSS_CORE_0][0]; + nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.high_water = + nss_n2h_water_mark[NSS_CORE_0][1]; + nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.pool_size = + nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_0]; + nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.low_water = + nss_n2h_paged_water_mark[NSS_CORE_0][0]; + nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.high_water = + nss_n2h_paged_water_mark[NSS_CORE_0][1]; + + /* + * WiFi pool buf cfg sema init + */ + sema_init(&nss_n2h_wp.sem, 1); + init_completion(&nss_n2h_wp.complete); + + /* + * N2H queue config sema init + */ + sema_init(&nss_n2h_q_lim_pvt.sem, 1); + init_completion(&nss_n2h_q_lim_pvt.complete); + + /* + * Back pressure config sema init + */ + sema_init(&nss_n2h_host_bp_cfg_pvt.sem, 1); + init_completion(&nss_n2h_host_bp_cfg_pvt.complete); + + nss_n2h_notify_register(NSS_CORE_0, NULL, NULL); + + /* + * Register sysctl table. + */ + nss_n2h_dir[0].child = nss_n2h_table_single_core; + nss_n2h_header = register_sysctl_table(nss_n2h_root); +} + +/* + * nss_n2h_multi_core_register_sysctl() + */ +void nss_n2h_multi_core_register_sysctl(void) +{ + /* + * RPS sema init + */ + sema_init(&nss_n2h_rcp.sem, 1); + init_completion(&nss_n2h_rcp.complete); + + /* + * MITIGATION sema init for core0 + */ + sema_init(&nss_n2h_mitigationcp[NSS_CORE_0].sem, 1); + init_completion(&nss_n2h_mitigationcp[NSS_CORE_0].complete); + + /* + * MITIGATION sema init for core1 + */ + sema_init(&nss_n2h_mitigationcp[NSS_CORE_1].sem, 1); + init_completion(&nss_n2h_mitigationcp[NSS_CORE_1].complete); + + /* + * PBUF addition sema init for core0 + */ + sema_init(&nss_n2h_bufcp[NSS_CORE_0].sem, 1); + init_completion(&nss_n2h_bufcp[NSS_CORE_0].complete); + + /* + * PBUF addition sema init for core1 + */ + sema_init(&nss_n2h_bufcp[NSS_CORE_1].sem, 1); + init_completion(&nss_n2h_bufcp[NSS_CORE_1].complete); + + /* + * Core0 + */ + sema_init(&nss_n2h_nepbcfgp[NSS_CORE_0].sem, 1); + init_completion(&nss_n2h_nepbcfgp[NSS_CORE_0].complete); + nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.pool_size = + nss_n2h_empty_pool_buf_cfg[NSS_CORE_0]; + nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.low_water = + nss_n2h_water_mark[NSS_CORE_0][0]; + nss_n2h_nepbcfgp[NSS_CORE_0].empty_buf_pool_info.high_water = + nss_n2h_water_mark[NSS_CORE_0][1]; + nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.pool_size = + nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_0]; + nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.low_water = + nss_n2h_paged_water_mark[NSS_CORE_0][0]; + nss_n2h_nepbcfgp[NSS_CORE_0].empty_paged_buf_pool_info.high_water = + nss_n2h_paged_water_mark[NSS_CORE_0][1]; + + /* + * Core1 + */ + sema_init(&nss_n2h_nepbcfgp[NSS_CORE_1].sem, 1); + init_completion(&nss_n2h_nepbcfgp[NSS_CORE_1].complete); + nss_n2h_nepbcfgp[NSS_CORE_1].empty_buf_pool_info.pool_size = + nss_n2h_empty_pool_buf_cfg[NSS_CORE_1]; + nss_n2h_nepbcfgp[NSS_CORE_1].empty_buf_pool_info.low_water = + nss_n2h_water_mark[NSS_CORE_1][0]; + nss_n2h_nepbcfgp[NSS_CORE_1].empty_buf_pool_info.high_water = + nss_n2h_water_mark[NSS_CORE_1][1]; + nss_n2h_nepbcfgp[NSS_CORE_1].empty_paged_buf_pool_info.pool_size = + nss_n2h_empty_paged_pool_buf_cfg[NSS_CORE_1]; + nss_n2h_nepbcfgp[NSS_CORE_1].empty_paged_buf_pool_info.low_water = + nss_n2h_paged_water_mark[NSS_CORE_1][0]; + nss_n2h_nepbcfgp[NSS_CORE_1].empty_paged_buf_pool_info.high_water = + nss_n2h_paged_water_mark[NSS_CORE_1][1]; + + /* + * WiFi pool buf cfg sema init + */ + sema_init(&nss_n2h_wp.sem, 1); + init_completion(&nss_n2h_wp.complete); + + /* + * N2H queue config sema init + */ + sema_init(&nss_n2h_q_lim_pvt.sem, 1); + init_completion(&nss_n2h_q_lim_pvt.complete); + + /* + * Back pressure config sema init + */ + sema_init(&nss_n2h_host_bp_cfg_pvt.sem, 1); + init_completion(&nss_n2h_host_bp_cfg_pvt.complete); + + nss_n2h_notify_register(NSS_CORE_0, NULL, NULL); + nss_n2h_notify_register(NSS_CORE_1, NULL, NULL); + + /* + * Register sysctl table. + */ + nss_n2h_header = register_sysctl_table(nss_n2h_root); +} + +/* + * nss_n2h_unregister_sysctl() + * Unregister sysctl specific to n2h + */ +void nss_n2h_unregister_sysctl(void) +{ + /* + * Unregister sysctl table. + */ + if (nss_n2h_header) { + unregister_sysctl_table(nss_n2h_header); + } +} + +EXPORT_SYMBOL(nss_n2h_notify_register); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_n2h_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_n2h_stats.c new file mode 100644 index 000000000..60ff88ba9 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_n2h_stats.c @@ -0,0 +1,214 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_n2h_stats.h" +#include "nss_n2h.h" +#include "nss_n2h_strings.h" + +/* + * Declare atomic notifier data structure for statistics. + */ +ATOMIC_NOTIFIER_HEAD(nss_n2h_stats_notifier); + +uint64_t nss_n2h_stats[NSS_MAX_CORES][NSS_N2H_STATS_MAX]; + +/* + * nss_n2h_stats_read() + * Read N2H stats + */ +static ssize_t nss_n2h_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i, core; + + /* + * Max output lines = #stats + few blank lines for banner printing + + * Number of Extra outputlines for future reference to add new stats + */ + uint32_t max_output_lines = (NSS_N2H_STATS_MAX + 3) * NSS_MAX_CORES + NSS_STATS_EXTRA_OUTPUT_LINES; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + stats_shadow = kzalloc(NSS_N2H_STATS_MAX * 8, GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return 0; + } + + /* + * N2H node stats + */ + for (core = 0; core < nss_top_main.num_nss; core++) { + spin_lock_bh(&nss_top_main.stats_lock); + for (i = 0; i < NSS_N2H_STATS_MAX; i++) { + stats_shadow[i] = nss_n2h_stats[core][i]; + } + spin_unlock_bh(&nss_top_main.stats_lock); + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "n2h", core); + size_wr += nss_stats_print("n2h", NULL, NSS_STATS_SINGLE_INSTANCE + , nss_n2h_strings_stats + , stats_shadow + , NSS_N2H_STATS_MAX + , lbuf, size_wr, size_al); + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * nss_n2h_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(n2h); + +/* + * nss_n2h_stats_dentry_create() + * Create N2H statistics debug entry. + */ +void nss_n2h_stats_dentry_create(void) +{ + nss_stats_create_dentry("n2h", &nss_n2h_stats_ops); +} + +/* + * nss_n2h_stats_sync() + * Handle the syncing of NSS statistics. + */ +void nss_n2h_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_n2h_stats_sync *nnss) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + int id = nss_ctx->id; + int j; + + spin_lock_bh(&nss_top->stats_lock); + + /* + * common node stats + */ + nss_n2h_stats[id][NSS_STATS_NODE_RX_PKTS] += nnss->node_stats.rx_packets; + nss_n2h_stats[id][NSS_STATS_NODE_RX_BYTES] += nnss->node_stats.rx_bytes; + nss_n2h_stats[id][NSS_STATS_NODE_TX_PKTS] += nnss->node_stats.tx_packets; + nss_n2h_stats[id][NSS_STATS_NODE_TX_BYTES] += nnss->node_stats.tx_bytes; + + for (j = 0; j < NSS_MAX_NUM_PRI; j++) { + nss_n2h_stats[id][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + j] += nnss->node_stats.rx_dropped[j]; + } + + /* + * General N2H stats + */ + nss_n2h_stats[id][NSS_N2H_STATS_QUEUE_DROPPED] += nnss->queue_dropped; + nss_n2h_stats[id][NSS_N2H_STATS_TOTAL_TICKS] += nnss->total_ticks; + nss_n2h_stats[id][NSS_N2H_STATS_WORST_CASE_TICKS] += nnss->worst_case_ticks; + nss_n2h_stats[id][NSS_N2H_STATS_ITERATIONS] += nnss->iterations; + + /* + * pbuf manager ocm and default pool stats + */ + nss_n2h_stats[id][NSS_N2H_STATS_PBUF_OCM_ALLOC_FAILS_WITH_PAYLOAD] += nnss->pbuf_ocm_stats.pbuf_alloc_fails_with_payload; + nss_n2h_stats[id][NSS_N2H_STATS_PBUF_OCM_FREE_COUNT] = nnss->pbuf_ocm_stats.pbuf_free_count; + nss_n2h_stats[id][NSS_N2H_STATS_PBUF_OCM_TOTAL_COUNT] = nnss->pbuf_ocm_stats.pbuf_total_count; + nss_n2h_stats[id][NSS_N2H_STATS_PBUF_OCM_ALLOC_FAILS_NO_PAYLOAD] += nnss->pbuf_ocm_stats.pbuf_alloc_fails_no_payload; + + nss_n2h_stats[id][NSS_N2H_STATS_PBUF_DEFAULT_ALLOC_FAILS_WITH_PAYLOAD] += nnss->pbuf_default_stats.pbuf_alloc_fails_with_payload; + nss_n2h_stats[id][NSS_N2H_STATS_PBUF_DEFAULT_FREE_COUNT] = nnss->pbuf_default_stats.pbuf_free_count; + nss_n2h_stats[id][NSS_N2H_STATS_PBUF_DEFAULT_TOTAL_COUNT] = nnss->pbuf_default_stats.pbuf_total_count; + nss_n2h_stats[id][NSS_N2H_STATS_PBUF_DEFAULT_ALLOC_FAILS_NO_PAYLOAD] += nnss->pbuf_default_stats.pbuf_alloc_fails_no_payload; + + /* + * payload mgr stats + */ + nss_n2h_stats[id][NSS_N2H_STATS_PAYLOAD_ALLOC_FAILS] += nnss->payload_alloc_fails; + nss_n2h_stats[id][NSS_N2H_STATS_PAYLOAD_FREE_COUNT] = nnss->payload_free_count; + + /* + * Host <=> NSS control traffic stats + */ + nss_n2h_stats[id][NSS_N2H_STATS_H2N_CONTROL_PACKETS] += nnss->h2n_ctrl_pkts; + nss_n2h_stats[id][NSS_N2H_STATS_H2N_CONTROL_BYTES] += nnss->h2n_ctrl_bytes; + nss_n2h_stats[id][NSS_N2H_STATS_N2H_CONTROL_PACKETS] += nnss->n2h_ctrl_pkts; + nss_n2h_stats[id][NSS_N2H_STATS_N2H_CONTROL_BYTES] += nnss->n2h_ctrl_bytes; + + /* + * Host <=> NSS control data traffic stats + */ + nss_n2h_stats[id][NSS_N2H_STATS_H2N_DATA_PACKETS] += nnss->h2n_data_pkts; + nss_n2h_stats[id][NSS_N2H_STATS_H2N_DATA_BYTES] += nnss->h2n_data_bytes; + nss_n2h_stats[id][NSS_N2H_STATS_N2H_DATA_PACKETS] += nnss->n2h_data_pkts; + nss_n2h_stats[id][NSS_N2H_STATS_N2H_DATA_BYTES] += nnss->n2h_data_bytes; + + /* + * Payloads related stats + */ + nss_n2h_stats[id][NSS_N2H_STATS_N2H_TOT_PAYLOADS] = nnss->tot_payloads; + + nss_n2h_stats[id][NSS_N2H_STATS_N2H_INTERFACE_INVALID] += nnss->data_interface_invalid; + nss_n2h_stats[id][NSS_N2H_STATS_ENQUEUE_RETRIES] += nnss->enqueue_retries; + + spin_unlock_bh(&nss_top->stats_lock); +} + +/* + * nss_n2h_stats_notify() + * Sends notifications to all the registered modules. + * + * Leverage NSS-FW statistics timing to update Netlink. + */ +void nss_n2h_stats_notify(struct nss_ctx_instance *nss_ctx) +{ + int i; + struct nss_n2h_stats_notification stats; + + for (i = 0; (i < NSS_STATS_DRV_MAX); i++) { + stats.drv_stats[i] = NSS_PKT_STATS_READ(&nss_top_main.stats_drv[i]); + } + + stats.core_id = nss_ctx->id; + memcpy(stats.n2h_stats, nss_n2h_stats[stats.core_id], sizeof(stats.n2h_stats)); + atomic_notifier_call_chain(&nss_n2h_stats_notifier, NSS_STATS_EVENT_NOTIFY, (void *)&stats); +} + +/* + * nss_n2h_stats_register_notifier() + * Registers statistics notifier. + */ +int nss_n2h_stats_register_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&nss_n2h_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_n2h_stats_register_notifier); + +/* + * nss_n2h_stats_unregister_notifier() + * Deregisters statistics notifier. + */ +int nss_n2h_stats_unregister_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&nss_n2h_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_n2h_stats_unregister_notifier); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_n2h_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_n2h_stats.h new file mode 100644 index 000000000..96d065eb1 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_n2h_stats.h @@ -0,0 +1,27 @@ +/* + ****************************************************************************** + * Copyright (c) 2017,2019-2020 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_N2H_STATS_H +#define __NSS_N2H_STATS_H + +/* + * N2H statistics APIs + */ +extern void nss_n2h_stats_notify(struct nss_ctx_instance *nss_ctx); +extern void nss_n2h_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_n2h_stats_sync *nnss); +extern void nss_n2h_stats_dentry_create(void); + +#endif /* __NSS_N2H_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_n2h_strings.c b/feeds/ipq807x/qca-nss-drv/src/nss_n2h_strings.c new file mode 100644 index 000000000..c4c2ce525 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_n2h_strings.c @@ -0,0 +1,85 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_stats.h" +#include "nss_core.h" +#include +#include "nss_strings.h" + +/* + * nss_n2h_strings_stats + * N2H statistics strings. + */ +struct nss_stats_info nss_n2h_strings_stats[NSS_N2H_STATS_MAX] = { + {"rx_pkts" , NSS_STATS_TYPE_COMMON}, + {"rx_byts" , NSS_STATS_TYPE_COMMON}, + {"tx_pkts" , NSS_STATS_TYPE_COMMON}, + {"tx_byts" , NSS_STATS_TYPE_COMMON}, + {"rx_queue[0]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[1]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[2]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[3]_drops" , NSS_STATS_TYPE_DROP}, + {"queue_drops" , NSS_STATS_TYPE_DROP}, + {"ticks" , NSS_STATS_TYPE_SPECIAL}, + {"worst_ticks" , NSS_STATS_TYPE_SPECIAL}, + {"iterations" , NSS_STATS_TYPE_SPECIAL}, + {"pbuf_ocm_total_count" , NSS_STATS_TYPE_SPECIAL}, + {"pbuf_ocm_free_count" , NSS_STATS_TYPE_SPECIAL}, + {"pbuf_ocm_alloc_fail_payload" , NSS_STATS_TYPE_SPECIAL}, + {"pbuf_ocm_alloc_fail_nopayload", NSS_STATS_TYPE_SPECIAL}, + {"pbuf_def_total_count" , NSS_STATS_TYPE_SPECIAL}, + {"pbuf_def_free_count" , NSS_STATS_TYPE_SPECIAL}, + {"pbuf_def_alloc_fail_payload" , NSS_STATS_TYPE_SPECIAL}, + {"pbuf_def_alloc_fail_nopayload", NSS_STATS_TYPE_SPECIAL}, + {"payload_alloc_fails" , NSS_STATS_TYPE_SPECIAL}, + {"payload_free_count" , NSS_STATS_TYPE_SPECIAL}, + {"h2n_control_pkts" , NSS_STATS_TYPE_SPECIAL}, + {"h2n_control_byts" , NSS_STATS_TYPE_SPECIAL}, + {"n2h_control_pkts" , NSS_STATS_TYPE_SPECIAL}, + {"n2h_control_byts" , NSS_STATS_TYPE_SPECIAL}, + {"h2n_data_pkts" , NSS_STATS_TYPE_SPECIAL}, + {"h2n_data_byts" , NSS_STATS_TYPE_SPECIAL}, + {"n2h_data_pkts" , NSS_STATS_TYPE_SPECIAL}, + {"n2h_data_byts" , NSS_STATS_TYPE_SPECIAL}, + {"n2h_tot_payloads" , NSS_STATS_TYPE_SPECIAL}, + {"n2h_data_interface_invalid" , NSS_STATS_TYPE_SPECIAL}, + {"n2h_enqueue_retries" , NSS_STATS_TYPE_SPECIAL} +}; + +/* + * nss_n2h_strings_read() + * Read N2H node statistics names. + */ +static ssize_t nss_n2h_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_n2h_strings_stats, NSS_N2H_STATS_MAX); +} + +/* + * nss_n2h_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(n2h); + +/* + * nss_n2h_strings_dentry_create() + * Create N2H statistics strings debug entry. + */ +void nss_n2h_strings_dentry_create(void) +{ + nss_strings_create_dentry("n2h", &nss_n2h_strings_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_n2h_strings.h b/feeds/ipq807x/qca-nss-drv/src/nss_n2h_strings.h new file mode 100644 index 000000000..5d8c2131c --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_n2h_strings.h @@ -0,0 +1,25 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_N2H_STRINGS_H +#define __NSS_N2H_STRINGS_H + +extern struct nss_stats_info nss_n2h_strings_stats[NSS_N2H_STATS_MAX]; +extern void nss_n2h_strings_dentry_create(void); + +#endif /* __NSS_N2H_STRINGS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_oam.c b/feeds/ipq807x/qca-nss-drv/src/nss_oam.c new file mode 100644 index 000000000..baf43d352 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_oam.c @@ -0,0 +1,141 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2018, 2020 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_oam.c + * OAM - Operations, Administration and Maintenance Service for NSS + * + * This adapter module is responsible for sending and + * receiving to and from NSS FW + * This file contains the API for communicating NSS FW to send/receive + * commands OAM commands. + */ + +#include "nss_tx_rx_common.h" +#include "nss_oam_log.h" + +/* + * nss_oam_rx_msg_handler() + * Message handler for OAM messages from NSS + */ +static void nss_oam_rx_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused)) void *app_data) +{ + struct nss_oam_msg *nom = (struct nss_oam_msg *)ncm; + nss_oam_msg_callback_t cb; + + /* + * Trace Messages + */ + nss_oam_log_rx_msg(nom); + + /* + * Sanity check the message type + */ + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_oam_msg)) { + nss_warning("%px: recevied with invalid msg size: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + if (ncm->type > NSS_OAM_MSG_TYPE_MAX) { + nss_warning("%px: received with invalid resp type: %d", nss_ctx, ncm->type); + return; + } + + /* + * Log the failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_top_main.oam_callback; + ncm->app_data = (nss_ptr_t)nss_top_main.oam_ctx; + } + + cb = (nss_oam_msg_callback_t)ncm->cb; + if (unlikely(!cb)) { + nss_trace("%px: rx handler has been unregistered for i/f: %d", nss_ctx, ncm->interface); + return; + } + cb((void *)ncm->app_data, nom); +} + +/* + * nss_oam_tx() + * Transmit an oam message to the FW. + */ +nss_tx_status_t nss_oam_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_oam_msg *nom) +{ + struct nss_cmn_msg *ncm = &nom->cm; + + /* + * Trace Messages + */ + nss_oam_log_tx_msg(nom); + + if (ncm->type > NSS_OAM_MSG_TYPE_MAX) { + nss_warning("%px: CMD type for oam module is invalid - %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE_BAD_PARAM; + } + + if (ncm->interface != NSS_OAM_INTERFACE) { + nss_warning("%px: tx message request for another interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, nom, sizeof(*nom), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_oam_tx_msg); + +/* + * nss_oam_notify_register() + * Register to receive OAM events. + */ +struct nss_ctx_instance *nss_oam_notify_register(nss_oam_msg_callback_t cb, void *app_data) +{ + if (nss_top_main.oam_ctx || nss_top_main.oam_callback) { + nss_warning("Failed to register notify callback - already registered\n"); + return NULL; + } + + nss_top_main.oam_ctx = app_data; + nss_top_main.oam_callback = cb; + return &nss_top_main.nss[nss_top_main.oam_handler_id]; +} +EXPORT_SYMBOL(nss_oam_notify_register); + +/* + * nss_oam_notify_unregister() + * Unregister to received OAM events. + */ +void nss_oam_notify_unregister(void) +{ + nss_top_main.oam_callback = NULL; + nss_top_main.oam_ctx = NULL; +} +EXPORT_SYMBOL(nss_oam_notify_unregister); + +/* + * nss_register_oam_handler() + * Register our handler to receive messages for this interface + */ +void nss_oam_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[nss_top_main.oam_handler_id]; + + if (nss_core_register_handler(nss_ctx, NSS_OAM_INTERFACE, nss_oam_rx_msg_handler, NULL) != NSS_CORE_STATUS_SUCCESS) { + nss_warning("OAM handler failed to register"); + } +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_oam_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_oam_log.c new file mode 100644 index 000000000..08ffec483 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_oam_log.c @@ -0,0 +1,101 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_oam_log.c + * NSS OAM logger file. + */ + +#include "nss_core.h" + +/* + * nss_oam_log_message_types_str + * NSS OAM message strings + */ +static int8_t *nss_oam_log_message_types_str[NSS_OAM_MSG_TYPE_MAX] __maybe_unused = { + "OAM Message None", + "OAM Get FW Version", +}; + +/* + * nss_oam_log_get_fw_version_msg() + * Log NSS OAM GET FW Version. + */ +static void nss_oam_log_get_fw_version_msg(struct nss_oam_msg *nom) +{ + struct nss_oam_fw_ver *nofm __maybe_unused = &nom->msg.fw_ver; + nss_trace("%px: NSS OAM Get FW Version message \n" + "OAM FW Version: %px\n", + nofm, nofm->string); +} + +/* + * nss_oam_log_verbose() + * Log message contents. + */ +static void nss_oam_log_verbose(struct nss_oam_msg *nom) +{ + switch (nom->cm.type) { + case NSS_OAM_MSG_TYPE_GET_FW_VER: + nss_oam_log_get_fw_version_msg(nom); + break; + + default: + nss_trace("%px: Invalid message type\n", nom); + break; + } +} + +/* + * nss_oam_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_oam_log_tx_msg(struct nss_oam_msg *nom) +{ + if (nom->cm.type >= NSS_OAM_MSG_TYPE_MAX) { + nss_warning("%px: Invalid message type\n", nom); + return; + } + + nss_info("%px: type[%d]:%s\n", nom, nom->cm.type, nss_oam_log_message_types_str[nom->cm.type]); + nss_oam_log_verbose(nom); +} + +/* + * nss_oam_log_rx_msg() + * Log messages received from FW. + */ +void nss_oam_log_rx_msg(struct nss_oam_msg *nom) +{ + if (nom->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", nom); + return; + } + + if (nom->cm.response == NSS_CMN_RESPONSE_NOTIFY || (nom->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", nom, nom->cm.type, + nss_oam_log_message_types_str[nom->cm.type], + nom->cm.response, nss_cmn_response_str[nom->cm.response]); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s\n", + nom, nom->cm.type, nss_oam_log_message_types_str[nom->cm.type], + nom->cm.response, nss_cmn_response_str[nom->cm.response]); + +verbose: + nss_oam_log_verbose(nom); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_oam_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_oam_log.h new file mode 100644 index 000000000..b02611ba2 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_oam_log.h @@ -0,0 +1,41 @@ +/* + ************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_OAM_LOG_H +#define __NSS_OAM_LOG_H + +/* + * nss_oam.h + * NSS OAM header file. + */ + +/* + * Logger APIs + */ + +/* + * nss_oam_log_tx_msg + * Logs a oam message that is sent to the NSS firmware. + */ +void nss_oam_log_tx_msg(struct nss_oam_msg *nom); + +/* + * nss_oam_log_rx_msg + * Logs a oam message that is received from the NSS firmware. + */ +void nss_oam_log_rx_msg(struct nss_oam_msg *nom); + +#endif /* __NSS_OAM_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_phys_if.c b/feeds/ipq807x/qca-nss-drv/src/nss_phys_if.c new file mode 100644 index 000000000..4e5811a3e --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_phys_if.c @@ -0,0 +1,629 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_phy_if.c + * NSS physical interface functions + */ + +#include "nss_tx_rx_common.h" +#include "nss_tstamp.h" +#if defined(NSS_HAL_IPQ807x_SUPPORT) || defined(NSS_HAL_IPQ60XX_SUPPORT) +#include +#endif + +#define NSS_PHYS_IF_TX_TIMEOUT 3000 /* 3 Seconds */ + +/* + * NSS phys_if modes + */ +#define NSS_PHYS_IF_MODE0 0 /* phys_if mode 0 */ +#define NSS_PHYS_IF_MODE1 1 /* phys_if mode 1 */ +#define NSS_PHYS_IF_MODE2 2 /* phys_if mode 2 */ + +/* + * Private data structure for phys_if interface + */ +static struct nss_phys_if_pvt { + struct semaphore sem; + struct completion complete; + int response; +} phif; + +static int nss_phys_if_sem_init_done; + +/* + * nss_phys_if_update_driver_stats() + * Snoop the extended message and update driver statistics. + */ +static void nss_phys_if_update_driver_stats(struct nss_ctx_instance *nss_ctx, uint32_t id, struct nss_phys_if_stats *stats) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + uint64_t *top_stats = &(nss_top->stats_gmac[id][0]); + + spin_lock_bh(&nss_top->stats_lock); + top_stats[NSS_GMAC_STATS_TOTAL_TICKS] += stats->estats.gmac_total_ticks; + if (unlikely(top_stats[NSS_GMAC_STATS_WORST_CASE_TICKS] < stats->estats.gmac_worst_case_ticks)) { + top_stats[NSS_GMAC_STATS_WORST_CASE_TICKS] = stats->estats.gmac_worst_case_ticks; + } + top_stats[NSS_GMAC_STATS_ITERATIONS] += stats->estats.gmac_iterations; + spin_unlock_bh(&nss_top->stats_lock); +} + +/* + * nss_phys_if_msg_handler() + * Handle NSS -> HLOS messages for physical interface/gmacs + */ +static void nss_phys_if_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, + __attribute__((unused))void *app_data) +{ + struct nss_phys_if_msg *nim = (struct nss_phys_if_msg *)ncm; + nss_phys_if_msg_callback_t cb; + + /* + * Sanity check the message type + */ + if (ncm->type > NSS_PHYS_IF_MAX_MSG_TYPES) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return; + } + + if (!NSS_IS_IF_TYPE(PHYSICAL, ncm->interface)) { + nss_warning("%px: response for another interface: %d", nss_ctx, ncm->interface); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_phys_if_msg)) { + nss_warning("%px: message length too big: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Messages value that are within the base class are handled by the base class. + */ + if (ncm->type < NSS_IF_MAX_MSG_TYPES) { + return nss_if_msg_handler(nss_ctx, ncm, app_data); + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Snoop messages for local driver and handle deprecated interfaces. + */ + switch (nim->cm.type) { + case NSS_PHYS_IF_EXTENDED_STATS_SYNC: + /* + * To create the old API gmac statistics, we use the new extended GMAC stats. + */ + nss_phys_if_update_driver_stats(nss_ctx, ncm->interface, &nim->msg.stats); + nss_top_main.data_plane_ops->data_plane_stats_sync(&nim->msg.stats, ncm->interface); + break; + } + + /* + * Update the callback and app_data for NOTIFY messages, IPv4 sends all notify messages + * to the same callback/app_data. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_ctx->nss_top->phys_if_msg_callback[ncm->interface]; + ncm->app_data = (nss_ptr_t)nss_ctx->subsys_dp_register[ncm->interface].ndev; + } + + /* + * Do we have a callback? + */ + if (!ncm->cb) { + return; + } + + /* + * Callback + */ + cb = (nss_phys_if_msg_callback_t)ncm->cb; + cb((void *)ncm->app_data, nim); +} + +/* + * nss_phys_if_callback + * Callback to handle the completion of NSS ->HLOS messages. + */ +static void nss_phys_if_callback(void *app_data, struct nss_phys_if_msg *nim) +{ + if(nim->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("phys_if Error response %d\n", nim->cm.response); + phif.response = NSS_TX_FAILURE; + complete(&phif.complete); + return; + } + + phif.response = NSS_TX_SUCCESS; + complete(&phif.complete); +} + +/* + * nss_phys_if_buf() + * Send packet to physical interface owned by NSS + */ +nss_tx_status_t nss_phys_if_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf, uint32_t if_num) +{ + nss_trace("%px: Phys If Tx packet, id:%d, data=%px", nss_ctx, if_num, os_buf->data); + +#ifdef NSS_DRV_TSTAMP_ENABLE + /* + * If we need the packet to be timestamped by GMAC Hardware at Tx + * send the packet to tstamp NSS module + */ + if (unlikely(skb_shinfo(os_buf)->tx_flags & SKBTX_HW_TSTAMP)) { + /* try PHY Driver hook for transmit timestamping firstly */ +#if defined(NSS_HAL_IPQ807x_SUPPORT) || defined(NSS_HAL_IPQ60XX_SUPPORT) + nss_phy_tstamp_tx_buf(os_buf->dev, os_buf); +#endif + if (!(skb_shinfo(os_buf)->tx_flags & SKBTX_IN_PROGRESS)) + return nss_tstamp_tx_buf(nss_ctx, os_buf, if_num); + } +#endif + + return nss_core_send_packet(nss_ctx, os_buf, if_num, H2N_BIT_FLAG_BUFFER_REUSABLE); +} + +/* + * nss_phys_if_msg() + */ +nss_tx_status_t nss_phys_if_msg(struct nss_ctx_instance *nss_ctx, struct nss_phys_if_msg *nim) +{ + struct nss_cmn_msg *ncm = &nim->cm; + struct net_device *dev; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + /* + * Sanity check the message + */ + if (!NSS_IS_IF_TYPE(PHYSICAL, ncm->interface)) { + nss_warning("%px: tx request for another interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type > NSS_PHYS_IF_MAX_MSG_TYPES) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + dev = nss_ctx->subsys_dp_register[ncm->interface].ndev; + if (!dev) { + nss_warning("%px: Unregister physical interface %d: no context", nss_ctx, ncm->interface); + return NSS_TX_FAILURE_BAD_PARAM; + } + + return nss_core_send_cmd(nss_ctx, nim, sizeof(*nim), NSS_NBUF_PAYLOAD_SIZE); +} + +/* + * nss_phys_if_tx_msg_sync() + * Send a message to physical interface & wait for the response. + */ +nss_tx_status_t nss_phys_if_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_phys_if_msg *nim) +{ + nss_tx_status_t status; + int ret = 0; + + down(&phif.sem); + + status = nss_phys_if_msg(nss_ctx, nim); + if(status != NSS_TX_SUCCESS) + { + nss_warning("%px: nss_phys_if_msg failed\n", nss_ctx); + up(&phif.sem); + return status; + } + + ret = wait_for_completion_timeout(&phif.complete, msecs_to_jiffies(NSS_PHYS_IF_TX_TIMEOUT)); + + if(!ret) + { + nss_warning("%px: phys_if tx failed due to timeout\n", nss_ctx); + phif.response = NSS_TX_FAILURE; + } + + status = phif.response; + up(&phif.sem); + + return status; +} + +/* + ********************************** + Register/Unregister/Miscellaneous APIs + ********************************** + */ + +/* + * nss_phys_if_register() + */ +struct nss_ctx_instance *nss_phys_if_register(uint32_t if_num, + nss_phys_if_rx_callback_t rx_callback, + nss_phys_if_msg_callback_t msg_callback, + struct net_device *netdev, + uint32_t features) +{ + uint8_t id = nss_top_main.phys_if_handler_id[if_num]; + struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[id]; + + nss_assert(nss_ctx); + nss_assert(if_num <= NSS_MAX_PHYSICAL_INTERFACES); + + nss_core_register_subsys_dp(nss_ctx, if_num, rx_callback, NULL, NULL, netdev, features); + + nss_top_main.phys_if_msg_callback[if_num] = msg_callback; + + nss_ctx->phys_if_mtu[if_num] = ETH_DATA_LEN; + return nss_ctx; +} + +/* + * nss_phys_if_unregister() + */ +void nss_phys_if_unregister(uint32_t if_num) +{ + uint8_t id = nss_top_main.phys_if_handler_id[if_num]; + struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[id]; + + nss_assert(nss_ctx); + nss_assert(if_num < NSS_MAX_PHYSICAL_INTERFACES); + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + + nss_top_main.phys_if_msg_callback[if_num] = NULL; + + nss_top_main.nss[0].phys_if_mtu[if_num] = 0; + nss_top_main.nss[1].phys_if_mtu[if_num] = 0; +} + +/* + * nss_phys_if_register_handler() + */ +void nss_phys_if_register_handler(struct nss_ctx_instance *nss_ctx, uint32_t if_num) +{ + uint32_t ret; + + ret = nss_core_register_handler(nss_ctx, if_num, nss_phys_if_msg_handler, NULL); + + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("Message handler FAILED to be registered for interface %d", if_num); + return; + } + + if(!nss_phys_if_sem_init_done) { + sema_init(&phif.sem, 1); + init_completion(&phif.complete); + nss_phys_if_sem_init_done = 1; + } +} + +/* + * nss_phys_if_open() + * Send open command to physical interface + */ +nss_tx_status_t nss_phys_if_open(struct nss_ctx_instance *nss_ctx, uint32_t tx_desc_ring, uint32_t rx_desc_ring, uint32_t mode, uint32_t if_num, uint32_t bypass_nw_process) +{ + struct nss_phys_if_msg nim; + struct nss_if_open *nio; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + nss_info("%px: Phys If Open, id:%d, TxDesc: %x, RxDesc: %x\n", nss_ctx, if_num, tx_desc_ring, rx_desc_ring); + + nss_cmn_msg_init(&nim.cm, if_num, NSS_PHYS_IF_OPEN, + sizeof(struct nss_if_open), nss_phys_if_callback, NULL); + + nio = &nim.msg.if_msg.open; + nio->tx_desc_ring = tx_desc_ring; + nio->rx_desc_ring = rx_desc_ring; + + if (mode == NSS_PHYS_IF_MODE0) { + nio->rx_forward_if = NSS_ETH_RX_INTERFACE; + nio->alignment_mode = NSS_IF_DATA_ALIGN_2BYTE; + } else if (mode == NSS_PHYS_IF_MODE1) { + nio->rx_forward_if = NSS_SJACK_INTERFACE; + nio->alignment_mode = NSS_IF_DATA_ALIGN_4BYTE; + } else if (mode == NSS_PHYS_IF_MODE2) { + nio->rx_forward_if = NSS_PORTID_INTERFACE; + nio->alignment_mode = NSS_IF_DATA_ALIGN_2BYTE; + } else { + nss_info("%px: Phys If Open, unknown mode %d\n", nss_ctx, mode); + return NSS_TX_FAILURE; + } + + /* + * If Network processing in NSS is bypassed + * update next hop and alignment accordingly + */ + if (bypass_nw_process) { + nio->rx_forward_if = NSS_N2H_INTERFACE; + nio->alignment_mode = NSS_IF_DATA_ALIGN_2BYTE; + } + + return nss_phys_if_msg_sync(nss_ctx, &nim); +} + +/* + * nss_phys_if_close() + * Send close command to physical interface + */ +nss_tx_status_t nss_phys_if_close(struct nss_ctx_instance *nss_ctx, uint32_t if_num) +{ + struct nss_phys_if_msg nim; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + nss_info("%px: Phys If Close, id:%d \n", nss_ctx, if_num); + + nss_cmn_msg_init(&nim.cm, if_num, NSS_PHYS_IF_CLOSE, + sizeof(struct nss_if_close), nss_phys_if_callback, NULL); + + return nss_phys_if_msg_sync(nss_ctx, &nim); +} + +/* + * nss_phys_if_link_state() + * Send link state to physical interface + */ +nss_tx_status_t nss_phys_if_link_state(struct nss_ctx_instance *nss_ctx, uint32_t link_state, uint32_t if_num) +{ + struct nss_phys_if_msg nim; + struct nss_if_link_state_notify *nils; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + nss_info("%px: Phys If Link State, id:%d, State: %x\n", nss_ctx, if_num, link_state); + + nss_cmn_msg_init(&nim.cm, if_num, NSS_PHYS_IF_LINK_STATE_NOTIFY, + sizeof(struct nss_if_link_state_notify), nss_phys_if_callback, NULL); + + nils = &nim.msg.if_msg.link_state_notify; + nils->state = link_state; + return nss_phys_if_msg_sync(nss_ctx, &nim); +} + +/* + * nss_phys_if_mac_addr() + * Send a MAC address to physical interface + */ +nss_tx_status_t nss_phys_if_mac_addr(struct nss_ctx_instance *nss_ctx, uint8_t *addr, uint32_t if_num) +{ + struct nss_phys_if_msg nim; + struct nss_if_mac_address_set *nmas; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + nss_info("%px: Phys If MAC Address, id:%d\n", nss_ctx, if_num); + nss_assert(addr != 0); + + nss_cmn_msg_init(&nim.cm, if_num, NSS_PHYS_IF_MAC_ADDR_SET, + sizeof(struct nss_if_mac_address_set), nss_phys_if_callback, NULL); + + nmas = &nim.msg.if_msg.mac_address_set; + memcpy(nmas->mac_addr, addr, ETH_ALEN); + return nss_phys_if_msg_sync(nss_ctx, &nim); +} + +/* + * nss_phys_if_change_mtu() + * Send a MTU change command + */ +nss_tx_status_t nss_phys_if_change_mtu(struct nss_ctx_instance *nss_ctx, uint32_t mtu, uint32_t if_num) +{ + struct nss_phys_if_msg nim; + struct nss_if_mtu_change *nimc; + uint16_t mtu_sz, max_mtu; + int i; + nss_tx_status_t status; + +/* + * We disallow MTU changes for low memory profiles in order to keep the buffer size constant + */ +#ifdef NSS_FIXED_BUFFER_SIZE + if (mtu > ETH_DATA_LEN) { + nss_info_always("MTU change beyond 1500 restricted for low memory profile \n"); + return NSS_TX_FAILURE; + } +#endif + NSS_VERIFY_CTX_MAGIC(nss_ctx); + nss_info("%px: Phys If Change MTU, id:%d, mtu=%d\n", nss_ctx, if_num, mtu); + + nss_cmn_msg_init(&nim.cm, if_num, NSS_PHYS_IF_MTU_CHANGE, + sizeof(struct nss_if_mtu_change), nss_phys_if_callback, NULL); + + nimc = &nim.msg.if_msg.mtu_change; + nimc->min_buf_size = mtu; + + status = nss_phys_if_msg_sync(nss_ctx, &nim); + if (status != NSS_TX_SUCCESS) { + return status; + } + + /* + * Update the mtu and max_buf_size accordingly + */ + nss_ctx->phys_if_mtu[if_num] = (uint16_t)mtu; + + /* + * Loop through MTU values of all Physical + * interfaces and get the maximum one of all + */ + max_mtu = nss_ctx->phys_if_mtu[0]; + for (i = 1; i < NSS_MAX_PHYSICAL_INTERFACES; i++) { + if (max_mtu < nss_ctx->phys_if_mtu[i]) { + max_mtu = nss_ctx->phys_if_mtu[i]; + } + } + + mtu_sz = nss_top_main.data_plane_ops->data_plane_get_mtu_sz(max_mtu); + +/* + * We need to ensure the max_buf_size for 256MB profile stays + * constant at NSS_EMPTY_BUFFER_SIZE. We do this by disallowing changes + * to it due to MTU changes. Also, NSS_EMPTY_BUFFER_SIZE includes the + * PAD and ETH_HLEN, and is aligned to SMP_CACHE_BYTES + */ +#ifndef NSS_FIXED_BUFFER_SIZE + nss_ctx->max_buf_size = ((mtu_sz + ETH_HLEN + SMP_CACHE_BYTES - 1) & ~(SMP_CACHE_BYTES - 1)) + NSS_NBUF_ETH_EXTRA + NSS_NBUF_PAD_EXTRA; + + /* + * max_buf_size should not be lesser than NSS_NBUF_PAYLOAD_SIZE + */ + if (nss_ctx->max_buf_size < NSS_NBUF_PAYLOAD_SIZE) { + nss_ctx->max_buf_size = NSS_NBUF_PAYLOAD_SIZE; + } +#else + nss_ctx->max_buf_size = NSS_EMPTY_BUFFER_SIZE; +#endif + +#if (NSS_SKB_REUSE_SUPPORT == 1) + if (nss_ctx->max_buf_size > nss_core_get_max_reuse()) + nss_core_set_max_reuse(ALIGN(nss_ctx->max_buf_size * 2, PAGE_SIZE)); +#endif + + nss_info("Current mtu:%u mtu_sz:%u max_buf_size:%d\n", mtu, mtu_sz, nss_ctx->max_buf_size); + + if (mtu_sz > nss_ctx->nss_top->prev_mtu_sz) { + + /* If crypto is enabled on platform + * Send the flush payloads message + */ + if (nss_ctx->nss_top->crypto_enabled) { + if (nss_n2h_flush_payloads(nss_ctx) != NSS_TX_SUCCESS) { + nss_info("Unable to send flush payloads command to NSS\n"); + } + } + } + nss_ctx->nss_top->prev_mtu_sz = mtu_sz; + + return status; +} + +/* + * nss_phys_if_vsi_assign() + * Send a vsi assign to physical interface + */ +nss_tx_status_t nss_phys_if_vsi_assign(struct nss_ctx_instance *nss_ctx, uint32_t vsi, uint32_t if_num) +{ + struct nss_phys_if_msg nim; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + nss_info("%px: Phys If VSI Assign, id:%d\n", nss_ctx, if_num); + + memset(&nim, 0, sizeof(struct nss_phys_if_msg)); + + nss_cmn_msg_init(&nim.cm, if_num, NSS_PHYS_IF_VSI_ASSIGN, + sizeof(struct nss_if_vsi_assign), nss_phys_if_callback, NULL); + + nim.msg.if_msg.vsi_assign.vsi = vsi; + return nss_phys_if_msg_sync(nss_ctx, &nim); +} + +/* + * nss_phys_if_vsi_unassign() + * Send a vsi unassign to physical interface + */ +nss_tx_status_t nss_phys_if_vsi_unassign(struct nss_ctx_instance *nss_ctx, uint32_t vsi, uint32_t if_num) +{ + struct nss_phys_if_msg nim; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + nss_info("%px: Phys If VSI Unassign, id:%d\n", nss_ctx, if_num); + + memset(&nim, 0, sizeof(struct nss_phys_if_msg)); + + nss_cmn_msg_init(&nim.cm, if_num, NSS_PHYS_IF_VSI_UNASSIGN, + sizeof(struct nss_if_vsi_unassign), nss_phys_if_callback, NULL); + + nim.msg.if_msg.vsi_unassign.vsi = vsi; + return nss_phys_if_msg_sync(nss_ctx, &nim); +} + +/* + * nss_phys_if_pause_on_off() + * Send a pause enabled/disabled message to GMAC + */ +nss_tx_status_t nss_phys_if_pause_on_off(struct nss_ctx_instance *nss_ctx, uint32_t pause_on, uint32_t if_num) +{ + struct nss_phys_if_msg nim; + struct nss_if_pause_on_off *nipe; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + nss_info("%px: phys if pause is set to %d, id:%d\n", nss_ctx, pause_on, if_num); + + nss_cmn_msg_init(&nim.cm, if_num, NSS_PHYS_IF_PAUSE_ON_OFF, + sizeof(struct nss_if_pause_on_off), nss_phys_if_callback, NULL); + + nipe = &nim.msg.if_msg.pause_on_off; + nipe->pause_on = pause_on; + + return nss_phys_if_msg_sync(nss_ctx, &nim); +} + +/* + * nss_phys_if_reset_nexthop() + * De-configures nexthop for an interface + */ +nss_tx_status_t nss_phys_if_reset_nexthop(struct nss_ctx_instance *nss_ctx, uint32_t if_num) +{ + struct nss_phys_if_msg nim; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + nss_cmn_msg_init(&nim.cm, if_num, NSS_PHYS_IF_RESET_NEXTHOP, + 0, nss_phys_if_callback, NULL); + + return nss_phys_if_msg_sync(nss_ctx, &nim); +} +EXPORT_SYMBOL(nss_phys_if_reset_nexthop); + +/* + * nss_phys_if_set_nexthop() + * Configures nexthop for an interface + */ +nss_tx_status_t nss_phys_if_set_nexthop(struct nss_ctx_instance *nss_ctx, uint32_t if_num, uint32_t nexthop) +{ + struct nss_phys_if_msg nim; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (nexthop >= NSS_MAX_NET_INTERFACES) { + nss_warning("%px: Invalid nexthop interface number: %d", nss_ctx, nexthop); + return NSS_TX_FAILURE_BAD_PARAM; + } + + nss_info("%px: Phys If nexthop will be set to %d, id:%d\n", nss_ctx, nexthop, if_num); + + nss_cmn_msg_init(&nim.cm, if_num, NSS_PHYS_IF_SET_NEXTHOP, + sizeof(struct nss_if_set_nexthop), nss_phys_if_callback, NULL); + nim.msg.if_msg.set_nexthop.nexthop = nexthop; + + return nss_phys_if_msg_sync(nss_ctx, &nim); +} +EXPORT_SYMBOL(nss_phys_if_set_nexthop); + +/* + * nss_get_state() + * Return the NSS initialization state + */ +nss_state_t nss_get_state(void *ctx) +{ + return nss_cmn_get_state(ctx); +} + +EXPORT_SYMBOL(nss_get_state); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_phys_if.h b/feeds/ipq807x/qca-nss-drv/src/nss_phys_if.h new file mode 100644 index 000000000..0df6bc32f --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_phys_if.h @@ -0,0 +1,326 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/** + * nss_phys_if + * Physical interface message structure + */ + +#ifndef __NSS_PHYS_IF_H +#define __NSS_PHYS_IF_H + +/** + * Physical IF + */ + +/** + * The NSS per-GMAC statistics sync structure. + */ +struct nss_phys_if_estats { + uint32_t rx_errors; /**< Number of RX errors */ + uint32_t rx_receive_errors; /**< Number of RX receive errors */ + uint32_t rx_descriptor_errors; /**< Number of RX descriptor errors */ + uint32_t rx_late_collision_errors; + /**< Number of RX late collision errors */ + uint32_t rx_dribble_bit_errors; /**< Number of RX dribble bit errors */ + uint32_t rx_length_errors; /**< Number of RX length errors */ + uint32_t rx_ip_header_errors; /**< Number of RX IP header errors */ + uint32_t rx_ip_payload_errors; /**< Number of RX IP payload errors */ + uint32_t rx_no_buffer_errors; /**< Number of RX no-buffer errors */ + uint32_t rx_transport_csum_bypassed; + /**< Number of RX packets where the transport checksum was bypassed */ + uint32_t tx_collisions; /**< Number of TX collisions */ + uint32_t tx_errors; /**< Number of TX errors */ + uint32_t tx_jabber_timeout_errors; + /**< Number of TX jabber timeout errors */ + uint32_t tx_frame_flushed_errors; + /**< Number of TX frame flushed errors */ + uint32_t tx_loss_of_carrier_errors; + /**< Number of TX loss of carrier errors */ + uint32_t tx_no_carrier_errors; /**< Number of TX no carrier errors */ + uint32_t tx_late_collision_errors; + /**< Number of TX late collision errors */ + uint32_t tx_excessive_collision_errors; + /**< Number of TX excessive collision errors */ + uint32_t tx_excessive_deferral_errors; + /**< Number of TX excessive deferral errors */ + uint32_t tx_underflow_errors; /**< Number of TX underflow errors */ + uint32_t tx_ip_header_errors; /**< Number of TX IP header errors */ + uint32_t tx_ip_payload_errors; /**< Number of TX IP payload errors */ + uint32_t tx_dropped; /**< Number of TX dropped packets */ + uint32_t hw_errs[10]; /**< GMAC DMA error counters */ + uint32_t rx_missed; /**< Number of RX packets missed by the DMA */ + uint32_t fifo_overflows; /**< Number of RX FIFO overflows signalled by the DMA */ + uint32_t rx_scatter_errors; /**< Number of scattered frames received by the DMA */ + uint32_t tx_ts_create_errors; /**< Number of tx timestamp creation errors */ + uint32_t gmac_total_ticks; /**< Total clock ticks spend inside the GMAC */ + uint32_t gmac_worst_case_ticks; /**< Worst case iteration of the GMAC in ticks */ + uint32_t gmac_iterations; /**< Number of iterations around the GMAC */ + uint32_t tx_pause_frames; /**< Number of pause frames sent by the GMAC */ + uint32_t mmc_rx_overflow_errors; + /**< Number of RX overflow errors */ + uint32_t mmc_rx_watchdog_timeout_errors; + /**< Number of RX watchdog timeout errors */ + uint32_t mmc_rx_crc_errors; /**< Number of RX CRC errors */ + uint32_t mmc_rx_ip_header_errors; + /**< Number of RX IP header errors */ + uint32_t mmc_rx_octets_g; /* Number of good octets received */ + uint32_t mmc_rx_ucast_frames; /* Number of Unicast frames received */ + uint32_t mmc_rx_bcast_frames; /* Number of Bcast frames received */ + uint32_t mmc_rx_mcast_frames; /* Number of Mcast frames received */ + uint32_t mmc_rx_undersize; /* Number of RX undersize frames */ + uint32_t mmc_rx_oversize; /* Number of RX oversize frames */ + uint32_t mmc_rx_jabber; /* Number of jabber frames */ + uint32_t mmc_rx_octets_gb; /* Number of good/bad octets */ + uint32_t mmc_rx_frag_frames_g; /* Number of good ipv4 frag frames */ + uint32_t mmc_tx_octets_g; /* Number of good octets sent */ + uint32_t mmc_tx_ucast_frames; /* Number of Unicast frames sent*/ + uint32_t mmc_tx_bcast_frames; /* Number of Broadcast frames sent */ + uint32_t mmc_tx_mcast_frames; /* Number of Multicast frames sent */ + uint32_t mmc_tx_deferred; /* Number of Deferred frames sent */ + uint32_t mmc_tx_single_col; /* Number of single collisions */ + uint32_t mmc_tx_multiple_col; /* Number of multiple collisions */ + uint32_t mmc_tx_octets_gb; /* Number of good/bad octets sent*/ +}; + +/** + * The NSS GMAC statistics sync structure. + */ +struct nss_phys_if_stats { + struct nss_cmn_node_stats if_stats; /**< Generic interface stats */ + struct nss_phys_if_estats estats; /**< Extended Statistics specific to GMAC */ +}; + +/** + * @brief Request/Response types + */ +enum nss_phys_if_msg_types { + NSS_PHYS_IF_OPEN = NSS_IF_OPEN, + NSS_PHYS_IF_CLOSE = NSS_IF_CLOSE, + NSS_PHYS_IF_LINK_STATE_NOTIFY = NSS_IF_LINK_STATE_NOTIFY, + NSS_PHYS_IF_MTU_CHANGE = NSS_IF_MTU_CHANGE, + NSS_PHYS_IF_MAC_ADDR_SET = NSS_IF_MAC_ADDR_SET, + NSS_PHYS_IF_STATS = NSS_IF_STATS, + NSS_PHYS_IF_ISHAPER_ASSIGN = NSS_IF_ISHAPER_ASSIGN, + NSS_PHYS_IF_BSHAPER_ASSIGN = NSS_IF_BSHAPER_ASSIGN, + NSS_PHYS_IF_ISHAPER_UNASSIGN = NSS_IF_ISHAPER_UNASSIGN, + NSS_PHYS_IF_BSHAPER_UNASSIGN = NSS_IF_BSHAPER_UNASSIGN, + NSS_PHYS_IF_ISHAPER_CONFIG = NSS_IF_ISHAPER_CONFIG, + NSS_PHYS_IF_BSHAPER_CONFIG = NSS_IF_BSHAPER_CONFIG, + NSS_PHYS_IF_PAUSE_ON_OFF = NSS_IF_PAUSE_ON_OFF, + NSS_PHYS_IF_VSI_ASSIGN = NSS_IF_VSI_ASSIGN, + NSS_PHYS_IF_VSI_UNASSIGN = NSS_IF_VSI_UNASSIGN, + NSS_PHYS_IF_SET_NEXTHOP = NSS_IF_SET_NEXTHOP, + NSS_PHYS_IF_RESET_NEXTHOP = NSS_IF_RESET_NEXTHOP, + NSS_PHYS_IF_EXTENDED_STATS_SYNC = NSS_IF_MAX_MSG_TYPES + 1, + NSS_PHYS_IF_MAX_MSG_TYPES +}; + +/** + * Message structure to send/receive physical interface commands + * + * NOTE: Do not adjust the location of if_msg relative to new + * message types as it represents the base messages for all + * intefaces. + */ +struct nss_phys_if_msg { + struct nss_cmn_msg cm; /**< Message Header */ + union { + union nss_if_msgs if_msg; /**< Interfaces messages */ + struct nss_phys_if_stats stats; /**< Phys If Statistics */ + } msg; +}; + +/** + * @brief Callback to receive physical interface messages + * + * @param app_data Application context for this message + * @param msg NSS physical interface message + * + * @return void + */ +typedef void (*nss_phys_if_msg_callback_t)(void *app_data, struct nss_phys_if_msg *msg); + +/** + * @brief Callback to send physical interface data to the tranmsit path. + * + * @param netdev Net device + * @param skb Data buffer + * + * @return void + */ +typedef void (*nss_phys_if_xmit_callback_t)(struct net_device *netdev, struct sk_buff *skb); + +/** + * @brief Callback to receive physical interface data + * TODO: Adjust to pass app_data as unknown to the + * list layer and netdev/sk as known. + * + * @param app_data Application context for this message + * @param os_buf Data buffer + * + * @return void + */ +typedef void (*nss_phys_if_rx_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * @brief Callback to recieve extended data plane packet on interface. + * + * @param app_data Application context for this message + * @param skb Data buffer + * @param napi napi pointer + * + * @return void + */ +typedef void (*nss_phys_if_rx_ext_data_callback_t)(struct net_device *netdev, struct sk_buff *skb, struct napi_struct *napi); + +/** + * @brief Register to send/receive GMAC packets/messages + * + * @param if_num GMAC i/f number + * @param rx_callback Receive callback for packets + * @param event_callback Receive callback for events + * @param netdev netdevice associated with this interface. + * @param features denote the skb types supported by this interface + * + * @return void* NSS context + */ +struct nss_ctx_instance *nss_phys_if_register(uint32_t if_num, + nss_phys_if_rx_callback_t rx_callback, + nss_phys_if_msg_callback_t msg_callback, + struct net_device *netdev, + uint32_t features); + +/** + * @brief Send GMAC packet + * + * @param nss_ctx NSS context + * @param os_buf OS buffer (e.g. skbuff) + * @param if_num GMAC i/f number + * + * @return nss_tx_status_t Tx status + */ +nss_tx_status_t nss_phys_if_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf, uint32_t if_num); + +/** + * @brief Send message to physical interface + * + * @param nim Physical interface message + * + * @return command Tx status + */ +nss_tx_status_t nss_phys_if_msg(struct nss_ctx_instance *nss_ctx, struct nss_phys_if_msg *nim); + +/** + * @brief Send a message to physical interface & wait for the response. + * + * @param nim Physical interface message + * + * @return command Tx status + */ +nss_tx_status_t nss_phys_if_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_phys_if_msg *nim); + +/** + * @brief Open GMAC interface on NSS + * + * @param nss_ctx NSS context + * @param tx_desc_ring Tx descriptor ring address + * @param rx_desc_ring Rx descriptor ring address + * @param if_num GMAC i/f number + * @param bypass_nw_process network processing in nss is bypassed for GMAC + * + * @return nss_tx_status_t Tx status + */ +nss_tx_status_t nss_phys_if_open(struct nss_ctx_instance *nss_ctx, uint32_t tx_desc_ring, uint32_t rx_desc_ring, uint32_t mode, uint32_t if_num, + uint32_t bypass_nw_process); + +/** + * @brief Close GMAC interface on NSS + * + * @param nss_ctx NSS context + * @param if_num GMAC i/f number + * + * @return nss_tx_status_t Tx status + */ +nss_tx_status_t nss_phys_if_close(struct nss_ctx_instance *nss_ctx, uint32_t if_num); + +/** + * @brief Send link state message to NSS + * + * @param nss_ctx NSS context + * @param link_state Link state + * @param if_num GMAC i/f number + * + * @return nss_tx_status_t Tx status + */ +nss_tx_status_t nss_phys_if_link_state(struct nss_ctx_instance *nss_ctx, uint32_t link_state, uint32_t if_num); + +/** + * @brief Send MAC address to NSS + * + * @param nss_ctx NSS context + * @param addr MAC address pointer + * @param if_num GMAC i/f number + * + * @return nss_tx_status_t Tx status + */ +nss_tx_status_t nss_phys_if_mac_addr(struct nss_ctx_instance *nss_ctx, uint8_t *addr, uint32_t if_num); + +/** + * @brief Send MTU change notification to NSS + * + * @param nss_ctx NSS context + * @param mtu MTU + * @param if_num GMAC i/f number + * + * @return nss_tx_status_t Tx status + */ +nss_tx_status_t nss_phys_if_change_mtu(struct nss_ctx_instance *nss_ctx, uint32_t mtu, uint32_t if_num); + +/** + * @brief Send vsi assign to NSS + * + * @param nss_ctx NSS context + * @param vsi VSI number + * @param if_num GMAC i/f number + * + * @return nss_tx_status_t Tx status + */ +nss_tx_status_t nss_phys_if_vsi_assign(struct nss_ctx_instance *nss_ctx, uint32_t vsi, uint32_t if_num); + +/** + * @brief Send vsi unassign to NSS + * + * @param nss_ctx NSS context + * @param vsi VSI number + * @param if_num GMAC i/f number + * + * @return nss_tx_status_t Tx status + */ +nss_tx_status_t nss_phys_if_vsi_unassign(struct nss_ctx_instance *nss_ctx, uint32_t vsi, uint32_t if_num); + +/** + * @brief Send pause frame enabled notification to NSS + * + * @param nss_ctx NSS context + * @param pause_on Pause on or off + * @param if_num GMAC i/f number + * + * @return nss_tx_status_t Tx status + */ +nss_tx_status_t nss_phys_if_pause_on_off(struct nss_ctx_instance *nss_ctx, uint32_t pause_on, uint32_t if_num); + +#endif /* __NSS_PHYS_IF_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_pm.c b/feeds/ipq807x/qca-nss-drv/src/nss_pm.c new file mode 100644 index 000000000..75527cddb --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_pm.c @@ -0,0 +1,447 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_pm.c + * NSS Power Management APIs + * + */ +#include +#include +#include +#include +#include + +#if (NSS_DT_SUPPORT != 1) +#include +#endif + +#if (NSS_PM_SUPPORT == 1) +#include "nss_pm.h" + +/* + * Global NSS PM structure + */ +struct nss_pm_global_ctx ctx; + +/* + * Bus vector table for GMAC driver + */ +static struct msm_bus_paths nss_gmac_bw_level_tbl[NSS_PM_PERF_MAX_LEVELS] = { + [NSS_PM_PERF_LEVEL_SUSPEND] = GMAC_BW_MBPS(0, 0), + /* 0 MHz to DDR, 0 MHz to TCM */ + [NSS_PM_PERF_LEVEL_IDLE] = GMAC_BW_MBPS(133, 5), + /* 133 MHz to DDR, 5 MHz to TCM */ + [NSS_PM_PERF_LEVEL_NOMINAL] = GMAC_BW_MBPS(200, 400), + /* 200 MHz to DDR, 10 MHz to TCM */ + [NSS_PM_PERF_LEVEL_TURBO] = GMAC_BW_MBPS(266, 533), + /* 266 MHz to DDR, 20 MHz to TCM */ +}; + +/* + * Bus vector table for Crypto driver + */ +static struct msm_bus_paths nss_crypto_bw_level_tbl[NSS_PM_PERF_MAX_LEVELS] = { + [NSS_PM_PERF_LEVEL_SUSPEND] = CRYPTO_BW_MBPS(0, 0), + /* 0 MHz to DDR, 0 MHz to TCM */ + [NSS_PM_PERF_LEVEL_IDLE] = CRYPTO_BW_MBPS(133, 5), + /* 133 MHz to DDR, 5 MHz to TCM */ + [NSS_PM_PERF_LEVEL_NOMINAL] = CRYPTO_BW_MBPS(200, 400), + /* 200 MHz to DDR, 10 MHz to TCM */ + [NSS_PM_PERF_LEVEL_TURBO] = CRYPTO_BW_MBPS(266, 533), + /* 266 MHz to DDR, 20 MHz to TCM */ +}; + +#ifdef NSS_PM_NETAP_GMAC_SCALING + +/* + * Bus vector table for NSS HLOS driver + * This requests bw for both NSS Fab0 and Fab1 on behalf of GMAC and NSS Drivers + */ +static struct msm_bus_paths nss_netap_bw_level_tbl[NSS_PM_PERF_MAX_LEVELS] = { + [NSS_PM_PERF_LEVEL_SUSPEND] = GMAC_BW_MBPS(0, 0), + /* 0 MHz to DDR, 0 MHz to TCM */ + [NSS_PM_PERF_LEVEL_IDLE] = GMAC_BW_MBPS(122, 122), + /* 133 MHz to DDR and TCM */ + [NSS_PM_PERF_LEVEL_NOMINAL] = GMAC_BW_MBPS(200, 200), + /* 400 MHz to DDR and TCM */ + [NSS_PM_PERF_LEVEL_TURBO] = GMAC_BW_MBPS(400, 400), + /* 533 MHz to DDR and TCM */ +}; + +#else + +/* + * Bus vector table for NSS HLOS driver + */ +static struct msm_bus_paths nss_netap_bw_level_tbl[NSS_PM_PERF_MAX_LEVELS] = { + [NSS_PM_PERF_LEVEL_SUSPEND] = NETAP_BW_MBPS(0, 0), + /* 0 MHz to DDR, 0 MHz to TCM */ + [NSS_PM_PERF_LEVEL_IDLE] = NETAP_BW_MBPS(133, 133), + /* 133 MHz to DDR and TCM */ + [NSS_PM_PERF_LEVEL_NOMINAL] = NETAP_BW_MBPS(400, 400), + /* 400 MHz to DDR and TCM */ + [NSS_PM_PERF_LEVEL_TURBO] = NETAP_BW_MBPS(533, 533), + /* 533 MHz to DDR and TCM */ +}; + +#endif + +/* + * Bus Driver Platform data for GMAC, Crypto and Netap clients + */ +static struct msm_bus_scale_pdata nss_bus_scale[] = { + [NSS_PM_CLIENT_GMAC] = { + .usecase = nss_gmac_bw_level_tbl, + .num_usecases = ARRAY_SIZE(nss_gmac_bw_level_tbl), + .active_only = 1, + .name = "qca-nss-gmac", + }, + + [NSS_PM_CLIENT_CRYPTO] = { + .usecase = nss_crypto_bw_level_tbl, + .num_usecases = ARRAY_SIZE(nss_crypto_bw_level_tbl), + .active_only = 1, + .name = "qca-nss-crypto", + }, + + [NSS_PM_CLIENT_NETAP] = { + .usecase = nss_netap_bw_level_tbl, + .num_usecases = ARRAY_SIZE(nss_netap_bw_level_tbl), + .active_only = 1, + .name = "qca-nss-drv", + }, +}; + +/* + * nss_pm_dbg_perf_level_get + * debugfs hook to get the current performance level + */ +static int nss_pm_dbg_perf_level_get(void *data, u64 *val) +{ + nss_pm_client_data_t *pm_client; + + pm_client = (nss_pm_client_data_t *)data; + *val = pm_client->current_perf_lvl; + + return NSS_PM_API_SUCCESS; +} + +/* + * nss_pm_dbg_autoscale_get + * debugfs hook to get the current autoscale setting + */ +static int nss_pm_dbg_autoscale_get(void *data, u64 *val) +{ + nss_pm_client_data_t *pm_client; + + pm_client = (nss_pm_client_data_t *)data; + *val = pm_client->auto_scale; + + return NSS_PM_API_SUCCESS; +} + +/* + * nss_pm_dbg_perf_level_set + * debugfs hook to set perf level for a client + */ +static int nss_pm_dbg_perf_level_set(void *data, u64 val) +{ + uint32_t perf_level; + + perf_level = (uint32_t) val; + + if (perf_level >= NSS_PM_PERF_MAX_LEVELS || + perf_level < NSS_PM_PERF_LEVEL_IDLE) { + nss_pm_warning("unsupported performance level %d \n", perf_level); + return NSS_PM_API_FAILED; + } + + nss_pm_set_perf_level(data, perf_level); + return NSS_PM_API_SUCCESS; +} + +/* + * nss_pm_dbg_autoscale_set + * debugfs hook to enable auto scaling for a client + */ +static int nss_pm_dbg_autoscale_set(void *data, u64 val) +{ + nss_pm_client_data_t *pm_client; + + if (val > 1) { + nss_pm_warning(" Invalid set value, valid values are 0/1 \n"); + return NSS_PM_API_FAILED; + } + + pm_client->auto_scale = (uint32_t)val; + return NSS_PM_API_SUCCESS; +} + +DEFINE_SIMPLE_ATTRIBUTE(perf_level_fops, nss_pm_dbg_perf_level_get, nss_pm_dbg_perf_level_set, "%llu\n"); + +DEFINE_SIMPLE_ATTRIBUTE(autoscale_fops, nss_pm_dbg_autoscale_get, nss_pm_dbg_autoscale_set, "%llu\n"); +#endif /** (NSS_PM_SUPPORT == 1) */ + +/* + * nss_pm_client_register + * Initialize GMAC specific PM parameters + * + * Creates debugfs hooks for user-space control of NSS Client PM + * Initializes Bus BW to Idle Perf level + * Returns PM handle to the caller. + * + */ +void *nss_pm_client_register(nss_pm_client_t client_id) +{ +#if (NSS_PM_SUPPORT == 1) + int ret; + struct dentry *pm_dentry; + nss_pm_client_data_t *pm_client; + + if (unlikely(client_id >= NSS_PM_MAX_CLIENTS)) { + nss_pm_warning("nss_pm_client_register invalid client id %d \n", client_id); + goto error; + } + + pm_client = &ctx.nss_pm_client[client_id]; + + pm_client->bus_perf_client = msm_bus_scale_register_client(&nss_bus_scale[client_id]); + if (!pm_client->bus_perf_client) { + nss_pm_warning("unable to register bus client \n"); + goto error; + } + + ret = msm_bus_scale_client_update_request(pm_client->bus_perf_client, NSS_PM_PERF_LEVEL_IDLE); + if (ret) { + nss_pm_warning("initial bandwidth req failed (%d)\n", ret); + msm_bus_scale_unregister_client((uint32_t) pm_client->bus_perf_client); + goto error; + } + + pm_client->current_perf_lvl = NSS_PM_PERF_LEVEL_IDLE; + + switch (client_id) { + case NSS_PM_CLIENT_GMAC: + pm_dentry = debugfs_create_dir("gmac" , ctx.pm_dentry); + break; + + case NSS_PM_CLIENT_CRYPTO: + pm_dentry = debugfs_create_dir("crypto" , ctx.pm_dentry); + break; + + case NSS_PM_CLIENT_NETAP: + pm_dentry = debugfs_create_dir("netap" , ctx.pm_dentry); + break; + + default: + nss_pm_warning("debugfs create failed invalid client id %d \n", client_id); + msm_bus_scale_unregister_client((uint32_t) pm_client->bus_perf_client); + goto error; + + } + + if (unlikely(pm_dentry == NULL)) { + nss_pm_info("debugfs not created for %d client pm \n", client_id); + goto out; + } + + pm_client->dentry = pm_dentry; + pm_client->client_id = client_id; + + if (!debugfs_create_file("perf_level", S_IRUGO | S_IWUSR, pm_dentry, pm_client, &perf_level_fops)) { + nss_pm_info("debugfs perf_level file not created for %d client pm \n", client_id); + } + + if (!debugfs_create_file("auto-scale", S_IRUGO | S_IWUSR, pm_dentry, pm_client, &autoscale_fops)) { + nss_pm_info("debugfs auto-scale file not created for %d client pm \n", client_id); + } + +out: + return (void *)pm_client; +error: +#endif + return NULL; +} +EXPORT_SYMBOL(nss_pm_client_register); + +/* + * nss_pm_client_unregister + * Unregister the client for any PM operations + */ +int nss_pm_client_unregister(nss_pm_client_t client_id) +{ +#if (NSS_PM_SUPPORT == 1) + nss_pm_client_data_t *pm_client; + + if (unlikely(client_id >= NSS_PM_MAX_CLIENTS)) { + nss_pm_warning("nss_pm_client_unregister invalid client id %d \n", client_id); + goto error; + } + + pm_client = &ctx.nss_pm_client[client_id]; + + if (unlikely(pm_client == NULL)) { + nss_pm_warning("nss_pm_client_unregister client not registered %d \n", client_id); + goto error; + } + + if (pm_client->bus_perf_client) { + msm_bus_scale_unregister_client((uint32_t) pm_client->bus_perf_client); + } else { + nss_pm_info("nss_pm_client_unregister: client not registered \n"); + } + + if (likely(pm_client->dentry != NULL)) { + debugfs_remove_recursive(pm_client->dentry); + } + + return NSS_PM_API_SUCCESS; + +error: +#endif + return NSS_PM_API_FAILED; +} + +/* + * nss_pm_set_perf_level() + * Sets the performance level of client specific Fabrics and Clocks to requested level + */ +nss_pm_interface_status_t nss_pm_set_perf_level(void *handle, nss_pm_perf_level_t lvl) +{ +#if ((NSS_DT_SUPPORT == 1) && (NSS_FREQ_SCALE_SUPPORT == 1)) + nss_freq_scales_t index; + + switch (lvl) { + case NSS_PM_PERF_LEVEL_TURBO: + index = NSS_FREQ_HIGH_SCALE; + break; + + case NSS_PM_PERF_LEVEL_NOMINAL: + index = NSS_FREQ_MID_SCALE; + break; + + default: + index = NSS_PM_PERF_LEVEL_IDLE; + } + +#if !defined(NSS_HAL_IPQ807x_SUPPORT) + nss_freq_sched_change(index, false); +#endif + +#elif (NSS_PM_SUPPORT == 1) + + int ret = 0; + nss_pm_client_data_t *pm_client; + + pm_client = (nss_pm_client_data_t *) handle; + if (pm_client->current_perf_lvl == lvl) { + nss_pm_trace("Already at perf level %d , ignoring request \n", lvl); + return NSS_PM_API_SUCCESS; + } + + if (!pm_client->bus_perf_client) { + nss_pm_warning("Bus driver client not registered.request failed \n"); + return NSS_PM_API_FAILED; + } + + /* + * Do client specific operations here + */ + if (pm_client->client_id == NSS_PM_CLIENT_NETAP) { + if ((lvl == NSS_PM_PERF_LEVEL_TURBO) && (ctx.turbo_support == true)) { + /* + * For turbo perf level, switch TCM source to + * SRC1 to set TCM clock = 400 MHz + * SRC0 and SRC1 are set to 266 and 400 MHz resp. + * in nss_hal/ipq806x/nss_hal_pvt.c + */ + writel(0x3, NSSTCM_CLK_SRC_CTL); + } else { + /* + * For Nominal and Idle perf level, switch to SRC0 to + * set TCM clock = 266 MHz + */ + writel(0x2, NSSTCM_CLK_SRC_CTL); + + if (lvl == NSS_PM_PERF_LEVEL_TURBO) { + lvl = NSS_PM_PERF_LEVEL_NOMINAL; + } + } + } + + if (pm_client->client_id == NSS_PM_CLIENT_CRYPTO) { + if ((lvl == NSS_PM_PERF_LEVEL_TURBO) && (ctx.turbo_support == true)) { + /* + * For Turbo mode, set Crypto core and + * Fabric port clocks to 213 MHz + */ + writel(0x23, CE5_ACLK_SRC0_NS); + writel(0x23, CE5_HCLK_SRC0_NS); + writel(0x23, CE5_CORE_CLK_SRC0_NS); + + writel(0x2, CE5_ACLK_SRC_CTL); + writel(0x2, CE5_HCLK_SRC_CTL); + writel(0x2, CE5_CORE_CLK_SRC_CTL); + } else { + lvl = NSS_PM_PERF_LEVEL_NOMINAL; + } + } + + /* Update bandwidth if request has changed. This may sleep. */ + ret = msm_bus_scale_client_update_request(pm_client->bus_perf_client, lvl); + if (ret) { + nss_pm_warning("bandwidth request failed (%d)\n", ret); + return NSS_PM_API_FAILED; + } + + nss_pm_info("perf level request, current: %d new: %d \n", pm_client->current_perf_lvl, lvl); + pm_client->current_perf_lvl = lvl; +#endif + + return NSS_PM_API_SUCCESS; +} +EXPORT_SYMBOL(nss_pm_set_perf_level); + +#if (NSS_PM_SUPPORT == 1) +/* + * nss_pm_set_turbo() + * Sets the turbo support flag globally for all clients + */ +void nss_pm_set_turbo() { + + nss_pm_info("NSS Bus PM - Platform supports Turbo Mode \n"); + ctx.turbo_support = true; +} + +/* + * nss_pm_init() + * Initialize NSS PM top level structures + */ +void nss_pm_init(void) { + + nss_pm_info("NSS Bus PM (platform - IPQ806x, build - %s:%s)\n", __DATE__, __TIME__); + + ctx.pm_dentry = debugfs_create_dir("qca-nss-pm", NULL); + + /* Default turbo support is set to off */ + ctx.turbo_support = false; + + if (unlikely(ctx.pm_dentry == NULL)) { + nss_pm_warning("Failed to create qca-nss-drv directory in debugfs"); + } +} +#endif diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_pm.h b/feeds/ipq807x/qca-nss-drv/src/nss_pm.h new file mode 100644 index 000000000..aaca293cb --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_pm.h @@ -0,0 +1,164 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_pm.h + * NSS PM Driver header file + */ + +#ifndef __NSS_PM_H +#define __NSS_PM_H + +#include + +#include +#include +#include +#include + +#include + +/* + * NSS PM debug macros + */ +#if (NSS_PM_DEBUG_LEVEL < 1) +#define nss_pm_assert(fmt, args...) +#else +#define nss_pm_assert(c) if (!(c)) { BUG_ON(!(c)); } +#endif + +#if (NSS_PM_DEBUG_LEVEL < 2) +#define nss_pm_warning(fmt, args...) +#else +#define nss_pm_warning(fmt, args...) printk(KERN_WARNING "nss_pm:"fmt, ##args) +#endif + +#if (NSS_PM_DEBUG_LEVEL < 3) +#define nss_pm_info(fmt, args...) +#else +#define nss_pm_info(fmt, args...) printk(KERN_INFO "nss_pm:"fmt, ##args) +#endif + +#if (NSS_PM_DEBUG_LEVEL < 4) +#define nss_pm_trace(fmt, args...) +#else +#define nss_pm_trace(fmt, args...) printk(KERN_DEBUG "nss_pm:"fmt, ##args) +#endif + +/* + * Define this to use NETAP driver also request for NSS Fab1 BW on behalf of GMAC driver + */ +#define NSS_PM_NETAP_GMAC_SCALING 1 + +/* + * PM Client data structure + */ +typedef struct { + uint32_t bus_perf_client; + uint32_t clk_handle; + uint32_t current_perf_lvl; + uint32_t auto_scale; + struct dentry *dentry; + nss_pm_client_t client_id; +} nss_pm_client_data_t; + +/* + * NSS PM driver context + */ +struct nss_pm_global_ctx { + struct dentry *pm_dentry; + bool turbo_support; + nss_pm_client_data_t nss_pm_client[NSS_PM_MAX_CLIENTS]; +}; + +/* + * Macro defining Bus vector for GMAC driver + */ +#define GMAC_BW_MBPS(_data_bw, _desc_bw) \ +{ \ + .vectors = (struct msm_bus_vectors[]){ \ + {\ + .src = MSM_BUS_MASTER_NSS_GMAC_0, \ + .dst = MSM_BUS_SLAVE_EBI_CH0, \ + .ab = (_data_bw) * 16 * 1000000ULL, \ + .ib = (_data_bw) * 16 * 1000000ULL, \ + }, \ + { \ + .src = MSM_BUS_MASTER_NSS_GMAC_0, \ + .dst = MSM_BUS_SLAVE_NSS_TCM, \ + .ab = (_desc_bw) * 8 * 1000000ULL, \ + .ib = (_desc_bw) * 8 * 1000000ULL, \ + }, \ + }, \ + .num_paths = 2, \ +} + +/* + * Macro defining Bus vector for NSS crypto driver + */ +#define CRYPTO_BW_MBPS(_data_bw, _desc_bw) \ +{ \ + .vectors = (struct msm_bus_vectors[]){ \ + {\ + .src = MSM_BUS_MASTER_NSS_CRYPTO5_0, \ + .dst = MSM_BUS_SLAVE_EBI_CH0, \ + .ab = 0, \ + .ib = 0, \ + }, \ + { \ + .src = MSM_BUS_MASTER_NSS_CRYPTO5_0, \ + .dst = MSM_BUS_SLAVE_NSS_TCM, \ + .ab = (_desc_bw) * 8 * 1000000ULL, \ + .ib = (_desc_bw) * 8 * 1000000ULL, \ + }, \ + }, \ + .num_paths = 2, \ +} + +/* + * Macro defining Bus vector for NSS driver + * + */ +#define NETAP_BW_MBPS(_data_bw, _desc_bw) \ +{ \ + .vectors = (struct msm_bus_vectors[]){ \ + {\ + .src = MSM_BUS_MASTER_UBI32_0, \ + .dst = MSM_BUS_SLAVE_EBI_CH0, \ + .ab = (_data_bw) * 16 * 1000000ULL, \ + .ib = (_data_bw) * 16 * 1000000ULL, \ + }, \ + { \ + .src = MSM_BUS_MASTER_UBI32_0, \ + .dst = MSM_BUS_SLAVE_NSS_TCM, \ + .ab = (_desc_bw) * 8 * 1000000ULL, \ + .ib = (_desc_bw) * 8 * 1000000ULL, \ + }, \ + }, \ + .num_paths = 2, \ +} + +/* + * Initialize NSS PM top level structures + */ +void nss_pm_init(void); + +/* + * Sets the turbo support flag globally for all PM clients + */ +void nss_pm_set_turbo(void); + +#endif /** __NSS_PM_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_portid.c b/feeds/ipq807x/qca-nss-drv/src/nss_portid.c new file mode 100644 index 000000000..65982f09a --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_portid.c @@ -0,0 +1,423 @@ +/* + ************************************************************************** + * Copyright (c) 2015-2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_portid_stats.h" +#include "nss_portid_log.h" + +/* + * Spinlock to protect portid interface create/destroy/update + */ +DEFINE_SPINLOCK(nss_portid_spinlock); + +#define NSS_PORTID_TX_TIMEOUT 3000 /* 3 Seconds */ + +/* + * Private data structure for phys_if interface + */ +static struct nss_portid_pvt { + struct semaphore sem; + struct completion complete; + int response; +} pid; + +/* + * Array of portid interface handles. Indexing based on the physical port_id + */ +struct nss_portid_handle nss_portid_hdl[NSS_PORTID_MAX_SWITCH_PORT]; + +/* + * nss_portid_handler() + * Handle NSS -> HLOS messages for portid + */ +static void nss_portid_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, + __attribute__((unused))void *app_data) +{ + nss_portid_msg_callback_t cb; + struct nss_portid_msg *npm = (struct nss_portid_msg *)ncm; + + BUG_ON(ncm->interface != NSS_PORTID_INTERFACE); + + /* + * Trace Messages + */ + nss_portid_log_rx_msg(npm); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_PORTID_MAX_MSG_TYPE) { + nss_warning("%px: received invalid message %d for portid interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_portid_msg)) { + nss_warning("%px: message size incorrect: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + switch (ncm->type) { + case NSS_PORTID_STATS_SYNC_MSG: + /* + * Update portid statistics. + */ + nss_portid_stats_sync(nss_ctx, &npm->msg.stats_sync); + break; + } + + /* + * Update the callback and app_data for NOTIFY messages, portid sends all notify messages + * to the same callback/app_data. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_core_get_msg_handler(nss_ctx, ncm->interface); + ncm->app_data = (nss_ptr_t)nss_ctx->subsys_dp_register[ncm->interface].ndev; + } + + /* + * Do we have a call back + */ + if (!ncm->cb) { + return; + } + + /* + * callback + */ + cb = (nss_portid_msg_callback_t)ncm->cb; + + cb((void *)ncm->app_data, npm); +} + +/* + * nss_portid_get_ctx() + * Return a portid's NSS context. + */ +struct nss_ctx_instance *nss_portid_get_ctx(void) +{ + struct nss_ctx_instance *nss_ctx; + + nss_ctx = &nss_top_main.nss[nss_top_main.portid_handler_id]; + return nss_ctx; +} + +/* + * nss_portid_verify_if_num() + * Verify if_num passed to us. + */ +static bool nss_portid_verify_if_num(uint32_t if_num) +{ + if (nss_is_dynamic_interface(if_num) == false) { + return false; + } + + if (nss_dynamic_interface_get_type(nss_portid_get_ctx(), if_num) != NSS_DYNAMIC_INTERFACE_TYPE_PORTID) { + return false; + } + + return true; +} + +/* + * nss_portid_get_stats() + * API for getting stats from a port interface + */ +bool nss_portid_get_stats(uint32_t if_num, struct rtnl_link_stats64 *stats) +{ + int i; + + spin_lock_bh(&nss_portid_spinlock); + for (i = 0; i < NSS_PORTID_MAX_SWITCH_PORT; i++) { + if (nss_portid_hdl[i].if_num == if_num) { + memcpy(stats, &nss_portid_hdl[i].stats, sizeof(*stats)); + spin_unlock_bh(&nss_portid_spinlock); + return true; + } + } + spin_unlock_bh(&nss_portid_spinlock); + return false; +} +EXPORT_SYMBOL(nss_portid_get_stats); + +/* + * nss_portid_if_tx_data() + * Transmit data buffer (skb) to a NSS interface number + */ +nss_tx_status_t nss_portid_if_tx_data(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf, uint32_t if_num) +{ + return nss_if_tx_buf(nss_ctx, os_buf, if_num); +} +EXPORT_SYMBOL(nss_portid_if_tx_data); + +/* + * nss_portid_tx_msg() + * Transmit a portid message to NSSFW + */ +nss_tx_status_t nss_portid_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_portid_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Trace Messages + */ + nss_portid_log_tx_msg(msg); + + /* + * Sanity check the message + */ + if (ncm->interface != NSS_PORTID_INTERFACE) { + nss_warning("%px: tx request for another interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type > NSS_PORTID_MAX_MSG_TYPE) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_portid_tx_msg); + +/* + * nss_portid_callback + * Callback to handle the completion of NSS ->HLOS messages. + */ +static void nss_portid_callback(void *app_data, struct nss_portid_msg *npm) +{ + if(npm->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("portid error response %d\n", npm->cm.response); + pid.response = NSS_TX_FAILURE; + complete(&pid.complete); + return; + } + + pid.response = NSS_TX_SUCCESS; + complete(&pid.complete); +} + +/* + * nss_portid_tx_msg_sync() + * Send a message to portid interface & wait for the response. + */ +nss_tx_status_t nss_portid_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_portid_msg *msg) +{ + nss_tx_status_t status; + int ret = 0; + + down(&pid.sem); + + status = nss_portid_tx_msg(nss_ctx, msg); + if(status != NSS_TX_SUCCESS) + { + nss_warning("%px: nss_phys_if_msg failed\n", nss_ctx); + up(&pid.sem); + return status; + } + + ret = wait_for_completion_timeout(&pid.complete, msecs_to_jiffies(NSS_PORTID_TX_TIMEOUT)); + + if(!ret) + { + nss_warning("%px: portid tx failed due to timeout\n", nss_ctx); + pid.response = NSS_TX_FAILURE; + } + + status = pid.response; + up(&pid.sem); + + return status; +} +EXPORT_SYMBOL(nss_portid_tx_msg_sync); + +/* + * nss_portid_msg_init() + * Initialize portid message. + */ +void nss_portid_msg_init(struct nss_portid_msg *npm, uint16_t if_num, uint32_t type, uint32_t len, + nss_portid_msg_callback_t cb, void *app_data) +{ + nss_cmn_msg_init(&npm->cm, if_num, type, len, (void*)cb, app_data); +} +EXPORT_SYMBOL(nss_portid_msg_init); + +/* + * nss_portid_tx_configure_port_if_msg + * API to send configure port message to NSS FW + */ +nss_tx_status_t nss_portid_tx_configure_port_if_msg(struct nss_ctx_instance *nss_ctx, uint32_t port_if_num, uint8_t port_id, uint8_t gmac_id) +{ + struct nss_portid_msg npm; + struct nss_portid_configure_msg *npcm; + + if (nss_portid_verify_if_num(port_if_num) == false) { + nss_warning("received invalid interface %d", port_if_num); + return NSS_TX_FAILURE; + } + + if (port_id >= NSS_PORTID_MAX_SWITCH_PORT) { + nss_warning("port_id %d exceeds NSS_PORTID_MAX_SWITCH_PORT\n", port_id); + return NSS_TX_FAILURE; + } + + if (gmac_id >= NSS_MAX_PHYSICAL_INTERFACES) { + nss_warning("gmac_id %d not valid\n", gmac_id); + return NSS_TX_FAILURE; + } + + /* + * Prepare message to configure a port interface + */ + npcm = &npm.msg.configure; + npcm->port_if_num = port_if_num; + npcm->port_id = port_id; + npcm->gmac_id = gmac_id; + + nss_portid_msg_init(&npm, NSS_PORTID_INTERFACE, NSS_PORTID_CONFIGURE_MSG, + sizeof(struct nss_portid_configure_msg), nss_portid_callback, NULL); + nss_info("Dynamic interface allocated, sending message to FW with port_if_num %d port_id %d gmac_id %d\n", + npcm->port_if_num, npcm->port_id, npcm->gmac_id); + return nss_portid_tx_msg_sync(nss_ctx, &npm); +} +EXPORT_SYMBOL(nss_portid_tx_configure_port_if_msg); + +/* + * nss_portid_tx_unconfigure_port_if_msg + * API to send unconfigure port message to NSS FW + */ +nss_tx_status_t nss_portid_tx_unconfigure_port_if_msg(struct nss_ctx_instance *nss_ctx, uint32_t port_if_num, uint8_t port_id) +{ + struct nss_portid_msg npm; + struct nss_portid_unconfigure_msg *npum; + + if (nss_portid_verify_if_num(port_if_num) == false) { + nss_warning("received invalid interface %d", port_if_num); + return NSS_TX_FAILURE; + } + + if (port_id >= NSS_PORTID_MAX_SWITCH_PORT) { + nss_warning("port_id %d exceeds NSS_PORTID_MAX_SWITCH_PORT\n", port_id); + return NSS_TX_FAILURE; + } + + /* + * Prepare message to unconfigure a port interface + */ + npum = &npm.msg.unconfigure; + npum->port_if_num = port_if_num; + npum->port_id = port_id; + + nss_portid_msg_init(&npm, NSS_PORTID_INTERFACE, NSS_PORTID_UNCONFIGURE_MSG, + sizeof(struct nss_portid_configure_msg), nss_portid_callback, NULL); + + return nss_portid_tx_msg_sync(nss_ctx, &npm); +} +EXPORT_SYMBOL(nss_portid_tx_unconfigure_port_if_msg); + +/* + * nss_portid_register_port_if() + * Register with portid node and get back nss_ctx + */ +struct nss_ctx_instance *nss_portid_register_port_if(uint32_t if_num, uint32_t port_id, struct net_device *netdev, + nss_portid_buf_callback_t buf_callback) +{ + struct nss_ctx_instance *nss_ctx = nss_portid_get_ctx(); + + if (nss_portid_verify_if_num(if_num) == false) { + nss_warning("nss portid register received invalid interface %d", if_num); + return NULL; + } + + if (port_id >= NSS_PORTID_MAX_SWITCH_PORT) { + nss_warning("nss portid register received invalid port number %d", port_id); + return NULL; + } + + spin_lock(&nss_portid_spinlock); + if (nss_portid_hdl[port_id].if_num != 0) { + nss_warning("nss portid failed: port already registered %d", port_id); + spin_unlock(&nss_portid_spinlock); + return NULL; + } + nss_portid_hdl[port_id].if_num = if_num; + spin_unlock(&nss_portid_spinlock); + + nss_core_register_subsys_dp(nss_ctx, if_num, buf_callback, NULL, NULL, netdev, 0); + + return nss_ctx; +} +EXPORT_SYMBOL(nss_portid_register_port_if); + +/* + * nss_portid_unregister_port_if() + * Unregister portid node with NSS FW + */ +bool nss_portid_unregister_port_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx; + int i; + + nss_ctx = nss_portid_get_ctx(); + if (nss_portid_verify_if_num(if_num) == false) { + nss_warning("%px: unregister received for invalid interface %d", nss_ctx, if_num); + return false; + } + + spin_lock(&nss_portid_spinlock); + for (i = 0; i < NSS_PORTID_MAX_SWITCH_PORT; i++) { + if (nss_portid_hdl[i].if_num == if_num) { + nss_portid_hdl[i].if_num = 0; + } + } + spin_unlock(&nss_portid_spinlock); + + nss_core_unregister_handler(nss_ctx, if_num); + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + + return true; +} +EXPORT_SYMBOL(nss_portid_unregister_port_if); + +/* + * nss_portid_init() + * Initializes portid node. Gets called from nss_init.c + */ +void nss_portid_init(void) +{ + memset(&nss_portid_hdl, 0, sizeof(struct nss_portid_handle) * NSS_PORTID_MAX_SWITCH_PORT); +} + +/* + * nss_portid_register_handler() + * Registering handler for sending msg to portid node on NSS. + */ +void nss_portid_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx = nss_portid_get_ctx(); + + nss_core_register_handler(nss_ctx, NSS_PORTID_INTERFACE, nss_portid_handler, NULL); + + nss_portid_stats_dentry_create(); + + sema_init(&pid.sem, 1); + init_completion(&pid.complete); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_portid_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_portid_log.c new file mode 100644 index 000000000..700e1181b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_portid_log.c @@ -0,0 +1,129 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_portid_log.c + * NSS PORTID logger file. + */ + +#include "nss_core.h" + +/* + * nss_portid_log_message_types_str + * NSS PORTID message strings + */ +static int8_t *nss_portid_log_message_types_str[NSS_PORTID_MAX_MSG_TYPE] __maybe_unused = { + "PORTID Configure", + "PORTID Unconfigure", + "PORTID Stats", +}; + +/* + * nss_portid_log_configure_msg() + * Log NSS PORTID Configure. + */ +static void nss_portid_log_configure_msg(struct nss_portid_msg *npm) +{ + struct nss_portid_configure_msg *npcm __maybe_unused = &npm->msg.configure; + nss_trace("%px: NSS PORTID Configure message \n" + "PORTID Interface Number: %d\n" + "PORTID Interface ID: %d\n" + "PORTID GMAC ID: %d\n", + npcm, npcm->port_if_num, + npcm->port_id, npcm->gmac_id); +} + +/* + * nss_portid_log_unconfigure_msg() + * Log NSS PORTID Unconfigure. + */ +static void nss_portid_log_unconfigure_msg(struct nss_portid_msg *npm) +{ + struct nss_portid_unconfigure_msg *npum __maybe_unused = &npm->msg.unconfigure; + nss_trace("%px: NSS PORTID Configure message \n" + "PORTID Interface Number: %d\n" + "PORTID Interface ID: %d\n", + npum, npum->port_if_num, + npum->port_id); +} + +/* + * nss_portid_log_verbose() + * Log message contents. + */ +static void nss_portid_log_verbose(struct nss_portid_msg *npm) +{ + switch (npm->cm.type) { + case NSS_PORTID_CONFIGURE_MSG: + nss_portid_log_configure_msg(npm); + break; + + case NSS_PORTID_UNCONFIGURE_MSG: + nss_portid_log_unconfigure_msg(npm); + break; + + case NSS_PORTID_STATS_SYNC_MSG: + /* + * No log for valid stats message. + */ + break; + + default: + nss_trace("%px: Invalid message type\n", npm); + break; + } +} + +/* + * nss_portid_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_portid_log_tx_msg(struct nss_portid_msg *npm) +{ + if (npm->cm.type >= NSS_PORTID_MAX_MSG_TYPE) { + nss_warning("%px: Invalid message type\n", npm); + return; + } + + nss_info("%px: type[%d]:%s\n", npm, npm->cm.type, nss_portid_log_message_types_str[npm->cm.type]); + nss_portid_log_verbose(npm); +} + +/* + * nss_portid_log_rx_msg() + * Log messages received from FW. + */ +void nss_portid_log_rx_msg(struct nss_portid_msg *npm) +{ + if (npm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", npm); + return; + } + + if (npm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (npm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", npm, npm->cm.type, + nss_portid_log_message_types_str[npm->cm.type], + npm->cm.response, nss_cmn_response_str[npm->cm.response]); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s\n", + npm, npm->cm.type, nss_portid_log_message_types_str[npm->cm.type], + npm->cm.response, nss_cmn_response_str[npm->cm.response]); + +verbose: + nss_portid_log_verbose(npm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_portid_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_portid_log.h new file mode 100644 index 000000000..54d904fe9 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_portid_log.h @@ -0,0 +1,41 @@ +/* + ************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_PORTID_LOG_H +#define __NSS_PORTID_LOG_H + +/* + * nss_portid.h + * NSS PORTID header file. + */ + +/* + * Logger APIs + */ + +/* + * nss_portid_log_tx_msg + * Logs a portid message that is sent to the NSS firmware. + */ +void nss_portid_log_tx_msg(struct nss_portid_msg *ntm); + +/* + * nss_portid_log_rx_msg + * Logs a portid message that is received from the NSS firmware. + */ +void nss_portid_log_rx_msg(struct nss_portid_msg *ntm); + +#endif /* __NSS_PORTID_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_portid_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_portid_stats.c new file mode 100644 index 000000000..8b6086dba --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_portid_stats.c @@ -0,0 +1,153 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2017, 2019-2020 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_portid_stats.h" + +extern spinlock_t nss_portid_spinlock; +extern struct nss_portid_handle nss_portid_hdl[]; + +/* + * nss_portid_stats_str + * PortID statistics strings. + */ +struct nss_stats_info nss_portid_stats_str[NSS_PORTID_STATS_MAX] = { + {"rx_invalid_header" , NSS_STATS_TYPE_EXCEPTION} +}; + +uint64_t nss_portid_stats[NSS_PORTID_STATS_MAX]; + +/* + * nss_portid_stats_read() + * Read PortID stats. + */ +static ssize_t nss_portid_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i; + /* + * Max output lines = #stats + few output lines for banner printing + + * Number of Extra outputlines for future reference to add new stats. + */ + uint32_t max_output_lines = NSS_STATS_NODE_MAX + NSS_PORTID_STATS_MAX + NSS_STATS_EXTRA_OUTPUT_LINES; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + stats_shadow = kzalloc(NSS_STATS_NODE_MAX * 8, GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return 0; + } + + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "portid", NSS_STATS_SINGLE_CORE); + size_wr += nss_stats_fill_common_stats(NSS_PORTID_INTERFACE, NSS_STATS_SINGLE_INSTANCE, lbuf, size_wr, size_al, "portid"); + + /* + * PortID node stats + */ + spin_lock_bh(&nss_top_main.stats_lock); + for (i = 0; (i < NSS_PORTID_STATS_MAX); i++) { + stats_shadow[i] = nss_portid_stats[i]; + } + + spin_unlock_bh(&nss_top_main.stats_lock); + + size_wr += nss_stats_print("portid", NULL, NSS_STATS_SINGLE_INSTANCE + , nss_portid_stats_str + , stats_shadow + , NSS_PORTID_STATS_MAX + , lbuf, size_wr, size_al); + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * nss_portid_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(portid) + +/* + * nss_portid_stats_dentry_create() + * Create portid node statistics debug entry. + */ +void nss_portid_stats_dentry_create(void) +{ + nss_stats_create_dentry("portid", &nss_portid_stats_ops); +} + +/* + * nss_portid_stats_sync() + * Update portid node stats. + */ +void nss_portid_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_portid_stats_sync_msg *npsm) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + struct nss_portid_handle *hdl; + int j; + + if (npsm->port_id == NSS_PORTID_MAX_SWITCH_PORT) { + /* + * Update PORTID base node stats. + */ + spin_lock_bh(&nss_top->stats_lock); + nss_top->stats_node[NSS_PORTID_INTERFACE][NSS_STATS_NODE_RX_PKTS] += npsm->node_stats.rx_packets; + nss_top->stats_node[NSS_PORTID_INTERFACE][NSS_STATS_NODE_RX_BYTES] += npsm->node_stats.rx_bytes; + nss_top->stats_node[NSS_PORTID_INTERFACE][NSS_STATS_NODE_TX_PKTS] += npsm->node_stats.tx_packets; + nss_top->stats_node[NSS_PORTID_INTERFACE][NSS_STATS_NODE_TX_BYTES] += npsm->node_stats.tx_bytes; + + for (j = 0; j < NSS_MAX_NUM_PRI; j++) { + nss_top->stats_node[NSS_PORTID_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + j] += npsm->node_stats.rx_dropped[j]; + } + + nss_portid_stats[NSS_PORTID_STATS_RX_INVALID_HEADER] += npsm->rx_invalid_header; + spin_unlock_bh(&nss_top->stats_lock); + return; + } + + if (npsm->port_id >= NSS_PORTID_MAX_SWITCH_PORT) { + nss_warning("port_id %d exceeds NSS_PORTID_MAX_SWITCH_PORT\n", npsm->port_id); + return; + } + + /* + * Update PORTID interface stats. + */ + spin_lock_bh(&nss_portid_spinlock); + hdl = &nss_portid_hdl[npsm->port_id]; + if (hdl->if_num == 0) { + nss_warning("%px: nss_portid recv'd stats with unconfigured port %d", nss_ctx, npsm->port_id); + spin_unlock_bh(&nss_portid_spinlock); + return; + } + hdl->stats.rx_packets += npsm->node_stats.rx_packets; + hdl->stats.rx_bytes += npsm->node_stats.rx_bytes; + hdl->stats.rx_dropped += nss_cmn_rx_dropped_sum(&npsm->node_stats); + hdl->stats.tx_packets += npsm->node_stats.tx_packets; + hdl->stats.tx_bytes += npsm->node_stats.tx_bytes; + spin_unlock_bh(&nss_portid_spinlock); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_portid_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_portid_stats.h new file mode 100644 index 000000000..b1a1ee5b7 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_portid_stats.h @@ -0,0 +1,39 @@ +/* + ****************************************************************************** + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_PORTID_STATS_H +#define __NSS_PORTID_STATS_H + +/* + * PortID statistics + */ +enum nss_portid_stats_types { + NSS_PORTID_STATS_RX_INVALID_HEADER, + NSS_PORTID_STATS_MAX, +}; + +struct nss_portid_handle { + uint32_t if_num; /**< Interface number */ + struct rtnl_link_stats64 stats; /**< statistics counters */ +}; + +/* + * PortID statistics APIs + */ +extern void nss_portid_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_portid_stats_sync_msg *npsm); +extern void nss_portid_stats_dentry_create(void); + +#endif /* __NSS_PORTID_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ppe.c b/feeds/ipq807x/qca-nss-drv/src/nss_ppe.c new file mode 100644 index 000000000..b3d70431b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ppe.c @@ -0,0 +1,371 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_ppe.h" +#include "nss_ppe_stats.h" + +DEFINE_SPINLOCK(nss_ppe_stats_lock); + +struct nss_ppe_stats_debug nss_ppe_debug_stats; +struct nss_ppe_pvt ppe_pvt; + +/* + * nss_ppe_verify_ifnum() + * Verify PPE interface number. + */ +static inline bool nss_ppe_verify_ifnum(int if_num) +{ + return nss_is_dynamic_interface(if_num) || (if_num == NSS_PPE_INTERFACE); +} + +/* + * nss_ppe_callback() + * Callback to handle the completion of NSS->HLOS messages. + */ +static void nss_ppe_callback(void *app_data, struct nss_ppe_msg *npm) +{ + nss_ppe_msg_callback_t callback = (nss_ppe_msg_callback_t)ppe_pvt.cb; + void *data = ppe_pvt.app_data; + + ppe_pvt.response = NSS_TX_SUCCESS; + ppe_pvt.cb = NULL; + ppe_pvt.app_data = NULL; + + if (npm->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("ppe error response %d\n", npm->cm.response); + ppe_pvt.response = npm->cm.response; + } + + if (callback) { + callback(data, npm); + } + complete(&ppe_pvt.complete); +} + +/* + * nss_ppe_tx_msg() + * Transmit a ppe message to NSSFW + */ +nss_tx_status_t nss_ppe_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_ppe_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Trace messages. + */ + nss_ppe_log_tx_msg(msg); + + /* + * Sanity check the message + */ + if (ncm->type >= NSS_PPE_MSG_MAX) { + nss_warning("%px: message type out of range: %d\n", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + if (!nss_ppe_verify_ifnum(ncm->interface)) { + nss_warning("%px: invalid interface %d\n", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} + +/* + * nss_ppe_tx_msg_sync() + * Transmit a ppe message to NSS firmware synchronously. + */ +nss_tx_status_t nss_ppe_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_ppe_msg *npm) +{ + nss_tx_status_t status; + int ret = 0; + + down(&ppe_pvt.sem); + ppe_pvt.cb = (void *)npm->cm.cb; + ppe_pvt.app_data = (void *)npm->cm.app_data; + + npm->cm.cb = (nss_ptr_t)nss_ppe_callback; + npm->cm.app_data = (nss_ptr_t)NULL; + + status = nss_ppe_tx_msg(nss_ctx, npm); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: ppe_tx_msg failed\n", nss_ctx); + up(&ppe_pvt.sem); + return status; + } + + ret = wait_for_completion_timeout(&ppe_pvt.complete, msecs_to_jiffies(NSS_PPE_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: ppe msg tx failed due to timeout\n", nss_ctx); + ppe_pvt.response = NSS_TX_FAILURE; + } + + status = ppe_pvt.response; + up(&ppe_pvt.sem); + return status; +} + +/* + * nss_ppe_get_context() + * Get NSS context instance for ppe + */ +struct nss_ctx_instance *nss_ppe_get_context(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.ppe_handler_id]; +} + +/* + * nss_ppe_msg_init() + * Initialize nss_ppe_msg. + */ +void nss_ppe_msg_init(struct nss_ppe_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data) +{ + nss_cmn_msg_init(&ncm->cm, if_num, type, len, cb, app_data); +} + +/* + * nss_ppe_tx_ipsec_config_msg + * API to send inline IPsec port configure message to NSS FW + */ +nss_tx_status_t nss_ppe_tx_ipsec_config_msg(uint32_t nss_ifnum, uint32_t vsi_num, uint16_t mtu, + __attribute__((unused))uint16_t mru) +{ + struct nss_ctx_instance *nss_ctx = nss_ppe_get_context(); + struct nss_ppe_msg npm = {0}; + + if (!nss_ctx) { + nss_warning("Can't get nss context\n"); + return NSS_TX_FAILURE; + } + + if (vsi_num >= NSS_PPE_VSI_NUM_MAX) { + nss_warning("Invalid vsi number:%u\n", vsi_num); + return NSS_TX_FAILURE; + } + + nss_ppe_msg_init(&npm, NSS_PPE_INTERFACE, NSS_PPE_MSG_IPSEC_PORT_CONFIG, + sizeof(struct nss_ppe_ipsec_port_config_msg), NULL, NULL); + + npm.msg.ipsec_config.nss_ifnum = nss_ifnum; + npm.msg.ipsec_config.vsi_num = vsi_num; + npm.msg.ipsec_config.mtu = mtu; + + return nss_ppe_tx_msg_sync(nss_ctx, &npm); +} + +/* + * nss_ppe_tx_ipsec_mtu_msg + * API to send IPsec port MTU change message to NSS FW + */ +nss_tx_status_t nss_ppe_tx_ipsec_mtu_msg(uint32_t nss_ifnum, uint16_t mtu, __attribute__((unused))uint16_t mru) +{ + struct nss_ctx_instance *nss_ctx = nss_ppe_get_context(); + struct nss_ppe_msg npm = {0}; + + if (!nss_ctx) { + nss_warning("Can't get nss context\n"); + return NSS_TX_FAILURE; + } + + nss_ppe_msg_init(&npm, NSS_PPE_INTERFACE, NSS_PPE_MSG_IPSEC_PORT_MTU_CHANGE, + sizeof(struct nss_ppe_ipsec_port_mtu_msg), NULL, NULL); + + npm.msg.ipsec_mtu.nss_ifnum = nss_ifnum; + npm.msg.ipsec_mtu.mtu = mtu; + + return nss_ppe_tx_msg_sync(nss_ctx, &npm); +} + +/* + * nss_ppe_tx_ipsec_add_intf_msg + * API to attach NSS interface to IPsec port + */ +nss_tx_status_t nss_ppe_tx_ipsec_add_intf_msg(uint32_t nss_ifnum) +{ + struct nss_ctx_instance *nss_ctx = nss_ppe_get_context(); + struct nss_ppe_msg npm = {0}; + + if (!nss_ctx) { + nss_warning("Can't get nss context\n"); + return NSS_TX_FAILURE; + } + + nss_ppe_msg_init(&npm, NSS_PPE_INTERFACE, NSS_PPE_MSG_IPSEC_ADD_INTF, + sizeof(struct nss_ppe_ipsec_add_intf_msg), NULL, NULL); + + npm.msg.ipsec_addif.nss_ifnum = nss_ifnum; + + return nss_ppe_tx_msg_sync(nss_ctx, &npm); +} + +/* + * nss_ppe_tx_ipsec_del_intf_msg + * API to detach NSS interface to IPsec port + */ +nss_tx_status_t nss_ppe_tx_ipsec_del_intf_msg(uint32_t nss_ifnum) +{ + struct nss_ctx_instance *nss_ctx = nss_ppe_get_context(); + struct nss_ppe_msg npm = {0}; + + if (!nss_ctx) { + nss_warning("Can't get nss context\n"); + return NSS_TX_FAILURE; + } + + nss_ppe_msg_init(&npm, NSS_PPE_INTERFACE, NSS_PPE_MSG_IPSEC_DEL_INTF, + sizeof(struct nss_ppe_ipsec_del_intf_msg), NULL, NULL); + + npm.msg.ipsec_delif.nss_ifnum = nss_ifnum; + + return nss_ppe_tx_msg_sync(nss_ctx, &npm); +} + +/* + * nss_ppe_handler() + * Handle NSS -> HLOS messages for ppe + */ +static void nss_ppe_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_ppe_msg *msg = (struct nss_ppe_msg *)ncm; + void *ctx; + + nss_ppe_msg_callback_t cb; + + nss_trace("nss_ctx: %px ppe msg: %px\n", nss_ctx, msg); + BUG_ON(!nss_ppe_verify_ifnum(ncm->interface)); + + /* + * Trace messages. + */ + nss_ppe_log_rx_msg(msg); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_PPE_MSG_MAX) { + nss_warning("%px: received invalid message %d for PPE interface\n", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_ppe_msg)) { + nss_warning("%px: Length of message is greater than required: %d\n", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + switch (msg->cm.type) { + case NSS_PPE_MSG_SYNC_STATS: + /* + * session debug stats embeded in session stats msg + */ + nss_ppe_stats_sync(nss_ctx, &msg->msg.stats, ncm->interface); + return; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Do we have a call back + */ + if (!ncm->cb) { + return; + } + + /* + * callback + */ + cb = (nss_ppe_msg_callback_t)ncm->cb; + ctx = (void *)ncm->app_data; + + cb(ctx, msg); +} + +/* + * nss_ppe_register_handler() + * debugfs stats msg handler received on static ppe interface + * + * TODO: Export API so that others can also read PPE stats. + */ +void nss_ppe_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx = nss_ppe_get_context(); + + nss_core_register_handler(nss_ctx, NSS_PPE_INTERFACE, nss_ppe_handler, NULL); + + if (nss_ppe_debug_stats.valid) { + nss_ppe_stats_dentry_create(); + } +} + +/* + * nss_ppe_free() + * Uninitialize PPE base + */ +void nss_ppe_free(void) +{ + /* + * Check if PPE base is already uninitialized. + */ + if (!ppe_pvt.ppe_base) { + return; + } + + /* + * Unmap PPE base address + */ + iounmap(ppe_pvt.ppe_base); + ppe_pvt.ppe_base = NULL; + + spin_lock_bh(&nss_ppe_stats_lock); + nss_ppe_debug_stats.valid = false; + nss_ppe_debug_stats.if_num = 0; + nss_ppe_debug_stats.if_index = 0; + spin_unlock_bh(&nss_ppe_stats_lock); +} + +/* + * nss_ppe_init() + * Initialize PPE base + */ +void nss_ppe_init(void) +{ + /* + * Check if PPE base is already initialized. + */ + if (ppe_pvt.ppe_base) { + return; + } + + /* + * Get the PPE base address + */ + ppe_pvt.ppe_base = ioremap_nocache(PPE_BASE_ADDR, PPE_REG_SIZE); + if (!ppe_pvt.ppe_base) { + nss_warning("DRV can't get PPE base address\n"); + return; + } + + spin_lock_bh(&nss_ppe_stats_lock); + nss_ppe_debug_stats.valid = true; + nss_ppe_debug_stats.if_num = 0; + nss_ppe_debug_stats.if_index = 0; + spin_unlock_bh(&nss_ppe_stats_lock); + + sema_init(&ppe_pvt.sem, 1); + init_completion(&ppe_pvt.complete); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ppe.h b/feeds/ipq807x/qca-nss-drv/src/nss_ppe.h new file mode 100644 index 000000000..d71021145 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ppe.h @@ -0,0 +1,423 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_ppe.h + * NSS PPE header file + */ + +#include +#include "nss_tx_rx_common.h" + +#define PPE_BASE_ADDR 0x3a000000 +#define PPE_REG_SIZE 0x1000000 + +#define PPE_L3_DBG_WR_OFFSET 0x200c04 +#define PPE_L3_DBG_RD_OFFSET 0x200c0c +#define PPE_L3_DBG0_OFFSET 0x10001 +#define PPE_L3_DBG1_OFFSET 0x10002 +#define PPE_L3_DBG2_OFFSET 0x10003 +#define PPE_L3_DBG3_OFFSET 0x10004 +#define PPE_L3_DBG4_OFFSET 0x10005 +#define PPE_L3_DBG_PORT_OFFSET 0x11e80 + +#define PPE_PKT_CODE_WR_OFFSET 0x100080 +#define PPE_PKT_CODE_RD_OFFSET 0x100084 +#define PPE_PKT_CODE_DROP0_OFFSET 0xf000000 +#define PPE_PKT_CODE_DROP1_OFFSET 0x10000000 +#define PPE_PKT_CODE_CPU_OFFSET 0x40000000 + +#define PPE_PKT_CODE_DROP0_GET(x) (((x) & 0xe0000000) >> 29) +#define PPE_PKT_CODE_DROP1_GET(x) (((x) & 0x7) << 3) +#define PPE_PKT_CODE_DROP_GET(d0, d1) (PPE_PKT_CODE_DROP0_GET(d0) | PPE_PKT_CODE_DROP1_GET(d1)) + +#define PPE_PKT_CODE_CPU_GET(x) (((x) >> 3) & 0xff) + +#define PPE_IPE_PC_REG 0x100000 + +/* + * NSS_SYS_REG_DROP_CPU_CNT_TBL + * Address map and access APIs for DROP_CPU_CNT table. + */ +#define PPE_DROP_CPU_CNT_TBL_OFFSET 0x60000 +#define PPE_DROP_CPU_CNT_TBL_ENTRY_SIZE 0x10 +#define PPE_DROP_CPU_CNT_TBL_BASE_OFFSET (PPE_IPE_PC_REG + PPE_DROP_CPU_CNT_TBL_OFFSET) +#define PPE_CPU_CODE_MAX_NUM 256 + +/* + * CPU code offset + */ +#define PPE_CPU_CODE_OFFSET(n) (PPE_DROP_CPU_CNT_TBL_BASE_OFFSET + ((n) * PPE_DROP_CPU_CNT_TBL_ENTRY_SIZE)) + +/* + * DROP code offset + */ +#define PPE_DROP_CODE_IDX(code, src_port) (PPE_CPU_CODE_MAX_NUM + (8 * (code)) + (src_port)) +#define PPE_DROP_CODE_OFFSET(code, src_port) (PPE_DROP_CPU_CNT_TBL_BASE_OFFSET + ((PPE_DROP_CODE_IDX(code, src_port)) * PPE_DROP_CPU_CNT_TBL_ENTRY_SIZE)) + +#define NSS_PPE_TX_TIMEOUT 1000 /* 1 Second */ + +/* + * Maximum number of VSI + */ +#define NSS_PPE_VSI_NUM_MAX 32 + +/* + * ppe nss debug stats lock + */ +extern spinlock_t nss_ppe_stats_lock; + +/* + * Private data structure + */ +struct nss_ppe_pvt { + void * __iomem ppe_base; + struct semaphore sem; + struct completion complete; + int response; + void *cb; + void *app_data; +}; + +/* + * Data structure to store to PPE private context + */ +extern struct nss_ppe_pvt ppe_pvt; + +/** + * nss_ppe_message_types + * Message types for Packet Processing Engine (PPE) requests and responses. + * + * Note: PPE messages are added as short term approach, expect all + * messages below to be deprecated for more integrated approach. + */ +enum nss_ppe_message_types { + NSS_PPE_MSG_SYNC_STATS, + NSS_PPE_MSG_IPSEC_PORT_CONFIG, + NSS_PPE_MSG_IPSEC_PORT_MTU_CHANGE, + NSS_PPE_MSG_IPSEC_ADD_INTF, + NSS_PPE_MSG_IPSEC_DEL_INTF, + NSS_PPE_MSG_MAX, +}; + +/** + * nss_ppe_msg_error_type + * PPE error types. + */ +enum nss_ppe_msg_error_type { + PPE_MSG_ERROR_OK, + PPE_MSG_ERROR_UNKNOWN_TYPE, + PPE_MSG_ERROR_PORT_CREATION_FAIL, + PPE_MSG_ERROR_INVALID_PORT_VSI, + PPE_MSG_ERROR_INVALID_L3_IF, + PPE_MSG_ERROR_IPSEC_PORT_CONFIG, + PPE_MSG_ERROR_IPSEC_INTF_TABLE_FULL, + PPE_MSG_ERROR_IPSEC_INTF_ATTACHED, + PPE_MSG_ERROR_IPSEC_INTF_UNATTACHED, + PPE_ERROR_MAX +}; + +/** + * nss_ppe_stats_sc + * Message structure for per service code stats. + */ +struct nss_ppe_stats_sc { + uint32_t nss_ppe_sc_cb_unregister; /* Per service-code counter for callback not registered */ + uint32_t nss_ppe_sc_cb_success; /* Per service-code coutner for successful callback */ + uint32_t nss_ppe_sc_cb_failure; /* Per service-code counter for failure callback */ +}; + +/** + * nss_ppe_stats + * Message structure for ppe general stats + */ +struct nss_ppe_stats { + uint32_t nss_ppe_v4_l3_flows; /**< Number of IPv4 routed flows. */ + uint32_t nss_ppe_v4_l2_flows; /**< Number of IPv4 bridge flows. */ + uint32_t nss_ppe_v4_create_req; /**< Number of IPv4 create requests. */ + uint32_t nss_ppe_v4_create_fail; /**< Number of IPv4 create failures. */ + uint32_t nss_ppe_v4_destroy_req; /**< Number of IPv4 delete requests. */ + uint32_t nss_ppe_v4_destroy_fail; /**< Number of IPv4 delete failures. */ + uint32_t nss_ppe_v4_mc_create_req; /**< Number of IPv4 MC create requests. */ + uint32_t nss_ppe_v4_mc_create_fail; /**< Number of IPv4 MC create failure. */ + uint32_t nss_ppe_v4_mc_update_req; /**< Number of IPv4 MC update requests. */ + uint32_t nss_ppe_v4_mc_update_fail; /**< Number of IPv4 MC update failure. */ + uint32_t nss_ppe_v4_mc_destroy_req; /**< Number of IPv4 MC delete requests. */ + uint32_t nss_ppe_v4_mc_destroy_fail; /**< Number of IPv4 MC delete failure. */ + uint32_t nss_ppe_v4_unknown_interface; /**< Number of IPv4 create failures */ + + uint32_t nss_ppe_v6_l3_flows; /**< Number of IPv6 routed flows. */ + uint32_t nss_ppe_v6_l2_flows; /**< Number of IPv6 bridge flows. */ + uint32_t nss_ppe_v6_create_req; /**< Number of IPv6 create requests. */ + uint32_t nss_ppe_v6_create_fail; /**< Number of IPv6 create failures. */ + uint32_t nss_ppe_v6_destroy_req; /**< Number of IPv6 delete requests. */ + uint32_t nss_ppe_v6_destroy_fail; /**< Number of IPv6 delete failures. */ + uint32_t nss_ppe_v6_mc_create_req; /**< Number of IPv6 MC create requests. */ + uint32_t nss_ppe_v6_mc_create_fail; /**< Number of IPv6 MC create failure. */ + uint32_t nss_ppe_v6_mc_update_req; /**< Number of IPv6 MC update requests. */ + uint32_t nss_ppe_v6_mc_update_fail; /**< Number of IPv6 MC update failure. */ + uint32_t nss_ppe_v6_mc_destroy_req; /**< Number of IPv6 MC delete requests. */ + uint32_t nss_ppe_v6_mc_destroy_fail; /**< Number of IPv6 MC delete failure. */ + uint32_t nss_ppe_v6_unknown_interface; /**< Number of IPv6 create failures */ + + uint32_t nss_ppe_fail_vp_full; + /**< Request failed because the virtual port table is full */ + uint32_t nss_ppe_fail_nh_full; + /**< Request failed because the next hop table is full. */ + uint32_t nss_ppe_fail_flow_full; + /**< Request failed because the flow table is full. */ + uint32_t nss_ppe_fail_host_full; + /**< Request failed because the host table is full. */ + uint32_t nss_ppe_fail_pubip_full; + /**< Request failed because the public IP table is full. */ + uint32_t nss_ppe_fail_port_setup; + /**< Request failed because the PPE port is not setup. */ + uint32_t nss_ppe_fail_rw_fifo_full; + /**< Request failed because the read/write FIFO is full. */ + uint32_t nss_ppe_fail_flow_command; + /**< Request failed because the PPE flow command failed. */ + uint32_t nss_ppe_fail_unknown_proto; + /**< Request failed because of an unknown protocol. */ + uint32_t nss_ppe_fail_ppe_unresponsive; + /**< Request failed because the PPE is not responding. */ + uint32_t nss_ppe_ce_opaque_invalid; + /**< Request failed because of invalid opaque in connection entry. */ + uint32_t nss_ppe_fail_fqg_full; + /**< Request failed because the flow QoS group is full. */ +}; + + +/** + * nss_ppe_sync_stats_msg + * Message information for PPE synchronization statistics. + */ +struct nss_ppe_sync_stats_msg { + struct nss_ppe_stats stats; /**< General stats */ + struct nss_ppe_stats_sc sc_stats[NSS_PPE_SC_MAX]; + /**< Per service-code stats */ +}; + +/** + * nss_ppe_ipsec_port_config_msg + * Message structure for inline IPsec port configuration. + */ +struct nss_ppe_ipsec_port_config_msg { + uint32_t nss_ifnum; /**< NSS interface number corresponding to inline IPsec port. */ + uint16_t mtu; /**< MTU value for inline IPsec port. */ + uint8_t vsi_num; /**< Default port VSI for inline IPsec port. */ +}; + +/** + * nss_ppe_ipsec_port_mtu_msg + * Message structure for inline IPsec port MTU change. + */ +struct nss_ppe_ipsec_port_mtu_msg { + uint32_t nss_ifnum; /**< NSS interface number corresponding to inline IPsec port. */ + uint16_t mtu; /**< MTU value for inline IPsec port. */ +}; + +/** + * nss_ppe_ipsec_add_intf_msg + * Message structure for adding dynamic IPsec/DTLS interface to inline IPsec port. + */ +struct nss_ppe_ipsec_add_intf_msg { + uint32_t nss_ifnum; /**< Dynamic IPsec/DTLS interface number. */ +}; + +/** + * nss_ppe_ipsec_del_intf_msg + * Message structure for deleting dynamic IPsec/DTLS interface to inline IPsec port. + */ +struct nss_ppe_ipsec_del_intf_msg { + uint32_t nss_ifnum; /**< Dynamic IPsec/DTLS interface number. */ +}; + +/** + * nss_ppe_msg + * Data for sending and receiving PPE host-to-NSS messages. + */ +struct nss_ppe_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /** + * Payload of a PPE host-to-NSS message. + */ + union { + struct nss_ppe_sync_stats_msg stats; + /**< Synchronization statistics. */ + struct nss_ppe_ipsec_port_config_msg ipsec_config; + /**< PPE inline IPsec port configuration message. */ + struct nss_ppe_ipsec_port_mtu_msg ipsec_mtu; + /**< Inline IPsec port MTU change message. */ + struct nss_ppe_ipsec_add_intf_msg ipsec_addif; + /**< Inline IPsec NSS interface attach message. */ + struct nss_ppe_ipsec_del_intf_msg ipsec_delif; + /**< Inline IPsec NSS interface detach message. */ + } msg; /**< Message payload. */ +}; + +/** + * Callback function for receiving PPE messages. + * + * @datatypes + * nss_ppe_msg + * + * @param[in] app_data Pointer to the application context of the message. + * @param[in] msg Pointer to the message data. + */ +typedef void (*nss_ppe_msg_callback_t)(void *app_data, struct nss_ppe_msg *msg); + +/** + * nss_ppe_tx_msg + * Sends PPE messages to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_ppe_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_ppe_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_ppe_msg *msg); + +/** + * nss_ppe_tx_msg_sync + * Sends PPE messages synchronously to the NSS. + * + * @datatypes + * nss_ctx_instance \n + * nss_ppe_msg + * + * @param[in] nss_ctx Pointer to the NSS context. + * @param[in,out] msg Pointer to the message data. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_ppe_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_ppe_msg *msg); + +/** + * nss_ppe_msg_init + * Initializes a PPE message. + * + * @datatypes + * nss_ppe_msg + * + * @param[in,out] ncm Pointer to the message. + * @param[in] if_num Interface number + * @param[in] type Type of message. + * @param[in] len Size of the payload. + * @param[in] cb Callback function for the message. + * @param[in] app_data Pointer to the application context of the message. + * + * @return + * None. + */ +void nss_ppe_msg_init(struct nss_ppe_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data); + +/** + * nss_ppe_get_context + * Gets the PPE context used in nss_ppe_tx. + * + * @return + * Pointer to the NSS core context. + */ +struct nss_ctx_instance *nss_ppe_get_context(void); + +/** + * nss_ppe_tx_ipsec_config_msg + * Sends the PPE a message to configure inline IPsec port. + * + * @param[in] if_num Static IPsec interface number. + * @param[in] vsi_num Default VSI number associated with inline IPsec port. + * @param[in] mtu Default MTU of static inline IPsec port. + * @param[in] mru Default MRU of static inline IPsec port. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_ppe_tx_ipsec_config_msg(uint32_t nss_ifnum, uint32_t vsi_num, uint16_t mtu, uint16_t mru); + +/** + * nss_ppe_tx_ipsec_mtu_msg + * Sends the PPE a message to configure MTU value on IPsec port. + * + * @param[in] nss_ifnum Static IPsec interface number. + * @param[in] mtu MTU of static IPsec interface. + * @param[in] mru MRU of static IPsec interface. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_ppe_tx_ipsec_mtu_msg(uint32_t nss_ifnum, uint16_t mtu, uint16_t mru); + +/** + * nss_ppe_tx_ipsec_add_intf_msg + * Sends the PPE a message to attach a dynamic interface number to IPsec port. + * + * @param[in] if_num Dynamic IPsec/DTLS interface number. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_ppe_tx_ipsec_add_intf_msg(uint32_t nss_ifnum); + +/** + * nss_ppe_tx_ipsec_del_intf_msg + * Sends the PPE a message to detach a dynamic interface number to IPsec port. + * + * @param[in] if_num Dynamic IPsec/DTLS interface number. + * + * @return + * Status of the Tx operation. + */ +nss_tx_status_t nss_ppe_tx_ipsec_del_intf_msg(uint32_t nss_ifnum); + +/* + * nss_ppe_reg_read() + */ +static inline void nss_ppe_reg_read(u32 reg, u32 *val) +{ + *val = readl((ppe_pvt.ppe_base + reg)); +} + +/* + * nss_ppe_reg_write() + */ +static inline void nss_ppe_reg_write(u32 reg, u32 val) +{ + writel(val, (ppe_pvt.ppe_base + reg)); +} + +/* + * nss_ppe_log.h + * NSS PPE Log Header File + */ + +/* + * nss_ppe_log_tx_msg + * Logs a ppe message that is sent to the NSS firmware. + */ +void nss_ppe_log_tx_msg(struct nss_ppe_msg *npm); + +/* + * nss_ppe_log_rx_msg + * Logs a ppe message that is received from the NSS firmware. + */ +void nss_ppe_log_rx_msg(struct nss_ppe_msg *npm); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ppe_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_ppe_log.c new file mode 100644 index 000000000..a6517322b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ppe_log.c @@ -0,0 +1,189 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_ppe_log.c + * NSS PPE logger file. + */ + +#include "nss_core.h" +#include "nss_ppe.h" + +/* + * nss_ppe_log_message_types_str + * PPE message strings + */ +static int8_t *nss_ppe_log_message_types_str[NSS_PPE_MSG_MAX] __maybe_unused = { + "PPE Stats", + "PPE IPSEC Port Config", + "PPE IPSEC Port MTU Change", + "PPE IPSEC Add Interface", + "PPE IPSEC Del Interface", +}; + +/* + * nss_ppe_log_error_response_types_str + * Strings for error types for PPE messages + */ +static int8_t *nss_ppe_log_error_response_types_str[PPE_ERROR_MAX] __maybe_unused = { + "PPE No Error", + "PPE Uknown Type", + "PPE Port Creation Failure", + "PPE Invalid Port VSI", + "PPE Invalid L3 Interface", + "PPE IPSEC Port Config Error", + "PPE IPSEC Interface Table Full", + "PPE IPSEC Interface Attached", + "PPE IPSEC Interface Unattached", +}; + +/* + * nss_ppe_log_port_config_msg() + * Log NSS PPE port config message. + */ +static void nss_ppe_log_port_config_msg(struct nss_ppe_msg *npm) +{ + struct nss_ppe_ipsec_port_config_msg *npcm __maybe_unused = &npm->msg.ipsec_config; + nss_trace("%px: NSS PPE Port Configure Message:\n" + "PPE NSS Interface Number: %d\n" + "PPE MTU: %d\n" + "PPE VSI Number: %d\n", + npcm, npcm->nss_ifnum, + npcm->mtu, npcm->vsi_num); +} + +/* + * nss_ppe_log_port_mtu_msg() + * Log NSS PPE port mtu message. + */ +static void nss_ppe_log_port_mtu_msg(struct nss_ppe_msg *npm) +{ + struct nss_ppe_ipsec_port_mtu_msg *npmm __maybe_unused = &npm->msg.ipsec_mtu; + nss_trace("%px: NSS PPE Port Configure Message:\n" + "PPE NSS Interface Number: %d\n" + "PPE MTU: %d\n", + npmm, npmm->nss_ifnum, + npmm->mtu); +} + +/* + * nss_ppe_log_add_intf_msg() + * Log NSS PPE IPSEC Add Interface Message. + */ +static void nss_ppe_log_add_intf_msg(struct nss_ppe_msg *npm) +{ + struct nss_ppe_ipsec_add_intf_msg *npam __maybe_unused = &npm->msg.ipsec_addif; + nss_trace("%px: NSS PPE IPSEC add Interface Message:\n" + "PPE NSS Interface Number: %d\n", + npam, npam->nss_ifnum); +} + +/* + * nss_ppe_log_del_intf_msg() + * Log NSS PPE IPSEC Delete Interface Message. + */ +static void nss_ppe_log_del_intf_msg(struct nss_ppe_msg *npm) +{ + struct nss_ppe_ipsec_del_intf_msg *npdm __maybe_unused = &npm->msg.ipsec_delif; + nss_trace("%px: NSS PPE IPSEC Delete Interface Message:\n" + "PPE NSS Interface Number: %d\n", + npdm, npdm->nss_ifnum); +} + +/* + * nss_ppe_log_verbose() + * Log message contents. + */ +static void nss_ppe_log_verbose(struct nss_ppe_msg *npm) +{ + switch (npm->cm.type) { + case NSS_PPE_MSG_IPSEC_PORT_CONFIG: + nss_ppe_log_port_config_msg(npm); + break; + + case NSS_PPE_MSG_IPSEC_PORT_MTU_CHANGE: + nss_ppe_log_port_mtu_msg(npm); + break; + + case NSS_PPE_MSG_IPSEC_ADD_INTF: + nss_ppe_log_add_intf_msg(npm); + break; + + case NSS_PPE_MSG_IPSEC_DEL_INTF: + nss_ppe_log_del_intf_msg(npm); + break; + + case NSS_PPE_MSG_SYNC_STATS: + /* + * No log for valid stats message. + */ + break; + + default: + nss_warning("%px: Invalid message type\n", npm); + break; + } +} + +/* + * nss_ppe_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_ppe_log_tx_msg(struct nss_ppe_msg *npm) +{ + if (npm->cm.type >= NSS_PPE_MSG_MAX) { + nss_warning("%px: Invalid message type\n", npm); + return; + } + + nss_info("%px: type[%d]:%s\n", npm, npm->cm.type, nss_ppe_log_message_types_str[npm->cm.type]); + nss_ppe_log_verbose(npm); +} + +/* + * nss_ppe_log_rx_msg() + * Log messages received from FW. + */ +void nss_ppe_log_rx_msg(struct nss_ppe_msg *npm) +{ + if (npm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", npm); + return; + } + + if (npm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (npm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", npm, npm->cm.type, + nss_ppe_log_message_types_str[npm->cm.type], + npm->cm.response, nss_cmn_response_str[npm->cm.response]); + goto verbose; + } + + if (npm->cm.error >= PPE_ERROR_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + npm, npm->cm.type, nss_ppe_log_message_types_str[npm->cm.type], + npm->cm.response, nss_cmn_response_str[npm->cm.response], + npm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + npm, npm->cm.type, nss_ppe_log_message_types_str[npm->cm.type], + npm->cm.response, nss_cmn_response_str[npm->cm.response], + npm->cm.error, nss_ppe_log_error_response_types_str[npm->cm.error]); + +verbose: + nss_ppe_log_verbose(npm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ppe_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_ppe_stats.c new file mode 100644 index 000000000..8f387dfd1 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ppe_stats.c @@ -0,0 +1,1238 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_ppe.h" +#include "nss_ppe_stats.h" + +static uint8_t ppe_cc_nonexception[NSS_PPE_STATS_CPU_CODE_NONEXCEPTION_MAX] = { + NSS_PPE_STATS_CPU_CODE_EXP_FAKE_L2_PROT_ERR, + NSS_PPE_STATS_CPU_CODE_EXP_FAKE_MAC_HEADER_ERR, + NSS_PPE_STATS_CPU_CODE_EXP_BITMAP_MAX, + NSS_PPE_STATS_CPU_CODE_L2_EXP_MRU_FAIL, + NSS_PPE_STATS_CPU_CODE_L2_EXP_MTU_FAIL, + NSS_PPE_STATS_CPU_CODE_L3_EXP_IP_PREFIX_BC, + NSS_PPE_STATS_CPU_CODE_L3_EXP_MTU_FAIL, + NSS_PPE_STATS_CPU_CODE_L3_EXP_MRU_FAIL, + NSS_PPE_STATS_CPU_CODE_L3_EXP_ICMP_RDT, + NSS_PPE_STATS_CPU_CODE_L3_EXP_IP_RT_TTL1_TO_ME, + NSS_PPE_STATS_CPU_CODE_L3_EXP_IP_RT_TTL_ZERO, + NSS_PPE_STATS_CPU_CODE_L3_FLOW_SERVICE_CODE_LOOP, + NSS_PPE_STATS_CPU_CODE_L3_FLOW_DE_ACCELERATE, + NSS_PPE_STATS_CPU_CODE_L3_EXP_FLOW_SRC_IF_CHK_FAIL, + NSS_PPE_STATS_CPU_CODE_L3_FLOW_SYNC_TOGGLE_MISMATCH, + NSS_PPE_STATS_CPU_CODE_L3_EXP_MTU_DF_FAIL, + NSS_PPE_STATS_CPU_CODE_L3_EXP_PPPOE_MULTICAST, + NSS_PPE_STATS_CPU_CODE_MGMT_OFFSET, + NSS_PPE_STATS_CPU_CODE_MGMT_EAPOL, + NSS_PPE_STATS_CPU_CODE_MGMT_PPPOE_DIS, + NSS_PPE_STATS_CPU_CODE_MGMT_IGMP, + NSS_PPE_STATS_CPU_CODE_MGMT_ARP_REQ, + NSS_PPE_STATS_CPU_CODE_MGMT_ARP_REP, + NSS_PPE_STATS_CPU_CODE_MGMT_DHCPv4, + NSS_PPE_STATS_CPU_CODE_MGMT_MLD, + NSS_PPE_STATS_CPU_CODE_MGMT_NS, + NSS_PPE_STATS_CPU_CODE_MGMT_NA, + NSS_PPE_STATS_CPU_CODE_MGMT_DHCPv6, + NSS_PPE_STATS_CPU_CODE_PTP_OFFSET, + NSS_PPE_STATS_CPU_CODE_PTP_SYNC, + NSS_PPE_STATS_CPU_CODE_PTP_FOLLOW_UP, + NSS_PPE_STATS_CPU_CODE_PTP_DELAY_REQ, + NSS_PPE_STATS_CPU_CODE_PTP_DELAY_RESP, + NSS_PPE_STATS_CPU_CODE_PTP_PDELAY_REQ, + NSS_PPE_STATS_CPU_CODE_PTP_PDELAY_RESP, + NSS_PPE_STATS_CPU_CODE_PTP_PDELAY_RESP_FOLLOW_UP, + NSS_PPE_STATS_CPU_CODE_PTP_ANNOUNCE, + NSS_PPE_STATS_CPU_CODE_PTP_MANAGEMENT, + NSS_PPE_STATS_CPU_CODE_PTP_SIGNALING, + NSS_PPE_STATS_CPU_CODE_PTP_PKT_RSV_MSG, + NSS_PPE_STATS_CPU_CODE_IPV4_SG_UNKNOWN, + NSS_PPE_STATS_CPU_CODE_IPV6_SG_UNKNOWN, + NSS_PPE_STATS_CPU_CODE_ARP_SG_UNKNOWN, + NSS_PPE_STATS_CPU_CODE_ND_SG_UNKNOWN, + NSS_PPE_STATS_CPU_CODE_IPV4_SG_VIO, + NSS_PPE_STATS_CPU_CODE_IPV6_SG_VIO, + NSS_PPE_STATS_CPU_CODE_ARP_SG_VIO, + NSS_PPE_STATS_CPU_CODE_ND_SG_VIO, + NSS_PPE_STATS_CPU_CODE_L3_ROUTING_IP_TO_ME, + NSS_PPE_STATS_CPU_CODE_L3_FLOW_SNAT_ACTION, + NSS_PPE_STATS_CPU_CODE_L3_FLOW_DNAT_ACTION, + NSS_PPE_STATS_CPU_CODE_L3_FLOW_RT_ACTION, + NSS_PPE_STATS_CPU_CODE_L3_FLOW_BR_ACTION, + NSS_PPE_STATS_CPU_CODE_L3_MC_BRIDGE_ACTION, + NSS_PPE_STATS_CPU_CODE_L3_ROUTE_PREHEAD_RT_ACTION, + NSS_PPE_STATS_CPU_CODE_L3_ROUTE_PREHEAD_SNAPT_ACTION, + NSS_PPE_STATS_CPU_CODE_L3_ROUTE_PREHEAD_DNAPT_ACTION, + NSS_PPE_STATS_CPU_CODE_L3_ROUTE_PREHEAD_SNAT_ACTION, + NSS_PPE_STATS_CPU_CODE_L3_ROUTE_PREHEAD_DNAT_ACTION, + NSS_PPE_STATS_CPU_CODE_L3_NO_ROUTE_PREHEAD_NAT_ACTION, + NSS_PPE_STATS_CPU_CODE_L3_NO_ROUTE_PREHEAD_NAT_ERROR, + NSS_PPE_STATS_CPU_CODE_L3_ROUTE_ACTION, + NSS_PPE_STATS_CPU_CODE_L3_NO_ROUTE_ACTION, + NSS_PPE_STATS_CPU_CODE_L3_NO_ROUTE_NH_INVALID_ACTION, + NSS_PPE_STATS_CPU_CODE_L3_NO_ROUTE_PREHEAD_ACTION, + NSS_PPE_STATS_CPU_CODE_L3_BRIDGE_ACTION, + NSS_PPE_STATS_CPU_CODE_L3_FLOW_ACTION, + NSS_PPE_STATS_CPU_CODE_L3_FLOW_MISS_ACTION, + NSS_PPE_STATS_CPU_CODE_L2_NEW_MAC_ADDRESS, + NSS_PPE_STATS_CPU_CODE_L2_HASH_COLLISION, + NSS_PPE_STATS_CPU_CODE_L2_STATION_MOVE, + NSS_PPE_STATS_CPU_CODE_L2_LEARN_LIMIT, + NSS_PPE_STATS_CPU_CODE_L2_SA_LOOKUP_ACTION, + NSS_PPE_STATS_CPU_CODE_L2_DA_LOOKUP_ACTION, + NSS_PPE_STATS_CPU_CODE_APP_CTRL_ACTION, + NSS_PPE_STATS_CPU_CODE_IN_VLAN_FILTER_ACTION, + NSS_PPE_STATS_CPU_CODE_IN_VLAN_XLT_MISS, + NSS_PPE_STATS_CPU_CODE_EG_VLAN_FILTER_DROP, + NSS_PPE_STATS_CPU_CODE_ACL_PRE_ACTION, + NSS_PPE_STATS_CPU_CODE_ACL_POST_ACTION, + NSS_PPE_STATS_CPU_CODE_SERVICE_CODE_ACTION, +}; + +/* + * nss_ppe_stats_str_conn + * PPE statistics strings for nss flow stats + */ +static int8_t *nss_ppe_stats_str_conn[NSS_PPE_STATS_CONN_MAX] = { + "v4 routed flows", + "v4 bridge flows", + "v4 conn create req", + "v4 conn create fail", + "v4 conn destroy req", + "v4 conn destroy fail", + "v4 conn MC create req", + "v4 conn MC create fail", + "v4 conn MC update req", + "v4 conn MC update fail", + "v4 conn MC delete req", + "v4 conn MC delete fail", + "v4 conn unknown if", + + "v6 routed flows", + "v6 bridge flows", + "v6 conn create req", + "v6 conn create fail", + "v6 conn destroy req", + "v6 conn destroy fail", + "v6 conn MC create req", + "v6 conn MC create fail", + "v6 conn MC update req", + "v6 conn MC update fail", + "v6 conn MC delete req", + "v6 conn MC delete fail", + "v6 conn unknown if", + + "conn fail - vp full", + "conn fail - nexthop full", + "conn fail - flow full", + "conn fail - host full", + "conn fail - pub-ip full", + "conn fail - port not setup", + "conn fail - rw fifo full", + "conn fail - flow cmd failure", + "conn fail - unknown proto", + "conn fail - ppe not responding", + "conn fail - CE opaque invalid", + "conn fail - fqg full" +}; + +/* + * nss_ppe_stats_str_l3 + * PPE statistics strings for nss debug stats + */ +static int8_t *nss_ppe_stats_str_l3[NSS_PPE_STATS_L3_MAX] = { + "PPE L3 dbg reg 0", + "PPE L3 dbg reg 1", + "PPE L3 dbg reg 2", + "PPE L3 dbg reg 3", + "PPE L3 dbg reg 4", + "PPE L3 dbg reg port", +}; + +/* + * nss_ppe_stats_str_code + * PPE statistics strings for nss debug stats + */ +static int8_t *nss_ppe_stats_str_code[NSS_PPE_STATS_CODE_MAX] = { + "PPE CPU_CODE", + "PPE DROP_CODE", +}; + +/* + * nss_ppe_stats_str_dc + * PPE statistics strings for drop code + */ +static int8_t *nss_ppe_stats_str_dc[NSS_PPE_STATS_DROP_CODE_MAX] = { + "PPE_DROP_CODE_NONE", + "PPE_DROP_CODE_EXP_UNKNOWN_L2_PORT", + "PPE_DROP_CODE_EXP_PPPOE_WRONG_VER_TYPE", + "PPE_DROP_CODE_EXP_PPPOE_WRONG_CODE", + "PPE_DROP_CODE_EXP_PPPOE_UNSUPPORTED_PPP_PROT", + "PPE_DROP_CODE_EXP_IPV4_WRONG_VER", + "PPE_DROP_CODE_EXP_IPV4_SMALL_IHL", + "PPE_DROP_CODE_EXP_IPV4_WITH_OPTION", + "PPE_DROP_CODE_EXP_IPV4_HDR_INCOMPLETE", + "PPE_DROP_CODE_EXP_IPV4_BAD_TOTAL_LEN", + "PPE_DROP_CODE_EXP_IPV4_DATA_INCOMPLETE", + "PPE_DROP_CODE_EXP_IPV4_FRAG", + "PPE_DROP_CODE_EXP_IPV4_PING_OF_DEATH", + "PPE_DROP_CODE_EXP_IPV4_SNALL_TTL", + "PPE_DROP_CODE_EXP_IPV4_UNK_IP_PROT", + "PPE_DROP_CODE_EXP_IPV4_CHECKSUM_ERR", + "PPE_DROP_CODE_EXP_IPV4_INV_SIP", + "PPE_DROP_CODE_EXP_IPV4_INV_DIP", + "PPE_DROP_CODE_EXP_IPV4_LAND_ATTACK", + "PPE_DROP_CODE_EXP_IPV4_AH_HDR_INCOMPLETE", + "PPE_DROP_CODE_EXP_IPV4_AH_HDR_CROSS_BORDER", + "PPE_DROP_CODE_EXP_IPV4_ESP_HDR_INCOMPLETE", + "PPE_DROP_CODE_EXP_IPV6_WRONG_VER", + "PPE_DROP_CODE_EXP_IPV6_HDR_INCOMPLETE", + "PPE_DROP_CODE_EXP_IPV6_BAD_PAYLOAD_LEN", + "PPE_DROP_CODE_EXP_IPV6_DATA_INCOMPLETE", + "PPE_DROP_CODE_EXP_IPV6_WITH_EXT_HDR", + "PPE_DROP_CODE_EXP_IPV6_SMALL_HOP_LIMIT", + "PPE_DROP_CODE_EXP_IPV6_INV_SIP", + "PPE_DROP_CODE_EXP_IPV6_INV_DIP", + "PPE_DROP_CODE_EXP_IPV6_LAND_ATTACK", + "PPE_DROP_CODE_EXP_IPV6_FRAG", + "PPE_DROP_CODE_EXP_IPV6_PING_OF_DEATH", + "PPE_DROP_CODE_EXP_IPV6_WITH_MORE_EXT_HDR", + "PPE_DROP_CODE_EXP_IPV6_UNK_LAST_NEXT_HDR", + "PPE_DROP_CODE_EXP_IPV6_MOBILITY_HDR_INCOMPLETE", + "PPE_DROP_CODE_EXP_IPV6_MOBILITY_HDR_CROSS_BORDER", + "PPE_DROP_CODE_EXP_IPV6_AH_HDR_INCOMPLETE", + "PPE_DROP_CODE_EXP_IPV6_AH_HDR_CROSS_BORDER", + "PPE_DROP_CODE_EXP_IPV6_ESP_HDR_INCOMPLETE", + "PPE_DROP_CODE_EXP_IPV6_ESP_HDR_CROSS_BORDER", + "PPE_DROP_CODE_EXP_IPV6_OTHER_EXT_HDR_INCOMPLETE", + "PPE_DROP_CODE_EXP_IPV6_OTHER_EXT_HDR_CROSS_BORDER", + "PPE_DROP_CODE_EXP_TCP_HDR_INCOMPLETE", + "PPE_DROP_CODE_EXP_TCP_HDR_CROSS_BORDER", + "PPE_DROP_CODE_EXP_TCP_SMAE_SP_DP", + "PPE_DROP_CODE_EXP_TCP_SMALL_DATA_OFFSET", + "PPE_DROP_CODE_EXP_TCP_FLAGS_0", + "PPE_DROP_CODE_EXP_TCP_FLAGS_1", + "PPE_DROP_CODE_EXP_TCP_FLAGS_2", + "PPE_DROP_CODE_EXP_TCP_FLAGS_3", + "PPE_DROP_CODE_EXP_TCP_FLAGS_4", + "PPE_DROP_CODE_EXP_TCP_FLAGS_5", + "PPE_DROP_CODE_EXP_TCP_FLAGS_6", + "PPE_DROP_CODE_EXP_TCP_FLAGS_7", + "PPE_DROP_CODE_EXP_TCP_CHECKSUM_ERR", + "PPE_DROP_CODE_EXP_UDP_HDR_INCOMPLETE", + "PPE_DROP_CODE_EXP_UDP_HDR_CROSS_BORDER", + "PPE_DROP_CODE_EXP_UDP_SMAE_SP_DP", + "PPE_DROP_CODE_EXP_UDP_BAD_LEN", + "PPE_DROP_CODE_EXP_UDP_DATA_INCOMPLETE", + "PPE_DROP_CODE_EXP_UDP_CHECKSUM_ERR", + "PPE_DROP_CODE_EXP_UDP_LITE_HDR_INCOMPLETE", + "PPE_DROP_CODE_EXP_UDP_LITE_HDR_CROSS_BORDER", + "PPE_DROP_CODE_EXP_UDP_LITE_SMAE_SP_DP", + "PPE_DROP_CODE_EXP_UDP_LITE_CSM_COV_1_TO_7", + "PPE_DROP_CODE_EXP_UDP_LITE_CSM_COV_TOO_LONG", + "PPE_DROP_CODE_EXP_UDP_LITE_CSM_COV_CROSS_BORDER", + "PPE_DROP_CODE_EXP_UDP_LITE_CHECKSUM_ERR", + "PPE_DROP_CODE_L3_MC_BRIDGE_ACTION", + "PPE_DROP_CODE_L3_NO_ROUTE_PREHEAD_NAT_ACTION", + "PPE_DROP_CODE_L3_NO_ROUTE_PREHEAD_NAT_ERROR", + "PPE_DROP_CODE_L3_ROUTE_ACTION", + "PPE_DROP_CODE_L3_NO_ROUTE_ACTION", + "PPE_DROP_CODE_L3_NO_ROUTE_NH_INVALID_ACTION", + "PPE_DROP_CODE_L3_NO_ROUTE_PREHEAD_ACTION", + "PPE_DROP_CODE_L3_BRIDGE_ACTION", + "PPE_DROP_CODE_L3_FLOW_ACTION", + "PPE_DROP_CODE_L3_FLOW_MISS_ACTION", + "PPE_DROP_CODE_L2_EXP_MRU_FAIL", + "PPE_DROP_CODE_L2_EXP_MTU_FAIL", + "PPE_DROP_CODE_L3_EXP_IP_PREFIX_BC", + "PPE_DROP_CODE_L3_EXP_MTU_FAIL", + "PPE_DROP_CODE_L3_EXP_MRU_FAIL", + "PPE_DROP_CODE_L3_EXP_ICMP_RDT", + "PPE_DROP_CODE_FAKE_MAC_HEADER_ERR", + "PPE_DROP_CODE_L3_EXP_IP_RT_TTL_ZERO", + "PPE_DROP_CODE_L3_FLOW_SERVICE_CODE_LOOP", + "PPE_DROP_CODE_L3_FLOW_DE_ACCELEARTE", + "PPE_DROP_CODE_L3_EXP_FLOW_SRC_IF_CHK_FAIL", + "PPE_DROP_CODE_L3_FLOW_SYNC_TOGGLE_MISMATCH", + "PPE_DROP_CODE_L3_EXP_MTU_DF_FAIL", + "PPE_DROP_CODE_L3_EXP_PPPOE_MULTICAST", + "PPE_DROP_CODE_IPV4_SG_UNKNOWN", + "PPE_DROP_CODE_IPV6_SG_UNKNOWN", + "PPE_DROP_CODE_ARP_SG_UNKNOWN", + "PPE_DROP_CODE_ND_SG_UNKNOWN", + "PPE_DROP_CODE_IPV4_SG_VIO", + "PPE_DROP_CODE_IPV6_SG_VIO", + "PPE_DROP_CODE_ARP_SG_VIO", + "PPE_DROP_CODE_ND_SG_VIO", + "PPE_DROP_CODE_L2_NEW_MAC_ADDRESS", + "PPE_DROP_CODE_L2_HASH_COLLISION", + "PPE_DROP_CODE_L2_STATION_MOVE", + "PPE_DROP_CODE_L2_LEARN_LIMIT", + "PPE_DROP_CODE_L2_SA_LOOKUP_ACTION", + "PPE_DROP_CODE_L2_DA_LOOKUP_ACTION", + "PPE_DROP_CODE_APP_CTRL_ACTION", + "PPE_DROP_CODE_IN_VLAN_FILTER_ACTION", + "PPE_DROP_CODE_IN_VLAN_XLT_MISS", + "PPE_DROP_CODE_EG_VLAN_FILTER_DROP", + "PPE_DROP_CODE_ACL_PRE_ACTION", + "PPE_DROP_CODE_ACL_POST_ACTION", + "PPE_DROP_CODE_MC_BC_SA", + "PPE_DROP_CODE_NO_DESTINATION", + "PPE_DROP_CODE_STG_IN_FILTER", + "PPE_DROP_CODE_STG_EG_FILTER", + "PPE_DROP_CODE_SOURCE_FILTER_FAIL", + "PPE_DROP_CODE_TRUNK_SEL_FAIL", + "PPE_DROP_CODE_TX_EN_FAIL", + "PPE_DROP_CODE_VLAN_TAG_FMT", + "PPE_DROP_CODE_CRC_ERR", + "PPE_DROP_CODE_PAUSE_FRAME", + "PPE_DROP_CODE_PROMISC", + "PPE_DROP_CODE_ISOLATION", + "PPE_DROP_CODE_MGMT_APP", + "PPE_DROP_CODE_FAKE_L2_PROT_ERR", + "PPE_DROP_CODE_POLICER", +}; + +/* + * nss_ppe_stats_str_cc + * PPE statistics strings for cpu code + */ +static int8_t *nss_ppe_stats_str_cc[NSS_PPE_STATS_CPU_CODE_MAX] = { + "PPE_CPU_CODE_FORWARDING", + "PPE_CPU_CODE_EXP_UNKNOWN_L2_PROT", + "PPE_CPU_CODE_EXP_PPPOE_WRONG_VER_TYPE", + "PPE_CPU_CODE_EXP_WRONG_CODE", + "PPE_CPU_CODE_EXP_PPPOE_UNSUPPORTED_PPP_PROT", + "PPE_CPU_CODE_EXP_WRONG_VER", + "PPE_CPU_CODE_EXP_SMALL_IHL", + "PPE_CPU_CODE_EXP_WITH_OPTION", + "PPE_CPU_CODE_EXP_HDR_INCOMPLETE", + "PPE_CPU_CODE_EXP_IPV4_BAD_TOTAL_LEN", + "PPE_CPU_CODE_EXP_DATA_INCOMPLETE", + "PPE_CPU_CODE_IPV4_FRAG", + "PPE_CPU_CODE_EXP_IPV4_PING_OF_DEATH", + "PPE_CPU_CODE_EXP_SNALL_TTL", + "PPE_CPU_CODE_EXP_IPV4_UNK_IP_PROT", + "PPE_CPU_CODE_EXP_CHECKSUM_ERR", + "PPE_CPU_CODE_EXP_INV_SIP", + "PPE_CPU_CODE_EXP_INV_DIP", + "PPE_CPU_CODE_EXP_LAND_ATTACK", + "PPE_CPU_CODE_EXP_IPV4_AH_HDR_INCOMPLETE", + "PPE_CPU_CODE_EXP_IPV4_AH_CROSS_BORDER", + "PPE_CPU_CODE_EXP_IPV4_ESP_HDR_INCOMPLETE", + "PPE_CPU_CODE_EXP_WRONG_VER", + "PPE_CPU_CODE_EXP_HDR_INCOMPLETE", + "PPE_CPU_CODE_EXP_IPV6_BAD_PAYLOAD_LEN", + "PPE_CPU_CODE_EXP_DATA_INCOMPLETE", + "PPE_CPU_CODE_EXP_IPV6_WITH_EXT_HDR", + "PPE_CPU_CODE_EXP_IPV6_SMALL_HOP_LIMIT", + "PPE_CPU_CODE_EXP_INV_SIP", + "PPE_CPU_CODE_EXP_INV_DIP", + "PPE_CPU_CODE_EXP_LAND_ATTACK", + "PPE_CPU_CODE_IPV6_FRAG", + "PPE_CPU_CODE_EXP_IPV6_PING_OF_DEATH", + "PPE_CPU_CODE_EXP_IPV6_WITH_EXT_HDR", + "PPE_CPU_CODE_EXP_IPV6_UNK_NEXT_HDR", + "PPE_CPU_CODE_EXP_IPV6_MOBILITY_HDR_INCOMPLETE", + "PPE_CPU_CODE_EXP_IPV6_MOBILITY_CROSS_BORDER", + "PPE_CPU_CODE_EXP_IPV6_AH_HDR_INCOMPLETE", + "PPE_CPU_CODE_EXP_IPV6_AH_CROSS_BORDER", + "PPE_CPU_CODE_EXP_IPV6_ESP_HDR_INCOMPLETE", + "PPE_CPU_CODE_EXP_IPV6_ESP_CROSS_BORDER", + "PPE_CPU_CODE_EXP_IPV6_OTHER_HDR_INCOMPLETE", + "PPE_CPU_CODE_EXP_IPV6_OTHER_EXT_CROSS_BORDER", + "PPE_CPU_CODE_EXP_HDR_INCOMPLETE", + "PPE_CPU_CODE_EXP_TCP_HDR_CROSS_BORDER", + "PPE_CPU_CODE_EXP_TCP_SMAE_SP_DP", + "PPE_CPU_CODE_EXP_TCP_SMALL_DATA_OFFSET", + "PPE_CPU_CODE_EXP_FLAGS_0", + "PPE_CPU_CODE_EXP_FLAGS_1", + "PPE_CPU_CODE_EXP_FLAGS_2", + "PPE_CPU_CODE_EXP_FLAGS_3", + "PPE_CPU_CODE_EXP_FLAGS_4", + "PPE_CPU_CODE_EXP_FLAGS_5", + "PPE_CPU_CODE_EXP_FLAGS_6", + "PPE_CPU_CODE_EXP_FLAGS_7", + "PPE_CPU_CODE_EXP_CHECKSUM_ERR", + "PPE_CPU_CODE_EXP_HDR_INCOMPLETE", + "PPE_CPU_CODE_EXP_UDP_HDR_CROSS_BORDER", + "PPE_CPU_CODE_EXP_UDP_SMAE_SP_DP", + "PPE_CPU_CODE_EXP_BAD_LEN", + "PPE_CPU_CODE_EXP_DATA_INCOMPLETE", + "PPE_CPU_CODE_EXP_CHECKSUM_ERR", + "PPE_CPU_CODE_EXP_UDP_LITE_HDR_INCOMPLETE", + "PPE_CPU_CODE_EXP_UDP_LITE_CROSS_BORDER", + "PPE_CPU_CODE_EXP_UDP_LITE_SP_DP", + "PPE_CPU_CODE_EXP_UDP_LITE_CSM_COV_TO_7", + "PPE_CPU_CODE_EXP_UDP_LITE_CSM_TOO_LONG", + "PPE_CPU_CODE_EXP_UDP_LITE_CSM_CROSS_BORDER", + "PPE_CPU_CODE_EXP_UDP_LITE_CHECKSUM_ERR", + "PPE_CPU_CODE_EXP_FAKE_L2_PROT_ERR", + "PPE_CPU_CODE_EXP_FAKE_MAC_HEADER_ERR", + "PPE_CPU_CODE_BITMAP_MAX", + "PPE_CPU_CODE_L2_MRU_FAIL", + "PPE_CPU_CODE_L2_MTU_FAIL", + "PPE_CPU_CODE_L3_EXP_IP_PREFIX_BC", + "PPE_CPU_CODE_L3_MTU_FAIL", + "PPE_CPU_CODE_L3_MRU_FAIL", + "PPE_CPU_CODE_L3_ICMP_RDT", + "PPE_CPU_CODE_L3_EXP_IP_RT_TO_ME", + "PPE_CPU_CODE_L3_EXP_IP_TTL_ZERO", + "PPE_CPU_CODE_L3_FLOW_SERVICE_CODE_LOOP", + "PPE_CPU_CODE_L3_DE_ACCELERATE", + "PPE_CPU_CODE_L3_EXP_FLOW_SRC_CHK_FAIL", + "PPE_CPU_CODE_L3_FLOW_SYNC_TOGGLE_MISMATCH", + "PPE_CPU_CODE_L3_EXP_MTU_DF_FAIL", + "PPE_CPU_CODE_L3_PPPOE_MULTICAST", + "PPE_CPU_CODE_MGMT_OFFSET", + "PPE_CPU_CODE_MGMT_EAPOL", + "PPE_CPU_CODE_PPPOE_DIS", + "PPE_CPU_CODE_MGMT_IGMP", + "PPE_CPU_CODE_ARP_REQ", + "PPE_CPU_CODE_ARP_REP", + "PPE_CPU_CODE_MGMT_DHCPv4", + "PPE_CPU_CODE_MGMT_MLD", + "PPE_CPU_CODE_MGMT_NS", + "PPE_CPU_CODE_MGMT_NA", + "PPE_CPU_CODE_MGMT_DHCPv6", + "PPE_CPU_CODE_PTP_OFFSET", + "PPE_CPU_CODE_PTP_SYNC", + "PPE_CPU_CODE_FOLLOW_UP", + "PPE_CPU_CODE_DELAY_REQ", + "PPE_CPU_CODE_DELAY_RESP", + "PPE_CPU_CODE_PDELAY_REQ", + "PPE_CPU_CODE_PDELAY_RESP", + "PPE_CPU_CODE_PTP_PDELAY_RESP_FOLLOW_UP", + "PPE_CPU_CODE_PTP_ANNOUNCE", + "PPE_CPU_CODE_PTP_MANAGEMENT", + "PPE_CPU_CODE_PTP_SIGNALING", + "PPE_CPU_CODE_PTP_RSV_MSG", + "PPE_CPU_CODE_SG_UNKNOWN", + "PPE_CPU_CODE_SG_UNKNOWN", + "PPE_CPU_CODE_SG_UNKNOWN", + "PPE_CPU_CODE_SG_UNKNOWN", + "PPE_CPU_CODE_SG_VIO", + "PPE_CPU_CODE_SG_VIO", + "PPE_CPU_CODE_SG_VIO", + "PPE_CPU_CODE_SG_VIO", + "PPE_CPU_CODE_L3_ROUTING_IP_TO_ME", + "PPE_CPU_CODE_L3_SNAT_ACTION", + "PPE_CPU_CODE_L3_DNAT_ACTION", + "PPE_CPU_CODE_L3_RT_ACTION", + "PPE_CPU_CODE_L3_BR_ACTION", + "PPE_CPU_CODE_L3_BRIDGE_ACTION", + "PPE_CPU_CODE_L3_ROUTE_PREHEAD_RT_ACTION", + "PPE_CPU_CODE_L3_ROUTE_PREHEAD_SNAPT_ACTION", + "PPE_CPU_CODE_L3_ROUTE_PREHEAD_DNAPT_ACTION", + "PPE_CPU_CODE_L3_ROUTE_PREHEAD_SNAT_ACTION", + "PPE_CPU_CODE_L3_ROUTE_PREHEAD_DNAT_ACTION", + "PPE_CPU_CODE_L3_NO_ROUTE_NAT_ACTION", + "PPE_CPU_CODE_L3_NO_ROUTE_NAT_ERROR", + "PPE_CPU_CODE_ROUTE_ACTION", + "PPE_CPU_CODE_L3_ROUTE_ACTION", + "PPE_CPU_CODE_L3_NO_ROUTE_INVALID_ACTION", + "PPE_CPU_CODE_L3_NO_ROUTE_PREHEAD_ACTION", + "PPE_CPU_CODE_BRIDGE_ACTION", + "PPE_CPU_CODE_FLOW_ACTION", + "PPE_CPU_CODE_L3_MISS_ACTION", + "PPE_CPU_CODE_L2_MAC_ADDRESS", + "PPE_CPU_CODE_HASH_COLLISION", + "PPE_CPU_CODE_STATION_MOVE", + "PPE_CPU_CODE_LEARN_LIMIT", + "PPE_CPU_CODE_L2_LOOKUP_ACTION", + "PPE_CPU_CODE_L2_LOOKUP_ACTION", + "PPE_CPU_CODE_CTRL_ACTION", + "PPE_CPU_CODE_IN_FILTER_ACTION", + "PPE_CPU_CODE_IN_XLT_MISS", + "PPE_CPU_CODE_EG_FILTER_DROP", + "PPE_CPU_CODE_PRE_ACTION", + "PPE_CPU_CODE_POST_ACTION", + "PPE_CPU_CODE_CODE_ACTION", +}; + +/* + * nss_ppe_stats_str_sc + * PPE statistics strings for service-code stats + */ +static int8_t *nss_ppe_stats_str_sc[NSS_PPE_SC_MAX] = { + "SC_NONE ", + "SC_BYPASS_ALL ", + "SC_ADV_QOS_BRIDGED", + "SC_BR_QOS ", + "SC_BNC_0 ", + "SC_BNC_CMPL_0 ", + "SC_ADV_QOS_ROUTED ", + "SC_IPSEC_PPE2EIP ", + "SC_IPSEC_EIP2PPE ", + "SC_PTP ", + "SC_VLAN_FILTER ", + "SC_L3_EXCEPT ", +}; + +/* + * nss_ppe_stats_sync + * PPE connection sync statistics from NSS + */ +void nss_ppe_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_ppe_sync_stats_msg *stats_msg, uint16_t if_num) +{ + uint32_t sc; + spin_lock_bh(&nss_ppe_stats_lock); + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V4_L3_FLOWS] += stats_msg->stats.nss_ppe_v4_l3_flows; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V4_L2_FLOWS] += stats_msg->stats.nss_ppe_v4_l2_flows; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V4_CREATE_REQ] += stats_msg->stats.nss_ppe_v4_create_req; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V4_CREATE_FAIL] += stats_msg->stats.nss_ppe_v4_create_fail; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V4_DESTROY_REQ] += stats_msg->stats.nss_ppe_v4_destroy_req; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V4_DESTROY_FAIL] += stats_msg->stats.nss_ppe_v4_destroy_fail; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V4_MC_CREATE_REQ] += stats_msg->stats.nss_ppe_v4_mc_create_req; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V4_MC_CREATE_FAIL] += stats_msg->stats.nss_ppe_v4_mc_create_fail; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V4_MC_UPDATE_REQ] += stats_msg->stats.nss_ppe_v4_mc_update_req; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V4_MC_UPDATE_FAIL] += stats_msg->stats.nss_ppe_v4_mc_update_fail; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V4_MC_DESTROY_REQ] += stats_msg->stats.nss_ppe_v4_mc_destroy_req; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V4_MC_DESTROY_FAIL] += stats_msg->stats.nss_ppe_v4_mc_destroy_fail; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V4_UNKNOWN_INTERFACE] += stats_msg->stats.nss_ppe_v4_unknown_interface; + + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V6_L3_FLOWS] += stats_msg->stats.nss_ppe_v6_l3_flows; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V6_L2_FLOWS] += stats_msg->stats.nss_ppe_v6_l2_flows; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V6_CREATE_REQ] += stats_msg->stats.nss_ppe_v6_create_req; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V6_CREATE_FAIL] += stats_msg->stats.nss_ppe_v6_create_fail; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V6_DESTROY_REQ] += stats_msg->stats.nss_ppe_v6_destroy_req; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V6_DESTROY_FAIL] += stats_msg->stats.nss_ppe_v6_destroy_fail; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V6_MC_CREATE_REQ] += stats_msg->stats.nss_ppe_v6_mc_create_req; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V6_MC_CREATE_FAIL] += stats_msg->stats.nss_ppe_v6_mc_create_fail; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V6_MC_UPDATE_REQ] += stats_msg->stats.nss_ppe_v6_mc_update_req; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V6_MC_UPDATE_FAIL] += stats_msg->stats.nss_ppe_v6_mc_update_fail; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V6_MC_DESTROY_REQ] += stats_msg->stats.nss_ppe_v6_mc_destroy_req; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V6_MC_DESTROY_FAIL] += stats_msg->stats.nss_ppe_v6_mc_destroy_fail; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_V6_UNKNOWN_INTERFACE] += stats_msg->stats.nss_ppe_v6_unknown_interface; + + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_FAIL_VP_FULL] += stats_msg->stats.nss_ppe_fail_vp_full; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_FAIL_NH_FULL] += stats_msg->stats.nss_ppe_fail_nh_full; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_FAIL_FLOW_FULL] += stats_msg->stats.nss_ppe_fail_flow_full; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_FAIL_HOST_FULL] += stats_msg->stats.nss_ppe_fail_host_full; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_FAIL_PUBIP_FULL] += stats_msg->stats.nss_ppe_fail_pubip_full; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_FAIL_PORT_SETUP] += stats_msg->stats.nss_ppe_fail_port_setup; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_FAIL_RW_FIFO_FULL] += stats_msg->stats.nss_ppe_fail_rw_fifo_full; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_FAIL_FLOW_COMMAND] += stats_msg->stats.nss_ppe_fail_flow_command; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_FAIL_UNKNOWN_PROTO] += stats_msg->stats.nss_ppe_fail_unknown_proto; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_FAIL_PPE_UNRESPONSIVE] += stats_msg->stats.nss_ppe_fail_ppe_unresponsive; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_CE_OPAQUE_INVALID] += stats_msg->stats.nss_ppe_ce_opaque_invalid; + nss_ppe_debug_stats.conn_stats[NSS_PPE_STATS_FAIL_FQG_FULL] += stats_msg->stats.nss_ppe_fail_fqg_full; + + /* + * Update service-code stats. + */ + for (sc = 0; sc < NSS_PPE_SC_MAX; sc++) { + nss_ppe_debug_stats.sc_stats[sc].nss_ppe_sc_cb_unregister += stats_msg->sc_stats[sc].nss_ppe_sc_cb_unregister; + nss_ppe_debug_stats.sc_stats[sc].nss_ppe_sc_cb_success += stats_msg->sc_stats[sc].nss_ppe_sc_cb_success; + nss_ppe_debug_stats.sc_stats[sc].nss_ppe_sc_cb_failure += stats_msg->sc_stats[sc].nss_ppe_sc_cb_failure; + } + + spin_unlock_bh(&nss_ppe_stats_lock); +} + +/* + * nss_ppe_stats_conn_get() + * Get PPE connection statistics. + */ +static void nss_ppe_stats_conn_get(uint32_t *stats) +{ + if (!stats) { + nss_warning("No memory to copy ppe connection stats"); + return; + } + + /* + * Get flow stats + */ + spin_lock_bh(&nss_ppe_stats_lock); + memcpy(stats, nss_ppe_debug_stats.conn_stats, (sizeof(uint32_t) * NSS_PPE_STATS_CONN_MAX)); + spin_unlock_bh(&nss_ppe_stats_lock); +} + +/* + * nss_ppe_stats_sc_get() + * Get PPE service-code statistics. + */ +static void nss_ppe_stats_sc_get(struct nss_ppe_sc_stats_debug *sc_stats) +{ + if (!sc_stats) { + nss_warning("No memory to copy ppe connection stats"); + return; + } + + /* + * Get flow stats + */ + spin_lock_bh(&nss_ppe_stats_lock); + memcpy(sc_stats, nss_ppe_debug_stats.sc_stats, (sizeof(struct nss_ppe_sc_stats_debug) * NSS_PPE_SC_MAX)); + spin_unlock_bh(&nss_ppe_stats_lock); +} + +/* + * nss_ppe_stats_l3_get() + * Get PPE L3 debug statistics. + */ +static void nss_ppe_stats_l3_get(uint32_t *stats) +{ + if (!stats) { + nss_warning("No memory to copy ppe l3 dbg stats\n"); + return; + } + + spin_lock_bh(&nss_ppe_stats_lock); + nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG0_OFFSET); + nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_PPE_STATS_L3_DBG_0]); + + nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG1_OFFSET); + nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_PPE_STATS_L3_DBG_1]); + + nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG2_OFFSET); + nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_PPE_STATS_L3_DBG_2]); + + nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG3_OFFSET); + nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_PPE_STATS_L3_DBG_3]); + + nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG4_OFFSET); + nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_PPE_STATS_L3_DBG_4]); + + nss_ppe_reg_write(PPE_L3_DBG_WR_OFFSET, PPE_L3_DBG_PORT_OFFSET); + nss_ppe_reg_read(PPE_L3_DBG_RD_OFFSET, &stats[NSS_PPE_STATS_L3_DBG_PORT]); + spin_unlock_bh(&nss_ppe_stats_lock); +} + +/* + * nss_ppe_stats_code_get() + * Get PPE CPU and DROP code for last packet processed. + */ +static void nss_ppe_stats_code_get(uint32_t *stats) +{ + uint32_t drop_0, drop_1, cpu_code; + + nss_trace("%s(%d) Start\n", __func__, __LINE__); + if (!stats) { + nss_warning("No memory to copy ppe code\n"); + return; + } + + spin_lock_bh(&nss_ppe_stats_lock); + nss_ppe_reg_write(PPE_PKT_CODE_WR_OFFSET, PPE_PKT_CODE_DROP0_OFFSET); + nss_ppe_reg_read(PPE_PKT_CODE_RD_OFFSET, &drop_0); + + nss_ppe_reg_write(PPE_PKT_CODE_WR_OFFSET, PPE_PKT_CODE_DROP1_OFFSET); + nss_ppe_reg_read(PPE_PKT_CODE_RD_OFFSET, &drop_1); + + stats[NSS_PPE_STATS_CODE_DROP] = PPE_PKT_CODE_DROP_GET(drop_0, drop_1); + + nss_ppe_reg_write(PPE_PKT_CODE_WR_OFFSET, PPE_PKT_CODE_CPU_OFFSET); + nss_ppe_reg_read(PPE_PKT_CODE_RD_OFFSET, &cpu_code); + + stats[NSS_PPE_STATS_CODE_CPU] = PPE_PKT_CODE_CPU_GET(cpu_code); + + spin_unlock_bh(&nss_ppe_stats_lock); +} + +/* + * nss_ppe_port_drop_code_get() + * Get ppe per port drop code. + */ +static void nss_ppe_port_drop_code_get(uint32_t *stats, uint8_t port_id) +{ + uint8_t i; + nss_trace("%s(%d) Start\n", __func__, __LINE__); + if (!stats) { + nss_warning("No memory to copy ppe code\n"); + return; + } + + if (port_id > NSS_PPE_NUM_PHY_PORTS_MAX) { + nss_warning("Port id is out of range\n"); + return; + } + + spin_lock_bh(&nss_ppe_stats_lock); + + for (i = 0; i < NSS_PPE_STATS_DROP_CODE_MAX; i++) { + nss_ppe_reg_read(PPE_DROP_CODE_OFFSET(i, port_id), &stats[i]); + } + + spin_unlock_bh(&nss_ppe_stats_lock); +} + +/* + * nss_ppe_cpu_code_exception_get() + * Get ppe cpu code specific for flow exceptions. + */ +static void nss_ppe_cpu_code_exception_get(uint32_t *stats) +{ + uint8_t i; + nss_trace("%s(%d) Start\n", __func__, __LINE__); + if (!stats) { + nss_warning("No memory to copy ppe code\n"); + return; + } + + spin_lock_bh(&nss_ppe_stats_lock); + + for (i = 0; i < NSS_PPE_STATS_CPU_CODE_EXCEPTION_MAX ; i++) { + nss_ppe_reg_read(PPE_CPU_CODE_OFFSET(i), &stats[i]); + } + + spin_unlock_bh(&nss_ppe_stats_lock); +} + +/* + * nss_ppe_cpu_code_nonexception_get() + * Get ppe cpu code specific for flow exceptions. + */ +static void nss_ppe_cpu_code_nonexception_get(uint32_t *stats) +{ + uint8_t i; + nss_trace("%s(%d) Start\n", __func__, __LINE__); + if (!stats) { + nss_warning("No memory to copy ppe code\n"); + return; + } + + spin_lock_bh(&nss_ppe_stats_lock); + + for (i = 0; i < NSS_PPE_STATS_CPU_CODE_NONEXCEPTION_MAX; i++) { + nss_ppe_reg_read(PPE_CPU_CODE_OFFSET(ppe_cc_nonexception[i]), &stats[i]); + } + + spin_unlock_bh(&nss_ppe_stats_lock); +} + +/* + * nss_ppe_conn_stats_read() + * Read ppe connection statistics + */ +static ssize_t nss_ppe_conn_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int i; + char *lbuf = NULL; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint32_t ppe_stats[NSS_PPE_STATS_CONN_MAX]; + uint32_t max_output_lines = 2 /* header & footer for session stats */ + + NSS_PPE_STATS_CONN_MAX /* PPE flow counters */ + + 2; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + + lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + memset(ppe_stats, 0, sizeof(uint32_t) * NSS_PPE_STATS_CONN_MAX); + + /* + * Get all stats + */ + nss_ppe_stats_conn_get(ppe_stats); + + /* + * flow stats + */ + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe flow counters start:\n\n"); + + for (i = 0; i < NSS_PPE_STATS_CONN_MAX; i++) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "\t%s = %u\n", nss_ppe_stats_str_conn[i], + ppe_stats[i]); + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n"); + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe flow counters end\n"); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr); + + kfree(lbuf); + return bytes_read; +} + +/* + * nss_ppe_sc_stats_read() + * Read ppe service code statistics + */ +static ssize_t nss_ppe_sc_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int i; + char *lbuf = NULL; + size_t size_wr = 0; + ssize_t bytes_read = 0; + struct nss_ppe_sc_stats_debug sc_stats[NSS_PPE_SC_MAX]; + uint32_t max_output_lines = 2 /* header & footer for sc stats */ + + NSS_PPE_SC_MAX /* PPE service-code counters */ + + 2; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + + lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + memset(sc_stats, 0, sizeof(sc_stats)); + + /* + * Get stats + */ + nss_ppe_stats_sc_get(sc_stats); + + /* + * service code stats + */ + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe service code counters start:\n\n"); + + for (i = 0; i < NSS_PPE_SC_MAX; i++) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "\t%s \tcb_unregister:%llu process_ok:%llu process_fail:%llu\n", + nss_ppe_stats_str_sc[i], sc_stats[i].nss_ppe_sc_cb_unregister, + sc_stats[i].nss_ppe_sc_cb_success, sc_stats[i].nss_ppe_sc_cb_failure); + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n"); + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe service code counters end\n"); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr); + + kfree(lbuf); + return bytes_read; +} + +/* + * nss_ppe_l3_stats_read() + * Read PPE L3 debug statistics + */ +static ssize_t nss_ppe_l3_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int i; + char *lbuf = NULL; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint32_t ppe_stats[NSS_PPE_STATS_L3_MAX]; + uint32_t max_output_lines = 2 /* header & footer for session stats */ + + NSS_PPE_STATS_L3_MAX /* PPE flow counters */ + + 2; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + + lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(!lbuf)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + memset(ppe_stats, 0, sizeof(uint32_t) * NSS_PPE_STATS_L3_MAX); + + /* + * Get all stats + */ + nss_ppe_stats_l3_get(ppe_stats); + + /* + * flow stats + */ + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe l3 debug stats start:\n\n"); + + for (i = 0; i < NSS_PPE_STATS_L3_MAX; i++) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "\t%s = 0x%x\n", nss_ppe_stats_str_l3[i], + ppe_stats[i]); + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n"); + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe l3 debug stats end\n"); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr); + + kfree(lbuf); + return bytes_read; +} + +/* + * nss_ppe_code_stats_read() + * Read ppe CPU & DROP code + */ +static ssize_t nss_ppe_code_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int i; + char *lbuf = NULL; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint32_t ppe_stats[NSS_PPE_STATS_CODE_MAX]; + uint32_t max_output_lines = 2 /* header & footer for session stats */ + + NSS_PPE_STATS_CODE_MAX /* PPE flow counters */ + + 2; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + + lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(!lbuf)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + memset(ppe_stats, 0, sizeof(uint32_t) * NSS_PPE_STATS_CODE_MAX); + + /* + * Get all stats + */ + nss_ppe_stats_code_get(ppe_stats); + + /* + * flow stats + */ + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe session stats start:\n\n"); + + for (i = 0; i < NSS_PPE_STATS_CODE_MAX; i++) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "\t%s = %u\n", nss_ppe_stats_str_code[i], + ppe_stats[i]); + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n"); + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe session stats end\n"); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr); + + kfree(lbuf); + return bytes_read; +} + +/* + * nss_ppe_port_dc_stats_read() + * Read PPE per port drop code stats + */ +static ssize_t nss_ppe_port_dc_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i; + + /* + * max output lines = #stats + 2 start tag line + 2 end tag line + five blank lines + */ + uint32_t max_output_lines = (NSS_PPE_STATS_DROP_CODE_MAX + 4) + 5; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + struct nss_stats_data *data = fp->private_data; + uint32_t *ppe_stats; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + ppe_stats = kzalloc(sizeof(uint32_t) * NSS_PPE_STATS_DROP_CODE_MAX, GFP_KERNEL); + if (unlikely(ppe_stats == NULL)) { + kfree(lbuf); + nss_warning("Could not allocate memory for ppe stats buffer"); + return 0; + } + + /* + * Get drop code counters for specific port + */ + nss_ppe_port_drop_code_get(ppe_stats, data->edma_id); + size_wr = scnprintf(lbuf, size_al, "ppe no drop code stats start:\n\n"); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "\t%s = %u\n", nss_ppe_stats_str_dc[0], + ppe_stats[0]); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe no drop code stats end\n\n"); + + /* + * Drop code stats + */ + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "ppe non-zero drop code stats start:\n\n"); + for (i = 1; i < NSS_PPE_STATS_DROP_CODE_MAX; i++) { + /* + * Print only non-zero stats. + */ + if (!ppe_stats[i]) { + continue; + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "\t%s = %u\n", nss_ppe_stats_str_dc[i], + ppe_stats[i]); + } + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe non-zero drop code stats end\n\n"); + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(ppe_stats); + kfree(lbuf); + + return bytes_read; +} + +/* + * nss_ppe_exception_cc_stats_read() + * Read PPE CPU code stats specific to flow exceptions + */ +static ssize_t nss_ppe_exception_cc_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i; + + /* + * max output lines = #stats + start tag line + end tag line + three blank lines + */ + uint32_t max_output_lines = (NSS_PPE_STATS_CPU_CODE_EXCEPTION_MAX + 2) + 3; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint32_t *ppe_stats; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + ppe_stats = kzalloc(sizeof(uint32_t) * NSS_PPE_STATS_CPU_CODE_EXCEPTION_MAX, GFP_KERNEL); + if (unlikely(ppe_stats == NULL)) { + kfree(lbuf); + nss_warning("Could not allocate memory for ppe stats buffer"); + return 0; + } + + /* + * Get CPU code counters for flow specific exceptions + */ + nss_ppe_cpu_code_exception_get(ppe_stats); + + size_wr = scnprintf(lbuf, size_al, "ppe non-zero cpu code flow-exception stats start:\n\n"); + + /* + * CPU code stats + */ + for (i = 0; i < NSS_PPE_STATS_CPU_CODE_EXCEPTION_MAX; i++) { + /* + * Print only non-zero stats. + */ + if (!ppe_stats[i]) { + continue; + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "\t%s = %u\n", nss_ppe_stats_str_cc[i], + ppe_stats[i]); + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe non-zero cpu code flow-exception stats end\n\n"); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(ppe_stats); + kfree(lbuf); + + return bytes_read; +} + +/* + * nss_ppe_nonexception_cc_stats_read() + * Read PPE CPU code stats for other than flow exceptions + */ +static ssize_t nss_ppe_nonexception_cc_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i; + + /* + * max output lines = #stats + start tag line + end tag line + three blank lines + */ + uint32_t max_output_lines = (NSS_PPE_STATS_CPU_CODE_NONEXCEPTION_MAX + 2) + 3; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint32_t *ppe_stats; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + ppe_stats = kzalloc(sizeof(uint32_t) * NSS_PPE_STATS_CPU_CODE_NONEXCEPTION_MAX, GFP_KERNEL); + if (unlikely(ppe_stats == NULL)) { + kfree(lbuf); + nss_warning("Could not allocate memory for ppe stats buffer"); + return 0; + } + + /* + * Get CPU code counters for non flow exceptions + */ + nss_ppe_cpu_code_nonexception_get(ppe_stats); + + /* + * CPU code stats + */ + size_wr = scnprintf(lbuf, size_al, "ppe non-zero cpu code non-flow exception stats start:\n\n"); + for (i = 0; i < NSS_PPE_STATS_CPU_CODE_NONEXCEPTION_MAX; i++) { + /* + * Print only non-zero stats. + */ + if (!ppe_stats[i]) { + continue; + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "\t%s = %u\n", nss_ppe_stats_str_cc[i + NSS_PPE_STATS_CPU_CODE_NONEXCEPTION_START], + ppe_stats[i]); + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nppe non-zero cpu code non-flow exception stats end\n\n"); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(ppe_stats); + kfree(lbuf); + + return bytes_read; +} + +/* + * nss_ppe_conn_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(ppe_conn) + +/* + * nss_ppe_l3_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(ppe_l3) + +/* + * nss_ppe_code_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(ppe_code) + +/* + * nss_ppe_port_dc_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(ppe_port_dc) +/* + * nss_ppe_exception_cc_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(ppe_exception_cc) + +/* + * nss_ppe_nonexception_cc_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(ppe_nonexception_cc) + +/* + * nss_ppe_sc_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(ppe_sc) + +/* + * nss_ppe_stats_dentry_create() + * Create PPE statistics debug entry. + */ +void nss_ppe_stats_dentry_create(void) +{ + int i; + struct dentry *ppe_dentry = NULL; + struct dentry *ppe_conn_d = NULL; + struct dentry *ppe_sc_d = NULL; + struct dentry *ppe_l3_d = NULL; + struct dentry *ppe_ppe_code_d = NULL; + struct dentry *ppe_code_d = NULL; + struct dentry *ppe_drop_d = NULL; + struct dentry *ppe_port_dc_d = NULL; + struct dentry *ppe_cpu_d = NULL; + struct dentry *ppe_exception_d = NULL; + struct dentry *ppe_nonexception_d = NULL; + char file_name[10]; + + ppe_dentry = debugfs_create_dir("ppe", nss_top_main.stats_dentry); + if (unlikely(ppe_dentry == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/ppe directory"); + return; + } + + ppe_conn_d = debugfs_create_file("connection", 0400, ppe_dentry, + &nss_top_main, &nss_ppe_conn_stats_ops); + if (unlikely(ppe_conn_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/ppe/connection file"); + return; + } + + ppe_sc_d = debugfs_create_file("sc_stats", 0400, ppe_dentry, + &nss_top_main, &nss_ppe_sc_stats_ops); + if (unlikely(ppe_sc_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/ppe/sc_stats file"); + return; + } + + ppe_l3_d = debugfs_create_file("l3", 0400, ppe_dentry, + &nss_top_main, &nss_ppe_l3_stats_ops); + if (unlikely(ppe_l3_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/ppe/l3 filed"); + return; + } + + ppe_ppe_code_d = debugfs_create_file("ppe_code", 0400, ppe_dentry, + &nss_top_main, &nss_ppe_code_stats_ops); + if (unlikely(ppe_ppe_code_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/ppe/ppe_code file"); + return; + } + + /* + * ppe exception and drop code stats + */ + ppe_code_d = debugfs_create_dir("code", ppe_dentry); + if (unlikely(ppe_code_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/ppe/code directory"); + return; + } + + ppe_cpu_d = debugfs_create_dir("cpu", ppe_code_d); + if (unlikely(ppe_cpu_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/ppe/code/cpu directory"); + return; + } + + ppe_exception_d = debugfs_create_file("exception", 0400, ppe_cpu_d, + &nss_top_main, &nss_ppe_exception_cc_stats_ops); + if (unlikely(ppe_exception_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/ppe/code/exception file"); + return; + } + + ppe_nonexception_d = debugfs_create_file("non-exception", 0400, ppe_cpu_d, + &nss_top_main, &nss_ppe_nonexception_cc_stats_ops); + if (unlikely(ppe_nonexception_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/ppe/code/non-exception file"); + return; + } + + ppe_drop_d = debugfs_create_dir("drop", ppe_code_d); + if (unlikely(ppe_drop_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/ppe/code/drop directory"); + return; + } + + for (i = 0; i < NSS_PPE_NUM_PHY_PORTS_MAX; i++) { + if (i > 0) { + memset(file_name, 0, sizeof(file_name)); + snprintf(file_name, sizeof(file_name), "%d", i); + } + + ppe_port_dc_d = debugfs_create_file((i == 0) ? "cpu" : file_name, 0400, ppe_drop_d, + (void *)(nss_ptr_t)i, &nss_ppe_port_dc_stats_ops); + if (unlikely(ppe_port_dc_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/ppe/code/drop/%d file", i); + return; + } + } +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ppe_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_ppe_stats.h new file mode 100644 index 000000000..af9c33b3b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ppe_stats.h @@ -0,0 +1,423 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_ppe_stats.h + * NSS PPE statistics header file. + */ + +#ifndef __NSS_PPE_STATS_H +#define __NSS_PPE_STATS_H + +/* + * NSS PPE connection statistics + */ +enum nss_ppe_stats_conn { + NSS_PPE_STATS_V4_L3_FLOWS, /* No of v4 routed flows */ + NSS_PPE_STATS_V4_L2_FLOWS, /* No of v4 bridge flows */ + NSS_PPE_STATS_V4_CREATE_REQ, /* No of v4 create requests */ + NSS_PPE_STATS_V4_CREATE_FAIL, /* No of v4 create failure */ + NSS_PPE_STATS_V4_DESTROY_REQ, /* No of v4 delete requests */ + NSS_PPE_STATS_V4_DESTROY_FAIL, /* No of v4 delete failure */ + NSS_PPE_STATS_V4_MC_CREATE_REQ, /* No of v4 MC create requests */ + NSS_PPE_STATS_V4_MC_CREATE_FAIL, /* No of v4 MC create failure */ + NSS_PPE_STATS_V4_MC_UPDATE_REQ, /* No of v4 MC update requests */ + NSS_PPE_STATS_V4_MC_UPDATE_FAIL, /* No of v4 MC update failure */ + NSS_PPE_STATS_V4_MC_DESTROY_REQ, /* No of v4 MC delete requests */ + NSS_PPE_STATS_V4_MC_DESTROY_FAIL, /* No of v4 MC delete failure */ + NSS_PPE_STATS_V4_UNKNOWN_INTERFACE, /* No of v4 create failure due to invalid if */ + + NSS_PPE_STATS_V6_L3_FLOWS, /* No of v6 routed flows */ + NSS_PPE_STATS_V6_L2_FLOWS, /* No of v6 bridge flows */ + NSS_PPE_STATS_V6_CREATE_REQ, /* No of v6 create requests */ + NSS_PPE_STATS_V6_CREATE_FAIL, /* No of v6 create failure */ + NSS_PPE_STATS_V6_DESTROY_REQ, /* No of v6 delete requests */ + NSS_PPE_STATS_V6_DESTROY_FAIL, /* No of v6 delete failure */ + NSS_PPE_STATS_V6_MC_CREATE_REQ, /* No of v6 MC create requests */ + NSS_PPE_STATS_V6_MC_CREATE_FAIL, /* No of v6 MC create failure */ + NSS_PPE_STATS_V6_MC_UPDATE_REQ, /* No of v6 MC update requests */ + NSS_PPE_STATS_V6_MC_UPDATE_FAIL, /* No of v6 MC update failure */ + NSS_PPE_STATS_V6_MC_DESTROY_REQ, /* No of v6 MC delete requests */ + NSS_PPE_STATS_V6_MC_DESTROY_FAIL, /* No of v6 MC delete failure */ + NSS_PPE_STATS_V6_UNKNOWN_INTERFACE, /* No of v6 create failure due to invalid if */ + + NSS_PPE_STATS_FAIL_VP_FULL, /* Create req fail due to VP table full */ + NSS_PPE_STATS_FAIL_NH_FULL, /* Create req fail due to nexthop table full */ + NSS_PPE_STATS_FAIL_FLOW_FULL, /* Create req fail due to flow table full */ + NSS_PPE_STATS_FAIL_HOST_FULL, /* Create req fail due to host table full */ + NSS_PPE_STATS_FAIL_PUBIP_FULL, /* Create req fail due to pub-ip table full */ + NSS_PPE_STATS_FAIL_PORT_SETUP, /* Create req fail due to PPE port not setup */ + NSS_PPE_STATS_FAIL_RW_FIFO_FULL, /* Create req fail due to rw fifo full */ + NSS_PPE_STATS_FAIL_FLOW_COMMAND, /* Create req fail due to PPE flow command failure */ + NSS_PPE_STATS_FAIL_UNKNOWN_PROTO, /* Create req fail due to unknown protocol */ + NSS_PPE_STATS_FAIL_PPE_UNRESPONSIVE, /* Create req fail due to PPE not responding */ + NSS_PPE_STATS_CE_OPAQUE_INVALID, /* Create req fail due to invalid opaque in CE */ + NSS_PPE_STATS_FAIL_FQG_FULL, /* Create req fail due to flow qos group full */ + NSS_PPE_STATS_CONN_MAX +}; + +/* + * NSS PPE L3 statistics + */ +enum nss_ppe_stats_l3 { + NSS_PPE_STATS_L3_DBG_0, /* PPE L3 debug register 0 */ + NSS_PPE_STATS_L3_DBG_1, /* PPE L3 debug register 1 */ + NSS_PPE_STATS_L3_DBG_2, /* PPE L3 debug register 2 */ + NSS_PPE_STATS_L3_DBG_3, /* PPE L3 debug register 3 */ + NSS_PPE_STATS_L3_DBG_4, /* PPE L3 debug register 4 */ + NSS_PPE_STATS_L3_DBG_PORT, /* PPE L3 debug register Port */ + NSS_PPE_STATS_L3_MAX +}; + +/* + * NSS PPE_code statistics + */ +enum nss_ppe_stats_code { + NSS_PPE_STATS_CODE_CPU, /* PPE CPU code for last packet processed */ + NSS_PPE_STATS_CODE_DROP, /* PPE DROP code for last packet processed */ + NSS_PPE_STATS_CODE_MAX +}; + +/* + * PPE drop codes + */ +enum nss_ppe_stats_dc { + NSS_PPE_STATS_DROP_CODE_UNKNOWN, /* PPE drop code unknown */ + NSS_PPE_STATS_DROP_CODE_EXP_UNKNOWN_L2_PROT, /* PPE drop code exp unknown l2 prot */ + NSS_PPE_STATS_DROP_CODE_EXP_PPPOE_WRONG_VER_TYPE, /* PPE drop code exp pppoe wrong ver type */ + NSS_PPE_STATS_DROP_CODE_EXP_PPPOE_WRONG_CODE, /* PPE drop code exp pppoe wrong code */ + NSS_PPE_STATS_DROP_CODE_EXP_PPPOE_UNSUPPORTED_PPP_PROT, /* PPE drop code exp pppoe unsupported ppp prot */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV4_WRONG_VER, /* PPE drop code exp ipv4 wrong ver */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV4_SMALL_IHL, /* PPE drop code exp ipv4 small ihl */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV4_WITH_OPTION, /* PPE drop code exp ipv4 with option */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV4_HDR_INCOMPLETE, /* PPE drop code exp ipv4 hdr incomplete */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV4_BAD_TOTAL_LEN, /* PPE drop code exp ipv4 bad total len */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV4_DATA_INCOMPLETE, /* PPE drop code exp ipv4 data incomplete */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV4_FRAG, /* PPE drop code exp ipv4 frag */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV4_PING_OF_DEATH, /* PPE drop code exp ipv4 ping of death */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV4_SNALL_TTL, /* PPE drop code exp ipv4 snall ttl */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV4_UNK_IP_PROT, /* PPE drop code exp ipv4 unk ip prot */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV4_CHECKSUM_ERR, /* PPE drop code exp ipv4 checksum err */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV4_INV_SIP, /* PPE drop code exp ipv4 inv sip */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV4_INV_DIP, /* PPE drop code exp ipv4 inv dip */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV4_LAND_ATTACK, /* PPE drop code exp ipv4 land attack */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV4_AH_HDR_INCOMPLETE, /* PPE drop code exp ipv4 ah hdr incomplete */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV4_AH_HDR_CROSS_BORDER, /* PPE drop code exp ipv4 ah hdr cross border */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV4_ESP_HDR_INCOMPLETE, /* PPE drop code exp ipv4 esp hdr incomplete */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV6_WRONG_VER, /* PPE drop code exp ipv6 wrong ver */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV6_HDR_INCOMPLETE, /* PPE drop code exp ipv6 hdr incomplete */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV6_BAD_PAYLOAD_LEN, /* PPE drop code exp ipv6 bad payload len */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV6_DATA_INCOMPLETE, /* PPE drop code exp ipv6 data incomplete */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV6_WITH_EXT_HDR, /* PPE drop code exp ipv6 with ext hdr */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV6_SMALL_HOP_LIMIT, /* PPE drop code exp ipv6 small hop limit */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV6_INV_SIP, /* PPE drop code exp ipv6 inv sip */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV6_INV_DIP, /* PPE drop code exp ipv6 inv dip */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV6_LAND_ATTACK, /* PPE drop code exp ipv6 land attack */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV6_FRAG, /* PPE drop code exp ipv6 frag */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV6_PING_OF_DEATH, /* PPE drop code exp ipv6 ping of death */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV6_WITH_MORE_EXT_HDR, /* PPE drop code exp ipv6 with more ext hdr */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV6_UNK_LAST_NEXT_HDR, /* PPE drop code exp ipv6 unk last next hdr */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV6_MOBILITY_HDR_INCOMPLETE, /* PPE drop code exp ipv6 mobility hdr incomplete */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV6_MOBILITY_HDR_CROSS_BORDER, /* PPE drop code exp ipv6 mobility hdr cross border */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV6_AH_HDR_INCOMPLETE, /* PPE drop code exp ipv6 ah hdr incomplete */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV6_AH_HDR_CROSS_BORDER, /* PPE drop code exp ipv6 ah hdr cross border */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV6_ESP_HDR_INCOMPLETE, /* PPE drop code exp ipv6 esp hdr incomplete */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV6_ESP_HDR_CROSS_BORDER, /* PPE drop code exp ipv6 esp hdr cross border */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV6_OTHER_EXT_HDR_INCOMPLETE, /* PPE drop code exp ipv6 other ext hdr incomplete */ + NSS_PPE_STATS_DROP_CODE_EXP_IPV6_OTHER_EXT_HDR_CROSS_BORDER, /* PPE drop code exp ipv6 other ext hdr cross border */ + NSS_PPE_STATS_DROP_CODE_EXP_TCP_HDR_INCOMPLETE, /* PPE drop code exp tcp hdr incomplete */ + NSS_PPE_STATS_DROP_CODE_EXP_TCP_HDR_CROSS_BORDER, /* PPE drop code exp tcp hdr cross border */ + NSS_PPE_STATS_DROP_CODE_EXP_TCP_SMAE_SP_DP, /* PPE drop code exp tcp smae sp dp */ + NSS_PPE_STATS_DROP_CODE_EXP_TCP_SMALL_DATA_OFFSET, /* PPE drop code exp tcp small data offset */ + NSS_PPE_STATS_DROP_CODE_EXP_TCP_FLAGS_0, /* PPE drop code exp tcp flags 0 */ + NSS_PPE_STATS_DROP_CODE_EXP_TCP_FLAGS_1, /* PPE drop code exp tcp flags 1 */ + NSS_PPE_STATS_DROP_CODE_EXP_TCP_FLAGS_2, /* PPE drop code exp tcp flags 2 */ + NSS_PPE_STATS_DROP_CODE_EXP_TCP_FLAGS_3, /* PPE drop code exp tcp flags 3 */ + NSS_PPE_STATS_DROP_CODE_EXP_TCP_FLAGS_4, /* PPE drop code exp tcp flags 4 */ + NSS_PPE_STATS_DROP_CODE_EXP_TCP_FLAGS_5, /* PPE drop code exp tcp flags 5 */ + NSS_PPE_STATS_DROP_CODE_EXP_TCP_FLAGS_6, /* PPE drop code exp tcp flags 6 */ + NSS_PPE_STATS_DROP_CODE_EXP_TCP_FLAGS_7, /* PPE drop code exp tcp flags 7 */ + NSS_PPE_STATS_DROP_CODE_EXP_TCP_CHECKSUM_ERR, /* PPE drop code exp tcp checksum err */ + NSS_PPE_STATS_DROP_CODE_EXP_UDP_HDR_INCOMPLETE, /* PPE drop code exp udp hdr incomplete */ + NSS_PPE_STATS_DROP_CODE_EXP_UDP_HDR_CROSS_BORDER, /* PPE drop code exp udp hdr cross border */ + NSS_PPE_STATS_DROP_CODE_EXP_UDP_SMAE_SP_DP, /* PPE drop code exp udp smae sp dp */ + NSS_PPE_STATS_DROP_CODE_EXP_UDP_BAD_LEN, /* PPE drop code exp udp bad len */ + NSS_PPE_STATS_DROP_CODE_EXP_UDP_DATA_INCOMPLETE, /* PPE drop code exp udp data incomplete */ + NSS_PPE_STATS_DROP_CODE_EXP_UDP_CHECKSUM_ERR, /* PPE drop code exp udp checksum err */ + NSS_PPE_STATS_DROP_CODE_EXP_UDP_LITE_HDR_INCOMPLETE, /* PPE drop code exp udp lite hdr incomplete */ + NSS_PPE_STATS_DROP_CODE_EXP_UDP_LITE_HDR_CROSS_BORDER, /* PPE drop code exp udp lite hdr cross border */ + NSS_PPE_STATS_DROP_CODE_EXP_UDP_LITE_SMAE_SP_DP, /* PPE drop code exp udp lite smae sp dp */ + NSS_PPE_STATS_DROP_CODE_EXP_UDP_LITE_CSM_COV_1_TO_7, /* PPE drop code exp udp lite csm cov 1 to 7 */ + NSS_PPE_STATS_DROP_CODE_EXP_UDP_LITE_CSM_COV_TOO_LONG, /* PPE drop code exp udp lite csm cov too long */ + NSS_PPE_STATS_DROP_CODE_EXP_UDP_LITE_CSM_COV_CROSS_BORDER, /* PPE drop code exp udp lite csm cov cross border */ + NSS_PPE_STATS_DROP_CODE_EXP_UDP_LITE_CHECKSUM_ERR, /* PPE drop code exp udp lite checksum err */ + NSS_PPE_STATS_DROP_CODE_L3_MC_BRIDGE_ACTION, /* PPE drop code l3 mc bridge action */ + NSS_PPE_STATS_DROP_CODE_L3_NO_ROUTE_PREHEAD_NAT_ACTION, /* PPE drop code l3 no route prehead nat action */ + NSS_PPE_STATS_DROP_CODE_L3_NO_ROUTE_PREHEAD_NAT_ERROR, /* PPE drop code l3 no route prehead nat error */ + NSS_PPE_STATS_DROP_CODE_L3_ROUTE_ACTION, /* PPE drop code l3 route action */ + NSS_PPE_STATS_DROP_CODE_L3_NO_ROUTE_ACTION, /* PPE drop code l3 no route action */ + NSS_PPE_STATS_DROP_CODE_L3_NO_ROUTE_NH_INVALID_ACTION, /* PPE drop code l3 no route nh invalid action */ + NSS_PPE_STATS_DROP_CODE_L3_NO_ROUTE_PREHEAD_ACTION, /* PPE drop code l3 no route prehead action */ + NSS_PPE_STATS_DROP_CODE_L3_BRIDGE_ACTION, /* PPE drop code l3 bridge action */ + NSS_PPE_STATS_DROP_CODE_L3_FLOW_ACTION, /* PPE drop code l3 flow action */ + NSS_PPE_STATS_DROP_CODE_L3_FLOW_MISS_ACTION, /* PPE drop code l3 flow miss action */ + NSS_PPE_STATS_DROP_CODE_L2_EXP_MRU_FAIL, /* PPE drop code l2 exp mru fail */ + NSS_PPE_STATS_DROP_CODE_L2_EXP_MTU_FAIL, /* PPE drop code l2 exp mtu fail */ + NSS_PPE_STATS_DROP_CODE_L3_EXP_IP_PREFIX_BC, /* PPE drop code l3 exp ip prefix bc */ + NSS_PPE_STATS_DROP_CODE_L3_EXP_MTU_FAIL, /* PPE drop code l3 exp mtu fail */ + NSS_PPE_STATS_DROP_CODE_L3_EXP_MRU_FAIL, /* PPE drop code l3 exp mru fail */ + NSS_PPE_STATS_DROP_CODE_L3_EXP_ICMP_RDT, /* PPE drop code l3 exp icmp rdt */ + NSS_PPE_STATS_DROP_CODE_FAKE_MAC_HEADER_ERR, /* PPE drop code fake mac header err */ + NSS_PPE_STATS_DROP_CODE_L3_EXP_IP_RT_TTL_ZERO, /* PPE drop code l3 exp ip rt ttl zero */ + NSS_PPE_STATS_DROP_CODE_L3_FLOW_SERVICE_CODE_LOOP, /* PPE drop code l3 flow service code loop */ + NSS_PPE_STATS_DROP_CODE_L3_FLOW_DE_ACCELEARTE, /* PPE drop code l3 flow de accelearte */ + NSS_PPE_STATS_DROP_CODE_L3_EXP_FLOW_SRC_IF_CHK_FAIL, /* PPE drop code l3 exp flow src if chk fail */ + NSS_PPE_STATS_DROP_CODE_L3_FLOW_SYNC_TOGGLE_MISMATCH, /* PPE drop code l3 flow sync toggle mismatch */ + NSS_PPE_STATS_DROP_CODE_L3_EXP_MTU_DF_FAIL, /* PPE drop code l3 exp mtu df fail */ + NSS_PPE_STATS_DROP_CODE_L3_EXP_PPPOE_MULTICAST, /* PPE drop code l3 exp pppoe multicast */ + NSS_PPE_STATS_DROP_CODE_IPV4_SG_UNKNOWN, /* PPE drop code ipv4 sg unknown */ + NSS_PPE_STATS_DROP_CODE_IPV6_SG_UNKNOWN, /* PPE drop code ipv6 sg unknown */ + NSS_PPE_STATS_DROP_CODE_ARP_SG_UNKNOWN, /* PPE drop code arp sg unknown */ + NSS_PPE_STATS_DROP_CODE_ND_SG_UNKNOWN, /* PPE drop code nd sg unknown */ + NSS_PPE_STATS_DROP_CODE_IPV4_SG_VIO, /* PPE drop code ipv4 sg vio */ + NSS_PPE_STATS_DROP_CODE_IPV6_SG_VIO, /* PPE drop code ipv6 sg vio */ + NSS_PPE_STATS_DROP_CODE_ARP_SG_VIO, /* PPE drop code arp sg vio */ + NSS_PPE_STATS_DROP_CODE_ND_SG_VIO, /* PPE drop code nd sg vio */ + NSS_PPE_STATS_DROP_CODE_L2_NEW_MAC_ADDRESS, /* PPE drop code l2 new mac address */ + NSS_PPE_STATS_DROP_CODE_L2_HASH_COLLISION, /* PPE drop code l2 hash collision */ + NSS_PPE_STATS_DROP_CODE_L2_STATION_MOVE, /* PPE drop code l2 station move */ + NSS_PPE_STATS_DROP_CODE_L2_LEARN_LIMIT, /* PPE drop code l2 learn limit */ + NSS_PPE_STATS_DROP_CODE_L2_SA_LOOKUP_ACTION, /* PPE drop code l2 sa lookup action */ + NSS_PPE_STATS_DROP_CODE_L2_DA_LOOKUP_ACTION, /* PPE drop code l2 da lookup action */ + NSS_PPE_STATS_DROP_CODE_APP_CTRL_ACTION, /* PPE drop code app ctrl action */ + NSS_PPE_STATS_DROP_CODE_IN_VLAN_FILTER_ACTION, /* PPE drop code in vlan filter action */ + NSS_PPE_STATS_DROP_CODE_IN_VLAN_XLT_MISS, /* PPE drop code in vlan xlt miss */ + NSS_PPE_STATS_DROP_CODE_EG_VLAN_FILTER_DROP, /* PPE drop code eg vlan filter drop */ + NSS_PPE_STATS_DROP_CODE_ACL_PRE_ACTION, /* PPE drop code acl pre action */ + NSS_PPE_STATS_DROP_CODE_ACL_POST_ACTION, /* PPE drop code acl post action */ + NSS_PPE_STATS_DROP_CODE_MC_BC_SA, /* PPE drop code mc bc sa */ + NSS_PPE_STATS_DROP_CODE_NO_DESTINATION, /* PPE drop code no destination */ + NSS_PPE_STATS_DROP_CODE_STG_IN_FILTER, /* PPE drop code stg in filter */ + NSS_PPE_STATS_DROP_CODE_STG_EG_FILTER, /* PPE drop code stg eg filter */ + NSS_PPE_STATS_DROP_CODE_SOURCE_FILTER_FAIL, /* PPE drop code source filter fail */ + NSS_PPE_STATS_DROP_CODE_TRUNK_SEL_FAIL, /* PPE drop code trunk sel fail */ + NSS_PPE_STATS_DROP_CODE_TX_EN_FAIL, /* PPE drop code tx en fail */ + NSS_PPE_STATS_DROP_CODE_VLAN_TAG_FMT, /* PPE drop code vlan tag fmt */ + NSS_PPE_STATS_DROP_CODE_CRC_ERR, /* PPE drop code crc err */ + NSS_PPE_STATS_DROP_CODE_PAUSE_FRAME, /* PPE drop code pause frame */ + NSS_PPE_STATS_DROP_CODE_PROMISC, /* PPE drop code promisc */ + NSS_PPE_STATS_DROP_CODE_ISOLATION, /* PPE drop code isolation */ + NSS_PPE_STATS_DROP_CODE_MGMT_APP, /* PPE drop code mgmt app */ + NSS_PPE_STATS_DROP_CODE_FAKE_L2_PROT_ERR, /* PPE drop code fake l2 prot err */ + NSS_PPE_STATS_DROP_CODE_POLICER, /* PPE drop code policer */ + NSS_PPE_STATS_DROP_CODE_MAX /* PPE drop code max */ +}; + +/* + * PPE CPU codes + */ +#define NSS_PPE_STATS_CPU_CODE_MAX 150 +#define NSS_PPE_STATS_CPU_CODE_EXCEPTION_MAX 69 +#define NSS_PPE_STATS_CPU_CODE_NONEXCEPTION_START 69 +#define NSS_PPE_STATS_CPU_CODE_NONEXCEPTION_MAX (NSS_PPE_STATS_CPU_CODE_MAX - NSS_PPE_STATS_CPU_CODE_NONEXCEPTION_START) + +enum nss_ppe_stats_cc { + NSS_PPE_STATS_CPU_CODE_FORWARDING = 0, /* PPE cpu code forwarding */ + NSS_PPE_STATS_CPU_CODE_EXP_UNKNOWN_L2_PROT = 1, /* PPE cpu code exp unknown l2 prot */ + NSS_PPE_STATS_CPU_CODE_EXP_PPPOE_WRONG_VER_TYPE = 2, /* PPE cpu code exp pppoe wrong ver type */ + NSS_PPE_STATS_CPU_CODE_EXP_PPPOE_WRONG_CODE = 3, /* PPE cpu code exp pppoe wrong code */ + NSS_PPE_STATS_CPU_CODE_EXP_PPPOE_UNSUPPORTED_PPP_PROT = 4, /* PPE cpu code exp pppoe unsupported ppp prot */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV4_WRONG_VER = 5, /* PPE cpu code exp ipv4 wrong ver */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV4_SMALL_IHL = 6, /* PPE cpu code exp ipv4 small ihl */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV4_WITH_OPTION = 7, /* PPE cpu code exp ipv4 with option */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV4_HDR_INCOMPLETE = 8, /* PPE cpu code exp ipv4 hdr incomplete */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV4_BAD_TOTAL_LEN = 9, /* PPE cpu code exp ipv4 bad total len */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV4_DATA_INCOMPLETE = 10, /* PPE cpu code exp ipv4 data incomplete */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV4_FRAG = 11, /* PPE cpu code exp ipv4 frag */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV4_PING_OF_DEATH = 12, /* PPE cpu code exp ipv4 ping of death */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV4_SNALL_TTL = 13, /* PPE cpu code exp ipv4 snall ttl */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV4_UNK_IP_PROT = 14, /* PPE cpu code exp ipv4 unk ip prot */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV4_CHECKSUM_ERR = 15, /* PPE cpu code exp ipv4 checksum err */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV4_INV_SIP = 16, /* PPE cpu code exp ipv4 inv sip */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV4_INV_DIP = 17, /* PPE cpu code exp ipv4 inv dip */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV4_LAND_ATTACK = 18, /* PPE cpu code exp ipv4 land attack */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV4_AH_HDR_INCOMPLETE = 19, /* PPE cpu code exp ipv4 ah hdr incomplete */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV4_AH_HDR_CROSS_BORDER = 20, /* PPE cpu code exp ipv4 ah hdr cross border */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV4_ESP_HDR_INCOMPLETE = 21, /* PPE cpu code exp ipv4 esp hdr incomplete */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV6_WRONG_VER = 22, /* PPE cpu code exp ipv6 wrong ver */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV6_HDR_INCOMPLETE = 23, /* PPE cpu code exp ipv6 hdr incomplete */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV6_BAD_PAYLOAD_LEN = 24, /* PPE cpu code exp ipv6 bad payload len */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV6_DATA_INCOMPLETE = 25, /* PPE cpu code exp ipv6 data incomplete */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV6_WITH_EXT_HDR = 26, /* PPE cpu code exp ipv6 with ext hdr */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV6_SMALL_HOP_LIMIT = 27, /* PPE cpu code exp ipv6 small hop limit */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV6_INV_SIP = 28, /* PPE cpu code exp ipv6 inv sip */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV6_INV_DIP = 29, /* PPE cpu code exp ipv6 inv dip */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV6_LAND_ATTACK = 30, /* PPE cpu code exp ipv6 land attack */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV6_FRAG = 31, /* PPE cpu code exp ipv6 frag */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV6_PING_OF_DEATH = 32, /* PPE cpu code exp ipv6 ping of death */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV6_WITH_MORE_EXT_HDR = 33, /* PPE cpu code exp ipv6 with more ext hdr */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV6_UNK_LAST_NEXT_HDR = 34, /* PPE cpu code exp ipv6 unk last next hdr */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV6_MOBILITY_HDR_INCOMPLETE = 35, /* PPE cpu code exp ipv6 mobility hdr incomplete */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV6_MOBILITY_HDR_CROSS_BORDER = 36, /* PPE cpu code exp ipv6 mobility hdr cross border */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV6_AH_HDR_INCOMPLETE = 37, /* PPE cpu code exp ipv6 ah hdr incomplete */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV6_AH_HDR_CROSS_BORDER = 38, /* PPE cpu code exp ipv6 ah hdr cross border */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV6_ESP_HDR_INCOMPLETE = 39, /* PPE cpu code exp ipv6 esp hdr incomplete */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV6_ESP_HDR_CROSS_BORDER = 40, /* PPE cpu code exp ipv6 esp hdr cross border */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV6_OTHER_EXT_HDR_INCOMPLETE = 41, /* PPE cpu code exp ipv6 other ext hdr incomplete */ + NSS_PPE_STATS_CPU_CODE_EXP_IPV6_OTHER_EXT_HDR_CROSS_BORDER = 42, /* PPE cpu code exp ipv6 other ext hdr cross border */ + NSS_PPE_STATS_CPU_CODE_EXP_TCP_HDR_INCOMPLETE = 43, /* PPE cpu code exp tcp hdr incomplete */ + NSS_PPE_STATS_CPU_CODE_EXP_TCP_HDR_CROSS_BORDER = 44, /* PPE cpu code exp tcp hdr cross border */ + NSS_PPE_STATS_CPU_CODE_EXP_TCP_SMAE_SP_DP = 45, /* PPE cpu code exp tcp smae sp dp */ + NSS_PPE_STATS_CPU_CODE_EXP_TCP_SMALL_DATA_OFFSET = 46, /* PPE cpu code exp tcp small data offset */ + NSS_PPE_STATS_CPU_CODE_EXP_TCP_FLAGS_0 = 47, /* PPE cpu code exp tcp flags 0 */ + NSS_PPE_STATS_CPU_CODE_EXP_TCP_FLAGS_1 = 48, /* PPE cpu code exp tcp flags 1 */ + NSS_PPE_STATS_CPU_CODE_EXP_TCP_FLAGS_2 = 49, /* PPE cpu code exp tcp flags 2 */ + NSS_PPE_STATS_CPU_CODE_EXP_TCP_FLAGS_3 = 50, /* PPE cpu code exp tcp flags 3 */ + NSS_PPE_STATS_CPU_CODE_EXP_TCP_FLAGS_4 = 51, /* PPE cpu code exp tcp flags 4 */ + NSS_PPE_STATS_CPU_CODE_EXP_TCP_FLAGS_5 = 52, /* PPE cpu code exp tcp flags 5 */ + NSS_PPE_STATS_CPU_CODE_EXP_TCP_FLAGS_6 = 53, /* PPE cpu code exp tcp flags 6 */ + NSS_PPE_STATS_CPU_CODE_EXP_TCP_FLAGS_7 = 54, /* PPE cpu code exp tcp flags 7 */ + NSS_PPE_STATS_CPU_CODE_EXP_TCP_CHECKSUM_ERR = 55, /* PPE cpu code exp tcp checksum err */ + NSS_PPE_STATS_CPU_CODE_EXP_UDP_HDR_INCOMPLETE = 56, /* PPE cpu code exp udp hdr incomplete */ + NSS_PPE_STATS_CPU_CODE_EXP_UDP_HDR_CROSS_BORDER = 57, /* PPE cpu code exp udp hdr cross border */ + NSS_PPE_STATS_CPU_CODE_EXP_UDP_SMAE_SP_DP = 58, /* PPE cpu code exp udp smae sp dp */ + NSS_PPE_STATS_CPU_CODE_EXP_UDP_BAD_LEN = 59, /* PPE cpu code exp udp bad len */ + NSS_PPE_STATS_CPU_CODE_EXP_UDP_DATA_INCOMPLETE = 60, /* PPE cpu code exp udp data incomplete */ + NSS_PPE_STATS_CPU_CODE_EXP_UDP_CHECKSUM_ERR = 61, /* PPE cpu code exp udp checksum err */ + NSS_PPE_STATS_CPU_CODE_EXP_UDP_LITE_HDR_INCOMPLETE = 62, /* PPE cpu code exp udp lite hdr incomplete */ + NSS_PPE_STATS_CPU_CODE_EXP_UDP_LITE_HDR_CROSS_BORDER = 63, /* PPE cpu code exp udp lite hdr cross border */ + NSS_PPE_STATS_CPU_CODE_EXP_UDP_LITE_SMAE_SP_DP = 64, /* PPE cpu code exp udp lite smae sp dp */ + NSS_PPE_STATS_CPU_CODE_EXP_UDP_LITE_CSM_COV_1_TO_7 = 65, /* PPE cpu code exp udp lite csm cov 1 to 7 */ + NSS_PPE_STATS_CPU_CODE_EXP_UDP_LITE_CSM_COV_TOO_LONG = 66, /* PPE cpu code exp udp lite csm cov too long */ + NSS_PPE_STATS_CPU_CODE_EXP_UDP_LITE_CSM_COV_CROSS_BORDER = 67, /* PPE cpu code exp udp lite csm cov cross border */ + NSS_PPE_STATS_CPU_CODE_EXP_UDP_LITE_CHECKSUM_ERR = 68, /* PPE cpu code exp udp lite checksum err */ + NSS_PPE_STATS_CPU_CODE_EXP_FAKE_L2_PROT_ERR = 69, /* PPE cpu code exp fake l2 prot err */ + NSS_PPE_STATS_CPU_CODE_EXP_FAKE_MAC_HEADER_ERR = 70, /* PPE cpu code exp fake mac header err */ + NSS_PPE_STATS_CPU_CODE_EXP_BITMAP_MAX = 78, /* PPE cpu code exp bitmap max */ + NSS_PPE_STATS_CPU_CODE_L2_EXP_MRU_FAIL = 79, /* PPE cpu code l2 exp mru fail */ + NSS_PPE_STATS_CPU_CODE_L2_EXP_MTU_FAIL = 80, /* PPE cpu code l2 exp mtu fail */ + NSS_PPE_STATS_CPU_CODE_L3_EXP_IP_PREFIX_BC = 81, /* PPE cpu code l3 exp ip prefix bc */ + NSS_PPE_STATS_CPU_CODE_L3_EXP_MTU_FAIL = 82, /* PPE cpu code l3 exp mtu fail */ + NSS_PPE_STATS_CPU_CODE_L3_EXP_MRU_FAIL = 83, /* PPE cpu code l3 exp mru fail */ + NSS_PPE_STATS_CPU_CODE_L3_EXP_ICMP_RDT = 84, /* PPE cpu code l3 exp icmp rdt */ + NSS_PPE_STATS_CPU_CODE_L3_EXP_IP_RT_TTL1_TO_ME = 85, /* PPE cpu code l3 exp ip rt ttl1 to me */ + NSS_PPE_STATS_CPU_CODE_L3_EXP_IP_RT_TTL_ZERO = 86, /* PPE cpu code l3 exp ip rt ttl zero */ + NSS_PPE_STATS_CPU_CODE_L3_FLOW_SERVICE_CODE_LOOP = 87, /* PPE cpu code l3 flow service code loop */ + NSS_PPE_STATS_CPU_CODE_L3_FLOW_DE_ACCELERATE = 88, /* PPE cpu code l3 flow de accelerate */ + NSS_PPE_STATS_CPU_CODE_L3_EXP_FLOW_SRC_IF_CHK_FAIL = 89, /* PPE cpu code l3 exp flow src if chk fail */ + NSS_PPE_STATS_CPU_CODE_L3_FLOW_SYNC_TOGGLE_MISMATCH = 90, /* PPE cpu code l3 flow sync toggle mismatch */ + NSS_PPE_STATS_CPU_CODE_L3_EXP_MTU_DF_FAIL = 91, /* PPE cpu code l3 exp mtu df fail */ + NSS_PPE_STATS_CPU_CODE_L3_EXP_PPPOE_MULTICAST = 92, /* PPE cpu code l3 exp pppoe multicast */ + NSS_PPE_STATS_CPU_CODE_MGMT_OFFSET = 96, /* PPE cpu code mgmt offset */ + NSS_PPE_STATS_CPU_CODE_MGMT_EAPOL = 97, /* PPE cpu code mgmt eapol */ + NSS_PPE_STATS_CPU_CODE_MGMT_PPPOE_DIS = 98, /* PPE cpu code mgmt pppoe dis */ + NSS_PPE_STATS_CPU_CODE_MGMT_IGMP = 99, /* PPE cpu code mgmt igmp */ + NSS_PPE_STATS_CPU_CODE_MGMT_ARP_REQ = 100, /* PPE cpu code mgmt arp req */ + NSS_PPE_STATS_CPU_CODE_MGMT_ARP_REP = 101, /* PPE cpu code mgmt arp rep */ + NSS_PPE_STATS_CPU_CODE_MGMT_DHCPv4 = 102, /* PPE cpu code mgmt dhcpv4 */ + NSS_PPE_STATS_CPU_CODE_MGMT_MLD = 107, /* PPE cpu code mgmt mld */ + NSS_PPE_STATS_CPU_CODE_MGMT_NS = 108, /* PPE cpu code mgmt ns */ + NSS_PPE_STATS_CPU_CODE_MGMT_NA = 109, /* PPE cpu code mgmt na */ + NSS_PPE_STATS_CPU_CODE_MGMT_DHCPv6 = 110, /* PPE cpu code mgmt dhcpv6 */ + NSS_PPE_STATS_CPU_CODE_PTP_OFFSET = 112, /* PPE cpu code ptp offset */ + NSS_PPE_STATS_CPU_CODE_PTP_SYNC = 113, /* PPE cpu code ptp sync */ + NSS_PPE_STATS_CPU_CODE_PTP_FOLLOW_UP = 114, /* PPE cpu code ptp follow up */ + NSS_PPE_STATS_CPU_CODE_PTP_DELAY_REQ = 115, /* PPE cpu code ptp delay req */ + NSS_PPE_STATS_CPU_CODE_PTP_DELAY_RESP = 116, /* PPE cpu code ptp delay resp */ + NSS_PPE_STATS_CPU_CODE_PTP_PDELAY_REQ = 117, /* PPE cpu code ptp pdelay req */ + NSS_PPE_STATS_CPU_CODE_PTP_PDELAY_RESP = 118, /* PPE cpu code ptp pdelay resp */ + NSS_PPE_STATS_CPU_CODE_PTP_PDELAY_RESP_FOLLOW_UP = 119, /* PPE cpu code ptp pdelay resp follow up */ + NSS_PPE_STATS_CPU_CODE_PTP_ANNOUNCE = 120, /* PPE cpu code ptp announce */ + NSS_PPE_STATS_CPU_CODE_PTP_MANAGEMENT = 121, /* PPE cpu code ptp management */ + NSS_PPE_STATS_CPU_CODE_PTP_SIGNALING = 122, /* PPE cpu code ptp signaling */ + NSS_PPE_STATS_CPU_CODE_PTP_PKT_RSV_MSG = 127, /* PPE cpu code ptp pkt rsv msg */ + NSS_PPE_STATS_CPU_CODE_IPV4_SG_UNKNOWN = 136, /* PPE cpu code ipv4 sg unknown */ + NSS_PPE_STATS_CPU_CODE_IPV6_SG_UNKNOWN = 137, /* PPE cpu code ipv6 sg unknown */ + NSS_PPE_STATS_CPU_CODE_ARP_SG_UNKNOWN = 138, /* PPE cpu code arp sg unknown */ + NSS_PPE_STATS_CPU_CODE_ND_SG_UNKNOWN = 139, /* PPE cpu code nd sg unknown */ + NSS_PPE_STATS_CPU_CODE_IPV4_SG_VIO = 140, /* PPE cpu code ipv4 sg vio */ + NSS_PPE_STATS_CPU_CODE_IPV6_SG_VIO = 141, /* PPE cpu code ipv6 sg vio */ + NSS_PPE_STATS_CPU_CODE_ARP_SG_VIO = 142, /* PPE cpu code arp sg vio */ + NSS_PPE_STATS_CPU_CODE_ND_SG_VIO = 143, /* PPE cpu code nd sg vio */ + NSS_PPE_STATS_CPU_CODE_L3_ROUTING_IP_TO_ME = 148, /* PPE cpu code l3 routing ip to me */ + NSS_PPE_STATS_CPU_CODE_L3_FLOW_SNAT_ACTION = 149, /* PPE cpu code l3 flow snat action */ + NSS_PPE_STATS_CPU_CODE_L3_FLOW_DNAT_ACTION = 150, /* PPE cpu code l3 flow dnat action */ + NSS_PPE_STATS_CPU_CODE_L3_FLOW_RT_ACTION = 151, /* PPE cpu code l3 flow rt action */ + NSS_PPE_STATS_CPU_CODE_L3_FLOW_BR_ACTION = 152, /* PPE cpu code l3 flow br action */ + NSS_PPE_STATS_CPU_CODE_L3_MC_BRIDGE_ACTION = 153, /* PPE cpu code l3 mc bridge action */ + NSS_PPE_STATS_CPU_CODE_L3_ROUTE_PREHEAD_RT_ACTION = 154, /* PPE cpu code l3 route prehead rt action */ + NSS_PPE_STATS_CPU_CODE_L3_ROUTE_PREHEAD_SNAPT_ACTION = 155, /* PPE cpu code l3 route prehead snapt action */ + NSS_PPE_STATS_CPU_CODE_L3_ROUTE_PREHEAD_DNAPT_ACTION = 156, /* PPE cpu code l3 route prehead dnapt action */ + NSS_PPE_STATS_CPU_CODE_L3_ROUTE_PREHEAD_SNAT_ACTION = 157, /* PPE cpu code l3 route prehead snat action */ + NSS_PPE_STATS_CPU_CODE_L3_ROUTE_PREHEAD_DNAT_ACTION = 158, /* PPE cpu code l3 route prehead dnat action */ + NSS_PPE_STATS_CPU_CODE_L3_NO_ROUTE_PREHEAD_NAT_ACTION = 159, /* PPE cpu code l3 no route prehead nat action */ + NSS_PPE_STATS_CPU_CODE_L3_NO_ROUTE_PREHEAD_NAT_ERROR = 160, /* PPE cpu code l3 no route prehead nat error */ + NSS_PPE_STATS_CPU_CODE_L3_ROUTE_ACTION = 161, /* PPE cpu code l3 route action */ + NSS_PPE_STATS_CPU_CODE_L3_NO_ROUTE_ACTION = 162, /* PPE cpu code l3 no route action */ + NSS_PPE_STATS_CPU_CODE_L3_NO_ROUTE_NH_INVALID_ACTION = 163, /* PPE cpu code l3 no route nh invalid action */ + NSS_PPE_STATS_CPU_CODE_L3_NO_ROUTE_PREHEAD_ACTION = 164, /* PPE cpu code l3 no route prehead action */ + NSS_PPE_STATS_CPU_CODE_L3_BRIDGE_ACTION = 165, /* PPE cpu code l3 bridge action */ + NSS_PPE_STATS_CPU_CODE_L3_FLOW_ACTION = 166, /* PPE cpu code l3 flow action */ + NSS_PPE_STATS_CPU_CODE_L3_FLOW_MISS_ACTION = 167, /* PPE cpu code l3 flow miss action */ + NSS_PPE_STATS_CPU_CODE_L2_NEW_MAC_ADDRESS = 168, /* PPE cpu code l2 new mac address */ + NSS_PPE_STATS_CPU_CODE_L2_HASH_COLLISION = 169, /* PPE cpu code l2 hash collision */ + NSS_PPE_STATS_CPU_CODE_L2_STATION_MOVE = 170, /* PPE cpu code l2 station move */ + NSS_PPE_STATS_CPU_CODE_L2_LEARN_LIMIT = 171, /* PPE cpu code l2 learn limit */ + NSS_PPE_STATS_CPU_CODE_L2_SA_LOOKUP_ACTION = 172, /* PPE cpu code l2 sa lookup action */ + NSS_PPE_STATS_CPU_CODE_L2_DA_LOOKUP_ACTION = 173, /* PPE cpu code l2 da lookup action */ + NSS_PPE_STATS_CPU_CODE_APP_CTRL_ACTION = 174, /* PPE cpu code app ctrl action */ + NSS_PPE_STATS_CPU_CODE_IN_VLAN_FILTER_ACTION = 175, /* PPE cpu code in vlan filter action */ + NSS_PPE_STATS_CPU_CODE_IN_VLAN_XLT_MISS = 176, /* PPE cpu code in vlan xlt miss */ + NSS_PPE_STATS_CPU_CODE_EG_VLAN_FILTER_DROP = 177, /* PPE cpu code eg vlan filter drop */ + NSS_PPE_STATS_CPU_CODE_ACL_PRE_ACTION = 178, /* PPE cpu code acl pre action */ + NSS_PPE_STATS_CPU_CODE_ACL_POST_ACTION = 179, /* PPE cpu code acl post action */ + NSS_PPE_STATS_CPU_CODE_SERVICE_CODE_ACTION = 180, /* PPE cpu code service code action */ +}; + +/* + * nss_ppe_sc_stats_debug + */ +struct nss_ppe_sc_stats_debug { + uint64_t nss_ppe_sc_cb_unregister; /* Per service-code counter for callback not registered */ + uint64_t nss_ppe_sc_cb_success; /* Per service-code coutner for successful callback */ + uint64_t nss_ppe_sc_cb_failure; /* Per service-code counter for failure callback */ +}; + +/* + * NSS PPE statistics + */ +struct nss_ppe_stats_debug { + uint32_t conn_stats[NSS_PPE_STATS_CONN_MAX]; + uint32_t l3_stats[NSS_PPE_STATS_L3_MAX]; + uint32_t code_stats[NSS_PPE_STATS_CODE_MAX]; + struct nss_ppe_sc_stats_debug sc_stats[NSS_PPE_SC_MAX]; + int32_t if_index; + uint32_t if_num; /* nss interface number */ + bool valid; +}; + +/* + * Data structures to store NSS PPE debug statistics + */ +extern struct nss_ppe_stats_debug nss_ppe_debug_stats; + +/* + * NSS PPE statistics APIs + */ +extern void nss_ppe_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_ppe_sync_stats_msg *stats_msg, uint16_t if_num); +extern void nss_ppe_stats_dentry_create(void); + +#endif /* __NSS_PPE_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ppe_vp.c b/feeds/ipq807x/qca-nss-drv/src/nss_ppe_vp.c new file mode 100644 index 000000000..d3e8ce9e5 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ppe_vp.c @@ -0,0 +1,414 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_ppe_vp.h" +#include "nss_ppe_vp_stats.h" + +#define NSS_PPE_VP_TX_TIMEOUT 1000 /* 1 Second */ + +/* + * Private data structure + */ +static struct nss_ppe_vp_pvt { + struct semaphore sem; + struct completion complete; + int response; + void *cb; + void *app_data; +} ppe_vp_pvt; + +int nss_ppe_vp_enable __read_mostly = 0; +int nss_ppe_vp_disable __read_mostly = 0; + +DEFINE_SPINLOCK(nss_ppe_vp_stats_lock); + +struct nss_ppe_vp_stats_debug nss_ppe_vp_debug_stats; +static struct dentry *nss_ppe_vp_dentry; + +/* + * nss_ppe_vp_verify_ifnum() + * Verify PPE VP interface number. + */ +static inline bool nss_ppe_vp_verify_ifnum(int if_num) +{ + return (if_num == NSS_PPE_VP_INTERFACE); +} + +/* + * nss_ppe_vp_get_context() + * Get NSS context instance for ppe_vp + */ +struct nss_ctx_instance *nss_ppe_vp_get_context(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.ppe_handler_id]; +} + +/* + * nss_ppe_vp_callback() + * Callback to handle the completion of NSS->HLOS messages. + */ +static void nss_ppe_vp_callback(void *app_data, struct nss_ppe_vp_msg *npvm) +{ + if (npvm->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("ppe_vp error response %d\n", npvm->cm.response); + ppe_vp_pvt.response = npvm->cm.response; + } + + ppe_vp_pvt.response = NSS_TX_SUCCESS; + complete(&ppe_vp_pvt.complete); +} + +/* + * nss_ppe_vp_tx_msg() + * Transmit a ppe_vp message to NSS FW + */ +nss_tx_status_t nss_ppe_vp_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_ppe_vp_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Trace messages. + */ + nss_ppe_vp_log_tx_msg(msg); + + /* + * Sanity check the message + */ + if (ncm->type >= NSS_PPE_VP_MSG_MAX) { + nss_warning("%px: message type out of range: %d\n", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + if (!nss_ppe_vp_verify_ifnum(ncm->interface)) { + nss_warning("%px: invalid interface %d\n", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} + +/* + * nss_ppe_vp_tx_msg_sync() + * Transmit a ppe_vp message to NSS firmware synchronously. + */ +nss_tx_status_t nss_ppe_vp_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_ppe_vp_msg *npvm) +{ + nss_tx_status_t status; + int ret = 0; + + down(&ppe_vp_pvt.sem); + npvm->cm.cb = (nss_ptr_t)nss_ppe_vp_callback; + npvm->cm.app_data = (nss_ptr_t)NULL; + + status = nss_ppe_vp_tx_msg(nss_ctx, npvm); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: ppe_tx_msg failed\n", nss_ctx); + up(&ppe_vp_pvt.sem); + return status; + } + + ret = wait_for_completion_timeout(&ppe_vp_pvt.complete, msecs_to_jiffies(NSS_PPE_VP_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: ppe_vp msg tx failed due to timeout\n", nss_ctx); + ppe_vp_pvt.response = NSS_TX_FAILURE; + } + + status = ppe_vp_pvt.response; + up(&ppe_vp_pvt.sem); + return status; +} + +/* + * nss_ppe_vp_tx_config_msg + * API to send ppe_vp support configure message to NSS FW + */ +nss_tx_status_t nss_ppe_vp_tx_config_msg(enum nss_dynamic_interface_type type, bool enable) +{ + struct nss_ctx_instance *nss_ctx = nss_ppe_vp_get_context(); + struct nss_ppe_vp_config_msg *npvcm; + struct nss_ppe_vp_msg *npvm; + nss_tx_status_t status; + + if (type >= NSS_DYNAMIC_INTERFACE_TYPE_MAX) { + nss_warning("%px: Dynamic if msg drooped as type is wrong:%d\n", nss_ctx, type); + return -1; + } + + npvm = kzalloc(sizeof(struct nss_ppe_vp_msg), GFP_KERNEL); + if (!npvm) { + nss_warning("%px: Unable to allocate message\n", nss_ctx); + return -1; + } + + nss_cmn_msg_init(&npvm->cm, NSS_PPE_VP_INTERFACE, NSS_PPE_VP_MSG_CONFIG, + sizeof(struct nss_ppe_vp_config_msg), NULL, NULL); + + npvcm = &npvm->msg.vp_config; + npvcm->type = type; + npvcm->vp_enable = enable; + + status = nss_ppe_vp_tx_msg_sync(nss_ctx, npvm); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: Unable to send ppe_vp config message for type:%d\n", nss_ctx, type); + } + + kfree(npvm); + return status; +} + +/* + * nss_ppe_vp_handler() + * Handle NSS -> HLOS messages for ppe + */ +static void nss_ppe_vp_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_ppe_vp_msg *msg = (struct nss_ppe_vp_msg *)ncm; + nss_ppe_vp_msg_callback_t cb; + void *ctx; + + nss_trace("nss_ctx: %px ppe_vp msg: %px\n", nss_ctx, msg); + BUG_ON(!nss_ppe_vp_verify_ifnum(ncm->interface)); + + /* + * Trace messages. + */ + nss_ppe_vp_log_rx_msg(msg); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_PPE_VP_MSG_MAX) { + nss_warning("%px: received invalid message %d for PPE_VP interface\n", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_ppe_vp_msg)) { + nss_warning("%px: Length of message is greater than required: %d\n", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + switch (msg->cm.type) { + case NSS_PPE_VP_MSG_SYNC_STATS: + /* + * Per VP stats msg + */ + nss_ppe_vp_stats_sync(nss_ctx, &msg->msg.stats, ncm->interface); + return; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Do we have a call back + */ + if (!ncm->cb) { + return; + } + + /* + * Callback + */ + cb = (nss_ppe_vp_msg_callback_t)ncm->cb; + ctx = (void *)ncm->app_data; + + cb(ctx, msg); +} + +/* + * nss_ppe_vp_proc_help + * Print usage information for ppe_vp configure sysctl. + */ +void nss_ppe_vp_proc_help(void) +{ + printk("== for dynamic interface types read following file ==\n"); + printk("/sys/kernel/debug/qca-nss-drv/stats/dynamic_if/type_names\n"); +} + +/* + * nss_ppe_vp_enable_handler + * Enable VP support for specfic dynamic interface type. + */ +static int nss_ppe_vp_enable_handler(struct ctl_table *table, int write, void __user *buffer, + size_t *lenp, loff_t *ppos) +{ + nss_tx_status_t status; + enum nss_dynamic_interface_type type; + + int ret = proc_dointvec(table, write, buffer, lenp, ppos); + if (ret) + return ret; + + nss_info("%s:%d start\n", __func__, __LINE__); + + if (!write) { + nss_info("print dynamic interface type table\n"); + nss_ppe_vp_proc_help(); + return ret; + } + + type = nss_ppe_vp_enable; + if ((type <= NSS_DYNAMIC_INTERFACE_TYPE_NONE) || (type >= NSS_DYNAMIC_INTERFACE_TYPE_MAX)) { + nss_warning("incorrect type: %u", nss_ppe_vp_enable); + nss_ppe_vp_proc_help(); + return -EINVAL; + } + + status = nss_ppe_vp_tx_config_msg(type, true); + if (status != NSS_TX_SUCCESS) { + nss_warning("failed to enable VP support for type: %u", type); + return -EINVAL; + } + + return 0; +} + +/* + * nss_ppe_vp_disable_handler + * Disable VP support for a given dynamic interface type. + */ +static int nss_ppe_vp_disable_handler(struct ctl_table *table, int write, void __user *buffer, + size_t *lenp, loff_t *ppos) +{ + nss_tx_status_t status; + enum nss_dynamic_interface_type type; + + int ret = proc_dointvec(table, write, buffer, lenp, ppos); + if (ret) + return ret; + + if (!write) { + nss_ppe_vp_proc_help(); + return ret; + } + + type = nss_ppe_vp_disable; + if ((type <= NSS_DYNAMIC_INTERFACE_TYPE_NONE) || (type >= NSS_DYNAMIC_INTERFACE_TYPE_MAX)) { + nss_warning("incorrect type: %u", nss_ppe_vp_enable); + nss_ppe_vp_proc_help(); + return -EINVAL; + } + + status = nss_ppe_vp_tx_config_msg(type, false); + if (status != NSS_TX_SUCCESS) { + nss_warning("failed to disable VP support for type: %u", type); + return -EINVAL; + } + + return 0; +} + +static struct ctl_table nss_ppe_vp_table[] = { + { + .procname = "enable", + .data = &nss_ppe_vp_enable, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_ppe_vp_enable_handler, + }, + { + .procname = "disable", + .data = &nss_ppe_vp_disable, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_ppe_vp_disable_handler, + }, + { } +}; + +static struct ctl_table nss_ppe_vp_dir[] = { + { + .procname = "ppe_vp", + .mode = 0555, + .child = nss_ppe_vp_table, + }, + { } +}; + +static struct ctl_table nss_ppe_vp_root_dir[] = { + { + .procname = "nss", + .mode = 0555, + .child = nss_ppe_vp_dir, + }, + { } +}; + +static struct ctl_table_header *nss_ppe_vp_procfs_header; + +/* + * nss_ppe_vp_procfs_register() + * Register sysctl specific to ppe_vp + */ +void nss_ppe_vp_procfs_register(void) +{ + /* + * Register sysctl table. + */ + nss_ppe_vp_procfs_header = register_sysctl_table(nss_ppe_vp_root_dir); +} + +/* + * uss_ppe_vp_procfs_unregister() + * Unregister sysctl specific for ppe_vp + */ +void nss_ppe_vp_procfs_unregister(void) +{ + /* + * Unregister sysctl table. + */ + if (nss_ppe_vp_procfs_header) { + unregister_sysctl_table(nss_ppe_vp_procfs_header); + } +} + +/* + * nss_ppe_vp_register_handler() + * + */ +void nss_ppe_vp_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx = nss_ppe_vp_get_context(); + + nss_ppe_vp_dentry = nss_ppe_vp_stats_dentry_create(); + if (nss_ppe_vp_dentry == NULL) { + nss_warning("%px: Not able to create debugfs entry\n", nss_ctx); + return; + } + + nss_core_register_handler(nss_ctx, NSS_PPE_VP_INTERFACE, nss_ppe_vp_handler, NULL); + nss_ppe_vp_procfs_register(); + + sema_init(&ppe_vp_pvt.sem, 1); + init_completion(&ppe_vp_pvt.complete); +} + +/* + * nss_ppe_vp_unregister_handler() + * + */ +void nss_ppe_vp_unregister_handler(void) +{ + struct nss_ctx_instance *nss_ctx = nss_ppe_vp_get_context(); + + debugfs_remove_recursive(nss_ppe_vp_dentry); + nss_ppe_vp_procfs_unregister(); + nss_core_unregister_handler(nss_ctx, NSS_PPE_VP_INTERFACE); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ppe_vp.h b/feeds/ipq807x/qca-nss-drv/src/nss_ppe_vp.h new file mode 100644 index 000000000..3508ea530 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ppe_vp.h @@ -0,0 +1,117 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_ppe_vp.h + * NSS PPE virtual port header file + */ + +#include +#include "nss_tx_rx_common.h" + +/* + * Maximum number of virtual port supported by PPE hardware + */ +#define NSS_PPE_VP_MAX_NUM 192 +#define NSS_PPE_VP_START 64 +#define NSS_PPE_VP_NODE_STATS_MAX 32 + + +/* + * ppe_vp nss debug stats lock + */ +extern spinlock_t nss_ppe_vp_stats_lock; + +/* + * nss_ppe_vp_msg_error_type + * ppe_vp message errors + */ +enum nss_ppe_vp_msg_error_type { + NSS_PPE_VP_MSG_ERROR_TYPE_UNKNOWN, /* Unknown message error */ + NSS_PPE_VP_MSG_ERROR_TYPE_INVALID_DI, /* Invalid dynamic interface type error */ + NSS_PPE_VP_MSG_ERROR_TYPE_MAX /* Maximum error type */ +}; + +/* + * nss_ppe_vp_message_types + * Message types for Packet Processing Engine (PPE) requests and responses. + */ +enum nss_ppe_vp_message_types { + NSS_PPE_VP_MSG_CONFIG, + NSS_PPE_VP_MSG_SYNC_STATS, + NSS_PPE_VP_MSG_MAX, +}; + +/* + * nss_ppe_vp_config_msg + * Message to enable/disable VP support for a specific dynamic interface type. + */ +struct nss_ppe_vp_config_msg { + enum nss_dynamic_interface_type type; /* Interface type */ + bool vp_enable; /* VP support enable */ +}; + +/* + * nss_ppe_vp_statistics + * Message structure for ppe_vp statistics + */ +struct nss_ppe_vp_statistics { + uint32_t nss_if; /* NSS interface number corresponding to VP */ + uint32_t vp_num; /* VP number */ + uint32_t rx_drop; /* Rx drops due to VP node inactive */ + uint32_t tx_drop; /* Tx drops due to VP node inactive */ + uint32_t packet_big_err; /* Number of packets not sent to PPE because packet was too large */ + struct nss_cmn_node_stats stats; /* Common node statistics */ +}; + +/* + * nss_ppe_vp_sync_stats_msg + * Message information for ppe_vp synchronization statistics. + */ +struct nss_ppe_vp_sync_stats_msg { + uint16_t count; /* Number of VP node stats with the sync message */ + uint32_t rx_dropped[NSS_MAX_NUM_PRI]; /* Rx packet dropped due to queue full */ + struct nss_ppe_vp_statistics vp_stats[NSS_PPE_VP_NODE_STATS_MAX]; + /* Per service-code stats */ +}; + +/* + * nss_ppe_vp_msg + * Message for receiving ppe_vp NSS to host messages. + */ +struct nss_ppe_vp_msg { + struct nss_cmn_msg cm; /**< Common message header. */ + + /* + * Payload. + */ + union { + struct nss_ppe_vp_config_msg vp_config; + /**< Enable/disable VP support for specific type */ + struct nss_ppe_vp_sync_stats_msg stats; + /**< Synchronization statistics. */ + } msg; /**< Message payload. */ +}; + +typedef void (*nss_ppe_vp_msg_callback_t)(void *app_data, struct nss_ppe_vp_msg *msg); + +/* + * Logging APIs. + */ +void nss_ppe_vp_log_tx_msg(struct nss_ppe_vp_msg *npvm); +void nss_ppe_vp_log_rx_msg(struct nss_ppe_vp_msg *npvm); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ppe_vp_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_ppe_vp_log.c new file mode 100644 index 000000000..02e352d1e --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ppe_vp_log.c @@ -0,0 +1,128 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_ppe_vp_log.c + * NSS PPE logger file. + */ + +#include "nss_core.h" +#include "nss_ppe_vp.h" + +/* + * nss_ppe_vp_log_message_types_str + * PPE message strings + */ +static int8_t *nss_ppe_vp_log_message_types_str[NSS_PPE_VP_MSG_MAX] __maybe_unused = { + "PPE VP Config", + "PPE VP Stats", +}; + +/* + * nss_ppe_vp_log_error_response_types_str + * Strings for error types for PPE-VP messages + */ +static int8_t *nss_ppe_vp_log_error_response_types_str[NSS_PPE_VP_MSG_ERROR_TYPE_MAX] __maybe_unused = { + "PPE VP Unknown message type", + "PPE VP Invalid dynamic interface type", +}; + +/* + * nss_ppe_vp_log_config_msg() + * Log NSS PPE VP configuration message. + */ +static void nss_ppe_vp_log_config_msg(struct nss_ppe_vp_msg *npvm) +{ + struct nss_ppe_vp_config_msg *npcm __maybe_unused = &npvm->msg.vp_config; + nss_trace("%px: NSS PPE VP configuration message:\n" + "Dynamic interface type: %d is_vp_support_enable: %d\n", + npcm, npcm->type, npcm->vp_enable); +} + +/* + * nss_ppe_vp_log_verbose() + * Log message contents. + */ +static void nss_ppe_vp_log_verbose(struct nss_ppe_vp_msg *npvm) +{ + switch (npvm->cm.type) { + case NSS_PPE_VP_MSG_CONFIG: + nss_ppe_vp_log_config_msg(npvm); + break; + + case NSS_PPE_VP_MSG_SYNC_STATS: + /* + * No log for valid stats message. + */ + break; + + default: + nss_warning("%px: Invalid message type\n", npvm); + break; + } +} + +/* + * nss_ppe_vp_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_ppe_vp_log_tx_msg(struct nss_ppe_vp_msg *npvm) +{ + if (npvm->cm.type >= NSS_PPE_VP_MSG_MAX) { + nss_warning("%px: Invalid message type\n", npvm); + return; + } + + nss_info("%px: type[%d]:%s\n", npvm, npvm->cm.type, nss_ppe_vp_log_message_types_str[npvm->cm.type]); + nss_ppe_vp_log_verbose(npvm); +} + +/* + * nss_ppe_vp_log_rx_msg() + * Log messages received from FW. + */ +void nss_ppe_vp_log_rx_msg(struct nss_ppe_vp_msg *npvm) +{ + if (npvm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", npvm); + return; + } + + if (npvm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (npvm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", npvm, npvm->cm.type, + nss_ppe_vp_log_message_types_str[npvm->cm.type], + npvm->cm.response, nss_cmn_response_str[npvm->cm.response]); + goto verbose; + } + + if (npvm->cm.error >= NSS_PPE_VP_MSG_ERROR_TYPE_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + npvm, npvm->cm.type, nss_ppe_vp_log_message_types_str[npvm->cm.type], + npvm->cm.response, nss_cmn_response_str[npvm->cm.response], + npvm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + npvm, npvm->cm.type, nss_ppe_vp_log_message_types_str[npvm->cm.type], + npvm->cm.response, nss_cmn_response_str[npvm->cm.response], + npvm->cm.error, nss_ppe_vp_log_error_response_types_str[npvm->cm.error]); + +verbose: + nss_ppe_vp_log_verbose(npvm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ppe_vp_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_ppe_vp_stats.c new file mode 100644 index 000000000..a51973690 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ppe_vp_stats.c @@ -0,0 +1,236 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_ppe_vp.h" +#include "nss_ppe_vp_stats.h" + +/* + * nss_ppe_vp_stats_cntrs + * PPE VP stats counters displayed using debugfs + */ +enum nss_ppe_vp_stats_cntrs { + NSS_PPE_VP_STATS_VP_NUM, + NSS_PPE_VP_STATS_NSS_IF, + NSS_PPE_VP_STATS_RX_PKTS, + NSS_PPE_VP_STATS_RX_BYTES, + NSS_PPE_VP_STATS_TX_PKTS, + NSS_PPE_VP_STATS_TX_BYTES, + NSS_PPE_VP_STATS_RX_INACTIVE, + NSS_PPE_VP_STATS_TX_INACTIVE, + NSS_PPE_VP_STATS_PACKET_BIG, + NSS_PPE_VP_STATS_TX_Q_0_DROP, + NSS_PPE_VP_STATS_TX_Q_1_DROP, + NSS_PPE_VP_STATS_TX_Q_2_DROP, + NSS_PPE_VP_STATS_TX_Q_3_DROP, + NSS_PPE_VP_STATS_MAX +}; + +/* + * nss_ppe_vp_stats_rx_cntrs + * PPE VP RX stats counters displayed using debugfs + */ +enum nss_ppe_vp_stats_rx_cntrs { + NSS_PPE_VP_STATS_RX_Q_0_DROP, + NSS_PPE_VP_STATS_RX_Q_1_DROP, + NSS_PPE_VP_STATS_RX_Q_2_DROP, + NSS_PPE_VP_STATS_RX_Q_3_DROP, + NSS_PPE_VP_STATS_RX_MAX +}; + +/* + * nss_ppe_vp_rx_stats_str + * PPE VP Rx statistics strings + */ +struct nss_stats_info nss_ppe_vp_stats_rx_str[NSS_PPE_VP_STATS_RX_MAX] = { + {"rx_queue_0_drop" , NSS_STATS_TYPE_DROP}, + {"rx_queue_1_drop" , NSS_STATS_TYPE_DROP}, + {"rx_queue_2_drop" , NSS_STATS_TYPE_DROP}, + {"rx_queue_3_drop" , NSS_STATS_TYPE_DROP}, +}; + +/* + * nss_ppe_vp_stats_str + * PPE VP statistics strings + */ +struct nss_stats_info nss_ppe_vp_stats_str[NSS_PPE_VP_STATS_MAX] = { + {"vp_num" , NSS_STATS_TYPE_SPECIAL}, + {"nss_if" , NSS_STATS_TYPE_SPECIAL}, + {"rx_packets" , NSS_STATS_TYPE_COMMON}, + {"rx_bytes" , NSS_STATS_TYPE_COMMON}, + {"tx_packets" , NSS_STATS_TYPE_COMMON}, + {"tx_bytes" , NSS_STATS_TYPE_COMMON}, + {"rx_inactive" , NSS_STATS_TYPE_DROP}, + {"tx_inactive" , NSS_STATS_TYPE_DROP}, + {"packet_large_err" , NSS_STATS_TYPE_EXCEPTION}, + {"tx_queue_0_drop" , NSS_STATS_TYPE_DROP}, + {"tx_queue_1_drop" , NSS_STATS_TYPE_DROP}, + {"tx_queue_2_drop" , NSS_STATS_TYPE_DROP}, + {"tx_queue_3_drop" , NSS_STATS_TYPE_DROP}, +}; + +/* + * nss_ppe_vp_stats_sync + * PPE VP sync statistics from NSS + */ +void nss_ppe_vp_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_ppe_vp_sync_stats_msg *stats_msg, uint16_t if_num) +{ + uint16_t count = stats_msg->count; + uint16_t vp_index, i; + + spin_lock_bh(&nss_ppe_vp_stats_lock); + + /* + * Update general rx dropped stats. + */ + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + nss_ppe_vp_debug_stats.rx_dropped[i] += stats_msg->rx_dropped[i]; + } + + /* + * Update per VP tx and rx stats. + */ + while (count) { + count--; + + /* + * If nss interface is changed from previous entry, reset the stats. + */ + vp_index = stats_msg->vp_stats[count].vp_num - NSS_PPE_VP_START; + if (nss_ppe_vp_debug_stats.vp_stats[vp_index].nss_if != stats_msg->vp_stats[count].nss_if) { + memset(&nss_ppe_vp_debug_stats.vp_stats[vp_index], 0, sizeof(struct nss_ppe_vp_statistics_debug)); + } + + /* + * Update stats in global array + */ + nss_ppe_vp_debug_stats.vp_stats[vp_index].vp_num = stats_msg->vp_stats[count].vp_num; + nss_ppe_vp_debug_stats.vp_stats[vp_index].nss_if = stats_msg->vp_stats[count].nss_if; + nss_ppe_vp_debug_stats.vp_stats[vp_index].rx_packets += stats_msg->vp_stats[count].stats.rx_packets; + nss_ppe_vp_debug_stats.vp_stats[vp_index].rx_bytes += stats_msg->vp_stats[count].stats.rx_bytes; + nss_ppe_vp_debug_stats.vp_stats[vp_index].tx_packets += stats_msg->vp_stats[count].stats.tx_packets; + nss_ppe_vp_debug_stats.vp_stats[vp_index].tx_bytes += stats_msg->vp_stats[count].stats.tx_bytes; + nss_ppe_vp_debug_stats.vp_stats[vp_index].rx_inactive_drop += stats_msg->vp_stats[count].rx_drop; + nss_ppe_vp_debug_stats.vp_stats[vp_index].tx_inactive_drop += stats_msg->vp_stats[count].tx_drop; + nss_ppe_vp_debug_stats.vp_stats[vp_index].packet_big_err += stats_msg->vp_stats[count].packet_big_err; + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + nss_ppe_vp_debug_stats.vp_stats[vp_index].tx_dropped[i] += stats_msg->vp_stats[count].stats.rx_dropped[i]; + } + + nss_trace("sync count:%d vp_num %d rx_packets %d tx_packets %d\n", + count, stats_msg->vp_stats[count].vp_num, + stats_msg->vp_stats[count].stats.rx_packets, + stats_msg->vp_stats[count].stats.tx_packets); + } + spin_unlock_bh(&nss_ppe_vp_stats_lock); +} + +/* + * nss_ppe_vp_stats_read() + * Read ppe vp statistics + */ +static ssize_t nss_ppe_vp_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int i; + char *lbuf = NULL; + size_t size_wr = 0; + ssize_t bytes_read = 0; + struct nss_ppe_vp_stats_debug *ppe_vp_stats; + uint32_t max_output_lines = ((NSS_PPE_VP_STATS_RX_MAX + NSS_PPE_VP_STATS_MAX) * NSS_PPE_VP_MAX_NUM) + NSS_STATS_EXTRA_OUTPUT_LINES; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t stats_sz = sizeof(struct nss_ppe_vp_stats_debug); + + ppe_vp_stats = kzalloc(stats_sz, GFP_KERNEL); + if (!ppe_vp_stats) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + + lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(!lbuf)) { + kfree(ppe_vp_stats); + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + /* + * Get vp stats + */ + spin_lock_bh(&nss_ppe_vp_stats_lock); + memcpy(ppe_vp_stats, &nss_ppe_vp_debug_stats, stats_sz); + spin_unlock_bh(&nss_ppe_vp_stats_lock); + + /* + * VP stats + */ + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "ppe_vp", NSS_STATS_SINGLE_CORE); + + /* + * Print Rx dropped. + */ + size_wr += nss_stats_print("ppe_vp", "ppe_vp rx dropped:" + , NSS_STATS_SINGLE_INSTANCE + , nss_ppe_vp_stats_rx_str + , ppe_vp_stats->rx_dropped + , NSS_PPE_VP_STATS_RX_MAX + , lbuf, size_wr, size_al); + + /* + * Print individual VP stats + */ + for (i = 0; i < NSS_PPE_VP_MAX_NUM; i++) { + if (!ppe_vp_stats->vp_stats[i].nss_if) { + continue; + } + + size_wr += nss_stats_print("ppe_vp", "ppe_vp stats" + , NSS_STATS_SINGLE_INSTANCE + , nss_ppe_vp_stats_str + , (uint64_t *) &ppe_vp_stats->vp_stats[i] + , NSS_PPE_VP_STATS_MAX + , lbuf, size_wr, size_al); + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr); + + kfree(ppe_vp_stats); + kfree(lbuf); + return bytes_read; +} + +/* + * nss_ppe_vp_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(ppe_vp) + +/* + * nss_ppe_vp_stats_dentry_create() + * Create PPE statistics debug entry. + */ +struct dentry *nss_ppe_vp_stats_dentry_create(void) +{ + struct dentry *ppe_vp_d = debugfs_create_file("ppe_vp", 0400, nss_top_main.stats_dentry, + &nss_top_main, &nss_ppe_vp_stats_ops); + if (unlikely(ppe_vp_d == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/ppe_vp file"); + return NULL; + } + + return ppe_vp_d; +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_ppe_vp_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_ppe_vp_stats.h new file mode 100644 index 000000000..56a828905 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_ppe_vp_stats.h @@ -0,0 +1,63 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_ppe_vp_stats.h + * NSS PPE-VP statistics header file. + */ + +#ifndef __NSS_PPE_VP_STATS_H +#define __NSS_PPE_VP_STATS_H + +/* + * NSS PPE-VP statistics + */ +struct nss_ppe_vp_statistics_debug { + uint64_t vp_num; /* VP number */ + uint64_t nss_if; /* NSS interface number corresponding to VP */ + uint64_t rx_packets; /* Number of packets received. */ + uint64_t rx_bytes; /* Number of bytes received. */ + uint64_t tx_packets; /* Number of packets transmitted. */ + uint64_t tx_bytes; /* Number of bytes transmitted. */ + uint64_t rx_inactive_drop; /* Number of packets dropped from PPE to VP due to VP inactive */ + uint64_t tx_inactive_drop; /* Number of packets dropped from VP to PPE due to VP inactive */ + uint64_t packet_big_err; /* Number of packets not sent to PPE because packet was too large */ + uint64_t tx_dropped[NSS_MAX_NUM_PRI]; /* Tx packets dropped on due to queue full. */ +}; + +/* + * NSS PPE-VP statistics + */ +struct nss_ppe_vp_stats_debug { + uint64_t rx_dropped[NSS_MAX_NUM_PRI]; /* Packets dropped on receive due to queue full. */ + struct nss_ppe_vp_statistics_debug vp_stats[NSS_PPE_VP_MAX_NUM]; + /* Per VP Tx and Rx stats. */ +}; + +/* + * Data structures to store NSS PPE_VP debug statistics + */ +extern struct nss_ppe_vp_stats_debug nss_ppe_vp_debug_stats; + +/* + * NSS PPE-VP statistics APIs + */ +extern void nss_ppe_vp_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_ppe_vp_sync_stats_msg *stats_msg, uint16_t if_num); +extern struct dentry *nss_ppe_vp_stats_dentry_create(void); + +#endif /* __NSS_PPE_VP_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_pppoe.c b/feeds/ipq807x/qca-nss-drv/src/nss_pppoe.c new file mode 100644 index 000000000..df613f76a --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_pppoe.c @@ -0,0 +1,435 @@ +/* + ************************************************************************** + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_pppoe.c + * NSS PPPoE APIs + */ + +#include "nss_tx_rx_common.h" +#include "nss_pppoe_stats.h" +#include "nss_pppoe_log.h" +#include "nss_pppoe_strings.h" + +#define NSS_PPPOE_TX_TIMEOUT 3000 /* 3 Seconds */ + +int nss_pppoe_br_accel_mode __read_mostly = NSS_PPPOE_BR_ACCEL_MODE_EN_5T; + +/* + * Private data structure + */ +static struct nss_pppoe_pvt { + struct semaphore sem; + struct completion complete; + int response; + void *cb; + void *app_data; +} pppoe_pvt; + +/* + * nss_pppoe_br_help() + * Usage information for pppoe bride accel mode + */ +static inline void nss_pppoe_br_help(int mode) +{ + printk("Incorrect pppoe bridge accel mode: %d\n", mode); + printk("Supported modes\n"); + printk("%d: pppoe bridge acceleration disable\n", NSS_PPPOE_BR_ACCEL_MODE_DIS); + printk("%d: pppoe bridge acceleration enable with 5-tuple\n", NSS_PPPOE_BR_ACCEL_MODE_EN_5T); + printk("%d: pppoe bridge acceleration enable with 3-tuple\n", NSS_PPPOE_BR_ACCEL_MODE_EN_3T); +} + +/* + * nss_pppoe_get_context() + */ +struct nss_ctx_instance *nss_pppoe_get_context(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.pppoe_handler_id]; +} +EXPORT_SYMBOL(nss_pppoe_get_context); + +/* + * nss_pppoe_tx_msg() + * Transmit a PPPoE message to NSS firmware + */ +static nss_tx_status_t nss_pppoe_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_pppoe_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + enum nss_dynamic_interface_type type; + + /* + * Trace Messages + */ + nss_pppoe_log_tx_msg(msg); + + /* + * Sanity check the message + */ + type = nss_dynamic_interface_get_type(nss_pppoe_get_context(), ncm->interface); + if ((ncm->interface != NSS_PPPOE_INTERFACE) && (type != NSS_DYNAMIC_INTERFACE_TYPE_PPPOE)) { + nss_warning("%px: tx request for not PPPoE interface: %d type: %d\n", + nss_ctx, ncm->interface, type); + return NSS_TX_FAILURE; + } + + if (ncm->type >= NSS_PPPOE_MSG_MAX) { + nss_warning("%px: message type out of range: %d\n", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} + +/* + * nss_pppoe_sync_msg_callback() + * Callback to handle the completion of NSS->HLOS messages. + */ +static void nss_pppoe_sync_msg_callback(void *app_data, struct nss_pppoe_msg *npm) +{ + nss_pppoe_msg_callback_t callback = (nss_pppoe_msg_callback_t)pppoe_pvt.cb; + void *data = pppoe_pvt.app_data; + + pppoe_pvt.cb = NULL; + pppoe_pvt.app_data = NULL; + + pppoe_pvt.response = NSS_TX_SUCCESS; + if (npm->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("pppoe Error response %d\n", npm->cm.response); + pppoe_pvt.response = NSS_TX_FAILURE; + } + + if (callback) { + callback(data, npm); + } + + complete(&pppoe_pvt.complete); +} + +/* + * nss_pppoe_handler() + * Handle NSS -> HLOS messages for PPPoE + */ +static void nss_pppoe_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_pppoe_msg *npm = (struct nss_pppoe_msg *)ncm; + void *ctx; + nss_pppoe_msg_callback_t cb; + + BUG_ON(!(nss_is_dynamic_interface(ncm->interface) || ncm->interface == NSS_PPPOE_INTERFACE)); + + /* + * Trace Messages + */ + nss_pppoe_log_rx_msg(npm); + + /* + * Sanity check the message type + */ + if (ncm->type >= NSS_PPPOE_MSG_MAX) { + nss_warning("%px: message type out of range: %d\n", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_pppoe_msg)) { + nss_warning("%px: message length is invalid: %d\n", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Handling PPPoE messages coming from NSS fw. + */ + switch (npm->cm.type) { + case NSS_PPPOE_MSG_SYNC_STATS: + /* + * Update PPPoE debug statistics and send statistics notifications to the registered modules + */ + nss_pppoe_stats_sync(nss_ctx, &npm->msg.sync_stats, ncm->interface); + nss_pppoe_stats_notify(nss_ctx, ncm->interface); + break; + default: + nss_warning("%px: Received response %d for type %d, interface %d\n", + nss_ctx, ncm->response, ncm->type, ncm->interface); + } + + /* + * Update the callback and app_data for NOTIFY messages, pppoe sends all notify messages + * to the same callback/app_data. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_ctx->nss_top->pppoe_msg_callback; + ncm->app_data = (nss_ptr_t)nss_ctx->subsys_dp_register[ncm->interface].app_data; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Do we have a call back + */ + if (!ncm->cb) { + return; + } + + /* + * callback + */ + cb = (nss_pppoe_msg_callback_t)ncm->cb; + ctx = (void *)ncm->app_data; + + cb(ctx, npm); +} + +/* + * nss_pppoe_br_accel_mode_handler() + * Enable/disable pppoe bridge acceleration in NSS + */ +int nss_pppoe_br_accel_mode_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + struct nss_ctx_instance *nss_ctx = nss_pppoe_get_context(); + struct nss_pppoe_msg npm; + struct nss_pppoe_br_accel_cfg_msg *npbacm; + nss_tx_status_t status; + int ret; + enum nss_pppoe_br_accel_modes current_value, new_val; + + /* + * Take snap shot of current value + */ + current_value = nss_pppoe_br_accel_mode; + + /* + * Write the variable with user input + */ + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + if (ret || (!write)) { + return ret; + } + + new_val = nss_pppoe_br_accel_mode; + if ((new_val < NSS_PPPOE_BR_ACCEL_MODE_DIS) || (new_val >= NSS_PPPOE_BR_ACCEL_MODE_MAX)) { + nss_warning("%px: value out of range: %d\n", nss_ctx, new_val); + nss_pppoe_br_accel_mode = current_value; + nss_pppoe_br_help(new_val); + return -EINVAL; + } + + memset(&npm, 0, sizeof(struct nss_pppoe_msg)); + nss_pppoe_msg_init(&npm, NSS_PPPOE_INTERFACE, NSS_PPPOE_MSG_BR_ACCEL_CFG, + sizeof(struct nss_pppoe_br_accel_cfg_msg), NULL, NULL); + + npbacm = &npm.msg.br_accel; + npbacm->br_accel_cfg = new_val; + + status = nss_pppoe_tx_msg_sync(nss_ctx, &npm); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: Send acceleration mode message failed\n", nss_ctx); + nss_pppoe_br_accel_mode = current_value; + return -EIO; + } + + return 0; +} + +/* + * nss_pppoe_get_br_accel_mode() + * Gets PPPoE bridge acceleration mode + */ +enum nss_pppoe_br_accel_modes nss_pppoe_get_br_accel_mode(void) +{ + return nss_pppoe_br_accel_mode; +} +EXPORT_SYMBOL(nss_pppoe_get_br_accel_mode); + +/* + * nss_pppoe_tx_msg_sync() + */ +nss_tx_status_t nss_pppoe_tx_msg_sync(struct nss_ctx_instance *nss_ctx, + struct nss_pppoe_msg *msg) +{ + nss_tx_status_t status; + int ret = 0; + + down(&pppoe_pvt.sem); + pppoe_pvt.cb = (void *)msg->cm.cb; + pppoe_pvt.app_data = (void *)msg->cm.app_data; + + msg->cm.cb = (nss_ptr_t)nss_pppoe_sync_msg_callback; + msg->cm.app_data = (nss_ptr_t)NULL; + + status = nss_pppoe_tx_msg(nss_ctx, msg); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: nss_pppoe_tx_msg failed\n", nss_ctx); + up(&pppoe_pvt.sem); + return status; + } + + ret = wait_for_completion_timeout(&pppoe_pvt.complete, msecs_to_jiffies(NSS_PPPOE_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: PPPoE msg tx failed due to timeout\n", nss_ctx); + pppoe_pvt.response = NSS_TX_FAILURE; + } + + status = pppoe_pvt.response; + up(&pppoe_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_pppoe_tx_msg_sync); + +/* + * nss_register_pppoe_session_if() + */ +struct nss_ctx_instance *nss_register_pppoe_session_if(uint32_t if_num, + nss_pppoe_msg_callback_t notification_callback, + struct net_device *netdev, uint32_t features, void *app_ctx) +{ + struct nss_ctx_instance *nss_ctx = nss_pppoe_get_context(); + + nss_assert(nss_ctx); + nss_assert(nss_is_dynamic_interface(if_num)); + + if (!nss_pppoe_stats_pppoe_session_init(if_num, netdev)) { + return NULL; + } + + nss_core_register_subsys_dp(nss_ctx, if_num, NULL, NULL, app_ctx, netdev, features); + + nss_top_main.pppoe_msg_callback = notification_callback; + + nss_core_register_handler(nss_ctx, if_num, nss_pppoe_handler, NULL); + + return nss_ctx; +} +EXPORT_SYMBOL(nss_register_pppoe_session_if); + +/* + * nss_unregister_pppoe_session_if() + */ +void nss_unregister_pppoe_session_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = nss_pppoe_get_context(); + + nss_assert(nss_ctx); + nss_assert(nss_is_dynamic_interface(if_num)); + + nss_pppoe_stats_pppoe_session_deinit(if_num); + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + + nss_top_main.pppoe_msg_callback = NULL; + + nss_core_unregister_handler(nss_ctx, if_num); + +} +EXPORT_SYMBOL(nss_unregister_pppoe_session_if); + +static struct ctl_table nss_pppoe_table[] = { + { + .procname = "br_accel_mode", + .data = &nss_pppoe_br_accel_mode, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_pppoe_br_accel_mode_handler, + }, + { } +}; + +static struct ctl_table nss_pppoe_dir[] = { + { + .procname = "pppoe", + .mode = 0555, + .child = nss_pppoe_table, + }, + { } +}; + +static struct ctl_table nss_pppoe_root_dir[] = { + { + .procname = "nss", + .mode = 0555, + .child = nss_pppoe_dir, + }, + { } +}; + +static struct ctl_table nss_pppoe_root[] = { + { + .procname = "dev", + .mode = 0555, + .child = nss_pppoe_root_dir, + }, + { } +}; + +static struct ctl_table_header *nss_pppoe_header; + +/* + * nss_pppoe_register_sysctl() + * Register sysctl specific to pppoe + */ +void nss_pppoe_register_sysctl(void) +{ + /* + * Register sysctl table. + */ + nss_pppoe_header = register_sysctl_table(nss_pppoe_root); +} + +/* + * nss_pppoe_unregister_sysctl() + * Unregister sysctl specific to pppoe + */ +void nss_pppoe_unregister_sysctl(void) +{ + /* + * Unregister sysctl table. + */ + if (nss_pppoe_header) { + unregister_sysctl_table(nss_pppoe_header); + } +} + +/* + * nss_pppoe_register_handler() + */ +void nss_pppoe_register_handler(void) +{ + nss_info("nss_pppoe_register_handler\n"); + nss_core_register_handler(nss_pppoe_get_context(), NSS_PPPOE_INTERFACE, nss_pppoe_handler, NULL); + + sema_init(&pppoe_pvt.sem, 1); + init_completion(&pppoe_pvt.complete); + + nss_pppoe_stats_dentry_create(); + nss_pppoe_strings_dentry_create(); +} + +/* + * nss_pppoe_msg_init() + */ +void nss_pppoe_msg_init(struct nss_pppoe_msg *npm, uint16_t if_num, uint32_t type, uint32_t len, + void *cb, void *app_data) +{ + nss_cmn_msg_init(&npm->cm, if_num, type, len, (void *)cb, app_data); + +} +EXPORT_SYMBOL(nss_pppoe_msg_init); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_pppoe_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_pppoe_log.c new file mode 100644 index 000000000..7ab8b1902 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_pppoe_log.c @@ -0,0 +1,133 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_pppoe_log.c + * NSS PPPOE logger file. + */ + +#include "nss_core.h" + +/* + * nss_pppoe_log_message_types_str + * NSS PPPOE message strings + */ +static int8_t *nss_pppoe_log_message_types_str[NSS_PPPOE_MSG_MAX] __maybe_unused = { + "PPPOE Session Create", + "PPPOE Session Destroy", + "PPPOE Stats", +}; + +/* + * nss_pppoe_log_session_create_msg() + * Log NSS Session Create. + */ +static void nss_pppoe_log_session_create_msg(struct nss_pppoe_msg *npm) +{ + struct nss_pppoe_create_msg *npcm __maybe_unused = &npm->msg.create; + nss_trace("%px: NSS PPPOE Session Create message \n" + "PPPOE Base Interface Number: %d\n" + "PPPOE MTU: %d\n" + "PPPOE Server MAC: %pM\n" + "PPPOE Local MAC: %pM\n" + "PPPOE Session ID: %d\n", + npcm, npcm->base_if_num, + npcm->mtu, npcm->server_mac, + npcm->local_mac, npcm->session_id); +} + +/* + * nss_pppoe_log_session_destroy_msg() + * Log NSS Session Destroy. + */ +static void nss_pppoe_log_session_destroy_msg(struct nss_pppoe_msg *npm) +{ + struct nss_pppoe_destroy_msg *npdm __maybe_unused = &npm->msg.destroy; + nss_trace("%px: NSS PPPOE Session Destroy message \n" + "PPPOE Session ID: %d\n" + "PPPOE Server MAC: %pM\n" + "PPPOE Local MAC: %pM\n", + npdm, npdm->session_id, + npdm->server_mac, npdm->local_mac); +} + +/* + * nss_pppoe_log_verbose() + * Log message contents. + */ +static void nss_pppoe_log_verbose(struct nss_pppoe_msg *npm) +{ + switch (npm->cm.type) { + case NSS_PPPOE_MSG_SESSION_CREATE: + nss_pppoe_log_session_create_msg(npm); + break; + + case NSS_PPPOE_MSG_SESSION_DESTROY: + nss_pppoe_log_session_destroy_msg(npm); + break; + + case NSS_PPPOE_MSG_SYNC_STATS: + /* + * No log for valid stats message. + */ + break; + + default: + nss_trace("%px: Invalid message type\n", npm); + break; + } +} + +/* + * nss_pppoe_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_pppoe_log_tx_msg(struct nss_pppoe_msg *npm) +{ + if (npm->cm.type >= NSS_PPPOE_MSG_MAX) { + nss_warning("%px: Invalid message type\n", npm); + return; + } + + nss_info("%px: type[%d]:%s\n", npm, npm->cm.type, nss_pppoe_log_message_types_str[npm->cm.type]); + nss_pppoe_log_verbose(npm); +} + +/* + * nss_pppoe_log_rx_msg() + * Log messages received from FW. + */ +void nss_pppoe_log_rx_msg(struct nss_pppoe_msg *npm) +{ + if (npm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", npm); + return; + } + + if (npm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (npm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", npm, npm->cm.type, + nss_pppoe_log_message_types_str[npm->cm.type], + npm->cm.response, nss_cmn_response_str[npm->cm.response]); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s\n", + npm, npm->cm.type, nss_pppoe_log_message_types_str[npm->cm.type], + npm->cm.response, nss_cmn_response_str[npm->cm.response]); + +verbose: + nss_pppoe_log_verbose(npm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_pppoe_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_pppoe_log.h new file mode 100644 index 000000000..4636b08d8 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_pppoe_log.h @@ -0,0 +1,41 @@ +/* + ************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_PPPOE_LOG_H +#define __NSS_PPPOE_LOG_H + +/* + * nss_pppoe.h + * NSS PPPOE header file. + */ + +/* + * Logger APIs + */ + +/* + * nss_pppoe_log_tx_msg + * Logs a pppoe message that is sent to the NSS firmware. + */ +void nss_pppoe_log_tx_msg(struct nss_pppoe_msg *nim); + +/* + * nss_pppoe_log_rx_msg + * Logs a pppoe message that is received from the NSS firmware. + */ +void nss_pppoe_log_rx_msg(struct nss_pppoe_msg *nim); + +#endif /* __NSS_PPPOE_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_pppoe_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_pppoe_stats.c new file mode 100644 index 000000000..75b24c8ed --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_pppoe_stats.c @@ -0,0 +1,265 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include +#include "nss_pppoe_stats.h" +#include "nss_pppoe_strings.h" + +/* + * Declare atomic notifier data structure for statistics. + */ +ATOMIC_NOTIFIER_HEAD(nss_pppoe_stats_notifier); + +/* + * Lock used for PPPoE statistics + */ +static DEFINE_SPINLOCK(nss_pppoe_stats_lock); + +/* + * PPPoE session stats structure for debug interface + */ +struct nss_pppoe_stats_session_stats { + uint64_t stats[NSS_PPPOE_STATS_SESSION_MAX]; + /* stats for the session */ + int32_t if_index; /* net device index for the session */ + uint32_t if_num; /* nss interface number */ + bool valid; /* dynamic interface valid flag */ +}; + +/* + * PPPoE interface stats structure for base node and sessions + */ +struct nss_pppoe_stats { + uint64_t base_stats[NSS_PPPOE_STATS_BASE_MAX]; + /* Base node stats */ + struct nss_pppoe_stats_session_stats session_stats[NSS_MAX_PPPOE_DYNAMIC_INTERFACES]; + /* Per session stats */ +}; + +/* + * Global PPPoE stats decleration. + */ +static struct nss_pppoe_stats pppoe_stats; + +/* + * nss_pppoe_stats_read() + * Read pppoe statistics + */ +static ssize_t nss_pppoe_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + + uint32_t max_output_lines = 2 /* header & footer for session stats */ + + NSS_MAX_PPPOE_DYNAMIC_INTERFACES * (NSS_PPPOE_STATS_SESSION_MAX + 2) /*session stats */ + + 2 + NSS_PPPOE_STATS_BASE_MAX + 2; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + struct net_device *dev; + int id; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + /* + * Base node stats + */ + size_wr += nss_stats_print("pppoe", "pppoe base node stats start" + , NSS_STATS_SINGLE_INSTANCE + , nss_pppoe_strings_base_stats + , pppoe_stats.base_stats + , NSS_PPPOE_STATS_BASE_MAX + , lbuf, size_wr, size_al); + + /* + * Session stats + */ + for (id = 0; id < NSS_MAX_PPPOE_DYNAMIC_INTERFACES; id++) { + if (!pppoe_stats.session_stats[id].valid) { + continue; + } + + dev = dev_get_by_index(&init_net, pppoe_stats.session_stats[id].if_index); + if (unlikely(!dev)) { + continue; + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d, netdevice=%s\n", id, + pppoe_stats.session_stats[id].if_num, dev->name); + dev_put(dev); + + size_wr += nss_stats_print("pppoe", "pppoe session node stats" + , id + , nss_pppoe_strings_session_stats + , pppoe_stats.session_stats[id].stats + , NSS_PPPOE_STATS_SESSION_MAX + , lbuf, size_wr, size_al); + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr); + + kfree(lbuf); + return bytes_read; +} + +/* + * nss_pppoe_stats_pppoe_session_init() + * Initialize the session statistics. + */ +bool nss_pppoe_stats_pppoe_session_init(uint32_t if_num, struct net_device *dev) +{ + int i; + + spin_lock_bh(&nss_pppoe_stats_lock); + for (i = 0; i < NSS_MAX_PPPOE_DYNAMIC_INTERFACES; i++) { + if (!pppoe_stats.session_stats[i].valid) { + pppoe_stats.session_stats[i].valid = true; + pppoe_stats.session_stats[i].if_num = if_num; + pppoe_stats.session_stats[i].if_index = dev->ifindex; + spin_unlock_bh(&nss_pppoe_stats_lock); + return true; + } + } + spin_unlock_bh(&nss_pppoe_stats_lock); + + return false; +} + +/* + * nss_pppoe_stats_pppoe_session_deinit() + * De-initialize the session's stats. + */ +void nss_pppoe_stats_pppoe_session_deinit(uint32_t if_num) +{ + int i; + + spin_lock_bh(&nss_pppoe_stats_lock); + for (i = 0; i < NSS_MAX_PPPOE_DYNAMIC_INTERFACES; i++) { + if (pppoe_stats.session_stats[i].if_num == if_num) { + memset(&pppoe_stats.session_stats[i], 0, sizeof(pppoe_stats.session_stats[i])); + } + } + spin_unlock_bh(&nss_pppoe_stats_lock); +} + +/* + * nss_pppoe_stats_sync + * Per session debug stats for pppoe + */ +void nss_pppoe_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_pppoe_sync_stats_msg *stats_msg, uint16_t if_num) +{ + int i; + spin_lock_bh(&nss_pppoe_stats_lock); + for (i = 0; i < NSS_MAX_PPPOE_DYNAMIC_INTERFACES; i++) { + if (pppoe_stats.session_stats[i].if_num == if_num) { + int j; + + /* + * Sync PPPoE session stats. + */ + pppoe_stats.session_stats[i].stats[NSS_PPPOE_STATS_SESSION_RX_PACKETS] += stats_msg->session_stats.node.rx_packets; + pppoe_stats.session_stats[i].stats[NSS_PPPOE_STATS_SESSION_RX_BYTES] += stats_msg->session_stats.node.rx_bytes; + pppoe_stats.session_stats[i].stats[NSS_PPPOE_STATS_SESSION_TX_PACKETS] += stats_msg->session_stats.node.tx_packets; + pppoe_stats.session_stats[i].stats[NSS_PPPOE_STATS_SESSION_TX_BYTES] += stats_msg->session_stats.node.tx_bytes; + pppoe_stats.session_stats[i].stats[NSS_PPPOE_STATS_SESSION_WRONG_VERSION_OR_TYPE] += stats_msg->session_stats.exception[NSS_PPPOE_SESSION_EXCEPTION_EVENT_WRONG_VERSION_OR_TYPE]; + pppoe_stats.session_stats[i].stats[NSS_PPPOE_STATS_SESSION_WRONG_CODE] += stats_msg->session_stats.exception[NSS_PPPOE_SESSION_EXCEPTION_EVENT_WRONG_CODE]; + pppoe_stats.session_stats[i].stats[NSS_PPPOE_STATS_SESSION_UNSUPPORTED_PPP_PROTOCOL] += stats_msg->session_stats.exception[NSS_PPPOE_SESSION_EXCEPTION_EVENT_UNSUPPORTED_PPP_PROTOCOL]; + + /* + * Sync PPPoE base node stats coming with this session's stats. + */ + pppoe_stats.base_stats[NSS_PPPOE_STATS_BASE_RX_PACKETS] += stats_msg->base_stats.node.rx_packets; + pppoe_stats.base_stats[NSS_PPPOE_STATS_BASE_RX_BYTES] += stats_msg->base_stats.node.rx_bytes; + pppoe_stats.base_stats[NSS_PPPOE_STATS_BASE_TX_PACKETS] += stats_msg->base_stats.node.tx_packets; + pppoe_stats.base_stats[NSS_PPPOE_STATS_BASE_TX_BYTES] += stats_msg->base_stats.node.tx_bytes; + + for (j = 0; j < NSS_MAX_NUM_PRI; j++) { + pppoe_stats.base_stats[NSS_PPPOE_STATS_BASE_RX_QUEUE_0_DROPPED + j] += stats_msg->base_stats.node.rx_dropped[j]; + } + + /* + * Sync PPPoE base exception stats coming with this session's stats. + */ + pppoe_stats.base_stats[NSS_PPPOE_STATS_BASE_SHORT_PPPOE_HDR_LENGTH] += stats_msg->base_stats.exception[NSS_PPPOE_BASE_EXCEPTION_EVENT_SHORT_PPPOE_HDR_LENGTH]; + pppoe_stats.base_stats[NSS_PPPOE_STATS_BASE_SHORT_PACKET_LENGTH] += stats_msg->base_stats.exception[NSS_PPPOE_BASE_EXCEPTION_EVENT_SHORT_PACKET_LENGTH]; + pppoe_stats.base_stats[NSS_PPPOE_STATS_BASE_WRONG_VERSION_OR_TYPE] += stats_msg->base_stats.exception[NSS_PPPOE_BASE_EXCEPTION_EVENT_WRONG_VERSION_OR_TYPE]; + pppoe_stats.base_stats[NSS_PPPOE_STATS_BASE_WRONG_CODE] += stats_msg->base_stats.exception[NSS_PPPOE_BASE_EXCEPTION_EVENT_WRONG_CODE]; + pppoe_stats.base_stats[NSS_PPPOE_STATS_BASE_UNSUPPORTED_PPP_PROTOCOL] += stats_msg->base_stats.exception[NSS_PPPOE_BASE_EXCEPTION_EVENT_UNSUPPORTED_PPP_PROTOCOL]; + pppoe_stats.base_stats[NSS_PPPOE_STATS_BASE_DISABLED_BRIDGE_PACKET] += stats_msg->base_stats.exception[NSS_PPPOE_BASE_EXCEPTION_EVENT_DISABLED_BRIDGE_PACKET]; + break; + } + } + spin_unlock_bh(&nss_pppoe_stats_lock); +} + +/* + * nss_pppoe_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(pppoe); + +/* + * nss_pppoe_stats_dentry_create() + * Create PPPoE node statistics debug entry. + */ +void nss_pppoe_stats_dentry_create(void) +{ + nss_stats_create_dentry("pppoe", &nss_pppoe_stats_ops); +} + +/* + * nss_pppoe_stats_notify() + * Sends notifications to the registered modules. + * + * Leverage NSS-FW statistics timing to update Netlink. + */ +void nss_pppoe_stats_notify(struct nss_ctx_instance *nss_ctx, uint32_t if_num) +{ + struct nss_pppoe_stats_notification nss_pppoe_stats; + int id; + + for (id = 0; id < NSS_MAX_PPPOE_DYNAMIC_INTERFACES; id++) { + if (pppoe_stats.session_stats[id].if_num == if_num) { + memcpy(&nss_pppoe_stats.session_stats, &pppoe_stats.session_stats[id].stats, sizeof(nss_pppoe_stats.session_stats)); + } + } + memcpy(&nss_pppoe_stats.base_stats, &pppoe_stats.base_stats, sizeof(nss_pppoe_stats.base_stats)); + nss_pppoe_stats.core_id = nss_ctx->id; + nss_pppoe_stats.if_num = if_num; + atomic_notifier_call_chain(&nss_pppoe_stats_notifier, NSS_STATS_EVENT_NOTIFY, (void *)&nss_pppoe_stats); +} + +/* + * nss_pppoe_stats_register_notifier() + * Registers statistics notifier. + */ +int nss_pppoe_stats_register_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&nss_pppoe_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_pppoe_stats_register_notifier); + +/* + * nss_pppoe_stats_unregister_notifier() + * Deregisters statistics notifier. + */ +int nss_pppoe_stats_unregister_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&nss_pppoe_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_pppoe_stats_unregister_notifier); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_pppoe_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_pppoe_stats.h new file mode 100644 index 000000000..41c726ed1 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_pppoe_stats.h @@ -0,0 +1,28 @@ +/* + ****************************************************************************** + * Copyright (c) 2017,2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_PPPOE_STATS_H +#define __NSS_PPPOE_STATS_H + +/* + * PPPoE statistics APIs + */ +extern void nss_pppoe_stats_notify(struct nss_ctx_instance *nss_ctx, uint32_t if_num); +extern void nss_pppoe_stats_dentry_create(void); +extern void nss_pppoe_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_pppoe_sync_stats_msg *stats_msg, uint16_t if_num); +extern bool nss_pppoe_stats_pppoe_session_init(uint32_t if_num, struct net_device *dev); +extern void nss_pppoe_stats_pppoe_session_deinit(uint32_t if_num); +#endif /* __NSS_PPPOE_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_pppoe_strings.c b/feeds/ipq807x/qca-nss-drv/src/nss_pppoe_strings.c new file mode 100644 index 000000000..953945bc6 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_pppoe_strings.c @@ -0,0 +1,121 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_stats.h" +#include "nss_core.h" +#include +#include "nss_strings.h" + +/* + * nss_pppoe_strings_session_stats + * PPPoE session stats strings. + */ +struct nss_stats_info nss_pppoe_strings_session_stats[NSS_PPPOE_STATS_SESSION_MAX] = { + {"rx_pkts" , NSS_STATS_TYPE_COMMON}, + {"rx_byts" , NSS_STATS_TYPE_COMMON}, + {"tx_pkts" , NSS_STATS_TYPE_COMMON}, + {"tx_byts" , NSS_STATS_TYPE_COMMON}, + {"wrong_version_or_type" , NSS_STATS_TYPE_EXCEPTION}, + {"wrong_code" , NSS_STATS_TYPE_EXCEPTION}, + {"unsupported_ppp_protocol" , NSS_STATS_TYPE_EXCEPTION} +}; + +/* + * nss_pppoe_strings_base_stats + * PPPoE base node stats strings. + */ +struct nss_stats_info nss_pppoe_strings_base_stats[NSS_PPPOE_STATS_BASE_MAX] = { + {"rx_packets" , NSS_STATS_TYPE_COMMON}, + {"rx_bytes" , NSS_STATS_TYPE_COMMON}, + {"tx_packets" , NSS_STATS_TYPE_COMMON}, + {"tx_bytes" , NSS_STATS_TYPE_COMMON}, + {"rx_dropped[0]" , NSS_STATS_TYPE_DROP}, + {"rx_dropped[1]" , NSS_STATS_TYPE_DROP}, + {"rx_dropped[2]" , NSS_STATS_TYPE_DROP}, + {"rx_dropped[3]" , NSS_STATS_TYPE_DROP}, + {"short_pppoe_hdr_length" , NSS_STATS_TYPE_EXCEPTION}, + {"short_packet_length" , NSS_STATS_TYPE_EXCEPTION}, + {"wrong_version_or_type" , NSS_STATS_TYPE_EXCEPTION}, + {"wrong_code" , NSS_STATS_TYPE_EXCEPTION}, + {"unsupported_ppp_protocol" , NSS_STATS_TYPE_EXCEPTION}, + {"disabled_bridge_packet" , NSS_STATS_TYPE_EXCEPTION} +}; + +/* + * nss_pppoe_isession_stats_strings_read() + * Read PPPoE session statistics names. + */ +static ssize_t nss_pppoe_session_stats_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_pppoe_strings_session_stats, NSS_PPPOE_STATS_SESSION_MAX); +} + +/* + * nss_pppoe_base_stats_strings_read() + * Read PPPoE base statistics names. + */ +static ssize_t nss_pppoe_base_stats_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_pppoe_strings_base_stats, NSS_PPPOE_STATS_BASE_MAX); +} + +/* + * nss_pppoe_session_stats_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(pppoe_session_stats); + +/* + * nss_pppoe_base_stats_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(pppoe_base_stats); + +/* + * nss_pppoe_strings_dentry_create() + * Create PPPoE statistics strings debug entry. + */ +void nss_pppoe_strings_dentry_create(void) +{ + struct dentry *pppoe_d = NULL; + struct dentry *pppoe_session_stats_d = NULL; + struct dentry *pppoe_base_stats_d = NULL; + + if (!nss_top_main.strings_dentry) { + nss_warning("qca-nss-drv/strings is not present"); + return; + } + + pppoe_d = debugfs_create_dir("pppoe", nss_top_main.strings_dentry); + if (!pppoe_d) { + nss_warning("Failed to create qca-nss-drv/strings/pppoe directory"); + return; + } + + pppoe_session_stats_d = debugfs_create_file("session_stats_str", 0400, pppoe_d, &nss_top_main, &nss_pppoe_session_stats_strings_ops); + if (!pppoe_session_stats_d) { + nss_warning("Failed to create qca-nss-drv/stats/pppoe/session_stats_str file"); + debugfs_remove_recursive(pppoe_d); + return; + } + + pppoe_base_stats_d = debugfs_create_file("base_stats_str", 0400, pppoe_d, &nss_top_main, &nss_pppoe_base_stats_strings_ops); + if (!pppoe_base_stats_d) { + nss_warning("Failed to create qca-nss-drv/stats/pppoe/base_stats_str file"); + debugfs_remove_recursive(pppoe_d); + return; + } +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_pppoe_strings.h b/feeds/ipq807x/qca-nss-drv/src/nss_pppoe_strings.h new file mode 100644 index 000000000..8cf9393a1 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_pppoe_strings.h @@ -0,0 +1,26 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_PPPOE_STRINGS_H +#define __NSS_PPPOE_STRINGS_H + +extern struct nss_stats_info nss_pppoe_strings_session_stats[NSS_PPPOE_STATS_SESSION_MAX]; +extern struct nss_stats_info nss_pppoe_strings_base_stats[NSS_PPPOE_STATS_BASE_MAX]; +extern void nss_pppoe_strings_dentry_create(void); + +#endif /* __NSS_PPPOE_STRINGS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_pptp.c b/feeds/ipq807x/qca-nss-drv/src/nss_pptp.c new file mode 100644 index 000000000..1066d0042 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_pptp.c @@ -0,0 +1,472 @@ +/* + ************************************************************************** + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include +#include "nss_tx_rx_common.h" +#include "nss_pptp_stats.h" +#include "nss_pptp_log.h" +#include "nss_pptp_strings.h" + +#define NSS_PPTP_TX_TIMEOUT 3000 /* 3 Seconds */ + +/* + * Data structures to store pptp nss debug stats + */ +static DEFINE_SPINLOCK(nss_pptp_session_debug_stats_lock); +static struct nss_pptp_stats_session_debug nss_pptp_session_debug_stats[NSS_MAX_PPTP_DYNAMIC_INTERFACES]; + +/* + * Private data structure + */ +static struct nss_pptp_pvt { + struct semaphore sem; + struct completion complete; + int response; + void *cb; + void *app_data; +} pptp_pvt; + +/* + * nss_pptp_session_debug_stats_sync + * Per session debug stats for pptp + */ +void nss_pptp_session_debug_stats_sync(struct nss_ctx_instance *nss_ctx, + struct nss_pptp_sync_session_stats_msg *stats_msg, uint16_t if_num) +{ + int i, j, if_type; + + if_type = nss_dynamic_interface_get_type(nss_pptp_get_context(), if_num); + spin_lock_bh(&nss_pptp_session_debug_stats_lock); + for (i = 0; i < NSS_MAX_PPTP_DYNAMIC_INTERFACES; i++) { + if (nss_pptp_session_debug_stats[i].if_num == if_num) { + break; + } + } + + if (i == NSS_MAX_PPTP_DYNAMIC_INTERFACES) { + spin_unlock_bh(&nss_pptp_session_debug_stats_lock); + return; + } + + if (if_type == NSS_DYNAMIC_INTERFACE_TYPE_PPTP_OUTER) { + nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_DECAP_RX_PACKETS] += + stats_msg->node_stats.rx_packets; + nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_DECAP_RX_BYTES] += + stats_msg->node_stats.rx_bytes; + nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_DECAP_TX_PACKETS] += + stats_msg->node_stats.tx_packets; + nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_DECAP_TX_BYTES] += + stats_msg->node_stats.tx_bytes; + for (j = 0; j < NSS_MAX_NUM_PRI; j++) { + nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_DECAP_RX_QUEUE_0_DROP + j] += + stats_msg->node_stats.rx_dropped[j]; + } + } else { + nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_ENCAP_RX_PACKETS] += + stats_msg->node_stats.rx_packets; + nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_ENCAP_RX_BYTES] += + stats_msg->node_stats.rx_bytes; + nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_ENCAP_TX_PACKETS] += + stats_msg->node_stats.tx_packets; + nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_ENCAP_TX_BYTES] += + stats_msg->node_stats.tx_bytes; + for (j = 0; j < NSS_MAX_NUM_PRI; j++) { + nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_ENCAP_RX_QUEUE_0_DROP + j] += + stats_msg->node_stats.rx_dropped[j]; + } + } + + nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_SESSION_ENCAP_HEADROOM_ERR] += + stats_msg->exception_events[PPTP_EXCEPTION_EVENT_ENCAP_HEADROOM_ERR]; + nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_SESSION_ENCAP_SMALL_SIZE] += + stats_msg->exception_events[PPTP_EXCEPTION_EVENT_ENCAP_SMALL_SIZE]; + nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_SESSION_ENCAP_PNODE_ENQUEUE_FAIL] += + stats_msg->exception_events[PPTP_EXCEPTION_EVENT_ENCAP_PNODE_ENQUEUE_FAIL]; + nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_SESSION_DECAP_NO_SEQ_NOR_ACK] += + stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_NO_SEQ_NOR_ACK]; + nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_SESSION_DECAP_INVAL_GRE_FLAGS] += + stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_INVAL_GRE_FLAGS]; + nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_SESSION_DECAP_INVAL_GRE_PROTO] += + stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_INVAL_GRE_PROTO]; + nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_SESSION_DECAP_WRONG_SEQ] += + stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_WRONG_SEQ]; + nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_SESSION_DECAP_INVAL_PPP_HDR] += + stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_INVAL_PPP_HDR]; + nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_SESSION_DECAP_PPP_LCP] += + stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_PPP_LCP]; + nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_SESSION_DECAP_UNSUPPORTED_PPP_PROTO] += + stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_UNSUPPORTED_PPP_PROTO]; + nss_pptp_session_debug_stats[i].stats[NSS_PPTP_STATS_SESSION_DECAP_PNODE_ENQUEUE_FAIL] += + stats_msg->exception_events[PPTP_EXCEPTION_EVENT_DECAP_PNODE_ENQUEUE_FAIL]; + + spin_unlock_bh(&nss_pptp_session_debug_stats_lock); +} + +/* + * nss_pptp_global_session_stats_get() + * Get session pptp statitics. + */ +void nss_pptp_session_debug_stats_get(void *stats_mem) +{ + struct nss_pptp_stats_session_debug *stats = (struct nss_pptp_stats_session_debug *)stats_mem; + int i; + + if (!stats) { + nss_warning("No memory to copy pptp session stats"); + return; + } + + spin_lock_bh(&nss_pptp_session_debug_stats_lock); + for (i = 0; i < NSS_MAX_PPTP_DYNAMIC_INTERFACES; i++) { + if (nss_pptp_session_debug_stats[i].valid) { + memcpy(stats, &nss_pptp_session_debug_stats[i], sizeof(struct nss_pptp_stats_session_debug)); + stats++; + } + } + spin_unlock_bh(&nss_pptp_session_debug_stats_lock); +} + +/* + * nss_pptp_verify_if_num() + * Verify if_num passed to us. + */ +static bool nss_pptp_verify_if_num(uint32_t if_num) +{ + uint32_t if_type; + + if (nss_is_dynamic_interface(if_num) == false) { + return false; + } + + if_type = nss_dynamic_interface_get_type(nss_pptp_get_context(), if_num); + switch(if_type) { + case NSS_DYNAMIC_INTERFACE_TYPE_PPTP_INNER: + case NSS_DYNAMIC_INTERFACE_TYPE_PPTP_OUTER: + case NSS_DYNAMIC_INTERFACE_TYPE_PPTP_HOST_INNER: + return true; + } + + return false; +} + +/* + * nss_pptp_handler() + * Handle NSS -> HLOS messages for pptp tunnel + */ +static void nss_pptp_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_pptp_msg *ntm = (struct nss_pptp_msg *)ncm; + void *ctx; + + nss_pptp_msg_callback_t cb; + + BUG_ON(!nss_pptp_verify_if_num(ncm->interface)); + + /* + * Trace Messages + */ + nss_pptp_log_rx_msg(ntm); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_PPTP_MSG_MAX) { + nss_warning("%px: received invalid message %d for PPTP interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_pptp_msg)) { + nss_warning("%px: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + switch (ntm->cm.type) { + + case NSS_PPTP_MSG_SYNC_STATS: + /* + * Update session debug stats in stats msg and send statistics notifications to the registered modules. + */ + nss_pptp_session_debug_stats_sync(nss_ctx, &ntm->msg.stats, ncm->interface); + nss_pptp_stats_notify(nss_ctx, ncm->interface); + break; + } + + /* + * Update the callback and app_data for NOTIFY messages, pptp sends all notify messages + * to the same callback/app_data. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_ctx->nss_top->pptp_msg_callback; + ncm->app_data = (nss_ptr_t)nss_ctx->subsys_dp_register[ncm->interface].app_data; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Do we have a call back + */ + if (!ncm->cb) { + return; + } + + /* + * callback + */ + cb = (nss_pptp_msg_callback_t)ncm->cb; + ctx = (void *)ncm->app_data; + + /* + * call pptp tunnel callback + */ + if (!cb) { + nss_warning("%px: Event received for pptp tunnel interface %d before registration", nss_ctx, ncm->interface); + return; + } + + cb(ctx, ntm); +} + +/* + * nss_pptp_tx_msg() + * Transmit a pptp message to NSS firmware + */ +static nss_tx_status_t nss_pptp_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_pptp_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Trace Messages + */ + nss_pptp_log_tx_msg(msg); + + /* + * Sanity check the message + */ + if (!nss_is_dynamic_interface(ncm->interface)) { + nss_warning("%px: tx request for non dynamic interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type > NSS_PPTP_MSG_MAX) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} + +/* + * nss_pptp_sync_msg_callback() + * Callback to handle the completion of NSS->HLOS messages. + */ +static void nss_pptp_sync_msg_callback(void *app_data, struct nss_pptp_msg *nim) +{ + nss_pptp_msg_callback_t callback = (nss_pptp_msg_callback_t)pptp_pvt.cb; + void *data = pptp_pvt.app_data; + + pptp_pvt.cb = NULL; + pptp_pvt.app_data = NULL; + + if (nim->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("pptp Error response %d\n", nim->cm.response); + + pptp_pvt.response = NSS_TX_FAILURE; + if (callback) { + callback(data, nim); + } + + complete(&pptp_pvt.complete); + return; + } + + pptp_pvt.response = NSS_TX_SUCCESS; + if (callback) { + callback(data, nim); + } + + complete(&pptp_pvt.complete); +} + +/* + * nss_pptp_tx_msg() + * Transmit a pptp message to NSS firmware synchronously. + */ +nss_tx_status_t nss_pptp_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_pptp_msg *msg) +{ + + nss_tx_status_t status; + int ret = 0; + + down(&pptp_pvt.sem); + pptp_pvt.cb = (void *)msg->cm.cb; + pptp_pvt.app_data = (void *)msg->cm.app_data; + + msg->cm.cb = (nss_ptr_t)nss_pptp_sync_msg_callback; + msg->cm.app_data = (nss_ptr_t)NULL; + + status = nss_pptp_tx_msg(nss_ctx, msg); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: pptp_tx_msg failed\n", nss_ctx); + up(&pptp_pvt.sem); + return status; + } + + ret = wait_for_completion_timeout(&pptp_pvt.complete, msecs_to_jiffies(NSS_PPTP_TX_TIMEOUT)); + + if (!ret) { + nss_warning("%px: PPTP msg tx failed due to timeout\n", nss_ctx); + pptp_pvt.response = NSS_TX_FAILURE; + } + + status = pptp_pvt.response; + up(&pptp_pvt.sem); + return status; +} + +/* + * nss_pptp_tx_buf() + * Send packet to pptp interface owned by NSS + */ +nss_tx_status_t nss_pptp_tx_buf(struct nss_ctx_instance *nss_ctx, uint32_t if_num, struct sk_buff *skb) +{ + nss_trace("%px: pptp If Tx packet, id:%d, data=%px", nss_ctx, if_num, skb->data); + + return nss_core_send_packet(nss_ctx, skb, if_num, H2N_BIT_FLAG_BUFFER_REUSABLE); +} + +/* + * nss_register_pptp_if() + */ +struct nss_ctx_instance *nss_register_pptp_if(uint32_t if_num, + uint32_t type, + nss_pptp_callback_t pptp_data_callback, + nss_pptp_msg_callback_t notification_callback, + struct net_device *netdev, + uint32_t features, + void *app_ctx) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.pptp_handler_id]; + int i = 0; + + nss_assert(nss_ctx); + nss_assert(nss_pptp_verify_if_num()); + + nss_ctx->subsys_dp_register[if_num].type = type; + + nss_core_register_subsys_dp(nss_ctx, if_num, pptp_data_callback, NULL, app_ctx, netdev, features); + + nss_top_main.pptp_msg_callback = notification_callback; + + nss_core_register_handler(nss_ctx, if_num, nss_pptp_handler, NULL); + + spin_lock_bh(&nss_pptp_session_debug_stats_lock); + for (i = 0; i < NSS_MAX_PPTP_DYNAMIC_INTERFACES; i++) { + if (!nss_pptp_session_debug_stats[i].valid) { + nss_pptp_session_debug_stats[i].valid = true; + nss_pptp_session_debug_stats[i].if_num = if_num; + nss_pptp_session_debug_stats[i].if_index = netdev->ifindex; + break; + } + } + spin_unlock_bh(&nss_pptp_session_debug_stats_lock); + + return nss_ctx; +} + +/* + * nss_unregister_pptp_if() + */ +void nss_unregister_pptp_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.pptp_handler_id]; + int i; + int j; + + nss_assert(nss_ctx); + nss_assert(nss_is_dynamic_interface(if_num)); + + spin_lock_bh(&nss_pptp_session_debug_stats_lock); + for (i = 0; i < NSS_MAX_PPTP_DYNAMIC_INTERFACES; i++) { + if (nss_pptp_session_debug_stats[i].valid == true && + nss_pptp_session_debug_stats[i].if_num == if_num) { + nss_pptp_session_debug_stats[i].valid = false; + nss_pptp_session_debug_stats[i].if_num = 0; + nss_pptp_session_debug_stats[i].if_index = 0; + for (j = 0; j < NSS_PPTP_STATS_SESSION_MAX; j++) + nss_pptp_session_debug_stats[i].stats[j] = 0; + break; + } + } + spin_unlock_bh(&nss_pptp_session_debug_stats_lock); + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + + nss_top_main.pptp_msg_callback = NULL; + + nss_core_unregister_handler(nss_ctx, if_num); +} + +/* + * nss_get_pptp_context() + */ +struct nss_ctx_instance *nss_pptp_get_context() +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.pptp_handler_id]; +} + +/* + * nss_pptp_msg_init() + * Initialize nss_pptp msg. + */ +void nss_pptp_msg_init(struct nss_pptp_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data) +{ + nss_cmn_msg_init(&ncm->cm, if_num, type, len, cb, app_data); +} + +/* nss_pptp_register_handler() + * debugfs stats msg handler received on static pptp interface + */ +void nss_pptp_register_handler(void) +{ + int i; + + nss_info("nss_pptp_register_handler"); + nss_core_register_handler(nss_pptp_get_context(), NSS_PPTP_INTERFACE, nss_pptp_handler, NULL); + + spin_lock_bh(&nss_pptp_session_debug_stats_lock); + for (i = 0; i < NSS_MAX_PPTP_DYNAMIC_INTERFACES; i++) { + nss_pptp_session_debug_stats[i].valid = false; + nss_pptp_session_debug_stats[i].if_num = 0; + nss_pptp_session_debug_stats[i].if_index = 0; + } + spin_unlock_bh(&nss_pptp_session_debug_stats_lock); + + sema_init(&pptp_pvt.sem, 1); + init_completion(&pptp_pvt.complete); + + nss_pptp_stats_dentry_create(); + nss_pptp_strings_dentry_create(); +} + +EXPORT_SYMBOL(nss_pptp_get_context); +EXPORT_SYMBOL(nss_pptp_tx_msg_sync); +EXPORT_SYMBOL(nss_pptp_tx_buf); +EXPORT_SYMBOL(nss_unregister_pptp_if); +EXPORT_SYMBOL(nss_pptp_msg_init); +EXPORT_SYMBOL(nss_register_pptp_if); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_pptp_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_pptp_log.c new file mode 100644 index 000000000..136a3c863 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_pptp_log.c @@ -0,0 +1,129 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_pptp_log.c + * NSS PPTP logger file. + */ + +#include "nss_core.h" + +/* + * nss_pptp_log_message_types_str + * NSS PPTP message strings + */ +static int8_t *nss_pptp_log_message_types_str[NSS_PPTP_MSG_MAX] __maybe_unused = { + "PPTP Session Configure", + "PPTP Session Deconfigure", + "PPTP Stats", +}; + +/* + * nss_pptp_log_configure_msg() + * Log NSS PPTP Session Configure. + */ +static void nss_pptp_log_configure_msg(struct nss_pptp_msg *npm) +{ + struct nss_pptp_session_configure_msg *npcm __maybe_unused = &npm->msg.session_configure_msg; + nss_trace("%px: NSS PPTP Session Configure message\n" + "PPTP Source Call ID: %x\n" + "PPTP Destination Call ID: %x\n" + "PPTP Source IP: %pI4\n" + "PPTP Destination IP: %pI4\n", + npcm, npcm->src_call_id, + npcm->dst_call_id, &npcm->sip, + &npcm->dip); +} + +/* + * nss_pptp_log_deconfigure_msg() + * Log NSS PPTP Session Deconfigure. + */ +static void nss_pptp_log_deconfigure_msg(struct nss_pptp_msg *npm) +{ + struct nss_pptp_session_deconfigure_msg *npdm __maybe_unused = &npm->msg.session_deconfigure_msg; + nss_trace("%px: NSS PPTP Session Configure message \n" + "PPTP Source Call ID: %x\n", + npdm, npdm->src_call_id); +} + +/* + * nss_pptp_log_verbose() + * Log message contents. + */ +static void nss_pptp_log_verbose(struct nss_pptp_msg *npm) +{ + switch (npm->cm.type) { + case NSS_PPTP_MSG_SESSION_CONFIGURE: + nss_pptp_log_configure_msg(npm); + break; + + case NSS_PPTP_MSG_SESSION_DECONFIGURE: + nss_pptp_log_deconfigure_msg(npm); + break; + + case NSS_PPTP_MSG_SYNC_STATS: + /* + * No log for valid stats message. + */ + break; + + default: + nss_trace("%px: Invalid message type\n", npm); + break; + } +} + +/* + * nss_pptp_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_pptp_log_tx_msg(struct nss_pptp_msg *npm) +{ + if (npm->cm.type >= NSS_PPTP_MSG_MAX) { + nss_warning("%px: Invalid message type\n", npm); + return; + } + + nss_info("%px: type[%d]:%s\n", npm, npm->cm.type, nss_pptp_log_message_types_str[npm->cm.type]); + nss_pptp_log_verbose(npm); +} + +/* + * nss_pptp_log_rx_msg() + * Log messages received from FW. + */ +void nss_pptp_log_rx_msg(struct nss_pptp_msg *npm) +{ + if (npm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", npm); + return; + } + + if (npm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (npm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", npm, npm->cm.type, + nss_pptp_log_message_types_str[npm->cm.type], + npm->cm.response, nss_cmn_response_str[npm->cm.response]); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s\n", + npm, npm->cm.type, nss_pptp_log_message_types_str[npm->cm.type], + npm->cm.response, nss_cmn_response_str[npm->cm.response]); + +verbose: + nss_pptp_log_verbose(npm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_pptp_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_pptp_log.h new file mode 100644 index 000000000..bb800d5ed --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_pptp_log.h @@ -0,0 +1,41 @@ +/* + ************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_PPTP_LOG_H +#define __NSS_PPTP_LOG_H + +/* + * nss_pptp.h + * NSS PPTP header file. + */ + +/* + * Logger APIs + */ + +/* + * nss_pptp_log_tx_msg + * Logs a pptp message that is sent to the NSS firmware. + */ +void nss_pptp_log_tx_msg(struct nss_pptp_msg *ntm); + +/* + * nss_pptp_log_rx_msg + * Logs a pptp message that is received from the NSS firmware. + */ +void nss_pptp_log_rx_msg(struct nss_pptp_msg *ntm); + +#endif /* __NSS_PPTP_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_pptp_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_pptp_stats.c new file mode 100644 index 000000000..afbe00ee0 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_pptp_stats.c @@ -0,0 +1,154 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_pptp_stats.h" +#include "nss_pptp_strings.h" + +/* + * Declare atomic notifier data structure for statistics. + */ +ATOMIC_NOTIFIER_HEAD(nss_pptp_stats_notifier); + +struct nss_pptp_stats_session_debug pptp_session_stats[NSS_MAX_PPTP_DYNAMIC_INTERFACES]; + +/* + * nss_pptp_stats_read() + * Read pptp statistics + */ +static ssize_t nss_pptp_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + + uint32_t max_output_lines = 2 /* header & footer for session stats */ + + NSS_MAX_PPTP_DYNAMIC_INTERFACES * (NSS_PPTP_STATS_SESSION_MAX + 2) /*session stats */ + + 2; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines ; + size_t size_wr = 0; + ssize_t bytes_read = 0; + struct net_device *dev; + int id, i; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + memset(&pptp_session_stats, 0, sizeof(struct nss_pptp_stats_session_debug) * NSS_MAX_PPTP_DYNAMIC_INTERFACES); + + /* + * Get all stats + */ + nss_pptp_session_debug_stats_get((void *)&pptp_session_stats); + + /* + * Session stats + */ + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\npptp session stats start:\n\n"); + for (id = 0; id < NSS_MAX_PPTP_DYNAMIC_INTERFACES; id++) { + + if (!pptp_session_stats[id].valid) { + break; + } + + dev = dev_get_by_index(&init_net, pptp_session_stats[id].if_index); + if (likely(dev)) { + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d, netdevice=%s\n", id, + pptp_session_stats[id].if_num, dev->name); + dev_put(dev); + } else { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. nss interface id=%d\n", id, + pptp_session_stats[id].if_num); + } + + for (i = 0; i < NSS_PPTP_STATS_SESSION_MAX; i++) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "\t%s = %llu\n", nss_pptp_strings_session_debug_stats[i].stats_name, + pptp_session_stats[id].stats[i]); + } + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n"); + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\npptp session stats end\n"); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr); + + kfree(lbuf); + return bytes_read; +} + +/* + * nss_pptp_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(pptp); + +/* + * nss_pptp_stats_dentry_create() + * Create PPTP node statistics debug entry. + */ +void nss_pptp_stats_dentry_create(void) +{ + nss_stats_create_dentry("pptp", &nss_pptp_stats_ops); +} + +/* + * nss_pptp_stats_notify() + * Sends notifications to the registered modules. + * + * Leverage NSS-FW statistics timing to update Netlink. + */ +void nss_pptp_stats_notify(struct nss_ctx_instance *nss_ctx, uint32_t if_num) +{ + struct nss_pptp_stats_notification pptp_stats; + int id; + + memset(&pptp_session_stats, 0, sizeof(pptp_session_stats)); + + /* + * Get all stats + */ + nss_pptp_session_debug_stats_get((void *)&pptp_session_stats); + + for (id = 0; id < NSS_MAX_PPTP_DYNAMIC_INTERFACES; id++) { + if (pptp_session_stats[id].if_num == if_num) { + memcpy(&pptp_stats.stats, &pptp_session_stats[id].stats, sizeof(pptp_stats.stats)); + } + } + pptp_stats.if_type = nss_dynamic_interface_get_type(nss_ctx, if_num); + pptp_stats.core_id = nss_ctx->id; + pptp_stats.if_num = if_num; + atomic_notifier_call_chain(&nss_pptp_stats_notifier, NSS_STATS_EVENT_NOTIFY, (void *)&pptp_stats); +} + +/* + * nss_pptp_stats_register_notifier() + * Registers statistics notifier. + */ +int nss_pptp_stats_register_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&nss_pptp_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_pptp_stats_register_notifier); + +/* + * nss_pptp_stats_unregister_notifier() + * Deregisters statistics notifier. + */ +int nss_pptp_stats_unregister_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&nss_pptp_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_pptp_stats_unregister_notifier); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_pptp_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_pptp_stats.h new file mode 100644 index 000000000..11c016617 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_pptp_stats.h @@ -0,0 +1,36 @@ +/* + ****************************************************************************** + * Copyright (c) 2016-2017,2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_PPTP_STATS_H +#define __NSS_PPTP_STATS_H + +/* + * NSS PPTP node statistics session + */ +struct nss_pptp_stats_session_debug { + uint64_t stats[NSS_PPTP_STATS_SESSION_MAX]; + int32_t if_index; + uint32_t if_num; /* nss interface number */ + bool valid; +}; + +/* + * NSS PPTP statistics APIs + */ +extern void nss_pptp_stats_notify(struct nss_ctx_instance *nss_ctx, uint32_t if_num); +extern void nss_pptp_stats_dentry_create(void); + +#endif /* __NSS_PPTP_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_pptp_strings.c b/feeds/ipq807x/qca-nss-drv/src/nss_pptp_strings.c new file mode 100644 index 000000000..966ec07f3 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_pptp_strings.c @@ -0,0 +1,79 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_stats.h" +#include "nss_core.h" +#include +#include "nss_strings.h" + +/* + * nss_pptp_strings_session_debug_stats + * PPTP statistics strings for NSS session statistics. + */ +struct nss_stats_info nss_pptp_strings_session_debug_stats[NSS_PPTP_STATS_SESSION_MAX] = { + {"ENCAP_RX_PACKETS", NSS_STATS_TYPE_COMMON}, + {"ENCAP_RX_BYTES", NSS_STATS_TYPE_COMMON}, + {"ENCAP_TX_PACKETS", NSS_STATS_TYPE_COMMON}, + {"ENCAP_TX_BYTES", NSS_STATS_TYPE_COMMON}, + {"ENCAP_RX_QUEUE_0_DROP", NSS_STATS_TYPE_DROP}, + {"ENCAP_RX_QUEUE_1_DROP", NSS_STATS_TYPE_DROP}, + {"ENCAP_RX_QUEUE_2_DROP", NSS_STATS_TYPE_DROP}, + {"ENCAP_RX_QUEUE_3_DROP", NSS_STATS_TYPE_DROP}, + {"DECAP_RX_PACKETS", NSS_STATS_TYPE_COMMON}, + {"DECAP_RX_BYTES", NSS_STATS_TYPE_COMMON}, + {"DECAP_TX_PACKETS", NSS_STATS_TYPE_COMMON}, + {"DECAP_TX_BYTES", NSS_STATS_TYPE_COMMON}, + {"DECAP_RX_QUEUE_0_DROP", NSS_STATS_TYPE_DROP}, + {"DECAP_RX_QUEUE_1_DROP", NSS_STATS_TYPE_DROP}, + {"DECAP_RX_QUEUE_2_DROP", NSS_STATS_TYPE_DROP}, + {"DECAP_RX_QUEUE_3_DROP", NSS_STATS_TYPE_DROP}, + {"ENCAP_HEADROOM_ERR", NSS_STATS_TYPE_ERROR}, + {"ENCAP_SMALL_SIZE", NSS_STATS_TYPE_SPECIAL}, + {"ENCAP_PNODE_ENQUEUE_FAIL", NSS_STATS_TYPE_ERROR}, + {"DECAP_NO_SEQ_NOR_ACK", NSS_STATS_TYPE_ERROR}, + {"DECAP_INVAL_GRE_FLAGS", NSS_STATS_TYPE_ERROR}, + {"DECAP_INVAL_GRE_PROTO", NSS_STATS_TYPE_ERROR}, + {"DECAP_WRONG_SEQ", NSS_STATS_TYPE_ERROR}, + {"DECAP_INVAL_PPP_HDR", NSS_STATS_TYPE_ERROR}, + {"DECAP_PPP_LCP", NSS_STATS_TYPE_SPECIAL}, + {"DECAP_UNSUPPORTED_PPP_PROTO", NSS_STATS_TYPE_ERROR}, + {"DECAP_PNODE_ENQUEUE_FAIL", NSS_STATS_TYPE_ERROR} +}; + +/* + * nss_pptp_strings_read() + * Read PPTP node statistics names. + */ +static ssize_t nss_pptp_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_pptp_strings_session_debug_stats, NSS_PPTP_STATS_SESSION_MAX); +} + +/* + * nss_pptp_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(pptp); + +/* + * nss_pptp_strings_dentry_create() + * Create PPTP statistics strings debug entry. + */ +void nss_pptp_strings_dentry_create(void) +{ + nss_strings_create_dentry("pptp", &nss_pptp_strings_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_pptp_strings.h b/feeds/ipq807x/qca-nss-drv/src/nss_pptp_strings.h new file mode 100644 index 000000000..788a387c6 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_pptp_strings.h @@ -0,0 +1,25 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_PPTP_STRINGS_H +#define __NSS_PPTP_STRINGS_H + +extern struct nss_stats_info nss_pptp_strings_session_debug_stats[NSS_PPTP_STATS_SESSION_MAX]; +extern void nss_pptp_strings_dentry_create(void); + +#endif /* __NSS_PPTP_STRINGS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_profiler.c b/feeds/ipq807x/qca-nss-drv/src/nss_profiler.c new file mode 100755 index 000000000..5717ac365 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_profiler.c @@ -0,0 +1,254 @@ +/* + ************************************************************************** + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_profiler.c + * NSS profiler APIs + */ + +#include "nss_tx_rx_common.h" + +/* + * nss_profiler_rx_msg_handler() + * Handle profiler information. + */ +static void nss_profiler_rx_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, void *app) +{ + struct nss_profiler_msg *pm = (struct nss_profiler_msg*)ncm; + void *ctx = nss_ctx->nss_top->profiler_ctx[nss_ctx->id]; + nss_profiler_callback_t cb = nss_ctx->nss_top->profiler_callback[nss_ctx->id]; + + if (ncm->type >= NSS_PROFILER_MAX_MSG_TYPES) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return; + } + + if (ncm->type <= NSS_PROFILER_FLOWCTRL_MSG) { + if (ncm->len > sizeof(pm->payload.pcmdp)) { + nss_warning("%px: reply for cmd %d size is wrong %d : %d\n", nss_ctx, ncm->type, ncm->len, ncm->interface); + return; + } + } else if (ncm->type <= NSS_PROFILER_DEBUG_REPLY_MSG) { + if (ncm->len > sizeof(pm->payload.pdm)) { + nss_warning("%px: reply for debug %d is too big %d\n", nss_ctx, ncm->type, ncm->len); + return; + } + } else if (ncm->type <= NSS_PROFILER_COUNTERS_MSG) { + if (ncm->len < (sizeof(pm->payload.pcmdp) - (PROFILE_MAX_APP_COUNTERS - pm->payload.pcmdp.num_counters) * sizeof(pm->payload.pcmdp.counters[0])) || ncm->len > sizeof(pm->payload.pcmdp)) { + nss_warning("%px: %d params data is too big %d : %d\n", nss_ctx, ncm->type, ncm->len, ncm->interface); + return; + } + } + + /* + * status per request callback + */ + if (ncm->response != NSS_CMN_RESPONSE_NOTIFY && ncm->cb) { + nss_info("%px: reply CB %px for %d %d\n", nss_ctx, (void *)ncm->cb, ncm->type, ncm->response); + cb = (nss_profiler_callback_t)ncm->cb; + } + + /* + * sample related callback + */ + if (!cb || !ctx) { + nss_warning("%px: Event received for profiler interface before registration", nss_ctx); + return; + } + + cb(ctx, (struct nss_profiler_msg *)ncm); +} + +/* + * nss_tx_profiler_if_buf() + * NSS profiler Tx API + */ +nss_tx_status_t nss_profiler_if_tx_buf(void *ctx, void *buf, uint32_t len, + void *cb, void *app_data) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)ctx; + struct nss_profiler_msg *npm; + struct nss_profiler_data_msg *pdm = (struct nss_profiler_data_msg *)buf; + nss_tx_status_t ret; + + nss_trace("%px: Profiler If Tx, buf=%px", nss_ctx, buf); + + if (sizeof(npm->payload) < len) { + nss_warning("%px: (%u)Bad message length(%u)", nss_ctx, NSS_PROFILER_INTERFACE, len); + return NSS_TX_FAILURE_TOO_LARGE; + } + + if (NSS_NBUF_PAYLOAD_SIZE < (len + sizeof(npm->cm))) { + nss_warning("%px: (%u)Message length(%u) is larger than payload size (%u)", + nss_ctx, NSS_PROFILER_INTERFACE, (uint32_t)(len + sizeof(npm->cm)), NSS_NBUF_PAYLOAD_SIZE); + return NSS_TX_FAILURE_TOO_LARGE; + } + + npm = kzalloc(sizeof(*npm), GFP_KERNEL); + if (!npm) { + nss_warning("%px: Failed to allocate memory for message\n", nss_ctx); + return NSS_TX_FAILURE; + } + + memcpy(&npm->payload, pdm, len); + nss_profiler_msg_init(npm, NSS_PROFILER_INTERFACE, pdm->hd_magic & 0xFF, len, + cb, app_data); + + ret = nss_core_send_cmd(nss_ctx, npm, sizeof(npm->cm) + len, NSS_NBUF_PAYLOAD_SIZE); + kfree(npm); + return ret; +} +EXPORT_SYMBOL(nss_profiler_if_tx_buf); + +/* + * nss_profiler_alloc_dma() + * Allocate a DMA for profiler. + */ +void *nss_profiler_alloc_dma(struct nss_ctx_instance *nss_ctx, struct nss_profile_sdma_producer **dma_p) +{ + int size; + void *kaddr; + struct nss_profile_sdma_producer *dma; + struct nss_profile_sdma_ctrl *ctrl = (struct nss_profile_sdma_ctrl *)nss_ctx->meminfo_ctx.sdma_ctrl; + if (!ctrl) + return NULL; + + dma = ctrl->producer; + *dma_p = dma; + size = dma->num_bufs * dma->buf_size; + kaddr = kmalloc(size, GFP_KERNEL | __GFP_ZERO); + + if (kaddr) { + dma->desc_ring = dma_map_single(nss_ctx->dev, kaddr, size, DMA_FROM_DEVICE); + NSS_CORE_DSB(); + } + ctrl->consumer[0].ring.kp = kaddr; + return kaddr; +} +EXPORT_SYMBOL(nss_profiler_alloc_dma); + +/* + * nss_profiler_release_dma() + * Free profiler DMA. + */ +void nss_profiler_release_dma(struct nss_ctx_instance *nss_ctx) +{ + struct nss_profile_sdma_ctrl *ctrl; + if (!nss_ctx) + return; + + ctrl = nss_ctx->meminfo_ctx.sdma_ctrl; + + if (ctrl && ctrl->consumer[0].ring.kp) { + kfree(ctrl->consumer[0].ring.kp); + ctrl->consumer[0].ring.kp = NULL; + } +} +EXPORT_SYMBOL(nss_profiler_release_dma); + +/* + * nss_profile_dma_register_cb + * Register a handler for profile DMA. + */ +bool nss_profile_dma_register_cb(struct nss_ctx_instance *nss_ctx, int id, + void (*cb)(void*), void *arg) +{ + struct nss_profile_sdma_ctrl *ctrl = (struct nss_profile_sdma_ctrl *)nss_ctx->meminfo_ctx.sdma_ctrl; + nss_info("%px dma_register_cb %d: %px %px\n", ctrl, id, cb, arg); + if (!ctrl) + return false; + + ctrl->consumer[id].dispatch.fp = cb; + ctrl->consumer[id].arg.kp = arg; + return true; +} +EXPORT_SYMBOL(nss_profile_dma_register_cb); + +/* + * nss_profile_dma_deregister_cb + * Deregister callback for profile DMA. + */ +bool nss_profile_dma_deregister_cb(struct nss_ctx_instance *nss_ctx, int id) +{ + struct nss_profile_sdma_ctrl *ctrl = (struct nss_profile_sdma_ctrl *)nss_ctx->meminfo_ctx.sdma_ctrl; + if (!ctrl) + return false; + + ctrl->consumer[id].dispatch.fp = NULL; + return true; +} +EXPORT_SYMBOL(nss_profile_dma_deregister_cb); + +/* + * nss_profile_dma_get_ctrl + * Wrapper to get profile DMA control. + */ +struct nss_profile_sdma_ctrl *nss_profile_dma_get_ctrl(struct nss_ctx_instance *nss_ctx) +{ + struct nss_profile_sdma_ctrl *ctrl = nss_ctx->meminfo_ctx.sdma_ctrl; + if (!ctrl) { + return ctrl; + } + + dmac_inv_range(ctrl, &ctrl->cidx); + dsb(sy); + return ctrl; +} +EXPORT_SYMBOL(nss_profile_dma_get_ctrl); + +/* + * nss_profiler_notify_register() + */ +void *nss_profiler_notify_register(nss_core_id_t core_id, nss_profiler_callback_t profiler_callback, void *ctx) +{ + nss_assert(core_id < NSS_CORE_MAX); + + if (NSS_CORE_STATUS_SUCCESS != + nss_core_register_handler(&nss_top_main.nss[core_id], NSS_PROFILER_INTERFACE, nss_profiler_rx_msg_handler, NULL)) { + nss_warning("Message handler FAILED to be registered for profiler"); + return NULL; + } + + nss_top_main.profiler_ctx[core_id] = ctx; + nss_top_main.profiler_callback[core_id] = profiler_callback; + + return (void *)&nss_top_main.nss[core_id]; +} +EXPORT_SYMBOL(nss_profiler_notify_register); + +/* + * nss_profiler_notify_unregister() + */ +void nss_profiler_notify_unregister(nss_core_id_t core_id) +{ + nss_assert(core_id < NSS_CORE_MAX); + + nss_core_unregister_handler(&nss_top_main.nss[core_id], NSS_PROFILER_INTERFACE); + nss_top_main.profiler_callback[core_id] = NULL; + nss_top_main.profiler_ctx[core_id] = NULL; +} +EXPORT_SYMBOL(nss_profiler_notify_unregister); + +/* + * nss_profiler_msg_init() + * Initialize profiler message. + */ +void nss_profiler_msg_init(struct nss_profiler_msg *npm, uint16_t if_num, uint32_t type, uint32_t len, + nss_profiler_callback_t cb, void *app_data) +{ + nss_cmn_msg_init(&npm->cm, if_num, type, len, (void *)cb, app_data); +} +EXPORT_SYMBOL(nss_profiler_msg_init); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_project.c b/feeds/ipq807x/qca-nss-drv/src/nss_project.c new file mode 100644 index 000000000..07402fb76 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_project.c @@ -0,0 +1,338 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * @file nss_project.h + * NSS project APIs. + */ +#include "nss_tx_rx_common.h" + +static int nss_project_wt_stats_enable; + +/* + * nss_project_free_wt_stats() + * Frees a number of allocated worker thread statistics. + */ +static void nss_project_free_wt_stats(struct nss_worker_thread_stats *wt_stats, int num_alloc) +{ + int i; + + if (!wt_stats) { + return; + } + + for (i = 0; i < num_alloc; i++) { + kfree(wt_stats[i].irq_stats); + } + kfree(wt_stats); +} + +/* + * nss_project_alloc_wt_stats() + * Allocates worker thread stats for a given number of threads and IRQs. + */ +static struct nss_worker_thread_stats *nss_project_alloc_wt_stats(uint32_t thread_count, uint32_t irq_count) +{ + struct nss_worker_thread_stats *wt_stats; + int i; + + wt_stats = kzalloc(thread_count * sizeof(struct nss_worker_thread_stats), GFP_ATOMIC); + if (unlikely(!wt_stats)) { + return NULL; + } + + for (i = 0; i < thread_count; i++) { + wt_stats[i].irq_stats = + kzalloc(irq_count * sizeof(struct nss_project_irq_stats), GFP_ATOMIC); + if (unlikely(!wt_stats[i].irq_stats)) { + nss_project_free_wt_stats(wt_stats, i); + return NULL; + } + } + + return wt_stats; +} + +/* + * nss_project_wt_stats_enable_callback() + * Callback function for wt stats enable messages + */ +static void nss_project_wt_stats_enable_callback(void *app_data, struct nss_project_msg *msg) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)app_data; + struct nss_project_msg_wt_stats_enable *stats_enable = &msg->msg.wt_stats_enable; + struct nss_worker_thread_stats *stats_temp; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + if (msg->cm.response != NSS_CMN_RESPONSE_ACK) { + return; + } + + nss_info("%px: Received response ACK for worker thread stats enable msg.\n", nss_ctx); + + /* + * If statistics have already been allocated, nothing else to do. + */ + if (nss_ctx->wt_stats) { + return; + } + + stats_temp = nss_project_alloc_wt_stats(stats_enable->worker_thread_count, + stats_enable->irq_count); + if (unlikely(!stats_temp)) { + nss_warning("%px: Unable to allocate worker thread statistics.\n", nss_ctx); + return; + } + + spin_lock_bh(&nss_ctx->nss_top->stats_lock); + nss_ctx->wt_stats = stats_temp; + nss_ctx->worker_thread_count = stats_enable->worker_thread_count; + nss_ctx->irq_count = stats_enable->irq_count; + spin_unlock_bh(&nss_ctx->nss_top->stats_lock); +} + +/* + * nss_project_wt_stats_send_enable() + * Sends message to firmware to enable or disable worker_thread statistics collection. + */ +static nss_tx_status_t nss_project_wt_stats_send_enable(struct nss_ctx_instance *nss_ctx, bool enable) +{ + struct nss_project_msg *npm; + struct nss_cmn_msg *ncm; + nss_tx_status_t ret; + + npm = kzalloc(sizeof(*npm), GFP_KERNEL); + if (!npm) { + nss_warning("%px: Failed to allocate buffer for message\n", nss_ctx); + return NSS_TX_FAILURE; + } + + /* + * Populate the message + */ + ncm = &npm->cm; + nss_cmn_msg_init(ncm, NSS_PROJECT_INTERFACE, + NSS_PROJECT_MSG_WT_STATS_ENABLE, + sizeof(struct nss_project_msg_wt_stats_enable), + (void *)nss_project_wt_stats_enable_callback, + (void *)nss_ctx); + npm->msg.wt_stats_enable.enable = enable; + + ret = nss_core_send_cmd(nss_ctx, npm, sizeof(*npm), NSS_NBUF_PAYLOAD_SIZE); + kfree(npm); + return ret; +} + +/* + * nss_project_wt_stats_update() + * Updates stored statistics with the data found in the notify. + */ +static void nss_project_wt_stats_update(struct nss_ctx_instance *nss_ctx, + struct nss_project_msg_wt_stats_notify *stats_notify) +{ + struct nss_worker_thread_stats *wt_stats; + int i; + + if (unlikely(!nss_ctx->wt_stats)) { + nss_warning("%px: Worker thread statistics not yet allocated.\n", nss_ctx); + return; + } + + if (unlikely(stats_notify->threadno >= nss_ctx->worker_thread_count)) { + nss_warning("%px: Invalid WT number %d\n", nss_ctx, stats_notify->threadno); + return; + } + + if (unlikely(stats_notify->stats_written > NSS_PROJECT_IRQS_PER_MESSAGE)) { + nss_warning("%px: Invalid worker thread stats written count %d\n", + nss_ctx, stats_notify->stats_written); + return; + } + + wt_stats = &(nss_ctx->wt_stats[stats_notify->threadno]); + + if (unlikely(!wt_stats->irq_stats)) { + nss_warning("%px: Worker thread statistics not allocated for thread %d\n", + nss_ctx, stats_notify->threadno); + return; + } + + spin_lock_bh(&nss_ctx->nss_top->stats_lock); + for (i = 0; i < stats_notify->stats_written; ++i) { + int irq = stats_notify->stats[i].irq; + if (unlikely(irq >= nss_ctx->irq_count)) { + nss_warning("%px: Invalid IRQ number %d\n", nss_ctx, irq); + continue; + } + + wt_stats->irq_stats[irq] = stats_notify->stats[i]; + } + spin_unlock_bh(&nss_ctx->nss_top->stats_lock); +} + +/* + * nss_project_msg_handler() + * Handles metadata messages on the project interface. + */ +static void nss_project_msg_handler(struct nss_ctx_instance *nss_ctx, + struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_project_msg *npm = (struct nss_project_msg *)ncm; + nss_project_msg_callback_t cb; + + /* + * Sanity checks on message + */ + if (npm->cm.type >= NSS_PROJECT_MSG_MAX) { + nss_warning("%px: message type out of range: %d\n", nss_ctx, npm->cm.type); + return; + } + + if (nss_cmn_get_msg_len(&(npm->cm)) > sizeof(struct nss_project_msg)) { + nss_warning("%px: message length is invalid: %d\n", nss_ctx, nss_cmn_get_msg_len(&(npm->cm))); + return; + } + + switch (npm->cm.type) { + case NSS_PROJECT_MSG_WT_STATS_NOTIFY: + nss_project_wt_stats_update(nss_ctx, &(npm->msg.wt_stats_notify)); + return; + } + + nss_core_log_msg_failures(nss_ctx, ncm); + + if (!ncm->cb) { + return; + } + + cb = (nss_project_msg_callback_t)ncm->cb; + cb((void *)nss_ctx, npm); +} + +/* + * nss_project_wt_stats_handler() + * Sysctl handler for wt_stats. + * + * Uses proc_dointvec to process data. For a write operation, also sends worker + * thread stats enable messages containing the new value to each NSS core. + */ +static int nss_project_wt_stats_handler(struct ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + int ret; + int i; + + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + + /* + * In case of error, stop now. + */ + if (ret) { + return ret; + } + + /* + * No additional behavior necessary for a read operation. + */ + if (!write) { + return ret; + } + + /* + * If a value was written, send a message containing that value to each + * NSS core. + */ + for (i = 0; i < nss_top_main.num_nss; ++i) { + nss_project_wt_stats_send_enable(&(nss_top_main.nss[i]), + nss_project_wt_stats_enable); + } + return ret; + +} + +/* + * Tree of ctl_tables used to put the wt_stats proc node in the correct place in + * the file system. Allows the command $ echo 1 > proc/sys/dev/nss/project/wt_stats + * to enable worker thread statistics (echoing 0 into the same target will disable). + */ +static struct ctl_table nss_project_table[] = { + { + .procname = "wt_stats", + .data = &nss_project_wt_stats_enable, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_project_wt_stats_handler, + }, + { } +}; + +static struct ctl_table nss_project_dir[] = { + { + .procname = "project", + .mode = 0555, + .child = nss_project_table, + }, + { } +}; + +static struct ctl_table nss_project_root_dir[] = { + { + .procname = "nss", + .mode = 0555, + .child = nss_project_dir, + }, + { } +}; + +static struct ctl_table nss_project_root[] = { + { + .procname = "dev", + .mode = 0555, + .child = nss_project_root_dir, + }, + { } +}; + +static struct ctl_table_header *nss_project_header; + +/* + * nss_project_register_sysctl() + * Registers any sysctl handlers for the project. + */ +void nss_project_register_sysctl(void) +{ + nss_project_header = register_sysctl_table(nss_project_root); +} + +/* + * nss_project_unregister_sysctl() + * De-registers any sysctl handlers for the project. + */ +void nss_project_unregister_sysctl(void) +{ + if (nss_project_header) { + unregister_sysctl_table(nss_project_header); + } +} + +/* + * nss_project_register_handler() + * Registers the handler for NSS->HLOS messages + */ +void nss_project_register_handler(struct nss_ctx_instance *nss_ctx) +{ + nss_core_register_handler(nss_ctx, NSS_PROJECT_INTERFACE, nss_project_msg_handler, NULL); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_pvxlan.c b/feeds/ipq807x/qca-nss-drv/src/nss_pvxlan.c new file mode 100644 index 000000000..b06136323 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_pvxlan.c @@ -0,0 +1,446 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + + /* + * nss_pvxlan.c + * NSS PVXLAN driver interface APIs + */ +#include "nss_core.h" +#include "nss_pvxlan.h" +#include "nss_cmn.h" +#include "nss_tx_rx_common.h" +#include "nss_pvxlan_stats.h" +#include "nss_pvxlan_log.h" + +#define NSS_PVXLAN_TX_TIMEOUT 3000 + +/* + * Spinlock for protecting tunnel operations colliding with a tunnel destroy + */ +DEFINE_SPINLOCK(nss_pvxlan_spinlock); + +/* + * Private data structure + */ +static struct nss_pvxlan_pvt { + struct semaphore sem; /* Semaphore structure. */ + struct completion complete; /* Completion structure. */ + int response; /* Response from FW. */ + void *cb; /* Original cb for msgs. */ + void *app_data; /* Original app_data for msgs. */ +} pvxlan_pvt; + +/* + * Per PVxLAN tunnel/interface number instance. + */ +struct nss_pvxlan_handle { + atomic_t refcnt; /* Reference count on the tunnel */ + uint32_t if_num; /* Interface number */ + uint32_t tunnel_status; /* 0=disable, 1=enabled */ + nss_pvxlan_msg_callback_t msg_callback; /* Msg callback */ + void *app_data; /* App data (argument) */ +}; + +/* + * Array of pointer for NSS PvLAN handles. Each handle has per-tunnel + * stats based on the if_num which is an index. + */ +static struct nss_pvxlan_handle *nss_pvxlan_hdl[NSS_MAX_DYNAMIC_INTERFACES]; + +/* + * nss_pvxlan_verify_if_num() + * Verify if_num passed to us. + */ +static bool nss_pvxlan_verify_if_num(uint32_t if_num) +{ + uint32_t type = nss_dynamic_interface_get_type(nss_pvxlan_get_ctx(), if_num); + + return ((type == NSS_DYNAMIC_INTERFACE_TYPE_PVXLAN_HOST_INNER) || + (type == NSS_DYNAMIC_INTERFACE_TYPE_PVXLAN_OUTER)); +} + +/* + * nss_pvxlan_hdl_instance_free() + * Free PVxLAN tunnel handle instance. + */ +static bool nss_pvxlan_hdl_instance_free(struct nss_ctx_instance *nss_ctx, uint32_t if_num) +{ + struct nss_pvxlan_handle *h; + + spin_lock(&nss_pvxlan_spinlock); + h = nss_pvxlan_hdl[if_num - NSS_DYNAMIC_IF_START]; + if (!h) { + spin_unlock(&nss_pvxlan_spinlock); + nss_warning("%px: Instance does not exist: %d", nss_ctx, if_num); + return false; + } + + if (h->if_num != if_num) { + spin_unlock(&nss_pvxlan_spinlock); + nss_warning("%px: Not correct if_num: %d", nss_ctx, if_num); + return false; + } + + nss_pvxlan_hdl[if_num - NSS_DYNAMIC_IF_START] = NULL; + spin_unlock(&nss_pvxlan_spinlock); + kfree(h); + return true; +} + +/* + * nss_pvxlan_hdl_instance_alloc() + * Allocate PVxLAN tunnel instance. + */ +static bool nss_pvxlan_hdl_instance_alloc(struct nss_ctx_instance *nss_ctx, uint32_t if_num, + nss_pvxlan_msg_callback_t notify_cb, void *app_data) +{ + struct nss_pvxlan_handle *h; + + /* + * Allocate a handle + */ + h = kzalloc(sizeof(struct nss_pvxlan_handle), GFP_ATOMIC); + if (!h) { + nss_warning("%px: no memory for allocating PVxLAN handle instance for interface : %d", nss_ctx, if_num); + return false; + } + h->if_num = if_num; + + spin_lock(&nss_pvxlan_spinlock); + if (nss_pvxlan_hdl[if_num - NSS_DYNAMIC_IF_START] != NULL) { + spin_unlock(&nss_pvxlan_spinlock); + kfree(h); + nss_warning("%px: The handle has been taken by another thread :%d", nss_ctx, if_num); + return false; + } + + h->msg_callback = notify_cb; + h->app_data = app_data; + nss_pvxlan_hdl[if_num - NSS_DYNAMIC_IF_START] = h; + spin_unlock(&nss_pvxlan_spinlock); + + return true; +} + +/* + * nss_pvxlan_callback() + * Callback to handle the completion of NSS->HLOS messages. + */ +static void nss_pvxlan_callback(void *app_data, struct nss_pvxlan_msg *nvxm) +{ + nss_pvxlan_msg_callback_t callback = (nss_pvxlan_msg_callback_t)pvxlan_pvt.cb; + void *data = pvxlan_pvt.app_data; + + pvxlan_pvt.response = NSS_TX_SUCCESS; + pvxlan_pvt.cb = NULL; + pvxlan_pvt.app_data = NULL; + + if (nvxm->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("Pvxlan Error response %d\n", nvxm->cm.response); + pvxlan_pvt.response = nvxm->cm.response; + } + + if (callback) { + callback(data, nvxm); + } + complete(&pvxlan_pvt.complete); +} + +/* + * nss_pvxlan_handler() + * Handle NSS -> HLOS messages for PVxLAN. + */ +static void nss_pvxlan_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_pvxlan_msg *nvxm = (struct nss_pvxlan_msg *)ncm; + nss_pvxlan_msg_callback_t cb; + struct nss_pvxlan_handle * h; + + BUG_ON(!nss_pvxlan_verify_if_num(ncm->interface)); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_PVXLAN_MSG_TYPE_MAX) { + nss_warning("%px: received invalid message %d for PVXLAN interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_pvxlan_msg)) { + nss_warning("%px: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Trace messages. + */ + nss_core_log_msg_failures(nss_ctx, ncm); + nss_pvxlan_log_rx_msg(nvxm); + + switch (nvxm->cm.type) { + case NSS_PVXLAN_MSG_TYPE_SYNC_STATS: + nss_pvxlan_stats_sync(nss_ctx, &nvxm->msg.stats, ncm->interface); + break; + } + + /* + * Update the callback and app_data for NOTIFY messages. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + uint32_t if_num = ncm->interface - NSS_DYNAMIC_IF_START; + spin_lock(&nss_pvxlan_spinlock); + h = nss_pvxlan_hdl[if_num]; + if (h) { + ncm->cb = (nss_ptr_t)h->msg_callback; + ncm->app_data = (nss_ptr_t)h->app_data; + } + spin_unlock(&nss_pvxlan_spinlock); + + } + + cb = (nss_pvxlan_msg_callback_t)ncm->cb; + + /* + * Do we have a callback + */ + if (!cb) { + nss_trace("%px: cb is null for interface %d", nss_ctx, ncm->interface); + return; + } + + cb((void *)ncm->app_data, nvxm); +} + +/* + * nss_pvxlan_tx_msg() + * Transmit a PVXLAN message to NSS FW. Don't call this from softirq/interrupts. + */ +nss_tx_status_t nss_pvxlan_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_pvxlan_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + if (!nss_pvxlan_verify_if_num(msg->cm.interface)) { + return NSS_TX_FAILURE_BAD_PARAM; + } + + if (ncm->type >= NSS_PVXLAN_MSG_TYPE_MAX) { + return NSS_TX_FAILURE_BAD_PARAM; + } + + /* + * Trace messages. + */ + nss_pvxlan_log_tx_msg(msg); + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_pvxlan_tx_msg); + +/* + * nss_pvxlan_tx_msg_sync() + * Transmit a pvxlan message to NSS firmware synchronously. + */ +nss_tx_status_t nss_pvxlan_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_pvxlan_msg *nvxm) +{ + nss_tx_status_t status; + int ret; + + down(&pvxlan_pvt.sem); + nvxm->cm.cb = (nss_ptr_t)nss_pvxlan_callback; + nvxm->cm.app_data = (nss_ptr_t)NULL; + + status = nss_pvxlan_tx_msg(nss_ctx, nvxm); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: pvxlan_tx_msg failed\n", nss_ctx); + up(&pvxlan_pvt.sem); + return status; + } + + ret = wait_for_completion_timeout(&pvxlan_pvt.complete, msecs_to_jiffies(NSS_PVXLAN_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: pvxlan tx sync failed due to timeout\n", nss_ctx); + pvxlan_pvt.response = NSS_TX_FAILURE; + } + + status = pvxlan_pvt.response; + up(&pvxlan_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_pvxlan_tx_msg_sync); + +/* + * nss_pvxlan_tx_buf() + * Transmit data buffer (skb) to a NSS interface number + */ +nss_tx_status_t nss_pvxlan_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *buf, uint32_t if_num) +{ + BUG_ON(!nss_pvxlan_verify_if_num(if_num)); + + return nss_core_send_packet(nss_ctx, buf, if_num, H2N_BIT_FLAG_VIRTUAL_BUFFER | H2N_BIT_FLAG_BUFFER_REUSABLE); +} +EXPORT_SYMBOL(nss_pvxlan_tx_buf); + +/* + *********************************** + * Register/Unregister/Miscellaneous APIs + *********************************** + */ + +/* + * nss_pvxlan_unregister() + * Unregister a data packet notifier with NSS FW. + */ +bool nss_pvxlan_unregister(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx; + int32_t i; + + nss_ctx = nss_pvxlan_get_ctx(); + if (!nss_pvxlan_verify_if_num(if_num)) { + nss_warning("%px: data unregister received for invalid interface %d", nss_ctx, if_num); + return false; + } + + spin_lock_bh(&nss_pvxlan_tunnel_stats_debug_lock); + for (i = 0; i < NSS_PVXLAN_MAX_INTERFACES; i++) { + if (nss_pvxlan_tunnel_debug_stats[i].if_num != if_num) { + continue; + } + + memset(&nss_pvxlan_tunnel_debug_stats[i], 0, + sizeof(struct nss_pvxlan_tunnel_stats_debug)); + break; + } + spin_unlock_bh(&nss_pvxlan_tunnel_stats_debug_lock); + + nss_core_unregister_handler(nss_ctx, if_num); + nss_core_unregister_subsys_dp(nss_ctx, if_num); + nss_pvxlan_hdl_instance_free(nss_ctx, if_num); + return true; +} +EXPORT_SYMBOL(nss_pvxlan_unregister); + +/* + * nss_pvxlan_register() + * Registers a data packet notifier with NSS FW. + */ +struct nss_ctx_instance *nss_pvxlan_register(uint32_t if_num, + nss_pvxlan_buf_callback_t data_cb, + nss_pvxlan_msg_callback_t notify_cb, + struct net_device *netdev, + uint32_t features) +{ + struct nss_ctx_instance *nss_ctx; + int core_status; + int32_t i; + + nss_ctx = nss_pvxlan_get_ctx(); + if (!nss_pvxlan_verify_if_num(if_num)) { + nss_warning("%px: data register received for invalid interface %d", nss_ctx, if_num); + return NULL; + } + + core_status = nss_core_register_handler(nss_ctx, if_num, nss_pvxlan_msg_handler, NULL); + if (core_status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: nss core register handler failed for if_num:%d with error :%d", nss_ctx, if_num, core_status); + return NULL; + } + + if (!nss_pvxlan_hdl_instance_alloc(nss_ctx, if_num, notify_cb, (void *)netdev)) { + nss_core_unregister_handler(nss_ctx, if_num); + nss_warning("%px: couldn't allocate handle instance for if_num:%d", nss_ctx, if_num); + return NULL; + } + + spin_lock_bh(&nss_pvxlan_tunnel_stats_debug_lock); + for (i = 0; i < NSS_PVXLAN_MAX_INTERFACES; i++) { + if (nss_pvxlan_tunnel_debug_stats[i].valid) { + continue; + } + + nss_pvxlan_tunnel_debug_stats[i].valid = true; + nss_pvxlan_tunnel_debug_stats[i].if_num = if_num; + nss_pvxlan_tunnel_debug_stats[i].if_index = netdev->ifindex; + break; + } + spin_unlock_bh(&nss_pvxlan_tunnel_stats_debug_lock); + + if (i == NSS_PVXLAN_MAX_INTERFACES) { + nss_warning("%px: No available debug stats instance :%d", nss_ctx, if_num); + nss_pvxlan_hdl_instance_free(nss_ctx, if_num); + nss_core_unregister_handler(nss_ctx, if_num); + return NULL; + } + + nss_core_register_subsys_dp(nss_ctx, if_num, data_cb, NULL, NULL, netdev, features); + return nss_ctx; +} +EXPORT_SYMBOL(nss_pvxlan_register); + +/* + * nss_pvxlan_ifnum_with_core_id() + * Append core id to pvxlan interface num. + */ +int nss_pvxlan_ifnum_with_core_id(int if_num) +{ + struct nss_ctx_instance *nss_ctx = nss_pvxlan_get_ctx(); + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (!nss_is_dynamic_interface(if_num)) { + nss_warning("%px: Invalid if_num: %d, must be a dynamic interface\n", nss_ctx, if_num); + return 0; + } + return NSS_INTERFACE_NUM_APPEND_COREID(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_pvxlan_ifnum_with_core_id); + +/* + * nss_pvxlan_msg_init() + * Initialize pvxlan message. + */ +void nss_pvxlan_msg_init(struct nss_pvxlan_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, + nss_pvxlan_msg_callback_t cb, void *app_data) +{ + nss_cmn_msg_init(&ncm->cm, if_num, type, len, (void*)cb, app_data); +} +EXPORT_SYMBOL(nss_pvxlan_msg_init); + +/* + * nss_pvxlan_get_ctx() + * Return a Pvxlan NSS context. + */ +struct nss_ctx_instance *nss_pvxlan_get_ctx() +{ + struct nss_ctx_instance *nss_ctx; + + nss_ctx = &nss_top_main.nss[nss_top_main.pvxlan_handler_id]; + return nss_ctx; +} +EXPORT_SYMBOL(nss_pvxlan_get_ctx); + +/* + * nss_pvxlan_init() + * Initializes Pvxlan. Gets called from nss_init.c. + */ +void nss_pvxlan_init() +{ + nss_pvxlan_stats_dentry_create(); + sema_init(&pvxlan_pvt.sem, 1); + init_completion(&pvxlan_pvt.complete); + + memset(&nss_pvxlan_hdl, 0, sizeof(nss_pvxlan_hdl)); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_pvxlan_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_pvxlan_log.c new file mode 100644 index 000000000..af516ab54 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_pvxlan_log.c @@ -0,0 +1,244 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_pvxlan_log.c + * NSS PVXLAN logger file. + */ + +#include "nss_core.h" + +/* + * nss_pvxlan_log_message_types_str + * PVXLAN message strings + */ +static int8_t *nss_pvxlan_log_message_types_str[NSS_PVXLAN_MSG_TYPE_MAX] __maybe_unused = { + "PVxLAN Sync Stats", + "PVxLAN Tunnel Configure Rule", + "PVxLAN Tunnel Unconfigure Rule", + "PVxLAN Enable Tunnel", + "PVxLAN Disable Tunnel", + "PVxLAN Add MAC rule", + "PVxLAN Delete MAC rule" +}; + +/* + * nss_pvxlan_log_error_response_types_str + * Strings for error types for PVXLAN messages + */ +static int8_t *nss_pvxlan_log_error_response_types_str[NSS_PVXLAN_ERROR_MAX] __maybe_unused = { + "PVXLAN Invalid L3 Protocool", + "PVXLAN Invalid UDP Protocol", + "PVXLAN Tunnel Disabled", + "PVXLAN Tunnel Enabled", + "PVXLAN Tunnel Not Configured", + "PVXLAN Invalid IP Node", + "PVXLAN Invalid Flag", + "PVXLAN MAC Table Full", + "PVXLAN MAC Exists", + "PVXLAN MAC Does Not Exist" +}; + +/* + * nss_pvxlan_log_rule_msg() + * Log NSS PVXLAN rule message. + */ +static void nss_pvxlan_log_rule_msg(struct nss_pvxlan_rule_msg *npvrm) +{ + nss_trace("%px: NSS PVXLAN Rule message \n" + "Encap Rule Src IP: %px\n" + "Encap Rule Src Port: %d\n" + "Encap Rule Dst Ip: %px\n" + "Encap Rule Dst Port: %d\n" + "RPS: %d\n" + "Flags: %x\n" + "Tunnel ID: %d\n", + npvrm, + &npvrm->encap.src.ip, + npvrm->encap.src_port, + &npvrm->encap.dest.ip, + npvrm->encap.dest_port, + npvrm->rps, npvrm->flags, + npvrm->tunnel_id); +} + +/* + * nss_pvxlan_mac_rule_msg() + * Log NSS PVxLAN MAC rule message. + */ +static void nss_pvxlan_log_mac_msg(struct nss_pvxlan_mac_msg *npvcm) +{ + nss_trace("%px: NSS PVXLAN MAC message \n" + "PVxLAN Mac Addr: %x : %x : %x" + "PVxLAN Flags: %u\n" + "PVxLAN VNet ID: %u\n" + "PVxLAN Tunnel ID: %d\n" + "PVxLAN Policy ID: %d", + npvcm, + npvcm->mac_addr[0], npvcm->mac_addr[1], + npvcm->mac_addr[2], npvcm->flags, + npvcm->vnet_id, npvcm->tunnel_id, + npvcm->policy_id); +} + +/* + * nss_pvxlan_log_rule_cfg_msg() + * Log NSS PVxLAN rule configure message. + */ +static void nss_pvxlan_log_rule_cfg_msg(struct nss_pvxlan_msg *npvm) +{ + struct nss_pvxlan_rule_msg *npvrm __maybe_unused = &npvm->msg.rule_cfg; + nss_pvxlan_log_rule_msg(npvrm); +} + +/* + * nss_pvxlan_log_rule_uncfg_msg() + * Log NSS PVxLAN rule unconfigure message. + */ +static void nss_pvxlan_log_rule_uncfg_msg(struct nss_pvxlan_msg *npvm) +{ + struct nss_pvxlan_rule_msg *npvrm __maybe_unused = &npvm->msg.rule_uncfg; + nss_pvxlan_log_rule_msg(npvrm); +} + +/* + * nss_pvxlan_log_enable_msg() + * Log NSS PVxLAN rule enable message. + */ +static void nss_pvxlan_log_enable_msg(struct nss_pvxlan_msg *npvm) +{ + struct nss_pvxlan_tunnel_state_msg *npvrm __maybe_unused = &npvm->msg.enable; + nss_trace("%px: NSS PVXLAN Tunnel state message: Enable \n", npvrm); +} + +/* + * nss_pvxlan_log_disable_msg() + * Log NSS PVxLAN rule disable message. + */ +static void nss_pvxlan_log_disable_msg(struct nss_pvxlan_msg *npvm) +{ + nss_trace("%px: NSS PVXLAN Tunnel state message: Disable \n", npvm); +} + +/* + * nss_pvxlan_log_mac_add_msg() + * Log NSS PVXLAN mac rule add message. + */ +static void nss_pvxlan_log_mac_add_msg(struct nss_pvxlan_msg *npvm) +{ + struct nss_pvxlan_mac_msg *npvcm __maybe_unused = &npvm->msg.mac_add; + nss_pvxlan_log_mac_msg(npvcm); +} + +/* + * nss_pvxlan_log_mac_del_msg() + * Log NSS PVXLAN mac rule del message. + */ +static void nss_pvxlan_log_mac_del_msg(struct nss_pvxlan_msg *npvm) +{ + struct nss_pvxlan_mac_msg *npvcm __maybe_unused = &npvm->msg.mac_del; + nss_pvxlan_log_mac_msg(npvcm); +} + +/* + * nss_pvxlan_log_verbose() + * Log message contents. + */ +static void nss_pvxlan_log_verbose(struct nss_pvxlan_msg *npvm) +{ + switch (npvm->cm.type) { + case NSS_PVXLAN_MSG_TYPE_TUNNEL_CREATE_RULE: + nss_pvxlan_log_rule_cfg_msg(npvm); + break; + + case NSS_PVXLAN_MSG_TYPE_TUNNEL_DESTROY_RULE: + nss_pvxlan_log_rule_uncfg_msg(npvm); + break; + + case NSS_PVXLAN_MSG_TYPE_TUNNEL_ENABLE: + nss_pvxlan_log_enable_msg(npvm); + break; + + case NSS_PVXLAN_MSG_TYPE_TUNNEL_DISABLE: + nss_pvxlan_log_disable_msg(npvm); + break; + + case NSS_PVXLAN_MSG_TYPE_MAC_ADD: + nss_pvxlan_log_mac_add_msg(npvm); + break; + + case NSS_PVXLAN_MSG_TYPE_MAC_DEL: + nss_pvxlan_log_mac_del_msg(npvm); + break; + + case NSS_PVXLAN_MSG_TYPE_SYNC_STATS: + break; + + default: + nss_trace("%px: Invalid message type\n", npvm); + break; + } +} + +/* + * nss_pvxlan_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_pvxlan_log_tx_msg(struct nss_pvxlan_msg *npvm) +{ + if (npvm->cm.type >= NSS_PVXLAN_MSG_TYPE_MAX) { + nss_warning("%px: Invalid message type\n", npvm); + return; + } + + nss_info("%px: type[%d]:%s\n", npvm, npvm->cm.type, nss_pvxlan_log_message_types_str[npvm->cm.type]); + nss_pvxlan_log_verbose(npvm); +} + +/* + * nss_pvxlan_log_rx_msg() + * Log messages received from FW. + */ +void nss_pvxlan_log_rx_msg(struct nss_pvxlan_msg *npvm) +{ + if (npvm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", npvm); + return; + } + + if (npvm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (npvm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", npvm, npvm->cm.type, + nss_pvxlan_log_message_types_str[npvm->cm.type], + npvm->cm.response, nss_cmn_response_str[npvm->cm.response]); + goto verbose; + } + + if (npvm->cm.error >= NSS_PVXLAN_ERROR_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + npvm, npvm->cm.type, nss_pvxlan_log_message_types_str[npvm->cm.type], + npvm->cm.response, nss_cmn_response_str[npvm->cm.response], + npvm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + npvm, npvm->cm.type, nss_pvxlan_log_message_types_str[npvm->cm.type], + npvm->cm.response, nss_cmn_response_str[npvm->cm.response], + npvm->cm.error, nss_pvxlan_log_error_response_types_str[npvm->cm.error]); + +verbose: + nss_pvxlan_log_verbose(npvm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_pvxlan_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_pvxlan_log.h new file mode 100644 index 000000000..cdc0dd772 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_pvxlan_log.h @@ -0,0 +1,37 @@ +/* + ****************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_PVXLAN_LOG_H__ +#define __NSS_PVXLAN_LOG_H__ + +/* + * nss_pvxlan_log.h + * NSS PVXLAN Log Header File. + */ + +/* + * nss_pvxlan_log_tx_msg + * Logs a PVxLAN message that is sent to the NSS firmware. + */ +void nss_pvxlan_log_tx_msg(struct nss_pvxlan_msg *ncm); + +/* + * nss_pvxlan_log_rx_msg + * Logs a PVxLAN message that is received from the NSS firmware. + */ +void nss_pvxlan_log_rx_msg(struct nss_pvxlan_msg *ncm); + +#endif /* __NSS_PVXLAN_LOG_H__ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_pvxlan_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_pvxlan_stats.c new file mode 100644 index 000000000..59f861604 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_pvxlan_stats.c @@ -0,0 +1,213 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_pvxlan_stats.h" + +DEFINE_SPINLOCK(nss_pvxlan_tunnel_stats_debug_lock); +struct nss_pvxlan_tunnel_stats_debug nss_pvxlan_tunnel_debug_stats[NSS_PVXLAN_MAX_INTERFACES]; + +/* + * nss_pvxlan_tunnel_stats_debug_str + * PVxLAN statistics strings for nss tunnel stats + */ +static int8_t *nss_pvxlan_tunnel_stats_debug_str[NSS_PVXLAN_MAX_INTERFACES] = { + "rx_pkts", + "rx_bytes", + "tx_pkts", + "tx_bytes", + "rx_queue_0_dropped", + "rx_queue_1_dropped", + "rx_queue_2_dropped", + "rx_queue_3_dropped", + "MAC DB look up failed", + "UDP ENCAP look up failed", + "dropped packet malformed", + "dropped next node queue is full", + "dropped headroom insufficient", + "dropped version mismatch", + "dropped zero sized packet", + "dropped pbuf alloc failed", + "dropped linearization failed" +}; + +/* + * nss_pvxlan_tunnel_stats_debug_get() + * Get PVxLAN Tunnel statitics. + */ +static void nss_pvxlan_tunnel_stats_debug_get(struct nss_pvxlan_tunnel_stats_debug *stats) +{ + uint32_t i; + + if (!stats) { + nss_warning("No memory to copy pvxlan tunnel stats"); + return; + } + + spin_lock_bh(&nss_pvxlan_tunnel_stats_debug_lock); + for (i = 0; i < NSS_PVXLAN_MAX_INTERFACES; i++) { + if (nss_pvxlan_tunnel_debug_stats[i].valid) { + memcpy(stats, &nss_pvxlan_tunnel_debug_stats[i], + sizeof(struct nss_pvxlan_tunnel_stats_debug)); + stats++; + } + } + spin_unlock_bh(&nss_pvxlan_tunnel_stats_debug_lock); +} + +/* + * nss_pvxlan_stats_read() + * Read PVxLAN Tunnel statistics + */ +static ssize_t nss_pvxlan_stats_read(struct file *fp, char __user *ubuf, + size_t sz, loff_t *ppos) +{ + uint32_t max_output_lines = 2 + (NSS_PVXLAN_MAX_INTERFACES + * (NSS_PVXLAN_TUNNEL_STATS_MAX + 2)) + 2; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + struct net_device *dev; + uint32_t id, i; + struct nss_pvxlan_tunnel_stats_debug *pvxlan_tunnel_stats = NULL; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + pvxlan_tunnel_stats = kzalloc((sizeof(struct nss_pvxlan_tunnel_stats_debug) + * NSS_PVXLAN_MAX_INTERFACES), GFP_KERNEL); + if (unlikely(!pvxlan_tunnel_stats)) { + nss_warning("Could not allocate memory for populating PVxLAN stats"); + kfree(lbuf); + return 0; + } + + /* + * Get all stats + */ + nss_pvxlan_tunnel_stats_debug_get(pvxlan_tunnel_stats); + + /* + * Tunnel stats + */ + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "\n PVxLAN Tunnel stats start:\n\n"); + + for (id = 0; id < NSS_PVXLAN_MAX_INTERFACES; id++) { + if (!pvxlan_tunnel_stats[id].valid) + break; + + dev = dev_get_by_index(&init_net, pvxlan_tunnel_stats[id].if_index); + if (likely(dev)) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "%d. nss interface id=%d, netdevice=%s\n", + id, pvxlan_tunnel_stats[id].if_num, + dev->name); + dev_put(dev); + } else { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "%d. nss interface id=%d\n", id, + pvxlan_tunnel_stats[id].if_num); + } + + for (i = 0; i < NSS_PVXLAN_TUNNEL_STATS_MAX; i++) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "\t%s = %llu\n", + nss_pvxlan_tunnel_stats_debug_str[i], + pvxlan_tunnel_stats[id].stats[i]); + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n"); + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "\n PVxLAN Tunnel stats end\n"); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr); + + kfree(pvxlan_tunnel_stats); + kfree(lbuf); + return bytes_read; +} + +/* + * nss_pvxlan_stats_sync() + * Sync function for pvxlan statistics + */ +void nss_pvxlan_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_pvxlan_stats_msg *stats_msg, uint32_t if_num) +{ + uint32_t i; + struct nss_pvxlan_tunnel_stats_debug *s = NULL; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + spin_lock_bh(&nss_pvxlan_tunnel_stats_debug_lock); + for (i = 0; i < NSS_PVXLAN_MAX_INTERFACES; i++) { + if (nss_pvxlan_tunnel_debug_stats[i].if_num == if_num) { + s = &nss_pvxlan_tunnel_debug_stats[i]; + break; + } + } + + if (!s) { + spin_unlock_bh(&nss_pvxlan_tunnel_stats_debug_lock); + nss_warning("%px: Tunnel not found: %u", nss_ctx, if_num); + return; + } + + s->stats[NSS_PVXLAN_TUNNEL_STATS_RX_PKTS] += stats_msg->node_stats.rx_packets; + s->stats[NSS_PVXLAN_TUNNEL_STATS_RX_BYTES] += stats_msg->node_stats.rx_bytes; + s->stats[NSS_PVXLAN_TUNNEL_STATS_TX_PKTS] += stats_msg->node_stats.tx_packets; + s->stats[NSS_PVXLAN_TUNNEL_STATS_TX_BYTES] += stats_msg->node_stats.tx_bytes; + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + s->stats[NSS_PVXLAN_TUNNEL_STATS_RX_QUEUE_0_DROPPED + i] += stats_msg->node_stats.rx_dropped[i]; + } + s->stats[NSS_PVXLAN_TUNNEL_STATS_MAC_DB_LOOKUP_FAILED] += + stats_msg->mac_db_lookup_failed; + s->stats[NSS_PVXLAN_TUNNEL_STATS_UDP_ENCAP_LOOKUP_FAILED] += + stats_msg->udp_encap_lookup_failed; + s->stats[NSS_PVXLAN_TUNNEL_STATS_DROP_MALFORMED] += + stats_msg->dropped_malformed; + s->stats[NSS_PVXLAN_TUNNEL_STATS_DROP_NEXT_NODE_QUEUE_FULL] += + stats_msg->dropped_next_node_queue_full; + s->stats[NSS_PVXLAN_TUNNEL_STATS_DROP_HEADROOM_INSUFFICIENT] += + stats_msg->dropped_hroom; + s->stats[NSS_PVXLAN_TUNNEL_STATS_DROP_VERSION_MISMATCH] += + stats_msg->dropped_ver_mis; + s->stats[NSS_PVXLAN_TUNNEL_STATS_DROP_ZERO_SIZED_PACKET] += + stats_msg->dropped_zero_sized_packet; + s->stats[NSS_PVXLAN_TUNNEL_STATS_DROP_PBUF_ALLOC_FAILED] += + stats_msg->dropped_pbuf_alloc_failed; + s->stats[NSS_PVXLAN_TUNNEL_STATS_DROP_LINEAR_FAILED] += + stats_msg->dropped_linear_failed; + spin_unlock_bh(&nss_pvxlan_tunnel_stats_debug_lock); +} + +/* + * nss_pvxlan_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(pvxlan) + +/* + * nss_pvxlan_stats_dentry_create() + * Create gre tunnel statistics debug entry. + */ +void nss_pvxlan_stats_dentry_create(void) +{ + nss_stats_create_dentry("pvxlan", &nss_pvxlan_stats_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_pvxlan_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_pvxlan_stats.h new file mode 100644 index 000000000..874bf785e --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_pvxlan_stats.h @@ -0,0 +1,66 @@ +/* + ****************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_PVXLAN_STATS_H +#define __NSS_PVXLAN_STATS_H + +/* + * pvxlan statistic counters + */ +enum nss_pvxlan_tunnel_stats { + NSS_PVXLAN_TUNNEL_STATS_RX_PKTS, + NSS_PVXLAN_TUNNEL_STATS_RX_BYTES, + NSS_PVXLAN_TUNNEL_STATS_TX_PKTS, + NSS_PVXLAN_TUNNEL_STATS_TX_BYTES, + NSS_PVXLAN_TUNNEL_STATS_RX_QUEUE_0_DROPPED, + NSS_PVXLAN_TUNNEL_STATS_RX_QUEUE_1_DROPPED, + NSS_PVXLAN_TUNNEL_STATS_RX_QUEUE_2_DROPPED, + NSS_PVXLAN_TUNNEL_STATS_RX_QUEUE_3_DROPPED, + NSS_PVXLAN_TUNNEL_STATS_MAC_DB_LOOKUP_FAILED, + NSS_PVXLAN_TUNNEL_STATS_UDP_ENCAP_LOOKUP_FAILED, + NSS_PVXLAN_TUNNEL_STATS_DROP_MALFORMED, + NSS_PVXLAN_TUNNEL_STATS_DROP_NEXT_NODE_QUEUE_FULL, + NSS_PVXLAN_TUNNEL_STATS_DROP_HEADROOM_INSUFFICIENT, + NSS_PVXLAN_TUNNEL_STATS_DROP_VERSION_MISMATCH, + NSS_PVXLAN_TUNNEL_STATS_DROP_ZERO_SIZED_PACKET, + NSS_PVXLAN_TUNNEL_STATS_DROP_PBUF_ALLOC_FAILED, + NSS_PVXLAN_TUNNEL_STATS_DROP_LINEAR_FAILED, + NSS_PVXLAN_TUNNEL_STATS_MAX, +}; + +/* + * PVxLAN session debug statistics + */ +struct nss_pvxlan_tunnel_stats_debug { + uint64_t stats[NSS_PVXLAN_TUNNEL_STATS_MAX]; + int32_t if_index; + uint32_t if_num; /* nss interface number */ + bool valid; +}; + +/* + * Data structures to store PVxLAN nss debug stats + */ +extern spinlock_t nss_pvxlan_tunnel_stats_debug_lock; +extern struct nss_pvxlan_tunnel_stats_debug nss_pvxlan_tunnel_debug_stats[NSS_PVXLAN_MAX_INTERFACES]; + +/* + * PVxLAN statistics APIs + */ +extern void nss_pvxlan_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_pvxlan_stats_msg *stats_msg, uint32_t if_num); +extern void nss_pvxlan_stats_dentry_create(void); + +#endif /* __NSS_PVXLAN_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_qrfs.c b/feeds/ipq807x/qca-nss-drv/src/nss_qrfs.c new file mode 100644 index 000000000..cfbff597e --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_qrfs.c @@ -0,0 +1,472 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_qrfs_stats.h" +#include "nss_qrfs_log.h" + +/* + * Notify data structure + */ +struct nss_qrfs_notify_data { + nss_qrfs_msg_callback_t qrfs_callback; + void *app_data; +}; + +static struct nss_qrfs_notify_data nss_qrfs_notify[NSS_CORE_MAX]; + +/* + * nss_qrfs_verify_if_num() + * Verify if_num passed to us. + */ +static bool nss_qrfs_verify_if_num(uint32_t if_num) +{ + return if_num == NSS_QRFS_INTERFACE; +} + +/* + * nss_qrfs_msg_handler() + * Handle NSS -> HLOS messages for QRFS + */ +static void nss_qrfs_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, void *app_data) +{ + struct nss_qrfs_msg *nqm = (struct nss_qrfs_msg *)ncm; + nss_qrfs_msg_callback_t cb; + + /* + * Trace messages. + */ + nss_qrfs_log_rx_msg(nqm); + + if (!nss_qrfs_verify_if_num(ncm->interface)) { + nss_warning("%px: invalid interface %d for QRFS\n", nss_ctx, ncm->interface); + return; + } + + /* + * Is this a valid request/response? + */ + if (ncm->type >= NSS_QRFS_MSG_MAX) { + nss_warning("%px: invalid message %d for QRFS\n", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_qrfs_msg)) { + nss_warning("%px: message length is greater than required: %d\n", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + switch (ncm->type) { + case NSS_QRFS_MSG_STATS_SYNC: + /* + * Update QRFS statistics. + */ + nss_qrfs_stats_sync(nss_ctx, &nqm->msg.stats_sync); + break; + } + + /* + * Update the callback and app_data for NOTIFY messages + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_qrfs_notify[nss_ctx->id].qrfs_callback; + ncm->app_data = (nss_ptr_t)nss_qrfs_notify[nss_ctx->id].app_data; + } + + /* + * Do we have a callback? + */ + if (!ncm->cb) { + return; + } + + /* + * callback + */ + cb = (nss_qrfs_msg_callback_t)ncm->cb; + cb((void *)ncm->app_data, nqm); +} + +/* + * nss_qrfs_get_ctx() + */ +static struct nss_ctx_instance *nss_qrfs_get_ctx(int core_id) +{ + return &nss_top_main.nss[core_id]; +} + +/* + * nss_qrfs_get_flow_keys() + * Get 5 tuple information from flow keys and set in flow rule message. + */ +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 18, 21)) +static bool nss_qrfs_get_flow_keys(struct nss_ctx_instance *nss_ctx, struct sk_buff *skb, + struct nss_qrfs_flow_rule_msg *nqfrm) +{ + struct flow_keys keys; + uint16_t protocol = skb->protocol; + bool res; + struct ipv6hdr *ip6hdr; + + res = skb_flow_dissect(skb, &keys); + if (!res) { + nss_warning("%px: failed to get flow keys\n", nss_ctx); + return res; + } + + nqfrm->protocol = keys.ip_proto; + nqfrm->src_port = keys.port16[0]; + nqfrm->dst_port = keys.port16[1]; + + if (protocol == htons(ETH_P_IP)) { + nqfrm->ip_version = 4; + nqfrm->src_addr[0] = keys.src; + nqfrm->dst_addr[0] = keys.dst; + return true; + } + + nqfrm->ip_version = 6; + ip6hdr = (struct ipv6hdr *)skb_network_header(skb); + if (!ip6hdr) { + nss_warning("%px: failed to get IPv6 address\n", nss_ctx); + return false; + } + + memcpy(nqfrm->src_addr, &ip6hdr->saddr, sizeof(struct in6_addr)); + memcpy(nqfrm->dst_addr, &ip6hdr->daddr, sizeof(struct in6_addr)); + + return true; +} +#else +static bool nss_qrfs_get_flow_keys(struct nss_ctx_instance *nss_ctx, struct sk_buff *skb, + struct nss_qrfs_flow_rule_msg *nqfrm) +{ + struct flow_keys keys; + bool res; + + res = skb_flow_dissect_flow_keys(skb, &keys, 0); + if (!res) { + nss_warning("%px: failed to get flow keys\n", nss_ctx); + return res; + } + + nqfrm->protocol = (uint16_t)keys.basic.ip_proto; + nqfrm->src_port = keys.ports.src; + nqfrm->dst_port = keys.ports.dst; + + if (keys.basic.n_proto == htons(ETH_P_IP)) { + nqfrm->ip_version = 4; + nqfrm->src_addr[0] = keys.addrs.v4addrs.src; + nqfrm->dst_addr[0] = keys.addrs.v4addrs.dst; + return true; + } + + nqfrm->ip_version = 6; + memcpy(nqfrm->src_addr, &keys.addrs.v6addrs.src, sizeof(struct in6_addr)); + memcpy(nqfrm->dst_addr, &keys.addrs.v6addrs.dst, sizeof(struct in6_addr)); + + return true; +} +#endif + +/* + * nss_qrfs_flow_add_msg_callback() + * Callback function for receiving flow add response messages. + */ +static void nss_qrfs_flow_add_msg_callback(void *app_data, struct nss_qrfs_msg *nqm) +{ + struct nss_ctx_instance *nss_ctx __maybe_unused = (struct nss_ctx_instance *)app_data; + struct nss_qrfs_flow_rule_msg *nqfrm; + + if (nqm->cm.type != NSS_QRFS_MSG_FLOW_ADD) { + nss_warning("%px: invalid flow response message %d\n", nss_ctx, nqm->cm.type); + return; + } + + nqfrm = &nqm->msg.flow_add; + + if ((nqfrm->ip_version != 4) && (nqfrm->ip_version != 6)) { + nss_warning("%px: invalid IP version %d\n", nss_ctx, nqfrm->ip_version); + return; + } + + if (nqm->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("%px: flow add configuration error: %d for NSS core %d\n", + nss_ctx, nqm->cm.error, nss_ctx->id); + } +} + +/* + * nss_qrfs_flow_delete_msg_callback() + * Callback function for receiving flow delete response messages. + */ +static void nss_qrfs_flow_delete_msg_callback(void *app_data, struct nss_qrfs_msg *nqm) +{ + struct nss_ctx_instance *nss_ctx __maybe_unused = (struct nss_ctx_instance *)app_data; + struct nss_qrfs_flow_rule_msg *nqfrm; + + if (nqm->cm.type != NSS_QRFS_MSG_FLOW_DELETE) { + nss_warning("%px: invalid flow response message %d\n", nss_ctx, nqm->cm.type); + return; + } + + nqfrm = &nqm->msg.flow_delete; + + if ((nqfrm->ip_version != 4) && (nqfrm->ip_version != 6)) { + nss_warning("%px: invalid IP version %d\n", nss_ctx, nqfrm->ip_version); + return; + } + + if (nqm->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("%px: flow delete configuration error: %d for NSS core %d\n", + nss_ctx, nqm->cm.error, nss_ctx->id); + } +} + +/* + * nss_qrfs_msg_init() + * Initialize the common header of QRFS message + */ +static void nss_qrfs_msg_init(struct nss_qrfs_msg *nqm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data) +{ + nss_cmn_msg_init(&nqm->cm, if_num, type, len, cb, app_data); +} + +/* + * nss_qrfs_tx_msg() + * Transmit a QRFS message to NSS firmware + */ +static nss_tx_status_t nss_qrfs_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_qrfs_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Trace messages. + */ + nss_qrfs_log_tx_msg(msg); + + /* + * Sanity check the message + */ + if (!nss_qrfs_verify_if_num(ncm->interface)) { + nss_warning("%px: interface is not QRFS interface: %d\n", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type >= NSS_QRFS_MSG_MAX) { + nss_warning("%px: message type is out of range: %d\n", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} + +/* + * nss_qrfs_add_flow_rule() + * Set a QRFS flow rule add message and transmit the message to NSS core. + */ +static nss_tx_status_t nss_qrfs_add_flow_rule(struct nss_ctx_instance *nss_ctx, uint32_t if_num, + struct sk_buff *skb, uint32_t cpu, bool need_cb) +{ + struct nss_qrfs_msg nqm; + struct nss_qrfs_flow_rule_msg *nqfrm; + nss_tx_status_t status; + nss_qrfs_msg_callback_t cb = NULL; + void *app_data = NULL; + bool res; + + memset(&nqm, 0, sizeof(struct nss_qrfs_msg)); + + if (need_cb) { + cb = nss_qrfs_flow_add_msg_callback; + app_data = (void *)nss_ctx; + } + + /* + * Initialize common header of QRFS flow rule add message. + */ + nss_qrfs_msg_init(&nqm, NSS_QRFS_INTERFACE, NSS_QRFS_MSG_FLOW_ADD, + sizeof(struct nss_qrfs_flow_rule_msg), cb, app_data); + + /* + * Set flow rule of QRFS flow rule add message + */ + nqfrm = &nqm.msg.flow_add; + res = nss_qrfs_get_flow_keys(nss_ctx, skb, nqfrm); + if (!res) { + return NSS_TX_FAILURE; + } + + nqfrm->cpu = (uint16_t)cpu; + nqfrm->if_num = if_num; + + /* + * Send QRFS flow rule add message to NSS core + */ + status = nss_qrfs_tx_msg(nss_ctx, &nqm); + if (status == NSS_TX_SUCCESS) { + return status; + } + + return NSS_TX_FAILURE; +} + +/* + * nss_qrfs_delete_flow_rule() + * Set a QRFS delete flow rule message and transmit the message to all NSS core. + */ +static nss_tx_status_t nss_qrfs_delete_flow_rule(struct nss_ctx_instance *nss_ctx, uint32_t if_num, + struct sk_buff *skb, uint32_t cpu, bool need_cb) +{ + struct nss_qrfs_msg nqm; + struct nss_qrfs_flow_rule_msg *nqfrm; + nss_tx_status_t status; + nss_qrfs_msg_callback_t cb = NULL; + void *app_data = NULL; + bool res; + + memset(&nqm, 0, sizeof(struct nss_qrfs_msg)); + + if (need_cb) { + cb = nss_qrfs_flow_delete_msg_callback; + app_data = (void *)nss_ctx; + } + + /* + * Initialize common header of QRFS flow rule delete message. + */ + nss_qrfs_msg_init(&nqm, NSS_QRFS_INTERFACE, NSS_QRFS_MSG_FLOW_DELETE, + sizeof(struct nss_qrfs_flow_rule_msg), cb, app_data); + + /* + * Set flow rule of QRFS flow rule delete message + */ + nqfrm = &nqm.msg.flow_delete; + res = nss_qrfs_get_flow_keys(nss_ctx, skb, nqfrm); + if (!res) { + return NSS_TX_FAILURE; + } + + nqfrm->cpu = (uint16_t)cpu; + nqfrm->if_num = if_num; + + /* + * Send QRFS flow rule delete message to NSS core + */ + status = nss_qrfs_tx_msg(nss_ctx, &nqm); + if (status == NSS_TX_SUCCESS) { + return status; + } + + return NSS_TX_FAILURE; +} + +/* + * nss_qrfs_set_flow_rule() + * Set a QRFS flow rule message and transmit the message to all NSS cores. + */ +nss_tx_status_t nss_qrfs_set_flow_rule(struct sk_buff *skb, uint32_t cpu, uint32_t action) +{ + struct nss_ctx_instance *nss_ctx; + nss_tx_status_t status; + int i; + + for (i = 0; i < NSS_CORE_MAX; i++) { + nss_ctx = nss_qrfs_get_ctx(i); + + /* + * Set QRFS flow rule message and transmit the message to NSS core. + * + * TODO: Remove if_num parameter from add_flow_rule() and + * delete_flow_rule(), since it is unused in firmware. + */ + if (action == NSS_QRFS_MSG_FLOW_ADD) { + status = nss_qrfs_add_flow_rule(nss_ctx, 0, skb, cpu, true); + } else { + status = nss_qrfs_delete_flow_rule(nss_ctx, 0, skb, cpu, true); + } + + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: failed to send flow rule to NSS core %d\n", nss_ctx, i); + return NSS_TX_FAILURE; + } + } + + return NSS_TX_SUCCESS; +} +EXPORT_SYMBOL(nss_qrfs_set_flow_rule); + +/* + * nss_qrfs_register_handler() + */ +void nss_qrfs_register_handler(struct nss_ctx_instance *nss_ctx) +{ + nss_core_register_handler(nss_ctx, NSS_QRFS_INTERFACE, nss_qrfs_msg_handler, NULL); + + if (nss_ctx->id == NSS_CORE_0) { + nss_qrfs_stats_dentry_create(); + } +} +EXPORT_SYMBOL(nss_qrfs_register_handler); + +/* + * nss_qrfs_notify_register() + * Register to receive QRFS notify messages. + */ +struct nss_ctx_instance *nss_qrfs_notify_register(int core, nss_qrfs_msg_callback_t cb, void *app_data) +{ + if (core >= NSS_CORE_MAX) { + nss_warning("Input core number %d is wrong\n", core); + return NULL; + } + + nss_qrfs_notify[core].qrfs_callback = cb; + nss_qrfs_notify[core].app_data = app_data; + + return (struct nss_ctx_instance *)&nss_top_main.nss[core]; +} + +/* + * nss_qrfs_notify_unregister() + * Unregister to receive QRFS notify messages. + */ +void nss_qrfs_notify_unregister(int core) +{ + if (core >= NSS_CORE_MAX) { + nss_warning("Input core number %d is wrong\n", core); + return; + } + + nss_qrfs_notify[core].qrfs_callback = NULL; + nss_qrfs_notify[core].app_data = NULL; +} + +/* + * nss_qrfs_init() + */ +void nss_qrfs_init(void) +{ + int core; + + for (core = 0; core < NSS_CORE_MAX; core++) { + nss_qrfs_notify_register(core, NULL, NULL); + } +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_qrfs_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_qrfs_log.c new file mode 100644 index 000000000..d481e2866 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_qrfs_log.c @@ -0,0 +1,174 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_qrfs_log.c + * NSS QRFS logger file. + */ + +#include "nss_core.h" +#define NSS_QRFS_LOG_IPV4 4 +#define NSS_QRFS_LOG_IPV6 6 + +/* + * nss_qrfs_log_message_types_str + * QRFS message strings + */ +static int8_t *nss_qrfs_log_message_types_str[NSS_QRFS_MSG_MAX] __maybe_unused = { + "QRFS Flow Add Message", + "QRFS Flow Delete Message", + "QRFS MAC Add Message", + "QRFS MAC Delete Message", + "QRFS Stats Sync", +}; + +/* + * nss_qrfs_log_error_response_types_str + * Strings for error types for QRFS messages + */ +static int8_t *nss_qrfs_log_error_response_types_str[NSS_QRFS_ERROR_MAX] __maybe_unused = { + "QRFS Invalid Message Type", + "QRFS Invalid Message Size", + "QRFS Invalid IP Version", + "QRFS V4 Flow Table Full", + "QRFS V6 Flow Table Full", + "QRFS MAC Table Full", +}; + +/* + * nss_qrfs_log_flow_rule_msg() + * Log NSS QRFS Flow Rule Message. + */ +static void nss_qrfs_log_flow_rule_msg(struct nss_qrfs_flow_rule_msg *nqfm) +{ + nss_trace("%px: NSS QRFS Flow Rule Message:\n" + "QRFS Source Port: %d\n" + "QRFS Destination Port: %d\n" + "QRFS IP Version: %d\n" + "QRFS Protcol: %d\n" + "QRFS CPU ID: %d\n" + "QRFS Physical Interface Number: %d\n", + nqfm, nqfm->src_port, + nqfm->dst_port, nqfm->ip_version, + nqfm->protocol, nqfm->cpu, + nqfm->if_num); + + /* + * Continuation of log. Different identifiers based on ip_version + */ + if (nqfm->ip_version == NSS_QRFS_LOG_IPV6) { + nss_trace("QRFS Source Address: %pI6\n" + "QRFS Destination Address: %pI6\n", + nqfm->src_addr, nqfm->dst_addr); + } else if (nqfm->ip_version == NSS_QRFS_LOG_IPV4) { + nss_trace("QRFS Source Address: %pI4\n" + "QRFS Destination Address: %pI4\n", + nqfm->src_addr, nqfm->dst_addr); + } +} + +/* + * nss_qrfs_log_mac_rule_msg() + * Log NSS QRFS MAC Rule Message. + */ +static void nss_qrfs_log_mac_rule_msg(struct nss_qrfs_mac_rule_msg *nqmm) +{ + nss_trace("%px: NSS QRFS MAC Rule Message:\n" + "QRFS MAC: %pM\n" + "QRFS CPU ID: %d\n" + "QRFS Physical Interface Number: %d\n", + nqmm, nqmm->mac, + nqmm->cpu, nqmm->if_num); +} + +/* + * nss_qrfs_log_verbose() + * Log message contents. + */ +static void nss_qrfs_log_verbose(struct nss_qrfs_msg *nqm) +{ + switch (nqm->cm.type) { + case NSS_QRFS_MSG_FLOW_ADD: + case NSS_QRFS_MSG_FLOW_DELETE: + nss_qrfs_log_flow_rule_msg(&nqm->msg.flow_add); + break; + + case NSS_QRFS_MSG_MAC_ADD: + case NSS_QRFS_MSG_MAC_DELETE: + nss_qrfs_log_mac_rule_msg(&nqm->msg.mac_add); + break; + + case NSS_QRFS_MSG_STATS_SYNC: + /* + * No log for valid stats message. + */ + break; + + default: + nss_warning("%px: Invalid message type\n", nqm); + break; + } +} + +/* + * nss_qrfs_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_qrfs_log_tx_msg(struct nss_qrfs_msg *nqm) +{ + if (nqm->cm.type >= NSS_QRFS_MSG_MAX) { + nss_warning("%px: Invalid message type\n", nqm); + return; + } + + nss_info("%px: type[%d]:%s\n", nqm, nqm->cm.type, nss_qrfs_log_message_types_str[nqm->cm.type]); + nss_qrfs_log_verbose(nqm); +} + +/* + * nss_qrfs_log_rx_msg() + * Log messages received from FW. + */ +void nss_qrfs_log_rx_msg(struct nss_qrfs_msg *nqm) +{ + if (nqm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", nqm); + return; + } + + if (nqm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (nqm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", nqm, nqm->cm.type, + nss_qrfs_log_message_types_str[nqm->cm.type], + nqm->cm.response, nss_cmn_response_str[nqm->cm.response]); + goto verbose; + } + + if (nqm->cm.error >= NSS_QRFS_ERROR_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + nqm, nqm->cm.type, nss_qrfs_log_message_types_str[nqm->cm.type], + nqm->cm.response, nss_cmn_response_str[nqm->cm.response], + nqm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + nqm, nqm->cm.type, nss_qrfs_log_message_types_str[nqm->cm.type], + nqm->cm.response, nss_cmn_response_str[nqm->cm.response], + nqm->cm.error, nss_qrfs_log_error_response_types_str[nqm->cm.error]); + +verbose: + nss_qrfs_log_verbose(nqm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_qrfs_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_qrfs_log.h new file mode 100644 index 000000000..de9832e66 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_qrfs_log.h @@ -0,0 +1,37 @@ +/* + ****************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_QRFS_LOG_H__ +#define __NSS_QRFS_LOG_H__ + +/* + * nss_qrfs_log.h + * NSS QRFS Log Header File + */ + +/* + * nss_qrfs_log_tx_msg + * Logs a qrfs message that is sent to the NSS firmware. + */ +void nss_qrfs_log_tx_msg(struct nss_qrfs_msg *nqm); + +/* + * nss_qrfs_log_rx_msg + * Logs a qrfs message that is received from the NSS firmware. + */ +void nss_qrfs_log_rx_msg(struct nss_qrfs_msg *nqm); + +#endif /* __NSS_QRFS_LOG_H__ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_qrfs_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_qrfs_stats.c new file mode 100644 index 000000000..694908307 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_qrfs_stats.c @@ -0,0 +1,148 @@ +/* + ************************************************************************** + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_qrfs_stats.h" + +/* + * Spinlock to protect QRFS statistics update/read + */ +DEFINE_SPINLOCK(nss_qrfs_stats_lock); + +/* + * nss_qrfs_stats_str + * QRFS stats strings + */ +struct nss_stats_info nss_qrfs_stats_str[NSS_QRFS_STATS_MAX] = { + {"rx_pkts" , NSS_STATS_TYPE_COMMON}, + {"rx_byts" , NSS_STATS_TYPE_COMMON}, + {"tx_pkts" , NSS_STATS_TYPE_COMMON}, + {"tx_byts" , NSS_STATS_TYPE_COMMON}, + {"rx_queue[0]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[1]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[2]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[3]_drops" , NSS_STATS_TYPE_DROP}, + {"invalid_offset" , NSS_STATS_TYPE_EXCEPTION}, + {"unknown_protocol" , NSS_STATS_TYPE_EXCEPTION}, + {"ipv4_flow_rule_hits" , NSS_STATS_TYPE_SPECIAL}, + {"ipv6_flow_rule_hits" , NSS_STATS_TYPE_SPECIAL} +}; + +uint64_t nss_qrfs_stats[NSS_MAX_CORES][NSS_QRFS_STATS_MAX]; + +/* + * nss_qrfs_stats_read() + * Read QRFS statistics. + */ +static ssize_t nss_qrfs_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i, core; + + /* + * Max output lines = #stats + few blank lines for banner printing + + * Number of Extra outputlines for future reference to add new stats. + */ + uint32_t max_output_lines = (NSS_QRFS_STATS_MAX + 3) * NSS_MAX_CORES + NSS_STATS_EXTRA_OUTPUT_LINES; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + stats_shadow = kzalloc(NSS_QRFS_STATS_MAX * 8, GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return 0; + } + + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "qrfs", NSS_STATS_SINGLE_CORE); + /* + * QRFS statistics + */ + for (core = 0; core < nss_top_main.num_nss; core++) { + spin_lock_bh(&nss_qrfs_stats_lock); + for (i = 0; i < NSS_QRFS_STATS_MAX; i++) { + stats_shadow[i] = nss_qrfs_stats[core][i]; + } + spin_unlock_bh(&nss_qrfs_stats_lock); + + size_wr += nss_stats_print("qrfs", NULL, NSS_STATS_SINGLE_INSTANCE + , nss_qrfs_stats_str + , stats_shadow + , NSS_QRFS_STATS_MAX + , lbuf, size_wr, size_al); + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * nss_qrfs_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(qrfs) + +/* + * nss_qrfs_stats_dentry_create() + * Create QRFS statistics debug entry. + */ +void nss_qrfs_stats_dentry_create(void) +{ + nss_stats_create_dentry("qrfs", &nss_qrfs_stats_ops); +} + +/* + * nss_qrfs_stats_sync() + * Handle the syncing of NSS QRFS statistics. + */ +void nss_qrfs_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_qrfs_stats_sync_msg *nqssm) +{ + int id = nss_ctx->id; + int j; + + spin_lock_bh(&nss_qrfs_stats_lock); + + /* + * Common node stats + */ + nss_qrfs_stats[id][NSS_STATS_NODE_RX_PKTS] += nqssm->node_stats.rx_packets; + nss_qrfs_stats[id][NSS_STATS_NODE_RX_BYTES] += nqssm->node_stats.rx_bytes; + nss_qrfs_stats[id][NSS_STATS_NODE_TX_PKTS] += nqssm->node_stats.tx_packets; + nss_qrfs_stats[id][NSS_STATS_NODE_TX_BYTES] += nqssm->node_stats.tx_bytes; + + for (j = 0; j < NSS_MAX_NUM_PRI; j++) { + nss_qrfs_stats[id][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + j] += nqssm->node_stats.rx_dropped[j]; + } + + /* + * QRFS statistics + */ + nss_qrfs_stats[id][NSS_QRFS_STATS_INVALID_OFFSET] += nqssm->invalid_offset; + nss_qrfs_stats[id][NSS_QRFS_STATS_UNKNOWN_PROTO] += nqssm->unknown_protocol; + nss_qrfs_stats[id][NSS_QRFS_STATS_IPV4_FLOW_HITS] += nqssm->ipv4_flow_rule_hits; + nss_qrfs_stats[id][NSS_QRFS_STATS_IPV6_FLOW_HITS] += nqssm->ipv6_flow_rule_hits; + + spin_unlock_bh(&nss_qrfs_stats_lock); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_qrfs_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_qrfs_stats.h new file mode 100644 index 000000000..7992270da --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_qrfs_stats.h @@ -0,0 +1,38 @@ +/* + ****************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_QRFS_STATS_H +#define __NSS_QRFS_STATS_H + +/* + * QRFS node statistics + */ +enum nss_qrfs_stats_types { + NSS_QRFS_STATS_INVALID_OFFSET = NSS_STATS_NODE_MAX, + /* Number of packets with invalid L3, L4 offset */ + NSS_QRFS_STATS_UNKNOWN_PROTO, /* Number of packets with protocol other than TCP, UDP */ + NSS_QRFS_STATS_IPV4_FLOW_HITS, /* Number of IPv4 flow rule hits */ + NSS_QRFS_STATS_IPV6_FLOW_HITS, /* Number of IPv6 flow rule hits */ + NSS_QRFS_STATS_MAX, +}; + +/* + * QRFS statistics APIs + */ +extern void nss_qrfs_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_qrfs_stats_sync_msg *nqssm); +extern void nss_qrfs_stats_dentry_create(void); + +#endif /* __NSS_QRFS_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_qvpn.c b/feeds/ipq807x/qca-nss-drv/src/nss_qvpn.c new file mode 100644 index 000000000..756bd5677 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_qvpn.c @@ -0,0 +1,370 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_qvpn_stats.h" +#include "nss_qvpn_log.h" + +#define NSS_QVPN_TX_TIMEOUT 1000 /* 1 Second */ + +/* + * Private data structure + */ +static struct nss_qvpn_pvt { + struct semaphore sem; + struct completion complete; + unsigned long if_map[NSS_QVPN_INTERFACE_MAX_LONG]; + enum nss_qvpn_error_type resp; +} qvpn_pvt; + +/* + * nss_qvpn_verify_if_num() + * Verify if_num passed to us. + */ +static bool nss_qvpn_verify_if_num(uint32_t if_num) +{ + enum nss_dynamic_interface_type if_type; + + if_type = nss_dynamic_interface_get_type(nss_qvpn_get_context(), if_num); + if ((if_type != NSS_DYNAMIC_INTERFACE_TYPE_QVPN_INNER) && + (if_type != NSS_DYNAMIC_INTERFACE_TYPE_QVPN_OUTER)) { + nss_warning("%px: if_num = %u interface type returned is %d\n", nss_qvpn_get_context(), if_num, if_type); + return false; + } + + return true; +} + +/* + * nss_qvpn_tunnel_stats_sync + * Update qvpn interface statistics. + */ +static void nss_qvpn_tunnel_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm) +{ + struct nss_qvpn_msg *ndcm = (struct nss_qvpn_msg *)ncm; + struct nss_top_instance *nss_top = nss_ctx->nss_top; + struct nss_qvpn_stats_sync_msg *msg_stats = &ndcm->msg.stats; + uint64_t *if_stats; + + spin_lock_bh(&nss_top->stats_lock); + + /* + * Update common node stats + */ + if_stats = nss_top->stats_node[ncm->interface]; + if_stats[NSS_STATS_NODE_RX_PKTS] += msg_stats->node_stats.rx_packets; + if_stats[NSS_STATS_NODE_RX_BYTES] += msg_stats->node_stats.rx_bytes; + if_stats[NSS_STATS_NODE_RX_QUEUE_0_DROPPED] += msg_stats->node_stats.rx_dropped[0]; + if_stats[NSS_STATS_NODE_RX_QUEUE_1_DROPPED] += msg_stats->node_stats.rx_dropped[1]; + if_stats[NSS_STATS_NODE_RX_QUEUE_2_DROPPED] += msg_stats->node_stats.rx_dropped[2]; + if_stats[NSS_STATS_NODE_RX_QUEUE_3_DROPPED] += msg_stats->node_stats.rx_dropped[3]; + + if_stats[NSS_STATS_NODE_TX_PKTS] += msg_stats->node_stats.tx_packets; + if_stats[NSS_STATS_NODE_TX_BYTES] += msg_stats->node_stats.tx_bytes; + + spin_unlock_bh(&nss_top->stats_lock); +} + +/* + * nss_qvpn_handler() + * Handle NSS to HLOS messages for QVPN + */ +static void nss_qvpn_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, void *app_data) +{ + nss_qvpn_msg_callback_t cb; + + nss_assert(nss_qvpn_verify_if_num(ncm->interface)); + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_QVPN_MSG_TYPE_MAX) { + nss_warning("%px: received invalid message %d for qvpn interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_qvpn_msg)) { + nss_warning("%px: length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Log failures + */ + + nss_core_log_msg_failures(nss_ctx, ncm); + /* + * Trace messages. + */ + nss_qvpn_log_rx_msg((struct nss_qvpn_msg *)ncm); + + if (ncm->type == NSS_QVPN_MSG_TYPE_SYNC_STATS) { + nss_qvpn_tunnel_stats_sync(nss_ctx, ncm); + } + + /* + * Update the callback and app_data for NOTIFY messages, qvpn sends all notify messages + * to the same callback/app_data. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_core_get_msg_handler(nss_ctx, ncm->interface); + ncm->app_data = (nss_ptr_t)nss_ctx->nss_rx_interface_handlers[ncm->interface].app_data; + } + + /* + * load, test & call + */ + cb = (nss_qvpn_msg_callback_t)ncm->cb; + if (unlikely(!cb)) { + nss_trace("%px: rx handler unregistered for i/f: %u\n", nss_ctx, ncm->interface); + return; + } + + cb((void *)ncm->app_data, ncm); +} + +/* + * nss_qvpn_callback() + * Callback to handle the completion of NSS to HLOS messages. + */ +static void nss_qvpn_callback(void *app_data, struct nss_qvpn_msg *nvm) +{ + enum nss_qvpn_error_type *resp = (enum nss_qvpn_error_type *)app_data; + + *resp = (nvm->cm.response == NSS_CMN_RESPONSE_ACK) ? NSS_QVPN_ERROR_TYPE_NONE : nvm->cm.error; + + /* + * Write memory barrier + */ + smp_wmb(); + + complete(&qvpn_pvt.complete); +} + +/* + * nss_qvpn_ifmap_get() + * Return QVPN active interfaces map. + */ +unsigned long *nss_qvpn_ifmap_get(void) +{ + return qvpn_pvt.if_map; +} + +/* + * nss_qvpn_get_context() + * Return NSS QVPN context. + */ +struct nss_ctx_instance *nss_qvpn_get_context(void) +{ + return &nss_top_main.nss[nss_top_main.qvpn_handler_id]; +} +EXPORT_SYMBOL(nss_qvpn_get_context); + +/* + * nss_qvpn_tx_msg() + * Transmit a QVPN message to NSS firmware + */ +nss_tx_status_t nss_qvpn_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_qvpn_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Sanity check the message + */ + if (!nss_qvpn_verify_if_num(ncm->interface)) { + nss_warning("%px: tx request for interface that is not a qvpn: %u\n", nss_ctx, ncm->interface); + return NSS_TX_FAILURE_BAD_PARAM; + } + + if (ncm->type >= NSS_QVPN_MSG_TYPE_MAX) { + nss_warning("%px: message type out of range: %d\n", nss_ctx, ncm->type); + return NSS_TX_FAILURE_BAD_PARAM; + } + + /* + * Trace messages. + */ + nss_qvpn_log_tx_msg(msg); + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_qvpn_tx_msg); + +/* + * nss_qvpn_tx_msg_sync() + * Transmit a QVPN message to NSS firmware synchronously. + */ +nss_tx_status_t nss_qvpn_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_qvpn_msg *nvm, + uint32_t if_num, enum nss_qvpn_msg_type type, uint16_t len, enum nss_qvpn_error_type *resp) +{ + struct nss_qvpn_msg nqm; + nss_tx_status_t status; + int ret = 0; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (len > sizeof(nqm.msg)) { + nss_warning("%px: Incorrect message length=%u for type %d and if_num=%u\n", nss_ctx, len, type, if_num); + return NSS_TX_FAILURE_TOO_LARGE; + } + + if (!resp) { + nss_warning("%px: Invalid input, resp=NULL\n", nss_ctx); + return NSS_TX_FAILURE_BAD_PARAM; + } + + nss_qvpn_msg_init(&nqm, if_num, type, len, nss_qvpn_callback, &qvpn_pvt.resp); + memcpy(&nqm.msg, &nvm->msg, len); + + down(&qvpn_pvt.sem); + + status = nss_qvpn_tx_msg(nss_ctx, &nqm); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: qvpn_tx_msg failed\n", nss_ctx); + goto done; + } + + ret = wait_for_completion_timeout(&qvpn_pvt.complete, msecs_to_jiffies(NSS_QVPN_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: qvpn msg tx failed due to timeout\n", nss_ctx); + status = NSS_TX_FAILURE_SYNC_TIMEOUT; + goto done; + } + + /* + * Read memory barrier + */ + smp_rmb(); + + *resp = qvpn_pvt.resp; + if (*resp != NSS_QVPN_ERROR_TYPE_NONE) + status = NSS_TX_FAILURE; +done: + up(&qvpn_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_qvpn_tx_msg_sync); + +/* + * nss_qvpn_tx_buf() + * Send packet to QVPN interface owned by NSS + */ +nss_tx_status_t nss_qvpn_tx_buf(struct nss_ctx_instance *nss_ctx, uint32_t if_num, struct sk_buff *skb) +{ + if (!nss_qvpn_verify_if_num(if_num)) { + nss_warning("%px: tx request for interface that is not a qvpn: %u\n", nss_ctx, if_num); + return NSS_TX_FAILURE_BAD_PARAM; + } + + return nss_core_send_packet(nss_ctx, skb, if_num, H2N_BIT_FLAG_BUFFER_REUSABLE); +} +EXPORT_SYMBOL(nss_qvpn_tx_buf); + +/* + * nss_qvpn_msg_init() + * Initialize nss_qvpn_msg. + */ +void nss_qvpn_msg_init(struct nss_qvpn_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data) +{ + nss_cmn_msg_init(&ncm->cm, if_num, type, len, cb, app_data); +} +EXPORT_SYMBOL(nss_qvpn_msg_init); + +/* + * nss_qvpn_register_if() + * Register QVPN interface. + */ +struct nss_ctx_instance *nss_qvpn_register_if(uint32_t if_num, nss_qvpn_callback_t qvpn_data_callback, + nss_qvpn_msg_callback_t qvpn_event_callback, + struct net_device *netdev, uint32_t features, void *app_ctx) +{ + struct nss_ctx_instance *nss_ctx = nss_qvpn_get_context(); + uint32_t status; + + nss_assert(nss_ctx); + nss_assert(nss_qvpn_verify_if_num(if_num)); + + nss_core_register_subsys_dp(nss_ctx, if_num, qvpn_data_callback, NULL, app_ctx, netdev, features); + nss_core_register_handler(nss_ctx, if_num, nss_qvpn_handler, app_ctx); + status = nss_core_register_msg_handler(nss_ctx, if_num, qvpn_event_callback); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Not able to register handler for interface %d with NSS core\n", nss_ctx, if_num); + return NULL; + } + + set_bit(if_num, qvpn_pvt.if_map); + return nss_ctx; +} +EXPORT_SYMBOL(nss_qvpn_register_if); + +/* + * nss_unregister_qvpn_if() + * Unregister QVPN interface. + */ +void nss_qvpn_unregister_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = nss_qvpn_get_context(); + uint32_t status; + + nss_assert(nss_qvpn_verify_if_num(if_num)); + + clear_bit(if_num, qvpn_pvt.if_map); + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + status = nss_core_unregister_msg_handler(nss_ctx, if_num); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Failed to unregister handler for IPsec NSS I/F:%u\n", nss_ctx, if_num); + return; + } + + status = nss_core_unregister_handler(nss_ctx, if_num); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Failed to unregister handler for IPsec NSS I/F:%u\n", nss_ctx, if_num); + return; + } +} +EXPORT_SYMBOL(nss_qvpn_unregister_if); + +/* + * nss_qvpn_ifnum_with_core_id() + * Append core id to QVPN interface number + */ +int nss_qvpn_ifnum_with_core_id(int if_num) +{ + struct nss_ctx_instance *nss_ctx = nss_qvpn_get_context(); + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + if (nss_qvpn_verify_if_num(if_num) == false) { + nss_info("%px: if_num: %u is not QVPN interface\n", nss_ctx, if_num); + return 0; + } + return NSS_INTERFACE_NUM_APPEND_COREID(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_qvpn_ifnum_with_core_id); + +/* + * nss_qvpn_register_handler() + * Intialize QVPN driver and register handler. + */ +void nss_qvpn_register_handler(void) +{ + nss_info("nss_qvpn_register_handler\n"); + sema_init(&qvpn_pvt.sem, 1); + init_completion(&qvpn_pvt.complete); + nss_qvpn_stats_dentry_create(); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_qvpn_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_qvpn_log.c new file mode 100644 index 000000000..d71c79ee1 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_qvpn_log.c @@ -0,0 +1,262 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_qvpn_log.c + * NSS qvpn logger file. + */ + +#include "nss_core.h" + +/* + * nss_qvpn_log_message_types_str + * qvpn message strings + */ +static int8_t *nss_qvpn_log_message_types_str[NSS_QVPN_MSG_TYPE_MAX] __maybe_unused = { + "QVPN tunnel config", + "QVPN tunnel deconfig", + "QVPN crypto key add", + "QVPN crypto key delete", + "QVPN crypto crypto key activate", + "QVPN crypto key Deactivate", + "QVPN statistics synchronization" +}; + +/* + * nss_qvpn_log_error_response_types_str + * Strings for error types for qvpn messages + */ +static int8_t *nss_qvpn_log_error_response_types_str[NSS_QVPN_ERROR_TYPE_MAX] __maybe_unused = { + "QVPN No error", + "QVPN Unknown message", + "QVPN Tunnel already configured", + "QVPN Invalid interface", + "QVPN Invalid sibling interface number", + "QVPN Invalid IV size", + "QVPN Invalid HMAC size", + "QVPN Invalid crypto block size", + "QVPN Invalid session idx size", + "QVPN Supported processing command count invalid", + "QVPN L4 protocol encapsulation is not supported", + "QVPN Invalid sibling interface type", + "QVPN Total number of commands is invalid", + "QVPN Entry not found", + "QVPN Entry not active", + "QVPN Entry already active", + "QVPN Invalid crypto index", + "QVPN Key info allocation failure", + "QVPN Invalid command profile", + "QVPN VPN with tail not supported" +}; + +/* + * nss_qvpn_tun_config_msg() + * Log NSS QVPN configuration message. + */ +static void nss_qvpn_log_tun_config_msg(struct nss_qvpn_msg *ncm) +{ + struct nss_qvpn_tunnel_config_msg *nqtcm __maybe_unused = &ncm->msg.tunnel_config; + nss_trace("%px: NSS QVPN tunnel config message \n" + "Sibling interface: %d" + "Total number of commands: %d" + "Commands: %px" + "Source IP: %x:%x:%x:%x\n" + "Source Port: %d\n" + "Destination IP: %x:%x:%x:%x\n" + "Destination Port: %d\n" + "Header Flags: %x\n" + "Sequence number size: %d\n" + "Sequence number offset: %d\n" + "Anti-replay algorithm: %d\n" + "Session ID size: %d\n" + "Session ID offset: %x\n" + "VPN header head size: %d\n" + "VPN header head offset: %d\n" + "VPN header tail size: %d\n" + "VPN header head: %px\n" + "VPN header tail: %px\n", + nqtcm, + nqtcm->sibling_if, + nqtcm->total_cmds, + nqtcm->cmd, + nqtcm->hdr_cfg.src_ip[0], nqtcm->hdr_cfg.src_ip[1], nqtcm->hdr_cfg.src_ip[2], nqtcm->hdr_cfg.src_ip[3], + nqtcm->hdr_cfg.src_port, + nqtcm->hdr_cfg.dst_ip[0], nqtcm->hdr_cfg.dst_ip[1], nqtcm->hdr_cfg.dst_ip[2], nqtcm->hdr_cfg.dst_ip[3], + nqtcm->hdr_cfg.dst_port, + nqtcm->hdr_cfg.hdr_flags, + nqtcm->hdr_cfg.seqnum_size, + nqtcm->hdr_cfg.seqnum_offset, + nqtcm->hdr_cfg.anti_replay_alg, + nqtcm->hdr_cfg.session_id_size, + nqtcm->hdr_cfg.session_id_offset, + nqtcm->hdr_cfg.vpn_hdr_head_size, + nqtcm->hdr_cfg.vpn_hdr_head_offset, + nqtcm->hdr_cfg.vpn_hdr_tail_size, + nqtcm->hdr_cfg.vpn_hdr_head, + nqtcm->hdr_cfg.vpn_hdr_tail); +} + +/* + * nss_qvpn_log_tun_deconfig_msg() + * Log NSS qvpn tunnel deconfigure message. + */ +static void nss_qvpn_log_tun_deconfig_msg(struct nss_qvpn_msg *ncm) +{ + nss_trace("%px: NSS QVPN deconfigure message \n", ncm); +} + +/* + * nss_qvpn_log_crypto_key_add_msg() + * Log NSS QVPN crypto key add message. + */ +static void nss_qvpn_log_crypto_key_add_msg(struct nss_qvpn_msg *ncm) +{ + struct nss_qvpn_crypto_key_add_msg *nqckam __maybe_unused = &ncm->msg.key_add; + nss_trace("%px: NSS QVPN crypto key add message \n" + "Crypto index: %d\n" + "Crypto session ID: %px", + nqckam, + nqckam->crypto_idx, + nqckam->session_id); +} + +/* + * nss_qvpn_log_crypto_key_activate_msg() + * Log NSS QVPN crypto key activate message. + */ +static void nss_qvpn_log_crypto_key_activate_msg(struct nss_qvpn_msg *ncm) +{ + struct nss_qvpn_crypto_key_activate_msg *nqckam __maybe_unused = &ncm->msg.key_activate; + nss_trace("%px: NSS QVPN crypto key activate message \n" + "Crypto index: %d\n" + "Crypto VPN header head: %px", + nqckam, + nqckam->crypto_idx, + nqckam->vpn_hdr_head); +} + +/* + * nss_qvpn_log_crypto_key_del_msg() + * Log NSS QVPN crypto key delete message. + */ +static void nss_qvpn_log_crypto_key_del_msg(struct nss_qvpn_msg *ncm) +{ + struct nss_qvpn_crypto_key_del_msg *nqckdm __maybe_unused = &ncm->msg.key_del; + nss_trace("%px: NSS QVPN crypto key delete message \n" + "Crypto index: %d\n", + nqckdm, + nqckdm->crypto_idx); +} + +/* + * nss_qvpn_log_crypto_key_deactivate_msg() + * Log NSS QVPN crypto key deactivate message. + */ +static void nss_qvpn_log_crypto_key_deactivate_msg(struct nss_qvpn_msg *ncm) +{ + struct nss_qvpn_crypto_key_del_msg *nqckdm __maybe_unused = &ncm->msg.key_del; + nss_trace("%px: NSS QVPN crypto key deactivate message \n" + "Crypto index: %d\n", + nqckdm, + nqckdm->crypto_idx); +} + +/* + * nss_qvpn_log_verbose() + * Log message contents. + */ +static void nss_qvpn_log_verbose(struct nss_qvpn_msg *ncm) +{ + switch (ncm->cm.type) { + case NSS_QVPN_MSG_TYPE_TUNNEL_CONFIGURE: + nss_qvpn_log_tun_config_msg(ncm); + break; + + case NSS_QVPN_MSG_TYPE_TUNNEL_DECONFIGURE: + nss_qvpn_log_tun_deconfig_msg(ncm); + break; + + case NSS_QVPN_MSG_TYPE_CRYPTO_KEY_ADD: + nss_qvpn_log_crypto_key_add_msg(ncm); + break; + + case NSS_QVPN_MSG_TYPE_CRYPTO_KEY_ACTIVATE: + nss_qvpn_log_crypto_key_activate_msg(ncm); + break; + + case NSS_QVPN_MSG_TYPE_CRYPTO_KEY_DEL: + nss_qvpn_log_crypto_key_del_msg(ncm); + break; + + case NSS_QVPN_MSG_TYPE_CRYPTO_KEY_DEACTIVATE: + nss_qvpn_log_crypto_key_deactivate_msg(ncm); + break; + + default: + nss_trace("%px: Invalid message type\n", ncm); + break; + } +} + +/* + * nss_qvpn_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_qvpn_log_tx_msg(struct nss_qvpn_msg *ncm) +{ + if (ncm->cm.type >= NSS_QVPN_MSG_TYPE_MAX) { + nss_warning("%px: Invalid message type\n", ncm); + return; + } + + nss_info("%px: type[%d]:%s\n", ncm, ncm->cm.type, nss_qvpn_log_message_types_str[ncm->cm.type]); + nss_qvpn_log_verbose(ncm); +} + +/* + * nss_qvpn_log_rx_msg() + * Log messages received from FW. + */ +void nss_qvpn_log_rx_msg(struct nss_qvpn_msg *ncm) +{ + if (ncm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", ncm); + return; + } + + if (ncm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ncm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", ncm, ncm->cm.type, + nss_qvpn_log_message_types_str[ncm->cm.type], + ncm->cm.response, nss_cmn_response_str[ncm->cm.response]); + goto verbose; + } + + if (ncm->cm.error >= NSS_QVPN_ERROR_TYPE_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + ncm, ncm->cm.type, nss_qvpn_log_message_types_str[ncm->cm.type], + ncm->cm.response, nss_cmn_response_str[ncm->cm.response], + ncm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + ncm, ncm->cm.type, nss_qvpn_log_message_types_str[ncm->cm.type], + ncm->cm.response, nss_cmn_response_str[ncm->cm.response], + ncm->cm.error, nss_qvpn_log_error_response_types_str[ncm->cm.error]); + +verbose: + nss_qvpn_log_verbose(ncm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_qvpn_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_qvpn_log.h new file mode 100644 index 000000000..e1dee898b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_qvpn_log.h @@ -0,0 +1,37 @@ +/* + ****************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_QVPN_LOG_H__ +#define __NSS_QVPN_LOG_H__ + +/* + * nss_qvpn_log.h + * NSS QVPN Log Header File. + */ + +/* + * nss_qvpn_log_tx_msg + * Logs QVPN message that is sent to the NSS firmware. + */ +void nss_qvpn_log_tx_msg(struct nss_qvpn_msg *ncm); + +/* + * nss_qvpn_log_rx_msg + * Logs QVPN message that is received from the NSS firmware. + */ +void nss_qvpn_log_rx_msg(struct nss_qvpn_msg *ncm); + +#endif /* __NSS_QVPN_LOG_H__ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_qvpn_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_qvpn_stats.c new file mode 100644 index 000000000..ff139bc99 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_qvpn_stats.c @@ -0,0 +1,86 @@ +/* + ************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include + +/* + * nss_qvpn_stats_read() + * Read qvpn node statiistics. + */ +static ssize_t nss_qvpn_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + struct nss_ctx_instance *nss_ctx = nss_qvpn_get_context(); + enum nss_dynamic_interface_type type; + ssize_t bytes_read = 0; + size_t len = 0, size; + uint32_t if_num; + unsigned long *ifmap; + char *buf; + + ifmap = nss_qvpn_ifmap_get(); + size = NSS_QVPN_STATS_SIZE_PER_IF * bitmap_weight(ifmap, NSS_MAX_NET_INTERFACES); + + buf = kzalloc(size, GFP_KERNEL); + if (!buf) { + nss_warning("Could not allocate memory for local statistics buffer\n"); + return 0; + } + + /* + * Common node stats for each QVPN dynamic interface. + */ + len += nss_stats_banner(buf, len, size, "qvpn", NSS_STATS_SINGLE_CORE); + for_each_set_bit(if_num, ifmap, NSS_MAX_NET_INTERFACES) { + type = nss_dynamic_interface_get_type(nss_ctx, if_num); + + switch (type) { + case NSS_DYNAMIC_INTERFACE_TYPE_QVPN_INNER: + len += scnprintf(buf + len, size - len, "\nInner if_num:%03u", if_num); + break; + + case NSS_DYNAMIC_INTERFACE_TYPE_QVPN_OUTER: + len += scnprintf(buf + len, size - len, "\nOuter if_num:%03u", if_num); + break; + + default: + len += scnprintf(buf + len, size - len, "\nUnknown(%d) if_num:%03u", type, if_num); + break; + } + + len += scnprintf(buf + len, size - len, "\n-------------------\n"); + len += nss_stats_fill_common_stats(if_num, NSS_STATS_SINGLE_INSTANCE, buf, len, size - len, "qvpn"); + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, buf, len); + kfree(buf); + + return bytes_read; +} + +/* + * nss_qvpn_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(qvpn) + +/* + * nss_qvpn_stats_dentry_create() + * Create QVPN statistics debug entry. + */ +void nss_qvpn_stats_dentry_create(void) +{ + nss_stats_create_dentry("qvpn", &nss_qvpn_stats_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_qvpn_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_qvpn_stats.h new file mode 100644 index 000000000..d9d3dc2fc --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_qvpn_stats.h @@ -0,0 +1,26 @@ +/* + ************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef _NSS_QVPN_STATS_H_ +#define _NSS_QVPN_STATS_H_ + +/* + * nss_qvpn_stats_dentry_create + * Creates QVPN interface statistics debug entry. + */ +void nss_qvpn_stats_dentry_create(void); + +#endif /* _NSS_QVPN_STATS_H_ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_rmnet_rx.c b/feeds/ipq807x/qca-nss-drv/src/nss_rmnet_rx.c new file mode 100644 index 000000000..adba8062a --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_rmnet_rx.c @@ -0,0 +1,760 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_rmnet_rx.c + * NSS rmnet receive handler APIs + */ + +#include "nss_tx_rx_common.h" +#include "nss_rmnet_rx_stats.h" +#include + +#define NSS_RMNET_RX_TX_TIMEOUT 3000 /* 3 Seconds */ +#define NSS_RMNET_RX_GET_INDEX(if_num) (if_num - NSS_DYNAMIC_IF_START) + +/* + * Spinlock to protect the global data structure virt_handle. + */ +DEFINE_SPINLOCK(nss_rmnet_rx_lock); + +extern int nss_ctl_redirect; + +/* + * Data structure that holds theinterface context. + */ +struct nss_rmnet_rx_handle *rmnet_rx_handle[NSS_MAX_DYNAMIC_INTERFACES]; + +/* + * nss_rmnet_rx_verify_if_num() + * Verify if_num passed to us. + */ +bool nss_rmnet_rx_verify_if_num(uint32_t if_num) +{ + enum nss_dynamic_interface_type type = nss_dynamic_interface_get_type(nss_rmnet_rx_get_context(), if_num); + + return type == NSS_DYNAMIC_INTERFACE_TYPE_RMNET_RX_N2H + || type == NSS_DYNAMIC_INTERFACE_TYPE_RMNET_RX_H2N; +} + +/* + * nss_rmnet_rx_msg_handler() + * Handle msg responses from the FW on interfaces + */ +static void nss_rmnet_rx_msg_handler(struct nss_ctx_instance *nss_ctx, + struct nss_cmn_msg *ncm, + void *app_data) +{ + struct nss_rmnet_rx_msg *nvim = (struct nss_rmnet_rx_msg *)ncm; + int32_t if_num; + + nss_rmnet_rx_msg_callback_t cb; + struct nss_rmnet_rx_handle *handle = NULL; + + /* + * Sanity check the message type + */ + if (ncm->type > NSS_RMNET_RX_MAX_MSG_TYPES) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return; + } + + /* + * Messages value that are within the base class are handled by the base class. + */ + if (ncm->type < NSS_IF_MAX_MSG_TYPES) { + return nss_if_msg_handler(nss_ctx, ncm, app_data); + } + + if (!nss_rmnet_rx_verify_if_num(ncm->interface)) { + nss_warning("%px: response for another interface: %d", nss_ctx, ncm->interface); + return; + } + + if_num = NSS_RMNET_RX_GET_INDEX(ncm->interface); + + spin_lock_bh(&nss_rmnet_rx_lock); + if (!rmnet_rx_handle[if_num]) { + spin_unlock_bh(&nss_rmnet_rx_lock); + nss_warning("%px: rmnet_rx handle is NULL\n", nss_ctx); + return; + } + + handle = rmnet_rx_handle[if_num]; + spin_unlock_bh(&nss_rmnet_rx_lock); + + switch (nvim->cm.type) { + case NSS_RMNET_RX_STATS_SYNC_MSG: + nss_rmnet_rx_stats_sync(handle, &nvim->msg.stats, ncm->interface); + break; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Update the callback and app_data for NOTIFY messages, IPv4 sends all notify messages + * to the same callback/app_data. + * + * TODO: RMNet driver does not provide a registration for a notifier callback. + * Since dynamic interface are allocated on both cores and since the array for + * registered callback is not core specific, we call the Wi-Fi callback + * inappropriately. Disable the callback locally until we have per-core + * callback registrations. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)NULL; + ncm->app_data = (nss_ptr_t)nss_ctx->subsys_dp_register[ncm->interface].ndev; + } + + /* + * Do we have a callback? + */ + if (!ncm->cb) { + return; + } + + /* + * Callback + */ + cb = (nss_rmnet_rx_msg_callback_t)ncm->cb; + cb((void *)ncm->app_data, ncm); +} + +/* + * nss_rmnet_rx_callback + * Callback to handle the completion of NSS ->HLOS messages. + */ +static void nss_rmnet_rx_callback(void *app_data, struct nss_cmn_msg *ncm) +{ + struct nss_rmnet_rx_handle *handle = (struct nss_rmnet_rx_handle *)app_data; + struct nss_rmnet_rx_pvt *nvip = handle->pvt; + + if (ncm->response != NSS_CMN_RESPONSE_ACK) { + nss_warning("%px: rmnet_rx Error response %d\n", handle->nss_ctx, ncm->response); + nvip->response = NSS_TX_FAILURE; + complete(&nvip->complete); + return; + } + + nvip->response = NSS_TX_SUCCESS; + complete(&nvip->complete); +} + +/* + * nss_rmnet_rx_tx_msg_sync + * Send a message from HLOS to NSS synchronously. + */ +static nss_tx_status_t nss_rmnet_rx_tx_msg_sync(struct nss_rmnet_rx_handle *handle, + struct nss_rmnet_rx_msg *nvim) +{ + nss_tx_status_t status; + int ret = 0; + struct nss_rmnet_rx_pvt *nwip = handle->pvt; + struct nss_ctx_instance *nss_ctx = handle->nss_ctx; + + down(&nwip->sem); + + status = nss_rmnet_rx_tx_msg(nss_ctx, nvim); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: nss_rmnet_rx_msg failed\n", nss_ctx); + up(&nwip->sem); + return status; + } + + ret = wait_for_completion_timeout(&nwip->complete, + msecs_to_jiffies(NSS_RMNET_RX_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: rmnet_rx tx failed due to timeout\n", nss_ctx); + nwip->response = NSS_TX_FAILURE; + } + + status = nwip->response; + up(&nwip->sem); + + return status; +} + +/* + * nss_rmnet_rx_msg_init() + * Initialize virt specific message structure. + */ +static void nss_rmnet_rx_msg_init(struct nss_rmnet_rx_msg *nvim, + uint16_t if_num, + uint32_t type, + uint32_t len, + nss_rmnet_rx_msg_callback_t cb, + struct nss_rmnet_rx_handle *app_data) +{ + nss_cmn_msg_init(&nvim->cm, if_num, type, len, (void *)cb, (void *)app_data); +} + +/* + * nss_rmnet_rx_handle_destroy_sync() + * Destroy the virt handle either due to request from user or due to error, synchronously. + */ +static int nss_rmnet_rx_handle_destroy_sync(struct nss_rmnet_rx_handle *handle) +{ + nss_tx_status_t status; + int32_t if_num_n2h = handle->if_num_n2h; + int32_t if_num_h2n = handle->if_num_h2n; + int32_t index_n2h; + int32_t index_h2n; + + if (!nss_rmnet_rx_verify_if_num(if_num_n2h) || !nss_rmnet_rx_verify_if_num(if_num_h2n)) { + nss_warning("%px: bad interface numbers %d %d\n", handle->nss_ctx, if_num_n2h, if_num_h2n); + return NSS_TX_FAILURE_BAD_PARAM; + } + + index_n2h = NSS_RMNET_RX_GET_INDEX(if_num_n2h); + index_h2n = NSS_RMNET_RX_GET_INDEX(if_num_h2n); + + status = nss_dynamic_interface_dealloc_node(if_num_n2h, NSS_DYNAMIC_INTERFACE_TYPE_RMNET_RX_N2H); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: Dynamic interface destroy failed status %d\n", handle->nss_ctx, status); + return status; + } + + status = nss_dynamic_interface_dealloc_node(if_num_h2n, NSS_DYNAMIC_INTERFACE_TYPE_RMNET_RX_H2N); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: Dynamic interface destroy failed status %d\n", handle->nss_ctx, status); + return status; + } + + spin_lock_bh(&nss_rmnet_rx_lock); + rmnet_rx_handle[index_n2h] = NULL; + rmnet_rx_handle[index_h2n] = NULL; + spin_unlock_bh(&nss_rmnet_rx_lock); + + kfree(handle->pvt); + kfree(handle); + + return status; +} + +/* + * nss_rmnet_rx_handle_create_sync() + * Initialize virt handle which holds the if_num and stats per interface. + */ +static struct nss_rmnet_rx_handle *nss_rmnet_rx_handle_create_sync(struct nss_ctx_instance *nss_ctx, int32_t if_num_n2h, int32_t if_num_h2n, int32_t *cmd_rsp) +{ + int32_t index_n2h; + int32_t index_h2n; + struct nss_rmnet_rx_handle *handle; + + if (!nss_rmnet_rx_verify_if_num(if_num_n2h) || !nss_rmnet_rx_verify_if_num(if_num_h2n)) { + nss_warning("%px: bad interface numbers %d %d\n", nss_ctx, if_num_n2h, if_num_h2n); + return NULL; + } + + index_n2h = NSS_RMNET_RX_GET_INDEX(if_num_n2h); + index_h2n = NSS_RMNET_RX_GET_INDEX(if_num_h2n); + + handle = (struct nss_rmnet_rx_handle *)kzalloc(sizeof(struct nss_rmnet_rx_handle), + GFP_KERNEL); + if (!handle) { + nss_warning("%px: handle memory alloc failed\n", nss_ctx); + *cmd_rsp = NSS_RMNET_RX_ALLOC_FAILURE; + goto error1; + } + + handle->nss_ctx = nss_ctx; + handle->if_num_n2h = if_num_n2h; + handle->if_num_h2n = if_num_h2n; + handle->pvt = (struct nss_rmnet_rx_pvt *)kzalloc(sizeof(struct nss_rmnet_rx_pvt), + GFP_KERNEL); + if (!handle->pvt) { + nss_warning("%px: failure allocating memory for nss_rmnet_rx_pvt\n", nss_ctx); + *cmd_rsp = NSS_RMNET_RX_ALLOC_FAILURE; + goto error2; + } + + handle->stats_n2h = (uint64_t *)kzalloc(sizeof(uint64_t) * NSS_RMNET_RX_STATS_MAX, + GFP_KERNEL); + if (!handle->stats_n2h) { + nss_warning("%px: failure allocating memory for N2H stats\n", nss_ctx); + *cmd_rsp = NSS_RMNET_RX_ALLOC_FAILURE; + goto error3; + } + + handle->stats_h2n = (uint64_t *)kzalloc(sizeof(uint64_t) * NSS_RMNET_RX_STATS_MAX, + GFP_KERNEL); + if (!handle->stats_h2n) { + nss_warning("%px: failure allocating memory for H2N stats\n", nss_ctx); + *cmd_rsp = NSS_RMNET_RX_ALLOC_FAILURE; + goto error4; + } + + handle->cb = NULL; + handle->app_data = NULL; + + spin_lock_bh(&nss_rmnet_rx_lock); + rmnet_rx_handle[index_n2h] = handle; + rmnet_rx_handle[index_h2n] = handle; + spin_unlock_bh(&nss_rmnet_rx_lock); + + *cmd_rsp = NSS_RMNET_RX_SUCCESS; + + return handle; + +error4: + kfree(handle->stats_n2h); +error3: + kfree(handle->pvt); +error2: + kfree(handle); +error1: + return NULL; +} + +/* + * nss_rmnet_rx_register_handler_sync() + * register msg handler for interface and initialize semaphore and completion. + */ +static uint32_t nss_rmnet_rx_register_handler_sync(struct nss_ctx_instance *nss_ctx, struct nss_rmnet_rx_handle *handle) +{ + uint32_t ret; + struct nss_rmnet_rx_pvt *nvip = NULL; + int32_t if_num_n2h = handle->if_num_n2h; + int32_t if_num_h2n = handle->if_num_h2n; + + ret = nss_core_register_handler(nss_ctx, if_num_n2h, nss_rmnet_rx_msg_handler, NULL); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Failed to register message handler for redir_n2h interface %d\n", nss_ctx, if_num_n2h); + return NSS_RMNET_RX_REG_FAILURE; + } + + ret = nss_core_register_handler(nss_ctx, if_num_h2n, nss_rmnet_rx_msg_handler, NULL); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_core_unregister_handler(nss_ctx, if_num_n2h); + nss_warning("%px: Failed to register message handler for redir_h2n interface %d\n", nss_ctx, if_num_h2n); + return NSS_RMNET_RX_REG_FAILURE; + } + + nvip = handle->pvt; + if (!nvip->sem_init_done) { + sema_init(&nvip->sem, 1); + init_completion(&nvip->complete); + nvip->sem_init_done = 1; + } + + nss_rmnet_rx_stats_dentry_create(); + return NSS_RMNET_RX_SUCCESS; +} + +/* + * nss_rmnet_rx_destroy_sync() + * Destroy the virt interface associated with the interface number, synchronously. + */ +nss_tx_status_t nss_rmnet_rx_destroy_sync(struct nss_rmnet_rx_handle *handle) +{ + nss_tx_status_t status; + struct net_device *dev; + int32_t if_num_n2h; + int32_t if_num_h2n; + struct nss_ctx_instance *nss_ctx; + uint32_t ret; + + if (!handle) { + nss_warning("handle is NULL\n"); + return NSS_TX_FAILURE_BAD_PARAM; + } + + if_num_n2h = handle->if_num_n2h; + if_num_h2n = handle->if_num_h2n; + nss_ctx = handle->nss_ctx; + + if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) { + nss_warning("%px: Interface could not be destroyed as core not ready\n", nss_ctx); + return NSS_TX_FAILURE_NOT_READY; + } + + spin_lock_bh(&nss_top_main.lock); + if (!nss_ctx->subsys_dp_register[if_num_n2h].ndev || !nss_ctx->subsys_dp_register[if_num_h2n].ndev) { + spin_unlock_bh(&nss_top_main.lock); + nss_warning("%px: Unregister virt interface %d %d: no context\n", nss_ctx, if_num_n2h, if_num_h2n); + return NSS_TX_FAILURE_BAD_PARAM; + } + + dev = nss_ctx->subsys_dp_register[if_num_n2h].ndev; + nss_assert(dev == nss_ctx->subsys_dp_register[if_num_h2n].ndev); + nss_core_unregister_subsys_dp(nss_ctx, if_num_n2h); + nss_core_unregister_subsys_dp(nss_ctx, if_num_h2n); + spin_unlock_bh(&nss_top_main.lock); + dev_put(dev); + + status = nss_rmnet_rx_handle_destroy_sync(handle); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: handle destroy failed for if_num_n2h %d and if_num_h2n %d\n", nss_ctx, if_num_n2h, if_num_h2n); + return NSS_TX_FAILURE; + } + + ret = nss_core_unregister_handler(nss_ctx, if_num_n2h); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Not able to unregister handler for redir_n2h interface %d with NSS core\n", nss_ctx, if_num_n2h); + return NSS_TX_FAILURE_BAD_PARAM; + } + + ret = nss_core_unregister_handler(nss_ctx, if_num_h2n); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Not able to unregister handler for redir_h2n interface %d with NSS core\n", nss_ctx, if_num_h2n); + return NSS_TX_FAILURE_BAD_PARAM; + } + + return status; +} +EXPORT_SYMBOL(nss_rmnet_rx_destroy_sync); + +/* + * nss_rmnet_rx_create_sync_nexthop() + * Create redir_n2h and redir_h2n interfaces, synchronously and associate it with same netdev. + */ +struct nss_rmnet_rx_handle *nss_rmnet_rx_create_sync_nexthop(struct net_device *netdev, uint32_t nexthop_n2h, uint32_t nexthop_h2n) +{ + struct nss_ctx_instance *nss_ctx = nss_rmnet_rx_get_context(); + struct nss_rmnet_rx_msg nvim; + struct nss_rmnet_rx_config_msg *nvcm; + uint32_t ret; + struct nss_rmnet_rx_handle *handle = NULL; + int32_t if_num_n2h, if_num_h2n; + + if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) { + nss_warning("%px: Interface could not be created as core not ready\n", nss_ctx); + return NULL; + } + + if_num_n2h = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_RMNET_RX_N2H); + if (if_num_n2h < 0) { + nss_warning("%px: failure allocating redir_n2h\n", nss_ctx); + return NULL; + } + + if_num_h2n = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_RMNET_RX_H2N); + if (if_num_h2n < 0) { + nss_warning("%px: failure allocating redir_h2n\n", nss_ctx); + nss_dynamic_interface_dealloc_node(if_num_n2h, NSS_DYNAMIC_INTERFACE_TYPE_RMNET_RX_N2H); + return NULL; + } + + handle = nss_rmnet_rx_handle_create_sync(nss_ctx, if_num_n2h, if_num_h2n, &ret); + if (!handle) { + nss_warning("%px: rmnet_rx handle creation failed ret %d\n", nss_ctx, ret); + nss_dynamic_interface_dealloc_node(if_num_n2h, NSS_DYNAMIC_INTERFACE_TYPE_RMNET_RX_N2H); + nss_dynamic_interface_dealloc_node(if_num_h2n, NSS_DYNAMIC_INTERFACE_TYPE_RMNET_RX_H2N); + return NULL; + } + + /* + * Initializes the semaphore and also sets the msg handler for if_num. + */ + ret = nss_rmnet_rx_register_handler_sync(nss_ctx, handle); + if (ret != NSS_RMNET_RX_SUCCESS) { + nss_warning("%px: Registration handler failed reason: %d\n", nss_ctx, ret); + goto error1; + } + + nss_rmnet_rx_msg_init(&nvim, handle->if_num_n2h, NSS_RMNET_RX_TX_CONFIG_MSG, + sizeof(struct nss_rmnet_rx_config_msg), nss_rmnet_rx_callback, handle); + + nvcm = &nvim.msg.if_config; + nvcm->flags = 0; + nvcm->sibling = if_num_h2n; + nvcm->nexthop = nexthop_n2h; + nvcm->no_channel = 0; + + ret = nss_rmnet_rx_tx_msg_sync(handle, &nvim); + if (ret != NSS_TX_SUCCESS) { + nss_warning("%px: nss_rmnet_rx_tx_msg_sync failed %u\n", nss_ctx, ret); + goto error2; + } + + nvim.cm.interface = if_num_h2n; + nvcm->sibling = if_num_n2h; + nvcm->nexthop = nexthop_h2n; + nvcm->no_channel = NSS_RMNET_RX_CHANNEL_MAX; + + ret = nss_rmnet_rx_tx_msg_sync(handle, &nvim); + if (ret != NSS_TX_SUCCESS) { + nss_warning("%px: nss_rmnet_rx_tx_msg_sync failed %u\n", nss_ctx, ret); + goto error2; + } + + nss_core_register_subsys_dp(nss_ctx, (uint32_t)if_num_n2h, NULL, NULL, NULL, netdev, 0); + nss_core_register_subsys_dp(nss_ctx, (uint32_t)if_num_h2n, NULL, NULL, NULL, netdev, 0); + + nss_core_set_subsys_dp_type(nss_ctx, netdev, if_num_n2h, NSS_RMNET_RX_DP_N2H); + nss_core_set_subsys_dp_type(nss_ctx, netdev, if_num_h2n, NSS_RMNET_RX_DP_H2N); + + /* + * Hold a reference to the net_device + */ + dev_hold(netdev); + + /* + * The context returned is the handle interface # which contains all the info related to + * the interface if_num. + */ + + return handle; + +error2: + nss_core_unregister_handler(nss_ctx, if_num_n2h); + nss_core_unregister_handler(nss_ctx, if_num_h2n); + +error1: + nss_rmnet_rx_handle_destroy_sync(handle); + return NULL; +} +EXPORT_SYMBOL(nss_rmnet_rx_create_sync_nexthop); + +/* + * nss_rmnet_rx_tx_buf() + * HLOS interface has received a packet which we redirect to the NSS, if appropriate to do so. + */ +nss_tx_status_t nss_rmnet_rx_tx_buf(struct nss_rmnet_rx_handle *handle, + struct sk_buff *skb) +{ + int32_t if_num = handle->if_num_h2n; + struct nss_ctx_instance *nss_ctx = handle->nss_ctx; + int cpu = 0; + + if (unlikely(nss_ctl_redirect == 0)) { + return NSS_TX_FAILURE_NOT_ENABLED; + } + + if (unlikely(skb->vlan_tci)) { + return NSS_TX_FAILURE_NOT_SUPPORTED; + } + + if (!nss_rmnet_rx_verify_if_num(if_num)) { + nss_warning("%px: bad interface number %d\n", nss_ctx, if_num); + return NSS_TX_FAILURE_BAD_PARAM; + } + + nss_trace("%px: RmnetRx packet, if_num:%d, skb:%px", nss_ctx, if_num, skb); + + /* + * Sanity check the SKB to ensure that it's suitable for us + */ + if (unlikely(skb->len <= ETH_HLEN)) { + nss_warning("%px: Rmnet Rx packet: %px too short", nss_ctx, skb); + return NSS_TX_FAILURE_TOO_SHORT; + } + + /* + * set skb queue mapping + */ + cpu = get_cpu(); + put_cpu(); + skb_set_queue_mapping(skb, cpu); + + return nss_core_send_packet(nss_ctx, skb, if_num, H2N_BIT_FLAG_VIRTUAL_BUFFER); +} +EXPORT_SYMBOL(nss_rmnet_rx_tx_buf); + +/* + * nss_rmnet_rx_tx_msg() + */ +nss_tx_status_t nss_rmnet_rx_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_rmnet_rx_msg *nvim) +{ + struct nss_cmn_msg *ncm = &nvim->cm; + + /* + * Sanity check the message + */ + if (!nss_rmnet_rx_verify_if_num(ncm->interface)) { + nss_warning("%px: tx request for another interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type > NSS_RMNET_RX_MAX_MSG_TYPES) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, nvim, sizeof(*nvim), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_rmnet_rx_tx_msg); + +/* + * nss_rmnet_rx_xmit_callback_unregister() + * Unregister interface xmit callback. + */ +void nss_rmnet_rx_xmit_callback_unregister(struct nss_rmnet_rx_handle *handle) +{ + struct nss_ctx_instance *nss_ctx; + struct nss_subsystem_dataplane_register *reg; + + if (!handle) { + nss_warning("handle is NULL\n"); + return; + } + + nss_ctx = handle->nss_ctx; + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (!nss_rmnet_rx_verify_if_num(handle->if_num_n2h)) { + nss_warning("if_num is invalid\n"); + return; + } + + reg = &nss_ctx->subsys_dp_register[handle->if_num_n2h]; + reg->xmit_cb = NULL; +} +EXPORT_SYMBOL(nss_rmnet_rx_xmit_callback_unregister); + +/* + * nss_rmnet_rx_xmit_callback_register() + * Register interface xmit callback. + */ +void nss_rmnet_rx_xmit_callback_register(struct nss_rmnet_rx_handle *handle, + nss_rmnet_rx_xmit_callback_t cb) +{ + struct nss_ctx_instance *nss_ctx; + struct nss_subsystem_dataplane_register *reg; + + if (!handle) { + nss_warning("handle is NULL\n"); + return; + } + + nss_ctx = handle->nss_ctx; + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (!nss_rmnet_rx_verify_if_num(handle->if_num_n2h)) { + nss_warning("if_num is invalid\n"); + return; + } + + reg = &nss_ctx->subsys_dp_register[handle->if_num_n2h]; + reg->xmit_cb = cb; +} +EXPORT_SYMBOL(nss_rmnet_rx_xmit_callback_register); + +/* + * nss_rmnet_rx_unregister() + */ +void nss_rmnet_rx_unregister(struct nss_rmnet_rx_handle *handle) +{ + struct nss_ctx_instance *nss_ctx; + int32_t if_num; + + if (!handle) { + nss_warning("handle is NULL\n"); + return; + } + + nss_ctx = handle->nss_ctx; + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (!nss_rmnet_rx_verify_if_num(handle->if_num_n2h)) { + nss_warning("if_num is invalid\n"); + return; + } + + if_num = handle->if_num_n2h; + + nss_core_unregister_subsys_dp(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_rmnet_rx_unregister); + +/* + * nss_rmnet_rx_register() + */ +void nss_rmnet_rx_register(struct nss_rmnet_rx_handle *handle, + nss_rmnet_rx_data_callback_t data_callback, + struct net_device *netdev) +{ + struct nss_ctx_instance *nss_ctx; + int32_t if_num; + + if (!handle) { + nss_warning("handle is NULL\n"); + return; + } + + nss_ctx = handle->nss_ctx; + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (!nss_rmnet_rx_verify_if_num(handle->if_num_n2h)) { + nss_warning("if_num is invalid\n"); + return; + } + + if_num = handle->if_num_n2h; + + nss_core_register_subsys_dp(nss_ctx, if_num, data_callback, NULL, NULL, netdev, (uint32_t)netdev->features); +} +EXPORT_SYMBOL(nss_rmnet_rx_register); + +/* + * nss_rmnet_rx_get_ifnum_with_core_id() + * Append core id to rmnet interface number + */ +int32_t nss_rmnet_rx_get_ifnum_with_core_id(int32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = nss_rmnet_rx_get_context(); + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + if (nss_rmnet_rx_verify_if_num(if_num) == false) { + nss_info("%px: if_num: %u is not RMNET interface\n", nss_ctx, if_num); + return -1; + } + return NSS_INTERFACE_NUM_APPEND_COREID(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_rmnet_rx_get_ifnum_with_core_id); + +/* + * nss_rmnet_rx_get_ifnum() + * Return rmnet interface number with core ID + */ +int32_t nss_rmnet_rx_get_ifnum(struct net_device *dev) +{ + int32_t ifnum = nss_cmn_get_interface_number_by_dev(dev); + return nss_rmnet_rx_get_ifnum_with_core_id(ifnum); +} +EXPORT_SYMBOL(nss_rmnet_rx_get_ifnum); + +/* + * nss_rmnet_rx_get_interface_num() + * Get interface number for an interface + */ +int32_t nss_rmnet_rx_get_interface_num(struct nss_rmnet_rx_handle *handle) +{ + if (!handle) { + nss_warning("rmnet_rx handle is NULL\n"); + return -1; + } + + /* + * Return if_num_n2h whose datapath type is 0. + */ + return handle->if_num_n2h; +} +EXPORT_SYMBOL(nss_rmnet_rx_get_interface_num); + +/* + * nss_rmnet_rx_get_context() + */ +struct nss_ctx_instance *nss_rmnet_rx_get_context(void) +{ + return &nss_top_main.nss[nss_top_main.rmnet_rx_handler_id]; +} +EXPORT_SYMBOL(nss_rmnet_rx_get_context); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_rmnet_rx_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_rmnet_rx_stats.c new file mode 100644 index 000000000..efbcaffc0 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_rmnet_rx_stats.c @@ -0,0 +1,209 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_stats.h" +#include "nss_core.h" +#include "nss_rmnet_rx_stats.h" + +/* + * Data structure that holds the virtual interface context. + */ +extern struct nss_rmnet_rx_handle *rmnet_rx_handle[]; + +/* + * Spinlock to protect the global data structure virt_handle. + */ +extern spinlock_t nss_rmnet_rx_lock; + +/* + * nss_rmnet_rx_stats_str + * rmnet_rx interface stats strings + */ +struct nss_stats_info nss_rmnet_rx_stats_str[NSS_RMNET_RX_STATS_MAX] = { + {"rx_packets" , NSS_STATS_TYPE_COMMON}, + {"rx_bytes" , NSS_STATS_TYPE_COMMON}, + {"tx_packets" , NSS_STATS_TYPE_COMMON}, + {"tx_bytes" , NSS_STATS_TYPE_COMMON}, + {"rx_queue_0_dropped" , NSS_STATS_TYPE_DROP}, + {"rx_queue_1_dropped" , NSS_STATS_TYPE_DROP}, + {"rx_queue_2_dropped" , NSS_STATS_TYPE_DROP}, + {"rx_queue_3_dropped" , NSS_STATS_TYPE_DROP}, + {"enqueue failed" , NSS_STATS_TYPE_DROP}, + {"no available channel" , NSS_STATS_TYPE_SPECIAL}, + {"linear pbuf count" , NSS_STATS_TYPE_SPECIAL}, + {"no pbuf to linear" , NSS_STATS_TYPE_SPECIAL}, + {"no enough room" , NSS_STATS_TYPE_SPECIAL}, + {"channel[0]" , NSS_STATS_TYPE_SPECIAL}, + {"channel[1]" , NSS_STATS_TYPE_SPECIAL}, + {"channel[2]" , NSS_STATS_TYPE_SPECIAL}, + {"channel[3]" , NSS_STATS_TYPE_SPECIAL}, + {"channel[4]" , NSS_STATS_TYPE_SPECIAL}, + {"channel[5]" , NSS_STATS_TYPE_SPECIAL}, + {"channel[6]" , NSS_STATS_TYPE_SPECIAL}, + {"channel[7]" , NSS_STATS_TYPE_SPECIAL}, + {"channel[8]" , NSS_STATS_TYPE_SPECIAL}, + {"channel[9]" , NSS_STATS_TYPE_SPECIAL}, + {"channel[10]" , NSS_STATS_TYPE_SPECIAL}, + {"channel[11]" , NSS_STATS_TYPE_SPECIAL}, + {"DMA full" , NSS_STATS_TYPE_SPECIAL} +}; + +/* + * nss_rmnet_rx_stats_get() + * Get rmnet_rx interface stats by interface number. + */ +static bool nss_rmnet_rx_stats_get(struct nss_ctx_instance *nss_ctx, uint32_t if_num, uint64_t *stats, bool is_base) +{ + int i; + uint32_t if_num_curr = if_num; + uint64_t *stats_local; + + if_num = if_num - NSS_DYNAMIC_IF_START; + + spin_lock_bh(&nss_rmnet_rx_lock); + if (!rmnet_rx_handle[if_num]) { + spin_unlock_bh(&nss_rmnet_rx_lock); + return false; + } + + if (if_num_curr == rmnet_rx_handle[if_num]->if_num_n2h) { + stats_local = rmnet_rx_handle[if_num]->stats_n2h; + } else { + stats_local = rmnet_rx_handle[if_num]->stats_h2n; + } + + for (i = 0; i < NSS_RMNET_RX_STATS_MAX; i++) { + stats[i] = stats_local[i]; + } + spin_unlock_bh(&nss_rmnet_rx_lock); + + return true; +} + +/* + * nss_rmnet_rx_stats_read() + * Read rmnet_rx statistics + */ +static ssize_t nss_rmnet_rx_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + struct nss_stats_data *data = fp->private_data; + struct nss_ctx_instance *nss_ctx = nss_rmnet_rx_get_context(); + int32_t if_num = NSS_DYNAMIC_IF_START; + int32_t max_if_num = if_num + NSS_MAX_DYNAMIC_INTERFACES; + uint32_t max_output_lines = ((NSS_RMNET_RX_STATS_MAX + 3) * NSS_MAX_DYNAMIC_INTERFACES) + + NSS_STATS_EXTRA_OUTPUT_LINES; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(!lbuf)) { + nss_warning("%px: Could not allocate memory for local statistics buffer", data); + return 0; + } + + stats_shadow = kzalloc(NSS_RMNET_RX_STATS_MAX * sizeof(uint64_t), GFP_KERNEL); + if (unlikely(!stats_shadow)) { + nss_warning("%px: Could not allocate memory for local shadow buffer", data); + kfree(lbuf); + return 0; + } + + if (data) { + if_num = data->if_num; + } + + if (if_num > max_if_num) { + return 0; + } + + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "rmnet_rx", NSS_STATS_SINGLE_CORE); + + /* + * Interface statistics for all interfaces. + */ + for (; if_num < max_if_num; if_num++) { + + if (!nss_rmnet_rx_stats_get(nss_ctx, if_num, stats_shadow, false)) { + continue; + } + + size_wr += nss_stats_print("rmnet_rx", "interface", if_num, + nss_rmnet_rx_stats_str, stats_shadow, NSS_RMNET_RX_STATS_MAX, + lbuf, size_wr, size_al); + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * nss_rmnet_rx_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(rmnet_rx) + +/* + * nss_rmnet_rx_stats_dentry_create() + * Create rmnet_rx statistics debug entry. + */ +void nss_rmnet_rx_stats_dentry_create(void) +{ + nss_stats_create_dentry("rmnet_rx", &nss_rmnet_rx_stats_ops); +} + +/* + * nss_rmnet_rx_stats_sync() + * Sync stats from the NSS FW + */ +void nss_rmnet_rx_stats_sync(struct nss_rmnet_rx_handle *handle, + struct nss_rmnet_rx_stats *nwis, uint32_t if_num) +{ + int i; + uint64_t *stats; + spin_lock_bh(&nss_rmnet_rx_lock); + if (if_num == handle->if_num_n2h) { + stats = handle->stats_n2h; + } else { + stats = handle->stats_h2n; + } + + stats[NSS_RMNET_RX_STATS_RX_PKTS] += nwis->node_stats.rx_packets; + stats[NSS_RMNET_RX_STATS_RX_BYTES] += nwis->node_stats.rx_bytes; + stats[NSS_RMNET_RX_STATS_TX_PKTS] += nwis->node_stats.tx_packets; + stats[NSS_RMNET_RX_STATS_TX_BYTES] += nwis->node_stats.tx_bytes; + + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + stats[NSS_RMNET_RX_STATS_QUEUE_0_DROPPED + i] += nwis->node_stats.rx_dropped[i]; + } + + stats[NSS_RMNET_RX_STATS_ENQUEUE_FAILED] += nwis->enqueue_failed; + stats[NSS_RMNET_RX_STATS_NO_AVAIL_CHANNEL] += nwis->no_avail_channel; + stats[NSS_RMNET_RX_STATS_NUM_LINEAR_PBUF] += nwis->num_linear_pbuf; + stats[NSS_RMNET_RX_STATS_NO_PBUF_TO_LINEAR] += nwis->no_pbuf_to_linear; + stats[NSS_RMNET_RX_STATS_NO_ENOUGH_ROOM] += nwis->no_enough_room; + + for (i = 0; i < NSS_RMNET_RX_CHANNEL_MAX; i++) { + stats[NSS_RMNET_RX_STATS_USING_CHANNEL0 + i] += nwis->using_channel[i]; + } + + stats[NSS_RMNET_RX_STATS_DMA_FAILED] += nwis->dma_failed; + spin_unlock_bh(&nss_rmnet_rx_lock); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_rmnet_rx_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_rmnet_rx_stats.h new file mode 100644 index 000000000..638593a6c --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_rmnet_rx_stats.h @@ -0,0 +1,61 @@ +/* + ****************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_RMNET_RX_STATS_H +#define __NSS_RMNET_RX_STATS_H + +/* + * rmnet_rx interface statistics types. + */ +enum nss_rmnet_rx_stats_types { + NSS_RMNET_RX_STATS_RX_PKTS, + NSS_RMNET_RX_STATS_RX_BYTES, + NSS_RMNET_RX_STATS_TX_PKTS, + NSS_RMNET_RX_STATS_TX_BYTES, + NSS_RMNET_RX_STATS_QUEUE_0_DROPPED, + NSS_RMNET_RX_STATS_QUEUE_1_DROPPED, + NSS_RMNET_RX_STATS_QUEUE_2_DROPPED, + NSS_RMNET_RX_STATS_QUEUE_3_DROPPED, + NSS_RMNET_RX_STATS_ENQUEUE_FAILED, + NSS_RMNET_RX_STATS_NO_AVAIL_CHANNEL, + NSS_RMNET_RX_STATS_NUM_LINEAR_PBUF, + NSS_RMNET_RX_STATS_NO_PBUF_TO_LINEAR, + NSS_RMNET_RX_STATS_NO_ENOUGH_ROOM, + NSS_RMNET_RX_STATS_USING_CHANNEL0, + NSS_RMNET_RX_STATS_USING_CHANNEL1, + NSS_RMNET_RX_STATS_USING_CHANNEL2, + NSS_RMNET_RX_STATS_USING_CHANNEL3, + NSS_RMNET_RX_STATS_USING_CHANNEL4, + NSS_RMNET_RX_STATS_USING_CHANNEL5, + NSS_RMNET_RX_STATS_USING_CHANNEL6, + NSS_RMNET_RX_STATS_USING_CHANNEL7, + NSS_RMNET_RX_STATS_USING_CHANNEL8, + NSS_RMNET_RX_STATS_USING_CHANNEL9, + NSS_RMNET_RX_STATS_USING_CHANNEL10, + NSS_RMNET_RX_STATS_USING_CHANNEL11, + NSS_RMNET_RX_STATS_DMA_FAILED, + NSS_RMNET_RX_STATS_MAX, +}; + +/* + * Virtual interface statistics APIs + */ +extern void nss_rmnet_rx_stats_sync(struct nss_rmnet_rx_handle *handle, struct nss_rmnet_rx_stats *nwis, uint32_t if_num); +extern void nss_rmnet_rx_stats_dentry_create(void); + +#endif /* __NSS_RMNET_RX_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_rps.c b/feeds/ipq807x/qca-nss-drv/src/nss_rps.c new file mode 100644 index 000000000..59a4e72d6 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_rps.c @@ -0,0 +1,638 @@ +/* + ************************************************************************** + * Copyright (c) 2013-2017, 2019-2020 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_rps.c + * NSS RPS based APIs + */ + +#include "nss_tx_rx_common.h" + +#define NSS_RPS_MAX_CORE_HASH_BITMAP ((1 << (NSS_HOST_CORES)) - 1) + /**< Maximum value that when all cores are available. */ +#define NSS_RPS_PRI_MAP_PARAM_FIELD_COUNT 2 + +int nss_rps_config __read_mostly; +int nss_rps_hash_bitmap = NSS_RPS_MAX_CORE_HASH_BITMAP; +int nss_rps_pri_map[NSS_MAX_NUM_PRI]; + +/* + * It is used to parse priority and core from the input. + */ +struct nss_rps_pri_map_parse_data { + uint8_t pri; /**< Priority Index. */ + int8_t core; /**< Host core-id. */ +}; + +/* + * Private data structure. + */ +struct nss_rps_pvt { + struct semaphore sem; /* Semaphore structure. */ + struct completion complete; /* Completion structure. */ + int response; /* Response from FW. */ + void *cb; /* Original cb for sync msgs. */ + void *app_data; /* Original app_data for sync msgs. */ +}; + +static struct nss_rps_pvt nss_rps_cfg_pvt; + +/* + * nss_rps_pri_map_usage() + * Help function shows the usage of the command. + */ +static inline void nss_rps_pri_map_usage(void) +{ + nss_info_always("\nUsage:\n"); + nss_info_always("echo > /proc/sys/dev/nss/rps/pri_map\n\n"); + nss_info_always("priority[0 to %u] core[-1 to %u]:\n\n", + NSS_MAX_NUM_PRI - 1, + NSS_HOST_CORES - 1); +} + +/* + * nss_rps_pri_map_print() + * Sysctl handler for printing rps/pri mapping. + */ +static int nss_rps_pri_map_print(struct ctl_table *ctl, void __user *buffer, + size_t *lenp, loff_t *ppos, int *pri_map) +{ + char *r_buf; + int i, len; + size_t cp_bytes = 0; + + /* + * (2 * 4) + 12 bytes for the buffer size is sufficient to write + * the table including the spaces and new line characters. + */ + r_buf = kzalloc(((4 * NSS_MAX_NUM_PRI) + 12) * sizeof(char), + GFP_KERNEL); + if (!r_buf) { + nss_warning("Failed to alloc buffer to print pri map\n"); + return -EFAULT; + } + + /* + * Write the core values that corresponds to each priorities. + */ + len = scnprintf(r_buf + cp_bytes, 8, "Cores: "); + cp_bytes += len; + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + len = scnprintf(r_buf + cp_bytes, 4, "%d ", pri_map[i]); + if (!len) { + nss_warning("failed to read from buffer %d\n", pri_map[i]); + kfree(r_buf); + return -EFAULT; + } + cp_bytes += len; + } + + /* + * Add new line character at the end. + */ + len = scnprintf(r_buf + cp_bytes, 4, "\n"); + cp_bytes += len; + + cp_bytes = simple_read_from_buffer(buffer, *lenp, ppos, r_buf, cp_bytes); + *lenp = cp_bytes; + kfree(r_buf); + return 0; +} + +/* + * nss_rps_pri_map_parse() + * Sysctl handler for rps/pri mappings. + */ +static int nss_rps_pri_map_parse(struct ctl_table *ctl, void __user *buffer, + size_t *lenp, loff_t *ppos, struct nss_rps_pri_map_parse_data *out) +{ + size_t cp_bytes = 0; + char w_buf[5]; + loff_t w_offset = 0; + char *str; + unsigned int pri; + int core, res; + + /* + * Buffer length cannot be different than 4 or 5. + */ + if (*lenp < 4 || *lenp > 5) { + nss_warning("Buffer is not correct. Invalid lenght: %d\n", (int)*lenp); + return -EINVAL; + } + + /* + * It's a write operation + */ + cp_bytes = simple_write_to_buffer(w_buf, *lenp, &w_offset, buffer, 5); + if (cp_bytes != *lenp) { + nss_warning("failed to write to buffer\n"); + return -EFAULT; + } + + str = w_buf; + res = sscanf(str, "%u %d", &pri, &core); + if (res != NSS_RPS_PRI_MAP_PARAM_FIELD_COUNT) { + nss_warning("failed to read the buffer\n"); + return -EFAULT; + } + /* + * pri value cannot be higher than NSS_MAX_NUM_PRI. + */ + if (pri >= NSS_MAX_NUM_PRI) { + nss_warning("invalid pri value: %d\n", pri); + return -EINVAL; + } + + /* + * Host core must be less than NSS_HOST_CORE. + */ + if (core >= NSS_HOST_CORES || core < NSS_N2H_RPS_PRI_DEFAULT) { + nss_warning("invalid priority value: %d\n", core); + return -EINVAL; + } + + nss_info("priority: %d core: %d\n", pri, core); + + out->pri = pri; + out->core = core; + return 0; +} + +/* + * nss_rps_cfg_callback() + * Callback function for rps configuration. + */ +static void nss_rps_cfg_callback(void *app_data, struct nss_n2h_msg *nnm) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)app_data; + if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) { + + /* + * Error, hence we are not updating the nss_rps + * Send a FAILURE to restore the current value + * to its previous state. + */ + nss_rps_cfg_pvt.response = NSS_FAILURE; + complete(&nss_rps_cfg_pvt.complete); + nss_warning("%px: RPS configuration failed : %d\n", nss_ctx, + nnm->cm.error); + return; + } + + nss_info("%px: RPS configuration succeeded: %d\n", nss_ctx, + nnm->cm.error); + nss_ctx->rps_en = nnm->msg.rps_cfg.enable; + nss_rps_cfg_pvt.response = NSS_SUCCESS; + complete(&nss_rps_cfg_pvt.complete); +} + +/* + * nss_rps_pri_map_cfg_callback() + * Callback function for rps pri map configuration. + */ +static void nss_rps_pri_map_cfg_callback(void *app_data, struct nss_n2h_msg *nnm) +{ + if (nnm->cm.response != NSS_CMN_RESPONSE_ACK) { + + /* + * Error, hence we are not updating the nss_pri_map + * Send a failure to restore the current value + * to its previous state. + */ + nss_rps_cfg_pvt.response = NSS_FAILURE; + complete(&nss_rps_cfg_pvt.complete); + nss_warning("%px: RPS pri_map configuration failed : %d\n", + app_data, nnm->cm.error); + return; + } + + nss_info("%px: RPS pri_map configuration succeeded: %d\n", + app_data, nnm->cm.error); + + nss_rps_cfg_pvt.response = NSS_SUCCESS; + complete(&nss_rps_cfg_pvt.complete); +} + +/* + * nss_rps_cfg() + * Send Message to NSS to enable RPS. + */ +static nss_tx_status_t nss_rps_cfg(struct nss_ctx_instance *nss_ctx, int enable_rps) +{ + struct nss_n2h_msg nnm; + nss_tx_status_t nss_tx_status; + int ret; + + down(&nss_rps_cfg_pvt.sem); + nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_TX_METADATA_TYPE_N2H_RPS_CFG, + sizeof(struct nss_n2h_rps), + nss_rps_cfg_callback, + (void *)nss_ctx); + + nnm.msg.rps_cfg.enable = enable_rps; + + nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm); + + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: nss_tx error setting rps\n", nss_ctx); + + up(&nss_rps_cfg_pvt.sem); + return NSS_FAILURE; + } + + /* + * Blocking call, wait till we get ACK for this msg. + */ + ret = wait_for_completion_timeout(&nss_rps_cfg_pvt.complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT)); + if (ret == 0) { + nss_warning("%px: Waiting for ack timed out\n", nss_ctx); + up(&nss_rps_cfg_pvt.sem); + return NSS_FAILURE; + } + + /* + * ACK/NACK received from NSS FW + * If NACK: Handler function will restore nss_rps_config + * to previous state. + */ + if (NSS_FAILURE == nss_rps_cfg_pvt.response) { + up(&nss_rps_cfg_pvt.sem); + return NSS_FAILURE; + } + + up(&nss_rps_cfg_pvt.sem); + return NSS_SUCCESS; +} + +/* + * nss_rps_ipv4_hash_bitmap_cfg() + * Send Message to NSS to configure hash_bitmap. + */ +static nss_tx_status_t nss_rps_ipv4_hash_bitmap_cfg(struct nss_ctx_instance *nss_ctx, int hash_bitmap) +{ + struct nss_ipv4_msg nim; + nss_tx_status_t nss_tx_status; + + down(&nss_rps_cfg_pvt.sem); + nss_ipv4_msg_init(&nim, NSS_IPV4_RX_INTERFACE, NSS_IPV4_TX_RPS_HASH_BITMAP_CFG_MSG, + sizeof(struct nss_ipv4_rps_hash_bitmap_cfg_msg), + NULL, NULL); + + nim.msg.rps_hash_bitmap.hash_bitmap = hash_bitmap; + + nss_tx_status = nss_ipv4_tx_sync(nss_ctx, &nim); + + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: nss_tx error setting rps\n", nss_ctx); + + up(&nss_rps_cfg_pvt.sem); + return NSS_FAILURE; + } + + up(&nss_rps_cfg_pvt.sem); + return NSS_SUCCESS; +} + +/* + * nss_rps_ipv6_hash_bitmap_cfg() + * Send Message to NSS to configure hash_bitmap. + */ +static nss_tx_status_t nss_rps_ipv6_hash_bitmap_cfg(struct nss_ctx_instance *nss_ctx, int hash_bitmap) +{ + struct nss_ipv6_msg nim; + nss_tx_status_t nss_tx_status; + + down(&nss_rps_cfg_pvt.sem); + nss_ipv6_msg_init(&nim, NSS_IPV6_RX_INTERFACE, NSS_IPV6_TX_RPS_HASH_BITMAP_CFG_MSG, + sizeof(struct nss_ipv4_rps_hash_bitmap_cfg_msg), + NULL, NULL); + + nim.msg.rps_hash_bitmap.hash_bitmap = hash_bitmap; + + nss_tx_status = nss_ipv6_tx_sync(nss_ctx, &nim); + + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: nss_tx error setting rps\n", nss_ctx); + + up(&nss_rps_cfg_pvt.sem); + return NSS_FAILURE; + } + + up(&nss_rps_cfg_pvt.sem); + return NSS_SUCCESS; +} + +/* + * nss_rps_pri_map_cfg() + * Send Message to NSS to configure pri_map. + */ +static nss_tx_status_t nss_rps_pri_map_cfg(struct nss_ctx_instance *nss_ctx, int *pri_map) +{ + struct nss_n2h_msg nnm; + struct nss_n2h_rps_pri_map *rps_pri_map; + nss_tx_status_t nss_tx_status; + int ret, i; + + down(&nss_rps_cfg_pvt.sem); + nss_n2h_msg_init(&nnm, NSS_N2H_INTERFACE, NSS_TX_METADATA_TYPE_N2H_RPS_PRI_MAP_CFG, + sizeof(struct nss_n2h_rps_pri_map), + nss_rps_pri_map_cfg_callback, + (void *)nss_ctx); + + rps_pri_map = &nnm.msg.rps_pri_map; + + /* + * Fill entries at pri_map. + */ + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + rps_pri_map->pri_map[i] = pri_map[i]; + } + + nss_tx_status = nss_n2h_tx_msg(nss_ctx, &nnm); + + if (nss_tx_status != NSS_TX_SUCCESS) { + nss_warning("%px: nss_tx error setting rps\n", nss_ctx); + + up(&nss_rps_cfg_pvt.sem); + return NSS_FAILURE; + } + + /* + * Blocking call, wait till we get ACK for this msg. + */ + ret = wait_for_completion_timeout(&nss_rps_cfg_pvt.complete, msecs_to_jiffies(NSS_CONN_CFG_TIMEOUT)); + if (ret == 0) { + nss_warning("%px: Waiting for ack timed out\n", nss_ctx); + up(&nss_rps_cfg_pvt.sem); + return NSS_FAILURE; + } + + /* + * ACK/NACK received from NSS FW + * If NACK: Handler function will restore nss_rps_config + * to previous state. + */ + if (NSS_FAILURE == nss_rps_cfg_pvt.response) { + up(&nss_rps_cfg_pvt.sem); + return NSS_FAILURE; + } + + up(&nss_rps_cfg_pvt.sem); + return NSS_SUCCESS; +} + +/* + * nss_rps_cfg_handler() + * Enable NSS RPS. + */ +static int nss_rps_cfg_handler(struct ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx; + int ret, ret_rps, current_state, i; + current_state = nss_rps_config; + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + + if (ret != NSS_SUCCESS) { + return ret; + } + + if (!write) { + return ret; + } + + if (nss_rps_config == 0) { + nss_info_always("Runtime disabling of NSS RPS not supported\n"); + return ret; + } + + if (nss_rps_config != 1) { + nss_info_always("Invalid input value. Valid values are 0 and 1\n"); + return ret; + } + + for (i = 0; i < nss_top_main.num_nss; i++) { + nss_ctx = &nss_top->nss[i]; + nss_info("Enabling NSS RPS\n"); + ret_rps = nss_rps_cfg(nss_ctx, 1); + + /* + * In here, we also need to revert the state of the previously enabled cores. + * However, runtime disabling is currently not supported since queues are not + * flushed in NSS FW. + * TODO: Flush queues in NSS FW. + */ + if (ret_rps != NSS_SUCCESS) { + nss_warning("%px: rps enabling failed\n", nss_ctx); + nss_rps_config = current_state; + return ret_rps; + } + } + return NSS_SUCCESS; +} + +/* + * nss_rps_hash_bitmap_cfg_handler() + * Configure NSS rps_hash_bitmap + */ +static int nss_rps_hash_bitmap_cfg_handler(struct ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[0]; + int ret, ret_ipv4, ret_ipv6, current_state; + + current_state = nss_rps_hash_bitmap; + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + + if (ret != NSS_SUCCESS) { + nss_rps_hash_bitmap = current_state; + return ret; + } + + if (!write) { + return ret; + } + + if (nss_rps_hash_bitmap <= (NSS_RPS_MAX_CORE_HASH_BITMAP)) { + nss_info("Configuring NSS RPS hash_bitmap\n"); + ret_ipv4 = nss_rps_ipv4_hash_bitmap_cfg(nss_ctx, nss_rps_hash_bitmap); + + if (ret_ipv4 != NSS_SUCCESS) { + nss_warning("%px: ipv4 hash_bitmap config message failed\n", nss_ctx); + nss_rps_hash_bitmap = current_state; + return ret_ipv4; + } + + ret_ipv6 = nss_rps_ipv6_hash_bitmap_cfg(nss_ctx, nss_rps_hash_bitmap); + + if (ret_ipv6 != NSS_SUCCESS) { + nss_warning("%px: ipv6 hash_bitmap config message failed\n", nss_ctx); + nss_rps_hash_bitmap = current_state; + if (nss_rps_ipv4_hash_bitmap_cfg(nss_ctx, nss_rps_hash_bitmap != NSS_SUCCESS)) { + nss_warning("%px: ipv4 and ipv6 have different hash_bitmaps.\n", nss_ctx); + } + return ret_ipv6; + } + + return 0; + } + + nss_info_always("Invalid input value. Valid values are less than %d\n", (NSS_RPS_MAX_CORE_HASH_BITMAP)); + return ret; +} + +/* nss_rps_pri_map_cfg_handler() + * Configure NSS rps_pri_map + */ +static int nss_rps_pri_map_cfg_handler(struct ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx = &nss_top->nss[0]; + + int ret, ret_pri_map; + struct nss_rps_pri_map_parse_data out, current_state; + if (!write) { + return nss_rps_pri_map_print(ctl, buffer, lenp, ppos, nss_rps_pri_map); + } + + ret = nss_rps_pri_map_parse(ctl, buffer, lenp, ppos, &out); + + if (ret != NSS_SUCCESS) { + nss_rps_pri_map_usage(); + return ret; + } + + nss_info("Configuring NSS RPS Priority Map\n"); + current_state.pri = out.pri; + current_state.core = nss_rps_pri_map[out.pri]; + nss_rps_pri_map[out.pri] = out.core; + ret_pri_map = nss_rps_pri_map_cfg(nss_ctx, nss_rps_pri_map); + if (ret_pri_map != NSS_SUCCESS) { + nss_rps_pri_map[current_state.pri] = current_state.core; + nss_warning("%px: pri_map config message failed\n", nss_ctx); + } + + return ret_pri_map; +} + +static struct ctl_table nss_rps_table[] = { + { + .procname = "enable", + .data = &nss_rps_config, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_rps_cfg_handler, + }, + { + .procname = "hash_bitmap", + .data = &nss_rps_hash_bitmap, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_rps_hash_bitmap_cfg_handler, + }, + { + .procname = "pri_map", + .data = &nss_rps_pri_map[NSS_MAX_NUM_PRI], + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_rps_pri_map_cfg_handler, + }, + { } +}; + +static struct ctl_table nss_rps_dir[] = { + { + .procname = "rps", + .mode = 0555, + .child = nss_rps_table, + }, + { } +}; + +static struct ctl_table nss_rps_root_dir[] = { + { + .procname = "nss", + .mode = 0555, + .child = nss_rps_dir, + }, + { } +}; + +static struct ctl_table nss_rps_root[] = { + { + .procname = "dev", + .mode = 0555, + .child = nss_rps_root_dir, + }, + { } +}; + +static struct ctl_table_header *nss_rps_header; + +/* + * nss_rps_pri_map_init_handler() + * Initialize pri_map for priority based rps selection. + */ +void nss_rps_pri_map_init_handler(void) +{ + int i; + + /* + Initialize the mapping table with the default values. + */ + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + nss_rps_pri_map[i] = NSS_N2H_RPS_PRI_DEFAULT; + } + +} + +/* + * nss_rps_register_sysctl() + */ +void nss_rps_register_sysctl(void) +{ + + /* + * rps sema init. + */ + sema_init(&nss_rps_cfg_pvt.sem, 1); + init_completion(&nss_rps_cfg_pvt.complete); + + nss_rps_pri_map_init_handler(); + + /* + * Register sysctl table. + */ + nss_rps_header = register_sysctl_table(nss_rps_root); +} + +/* + * nss_rps_unregister_sysctl() + * Unregister sysctl specific to rps + */ +void nss_rps_unregister_sysctl(void) +{ + /* + * Unregister sysctl table. + */ + if (nss_rps_header) { + unregister_sysctl_table(nss_rps_header); + } +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_shaper.c b/feeds/ipq807x/qca-nss-drv/src/nss_shaper.c new file mode 100644 index 000000000..2726b8ba5 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_shaper.c @@ -0,0 +1,367 @@ +/* + ************************************************************************** + * Copyright (c) 2014, 2016-2020 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" + +/* + * nss_shaper_register_shaping() + * Register to obtain an NSS context for basic shaping operations + */ +void *nss_shaper_register_shaping(void) +{ + if (nss_top_main.shaping_handler_id == (uint8_t)-1) { + nss_warning("%px: SHAPING IS NOT ENABLED", __func__); + return NULL; + } + return (void *)&nss_top_main.nss[nss_top_main.shaping_handler_id]; +} + +/* + * nss_shaper_unregister_shaping() + * Unregister an NSS shaping context + */ +void nss_shaper_unregister_shaping(void *nss_ctx) +{ +} + +/* + * nss_shaper_register_shaper_bounce_interface() + * Register for performing shaper bounce operations for interface shaper + */ +void *nss_shaper_register_shaper_bounce_interface(uint32_t if_num, nss_shaper_bounced_callback_t cb, void *app_data, struct module *owner) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_shaper_bounce_registrant *reg; + + nss_info("Shaper bounce interface register: %u, cb: %px, app_data: %px, owner: %px", + if_num, cb, app_data, owner); + + /* + * Must be valid interface number + */ + if (if_num >= NSS_MAX_NET_INTERFACES) { + nss_warning("Invalid if_num: %u", if_num); + BUG_ON(false); + } + + /* + * Shaping enabled? + */ + if (nss_top_main.shaping_handler_id == (uint8_t)-1) { + nss_warning("%px: SHAPING IS NOT ENABLED", __func__); + return NULL; + } + + /* + * Can we hold the module? + */ + if (!try_module_get(owner)) { + nss_warning("%px: Unable to hold owner", __func__); + return NULL; + } + + spin_lock_bh(&nss_top->lock); + + /* + * Must not have existing registrant + */ + reg = &nss_top->bounce_interface_registrants[if_num]; + if (reg->registered) { + spin_unlock_bh(&nss_top->stats_lock); + module_put(owner); + nss_warning("Already registered: %u", if_num); + BUG_ON(false); + } + + /* + * Register + */ + reg->bounced_callback = cb; + reg->app_data = app_data; + reg->owner = owner; + reg->registered = true; + spin_unlock_bh(&nss_top->lock); + + return (void *)&nss_top->nss[nss_top->shaping_handler_id]; +} + +/* + * nss_shaper_unregister_shaper_bounce_interface() + * Unregister for shaper bounce operations for interface shaper + */ +void nss_shaper_unregister_shaper_bounce_interface(uint32_t if_num) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_shaper_bounce_registrant *reg; + struct module *owner; + + nss_info("Shaper bounce interface unregister: %u", if_num); + + /* + * Must be valid interface number + */ + if (if_num >= NSS_MAX_NET_INTERFACES) { + nss_warning("Invalid if_num: %u", if_num); + BUG_ON(false); + } + + spin_lock_bh(&nss_top->lock); + + /* + * Must have existing registrant + */ + reg = &nss_top->bounce_interface_registrants[if_num]; + if (!reg->registered) { + spin_unlock_bh(&nss_top->stats_lock); + nss_warning("Already unregistered: %u", if_num); + BUG_ON(false); + } + + /* + * Unegister + */ + owner = reg->owner; + reg->owner = NULL; + reg->registered = false; + spin_unlock_bh(&nss_top->lock); + + module_put(owner); +} + +/* + * nss_shaper_register_shaper_bounce_bridge() + * Register for performing shaper bounce operations for bridge shaper + */ +void *nss_shaper_register_shaper_bounce_bridge(uint32_t if_num, nss_shaper_bounced_callback_t cb, void *app_data, struct module *owner) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_ctx_instance *nss_ctx; + struct nss_shaper_bounce_registrant *reg; + + nss_info("Shaper bounce bridge register: %u, cb: %px, app_data: %px, owner: %px", + if_num, cb, app_data, owner); + + /* + * Must be valid interface number + */ + if (if_num >= NSS_MAX_NET_INTERFACES) { + nss_warning("Invalid if_num: %u", if_num); + BUG_ON(false); + } + + /* + * Shaping enabled? + */ + if (nss_top_main.shaping_handler_id == (uint8_t)-1) { + nss_warning("%px: SHAPING IS NOT ENABLED", __func__); + return NULL; + } + + /* + * Can we hold the module? + */ + if (!try_module_get(owner)) { + nss_warning("%px: Unable to hold owner", __func__); + return NULL; + } + + spin_lock_bh(&nss_top->lock); + + /* + * Must not have existing registrant + */ + reg = &nss_top->bounce_bridge_registrants[if_num]; + if (reg->registered) { + spin_unlock_bh(&nss_top->stats_lock); + module_put(owner); + nss_warning("Already registered: %u", if_num); + BUG_ON(false); + } + + /* + * Register + */ + reg->bounced_callback = cb; + reg->app_data = app_data; + reg->owner = owner; + reg->registered = true; + spin_unlock_bh(&nss_top->lock); + + nss_ctx = &nss_top->nss[nss_top->shaping_handler_id]; + return (void *)nss_ctx; +} + +/* + * nss_shaper_unregister_shaper_bounce_bridge() + * Unregister for shaper bounce operations for bridge shaper + */ +void nss_shaper_unregister_shaper_bounce_bridge(uint32_t if_num) +{ + struct nss_top_instance *nss_top = &nss_top_main; + struct nss_shaper_bounce_registrant *reg; + struct module *owner; + + nss_info("Shaper bounce bridge unregister: %u", if_num); + + /* + * Must be valid interface number + */ + if (if_num >= NSS_MAX_NET_INTERFACES) { + nss_warning("Invalid if_num: %u", if_num); + BUG_ON(false); + } + + spin_lock_bh(&nss_top->lock); + + /* + * Must have existing registrant + */ + reg = &nss_top->bounce_bridge_registrants[if_num]; + if (!reg->registered) { + spin_unlock_bh(&nss_top->stats_lock); + nss_warning("Already unregistered: %u", if_num); + BUG_ON(false); + } + + /* + * Wait until any bounce callback that is active is finished + */ + while (reg->callback_active) { + spin_unlock_bh(&nss_top->stats_lock); + yield(); + spin_lock_bh(&nss_top->stats_lock); + } + + /* + * Unegister + */ + owner = reg->owner; + reg->owner = NULL; + reg->registered = false; + spin_unlock_bh(&nss_top->lock); + + module_put(owner); +} + +/* + * nss_shaper_bounce_interface_packet() + * Bounce a packet to the NSS for interface shaping. + * + * You must have registered for interface bounce shaping to call this. + */ +nss_tx_status_t nss_shaper_bounce_interface_packet(void *ctx, uint32_t if_num, struct sk_buff *skb) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)ctx; + struct nss_top_instance *nss_top = nss_ctx->nss_top; + struct nss_shaper_bounce_registrant *reg; + int32_t status; + + /* + * Must be valid interface number + */ + if (if_num >= NSS_MAX_NET_INTERFACES) { + nss_warning("Invalid if_num: %u", if_num); + BUG_ON(false); + } + + /* + * Must have existing registrant + */ + spin_lock_bh(&nss_top->lock); + reg = &nss_top->bounce_interface_registrants[if_num]; + if (!reg->registered) { + spin_unlock_bh(&nss_top->stats_lock); + nss_warning("unregistered: %u", if_num); + return NSS_TX_FAILURE; + } + spin_unlock_bh(&nss_top->lock); + + status = nss_core_send_buffer(nss_ctx, if_num, skb, NSS_IF_H2N_DATA_QUEUE, + H2N_BUFFER_SHAPER_BOUNCE_INTERFACE, 0); + if (status != NSS_CORE_STATUS_SUCCESS) { + return NSS_TX_FAILURE; + } + nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_DATA_COMMAND_QUEUE); + + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_TX_PACKET]); + return NSS_TX_SUCCESS; +} + +/* + * nss_shaper_bounce_bridge_packet() + * Bounce a packet to the NSS for bridge shaping. + * + * You must have registered for bridge bounce shaping to call this. + */ +nss_tx_status_t nss_shaper_bounce_bridge_packet(void *ctx, uint32_t if_num, struct sk_buff *skb) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)ctx; + struct nss_top_instance *nss_top = nss_ctx->nss_top; + struct nss_shaper_bounce_registrant *reg; + int32_t status; + + /* + * Must be valid interface number + */ + if (if_num >= NSS_MAX_NET_INTERFACES) { + nss_warning("Invalid if_num: %u", if_num); + BUG_ON(false); + } + + /* + * Must have existing registrant + */ + spin_lock_bh(&nss_top->lock); + reg = &nss_top->bounce_bridge_registrants[if_num]; + if (!reg->registered) { + spin_unlock_bh(&nss_top->stats_lock); + nss_warning("unregistered: %u", if_num); + return NSS_TX_FAILURE; + } + spin_unlock_bh(&nss_top->lock); + + nss_info("%s: Bridge bounce skb: %px, if_num: %u, ctx: %px", __func__, skb, if_num, nss_ctx); + status = nss_core_send_buffer(nss_ctx, if_num, skb, NSS_IF_H2N_DATA_QUEUE, + H2N_BUFFER_SHAPER_BOUNCE_BRIDGE, 0); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_info("%s: Bridge bounce core send rejected", __func__); + return NSS_TX_FAILURE; + } + nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_DATA_COMMAND_QUEUE); + + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_TX_PACKET]); + return NSS_TX_SUCCESS; +} + +/* + * nss_shaper_get_device() + * Gets the original device from probe. + */ +struct device *nss_shaper_get_dev(void) +{ + struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[nss_top_main.shaping_handler_id]; + return nss_ctx->dev; +} + +EXPORT_SYMBOL(nss_shaper_bounce_bridge_packet); +EXPORT_SYMBOL(nss_shaper_bounce_interface_packet); +EXPORT_SYMBOL(nss_shaper_unregister_shaper_bounce_interface); +EXPORT_SYMBOL(nss_shaper_register_shaper_bounce_interface); +EXPORT_SYMBOL(nss_shaper_unregister_shaper_bounce_bridge); +EXPORT_SYMBOL(nss_shaper_register_shaper_bounce_bridge); +EXPORT_SYMBOL(nss_shaper_register_shaping); +EXPORT_SYMBOL(nss_shaper_unregister_shaping); +EXPORT_SYMBOL(nss_shaper_get_dev); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_sjack.c b/feeds/ipq807x/qca-nss-drv/src/nss_sjack.c new file mode 100644 index 000000000..086eedfea --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_sjack.c @@ -0,0 +1,189 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_sjack_stats.h" +#include "nss_sjack_log.h" + +/* + * nss_sjack_handler() + * Handle NSS -> HLOS messages for sjack + */ +static void nss_sjack_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, + __attribute__((unused))void *app_data) +{ + void *ctx; + nss_sjack_msg_callback_t cb; + struct nss_sjack_msg *nsm = (struct nss_sjack_msg *)ncm; + + BUG_ON(ncm->interface != NSS_SJACK_INTERFACE); + + /* + * Trace Messages + */ + nss_sjack_log_rx_msg(nsm); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_SJACK_MAX_MSG_TYPE) { + nss_warning("%px: received invalid message %d for sjack interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_sjack_msg)) { + nss_warning("%px: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Update the callback and app_data for NOTIFY messages, sjack sends all notify messages + * to the same callback/app_data. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_core_get_msg_handler(nss_ctx, ncm->interface); + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + switch (ncm->type) { + case NSS_SJACK_STATS_SYNC_MSG: + /* + * Update sjack statistics on node sync. + */ + nss_sjack_stats_node_sync(nss_ctx, &nsm->msg.stats_sync); + break; + } + + /* + * Do we have a call back + */ + if (!ncm->cb) { + return; + } + + /* + * callback + */ + cb = (nss_sjack_msg_callback_t)ncm->cb; + ctx = nss_ctx->subsys_dp_register[ncm->interface].ndev; + + cb(ctx, ncm); +} + +/* + * nss_sjack_tx_msg() + * Transmit a sjack message to NSSFW + */ +nss_tx_status_t nss_sjack_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_sjack_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Trace Messages + */ + nss_sjack_log_tx_msg(msg); + + /* + * Sanity check the message + */ + if (ncm->interface != NSS_SJACK_INTERFACE) { + nss_warning("%px: tx request for another interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type > NSS_SJACK_MAX_MSG_TYPE) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} + +/* + * nss_sjack_register_if() + */ +struct nss_ctx_instance *nss_sjack_register_if(uint32_t if_num, struct net_device *netdev, + nss_sjack_msg_callback_t event_callback) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.sjack_handler_id]; + uint32_t status; + + nss_assert(nss_ctx); + nss_assert(if_num == NSS_SJACK_INTERFACE); + + nss_core_register_subsys_dp(nss_ctx, if_num, NULL, NULL, NULL, netdev, 0); + + status = nss_core_register_msg_handler(nss_ctx, NSS_SJACK_INTERFACE, event_callback); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Not able to register handler for interface %d with NSS core\n", nss_ctx, if_num); + return NULL; + } + + return nss_ctx; +} + +/* + * nss_sjack_unregister_if() + */ +void nss_sjack_unregister_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.sjack_handler_id]; + uint32_t status; + + nss_assert(nss_ctx); + nss_assert(if_num == NSS_SJACK_INTERFACE); + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + + status = nss_core_unregister_msg_handler(nss_ctx, if_num); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Not able to unregister handler for interface %d with NSS core\n", nss_ctx, if_num); + return; + } + + return; +} + +/* + * nss_sjack_get_context() + * get NSS context instance for sjack + */ +struct nss_ctx_instance *nss_sjack_get_context(void) +{ + return &nss_top_main.nss[nss_top_main.sjack_handler_id]; +} +EXPORT_SYMBOL(nss_sjack_get_context); + +/* + * nss_sjack_register_handler() + * Registering handler for sending msg to sjack node on NSS. + */ +void nss_sjack_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx = nss_sjack_get_context(); + + nss_core_register_handler(nss_ctx, NSS_SJACK_INTERFACE, nss_sjack_handler, NULL); + + nss_sjack_stats_dentry_create(); +} + +EXPORT_SYMBOL(nss_sjack_register_if); +EXPORT_SYMBOL(nss_sjack_unregister_if); +EXPORT_SYMBOL(nss_sjack_tx_msg); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_sjack_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_sjack_log.c new file mode 100644 index 000000000..c585b7483 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_sjack_log.c @@ -0,0 +1,133 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_sjack_log.c + * NSS SJACK logger file. + */ + +#include "nss_core.h" + +/* + * nss_sjack_log_message_types_str + * NSS SJACK message strings + */ +static int8_t *nss_sjack_log_message_types_str[NSS_SJACK_MAX_MSG_TYPE] __maybe_unused = { + "SJACK Configure", + "SJACK Unconfigure", + "SJACK Stats", +}; + +/* + * nss_sjack_log_configure_msg() + * Log NSS SJACK Configure. + */ +static void nss_sjack_log_configure_msg(struct nss_sjack_msg *nsm) +{ + struct nss_sjack_configure_msg *nscm __maybe_unused = &nsm->msg.configure; + nss_trace("%px: NSS SJACK Configure message \n" + "SJACK Ingress Interface Number: %d\n" + "SJACK Engress Interface Number: %d\n" + "SJACK Tunnel ID: %d\n" + "SJACK DSCP Value: %d\n" + "SJACK GRE Priority: %d\n" + "SJACK GRE Flags: %d\n" + "SJACK IPSEC SA Pattern Flag: %d\n", + nscm, nscm->ingress_if_num, + nscm->egress_if_num, nscm->tunnel_id, + nscm->ip_dscp, nscm->gre_prio, + nscm->gre_flags, nscm->use_ipsec_sa_pattern); +} + +/* + * nss_sjack_log_unconfigure_msg() + * Log NSS SJACK Unconfigure. + */ +static void nss_sjack_log_unconfigure_msg(struct nss_sjack_msg *nsm) +{ + struct nss_sjack_unconfigure_msg *nsum __maybe_unused = &nsm->msg.unconfigure; + nss_trace("%px: NSS SJACK UnConfigure message \n" + "SJACK Ingress Interface Number: %d\n", + nsum, nsum->ingress_if_num); +} + +/* + * nss_sjack_log_verbose() + * Log message contents. + */ +static void nss_sjack_log_verbose(struct nss_sjack_msg *nsm) +{ + switch (nsm->cm.type) { + case NSS_SJACK_CONFIGURE_MSG: + nss_sjack_log_configure_msg(nsm); + break; + + case NSS_SJACK_UNCONFIGURE_MSG: + nss_sjack_log_unconfigure_msg(nsm); + break; + + case NSS_SJACK_STATS_SYNC_MSG: + /* + * No log for valid stats message. + */ + break; + + default: + nss_trace("%px: Invalid message type\n", nsm); + break; + } +} + +/* + * nss_sjack_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_sjack_log_tx_msg(struct nss_sjack_msg *nsm) +{ + if (nsm->cm.type >= NSS_SJACK_MAX_MSG_TYPE) { + nss_warning("%px: Invalid message type\n", nsm); + return; + } + + nss_info("%px: type[%d]:%s\n", nsm, nsm->cm.type, nss_sjack_log_message_types_str[nsm->cm.type]); + nss_sjack_log_verbose(nsm); +} + +/* + * nss_sjack_log_rx_msg() + * Log messages received from FW. + */ +void nss_sjack_log_rx_msg(struct nss_sjack_msg *nsm) +{ + if (nsm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", nsm); + return; + } + + if (nsm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (nsm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", nsm, nsm->cm.type, + nss_sjack_log_message_types_str[nsm->cm.type], + nsm->cm.response, nss_cmn_response_str[nsm->cm.response]); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s\n", + nsm, nsm->cm.type, nss_sjack_log_message_types_str[nsm->cm.type], + nsm->cm.response, nss_cmn_response_str[nsm->cm.response]); + +verbose: + nss_sjack_log_verbose(nsm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_sjack_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_sjack_log.h new file mode 100644 index 000000000..56435a444 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_sjack_log.h @@ -0,0 +1,41 @@ +/* + ************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_SJACK_LOG_H +#define __NSS_SJACK_LOG_H + +/* + * nss_sjack.h + * NSS SJACK header file. + */ + +/* + * Logger APIs + */ + +/* + * nss_sjack_log_tx_msg + * Logs a sjack message that is sent to the NSS firmware. + */ +void nss_sjack_log_tx_msg(struct nss_sjack_msg *nsm); + +/* + * nss_sjack_log_rx_msg + * Logs a sjack message that is received from the NSS firmware. + */ +void nss_sjack_log_rx_msg(struct nss_sjack_msg *nsm); + +#endif /* __NSS_SJACK_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_sjack_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_sjack_stats.c new file mode 100644 index 000000000..139a34941 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_sjack_stats.c @@ -0,0 +1,94 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_sjack_stats.h" + +/* + * nss_sjack_stats_read() + * Read SJACK stats + */ +static ssize_t nss_sjack_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + /* + * max output lines = #stats + start tag line + end tag line + three blank lines + */ + uint32_t max_output_lines = NSS_STATS_NODE_MAX + 5; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + stats_shadow = kzalloc(NSS_STATS_NODE_MAX * 8, GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return 0; + } + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "sjack", NSS_STATS_SINGLE_CORE); + size_wr += nss_stats_fill_common_stats(NSS_SJACK_INTERFACE, NSS_STATS_SINGLE_INSTANCE, lbuf, size_wr, size_al, "sjack"); + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * nss_sjack_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(sjack) + +/* + * nss_sjack_stats_dentry_create() + * Create SJACK node statistics debug entry. + */ +void nss_sjack_stats_dentry_create(void) +{ + nss_stats_create_dentry("sjack", &nss_sjack_stats_ops); +} + +/* + * nss_sjack_stats_node_sync() + * Update sjack node stats. + */ +void nss_sjack_stats_node_sync(struct nss_ctx_instance *nss_ctx, struct nss_sjack_stats_sync_msg *nins) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + int j; + + /* + * Update SJACK node stats. + */ + spin_lock_bh(&nss_top->stats_lock); + nss_top->stats_node[NSS_SJACK_INTERFACE][NSS_SJACK_STATS_RX_PKTS] += nins->node_stats.rx_packets; + nss_top->stats_node[NSS_SJACK_INTERFACE][NSS_SJACK_STATS_RX_BYTES] += nins->node_stats.rx_bytes; + nss_top->stats_node[NSS_SJACK_INTERFACE][NSS_SJACK_STATS_TX_PKTS] += nins->node_stats.tx_packets; + nss_top->stats_node[NSS_SJACK_INTERFACE][NSS_SJACK_STATS_TX_BYTES] += nins->node_stats.tx_bytes; + + for (j = 0; j < NSS_MAX_NUM_PRI; j++) { + nss_top->stats_node[NSS_SJACK_INTERFACE][NSS_SJACK_STATS_RX_QUEUE_0_DROPPED + j] += nins->node_stats.rx_dropped[j]; + } + + spin_unlock_bh(&nss_top->stats_lock); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_sjack_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_sjack_stats.h new file mode 100644 index 000000000..cbcd60453 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_sjack_stats.h @@ -0,0 +1,45 @@ +/* + ****************************************************************************** + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_SJACK_STATS_H +#define __NSS_SJACK_STATS_H + +/* + * SJACK statistics + */ +enum nss_sjack_stats_types { + NSS_SJACK_STATS_RX_PKTS, /* sjack node RX packets */ + NSS_SJACK_STATS_RX_BYTES, /* sjack node RX bytes */ + NSS_SJACK_STATS_TX_PKTS, /* sjack node TX packets */ + NSS_SJACK_STATS_TX_BYTES, /* sjack node TX bytes */ + NSS_SJACK_STATS_RX_QUEUE_0_DROPPED, + /* sjack node RX Queue 0 dropped */ + NSS_SJACK_STATS_RX_QUEUE_1_DROPPED, + /* sjack node RX Queue 1 dropped */ + NSS_SJACK_STATS_RX_QUEUE_2_DROPPED, + /* sjack node RX Queue 2 dropped */ + NSS_SJACK_STATS_RX_QUEUE_3_DROPPED, + /* sjack node RX Queue 3 dropped */ + NSS_SJACK_STATS_MAX, +}; + +/* + * SJACK statistics APIs + */ +extern void nss_sjack_stats_node_sync(struct nss_ctx_instance *nss_ctx, struct nss_sjack_stats_sync_msg *nins); +extern void nss_sjack_stats_dentry_create(void); + +#endif /* __NSS_SJACK_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_stats.c new file mode 100644 index 000000000..9605c372b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_stats.c @@ -0,0 +1,481 @@ +/* + ************************************************************************** + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_strings.h" +#include "nss_drv_stats.h" + +/* + * Maximum banner length: + */ +#define NSS_STATS_BANNER_MAX_LENGTH 80 + +/* + * Maximum number of digits a stats value can have: + */ +#define NSS_STATS_DIGITS_MAX 16 + +/* + * Spaces to print core details inside banner + */ +#define NSS_STATS_BANNER_SPACES 12 + +/* + * Max characters for a node name. + */ +#define NSS_STATS_NODE_NAME_MAX 24 + +int nonzero_stats_print = 0; + +/* + * nss_stats_spacing() + * Framework to maintain consistent spacing between stats value and stats type. + */ +static size_t nss_stats_spacing(uint64_t stats_val, char *lbuf, size_t size_wr, size_t size_al) +{ + int i; + int digit_counter = (stats_val == 0 ? 1 : 0); + while (stats_val != 0) { + /* + * TODO: need to check for (nss_ptr_t) + */ + stats_val = (nss_ptr_t)stats_val / 10; + digit_counter++; + } + + for (i = 0; i < NSS_STATS_DIGITS_MAX - digit_counter; i++) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, " "); + } + + return size_wr; +} + +/* + * nss_stats_nonzero_handler() + * Handler to take nonzero stats print configuration. + */ +static int nss_stats_nonzero_handler(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) +{ + int ret; + ret = proc_dointvec(ctl, write, buffer, lenp, ppos); + return ret; +} + +static struct ctl_table nss_stats_table[] = { + { + .procname = "non_zero_stats", + .data = &nonzero_stats_print, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &nss_stats_nonzero_handler, + }, + { } +}; + +static struct ctl_table nss_stats_dir[] = { + { + .procname = "stats", + .mode = 0555, + .child = nss_stats_table, + }, + { } +}; + +static struct ctl_table nss_stats_root_dir[] = { + { + .procname = "nss", + .mode = 0555, + .child = nss_stats_dir, + }, + { } +}; + +static struct ctl_table nss_stats_root[] = { + { + .procname = "dev", + .mode = 0555, + .child = nss_stats_root_dir, + }, + { } +}; +static struct ctl_table_header *nss_stats_header; + +/* + * nss_stats_register_sysctl() + * Register a sysctl table for stats. + */ +void nss_stats_register_sysctl(void) +{ + /* + * Register sysctl table. + */ + nss_stats_header = register_sysctl_table(nss_stats_root); +} + +/* + * nss_stats_open() + * Opens stats file. + */ +int nss_stats_open(struct inode *inode, struct file *filp) +{ + struct nss_stats_data *data = NULL; + + data = kzalloc(sizeof(struct nss_stats_data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + + memset(data, 0, sizeof (struct nss_stats_data)); + data->if_num = NSS_DYNAMIC_IF_START; + data->index = 0; + data->edma_id = (nss_ptr_t)inode->i_private; + data->nss_ctx = (struct nss_ctx_instance *)(inode->i_private); + filp->private_data = data; + + return 0; +} + +/* + * nss_stats_release() + * Releases stats file. + */ +int nss_stats_release(struct inode *inode, struct file *filp) +{ + struct nss_stats_data *data = filp->private_data; + + if (data) { + kfree(data); + } + + return 0; +} + +/* + * nss_stats_clean() + * Cleanup NSS statistics files. + */ +void nss_stats_clean(void) +{ + /* + * Remove debugfs tree + */ + if (likely(nss_top_main.top_dentry != NULL)) { + debugfs_remove_recursive(nss_top_main.top_dentry); + nss_top_main.top_dentry = NULL; + } +} + +/* + * nss_stats_reset_common_stats() + * Reset common node statistics. + */ +void nss_stats_reset_common_stats(uint32_t if_num) +{ + if (unlikely(if_num >= NSS_MAX_NET_INTERFACES)) { + return; + } + + spin_lock_bh(&nss_top_main.stats_lock); + memset(nss_top_main.stats_node[if_num], 0, NSS_STATS_NODE_MAX * sizeof(uint64_t)); + spin_unlock_bh(&nss_top_main.stats_lock); +} + +/* + * nss_stats_fill_common_stats() + * Fill common node statistics. + */ +size_t nss_stats_fill_common_stats(uint32_t if_num, int instance, char *lbuf, size_t size_wr, size_t size_al, char *node) +{ + uint64_t stats_val[NSS_STATS_NODE_MAX]; + int i; + size_t orig_size_wr = size_wr; + + spin_lock_bh(&nss_top_main.stats_lock); + for (i = 0; i < NSS_STATS_NODE_MAX; i++) { + stats_val[i] = nss_top_main.stats_node[if_num][i]; + } + + spin_unlock_bh(&nss_top_main.stats_lock); + size_wr += nss_stats_print(node, NULL, instance, nss_strings_stats_node, stats_val, NSS_STATS_NODE_MAX, lbuf, size_wr, size_al); + return size_wr - orig_size_wr; +} + +/* + * nss_stats_banner() + * Printing banner for node. + */ +size_t nss_stats_banner(char *lbuf, size_t size_wr, size_t size_al, char *node, int core) +{ + uint16_t banner_char_length, i; + size_t orig_size_wr = size_wr; + char node_upr[NSS_STATS_NODE_NAME_MAX + 1]; + + if (strlen(node) > NSS_STATS_NODE_NAME_MAX) { + nss_warning("Node name %s larger than %d characters\n", node, NSS_STATS_NODE_NAME_MAX); + return 0; + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n"); + for (i = 0; i < NSS_STATS_BANNER_MAX_LENGTH ; i++) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "_"); + } + if (core > NSS_STATS_SINGLE_CORE) { + banner_char_length = (uint16_t)((NSS_STATS_BANNER_MAX_LENGTH - (strlen(node) + NSS_STATS_BANNER_SPACES)) / 2); + } else { + banner_char_length = (uint16_t)((NSS_STATS_BANNER_MAX_LENGTH - (strlen(node) + 2)) / 2); + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n\n"); + for (i = 0; i < banner_char_length; i++) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "<"); + } + + strlcpy(node_upr, node, NSS_STATS_NODE_NAME_MAX); + for (i = 0; node_upr[i] != '\0' && i < NSS_STATS_NODE_NAME_MAX; i++) { + node_upr[i] = toupper(node_upr[i]); + } + + /* + * TODO: Enhance so that both core0 and core1 print the same way for a + * node that has presence in both cores. i.e. Core0 should have [CORE 0] + * and not just Core1. + */ + if (core > 1) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, " %s [CORE %d] ", node_upr, core); + } else { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, " %s ", node_upr); + } + for (i = 0; i < banner_char_length; i++) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, ">"); + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n"); + for (i = 0; i < NSS_STATS_BANNER_MAX_LENGTH; i++) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "_"); + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n\n"); + return size_wr - orig_size_wr; +} + +/* + * nss_stats_print() + * Helper API to print stats. + */ +size_t nss_stats_print(char *node, char *stat_details, int instance, struct nss_stats_info *stats_info, + uint64_t *stats_val, uint16_t max, char *lbuf, size_t size_wr, size_t size_al) +{ + uint16_t i, j; + uint16_t maxlen = 0; + char stats_string[NSS_STATS_MAX_STR_LENGTH]; + size_t orig_size_wr = size_wr; + char node_lwr[NSS_STATS_NODE_NAME_MAX + 1]; + + if (strlen(node) > NSS_STATS_NODE_NAME_MAX) { + nss_warning("Node name %s (%u chars) is longer than max chars of %d\n", + node, (uint32_t)strlen(node), NSS_STATS_NODE_NAME_MAX); + return 0; + } + + /* + * Calculating the maximum of the array for indentation purposes. + */ + for (i = 0; i < max; i++){ + if (strlen(stats_info[i].stats_name) > maxlen) { + maxlen = strlen(stats_info[i].stats_name); + } + } + + if (stat_details != NULL) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n#%s\n\n", stat_details); + } + + for (i = 0; i < max; i++){ + if (nonzero_stats_print == 1 && stats_val[i] == 0) { + continue; + } + + strlcpy(stats_string, stats_info[i].stats_name, NSS_STATS_MAX_STR_LENGTH); + + /* + * Converting uppercase to lower case. + */ + for (j = 0; stats_string[j] != '\0' && j < NSS_STATS_MAX_STR_LENGTH; j++) { + stats_string[j] = tolower(stats_string[j]); + } + + strlcpy(node_lwr, node, NSS_STATS_NODE_NAME_MAX); + for (j = 0; node_lwr[j] != '\0' && j < NSS_STATS_NODE_NAME_MAX; j++) { + node_lwr[j] = tolower(node_lwr[j]); + } + + /* + * Space before %s is needed to avoid printing stat name from start of the line. + */ + if (instance < 0) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\t%s_%s", node_lwr, stats_string); + } else { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\t%s[%d]_%s", node_lwr, instance, stats_string); + } + + for (j = 0; j < (1 + maxlen - strlen(stats_string)); j++){ + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, " "); + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "= %llu", stats_val[i]); + size_wr = nss_stats_spacing(stats_val[i], lbuf, size_wr, size_al); + + /* + * Switch case will take care of the indentation and spacing details. + */ + switch (stats_info[i].stats_type) { + case NSS_STATS_TYPE_COMMON: + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common\n"); + break; + + case NSS_STATS_TYPE_SPECIAL: + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "special\n"); + break; + + case NSS_STATS_TYPE_DROP: + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "drop\n"); + break; + + case NSS_STATS_TYPE_ERROR: + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "error\n"); + break; + + case NSS_STATS_TYPE_EXCEPTION: + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "exception\n"); + break; + + default: + nss_warning("unknown statistics type"); + break; + } + } + + return size_wr - orig_size_wr; +} + +/* + * nss_stats_create_dentry() + * Create statistics debug entry for subsystem. + */ +void nss_stats_create_dentry(char *name, const struct file_operations *ops) +{ + if (!debugfs_create_file(name, 0400, nss_top_main.stats_dentry, &nss_top_main, ops)) { + nss_warning("Failed to create debug entry for subsystem %s\n", name); + } +} + +/* + * TODO: Move the rest of the code to (nss_wt_stats.c, nss_gmac_stats.c) accordingly. + */ + +/* + * gmac_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(gmac); + +/* + * wt_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(wt); + +/* + * nss_stats_init() + * Enable NSS statistics. + */ +void nss_stats_init(void) +{ + struct dentry *core_dentry = NULL; + struct dentry *wt_dentry = NULL; + char file_name[10]; + int i; + + /* + * NSS driver entry + */ + nss_top_main.top_dentry = debugfs_create_dir("qca-nss-drv", NULL); + if (unlikely(nss_top_main.top_dentry == NULL)) { + nss_warning("Failed to create qca-nss-drv directory in debugfs"); + + /* + * Non availability of debugfs directory is not a catastrophy. + * We can still go ahead with other initialization. + */ + return; + } + + nss_top_main.stats_dentry = debugfs_create_dir("stats", nss_top_main.top_dentry); + if (unlikely(nss_top_main.stats_dentry == NULL)) { + nss_warning("Failed to create qca-nss-drv directory in debugfs"); + + /* + * Non availability of debugfs directory is not a catastrophy. + * We can still go ahead with rest of initialization. + */ + return; + } + + /* + * Create files to obtain statistics. + */ + + /* + * drv_stats + */ + nss_drv_stats_dentry_create(); + + /* + * gmac_stats + */ + nss_stats_create_dentry("gmac", &nss_gmac_stats_ops); + + /* + * Per-project stats + */ + nss_top_main.project_dentry = debugfs_create_dir("project", + nss_top_main.stats_dentry); + if (unlikely(nss_top_main.project_dentry == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/project directory in debugfs"); + return; + } + + for (i = 0; i < nss_top_main.num_nss; ++i) { + memset(file_name, 0, sizeof(file_name)); + scnprintf(file_name, sizeof(file_name), "core%d", i); + core_dentry = debugfs_create_dir(file_name, + nss_top_main.project_dentry); + if (unlikely(core_dentry == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/project/core%d directory in debugfs", i); + return; + } + + wt_dentry = debugfs_create_file("worker_threads", + 0400, + core_dentry, + &(nss_top_main.nss[i]), + &nss_wt_stats_ops); + if (unlikely(wt_dentry == NULL)) { + nss_warning("Failed to create qca-nss-drv/stats/project/core%d/worker_threads file in debugfs", i); + return; + } + } + + nss_log_init(); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_stats.h new file mode 100644 index 000000000..385c71aad --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_stats.h @@ -0,0 +1,76 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2017, 2019-2020 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_stats.h + * printing stats header file + */ + +#ifndef __NSS_STATS_PRINT_H +#define __NSS_STATS_PRINT_H +#include +#include +#include +#include + +/* + * Defines to be used by single instance/core packages. +*/ +#define NSS_STATS_SINGLE_CORE -1 +#define NSS_STATS_SINGLE_INSTANCE -1 + +/* + * Number of Extra outputlines for future reference to add new stats + start tag line + end tag line + three blank lines + */ +#define NSS_STATS_EXTRA_OUTPUT_LINES 35 + +#define NSS_STATS_DECLARE_FILE_OPERATIONS(name) \ +static const struct file_operations nss_##name##_stats_ops = { \ + .open = nss_stats_open, \ + .read = nss_##name##_stats_read, \ + .llseek = generic_file_llseek, \ + .release = nss_stats_release, \ +}; + +/* + * Private data for every file descriptor + */ +struct nss_stats_data { + uint32_t if_num; /**< Interface number for stats */ + uint32_t index; /**< Index for GRE_REDIR stats */ + uint32_t edma_id; /**< EDMA port ID or ring ID */ + struct nss_ctx_instance *nss_ctx; + /**< The core for project stats */ +}; + +/* + * Structure definition carrying stats info. + */ +struct nss_stats_info { + char stats_name[NSS_STATS_MAX_STR_LENGTH]; /* stat name */ + enum nss_stats_types stats_type; /* enum that tags stat type */ +}; + +extern void nss_stats_register_sysctl(void); +void nss_stats_init(void); +extern int nss_stats_release(struct inode *inode, struct file *filp); +extern int nss_stats_open(struct inode *inode, struct file *filp); +void nss_stats_create_dentry(char *name, const struct file_operations *ops); +extern void nss_stats_reset_common_stats(uint32_t if_num); +extern size_t nss_stats_fill_common_stats(uint32_t if_num, int instance, char *lbuf, size_t size_wr, size_t size_al, char *node); +extern size_t nss_stats_banner(char *lbuf , size_t size_wr, size_t size_al, char *node, int core); +extern size_t nss_stats_print(char *node, char *stat_details, int instance, struct nss_stats_info *stats_info, uint64_t *stats_val, uint16_t max, char *lbuf, size_t size_wr, size_t size_al); +#endif /* __NSS_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_strings.c b/feeds/ipq807x/qca-nss-drv/src/nss_strings.c new file mode 100644 index 000000000..432b1546b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_strings.c @@ -0,0 +1,148 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_strings.c + * NSS driver strings APIs. + */ + +#include "nss_strings.h" +#include "nss_core.h" +#include "nss_drv_strings.h" + +/* + * common stats + */ +struct nss_stats_info nss_strings_stats_node[NSS_STATS_NODE_MAX] = { + {"rx_pkts" , NSS_STATS_TYPE_COMMON}, + {"rx_byts" , NSS_STATS_TYPE_COMMON}, + {"tx_pkts" , NSS_STATS_TYPE_COMMON}, + {"tx_byts" , NSS_STATS_TYPE_COMMON}, + {"rx_queue[0]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[1]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[2]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[3]_drops" , NSS_STATS_TYPE_DROP} +}; + +/* + * nss_strings_print() + * Helper API to print stats names + */ +size_t nss_strings_print(char __user *ubuf, size_t sz, loff_t *ppos, struct nss_stats_info *stats_info, uint16_t max) +{ + int32_t i; + size_t size_al = (NSS_STATS_MAX_STR_LENGTH + 12) * max; + size_t size_wr = 0; + ssize_t bytes_read = 0; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (!lbuf) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + for (i = 0; i < max; i++) { + /* + * Print what we have but don't exceed the buffer. + */ + if (size_wr >= size_al) { + nss_info_always("Buffer overflowed.\n"); + break; + } + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "\t%d , %s\n", stats_info[i].stats_type, stats_info[i].stats_name); + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + + return bytes_read; +} + +/* + * nss_strings_create_dentry() + * Create strings debug entry for subsystem. + */ +void nss_strings_create_dentry(char *name, const struct file_operations *ops) +{ + if (!nss_top_main.strings_dentry || !debugfs_create_file(name, 0400, nss_top_main.strings_dentry, &nss_top_main, ops)) { + nss_warning("Failed to create debug entry for subsystem %s\n", name); + } +} + +/* + * nss_strings_open() + */ +int nss_strings_open(struct inode *inode, struct file *filp) +{ + struct nss_strings_data *data = NULL; + + data = kzalloc(sizeof(struct nss_strings_data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + data->if_num = NSS_DYNAMIC_IF_START; + data->nss_ctx = (struct nss_ctx_instance *)(inode->i_private); + filp->private_data = data; + + return 0; +} + +/* + * nss_strings_release() + */ +int nss_strings_release(struct inode *inode, struct file *filp) +{ + struct nss_strings_data *data = filp->private_data; + + if (data) { + kfree(data); + } + + return 0; +} + +/* + * nss_common_node_stats_strings_read() + * Read common node statistics names. + */ +static ssize_t nss_common_node_stats_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_strings_stats_node, NSS_STATS_NODE_MAX); +} + +/* + * nss_common_node_stats_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(common_node_stats); + +/* + * nss_strings_init() + * Enable NSS statistics + */ +void nss_strings_init(void) +{ + nss_top_main.strings_dentry = debugfs_create_dir("strings", nss_top_main.top_dentry); + if (unlikely(nss_top_main.strings_dentry == NULL)) { + nss_warning("Failed to create strings directory in debugfs/qca-nss-drv"); + return; + } + + /* + * Common node statistics + */ + nss_strings_create_dentry("common_node_stats", &nss_common_node_stats_strings_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_strings.h b/feeds/ipq807x/qca-nss-drv/src/nss_strings.h new file mode 100644 index 000000000..32bf46601 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_strings.h @@ -0,0 +1,52 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_strings.h + * NSS driver strings header file. + */ + +#ifndef __NSS_STRINGS_H +#define __NSS_STRINGS_H + +#include +#include "nss_stats.h" + +#define NSS_STRINGS_DECLARE_FILE_OPERATIONS(name) \ +static const struct file_operations nss_##name##_strings_ops = { \ + .open = nss_strings_open, \ + .read = nss_##name##_strings_read, \ + .llseek = generic_file_llseek, \ + .release = nss_strings_release, \ +} + +/* + * Private data for every file descriptor + */ +struct nss_strings_data { + uint32_t if_num; /**< Interface number for stats */ + struct nss_ctx_instance *nss_ctx; /**< The core for project stats */ +}; + +extern struct nss_stats_info nss_strings_stats_node[NSS_STATS_NODE_MAX]; +void nss_strings_init(void); +int nss_strings_release(struct inode *inode, struct file *filp); +int nss_strings_open(struct inode *inode, struct file *filp); +void nss_strings_create_dentry(char *name, const struct file_operations *ops); +size_t nss_strings_fill_common_stats(char __user *ubuf, size_t sz, loff_t *ppos); +size_t nss_strings_print(char __user *ubuf, size_t sz, loff_t *ppos, struct nss_stats_info *stats_info, uint16_t max); + +#endif /* __NSS_STRINGS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_tls.c b/feeds/ipq807x/qca-nss-drv/src/nss_tls.c new file mode 100644 index 000000000..6fda9c7f1 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_tls.c @@ -0,0 +1,550 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_tls_log.h" + +#define NSS_TLS_INTERFACE_MAX_LONG BITS_TO_LONGS(NSS_MAX_NET_INTERFACES) +#define NSS_TLS_STATS_MAX_LINES (NSS_STATS_NODE_MAX + 32) +#define NSS_TLS_STATS_SIZE_PER_IF (NSS_STATS_MAX_STR_LENGTH * NSS_TLS_STATS_MAX_LINES) +#define NSS_TLS_TX_TIMEOUT 3000 /* 3 Seconds */ + +/* + * Private data structure for handling synchronous messaging. + */ +static struct nss_tls_pvt { + struct semaphore sem; + struct completion complete; + struct nss_tls_msg ntcm; + unsigned long if_map[NSS_TLS_INTERFACE_MAX_LONG]; +} tls_pvt; + +/* + * nss_tls_stats_sync() + * Update tls node statistics. + */ +static void nss_tls_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm) +{ + struct nss_tls_msg *ndcm = (struct nss_tls_msg *)ncm; + struct nss_top_instance *nss_top = nss_ctx->nss_top; + struct nss_tls_ctx_stats *msg_stats = &ndcm->msg.stats; + uint64_t *if_stats; + int i; + + spin_lock_bh(&nss_top->stats_lock); + + /* + * Update common node stats, + * Note: TLS only supports a single queue for RX + */ + if_stats = nss_top->stats_node[ncm->interface]; + if_stats[NSS_STATS_NODE_RX_PKTS] += msg_stats->pkt.rx_packets; + if_stats[NSS_STATS_NODE_RX_BYTES] += msg_stats->pkt.rx_bytes; + + for (i = 0; i < NSS_MAX_NUM_PRI; i++) + if_stats[NSS_STATS_NODE_RX_QUEUE_0_DROPPED + i] += msg_stats->pkt.rx_dropped[i]; + + if_stats[NSS_STATS_NODE_TX_PKTS] += msg_stats->pkt.tx_packets; + if_stats[NSS_STATS_NODE_TX_BYTES] += msg_stats->pkt.tx_bytes; + + spin_unlock_bh(&nss_top->stats_lock); +} + +/* + * nss_tls_stats_read() + * Read tls node statiistics. + */ +static ssize_t nss_tls_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + struct nss_ctx_instance *nss_ctx = nss_tls_get_context(); + enum nss_dynamic_interface_type type; + ssize_t bytes_read = 0; + size_t len = 0, size; + uint32_t if_num; + char *buf; + + size = NSS_TLS_STATS_SIZE_PER_IF * bitmap_weight(tls_pvt.if_map, NSS_MAX_NET_INTERFACES); + + buf = kzalloc(size, GFP_KERNEL); + if (!buf) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + /* + * Common node stats for each TLS dynamic interface. + */ + for_each_set_bit(if_num, tls_pvt.if_map, NSS_MAX_NET_INTERFACES) { + type = nss_dynamic_interface_get_type(nss_ctx, if_num); + + switch (type) { + case NSS_DYNAMIC_INTERFACE_TYPE_TLS_INNER: + len += scnprintf(buf + len, size - len, "\nInner if_num:%03u", if_num); + break; + + case NSS_DYNAMIC_INTERFACE_TYPE_TLS_OUTER: + len += scnprintf(buf + len, size - len, "\nOuter if_num:%03u", if_num); + break; + + default: + len += scnprintf(buf + len, size - len, "\nUnknown(%d) if_num:%03u", type, if_num); + break; + } + + len += scnprintf(buf + len, size - len, "\n-------------------\n"); + len = nss_stats_fill_common_stats(if_num, NSS_STATS_SINGLE_INSTANCE, buf, len, size - len, "tls"); + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, buf, len); + kfree(buf); + + return bytes_read; +} + +/* + * nss_tls_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(tls) + +/* + * nss_tls_verify_ifnum() + * Verify if the interface number is a TLS interface. + */ +static bool nss_tls_verify_ifnum(struct nss_ctx_instance *nss_ctx, uint32_t if_num) +{ + enum nss_dynamic_interface_type type = nss_dynamic_interface_get_type(nss_ctx, if_num); + + if (type == NSS_DYNAMIC_INTERFACE_TYPE_TLS_INNER) + return true; + + if (type == NSS_DYNAMIC_INTERFACE_TYPE_TLS_OUTER) + return true; + + if (if_num == NSS_TLS_INTERFACE) + return true; + + return false; +} + +/* + * nss_tls_handler() + * Handle NSS -> HLOS messages for tls tunnel + */ +static void nss_tls_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, void *data) +{ + nss_tls_msg_callback_t cb; + void *app_data; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + nss_trace("%px: handle event for interface num :%u", nss_ctx, ncm->interface); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_TLS_MSG_MAX) { + nss_warning("%px:Bad message type(%d) for TLS interface %d", nss_ctx, ncm->type, ncm->interface); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_tls_msg)) { + nss_warning("%px:Bad message length(%d)", nss_ctx, ncm->len); + return; + } + + if (ncm->type == NSS_TLS_MSG_TYPE_CTX_SYNC) + nss_tls_stats_sync(nss_ctx, ncm); + + /* + * Update the callback and app_data for NOTIFY messages + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_core_get_msg_handler(nss_ctx, ncm->interface); + ncm->app_data = (nss_ptr_t)nss_ctx->nss_rx_interface_handlers[ncm->interface].app_data; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Trace messages. + */ + nss_tls_log_rx_msg((struct nss_tls_msg *)ncm); + + /* + * Callback + */ + cb = (nss_tls_msg_callback_t)ncm->cb; + app_data = (void *)ncm->app_data; + + /* + * Call TLS session callback + */ + if (!cb) { + nss_warning("%px: No callback for tls session interface %d", nss_ctx, ncm->interface); + return; + } + + nss_trace("%px: calling tlsmgr event handler(%u)", nss_ctx, ncm->interface); + cb(app_data, ncm); +} + +/* + * nss_tls_sync_resp() + * Callback to handle the completion of HLOS-->NSS messages. + */ +static void nss_tls_sync_resp(void *app_data, struct nss_cmn_msg *ncm) +{ + struct nss_tls_msg *pvt_msg = app_data; + struct nss_tls_msg *resp_msg = container_of(ncm, struct nss_tls_msg, cm); + + /* + * Copy response message to pvt message + */ + memcpy(pvt_msg, resp_msg, sizeof(*resp_msg)); + + /* + * Write memory barrier + */ + smp_wmb(); + + complete(&tls_pvt.complete); +} + +/* + * nss_tls_tx_buf() + * Transmit buffer over TLS interface + */ +nss_tx_status_t nss_tls_tx_buf(struct sk_buff *skb, uint32_t if_num, struct nss_ctx_instance *nss_ctx) +{ + int32_t status; + + if (!nss_tls_verify_ifnum(nss_ctx, if_num)) + return NSS_TX_FAILURE; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) { + nss_warning("%px: tx_data packet dropped as core not ready", nss_ctx); + return NSS_TX_FAILURE_NOT_READY; + } + + status = nss_core_send_buffer(nss_ctx, if_num, skb, NSS_IF_H2N_DATA_QUEUE, H2N_BUFFER_PACKET, 0); + switch (status) { + case NSS_CORE_STATUS_SUCCESS: + break; + + case NSS_CORE_STATUS_FAILURE_QUEUE: /* queue full condition */ + nss_warning("%px: H2N queue full for tx_buf", nss_ctx); + return NSS_TX_FAILURE_QUEUE; + + default: + nss_warning("%px: general failure for tx_buf", nss_ctx); + return NSS_TX_FAILURE; + } + + /* + * Kick the NSS awake so it can process our new entry. + */ + nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_DATA_COMMAND_QUEUE); + + return NSS_TX_SUCCESS; +} +EXPORT_SYMBOL(nss_tls_tx_buf); + +/* + * nss_tls_tx_msg() + * Transmit a TLS message to NSS firmware + */ +nss_tx_status_t nss_tls_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_tls_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + if (ncm->type >= NSS_TLS_MSG_MAX) { + nss_warning("%px: tls message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + if (!nss_tls_verify_ifnum(nss_ctx, ncm->interface)) { + nss_warning("%px: tls message interface is bad: %u", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + /* + * Trace messages. + */ + nss_tls_log_tx_msg(msg); + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_tls_tx_msg); + +/* + * nss_tls_tx_msg_sync() + * Transmit a TLS message to NSS firmware synchronously. + */ +nss_tx_status_t nss_tls_tx_msg_sync(struct nss_ctx_instance *nss_ctx, uint32_t if_num, + enum nss_tls_msg_type type, uint16_t len, + struct nss_tls_msg *ntcm) +{ + struct nss_tls_msg *local_ntcm = &tls_pvt.ntcm; + nss_tx_status_t status; + int ret = 0; + + /* + * Length of the message should be the based on type + */ + if (len > sizeof(struct nss_tls_msg)) { + nss_warning("%px: Invalid message length(%u), type (%d), I/F(%u)\n", nss_ctx, len, type, if_num); + return NSS_TX_FAILURE; + } + + down(&tls_pvt.sem); + + /* + * We need to copy the message content into the actual message + * to be sent to NSS + */ + memset(local_ntcm, 0, sizeof(*local_ntcm)); + + nss_tls_msg_init(local_ntcm, if_num, type, len, nss_tls_sync_resp, local_ntcm); + memcpy(&local_ntcm->msg, &ntcm->msg, len); + + status = nss_tls_tx_msg(nss_ctx, local_ntcm); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: Failed to send message\n", nss_ctx); + goto done; + } + + ret = wait_for_completion_timeout(&tls_pvt.complete, msecs_to_jiffies(NSS_TLS_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: Failed to receive response, timeout(%d)\n", nss_ctx, ret); + status = NSS_TX_FAILURE_NOT_READY; + goto done; + } + + /* + * Read memory barrier + */ + smp_rmb(); + + if (local_ntcm->cm.response != NSS_CMN_RESPONSE_ACK) { + status = NSS_TX_FAILURE; + ntcm->cm.response = local_ntcm->cm.response; + ntcm->cm.error = local_ntcm->cm.error; + goto done; + } + + /* + * Copy the message received + */ + memcpy(&ntcm->msg, &local_ntcm->msg, len); + +done: + up(&tls_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_tls_tx_msg_sync); + +/* + * nss_tls_notify_register() + * Register a handler for notification from NSS firmware. + */ +struct nss_ctx_instance *nss_tls_notify_register(uint32_t if_num, nss_tls_msg_callback_t ev_cb, void *app_data) +{ + struct nss_ctx_instance *nss_ctx = nss_tls_get_context(); + uint32_t ret; + + BUG_ON(!nss_ctx); + + ret = nss_core_register_handler(nss_ctx, if_num, nss_tls_handler, app_data); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: unable to register event handler for interface(%u)", nss_ctx, if_num); + return NULL; + } + + ret = nss_core_register_msg_handler(nss_ctx, if_num, ev_cb); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_core_unregister_handler(nss_ctx, if_num); + nss_warning("%px: unable to register event handler for interface(%u)", nss_ctx, if_num); + return NULL; + } + + return nss_ctx; +} +EXPORT_SYMBOL(nss_tls_notify_register); + +/* + * nss_tls_notify_unregister() + * Unregister notification callback handler. + */ +void nss_tls_notify_unregister(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = nss_tls_get_context(); + uint32_t ret; + + BUG_ON(!nss_ctx); + + ret = nss_core_unregister_msg_handler(nss_ctx, if_num); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: unable to un register event handler for interface(%u)", nss_ctx, if_num); + return; + } + + ret = nss_core_unregister_handler(nss_ctx, if_num); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: unable to un register event handler for interface(%u)", nss_ctx, if_num); + return; + } + + return; +} +EXPORT_SYMBOL(nss_tls_notify_unregister); + +/* + * nss_tls_register_if() + * Register data and event callback handlers for dynamic interface. + */ +struct nss_ctx_instance *nss_tls_register_if(uint32_t if_num, + nss_tls_data_callback_t data_cb, + nss_tls_msg_callback_t ev_cb, + struct net_device *netdev, + uint32_t features, + uint32_t type, + void *app_data) +{ + struct nss_ctx_instance *nss_ctx = nss_tls_get_context(); + uint32_t ret; + + if (!nss_tls_verify_ifnum(nss_ctx, if_num)) { + nss_warning("%px: TLS Interface is not dynamic:%u", nss_ctx, if_num); + return NULL; + } + + if (nss_ctx->subsys_dp_register[if_num].ndev) { + nss_warning("%px: Cannot find free slot for TLS NSS I/F:%u", nss_ctx, if_num); + return NULL; + } + + nss_core_register_subsys_dp(nss_ctx, if_num, data_cb, NULL, app_data, netdev, features); + nss_core_set_subsys_dp_type(nss_ctx, netdev, if_num, type); + + ret = nss_core_register_handler(nss_ctx, if_num, nss_tls_handler, app_data); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: unable to register event handler for interface(%u)", nss_ctx, if_num); + return NULL; + } + + ret = nss_core_register_msg_handler(nss_ctx, if_num, ev_cb); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_core_unregister_handler(nss_ctx, if_num); + nss_warning("%px: unable to register event handler for interface(%u)", nss_ctx, if_num); + return NULL; + } + + /* + * Atomically set the bitmap for the interface number + */ + set_bit(if_num, tls_pvt.if_map); + return nss_ctx; +} +EXPORT_SYMBOL(nss_tls_register_if); + +/* + * nss_tls_unregister_if() + * Unregister data and event callback handlers for the interface. + */ +void nss_tls_unregister_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = nss_tls_get_context(); + uint32_t ret; + + if (!nss_ctx->subsys_dp_register[if_num].ndev) { + nss_warning("%px: Cannot find registered netdev for TLS NSS I/F:%u", nss_ctx, if_num); + return; + } + + /* + * Atomically clear the bitmap for the interface number + */ + clear_bit(if_num, tls_pvt.if_map); + + ret = nss_core_unregister_msg_handler(nss_ctx, if_num); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: unable to un register event handler for interface(%u)", nss_ctx, if_num); + return; + } + + nss_core_unregister_handler(nss_ctx, if_num); + + nss_core_unregister_subsys_dp(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_tls_unregister_if); + +/* + * nss_tls_get_context() + * Return TLS NSS context. + */ +struct nss_ctx_instance *nss_tls_get_context(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.tls_handler_id]; +} +EXPORT_SYMBOL(nss_tls_get_context); + +/* + * nss_tls_get_device() + * Gets the original device from probe. + */ +struct device *nss_tls_get_dev(struct nss_ctx_instance *nss_ctx) +{ + return nss_ctx->dev; +} +EXPORT_SYMBOL(nss_tls_get_dev); + +/* + * nss_tls_msg_init() + * Initialize nss_tls msg to be sent asynchronously. + */ +void nss_tls_msg_init(struct nss_tls_msg *ncm, uint32_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data) +{ + nss_cmn_msg_init(&ncm->cm, if_num, type, len, cb, app_data); +} +EXPORT_SYMBOL(nss_tls_msg_init); + +/* + * nss_tls_msg_sync_init() + * Initialize nss_tls_msg to be sent synchronously. + */ +void nss_tls_msg_sync_init(struct nss_tls_msg *ncm, uint32_t if_num, uint32_t type, uint32_t len) +{ + nss_cmn_msg_sync_init(&ncm->cm, if_num, type, len); +} +EXPORT_SYMBOL(nss_tls_msg_sync_init); + +/* + * nss_tls_register_handler() + * TLS initialization. + */ +void nss_tls_register_handler(void) +{ + sema_init(&tls_pvt.sem, 1); + init_completion(&tls_pvt.complete); + nss_stats_create_dentry("tls", &nss_tls_stats_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_tls_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_tls_log.c new file mode 100644 index 000000000..11afe45ed --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_tls_log.c @@ -0,0 +1,167 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE + ************************************************************************** + */ + +/* + * nss_tls_log.c + * NSS TLS logger file. + */ + +#include "nss_core.h" + +/* + * nss_tls_log_message_types_str + * TLS message strings + */ +static int8_t *nss_tls_log_message_types_str[NSS_TLS_MSG_MAX] __maybe_unused = { + "TLS Node Configure", + "TLS Context Configure", + "TLS Context Deconfigure", + "TLS Cipher Update", + "TLS Context Sync", + "TLS Node Sync", +}; + +/* + * nss_tls_log_error_response_types_str + * Strings for error types for TLS messages + */ +static int8_t *nss_tls_log_error_response_types_str[NSS_TLS_ERROR_MAX] __maybe_unused = { + "TLS no_error", + "TLS unknown message", + "TLS fail node already config", + "TLS fail inner ctx", + "TLS fail outer ctx", + "TLS fail req pool", + "TLS invalid block len", + "TLS invalid hash len", + "TLS invalid version", + "TLS invalid context words", + "TLS fail alloc hwctx", + "TLS fail copy ctx", + "TLS Invalid algorithm", + "TLS fail nomem" +}; + +/* + * nss_tls_node_config_msg() + * Log TLS node configure message. + */ +static void nss_tls_node_config_msg(struct nss_tls_msg *ntm) +{ + nss_trace("%px: NSS TLS Node Configure Message:\n" + "TLS Interface: %d\n", ntm, ntm->cm.interface); +} + +/* + * nss_tls_ctx_config_msg() + * Log TLS session configure message. + */ +static void nss_tls_ctx_config_msg(struct nss_tls_msg *ntm) +{ + struct nss_tls_ctx_config *ntccm __maybe_unused = &ntm->msg.ctx_cfg; + nss_trace("%px: NSS TLS Context Configure Message:\n" + "TLS Except if_num: %d\n", + ntccm, ntccm->except_ifnum); +} + +/* + * nss_tls_cipher_upddate_msg() + * Log TLS Cipher Update message. + */ +static void nss_tls_cipher_update_msg(struct nss_tls_msg *ntm) +{ + struct nss_tls_cipher_update *ntcum __maybe_unused = &ntm->msg.cipher_update; + nss_trace("%px: NSS TLS Cipher Update message\n" + "TLS crypto index: %d\n", + ntcum, ntcum->crypto_idx); +} + +/* + * nss_tls_log_verbose() + * Log message contents. + */ +static void nss_tls_log_verbose(struct nss_tls_msg *ntm) +{ + switch (ntm->cm.type) { + case NSS_TLS_MSG_TYPE_NODE_CONFIG: + nss_tls_node_config_msg(ntm); + break; + + case NSS_TLS_MSG_TYPE_CIPHER_UPDATE: + nss_tls_cipher_update_msg(ntm); + break; + + case NSS_TLS_MSG_TYPE_CTX_CONFIG: + nss_tls_ctx_config_msg(ntm); + break; + + default: + nss_warning("%px: Invalid message type\n", ntm); + break; + } +} + +/* + * nss_tls_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_tls_log_tx_msg(struct nss_tls_msg *ntm) +{ + if (ntm->cm.type >= NSS_TLS_MSG_MAX) { + nss_warning("%px: Invalid message type\n", ntm); + return; + } + + nss_info("%px: type[%d]:%s\n", ntm, ntm->cm.type, nss_tls_log_message_types_str[ntm->cm.type]); + nss_tls_log_verbose(ntm); +} + +/* + * nss_tls_log_rx_msg() + * Log messages received from FW. + */ +void nss_tls_log_rx_msg(struct nss_tls_msg *ntm) +{ + if (ntm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", ntm); + return; + } + + if (ntm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ntm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", ntm, ntm->cm.type, + nss_tls_log_message_types_str[ntm->cm.type], + ntm->cm.response, nss_cmn_response_str[ntm->cm.response]); + goto verbose; + } + + if (ntm->cm.error >= NSS_TLS_ERROR_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + ntm, ntm->cm.type, nss_tls_log_message_types_str[ntm->cm.type], + ntm->cm.response, nss_cmn_response_str[ntm->cm.response], + ntm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + ntm, ntm->cm.type, nss_tls_log_message_types_str[ntm->cm.type], + ntm->cm.response, nss_cmn_response_str[ntm->cm.response], + ntm->cm.error, nss_tls_log_error_response_types_str[ntm->cm.error]); + +verbose: + nss_tls_log_verbose(ntm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_tls_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_tls_log.h new file mode 100644 index 000000000..37846c2b6 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_tls_log.h @@ -0,0 +1,39 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE + ************************************************************************** + */ + +#ifndef __NSS_TLS_LOG_H +#define __NSS_TLS_LOG_H + +/* + * nss_tls_log.h + * NSS TLS Log Header File + */ + +/* + * nss_tls_log_tx_msg + * Logs a TLS message that is sent to the NSS firmware. + */ +void nss_tls_log_tx_msg(struct nss_tls_msg *ndm); + +/* + * nss_tls_log_rx_msg + * Logs a TLS message that is received from the NSS firmware. + */ +void nss_tls_log_rx_msg(struct nss_tls_msg *ndm); + +#endif /* __NSS_TLS_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_trustsec_tx.c b/feeds/ipq807x/qca-nss-drv/src/nss_trustsec_tx.c new file mode 100644 index 000000000..2ba6ee64d --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_trustsec_tx.c @@ -0,0 +1,299 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2018, 2020 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_trustsec_tx_stats.h" +#include "nss_trustsec_tx_log.h" + +#define NSS_TRUSTSEC_TX_TIMEOUT 3000 /* 3 Seconds */ + +/* + * Private data structure for trustsec_tx interface + */ +static struct nss_trustsec_tx_pvt { + struct semaphore sem; + struct completion complete; + int response; +} ttx; + +/* + * nss_trustsec_tx_handler() + * Handle NSS -> HLOS messages for trustsec_tx + */ +static void nss_trustsec_tx_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, + __attribute__((unused))void *app_data) +{ + nss_trustsec_tx_msg_callback_t cb; + struct nss_trustsec_tx_msg *npm = (struct nss_trustsec_tx_msg *)ncm; + + BUG_ON(ncm->interface != NSS_TRUSTSEC_TX_INTERFACE); + + /* + * Trace messages. + */ + nss_trustsec_tx_log_rx_msg(npm); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_TRUSTSEC_TX_MSG_MAX) { + nss_warning("%px: received invalid message %d for trustsec_tx interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_trustsec_tx_msg)) { + nss_warning("%px: message size incorrect: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + switch (ncm->type) { + case NSS_TRUSTSEC_TX_MSG_STATS_SYNC: + /* + * Update trustsec_tx statistics. + */ + nss_trustsec_tx_stats_sync(nss_ctx, &npm->msg.stats_sync); + break; + } + + /* + * Update the callback and app_data for NOTIFY messages, trustsec_tx sends all notify messages + * to the same callback/app_data. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_core_get_msg_handler(nss_ctx, ncm->interface); + ncm->app_data = (nss_ptr_t)nss_ctx->subsys_dp_register[ncm->interface].ndev; + } + + /* + * Do we have a call back + */ + if (!ncm->cb) { + return; + } + + /* + * callback + */ + cb = (nss_trustsec_tx_msg_callback_t)ncm->cb; + + cb((void *)ncm->app_data, npm); +} + +/* + * nss_trustsec_tx_msg() + * Transmit a trustsec_tx message to NSSFW + */ +nss_tx_status_t nss_trustsec_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_trustsec_tx_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Trace messages. + */ + nss_trustsec_tx_log_tx_msg(msg); + + /* + * Sanity check the message + */ + if (ncm->interface != NSS_TRUSTSEC_TX_INTERFACE) { + nss_warning("%px: tx request for another interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type > NSS_TRUSTSEC_TX_MSG_MAX) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_trustsec_tx_msg); + +/* + * nss_trustsec_tx_callback + * Callback to handle the completion of NSS ->HLOS messages. + */ +static void nss_trustsec_tx_callback(void *app_data, struct nss_trustsec_tx_msg *npm) +{ + if (npm->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("trustsec_tx error response %d\n", npm->cm.response); + ttx.response = NSS_TX_FAILURE; + complete(&ttx.complete); + return; + } + + ttx.response = NSS_TX_SUCCESS; + complete(&ttx.complete); +} + +/* + * nss_trustsec_tx_msg_sync() + * Send a message to trustsec_tx interface & wait for the response. + */ +nss_tx_status_t nss_trustsec_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_trustsec_tx_msg *msg) +{ + nss_tx_status_t status; + int ret = 0; + + down(&ttx.sem); + + msg->cm.cb = (nss_ptr_t)nss_trustsec_tx_callback; + msg->cm.app_data = (nss_ptr_t)NULL; + + status = nss_trustsec_tx_msg(nss_ctx, msg); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: nss_trustsec_tx_msg failed\n", nss_ctx); + up(&ttx.sem); + return status; + } + + ret = wait_for_completion_timeout(&ttx.complete, msecs_to_jiffies(NSS_TRUSTSEC_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: trustsec_tx tx failed due to timeout\n", nss_ctx); + ttx.response = NSS_TX_FAILURE; + } + + status = ttx.response; + up(&ttx.sem); + + return status; +} +EXPORT_SYMBOL(nss_trustsec_tx_msg_sync); + +/* + * nss_trustsec_tx_get_ctx() + * Return a TrustSec TX NSS context. + */ +struct nss_ctx_instance *nss_trustsec_tx_get_ctx() +{ + return &nss_top_main.nss[nss_top_main.trustsec_tx_handler_id]; +} +EXPORT_SYMBOL(nss_trustsec_tx_get_ctx); + +/* + * nss_trustsec_tx_msg_init() + * Initialize trustsec_tx message. + */ +void nss_trustsec_tx_msg_init(struct nss_trustsec_tx_msg *npm, uint16_t if_num, uint32_t type, uint32_t len, + nss_trustsec_tx_msg_callback_t cb, void *app_data) +{ + nss_cmn_msg_init(&npm->cm, if_num, type, len, (void *)cb, app_data); +} +EXPORT_SYMBOL(nss_trustsec_tx_msg_init); + +/* + * nss_trustsec_tx_update_nexthop() + */ +nss_tx_status_t nss_trustsec_tx_update_nexthop(uint32_t src, uint32_t dest, uint16_t sgt) +{ + struct nss_ctx_instance *ctx = nss_trustsec_tx_get_ctx(); + struct nss_trustsec_tx_msg ttx_msg = {{0}}; + struct nss_trustsec_tx_update_nexthop_msg *ttxunh; + nss_tx_status_t status; + + ttxunh = &ttx_msg.msg.upd_nexthop; + ttxunh->src = src; + ttxunh->dest = dest; + ttxunh->sgt = sgt; + + nss_trustsec_tx_msg_init(&ttx_msg, NSS_TRUSTSEC_TX_INTERFACE, NSS_TRUSTSEC_TX_MSG_UPDATE_NEXTHOP, + sizeof(*ttxunh), NULL, NULL); + + BUG_ON(in_atomic()); + status = nss_trustsec_tx_msg_sync(ctx, &ttx_msg); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: configure trustsec_tx failed: %d\n", ctx, status); + } + + return status; +} +EXPORT_SYMBOL(nss_trustsec_tx_update_nexthop); + +/* + * nss_trustsec_tx_configure_sgt() + */ +nss_tx_status_t nss_trustsec_tx_configure_sgt(uint32_t src, uint32_t dest, uint16_t sgt) +{ + struct nss_ctx_instance *ctx = nss_trustsec_tx_get_ctx(); + struct nss_trustsec_tx_msg ttx_msg = {{0}}; + struct nss_trustsec_tx_configure_msg *ttxcfg; + nss_tx_status_t status; + + ttxcfg = &ttx_msg.msg.configure; + ttxcfg->src = src; + ttxcfg->dest = dest; + ttxcfg->sgt = sgt; + + nss_trustsec_tx_msg_init(&ttx_msg, NSS_TRUSTSEC_TX_INTERFACE, NSS_TRUSTSEC_TX_MSG_CONFIGURE, + sizeof(*ttxcfg), NULL, NULL); + + BUG_ON(in_atomic()); + status = nss_trustsec_tx_msg_sync(ctx, &ttx_msg); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: configure trustsec_tx failed: %d\n", ctx, status); + } + + return status; +} +EXPORT_SYMBOL(nss_trustsec_tx_configure_sgt); + +/* + * nss_trustsec_tx_unconfigure() + */ +nss_tx_status_t nss_trustsec_tx_unconfigure_sgt(uint32_t src, uint16_t sgt) +{ + struct nss_ctx_instance *ctx = nss_trustsec_tx_get_ctx(); + struct nss_trustsec_tx_msg ttx_msg = {{0}}; + struct nss_trustsec_tx_unconfigure_msg *ttxucfg; + nss_tx_status_t status; + + ttxucfg = &ttx_msg.msg.unconfigure; + ttxucfg->src = src; + ttxucfg->sgt = sgt; + + nss_trustsec_tx_msg_init(&ttx_msg, NSS_TRUSTSEC_TX_INTERFACE, NSS_TRUSTSEC_TX_MSG_UNCONFIGURE, + sizeof(*ttxucfg), NULL, NULL); + + BUG_ON(in_atomic()); + status = nss_trustsec_tx_msg_sync(ctx, &ttx_msg); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: unconfigure trustsec_tx failed: %d\n", ctx, status); + } + + return status; +} +EXPORT_SYMBOL(nss_trustsec_tx_unconfigure_sgt); + +/* + * nss_trustsec_tx_register_handler() + * Registering handler for sending msg to trustsec_tx node on NSS. + */ +void nss_trustsec_tx_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx = nss_trustsec_tx_get_ctx(); + + nss_core_register_handler(nss_ctx, NSS_TRUSTSEC_TX_INTERFACE, nss_trustsec_tx_handler, NULL); + + nss_trustsec_tx_stats_dentry_create(); + + sema_init(&ttx.sem, 1); + init_completion(&ttx.complete); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_trustsec_tx_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_trustsec_tx_log.c new file mode 100644 index 000000000..3ed5b5149 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_trustsec_tx_log.c @@ -0,0 +1,170 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_trustsec_tx_log.c + * NSS TRUSTSEC_TX logger file. + */ + +#include "nss_core.h" + +/* + * nss_trustsec_tx_log_message_types_str + * TRUSTSEC_TX message strings + */ +static int8_t *nss_trustsec_tx_log_message_types_str[NSS_TRUSTSEC_TX_MSG_MAX] __maybe_unused = { + "TRUSTSEC_TX Configure Message", + "TRUSTSEC_TX Unconfigure Message", + "TRUSTSEC_TX Stats Sync", + "TRUSTSEC_TX Update next Hop", +}; + +/* + * nss_trustsec_tx_log_error_response_types_str + * Strings for error types for TRUSTSEC_TX messages + */ +static int8_t *nss_trustsec_tx_log_error_response_types_str[NSS_TRUSTSEC_TX_ERR_UNKNOWN] __maybe_unused = { + "TRUSTSEC_TX Invalid Source Interface", + "TRUSTSEC_TX Reconfigure Source Interface" + "TRUSTSEC_TX Destination Interface Not Found", + "TRUSTSEC_TX Not Configured", + "TRUSTSEC_TX SGT Mismatch", + "TRUSTSEC_TX Unknown Error", +}; + +/* + * nss_trustsec_tx_log_configure_msg() + * Log NSS TRUSTSEC_TX configure message. + */ +static void nss_trustsec_tx_log_configure_msg(struct nss_trustsec_tx_msg *ntm) +{ + struct nss_trustsec_tx_configure_msg *ntcm __maybe_unused = &ntm->msg.configure; + nss_trace("%px: NSS TRUSTSEC_TX Configure Message:\n" + "TRUSTSEC_TX Source: %d\n" + "TRUSTSEC_TX Destination: %d\n" + "TRUSTSEC_TX Security Group Tag: %d\n", + ntcm, ntcm->src, + ntcm->dest, ntcm->sgt); +} + +/* + * nss_trustsec_tx_log_unconfigure_msg() + * Log NSS TRUSTSEC_TX unconfigure message. + */ +static void nss_trustsec_tx_log_unconfigure_msg(struct nss_trustsec_tx_msg *ntm) +{ + struct nss_trustsec_tx_unconfigure_msg *ntcm __maybe_unused = &ntm->msg.unconfigure; + nss_trace("%px: NSS TRUSTSEC_TX Unconfigure Message:\n" + "TRUSTSEC_TX Source: %d\n" + "TRUSTSEC_TX Security Group Tag: %d\n", + ntcm, ntcm->src, ntcm->sgt); +} + +/* + * nss_trustsec_tx_log_update_nexthop_msg() + * Log NSS TRUSTSEC_TX update nexthop message. + */ +static void nss_trustsec_tx_log_update_nexthop_msg(struct nss_trustsec_tx_msg *ntm) +{ + struct nss_trustsec_tx_update_nexthop_msg *ntunm __maybe_unused = &ntm->msg.upd_nexthop; + nss_trace("%px: NSS TRUSTSEC_TX Update Next Hop Message:\n" + "TRUSTSEC_TX Source: %d\n" + "TRUSTSEC_TX Destination: %d\n" + "TRUSTSEC_TX Security Group Tag: %d\n", + ntunm, ntunm->src, + ntunm->dest, ntunm->sgt); +} + +/* + * nss_trustsec_tx_log_verbose() + * Log message contents. + */ +static void nss_trustsec_tx_log_verbose(struct nss_trustsec_tx_msg *ntm) +{ + switch (ntm->cm.type) { + case NSS_TRUSTSEC_TX_MSG_CONFIGURE: + nss_trustsec_tx_log_configure_msg(ntm); + break; + + case NSS_TRUSTSEC_TX_MSG_UNCONFIGURE: + nss_trustsec_tx_log_unconfigure_msg(ntm); + break; + + case NSS_TRUSTSEC_TX_MSG_UPDATE_NEXTHOP: + nss_trustsec_tx_log_update_nexthop_msg(ntm); + break; + + case NSS_TRUSTSEC_TX_MSG_STATS_SYNC: + /* + * No log for valid stats message. + */ + break; + + default: + nss_warning("%px: Invalid message type\n", ntm); + break; + } +} + +/* + * nss_trustsec_tx_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_trustsec_tx_log_tx_msg(struct nss_trustsec_tx_msg *ntm) +{ + if (ntm->cm.type >= NSS_TRUSTSEC_TX_MSG_MAX) { + nss_warning("%px: Invalid message type\n", ntm); + return; + } + + nss_info("%px: type[%d]:%s\n", ntm, ntm->cm.type, nss_trustsec_tx_log_message_types_str[ntm->cm.type]); + nss_trustsec_tx_log_verbose(ntm); +} + +/* + * nss_trustsec_tx_log_rx_msg() + * Log messages received from FW. + */ +void nss_trustsec_tx_log_rx_msg(struct nss_trustsec_tx_msg *ntm) +{ + if (ntm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", ntm); + return; + } + + if (ntm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ntm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", ntm, ntm->cm.type, + nss_trustsec_tx_log_message_types_str[ntm->cm.type], + ntm->cm.response, nss_cmn_response_str[ntm->cm.response]); + goto verbose; + } + + if (ntm->cm.error >= NSS_TRUSTSEC_TX_ERR_UNKNOWN) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + ntm, ntm->cm.type, nss_trustsec_tx_log_message_types_str[ntm->cm.type], + ntm->cm.response, nss_cmn_response_str[ntm->cm.response], + ntm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + ntm, ntm->cm.type, nss_trustsec_tx_log_message_types_str[ntm->cm.type], + ntm->cm.response, nss_cmn_response_str[ntm->cm.response], + ntm->cm.error, nss_trustsec_tx_log_error_response_types_str[ntm->cm.error]); + +verbose: + nss_trustsec_tx_log_verbose(ntm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_trustsec_tx_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_trustsec_tx_log.h new file mode 100644 index 000000000..58633c942 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_trustsec_tx_log.h @@ -0,0 +1,37 @@ +/* + ****************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_TRUSTSEC_TX_LOG_H__ +#define __NSS_TRUSTSEC_TX_LOG_H__ + +/* + * nss_trustsec_tx_log.h + * NSS TRUSTSEC_TX Log Header File + */ + +/* + * nss_trustsec_tx_log_tx_msg + * Logs a trustsec_tx message that is sent to the NSS firmware. + */ +void nss_trustsec_tx_log_tx_msg(struct nss_trustsec_tx_msg *ncm); + +/* + * nss_trustsec_tx_log_rx_msg + * Logs a trustsec_tx message that is received from the NSS firmware. + */ +void nss_trustsec_tx_log_rx_msg(struct nss_trustsec_tx_msg *ncm); + +#endif /* __NSS_TRUSTSEC_TX_LOG_H__ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_trustsec_tx_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_trustsec_tx_stats.c new file mode 100644 index 000000000..5302321ae --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_trustsec_tx_stats.c @@ -0,0 +1,145 @@ +/* + ************************************************************************** + * Copyright (c) 2017, 2019 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_trustsec_tx_stats.h" + +/* + * nss_trustsec_tx_stats_str + * Trustsec TX statistics strings. + */ + +struct nss_stats_info nss_trustsec_tx_stats_str[NSS_TRUSTSEC_TX_STATS_MAX] = { + {"INVALID_SRC" , NSS_STATS_TYPE_ERROR}, + {"UNCONFIGURED_SRC" , NSS_STATS_TYPE_ERROR}, + {"HEADROOM_NOT_ENOUGH" , NSS_STATS_TYPE_ERROR} +}; + +/* + * trustsec_tx_stats + * Trustsec TX statistics. + */ +uint64_t trustsec_tx_stats[NSS_TRUSTSEC_TX_STATS_MAX]; + +/* + * Trustsec TX statistics APIs + */ + +/* + * nss_trustsec_tx_stats_sync() + * Update trustsec_tx node statistics. + */ +void nss_trustsec_tx_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_trustsec_tx_stats_sync_msg *ntsm) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + int j; + + spin_lock_bh(&nss_top->stats_lock); + + /* + * Update common node stats + */ + nss_top->stats_node[NSS_TRUSTSEC_TX_INTERFACE][NSS_STATS_NODE_RX_PKTS] += ntsm->node_stats.rx_packets; + nss_top->stats_node[NSS_TRUSTSEC_TX_INTERFACE][NSS_STATS_NODE_RX_BYTES] += ntsm->node_stats.rx_bytes; + nss_top->stats_node[NSS_TRUSTSEC_TX_INTERFACE][NSS_STATS_NODE_TX_PKTS] += ntsm->node_stats.tx_packets; + nss_top->stats_node[NSS_TRUSTSEC_TX_INTERFACE][NSS_STATS_NODE_TX_BYTES] += ntsm->node_stats.tx_bytes; + + for (j = 0; j < NSS_MAX_NUM_PRI; j++) { + nss_top->stats_node[NSS_TRUSTSEC_TX_INTERFACE][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + j] += ntsm->node_stats.rx_dropped[j]; + } + + /* + * Update trustsec node stats + */ + trustsec_tx_stats[NSS_TRUSTSEC_TX_STATS_INVALID_SRC] += ntsm->invalid_src; + trustsec_tx_stats[NSS_TRUSTSEC_TX_STATS_UNCONFIGURED_SRC] += ntsm->unconfigured_src; + trustsec_tx_stats[NSS_TRUSTSEC_TX_STATS_HEADROOM_NOT_ENOUGH] += ntsm->headroom_not_enough; + + spin_unlock_bh(&nss_top->stats_lock); +} + +/* + * nss_trustsec_tx_stats_read() + * Read trustsec_tx statiistics. + */ +static ssize_t nss_trustsec_tx_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i; + + /* + * Max output lines = #stats + few blank lines for banner printing + + * Number of Extra outputlines for future reference to add new stats. + */ + uint32_t max_output_lines = NSS_STATS_NODE_MAX + NSS_TRUSTSEC_TX_STATS_MAX + NSS_STATS_EXTRA_OUTPUT_LINES; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + stats_shadow = kzalloc(NSS_STATS_NODE_MAX * 8, GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return 0; + } + + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "trustsec_tx", NSS_STATS_SINGLE_CORE); + + /* + * Common node stats + */ + size_wr += nss_stats_fill_common_stats(NSS_TRUSTSEC_TX_INTERFACE, NSS_STATS_SINGLE_INSTANCE, lbuf, size_wr, size_al, "trustsec_tx"); + + /* + * TrustSec TX node stats + */ + spin_lock_bh(&nss_top_main.stats_lock); + for (i = 0; (i < NSS_TRUSTSEC_TX_STATS_MAX); i++) { + stats_shadow[i] = trustsec_tx_stats[i]; + } + + spin_unlock_bh(&nss_top_main.stats_lock); + size_wr += nss_stats_print("trustsec_tx", NULL, NSS_STATS_SINGLE_INSTANCE + , nss_trustsec_tx_stats_str + , stats_shadow + , NSS_TRUSTSEC_TX_STATS_MAX + , lbuf, size_wr, size_al); + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * nss_trustsec_tx_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(trustsec_tx) + +/* + * nss_trustsec_tx_stats_dentry_create() + * Create trustsec_tx statistics debug entry. + */ +void nss_trustsec_tx_stats_dentry_create(void) +{ + nss_stats_create_dentry("trustsec_tx", &nss_trustsec_tx_stats_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_trustsec_tx_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_trustsec_tx_stats.h new file mode 100644 index 000000000..11a4d8f56 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_trustsec_tx_stats.h @@ -0,0 +1,44 @@ +/* + ************************************************************************** + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_trustsec_tx_stats.h + * NSS TRUSTSEC TX statistics header file. + */ + +#ifndef __NSS_TRUSTSEC_TX_STATS_H +#define __NSS_TRUSTSEC_TX_STATS_H + +/* + * Trustsec TX statistics + */ +enum nss_trustsec_tx_stats { + NSS_TRUSTSEC_TX_STATS_INVALID_SRC, + /* Number of packets with invalid src if */ + NSS_TRUSTSEC_TX_STATS_UNCONFIGURED_SRC, + /* Number of packets with unconfigured src if */ + NSS_TRUSTSEC_TX_STATS_HEADROOM_NOT_ENOUGH, + /* Number of packets with not enough headroom */ + NSS_TRUSTSEC_TX_STATS_MAX +}; + +/* + * Trustsec TX statistics APIs + */ +extern void nss_trustsec_tx_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_trustsec_tx_stats_sync_msg *ntsm); +extern void nss_trustsec_tx_stats_dentry_create(void); + +#endif /* __NSS_TRUSTSEC_TX_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_tstamp.c b/feeds/ipq807x/qca-nss-drv/src/nss_tstamp.c new file mode 100644 index 000000000..1984afb07 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_tstamp.c @@ -0,0 +1,423 @@ +/* + ************************************************************************** + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_tstamp.c + * NSS Tstamp APIs + */ + +#include +#include +#include +#include +#include +#include +#include "nss_tx_rx_common.h" +#include "nss_tstamp.h" +#include "nss_tstamp_stats.h" + +#define NSS_TSTAMP_HEADER_SIZE max(sizeof(struct nss_tstamp_h2n_pre_hdr), sizeof(struct nss_tstamp_n2h_pre_hdr)) + +/* + * Notify data structure + */ +struct nss_tstamp_notify_data { + nss_tstamp_msg_callback_t tstamp_callback; + void *app_data; +}; + +static struct nss_tstamp_notify_data nss_tstamp_notify = { + .tstamp_callback = NULL, + .app_data = NULL, +}; + +static struct net_device_stats *nss_tstamp_ndev_stats(struct net_device *ndev); + +/* + * dummy netdevice ops + */ +static const struct net_device_ops nss_tstamp_ndev_ops = { + .ndo_get_stats = nss_tstamp_ndev_stats, +}; + +/* + * nss_tstamp_ndev_setup() + * Dummy setup for net_device handler + */ +static void nss_tstamp_ndev_setup(struct net_device *ndev) +{ + return; +} + +/* + * nss_tstamp_ndev_stats() + * Return net device stats + */ +static struct net_device_stats *nss_tstamp_ndev_stats(struct net_device *ndev) +{ + return &ndev->stats; +} + +/* + * nss_tstamp_verify_if_num() + * Verify if_num passed to us. + */ +static bool nss_tstamp_verify_if_num(uint32_t if_num) +{ + return (if_num == NSS_TSTAMP_TX_INTERFACE) || (if_num == NSS_TSTAMP_RX_INTERFACE); +} + +/* + * nss_tstamp_interface_handler() + * Handle NSS -> HLOS messages for TSTAMP Statistics + */ +static void nss_tstamp_interface_handler(struct nss_ctx_instance *nss_ctx, + struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_tstamp_msg *ntm = (struct nss_tstamp_msg *)ncm; + nss_tstamp_msg_callback_t cb; + + if (!nss_tstamp_verify_if_num(ncm->interface)) { + nss_warning("%px: invalid interface %d for tstamp_tx", nss_ctx, ncm->interface); + return; + } + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_TSTAMP_MSG_TYPE_MAX) { + nss_warning("%px: received invalid message %d for tstamp", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_tstamp_msg)) { + nss_warning("%px: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + switch (ntm->cm.type) { + case NSS_TSTAMP_MSG_TYPE_SYNC_STATS: + nss_tstamp_stats_sync(nss_ctx, &ntm->msg.stats, ncm->interface); + break; + default: + nss_warning("%px: Unknown message type %d", + nss_ctx, ncm->type); + return; + } + + /* + * Update the callback and app_data for NOTIFY messages + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_tstamp_notify.tstamp_callback; + ncm->app_data = (nss_ptr_t)nss_tstamp_notify.app_data; + } + + /* + * Do we have a callback? + */ + if (!ncm->cb) { + return; + } + + /* + * callback + */ + cb = (nss_tstamp_msg_callback_t)ncm->cb; + cb((void *)ncm->app_data, ntm); +} + +/* + * nss_tstamp_copy_data() + * Copy timestamps from received nss frame into skb + */ +static void nss_tstamp_copy_data(struct nss_tstamp_n2h_pre_hdr *ntm, struct sk_buff *skb) +{ + struct skb_shared_hwtstamps *tstamp; + + tstamp = skb_hwtstamps(skb); + tstamp->hwtstamp = ktime_set(ntm->ts_data_hi, ntm->ts_data_lo); +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 16, 0)) + tstamp->syststamp = ktime_set(ntm->ts_data_hi, ntm->ts_data_lo); +#endif +} + +/* + * nss_tstamp_get_dev() + * Get the net_device associated with the packet. + */ +static struct net_device *nss_tstamp_get_dev(struct sk_buff *skb) +{ + struct dst_entry *dst; + struct net_device *dev; + struct rtable *rt; + struct flowi6 fl6; + uint32_t ip_addr; + + /* + * It seems like the data came over IPsec, hence indicate + * it to the Linux over this interface + */ + skb_reset_network_header(skb); + skb_reset_mac_header(skb); + + skb->pkt_type = PACKET_HOST; + + switch (ip_hdr(skb)->version) { + case IPVERSION: + ip_addr = ip_hdr(skb)->saddr; + + rt = ip_route_output(&init_net, ip_addr, 0, 0, 0); + if (IS_ERR(rt)) { + return NULL; + } + + dst = (struct dst_entry *)rt; + skb->protocol = cpu_to_be16(ETH_P_IP); + break; + + case 6: + memset(&fl6, 0, sizeof(fl6)); + memcpy(&fl6.daddr, &ipv6_hdr(skb)->saddr, sizeof(fl6.daddr)); + + dst = ip6_route_output(&init_net, NULL, &fl6); + if (IS_ERR(dst)) { + return NULL; + } + + skb->protocol = cpu_to_be16(ETH_P_IPV6); + break; + + default: + nss_warning("%px:could not get dev for the skb\n", skb); + return NULL; + } + + dev = dst->dev; + dev_hold(dev); + + dst_release(dst); + return dev; +} + +/* + * nss_tstamp_buf_receive() + * Receive nss exception packets. + */ +static void nss_tstamp_buf_receive(struct net_device *ndev, struct sk_buff *skb, struct napi_struct *napi) +{ + struct nss_tstamp_n2h_pre_hdr *n2h_hdr = (struct nss_tstamp_n2h_pre_hdr *)skb->data; + struct nss_ctx_instance *nss_ctx; + struct net_device *dev; + uint32_t tstamp_sz; + + BUG_ON(!n2h_hdr); + + tstamp_sz = n2h_hdr->ts_hdr_sz; + if (tstamp_sz > (NSS_TSTAMP_HEADER_SIZE)) { + goto free; + } + + nss_ctx = &nss_top_main.nss[nss_top_main.tstamp_handler_id]; + BUG_ON(!nss_ctx); + + skb_pull_inline(skb, tstamp_sz); + + /* + * copy the time stamp and convert into ktime_t + */ + nss_tstamp_copy_data(n2h_hdr, skb); + if (unlikely(n2h_hdr->ts_tx)) { + /* + * We are in TX Path + */ + skb_tstamp_tx(skb, skb_hwtstamps(skb)); + + ndev->stats.tx_packets++; + ndev->stats.tx_bytes += skb->len; + goto free; + } + + /* + * We are in RX path. + */ + dev = nss_cmn_get_interface_dev(nss_ctx, n2h_hdr->ts_ifnum); + if (!dev) { + ndev->stats.rx_dropped++; + goto free; + } + + /* + * Hold the dev until we finish + */ + dev_hold(dev); + + switch(dev->type) { + case NSS_IPSEC_ARPHRD_IPSEC: + /* + * Release the prev dev reference + */ + dev_put(dev); + + /* + * find the actual IPsec tunnel device + */ + dev = nss_tstamp_get_dev(skb); + break; + + default: + /* + * This is a plain non-encrypted data packet. + */ + skb->protocol = eth_type_trans(skb, dev); + break; + } + + skb->skb_iif = dev->ifindex; + skb->dev = dev; + + ndev->stats.rx_packets++; + ndev->stats.rx_bytes += skb->len; + + netif_receive_skb(skb); + + /* + * release the device as we are done + */ + dev_put(dev); + return; +free: + dev_kfree_skb_any(skb); + return; +} + +/* + * nss_tstamp_tx_buf() + * Send data packet for tstamp processing + */ +nss_tx_status_t nss_tstamp_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *skb, uint32_t if_num) +{ + struct nss_tstamp_h2n_pre_hdr *h2n_hdr; + int extra_head; + int extra_tail = 0; + char *align_data; + uint32_t hdr_sz; + + nss_trace("%px: Tstamp If Tx packet, id:%d, data=%px", nss_ctx, NSS_TSTAMP_RX_INTERFACE, skb->data); + + /* + * header size + alignment size + */ + hdr_sz = NSS_TSTAMP_HEADER_SIZE; + extra_head = hdr_sz - skb_headroom(skb); + + /* + * Expand the head for h2n_hdr + */ + if (extra_head > 0) { + /* + * Try to accommodate using available tailroom. + */ + if (skb->end - skb->tail >= extra_head) + extra_tail = -extra_head; + if (pskb_expand_head(skb, extra_head, extra_tail, GFP_KERNEL)) { + nss_trace("%px: expand head room failed", nss_ctx); + return NSS_TX_FAILURE; + } + } + + align_data = PTR_ALIGN((skb->data - hdr_sz), sizeof(uint32_t)); + hdr_sz = (nss_ptr_t)skb->data - (nss_ptr_t)align_data; + + h2n_hdr = (struct nss_tstamp_h2n_pre_hdr *)skb_push(skb, hdr_sz); + h2n_hdr->ts_ifnum = if_num; + h2n_hdr->ts_tx_hdr_sz = hdr_sz; + + return nss_core_send_packet(nss_ctx, skb, NSS_TSTAMP_RX_INTERFACE, H2N_BIT_FLAG_VIRTUAL_BUFFER | H2N_BIT_FLAG_BUFFER_REUSABLE); +} +EXPORT_SYMBOL(nss_tstamp_tx_buf); + +/* + * nss_tstamp_register_netdev() + * register dummy netdevice for tstamp interface + */ +struct net_device *nss_tstamp_register_netdev(void) +{ + struct net_device *ndev; + uint32_t err = 0; + +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 16, 0)) + ndev = alloc_netdev(sizeof(struct netdev_priv_instance), "qca-nss-tstamp", nss_tstamp_ndev_setup); +#else + ndev = alloc_netdev(sizeof(struct netdev_priv_instance), "qca-nss-tstamp", NET_NAME_ENUM, nss_tstamp_ndev_setup); +#endif + if (!ndev) { + nss_warning("Tstamp: Could not allocate tstamp net_device "); + return NULL; + } + + ndev->netdev_ops = &nss_tstamp_ndev_ops; + + err = register_netdev(ndev); + if (err) { + nss_warning("Tstamp: Could not register tstamp net_device "); + free_netdev(ndev); + return NULL; + } + + return ndev; +} + +/* + * nss_tstamp_notify_register() + * Register to receive tstamp notify messages. + */ +struct nss_ctx_instance *nss_tstamp_notify_register(nss_tstamp_msg_callback_t cb, void *app_data) +{ + struct nss_ctx_instance *nss_ctx; + + nss_ctx = &nss_top_main.nss[nss_top_main.tstamp_handler_id]; + + nss_tstamp_notify.tstamp_callback = cb; + nss_tstamp_notify.app_data = app_data; + + return nss_ctx; +} +EXPORT_SYMBOL(nss_tstamp_notify_register); + +/* + * nss_tstamp_register_handler() + */ +void nss_tstamp_register_handler(struct net_device *ndev) +{ + uint32_t features = 0; + struct nss_ctx_instance *nss_ctx; + + nss_ctx = &nss_top_main.nss[nss_top_main.tstamp_handler_id]; + + nss_core_register_subsys_dp(nss_ctx, NSS_TSTAMP_TX_INTERFACE, nss_tstamp_buf_receive, NULL, NULL, ndev, features); + + nss_core_register_handler(nss_ctx, NSS_TSTAMP_TX_INTERFACE, nss_tstamp_interface_handler, NULL); + + nss_core_register_handler(nss_ctx, NSS_TSTAMP_RX_INTERFACE, nss_tstamp_interface_handler, NULL); + + nss_tstamp_stats_dentry_create(); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_tstamp_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_tstamp_stats.c new file mode 100644 index 000000000..6285ad84b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_tstamp_stats.c @@ -0,0 +1,165 @@ +/* + ************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_stats.h" +#include "nss_core.h" +#include "nss_tstamp_stats.h" + +/* + * Spinlock to protect TSTAMP statistics update/read + */ +DEFINE_SPINLOCK(nss_tstamp_stats_lock); + +/* + * nss_tstamp_stats_str + * TSTAMP stats strings + */ +struct nss_stats_info nss_tstamp_stats_str[NSS_TSTAMP_STATS_MAX] = { + {"rx_packets" , NSS_STATS_TYPE_COMMON}, + {"rx_bytes" , NSS_STATS_TYPE_COMMON}, + {"tx_packets" , NSS_STATS_TYPE_COMMON}, + {"tx_bytes" , NSS_STATS_TYPE_COMMON}, + {"rx_queue_0_dropped" , NSS_STATS_TYPE_DROP}, + {"rx_queue_1_dropped" , NSS_STATS_TYPE_DROP}, + {"rx_queue_2_dropped" , NSS_STATS_TYPE_DROP}, + {"rx_queue_3_dropped" , NSS_STATS_TYPE_DROP}, + {"boomeranged" , NSS_STATS_TYPE_SPECIAL}, + {"dropped_fail_enqueue" , NSS_STATS_TYPE_DROP}, + {"dropped_fail_alloc" , NSS_STATS_TYPE_DROP}, + {"dropped_fail_copy" , NSS_STATS_TYPE_DROP}, + {"dropped_no_interface" , NSS_STATS_TYPE_DROP}, + {"dropped_no_headroom" , NSS_STATS_TYPE_DROP} +}; + +/* + * nss_tstamp_stats + * tstamp statistics + */ +uint64_t nss_tstamp_stats[2][NSS_TSTAMP_STATS_MAX]; + +/* + * nss_tstamp_stats_read() + * Read tstamp statistics + */ +static ssize_t nss_tstamp_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + int32_t i, num; + + /* + * Max output lines = (#stats + tx or rx tag + two blank lines) * 2(TX and RX) + + * start tag line + end tag line + three blank lines + */ + uint32_t max_output_lines = (NSS_TSTAMP_STATS_MAX + 3) * 2 + 5; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return -ENOMEM; + } + + stats_shadow = kzalloc(NSS_TSTAMP_STATS_MAX * sizeof(uint64_t), GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return -ENOMEM; + } + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "tstamp", NSS_STATS_SINGLE_CORE); + /* + * TSTAMP statistics + */ + for (num = 0; num < 2; num++) { + if (num == 0) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ntstamp TX stats:\n\n"); + } else { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ntstamp RX stats:\n\n"); + } + + spin_lock_bh(&nss_tstamp_stats_lock); + for (i = 0; i < NSS_TSTAMP_STATS_MAX; i++) { + stats_shadow[i] = nss_tstamp_stats[num][i]; + } + spin_unlock_bh(&nss_tstamp_stats_lock); + size_wr += nss_stats_print("tstamp", NULL, NSS_STATS_SINGLE_INSTANCE + , nss_tstamp_stats_str + , stats_shadow + , NSS_TSTAMP_STATS_MAX + , lbuf, size_wr, size_al); + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * nss_tstamp_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(tstamp) + +/* + * nss_tstamp_stats_dentry_create() + * Create tstamp statistics debug entry. + */ +void nss_tstamp_stats_dentry_create(void) +{ + nss_stats_create_dentry("tstamp", &nss_tstamp_stats_ops); +} + +/* + * nss_tstamp_stats_sync() + * Handle the syncing of NSS TSTAMP statistics. + */ +void nss_tstamp_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_tstamp_stats_msg *nts, uint32_t interface) +{ + int id, j; + + if (interface == NSS_TSTAMP_TX_INTERFACE) { + id = 0; + } else { + id = 1; + } + + spin_lock_bh(&nss_tstamp_stats_lock); + + /* + * Common node stats + */ + nss_tstamp_stats[id][NSS_STATS_NODE_RX_PKTS] += nts->node_stats.rx_packets; + nss_tstamp_stats[id][NSS_STATS_NODE_RX_BYTES] += nts->node_stats.rx_bytes; + nss_tstamp_stats[id][NSS_STATS_NODE_TX_PKTS] += nts->node_stats.tx_packets; + nss_tstamp_stats[id][NSS_STATS_NODE_TX_BYTES] += nts->node_stats.tx_bytes; + + for (j = 0; j < NSS_MAX_NUM_PRI; j++) { + nss_tstamp_stats[id][NSS_STATS_NODE_RX_QUEUE_0_DROPPED + j] += nts->node_stats.rx_dropped[j]; + } + + /* + * TSTAMP statistics + */ + nss_tstamp_stats[id][NSS_TSTAMP_STATS_BOOMERANGED] += nts->boomeranged; + nss_tstamp_stats[id][NSS_TSTAMP_STATS_DROPPED_FAIL_ENQUEUE] += nts->dropped_fail_enqueue; + nss_tstamp_stats[id][NSS_TSTAMP_STATS_DROPPED_FAIL_ALLOC] += nts->dropped_fail_alloc; + nss_tstamp_stats[id][NSS_TSTAMP_STATS_DROPPED_FAIL_COPY] += nts->dropped_fail_copy; + nss_tstamp_stats[id][NSS_TSTAMP_STATS_DROPPED_NO_INTERFACE] += nts->dropped_no_interface; + nss_tstamp_stats[id][NSS_TSTAMP_STATS_DROPPED_NO_HEADROOM] += nts->dropped_no_headroom; + spin_unlock_bh(&nss_tstamp_stats_lock); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_tstamp_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_tstamp_stats.h new file mode 100644 index 000000000..d488ae7d7 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_tstamp_stats.h @@ -0,0 +1,48 @@ +/* + ****************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_TSTAMP_STATS_H +#define __NSS_TSTAMP_STATS_H + +#include + +/** + * TSTAMP node statistics + */ +enum nss_tstamp_stats_types { + + NSS_TSTAMP_STATS_BOOMERANGED = NSS_STATS_NODE_MAX, + /**< Number of boomeranged packets. */ + NSS_TSTAMP_STATS_DROPPED_FAIL_ENQUEUE, + /**< Number of failed enqueue drops. */ + NSS_TSTAMP_STATS_DROPPED_FAIL_ALLOC, + /**< Number of failed allocation drops. */ + NSS_TSTAMP_STATS_DROPPED_FAIL_COPY, + /**< Number of failed copy drops. */ + NSS_TSTAMP_STATS_DROPPED_NO_INTERFACE, + /**< Number of failed no interface drops. */ + NSS_TSTAMP_STATS_DROPPED_NO_HEADROOM, + /**< Number of failed no headroom drops. */ + NSS_TSTAMP_STATS_MAX, +}; + +/* + * TSTAMP statistics APIs + */ +extern void nss_tstamp_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_tstamp_stats_msg *nts, uint32_t interface); +extern void nss_tstamp_stats_dentry_create(void); + +#endif /* __NSS_TSTAMP_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_tun6rd.c b/feeds/ipq807x/qca-nss-drv/src/nss_tun6rd.c new file mode 100644 index 000000000..af1a4ac2f --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_tun6rd.c @@ -0,0 +1,183 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_tun6rd_log.h" + +/* + * nss_tun6rd_handler() + * Handle NSS -> HLOS messages for 6rd tunnel + */ +static void nss_tun6rd_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_tun6rd_msg *ntm = (struct nss_tun6rd_msg *)ncm; + void *ctx; + + nss_tun6rd_msg_callback_t cb; + + BUG_ON(!nss_is_dynamic_interface(ncm->interface)); + + /* + * Trace Messages + */ + nss_tun6rd_log_rx_msg(ntm); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_TUN6RD_MAX) { + nss_warning("%px: received invalid message %d for Tun6RD interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_tun6rd_msg)) { + nss_warning("%px: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Update the callback and app_data for NOTIFY messages, tun6rd sends all notify messages + * to the same callback/app_data. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_ctx->nss_top->tun6rd_msg_callback; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Do we have a call back + */ + if (!ncm->cb) { + return; + } + + /* + * callback + */ + cb = (nss_tun6rd_msg_callback_t)ncm->cb; + ctx = nss_ctx->subsys_dp_register[ncm->interface].ndev; + + /* + * call 6rd tunnel callback + */ + if (!ctx) { + nss_warning("%px: Event received for 6rd tunnel interface %d before registration", nss_ctx, ncm->interface); + return; + } + + cb(ctx, ntm); +} + +/* + * nss_tun6rd_tx() + * Transmit a tun6rd message to NSSFW + */ +nss_tx_status_t nss_tun6rd_tx(struct nss_ctx_instance *nss_ctx, struct nss_tun6rd_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Trace Messages + */ + nss_tun6rd_log_tx_msg(msg); + + /* + * Sanity check the message + */ + if (!nss_is_dynamic_interface(ncm->interface)) { + nss_warning("%px: tx request for another interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type > NSS_TUN6RD_MAX) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} + +/* + *********************************** + * Register/Unregister/Miscellaneous APIs + *********************************** + */ + +/* + * nss_register_tun6rd_if() + */ +struct nss_ctx_instance *nss_register_tun6rd_if(uint32_t if_num, uint32_t type, nss_tun6rd_callback_t tun6rd_callback, + nss_tun6rd_msg_callback_t event_callback, struct net_device *netdev, uint32_t features) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.tun6rd_handler_id]; + + nss_assert(nss_ctx); + nss_assert((if_num >= NSS_DYNAMIC_IF_START) && (if_num < NSS_SPECIAL_IF_START)); + + nss_core_register_subsys_dp(nss_ctx, if_num, tun6rd_callback, NULL, NULL, netdev, features); + nss_ctx->subsys_dp_register[if_num].type = type; + + nss_top_main.tun6rd_msg_callback = event_callback; + + nss_core_register_handler(nss_ctx, if_num, nss_tun6rd_handler, NULL); + + return nss_ctx; +} + +/* + * nss_tun6rd_get_context() + */ +struct nss_ctx_instance *nss_tun6rd_get_context() +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.tun6rd_handler_id]; +} + +/* + * nss_unregister_tun6rd_if() + */ +void nss_unregister_tun6rd_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.tun6rd_handler_id]; + + nss_assert(nss_ctx); + nss_assert(nss_is_dynamic_interface(if_num)); + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + nss_ctx->subsys_dp_register[if_num].type = 0; + + nss_top_main.tun6rd_msg_callback = NULL; + + nss_core_unregister_handler(nss_ctx, if_num); +} + +/* + * nss_tun6rd_msg_init() + * Initialize nss_tun6rd msg. + */ +void nss_tun6rd_msg_init(struct nss_tun6rd_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data) +{ + nss_cmn_msg_init(&ncm->cm, if_num, type, len, cb, app_data); +} + +EXPORT_SYMBOL(nss_tun6rd_get_context); +EXPORT_SYMBOL(nss_tun6rd_tx); +EXPORT_SYMBOL(nss_register_tun6rd_if); +EXPORT_SYMBOL(nss_unregister_tun6rd_if); +EXPORT_SYMBOL(nss_tun6rd_msg_init); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_tun6rd_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_tun6rd_log.c new file mode 100644 index 000000000..121d70f82 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_tun6rd_log.c @@ -0,0 +1,132 @@ +/* + ************************************************************************** + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_tun6rd_log.c + * NSS TUN6RD logger file. + */ + +#include "nss_core.h" + +/* + * nss_tun6rd_log_message_types_str + * NSS TUN6RD message strings + */ +static int8_t *nss_tun6rd_log_message_types_str[NSS_TUN6RD_MAX] __maybe_unused = { + "TUN6RD Attach PNODE", + "TUN6RD Stats", + "TUN6RD Update Peer", +}; + +/* + * nss_tun6rd_log_attach_pnode_msg() + * Log NSS TUN6RD Attach PNODE + */ +static void nss_tun6rd_log_attach_pnode_msg(struct nss_tun6rd_msg *ntm) +{ + struct nss_tun6rd_attach_tunnel_msg *ntam __maybe_unused = &ntm->msg.tunnel; + nss_trace("%px: NSS TUN6RD Attach Tunnel message \n" + "TUN6RD Source Address: %pI4\n" + "TUN6RD Destination Address: %pI4\n" + "TUN6RD Type of Service: %d\n" + "TUN6RD Time To Live: %d\n" + "TUN6RD Sibling Interface Number: %d\n", + ntam, &ntam->saddr, + &ntam->daddr, ntam->tos, + ntam->ttl, ntam->sibling_if_num); +} + +/* + * nss_tun6rd_log_set_peer_msg() + * Log NSS TUN6RD Set Peer Message + */ +static void nss_tun6rd_log_set_peer_msg(struct nss_tun6rd_msg *ntm) +{ + struct nss_tun6rd_set_peer_msg *ntspm __maybe_unused = &ntm->msg.peer; + nss_trace("%px: NSS TUN6RD Set Peer message \n" + "TUN6RD IPv6 Address: %pI6\n" + "TUN6RD Destination: %pI4\n", + ntspm, ntspm->ipv6_address, + &ntspm->dest); +} + +/* + * nss_tun6rd_log_verbose() + * Log message contents. + */ +static void nss_tun6rd_log_verbose(struct nss_tun6rd_msg *ntm) +{ + switch (ntm->cm.type) { + case NSS_TUN6RD_ATTACH_PNODE: + nss_tun6rd_log_attach_pnode_msg(ntm); + break; + + case NSS_TUN6RD_ADD_UPDATE_PEER: + nss_tun6rd_log_set_peer_msg(ntm); + break; + + case NSS_TUN6RD_RX_STATS_SYNC: + /* + * No log for valid stats message. + */ + break; + + default: + nss_trace("%px: Invalid message type\n", ntm); + break; + } +} + +/* + * nss_tun6rd_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_tun6rd_log_tx_msg(struct nss_tun6rd_msg *ntm) +{ + if (ntm->cm.type >= NSS_TUN6RD_MAX) { + nss_warning("%px: Invalid message type\n", ntm); + return; + } + + nss_info("%px: type[%d]:%s\n", ntm, ntm->cm.type, nss_tun6rd_log_message_types_str[ntm->cm.type]); + nss_tun6rd_log_verbose(ntm); +} + +/* + * nss_tun6rd_log_rx_msg() + * Log messages received from FW. + */ +void nss_tun6rd_log_rx_msg(struct nss_tun6rd_msg *ntm) +{ + if (ntm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", ntm); + return; + } + + if (ntm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ntm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", ntm, ntm->cm.type, + nss_tun6rd_log_message_types_str[ntm->cm.type], + ntm->cm.response, nss_cmn_response_str[ntm->cm.response]); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s\n", + ntm, ntm->cm.type, nss_tun6rd_log_message_types_str[ntm->cm.type], + ntm->cm.response, nss_cmn_response_str[ntm->cm.response]); + +verbose: + nss_tun6rd_log_verbose(ntm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_tun6rd_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_tun6rd_log.h new file mode 100644 index 000000000..c7c3b3a90 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_tun6rd_log.h @@ -0,0 +1,41 @@ +/* + ************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_TUN6RD_LOG_H +#define __NSS_TUN6RD_LOG_H + +/* + * nss_tun6rd.h + * NSS TUN6RD header file. + */ + +/* + * Logger APIs + */ + +/* + * nss_tun6rd_log_tx_msg + * Logs a tun6rd message that is sent to the NSS firmware. + */ +void nss_tun6rd_log_tx_msg(struct nss_tun6rd_msg *ntm); + +/* + * nss_tun6rd_log_rx_msg + * Logs a tun6rd message that is received from the NSS firmware. + */ +void nss_tun6rd_log_rx_msg(struct nss_tun6rd_msg *ntm); + +#endif /* __NSS_TUN6RD_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_tunipip6.c b/feeds/ipq807x/qca-nss-drv/src/nss_tunipip6.c new file mode 100644 index 000000000..1801e861f --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_tunipip6.c @@ -0,0 +1,291 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_tunipip6_log.h" +#include "nss_tunipip6_stats.h" + +#define NSS_TUNIPIP6_TX_TIMEOUT 3000 + +/* + * Data structure used to handle sync message. + */ +static struct nss_tunipip6_pvt { + struct semaphore sem; /* Semaphore structure. */ + struct completion complete; /* Completion structure. */ + int response; /* Response from FW. */ + void *cb; /* Original cb for msgs. */ + void *app_data; /* Original app_data for msgs. */ +} tunipip6_pvt; + +/* + * nss_tunipip6_verify_if_num + * Verify the interface is a valid interface + */ +static bool nss_tunipip6_verify_if_num(uint32_t if_num) +{ + enum nss_dynamic_interface_type type; + + type = nss_dynamic_interface_get_type(nss_tunipip6_get_context(), if_num); + + switch (type) { + case NSS_DYNAMIC_INTERFACE_TYPE_TUNIPIP6_INNER: + case NSS_DYNAMIC_INTERFACE_TYPE_TUNIPIP6_OUTER: + return true; + default: + return false; + } +} + +/* + * nss_tunipip6_handler() + * Handle NSS -> HLOS messages for ipip6 tunnel + */ +static void nss_tunipip6_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_tunipip6_msg *ntm = (struct nss_tunipip6_msg *)ncm; + void *ctx; + nss_tunipip6_msg_callback_t cb; + + BUG_ON(!nss_tunipip6_verify_if_num(ncm->interface)); + + /* + * Trace Messages + */ + nss_tunipip6_log_rx_msg(ntm); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_TUNIPIP6_MAX) { + nss_warning("%px: received invalid message %d for DS-Lite interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_tunipip6_msg)) { + nss_warning("%px: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + switch (ntm->cm.type) { + case NSS_TUNIPIP6_STATS_SYNC: + /* + * Sync common node stats. + */ + nss_tunipip6_stats_sync(nss_ctx, ntm); + break; + } + + /* + * Update the callback and app_data for NOTIFY messages, tunipip6 sends all notify messages + * to the same callback/app_data. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_ctx->nss_top->tunipip6_msg_callback; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Do we have a call back + */ + if (!ncm->cb) { + return; + } + + /* + * callback + */ + cb = (nss_tunipip6_msg_callback_t)ncm->cb; + ctx = nss_ctx->subsys_dp_register[ncm->interface].ndev; + + /* + * call ipip6 tunnel callback + */ + if (!ctx) { + nss_warning("%px: Event received for DS-Lite tunnel interface %d before registration", nss_ctx, ncm->interface); + return; + } + + cb(ctx, ntm); +} + +/* + * nss_tunipip6_tx() + * Transmit a tunipip6 message to NSSFW + */ +nss_tx_status_t nss_tunipip6_tx(struct nss_ctx_instance *nss_ctx, struct nss_tunipip6_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Trace Messages + */ + nss_tunipip6_log_tx_msg(msg); + + /* + * Sanity check the message + */ + if (!nss_tunipip6_verify_if_num(ncm->interface)) { + nss_warning("%px: tx request for another interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type > NSS_TUNIPIP6_MAX) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_tunipip6_tx); + +/* + * nss_tunipip6_callback() + * Callback to handle the completion of NSS->HLOS messages. + */ +static void nss_tunipip6_callback(void *app_data, struct nss_tunipip6_msg *nclm) +{ + tunipip6_pvt.response = NSS_TX_SUCCESS; + tunipip6_pvt.cb = NULL; + tunipip6_pvt.app_data = NULL; + + if (nclm->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("%px: tunipip6 Error response %d Error: %d\n", app_data, nclm->cm.response, nclm->cm.error); + tunipip6_pvt.response = nclm->cm.response; + } + + /* + * Write memory barrier. + */ + smp_wmb(); + complete(&tunipip6_pvt.complete); +} + +/* + * nss_tunipip6_tx_sync() + * Transmit a tunipip6 message to NSSFW synchronously. + */ +nss_tx_status_t nss_tunipip6_tx_sync(struct nss_ctx_instance *nss_ctx, struct nss_tunipip6_msg *msg) +{ + nss_tx_status_t status; + int ret; + + down(&tunipip6_pvt.sem); + msg->cm.cb = (nss_ptr_t)nss_tunipip6_callback; + msg->cm.app_data = (nss_ptr_t)NULL; + + status = nss_tunipip6_tx(nss_ctx, msg); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: tunipip6_tx_msg failed\n", nss_ctx); + up(&tunipip6_pvt.sem); + return status; + } + + ret = wait_for_completion_timeout(&tunipip6_pvt.complete, msecs_to_jiffies(NSS_TUNIPIP6_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: tunipip6 tx sync failed due to timeout\n", nss_ctx); + tunipip6_pvt.response = NSS_TX_FAILURE; + } + + status = tunipip6_pvt.response; + up(&tunipip6_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_tunipip6_tx_sync); + +/* + * ********************************** + * Register/Unregister/Miscellaneous APIs + * ********************************** + */ + +/* + * nss_register_tunipip6_if() + */ +struct nss_ctx_instance *nss_register_tunipip6_if(uint32_t if_num, + uint32_t dynamic_interface_type, + nss_tunipip6_callback_t tunipip6_callback, + nss_tunipip6_msg_callback_t event_callback, + struct net_device *netdev, + uint32_t features) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.tunipip6_handler_id]; + + nss_assert(nss_ctx); + nss_assert(nss_tunipip6_verify_if_num(if_num)); + + nss_ctx->subsys_dp_register[if_num].type = dynamic_interface_type; + nss_top_main.tunipip6_msg_callback = event_callback; + nss_core_register_subsys_dp(nss_ctx, if_num, tunipip6_callback, NULL, NULL, netdev, features); + nss_core_register_handler(nss_ctx, if_num, nss_tunipip6_handler, NULL); + + return nss_ctx; +} +EXPORT_SYMBOL(nss_register_tunipip6_if); + +/* + * nss_unregister_tunipip6_if() + */ +void nss_unregister_tunipip6_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.tunipip6_handler_id]; + + nss_assert(nss_ctx); + nss_assert(nss_tunipip6_verify_if_num(if_num)); + + nss_stats_reset_common_stats(if_num); + nss_core_unregister_handler(nss_ctx, if_num); + nss_core_unregister_subsys_dp(nss_ctx, if_num); + + nss_top_main.tunipip6_msg_callback = NULL; +} +EXPORT_SYMBOL(nss_unregister_tunipip6_if); + +/* + * nss_tunipip6_get_context() + */ +struct nss_ctx_instance *nss_tunipip6_get_context(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.tunipip6_handler_id]; +} +EXPORT_SYMBOL(nss_tunipip6_get_context); + +/* + * nss_tunipip6_register_handler() + */ +void nss_tunipip6_register_handler() +{ + struct nss_ctx_instance *nss_ctx = nss_tunipip6_get_context(); + + nss_core_register_handler(nss_ctx, NSS_TUNIPIP6_INTERFACE, nss_tunipip6_handler, NULL); + nss_tunipip6_stats_dentry_create(); + sema_init(&tunipip6_pvt.sem, 1); + init_completion(&tunipip6_pvt.complete); +} + +/* + * nss_tunipip6_msg_init() + * Initialize nss_tunipip6 msg. + */ +void nss_tunipip6_msg_init(struct nss_tunipip6_msg *ntm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data) +{ + nss_cmn_msg_init(&ntm->cm, if_num, type, len, cb, app_data); +} +EXPORT_SYMBOL(nss_tunipip6_msg_init); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_tunipip6_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_tunipip6_log.c new file mode 100644 index 000000000..1565ed87c --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_tunipip6_log.c @@ -0,0 +1,189 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_tunipip6_log.c + * NSS TUNIPIP6 logger file. + */ + +#include "nss_core.h" + +/* + * nss_tunipip6_log_message_types_str + * NSS TUNIPIP6 message strings + */ +static int8_t *nss_tunipip6_log_message_types_str[NSS_TUNIPIP6_MAX] __maybe_unused = { + "TUNIPIP6 Encap Interface Create", + "TUNIPIP6 Decap Interface Create", + "TUNIPIP6 Stats", + "TUNIPIP6 FMR add", + "TUNIPIP6 FMR delete", + "TUNIPIP6 FMR flush", + "TUNIPIP6 BMR add", + "TUNIPIP6 BMR delete", +}; + +/* + * nss_tunipip6_log_error_types_str + * Strings for error types for TUNIPIP6 messages + */ +static char *nss_tunipip6_log_error_types_str[NSS_TUNIPIP6_ERROR_MAX] __maybe_unused = { + "TUNIPIP6 maximum tunnel reached", + "TUNIPIP6 tunnel already exists", + "TUNIPIP6 configuration parameters are incorrect", + "TUNIPIP6 FMR already exists ", + "TUNIPIP6 no FMR configured", + "TUNIPIP6 FMR table is full", + "TUNIPIP6 invalid FMR", + "TUNIPIP6 BMR already exists", + "TUNIPIP6 no BMR configured", + "TUNIPIP6 memory allocation for FMR failed", + "TUNIPIP6 unknown error", +}; + +/* + * nss_tunipip6_log_map_rule() + * Log NSS TUNIPIP6 map rule. + */ +static void nss_tunipip6_log_map_rule(struct nss_tunipip6_msg *ntm) +{ + struct nss_tunipip6_map_rule *nmr __maybe_unused = &ntm->msg.map_rule; + nss_trace("%px: NSS TUNIPIP6 Interface Create message \n" + "TUNIPIP6 Map Rule IPv6 prefix: %pI6\n" + "TUNIPIP6 Map Rule IPv6 prefix length: %d\n" + "TUNIPIP6 Map Rule IPv4 prefix: %pI4\n" + "TUNIPIP6 Map Rule IPv4 prefix length: %d\n" + "TUNIPIP6 Map Rule IPv6 suffix: %pI6\n" + "TUNIPIP6 Map Rule IPv6 suffix length: %d\n" + "TUNIPIP6 Map Rule EA length: %d\n" + "TUNIPIP6 Map Rule PSID offset: %d\n", + nmr, nmr->ip6_prefix, + nmr->ip6_prefix_len,&nmr->ip4_prefix, + nmr->ip4_prefix_len, nmr->ip6_suffix, + nmr->ip6_suffix_len, nmr->ea_len, + nmr->psid_offset); +} + +/* + * nss_tunipip6_log_if_create_msg() + * Log NSS TUNIPIP6 Interface Create + */ +static void nss_tunipip6_log_if_create_msg(struct nss_tunipip6_msg *ntm) +{ + struct nss_tunipip6_create_msg *ntcm __maybe_unused = &ntm->msg.tunipip6_create; + nss_trace("%px: NSS TUNIPIP6 Interface Create message \n" + "TUNIPIP6 Source Address: %pI6\n" + "TUNIPIP6 Destination Address: %pI6\n" + "TUNIPIP6 Flow Label: %d\n" + "TUNIPIP6 Flags: %d\n" + "TUNIPIP6 Hop Limit: %d\n" + "TUNIPIP6 Draft03 Specification: %d\n" + "TUNIPIP6 TTL inherit: %u\n" + "TUNIPIP6 TOS inherit: %u\n" + "TUNIPIP6 Frag ID Update: %u\n" + "TUNIPIP6 Max FMR: %u\n", + ntcm, ntcm->saddr, + ntcm->daddr, ntcm->flowlabel, + ntcm->flags, ntcm->hop_limit, + ntcm->draft03, + ntcm->ttl_inherit, + ntcm->tos_inherit, + ntcm->frag_id_update, + ntcm->fmr_max); +} + +/* + * nss_tunipip6_log_verbose() + * Log message contents. + */ +static void nss_tunipip6_log_verbose(struct nss_tunipip6_msg *ntm) +{ + switch (ntm->cm.type) { + case NSS_TUNIPIP6_TX_ENCAP_IF_CREATE: + case NSS_TUNIPIP6_TX_DECAP_IF_CREATE: + nss_tunipip6_log_if_create_msg(ntm); + break; + + case NSS_TUNIPIP6_STATS_SYNC: + /* + * No log for valid stats message. + */ + break; + + case NSS_TUNIPIP6_BMR_RULE_ADD: + case NSS_TUNIPIP6_BMR_RULE_DEL: + case NSS_TUNIPIP6_FMR_RULE_ADD: + case NSS_TUNIPIP6_FMR_RULE_DEL: + nss_tunipip6_log_map_rule(ntm); + break; + case NSS_TUNIPIP6_FMR_RULE_FLUSH: + nss_trace("%px: FMR rule flush.\n", ntm); + break; + default: + nss_trace("%px: Invalid message type\n", ntm); + break; + } +} + +/* + * nss_tunipip6_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_tunipip6_log_tx_msg(struct nss_tunipip6_msg *ntm) +{ + if (ntm->cm.type >= NSS_TUNIPIP6_MAX) { + nss_warning("%px: Invalid message type\n", ntm); + return; + } + + nss_info("%px: type[%d]:%s\n", ntm, ntm->cm.type, nss_tunipip6_log_message_types_str[ntm->cm.type]); + nss_tunipip6_log_verbose(ntm); +} + +/* + * nss_tunipip6_log_rx_msg() + * Log messages received from FW. + */ +void nss_tunipip6_log_rx_msg(struct nss_tunipip6_msg *ntm) +{ + if (ntm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", ntm); + return; + } + + if (ntm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ntm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", ntm, ntm->cm.type, + nss_tunipip6_log_message_types_str[ntm->cm.type], + ntm->cm.response, nss_cmn_response_str[ntm->cm.response]); + goto verbose; + } + + if (ntm->cm.error >= NSS_TUNIPIP6_ERROR_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + ntm, ntm->cm.type, nss_tunipip6_log_message_types_str[ntm->cm.type], + ntm->cm.response, nss_cmn_response_str[ntm->cm.response], + ntm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + ntm, ntm->cm.type, nss_tunipip6_log_message_types_str[ntm->cm.type], + ntm->cm.response, nss_cmn_response_str[ntm->cm.response], + ntm->cm.error, nss_tunipip6_log_error_types_str[ntm->cm.error]); + +verbose: + nss_tunipip6_log_verbose(ntm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_tunipip6_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_tunipip6_log.h new file mode 100644 index 000000000..2ebccee1f --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_tunipip6_log.h @@ -0,0 +1,41 @@ +/* + ************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_TUNIPIP6_LOG_H +#define __NSS_TUNIPIP6_LOG_H + +/* + * nss_tunipip6.h + * NSS TUNIPIP6 header file. + */ + +/* + * Logger APIs + */ + +/* + * nss_tunipip6_log_tx_msg + * Logs a tunipip6 message that is sent to the NSS firmware. + */ +void nss_tunipip6_log_tx_msg(struct nss_tunipip6_msg *ntm); + +/* + * nss_tunipip6_log_rx_msg + * Logs a tunipip6 message that is received from the NSS firmware. + */ +void nss_tunipip6_log_rx_msg(struct nss_tunipip6_msg *ntm); + +#endif /* __NSS_TUNIPIP6_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_tunipip6_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_tunipip6_stats.c new file mode 100644 index 000000000..76834d3ef --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_tunipip6_stats.c @@ -0,0 +1,124 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_tunipip6.h" +#include "nss_stats.h" +#include "nss_tunipip6_stats.h" + +#define NSS_TUNIPIP6_STATS_MAX_LINES (NSS_STATS_NODE_MAX + 32) + /**< Maximum number of lines for tunipip6 statistics dump. */ +#define NSS_TUNIPIP6_STATS_SIZE_PER_IF (NSS_STATS_MAX_STR_LENGTH * NSS_TUNIPIP6_STATS_MAX_LINES) + /**< Total number of statistics per tunipip6 interface. */ + +/* + * nss_tunipip6_stats_read() + * Read tunipip6 common node statistics + */ +static ssize_t nss_tunipip6_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + struct nss_ctx_instance *nss_ctx = nss_tunipip6_get_context(); + enum nss_dynamic_interface_type type; + ssize_t bytes_read = 0; + size_t len = 0, size; + uint32_t if_num; + char *buf; + + /* + * Allocate memory for NSS_TUNIPIP6_TUNNEL_MAX tunnels and one + * static interface. + */ + size = NSS_TUNIPIP6_STATS_SIZE_PER_IF * (NSS_TUNIPIP6_TUNNEL_MAX << 1) + 1; + buf = vzalloc(size); + if (!buf) { + nss_warning("tunipip6: Could not allocate memory for local statistics buffer\n"); + return 0; + } + + len += nss_stats_banner(buf, len, size, "tunipip6", NSS_STATS_SINGLE_CORE); + + len += scnprintf(buf + len, size - len, "\nBase node if_num:%03u", NSS_TUNIPIP6_INTERFACE); + len += scnprintf(buf + len, size - len, "\n-------------------\n"); + len += nss_stats_fill_common_stats(NSS_TUNIPIP6_INTERFACE, NSS_STATS_SINGLE_INSTANCE, buf, len, size - len, "tunipip6"); + + /* + * Common node stats for each tunipip6 dynamic interface. + */ + for (if_num = NSS_DYNAMIC_IF_START; if_num < NSS_DYNAMIC_IF_START + NSS_MAX_DYNAMIC_INTERFACES; if_num++) { + type = nss_dynamic_interface_get_type(nss_ctx, if_num); + switch (type) { + case NSS_DYNAMIC_INTERFACE_TYPE_TUNIPIP6_INNER: + len += scnprintf(buf + len, size - len, "\nInner if_num:%03u", if_num); + break; + + case NSS_DYNAMIC_INTERFACE_TYPE_TUNIPIP6_OUTER: + len += scnprintf(buf + len, size - len, "\nOuter if_num:%03u", if_num); + break; + + default: + continue; + } + + len += scnprintf(buf + len, size - len, "\n-------------------\n"); + len += nss_stats_fill_common_stats(if_num, NSS_STATS_SINGLE_INSTANCE, buf, len, size - len, "tunipip6"); + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, buf, len); + vfree(buf); + return bytes_read; +} + +/* + * nss_tunipip6_stats_sync() + * Update tunipip6 common node statistics. + */ +void nss_tunipip6_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_tunipip6_msg *ntm) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + struct nss_tunipip6_stats_sync_msg *msg_stats = &ntm->msg.stats; + uint64_t i, *dest; + uint32_t *src; + + spin_lock_bh(&nss_top->stats_lock); + + /* + * Update common node stats + */ + dest = nss_top->stats_node[ntm->cm.interface]; + src = &msg_stats->node_stats.rx_packets; + for (i = NSS_STATS_NODE_RX_PKTS; i <= NSS_STATS_NODE_RX_QUEUE_3_DROPPED; i++) { + *dest++ = *src++; + } + + spin_unlock_bh(&nss_top->stats_lock); + +} + +/* + * nss_tunipip6_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(tunipip6) + +/* + * nss_tunipip6_stats_dentry_create() + * Create tunipip6 statistics debug entry. + */ +void nss_tunipip6_stats_dentry_create(void) +{ + nss_stats_create_dentry("tunipip6", &nss_tunipip6_stats_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_tunipip6_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_tunipip6_stats.h new file mode 100644 index 000000000..0f1748fc3 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_tunipip6_stats.h @@ -0,0 +1,34 @@ +/* + ****************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_TUNIPIP6_STATS_H +#define __NSS_TUNIPIP6_STATS_H + +/* + * nss_tunipip6_stats_dentry_create() + * Creates tunipip6 interface statistics debug entry. + */ +void nss_tunipip6_stats_dentry_create(void); + +/* + * nss_tunipip6_stats_sync() + * Update tunipip6 common node statistics. + */ +void nss_tunipip6_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_tunipip6_msg *ntm); + +#endif /* __NSS_TUNIPIP6_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_tx_msg_sync.c b/feeds/ipq807x/qca-nss-drv/src/nss_tx_msg_sync.c new file mode 100644 index 000000000..9eb0c70a9 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_tx_msg_sync.c @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * nss_tx_msg_sync.c + * NSS Tx msg sync core APIs + */ + +#include "nss_tx_rx_common.h" + +/* + * nss_tx_msg_sync_callback() + * Internal callback used to handle the message response. + */ +static void nss_tx_msg_sync_callback(void *app_data, struct nss_cmn_msg *ncm) +{ + uint32_t resp_offset; + + /* + * Per-message sync data was used as app_data. + * Retrieve the address of the original message from it. + */ + struct nss_tx_msg_sync_cmn_data *sync_data = (struct nss_tx_msg_sync_cmn_data *)app_data; + struct nss_cmn_msg *original_msg = (struct nss_cmn_msg *)sync_data->original_msg; + + /* + * Set TX status. And Copy back ncm->error and ncm->response if it is NACK. + */ + sync_data->status = NSS_TX_SUCCESS; + if (ncm->response != NSS_CMN_RESPONSE_ACK) { + nss_warning("Tx msg sync error response %d\n", ncm->response); + sync_data->status = NSS_TX_FAILURE_SYNC_FW_ERR; + original_msg->error = ncm->error; + original_msg->response = ncm->response; + } + + /* + * ncm is the return message containing message response. + * It is different from the original message caller built. + * Because the return message is only visible in this callback context, + * we copy back message response by specifying offset and length to + * the return message. So the caller can use response in their context + * once wake up instead of calling a passed-in user callback here. + */ + resp_offset = sync_data->resp_offset + sizeof(struct nss_cmn_msg); + + if (sync_data->copy_len > 0) + memcpy((uint8_t *)((nss_ptr_t)original_msg + resp_offset), + (uint8_t *)((nss_ptr_t)ncm + resp_offset), + sync_data->copy_len); + + /* + * Wake up the caller + */ + complete(&sync_data->complete); +} + +/* + * nss_tx_msg_sync_internal() + * Internal call for sending messages to FW synchronously. + */ +static nss_tx_status_t nss_tx_msg_sync_internal(struct nss_ctx_instance *nss_ctx, + nss_tx_msg_sync_subsys_async_t tx_msg_async, + nss_tx_msg_sync_subsys_async_with_size_t tx_msg_async_with_size, + uint32_t msg_buf_size, + struct nss_tx_msg_sync_cmn_data *sync_data, + struct nss_cmn_msg *ncm, + uint32_t timeout) +{ + nss_tx_status_t status; + int ret; + + /* + * Per-msg sync data is used as app_data. + * A generic callback is used to handle the return message. + */ + ncm->cb = (nss_ptr_t)nss_tx_msg_sync_callback; + ncm->app_data = (nss_ptr_t)sync_data; + + BUG_ON(!tx_msg_async && !tx_msg_async_with_size); + + /* + * Per-subsystem asynchronous call to send down the message. + */ + if (tx_msg_async) + status = tx_msg_async(nss_ctx, ncm); + else + status = tx_msg_async_with_size(nss_ctx, ncm, msg_buf_size); + + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: Tx msg async failed\n", nss_ctx); + return status; + } + + /* + * Sleep. Wake up either by notification or timeout. + */ + ret = wait_for_completion_timeout(&sync_data->complete, msecs_to_jiffies(timeout)); + if (!ret) { + nss_warning("%px: Tx msg sync timeout\n", nss_ctx); + return NSS_TX_FAILURE_SYNC_TIMEOUT; + } + + /* + * Wake up. Message response has been received within timeout. + */ + return sync_data->status; +} + +/* + * nss_tx_msg_sync() + * Send messages to FW synchronously with default message buffer size. + * + * tx_msg_async specifies the per-subsystem asynchronous call. + * timeout specifies the maximum sleep time for the completion. + * ncm is the original message the caller built. + * Since the caller cannot access the return message containing message response, + * we copy back message response from return message. + * resp_offset and copy_len specify the part of return message it'll copy. + */ +nss_tx_status_t nss_tx_msg_sync(struct nss_ctx_instance *nss_ctx, + nss_tx_msg_sync_subsys_async_t tx_msg_async, + uint32_t timeout, struct nss_cmn_msg *ncm, + uint32_t resp_offset, uint32_t copy_len) +{ + struct nss_tx_msg_sync_cmn_data sync_data; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + /* + * Check Tx msg async API + */ + if (!unlikely(tx_msg_async)) { + nss_warning("%px: missing Tx msg async API\n", nss_ctx); + return NSS_TX_FAILURE_SYNC_BAD_PARAM; + } + + /* + * Initialize the per-message sync data. + */ + init_completion(&sync_data.complete); + sync_data.status = NSS_TX_FAILURE; + sync_data.original_msg = (void *)ncm; + sync_data.resp_offset = resp_offset; + sync_data.copy_len = copy_len; + + return nss_tx_msg_sync_internal(nss_ctx, tx_msg_async, NULL, 0, &sync_data, ncm, timeout); +} +EXPORT_SYMBOL(nss_tx_msg_sync); + +/* + * nss_tx_msg_sync_with_size() + * Send messages to FW synchronously with specified message buffer size. + */ +nss_tx_status_t nss_tx_msg_sync_with_size(struct nss_ctx_instance *nss_ctx, + nss_tx_msg_sync_subsys_async_with_size_t tx_msg_async_with_size, + uint32_t msg_buf_size, uint32_t timeout, + struct nss_cmn_msg *ncm, uint32_t resp_offset, uint32_t copy_len) +{ + struct nss_tx_msg_sync_cmn_data sync_data; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + /* + * Check Tx msg async API + */ + if (!unlikely(tx_msg_async_with_size)) { + nss_warning("%px: missing Tx msg async API\n", nss_ctx); + return NSS_TX_FAILURE_SYNC_BAD_PARAM; + } + + /* + * Initialize the per-message sync data. + */ + init_completion(&sync_data.complete); + sync_data.status = NSS_TX_FAILURE; + sync_data.original_msg = (void *)ncm; + sync_data.resp_offset = resp_offset; + sync_data.copy_len = copy_len; + + return nss_tx_msg_sync_internal(nss_ctx, NULL, tx_msg_async_with_size, + msg_buf_size, &sync_data, ncm, timeout); +} +EXPORT_SYMBOL(nss_tx_msg_sync_with_size); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_tx_msg_sync.h b/feeds/ipq807x/qca-nss-drv/src/nss_tx_msg_sync.h new file mode 100644 index 000000000..248287e2e --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_tx_msg_sync.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * nss_tx_msg_sync.h + * NSS Tx msg sync header file + */ + +#ifndef __NSS_TX_MSG_SYNC_H +#define __NSS_TX_MSG_SYNC_H + +#include + +/* + * Amount time in msec the synchronous message should wait for response + * from NSS before the timeout happens. + */ +#define NSS_TX_MSG_SYNC_DEFAULT_TIMEOUT_MSEC (5000) + +/* + * Per-message sync data + * Used as message app_data. + */ +struct nss_tx_msg_sync_cmn_data { + struct completion complete; /* Completion structure */ + nss_tx_status_t status; /* Tx status */ + void *original_msg; /* Address of the caller-build message */ + uint32_t resp_offset; /* Response offset in message payload */ + uint32_t copy_len; /* Length in bytes copied from the return message */ +}; + +/* + * nss_tx_msg_sync_subsys_async_t() + * Tx msg asynchronous API of each subsystem. + */ +typedef nss_tx_status_t (*nss_tx_msg_sync_subsys_async_t)(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm); + +/* + * nss_tx_msg_sync_subsys_async_with_size_t() + * Tx msg asynchronous API of each subsystem with message buffer size specified. + */ +typedef nss_tx_status_t (*nss_tx_msg_sync_subsys_async_with_size_t)(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, uint32_t size); + +/* + * nss_tx_msg_sync() + * Core function to send message to FW synchronously. + * + * tx_msg_async specifies the per-subsystem asynchronous call. + * timeout specifies the maximum sleep time for the completion. + * ncm is the original message the caller built. + * Since the caller cannot access the return message containing message response, + * we copy back message response from the return message. + * resp_offset and copy_len specify the part of return message it'll copy. + */ +nss_tx_status_t nss_tx_msg_sync(struct nss_ctx_instance *nss_ctx, + nss_tx_msg_sync_subsys_async_t tx_msg_async, + uint32_t timeout, struct nss_cmn_msg *ncm, + uint32_t resp_offset, uint32_t copy_len); + +/* + * nss_tx_msg_sync_with_size() + * Send messages to FW synchronously with specified message buffer size. + */ +nss_tx_status_t nss_tx_msg_sync_with_size(struct nss_ctx_instance *nss_ctx, + nss_tx_msg_sync_subsys_async_with_size_t tx_msg_async_with_size, + uint32_t msg_buf_size, uint32_t timeout, + struct nss_cmn_msg *ncm, uint32_t resp_offset, uint32_t copy_len); + +#endif /* __NSS_TX_MSG_SYNC_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_tx_rx_common.h b/feeds/ipq807x/qca-nss-drv/src/nss_tx_rx_common.h new file mode 100644 index 000000000..7ace9ec5b --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_tx_rx_common.h @@ -0,0 +1,113 @@ +/* + ************************************************************************** + * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_tx_rx_common.h + * NSS APIs common header file + */ + +#ifndef __NSS_TX_RX_COMMON_H +#define __NSS_TX_RX_COMMON_H + +#include +#include +#include +#include +#include "nss_tx_msg_sync.h" + +/* + * Global definitions + */ +#define NSS_HLOS_MESSAGE_VERSION 1 /* Update when the common message structure changed */ + +#if (NSS_DEBUG_LEVEL > 0) +#define NSS_VERIFY_CTX_MAGIC(x) nss_verify_ctx_magic(x) +#define NSS_VERIFY_INIT_DONE(x) nss_verify_init_done(x) + +/* + * nss_verify_ctx_magic() + */ +static inline void nss_verify_ctx_magic(struct nss_ctx_instance *nss_ctx) +{ + nss_assert(nss_ctx->magic == NSS_CTX_MAGIC); +} + +static inline void nss_verify_init_done(struct nss_ctx_instance *nss_ctx) +{ + nss_assert(nss_ctx->state == NSS_CORE_STATE_INITIALIZED); +} + +#else +#define NSS_VERIFY_CTX_MAGIC(x) +#define NSS_VERIFY_INIT_DONE(x) +#endif + +/* + * CB handlers for variour interfaces + */ +void nss_phys_if_register_handler(struct nss_ctx_instance *nss_ctx, uint32_t if_num); +extern void nss_c2c_tx_register_handler(struct nss_ctx_instance *nss_ctx); +extern void nss_c2c_rx_register_handler(struct nss_ctx_instance *nss_ctx); +extern void nss_crypto_register_handler(void); +extern void nss_crypto_cmn_register_handler(void); +extern void nss_ipsec_register_handler(void); +extern void nss_ipsec_cmn_register_handler(void); +extern void nss_ipv4_register_handler(void); +extern void nss_ipv4_reasm_register_handler(void); +extern void nss_ipv6_register_handler(void); +extern void nss_ipv6_reasm_register_handler(void); +extern void nss_n2h_register_handler(struct nss_ctx_instance *nss_ctx); +extern void nss_tunipip6_register_handler(void); +extern void nss_pppoe_register_handler(void); +extern void nss_freq_register_handler(void); +extern void nss_eth_rx_register_handler(struct nss_ctx_instance *nss_ctx); +extern void nss_edma_register_handler(void); +extern void nss_lag_register_handler(void); +extern void nss_dynamic_interface_register_handler(struct nss_ctx_instance *nss_ctx); +extern void nss_gre_redir_register_handler(void); +extern void nss_gre_redir_lag_us_register_handler(void); +extern void nss_gre_redir_lag_ds_register_handler(void); +extern void nss_lso_rx_register_handler(struct nss_ctx_instance *nss_ctx); +extern void nss_sjack_register_handler(void); +extern void nss_wifi_register_handler(void); +extern struct net_device *nss_tstamp_register_netdev(void); +extern void nss_tstamp_register_handler(struct net_device *ndev); +extern void nss_portid_register_handler(void); +extern void nss_oam_register_handler(void); +extern void nss_dtls_register_handler(void); +extern void nss_dtls_cmn_register_handler(void); +extern void nss_tls_register_handler(void); +extern void nss_gre_tunnel_register_handler(void); +extern void nss_trustsec_tx_register_handler(void); +extern void nss_wifili_register_handler(void); +extern void nss_ppe_register_handler(void); +extern void nss_gre_redir_mark_register_handler(void); +extern void nss_ppe_vp_register_handler(void); +extern void nss_wifi_mac_db_register_handler(void); +extern void nss_wifi_ext_vdev_register_handler(void); +extern void nss_wifili_thread_scheme_db_init(uint8_t core_id); + +/* + * nss_if_msg_handler() + * External reference for internal base class handler for interface messages. + * + * This is not registered with nss_core.c as it is really a base class feature + * of the phys_if and virt_if handlers. + */ +extern void nss_if_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, + __attribute__((unused))void *app_data); + +#endif /* __NSS_TX_RX_COMMON_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_unaligned.c b/feeds/ipq807x/qca-nss-drv/src/nss_unaligned.c new file mode 100644 index 000000000..099abdb0a --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_unaligned.c @@ -0,0 +1,91 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_unaligned.c + * NSS unaligned APIs + */ + +#include "nss_tx_rx_common.h" +#include "nss_unaligned_stats.h" +#include "nss_unaligned_log.h" + +/* + * nss_unaligned_update_stats() + * Updates the statistics in the nss_ctx. + */ +static void nss_unaligned_update_stats(struct nss_ctx_instance *nss_ctx, + struct nss_unaligned_stats_msg *usm) +{ + uint32_t start_index = NSS_UNALIGNED_OPS_PER_MSG * usm->current_iteration; + uint32_t i; + spin_lock_bh(&nss_top_main.stats_lock); + nss_ctx->unaligned_stats.trap_count = usm->trap_count; + for (i = 0; i < NSS_UNALIGNED_OPS_PER_MSG; i++) { + uint32_t index = i + start_index; + if (unlikely(index >= NSS_UNALIGNED_EMULATED_OPS)) { + break; + } + nss_ctx->unaligned_stats.ops[index] = usm->ops[i]; + } + spin_unlock_bh(&nss_top_main.stats_lock); +} + +/* + * nss_unaligned_msg_handler() + * Handles metadata messages on the unaligned interface. + */ +static void nss_unaligned_msg_handler(struct nss_ctx_instance *nss_ctx, + struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_unaligned_msg *um = (struct nss_unaligned_msg *)ncm; + + /* + * Sanity checks on message + */ + if (um->cm.type >= NSS_UNALIGNED_MSG_MAX) { + nss_warning("%px: message type out of range: %d\n", nss_ctx, um->cm.type); + return; + } + + if (nss_cmn_get_msg_len(&(um->cm)) > sizeof(struct nss_unaligned_msg)) { + nss_warning("%px: message length is invalid: %d\n", nss_ctx, nss_cmn_get_msg_len(&(um->cm))); + return; + } + + nss_unaligned_log_rx_msg(um); + + switch (um->cm.type) { + case NSS_UNALIGNED_MSG_STATS: + nss_unaligned_update_stats(nss_ctx, &um->msg.stats_msg); + return; + } + + nss_core_log_msg_failures(nss_ctx, ncm); +} + +/* + * nss_unaligned_register_handler() + * Registers message handler on the NSS unaligned interface and stats dentry. + */ +void nss_unaligned_register_handler(struct nss_ctx_instance *nss_ctx) +{ + nss_core_register_handler(nss_ctx, NSS_UNALIGNED_INTERFACE, nss_unaligned_msg_handler, NULL); + + if (nss_ctx->id == NSS_CORE_0) { + nss_unaligned_stats_dentry_create(); + } +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_unaligned_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_unaligned_log.c new file mode 100644 index 000000000..079e2d76c --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_unaligned_log.c @@ -0,0 +1,75 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_unaligned_log.c + * NSS unaligned logger file. + */ + +#include "nss_core.h" + +/* + * nss_unaligned_log_message_types_str + * NSS unaligned message strings + */ +static int8_t *nss_unaligned_log_message_types_str[NSS_UNALIGNED_MSG_MAX] __maybe_unused = { + "Unaligned Stats Message", +}; + +/* + * nss_unaligned_log_verbose() + * Log message contents. + */ +static void nss_unaligned_log_verbose(struct nss_unaligned_msg *um) +{ + switch (um->cm.type) { + case NSS_UNALIGNED_MSG_STATS: + /* + * No log for valid stats message. + */ + break; + + default: + nss_trace("%px: Invalid message type\n", um); + break; + } +} + +/* + * nss_unaligned_log_rx_msg() + * Log messages received from FW. + */ +void nss_unaligned_log_rx_msg(struct nss_unaligned_msg *um) +{ + if (um->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", um); + return; + } + + if (um->cm.response == NSS_CMN_RESPONSE_NOTIFY || (um->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", um, um->cm.type, + nss_unaligned_log_message_types_str[um->cm.type], + um->cm.response, nss_cmn_response_str[um->cm.response]); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s\n", + um, um->cm.type, nss_unaligned_log_message_types_str[um->cm.type], + um->cm.response, nss_cmn_response_str[um->cm.response]); + +verbose: + nss_unaligned_log_verbose(um); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_unaligned_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_unaligned_log.h new file mode 100644 index 000000000..98ec707de --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_unaligned_log.h @@ -0,0 +1,31 @@ +/* + ****************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_UNALIGNED_LOG_H__ +#define __NSS_UNALIGNED_LOG_H__ + +/* + * nss_unaligned_log.h + * NSS Unaligned Log Header File. + */ + +/* + * nss_unaligned_log_rx_msg + * Logs an unaligned trap handler message that is received from the NSS firmware. + */ +void nss_unaligned_log_rx_msg(struct nss_unaligned_msg *um); + +#endif /* __NSS_UNALIGNED_LOG_H__ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_unaligned_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_unaligned_stats.c new file mode 100644 index 000000000..af0fd74be --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_unaligned_stats.c @@ -0,0 +1,88 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_unaligned_stats.h" + +/* + * nss_unaligned_stats_read() + * Read unaligned stats + */ +static ssize_t nss_unaligned_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + uint32_t max_output_lines = NSS_MAX_CORES * NSS_UNALIGNED_OPS_PER_MSG; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + struct nss_unaligned_stats *stats_shadow; + uint32_t i, j; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(!lbuf)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + stats_shadow = kzalloc(NSS_MAX_CORES * sizeof(struct nss_unaligned_stats), GFP_KERNEL); + if (unlikely(!stats_shadow)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return 0; + } + + spin_lock_bh(&nss_top_main.stats_lock); + for (i = 0; i < NSS_MAX_CORES; i++) { + stats_shadow[i] = nss_top_main.nss[i].unaligned_stats; + } + spin_unlock_bh(&nss_top_main.stats_lock); + + for (i = 0; i < NSS_MAX_CORES; i++) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "core: %u, total unaligned traps: %llu\n", + i, stats_shadow[i].trap_count); + for (j = 0; j < NSS_UNALIGNED_OPS_PER_MSG; j++) { + struct nss_unaligned_stats_op op = stats_shadow[i].ops[j]; + if (op.count == 0) { + break; + } + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "op: %2x, ext: %2x, count:%10llu, min: %10u, avg: %10u, max: %10u\n", + op.opcode_primary, op.opcode_extension, op.count, op.ticks_min, + op.ticks_avg, op.ticks_max); + } + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + + return bytes_read; +} + +/* + * nss_unaligned_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(unaligned) + +/* + * nss_unaligned_stats_dentry_create() + * Create unaligned statistics debug entry. + */ +void nss_unaligned_stats_dentry_create(void) +{ + nss_stats_create_dentry("unaligned", &nss_unaligned_stats_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_unaligned_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_unaligned_stats.h new file mode 100644 index 000000000..761cda634 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_unaligned_stats.h @@ -0,0 +1,22 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_UNALIGNED_STATS_H +#define __NSS_UNALIGNED_STATS_H + +extern void nss_unaligned_stats_dentry_create(void); + +#endif diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_virt_if.c b/feeds/ipq807x/qca-nss-drv/src/nss_virt_if.c new file mode 100644 index 000000000..b530517cf --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_virt_if.c @@ -0,0 +1,736 @@ +/* + ************************************************************************** + * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_virt_if.c + * NSS virtual/redirect handler APIs + */ + +#include "nss_tx_rx_common.h" +#include "nss_virt_if_stats.h" +#include + +#define NSS_VIRT_IF_TX_TIMEOUT 3000 /* 3 Seconds */ +#define NSS_VIRT_IF_GET_INDEX(if_num) (if_num-NSS_DYNAMIC_IF_START) + +extern int nss_ctl_redirect; + +/* + * Data structure that holds the virtual interface context. + */ +struct nss_virt_if_handle *nss_virt_if_handle_t[NSS_MAX_DYNAMIC_INTERFACES]; + +/* + * Spinlock to protect the global data structure virt_handle. + */ +DEFINE_SPINLOCK(nss_virt_if_lock); + +/* + * nss_virt_if_get_context() + */ +struct nss_ctx_instance *nss_virt_if_get_context(void) +{ + return &nss_top_main.nss[nss_top_main.virt_if_handler_id]; +} + +/* + * nss_virt_if_verify_if_num() + * Verify if_num passed to us. + */ +bool nss_virt_if_verify_if_num(uint32_t if_num) +{ + enum nss_dynamic_interface_type type = nss_dynamic_interface_get_type(nss_virt_if_get_context(), if_num); + + return type == NSS_DYNAMIC_INTERFACE_TYPE_GENERIC_REDIR_N2H + || type == NSS_DYNAMIC_INTERFACE_TYPE_GENERIC_REDIR_H2N; +} +EXPORT_SYMBOL(nss_virt_if_verify_if_num); + +/* + * nss_virt_if_msg_handler() + * Handle msg responses from the FW on virtual interfaces + */ +static void nss_virt_if_msg_handler(struct nss_ctx_instance *nss_ctx, + struct nss_cmn_msg *ncm, + void *app_data) +{ + struct nss_virt_if_msg *nvim = (struct nss_virt_if_msg *)ncm; + int32_t if_num; + + nss_virt_if_msg_callback_t cb; + struct nss_virt_if_handle *handle = NULL; + + /* + * Sanity check the message type + */ + if (ncm->type > NSS_VIRT_IF_MAX_MSG_TYPES) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return; + } + + /* + * Messages value that are within the base class are handled by the base class. + */ + if (ncm->type < NSS_IF_MAX_MSG_TYPES) { + return nss_if_msg_handler(nss_ctx, ncm, app_data); + } + + if (!nss_virt_if_verify_if_num(ncm->interface)) { + nss_warning("%px: response for another interface: %d", nss_ctx, ncm->interface); + return; + } + + if_num = NSS_VIRT_IF_GET_INDEX(ncm->interface); + + spin_lock_bh(&nss_virt_if_lock); + if (!nss_virt_if_handle_t[if_num]) { + spin_unlock_bh(&nss_virt_if_lock); + nss_warning("%px: virt_if handle is NULL\n", nss_ctx); + return; + } + + handle = nss_virt_if_handle_t[if_num]; + spin_unlock_bh(&nss_virt_if_lock); + + switch (nvim->cm.type) { + case NSS_VIRT_IF_STATS_SYNC_MSG: + nss_virt_if_stats_sync(handle, &nvim->msg.stats); + break; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Update the callback and app_data for NOTIFY messages, IPv4 sends all notify messages + * to the same callback/app_data. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_core_get_msg_handler(nss_ctx, ncm->interface); + ncm->app_data = (nss_ptr_t)nss_ctx->subsys_dp_register[ncm->interface].ndev; + } + + /* + * Do we have a callback? + */ + if (!ncm->cb) { + return; + } + + /* + * Callback + */ + cb = (nss_virt_if_msg_callback_t)ncm->cb; + cb((void *)ncm->app_data, ncm); +} + +/* + * nss_virt_if_callback + * Callback to handle the completion of NSS ->HLOS messages. + */ +static void nss_virt_if_callback(void *app_data, struct nss_cmn_msg *ncm) +{ + struct nss_virt_if_handle *handle = (struct nss_virt_if_handle *)app_data; + struct nss_virt_if_pvt *nvip = handle->pvt; + + if (ncm->response != NSS_CMN_RESPONSE_ACK) { + nss_warning("%px: virt_if Error response %d\n", handle->nss_ctx, ncm->response); + nvip->response = NSS_TX_FAILURE; + complete(&nvip->complete); + return; + } + + nvip->response = NSS_TX_SUCCESS; + complete(&nvip->complete); +} + +/* + * nss_virt_if_tx_msg_sync + * Send a message from HLOS to NSS synchronously. + */ +static nss_tx_status_t nss_virt_if_tx_msg_sync(struct nss_virt_if_handle *handle, + struct nss_virt_if_msg *nvim) +{ + nss_tx_status_t status; + int ret = 0; + struct nss_virt_if_pvt *nwip = handle->pvt; + struct nss_ctx_instance *nss_ctx = handle->nss_ctx; + + down(&nwip->sem); + + status = nss_virt_if_tx_msg(nss_ctx, nvim); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: nss_virt_if_msg failed\n", nss_ctx); + up(&nwip->sem); + return status; + } + + ret = wait_for_completion_timeout(&nwip->complete, + msecs_to_jiffies(NSS_VIRT_IF_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: virt_if tx failed due to timeout\n", nss_ctx); + nwip->response = NSS_TX_FAILURE; + } + + status = nwip->response; + up(&nwip->sem); + + return status; +} + +/* + * nss_virt_if_msg_init() + * Initialize virt specific message structure. + */ +static void nss_virt_if_msg_init(struct nss_virt_if_msg *nvim, + uint16_t if_num, + uint32_t type, + uint32_t len, + nss_virt_if_msg_callback_t cb, + struct nss_virt_if_handle *app_data) +{ + nss_cmn_msg_init(&nvim->cm, if_num, type, len, (void *)cb, (void *)app_data); +} + +/* + * nss_virt_if_handle_destroy_sync() + * Destroy the virt handle either due to request from user or due to error, synchronously. + */ +static int nss_virt_if_handle_destroy_sync(struct nss_virt_if_handle *handle) +{ + nss_tx_status_t status; + int32_t if_num_n2h = handle->if_num_n2h; + int32_t if_num_h2n = handle->if_num_h2n; + int32_t index_n2h; + int32_t index_h2n; + + if (!nss_virt_if_verify_if_num(if_num_n2h) || !nss_virt_if_verify_if_num(if_num_h2n)) { + nss_warning("%px: bad interface numbers %d %d\n", handle->nss_ctx, if_num_n2h, if_num_h2n); + return NSS_TX_FAILURE_BAD_PARAM; + } + + index_n2h = NSS_VIRT_IF_GET_INDEX(if_num_n2h); + index_h2n = NSS_VIRT_IF_GET_INDEX(if_num_h2n); + + status = nss_dynamic_interface_dealloc_node(if_num_n2h, NSS_DYNAMIC_INTERFACE_TYPE_GENERIC_REDIR_N2H); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: Dynamic interface destroy failed status %d\n", handle->nss_ctx, status); + return status; + } + + status = nss_dynamic_interface_dealloc_node(if_num_h2n, NSS_DYNAMIC_INTERFACE_TYPE_GENERIC_REDIR_H2N); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: Dynamic interface destroy failed status %d\n", handle->nss_ctx, status); + return status; + } + + spin_lock_bh(&nss_virt_if_lock); + nss_virt_if_handle_t[index_n2h] = NULL; + nss_virt_if_handle_t[index_h2n] = NULL; + spin_unlock_bh(&nss_virt_if_lock); + + kfree(handle->pvt); + kfree(handle); + + return status; +} + +/* + * nss_virt_if_handle_create_sync() + * Initialize virt handle which holds the if_num and stats per interface. + */ +static struct nss_virt_if_handle *nss_virt_if_handle_create_sync(struct nss_ctx_instance *nss_ctx, int32_t if_num_n2h, int32_t if_num_h2n, int32_t *cmd_rsp) +{ + int32_t index_n2h; + int32_t index_h2n; + struct nss_virt_if_handle *handle; + + if (!nss_virt_if_verify_if_num(if_num_n2h) || !nss_virt_if_verify_if_num(if_num_h2n)) { + nss_warning("%px: bad interface numbers %d %d\n", nss_ctx, if_num_n2h, if_num_h2n); + return NULL; + } + + index_n2h = NSS_VIRT_IF_GET_INDEX(if_num_n2h); + index_h2n = NSS_VIRT_IF_GET_INDEX(if_num_h2n); + + handle = (struct nss_virt_if_handle *)kzalloc(sizeof(struct nss_virt_if_handle), + GFP_KERNEL); + if (!handle) { + nss_warning("%px: handle memory alloc failed\n", nss_ctx); + *cmd_rsp = NSS_VIRT_IF_ALLOC_FAILURE; + goto error1; + } + + handle->nss_ctx = nss_ctx; + handle->if_num_n2h = if_num_n2h; + handle->if_num_h2n = if_num_h2n; + handle->pvt = (struct nss_virt_if_pvt *)kzalloc(sizeof(struct nss_virt_if_pvt), + GFP_KERNEL); + if (!handle->pvt) { + nss_warning("%px: failure allocating memory for nss_virt_if_pvt\n", nss_ctx); + *cmd_rsp = NSS_VIRT_IF_ALLOC_FAILURE; + goto error2; + } + + handle->cb = NULL; + handle->app_data = NULL; + + spin_lock_bh(&nss_virt_if_lock); + nss_virt_if_handle_t[index_n2h] = handle; + nss_virt_if_handle_t[index_h2n] = handle; + spin_unlock_bh(&nss_virt_if_lock); + + *cmd_rsp = NSS_VIRT_IF_SUCCESS; + + return handle; + +error2: + kfree(handle); +error1: + return NULL; +} + +/* + * nss_virt_if_register_handler_sync() + * register msg handler for virtual interface and initialize semaphore and completion. + */ +static uint32_t nss_virt_if_register_handler_sync(struct nss_ctx_instance *nss_ctx, struct nss_virt_if_handle *handle) +{ + uint32_t ret; + struct nss_virt_if_pvt *nvip = NULL; + int32_t if_num_n2h = handle->if_num_n2h; + int32_t if_num_h2n = handle->if_num_h2n; + + ret = nss_core_register_handler(nss_ctx, if_num_n2h, nss_virt_if_msg_handler, NULL); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Failed to register message handler for redir_n2h interface %d\n", nss_ctx, if_num_n2h); + return NSS_VIRT_IF_CORE_FAILURE; + } + + ret = nss_core_register_handler(nss_ctx, if_num_h2n, nss_virt_if_msg_handler, NULL); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_core_unregister_handler(nss_ctx, if_num_n2h); + nss_warning("%px: Failed to register message handler for redir_h2n interface %d\n", nss_ctx, if_num_h2n); + return NSS_VIRT_IF_CORE_FAILURE; + } + + nvip = handle->pvt; + if (!nvip->sem_init_done) { + sema_init(&nvip->sem, 1); + init_completion(&nvip->complete); + nvip->sem_init_done = 1; + } + + nss_virt_if_stats_dentry_create(); + return NSS_VIRT_IF_SUCCESS; +} + +/* + * nss_virt_if_create_sync_nexthop() + * Create redir_n2h and redir_h2n interfaces, synchronously and associate it with same netdev. + */ +struct nss_virt_if_handle *nss_virt_if_create_sync_nexthop(struct net_device *netdev, uint32_t nexthop_n2h, uint32_t nexthop_h2n) +{ + struct nss_ctx_instance *nss_ctx = nss_virt_if_get_context(); + struct nss_virt_if_msg nvim; + struct nss_virt_if_config_msg *nvcm; + uint32_t ret; + struct nss_virt_if_handle *handle = NULL; + int32_t if_num_n2h, if_num_h2n; + + if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) { + nss_warning("%px: Interface could not be created as core not ready\n", nss_ctx); + return NULL; + } + + if_num_n2h = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_GENERIC_REDIR_N2H); + if (if_num_n2h < 0) { + nss_warning("%px: failure allocating redir_n2h\n", nss_ctx); + return NULL; + } + + if_num_h2n = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_GENERIC_REDIR_H2N); + if (if_num_h2n < 0) { + nss_warning("%px: failure allocating redir_h2n\n", nss_ctx); + nss_dynamic_interface_dealloc_node(if_num_n2h, NSS_DYNAMIC_INTERFACE_TYPE_GENERIC_REDIR_N2H); + return NULL; + } + + handle = nss_virt_if_handle_create_sync(nss_ctx, if_num_n2h, if_num_h2n, &ret); + if (!handle) { + nss_warning("%px: virt_if handle creation failed ret %d\n", nss_ctx, ret); + nss_dynamic_interface_dealloc_node(if_num_n2h, NSS_DYNAMIC_INTERFACE_TYPE_GENERIC_REDIR_N2H); + nss_dynamic_interface_dealloc_node(if_num_h2n, NSS_DYNAMIC_INTERFACE_TYPE_GENERIC_REDIR_H2N); + return NULL; + } + + /* + * Initializes the semaphore and also sets the msg handler for if_num. + */ + ret = nss_virt_if_register_handler_sync(nss_ctx, handle); + if (ret != NSS_VIRT_IF_SUCCESS) { + nss_warning("%px: Registration handler failed reason: %d\n", nss_ctx, ret); + goto error1; + } + + nss_virt_if_msg_init(&nvim, handle->if_num_n2h, NSS_VIRT_IF_TX_CONFIG_MSG, + sizeof(struct nss_virt_if_config_msg), nss_virt_if_callback, handle); + + nvcm = &nvim.msg.if_config; + nvcm->flags = 0; + nvcm->sibling = if_num_h2n; + nvcm->nexthop = nexthop_n2h; + memcpy(nvcm->mac_addr, netdev->dev_addr, ETH_ALEN); + + ret = nss_virt_if_tx_msg_sync(handle, &nvim); + if (ret != NSS_TX_SUCCESS) { + nss_warning("%px: nss_virt_if_tx_msg_sync failed %u\n", nss_ctx, ret); + goto error2; + } + + nvim.cm.interface = if_num_h2n; + nvcm->sibling = if_num_n2h; + nvcm->nexthop = nexthop_h2n; + + ret = nss_virt_if_tx_msg_sync(handle, &nvim); + if (ret != NSS_TX_SUCCESS) { + nss_warning("%px: nss_virt_if_tx_msg_sync failed %u\n", nss_ctx, ret); + goto error2; + } + + nss_core_register_subsys_dp(nss_ctx, handle->if_num_n2h, NULL, NULL, NULL, netdev, 0); + nss_core_register_subsys_dp(nss_ctx, handle->if_num_h2n, NULL, NULL, NULL, netdev, 0); + + nss_core_set_subsys_dp_type(nss_ctx, netdev, if_num_n2h, NSS_VIRT_IF_DP_REDIR_N2H); + nss_core_set_subsys_dp_type(nss_ctx, netdev, if_num_h2n, NSS_VIRT_IF_DP_REDIR_H2N); + + /* + * Hold a reference to the net_device + */ + dev_hold(netdev); + + /* + * The context returned is the handle interface # which contains all the info related to + * the interface if_num. + */ + + return handle; + +error2: + nss_core_unregister_handler(nss_ctx, if_num_n2h); + nss_core_unregister_handler(nss_ctx, if_num_h2n); + +error1: + nss_virt_if_handle_destroy_sync(handle); + return NULL; +} +EXPORT_SYMBOL(nss_virt_if_create_sync_nexthop); + +/* + * nss_virt_if_create_sync() + * Create redir_n2h and redir_h2n interfaces, synchronously and associate it with same netdev. + * It uses the default nexthop interfaces. + * + * + */ +struct nss_virt_if_handle *nss_virt_if_create_sync(struct net_device *netdev) +{ + /* + * NSS_N2H_INTERFACE is the nexthop of the dynamic interface which is created for handling the + * n2h traffic. + * NSS_ETH_RX_INTERFACE is the nexthop of the dynamic interface which is created for handling the + * h2n traffic. + */ + return nss_virt_if_create_sync_nexthop(netdev, NSS_N2H_INTERFACE, NSS_ETH_RX_INTERFACE); +} +EXPORT_SYMBOL(nss_virt_if_create_sync); + +/* + * nss_virt_if_destroy_sync() + * Destroy the virt interface associated with the interface number, synchronously. + */ +nss_tx_status_t nss_virt_if_destroy_sync(struct nss_virt_if_handle *handle) +{ + nss_tx_status_t status; + struct net_device *dev; + int32_t if_num_n2h; + int32_t if_num_h2n; + struct nss_ctx_instance *nss_ctx; + uint32_t ret; + + if (!handle) { + nss_warning("handle is NULL\n"); + return NSS_TX_FAILURE_BAD_PARAM; + } + + if_num_n2h = handle->if_num_n2h; + if_num_h2n = handle->if_num_h2n; + nss_ctx = handle->nss_ctx; + + if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) { + nss_warning("%px: Interface could not be destroyed as core not ready\n", nss_ctx); + return NSS_TX_FAILURE_NOT_READY; + } + + spin_lock_bh(&nss_top_main.lock); + if (!nss_ctx->subsys_dp_register[if_num_n2h].ndev || !nss_ctx->subsys_dp_register[if_num_h2n].ndev) { + spin_unlock_bh(&nss_top_main.lock); + nss_warning("%px: Unregister virt interface %d %d: no context\n", nss_ctx, if_num_n2h, if_num_h2n); + return NSS_TX_FAILURE_BAD_PARAM; + } + + dev = nss_ctx->subsys_dp_register[if_num_n2h].ndev; + nss_assert(dev == nss_ctx->subsys_dp_register[if_num_h2n].ndev); + nss_core_unregister_subsys_dp(nss_ctx, if_num_n2h); + nss_core_unregister_subsys_dp(nss_ctx, if_num_h2n); + spin_unlock_bh(&nss_top_main.lock); + dev_put(dev); + + status = nss_virt_if_handle_destroy_sync(handle); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: handle destroy failed for if_num_n2h %d and if_num_h2n %d\n", nss_ctx, if_num_n2h, if_num_h2n); + return NSS_TX_FAILURE; + } + + ret = nss_core_unregister_handler(nss_ctx, if_num_n2h); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Not able to unregister handler for redir_n2h interface %d with NSS core\n", nss_ctx, if_num_n2h); + return NSS_TX_FAILURE_BAD_PARAM; + } + + ret = nss_core_unregister_handler(nss_ctx, if_num_h2n); + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Not able to unregister handler for redir_h2n interface %d with NSS core\n", nss_ctx, if_num_h2n); + return NSS_TX_FAILURE_BAD_PARAM; + } + + return status; +} +EXPORT_SYMBOL(nss_virt_if_destroy_sync); + +/* + * nss_virt_if_tx_buf() + * HLOS interface has received a packet which we redirect to the NSS, if appropriate to do so. + */ +nss_tx_status_t nss_virt_if_tx_buf(struct nss_virt_if_handle *handle, + struct sk_buff *skb) +{ + int32_t if_num = handle->if_num_h2n; + struct nss_ctx_instance *nss_ctx = handle->nss_ctx; + int cpu = 0; + + if (unlikely(nss_ctl_redirect == 0)) { + return NSS_TX_FAILURE_NOT_ENABLED; + } + + if (unlikely(skb->vlan_tci)) { + return NSS_TX_FAILURE_NOT_SUPPORTED; + } + + if (!nss_virt_if_verify_if_num(if_num)) { + nss_warning("%px: bad interface number %d\n", nss_ctx, if_num); + return NSS_TX_FAILURE_BAD_PARAM; + } + + nss_trace("%px: Virtual Rx packet, if_num:%d, skb:%px", nss_ctx, if_num, skb); + + /* + * Sanity check the SKB to ensure that it's suitable for us + */ + if (unlikely(skb->len <= ETH_HLEN)) { + nss_warning("%px: Virtual Rx packet: %px too short", nss_ctx, skb); + return NSS_TX_FAILURE_TOO_SHORT; + } + + /* + * set skb queue mapping + */ + cpu = get_cpu(); + put_cpu(); + skb_set_queue_mapping(skb, cpu); + + return nss_core_send_packet(nss_ctx, skb, if_num, H2N_BIT_FLAG_VIRTUAL_BUFFER | + H2N_BIT_FLAG_BUFFER_REUSABLE); +} +EXPORT_SYMBOL(nss_virt_if_tx_buf); + +/* + * nss_virt_if_tx_msg() + */ +nss_tx_status_t nss_virt_if_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_virt_if_msg *nvim) +{ + struct nss_cmn_msg *ncm = &nvim->cm; + + /* + * Sanity check the message + */ + if (!nss_virt_if_verify_if_num(ncm->interface)) { + nss_warning("%px: tx request for another interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type > NSS_VIRT_IF_MAX_MSG_TYPES) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, nvim, sizeof(*nvim), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_virt_if_tx_msg); + +/* + * nss_virt_if_xmit_callback_register() + * Register virtual interface xmit callback. + */ +void nss_virt_if_xmit_callback_register(struct nss_virt_if_handle *handle, + nss_virt_if_xmit_callback_t cb) +{ + struct nss_ctx_instance *nss_ctx; + struct nss_subsystem_dataplane_register *reg; + + if (!handle) { + nss_warning("handle is NULL\n"); + return; + } + + nss_ctx = handle->nss_ctx; + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (!nss_virt_if_verify_if_num(handle->if_num_n2h)) { + nss_warning("if_num is invalid\n"); + return; + } + + reg = &nss_ctx->subsys_dp_register[handle->if_num_n2h]; + reg->xmit_cb = cb; +} +EXPORT_SYMBOL(nss_virt_if_xmit_callback_register); + +/* + * nss_virt_if_xmit_callback_unregister() + * Unregister virtual interface xmit callback. + */ +void nss_virt_if_xmit_callback_unregister(struct nss_virt_if_handle *handle) +{ + struct nss_ctx_instance *nss_ctx; + struct nss_subsystem_dataplane_register *reg; + + if (!handle) { + nss_warning("handle is NULL\n"); + return; + } + + nss_ctx = handle->nss_ctx; + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (!nss_virt_if_verify_if_num(handle->if_num_n2h)) { + nss_warning("if_num is invalid\n"); + return; + } + + reg = &nss_ctx->subsys_dp_register[handle->if_num_n2h]; + reg->xmit_cb = NULL; +} +EXPORT_SYMBOL(nss_virt_if_xmit_callback_unregister); + +/* + * nss_virt_if_register() + */ +void nss_virt_if_register(struct nss_virt_if_handle *handle, + nss_virt_if_data_callback_t data_callback, + struct net_device *netdev) +{ + struct nss_ctx_instance *nss_ctx; + int32_t if_num; + uint32_t status; + + if (!handle) { + nss_warning("handle is NULL\n"); + return; + } + + nss_ctx = handle->nss_ctx; + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (!nss_virt_if_verify_if_num(handle->if_num_n2h)) { + nss_warning("if_num is invalid\n"); + return; + } + + if_num = handle->if_num_n2h; + + nss_core_register_subsys_dp(nss_ctx, if_num, data_callback, NULL, NULL, netdev, (uint32_t)netdev->features); + status = nss_core_unregister_msg_handler(nss_ctx, if_num); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: unable to unregister event handler for interface(%u)", nss_ctx, if_num); + return; + } +} +EXPORT_SYMBOL(nss_virt_if_register); + +/* + * nss_virt_if_unregister() + */ +void nss_virt_if_unregister(struct nss_virt_if_handle *handle) +{ + struct nss_ctx_instance *nss_ctx; + int32_t if_num; + uint32_t status; + + if (!handle) { + nss_warning("handle is NULL\n"); + return; + } + + nss_ctx = handle->nss_ctx; + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (!nss_virt_if_verify_if_num(handle->if_num_n2h)) { + nss_warning("if_num is invalid\n"); + return; + } + + if_num = handle->if_num_n2h; + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + + status = nss_core_unregister_msg_handler(nss_ctx, if_num); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: unable to unregister event handler for interface(%u)", nss_ctx, if_num); + return; + } +} +EXPORT_SYMBOL(nss_virt_if_unregister); + +/* + * nss_virt_if_get_interface_num() + * Get interface number for a virtual interface + */ +int32_t nss_virt_if_get_interface_num(struct nss_virt_if_handle *handle) +{ + if (!handle) { + nss_warning("virt_if handle is NULL\n"); + return -1; + } + + /* + * Return if_num_n2h whose datapath type is 0. + */ + return handle->if_num_n2h; +} +EXPORT_SYMBOL(nss_virt_if_get_interface_num); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_virt_if_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_virt_if_stats.c new file mode 100644 index 000000000..d43b72c3d --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_virt_if_stats.c @@ -0,0 +1,339 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2017, 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_virt_if_stats.h" + +/* + * Data structure that holds the virtual interface context. + */ +extern struct nss_virt_if_handle *nss_virt_if_handle_t[]; + +/* + * Spinlock to protect the global data structure virt_handle. + */ +extern spinlock_t nss_virt_if_lock; + +/* + * nss_virt_if_base_node_stats_str + * virt_if base node stats strings + */ +static int8_t *nss_virt_if_base_node_stats_str[NSS_VIRT_IF_BASE_NODE_STATS_MAX] = { + "active_interfaces", + "ocm_alloc_failed", + "ddr_alloc_failed", +}; + +/* + * nss_virt_if_interface_stats_str + * virt_if interface stats strings + */ +static int8_t *nss_virt_if_interface_stats_str[NSS_VIRT_IF_INTERFACE_STATS_MAX] = { + "rx_packets", + "rx_bytes", + "rx_dropped", + "tx_packets", + "tx_bytes", + "tx_enqueue_failed", + "shaper_enqueue_failed", + "ocm_alloc_failed", +}; + +/* + * nss_virt_if_base_node_stats_fill_row() + * Fill one row of virt_if base node stats. + */ +static int32_t nss_virt_if_base_node_stats_fill_row(char *line, int len, int start, struct nss_virt_if_base_node_stats *stats) +{ + uint64_t tcnt = 0; + switch (start) { + case NSS_VIRT_IF_BASE_NODE_STATS_ACTIVE_INTERFACES: + tcnt = stats->active_interfaces; + break; + + case NSS_VIRT_IF_BASE_NODE_STATS_OCM_ALLOC_FAILED: + tcnt = stats->ocm_alloc_failed; + break; + + case NSS_VIRT_IF_BASE_NODE_STATS_DDR_ALLOC_FAILED: + tcnt = stats->ddr_alloc_failed; + break; + + default: + return 0; + } + + return scnprintf(line, len, "%s = %llu\n", nss_virt_if_base_node_stats_str[start], tcnt); +} + +/* + * nss_virt_if_interface_stats_fill_row() + * Fill one row of virt_if interface stats. + */ +static int32_t nss_virt_if_interface_stats_fill_row(char *line, int len, int start, struct nss_virt_if_interface_stats *stats) +{ + uint64_t tcnt = 0; + switch (start) { + case NSS_VIRT_IF_INTERFACE_STATS_RX_PACKETS: + tcnt = stats->node_stats.rx_packets; + break; + + case NSS_VIRT_IF_INTERFACE_STATS_RX_BYTES: + tcnt = stats->node_stats.rx_bytes; + break; + + case NSS_VIRT_IF_INTERFACE_STATS_RX_DROPPED: + tcnt = nss_cmn_rx_dropped_sum(&stats->node_stats); + break; + + case NSS_VIRT_IF_INTERFACE_STATS_TX_PACKETS: + tcnt = stats->node_stats.tx_packets; + break; + + case NSS_VIRT_IF_INTERFACE_STATS_TX_BYTES: + tcnt = stats->node_stats.tx_bytes; + break; + + case NSS_VIRT_IF_INTERFACE_STATS_TX_ENQUEUE_FAILED: + tcnt = stats->tx_enqueue_failed; + break; + + case NSS_VIRT_IF_INTERFACE_STATS_SHAPER_ENQUEUE_FAILED: + tcnt = stats->shaper_enqueue_failed; + break; + + case NSS_VIRT_IF_INTERFACE_STATS_OCM_ALLOC_FAILED: + tcnt = stats->ocm_alloc_failed; + break; + + default: + return 0; + } + + return scnprintf(line, len, "%s = %llu\n", nss_virt_if_interface_stats_str[start], tcnt); +} + +/* + * nss_virt_if_stats_get() + * Get virt_if base node stats or interface stats by interface number. + */ +bool nss_virt_if_stats_get(struct nss_ctx_instance *nss_ctx, uint32_t if_num, void *stats, bool is_base) +{ + if (nss_virt_if_verify_if_num(if_num) == false) { + return false; + } + + /* + * Statistics for redir_h2n and redir_n2h are collected on redir_h2n in NSS. + */ + if (nss_dynamic_interface_get_type(nss_ctx, if_num) != NSS_DYNAMIC_INTERFACE_TYPE_GENERIC_REDIR_H2N) + return false; + + if_num = if_num - NSS_DYNAMIC_IF_START; + spin_lock_bh(&nss_virt_if_lock); + if (!nss_virt_if_handle_t[if_num]) { + spin_unlock_bh(&nss_virt_if_lock); + return false; + } + + /* + * Check if it is base node statistics or interface statistics. + */ + if (is_base) { + memcpy((struct nss_virt_if_base_node_stats *)stats, + &nss_virt_if_handle_t[if_num]->stats.base_stats, + sizeof(struct nss_virt_if_base_node_stats)); + } else { + memcpy((struct nss_virt_if_interface_stats *)stats, + &nss_virt_if_handle_t[if_num]->stats.if_stats, + sizeof(struct nss_virt_if_interface_stats)); + } + + spin_unlock_bh(&nss_virt_if_lock); + return true; +} + +/* + * nss_virt_if_stats_read() + * Read virt_if statistics + */ +static ssize_t nss_virt_if_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + struct nss_stats_data *data = fp->private_data; + struct nss_ctx_instance *nss_ctx = nss_virt_if_get_context(); + int32_t if_num = NSS_DYNAMIC_IF_START; + int32_t max_if_num = if_num + NSS_MAX_DYNAMIC_INTERFACES; + size_t bytes = 0; + ssize_t bytes_read = 0; + char line[80]; + int start, end; + int32_t if_num_valid = NSS_DYNAMIC_IF_START - 1; + struct nss_virt_if_base_node_stats base_node_stats_local; + struct nss_virt_if_interface_stats interface_stats_local; + + if (data) { + if_num = data->if_num; + } + + if (if_num > max_if_num) { + return 0; + } + + /* + * Interface statistics for all virtual interface pairs. + */ + for (; if_num < max_if_num; if_num++) { + + if (!nss_virt_if_stats_get(nss_ctx, if_num, &interface_stats_local, false)) + continue; + + bytes = scnprintf(line, sizeof(line), "if_num %d stats start:\n\n", if_num); + if ((bytes_read + bytes) > sz) + break; + + if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) + return -EFAULT; + + bytes_read += bytes; + + start = NSS_VIRT_IF_INTERFACE_STATS_RX_PACKETS; + end = NSS_VIRT_IF_INTERFACE_STATS_MAX; + while (bytes_read < sz && start < end) { + bytes = nss_virt_if_interface_stats_fill_row(line, sizeof(line), start, &interface_stats_local); + if (!bytes) + break; + + if ((bytes_read + bytes) > sz) + break; + + if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) + return -EFAULT; + + bytes_read += bytes; + start++; + } + + /* + * Save one valid interface number for base node statistics. + */ + if_num_valid = if_num; + + bytes = scnprintf(line, sizeof(line), "if_num %d stats end:\n\n", if_num); + if (bytes_read > (sz - bytes)) + break; + + if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) + return -EFAULT; + + bytes_read += bytes; + } + + /* + * Base node statistics. + */ + if (!nss_virt_if_stats_get(nss_ctx, if_num_valid, &base_node_stats_local, true)) + goto done; + + bytes = scnprintf(line, sizeof(line), "base node stats begin (shown on if_num %d):\n\n", if_num_valid); + if ((bytes_read + bytes) > sz) + goto done; + + if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) + return -EFAULT; + + bytes_read += bytes; + + start = NSS_VIRT_IF_BASE_NODE_STATS_ACTIVE_INTERFACES; + end = NSS_VIRT_IF_BASE_NODE_STATS_MAX; + while (bytes_read < sz && start < end) { + bytes = nss_virt_if_base_node_stats_fill_row(line, sizeof(line), start, &base_node_stats_local); + if (!bytes) + break; + + if ((bytes_read + bytes) > sz) + break; + + if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) + return -EFAULT; + + bytes_read += bytes; + start++; + } + + bytes = scnprintf(line, sizeof(line), "base node stats end.\n\n"); + if ((bytes_read + bytes) > sz) + goto done; + + if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) + return -EFAULT; + + bytes_read += bytes; + +done: + if (bytes_read > 0) { + *ppos = bytes_read; + } + + if (data) { + data->if_num = if_num; + } + + return bytes_read; +} + +/* + * nss_virt_if_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(virt_if) + +/* + * nss_virt_if_stats_dentry_create() + * Create virt_if statistics debug entry. + */ +void nss_virt_if_stats_dentry_create(void) +{ + nss_stats_create_dentry("virt_if", &nss_virt_if_stats_ops); +} + +/* + * nss_virt_if_stats_sync() + * Sync stats from the NSS FW + */ +void nss_virt_if_stats_sync(struct nss_virt_if_handle *handle, + struct nss_virt_if_stats *nwis) +{ + struct nss_virt_if_stats *stats = &handle->stats; + int i; + + spin_lock_bh(&nss_virt_if_lock); + stats->if_stats.node_stats.rx_packets += nwis->if_stats.node_stats.rx_packets; + stats->if_stats.node_stats.rx_bytes += nwis->if_stats.node_stats.rx_bytes; + stats->if_stats.node_stats.tx_packets += nwis->if_stats.node_stats.tx_packets; + stats->if_stats.node_stats.tx_bytes += nwis->if_stats.node_stats.tx_bytes; + + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + stats->if_stats.node_stats.rx_dropped[i] += nwis->if_stats.node_stats.rx_dropped[i]; + } + + stats->if_stats.tx_enqueue_failed += nwis->if_stats.tx_enqueue_failed; + stats->if_stats.shaper_enqueue_failed += nwis->if_stats.shaper_enqueue_failed; + stats->if_stats.ocm_alloc_failed += nwis->if_stats.ocm_alloc_failed; + + stats->base_stats.active_interfaces = nwis->base_stats.active_interfaces; + stats->base_stats.ocm_alloc_failed = nwis->base_stats.ocm_alloc_failed; + stats->base_stats.ddr_alloc_failed = nwis->base_stats.ddr_alloc_failed; + spin_unlock_bh(&nss_virt_if_lock); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_virt_if_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_virt_if_stats.h new file mode 100644 index 000000000..0c26fac92 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_virt_if_stats.h @@ -0,0 +1,51 @@ +/* + ****************************************************************************** + * Copyright (c) 2017,2019 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_VIRT_IF_STATS_H +#define __NSS_VIRT_IF_STATS_H + +/* + * virt_if base node statistics types. + */ +enum nss_virt_if_base_node_stats_types { + NSS_VIRT_IF_BASE_NODE_STATS_ACTIVE_INTERFACES, /* Number of active virtual interfaces */ + NSS_VIRT_IF_BASE_NODE_STATS_OCM_ALLOC_FAILED, /* Number of interface allocation failure on OCM */ + NSS_VIRT_IF_BASE_NODE_STATS_DDR_ALLOC_FAILED, /* Number of interface allocation failure on DDR */ + NSS_VIRT_IF_BASE_NODE_STATS_MAX, +}; + +/* + * virt_if interface statistics types. + */ +enum nss_virt_if_interface_stats_types { + NSS_VIRT_IF_INTERFACE_STATS_RX_PACKETS, /* Rx packets */ + NSS_VIRT_IF_INTERFACE_STATS_RX_BYTES, /* Rx bytes */ + NSS_VIRT_IF_INTERFACE_STATS_RX_DROPPED, /* Rx drop count */ + NSS_VIRT_IF_INTERFACE_STATS_TX_PACKETS, /* Tx packets */ + NSS_VIRT_IF_INTERFACE_STATS_TX_BYTES, /* Tx bytes */ + NSS_VIRT_IF_INTERFACE_STATS_TX_ENQUEUE_FAILED, /* Number of Tx enqueue failure */ + NSS_VIRT_IF_INTERFACE_STATS_SHAPER_ENQUEUE_FAILED, /* Number of shaper enqueue failure */ + NSS_VIRT_IF_INTERFACE_STATS_OCM_ALLOC_FAILED, /* Number of interface allocation failure on OCM */ + NSS_VIRT_IF_INTERFACE_STATS_MAX, +}; + +/* + * Virtual interface statistics APIs + */ +extern void nss_virt_if_stats_sync(struct nss_virt_if_handle *handle, struct nss_virt_if_stats *nwis); +extern void nss_virt_if_stats_dentry_create(void); + +#endif /* __NSS_VIRT_IF_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_vlan.c b/feeds/ipq807x/qca-nss-drv/src/nss_vlan.c new file mode 100644 index 000000000..23b5c0ba5 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_vlan.c @@ -0,0 +1,411 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_vlan_log.h" + +#define NSS_VLAN_TX_TIMEOUT 1000 /* 1 Second */ + +/* + * Private data structure + */ +static struct nss_vlan_pvt { + struct semaphore sem; + struct completion complete; + int response; + void *cb; + void *app_data; +} vlan_pvt; + +/* + * nss_vlan_get_context() + */ +struct nss_ctx_instance *nss_vlan_get_context(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.vlan_handler_id]; +} +EXPORT_SYMBOL(nss_vlan_get_context); + +/* + * nss_vlan_verify_if_num() + * Verify if_num passed to us. + */ +static bool nss_vlan_verify_if_num(uint32_t if_num) +{ + if (!nss_is_dynamic_interface(if_num)) { + return false; + } + + if (nss_dynamic_interface_get_type(nss_vlan_get_context(), if_num) != NSS_DYNAMIC_INTERFACE_TYPE_VLAN) { + return false; + } + + return true; +} + +/* + * nss_vlan_handler() + * Handle NSS -> HLOS messages for vlan + */ +static void nss_vlan_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, void *app_data) +{ + struct nss_vlan_msg *nvm = (struct nss_vlan_msg *)ncm; + nss_vlan_msg_callback_t cb; + + nss_assert(nss_vlan_verify_if_num(ncm->interface)); + + /* + * Trace messages. + */ + nss_vlan_log_rx_msg(nvm); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_VLAN_MSG_TYPE_MAX) { + nss_warning("%px: received invalid message %d for vlan interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_vlan_msg)) { + nss_warning("%px: length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Update the callback and app_data for NOTIFY messages, vlan sends all notify messages + * to the same callback/app_data. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_ctx->nss_top->vlan_callback; + ncm->app_data = (nss_ptr_t)app_data; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Do we have a call back + */ + if (!ncm->cb) { + return; + } + + /* + * callback + */ + cb = (nss_vlan_msg_callback_t)ncm->cb; + cb((void *)ncm->app_data, nvm); +} + +/* + * nss_vlan_callback() + * Callback to handle the completion of NSS->HLOS messages. + */ +static void nss_vlan_callback(void *app_data, struct nss_vlan_msg *nvm) +{ + nss_vlan_msg_callback_t callback = (nss_vlan_msg_callback_t)vlan_pvt.cb; + void *data = vlan_pvt.app_data; + + vlan_pvt.response = NSS_TX_SUCCESS; + vlan_pvt.cb = NULL; + vlan_pvt.app_data = NULL; + + if (nvm->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("vlan error response %d\n", nvm->cm.response); + vlan_pvt.response = nvm->cm.response; + } + + if (callback) { + callback(data, nvm); + } + complete(&vlan_pvt.complete); +} + +/* + * nss_vlan_tx_msg() + * Transmit a vlan message to NSSFW + */ +nss_tx_status_t nss_vlan_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_vlan_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Trace messages. + */ + nss_vlan_log_tx_msg(msg); + + /* + * Sanity check the message + */ + if (!nss_vlan_verify_if_num(ncm->interface)) { + nss_warning("%px: tx request for interface that is not a vlan: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type >= NSS_VLAN_MSG_TYPE_MAX) { + nss_warning("%px: message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_vlan_tx_msg); + +/* + * nss_vlan_tx_msg_sync() + * Transmit a vlan message to NSS firmware synchronously. + */ +nss_tx_status_t nss_vlan_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_vlan_msg *nvm) +{ + nss_tx_status_t status; + int ret = 0; + + down(&vlan_pvt.sem); + vlan_pvt.cb = (void *)nvm->cm.cb; + vlan_pvt.app_data = (void *)nvm->cm.app_data; + + nvm->cm.cb = (nss_ptr_t)nss_vlan_callback; + nvm->cm.app_data = (nss_ptr_t)NULL; + + status = nss_vlan_tx_msg(nss_ctx, nvm); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: vlan_tx_msg failed\n", nss_ctx); + up(&vlan_pvt.sem); + return status; + } + + ret = wait_for_completion_timeout(&vlan_pvt.complete, msecs_to_jiffies(NSS_VLAN_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: vlan msg tx failed due to timeout\n", nss_ctx); + vlan_pvt.response = NSS_TX_FAILURE; + } + + status = vlan_pvt.response; + up(&vlan_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_vlan_tx_msg_sync); + +/* + * nss_vlan_msg_init() + * Initialize nss_vlan_msg. + */ +void nss_vlan_msg_init(struct nss_vlan_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data) +{ + nss_cmn_msg_init(&ncm->cm, if_num, type, len, cb, app_data); +} +EXPORT_SYMBOL(nss_vlan_msg_init); + +/* + * nss_vlan_tx_change_mtu_msg + * API to send change mtu message to NSS FW + */ +nss_tx_status_t nss_vlan_tx_set_mtu_msg(uint32_t vlan_if_num, uint32_t mtu) +{ + struct nss_ctx_instance *nss_ctx = nss_vlan_get_context(); + struct nss_vlan_msg nvm; + struct nss_if_mtu_change *nimc; + + if (!nss_ctx) { + nss_warning("Can't get nss context\n"); + return NSS_TX_FAILURE; + } + + if (nss_vlan_verify_if_num(vlan_if_num) == false) { + nss_warning("%px: received invalid interface %d", nss_ctx, vlan_if_num); + return NSS_TX_FAILURE; + } + + nss_vlan_msg_init(&nvm, vlan_if_num, NSS_IF_MTU_CHANGE, + sizeof(struct nss_if_mtu_change), NULL, NULL); + + nimc = &nvm.msg.if_msg.mtu_change; + nimc->min_buf_size = (uint16_t)mtu; + + return nss_vlan_tx_msg_sync(nss_ctx, &nvm); +} +EXPORT_SYMBOL(nss_vlan_tx_set_mtu_msg); + +/* + * nss_vlan_tx_set_mac_addr_msg + * API to send change mac addr message to NSS FW + */ +nss_tx_status_t nss_vlan_tx_set_mac_addr_msg(uint32_t vlan_if_num, uint8_t *addr) +{ + struct nss_ctx_instance *nss_ctx = nss_vlan_get_context(); + struct nss_vlan_msg nvm; + struct nss_if_mac_address_set *nmas; + + if (!nss_ctx) { + nss_warning("Can't get nss context\n"); + return NSS_TX_FAILURE; + } + + if (nss_vlan_verify_if_num(vlan_if_num) == false) { + nss_warning("%px: received invalid interface %d", nss_ctx, vlan_if_num); + return NSS_TX_FAILURE; + } + + nss_vlan_msg_init(&nvm, vlan_if_num, NSS_IF_MAC_ADDR_SET, + sizeof(struct nss_if_mac_address_set), NULL, NULL); + + nmas = &nvm.msg.if_msg.mac_address_set; + memcpy(nmas->mac_addr, addr, ETH_ALEN); + return nss_vlan_tx_msg_sync(nss_ctx, &nvm); +} +EXPORT_SYMBOL(nss_vlan_tx_set_mac_addr_msg); + +/* + * nss_vlan_tx_vsi_attach_msg + * API to send VSI attach message to NSS FW + */ +nss_tx_status_t nss_vlan_tx_vsi_attach_msg(uint32_t vlan_if_num, uint32_t vsi) +{ + struct nss_ctx_instance *nss_ctx = nss_vlan_get_context(); + struct nss_vlan_msg nvm; + + if (!nss_ctx) { + nss_warning("Can't get nss context\n"); + return NSS_TX_FAILURE; + } + + if (nss_vlan_verify_if_num(vlan_if_num) == false) { + nss_warning("%px: received invalid interface %d\n", nss_ctx, vlan_if_num); + return NSS_TX_FAILURE; + } + + nvm.msg.if_msg.vsi_assign.vsi = vsi; + nss_vlan_msg_init(&nvm, vlan_if_num, NSS_IF_VSI_ASSIGN, + sizeof(struct nss_if_vsi_assign), NULL, NULL); + + return nss_vlan_tx_msg_sync(nss_ctx, &nvm); +} +EXPORT_SYMBOL(nss_vlan_tx_vsi_attach_msg); + +/* + * nss_vlan_tx_vsi_detach_msg + * API to send VSI detach message to NSS FW + */ +nss_tx_status_t nss_vlan_tx_vsi_detach_msg(uint32_t vlan_if_num, uint32_t vsi) +{ + struct nss_ctx_instance *nss_ctx = nss_vlan_get_context(); + struct nss_vlan_msg nvm; + + if (!nss_ctx) { + nss_warning("Can't get nss context\n"); + return NSS_TX_FAILURE; + } + + if (nss_vlan_verify_if_num(vlan_if_num) == false) { + nss_warning("%px: received invalid interface %d\n", nss_ctx, vlan_if_num); + return NSS_TX_FAILURE; + } + + nvm.msg.if_msg.vsi_unassign.vsi = vsi; + nss_vlan_msg_init(&nvm, vlan_if_num, NSS_IF_VSI_UNASSIGN, + sizeof(struct nss_if_vsi_unassign), NULL, NULL); + + return nss_vlan_tx_msg_sync(nss_ctx, &nvm); +} +EXPORT_SYMBOL(nss_vlan_tx_vsi_detach_msg); + +/* + * nss_vlan_tx_add_tag_msg + * API to send vlan add tag message to NSS FW + */ +nss_tx_status_t nss_vlan_tx_add_tag_msg(uint32_t vlan_if_num, uint32_t vlan_tag, uint32_t next_hop, uint32_t physical_dev) +{ + struct nss_ctx_instance *nss_ctx = nss_vlan_get_context(); + struct nss_vlan_msg nvm; + + if (!nss_ctx) { + nss_warning("Can't get nss context\n"); + return NSS_TX_FAILURE; + } + + if (nss_vlan_verify_if_num(vlan_if_num) == false) { + nss_warning("%px: received invalid interface %d\n", nss_ctx, vlan_if_num); + return NSS_TX_FAILURE; + } + + nvm.msg.add_tag.next_hop = next_hop; + nvm.msg.add_tag.if_num = physical_dev; + nvm.msg.add_tag.vlan_tag = vlan_tag; + nss_vlan_msg_init(&nvm, vlan_if_num, NSS_VLAN_MSG_ADD_TAG, + sizeof(struct nss_vlan_msg_add_tag), NULL, NULL); + + return nss_vlan_tx_msg_sync(nss_ctx, &nvm); +} +EXPORT_SYMBOL(nss_vlan_tx_add_tag_msg); + +/** + * @brief Register to send/receive vlan messages to NSS + * + * @param if_num NSS interface number + * @param vlan_data_callback Callback for vlan data + * @param netdev netdevice associated with the vlan interface + * @param features denotes the skb types supported by this interface + * + * @return nss_ctx_instance* NSS context + */ +struct nss_ctx_instance *nss_register_vlan_if(uint32_t if_num, nss_vlan_callback_t vlan_data_callback, + struct net_device *netdev, uint32_t features, void *app_ctx) +{ + struct nss_ctx_instance *nss_ctx = nss_vlan_get_context(); + + nss_assert(nss_vlan_verify_if_num(if_num)); + + nss_core_register_subsys_dp(nss_ctx, if_num, vlan_data_callback, NULL, app_ctx, netdev, features); + + nss_core_register_handler(nss_ctx, if_num, nss_vlan_handler, app_ctx); + + return nss_ctx; +} +EXPORT_SYMBOL(nss_register_vlan_if); + +/* + * nss_unregister_vlan_if() + */ +void nss_unregister_vlan_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = nss_vlan_get_context(); + + nss_assert(nss_vlan_verify_if_num(if_num)); + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + + nss_core_unregister_handler(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_unregister_vlan_if); + +/* + * nss_vlan_register_handler() + * debugfs stats msg handler received on static vlan interface + */ +void nss_vlan_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx = nss_vlan_get_context(); + + nss_info("nss_vlan_register_handler\n"); + nss_core_register_handler(nss_ctx, NSS_VLAN_INTERFACE, nss_vlan_handler, NULL); + + sema_init(&vlan_pvt.sem, 1); + init_completion(&vlan_pvt.complete); +} +EXPORT_SYMBOL(nss_vlan_register_handler); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_vlan_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_vlan_log.c new file mode 100644 index 000000000..b9e946a74 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_vlan_log.c @@ -0,0 +1,120 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_vlan_log.c + * NSS VLAN logger file. + */ + +#include "nss_core.h" + +/* + * nss_vlan_log_message_types_str + * VLAN message strings + */ +static int8_t *nss_vlan_log_message_types_str[NSS_VLAN_MSG_TYPE_MAX] __maybe_unused = { + "VLAN ADD TAG", +}; + +/* + * nss_vlan_log_error_response_types_str + * Strings for error types for VLAN messages + */ +static int8_t *nss_vlan_log_error_response_types_str[NSS_VLAN_ERROR_TYPE_MAX] __maybe_unused = { + "VLAN Unknown Message", +}; + +/* + * nss_vlan_log_add_tag_msg() + * Log NSS VLAN Add Tag message. + */ +static void nss_vlan_log_add_tag_msg(struct nss_vlan_msg *nvm) +{ + struct nss_vlan_msg_add_tag *nvtm __maybe_unused = &nvm->msg.add_tag; + nss_trace("%px: NSS VLAN Add Tag Message:\n" + "VLAN Tag: %d\n" + "VLAN Next Hop: %d\n" + "VLAN Interface Number: %d\n", + nvtm, nvtm->vlan_tag, + nvtm->next_hop, nvtm->if_num); +} + +/* + * nss_vlan_log_verbose() + * Log message contents. + */ +static void nss_vlan_log_verbose(struct nss_vlan_msg *nvm) +{ + switch (nvm->cm.type) { + case NSS_VLAN_MSG_ADD_TAG: + nss_vlan_log_add_tag_msg(nvm); + break; + + default: + nss_warning("%px: Invalid message type\n", nvm); + break; + } +} + +/* + * nss_vlan_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_vlan_log_tx_msg(struct nss_vlan_msg *nvm) +{ + if (nvm->cm.type >= NSS_VLAN_MSG_TYPE_MAX) { + nss_warning("%px: Invalid message type\n", nvm); + return; + } + + nss_info("%px: type[%d]:%s\n", nvm, nvm->cm.type, nss_vlan_log_message_types_str[nvm->cm.type]); + nss_vlan_log_verbose(nvm); +} + +/* + * nss_vlan_log_rx_msg() + * Log messages received from FW. + */ +void nss_vlan_log_rx_msg(struct nss_vlan_msg *nvm) +{ + if (nvm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", nvm); + return; + } + + if (nvm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (nvm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", nvm, nvm->cm.type, + nss_vlan_log_message_types_str[nvm->cm.type], + nvm->cm.response, nss_cmn_response_str[nvm->cm.response]); + goto verbose; + } + + if (nvm->cm.error >= NSS_VLAN_ERROR_TYPE_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + nvm, nvm->cm.type, nss_vlan_log_message_types_str[nvm->cm.type], + nvm->cm.response, nss_cmn_response_str[nvm->cm.response], + nvm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + nvm, nvm->cm.type, nss_vlan_log_message_types_str[nvm->cm.type], + nvm->cm.response, nss_cmn_response_str[nvm->cm.response], + nvm->cm.error, nss_vlan_log_error_response_types_str[nvm->cm.error]); + +verbose: + nss_vlan_log_verbose(nvm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_vlan_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_vlan_log.h new file mode 100644 index 000000000..21b365d15 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_vlan_log.h @@ -0,0 +1,37 @@ +/* + ****************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_VLAN_LOG_H__ +#define __NSS_VLAN_LOG_H__ + +/* + * nss_vlan_log.h + * NSS VLAN Log Header File + */ + +/* + * nss_vlan_log_tx_msg + * Logs a vlan message that is sent to the NSS firmware. + */ +void nss_vlan_log_tx_msg(struct nss_vlan_msg *ncm); + +/* + * nss_vlan_log_rx_msg + * Logs a vlan message that is received from the NSS firmware. + */ +void nss_vlan_log_rx_msg(struct nss_vlan_msg *ncm); + +#endif /* __NSS_VLAN_LOG_H__ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_vxlan.c b/feeds/ipq807x/qca-nss-drv/src/nss_vxlan.c new file mode 100644 index 000000000..bde299663 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_vxlan.c @@ -0,0 +1,326 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_vxlan.c + * NSS VxLAN driver interface APIs + */ +#include "nss_core.h" +#include "nss_vxlan.h" +#include "nss_cmn.h" +#include "nss_tx_rx_common.h" +#include "nss_vxlan_log.h" +#include "nss_vxlan_stats.h" + +#define NSS_VXLAN_TX_TIMEOUT 3000 + +/* + * Private data structure + */ +static struct { + struct semaphore sem; /* Semaphore structure. */ + struct completion complete; /* Completion structure. */ + int response; /* Response from FW. */ + void *cb; /* Original cb for msgs. */ + void *app_data; /* Original app_data for msgs. */ +} nss_vxlan_pvt; + +/* + * nss_vxlan_verify_if_num() + * Verify if_num passed to us. + */ +static bool nss_vxlan_verify_if_num(uint32_t if_num) +{ + uint32_t type; + + if (if_num == NSS_VXLAN_INTERFACE) { + return true; + } + + type = nss_dynamic_interface_get_type(nss_vxlan_get_ctx(), if_num); + + return ((type == NSS_DYNAMIC_INTERFACE_TYPE_VXLAN_INNER) || + (type == NSS_DYNAMIC_INTERFACE_TYPE_VXLAN_OUTER)); +} + +/* + * nss_vxlan_callback() + * Callback to handle the completion of NSS->HLOS messages. + */ +static void nss_vxlan_callback(void *app_data, struct nss_cmn_msg *msg) +{ + nss_vxlan_msg_callback_t callback = (nss_vxlan_msg_callback_t)nss_vxlan_pvt.cb; + void *data = nss_vxlan_pvt.app_data; + + nss_vxlan_pvt.response = NSS_TX_SUCCESS; + nss_vxlan_pvt.cb = NULL; + nss_vxlan_pvt.app_data = NULL; + + if (msg->response != NSS_CMN_RESPONSE_ACK) { + nss_warning("Vxlan Error response %d\n", msg->response); + nss_vxlan_pvt.response = NSS_TX_FAILURE; + } + + if (callback) { + callback(data, msg); + } + complete(&nss_vxlan_pvt.complete); +} + +/* + * nss_vxlan_handler() + * Handle NSS -> HLOS messages for vxlan. + */ +static void nss_vxlan_msg_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_vxlan_msg *nvm = (struct nss_vxlan_msg *)ncm; + nss_vxlan_msg_callback_t cb; + + BUG_ON(!nss_vxlan_verify_if_num(ncm->interface)); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_VXLAN_MSG_TYPE_MAX) { + nss_warning("%px: received invalid message %d for vxlan interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_vxlan_msg)) { + nss_warning("%px: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Log messages. + */ + nss_core_log_msg_failures(nss_ctx, ncm); + nss_vxlan_log_rx_msg(nvm); + + switch (nvm->cm.type) { + case NSS_VXLAN_MSG_TYPE_STATS_SYNC: + /* + * Update common node statistics + */ + nss_vxlan_stats_sync(nss_ctx, nvm); + } + + /* + * Update the callback for NOTIFY messages + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_core_get_msg_handler(nss_ctx, ncm->interface); + } + + cb = (nss_vxlan_msg_callback_t)ncm->cb; + + /* + * Do we have a callback? + */ + if (!cb) { + nss_trace("%px: cb is null for interface %d\n", nss_ctx, ncm->interface); + return; + } + + cb((void *)nss_ctx->subsys_dp_register[ncm->interface].ndev, ncm); +} + +/* + * nss_vxlan_tx_msg() + * Transmit a vxlan message to NSS FW. Don't call this from softirq/interrupts. + */ +nss_tx_status_t nss_vxlan_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_vxlan_msg *nvm) +{ + struct nss_cmn_msg *ncm = &nvm->cm; + + if (!nss_vxlan_verify_if_num(ncm->interface)) { + nss_warning("%px: wrong interface number %u\n", nss_ctx, nvm->cm.interface); + return NSS_TX_FAILURE_BAD_PARAM; + } + + if (ncm->type >= NSS_VXLAN_MSG_TYPE_MAX) { + nss_warning("%px: wrong message type %u\n", nss_ctx, ncm->type); + return NSS_TX_FAILURE_BAD_PARAM; + } + + /* + * Trace messages. + */ + nss_vxlan_log_tx_msg(nvm); + + return nss_core_send_cmd(nss_ctx, nvm, sizeof(*nvm), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_vxlan_tx_msg); + +/* + * nss_vxlan_tx_msg_sync() + * Transmit a vxlan message to NSS firmware synchronously. + */ +nss_tx_status_t nss_vxlan_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_vxlan_msg *nvm) +{ + nss_tx_status_t status; + int ret; + + down(&nss_vxlan_pvt.sem); + nss_vxlan_pvt.cb = (void *)nvm->cm.cb; + nss_vxlan_pvt.app_data = (void *)nvm->cm.app_data; + + nvm->cm.cb = (nss_ptr_t)nss_vxlan_callback; + nvm->cm.app_data = (nss_ptr_t)NULL; + + status = nss_vxlan_tx_msg(nss_ctx, nvm); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: vxlan_tx_msg failed\n", nss_ctx); + up(&nss_vxlan_pvt.sem); + return status; + } + + ret = wait_for_completion_timeout(&nss_vxlan_pvt.complete, msecs_to_jiffies(NSS_VXLAN_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: vxlan tx sync failed due to timeout\n", nss_ctx); + nss_vxlan_pvt.response = NSS_TX_FAILURE; + } + + status = nss_vxlan_pvt.response; + up(&nss_vxlan_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_vxlan_tx_msg_sync); + +/* + * nss_vxlan_msg_init() + * Initialize VxLAN message. + */ +void nss_vxlan_msg_init(struct nss_vxlan_msg *nvm, uint16_t if_num, uint32_t type, uint32_t len, + nss_vxlan_msg_callback_t cb, void *app_data) +{ + nss_cmn_msg_init(&nvm->cm, if_num, type, len, (void*)cb, app_data); +} +EXPORT_SYMBOL(nss_vxlan_msg_init); + +/* + * nss_vxlan_unregister_if() + * Unregister a data packet notifier with NSS FW. + */ +bool nss_vxlan_unregister_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx; + + nss_ctx = nss_vxlan_get_ctx(); + if (!nss_vxlan_verify_if_num(if_num)) { + nss_warning("%px: data unregister received for invalid interface %d", nss_ctx, if_num); + return false; + } + + nss_core_unregister_handler(nss_ctx, if_num); + nss_core_unregister_subsys_dp(nss_ctx, if_num); + return true; +} +EXPORT_SYMBOL(nss_vxlan_unregister_if); + +/* + * nss_vxlan_register_if() + * Registers a data packet notifier with NSS FW. + */ +struct nss_ctx_instance *nss_vxlan_register_if(uint32_t if_num, + uint32_t type, + nss_vxlan_buf_callback_t data_cb, + nss_vxlan_msg_callback_t notify_cb, + struct net_device *netdev, + uint32_t features) +{ + struct nss_ctx_instance *nss_ctx; + int core_status; + + nss_ctx = nss_vxlan_get_ctx(); + if (!nss_vxlan_verify_if_num(if_num)) { + nss_warning("%px: data register received for invalid interface %d", nss_ctx, if_num); + return NULL; + } + + core_status = nss_core_register_handler(nss_ctx, if_num, nss_vxlan_msg_handler, NULL); + if (core_status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: nss core register handler failed for if_num:%d with error :%d", nss_ctx, if_num, core_status); + return NULL; + } + + core_status = nss_core_register_msg_handler(nss_ctx, if_num, notify_cb); + if (core_status != NSS_CORE_STATUS_SUCCESS) { + nss_core_unregister_handler(nss_ctx, if_num); + nss_warning("%px: nss core register handler failed for if_num:%d with error :%d", nss_ctx, if_num, core_status); + return NULL; + } + + nss_core_register_subsys_dp(nss_ctx, if_num, data_cb, NULL, NULL, netdev, features); + nss_core_set_subsys_dp_type(nss_ctx, netdev, if_num, type); + return nss_ctx; +} +EXPORT_SYMBOL(nss_vxlan_register_if); + +/* + * nss_vxlan_ifnum_with_core_id() + * Append core id to vxlan interface num. + */ +int nss_vxlan_ifnum_with_core_id(int if_num) +{ + struct nss_ctx_instance *nss_ctx = nss_vxlan_get_ctx(); + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (!nss_vxlan_verify_if_num(if_num)) { + nss_warning("%px: Invalid if_num: %d, must be a dynamic interface\n", nss_ctx, if_num); + return 0; + } + return NSS_INTERFACE_NUM_APPEND_COREID(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_vxlan_ifnum_with_core_id); + +/* + * nss_vxlan_get_ctx() + * Return a VxLAN NSS context. + */ +struct nss_ctx_instance *nss_vxlan_get_ctx() +{ + struct nss_ctx_instance *nss_ctx; + + nss_ctx = &nss_top_main.nss[nss_top_main.vxlan_handler_id]; + return nss_ctx; +} +EXPORT_SYMBOL(nss_vxlan_get_ctx); + +/* + * nss_vxlan_init() + * Initializes Vxlan. Gets called from nss_init.c. + */ +void nss_vxlan_init() +{ + uint32_t core_status; + struct nss_ctx_instance *nss_ctx = nss_vxlan_get_ctx(); + if (!nss_ctx) { + nss_warning("%px: VxLAN is not registered", nss_ctx); + return; + } + + nss_vxlan_stats_dentry_create(); + sema_init(&nss_vxlan_pvt.sem, 1); + init_completion(&nss_vxlan_pvt.complete); + core_status = nss_core_register_handler(nss_ctx, NSS_VXLAN_INTERFACE, nss_vxlan_msg_handler, NULL); + + if (core_status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: nss core register handler failed for if_num:%d with error :%d", nss_ctx, NSS_VXLAN_INTERFACE, core_status); + } + +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_vxlan_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_vxlan_log.c new file mode 100644 index 000000000..7bbfc5e87 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_vxlan_log.c @@ -0,0 +1,257 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_vxlan_log.c + * NSS VXLAN logger file. + */ + +#include "nss_core.h" + +/* + * nss_vxlan_log_message_types_str + * VXLAN message strings + */ +static int8_t *nss_vxlan_log_message_types_str[NSS_VXLAN_MSG_TYPE_MAX] __maybe_unused = { + "VxLAN Sync Stats", + "VxLAN Tunnel Configure Rule", + "VxLAN Tunnel Unconfigure Rule", + "VxLAN Enable Tunnel", + "VxLAN Disable Tunnel", + "VxLAN Add MAC rule", + "VxLAN Delete MAC rule", + "VxLAN MAC DB Stats" +}; + +/* + * nss_vxlan_log_error_response_types_str + * Strings for error types for VXLAN messages + */ +static int8_t *nss_vxlan_log_error_response_types_str[NSS_VXLAN_ERROR_TYPE_MAX] __maybe_unused = { + "VxLAN Unknown Error", + "VXLAN Decap Register fail", + "VXLAN Dest IP mismatch", + "VXLAN Invalid VNI", + "VXLAN Invalid L3 Proto", + "VXLAN Invalid UDP Proto", + "VXLAN Invalid Src Port", + "VXLAN MAC Bad entry", + "VXLAN MAC Entry exists", + "VXLAN MAC Entry does not exist", + "VXLAN MAC Entry unhashed", + "VXLAN MAC Entry alloc failed", + "VXLAN MAC Entry delete failed", + "VXLAN MAC Table full", + "VXLAN Sibling Node does not exist", + "VXLAN Tunnel Configured", + "VXLAN Tunnel Unconfigured", + "VXLAN Tunnel addition failed", + "VXLAN Tunnel Disabled", + "VXLAN Tunnel Enabled", + "VXLAN Tunnel Entry exists" +}; + +/* + * nss_vxlan_log_rule_msg() + * Log NSS VXLAN rule message. + */ +static void nss_vxlan_log_rule_msg(struct nss_vxlan_rule_msg *nvrm) +{ + nss_trace("%px: NSS VXLAN Rule message \n" + "VxLAN Tunnel Flags: %x\n" + "VNET ID: %u\n" + "Flowlabel: %u\n" + "TOS: %u\n" + "TTL: %u\n" + "source port min: %u max: %u" + "destination port: %u", + nvrm, + nvrm->tunnel_flags, + nvrm->vni, + nvrm->flow_label, + nvrm->tos, + nvrm->ttl, + nvrm->src_port_min, + nvrm->src_port_max, + nvrm->dest_port); +} + +/* + * nss_vxlan_mac_rule_msg() + * Log NSS Vxlan MAC rule message. + */ +static void nss_vxlan_log_mac_msg(struct nss_vxlan_mac_msg *nvmm) +{ + nss_trace("%px: NSS VXLAN MAC message \n" + "Encap Rule Src IP: %px\n" + "Encap Rule Dst Ip: %px\n" + "Vxlan VNet ID: %u\n" + "Vxlan Mac Addr: %pM", + nvmm, + &nvmm->encap.src_ip, + &nvmm->encap.dest_ip, + nvmm->vni, + nvmm->mac_addr); +} + +/* + * nss_vxlan_log_rule_create_msg() + * Log NSS Vxlan rule create message. + */ +static void nss_vxlan_log_rule_create_msg(struct nss_vxlan_msg *nvm) +{ + struct nss_vxlan_rule_msg *nvrm __maybe_unused = &nvm->msg.vxlan_create; + nss_vxlan_log_rule_msg(nvrm); +} + +/* + * nss_vxlan_log_rule_destroy_msg() + * Log NSS Vxlan rule destroy message. + */ +static void nss_vxlan_log_rule_destroy_msg(struct nss_vxlan_msg *nvm) +{ + struct nss_vxlan_rule_msg *nvrm __maybe_unused = &nvm->msg.vxlan_destroy; + nss_vxlan_log_rule_msg(nvrm); +} + +/* + * nss_vxlan_log_enable_msg() + * Log NSS Vxlan rule enable message. + */ +static void nss_vxlan_log_enable_msg(struct nss_vxlan_msg *nvm) +{ + nss_trace("%px: NSS VXLAN Tunnel state message: Enable \n", nvm); +} + +/* + * nss_vxlan_log_disable_msg() + * Log NSS Vxlan rule disable message. + */ +static void nss_vxlan_log_disable_msg(struct nss_vxlan_msg *nvm) +{ + nss_trace("%px: NSS VXLAN Tunnel state message: Disable \n", nvm); +} + +/* + * nss_vxlan_log_mac_add_msg() + * Log NSS VXLAN mac rule add message. + */ +static void nss_vxlan_log_mac_add_msg(struct nss_vxlan_msg *nvm) +{ + struct nss_vxlan_mac_msg *nvmm __maybe_unused = &nvm->msg.mac_add; + nss_vxlan_log_mac_msg(nvmm); +} + +/* + * nss_vxlan_log_mac_del_msg() + * Log NSS VXLAN mac rule del message. + */ +static void nss_vxlan_log_mac_del_msg(struct nss_vxlan_msg *nvm) +{ + struct nss_vxlan_mac_msg *nvmm __maybe_unused = &nvm->msg.mac_del; + nss_vxlan_log_mac_msg(nvmm); +} + +/* + * nss_vxlan_log_verbose() + * Log message contents. + */ +static void nss_vxlan_log_verbose(struct nss_vxlan_msg *nvm) +{ + switch (nvm->cm.type) { + case NSS_VXLAN_MSG_TYPE_TUN_CONFIGURE: + nss_vxlan_log_rule_create_msg(nvm); + break; + + case NSS_VXLAN_MSG_TYPE_TUN_UNCONFIGURE: + nss_vxlan_log_rule_destroy_msg(nvm); + break; + + case NSS_VXLAN_MSG_TYPE_TUN_ENABLE: + nss_vxlan_log_enable_msg(nvm); + break; + + case NSS_VXLAN_MSG_TYPE_TUN_DISABLE: + nss_vxlan_log_disable_msg(nvm); + break; + + case NSS_VXLAN_MSG_TYPE_MAC_ADD: + nss_vxlan_log_mac_add_msg(nvm); + break; + + case NSS_VXLAN_MSG_TYPE_MAC_DEL: + nss_vxlan_log_mac_del_msg(nvm); + break; + + case NSS_VXLAN_MSG_TYPE_STATS_SYNC: + case NSS_VXLAN_MSG_TYPE_MACDB_STATS: + break; + + default: + nss_trace("%px: Invalid message type\n", nvm); + break; + } +} + +/* + * nss_vxlan_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_vxlan_log_tx_msg(struct nss_vxlan_msg *nvm) +{ + if (nvm->cm.type >= NSS_VXLAN_MSG_TYPE_MAX) { + nss_warning("%px: Invalid message type\n", nvm); + return; + } + + nss_info("%px: type[%d]:%s\n", nvm, nvm->cm.type, nss_vxlan_log_message_types_str[nvm->cm.type]); + nss_vxlan_log_verbose(nvm); +} + +/* + * nss_vxlan_log_rx_msg() + * Log messages received from FW. + */ +void nss_vxlan_log_rx_msg(struct nss_vxlan_msg *nvm) +{ + if (nvm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", nvm); + return; + } + + if (nvm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (nvm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", nvm, nvm->cm.type, + nss_vxlan_log_message_types_str[nvm->cm.type], + nvm->cm.response, nss_cmn_response_str[nvm->cm.response]); + goto verbose; + } + + if (nvm->cm.error >= NSS_VXLAN_ERROR_TYPE_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + nvm, nvm->cm.type, nss_vxlan_log_message_types_str[nvm->cm.type], + nvm->cm.response, nss_cmn_response_str[nvm->cm.response], + nvm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + nvm, nvm->cm.type, nss_vxlan_log_message_types_str[nvm->cm.type], + nvm->cm.response, nss_cmn_response_str[nvm->cm.response], + nvm->cm.error, nss_vxlan_log_error_response_types_str[nvm->cm.error]); + +verbose: + nss_vxlan_log_verbose(nvm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_vxlan_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_vxlan_log.h new file mode 100644 index 000000000..2db12be9f --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_vxlan_log.h @@ -0,0 +1,37 @@ +/* + ****************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_VXLAN_LOG_H__ +#define __NSS_VXLAN_LOG_H__ + +/* + * nss_vxlan_log.h + * NSS VXLAN Log Header File. + */ + +/* + * nss_vxlan_log_tx_msg + * Logs a Vxlan message that is sent to the NSS firmware. + */ +void nss_vxlan_log_tx_msg(struct nss_vxlan_msg *nvm); + +/* + * nss_vxlan_log_rx_msg + * Logs a Vxlan message that is received from the NSS firmware. + */ +void nss_vxlan_log_rx_msg(struct nss_vxlan_msg *nvm); + +#endif /* __NSS_VXLAN_LOG_H__ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_vxlan_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_vxlan_stats.c new file mode 100644 index 000000000..0559d0a2a --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_vxlan_stats.c @@ -0,0 +1,122 @@ +/* + ************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_stats.h" +#include "nss_vxlan_stats.h" +#include + +#define NSS_VXLAN_STATS_MAX_LINES (NSS_STATS_NODE_MAX + 32) + /**< Maximum number of lines for VXLAN statistics dump. */ +#define NSS_VXLAN_STATS_SIZE_PER_IF (NSS_STATS_MAX_STR_LENGTH * NSS_VXLAN_STATS_MAX_LINES) + /**< Total number of statistics per VXLAN interface. */ + +/* + * nss_vxlan_stats_read() + * Read vxlan node statiistics. + */ +static ssize_t nss_vxlan_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + struct nss_ctx_instance *nss_ctx = nss_vxlan_get_ctx(); + enum nss_dynamic_interface_type type; + ssize_t bytes_read = 0; + size_t len = 0, size; + uint32_t if_num; + char *buf; + + size = NSS_VXLAN_STATS_SIZE_PER_IF; + buf = kzalloc(size, GFP_KERNEL); + if (!buf) { + nss_warning("Could not allocate memory for local statistics buffer\n"); + return 0; + } + + /* + * Common node stats for each VxLAN dynamic interface. + */ + for (if_num = 0; if_num < NSS_MAX_NET_INTERFACES; if_num++) { + if (if_num == NSS_VXLAN_INTERFACE) { + len += scnprintf(buf + len, size - len, "\nBase node if_num:%03u", if_num); + len += scnprintf(buf + len, size - len, "\n-------------------\n"); + len += nss_stats_fill_common_stats(if_num, NSS_STATS_SINGLE_INSTANCE, buf, len, size - len, "vxlan"); + continue; + } + + type = nss_dynamic_interface_get_type(nss_ctx, if_num); + switch (type) { + case NSS_DYNAMIC_INTERFACE_TYPE_VXLAN_INNER: + len += scnprintf(buf + len, size - len, "\nInner if_num:%03u", if_num); + break; + + case NSS_DYNAMIC_INTERFACE_TYPE_VXLAN_OUTER: + len += scnprintf(buf + len, size - len, "\nOuter if_num:%03u", if_num); + break; + + default: + continue; + } + + len += scnprintf(buf + len, size - len, "\n-------------------\n"); + len += nss_stats_fill_common_stats(if_num, NSS_STATS_SINGLE_INSTANCE, buf, len, size - len, "vxlan"); + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, buf, len); + kfree(buf); + return bytes_read; +} + +/* + * nss_vxlan_stats_sync() + * Update vxlan common node statistics. + */ +void nss_vxlan_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_vxlan_msg *nvm) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + struct nss_vxlan_stats_msg *msg_stats = &nvm->msg.stats; + uint64_t *if_stats; + + spin_lock_bh(&nss_top->stats_lock); + + /* + * Update common node stats + */ + if_stats = nss_top->stats_node[nvm->cm.interface]; + if_stats[NSS_STATS_NODE_RX_PKTS] += msg_stats->node_stats.rx_packets; + if_stats[NSS_STATS_NODE_RX_BYTES] += msg_stats->node_stats.rx_bytes; + if_stats[NSS_STATS_NODE_RX_QUEUE_0_DROPPED] += msg_stats->node_stats.rx_dropped[0]; + if_stats[NSS_STATS_NODE_RX_QUEUE_1_DROPPED] += msg_stats->node_stats.rx_dropped[1]; + if_stats[NSS_STATS_NODE_RX_QUEUE_2_DROPPED] += msg_stats->node_stats.rx_dropped[2]; + if_stats[NSS_STATS_NODE_RX_QUEUE_3_DROPPED] += msg_stats->node_stats.rx_dropped[3]; + + if_stats[NSS_STATS_NODE_TX_PKTS] += msg_stats->node_stats.tx_packets; + if_stats[NSS_STATS_NODE_TX_BYTES] += msg_stats->node_stats.tx_bytes; + + spin_unlock_bh(&nss_top->stats_lock); +} + +/* + * nss_vxlan_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(vxlan) + +/* + * nss_vxlan_stats_dentry_create() + * Create vxlan statistics debug entry. + */ +void nss_vxlan_stats_dentry_create(void) +{ + nss_stats_create_dentry("vxlan", &nss_vxlan_stats_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_vxlan_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_vxlan_stats.h new file mode 100644 index 000000000..b4748f416 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_vxlan_stats.h @@ -0,0 +1,32 @@ +/* + ************************************************************************** + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef _NSS_VXLAN_STATS_H_ +#define _NSS_VXLAN_STATS_H_ + +/* + * nss_vxlan_stats_dentry_create + * Creates vxlan interface statistics debug entry. + */ +void nss_vxlan_stats_dentry_create(void); + +/* + * nss_vxlan_stats_sync + * Update vxlan common node statistics. + */ +void nss_vxlan_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_vxlan_msg *nvm); + +#endif /* _NSS_VXLAN_STATS_H_ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_wifi.c b/feeds/ipq807x/qca-nss-drv/src/nss_wifi.c new file mode 100644 index 000000000..559d947c8 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_wifi.c @@ -0,0 +1,198 @@ +/* + ************************************************************************** + * Copyright (c) 2015-2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_wifi_stats.h" +#include "nss_wifi_log.h" + +/* + * nss_wifi_get_context() + * Get NSS context of Wifi. + */ +struct nss_ctx_instance *nss_wifi_get_context() +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id]; +} + +/* + * nss_wifi_handler() + * Handle NSS -> HLOS messages for wifi + */ +static void nss_wifi_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_wifi_msg *ntm = (struct nss_wifi_msg *)ncm; + void *ctx; + nss_wifi_msg_callback_t cb; + + nss_info("%px: NSS ->HLOS message for wifi\n", nss_ctx); + + BUG_ON(((ncm->interface < NSS_WIFI_INTERFACE0) || (ncm->interface > NSS_WIFI_INTERFACE2))); + + /* + * Trace messages. + */ + nss_wifi_log_rx_msg(ntm); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_WIFI_MAX_MSG) { + nss_warning("%px: received invalid message %d for wifi interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_wifi_msg)) { + nss_warning("%px: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Snoop messages for local driver and handle + */ + switch (ntm->cm.type) { + case NSS_WIFI_STATS_MSG: + /* + * To create the old API gmac statistics, we use the new extended GMAC stats. + */ + nss_wifi_stats_sync(nss_ctx, &ntm->msg.statsmsg, ncm->interface); + break; + } + + /* + * Update the callback and app_data for NOTIFY messages, wifi sends all notify messages + * to the same callback/app_data. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_ctx->nss_top->wifi_msg_callback; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Do we have a call back + */ + if (!ncm->cb) { + nss_info("%px: cb null for wifi interface %d", nss_ctx, ncm->interface); + return; + } + + /* + * Get callback & context + */ + cb = (nss_wifi_msg_callback_t)ncm->cb; + ctx = nss_ctx->subsys_dp_register[ncm->interface].ndev; + + /* + * call wifi msg callback + */ + if (!ctx) { + nss_warning("%px: Event received for wifi interface %d before registration", nss_ctx, ncm->interface); + return; + } + + cb(ctx, ntm); +} + +/* + * nss_wifi_tx_msg + * Transmit a wifi message to NSS FW + */ +nss_tx_status_t nss_wifi_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_wifi_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Trace messages. + */ + nss_wifi_log_tx_msg(msg); + + if (ncm->type > NSS_WIFI_MAX_MSG) { + nss_warning("%px: wifi message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} + +/* + **************************************** + * Register/Unregister/Miscellaneous APIs + **************************************** + */ + +/* + * nss_register_wifi_if() + * Register Wifi with nss driver + */ +struct nss_ctx_instance *nss_register_wifi_if(uint32_t if_num, nss_wifi_callback_t wifi_callback, + nss_wifi_callback_t wifi_ext_callback, + nss_wifi_msg_callback_t event_callback, struct net_device *netdev, uint32_t features) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id]; + + nss_assert(nss_ctx); + nss_assert((if_num >= NSS_MAX_VIRTUAL_INTERFACES) && (if_num < NSS_MAX_NET_INTERFACES)); + + nss_info("%px: nss_register_wifi_if if_num %d wifictx %px", nss_ctx, if_num, netdev); + + nss_core_register_subsys_dp(nss_ctx, if_num, wifi_callback, wifi_ext_callback, NULL, netdev, features); + + nss_top_main.wifi_msg_callback = event_callback; + + return nss_ctx; +} + +/* + * nss_unregister_wifi_if() + * Unregister wifi with nss driver + */ +void nss_unregister_wifi_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id]; + + nss_assert(nss_ctx); + nss_assert((if_num >= NSS_MAX_VIRTUAL_INTERFACES) && (if_num < NSS_MAX_NET_INTERFACES)); + + nss_ctx->nss_top->wifi_msg_callback = NULL; + nss_core_unregister_subsys_dp(nss_ctx, if_num); +} + +/* + * nss_wifi_register_handler() + * Register handle for notfication messages received on wifi interface + */ +void nss_wifi_register_handler(void ) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id]; + + nss_assert(nss_ctx); + + nss_info("nss_wifi_register_handler"); + + nss_core_register_handler(nss_ctx, NSS_WIFI_INTERFACE0, nss_wifi_handler, NULL); + nss_core_register_handler(nss_ctx, NSS_WIFI_INTERFACE1, nss_wifi_handler, NULL); + nss_core_register_handler(nss_ctx, NSS_WIFI_INTERFACE2, nss_wifi_handler, NULL); + + nss_wifi_stats_dentry_create(); +} + +EXPORT_SYMBOL(nss_wifi_get_context); +EXPORT_SYMBOL(nss_wifi_tx_msg); +EXPORT_SYMBOL(nss_register_wifi_if); +EXPORT_SYMBOL(nss_unregister_wifi_if); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_wifi_ext_vdev.c b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_ext_vdev.c new file mode 100644 index 000000000..fce92d9fb --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_ext_vdev.c @@ -0,0 +1,337 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_wifi_ext_vdev_stats.h" +#include "nss_wifi_ext_vdev_log.h" + +#define NSS_WIFI_EXT_VDEV_TX_TIMEOUT 3000 /* 3 seconds */ + +/* + * Private data structure + */ +static struct nss_wifi_ext_vdev_pvt { + struct semaphore sem; + struct completion complete; + int response; + void *cb; + void *app_data; +} wifi_ext_vdev_pvt; + +/* + * nss_wifi_ext_vdev_verify_if_num() + * Verify if_num passed to us. + */ +static bool nss_wifi_ext_vdev_verify_if_num(uint32_t if_num) +{ + uint32_t type = nss_dynamic_interface_get_type(nss_wifi_ext_vdev_get_ctx(), if_num); + + switch (type) { + case NSS_DYNAMIC_INTERFACE_TYPE_WIFI_EXT_VDEV_WDS: + return true; + default: + return false; + } +} + +/* + * nss_wifi_ext_vdev_handler() + * Handle NSS -> HLOS messages for wifi_ext_vdev + */ +static void nss_wifi_ext_vdev_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, void *app_data) +{ + struct nss_wifi_ext_vdev_msg *nwevm = (struct nss_wifi_ext_vdev_msg *)ncm; + void *ctx; + + nss_wifi_ext_vdev_msg_callback_t cb; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + BUG_ON(!nss_wifi_ext_vdev_verify_if_num(ncm->interface)); + + /* + * Trace Messages + */ + nss_wifi_ext_vdev_log_rx_msg(nwevm); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_WIFI_EXT_VDEV_MSG_MAX) { + nss_warning("%px: received invalid message %d for WiFi extended VAP interface %d", nss_ctx, ncm->type, ncm->interface); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_wifi_ext_vdev_msg)) { + nss_warning("%px: wifi_ext_vdev message length is invalid: %d", nss_ctx, ncm->len); + return; + } + + /* + * Check messages + */ + switch (nwevm->cm.type) { + case NSS_WIFI_EXT_VDEV_MSG_STATS_SYNC: + nss_wifi_ext_vdev_stats_sync(nss_ctx, &nwevm->msg.stats, ncm->interface); + break; + } + + /* + * Update the callback and app_data for NOTIFY messages + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_core_get_msg_handler(nss_ctx, ncm->interface); + ncm->app_data = (nss_ptr_t)nss_ctx->subsys_dp_register[ncm->interface].app_data; + } + + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * callback + */ + cb = (nss_wifi_ext_vdev_msg_callback_t)ncm->cb; + ctx = (void *)ncm->app_data; + + /* + * call the callback + */ + if (!cb) { + return; + } + + cb(ctx, ncm); +} + +/* + * nss_wifi_ext_vdev_msg_init() + * Initialize wifi message. + */ +void nss_wifi_ext_vdev_msg_init(struct nss_wifi_ext_vdev_msg *nim, uint32_t if_num, + uint32_t type, uint32_t len, + nss_wifi_ext_vdev_msg_callback_t cb, void *app_data) +{ + nss_cmn_msg_init(&nim->cm, if_num, type, len, cb, app_data); +} +EXPORT_SYMBOL(nss_wifi_ext_vdev_msg_init); + +/* + * nss_wifi_ext_vdev_tx_msg() + * Transmit a wifi vdev message to NSSFW + */ +nss_tx_status_t nss_wifi_ext_vdev_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_wifi_ext_vdev_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Trace Messages + */ + nss_wifi_ext_vdev_log_tx_msg(msg); + + if (ncm->type >= NSS_WIFI_EXT_VDEV_MSG_MAX) { + nss_warning("%px: wifi vdev message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + BUG_ON(!nss_wifi_ext_vdev_verify_if_num(ncm->interface)); + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_wifi_ext_vdev_tx_msg); + +/* + * nss_wifi_ext_vdev_callback() + * Callback to handle the completion of NSS->HLOS messages. + */ +static void nss_wifi_ext_vdev_callback(void *app_data, struct nss_cmn_msg *ncm) +{ + nss_wifi_ext_vdev_msg_callback_t callback = (nss_wifi_ext_vdev_msg_callback_t)wifi_ext_vdev_pvt.cb; + void *data = wifi_ext_vdev_pvt.app_data; + + wifi_ext_vdev_pvt.response = NSS_TX_SUCCESS; + wifi_ext_vdev_pvt.cb = NULL; + wifi_ext_vdev_pvt.app_data = NULL; + + if (ncm->response != NSS_CMN_RESPONSE_ACK) { + nss_warning("WiFi extension vap Error response %d\n", ncm->response); + wifi_ext_vdev_pvt.response = NSS_TX_FAILURE; + } + + if (callback) { + callback(data, ncm); + } + complete(&wifi_ext_vdev_pvt.complete); +} + +/* + * nss_wifi_ext_vdev_tx_msg() + * Transmit a WiFi extended virtual interface to NSS firmware synchronously. + */ +nss_tx_status_t nss_wifi_ext_vdev_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_wifi_ext_vdev_msg *nwevm) +{ + nss_tx_status_t status; + int ret = 0; + + down(&wifi_ext_vdev_pvt.sem); + wifi_ext_vdev_pvt.cb = (void *)nwevm->cm.cb; + wifi_ext_vdev_pvt.app_data = (void *)nwevm->cm.app_data; + + nwevm->cm.cb = (nss_ptr_t)nss_wifi_ext_vdev_callback; + nwevm->cm.app_data = (nss_ptr_t)NULL; + + status = nss_wifi_ext_vdev_tx_msg(nss_ctx, nwevm); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: wifi_ext_vdev_tx_msg failed\n", nss_ctx); + up(&wifi_ext_vdev_pvt.sem); + return status; + } + + /* + * Wait for the acknowledgement + */ + ret = wait_for_completion_timeout(&wifi_ext_vdev_pvt.complete, msecs_to_jiffies(NSS_WIFI_EXT_VDEV_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: WiFi extended vap msg tx failed due to timeout\n", nss_ctx); + wifi_ext_vdev_pvt.response = NSS_TX_FAILURE; + } + + status = wifi_ext_vdev_pvt.response; + up(&wifi_ext_vdev_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_wifi_ext_vdev_tx_msg_sync); + +/* + * nss_wifi_ext_vdev_tx_buf + * Send data packet for vap processing + */ +nss_tx_status_t nss_wifi_ext_vdev_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *skb, uint32_t if_num) +{ + BUG_ON(!nss_wifi_ext_vdev_verify_if_num(if_num)); + + return nss_core_send_packet(nss_ctx, skb, if_num, H2N_BIT_FLAG_BUFFER_REUSABLE); +} +EXPORT_SYMBOL(nss_wifi_ext_vdev_tx_buf); + +/* + * nss_wifi_ext_vdev_set_next_hop() + * Set the WiFI extended vap next hop. + */ +nss_tx_status_t nss_wifi_ext_vdev_set_next_hop(struct nss_ctx_instance *ctx, int if_num, int next_hop) +{ + struct nss_wifi_ext_vdev_msg *nwevm = kzalloc(sizeof(struct nss_wifi_ext_vdev_msg), GFP_KERNEL); + struct nss_wifi_ext_vdev_set_next_hop_msg *nhm = NULL; + nss_tx_status_t status; + + if (!nwevm) { + nss_warning("%px: Unable to allocate next hop message", ctx); + return NSS_TX_FAILURE; + } + + nhm = &nwevm->msg.wnhm; + + nhm->if_num = next_hop; + nss_wifi_ext_vdev_msg_init(nwevm, if_num, NSS_WIFI_EXT_VDEV_SET_NEXT_HOP, + sizeof(struct nss_wifi_ext_vdev_set_next_hop_msg), NULL, NULL); + + status = nss_wifi_ext_vdev_tx_msg(ctx, nwevm); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: Unable to send next hop message", ctx); + } + + kfree(nwevm); + return status; +} +EXPORT_SYMBOL(nss_wifi_ext_vdev_set_next_hop); + +/* + * nss_get_wifi_ext_vdev_ext_context() + * Return the core ctx which the feature is on + */ +struct nss_ctx_instance *nss_wifi_ext_vdev_get_ctx(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id]; +} +EXPORT_SYMBOL(nss_wifi_ext_vdev_get_ctx); + +/* + * nss_wifi_ext_vdev_register_if() + */ +struct nss_ctx_instance *nss_wifi_ext_vdev_register_if(uint32_t if_num, + nss_wifi_ext_vdev_data_callback_t data_callback, + nss_wifi_ext_vdev_ext_data_callback_t ext_callback, + nss_wifi_ext_vdev_msg_callback_t event_callback, + struct net_device *netdev, + uint32_t features, void *app_data) +{ + struct nss_ctx_instance *nss_ctx = nss_wifi_ext_vdev_get_ctx(); + + BUG_ON(!nss_wifi_ext_vdev_verify_if_num(if_num)); + + nss_core_register_subsys_dp(nss_ctx, if_num, data_callback, ext_callback, app_data, netdev, features); + + nss_core_register_msg_handler(nss_ctx, if_num, event_callback); + + nss_core_register_handler(nss_ctx, if_num, nss_wifi_ext_vdev_handler, app_data); + + nss_wifi_ext_vdev_stats_register(if_num, netdev); + + return nss_ctx; +} +EXPORT_SYMBOL(nss_wifi_ext_vdev_register_if); + +/* + * nss_wifi_ext_vdev_unregister_if() + */ +bool nss_wifi_ext_vdev_unregister_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = nss_wifi_ext_vdev_get_ctx(); + struct net_device *netdev; + + BUG_ON(!nss_wifi_ext_vdev_verify_if_num(if_num)); + + nss_assert(nss_ctx); + + netdev = nss_cmn_get_interface_dev(nss_ctx, if_num); + if (!netdev) { + nss_warning("%px: Unable to find net device for the interface %d\n", nss_ctx, if_num); + return false; + } + nss_core_unregister_subsys_dp(nss_ctx, if_num); + + nss_core_unregister_msg_handler(nss_ctx, if_num); + + nss_core_unregister_handler(nss_ctx, if_num); + + nss_wifi_ext_vdev_stats_unregister(if_num, netdev); + return true; +} +EXPORT_SYMBOL(nss_wifi_ext_vdev_unregister_if); + +/* + * nss_wifi_ext_vdev_register_handler() + * Register debugfs handler received on base interface + */ +void nss_wifi_ext_vdev_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx = nss_wifi_ext_vdev_get_ctx(); + + nss_info("nss_wifi_ext_vdev_handler"); + sema_init(&wifi_ext_vdev_pvt.sem, 1); + init_completion(&wifi_ext_vdev_pvt.complete); + nss_core_register_handler(nss_ctx, NSS_WIFI_EXT_VDEV_INTERFACE, nss_wifi_ext_vdev_handler, NULL); + nss_wifi_ext_vdev_stats_dentry_create(); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_wifi_ext_vdev_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_ext_vdev_log.c new file mode 100644 index 000000000..b04c41027 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_ext_vdev_log.c @@ -0,0 +1,146 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_wifi_ext_vdev_log.c + * NSS WiFi extended VAP logger file. + */ + +#include "nss_core.h" + +/* + * nss_wifi_ext_vdev_log_message_types_str + * NSS WiFi extended VAP message strings + */ +static int8_t *nss_wifi_ext_vdev_log_message_types_str[NSS_WIFI_EXT_VDEV_MSG_MAX] __maybe_unused = { + "WiFi Extendev VAP configure", + "WiFi Extendev VAP configure wds", + "WiFi Extendev VAP configure next hop", + "WiFi Extendev VAP stats" +}; + +/* + * nss_wifi_ext_vdev_log_configure_msg() + * Log NSS WiFi extended vap configure message. + */ +static void nss_wifi_ext_vdev_log_configure_if_msg(struct nss_wifi_ext_vdev_msg *nwevm) +{ + struct nss_wifi_ext_vdev_configure_if_msg *cmsg __maybe_unused = &nwevm->msg.cmsg; + nss_trace("%px: WiFi extended VAP configure message \n" + "Mac address: %pM\n" + "Radion interface num: %d\n" + "Parent VAP interface num: %d\n", + cmsg, cmsg->mac_addr, cmsg->radio_ifnum, + cmsg->pvap_ifnum); + +} + +/* + * nss_wifi_ext_vdev_log_wds_msg() + * Log NSS WiFi extended vap wds message. + */ +static void nss_wifi_ext_vdev_log_wds_msg(struct nss_wifi_ext_vdev_msg *nwevm) +{ + struct nss_wifi_ext_vdev_wds_msg *wmsg __maybe_unused = &nwevm->msg.wmsg; + nss_trace("%px: NSS WiFi extended VAP wds message: \n" + "WDS sta ID: %d\n" + "WDS sta macaddr: %pM\n", + wmsg, wmsg->wds_peer_id, + wmsg->mac_addr); +} + +/* + * nss_wifi_ext_vdev_set_nxt_hop_msg() + * Set the next hop message. + */ +static void nss_wifi_ext_vdev_set_nxt_hop_msg(struct nss_wifi_ext_vdev_msg *nwevm) +{ + struct nss_wifi_ext_vdev_set_next_hop_msg *wnhm __maybe_unused = &nwevm->msg.wnhm; + nss_trace("%px: NSS WiFi extended vap set next hop message: \n" + "Next hop if num: %d\n", + wnhm, wnhm->if_num); + +} +/* + * nss_wifi_ext_vdev_log_verbose() + * Log message contents. + */ +static void nss_wifi_ext_vdev_log_verbose(struct nss_wifi_ext_vdev_msg *nwevm) +{ + switch (nwevm->cm.type) { + case NSS_WIFI_EXT_VDEV_MSG_CONFIGURE_IF: + nss_wifi_ext_vdev_log_configure_if_msg(nwevm); + break; + + case NSS_WIFI_EXT_VDEV_MSG_CONFIGURE_WDS : + nss_wifi_ext_vdev_log_wds_msg(nwevm); + break; + + case NSS_WIFI_EXT_VDEV_SET_NEXT_HOP: + nss_wifi_ext_vdev_set_nxt_hop_msg(nwevm); + break; + + case NSS_WIFI_EXT_VDEV_MSG_STATS_SYNC: + break; + + default: + nss_trace("%px: Invalid message type\n", nwevm); + break; + } +} + +/* + * nss_wifi_ext_vdev_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_wifi_ext_vdev_log_tx_msg(struct nss_wifi_ext_vdev_msg *nwevm) +{ + if (nwevm->cm.type >= NSS_WIFI_EXT_VDEV_MSG_MAX) { + nss_warning("%px: Invalid message type\n", nwevm); + return; + } + + nss_info("%px: type[%d]:%s\n", nwevm, nwevm->cm.type, nss_wifi_ext_vdev_log_message_types_str[nwevm->cm.type]); + nss_wifi_ext_vdev_log_verbose(nwevm); +} + +/* + * nss_wifi_ext_vdev_log_rx_msg() + * Log messages received from FW. + */ +void nss_wifi_ext_vdev_log_rx_msg(struct nss_wifi_ext_vdev_msg *nwevm) +{ + if (nwevm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", nwevm); + return; + } + + if (nwevm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (nwevm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", nwevm, nwevm->cm.type, + nss_wifi_ext_vdev_log_message_types_str[nwevm->cm.type], + nwevm->cm.response, nss_cmn_response_str[nwevm->cm.response]); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s\n", + nwevm, nwevm->cm.type, nss_wifi_ext_vdev_log_message_types_str[nwevm->cm.type], + nwevm->cm.response, nss_cmn_response_str[nwevm->cm.response]); + +verbose: + nss_wifi_ext_vdev_log_verbose(nwevm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_wifi_ext_vdev_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_ext_vdev_log.h new file mode 100644 index 000000000..a5c851055 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_ext_vdev_log.h @@ -0,0 +1,34 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_WIFI_EXT_VDEV_LOG_H +#define __NSS_WIFI_EXT_VDEV_LOG_H + +/* + * nss_wifi_ext_vdev_log_tx_msg + * Logs a wifi_ext_vdev message that is sent to the NSS firmware. + */ +void nss_wifi_ext_vdev_log_tx_msg(struct nss_wifi_ext_vdev_msg *nwevm); + +/* + * nss_wifi_ext_vdev_log_rx_msg + * Logs a wifi_ext_vdev message that is received from the NSS firmware. + */ +void nss_wifi_ext_vdev_log_rx_msg(struct nss_wifi_ext_vdev_msg *nwevm); + +#endif /* __NSS_WIFI_EXT_VDEV_LOG_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_wifi_ext_vdev_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_ext_vdev_stats.c new file mode 100644 index 000000000..493ca84b0 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_ext_vdev_stats.c @@ -0,0 +1,234 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_wifi_ext_vdev_stats.h" + +DEFINE_SPINLOCK(nss_wifi_ext_vdev_debug_lock); +struct nss_wifi_ext_vdev_debug nss_wifi_ext_vdev_debug_stats[NSS_WIFI_EXT_VDEV_MAX]; + +/* + * nss_wifi_ext_vdev_debug_str + * WiFi extended VAP statistics strings. + */ +struct nss_stats_info nss_wifi_ext_vdev_debug_str[NSS_WIFI_EXT_VDEV_STATS_MAX] = { + {"node_rx_pkts" , NSS_STATS_TYPE_COMMON}, + {"node_rx_bytes" , NSS_STATS_TYPE_COMMON}, + {"node_tx_pkts" , NSS_STATS_TYPE_COMMON}, + {"node_tx_bytes" , NSS_STATS_TYPE_COMMON}, + {"node_rx_dropped" , NSS_STATS_TYPE_DROP}, + {"mc_count" , NSS_STATS_TYPE_SPECIAL}, + {"uc_count" , NSS_STATS_TYPE_SPECIAL}, + {"nxt_hop_drop" , NSS_STATS_TYPE_DROP}, +}; + +/* + * WiFi extended vdev statistics APIs + */ + +/* + * nss_wifi_ext_vdev_stats_register() + * Register debug statistic for WiFi extended VAP. + */ +void nss_wifi_ext_vdev_stats_register(uint32_t if_num, struct net_device *netdev) +{ + int i; + + spin_lock_bh(&nss_wifi_ext_vdev_debug_lock); + for (i = 0; i < NSS_WIFI_EXT_VDEV_MAX; i++) { + if (!nss_wifi_ext_vdev_debug_stats[i].valid) { + nss_wifi_ext_vdev_debug_stats[i].valid = true; + nss_wifi_ext_vdev_debug_stats[i].if_num = if_num; + nss_wifi_ext_vdev_debug_stats[i].if_index = netdev->ifindex; + break; + } + } + + spin_unlock_bh(&nss_wifi_ext_vdev_debug_lock); +} + +/* + * nss_wifi_ext_vdev_stats_unregister() + * Register debug statistic for WiFi extended vap. + */ +void nss_wifi_ext_vdev_stats_unregister(uint32_t if_num, struct net_device *netdev) +{ + int i; + + spin_lock_bh(&nss_wifi_ext_vdev_debug_lock); + for (i = 0; i < NSS_WIFI_EXT_VDEV_MAX; i++) { + if (nss_wifi_ext_vdev_debug_stats[i].if_num == if_num) { + memset(&nss_wifi_ext_vdev_debug_stats[i], 0, + sizeof(struct nss_wifi_ext_vdev_debug)); + break; + } + } + spin_unlock_bh(&nss_wifi_ext_vdev_debug_lock); +} + +/* + * nss_wifi_ext_vdev_stats_sync() + * Sync function for WiFi extendev vap statistics. + */ +void nss_wifi_ext_vdev_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_wifi_ext_vdev_stats *stats_msg, + uint16_t if_num) +{ + int i; + struct nss_wifi_ext_vdev_debug *s = NULL; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + spin_lock_bh(&nss_wifi_ext_vdev_debug_lock); + for (i = 0; i < NSS_WIFI_EXT_VDEV_MAX; i++) { + if (nss_wifi_ext_vdev_debug_stats[i].if_num == if_num) { + s = &nss_wifi_ext_vdev_debug_stats[i]; + break; + } + } + + if (!s) { + spin_unlock_bh(&nss_wifi_ext_vdev_debug_lock); + nss_warning("%px: Interface:%u not found", nss_ctx, if_num); + return; + } + + s->stats[NSS_WIFI_EXT_VDEV_STATS_NODE_RX_PKTS ] += stats_msg->node_stats.rx_packets; + s->stats[NSS_WIFI_EXT_VDEV_STATS_NODE_RX_BYTES] += stats_msg->node_stats.rx_bytes; + s->stats[NSS_WIFI_EXT_VDEV_STATS_NODE_TX_PKTS] += stats_msg->node_stats.tx_packets; + s->stats[NSS_WIFI_EXT_VDEV_STATS_NODE_TX_BYTES] += stats_msg->node_stats.tx_bytes; + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + s->stats[NSS_WIFI_EXT_VDEV_STATS_NODE_TOTAL_DROPPED] += stats_msg->node_stats.rx_dropped[i]; + } + s->stats[NSS_WIFI_EXT_VDEV_STATS_MULTICAST_COUNT] += stats_msg->mc_count; + s->stats[NSS_WIFI_EXT_VDEV_STATS_UNICAST_COUNT] += stats_msg->node_stats.rx_packets - stats_msg->mc_count; + s->stats[NSS_WIFI_EXT_VDEV_STATS_NEXT_HOP_DROP_COUNT] += stats_msg->nxt_hop_drp; + spin_unlock_bh(&nss_wifi_ext_vdev_debug_lock); +} + +/* + * nss_wifi_ext_vdev_debug_get() + * Get WiFi extendev vap debug statitics. + */ +static void nss_wifi_ext_vdev_debug_get(struct nss_wifi_ext_vdev_debug *stats) +{ + int i; + + if (!stats) { + nss_warning("No memory to copy WiFi extended VAP stats"); + return; + } + + spin_lock_bh(&nss_wifi_ext_vdev_debug_lock); + for (i = 0; i < NSS_WIFI_EXT_VDEV_MAX; i++) { + if (nss_wifi_ext_vdev_debug_stats[i].valid) { + memcpy(stats, &nss_wifi_ext_vdev_debug_stats[i], + sizeof(struct nss_wifi_ext_vdev_debug)); + stats++; + } + } + spin_unlock_bh(&nss_wifi_ext_vdev_debug_lock); +} + +/* + * nss_wifi_ext_vdev_read() + * Read WiFi extended VAP statistics + */ +static ssize_t nss_wifi_ext_vdev_stats_read(struct file *fp, char __user *ubuf, + size_t sz, loff_t *ppos) +{ + uint32_t max_output_lines = 2 /* header and footer of the interface stats*/ + + (NSS_WIFI_EXT_VDEV_STATS_MAX * (NSS_WIFI_EXT_VDEV_MAX + 2)) /* Interface stats */ + + 2; + + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + size_t bytes_read = 0; + struct net_device *dev; + int id; + struct nss_wifi_ext_vdev_debug *wifi_ext_vdev_stats = NULL; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + wifi_ext_vdev_stats = kzalloc((sizeof(struct nss_wifi_ext_vdev_debug) * NSS_WIFI_EXT_VDEV_MAX), GFP_KERNEL); + if (unlikely(wifi_ext_vdev_stats == NULL)) { + nss_warning("Could not allocate memory for populating stats"); + kfree(lbuf); + return 0; + } + + /* + * Get all stats + */ + nss_wifi_ext_vdev_debug_get(wifi_ext_vdev_stats); + + /* + * WiFi extended vap stats. + */ + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "WiFi extended VAP stats", NSS_STATS_SINGLE_CORE); + + for (id = 0; id < NSS_WIFI_EXT_VDEV_MAX; id++) { + if (!wifi_ext_vdev_stats[id].valid) { + continue; + } + + dev = dev_get_by_index(&init_net, wifi_ext_vdev_stats[id].if_index); + if (likely(dev)) { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "%d. nss interface id=%d, netdevice=%s\n", + id, wifi_ext_vdev_stats[id].if_num, + dev->name); + dev_put(dev); + } else { + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, + "%d. nss interface id=%d\n", id, + wifi_ext_vdev_stats[id].if_num); + } + + size_wr += nss_stats_print("vdev", "debug", id + , nss_wifi_ext_vdev_debug_str + , wifi_ext_vdev_stats[id].stats + , NSS_WIFI_EXT_VDEV_STATS_MAX + , lbuf, size_wr, size_al); + + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n"); + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr); + + kfree(wifi_ext_vdev_stats); + kfree(lbuf); + return bytes_read; +} + +/* + * nss_wifi_ext_vdev_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(wifi_ext_vdev); + +/* + * nss_wifi_ext_vdev_dentry_create() + * Create wifi extension vap statistics debug entry. + */ +void nss_wifi_ext_vdev_stats_dentry_create(void) +{ + nss_stats_create_dentry("wifi_ext_vdev", &nss_wifi_ext_vdev_stats_ops); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_wifi_ext_vdev_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_ext_vdev_stats.h new file mode 100644 index 000000000..589e2c09e --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_ext_vdev_stats.h @@ -0,0 +1,60 @@ +/* + ****************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_WIFI_EXT_VDEV_STATS_H +#define __NSS_WIFI_EXT_VDEV_STATS_H + +/* + * WiFi extendev vap debug statistic counters. + */ +enum nss_wifi_ext_vdev_stats_types { + NSS_WIFI_EXT_VDEV_STATS_NODE_RX_PKTS, + NSS_WIFI_EXT_VDEV_STATS_NODE_RX_BYTES, + NSS_WIFI_EXT_VDEV_STATS_NODE_TX_PKTS, + NSS_WIFI_EXT_VDEV_STATS_NODE_TX_BYTES, + NSS_WIFI_EXT_VDEV_STATS_NODE_TOTAL_DROPPED, + NSS_WIFI_EXT_VDEV_STATS_MULTICAST_COUNT, + NSS_WIFI_EXT_VDEV_STATS_UNICAST_COUNT, + NSS_WIFI_EXT_VDEV_STATS_NEXT_HOP_DROP_COUNT, + NSS_WIFI_EXT_VDEV_STATS_MAX, +}; + +/* + * WiFi extendev vap debug statistics. + */ +struct nss_wifi_ext_vdev_debug { + uint64_t stats[NSS_WIFI_EXT_VDEV_STATS_MAX]; + int32_t if_index; /**< Netdevice's ifindex. */ + uint32_t if_num; /**< NSS interface number. */ + bool valid; /**< Is node valid ? */ +}; + +/* + * Data structures to store WiFi extended VAP debug stats. + */ +extern struct nss_wifi_ext_vdev_debug nss_wifi_ext_vdev_debug_stats[NSS_WIFI_EXT_VDEV_MAX]; + +/* + * WiFi extendev vap statistics APIs + */ +extern void nss_wifi_ext_vdev_stats_register(uint32_t if_num, struct net_device *netdev); +extern void nss_wifi_ext_vdev_stats_unregister(uint32_t if_num, struct net_device *netdev); +extern void nss_wifi_ext_vdev_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_wifi_ext_vdev_stats *stats_msg, uint16_t if_num); +extern void nss_wifi_ext_vdev_stats_dentry_create(void); + +#endif /* __NSS_WIFI_EXT_VDEV_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_wifi_if.c b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_if.c new file mode 100644 index 000000000..ba492802f --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_if.c @@ -0,0 +1,516 @@ +/* + ************************************************************************** + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_wifi_if.c + * NSS wifi/redirect handler APIs + */ + +#include "nss_tx_rx_common.h" +#include "nss_wifi_if_stats.h" +#include + +#define NSS_WIFI_IF_TX_TIMEOUT 3000 /* 3 Seconds */ +#define NSS_WIFI_IF_GET_INDEX(if_num) (if_num-NSS_DYNAMIC_IF_START) + +extern int nss_ctl_redirect; + +/* + * Data structure that holds the wifi interface context. + */ +struct nss_wifi_if_handle *wifi_handle[NSS_MAX_DYNAMIC_INTERFACES]; + +/* + * Spinlock to protect the global data structure wifi_handle. + */ +DEFINE_SPINLOCK(wifi_if_lock); + +/* + * nss_wifi_if_msg_handler() + * Handle NSS -> HLOS messages for wifi interface + */ +static void nss_wifi_if_msg_handler(struct nss_ctx_instance *nss_ctx, + struct nss_cmn_msg *ncm, + __attribute__((unused))void *app_data) +{ + struct nss_wifi_if_msg *nwim = (struct nss_wifi_if_msg *)ncm; + int32_t if_num; + + nss_wifi_if_msg_callback_t cb; + struct nss_wifi_if_handle *handle = NULL; + + /* + * Sanity check the message type + */ + if (ncm->type >= NSS_WIFI_IF_MAX_MSG_TYPES) { + nss_warning("%px: message type out of range: %d", + nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_wifi_if_msg)) { + nss_warning("%px: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + if (!NSS_IS_IF_TYPE(DYNAMIC, ncm->interface)) { + nss_warning("%px: response for another interface: %d", nss_ctx, ncm->interface); + return; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + if_num = NSS_WIFI_IF_GET_INDEX(ncm->interface); + + spin_lock_bh(&wifi_if_lock); + if (!wifi_handle[if_num]) { + spin_unlock_bh(&wifi_if_lock); + nss_warning("%px: wifi_if handle is NULL\n", nss_ctx); + return; + } + + handle = wifi_handle[if_num]; + spin_unlock_bh(&wifi_if_lock); + + switch (nwim->cm.type) { + case NSS_WIFI_IF_STATS_SYNC_MSG: + nss_wifi_if_stats_sync(handle, &nwim->msg.stats); + break; + } + + /* + * Update the callback and app_data for NOTIFY messages. + */ + if (nwim->cm.response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)handle->cb; + ncm->app_data = (nss_ptr_t)handle->app_data; + } + + /* + * Do we have a callback? + */ + if (!ncm->cb) { + nss_warning("cb is NULL\n"); + return; + } + + /* + * Callback + */ + cb = (nss_wifi_if_msg_callback_t)ncm->cb; + cb((void *)ncm->app_data, ncm); +} + +/* + * nss_wifi_if_register_handler() + * Register the message handler & initialize semaphore & completion for the * interface if_num + */ +static uint32_t nss_wifi_if_register_handler(struct nss_wifi_if_handle *handle) +{ + struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[nss_top_main.wlan_handler_id]; + uint32_t ret; + struct nss_wifi_if_pvt *nwip = NULL; + int32_t if_num = handle->if_num; + + ret = nss_core_register_handler(nss_ctx, if_num, nss_wifi_if_msg_handler, NULL); + + if (ret != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%d: Message handler failed to be registered for interface ret %d\n", if_num, ret); + return NSS_WIFI_IF_CORE_FAILURE; + } + + nwip = handle->pvt; + if (!nwip->sem_init_done) { + sema_init(&nwip->sem, 1); + init_completion(&nwip->complete); + nwip->sem_init_done = 1; + } + + nss_wifi_if_stats_dentry_create(); + return NSS_WIFI_IF_SUCCESS; +} + +/* + * nss_wifi_if_callback + * Callback to handle the completion of NSS->HLOS messages. + */ +static void nss_wifi_if_callback(void *app_data, struct nss_cmn_msg *ncm) +{ + struct nss_wifi_if_handle *handle = (struct nss_wifi_if_handle *)app_data; + struct nss_wifi_if_pvt *nwip = handle->pvt; + + if (ncm->response != NSS_CMN_RESPONSE_ACK) { + nss_warning("%px: wifi_if Error response %d\n", + handle->nss_ctx, ncm->response); + nwip->response = NSS_TX_FAILURE; + complete(&nwip->complete); + return; + } + + nwip->response = NSS_TX_SUCCESS; + complete(&nwip->complete); +} + +/* + * nss_wifi_if_tx_msg() + * Send a message from HLOS to NSS asynchronously. + */ +nss_tx_status_t nss_wifi_if_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_wifi_if_msg *nwim) +{ + struct nss_cmn_msg *ncm = &nwim->cm; + + if (ncm->type > NSS_WIFI_IF_MAX_MSG_TYPES) { + nss_warning("%px: message type out of range: %d\n", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, nwim, sizeof(*nwim), NSS_NBUF_PAYLOAD_SIZE); +} + +/* + * nss_wifi_if_tx_msg_sync + * Send a message from HLOS to NSS synchronously. + */ +static nss_tx_status_t nss_wifi_if_tx_msg_sync(struct nss_wifi_if_handle *handle, + struct nss_wifi_if_msg *nwim) +{ + nss_tx_status_t status; + int ret = 0; + struct nss_wifi_if_pvt *nwip = handle->pvt; + struct nss_ctx_instance *nss_ctx = handle->nss_ctx; + + down(&nwip->sem); + + status = nss_wifi_if_tx_msg(nss_ctx, nwim); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: nss_wifi_if_msg failed\n", nss_ctx); + up(&nwip->sem); + return status; + } + + ret = wait_for_completion_timeout(&nwip->complete, + msecs_to_jiffies(NSS_WIFI_IF_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: wifi_if tx failed due to timeout\n", nss_ctx); + nwip->response = NSS_TX_FAILURE; + } + + status = nwip->response; + up(&nwip->sem); + + return status; +} + +/* + * nss_wifi_if_handle_destroy() + * Destroy the wifi handle either due to request from WLAN or due to error. + */ +static int nss_wifi_if_handle_destroy(struct nss_wifi_if_handle *handle) +{ + int32_t if_num; + int32_t index; + struct nss_ctx_instance *nss_ctx; + nss_tx_status_t status; + + if (!handle) { + nss_warning("Destroy failed as wifi_if handle is NULL\n"); + return NSS_TX_FAILURE_BAD_PARAM; + } + + if_num = handle->if_num; + index = NSS_WIFI_IF_GET_INDEX(if_num); + nss_ctx = handle->nss_ctx; + + spin_lock_bh(&wifi_if_lock); + wifi_handle[index] = NULL; + spin_unlock_bh(&wifi_if_lock); + + status = nss_dynamic_interface_dealloc_node(if_num, NSS_DYNAMIC_INTERFACE_TYPE_WIFI); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: Dynamic interface destroy failed status %d\n", nss_ctx, status); + return status; + } + + kfree(handle->pvt); + kfree(handle); + + return status; +} + +/* + * nss_wifi_if_handle_init() + * Initialize wifi handle which holds the if_num and stats per interface. + */ +static struct nss_wifi_if_handle *nss_wifi_if_handle_create(struct nss_ctx_instance *nss_ctx, + int32_t *cmd_rsp) +{ + int32_t index; + int32_t if_num = 0; + struct nss_wifi_if_handle *handle; + + if_num = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_WIFI); + if (if_num < 0) { + nss_warning("%px:failure allocating wifi if\n", nss_ctx); + *cmd_rsp = NSS_WIFI_IF_DYNAMIC_IF_FAILURE; + return NULL; + } + + index = NSS_WIFI_IF_GET_INDEX(if_num); + + handle = (struct nss_wifi_if_handle *)kzalloc(sizeof(struct nss_wifi_if_handle), + GFP_KERNEL); + if (!handle) { + nss_warning("%px: handle memory alloc failed\n", nss_ctx); + *cmd_rsp = NSS_WIFI_IF_ALLOC_FAILURE; + goto error1; + } + + handle->nss_ctx = nss_ctx; + handle->if_num = if_num; + handle->pvt = (struct nss_wifi_if_pvt *)kzalloc(sizeof(struct nss_wifi_if_pvt), + GFP_KERNEL); + if (!handle->pvt) { + nss_warning("%px: failure allocating memory for nss_wifi_if_pvt\n", nss_ctx); + *cmd_rsp = NSS_WIFI_IF_ALLOC_FAILURE; + goto error2; + } + + handle->cb = NULL; + handle->app_data = NULL; + + spin_lock_bh(&wifi_if_lock); + wifi_handle[index] = handle; + spin_unlock_bh(&wifi_if_lock); + + *cmd_rsp = NSS_WIFI_IF_SUCCESS; + + return handle; + +error2: + kfree(handle); +error1: + nss_dynamic_interface_dealloc_node(if_num, NSS_DYNAMIC_INTERFACE_TYPE_WIFI); + return NULL; +} + +/* nss_wifi_if_msg_init() + * Initialize wifi specific message structure. + */ +static void nss_wifi_if_msg_init(struct nss_wifi_if_msg *nwim, + uint16_t if_num, + uint32_t type, + uint32_t len, + nss_wifi_if_msg_callback_t cb, + struct nss_wifi_if_handle *app_data) +{ + nss_cmn_msg_init(&nwim->cm, if_num, type, len, (void *)cb, (void *)app_data); +} + +/* + * nss_wifi_if_create_sync() + * Create a wifi interface and associate it with the netdev + */ +struct nss_wifi_if_handle *nss_wifi_if_create_sync(struct net_device *netdev) +{ + struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[nss_top_main.wlan_handler_id]; + struct nss_wifi_if_msg nwim; + struct nss_wifi_if_create_msg *nwcm; + uint32_t ret; + struct nss_wifi_if_handle *handle = NULL; + + if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) { + nss_warning("%px: Interface could not be created as core not ready\n", nss_ctx); + return NULL; + } + + handle = nss_wifi_if_handle_create(nss_ctx, &ret); + if (!handle) { + nss_warning("%px:wifi_if handle creation failed ret %d\n", nss_ctx, ret); + return NULL; + } + + /* Initializes the semaphore and also sets the msg handler for if_num */ + ret = nss_wifi_if_register_handler(handle); + if (ret != NSS_WIFI_IF_SUCCESS) { + nss_warning("%px: Registration handler failed reason: %d\n", nss_ctx, ret); + goto error; + } + + nss_wifi_if_msg_init(&nwim, handle->if_num, NSS_WIFI_IF_TX_CREATE_MSG, + sizeof(struct nss_wifi_if_create_msg), nss_wifi_if_callback, handle); + + nwcm = &nwim.msg.create; + nwcm->flags = 0; + memcpy(nwcm->mac_addr, netdev->dev_addr, ETH_ALEN); + + ret = nss_wifi_if_tx_msg_sync(handle, &nwim); + if (ret != NSS_TX_SUCCESS) { + nss_warning("%px: nss_wifi_if_tx_msg_sync failed %u\n", nss_ctx, ret); + goto error; + } + + nss_core_register_subsys_dp(nss_ctx, handle->if_num, NULL, NULL, NULL, netdev, 0); + + /* + * Hold a reference to the net_device + */ + dev_hold(netdev); + + /* + * The context returned is the interface # which is, essentially, the index into the if_ctx + * array that is holding the net_device pointer + */ + + return handle; + +error: + nss_wifi_if_handle_destroy(handle); + return NULL; +} +EXPORT_SYMBOL(nss_wifi_if_create_sync); + +/* + * nss_wifi_if_destroy_sync() + * Destroy the wifi interface associated with the interface number. + */ +nss_tx_status_t nss_wifi_if_destroy_sync(struct nss_wifi_if_handle *handle) +{ + nss_tx_status_t status; + struct net_device *dev; + int32_t if_num = handle->if_num; + struct nss_ctx_instance *nss_ctx = handle->nss_ctx; + + if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) { + nss_warning("%px: Interface could not be destroyed as core not ready\n", nss_ctx); + return NSS_TX_FAILURE_NOT_READY; + } + + spin_lock_bh(&nss_top_main.lock); + if (!nss_ctx->subsys_dp_register[if_num].ndev) { + spin_unlock_bh(&nss_top_main.lock); + nss_warning("%px: Unregister wifi interface %d: no context\n", nss_ctx, if_num); + return NSS_TX_FAILURE_BAD_PARAM; + } + + dev = nss_ctx->subsys_dp_register[if_num].ndev; + nss_core_unregister_subsys_dp(nss_ctx, if_num); + spin_unlock_bh(&nss_top_main.lock); + dev_put(dev); + + status = nss_wifi_if_handle_destroy(handle); + return status; +} +EXPORT_SYMBOL(nss_wifi_if_destroy_sync); + +/* + * nss_wifi_if_register() + * Register cb, netdev associated with the if_num to the nss data plane + * to receive data packets. + */ +void nss_wifi_if_register(struct nss_wifi_if_handle *handle, + nss_wifi_if_data_callback_t rx_callback, + struct net_device *netdev) +{ + struct nss_ctx_instance *nss_ctx; + int32_t if_num; + + if (!handle) { + nss_warning("nss_wifi_if_register handle is NULL\n"); + return; + } + + nss_ctx = handle->nss_ctx; + if_num = handle->if_num; + nss_assert(NSS_IS_IF_TYPE(DYNAMIC, if_num)); + + nss_core_register_subsys_dp(nss_ctx, if_num, rx_callback, NULL, NULL, netdev, netdev->features); +} +EXPORT_SYMBOL(nss_wifi_if_register); + +/* + * nss_wifi_if_unregister() + * Unregister the cb, netdev associated with the if_num. + */ +void nss_wifi_if_unregister(struct nss_wifi_if_handle *handle) +{ + struct nss_ctx_instance *nss_ctx; + int32_t if_num; + + if (!handle) { + nss_warning("nss_wifi_if_unregister handle is NULL\n"); + return; + } + + nss_ctx = handle->nss_ctx; + if_num = handle->if_num; + + nss_core_unregister_subsys_dp(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_wifi_if_unregister); + +/* + * nss_wifi_if_tx_buf() + * HLOS interface has received a packet which we redirect to the NSS. + */ +nss_tx_status_t nss_wifi_if_tx_buf(struct nss_wifi_if_handle *handle, + struct sk_buff *skb) +{ + struct nss_ctx_instance *nss_ctx; + int32_t if_num; + int cpu = 0; + + if (!handle) { + nss_warning("nss_wifi_if_tx_buf handle is NULL\n"); + return NSS_TX_FAILURE; + } + + nss_ctx = handle->nss_ctx; + if_num = handle->if_num; + + /* + * redirect should be turned on in /proc/ + */ + if (unlikely(nss_ctl_redirect == 0)) { + return NSS_TX_FAILURE_NOT_ENABLED; + } + + if (unlikely(skb->vlan_tci)) { + return NSS_TX_FAILURE_NOT_SUPPORTED; + } + + nss_assert(NSS_IS_IF_TYPE(DYNAMIC, if_num)); + + /* + * Sanity check the SKB to ensure that it's suitable for us + */ + if (unlikely(skb->len <= ETH_HLEN)) { + nss_warning("%px: Rx packet: %px too short", nss_ctx, skb); + return NSS_TX_FAILURE_TOO_SHORT; + } + + /* + * set skb queue mapping + */ + cpu = get_cpu(); + put_cpu(); + skb_set_queue_mapping(skb, cpu); + + return nss_core_send_packet(nss_ctx, skb, if_num, H2N_BIT_FLAG_VIRTUAL_BUFFER); +} +EXPORT_SYMBOL(nss_wifi_if_tx_buf); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_wifi_if_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_if_stats.c new file mode 100644 index 000000000..19c1c3653 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_if_stats.c @@ -0,0 +1,210 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_wifi_if.h" + +/* + * Data structure that holds the wifi interface context. + */ +extern struct nss_wifi_if_handle *wifi_handle[]; + +/* + * Spinlock to protect the global data structure wifi_handle. + */ +extern spinlock_t wifi_if_lock; + +/* + * nss_wifi_if_stats_get() + * Get the stats from wifi handle to buffer(line) for if_num. + */ +static int32_t nss_wifi_if_stats_get(int32_t if_num, int i, char *line) +{ + int32_t bytes = 0; + struct nss_wifi_if_stats *stats; + int32_t ifnum; + uint32_t len = 80; + struct nss_wifi_if_handle *handle = NULL; + + ifnum = if_num - NSS_DYNAMIC_IF_START; + + spin_lock_bh(&wifi_if_lock); + if (!wifi_handle[ifnum]) { + spin_unlock_bh(&wifi_if_lock); + goto end; + } + + handle = wifi_handle[ifnum]; + spin_unlock_bh(&wifi_if_lock); + stats = &handle->stats; + + switch (i) { + case 0: + bytes = scnprintf(line, len, "rx_packets=%d\n", + stats->node_stats.rx_packets); + break; + + case 1: + bytes = scnprintf(line, len, "rx_bytes=%d\n", + stats->node_stats.rx_bytes); + break; + + case 2: + bytes = scnprintf(line, len, "rx_dropped=%d\n", + nss_cmn_rx_dropped_sum(&stats->node_stats)); + break; + + case 3: + bytes = scnprintf(line, len, "tx_packets=%d\n", + stats->node_stats.tx_packets); + break; + + case 4: + bytes = scnprintf(line, len, "tx_bytes=%d\n", + stats->node_stats.tx_bytes); + break; + + case 5: + bytes = scnprintf(line, len, "tx_enqueue_failed=%d\n", + stats->tx_enqueue_failed); + break; + + case 6: + bytes = scnprintf(line, len, "shaper_enqueue_failed=%d\n", + stats->shaper_enqueue_failed); + break; + } + +end: + return bytes; +} + +/* + * nss_wifi_if_stats_read() + * Read wifi_if statistics + */ +static ssize_t nss_wifi_if_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + struct nss_stats_data *data = fp->private_data; + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id]; + int32_t if_num = NSS_DYNAMIC_IF_START; + int32_t max_if_num = if_num + NSS_MAX_DYNAMIC_INTERFACES; + size_t bytes = 0; + ssize_t bytes_read = 0; + char line[80]; + int start, end; + + if (data) { + if_num = data->if_num; + } + + if (if_num > max_if_num) { + return 0; + } + + for (; if_num < max_if_num; if_num++) { + if (nss_dynamic_interface_get_type(nss_ctx, if_num) != NSS_DYNAMIC_INTERFACE_TYPE_WIFI) + continue; + + bytes = scnprintf(line, sizeof(line), "if_num %d stats start:\n\n", if_num); + if ((bytes_read + bytes) > sz) + break; + + if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) { + bytes_read = -EFAULT; + goto end; + } + + bytes_read += bytes; + + start = 0; + end = 7; + while (bytes_read < sz && start < end) { + bytes = nss_wifi_if_stats_get(if_num, start, line); + if (!bytes) + break; + + if ((bytes_read + bytes) > sz) + break; + + if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) { + bytes_read = -EFAULT; + goto end; + } + + bytes_read += bytes; + start++; + } + + bytes = scnprintf(line, sizeof(line), "if_num %d stats end:\n\n", if_num); + if (bytes_read > (sz - bytes)) + break; + + if (copy_to_user(ubuf + bytes_read, line, bytes) != 0) { + bytes_read = -EFAULT; + goto end; + } + + bytes_read += bytes; + } + + if (bytes_read > 0) { + *ppos = bytes_read; + } + + if (data) { + data->if_num = if_num; + } + +end: + return bytes_read; +} + +/* + * nss_wifi_if_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(wifi_if) + +/* + * nss_wifi_if_stats_dentry_create() + * Create wifi_if statistics debug entry. + */ +void nss_wifi_if_stats_dentry_create(void) +{ + nss_stats_create_dentry("wifi_if", &nss_wifi_if_stats_ops); +} + +/* + * nss_wifi_if_stats_sync() + * Sync stats from the NSS FW + */ +void nss_wifi_if_stats_sync(struct nss_wifi_if_handle *handle, + struct nss_wifi_if_stats *nwis) +{ + struct nss_wifi_if_stats *stats = &handle->stats; + int i; + + stats->node_stats.rx_packets += nwis->node_stats.rx_packets; + stats->node_stats.rx_bytes += nwis->node_stats.rx_bytes; + + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + stats->node_stats.rx_dropped[i] += nwis->node_stats.rx_dropped[i]; + } + stats->node_stats.tx_packets += nwis->node_stats.tx_packets; + stats->node_stats.tx_bytes += nwis->node_stats.tx_bytes; + stats->tx_enqueue_failed += nwis->tx_enqueue_failed; + stats->shaper_enqueue_failed += nwis->shaper_enqueue_failed; +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_wifi_if_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_if_stats.h new file mode 100644 index 000000000..ffc1f83ea --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_if_stats.h @@ -0,0 +1,26 @@ +/* + ****************************************************************************** + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_WIFI_IF_STATS_H +#define __NSS_WIFI_IF_STATS_H + +/* + * wifi interface statistics APIs + */ +extern void nss_wifi_if_stats_sync(struct nss_wifi_if_handle *handle, struct nss_wifi_if_stats *nwis); +extern void nss_wifi_if_stats_dentry_create(void); + +#endif /* __NSS_WIFI_IF_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_wifi_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_log.c new file mode 100644 index 000000000..4d6b4c52d --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_log.c @@ -0,0 +1,806 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_wifi_log.c + * NSS WIFI logger file. + */ + +#include "nss_core.h" + +/* + * nss_wifi_log_message_types_str + * WIFI message strings + */ +static int8_t *nss_wifi_log_message_types_str[NSS_WIFI_MAX_MSG] __maybe_unused = { + "WIFI INIT MSG", + "WIFI POST RECV MSG", + "WIFI HTT INIT MSG", + "WIFI TX INIT MSG", + "WIFI RAW SEND MSG", + "WIFI MGMT SEND MSG", + "WIFI WDS PEER ADD MSG", + "WIFI WDS PEER DEL MSG", + "WIFI STOP MSG", + "WIFI RESET MSG", + "WIFI STATS MSG", + "WIFI PEER FREELIST APPEND MSG", + "WIFI RX REORDER ARRAY FREELIST APPEND MSG", + "WIFI SEND PEER MEMORY REQUEST MSG", + "WIFI SEND RRA MEMORY REQUEST MSG", + "WIFI FW STATS MSG", + "WIFI MONITOR FILTER SET MSG", + "WIFI PEER BS STATE MSG", + "WIFI MSDU TTL SET MSG", + "WIFI RX VOW EXTSTATS SET MSG", + "WIFI PKTLOG CFG MSG", + "WIFI ENABLE PERPKT TXSTATS MSG", + "WIFI IGMP MLD TOS OVERRIDE MSG", + "WIFI OL STATS CFG MSG", + "WIFI OL STATS MSG", + "WIFI TX QUEUE CFG MSG", + "WIFI TX MIN THRESHOLD CFG MSG", + "WIFI DBDC PROCESS ENABLE MSG", + "WIFI PRIMARY RADIO SET MSG", + "WIFI FORCE CLIENT MCAST TRAFFIC SET MSG", + "WIFI STORE OTHER PDEV STAVAP MSG", + "WIFI STA KICKOUT MSG", + "WIFI WNM PEER RX ACTIVITY MSG", + "WIFI PEER STATS MSG", + "WIFI WDS VENDOR MSG", + "WIFI TX CAPTURE SET MSG", + "WIFI ALWAYS PRIMARY SET MSG", + "WIFI FLUSH HTT CMD MSG", + "WIFI CMD MSG", + "WIFI ENABLE OL STATSV2 MSG", + "WIFI OL PEER TIME MSG", +}; + +/* + * nss_wifi_log_error_response_types_str + * Strings for error types for WIFI messages + */ +static int8_t *nss_wifi_log_error_response_types_str[NSS_WIFI_EMSG_MAX] __maybe_unused = { + "WIFI NO ERROR", + "WIFI UNKNOWN MSG", + "WIFI MGMT DLEN", + "WIFI MGMT SEND", + "WIFI CE INIT FAIL", + "WIFI PDEV INIT FAIL", + "WIFI HTT INIT FAIL", + "WIFI PEER ADD", + "WIFI WIFI START FAIL", + "WIFI STATE NOT RESET", + "WIFI STATE NOT INIT DONE", + "WIFI STATE NULL CE HANDLE", + "WIFI STATE NOT CE READY", + "WIFI STATE NOT HTT READY", + "WIFI FW STATS DLEN", + "WIFI FW STATS SEND", + "WIFI STATE TX INIT FAILED", + "WIFI IGMP MLD TOS OVERRIDE CFG", + "WIFI PDEV INVALID", + "WIFI OTHER PDEV STAVAP INVALID", + "WIFI HTT SEND FAIL", + "WIFI CE RING INIT", + "WIFI NOTIFY CB", + "WIFI PEERID INVALID", + "WIFI PEER INVALID", + "WIFI UNKNOWN CMD" +}; + +/* + * nss_wifi_log_init_msg() + * Log NSS WIFI Init message. + */ +static void nss_wifi_log_init_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_init_msg *nwim __maybe_unused = &ncm->msg.initmsg; + + nss_trace("%px: NSS WIFI Init Message:\n" + "WIFI Radio ID: %d\n" + "WIFI PCI Memory Address: %x\n" + "WIFI Target Type: %d\n" + "WIFI MU MIMO Enhancement Enable Flag: %d\n" + "WIFI Transmit Copy Engine Source Ring:\n" + "\tNumber of Entries: %d\n" + "\tNumber of Entries Mask: %x\n" + "\tInitial Software Index: %d\n" + "\tInitial Write Index: %d\n" + "\tInitial Hardware Index: %d\n" + "\tPhysical Address: %x\n" + "\tVirtual Address: %x\n" + "WIFI Transmit Copy Engine Dest Ring:\n" + "\tNumber of Entries: %d\n" + "\tNumber of Entries Mask: %x\n" + "\tInitial Software Index: %d\n" + "\tInitial Write Index: %d\n" + "\tInitial Hardware Index: %d\n" + "\tPhysical Address: %x\n" + "\tVirtual Address: %x\n" + "WIFI Transmit Control Address of PCIe Bar: %x\n" + "WIFI Receive Copy Engine Source Ring:\n" + "\tNumber of Entries: %d\n" + "\tNumber of Entries Mask: %x\n" + "\tInitial Software Index: %d\n" + "\tInitial Write Index: %d\n" + "\tInitial Hardware Index: %d\n" + "\tPhysical Address: %x\n" + "\tVirtual Address: %x\n" + "WIFI Receive Copy Engine Dest Ring:\n" + "\tNumber of Entries: %d\n" + "\tNumber of Entries Mask: %x\n" + "\tInitial Software Index: %d\n" + "\tInitial Write Index: %d\n" + "\tInitial Hardware Index: %d\n" + "\tPhysical Address: %x\n" + "\tVirtual Address: %x\n" + "WIFI Receive Control Address of PCIe Bar: %x\n" + "WIFI Bypass Network Process: %d", + nwim, nwim->radio_id, + nwim->pci_mem, nwim->target_type, + nwim->mu_mimo_enhancement_en, nwim->ce_tx_state.src_ring.nentries, + nwim->ce_tx_state.src_ring.nentries_mask, nwim->ce_tx_state.src_ring.sw_index, + nwim->ce_tx_state.src_ring.write_index, nwim->ce_tx_state.src_ring.hw_index, + nwim->ce_tx_state.src_ring.base_addr_CE_space, nwim->ce_tx_state.src_ring.base_addr_owner_space, + nwim->ce_tx_state.dest_ring.nentries, nwim->ce_tx_state.dest_ring.nentries_mask, + nwim->ce_tx_state.dest_ring.sw_index, nwim->ce_tx_state.dest_ring.write_index, + nwim->ce_tx_state.dest_ring.hw_index, nwim->ce_tx_state.dest_ring.base_addr_CE_space, + nwim->ce_tx_state.dest_ring.base_addr_owner_space, nwim->ce_tx_state.ctrl_addr, + nwim->ce_rx_state.src_ring.nentries, nwim->ce_rx_state.src_ring.nentries_mask, + nwim->ce_rx_state.src_ring.sw_index, nwim->ce_rx_state.src_ring.write_index, + nwim->ce_rx_state.src_ring.hw_index, nwim->ce_rx_state.src_ring.base_addr_CE_space, + nwim->ce_rx_state.src_ring.base_addr_owner_space, nwim->ce_rx_state.dest_ring.nentries, + nwim->ce_rx_state.dest_ring.nentries_mask, nwim->ce_rx_state.dest_ring.sw_index, + nwim->ce_rx_state.dest_ring.write_index, nwim->ce_rx_state.dest_ring.hw_index, + nwim->ce_rx_state.dest_ring.base_addr_CE_space, nwim->ce_rx_state.dest_ring.base_addr_owner_space, + nwim->ce_rx_state.ctrl_addr, nwim->bypass_nw_process); +} + +/* + * nss_wifi_log_stop_msg() + * Log NSS WIFI Init message. + */ +static void nss_wifi_log_stop_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_stop_msg *nwsm __maybe_unused = &ncm->msg.stopmsg; + nss_trace("%px: NSS WIFI Init Message:\n" + "WIFI Radio ID: %d\n", + nwsm, nwsm->radio_id); +} + +/* + * nss_wifi_log_reset_msg() + * Log NSS WIFI Init message. + */ +static void nss_wifi_log_reset_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_reset_msg *nwrm __maybe_unused = &ncm->msg.resetmsg; + nss_trace("%px: NSS WIFI Init Message:\n" + "WIFI Radio ID: %d\n", + nwrm, nwrm->radio_id); +} + +/* + * nss_wifi_log_htt_init_msg() + * Log NSS WIFI HTT Init message. + */ +static void nss_wifi_log_htt_init_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_htt_init_msg *nwim __maybe_unused = &ncm->msg.httinitmsg; + nss_trace("%px: NSS WIFI HTT Init Message:\n" + "WIFI Radio ID: %d\n" + "WIFI Ring Size: %d\n" + "WIFI Fill Level: %d\n" + "WIFI MAC Hardware Ring Phy Address: %x\n" + "WIFI MAC Hardware Ring Virtual Address: %x\n" + "WIFI Hardware Ring Index Phy Address: %x\n" + "WIFI Hardware Ring Index Virtual Address: %x\n", + nwim, nwim->radio_id, + nwim->ringsize, nwim->fill_level, + nwim->paddrs_ringptr, nwim->paddrs_ringpaddr, + nwim->alloc_idx_paddr, nwim->alloc_idx_vaddr); +} + +/* + * nss_wifi_log_tx_init_msg() + * Log NSS TX HTT Init message. + */ +static void nss_wifi_log_tx_init_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_tx_init_msg *nwim __maybe_unused = &ncm->msg.pdevtxinitmsg; + nss_trace("%px: NSS WIFI HTT Init Message:\n" + "WIFI Radio ID: %d\n" + "WIFI Number of Descriptor Pools Allocated: %d\n" + "WIFI TX Descriptor Array: %x\n" + "WIFI MAC extenstion descriptor Address: %x\n" + "WIFI WLAN MAC extenstion descriptor size: %d\n" + "WIFI HTT Tx descriptor memory start virtual address: %x\n" + "WIFI HTT Tx descriptor memory base virtual address: %x\n" + "WIFI HTT Tx descriptor memory offset: %x\n" + "WIFI Firmware shared TID map: %x\n", + nwim, nwim->radio_id, + nwim->desc_pool_size, nwim->tx_desc_array, + nwim->wlanextdesc_addr, nwim->wlanextdesc_size, + nwim->htt_tx_desc_base_vaddr, nwim->htt_tx_desc_base_paddr, + nwim->htt_tx_desc_offset, nwim->pmap_addr); +} + +/* + * nss_wifi_log_rawsend_msg() + * Log NSS WIFI RAW Send message. + */ +static void nss_wifi_log_rawsend_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_rawsend_msg *nwrm __maybe_unused = &ncm->msg.rawmsg; + nss_trace("%px: NSS WIFI RAW Send Message:\n" + "WIFI Radio ID: %d\n" + "WIFI Size of Raw Data: %d\n" + "WIFI Raw Data: %px", + nwrm, nwrm->radio_id, + nwrm->len, nwrm->array); +} + +/* + * nss_wifi_log_mgmtsend_msg() + * Log NSS WIFI Management Send message. + */ +static void nss_wifi_log_mgmtsend_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_mgmtsend_msg *nwmm __maybe_unused = &ncm->msg.mgmtmsg; + nss_trace("%px: NSS WIFI Management Send Message:\n" + "WIFI Descriptor ID: %d\n" + "WIFI Size of Management Data: %d\n" + "WIFI Management Data: %px", + nwmm, nwmm->desc_id, + nwmm->len, nwmm->array); +} + +/* + * nss_wifi_log_wds_peer_msg() + * Log NSS WIFI WDS Peer message. + */ +static void nss_wifi_log_wds_peer_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_wds_peer_msg *nwmm __maybe_unused = &ncm->msg.pdevwdspeermsg; + nss_trace("%px: NSS WIFI WDS Peer Message:\n" + "WIFI Dest MAC: %pM\n" + "WIFI Peer MAC: %pM\n", + nwmm, nwmm->dest_mac, + nwmm->peer_mac); +} + +/* + * nss_wifi_log_peer_freelist_append_msg() + * Log NSS WIFI Create/Append Freelist message + */ +static void nss_wifi_log_peer_freelist_append_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_peer_freelist_append_msg *nwpm __maybe_unused = &ncm->msg.peer_freelist_append; + nss_trace("%px: NSS WIFI Create/Append Freelist Message:\n" + "WIFI Starting Address of Peer Freelist Pool: %x\n" + "WIFI Length of freelist pool: %d\n" + "WIFI Number of Peers supported in freelist pool: %d\n", + nwpm, nwpm->addr, + nwpm->length, nwpm->num_peers); +} + +/* + * nss_wifi_log_rx_reorder_array_freelist_append_msg() + * Log NSS WIFI RX Reorder Array Freelist message + */ +static void nss_wifi_log_rx_reorder_array_freelist_append_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_rx_reorder_array_freelist_append_msg *nwpm __maybe_unused = &ncm->msg.rx_reorder_array_freelist_append; + nss_trace("%px: NSS WIFI RX Reorder Array Freelist Message:\n" + "WIFI Starting Address of TIDQ Freelist Pool: %x\n" + "WIFI Length of TIDQ freelist pool: %d\n" + "WIFI Number of Rx reorder array entries supported in freelist pool: %d\n", + nwpm, nwpm->addr, + nwpm->length, nwpm->num_rra); +} + +/* + * nss_wifi_log_set_filter_msg() + * Log NSS WIFI Set Filter message + */ +static void nss_wifi_log_set_filter_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_monitor_set_filter_msg *nwfm __maybe_unused = &ncm->msg.monitor_filter_msg; + nss_trace("%px: NSS WIFI Set Filter Message:\n" + "WIFI Filter Type: %dn", + nwfm, nwfm->filter_type); +} + +/* + * nss_wifi_log_peer_activity_msg() + * Log NSS WIFI Get Active Peer for Radio message + */ +static void nss_wifi_log_peer_activity_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_bs_peer_activity *nwpm __maybe_unused = &ncm->msg.peer_activity; + nss_trace("%px: NSS WIFI Get Active Peer Message:\n" + "WIFI Number of Entries in Peer ID Array: %d\n" + "WIFI PEER ID: %d\n", + nwpm, nwpm->nentries, + nwpm->peer_id[0]); +} + +/* + * nss_wifi_rx_vow_extstats_set_msg() + * Log NSS WIFI VoW Extended Statistics Set Message. + */ +static void nss_wifi_log_rx_vow_extstats_set_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_rx_vow_extstats_set_msg *nwpm __maybe_unused = &ncm->msg.vow_extstats_msg; + nss_trace("%px: NSS WIFI VoW Extended Statistics Set Message:\n" + "WIFI VoW Extended Statistics Enable:: %d\n", + nwpm, nwpm->vow_extstats_en); +} + +/* + * nss_wifi_log_pktlog_cfg_msg() + * Log NSS WIFI Packet Log Configuration Message. + */ +static void nss_wifi_log_pktlog_cfg_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_pktlog_cfg_msg *nwpm __maybe_unused = &ncm->msg.pcm_msg; + nss_trace("%px: NSS WIFI Packet Log Configuration Message:\n" + "WIFI Packet Log Enable: %d\n" + "WIFI PAcket Log buffer Size: %d\n" + "WIFI Size of packet log header: %d\n" + "WIFI Offset for the MSDU ID: %d\n", + nwpm, nwpm->enable, + nwpm->bufsize, nwpm->hdrsize, + nwpm->msdu_id_offset); +} + +/* + * nss_wifi_log_enable_perpkt_txstats_msg() + * Log NSS WIFI Enable TX Stats Message. + */ +static void nss_wifi_log_enable_perpkt_txstats_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_enable_perpkt_txstats_msg *nwpm __maybe_unused = &ncm->msg.ept_msg; + nss_trace("%px: NSS WIFI Enable TX Stats Message:\n" + "WIFI TX Stats Enable Flag: %d\n", + nwpm, nwpm->perpkt_txstats_flag); +} + +/* + * nss_wifi_log_override_tos_msg() + * Log NSS WIFI Override TOS Message. + */ +static void nss_wifi_log_override_tos_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_igmp_mld_override_tos_msg *nwpm __maybe_unused = &ncm->msg.wigmpmldtm_msg; + nss_trace("%px: NSS WIFI Override TOS Message:\n" + "WIFI enable TID override Flag: %d\n" + "WIFI Value of TID to be overriden: %d\n", + nwpm, nwpm->igmp_mld_ovride_tid_en, + nwpm->igmp_mld_ovride_tid_val); +} + +/* + * nss_wifi_log_ol_stats_cfg_msg() + * Log NSS WIFI Offload Stats Config Message. + */ +static void nss_wifi_log_ol_stats_cfg_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_ol_stats_cfg_msg *nwpm __maybe_unused = &ncm->msg.scm_msg; + nss_trace("%px: NSS WIFI Enable/Disable Offload Stats Message:\n" + "WIFI enable/disable offload stats config: %d\n", + nwpm, nwpm->stats_cfg); +} + +/* + * nss_wifi_log_tx_queue_cfg_msg() + * Log NSS WIFI TX Queue Configuration message. + */ +static void nss_wifi_log_tx_queue_cfg_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_tx_queue_cfg_msg *nwpm __maybe_unused = &ncm->msg.wtxqcm; + nss_trace("%px: NSS WIFI TX Queue Config Message:\n" + "WIFI TX Queue Size: %d\n" + "WIFI TX Queue Range: %d\n", + nwpm, nwpm->size, nwpm->range); +} + +/* + * nss_wifi_log_tx_min_threshold_cfg() + * Log NSS WIFI TX Queue Min Threshold Configuration message. + */ +static void nss_wifi_log_tx_min_threshold_cfg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_tx_min_threshold_cfg_msg *nwpm __maybe_unused = &ncm->msg.wtx_min_threshold_cm; + nss_trace("%px: NSS WIFI TX Queue Min Threshold Config Message:\n" + "WIFI TX Queue Min Threshold Value: %d\n", + nwpm, nwpm->min_threshold); +} + +/* + * nss_wifi_log_dbdc_process_enable_msg() + * Log NSS WIFI DBDC repeater process configuration. + */ +static void nss_wifi_log_dbdc_process_enable_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_dbdc_process_enable_msg *nwpm __maybe_unused = &ncm->msg.dbdcpe_msg; + nss_trace("%px: NSS WIFI DBDC repeater process configuration:\n" + "WIFI DBDC Process Enable Flag: %d\n", + nwpm, nwpm->dbdc_process_enable); +} + +/* + * nss_wifi_log_primary_radio_set_msg() + * Log NSS WIFI Primary Radio Set message. + */ +static void nss_wifi_log_primary_radio_set_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_primary_radio_set_msg *nwpm __maybe_unused = &ncm->msg.wprs_msg; + nss_trace("%px: NSS WIFI Primary Radio Set Message:\n" + "WIFI Current Radio as Primary Radio Enable/Disable Flag: %d\n", + nwpm, nwpm->flag); +} + +/* + * nss_wifi_log_force_client_mcast_traffic_set_msg() + * Log NSS WIFI Force Multicat Traffic for Radio + */ +static void nss_wifi_log_force_client_mcast_traffic_set_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_force_client_mcast_traffic_set_msg *nwpm __maybe_unused = &ncm->msg.wfcmts_msg; + nss_trace("%px: NSS WIFI Force Multicat Traffic for Radio Message:\n" + "WIFI Radio Multicast Traffic Flag: %d\n", + nwpm, nwpm->flag); +} + +/* + * nss_wifi_log_store_other_pdev_stavap_msg() + * Log NSS WIFI Store Other Radio Station VAP Message. + */ +static void nss_wifi_log_store_other_pdev_stavap_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_store_other_pdev_stavap_msg *nwpm __maybe_unused = &ncm->msg.wsops_msg; + nss_trace("%px: NSS WIFI Store Other Radio Station VAP Message:\n" + "WIFI Station VAP Interface Number: %d\n", + nwpm, nwpm->stavap_ifnum); +} + +/* + * nss_wifi_log_sta_kickout_msg() + * Log NSS WIFI Station Kickout Message. + */ +static void nss_wifi_log_sta_kickout_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_sta_kickout_msg *nwpm __maybe_unused = &ncm->msg.sta_kickout_msg; + nss_trace("%px: NSS WIFI Station Kickout Message:\n" + "WIFI PEER ID: %d\n", + nwpm, nwpm->peer_id); +} + +/* + * nss_wifi_log_wnm_peer_rx_activity() + * Log NSS WIFI RX Active State Information of Peer. + */ +static void nss_wifi_log_wnm_peer_rx_activity(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_wnm_peer_rx_activity_msg *nwpm __maybe_unused = &ncm->msg.wprm; + nss_trace("%px: NSS WIFI RX Active State Information of Peer:\n" + "WIFI Peer ID: %px\n" + "WIFI Number of Entries: %d\n", + nwpm, nwpm->peer_id, nwpm->nentries); +} + +/* + * nss_wifi_log_wds_extn_peer_cfg_msg() + * Log NSS WIFI WDS Extension Enabled Configuraion Message. + */ +static void nss_wifi_log_wds_extn_peer_cfg_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_wds_extn_peer_cfg_msg *nwpm __maybe_unused = &ncm->msg.wpeercfg; + nss_trace("%px: NSS WIFI Extension Enabled Configuraion Message:\n" + "WIFI Peer MAC Address: %pM\n" + "WIFI WDS Flags: %d\n" + "WIFI Peer ID: %d\n", + nwpm, nwpm->mac_addr, nwpm->wds_flags, + nwpm->peer_id); +} + +/* + * nss_wifi_log_tx_capture_msg() + * Log NSS WIFI Enable TX Capture Message. + */ +static void nss_wifi_log_tx_capture_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_tx_capture_msg *nwpm __maybe_unused = &ncm->msg.tx_capture_msg; + nss_trace("%px: NSS WIFI Enable TX Capture Message:\n" + "WIFI TX Capture Enable Flag: %d\n", + nwpm, nwpm->tx_capture_enable); +} + +/* + * nss_wifi_log_always_primary_set_msg() + * Log NSS WIFI Always Set Current Radio Primary Message. + */ +static void nss_wifi_log_always_primary_set_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_always_primary_set_msg *nwpm __maybe_unused = &ncm->msg.waps_msg; + nss_trace("%px: NSS WIFI Always Set Current Radio Primary Message:\n" + "WIFI Always Set Flag: %d\n", + nwpm, nwpm->flag); +} + +/* + * nss_wifi_log_cmd_msg() + * Log NSS WIFI PDEV Command Message. + */ +static void nss_wifi_log_cmd_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_cmd_msg *nwpm __maybe_unused = &ncm->msg.wcmdm; + nss_trace("%px: NSS WIFI PDEV Command Message:\n" + "WIFI Type of Command: %d\n" + "WIFI Value of Command: %d\n", + nwpm, nwpm->cmd, nwpm->value); +} + +/* + * nss_wifi_log_enable_ol_statsv2_msg() + * Log NSS WIFI Enable Version 2 of TX/RX Stats + */ +static void nss_wifi_log_enable_ol_statsv2_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_enable_ol_statsv2 *nwpm __maybe_unused = &ncm->msg.wesh_msg; + nss_trace("%px: NSS WIFI Enable Version 2 of TX/RX Stats:\n" + "WIFI Enable Version 2 Stats: %d\n", + nwpm, nwpm->enable_ol_statsv2); +} + +/* + * nss_wifi_log_enable_ol_peer_time_msg() + * Log NSS WIFI Enable Per Peer Stats to Host + */ +static void nss_wifi_log_enable_ol_peer_time_msg(struct nss_wifi_msg *ncm) +{ + struct nss_wifi_ol_peer_time_msg *nwpm __maybe_unused = &ncm->msg.wopt_msg; + int32_t i; + + nss_trace("%px: NSS WIFI Enable Per PEer Stats to Host:\n" + "WIFI Number of Peers: %d\n" + "WIFI Peed ID: %d\n", + nwpm, nwpm->npeers, + nwpm->tstats[0].peer_id); + /* + * Continuation of the log. + */ + nss_trace("WIFI TX Timestamp:\n"); + nss_trace("\tSum of sojourn for each packet:"); + for (i = 0; i < NSS_WIFI_TX_NUM_TOS_TIDS; i++) { + nss_trace("\t\t%d = %x", i, nwpm->tstats[0].sum[i].sum_tx); + } + nss_trace("\tNumber of MSDU per peer per TID:"); + for (i = 0; i < NSS_WIFI_TX_NUM_TOS_TIDS; i++) { + nss_trace("\t\t%d = %x", i, nwpm->tstats[0].sum[i].sum_msdus); + } + nss_trace("WIFI Exponential Weighted Average:"); + for (i = 0; i < NSS_WIFI_TX_NUM_TOS_TIDS; i++) { + nss_trace("\t%d = %d", i, nwpm->tstats[0].avg[i]); + } +} + +/* + * nss_wifi_log_verbose() + * Log message contents. + */ +static void nss_wifi_log_verbose(struct nss_wifi_msg *ncm) +{ + switch (ncm->cm.type) { + case NSS_WIFI_INIT_MSG: + nss_wifi_log_init_msg(ncm); + break; + + case NSS_WIFI_HTT_INIT_MSG: + nss_wifi_log_htt_init_msg(ncm); + break; + + case NSS_WIFI_TX_INIT_MSG: + nss_wifi_log_tx_init_msg(ncm); + break; + + case NSS_WIFI_RAW_SEND_MSG: + nss_wifi_log_rawsend_msg(ncm); + break; + + case NSS_WIFI_MGMT_SEND_MSG: + nss_wifi_log_mgmtsend_msg(ncm); + break; + + case NSS_WIFI_WDS_PEER_ADD_MSG: + nss_wifi_log_wds_peer_msg(ncm); + break; + + case NSS_WIFI_WDS_PEER_DEL_MSG: + nss_wifi_log_wds_peer_msg(ncm); + break; + + case NSS_WIFI_STOP_MSG: + nss_wifi_log_stop_msg(ncm); + break; + + case NSS_WIFI_RESET_MSG: + nss_wifi_log_reset_msg(ncm); + break; + + case NSS_WIFI_PEER_FREELIST_APPEND_MSG: + nss_wifi_log_peer_freelist_append_msg(ncm); + break; + + case NSS_WIFI_RX_REORDER_ARRAY_FREELIST_APPEND_MSG: + nss_wifi_log_rx_reorder_array_freelist_append_msg(ncm); + break; + + case NSS_WIFI_MONITOR_FILTER_SET_MSG: + nss_wifi_log_set_filter_msg(ncm); + break; + + case NSS_WIFI_PEER_BS_STATE_MSG: + nss_wifi_log_peer_activity_msg(ncm); + break; + + case NSS_WIFI_RX_VOW_EXTSTATS_SET_MSG: + nss_wifi_log_rx_vow_extstats_set_msg(ncm); + break; + + case NSS_WIFI_PKTLOG_CFG_MSG: + nss_wifi_log_pktlog_cfg_msg(ncm); + break; + + case NSS_WIFI_ENABLE_PERPKT_TXSTATS_MSG: + nss_wifi_log_enable_perpkt_txstats_msg(ncm); + break; + + case NSS_WIFI_IGMP_MLD_TOS_OVERRIDE_MSG: + nss_wifi_log_override_tos_msg(ncm); + break; + + case NSS_WIFI_OL_STATS_CFG_MSG: + nss_wifi_log_ol_stats_cfg_msg(ncm); + break; + + case NSS_WIFI_TX_QUEUE_CFG_MSG: + nss_wifi_log_tx_queue_cfg_msg(ncm); + break; + + case NSS_WIFI_TX_MIN_THRESHOLD_CFG_MSG: + nss_wifi_log_tx_min_threshold_cfg(ncm); + break; + + case NSS_WIFI_DBDC_PROCESS_ENABLE_MSG: + nss_wifi_log_dbdc_process_enable_msg(ncm); + break; + + case NSS_WIFI_PRIMARY_RADIO_SET_MSG: + nss_wifi_log_primary_radio_set_msg(ncm); + break; + + case NSS_WIFI_FORCE_CLIENT_MCAST_TRAFFIC_SET_MSG: + nss_wifi_log_force_client_mcast_traffic_set_msg(ncm); + break; + + case NSS_WIFI_STORE_OTHER_PDEV_STAVAP_MSG: + nss_wifi_log_store_other_pdev_stavap_msg(ncm); + break; + + case NSS_WIFI_STA_KICKOUT_MSG: + nss_wifi_log_sta_kickout_msg(ncm); + break; + + case NSS_WIFI_WNM_PEER_RX_ACTIVITY_MSG: + nss_wifi_log_wnm_peer_rx_activity(ncm); + break; + + case NSS_WIFI_WDS_VENDOR_MSG: + nss_wifi_log_wds_extn_peer_cfg_msg(ncm); + break; + + case NSS_WIFI_TX_CAPTURE_SET_MSG: + nss_wifi_log_tx_capture_msg(ncm); + break; + + case NSS_WIFI_ALWAYS_PRIMARY_SET_MSG: + nss_wifi_log_always_primary_set_msg(ncm); + break; + + case NSS_WIFI_CMD_MSG: + nss_wifi_log_cmd_msg(ncm); + break; + + case NSS_WIFI_ENABLE_OL_STATSV2_MSG: + nss_wifi_log_enable_ol_statsv2_msg(ncm); + break; + + case NSS_WIFI_OL_PEER_TIME_MSG: + nss_wifi_log_enable_ol_peer_time_msg(ncm); + break; + + case NSS_WIFI_FLUSH_HTT_CMD_MSG: + case NSS_WIFI_OL_STATS_MSG: + case NSS_WIFI_MSDU_TTL_SET_MSG: + case NSS_WIFI_PEER_STATS_MSG: + case NSS_WIFI_FW_STATS_MSG: + case NSS_WIFI_SEND_RRA_MEMORY_REQUEST_MSG: + case NSS_WIFI_STATS_MSG: + case NSS_WIFI_POST_RECV_MSG: + case NSS_WIFI_SEND_PEER_MEMORY_REQUEST_MSG: + /* + * No log for these valid messages. + */ + break; + + default: + nss_warning("%px: Invalid message type\n", ncm); + break; + } +} + +/* + * nss_wifi_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_wifi_log_tx_msg(struct nss_wifi_msg *ncm) +{ + if (ncm->cm.type >= NSS_WIFI_MAX_MSG) { + nss_warning("%px: Invalid message type\n", ncm); + return; + } + + nss_info("%px: type[%d]:%s\n", ncm, ncm->cm.type, nss_wifi_log_message_types_str[ncm->cm.type]); + nss_wifi_log_verbose(ncm); +} + +/* + * nss_wifi_log_rx_msg() + * Log messages received from FW. + */ +void nss_wifi_log_rx_msg(struct nss_wifi_msg *ncm) +{ + if (ncm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", ncm); + return; + } + + if (ncm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (ncm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", ncm, ncm->cm.type, + nss_wifi_log_message_types_str[ncm->cm.type], + ncm->cm.response, nss_cmn_response_str[ncm->cm.response]); + goto verbose; + } + + if (ncm->cm.error >= NSS_WIFI_EMSG_MAX) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + ncm, ncm->cm.type, nss_wifi_log_message_types_str[ncm->cm.type], + ncm->cm.response, nss_cmn_response_str[ncm->cm.response], + ncm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + ncm, ncm->cm.type, nss_wifi_log_message_types_str[ncm->cm.type], + ncm->cm.response, nss_cmn_response_str[ncm->cm.response], + ncm->cm.error, nss_wifi_log_error_response_types_str[ncm->cm.error]); + +verbose: + nss_wifi_log_verbose(ncm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_wifi_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_log.h new file mode 100644 index 000000000..c47a62b3a --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_log.h @@ -0,0 +1,37 @@ +/* + ****************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_WIFI_LOG_H__ +#define __NSS_WIFI_LOG_H__ + +/* + * nss_WIFI_log.h + * NSS WIFI Log Header File + */ + +/* + * nss_WIFI_log_tx_msg + * Logs a WIFI message that is sent to the NSS firmware. + */ +void nss_wifi_log_tx_msg(struct nss_wifi_msg *ncm); + +/* + * nss_WIFI_log_rx_msg + * Logs a WIFI message that is received from the NSS firmware. + */ +void nss_wifi_log_rx_msg(struct nss_wifi_msg *ncm); + +#endif /* __NSS_WIFI_LOG_H__ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_wifi_mac_db.c b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_mac_db.c new file mode 100644 index 000000000..5fb825a1a --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_mac_db.c @@ -0,0 +1,215 @@ +/* + ************************************************************************** + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_wifi_mac_db_if.h" + +/* + * Compile time assertion. + */ +#define NSS_WIFI_MAC_DB_COMPILE_TIME_ASSERT(assertion_name, predicate) \ + typedef char assertion_name[(predicate) ? 1 : -1] + +#define NSS_WIFI_MAC_DB_TX_TIMEOUT 1000 /* Millisecond to jiffies*/ + +/* + * Validate the Wi-Fi MAC database message size not exceeding buffer size. + */ +NSS_WIFI_MAC_DB_COMPILE_TIME_ASSERT(NSS_WIFI_MAC_DB_MAX_BUF_MSG, + (sizeof(struct nss_wifi_mac_db_msg) < NSS_NBUF_PAYLOAD_SIZE)); + +/* + * nss_wifi_mac_db_get_context() + */ +struct nss_ctx_instance *nss_wifi_mac_db_get_context(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wmdb_handler_id]; +} +EXPORT_SYMBOL(nss_wifi_mac_db_get_context); + +/* + * nss_wifi_mac_db_pvt + * Private data structure + */ +static struct nss_wifi_mac_db_pvt { + struct semaphore sem; + struct completion complete; + int response; + void *cb; + void *app_data; +} wifi_mac_db_pvt; + +/* + * nss_wifi_mac_db_handler() + * Handle NSS -> HLOS messages for wifi_mac_db + */ +static void nss_wifi_mac_db_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_wifi_mac_db_msg *ntm = (struct nss_wifi_mac_db_msg *)ncm; + void *ctx; + nss_wifi_mac_db_msg_callback_t cb; + + nss_info("%px: NSS->HLOS message for wifi_mac_db\n", nss_ctx); + + /* + * The interface number shall be wifi_mac_db soc interface or wifi_mac_db radio interface + */ + BUG_ON((ncm->interface != NSS_WIFI_MAC_DB_INTERFACE)); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_WIFI_MAC_DB_MAX_MSG) { + nss_warning("%px: Received invalid message %d for wifi_mac_db interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_wifi_mac_db_msg)) { + nss_warning("%px: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Update the callback and app_data for notify messages, wifi_mac_db sends all notify messages + * to the same callback/app_data. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_ctx->nss_top->wifi_mac_db_msg_callback; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Do we have a call back + */ + if (!ncm->cb) { + nss_info("%px: cb null for wifi_mac_db interface %d", nss_ctx, ncm->interface); + return; + } + + /* + * Get callback & context + */ + cb = (nss_wifi_mac_db_msg_callback_t)ncm->cb; + ctx = nss_ctx->subsys_dp_register[ncm->interface].ndev; + + /* + * call wifi_mac_db msg callback + */ + if (!ctx) { + nss_warning("%px: Event received for wifi_mac_db interface %d before registration", nss_ctx, ncm->interface); + return; + } + + cb(ctx, ntm); +} + +/* + * nss_wifi_mac_db_tx_msg + * Transmit a wifi_mac_db message to NSS FW + * + * NOTE: The caller is expected to handle synchronous wait for message + * response if needed. + */ +nss_tx_status_t nss_wifi_mac_db_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_wifi_mac_db_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + if (ncm->type >= NSS_WIFI_MAC_DB_MAX_MSG) { + nss_warning("%px: wifi_mac_db message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + /* + * The interface number shall be one of the wifi_mac_db soc interfaces + */ + if ((ncm->interface != NSS_WIFI_MAC_DB_INTERFACE)) { + nss_warning("%px: tx request for interface that is not a wifi_mac_db: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_wifi_mac_db_tx_msg); + +/* + **************************************** + * Register/Unregister/Miscellaneous APIs + **************************************** + */ + +/* + * nss_register_wifi_mac_db_if() + * Register wifi_mac_db with nss driver + */ +struct nss_ctx_instance *nss_register_wifi_mac_db_if(uint32_t if_num, nss_wifi_mac_db_callback_t wifi_mac_db_callback, + nss_wifi_mac_db_callback_t wifi_mac_db_ext_callback, + nss_wifi_mac_db_msg_callback_t event_callback, struct net_device *netdev, uint32_t features) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wmdb_handler_id]; + + /* + * The interface number shall be wifi_mac_db interface + */ + nss_assert(if_num == NSS_WIFI_MAC_DB_INTERFACE); + + nss_info("%px: nss_register_wifi_mac_db_if if_num:%d wifi_mac_db_dev:%px", nss_ctx, if_num, netdev); + + nss_core_register_subsys_dp(nss_ctx, if_num, wifi_mac_db_callback, NULL, NULL, netdev, features); + + nss_top_main.wifi_mac_db_msg_callback = event_callback; + + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wmdb_handler_id]; +} +EXPORT_SYMBOL(nss_register_wifi_mac_db_if); + +/* + * nss_unregister_wifi_mac_db_if() + * Unregister wifi_mac_db with nss driver + */ +void nss_unregister_wifi_mac_db_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wmdb_handler_id]; + + /* + * The interface number shall be wifi_mac_db interface + */ + nss_assert(if_num == NSS_WIFI_MAC_DB_INTERFACE); + + nss_core_unregister_subsys_dp(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_unregister_wifi_mac_db_if); + +/* + * nss_wifi_mac_db_register_handler() + * Register handle for notfication messages received on wifi mac db + */ +void nss_wifi_mac_db_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx = + (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wmdb_handler_id]; + + nss_info("wifi_mac_db_register_handler"); + nss_core_register_handler(nss_ctx, NSS_WIFI_MAC_DB_INTERFACE, nss_wifi_mac_db_handler, NULL); + + sema_init(&wifi_mac_db_pvt.sem, 1); + init_completion(&wifi_mac_db_pvt.complete); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_wifi_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_stats.c new file mode 100644 index 000000000..7a31b25b9 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_stats.c @@ -0,0 +1,213 @@ +/* + ************************************************************************** + * Copyright (c) 2016-2017, 2019-2020 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_core.h" +#include "nss_wifi.h" +#include "nss_wifi_stats.h" + +/* + * nss_wifi_stats_str + * Wifi statistics strings. + */ +struct nss_stats_info nss_wifi_stats_str[NSS_WIFI_STATS_MAX] = { + {"rx_pkts" , NSS_STATS_TYPE_COMMON}, + {"rx_queue[0]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[1]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[2]_drops" , NSS_STATS_TYPE_DROP}, + {"rx_queue[3]_drops" , NSS_STATS_TYPE_DROP}, + {"tx_pkts" , NSS_STATS_TYPE_COMMON}, + {"tx_drops" , NSS_STATS_TYPE_DROP}, + {"tx_transmit_completed" , NSS_STATS_TYPE_SPECIAL}, + {"tx_mgmt_received" , NSS_STATS_TYPE_SPECIAL}, + {"tx_mgmt_transmitted" , NSS_STATS_TYPE_SPECIAL}, + {"tx_mgmt_drops" , NSS_STATS_TYPE_DROP}, + {"tx_mgmt_completed" , NSS_STATS_TYPE_SPECIAL}, + {"tx_inv_peer_enq_cnt" , NSS_STATS_TYPE_SPECIAL}, + {"rx_inv_peer_rcv_cnt" , NSS_STATS_TYPE_SPECIAL}, + {"rx_pn_check_failed" , NSS_STATS_TYPE_DROP}, + {"rx_pkts_deliverd" , NSS_STATS_TYPE_SPECIAL}, + {"rx_bytes_delivered" , NSS_STATS_TYPE_SPECIAL}, + {"tx_bytes_completed" , NSS_STATS_TYPE_SPECIAL}, + {"rx_deliver_unaligned_drop_cnt" , NSS_STATS_TYPE_DROP}, + {"tidq_enqueue_cnt_0" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_enqueue_cnt_1" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_enqueue_cnt_2" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_enqueue_cnt_3" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_enqueue_cnt_4" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_enqueue_cnt_5" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_enqueue_cnt_6" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_enqueue_cnt_7" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_dequeue_cnt_0" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_dequeue_cnt_1" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_dequeue_cnt_2" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_dequeue_cnt_3" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_dequeue_cnt_4" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_dequeue_cnt_5" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_dequeue_cnt_6" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_dequeue_cnt_7" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_enqueue_fail_cnt_0" , NSS_STATS_TYPE_DROP}, + {"tidq_enqueue_fail_cnt_1" , NSS_STATS_TYPE_DROP}, + {"tidq_enqueue_fail_cnt_2" , NSS_STATS_TYPE_DROP}, + {"tidq_enqueue_fail_cnt_3" , NSS_STATS_TYPE_DROP}, + {"tidq_enqueue_fail_cnt_4" , NSS_STATS_TYPE_DROP}, + {"tidq_enqueue_fail_cnt_5" , NSS_STATS_TYPE_DROP}, + {"tidq_enqueue_fail_cnt_6" , NSS_STATS_TYPE_DROP}, + {"tidq_enqueue_fail_cnt_7" , NSS_STATS_TYPE_DROP}, + {"tidq_ttl_expire_cnt_0" , NSS_STATS_TYPE_DROP}, + {"tidq_ttl_expire_cnt_1" , NSS_STATS_TYPE_DROP}, + {"tidq_ttl_expire_cnt_2" , NSS_STATS_TYPE_DROP}, + {"tidq_ttl_expire_cnt_3" , NSS_STATS_TYPE_DROP}, + {"tidq_ttl_expire_cnt_4" , NSS_STATS_TYPE_DROP}, + {"tidq_ttl_expire_cnt_5" , NSS_STATS_TYPE_DROP}, + {"tidq_ttl_expire_cnt_6" , NSS_STATS_TYPE_DROP}, + {"tidq_ttl_expire_cnt_7" , NSS_STATS_TYPE_DROP}, + {"tidq_dequeue_req_cnt_0" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_dequeue_req_cnt_1" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_dequeue_req_cnt_2" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_dequeue_req_cnt_3" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_dequeue_req_cnt_4" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_dequeue_req_cnt_5" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_dequeue_req_cnt_6" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_dequeue_req_cnt_7" , NSS_STATS_TYPE_SPECIAL}, + {"total_tidq_depth" , NSS_STATS_TYPE_SPECIAL}, + {"rx_htt_fetch_cnt" , NSS_STATS_TYPE_SPECIAL}, + {"total_tidq_bypass_cnt" , NSS_STATS_TYPE_SPECIAL}, + {"global_q_full_cnt" , NSS_STATS_TYPE_SPECIAL}, + {"tidq_full_cnt" , NSS_STATS_TYPE_SPECIAL} +}; + +uint64_t nss_wifi_stats[NSS_MAX_WIFI_RADIO_INTERFACES][NSS_WIFI_STATS_MAX]; /* WIFI statistics */ + +/* + * nss_wifi_stats_read() + * Read wifi statistics. + */ +static ssize_t nss_wifi_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + uint32_t i, id; + + /* + * Max output lines = #stats * NSS_MAX_CORES + + * Few output lines for banner printing + Number of Extra outputlines for future reference to add new stats. + */ + uint32_t max_output_lines = NSS_WIFI_STATS_MAX * NSS_MAX_WIFI_RADIO_INTERFACES + NSS_STATS_EXTRA_OUTPUT_LINES; + size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + size_t size_wr = 0; + ssize_t bytes_read = 0; + uint64_t *stats_shadow; + + char *lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + stats_shadow = kzalloc(NSS_WIFI_STATS_MAX * 8, GFP_KERNEL); + if (unlikely(stats_shadow == NULL)) { + nss_warning("Could not allocate memory for local shadow buffer"); + kfree(lbuf); + return 0; + } + + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "wifi", NSS_STATS_SINGLE_CORE); + + for (id = 0; id < NSS_MAX_WIFI_RADIO_INTERFACES; id++) { + spin_lock_bh(&nss_top_main.stats_lock); + for (i = 0; (i < NSS_WIFI_STATS_MAX); i++) { + stats_shadow[i] = nss_wifi_stats[id][i]; + } + + spin_unlock_bh(&nss_top_main.stats_lock); + size_wr += nss_stats_print("wifi", NULL, id, nss_wifi_stats_str, stats_shadow, NSS_WIFI_STATS_MAX, lbuf, size_wr, size_al); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n"); + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + kfree(stats_shadow); + return bytes_read; +} + +/* + * nss_wifi_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(wifi) + +/* + * nss_wifi_stats_dentry_create() + * Create wifi statistics debug entry. + */ +void nss_wifi_stats_dentry_create(void) +{ + nss_stats_create_dentry("wifi", &nss_wifi_stats_ops); +} + +/* + * nss_wifi_stats_sync() + * Handle the syncing of WIFI stats. + */ +void nss_wifi_stats_sync(struct nss_ctx_instance *nss_ctx, + struct nss_wifi_stats_sync_msg *stats, uint16_t interface) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + uint32_t radio_id = interface - NSS_WIFI_INTERFACE0; + uint8_t i = 0; + + if (radio_id >= NSS_MAX_WIFI_RADIO_INTERFACES) { + nss_warning("%px: invalid interface: %d", nss_ctx, interface); + return; + } + + spin_lock_bh(&nss_top->stats_lock); + + /* + * Tx/Rx stats + */ + nss_wifi_stats[radio_id][NSS_WIFI_STATS_RX_PKTS] += stats->node_stats.rx_packets; + for (i = 0; i < NSS_MAX_NUM_PRI; i++) { + nss_wifi_stats[radio_id][NSS_WIFI_STATS_RX_QUEUE_0_DROPPED + i] += stats->node_stats.rx_dropped[i]; + } + nss_wifi_stats[radio_id][NSS_WIFI_STATS_TX_PKTS] += stats->node_stats.tx_packets; + nss_wifi_stats[radio_id][NSS_WIFI_STATS_TX_DROPPED] += stats->tx_transmit_dropped; + nss_wifi_stats[radio_id][NSS_WIFI_STATS_TX_COMPLETED] += stats->tx_transmit_completions; + nss_wifi_stats[radio_id][NSS_WIFI_STATS_MGMT_RCV_CNT] += stats->tx_mgmt_rcv_cnt; + nss_wifi_stats[radio_id][NSS_WIFI_STATS_MGMT_TX_PKTS] += stats->tx_mgmt_pkts; + nss_wifi_stats[radio_id][NSS_WIFI_STATS_MGMT_TX_DROPPED] += stats->tx_mgmt_dropped; + nss_wifi_stats[radio_id][NSS_WIFI_STATS_MGMT_TX_COMPLETIONS] += stats->tx_mgmt_completions; + nss_wifi_stats[radio_id][NSS_WIFI_STATS_TX_INV_PEER_ENQUEUE_CNT] += stats->tx_inv_peer_enq_cnt; + nss_wifi_stats[radio_id][NSS_WIFI_STATS_RX_INV_PEER_RCV_CNT] += stats->rx_inv_peer_rcv_cnt; + nss_wifi_stats[radio_id][NSS_WIFI_STATS_RX_PN_CHECK_FAILED] += stats->rx_pn_check_failed; + nss_wifi_stats[radio_id][NSS_WIFI_STATS_RX_DELIVERED] += stats->rx_pkts_deliverd; + nss_wifi_stats[radio_id][NSS_WIFI_STATS_RX_BYTES_DELIVERED] += stats->rx_bytes_deliverd; + nss_wifi_stats[radio_id][NSS_WIFI_STATS_TX_BYTES_COMPLETED] += stats->tx_bytes_transmit_completions; + nss_wifi_stats[radio_id][NSS_WIFI_STATS_RX_DELIVER_UNALIGNED_DROP_CNT] += stats->rx_deliver_unaligned_drop_cnt; + + for (i = 0; i < NSS_WIFI_TX_NUM_TOS_TIDS; i++) { + nss_wifi_stats[radio_id][NSS_WIFI_STATS_TIDQ_ENQUEUE_CNT + i] += stats->tidq_enqueue_cnt[i]; + nss_wifi_stats[radio_id][NSS_WIFI_STATS_TIDQ_DEQUEUE_CNT + i] += stats->tidq_dequeue_cnt[i]; + nss_wifi_stats[radio_id][NSS_WIFI_STATS_TIDQ_ENQUEUE_FAIL_CNT + i] += stats->tidq_enqueue_fail_cnt[i]; + nss_wifi_stats[radio_id][NSS_WIFI_STATS_TIDQ_TTL_EXPIRE_CNT + i] += stats->tidq_ttl_expire_cnt[i]; + nss_wifi_stats[radio_id][NSS_WIFI_STATS_TIDQ_DEQUEUE_REQ_CNT + i] += stats->tidq_dequeue_req_cnt[i]; + } + + nss_wifi_stats[radio_id][NSS_WIFI_STATS_RX_HTT_FETCH_CNT] += stats->rx_htt_fetch_cnt; + nss_wifi_stats[radio_id][NSS_WIFI_STATS_TOTAL_TIDQ_DEPTH] = stats->total_tidq_depth; + nss_wifi_stats[radio_id][NSS_WIFI_STATS_TOTAL_TIDQ_BYPASS_CNT] += stats->total_tidq_bypass_cnt; + nss_wifi_stats[radio_id][NSS_WIFI_STATS_GLOBAL_Q_FULL_CNT] += stats->global_q_full_cnt; + nss_wifi_stats[radio_id][NSS_WIFI_STATS_TIDQ_FULL_CNT] += stats->tidq_full_cnt; + + spin_unlock_bh(&nss_top->stats_lock); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_wifi_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_stats.h new file mode 100644 index 000000000..782777777 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_stats.h @@ -0,0 +1,62 @@ +/* + ****************************************************************************** + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_WIFI_STATS_H +#define __NSS_WIFI_STATS_H + +/* + * wifi statistics + */ +enum nss_wifi_stats_types { + NSS_WIFI_STATS_RX_PKTS, + NSS_WIFI_STATS_RX_QUEUE_0_DROPPED, + NSS_WIFI_STATS_RX_QUEUE_1_DROPPED, + NSS_WIFI_STATS_RX_QUEUE_2_DROPPED, + NSS_WIFI_STATS_RX_QUEUE_3_DROPPED, + NSS_WIFI_STATS_TX_PKTS, + NSS_WIFI_STATS_TX_DROPPED, + NSS_WIFI_STATS_TX_COMPLETED, + NSS_WIFI_STATS_MGMT_RCV_CNT, + NSS_WIFI_STATS_MGMT_TX_PKTS, + NSS_WIFI_STATS_MGMT_TX_DROPPED, + NSS_WIFI_STATS_MGMT_TX_COMPLETIONS, + NSS_WIFI_STATS_TX_INV_PEER_ENQUEUE_CNT, + NSS_WIFI_STATS_RX_INV_PEER_RCV_CNT, + NSS_WIFI_STATS_RX_PN_CHECK_FAILED, + NSS_WIFI_STATS_RX_DELIVERED, + NSS_WIFI_STATS_RX_BYTES_DELIVERED, + NSS_WIFI_STATS_TX_BYTES_COMPLETED, + NSS_WIFI_STATS_RX_DELIVER_UNALIGNED_DROP_CNT, + NSS_WIFI_STATS_TIDQ_ENQUEUE_CNT, + NSS_WIFI_STATS_TIDQ_DEQUEUE_CNT = NSS_WIFI_STATS_TIDQ_ENQUEUE_CNT + 8, + NSS_WIFI_STATS_TIDQ_ENQUEUE_FAIL_CNT = NSS_WIFI_STATS_TIDQ_DEQUEUE_CNT + 8, + NSS_WIFI_STATS_TIDQ_TTL_EXPIRE_CNT = NSS_WIFI_STATS_TIDQ_ENQUEUE_FAIL_CNT + 8, + NSS_WIFI_STATS_TIDQ_DEQUEUE_REQ_CNT = NSS_WIFI_STATS_TIDQ_TTL_EXPIRE_CNT + 8, + NSS_WIFI_STATS_TOTAL_TIDQ_DEPTH = NSS_WIFI_STATS_TIDQ_DEQUEUE_REQ_CNT + 8, + NSS_WIFI_STATS_RX_HTT_FETCH_CNT, + NSS_WIFI_STATS_TOTAL_TIDQ_BYPASS_CNT, + NSS_WIFI_STATS_GLOBAL_Q_FULL_CNT, + NSS_WIFI_STATS_TIDQ_FULL_CNT, + NSS_WIFI_STATS_MAX, +}; + +/* + * wifi statistics APIs + */ +extern void nss_wifi_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_wifi_stats_sync_msg *stats, uint16_t interface); +extern void nss_wifi_stats_dentry_create(void); + +#endif /* __NSS_WIFI_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_wifi_vdev.c b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_vdev.c new file mode 100644 index 000000000..8f020b2a6 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_wifi_vdev.c @@ -0,0 +1,379 @@ +/* + ************************************************************************** + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" + +/* + * nss_wifi_vdev_handler() + * Handle NSS -> HLOS messages for wifi_vdev + */ +static void nss_wifi_vdev_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + nss_wifi_vdev_msg_callback_t cb; + + nss_info("%px: NSS->HLOS message for wifi vdev on interface:%d", nss_ctx, ncm->interface); + + BUG_ON(((ncm->interface < NSS_DYNAMIC_IF_START) || (ncm->interface >= (NSS_DYNAMIC_IF_START + NSS_MAX_DYNAMIC_INTERFACES)))); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_WIFI_VDEV_MAX_MSG) { + nss_warning("%px: received invalid message %d for wifi vdev interface", nss_ctx, ncm->type); + return; + } + + if (nss_cmn_get_msg_len(ncm) > sizeof(struct nss_wifi_vdev_msg)) { + nss_warning("%px: Length of message %d is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm), (int)sizeof(struct nss_wifi_vdev_msg)); + return; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * callback + */ + if (!nss_ctx->subsys_dp_register[ncm->interface].ndev) { + nss_warning("%px: Event received wifi vdev interface %d before registration", nss_ctx, ncm->interface); + return; + + } + + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_core_get_msg_handler(nss_ctx, ncm->interface); + ncm->app_data = (nss_ptr_t)nss_ctx->subsys_dp_register[ncm->interface].ndev; + } + + /* + * Do we have a callback? + */ + if (!ncm->cb) { + return; + } + + cb = (nss_wifi_vdev_msg_callback_t)ncm->cb; + cb((void *)ncm->app_data, ncm); +} + +/* + * nss_wifi_vdev_msg_init() + * Initialize wifi message. + */ +void nss_wifi_vdev_msg_init(struct nss_wifi_vdev_msg *nim, uint32_t if_num, uint32_t type, uint32_t len, + nss_wifi_vdev_msg_callback_t *cb, void *app_data) +{ + nss_cmn_msg_init(&nim->cm, if_num, type, len, (void *)cb, app_data); +} +EXPORT_SYMBOL(nss_wifi_vdev_msg_init); + +/* + * nss_wifi_vdev_base_tx_msg() + * Transmit a wifi vdev base message to NSSFW + */ +nss_tx_status_t nss_wifi_vdev_base_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_wifi_vdev_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + nss_trace("%px: Sending wifi vdev message on interface :%d", nss_ctx, ncm->interface); + + /* + * Sanity checks on the message + */ + + /* + * The interface number shall be wifi vdev base vap + */ + if (ncm->interface != NSS_VAP_INTERFACE) { + nss_warning("%px: wifi vdev base tx request not on wifi vdev vap: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type >= NSS_WIFI_VDEV_MAX_MSG) { + nss_warning("%px: wifi vdev base message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_wifi_vdev_base_tx_msg); + +/* + * nss_wifi_vdev_tx_msg() + * Transmit a wifi vdev message to NSSFW + */ +nss_tx_status_t nss_wifi_vdev_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_wifi_vdev_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + nss_trace("%px: Sending wifi vdev message on interface :%d", nss_ctx, ncm->interface); + + /* + * Sanity checks on the message + */ + + /* + * Interface shall be of dynamic interface type + */ + if ((ncm->interface < NSS_DYNAMIC_IF_START) || (ncm->interface >= (NSS_DYNAMIC_IF_START + NSS_MAX_DYNAMIC_INTERFACES))) { + nss_warning("%px: wifi vdev tx request for invalid interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type >= NSS_WIFI_VDEV_MAX_MSG) { + nss_warning("%px: wifi vdev message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_wifi_vdev_tx_msg); + +/* + * nss_wifi_vdev_tx_msg_ext() + * Send special data packet with metadata for vap processing + */ +nss_tx_status_t nss_wifi_vdev_tx_msg_ext(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf) +{ + struct nss_wifi_vdev_msg *nm; + struct nss_cmn_msg *ncm; + nss_tx_status_t status; + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) { + nss_warning("%px: wifi vdev message dropped as core not ready", nss_ctx); + return NSS_TX_FAILURE_NOT_READY; + } + + nm = (struct nss_wifi_vdev_msg *) os_buf->data; + ncm = &nm->cm; + + nss_trace("%px: Sending wifi vdev message on interface :%d", nss_ctx, ncm->interface); + + /* + * Interface shall be of dynamic interface type + */ + if ((ncm->interface < NSS_DYNAMIC_IF_START) || (ncm->interface >= (NSS_DYNAMIC_IF_START + NSS_MAX_DYNAMIC_INTERFACES))) { + nss_warning("%px: wifi vdev tx request for invalid interface: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + if (ncm->type >= NSS_WIFI_VDEV_MAX_MSG) { + nss_warning("%px: wifi vdev message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + status = nss_core_send_buffer(nss_ctx, 0, os_buf, NSS_IF_H2N_CMD_QUEUE, H2N_BUFFER_CTRL, H2N_BIT_FLAG_BUFFER_REUSABLE); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: Unable to enqueue 'wifi vdev message'", nss_ctx); + return NSS_TX_FAILURE; + } + + nss_hal_send_interrupt(nss_ctx, NSS_H2N_INTR_DATA_COMMAND_QUEUE); + + NSS_PKT_STATS_INC(&nss_ctx->nss_top->stats_drv[NSS_DRV_STATS_TX_CMD_REQ]); + +return status; +} +EXPORT_SYMBOL(nss_wifi_vdev_tx_msg_ext); + +/* + * nss_wifi_vdev_tx_buf + * Send data packet for vap processing + */ +nss_tx_status_t nss_wifi_vdev_tx_buf(struct nss_ctx_instance *nss_ctx, struct sk_buff *os_buf, uint32_t if_num) +{ + BUG_ON(((if_num < NSS_DYNAMIC_IF_START) || (if_num >= (NSS_DYNAMIC_IF_START + NSS_MAX_DYNAMIC_INTERFACES)))); + + return nss_core_send_packet(nss_ctx, os_buf, if_num, H2N_BIT_FLAG_BUFFER_REUSABLE); +} +EXPORT_SYMBOL(nss_wifi_vdev_tx_buf); + +/* + * nss_wifi_vdev_set_next_hop() + */ +nss_tx_status_t nss_wifi_vdev_set_next_hop(struct nss_ctx_instance *ctx, int if_num, int next_hop) +{ + nss_tx_status_t status; + struct nss_wifi_vdev_msg *wifivdevmsg = kzalloc(sizeof(struct nss_wifi_vdev_msg), GFP_KERNEL); + struct nss_wifi_vdev_set_next_hop_msg *next_hop_msg = NULL; + + if (!wifivdevmsg) { + nss_warning("%px: Unable to allocate next hop message", ctx); + return NSS_TX_FAILURE; + } + + next_hop_msg = &wifivdevmsg->msg.next_hop; + + next_hop_msg->ifnumber = next_hop; + nss_wifi_vdev_msg_init(wifivdevmsg, if_num, NSS_WIFI_VDEV_SET_NEXT_HOP, sizeof(struct nss_wifi_vdev_set_next_hop_msg), NULL, NULL); + + status = nss_wifi_vdev_tx_msg(ctx, wifivdevmsg); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: Unable to send next hop message", ctx); + } + + kfree(wifivdevmsg); + return status; +} +EXPORT_SYMBOL(nss_wifi_vdev_set_next_hop); + +/* + * nss_wifi_vdev_base_set_next_hop() + */ +nss_tx_status_t nss_wifi_vdev_base_set_next_hop(struct nss_ctx_instance *ctx, int next_hop) +{ + nss_tx_status_t status; + struct nss_wifi_vdev_msg *wifivdevmsg = kzalloc(sizeof(struct nss_wifi_vdev_msg), GFP_KERNEL); + struct nss_wifi_vdev_set_next_hop_msg *next_hop_msg = NULL; + + if (!wifivdevmsg) { + nss_warning("%px: Unable to allocate next hop message", ctx); + return NSS_TX_FAILURE; + } + + next_hop_msg = &wifivdevmsg->msg.next_hop; + + next_hop_msg->ifnumber = next_hop; + nss_wifi_vdev_msg_init(wifivdevmsg, NSS_VAP_INTERFACE, NSS_WIFI_VDEV_SET_NEXT_HOP, sizeof(struct nss_wifi_vdev_set_next_hop_msg), NULL, NULL); + + status = nss_wifi_vdev_base_tx_msg(ctx, wifivdevmsg); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: Unable to send next hop message", ctx); + } + + kfree(wifivdevmsg); + return status; +} +EXPORT_SYMBOL(nss_wifi_vdev_base_set_next_hop); + +/* + * nss_wifi_vdev_set_peer_next_hop() + */ +nss_tx_status_t nss_wifi_vdev_set_peer_next_hop(struct nss_ctx_instance *ctx, uint32_t nss_if, uint8_t *addr, uint32_t next_hop_if) +{ + nss_tx_status_t status; + struct nss_wifi_vdev_msg *wifivdevmsg = kzalloc(sizeof(struct nss_wifi_vdev_msg), GFP_KERNEL); + struct nss_wifi_vdev_set_peer_next_hop_msg *peer_next_hop_msg = NULL; + + if (!wifivdevmsg) { + nss_warning("%px: Unable to allocate next hop message", ctx); + return NSS_TX_FAILURE; + } + + peer_next_hop_msg = &wifivdevmsg->msg.vdev_set_peer_next_hp; + memcpy(peer_next_hop_msg->peer_mac_addr, addr, ETH_ALEN); + + peer_next_hop_msg->if_num = next_hop_if; + nss_wifi_vdev_msg_init(wifivdevmsg, nss_if, NSS_WIFI_VDEV_SET_PEER_NEXT_HOP, + sizeof(struct nss_wifi_vdev_set_peer_next_hop_msg), NULL, NULL); + + status = nss_wifi_vdev_tx_msg(ctx, wifivdevmsg); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: Unable to send peer next hop message", ctx); + } + + kfree(wifivdevmsg); + return status; +} +EXPORT_SYMBOL(nss_wifi_vdev_set_peer_next_hop); + +/* + * nss_wifi_vdev_set_dp_type() + * Set the vap datapath type of the packet. + */ +bool nss_wifi_vdev_set_dp_type(struct nss_ctx_instance *nss_ctx, struct net_device *netdev, + uint32_t if_num, enum nss_wifi_vdev_dp_type dp_type) +{ + + NSS_VERIFY_CTX_MAGIC(nss_ctx); + + nss_assert((if_num >= NSS_DYNAMIC_IF_START) && (if_num < (NSS_DYNAMIC_IF_START + NSS_MAX_DYNAMIC_INTERFACES))); + + if (unlikely(nss_ctx->state != NSS_CORE_STATE_INITIALIZED)) { + nss_warning("%px: Vap interface dp type could not be set as core is not initialized\n", nss_ctx); + return false; + } + + /* + * set the subsytem dp type for the Wi-Fi vdev + */ + nss_core_set_subsys_dp_type(nss_ctx, netdev, if_num, dp_type); + + return true; +} +EXPORT_SYMBOL(nss_wifi_vdev_set_dp_type); + +/* + *********************************** + * Register/Unregister/Miscellaneous APIs + *********************************** + */ + +/* + * nss_register_wifi_vdev_if() + */ +uint32_t nss_register_wifi_vdev_if(struct nss_ctx_instance *nss_ctx, + int32_t if_num, + nss_wifi_vdev_callback_t vdev_data_callback, + nss_wifi_vdev_ext_data_callback_t vdev_ext_data_callback, + nss_wifi_vdev_msg_callback_t vdev_event_callback, + struct net_device *netdev, + uint32_t features) +{ + uint32_t status; + + nss_assert((if_num >= NSS_DYNAMIC_IF_START) && (if_num < (NSS_DYNAMIC_IF_START + NSS_MAX_DYNAMIC_INTERFACES))); + + nss_core_register_subsys_dp(nss_ctx, if_num, vdev_data_callback, vdev_ext_data_callback, NULL, netdev, features); + + status = nss_core_register_msg_handler(nss_ctx, if_num, vdev_event_callback); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: unable to register event handler for interface(%u)", nss_ctx, if_num); + return status; + } + + nss_core_register_handler(nss_ctx, if_num, nss_wifi_vdev_handler, NULL); + + return NSS_CORE_STATUS_SUCCESS; +} +EXPORT_SYMBOL(nss_register_wifi_vdev_if); + +/* + * nss_unregister_wifi_vdev_if() + */ +void nss_unregister_wifi_vdev_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id]; + uint32_t status; + + nss_assert(nss_ctx); + nss_assert((if_num >= NSS_DYNAMIC_IF_START) && (if_num < (NSS_DYNAMIC_IF_START + NSS_MAX_DYNAMIC_INTERFACES))); + + nss_core_unregister_subsys_dp(nss_ctx, if_num); + + status = nss_core_unregister_msg_handler(nss_ctx, if_num); + if (status != NSS_CORE_STATUS_SUCCESS) { + nss_warning("%px: unable to unregister event handler for interface(%u)", nss_ctx, if_num); + return; + } + + nss_core_unregister_handler(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_unregister_wifi_vdev_if); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_wifili.c b/feeds/ipq807x/qca-nss-drv/src/nss_wifili.c new file mode 100644 index 000000000..43e8d0b13 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_wifili.c @@ -0,0 +1,597 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_tx_rx_common.h" +#include "nss_wifili_stats.h" +#include "nss_wifili_log.h" +#include "nss_wifili_strings.h" + +#define NSS_WIFILI_TX_TIMEOUT 1000 /* Millisecond to jiffies*/ +#define NSS_WIFILI_INVALID_SCHEME_ID -1 +#define NSS_WIFILI_THREAD_SCHEME_ENTRY_MAX 4 + /* Maximum number of thread scheme entries. */ + +/* + * nss_wifili_thread_scheme_entry + * Details of thread scheme. + */ +struct nss_wifili_thread_scheme_entry { + int32_t radio_ifnum; /* Radio interface number. */ + uint32_t radio_priority; /* Priority of radio. */ + uint32_t scheme_priority; /* Priority of scheme. */ + uint8_t scheme_index; /* Scheme index allocated to radio. */ + bool allocated; /* Flag to check if scheme is allocated. */ +}; + +/* + * nss_wifili_thread_scheme_db + * Wifili thread scheme database. + */ +struct nss_wifili_thread_scheme_db { + spinlock_t lock; /* Lock to protect from simultaneous access. */ + uint32_t radio_count; /* Radio counter. */ + struct nss_wifili_thread_scheme_entry nwtse[NSS_WIFILI_THREAD_SCHEME_ENTRY_MAX]; + /* Metadata for each of scheme. */ +}; + +/* + * nss_wifili_pvt + * Private data structure + */ +static struct nss_wifili_pvt { + struct semaphore sem; + struct completion complete; + int response; + void *cb; + void *app_data; +} wifili_pvt; + +/* + * Scheme to radio mapping database + */ +static struct nss_wifili_thread_scheme_db ts_db[NSS_MAX_CORES]; + +/* + * nss_wifili_handler() + * Handle NSS -> HLOS messages for wifi + */ +static void nss_wifili_handler(struct nss_ctx_instance *nss_ctx, struct nss_cmn_msg *ncm, __attribute__((unused))void *app_data) +{ + struct nss_wifili_msg *ntm = (struct nss_wifili_msg *)ncm; + void *ctx; + nss_wifili_msg_callback_t cb; + + nss_info("%px: NSS->HLOS message for wifili\n", nss_ctx); + + /* + * The interface number shall be wifili soc interface or wifili radio interface + */ + BUG_ON((nss_is_dynamic_interface(ncm->interface)) + || ((ncm->interface != NSS_WIFILI_INTERNAL_INTERFACE) + && (ncm->interface != NSS_WIFILI_EXTERNAL_INTERFACE0) + && (ncm->interface != NSS_WIFILI_EXTERNAL_INTERFACE1))); + + /* + * Trace messages. + */ + nss_wifili_log_rx_msg(ntm); + + /* + * Is this a valid request/response packet? + */ + if (ncm->type >= NSS_WIFILI_MAX_MSG) { + nss_warning("%px: Received invalid message %d for wifili interface", nss_ctx, ncm->type); + return; + } + + if ((nss_cmn_get_msg_len(ncm) > sizeof(struct nss_wifili_msg)) && + ntm->cm.type != NSS_WIFILI_PEER_EXT_STATS_MSG) { + nss_warning("%px: Length of message is greater than required: %d", nss_ctx, nss_cmn_get_msg_len(ncm)); + return; + } + + /* + * Snoop messages for local driver and handle + */ + switch (ntm->cm.type) { + case NSS_WIFILI_STATS_MSG: + /* + * Update WIFI driver statistics and send statistics notifications to the registered modules + */ + nss_wifili_stats_sync(nss_ctx, &ntm->msg.wlsoc_stats, ncm->interface); + nss_wifili_stats_notify(nss_ctx, ncm->interface); + break; + } + + /* + * Update the callback and app_data for notify messages, wifili sends all notify messages + * to the same callback/app_data. + */ + if (ncm->response == NSS_CMN_RESPONSE_NOTIFY) { + ncm->cb = (nss_ptr_t)nss_ctx->nss_top->wifili_msg_callback; + } + + /* + * Log failures + */ + nss_core_log_msg_failures(nss_ctx, ncm); + + /* + * Do we have a call back + */ + if (!ncm->cb) { + nss_info("%px: cb null for wifili interface %d", nss_ctx, ncm->interface); + return; + } + + /* + * Get callback & context + */ + cb = (nss_wifili_msg_callback_t)ncm->cb; + ctx = nss_ctx->subsys_dp_register[ncm->interface].ndev; + + /* + * call wifili msg callback + */ + if (!ctx) { + nss_warning("%px: Event received for wifili interface %d before registration", nss_ctx, ncm->interface); + return; + } + + cb(ctx, ntm); +} + +/* + * nss_wifili_callback() + * Callback to handle the completion of NSS->HLOS messages. + */ +static void nss_wifili_callback(void *app_data, struct nss_wifili_msg *nvm) +{ + nss_wifili_msg_callback_t callback = (nss_wifili_msg_callback_t)wifili_pvt.cb; + void *data = wifili_pvt.app_data; + + wifili_pvt.response = NSS_TX_SUCCESS; + wifili_pvt.cb = NULL; + wifili_pvt.app_data = NULL; + + if (nvm->cm.response != NSS_CMN_RESPONSE_ACK) { + nss_warning("wifili error response %d\n", nvm->cm.response); + wifili_pvt.response = nvm->cm.response; + } + + if (callback) { + callback(data, nvm); + } + complete(&wifili_pvt.complete); +} + +/* + * nss_wifili_tx_msg + * Transmit a wifili message to NSS FW + * + * NOTE: The caller is expected to handle synchronous wait for message + * response if needed. + */ +nss_tx_status_t nss_wifili_tx_msg(struct nss_ctx_instance *nss_ctx, struct nss_wifili_msg *msg) +{ + struct nss_cmn_msg *ncm = &msg->cm; + + /* + * Trace messages. + */ + nss_wifili_log_tx_msg(msg); + + if (ncm->type >= NSS_WIFILI_MAX_MSG) { + nss_warning("%px: wifili message type out of range: %d", nss_ctx, ncm->type); + return NSS_TX_FAILURE; + } + + /* + * The interface number shall be one of the wifili soc interfaces + */ + if ((ncm->interface != NSS_WIFILI_INTERNAL_INTERFACE) + && (ncm->interface != NSS_WIFILI_EXTERNAL_INTERFACE0) + && (ncm->interface != NSS_WIFILI_EXTERNAL_INTERFACE1)) { + nss_warning("%px: tx request for interface that is not a wifili: %d", nss_ctx, ncm->interface); + return NSS_TX_FAILURE; + } + + return nss_core_send_cmd(nss_ctx, msg, sizeof(*msg), NSS_NBUF_PAYLOAD_SIZE); +} +EXPORT_SYMBOL(nss_wifili_tx_msg); + +/* + * nss_wifili_tx_msg_sync() + * Transmit a wifili message to NSS firmware synchronously. + */ +nss_tx_status_t nss_wifili_tx_msg_sync(struct nss_ctx_instance *nss_ctx, struct nss_wifili_msg *nvm) +{ + nss_tx_status_t status; + int ret = 0; + + down(&wifili_pvt.sem); + wifili_pvt.cb = (void *)nvm->cm.cb; + wifili_pvt.app_data = (void *)nvm->cm.app_data; + + nvm->cm.cb = (nss_ptr_t)nss_wifili_callback; + nvm->cm.app_data = (nss_ptr_t)NULL; + + status = nss_wifili_tx_msg(nss_ctx, nvm); + if (status != NSS_TX_SUCCESS) { + nss_warning("%px: wifili_tx_msg failed\n", nss_ctx); + up(&wifili_pvt.sem); + return status; + } + + ret = wait_for_completion_timeout(&wifili_pvt.complete, msecs_to_jiffies(NSS_WIFILI_TX_TIMEOUT)); + if (!ret) { + nss_warning("%px: wifili msg tx failed due to timeout\n", nss_ctx); + wifili_pvt.response = NSS_TX_FAILURE; + } + + status = wifili_pvt.response; + up(&wifili_pvt.sem); + return status; +} +EXPORT_SYMBOL(nss_wifili_tx_msg_sync); + +/* + * nss_wifili_get_context() + */ +struct nss_ctx_instance *nss_wifili_get_context(void) +{ + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id]; +} +EXPORT_SYMBOL(nss_wifili_get_context); + +/* + * nss_get_available_wifili_external_if() + * Check and return the available external interface + */ +uint32_t nss_get_available_wifili_external_if(void) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id]; + /* + * Check if the external interface is registered. + * Return the interface number if not registered. + */ + if (!(nss_ctx->subsys_dp_register[NSS_WIFILI_EXTERNAL_INTERFACE0].ndev)) { + return NSS_WIFILI_EXTERNAL_INTERFACE0; + } + + if (!(nss_ctx->subsys_dp_register[NSS_WIFILI_EXTERNAL_INTERFACE1].ndev)) { + return NSS_WIFILI_EXTERNAL_INTERFACE1; + } + + nss_warning("%px: No available external intefaces\n", nss_ctx); + + return NSS_MAX_NET_INTERFACES; +} +EXPORT_SYMBOL(nss_get_available_wifili_external_if); + +/* + * nss_wifili_get_radio_num() + * Get NSS wifili radio count. + * + * Wi-Fi host driver needs to know the current radio count + * to extract the radio priority from ini file. + */ +uint32_t nss_wifili_get_radio_num(struct nss_ctx_instance *nss_ctx) +{ + uint8_t core_id; + uint32_t radio_count; + + nss_assert(nss_ctx); + nss_assert(nss_ctx->id < nss_top_main.num_nss); + + core_id = nss_ctx->id; + + spin_lock_bh(&ts_db[core_id].lock); + radio_count = ts_db[core_id].radio_count; + spin_unlock_bh(&ts_db[core_id].lock); + + return radio_count; +} +EXPORT_SYMBOL(nss_wifili_get_radio_num); + +/* + * nss_wifili_thread_scheme_alloc() + * Allocate NSS worker thread scheme index. + * + * API does search on scheme database and returns scheme index based on + * priority of radio and free entry available. + * Wi-Fi driver fetches radio priority from ini file and calls this API + * to get the scheme index based on radio priority. + * + */ +uint8_t nss_wifili_thread_scheme_alloc(struct nss_ctx_instance *nss_ctx, + int32_t radio_ifnum, + enum nss_wifili_thread_scheme_priority radio_priority) +{ + uint8_t i; + uint8_t scheme_idx; + uint8_t core_id; + uint8_t next_avail_entry_idx = NSS_WIFILI_THREAD_SCHEME_ENTRY_MAX; + + nss_assert(nss_ctx); + nss_assert(nss_ctx->id < nss_top_main.num_nss); + + core_id = nss_ctx->id; + + /* + * Iterate through scheme database and allocate + * scheme_id matching the priority requested. + */ + spin_lock_bh(&ts_db[core_id].lock); + for (i = 0; i < NSS_WIFILI_THREAD_SCHEME_ENTRY_MAX; i++) { + if (ts_db[core_id].nwtse[i].allocated) { + continue; + } + + if (radio_priority == + ts_db[core_id].nwtse[i].scheme_priority) { + ts_db[core_id].nwtse[i].radio_ifnum = radio_ifnum; + ts_db[core_id].nwtse[i].radio_priority = radio_priority; + ts_db[core_id].nwtse[i].allocated = true; + ts_db[core_id].radio_count++; + scheme_idx = ts_db[core_id].nwtse[i].scheme_index; + spin_unlock_bh(&ts_db[core_id].lock); + + nss_info("%px: Allocated scheme index:%d radio_ifnum:%d", + nss_ctx, + scheme_idx, + radio_ifnum); + + return scheme_idx; + } + + next_avail_entry_idx = i; + } + + /* + * When radio priority does not match any of scheme entry priority + * and database has unallocated entries, provide available unallocated entry. + * This prevents any catastrophic failure during attach of Wi-Fi radio. + */ + if (next_avail_entry_idx != NSS_WIFILI_THREAD_SCHEME_ENTRY_MAX) { + + ts_db[core_id].nwtse[next_avail_entry_idx].radio_ifnum = radio_ifnum; + ts_db[core_id].nwtse[next_avail_entry_idx].radio_priority = radio_priority; + ts_db[core_id].nwtse[next_avail_entry_idx].allocated = true; + ts_db[core_id].radio_count++; + scheme_idx = ts_db[core_id].nwtse[next_avail_entry_idx].scheme_index; + spin_unlock_bh(&ts_db[core_id].lock); + + nss_info("%px: Priority did not match for radio_ifnum:%d, allocated a next available scheme:%d", + nss_ctx, + radio_ifnum, + scheme_idx); + + return scheme_idx; + } + spin_unlock_bh(&ts_db[core_id].lock); + + nss_warning("%px: Could not find scheme - radio_ifnum:%d radio_map:%d\n", + nss_ctx, + radio_ifnum, + radio_priority); + + return NSS_WIFILI_INVALID_SCHEME_ID; +} +EXPORT_SYMBOL(nss_wifili_thread_scheme_alloc); + +/* + * nss_wifili_thread_scheme_dealloc() + * Reset thread scheme metadata. + */ +void nss_wifili_thread_scheme_dealloc(struct nss_ctx_instance *nss_ctx, + int32_t radio_ifnum) +{ + uint32_t id; + uint8_t core_id; + + nss_assert(nss_ctx); + nss_assert(nss_ctx->id < nss_top_main.num_nss); + + core_id = nss_ctx->id; + + /* + * Radio count cannot be zero here. + */ + nss_assert(ts_db[core_id].radio_count); + + spin_lock_bh(&ts_db[core_id].lock); + for (id = 0; id < NSS_WIFILI_THREAD_SCHEME_ENTRY_MAX; id++) { + if (ts_db[core_id].nwtse[id].radio_ifnum != radio_ifnum) { + continue; + } + + ts_db[core_id].nwtse[id].radio_priority = 0; + ts_db[core_id].nwtse[id].allocated = false; + ts_db[core_id].nwtse[id].radio_ifnum = 0; + ts_db[core_id].radio_count--; + break; + } + spin_unlock_bh(&ts_db[core_id].lock); + + if (id == NSS_WIFILI_THREAD_SCHEME_ENTRY_MAX) { + nss_warning("%px: Could not find scheme database with radio_ifnum:%d", + nss_ctx, + radio_ifnum); + } +} +EXPORT_SYMBOL(nss_wifili_thread_scheme_dealloc); + +/* + * nss_wifili_thread_scheme_db_init() + * Initialize thread scheme database. + */ +void nss_wifili_thread_scheme_db_init(uint8_t core_id) +{ + uint32_t id; + + spin_lock_init(&ts_db[core_id].lock); + + /* + * Iterate through scheme database and assign + * scheme_id and priority for each entry + */ + ts_db[core_id].radio_count = 0; + for (id = 0; id < NSS_WIFILI_THREAD_SCHEME_ENTRY_MAX; id++) { + ts_db[core_id].nwtse[id].radio_priority = 0; + ts_db[core_id].nwtse[id].radio_ifnum = 0; + ts_db[core_id].nwtse[id].allocated = false; + + switch (id) { + case 0: + ts_db[core_id].nwtse[id].scheme_priority = NSS_WIFILI_HIGH_PRIORITY_SCHEME; + ts_db[core_id].nwtse[id].scheme_index = NSS_WIFILI_THREAD_SCHEME_ID_0; + break; + case 1: + ts_db[core_id].nwtse[id].scheme_priority = NSS_WIFILI_LOW_PRIORITY_SCHEME; + ts_db[core_id].nwtse[id].scheme_index = NSS_WIFILI_THREAD_SCHEME_ID_1; + break; + case 2: + case 3: + ts_db[core_id].nwtse[id].scheme_priority = NSS_WIFILI_HIGH_PRIORITY_SCHEME; + ts_db[core_id].nwtse[id].scheme_index = NSS_WIFILI_THREAD_SCHEME_ID_2; + break; + default: + nss_warning("Invalid scheme index:%d", id); + } + } +} + +/* + * nss_wifili_msg_init() + * Initialize nss_wifili_msg. + */ +void nss_wifili_msg_init(struct nss_wifili_msg *ncm, uint16_t if_num, uint32_t type, uint32_t len, void *cb, void *app_data) +{ + nss_cmn_msg_init(&ncm->cm, if_num, type, len, cb, app_data); +} +EXPORT_SYMBOL(nss_wifili_msg_init); + +/* + **************************************** + * Register/Unregister/Miscellaneous APIs + **************************************** + */ + +/* + * nss_register_wifili_if() + * Register wifili with nss driver + */ +struct nss_ctx_instance *nss_register_wifili_if(uint32_t if_num, nss_wifili_callback_t wifili_callback, + nss_wifili_callback_t wifili_ext_callback, + nss_wifili_msg_callback_t event_callback, struct net_device *netdev, uint32_t features) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id]; + + /* + * The interface number shall be wifili soc interface + */ + nss_assert((if_num == NSS_WIFILI_INTERNAL_INTERFACE) + || (if_num == NSS_WIFILI_EXTERNAL_INTERFACE0) + || (if_num == NSS_WIFILI_EXTERNAL_INTERFACE1)); + + nss_info("nss_register_wifili_if if_num %d wifictx %px", if_num, netdev); + + nss_core_register_subsys_dp(nss_ctx, if_num, wifili_callback, wifili_ext_callback, NULL, netdev, features); + + nss_top_main.wifili_msg_callback = event_callback; + + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id]; +} +EXPORT_SYMBOL(nss_register_wifili_if); + +/* + * nss_unregister_wifili_if() + * Unregister wifili with nss driver + */ +void nss_unregister_wifili_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id]; + + /* + * The interface number shall be wifili soc interface + */ + nss_assert((if_num == NSS_WIFILI_INTERNAL_INTERFACE) + || (if_num == NSS_WIFILI_EXTERNAL_INTERFACE0) + || (if_num == NSS_WIFILI_EXTERNAL_INTERFACE1)); + + nss_core_unregister_subsys_dp(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_unregister_wifili_if); + +/* + * nss_register_wifili_radio_if() + * Register wifili radio with nss driver + */ +struct nss_ctx_instance *nss_register_wifili_radio_if(uint32_t if_num, nss_wifili_callback_t wifili_callback, + nss_wifili_callback_t wifili_ext_callback, + nss_wifili_msg_callback_t event_callback, struct net_device *netdev, uint32_t features) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id]; + + /* + * The interface number shall be wifili radio dynamic interface + */ + nss_assert(nss_is_dynamic_interface(if_num)); + nss_info("nss_register_wifili_if if_num %d wifictx %px", if_num, netdev); + + nss_core_register_subsys_dp(nss_ctx, if_num, wifili_callback, wifili_ext_callback, NULL, netdev, features); + + return (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id]; +} +EXPORT_SYMBOL(nss_register_wifili_radio_if); + +/* + * nss_unregister_wifili_radio_if() + * Unregister wifili radio with nss driver + */ +void nss_unregister_wifili_radio_if(uint32_t if_num) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id]; + + /* + * The interface number shall be wifili radio dynamic interface + */ + nss_assert(nss_is_dynamic_interface(if_num)); + + nss_core_unregister_subsys_dp(nss_ctx, if_num); +} +EXPORT_SYMBOL(nss_unregister_wifili_radio_if); + +/* + * nss_wifili_register_handler() + * Register handle for notfication messages received on wifi interface + */ +void nss_wifili_register_handler(void) +{ + struct nss_ctx_instance *nss_ctx = (struct nss_ctx_instance *)&nss_top_main.nss[nss_top_main.wifi_handler_id]; + + nss_info("nss_wifili_register_handler"); + nss_core_register_handler(nss_ctx, NSS_WIFILI_INTERNAL_INTERFACE, nss_wifili_handler, NULL); + nss_core_register_handler(nss_ctx, NSS_WIFILI_EXTERNAL_INTERFACE0, nss_wifili_handler, NULL); + nss_core_register_handler(nss_ctx, NSS_WIFILI_EXTERNAL_INTERFACE1, nss_wifili_handler, NULL); + + nss_wifili_stats_dentry_create(); + nss_wifili_strings_dentry_create(); + + sema_init(&wifili_pvt.sem, 1); + init_completion(&wifili_pvt.complete); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_wifili_log.c b/feeds/ipq807x/qca-nss-drv/src/nss_wifili_log.c new file mode 100644 index 000000000..7c679dfca --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_wifili_log.c @@ -0,0 +1,553 @@ +/* + ************************************************************************** + * Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_wifili_log.c + * NSS WIFILI logger file. + */ + +#include "nss_core.h" + +/* + * nss_wifili_log_message_types_str + * WIFILI message strings + */ +static int8_t *nss_wifili_log_message_types_str[NSS_WIFILI_MAX_MSG] __maybe_unused = { + "WIFILI INIT MSG", + "WIFILI SOC RESET MSG", + "WIFILI PDEV INIT MSG", + "WIFILI PDEV DEINIT MSG", + "WIFILI START MSG", + "WIFILI STOP MSG", + "WIFILI PEER CREATE MSG", + "WIFILI PEER DELETE MSG", + "WIFILI SEND PEER MEMORY REQUEST MSG", + "WIFILI PEER FREELIST APPEND MSG", + "WIFILI STATS MSG", + "WIFILI WDS VENDOR MSG", + "WIFILI PEER STATS MSG", + "WIFILI WDS PEER ADD MSG", + "WIFILI WDS PEER DEL MSG", + "WIFILI WDS PEER MAP MSG", + "WIFILI WDS ACTIVE INFO MSG", + "WIFILI STATS CFG MSG", + "WIFILI TID REOQ SETUP MSG", + "WIFILI RADIO CMD MSG", + "WIFILI LINK DESC INFO MSG", + "WIFILI PEER SECURITY TYPE MSG", + "WIFILI PEER NAWDS ENABLE MSG", + "WIFILI RADIO BUF CFG", + "WIFILI DBDC REPEATER SET MSG", + "WIFILI DBDC REPEATER AST FLUSH MSG" +}; + +/* + * nss_wifili_log_error_response_types_str + * Strings for error types for WIFILI messages + */ +static int8_t *nss_wifili_log_error_response_types_str[NSS_WIFILI_EMSG_UNKNOWN] __maybe_unused = { + "WIFILI NO ERROR", + "WIFILI INIT FAIL IMPROPER STATE", + "WIFILI RINGS INIT FAIL", + "WIFILI PDEV INIT IMPROPER STATE FAIL", + "WIFILI PDEV INIT INVALID RADIOID FAIL", + "WIFILI PDEV TX IRQ ALLOC FAIL", + "WIFILI PDEV RESET INVALID RADIOID FAIL", + "WIFILI PDEV RESET PDEV NULL FAIL", + "WIFILI PDEV RESET IMPROPER STATE FAIL", + "WIFILI START IMPROPER STATE FAIL", + "WIFILI PEER CREATE FAIL", + "WIFILI PEER DELETE FAIL", + "WIFILI HASHMEM INIT FAIL", + "WIFILI PEER FREELIST APPEND FAIL", + "WIFILI PEER CREATE INVALID VDEVID FAIL", + "WIFILI PEER CREATE INVALID PEER ID FAIL", + "WIFILI PEER CREATE VDEV NULL FAIL", + "WIFILI PEER CREATE PDEV NULL FAIL", + "WIFILI PEER CREATE ALLOC FAIL", + "WIFILI PEER DELETE VAPID INVALID FAIL", + "WIFILI PEER DELETE INVALID PEERID FAIL", + "WIFILI PEER DELETE VDEV NULL FAIL", + "WIFILI PEER DELETE PDEV NULL FAIL", + "WIFILI PEER DELETE PEER NULL FAIL", + "WIFILI PEER DELETE PEER CORRUPTED FAIL", + "WIFILI PEER DUPLICATE AST INDEX PEER ID FAIL", + "WIFILI GROUP0 TIMER ALLOC FAIL", + "WIFILI INSUFFICIENT WT FAIL", + "WIFILI INVALID NUM TCL RING FAIL", + "WIFILI INVALID NUM REO DST RING FAIL", + "WIFILI HAL SRNG SOC ALLOC FAIL", + "WIFILI HAL SRNG INVALID RING INFO FAIL", + "WIFILI HAL SRNG TCL ALLOC FAIL", + "WIFILI HAL SRNG TXCOMP ALLOC FAIL", + "WIFILI HAL SRNG REODST ALLOC FAIL", + "WIFILI HAL SRNG REOREINJECT ALLOC FAIL", + "WIFILI HAL SRNG RXRELEASE ALLOC FAIL", + "WIFILI HAL SRNG RXEXCP ALLOC FAIL", + "WIFILI HAL TX MEMALLOC FAIL", + "WIFILI HAL TX INVLID POOL NUM FAIL", + "WIFILI HAL TX INVALID PAGE NUM FAIL", + "WIFILI HAL TX DESC MEM ALLOC FAIL", + "WIFILI HAL RX MEMALLOC FAIL", + "WIFILI PDEV RXDMA RING ALLOC FAIL", + "WIFILI NAWDSEN PEERID INVALID", + "WIFILI NAWDSEN PEER NULL", + "WIFILI NAWDSEN PEER CORRUPTED", + "WIFILI WDS PEER CFG FAIL", + "WIFILI RESET NO STOP", + "WIFILI HAL SRNG INVALID RING BASE FAIL", + "WIFILI PDEV RX INIT FAIL", + "WIFILI EMESG AST ADD FAIL", + "WIFILI EMESG AST REMOVE FAIL", + "WIFILI EMESG WDS ADD FAIL", + "WIFILI EMESG WDS REMOVE FAIL", + "WIFILI EMESG WDS MAP FAIL", + "WIFILI WDS INVALID PEERID FAIL", + "WIFILI WDS DUPLICATE AST INDEX PEER ID FAIL", + "WIFILI INVALID RADIO CMD", + "WIFILI INVALID RADIO IFNUM", + "WIFILI PEER SECURITY PEER NULL FAIL", + "WIFILI PEER SECURITY PEER CORRUPTED FAIL", + "WIFILI RADIO INVALID BUF CFG", +}; + +/* + * nss_wifili_log_wifili_hal_srng() + * Log NSS WIFILI HAL SRNG Information + */ +static void nss_wifili_log_wifili_hal_srng(struct nss_wifili_hal_srng_info *ring) +{ + int32_t i; + nss_trace("\tRing ID: %d\n" + "\tMAC ID: %d\n" + "\tRing base physical address: %x\n" + "\tNumber of entries: %d\n" + "\tFlags: %x\n" + "\tDirection: %d\n" + "\tEntry size: %d\n" + "\tLow Threshold: %d\n", + ring->ring_id, ring->mac_id, + ring->ring_base_paddr, ring->num_entries, + ring->flags, ring->ring_dir, + ring->entry_size, ring->low_threshold); + nss_trace("Ring Base Addresses:"); + for (i = 0; i < NSS_WIFILI_MAX_SRNG_REG_GROUPS_MSG; i++) { + nss_trace("\t%x", ring->hwreg_base[i]); + } +} + +/* + * nss_wifili_log_init_msg() + * Log NSS WIFILI Init message. + */ +static void nss_wifili_log_init_msg(struct nss_wifili_msg *nwm) +{ + struct nss_wifili_init_msg *nwim __maybe_unused = &nwm->msg.init; + int32_t i; + nss_trace("%px: NSS WIFILI Init Message:\n" + "WIFILI HAL Source Ring Base Address: %x\n" + "WIFILI HAL Source Ring Shadow Read Pointer Address: %x\n" + "WIFILI HAL Source Ring Shadow Write Pointer Address: %x\n" + "WIFILI Number of Transmit Classifier data rings: %d\n" + "WIFILI Number of reorder rings: %d\n" + "WIFILI Flags for SoC initialization: %d\n" + "WIFILI Tx descriptor initialization number of software descriptors: %d" + "WIFILI Tx descriptor initialization number of software extended descriptors: %d" + "WIFILI Tx descriptor initialization number of descriptor pools: %d" + "WIFILI Tx descriptor initialization number of memory addresses: %d" + "WIFILI Tx descriptor initialization extended descriptor page number: %d" + "WIFILI Tx descriptor initialization number of software secriptors for second radio: %d" + "WIFILI Tx descriptor initialization number of software extended descriptors for second radio: %d", + nwim, nwim->hssm.dev_base_addr, + nwim->hssm.shadow_rdptr_mem_addr, nwim->hssm.shadow_wrptr_mem_addr, + nwim->num_tcl_data_rings, nwim->num_reo_dest_rings, + nwim->flags, nwim->wtdim.num_tx_desc, + nwim->wtdim.num_tx_desc_ext, nwim->wtdim.num_pool, + nwim->wtdim.num_memaddr, nwim->wtdim.ext_desc_page_num, + nwim->wtdim.num_tx_desc_2, nwim->wtdim.num_tx_desc_ext_2); + /* + * Continuation of the log. + */ + nss_trace("WIFILI Tx descriptor initialization memory start address and size:"); + for (i = 0; i < NSS_WIFILI_MAX_NUMBER_OF_PAGE_MSG; i++) { + nss_trace("\tPage[%d]: Addr: %x Size: %d", i, nwim->wtdim.memory_addr[i], nwim->wtdim.memory_size[i]); + } + nss_trace("WIFILI Transmit Classifier data ring Information:"); + for (i = 0; i < NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG; i++) { + nss_wifili_log_wifili_hal_srng(&nwim->tcl_ring_info[i]); + } + nss_trace("WIFILI TX Completion Ring configuration information:"); + for (i = 0; i < NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG; i++) { + nss_wifili_log_wifili_hal_srng(&nwim->tx_comp_ring[i]); + } + nss_trace("WIFILI Reorder destination ring configuration information:"); + for (i = 0; i < NSS_WIFILI_MAX_REO_DATA_RINGS_MSG; i++) { + nss_wifili_log_wifili_hal_srng(&nwim->reo_dest_ring[i]); + } + nss_trace("WIFILI Reorder exception ring configuration information:"); + nss_wifili_log_wifili_hal_srng(&nwim->reo_exception_ring); + nss_trace("WIFILI Reinject ring configuration information:"); + nss_wifili_log_wifili_hal_srng(&nwim->reo_reinject_ring); +} + +/* + * nss_wifili_log_pdev_init_msg() + * Log NSS WIFILI PDEV Init message. + */ +static void nss_wifili_log_pdev_init_msg(struct nss_wifili_msg *nwm) +{ + struct nss_wifili_pdev_init_msg *nwim __maybe_unused = &nwm->msg.pdevmsg; + nss_trace("%px: NSS WIFILI PDEV Init Message:\n" + "WIFILI Radio ID: %x\n" + "WIFILI MAC Hardware Mode: %d\n" + "WIFILI Lower MAC ID: %x\n", + nwim, nwim->radio_id, + nwim->hwmode, nwim->lmac_id); + /* + * Continuation of the log. + */ + nss_trace("WIFILI Media Access Point ring information:"); + nss_wifili_log_wifili_hal_srng(&nwim->rxdma_ring); +} + +/* + * nss_wifili_log_pdev_init_msg() + * Log NSS WIFILI PDEV Deinit message. + */ +static void nss_wifili_log_pdev_deinit_msg(struct nss_wifili_msg *nwm) +{ + struct nss_wifili_pdev_deinit_msg *nwim __maybe_unused = &nwm->msg.pdevdeinit; + nss_trace("%px: NSS WIFILI PDEV Deinit Message:\n" + "WIFILI Interface Number: %d\n", + nwim, nwim->ifnum); +} + +/* + * nss_wifili_log_peer_msg() + * Log NSS WIFILI Peer message. + */ +static void nss_wifili_log_peer_msg(struct nss_wifili_msg *nwm) +{ + struct nss_wifili_peer_msg *nwim __maybe_unused = &nwm->msg.peermsg; + nss_trace("%px: NSS WIFILI Peer Message:\n" + "WIFILI Peer MAC Address: %pM\n" + "WIFILI VAP ID: %d\n" + "WIFILI Peed ID: %d\n" + "WIFILI Hardware address search table index: %d\n" + "WIFILI NAWDS enabled for peer: %d\n" + "WIFILI peer memory adderss for NSS: %x\n", + nwim, nwim->peer_mac_addr, + nwim->vdev_id, nwim->peer_id, + nwim->hw_ast_idx, nwim->is_nawds, + nwim->nss_peer_mem); +} + +/* + * nss_wifili_log_peer_freelist_append_msg() + * Log NSS WIFILI Peer memory request message. + */ +static void nss_wifili_log_peer_freelist_append_msg(struct nss_wifili_msg *nwm) +{ + struct nss_wifili_peer_freelist_append_msg *nwim __maybe_unused = &nwm->msg.peer_freelist_append; + nss_trace("%px: NSS WIFILI Peer Memory Request Message:\n" + "WIFILI Starting Address of Freelist: %x\n" + "WIFILI Length: %d\n" + "WIFILI Maximum number of peer entries supported in pool: %d\n", + nwim, nwim->addr, + nwim->length, nwim->num_peers); +} + +/* + * nss_wifili_log_wds_peer_msg() + * Log NSS WIFILI WDS Peer message. + */ +static void nss_wifili_log_wds_peer_msg(struct nss_wifili_msg *nwm) +{ + struct nss_wifili_wds_peer_msg *nwim __maybe_unused = &nwm->msg.wdspeermsg; + nss_trace("%px: NSS WIFILI WDS Peer Message:\n" + "WIFILI Destination MAC: %pM\n" + "WIFILI Peer MAC: %pM\n", + nwim, nwim->dest_mac, nwim->peer_mac); +} + +/* + * nss_wifili_log_wds_active_info_msg() + * Log NSS WIFILI WDS Active Info message. + */ +static void nss_wifili_log_wds_active_info_msg(struct nss_wifili_msg *nwm) +{ + struct nss_wifili_wds_active_info_msg *nwim __maybe_unused = &nwm->msg.wdsinfomsg; + nss_trace("%px: NSS WIFILI WDS Active Info Message:\n" + "WIFILI Number OF Entries: %d\n" + "WIFILI Hardware AST Index: %d\n", + nwim, nwim->nentries, nwim->info[0].ast_idx); +} + +/* + * nss_wifili_log_stats_cfg_msg() + * Log NSS WIFILI Stats Configuration Message. + */ +static void nss_wifili_log_stats_cfg_msg(struct nss_wifili_msg *nwm) +{ + struct nss_wifili_stats_cfg_msg *nwim __maybe_unused = &nwm->msg.scm; + nss_trace("%px: NSS WIFILI Stats Config Message:\n" + "WIFILI Enable/Disable Config: %d\n", + nwim, nwim->cfg); +} + +/* + * nss_wifili_log_reo_tidq_msg() + * Log NSS WIFILI REO TIDQ Setup Message. + */ +static void nss_wifili_log_reo_tidq_msg(struct nss_wifili_msg *nwm) +{ + struct nss_wifili_reo_tidq_msg *nwim __maybe_unused = &nwm->msg.reotidqmsg; + nss_trace("%px: NSS WIFILI reo tidq setup Message:\n" + "WIFILI Traffic Identification Value: %d\n" + "WIFILI Peer ID: %d\n", + nwim, nwim->tid, nwim->peer_id); +} + +/* + * nss_wifili_log_radio_cfg_msg() + * Log NSS WIFILI Radio Command Message. + */ +static void nss_wifili_log_radio_cfg_msg(struct nss_wifili_msg *nwm) +{ + struct nss_wifili_radio_cfg_msg *nwim __maybe_unused = &nwm->msg.radiocfgmsg; + nss_trace("%px: NSS WIFILI Radio Command Message:\n" + "WIFILI Radio Interface Number %d\n", + nwim, nwim->radio_if_num); +} + +/* + * nss_wifili_log_wds_extn_peer_cfg_msg() + * Log NSS WIFILI WDS vendor extension configuration message. + */ +static void nss_wifili_log_wds_extn_peer_cfg_msg(struct nss_wifili_msg *nwm) +{ + struct nss_wifili_wds_extn_peer_cfg_msg *nwim __maybe_unused = &nwm->msg.wpeercfg; + nss_trace("%px: NSS WIFILI WDS vendor extension configuration message:\n" + "WIFILI Peer MAC Addr: %pM\n" + "WIFILI WDS Flags: %d\n" + "WIFILI Peer ID: %d\n", + nwim, nwim->peer_mac_addr, + nwim->wds_flags, nwim->peer_id); +} + +/* + * nss_wifili_log_soc_linkdesc_buf_info_msg() + * Log NSS WIFILI Link descriptor buffer address information. + */ +static void nss_wifili_log_soc_linkdesc_buf_info_msg(struct nss_wifili_msg *nwm) +{ + struct nss_wifili_soc_linkdesc_buf_info_msg *nwim __maybe_unused = &nwm->msg.linkdescinfomsg; + nss_trace("%px: NSS WIFILI Link descriptor buffer address information:\n" + "WIFILI Link Descriptor Low Address: %x\n" + "WIFILI Link Descriptor High Address: %x\n", + nwim, nwim->buffer_addr_low, + nwim->buffer_addr_high); +} + +/* + * nss_wifili_log_peer_security_msg() + * Log NSS WIFILI Peer Security Message. + */ +static void nss_wifili_log_peer_security_msg(struct nss_wifili_msg *nwm) +{ + struct nss_wifili_peer_security_type_msg *nwim __maybe_unused = &nwm->msg.securitymsg; + int32_t i; + nss_trace("%px: NSS WIFILI Peer Security Message:\n" + "WIFILI Peer ID: %d\n" + "WIFILI Packet Type: %d\n" + "WIFILI Security Type: %d\n", + nwim, nwim->peer_id, + nwim->pkt_type, nwim->security_type); + /* + * Continuation of the log. + */ + nss_trace("WIFILI MIC KEY:"); + for (i = 0; i < NSS_WIFILI_MIC_KEY_LEN; i++) { + nss_trace("\t%x", nwim->mic_key[i]); + } +} + +/* + * nss_wifili_log_peer_nawds_enable_msg() + * Log NSS WIFILI NAWDS enable for peer. + */ +static void nss_wifili_log_peer_nawds_enable_msg(struct nss_wifili_msg *nwm) +{ + struct nss_wifili_peer_nawds_enable_msg *nwim __maybe_unused = &nwm->msg.nawdsmsg; + nss_trace("%px: NSS WIFILI NAWDS enable for peer:\n" + "WIFILI Peer ID: %d\n" + "WIFILI Enable NAWDS: %d\n", + nwim, nwim->peer_id, nwim->is_nawds); +} + +/* + * nss_wifili_log_dbdc_repeater_set_msg() + * Log NSS WIFILI DBDC Repeaster Enable Message + */ +static void nss_wifili_log_dbdc_repeater_set_msg(struct nss_wifili_msg *nwm) +{ + struct nss_wifili_dbdc_repeater_set_msg *nwim __maybe_unused = &nwm->msg.dbdcrptrmsg; + nss_trace("%px: NSS WIFILI DBDC Repeater Enable Message:\n" + "WIFILI DBDC Enable Flag: %d\n", + nwim, nwim->is_dbdc_en); +} + +/* + * nss_wifili_log_verbose() + * Log message contents. + */ +static void nss_wifili_log_verbose(struct nss_wifili_msg *nwm) +{ + switch (nwm->cm.type) { + case NSS_WIFILI_INIT_MSG: + nss_wifili_log_init_msg(nwm); + break; + + case NSS_WIFILI_SOC_RESET_MSG: + break; + + case NSS_WIFILI_PDEV_INIT_MSG: + nss_wifili_log_pdev_init_msg(nwm); + break; + + case NSS_WIFILI_PDEV_DEINIT_MSG: + nss_wifili_log_pdev_deinit_msg(nwm); + break; + + case NSS_WIFILI_PEER_CREATE_MSG: + case NSS_WIFILI_PEER_DELETE_MSG: + nss_wifili_log_peer_msg(nwm); + break; + + case NSS_WIFILI_PEER_FREELIST_APPEND_MSG: + nss_wifili_log_peer_freelist_append_msg(nwm); + break; + + case NSS_WIFILI_WDS_VENDOR_MSG: + nss_wifili_log_wds_extn_peer_cfg_msg(nwm); + break; + + case NSS_WIFILI_WDS_PEER_ADD_MSG: + case NSS_WIFILI_WDS_PEER_DEL_MSG: + case NSS_WIFILI_WDS_PEER_MAP_MSG: + nss_wifili_log_wds_peer_msg(nwm); + break; + + case NSS_WIFILI_WDS_ACTIVE_INFO_MSG: + nss_wifili_log_wds_active_info_msg(nwm); + break; + + case NSS_WIFILI_STATS_CFG_MSG: + nss_wifili_log_stats_cfg_msg(nwm); + break; + + case NSS_WIFILI_TID_REOQ_SETUP_MSG: + nss_wifili_log_reo_tidq_msg(nwm); + break; + + case NSS_WIFILI_RADIO_CMD_MSG: + nss_wifili_log_radio_cfg_msg(nwm); + break; + + case NSS_WIFILI_LINK_DESC_INFO_MSG: + nss_wifili_log_soc_linkdesc_buf_info_msg(nwm); + break; + + case NSS_WIFILI_PEER_SECURITY_TYPE_MSG: + nss_wifili_log_peer_security_msg(nwm); + break; + + case NSS_WIFILI_PEER_NAWDS_ENABLE_MSG: + nss_wifili_log_peer_nawds_enable_msg(nwm); + break; + + case NSS_WIFILI_DBDC_REPEATER_SET_MSG: + nss_wifili_log_dbdc_repeater_set_msg(nwm); + break; + + case NSS_WIFILI_SOJOURN_STATS_MSG: + case NSS_DBDC_REPEATER_AST_FLUSH_MSG: + case NSS_WIFILI_SEND_PEER_MEMORY_REQUEST_MSG: + case NSS_WIFILI_PEER_STATS_MSG: + case NSS_WIFILI_RADIO_BUF_CFG: + case NSS_WIFILI_STATS_MSG: + case NSS_WIFILI_START_MSG: + case NSS_WIFILI_STOP_MSG: + /* + * No log for these valid messages. + */ + break; + + default: + nss_warning("%px: Invalid message type\n", nwm); + break; + } +} + +/* + * nss_wifili_log_tx_msg() + * Log messages transmitted to FW. + */ +void nss_wifili_log_tx_msg(struct nss_wifili_msg *nwm) +{ + if (nwm->cm.type >= NSS_WIFILI_MAX_MSG) { + nss_warning("%px: Invalid message type\n", nwm); + return; + } + + nss_info("%px: type[%d]:%s\n", nwm, nwm->cm.type, nss_wifili_log_message_types_str[nwm->cm.type]); + nss_wifili_log_verbose(nwm); +} + +/* + * nss_wifili_log_rx_msg() + * Log messages received from FW. + */ +void nss_wifili_log_rx_msg(struct nss_wifili_msg *nwm) +{ + if (nwm->cm.response >= NSS_CMN_RESPONSE_LAST) { + nss_warning("%px: Invalid response\n", nwm); + return; + } + + if (nwm->cm.response == NSS_CMN_RESPONSE_NOTIFY || (nwm->cm.response == NSS_CMN_RESPONSE_ACK)) { + nss_info("%px: type[%d]:%s, response[%d]:%s\n", nwm, nwm->cm.type, + nss_wifili_log_message_types_str[nwm->cm.type], + nwm->cm.response, nss_cmn_response_str[nwm->cm.response]); + goto verbose; + } + + if (nwm->cm.error >= NSS_WIFILI_EMSG_UNKNOWN) { + nss_warning("%px: msg failure - type[%d]:%s, response[%d]:%s, error[%d]:Invalid error\n", + nwm, nwm->cm.type, nss_wifili_log_message_types_str[nwm->cm.type], + nwm->cm.response, nss_cmn_response_str[nwm->cm.response], + nwm->cm.error); + goto verbose; + } + + nss_info("%px: msg nack - type[%d]:%s, response[%d]:%s, error[%d]:%s\n", + nwm, nwm->cm.type, nss_wifili_log_message_types_str[nwm->cm.type], + nwm->cm.response, nss_cmn_response_str[nwm->cm.response], + nwm->cm.error, nss_wifili_log_error_response_types_str[nwm->cm.error]); + +verbose: + nss_wifili_log_verbose(nwm); +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_wifili_log.h b/feeds/ipq807x/qca-nss-drv/src/nss_wifili_log.h new file mode 100644 index 000000000..a381ab6cf --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_wifili_log.h @@ -0,0 +1,37 @@ +/* + ****************************************************************************** + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * **************************************************************************** + */ + +#ifndef __NSS_WIFILI_LOG_H__ +#define __NSS_WIFILI_LOG_H__ + +/* + * nss_WIFILI_log.h + * NSS WIFILI Log Header File + */ + +/* + * nss_WIFILI_log_tx_msg + * Logs a WIFILI message that is sent to the NSS firmware. + */ +void nss_wifili_log_tx_msg(struct nss_wifili_msg *ncm); + +/* + * nss_WIFILI_log_rx_msg + * Logs a WIFILI message that is received from the NSS firmware. + */ +void nss_wifili_log_rx_msg(struct nss_wifili_msg *ncm); + +#endif /* __NSS_WIFILI_LOG_H__ */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_wifili_stats.c b/feeds/ipq807x/qca-nss-drv/src/nss_wifili_stats.c new file mode 100644 index 000000000..add36990d --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_wifili_stats.c @@ -0,0 +1,512 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_wifili_stats.c + * NSS wifili statistics APIs + */ + +#include "nss_tx_rx_common.h" +#include "nss_core.h" +#include "nss_wifili_if.h" +#include "nss_wifili_stats.h" +#include "nss_wifili_strings.h" + +/* + * Declare atomic notifier data structure for statistics. + */ +ATOMIC_NOTIFIER_HEAD(nss_wifili_stats_notifier); + +/* + * Statistics structures + * The structure will hold the statistics for 3 SOCs. + */ +struct nss_wifili_soc_stats soc_stats[NSS_WIFILI_MAX_SOC_NUM]; + +/* + * nss_wifili_stats_read() + * Read wifili statistics + */ +static ssize_t nss_wifili_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + uint32_t i; + + /* + * max output lines = ((#stats + eight blank lines) * #WIFILI #STATS) + start/end tag + 3 blank + * + Number of Extra outputlines for future reference to add new stats + */ + uint32_t max_pdev = 0; + uint32_t max_output_lines; + size_t size_al = 0; + size_t size_wr = 0; + ssize_t bytes_read = 0; + char *lbuf = NULL; + uint32_t soc_idx; + struct nss_wifili_stats *stats_wifili = NULL; + + /* + * Max number of pdev depends on type of soc (Internal/Attached). + */ + for (soc_idx = 0; soc_idx < NSS_WIFILI_MAX_SOC_NUM; soc_idx++) { + max_pdev += soc_stats[soc_idx].soc_maxpdev; + } + + /* + * Max pdev cannot be null. + */ + if (unlikely(max_pdev == 0)) { + nss_warning("Cannot have max pdev zero "); + return 0; + } + + max_output_lines = (((NSS_WIFILI_STATS_MAX + 9) * max_pdev) + + NSS_WIFILI_STATS_WBM_MAX + NSS_STATS_EXTRA_OUTPUT_LINES); + + size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines; + + lbuf = kzalloc(size_al, GFP_KERNEL); + if (unlikely(lbuf == NULL)) { + nss_warning("Could not allocate memory for local statistics buffer"); + return 0; + } + + size_wr += nss_stats_banner(lbuf, size_wr, size_al, "wifili", NSS_STATS_SINGLE_CORE); + + for (soc_idx = 0; soc_idx < NSS_WIFILI_MAX_SOC_NUM; soc_idx++) { + stats_wifili = &(soc_stats[soc_idx].stats_wifili); + for (i = 0; i < soc_stats[soc_idx].soc_maxpdev; i++) { + + spin_lock_bh(&nss_top_main.stats_lock); + size_wr += nss_stats_print("wifili", "txrx", i + , nss_wifili_strings_stats_txrx + , stats_wifili->stats_txrx[i] + , NSS_WIFILI_STATS_TXRX_MAX + , lbuf, size_wr, size_al); + spin_unlock_bh(&nss_top_main.stats_lock); + size_wr += scnprintf(lbuf + size_wr + , size_al - size_wr, "\n"); + + /* + * Filling TCL ring stats + */ + spin_lock_bh(&nss_top_main.stats_lock); + size_wr += nss_stats_print("wifili", "tcl ring", i + , nss_wifili_strings_stats_tcl + , stats_wifili->stats_tcl_ring[i] + , NSS_WIFILI_STATS_TCL_MAX + , lbuf, size_wr, size_al); + spin_unlock_bh(&nss_top_main.stats_lock); + size_wr += scnprintf(lbuf + size_wr + , size_al - size_wr, "\n"); + + /* + * Filling TCL comp stats + */ + spin_lock_bh(&nss_top_main.stats_lock); + size_wr += nss_stats_print("wifili", "tcl comp", i + , nss_wifili_strings_stats_tx_comp + , stats_wifili->stats_tx_comp[i] + , NSS_WIFILI_STATS_TX_DESC_FREE_MAX + , lbuf, size_wr, size_al); + spin_unlock_bh(&nss_top_main.stats_lock); + size_wr += scnprintf(lbuf + size_wr + , size_al - size_wr, "\n"); + + /* + * Filling reo ring stats + */ + spin_lock_bh(&nss_top_main.stats_lock); + size_wr += nss_stats_print("wifili", "reo ring", i + , nss_wifili_strings_stats_reo + , stats_wifili->stats_reo[i] + , NSS_WIFILI_STATS_REO_MAX + , lbuf, size_wr, size_al); + + spin_unlock_bh(&nss_top_main.stats_lock); + size_wr += scnprintf(lbuf + size_wr + , size_al - size_wr, "\n"); + + /* + * Filling TX SW Pool + */ + spin_lock_bh(&nss_top_main.stats_lock); + size_wr += nss_stats_print("wifili", "tx sw pool", i + , nss_wifili_strings_stats_txsw_pool + , stats_wifili->stats_tx_desc[i] + , NSS_WIFILI_STATS_TX_DESC_MAX + , lbuf, size_wr, size_al); + spin_unlock_bh(&nss_top_main.stats_lock); + size_wr += scnprintf(lbuf + size_wr + , size_al - size_wr, "\n"); + + /* + * Filling TX EXt SW Pool + */ + spin_lock_bh(&nss_top_main.stats_lock); + size_wr += nss_stats_print("wifili", "tx ext sw pool", i + , nss_wifili_strings_stats_ext_txsw_pool + , stats_wifili->stats_ext_tx_desc[i] + , NSS_WIFILI_STATS_EXT_TX_DESC_MAX + , lbuf, size_wr, size_al); + spin_unlock_bh(&nss_top_main.stats_lock); + size_wr += scnprintf(lbuf + size_wr + , size_al - size_wr, "\n"); + + /* + * Filling rxdma pool stats + */ + spin_lock_bh(&nss_top_main.stats_lock); + size_wr += nss_stats_print("wifili", "rxdma pool", i + , nss_wifili_strings_stats_rxdma_pool + , stats_wifili->stats_rx_desc[i] + , NSS_WIFILI_STATS_RX_DESC_MAX + , lbuf, size_wr, size_al); + spin_unlock_bh(&nss_top_main.stats_lock); + size_wr += scnprintf(lbuf + size_wr + , size_al - size_wr, "\n"); + + /* + * Filling rxdma ring stats + */ + spin_lock_bh(&nss_top_main.stats_lock); + size_wr += nss_stats_print("wifili", "rxdma ring", i + , nss_wifili_strings_stats_rxdma_ring + , stats_wifili->stats_rxdma[i] + , NSS_WIFILI_STATS_RXDMA_DESC_MAX + , lbuf, size_wr, size_al); + spin_unlock_bh(&nss_top_main.stats_lock); + size_wr += scnprintf(lbuf + size_wr + , size_al - size_wr, "\n"); + } + + /* + * Filling wbm ring stats + */ + spin_lock_bh(&nss_top_main.stats_lock); + size_wr += nss_stats_print("wifili", "wbm ring" + , NSS_STATS_SINGLE_INSTANCE + , nss_wifili_strings_stats_wbm + , stats_wifili->stats_wbm + , NSS_WIFILI_STATS_WBM_MAX + , lbuf, size_wr, size_al); + spin_unlock_bh(&nss_top_main.stats_lock); + size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n"); + } + + bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf)); + kfree(lbuf); + + return bytes_read; +} + +/* + * wifili_stats_ops + */ +NSS_STATS_DECLARE_FILE_OPERATIONS(wifili); + +/* + * nss_wifili_stats_dentry_create() + * Create wifili statistics debug entry. + */ +void nss_wifili_stats_dentry_create(void) +{ + nss_stats_create_dentry("wifili", &nss_wifili_stats_ops); +} + +/* + * nss_wifili_stats_sync() + * Handle the syncing of WIFI stats. + */ +void nss_wifili_stats_sync(struct nss_ctx_instance *nss_ctx, + struct nss_wifili_stats_sync_msg *wlsoc_stats, uint16_t interface) +{ + struct nss_top_instance *nss_top = nss_ctx->nss_top; + struct nss_wifili_soc_stats *nwss = NULL; + struct nss_wifili_stats *stats = NULL; + struct nss_wifili_device_stats *devstats = &wlsoc_stats->stats; + uint32_t index; + + /* + * Max number of pdev depends on type of soc (Internal/Attached). + */ + switch (interface) { + case NSS_WIFILI_INTERNAL_INTERFACE: + nwss = &soc_stats[0]; + nwss->soc_maxpdev = NSS_WIFILI_MAX_PDEV_NUM_MSG; + break; + + case NSS_WIFILI_EXTERNAL_INTERFACE0: + nwss = &soc_stats[1]; + nwss->soc_maxpdev = NSS_WIFILI_SOC_ATTACHED_MAX_PDEV_NUM; + break; + + case NSS_WIFILI_EXTERNAL_INTERFACE1: + nwss = &soc_stats[2]; + nwss->soc_maxpdev = NSS_WIFILI_SOC_ATTACHED_MAX_PDEV_NUM; + break; + + default: + nss_warning("%px: Invalid wifili interface\n", nss_ctx); + return; + } + + /* + * Wifili statistics structure. + */ + stats = &(nwss->stats_wifili); + + spin_lock_bh(&nss_top->stats_lock); + + for (index = 0; index < nwss->soc_maxpdev; index++) { + /* + * Rx stats + */ + stats->stats_txrx[index][NSS_WIFILI_STATS_RX_MSDU_ERROR] += + devstats->rx_data_stats[index].rx_msdu_err; + stats->stats_txrx[index][NSS_WIFILI_STATS_RX_INV_PEER_RCV] += + (devstats->rx_data_stats[index].rx_inv_peer + + devstats->rx_data_stats[index].rx_scatter_inv_peer); + stats->stats_txrx[index][NSS_WIFILI_STATS_RX_WDS_SRCPORT_EXCEPTION] += + devstats->rx_data_stats[index].rx_wds_learn_send; + stats->stats_txrx[index][NSS_WIFILI_STATS_RX_WDS_SRCPORT_EXCEPTION_FAIL] += + devstats->rx_data_stats[index].rx_wds_learn_send_fail; + stats->stats_txrx[index][NSS_WIFILI_STATS_RX_DELIVERD] += + devstats->rx_data_stats[index].rx_deliver_cnt; + stats->stats_txrx[index][NSS_WIFILI_STATS_RX_DELIVER_DROPPED] += + devstats->rx_data_stats[index].rx_deliver_cnt_fail; + stats->stats_txrx[index][NSS_WIFILI_STATS_RX_INTRA_BSS_UCAST] += + devstats->rx_data_stats[index].rx_intra_bss_ucast_send; + stats->stats_txrx[index][NSS_WIFILI_STATS_RX_INTRA_BSS_UCAST_FAIL] += + devstats->rx_data_stats[index].rx_intra_bss_ucast_send_fail; + stats->stats_txrx[index][NSS_WIFILI_STATS_RX_INTRA_BSS_MCAST] += + devstats->rx_data_stats[index].rx_intra_bss_mcast_send; + stats->stats_txrx[index][NSS_WIFILI_STATS_RX_INTRA_BSS_MCAST_FAIL] += + devstats->rx_data_stats[index].rx_intra_bss_mcast_send_fail; + stats->stats_txrx[index][NSS_WIFILI_STATS_RX_SG_RCV_SEND] += + devstats->rx_data_stats[index].rx_sg_recv_send; + stats->stats_txrx[index][NSS_WIFILI_STATS_RX_SG_RCV_FAIL] += + devstats->rx_data_stats[index].rx_sg_recv_fail; + stats->stats_txrx[index][NSS_STATS_WIFILI_RX_MCAST_ECHO] += + devstats->rx_data_stats[index].rx_me_pkts; + stats->stats_txrx[index][NSS_STATS_WIFILI_RX_INV_TID] += + devstats->rx_data_stats[index].rx_inv_tid; + stats->stats_txrx[index][NSS_WIFILI_STATS_RX_FRAG_INV_SC] += + devstats->rx_data_stats[index].rx_frag_inv_sc; + stats->stats_txrx[index][NSS_WIFILI_STATS_RX_FRAG_INV_FC] += + devstats->rx_data_stats[index].rx_frag_inv_fc; + stats->stats_txrx[index][NSS_WIFILI_STATS_RX_FRAG_NON_FRAG] += + devstats->rx_data_stats[index].rx_non_frag_err; + stats->stats_txrx[index][NSS_WIFILI_STATS_RX_FRAG_RETRY] += + devstats->rx_data_stats[index].rx_repeat_fragno; + stats->stats_txrx[index][NSS_WIFILI_STATS_RX_FRAG_OOO] += + devstats->rx_data_stats[index].rx_ooo_frag; + stats->stats_txrx[index][NSS_WIFILI_STATS_RX_FRAG_OOO_SEQ] += + devstats->rx_data_stats[index].rx_ooo_frag_seq; + stats->stats_txrx[index][NSS_WIFILI_STATS_RX_FRAG_ALL_FRAG_RCV] += + devstats->rx_data_stats[index].rx_all_frag_rcv; + stats->stats_txrx[index][NSS_WIFILI_STATS_RX_FRAG_DELIVER] += + devstats->rx_data_stats[index].rx_frag_deliver; + + /* + * Tx stats + */ + stats->stats_txrx[index][NSS_WIFILI_STATS_TX_ENQUEUE] += + devstats->tx_data_stats[index].tx_enqueue_cnt; + stats->stats_txrx[index][NSS_WIFILI_STATS_TX_ENQUEUE_DROP] += + devstats->tx_data_stats[index].tx_enqueue_dropped; + stats->stats_txrx[index][NSS_WIFILI_STATS_TX_DEQUEUE] += + devstats->tx_data_stats[index].tx_dequeue_cnt; + stats->stats_txrx[index][NSS_WIFILI_STATS_TX_HW_ENQUEUE_FAIL] += + devstats->tx_data_stats[index].tx_send_fail_cnt; + stats->stats_txrx[index][NSS_WIFILI_STATS_TX_SENT_COUNT] += + devstats->tx_data_stats[index].tx_processed_pkt; + } + + /* + * update the tcl ring stats + */ + for (index = 0; index < NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG; index++) { + stats->stats_tcl_ring[index][NSS_WIFILI_STATS_TCL_NO_HW_DESC] += + devstats->tcl_stats[index].tcl_no_hw_desc; + stats->stats_tcl_ring[index][NSS_WIFILI_STATS_TCL_RING_FULL] += + devstats->tcl_stats[index].tcl_ring_full; + stats->stats_tcl_ring[index][NSS_WIFILI_STATS_TCL_RING_SENT] += + devstats->tcl_stats[index].tcl_ring_sent; + } + + /* + * update the tcl comp stats + */ + for (index = 0; index < NSS_WIFILI_MAX_TCL_DATA_RINGS_MSG; index++) { + stats->stats_tx_comp[index][NSS_WIFILI_STATS_TX_DESC_FREE_INV_BUFSRC] += + devstats->txcomp_stats[index].invalid_bufsrc; + stats->stats_tx_comp[index][NSS_WIFILI_STATS_TX_DESC_FREE_INV_COOKIE] += + devstats->txcomp_stats[index].invalid_cookie; + stats->stats_tx_comp[index][NSS_WIFILI_STATS_TX_DESC_FREE_HW_RING_EMPTY] += + devstats->txcomp_stats[index].hw_ring_empty; + stats->stats_tx_comp[index][NSS_WIFILI_STATS_TX_DESC_FREE_REAPED] += + devstats->txcomp_stats[index].ring_reaped; + } + + /* + * update reo ring stats + */ + for (index = 0; index < NSS_WIFILI_MAX_REO_DATA_RINGS_MSG; index++) { + stats->stats_reo[index][NSS_WIFILI_STATS_REO_ERROR] += + devstats->rxreo_stats[index].ring_error; + stats->stats_reo[index][NSS_WIFILI_STATS_REO_REAPED] += + devstats->rxreo_stats[index].ring_reaped; + stats->stats_reo[index][NSS_WIFILI_STATS_REO_INV_COOKIE] += + devstats->rxreo_stats[index].invalid_cookie; + stats->stats_reo[index][NSS_WIFILI_STATS_REO_FRAG_RCV] += + devstats->rxreo_stats[index].defrag_reaped; + } + + /* + * update tx sw pool + */ + for (index = 0; index < NSS_WIFILI_MAX_TXDESC_POOLS_MSG; index++) { + stats->stats_tx_desc[index][NSS_WIFILI_STATS_TX_DESC_IN_USE] = + devstats->tx_sw_pool_stats[index].desc_alloc; + stats->stats_tx_desc[index][NSS_WIFILI_STATS_TX_DESC_ALLOC_FAIL] += + devstats->tx_sw_pool_stats[index].desc_alloc_fail; + stats->stats_tx_desc[index][NSS_WIFILI_STATS_TX_DESC_ALREADY_ALLOCATED] += + devstats->tx_sw_pool_stats[index].desc_already_allocated; + stats->stats_tx_desc[index][NSS_WIFILI_STATS_TX_DESC_INVALID_FREE] += + devstats->tx_sw_pool_stats[index].desc_invalid_free; + stats->stats_tx_desc[index][NSS_WIFILI_STATS_TX_DESC_FREE_SRC_FW] += + devstats->tx_sw_pool_stats[index].tx_rel_src_fw; + stats->stats_tx_desc[index][NSS_WIFILI_STATS_TX_DESC_FREE_COMPLETION] += + devstats->tx_sw_pool_stats[index].tx_rel_tx_desc; + stats->stats_tx_desc[index][NSS_WIFILI_STATS_TX_DESC_NO_PB] += + devstats->tx_sw_pool_stats[index].tx_rel_no_pb; + stats->stats_tx_desc[index][NSS_WIFILI_STATS_TX_QUEUELIMIT_DROP] += + devstats->tx_sw_pool_stats[index].tx_queue_limit_drop; + } + + /* + * update ext tx desc pool stats + */ + for (index = 0; index < NSS_WIFILI_MAX_TX_EXT_DESC_POOLS_MSG; index++) { + stats->stats_ext_tx_desc[index][NSS_WIFILI_STATS_EXT_TX_DESC_IN_USE] = + devstats->tx_ext_sw_pool_stats[index].desc_alloc; + stats->stats_ext_tx_desc[index][NSS_WIFILI_STATS_EXT_TX_DESC_ALLOC_FAIL] += + devstats->tx_ext_sw_pool_stats[index].desc_alloc_fail; + stats->stats_ext_tx_desc[index][NSS_WIFILI_STATS_EXT_TX_DESC_ALREADY_ALLOCATED] += + devstats->tx_ext_sw_pool_stats[index].desc_already_allocated; + stats->stats_ext_tx_desc[index][NSS_WIFILI_STATS_EXT_TX_DESC_INVALID_FREE] += + devstats->tx_ext_sw_pool_stats[index].desc_invalid_free; + } + + /* + * update rx desc pool stats + */ + for (index = 0; index < nwss->soc_maxpdev; index++) { + stats->stats_rx_desc[index][NSS_WIFILI_STATS_RX_DESC_NO_PB] += + devstats->rx_sw_pool_stats[index].rx_no_pb; + stats->stats_rx_desc[index][NSS_WIFILI_STATS_RX_DESC_ALLOC_FAIL] += + devstats->rx_sw_pool_stats[index].desc_alloc_fail; + stats->stats_rx_desc[index][NSS_WIFILI_STATS_RX_DESC_IN_USE] = + devstats->rx_sw_pool_stats[index].desc_alloc; + } + + /* + * update rx dma ring stats + */ + for (index = 0; index < nwss->soc_maxpdev; index++) { + stats->stats_rxdma[index][NSS_WIFILI_STATS_RXDMA_DESC_UNAVAILABLE] += + devstats->rxdma_stats[index].rx_hw_desc_unavailable; + stats->stats_rxdma[index][NSS_WIFILI_STATS_RXDMA_BUF_REPLENISHED] += + devstats->rxdma_stats[index].rx_buf_replenished; + } + + /* + * update wbm ring stats + */ + stats->stats_wbm[NSS_WIFILI_STATS_WBM_IE_LOCAL_ALLOC_FAIL] += devstats->rxwbm_stats.invalid_buf_mgr; + stats->stats_wbm[NSS_WIFILI_STATS_WBM_SRC_DMA] += devstats->rxwbm_stats.err_src_rxdma; + stats->stats_wbm[NSS_WIFILI_STATS_WBM_SRC_DMA_CODE_INV] += devstats->rxwbm_stats.err_src_rxdma_code_inv; + stats->stats_wbm[NSS_WIFILI_STATS_WBM_SRC_REO] += devstats->rxwbm_stats.err_src_reo; + stats->stats_wbm[NSS_WIFILI_STATS_WBM_SRC_REO_CODE_NULLQ] += devstats->rxwbm_stats.err_src_reo_code_nullq; + stats->stats_wbm[NSS_WIFILI_STATS_WBM_SRC_REO_CODE_INV] += devstats->rxwbm_stats.err_src_reo_code_inv; + stats->stats_wbm[NSS_WIFILI_STATS_WBM_SRC_INV] += devstats->rxwbm_stats.err_src_invalid; + spin_unlock_bh(&nss_top->stats_lock); + return; +} + +/* + * nss_wifili_stats_notify() + * Sends notifications to the registered modules. + * + * Leverage NSS-FW statistics timing to update Netlink. + */ +void nss_wifili_stats_notify(struct nss_ctx_instance *nss_ctx, uint32_t if_num) +{ + struct nss_wifili_stats_notification *wifili_stats; + uint32_t index = 0; + + wifili_stats = kzalloc(sizeof(struct nss_wifili_stats_notification), GFP_KERNEL); + if (!wifili_stats) { + nss_warning("%px: Failed to allocate memory for wifili stats\n", nss_ctx); + return; + } + + wifili_stats->core_id = nss_ctx->id; + switch (if_num) { + case NSS_WIFILI_INTERNAL_INTERFACE: + index = 0; + break; + + case NSS_WIFILI_EXTERNAL_INTERFACE0: + index = 1; + break; + + case NSS_WIFILI_EXTERNAL_INTERFACE1: + index = 2; + break; + + default: + nss_warning("%px: Invalid wifili interface\n", nss_ctx); + goto done; + } + wifili_stats->if_num = if_num; + memcpy(&wifili_stats->stats, &soc_stats[index].stats_wifili, sizeof(wifili_stats->stats)); + atomic_notifier_call_chain(&nss_wifili_stats_notifier, NSS_STATS_EVENT_NOTIFY, (void *)wifili_stats); + +done: + kfree(wifili_stats); + return; +} + +/* + * nss_wifili_stats_register_notifier() + * Registers statistics notifier. + */ +int nss_wifili_stats_register_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&nss_wifili_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_wifili_stats_register_notifier); + +/* + * nss_wifili_stats_unregister_notifier() + * Deregisters statistics notifier. + */ +int nss_wifili_stats_unregister_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&nss_wifili_stats_notifier, nb); +} +EXPORT_SYMBOL(nss_wifili_stats_unregister_notifier); diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_wifili_stats.h b/feeds/ipq807x/qca-nss-drv/src/nss_wifili_stats.h new file mode 100644 index 000000000..9c073ce8d --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_wifili_stats.h @@ -0,0 +1,35 @@ +/* + ************************************************************************** + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +/* + * nss_wifili_stats.h + * NSS wifili statistics header file. + */ + +#ifndef __NSS_WIFILI_STATS_H +#define __NSS_WIFILI_STATS_H + +#include "nss_core.h" +#include "nss_wifili_if.h" + +/* + * NSS wifili statistics APIs + */ +extern void nss_wifili_stats_notify(struct nss_ctx_instance *nss_ctx, uint32_t if_num); +extern void nss_wifili_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_wifili_stats_sync_msg *wlsoc_stats, uint16_t interface); +extern void nss_wifili_stats_dentry_create(void); + +#endif /* __NSS_WIFILI_STATS_H */ diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_wifili_strings.c b/feeds/ipq807x/qca-nss-drv/src/nss_wifili_strings.c new file mode 100644 index 000000000..3828221bd --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_wifili_strings.c @@ -0,0 +1,366 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#include "nss_stats.h" +#include "nss_core.h" +#include +#include "nss_strings.h" +#include "nss_wifili_strings.h" + +/* + * nss_wifili_strings_stats_txrx + * wifili txrx statistics + */ +struct nss_stats_info nss_wifili_strings_stats_txrx[NSS_WIFILI_STATS_TXRX_MAX] = { + {"rx_msdu_error" , NSS_STATS_TYPE_ERROR}, + {"rx_inv_peer_rcv" , NSS_STATS_TYPE_SPECIAL}, + {"rx_wds_srcport_exception" , NSS_STATS_TYPE_EXCEPTION}, + {"rx_wds_srcport_exception_fail" , NSS_STATS_TYPE_DROP}, + {"rx_deliverd" , NSS_STATS_TYPE_SPECIAL}, + {"rx_deliver_drops" , NSS_STATS_TYPE_DROP}, + {"rx_intra_bss_ucast" , NSS_STATS_TYPE_SPECIAL}, + {"rx_intra_bss_ucast_fail" , NSS_STATS_TYPE_DROP}, + {"rx_intra_bss_mcast" , NSS_STATS_TYPE_SPECIAL}, + {"rx_intra_bss_mcast_fail" , NSS_STATS_TYPE_DROP}, + {"rx_sg_rcv_send" , NSS_STATS_TYPE_SPECIAL}, + {"rx_sg_rcv_fail" , NSS_STATS_TYPE_DROP}, + {"rx_mcast_echo" , NSS_STATS_TYPE_SPECIAL}, + {"rx_inv_tid" , NSS_STATS_TYPE_SPECIAL}, + {"stats_rx_frag_inv_sc" , NSS_STATS_TYPE_SPECIAL}, + {"stats_rx_frag_inv_fc" , NSS_STATS_TYPE_SPECIAL}, + {"stats_rx_frag_non_frag" , NSS_STATS_TYPE_SPECIAL}, + {"stats_rx_frag_retry" , NSS_STATS_TYPE_SPECIAL}, + {"stats_rx_frag_ooo" , NSS_STATS_TYPE_SPECIAL}, + {"stats_rx_frag_ooo_seq" , NSS_STATS_TYPE_SPECIAL}, + {"stats_rx_frag_all_frag_rcv" , NSS_STATS_TYPE_SPECIAL}, + {"stats_rx_frag_deliver" , NSS_STATS_TYPE_SPECIAL}, + {"tx_enqueue" , NSS_STATS_TYPE_SPECIAL}, + {"tx_enqueue_drop" , NSS_STATS_TYPE_DROP}, + {"tx_dequeue" , NSS_STATS_TYPE_SPECIAL}, + {"tx_hw_enqueue_fail" , NSS_STATS_TYPE_DROP}, + {"tx_sent_count" , NSS_STATS_TYPE_SPECIAL} +}; + +/* + * nss_wifili_strings_stats_tcl + * wifili tcl stats + */ +struct nss_stats_info nss_wifili_strings_stats_tcl[NSS_WIFILI_STATS_TCL_MAX] = { + {"tcl_no_hw_desc" , NSS_STATS_TYPE_SPECIAL}, + {"tcl_ring_full" , NSS_STATS_TYPE_SPECIAL}, + {"tcl_ring_sent" , NSS_STATS_TYPE_SPECIAL} +}; + +/* + * nss_wifili_strings_stats_tx_comp + * wifili tx comp stats + */ +struct nss_stats_info nss_wifili_strings_stats_tx_comp[NSS_WIFILI_STATS_TX_DESC_FREE_MAX] = { + {"tx_desc_free_inv_bufsrc" , NSS_STATS_TYPE_ERROR}, + {"tx_desc_free_inv_cookie" , NSS_STATS_TYPE_SPECIAL}, + {"tx_desc_free_hw_ring_empty" , NSS_STATS_TYPE_SPECIAL}, + {"tx_desc_free_reaped" , NSS_STATS_TYPE_SPECIAL} +}; + +/* + * nss_wifili_strings_stats_reo + * wifili tx reo stats + */ +struct nss_stats_info nss_wifili_strings_stats_reo[NSS_WIFILI_STATS_REO_MAX] = { + {"reo_error" , NSS_STATS_TYPE_ERROR}, + {"reo_reaped" , NSS_STATS_TYPE_SPECIAL}, + {"reo_inv_cookie" , NSS_STATS_TYPE_SPECIAL}, + {"stats_reo_frag_rcv" , NSS_STATS_TYPE_SPECIAL} +}; + +/* + * nss_wifili_strings_stats_txsw_pool + * wifili tx desc stats + */ +struct nss_stats_info nss_wifili_strings_stats_txsw_pool[NSS_WIFILI_STATS_TX_DESC_MAX] = { + {"tx_desc_in_use" , NSS_STATS_TYPE_SPECIAL}, + {"tx_desc_alloc_fail" , NSS_STATS_TYPE_SPECIAL}, + {"tx_desc_already_allocated" , NSS_STATS_TYPE_SPECIAL}, + {"tx_desc_invalid_free" , NSS_STATS_TYPE_SPECIAL}, + {"tx_desc_free_src_fw" , NSS_STATS_TYPE_SPECIAL}, + {"tx_desc_free_completion" , NSS_STATS_TYPE_SPECIAL}, + {"tx_desc_no_pb" , NSS_STATS_TYPE_SPECIAL}, + {"tx_desc_queuelimit_drop" , NSS_STATS_TYPE_DROP} +}; + +/* + * nss_wifili_strings_stats_ext_txsw_pool + * wifili tx ext desc stats + */ +struct nss_stats_info nss_wifili_strings_stats_ext_txsw_pool[NSS_WIFILI_STATS_EXT_TX_DESC_MAX] = { + {"ext_tx_desc_in_use" , NSS_STATS_TYPE_SPECIAL}, + {"ext_tx_desc_alloc_fail" , NSS_STATS_TYPE_SPECIAL}, + {"ext_tx_desc_already_allocated" , NSS_STATS_TYPE_SPECIAL}, + {"ext_tx_desc_invalid_free" , NSS_STATS_TYPE_SPECIAL} +}; + +/* + * nss_wifili_strings_stats_rxdma_pool + * wifili rx desc stats + */ +struct nss_stats_info nss_wifili_strings_stats_rxdma_pool[NSS_WIFILI_STATS_RX_DESC_MAX] = { + {"rx_desc_no_pb" , NSS_STATS_TYPE_SPECIAL}, + {"rx_desc_alloc_fail" , NSS_STATS_TYPE_SPECIAL}, + {"rx_desc_in_use" , NSS_STATS_TYPE_SPECIAL} +}; + +/* + * nss_wifili_strings_stats_rxdma_ring + * wifili rx dma ring stats + */ +struct nss_stats_info nss_wifili_strings_stats_rxdma_ring[NSS_WIFILI_STATS_RXDMA_DESC_MAX] = { + {"rxdma_hw_desc_unavailable" , NSS_STATS_TYPE_SPECIAL}, + {"rxdma_buf_replenished" , NSS_STATS_TYPE_SPECIAL} +}; + +/* + * nss_wifili_strings_stats_wbm + * wifili wbm ring stats + */ +struct nss_stats_info nss_wifili_strings_stats_wbm[NSS_WIFILI_STATS_WBM_MAX] = { + {"wbm_ie_local_alloc_fail" , NSS_STATS_TYPE_ERROR}, + {"wbm_src_dma" , NSS_STATS_TYPE_SPECIAL}, + {"wbm_src_dma_code_inv" , NSS_STATS_TYPE_SPECIAL}, + {"wbm_src_reo" , NSS_STATS_TYPE_SPECIAL}, + {"wbm_src_reo_code_nullq" , NSS_STATS_TYPE_SPECIAL}, + {"wbm_src_reo_code_inv" , NSS_STATS_TYPE_ERROR}, + {"wbm_src_inv" , NSS_STATS_TYPE_ERROR} +}; + +/* + * nss_wifili_txrx_strings_read() + * Read wifili Tx Rx statistics names. + */ +static ssize_t nss_wifili_txrx_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_wifili_strings_stats_txrx, NSS_WIFILI_STATS_TXRX_MAX); +} + +/* + * nss_wifili_tcl_ring_strings_read() + * Read wifili TCL ring statistics names. + */ +static ssize_t nss_wifili_tcl_ring_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_wifili_strings_stats_tcl, NSS_WIFILI_STATS_TCL_MAX); +} + +/* + * nss_wifili_tcl_comp_strings_read() + * Read wifili TCL comp statistics names. + */ +static ssize_t nss_wifili_tcl_comp_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_wifili_strings_stats_tx_comp, NSS_WIFILI_STATS_TX_DESC_FREE_MAX); +} + +/* + * nss_wifili_reo_ring_strings_read() + * Read wifili reorder ring statistics names. + */ +static ssize_t nss_wifili_reo_ring_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_wifili_strings_stats_reo, NSS_WIFILI_STATS_REO_MAX); +} + +/* + * nss_wifili_tx_sw_strings_read() + * Read wifili Tx sw statistics names. + */ +static ssize_t nss_wifili_tx_sw_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_wifili_strings_stats_txsw_pool, NSS_WIFILI_STATS_TX_DESC_MAX); +} + +/* + * nss_wifili_tx_ext_sw_strings_read() + * Read wifili Tx ext sw statistics names. + */ +static ssize_t nss_wifili_tx_ext_sw_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_wifili_strings_stats_ext_txsw_pool, NSS_WIFILI_STATS_EXT_TX_DESC_MAX); +} + +/* + * nss_wifili_rx_dma_pool_strings_read() + * Read wifili Rx DMA pool statistics names. + */ +static ssize_t nss_wifili_rx_dma_pool_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_wifili_strings_stats_rxdma_pool, NSS_WIFILI_STATS_RX_DESC_MAX); +} + +/* + * nss_wifili_rx_dma_ring_strings_read() + * Read wifili Rx DMA ring statistics names. + */ +static ssize_t nss_wifili_rx_dma_ring_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_wifili_strings_stats_rxdma_ring, NSS_WIFILI_STATS_RXDMA_DESC_MAX); +} + +/* + * nss_wifili_wbm_ring_strings_read() + * Read wifili WBM ring statistics names. + */ +static ssize_t nss_wifili_wbm_ring_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos) +{ + return nss_strings_print(ubuf, sz, ppos, nss_wifili_strings_stats_wbm, NSS_WIFILI_STATS_WBM_MAX); +} + +/* + * nss_wifili_txrx_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(wifili_txrx); + +/* + * nss_wifili_tcl_ring_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(wifili_tcl_ring); + +/* + * nss_wifili_tcl_comp_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(wifili_tcl_comp); + +/* + * nss_wifili_reo_ring_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(wifili_reo_ring); + +/* + * nss_wifili_tx_sw_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(wifili_tx_sw); + +/* + * nss_wifili_tx_ext_sw_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(wifili_tx_ext_sw); + +/* + * nss_wifili_rx_dma_pool_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(wifili_rx_dma_pool); + +/* + * nss_wifili_rx_dma_ring_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(wifili_rx_dma_ring); + +/* + * nss_wifili_wbm_ring_strings_ops + */ +NSS_STRINGS_DECLARE_FILE_OPERATIONS(wifili_wbm_ring); + +/* + * nss_wifili_strings_dentry_create() + * Create wifili statistics strings debug entry. + */ +void nss_wifili_strings_dentry_create(void) +{ + struct dentry *wifili_d = NULL; + struct dentry *wifili_txrx_d = NULL; + struct dentry *wifili_tcl_ring_d = NULL; + struct dentry *wifili_tcl_comp_d = NULL; + struct dentry *wifili_reo_ring_d = NULL; + struct dentry *wifili_tx_sw_d = NULL; + struct dentry *wifili_tx_ext_sw_d = NULL; + struct dentry *wifili_rx_dma_pool_d = NULL; + struct dentry *wifili_rx_dma_ring_d = NULL; + struct dentry *wifili_wbm_ring_d = NULL; + + if (!nss_top_main.strings_dentry) { + nss_warning("qca-nss-drv/strings is not present"); + return; + } + + wifili_d = debugfs_create_dir("wifili", nss_top_main.strings_dentry); + if (!wifili_d) { + nss_warning("Failed to create qca-nss-drv/strings/wifili directory"); + return; + } + + wifili_txrx_d = debugfs_create_file("txrx_str", 0400, wifili_d, &nss_top_main, &nss_wifili_txrx_strings_ops); + if (!wifili_txrx_d) { + nss_warning("Failed to create qca-nss-drv/strings/wifili/txrx_str file"); + debugfs_remove_recursive(wifili_d); + return; + } + + wifili_tcl_ring_d = debugfs_create_file("tcl_ring_str", 0400, wifili_d, &nss_top_main, &nss_wifili_tcl_ring_strings_ops); + if (!wifili_tcl_ring_d) { + nss_warning("Failed to create qca-nss-drv/strings/wifili/tcl_ring_str file"); + debugfs_remove_recursive(wifili_d); + return; + } + + wifili_tcl_comp_d = debugfs_create_file("tcl_comp_str", 0400, wifili_d, &nss_top_main, &nss_wifili_tcl_comp_strings_ops); + if (!wifili_tcl_comp_d) { + nss_warning("Failed to create qca-nss-drv/strings/wifili/tcl_comp_str file"); + debugfs_remove_recursive(wifili_d); + return; + } + + wifili_reo_ring_d = debugfs_create_file("reo_ring_str", 0400, wifili_d, &nss_top_main, &nss_wifili_reo_ring_strings_ops); + if (!wifili_reo_ring_d) { + nss_warning("Failed to create qca-nss-drv/strings/wifili/reo_ring_str file"); + debugfs_remove_recursive(wifili_d); + return; + } + + wifili_tx_sw_d = debugfs_create_file("tx_sw_str", 0400, wifili_d, &nss_top_main, &nss_wifili_tx_sw_strings_ops); + if (!wifili_tx_sw_d) { + nss_warning("Failed to create qca-nss-drv/strings/wifili/tx_sw_str file"); + debugfs_remove_recursive(wifili_d); + return; + } + + wifili_tx_ext_sw_d = debugfs_create_file("tx_ext_sw_str", 0400, wifili_d, &nss_top_main, &nss_wifili_tx_ext_sw_strings_ops); + if (!wifili_tx_ext_sw_d) { + nss_warning("Failed to create qca-nss-drv/strings/wifili/tx_ext_sw_str file"); + debugfs_remove_recursive(wifili_d); + return; + } + + wifili_rx_dma_pool_d = debugfs_create_file("rx_dma_pool_str", 0400, wifili_d, &nss_top_main, &nss_wifili_rx_dma_pool_strings_ops); + if (!wifili_rx_dma_pool_d) { + nss_warning("Failed to create qca-nss-drv/strings/wifili/rx_dma_pool_str file"); + debugfs_remove_recursive(wifili_d); + return; + } + + wifili_rx_dma_ring_d = debugfs_create_file("rx_dma_ring_str", 0400, wifili_d, &nss_top_main, &nss_wifili_rx_dma_ring_strings_ops); + if (!wifili_rx_dma_ring_d) { + nss_warning("Failed to create qca-nss-drv/strings/wifili/rx_dma_ring_str file"); + debugfs_remove_recursive(wifili_d); + return; + } + + wifili_wbm_ring_d = debugfs_create_file("wbm_ring_str", 0400, wifili_d, &nss_top_main, &nss_wifili_wbm_ring_strings_ops); + if (!wifili_wbm_ring_d) { + nss_warning("Failed to create qca-nss-drv/strings/wifili/wbm_ring_str file"); + debugfs_remove_recursive(wifili_d); + return; + } +} diff --git a/feeds/ipq807x/qca-nss-drv/src/nss_wifili_strings.h b/feeds/ipq807x/qca-nss-drv/src/nss_wifili_strings.h new file mode 100644 index 000000000..263d172f6 --- /dev/null +++ b/feeds/ipq807x/qca-nss-drv/src/nss_wifili_strings.h @@ -0,0 +1,44 @@ +/* + ************************************************************************** + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + ************************************************************************** + */ + +#ifndef __NSS_WIFILI_STRINGS_H +#define __NSS_WIFILI_STRINGS_H + +/* + * Maximum string length: + * This should be equal to maximum string size of any stats + * inclusive of stats value + */ +#define NSS_WIFILI_STATS_MAX (NSS_WIFILI_STATS_TXRX_MAX + NSS_WIFILI_STATS_TCL_MAX + \ + NSS_WIFILI_STATS_TX_DESC_FREE_MAX + NSS_WIFILI_STATS_REO_MAX + \ + NSS_WIFILI_STATS_TX_DESC_MAX + NSS_WIFILI_STATS_EXT_TX_DESC_MAX + \ + NSS_WIFILI_STATS_RX_DESC_MAX + NSS_WIFILI_STATS_RXDMA_DESC_MAX) + +extern struct nss_stats_info nss_wifili_strings_stats_txrx[NSS_WIFILI_STATS_TXRX_MAX]; +extern struct nss_stats_info nss_wifili_strings_stats_tcl[NSS_WIFILI_STATS_TCL_MAX]; +extern struct nss_stats_info nss_wifili_strings_stats_tx_comp[NSS_WIFILI_STATS_TX_DESC_FREE_MAX]; +extern struct nss_stats_info nss_wifili_strings_stats_reo[NSS_WIFILI_STATS_REO_MAX]; +extern struct nss_stats_info nss_wifili_strings_stats_txsw_pool[NSS_WIFILI_STATS_TX_DESC_MAX]; +extern struct nss_stats_info nss_wifili_strings_stats_ext_txsw_pool[NSS_WIFILI_STATS_EXT_TX_DESC_MAX]; +extern struct nss_stats_info nss_wifili_strings_stats_rxdma_pool[NSS_WIFILI_STATS_RX_DESC_MAX]; +extern struct nss_stats_info nss_wifili_strings_stats_rxdma_ring[NSS_WIFILI_STATS_RXDMA_DESC_MAX]; +extern struct nss_stats_info nss_wifili_strings_stats_wbm[NSS_WIFILI_STATS_WBM_MAX]; + +extern void nss_wifili_strings_dentry_create(void); + +#endif /* __NSS_WIFILI_STRINGS_H */ diff --git a/feeds/ipq807x/qca-nss-fw/Makefile b/feeds/ipq807x/qca-nss-fw/Makefile new file mode 100644 index 000000000..45f866a55 --- /dev/null +++ b/feeds/ipq807x/qca-nss-fw/Makefile @@ -0,0 +1,54 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=qca-nss-fw +PKG_VERSION:=383 + +PKG_MAINTAINER:=John Crispin + +include $(INCLUDE_DIR)/package.mk + +define Package/qca-nss-fw-default + SECTION:=firmware + CATEGORY:=Firmware + URL:=$(PKG_SOURCE_URL) + DEPENDS:= +endef + +define Package/qca-nss-fw-ipq60xx +$(Package/qca-nss-fw-default) + TITLE:=NSS firmware for IPQ60xx devices + DEPENDS:=@TARGET_ipq807x_ipq60xx +endef + +define Package/qca-nss-fw-ipq807x +$(Package/qca-nss-fw-default) + TITLE:=NSS firmware for IPQ807x devices + DEPENDS:=@TARGET_ipq807x_ipq807x +endef + +define Package/qca-nss-fw-ipq60xx/description +Retail NSS firmware for IPQ60xx from QCA +endef + +define Package/qca-nss-fw-ipq807x/description +Retail NSS firmware for IPQ807x from QCA +endef + +define Build/Compile + +endef + +define Package/qca-nss-fw-ipq60xx/install + $(INSTALL_DIR) $(1)/lib/firmware/ + $(INSTALL_DATA) ./files/IPQ6018/* \ + $(1)/lib/firmware/ +endef + +define Package/qca-nss-fw-ipq807x/install + $(INSTALL_DIR) $(1)/lib/firmware/ + $(INSTALL_DATA) ./files/IPQ8074/* \ + $(1)/lib/firmware/ +endef + +$(eval $(call BuildPackage,qca-nss-fw-ipq60xx)) +$(eval $(call BuildPackage,qca-nss-fw-ipq807x)) diff --git a/feeds/ipq807x/qca-nss-fw/files/IPQ6018/Notice.txt b/feeds/ipq807x/qca-nss-fw/files/IPQ6018/Notice.txt new file mode 100644 index 000000000..14ae319ec --- /dev/null +++ b/feeds/ipq807x/qca-nss-fw/files/IPQ6018/Notice.txt @@ -0,0 +1,236 @@ +============================================================================= + +This Notice.txt file contains certain notices of software components included with the software that Qualcomm Atheros, Inc. ("Qualcomm Atheros") is required to provide you. Except where prohibited by the open source license, the content of this notices file is only provided to satisfy Qualcomm Atheros's attribution and notice requirement; your use of these software components together with the Qualcomm Atheros software (Qualcomm Atheros software hereinafter referred to as "Software") is subject to the terms of your agreement from Qualcomm Atheros. Compliance with all copyright laws and software license agreements included in the notice section of this file are the responsibility of the user. Except as may be granted by separate express written agreement, this file provides no license to any patents, trademarks, copyrights, or other intellectual property of Qualcomm Incorporated or any of its subsidiaries. + +Qualcomm is a trademark of Qualcomm Incorporated, registered in the United States and other countries. All Qualcomm Incorporated trademarks are used with permission. Other products and brand names may be trademarks or registered trademarks of their respective owners. + + +NOTICES: + +============================================================================= + +/* + * doprint.c + * Formatted string print support. + * + * Copyright (c) 2015 Qualcomm Atheros, Inc. + * + * All Rights Reserved. + * + * Qualcomm Atheros Confidential and Proprietary. + * + * Notifications and licenses are retained for attribution purposes only + * + * This code originates with BSD Unix however it has been extensively + * modified. The original copyright is reproduced below: + * + * Copyright (c) 1988 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted provided + * that: (1) source distributions retain this entire copyright notice and + * comment, and (2) distributions including binaries display the following + * acknowledgement: ``This product includes software developed by the + * University of California, Berkeley and its contributors'' in the + * documentation or other materials provided with the distribution and in + * all advertising materials mentioning features or use of this software. + * Neither the name of the University nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +/* + * math.c + * Support for the standard C library. + * + * Copyright (c) 2015 Qualcomm Atheros, Inc. + * + * All Rights Reserved. + * + * Qualcomm Atheros Confidential and Proprietary. + * + * Notifications and licenses are retained for attribution purposes only + * + * Software contained within this file was originally released with the following + * copyright and license statement: + * + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + + +/* + * stdlib.c + * Routines from stdlib.h. + * + * Copyright (c) 2015 Qualcomm Atheros, Inc. + * + * All Rights Reserved. + * + * Qualcomm Atheros Confidential and Proprietary. + * + * Notifications and licenses are retained for attribution purposes only + * + * The code for strtol() and strtoul() are also subject to the following: + * + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +drr_alg_utils.h: +/****************************************************************************/ +/*- + * Copyright (c) 2015 Qualcomm Atheros, Inc. + * + * All Rights Reserved. + * + * Qualcomm Atheros Confidential and Proprietary. + * + * Notifications and licenses are retained for attribution purposes only + * + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +shaper_list_utils.h: +/****************************************************************************/ +/*- + * Copyright (c) 2015 Qualcomm Atheros, Inc. + * + * All Rights Reserved. + * + * Qualcomm Atheros Confidential and Proprietary. + * + * Notifications and licenses are retained for attribution purposes only + * + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +codel_alg_inv_sqrt.h +/****************************************************************************/ +/*- + * Copyright (c) 2015 Qualcomm Atheros, Inc. + * + * All Rights Reserved. + * + * Qualcomm Atheros Confidential and Proprietary. + * + * Notifications and licenses are retained for attribution purposes only + * + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ diff --git a/feeds/ipq807x/qca-nss-fw/files/IPQ6018/ReadMe.txt b/feeds/ipq807x/qca-nss-fw/files/IPQ6018/ReadMe.txt new file mode 100644 index 000000000..01d96758e --- /dev/null +++ b/feeds/ipq807x/qca-nss-fw/files/IPQ6018/ReadMe.txt @@ -0,0 +1,10 @@ +Identification + +This release is: IPQ6018.ATH.11.3.0 ED1 + +The Linux Foundation hosted open-source label +(CAF_TAG) that corresponds to this release is: caf_AU_LINUX_QSDK_NHSS.QSDK.11.3.0.5.R1_TARGET_ALL.12.0.5005.031.xml + +NSS Firmware Version: NSS.CP.2.0-383-R + +This product includes software developed by the University of California, Berkeley, and its contributors. diff --git a/feeds/ipq807x/qca-nss-fw/files/IPQ6018/qca-nss0.bin b/feeds/ipq807x/qca-nss-fw/files/IPQ6018/qca-nss0.bin new file mode 100755 index 000000000..da083e859 Binary files /dev/null and b/feeds/ipq807x/qca-nss-fw/files/IPQ6018/qca-nss0.bin differ diff --git a/feeds/ipq807x/qca-nss-fw/files/IPQ8074/Notice.txt b/feeds/ipq807x/qca-nss-fw/files/IPQ8074/Notice.txt new file mode 100644 index 000000000..14ae319ec --- /dev/null +++ b/feeds/ipq807x/qca-nss-fw/files/IPQ8074/Notice.txt @@ -0,0 +1,236 @@ +============================================================================= + +This Notice.txt file contains certain notices of software components included with the software that Qualcomm Atheros, Inc. ("Qualcomm Atheros") is required to provide you. Except where prohibited by the open source license, the content of this notices file is only provided to satisfy Qualcomm Atheros's attribution and notice requirement; your use of these software components together with the Qualcomm Atheros software (Qualcomm Atheros software hereinafter referred to as "Software") is subject to the terms of your agreement from Qualcomm Atheros. Compliance with all copyright laws and software license agreements included in the notice section of this file are the responsibility of the user. Except as may be granted by separate express written agreement, this file provides no license to any patents, trademarks, copyrights, or other intellectual property of Qualcomm Incorporated or any of its subsidiaries. + +Qualcomm is a trademark of Qualcomm Incorporated, registered in the United States and other countries. All Qualcomm Incorporated trademarks are used with permission. Other products and brand names may be trademarks or registered trademarks of their respective owners. + + +NOTICES: + +============================================================================= + +/* + * doprint.c + * Formatted string print support. + * + * Copyright (c) 2015 Qualcomm Atheros, Inc. + * + * All Rights Reserved. + * + * Qualcomm Atheros Confidential and Proprietary. + * + * Notifications and licenses are retained for attribution purposes only + * + * This code originates with BSD Unix however it has been extensively + * modified. The original copyright is reproduced below: + * + * Copyright (c) 1988 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted provided + * that: (1) source distributions retain this entire copyright notice and + * comment, and (2) distributions including binaries display the following + * acknowledgement: ``This product includes software developed by the + * University of California, Berkeley and its contributors'' in the + * documentation or other materials provided with the distribution and in + * all advertising materials mentioning features or use of this software. + * Neither the name of the University nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + + +/* + * math.c + * Support for the standard C library. + * + * Copyright (c) 2015 Qualcomm Atheros, Inc. + * + * All Rights Reserved. + * + * Qualcomm Atheros Confidential and Proprietary. + * + * Notifications and licenses are retained for attribution purposes only + * + * Software contained within this file was originally released with the following + * copyright and license statement: + * + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + + +/* + * stdlib.c + * Routines from stdlib.h. + * + * Copyright (c) 2015 Qualcomm Atheros, Inc. + * + * All Rights Reserved. + * + * Qualcomm Atheros Confidential and Proprietary. + * + * Notifications and licenses are retained for attribution purposes only + * + * The code for strtol() and strtoul() are also subject to the following: + * + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +drr_alg_utils.h: +/****************************************************************************/ +/*- + * Copyright (c) 2015 Qualcomm Atheros, Inc. + * + * All Rights Reserved. + * + * Qualcomm Atheros Confidential and Proprietary. + * + * Notifications and licenses are retained for attribution purposes only + * + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +shaper_list_utils.h: +/****************************************************************************/ +/*- + * Copyright (c) 2015 Qualcomm Atheros, Inc. + * + * All Rights Reserved. + * + * Qualcomm Atheros Confidential and Proprietary. + * + * Notifications and licenses are retained for attribution purposes only + * + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +codel_alg_inv_sqrt.h +/****************************************************************************/ +/*- + * Copyright (c) 2015 Qualcomm Atheros, Inc. + * + * All Rights Reserved. + * + * Qualcomm Atheros Confidential and Proprietary. + * + * Notifications and licenses are retained for attribution purposes only + * + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ diff --git a/feeds/ipq807x/qca-nss-fw/files/IPQ8074/ReadMe.txt b/feeds/ipq807x/qca-nss-fw/files/IPQ8074/ReadMe.txt new file mode 100644 index 000000000..389323de8 --- /dev/null +++ b/feeds/ipq807x/qca-nss-fw/files/IPQ8074/ReadMe.txt @@ -0,0 +1,10 @@ +Identification + +This release is: IPQ8074.ATH.11.3.0 ED1 + +The Linux Foundation hosted open-source label +(CAF_TAG) that corresponds to this release is: caf_AU_LINUX_QSDK_NHSS.QSDK.11.3.0.5.R1_TARGET_ALL.12.0.5005.031.xml + +NSS Firmware Version: NSS.HK.2.0-383-R + +This product includes software developed by the University of California, Berkeley, and its contributors. diff --git a/feeds/ipq807x/qca-nss-fw/files/IPQ8074/qca-nss0.bin b/feeds/ipq807x/qca-nss-fw/files/IPQ8074/qca-nss0.bin new file mode 100755 index 000000000..e94173757 Binary files /dev/null and b/feeds/ipq807x/qca-nss-fw/files/IPQ8074/qca-nss0.bin differ diff --git a/feeds/ipq807x/qca-nss-fw/files/IPQ8074/qca-nss1.bin b/feeds/ipq807x/qca-nss-fw/files/IPQ8074/qca-nss1.bin new file mode 100755 index 000000000..6899db883 Binary files /dev/null and b/feeds/ipq807x/qca-nss-fw/files/IPQ8074/qca-nss1.bin differ diff --git a/feeds/ipq807x/qca-ssdk-shell/Makefile b/feeds/ipq807x/qca-ssdk-shell/Makefile new file mode 100755 index 000000000..a06afadf5 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/Makefile @@ -0,0 +1,43 @@ + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=qca-ssdk-shell +PKG_RELEASE:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/qca-ssdk-shell + SECTION:=QCA + CATEGORY:=Utilities + TITLE:=Shell application for QCA SSDK +endef + + +define Package/qca-ssdk-shell/Description + This package contains a qca-ssdk shell application for QCA chipset +endef + +ifndef CONFIG_TOOLCHAIN_BIN_PATH +CONFIG_TOOLCHAIN_BIN_PATH=$(TOOLCHAIN_DIR)/bin +endif + +QCASSDK_CONFIG_OPTS+= TOOL_PATH=$(CONFIG_TOOLCHAIN_BIN_PATH) \ + SYS_PATH=$(LINUX_DIR) \ + TOOLPREFIX=$(TARGET_CROSS) \ + KVER=$(LINUX_VERSION) \ + CFLAGS="$(TARGET_CFLAGS)" \ + LDFLAGS="$(TARGET_LDFLAGS)" \ + ARCH=$(LINUX_KARCH) + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) $(strip $(QCASSDK_CONFIG_OPTS)) +endef + +define Package/qca-ssdk-shell/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/build/bin/ssdk_sh $(1)/usr/sbin/ +endef + + +$(eval $(call BuildPackage,qca-ssdk-shell)) diff --git a/feeds/ipq807x/qca-ssdk-shell/src/Makefile b/feeds/ipq807x/qca-ssdk-shell/src/Makefile new file mode 100755 index 000000000..adcf87282 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/Makefile @@ -0,0 +1,47 @@ +include ./config + +ifndef PRJ_PATH + PRJ_PATH=$(shell pwd) +endif +export PRJ_PATH + +include ./make/config.mk +include ./make/tools.mk +include ./make/$(OS)_opt.mk + +SUB_DIR=$(patsubst %/, %, $(dir $(wildcard src/*/Makefile))) +SUB_LIB=$(subst src/, , $(SUB_DIR)) + +all: $(BIN_DIR) uslib shell + @echo "---Build [SSDK_SH-$(VERSION)] at $(BUILD_DATE) finished." + +kslib:kslib_o + $(AR) -r $(BIN_DIR)/$(KS_MOD)_$(RUNMODE).a $(wildcard $(BLD_DIR)/KSLIB/*.o) + +kslib_o: + $(foreach i, $(SUB_LIB), $(MAKE) MODULE_TYPE=KSLIB -C src/$i all || exit 1;) + +uslib:uslib_o + $(AR) -r $(BIN_DIR)/$(US_MOD)_$(RUNMODE).a $(wildcard $(BLD_DIR)/USLIB/*.o) + +uslib_o: + $(foreach i, $(SUB_LIB), $(MAKE) MODULE_TYPE=USLIB -C src/$i all || exit 1;) + +shell:uslib shell_o + $(CP) $(BLD_DIR)/SHELL/$(SHELLOBJ) $(BIN_DIR)/$(SHELLOBJ) + $(STRIP) $(BIN_DIR)/$(SHELLOBJ) + +shell_o: + $(foreach i, $(SUB_LIB), $(MAKE) MODULE_TYPE=SHELL -C src/$i all || exit 1;) + +$(BIN_DIR): + $(MKDIR) -p $@ + +release: + @cd make; ./release.sh $(VER) + +clean: + $(RM) -f $(BLD_DIR)/KSLIB/* + $(RM) -f $(BLD_DIR)/USLIB/* + $(RM) -f $(BLD_DIR)/SHELL/* + $(RM) -f $(BIN_DIR)/* diff --git a/feeds/ipq807x/qca-ssdk-shell/src/config b/feeds/ipq807x/qca-ssdk-shell/src/config new file mode 100755 index 000000000..e2d4c4405 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/config @@ -0,0 +1,153 @@ +#CPU=mips + +OS=linux + +ifeq ($(KVER), 3.4.0) +OS_VER=3_4 +endif + +ifeq ($(KVER), 3.3.8) +OS_VER=3_2 +endif + +ifeq ($(ARCH), arm) +BOARD=ipq806x +endif + +ifeq ($(ARCH), mips) +BOARD=ar71xx +endif + +ifeq ($(BOARD), ar71xx) +BOARD_NAME=BOARD_AR71XX +endif + +ifeq ($(BOARD), ipq806x) +BOARD_NAME=BOARD_IPQ806X +endif + +OS_SUB=31 +CHIP_TYPE=ISISC + +ifndef OS_VER +OS_VER=2_6 +endif +# OS subversion, 2.6.31 for WASP (db120) +#OS_SUB=31 +# GCC version, 3 or 4 +#GCC_VER=4 + +#For MIPS Linux2.6 + #pb45 + #TOOL_PATH=/disk/pb45/sw/build/gcc-3.4.4-2.16.1/build_mips_nofpu/bin + #SYS_PATH=/disk/pb45/sw/linux/kernels/mips-linux-2.6.15 + + #ap81 +# compatiable with OpenWRT +ifndef TOOL_PATH +TOOL_PATH=/disk/ap81fus/sw/build/gcc-3.4.4-2.16.1/build_mips/bin +endif +ifndef SYS_PATH +SYS_PATH=/disk/ap81fus/sw/linux/kernels/mips-linux-2.6.15 +endif +ifeq ($(ARCH), mips) + CPU_CFLAG=-Wstrict-prototypes -fomit-frame-pointer -G 0 -mno-abicalls -fno-strict-aliasing -O2 -fno-pic -pipe -mabi=32 -march=mips32r2 -DMODULE -mlong-calls -DEXPORT_SYMTAB -D$(BOARD_NAME) +endif + + +#db120 +ifeq ($(BOARD_TYPE),db12x) +OS_SUB=31 +GCC_VER=4 +TOOL_PATH=$(TOPDIR)/build/gcc-4.3.3/build_mips/staging_dir/usr/bin +SYS_PATH=$(TOPDIR)/linux/kernels/mips-linux-2.6.31 +CPU_CFLAG=-Wstrict-prototypes -fomit-frame-pointer -G 0 -mno-abicalls -fno-strict-aliasing -O2 -fno-pic -pipe -mabi=32 -march=mips32r2 -DMODULE -mlong-calls -DEXPORT_SYMTAB +endif + +ifeq ($(ARCH), arm) + CPU_CFLAG=-D__LINUX_ARM_ARCH__=7 -DMODULE -fno-common -DCONFIG_MMU -D$(BOARD_NAME) +endif + +ifeq ($(BOARD_TYPE), ap136) +OS_SUB=31 +GCC_VER=4 +TOOL_PATH=$(TOPDIR)/build/gcc-4.3.3/build_mips/staging_dir/usr/bin +SYS_PATH=$(TOPDIR)/linux/kernels/mips-linux-2.6.31 +CPU_CFLAG=-Wstrict-prototypes -fomit-frame-pointer -G 0 -mno-abicalls -fno-strict-aliasing -O2 -fno-pic -pipe -mabi=32 -march=mips32r2 -DMODULE -mlong-calls -DEXPORT_SYMTAB +endif + +#For MIPS Linux2.4 + #TOOL_PATH=/home/perforce/kernel2.4/5.3.1.20/tools/gcc-3.3.3-2.4.25/toolchain_mips/bin + #SYS_PATH=/home/perforce/kernel2.4/5.3.1.20/src/kernels/mips-linux-2.4.25 + + #TOOLPREFIX=$(CPU)-$(OS)- + #CPU_CFLAG=-Wstrict-prototypes -Wundef -fomit-frame-pointer -G 0 -mno-abicalls -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -O2 -fno-pic -pipe -mabi=32 -march=r4600 -Wa,-32 -Wa,-march=r4600 -Wa,--trap -DMODULE -mlong-calls -DEXPORT_SYMTAB + + +KERNEL_MODE=TRUE +#compatiable with OpenWRT +ifeq ($(SWITCH_SSDK_MODE),user) +KERNEL_MODE=FLASE +endif + +#FAL=FALSE or not define FAL, FAL will not be included in SSDK +FAL=TRUE + +#CHIP_TYPE can be defined as ATHENA, GARUDA, SHIVA, HORUS, ISIS, ISISC and ALL_CHIP(ALL_CHIP means GARUDA, SHIVA, HORUS and ISIS) +CHIP_TYPE=ISISC + +#UK_IF=FALSE or not define UK_IF, UK_IF will not be included in SSDK +#when UK_IF=TRUE one of UK_NETLINK,UK_IOCTL must be defined as TRUE +UK_IF=TRUE +#UK_IOCTL=TRUE define user-kernel space communication based on ioctl +UK_IOCTL=TRUE +UK_MINOR_DEV=254 + +#API_LOCK=FALSE or not define API_LOCK, API_LOCK will not be included in SSDK +API_LOCK=FALSE + +#REG_ACCESS_SPEEDUP=FALSE or not define REG_ACCESS_SPEEDUP, REG_ACCESS_SPEEDUP will not be enabled, now only ISIS supports +REG_ACCESS_SPEEDUP=FALSE + +#ALL supported features: +#ACL FDB IGMP LEAKY LED MIB MIRROR MISC PORTCONTROL PORTVLAN QOS RATE STP VLAN +#IN_X=FALSE or not define IN_X, X will not be included in SSDK +IN_ACL=TRUE +IN_FDB=TRUE +IN_IGMP=TRUE +IN_LEAKY=TRUE +IN_LED=TRUE +IN_MIB=TRUE +IN_MIRROR=TRUE +IN_MISC=TRUE +IN_PORTCONTROL=TRUE +IN_PORTVLAN=TRUE +IN_QOS=TRUE +IN_RATE=TRUE +IN_STP=TRUE +IN_VLAN=TRUE +IN_REDUCED_ACL=FALSE +IN_COSMAP=TRUE +IN_IP=TRUE +IN_NAT=TRUE +IN_TRUNK=TRUE +IN_QM=TRUE +IN_FLOW=TRUE +IN_SEC=TRUE +ifeq ($(HNAT_FEATURE), enable) +IN_NAT_HELPER=TRUE +else +IN_NAT_HELPER=FALSE +endif +IN_INTERFACECONTROL=TRUE +IN_MACBLOCK=FALSE +IN_VSI=TRUE +IN_CTRLPKT=TRUE +IN_SERVCODE=TRUE +IN_RSS_HASH=TRUE +IN_PPPOE=TRUE +IN_BM=TRUE +IN_SHAPER=TRUE +IN_POLICER=TRUE +IN_PTP=TRUE +IN_SFP=TRUE diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/api/api_access.h b/feeds/ipq807x/qca-ssdk-shell/src/include/api/api_access.h new file mode 100755 index 000000000..806c24dea --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/api/api_access.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#ifndef _API_ACCESS_H +#define _API_ACCESS_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + sw_api_func_t * + sw_api_func_find(a_uint32_t api_id); + + sw_api_param_t * + sw_api_param_find(a_uint32_t api_id); + + a_uint32_t + sw_api_param_nums(a_uint32_t api_id); + + sw_error_t + sw_api_get(sw_api_t *sw_api); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _API_ACCESS_H */ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/api/api_desc.h b/feeds/ipq807x/qca-ssdk-shell/src/include/api/api_desc.h new file mode 100755 index 000000000..009d57502 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/api/api_desc.h @@ -0,0 +1,4240 @@ +/* + * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/*qca808x_start*/ +#ifndef _API_DESC_H_ +#define _API_DESC_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define SW_API_PT_DUPLEX_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_DUPLEX_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_DUPLEX_GET, SW_UINT32, 4, SW_PARAM_IN, "Port No."), \ + SW_PARAM_DEF(SW_API_PT_DUPLEX_GET, SW_DUPLEX, sizeof(fal_port_duplex_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "duplex"), + +#define SW_API_PT_DUPLEX_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_DUPLEX_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_DUPLEX_SET, SW_UINT32, 4, SW_PARAM_IN, "Port No."), \ + SW_PARAM_DEF(SW_API_PT_DUPLEX_SET, SW_DUPLEX, sizeof(fal_port_duplex_t), SW_PARAM_IN, \ + "duplex"), + +#define SW_API_PT_SPEED_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_SPEED_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_SPEED_GET, SW_UINT32, 4, SW_PARAM_IN, "Port No."), \ + SW_PARAM_DEF(SW_API_PT_SPEED_GET, SW_SPEED, sizeof(fal_port_speed_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "speed"), + +#define SW_API_PT_SPEED_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_SPEED_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_SPEED_SET, SW_UINT32, 4, SW_PARAM_IN, "Port No."), \ + SW_PARAM_DEF(SW_API_PT_SPEED_SET, SW_SPEED, sizeof(fal_port_speed_t), SW_PARAM_IN, \ + "speed"), + +#define SW_API_PT_AN_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_AN_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_AN_GET, SW_UINT32, 4, SW_PARAM_IN, "Port No."), \ + SW_PARAM_DEF(SW_API_PT_AN_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "autoneg"), + + +#define SW_API_PT_AN_ENABLE_DESC \ + SW_PARAM_DEF(SW_API_PT_AN_ENABLE, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_AN_ENABLE, SW_UINT32, 4, SW_PARAM_IN, "Port No."), + + +#define SW_API_PT_AN_RESTART_DESC \ + SW_PARAM_DEF(SW_API_PT_AN_RESTART, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_AN_RESTART, SW_UINT32, 4, SW_PARAM_IN, "Port No."), + +#define SW_API_PT_AN_ADV_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_AN_ADV_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_AN_ADV_GET, SW_UINT32, 4, SW_PARAM_IN, "Port No."), \ + SW_PARAM_DEF(SW_API_PT_AN_ADV_GET, SW_CAP, 4, SW_PARAM_PTR|SW_PARAM_OUT, "autoneg"), + +#define SW_API_PT_AN_ADV_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_AN_ADV_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_AN_ADV_SET, SW_UINT32, 4, SW_PARAM_IN, "Port No."), \ + SW_PARAM_DEF(SW_API_PT_AN_ADV_SET, SW_CAP, 4, SW_PARAM_IN, "autoneg"), +/*qca808x_end*/ + +#define SW_API_PT_HDR_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_HDR_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_HDR_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_HDR_SET, SW_ENABLE, 4, SW_PARAM_IN, "Header"), + +#define SW_API_PT_HDR_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_HDR_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_HDR_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_HDR_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Header"), + +#define SW_API_PT_FLOWCTRL_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_FLOWCTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_FLOWCTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_FLOWCTRL_SET, SW_ENABLE, 4, SW_PARAM_IN, "Flow control"), + +#define SW_API_PT_FLOWCTRL_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_FLOWCTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_FLOWCTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_FLOWCTRL_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Flow control"), + +#define SW_API_PT_FLOWCTRL_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_FLOWCTRL_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_FLOWCTRL_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_FLOWCTRL_MODE_SET, SW_ENABLE, 4, SW_PARAM_IN, "Force mode"), + +#define SW_API_PT_FLOWCTRL_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_FLOWCTRL_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_FLOWCTRL_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_FLOWCTRL_MODE_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Force mode"), + +#define SW_API_PT_POWERSAVE_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_POWERSAVE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_POWERSAVE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_POWERSAVE_SET, SW_ENABLE, 4, SW_PARAM_IN, "Powersave Status"), + +#define SW_API_PT_POWERSAVE_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_POWERSAVE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_POWERSAVE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_POWERSAVE_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Powersave Status"), +/*qca808x_start*/ +#define SW_API_PT_HIBERNATE_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_HIBERNATE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_HIBERNATE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_HIBERNATE_SET, SW_ENABLE, 4, SW_PARAM_IN, "Hibernate status"), + +#define SW_API_PT_HIBERNATE_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_HIBERNATE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_HIBERNATE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_HIBERNATE_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Hibernate Status"), + +#define SW_API_PT_CDT_DESC \ + SW_PARAM_DEF(SW_API_PT_CDT, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_CDT, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_CDT, SW_UINT32, 4, SW_PARAM_IN, "MDI Pair ID"), \ + SW_PARAM_DEF(SW_API_PT_CDT, SW_CABLESTATUS, 4, SW_PARAM_PTR|SW_PARAM_OUT, "cable status"), \ + SW_PARAM_DEF(SW_API_PT_CDT, SW_CABLELEN, 4, SW_PARAM_PTR|SW_PARAM_OUT, "cable len"), +/*qca808x_end*/ +#define SW_API_PT_TXHDR_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_TXHDR_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_TXHDR_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_TXHDR_SET, SW_HDRMODE, sizeof(fal_port_header_mode_t), \ + SW_PARAM_IN, "HdrMode"), + +#define SW_API_PT_TXHDR_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_TXHDR_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_TXHDR_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_TXHDR_GET, SW_HDRMODE, sizeof(fal_port_header_mode_t), \ + SW_PARAM_PTR|SW_PARAM_OUT, "HdrMode"), + +#define SW_API_PT_RXHDR_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_RXHDR_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_RXHDR_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_RXHDR_SET, SW_HDRMODE, sizeof(fal_port_header_mode_t), \ + SW_PARAM_IN, "HdrMode"), + +#define SW_API_PT_RXHDR_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_RXHDR_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_RXHDR_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_RXHDR_GET, SW_HDRMODE, sizeof(fal_port_header_mode_t), \ + SW_PARAM_PTR|SW_PARAM_OUT, "HdrMode"), + +#define SW_API_HEADER_TYPE_SET_DESC \ + SW_PARAM_DEF(SW_API_HEADER_TYPE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_HEADER_TYPE_SET, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), \ + SW_PARAM_DEF(SW_API_HEADER_TYPE_SET, SW_UINT32, 4, SW_PARAM_IN, "Value"), + +#define SW_API_HEADER_TYPE_GET_DESC \ + SW_PARAM_DEF(SW_API_HEADER_TYPE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_HEADER_TYPE_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Enable"), \ + SW_PARAM_DEF(SW_API_HEADER_TYPE_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Value"), + +#define SW_API_TXMAC_STATUS_SET_DESC \ + SW_PARAM_DEF(SW_API_TXMAC_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_TXMAC_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_TXMAC_STATUS_SET, SW_ENABLE, 4, SW_PARAM_IN, "Value"), + +#define SW_API_TXMAC_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_TXMAC_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_TXMAC_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_TXMAC_STATUS_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Value"), + +#define SW_API_RXMAC_STATUS_SET_DESC \ + SW_PARAM_DEF(SW_API_RXMAC_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_RXMAC_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_RXMAC_STATUS_SET, SW_ENABLE, 4, SW_PARAM_IN, "Value"), + +#define SW_API_RXMAC_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_RXMAC_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_RXMAC_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_RXMAC_STATUS_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Value"), + +#define SW_API_TXFC_STATUS_SET_DESC \ + SW_PARAM_DEF(SW_API_TXFC_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_TXFC_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_TXFC_STATUS_SET, SW_ENABLE, 4, SW_PARAM_IN, "Value"), + +#define SW_API_TXFC_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_TXFC_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_TXFC_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_TXFC_STATUS_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Value"), + +#define SW_API_RXFC_STATUS_SET_DESC \ + SW_PARAM_DEF(SW_API_RXFC_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_RXFC_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_RXFC_STATUS_SET, SW_ENABLE, 4, SW_PARAM_IN, "Value"), + +#define SW_API_RXFC_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_RXFC_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_RXFC_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_RXFC_STATUS_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Value"), + +#define SW_API_BP_STATUS_SET_DESC \ + SW_PARAM_DEF(SW_API_BP_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_BP_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_BP_STATUS_SET, SW_ENABLE, 4, SW_PARAM_IN, "Value"), + +#define SW_API_BP_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_BP_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_BP_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_BP_STATUS_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Value"), + +#define SW_API_PT_LINK_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_LINK_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_LINK_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_LINK_MODE_SET, SW_ENABLE, 4, SW_PARAM_IN, "Value"), + +#define SW_API_PT_LINK_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_LINK_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_LINK_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_LINK_MODE_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Value"), +/*qca808x_start*/ +#define SW_API_PT_LINK_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_LINK_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_LINK_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_LINK_STATUS_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Status"), +/*qca808x_end*/ +#define SW_API_PT_MAC_LOOPBACK_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_MAC_LOOPBACK_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_MAC_LOOPBACK_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_MAC_LOOPBACK_SET, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_PT_MAC_LOOPBACK_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_MAC_LOOPBACK_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_MAC_LOOPBACK_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_MAC_LOOPBACK_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Enable"), + +#define SW_API_PT_CONGESTION_DROP_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_CONGESTION_DROP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_CONGESTION_DROP_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_CONGESTION_DROP_SET, SW_UINT32, 4, SW_PARAM_IN, "Queue ID"), \ + SW_PARAM_DEF(SW_API_PT_CONGESTION_DROP_SET, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_PT_CONGESTION_DROP_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_CONGESTION_DROP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_CONGESTION_DROP_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_CONGESTION_DROP_GET, SW_UINT32, 4, SW_PARAM_IN, "Queue ID"), \ + SW_PARAM_DEF(SW_API_PT_CONGESTION_DROP_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Enable"), + +#define SW_API_PT_RING_FLOW_CTRL_THRES_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_RING_FLOW_CTRL_THRES_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_RING_FLOW_CTRL_THRES_SET, SW_UINT32, 4, SW_PARAM_IN, "Ring ID"), \ + SW_PARAM_DEF(SW_API_PT_RING_FLOW_CTRL_THRES_SET, SW_UINT8, 1, SW_PARAM_IN, "On Thres"), \ + SW_PARAM_DEF(SW_API_PT_RING_FLOW_CTRL_THRES_SET, SW_UINT8, 1, SW_PARAM_IN, "Off Thres"), + +#define SW_API_PT_RING_FLOW_CTRL_THRES_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_RING_FLOW_CTRL_THRES_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_RING_FLOW_CTRL_THRES_GET, SW_UINT32, 4, SW_PARAM_IN, "Ring ID"), \ + SW_PARAM_DEF(SW_API_PT_RING_FLOW_CTRL_THRES_GET, SW_UINT8, 1, SW_PARAM_PTR|SW_PARAM_OUT, "On Thres"), \ + SW_PARAM_DEF(SW_API_PT_RING_FLOW_CTRL_THRES_GET, SW_UINT8, 1, SW_PARAM_PTR|SW_PARAM_OUT, "Off Thres"), + +#define SW_API_PTS_LINK_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_PTS_LINK_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTS_LINK_STATUS_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Status"), +/*qca808x_start*/ +#define SW_API_PT_8023AZ_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_8023AZ_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_8023AZ_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_8023AZ_SET, SW_ENABLE, 4, SW_PARAM_IN, "8023az Status"), + +#define SW_API_PT_8023AZ_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_8023AZ_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_8023AZ_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_8023AZ_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "8023az Status"), + +#define SW_API_PT_MDIX_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_MDIX_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_MDIX_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_MDIX_SET, SW_CROSSOVER_MODE, sizeof(fal_port_mdix_mode_t), SW_PARAM_IN, "Crossover Mode"), + + +#define SW_API_PT_MDIX_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_MDIX_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_MDIX_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_MDIX_GET, SW_CROSSOVER_MODE, sizeof(fal_port_mdix_mode_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "Crossover Mode"), + +#define SW_API_PT_MDIX_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_MDIX_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_MDIX_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_MDIX_STATUS_GET, SW_CROSSOVER_STATUS, sizeof(fal_port_mdix_status_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "Crossover Status"), +/*qca808x_end*/ + +#define SW_API_PT_COMBO_PREFER_MEDIUM_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_COMBO_PREFER_MEDIUM_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_COMBO_PREFER_MEDIUM_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_COMBO_PREFER_MEDIUM_SET, SW_PREFER_MEDIUM, sizeof(fal_port_medium_t), SW_PARAM_IN, "Prefer Medium"), + + +#define SW_API_PT_COMBO_PREFER_MEDIUM_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_COMBO_PREFER_MEDIUM_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_COMBO_PREFER_MEDIUM_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_COMBO_PREFER_MEDIUM_GET, SW_PREFER_MEDIUM, sizeof(fal_port_medium_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "Prefer Medium"), + +#define SW_API_PT_COMBO_MEDIUM_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_COMBO_MEDIUM_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_COMBO_MEDIUM_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_COMBO_MEDIUM_STATUS_GET, SW_PREFER_MEDIUM, sizeof(fal_port_medium_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "Medium Type"), + +#define SW_API_PT_COMBO_FIBER_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_COMBO_FIBER_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_COMBO_FIBER_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_COMBO_FIBER_MODE_SET, SW_FIBER_MODE, sizeof(fal_port_fiber_mode_t), SW_PARAM_IN, "Fbier Mode"), + + +#define SW_API_PT_COMBO_FIBER_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_COMBO_FIBER_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_COMBO_FIBER_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_COMBO_FIBER_MODE_GET, SW_FIBER_MODE, sizeof(fal_port_fiber_mode_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "Fiber Mode"), +/*qca808x_start*/ +#define SW_API_PT_LOCAL_LOOPBACK_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_LOCAL_LOOPBACK_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_LOCAL_LOOPBACK_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_LOCAL_LOOPBACK_SET, SW_ENABLE, 4, SW_PARAM_IN, "Local Loopback Status"), + +#define SW_API_PT_LOCAL_LOOPBACK_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_LOCAL_LOOPBACK_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_LOCAL_LOOPBACK_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_LOCAL_LOOPBACK_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Local Loopback Status"), + +#define SW_API_PT_REMOTE_LOOPBACK_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_REMOTE_LOOPBACK_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_REMOTE_LOOPBACK_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_REMOTE_LOOPBACK_SET, SW_ENABLE, 4, SW_PARAM_IN, "Remote Loopback Status"), + +#define SW_API_PT_REMOTE_LOOPBACK_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_REMOTE_LOOPBACK_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_REMOTE_LOOPBACK_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_REMOTE_LOOPBACK_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Remote Loopback Status"), + +#define SW_API_PT_RESET_DESC \ + SW_PARAM_DEF(SW_API_PT_RESET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_RESET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), + +#define SW_API_PT_POWER_OFF_DESC \ + SW_PARAM_DEF(SW_API_PT_POWER_OFF, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_POWER_OFF, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), + +#define SW_API_PT_POWER_ON_DESC \ + SW_PARAM_DEF(SW_API_PT_POWER_ON, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_POWER_ON, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), + +#define SW_API_PT_MAGIC_FRAME_MAC_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_MAGIC_FRAME_MAC_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_MAGIC_FRAME_MAC_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_MAGIC_FRAME_MAC_SET, SW_MACADDR, sizeof(fal_mac_addr_t), SW_PARAM_PTR|SW_PARAM_IN, "[Magic mac]"), + +#define SW_API_PT_MAGIC_FRAME_MAC_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_MAGIC_FRAME_MAC_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_MAGIC_FRAME_MAC_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_MAGIC_FRAME_MAC_GET, SW_MACADDR, sizeof(fal_mac_addr_t), SW_PARAM_PTR|SW_PARAM_OUT, "[Magic mac]"), + +#define SW_API_PT_PHY_ID_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_PHY_ID_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_PHY_ID_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_PHY_ID_GET, SW_UINT16, 2, SW_PARAM_PTR|SW_PARAM_OUT, "Org ID"), \ + SW_PARAM_DEF(SW_API_PT_PHY_ID_GET, SW_UINT16, 2, SW_PARAM_PTR|SW_PARAM_OUT, "Rev ID"), + +#define SW_API_PT_WOL_STATUS_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_WOL_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_WOL_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_WOL_STATUS_SET, SW_ENABLE, 4, SW_PARAM_IN, "Wol Status"), + +#define SW_API_PT_WOL_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_WOL_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_WOL_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_WOL_STATUS_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Wol Status"), +/*qca808x_end*/ +#define SW_API_PT_INTERFACE_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_INTERFACE_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_INTERFACE_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_INTERFACE_MODE_SET, SW_INTERFACE_MODE, sizeof(fal_port_interface_mode_t), SW_PARAM_IN, "Interface Mode"), + + +#define SW_API_PT_INTERFACE_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_INTERFACE_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_INTERFACE_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_INTERFACE_MODE_GET, SW_INTERFACE_MODE, sizeof(fal_port_interface_mode_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "Interface Mode"), + +#define SW_API_PT_INTERFACE_MODE_APPLY_DESC \ + SW_PARAM_DEF(SW_API_PT_INTERFACE_MODE_APPLY, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), +/*qca808x_start*/ +#define SW_API_PT_INTERFACE_MODE_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_INTERFACE_MODE_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_INTERFACE_MODE_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_INTERFACE_MODE_STATUS_GET, SW_INTERFACE_MODE, sizeof(fal_port_interface_mode_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "Interface Status"), + +#define SW_API_DEBUG_PHYCOUNTER_SET_DESC \ + SW_PARAM_DEF(SW_API_DEBUG_PHYCOUNTER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_DEBUG_PHYCOUNTER_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_DEBUG_PHYCOUNTER_SET, SW_ENABLE, 4, SW_PARAM_IN, "Counter Status"), + +#define SW_API_DEBUG_PHYCOUNTER_GET_DESC \ + SW_PARAM_DEF(SW_API_DEBUG_PHYCOUNTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_DEBUG_PHYCOUNTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_DEBUG_PHYCOUNTER_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Counter Status"), + +#define SW_API_DEBUG_PHYCOUNTER_SHOW_DESC \ + SW_PARAM_DEF(SW_API_DEBUG_PHYCOUNTER_SHOW, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_DEBUG_PHYCOUNTER_SHOW, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_DEBUG_PHYCOUNTER_SHOW, SW_COUNTER_INFO, sizeof(fal_port_counter_info_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "Phy Counter Statistics On port"), +/*qca808x_end*/ +#define SW_API_PT_MTU_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_MTU_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_MTU_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_MTU_SET, SW_MTU_ENTRY, sizeof(fal_mtu_ctrl_t), SW_PARAM_PTR|SW_PARAM_IN, "Port MTU"), + +#define SW_API_PT_MTU_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_MTU_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_MTU_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_MTU_GET, SW_MTU_INFO, sizeof(fal_mtu_ctrl_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Port MTU"), + +#define SW_API_PT_MRU_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_MRU_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_MRU_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_MRU_SET, SW_MRU_ENTRY, sizeof(fal_mru_ctrl_t), SW_PARAM_PTR|SW_PARAM_IN, "Port MRU"), + +#define SW_API_PT_MRU_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_MRU_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_MRU_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_MRU_GET, SW_MRU_INFO, sizeof(fal_mru_ctrl_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Port MRU"), + +#define SW_API_PT_SOURCE_FILTER_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_SOURCE_FILTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_SOURCE_FILTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_SOURCE_FILTER_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Enable"), + +#define SW_API_PT_SOURCE_FILTER_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_SOURCE_FILTER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_SOURCE_FILTER_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_SOURCE_FILTER_SET, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_PT_FRAME_MAX_SIZE_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_FRAME_MAX_SIZE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_FRAME_MAX_SIZE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_FRAME_MAX_SIZE_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Frame Max Size"), + +#define SW_API_PT_FRAME_MAX_SIZE_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_FRAME_MAX_SIZE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_FRAME_MAX_SIZE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_FRAME_MAX_SIZE_SET, SW_UINT32, 4, SW_PARAM_IN, "Frame Max Size"), + +#define SW_API_PT_INTERFACE_3AZ_STATUS_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_INTERFACE_3AZ_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_INTERFACE_3AZ_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_INTERFACE_3AZ_STATUS_SET, SW_ENABLE, sizeof(a_bool_t), SW_PARAM_IN, "Status"), + +#define SW_API_PT_INTERFACE_3AZ_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_INTERFACE_3AZ_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_INTERFACE_3AZ_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_INTERFACE_3AZ_STATUS_GET, SW_ENABLE, sizeof(a_bool_t), SW_PARAM_PTR|SW_PARAM_OUT, "Status"), + +#define SW_API_PT_PROMISC_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_PROMISC_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_PROMISC_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_PT_PROMISC_MODE_SET, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_PT_PROMISC_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_PROMISC_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_PT_PROMISC_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_PT_PROMISC_MODE_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Enable"), + +#define SW_API_PT_INTERFACE_EEE_CFG_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_INTERFACE_EEE_CFG_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_INTERFACE_EEE_CFG_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_INTERFACE_EEE_CFG_SET, SW_PORT_EEE_CONFIG, \ + sizeof(fal_port_eee_cfg_t), SW_PARAM_PTR|SW_PARAM_IN, "EEE"), + +#define SW_API_PT_INTERFACE_EEE_CFG_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_INTERFACE_EEE_CFG_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_INTERFACE_EEE_CFG_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_INTERFACE_EEE_CFG_GET, SW_PORT_EEE_CONFIG,\ + sizeof(fal_port_eee_cfg_t), SW_PARAM_PTR|SW_PARAM_OUT, "EEE"), + +#define SW_API_PT_SOURCE_FILTER_CONFIG_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_SOURCE_FILTER_CONFIG_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_SOURCE_FILTER_CONFIG_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_SOURCE_FILTER_CONFIG_GET, SW_SRC_FILTER_CONFIG, \ + sizeof(fal_src_filter_config_t), SW_PARAM_PTR|SW_PARAM_OUT, "srcfilter config"), + +#define SW_API_PT_SOURCE_FILTER_CONFIG_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_SOURCE_FILTER_CONFIG_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_SOURCE_FILTER_CONFIG_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_SOURCE_FILTER_CONFIG_SET, SW_SRC_FILTER_CONFIG, \ + sizeof(fal_src_filter_config_t), SW_PARAM_PTR|SW_PARAM_IN, "srcfilter config"), + +#define SW_API_PT_SWITCH_PORT_LOOPBACK_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_SWITCH_PORT_LOOPBACK_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_SWITCH_PORT_LOOPBACK_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_SWITCH_PORT_LOOPBACK_SET, SW_PORT_LOOPBACK_CONFIG, \ + sizeof(fal_loopback_config_t), SW_PARAM_PTR|SW_PARAM_IN, "LOOPBACK"), + +#define SW_API_PT_SWITCH_PORT_LOOPBACK_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_SWITCH_PORT_LOOPBACK_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_SWITCH_PORT_LOOPBACK_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_SWITCH_PORT_LOOPBACK_GET, SW_PORT_LOOPBACK_CONFIG,\ + sizeof(fal_loopback_config_t), SW_PARAM_PTR|SW_PARAM_OUT, "LOOPBACK"), + +#define SW_API_VLAN_ADD_DESC \ + SW_PARAM_DEF(SW_API_VLAN_ADD, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_VLAN_ADD, SW_UINT32, 4, SW_PARAM_IN, "Vlan Id"), + +#define SW_API_VLAN_DEL_DESC \ + SW_PARAM_DEF(SW_API_VLAN_DEL, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_VLAN_DEL, SW_UINT32, 4, SW_PARAM_IN, "Vlan Id"), + +#define SW_API_VLAN_MEM_UPDATE_DESC \ + SW_PARAM_DEF(SW_API_VLAN_MEM_UPDATE, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_VLAN_MEM_UPDATE, SW_UINT32, 4, SW_PARAM_IN, "Vlan Id"), \ + SW_PARAM_DEF(SW_API_VLAN_MEM_UPDATE, SW_PBMP, sizeof(fal_pbmp_t), SW_PARAM_IN, \ + "Member Port Map"), \ + SW_PARAM_DEF(SW_API_VLAN_MEM_UPDATE, SW_PBMP, sizeof(fal_pbmp_t), SW_PARAM_IN, \ + "U Member Port Map"), + +#define SW_API_VLAN_FIND_DESC \ + SW_PARAM_DEF(SW_API_VLAN_FIND, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_VLAN_FIND, SW_UINT32, 4, SW_PARAM_IN, "Vlan Id"), \ + SW_PARAM_DEF(SW_API_VLAN_FIND, SW_VLAN, sizeof(fal_vlan_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "Vlan Entry"), + +#define SW_API_VLAN_NEXT_DESC \ + SW_PARAM_DEF(SW_API_VLAN_NEXT, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_VLAN_NEXT, SW_UINT32, 4, SW_PARAM_IN, "Vlan Id"), \ + SW_PARAM_DEF(SW_API_VLAN_NEXT, SW_VLAN, sizeof(fal_vlan_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "Vlan Entry"), + +#define SW_API_VLAN_APPEND_DESC \ + SW_PARAM_DEF(SW_API_VLAN_APPEND, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_VLAN_APPEND, SW_VLAN, sizeof(fal_vlan_t), SW_PARAM_PTR|SW_PARAM_IN, "Vlan Entry"), + +#define SW_API_VLAN_FLUSH_DESC \ + SW_PARAM_DEF(SW_API_VLAN_FLUSH, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), + +#define SW_API_VLAN_FID_SET_DESC \ + SW_PARAM_DEF(SW_API_VLAN_FID_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_VLAN_FID_SET, SW_UINT32, 4, SW_PARAM_IN, "Vlan ID"), \ + SW_PARAM_DEF(SW_API_VLAN_FID_SET, SW_UINT32, 4, SW_PARAM_IN, "FDB ID"), + +#define SW_API_VLAN_FID_GET_DESC \ + SW_PARAM_DEF(SW_API_VLAN_FID_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_VLAN_FID_GET, SW_UINT32, 4, SW_PARAM_IN, "Vlan ID"), \ + SW_PARAM_DEF(SW_API_VLAN_FID_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "FDB ID"), + +#define SW_API_VLAN_MEMBER_ADD_DESC \ + SW_PARAM_DEF(SW_API_VLAN_MEMBER_ADD, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_VLAN_MEMBER_ADD, SW_UINT32, 4, SW_PARAM_IN, "Vlan ID"), \ + SW_PARAM_DEF(SW_API_VLAN_MEMBER_ADD, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_VLAN_MEMBER_ADD, SW_EGMODE, sizeof(fal_pt_1q_egmode_t), \ + SW_PARAM_IN, "Port Info"), + +#define SW_API_VLAN_MEMBER_DEL_DESC \ + SW_PARAM_DEF(SW_API_VLAN_MEMBER_DEL, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_VLAN_MEMBER_DEL, SW_UINT32, 4, SW_PARAM_IN, "Vlan ID"), \ + SW_PARAM_DEF(SW_API_VLAN_MEMBER_DEL, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), + +#define SW_API_VLAN_LEARN_STATE_SET_DESC \ + SW_PARAM_DEF(SW_API_VLAN_LEARN_STATE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_VLAN_LEARN_STATE_SET, SW_UINT32, 4, SW_PARAM_IN, "Vlan ID"), \ + SW_PARAM_DEF(SW_API_VLAN_LEARN_STATE_SET, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_VLAN_LEARN_STATE_GET_DESC \ + SW_PARAM_DEF(SW_API_VLAN_LEARN_STATE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_VLAN_LEARN_STATE_GET, SW_UINT32, 4, SW_PARAM_IN, "Vlan ID"), \ + SW_PARAM_DEF(SW_API_VLAN_LEARN_STATE_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Enable"), + +#define SW_API_LAN_WAN_CFG_SET_DESC \ + SW_PARAM_DEF(SW_API_LAN_WAN_CFG_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_LAN_WAN_CFG_SET, SW_LAN_WAN_CFG, sizeof(qca_lan_wan_cfg_t), \ + SW_PARAM_PTR|SW_PARAM_IN, "Vlan Lan Wan Configuration"), + +#define SW_API_LAN_WAN_CFG_GET_DESC \ + SW_PARAM_DEF(SW_API_LAN_WAN_CFG_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_LAN_WAN_CFG_GET, SW_LAN_WAN_CFG, sizeof(qca_lan_wan_cfg_t), \ + SW_PARAM_PTR|SW_PARAM_OUT, "Vlan Lan Wan Configuration"), + +#define SW_API_PT_ING_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_ING_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_ING_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port No."), \ + SW_PARAM_DEF(SW_API_PT_ING_MODE_GET, SW_1QMODE, sizeof(fal_pt_1qmode_t), \ + SW_PARAM_PTR|SW_PARAM_OUT, "1qmode"), + +#define SW_API_PT_ING_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_ING_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_ING_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port No."), \ + SW_PARAM_DEF(SW_API_PT_ING_MODE_SET, SW_1QMODE, sizeof(fal_pt_1qmode_t), \ + SW_PARAM_IN, "1qmode"), + +#define SW_API_PT_EG_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_EG_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_EG_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port No."), \ + SW_PARAM_DEF(SW_API_PT_EG_MODE_GET, SW_EGMODE, sizeof(fal_pt_1q_egmode_t),\ + SW_PARAM_PTR|SW_PARAM_OUT, "egvlan"), + +#define SW_API_PT_EG_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_EG_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_EG_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port No."), \ + SW_PARAM_DEF(SW_API_PT_EG_MODE_SET, SW_EGMODE, sizeof(fal_pt_1q_egmode_t), \ + SW_PARAM_IN, "egvlan"), + +#define SW_API_PT_VLAN_MEM_ADD_DESC \ + SW_PARAM_DEF(SW_API_PT_VLAN_MEM_ADD, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_MEM_ADD, SW_UINT32, 4, SW_PARAM_IN, "Port No."), \ + SW_PARAM_DEF(SW_API_PT_VLAN_MEM_ADD, SW_UINT32, 4, SW_PARAM_IN, "Member Port Id"), + +#define SW_API_PT_VLAN_MEM_DEL_DESC \ + SW_PARAM_DEF(SW_API_PT_VLAN_MEM_DEL, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_MEM_DEL, SW_UINT32, 4, SW_PARAM_IN, "Port No."), \ + SW_PARAM_DEF(SW_API_PT_VLAN_MEM_DEL, SW_UINT32, 4, SW_PARAM_IN, "Member Port Id"), + +#define SW_API_PT_VLAN_MEM_UPDATE_DESC \ + SW_PARAM_DEF(SW_API_PT_VLAN_MEM_UPDATE, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_MEM_UPDATE, SW_UINT32, 4, SW_PARAM_IN, "Port No."), \ + SW_PARAM_DEF(SW_API_PT_VLAN_MEM_UPDATE, SW_PBMP, sizeof(fal_pbmp_t), SW_PARAM_IN, \ + "Member Port Bitmap"), + +#define SW_API_PT_VLAN_MEM_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_VLAN_MEM_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_MEM_GET, SW_UINT32, 4, SW_PARAM_IN, "Port No."), \ + SW_PARAM_DEF(SW_API_PT_VLAN_MEM_GET, SW_PBMP, sizeof(fal_pbmp_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "Member Port Bitmap"), + +#define SW_API_PT_DEF_VID_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_DEF_VID_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_DEF_VID_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID."), \ + SW_PARAM_DEF(SW_API_PT_DEF_VID_SET, SW_UINT32, 4, SW_PARAM_IN, "Vlan Id"), + +#define SW_API_PT_DEF_VID_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_DEF_VID_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_DEF_VID_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID."), \ + SW_PARAM_DEF(SW_API_PT_DEF_VID_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Vlan Id"), + +#define SW_API_PT_FORCE_DEF_VID_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_FORCE_DEF_VID_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_FORCE_DEF_VID_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_FORCE_DEF_VID_SET, SW_ENABLE, 4, SW_PARAM_IN, "Force"), + +#define SW_API_PT_FORCE_DEF_VID_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_FORCE_DEF_VID_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_FORCE_DEF_VID_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_FORCE_DEF_VID_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Force"), + +#define SW_API_PT_FORCE_PORTVLAN_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_FORCE_PORTVLAN_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_FORCE_PORTVLAN_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_FORCE_PORTVLAN_SET, SW_ENABLE, 4, SW_PARAM_IN, "Force"), + +#define SW_API_PT_FORCE_PORTVLAN_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_FORCE_PORTVLAN_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_FORCE_PORTVLAN_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_FORCE_PORTVLAN_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Force"), + +#define SW_API_PT_NESTVLAN_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_NESTVLAN_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_NESTVLAN_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_NESTVLAN_SET, SW_ENABLE, 4, SW_PARAM_IN, "Nestvlan"), + +#define SW_API_PT_NESTVLAN_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_NESTVLAN_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_NESTVLAN_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_NESTVLAN_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Nestvlan"), + +#define SW_API_NESTVLAN_TPID_SET_DESC \ + SW_PARAM_DEF(SW_API_NESTVLAN_TPID_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NESTVLAN_TPID_SET, SW_UINT32, 4, SW_PARAM_IN, "TPID"), + +#define SW_API_NESTVLAN_TPID_GET_DESC \ + SW_PARAM_DEF(SW_API_NESTVLAN_TPID_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NESTVLAN_TPID_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "TPID"), + +#define SW_API_PT_IN_VLAN_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_IN_VLAN_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_IN_VLAN_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_IN_VLAN_MODE_SET, SW_INVLAN, sizeof(fal_pt_invlan_mode_t), SW_PARAM_IN, "Invlan"), + +#define SW_API_PT_IN_VLAN_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_IN_VLAN_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_IN_VLAN_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_IN_VLAN_MODE_GET, SW_INVLAN, sizeof(fal_pt_invlan_mode_t), SW_PARAM_PTR|SW_PARAM_OUT, "Invlan"), + +#define SW_API_PT_TLS_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_TLS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_TLS_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_TLS_SET, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_PT_TLS_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_TLS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_TLS_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_TLS_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Enable"), + +#define SW_API_PT_PRI_PROPAGATION_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_PRI_PROPAGATION_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_PRI_PROPAGATION_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_PRI_PROPAGATION_SET, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_PT_PRI_PROPAGATION_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_PRI_PROPAGATION_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_PRI_PROPAGATION_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_PRI_PROPAGATION_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Enable"), + +#define SW_API_PT_DEF_SVID_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_DEF_SVID_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_DEF_SVID_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_DEF_SVID_SET, SW_UINT32, 4, SW_PARAM_IN, "svid"), + +#define SW_API_PT_DEF_SVID_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_DEF_SVID_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_DEF_SVID_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_DEF_SVID_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "svid"), + +#define SW_API_PT_DEF_CVID_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_DEF_CVID_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_DEF_CVID_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_DEF_CVID_SET, SW_UINT32, 4, SW_PARAM_IN, "cvid"), + +#define SW_API_PT_DEF_CVID_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_DEF_CVID_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_DEF_CVID_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_DEF_CVID_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "cvid"), + +#define SW_API_PT_VLAN_PROPAGATION_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_VLAN_PROPAGATION_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_PROPAGATION_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_PROPAGATION_SET, SW_VLANPROPAGATION, sizeof(fal_vlan_propagation_mode_t), SW_PARAM_IN, "Vlan propagation"), + +#define SW_API_PT_VLAN_PROPAGATION_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_VLAN_PROPAGATION_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_PROPAGATION_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_PROPAGATION_GET, SW_VLANPROPAGATION, sizeof(fal_vlan_propagation_mode_t), SW_PARAM_PTR|SW_PARAM_OUT, "Vlan propagation"), + +#define SW_API_PT_VLAN_TRANS_ADD_DESC \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ADD, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ADD, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ADD, SW_VLANTRANSLATION, sizeof(fal_vlan_trans_entry_t), SW_PARAM_PTR|SW_PARAM_IN, "Vlan Translation"), + +#define SW_API_PT_VLAN_TRANS_DEL_DESC \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_DEL, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_DEL, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_DEL, SW_VLANTRANSLATION, sizeof(fal_vlan_trans_entry_t), SW_PARAM_PTR|SW_PARAM_IN, "Vlan Translation"), + +#define SW_API_PT_VLAN_TRANS_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_GET, SW_VLANTRANSLATION, sizeof(fal_vlan_trans_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Vlan Translation"), + +#define SW_API_QINQ_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_QINQ_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_QINQ_MODE_SET, SW_QINQMODE, sizeof(fal_qinq_mode_t), SW_PARAM_IN, "qinq mode"), + +#define SW_API_QINQ_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_QINQ_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_QINQ_MODE_GET, SW_QINQMODE, sizeof(fal_qinq_mode_t), SW_PARAM_PTR|SW_PARAM_OUT, "qinq mode"), + +#define SW_API_PT_QINQ_ROLE_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_QINQ_ROLE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_QINQ_ROLE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_QINQ_ROLE_SET, SW_QINQROLE, sizeof(fal_qinq_port_role_t), SW_PARAM_IN, "qinq role"), + +#define SW_API_PT_QINQ_ROLE_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_QINQ_ROLE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_QINQ_ROLE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_QINQ_ROLE_GET, SW_QINQROLE, sizeof(fal_qinq_port_role_t), SW_PARAM_PTR|SW_PARAM_OUT, "qinq role"), + +#define SW_API_PT_VLAN_TRANS_ITERATE_DESC \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ITERATE, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ITERATE, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ITERATE, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Iterator"),\ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ITERATE, SW_VLANTRANSLATION, sizeof(fal_vlan_trans_entry_t), SW_PARAM_PTR|SW_PARAM_OUT, "Vlan Translation"), + +#define SW_API_PT_MAC_VLAN_XLT_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_MAC_VLAN_XLT_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_MAC_VLAN_XLT_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_MAC_VLAN_XLT_SET, SW_ENABLE, 4, SW_PARAM_IN, "Status"), + +#define SW_API_PT_MAC_VLAN_XLT_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_MAC_VLAN_XLT_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_MAC_VLAN_XLT_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_MAC_VLAN_XLT_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Status"), + +#define SW_API_NETISOLATE_SET_DESC \ + SW_PARAM_DEF(SW_API_NETISOLATE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NETISOLATE_SET, SW_ENABLE, 4, SW_PARAM_IN, "enable"), + +#define SW_API_NETISOLATE_GET_DESC \ + SW_PARAM_DEF(SW_API_NETISOLATE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NETISOLATE_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "enable"), + +#define SW_API_EG_FLTR_BYPASS_EN_SET_DESC \ + SW_PARAM_DEF(SW_API_EG_FLTR_BYPASS_EN_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_EG_FLTR_BYPASS_EN_SET, SW_ENABLE, 4, SW_PARAM_IN, "enable"), + +#define SW_API_EG_FLTR_BYPASS_EN_GET_DESC \ + SW_PARAM_DEF(SW_API_EG_FLTR_BYPASS_EN_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_EG_FLTR_BYPASS_EN_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "enable"), + +#define SW_API_PT_VRF_ID_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_VRF_ID_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_VRF_ID_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_VRF_ID_SET, SW_UINT32, 4, SW_PARAM_IN, "vrf_id"), + +#define SW_API_PT_VRF_ID_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_VRF_ID_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_VRF_ID_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_VRF_ID_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "vrf_id"), + +#define SW_API_GLOBAL_QINQ_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_GLOBAL_QINQ_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_GLOBAL_QINQ_MODE_SET, SW_GLOBAL_QINQMODE, sizeof(fal_global_qinq_mode_t), SW_PARAM_PTR|SW_PARAM_IN, "global qinq mode"), + +#define SW_API_GLOBAL_QINQ_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_GLOBAL_QINQ_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_GLOBAL_QINQ_MODE_GET, SW_GLOBAL_QINQMODE, sizeof(fal_global_qinq_mode_t), SW_PARAM_PTR|SW_PARAM_OUT, "global qinq mode"), + +#define SW_API_PORT_QINQ_MODE_SET_DESC \ + SW_PARAM_DEF( SW_API_PORT_QINQ_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF( SW_API_PORT_QINQ_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF( SW_API_PORT_QINQ_MODE_SET, SW_PT_QINQMODE, sizeof(fal_port_qinq_role_t), SW_PARAM_PTR|SW_PARAM_IN, "port qinq mode"), + +#define SW_API_PORT_QINQ_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_PORT_QINQ_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PORT_QINQ_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PORT_QINQ_MODE_GET, SW_PT_QINQMODE, sizeof(fal_port_qinq_role_t), SW_PARAM_PTR|SW_PARAM_OUT, "port qinq mode"), + +#define SW_API_TPID_SET_DESC \ + SW_PARAM_DEF(SW_API_TPID_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_TPID_SET, SW_TPID, sizeof(fal_tpid_t), SW_PARAM_PTR|SW_PARAM_IN, "ingress tpid"), + +#define SW_API_TPID_GET_DESC \ + SW_PARAM_DEF(SW_API_TPID_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_TPID_GET, SW_TPID, sizeof(fal_tpid_t), SW_PARAM_PTR|SW_PARAM_OUT, "ingress tpid"), + +#define SW_API_EGRESS_TPID_SET_DESC \ + SW_PARAM_DEF(SW_API_EGRESS_TPID_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_EGRESS_TPID_SET, SW_TPID, sizeof(fal_tpid_t), SW_PARAM_PTR|SW_PARAM_IN, "egress tpid"), + +#define SW_API_EGRESS_TPID_GET_DESC \ + SW_PARAM_DEF(SW_API_EGRESS_TPID_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_EGRESS_TPID_GET, SW_TPID, sizeof(fal_tpid_t), SW_PARAM_PTR|SW_PARAM_OUT, "egress tpid"), + +#define SW_API_PT_INGRESS_VLAN_FILTER_SET_DESC \ + SW_PARAM_DEF( SW_API_PT_INGRESS_VLAN_FILTER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF( SW_API_PT_INGRESS_VLAN_FILTER_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF( SW_API_PT_INGRESS_VLAN_FILTER_SET, SW_INGRESS_FILTER, sizeof(fal_ingress_vlan_filter_t), SW_PARAM_PTR|SW_PARAM_IN, "ingress filter mode"), + +#define SW_API_PT_INGRESS_VLAN_FILTER_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_INGRESS_VLAN_FILTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_INGRESS_VLAN_FILTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_INGRESS_VLAN_FILTER_GET, SW_INGRESS_FILTER, sizeof(fal_ingress_vlan_filter_t), SW_PARAM_PTR|SW_PARAM_OUT, "ingress filter mode"), + +#define SW_API_PT_DEFAULT_VLANTAG_SET_DESC \ + SW_PARAM_DEF( SW_API_PT_DEFAULT_VLANTAG_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF( SW_API_PT_DEFAULT_VLANTAG_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF( SW_API_PT_DEFAULT_VLANTAG_SET, SW_PT_VLAN_DIRECTION, sizeof(fal_port_vlan_direction_t), SW_PARAM_IN, "vlan direction"), \ + SW_PARAM_DEF( SW_API_PT_DEFAULT_VLANTAG_SET, SW_PT_DEF_VID_EN, sizeof(fal_port_default_vid_enable_t), SW_PARAM_PTR|SW_PARAM_IN, "default vid en"), \ + SW_PARAM_DEF( SW_API_PT_DEFAULT_VLANTAG_SET, SW_PT_VLAN_TAG, sizeof(fal_port_vlan_tag_t), SW_PARAM_PTR|SW_PARAM_IN, "vlan tag"), + +#define SW_API_PT_DEFAULT_VLANTAG_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_DEFAULT_VLANTAG_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_DEFAULT_VLANTAG_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_DEFAULT_VLANTAG_GET, SW_PT_VLAN_DIRECTION, sizeof(fal_port_vlan_direction_t), SW_PARAM_IN, "vlan direction"), \ + SW_PARAM_DEF(SW_API_PT_DEFAULT_VLANTAG_GET, SW_PT_DEF_VID_EN, sizeof(fal_port_default_vid_enable_t), SW_PARAM_PTR|SW_PARAM_OUT, "default vid en"), \ + SW_PARAM_DEF(SW_API_PT_DEFAULT_VLANTAG_GET, SW_PT_VLAN_TAG, sizeof(fal_port_vlan_tag_t), SW_PARAM_PTR|SW_PARAM_OUT, "vlan tag"), + +#define SW_API_PT_TAG_PROPAGATION_SET_DESC \ + SW_PARAM_DEF( SW_API_PT_TAG_PROPAGATION_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF( SW_API_PT_TAG_PROPAGATION_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF( SW_API_PT_TAG_PROPAGATION_SET, SW_PT_VLAN_DIRECTION, sizeof(fal_port_vlan_direction_t), SW_PARAM_IN, "vlan direction"), \ + SW_PARAM_DEF( SW_API_PT_TAG_PROPAGATION_SET, SW_TAG_PROPAGATION, sizeof(fal_vlantag_propagation_t), SW_PARAM_PTR|SW_PARAM_IN, "tag propagation"), + +#define SW_API_PT_TAG_PROPAGATION_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_TAG_PROPAGATION_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_TAG_PROPAGATION_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_TAG_PROPAGATION_GET, SW_PT_VLAN_DIRECTION, sizeof(fal_port_vlan_direction_t), SW_PARAM_IN, "vlan direction"), \ + SW_PARAM_DEF(SW_API_PT_TAG_PROPAGATION_GET, SW_TAG_PROPAGATION, sizeof(fal_vlantag_propagation_t), SW_PARAM_PTR|SW_PARAM_OUT, "tag propagation"), + +#define SW_API_PT_VLANTAG_EGMODE_SET_DESC \ + SW_PARAM_DEF( SW_API_PT_VLANTAG_EGMODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF( SW_API_PT_VLANTAG_EGMODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF( SW_API_PT_VLANTAG_EGMODE_SET, SW_EGRESS_MODE, sizeof(fal_vlantag_egress_mode_t), SW_PARAM_PTR|SW_PARAM_IN, "egress mode"), + +#define SW_API_PT_VLANTAG_EGMODE_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_VLANTAG_EGMODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_VLANTAG_EGMODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_VLANTAG_EGMODE_GET, SW_EGRESS_MODE, sizeof(fal_vlantag_egress_mode_t), SW_PARAM_PTR|SW_PARAM_OUT, "egress mode"), + +#define SW_API_PT_VLAN_XLT_MISS_CMD_SET_DESC \ + SW_PARAM_DEF( SW_API_PT_VLAN_XLT_MISS_CMD_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF( SW_API_PT_VLAN_XLT_MISS_CMD_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF( SW_API_PT_VLAN_XLT_MISS_CMD_SET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_IN, "translation_miss_action"), + +#define SW_API_PT_VLAN_XLT_MISS_CMD_GET_DESC \ + SW_PARAM_DEF( SW_API_PT_VLAN_XLT_MISS_CMD_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF( SW_API_PT_VLAN_XLT_MISS_CMD_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF( SW_API_PT_VLAN_XLT_MISS_CMD_GET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_PTR|SW_PARAM_OUT, "translation_miss_action"), + +#define SW_API_PT_VSI_EGMODE_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_VSI_EGMODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_VSI_EGMODE_SET, SW_UINT32, 4, SW_PARAM_IN, "VSI ID"), \ + SW_PARAM_DEF(SW_API_PT_VSI_EGMODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_VSI_EGMODE_SET, SW_EGMODE, sizeof(fal_pt_1q_egmode_t), SW_PARAM_IN, "vsi_egress_vlan_mode"), + +#define SW_API_PT_VSI_EGMODE_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_VSI_EGMODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_VSI_EGMODE_GET, SW_UINT32, 4, SW_PARAM_IN, "VSI ID"), \ + SW_PARAM_DEF(SW_API_PT_VSI_EGMODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_VSI_EGMODE_GET, SW_EGMODE, sizeof(fal_pt_1q_egmode_t), SW_PARAM_PTR|SW_PARAM_OUT, "vsi_egress_vlan_mode"), + +#define SW_API_PT_VLANTAG_VSI_EGMODE_EN_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_VLANTAG_VSI_EGMODE_EN_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_VLANTAG_VSI_EGMODE_EN_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_VLANTAG_VSI_EGMODE_EN_SET, SW_ENABLE, 4, SW_PARAM_IN, "vsi_egress_vlan_mode_en"), + +#define SW_API_PT_VLANTAG_VSI_EGMODE_EN_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_VLANTAG_VSI_EGMODE_EN_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_VLANTAG_VSI_EGMODE_EN_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_VLANTAG_VSI_EGMODE_EN_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "vsi_egress_vlan_mode_en"), + +#define SW_API_PT_VLAN_TRANS_ADV_ADD_DESC \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ADV_ADD, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ADV_ADD, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ADV_ADD, SW_PT_VLAN_DIRECTION, sizeof(fal_port_vlan_direction_t), SW_PARAM_IN, "vlan direction"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ADV_ADD, SW_PT_VLAN_TRANS_ADV_RULE, sizeof(fal_vlan_trans_adv_rule_t), SW_PARAM_PTR|SW_PARAM_IN, "vlan trans rule"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ADV_ADD, SW_PT_VLAN_TRANS_ADV_ACTION, sizeof(fal_vlan_trans_adv_action_t), SW_PARAM_PTR|SW_PARAM_IN, "vlan trans action"), + +#define SW_API_PT_VLAN_TRANS_ADV_DEL_DESC \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ADV_DEL, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ADV_DEL, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ADV_DEL, SW_PT_VLAN_DIRECTION, sizeof(fal_port_vlan_direction_t), SW_PARAM_IN, "vlan direction"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ADV_DEL, SW_PT_VLAN_TRANS_ADV_RULE, sizeof(fal_vlan_trans_adv_rule_t), SW_PARAM_PTR|SW_PARAM_IN, "vlan trans rule"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ADV_DEL, SW_PT_VLAN_TRANS_ADV_ACTION, sizeof(fal_vlan_trans_adv_action_t), SW_PARAM_PTR|SW_PARAM_IN, "vlan trans action"), + +#define SW_API_PT_VLAN_TRANS_ADV_GETFIRST_DESC \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ADV_GETFIRST, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ADV_GETFIRST, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ADV_GETFIRST, SW_PT_VLAN_DIRECTION, sizeof(fal_port_vlan_direction_t), SW_PARAM_IN, "vlan direction"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ADV_GETFIRST, SW_PT_VLAN_TRANS_ADV_RULE, sizeof(fal_vlan_trans_adv_rule_t), SW_PARAM_PTR|SW_PARAM_OUT, "vlan trans rule"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ADV_GETFIRST, SW_PT_VLAN_TRANS_ADV_ACTION, sizeof(fal_vlan_trans_adv_action_t), SW_PARAM_PTR|SW_PARAM_OUT, "vlan trans action"), + +#define SW_API_PT_VLAN_TRANS_ADV_GETNEXT_DESC \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ADV_GETNEXT, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ADV_GETNEXT, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ADV_GETNEXT, SW_PT_VLAN_DIRECTION, sizeof(fal_port_vlan_direction_t), SW_PARAM_IN, "vlan direction"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ADV_GETNEXT, SW_PT_VLAN_TRANS_ADV_RULE, sizeof(fal_vlan_trans_adv_rule_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "vlan trans rule"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_TRANS_ADV_GETNEXT, SW_PT_VLAN_TRANS_ADV_ACTION, sizeof(fal_vlan_trans_adv_action_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "vlan trans action"), + +#define SW_API_PT_VLAN_COUNTER_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_VLAN_COUNTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_COUNTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Cnt Index"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_COUNTER_GET, SW_PT_VLAN_COUNTER, sizeof(fal_port_vlan_counter_t), SW_PARAM_PTR|SW_PARAM_OUT, "enable"), + +#define SW_API_PT_VLAN_COUNTER_CLEANUP_DESC \ + SW_PARAM_DEF(SW_API_PT_VLAN_COUNTER_CLEANUP, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_VLAN_COUNTER_CLEANUP, SW_UINT32, 4, SW_PARAM_IN, "Cnt Index"), + +#define SW_API_FDB_ADD_DESC \ + SW_PARAM_DEF(SW_API_FDB_ADD, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_ADD, SW_FDBENTRY, sizeof(fal_fdb_entry_t), SW_PARAM_PTR|SW_PARAM_IN, "Fdb Entry"), + +#define SW_API_FDB_DELALL_DESC \ + SW_PARAM_DEF(SW_API_FDB_DELALL, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_DELALL, SW_UINT32, 4, SW_PARAM_IN, "Flag"), + +#define SW_API_FDB_DELPORT_DESC \ + SW_PARAM_DEF(SW_API_FDB_DELPORT, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_DELPORT, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_FDB_DELPORT, SW_UINT32, 4, SW_PARAM_IN, "Flag"), + +#define SW_API_FDB_DELMAC_DESC \ + SW_PARAM_DEF(SW_API_FDB_DELMAC, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_DELMAC, SW_FDBENTRY, sizeof(fal_fdb_entry_t), SW_PARAM_PTR|SW_PARAM_IN, "Fdb Entry"), + +#define SW_API_FDB_FIRST_DESC \ + SW_PARAM_DEF(SW_API_FDB_FIRST, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_FIRST, SW_FDBENTRY, sizeof(fal_fdb_entry_t), SW_PARAM_PTR|SW_PARAM_OUT, "Fdb Entry"), + +#define SW_API_FDB_NEXT_DESC \ + SW_PARAM_DEF(SW_API_FDB_NEXT, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_NEXT, SW_FDBENTRY, sizeof(fal_fdb_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Fdb Entry"), + +#define SW_API_FDB_FIND_DESC \ + SW_PARAM_DEF(SW_API_FDB_FIND, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_FIND, SW_FDBENTRY, sizeof(fal_fdb_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Fdb Entry"), + +#define SW_API_FDB_PT_LEARN_SET_DESC \ + SW_PARAM_DEF(SW_API_FDB_PT_LEARN_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_PT_LEARN_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_FDB_PT_LEARN_SET, SW_ENABLE, 4, SW_PARAM_IN, "Learn"), + +#define SW_API_FDB_PT_LEARN_GET_DESC \ + SW_PARAM_DEF(SW_API_FDB_PT_LEARN_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_PT_LEARN_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_FDB_PT_LEARN_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Learn"), + +#define SW_API_FDB_PT_NEWADDR_LEARN_SET_DESC \ + SW_PARAM_DEF(SW_API_FDB_PT_NEWADDR_LEARN_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FDB_PT_NEWADDR_LEARN_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_FDB_PT_NEWADDR_LEARN_SET, SW_ENABLE, 4, SW_PARAM_IN, "Learn Ctrl"),\ + SW_PARAM_DEF(SW_API_FDB_PT_NEWADDR_LEARN_SET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_IN, "Action"), + +#define SW_API_FDB_PT_NEWADDR_LEARN_GET_DESC \ + SW_PARAM_DEF(SW_API_FDB_PT_NEWADDR_LEARN_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FDB_PT_NEWADDR_LEARN_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_FDB_PT_NEWADDR_LEARN_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Learn Ctrl"),\ + SW_PARAM_DEF(SW_API_FDB_PT_NEWADDR_LEARN_GET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_PTR|SW_PARAM_OUT, "Action"), + +#define SW_API_FDB_PT_STAMOVE_SET_DESC \ + SW_PARAM_DEF(SW_API_FDB_PT_STAMOVE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FDB_PT_STAMOVE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_FDB_PT_STAMOVE_SET, SW_ENABLE, 4, SW_PARAM_IN, "Station Move"),\ + SW_PARAM_DEF(SW_API_FDB_PT_STAMOVE_SET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_IN, "Action"), + +#define SW_API_FDB_PT_STAMOVE_GET_DESC \ + SW_PARAM_DEF(SW_API_FDB_PT_STAMOVE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FDB_PT_STAMOVE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_FDB_PT_STAMOVE_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Station Move"),\ + SW_PARAM_DEF(SW_API_FDB_PT_STAMOVE_GET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_PTR|SW_PARAM_OUT, "Action"), + +#define SW_API_FDB_AGE_CTRL_SET_DESC \ + SW_PARAM_DEF(SW_API_FDB_AGE_CTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_AGE_CTRL_SET, SW_ENABLE, 4, SW_PARAM_IN, "Age"), + +#define SW_API_FDB_AGE_CTRL_GET_DESC \ + SW_PARAM_DEF(SW_API_FDB_AGE_CTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_AGE_CTRL_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Age"), + +#define SW_API_FDB_LEARN_CTRL_SET_DESC \ + SW_PARAM_DEF(SW_API_FDB_LEARN_CTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_LEARN_CTRL_SET, SW_ENABLE, 4, SW_PARAM_IN, "Learn Ctrl"), + +#define SW_API_FDB_LEARN_CTRL_GET_DESC \ + SW_PARAM_DEF(SW_API_FDB_LEARN_CTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_LEARN_CTRL_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Learn Ctrl"), + +#define SW_API_FDB_VLAN_IVL_SVL_SET_DESC \ + SW_PARAM_DEF(SW_API_FDB_VLAN_IVL_SVL_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_VLAN_IVL_SVL_SET, SW_FDBSMODE, 4, SW_PARAM_IN, "Smode"), + +#define SW_API_FDB_VLAN_IVL_SVL_GET_DESC \ + SW_PARAM_DEF(SW_API_FDB_VLAN_IVL_SVL_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_VLAN_IVL_SVL_GET, SW_FDBSMODE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Smode"), + +#define SW_API_FDB_AGE_TIME_SET_DESC \ + SW_PARAM_DEF(SW_API_FDB_AGE_TIME_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_AGE_TIME_SET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Time"), + +#define SW_API_FDB_AGE_TIME_GET_DESC \ + SW_PARAM_DEF(SW_API_FDB_AGE_TIME_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_AGE_TIME_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Time"), + +#define SW_API_FDB_ITERATE_DESC \ + SW_PARAM_DEF(SW_API_FDB_ITERATE, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_ITERATE, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Iterator"),\ + SW_PARAM_DEF(SW_API_FDB_ITERATE, SW_FDBENTRY, sizeof(fal_fdb_entry_t), SW_PARAM_PTR|SW_PARAM_OUT, "Fdb Entry"), + +#define SW_API_FDB_EXTEND_NEXT_DESC \ + SW_PARAM_DEF(SW_API_FDB_EXTEND_NEXT, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_EXTEND_NEXT, SW_FDBOPRATION, sizeof(fal_fdb_op_t), SW_PARAM_PTR|SW_PARAM_IN, "OperateOption"),\ + SW_PARAM_DEF(SW_API_FDB_EXTEND_NEXT, SW_FDBENTRY, sizeof(fal_fdb_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Fdb Entry"), + +#define SW_API_FDB_EXTEND_FIRST_DESC \ + SW_PARAM_DEF(SW_API_FDB_EXTEND_FIRST, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_EXTEND_FIRST, SW_FDBOPRATION, sizeof(fal_fdb_op_t), SW_PARAM_PTR|SW_PARAM_IN, "OperateOption"),\ + SW_PARAM_DEF(SW_API_FDB_EXTEND_FIRST, SW_FDBENTRY, sizeof(fal_fdb_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Fdb Entry"), + +#define SW_API_FDB_TRANSFER_DESC \ + SW_PARAM_DEF(SW_API_FDB_TRANSFER, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_TRANSFER, SW_UINT32, 4, SW_PARAM_IN, "Old Port ID"),\ + SW_PARAM_DEF(SW_API_FDB_TRANSFER, SW_UINT32, 4, SW_PARAM_IN, "New Port ID"),\ + SW_PARAM_DEF(SW_API_FDB_TRANSFER, SW_UINT32, 4, SW_PARAM_IN, "FID"),\ + SW_PARAM_DEF(SW_API_FDB_TRANSFER, SW_FDBOPRATION, sizeof(fal_fdb_op_t), SW_PARAM_PTR|SW_PARAM_IN, "OperateOption"), + +#define SW_API_PT_FDB_LEARN_COUNTER_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_FDB_LEARN_COUNTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_FDB_LEARN_COUNTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_PT_FDB_LEARN_COUNTER_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "LearnCnt"), + +#define SW_API_PT_FDB_LEARN_LIMIT_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_FDB_LEARN_LIMIT_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_FDB_LEARN_LIMIT_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_PT_FDB_LEARN_LIMIT_SET, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), \ + SW_PARAM_DEF(SW_API_PT_FDB_LEARN_LIMIT_SET, SW_UINT32, 4, SW_PARAM_IN, "LimitCnt"), + +#define SW_API_PT_FDB_LEARN_LIMIT_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_FDB_LEARN_LIMIT_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_PT_FDB_LEARN_LIMIT_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_PT_FDB_LEARN_LIMIT_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Enable"), \ + SW_PARAM_DEF(SW_API_PT_FDB_LEARN_LIMIT_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "LimitCnt"), + +#define SW_API_PT_FDB_LEARN_EXCEED_CMD_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_FDB_LEARN_EXCEED_CMD_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_FDB_LEARN_EXCEED_CMD_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_PT_FDB_LEARN_EXCEED_CMD_SET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_IN, "cmd"), + +#define SW_API_PT_FDB_LEARN_EXCEED_CMD_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_FDB_LEARN_EXCEED_CMD_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_FDB_LEARN_EXCEED_CMD_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_PT_FDB_LEARN_EXCEED_CMD_GET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_PTR|SW_PARAM_OUT, "cmd"), + +#define SW_API_FDB_LEARN_LIMIT_SET_DESC \ + SW_PARAM_DEF(SW_API_FDB_LEARN_LIMIT_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FDB_LEARN_LIMIT_SET, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), \ + SW_PARAM_DEF(SW_API_FDB_LEARN_LIMIT_SET, SW_UINT32, 4, SW_PARAM_IN, "LimitCnt"), + +#define SW_API_FDB_LEARN_LIMIT_GET_DESC \ + SW_PARAM_DEF(SW_API_FDB_LEARN_LIMIT_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_LEARN_LIMIT_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Enable"), \ + SW_PARAM_DEF(SW_API_FDB_LEARN_LIMIT_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "LimitCnt"), + +#define SW_API_FDB_LEARN_EXCEED_CMD_SET_DESC \ + SW_PARAM_DEF(SW_API_FDB_LEARN_EXCEED_CMD_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FDB_LEARN_EXCEED_CMD_SET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_IN, "cmd"), + +#define SW_API_FDB_LEARN_EXCEED_CMD_GET_DESC \ + SW_PARAM_DEF(SW_API_FDB_LEARN_EXCEED_CMD_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FDB_LEARN_EXCEED_CMD_GET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_PTR|SW_PARAM_OUT, "cmd"), + +#define SW_API_FDB_RESV_ADD_DESC \ + SW_PARAM_DEF(SW_API_FDB_RESV_ADD, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_RESV_ADD, SW_FDBENTRY, sizeof(fal_fdb_entry_t), SW_PARAM_PTR|SW_PARAM_IN, "Fdb Resv Entry"), + +#define SW_API_FDB_RESV_DEL_DESC \ + SW_PARAM_DEF(SW_API_FDB_RESV_DEL, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_RESV_DEL, SW_FDBENTRY, sizeof(fal_fdb_entry_t), SW_PARAM_PTR|SW_PARAM_IN, "Fdb Resv Entry"), + +#define SW_API_FDB_RESV_FIND_DESC \ + SW_PARAM_DEF(SW_API_FDB_RESV_FIND, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_RESV_FIND, SW_FDBENTRY, sizeof(fal_fdb_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Fdb Resv Entry"), + +#define SW_API_FDB_RESV_ITERATE_DESC \ + SW_PARAM_DEF(SW_API_FDB_RESV_ITERATE, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_RESV_ITERATE, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Iterator"),\ + SW_PARAM_DEF(SW_API_FDB_RESV_ITERATE, SW_FDBENTRY, sizeof(fal_fdb_entry_t), SW_PARAM_PTR|SW_PARAM_OUT, "Fdb Resv Entry"), + +#define SW_API_FDB_PT_LEARN_STATIC_SET_DESC \ + SW_PARAM_DEF(SW_API_FDB_PT_LEARN_STATIC_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_PT_LEARN_STATIC_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_FDB_PT_LEARN_STATIC_SET, SW_ENABLE, 4, SW_PARAM_IN, "LearnStatic"), + +#define SW_API_FDB_PT_LEARN_STATIC_GET_DESC \ + SW_PARAM_DEF(SW_API_FDB_PT_LEARN_STATIC_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_PT_LEARN_STATIC_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_FDB_PT_LEARN_STATIC_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "LearnStatic"), + +#define SW_API_FDB_PORT_ADD_DESC \ + SW_PARAM_DEF(SW_API_FDB_PORT_ADD, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_PORT_ADD, SW_UINT32, 4, SW_PARAM_IN, "FID"),\ + SW_PARAM_DEF(SW_API_FDB_PORT_ADD, SW_MACADDR, sizeof(fal_mac_addr_t), SW_PARAM_PTR|SW_PARAM_IN, "Address"),\ + SW_PARAM_DEF(SW_API_FDB_PORT_ADD, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), + +#define SW_API_FDB_PORT_DEL_DESC \ + SW_PARAM_DEF(SW_API_FDB_PORT_DEL, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_PORT_DEL, SW_UINT32, 4, SW_PARAM_IN, "FID"),\ + SW_PARAM_DEF(SW_API_FDB_PORT_DEL, SW_MACADDR, sizeof(fal_mac_addr_t), SW_PARAM_PTR|SW_PARAM_IN, "Address"),\ + SW_PARAM_DEF(SW_API_FDB_PORT_DEL, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), + +#define SW_API_FDB_RFS_SET_DESC \ + SW_PARAM_DEF(SW_API_FDB_RFS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_RFS_SET, SW_FDB_RFS, sizeof(fal_fdb_rfs_t), SW_PARAM_PTR|SW_PARAM_IN, "Fdb Rfs"), + +#define SW_API_FDB_RFS_DEL_DESC \ + SW_PARAM_DEF(SW_API_FDB_RFS_DEL, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_RFS_DEL, SW_FDB_RFS, sizeof(fal_fdb_rfs_t), SW_PARAM_PTR|SW_PARAM_IN, "Fdb Rfs"), + +#define SW_API_FDB_PT_MACLIMIT_CTRL_SET_DESC \ + SW_PARAM_DEF(SW_API_FDB_PT_MACLIMIT_CTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_PT_MACLIMIT_CTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_FDB_PT_MACLIMIT_CTRL_SET, SW_MACLIMIT_CTRL, sizeof(fal_maclimit_ctrl_t), SW_PARAM_PTR|SW_PARAM_IN, "MacLimit Ctrl"), + +#define SW_API_FDB_PT_MACLIMIT_CTRL_GET_DESC \ + SW_PARAM_DEF(SW_API_FDB_PT_MACLIMIT_CTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_PT_MACLIMIT_CTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_FDB_PT_MACLIMIT_CTRL_GET, SW_MACLIMIT_CTRL, sizeof(fal_maclimit_ctrl_t), SW_PARAM_PTR|SW_PARAM_OUT, "MacLimit Ctrl"), + +#define SW_API_FDB_DEL_BY_FID_DESC \ + SW_PARAM_DEF(SW_API_FDB_DEL_BY_FID, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_FDB_DEL_BY_FID, SW_UINT16, 2, SW_PARAM_IN, "FID"),\ + SW_PARAM_DEF(SW_API_FDB_DEL_BY_FID, SW_UINT32, 4, SW_PARAM_IN, "Flag"), + + +#define SW_API_ACL_LIST_CREAT_DESC \ + SW_PARAM_DEF(SW_API_ACL_LIST_CREAT, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_ACL_LIST_CREAT, SW_UINT32, 4, SW_PARAM_IN, "List ID"),\ + SW_PARAM_DEF(SW_API_ACL_LIST_CREAT, SW_UINT32, 4, SW_PARAM_IN, "List Priority"), + +#define SW_API_ACL_LIST_DESTROY_DESC \ + SW_PARAM_DEF(SW_API_ACL_LIST_DESTROY, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_ACL_LIST_DESTROY, SW_UINT32, 4, SW_PARAM_IN, "List ID"), + +#define SW_API_ACL_RULE_ADD_DESC \ + SW_PARAM_DEF(SW_API_ACL_RULE_ADD, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_ACL_RULE_ADD, SW_UINT32, 4, SW_PARAM_IN, "List ID"),\ + SW_PARAM_DEF(SW_API_ACL_RULE_ADD, SW_UINT32, 4, SW_PARAM_IN, "Rule ID"),\ + SW_PARAM_DEF(SW_API_ACL_RULE_ADD, SW_UINT32, 4, SW_PARAM_IN, "Rule Number"),\ + SW_PARAM_DEF(SW_API_ACL_RULE_ADD, SW_ACLRULE, sizeof(fal_acl_rule_t), SW_PARAM_PTR|SW_PARAM_IN, "Rule"), + +#define SW_API_ACL_RULE_DELETE_DESC \ + SW_PARAM_DEF(SW_API_ACL_RULE_DELETE, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_ACL_RULE_DELETE, SW_UINT32, 4, SW_PARAM_IN, "List ID"),\ + SW_PARAM_DEF(SW_API_ACL_RULE_DELETE, SW_UINT32, 4, SW_PARAM_IN, "Rule ID"),\ + SW_PARAM_DEF(SW_API_ACL_RULE_DELETE, SW_UINT32, 4, SW_PARAM_IN, "Rule Number"), + +#define SW_API_ACL_RULE_QUERY_DESC \ + SW_PARAM_DEF(SW_API_ACL_RULE_QUERY, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_ACL_RULE_QUERY, SW_UINT32, 4, SW_PARAM_IN, "List ID"),\ + SW_PARAM_DEF(SW_API_ACL_RULE_QUERY, SW_UINT32, 4, SW_PARAM_IN, "Rule ID"),\ + SW_PARAM_DEF(SW_API_ACL_RULE_QUERY, SW_ACLRULE, sizeof(fal_acl_rule_t), SW_PARAM_PTR|SW_PARAM_OUT, "Rule"), + +#define SW_API_ACL_LIST_BIND_DESC \ + SW_PARAM_DEF(SW_API_ACL_LIST_BIND, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_ACL_LIST_BIND, SW_UINT32, 4, SW_PARAM_IN, "List ID"),\ + SW_PARAM_DEF(SW_API_ACL_LIST_BIND, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_ACL_LIST_BIND, SW_UINT32, 4, SW_PARAM_IN, "List ID"),\ + SW_PARAM_DEF(SW_API_ACL_LIST_BIND, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), + +#define SW_API_ACL_LIST_UNBIND_DESC \ + SW_PARAM_DEF(SW_API_ACL_LIST_UNBIND, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_ACL_LIST_UNBIND, SW_UINT32, 4, SW_PARAM_IN, "List ID"),\ + SW_PARAM_DEF(SW_API_ACL_LIST_UNBIND, SW_UINT32, 4, SW_PARAM_IN, "Direction"),\ + SW_PARAM_DEF(SW_API_ACL_LIST_UNBIND, SW_UINT32, 4, SW_PARAM_IN, "Object Type"),\ + SW_PARAM_DEF(SW_API_ACL_LIST_UNBIND, SW_UINT32, 4, SW_PARAM_IN, "Object Index"), + +#define SW_API_ACL_STATUS_SET_DESC \ + SW_PARAM_DEF(SW_API_ACL_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_ACL_STATUS_SET, SW_ENABLE, 4, SW_PARAM_IN, "Status"), + +#define SW_API_ACL_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_ACL_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_ACL_STATUS_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Status"), + +#define SW_API_ACL_LIST_DUMP_DESC \ + SW_PARAM_DEF(SW_API_ACL_LIST_DUMP, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), + +#define SW_API_ACL_RULE_DUMP_DESC \ + SW_PARAM_DEF(SW_API_ACL_RULE_DUMP, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), + +#define SW_API_ACL_PT_UDF_PROFILE_SET_DESC \ + SW_PARAM_DEF(SW_API_ACL_PT_UDF_PROFILE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_ACL_PT_UDF_PROFILE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_ACL_PT_UDF_PROFILE_SET, SW_ACL_UDF_TYPE, sizeof(fal_acl_udf_type_t), SW_PARAM_IN, "udf_type"),\ + SW_PARAM_DEF(SW_API_ACL_PT_UDF_PROFILE_SET, SW_UINT32, 4, SW_PARAM_IN, "udf_offset"),\ + SW_PARAM_DEF(SW_API_ACL_PT_UDF_PROFILE_SET, SW_UINT32, 4, SW_PARAM_IN, "udf_length"), + +#define SW_API_ACL_PT_UDF_PROFILE_GET_DESC \ + SW_PARAM_DEF(SW_API_ACL_PT_UDF_PROFILE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_ACL_PT_UDF_PROFILE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_ACL_PT_UDF_PROFILE_GET, SW_ACL_UDF_TYPE, sizeof(fal_acl_udf_type_t), SW_PARAM_IN, "udf_type"),\ + SW_PARAM_DEF(SW_API_ACL_PT_UDF_PROFILE_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "udf_offset"),\ + SW_PARAM_DEF(SW_API_ACL_PT_UDF_PROFILE_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "udf_length"), + +#define SW_API_ACL_RULE_ACTIVE_DESC \ + SW_PARAM_DEF(SW_API_ACL_RULE_ACTIVE, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_ACL_RULE_ACTIVE, SW_UINT32, 4, SW_PARAM_IN, "List ID"),\ + SW_PARAM_DEF(SW_API_ACL_RULE_ACTIVE, SW_UINT32, 4, SW_PARAM_IN, "Rule ID"),\ + SW_PARAM_DEF(SW_API_ACL_RULE_ACTIVE, SW_UINT32, 4, SW_PARAM_IN, "Rule Number"), + +#define SW_API_ACL_RULE_DEACTIVE_DESC \ + SW_PARAM_DEF(SW_API_ACL_RULE_DEACTIVE, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_ACL_RULE_DEACTIVE, SW_UINT32, 4, SW_PARAM_IN, "List ID"),\ + SW_PARAM_DEF(SW_API_ACL_RULE_DEACTIVE, SW_UINT32, 4, SW_PARAM_IN, "Rule ID"),\ + SW_PARAM_DEF(SW_API_ACL_RULE_DEACTIVE, SW_UINT32, 4, SW_PARAM_IN, "Rule Number"), + +#define SW_API_ACL_RULE_SRC_FILTER_STS_SET_DESC \ + SW_PARAM_DEF(SW_API_ACL_RULE_SRC_FILTER_STS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_ACL_RULE_SRC_FILTER_STS_SET, SW_UINT32, 4, SW_PARAM_IN, "Rule ID"),\ + SW_PARAM_DEF(SW_API_ACL_RULE_SRC_FILTER_STS_SET, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_ACL_RULE_SRC_FILTER_STS_GET_DESC \ + SW_PARAM_DEF(SW_API_ACL_RULE_SRC_FILTER_STS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_ACL_RULE_SRC_FILTER_STS_GET, SW_UINT32, 4, SW_PARAM_IN, "Rule ID"),\ + SW_PARAM_DEF(SW_API_ACL_RULE_SRC_FILTER_STS_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Enable"), + +#define SW_API_ACL_UDF_SET_DESC \ + SW_PARAM_DEF(SW_API_ACL_UDF_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_ACL_UDF_SET, SW_ACL_UDF_PKT_TYPE, sizeof(fal_acl_udf_pkt_type_t), SW_PARAM_IN, "udf_packet_type"),\ + SW_PARAM_DEF(SW_API_ACL_UDF_SET, SW_UINT32, 4, SW_PARAM_IN, "udf_index"),\ + SW_PARAM_DEF(SW_API_ACL_UDF_SET, SW_ACL_UDF_TYPE, sizeof(fal_acl_udf_type_t), SW_PARAM_IN, "udf_type"),\ + SW_PARAM_DEF(SW_API_ACL_UDF_SET, SW_UINT32, 4, SW_PARAM_IN, "udf_offset"), + +#define SW_API_ACL_UDF_GET_DESC \ + SW_PARAM_DEF(SW_API_ACL_UDF_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_ACL_UDF_GET, SW_ACL_UDF_PKT_TYPE, sizeof(fal_acl_udf_pkt_type_t), SW_PARAM_IN, "udf_packet_type"),\ + SW_PARAM_DEF(SW_API_ACL_UDF_GET, SW_UINT32, 4, SW_PARAM_IN, "udf_index"),\ + SW_PARAM_DEF(SW_API_ACL_UDF_GET, SW_ACL_UDF_TYPE, sizeof(fal_acl_udf_type_t), SW_PARAM_PTR|SW_PARAM_OUT, "udf_type"),\ + SW_PARAM_DEF(SW_API_ACL_UDF_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "udf_offset"), + +#define SW_API_QOS_SCH_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_SCH_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_SCH_MODE_SET, SW_SCH, sizeof(fal_sch_mode_t), SW_PARAM_IN, "Schedule mode"),\ + SW_PARAM_DEF(SW_API_QOS_SCH_MODE_SET, SW_UINT_A, 16, SW_PARAM_PTR|SW_PARAM_IN, "Weight"), + +#define SW_API_QOS_SCH_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_SCH_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_SCH_MODE_GET, SW_SCH, sizeof(fal_sch_mode_t), SW_PARAM_PTR|SW_PARAM_OUT, "Schedule mode"),\ + SW_PARAM_DEF(SW_API_QOS_SCH_MODE_GET, SW_UINT_A, 16, SW_PARAM_PTR|SW_PARAM_OUT, "Weight"), + +#define SW_API_QOS_QU_TX_BUF_ST_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_QU_TX_BUF_ST_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_QU_TX_BUF_ST_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_QU_TX_BUF_ST_SET, SW_ENABLE, 4, SW_PARAM_IN, "Buffer limit"), + +#define SW_API_QOS_QU_TX_BUF_ST_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_QU_TX_BUF_ST_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_QU_TX_BUF_ST_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_QU_TX_BUF_ST_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Buffer limit"), + +#define SW_API_QOS_QU_TX_BUF_NR_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_QU_TX_BUF_NR_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_QU_TX_BUF_NR_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_QU_TX_BUF_NR_SET, SW_UINT32, 4, SW_PARAM_IN, "Queue ID"),\ + SW_PARAM_DEF(SW_API_QOS_QU_TX_BUF_NR_SET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Buffer Number"), + +#define SW_API_QOS_QU_TX_BUF_NR_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_QU_TX_BUF_NR_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_QU_TX_BUF_NR_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_QU_TX_BUF_NR_GET, SW_UINT32, 4, SW_PARAM_IN, "Queue ID"),\ + SW_PARAM_DEF(SW_API_QOS_QU_TX_BUF_NR_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Buffer Number"), + +#define SW_API_QOS_PT_TX_BUF_ST_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PT_TX_BUF_ST_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_TX_BUF_ST_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_TX_BUF_ST_SET, SW_ENABLE, 4, SW_PARAM_IN, "Buffer limit"), + +#define SW_API_QOS_PT_TX_BUF_ST_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PT_TX_BUF_ST_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_TX_BUF_ST_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_TX_BUF_ST_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Buffer limit"), + +#define SW_API_QOS_PT_RED_EN_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PT_RED_EN_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_RED_EN_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_RED_EN_SET, SW_ENABLE, 4, SW_PARAM_IN, "enable"), + +#define SW_API_QOS_PT_RED_EN_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PT_RED_EN_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_RED_EN_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_RED_EN_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "enable"), + +#define SW_API_QOS_PT_TX_BUF_NR_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PT_TX_BUF_NR_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_TX_BUF_NR_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_TX_BUF_NR_SET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Buffer Number"), + +#define SW_API_QOS_PT_TX_BUF_NR_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PT_TX_BUF_NR_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_TX_BUF_NR_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_TX_BUF_NR_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Buffer Number"), + +#define SW_API_QOS_PT_RX_BUF_NR_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PT_RX_BUF_NR_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_RX_BUF_NR_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_RX_BUF_NR_SET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Buffer Number"), + +#define SW_API_QOS_PT_RX_BUF_NR_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PT_RX_BUF_NR_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_RX_BUF_NR_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_RX_BUF_NR_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Buffer Number"), + +#define SW_API_COSMAP_UP_QU_SET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_UP_QU_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_COSMAP_UP_QU_SET, SW_UINT32, 4, SW_PARAM_IN, "Dot1p"),\ + SW_PARAM_DEF(SW_API_COSMAP_UP_QU_SET, SW_UINT32, 4, SW_PARAM_IN, "Queue"), + +#define SW_API_COSMAP_UP_QU_GET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_UP_QU_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_COSMAP_UP_QU_GET, SW_UINT32, 4, SW_PARAM_IN, "Dot1p"),\ + SW_PARAM_DEF(SW_API_COSMAP_UP_QU_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Queue"), + +#define SW_API_COSMAP_DSCP_QU_SET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_QU_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_QU_SET, SW_UINT32, 4, SW_PARAM_IN, "DSCP"),\ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_QU_SET, SW_UINT32, 4, SW_PARAM_IN, "Queue"), + +#define SW_API_COSMAP_DSCP_QU_GET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_QU_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_QU_GET, SW_UINT32, 4, SW_PARAM_IN, "DSCP"),\ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_QU_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Queue"), + +#define SW_API_QOS_PT_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PT_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_MODE_SET, SW_QOS, sizeof(fal_qos_mode_t), SW_PARAM_IN, "Qos mode"),\ + SW_PARAM_DEF(SW_API_QOS_PT_MODE_SET, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_QOS_PT_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PT_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_MODE_GET, SW_QOS, sizeof(fal_qos_mode_t), SW_PARAM_IN, "Qos mode"),\ + SW_PARAM_DEF(SW_API_QOS_PT_MODE_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Enable"), + +#define SW_API_QOS_PT_MODE_PRI_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PT_MODE_PRI_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_MODE_PRI_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_MODE_PRI_SET, SW_QOS, sizeof(fal_qos_mode_t), SW_PARAM_IN, "Qos mode"),\ + SW_PARAM_DEF(SW_API_QOS_PT_MODE_PRI_SET, SW_UINT32, 4, SW_PARAM_IN, "Priority"), + +#define SW_API_QOS_PT_MODE_PRI_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PT_MODE_PRI_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_MODE_PRI_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_MODE_PRI_GET, SW_QOS, sizeof(fal_qos_mode_t), SW_PARAM_IN, "Qos mode"),\ + SW_PARAM_DEF(SW_API_QOS_PT_MODE_PRI_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Priority"), + +#define SW_API_QOS_PORT_DEF_UP_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PORT_DEF_UP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_DEF_UP_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_DEF_UP_SET, SW_UINT32, 4, SW_PARAM_IN, "default up"), + +#define SW_API_QOS_PORT_DEF_UP_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PORT_DEF_UP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_DEF_UP_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_DEF_UP_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "default up"), + +#define SW_API_QOS_PORT_SCH_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PORT_SCH_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_SCH_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_SCH_MODE_SET, SW_SCH, sizeof(fal_sch_mode_t), SW_PARAM_IN, "Schedule mode"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_SCH_MODE_SET, SW_UINT_A, 24, SW_PARAM_PTR|SW_PARAM_IN, "Weight"), + +#define SW_API_QOS_PORT_SCH_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PORT_SCH_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_SCH_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_SCH_MODE_GET, SW_SCH, sizeof(fal_sch_mode_t), SW_PARAM_PTR|SW_PARAM_OUT, "Schedule mode"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_SCH_MODE_GET, SW_UINT_A, 24, SW_PARAM_PTR|SW_PARAM_OUT, "Weight"), + +#define SW_API_QOS_PT_DEF_SPRI_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PT_DEF_SPRI_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_DEF_SPRI_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_DEF_SPRI_SET, SW_UINT32, 4, SW_PARAM_IN, "default spri"), + +#define SW_API_QOS_PT_DEF_SPRI_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PT_DEF_SPRI_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_DEF_SPRI_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_DEF_SPRI_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "default spri"), + +#define SW_API_QOS_PT_DEF_CPRI_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PT_DEF_CPRI_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_DEF_CPRI_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_DEF_CPRI_SET, SW_UINT32, 4, SW_PARAM_IN, "default cpri"), + + +#define SW_API_QOS_PT_FORCE_SPRI_ST_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PT_FORCE_SPRI_ST_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_FORCE_SPRI_ST_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_FORCE_SPRI_ST_SET, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_QOS_PT_FORCE_SPRI_ST_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PT_FORCE_SPRI_ST_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_FORCE_SPRI_ST_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_FORCE_SPRI_ST_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Enable"), + +#define SW_API_QOS_PT_FORCE_CPRI_ST_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PT_FORCE_CPRI_ST_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_FORCE_CPRI_ST_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_FORCE_CPRI_ST_SET, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_QOS_PT_FORCE_CPRI_ST_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PT_FORCE_CPRI_ST_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_FORCE_CPRI_ST_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_FORCE_CPRI_ST_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Enable"), + + + +#define SW_API_QOS_PT_DEF_CPRI_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PT_DEF_CPRI_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_DEF_CPRI_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PT_DEF_CPRI_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "default cpri"), + + +#define SW_API_QOS_QUEUE_REMARK_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_QUEUE_REMARK_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_QUEUE_REMARK_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_QUEUE_REMARK_SET, SW_UINT32, 4, SW_PARAM_IN, "Queue ID"),\ + SW_PARAM_DEF(SW_API_QOS_QUEUE_REMARK_SET, SW_UINT32, 4, SW_PARAM_IN, "Table ID"), \ + SW_PARAM_DEF(SW_API_QOS_QUEUE_REMARK_SET, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_QOS_QUEUE_REMARK_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_QUEUE_REMARK_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_QUEUE_REMARK_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_QUEUE_REMARK_GET, SW_UINT32, 4, SW_PARAM_IN, "Queue ID"),\ + SW_PARAM_DEF(SW_API_QOS_QUEUE_REMARK_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Table ID"), \ + SW_PARAM_DEF(SW_API_QOS_QUEUE_REMARK_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Enable"), + +#define SW_API_QOS_PORT_GROUP_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PORT_GROUP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_GROUP_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_GROUP_SET, SW_PORTGROUP, sizeof(fal_qos_group_t), SW_PARAM_PTR|SW_PARAM_IN, "PortGroup"), + +#define SW_API_QOS_PORT_GROUP_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PORT_GROUP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_GROUP_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_GROUP_GET, SW_PORTGROUP, sizeof(fal_qos_group_t), SW_PARAM_PTR|SW_PARAM_OUT, "PortGroup"), + +#define SW_API_QOS_PORT_PRI_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PORT_PRI_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_PRI_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_PRI_SET, SW_PORTPRI, sizeof(fal_qos_pri_precedence_t), SW_PARAM_PTR|SW_PARAM_IN, "PortPri"), + +#define SW_API_QOS_PORT_PRI_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PORT_PRI_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_PRI_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_PRI_GET, SW_PORTPRI, sizeof(fal_qos_pri_precedence_t), SW_PARAM_PTR|SW_PARAM_OUT, "PortPri"), + +#define SW_API_QOS_PORT_REMARK_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PORT_REMARK_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_REMARK_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_REMARK_SET, SW_PORTREMARK, sizeof(fal_qos_remark_enable_t), SW_PARAM_PTR|SW_PARAM_IN, "PortRemark"), + +#define SW_API_QOS_PORT_REMARK_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PORT_REMARK_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_REMARK_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_REMARK_GET, SW_PORTREMARK, sizeof(fal_qos_remark_enable_t), SW_PARAM_PTR|SW_PARAM_OUT, "PortRemark"), + +#define SW_API_QOS_PCP_MAP_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PCP_MAP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PCP_MAP_SET, SW_UINT32, 4, SW_PARAM_IN, "Group ID"),\ + SW_PARAM_DEF(SW_API_QOS_PCP_MAP_SET, SW_UINT32, 4, SW_PARAM_IN, "PCP"),\ + SW_PARAM_DEF(SW_API_QOS_PCP_MAP_SET, SW_COSMAP, sizeof(fal_qos_cosmap_t), SW_PARAM_PTR|SW_PARAM_IN, "Cosmap"), + +#define SW_API_QOS_PCP_MAP_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PCP_MAP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PCP_MAP_GET, SW_UINT32, 4, SW_PARAM_IN, "Group ID"),\ + SW_PARAM_DEF(SW_API_QOS_PCP_MAP_GET, SW_UINT32, 4, SW_PARAM_IN, "PCP"),\ + SW_PARAM_DEF(SW_API_QOS_PCP_MAP_GET, SW_COSMAP, sizeof(fal_qos_cosmap_t), SW_PARAM_PTR|SW_PARAM_OUT, "Cosmap"), + +#define SW_API_QOS_FLOW_MAP_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_FLOW_MAP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_FLOW_MAP_SET, SW_UINT32, 4, SW_PARAM_IN, "Group ID"),\ + SW_PARAM_DEF(SW_API_QOS_FLOW_MAP_SET, SW_UINT32, 4, SW_PARAM_IN, "Flow"),\ + SW_PARAM_DEF(SW_API_QOS_FLOW_MAP_SET, SW_COSMAP, sizeof(fal_qos_cosmap_t), SW_PARAM_PTR|SW_PARAM_IN, "Cosmap"), + +#define SW_API_QOS_FLOW_MAP_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_FLOW_MAP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_FLOW_MAP_GET, SW_UINT32, 4, SW_PARAM_IN, "Group ID"),\ + SW_PARAM_DEF(SW_API_QOS_FLOW_MAP_GET, SW_UINT32, 4, SW_PARAM_IN, "Flow"),\ + SW_PARAM_DEF(SW_API_QOS_FLOW_MAP_GET, SW_COSMAP, sizeof(fal_qos_cosmap_t), SW_PARAM_PTR|SW_PARAM_OUT, "Cosmap"), + +#define SW_API_QOS_DSCP_MAP_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_DSCP_MAP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_DSCP_MAP_SET, SW_UINT32, 4, SW_PARAM_IN, "Group ID"),\ + SW_PARAM_DEF(SW_API_QOS_DSCP_MAP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dscp"),\ + SW_PARAM_DEF(SW_API_QOS_DSCP_MAP_SET, SW_COSMAP, sizeof(fal_qos_cosmap_t), SW_PARAM_PTR|SW_PARAM_IN, "Cosmap"), + +#define SW_API_QOS_DSCP_MAP_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_DSCP_MAP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_DSCP_MAP_GET, SW_UINT32, 4, SW_PARAM_IN, "Group ID"),\ + SW_PARAM_DEF(SW_API_QOS_DSCP_MAP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dscp"),\ + SW_PARAM_DEF(SW_API_QOS_DSCP_MAP_GET, SW_COSMAP, sizeof(fal_qos_cosmap_t), SW_PARAM_PTR|SW_PARAM_OUT, "Cosmap"), + +#define SW_API_QOS_QUEUE_SCHEDULER_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_QUEUE_SCHEDULER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_QUEUE_SCHEDULER_SET, SW_UINT32, 4, SW_PARAM_IN, "Node ID"),\ + SW_PARAM_DEF(SW_API_QOS_QUEUE_SCHEDULER_SET, SW_UINT32, 4, SW_PARAM_IN, "Level"),\ + SW_PARAM_DEF(SW_API_QOS_QUEUE_SCHEDULER_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_QUEUE_SCHEDULER_SET, SW_SCHEDULER, sizeof(fal_qos_scheduler_cfg_t), SW_PARAM_PTR|SW_PARAM_IN, "Scheduler"), + +#define SW_API_QOS_QUEUE_SCHEDULER_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_QUEUE_SCHEDULER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_QUEUE_SCHEDULER_GET, SW_UINT32, 4, SW_PARAM_IN, "Node ID"),\ + SW_PARAM_DEF(SW_API_QOS_QUEUE_SCHEDULER_GET, SW_UINT32, 4, SW_PARAM_IN, "Level"),\ + SW_PARAM_DEF(SW_API_QOS_QUEUE_SCHEDULER_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_QUEUE_SCHEDULER_GET, SW_SCHEDULER, sizeof(fal_qos_scheduler_cfg_t), SW_PARAM_PTR|SW_PARAM_OUT, "Scheduler"), + +#define SW_API_QOS_RING_QUEUE_MAP_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_RING_QUEUE_MAP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_RING_QUEUE_MAP_SET, SW_UINT32, 4, SW_PARAM_IN, "Ring ID"),\ + SW_PARAM_DEF(SW_API_QOS_RING_QUEUE_MAP_SET, SW_QUEUEBMP, sizeof(fal_queue_bmp_t), SW_PARAM_PTR|SW_PARAM_IN, "Queue bmp"), + +#define SW_API_QOS_RING_QUEUE_MAP_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_RING_QUEUE_MAP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_RING_QUEUE_MAP_GET, SW_UINT32, 4, SW_PARAM_IN, "Ring ID"),\ + SW_PARAM_DEF(SW_API_QOS_RING_QUEUE_MAP_GET, SW_QUEUEBMP, sizeof(fal_queue_bmp_t), SW_PARAM_PTR|SW_PARAM_OUT, "Queue bmp"), + +#define SW_API_QOS_PORT_QUEUES_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PORT_QUEUES_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_QUEUES_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_QUEUES_GET, SW_QUEUEBMP, sizeof(fal_queue_bmp_t), SW_PARAM_PTR|SW_PARAM_OUT, "Queue bmp"), + +#define SW_API_QOS_PORT_SCHEDULER_CFG_RESET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PORT_SCHEDULER_CFG_RESET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_QOS_PORT_SCHEDULER_CFG_RESET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), + +#define SW_API_QOS_SCHEDULER_DEQUEU_CTRL_SET_DESC \ + SW_PARAM_DEF(SW_API_QOS_SCHEDULER_DEQUEU_CTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_QOS_SCHEDULER_DEQUEU_CTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "queue ID"), \ + SW_PARAM_DEF(SW_API_QOS_SCHEDULER_DEQUEU_CTRL_SET, SW_ENABLE, sizeof(a_bool_t), SW_PARAM_IN, "dequeue en"), + +#define SW_API_QOS_SCHEDULER_DEQUEU_CTRL_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_SCHEDULER_DEQUEU_CTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_QOS_SCHEDULER_DEQUEU_CTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "queue ID"), \ + SW_PARAM_DEF(SW_API_QOS_SCHEDULER_DEQUEU_CTRL_GET, SW_ENABLE, sizeof(a_bool_t), SW_PARAM_PTR|SW_PARAM_OUT, "dequeue en"), + +#define SW_API_QOS_PORT_SCHEDULER_RESOURCE_GET_DESC \ + SW_PARAM_DEF(SW_API_QOS_PORT_SCHEDULER_RESOURCE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_QOS_PORT_SCHEDULER_RESOURCE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_QOS_PORT_SCHEDULER_RESOURCE_GET, SW_RESOURCE_SCHE, sizeof(fal_portscheduler_resource_t), SW_PARAM_PTR|SW_PARAM_OUT, "scheduler resource"), + +#define SW_API_PT_IGMPS_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_IGMPS_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_PT_IGMPS_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port No."), \ + SW_PARAM_DEF(SW_API_PT_IGMPS_MODE_SET, SW_ENABLE, 4, SW_PARAM_IN, "IGMP snooping"), + +#define SW_API_PT_IGMPS_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_IGMPS_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_IGMPS_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port No."), \ + SW_PARAM_DEF(SW_API_PT_IGMPS_MODE_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "IGMP snooping"), + +#define SW_API_IGMP_MLD_CMD_SET_DESC \ + SW_PARAM_DEF(SW_API_IGMP_MLD_CMD_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IGMP_MLD_CMD_SET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_IN, "cmd"), + +#define SW_API_IGMP_MLD_CMD_GET_DESC \ + SW_PARAM_DEF(SW_API_IGMP_MLD_CMD_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IGMP_MLD_CMD_GET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_PTR|SW_PARAM_OUT, "cmd"), + +#define SW_API_IGMP_PT_JOIN_SET_DESC \ + SW_PARAM_DEF(SW_API_IGMP_PT_JOIN_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IGMP_PT_JOIN_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_IGMP_PT_JOIN_SET, SW_ENABLE, 4, SW_PARAM_IN, "Join"), + +#define SW_API_IGMP_PT_JOIN_GET_DESC \ + SW_PARAM_DEF(SW_API_IGMP_PT_JOIN_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IGMP_PT_JOIN_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_IGMP_PT_JOIN_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Join"), + +#define SW_API_IGMP_PT_LEAVE_SET_DESC \ + SW_PARAM_DEF(SW_API_IGMP_PT_LEAVE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IGMP_PT_LEAVE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_IGMP_PT_LEAVE_SET, SW_ENABLE, 4, SW_PARAM_IN, "Leave"), + +#define SW_API_IGMP_PT_LEAVE_GET_DESC \ + SW_PARAM_DEF(SW_API_IGMP_PT_LEAVE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IGMP_PT_LEAVE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_IGMP_PT_LEAVE_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Leave"), + +#define SW_API_IGMP_RP_SET_DESC \ + SW_PARAM_DEF(SW_API_IGMP_RP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IGMP_RP_SET, SW_PBMP, sizeof(fal_pbmp_t), SW_PARAM_IN, "Ports"), + +#define SW_API_IGMP_RP_GET_DESC \ + SW_PARAM_DEF(SW_API_IGMP_RP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IGMP_RP_GET, SW_PBMP, sizeof(fal_pbmp_t), SW_PARAM_PTR|SW_PARAM_OUT, "Ports"), + +#define SW_API_IGMP_ENTRY_CREAT_SET_DESC \ + SW_PARAM_DEF(SW_API_IGMP_ENTRY_CREAT_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IGMP_ENTRY_CREAT_SET, SW_ENABLE, 4, SW_PARAM_IN, "creat Entry"), + +#define SW_API_IGMP_ENTRY_CREAT_GET_DESC \ + SW_PARAM_DEF(SW_API_IGMP_ENTRY_CREAT_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IGMP_ENTRY_CREAT_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "creat Entry"), + +#define SW_API_IGMP_ENTRY_STATIC_SET_DESC \ + SW_PARAM_DEF(SW_API_IGMP_ENTRY_STATIC_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IGMP_ENTRY_STATIC_SET, SW_ENABLE, 4, SW_PARAM_IN, "static"), + +#define SW_API_IGMP_ENTRY_STATIC_GET_DESC \ + SW_PARAM_DEF(SW_API_IGMP_ENTRY_STATIC_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IGMP_ENTRY_STATIC_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "static"), + +#define SW_API_IGMP_ENTRY_LEAKY_SET_DESC \ + SW_PARAM_DEF(SW_API_IGMP_ENTRY_LEAKY_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IGMP_ENTRY_LEAKY_SET, SW_ENABLE, 4, SW_PARAM_IN, "leaky"), + +#define SW_API_IGMP_ENTRY_LEAKY_GET_DESC \ + SW_PARAM_DEF(SW_API_IGMP_ENTRY_LEAKY_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IGMP_ENTRY_LEAKY_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "leaky"), + +#define SW_API_IGMP_ENTRY_V3_SET_DESC \ + SW_PARAM_DEF(SW_API_IGMP_ENTRY_V3_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IGMP_ENTRY_V3_SET, SW_ENABLE, 4, SW_PARAM_IN, "version3"), + +#define SW_API_IGMP_ENTRY_V3_GET_DESC \ + SW_PARAM_DEF(SW_API_IGMP_ENTRY_V3_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IGMP_ENTRY_V3_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "version3"), + +#define SW_API_IGMP_ENTRY_QUEUE_SET_DESC \ + SW_PARAM_DEF(SW_API_IGMP_ENTRY_QUEUE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IGMP_ENTRY_QUEUE_SET, SW_ENABLE, 4, SW_PARAM_IN, "queue"), \ + SW_PARAM_DEF(SW_API_IGMP_ENTRY_QUEUE_SET, SW_UINT32, 4, SW_PARAM_IN, "queue_id"), + +#define SW_API_IGMP_ENTRY_QUEUE_GET_DESC \ + SW_PARAM_DEF(SW_API_IGMP_ENTRY_QUEUE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IGMP_ENTRY_QUEUE_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "queue"), \ + SW_PARAM_DEF(SW_API_IGMP_ENTRY_QUEUE_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "queue_id"), + +#define SW_API_PT_IGMP_LEARN_LIMIT_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_IGMP_LEARN_LIMIT_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_IGMP_LEARN_LIMIT_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_PT_IGMP_LEARN_LIMIT_SET, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), \ + SW_PARAM_DEF(SW_API_PT_IGMP_LEARN_LIMIT_SET, SW_UINT32, 4, SW_PARAM_IN, "LimitCnt"), + +#define SW_API_PT_IGMP_LEARN_LIMIT_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_IGMP_LEARN_LIMIT_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_PT_IGMP_LEARN_LIMIT_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_PT_IGMP_LEARN_LIMIT_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Enable"), \ + SW_PARAM_DEF(SW_API_PT_IGMP_LEARN_LIMIT_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "LimitCnt"), + +#define SW_API_PT_IGMP_LEARN_EXCEED_CMD_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_IGMP_LEARN_EXCEED_CMD_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_IGMP_LEARN_EXCEED_CMD_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_PT_IGMP_LEARN_EXCEED_CMD_SET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_IN, "cmd"), + +#define SW_API_PT_IGMP_LEARN_EXCEED_CMD_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_IGMP_LEARN_EXCEED_CMD_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_IGMP_LEARN_EXCEED_CMD_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_PT_IGMP_LEARN_EXCEED_CMD_GET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_PTR|SW_PARAM_OUT, "cmd"), + +#define SW_API_IGMP_SG_ENTRY_SET_DESC \ + SW_PARAM_DEF(SW_API_IGMP_SG_ENTRY_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IGMP_SG_ENTRY_SET, SW_SGENTRY, sizeof(fal_igmp_sg_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "entry"), + +#define SW_API_IGMP_SG_ENTRY_CLEAR_DESC \ + SW_PARAM_DEF(SW_API_IGMP_SG_ENTRY_CLEAR, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IGMP_SG_ENTRY_CLEAR, SW_SGENTRY, sizeof(fal_igmp_sg_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "entry"), + +#define SW_API_IGMP_SG_ENTRY_SHOW_DESC \ + SW_PARAM_DEF(SW_API_IGMP_SG_ENTRY_SHOW, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), + +#define SW_API_IGMP_SG_ENTRY_QUERY_DESC \ + SW_PARAM_DEF(SW_API_IGMP_SG_ENTRY_QUERY, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IGMP_SG_ENTRY_QUERY, SW_SGINFOENTRY, sizeof(fal_igmp_sg_info_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "info"), + + +#define SW_API_UC_LEAKY_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_UC_LEAKY_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_UC_LEAKY_MODE_SET, SW_LEAKY, sizeof(fal_leaky_ctrl_mode_t), SW_PARAM_IN, "Uc Leaky mode"), + +#define SW_API_UC_LEAKY_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_UC_LEAKY_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_UC_LEAKY_MODE_GET, SW_LEAKY, sizeof(fal_leaky_ctrl_mode_t), SW_PARAM_PTR|SW_PARAM_OUT, "Uc Leaky mode"), + +#define SW_API_MC_LEAKY_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_MC_LEAKY_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MC_LEAKY_MODE_SET, SW_LEAKY, sizeof(fal_leaky_ctrl_mode_t), SW_PARAM_IN, "Mc Leaky mode"), + +#define SW_API_MC_LEAKY_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_MC_LEAKY_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MC_LEAKY_MODE_GET, SW_LEAKY, sizeof(fal_leaky_ctrl_mode_t), SW_PARAM_PTR|SW_PARAM_OUT, "Mc Leaky mode"), + +#define SW_API_ARP_LEAKY_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_ARP_LEAKY_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_ARP_LEAKY_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_ARP_LEAKY_MODE_SET, SW_ENABLE, 4, SW_PARAM_IN, "Arp leaky"), + +#define SW_API_ARP_LEAKY_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_ARP_LEAKY_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_ARP_LEAKY_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_ARP_LEAKY_MODE_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Arp leaky"), + +#define SW_API_PT_UC_LEAKY_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_UC_LEAKY_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_UC_LEAKY_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_UC_LEAKY_MODE_SET, SW_ENABLE, 4, SW_PARAM_IN, "Port Unicast leaky"), + +#define SW_API_PT_UC_LEAKY_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_UC_LEAKY_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_UC_LEAKY_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_UC_LEAKY_MODE_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Port Uc leaky"), + +#define SW_API_PT_MC_LEAKY_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_MC_LEAKY_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_MC_LEAKY_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_MC_LEAKY_MODE_SET, SW_ENABLE, 4, SW_PARAM_IN, "Port Multicast leaky"), + +#define SW_API_PT_MC_LEAKY_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_MC_LEAKY_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_MC_LEAKY_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_MC_LEAKY_MODE_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Port Mc leaky"), + + + +#define SW_API_MIRROR_ANALY_PT_SET_DESC \ + SW_PARAM_DEF(SW_API_MIRROR_ANALY_PT_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MIRROR_ANALY_PT_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), + +#define SW_API_MIRROR_ANALY_PT_GET_DESC \ + SW_PARAM_DEF(SW_API_MIRROR_ANALY_PT_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MIRROR_ANALY_PT_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Port ID"), + +#define SW_API_MIRROR_IN_PT_SET_DESC \ + SW_PARAM_DEF(SW_API_MIRROR_IN_PT_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MIRROR_IN_PT_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_MIRROR_IN_PT_SET, SW_ENABLE, 4, SW_PARAM_IN, "Ingerss mirror"), + +#define SW_API_MIRROR_IN_PT_GET_DESC \ + SW_PARAM_DEF(SW_API_MIRROR_IN_PT_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MIRROR_IN_PT_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_MIRROR_IN_PT_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Ingeress mirror"), + +#define SW_API_MIRROR_EG_PT_SET_DESC \ + SW_PARAM_DEF(SW_API_MIRROR_EG_PT_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MIRROR_EG_PT_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_MIRROR_EG_PT_SET, SW_ENABLE, 4, SW_PARAM_IN, "Egerss mirror"), + +#define SW_API_MIRROR_EG_PT_GET_DESC \ + SW_PARAM_DEF(SW_API_MIRROR_EG_PT_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MIRROR_EG_PT_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_MIRROR_EG_PT_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Egeress mirror"), + +#define SW_API_MIRROR_ANALYSIS_CONFIG_SET_DESC \ + SW_PARAM_DEF(SW_API_MIRROR_ANALYSIS_CONFIG_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MIRROR_ANALYSIS_CONFIG_SET, SW_MIRR_DIRECTION, sizeof(fal_mirr_direction_t), SW_PARAM_IN, "Direction"), \ + SW_PARAM_DEF(SW_API_MIRROR_ANALYSIS_CONFIG_SET, SW_MIRR_ANALYSIS_CONFIG, sizeof(fal_mirr_analysis_config_t), SW_PARAM_PTR|SW_PARAM_IN, "Config"), + +#define SW_API_MIRROR_ANALYSIS_CONFIG_GET_DESC \ + SW_PARAM_DEF(SW_API_MIRROR_ANALYSIS_CONFIG_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MIRROR_ANALYSIS_CONFIG_GET, SW_MIRR_DIRECTION, sizeof(fal_mirr_direction_t), SW_PARAM_IN, "Direction"), \ + SW_PARAM_DEF(SW_API_MIRROR_ANALYSIS_CONFIG_GET, SW_MIRR_ANALYSIS_CONFIG, sizeof(fal_mirr_analysis_config_t), SW_PARAM_PTR|SW_PARAM_OUT, "Config"), + +#define SW_API_RSS_HASH_CONFIG_SET_DESC \ + SW_PARAM_DEF(SW_API_RSS_HASH_CONFIG_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_RSS_HASH_CONFIG_SET, SW_RSS_HASH_MODE, sizeof(fal_rss_hash_mode_t), SW_PARAM_IN, "Mode"), \ + SW_PARAM_DEF(SW_API_RSS_HASH_CONFIG_SET, SW_RSS_HASH_CONFIG, sizeof(fal_rss_hash_config_t), SW_PARAM_PTR|SW_PARAM_IN, "Config"), + +#define SW_API_RSS_HASH_CONFIG_GET_DESC \ + SW_PARAM_DEF(SW_API_RSS_HASH_CONFIG_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_RSS_HASH_CONFIG_GET, SW_RSS_HASH_MODE, sizeof(fal_rss_hash_mode_t), SW_PARAM_IN, "Mode"), \ + SW_PARAM_DEF(SW_API_RSS_HASH_CONFIG_GET, SW_RSS_HASH_CONFIG, sizeof(fal_rss_hash_config_t), SW_PARAM_PTR|SW_PARAM_OUT, "Config"), + + +#define SW_API_RATE_QU_EGRL_SET_DESC \ + SW_PARAM_DEF(SW_API_RATE_QU_EGRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_RATE_QU_EGRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_RATE_QU_EGRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Queue ID"),\ + SW_PARAM_DEF(SW_API_RATE_QU_EGRL_SET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Speed"),\ + SW_PARAM_DEF(SW_API_RATE_QU_EGRL_SET, SW_ENABLE, 4, SW_PARAM_IN, "Rate limit"), + +#define SW_API_RATE_QU_EGRL_GET_DESC \ + SW_PARAM_DEF(SW_API_RATE_QU_EGRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_RATE_QU_EGRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_RATE_QU_EGRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Queue ID"),\ + SW_PARAM_DEF(SW_API_RATE_QU_EGRL_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Speed"),\ + SW_PARAM_DEF(SW_API_RATE_QU_EGRL_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Rate limit"), + +#define SW_API_RATE_PT_EGRL_SET_DESC \ + SW_PARAM_DEF(SW_API_RATE_PT_EGRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_RATE_PT_EGRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_RATE_PT_EGRL_SET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Speed"),\ + SW_PARAM_DEF(SW_API_RATE_PT_EGRL_SET, SW_ENABLE, 4, SW_PARAM_IN, "Rate limit"), + +#define SW_API_RATE_PT_EGRL_GET_DESC \ + SW_PARAM_DEF(SW_API_RATE_PT_EGRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_RATE_PT_EGRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_RATE_PT_EGRL_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Speed"),\ + SW_PARAM_DEF(SW_API_RATE_PT_EGRL_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Rate limit"), + +#define SW_API_RATE_PT_INRL_SET_DESC \ + SW_PARAM_DEF(SW_API_RATE_PT_INRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_RATE_PT_INRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_RATE_PT_INRL_SET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Speed"),\ + SW_PARAM_DEF(SW_API_RATE_PT_INRL_SET, SW_ENABLE, 4, SW_PARAM_IN, "Rate limit"), + +#define SW_API_RATE_PT_INRL_GET_DESC \ + SW_PARAM_DEF(SW_API_RATE_PT_INRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_RATE_PT_INRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_RATE_PT_INRL_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Speed"),\ + SW_PARAM_DEF(SW_API_RATE_PT_INRL_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Rate limit"), + +#define SW_API_STORM_CTRL_FRAME_SET_DESC \ + SW_PARAM_DEF(SW_API_STORM_CTRL_FRAME_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_STORM_CTRL_FRAME_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_STORM_CTRL_FRAME_SET, SW_STORM, sizeof(fal_storm_type_t), SW_PARAM_IN, "Frame type"),\ + SW_PARAM_DEF(SW_API_STORM_CTRL_FRAME_SET, SW_ENABLE, 4, SW_PARAM_IN, "strom contrl"), + +#define SW_API_STORM_CTRL_FRAME_GET_DESC \ + SW_PARAM_DEF(SW_API_STORM_CTRL_FRAME_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_STORM_CTRL_FRAME_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_STORM_CTRL_FRAME_GET, SW_STORM, sizeof(fal_storm_type_t), SW_PARAM_IN, "Frame type"),\ + SW_PARAM_DEF(SW_API_STORM_CTRL_FRAME_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "strom contrl"), + +#define SW_API_STORM_CTRL_RATE_SET_DESC \ + SW_PARAM_DEF(SW_API_STORM_CTRL_RATE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_STORM_CTRL_RATE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_STORM_CTRL_RATE_SET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Speed"), + +#define SW_API_STORM_CTRL_RATE_GET_DESC \ + SW_PARAM_DEF(SW_API_STORM_CTRL_RATE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_STORM_CTRL_RATE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_STORM_CTRL_RATE_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Speed"), + +#define SW_API_RATE_PORT_POLICER_SET_DESC \ + SW_PARAM_DEF(SW_API_RATE_PORT_POLICER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_RATE_PORT_POLICER_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_RATE_PORT_POLICER_SET, SW_INGPOLICER, sizeof(fal_port_policer_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Policer"), + +#define SW_API_RATE_PORT_POLICER_GET_DESC \ + SW_PARAM_DEF(SW_API_RATE_PORT_POLICER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_RATE_PORT_POLICER_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_RATE_PORT_POLICER_GET, SW_INGPOLICER, sizeof(fal_port_policer_t), SW_PARAM_PTR|SW_PARAM_OUT, "Policer"), + +#define SW_API_RATE_PORT_SHAPER_SET_DESC \ + SW_PARAM_DEF(SW_API_RATE_PORT_SHAPER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_RATE_PORT_SHAPER_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_RATE_PORT_SHAPER_SET, SW_ENABLE, 4, SW_PARAM_IN, "Status"), \ + SW_PARAM_DEF(SW_API_RATE_PORT_SHAPER_SET, SW_EGSHAPER, sizeof(fal_egress_shaper_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Shaper"), + +#define SW_API_RATE_PORT_SHAPER_GET_DESC \ + SW_PARAM_DEF(SW_API_RATE_PORT_SHAPER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_RATE_PORT_SHAPER_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_RATE_PORT_SHAPER_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Status"), \ + SW_PARAM_DEF(SW_API_RATE_PORT_SHAPER_GET, SW_EGSHAPER, sizeof(fal_egress_shaper_t), SW_PARAM_PTR|SW_PARAM_OUT, "Shaper"), + +#define SW_API_RATE_QUEUE_SHAPER_SET_DESC \ + SW_PARAM_DEF(SW_API_RATE_QUEUE_SHAPER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_RATE_QUEUE_SHAPER_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_RATE_QUEUE_SHAPER_SET, SW_UINT32, 4, SW_PARAM_IN, "Queue ID"),\ + SW_PARAM_DEF(SW_API_RATE_QUEUE_SHAPER_SET, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), \ + SW_PARAM_DEF(SW_API_RATE_QUEUE_SHAPER_SET, SW_EGSHAPER, sizeof(fal_egress_shaper_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Shaper"), + +#define SW_API_RATE_QUEUE_SHAPER_GET_DESC \ + SW_PARAM_DEF(SW_API_RATE_QUEUE_SHAPER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_RATE_QUEUE_SHAPER_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_RATE_QUEUE_SHAPER_GET, SW_UINT32, 4, SW_PARAM_IN, "Queue ID"),\ + SW_PARAM_DEF(SW_API_RATE_QUEUE_SHAPER_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Status"), \ + SW_PARAM_DEF(SW_API_RATE_QUEUE_SHAPER_GET, SW_EGSHAPER, sizeof(fal_egress_shaper_t), SW_PARAM_PTR|SW_PARAM_OUT, "Shaper"), + +#define SW_API_RATE_ACL_POLICER_SET_DESC \ + SW_PARAM_DEF(SW_API_RATE_ACL_POLICER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_RATE_ACL_POLICER_SET, SW_UINT32, 4, SW_PARAM_IN, "Policer ID"),\ + SW_PARAM_DEF(SW_API_RATE_ACL_POLICER_SET, SW_ACLPOLICER, sizeof(fal_acl_policer_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Policer"), + +#define SW_API_RATE_ACL_POLICER_GET_DESC \ + SW_PARAM_DEF(SW_API_RATE_ACL_POLICER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_RATE_ACL_POLICER_GET, SW_UINT32, 4, SW_PARAM_IN, "Policer ID"),\ + SW_PARAM_DEF(SW_API_RATE_ACL_POLICER_GET, SW_ACLPOLICER, sizeof(fal_acl_policer_t), SW_PARAM_PTR|SW_PARAM_OUT, "Policer"), + +#define SW_API_RATE_PT_ADDRATEBYTE_SET_DESC\ + SW_PARAM_DEF(SW_API_RATE_PT_ADDRATEBYTE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_RATE_PT_ADDRATEBYTE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_RATE_PT_ADDRATEBYTE_SET, SW_UINT32, 4, SW_PARAM_IN, "AddRateByte"), + +#define SW_API_RATE_PT_ADDRATEBYTE_GET_DESC\ + SW_PARAM_DEF(SW_API_RATE_PT_ADDRATEBYTE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_RATE_PT_ADDRATEBYTE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_RATE_PT_ADDRATEBYTE_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "AddRateByte"), + +#define SW_API_RATE_PT_GOL_FLOW_EN_SET_DESC \ + SW_PARAM_DEF(SW_API_RATE_PT_GOL_FLOW_EN_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_RATE_PT_GOL_FLOW_EN_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_RATE_PT_GOL_FLOW_EN_SET, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_RATE_PT_GOL_FLOW_EN_GET_DESC \ + SW_PARAM_DEF(SW_API_RATE_PT_GOL_FLOW_EN_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_RATE_PT_GOL_FLOW_EN_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_RATE_PT_GOL_FLOW_EN_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Enable"), + +#define SW_API_STP_PT_STATE_SET_DESC \ + SW_PARAM_DEF(SW_API_STP_PT_STATE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_STP_PT_STATE_SET, SW_UINT32, 4, SW_PARAM_IN, "Spaning tree ID"),\ + SW_PARAM_DEF(SW_API_STP_PT_STATE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_STP_PT_STATE_SET, SW_STP, sizeof(fal_stp_state_t), SW_PARAM_IN, "Port State"), + +#define SW_API_STP_PT_STATE_GET_DESC \ + SW_PARAM_DEF(SW_API_STP_PT_STATE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_STP_PT_STATE_GET, SW_UINT32, 4, SW_PARAM_IN, "Spaning tree ID"),\ + SW_PARAM_DEF(SW_API_STP_PT_STATE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"),\ + SW_PARAM_DEF(SW_API_STP_PT_STATE_GET, SW_STP, sizeof(fal_stp_state_t), SW_PARAM_PTR|SW_PARAM_OUT, "Port State"), + + + + +#define SW_API_PT_MIB_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_MIB_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_MIB_GET, SW_UINT32, 4, SW_PARAM_IN, "Port No."), \ + SW_PARAM_DEF(SW_API_PT_MIB_GET, SW_MIB, sizeof(fal_mib_info_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "MIB info"), +#define SW_API_PT_XGMIB_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_XGMIB_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_XGMIB_GET, SW_UINT32, 4, SW_PARAM_IN, "Port No."), \ + SW_PARAM_DEF(SW_API_PT_XGMIB_GET, SW_XGMIB, sizeof(fal_xgmib_info_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "XGMIB info"), + +#define SW_API_MIB_STATUS_SET_DESC \ + SW_PARAM_DEF(SW_API_MIB_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MIB_STATUS_SET, SW_ENABLE, 4, SW_PARAM_IN, "MIB status"), + +#define SW_API_MIB_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_MIB_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MIB_STATUS_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "MIB status"), + +#define SW_API_PT_MIB_FLUSH_COUNTERS_DESC\ + SW_PARAM_DEF(SW_API_PT_MIB_FLUSH_COUNTERS, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_MIB_FLUSH_COUNTERS, SW_UINT32, 4, SW_PARAM_IN, "Port No."), + +#define SW_API_MIB_CPU_KEEP_SET_DESC \ + SW_PARAM_DEF(SW_API_MIB_CPU_KEEP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MIB_CPU_KEEP_SET, SW_ENABLE, 4, SW_PARAM_IN, "CPU_KEEP Set"), + +#define SW_API_MIB_CPU_KEEP_GET_DESC \ + SW_PARAM_DEF(SW_API_MIB_CPU_KEEP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MIB_CPU_KEEP_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "CPU_KEEP Get"), + +#define SW_API_PT_MIB_COUNTER_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_MIB_COUNTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_MIB_COUNTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Port No."), \ + SW_PARAM_DEF(SW_API_PT_MIB_COUNTER_GET, SW_MIB_CNTR, sizeof(fal_mib_counter_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "MIB Counter"), + + + +#define SW_API_ARP_STATUS_SET_DESC \ + SW_PARAM_DEF(SW_API_ARP_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_ARP_STATUS_SET, SW_ENABLE, 4, SW_PARAM_IN, "ARP acknowledge"), + +#define SW_API_ARP_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_ARP_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_ARP_STATUS_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "ARP acknowledge"), + +#define SW_API_FRAME_MAX_SIZE_SET_DESC \ + SW_PARAM_DEF(SW_API_FRAME_MAX_SIZE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FRAME_MAX_SIZE_SET, SW_UINT32, 4, SW_PARAM_IN, "Frame Size"), + +#define SW_API_FRAME_MAX_SIZE_GET_DESC \ + SW_PARAM_DEF(SW_API_FRAME_MAX_SIZE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FRAME_MAX_SIZE_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Frame Size"), + +#define SW_API_PT_UNK_SA_CMD_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_UNK_SA_CMD_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_UNK_SA_CMD_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_UNK_SA_CMD_SET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_IN, "Forwarding"), + +#define SW_API_PT_UNK_SA_CMD_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_UNK_SA_CMD_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_UNK_SA_CMD_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_UNK_SA_CMD_GET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_PTR|SW_PARAM_OUT, "Forwarding"), + +#define SW_API_PT_UNK_UC_FILTER_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_UNK_UC_FILTER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_UNK_UC_FILTER_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_UNK_UC_FILTER_SET, SW_ENABLE, 4, SW_PARAM_IN, "Filter"), + +#define SW_API_PT_UNK_UC_FILTER_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_UNK_UC_FILTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_UNK_UC_FILTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_UNK_UC_FILTER_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Filter"), + +#define SW_API_PT_UNK_MC_FILTER_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_UNK_MC_FILTER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_UNK_MC_FILTER_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_UNK_MC_FILTER_SET, SW_ENABLE, 4, SW_PARAM_IN, "Filter"), + +#define SW_API_PT_UNK_MC_FILTER_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_UNK_MC_FILTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_UNK_MC_FILTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_UNK_MC_FILTER_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Filter"), + +#define SW_API_PT_BC_FILTER_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_BC_FILTER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_BC_FILTER_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_BC_FILTER_SET, SW_ENABLE, 4, SW_PARAM_IN, "Filter"), + +#define SW_API_PT_BC_FILTER_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_BC_FILTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_BC_FILTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_BC_FILTER_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Filter"), + +#define SW_API_CPU_PORT_STATUS_SET_DESC \ + SW_PARAM_DEF(SW_API_CPU_PORT_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_CPU_PORT_STATUS_SET, SW_ENABLE, 4, SW_PARAM_IN, "Cpu port"), + +#define SW_API_CPU_PORT_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_CPU_PORT_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_CPU_PORT_STATUS_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Cpu port"), + +#define SW_API_BC_TO_CPU_PORT_SET_DESC \ + SW_PARAM_DEF(SW_API_BC_TO_CPU_PORT_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_BC_TO_CPU_PORT_SET, SW_ENABLE, 4, SW_PARAM_IN, "ToCpu"), + +#define SW_API_BC_TO_CPU_PORT_GET_DESC \ + SW_PARAM_DEF(SW_API_BC_TO_CPU_PORT_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_BC_TO_CPU_PORT_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "ToCpu"), + +#define SW_API_PPPOE_CMD_SET_DESC \ + SW_PARAM_DEF(SW_API_PPPOE_CMD_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PPPOE_CMD_SET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_IN, "Forwarding"), + +#define SW_API_PPPOE_CMD_GET_DESC \ + SW_PARAM_DEF(SW_API_PPPOE_CMD_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PPPOE_CMD_GET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_PTR|SW_PARAM_OUT, "Forwarding"), + +#define SW_API_PPPOE_STATUS_SET_DESC \ + SW_PARAM_DEF(SW_API_PPPOE_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PPPOE_STATUS_SET, SW_ENABLE, 4, SW_PARAM_IN, "PPPOE"), + +#define SW_API_PPPOE_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_PPPOE_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PPPOE_STATUS_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "PPPOE"), + +#define SW_API_PT_DHCP_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_DHCP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_DHCP_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_DHCP_SET, SW_ENABLE, 4, SW_PARAM_IN, "DHCP"), + +#define SW_API_PT_DHCP_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_DHCP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_DHCP_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_DHCP_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "DHCP"), + +#define SW_API_ARP_CMD_SET_DESC \ + SW_PARAM_DEF(SW_API_ARP_CMD_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_ARP_CMD_SET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_IN, "cmd"), + +#define SW_API_ARP_CMD_GET_DESC \ + SW_PARAM_DEF(SW_API_ARP_CMD_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_ARP_CMD_GET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_PTR|SW_PARAM_OUT, "cmd"), + +#define SW_API_EAPOL_CMD_SET_DESC \ + SW_PARAM_DEF(SW_API_EAPOL_CMD_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_EAPOL_CMD_SET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_IN, "cmd"), + +#define SW_API_EAPOL_CMD_GET_DESC \ + SW_PARAM_DEF(SW_API_EAPOL_CMD_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_EAPOL_CMD_GET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_PTR|SW_PARAM_OUT, "cmd"), + +#define SW_API_PPPOE_SESSION_ADD_DESC \ + SW_PARAM_DEF(SW_API_PPPOE_SESSION_ADD, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PPPOE_SESSION_ADD, SW_UINT32, 4, SW_PARAM_IN, "Session ID"), \ + SW_PARAM_DEF(SW_API_PPPOE_SESSION_ADD, SW_ENABLE, 4, SW_PARAM_IN, "StripHdr"), + +#define SW_API_PPPOE_SESSION_DEL_DESC \ + SW_PARAM_DEF(SW_API_PPPOE_SESSION_DEL, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PPPOE_SESSION_DEL, SW_UINT32, 4, SW_PARAM_IN, "Session ID"), + +#define SW_API_PPPOE_SESSION_GET_DESC \ + SW_PARAM_DEF(SW_API_PPPOE_SESSION_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PPPOE_SESSION_GET, SW_UINT32, 4, SW_PARAM_IN, "Session ID"), \ + SW_PARAM_DEF(SW_API_PPPOE_SESSION_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "StripHdr"), + +#define SW_API_EAPOL_STATUS_SET_DESC \ + SW_PARAM_DEF(SW_API_EAPOL_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_EAPOL_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_EAPOL_STATUS_SET, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_EAPOL_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_EAPOL_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_EAPOL_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_EAPOL_STATUS_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Enable"), + +#define SW_API_RIPV1_STATUS_SET_DESC \ + SW_PARAM_DEF(SW_API_RIPV1_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_RIPV1_STATUS_SET, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_RIPV1_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_RIPV1_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_RIPV1_STATUS_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Enable"), + +#define SW_API_PT_ARP_REQ_STATUS_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_ARP_REQ_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_ARP_REQ_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_ARP_REQ_STATUS_SET, SW_ENABLE, 4, SW_PARAM_IN, "ARP Req acknowledge"), + +#define SW_API_PT_ARP_REQ_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_ARP_REQ_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_ARP_REQ_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_ARP_REQ_STATUS_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "ARP Req acknowledge"), + +#define SW_API_PT_ARP_ACK_STATUS_SET_DESC \ + SW_PARAM_DEF(SW_API_PT_ARP_ACK_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_ARP_ACK_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_ARP_ACK_STATUS_SET, SW_ENABLE, 4, SW_PARAM_IN, "ARP Ack acknowledge"), + +#define SW_API_PT_ARP_ACK_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_PT_ARP_ACK_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PT_ARP_ACK_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PT_ARP_ACK_STATUS_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "ARP Ack acknowledge"), + +#define SW_API_PPPOE_SESSION_TABLE_ADD_DESC \ + SW_PARAM_DEF(SW_API_PPPOE_SESSION_TABLE_ADD, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PPPOE_SESSION_TABLE_ADD, SW_PPPOE, sizeof(fal_pppoe_session_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Session"), + +#define SW_API_PPPOE_SESSION_TABLE_DEL_DESC \ + SW_PARAM_DEF(SW_API_PPPOE_SESSION_TABLE_DEL, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PPPOE_SESSION_TABLE_DEL, SW_PPPOE, sizeof(fal_pppoe_session_t), SW_PARAM_PTR|SW_PARAM_IN, "Session"), + +#define SW_API_PPPOE_SESSION_TABLE_GET_DESC \ + SW_PARAM_DEF(SW_API_PPPOE_SESSION_TABLE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PPPOE_SESSION_TABLE_GET, SW_PPPOE, sizeof(fal_pppoe_session_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Session"), + +#define SW_API_PPPOE_SESSION_ID_SET_DESC \ + SW_PARAM_DEF(SW_API_PPPOE_SESSION_ID_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PPPOE_SESSION_ID_SET, SW_UINT32, 4, SW_PARAM_IN, "Index"), \ + SW_PARAM_DEF(SW_API_PPPOE_SESSION_ID_SET, SW_UINT32, 4, SW_PARAM_IN, "ID"), + +#define SW_API_PPPOE_SESSION_ID_GET_DESC \ + SW_PARAM_DEF(SW_API_PPPOE_SESSION_ID_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PPPOE_SESSION_ID_GET, SW_UINT32, 4, SW_PARAM_IN, "Index"), \ + SW_PARAM_DEF(SW_API_PPPOE_SESSION_ID_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "ID"), + +#define SW_API_INTR_MASK_SET_DESC \ + SW_PARAM_DEF(SW_API_INTR_MASK_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_INTR_MASK_SET, SW_UINT32, 4, SW_PARAM_IN, "Mask"), + +#define SW_API_INTR_MASK_GET_DESC \ + SW_PARAM_DEF(SW_API_INTR_MASK_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_INTR_MASK_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Mask"), + +#define SW_API_INTR_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_INTR_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_INTR_STATUS_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Status"), + +#define SW_API_INTR_STATUS_CLEAR_DESC \ + SW_PARAM_DEF(SW_API_INTR_STATUS_CLEAR, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_INTR_STATUS_CLEAR, SW_UINT32, 4, SW_PARAM_IN, "Status"), + +#define SW_API_INTR_PORT_LINK_MASK_SET_DESC \ + SW_PARAM_DEF(SW_API_INTR_PORT_LINK_MASK_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_INTR_PORT_LINK_MASK_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_INTR_PORT_LINK_MASK_SET, SW_UINT32, 4, SW_PARAM_IN, "Mask"), + +#define SW_API_INTR_PORT_LINK_MASK_GET_DESC \ + SW_PARAM_DEF(SW_API_INTR_PORT_LINK_MASK_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_INTR_PORT_LINK_MASK_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_INTR_PORT_LINK_MASK_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Mask"), + +#define SW_API_INTR_PORT_LINK_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_INTR_PORT_LINK_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_INTR_PORT_LINK_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_INTR_PORT_LINK_STATUS_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Status"), + +#define SW_API_INTR_MASK_MAC_LINKCHG_SET_DESC \ + SW_PARAM_DEF(SW_API_INTR_MASK_MAC_LINKCHG_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_INTR_MASK_MAC_LINKCHG_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_INTR_MASK_MAC_LINKCHG_SET, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_INTR_MASK_MAC_LINKCHG_GET_DESC \ + SW_PARAM_DEF(SW_API_INTR_MASK_MAC_LINKCHG_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_INTR_MASK_MAC_LINKCHG_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_INTR_MASK_MAC_LINKCHG_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Enable"), + +#define SW_API_INTR_STATUS_MAC_LINKCHG_GET_DESC \ + SW_PARAM_DEF(SW_API_INTR_STATUS_MAC_LINKCHG_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_INTR_STATUS_MAC_LINKCHG_GET, SW_PBMP, sizeof(fal_pbmp_t), SW_PARAM_PTR|SW_PARAM_OUT, "Intr Port Bitmap"), + +#define SW_API_INTR_STATUS_MAC_LINKCHG_CLEAR_DESC \ + SW_PARAM_DEF(SW_API_INTR_STATUS_MAC_LINKCHG_CLEAR, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), + +#define SW_API_CPU_VID_EN_SET_DESC \ + SW_PARAM_DEF(SW_API_CPU_VID_EN_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_CPU_VID_EN_SET, SW_ENABLE, 4, SW_PARAM_IN, "Cpu vid"), + +#define SW_API_CPU_VID_EN_GET_DESC \ + SW_PARAM_DEF(SW_API_CPU_VID_EN_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_CPU_VID_EN_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Cpu vid"), + +#define SW_API_RTD_PPPOE_EN_SET_DESC \ + SW_PARAM_DEF(SW_API_RTD_PPPOE_EN_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_RTD_PPPOE_EN_SET, SW_ENABLE, 4, SW_PARAM_IN, "RTD PPPoE"), + +#define SW_API_RTD_PPPOE_EN_GET_DESC \ + SW_PARAM_DEF(SW_API_RTD_PPPOE_EN_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_RTD_PPPOE_EN_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "RTD PPPoE"), + +#define SW_API_PPPOE_EN_SET_DESC \ + SW_PARAM_DEF(SW_API_PPPOE_EN_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PPPOE_EN_SET, SW_UINT32, 4, SW_PARAM_IN, "L3 Interface"), \ + SW_PARAM_DEF(SW_API_PPPOE_EN_SET, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_PPPOE_EN_GET_DESC \ + SW_PARAM_DEF(SW_API_PPPOE_EN_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PPPOE_EN_GET, SW_UINT32, 4, SW_PARAM_IN, "L3 Interface"), \ + SW_PARAM_DEF(SW_API_PPPOE_EN_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Enable"), + +#define SW_API_GLOBAL_MACADDR_SET_DESC \ + SW_PARAM_DEF(SW_API_GLOBAL_MACADDR_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_GLOBAL_MACADDR_SET, SW_MACADDR, sizeof(fal_mac_addr_t), SW_PARAM_PTR|SW_PARAM_IN, "[Macaddr]:"), + +#define SW_API_GLOBAL_MACADDR_GET_DESC \ + SW_PARAM_DEF(SW_API_GLOBAL_MACADDR_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_GLOBAL_MACADDR_GET, SW_MACADDR, sizeof(fal_mac_addr_t), SW_PARAM_PTR|SW_PARAM_OUT, "[Macaddr]:"), + +#define SW_API_LLDP_STATUS_SET_DESC \ + SW_PARAM_DEF(SW_API_LLDP_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_LLDP_STATUS_SET, SW_ENABLE, 4, SW_PARAM_IN, "LLDP"), + +#define SW_API_LLDP_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_LLDP_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_LLDP_STATUS_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "LLDP"), + +#define SW_API_FRAME_CRC_RESERVE_SET_DESC \ + SW_PARAM_DEF(SW_API_FRAME_CRC_RESERVE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FRAME_CRC_RESERVE_SET, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_FRAME_CRC_RESERVE_GET_DESC \ + SW_PARAM_DEF(SW_API_FRAME_CRC_RESERVE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FRAME_CRC_RESERVE_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Enable"), + +#define SW_API_DEBUG_PORT_COUNTER_ENABLE_DESC \ + SW_PARAM_DEF(SW_API_DEBUG_PORT_COUNTER_ENABLE, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_DEBUG_PORT_COUNTER_ENABLE, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_DEBUG_PORT_COUNTER_ENABLE, SW_DEBUG_COUNTER_EN, sizeof(fal_counter_en_t), SW_PARAM_PTR|SW_PARAM_IN, "enable"), + +#define SW_API_DEBUG_PORT_COUNTER_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_DEBUG_PORT_COUNTER_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_DEBUG_PORT_COUNTER_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_DEBUG_PORT_COUNTER_STATUS_GET, SW_DEBUG_COUNTER_EN, sizeof(fal_counter_en_t), SW_PARAM_PTR|SW_PARAM_OUT, "enable"), + + +#define SW_API_LED_PATTERN_SET_DESC \ + SW_PARAM_DEF(SW_API_LED_PATTERN_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_LED_PATTERN_SET, SW_UINT32, 4, SW_PARAM_IN, "Pattern Group"),\ + SW_PARAM_DEF(SW_API_LED_PATTERN_SET, SW_UINT32, 4, SW_PARAM_IN, "Pattern ID"),\ + SW_PARAM_DEF(SW_API_LED_PATTERN_SET, SW_LEDPATTERN, sizeof(led_ctrl_pattern_t), SW_PARAM_PTR|SW_PARAM_IN, "Pattern"), + +#define SW_API_LED_PATTERN_GET_DESC \ + SW_PARAM_DEF(SW_API_LED_PATTERN_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_LED_PATTERN_GET, SW_UINT32, 4, SW_PARAM_IN, "Pattern Group"),\ + SW_PARAM_DEF(SW_API_LED_PATTERN_GET, SW_UINT32, 4, SW_PARAM_IN, "Pattern ID"),\ + SW_PARAM_DEF(SW_API_LED_PATTERN_GET, SW_LEDPATTERN, sizeof(led_ctrl_pattern_t), SW_PARAM_PTR|SW_PARAM_OUT, "Pattern"), + +/*qca808x_start*/ +#define SW_API_PHY_GET_DESC \ + SW_PARAM_DEF(SW_API_PHY_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_PHY_GET, SW_UINT32, 4, SW_PARAM_IN, "Phy ID"),\ + SW_PARAM_DEF(SW_API_PHY_GET, SW_UINT32, 4, SW_PARAM_IN, "Reg ID"),\ + SW_PARAM_DEF(SW_API_PHY_GET, SW_UINT16, 2, SW_PARAM_PTR|SW_PARAM_OUT, "Data"), + + +#define SW_API_PHY_SET_DESC \ + SW_PARAM_DEF(SW_API_PHY_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_PHY_SET, SW_UINT32, 4, SW_PARAM_IN, "Phy ID"),\ + SW_PARAM_DEF(SW_API_PHY_SET, SW_UINT32, 4, SW_PARAM_IN, "Reg ID"),\ + SW_PARAM_DEF(SW_API_PHY_SET, SW_UINT16, 2, SW_PARAM_IN, "Data"), +/*qca808x_end*/ + +#define SW_API_REG_GET_DESC \ + SW_PARAM_DEF(SW_API_REG_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_REG_GET, SW_UINT32, 4, SW_PARAM_IN, "Reg Addr"),\ + SW_PARAM_DEF(SW_API_REG_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Data"),\ + SW_PARAM_DEF(SW_API_REG_GET, SW_UINT32, 4, SW_PARAM_IN, "Data Len"), + +#define SW_API_REG_SET_DESC \ + SW_PARAM_DEF(SW_API_REG_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_REG_SET, SW_UINT32, 4, SW_PARAM_IN, "Reg Addr"),\ + SW_PARAM_DEF(SW_API_REG_SET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN, "Data"),\ + SW_PARAM_DEF(SW_API_REG_SET, SW_UINT32, 4, SW_PARAM_IN, "Data Len"), + +#define SW_API_PSGMII_REG_GET_DESC \ + SW_PARAM_DEF(SW_API_PSGMII_REG_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_PSGMII_REG_GET, SW_UINT32, 4, SW_PARAM_IN, "Reg Addr"),\ + SW_PARAM_DEF(SW_API_PSGMII_REG_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Data"),\ + SW_PARAM_DEF(SW_API_PSGMII_REG_GET, SW_UINT32, 4, SW_PARAM_IN, "Data Len"), + +#define SW_API_PSGMII_REG_SET_DESC \ + SW_PARAM_DEF(SW_API_PSGMII_REG_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_PSGMII_REG_SET, SW_UINT32, 4, SW_PARAM_IN, "Reg Addr"),\ + SW_PARAM_DEF(SW_API_PSGMII_REG_SET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN, "Data"),\ + SW_PARAM_DEF(SW_API_PSGMII_REG_SET, SW_UINT32, 4, SW_PARAM_IN, "Data Len"), + +#define SW_API_REG_FIELD_GET_DESC \ + SW_PARAM_DEF(SW_API_REG_FIELD_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_REG_FIELD_GET, SW_UINT32, 4, SW_PARAM_IN, "Reg Addr"),\ + SW_PARAM_DEF(SW_API_REG_FIELD_GET, SW_UINT32, 4, SW_PARAM_IN, "Bit Offset"),\ + SW_PARAM_DEF(SW_API_REG_FIELD_GET, SW_UINT32, 4, SW_PARAM_IN, "Field Len"),\ + SW_PARAM_DEF(SW_API_REG_FIELD_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Data"),\ + SW_PARAM_DEF(SW_API_REG_FIELD_GET, SW_UINT32, 4, SW_PARAM_IN, "Data Len"), + +#define SW_API_REG_FIELD_SET_DESC \ + SW_PARAM_DEF(SW_API_REG_FIELD_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_REG_FIELD_SET, SW_UINT32, 4, SW_PARAM_IN, "Reg Addr"),\ + SW_PARAM_DEF(SW_API_REG_FIELD_SET, SW_UINT32, 4, SW_PARAM_IN, "Bit Offset"),\ + SW_PARAM_DEF(SW_API_REG_FIELD_SET, SW_UINT32, 4, SW_PARAM_IN, "Field Len"),\ + SW_PARAM_DEF(SW_API_REG_FIELD_SET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN, "Data"),\ + SW_PARAM_DEF(SW_API_REG_FIELD_SET, SW_UINT32, 4, SW_PARAM_IN, "Data Len"), + +#define SW_API_REG_DUMP_DESC \ + SW_PARAM_DEF(SW_API_REG_DUMP, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_REG_DUMP, SW_UINT32, 4, SW_PARAM_IN, "Register group idx"), \ + SW_PARAM_DEF(SW_API_REG_DUMP, SW_REG_DUMP, sizeof(fal_reg_dump_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "Register dump"), + +#define SW_API_DBG_REG_DUMP_DESC \ + SW_PARAM_DEF(SW_API_DBG_REG_DUMP, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_DBG_REG_DUMP, SW_DBG_REG_DUMP, sizeof(fal_debug_reg_dump_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "Debug Register dump"), + +#define SW_API_DBG_PSGMII_SELF_TEST_DESC \ + SW_PARAM_DEF(SW_API_DBG_PSGMII_SELF_TEST, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_DBG_PSGMII_SELF_TEST, SW_ENABLE, 4, SW_PARAM_IN, "enable"),\ + SW_PARAM_DEF(SW_API_DBG_PSGMII_SELF_TEST, SW_UINT32, 4, SW_PARAM_IN, "times"),\ + SW_PARAM_DEF(SW_API_DBG_PSGMII_SELF_TEST, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Status"), + +#define SW_API_PHY_DUMP_DESC \ + SW_PARAM_DEF(SW_API_PHY_DUMP, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PHY_DUMP, SW_UINT32, 4, SW_PARAM_IN, "Phy ID"),\ + SW_PARAM_DEF(SW_API_PHY_DUMP, SW_UINT32, 4, SW_PARAM_IN, "Register group idx"), \ + SW_PARAM_DEF(SW_API_PHY_DUMP, SW_PHY_DUMP, sizeof(fal_phy_dump_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "PHY dump"), + +#define SW_API_UNIPHY_REG_GET_DESC \ + SW_PARAM_DEF(SW_API_UNIPHY_REG_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_UNIPHY_REG_GET, SW_UINT32, 4, SW_PARAM_IN, "Reg Index"),\ + SW_PARAM_DEF(SW_API_UNIPHY_REG_GET, SW_UINT32, 4, SW_PARAM_IN, "Reg Addr"),\ + SW_PARAM_DEF(SW_API_UNIPHY_REG_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Data"),\ + SW_PARAM_DEF(SW_API_UNIPHY_REG_GET, SW_UINT32, 4, SW_PARAM_IN, "Data Len"), + +#define SW_API_UNIPHY_REG_SET_DESC \ + SW_PARAM_DEF(SW_API_UNIPHY_REG_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_UNIPHY_REG_SET, SW_UINT32, 4, SW_PARAM_IN, "Reg Index"),\ + SW_PARAM_DEF(SW_API_UNIPHY_REG_SET, SW_UINT32, 4, SW_PARAM_IN, "Reg Addr"),\ + SW_PARAM_DEF(SW_API_UNIPHY_REG_SET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN, "Data"),\ + SW_PARAM_DEF(SW_API_UNIPHY_REG_SET, SW_UINT32, 4, SW_PARAM_IN, "Data Len"), + +#define SW_API_COSMAP_DSCP_TO_PRI_SET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_PRI_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_PRI_SET, SW_UINT32, 4, SW_PARAM_IN, "DSCP"), \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_PRI_SET, SW_UINT32, 4, SW_PARAM_IN, "Priority"), + +#define SW_API_COSMAP_DSCP_TO_PRI_GET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_PRI_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_PRI_GET, SW_UINT32, 4, SW_PARAM_IN, "DSCP"), \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_PRI_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Priority"), + +#define SW_API_COSMAP_DSCP_TO_DP_SET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_DP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_DP_SET, SW_UINT32, 4, SW_PARAM_IN, "DSCP"), \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_DP_SET, SW_UINT32, 4, SW_PARAM_IN, "DP"), + +#define SW_API_COSMAP_DSCP_TO_DP_GET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_DP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_DP_GET, SW_UINT32, 4, SW_PARAM_IN, "DSCP"), \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_DP_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "DP"), + +#define SW_API_COSMAP_UP_TO_PRI_SET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_PRI_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_PRI_SET, SW_UINT32, 4, SW_PARAM_IN, "Dot1p"), \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_PRI_SET, SW_UINT32, 4, SW_PARAM_IN, "Priority"), + +#define SW_API_COSMAP_UP_TO_PRI_GET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_PRI_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_PRI_GET, SW_UINT32, 4, SW_PARAM_IN, "Dot1p"), \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_PRI_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Priority"), + +#define SW_API_COSMAP_UP_TO_DP_SET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_DP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_DP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dot1p"), \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_DP_SET, SW_UINT32, 4, SW_PARAM_IN, "DP"), + +#define SW_API_COSMAP_UP_TO_DP_GET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_DP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_DP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dot1p"), \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_DP_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "DP"), + +#define SW_API_COSMAP_DSCP_TO_EHPRI_SET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_EHPRI_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_EHPRI_SET, SW_UINT32, 4, SW_PARAM_IN, "DSCP"), \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_EHPRI_SET, SW_UINT32, 4, SW_PARAM_IN, "Priority"), + +#define SW_API_COSMAP_DSCP_TO_EHPRI_GET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_EHPRI_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_EHPRI_GET, SW_UINT32, 4, SW_PARAM_IN, "DSCP"), \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_EHPRI_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Priority"), + +#define SW_API_COSMAP_DSCP_TO_EHDP_SET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_EHDP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_EHDP_SET, SW_UINT32, 4, SW_PARAM_IN, "DSCP"), \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_EHDP_SET, SW_UINT32, 4, SW_PARAM_IN, "DP"), + +#define SW_API_COSMAP_DSCP_TO_EHDP_GET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_EHDP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_EHDP_GET, SW_UINT32, 4, SW_PARAM_IN, "DSCP"), \ + SW_PARAM_DEF(SW_API_COSMAP_DSCP_TO_EHDP_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "DP"), + +#define SW_API_COSMAP_UP_TO_EHPRI_SET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_EHPRI_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_EHPRI_SET, SW_UINT32, 4, SW_PARAM_IN, "Dot1p"), \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_EHPRI_SET, SW_UINT32, 4, SW_PARAM_IN, "Priority"), + +#define SW_API_COSMAP_UP_TO_EHPRI_GET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_EHPRI_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_EHPRI_GET, SW_UINT32, 4, SW_PARAM_IN, "Dot1p"), \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_EHPRI_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Priority"), + +#define SW_API_COSMAP_UP_TO_EHDP_SET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_EHDP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_EHDP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dot1p"), \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_EHDP_SET, SW_UINT32, 4, SW_PARAM_IN, "DP"), + +#define SW_API_COSMAP_UP_TO_EHDP_GET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_EHDP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_EHDP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dot1p"), \ + SW_PARAM_DEF(SW_API_COSMAP_UP_TO_EHDP_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "DP"), + +#define SW_API_COSMAP_PRI_TO_QU_SET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_PRI_TO_QU_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_PRI_TO_QU_SET, SW_UINT32, 4, SW_PARAM_IN, "Priority"), \ + SW_PARAM_DEF(SW_API_COSMAP_PRI_TO_QU_SET, SW_UINT32, 4, SW_PARAM_IN, "Queue"), + +#define SW_API_COSMAP_PRI_TO_QU_GET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_PRI_TO_QU_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_PRI_TO_QU_GET, SW_UINT32, 4, SW_PARAM_IN, "Priority"), \ + SW_PARAM_DEF(SW_API_COSMAP_PRI_TO_QU_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Queue"), + +#define SW_API_COSMAP_PRI_TO_EHQU_SET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_PRI_TO_EHQU_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_PRI_TO_EHQU_SET, SW_UINT32, 4, SW_PARAM_IN, "Priority"), \ + SW_PARAM_DEF(SW_API_COSMAP_PRI_TO_EHQU_SET, SW_UINT32, 4, SW_PARAM_IN, "Queue"), + +#define SW_API_COSMAP_PRI_TO_EHQU_GET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_PRI_TO_EHQU_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_PRI_TO_EHQU_GET, SW_UINT32, 4, SW_PARAM_IN, "Priority"), \ + SW_PARAM_DEF(SW_API_COSMAP_PRI_TO_EHQU_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Queue"), + +#define SW_API_COSMAP_EG_REMARK_SET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_EG_REMARK_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_EG_REMARK_SET, SW_UINT32, 4, SW_PARAM_IN, "Table ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_EG_REMARK_SET, SW_REMARKENTRY, sizeof(fal_egress_remark_table_t), SW_PARAM_IN|SW_PARAM_PTR, "Table Entry"), + +#define SW_API_COSMAP_EG_REMARK_GET_DESC \ + SW_PARAM_DEF(SW_API_COSMAP_EG_REMARK_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_EG_REMARK_GET, SW_UINT32, 4, SW_PARAM_IN, "Table ID"), \ + SW_PARAM_DEF(SW_API_COSMAP_EG_REMARK_GET, SW_REMARKENTRY, sizeof(fal_egress_remark_table_t), SW_PARAM_OUT|SW_PARAM_PTR, "Table Entry"), + + + +#define SW_API_SEC_NORM_SET_DESC \ + SW_PARAM_DEF(SW_API_SEC_NORM_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_NORM_SET, SW_UINT32, 4, SW_PARAM_IN, "NormItem"), \ + SW_PARAM_DEF(SW_API_SEC_NORM_SET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN, "NormVal"), + +#define SW_API_SEC_NORM_GET_DESC \ + SW_PARAM_DEF(SW_API_SEC_NORM_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_NORM_GET, SW_UINT32, 4, SW_PARAM_IN, "NormItem"), \ + SW_PARAM_DEF(SW_API_SEC_NORM_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "NormVal"), + +#define SW_API_SEC_MAC_SET_DESC \ + SW_PARAM_DEF(SW_API_SEC_MAC_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_MAC_SET, SW_SEC_MAC, 4, SW_PARAM_IN, "MAC related normalized item"), \ + SW_PARAM_DEF(SW_API_SEC_MAC_SET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN, "NormVal"), + +#define SW_API_SEC_MAC_GET_DESC \ + SW_PARAM_DEF(SW_API_SEC_MAC_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_MAC_GET, SW_SEC_MAC, 4, SW_PARAM_IN, "MAC related normalized item"), \ + SW_PARAM_DEF(SW_API_SEC_MAC_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "NormVal"), + +#define SW_API_SEC_IP_SET_DESC \ + SW_PARAM_DEF(SW_API_SEC_IP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_IP_SET, SW_SEC_IP, 4, SW_PARAM_IN, "IP related normalized item"), \ + SW_PARAM_DEF(SW_API_SEC_IP_SET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN, "NormVal"), + +#define SW_API_SEC_IP_GET_DESC \ + SW_PARAM_DEF(SW_API_SEC_IP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_IP_GET, SW_SEC_IP, 4, SW_PARAM_IN, "IP related normalized item"), \ + SW_PARAM_DEF(SW_API_SEC_IP_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "NormVal"), + +#define SW_API_SEC_IP4_SET_DESC \ + SW_PARAM_DEF(SW_API_SEC_IP4_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_IP4_SET, SW_SEC_IP4, 4, SW_PARAM_IN, "IP4 related normalized item"), \ + SW_PARAM_DEF(SW_API_SEC_IP4_SET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN, "NormVal"), + +#define SW_API_SEC_IP4_GET_DESC \ + SW_PARAM_DEF(SW_API_SEC_IP4_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_IP4_GET, SW_SEC_IP4, 4, SW_PARAM_IN, "IP4 related normalized item"), \ + SW_PARAM_DEF(SW_API_SEC_IP4_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "NormVal"), + +#define SW_API_SEC_IP6_SET_DESC \ + SW_PARAM_DEF(SW_API_SEC_IP6_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_IP6_SET, SW_SEC_IP6, 4, SW_PARAM_IN, "IP6 related normalized item"), \ + SW_PARAM_DEF(SW_API_SEC_IP6_SET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN, "NormVal"), + +#define SW_API_SEC_IP6_GET_DESC \ + SW_PARAM_DEF(SW_API_SEC_IP6_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_IP6_GET, SW_SEC_IP6, 4, SW_PARAM_IN, "IP6 related normalized item"), \ + SW_PARAM_DEF(SW_API_SEC_IP6_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "NormVal"), + +#define SW_API_SEC_TCP_SET_DESC \ + SW_PARAM_DEF(SW_API_SEC_TCP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_TCP_SET, SW_SEC_TCP, 4, SW_PARAM_IN, "TCP related normalized item"), \ + SW_PARAM_DEF(SW_API_SEC_TCP_SET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN, "NormVal"), + +#define SW_API_SEC_TCP_GET_DESC \ + SW_PARAM_DEF(SW_API_SEC_TCP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_TCP_GET, SW_SEC_TCP, 4, SW_PARAM_IN, "TCP related normalized item"), \ + SW_PARAM_DEF(SW_API_SEC_TCP_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "NormVal"), + +#define SW_API_SEC_UDP_SET_DESC \ + SW_PARAM_DEF(SW_API_SEC_UDP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_UDP_SET, SW_SEC_UDP, 4, SW_PARAM_IN, "UDP related normalized item"), \ + SW_PARAM_DEF(SW_API_SEC_UDP_SET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN, "NormVal"), + +#define SW_API_SEC_UDP_GET_DESC \ + SW_PARAM_DEF(SW_API_SEC_UDP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_UDP_GET, SW_SEC_UDP, 4, SW_PARAM_IN, "UDP related normalized item"), \ + SW_PARAM_DEF(SW_API_SEC_UDP_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "NormVal"), + +#define SW_API_SEC_ICMP4_SET_DESC \ + SW_PARAM_DEF(SW_API_SEC_ICMP4_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_ICMP4_SET, SW_SEC_ICMP4, 4, SW_PARAM_IN, "ICMP4 related normalized item"), \ + SW_PARAM_DEF(SW_API_SEC_ICMP4_SET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN, "NormVal"), + +#define SW_API_SEC_ICMP4_GET_DESC \ + SW_PARAM_DEF(SW_API_SEC_ICMP4_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_ICMP4_GET, SW_SEC_ICMP4, 4, SW_PARAM_IN, "ICMP4 related normalized item"), \ + SW_PARAM_DEF(SW_API_SEC_ICMP4_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "NormVal"), + +#define SW_API_SEC_ICMP6_SET_DESC \ + SW_PARAM_DEF(SW_API_SEC_ICMP6_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_ICMP6_SET, SW_SEC_ICMP6, 4, SW_PARAM_IN, "ICMP6 related normalized item"), \ + SW_PARAM_DEF(SW_API_SEC_ICMP6_SET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN, "NormVal"), + +#define SW_API_SEC_ICMP6_GET_DESC \ + SW_PARAM_DEF(SW_API_SEC_ICMP6_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_ICMP6_GET, SW_SEC_ICMP6, 4, SW_PARAM_IN, "ICMP6 related normalized item"), \ + SW_PARAM_DEF(SW_API_SEC_ICMP6_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "NormVal"), + +#define SW_API_SEC_L3_PARSER_CTRL_GET_DESC \ + SW_PARAM_DEF(SW_API_SEC_L3_PARSER_CTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_L3_PARSER_CTRL_GET, SW_L3_PARSER, sizeof(fal_l3_excep_parser_ctrl), SW_PARAM_PTR|SW_PARAM_OUT, "L3Parser"), + +#define SW_API_SEC_L3_PARSER_CTRL_SET_DESC \ + SW_PARAM_DEF(SW_API_SEC_L3_PARSER_CTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_L3_PARSER_CTRL_SET, SW_L3_PARSER, sizeof(fal_l3_excep_parser_ctrl), SW_PARAM_PTR|SW_PARAM_IN, "L3Parser"), + +#define SW_API_SEC_L4_PARSER_CTRL_GET_DESC \ + SW_PARAM_DEF(SW_API_SEC_L4_PARSER_CTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_L4_PARSER_CTRL_GET, SW_L4_PARSER, sizeof(fal_l4_excep_parser_ctrl), SW_PARAM_PTR|SW_PARAM_OUT, "L4Parser"), + +#define SW_API_SEC_L4_PARSER_CTRL_SET_DESC \ + SW_PARAM_DEF(SW_API_SEC_L4_PARSER_CTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_L4_PARSER_CTRL_SET, SW_L4_PARSER, sizeof(fal_l4_excep_parser_ctrl), SW_PARAM_PTR|SW_PARAM_IN, "L4Parser"), + +#define SW_API_SEC_EXP_CTRL_GET_DESC \ + SW_PARAM_DEF(SW_API_SEC_EXP_CTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_EXP_CTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "ExpType"), \ + SW_PARAM_DEF(SW_API_SEC_EXP_CTRL_GET, SW_EXP_CTRL, sizeof(fal_l3_excep_ctrl_t), SW_PARAM_PTR|SW_PARAM_OUT, "ExpCtrl"), + +#define SW_API_SEC_EXP_CTRL_SET_DESC \ + SW_PARAM_DEF(SW_API_SEC_EXP_CTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SEC_EXP_CTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "ExpType"), \ + SW_PARAM_DEF(SW_API_SEC_EXP_CTRL_SET, SW_EXP_CTRL, sizeof(fal_l3_excep_ctrl_t), SW_PARAM_PTR|SW_PARAM_IN, "ExpCtrl"), + +#define SW_API_IP_HOST_ADD_DESC \ + SW_PARAM_DEF(SW_API_IP_HOST_ADD, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_HOST_ADD, SW_IP_HOSTENTRY, sizeof(fal_host_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Hostentry"), + +#define SW_API_IP_HOST_DEL_DESC \ + SW_PARAM_DEF(SW_API_IP_HOST_DEL, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_HOST_DEL, SW_UINT32, 4, SW_PARAM_IN, "DelMode"), \ + SW_PARAM_DEF(SW_API_IP_HOST_DEL, SW_IP_HOSTENTRY, sizeof(fal_host_entry_t), SW_PARAM_PTR|SW_PARAM_IN, "Hostentry"), + +#define SW_API_IP_HOST_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_HOST_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_HOST_GET, SW_UINT32, 4, SW_PARAM_IN, "GetMode"), \ + SW_PARAM_DEF(SW_API_IP_HOST_GET, SW_IP_HOSTENTRY, sizeof(fal_host_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Hostentry"), + +#define SW_API_IP_HOST_NEXT_DESC \ + SW_PARAM_DEF(SW_API_IP_HOST_NEXT, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_HOST_NEXT, SW_UINT32, 4, SW_PARAM_IN, "NextMode"), \ + SW_PARAM_DEF(SW_API_IP_HOST_NEXT, SW_IP_HOSTENTRY, sizeof(fal_host_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Hostentry"), + +#define SW_API_IP_HOST_COUNTER_BIND_DESC \ + SW_PARAM_DEF(SW_API_IP_HOST_COUNTER_BIND, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_HOST_COUNTER_BIND, SW_UINT32, 4, SW_PARAM_IN, "EntryID"), \ + SW_PARAM_DEF(SW_API_IP_HOST_COUNTER_BIND, SW_UINT32, 4, SW_PARAM_IN, "CounterID"),\ + SW_PARAM_DEF(SW_API_IP_HOST_COUNTER_BIND, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_IP_HOST_PPPOE_BIND_DESC \ + SW_PARAM_DEF(SW_API_IP_HOST_PPPOE_BIND, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_HOST_PPPOE_BIND, SW_UINT32, 4, SW_PARAM_IN, "EntryID"), \ + SW_PARAM_DEF(SW_API_IP_HOST_PPPOE_BIND, SW_UINT32, 4, SW_PARAM_IN, "PPPoEID"), \ + SW_PARAM_DEF(SW_API_IP_HOST_PPPOE_BIND, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_IP_PT_ARP_LEARN_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_PT_ARP_LEARN_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_PT_ARP_LEARN_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_IP_PT_ARP_LEARN_SET, SW_UINT32, 4, SW_PARAM_IN, "LearnStatus"), + +#define SW_API_IP_PT_ARP_LEARN_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_PT_ARP_LEARN_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_PT_ARP_LEARN_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_IP_PT_ARP_LEARN_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "LearnStatus"), + +#define SW_API_IP_ARP_LEARN_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_ARP_LEARN_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_ARP_LEARN_SET, SW_ARP_LEARNMODE, sizeof(fal_arp_learn_mode_t), SW_PARAM_IN, "LearnMode"), + +#define SW_API_IP_ARP_LEARN_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_ARP_LEARN_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_ARP_LEARN_GET, SW_ARP_LEARNMODE, sizeof(fal_arp_learn_mode_t), SW_PARAM_PTR|SW_PARAM_OUT, "LearnMode"), + +#define SW_API_IP_SOURCE_GUARD_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_SOURCE_GUARD_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_SOURCE_GUARD_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_IP_SOURCE_GUARD_SET, SW_IP_GUARDMODE, sizeof(fal_source_guard_mode_t), SW_PARAM_IN, "GuardMode"), + +#define SW_API_IP_SOURCE_GUARD_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_SOURCE_GUARD_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_SOURCE_GUARD_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_IP_SOURCE_GUARD_GET, SW_IP_GUARDMODE, sizeof(fal_source_guard_mode_t), SW_PARAM_PTR|SW_PARAM_OUT, "GuardMode"), + +#define SW_API_IP_ARP_GUARD_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_ARP_GUARD_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_ARP_GUARD_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_IP_ARP_GUARD_SET, SW_IP_GUARDMODE, sizeof(fal_source_guard_mode_t), SW_PARAM_IN, "GuardMode"), + +#define SW_API_IP_ARP_GUARD_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_ARP_GUARD_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_ARP_GUARD_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_IP_ARP_GUARD_GET, SW_IP_GUARDMODE, sizeof(fal_source_guard_mode_t), SW_PARAM_PTR|SW_PARAM_OUT, "GuardMode"), + +#define SW_API_IP_ROUTE_STATUS_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_ROUTE_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_ROUTE_STATUS_SET, SW_ENABLE, 4, SW_PARAM_IN, "Status"), + +#define SW_API_IP_ROUTE_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_ROUTE_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_ROUTE_STATUS_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Status"), + +#define SW_API_IP_INTF_ENTRY_ADD_DESC \ + SW_PARAM_DEF(SW_API_IP_INTF_ENTRY_ADD, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_INTF_ENTRY_ADD, SW_INTFMACENTRY, sizeof(fal_intf_mac_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Entry"), + +#define SW_API_IP_INTF_ENTRY_DEL_DESC \ + SW_PARAM_DEF(SW_API_IP_INTF_ENTRY_DEL, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_INTF_ENTRY_DEL, SW_UINT32, 4, SW_PARAM_IN, "Del Mode"), \ + SW_PARAM_DEF(SW_API_IP_INTF_ENTRY_DEL, SW_INTFMACENTRY, sizeof(fal_intf_mac_entry_t), SW_PARAM_PTR|SW_PARAM_IN, "Entry"), + +#define SW_API_IP_INTF_ENTRY_NEXT_DESC \ + SW_PARAM_DEF(SW_API_IP_INTF_ENTRY_NEXT, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_INTF_ENTRY_NEXT, SW_UINT32, 4, SW_PARAM_IN, "Next Mode"), \ + SW_PARAM_DEF(SW_API_IP_INTF_ENTRY_NEXT, SW_INTFMACENTRY, sizeof(fal_intf_mac_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Entry"), + +#define SW_API_IP_UNK_SOURCE_CMD_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_UNK_SOURCE_CMD_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_UNK_SOURCE_CMD_SET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_IN, "Forwarding"), + +#define SW_API_IP_UNK_SOURCE_CMD_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_UNK_SOURCE_CMD_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_UNK_SOURCE_CMD_GET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_PTR|SW_PARAM_OUT, "Forwarding"), + +#define SW_API_ARP_UNK_SOURCE_CMD_SET_DESC \ + SW_PARAM_DEF(SW_API_ARP_UNK_SOURCE_CMD_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_ARP_UNK_SOURCE_CMD_SET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_IN, "Forwarding"), + +#define SW_API_ARP_UNK_SOURCE_CMD_GET_DESC \ + SW_PARAM_DEF(SW_API_ARP_UNK_SOURCE_CMD_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_ARP_UNK_SOURCE_CMD_GET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_PTR|SW_PARAM_OUT, "Forwarding"), + +#define SW_API_IP_AGE_TIME_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_AGE_TIME_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_AGE_TIME_SET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Time"), + +#define SW_API_IP_AGE_TIME_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_AGE_TIME_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_AGE_TIME_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Time"), + +#define SW_API_WCMP_HASH_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_WCMP_HASH_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_WCMP_HASH_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Hash Mode"), + +#define SW_API_WCMP_HASH_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_WCMP_HASH_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_WCMP_HASH_MODE_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Hash Mode"), + +#define SW_API_IP_VRF_BASE_ADDR_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_VRF_BASE_ADDR_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_VRF_BASE_ADDR_SET, SW_UINT32, 4, SW_PARAM_IN, "VRF ID"), \ + SW_PARAM_DEF(SW_API_IP_VRF_BASE_ADDR_SET, SW_IP4ADDR, sizeof(fal_ip4_addr_t), SW_PARAM_IN, "BaseAddr"), + +#define SW_API_IP_VRF_BASE_ADDR_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_VRF_BASE_ADDR_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_VRF_BASE_ADDR_GET, SW_UINT32, 4, SW_PARAM_IN, "VRF ID"), \ + SW_PARAM_DEF(SW_API_IP_VRF_BASE_ADDR_GET, SW_IP4ADDR, sizeof(fal_ip4_addr_t), SW_PARAM_PTR|SW_PARAM_OUT, "BaseAddr"), + +#define SW_API_IP_VRF_BASE_MASK_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_VRF_BASE_MASK_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_VRF_BASE_MASK_SET, SW_UINT32, 4, SW_PARAM_IN, "VRF ID"), \ + SW_PARAM_DEF(SW_API_IP_VRF_BASE_MASK_SET, SW_IP4ADDR, sizeof(fal_ip4_addr_t), SW_PARAM_IN, "BaseMask"), + +#define SW_API_IP_VRF_BASE_MASK_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_VRF_BASE_MASK_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_VRF_BASE_MASK_GET, SW_UINT32, 4, SW_PARAM_IN, "VRF ID"), \ + SW_PARAM_DEF(SW_API_IP_VRF_BASE_MASK_GET, SW_IP4ADDR, sizeof(fal_ip4_addr_t), SW_PARAM_PTR|SW_PARAM_OUT, "BaseMask"), + +#define SW_API_IP_DEFAULT_ROUTE_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_DEFAULT_ROUTE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_DEFAULT_ROUTE_SET, SW_UINT32, 4, SW_PARAM_IN, "DefaultRoute ID"), \ + SW_PARAM_DEF(SW_API_IP_DEFAULT_ROUTE_SET, SW_DEFAULT_ROUTE_ENTRY, sizeof(fal_default_route_t), SW_PARAM_PTR|SW_PARAM_IN, "DefaultRoute"), + +#define SW_API_IP_DEFAULT_ROUTE_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_DEFAULT_ROUTE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_DEFAULT_ROUTE_GET, SW_UINT32, 4, SW_PARAM_IN, "DefaultRoute ID"), \ + SW_PARAM_DEF(SW_API_IP_DEFAULT_ROUTE_GET, SW_DEFAULT_ROUTE_ENTRY, sizeof(fal_default_route_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "DefaultRoute"), + +#define SW_API_IP_HOST_ROUTE_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_HOST_ROUTE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_HOST_ROUTE_SET, SW_UINT32, 4, SW_PARAM_IN, "HostRoute ID"), \ + SW_PARAM_DEF(SW_API_IP_HOST_ROUTE_SET, SW_HOST_ROUTE_ENTRY, sizeof(fal_host_route_t), SW_PARAM_PTR|SW_PARAM_IN, "HostRoute"), + +#define SW_API_IP_HOST_ROUTE_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_HOST_ROUTE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_HOST_ROUTE_GET, SW_UINT32, 4, SW_PARAM_IN, "HostRoute ID"), \ + SW_PARAM_DEF(SW_API_IP_HOST_ROUTE_GET, SW_HOST_ROUTE_ENTRY, sizeof(fal_host_route_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "HostRoute"), + +#define SW_API_IP_WCMP_ENTRY_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_WCMP_ENTRY_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_WCMP_ENTRY_SET, SW_UINT32, 4, SW_PARAM_IN, "Wcmp ID"), \ + SW_PARAM_DEF(SW_API_IP_WCMP_ENTRY_SET, SW_IP_WCMP_ENTRY, sizeof(fal_ip_wcmp_t), SW_PARAM_PTR|SW_PARAM_IN, "WcmpEntry"), + +#define SW_API_IP_WCMP_ENTRY_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_WCMP_ENTRY_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_WCMP_ENTRY_GET, SW_UINT32, 4, SW_PARAM_IN, "Wcmp ID"), \ + SW_PARAM_DEF(SW_API_IP_WCMP_ENTRY_GET, SW_IP_WCMP_ENTRY, sizeof(fal_ip_wcmp_t), SW_PARAM_PTR|SW_PARAM_OUT, "WcmpEntry"), + +#define SW_API_IP_RFS_IP4_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_RFS_IP4_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_RFS_IP4_SET, SW_IP_RFS_IP4, sizeof(fal_ip4_rfs_t), SW_PARAM_PTR|SW_PARAM_IN, "RfsIp4"), + +#define SW_API_IP_RFS_IP6_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_RFS_IP6_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_RFS_IP6_SET, SW_IP_RFS_IP6, sizeof(fal_ip6_rfs_t), SW_PARAM_PTR|SW_PARAM_IN, "RfsIp6"), + +#define SW_API_IP_RFS_IP4_DEL_DESC \ + SW_PARAM_DEF(SW_API_IP_RFS_IP4_DEL, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_RFS_IP4_DEL, SW_IP_RFS_IP4, sizeof(fal_ip4_rfs_t), SW_PARAM_PTR|SW_PARAM_IN, "RfsIp4"), + +#define SW_API_IP_RFS_IP6_DEL_DESC \ + SW_PARAM_DEF(SW_API_IP_RFS_IP6_DEL, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_RFS_IP6_DEL, SW_IP_RFS_IP6, sizeof(fal_ip6_rfs_t), SW_PARAM_PTR|SW_PARAM_IN, "RfsIp6"), + +#define SW_API_IP_DEFAULT_FLOW_CMD_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_DEFAULT_FLOW_CMD_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_DEFAULT_FLOW_CMD_SET, SW_UINT32, 4, SW_PARAM_IN, "Vrf ID"), \ + SW_PARAM_DEF(SW_API_IP_DEFAULT_FLOW_CMD_SET, SW_FLOWTYPE, sizeof(fal_flow_type_t), SW_PARAM_IN, "FlowType"), \ + SW_PARAM_DEF(SW_API_IP_DEFAULT_FLOW_CMD_SET, SW_FLOWCMD, sizeof(fal_default_flow_cmd_t), SW_PARAM_IN, "FlowCmd"), + +#define SW_API_IP_DEFAULT_FLOW_CMD_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_DEFAULT_FLOW_CMD_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_DEFAULT_FLOW_CMD_GET, SW_UINT32, 4, SW_PARAM_IN, "Vrf ID"), \ + SW_PARAM_DEF(SW_API_IP_DEFAULT_FLOW_CMD_GET, SW_FLOWTYPE, sizeof(fal_flow_type_t), SW_PARAM_IN, "FlowType"), \ + SW_PARAM_DEF(SW_API_IP_DEFAULT_FLOW_CMD_GET, SW_FLOWCMD, sizeof(fal_default_flow_cmd_t), SW_PARAM_PTR|SW_PARAM_OUT, "FlowCmd"), + +#define SW_API_IP_DEFAULT_RT_FLOW_CMD_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_DEFAULT_RT_FLOW_CMD_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_DEFAULT_RT_FLOW_CMD_SET, SW_UINT32, 4, SW_PARAM_IN, "Vrf ID"), \ + SW_PARAM_DEF(SW_API_IP_DEFAULT_RT_FLOW_CMD_SET, SW_FLOWTYPE, sizeof(fal_flow_type_t), SW_PARAM_IN, "FlowType"), \ + SW_PARAM_DEF(SW_API_IP_DEFAULT_RT_FLOW_CMD_SET, SW_FLOWCMD, sizeof(fal_default_flow_cmd_t), SW_PARAM_IN, "FlowCmd"), + +#define SW_API_IP_DEFAULT_RT_FLOW_CMD_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_DEFAULT_RT_FLOW_CMD_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_DEFAULT_RT_FLOW_CMD_GET, SW_UINT32, 4, SW_PARAM_IN, "Vrf ID"), \ + SW_PARAM_DEF(SW_API_IP_DEFAULT_RT_FLOW_CMD_GET, SW_FLOWTYPE, sizeof(fal_flow_type_t), SW_PARAM_IN, "FlowType"), \ + SW_PARAM_DEF(SW_API_IP_DEFAULT_RT_FLOW_CMD_GET, SW_FLOWCMD, sizeof(fal_default_flow_cmd_t), SW_PARAM_PTR|SW_PARAM_OUT, "FlowCmd"), + +#define SW_API_IP_VIS_ARP_SG_CFG_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_VIS_ARP_SG_CFG_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_VIS_ARP_SG_CFG_GET, SW_UINT32, 4, SW_PARAM_IN, "VSI ID"), \ + SW_PARAM_DEF(SW_API_IP_VIS_ARP_SG_CFG_GET, SW_ARP_SG_CFG, sizeof(fal_arp_sg_cfg_t), SW_PARAM_PTR|SW_PARAM_OUT, "ArpSg"), + +#define SW_API_IP_VIS_ARP_SG_CFG_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_VIS_ARP_SG_CFG_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_VIS_ARP_SG_CFG_SET, SW_UINT32, 4, SW_PARAM_IN, "VSI ID"), \ + SW_PARAM_DEF(SW_API_IP_VIS_ARP_SG_CFG_SET, SW_ARP_SG_CFG, sizeof(fal_arp_sg_cfg_t), SW_PARAM_PTR|SW_PARAM_IN, "ArpSg"), + +#define SW_API_IP_NETWORK_ROUTE_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_NETWORK_ROUTE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_NETWORK_ROUTE_GET, SW_UINT32, 4, SW_PARAM_IN, "Index"), \ + SW_PARAM_DEF(SW_API_IP_NETWORK_ROUTE_GET, SW_UINT8, 1, SW_PARAM_IN, "Type"), \ + SW_PARAM_DEF(SW_API_IP_NETWORK_ROUTE_GET, SW_IP_NETWORK_ROUTE, sizeof(fal_network_route_entry_t), SW_PARAM_PTR|SW_PARAM_OUT, "NetworkRoute"), + +#define SW_API_IP_NETWORK_ROUTE_ADD_DESC \ + SW_PARAM_DEF(SW_API_IP_NETWORK_ROUTE_ADD, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_NETWORK_ROUTE_ADD, SW_UINT32, 4, SW_PARAM_IN, "Index"), \ + SW_PARAM_DEF(SW_API_IP_NETWORK_ROUTE_ADD, SW_IP_NETWORK_ROUTE, sizeof(fal_network_route_entry_t), SW_PARAM_PTR|SW_PARAM_IN, "NetworkRoute"), + +#define SW_API_IP_INTF_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_INTF_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_INTF_GET, SW_UINT32, 4, SW_PARAM_IN, "Index"), \ + SW_PARAM_DEF(SW_API_IP_INTF_GET, SW_IP_INTF, sizeof(fal_intf_entry_t), SW_PARAM_PTR|SW_PARAM_OUT, "INTF"), + +#define SW_API_IP_INTF_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_INTF_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_INTF_SET, SW_UINT32, 4, SW_PARAM_IN, "Index"), \ + SW_PARAM_DEF(SW_API_IP_INTF_SET, SW_IP_INTF, sizeof(fal_intf_entry_t), SW_PARAM_PTR|SW_PARAM_IN, "INTF"), + +#define SW_API_IP_VSI_INTF_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_VSI_INTF_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_VSI_INTF_GET, SW_UINT32, 4, SW_PARAM_IN, "vSI"), \ + SW_PARAM_DEF(SW_API_IP_VSI_INTF_GET, SW_IP_VSI_INTF, sizeof(fal_intf_id_t), SW_PARAM_PTR|SW_PARAM_OUT, "VsiIntf"), + +#define SW_API_IP_VSI_INTF_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_VSI_INTF_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_VSI_INTF_SET, SW_UINT32, 4, SW_PARAM_IN, "Vsi"), \ + SW_PARAM_DEF(SW_API_IP_VSI_INTF_SET, SW_IP_VSI_INTF, sizeof(fal_intf_id_t), SW_PARAM_PTR|SW_PARAM_IN, "VsiIntf"), + +#define SW_API_IP_PORT_INTF_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_PORT_INTF_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_PORT_INTF_GET, SW_UINT32, 4, SW_PARAM_IN, "port"), \ + SW_PARAM_DEF(SW_API_IP_PORT_INTF_GET, SW_IP_VSI_INTF, sizeof(fal_intf_id_t), SW_PARAM_PTR|SW_PARAM_OUT, "PortIntf"), + +#define SW_API_IP_PORT_INTF_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_PORT_INTF_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_PORT_INTF_SET, SW_UINT32, 4, SW_PARAM_IN, "Port"), \ + SW_PARAM_DEF(SW_API_IP_PORT_INTF_SET, SW_IP_VSI_INTF, sizeof(fal_intf_id_t), SW_PARAM_PTR|SW_PARAM_IN, "PortIntf"), + +#define SW_API_IP_NEXTHOP_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_NEXTHOP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_NEXTHOP_GET, SW_UINT32, 4, SW_PARAM_IN, "index"), \ + SW_PARAM_DEF(SW_API_IP_NEXTHOP_GET, SW_IP_NEXTHOP, sizeof(fal_ip_nexthop_t), SW_PARAM_PTR|SW_PARAM_OUT, "Nexthop"), + +#define SW_API_IP_NEXTHOP_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_NEXTHOP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_NEXTHOP_SET, SW_UINT32, 4, SW_PARAM_IN, "index"), \ + SW_PARAM_DEF(SW_API_IP_NEXTHOP_SET, SW_IP_NEXTHOP, sizeof(fal_ip_nexthop_t), SW_PARAM_PTR|SW_PARAM_IN, "Nexthop"), + +#define SW_API_IP_VSI_SG_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_VSI_SG_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_VSI_SG_SET, SW_UINT32, 4, SW_PARAM_IN, "vsi"), \ + SW_PARAM_DEF(SW_API_IP_VSI_SG_SET, SW_IP_SG, sizeof(fal_sg_cfg_t), SW_PARAM_PTR|SW_PARAM_IN, "vsisg"), + +#define SW_API_IP_VSI_SG_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_VSI_SG_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_VSI_SG_GET, SW_UINT32, 4, SW_PARAM_IN, "vsi"), \ + SW_PARAM_DEF(SW_API_IP_VSI_SG_GET, SW_IP_SG, sizeof(fal_sg_cfg_t), SW_PARAM_PTR|SW_PARAM_OUT, "vsisg"), + +#define SW_API_IP_PORT_SG_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_PORT_SG_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_PORT_SG_SET, SW_UINT32, 4, SW_PARAM_IN, "port"), \ + SW_PARAM_DEF(SW_API_IP_PORT_SG_SET, SW_IP_SG, sizeof(fal_sg_cfg_t), SW_PARAM_PTR|SW_PARAM_IN, "portsg"), + +#define SW_API_IP_PORT_SG_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_PORT_SG_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_PORT_SG_GET, SW_UINT32, 4, SW_PARAM_IN, "port"), \ + SW_PARAM_DEF(SW_API_IP_PORT_SG_GET, SW_IP_SG, sizeof(fal_sg_cfg_t), SW_PARAM_PTR|SW_PARAM_OUT, "portsg"), + +#define SW_API_IP_PUB_IP_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_PUB_IP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_PUB_IP_SET, SW_UINT32, 4, SW_PARAM_IN, "index"), \ + SW_PARAM_DEF(SW_API_IP_PUB_IP_SET, SW_IP_PUB, sizeof(fal_ip_pub_addr_t), SW_PARAM_PTR|SW_PARAM_IN, "PubAdd"), + +#define SW_API_IP_NETWORK_ROUTE_DEL_DESC \ + SW_PARAM_DEF(SW_API_IP_NETWORK_ROUTE_DEL, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_NETWORK_ROUTE_DEL, SW_UINT32, 4, SW_PARAM_IN, "index"), \ + SW_PARAM_DEF(SW_API_IP_NETWORK_ROUTE_DEL, SW_UINT8, 1, SW_PARAM_IN, "type"), + +#define SW_API_IP_PUB_IP_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_PUB_IP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_PUB_IP_GET, SW_UINT32, 4, SW_PARAM_IN, "index"), \ + SW_PARAM_DEF(SW_API_IP_PUB_IP_GET, SW_IP_PUB, sizeof(fal_ip_pub_addr_t), SW_PARAM_PTR|SW_PARAM_OUT, "PubGet"), + +#define SW_API_IP_PORT_MAC_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_PORT_MAC_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_PORT_MAC_GET, SW_UINT32, 4, SW_PARAM_IN, "port"), \ + SW_PARAM_DEF(SW_API_IP_PORT_MAC_GET, SW_IP_PORTMAC, sizeof(fal_macaddr_entry_t), SW_PARAM_PTR|SW_PARAM_OUT, "portmac"), + +#define SW_API_IP_PORT_MAC_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_PORT_MAC_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_PORT_MAC_SET, SW_UINT32, 4, SW_PARAM_IN, "port"), \ + SW_PARAM_DEF(SW_API_IP_PORT_MAC_SET, SW_IP_PORTMAC, sizeof(fal_macaddr_entry_t), SW_PARAM_PTR|SW_PARAM_IN, "portmac"), + +#define SW_API_IP_ROUTE_MISS_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_ROUTE_MISS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_ROUTE_MISS_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "cmd"), + +#define SW_API_IP_ROUTE_MISS_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_ROUTE_MISS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_ROUTE_MISS_SET, SW_UINT32, 4, SW_PARAM_IN, "cmd"), + +#define SW_API_IP_PORT_ARP_SG_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_PORT_ARP_SG_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_PORT_ARP_SG_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_IP_PORT_ARP_SG_GET, SW_ARP_SG_CFG, sizeof(fal_arp_sg_cfg_t), SW_PARAM_PTR|SW_PARAM_OUT, "portArpSg"), + +#define SW_API_IP_PORT_ARP_SG_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_PORT_ARP_SG_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_PORT_ARP_SG_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_IP_PORT_ARP_SG_SET, SW_ARP_SG_CFG, sizeof(fal_arp_sg_cfg_t), SW_PARAM_PTR|SW_PARAM_IN, "portArpSg"), + +#define SW_API_IP_VSI_MC_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_IP_VSI_MC_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_VSI_MC_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Vsi"), \ + SW_PARAM_DEF(SW_API_IP_VSI_MC_MODE_GET, SW_IP_MCMODE, sizeof(fal_mc_mode_cfg_t), SW_PARAM_PTR|SW_PARAM_OUT, "mcmode"), + +#define SW_API_IP_VSI_MC_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_IP_VSI_MC_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_IP_VSI_MC_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Vsi"), \ + SW_PARAM_DEF(SW_API_IP_VSI_MC_MODE_SET, SW_IP_MCMODE, sizeof(fal_mc_mode_cfg_t), SW_PARAM_PTR|SW_PARAM_IN, "mcmode"), + +#define SW_API_GLOBAL_CTRL_SET_DESC \ + SW_PARAM_DEF(SW_API_GLOBAL_CTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_GLOBAL_CTRL_SET, SW_IP_GLOBAL, sizeof(fal_ip_global_cfg_t), SW_PARAM_PTR|SW_PARAM_IN, "global"), + +#define SW_API_GLOBAL_CTRL_GET_DESC \ + SW_PARAM_DEF(SW_API_GLOBAL_CTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_GLOBAL_CTRL_GET, SW_IP_GLOBAL, sizeof(fal_ip_global_cfg_t), SW_PARAM_PTR|SW_PARAM_OUT, "global"), + +#define SW_API_FLOW_STATUS_SET_DESC \ + SW_PARAM_DEF(SW_API_FLOW_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "status"), + +#define SW_API_FLOW_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_FLOW_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_STATUS_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "status"), + +#define SW_API_FLOW_AGE_TIMER_SET_DESC \ + SW_PARAM_DEF(SW_API_FLOW_AGE_TIMER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_AGE_TIMER_SET, SW_FLOW_AGE, sizeof(fal_flow_age_timer_t), SW_PARAM_PTR|SW_PARAM_IN, "age"), + +#define SW_API_FLOW_AGE_TIMER_GET_DESC \ + SW_PARAM_DEF(SW_API_FLOW_AGE_TIMER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_AGE_TIMER_GET, SW_FLOW_AGE, sizeof(fal_flow_age_timer_t), SW_PARAM_PTR|SW_PARAM_OUT, "age"), + +#define SW_API_FLOW_CTRL_SET_DESC \ + SW_PARAM_DEF(SW_API_FLOW_CTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_CTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "type"), \ + SW_PARAM_DEF(SW_API_FLOW_CTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "dir"), \ + SW_PARAM_DEF(SW_API_FLOW_CTRL_SET, SW_FLOW_CTRL, sizeof(fal_flow_mgmt_t), SW_PARAM_PTR|SW_PARAM_IN, "ctrl"), + +#define SW_API_FLOW_CTRL_GET_DESC \ + SW_PARAM_DEF(SW_API_FLOW_CTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_CTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "type"), \ + SW_PARAM_DEF(SW_API_FLOW_CTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "dir"), \ + SW_PARAM_DEF(SW_API_FLOW_CTRL_GET, SW_FLOW_CTRL, sizeof(fal_flow_mgmt_t), SW_PARAM_PTR|SW_PARAM_OUT, "ctrl"), + +#define SW_API_FLOW_ENTRY_ADD_DESC \ + SW_PARAM_DEF(SW_API_FLOW_ENTRY_ADD, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_ENTRY_ADD, SW_UINT32, 4, SW_PARAM_IN, "add mode"), \ + SW_PARAM_DEF(SW_API_FLOW_ENTRY_ADD, SW_FLOW_ENTRY, sizeof(fal_flow_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Flowentry"), + +#define SW_API_FLOW_ENTRY_DEL_DESC \ + SW_PARAM_DEF(SW_API_FLOW_ENTRY_DEL, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_ENTRY_DEL, SW_UINT32, 4, SW_PARAM_IN, "Del mode"), \ + SW_PARAM_DEF(SW_API_FLOW_ENTRY_DEL, SW_FLOW_ENTRY, sizeof(fal_flow_entry_t), SW_PARAM_PTR|SW_PARAM_IN, "Flowentry"), + +#define SW_API_FLOW_ENTRY_GET_DESC \ + SW_PARAM_DEF(SW_API_FLOW_ENTRY_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_ENTRY_GET, SW_UINT32, 4, SW_PARAM_IN, "get mode"), \ + SW_PARAM_DEF(SW_API_FLOW_ENTRY_GET, SW_FLOW_ENTRY, sizeof(fal_flow_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Flowentry"), + +#define SW_API_FLOW_HOST_ADD_DESC \ + SW_PARAM_DEF(SW_API_FLOW_HOST_ADD, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_HOST_ADD, SW_UINT32, 4, SW_PARAM_IN, "add mode"), \ + SW_PARAM_DEF(SW_API_FLOW_HOST_ADD, SW_FLOW_HOST, sizeof(fal_flow_host_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Flowhost"), + +#define SW_API_FLOW_HOST_DEL_DESC \ + SW_PARAM_DEF(SW_API_FLOW_HOST_DEL, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_HOST_DEL, SW_UINT32, 4, SW_PARAM_IN, "Del mode"), \ + SW_PARAM_DEF(SW_API_FLOW_HOST_DEL, SW_FLOW_HOST, sizeof(fal_flow_host_entry_t), SW_PARAM_PTR|SW_PARAM_IN, "Flowhost"), + +#define SW_API_FLOW_HOST_GET_DESC \ + SW_PARAM_DEF(SW_API_FLOW_HOST_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_HOST_GET, SW_UINT32, 4, SW_PARAM_IN, "get mode"), \ + SW_PARAM_DEF(SW_API_FLOW_HOST_GET, SW_FLOW_HOST, sizeof(fal_flow_host_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Flowhost"), + +#define SW_API_FLOW_GLOBAL_CFG_GET_DESC \ + SW_PARAM_DEF(SW_API_FLOW_GLOBAL_CFG_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_GLOBAL_CFG_GET, SW_FLOW_GLOBAL, sizeof(fal_flow_global_cfg_t), SW_PARAM_PTR|SW_PARAM_OUT, "Flowglobal"), + +#define SW_API_FLOW_GLOBAL_CFG_SET_DESC \ + SW_PARAM_DEF(SW_API_FLOW_GLOBAL_CFG_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_GLOBAL_CFG_SET, SW_FLOW_GLOBAL, sizeof(fal_flow_global_cfg_t), SW_PARAM_PTR|SW_PARAM_IN, "Flowglobal"), + +#define SW_API_FLOWENTRY_NEXT_DESC \ + SW_PARAM_DEF(SW_API_FLOWENTRY_NEXT, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOWENTRY_NEXT, SW_UINT32, 4, SW_PARAM_IN, "Next mode"), \ + SW_PARAM_DEF(SW_API_FLOWENTRY_NEXT, SW_FLOW_ENTRY, sizeof(fal_flow_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Flowentry"), + +#define SW_API_NAT_ADD_DESC \ + SW_PARAM_DEF(SW_API_NAT_ADD, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NAT_ADD, SW_NATENTRY, sizeof(fal_nat_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Natentry"), + +#define SW_API_NAT_DEL_DESC \ + SW_PARAM_DEF(SW_API_NAT_DEL, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NAT_DEL, SW_UINT32, 4, SW_PARAM_IN, "DelMode"), \ + SW_PARAM_DEF(SW_API_NAT_DEL, SW_NATENTRY, sizeof(fal_nat_entry_t), SW_PARAM_PTR|SW_PARAM_IN, "Natentry"), + +#define SW_API_NAT_GET_DESC \ + SW_PARAM_DEF(SW_API_NAT_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NAT_GET, SW_UINT32, 4, SW_PARAM_IN, "GetMode"), \ + SW_PARAM_DEF(SW_API_NAT_GET, SW_NATENTRY, sizeof(fal_nat_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Natentry"), + +#define SW_API_NAT_NEXT_DESC \ + SW_PARAM_DEF(SW_API_NAT_NEXT, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NAT_NEXT, SW_UINT32, 4, SW_PARAM_IN, "NextMode"), \ + SW_PARAM_DEF(SW_API_NAT_NEXT, SW_NATENTRY, sizeof(fal_nat_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Natentry"), + +#define SW_API_NAT_COUNTER_BIND_DESC \ + SW_PARAM_DEF(SW_API_NAT_COUNTER_BIND, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NAT_COUNTER_BIND, SW_UINT32, 4, SW_PARAM_IN, "EntryID"), \ + SW_PARAM_DEF(SW_API_NAT_COUNTER_BIND, SW_UINT32, 4, SW_PARAM_IN, "CounterID"),\ + SW_PARAM_DEF(SW_API_NAT_COUNTER_BIND, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_NAPT_ADD_DESC \ + SW_PARAM_DEF(SW_API_NAPT_ADD, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NAPT_ADD, SW_NAPTENTRY, sizeof(fal_napt_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Naptentry"), + +#define SW_API_NAPT_DEL_DESC \ + SW_PARAM_DEF(SW_API_NAPT_DEL, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NAPT_DEL, SW_UINT32, 4, SW_PARAM_IN, "DelMode"), \ + SW_PARAM_DEF(SW_API_NAPT_DEL, SW_NAPTENTRY, sizeof(fal_napt_entry_t), SW_PARAM_PTR|SW_PARAM_IN, "Naptentry"), + +#define SW_API_NAPT_GET_DESC \ + SW_PARAM_DEF(SW_API_NAPT_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NAPT_GET, SW_UINT32, 4, SW_PARAM_IN, "GetMode"), \ + SW_PARAM_DEF(SW_API_NAPT_GET, SW_NAPTENTRY, sizeof(fal_napt_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Naptentry"), + +#define SW_API_NAPT_NEXT_DESC \ + SW_PARAM_DEF(SW_API_NAPT_NEXT, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NAPT_NEXT, SW_UINT32, 4, SW_PARAM_IN, "NextMode"), \ + SW_PARAM_DEF(SW_API_NAPT_NEXT, SW_NAPTENTRY, sizeof(fal_napt_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Naptentry"), + +#define SW_API_NAPT_COUNTER_BIND_DESC \ + SW_PARAM_DEF(SW_API_NAPT_COUNTER_BIND, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NAPT_COUNTER_BIND, SW_UINT32, 4, SW_PARAM_IN, "EntryID"), \ + SW_PARAM_DEF(SW_API_NAPT_COUNTER_BIND, SW_UINT32, 4, SW_PARAM_IN, "CounterID"),\ + SW_PARAM_DEF(SW_API_NAPT_COUNTER_BIND, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_FLOW_ADD_DESC \ + SW_PARAM_DEF(SW_API_FLOW_ADD, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_ADD, SW_FLOWENTRY, sizeof(fal_napt_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Flowentry"), + +#define SW_API_FLOW_DEL_DESC \ + SW_PARAM_DEF(SW_API_FLOW_DEL, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_DEL, SW_UINT32, 4, SW_PARAM_IN, "DelMode"), \ + SW_PARAM_DEF(SW_API_FLOW_DEL, SW_FLOWENTRY, sizeof(fal_napt_entry_t), SW_PARAM_PTR|SW_PARAM_IN, "Flowentry"), + +#define SW_API_FLOW_GET_DESC \ + SW_PARAM_DEF(SW_API_FLOW_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_GET, SW_UINT32, 4, SW_PARAM_IN, "GetMode"), \ + SW_PARAM_DEF(SW_API_FLOW_GET, SW_FLOWENTRY, sizeof(fal_napt_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Flowentry"), + +#define SW_API_FLOW_COOKIE_SET_DESC \ + SW_PARAM_DEF(SW_API_FLOW_COOKIE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_COOKIE_SET, SW_FLOWCOOKIE, sizeof(fal_flow_cookie_t), SW_PARAM_PTR|SW_PARAM_IN, "Flowcookieentry"), + +#define SW_API_FLOW_RFS_SET_DESC \ + SW_PARAM_DEF(SW_API_FLOW_RFS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_RFS_SET, SW_UINT32, 4, SW_PARAM_IN, "action"), \ + SW_PARAM_DEF(SW_API_FLOW_RFS_SET, SW_FLOWRFS, sizeof(fal_flow_rfs_t), SW_PARAM_PTR|SW_PARAM_IN, "Flowrfs"), + + +#define SW_API_FLOW_NEXT_DESC \ + SW_PARAM_DEF(SW_API_FLOW_NEXT, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_NEXT, SW_UINT32, 4, SW_PARAM_IN, "NextMode"), \ + SW_PARAM_DEF(SW_API_FLOW_NEXT, SW_FLOWENTRY, sizeof(fal_napt_entry_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Flowentry"), + +#define SW_API_FLOW_COUNTER_BIND_DESC \ + SW_PARAM_DEF(SW_API_FLOW_COUNTER_BIND, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_COUNTER_BIND, SW_UINT32, 4, SW_PARAM_IN, "EntryID"), \ + SW_PARAM_DEF(SW_API_FLOW_COUNTER_BIND, SW_UINT32, 4, SW_PARAM_IN, "CounterID"),\ + SW_PARAM_DEF(SW_API_FLOW_COUNTER_BIND, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_NAT_STATUS_SET_DESC \ + SW_PARAM_DEF(SW_API_NAT_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NAT_STATUS_SET, SW_ENABLE, 4, SW_PARAM_IN, "Status"), + +#define SW_API_NAT_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_NAT_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NAT_STATUS_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Status"), + +#define SW_API_NAT_HASH_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_NAT_HASH_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NAT_HASH_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Hashmode"), + +#define SW_API_NAT_HASH_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_NAT_HASH_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NAT_HASH_MODE_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Hashmode"), + +#define SW_API_NAPT_STATUS_SET_DESC \ + SW_PARAM_DEF(SW_API_NAPT_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NAPT_STATUS_SET, SW_ENABLE, 4, SW_PARAM_IN, "Status"), + +#define SW_API_NAPT_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_NAPT_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NAPT_STATUS_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Status"), + +#define SW_API_NAPT_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_NAPT_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NAPT_MODE_SET, SW_NAPTMODE, sizeof(fal_napt_mode_t), SW_PARAM_IN, "Mode"), + +#define SW_API_NAPT_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_NAPT_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NAPT_MODE_GET, SW_NAPTMODE, sizeof(fal_napt_mode_t), SW_PARAM_PTR|SW_PARAM_OUT, "Mode"), + +#define SW_API_PRV_BASE_ADDR_SET_DESC \ + SW_PARAM_DEF(SW_API_PRV_BASE_ADDR_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PRV_BASE_ADDR_SET, SW_IP4ADDR, sizeof(fal_ip4_addr_t), SW_PARAM_IN, "BaseAddr"), + +#define SW_API_PRV_BASE_ADDR_GET_DESC \ + SW_PARAM_DEF(SW_API_PRV_BASE_ADDR_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PRV_BASE_ADDR_GET, SW_IP4ADDR, sizeof(fal_ip4_addr_t), SW_PARAM_PTR|SW_PARAM_OUT, "BaseAddr"), + +#define SW_API_PRV_ADDR_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_PRV_ADDR_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PRV_ADDR_MODE_SET, SW_ENABLE, sizeof(a_bool_t), SW_PARAM_IN, "Mode"), + +#define SW_API_PRV_ADDR_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_PRV_ADDR_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PRV_ADDR_MODE_GET, SW_ENABLE, sizeof(a_bool_t), SW_PARAM_PTR|SW_PARAM_OUT, "Mode"), + +#define SW_API_PUB_ADDR_ENTRY_ADD_DESC \ + SW_PARAM_DEF(SW_API_PUB_ADDR_ENTRY_ADD, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PUB_ADDR_ENTRY_ADD, SW_PUBADDRENTRY, sizeof(fal_nat_pub_addr_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "PubAddrEntry"), + +#define SW_API_PUB_ADDR_ENTRY_DEL_DESC \ + SW_PARAM_DEF(SW_API_PUB_ADDR_ENTRY_DEL, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PUB_ADDR_ENTRY_DEL, SW_UINT32, 4, SW_PARAM_IN, "DelMode"), \ + SW_PARAM_DEF(SW_API_PUB_ADDR_ENTRY_DEL, SW_PUBADDRENTRY, sizeof(fal_nat_pub_addr_t), SW_PARAM_PTR|SW_PARAM_IN, "PubAddrEntry"), + +#define SW_API_PUB_ADDR_ENTRY_NEXT_DESC \ + SW_PARAM_DEF(SW_API_PUB_ADDR_ENTRY_NEXT, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PUB_ADDR_ENTRY_NEXT, SW_UINT32, 4, SW_PARAM_IN, "NextMode"), \ + SW_PARAM_DEF(SW_API_PUB_ADDR_ENTRY_NEXT, SW_PUBADDRENTRY, sizeof(fal_nat_pub_addr_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "PubAddrEntry"), + +#define SW_API_NAT_UNK_SESSION_CMD_SET_DESC \ + SW_PARAM_DEF(SW_API_NAT_UNK_SESSION_CMD_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NAT_UNK_SESSION_CMD_SET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_IN, "Forwarding"), + +#define SW_API_NAT_UNK_SESSION_CMD_GET_DESC \ + SW_PARAM_DEF(SW_API_NAT_UNK_SESSION_CMD_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NAT_UNK_SESSION_CMD_GET, SW_MACCMD, sizeof(fal_fwd_cmd_t), SW_PARAM_PTR|SW_PARAM_OUT, "Forwarding"), + +#define SW_API_PRV_BASE_MASK_SET_DESC \ + SW_PARAM_DEF(SW_API_PRV_BASE_MASK_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PRV_BASE_MASK_SET, SW_IP4ADDR, sizeof(fal_ip4_addr_t), SW_PARAM_IN, "BaseMask"), + +#define SW_API_PRV_BASE_MASK_GET_DESC \ + SW_PARAM_DEF(SW_API_PRV_BASE_MASK_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PRV_BASE_MASK_GET, SW_IP4ADDR, sizeof(fal_ip4_addr_t), SW_PARAM_PTR|SW_PARAM_OUT, "BaseMask"), + +#define SW_API_NAT_GLOBAL_SET_DESC \ + SW_PARAM_DEF(SW_API_NAT_GLOBAL_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_NAT_GLOBAL_SET, SW_ENABLE, 4, SW_PARAM_IN, "Status"), \ + SW_PARAM_DEF(SW_API_NAT_GLOBAL_SET, SW_ENABLE, 4, SW_PARAM_IN, "Sync Flow Counter"), \ + SW_PARAM_DEF(SW_API_NAT_GLOBAL_SET, SW_UINT32, 4, SW_PARAM_IN, "wan portbmp"), + +#define SW_API_TRUNK_GROUP_SET_DESC \ + SW_PARAM_DEF(SW_API_TRUNK_GROUP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_TRUNK_GROUP_SET, SW_UINT32, 4, SW_PARAM_IN, "Trunk ID"), \ + SW_PARAM_DEF(SW_API_TRUNK_GROUP_SET, SW_ENABLE, sizeof(a_bool_t), SW_PARAM_IN, "Status"), \ + SW_PARAM_DEF(SW_API_TRUNK_GROUP_SET, SW_PBMP, sizeof(fal_pbmp_t), SW_PARAM_IN, "Member Port Bitmap"), + +#define SW_API_TRUNK_GROUP_GET_DESC \ + SW_PARAM_DEF(SW_API_TRUNK_GROUP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_TRUNK_GROUP_GET, SW_UINT32, 4, SW_PARAM_IN, "Trunk ID"), \ + SW_PARAM_DEF(SW_API_TRUNK_GROUP_GET, SW_ENABLE, sizeof(a_bool_t), SW_PARAM_PTR|SW_PARAM_OUT, "Status"), \ + SW_PARAM_DEF(SW_API_TRUNK_GROUP_GET, SW_PBMP, sizeof(fal_pbmp_t), SW_PARAM_PTR|SW_PARAM_OUT, "Member Port Bitmap"), + +#define SW_API_TRUNK_HASH_SET_DESC \ + SW_PARAM_DEF(SW_API_TRUNK_HASH_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_TRUNK_HASH_SET, SW_UINT32, 4, SW_PARAM_IN, "Hash Mode"), + +#define SW_API_TRUNK_HASH_GET_DESC \ + SW_PARAM_DEF(SW_API_TRUNK_HASH_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_TRUNK_HASH_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Hash Mode"), + +#define SW_API_TRUNK_MAN_SA_SET_DESC \ + SW_PARAM_DEF(SW_API_TRUNK_MAN_SA_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_TRUNK_MAN_SA_SET, SW_MACADDR, sizeof(fal_mac_addr_t), SW_PARAM_PTR|SW_PARAM_IN, "[Manipulable SA]:"), + +#define SW_API_TRUNK_MAN_SA_GET_DESC \ + SW_PARAM_DEF(SW_API_TRUNK_MAN_SA_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_TRUNK_MAN_SA_GET, SW_MACADDR, sizeof(fal_mac_addr_t), SW_PARAM_PTR|SW_PARAM_OUT, "[Manipulable SA]:"), + +#define SW_API_TRUNK_FAILOVER_EN_SET_DESC \ + SW_PARAM_DEF(SW_API_TRUNK_FAILOVER_EN_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_TRUNK_FAILOVER_EN_SET, SW_ENABLE, 4, SW_PARAM_IN, "failover_en"), + +#define SW_API_TRUNK_FAILOVER_EN_GET_DESC \ + SW_PARAM_DEF(SW_API_TRUNK_FAILOVER_EN_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_TRUNK_FAILOVER_EN_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "failover_en"), + +#define SW_API_MAC_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_MAC_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MAC_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_MAC_MODE_SET, SW_MACCONFIG, sizeof(fal_mac_config_t), SW_PARAM_PTR|SW_PARAM_IN, "MAC config"), + +#define SW_API_MAC_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_MAC_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MAC_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_MAC_MODE_GET, SW_MACCONFIG, sizeof(fal_mac_config_t), SW_PARAM_PTR|SW_PARAM_OUT, "MAC config"), + +#define SW_API_PORT_3AZ_STATUS_SET_DESC \ + SW_PARAM_DEF(SW_API_PORT_3AZ_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PORT_3AZ_STATUS_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PORT_3AZ_STATUS_SET, SW_ENABLE, sizeof(a_bool_t), SW_PARAM_IN, "Status"), + +#define SW_API_PORT_3AZ_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_PORT_3AZ_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PORT_3AZ_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PORT_3AZ_STATUS_GET, SW_ENABLE, sizeof(a_bool_t), SW_PARAM_PTR|SW_PARAM_OUT, "Status"), + +#define SW_API_PHY_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_PHY_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PHY_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Phy ID"), \ + SW_PARAM_DEF(SW_API_PHY_MODE_SET, SW_PHYCONFIG, sizeof(fal_phy_config_t), SW_PARAM_PTR|SW_PARAM_IN, "PHY config"), + +#define SW_API_PHY_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_PHY_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PHY_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Phy ID"), \ + SW_PARAM_DEF(SW_API_PHY_MODE_GET, SW_PHYCONFIG, sizeof(fal_phy_config_t), SW_PARAM_PTR|SW_PARAM_OUT, "PHY config"), + +#define SW_API_FX100_CTRL_SET_DESC \ + SW_PARAM_DEF(SW_API_FX100_CTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FX100_CTRL_SET, SW_FX100CONFIG, sizeof(fal_fx100_ctrl_config_t), SW_PARAM_PTR|SW_PARAM_IN, "fx100 config"), + +#define SW_API_FX100_CTRL_GET_DESC \ + SW_PARAM_DEF(SW_API_FX100_CTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FX100_CTRL_GET, SW_FX100CONFIG, sizeof(fal_fx100_ctrl_config_t), SW_PARAM_PTR|SW_PARAM_OUT, "fx100 config"), + +#define SW_API_FX100_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_FX100_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FX100_STATUS_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "fx100 status"), + + +#define SW_API_MAC06_EXCH_SET_DESC \ + SW_PARAM_DEF(SW_API_MAC06_EXCH_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MAC06_EXCH_SET, SW_ENABLE, sizeof(a_bool_t), SW_PARAM_IN, "enable"), + +#define SW_API_MAC06_EXCH_GET_DESC \ + SW_PARAM_DEF(SW_API_MAC06_EXCH_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MAC06_EXCH_GET, SW_ENABLE, sizeof(a_bool_t), SW_PARAM_PTR|SW_PARAM_OUT, "enable"), + +#define SW_API_VSI_ALLOC_DESC \ + SW_PARAM_DEF(SW_API_VSI_ALLOC, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_VSI_ALLOC, SW_UINT32, sizeof(a_bool_t), SW_PARAM_PTR|SW_PARAM_OUT, "VSI value"), + +#define SW_API_VSI_FREE_DESC \ + SW_PARAM_DEF(SW_API_VSI_FREE, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_VSI_FREE, SW_UINT32, 4, SW_PARAM_IN, "VSI value"), \ + +#define SW_API_PORT_VSI_SET_DESC \ + SW_PARAM_DEF(SW_API_PORT_VSI_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PORT_VSI_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PORT_VSI_SET, SW_UINT32, 4, SW_PARAM_IN, "VSI value"), + +#define SW_API_PORT_VSI_GET_DESC \ + SW_PARAM_DEF(SW_API_PORT_VSI_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PORT_VSI_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PORT_VSI_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "VSI value"), + +#define SW_API_PORT_VLAN_VSI_SET_DESC \ + SW_PARAM_DEF(SW_API_PORT_VLAN_VSI_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PORT_VLAN_VSI_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PORT_VLAN_VSI_SET, SW_UINT32, 4, SW_PARAM_IN, "STAG VID"), \ + SW_PARAM_DEF(SW_API_PORT_VLAN_VSI_SET, SW_UINT32, 4, SW_PARAM_IN, "CTAG VID"), \ + SW_PARAM_DEF(SW_API_PORT_VLAN_VSI_SET, SW_UINT32, 4, SW_PARAM_IN, "VSI value"), + +#define SW_API_PORT_VLAN_VSI_GET_DESC \ + SW_PARAM_DEF(SW_API_PORT_VLAN_VSI_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PORT_VLAN_VSI_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PORT_VLAN_VSI_GET, SW_UINT32, 4, SW_PARAM_IN, "STAG VID"), \ + SW_PARAM_DEF(SW_API_PORT_VLAN_VSI_GET, SW_UINT32, 4, SW_PARAM_IN, "CTAG VID"), \ + SW_PARAM_DEF(SW_API_PORT_VLAN_VSI_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "VSI value"), + +#define SW_API_VSI_TBL_DUMP_DESC \ + SW_PARAM_DEF(SW_API_VSI_TBL_DUMP, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + +#define SW_API_VSI_NEWADDR_LRN_GET_DESC \ + SW_PARAM_DEF(SW_API_VSI_NEWADDR_LRN_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_VSI_NEWADDR_LRN_GET, SW_UINT32, 4, SW_PARAM_IN, "VSI ID"), \ + SW_PARAM_DEF(SW_API_VSI_NEWADDR_LRN_GET, SW_VSI_NEWADDR_LRN, sizeof(fal_vsi_newaddr_lrn_t), SW_PARAM_PTR|SW_PARAM_OUT, "newaddr_lrn"), + +#define SW_API_VSI_NEWADDR_LRN_SET_DESC \ + SW_PARAM_DEF(SW_API_VSI_NEWADDR_LRN_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_VSI_NEWADDR_LRN_SET, SW_UINT32, 4, SW_PARAM_IN, "VSI ID"), \ + SW_PARAM_DEF(SW_API_VSI_NEWADDR_LRN_SET, SW_VSI_NEWADDR_LRN, sizeof(fal_vsi_newaddr_lrn_t), SW_PARAM_PTR|SW_PARAM_IN, "newaddr_lrn"), + +#define SW_API_VSI_STAMOVE_SET_DESC \ + SW_PARAM_DEF(SW_API_VSI_STAMOVE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_VSI_STAMOVE_SET, SW_UINT32, 4, SW_PARAM_IN, "VSI ID"), \ + SW_PARAM_DEF(SW_API_VSI_STAMOVE_SET, SW_VSI_STAMOVE, sizeof(fal_vsi_stamove_t), SW_PARAM_PTR|SW_PARAM_IN, "stamove"), + +#define SW_API_VSI_STAMOVE_GET_DESC \ + SW_PARAM_DEF(SW_API_VSI_STAMOVE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_VSI_STAMOVE_GET, SW_UINT32, 4, SW_PARAM_IN, "VSI ID"), \ + SW_PARAM_DEF(SW_API_VSI_STAMOVE_GET, SW_VSI_STAMOVE, sizeof(fal_vsi_stamove_t), SW_PARAM_PTR|SW_PARAM_OUT, "stamove"), + +#define SW_API_VSI_MEMBER_SET_DESC \ + SW_PARAM_DEF(SW_API_VSI_MEMBER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_VSI_MEMBER_SET, SW_UINT32, 4, SW_PARAM_IN, "VSI ID"), \ + SW_PARAM_DEF(SW_API_VSI_MEMBER_SET, SW_VSI_MEMBER, sizeof(fal_vsi_member_t), SW_PARAM_PTR|SW_PARAM_IN, "members"), + +#define SW_API_VSI_MEMBER_GET_DESC \ + SW_PARAM_DEF(SW_API_VSI_MEMBER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_VSI_MEMBER_GET, SW_UINT32, 4, SW_PARAM_IN, "VSI ID"), \ + SW_PARAM_DEF(SW_API_VSI_MEMBER_GET, SW_VSI_MEMBER, sizeof(fal_vsi_member_t), SW_PARAM_PTR|SW_PARAM_OUT, "members"), + +#define SW_API_VSI_COUNTER_GET_DESC \ + SW_PARAM_DEF(SW_API_VSI_COUNTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_VSI_COUNTER_GET, SW_UINT32, 4, SW_PARAM_IN, "VSI ID"), \ + SW_PARAM_DEF(SW_API_VSI_COUNTER_GET, SW_VSI_COUNTER, sizeof(fal_vsi_counter_t), SW_PARAM_PTR|SW_PARAM_OUT, "counter"), + +#define SW_API_VSI_COUNTER_CLEANUP_DESC \ + SW_PARAM_DEF(SW_API_VSI_COUNTER_CLEANUP, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_VSI_COUNTER_CLEANUP, SW_UINT32, 4, SW_PARAM_IN, "VSI ID"), + +#define SW_API_UCAST_QUEUE_BASE_PROFILE_SET_DESC \ + SW_PARAM_DEF(SW_API_UCAST_QUEUE_BASE_PROFILE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_UCAST_QUEUE_BASE_PROFILE_SET, SW_UCAST_QUEUE_MAP, sizeof(fal_ucast_queue_dest_t), SW_PARAM_PTR|SW_PARAM_IN, "queue dest"), \ + SW_PARAM_DEF(SW_API_UCAST_QUEUE_BASE_PROFILE_SET, SW_UINT32, 4, SW_PARAM_IN, "Queue base"), \ + SW_PARAM_DEF(SW_API_UCAST_QUEUE_BASE_PROFILE_SET, SW_UINT8, 1, SW_PARAM_IN, "Profile"), + +#define SW_API_UCAST_QUEUE_BASE_PROFILE_GET_DESC \ + SW_PARAM_DEF(SW_API_UCAST_QUEUE_BASE_PROFILE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_UCAST_QUEUE_BASE_PROFILE_GET, SW_UCAST_QUEUE_MAP, sizeof(fal_ucast_queue_dest_t), SW_PARAM_PTR|SW_PARAM_IN, "queue dest"), \ + SW_PARAM_DEF(SW_API_UCAST_QUEUE_BASE_PROFILE_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Queue base"), \ + SW_PARAM_DEF(SW_API_UCAST_QUEUE_BASE_PROFILE_GET, SW_UINT8, 1, SW_PARAM_PTR|SW_PARAM_OUT, "Profile"), + +#define SW_API_UCAST_PRIORITY_CLASS_SET_DESC \ + SW_PARAM_DEF(SW_API_UCAST_PRIORITY_CLASS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_UCAST_PRIORITY_CLASS_SET, SW_UINT8, 1, SW_PARAM_IN, "Profile"), \ + SW_PARAM_DEF(SW_API_UCAST_PRIORITY_CLASS_SET, SW_UINT8, 1, SW_PARAM_IN, "Priority"), \ + SW_PARAM_DEF(SW_API_UCAST_PRIORITY_CLASS_SET, SW_UINT8, 1, SW_PARAM_IN, "Class"), + +#define SW_API_UCAST_PRIORITY_CLASS_GET_DESC \ + SW_PARAM_DEF(SW_API_UCAST_PRIORITY_CLASS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_UCAST_PRIORITY_CLASS_GET, SW_UINT8, 1, SW_PARAM_IN, "Profile"), \ + SW_PARAM_DEF(SW_API_UCAST_PRIORITY_CLASS_GET, SW_UINT8, 1, SW_PARAM_IN, "Priority"), \ + SW_PARAM_DEF(SW_API_UCAST_PRIORITY_CLASS_GET, SW_UINT8, 1, SW_PARAM_PTR|SW_PARAM_OUT, "Class"), + +#define SW_API_UCAST_HASH_MAP_SET_DESC \ + SW_PARAM_DEF(SW_API_UCAST_HASH_MAP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_UCAST_HASH_MAP_SET, SW_UINT8, 1, SW_PARAM_IN, "Profile"), \ + SW_PARAM_DEF(SW_API_UCAST_HASH_MAP_SET, SW_UINT8, 1, SW_PARAM_IN, "Rss hash"), \ + SW_PARAM_DEF(SW_API_UCAST_HASH_MAP_SET, SW_UINT8, 1, SW_PARAM_IN, "Queue hash"), + +#define SW_API_UCAST_HASH_MAP_GET_DESC \ + SW_PARAM_DEF(SW_API_UCAST_HASH_MAP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_UCAST_HASH_MAP_GET, SW_UINT8, 1, SW_PARAM_IN, "Profile"), \ + SW_PARAM_DEF(SW_API_UCAST_HASH_MAP_GET, SW_UINT8, 1, SW_PARAM_IN, "Rss hash"), \ + SW_PARAM_DEF(SW_API_UCAST_HASH_MAP_GET, SW_UINT8, 1, SW_PARAM_PTR|SW_PARAM_OUT, "Queue hash"), + +#define SW_API_MCAST_CPUCODE_CLASS_SET_DESC \ + SW_PARAM_DEF(SW_API_MCAST_CPUCODE_CLASS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MCAST_CPUCODE_CLASS_SET, SW_UINT8, 1, SW_PARAM_IN, "Cpu code"), \ + SW_PARAM_DEF(SW_API_MCAST_CPUCODE_CLASS_SET, SW_UINT8, 1, SW_PARAM_IN, "Queue Class"), + +#define SW_API_MCAST_CPUCODE_CLASS_GET_DESC \ + SW_PARAM_DEF(SW_API_MCAST_CPUCODE_CLASS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MCAST_CPUCODE_CLASS_GET, SW_UINT8, 1, SW_PARAM_IN, "Cpu code"), \ + SW_PARAM_DEF(SW_API_MCAST_CPUCODE_CLASS_GET, SW_UINT8, 1, SW_PARAM_PTR|SW_PARAM_OUT, "Queue Class"), + +#define SW_API_MCAST_PRIORITY_CLASS_SET_DESC \ + SW_PARAM_DEF(SW_API_MCAST_PRIORITY_CLASS_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MCAST_PRIORITY_CLASS_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_MCAST_PRIORITY_CLASS_SET, SW_UINT8, 1, SW_PARAM_IN, "Priority"), \ + SW_PARAM_DEF(SW_API_MCAST_PRIORITY_CLASS_SET, SW_UINT8, 1, SW_PARAM_IN, "Queue Class"), + +#define SW_API_MCAST_PRIORITY_CLASS_GET_DESC \ + SW_PARAM_DEF(SW_API_MCAST_PRIORITY_CLASS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MCAST_PRIORITY_CLASS_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_MCAST_PRIORITY_CLASS_GET, SW_UINT8, 1, SW_PARAM_IN, "Priority"), \ + SW_PARAM_DEF(SW_API_MCAST_PRIORITY_CLASS_GET, SW_UINT8, 1, SW_PARAM_PTR|SW_PARAM_OUT, "Queue Class"), + +#define SW_API_QUEUE_FLUSH_DESC \ + SW_PARAM_DEF(SW_API_QUEUE_FLUSH, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_QUEUE_FLUSH, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_QUEUE_FLUSH, SW_UINT16, 2, SW_PARAM_IN, "queue ID"), + +#define SW_API_UCAST_DFLT_HASH_MAP_SET_DESC \ + SW_PARAM_DEF(SW_API_UCAST_DFLT_HASH_MAP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_UCAST_DFLT_HASH_MAP_SET, SW_UINT8, 1, SW_PARAM_IN, "ucast dflt hash"), + +#define SW_API_UCAST_DFLT_HASH_MAP_GET_DESC \ + SW_PARAM_DEF(SW_API_UCAST_DFLT_HASH_MAP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_UCAST_DFLT_HASH_MAP_GET, SW_UINT8, 1, SW_PARAM_PTR|SW_PARAM_OUT, "ucast dflt hash"), + +#define SW_API_AC_CTRL_SET_DESC \ + SW_PARAM_DEF(SW_API_AC_CTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_AC_CTRL_SET, SW_AC_OBJ, sizeof(fal_ac_obj_t), SW_PARAM_PTR|SW_PARAM_IN, "ac obj"), \ + SW_PARAM_DEF(SW_API_AC_CTRL_SET, SW_AC_CTRL, sizeof(fal_ac_ctrl_t), SW_PARAM_PTR|SW_PARAM_IN, "ac ctrl"), + +#define SW_API_AC_CTRL_GET_DESC \ + SW_PARAM_DEF(SW_API_AC_CTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_AC_CTRL_GET, SW_AC_OBJ, sizeof(fal_ac_obj_t), SW_PARAM_PTR|SW_PARAM_IN, "AC obj"), \ + SW_PARAM_DEF(SW_API_AC_CTRL_GET, SW_AC_CTRL, sizeof(fal_ac_ctrl_t), SW_PARAM_PTR|SW_PARAM_OUT, "ac ctrl"), + +#define SW_API_AC_PRE_BUFFER_SET_DESC \ + SW_PARAM_DEF(SW_API_AC_PRE_BUFFER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_AC_PRE_BUFFER_SET, SW_AC_OBJ, sizeof(fal_ac_obj_t), SW_PARAM_PTR|SW_PARAM_IN, "AC obj"), \ + SW_PARAM_DEF(SW_API_AC_PRE_BUFFER_SET, SW_UINT16, 2, SW_PARAM_IN, "num"), + +#define SW_API_AC_PRE_BUFFER_GET_DESC \ + SW_PARAM_DEF(SW_API_AC_PRE_BUFFER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_AC_PRE_BUFFER_GET, SW_AC_OBJ, sizeof(fal_ac_obj_t), SW_PARAM_PTR|SW_PARAM_IN, "AC obj"), \ + SW_PARAM_DEF(SW_API_AC_PRE_BUFFER_GET, SW_UINT16, 2, SW_PARAM_PTR|SW_PARAM_OUT, "num"), + +#define SW_API_QUEUE_GROUP_SET_DESC \ + SW_PARAM_DEF(SW_API_QUEUE_GROUP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_QUEUE_GROUP_SET, SW_UINT32, 4, SW_PARAM_IN, "queue id"), \ + SW_PARAM_DEF(SW_API_QUEUE_GROUP_SET, SW_UINT8, 1, SW_PARAM_IN, "group id"), + +#define SW_API_QUEUE_GROUP_GET_DESC \ + SW_PARAM_DEF(SW_API_QUEUE_GROUP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_QUEUE_GROUP_GET, SW_UINT32, 4, SW_PARAM_IN, "queue id"), \ + SW_PARAM_DEF(SW_API_QUEUE_GROUP_GET, SW_UINT8, 1, SW_PARAM_PTR|SW_PARAM_OUT, "group id"), + +#define SW_API_STATIC_THRESH_SET_DESC \ + SW_PARAM_DEF(SW_API_STATIC_THRESH_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_STATIC_THRESH_SET, SW_AC_OBJ, sizeof(fal_ac_obj_t), SW_PARAM_PTR|SW_PARAM_IN, "AC obj"), \ + SW_PARAM_DEF(SW_API_STATIC_THRESH_SET, SW_STATIC_THRESH, sizeof(fal_ac_static_threshold_t), SW_PARAM_PTR|SW_PARAM_IN, "static thresh"), + +#define SW_API_STATIC_THRESH_GET_DESC \ + SW_PARAM_DEF(SW_API_STATIC_THRESH_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_STATIC_THRESH_GET, SW_AC_OBJ, sizeof(fal_ac_obj_t), SW_PARAM_PTR|SW_PARAM_IN, "AC obj"), \ + SW_PARAM_DEF(SW_API_STATIC_THRESH_GET, SW_STATIC_THRESH, sizeof(fal_ac_static_threshold_t), SW_PARAM_PTR|SW_PARAM_OUT, "static thresh"), + +#define SW_API_DYNAMIC_THRESH_SET_DESC \ + SW_PARAM_DEF(SW_API_DYNAMIC_THRESH_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_DYNAMIC_THRESH_SET, SW_UINT32, 4, SW_PARAM_IN, "queue id"), \ + SW_PARAM_DEF(SW_API_DYNAMIC_THRESH_SET, SW_DYNAMIC_THRESH, sizeof(fal_ac_dynamic_threshold_t), SW_PARAM_PTR|SW_PARAM_IN, "dynamic thresh"), + +#define SW_API_DYNAMIC_THRESH_GET_DESC \ + SW_PARAM_DEF(SW_API_DYNAMIC_THRESH_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_DYNAMIC_THRESH_GET, SW_UINT32, 4, SW_PARAM_IN, "queue id"), \ + SW_PARAM_DEF(SW_API_DYNAMIC_THRESH_GET, SW_DYNAMIC_THRESH, sizeof(fal_ac_dynamic_threshold_t), SW_PARAM_PTR|SW_PARAM_OUT, "dynamic thresh"), + +#define SW_API_GOURP_BUFFER_SET_DESC \ + SW_PARAM_DEF(SW_API_GOURP_BUFFER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_GOURP_BUFFER_SET, SW_UINT8, 1, SW_PARAM_IN, "group"), \ + SW_PARAM_DEF(SW_API_GOURP_BUFFER_SET, SW_GROUP_BUFFER, sizeof(fal_ac_group_buffer_t), SW_PARAM_PTR|SW_PARAM_IN, "buffer cfg"), + +#define SW_API_GOURP_BUFFER_GET_DESC \ + SW_PARAM_DEF(SW_API_GOURP_BUFFER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_GOURP_BUFFER_GET, SW_UINT8, 1, SW_PARAM_IN, "group"), \ + SW_PARAM_DEF(SW_API_GOURP_BUFFER_GET, SW_GROUP_BUFFER, sizeof(fal_ac_group_buffer_t), SW_PARAM_PTR|SW_PARAM_OUT, "buffer cfg"), + +#define SW_API_QUEUE_CNT_CTRL_GET_DESC \ + SW_PARAM_DEF(SW_API_QUEUE_CNT_CTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_QUEUE_CNT_CTRL_GET, SW_ENABLE, sizeof(a_bool_t), SW_PARAM_PTR|SW_PARAM_OUT, "queue cnt en"), + +#define SW_API_QUEUE_CNT_CTRL_SET_DESC \ + SW_PARAM_DEF(SW_API_QUEUE_CNT_CTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_QUEUE_CNT_CTRL_SET, SW_ENABLE, sizeof(a_bool_t), SW_PARAM_IN, "queue cnt en"), + +#define SW_API_QUEUE_CNT_CLEANUP_DESC \ + SW_PARAM_DEF(SW_API_QUEUE_CNT_CLEANUP, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_QUEUE_CNT_CLEANUP, SW_UINT32, 4, SW_PARAM_IN, "queue id"), + +#define SW_API_QUEUE_CNT_GET_DESC \ + SW_PARAM_DEF(SW_API_QUEUE_CNT_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_QUEUE_CNT_GET, SW_UINT32, 4, SW_PARAM_IN, "queue ID"), \ + SW_PARAM_DEF(SW_API_QUEUE_CNT_GET, SW_QM_CNT, sizeof(fal_queue_stats_t), SW_PARAM_PTR|SW_PARAM_OUT, "queue cnt"), + +#define SW_API_QM_ENQUEUE_CTRL_SET_DESC \ + SW_PARAM_DEF(SW_API_QM_ENQUEUE_CTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_QM_ENQUEUE_CTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "queue ID"), \ + SW_PARAM_DEF(SW_API_QM_ENQUEUE_CTRL_SET, SW_ENABLE, sizeof(a_bool_t), SW_PARAM_IN, "enqueue en"), + +#define SW_API_QM_ENQUEUE_CTRL_GET_DESC \ + SW_PARAM_DEF(SW_API_QM_ENQUEUE_CTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_QM_ENQUEUE_CTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "queue ID"), \ + SW_PARAM_DEF(SW_API_QM_ENQUEUE_CTRL_GET, SW_ENABLE, sizeof(a_bool_t), SW_PARAM_PTR|SW_PARAM_OUT, "enqueue en"), + +#define SW_API_QM_SOURCE_PROFILE_SET_DESC \ + SW_PARAM_DEF(SW_API_QM_SOURCE_PROFILE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_QM_SOURCE_PROFILE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_QM_SOURCE_PROFILE_SET, SW_UINT32, 4, SW_PARAM_IN, "Source profile"), + +#define SW_API_QM_SOURCE_PROFILE_GET_DESC \ + SW_PARAM_DEF(SW_API_QM_SOURCE_PROFILE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_QM_SOURCE_PROFILE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_QM_SOURCE_PROFILE_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Source profile"), + +#define SW_API_MGMTCTRL_ETHTYPE_PROFILE_SET_DESC \ + SW_PARAM_DEF(SW_API_MGMTCTRL_ETHTYPE_PROFILE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MGMTCTRL_ETHTYPE_PROFILE_SET, SW_UINT32, 4, SW_PARAM_IN, "Profile ID"), \ + SW_PARAM_DEF(SW_API_MGMTCTRL_ETHTYPE_PROFILE_SET, SW_UINT32, 4, SW_PARAM_IN, "Ethernet Type"), + +#define SW_API_MGMTCTRL_ETHTYPE_PROFILE_GET_DESC \ + SW_PARAM_DEF(SW_API_MGMTCTRL_ETHTYPE_PROFILE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MGMTCTRL_ETHTYPE_PROFILE_GET, SW_UINT32, 4, SW_PARAM_IN, "Profile ID"), \ + SW_PARAM_DEF(SW_API_MGMTCTRL_ETHTYPE_PROFILE_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Ethernet Type"), + +#define SW_API_MGMTCTRL_RFDB_PROFILE_SET_DESC \ + SW_PARAM_DEF(SW_API_MGMTCTRL_RFDB_PROFILE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MGMTCTRL_RFDB_PROFILE_SET, SW_UINT32, 4, SW_PARAM_IN, "Profile ID"), \ + SW_PARAM_DEF(SW_API_MGMTCTRL_RFDB_PROFILE_SET, SW_MACADDR, sizeof(fal_mac_addr_t), SW_PARAM_PTR|SW_PARAM_IN, "Address"), + +#define SW_API_MGMTCTRL_RFDB_PROFILE_GET_DESC \ + SW_PARAM_DEF(SW_API_MGMTCTRL_RFDB_PROFILE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MGMTCTRL_RFDB_PROFILE_GET, SW_UINT32, 4, SW_PARAM_IN, "Profile ID"), \ + SW_PARAM_DEF(SW_API_MGMTCTRL_RFDB_PROFILE_GET, SW_MACADDR, sizeof(fal_mac_addr_t), SW_PARAM_PTR|SW_PARAM_OUT, "Address"), + +#define SW_API_MGMTCTRL_CTRLPKT_PROFILE_ADD_DESC \ + SW_PARAM_DEF(SW_API_MGMTCTRL_CTRLPKT_PROFILE_ADD, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MGMTCTRL_CTRLPKT_PROFILE_ADD, SW_CTRLPKT_PROFILE, sizeof(fal_ctrlpkt_profile_t), SW_PARAM_PTR|SW_PARAM_IN, "app entry"), + +#define SW_API_MGMTCTRL_CTRLPKT_PROFILE_DEL_DESC \ + SW_PARAM_DEF(SW_API_MGMTCTRL_CTRLPKT_PROFILE_DEL, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MGMTCTRL_CTRLPKT_PROFILE_DEL, SW_CTRLPKT_PROFILE, sizeof(fal_ctrlpkt_profile_t), SW_PARAM_PTR|SW_PARAM_IN, "app entry"), + +#define SW_API_MGMTCTRL_CTRLPKT_PROFILE_GETFIRST_DESC \ + SW_PARAM_DEF(SW_API_MGMTCTRL_CTRLPKT_PROFILE_GETFIRST, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MGMTCTRL_CTRLPKT_PROFILE_GETFIRST, SW_CTRLPKT_PROFILE, sizeof(fal_ctrlpkt_profile_t), SW_PARAM_PTR|SW_PARAM_OUT, "app entry"), + +#define SW_API_MGMTCTRL_CTRLPKT_PROFILE_GETNEXT_DESC \ + SW_PARAM_DEF(SW_API_MGMTCTRL_CTRLPKT_PROFILE_GETNEXT, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MGMTCTRL_CTRLPKT_PROFILE_GETNEXT, SW_CTRLPKT_PROFILE, sizeof(fal_ctrlpkt_profile_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "app entry"), + + +#define SW_API_SERVCODE_CONFIG_SET_DESC \ + SW_PARAM_DEF(SW_API_SERVCODE_CONFIG_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SERVCODE_CONFIG_SET, SW_UINT32, 4, SW_PARAM_IN, "Index"), \ + SW_PARAM_DEF(SW_API_SERVCODE_CONFIG_SET, SW_SERVCODE_CONFIG, sizeof(fal_servcode_config_t), SW_PARAM_PTR|SW_PARAM_IN, "Servcode Config"), + +#define SW_API_SERVCODE_CONFIG_GET_DESC \ + SW_PARAM_DEF(SW_API_SERVCODE_CONFIG_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SERVCODE_CONFIG_GET, SW_UINT32, 4, SW_PARAM_IN, "Index"), \ + SW_PARAM_DEF(SW_API_SERVCODE_CONFIG_GET, SW_SERVCODE_CONFIG, sizeof(fal_servcode_config_t), SW_PARAM_PTR|SW_PARAM_OUT, "Servcode Config"), + +#define SW_API_SERVCODE_LOOPCHECK_EN_DESC \ + SW_PARAM_DEF(SW_API_SERVCODE_LOOPCHECK_EN, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SERVCODE_LOOPCHECK_EN, SW_ENABLE, 4, SW_PARAM_IN, "Enable"), + +#define SW_API_SERVCODE_LOOPCHECK_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_SERVCODE_LOOPCHECK_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SERVCODE_LOOPCHECK_STATUS_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Enable"), + +#define SW_API_POLICER_TIMESLOT_SET_DESC \ + SW_PARAM_DEF(SW_API_POLICER_TIMESLOT_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_POLICER_TIMESLOT_SET, SW_UINT32, 4, SW_PARAM_IN, "Time Slot"), + +#define SW_API_POLICER_TIMESLOT_GET_DESC \ + SW_PARAM_DEF(SW_API_POLICER_TIMESLOT_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_POLICER_TIMESLOT_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Time Slot"), + +#define SW_API_POLICER_PORT_COUNTER_GET_DESC \ + SW_PARAM_DEF(SW_API_POLICER_PORT_COUNTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_POLICER_PORT_COUNTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_POLICER_PORT_COUNTER_GET, SW_POLICER_COUNTER, sizeof(fal_policer_counter_t), SW_PARAM_PTR|SW_PARAM_OUT, "Port Statistics"), + +#define SW_API_POLICER_ACL_COUNTER_GET_DESC \ + SW_PARAM_DEF(SW_API_POLICER_ACL_COUNTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_POLICER_ACL_COUNTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Index"), \ + SW_PARAM_DEF(SW_API_POLICER_ACL_COUNTER_GET, SW_POLICER_COUNTER, sizeof(fal_policer_counter_t), SW_PARAM_PTR|SW_PARAM_OUT, "ACL Statistics"), + +#define SW_API_POLICER_COMPENSATION_SET_DESC \ + SW_PARAM_DEF(SW_API_POLICER_COMPENSATION_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_POLICER_COMPENSATION_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_POLICER_COMPENSATION_SET, SW_UINT32, 4, SW_PARAM_IN, "Number"), + +#define SW_API_POLICER_COMPENSATION_GET_DESC \ + SW_PARAM_DEF(SW_API_POLICER_COMPENSATION_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_POLICER_COMPENSATION_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_POLICER_COMPENSATION_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Number"), + +#define SW_API_POLICER_PORT_ENTRY_SET_DESC \ + SW_PARAM_DEF(SW_API_POLICER_PORT_ENTRY_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_POLICER_PORT_ENTRY_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_POLICER_PORT_ENTRY_SET, SW_POLICER_PORT_CONFIG, sizeof(fal_policer_config_t), SW_PARAM_PTR|SW_PARAM_IN, "Port Config"), \ + SW_PARAM_DEF(SW_API_POLICER_PORT_ENTRY_SET, SW_POLICER_CMD_CONFIG, sizeof(fal_policer_action_t), SW_PARAM_PTR|SW_PARAM_IN, "CMD"), + +#define SW_API_POLICER_PORT_ENTRY_GET_DESC \ + SW_PARAM_DEF(SW_API_POLICER_PORT_ENTRY_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_POLICER_PORT_ENTRY_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_POLICER_PORT_ENTRY_GET, SW_POLICER_PORT_CONFIG, sizeof(fal_policer_config_t), SW_PARAM_PTR|SW_PARAM_OUT, "Port Config"), \ + SW_PARAM_DEF(SW_API_POLICER_PORT_ENTRY_GET, SW_POLICER_CMD_CONFIG, sizeof(fal_policer_action_t), SW_PARAM_PTR|SW_PARAM_OUT, "CMD"), + +#define SW_API_POLICER_ACL_ENTRY_SET_DESC \ + SW_PARAM_DEF(SW_API_POLICER_ACL_ENTRY_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_POLICER_ACL_ENTRY_SET, SW_UINT32, 4, SW_PARAM_IN, "Index"), \ + SW_PARAM_DEF(SW_API_POLICER_ACL_ENTRY_SET, SW_POLICER_ACL_CONFIG, sizeof(fal_policer_config_t), SW_PARAM_PTR|SW_PARAM_IN, "ACL Config"), \ + SW_PARAM_DEF(SW_API_POLICER_ACL_ENTRY_SET, SW_POLICER_CMD_CONFIG, sizeof(fal_policer_action_t), SW_PARAM_PTR|SW_PARAM_IN, "CMD"), + +#define SW_API_POLICER_ACL_ENTRY_GET_DESC \ + SW_PARAM_DEF(SW_API_POLICER_ACL_ENTRY_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_POLICER_ACL_ENTRY_GET, SW_UINT32, 4, SW_PARAM_IN, "Index"), \ + SW_PARAM_DEF(SW_API_POLICER_ACL_ENTRY_GET, SW_POLICER_ACL_CONFIG, sizeof(fal_policer_config_t), SW_PARAM_PTR|SW_PARAM_OUT, "ACL Config"), \ + SW_PARAM_DEF(SW_API_POLICER_ACL_ENTRY_GET, SW_POLICER_CMD_CONFIG, sizeof(fal_policer_action_t), SW_PARAM_PTR|SW_PARAM_OUT, "CMD"), + +#define SW_API_POLICER_GLOBAL_COUNTER_GET_DESC \ + SW_PARAM_DEF(SW_API_POLICER_GLOBAL_COUNTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_POLICER_GLOBAL_COUNTER_GET, SW_POLICER_GLOBAL_COUNTER, sizeof(fal_policer_global_counter_t), SW_PARAM_PTR|SW_PARAM_OUT, "Global Statistics"), + +#define SW_API_PORT_SHAPER_TIMESLOT_SET_DESC \ + SW_PARAM_DEF(SW_API_PORT_SHAPER_TIMESLOT_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PORT_SHAPER_TIMESLOT_SET, SW_UINT32, 4, SW_PARAM_IN, "Time Slot"), + +#define SW_API_PORT_SHAPER_TIMESLOT_GET_DESC \ + SW_PARAM_DEF(SW_API_PORT_SHAPER_TIMESLOT_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PORT_SHAPER_TIMESLOT_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Time Slot"), + +#define SW_API_FLOW_SHAPER_TIMESLOT_SET_DESC \ + SW_PARAM_DEF(SW_API_FLOW_SHAPER_TIMESLOT_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_SHAPER_TIMESLOT_SET, SW_UINT32, 4, SW_PARAM_IN, "Time Slot"), + +#define SW_API_FLOW_SHAPER_TIMESLOT_GET_DESC \ + SW_PARAM_DEF(SW_API_FLOW_SHAPER_TIMESLOT_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_SHAPER_TIMESLOT_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Time Slot"), + +#define SW_API_QUEUE_SHAPER_TIMESLOT_SET_DESC \ + SW_PARAM_DEF(SW_API_QUEUE_SHAPER_TIMESLOT_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_QUEUE_SHAPER_TIMESLOT_SET, SW_UINT32, 4, SW_PARAM_IN, "Time Slot"), + +#define SW_API_QUEUE_SHAPER_TIMESLOT_GET_DESC \ + SW_PARAM_DEF(SW_API_QUEUE_SHAPER_TIMESLOT_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_QUEUE_SHAPER_TIMESLOT_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "Time Slot"), + +#define SW_API_PORT_SHAPER_TOKEN_NUMBER_SET_DESC \ + SW_PARAM_DEF(SW_API_PORT_SHAPER_TOKEN_NUMBER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PORT_SHAPER_TOKEN_NUMBER_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PORT_SHAPER_TOKEN_NUMBER_SET, SW_PORT_SHAPER_TOKEN_CONFIG, sizeof(fal_shaper_token_number_t), SW_PARAM_PTR|SW_PARAM_IN, "CONFIG"), + +#define SW_API_PORT_SHAPER_TOKEN_NUMBER_GET_DESC \ + SW_PARAM_DEF(SW_API_PORT_SHAPER_TOKEN_NUMBER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PORT_SHAPER_TOKEN_NUMBER_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PORT_SHAPER_TOKEN_NUMBER_GET, SW_PORT_SHAPER_TOKEN_CONFIG, sizeof(fal_shaper_token_number_t), SW_PARAM_PTR|SW_PARAM_OUT, "CONFIG"), + +#define SW_API_FLOW_SHAPER_TOKEN_NUMBER_SET_DESC \ + SW_PARAM_DEF(SW_API_FLOW_SHAPER_TOKEN_NUMBER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_SHAPER_TOKEN_NUMBER_SET, SW_UINT32, 4, SW_PARAM_IN, "Flow ID"), \ + SW_PARAM_DEF(SW_API_FLOW_SHAPER_TOKEN_NUMBER_SET, SW_SHAPER_TOKEN_CONFIG, sizeof(fal_shaper_token_number_t), SW_PARAM_PTR|SW_PARAM_IN, "CONFIG"), + +#define SW_API_FLOW_SHAPER_TOKEN_NUMBER_GET_DESC \ + SW_PARAM_DEF(SW_API_FLOW_SHAPER_TOKEN_NUMBER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_SHAPER_TOKEN_NUMBER_GET, SW_UINT32, 4, SW_PARAM_IN, "Flow ID"), \ + SW_PARAM_DEF(SW_API_FLOW_SHAPER_TOKEN_NUMBER_GET, SW_SHAPER_TOKEN_CONFIG, sizeof(fal_shaper_token_number_t), SW_PARAM_PTR|SW_PARAM_OUT, "CONFIG"), + +#define SW_API_QUEUE_SHAPER_TOKEN_NUMBER_SET_DESC \ + SW_PARAM_DEF(SW_API_QUEUE_SHAPER_TOKEN_NUMBER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_QUEUE_SHAPER_TOKEN_NUMBER_SET, SW_UINT32, 4, SW_PARAM_IN, "Queue ID"), \ + SW_PARAM_DEF(SW_API_QUEUE_SHAPER_TOKEN_NUMBER_SET, SW_SHAPER_TOKEN_CONFIG, sizeof(fal_shaper_token_number_t), SW_PARAM_PTR|SW_PARAM_IN, "CONFIG"), + +#define SW_API_QUEUE_SHAPER_TOKEN_NUMBER_GET_DESC \ + SW_PARAM_DEF(SW_API_QUEUE_SHAPER_TOKEN_NUMBER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_QUEUE_SHAPER_TOKEN_NUMBER_GET, SW_UINT32, 4, SW_PARAM_IN, "Queue ID"), \ + SW_PARAM_DEF(SW_API_QUEUE_SHAPER_TOKEN_NUMBER_GET, SW_SHAPER_TOKEN_CONFIG, sizeof(fal_shaper_token_number_t), SW_PARAM_PTR|SW_PARAM_OUT, "CONFIG"), + +#define SW_API_PORT_SHAPER_SET_DESC \ + SW_PARAM_DEF(SW_API_PORT_SHAPER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PORT_SHAPER_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PORT_SHAPER_SET, SW_PORT_SHAPER_CONFIG, sizeof(fal_shaper_config_t), SW_PARAM_PTR|SW_PARAM_IN, "CONFIG"), + +#define SW_API_PORT_SHAPER_GET_DESC \ + SW_PARAM_DEF(SW_API_PORT_SHAPER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PORT_SHAPER_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PORT_SHAPER_GET, SW_PORT_SHAPER_CONFIG, sizeof(fal_shaper_config_t), SW_PARAM_PTR|SW_PARAM_OUT, "CONFIG"), + +#define SW_API_FLOW_SHAPER_SET_DESC \ + SW_PARAM_DEF(SW_API_FLOW_SHAPER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_SHAPER_SET, SW_UINT32, 4, SW_PARAM_IN, "Flow ID"), \ + SW_PARAM_DEF(SW_API_FLOW_SHAPER_SET, SW_SHAPER_CONFIG, sizeof(fal_shaper_config_t), SW_PARAM_PTR|SW_PARAM_IN, "CONFIG"), + +#define SW_API_FLOW_SHAPER_GET_DESC \ + SW_PARAM_DEF(SW_API_FLOW_SHAPER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_FLOW_SHAPER_GET, SW_UINT32, 4, SW_PARAM_IN, "Flow ID"), \ + SW_PARAM_DEF(SW_API_FLOW_SHAPER_GET, SW_SHAPER_CONFIG, sizeof(fal_shaper_config_t), SW_PARAM_PTR|SW_PARAM_OUT, "CONFIG"), + +#define SW_API_QUEUE_SHAPER_SET_DESC \ + SW_PARAM_DEF(SW_API_QUEUE_SHAPER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_QUEUE_SHAPER_SET, SW_UINT32, 4, SW_PARAM_IN, "Queue ID"), \ + SW_PARAM_DEF(SW_API_QUEUE_SHAPER_SET, SW_SHAPER_CONFIG, sizeof(fal_shaper_config_t), SW_PARAM_PTR|SW_PARAM_IN, "CONFIG"), + +#define SW_API_QUEUE_SHAPER_GET_DESC \ + SW_PARAM_DEF(SW_API_QUEUE_SHAPER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_QUEUE_SHAPER_GET, SW_UINT32, 4, SW_PARAM_IN, "Queue ID"), \ + SW_PARAM_DEF(SW_API_QUEUE_SHAPER_GET, SW_SHAPER_CONFIG, sizeof(fal_shaper_config_t), SW_PARAM_PTR|SW_PARAM_OUT, "CONFIG"), + +#define SW_API_SHAPER_IPG_PRE_SET_DESC \ + SW_PARAM_DEF(SW_API_SHAPER_IPG_PRE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SHAPER_IPG_PRE_SET, SW_UINT32, 4, SW_PARAM_IN, "IPG and Preamble"), + +#define SW_API_SHAPER_IPG_PRE_GET_DESC \ + SW_PARAM_DEF(SW_API_SHAPER_IPG_PRE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SHAPER_IPG_PRE_GET, SW_UINT32, 4, SW_PARAM_PTR|SW_PARAM_OUT, "IPG and Preamble"), + +#define SW_API_BM_CTRL_SET_DESC \ + SW_PARAM_DEF(SW_API_BM_CTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_BM_CTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "port id"), \ + SW_PARAM_DEF(SW_API_BM_CTRL_SET, SW_ENABLE, 4, SW_PARAM_IN, "bm ctrl"), + +#define SW_API_BM_CTRL_GET_DESC \ + SW_PARAM_DEF(SW_API_BM_CTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_BM_CTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "port id"), \ + SW_PARAM_DEF(SW_API_BM_CTRL_GET, SW_ENABLE, 4, SW_PARAM_PTR|SW_PARAM_OUT, "bm ctrl"), + +#define SW_API_BM_PORTGROUP_MAP_SET_DESC \ + SW_PARAM_DEF(SW_API_BM_PORTGROUP_MAP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_BM_PORTGROUP_MAP_SET, SW_UINT32, 4, SW_PARAM_IN, "port id"), \ + SW_PARAM_DEF(SW_API_BM_PORTGROUP_MAP_SET, SW_UINT8, 4, SW_PARAM_IN, "group"), + +#define SW_API_BM_PORTGROUP_MAP_GET_DESC \ + SW_PARAM_DEF(SW_API_BM_PORTGROUP_MAP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_BM_PORTGROUP_MAP_GET, SW_UINT32, 4, SW_PARAM_IN, "port id"), \ + SW_PARAM_DEF(SW_API_BM_PORTGROUP_MAP_GET, SW_UINT8, 4, \ + SW_PARAM_PTR|SW_PARAM_OUT, "group"), + +#define SW_API_BM_GROUP_BUFFER_SET_DESC \ + SW_PARAM_DEF(SW_API_BM_GROUP_BUFFER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_BM_GROUP_BUFFER_SET, SW_UINT8, 1, SW_PARAM_IN, "group id"), \ + SW_PARAM_DEF(SW_API_BM_GROUP_BUFFER_SET, SW_UINT16, 2, SW_PARAM_IN, "buff num"), + +#define SW_API_BM_GROUP_BUFFER_GET_DESC \ + SW_PARAM_DEF(SW_API_BM_GROUP_BUFFER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_BM_GROUP_BUFFER_GET, SW_UINT8, 1, SW_PARAM_IN, "group id"), \ + SW_PARAM_DEF(SW_API_BM_GROUP_BUFFER_GET, SW_UINT16, 2, \ + SW_PARAM_PTR|SW_PARAM_OUT, "buff num"), + +#define SW_API_BM_PORT_RSVBUFFER_SET_DESC \ + SW_PARAM_DEF(SW_API_BM_PORT_RSVBUFFER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_BM_PORT_RSVBUFFER_SET, SW_UINT32, 4, SW_PARAM_IN, "port id"), \ + SW_PARAM_DEF(SW_API_BM_PORT_RSVBUFFER_SET, SW_UINT16, 2, SW_PARAM_IN, "prealloc buff"), \ + SW_PARAM_DEF(SW_API_BM_PORT_RSVBUFFER_SET, SW_UINT16, 2, SW_PARAM_IN, "react buff"), + +#define SW_API_BM_PORT_RSVBUFFER_GET_DESC \ + SW_PARAM_DEF(SW_API_BM_PORT_RSVBUFFER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_BM_PORT_RSVBUFFER_GET, SW_UINT32, 4, SW_PARAM_IN, "port id"), \ + SW_PARAM_DEF(SW_API_BM_PORT_RSVBUFFER_GET, SW_UINT16, 2, \ + SW_PARAM_PTR|SW_PARAM_OUT, "prealloc num"), \ + SW_PARAM_DEF(SW_API_BM_PORT_RSVBUFFER_GET, SW_UINT16, 2, \ + SW_PARAM_PTR|SW_PARAM_OUT, "react num"), + +#define SW_API_BM_STATIC_THRESH_SET_DESC \ + SW_PARAM_DEF(SW_API_BM_STATIC_THRESH_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_BM_STATIC_THRESH_SET, SW_UINT32, 4, SW_PARAM_IN, "port id"), \ + SW_PARAM_DEF(SW_API_BM_STATIC_THRESH_SET, SW_BMSTHRESH, sizeof(fal_bm_static_cfg_t), \ + SW_PARAM_PTR|SW_PARAM_IN, \ + "static thresh"), + +#define SW_API_BM_STATIC_THRESH_GET_DESC \ + SW_PARAM_DEF(SW_API_BM_STATIC_THRESH_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_BM_STATIC_THRESH_GET, SW_UINT32, 4, SW_PARAM_IN, "port id"), \ + SW_PARAM_DEF(SW_API_BM_STATIC_THRESH_GET, SW_BMSTHRESH, \ + sizeof(fal_bm_static_cfg_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "static thresh"), + +#define SW_API_BM_DYNAMIC_THRESH_SET_DESC \ + SW_PARAM_DEF(SW_API_BM_DYNAMIC_THRESH_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_BM_DYNAMIC_THRESH_SET, SW_UINT32, 4, SW_PARAM_IN, "port id"), \ + SW_PARAM_DEF(SW_API_BM_DYNAMIC_THRESH_SET, SW_BMDTHRESH, \ + sizeof(fal_bm_dynamic_cfg_t), SW_PARAM_PTR|SW_PARAM_IN, \ + "dynamic thresh"), + +#define SW_API_BM_DYNAMIC_THRESH_GET_DESC \ + SW_PARAM_DEF(SW_API_BM_DYNAMIC_THRESH_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_BM_DYNAMIC_THRESH_GET, SW_UINT32, 4, SW_PARAM_IN, "port id"), \ + SW_PARAM_DEF(SW_API_BM_DYNAMIC_THRESH_GET, SW_BMDTHRESH, \ + sizeof(fal_bm_dynamic_cfg_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "dynamic thresh"), + +#define SW_API_BM_PORT_COUNTER_GET_DESC \ + SW_PARAM_DEF(SW_API_BM_PORT_COUNTER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_BM_PORT_COUNTER_GET, SW_UINT32, 4, SW_PARAM_IN, "port id"), \ + SW_PARAM_DEF(SW_API_BM_PORT_COUNTER_GET, SW_BMPORTCNT, \ + sizeof(fal_bm_port_counter_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "port counter"), + + +#define SW_API_PTP_CONFIG_SET_DESC \ + SW_PARAM_DEF(SW_API_PTP_CONFIG_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_CONFIG_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_CONFIG_SET, SW_PTP_CONFIG, \ + sizeof(fal_ptp_config_t), SW_PARAM_PTR|SW_PARAM_IN, "CONFIG"), + +#define SW_API_PTP_CONFIG_GET_DESC \ + SW_PARAM_DEF(SW_API_PTP_CONFIG_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_CONFIG_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_CONFIG_GET, SW_PTP_CONFIG, \ + sizeof(fal_ptp_config_t), SW_PARAM_PTR|SW_PARAM_OUT, "CONFIG"), + +#define SW_API_PTP_REFERENCE_CLOCK_SET_DESC \ + SW_PARAM_DEF(SW_API_PTP_REFERENCE_CLOCK_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_REFERENCE_CLOCK_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_REFERENCE_CLOCK_SET, SW_PTP_REFERENCE_CLOCK, \ + sizeof(fal_ptp_reference_clock_t), SW_PARAM_IN, "Ref Clock"), + +#define SW_API_PTP_REFERENCE_CLOCK_GET_DESC \ + SW_PARAM_DEF(SW_API_PTP_REFERENCE_CLOCK_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_REFERENCE_CLOCK_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_REFERENCE_CLOCK_GET, SW_PTP_REFERENCE_CLOCK, \ + sizeof(fal_ptp_reference_clock_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "Ref Clock"), + +#define SW_API_PTP_RX_TIMESTAMP_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_PTP_RX_TIMESTAMP_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_RX_TIMESTAMP_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_RX_TIMESTAMP_MODE_SET, SW_PTP_RX_TIMESTAMP_MODE, \ + sizeof(fal_ptp_rx_timestamp_mode_t), SW_PARAM_IN, "Timestamp Mode"), + +#define SW_API_PTP_RX_TIMESTAMP_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_PTP_RX_TIMESTAMP_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_RX_TIMESTAMP_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_RX_TIMESTAMP_MODE_GET, SW_PTP_RX_TIMESTAMP_MODE, \ + sizeof(fal_ptp_rx_timestamp_mode_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "Timestamp Mode"), + +#define SW_API_PTP_TIMESTAMP_GET_DESC \ + SW_PARAM_DEF(SW_API_PTP_TIMESTAMP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_TIMESTAMP_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_TIMESTAMP_GET, SW_PTP_DIRECTION, \ + sizeof(fal_ptp_direction_t), SW_PARAM_IN, "Direction"), \ + SW_PARAM_DEF(SW_API_PTP_TIMESTAMP_GET, SW_PTP_PKT_INFO, \ + sizeof(fal_ptp_pkt_info_t), SW_PARAM_PTR|SW_PARAM_IN, "Pkt Info"), \ + SW_PARAM_DEF(SW_API_PTP_TIMESTAMP_GET, SW_PTP_TIME, \ + sizeof(fal_ptp_time_t), SW_PARAM_PTR|SW_PARAM_OUT, "Time"), + +#define SW_API_PTP_PKT_TIMESTAMP_SET_DESC \ + SW_PARAM_DEF(SW_API_PTP_PKT_TIMESTAMP_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_PKT_TIMESTAMP_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_PKT_TIMESTAMP_SET, SW_PTP_TIME, \ + sizeof(fal_ptp_time_t), SW_PARAM_PTR|SW_PARAM_IN, "Time"), + +#define SW_API_PTP_PKT_TIMESTAMP_GET_DESC \ + SW_PARAM_DEF(SW_API_PTP_PKT_TIMESTAMP_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_PKT_TIMESTAMP_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_PKT_TIMESTAMP_GET, SW_PTP_TIME, \ + sizeof(fal_ptp_time_t), SW_PARAM_PTR|SW_PARAM_OUT, "Time"), + +#define SW_API_PTP_GRANDMASTER_MODE_SET_DESC \ + SW_PARAM_DEF(SW_API_PTP_GRANDMASTER_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_GRANDMASTER_MODE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_GRANDMASTER_MODE_SET, SW_PTP_GRANDMASTER_MODE, \ + sizeof(fal_ptp_grandmaster_mode_t), SW_PARAM_PTR|SW_PARAM_IN, \ + "Grandmaster Mode"), + +#define SW_API_PTP_GRANDMASTER_MODE_GET_DESC \ + SW_PARAM_DEF(SW_API_PTP_GRANDMASTER_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_GRANDMASTER_MODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_GRANDMASTER_MODE_GET, SW_PTP_GRANDMASTER_MODE, \ + sizeof(fal_ptp_grandmaster_mode_t), SW_PARAM_PTR|SW_PARAM_OUT, \ + "Grandmaster Mode"), + +#define SW_API_PTP_RTC_TIME_SET_DESC \ + SW_PARAM_DEF(SW_API_PTP_RTC_TIME_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_RTC_TIME_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_RTC_TIME_SET, SW_PTP_TIME, \ + sizeof(fal_ptp_time_t), SW_PARAM_PTR|SW_PARAM_IN, "Time"), + +#define SW_API_PTP_RTC_TIME_GET_DESC \ + SW_PARAM_DEF(SW_API_PTP_RTC_TIME_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_RTC_TIME_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_RTC_TIME_GET, SW_PTP_TIME, \ + sizeof(fal_ptp_time_t), SW_PARAM_PTR|SW_PARAM_OUT, "Time"), + +#define SW_API_PTP_RTC_TIME_CLEAR_DESC \ + SW_PARAM_DEF(SW_API_PTP_RTC_TIME_CLEAR, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_RTC_TIME_CLEAR, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), + +#define SW_API_PTP_RTC_ADJTIME_SET_DESC \ + SW_PARAM_DEF(SW_API_PTP_RTC_ADJTIME_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_RTC_ADJTIME_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_RTC_ADJTIME_SET, SW_PTP_TIME, \ + sizeof(fal_ptp_time_t), SW_PARAM_PTR|SW_PARAM_IN, "Time"), + +#define SW_API_PTP_RTC_ADJFREQ_SET_DESC \ + SW_PARAM_DEF(SW_API_PTP_RTC_ADJFREQ_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_RTC_ADJFREQ_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_RTC_ADJFREQ_SET, SW_PTP_TIME, \ + sizeof(fal_ptp_time_t), SW_PARAM_PTR|SW_PARAM_IN, "Time"), + +#define SW_API_PTP_RTC_ADJFREQ_GET_DESC \ + SW_PARAM_DEF(SW_API_PTP_RTC_ADJFREQ_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_RTC_ADJFREQ_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_RTC_ADJFREQ_GET, SW_PTP_TIME, \ + sizeof(fal_ptp_time_t), SW_PARAM_PTR|SW_PARAM_OUT, "Time"), + +#define SW_API_PTP_LINK_DELAY_SET_DESC \ + SW_PARAM_DEF(SW_API_PTP_LINK_DELAY_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_LINK_DELAY_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_LINK_DELAY_SET, SW_PTP_TIME, \ + sizeof(fal_ptp_time_t), SW_PARAM_PTR|SW_PARAM_IN, "Time"), + +#define SW_API_PTP_LINK_DELAY_GET_DESC \ + SW_PARAM_DEF(SW_API_PTP_LINK_DELAY_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_LINK_DELAY_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_LINK_DELAY_GET, SW_PTP_TIME, \ + sizeof(fal_ptp_time_t), SW_PARAM_PTR|SW_PARAM_OUT, "Time"), + +#define SW_API_PTP_SECURITY_SET_DESC \ + SW_PARAM_DEF(SW_API_PTP_SECURITY_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_SECURITY_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_SECURITY_SET, SW_PTP_SECURITY, \ + sizeof(fal_ptp_security_t), SW_PARAM_PTR|SW_PARAM_IN, "Security"), + +#define SW_API_PTP_SECURITY_GET_DESC \ + SW_PARAM_DEF(SW_API_PTP_SECURITY_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_SECURITY_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_SECURITY_GET, SW_PTP_SECURITY, \ + sizeof(fal_ptp_security_t), SW_PARAM_PTR|SW_PARAM_OUT, "Security"), + +#define SW_API_PTP_PPS_SIGNAL_CONTROL_SET_DESC \ + SW_PARAM_DEF(SW_API_PTP_PPS_SIGNAL_CONTROL_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_PPS_SIGNAL_CONTROL_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_PPS_SIGNAL_CONTROL_SET, SW_PTP_PPS_SIGNAL_CONTROL, \ + sizeof(fal_ptp_pps_signal_control_t), SW_PARAM_PTR|SW_PARAM_IN, "Sig Ctrl"), + +#define SW_API_PTP_PPS_SIGNAL_CONTROL_GET_DESC \ + SW_PARAM_DEF(SW_API_PTP_PPS_SIGNAL_CONTROL_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_PPS_SIGNAL_CONTROL_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_PPS_SIGNAL_CONTROL_GET, SW_PTP_PPS_SIGNAL_CONTROL, \ + sizeof(fal_ptp_pps_signal_control_t), SW_PARAM_PTR|SW_PARAM_OUT, "Sig Ctrl"), + +#define SW_API_PTP_RX_CRC_RECALC_SET_DESC \ + SW_PARAM_DEF(SW_API_PTP_RX_CRC_RECALC_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_RX_CRC_RECALC_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_RX_CRC_RECALC_SET, SW_ENABLE, \ + sizeof(a_bool_t), SW_PARAM_IN, "Status"), + +#define SW_API_PTP_RX_CRC_RECALC_GET_DESC \ + SW_PARAM_DEF(SW_API_PTP_RX_CRC_RECALC_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_RX_CRC_RECALC_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_RX_CRC_RECALC_GET, SW_ENABLE, \ + sizeof(a_bool_t), SW_PARAM_PTR|SW_PARAM_OUT, "Status"), + +#define SW_API_PTP_ASYM_CORRECTION_SET_DESC \ + SW_PARAM_DEF(SW_API_PTP_ASYM_CORRECTION_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_ASYM_CORRECTION_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_ASYM_CORRECTION_SET, SW_PTP_ASYM_CORRECTION, \ + sizeof(fal_ptp_asym_correction_t), SW_PARAM_PTR|SW_PARAM_IN, "Asym CF"), + +#define SW_API_PTP_ASYM_CORRECTION_GET_DESC \ + SW_PARAM_DEF(SW_API_PTP_ASYM_CORRECTION_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_ASYM_CORRECTION_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_ASYM_CORRECTION_GET, SW_PTP_ASYM_CORRECTION, \ + sizeof(fal_ptp_asym_correction_t), SW_PARAM_PTR|SW_PARAM_OUT, "Asym CF"), + +#define SW_API_PTP_OUTPUT_WAVEFORM_SET_DESC \ + SW_PARAM_DEF(SW_API_PTP_OUTPUT_WAVEFORM_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_OUTPUT_WAVEFORM_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_OUTPUT_WAVEFORM_SET, SW_PTP_OUTPUT_WAVEFORM, \ + sizeof(fal_ptp_output_waveform_t), SW_PARAM_PTR|SW_PARAM_IN, "Waveform"), + +#define SW_API_PTP_OUTPUT_WAVEFORM_GET_DESC \ + SW_PARAM_DEF(SW_API_PTP_OUTPUT_WAVEFORM_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_OUTPUT_WAVEFORM_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_OUTPUT_WAVEFORM_GET, SW_PTP_OUTPUT_WAVEFORM, \ + sizeof(fal_ptp_output_waveform_t), SW_PARAM_PTR|SW_PARAM_OUT, "Waveform"), + +#define SW_API_PTP_RTC_TIME_SNAPSHOT_SET_DESC \ + SW_PARAM_DEF(SW_API_PTP_RTC_TIME_SNAPSHOT_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_RTC_TIME_SNAPSHOT_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_RTC_TIME_SNAPSHOT_SET, SW_ENABLE, \ + sizeof(a_bool_t), SW_PARAM_IN, "Status"), + +#define SW_API_PTP_RTC_TIME_SNAPSHOT_GET_DESC \ + SW_PARAM_DEF(SW_API_PTP_RTC_TIME_SNAPSHOT_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_RTC_TIME_SNAPSHOT_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_RTC_TIME_SNAPSHOT_GET, SW_ENABLE, \ + sizeof(a_bool_t), SW_PARAM_PTR|SW_PARAM_OUT, "Status"), + +#define SW_API_PTP_INCREMENT_SYNC_FROM_CLOCK_SET_DESC \ + SW_PARAM_DEF(SW_API_PTP_INCREMENT_SYNC_FROM_CLOCK_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_INCREMENT_SYNC_FROM_CLOCK_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_INCREMENT_SYNC_FROM_CLOCK_SET, SW_ENABLE, \ + sizeof(a_bool_t), SW_PARAM_IN, "Status"), + +#define SW_API_PTP_INCREMENT_SYNC_FROM_CLOCK_GET_DESC \ + SW_PARAM_DEF(SW_API_PTP_INCREMENT_SYNC_FROM_CLOCK_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_INCREMENT_SYNC_FROM_CLOCK_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_INCREMENT_SYNC_FROM_CLOCK_GET, SW_ENABLE, \ + sizeof(a_bool_t), SW_PARAM_PTR|SW_PARAM_OUT, "Status"), + +#define SW_API_PTP_TOD_UART_SET_DESC \ + SW_PARAM_DEF(SW_API_PTP_TOD_UART_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_TOD_UART_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_TOD_UART_SET, SW_PTP_TOD_UART, \ + sizeof(fal_ptp_tod_uart_t), SW_PARAM_PTR|SW_PARAM_IN, "TOD UART"), + +#define SW_API_PTP_TOD_UART_GET_DESC \ + SW_PARAM_DEF(SW_API_PTP_TOD_UART_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_TOD_UART_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_TOD_UART_GET, SW_PTP_TOD_UART, \ + sizeof(fal_ptp_tod_uart_t), SW_PARAM_PTR|SW_PARAM_OUT, "TOD UART"), + +#define SW_API_PTP_ENHANCED_TIMESTAMP_ENGINE_SET_DESC \ + SW_PARAM_DEF(SW_API_PTP_ENHANCED_TIMESTAMP_ENGINE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_ENHANCED_TIMESTAMP_ENGINE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_ENHANCED_TIMESTAMP_ENGINE_SET, SW_PTP_DIRECTION, \ + sizeof(fal_ptp_direction_t), SW_PARAM_IN, "Direction"), \ + SW_PARAM_DEF(SW_API_PTP_ENHANCED_TIMESTAMP_ENGINE_SET, SW_PTP_ENHANCED_TS_ENGINE, \ + sizeof(fal_ptp_enhanced_ts_engine_t), SW_PARAM_PTR|SW_PARAM_IN, "TS Engine"), + +#define SW_API_PTP_ENHANCED_TIMESTAMP_ENGINE_GET_DESC \ + SW_PARAM_DEF(SW_API_PTP_ENHANCED_TIMESTAMP_ENGINE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_ENHANCED_TIMESTAMP_ENGINE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_ENHANCED_TIMESTAMP_ENGINE_GET, \ + SW_PTP_DIRECTION, sizeof(fal_ptp_direction_t), SW_PARAM_IN, "Direction"), \ + SW_PARAM_DEF(SW_API_PTP_ENHANCED_TIMESTAMP_ENGINE_GET, SW_PTP_ENHANCED_TS_ENGINE, \ + sizeof(fal_ptp_enhanced_ts_engine_t), SW_PARAM_PTR|SW_PARAM_OUT, "TS Engine"), + +#define SW_API_PTP_TRIGGER_SET_DESC \ + SW_PARAM_DEF(SW_API_PTP_TRIGGER_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_TRIGGER_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_TRIGGER_SET, SW_UINT32, 4, SW_PARAM_IN, "Trigger ID"), \ + SW_PARAM_DEF(SW_API_PTP_TRIGGER_SET, SW_PTP_TRIGGER, \ + sizeof(fal_ptp_trigger_t), SW_PARAM_PTR|SW_PARAM_IN, "Trigger"), + +#define SW_API_PTP_TRIGGER_GET_DESC \ + SW_PARAM_DEF(SW_API_PTP_TRIGGER_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_TRIGGER_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_TRIGGER_GET, SW_UINT32, 4, SW_PARAM_IN, "Trigger ID"), \ + SW_PARAM_DEF(SW_API_PTP_TRIGGER_GET, SW_PTP_TRIGGER, \ + sizeof(fal_ptp_trigger_t), SW_PARAM_PTR|SW_PARAM_OUT, "Trigger"), + +#define SW_API_PTP_CAPTURE_SET_DESC \ + SW_PARAM_DEF(SW_API_PTP_CAPTURE_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_CAPTURE_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_CAPTURE_SET, SW_UINT32, 4, SW_PARAM_IN, "Capture ID"), \ + SW_PARAM_DEF(SW_API_PTP_CAPTURE_SET, SW_PTP_CAPTURE, \ + sizeof(fal_ptp_capture_t), SW_PARAM_PTR|SW_PARAM_IN, "Capture"), + +#define SW_API_PTP_CAPTURE_GET_DESC \ + SW_PARAM_DEF(SW_API_PTP_CAPTURE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_CAPTURE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_CAPTURE_GET, SW_UINT32, 4, SW_PARAM_IN, "Capture ID"), \ + SW_PARAM_DEF(SW_API_PTP_CAPTURE_GET, SW_PTP_CAPTURE, \ + sizeof(fal_ptp_capture_t), SW_PARAM_PTR|SW_PARAM_OUT, "Capture"), + +#define SW_API_PTP_INTERRUPT_SET_DESC \ + SW_PARAM_DEF(SW_API_PTP_INTERRUPT_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_INTERRUPT_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_INTERRUPT_SET, SW_PTP_INTERRUPT, \ + sizeof(fal_ptp_interrupt_t), SW_PARAM_PTR|SW_PARAM_IN, "Interrupt"), + +#define SW_API_PTP_INTERRUPT_GET_DESC \ + SW_PARAM_DEF(SW_API_PTP_INTERRUPT_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_PTP_INTERRUPT_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_PTP_INTERRUPT_GET, SW_PTP_INTERRUPT, \ + sizeof(fal_ptp_interrupt_t), SW_PARAM_PTR|SW_PARAM_OUT, "Interrupt"), + +#define SW_API_SFP_DATA_GET_DESC \ + SW_PARAM_DEF(SW_API_SFP_DATA_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_SFP_DATA_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_SFP_DATA_GET, SW_SFP_DATA, \ + sizeof(fal_sfp_data_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Data"), + +#define SW_API_SFP_DATA_SET_DESC \ + SW_PARAM_DEF(SW_API_SFP_DATA_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"),\ + SW_PARAM_DEF(SW_API_SFP_DATA_SET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_SFP_DATA_SET, SW_SFP_DATA, \ + sizeof(fal_sfp_data_t), SW_PARAM_PTR|SW_PARAM_IN|SW_PARAM_OUT, "Data"), + +#define SW_API_SFP_DEV_TYPE_GET_DESC \ + SW_PARAM_DEF(SW_API_SFP_DEV_TYPE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SFP_DEV_TYPE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_SFP_DEV_TYPE_GET, SW_SFP_DEV_TYPE, \ + sizeof(fal_sfp_dev_type_t), SW_PARAM_PTR|SW_PARAM_OUT, "Device Type"), + +#define SW_API_SFP_TRANSC_CODE_GET_DESC \ + SW_PARAM_DEF(SW_API_SFP_TRANSC_CODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SFP_TRANSC_CODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_SFP_TRANSC_CODE_GET, SW_SFP_TRANSC_CODE, \ + sizeof(fal_sfp_transc_code_t), SW_PARAM_PTR|SW_PARAM_OUT, "Transceiver Code"), + +#define SW_API_SFP_RATE_ENCODE_GET_DESC \ + SW_PARAM_DEF(SW_API_SFP_RATE_ENCODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SFP_RATE_ENCODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_SFP_RATE_ENCODE_GET, SW_SFP_RATE_ENCODE, \ + sizeof(fal_sfp_rate_encode_t), SW_PARAM_PTR|SW_PARAM_OUT, "Rate Encode"), + +#define SW_API_SFP_LINK_LENGTH_GET_DESC \ + SW_PARAM_DEF(SW_API_SFP_LINK_LENGTH_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SFP_LINK_LENGTH_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_SFP_LINK_LENGTH_GET, SW_SFP_LINK_LENGTH, \ + sizeof(fal_sfp_link_length_t), SW_PARAM_PTR|SW_PARAM_OUT, "Link Length"), + +#define SW_API_SFP_VENDOR_INFO_GET_DESC \ + SW_PARAM_DEF(SW_API_SFP_VENDOR_INFO_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SFP_VENDOR_INFO_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_SFP_VENDOR_INFO_GET, SW_SFP_VENDOR_INFO, \ + sizeof(fal_sfp_vendor_info_t), SW_PARAM_PTR|SW_PARAM_OUT, "Vendor Info"), + +#define SW_API_SFP_LASER_WAVELENGTH_GET_DESC \ + SW_PARAM_DEF(SW_API_SFP_LASER_WAVELENGTH_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SFP_LASER_WAVELENGTH_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_SFP_LASER_WAVELENGTH_GET, SW_SFP_LASER_WAVELENGTH, \ + sizeof(fal_sfp_laser_wavelength_t), SW_PARAM_PTR|SW_PARAM_OUT, "Wave Length"), + +#define SW_API_SFP_OPTION_GET_DESC \ + SW_PARAM_DEF(SW_API_SFP_OPTION_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SFP_OPTION_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_SFP_OPTION_GET, SW_SFP_OPTION, \ + sizeof(fal_sfp_option_t), SW_PARAM_PTR|SW_PARAM_OUT, "Option"), + +#define SW_API_SFP_CTRL_RATE_GET_DESC \ + SW_PARAM_DEF(SW_API_SFP_CTRL_RATE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SFP_CTRL_RATE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_SFP_CTRL_RATE_GET, SW_SFP_CTRL_RATE, \ + sizeof(fal_sfp_rate_t), SW_PARAM_PTR|SW_PARAM_OUT, "Control Rate"), + +#define SW_API_SFP_ENHANCED_CFG_GET_DESC \ + SW_PARAM_DEF(SW_API_SFP_ENHANCED_CFG_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SFP_ENHANCED_CFG_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_SFP_ENHANCED_CFG_GET, SW_SFP_ENHANCED_CFG, \ + sizeof(fal_sfp_enhanced_cfg_t), SW_PARAM_PTR|SW_PARAM_OUT, "Enhanced Config"), + +#define SW_API_SFP_DIAG_THRESHOLD_GET_DESC \ + SW_PARAM_DEF(SW_API_SFP_DIAG_THRESHOLD_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SFP_DIAG_THRESHOLD_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_SFP_DIAG_THRESHOLD_GET, SW_SFP_DIAG_THRESHOLD, \ + sizeof(fal_sfp_internal_threshold_t), SW_PARAM_PTR|SW_PARAM_OUT, "Threshold"), + +#define SW_API_SFP_DIAG_CAL_CONST_GET_DESC \ + SW_PARAM_DEF(SW_API_SFP_DIAG_CAL_CONST_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SFP_DIAG_CAL_CONST_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_SFP_DIAG_CAL_CONST_GET, SW_SFP_DIAG_CAL_CONST, \ + sizeof(fal_sfp_cal_const_t), SW_PARAM_PTR|SW_PARAM_OUT, "Calibration"), + +#define SW_API_SFP_DIAG_REALTIME_GET_DESC \ + SW_PARAM_DEF(SW_API_SFP_DIAG_REALTIME_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SFP_DIAG_REALTIME_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_SFP_DIAG_REALTIME_GET, SW_SFP_DIAG_REALTIME, \ + sizeof(fal_sfp_realtime_diag_t), SW_PARAM_PTR|SW_PARAM_OUT, "Realtime Diag"), + +#define SW_API_SFP_DIAG_CTRL_STATUS_GET_DESC \ + SW_PARAM_DEF(SW_API_SFP_DIAG_CTRL_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SFP_DIAG_CTRL_STATUS_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_SFP_DIAG_CTRL_STATUS_GET, SW_SFP_CTRL_STATUS, \ + sizeof(fal_sfp_ctrl_status_t), SW_PARAM_PTR|SW_PARAM_OUT, "Control Status"), + +#define SW_API_SFP_DIAG_ALARM_WARN_FLAG_GET_DESC \ + SW_PARAM_DEF(SW_API_SFP_DIAG_ALARM_WARN_FLAG_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SFP_DIAG_ALARM_WARN_FLAG_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_SFP_DIAG_ALARM_WARN_FLAG_GET, SW_SFP_ALARM_WARN_FLAG, \ + sizeof(fal_sfp_alarm_warn_flag_t), SW_PARAM_PTR|SW_PARAM_OUT, "A/W Flag"), + +#define SW_API_SFP_CHECKCODE_GET_DESC \ + SW_PARAM_DEF(SW_API_SFP_CHECKCODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SFP_CHECKCODE_GET, SW_UINT32, 4, SW_PARAM_IN, "Port ID"), \ + SW_PARAM_DEF(SW_API_SFP_CHECKCODE_GET, SW_SFP_CCODE_TYPE, \ + sizeof(fal_sfp_cc_type_t), SW_PARAM_IN, "Check Code Type"), \ + SW_PARAM_DEF(SW_API_SFP_CHECKCODE_GET, SW_UINT8, \ + sizeof(a_uint8_t), SW_PARAM_PTR|SW_PARAM_OUT, "Check Code"), + +/*qca808x_start*/ +#define SW_API_DESC(api_id) api_id##_DESC + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _API_DESC_H_ */ +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/api/sw_api.h b/feeds/ipq807x/qca-ssdk-shell/src/include/api/sw_api.h new file mode 100755 index 000000000..4717a6f03 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/api/sw_api.h @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#ifndef _SW_API_H +#define _SW_API_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" +#include "sw_ioctl.h" + +#define SW_MAX_API_BUF 2048 +#define SW_MAX_API_PARAM 12 /* cmd type + return value + ten parameters */ +#define SW_MAX_PAYLOAD (SW_MAX_API_PARAM << 2) /* maximum payload size for netlink msg*/ +#define SW_PARAM_IN 0x1 +#define SW_PARAM_OUT 0x2 +#define SW_PARAM_PTR 0x4 + +#define SW_API_DEF(ioctl, name) {ioctl, name} +#if (!defined(KERNEL_MODULE)) +#define SW_PARAM_DEF(ioctl, data, size, type, name) \ + {ioctl, size, data, type, name} +#else +#define SW_PARAM_DEF(ioctl, data, size, type, name) {ioctl, size, data, type} +#endif + +typedef enum +{ + SW_UINT8 = 1, + SW_INT8, + SW_UINT16, + SW_INT16, + SW_UINT32, + SW_INT32, + SW_UINT64, + SW_INT64, + SW_ENABLE, + SW_SPEED, + SW_DUPLEX, + SW_1QMODE, + SW_EGMODE, + SW_CAP, + SW_VLAN, + SW_LAN_WAN_CFG, + SW_PBMP, + SW_MIB, + SW_MIB_CNTR, + SW_XGMIB, + SW_MACADDR, + SW_FDBENTRY, + SW_MACLIMIT_CTRL, + SW_SCH, + SW_QOS, + SW_STORM, + SW_STP, + SW_LEAKY, + SW_MACCMD, + SW_FLOWTYPE, + SW_FLOWCMD, + SW_UINT_A, + SW_ACLRULE, + SW_LEDPATTERN, + SW_INVLAN, + SW_VLANPROPAGATION, + SW_VLANTRANSLATION, + SW_QINQMODE, + SW_QINQROLE, + SW_CABLESTATUS, + SW_CABLELEN, + SW_SSDK_CFG, + SW_HDRMODE, + SW_FDBOPRATION, + SW_PPPOE, + SW_PPPOE_LESS, + SW_ACL_UDF_TYPE, + SW_IP_HOSTENTRY, + SW_ARP_LEARNMODE, + SW_IP_GUARDMODE, + SW_NATENTRY, + SW_NAPTENTRY, + SW_FLOWENTRY, + SW_NAPTMODE, + SW_IP4ADDR, + SW_IP6ADDR, + SW_INTFMACENTRY, + SW_PUBADDRENTRY, + SW_INGPOLICER, + SW_EGSHAPER, + SW_ACLPOLICER, + SW_MACCONFIG, + SW_PHYCONFIG, + SW_DATA_MAX, + SW_FDBSMODE, + SW_FDB_CTRL_MODE, + SW_FX100CONFIG, + SW_SGENTRY, + SW_SEC_MAC, + SW_SEC_IP, + SW_SEC_IP4, + SW_SEC_IP6, + SW_SEC_TCP, + SW_SEC_UDP, + SW_SEC_ICMP4, + SW_SEC_ICMP6, + SW_REMARKENTRY, + SW_SGINFOENTRY, + SW_DEFAULT_ROUTE_ENTRY, + SW_HOST_ROUTE_ENTRY, + SW_IP_WCMP_ENTRY, + SW_IP_RFS_IP4, + SW_IP_RFS_IP6, + SW_FLOWCOOKIE, + SW_FDB_RFS, + SW_FLOWRFS, + SW_CROSSOVER_MODE, + SW_CROSSOVER_STATUS, + SW_PREFER_MEDIUM, + SW_FIBER_MODE, + SW_INTERFACE_MODE, + SW_COUNTER_INFO, + SW_REG_DUMP, + SW_DBG_REG_DUMP, + SW_VSI_NEWADDR_LRN, + SW_VSI_STAMOVE, + SW_VSI_MEMBER, + SW_VSI_COUNTER, + SW_MTU_INFO, + SW_MRU_INFO, + SW_MTU_ENTRY, + SW_MRU_ENTRY, + SW_ARP_SG_CFG, + SW_IP_NETWORK_ROUTE, + SW_IP_INTF, + SW_IP_VSI_INTF, + SW_IP_NEXTHOP, + SW_UCAST_QUEUE_MAP, + SW_UCAST_PRI_CLASS, + SW_MCAST_PRI_CLASS, + SW_IP_SG, + SW_IP_PUB, + SW_IP_PORTMAC, + SW_IP_MCMODE, + SW_FLOW_AGE, + SW_FLOW_CTRL, + SW_AC_CTRL, + SW_AC_OBJ, + SW_STATIC_THRESH, + SW_DYNAMIC_THRESH, + SW_GROUP_BUFFER, + SW_FLOW_ENTRY, + SW_FLOW_HOST, + SW_IP_GLOBAL, + SW_FLOW_GLOBAL, + SW_GLOBAL_QINQMODE, + SW_PT_QINQMODE, + SW_TPID, + SW_INGRESS_FILTER, + SW_PT_DEF_VID_EN, + SW_PT_VLAN_TAG, + SW_PT_VLAN_DIRECTION, + SW_PT_VLAN_TRANS_ADV_RULE, + SW_PT_VLAN_TRANS_ADV_ACTION, + SW_PT_VLAN_COUNTER, + SW_DEBUG_COUNTER_EN, + SW_TAG_PROPAGATION, + SW_EGRESS_DEFAULT_VID, + SW_EGRESS_MODE, + SW_CTRLPKT_PROFILE, + SW_SERVCODE_CONFIG, + SW_RSS_HASH_MODE, + SW_RSS_HASH_CONFIG, + SW_PTP_CONFIG, + SW_PTP_REFERENCE_CLOCK, + SW_PTP_RX_TIMESTAMP_MODE, + SW_PTP_DIRECTION, + SW_PTP_PKT_INFO, + SW_PTP_TIME, + SW_PTP_GRANDMASTER_MODE, + SW_PTP_SECURITY, + SW_PTP_PPS_SIGNAL_CONTROL, + SW_PTP_ASYM_CORRECTION, + SW_PTP_OUTPUT_WAVEFORM, + SW_PTP_TOD_UART, + SW_PTP_ENHANCED_TS_ENGINE, + SW_PTP_TRIGGER, + SW_PTP_CAPTURE, + SW_PTP_INTERRUPT, + SW_MIRR_ANALYSIS_CONFIG, + SW_MIRR_DIRECTION, + SW_L3_PARSER, + SW_L4_PARSER, + SW_EXP_CTRL, + SW_ACL_UDF_PKT_TYPE, + SW_PORTGROUP, + SW_PORTPRI, + SW_PORTREMARK, + SW_COSMAP, + SW_SCHEDULER, + SW_QUEUEBMP, + SW_PORT_SHAPER_TOKEN_CONFIG, + SW_SHAPER_TOKEN_CONFIG, + SW_PORT_SHAPER_CONFIG, + SW_SHAPER_CONFIG, + SW_BMSTHRESH, + SW_BMDTHRESH, + SW_BMPORTCNT, + SW_MODULE, + SW_FUNC_CTRL, + SW_QM_CNT, + SW_POLICER_COUNTER, + SW_POLICER_PORT_CONFIG, + SW_POLICER_ACL_CONFIG, + SW_POLICER_CMD_CONFIG, + SW_POLICER_GLOBAL_COUNTER, + SW_PHY_DUMP, + SW_RESOURCE_SCHE, + SW_PORT_EEE_CONFIG, + SW_SRC_FILTER_CONFIG, + SW_PORT_LOOPBACK_CONFIG, + SW_SFP_DATA, + SW_SFP_DEV_TYPE, + SW_SFP_TRANSC_CODE, + SW_SFP_RATE_ENCODE, + SW_SFP_LINK_LENGTH, + SW_SFP_VENDOR_INFO, + SW_SFP_LASER_WAVELENGTH, + SW_SFP_OPTION, + SW_SFP_CTRL_RATE, + SW_SFP_ENHANCED_CFG, + SW_SFP_DIAG_THRESHOLD, + SW_SFP_DIAG_CAL_CONST, + SW_SFP_DIAG_REALTIME, + SW_SFP_CTRL_STATUS, + SW_SFP_ALARM_WARN_FLAG, + SW_SFP_CCODE_TYPE, +} sw_data_type_e; + + typedef struct + { + a_uint32_t api_id; + void *func; + } sw_api_func_t; + + typedef struct + { + a_uint32_t api_id; + a_uint16_t data_size; + a_uint8_t data_type; + a_uint8_t param_type; +#if (!defined(KERNEL_MODULE)) + a_uint8_t param_name[30]; +#endif + } sw_api_param_t; + + typedef struct + { + a_uint32_t api_id; + sw_api_func_t *api_fp; + sw_api_param_t *api_pp; + a_uint32_t api_nr; + } sw_api_t; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SW_API_H */ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/api/sw_ioctl.h b/feeds/ipq807x/qca-ssdk-shell/src/include/api/sw_ioctl.h new file mode 100755 index 000000000..0f29504ac --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/api/sw_ioctl.h @@ -0,0 +1,981 @@ +/* + * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/*qca808x_start*/ +#ifndef _SW_IOCTL_H_ +#define _SW_IOCTL_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + /*init*/ +#define SW_API_INIT_OFFSET 10 +#define SW_API_SWITCH_INIT (0 + SW_API_INIT_OFFSET) +#define SW_API_SWITCH_RESET (1 + SW_API_INIT_OFFSET) +#define SW_API_SSDK_CFG (2 + SW_API_INIT_OFFSET) +#define SW_API_MODULE_FUNC_CTRL_SET (3 + SW_API_INIT_OFFSET) +#define SW_API_MODULE_FUNC_CTRL_GET (4 + SW_API_INIT_OFFSET) + + /*port ctrl*/ +#define SW_API_PORT_OFFSET 30 +#define SW_API_PT_DUPLEX_GET (0 + SW_API_PORT_OFFSET) +#define SW_API_PT_DUPLEX_SET (1 + SW_API_PORT_OFFSET) +#define SW_API_PT_SPEED_GET (2 + SW_API_PORT_OFFSET) +#define SW_API_PT_SPEED_SET (3 + SW_API_PORT_OFFSET) +#define SW_API_PT_AN_ADV_GET (4 + SW_API_PORT_OFFSET) +#define SW_API_PT_AN_ADV_SET (5 + SW_API_PORT_OFFSET) +#define SW_API_PT_AN_GET (6 + SW_API_PORT_OFFSET) +#define SW_API_PT_AN_ENABLE (7 + SW_API_PORT_OFFSET) +#define SW_API_PT_AN_RESTART (8 + SW_API_PORT_OFFSET) +/*qca808x_end*/ +#define SW_API_PT_HDR_SET (9 + SW_API_PORT_OFFSET) +#define SW_API_PT_HDR_GET (10 + SW_API_PORT_OFFSET) +#define SW_API_PT_FLOWCTRL_SET (11 + SW_API_PORT_OFFSET) +#define SW_API_PT_FLOWCTRL_GET (12 + SW_API_PORT_OFFSET) +#define SW_API_PT_FLOWCTRL_MODE_SET (13 + SW_API_PORT_OFFSET) +#define SW_API_PT_FLOWCTRL_MODE_GET (14 + SW_API_PORT_OFFSET) +#define SW_API_PT_POWERSAVE_SET (15 + SW_API_PORT_OFFSET) +#define SW_API_PT_POWERSAVE_GET (16 + SW_API_PORT_OFFSET) +/*qca808x_start*/ +#define SW_API_PT_HIBERNATE_SET (17 + SW_API_PORT_OFFSET) +#define SW_API_PT_HIBERNATE_GET (18 + SW_API_PORT_OFFSET) +#define SW_API_PT_CDT (19 + SW_API_PORT_OFFSET) +/*qca808x_end*/ +#define SW_API_PT_TXHDR_SET (20 + SW_API_PORT_OFFSET) +#define SW_API_PT_TXHDR_GET (21 + SW_API_PORT_OFFSET) +#define SW_API_PT_RXHDR_SET (22 + SW_API_PORT_OFFSET) +#define SW_API_PT_RXHDR_GET (23 + SW_API_PORT_OFFSET) +#define SW_API_HEADER_TYPE_SET (24 + SW_API_PORT_OFFSET) +#define SW_API_HEADER_TYPE_GET (25 + SW_API_PORT_OFFSET) +#define SW_API_TXMAC_STATUS_SET (26 + SW_API_PORT_OFFSET) +#define SW_API_TXMAC_STATUS_GET (27 + SW_API_PORT_OFFSET) +#define SW_API_RXMAC_STATUS_SET (28 + SW_API_PORT_OFFSET) +#define SW_API_RXMAC_STATUS_GET (29 + SW_API_PORT_OFFSET) +#define SW_API_TXFC_STATUS_SET (30 + SW_API_PORT_OFFSET) +#define SW_API_TXFC_STATUS_GET (31 + SW_API_PORT_OFFSET) +#define SW_API_RXFC_STATUS_SET (32 + SW_API_PORT_OFFSET) +#define SW_API_RXFC_STATUS_GET (33 + SW_API_PORT_OFFSET) +#define SW_API_BP_STATUS_SET (34 + SW_API_PORT_OFFSET) +#define SW_API_BP_STATUS_GET (35 + SW_API_PORT_OFFSET) +#define SW_API_PT_LINK_MODE_SET (36 + SW_API_PORT_OFFSET) +#define SW_API_PT_LINK_MODE_GET (37 + SW_API_PORT_OFFSET) +/*qca808x_start*/ +#define SW_API_PT_LINK_STATUS_GET (38 + SW_API_PORT_OFFSET) +/*qca808x_end*/ +#define SW_API_PT_MAC_LOOPBACK_SET (39+ SW_API_PORT_OFFSET) +#define SW_API_PT_MAC_LOOPBACK_GET (40+ SW_API_PORT_OFFSET) +#define SW_API_PTS_LINK_STATUS_GET (41 + SW_API_PORT_OFFSET) +#define SW_API_PT_CONGESTION_DROP_SET (42+ SW_API_PORT_OFFSET) +#define SW_API_PT_CONGESTION_DROP_GET (43+ SW_API_PORT_OFFSET) +#define SW_API_PT_RING_FLOW_CTRL_THRES_SET (44+ SW_API_PORT_OFFSET) +#define SW_API_PT_RING_FLOW_CTRL_THRES_GET (45+ SW_API_PORT_OFFSET) +/*qca808x_start*/ +#define SW_API_PT_8023AZ_SET (46 + SW_API_PORT_OFFSET) +#define SW_API_PT_8023AZ_GET (47 + SW_API_PORT_OFFSET) +#define SW_API_PT_MDIX_SET (48 + SW_API_PORT_OFFSET) +#define SW_API_PT_MDIX_GET (49 + SW_API_PORT_OFFSET) +#define SW_API_PT_MDIX_STATUS_GET (50 + SW_API_PORT_OFFSET) +/*qca808x_end*/ +#define SW_API_PT_COMBO_PREFER_MEDIUM_SET (51 + SW_API_PORT_OFFSET) +#define SW_API_PT_COMBO_PREFER_MEDIUM_GET (52 + SW_API_PORT_OFFSET) +#define SW_API_PT_COMBO_MEDIUM_STATUS_GET (53 + SW_API_PORT_OFFSET) +#define SW_API_PT_COMBO_FIBER_MODE_SET (54 + SW_API_PORT_OFFSET) +#define SW_API_PT_COMBO_FIBER_MODE_GET (55 + SW_API_PORT_OFFSET) +/*qca808x_start*/ +#define SW_API_PT_LOCAL_LOOPBACK_SET (56 + SW_API_PORT_OFFSET) +#define SW_API_PT_LOCAL_LOOPBACK_GET (57 + SW_API_PORT_OFFSET) +#define SW_API_PT_REMOTE_LOOPBACK_SET (58 + SW_API_PORT_OFFSET) +#define SW_API_PT_REMOTE_LOOPBACK_GET (59 + SW_API_PORT_OFFSET) +#define SW_API_PT_RESET (60 + SW_API_PORT_OFFSET) +#define SW_API_PT_POWER_OFF (61 + SW_API_PORT_OFFSET) +#define SW_API_PT_POWER_ON (62 + SW_API_PORT_OFFSET) +#define SW_API_PT_MAGIC_FRAME_MAC_SET (63 + SW_API_PORT_OFFSET) +#define SW_API_PT_MAGIC_FRAME_MAC_GET (64 + SW_API_PORT_OFFSET) +#define SW_API_PT_PHY_ID_GET (65 + SW_API_PORT_OFFSET) +#define SW_API_PT_WOL_STATUS_SET (66 + SW_API_PORT_OFFSET) +#define SW_API_PT_WOL_STATUS_GET (67 + SW_API_PORT_OFFSET) +/*qca808x_end*/ +#define SW_API_PT_INTERFACE_MODE_SET (68 + SW_API_PORT_OFFSET) +#define SW_API_PT_INTERFACE_MODE_GET (69 + SW_API_PORT_OFFSET) +/*qca808x_start*/ +#define SW_API_PT_INTERFACE_MODE_STATUS_GET (70 + SW_API_PORT_OFFSET) +#define SW_API_DEBUG_PHYCOUNTER_SET (71 + SW_API_PORT_OFFSET) +#define SW_API_DEBUG_PHYCOUNTER_GET (72 + SW_API_PORT_OFFSET) +#define SW_API_DEBUG_PHYCOUNTER_SHOW (73 + SW_API_PORT_OFFSET) +/*qca808x_end*/ +#define SW_API_PT_INTERFACE_MODE_APPLY (74 + SW_API_PORT_OFFSET) +#define SW_API_PT_INTERFACE_3AZ_STATUS_SET (75 + SW_API_PORT_OFFSET) +#define SW_API_PT_INTERFACE_3AZ_STATUS_GET (76 + SW_API_PORT_OFFSET) +#define SW_API_PT_PROMISC_MODE_SET (77 + SW_API_PORT_OFFSET) +#define SW_API_PT_PROMISC_MODE_GET (78 + SW_API_PORT_OFFSET) +#define SW_API_PT_INTERFACE_EEE_CFG_SET (79 + SW_API_PORT_OFFSET) +#define SW_API_PT_INTERFACE_EEE_CFG_GET (80 + SW_API_PORT_OFFSET) +#define SW_API_PT_SWITCH_PORT_LOOPBACK_SET (81 + SW_API_PORT_OFFSET) +#define SW_API_PT_SWITCH_PORT_LOOPBACK_GET (82 + SW_API_PORT_OFFSET) + + /*vlan*/ +#define SW_API_VLAN_OFFSET 130 +#define SW_API_VLAN_ADD (0 + SW_API_VLAN_OFFSET) +#define SW_API_VLAN_DEL (1 + SW_API_VLAN_OFFSET) +#define SW_API_VLAN_MEM_UPDATE (2 + SW_API_VLAN_OFFSET) +#define SW_API_VLAN_FIND (3 + SW_API_VLAN_OFFSET) +#define SW_API_VLAN_NEXT (4 + SW_API_VLAN_OFFSET) +#define SW_API_VLAN_APPEND (5 + SW_API_VLAN_OFFSET) +#define SW_API_VLAN_FLUSH (6 + SW_API_VLAN_OFFSET) +#define SW_API_VLAN_FID_SET (7 + SW_API_VLAN_OFFSET) +#define SW_API_VLAN_FID_GET (8 + SW_API_VLAN_OFFSET) +#define SW_API_VLAN_MEMBER_ADD (9 + SW_API_VLAN_OFFSET) +#define SW_API_VLAN_MEMBER_DEL (10 + SW_API_VLAN_OFFSET) +#define SW_API_VLAN_LEARN_STATE_SET (11 + SW_API_VLAN_OFFSET) +#define SW_API_VLAN_LEARN_STATE_GET (12 + SW_API_VLAN_OFFSET) +#define SW_API_LAN_WAN_CFG_SET (13 + SW_API_VLAN_OFFSET) +#define SW_API_LAN_WAN_CFG_GET (14 + SW_API_VLAN_OFFSET) + + /*port ctrl extend*/ +#define SW_API_PORT_EXT_OFFSET 160 +#define SW_API_PT_MTU_SET (0 + SW_API_PORT_EXT_OFFSET) +#define SW_API_PT_MTU_GET (1 + SW_API_PORT_EXT_OFFSET) +#define SW_API_PT_MRU_SET (2 + SW_API_PORT_EXT_OFFSET) +#define SW_API_PT_MRU_GET (3 + SW_API_PORT_EXT_OFFSET) +#define SW_API_PT_SOURCE_FILTER_GET (4 + SW_API_PORT_EXT_OFFSET) +#define SW_API_PT_SOURCE_FILTER_SET (5 + SW_API_PORT_EXT_OFFSET) +#define SW_API_PT_FRAME_MAX_SIZE_GET (6 + SW_API_PORT_EXT_OFFSET) +#define SW_API_PT_FRAME_MAX_SIZE_SET (7 + SW_API_PORT_EXT_OFFSET) +#define SW_API_PT_SOURCE_FILTER_CONFIG_GET (8 + SW_API_PORT_EXT_OFFSET) +#define SW_API_PT_SOURCE_FILTER_CONFIG_SET (9 + SW_API_PORT_EXT_OFFSET) + + /*portvlan*/ +#define SW_API_PORTVLAN_OFFSET 200 +#define SW_API_PT_ING_MODE_GET (0 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_ING_MODE_SET (1 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_EG_MODE_GET (2 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_EG_MODE_SET (3 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VLAN_MEM_ADD (4 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VLAN_MEM_DEL (5 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VLAN_MEM_UPDATE (6 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VLAN_MEM_GET (7 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_DEF_VID_GET (8 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_DEF_VID_SET (9 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_FORCE_DEF_VID_SET (10 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_FORCE_DEF_VID_GET (11 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_FORCE_PORTVLAN_SET (12 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_FORCE_PORTVLAN_GET (13 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_NESTVLAN_SET (14 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_NESTVLAN_GET (15 + SW_API_PORTVLAN_OFFSET) +#define SW_API_NESTVLAN_TPID_SET (16 + SW_API_PORTVLAN_OFFSET) +#define SW_API_NESTVLAN_TPID_GET (17 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_IN_VLAN_MODE_SET (18 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_IN_VLAN_MODE_GET (19 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_TLS_SET (20 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_TLS_GET (21 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_PRI_PROPAGATION_SET (22 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_PRI_PROPAGATION_GET (23 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_DEF_SVID_SET (24 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_DEF_SVID_GET (25 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_DEF_CVID_SET (26 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_DEF_CVID_GET (27 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VLAN_PROPAGATION_SET (28 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VLAN_PROPAGATION_GET (29 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VLAN_TRANS_ADD (30 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VLAN_TRANS_DEL (31 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VLAN_TRANS_GET (32 + SW_API_PORTVLAN_OFFSET) +#define SW_API_QINQ_MODE_SET (33 + SW_API_PORTVLAN_OFFSET) +#define SW_API_QINQ_MODE_GET (34 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_QINQ_ROLE_SET (35 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_QINQ_ROLE_GET (36 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VLAN_TRANS_ITERATE (37 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_MAC_VLAN_XLT_SET (38 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_MAC_VLAN_XLT_GET (39 + SW_API_PORTVLAN_OFFSET) +#define SW_API_NETISOLATE_SET (40 + SW_API_PORTVLAN_OFFSET) +#define SW_API_NETISOLATE_GET (41 + SW_API_PORTVLAN_OFFSET) +#define SW_API_EG_FLTR_BYPASS_EN_SET (42 + SW_API_PORTVLAN_OFFSET) +#define SW_API_EG_FLTR_BYPASS_EN_GET (43 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VRF_ID_SET (44 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VRF_ID_GET (45 + SW_API_PORTVLAN_OFFSET) +#define SW_API_GLOBAL_QINQ_MODE_SET (46 + SW_API_PORTVLAN_OFFSET) +#define SW_API_GLOBAL_QINQ_MODE_GET (47 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PORT_QINQ_MODE_SET (48 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PORT_QINQ_MODE_GET (49 + SW_API_PORTVLAN_OFFSET) +#define SW_API_TPID_SET (50 + SW_API_PORTVLAN_OFFSET) +#define SW_API_TPID_GET (51 + SW_API_PORTVLAN_OFFSET) +#define SW_API_EGRESS_TPID_SET (52 + SW_API_PORTVLAN_OFFSET) +#define SW_API_EGRESS_TPID_GET (53 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_INGRESS_VLAN_FILTER_SET (54 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_INGRESS_VLAN_FILTER_GET (55 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_DEFAULT_VLANTAG_SET (56 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_DEFAULT_VLANTAG_GET (57 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_TAG_PROPAGATION_SET (58 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_TAG_PROPAGATION_GET (59 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VLANTAG_EGMODE_SET (60 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VLANTAG_EGMODE_GET (61 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VLAN_XLT_MISS_CMD_SET (62 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VLAN_XLT_MISS_CMD_GET (63 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VSI_EGMODE_SET (64 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VSI_EGMODE_GET (65 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VLANTAG_VSI_EGMODE_EN_SET (66 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VLANTAG_VSI_EGMODE_EN_GET (67 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VLAN_TRANS_ADV_ADD (68 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VLAN_TRANS_ADV_DEL (69 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VLAN_TRANS_ADV_GETFIRST (70 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VLAN_TRANS_ADV_GETNEXT (71 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VLAN_COUNTER_GET (72 + SW_API_PORTVLAN_OFFSET) +#define SW_API_PT_VLAN_COUNTER_CLEANUP (73 + SW_API_PORTVLAN_OFFSET) + + + /*fdb*/ +#define SW_API_FDB_OFFSET 300 +#define SW_API_FDB_ADD (0 + SW_API_FDB_OFFSET) +#define SW_API_FDB_DELALL (1 + SW_API_FDB_OFFSET) +#define SW_API_FDB_DELPORT (2 + SW_API_FDB_OFFSET) +#define SW_API_FDB_DELMAC (3 + SW_API_FDB_OFFSET) +#define SW_API_FDB_FIRST (4 + SW_API_FDB_OFFSET) +#define SW_API_FDB_NEXT (5 + SW_API_FDB_OFFSET) +#define SW_API_FDB_FIND (6 + SW_API_FDB_OFFSET) +#define SW_API_FDB_PT_LEARN_SET (7 + SW_API_FDB_OFFSET) +#define SW_API_FDB_PT_LEARN_GET (8 + SW_API_FDB_OFFSET) +#define SW_API_FDB_AGE_CTRL_SET (9 + SW_API_FDB_OFFSET) +#define SW_API_FDB_AGE_CTRL_GET (10 + SW_API_FDB_OFFSET) +#define SW_API_FDB_AGE_TIME_SET (11 + SW_API_FDB_OFFSET) +#define SW_API_FDB_AGE_TIME_GET (12 + SW_API_FDB_OFFSET) +#define SW_API_FDB_ITERATE (13 + SW_API_FDB_OFFSET) +#define SW_API_FDB_EXTEND_NEXT (14 + SW_API_FDB_OFFSET) +#define SW_API_PT_FDB_LEARN_LIMIT_SET (15 + SW_API_FDB_OFFSET) +#define SW_API_PT_FDB_LEARN_LIMIT_GET (16 + SW_API_FDB_OFFSET) +#define SW_API_PT_FDB_LEARN_EXCEED_CMD_SET (17 + SW_API_FDB_OFFSET) +#define SW_API_PT_FDB_LEARN_EXCEED_CMD_GET (18 + SW_API_FDB_OFFSET) +#define SW_API_FDB_LEARN_LIMIT_SET (19 + SW_API_FDB_OFFSET) +#define SW_API_FDB_LEARN_LIMIT_GET (20 + SW_API_FDB_OFFSET) +#define SW_API_FDB_LEARN_EXCEED_CMD_SET (21 + SW_API_FDB_OFFSET) +#define SW_API_FDB_LEARN_EXCEED_CMD_GET (22 + SW_API_FDB_OFFSET) +#define SW_API_FDB_RESV_ADD (23 + SW_API_FDB_OFFSET) +#define SW_API_FDB_RESV_DEL (24 + SW_API_FDB_OFFSET) +#define SW_API_FDB_RESV_FIND (25 + SW_API_FDB_OFFSET) +#define SW_API_FDB_RESV_ITERATE (26 + SW_API_FDB_OFFSET) +#define SW_API_FDB_EXTEND_FIRST (27 + SW_API_FDB_OFFSET) +#define SW_API_FDB_PT_LEARN_STATIC_SET (28 + SW_API_FDB_OFFSET) +#define SW_API_FDB_PT_LEARN_STATIC_GET (29 + SW_API_FDB_OFFSET) +#define SW_API_FDB_TRANSFER (30 + SW_API_FDB_OFFSET) +#define SW_API_FDB_PORT_ADD (31 + SW_API_FDB_OFFSET) +#define SW_API_FDB_PORT_DEL (32 + SW_API_FDB_OFFSET) +#define SW_API_FDB_VLAN_IVL_SVL_SET (33 + SW_API_FDB_OFFSET) +#define SW_API_FDB_VLAN_IVL_SVL_GET (34 + SW_API_FDB_OFFSET) +#define SW_API_FDB_RFS_SET (35 + SW_API_FDB_OFFSET) +#define SW_API_FDB_RFS_DEL (36 + SW_API_FDB_OFFSET) +#define SW_API_FDB_LEARN_CTRL_SET (37 + SW_API_FDB_OFFSET) +#define SW_API_FDB_LEARN_CTRL_GET (38 + SW_API_FDB_OFFSET) +#define SW_API_PT_FDB_LEARN_COUNTER_GET (39 + SW_API_FDB_OFFSET) +#define SW_API_FDB_PT_NEWADDR_LEARN_SET (40 + SW_API_FDB_OFFSET) +#define SW_API_FDB_PT_NEWADDR_LEARN_GET (41 + SW_API_FDB_OFFSET) +#define SW_API_FDB_PT_STAMOVE_SET (42 + SW_API_FDB_OFFSET) +#define SW_API_FDB_PT_STAMOVE_GET (43 + SW_API_FDB_OFFSET) +#define SW_API_FDB_PT_MACLIMIT_CTRL_SET (44 + SW_API_FDB_OFFSET) +#define SW_API_FDB_PT_MACLIMIT_CTRL_GET (45 + SW_API_FDB_OFFSET) +#define SW_API_FDB_DEL_BY_FID (46 + SW_API_FDB_OFFSET) + + + /*acl*/ +#define SW_API_ACL_OFFSET 400 +#define SW_API_ACL_LIST_CREAT (0 + SW_API_ACL_OFFSET) +#define SW_API_ACL_LIST_DESTROY (1 + SW_API_ACL_OFFSET) +#define SW_API_ACL_RULE_ADD (2 + SW_API_ACL_OFFSET) +#define SW_API_ACL_RULE_DELETE (3 + SW_API_ACL_OFFSET) +#define SW_API_ACL_RULE_QUERY (4 + SW_API_ACL_OFFSET) +#define SW_API_ACL_LIST_BIND (5 + SW_API_ACL_OFFSET) +#define SW_API_ACL_LIST_UNBIND (6 + SW_API_ACL_OFFSET) +#define SW_API_ACL_STATUS_SET (7 + SW_API_ACL_OFFSET) +#define SW_API_ACL_STATUS_GET (8 + SW_API_ACL_OFFSET) +#define SW_API_ACL_LIST_DUMP (9 + SW_API_ACL_OFFSET) +#define SW_API_ACL_RULE_DUMP (10 + SW_API_ACL_OFFSET) +#define SW_API_ACL_PT_UDF_PROFILE_SET (11 + SW_API_ACL_OFFSET) +#define SW_API_ACL_PT_UDF_PROFILE_GET (12 + SW_API_ACL_OFFSET) +#define SW_API_ACL_RULE_ACTIVE (13 + SW_API_ACL_OFFSET) +#define SW_API_ACL_RULE_DEACTIVE (14 + SW_API_ACL_OFFSET) +#define SW_API_ACL_RULE_SRC_FILTER_STS_SET (15 + SW_API_ACL_OFFSET) +#define SW_API_ACL_RULE_SRC_FILTER_STS_GET (16 + SW_API_ACL_OFFSET) +#define SW_API_ACL_RULE_GET_OFFSET (17 + SW_API_ACL_OFFSET) +#define SW_API_ACL_UDF_SET (18 + SW_API_ACL_OFFSET) +#define SW_API_ACL_UDF_GET (19 + SW_API_ACL_OFFSET) + + /*qos*/ +#define SW_API_QOS_OFFSET 500 +#define SW_API_QOS_SCH_MODE_SET (0 + SW_API_QOS_OFFSET) +#define SW_API_QOS_SCH_MODE_GET (1 + SW_API_QOS_OFFSET) +#define SW_API_QOS_QU_TX_BUF_ST_SET (2 + SW_API_QOS_OFFSET) +#define SW_API_QOS_QU_TX_BUF_ST_GET (3 + SW_API_QOS_OFFSET) +#define SW_API_QOS_QU_TX_BUF_NR_SET (4 + SW_API_QOS_OFFSET) +#define SW_API_QOS_QU_TX_BUF_NR_GET (5 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PT_TX_BUF_ST_SET (6 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PT_TX_BUF_ST_GET (7 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PT_TX_BUF_NR_SET (8 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PT_TX_BUF_NR_GET (9 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PT_RX_BUF_NR_SET (10 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PT_RX_BUF_NR_GET (11 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PT_MODE_SET (12 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PT_MODE_GET (13 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PT_MODE_PRI_SET (14 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PT_MODE_PRI_GET (15 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PORT_DEF_UP_SET (16 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PORT_DEF_UP_GET (17 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PORT_SCH_MODE_SET (18 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PORT_SCH_MODE_GET (19 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PT_DEF_SPRI_SET (20 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PT_DEF_SPRI_GET (21 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PT_DEF_CPRI_SET (22 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PT_DEF_CPRI_GET (23 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PT_FORCE_SPRI_ST_SET (24 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PT_FORCE_SPRI_ST_GET (25 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PT_FORCE_CPRI_ST_SET (26 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PT_FORCE_CPRI_ST_GET (27 + SW_API_QOS_OFFSET) +#define SW_API_QOS_QUEUE_REMARK_SET (28 + SW_API_QOS_OFFSET) +#define SW_API_QOS_QUEUE_REMARK_GET (29 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PT_RED_EN_SET (30 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PT_RED_EN_GET (31 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PORT_GROUP_GET (32 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PORT_GROUP_SET (33 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PORT_PRI_GET (34 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PORT_PRI_SET (35 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PORT_REMARK_GET (36 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PORT_REMARK_SET (37 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PCP_MAP_GET (38 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PCP_MAP_SET (39 + SW_API_QOS_OFFSET) +#define SW_API_QOS_FLOW_MAP_GET (40 + SW_API_QOS_OFFSET) +#define SW_API_QOS_FLOW_MAP_SET (41 + SW_API_QOS_OFFSET) +#define SW_API_QOS_DSCP_MAP_GET (42 + SW_API_QOS_OFFSET) +#define SW_API_QOS_DSCP_MAP_SET (43 + SW_API_QOS_OFFSET) +#define SW_API_QOS_QUEUE_SCHEDULER_GET (44 + SW_API_QOS_OFFSET) +#define SW_API_QOS_QUEUE_SCHEDULER_SET (45 + SW_API_QOS_OFFSET) +#define SW_API_QOS_RING_QUEUE_MAP_GET (46 + SW_API_QOS_OFFSET) +#define SW_API_QOS_RING_QUEUE_MAP_SET (47 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PORT_QUEUES_GET (48 + SW_API_QOS_OFFSET) +#define SW_API_QOS_SCHEDULER_DEQUEU_CTRL_GET (49 + SW_API_QOS_OFFSET) +#define SW_API_QOS_SCHEDULER_DEQUEU_CTRL_SET (50 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PORT_SCHEDULER_CFG_RESET (51 + SW_API_QOS_OFFSET) +#define SW_API_QOS_PORT_SCHEDULER_RESOURCE_GET (52 + SW_API_QOS_OFFSET) + + + /* igmp */ +#define SW_API_IGMP_OFFSET 600 +#define SW_API_PT_IGMPS_MODE_SET (0 + SW_API_IGMP_OFFSET) +#define SW_API_PT_IGMPS_MODE_GET (1 + SW_API_IGMP_OFFSET) +#define SW_API_IGMP_MLD_CMD_SET (2 + SW_API_IGMP_OFFSET) +#define SW_API_IGMP_MLD_CMD_GET (3 + SW_API_IGMP_OFFSET) +#define SW_API_IGMP_PT_JOIN_SET (4 + SW_API_IGMP_OFFSET) +#define SW_API_IGMP_PT_JOIN_GET (5 + SW_API_IGMP_OFFSET) +#define SW_API_IGMP_PT_LEAVE_SET (6 + SW_API_IGMP_OFFSET) +#define SW_API_IGMP_PT_LEAVE_GET (7 + SW_API_IGMP_OFFSET) +#define SW_API_IGMP_RP_SET (8 + SW_API_IGMP_OFFSET) +#define SW_API_IGMP_RP_GET (9 + SW_API_IGMP_OFFSET) +#define SW_API_IGMP_ENTRY_CREAT_SET (10 + SW_API_IGMP_OFFSET) +#define SW_API_IGMP_ENTRY_CREAT_GET (11 + SW_API_IGMP_OFFSET) +#define SW_API_IGMP_ENTRY_STATIC_SET (12 + SW_API_IGMP_OFFSET) +#define SW_API_IGMP_ENTRY_STATIC_GET (13 + SW_API_IGMP_OFFSET) +#define SW_API_IGMP_ENTRY_LEAKY_SET (14 + SW_API_IGMP_OFFSET) +#define SW_API_IGMP_ENTRY_LEAKY_GET (15 + SW_API_IGMP_OFFSET) +#define SW_API_IGMP_ENTRY_V3_SET (16 + SW_API_IGMP_OFFSET) +#define SW_API_IGMP_ENTRY_V3_GET (17 + SW_API_IGMP_OFFSET) +#define SW_API_IGMP_ENTRY_QUEUE_SET (18 + SW_API_IGMP_OFFSET) +#define SW_API_IGMP_ENTRY_QUEUE_GET (19 + SW_API_IGMP_OFFSET) +#define SW_API_PT_IGMP_LEARN_LIMIT_SET (20 + SW_API_IGMP_OFFSET) +#define SW_API_PT_IGMP_LEARN_LIMIT_GET (21 + SW_API_IGMP_OFFSET) +#define SW_API_PT_IGMP_LEARN_EXCEED_CMD_SET (22 + SW_API_IGMP_OFFSET) +#define SW_API_PT_IGMP_LEARN_EXCEED_CMD_GET (23 + SW_API_IGMP_OFFSET) +#define SW_API_IGMP_SG_ENTRY_SET (24 + SW_API_IGMP_OFFSET) +#define SW_API_IGMP_SG_ENTRY_CLEAR (25 + SW_API_IGMP_OFFSET) +#define SW_API_IGMP_SG_ENTRY_SHOW (26 + SW_API_IGMP_OFFSET) +#define SW_API_IGMP_SG_ENTRY_QUERY (27 + SW_API_IGMP_OFFSET) + + /* leaky */ +#define SW_API_LEAKY_OFFSET 700 +#define SW_API_UC_LEAKY_MODE_SET (0 + SW_API_LEAKY_OFFSET) +#define SW_API_UC_LEAKY_MODE_GET (1 + SW_API_LEAKY_OFFSET) +#define SW_API_MC_LEAKY_MODE_SET (2 + SW_API_LEAKY_OFFSET) +#define SW_API_MC_LEAKY_MODE_GET (3 + SW_API_LEAKY_OFFSET) +#define SW_API_ARP_LEAKY_MODE_SET (4 + SW_API_LEAKY_OFFSET) +#define SW_API_ARP_LEAKY_MODE_GET (5 + SW_API_LEAKY_OFFSET) +#define SW_API_PT_UC_LEAKY_MODE_SET (6 + SW_API_LEAKY_OFFSET) +#define SW_API_PT_UC_LEAKY_MODE_GET (7 + SW_API_LEAKY_OFFSET) +#define SW_API_PT_MC_LEAKY_MODE_SET (8 + SW_API_LEAKY_OFFSET) +#define SW_API_PT_MC_LEAKY_MODE_GET (9 + SW_API_LEAKY_OFFSET) + + /*mirror*/ +#define SW_API_MIR_OFFSET 800 +#define SW_API_MIRROR_ANALY_PT_SET (0 + SW_API_MIR_OFFSET) +#define SW_API_MIRROR_ANALY_PT_GET (1 + SW_API_MIR_OFFSET) +#define SW_API_MIRROR_IN_PT_SET (2 + SW_API_MIR_OFFSET) +#define SW_API_MIRROR_IN_PT_GET (3 + SW_API_MIR_OFFSET) +#define SW_API_MIRROR_EG_PT_SET (4 + SW_API_MIR_OFFSET) +#define SW_API_MIRROR_EG_PT_GET (5 + SW_API_MIR_OFFSET) +#define SW_API_MIRROR_ANALYSIS_CONFIG_SET (6 + SW_API_MIR_OFFSET) +#define SW_API_MIRROR_ANALYSIS_CONFIG_GET (7 + SW_API_MIR_OFFSET) + + /*rate*/ +#define SW_API_RATE_OFFSET 900 +#define SW_API_RATE_QU_EGRL_SET (0 + SW_API_RATE_OFFSET) +#define SW_API_RATE_QU_EGRL_GET (1 + SW_API_RATE_OFFSET) +#define SW_API_RATE_PT_EGRL_SET (2 + SW_API_RATE_OFFSET) +#define SW_API_RATE_PT_EGRL_GET (3 + SW_API_RATE_OFFSET) +#define SW_API_RATE_PT_INRL_SET (4 + SW_API_RATE_OFFSET) +#define SW_API_RATE_PT_INRL_GET (5 + SW_API_RATE_OFFSET) +#define SW_API_STORM_CTRL_FRAME_SET (6 + SW_API_RATE_OFFSET) +#define SW_API_STORM_CTRL_FRAME_GET (7 + SW_API_RATE_OFFSET) +#define SW_API_STORM_CTRL_RATE_SET (8 + SW_API_RATE_OFFSET) +#define SW_API_STORM_CTRL_RATE_GET (9 + SW_API_RATE_OFFSET) +#define SW_API_RATE_PORT_POLICER_SET (10 + SW_API_RATE_OFFSET) +#define SW_API_RATE_PORT_POLICER_GET (11 + SW_API_RATE_OFFSET) +#define SW_API_RATE_PORT_SHAPER_SET (12 + SW_API_RATE_OFFSET) +#define SW_API_RATE_PORT_SHAPER_GET (13 + SW_API_RATE_OFFSET) +#define SW_API_RATE_QUEUE_SHAPER_SET (14 + SW_API_RATE_OFFSET) +#define SW_API_RATE_QUEUE_SHAPER_GET (15 + SW_API_RATE_OFFSET) +#define SW_API_RATE_ACL_POLICER_SET (16 + SW_API_RATE_OFFSET) +#define SW_API_RATE_ACL_POLICER_GET (17 + SW_API_RATE_OFFSET) +#define SW_API_RATE_PT_ADDRATEBYTE_SET (18 + SW_API_RATE_OFFSET) +#define SW_API_RATE_PT_ADDRATEBYTE_GET (19 + SW_API_RATE_OFFSET) +#define SW_API_RATE_PT_GOL_FLOW_EN_SET (20 + SW_API_RATE_OFFSET) +#define SW_API_RATE_PT_GOL_FLOW_EN_GET (21 + SW_API_RATE_OFFSET) + + /*stp*/ +#define SW_API_STP_OFFSET 1000 +#define SW_API_STP_PT_STATE_SET (0 + SW_API_STP_OFFSET) +#define SW_API_STP_PT_STATE_GET (1 + SW_API_STP_OFFSET) + + /*mib*/ +#define SW_API_MIB_OFFSET 1100 +#define SW_API_PT_MIB_GET (0 + SW_API_MIB_OFFSET) +#define SW_API_MIB_STATUS_SET (1 + SW_API_MIB_OFFSET) +#define SW_API_MIB_STATUS_GET (2 + SW_API_MIB_OFFSET) +#define SW_API_PT_MIB_FLUSH_COUNTERS (3+ SW_API_MIB_OFFSET) +#define SW_API_MIB_CPU_KEEP_SET (4+ SW_API_MIB_OFFSET) +#define SW_API_MIB_CPU_KEEP_GET (5+ SW_API_MIB_OFFSET) +#define SW_API_PT_XGMIB_GET (6+ SW_API_MIB_OFFSET) +#define SW_API_PT_MIB_COUNTER_GET (7+ SW_API_MIB_OFFSET) + + /*misc*/ +#define SW_API_MISC_OFFSET 1200 +#define SW_API_ARP_STATUS_SET (0 + SW_API_MISC_OFFSET) +#define SW_API_ARP_STATUS_GET (1 + SW_API_MISC_OFFSET) +#define SW_API_FRAME_MAX_SIZE_SET (2 + SW_API_MISC_OFFSET) +#define SW_API_FRAME_MAX_SIZE_GET (3 + SW_API_MISC_OFFSET) +#define SW_API_PT_UNK_SA_CMD_SET (4 + SW_API_MISC_OFFSET) +#define SW_API_PT_UNK_SA_CMD_GET (5 + SW_API_MISC_OFFSET) +#define SW_API_PT_UNK_UC_FILTER_SET (6 + SW_API_MISC_OFFSET) +#define SW_API_PT_UNK_UC_FILTER_GET (7 + SW_API_MISC_OFFSET) +#define SW_API_PT_UNK_MC_FILTER_SET (8 + SW_API_MISC_OFFSET) +#define SW_API_PT_UNK_MC_FILTER_GET (9 + SW_API_MISC_OFFSET) +#define SW_API_PT_BC_FILTER_SET (10 + SW_API_MISC_OFFSET) +#define SW_API_PT_BC_FILTER_GET (11 + SW_API_MISC_OFFSET) +#define SW_API_CPU_PORT_STATUS_SET (12 + SW_API_MISC_OFFSET) +#define SW_API_CPU_PORT_STATUS_GET (13 + SW_API_MISC_OFFSET) +#define SW_API_BC_TO_CPU_PORT_SET (14 + SW_API_MISC_OFFSET) +#define SW_API_BC_TO_CPU_PORT_GET (15 + SW_API_MISC_OFFSET) +#define SW_API_PPPOE_CMD_SET (16 + SW_API_MISC_OFFSET) +#define SW_API_PPPOE_CMD_GET (17 + SW_API_MISC_OFFSET) +#define SW_API_PPPOE_STATUS_SET (18 + SW_API_MISC_OFFSET) +#define SW_API_PPPOE_STATUS_GET (19 + SW_API_MISC_OFFSET) +#define SW_API_PT_DHCP_SET (20 + SW_API_MISC_OFFSET) +#define SW_API_PT_DHCP_GET (21 + SW_API_MISC_OFFSET) +#define SW_API_ARP_CMD_SET (22 + SW_API_MISC_OFFSET) +#define SW_API_ARP_CMD_GET (23 + SW_API_MISC_OFFSET) +#define SW_API_EAPOL_CMD_SET (24 + SW_API_MISC_OFFSET) +#define SW_API_EAPOL_CMD_GET (25 + SW_API_MISC_OFFSET) +#define SW_API_PPPOE_SESSION_ADD (26 + SW_API_MISC_OFFSET) +#define SW_API_PPPOE_SESSION_DEL (27 + SW_API_MISC_OFFSET) +#define SW_API_PPPOE_SESSION_GET (28 + SW_API_MISC_OFFSET) +#define SW_API_EAPOL_STATUS_SET (29 + SW_API_MISC_OFFSET) +#define SW_API_EAPOL_STATUS_GET (30 + SW_API_MISC_OFFSET) +#define SW_API_RIPV1_STATUS_SET (31 + SW_API_MISC_OFFSET) +#define SW_API_RIPV1_STATUS_GET (32 + SW_API_MISC_OFFSET) +#define SW_API_PT_ARP_REQ_STATUS_SET (33 + SW_API_MISC_OFFSET) +#define SW_API_PT_ARP_REQ_STATUS_GET (34 + SW_API_MISC_OFFSET) +#define SW_API_PT_ARP_ACK_STATUS_SET (35 + SW_API_MISC_OFFSET) +#define SW_API_PT_ARP_ACK_STATUS_GET (36 + SW_API_MISC_OFFSET) +#define SW_API_PPPOE_SESSION_TABLE_ADD (37 + SW_API_MISC_OFFSET) +#define SW_API_PPPOE_SESSION_TABLE_DEL (38 + SW_API_MISC_OFFSET) +#define SW_API_PPPOE_SESSION_TABLE_GET (39 + SW_API_MISC_OFFSET) +#define SW_API_PPPOE_SESSION_ID_SET (40 + SW_API_MISC_OFFSET) +#define SW_API_PPPOE_SESSION_ID_GET (41 + SW_API_MISC_OFFSET) +#define SW_API_INTR_MASK_SET (42 + SW_API_MISC_OFFSET) +#define SW_API_INTR_MASK_GET (43 + SW_API_MISC_OFFSET) +#define SW_API_INTR_STATUS_GET (44 + SW_API_MISC_OFFSET) +#define SW_API_INTR_STATUS_CLEAR (45 + SW_API_MISC_OFFSET) +#define SW_API_INTR_PORT_LINK_MASK_SET (46 + SW_API_MISC_OFFSET) +#define SW_API_INTR_PORT_LINK_MASK_GET (47 + SW_API_MISC_OFFSET) +#define SW_API_INTR_PORT_LINK_STATUS_GET (48 + SW_API_MISC_OFFSET) +#define SW_API_INTR_MASK_MAC_LINKCHG_SET (49 + SW_API_MISC_OFFSET) +#define SW_API_INTR_MASK_MAC_LINKCHG_GET (50 + SW_API_MISC_OFFSET) +#define SW_API_INTR_STATUS_MAC_LINKCHG_GET (51 + SW_API_MISC_OFFSET) +#define SW_API_INTR_STATUS_MAC_LINKCHG_CLEAR (52 + SW_API_MISC_OFFSET) +#define SW_API_CPU_VID_EN_SET (53 + SW_API_MISC_OFFSET) +#define SW_API_CPU_VID_EN_GET (54 + SW_API_MISC_OFFSET) +#define SW_API_RTD_PPPOE_EN_SET (55 + SW_API_MISC_OFFSET) +#define SW_API_RTD_PPPOE_EN_GET (56 + SW_API_MISC_OFFSET) +#define SW_API_GLOBAL_MACADDR_SET (57 + SW_API_MISC_OFFSET) +#define SW_API_GLOBAL_MACADDR_GET (58 + SW_API_MISC_OFFSET) +#define SW_API_LLDP_STATUS_SET (59 + SW_API_MISC_OFFSET) +#define SW_API_LLDP_STATUS_GET (60 + SW_API_MISC_OFFSET) +#define SW_API_FRAME_CRC_RESERVE_SET (61 + SW_API_MISC_OFFSET) +#define SW_API_FRAME_CRC_RESERVE_GET (62 + SW_API_MISC_OFFSET) +#define SW_API_PPPOE_EN_SET (63 + SW_API_MISC_OFFSET) +#define SW_API_PPPOE_EN_GET (64 + SW_API_MISC_OFFSET) +#define SW_API_DEBUG_PORT_COUNTER_ENABLE (65 + SW_API_MISC_OFFSET) +#define SW_API_DEBUG_PORT_COUNTER_STATUS_GET (66 + SW_API_MISC_OFFSET) + + /*led*/ +#define SW_API_LED_OFFSET 1300 +#define SW_API_LED_PATTERN_SET (0 + SW_API_LED_OFFSET) +#define SW_API_LED_PATTERN_GET (1 + SW_API_LED_OFFSET) + + /* cosmap */ +#define SW_API_COSMAP_OFFSET 1400 +#define SW_API_COSMAP_UP_QU_SET (0 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_UP_QU_GET (1 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_DSCP_QU_SET (2 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_DSCP_QU_GET (3 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_DSCP_TO_PRI_SET (4 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_DSCP_TO_PRI_GET (5 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_DSCP_TO_DP_SET (6 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_DSCP_TO_DP_GET (7 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_UP_TO_PRI_SET (8 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_UP_TO_PRI_GET (9 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_UP_TO_DP_SET (10 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_UP_TO_DP_GET (11 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_PRI_TO_QU_SET (12 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_PRI_TO_QU_GET (13 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_PRI_TO_EHQU_SET (14 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_PRI_TO_EHQU_GET (15 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_EG_REMARK_SET (16 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_EG_REMARK_GET (17 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_DSCP_TO_EHPRI_SET (18 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_DSCP_TO_EHPRI_GET (19 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_DSCP_TO_EHDP_SET (20 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_DSCP_TO_EHDP_GET (21 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_UP_TO_EHPRI_SET (22 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_UP_TO_EHPRI_GET (23 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_UP_TO_EHDP_SET (24 + SW_API_COSMAP_OFFSET) +#define SW_API_COSMAP_UP_TO_EHDP_GET (25 + SW_API_COSMAP_OFFSET) + + /* sec */ +#define SW_API_SEC_OFFSET 1500 +#define SW_API_SEC_NORM_SET (0 + SW_API_SEC_OFFSET) +#define SW_API_SEC_NORM_GET (1 + SW_API_SEC_OFFSET) +#define SW_API_SEC_MAC_SET (2 + SW_API_SEC_OFFSET) +#define SW_API_SEC_MAC_GET (3 + SW_API_SEC_OFFSET) +#define SW_API_SEC_IP_SET (4 + SW_API_SEC_OFFSET) +#define SW_API_SEC_IP_GET (5 + SW_API_SEC_OFFSET) +#define SW_API_SEC_IP4_SET (6 + SW_API_SEC_OFFSET) +#define SW_API_SEC_IP4_GET (7 + SW_API_SEC_OFFSET) +#define SW_API_SEC_IP6_SET (8 + SW_API_SEC_OFFSET) +#define SW_API_SEC_IP6_GET (9 + SW_API_SEC_OFFSET) +#define SW_API_SEC_TCP_SET (10 + SW_API_SEC_OFFSET) +#define SW_API_SEC_TCP_GET (11 + SW_API_SEC_OFFSET) +#define SW_API_SEC_UDP_SET (12 + SW_API_SEC_OFFSET) +#define SW_API_SEC_UDP_GET (13 + SW_API_SEC_OFFSET) +#define SW_API_SEC_ICMP4_SET (14 + SW_API_SEC_OFFSET) +#define SW_API_SEC_ICMP4_GET (15 + SW_API_SEC_OFFSET) +#define SW_API_SEC_ICMP6_SET (16 + SW_API_SEC_OFFSET) +#define SW_API_SEC_ICMP6_GET (17 + SW_API_SEC_OFFSET) +#define SW_API_SEC_L3_PARSER_CTRL_GET (18 + SW_API_SEC_OFFSET) +#define SW_API_SEC_L3_PARSER_CTRL_SET (19 + SW_API_SEC_OFFSET) +#define SW_API_SEC_L4_PARSER_CTRL_GET (20 + SW_API_SEC_OFFSET) +#define SW_API_SEC_L4_PARSER_CTRL_SET (21 + SW_API_SEC_OFFSET) +#define SW_API_SEC_EXP_CTRL_GET (22 + SW_API_SEC_OFFSET) +#define SW_API_SEC_EXP_CTRL_SET (23 + SW_API_SEC_OFFSET) + + /* ip */ +#define SW_API_IP_OFFSET 1600 +#define SW_API_IP_HOST_ADD (0 + SW_API_IP_OFFSET) +#define SW_API_IP_HOST_DEL (1 + SW_API_IP_OFFSET) +#define SW_API_IP_HOST_GET (2 + SW_API_IP_OFFSET) +#define SW_API_IP_HOST_NEXT (3 + SW_API_IP_OFFSET) +#define SW_API_IP_HOST_COUNTER_BIND (4 + SW_API_IP_OFFSET) +#define SW_API_IP_HOST_PPPOE_BIND (5 + SW_API_IP_OFFSET) +#define SW_API_IP_PT_ARP_LEARN_SET (6 + SW_API_IP_OFFSET) +#define SW_API_IP_PT_ARP_LEARN_GET (7 + SW_API_IP_OFFSET) +#define SW_API_IP_ARP_LEARN_SET (8 + SW_API_IP_OFFSET) +#define SW_API_IP_ARP_LEARN_GET (9 + SW_API_IP_OFFSET) +#define SW_API_IP_SOURCE_GUARD_SET (10 + SW_API_IP_OFFSET) +#define SW_API_IP_SOURCE_GUARD_GET (11 + SW_API_IP_OFFSET) +#define SW_API_IP_ARP_GUARD_SET (12 + SW_API_IP_OFFSET) +#define SW_API_IP_ARP_GUARD_GET (13 + SW_API_IP_OFFSET) +#define SW_API_IP_ROUTE_STATUS_SET (14 + SW_API_IP_OFFSET) +#define SW_API_IP_ROUTE_STATUS_GET (15 + SW_API_IP_OFFSET) +#define SW_API_IP_INTF_ENTRY_ADD (16 + SW_API_IP_OFFSET) +#define SW_API_IP_INTF_ENTRY_DEL (17 + SW_API_IP_OFFSET) +#define SW_API_IP_INTF_ENTRY_NEXT (18 + SW_API_IP_OFFSET) +#define SW_API_IP_UNK_SOURCE_CMD_SET (19 + SW_API_IP_OFFSET) +#define SW_API_IP_UNK_SOURCE_CMD_GET (20 + SW_API_IP_OFFSET) +#define SW_API_ARP_UNK_SOURCE_CMD_SET (21 + SW_API_IP_OFFSET) +#define SW_API_ARP_UNK_SOURCE_CMD_GET (22 + SW_API_IP_OFFSET) +#define SW_API_IP_AGE_TIME_SET (23 + SW_API_IP_OFFSET) +#define SW_API_IP_AGE_TIME_GET (24 + SW_API_IP_OFFSET) +#define SW_API_WCMP_HASH_MODE_SET (25 + SW_API_IP_OFFSET) +#define SW_API_WCMP_HASH_MODE_GET (26 + SW_API_IP_OFFSET) +#define SW_API_IP_VRF_BASE_ADDR_SET (27 + SW_API_IP_OFFSET) +#define SW_API_IP_VRF_BASE_ADDR_GET (28 + SW_API_IP_OFFSET) +#define SW_API_IP_VRF_BASE_MASK_SET (29 + SW_API_IP_OFFSET) +#define SW_API_IP_VRF_BASE_MASK_GET (30 + SW_API_IP_OFFSET) +#define SW_API_IP_DEFAULT_ROUTE_SET (31 + SW_API_IP_OFFSET) +#define SW_API_IP_DEFAULT_ROUTE_GET (32 + SW_API_IP_OFFSET) +#define SW_API_IP_HOST_ROUTE_SET (33 + SW_API_IP_OFFSET) +#define SW_API_IP_HOST_ROUTE_GET (34 + SW_API_IP_OFFSET) +#define SW_API_IP_WCMP_ENTRY_SET (35 + SW_API_IP_OFFSET) +#define SW_API_IP_WCMP_ENTRY_GET (36 + SW_API_IP_OFFSET) +#define SW_API_IP_RFS_IP4_SET (37 + SW_API_IP_OFFSET) +#define SW_API_IP_RFS_IP6_SET (38 + SW_API_IP_OFFSET) +#define SW_API_IP_RFS_IP4_DEL (39 + SW_API_IP_OFFSET) +#define SW_API_IP_RFS_IP6_DEL (40 + SW_API_IP_OFFSET) +#define SW_API_IP_DEFAULT_FLOW_CMD_SET (41 + SW_API_IP_OFFSET) +#define SW_API_IP_DEFAULT_FLOW_CMD_GET (42 + SW_API_IP_OFFSET) +#define SW_API_IP_DEFAULT_RT_FLOW_CMD_SET (43 + SW_API_IP_OFFSET) +#define SW_API_IP_DEFAULT_RT_FLOW_CMD_GET (44 + SW_API_IP_OFFSET) +#define SW_API_IP_VIS_ARP_SG_CFG_GET (45 + SW_API_IP_OFFSET) +#define SW_API_IP_VIS_ARP_SG_CFG_SET (46 + SW_API_IP_OFFSET) +#define SW_API_IP_NETWORK_ROUTE_GET (47 + SW_API_IP_OFFSET) +#define SW_API_IP_NETWORK_ROUTE_ADD (48 + SW_API_IP_OFFSET) +#define SW_API_IP_INTF_GET (49 + SW_API_IP_OFFSET) +#define SW_API_IP_INTF_SET (50 + SW_API_IP_OFFSET) +#define SW_API_IP_VSI_INTF_GET (51 + SW_API_IP_OFFSET) +#define SW_API_IP_VSI_INTF_SET (52 + SW_API_IP_OFFSET) +#define SW_API_IP_NEXTHOP_GET (53 + SW_API_IP_OFFSET) +#define SW_API_IP_NEXTHOP_SET (54 + SW_API_IP_OFFSET) +#define SW_API_IP_VSI_SG_SET (55 + SW_API_IP_OFFSET) +#define SW_API_IP_VSI_SG_GET (56 + SW_API_IP_OFFSET) +#define SW_API_IP_PORT_SG_SET (57 + SW_API_IP_OFFSET) +#define SW_API_IP_PORT_SG_GET (58 + SW_API_IP_OFFSET) +#define SW_API_IP_PUB_IP_SET (59 + SW_API_IP_OFFSET) +#define SW_API_IP_PUB_IP_GET (60 + SW_API_IP_OFFSET) +#define SW_API_IP_NETWORK_ROUTE_DEL (61 + SW_API_IP_OFFSET) +#define SW_API_IP_PORT_INTF_GET (62 + SW_API_IP_OFFSET) +#define SW_API_IP_PORT_INTF_SET (63 + SW_API_IP_OFFSET) +#define SW_API_IP_PORT_MAC_GET (64 + SW_API_IP_OFFSET) +#define SW_API_IP_PORT_MAC_SET (65 + SW_API_IP_OFFSET) +#define SW_API_IP_ROUTE_MISS_GET (66 + SW_API_IP_OFFSET) +#define SW_API_IP_ROUTE_MISS_SET (67 + SW_API_IP_OFFSET) +#define SW_API_IP_PORT_ARP_SG_GET (68 + SW_API_IP_OFFSET) +#define SW_API_IP_PORT_ARP_SG_SET (69 + SW_API_IP_OFFSET) +#define SW_API_IP_VSI_MC_MODE_GET (70 + SW_API_IP_OFFSET) +#define SW_API_IP_VSI_MC_MODE_SET (71 + SW_API_IP_OFFSET) +#define SW_API_GLOBAL_CTRL_GET (72 + SW_API_IP_OFFSET) +#define SW_API_GLOBAL_CTRL_SET (73 + SW_API_IP_OFFSET) + + /* nat */ +#define SW_API_NAT_OFFSET 1700 +#define SW_API_NAT_ADD (0 + SW_API_NAT_OFFSET) +#define SW_API_NAT_DEL (1 + SW_API_NAT_OFFSET) +#define SW_API_NAT_GET (2 + SW_API_NAT_OFFSET) +#define SW_API_NAT_NEXT (3 + SW_API_NAT_OFFSET) +#define SW_API_NAT_COUNTER_BIND (4 + SW_API_NAT_OFFSET) +#define SW_API_NAPT_ADD (5 + SW_API_NAT_OFFSET) +#define SW_API_NAPT_DEL (6 + SW_API_NAT_OFFSET) +#define SW_API_NAPT_GET (7 + SW_API_NAT_OFFSET) +#define SW_API_NAPT_NEXT (8 + SW_API_NAT_OFFSET) +#define SW_API_NAPT_COUNTER_BIND (9 + SW_API_NAT_OFFSET) +#define SW_API_NAT_STATUS_SET (10 + SW_API_NAT_OFFSET) +#define SW_API_NAT_STATUS_GET (11 + SW_API_NAT_OFFSET) +#define SW_API_NAT_HASH_MODE_SET (12 + SW_API_NAT_OFFSET) +#define SW_API_NAT_HASH_MODE_GET (13 + SW_API_NAT_OFFSET) +#define SW_API_NAPT_STATUS_SET (14 + SW_API_NAT_OFFSET) +#define SW_API_NAPT_STATUS_GET (15 + SW_API_NAT_OFFSET) +#define SW_API_NAPT_MODE_SET (16 + SW_API_NAT_OFFSET) +#define SW_API_NAPT_MODE_GET (17 + SW_API_NAT_OFFSET) +#define SW_API_PRV_BASE_ADDR_SET (18 + SW_API_NAT_OFFSET) +#define SW_API_PRV_BASE_ADDR_GET (19 + SW_API_NAT_OFFSET) +#define SW_API_PRV_ADDR_MODE_SET (20 + SW_API_NAT_OFFSET) +#define SW_API_PRV_ADDR_MODE_GET (21 + SW_API_NAT_OFFSET) +#define SW_API_PUB_ADDR_ENTRY_ADD (22 + SW_API_NAT_OFFSET) +#define SW_API_PUB_ADDR_ENTRY_DEL (23 + SW_API_NAT_OFFSET) +#define SW_API_PUB_ADDR_ENTRY_NEXT (24 + SW_API_NAT_OFFSET) +#define SW_API_NAT_UNK_SESSION_CMD_SET (25 + SW_API_NAT_OFFSET) +#define SW_API_NAT_UNK_SESSION_CMD_GET (26 + SW_API_NAT_OFFSET) +#define SW_API_PRV_BASE_MASK_SET (27 + SW_API_NAT_OFFSET) +#define SW_API_PRV_BASE_MASK_GET (28 + SW_API_NAT_OFFSET) +#define SW_API_NAT_GLOBAL_SET (29 + SW_API_NAT_OFFSET) +#define SW_API_FLOW_ADD (30 + SW_API_NAT_OFFSET) +#define SW_API_FLOW_DEL (31 + SW_API_NAT_OFFSET) +#define SW_API_FLOW_GET (32 + SW_API_NAT_OFFSET) +#define SW_API_FLOW_NEXT (33 + SW_API_NAT_OFFSET) +#define SW_API_FLOW_COUNTER_BIND (34 + SW_API_NAT_OFFSET) +#define SW_API_FLOW_COOKIE_SET (35 + SW_API_NAT_OFFSET) +#define SW_API_FLOW_RFS_SET (36 + SW_API_NAT_OFFSET) + + + /* trunk */ +#define SW_API_TRUNK_OFFSET 1800 +#define SW_API_TRUNK_GROUP_SET (0 + SW_API_TRUNK_OFFSET) +#define SW_API_TRUNK_GROUP_GET (1 + SW_API_TRUNK_OFFSET) +#define SW_API_TRUNK_HASH_SET (2 + SW_API_TRUNK_OFFSET) +#define SW_API_TRUNK_HASH_GET (3 + SW_API_TRUNK_OFFSET) +#define SW_API_TRUNK_MAN_SA_SET (4 + SW_API_TRUNK_OFFSET) +#define SW_API_TRUNK_MAN_SA_GET (5 + SW_API_TRUNK_OFFSET) +#define SW_API_TRUNK_FAILOVER_EN_SET (6 + SW_API_TRUNK_OFFSET) +#define SW_API_TRUNK_FAILOVER_EN_GET (7 + SW_API_TRUNK_OFFSET) + + /* Interface Control */ +#define SW_API_INTERFACE_OFFSET 1900 +#define SW_API_MAC_MODE_SET (0 + SW_API_INTERFACE_OFFSET) +#define SW_API_MAC_MODE_GET (1 + SW_API_INTERFACE_OFFSET) +#define SW_API_PORT_3AZ_STATUS_SET (2 + SW_API_INTERFACE_OFFSET) +#define SW_API_PORT_3AZ_STATUS_GET (3 + SW_API_INTERFACE_OFFSET) +#define SW_API_PHY_MODE_SET (4 + SW_API_INTERFACE_OFFSET) +#define SW_API_PHY_MODE_GET (5 + SW_API_INTERFACE_OFFSET) +#define SW_API_FX100_CTRL_SET (6 + SW_API_INTERFACE_OFFSET) +#define SW_API_FX100_CTRL_GET (7 + SW_API_INTERFACE_OFFSET) +#define SW_API_FX100_STATUS_GET (8 + SW_API_INTERFACE_OFFSET) +#define SW_API_MAC06_EXCH_SET (9 + SW_API_INTERFACE_OFFSET) +#define SW_API_MAC06_EXCH_GET (10 + SW_API_INTERFACE_OFFSET) + + /* VSI */ +#define SW_API_VSI_OFFSET 2000 +#define SW_API_VSI_ALLOC (0 + SW_API_VSI_OFFSET) +#define SW_API_VSI_FREE (1 + SW_API_VSI_OFFSET) +#define SW_API_PORT_VSI_SET (2 + SW_API_VSI_OFFSET) +#define SW_API_PORT_VSI_GET (3 + SW_API_VSI_OFFSET) +#define SW_API_PORT_VLAN_VSI_SET (4 + SW_API_VSI_OFFSET) +#define SW_API_PORT_VLAN_VSI_GET (5 + SW_API_VSI_OFFSET) +#define SW_API_VSI_TBL_DUMP (6 + SW_API_VSI_OFFSET) +#define SW_API_VSI_NEWADDR_LRN_SET (7 + SW_API_VSI_OFFSET) +#define SW_API_VSI_NEWADDR_LRN_GET (8 + SW_API_VSI_OFFSET) +#define SW_API_VSI_STAMOVE_SET (9 + SW_API_VSI_OFFSET) +#define SW_API_VSI_STAMOVE_GET (10 + SW_API_VSI_OFFSET) +#define SW_API_VSI_MEMBER_SET (11 + SW_API_VSI_OFFSET) +#define SW_API_VSI_MEMBER_GET (12 + SW_API_VSI_OFFSET) +#define SW_API_VSI_COUNTER_GET (13 + SW_API_VSI_OFFSET) +#define SW_API_VSI_COUNTER_CLEANUP (14 + SW_API_VSI_OFFSET) + + /* qm */ +#define SW_API_QM_OFFSET 2100 +#define SW_API_UCAST_QUEUE_BASE_PROFILE_SET (0 + SW_API_QM_OFFSET) +#define SW_API_UCAST_QUEUE_BASE_PROFILE_GET (1 + SW_API_QM_OFFSET) +#define SW_API_UCAST_PRIORITY_CLASS_SET (2 + SW_API_QM_OFFSET) +#define SW_API_UCAST_PRIORITY_CLASS_GET (3 + SW_API_QM_OFFSET) +#define SW_API_MCAST_PRIORITY_CLASS_SET (4 + SW_API_QM_OFFSET) +#define SW_API_MCAST_PRIORITY_CLASS_GET (5 + SW_API_QM_OFFSET) +#define SW_API_UCAST_HASH_MAP_SET (6 + SW_API_QM_OFFSET) +#define SW_API_UCAST_HASH_MAP_GET (7 + SW_API_QM_OFFSET) +#define SW_API_UCAST_DFLT_HASH_MAP_SET (8 + SW_API_QM_OFFSET) +#define SW_API_UCAST_DFLT_HASH_MAP_GET (9 + SW_API_QM_OFFSET) +#define SW_API_MCAST_CPUCODE_CLASS_SET (10 + SW_API_QM_OFFSET) +#define SW_API_MCAST_CPUCODE_CLASS_GET (11 + SW_API_QM_OFFSET) +#define SW_API_QUEUE_FLUSH (12 + SW_API_QM_OFFSET) +#define SW_API_AC_CTRL_SET (13 + SW_API_QM_OFFSET) +#define SW_API_AC_CTRL_GET (14 + SW_API_QM_OFFSET) +#define SW_API_AC_PRE_BUFFER_SET (15 + SW_API_QM_OFFSET) +#define SW_API_AC_PRE_BUFFER_GET (16 + SW_API_QM_OFFSET) +#define SW_API_QUEUE_GROUP_SET (17 + SW_API_QM_OFFSET) +#define SW_API_QUEUE_GROUP_GET (18 + SW_API_QM_OFFSET) +#define SW_API_STATIC_THRESH_SET (19 + SW_API_QM_OFFSET) +#define SW_API_STATIC_THRESH_GET (20 + SW_API_QM_OFFSET) +#define SW_API_DYNAMIC_THRESH_SET (21 + SW_API_QM_OFFSET) +#define SW_API_DYNAMIC_THRESH_GET (22 + SW_API_QM_OFFSET) +#define SW_API_GOURP_BUFFER_SET (23 + SW_API_QM_OFFSET) +#define SW_API_GOURP_BUFFER_GET (24 + SW_API_QM_OFFSET) +#define SW_API_QUEUE_CNT_CTRL_GET (25 + SW_API_QM_OFFSET) +#define SW_API_QUEUE_CNT_CTRL_SET (26 + SW_API_QM_OFFSET) +#define SW_API_QUEUE_CNT_GET (27 + SW_API_QM_OFFSET) +#define SW_API_QUEUE_CNT_CLEANUP (28 + SW_API_QM_OFFSET) +#define SW_API_QM_ENQUEUE_CTRL_SET (29 + SW_API_QM_OFFSET) +#define SW_API_QM_ENQUEUE_CTRL_GET (30 + SW_API_QM_OFFSET) +#define SW_API_QM_SOURCE_PROFILE_SET (31 + SW_API_QM_OFFSET) +#define SW_API_QM_SOURCE_PROFILE_GET (32 + SW_API_QM_OFFSET) + +/* flow */ +#define SW_API_FLOW_OFFSET 2200 +#define SW_API_FLOW_STATUS_SET (0 + SW_API_FLOW_OFFSET) +#define SW_API_FLOW_STATUS_GET (1 + SW_API_FLOW_OFFSET) +#define SW_API_FLOW_AGE_TIMER_SET (2 + SW_API_FLOW_OFFSET) +#define SW_API_FLOW_AGE_TIMER_GET (3 + SW_API_FLOW_OFFSET) +#define SW_API_FLOW_CTRL_SET (4 + SW_API_FLOW_OFFSET) +#define SW_API_FLOW_CTRL_GET (5 + SW_API_FLOW_OFFSET) +#define SW_API_FLOW_ENTRY_ADD (6 + SW_API_FLOW_OFFSET) +#define SW_API_FLOW_ENTRY_DEL (7 + SW_API_FLOW_OFFSET) +#define SW_API_FLOW_ENTRY_GET (8 + SW_API_FLOW_OFFSET) +#define SW_API_FLOW_GLOBAL_CFG_GET (9 + SW_API_FLOW_OFFSET) +#define SW_API_FLOW_GLOBAL_CFG_SET (10 + SW_API_FLOW_OFFSET) +#define SW_API_FLOWENTRY_NEXT (11 + SW_API_FLOW_OFFSET) + +#define SW_API_FLOW_HOST_ADD (20 + SW_API_FLOW_OFFSET) +#define SW_API_FLOW_HOST_DEL (21 + SW_API_FLOW_OFFSET) +#define SW_API_FLOW_HOST_GET (22 + SW_API_FLOW_OFFSET) + +/* rss hash */ +#define SW_API_RSS_HASH_OFFSET 2400 +#define SW_API_RSS_HASH_CONFIG_SET (0 + SW_API_RSS_HASH_OFFSET) +#define SW_API_RSS_HASH_CONFIG_GET (1 + SW_API_RSS_HASH_OFFSET) + +/* bm */ +#define SW_API_BM_OFFSET 3000 +#define SW_API_BM_CTRL_SET (0 + SW_API_BM_OFFSET) +#define SW_API_BM_CTRL_GET (1 + SW_API_BM_OFFSET) +#define SW_API_BM_PORTGROUP_MAP_SET (2 + SW_API_BM_OFFSET) +#define SW_API_BM_PORTGROUP_MAP_GET (3 + SW_API_BM_OFFSET) +#define SW_API_BM_GROUP_BUFFER_SET (4 + SW_API_BM_OFFSET) +#define SW_API_BM_GROUP_BUFFER_GET (5 + SW_API_BM_OFFSET) +#define SW_API_BM_PORT_RSVBUFFER_SET (6 + SW_API_BM_OFFSET) +#define SW_API_BM_PORT_RSVBUFFER_GET (7 + SW_API_BM_OFFSET) +#define SW_API_BM_STATIC_THRESH_SET (8 + SW_API_BM_OFFSET) +#define SW_API_BM_STATIC_THRESH_GET (9 + SW_API_BM_OFFSET) +#define SW_API_BM_DYNAMIC_THRESH_SET (10 + SW_API_BM_OFFSET) +#define SW_API_BM_DYNAMIC_THRESH_GET (11 + SW_API_BM_OFFSET) +#define SW_API_BM_PORT_COUNTER_GET (12 + SW_API_BM_OFFSET) + +/* ptp */ +#define SW_API_PTP_OFFSET 3100 +#define SW_API_PTP_CONFIG_SET (0 + SW_API_PTP_OFFSET) +#define SW_API_PTP_CONFIG_GET (1 + SW_API_PTP_OFFSET) +#define SW_API_PTP_REFERENCE_CLOCK_SET (2 + SW_API_PTP_OFFSET) +#define SW_API_PTP_REFERENCE_CLOCK_GET (3 + SW_API_PTP_OFFSET) +#define SW_API_PTP_RX_TIMESTAMP_MODE_SET (4 + SW_API_PTP_OFFSET) +#define SW_API_PTP_RX_TIMESTAMP_MODE_GET (5 + SW_API_PTP_OFFSET) +#define SW_API_PTP_TIMESTAMP_GET (6 + SW_API_PTP_OFFSET) +#define SW_API_PTP_PKT_TIMESTAMP_SET (7 + SW_API_PTP_OFFSET) +#define SW_API_PTP_PKT_TIMESTAMP_GET (8 + SW_API_PTP_OFFSET) +#define SW_API_PTP_GRANDMASTER_MODE_SET (9 + SW_API_PTP_OFFSET) +#define SW_API_PTP_GRANDMASTER_MODE_GET (10 + SW_API_PTP_OFFSET) +#define SW_API_PTP_RTC_TIME_SET (11 + SW_API_PTP_OFFSET) +#define SW_API_PTP_RTC_TIME_GET (12 + SW_API_PTP_OFFSET) +#define SW_API_PTP_RTC_TIME_CLEAR (13 + SW_API_PTP_OFFSET) +#define SW_API_PTP_RTC_ADJTIME_SET (14 + SW_API_PTP_OFFSET) +#define SW_API_PTP_RTC_ADJFREQ_SET (15 + SW_API_PTP_OFFSET) +#define SW_API_PTP_RTC_ADJFREQ_GET (16 + SW_API_PTP_OFFSET) +#define SW_API_PTP_LINK_DELAY_SET (17 + SW_API_PTP_OFFSET) +#define SW_API_PTP_LINK_DELAY_GET (18 + SW_API_PTP_OFFSET) +#define SW_API_PTP_SECURITY_SET (19 + SW_API_PTP_OFFSET) +#define SW_API_PTP_SECURITY_GET (20 + SW_API_PTP_OFFSET) +#define SW_API_PTP_PPS_SIGNAL_CONTROL_SET (21 + SW_API_PTP_OFFSET) +#define SW_API_PTP_PPS_SIGNAL_CONTROL_GET (22 + SW_API_PTP_OFFSET) +#define SW_API_PTP_RX_CRC_RECALC_SET (23 + SW_API_PTP_OFFSET) +#define SW_API_PTP_RX_CRC_RECALC_GET (24 + SW_API_PTP_OFFSET) +#define SW_API_PTP_ASYM_CORRECTION_SET (25 + SW_API_PTP_OFFSET) +#define SW_API_PTP_ASYM_CORRECTION_GET (26 + SW_API_PTP_OFFSET) +#define SW_API_PTP_OUTPUT_WAVEFORM_SET (27 + SW_API_PTP_OFFSET) +#define SW_API_PTP_OUTPUT_WAVEFORM_GET (28 + SW_API_PTP_OFFSET) +#define SW_API_PTP_RTC_TIME_SNAPSHOT_SET (29 + SW_API_PTP_OFFSET) +#define SW_API_PTP_RTC_TIME_SNAPSHOT_GET (30 + SW_API_PTP_OFFSET) +#define SW_API_PTP_INCREMENT_SYNC_FROM_CLOCK_SET (31 + SW_API_PTP_OFFSET) +#define SW_API_PTP_INCREMENT_SYNC_FROM_CLOCK_GET (32 + SW_API_PTP_OFFSET) +#define SW_API_PTP_TOD_UART_SET (33 + SW_API_PTP_OFFSET) +#define SW_API_PTP_TOD_UART_GET (34 + SW_API_PTP_OFFSET) +#define SW_API_PTP_ENHANCED_TIMESTAMP_ENGINE_SET (35 + SW_API_PTP_OFFSET) +#define SW_API_PTP_ENHANCED_TIMESTAMP_ENGINE_GET (36 + SW_API_PTP_OFFSET) +#define SW_API_PTP_TRIGGER_SET (37 + SW_API_PTP_OFFSET) +#define SW_API_PTP_TRIGGER_GET (38 + SW_API_PTP_OFFSET) +#define SW_API_PTP_CAPTURE_SET (39 + SW_API_PTP_OFFSET) +#define SW_API_PTP_CAPTURE_GET (40 + SW_API_PTP_OFFSET) +#define SW_API_PTP_INTERRUPT_SET (41 + SW_API_PTP_OFFSET) +#define SW_API_PTP_INTERRUPT_GET (42 + SW_API_PTP_OFFSET) + +/* sfp */ +#define SW_API_SFP_OFFSET 3200 +#define SW_API_SFP_DATA_GET (0 + SW_API_SFP_OFFSET) +#define SW_API_SFP_DATA_SET (1 + SW_API_SFP_OFFSET) +#define SW_API_SFP_DEV_TYPE_GET (2 + SW_API_SFP_OFFSET) +#define SW_API_SFP_TRANSC_CODE_GET (3 + SW_API_SFP_OFFSET) +#define SW_API_SFP_RATE_ENCODE_GET (4 + SW_API_SFP_OFFSET) +#define SW_API_SFP_LINK_LENGTH_GET (5 + SW_API_SFP_OFFSET) +#define SW_API_SFP_VENDOR_INFO_GET (6 + SW_API_SFP_OFFSET) +#define SW_API_SFP_LASER_WAVELENGTH_GET (7 + SW_API_SFP_OFFSET) +#define SW_API_SFP_OPTION_GET (8 + SW_API_SFP_OFFSET) +#define SW_API_SFP_CTRL_RATE_GET (9 + SW_API_SFP_OFFSET) +#define SW_API_SFP_ENHANCED_CFG_GET (10 + SW_API_SFP_OFFSET) +#define SW_API_SFP_DIAG_THRESHOLD_GET (11 + SW_API_SFP_OFFSET) +#define SW_API_SFP_DIAG_CAL_CONST_GET (12 + SW_API_SFP_OFFSET) +#define SW_API_SFP_DIAG_REALTIME_GET (13 + SW_API_SFP_OFFSET) +#define SW_API_SFP_DIAG_CTRL_STATUS_GET (14 + SW_API_SFP_OFFSET) +#define SW_API_SFP_DIAG_ALARM_WARN_FLAG_GET (15 + SW_API_SFP_OFFSET) +#define SW_API_SFP_CHECKCODE_GET (16 + SW_API_SFP_OFFSET) + +/*qca808x_start*/ + /*debug*/ +#define SW_API_DEBUG_OFFSET 10000 +#define SW_API_PHY_GET (0 + SW_API_DEBUG_OFFSET) +#define SW_API_PHY_SET (1 + SW_API_DEBUG_OFFSET) +/*qca808x_end*/ +#define SW_API_REG_GET (2 + SW_API_DEBUG_OFFSET) +#define SW_API_REG_SET (3 + SW_API_DEBUG_OFFSET) +#define SW_API_REG_ENTRY_GET (4 + SW_API_DEBUG_OFFSET) +#define SW_API_REG_ENTRY_SET (5 + SW_API_DEBUG_OFFSET) +#define SW_API_REG_FIELD_GET (6 + SW_API_DEBUG_OFFSET) +#define SW_API_REG_FIELD_SET (7 + SW_API_DEBUG_OFFSET) +#define SW_API_PSGMII_REG_GET (8 + SW_API_DEBUG_OFFSET) +#define SW_API_PSGMII_REG_SET (9 + SW_API_DEBUG_OFFSET) +#define SW_API_REG_DUMP (10 + SW_API_DEBUG_OFFSET) +#define SW_API_DBG_REG_DUMP (11 + SW_API_DEBUG_OFFSET) +#define SW_API_DBG_PSGMII_SELF_TEST (12 + SW_API_DEBUG_OFFSET) +#define SW_API_PHY_DUMP (13 + SW_API_DEBUG_OFFSET) +#define SW_API_UNIPHY_REG_GET (20 + SW_API_DEBUG_OFFSET) +#define SW_API_UNIPHY_REG_SET (21 + SW_API_DEBUG_OFFSET) + /* Ctrlpkt Control */ +#define SW_API_CTRLPKT_OFFSET 2500 +#define SW_API_MGMTCTRL_ETHTYPE_PROFILE_SET (0 + SW_API_CTRLPKT_OFFSET) +#define SW_API_MGMTCTRL_ETHTYPE_PROFILE_GET (1 + SW_API_CTRLPKT_OFFSET) +#define SW_API_MGMTCTRL_RFDB_PROFILE_SET (2 + SW_API_CTRLPKT_OFFSET) +#define SW_API_MGMTCTRL_RFDB_PROFILE_GET (3 + SW_API_CTRLPKT_OFFSET) +#define SW_API_MGMTCTRL_CTRLPKT_PROFILE_ADD (4 + SW_API_CTRLPKT_OFFSET) +#define SW_API_MGMTCTRL_CTRLPKT_PROFILE_DEL (5 + SW_API_CTRLPKT_OFFSET) +#define SW_API_MGMTCTRL_CTRLPKT_PROFILE_GETFIRST (6 + SW_API_CTRLPKT_OFFSET) +#define SW_API_MGMTCTRL_CTRLPKT_PROFILE_GETNEXT (7 + SW_API_CTRLPKT_OFFSET) + + /* Service Code */ +#define SW_API_SERVCODE_OFFSET 2600 +#define SW_API_SERVCODE_CONFIG_SET (0 + SW_API_SERVCODE_OFFSET) +#define SW_API_SERVCODE_CONFIG_GET (1 + SW_API_SERVCODE_OFFSET) +#define SW_API_SERVCODE_LOOPCHECK_EN (2 + SW_API_SERVCODE_OFFSET) +#define SW_API_SERVCODE_LOOPCHECK_STATUS_GET (3 + SW_API_SERVCODE_OFFSET) + + + /* POLICER */ +#define SW_API_POLICER_OFFSET 2800 +#define SW_API_POLICER_TIMESLOT_SET (0 + SW_API_POLICER_OFFSET) +#define SW_API_POLICER_TIMESLOT_GET (1 + SW_API_POLICER_OFFSET) +#define SW_API_POLICER_PORT_COUNTER_GET (2 + SW_API_POLICER_OFFSET) +#define SW_API_POLICER_ACL_COUNTER_GET (3 + SW_API_POLICER_OFFSET) +#define SW_API_POLICER_COMPENSATION_SET (4 + SW_API_POLICER_OFFSET) +#define SW_API_POLICER_COMPENSATION_GET (5 + SW_API_POLICER_OFFSET) +#define SW_API_POLICER_PORT_ENTRY_SET (6 + SW_API_POLICER_OFFSET) +#define SW_API_POLICER_PORT_ENTRY_GET (7 + SW_API_POLICER_OFFSET) +#define SW_API_POLICER_ACL_ENTRY_SET (8 + SW_API_POLICER_OFFSET) +#define SW_API_POLICER_ACL_ENTRY_GET (9 + SW_API_POLICER_OFFSET) +#define SW_API_POLICER_GLOBAL_COUNTER_GET (10 + SW_API_POLICER_OFFSET) + + +/* SHAPER */ +#define SW_API_SHAPER_OFFSET 2900 +#define SW_API_PORT_SHAPER_TIMESLOT_SET (0 + SW_API_SHAPER_OFFSET) +#define SW_API_PORT_SHAPER_TIMESLOT_GET (1 + SW_API_SHAPER_OFFSET) +#define SW_API_FLOW_SHAPER_TIMESLOT_SET (2 + SW_API_SHAPER_OFFSET) +#define SW_API_FLOW_SHAPER_TIMESLOT_GET (3 + SW_API_SHAPER_OFFSET) +#define SW_API_QUEUE_SHAPER_TIMESLOT_SET (4 + SW_API_SHAPER_OFFSET) +#define SW_API_QUEUE_SHAPER_TIMESLOT_GET (5 + SW_API_SHAPER_OFFSET) +#define SW_API_PORT_SHAPER_TOKEN_NUMBER_SET (6 + SW_API_SHAPER_OFFSET) +#define SW_API_PORT_SHAPER_TOKEN_NUMBER_GET (7 + SW_API_SHAPER_OFFSET) +#define SW_API_FLOW_SHAPER_TOKEN_NUMBER_SET (8 + SW_API_SHAPER_OFFSET) +#define SW_API_FLOW_SHAPER_TOKEN_NUMBER_GET (9 + SW_API_SHAPER_OFFSET) +#define SW_API_QUEUE_SHAPER_TOKEN_NUMBER_SET (10 + SW_API_SHAPER_OFFSET) +#define SW_API_QUEUE_SHAPER_TOKEN_NUMBER_GET (11 + SW_API_SHAPER_OFFSET) +#define SW_API_PORT_SHAPER_SET (12 + SW_API_SHAPER_OFFSET) +#define SW_API_PORT_SHAPER_GET (13 + SW_API_SHAPER_OFFSET) +#define SW_API_FLOW_SHAPER_SET (14 + SW_API_SHAPER_OFFSET) +#define SW_API_FLOW_SHAPER_GET (15 + SW_API_SHAPER_OFFSET) +#define SW_API_QUEUE_SHAPER_SET (16 + SW_API_SHAPER_OFFSET) +#define SW_API_QUEUE_SHAPER_GET (17 + SW_API_SHAPER_OFFSET) +#define SW_API_SHAPER_IPG_PRE_SET (18 + SW_API_SHAPER_OFFSET) +#define SW_API_SHAPER_IPG_PRE_GET (19 + SW_API_SHAPER_OFFSET) +/*qca808x_start*/ +#define SW_API_MAX 0xffff +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SW_IOCTL_H_ */ +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/common/aos_head.h b/feeds/ipq807x/qca-ssdk-shell/src/include/common/aos_head.h new file mode 100755 index 000000000..3332f0ae2 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/common/aos_head.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2014,2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/*qca808x_start*/ +#include "aos_mem.h" +#include "aos_types.h" +/*qca808x_end*/ +#include "aos_timer.h" +#include "aos_lock.h" diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/common/shared_func.h b/feeds/ipq807x/qca-ssdk-shell/src/include/common/shared_func.h new file mode 100755 index 000000000..6b0d72587 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/common/shared_func.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#ifndef _SHARED_FUNC_H +#define _SHARED_FUNC_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define SW_RTN_ON_ERROR(rtn) \ + do { if (rtn != SW_OK) return(rtn); } while(0); + +#define SW_OUT_ON_ERROR(rtn) \ + do { \ + if (rtn != SW_OK) { \ + rv = rtn; \ + goto out;\ + } \ + } while(0); + +#define SW_RTN_ON_ERROR_EXCEPT_COND1(rtn, cond1) \ + do { \ + if ((rtn != SW_OK) && (rtn != cond1)) \ + return rtn; \ + }while(0); + +#define SW_RTN_ON_NULL(op) \ + do { \ + if ((op) == NULL) \ + return SW_NOT_INITIALIZED;\ + }while(0); + + /* register functions */ +#define SW_BIT_MASK_U32(nr) (~(0xFFFFFFFF << (nr))) + +#define SW_FIELD_MASK_U32(offset, len) \ + ((SW_BIT_MASK_U32(len) << (offset))) + +#define SW_FIELD_MASK_NOT_U32(offset,len) \ + (~(SW_BIT_MASK_U32(len) << (offset))) + +#define SW_FIELD_2_REG(field_val, bit_offset) \ + (field_val << (bit_offset) ) + +#define SW_REG_2_FIELD(reg_val, bit_offset, field_len) \ + (((reg_val) >> (bit_offset)) & ((1 << (field_len)) - 1)) + +#define SW_REG_SET_BY_FIELD_U32(reg_value, field_value, bit_offset, field_len)\ + do { \ + (reg_value) = \ + (((reg_value) & SW_FIELD_MASK_NOT_U32((bit_offset),(field_len))) \ + | (((field_value) & SW_BIT_MASK_U32(field_len)) << (bit_offset)));\ + } while (0) + +#define SW_FIELD_GET_BY_REG_U32(reg_value, field_value, bit_offset, field_len)\ + do { \ + (field_value) = \ + (((reg_value) >> (bit_offset)) & SW_BIT_MASK_U32(field_len)); \ + } while (0) + +#define SW_SWAP_BITS_U8(x) \ + ((((x)&0x80)>>7) | (((x)&0x40)>>5) | (((x)&0x20)>>3) | (((x)&0x10)>>1) \ + |(((x)&0x1)<<7) | (((x)&0x2)<<5) | (((x)&0x4)<<3) |(((x)&0x8)<<1) ) + + +#define SW_OFFSET_U8_2_U16(byte_offset) ((byte_offset) >> 1) + +#define SW_OFFSET_U16_2_U8(word16_offset) ((word16_offset) << 1) + +#define SW_OFFSET_BIT_2_U8_ALIGN16(bit_offset) (((bit_offset) / 16) * 2) + +#define SW_SET_REG_BY_FIELD(reg, field, field_value, reg_value) \ + SW_REG_SET_BY_FIELD_U32(reg_value, field_value, reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN) + +#define SW_GET_FIELD_BY_REG(reg, field, field_value, reg_value) \ + SW_FIELD_GET_BY_REG_U32(reg_value, field_value, reg##_##field##_BOFFSET, \ + reg##_##field##_BLEN) + + /* port bitmap functions */ +#define SW_IS_PBMP_MEMBER(pbm, port) ((pbm & (1 << port)) ? A_TRUE: A_FALSE) +#define SW_IS_PBMP_EQ(pbm0, pbm1) ((pbm0 == pbm1) ? A_TRUE: A_FALSE) + +#define SW_PBMP_AND(pbm0, pbm1) ((pbm0) &= (pbm1)) +#define SW_PBMP_OR(pbm0, pbm1) ((pbm0) |= (pbm1)) +#define SW_IS_PBMP_INCLUDE(pbm0, pbm1) \ + ((pbm1 == SW_PBMP_AND(pbm0, pbm1)) ? A_TRUE: A_FALSE) + +#define SW_PBMP_CLEAR(pbm) ((pbm) = 0) +#define SW_PBMP_ADD_PORT(pbm, port) ((pbm) |= (1U << (port))) +#define SW_PBMP_DEL_PORT(pbm,port) ((pbm) &= ~(1U << (port))) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SHARED_FUNC_H */ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/common/sw.h b/feeds/ipq807x/qca-ssdk-shell/src/include/common/sw.h new file mode 100755 index 000000000..2793cd205 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/common/sw.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2014,2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#ifndef _SW_H_ +#define _SW_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw_config.h" +#include "aos_head.h" +#include "sw_error.h" +#include "shared_func.h" + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SW_H_ */ + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/common/sw_config.h b/feeds/ipq807x/qca-ssdk-shell/src/include/common/sw_config.h new file mode 100755 index 000000000..7809571fc --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/common/sw_config.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#ifndef _SW_CONFIG_H +#define _SW_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define SW_MAX_NR_DEV 3 +#define SW_MAX_NR_PORT 16 + +#ifdef HSL_STANDALONG +#define HSL_LOCAL +#else +#define HSL_LOCAL static +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/common/sw_error.h b/feeds/ipq807x/qca-ssdk-shell/src/include/common/sw_error.h new file mode 100755 index 000000000..e6cb2d20b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/common/sw_error.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#ifndef _SW_ERROR_H +#define _SW_ERROR_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + typedef enum { + SW_OK = 0, /* Operation succeeded */ + SW_FAIL = -1, /* Operation failed */ + SW_BAD_VALUE = -2, /* Illegal value */ + SW_OUT_OF_RANGE = -3, /* Value is out of range */ + SW_BAD_PARAM = -4, /* Illegal parameter(s) */ + SW_BAD_PTR = -5, /* Illegal pointer value */ + SW_BAD_LEN = -6, /* Wrong length */ + SW_BAD_STATE = -7, /* Wrong state of state machine */ + SW_READ_ERROR = -8, /* Read operation failed */ + SW_WRITE_ERROR = -9, /* Write operation failed */ + SW_CREATE_ERROR = -10, /* Fail in creating an entry */ + SW_DELETE_ERROR = -11, /* Fail in deleteing an entry */ + SW_NOT_FOUND = -12, /* Entry not found */ + SW_NO_CHANGE = -13, /* The parameter(s) is the same */ + SW_NO_MORE = -14, /* No more entry found */ + SW_NO_SUCH = -15, /* No such entry */ + SW_ALREADY_EXIST = -16, /* Tried to create existing entry */ + SW_FULL = -17, /* Table is full */ + SW_EMPTY = -18, /* Table is empty */ + SW_NOT_SUPPORTED = -19, /* This request is not support */ + SW_NOT_IMPLEMENTED = -20, /* This request is not implemented */ + SW_NOT_INITIALIZED = -21, /* The item is not initialized */ + SW_BUSY = -22, /* Operation is still running */ + SW_TIMEOUT = -23, /* Operation Time Out */ + SW_DISABLE = -24, /* Operation is disabled */ + SW_NO_RESOURCE = -25, /* Resource not available (memory ...) */ + SW_INIT_ERROR = -26, /* Error occured while INIT process */ + SW_NOT_READY = -27, /* The other side is not ready yet */ + SW_OUT_OF_MEM = -28, /* Cpu memory allocation failed. */ + SW_ABORTED = -29 /* Operation has been aborted. */ + } sw_error_t; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SW_ERROR_H */ + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/common/util.h b/feeds/ipq807x/qca-ssdk-shell/src/include/common/util.h new file mode 100755 index 000000000..94b5ab65f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/common/util.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#ifndef _UTIL_H_ +#define _UTIL_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define LL_IN_ORDER 0x1 +#define LL_FIX_NDNR 0x2 + + typedef enum { + LL_CMP_EQUAL = 0, + LL_CMP_GREATER = 1, + LL_CMP_SMALLER = 2 + } + ll_cmp_rslt_t; + + typedef ll_cmp_rslt_t(*ll_nd_cmp) (void *src, void *dest); + + typedef void (*ll_nd_dump) (void *data); + + typedef struct _sll_node_t + { + struct _sll_node_t *next; + void *data; + } sll_node_t; + + typedef struct + { + sll_node_t *fst_nd; + a_uint32_t nd_nr; + a_uint32_t flag; + ll_nd_cmp nd_cmp; + ll_nd_dump nd_dump; + sll_node_t *free_nd; + } sll_head_t; + + sll_head_t *sll_creat(ll_nd_cmp cmp_func, ll_nd_dump dump_func, + a_uint32_t flag, a_uint32_t nd_nr); + + void sll_destroy(sll_head_t * sll); + + void sll_lock(sll_head_t * sll); + + void sll_unlock(sll_head_t * sll); + + void *sll_nd_find(const sll_head_t * sll, void *data, + a_uint32_t * iterator); + + void *sll_nd_next(const sll_head_t * sll, a_uint32_t * iterator); + + sw_error_t sll_nd_insert(sll_head_t * sll, void *data); + + sw_error_t sll_nd_delete(sll_head_t * sll, void *data); + + typedef struct + { + a_uint32_t id_ptr; + a_uint32_t id_nr; + a_uint32_t id_min; + a_uint32_t id_size; + void *id_pool; + } sid_pool_t; + + sid_pool_t *sid_pool_creat(a_uint32_t id_nr, a_uint32_t min_id); + + void sid_pool_destroy(sid_pool_t * pool); + + sw_error_t sid_pool_id_alloc(sid_pool_t * pool, a_uint32_t * id); + + sw_error_t sid_pool_id_free(sid_pool_t * pool, a_uint32_t id); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _UTIL_H_ */ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal.h new file mode 100755 index 000000000..cdffadee4 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014, 2017-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/*qca808x_start*/ +#ifndef _FAL_H +#define _FAL_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +#include "fal_port_ctrl.h" +/*qca808x_end*/ +#include "fal_misc.h" +#include "fal_vlan.h" +#include "fal_fdb.h" +#include "fal_portvlan.h" +#include "fal_qos.h" +#include "fal_stp.h" +#include "fal_rate.h" +#include "fal_mirror.h" +#include "fal_leaky.h" +#include "fal_igmp.h" +#include "fal_mib.h" +#include "fal_acl.h" +#include "fal_led.h" +/*qca808x_start*/ +#include "fal_reg_access.h" +#include "fal_init.h" +/*qca808x_end*/ +#include "fal_cosmap.h" +#include "fal_ip.h" +#include "fal_nat.h" +#include "fal_sec.h" +#include "fal_trunk.h" +#include "fal_interface_ctrl.h" +#include "fal_fdb.h" +#include "fal_multi.h" +#include "fal_vsi.h" +#include "fal_qm.h" +#include "fal_flow.h" +#include "fal_ctrlpkt.h" +#include "fal_servcode.h" +#include "fal_rss_hash.h" +#include "fal_pppoe.h" +#include "fal_shaper.h" +#include "fal_bm.h" +#include "fal_policer.h" +#include "fal_ptp.h" +#include "fal_sfp.h" +/*qca808x_start*/ +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_H */ +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_acl.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_acl.h new file mode 100755 index 000000000..edb605e40 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_acl.h @@ -0,0 +1,619 @@ +/* + * Copyright (c) 2014, 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/** + * @defgroup fal_acl FAL_ACL + * @{ + */ +#ifndef _FAL_ACL_H_ +#define _FAL_ACL_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "common/sw.h" +#include "fal/fal_type.h" + + + /** + @brief This enum defines the ACL rule type. + */ + typedef enum { + FAL_ACL_RULE_MAC = 0, /**< include MAC, udf fields*/ + FAL_ACL_RULE_IP4, /**< include MAC, IP4 and Tcp/Udp udf fields*/ + FAL_ACL_RULE_IP6, /**< include MAC, IP6 and Tcp/Udp udf fields*/ + FAL_ACL_RULE_UDF, /**< only include user defined fields*/ + FAL_ACL_RULE_BUTT, + } + fal_acl_rule_type_t; + + + /** + @brief This enum defines the ACL field operation type. + */ + typedef enum + { + FAL_ACL_FIELD_MASK = 0, /**< match operation is mask*/ + FAL_ACL_FIELD_RANGE, /**< match operation is range*/ + FAL_ACL_FIELD_LE, /**< match operation is less and equal*/ + FAL_ACL_FIELD_GE, /**< match operation is great and equal*/ + FAL_ACL_FIELD_NE, /**<- match operation is not equal*/ + FAL_ACL_FIELD_OP_BUTT, + } fal_acl_field_op_t; + + + typedef enum + { + FAL_ACL_POLICY_ROUTE = 0, + FAL_ACL_POLICY_SNAT, + FAL_ACL_POLICY_DNAT, + FAL_ACL_POLICY_RESERVE, + } fal_policy_forward_t; + + typedef enum + { + FAL_ACL_COMBINED_NONE = 0, + FAL_ACL_COMBINED_START, + FAL_ACL_COMBINED_CONTINUE, + FAL_ACL_COMBINED_END, + } fal_combined_t; + + /** + @brief This enum defines the ACL field operation type. + */ + typedef enum + { + FAL_ACL_UDF_TYPE_L2 = 0, /**< */ + FAL_ACL_UDF_TYPE_L3, /**< */ + FAL_ACL_UDF_TYPE_L4, /**< */ + FAL_ACL_UDF_TYPE_L2_SNAP, /**< */ + FAL_ACL_UDF_TYPE_L3_PLUS, /**< */ + FAL_ACL_UDF_TYPE_BUTT, + } fal_acl_udf_type_t; + + /** + @brief This enum defines the ACL rule type. + */ + typedef enum { + FAL_ACL_UDF_NON_IP = 0, + FAL_ACL_UDF_IP4, + FAL_ACL_UDF_IP6, + FAL_ACL_UDF_BUTT, + }fal_acl_udf_pkt_type_t; + + typedef enum { + FAL_ACL_DEST_PORT_BMP = 0, /*dest info is bitmap*/ + FAL_ACL_DEST_NEXTHOP, /*dest info is nexthop*/ + FAL_ACL_DEST_PORT_ID, /*dest info is port id*/ + }fal_acl_dest_type_t; + +#define FAL_ACL_DEST_OFFSET(type,value) (((type)<<24)|(value)) +#define FAL_ACL_DEST_TYPE(dest) (((dest)>>24)&0xff) +#define FAL_ACL_DEST_VALUE(dest) ((dest)&0xffffff) + +#define FAL_ACL_FIELD_MAC_DA 0 +#define FAL_ACL_FIELD_MAC_SA 1 +#define FAL_ACL_FIELD_MAC_ETHTYPE 2 +#define FAL_ACL_FIELD_MAC_TAGGED 3 +#define FAL_ACL_FIELD_MAC_UP 4 +#define FAL_ACL_FIELD_MAC_VID 5 +#define FAL_ACL_FIELD_IP4_SIP 6 +#define FAL_ACL_FIELD_IP4_DIP 7 +#define FAL_ACL_FIELD_IP6_LABEL 8 +#define FAL_ACL_FIELD_IP6_SIP 9 +#define FAL_ACL_FIELD_IP6_DIP 10 +#define FAL_ACL_FIELD_IP_PROTO 11 +#define FAL_ACL_FIELD_IP_DSCP 12 +#define FAL_ACL_FIELD_L4_SPORT 13 +#define FAL_ACL_FIELD_L4_DPORT 14 +#define FAL_ACL_FIELD_UDF 15 +#define FAL_ACL_FIELD_MAC_CFI 16 +#define FAL_ACL_FIELD_ICMP_TYPE 17 +#define FAL_ACL_FIELD_ICMP_CODE 18 +#define FAL_ACL_FIELD_TCP_FLAG 19 +#define FAL_ACL_FIELD_RIPV1 20 +#define FAL_ACL_FIELD_DHCPV4 21 +#define FAL_ACL_FIELD_DHCPV6 22 +#define FAL_ACL_FIELD_MAC_STAG_VID 23 +#define FAL_ACL_FIELD_MAC_STAG_PRI 24 +#define FAL_ACL_FIELD_MAC_STAG_DEI 25 +#define FAL_ACL_FIELD_MAC_STAGGED 26 +#define FAL_ACL_FIELD_MAC_CTAG_VID 27 +#define FAL_ACL_FIELD_MAC_CTAG_PRI 28 +#define FAL_ACL_FIELD_MAC_CTAG_CFI 29 +#define FAL_ACL_FIELD_MAC_CTAGGED 30 +#define FAL_ACL_FIELD_INVERSE_ALL 31 +/*new add for hawkeye*/ +#define FAL_ACL_FIELD_POST_ROURING_EN 32 +#define FAL_ACL_FIELD_RES_CHAIN 33 +#define FAL_ACL_FIELD_FAKE_MAC_HEADER 34 +#define FAL_ACL_FIELD_SNAP 35 +#define FAL_ACL_FIELD_ETHERNET 36 +#define FAL_ACL_FIELD_IPV6 37 +#define FAL_ACL_FIELD_IP 38 +#define FAL_ACL_FIELD_VSI 39 +#define FAL_ACL_FIELD_PPPOE_SESSIONID 40 +#define FAL_ACL_FIELD_L3_FRAGMENT 41 +#define FAL_ACL_FIELD_AH_HEADER 42 +#define FAL_ACL_FIELD_ESP_HEADER 43 +#define FAL_ACL_FIELD_MOBILITY_HEADER 44 +#define FAL_ACL_FIELD_FRAGMENT_HEADER 45 +#define FAL_ACL_FIELD_OTHER_EXT_HEADER 46 +#define FAL_ACL_FIELD_L3_TTL 47 +#define FAL_ACL_FIELD_IPV4_OPTION 48 +#define FAL_ACL_FIELD_FIRST_FRAGMENT 49 +#define FAL_ACL_FIELD_L3_LENGTH 50 +#define FAL_ACL_FIELD_VSI_VALID 51 +#define FAL_ACL_FIELD_IP_PKT_TYPE 52 + +#define FAL_ACL_FIELD_UDF0 53 +#define FAL_ACL_FIELD_UDF1 54 +#define FAL_ACL_FIELD_UDF2 55 +#define FAL_ACL_FIELD_UDF3 56 + +#define FAL_ACL_FIELD_NUM 57 + + +#define FAL_ACL_ACTION_PERMIT 0 +#define FAL_ACL_ACTION_DENY 1 +#define FAL_ACL_ACTION_REDPT 2 +#define FAL_ACL_ACTION_RDTCPU 3 +#define FAL_ACL_ACTION_CPYCPU 4 +#define FAL_ACL_ACTION_MIRROR 5 +#define FAL_ACL_ACTION_MODIFY_VLAN 6 +#define FAL_ACL_ACTION_NEST_VLAN 7 +#define FAL_ACL_ACTION_REMARK_UP 8 +#define FAL_ACL_ACTION_REMARK_QUEUE 9 +#define FAL_ACL_ACTION_REMARK_STAG_VID 10 +#define FAL_ACL_ACTION_REMARK_STAG_PRI 11 +#define FAL_ACL_ACTION_REMARK_STAG_DEI 12 +#define FAL_ACL_ACTION_REMARK_CTAG_VID 13 +#define FAL_ACL_ACTION_REMARK_CTAG_PRI 14 +#define FAL_ACL_ACTION_REMARK_CTAG_CFI 15 +#define FAL_ACL_ACTION_REMARK_LOOKUP_VID 16 +#define FAL_ACL_ACTION_REMARK_DSCP 17 +#define FAL_ACL_ACTION_POLICER_EN 18 +#define FAL_ACL_ACTION_WCMP_EN 19 +#define FAL_ACL_ACTION_ARP_EN 20 +#define FAL_ACL_ACTION_POLICY_FORWARD_EN 21 +#define FAL_ACL_ACTION_BYPASS_EGRESS_TRANS 22 +#define FAL_ACL_ACTION_MATCH_TRIGGER_INTR 23 +/*new add for hawkeye*/ +#define FAL_ACL_ACTION_ENQUEUE_PRI 25 +#define FAL_ACL_ACTION_INT_DP 26 +#define FAL_ACL_ACTION_SERVICE_CODE 27 +#define FAL_ACL_ACTION_CPU_CODE 28 +#define FAL_ACL_ACTION_SYN_TOGGLE 29 +#define FAL_ACL_ACTION_METADATA_EN 30 + + +enum{ + FAL_ACL_BYPASS_IN_VLAN_MISS = 0, + FAL_ACL_BYPASS_SOUCE_GUARD, + FAL_ACL_BYPASS_MRU_MTU_CHECK, + FAL_ACL_BYPASS_EG_VSI_MEMBER_CHECK = 8, + FAL_ACL_BYPASS_EG_VLAN_TRANSLATION, + FAL_ACL_BYPASS_EG_VLAN_TAG_CTRL = 10, + FAL_ACL_BYPASS_FDB_LEARNING, + FAL_ACL_BYPASS_FDB_REFRESH, + FAL_ACL_BYPASS_L2_SECURITY,/*new address, station move, learn limit, hash full*/ + FAL_ACL_BYPASS_MANAGEMENT_FWD, + FAL_ACL_BYPASS_L2_FWD = 15, + FAL_ACL_BYPASS_IN_STP_CHECK, + FAL_ACL_BYPASS_EG_STP_CHECK, + FAL_ACL_BYPASS_SOURCE_FILTER, + FAL_ACL_BYPASS_POLICYER, + FAL_ACL_BYPASS_L2_EDIT = 20,/*VLAN tag edit*/ + FAL_ACL_BYPASS_L3_EDIT,/*Edit MAC address, PPPoE, IP address, TTL, DSCP, L4 port*/ + FAL_ACL_BYPASS_POST_ACL_CHECK_ROUTING, + FAL_ACL_BYPASS_PORT_ISOLATION, +}; + + + /** + * @brief This type defines the action in Acl rule. + * @details Comments: + * It's a bit map type, we can access it through macro FAL_ACTION_FLG_SET, + * FAL_ACTION_FLG_CLR and FAL_ACTION_FLG_TST. + */ + typedef a_uint32_t fal_acl_action_map_t; + +#define FAL_ACTION_FLG_SET(flag, action) \ + (flag) |= (0x1UL << (action)) + +#define FAL_ACTION_FLG_CLR(flag, action) \ + (flag) &= (~(0x1UL << (action))) + +#define FAL_ACTION_FLG_TST(flag, action) \ + ((flag) & (0x1UL << (action))) ? 1 : 0 + + + /** + * @brief This type defines the field in Acl rule. + * @details Comments: + * It's a bit map type, we can access it through macro FAL_FIELD_FLG_SET, + * FAL_FIELD_FLG_CLR and FAL_FIELD_FLG_TST. + */ + typedef a_uint32_t fal_acl_field_map_t[2]; + +#define FAL_FIELD_FLG_SET(flag, field) \ + ((flag[(field) / 32]) |= (0x1UL << ((field) % 32))) + +#define FAL_FIELD_FLG_CLR(flag, field) \ + ((flag[(field) / 32]) &= (~(0x1UL << ((field) % 32)))) + +#define FAL_FIELD_FLG_TST(flag, field) \ + (((flag[(field) / 32]) & (0x1UL << ((field) % 32))) ? 1 : 0) + +#define FAL_ACL_UDF_MAX_LENGTH 16 + + /** + * @brief This structure defines the Acl rule. + * @details Fields description: + * + * + * vid_val - If vid_op equals FAL_ACL_FIELD_MASK it's vlan id field value. + * If vid_op equals FAL_ACL_FIELD_RANGE it's vlan id field low value. If + * vid_op equals other value it's the compared value. + * + * vid_mask - If vid_op equals FAL_ACL_FIELD_MASK it's vlan id field mask. + * If vid_op equals FAL_ACL_FIELD_RANGE it's vlan id field high value. If vid_op + * equals other value it's meaningless. + * + * + * ip_dscp_val - It's eight bits field we can set any value between 0 - 255. + * ip_dscp_mask - It's eight bits field we can set any value between 0 - 255. + * + * + * src_l4port_val - If src_l4port_op equals FAL_ACL_FIELD_MASK it's layer four + * source port field value. If src_l4port_op equals FAL_ACL_FIELD_RANGE it's + * layer four source port field low value. If src_l4port_op equals other value + * it's the compared value. + * + * + * src_l4port_mask - If src_l4port_op equals FAL_ACL_FIELD_MASK it's layer four + * source port field mask. If src_l4port_op equals FAL_ACL_FIELD_RANGE it's + * layer four source port field high value. If src_l4port_op equals other value + * it's meaningless. + * + * + * dest_l4port_val - If dest_l4port_op equals FAL_ACL_FIELD_MASK it's layer four + * destination port field value. If dest_l4port_op equals FAL_ACL_FIELD_RANGE it's + * layer four source port field low value. If dest_l4port_op equals other value + * it's the compared value. + * + * + * dest_l4port_mask - If dest_l4port_op equals FAL_ACL_FIELD_MASK it's layer four + * source port field mask. If dest_l4port_op equals FAL_ACL_FIELD_RANGE it's + * layer four source port field high value. If dest_l4port_op equals other value + * it's meaningless. + * + * + * ports - If FAL_ACL_ACTION_REDPT bit is setted in action_flg it's redirect + * destination ports. + * + * + * dot1p - If FAL_ACL_ACTION_REMARK_DOT1P bit is setted in action_flg it's + * the expected dot1p value. + * + * + * queue - If FAL_ACL_ACTION_REMARK_QUEUE bit is setted in action_flg it's + * the expected queue value. + * + * + * vid - If FAL_ACL_ACTION_MODIFY_VLAN or FAL_ACL_ACTION_NEST_VLAN bit is + * setted in action_flg it's the expected vlan id value. + */ + typedef struct + { + fal_acl_rule_type_t rule_type; + fal_acl_field_map_t field_flg; + + /* fields of mac rule */ + fal_mac_addr_t src_mac_val; + fal_mac_addr_t src_mac_mask; + fal_mac_addr_t dest_mac_val; + fal_mac_addr_t dest_mac_mask; + a_uint16_t ethtype_val; + a_uint16_t ethtype_mask; + a_uint16_t vid_val; + a_uint16_t vid_mask; + fal_acl_field_op_t vid_op; + a_uint8_t tagged_val; + a_uint8_t tagged_mask; + a_uint8_t up_val; + a_uint8_t up_mask; + a_uint8_t cfi_val; + a_uint8_t cfi_mask; + a_uint16_t resv0; + + /* fields of enhanced mac rule*/ + a_uint8_t stagged_val; /*for s17c : 0-untag, 1-tag, for hawkeye: 2-pritag, 3-utag+pritag, 4- untag+tag, 5-tag+pritag, 6-all*/ + a_uint8_t stagged_mask; + a_uint8_t ctagged_val; + a_uint8_t ctagged_mask; + a_uint16_t stag_vid_val; + a_uint16_t stag_vid_mask; + fal_acl_field_op_t stag_vid_op; + a_uint16_t ctag_vid_val; + a_uint16_t ctag_vid_mask; + fal_acl_field_op_t ctag_vid_op; + a_uint8_t stag_pri_val; + a_uint8_t stag_pri_mask; + a_uint8_t ctag_pri_val; + a_uint8_t ctag_pri_mask; + a_uint8_t stag_dei_val; + a_uint8_t stag_dei_mask; + a_uint8_t ctag_cfi_val; + a_uint8_t ctag_cfi_mask; + + + /* fields of ip4 rule */ + fal_ip4_addr_t src_ip4_val; + fal_ip4_addr_t src_ip4_mask; + fal_ip4_addr_t dest_ip4_val; + fal_ip4_addr_t dest_ip4_mask; + + /* fields of ip6 rule */ + a_uint32_t ip6_lable_val; + a_uint32_t ip6_lable_mask; + fal_ip6_addr_t src_ip6_val; + fal_ip6_addr_t src_ip6_mask; + fal_ip6_addr_t dest_ip6_val; + fal_ip6_addr_t dest_ip6_mask; + + /* fields of ip rule */ + a_uint8_t ip_proto_val; + a_uint8_t ip_proto_mask; + a_uint8_t ip_dscp_val; + a_uint8_t ip_dscp_mask; + + /* fields of layer four */ + a_uint16_t src_l4port_val; + a_uint16_t src_l4port_mask; + fal_acl_field_op_t src_l4port_op; + a_uint16_t dest_l4port_val; + a_uint16_t dest_l4port_mask; + fal_acl_field_op_t dest_l4port_op; + a_uint8_t icmp_type_val; + a_uint8_t icmp_type_mask; + a_uint8_t icmp_code_val; + a_uint8_t icmp_code_mask; + a_uint8_t tcp_flag_val; + a_uint8_t tcp_flag_mask; + a_uint8_t ripv1_val; + a_uint8_t ripv1_mask; + a_uint8_t dhcpv4_val; + a_uint8_t dhcpv4_mask; + a_uint8_t dhcpv6_val; + a_uint8_t dhcpv6_mask; + + /* user defined fields */ + fal_acl_udf_type_t udf_type; + a_uint8_t udf_offset; + a_uint8_t udf_len; + a_uint8_t udf_val[FAL_ACL_UDF_MAX_LENGTH]; + a_uint8_t udf_mask[FAL_ACL_UDF_MAX_LENGTH]; + + /* fields of action */ + fal_acl_action_map_t action_flg; + fal_pbmp_t ports; /*high 8bits, 00-port bitmap, 01-nexthop, 10-vp*/ + a_uint32_t match_cnt; + a_uint16_t vid; + a_uint8_t up; + a_uint8_t queue; + a_uint16_t stag_vid; + a_uint8_t stag_pri; + a_uint8_t stag_dei; + a_uint16_t ctag_vid; + a_uint8_t ctag_pri; + a_uint8_t ctag_cfi; + a_uint16_t policer_ptr; + a_uint16_t arp_ptr; + a_uint16_t wcmp_ptr; + a_uint8_t dscp; + a_uint8_t rsv; + fal_policy_forward_t policy_fwd; + fal_combined_t combined; + + /*new add match fields for hawkeye*/ + a_uint8_t pri; /*rule priority 0-7*/ + a_bool_t post_routing; + a_uint8_t acl_pool; + + a_bool_t is_ip_val; + a_uint8_t is_ip_mask; + + a_bool_t is_ipv6_val; + a_uint8_t is_ipv6_mask; + + a_bool_t is_fake_mac_header_val; + a_uint8_t is_fake_mac_header_mask; + + a_bool_t is_snap_val; + a_uint8_t is_snap_mask; + + a_bool_t is_ethernet_val; + a_uint8_t is_ethernet_mask; + + a_bool_t is_fragement_val; + a_uint8_t is_fragement_mask; + + a_bool_t is_ah_header_val; + a_uint8_t is_ah_header_mask; + + a_bool_t is_esp_header_val; + a_uint8_t is_esp_header_mask; + + a_bool_t is_mobility_header_val; + a_uint8_t is_mobility_header_mask; + + a_bool_t is_fragment_header_val; + a_uint8_t is_fragment_header_mask; + + a_bool_t is_other_header_val; + a_uint8_t is_other_header_mask; + + a_bool_t is_ipv4_option_val; + a_uint8_t is_ipv4_option_mask; + + a_bool_t is_first_frag_val; + a_uint8_t is_first_frag_mask; + + /*fields of VLAN rule*/ + a_bool_t vsi_valid; + a_uint8_t vsi_valid_mask; + a_uint8_t vsi; /*0-31*/ + a_uint8_t vsi_mask; /*0-31*/ + /*fields of L2 MISC rule*/ + a_uint16_t pppoe_sessionid; + a_uint16_t pppoe_sessionid_mask; + fal_acl_field_op_t icmp_type_code_op; + /*fields of IP MISC rule*/ + a_uint8_t l3_ttl; + a_uint8_t l3_ttl_mask; + fal_acl_field_op_t l3_length_op; + a_uint16_t l3_length; + a_uint16_t l3_length_mask; + a_uint16_t l3_pkt_type; + a_uint16_t l3_pkt_type_mask; + /*field of udf*/ + fal_acl_field_op_t udf0_op; + a_uint16_t udf0_val; + a_uint16_t udf0_mask; + fal_acl_field_op_t udf1_op; + a_uint16_t udf1_val; + a_uint16_t udf1_mask; + a_uint16_t udf2_val; + a_uint16_t udf2_mask; + a_uint16_t udf3_val; + a_uint16_t udf3_mask; + + /*new add acl action for hawkeye*/ + a_uint32_t bypass_bitmap; + a_uint8_t enqueue_pri; + a_uint8_t stag_fmt; + a_uint8_t ctag_fmt; + a_uint8_t int_dp; + a_uint8_t service_code; + a_uint8_t cpu_code; + a_uint64_t match_bytes; + /*new add acl action for IPQ60xx*/ + a_uint8_t dscp_mask; + a_uint8_t qos_res_prec; + } fal_acl_rule_t; + + + /** + @brief This enum defines the ACL will work on which derection traffic. + */ + typedef enum + { + FAL_ACL_DIREC_IN = 0, /**< Acl will work on ingressive traffic */ + FAL_ACL_DIREC_EG, /**< Acl will work on egressive traffic */ + FAL_ACL_DIREC_BOTH, /**< Acl will work on both ingressive and egressive traffic*/ + } fal_acl_direc_t; + + + /** + @brief This enum defines the ACL will work on which partiualr object. + */ + typedef enum + { + FAL_ACL_BIND_PORT = 0, /**< Acl wil work on particular port and virtual port */ + FAL_ACL_BIND_PORTBITMAP = 1, /**< Acl wil work on port bitmap */ + FAL_ACL_BIND_SERVICE_CODE = 2, /**< Acl wil work on service code */ + FAL_ACL_BIND_L3_IF = 3, /**< Acl wil work on l3 interface */ + } fal_acl_bind_obj_t; + +enum +{ + /*acl*/ + FUNC_ACL_LIST_CREAT = 0, + FUNC_ACL_LIST_DESTROY, + FUNC_ACL_RULE_ADD, + FUNC_ACL_RULE_DELETE, + FUNC_ACL_RULE_QUERY, + FUNC_ACL_RULE_DUMP, + FUNC_ACL_LIST_BIND, + FUNC_ACL_LIST_UNBIND, + FUNC_ACL_LIST_DUMP, + FUNC_ACL_UDF_PROFILE_SET, + FUNC_ACL_UDF_PROFILE_GET, +}; + + +sw_error_t +fal_acl_list_creat(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t list_pri); + +sw_error_t +fal_acl_list_destroy(a_uint32_t dev_id, a_uint32_t list_id); + +sw_error_t +fal_acl_rule_add(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t rule_id, a_uint32_t rule_nr, fal_acl_rule_t * rule); + +sw_error_t +fal_acl_rule_delete(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t rule_id, a_uint32_t rule_nr); + +sw_error_t +fal_acl_rule_query(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t rule_id, fal_acl_rule_t * rule); + +sw_error_t +fal_acl_list_bind(a_uint32_t dev_id, a_uint32_t list_id, fal_acl_direc_t direc, fal_acl_bind_obj_t obj_t, a_uint32_t obj_idx); + +sw_error_t +fal_acl_list_unbind(a_uint32_t dev_id, a_uint32_t list_id, fal_acl_direc_t direc, fal_acl_bind_obj_t obj_t, a_uint32_t obj_idx); + +sw_error_t +fal_acl_status_set(a_uint32_t dev_id, a_bool_t enable); + +sw_error_t +fal_acl_status_get(a_uint32_t dev_id, a_bool_t * enable); + +sw_error_t +fal_acl_list_dump(a_uint32_t dev_id); + +sw_error_t +fal_acl_rule_dump(a_uint32_t dev_id); + +sw_error_t +fal_acl_port_udf_profile_set(a_uint32_t dev_id, fal_port_t port_id, fal_acl_udf_type_t udf_type, a_uint32_t offset, a_uint32_t length); +sw_error_t +fal_acl_port_udf_profile_get(a_uint32_t dev_id, fal_port_t port_id, fal_acl_udf_type_t udf_type, a_uint32_t * offset, a_uint32_t * length); + +sw_error_t +fal_acl_udf_profile_set(a_uint32_t dev_id, fal_acl_udf_pkt_type_t pkt_type,a_uint32_t udf_idx, fal_acl_udf_type_t udf_type, a_uint32_t offset); + +sw_error_t +fal_acl_udf_profile_get(a_uint32_t dev_id, fal_acl_udf_pkt_type_t pkt_type,a_uint32_t udf_idx, fal_acl_udf_type_t *udf_type, a_uint32_t *offset); + +sw_error_t +fal_acl_rule_active(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t rule_id, a_uint32_t rule_nr); +sw_error_t +fal_acl_rule_deactive(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t rule_id, a_uint32_t rule_nr); +sw_error_t +fal_acl_rule_src_filter_sts_set(a_uint32_t dev_id, a_uint32_t rule_id, a_bool_t enable); +sw_error_t +fal_acl_rule_src_filter_sts_get(a_uint32_t dev_id, a_uint32_t rule_id, a_bool_t* enable); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_ACL_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_api.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_api.h new file mode 100755 index 000000000..2a8121db2 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_api.h @@ -0,0 +1,2115 @@ +/* + * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/*qca808x_start*/ +#ifndef _FAL_API_H_ +#define _FAL_API_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +/*qca808x_end*/ +#ifdef IN_PORTCONTROL +/*qca808x_start*/ +#define PORTCONTROL_API \ + SW_API_DEF(SW_API_PT_DUPLEX_GET, fal_port_duplex_get), \ + SW_API_DEF(SW_API_PT_DUPLEX_SET, fal_port_duplex_set), \ + SW_API_DEF(SW_API_PT_SPEED_GET, fal_port_speed_get), \ + SW_API_DEF(SW_API_PT_SPEED_SET, fal_port_speed_set), \ + SW_API_DEF(SW_API_PT_AN_GET, fal_port_autoneg_status_get), \ + SW_API_DEF(SW_API_PT_AN_ENABLE, fal_port_autoneg_enable), \ + SW_API_DEF(SW_API_PT_AN_RESTART, fal_port_autoneg_restart), \ + SW_API_DEF(SW_API_PT_AN_ADV_GET, fal_port_autoneg_adv_get), \ + SW_API_DEF(SW_API_PT_AN_ADV_SET, fal_port_autoneg_adv_set), \ +/*qca808x_end*/\ + SW_API_DEF(SW_API_PT_HDR_SET, fal_port_hdr_status_set), \ + SW_API_DEF(SW_API_PT_HDR_GET, fal_port_hdr_status_get), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_SET, fal_port_flowctrl_set), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_GET, fal_port_flowctrl_get), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_MODE_SET, fal_port_flowctrl_forcemode_set), \ + SW_API_DEF(SW_API_PT_FLOWCTRL_MODE_GET, fal_port_flowctrl_forcemode_get), \ + SW_API_DEF(SW_API_PT_POWERSAVE_SET, fal_port_powersave_set), \ + SW_API_DEF(SW_API_PT_POWERSAVE_GET, fal_port_powersave_get), \ +/*qca808x_start*/\ + SW_API_DEF(SW_API_PT_HIBERNATE_SET, fal_port_hibernate_set), \ + SW_API_DEF(SW_API_PT_HIBERNATE_GET, fal_port_hibernate_get), \ + SW_API_DEF(SW_API_PT_CDT, fal_port_cdt), \ +/*qca808x_end*/\ + SW_API_DEF(SW_API_PT_TXHDR_SET, fal_port_txhdr_mode_set), \ + SW_API_DEF(SW_API_PT_TXHDR_GET, fal_port_txhdr_mode_get), \ + SW_API_DEF(SW_API_PT_RXHDR_SET, fal_port_rxhdr_mode_set), \ + SW_API_DEF(SW_API_PT_RXHDR_GET, fal_port_rxhdr_mode_get), \ + SW_API_DEF(SW_API_HEADER_TYPE_SET, fal_header_type_set), \ + SW_API_DEF(SW_API_HEADER_TYPE_GET, fal_header_type_get), \ + SW_API_DEF(SW_API_TXMAC_STATUS_SET, fal_port_txmac_status_set), \ + SW_API_DEF(SW_API_TXMAC_STATUS_GET, fal_port_txmac_status_get), \ + SW_API_DEF(SW_API_RXMAC_STATUS_SET, fal_port_rxmac_status_set), \ + SW_API_DEF(SW_API_RXMAC_STATUS_GET, fal_port_rxmac_status_get), \ + SW_API_DEF(SW_API_TXFC_STATUS_SET, fal_port_txfc_status_set), \ + SW_API_DEF(SW_API_TXFC_STATUS_GET, fal_port_txfc_status_get), \ + SW_API_DEF(SW_API_RXFC_STATUS_SET, fal_port_rxfc_status_set), \ + SW_API_DEF(SW_API_RXFC_STATUS_GET, fal_port_rxfc_status_get), \ + SW_API_DEF(SW_API_BP_STATUS_SET, fal_port_bp_status_set), \ + SW_API_DEF(SW_API_BP_STATUS_GET, fal_port_bp_status_get), \ + SW_API_DEF(SW_API_PT_LINK_MODE_SET, fal_port_link_forcemode_set), \ + SW_API_DEF(SW_API_PT_LINK_MODE_GET, fal_port_link_forcemode_get), \ +/*qca808x_start*/\ + SW_API_DEF(SW_API_PT_LINK_STATUS_GET, fal_port_link_status_get), \ +/*qca808x_end*/\ + SW_API_DEF(SW_API_PT_MAC_LOOPBACK_SET, fal_port_mac_loopback_set), \ + SW_API_DEF(SW_API_PT_MAC_LOOPBACK_GET, fal_port_mac_loopback_get), \ + SW_API_DEF(SW_API_PTS_LINK_STATUS_GET, fal_ports_link_status_get), \ + SW_API_DEF(SW_API_PT_CONGESTION_DROP_SET, fal_port_congestion_drop_set), \ + SW_API_DEF(SW_API_PT_CONGESTION_DROP_GET, fal_port_congestion_drop_get), \ + SW_API_DEF(SW_API_PT_RING_FLOW_CTRL_THRES_SET, fal_ring_flow_ctrl_thres_set), \ + SW_API_DEF(SW_API_PT_RING_FLOW_CTRL_THRES_GET, fal_ring_flow_ctrl_thres_get), \ +/*qca808x_start*/\ + SW_API_DEF(SW_API_PT_8023AZ_SET, fal_port_8023az_set), \ + SW_API_DEF(SW_API_PT_8023AZ_GET, fal_port_8023az_get), \ + SW_API_DEF(SW_API_PT_MDIX_SET, fal_port_mdix_set), \ + SW_API_DEF(SW_API_PT_MDIX_GET, fal_port_mdix_get), \ + SW_API_DEF(SW_API_PT_MDIX_STATUS_GET, fal_port_mdix_status_get), \ +/*qca808x_end*/\ + SW_API_DEF(SW_API_PT_COMBO_PREFER_MEDIUM_SET, fal_port_combo_prefer_medium_set), \ + SW_API_DEF(SW_API_PT_COMBO_PREFER_MEDIUM_GET, fal_port_combo_prefer_medium_get), \ + SW_API_DEF(SW_API_PT_COMBO_MEDIUM_STATUS_GET, fal_port_combo_medium_status_get), \ + SW_API_DEF(SW_API_PT_COMBO_FIBER_MODE_SET, fal_port_combo_fiber_mode_set), \ + SW_API_DEF(SW_API_PT_COMBO_FIBER_MODE_GET, fal_port_combo_fiber_mode_get), \ +/*qca808x_start*/\ + SW_API_DEF(SW_API_PT_LOCAL_LOOPBACK_SET, fal_port_local_loopback_set), \ + SW_API_DEF(SW_API_PT_LOCAL_LOOPBACK_GET, fal_port_local_loopback_get), \ + SW_API_DEF(SW_API_PT_REMOTE_LOOPBACK_SET, fal_port_remote_loopback_set), \ + SW_API_DEF(SW_API_PT_REMOTE_LOOPBACK_GET, fal_port_remote_loopback_get), \ + SW_API_DEF(SW_API_PT_RESET, fal_port_reset), \ + SW_API_DEF(SW_API_PT_POWER_OFF, fal_port_power_off), \ + SW_API_DEF(SW_API_PT_POWER_ON, fal_port_power_on), \ + SW_API_DEF(SW_API_PT_MAGIC_FRAME_MAC_SET, fal_port_magic_frame_mac_set), \ + SW_API_DEF(SW_API_PT_MAGIC_FRAME_MAC_GET, fal_port_magic_frame_mac_get), \ + SW_API_DEF(SW_API_PT_PHY_ID_GET, fal_port_phy_id_get), \ + SW_API_DEF(SW_API_PT_WOL_STATUS_SET, fal_port_wol_status_set), \ + SW_API_DEF(SW_API_PT_WOL_STATUS_GET, fal_port_wol_status_get), \ +/*qca808x_end*/\ + SW_API_DEF(SW_API_PT_INTERFACE_MODE_APPLY, fal_port_interface_mode_apply), \ + SW_API_DEF(SW_API_PT_INTERFACE_MODE_SET, fal_port_interface_mode_set), \ + SW_API_DEF(SW_API_PT_INTERFACE_MODE_GET, fal_port_interface_mode_get), \ +/*qca808x_start*/\ + SW_API_DEF(SW_API_PT_INTERFACE_MODE_STATUS_GET, fal_port_interface_mode_status_get), \ + SW_API_DEF(SW_API_DEBUG_PHYCOUNTER_SET, fal_debug_phycounter_set), \ + SW_API_DEF(SW_API_DEBUG_PHYCOUNTER_GET, fal_debug_phycounter_get), \ + SW_API_DEF(SW_API_DEBUG_PHYCOUNTER_SHOW, fal_debug_phycounter_show),\ +/*qca808x_end*/\ + SW_API_DEF(SW_API_PT_MTU_SET, fal_port_mtu_set), \ + SW_API_DEF(SW_API_PT_MTU_GET, fal_port_mtu_get), \ + SW_API_DEF(SW_API_PT_MRU_SET, fal_port_mru_set), \ + SW_API_DEF(SW_API_PT_MRU_GET, fal_port_mru_get), \ + SW_API_DEF(SW_API_PT_SOURCE_FILTER_GET, fal_port_source_filter_status_get), \ + SW_API_DEF(SW_API_PT_SOURCE_FILTER_SET, fal_port_source_filter_enable), \ + SW_API_DEF(SW_API_PT_FRAME_MAX_SIZE_GET, fal_port_max_frame_size_get), \ + SW_API_DEF(SW_API_PT_FRAME_MAX_SIZE_SET, fal_port_max_frame_size_set), \ + SW_API_DEF(SW_API_PT_INTERFACE_3AZ_STATUS_SET, fal_port_interface_3az_status_set), \ + SW_API_DEF(SW_API_PT_INTERFACE_3AZ_STATUS_GET, fal_port_interface_3az_status_get), \ + SW_API_DEF(SW_API_PT_PROMISC_MODE_SET, fal_port_promisc_mode_set), \ + SW_API_DEF(SW_API_PT_PROMISC_MODE_GET, fal_port_promisc_mode_get), \ + SW_API_DEF(SW_API_PT_INTERFACE_EEE_CFG_SET, fal_port_interface_eee_cfg_set), \ + SW_API_DEF(SW_API_PT_INTERFACE_EEE_CFG_GET, fal_port_interface_eee_cfg_get), \ + SW_API_DEF(SW_API_PT_SOURCE_FILTER_CONFIG_GET, fal_port_source_filter_config_get),\ + SW_API_DEF(SW_API_PT_SOURCE_FILTER_CONFIG_SET, fal_port_source_filter_config_set), \ + SW_API_DEF(SW_API_PT_SWITCH_PORT_LOOPBACK_SET, fal_switch_port_loopback_set), \ + SW_API_DEF(SW_API_PT_SWITCH_PORT_LOOPBACK_GET, fal_switch_port_loopback_get), +/*qca808x_start*/\ +/*end of PORTCONTROL_API*/ +#define PORTCONTROL_API_PARAM \ + SW_API_DESC(SW_API_PT_DUPLEX_GET) \ + SW_API_DESC(SW_API_PT_DUPLEX_SET) \ + SW_API_DESC(SW_API_PT_SPEED_GET) \ + SW_API_DESC(SW_API_PT_SPEED_SET) \ + SW_API_DESC(SW_API_PT_AN_GET) \ + SW_API_DESC(SW_API_PT_AN_ENABLE) \ + SW_API_DESC(SW_API_PT_AN_RESTART) \ + SW_API_DESC(SW_API_PT_AN_ADV_GET) \ + SW_API_DESC(SW_API_PT_AN_ADV_SET) \ +/*qca808x_end*/\ + SW_API_DESC(SW_API_PT_HDR_SET) \ + SW_API_DESC(SW_API_PT_HDR_GET) \ + SW_API_DESC(SW_API_PT_FLOWCTRL_SET) \ + SW_API_DESC(SW_API_PT_FLOWCTRL_GET) \ + SW_API_DESC(SW_API_PT_FLOWCTRL_MODE_SET) \ + SW_API_DESC(SW_API_PT_FLOWCTRL_MODE_GET) \ + SW_API_DESC(SW_API_PT_POWERSAVE_SET) \ + SW_API_DESC(SW_API_PT_POWERSAVE_GET) \ +/*qca808x_start*/\ + SW_API_DESC(SW_API_PT_HIBERNATE_SET) \ + SW_API_DESC(SW_API_PT_HIBERNATE_GET) \ + SW_API_DESC(SW_API_PT_CDT) \ +/*qca808x_end*/\ + SW_API_DESC(SW_API_PT_TXHDR_SET) \ + SW_API_DESC(SW_API_PT_TXHDR_GET) \ + SW_API_DESC(SW_API_PT_RXHDR_SET) \ + SW_API_DESC(SW_API_PT_RXHDR_GET) \ + SW_API_DESC(SW_API_HEADER_TYPE_SET) \ + SW_API_DESC(SW_API_HEADER_TYPE_GET) \ + SW_API_DESC(SW_API_TXMAC_STATUS_SET) \ + SW_API_DESC(SW_API_TXMAC_STATUS_GET) \ + SW_API_DESC(SW_API_RXMAC_STATUS_SET) \ + SW_API_DESC(SW_API_RXMAC_STATUS_GET) \ + SW_API_DESC(SW_API_TXFC_STATUS_SET) \ + SW_API_DESC(SW_API_TXFC_STATUS_GET) \ + SW_API_DESC(SW_API_RXFC_STATUS_SET) \ + SW_API_DESC(SW_API_RXFC_STATUS_GET) \ + SW_API_DESC(SW_API_BP_STATUS_SET) \ + SW_API_DESC(SW_API_BP_STATUS_GET) \ + SW_API_DESC(SW_API_PT_LINK_MODE_SET) \ + SW_API_DESC(SW_API_PT_LINK_MODE_GET) \ +/*qca808x_start*/\ + SW_API_DESC(SW_API_PT_LINK_STATUS_GET) \ +/*qca808x_end*/\ + SW_API_DESC(SW_API_PT_MAC_LOOPBACK_SET) \ + SW_API_DESC(SW_API_PT_MAC_LOOPBACK_GET) \ + SW_API_DESC(SW_API_PTS_LINK_STATUS_GET) \ + SW_API_DESC(SW_API_PT_CONGESTION_DROP_SET) \ + SW_API_DESC(SW_API_PT_CONGESTION_DROP_GET) \ + SW_API_DESC(SW_API_PT_RING_FLOW_CTRL_THRES_SET) \ + SW_API_DESC(SW_API_PT_RING_FLOW_CTRL_THRES_GET) \ +/*qca808x_start*/\ + SW_API_DESC(SW_API_PT_8023AZ_SET) \ + SW_API_DESC(SW_API_PT_8023AZ_GET) \ + SW_API_DESC(SW_API_PT_MDIX_SET) \ + SW_API_DESC(SW_API_PT_MDIX_GET) \ + SW_API_DESC(SW_API_PT_MDIX_STATUS_GET) \ +/*qca808x_end*/\ + SW_API_DESC(SW_API_PT_COMBO_PREFER_MEDIUM_SET) \ + SW_API_DESC(SW_API_PT_COMBO_PREFER_MEDIUM_GET) \ + SW_API_DESC(SW_API_PT_COMBO_MEDIUM_STATUS_GET) \ + SW_API_DESC(SW_API_PT_COMBO_FIBER_MODE_SET) \ + SW_API_DESC(SW_API_PT_COMBO_FIBER_MODE_GET) \ +/*qca808x_start*/\ + SW_API_DESC(SW_API_PT_LOCAL_LOOPBACK_SET) \ + SW_API_DESC(SW_API_PT_LOCAL_LOOPBACK_GET) \ + SW_API_DESC(SW_API_PT_REMOTE_LOOPBACK_SET) \ + SW_API_DESC(SW_API_PT_REMOTE_LOOPBACK_GET) \ + SW_API_DESC(SW_API_PT_RESET) \ + SW_API_DESC(SW_API_PT_POWER_OFF) \ + SW_API_DESC(SW_API_PT_POWER_ON) \ + SW_API_DESC(SW_API_PT_MAGIC_FRAME_MAC_SET) \ + SW_API_DESC(SW_API_PT_MAGIC_FRAME_MAC_GET) \ + SW_API_DESC(SW_API_PT_PHY_ID_GET) \ + SW_API_DESC(SW_API_PT_WOL_STATUS_SET) \ + SW_API_DESC(SW_API_PT_WOL_STATUS_GET) \ +/*qca808x_end*/\ + SW_API_DESC(SW_API_PT_INTERFACE_MODE_SET) \ + SW_API_DESC(SW_API_PT_INTERFACE_MODE_GET) \ + SW_API_DESC(SW_API_PT_INTERFACE_MODE_APPLY) \ +/*qca808x_start*/\ + SW_API_DESC(SW_API_PT_INTERFACE_MODE_STATUS_GET) \ + SW_API_DESC(SW_API_DEBUG_PHYCOUNTER_SET) \ + SW_API_DESC(SW_API_DEBUG_PHYCOUNTER_GET) \ + SW_API_DESC(SW_API_DEBUG_PHYCOUNTER_SHOW)\ +/*qca808x_end*/\ + SW_API_DESC(SW_API_PT_MTU_SET) \ + SW_API_DESC(SW_API_PT_MTU_GET) \ + SW_API_DESC(SW_API_PT_MRU_SET) \ + SW_API_DESC(SW_API_PT_MRU_GET) \ + SW_API_DESC(SW_API_PT_SOURCE_FILTER_GET) \ + SW_API_DESC(SW_API_PT_SOURCE_FILTER_SET) \ + SW_API_DESC(SW_API_PT_FRAME_MAX_SIZE_GET) \ + SW_API_DESC(SW_API_PT_FRAME_MAX_SIZE_SET) \ + SW_API_DESC(SW_API_PT_INTERFACE_3AZ_STATUS_SET) \ + SW_API_DESC(SW_API_PT_INTERFACE_3AZ_STATUS_GET)\ + SW_API_DESC(SW_API_PT_PROMISC_MODE_SET) \ + SW_API_DESC(SW_API_PT_PROMISC_MODE_GET) \ + SW_API_DESC(SW_API_PT_INTERFACE_EEE_CFG_SET) \ + SW_API_DESC(SW_API_PT_INTERFACE_EEE_CFG_GET) \ + SW_API_DESC(SW_API_PT_SOURCE_FILTER_CONFIG_GET) \ + SW_API_DESC(SW_API_PT_SOURCE_FILTER_CONFIG_SET) \ + SW_API_DESC(SW_API_PT_SWITCH_PORT_LOOPBACK_SET) \ + SW_API_DESC(SW_API_PT_SWITCH_PORT_LOOPBACK_GET) +/*qca808x_start*/\ +/*end of PORTCONTROL_API_PARAM*/ +/*qca808x_end*/ +#else +#define PORTCONTROL_API +#define PORTCONTROL_API_PARAM +#endif + +#ifdef IN_VLAN +#define VLAN_API \ + SW_API_DEF(SW_API_VLAN_ADD, fal_vlan_create), \ + SW_API_DEF(SW_API_VLAN_DEL, fal_vlan_delete), \ + SW_API_DEF(SW_API_VLAN_MEM_UPDATE, fal_vlan_member_update), \ + SW_API_DEF(SW_API_VLAN_FIND, fal_vlan_find), \ + SW_API_DEF(SW_API_VLAN_NEXT, fal_vlan_next), \ + SW_API_DEF(SW_API_VLAN_APPEND, fal_vlan_entry_append), \ + SW_API_DEF(SW_API_VLAN_FLUSH, fal_vlan_flush), \ + SW_API_DEF(SW_API_VLAN_FID_SET, fal_vlan_fid_set), \ + SW_API_DEF(SW_API_VLAN_FID_GET, fal_vlan_fid_get), \ + SW_API_DEF(SW_API_VLAN_MEMBER_ADD, fal_vlan_member_add), \ + SW_API_DEF(SW_API_VLAN_MEMBER_DEL, fal_vlan_member_del), \ + SW_API_DEF(SW_API_VLAN_LEARN_STATE_SET, fal_vlan_learning_state_set), \ + SW_API_DEF(SW_API_VLAN_LEARN_STATE_GET, fal_vlan_learning_state_get), + +#define VLAN_API_PARAM \ + SW_API_DESC(SW_API_VLAN_ADD) \ + SW_API_DESC(SW_API_VLAN_DEL) \ + SW_API_DESC(SW_API_VLAN_MEM_UPDATE) \ + SW_API_DESC(SW_API_VLAN_FIND) \ + SW_API_DESC(SW_API_VLAN_NEXT) \ + SW_API_DESC(SW_API_VLAN_APPEND) \ + SW_API_DESC(SW_API_VLAN_FLUSH) \ + SW_API_DESC(SW_API_VLAN_FID_SET) \ + SW_API_DESC(SW_API_VLAN_FID_GET) \ + SW_API_DESC(SW_API_VLAN_MEMBER_ADD) \ + SW_API_DESC(SW_API_VLAN_MEMBER_DEL) \ + SW_API_DESC(SW_API_VLAN_LEARN_STATE_SET) \ + SW_API_DESC(SW_API_VLAN_LEARN_STATE_GET) +#else +#define VLAN_API +#define VLAN_API_PARAM +#endif + +#ifdef IN_PORTVLAN +#define PORTVLAN_API \ + SW_API_DEF(SW_API_PT_ING_MODE_GET, fal_port_1qmode_get), \ + SW_API_DEF(SW_API_PT_ING_MODE_SET, fal_port_1qmode_set), \ + SW_API_DEF(SW_API_PT_EG_MODE_GET, fal_port_egvlanmode_get), \ + SW_API_DEF(SW_API_PT_EG_MODE_SET, fal_port_egvlanmode_set), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_ADD, fal_portvlan_member_add), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_DEL, fal_portvlan_member_del), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_UPDATE, fal_portvlan_member_update), \ + SW_API_DEF(SW_API_PT_VLAN_MEM_GET, fal_portvlan_member_get), \ + SW_API_DEF(SW_API_PT_DEF_VID_SET, fal_port_default_vid_set), \ + SW_API_DEF(SW_API_PT_DEF_VID_GET, fal_port_default_vid_get), \ + SW_API_DEF(SW_API_PT_FORCE_DEF_VID_SET, fal_port_force_default_vid_set), \ + SW_API_DEF(SW_API_PT_FORCE_DEF_VID_GET, fal_port_force_default_vid_get), \ + SW_API_DEF(SW_API_PT_FORCE_PORTVLAN_SET, fal_port_force_portvlan_set), \ + SW_API_DEF(SW_API_PT_FORCE_PORTVLAN_GET, fal_port_force_portvlan_get), \ + SW_API_DEF(SW_API_PT_NESTVLAN_SET, fal_port_nestvlan_set), \ + SW_API_DEF(SW_API_PT_NESTVLAN_GET, fal_port_nestvlan_get), \ + SW_API_DEF(SW_API_NESTVLAN_TPID_SET, fal_nestvlan_tpid_set), \ + SW_API_DEF(SW_API_NESTVLAN_TPID_GET, fal_nestvlan_tpid_get), \ + SW_API_DEF(SW_API_PT_IN_VLAN_MODE_SET, fal_port_invlan_mode_set), \ + SW_API_DEF(SW_API_PT_IN_VLAN_MODE_GET, fal_port_invlan_mode_get), \ + SW_API_DEF(SW_API_PT_TLS_SET, fal_port_tls_set), \ + SW_API_DEF(SW_API_PT_TLS_GET, fal_port_tls_get), \ + SW_API_DEF(SW_API_PT_PRI_PROPAGATION_SET, fal_port_pri_propagation_set), \ + SW_API_DEF(SW_API_PT_PRI_PROPAGATION_GET, fal_port_pri_propagation_get), \ + SW_API_DEF(SW_API_PT_DEF_SVID_SET, fal_port_default_svid_set), \ + SW_API_DEF(SW_API_PT_DEF_SVID_GET, fal_port_default_svid_get), \ + SW_API_DEF(SW_API_PT_DEF_CVID_SET, fal_port_default_cvid_set), \ + SW_API_DEF(SW_API_PT_DEF_CVID_GET, fal_port_default_cvid_get), \ + SW_API_DEF(SW_API_PT_VLAN_PROPAGATION_SET, fal_port_vlan_propagation_set), \ + SW_API_DEF(SW_API_PT_VLAN_PROPAGATION_GET, fal_port_vlan_propagation_get), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_ADD, fal_port_vlan_trans_add), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_DEL, fal_port_vlan_trans_del), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_GET, fal_port_vlan_trans_get), \ + SW_API_DEF(SW_API_QINQ_MODE_SET, fal_qinq_mode_set), \ + SW_API_DEF(SW_API_QINQ_MODE_GET, fal_qinq_mode_get), \ + SW_API_DEF(SW_API_PT_QINQ_ROLE_SET, fal_port_qinq_role_set), \ + SW_API_DEF(SW_API_PT_QINQ_ROLE_GET, fal_port_qinq_role_get), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_ITERATE, fal_port_vlan_trans_iterate), \ + SW_API_DEF(SW_API_PT_MAC_VLAN_XLT_SET, fal_port_mac_vlan_xlt_set), \ + SW_API_DEF(SW_API_PT_MAC_VLAN_XLT_GET, fal_port_mac_vlan_xlt_get), \ + SW_API_DEF(SW_API_NETISOLATE_SET, fal_netisolate_set), \ + SW_API_DEF(SW_API_NETISOLATE_GET, fal_netisolate_get), \ + SW_API_DEF(SW_API_EG_FLTR_BYPASS_EN_SET, fal_eg_trans_filter_bypass_en_set), \ + SW_API_DEF(SW_API_EG_FLTR_BYPASS_EN_GET, fal_eg_trans_filter_bypass_en_get), \ + SW_API_DEF(SW_API_PT_VRF_ID_SET, fal_port_vrf_id_set), \ + SW_API_DEF(SW_API_PT_VRF_ID_GET, fal_port_vrf_id_get), \ + SW_API_DEF(SW_API_GLOBAL_QINQ_MODE_SET, fal_global_qinq_mode_set), \ + SW_API_DEF(SW_API_GLOBAL_QINQ_MODE_GET, fal_global_qinq_mode_get), \ + SW_API_DEF(SW_API_PORT_QINQ_MODE_SET, fal_port_qinq_mode_set), \ + SW_API_DEF(SW_API_PORT_QINQ_MODE_GET, fal_port_qinq_mode_get), \ + SW_API_DEF(SW_API_TPID_SET, fal_ingress_tpid_set), \ + SW_API_DEF(SW_API_TPID_GET, fal_ingress_tpid_get), \ + SW_API_DEF(SW_API_EGRESS_TPID_SET, fal_egress_tpid_set), \ + SW_API_DEF(SW_API_EGRESS_TPID_GET, fal_egress_tpid_get), \ + SW_API_DEF(SW_API_PT_INGRESS_VLAN_FILTER_SET, fal_port_ingress_vlan_filter_set), \ + SW_API_DEF(SW_API_PT_INGRESS_VLAN_FILTER_GET, fal_port_ingress_vlan_filter_get), \ + SW_API_DEF(SW_API_PT_DEFAULT_VLANTAG_SET, fal_port_default_vlantag_set), \ + SW_API_DEF(SW_API_PT_DEFAULT_VLANTAG_GET, fal_port_default_vlantag_get), \ + SW_API_DEF(SW_API_PT_TAG_PROPAGATION_SET, fal_port_tag_propagation_set), \ + SW_API_DEF(SW_API_PT_TAG_PROPAGATION_GET, fal_port_tag_propagation_get), \ + SW_API_DEF(SW_API_PT_VLANTAG_EGMODE_SET, fal_port_vlantag_egmode_set), \ + SW_API_DEF(SW_API_PT_VLANTAG_EGMODE_GET, fal_port_vlantag_egmode_get), \ + SW_API_DEF(SW_API_PT_VLAN_XLT_MISS_CMD_SET, fal_port_vlan_xlt_miss_cmd_set), \ + SW_API_DEF(SW_API_PT_VLAN_XLT_MISS_CMD_GET, fal_port_vlan_xlt_miss_cmd_get), \ + SW_API_DEF(SW_API_PT_VSI_EGMODE_SET, fal_port_vsi_egmode_set), \ + SW_API_DEF(SW_API_PT_VSI_EGMODE_GET, fal_port_vsi_egmode_get), \ + SW_API_DEF(SW_API_PT_VLANTAG_VSI_EGMODE_EN_SET, fal_port_vlantag_vsi_egmode_enable), \ + SW_API_DEF(SW_API_PT_VLANTAG_VSI_EGMODE_EN_GET, fal_port_vlantag_vsi_egmode_status_get), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_ADV_ADD, fal_port_vlan_trans_adv_add), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_ADV_DEL, fal_port_vlan_trans_adv_del), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_ADV_GETFIRST, fal_port_vlan_trans_adv_getfirst), \ + SW_API_DEF(SW_API_PT_VLAN_TRANS_ADV_GETNEXT, fal_port_vlan_trans_adv_getnext), \ + SW_API_DEF(SW_API_PT_VLAN_COUNTER_GET, fal_port_vlan_counter_get), \ + SW_API_DEF(SW_API_PT_VLAN_COUNTER_CLEANUP, fal_port_vlan_counter_cleanup), + +#define PORTVLAN_API_PARAM \ + SW_API_DESC(SW_API_PT_ING_MODE_GET) \ + SW_API_DESC(SW_API_PT_ING_MODE_SET) \ + SW_API_DESC(SW_API_PT_EG_MODE_GET) \ + SW_API_DESC(SW_API_PT_EG_MODE_SET) \ + SW_API_DESC(SW_API_PT_VLAN_MEM_ADD) \ + SW_API_DESC(SW_API_PT_VLAN_MEM_DEL) \ + SW_API_DESC(SW_API_PT_VLAN_MEM_UPDATE) \ + SW_API_DESC(SW_API_PT_VLAN_MEM_GET) \ + SW_API_DESC(SW_API_PT_DEF_VID_SET) \ + SW_API_DESC(SW_API_PT_DEF_VID_GET) \ + SW_API_DESC(SW_API_PT_FORCE_DEF_VID_SET) \ + SW_API_DESC(SW_API_PT_FORCE_DEF_VID_GET) \ + SW_API_DESC(SW_API_PT_FORCE_PORTVLAN_SET) \ + SW_API_DESC(SW_API_PT_FORCE_PORTVLAN_GET) \ + SW_API_DESC(SW_API_PT_NESTVLAN_SET) \ + SW_API_DESC(SW_API_PT_NESTVLAN_GET) \ + SW_API_DESC(SW_API_NESTVLAN_TPID_SET) \ + SW_API_DESC(SW_API_NESTVLAN_TPID_GET) \ + SW_API_DESC(SW_API_PT_IN_VLAN_MODE_SET) \ + SW_API_DESC(SW_API_PT_IN_VLAN_MODE_GET) \ + SW_API_DESC(SW_API_PT_TLS_SET) \ + SW_API_DESC(SW_API_PT_TLS_GET) \ + SW_API_DESC(SW_API_PT_PRI_PROPAGATION_SET) \ + SW_API_DESC(SW_API_PT_PRI_PROPAGATION_GET) \ + SW_API_DESC(SW_API_PT_DEF_SVID_SET) \ + SW_API_DESC(SW_API_PT_DEF_SVID_GET) \ + SW_API_DESC(SW_API_PT_DEF_CVID_SET) \ + SW_API_DESC(SW_API_PT_DEF_CVID_GET) \ + SW_API_DESC(SW_API_PT_VLAN_PROPAGATION_SET) \ + SW_API_DESC(SW_API_PT_VLAN_PROPAGATION_GET) \ + SW_API_DESC(SW_API_PT_VLAN_TRANS_ADD) \ + SW_API_DESC(SW_API_PT_VLAN_TRANS_DEL) \ + SW_API_DESC(SW_API_PT_VLAN_TRANS_GET) \ + SW_API_DESC(SW_API_QINQ_MODE_SET) \ + SW_API_DESC(SW_API_QINQ_MODE_GET) \ + SW_API_DESC(SW_API_PT_QINQ_ROLE_SET) \ + SW_API_DESC(SW_API_PT_QINQ_ROLE_GET) \ + SW_API_DESC(SW_API_PT_VLAN_TRANS_ITERATE) \ + SW_API_DESC(SW_API_PT_MAC_VLAN_XLT_SET) \ + SW_API_DESC(SW_API_PT_MAC_VLAN_XLT_GET) \ + SW_API_DESC(SW_API_NETISOLATE_SET) \ + SW_API_DESC(SW_API_NETISOLATE_GET) \ + SW_API_DESC(SW_API_EG_FLTR_BYPASS_EN_SET) \ + SW_API_DESC(SW_API_EG_FLTR_BYPASS_EN_GET) \ + SW_API_DESC(SW_API_PT_VRF_ID_SET) \ + SW_API_DESC(SW_API_PT_VRF_ID_GET) \ + SW_API_DESC(SW_API_GLOBAL_QINQ_MODE_SET) \ + SW_API_DESC(SW_API_GLOBAL_QINQ_MODE_GET) \ + SW_API_DESC(SW_API_PORT_QINQ_MODE_SET) \ + SW_API_DESC(SW_API_PORT_QINQ_MODE_GET) \ + SW_API_DESC(SW_API_TPID_SET) \ + SW_API_DESC(SW_API_TPID_GET) \ + SW_API_DESC(SW_API_EGRESS_TPID_SET) \ + SW_API_DESC(SW_API_EGRESS_TPID_GET) \ + SW_API_DESC(SW_API_PT_INGRESS_VLAN_FILTER_SET) \ + SW_API_DESC(SW_API_PT_INGRESS_VLAN_FILTER_GET) \ + SW_API_DESC(SW_API_PT_DEFAULT_VLANTAG_SET) \ + SW_API_DESC(SW_API_PT_DEFAULT_VLANTAG_GET) \ + SW_API_DESC(SW_API_PT_TAG_PROPAGATION_SET) \ + SW_API_DESC(SW_API_PT_TAG_PROPAGATION_GET) \ + SW_API_DESC(SW_API_PT_VLANTAG_EGMODE_SET) \ + SW_API_DESC(SW_API_PT_VLANTAG_EGMODE_GET) \ + SW_API_DESC(SW_API_PT_VLAN_XLT_MISS_CMD_SET) \ + SW_API_DESC(SW_API_PT_VLAN_XLT_MISS_CMD_GET) \ + SW_API_DESC(SW_API_PT_VSI_EGMODE_SET) \ + SW_API_DESC(SW_API_PT_VSI_EGMODE_GET) \ + SW_API_DESC(SW_API_PT_VLANTAG_VSI_EGMODE_EN_SET) \ + SW_API_DESC(SW_API_PT_VLANTAG_VSI_EGMODE_EN_GET) \ + SW_API_DESC(SW_API_PT_VLAN_TRANS_ADV_ADD) \ + SW_API_DESC(SW_API_PT_VLAN_TRANS_ADV_DEL) \ + SW_API_DESC(SW_API_PT_VLAN_TRANS_ADV_GETFIRST) \ + SW_API_DESC(SW_API_PT_VLAN_TRANS_ADV_GETNEXT) \ + SW_API_DESC(SW_API_PT_VLAN_COUNTER_GET) \ + SW_API_DESC(SW_API_PT_VLAN_COUNTER_CLEANUP) + + +#else +#define PORTVLAN_API +#define PORTVLAN_API_PARAM +#endif + +#ifdef IN_FDB +#define FDB_API \ + SW_API_DEF(SW_API_FDB_ADD, fal_fdb_entry_add), \ + SW_API_DEF(SW_API_FDB_DELALL, fal_fdb_entry_flush), \ + SW_API_DEF(SW_API_FDB_DELPORT,fal_fdb_entry_del_byport), \ + SW_API_DEF(SW_API_FDB_DELMAC, fal_fdb_entry_del_bymac), \ + SW_API_DEF(SW_API_FDB_FIRST, fal_fdb_entry_getfirst), \ + SW_API_DEF(SW_API_FDB_NEXT, fal_fdb_entry_getnext), \ + SW_API_DEF(SW_API_FDB_FIND, fal_fdb_entry_search), \ + SW_API_DEF(SW_API_FDB_PT_LEARN_SET, fal_fdb_port_learn_set), \ + SW_API_DEF(SW_API_FDB_PT_LEARN_GET, fal_fdb_port_learn_get), \ + SW_API_DEF(SW_API_FDB_PT_NEWADDR_LEARN_SET, fal_fdb_port_learning_ctrl_set), \ + SW_API_DEF(SW_API_FDB_PT_NEWADDR_LEARN_GET, fal_fdb_port_learning_ctrl_get), \ + SW_API_DEF(SW_API_FDB_PT_STAMOVE_SET, fal_fdb_port_stamove_ctrl_set), \ + SW_API_DEF(SW_API_FDB_PT_STAMOVE_GET, fal_fdb_port_stamove_ctrl_get), \ + SW_API_DEF(SW_API_FDB_AGE_CTRL_SET, fal_fdb_aging_ctrl_set), \ + SW_API_DEF(SW_API_FDB_AGE_CTRL_GET, fal_fdb_aging_ctrl_get), \ + SW_API_DEF(SW_API_FDB_LEARN_CTRL_SET, fal_fdb_learning_ctrl_set), \ + SW_API_DEF(SW_API_FDB_LEARN_CTRL_GET, fal_fdb_learning_ctrl_get), \ + SW_API_DEF(SW_API_FDB_VLAN_IVL_SVL_SET, fal_fdb_vlan_ivl_svl_set),\ + SW_API_DEF(SW_API_FDB_VLAN_IVL_SVL_GET, fal_fdb_vlan_ivl_svl_get),\ + SW_API_DEF(SW_API_FDB_AGE_TIME_SET, fal_fdb_aging_time_set), \ + SW_API_DEF(SW_API_FDB_AGE_TIME_GET, fal_fdb_aging_time_get), \ + SW_API_DEF(SW_API_FDB_ITERATE, fal_fdb_entry_getnext_byindex), \ + SW_API_DEF(SW_API_FDB_EXTEND_NEXT, fal_fdb_entry_extend_getnext), \ + SW_API_DEF(SW_API_FDB_EXTEND_FIRST, fal_fdb_entry_extend_getfirst), \ + SW_API_DEF(SW_API_FDB_TRANSFER, fal_fdb_entry_update_byport), \ + SW_API_DEF(SW_API_PT_FDB_LEARN_COUNTER_GET, fal_fdb_port_learned_mac_counter_get), \ + SW_API_DEF(SW_API_PT_FDB_LEARN_LIMIT_SET, fal_port_fdb_learn_limit_set), \ + SW_API_DEF(SW_API_PT_FDB_LEARN_LIMIT_GET, fal_port_fdb_learn_limit_get), \ + SW_API_DEF(SW_API_PT_FDB_LEARN_EXCEED_CMD_SET, fal_port_fdb_learn_exceed_cmd_set), \ + SW_API_DEF(SW_API_PT_FDB_LEARN_EXCEED_CMD_GET, fal_port_fdb_learn_exceed_cmd_get), \ + SW_API_DEF(SW_API_FDB_LEARN_LIMIT_SET, fal_fdb_learn_limit_set), \ + SW_API_DEF(SW_API_FDB_LEARN_LIMIT_GET, fal_fdb_learn_limit_get), \ + SW_API_DEF(SW_API_FDB_LEARN_EXCEED_CMD_SET, fal_fdb_learn_exceed_cmd_set), \ + SW_API_DEF(SW_API_FDB_LEARN_EXCEED_CMD_GET, fal_fdb_learn_exceed_cmd_get), \ + SW_API_DEF(SW_API_FDB_RESV_ADD, fal_fdb_resv_add), \ + SW_API_DEF(SW_API_FDB_RESV_DEL, fal_fdb_resv_del), \ + SW_API_DEF(SW_API_FDB_RESV_FIND, fal_fdb_resv_find), \ + SW_API_DEF(SW_API_FDB_RESV_ITERATE, fal_fdb_resv_iterate), \ + SW_API_DEF(SW_API_FDB_PT_LEARN_STATIC_SET, fal_fdb_port_learn_static_set), \ + SW_API_DEF(SW_API_FDB_PT_LEARN_STATIC_GET, fal_fdb_port_learn_static_get), \ + SW_API_DEF(SW_API_FDB_PORT_ADD, fal_fdb_port_add), \ + SW_API_DEF(SW_API_FDB_PORT_DEL, fal_fdb_port_del), \ + SW_API_DEF(SW_API_FDB_RFS_SET, fal_fdb_rfs_set), \ + SW_API_DEF(SW_API_FDB_RFS_DEL, fal_fdb_rfs_del), \ + SW_API_DEF(SW_API_FDB_PT_MACLIMIT_CTRL_SET, fal_fdb_port_maclimit_ctrl_set), \ + SW_API_DEF(SW_API_FDB_PT_MACLIMIT_CTRL_GET, fal_fdb_port_maclimit_ctrl_get), \ + SW_API_DEF(SW_API_FDB_DEL_BY_FID, fal_fdb_entry_del_byfid), + +#define FDB_API_PARAM \ + SW_API_DESC(SW_API_FDB_ADD) \ + SW_API_DESC(SW_API_FDB_DELALL) \ + SW_API_DESC(SW_API_FDB_DELPORT) \ + SW_API_DESC(SW_API_FDB_DELMAC) \ + SW_API_DESC(SW_API_FDB_FIRST) \ + SW_API_DESC(SW_API_FDB_NEXT) \ + SW_API_DESC(SW_API_FDB_FIND) \ + SW_API_DESC(SW_API_FDB_PT_LEARN_SET) \ + SW_API_DESC(SW_API_FDB_PT_LEARN_GET) \ + SW_API_DESC(SW_API_FDB_PT_NEWADDR_LEARN_SET) \ + SW_API_DESC(SW_API_FDB_PT_NEWADDR_LEARN_GET) \ + SW_API_DESC(SW_API_FDB_PT_STAMOVE_SET) \ + SW_API_DESC(SW_API_FDB_PT_STAMOVE_GET) \ + SW_API_DESC(SW_API_FDB_AGE_CTRL_SET) \ + SW_API_DESC(SW_API_FDB_AGE_CTRL_GET) \ + SW_API_DESC(SW_API_FDB_LEARN_CTRL_SET) \ + SW_API_DESC(SW_API_FDB_LEARN_CTRL_GET) \ + SW_API_DESC(SW_API_FDB_VLAN_IVL_SVL_SET) \ + SW_API_DESC(SW_API_FDB_VLAN_IVL_SVL_GET) \ + SW_API_DESC(SW_API_FDB_AGE_TIME_SET) \ + SW_API_DESC(SW_API_FDB_AGE_TIME_GET) \ + SW_API_DESC(SW_API_FDB_ITERATE) \ + SW_API_DESC(SW_API_FDB_EXTEND_NEXT) \ + SW_API_DESC(SW_API_FDB_EXTEND_FIRST) \ + SW_API_DESC(SW_API_FDB_TRANSFER) \ + SW_API_DESC(SW_API_PT_FDB_LEARN_COUNTER_GET) \ + SW_API_DESC(SW_API_PT_FDB_LEARN_LIMIT_SET) \ + SW_API_DESC(SW_API_PT_FDB_LEARN_LIMIT_GET) \ + SW_API_DESC(SW_API_PT_FDB_LEARN_EXCEED_CMD_SET) \ + SW_API_DESC(SW_API_PT_FDB_LEARN_EXCEED_CMD_GET) \ + SW_API_DESC(SW_API_FDB_LEARN_LIMIT_SET) \ + SW_API_DESC(SW_API_FDB_LEARN_LIMIT_GET) \ + SW_API_DESC(SW_API_FDB_LEARN_EXCEED_CMD_SET) \ + SW_API_DESC(SW_API_FDB_LEARN_EXCEED_CMD_GET) \ + SW_API_DESC(SW_API_FDB_RESV_ADD) \ + SW_API_DESC(SW_API_FDB_RESV_DEL) \ + SW_API_DESC(SW_API_FDB_RESV_FIND) \ + SW_API_DESC(SW_API_FDB_RESV_ITERATE) \ + SW_API_DESC(SW_API_FDB_PT_LEARN_STATIC_SET) \ + SW_API_DESC(SW_API_FDB_PT_LEARN_STATIC_GET) \ + SW_API_DESC(SW_API_FDB_PORT_ADD) \ + SW_API_DESC(SW_API_FDB_PORT_DEL) \ + SW_API_DESC(SW_API_FDB_RFS_SET) \ + SW_API_DESC(SW_API_FDB_RFS_DEL) \ + SW_API_DESC(SW_API_FDB_PT_MACLIMIT_CTRL_SET) \ + SW_API_DESC(SW_API_FDB_PT_MACLIMIT_CTRL_GET) \ + SW_API_DESC(SW_API_FDB_DEL_BY_FID) +#else +#define FDB_API +#define FDB_API_PARAM +#endif + +#ifdef IN_ACL +#define ACL_API \ + SW_API_DEF(SW_API_ACL_LIST_CREAT, fal_acl_list_creat), \ + SW_API_DEF(SW_API_ACL_LIST_DESTROY, fal_acl_list_destroy), \ + SW_API_DEF(SW_API_ACL_RULE_ADD, fal_acl_rule_add), \ + SW_API_DEF(SW_API_ACL_RULE_DELETE, fal_acl_rule_delete), \ + SW_API_DEF(SW_API_ACL_RULE_QUERY, fal_acl_rule_query), \ + SW_API_DEF(SW_API_ACL_LIST_BIND, fal_acl_list_bind), \ + SW_API_DEF(SW_API_ACL_LIST_UNBIND, fal_acl_list_unbind), \ + SW_API_DEF(SW_API_ACL_STATUS_SET, fal_acl_status_set), \ + SW_API_DEF(SW_API_ACL_STATUS_GET, fal_acl_status_get), \ + SW_API_DEF(SW_API_ACL_LIST_DUMP, fal_acl_list_dump), \ + SW_API_DEF(SW_API_ACL_RULE_DUMP, fal_acl_rule_dump), \ + SW_API_DEF(SW_API_ACL_PT_UDF_PROFILE_SET, fal_acl_port_udf_profile_set), \ + SW_API_DEF(SW_API_ACL_PT_UDF_PROFILE_GET, fal_acl_port_udf_profile_get), \ + SW_API_DEF(SW_API_ACL_RULE_ACTIVE, fal_acl_rule_active), \ + SW_API_DEF(SW_API_ACL_RULE_DEACTIVE, fal_acl_rule_deactive),\ + SW_API_DEF(SW_API_ACL_RULE_SRC_FILTER_STS_SET, fal_acl_rule_src_filter_sts_set),\ + SW_API_DEF(SW_API_ACL_RULE_SRC_FILTER_STS_GET, fal_acl_rule_src_filter_sts_get),\ + SW_API_DEF(SW_API_ACL_UDF_SET, fal_acl_udf_profile_set),\ + SW_API_DEF(SW_API_ACL_UDF_GET, fal_acl_udf_profile_get), + +#define ACL_API_PARAM \ + SW_API_DESC(SW_API_ACL_LIST_CREAT) \ + SW_API_DESC(SW_API_ACL_LIST_DESTROY) \ + SW_API_DESC(SW_API_ACL_RULE_ADD) \ + SW_API_DESC(SW_API_ACL_RULE_DELETE) \ + SW_API_DESC(SW_API_ACL_RULE_QUERY) \ + SW_API_DESC(SW_API_ACL_LIST_BIND) \ + SW_API_DESC(SW_API_ACL_LIST_UNBIND) \ + SW_API_DESC(SW_API_ACL_STATUS_SET) \ + SW_API_DESC(SW_API_ACL_STATUS_GET) \ + SW_API_DESC(SW_API_ACL_LIST_DUMP) \ + SW_API_DESC(SW_API_ACL_RULE_DUMP) \ + SW_API_DESC(SW_API_ACL_PT_UDF_PROFILE_SET) \ + SW_API_DESC(SW_API_ACL_PT_UDF_PROFILE_GET) \ + SW_API_DESC(SW_API_ACL_RULE_ACTIVE) \ + SW_API_DESC(SW_API_ACL_RULE_DEACTIVE) \ + SW_API_DESC(SW_API_ACL_RULE_SRC_FILTER_STS_SET)\ + SW_API_DESC(SW_API_ACL_RULE_SRC_FILTER_STS_GET)\ + SW_API_DESC(SW_API_ACL_UDF_SET) \ + SW_API_DESC(SW_API_ACL_UDF_GET) +#else +#define ACL_API +#define ACL_API_PARAM +#endif + +#ifdef IN_QOS +#define QOS_API \ + SW_API_DEF(SW_API_QOS_SCH_MODE_SET, fal_qos_sch_mode_set), \ + SW_API_DEF(SW_API_QOS_SCH_MODE_GET, fal_qos_sch_mode_get), \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_ST_SET, fal_qos_queue_tx_buf_status_set), \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_ST_GET, fal_qos_queue_tx_buf_status_get), \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_NR_SET, fal_qos_queue_tx_buf_nr_set), \ + SW_API_DEF(SW_API_QOS_QU_TX_BUF_NR_GET, fal_qos_queue_tx_buf_nr_get), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_ST_SET, fal_qos_port_tx_buf_status_set), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_ST_GET, fal_qos_port_tx_buf_status_get), \ + SW_API_DEF(SW_API_QOS_PT_RED_EN_SET, fal_qos_port_red_en_set), \ + SW_API_DEF(SW_API_QOS_PT_RED_EN_GET, fal_qos_port_red_en_get), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_NR_SET, fal_qos_port_tx_buf_nr_set), \ + SW_API_DEF(SW_API_QOS_PT_TX_BUF_NR_GET, fal_qos_port_tx_buf_nr_get), \ + SW_API_DEF(SW_API_QOS_PT_RX_BUF_NR_SET, fal_qos_port_rx_buf_nr_set), \ + SW_API_DEF(SW_API_QOS_PT_RX_BUF_NR_GET, fal_qos_port_rx_buf_nr_get), \ + SW_API_DEF(SW_API_COSMAP_UP_QU_SET, fal_cosmap_up_queue_set), \ + SW_API_DEF(SW_API_COSMAP_UP_QU_GET, fal_cosmap_up_queue_get), \ + SW_API_DEF(SW_API_COSMAP_DSCP_QU_SET, fal_cosmap_dscp_queue_set), \ + SW_API_DEF(SW_API_COSMAP_DSCP_QU_GET, fal_cosmap_dscp_queue_get), \ + SW_API_DEF(SW_API_QOS_PT_MODE_SET, fal_qos_port_mode_set), \ + SW_API_DEF(SW_API_QOS_PT_MODE_GET, fal_qos_port_mode_get), \ + SW_API_DEF(SW_API_QOS_PT_MODE_PRI_SET, fal_qos_port_mode_pri_set), \ + SW_API_DEF(SW_API_QOS_PT_MODE_PRI_GET, fal_qos_port_mode_pri_get), \ + SW_API_DEF(SW_API_QOS_PORT_DEF_UP_SET, fal_qos_port_default_up_set), \ + SW_API_DEF(SW_API_QOS_PORT_DEF_UP_GET, fal_qos_port_default_up_get), \ + SW_API_DEF(SW_API_QOS_PORT_SCH_MODE_SET, fal_qos_port_sch_mode_set), \ + SW_API_DEF(SW_API_QOS_PORT_SCH_MODE_GET, fal_qos_port_sch_mode_get), \ + SW_API_DEF(SW_API_QOS_PT_DEF_SPRI_SET, fal_qos_port_default_spri_set), \ + SW_API_DEF(SW_API_QOS_PT_DEF_SPRI_GET, fal_qos_port_default_spri_get), \ + SW_API_DEF(SW_API_QOS_PT_DEF_CPRI_SET, fal_qos_port_default_cpri_set), \ + SW_API_DEF(SW_API_QOS_PT_DEF_CPRI_GET, fal_qos_port_default_cpri_get), \ + SW_API_DEF(SW_API_QOS_PT_FORCE_SPRI_ST_SET, fal_qos_port_force_spri_status_set), \ + SW_API_DEF(SW_API_QOS_PT_FORCE_SPRI_ST_GET, fal_qos_port_force_spri_status_get), \ + SW_API_DEF(SW_API_QOS_PT_FORCE_CPRI_ST_SET, fal_qos_port_force_cpri_status_set), \ + SW_API_DEF(SW_API_QOS_PT_FORCE_CPRI_ST_GET, fal_qos_port_force_cpri_status_get), \ + SW_API_DEF(SW_API_QOS_QUEUE_REMARK_SET, fal_qos_queue_remark_table_set), \ + SW_API_DEF(SW_API_QOS_QUEUE_REMARK_GET, fal_qos_queue_remark_table_get), \ + SW_API_DEF(SW_API_QOS_PORT_GROUP_GET, fal_qos_port_group_get), \ + SW_API_DEF(SW_API_QOS_PORT_GROUP_SET, fal_qos_port_group_set), \ + SW_API_DEF(SW_API_QOS_PORT_PRI_GET, fal_qos_port_pri_precedence_get), \ + SW_API_DEF(SW_API_QOS_PORT_PRI_SET, fal_qos_port_pri_precedence_set), \ + SW_API_DEF(SW_API_QOS_PORT_REMARK_GET, fal_qos_port_remark_get), \ + SW_API_DEF(SW_API_QOS_PORT_REMARK_SET, fal_qos_port_remark_set), \ + SW_API_DEF(SW_API_QOS_PCP_MAP_GET, fal_qos_cosmap_pcp_get), \ + SW_API_DEF(SW_API_QOS_PCP_MAP_SET, fal_qos_cosmap_pcp_set), \ + SW_API_DEF(SW_API_QOS_FLOW_MAP_GET, fal_qos_cosmap_flow_get), \ + SW_API_DEF(SW_API_QOS_FLOW_MAP_SET, fal_qos_cosmap_flow_set), \ + SW_API_DEF(SW_API_QOS_DSCP_MAP_GET, fal_qos_cosmap_dscp_get), \ + SW_API_DEF(SW_API_QOS_DSCP_MAP_SET, fal_qos_cosmap_dscp_set), \ + SW_API_DEF(SW_API_QOS_QUEUE_SCHEDULER_GET, fal_queue_scheduler_get), \ + SW_API_DEF(SW_API_QOS_QUEUE_SCHEDULER_SET, fal_queue_scheduler_set), \ + SW_API_DEF(SW_API_QOS_RING_QUEUE_MAP_GET, fal_edma_ring_queue_map_get), \ + SW_API_DEF(SW_API_QOS_RING_QUEUE_MAP_SET, fal_edma_ring_queue_map_set), \ + SW_API_DEF(SW_API_QOS_PORT_QUEUES_GET, fal_port_queues_get), \ + SW_API_DEF(SW_API_QOS_SCHEDULER_DEQUEU_CTRL_GET, fal_scheduler_dequeue_ctrl_get), \ + SW_API_DEF(SW_API_QOS_SCHEDULER_DEQUEU_CTRL_SET, fal_scheduler_dequeue_ctrl_set), \ + SW_API_DEF(SW_API_QOS_PORT_SCHEDULER_CFG_RESET, fal_port_scheduler_cfg_reset), \ + SW_API_DEF(SW_API_QOS_PORT_SCHEDULER_RESOURCE_GET, fal_port_scheduler_resource_get), + +#define QOS_API_PARAM \ + SW_API_DESC(SW_API_QOS_SCH_MODE_SET) \ + SW_API_DESC(SW_API_QOS_SCH_MODE_GET) \ + SW_API_DESC(SW_API_QOS_QU_TX_BUF_ST_SET) \ + SW_API_DESC(SW_API_QOS_QU_TX_BUF_ST_GET) \ + SW_API_DESC(SW_API_QOS_QU_TX_BUF_NR_SET) \ + SW_API_DESC(SW_API_QOS_QU_TX_BUF_NR_GET) \ + SW_API_DESC(SW_API_QOS_PT_TX_BUF_ST_SET) \ + SW_API_DESC(SW_API_QOS_PT_TX_BUF_ST_GET) \ + SW_API_DESC(SW_API_QOS_PT_RED_EN_SET)\ + SW_API_DESC(SW_API_QOS_PT_RED_EN_GET)\ + SW_API_DESC(SW_API_QOS_PT_TX_BUF_NR_SET) \ + SW_API_DESC(SW_API_QOS_PT_TX_BUF_NR_GET) \ + SW_API_DESC(SW_API_QOS_PT_RX_BUF_NR_SET) \ + SW_API_DESC(SW_API_QOS_PT_RX_BUF_NR_GET) \ + SW_API_DESC(SW_API_COSMAP_UP_QU_SET) \ + SW_API_DESC(SW_API_COSMAP_UP_QU_GET) \ + SW_API_DESC(SW_API_COSMAP_DSCP_QU_SET) \ + SW_API_DESC(SW_API_COSMAP_DSCP_QU_GET) \ + SW_API_DESC(SW_API_QOS_PT_MODE_SET) \ + SW_API_DESC(SW_API_QOS_PT_MODE_GET) \ + SW_API_DESC(SW_API_QOS_PT_MODE_PRI_SET) \ + SW_API_DESC(SW_API_QOS_PT_MODE_PRI_GET) \ + SW_API_DESC(SW_API_QOS_PORT_DEF_UP_SET) \ + SW_API_DESC(SW_API_QOS_PORT_DEF_UP_GET) \ + SW_API_DESC(SW_API_QOS_PORT_SCH_MODE_SET) \ + SW_API_DESC(SW_API_QOS_PORT_SCH_MODE_GET) \ + SW_API_DESC(SW_API_QOS_PT_DEF_SPRI_SET) \ + SW_API_DESC(SW_API_QOS_PT_DEF_SPRI_GET) \ + SW_API_DESC(SW_API_QOS_PT_DEF_CPRI_SET) \ + SW_API_DESC(SW_API_QOS_PT_DEF_CPRI_GET) \ + SW_API_DESC(SW_API_QOS_PT_FORCE_SPRI_ST_SET) \ + SW_API_DESC(SW_API_QOS_PT_FORCE_SPRI_ST_GET) \ + SW_API_DESC(SW_API_QOS_PT_FORCE_CPRI_ST_SET) \ + SW_API_DESC(SW_API_QOS_PT_FORCE_CPRI_ST_GET) \ + SW_API_DESC(SW_API_QOS_QUEUE_REMARK_SET) \ + SW_API_DESC(SW_API_QOS_QUEUE_REMARK_GET) \ + SW_API_DESC(SW_API_QOS_PORT_GROUP_GET) \ + SW_API_DESC(SW_API_QOS_PORT_GROUP_SET) \ + SW_API_DESC(SW_API_QOS_PORT_PRI_GET) \ + SW_API_DESC(SW_API_QOS_PORT_PRI_SET) \ + SW_API_DESC(SW_API_QOS_PORT_REMARK_GET) \ + SW_API_DESC(SW_API_QOS_PORT_REMARK_SET) \ + SW_API_DESC(SW_API_QOS_PCP_MAP_GET) \ + SW_API_DESC(SW_API_QOS_PCP_MAP_SET) \ + SW_API_DESC(SW_API_QOS_FLOW_MAP_GET) \ + SW_API_DESC(SW_API_QOS_FLOW_MAP_SET) \ + SW_API_DESC(SW_API_QOS_DSCP_MAP_GET) \ + SW_API_DESC(SW_API_QOS_DSCP_MAP_SET) \ + SW_API_DESC(SW_API_QOS_QUEUE_SCHEDULER_GET) \ + SW_API_DESC(SW_API_QOS_QUEUE_SCHEDULER_SET) \ + SW_API_DESC(SW_API_QOS_RING_QUEUE_MAP_GET) \ + SW_API_DESC(SW_API_QOS_RING_QUEUE_MAP_SET)\ + SW_API_DESC(SW_API_QOS_PORT_QUEUES_GET) \ + SW_API_DESC(SW_API_QOS_SCHEDULER_DEQUEU_CTRL_GET) \ + SW_API_DESC(SW_API_QOS_SCHEDULER_DEQUEU_CTRL_SET) \ + SW_API_DESC(SW_API_QOS_PORT_SCHEDULER_CFG_RESET) \ + SW_API_DESC(SW_API_QOS_PORT_SCHEDULER_RESOURCE_GET) +#else +#define QOS_API +#define QOS_API_PARAM +#endif + +#ifdef IN_IGMP +#define IGMP_API \ + SW_API_DEF(SW_API_PT_IGMPS_MODE_SET, fal_port_igmps_status_set), \ + SW_API_DEF(SW_API_PT_IGMPS_MODE_GET, fal_port_igmps_status_get), \ + SW_API_DEF(SW_API_IGMP_MLD_CMD_SET, fal_igmp_mld_cmd_set), \ + SW_API_DEF(SW_API_IGMP_MLD_CMD_GET, fal_igmp_mld_cmd_get), \ + SW_API_DEF(SW_API_IGMP_PT_JOIN_SET, fal_port_igmp_mld_join_set), \ + SW_API_DEF(SW_API_IGMP_PT_JOIN_GET, fal_port_igmp_mld_join_get), \ + SW_API_DEF(SW_API_IGMP_PT_LEAVE_SET, fal_port_igmp_mld_leave_set), \ + SW_API_DEF(SW_API_IGMP_PT_LEAVE_GET, fal_port_igmp_mld_leave_get), \ + SW_API_DEF(SW_API_IGMP_RP_SET, fal_igmp_mld_rp_set), \ + SW_API_DEF(SW_API_IGMP_RP_GET, fal_igmp_mld_rp_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_CREAT_SET, fal_igmp_mld_entry_creat_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_CREAT_GET, fal_igmp_mld_entry_creat_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_STATIC_SET, fal_igmp_mld_entry_static_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_STATIC_GET, fal_igmp_mld_entry_static_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_LEAKY_SET, fal_igmp_mld_entry_leaky_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_LEAKY_GET, fal_igmp_mld_entry_leaky_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_V3_SET, fal_igmp_mld_entry_v3_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_V3_GET, fal_igmp_mld_entry_v3_get), \ + SW_API_DEF(SW_API_IGMP_ENTRY_QUEUE_SET, fal_igmp_mld_entry_queue_set), \ + SW_API_DEF(SW_API_IGMP_ENTRY_QUEUE_GET, fal_igmp_mld_entry_queue_get), \ + SW_API_DEF(SW_API_PT_IGMP_LEARN_LIMIT_SET, fal_port_igmp_mld_learn_limit_set), \ + SW_API_DEF(SW_API_PT_IGMP_LEARN_LIMIT_GET, fal_port_igmp_mld_learn_limit_get), \ + SW_API_DEF(SW_API_PT_IGMP_LEARN_EXCEED_CMD_SET, fal_port_igmp_mld_learn_exceed_cmd_set), \ + SW_API_DEF(SW_API_PT_IGMP_LEARN_EXCEED_CMD_GET, fal_port_igmp_mld_learn_exceed_cmd_get), \ + SW_API_DEF(SW_API_IGMP_SG_ENTRY_SET, fal_igmp_sg_entry_set), \ + SW_API_DEF(SW_API_IGMP_SG_ENTRY_CLEAR, fal_igmp_sg_entry_clear), \ + SW_API_DEF(SW_API_IGMP_SG_ENTRY_SHOW, fal_igmp_sg_entry_show), \ + SW_API_DEF(SW_API_IGMP_SG_ENTRY_QUERY, fal_igmp_sg_entry_query), + +#define IGMP_API_PARAM \ + SW_API_DESC(SW_API_PT_IGMPS_MODE_SET) \ + SW_API_DESC(SW_API_PT_IGMPS_MODE_GET) \ + SW_API_DESC(SW_API_IGMP_MLD_CMD_SET) \ + SW_API_DESC(SW_API_IGMP_MLD_CMD_GET) \ + SW_API_DESC(SW_API_IGMP_PT_JOIN_SET) \ + SW_API_DESC(SW_API_IGMP_PT_JOIN_GET) \ + SW_API_DESC(SW_API_IGMP_PT_LEAVE_SET) \ + SW_API_DESC(SW_API_IGMP_PT_LEAVE_GET) \ + SW_API_DESC(SW_API_IGMP_RP_SET) \ + SW_API_DESC(SW_API_IGMP_RP_GET) \ + SW_API_DESC(SW_API_IGMP_ENTRY_CREAT_SET) \ + SW_API_DESC(SW_API_IGMP_ENTRY_CREAT_GET) \ + SW_API_DESC(SW_API_IGMP_ENTRY_STATIC_SET) \ + SW_API_DESC(SW_API_IGMP_ENTRY_STATIC_GET) \ + SW_API_DESC(SW_API_IGMP_ENTRY_LEAKY_SET) \ + SW_API_DESC(SW_API_IGMP_ENTRY_LEAKY_GET) \ + SW_API_DESC(SW_API_IGMP_ENTRY_V3_SET) \ + SW_API_DESC(SW_API_IGMP_ENTRY_V3_GET) \ + SW_API_DESC(SW_API_IGMP_ENTRY_QUEUE_SET) \ + SW_API_DESC(SW_API_IGMP_ENTRY_QUEUE_GET) \ + SW_API_DESC(SW_API_PT_IGMP_LEARN_LIMIT_SET) \ + SW_API_DESC(SW_API_PT_IGMP_LEARN_LIMIT_GET) \ + SW_API_DESC(SW_API_PT_IGMP_LEARN_EXCEED_CMD_SET) \ + SW_API_DESC(SW_API_PT_IGMP_LEARN_EXCEED_CMD_GET) \ + SW_API_DESC(SW_API_IGMP_SG_ENTRY_SET) \ + SW_API_DESC(SW_API_IGMP_SG_ENTRY_CLEAR) \ + SW_API_DESC(SW_API_IGMP_SG_ENTRY_SHOW) \ + SW_API_DESC(SW_API_IGMP_SG_ENTRY_QUERY) +#else +#define IGMP_API +#define IGMP_API_PARAM +#endif + +#ifdef IN_LEAKY +#define LEAKY_API \ + SW_API_DEF(SW_API_UC_LEAKY_MODE_SET, fal_uc_leaky_mode_set), \ + SW_API_DEF(SW_API_UC_LEAKY_MODE_GET, fal_uc_leaky_mode_get), \ + SW_API_DEF(SW_API_MC_LEAKY_MODE_SET, fal_mc_leaky_mode_set), \ + SW_API_DEF(SW_API_MC_LEAKY_MODE_GET, fal_mc_leaky_mode_get), \ + SW_API_DEF(SW_API_ARP_LEAKY_MODE_SET, fal_port_arp_leaky_set), \ + SW_API_DEF(SW_API_ARP_LEAKY_MODE_GET, fal_port_arp_leaky_get), \ + SW_API_DEF(SW_API_PT_UC_LEAKY_MODE_SET, fal_port_uc_leaky_set), \ + SW_API_DEF(SW_API_PT_UC_LEAKY_MODE_GET, fal_port_uc_leaky_get), \ + SW_API_DEF(SW_API_PT_MC_LEAKY_MODE_SET, fal_port_mc_leaky_set), \ + SW_API_DEF(SW_API_PT_MC_LEAKY_MODE_GET, fal_port_mc_leaky_get), + +#define LEAKY_API_PARAM \ + SW_API_DESC(SW_API_UC_LEAKY_MODE_SET) \ + SW_API_DESC(SW_API_UC_LEAKY_MODE_GET) \ + SW_API_DESC(SW_API_MC_LEAKY_MODE_SET) \ + SW_API_DESC(SW_API_MC_LEAKY_MODE_GET) \ + SW_API_DESC(SW_API_ARP_LEAKY_MODE_SET)\ + SW_API_DESC(SW_API_ARP_LEAKY_MODE_GET) \ + SW_API_DESC(SW_API_PT_UC_LEAKY_MODE_SET) \ + SW_API_DESC(SW_API_PT_UC_LEAKY_MODE_GET) \ + SW_API_DESC(SW_API_PT_MC_LEAKY_MODE_SET) \ + SW_API_DESC(SW_API_PT_MC_LEAKY_MODE_GET) +#else +#define LEAKY_API +#define LEAKY_API_PARAM +#endif + +#ifdef IN_MIRROR +#define MIRROR_API \ + SW_API_DEF(SW_API_MIRROR_ANALY_PT_SET, fal_mirr_analysis_port_set), \ + SW_API_DEF(SW_API_MIRROR_ANALY_PT_GET, fal_mirr_analysis_port_get), \ + SW_API_DEF(SW_API_MIRROR_IN_PT_SET, fal_mirr_port_in_set), \ + SW_API_DEF(SW_API_MIRROR_IN_PT_GET, fal_mirr_port_in_get), \ + SW_API_DEF(SW_API_MIRROR_EG_PT_SET, fal_mirr_port_eg_set), \ + SW_API_DEF(SW_API_MIRROR_EG_PT_GET, fal_mirr_port_eg_get), \ + SW_API_DEF(SW_API_MIRROR_ANALYSIS_CONFIG_SET, fal_mirr_analysis_config_set), \ + SW_API_DEF(SW_API_MIRROR_ANALYSIS_CONFIG_GET, fal_mirr_analysis_config_get), + +#define MIRROR_API_PARAM \ + SW_API_DESC(SW_API_MIRROR_ANALY_PT_SET) \ + SW_API_DESC(SW_API_MIRROR_ANALY_PT_GET) \ + SW_API_DESC(SW_API_MIRROR_IN_PT_SET) \ + SW_API_DESC(SW_API_MIRROR_IN_PT_GET) \ + SW_API_DESC(SW_API_MIRROR_EG_PT_SET) \ + SW_API_DESC(SW_API_MIRROR_EG_PT_GET) \ + SW_API_DESC(SW_API_MIRROR_ANALYSIS_CONFIG_SET) \ + SW_API_DESC(SW_API_MIRROR_ANALYSIS_CONFIG_GET) +#else +#define MIRROR_API +#define MIRROR_API_PARAM +#endif + +#ifdef IN_RATE +#define RATE_API \ + SW_API_DEF(SW_API_RATE_QU_EGRL_SET, fal_rate_queue_egrl_set), \ + SW_API_DEF(SW_API_RATE_QU_EGRL_GET, fal_rate_queue_egrl_get), \ + SW_API_DEF(SW_API_RATE_PT_EGRL_SET, fal_rate_port_egrl_set), \ + SW_API_DEF(SW_API_RATE_PT_EGRL_GET, fal_rate_port_egrl_get), \ + SW_API_DEF(SW_API_RATE_PT_INRL_SET, fal_rate_port_inrl_set), \ + SW_API_DEF(SW_API_RATE_PT_INRL_GET, fal_rate_port_inrl_get), \ + SW_API_DEF(SW_API_STORM_CTRL_FRAME_SET, fal_storm_ctrl_frame_set), \ + SW_API_DEF(SW_API_STORM_CTRL_FRAME_GET, fal_storm_ctrl_frame_get), \ + SW_API_DEF(SW_API_STORM_CTRL_RATE_SET, fal_storm_ctrl_rate_set), \ + SW_API_DEF(SW_API_STORM_CTRL_RATE_GET, fal_storm_ctrl_rate_get), \ + SW_API_DEF(SW_API_RATE_PORT_POLICER_SET, fal_rate_port_policer_set), \ + SW_API_DEF(SW_API_RATE_PORT_POLICER_GET, fal_rate_port_policer_get), \ + SW_API_DEF(SW_API_RATE_PORT_SHAPER_SET, fal_rate_port_shaper_set), \ + SW_API_DEF(SW_API_RATE_PORT_SHAPER_GET, fal_rate_port_shaper_get), \ + SW_API_DEF(SW_API_RATE_QUEUE_SHAPER_SET, fal_rate_queue_shaper_set), \ + SW_API_DEF(SW_API_RATE_QUEUE_SHAPER_GET, fal_rate_queue_shaper_get), \ + SW_API_DEF(SW_API_RATE_ACL_POLICER_SET, fal_rate_acl_policer_set), \ + SW_API_DEF(SW_API_RATE_ACL_POLICER_GET, fal_rate_acl_policer_get), \ + SW_API_DEF(SW_API_RATE_PT_ADDRATEBYTE_SET, fal_rate_port_add_rate_byte_set), \ + SW_API_DEF(SW_API_RATE_PT_ADDRATEBYTE_GET, fal_rate_port_add_rate_byte_get), \ + SW_API_DEF(SW_API_RATE_PT_GOL_FLOW_EN_SET, fal_rate_port_gol_flow_en_set), \ + SW_API_DEF(SW_API_RATE_PT_GOL_FLOW_EN_GET, fal_rate_port_gol_flow_en_get), + +#define RATE_API_PARAM \ + SW_API_DESC(SW_API_RATE_QU_EGRL_SET) \ + SW_API_DESC(SW_API_RATE_QU_EGRL_GET) \ + SW_API_DESC(SW_API_RATE_PT_EGRL_SET) \ + SW_API_DESC(SW_API_RATE_PT_EGRL_GET) \ + SW_API_DESC(SW_API_RATE_PT_INRL_SET) \ + SW_API_DESC(SW_API_RATE_PT_INRL_GET) \ + SW_API_DESC(SW_API_STORM_CTRL_FRAME_SET) \ + SW_API_DESC(SW_API_STORM_CTRL_FRAME_GET) \ + SW_API_DESC(SW_API_STORM_CTRL_RATE_SET) \ + SW_API_DESC(SW_API_STORM_CTRL_RATE_GET) \ + SW_API_DESC(SW_API_RATE_PORT_POLICER_SET) \ + SW_API_DESC(SW_API_RATE_PORT_POLICER_GET) \ + SW_API_DESC(SW_API_RATE_PORT_SHAPER_SET) \ + SW_API_DESC(SW_API_RATE_PORT_SHAPER_GET) \ + SW_API_DESC(SW_API_RATE_QUEUE_SHAPER_SET) \ + SW_API_DESC(SW_API_RATE_QUEUE_SHAPER_GET) \ + SW_API_DESC(SW_API_RATE_ACL_POLICER_SET) \ + SW_API_DESC(SW_API_RATE_ACL_POLICER_GET) \ + SW_API_DESC(SW_API_RATE_PT_ADDRATEBYTE_SET) \ + SW_API_DESC(SW_API_RATE_PT_ADDRATEBYTE_GET) \ + SW_API_DESC(SW_API_RATE_PT_GOL_FLOW_EN_SET) \ + SW_API_DESC(SW_API_RATE_PT_GOL_FLOW_EN_GET) +#else +#define RATE_API +#define RATE_API_PARAM +#endif + +#ifdef IN_STP +#define STP_API \ + SW_API_DEF(SW_API_STP_PT_STATE_SET, fal_stp_port_state_set), \ + SW_API_DEF(SW_API_STP_PT_STATE_GET, fal_stp_port_state_get), + +#define STP_API_PARAM \ + SW_API_DESC(SW_API_STP_PT_STATE_SET) \ + SW_API_DESC(SW_API_STP_PT_STATE_GET) +#else +#define STP_API +#define STP_API_PARAM +#endif + +#ifdef IN_MIB +#define MIB_API \ + SW_API_DEF(SW_API_PT_MIB_GET, fal_get_mib_info), \ + SW_API_DEF(SW_API_MIB_STATUS_SET, fal_mib_status_set), \ + SW_API_DEF(SW_API_MIB_STATUS_GET, fal_mib_status_get), \ + SW_API_DEF(SW_API_PT_MIB_FLUSH_COUNTERS, fal_mib_port_flush_counters), \ + SW_API_DEF(SW_API_MIB_CPU_KEEP_SET, fal_mib_cpukeep_set), \ + SW_API_DEF(SW_API_MIB_CPU_KEEP_GET, fal_mib_cpukeep_get),\ + SW_API_DEF(SW_API_PT_XGMIB_GET, fal_get_xgmib_info),\ + SW_API_DEF(SW_API_PT_MIB_COUNTER_GET, fal_mib_counter_get), +#define MIB_API_PARAM \ + SW_API_DESC(SW_API_PT_MIB_GET) \ + SW_API_DESC(SW_API_PT_XGMIB_GET) \ + SW_API_DESC(SW_API_MIB_STATUS_SET) \ + SW_API_DESC(SW_API_MIB_STATUS_GET) \ + SW_API_DESC(SW_API_PT_MIB_FLUSH_COUNTERS) \ + SW_API_DESC(SW_API_MIB_CPU_KEEP_SET) \ + SW_API_DESC(SW_API_MIB_CPU_KEEP_GET) \ + SW_API_DESC(SW_API_PT_MIB_COUNTER_GET) +#else +#define MIB_API +#define MIB_API_PARAM +#endif + +#ifdef IN_MISC +#define MISC_API \ + SW_API_DEF(SW_API_ARP_STATUS_SET, fal_arp_status_set), \ + SW_API_DEF(SW_API_ARP_STATUS_GET, fal_arp_status_get), \ + SW_API_DEF(SW_API_FRAME_MAX_SIZE_SET, fal_frame_max_size_set), \ + SW_API_DEF(SW_API_FRAME_MAX_SIZE_GET, fal_frame_max_size_get), \ + SW_API_DEF(SW_API_PT_UNK_SA_CMD_SET, fal_port_unk_sa_cmd_set), \ + SW_API_DEF(SW_API_PT_UNK_SA_CMD_GET, fal_port_unk_sa_cmd_get), \ + SW_API_DEF(SW_API_PT_UNK_UC_FILTER_SET, fal_port_unk_uc_filter_set), \ + SW_API_DEF(SW_API_PT_UNK_UC_FILTER_GET, fal_port_unk_uc_filter_get), \ + SW_API_DEF(SW_API_PT_UNK_MC_FILTER_SET, fal_port_unk_mc_filter_set), \ + SW_API_DEF(SW_API_PT_UNK_MC_FILTER_GET, fal_port_unk_mc_filter_get), \ + SW_API_DEF(SW_API_PT_BC_FILTER_SET, fal_port_bc_filter_set), \ + SW_API_DEF(SW_API_PT_BC_FILTER_GET, fal_port_bc_filter_get), \ + SW_API_DEF(SW_API_CPU_PORT_STATUS_SET, fal_cpu_port_status_set), \ + SW_API_DEF(SW_API_CPU_PORT_STATUS_GET, fal_cpu_port_status_get), \ + SW_API_DEF(SW_API_BC_TO_CPU_PORT_SET, fal_bc_to_cpu_port_set), \ + SW_API_DEF(SW_API_BC_TO_CPU_PORT_GET, fal_bc_to_cpu_port_get), \ + SW_API_DEF(SW_API_PT_DHCP_SET, fal_port_dhcp_set), \ + SW_API_DEF(SW_API_PT_DHCP_GET, fal_port_dhcp_get), \ + SW_API_DEF(SW_API_ARP_CMD_SET, fal_arp_cmd_set), \ + SW_API_DEF(SW_API_ARP_CMD_GET, fal_arp_cmd_get), \ + SW_API_DEF(SW_API_EAPOL_CMD_SET, fal_eapol_cmd_set), \ + SW_API_DEF(SW_API_EAPOL_CMD_GET, fal_eapol_cmd_get), \ + SW_API_DEF(SW_API_EAPOL_STATUS_SET, fal_eapol_status_set), \ + SW_API_DEF(SW_API_EAPOL_STATUS_GET, fal_eapol_status_get), \ + SW_API_DEF(SW_API_RIPV1_STATUS_SET, fal_ripv1_status_set), \ + SW_API_DEF(SW_API_RIPV1_STATUS_GET, fal_ripv1_status_get), \ + SW_API_DEF(SW_API_PT_ARP_REQ_STATUS_SET, fal_port_arp_req_status_set), \ + SW_API_DEF(SW_API_PT_ARP_REQ_STATUS_GET, fal_port_arp_req_status_get), \ + SW_API_DEF(SW_API_PT_ARP_ACK_STATUS_SET, fal_port_arp_ack_status_set), \ + SW_API_DEF(SW_API_PT_ARP_ACK_STATUS_GET, fal_port_arp_ack_status_get), \ + SW_API_DEF(SW_API_INTR_MASK_SET, fal_intr_mask_set), \ + SW_API_DEF(SW_API_INTR_MASK_GET, fal_intr_mask_get), \ + SW_API_DEF(SW_API_INTR_STATUS_GET, fal_intr_status_get), \ + SW_API_DEF(SW_API_INTR_STATUS_CLEAR, fal_intr_status_clear), \ + SW_API_DEF(SW_API_INTR_PORT_LINK_MASK_SET, fal_intr_port_link_mask_set), \ + SW_API_DEF(SW_API_INTR_PORT_LINK_MASK_GET, fal_intr_port_link_mask_get), \ + SW_API_DEF(SW_API_INTR_PORT_LINK_STATUS_GET, fal_intr_port_link_status_get), \ + SW_API_DEF(SW_API_INTR_MASK_MAC_LINKCHG_SET, fal_intr_mask_mac_linkchg_set), \ + SW_API_DEF(SW_API_INTR_MASK_MAC_LINKCHG_GET, fal_intr_mask_mac_linkchg_get), \ + SW_API_DEF(SW_API_INTR_STATUS_MAC_LINKCHG_GET, fal_intr_status_mac_linkchg_get), \ + SW_API_DEF(SW_API_INTR_STATUS_MAC_LINKCHG_CLEAR, fal_intr_status_mac_linkchg_clear), \ + SW_API_DEF(SW_API_CPU_VID_EN_SET, fal_cpu_vid_en_set), \ + SW_API_DEF(SW_API_CPU_VID_EN_GET, fal_cpu_vid_en_get), \ + SW_API_DEF(SW_API_GLOBAL_MACADDR_SET, fal_global_macaddr_set), \ + SW_API_DEF(SW_API_GLOBAL_MACADDR_GET, fal_global_macaddr_get), \ + SW_API_DEF(SW_API_LLDP_STATUS_SET, fal_lldp_status_set), \ + SW_API_DEF(SW_API_LLDP_STATUS_GET, fal_lldp_status_get), \ + SW_API_DEF(SW_API_FRAME_CRC_RESERVE_SET, fal_frame_crc_reserve_set), \ + SW_API_DEF(SW_API_FRAME_CRC_RESERVE_GET, fal_frame_crc_reserve_get), \ + SW_API_DEF(SW_API_DEBUG_PORT_COUNTER_ENABLE, fal_debug_port_counter_enable), \ + SW_API_DEF(SW_API_DEBUG_PORT_COUNTER_STATUS_GET, fal_debug_port_counter_status_get), + + + +#define MISC_API_PARAM \ + SW_API_DESC(SW_API_ARP_STATUS_SET) \ + SW_API_DESC(SW_API_ARP_STATUS_GET) \ + SW_API_DESC(SW_API_FRAME_MAX_SIZE_SET) \ + SW_API_DESC(SW_API_FRAME_MAX_SIZE_GET) \ + SW_API_DESC(SW_API_PT_UNK_SA_CMD_SET) \ + SW_API_DESC(SW_API_PT_UNK_SA_CMD_GET) \ + SW_API_DESC(SW_API_PT_UNK_UC_FILTER_SET) \ + SW_API_DESC(SW_API_PT_UNK_UC_FILTER_GET) \ + SW_API_DESC(SW_API_PT_UNK_MC_FILTER_SET) \ + SW_API_DESC(SW_API_PT_UNK_MC_FILTER_GET) \ + SW_API_DESC(SW_API_PT_BC_FILTER_SET) \ + SW_API_DESC(SW_API_PT_BC_FILTER_GET) \ + SW_API_DESC(SW_API_CPU_PORT_STATUS_SET) \ + SW_API_DESC(SW_API_CPU_PORT_STATUS_GET) \ + SW_API_DESC(SW_API_BC_TO_CPU_PORT_SET) \ + SW_API_DESC(SW_API_BC_TO_CPU_PORT_GET) \ + SW_API_DESC(SW_API_PT_DHCP_SET) \ + SW_API_DESC(SW_API_PT_DHCP_GET) \ + SW_API_DESC(SW_API_ARP_CMD_SET) \ + SW_API_DESC(SW_API_ARP_CMD_GET) \ + SW_API_DESC(SW_API_EAPOL_CMD_SET) \ + SW_API_DESC(SW_API_EAPOL_CMD_GET) \ + SW_API_DESC(SW_API_EAPOL_STATUS_SET) \ + SW_API_DESC(SW_API_EAPOL_STATUS_GET) \ + SW_API_DESC(SW_API_RIPV1_STATUS_SET) \ + SW_API_DESC(SW_API_RIPV1_STATUS_GET) \ + SW_API_DESC(SW_API_PT_ARP_REQ_STATUS_SET) \ + SW_API_DESC(SW_API_PT_ARP_REQ_STATUS_GET) \ + SW_API_DESC(SW_API_PT_ARP_ACK_STATUS_SET) \ + SW_API_DESC(SW_API_PT_ARP_ACK_STATUS_GET) \ + SW_API_DESC(SW_API_INTR_MASK_SET) \ + SW_API_DESC(SW_API_INTR_MASK_GET) \ + SW_API_DESC(SW_API_INTR_STATUS_GET) \ + SW_API_DESC(SW_API_INTR_STATUS_CLEAR) \ + SW_API_DESC(SW_API_INTR_PORT_LINK_MASK_SET) \ + SW_API_DESC(SW_API_INTR_PORT_LINK_MASK_GET) \ + SW_API_DESC(SW_API_INTR_PORT_LINK_STATUS_GET) \ + SW_API_DESC(SW_API_INTR_MASK_MAC_LINKCHG_SET) \ + SW_API_DESC(SW_API_INTR_MASK_MAC_LINKCHG_GET) \ + SW_API_DESC(SW_API_INTR_STATUS_MAC_LINKCHG_GET) \ + SW_API_DESC(SW_API_INTR_STATUS_MAC_LINKCHG_CLEAR) \ + SW_API_DESC(SW_API_CPU_VID_EN_SET) \ + SW_API_DESC(SW_API_CPU_VID_EN_GET) \ + SW_API_DESC(SW_API_GLOBAL_MACADDR_SET) \ + SW_API_DESC(SW_API_GLOBAL_MACADDR_GET) \ + SW_API_DESC(SW_API_LLDP_STATUS_SET) \ + SW_API_DESC(SW_API_LLDP_STATUS_GET) \ + SW_API_DESC(SW_API_FRAME_CRC_RESERVE_SET) \ + SW_API_DESC(SW_API_FRAME_CRC_RESERVE_GET) \ + SW_API_DESC(SW_API_DEBUG_PORT_COUNTER_ENABLE) \ + SW_API_DESC(SW_API_DEBUG_PORT_COUNTER_STATUS_GET) + + +#else +#define MISC_API +#define MISC_API_PARAM +#endif + +#ifdef IN_LED +#define LED_API \ + SW_API_DEF(SW_API_LED_PATTERN_SET, fal_led_ctrl_pattern_set), \ + SW_API_DEF(SW_API_LED_PATTERN_GET, fal_led_ctrl_pattern_get), + +#define LED_API_PARAM \ + SW_API_DESC(SW_API_LED_PATTERN_SET) \ + SW_API_DESC(SW_API_LED_PATTERN_GET) +#else +#define LED_API +#define LED_API_PARAM +#endif + +#ifdef IN_COSMAP +#define COSMAP_API \ + SW_API_DEF(SW_API_COSMAP_DSCP_TO_PRI_SET, fal_cosmap_dscp_to_pri_set), \ + SW_API_DEF(SW_API_COSMAP_DSCP_TO_PRI_GET, fal_cosmap_dscp_to_pri_get), \ + SW_API_DEF(SW_API_COSMAP_DSCP_TO_DP_SET, fal_cosmap_dscp_to_dp_set), \ + SW_API_DEF(SW_API_COSMAP_DSCP_TO_DP_GET, fal_cosmap_dscp_to_dp_get), \ + SW_API_DEF(SW_API_COSMAP_UP_TO_PRI_SET, fal_cosmap_up_to_pri_set), \ + SW_API_DEF(SW_API_COSMAP_UP_TO_PRI_GET, fal_cosmap_up_to_pri_get), \ + SW_API_DEF(SW_API_COSMAP_UP_TO_DP_SET, fal_cosmap_up_to_dp_set), \ + SW_API_DEF(SW_API_COSMAP_UP_TO_DP_GET, fal_cosmap_up_to_dp_get), \ + SW_API_DEF(SW_API_COSMAP_PRI_TO_QU_SET, fal_cosmap_pri_to_queue_set), \ + SW_API_DEF(SW_API_COSMAP_PRI_TO_QU_GET, fal_cosmap_pri_to_queue_get), \ + SW_API_DEF(SW_API_COSMAP_PRI_TO_EHQU_SET, fal_cosmap_pri_to_ehqueue_set), \ + SW_API_DEF(SW_API_COSMAP_PRI_TO_EHQU_GET, fal_cosmap_pri_to_ehqueue_get), \ + SW_API_DEF(SW_API_COSMAP_EG_REMARK_SET, fal_cosmap_egress_remark_set), \ + SW_API_DEF(SW_API_COSMAP_EG_REMARK_GET, fal_cosmap_egress_remark_get), \ + SW_API_DEF(SW_API_COSMAP_DSCP_TO_EHPRI_SET, fal_cosmap_dscp_to_ehpri_set), \ + SW_API_DEF(SW_API_COSMAP_DSCP_TO_EHPRI_GET, fal_cosmap_dscp_to_ehpri_get), \ + SW_API_DEF(SW_API_COSMAP_DSCP_TO_EHDP_SET, fal_cosmap_dscp_to_ehdp_set), \ + SW_API_DEF(SW_API_COSMAP_DSCP_TO_EHDP_GET, fal_cosmap_dscp_to_ehdp_get), \ + SW_API_DEF(SW_API_COSMAP_UP_TO_EHPRI_SET, fal_cosmap_up_to_ehpri_set), \ + SW_API_DEF(SW_API_COSMAP_UP_TO_EHPRI_GET, fal_cosmap_up_to_ehpri_get), \ + SW_API_DEF(SW_API_COSMAP_UP_TO_EHDP_SET, fal_cosmap_up_to_ehdp_set), \ + SW_API_DEF(SW_API_COSMAP_UP_TO_EHDP_GET, fal_cosmap_up_to_ehdp_get), + +#define COSMAP_API_PARAM \ + SW_API_DESC(SW_API_COSMAP_DSCP_TO_PRI_SET) \ + SW_API_DESC(SW_API_COSMAP_DSCP_TO_PRI_GET) \ + SW_API_DESC(SW_API_COSMAP_DSCP_TO_DP_SET) \ + SW_API_DESC(SW_API_COSMAP_DSCP_TO_DP_GET) \ + SW_API_DESC(SW_API_COSMAP_UP_TO_PRI_SET) \ + SW_API_DESC(SW_API_COSMAP_UP_TO_PRI_GET) \ + SW_API_DESC(SW_API_COSMAP_UP_TO_DP_SET) \ + SW_API_DESC(SW_API_COSMAP_UP_TO_DP_GET) \ + SW_API_DESC(SW_API_COSMAP_PRI_TO_QU_SET) \ + SW_API_DESC(SW_API_COSMAP_PRI_TO_QU_GET) \ + SW_API_DESC(SW_API_COSMAP_PRI_TO_EHQU_SET) \ + SW_API_DESC(SW_API_COSMAP_PRI_TO_EHQU_GET) \ + SW_API_DESC(SW_API_COSMAP_EG_REMARK_SET) \ + SW_API_DESC(SW_API_COSMAP_EG_REMARK_GET) \ + SW_API_DESC(SW_API_COSMAP_DSCP_TO_EHPRI_SET) \ + SW_API_DESC(SW_API_COSMAP_DSCP_TO_EHPRI_GET) \ + SW_API_DESC(SW_API_COSMAP_DSCP_TO_EHDP_SET) \ + SW_API_DESC(SW_API_COSMAP_DSCP_TO_EHDP_GET) \ + SW_API_DESC(SW_API_COSMAP_UP_TO_EHPRI_SET) \ + SW_API_DESC(SW_API_COSMAP_UP_TO_EHPRI_GET) \ + SW_API_DESC(SW_API_COSMAP_UP_TO_EHDP_SET) \ + SW_API_DESC(SW_API_COSMAP_UP_TO_EHDP_GET) +#else +#define COSMAP_API +#define COSMAP_API_PARAM +#endif + +#ifdef IN_SEC +#define SEC_API \ + SW_API_DEF(SW_API_SEC_NORM_SET, fal_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_NORM_GET, fal_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_MAC_SET, fal_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_MAC_GET, fal_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_IP_SET, fal_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_IP_GET, fal_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_IP4_SET, fal_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_IP4_GET, fal_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_IP6_SET, fal_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_IP6_GET, fal_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_TCP_SET, fal_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_TCP_GET, fal_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_UDP_SET, fal_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_UDP_GET, fal_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_ICMP4_SET, fal_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_ICMP4_GET, fal_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_ICMP6_SET, fal_sec_norm_item_set), \ + SW_API_DEF(SW_API_SEC_ICMP6_GET, fal_sec_norm_item_get), \ + SW_API_DEF(SW_API_SEC_L3_PARSER_CTRL_GET, fal_sec_l3_excep_parser_ctrl_get), \ + SW_API_DEF(SW_API_SEC_L3_PARSER_CTRL_SET, fal_sec_l3_excep_parser_ctrl_set), \ + SW_API_DEF(SW_API_SEC_L4_PARSER_CTRL_GET, fal_sec_l4_excep_parser_ctrl_get), \ + SW_API_DEF(SW_API_SEC_L4_PARSER_CTRL_SET, fal_sec_l4_excep_parser_ctrl_set), \ + SW_API_DEF(SW_API_SEC_EXP_CTRL_GET, fal_sec_l3_excep_ctrl_get), \ + SW_API_DEF(SW_API_SEC_EXP_CTRL_SET, fal_sec_l3_excep_ctrl_set), + +#define SEC_API_PARAM \ + SW_API_DESC(SW_API_SEC_NORM_SET) \ + SW_API_DESC(SW_API_SEC_NORM_GET) \ + SW_API_DESC(SW_API_SEC_MAC_SET) \ + SW_API_DESC(SW_API_SEC_MAC_GET) \ + SW_API_DESC(SW_API_SEC_IP_SET) \ + SW_API_DESC(SW_API_SEC_IP_GET) \ + SW_API_DESC(SW_API_SEC_IP4_SET) \ + SW_API_DESC(SW_API_SEC_IP4_GET) \ + SW_API_DESC(SW_API_SEC_IP6_SET) \ + SW_API_DESC(SW_API_SEC_IP6_GET) \ + SW_API_DESC(SW_API_SEC_TCP_SET) \ + SW_API_DESC(SW_API_SEC_TCP_GET) \ + SW_API_DESC(SW_API_SEC_UDP_SET) \ + SW_API_DESC(SW_API_SEC_UDP_GET) \ + SW_API_DESC(SW_API_SEC_ICMP4_SET) \ + SW_API_DESC(SW_API_SEC_ICMP4_GET) \ + SW_API_DESC(SW_API_SEC_ICMP6_SET) \ + SW_API_DESC(SW_API_SEC_ICMP6_GET) \ + SW_API_DESC(SW_API_SEC_L3_PARSER_CTRL_GET) \ + SW_API_DESC(SW_API_SEC_L3_PARSER_CTRL_SET) \ + SW_API_DESC(SW_API_SEC_L4_PARSER_CTRL_GET) \ + SW_API_DESC(SW_API_SEC_L4_PARSER_CTRL_SET) \ + SW_API_DESC(SW_API_SEC_EXP_CTRL_GET) \ + SW_API_DESC(SW_API_SEC_EXP_CTRL_SET) +#else +#define SEC_API +#define SEC_API_PARAM +#endif + +#ifdef IN_IP +#define IP_API \ + SW_API_DEF(SW_API_IP_HOST_ADD, fal_ip_host_add), \ + SW_API_DEF(SW_API_IP_HOST_DEL, fal_ip_host_del), \ + SW_API_DEF(SW_API_IP_HOST_GET, fal_ip_host_get), \ + SW_API_DEF(SW_API_IP_HOST_NEXT, fal_ip_host_next), \ + SW_API_DEF(SW_API_IP_HOST_COUNTER_BIND, fal_ip_host_counter_bind), \ + SW_API_DEF(SW_API_IP_HOST_PPPOE_BIND, fal_ip_host_pppoe_bind), \ + SW_API_DEF(SW_API_IP_PT_ARP_LEARN_SET, fal_ip_pt_arp_learn_set), \ + SW_API_DEF(SW_API_IP_PT_ARP_LEARN_GET, fal_ip_pt_arp_learn_get), \ + SW_API_DEF(SW_API_IP_ARP_LEARN_SET, fal_ip_arp_learn_set), \ + SW_API_DEF(SW_API_IP_ARP_LEARN_GET, fal_ip_arp_learn_get), \ + SW_API_DEF(SW_API_IP_SOURCE_GUARD_SET, fal_ip_source_guard_set), \ + SW_API_DEF(SW_API_IP_SOURCE_GUARD_GET, fal_ip_source_guard_get), \ + SW_API_DEF(SW_API_IP_ARP_GUARD_SET, fal_ip_arp_guard_set), \ + SW_API_DEF(SW_API_IP_ARP_GUARD_GET, fal_ip_arp_guard_get), \ + SW_API_DEF(SW_API_IP_ROUTE_STATUS_SET, fal_ip_route_status_set), \ + SW_API_DEF(SW_API_IP_ROUTE_STATUS_GET, fal_ip_route_status_get), \ + SW_API_DEF(SW_API_IP_INTF_ENTRY_ADD, fal_ip_intf_entry_add), \ + SW_API_DEF(SW_API_IP_INTF_ENTRY_DEL, fal_ip_intf_entry_del), \ + SW_API_DEF(SW_API_IP_INTF_ENTRY_NEXT, fal_ip_intf_entry_next), \ + SW_API_DEF(SW_API_IP_UNK_SOURCE_CMD_SET, fal_ip_unk_source_cmd_set), \ + SW_API_DEF(SW_API_IP_UNK_SOURCE_CMD_GET, fal_ip_unk_source_cmd_get), \ + SW_API_DEF(SW_API_ARP_UNK_SOURCE_CMD_SET, fal_arp_unk_source_cmd_set), \ + SW_API_DEF(SW_API_ARP_UNK_SOURCE_CMD_GET, fal_arp_unk_source_cmd_get), \ + SW_API_DEF(SW_API_IP_AGE_TIME_SET, fal_ip_age_time_set), \ + SW_API_DEF(SW_API_IP_AGE_TIME_GET, fal_ip_age_time_get), \ + SW_API_DEF(SW_API_WCMP_HASH_MODE_SET, fal_ip_wcmp_hash_mode_set), \ + SW_API_DEF(SW_API_WCMP_HASH_MODE_GET, fal_ip_wcmp_hash_mode_get), \ + SW_API_DEF(SW_API_IP_VRF_BASE_ADDR_SET, fal_ip_vrf_base_addr_set), \ + SW_API_DEF(SW_API_IP_VRF_BASE_ADDR_GET, fal_ip_vrf_base_addr_get), \ + SW_API_DEF(SW_API_IP_VRF_BASE_MASK_SET, fal_ip_vrf_base_mask_set), \ + SW_API_DEF(SW_API_IP_VRF_BASE_MASK_GET, fal_ip_vrf_base_mask_get), \ + SW_API_DEF(SW_API_IP_DEFAULT_ROUTE_SET, fal_ip_default_route_set), \ + SW_API_DEF(SW_API_IP_DEFAULT_ROUTE_GET, fal_ip_default_route_get), \ + SW_API_DEF(SW_API_IP_HOST_ROUTE_SET, fal_ip_host_route_set), \ + SW_API_DEF(SW_API_IP_HOST_ROUTE_GET, fal_ip_host_route_get), \ + SW_API_DEF(SW_API_IP_WCMP_ENTRY_SET, fal_ip_wcmp_entry_set), \ + SW_API_DEF(SW_API_IP_WCMP_ENTRY_GET, fal_ip_wcmp_entry_get), \ + SW_API_DEF(SW_API_IP_RFS_IP4_SET, fal_ip_rfs_ip4_rule_set), \ + SW_API_DEF(SW_API_IP_RFS_IP6_SET, fal_ip_rfs_ip6_rule_set), \ + SW_API_DEF(SW_API_IP_RFS_IP4_DEL, fal_ip_rfs_ip4_rule_del), \ + SW_API_DEF(SW_API_IP_RFS_IP6_DEL, fal_ip_rfs_ip6_rule_del), \ + SW_API_DEF(SW_API_IP_DEFAULT_FLOW_CMD_SET, fal_default_flow_cmd_set), \ + SW_API_DEF(SW_API_IP_DEFAULT_FLOW_CMD_GET, fal_default_flow_cmd_get), \ + SW_API_DEF(SW_API_IP_DEFAULT_RT_FLOW_CMD_SET, fal_default_rt_flow_cmd_set), \ + SW_API_DEF(SW_API_IP_DEFAULT_RT_FLOW_CMD_GET, fal_default_rt_flow_cmd_get), \ + SW_API_DEF(SW_API_IP_VIS_ARP_SG_CFG_GET, fal_ip_vsi_arp_sg_cfg_get), \ + SW_API_DEF(SW_API_IP_VIS_ARP_SG_CFG_SET, fal_ip_vsi_arp_sg_cfg_set), \ + SW_API_DEF(SW_API_IP_NETWORK_ROUTE_GET, fal_ip_network_route_get), \ + SW_API_DEF(SW_API_IP_NETWORK_ROUTE_ADD, fal_ip_network_route_add), \ + SW_API_DEF(SW_API_IP_INTF_GET, fal_ip_intf_get), \ + SW_API_DEF(SW_API_IP_INTF_SET, fal_ip_intf_set), \ + SW_API_DEF(SW_API_IP_VSI_INTF_GET, fal_ip_vsi_intf_get), \ + SW_API_DEF(SW_API_IP_VSI_INTF_SET, fal_ip_vsi_intf_set), \ + SW_API_DEF(SW_API_IP_NEXTHOP_GET, fal_ip_nexthop_get), \ + SW_API_DEF(SW_API_IP_NEXTHOP_SET, fal_ip_nexthop_set), \ + SW_API_DEF(SW_API_IP_VSI_SG_SET, fal_ip_vsi_sg_cfg_set), \ + SW_API_DEF(SW_API_IP_VSI_SG_GET, fal_ip_vsi_sg_cfg_get), \ + SW_API_DEF(SW_API_IP_PORT_SG_SET, fal_ip_port_sg_cfg_set), \ + SW_API_DEF(SW_API_IP_PORT_SG_GET, fal_ip_port_sg_cfg_get), \ + SW_API_DEF(SW_API_IP_PUB_IP_SET, fal_ip_pub_addr_set), \ + SW_API_DEF(SW_API_IP_PUB_IP_GET, fal_ip_pub_addr_get), \ + SW_API_DEF(SW_API_IP_NETWORK_ROUTE_DEL, fal_ip_network_route_del), \ + SW_API_DEF(SW_API_IP_PORT_INTF_GET, fal_ip_port_intf_get), \ + SW_API_DEF(SW_API_IP_PORT_INTF_SET, fal_ip_port_intf_set), \ + SW_API_DEF(SW_API_IP_PORT_MAC_GET, fal_ip_port_macaddr_get), \ + SW_API_DEF(SW_API_IP_PORT_MAC_SET, fal_ip_port_macaddr_set), \ + SW_API_DEF(SW_API_IP_ROUTE_MISS_GET, fal_ip_route_mismatch_action_get), \ + SW_API_DEF(SW_API_IP_ROUTE_MISS_SET, fal_ip_route_mismatch_action_set), \ + SW_API_DEF(SW_API_IP_PORT_ARP_SG_SET, fal_ip_port_arp_sg_cfg_set), \ + SW_API_DEF(SW_API_IP_PORT_ARP_SG_GET, fal_ip_port_arp_sg_cfg_get), \ + SW_API_DEF(SW_API_IP_VSI_MC_MODE_SET, fal_ip_vsi_mc_mode_set), \ + SW_API_DEF(SW_API_IP_VSI_MC_MODE_GET, fal_ip_vsi_mc_mode_get), \ + SW_API_DEF(SW_API_GLOBAL_CTRL_GET, fal_ip_global_ctrl_get), \ + SW_API_DEF(SW_API_GLOBAL_CTRL_SET, fal_ip_global_ctrl_set), + +#define IP_API_PARAM \ + SW_API_DESC(SW_API_IP_HOST_ADD) \ + SW_API_DESC(SW_API_IP_HOST_DEL) \ + SW_API_DESC(SW_API_IP_HOST_GET) \ + SW_API_DESC(SW_API_IP_HOST_NEXT) \ + SW_API_DESC(SW_API_IP_HOST_COUNTER_BIND) \ + SW_API_DESC(SW_API_IP_HOST_PPPOE_BIND) \ + SW_API_DESC(SW_API_IP_PT_ARP_LEARN_SET) \ + SW_API_DESC(SW_API_IP_PT_ARP_LEARN_GET) \ + SW_API_DESC(SW_API_IP_ARP_LEARN_SET) \ + SW_API_DESC(SW_API_IP_ARP_LEARN_GET) \ + SW_API_DESC(SW_API_IP_SOURCE_GUARD_SET) \ + SW_API_DESC(SW_API_IP_SOURCE_GUARD_GET) \ + SW_API_DESC(SW_API_IP_ARP_GUARD_SET) \ + SW_API_DESC(SW_API_IP_ARP_GUARD_GET) \ + SW_API_DESC(SW_API_IP_ROUTE_STATUS_SET) \ + SW_API_DESC(SW_API_IP_ROUTE_STATUS_GET) \ + SW_API_DESC(SW_API_IP_INTF_ENTRY_ADD) \ + SW_API_DESC(SW_API_IP_INTF_ENTRY_DEL) \ + SW_API_DESC(SW_API_IP_INTF_ENTRY_NEXT) \ + SW_API_DESC(SW_API_IP_UNK_SOURCE_CMD_SET) \ + SW_API_DESC(SW_API_IP_UNK_SOURCE_CMD_GET) \ + SW_API_DESC(SW_API_ARP_UNK_SOURCE_CMD_SET) \ + SW_API_DESC(SW_API_ARP_UNK_SOURCE_CMD_GET) \ + SW_API_DESC(SW_API_IP_AGE_TIME_SET) \ + SW_API_DESC(SW_API_IP_AGE_TIME_GET) \ + SW_API_DESC(SW_API_WCMP_HASH_MODE_SET) \ + SW_API_DESC(SW_API_WCMP_HASH_MODE_GET) \ + SW_API_DESC(SW_API_IP_VRF_BASE_ADDR_SET) \ + SW_API_DESC(SW_API_IP_VRF_BASE_ADDR_GET) \ + SW_API_DESC(SW_API_IP_VRF_BASE_MASK_SET) \ + SW_API_DESC(SW_API_IP_VRF_BASE_MASK_GET) \ + SW_API_DESC(SW_API_IP_DEFAULT_ROUTE_SET) \ + SW_API_DESC(SW_API_IP_DEFAULT_ROUTE_GET) \ + SW_API_DESC(SW_API_IP_HOST_ROUTE_SET) \ + SW_API_DESC(SW_API_IP_HOST_ROUTE_GET) \ + SW_API_DESC(SW_API_IP_WCMP_ENTRY_SET) \ + SW_API_DESC(SW_API_IP_WCMP_ENTRY_GET) \ + SW_API_DESC(SW_API_IP_RFS_IP4_SET) \ + SW_API_DESC(SW_API_IP_RFS_IP6_SET) \ + SW_API_DESC(SW_API_IP_RFS_IP4_DEL) \ + SW_API_DESC(SW_API_IP_RFS_IP6_DEL) \ + SW_API_DESC(SW_API_IP_DEFAULT_FLOW_CMD_SET) \ + SW_API_DESC(SW_API_IP_DEFAULT_FLOW_CMD_GET) \ + SW_API_DESC(SW_API_IP_DEFAULT_RT_FLOW_CMD_SET) \ + SW_API_DESC(SW_API_IP_DEFAULT_RT_FLOW_CMD_GET) \ + SW_API_DESC(SW_API_IP_VIS_ARP_SG_CFG_GET) \ + SW_API_DESC(SW_API_IP_VIS_ARP_SG_CFG_SET) \ + SW_API_DESC(SW_API_IP_NETWORK_ROUTE_GET) \ + SW_API_DESC(SW_API_IP_NETWORK_ROUTE_ADD) \ + SW_API_DESC(SW_API_IP_INTF_GET) \ + SW_API_DESC(SW_API_IP_INTF_SET) \ + SW_API_DESC(SW_API_IP_VSI_INTF_GET) \ + SW_API_DESC(SW_API_IP_VSI_INTF_SET) \ + SW_API_DESC(SW_API_IP_NEXTHOP_GET) \ + SW_API_DESC(SW_API_IP_NEXTHOP_SET) \ + SW_API_DESC(SW_API_IP_VSI_SG_SET) \ + SW_API_DESC(SW_API_IP_VSI_SG_GET) \ + SW_API_DESC(SW_API_IP_PORT_SG_SET) \ + SW_API_DESC(SW_API_IP_PORT_SG_GET) \ + SW_API_DESC(SW_API_IP_PUB_IP_SET) \ + SW_API_DESC(SW_API_IP_PUB_IP_GET) \ + SW_API_DESC(SW_API_IP_NETWORK_ROUTE_DEL) \ + SW_API_DESC(SW_API_IP_PORT_INTF_GET) \ + SW_API_DESC(SW_API_IP_PORT_INTF_SET) \ + SW_API_DESC(SW_API_IP_PORT_MAC_GET) \ + SW_API_DESC(SW_API_IP_PORT_MAC_SET) \ + SW_API_DESC(SW_API_IP_ROUTE_MISS_GET) \ + SW_API_DESC(SW_API_IP_ROUTE_MISS_SET) \ + SW_API_DESC(SW_API_IP_PORT_ARP_SG_SET) \ + SW_API_DESC(SW_API_IP_PORT_ARP_SG_GET) \ + SW_API_DESC(SW_API_IP_VSI_MC_MODE_SET) \ + SW_API_DESC(SW_API_IP_VSI_MC_MODE_GET) \ + SW_API_DESC(SW_API_GLOBAL_CTRL_GET) \ + SW_API_DESC(SW_API_GLOBAL_CTRL_SET) +#else +#define IP_API +#define IP_API_PARAM +#endif + +#ifdef IN_FLOW +#define FLOW_API \ + SW_API_DEF(SW_API_FLOW_STATUS_SET, fal_flow_status_set), \ + SW_API_DEF(SW_API_FLOW_STATUS_GET, fal_flow_status_get), \ + SW_API_DEF(SW_API_FLOW_AGE_TIMER_SET, fal_flow_age_timer_set), \ + SW_API_DEF(SW_API_FLOW_AGE_TIMER_GET, fal_flow_age_timer_get), \ + SW_API_DEF(SW_API_FLOW_CTRL_SET, fal_flow_mgmt_set), \ + SW_API_DEF(SW_API_FLOW_CTRL_GET, fal_flow_mgmt_get), \ + SW_API_DEF(SW_API_FLOW_ENTRY_ADD, fal_flow_entry_add), \ + SW_API_DEF(SW_API_FLOW_ENTRY_DEL, fal_flow_entry_del), \ + SW_API_DEF(SW_API_FLOW_ENTRY_GET, fal_flow_entry_get), \ + SW_API_DEF(SW_API_FLOW_GLOBAL_CFG_GET, fal_flow_global_cfg_get), \ + SW_API_DEF(SW_API_FLOW_GLOBAL_CFG_SET, fal_flow_global_cfg_set), \ + SW_API_DEF(SW_API_FLOW_HOST_ADD, fal_flow_host_add), \ + SW_API_DEF(SW_API_FLOW_HOST_GET, fal_flow_host_get), \ + SW_API_DEF(SW_API_FLOW_HOST_DEL, fal_flow_host_del), \ + SW_API_DEF(SW_API_FLOWENTRY_NEXT, fal_flow_entry_next), + +#define FLOW_API_PARAM \ + SW_API_DESC(SW_API_FLOW_STATUS_SET) \ + SW_API_DESC(SW_API_FLOW_STATUS_GET) \ + SW_API_DESC(SW_API_FLOW_AGE_TIMER_SET) \ + SW_API_DESC(SW_API_FLOW_AGE_TIMER_GET) \ + SW_API_DESC(SW_API_FLOW_CTRL_SET) \ + SW_API_DESC(SW_API_FLOW_CTRL_GET) \ + SW_API_DESC(SW_API_FLOW_ENTRY_ADD) \ + SW_API_DESC(SW_API_FLOW_ENTRY_DEL) \ + SW_API_DESC(SW_API_FLOW_ENTRY_GET) \ + SW_API_DESC(SW_API_FLOW_GLOBAL_CFG_GET) \ + SW_API_DESC(SW_API_FLOW_GLOBAL_CFG_SET) \ + SW_API_DESC(SW_API_FLOW_HOST_ADD) \ + SW_API_DESC(SW_API_FLOW_HOST_GET) \ + SW_API_DESC(SW_API_FLOW_HOST_DEL) \ + SW_API_DESC(SW_API_FLOWENTRY_NEXT) +#else +#define FLOW_API +#define FLOW_API_PARAM +#endif + +#ifdef IN_NAT +#define NAT_API \ + SW_API_DEF(SW_API_NAT_ADD, fal_nat_add), \ + SW_API_DEF(SW_API_NAT_DEL, fal_nat_del), \ + SW_API_DEF(SW_API_NAT_GET, fal_nat_get), \ + SW_API_DEF(SW_API_NAT_NEXT, fal_nat_next), \ + SW_API_DEF(SW_API_NAT_COUNTER_BIND, fal_nat_counter_bind), \ + SW_API_DEF(SW_API_NAPT_ADD, fal_napt_add), \ + SW_API_DEF(SW_API_NAPT_DEL, fal_napt_del), \ + SW_API_DEF(SW_API_NAPT_GET, fal_napt_get), \ + SW_API_DEF(SW_API_NAPT_NEXT, fal_napt_next), \ + SW_API_DEF(SW_API_NAPT_COUNTER_BIND, fal_napt_counter_bind), \ + SW_API_DEF(SW_API_FLOW_ADD, fal_flow_add), \ + SW_API_DEF(SW_API_FLOW_DEL, fal_flow_del), \ + SW_API_DEF(SW_API_FLOW_GET, fal_flow_get), \ + SW_API_DEF(SW_API_FLOW_NEXT, fal_flow_next), \ + SW_API_DEF(SW_API_FLOW_COUNTER_BIND, fal_flow_counter_bind), \ + SW_API_DEF(SW_API_NAT_STATUS_SET, fal_nat_status_set), \ + SW_API_DEF(SW_API_NAT_STATUS_GET, fal_nat_status_get), \ + SW_API_DEF(SW_API_NAT_HASH_MODE_SET, fal_nat_hash_mode_set), \ + SW_API_DEF(SW_API_NAT_HASH_MODE_GET, fal_nat_hash_mode_get), \ + SW_API_DEF(SW_API_NAPT_STATUS_SET, fal_napt_status_set), \ + SW_API_DEF(SW_API_NAPT_STATUS_GET, fal_napt_status_get), \ + SW_API_DEF(SW_API_NAPT_MODE_SET, fal_napt_mode_set), \ + SW_API_DEF(SW_API_NAPT_MODE_GET, fal_napt_mode_get), \ + SW_API_DEF(SW_API_PRV_BASE_ADDR_SET, fal_nat_prv_base_addr_set), \ + SW_API_DEF(SW_API_PRV_BASE_ADDR_GET, fal_nat_prv_base_addr_get), \ + SW_API_DEF(SW_API_PRV_ADDR_MODE_SET, fal_nat_prv_addr_mode_set), \ + SW_API_DEF(SW_API_PRV_ADDR_MODE_GET, fal_nat_prv_addr_mode_get), \ + SW_API_DEF(SW_API_PUB_ADDR_ENTRY_ADD, fal_nat_pub_addr_add), \ + SW_API_DEF(SW_API_PUB_ADDR_ENTRY_DEL, fal_nat_pub_addr_del), \ + SW_API_DEF(SW_API_PUB_ADDR_ENTRY_NEXT, fal_nat_pub_addr_next), \ + SW_API_DEF(SW_API_NAT_UNK_SESSION_CMD_SET, fal_nat_unk_session_cmd_set), \ + SW_API_DEF(SW_API_NAT_UNK_SESSION_CMD_GET, fal_nat_unk_session_cmd_get), \ + SW_API_DEF(SW_API_PRV_BASE_MASK_SET, fal_nat_prv_base_mask_set), \ + SW_API_DEF(SW_API_PRV_BASE_MASK_GET, fal_nat_prv_base_mask_get), \ + SW_API_DEF(SW_API_NAT_GLOBAL_SET, fal_nat_global_set), \ + SW_API_DEF(SW_API_FLOW_COOKIE_SET, fal_flow_cookie_set), \ + SW_API_DEF(SW_API_FLOW_RFS_SET, fal_flow_rfs_set), + +#define NAT_API_PARAM \ + SW_API_DESC(SW_API_NAT_ADD) \ + SW_API_DESC(SW_API_NAT_DEL) \ + SW_API_DESC(SW_API_NAT_GET) \ + SW_API_DESC(SW_API_NAT_NEXT) \ + SW_API_DESC(SW_API_NAT_COUNTER_BIND) \ + SW_API_DESC(SW_API_NAPT_ADD) \ + SW_API_DESC(SW_API_NAPT_DEL) \ + SW_API_DESC(SW_API_NAPT_GET) \ + SW_API_DESC(SW_API_NAPT_NEXT) \ + SW_API_DESC(SW_API_NAPT_COUNTER_BIND) \ + SW_API_DESC(SW_API_FLOW_ADD) \ + SW_API_DESC(SW_API_FLOW_DEL) \ + SW_API_DESC(SW_API_FLOW_GET) \ + SW_API_DESC(SW_API_FLOW_NEXT) \ + SW_API_DESC(SW_API_FLOW_COUNTER_BIND) \ + SW_API_DESC(SW_API_NAT_STATUS_SET) \ + SW_API_DESC(SW_API_NAT_STATUS_GET) \ + SW_API_DESC(SW_API_NAT_HASH_MODE_SET) \ + SW_API_DESC(SW_API_NAT_HASH_MODE_GET) \ + SW_API_DESC(SW_API_NAPT_STATUS_SET) \ + SW_API_DESC(SW_API_NAPT_STATUS_GET) \ + SW_API_DESC(SW_API_NAPT_MODE_SET) \ + SW_API_DESC(SW_API_NAPT_MODE_GET) \ + SW_API_DESC(SW_API_PRV_BASE_ADDR_SET) \ + SW_API_DESC(SW_API_PRV_BASE_ADDR_GET) \ + SW_API_DESC(SW_API_PRV_ADDR_MODE_SET) \ + SW_API_DESC(SW_API_PRV_ADDR_MODE_GET) \ + SW_API_DESC(SW_API_PUB_ADDR_ENTRY_ADD) \ + SW_API_DESC(SW_API_PUB_ADDR_ENTRY_DEL) \ + SW_API_DESC(SW_API_PUB_ADDR_ENTRY_NEXT) \ + SW_API_DESC(SW_API_NAT_UNK_SESSION_CMD_SET) \ + SW_API_DESC(SW_API_NAT_UNK_SESSION_CMD_GET) \ + SW_API_DESC(SW_API_PRV_BASE_MASK_SET) \ + SW_API_DESC(SW_API_PRV_BASE_MASK_GET) \ + SW_API_DESC(SW_API_NAT_GLOBAL_SET) \ + SW_API_DESC(SW_API_FLOW_COOKIE_SET) \ + SW_API_DESC(SW_API_FLOW_RFS_SET) +#else +#define NAT_API +#define NAT_API_PARAM +#endif + +#ifdef IN_TRUNK +#define TRUNK_API \ + SW_API_DEF(SW_API_TRUNK_GROUP_SET, fal_trunk_group_set), \ + SW_API_DEF(SW_API_TRUNK_GROUP_GET, fal_trunk_group_get), \ + SW_API_DEF(SW_API_TRUNK_HASH_SET, fal_trunk_hash_mode_set), \ + SW_API_DEF(SW_API_TRUNK_HASH_GET, fal_trunk_hash_mode_get), \ + SW_API_DEF(SW_API_TRUNK_MAN_SA_SET, fal_trunk_manipulate_sa_set), \ + SW_API_DEF(SW_API_TRUNK_MAN_SA_GET, fal_trunk_manipulate_sa_get), \ + SW_API_DEF(SW_API_TRUNK_FAILOVER_EN_SET, fal_trunk_failover_enable), \ + SW_API_DEF(SW_API_TRUNK_FAILOVER_EN_GET, fal_trunk_failover_status_get), + +#define TRUNK_API_PARAM \ + SW_API_DESC(SW_API_TRUNK_GROUP_SET) \ + SW_API_DESC(SW_API_TRUNK_GROUP_GET) \ + SW_API_DESC(SW_API_TRUNK_HASH_SET) \ + SW_API_DESC(SW_API_TRUNK_HASH_GET) \ + SW_API_DESC(SW_API_TRUNK_MAN_SA_SET)\ + SW_API_DESC(SW_API_TRUNK_MAN_SA_GET)\ + SW_API_DESC(SW_API_TRUNK_FAILOVER_EN_SET)\ + SW_API_DESC(SW_API_TRUNK_FAILOVER_EN_GET) +#else +#define TRUNK_API +#define TRUNK_API_PARAM +#endif + +#ifdef IN_INTERFACECONTROL +#define INTERFACECTRL_API \ + SW_API_DEF(SW_API_MAC_MODE_SET, fal_interface_mac_mode_set), \ + SW_API_DEF(SW_API_MAC_MODE_GET, fal_interface_mac_mode_get), \ + SW_API_DEF(SW_API_PORT_3AZ_STATUS_SET, fal_port_3az_status_set), \ + SW_API_DEF(SW_API_PORT_3AZ_STATUS_GET, fal_port_3az_status_get), \ + SW_API_DEF(SW_API_PHY_MODE_SET, fal_interface_phy_mode_set), \ + SW_API_DEF(SW_API_PHY_MODE_GET, fal_interface_phy_mode_get), \ + SW_API_DEF(SW_API_FX100_CTRL_SET, fal_interface_fx100_ctrl_set), \ + SW_API_DEF(SW_API_FX100_CTRL_GET, fal_interface_fx100_ctrl_get), \ + SW_API_DEF(SW_API_FX100_STATUS_GET, fal_interface_fx100_status_get),\ + SW_API_DEF(SW_API_MAC06_EXCH_SET, fal_interface_mac06_exch_set),\ + SW_API_DEF(SW_API_MAC06_EXCH_GET, fal_interface_mac06_exch_get), + +#define INTERFACECTRL_API_PARAM \ + SW_API_DESC(SW_API_MAC_MODE_SET) \ + SW_API_DESC(SW_API_MAC_MODE_GET) \ + SW_API_DESC(SW_API_PORT_3AZ_STATUS_SET) \ + SW_API_DESC(SW_API_PORT_3AZ_STATUS_GET) \ + SW_API_DESC(SW_API_PHY_MODE_SET) \ + SW_API_DESC(SW_API_PHY_MODE_GET) \ + SW_API_DESC(SW_API_FX100_CTRL_SET) \ + SW_API_DESC(SW_API_FX100_CTRL_GET) \ + SW_API_DESC(SW_API_FX100_STATUS_GET) \ + SW_API_DESC(SW_API_MAC06_EXCH_SET) \ + SW_API_DESC(SW_API_MAC06_EXCH_GET) + +#else +#define INTERFACECTRL_API +#define INTERFACECTRL_API_PARAM +#endif + +#ifdef IN_VSI +#define VSI_API \ + SW_API_DEF(SW_API_VSI_ALLOC, fal_vsi_alloc), \ + SW_API_DEF(SW_API_VSI_FREE, fal_vsi_free), \ + SW_API_DEF(SW_API_PORT_VSI_SET, fal_port_vsi_set), \ + SW_API_DEF(SW_API_PORT_VSI_GET, fal_port_vsi_get), \ + SW_API_DEF(SW_API_PORT_VLAN_VSI_SET, fal_port_vlan_vsi_set), \ + SW_API_DEF(SW_API_PORT_VLAN_VSI_GET, fal_port_vlan_vsi_get), \ + SW_API_DEF(SW_API_VSI_TBL_DUMP, fal_vsi_tbl_dump), \ + SW_API_DEF(SW_API_VSI_NEWADDR_LRN_GET, fal_vsi_newaddr_lrn_get), \ + SW_API_DEF(SW_API_VSI_NEWADDR_LRN_SET, fal_vsi_newaddr_lrn_set), \ + SW_API_DEF(SW_API_VSI_STAMOVE_SET, fal_vsi_stamove_set), \ + SW_API_DEF(SW_API_VSI_STAMOVE_GET,fal_vsi_stamove_get), \ + SW_API_DEF(SW_API_VSI_MEMBER_SET, fal_vsi_member_set), \ + SW_API_DEF(SW_API_VSI_MEMBER_GET, fal_vsi_member_get), \ + SW_API_DEF(SW_API_VSI_COUNTER_GET,fal_vsi_counter_get), \ + SW_API_DEF(SW_API_VSI_COUNTER_CLEANUP,fal_vsi_counter_cleanup), + + +#define VSI_API_PARAM \ + SW_API_DESC(SW_API_VSI_ALLOC) \ + SW_API_DESC(SW_API_VSI_FREE) \ + SW_API_DESC(SW_API_PORT_VSI_SET) \ + SW_API_DESC(SW_API_PORT_VSI_GET) \ + SW_API_DESC(SW_API_PORT_VLAN_VSI_SET) \ + SW_API_DESC(SW_API_PORT_VLAN_VSI_GET) \ + SW_API_DESC(SW_API_VSI_TBL_DUMP) \ + SW_API_DESC(SW_API_VSI_NEWADDR_LRN_GET) \ + SW_API_DESC(SW_API_VSI_NEWADDR_LRN_SET) \ + SW_API_DESC(SW_API_VSI_STAMOVE_SET) \ + SW_API_DESC(SW_API_VSI_STAMOVE_GET) \ + SW_API_DESC(SW_API_VSI_MEMBER_SET) \ + SW_API_DESC(SW_API_VSI_MEMBER_GET) \ + SW_API_DESC(SW_API_VSI_COUNTER_GET) \ + SW_API_DESC(SW_API_VSI_COUNTER_CLEANUP) + +#else +#define VSI_API +#define VSI_API_PARAM +#endif + +#ifdef IN_QM +#define QM_API \ + SW_API_DEF(SW_API_UCAST_QUEUE_BASE_PROFILE_SET, fal_ucast_queue_base_profile_set), \ + SW_API_DEF(SW_API_UCAST_QUEUE_BASE_PROFILE_GET, fal_ucast_queue_base_profile_get), \ + SW_API_DEF(SW_API_UCAST_PRIORITY_CLASS_SET, fal_ucast_priority_class_set), \ + SW_API_DEF(SW_API_UCAST_PRIORITY_CLASS_GET, fal_ucast_priority_class_get), \ + SW_API_DEF(SW_API_MCAST_PRIORITY_CLASS_SET, fal_port_mcast_priority_class_set), \ + SW_API_DEF(SW_API_MCAST_PRIORITY_CLASS_GET, fal_port_mcast_priority_class_get), \ + SW_API_DEF(SW_API_QUEUE_FLUSH, fal_queue_flush), \ + SW_API_DEF(SW_API_UCAST_HASH_MAP_SET, fal_ucast_hash_map_set), \ + SW_API_DEF(SW_API_UCAST_HASH_MAP_GET, fal_ucast_hash_map_get), \ + SW_API_DEF(SW_API_UCAST_DFLT_HASH_MAP_SET, fal_ucast_default_hash_set), \ + SW_API_DEF(SW_API_UCAST_DFLT_HASH_MAP_GET, fal_ucast_default_hash_get), \ + SW_API_DEF(SW_API_MCAST_CPUCODE_CLASS_SET, fal_mcast_cpu_code_class_set), \ + SW_API_DEF(SW_API_MCAST_CPUCODE_CLASS_GET, fal_mcast_cpu_code_class_get), \ + SW_API_DEF(SW_API_AC_CTRL_SET, fal_ac_ctrl_set), \ + SW_API_DEF(SW_API_AC_CTRL_GET, fal_ac_ctrl_get), \ + SW_API_DEF(SW_API_AC_PRE_BUFFER_SET, fal_ac_prealloc_buffer_set), \ + SW_API_DEF(SW_API_AC_PRE_BUFFER_GET, fal_ac_prealloc_buffer_get), \ + SW_API_DEF(SW_API_QUEUE_GROUP_SET, fal_ac_queue_group_set), \ + SW_API_DEF(SW_API_QUEUE_GROUP_GET, fal_ac_queue_group_get), \ + SW_API_DEF(SW_API_STATIC_THRESH_SET, fal_ac_static_threshold_set), \ + SW_API_DEF(SW_API_STATIC_THRESH_GET, fal_ac_static_threshold_get), \ + SW_API_DEF(SW_API_DYNAMIC_THRESH_SET, fal_ac_dynamic_threshold_set), \ + SW_API_DEF(SW_API_DYNAMIC_THRESH_GET, fal_ac_dynamic_threshold_get), \ + SW_API_DEF(SW_API_GOURP_BUFFER_SET, fal_ac_group_buffer_set), \ + SW_API_DEF(SW_API_GOURP_BUFFER_GET, fal_ac_group_buffer_get), \ + SW_API_DEF(SW_API_QUEUE_CNT_CTRL_GET, fal_queue_counter_ctrl_get), \ + SW_API_DEF(SW_API_QUEUE_CNT_CTRL_SET, fal_queue_counter_ctrl_set), \ + SW_API_DEF(SW_API_QUEUE_CNT_GET, fal_queue_counter_get), \ + SW_API_DEF(SW_API_QUEUE_CNT_CLEANUP, fal_queue_counter_cleanup), \ + SW_API_DEF(SW_API_QM_ENQUEUE_CTRL_SET, fal_qm_enqueue_ctrl_set), \ + SW_API_DEF(SW_API_QM_ENQUEUE_CTRL_GET, fal_qm_enqueue_ctrl_get), \ + SW_API_DEF(SW_API_QM_SOURCE_PROFILE_SET, fal_qm_port_source_profile_set), \ + SW_API_DEF(SW_API_QM_SOURCE_PROFILE_GET, fal_qm_port_source_profile_get), + +#define QM_API_PARAM \ + SW_API_DESC(SW_API_UCAST_QUEUE_BASE_PROFILE_SET) \ + SW_API_DESC(SW_API_UCAST_QUEUE_BASE_PROFILE_GET) \ + SW_API_DESC(SW_API_UCAST_PRIORITY_CLASS_SET) \ + SW_API_DESC(SW_API_UCAST_PRIORITY_CLASS_GET) \ + SW_API_DESC(SW_API_MCAST_PRIORITY_CLASS_SET) \ + SW_API_DESC(SW_API_MCAST_PRIORITY_CLASS_GET) \ + SW_API_DESC(SW_API_QUEUE_FLUSH) \ + SW_API_DESC(SW_API_UCAST_HASH_MAP_SET) \ + SW_API_DESC(SW_API_UCAST_HASH_MAP_GET) \ + SW_API_DESC(SW_API_UCAST_DFLT_HASH_MAP_SET) \ + SW_API_DESC(SW_API_UCAST_DFLT_HASH_MAP_GET) \ + SW_API_DESC(SW_API_MCAST_CPUCODE_CLASS_SET) \ + SW_API_DESC(SW_API_MCAST_CPUCODE_CLASS_GET) \ + SW_API_DESC(SW_API_AC_CTRL_SET) \ + SW_API_DESC(SW_API_AC_CTRL_GET) \ + SW_API_DESC(SW_API_AC_PRE_BUFFER_SET) \ + SW_API_DESC(SW_API_AC_PRE_BUFFER_GET) \ + SW_API_DESC(SW_API_QUEUE_GROUP_SET) \ + SW_API_DESC(SW_API_QUEUE_GROUP_GET) \ + SW_API_DESC(SW_API_STATIC_THRESH_SET) \ + SW_API_DESC(SW_API_STATIC_THRESH_GET) \ + SW_API_DESC(SW_API_DYNAMIC_THRESH_SET) \ + SW_API_DESC(SW_API_DYNAMIC_THRESH_GET) \ + SW_API_DESC(SW_API_GOURP_BUFFER_SET) \ + SW_API_DESC(SW_API_GOURP_BUFFER_GET) \ + SW_API_DESC(SW_API_QUEUE_CNT_CTRL_GET) \ + SW_API_DESC(SW_API_QUEUE_CNT_CTRL_SET) \ + SW_API_DESC(SW_API_QUEUE_CNT_GET) \ + SW_API_DESC(SW_API_QUEUE_CNT_CLEANUP) \ + SW_API_DESC(SW_API_QM_ENQUEUE_CTRL_SET) \ + SW_API_DESC(SW_API_QM_ENQUEUE_CTRL_GET) \ + SW_API_DESC(SW_API_QM_SOURCE_PROFILE_SET) \ + SW_API_DESC(SW_API_QM_SOURCE_PROFILE_GET) + +#else +#define QM_API +#define QM_API_PARAM +#endif + + +#ifdef IN_PPPOE +#define PPPOE_API \ + SW_API_DEF(SW_API_PPPOE_CMD_SET, fal_pppoe_cmd_set), \ + SW_API_DEF(SW_API_PPPOE_CMD_GET, fal_pppoe_cmd_get), \ + SW_API_DEF(SW_API_PPPOE_STATUS_SET, fal_pppoe_status_set), \ + SW_API_DEF(SW_API_PPPOE_STATUS_GET, fal_pppoe_status_get), \ + SW_API_DEF(SW_API_PPPOE_SESSION_ADD, fal_pppoe_session_add), \ + SW_API_DEF(SW_API_PPPOE_SESSION_DEL, fal_pppoe_session_del), \ + SW_API_DEF(SW_API_PPPOE_SESSION_GET, fal_pppoe_session_get), \ + SW_API_DEF(SW_API_PPPOE_SESSION_TABLE_ADD, fal_pppoe_session_table_add), \ + SW_API_DEF(SW_API_PPPOE_SESSION_TABLE_DEL, fal_pppoe_session_table_del), \ + SW_API_DEF(SW_API_PPPOE_SESSION_TABLE_GET, fal_pppoe_session_table_get), \ + SW_API_DEF(SW_API_PPPOE_SESSION_ID_SET, fal_pppoe_session_id_set), \ + SW_API_DEF(SW_API_PPPOE_SESSION_ID_GET, fal_pppoe_session_id_get), \ + SW_API_DEF(SW_API_RTD_PPPOE_EN_SET, fal_rtd_pppoe_en_set), \ + SW_API_DEF(SW_API_RTD_PPPOE_EN_GET, fal_rtd_pppoe_en_get), \ + SW_API_DEF(SW_API_PPPOE_EN_SET, fal_pppoe_l3intf_enable), \ + SW_API_DEF(SW_API_PPPOE_EN_GET, fal_pppoe_l3intf_status_get), + +#define PPPOE_API_PARAM \ + SW_API_DESC(SW_API_PPPOE_CMD_SET) \ + SW_API_DESC(SW_API_PPPOE_CMD_GET) \ + SW_API_DESC(SW_API_PPPOE_STATUS_SET) \ + SW_API_DESC(SW_API_PPPOE_STATUS_GET) \ + SW_API_DESC(SW_API_PPPOE_SESSION_ADD) \ + SW_API_DESC(SW_API_PPPOE_SESSION_DEL) \ + SW_API_DESC(SW_API_PPPOE_SESSION_GET) \ + SW_API_DESC(SW_API_PPPOE_SESSION_TABLE_ADD) \ + SW_API_DESC(SW_API_PPPOE_SESSION_TABLE_DEL) \ + SW_API_DESC(SW_API_PPPOE_SESSION_TABLE_GET) \ + SW_API_DESC(SW_API_PPPOE_SESSION_ID_SET) \ + SW_API_DESC(SW_API_PPPOE_SESSION_ID_GET) \ + SW_API_DESC(SW_API_RTD_PPPOE_EN_SET) \ + SW_API_DESC(SW_API_RTD_PPPOE_EN_GET) \ + SW_API_DESC(SW_API_PPPOE_EN_SET) \ + SW_API_DESC(SW_API_PPPOE_EN_GET) + +#else +#define PPPOE_API +#define PPPOE_API_PARAM +#endif + +#ifdef IN_BM +#define BM_API \ + SW_API_DEF(SW_API_BM_CTRL_SET, fal_port_bm_ctrl_set), \ + SW_API_DEF(SW_API_BM_CTRL_GET, fal_port_bm_ctrl_get), \ + SW_API_DEF(SW_API_BM_PORTGROUP_MAP_SET, fal_port_bufgroup_map_set), \ + SW_API_DEF(SW_API_BM_PORTGROUP_MAP_GET, fal_port_bufgroup_map_get), \ + SW_API_DEF(SW_API_BM_GROUP_BUFFER_SET, fal_bm_bufgroup_buffer_set), \ + SW_API_DEF(SW_API_BM_GROUP_BUFFER_GET, fal_bm_bufgroup_buffer_get), \ + SW_API_DEF(SW_API_BM_PORT_RSVBUFFER_SET, fal_bm_port_reserved_buffer_set), \ + SW_API_DEF(SW_API_BM_PORT_RSVBUFFER_GET, fal_bm_port_reserved_buffer_get), \ + SW_API_DEF(SW_API_BM_STATIC_THRESH_SET, fal_bm_port_static_thresh_set), \ + SW_API_DEF(SW_API_BM_STATIC_THRESH_GET, fal_bm_port_static_thresh_get), \ + SW_API_DEF(SW_API_BM_DYNAMIC_THRESH_SET, fal_bm_port_dynamic_thresh_set), \ + SW_API_DEF(SW_API_BM_DYNAMIC_THRESH_GET, fal_bm_port_dynamic_thresh_get), \ + SW_API_DEF(SW_API_BM_PORT_COUNTER_GET, fal_bm_port_counter_get), + +#define BM_API_PARAM \ + SW_API_DESC(SW_API_BM_CTRL_SET) \ + SW_API_DESC(SW_API_BM_CTRL_GET) \ + SW_API_DESC(SW_API_BM_PORTGROUP_MAP_SET) \ + SW_API_DESC(SW_API_BM_PORTGROUP_MAP_GET) \ + SW_API_DESC(SW_API_BM_GROUP_BUFFER_SET) \ + SW_API_DESC(SW_API_BM_GROUP_BUFFER_GET) \ + SW_API_DESC(SW_API_BM_PORT_RSVBUFFER_SET) \ + SW_API_DESC(SW_API_BM_PORT_RSVBUFFER_GET) \ + SW_API_DESC(SW_API_BM_STATIC_THRESH_SET) \ + SW_API_DESC(SW_API_BM_STATIC_THRESH_GET) \ + SW_API_DESC(SW_API_BM_DYNAMIC_THRESH_SET) \ + SW_API_DESC(SW_API_BM_DYNAMIC_THRESH_GET) \ + SW_API_DESC(SW_API_BM_PORT_COUNTER_GET) + +#else +#define BM_API +#define BM_API_PARAM +#endif + +/*qca808x_start*/ +#define REG_API \ + SW_API_DEF(SW_API_PHY_GET, fal_phy_get), \ + SW_API_DEF(SW_API_PHY_SET, fal_phy_set), \ +/*qca808x_end*/\ + SW_API_DEF(SW_API_REG_GET, fal_reg_get), \ + SW_API_DEF(SW_API_REG_SET, fal_reg_set), \ + SW_API_DEF(SW_API_PSGMII_REG_GET, fal_psgmii_reg_get), \ + SW_API_DEF(SW_API_PSGMII_REG_SET, fal_psgmii_reg_set), \ + SW_API_DEF(SW_API_REG_FIELD_GET, fal_reg_field_get), \ + SW_API_DEF(SW_API_REG_FIELD_SET, fal_reg_field_set), \ + SW_API_DEF(SW_API_REG_DUMP, fal_reg_dump), \ + SW_API_DEF(SW_API_DBG_REG_DUMP, fal_dbg_reg_dump),\ + SW_API_DEF(SW_API_DBG_PSGMII_SELF_TEST, fal_debug_psgmii_self_test), \ + SW_API_DEF(SW_API_PHY_DUMP, fal_phy_dump), \ + SW_API_DEF(SW_API_UNIPHY_REG_GET, fal_uniphy_reg_get), \ + SW_API_DEF(SW_API_UNIPHY_REG_SET, fal_uniphy_reg_set),\ +/*qca808x_start*/\ + /*end of REG_API*/ +#define REG_API_PARAM \ + SW_API_DESC(SW_API_PHY_GET) \ + SW_API_DESC(SW_API_PHY_SET)\ +/*qca808x_end*/\ + SW_API_DESC(SW_API_REG_GET) \ + SW_API_DESC(SW_API_REG_SET) \ + SW_API_DESC(SW_API_PSGMII_REG_GET) \ + SW_API_DESC(SW_API_PSGMII_REG_SET) \ + SW_API_DESC(SW_API_REG_FIELD_GET) \ + SW_API_DESC(SW_API_REG_FIELD_SET) \ + SW_API_DESC(SW_API_REG_DUMP) \ + SW_API_DESC(SW_API_DBG_REG_DUMP) \ + SW_API_DESC(SW_API_DBG_PSGMII_SELF_TEST) \ + SW_API_DESC(SW_API_PHY_DUMP) \ + SW_API_DESC(SW_API_UNIPHY_REG_GET) \ + SW_API_DESC(SW_API_UNIPHY_REG_SET)\ +/*qca808x_start*/\ +/*end of REG_API_PARAM*/ +/*qca808x_end*/ +#ifdef IN_CTRLPKT +#define CTRLPKT_API \ + SW_API_DEF(SW_API_MGMTCTRL_ETHTYPE_PROFILE_SET, fal_mgmtctrl_ethtype_profile_set), \ + SW_API_DEF(SW_API_MGMTCTRL_ETHTYPE_PROFILE_GET, fal_mgmtctrl_ethtype_profile_get), \ + SW_API_DEF(SW_API_MGMTCTRL_RFDB_PROFILE_SET, fal_mgmtctrl_rfdb_profile_set), \ + SW_API_DEF(SW_API_MGMTCTRL_RFDB_PROFILE_GET, fal_mgmtctrl_rfdb_profile_get), \ + SW_API_DEF(SW_API_MGMTCTRL_CTRLPKT_PROFILE_ADD, fal_mgmtctrl_ctrlpkt_profile_add), \ + SW_API_DEF(SW_API_MGMTCTRL_CTRLPKT_PROFILE_DEL, fal_mgmtctrl_ctrlpkt_profile_del), \ + SW_API_DEF(SW_API_MGMTCTRL_CTRLPKT_PROFILE_GETFIRST, fal_mgmtctrl_ctrlpkt_profile_getfirst), \ + SW_API_DEF(SW_API_MGMTCTRL_CTRLPKT_PROFILE_GETNEXT, fal_mgmtctrl_ctrlpkt_profile_getnext), + +#define CTRLPKT_API_PARAM \ + SW_API_DESC(SW_API_MGMTCTRL_ETHTYPE_PROFILE_SET) \ + SW_API_DESC(SW_API_MGMTCTRL_ETHTYPE_PROFILE_GET) \ + SW_API_DESC(SW_API_MGMTCTRL_RFDB_PROFILE_SET) \ + SW_API_DESC(SW_API_MGMTCTRL_RFDB_PROFILE_GET) \ + SW_API_DESC(SW_API_MGMTCTRL_CTRLPKT_PROFILE_ADD) \ + SW_API_DESC(SW_API_MGMTCTRL_CTRLPKT_PROFILE_DEL) \ + SW_API_DESC(SW_API_MGMTCTRL_CTRLPKT_PROFILE_GETFIRST) \ + SW_API_DESC(SW_API_MGMTCTRL_CTRLPKT_PROFILE_GETNEXT) +#else +#define CTRLPKT_API +#define CTRLPKT_API_PARAM +#endif + +#ifdef IN_SERVCODE +#define SERVCODE_API \ + SW_API_DEF(SW_API_SERVCODE_CONFIG_SET, fal_servcode_config_set), \ + SW_API_DEF(SW_API_SERVCODE_CONFIG_GET, fal_servcode_config_get), \ + SW_API_DEF(SW_API_SERVCODE_LOOPCHECK_EN, fal_servcode_loopcheck_en), \ + SW_API_DEF(SW_API_SERVCODE_LOOPCHECK_STATUS_GET, fal_servcode_loopcheck_status_get), + +#define SERVCODE_API_PARAM \ + SW_API_DESC(SW_API_SERVCODE_CONFIG_SET) \ + SW_API_DESC(SW_API_SERVCODE_CONFIG_GET) \ + SW_API_DESC(SW_API_SERVCODE_LOOPCHECK_EN) \ + SW_API_DESC(SW_API_SERVCODE_LOOPCHECK_STATUS_GET) +#else +#define SERVCODE_API +#define SERVCODE_API_PARAM +#endif + +#ifdef IN_RSS_HASH +#define RSS_HASH_API \ + SW_API_DEF(SW_API_RSS_HASH_CONFIG_SET, fal_rss_hash_config_set), \ + SW_API_DEF(SW_API_RSS_HASH_CONFIG_GET, fal_rss_hash_config_get), + +#define RSS_HASH_API_PARAM \ + SW_API_DESC(SW_API_RSS_HASH_CONFIG_SET) \ + SW_API_DESC(SW_API_RSS_HASH_CONFIG_GET) +#else +#define RSS_HASH_API +#define RSS_HASH_API_PARAM +#endif + +#ifdef IN_SHAPER +#define SHAPER_API \ + SW_API_DEF(SW_API_PORT_SHAPER_TIMESLOT_SET, fal_port_shaper_timeslot_set), \ + SW_API_DEF(SW_API_PORT_SHAPER_TIMESLOT_GET, fal_port_shaper_timeslot_get), \ + SW_API_DEF(SW_API_FLOW_SHAPER_TIMESLOT_SET, fal_flow_shaper_timeslot_set), \ + SW_API_DEF(SW_API_FLOW_SHAPER_TIMESLOT_GET, fal_flow_shaper_timeslot_get), \ + SW_API_DEF(SW_API_QUEUE_SHAPER_TIMESLOT_SET, fal_queue_shaper_timeslot_set), \ + SW_API_DEF(SW_API_QUEUE_SHAPER_TIMESLOT_GET, fal_queue_shaper_timeslot_get), \ + SW_API_DEF(SW_API_PORT_SHAPER_TOKEN_NUMBER_SET, fal_port_shaper_token_number_set), \ + SW_API_DEF(SW_API_PORT_SHAPER_TOKEN_NUMBER_GET, fal_port_shaper_token_number_get), \ + SW_API_DEF(SW_API_FLOW_SHAPER_TOKEN_NUMBER_SET, fal_flow_shaper_token_number_set), \ + SW_API_DEF(SW_API_FLOW_SHAPER_TOKEN_NUMBER_GET, fal_flow_shaper_token_number_get), \ + SW_API_DEF(SW_API_QUEUE_SHAPER_TOKEN_NUMBER_SET, fal_queue_shaper_token_number_set), \ + SW_API_DEF(SW_API_QUEUE_SHAPER_TOKEN_NUMBER_GET, fal_queue_shaper_token_number_get), \ + SW_API_DEF(SW_API_PORT_SHAPER_SET, fal_port_shaper_set), \ + SW_API_DEF(SW_API_PORT_SHAPER_GET,fal_port_shaper_get), \ + SW_API_DEF(SW_API_FLOW_SHAPER_SET, fal_flow_shaper_set), \ + SW_API_DEF(SW_API_FLOW_SHAPER_GET,fal_flow_shaper_get), \ + SW_API_DEF(SW_API_QUEUE_SHAPER_SET, fal_queue_shaper_set), \ + SW_API_DEF(SW_API_QUEUE_SHAPER_GET,fal_queue_shaper_get), \ + SW_API_DEF(SW_API_SHAPER_IPG_PRE_SET, fal_shaper_ipg_preamble_length_set), \ + SW_API_DEF(SW_API_SHAPER_IPG_PRE_GET,fal_shaper_ipg_preamble_length_get), + + +#define SHAPER_API_PARAM \ + SW_API_DESC(SW_API_PORT_SHAPER_TIMESLOT_SET) \ + SW_API_DESC(SW_API_PORT_SHAPER_TIMESLOT_GET) \ + SW_API_DESC(SW_API_FLOW_SHAPER_TIMESLOT_SET) \ + SW_API_DESC(SW_API_FLOW_SHAPER_TIMESLOT_GET) \ + SW_API_DESC(SW_API_QUEUE_SHAPER_TIMESLOT_SET) \ + SW_API_DESC(SW_API_QUEUE_SHAPER_TIMESLOT_GET) \ + SW_API_DESC(SW_API_PORT_SHAPER_TOKEN_NUMBER_SET) \ + SW_API_DESC(SW_API_PORT_SHAPER_TOKEN_NUMBER_GET) \ + SW_API_DESC(SW_API_FLOW_SHAPER_TOKEN_NUMBER_SET) \ + SW_API_DESC(SW_API_FLOW_SHAPER_TOKEN_NUMBER_GET) \ + SW_API_DESC(SW_API_QUEUE_SHAPER_TOKEN_NUMBER_SET) \ + SW_API_DESC(SW_API_QUEUE_SHAPER_TOKEN_NUMBER_GET) \ + SW_API_DESC(SW_API_PORT_SHAPER_SET) \ + SW_API_DESC(SW_API_PORT_SHAPER_GET) \ + SW_API_DESC(SW_API_FLOW_SHAPER_SET) \ + SW_API_DESC(SW_API_FLOW_SHAPER_GET) \ + SW_API_DESC(SW_API_QUEUE_SHAPER_SET) \ + SW_API_DESC(SW_API_QUEUE_SHAPER_GET) \ + SW_API_DESC(SW_API_SHAPER_IPG_PRE_SET) \ + SW_API_DESC(SW_API_SHAPER_IPG_PRE_GET) + +#else +#define SHAPER_API +#define SHAPER_API_PARAM +#endif + + +#ifdef IN_POLICER +#define POLICER_API \ + SW_API_DEF(SW_API_POLICER_TIMESLOT_SET, fal_policer_timeslot_set), \ + SW_API_DEF(SW_API_POLICER_TIMESLOT_GET, fal_policer_timeslot_get), \ + SW_API_DEF(SW_API_POLICER_PORT_COUNTER_GET, fal_port_policer_counter_get), \ + SW_API_DEF(SW_API_POLICER_ACL_COUNTER_GET, fal_acl_policer_counter_get), \ + SW_API_DEF(SW_API_POLICER_COMPENSATION_SET, fal_port_policer_compensation_byte_set), \ + SW_API_DEF(SW_API_POLICER_COMPENSATION_GET, fal_port_policer_compensation_byte_get), \ + SW_API_DEF(SW_API_POLICER_PORT_ENTRY_SET, fal_port_policer_entry_set), \ + SW_API_DEF(SW_API_POLICER_PORT_ENTRY_GET, fal_port_policer_entry_get), \ + SW_API_DEF(SW_API_POLICER_ACL_ENTRY_SET, fal_acl_policer_entry_set), \ + SW_API_DEF(SW_API_POLICER_ACL_ENTRY_GET,fal_acl_policer_entry_get), \ + SW_API_DEF(SW_API_POLICER_GLOBAL_COUNTER_GET, fal_policer_global_counter_get), + +#define POLICER_API_PARAM \ + SW_API_DESC(SW_API_POLICER_TIMESLOT_SET) \ + SW_API_DESC(SW_API_POLICER_TIMESLOT_GET) \ + SW_API_DESC(SW_API_POLICER_PORT_COUNTER_GET) \ + SW_API_DESC(SW_API_POLICER_ACL_COUNTER_GET) \ + SW_API_DESC(SW_API_POLICER_COMPENSATION_SET) \ + SW_API_DESC(SW_API_POLICER_COMPENSATION_GET) \ + SW_API_DESC(SW_API_POLICER_PORT_ENTRY_SET) \ + SW_API_DESC(SW_API_POLICER_PORT_ENTRY_GET) \ + SW_API_DESC(SW_API_POLICER_ACL_ENTRY_SET) \ + SW_API_DESC(SW_API_POLICER_ACL_ENTRY_GET) \ + SW_API_DESC(SW_API_POLICER_GLOBAL_COUNTER_GET) + +#else +#define POLICER_API +#define POLICER_API_PARAM +#endif + +#ifdef IN_PTP +#define PTP_API \ + SW_API_DEF(SW_API_PTP_CONFIG_SET, fal_ptp_config_set), \ + SW_API_DEF(SW_API_PTP_CONFIG_GET, fal_ptp_config_get), \ + SW_API_DEF(SW_API_PTP_REFERENCE_CLOCK_SET, fal_ptp_reference_clock_set), \ + SW_API_DEF(SW_API_PTP_REFERENCE_CLOCK_GET, fal_ptp_reference_clock_get), \ + SW_API_DEF(SW_API_PTP_RX_TIMESTAMP_MODE_SET, fal_ptp_rx_timestamp_mode_set), \ + SW_API_DEF(SW_API_PTP_RX_TIMESTAMP_MODE_GET, fal_ptp_rx_timestamp_mode_get), \ + SW_API_DEF(SW_API_PTP_TIMESTAMP_GET, fal_ptp_timestamp_get), \ + SW_API_DEF(SW_API_PTP_PKT_TIMESTAMP_SET, fal_ptp_pkt_timestamp_set), \ + SW_API_DEF(SW_API_PTP_PKT_TIMESTAMP_GET, fal_ptp_pkt_timestamp_get), \ + SW_API_DEF(SW_API_PTP_GRANDMASTER_MODE_SET, fal_ptp_grandmaster_mode_set), \ + SW_API_DEF(SW_API_PTP_GRANDMASTER_MODE_GET, fal_ptp_grandmaster_mode_get), \ + SW_API_DEF(SW_API_PTP_RTC_TIME_SET, fal_ptp_rtc_time_set), \ + SW_API_DEF(SW_API_PTP_RTC_TIME_GET, fal_ptp_rtc_time_get), \ + SW_API_DEF(SW_API_PTP_RTC_TIME_CLEAR, fal_ptp_rtc_time_clear), \ + SW_API_DEF(SW_API_PTP_RTC_ADJTIME_SET, fal_ptp_rtc_adjtime_set), \ + SW_API_DEF(SW_API_PTP_RTC_ADJFREQ_SET, fal_ptp_rtc_adjfreq_set), \ + SW_API_DEF(SW_API_PTP_RTC_ADJFREQ_GET, fal_ptp_rtc_adjfreq_get), \ + SW_API_DEF(SW_API_PTP_LINK_DELAY_SET, fal_ptp_link_delay_set), \ + SW_API_DEF(SW_API_PTP_LINK_DELAY_GET, fal_ptp_link_delay_get), \ + SW_API_DEF(SW_API_PTP_SECURITY_SET, fal_ptp_security_set), \ + SW_API_DEF(SW_API_PTP_SECURITY_GET, fal_ptp_security_get), \ + SW_API_DEF(SW_API_PTP_PPS_SIGNAL_CONTROL_SET, fal_ptp_pps_signal_control_set), \ + SW_API_DEF(SW_API_PTP_PPS_SIGNAL_CONTROL_GET, fal_ptp_pps_signal_control_get), \ + SW_API_DEF(SW_API_PTP_RX_CRC_RECALC_SET, fal_ptp_rx_crc_recalc_enable), \ + SW_API_DEF(SW_API_PTP_RX_CRC_RECALC_GET, fal_ptp_rx_crc_recalc_status_get), \ + SW_API_DEF(SW_API_PTP_ASYM_CORRECTION_SET, fal_ptp_asym_correction_set), \ + SW_API_DEF(SW_API_PTP_ASYM_CORRECTION_GET, fal_ptp_asym_correction_get), \ + SW_API_DEF(SW_API_PTP_OUTPUT_WAVEFORM_SET, fal_ptp_output_waveform_set), \ + SW_API_DEF(SW_API_PTP_OUTPUT_WAVEFORM_GET, fal_ptp_output_waveform_get), \ + SW_API_DEF(SW_API_PTP_RTC_TIME_SNAPSHOT_SET, fal_ptp_rtc_time_snapshot_enable), \ + SW_API_DEF(SW_API_PTP_RTC_TIME_SNAPSHOT_GET, fal_ptp_rtc_time_snapshot_status_get), \ + SW_API_DEF(SW_API_PTP_INCREMENT_SYNC_FROM_CLOCK_SET, \ + fal_ptp_increment_sync_from_clock_enable), \ + SW_API_DEF(SW_API_PTP_INCREMENT_SYNC_FROM_CLOCK_GET, \ + fal_ptp_increment_sync_from_clock_status_get), \ + SW_API_DEF(SW_API_PTP_TOD_UART_SET, fal_ptp_tod_uart_set), \ + SW_API_DEF(SW_API_PTP_TOD_UART_GET, fal_ptp_tod_uart_get), \ + SW_API_DEF(SW_API_PTP_ENHANCED_TIMESTAMP_ENGINE_SET, fal_ptp_enhanced_timestamp_engine_set), \ + SW_API_DEF(SW_API_PTP_ENHANCED_TIMESTAMP_ENGINE_GET, fal_ptp_enhanced_timestamp_engine_get), \ + SW_API_DEF(SW_API_PTP_TRIGGER_SET, fal_ptp_trigger_set), \ + SW_API_DEF(SW_API_PTP_TRIGGER_GET, fal_ptp_trigger_get), \ + SW_API_DEF(SW_API_PTP_CAPTURE_SET, fal_ptp_capture_set), \ + SW_API_DEF(SW_API_PTP_CAPTURE_GET, fal_ptp_capture_get), \ + SW_API_DEF(SW_API_PTP_INTERRUPT_SET, fal_ptp_interrupt_set), \ + SW_API_DEF(SW_API_PTP_INTERRUPT_GET, fal_ptp_interrupt_get), + +#define PTP_API_PARAM \ + SW_API_DESC(SW_API_PTP_CONFIG_SET) \ + SW_API_DESC(SW_API_PTP_CONFIG_GET) \ + SW_API_DESC(SW_API_PTP_REFERENCE_CLOCK_SET) \ + SW_API_DESC(SW_API_PTP_REFERENCE_CLOCK_GET) \ + SW_API_DESC(SW_API_PTP_RX_TIMESTAMP_MODE_SET) \ + SW_API_DESC(SW_API_PTP_RX_TIMESTAMP_MODE_GET) \ + SW_API_DESC(SW_API_PTP_TIMESTAMP_GET) \ + SW_API_DESC(SW_API_PTP_PKT_TIMESTAMP_SET) \ + SW_API_DESC(SW_API_PTP_PKT_TIMESTAMP_GET) \ + SW_API_DESC(SW_API_PTP_GRANDMASTER_MODE_SET) \ + SW_API_DESC(SW_API_PTP_GRANDMASTER_MODE_GET) \ + SW_API_DESC(SW_API_PTP_RTC_TIME_SET) \ + SW_API_DESC(SW_API_PTP_RTC_TIME_GET) \ + SW_API_DESC(SW_API_PTP_RTC_TIME_CLEAR) \ + SW_API_DESC(SW_API_PTP_RTC_ADJTIME_SET) \ + SW_API_DESC(SW_API_PTP_RTC_ADJFREQ_SET) \ + SW_API_DESC(SW_API_PTP_RTC_ADJFREQ_GET) \ + SW_API_DESC(SW_API_PTP_LINK_DELAY_SET) \ + SW_API_DESC(SW_API_PTP_LINK_DELAY_GET) \ + SW_API_DESC(SW_API_PTP_SECURITY_SET) \ + SW_API_DESC(SW_API_PTP_SECURITY_GET) \ + SW_API_DESC(SW_API_PTP_PPS_SIGNAL_CONTROL_SET) \ + SW_API_DESC(SW_API_PTP_PPS_SIGNAL_CONTROL_GET) \ + SW_API_DESC(SW_API_PTP_RX_CRC_RECALC_SET) \ + SW_API_DESC(SW_API_PTP_RX_CRC_RECALC_GET) \ + SW_API_DESC(SW_API_PTP_ASYM_CORRECTION_SET) \ + SW_API_DESC(SW_API_PTP_ASYM_CORRECTION_GET) \ + SW_API_DESC(SW_API_PTP_OUTPUT_WAVEFORM_SET) \ + SW_API_DESC(SW_API_PTP_OUTPUT_WAVEFORM_GET) \ + SW_API_DESC(SW_API_PTP_RTC_TIME_SNAPSHOT_SET) \ + SW_API_DESC(SW_API_PTP_RTC_TIME_SNAPSHOT_GET) \ + SW_API_DESC(SW_API_PTP_INCREMENT_SYNC_FROM_CLOCK_SET) \ + SW_API_DESC(SW_API_PTP_INCREMENT_SYNC_FROM_CLOCK_GET) \ + SW_API_DESC(SW_API_PTP_TOD_UART_SET) \ + SW_API_DESC(SW_API_PTP_TOD_UART_GET) \ + SW_API_DESC(SW_API_PTP_ENHANCED_TIMESTAMP_ENGINE_SET) \ + SW_API_DESC(SW_API_PTP_ENHANCED_TIMESTAMP_ENGINE_GET) \ + SW_API_DESC(SW_API_PTP_TRIGGER_SET) \ + SW_API_DESC(SW_API_PTP_TRIGGER_GET) \ + SW_API_DESC(SW_API_PTP_CAPTURE_SET) \ + SW_API_DESC(SW_API_PTP_CAPTURE_GET) \ + SW_API_DESC(SW_API_PTP_INTERRUPT_SET) \ + SW_API_DESC(SW_API_PTP_INTERRUPT_GET) +#else +#define PTP_API +#define PTP_API_PARAM +#endif + +#ifdef IN_SFP +#define SFP_API \ + SW_API_DEF(SW_API_SFP_DATA_GET, fal_sfp_eeprom_data_get), \ + SW_API_DEF(SW_API_SFP_DATA_SET, fal_sfp_eeprom_data_set), \ + SW_API_DEF(SW_API_SFP_DEV_TYPE_GET, fal_sfp_device_type_get), \ + SW_API_DEF(SW_API_SFP_TRANSC_CODE_GET, fal_sfp_transceiver_code_get), \ + SW_API_DEF(SW_API_SFP_RATE_ENCODE_GET, fal_sfp_rate_encode_get), \ + SW_API_DEF(SW_API_SFP_LINK_LENGTH_GET, fal_sfp_link_length_get), \ + SW_API_DEF(SW_API_SFP_VENDOR_INFO_GET, fal_sfp_vendor_info_get), \ + SW_API_DEF(SW_API_SFP_LASER_WAVELENGTH_GET, fal_sfp_laser_wavelength_get), \ + SW_API_DEF(SW_API_SFP_OPTION_GET, fal_sfp_option_get), \ + SW_API_DEF(SW_API_SFP_CTRL_RATE_GET, fal_sfp_ctrl_rate_get), \ + SW_API_DEF(SW_API_SFP_ENHANCED_CFG_GET, fal_sfp_enhanced_cfg_get), \ + SW_API_DEF(SW_API_SFP_DIAG_THRESHOLD_GET, fal_sfp_diag_internal_threshold_get), \ + SW_API_DEF(SW_API_SFP_DIAG_CAL_CONST_GET, fal_sfp_diag_extenal_calibration_const_get), \ + SW_API_DEF(SW_API_SFP_DIAG_REALTIME_GET, fal_sfp_diag_realtime_get), \ + SW_API_DEF(SW_API_SFP_DIAG_CTRL_STATUS_GET, fal_sfp_diag_ctrl_status_get), \ + SW_API_DEF(SW_API_SFP_DIAG_ALARM_WARN_FLAG_GET, fal_sfp_diag_alarm_warning_flag_get), \ + SW_API_DEF(SW_API_SFP_CHECKCODE_GET, fal_sfp_checkcode_get), + +#define SFP_API_PARAM \ + SW_API_DESC(SW_API_SFP_DATA_GET) \ + SW_API_DESC(SW_API_SFP_DATA_SET) \ + SW_API_DESC(SW_API_SFP_DEV_TYPE_GET) \ + SW_API_DESC(SW_API_SFP_TRANSC_CODE_GET) \ + SW_API_DESC(SW_API_SFP_RATE_ENCODE_GET) \ + SW_API_DESC(SW_API_SFP_LINK_LENGTH_GET) \ + SW_API_DESC(SW_API_SFP_VENDOR_INFO_GET) \ + SW_API_DESC(SW_API_SFP_LASER_WAVELENGTH_GET) \ + SW_API_DESC(SW_API_SFP_OPTION_GET) \ + SW_API_DESC(SW_API_SFP_CTRL_RATE_GET) \ + SW_API_DESC(SW_API_SFP_ENHANCED_CFG_GET) \ + SW_API_DESC(SW_API_SFP_DIAG_THRESHOLD_GET) \ + SW_API_DESC(SW_API_SFP_DIAG_CAL_CONST_GET) \ + SW_API_DESC(SW_API_SFP_DIAG_REALTIME_GET) \ + SW_API_DESC(SW_API_SFP_DIAG_CTRL_STATUS_GET) \ + SW_API_DESC(SW_API_SFP_DIAG_ALARM_WARN_FLAG_GET) \ + SW_API_DESC(SW_API_SFP_CHECKCODE_GET) +#else +#define SFP_API +#define SFP_API_PARAM +#endif + +/*qca808x_start*/ +#define SSDK_API \ +/*qca808x_end*/\ + SW_API_DEF(SW_API_SWITCH_RESET, fal_reset), \ + SW_API_DEF(SW_API_SSDK_CFG, fal_ssdk_cfg), \ + SW_API_DEF(SW_API_MODULE_FUNC_CTRL_SET, fal_module_func_ctrl_set), \ + SW_API_DEF(SW_API_MODULE_FUNC_CTRL_GET, fal_module_func_ctrl_get), \ + /*qca808x_start*/\ + PORTCONTROL_API \ +/*qca808x_end*/\ + VLAN_API \ + PORTVLAN_API \ + FDB_API \ + ACL_API \ + QOS_API \ + IGMP_API \ + LEAKY_API \ + MIRROR_API \ + RATE_API \ + STP_API \ + MIB_API \ + MISC_API \ + LED_API \ + COSMAP_API \ + SEC_API \ + IP_API \ + NAT_API \ + FLOW_API \ + TRUNK_API \ + INTERFACECTRL_API \ + VSI_API \ + QM_API \ + BM_API \ + PPPOE_API \ +/*qca808x_start*/\ + REG_API \ +/*qca808x_end*/\ + CTRLPKT_API \ + SERVCODE_API \ + RSS_HASH_API \ + POLICER_API \ + SHAPER_API \ + PTP_API \ + SFP_API \ +/*qca808x_start*/\ + SW_API_DEF(SW_API_MAX, NULL), + + +#define SSDK_PARAM \ +/*qca808x_end*/\ + SW_PARAM_DEF(SW_API_SWITCH_RESET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SSDK_CFG, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_SSDK_CFG, SW_SSDK_CFG, sizeof(ssdk_cfg_t), SW_PARAM_PTR|SW_PARAM_OUT, "ssdk configuration"), \ + SW_PARAM_DEF(SW_API_MODULE_FUNC_CTRL_SET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MODULE_FUNC_CTRL_SET, SW_MODULE, 4, SW_PARAM_IN, "Module"), \ + SW_PARAM_DEF(SW_API_MODULE_FUNC_CTRL_SET, SW_FUNC_CTRL, sizeof(fal_func_ctrl_t), SW_PARAM_PTR|SW_PARAM_IN, "Function bitmap"), \ + SW_PARAM_DEF(SW_API_MODULE_FUNC_CTRL_GET, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), \ + SW_PARAM_DEF(SW_API_MODULE_FUNC_CTRL_GET, SW_MODULE, 4, SW_PARAM_IN, "Module"), \ + SW_PARAM_DEF(SW_API_MODULE_FUNC_CTRL_GET, SW_FUNC_CTRL, sizeof(fal_func_ctrl_t), SW_PARAM_PTR|SW_PARAM_OUT, "Function bitmap"), \ + MIB_API_PARAM \ + LEAKY_API_PARAM \ + MISC_API_PARAM \ + IGMP_API_PARAM \ + MIRROR_API_PARAM \ +/*qca808x_start*/\ + PORTCONTROL_API_PARAM \ +/*qca808x_end*/\ + PORTVLAN_API_PARAM \ + VLAN_API_PARAM \ + FDB_API_PARAM \ + QOS_API_PARAM \ + RATE_API_PARAM \ + STP_API_PARAM \ + ACL_API_PARAM \ + LED_API_PARAM \ + COSMAP_API_PARAM \ + SEC_API_PARAM \ + IP_API_PARAM \ + NAT_API_PARAM \ + FLOW_API_PARAM \ + TRUNK_API_PARAM \ + INTERFACECTRL_API_PARAM \ + VSI_API_PARAM \ + QM_API_PARAM \ + BM_API_PARAM \ + PPPOE_API_PARAM \ +/*qca808x_start*/\ + REG_API_PARAM \ +/*qca808x_end*/\ + CTRLPKT_API_PARAM \ + SERVCODE_API_PARAM \ + RSS_HASH_API_PARAM \ + POLICER_API_PARAM \ + SHAPER_API_PARAM \ + PTP_API_PARAM \ + SFP_API_PARAM \ +/*qca808x_start*/\ + SW_PARAM_DEF(SW_API_MAX, SW_UINT32, 4, SW_PARAM_IN, "Dev ID"), + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* _FAL_API_H_ */ +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_bm.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_bm.h new file mode 100755 index 000000000..b8931053e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_bm.h @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/** + * @defgroup fal_qos FAL_BM + * @{ + */ +#ifndef _FAL_BM_H_ +#define _FAL_BM_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "common/sw.h" +#include "fal/fal_type.h" + +typedef struct +{ + a_uint16_t max_thresh; /* Static Maximum threshold */ + a_uint16_t resume_off; /*resume offset */ +} fal_bm_static_cfg_t; + +typedef struct +{ + a_uint8_t weight; /* port weight in the shared group */ + a_uint16_t shared_ceiling; /* Maximum shared buffers */ + a_uint16_t resume_off; /*resume offset */ + a_uint16_t resume_min_thresh; /* Minumum thresh for resume */ +} fal_bm_dynamic_cfg_t; + +enum { + FUNC_PORT_BUFGROUP_MAP_GET = 0, + FUNC_BM_PORT_RESERVED_BUFFER_GET, + FUNC_BM_BUFGROUP_BUFFER_GET, + FUNC_BM_PORT_DYNAMIC_THRESH_GET, + FUNC_PORT_BM_CTRL_GET, + FUNC_BM_BUFGROUP_BUFFER_SET, + FUNC_PORT_BUFGROUP_MAP_SET, + FUNC_BM_PORT_STATIC_THRESH_GET, + FUNC_BM_PORT_RESERVED_BUFFER_SET, + FUNC_BM_PORT_STATIC_THRESH_SET, + FUNC_BM_PORT_DYNAMIC_THRESH_SET, + FUNC_PORT_BM_CTRL_SET, + FUNC_PORT_TDM_CTRL_SET, + FUNC_PORT_TDM_TICK_CFG_SET, + FUNC_BM_PORT_COUNTER_GET, +}; + +typedef struct +{ + a_uint64_t drop_byte_counter; /*drop byte due to overload*/ + a_uint32_t drop_packet_counter; /*drop packet due to overload*/ + a_uint64_t fc_drop_byte_counter; /*drop byte due to fc*/ + a_uint32_t fc_drop_packet_counter; /*drop packet due to fc*/ + a_uint32_t used_counter; /*total used buffer counter for the port*/ + a_uint32_t react_counter; /*react used buffer counter for the port*/ +} fal_bm_port_counter_t; + +sw_error_t +fal_port_bm_ctrl_set(a_uint32_t dev_id, fal_port_t port, a_bool_t enable); + +sw_error_t +fal_port_bm_ctrl_get(a_uint32_t dev_id, fal_port_t port, a_bool_t *enable); + +sw_error_t +fal_port_bufgroup_map_set(a_uint32_t dev_id, fal_port_t port, + a_uint8_t group); + +sw_error_t +fal_port_bufgroup_map_get(a_uint32_t dev_id, fal_port_t port, + a_uint8_t *group); + +sw_error_t +fal_bm_bufgroup_buffer_set(a_uint32_t dev_id, a_uint8_t group, + a_uint16_t buff_num); + +sw_error_t +fal_bm_bufgroup_buffer_get(a_uint32_t dev_id, a_uint8_t group, + a_uint16_t *buff_num); + +sw_error_t +fal_bm_port_reserved_buffer_set(a_uint32_t dev_id, fal_port_t port, + a_uint16_t prealloc_buff, a_uint16_t react_buff); + +sw_error_t +fal_bm_port_reserved_buffer_get(a_uint32_t dev_id, fal_port_t port, + a_uint16_t *prealloc_buff, a_uint16_t *react_buff); + +sw_error_t +fal_bm_port_static_thresh_set(a_uint32_t dev_id, fal_port_t port, + fal_bm_static_cfg_t *cfg); + +sw_error_t +fal_bm_port_static_thresh_get(a_uint32_t dev_id, fal_port_t port, + fal_bm_static_cfg_t *cfg); + +sw_error_t +fal_bm_port_dynamic_thresh_set(a_uint32_t dev_id, fal_port_t port, + fal_bm_dynamic_cfg_t *cfg); + +sw_error_t +fal_bm_port_dynamic_thresh_get(a_uint32_t dev_id, fal_port_t port, + fal_bm_dynamic_cfg_t *cfg); + +sw_error_t +fal_bm_port_counter_get(a_uint32_t dev_id, fal_port_t port, + fal_bm_port_counter_t *counter); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _PORT_BM_H_ */ +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_cosmap.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_cosmap.h new file mode 100755 index 000000000..c8a9eff09 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_cosmap.h @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/** + * @defgroup fal_cosmap FAL_COSMAP + * @{ + */ +#ifndef _FAL_COSMAP_H_ +#define _FAL_COSMAP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "common/sw.h" +#include "fal/fal_type.h" + + typedef struct + { + a_bool_t remark_dscp; + a_bool_t remark_up; + a_bool_t remark_dei; + a_uint8_t g_dscp; + a_uint8_t y_dscp; + a_uint8_t g_up; + a_uint8_t y_up; + a_uint8_t g_dei; + a_uint8_t y_dei; + } fal_egress_remark_table_t; + + sw_error_t + fal_cosmap_dscp_to_pri_set(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t pri); + + sw_error_t + fal_cosmap_dscp_to_pri_get(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t * pri); + + sw_error_t + fal_cosmap_dscp_to_dp_set(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t dp); + + sw_error_t + fal_cosmap_dscp_to_dp_get(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t * dp); + + sw_error_t + fal_cosmap_up_to_pri_set(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t pri); + + sw_error_t + fal_cosmap_up_to_pri_get(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t * pri); + + sw_error_t + fal_cosmap_up_to_dp_set(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t dp); + + sw_error_t + fal_cosmap_up_to_dp_get(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t * dp); + + sw_error_t + fal_cosmap_dscp_to_ehpri_set(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t pri); + + sw_error_t + fal_cosmap_dscp_to_ehpri_get(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t * pri); + + sw_error_t + fal_cosmap_dscp_to_ehdp_set(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t dp); + + sw_error_t + fal_cosmap_dscp_to_ehdp_get(a_uint32_t dev_id, a_uint32_t dscp, + a_uint32_t * dp); + + sw_error_t + fal_cosmap_up_to_ehpri_set(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t pri); + + sw_error_t + fal_cosmap_up_to_ehpri_get(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t * pri); + + sw_error_t + fal_cosmap_up_to_ehdp_set(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t dp); + + sw_error_t + fal_cosmap_up_to_ehdp_get(a_uint32_t dev_id, a_uint32_t up, + a_uint32_t * dp); + + sw_error_t + fal_cosmap_pri_to_queue_set(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue); + + sw_error_t + fal_cosmap_pri_to_queue_get(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue); + + sw_error_t + fal_cosmap_pri_to_ehqueue_set(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue); + + sw_error_t + fal_cosmap_pri_to_ehqueue_get(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue); + + sw_error_t + fal_cosmap_egress_remark_set(a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl); + + sw_error_t + fal_cosmap_egress_remark_get(a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl); +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_COSMAP_H_ */ + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_ctrlpkt.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_ctrlpkt.h new file mode 100755 index 000000000..e2419d157 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_ctrlpkt.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +/** + * @defgroup fal_ctrlpkt FAL_CTRLPKT + * @{ + */ +#ifndef _FAL_CTRLPKT_H_ +#define _FAL_CTRLPKT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "common/sw.h" +#include "fal/fal_type.h" + +typedef struct { + fal_fwd_cmd_t action; /* the action when condition matched */ + a_bool_t sg_bypass; /* check if sg_bypass when condition matched */ + a_bool_t l2_filter_bypass; /* check if l2_filter_bypass when condition matched */ + a_bool_t in_stp_bypass; /* check if in_stp_bypass when condition matched */ + a_bool_t in_vlan_fltr_bypass; /* check if in_vlan_fltr_bypass when condition matched */ +} fal_ctrlpkt_action_t; + +typedef struct +{ + a_bool_t mgt_eapol; /* eapol protocol management type */ + a_bool_t mgt_pppoe; /* pppoe protocol management type */ + a_bool_t mgt_igmp; /* igmp protocol management type */ + a_bool_t mgt_arp_req; /* arp request protocol management type */ + a_bool_t mgt_arp_rep; /* arp response protocol management type */ + a_bool_t mgt_dhcp4; /* dhcp4 protocol management type */ + a_bool_t mgt_mld; /* mld protocol management type */ + a_bool_t mgt_ns; /* ns protocol management type */ + a_bool_t mgt_na; /* na protocol management type */ + a_bool_t mgt_dhcp6; /* dhcp6 protocol management type */ +} fal_ctrlpkt_protocol_type_t; + +typedef struct { + fal_ctrlpkt_action_t action; /* the all action when condition matched */ + fal_pbmp_t port_map; /* the condition port bitmap */ + a_uint32_t ethtype_profile_bitmap; /* the condition ethtype_profile bitmap */ + a_uint32_t rfdb_profile_bitmap; /* the condition rfdb_profile bitmap */ + fal_ctrlpkt_protocol_type_t protocol_types; /* the condition protocol types */ +} fal_ctrlpkt_profile_t; + +enum { + FUNC_MGMTCTRL_ETHTYPE_PROFILE_SET = 0, + FUNC_MGMTCTRL_ETHTYPE_PROFILE_GET, + FUNC_MGMTCTRL_RFDB_PROFILE_SET, + FUNC_MGMTCTRL_RFDB_PROFILE_GET, + FUNC_MGMTCTRL_CTRLPKT_PROFILE_ADD, + FUNC_MGMTCTRL_CTRLPKT_PROFILE_DEL, + FUNC_MGMTCTRL_CTRLPKT_PROFILE_GETFIRST, + FUNC_MGMTCTRL_CTRLPKT_PROFILE_GETNEXT, +}; + +sw_error_t fal_mgmtctrl_ethtype_profile_set(a_uint32_t dev_id, a_uint32_t profile_id, a_uint32_t ethtype); +sw_error_t fal_mgmtctrl_ethtype_profile_get(a_uint32_t dev_id, a_uint32_t profile_id, a_uint32_t * ethtype); + +sw_error_t fal_mgmtctrl_rfdb_profile_set(a_uint32_t dev_id, a_uint32_t profile_id, fal_mac_addr_t *addr); +sw_error_t fal_mgmtctrl_rfdb_profile_get(a_uint32_t dev_id, a_uint32_t profile_id, fal_mac_addr_t *addr); + +sw_error_t fal_mgmtctrl_ctrlpkt_profile_add(a_uint32_t dev_id, fal_ctrlpkt_profile_t *ctrlpkt); +sw_error_t fal_mgmtctrl_ctrlpkt_profile_del(a_uint32_t dev_id, fal_ctrlpkt_profile_t *ctrlpkt); +sw_error_t fal_mgmtctrl_ctrlpkt_profile_getfirst(a_uint32_t dev_id, fal_ctrlpkt_profile_t *ctrlpkt); +sw_error_t fal_mgmtctrl_ctrlpkt_profile_getnext(a_uint32_t dev_id, fal_ctrlpkt_profile_t *ctrlpkt); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_CTRLPKT_H_ */ +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_fdb.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_fdb.h new file mode 100755 index 000000000..be205d4fc --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_fdb.h @@ -0,0 +1,364 @@ +/* + * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/** + * @defgroup fal_fdb FAL_FDB + * @{ + */ +#ifndef _FAL_FDB_H_ +#define _FAL_FDB_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "common/sw.h" +#include "fal/fal_type.h" + + /** + @details Fields description: + + portmap_en - If value of portmap_en is A_TRUE then port.map is valid + otherwise port.id is valid. + + + leaky_en - If value of leaky_en is A_TRUE then packets which + destination address equals addr in this entry would be leaky. + + + mirror_en - If value of mirror_en is A_TRUE then packets which + destination address equals addr in this entry would be mirrored. + + + clone_en - If value of clone_en is A_TRUE which means this address is + a mac clone address. + @brief This structure defines the Fdb entry. + + */ + typedef struct + { + fal_mac_addr_t addr; /* mac address of fdb entry */ + a_uint16_t fid; /* vlan_id/vsi value of fdb entry */ + fal_fwd_cmd_t dacmd; /* source address command */ + fal_fwd_cmd_t sacmd; /* dest address command */ + union + { + fal_port_t id; /* union value is port id value */ + fal_pbmp_t map; /* union value is bitmap value */ + } port; + a_bool_t portmap_en; /* use port bitmap or not */ + a_bool_t is_multicast; /* if it is a multicast mac fdb entry */ + a_bool_t static_en; /* enable static or not */ + a_bool_t leaky_en; /* enable leaky or not */ + a_bool_t mirror_en; /* enable mirror or not */ + a_bool_t clone_en; /* enable clone or not */ + a_bool_t cross_pt_state; /* cross port state */ + a_bool_t da_pri_en; /* enable da pri or not */ + a_uint8_t da_queue; /* da queue value */ + a_bool_t white_list_en; /* enable white list or not */ + a_bool_t load_balance_en; /* enable load balance value or not */ + a_uint8_t load_balance; /* load balance value */ + a_bool_t entry_valid; /* check if entry is value */ + a_bool_t lookup_valid; /* check if entry is lookup */ + } fal_fdb_entry_t; + +#define FAL_FDB_DEL_STATIC 0x1 + + typedef struct + { + a_bool_t port_en; /* enable port value matching or not */ + a_bool_t fid_en; /* enable fid value matching or not */ + a_bool_t multicast_en; /* enable multicast value matching or not */ + } fal_fdb_op_t; + + typedef enum + { + INVALID_VLAN_SVL=0, + INVALID_VLAN_IVL + } fal_fdb_smode; + +enum { + FUNC_FDB_ENTRY_ADD = 0, + FUNC_FDB_ENTRY_FLUSH, + FUNC_FDB_ENTRY_DEL_BYPORT, + FUNC_FDB_ENTRY_DEL_BYMAC, + FUNC_FDB_ENTRY_GETFIRST, + FUNC_FDB_ENTRY_GETNEXT, + FUNC_FDB_ENTRY_SEARCH, + FUNC_FDB_PORT_LEARN_SET, + FUNC_FDB_PORT_LEARN_GET, + FUNC_FDB_PORT_LEARNING_CTRL_SET, + FUNC_FDB_PORT_LEARNING_CTRL_GET, + FUNC_FDB_PORT_STAMOVE_CTRL_SET, + FUNC_FDB_PORT_STAMOVE_CTRL_GET, + FUNC_FDB_AGING_CTRL_SET, + FUNC_FDB_AGING_CTRL_GET, + FUNC_FDB_LEARNING_CTRL_SET, + FUNC_FDB_LEARNING_CTRL_GET, + FUNC_FDB_AGING_TIME_SET, + FUNC_FDB_AGING_TIME_GET, + FUNC_FDB_ENTRY_GETNEXT_BYINDEX, + FUNC_FDB_ENTRY_EXTEND_GETNEXT, + FUNC_FDB_ENTRY_EXTEND_GETFIRST, + FUNC_FDB_ENTRY_UPDATE_BYPORT, + FUNC_PORT_FDB_LEARN_LIMIT_SET, + FUNC_PORT_FDB_LEARN_LIMIT_GET, + FUNC_PORT_FDB_LEARN_EXCEED_CMD_SET, + FUNC_PORT_FDB_LEARN_EXCEED_CMD_GET, + FUNC_FDB_PORT_LEARNED_MAC_COUNTER_GET, + FUNC_FDB_PORT_ADD, + FUNC_FDB_PORT_DEL, + FUNC_FDB_PORT_MACLIMIT_CTRL_SET, + FUNC_FDB_PORT_MACLIMIT_CTRL_GET, + FUNC_FDB_DEL_BY_FID, +}; + + typedef struct + { + fal_mac_addr_t addr; + a_uint16_t fid; + a_uint8_t load_balance; + } fal_fdb_rfs_t; + + typedef struct + { + a_bool_t enable; /* enable port learn limit or not */ + a_uint32_t limit_num; /* port learn limit number */ + fal_fwd_cmd_t action; /* the action when port learn number exceed limit*/ + } fal_maclimit_ctrl_t; + + sw_error_t + fal_fdb_rfs_set(a_uint32_t dev_id, fal_fdb_rfs_t * entry); + + sw_error_t + fal_fdb_rfs_del(a_uint32_t dev_id, fal_fdb_rfs_t * entry); + + sw_error_t + fal_fdb_entry_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry); + + + + sw_error_t + fal_fdb_entry_flush(a_uint32_t dev_id, a_uint32_t flag); + + + + sw_error_t + fal_fdb_entry_del_byport(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t flag); + + + + sw_error_t + fal_fdb_entry_del_bymac(a_uint32_t dev_id, const fal_fdb_entry_t *entry); + + + + sw_error_t + fal_fdb_entry_getfirst(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + + + sw_error_t + fal_fdb_entry_getnext(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + + + sw_error_t + fal_fdb_entry_search(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + + + sw_error_t + fal_fdb_port_learn_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + sw_error_t + fal_fdb_port_learning_ctrl_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, fal_fwd_cmd_t cmd); + + + sw_error_t + fal_fdb_port_learning_ctrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable, fal_fwd_cmd_t *cmd); + + + sw_error_t + fal_fdb_port_stamove_ctrl_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, fal_fwd_cmd_t cmd); + + + sw_error_t + fal_fdb_port_stamove_ctrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable, fal_fwd_cmd_t *cmd); + + + sw_error_t + fal_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + sw_error_t + fal_fdb_aging_ctrl_set(a_uint32_t dev_id, a_bool_t enable); + + + sw_error_t + fal_fdb_aging_ctrl_get(a_uint32_t dev_id, a_bool_t * enable); + + + sw_error_t + fal_fdb_learning_ctrl_set(a_uint32_t dev_id, a_bool_t enable); + + + sw_error_t + fal_fdb_learning_ctrl_get(a_uint32_t dev_id, a_bool_t * enable); + + + sw_error_t + fal_fdb_vlan_ivl_svl_set(a_uint32_t dev_id, fal_fdb_smode smode); + + + sw_error_t + fal_fdb_vlan_ivl_svl_get(a_uint32_t dev_id, fal_fdb_smode * smode); + + + sw_error_t + fal_fdb_aging_time_set(a_uint32_t dev_id, a_uint32_t * time); + + + + sw_error_t + fal_fdb_aging_time_get(a_uint32_t dev_id, a_uint32_t * time); + + + sw_error_t + fal_fdb_entry_getnext_byindex(a_uint32_t dev_id, a_uint32_t * iterator, fal_fdb_entry_t * entry); + + + sw_error_t + fal_fdb_entry_extend_getnext(a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry); + + + sw_error_t + fal_fdb_entry_extend_getfirst(a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry); + + + sw_error_t + fal_fdb_entry_update_byport(a_uint32_t dev_id, fal_port_t old_port, fal_port_t new_port, + a_uint32_t fid, fal_fdb_op_t * option); + + + sw_error_t + fal_fdb_port_learned_mac_counter_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * cnt); + + + sw_error_t + fal_port_fdb_learn_limit_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, a_uint32_t cnt); + + + sw_error_t + fal_port_fdb_learn_limit_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable, a_uint32_t * cnt); + + + sw_error_t + fal_port_fdb_learn_exceed_cmd_set(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t cmd); + + + sw_error_t + fal_port_fdb_learn_exceed_cmd_get(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t * cmd); + + + sw_error_t + fal_fdb_learn_limit_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t cnt); + + + sw_error_t + fal_fdb_learn_limit_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * cnt); + + + sw_error_t + fal_fdb_learn_exceed_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + sw_error_t + fal_fdb_learn_exceed_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + sw_error_t + fal_fdb_resv_add(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + sw_error_t + fal_fdb_resv_del(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + + sw_error_t + fal_fdb_resv_find(a_uint32_t dev_id, fal_fdb_entry_t * entry); + + + sw_error_t + fal_fdb_resv_iterate(a_uint32_t dev_id, a_uint32_t * iterator, fal_fdb_entry_t * entry); + + + sw_error_t + fal_fdb_port_learn_static_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + sw_error_t + fal_fdb_port_learn_static_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + sw_error_t + fal_fdb_port_add(a_uint32_t dev_id, a_uint32_t fid, fal_mac_addr_t * addr, fal_port_t port_id); + + sw_error_t + fal_fdb_port_del(a_uint32_t dev_id, a_uint32_t fid, fal_mac_addr_t * addr, fal_port_t port_id); + + sw_error_t + fal_fdb_port_maclimit_ctrl_set(a_uint32_t dev_id, fal_port_t port_id, fal_maclimit_ctrl_t * maclimit_ctrl); + + sw_error_t + fal_fdb_port_maclimit_ctrl_get(a_uint32_t dev_id, fal_port_t port_id, fal_maclimit_ctrl_t * maclimit_ctrl); + + sw_error_t + fal_fdb_entry_del_byfid(a_uint32_t dev_id, a_uint16_t fid, a_uint32_t flag); + +#define fal_fdb_add fal_fdb_entry_add +#define fal_fdb_del_all fal_fdb_entry_flush +#define fal_fdb_del_by_port fal_fdb_entry_del_byport +#define fal_fdb_del_by_mac fal_fdb_entry_del_bymac +#define fal_fdb_first fal_fdb_entry_getfirst +#define fal_fdb_next fal_fdb_entry_getnext +#define fal_fdb_find fal_fdb_entry_search +#define fal_fdb_age_ctrl_set fal_fdb_aging_ctrl_set +#define fal_fdb_age_ctrl_get fal_fdb_aging_ctrl_get +#define fal_fdb_age_time_set fal_fdb_aging_time_set +#define fal_fdb_age_time_get fal_fdb_aging_time_get +#define fal_fdb_iterate fal_fdb_entry_getnext_byindex +#define fal_fdb_extend_next fal_fdb_entry_extend_getnext +#define fal_fdb_extend_first fal_fdb_entry_extend_getfirst +#define fal_fdb_transfer fal_fdb_entry_update_byport + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_FDB_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_flow.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_flow.h new file mode 100755 index 000000000..66070f783 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_flow.h @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/** + * @defgroup fal_flow + * @{ + */ +#ifndef _FAL_FLOW_H_ +#define _FAL_FLOW_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "common/sw.h" +#include "fal/fal_type.h" +#include "fal/fal_ip.h" + +typedef enum { + FAL_FLOW_L3_UNICAST = 0, + FAL_FLOW_L2_UNICAST, + FAL_FLOW_MCAST, +} fal_flow_pkt_type_t; + +typedef enum { + FAL_FLOW_LAN_TO_LAN_DIR = 0, + FAL_FLOW_LAN_TO_WAN_DIR, + FAL_FLOW_WAN_TO_LAN_DIR, + FAL_FLOW_WAN_TO_WAN_DIR, + FAL_FLOW_UNKOWN_DIR_DIR, +} fal_flow_direction_t; + +typedef enum { + FAL_FLOW_FORWARD = 0, + FAL_FLOW_SNAT, + FAL_FLOW_DNAT, + FAL_FLOW_ROUTE, + FAL_FLOW_BRIDGE, +} fal_flow_fwd_type_t; + +/* FLOW entry type field */ +#define FAL_FLOW_IP4_5TUPLE_ADDR 0x1 +#define FAL_FLOW_IP6_5TUPLE_ADDR 0x2 +#define FAL_FLOW_IP4_3TUPLE_ADDR 0x4 +#define FAL_FLOW_IP6_3TUPLE_ADDR 0x8 + +#define FAL_FLOW_OP_MODE_KEY 0x0 +#define FAL_FLOW_OP_MODE_INDEX 0x1 +#define FAL_FLOW_OP_MODE_FLUSH 0x2 + +typedef struct { + fal_fwd_cmd_t miss_action; /* flow mismatch action*/ + a_bool_t frag_bypass_en; /*0 for disable and 1 for enable*/ + a_bool_t tcp_spec_bypass_en; /*0 for disable and 1 for enable*/ + a_bool_t all_bypass_en; /*0 for disable and 1 for enable*/ + a_uint8_t key_sel; /*0 for source ip address and 1 for destination ip address*/ +} fal_flow_mgmt_t; + +typedef struct { + a_uint32_t entry_id; /*entry index*/ + a_uint8_t entry_type; /*1:ipv4 5 tuple, 2:ipv6 5 tuple, 4:ipv4 3 tuple, 8:ipv6 3 tuple*/ + a_uint8_t host_addr_type; /*0:souce ip index, 1:destination ip index*/ + a_uint16_t host_addr_index; /*host table entry index*/ + a_uint8_t protocol; /*1:tcp, 2:udp, 3:udp-lite, 0:other*/ + a_uint8_t age; /*aging value*/ + a_bool_t src_intf_valid; /*source interface check valid*/ + a_uint8_t src_intf_index; /*souce l3 interface*/ + a_uint8_t fwd_type; /*forward type*/ + a_uint16_t snat_nexthop; /*nexthop index for snat*/ + a_uint16_t snat_srcport; /*new source l4 port*/ + a_uint16_t dnat_nexthop; /*nexthop index for dnat*/ + a_uint16_t dnat_dstport; /*new destination l4 port*/ + a_uint16_t route_nexthop; /*nexthop index for route*/ + a_bool_t port_valid; /*route port valid*/ + fal_port_t route_port; /*port for route*/ + fal_port_t bridge_port; /*port for l2 bridge*/ + a_bool_t deacclr_en; /*0 for disable and 1 for enable*/ + a_bool_t copy_tocpu_en; /*0 for disable and 1 for enable*/ + a_uint8_t syn_toggle; /*update by host*/ + a_uint8_t pri_profile; /*flow qos index*/ + a_uint8_t sevice_code; /*service code for bypass*/ + a_uint8_t ip_type; /*0 for ipv4 and 1 for ipv6*/ + union { + fal_ip4_addr_t ipv4; + fal_ip6_addr_t ipv6; + } flow_ip; + a_uint16_t src_port; /*l4 source port*/ + a_uint16_t dst_port; /*l4 destination port*/ + a_uint32_t tree_id; /*for qos*/ + a_uint32_t pkt_counter; /*flow packet counter*/ + a_uint64_t byte_counter; /*flow byte counter*/ +} fal_flow_entry_t; + +typedef struct { + fal_fwd_cmd_t src_if_check_action; /*source inferface check fail action*/ + a_bool_t src_if_check_deacclr_en; /*0 for disable and 1 for enable*/ + a_bool_t service_loop_en; /*0 for disable and 1 for enable*/ + fal_fwd_cmd_t service_loop_action; /*0 for disable and 1 for enable*/ + a_bool_t service_loop_deacclr_en; /*0 for disable and 1 for enable*/ + fal_fwd_cmd_t flow_deacclr_action; /*flow de acceleration action*/ + fal_fwd_cmd_t sync_mismatch_action; /*sync toggle mismatch action*/ + a_bool_t sync_mismatch_deacclr_en; /*0 for disable and 1 for enable*/ + a_uint8_t hash_mode_0; /*0 crc10, 1 xor, 2 crc16*/ + a_uint8_t hash_mode_1; /*0 crc10, 1 xor, 2 crc16*/ + a_bool_t flow_mismatch_copy_escape_en; /*0 for disable and 1 for enable*/ +} fal_flow_global_cfg_t; + +typedef struct { + fal_flow_entry_t flow_entry; + fal_host_entry_t host_entry; +} fal_flow_host_entry_t; + +typedef struct { + a_uint16_t age_time; /* age value*/ + a_uint16_t unit; /*0:second 1:cycle 2:million cycle*/ +} fal_flow_age_timer_t; + +enum { + FUNC_FLOW_HOST_ADD = 0, + FUNC_FLOW_ENTRY_GET, + FUNC_FLOW_ENTRY_DEL, + FUNC_FLOW_STATUS_GET, + FUNC_FLOW_CTRL_SET, + FUNC_FLOW_AGE_TIMER_GET, + FUNC_FLOW_STATUS_SET, + FUNC_FLOW_HOST_GET, + FUNC_FLOW_HOST_DEL, + FUNC_FLOW_CTRL_GET, + FUNC_FLOW_AGE_TIMER_SET, + FUNC_FLOW_ENTRY_ADD, + FUNC_FLOW_GLOBAL_CFG_GET, + FUNC_FLOW_GLOBAL_CFG_SET, + FUNC_FLOW_ENTRY_NEXT, +}; + +sw_error_t +fal_flow_status_set(a_uint32_t dev_id, a_bool_t enable); + +sw_error_t +fal_flow_status_get(a_uint32_t dev_id, a_bool_t *enable); + +sw_error_t +fal_flow_age_timer_set(a_uint32_t dev_id, fal_flow_age_timer_t *age_timer); + +sw_error_t +fal_flow_age_timer_get(a_uint32_t dev_id, fal_flow_age_timer_t *age_timer); + +sw_error_t +fal_flow_mgmt_set( + a_uint32_t dev_id, + fal_flow_pkt_type_t type, + fal_flow_direction_t dir, + fal_flow_mgmt_t *mgmt); + +sw_error_t +fal_flow_mgmt_get( + a_uint32_t dev_id, + fal_flow_pkt_type_t type, + fal_flow_direction_t dir, + fal_flow_mgmt_t *mgmt); + +sw_error_t +fal_flow_entry_add( + a_uint32_t dev_id, + a_uint32_t add_mode, /*index or hash*/ + fal_flow_entry_t *flow_entry); + +sw_error_t +fal_flow_entry_del( + a_uint32_t dev_id, + a_uint32_t del_mode, + fal_flow_entry_t *flow_entry); + +sw_error_t +fal_flow_entry_get( + a_uint32_t dev_id, + a_uint32_t get_mode, + fal_flow_entry_t *flow_entry); + +sw_error_t +fal_flow_entry_next( + a_uint32_t dev_id, + a_uint32_t next_mode, + fal_flow_entry_t *flow_entry); + +sw_error_t +fal_flow_host_add( + a_uint32_t dev_id, + a_uint32_t add_mode, + fal_flow_host_entry_t *flow_host_entry); + +sw_error_t +fal_flow_host_del( + a_uint32_t dev_id, + a_uint32_t del_mode, + fal_flow_host_entry_t *flow_host_entry); + +sw_error_t +fal_flow_host_get( + a_uint32_t dev_id, + a_uint32_t get_mode, + fal_flow_host_entry_t *flow_host_entry); + +sw_error_t +fal_flow_global_cfg_get( + a_uint32_t dev_id, + fal_flow_global_cfg_t *cfg); + +sw_error_t +fal_flow_global_cfg_set( + a_uint32_t dev_id, + fal_flow_global_cfg_t *cfg); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_FLOW_H_ */ + +/** + * @} + */ + + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_igmp.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_igmp.h new file mode 100755 index 000000000..f41fdf781 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_igmp.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/** + * @defgroup fal_igmp FAL_IGMP + * @{ + */ +#ifndef _FAL_IGMP_H_ +#define _FAL_IGMP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "common/sw.h" +#include "fal/fal_type.h" +#include "fal/fal_multi.h" + + + sw_error_t + fal_port_igmps_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + + sw_error_t + fal_port_igmps_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + + sw_error_t + fal_igmp_mld_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + + sw_error_t + fal_igmp_mld_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + + sw_error_t + fal_port_igmp_mld_join_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + + sw_error_t + fal_port_igmp_mld_join_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + + sw_error_t + fal_port_igmp_mld_leave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + + sw_error_t + fal_port_igmp_mld_leave_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + + sw_error_t + fal_igmp_mld_rp_set(a_uint32_t dev_id, fal_pbmp_t pts); + + + + sw_error_t + fal_igmp_mld_rp_get(a_uint32_t dev_id, fal_pbmp_t * pts); + + + + sw_error_t + fal_igmp_mld_entry_creat_set(a_uint32_t dev_id, a_bool_t enable); + + + + sw_error_t + fal_igmp_mld_entry_creat_get(a_uint32_t dev_id, a_bool_t * enable); + + + sw_error_t + fal_igmp_mld_entry_static_set(a_uint32_t dev_id, a_bool_t static_en); + + + sw_error_t + fal_igmp_mld_entry_static_get(a_uint32_t dev_id, a_bool_t * static_en); + + + sw_error_t + fal_igmp_mld_entry_leaky_set(a_uint32_t dev_id, a_bool_t enable); + + + sw_error_t + fal_igmp_mld_entry_leaky_get(a_uint32_t dev_id, a_bool_t * enable); + + + sw_error_t + fal_igmp_mld_entry_v3_set(a_uint32_t dev_id, a_bool_t enable); + + + sw_error_t + fal_igmp_mld_entry_v3_get(a_uint32_t dev_id, a_bool_t * enable); + + + sw_error_t + fal_igmp_mld_entry_queue_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t queue); + + + sw_error_t + fal_igmp_mld_entry_queue_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * queue); + + + sw_error_t + fal_port_igmp_mld_learn_limit_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, a_uint32_t cnt); + + + sw_error_t + fal_port_igmp_mld_learn_limit_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable, a_uint32_t * cnt); + + + sw_error_t + fal_port_igmp_mld_learn_exceed_cmd_set(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t cmd); + + + sw_error_t + fal_port_igmp_mld_learn_exceed_cmd_get(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t * cmd); + + sw_error_t + fal_igmp_sg_entry_set(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry); + + sw_error_t + fal_igmp_sg_entry_clear(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry); + + sw_error_t + fal_igmp_sg_entry_show(a_uint32_t dev_id); + + sw_error_t + fal_igmp_sg_entry_query(a_uint32_t dev_id, fal_igmp_sg_info_t * info); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_IGMP_H_ */ + +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_init.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_init.h new file mode 100755 index 000000000..6510291e3 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_init.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2014, 2016-2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/*qca808x_start*/ +/** + * @defgroup fal_init FAL_INIT + * @{ + */ +#ifndef _FAL_INIT_H_ +#define _FAL_INIT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "ssdk_init.h" +/*qca808x_end*/ +enum{ + FAL_MODULE_ACL, + FAL_MODULE_VSI, + FAL_MODULE_IP, + FAL_MODULE_FLOW, + FAL_MODULE_QM, + FAL_MODULE_QOS, + FAL_MODULE_BM, + FAL_MODULE_SERVCODE, + FAL_MODULE_RSS_HASH, + FAL_MODULE_PPPOE, + FAL_MODULE_SHAPER, + FAL_MODULE_PORTCTRL, + FAL_MODULE_MIB, + FAL_MODULE_MIRROR, + FAL_MODULE_FDB, + FAL_MODULE_STP, + FAL_MODULE_TRUNK, + FAL_MODULE_PORTVLAN, + FAL_MODULE_CTRLPKT, + FAL_MODULE_SEC, + FAL_MODULE_POLICER, + FAL_MODULE_PTP, + FAL_MODULE_MAX, +}; + +typedef struct +{ + a_uint32_t bitmap[3]; +}fal_func_ctrl_t; + + +sw_error_t fal_init(a_uint32_t dev_id, ssdk_init_cfg * cfg); +sw_error_t fal_reset(a_uint32_t dev_id); +/*qca808x_start*/ +sw_error_t fal_ssdk_cfg(a_uint32_t dev_id, ssdk_cfg_t *ssdk_cfg); +/*qca808x_end*/ +sw_error_t fal_cleanup(void); +sw_error_t fal_module_func_ctrl_set(a_uint32_t dev_id, + a_uint32_t module, fal_func_ctrl_t *func_ctrl); +sw_error_t fal_module_func_ctrl_get(a_uint32_t dev_id, + a_uint32_t module, fal_func_ctrl_t *func_ctrl); +/*qca808x_start*/ +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _FAL_INIT_H_ */ +/** + * @} + */ + /*qca808x_end*/ \ No newline at end of file diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_interface_ctrl.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_interface_ctrl.h new file mode 100755 index 000000000..40ac18b5b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_interface_ctrl.h @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/** + * @defgroup fal_interface_ctrl FAL_INTERFACE_CONTROL + * @{ + */ +#ifndef _FAL_INTERFACECTRL_H_ +#define _FAL_INTERFACECTRL_H_ + +#ifdef __cplusplus +extern "c" { +#endif + +#include "common/sw.h" +#include "fal/fal_type.h" + + typedef enum { + FAL_MAC_MODE_RGMII = 0, + FAL_MAC_MODE_GMII, + FAL_MAC_MODE_MII, + FAL_MAC_MODE_SGMII, + FAL_MAC_MODE_FIBER, + FAL_MAC_MODE_RMII, + FAL_MAC_MODE_DEFAULT + } + fal_interface_mac_mode_t; + + typedef enum + { + FAL_INTERFACE_CLOCK_MAC_MODE = 0, + FAL_INTERFACE_CLOCK_PHY_MODE = 1, + } fal_interface_clock_mode_t; + + typedef struct + { + a_bool_t txclk_delay_cmd; + a_bool_t rxclk_delay_cmd; + a_uint32_t txclk_delay_sel; + a_uint32_t rxclk_delay_sel; + } fal_mac_rgmii_config_t; + + typedef struct + { + a_bool_t master_mode; + a_bool_t slave_mode; + a_bool_t clock_inverse; + a_bool_t pipe_rxclk_sel; + } fal_mac_rmii_config_t; + + typedef struct + { + fal_interface_clock_mode_t clock_mode; + a_uint32_t txclk_select; + a_uint32_t rxclk_select; + } fal_mac_gmii_config_t; + + typedef struct + { + fal_interface_clock_mode_t clock_mode; + a_uint32_t txclk_select; + a_uint32_t rxclk_select; + } fal_mac_mii_config_t; + + typedef struct + { + fal_interface_clock_mode_t clock_mode; + a_bool_t auto_neg; + a_bool_t force_speed; + a_bool_t prbs_enable; + a_bool_t rem_phy_lpbk; + } fal_mac_sgmii_config_t; + + typedef struct + { + a_bool_t auto_neg; + a_bool_t fx100_enable; + } fal_mac_fiber_config_t; + + typedef struct + { + fal_interface_mac_mode_t mac_mode; + union + { + fal_mac_rgmii_config_t rgmii; + fal_mac_gmii_config_t gmii; + fal_mac_mii_config_t mii; + fal_mac_sgmii_config_t sgmii; + fal_mac_rmii_config_t rmii; + fal_mac_fiber_config_t fiber; + } config; + } fal_mac_config_t; + + typedef struct + { + fal_interface_mac_mode_t mac_mode; + a_bool_t txclk_delay_cmd; + a_bool_t rxclk_delay_cmd; + a_uint32_t txclk_delay_sel; + a_uint32_t rxclk_delay_sel; + } fal_phy_config_t; + + typedef enum + { + Fx100BASE_MODE = 2, + Fx100BASE_BUTT = 0xffff, + } fx100_ctrl_link_mode_t; + + typedef enum + { + FX100_SERDS_MODE = 1, + Fx100_SERDS_BUTT = 0xffff, + } sgmii_fiber_mode_t; + +#define FX100_HALF_DUPLEX 0 +#define FX100_FULL_DUPLEX 1 + + typedef struct + { + fx100_ctrl_link_mode_t link_mode; + a_bool_t overshoot; + a_bool_t loopback; + a_bool_t fd_mode; + a_bool_t col_test; + sgmii_fiber_mode_t sgmii_fiber_mode; + a_bool_t crs_ctrl; + a_bool_t loopback_ctrl; + a_bool_t crs_col_100_ctrl; + a_bool_t loop_en; + } fal_fx100_ctrl_config_t; + + sw_error_t + fal_port_3az_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + sw_error_t + fal_port_3az_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + sw_error_t + fal_interface_mac_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_mac_config_t * config); + + sw_error_t + fal_interface_mac_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_mac_config_t * config); + + sw_error_t + fal_interface_phy_mode_set(a_uint32_t dev_id, a_uint32_t phy_id, fal_phy_config_t * config); + + sw_error_t + fal_interface_phy_mode_get(a_uint32_t dev_id, a_uint32_t phy_id, fal_phy_config_t * config); + + sw_error_t + fal_interface_fx100_ctrl_set(a_uint32_t dev_id, fal_fx100_ctrl_config_t * config); + + sw_error_t + fal_interface_fx100_ctrl_get(a_uint32_t dev_id, fal_fx100_ctrl_config_t * config); + + sw_error_t + fal_interface_fx100_status_get(a_uint32_t dev_id, a_uint32_t* status); + + sw_error_t + fal_interface_mac06_exch_set(a_uint32_t dev_id, a_bool_t enable); + + sw_error_t + fal_interface_mac06_exch_get(a_uint32_t dev_id, a_bool_t* enable); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_INTERFACECTRL_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_ip.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_ip.h new file mode 100755 index 000000000..9303971a4 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_ip.h @@ -0,0 +1,633 @@ +/* + * Copyright (c) 2014, 2015, 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/** + * @defgroup fal_ip FAL_IP + * @{ + */ +#ifndef _FAL_IP_H_ +#define _FAL_IP_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "common/sw.h" +#include "fal/fal_type.h" +#include "fal_multi.h" + + /* IP WCMP hash key flags */ +#define FAL_WCMP_HASH_KEY_SIP 0x1 +#define FAL_WCMP_HASH_KEY_DIP 0x2 +#define FAL_WCMP_HASH_KEY_SPORT 0x4 +#define FAL_WCMP_HASH_KEY_DPORT 0x8 + + /* IP entry operation flags */ +#define FAL_IP_ENTRY_ID_EN 0x1 +#define FAL_IP_ENTRY_INTF_EN 0x2 +#define FAL_IP_ENTRY_PORT_EN 0x4 +#define FAL_IP_ENTRY_STATUS_EN 0x8 +#define FAL_IP_ENTRY_IPADDR_EN 0x10 +#define FAL_IP_ENTRY_ALL_EN 0x20 + + /* IP host entry structure flags field */ +#define FAL_IP_IP4_ADDR 0x1 +#define FAL_IP_IP6_ADDR 0x2 +#define FAL_IP_CPU_ADDR 0x4 +#define FAL_IP_IP4_ADDR_MCAST 0x8 +#define FAL_IP_IP6_ADDR_MCAST 0x10 + +typedef struct { + a_uint8_t vsi; /*vsi value for l2 multicast*/ + fal_ip4_addr_t sip4_addr; /*source ipv4 address*/ + fal_ip6_addr_t sip6_addr; /*source ipv4 address*/ +} fal_host_mcast_t; + +typedef struct +{ + a_uint32_t rx_pkt_counter; /*rx packet counter*/ + a_uint64_t rx_byte_counter; /*rx byte counter*/ + a_uint32_t rx_drop_pkt_counter; /*rx drop packet counter*/ + a_uint64_t rx_drop_byte_counter; /*rx drop byte counter*/ + a_uint32_t tx_pkt_counter; /*tx packet counter*/ + a_uint64_t tx_byte_counter; /*tx byte counter*/ + a_uint32_t tx_drop_pkt_counter; /*tx drop packet counter*/ + a_uint64_t tx_drop_byte_counter; /*tx drop byte counter*/ +} fal_ip_counter_t; + +typedef struct +{ + a_uint32_t entry_id; /*index for host table*/ + a_uint32_t flags; /*1:ipv4 uni 2:ipv6 uni 8:ipv4 multi 0x10:ipv6 multi*/ + a_uint32_t status; /* valid status: 0 or 1*/ + fal_ip4_addr_t ip4_addr; /* ipv4 address */ + fal_ip6_addr_t ip6_addr; /* ipv6 address */ + fal_mac_addr_t mac_addr; /* unused for ppe */ + a_uint32_t intf_id; /* unused for ppe */ + a_uint32_t lb_num; /* unused for ppe */ + a_uint32_t vrf_id; /* unused for ppe */ + a_uint32_t expect_vid; /* unused for ppe */ + fal_port_t port_id; /* unused for ppe */ + a_bool_t mirror_en; /* unused for ppe */ + a_bool_t counter_en; /* unused for ppe */ + a_uint32_t counter_id; /* unused for ppe */ + a_uint32_t packet; /* unused for ppe */ + a_uint32_t byte; /* unused for ppe */ + a_bool_t pppoe_en; /* unused for ppe */ + a_uint32_t pppoe_id; /* unused for ppe */ + fal_fwd_cmd_t action; /*forward action*/ + a_uint32_t dst_info; /*bit 12:13: 1.nexthop, 2.port id, 3.port bitmap*/ + a_uint8_t syn_toggle; /* sync toggle */ + a_uint8_t lan_wan; /*0: ip over lan side ; 1: ip over wan side*/ + fal_host_mcast_t mcast_info; /* multicast information */ +} fal_host_entry_t; + + typedef enum + { + FAL_MAC_IP_GUARD = 0, + FAL_MAC_IP_PORT_GUARD, + FAL_MAC_IP_VLAN_GUARD, + FAL_MAC_IP_PORT_VLAN_GUARD, + FAL_NO_SOURCE_GUARD, + } fal_source_guard_mode_t; + + typedef enum + { + FAL_DEFAULT_FLOW_FORWARD = 0, + FAL_DEFAULT_FLOW_DROP, + FAL_DEFAULT_FLOW_RDT_TO_CPU, + FAL_DEFAULT_FLOW_ADMIT_ALL, + } fal_default_flow_cmd_t; + + typedef enum + { + FAL_FLOW_LAN_TO_LAN = 0, + FAL_FLOW_WAN_TO_LAN, + FAL_FLOW_LAN_TO_WAN, + FAL_FLOW_WAN_TO_WAN, + } fal_flow_type_t; + + typedef enum + { + FAL_ARP_LEARN_LOCAL = 0, + FAL_ARP_LEARN_ALL, + } fal_arp_learn_mode_t; + + /* IP host entry auto learn arp packets type */ +#define FAL_ARP_LEARN_REQ 0x1 +#define FAL_ARP_LEARN_ACK 0x2 + + typedef struct + { + a_uint32_t entry_id; + a_uint32_t vrf_id; + a_uint16_t vid_low; + a_uint16_t vid_high; + fal_mac_addr_t mac_addr; + a_bool_t ip4_route; + a_bool_t ip6_route; + } fal_intf_mac_entry_t; + + typedef struct + { + a_uint32_t nh_nr; + a_uint32_t nh_id[16]; + } fal_ip_wcmp_t; + + typedef struct + { + fal_mac_addr_t mac_addr; + fal_ip4_addr_t ip4_addr; + a_uint32_t vid; + a_uint8_t load_balance; + } fal_ip4_rfs_t; + + typedef struct + { + fal_mac_addr_t mac_addr; + fal_ip6_addr_t ip6_addr; + a_uint32_t vid; + a_uint8_t load_balance; + } fal_ip6_rfs_t; + + typedef struct + { + a_bool_t valid; + a_uint32_t vrf_id; + fal_addr_type_t ip_version; /*0 for IPv4 and 1 for IPv6*/ + a_uint32_t droute_type; /*0 for ARP and 1 for WCMP*/ + a_uint32_t index;/*when droute_type equals 0, means ARP entry index or means WCMP indexs*/ + } fal_default_route_t; + + typedef struct + { + a_bool_t valid; + a_uint32_t vrf_id; + a_uint32_t ip_version; /*0 for IPv4 and 1 for IPv6*/ + union { + fal_ip4_addr_t ip4_addr; + fal_ip6_addr_t ip6_addr; + }route_addr; + a_uint32_t prefix_length;/*For IPv4, up to 32 and for IPv6, up to 128*/ + } fal_host_route_t; + +typedef struct +{ + a_bool_t ipv4_arp_sg_en; /*0 for disable and 1 for enable*/ + fal_fwd_cmd_t ipv4_arp_sg_vio_action; /* check fail action for arp source guard */ + a_bool_t ipv4_arp_sg_port_en; /* source port based arp source guard enable */ + a_bool_t ipv4_arp_sg_svlan_en; /* source svlan based arp source guard enable */ + a_bool_t ipv4_arp_sg_cvlan_en; /* source cvlan based arp source guard enable */ + fal_fwd_cmd_t ipv4_arp_src_unk_action; /* unknown action for arp source guard */ + a_bool_t ip_nd_sg_en; /*0 for disable and 1 for enable*/ + fal_fwd_cmd_t ip_nd_sg_vio_action; /* check fail action for nd source guard */ + a_bool_t ip_nd_sg_port_en; /* source port based nd source guard enable */ + a_bool_t ip_nd_sg_svlan_en; /* source svlan based nd source guard enable */ + a_bool_t ip_nd_sg_cvlan_en; /* source cvlan based nd source guard enable */ + fal_fwd_cmd_t ip_nd_src_unk_action; /* unknown action for nd source guard */ +} fal_arp_sg_cfg_t; + +typedef enum +{ + FAL_MC_MODE_GV = 0, /*not support igmpv3 source filter*/ + FAL_MC_MODE_SGV /*support igmpv3 source filter*/ +} fal_mc_mode_t; + +typedef struct +{ + a_bool_t l2_ipv4_mc_en; /*0 for disable and 1 for enable*/ + fal_mc_mode_t l2_ipv4_mc_mode; /*two modes*/ + a_bool_t l2_ipv6_mc_en; /*0 for disable and 1 for enable*/ + fal_mc_mode_t l2_ipv6_mc_mode; /*same with IPv4*/ +} fal_mc_mode_cfg_t; + +typedef struct +{ + a_uint8_t type; /*0 for IPv4 and 1 for IPv6*/ + fal_fwd_cmd_t action; /* forward action */ + a_uint32_t dst_info; /*bit 12:13: 1.nexthop, 2.port id, 3.port bitmap*/ + a_uint8_t lan_wan; /* 0:ip over lan side; 1:ip over wan side */ + union { + fal_ip4_addr_t ip4_addr; /* ipv4 address */ + fal_ip6_addr_t ip6_addr; /* ipv6 address */ + } route_addr; + union { + fal_ip4_addr_t ip4_addr_mask; /* ipv4 address mask */ + fal_ip6_addr_t ip6_addr_mask; /* ipv6 address mask */ + } route_addr_mask; +} fal_network_route_entry_t; + +typedef struct { + a_uint16_t mru; /* Maximum Receive Unit*/ + a_uint16_t mtu; /* Maximum Transmission Unit*/ + a_bool_t ttl_dec_bypass_en; /* Bypass TTL Decrement enable*/ + a_bool_t ipv4_uc_route_en; /*0 for disble and 1 for enable*/ + a_bool_t ipv6_uc_route_en; /*0 for disble and 1 for enable*/ + a_bool_t icmp_trigger_en; /* ICMP trigger flag enable*/ + fal_fwd_cmd_t ttl_exceed_action; /*action for ttl 0*/ + a_bool_t ttl_exceed_deacclr_en; /*0 for disble and 1 for enable*/ + a_uint8_t mac_addr_bitmap; /* bitmap for mac address*/ + fal_mac_addr_t mac_addr; /* mac address */ + fal_ip_counter_t counter; /* interface related counter */ +} fal_intf_entry_t; + +typedef struct +{ + a_bool_t l3_if_valid; /*0 for disable and 1 for enable*/ + a_uint32_t l3_if_index; /*index for interface table*/ +} fal_intf_id_t; + +typedef enum +{ + FAL_NEXTHOP_L3 = 0, + FAL_NEXTHOP_VP, +} fal_nexthop_type_t; + +typedef struct +{ + fal_nexthop_type_t type; /* 0: L3 1:port*/ + a_uint8_t vsi; /* output vsi value if type is 0 */ + fal_port_t port; /* destination port */ + a_uint32_t if_index; /* egress interface index */ + a_bool_t ip_to_me_en; /* 0 for disable and 1 for enable*/ + a_uint8_t pub_ip_index; /*index to public ip address*/ + a_uint8_t stag_fmt; /* 0: untag 1:tagged*/ + a_uint16_t svid; /*svlan id*/ + a_int8_t ctag_fmt; /* 0: untag 1:tagged*/ + a_uint16_t cvid; /* cvlan id */ + fal_mac_addr_t mac_addr; /* mac address */ + fal_ip4_addr_t dnat_ip; /*dnat ip address*/ +} fal_ip_nexthop_t; + +typedef struct +{ + a_bool_t ipv4_sg_en; /*0 for disable and 1 for enable*/ + fal_fwd_cmd_t ipv4_sg_vio_action; /* check fail action for ipv4 source guard */ + a_bool_t ipv4_sg_port_en; /* source port based ipv4 source guard enable */ + a_bool_t ipv4_sg_svlan_en; /* source svlan based ipv4 source guard enable */ + a_bool_t ipv4_sg_cvlan_en; /* source cvlan based ipv4 source guard enable */ + fal_fwd_cmd_t ipv4_src_unk_action; /* unknown action for ipv4 source guard */ + a_bool_t ipv6_sg_en; /*0 for disable and 1 for enable*/ + fal_fwd_cmd_t ipv6_sg_vio_action; /* check fail action for ipv6 source guard */ + a_bool_t ipv6_sg_port_en; /* source port based ipv6 source guard enable */ + a_bool_t ipv6_sg_svlan_en; /* source svlan based ipv6 source guard enable */ + a_bool_t ipv6_sg_cvlan_en; /* source cvlan based ipv6 source guard enable */ + fal_fwd_cmd_t ipv6_src_unk_action; /* unknown action for ipv6 source guard */ +} fal_sg_cfg_t; + +typedef struct +{ + fal_ip4_addr_t pub_ip_addr; /*public ip address*/ +} fal_ip_pub_addr_t; + +typedef struct { + a_bool_t valid; /* valid flag */ + fal_mac_addr_t mac_addr; /* mac address */ +} fal_macaddr_entry_t; + +typedef struct +{ + fal_fwd_cmd_t mru_fail_action; /*mru check fail action*/ + a_bool_t mru_deacclr_en; /*0 for disable and 1 for enable*/ + fal_fwd_cmd_t mtu_fail_action; /*mtu check fail action*/ + a_bool_t mtu_deacclr_en; /*0 for disable and 1 for enable*/ + fal_fwd_cmd_t mtu_nonfrag_fail_action; /*mtu check fail action for non-fragment */ + a_bool_t mtu_df_deacclr_en; /*0 for disable and 1 for enable*/ + fal_fwd_cmd_t prefix_bc_action; /*0 forward, 1 drop, 2 copy, 3 rdt_cpu*/ + a_bool_t prefix_deacclr_en; /*0 for disable and 1 for enable*/ + fal_fwd_cmd_t icmp_rdt_action; /*0 forward, 1 drop, 2 copy, 3 rdt_cpu*/ + a_bool_t icmp_rdt_deacclr_en; /*0 for disable and 1 for enable*/ + a_uint8_t hash_mode_0; /*0 crc10, 1 xor, 2 crc16*/ + a_uint8_t hash_mode_1; /*0 crc10, 1 xor, 2 crc16*/ +} fal_ip_global_cfg_t; + +enum { + FUNC_IP_NETWORK_ROUTE_GET = 0, + FUNC_IP_HOST_ADD, + FUNC_IP_VSI_SG_CFG_GET, + FUNC_IP_PUB_ADDR_SET, + FUNC_IP_PORT_SG_CFG_SET, + FUNC_IP_PORT_INTF_GET, + FUNC_IP_VSI_ARP_SG_CFG_SET, + FUNC_IP_PUB_ADDR_GET, + FUNC_IP_PORT_INTF_SET, + FUNC_IP_VSI_SG_CFG_SET, + FUNC_IP_HOST_NEXT, + FUNC_IP_PORT_MACADDR_SET, + FUNC_IP_VSI_INTF_GET, + FUNC_IP_NETWORK_ROUTE_ADD, + FUNC_IP_PORT_SG_CFG_GET, + FUNC_IP_INTF_GET, + FUNC_IP_NETWORK_ROUTE_DEL, + FUNC_IP_HOST_DEL, + FUNC_IP_ROUTE_MISMATCH_GET, + FUNC_IP_VSI_ARP_SG_CFG_GET, + FUNC_IP_PORT_ARP_SG_CFG_SET, + FUNC_IP_VSI_MC_MODE_SET, + FUNC_IP_VSI_INTF_SET, + FUNC_IP_NEXTHOP_GET, + FUNC_IP_ROUTE_MISMATCH_SET, + FUNC_IP_HOST_GET, + FUNC_IP_INTF_SET, + FUNC_IP_VSI_MC_MODE_GET, + FUNC_IP_PORT_MACADDR_GET, + FUNC_IP_PORT_ARP_SG_CFG_GET, + FUNC_IP_NEXTHOP_SET, + FUNC_IP_GLOBAL_CTRL_GET, + FUNC_IP_GLOBAL_CTRL_SET, +}; + + sw_error_t + fal_ip_host_add(a_uint32_t dev_id, fal_host_entry_t * host_entry); + + sw_error_t + fal_ip_host_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_host_entry_t * host_entry); + + sw_error_t + fal_ip_host_get(a_uint32_t dev_id, a_uint32_t get_mode, + fal_host_entry_t * host_entry); + + sw_error_t + fal_ip_host_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_host_entry_t * host_entry); + + sw_error_t + fal_ip_host_counter_bind(a_uint32_t dev_id, a_uint32_t entry_id, + a_uint32_t cnt_id, a_bool_t enable); + + sw_error_t + fal_ip_host_pppoe_bind(a_uint32_t dev_id, a_uint32_t entry_id, + a_uint32_t pppoe_id, a_bool_t enable); + + sw_error_t + fal_ip_pt_arp_learn_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t flags); + + sw_error_t + fal_ip_pt_arp_learn_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * flags); + + sw_error_t + fal_ip_arp_learn_set(a_uint32_t dev_id, fal_arp_learn_mode_t mode); + + sw_error_t + fal_ip_arp_learn_get(a_uint32_t dev_id, fal_arp_learn_mode_t * mode); + + sw_error_t + fal_ip_source_guard_set(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t mode); + + sw_error_t + fal_ip_source_guard_get(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t * mode); + + sw_error_t + fal_ip_arp_guard_set(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t mode); + + sw_error_t + fal_ip_arp_guard_get(a_uint32_t dev_id, fal_port_t port_id, + fal_source_guard_mode_t * mode); + + sw_error_t + fal_ip_route_status_set(a_uint32_t dev_id, a_bool_t enable); + + sw_error_t + fal_ip_route_status_get(a_uint32_t dev_id, a_bool_t * enable); + + sw_error_t + fal_ip_intf_entry_add(a_uint32_t dev_id, fal_intf_mac_entry_t * entry); + + sw_error_t + fal_ip_intf_entry_del(a_uint32_t dev_id, a_uint32_t del_mode, + fal_intf_mac_entry_t * entry); + + sw_error_t + fal_ip_intf_entry_next(a_uint32_t dev_id, a_uint32_t next_mode, + fal_intf_mac_entry_t * entry); + + sw_error_t + fal_ip_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + sw_error_t + fal_ip_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + sw_error_t + fal_arp_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + sw_error_t + fal_arp_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + sw_error_t + fal_ip_age_time_set(a_uint32_t dev_id, a_uint32_t * time); + + sw_error_t + fal_ip_age_time_get(a_uint32_t dev_id, a_uint32_t * time); + + sw_error_t + fal_ip_wcmp_entry_set(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp); + + sw_error_t + fal_ip_wcmp_entry_get(a_uint32_t dev_id, a_uint32_t wcmp_id, fal_ip_wcmp_t * wcmp); + + sw_error_t + fal_ip_wcmp_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode); + + sw_error_t + fal_ip_rfs_ip4_rule_set(a_uint32_t dev_id, fal_ip4_rfs_t * rfs); + + sw_error_t + fal_ip_rfs_ip6_rule_set(a_uint32_t dev_id, fal_ip6_rfs_t * rfs); + + sw_error_t + fal_ip_rfs_ip4_rule_del(a_uint32_t dev_id, fal_ip4_rfs_t * rfs); + + sw_error_t + fal_ip_rfs_ip6_rule_del(a_uint32_t dev_id, fal_ip6_rfs_t * rfs); + + sw_error_t + fal_ip_wcmp_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode); + + sw_error_t + fal_ip_vrf_base_addr_set(a_uint32_t dev_id, a_uint32_t vrf_id, fal_ip4_addr_t addr); + + sw_error_t + fal_ip_vrf_base_addr_get(a_uint32_t dev_id, a_uint32_t vrf_id, fal_ip4_addr_t * addr); + + sw_error_t + fal_ip_vrf_base_mask_set(a_uint32_t dev_id, a_uint32_t vrf_id, fal_ip4_addr_t addr); + + sw_error_t + fal_ip_vrf_base_mask_get(a_uint32_t dev_id, a_uint32_t vrf_id, fal_ip4_addr_t * addr); + + sw_error_t + fal_ip_default_route_set(a_uint32_t dev_id, a_uint32_t droute_id, + fal_default_route_t * entry); + + sw_error_t + fal_ip_default_route_get(a_uint32_t dev_id, a_uint32_t droute_id, + fal_default_route_t * entry); + + sw_error_t + fal_ip_host_route_set(a_uint32_t dev_id, a_uint32_t hroute_id, + fal_host_route_t * entry); + + sw_error_t + fal_ip_host_route_get(a_uint32_t dev_id, a_uint32_t hroute_id, + fal_host_route_t * entry); + + sw_error_t + fal_ip_wcmp_entry_set(a_uint32_t dev_id, a_uint32_t wcmp_id, + fal_ip_wcmp_t * wcmp); + + sw_error_t + fal_ip_wcmp_entry_get(a_uint32_t dev_id, a_uint32_t wcmp_id, + fal_ip_wcmp_t * wcmp); + + sw_error_t + fal_default_flow_cmd_set(a_uint32_t dev_id, a_uint32_t vrf_id, + fal_flow_type_t type, fal_default_flow_cmd_t cmd); + + sw_error_t + fal_default_flow_cmd_get(a_uint32_t dev_id, a_uint32_t vrf_id, + fal_flow_type_t type, fal_default_flow_cmd_t * cmd); + + sw_error_t + fal_default_rt_flow_cmd_set(a_uint32_t dev_id, a_uint32_t vrf_id, + fal_flow_type_t type, fal_default_flow_cmd_t cmd); + + sw_error_t + fal_default_rt_flow_cmd_get(a_uint32_t dev_id, a_uint32_t vrf_id, + fal_flow_type_t type, fal_default_flow_cmd_t * cmd); + +sw_error_t +fal_ip_vsi_arp_sg_cfg_get(a_uint32_t dev_id, a_uint32_t vsi, + fal_arp_sg_cfg_t *arp_sg_cfg); + +sw_error_t +fal_ip_vsi_arp_sg_cfg_set(a_uint32_t dev_id, a_uint32_t vsi, + fal_arp_sg_cfg_t *arp_sg_cfg); + +sw_error_t +fal_ip_network_route_add(a_uint32_t dev_id, a_uint32_t index, + fal_network_route_entry_t *entry); + +sw_error_t +fal_ip_network_route_get(a_uint32_t dev_id, + a_uint32_t index, a_uint8_t type, + fal_network_route_entry_t *entry); + +sw_error_t +fal_ip_network_route_del(a_uint32_t dev_id, + a_uint32_t index, a_uint8_t type); + +sw_error_t +fal_ip_intf_set(a_uint32_t dev_id, + a_uint32_t index, + fal_intf_entry_t *entry); + +sw_error_t +fal_ip_intf_get(a_uint32_t dev_id, + a_uint32_t index, + fal_intf_entry_t *entry); + +sw_error_t +fal_ip_vsi_intf_set(a_uint32_t dev_id, a_uint32_t vsi, fal_intf_id_t *id); + +sw_error_t +fal_ip_vsi_intf_get(a_uint32_t dev_id, a_uint32_t vsi, fal_intf_id_t *id); + +sw_error_t +fal_ip_port_intf_set(a_uint32_t dev_id, fal_port_t port_id, fal_intf_id_t *id); + +sw_error_t +fal_ip_port_intf_get(a_uint32_t dev_id, fal_port_t port_id, fal_intf_id_t *id); + +sw_error_t +fal_ip_nexthop_set(a_uint32_t dev_id, a_uint32_t index, + fal_ip_nexthop_t *entry); + +sw_error_t +fal_ip_nexthop_get(a_uint32_t dev_id, a_uint32_t index, + fal_ip_nexthop_t *entry); + +sw_error_t +fal_ip_vsi_sg_cfg_get(a_uint32_t dev_id, a_uint32_t vsi, + fal_sg_cfg_t *sg_cfg); + +sw_error_t +fal_ip_vsi_sg_cfg_set(a_uint32_t dev_id, a_uint32_t vsi, + fal_sg_cfg_t *sg_cfg); + +sw_error_t +fal_ip_port_sg_cfg_set(a_uint32_t dev_id, fal_port_t port_id, + fal_sg_cfg_t *sg_cfg); + +sw_error_t +fal_ip_port_sg_cfg_get(a_uint32_t dev_id, fal_port_t port_id, + fal_sg_cfg_t *sg_cfg); + +sw_error_t +fal_ip_pub_addr_set(a_uint32_t dev_id, a_uint32_t index, + fal_ip_pub_addr_t *entry); + +sw_error_t +fal_ip_pub_addr_get(a_uint32_t dev_id, a_uint32_t index, + fal_ip_pub_addr_t *entry); + +sw_error_t +fal_ip_port_macaddr_set(a_uint32_t dev_id, fal_port_t port_id, + fal_macaddr_entry_t *macaddr); + +sw_error_t +fal_ip_port_macaddr_get(a_uint32_t dev_id, fal_port_t port_id, + fal_macaddr_entry_t *macaddr); + +sw_error_t +fal_ip_route_mismatch_action_set(a_uint32_t dev_id, fal_fwd_cmd_t action); + +sw_error_t +fal_ip_route_mismatch_action_get(a_uint32_t dev_id, fal_fwd_cmd_t *action); + +sw_error_t +fal_ip_port_arp_sg_cfg_set(a_uint32_t dev_id, fal_port_t port_id, + fal_arp_sg_cfg_t *arp_sg_cfg); + +sw_error_t +fal_ip_port_arp_sg_cfg_get(a_uint32_t dev_id, fal_port_t port_id, + fal_arp_sg_cfg_t *arp_sg_cfg); + +sw_error_t +fal_ip_vsi_mc_mode_set(a_uint32_t dev_id, a_uint32_t vsi, + fal_mc_mode_cfg_t *cfg); + +sw_error_t +fal_ip_vsi_mc_mode_get(a_uint32_t dev_id, a_uint32_t vsi, + fal_mc_mode_cfg_t *cfg); + +sw_error_t +fal_ip_global_ctrl_get(a_uint32_t dev_id, fal_ip_global_cfg_t *cfg); + +sw_error_t +fal_ip_global_ctrl_set(a_uint32_t dev_id, fal_ip_global_cfg_t *cfg); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_IP_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_leaky.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_leaky.h new file mode 100755 index 000000000..255eac486 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_leaky.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/** + * @defgroup fal_leaky FAL_LEAKY + * @{ + */ +#ifndef _FAL_LEAKY_H_ +#define _FAL_LEAKY_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "common/sw.h" +#include "fal/fal_type.h" + + /** + @brief This enum defines the leaky control mode. + */ + typedef enum { + FAL_LEAKY_PORT_CTRL = 0, /**< control leaky through port which packets received*/ + FAL_LEAKY_FDB_CTRL, /**< control leaky through fdb entry*/ + FAL_LEAKY_CTRL_MODE_BUTT + } + fal_leaky_ctrl_mode_t; + + + + sw_error_t + fal_uc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode); + + + + sw_error_t + fal_uc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t * ctrl_mode); + + + + sw_error_t + fal_mc_leaky_mode_set(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t ctrl_mode); + + + + sw_error_t + fal_mc_leaky_mode_get(a_uint32_t dev_id, + fal_leaky_ctrl_mode_t * ctrl_mode); + + + + sw_error_t + fal_port_arp_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + + sw_error_t + fal_port_arp_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + + sw_error_t + fal_port_uc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + + sw_error_t + fal_port_uc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + + sw_error_t + fal_port_mc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + + sw_error_t + fal_port_mc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_LEAKY_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_led.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_led.h new file mode 100644 index 000000000..e0c78aa3d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_led.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2014,2020 The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/** + * @defgroup fal_led FAL_LED + * @{ + */ +#ifndef _FAL_LED_H_ +#define _FAL_LED_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "common/sw.h" +#include "fal/fal_type.h" + + /** + @brief This enum defines the led group. + */ + typedef enum { + LED_LAN_PORT_GROUP = 0, /**< control lan ports*/ + LED_WAN_PORT_GROUP, /**< control wan ports*/ + LED_MAC_PORT_GROUP, /**< control mac ports*/ + LED_GROUP_BUTT + } + led_pattern_group_t; + + /** + @brief This enum defines the led pattern id, each ports has three led + and pattern0 relates to led0, pattern1 relates to led1, pattern2 relates to led2. + */ + typedef a_uint32_t led_pattern_id_t; + + + /** + @brief This enum defines the led control pattern mode. + */ + typedef enum + { + LED_ALWAYS_OFF = 0, + LED_ALWAYS_BLINK, + LED_ALWAYS_ON, + LED_PATTERN_MAP_EN, + LED_PATTERN_MODE_BUTT + } led_pattern_mode_t; + + +#define FULL_DUPLEX_LIGHT_EN 0 +#define HALF_DUPLEX_LIGHT_EN 1 +#define POWER_ON_LIGHT_EN 2 +#define LINK_1000M_LIGHT_EN 3 +#define LINK_100M_LIGHT_EN 4 +#define LINK_10M_LIGHT_EN 5 +#define COLLISION_BLINK_EN 6 +#define RX_TRAFFIC_BLINK_EN 7 +#define TX_TRAFFIC_BLINK_EN 8 +#define LINKUP_OVERRIDE_EN 9 +#define LED_ACTIVE_HIGH 10 +#define LINK_2500M_LIGHT_EN 11 + + + /** + @brief This enum defines the led control pattern map. + */ + typedef a_uint32_t led_pattern_map_t; + + + /** + @brief This enum defines the led control pattern mode. + */ + typedef enum + { + LED_BLINK_2HZ = 0, + LED_BLINK_4HZ, + LED_BLINK_8HZ, + LED_BLINK_TXRX, /**< Frequency relates to speed, 1000M-8HZ,100M->4HZ,10M->2HZ,Others->4HZ */ + LED_BLINK_FREQ_BUTT + } led_blink_freq_t; + + + typedef struct + { + led_pattern_mode_t mode; + led_pattern_map_t map; + led_blink_freq_t freq; + } led_ctrl_pattern_t; + + + + + + sw_error_t + fal_led_ctrl_pattern_set(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern); + + + + sw_error_t + fal_led_ctrl_pattern_get(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_LED_H_ */ +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_mib.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_mib.h new file mode 100755 index 000000000..aa6e354c4 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_mib.h @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/** + * @defgroup fal_mib FAL_MIB + * @{ + */ +#ifndef _FAL_MIB_H +#define _FAL_MIB_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "common/sw.h" +#include "fal/fal_type.h" + + /**@brief This structure defines the mib infomation. + */ + typedef struct + { + a_uint32_t RxBroad; + a_uint32_t RxPause; + a_uint32_t RxMulti; + a_uint32_t RxFcsErr; + a_uint32_t RxAllignErr; + a_uint32_t RxRunt; + a_uint32_t RxFragment; + a_uint32_t Rx64Byte; + a_uint32_t Rx128Byte; + a_uint32_t Rx256Byte; + a_uint32_t Rx512Byte; + a_uint32_t Rx1024Byte; + a_uint32_t Rx1518Byte; + a_uint32_t RxMaxByte; + a_uint32_t RxTooLong; + a_uint32_t RxGoodByte_lo; /**< low 32 bits of RxGoodByte statistc item */ + a_uint32_t RxGoodByte_hi; /**< high 32 bits of RxGoodByte statistc item*/ + a_uint32_t RxBadByte_lo; /**< low 32 bits of RxBadByte statistc item */ + a_uint32_t RxBadByte_hi; /**< high 32 bits of RxBadByte statistc item */ + a_uint32_t RxOverFlow; + a_uint32_t Filtered; + a_uint32_t TxBroad; + a_uint32_t TxPause; + a_uint32_t TxMulti; + a_uint32_t TxUnderRun; + a_uint32_t Tx64Byte; + a_uint32_t Tx128Byte; + a_uint32_t Tx256Byte; + a_uint32_t Tx512Byte; + a_uint32_t Tx1024Byte; + a_uint32_t Tx1518Byte; + a_uint32_t TxMaxByte; + a_uint32_t TxOverSize; + a_uint32_t TxByte_lo; /**< low 32 bits of TxByte statistc item */ + a_uint32_t TxByte_hi; /**< high 32 bits of TxByte statistc item */ + a_uint32_t TxCollision; + a_uint32_t TxAbortCol; + a_uint32_t TxMultiCol; + a_uint32_t TxSingalCol; + a_uint32_t TxExcDefer; + a_uint32_t TxDefer; + a_uint32_t TxLateCol; + a_uint32_t RxUniCast; + a_uint32_t TxUniCast; + a_uint32_t RxJumboFcsErr; /* add for Hawkeye*/ + a_uint32_t RxJumboAligenErr; /* add for Hawkeye*/ + a_uint32_t Rx14To63; /*add for ipq60xx lpbk port*/ + a_uint32_t RxTooLongByte_lo; /*add for ipq60xx lpbk port*/ + a_uint32_t RxTooLongByte_hi; /*add for ipq60xx lpbk port*/ + a_uint32_t RxRuntByte_lo; /*add for ipq60xx lpbk port*/ + a_uint32_t RxRuntByte_hi; /*add for ipq60xx lpbk port*/ + } fal_mib_info_t; + +/*define structure for software with 64bit*/ +typedef struct +{ + a_uint64_t RxBroad; + a_uint64_t RxPause; + a_uint64_t RxMulti; + a_uint64_t RxFcsErr; + a_uint64_t RxAllignErr; + a_uint64_t RxRunt; + a_uint64_t RxFragment; + a_uint64_t Rx64Byte; + a_uint64_t Rx128Byte; + a_uint64_t Rx256Byte; + a_uint64_t Rx512Byte; + a_uint64_t Rx1024Byte; + a_uint64_t Rx1518Byte; + a_uint64_t RxMaxByte; + a_uint64_t RxTooLong; + a_uint64_t RxGoodByte; + a_uint64_t RxBadByte; + a_uint64_t RxOverFlow; /* no this counter for Hawkeye*/ + a_uint64_t Filtered; /*no this counter for Hawkeye*/ + a_uint64_t TxBroad; + a_uint64_t TxPause; + a_uint64_t TxMulti; + a_uint64_t TxUnderRun; + a_uint64_t Tx64Byte; + a_uint64_t Tx128Byte; + a_uint64_t Tx256Byte; + a_uint64_t Tx512Byte; + a_uint64_t Tx1024Byte; + a_uint64_t Tx1518Byte; + a_uint64_t TxMaxByte; + a_uint64_t TxOverSize; /*no this counter for Hawkeye*/ + a_uint64_t TxByte; + a_uint64_t TxCollision; + a_uint64_t TxAbortCol; + a_uint64_t TxMultiCol; + a_uint64_t TxSingalCol; + a_uint64_t TxExcDefer; + a_uint64_t TxDefer; + a_uint64_t TxLateCol; + a_uint64_t RxUniCast; + a_uint64_t TxUniCast; + a_uint64_t RxJumboFcsErr; /* add for Hawkeye*/ + a_uint64_t RxJumboAligenErr; /* add for Hawkeye*/ + a_uint64_t Rx14To63; /*add for ipq60xx lpbk port*/ + a_uint64_t RxTooLongByte; /*add for ipq60xx lpbk port*/ + a_uint64_t RxRuntByte; /*add for ipq60xx lpbk port*/ +} fal_mib_counter_t; + +typedef struct +{ + a_uint64_t RxFrame; + a_uint64_t RxByte; + a_uint64_t RxByteGood; + a_uint64_t RxBroadGood; + a_uint64_t RxMultiGood; + a_uint64_t RxFcsErr; + a_uint64_t RxRuntErr; + a_uint64_t RxJabberError; + a_uint64_t RxUndersizeGood; + a_uint64_t RxOversizeGood; + a_uint64_t Rx64Byte; + a_uint64_t Rx128Byte; + a_uint64_t Rx256Byte; + a_uint64_t Rx512Byte; + a_uint64_t Rx1024Byte; + a_uint64_t RxMaxByte; + a_uint64_t RxUnicastGood; + a_uint64_t RxLengthError; + a_uint64_t RxOutOfRangeError; + a_uint64_t RxPause; + a_uint64_t RxOverFlow; + a_uint64_t RxVLANFrameGoodBad; + a_uint64_t RxWatchDogError; + a_uint64_t RxLPIUsec; + a_uint64_t RxLPITran; + a_uint64_t RxDropFrameGoodBad; + a_uint64_t RxDropByteGoodBad; + + a_uint64_t TxByte; + a_uint64_t TxFrame; + a_uint64_t TxBroadGood; + a_uint64_t TxMultiGood; + a_uint64_t Tx64Byte; + a_uint64_t Tx128Byte; + a_uint64_t Tx256Byte; + a_uint64_t Tx512Byte; + a_uint64_t Tx1024Byte; + a_uint64_t TxMaxByte; + a_uint64_t TxUnicast; + a_uint64_t TxMulti; + a_uint64_t TxBroad; + a_uint64_t TxUnderFlowError; + a_uint64_t TxByteGood; + a_uint64_t TxFrameGood; + a_uint64_t TxPause; + a_uint64_t TxVLANFrameGood; + a_uint64_t TxLPIUsec; + a_uint64_t TxLPITran; +} fal_xgmib_info_t; + + enum + { + /*mib*/ + FUNC_GET_MIB_INFO = 0 , + FUNC_GET_RX_MIB_INFO, + FUNC_GET_TX_MIB_INFO, + FUNC_GET_XGMIB_INFO, + FUNC_GET_TX_XGMIB_INFO, + FUNC_GET_RX_XGMIB_INFO, + FUNC_MIB_STATUS_SET, + FUNC_MIB_STATUS_GET, + FUNC_MIB_PORT_FLUSH_COUNTERS, + FUNC_MIB_CPUKEEP_SET, + FUNC_MIB_CPUKEEP_GET, + }; + + sw_error_t + fal_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_info ); + + sw_error_t + fal_get_xgmib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_xgmib_info_t * mib_Info); + + + sw_error_t + fal_mib_status_set(a_uint32_t dev_id, a_bool_t enable); + + + + sw_error_t + fal_mib_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + sw_error_t + fal_mib_port_flush_counters(a_uint32_t dev_id, fal_port_t port_id); + + + sw_error_t + fal_mib_cpukeep_set(a_uint32_t dev_id, a_bool_t enable); + + sw_error_t + fal_mib_cpukeep_get(a_uint32_t dev_id, a_bool_t * enable); + +sw_error_t +fal_mib_counter_get(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_counter_t *mib_counter); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _FAL_MIB_H */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_mirror.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_mirror.h new file mode 100755 index 000000000..498bf86fc --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_mirror.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2014, 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/** + * @defgroup fal_mirror FAL_MIRROR + * @{ + */ +#ifndef _FAL_MIRROR_H_ +#define _FAL_MIRROR_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "common/sw.h" +#include "fal/fal_type.h" + + +typedef struct +{ + fal_port_t port_id; + a_uint32_t priority; +} fal_mirr_analysis_config_t; + +typedef enum +{ + FAL_MIRR_INGRESS= 0, + FAL_MIRR_EGRESS, + FAL_MIRR_BOTH, +} fal_mirr_direction_t; + +enum +{ + FUNC_MIRR_ANALYSIS_PORT_SET = 0, + FUNC_MIRR_ANALYSIS_PORT_GET, + FUNC_MIRR_PORT_IN_SET, + FUNC_MIRR_PORT_IN_GET, + FUNC_MIRR_PORT_EG_SET, + FUNC_MIRR_PORT_EG_GET, + FUNC_MIRR_ANALYSIS_CONFIG_SET, + FUNC_MIRR_ANALYSIS_CONFIG_GET, +}; + +sw_error_t +fal_mirr_analysis_port_set(a_uint32_t dev_id, fal_port_t port_id); + +sw_error_t +fal_mirr_analysis_port_get(a_uint32_t dev_id, fal_port_t * port_id); + +sw_error_t +fal_mirr_port_in_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); +sw_error_t +fal_mirr_port_in_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); +sw_error_t +fal_mirr_port_eg_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); +sw_error_t +fal_mirr_port_eg_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + +sw_error_t +fal_mirr_analysis_config_set(a_uint32_t dev_id, fal_mirr_direction_t direction, fal_mirr_analysis_config_t * config); + +sw_error_t +fal_mirr_analysis_config_get(a_uint32_t dev_id, fal_mirr_direction_t direction, fal_mirr_analysis_config_t * config); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _PORT_MIRROR_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_misc.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_misc.h new file mode 100755 index 000000000..e5e40b670 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_misc.h @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/** + * @defgroup fal_gen FAL_MISC + * @{ + */ +#ifndef _FAL_MISC_H_ +#define _FAL_MISC_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "common/sw.h" +#include "fal/fal_type.h" + + + typedef enum + { + FAL_LOOP_CHECK_1MS = 0, + FAL_LOOP_CHECK_10MS, + FAL_LOOP_CHECK_100MS, + FAL_LOOP_CHECK_500MS, + } fal_loop_check_time_t; + + typedef struct + { + a_bool_t rx_counter_en; /* Enable/disable virtual port rx counter */ + a_bool_t vp_uni_tx_counter_en; /* Enable/disable virtual port unicast tx counter */ + a_bool_t port_mc_tx_counter_en; /* Enable/disable physical port multicast tx counter */ + a_bool_t port_tx_counter_en; /* Enable/disable physical port tx counter */ + } fal_counter_en_t; + + sw_error_t + fal_debug_port_counter_enable(a_uint32_t dev_id, fal_port_t port_id, fal_counter_en_t * cnt_en); + + sw_error_t + fal_debug_port_counter_status_get(a_uint32_t dev_id, fal_port_t port_id, fal_counter_en_t * cnt_en); + + /* define switch interrupt type bitmap */ +#define FAL_SWITCH_INTR_LINK_STATUS 0x1 /* up/down/speed/duplex status */ + + sw_error_t fal_arp_status_set(a_uint32_t dev_id, a_bool_t enable); + + + + sw_error_t fal_arp_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + + sw_error_t fal_frame_max_size_set(a_uint32_t dev_id, a_uint32_t size); + + + + sw_error_t fal_frame_max_size_get(a_uint32_t dev_id, a_uint32_t * size); + + + + sw_error_t + fal_port_unk_sa_cmd_set(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t cmd); + + + + sw_error_t + fal_port_unk_sa_cmd_get(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t * cmd); + + + + sw_error_t + fal_port_unk_uc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + + sw_error_t + fal_port_unk_uc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + + sw_error_t + fal_port_unk_mc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + + sw_error_t + fal_port_unk_mc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + sw_error_t + fal_port_bc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable); + + + sw_error_t + fal_port_bc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable); + + + sw_error_t + fal_cpu_port_status_set(a_uint32_t dev_id, a_bool_t enable); + + + + sw_error_t + fal_cpu_port_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + + sw_error_t + fal_bc_to_cpu_port_set(a_uint32_t dev_id, a_bool_t enable); + + + + sw_error_t + fal_bc_to_cpu_port_get(a_uint32_t dev_id, a_bool_t * enable); + + + + sw_error_t + fal_port_dhcp_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + + sw_error_t + fal_port_dhcp_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable); + + + sw_error_t + fal_arp_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + sw_error_t + fal_arp_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + sw_error_t + fal_eapol_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + sw_error_t + fal_eapol_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + + sw_error_t + fal_eapol_status_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable); + + sw_error_t + fal_eapol_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t * enable); + + sw_error_t + fal_ripv1_status_set(a_uint32_t dev_id, a_bool_t enable); + + sw_error_t + fal_ripv1_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + sw_error_t + fal_port_arp_req_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + sw_error_t + fal_port_arp_req_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + sw_error_t + fal_port_arp_ack_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable); + + + sw_error_t + fal_port_arp_ack_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable); + + + sw_error_t + fal_intr_mask_set(a_uint32_t dev_id, a_uint32_t intr_mask); + + + sw_error_t + fal_intr_mask_get(a_uint32_t dev_id, a_uint32_t * intr_mask); + + + sw_error_t + fal_intr_status_get(a_uint32_t dev_id, a_uint32_t * intr_status); + + + sw_error_t + fal_intr_status_clear(a_uint32_t dev_id, a_uint32_t intr_status); + + + sw_error_t + fal_intr_port_link_mask_set(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t intr_mask); + + + sw_error_t + fal_intr_port_link_mask_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask); + + + sw_error_t + fal_intr_port_link_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask); + + + sw_error_t + fal_intr_mask_mac_linkchg_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable); + + + sw_error_t + fal_intr_mask_mac_linkchg_get(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t * enable); + + sw_error_t + fal_intr_status_mac_linkchg_get(a_uint32_t dev_id, fal_pbmp_t *port_bitmap); + + sw_error_t + fal_cpu_vid_en_set(a_uint32_t dev_id, a_bool_t enable); + + sw_error_t + fal_cpu_vid_en_get(a_uint32_t dev_id, a_bool_t * enable); + + sw_error_t + fal_intr_status_mac_linkchg_clear(a_uint32_t dev_id); + + sw_error_t + fal_global_macaddr_set(a_uint32_t dev_id, fal_mac_addr_t * addr); + + sw_error_t + fal_global_macaddr_get(a_uint32_t dev_id, fal_mac_addr_t * addr); + + sw_error_t + fal_lldp_status_set(a_uint32_t dev_id, a_bool_t enable); + + + sw_error_t + fal_lldp_status_get(a_uint32_t dev_id, a_bool_t * enable); + + sw_error_t + fal_frame_crc_reserve_set(a_uint32_t dev_id, a_bool_t enable); + + sw_error_t + fal_frame_crc_reserve_get(a_uint32_t dev_id, a_bool_t * enable); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_MISC_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_multi.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_multi.h new file mode 100755 index 000000000..fb651d0e8 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_multi.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +#ifndef _FAL_MULTI_H_ +#define _FAL_MULTI_H_ + +/*supports 32 entries*/ +#define FAL_IGMP_SG_ENTRY_MAX 32 + +typedef enum +{ + FAL_ADDR_IPV4 = 0, + FAL_ADDR_IPV6 +} fal_addr_type_t; + +typedef struct +{ + fal_addr_type_t type; + union + { + fal_ip4_addr_t ip4_addr; + fal_ip6_addr_t ip6_addr; + } u; +} fal_igmp_sg_addr_t; + +typedef struct +{ + fal_igmp_sg_addr_t source; + fal_igmp_sg_addr_t group; + fal_pbmp_t port_map; + a_uint32_t vlan_id; +} fal_igmp_sg_entry_t; + +//#define MULTI_DEBUG_ +#ifdef MULTI_DEBUG_ +#define MULTI_DEBUG(x...) aos_printk(x) +#else +#define MULTI_DEBUG(x...) +#endif + +#define FAL_ACL_LIST_MULTICAST 55 +#define FAL_MULTICAST_PRI 5 + +#define MULT_ACTION_SET 0 +#define MULT_ACTION_CLEAR 1 + +// static a_uint32_t rule_nr=1; + +typedef struct +{ + a_uint8_t index; //MAX is 32 + fal_igmp_sg_entry_t entry; //Stores the specific ACL rule info +} multi_acl_info_t; + +typedef struct +{ + a_uint8_t cnt; //MAX is 32 + multi_acl_info_t acl_info[FAL_IGMP_SG_ENTRY_MAX]; //Stores the all ACL rule info +} fal_igmp_sg_info_t; + +#endif diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_nat.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_nat.h new file mode 100755 index 000000000..9c6991196 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_nat.h @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2014, 2015, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/** + * @defgroup fal_nat FAL_NAT + * @{ + */ +#ifndef _FAL_NAT_H_ +#define _FAL_NAT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "common/sw.h" +#include "fal/fal_type.h" + + +#define FAL_NAT_ENTRY_PROTOCOL_TCP 0x1 +#define FAL_NAT_ENTRY_PROTOCOL_UDP 0x2 +#define FAL_NAT_ENTRY_PROTOCOL_PPTP 0x4 +#define FAL_NAT_ENTRY_PROTOCOL_ANY 0x8 +#define FAL_NAT_ENTRY_TRANS_IPADDR_INDEX 0x10 +#define FAL_NAT_ENTRY_PORT_CHECK 0x20 +#define FAL_NAT_HASH_KEY_PORT 0x40 +#define FAL_NAT_HASH_KEY_IPADDR 0x80 + + + /* NAT entry operation flags */ +#define FAL_NAT_ENTRY_ID_EN 0x1 +#define FAL_NAT_ENTRY_SRC_IPADDR_EN 0x2 +#define FAL_NAT_ENTRY_TRANS_IPADDR_EN 0x4 +#define FAL_NAT_ENTRY_KEY_EN 0x8 +#define FAL_NAT_ENTRY_PUBLIC_IP_EN 0x10 +#define FAL_NAT_ENTRY_SOURCE_IP_EN 0x20 +#define FAL_NAT_ENTRY_AGE_EN 0x40 +#define FAL_NAT_ENTRY_SYNC_EN 0x80 + + + typedef struct + { + a_uint32_t entry_id; + a_uint32_t flags; + a_uint32_t status; + fal_ip4_addr_t src_addr; + fal_ip4_addr_t dst_addr; + a_uint16_t src_port; + a_uint16_t dst_port; + fal_ip4_addr_t trans_addr; + a_uint16_t trans_port; + a_uint16_t rsv; + a_bool_t mirror_en; + a_bool_t counter_en; + a_uint32_t counter_id; + a_uint32_t ingress_packet; + a_uint32_t ingress_byte; + a_uint32_t egress_packet; + a_uint32_t egress_byte; + fal_fwd_cmd_t action; + a_uint32_t load_balance; + a_uint32_t flow_cookie; + a_uint32_t vrf_id; + a_uint32_t aging_sync; + a_bool_t priority_en; + a_uint32_t priority_val; + } fal_napt_entry_t; + + typedef struct + { + a_uint32_t proto; /*1 tcp; 2 udp*/ + fal_ip4_addr_t src_addr; + fal_ip4_addr_t dst_addr; + a_uint16_t src_port; + a_uint16_t dst_port; + a_uint32_t flow_cookie; + } fal_flow_cookie_t; + + typedef struct + { + a_uint32_t proto; /*1 tcp; 2 udp*/ + fal_ip4_addr_t src_addr; + fal_ip4_addr_t dst_addr; + a_uint16_t src_port; + a_uint16_t dst_port; + a_uint8_t load_balance; + } fal_flow_rfs_t; + + typedef struct + { + a_uint32_t entry_id; + a_uint32_t flags; + a_uint32_t status; + fal_ip4_addr_t src_addr; + fal_ip4_addr_t trans_addr; + a_uint16_t port_num; + a_uint16_t port_range; + a_uint32_t slct_idx; + a_bool_t mirror_en; + a_bool_t counter_en; + a_uint32_t counter_id; + a_uint32_t ingress_packet; + a_uint32_t ingress_byte; + a_uint32_t egress_packet; + a_uint32_t egress_byte; + fal_fwd_cmd_t action; + a_uint32_t vrf_id; + } fal_nat_entry_t; + + + typedef enum + { + FAL_NAPT_FULL_CONE = 0, + FAL_NAPT_STRICT_CONE, + FAL_NAPT_PORT_STRICT, + FAL_NAPT_SYNMETRIC, + } fal_napt_mode_t; + + + typedef struct + { + a_uint32_t entry_id; + fal_ip4_addr_t pub_addr; + } fal_nat_pub_addr_t; + + + sw_error_t + fal_nat_add(a_uint32_t dev_id, fal_nat_entry_t * nat_entry); + + + sw_error_t + fal_nat_del(a_uint32_t dev_id, a_uint32_t del_mode, fal_nat_entry_t * nat_entry); + + + sw_error_t + fal_nat_get(a_uint32_t dev_id, a_uint32_t get_mode, fal_nat_entry_t * nat_entry); + + + sw_error_t + fal_nat_next(a_uint32_t dev_id, a_uint32_t get_mode, fal_nat_entry_t * nat_entry); + + + sw_error_t + fal_nat_counter_bind(a_uint32_t dev_id, a_uint32_t entry_id, a_uint32_t cnt_id, a_bool_t enable); + + + sw_error_t + fal_napt_add(a_uint32_t dev_id, fal_napt_entry_t * napt_entry); + + + sw_error_t + fal_napt_del(a_uint32_t dev_id, a_uint32_t del_mode, fal_napt_entry_t * napt_entry); + + + sw_error_t + fal_napt_get(a_uint32_t dev_id, a_uint32_t get_mode, fal_napt_entry_t * napt_entry); + + + sw_error_t + fal_napt_next(a_uint32_t dev_id, a_uint32_t next_mode, fal_napt_entry_t * napt_entry); + + + sw_error_t + fal_napt_counter_bind(a_uint32_t dev_id, a_uint32_t entry_id, a_uint32_t cnt_id, a_bool_t enable); + + + sw_error_t + fal_flow_add(a_uint32_t dev_id, fal_napt_entry_t * napt_entry); + + + sw_error_t + fal_flow_del(a_uint32_t dev_id, a_uint32_t del_mode, fal_napt_entry_t * napt_entry); + + + sw_error_t + fal_flow_get(a_uint32_t dev_id, a_uint32_t get_mode, fal_napt_entry_t * napt_entry); + + + sw_error_t + fal_flow_next(a_uint32_t dev_id, a_uint32_t next_mode, fal_napt_entry_t * napt_entry); + + + sw_error_t + fal_flow_counter_bind(a_uint32_t dev_id, a_uint32_t entry_id, a_uint32_t cnt_id, a_bool_t enable); + + + sw_error_t + fal_nat_status_set(a_uint32_t dev_id, a_bool_t enable); + + + sw_error_t + fal_nat_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + sw_error_t + fal_nat_hash_mode_set(a_uint32_t dev_id, a_uint32_t mode); + + + sw_error_t + fal_nat_hash_mode_get(a_uint32_t dev_id, a_uint32_t * mode); + + + sw_error_t + fal_napt_status_set(a_uint32_t dev_id, a_bool_t enable); + + + sw_error_t + fal_napt_status_get(a_uint32_t dev_id, a_bool_t * enable); + + + sw_error_t + fal_napt_mode_set(a_uint32_t dev_id, fal_napt_mode_t mode); + + + sw_error_t + fal_napt_mode_get(a_uint32_t dev_id, fal_napt_mode_t * mode); + + + sw_error_t + fal_napt_mode_get(a_uint32_t dev_id, fal_napt_mode_t * mode); + + + sw_error_t + fal_nat_prv_base_addr_set(a_uint32_t dev_id, fal_ip4_addr_t addr); + + + sw_error_t + fal_nat_prv_base_addr_get(a_uint32_t dev_id, fal_ip4_addr_t * addr); + + sw_error_t + fal_nat_prv_base_mask_set(a_uint32_t dev_id, fal_ip4_addr_t addr); + + sw_error_t + fal_nat_prv_base_mask_get(a_uint32_t dev_id, fal_ip4_addr_t * addr); + + + sw_error_t + fal_nat_prv_addr_mode_set(a_uint32_t dev_id, a_bool_t map_en); + + + sw_error_t + fal_nat_prv_addr_mode_get(a_uint32_t dev_id, a_bool_t * map_en); + + + sw_error_t + fal_nat_pub_addr_add(a_uint32_t dev_id, fal_nat_pub_addr_t * entry); + + + sw_error_t + fal_nat_pub_addr_del(a_uint32_t dev_id, a_uint32_t del_mode, fal_nat_pub_addr_t * entry); + + + sw_error_t + fal_nat_pub_addr_next(a_uint32_t dev_id, a_uint32_t next_mode, fal_nat_pub_addr_t * entry); + + + sw_error_t + fal_nat_unk_session_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd); + + + sw_error_t + fal_nat_unk_session_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd); + + sw_error_t + fal_nat_global_set(a_uint32_t dev_id, a_bool_t enable, + a_bool_t sync_cnt_enable, a_uint32_t portbmp); + + sw_error_t + fal_flow_cookie_set(a_uint32_t dev_id, fal_flow_cookie_t * flow_cookie); + + sw_error_t + fal_flow_rfs_set(a_uint32_t dev_id, a_uint8_t action, fal_flow_rfs_t * rfs); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_NAT_H_ */ + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_policer.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_policer.h new file mode 100755 index 000000000..7a646348f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_policer.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/** + * @defgroup fal_policer FAL_POLICER + * @{ + */ +#ifndef _FAL_POLICER_H_ +#define _FAL_POLICER_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "common/sw.h" +#include "fal/fal_type.h" + +typedef struct +{ + a_bool_t meter_en; /* meter enable or disable */ + a_bool_t couple_en; /* two buckets coupling enable or disable*/ + a_uint32_t color_mode; /* color aware or color blind */ + a_uint32_t frame_type; /* frame type, bit0:unicast;bit1: unkown unicast;bit2:multicast;bit3: unknown multicast; bit4:broadcast */ + a_uint32_t meter_mode; + a_uint32_t meter_unit; /* 0:byte based; 1:packet based*/ + a_uint32_t cir; /* committed information rate */ + a_uint32_t cbs; /* committed burst size */ + a_uint32_t eir; /* excess information rate */ + a_uint32_t ebs; /* excess burst size */ +} fal_policer_config_t; + +typedef struct +{ + a_bool_t yellow_priority_en; /* yellow traffic internal priority change enable*/ + a_bool_t yellow_drop_priority_en; /* yellow traffic internal drop priority change enable*/ + a_bool_t yellow_pcp_en; /* yellow traffic pcp change enable*/ + a_bool_t yellow_dei_en; /* yellow traffic dei change enable*/ + a_uint32_t yellow_priority; /* yellow traffic internal priority value*/ + a_uint32_t yellow_drop_priority; /* yellow traffic internal drop priority value*/ + a_uint32_t yellow_pcp; /* yellow traffic pcp value*/ + a_uint32_t yellow_dei; /* yellow traffic dei value*/ + fal_fwd_cmd_t red_action; /* red traffic drop or forward*/ + a_bool_t red_priority_en; /* red traffic internal priority change enable*/ + a_bool_t red_drop_priority_en; /* red traffic internal drop priority change enable*/ + a_bool_t red_pcp_en; /* red traffic pcp change enable*/ + a_bool_t red_dei_en; /* red traffic dei change enable*/ + a_uint32_t red_priority; /* red traffic internal priority value*/ + a_uint32_t red_drop_priority; /* red traffic internal drop priority value*/ + a_uint32_t red_pcp; /* red traffic pcp value*/ + a_uint32_t red_dei; /* red traffic dei value*/ +}fal_policer_action_t; + +typedef struct +{ + a_uint32_t green_packet_counter; /*green packet counter */ + a_uint64_t green_byte_counter; /*green byte counter */ + a_uint32_t yellow_packet_counter; /*yellow packet counter */ + a_uint64_t yellow_byte_counter; /*yellow byte counter */ + a_uint32_t red_packet_counter; /*red packet counter */ + a_uint64_t red_byte_counter; /*red byte counter */ +} fal_policer_counter_t; + +typedef struct +{ + a_uint32_t policer_drop_packet_counter; /*drop packet counter by policer*/ + a_uint64_t policer_drop_byte_counter; /*drop byte counter by policer */ + a_uint32_t policer_forward_packet_counter; /*forward packet counter by policer*/ + a_uint64_t policer_forward_byte_counter; /*forward byte counter by policer*/ + a_uint32_t policer_bypass_packet_counter; /*bypass packet counter by policer*/ + a_uint64_t policer_bypass_byte_counter; /*bypass byte counter by policer */ +} fal_policer_global_counter_t; + +enum +{ + FUNC_ADPT_ACL_POLICER_COUNTER_GET = 0, + FUNC_ADPT_PORT_POLICER_COUNTER_GET, + FUNC_ADPT_PORT_COMPENSATION_BYTE_GET, + FUNC_ADPT_PORT_POLICER_ENTRY_GET, + FUNC_ADPT_PORT_POLICER_ENTRY_SET, + FUNC_ADPT_ACL_POLICER_ENTRY_GET, + FUNC_ADPT_ACL_POLICER_ENTRY_SET, + FUNC_ADPT_POLICER_TIME_SLOT_GET, + FUNC_ADPT_PORT_COMPENSATION_BYTE_SET, + FUNC_ADPT_POLICER_TIME_SLOT_SET, + FUNC_ADPT_POLICER_GLOBAL_COUNTER_GET, +}; + + +sw_error_t +fal_port_policer_entry_set(a_uint32_t dev_id, fal_port_t port_id, + fal_policer_config_t *policer, fal_policer_action_t *action); + +sw_error_t +fal_port_policer_entry_get(a_uint32_t dev_id, fal_port_t port_id, + fal_policer_config_t *policer, fal_policer_action_t *atcion); + +sw_error_t +fal_acl_policer_entry_set(a_uint32_t dev_id, a_uint32_t index, + fal_policer_config_t *policer, fal_policer_action_t *action); + +sw_error_t +fal_acl_policer_entry_get(a_uint32_t dev_id, a_uint32_t index, + fal_policer_config_t *policer, fal_policer_action_t *action); + +sw_error_t +fal_port_policer_counter_get(a_uint32_t dev_id, fal_port_t port_id, + fal_policer_counter_t *counter); + +sw_error_t +fal_acl_policer_counter_get(a_uint32_t dev_id, a_uint32_t index, + fal_policer_counter_t *counter); + +sw_error_t +fal_port_policer_compensation_byte_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t length); + +sw_error_t +fal_port_policer_compensation_byte_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *length); + +sw_error_t +fal_policer_timeslot_set(a_uint32_t dev_id, a_uint32_t timeslot); + +sw_error_t +fal_policer_timeslot_get(a_uint32_t dev_id, a_uint32_t *timeslot); + +sw_error_t +fal_policer_global_counter_get(a_uint32_t dev_id, + fal_policer_global_counter_t *counter); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_POLICER_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_port_ctrl.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_port_ctrl.h new file mode 100755 index 000000000..2b63059df --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_port_ctrl.h @@ -0,0 +1,777 @@ +/* + * Copyright (c) 2014, 2016-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/*qca808x_start*/ +/** + * @defgroup fal_port_ctrl FAL_PORT_CONTROL + * @{ + */ +#ifndef _FAL_PORTCTRL_H_ +#define _FAL_PORTCTRL_H_ + +#ifdef __cplusplus +extern "c" { +#endif + +#include "sw.h" +#include "fal_type.h" + + typedef enum { + FAL_HALF_DUPLEX = 0, + FAL_FULL_DUPLEX, + FAL_DUPLEX_BUTT = 0xffff + } + fal_port_duplex_t; + + typedef enum + { + FAL_SPEED_10 = 10, + FAL_SPEED_100 = 100, + FAL_SPEED_1000 = 1000, + FAL_SPEED_2500 = 2500, + FAL_SPEED_5000 = 5000, + FAL_SPEED_10000 = 10000, + FAL_SPEED_BUTT = 0xffff, + } fal_port_speed_t; + + typedef enum + { + FAL_CABLE_STATUS_NORMAL = 0, + FAL_CABLE_STATUS_SHORT = 1, + FAL_CABLE_STATUS_OPENED = 2, + FAL_CABLE_STATUS_INVALID = 3, + FAL_CABLE_STATUS_CROSSOVERA = 4, + FAL_CABLE_STATUS_CROSSOVERB = 5, + FAL_CABLE_STATUS_CROSSOVERC = 6, + FAL_CABLE_STATUS_CROSSOVERD = 7, + FAL_CABLE_STATUS_LOW_MISMATCH = 8, + FAL_CABLE_STATUS_HIGH_MISMATCH = 9, + FAL_CABLE_STATUS_BUTT = 0xffff, + } fal_cable_status_t; + +#define FAL_ENABLE 1 +#define FAL_DISABLE 0 +#define FAL_MAX_PORT_NUMBER 8 + +//phy autoneg adv +#define FAL_PHY_ADV_10T_HD 0x01 +#define FAL_PHY_ADV_10T_FD 0x02 +#define FAL_PHY_ADV_100TX_HD 0x04 +#define FAL_PHY_ADV_100TX_FD 0x08 +//#define FAL_PHY_ADV_1000T_HD 0x100 +#define FAL_PHY_ADV_1000T_FD 0x200 +#define FAL_PHY_ADV_1000BX_HD 0x400 +#define FAL_PHY_ADV_1000BX_FD 0x800 +#define FAL_PHY_ADV_2500T_FD 0x1000 +#define FAL_PHY_ADV_5000T_FD 0x2000 +#define FAL_PHY_ADV_10000T_FD 0x4000 + +#define FAL_PHY_ADV_10G_R_FD 0x8000 + +#define FAL_PHY_ADV_FE_SPEED_ALL \ + (FAL_PHY_ADV_10T_HD | FAL_PHY_ADV_10T_FD | FAL_PHY_ADV_100TX_HD |\ + FAL_PHY_ADV_100TX_FD) + +#define FAL_PHY_ADV_GE_SPEED_ALL \ + (FAL_PHY_ADV_10T_HD | FAL_PHY_ADV_10T_FD | FAL_PHY_ADV_100TX_HD |\ + FAL_PHY_ADV_100TX_FD | FAL_PHY_ADV_1000T_FD) + +#define FAL_PHY_ADV_BX_SPEED_ALL \ + (FAL_PHY_ADV_1000BX_HD | FAL_PHY_ADV_1000BX_FD |FAL_PHY_ADV_10G_R_FD) + +#define FAL_PHY_ADV_XGE_SPEED_ALL \ + (FAL_PHY_ADV_2500T_FD | FAL_PHY_ADV_5000T_FD | FAL_PHY_ADV_10000T_FD) + +#define FAL_PHY_ADV_PAUSE 0x10 +#define FAL_PHY_ADV_ASY_PAUSE 0x20 +#define FAL_PHY_FE_ADV_ALL \ + (FAL_PHY_ADV_FE_SPEED_ALL | FAL_PHY_ADV_PAUSE | FAL_PHY_ADV_ASY_PAUSE) +#define FAL_PHY_GE_ADV_ALL \ + (FAL_PHY_ADV_GE_SPEED_ALL | FAL_PHY_ADV_PAUSE | FAL_PHY_ADV_ASY_PAUSE) + +#define FAL_PHY_COMBO_ADV_ALL \ + (FAL_PHY_ADV_BX_SPEED_ALL | FAL_PHY_ADV_GE_SPEED_ALL | FAL_PHY_ADV_XGE_SPEED_ALL |\ + FAL_PHY_ADV_PAUSE | FAL_PHY_ADV_ASY_PAUSE) + +//phy capablity +#define FAL_PHY_AUTONEG_CAPS 0x01 +#define FAL_PHY_100T2_HD_CAPS 0x02 +#define FAL_PHY_100T2_FD_CAPS 0x04 +#define FAL_PHY_10T_HD_CAPS 0x08 +#define FAL_PHY_10T_FD_CAPS 0x10 +#define FAL_PHY_100X_HD_CAPS 0x20 +#define FAL_PHY_100X_FD_CAPS 0x40 +#define FAL_PHY_100T4_CAPS 0x80 +//#define FAL_PHY_1000T_HD_CAPS 0x100 +#define FAL_PHY_1000T_FD_CAPS 0x200 +//#define FAL_PHY_1000X_HD_CAPS 0x400 +#define FAL_PHY_1000X_FD_CAPS 0x800 + +//phy partner capablity +#define FAL_PHY_PART_10T_HD 0x1 +#define FAL_PHY_PART_10T_FD 0x2 +#define FAL_PHY_PART_100TX_HD 0x4 +#define FAL_PHY_PART_100TX_FD 0x8 +//#define FAL_PHY_PART_1000T_HD 0x10 +#define FAL_PHY_PART_1000T_FD 0x20 + +//phy interrupt flag +#define FAL_PHY_INTR_SPEED_CHANGE 0x1 +#define FAL_PHY_INTR_DUPLEX_CHANGE 0x2 +#define FAL_PHY_INTR_STATUS_UP_CHANGE 0x4 +#define FAL_PHY_INTR_STATUS_DOWN_CHANGE 0x8 +#define FAL_PHY_INTR_BX_FX_STATUS_UP_CHANGE 0x10 +#define FAL_PHY_INTR_BX_FX_STATUS_DOWN_CHANGE 0x20 +#define FAL_PHY_INTR_MEDIA_STATUS_CHANGE 0x40 +#define FAL_PHY_INTR_WOL_STATUS 0x80 +#define FAL_PHY_INTR_POE_STATUS 0x100 + + typedef enum + { + FAL_NO_HEADER_EN = 0, + FAL_ONLY_MANAGE_FRAME_EN, + FAL_ALL_TYPE_FRAME_EN + } fal_port_header_mode_t; + + typedef struct + { + a_uint16_t pair_a_status; + a_uint16_t pair_b_status; + a_uint16_t pair_c_status; + a_uint16_t pair_d_status; + a_uint32_t pair_a_len; + a_uint32_t pair_b_len; + a_uint32_t pair_c_len; + a_uint32_t pair_d_len; + } fal_port_cdt_t; + +/*below is new add for malibu phy*/ + +/** Phy mdix mode */ +typedef enum { + PHY_MDIX_AUTO = 0, /**< Auto MDI/MDIX */ + PHY_MDIX_MDI = 1, /**< Fixed MDI */ + PHY_MDIX_MDIX = 2 /**< Fixed MDIX */ +} fal_port_mdix_mode_t; + +/** Phy mdix status */ +typedef enum { + PHY_MDIX_STATUS_MDI = 0, /**< Fixed MDI */ + PHY_MDIX_STATUS_MDIX = 1 /**< Fixed MDIX */ + +} fal_port_mdix_status_t; + +/** Phy master mode */ +typedef enum { + PHY_MASTER_MASTER = 0, /**< Phy manual MASTER configuration */ + PHY_MASTER_SLAVE = 1, /**< Phy manual SLAVE configuration */ + PHY_MASTER_AUTO = 2 /**< Phy automatic MASTER/SLAVE configuration */ +} fal_port_master_t; +/*qca808x_end*/ +/** Phy preferred medium type */ +typedef enum { + PHY_MEDIUM_COPPER = 0, /**< Copper */ + PHY_MEDIUM_FIBER = 1, /**< Fiber */ + +} fal_port_medium_t; + +/** Phy pages */ +typedef enum { + PHY_SGBX_PAGES = 0, /**< sgbx pages */ + PHY_COPPER_PAGES = 1 /**< copper pages */ + +} fal_port_reg_pages_t; + + +/** Phy preferred Fiber mode */ +typedef enum { + PHY_FIBER_100FX = 0, /**< 100FX fiber mode */ + PHY_FIBER_1000BX = 1, /**< 1000BX fiber mode */ + PHY_FIBER_10G_R = 2, /**< 10G-R fiber mode */ + +} fal_port_fiber_mode_t; + +/** Phy reset status */ +typedef enum { + PHY_RESET_DONE = 0, /**< Phy reset done */ + PHY_RESET_BUSY = 1 /**< Phy still in reset process */ +} fal_port_reset_status_t; + +/** Phy auto-negotiation status */ +typedef enum { + PHY_AUTO_NEG_STATUS_BUSY = 0, /**< Phy still in auto-negotiation process */ + PHY_AUTO_NEG_STATUS_DONE = 1 /**< Phy auto-negotiation done */ +} fal_port_auto_neg_status_t; +/*qca808x_start*/ + +/** Phy interface mode */ + typedef enum { + PHY_PSGMII_BASET = 0, + /**< PSGMII mode */ + PHY_PSGMII_BX1000 = 1, + /**< PSGMII BX1000 mode */ + PHY_PSGMII_FX100 = 2, + /**< PSGMII FX100 mode */ + PHY_PSGMII_AMDET = 3, + /**< PSGMII Auto mode */ + PHY_SGMII_BASET = 4, + /**< SGMII mode */ + PORT_QSGMII, + /**>24)&0xff) +#define FAL_PORT_ID_VALUE(port_id) ((port_id)&0xffffff) +#define FAL_PORT_ID(type, value) (((type)<<24)|(value)) + +#define FAL_IS_PPORT(port_id) (((FAL_PORT_ID_TYPE(port_id))==FAL_PORT_TYPE_PPORT)?1:0) +#define FAL_IS_TRUNK(port_id) (((FAL_PORT_ID_TYPE(port_id))==FAL_PORT_TYPE_TRUNK)?1:0) +#define FAL_IS_VPORT(port_id) (((FAL_PORT_ID_TYPE(port_id))==FAL_PORT_TYPE_VPORT)?1:0) + + +#if (SW_MAX_NR_PORT <= 32) + typedef a_uint32_t fal_pbmp_t; +#else + typedef a_uint64_t fal_pbmp_t; +#endif + + typedef struct + { + a_uint8_t uc[6]; + } fal_mac_addr_t; + + typedef a_uint32_t fal_ip4_addr_t; + + typedef struct + { + a_uint32_t ul[4]; + } fal_ip6_addr_t; + + /** + @brief This enum defines several forwarding command type. + * Field description: + FAL_MAC_FRWRD - packets are normally forwarded + FAL_MAC_DROP - packets are dropped + FAL_MAC_CPY_TO_CPU - packets are copyed to cpu + FAL_MAC_RDT_TO_CPU - packets are redirected to cpu + */ + typedef enum + { + FAL_MAC_FRWRD = 0, /**< packets are normally forwarded */ + FAL_MAC_DROP, /**< packets are dropped */ + FAL_MAC_CPY_TO_CPU, /**< packets are copyed to cpu */ + FAL_MAC_RDT_TO_CPU /**< packets are redirected to cpu */ + } fal_fwd_cmd_t; + + typedef enum + { + FAL_BYTE_BASED = 0, + FAL_FRAME_BASED, + FAL_RATE_MODE_BUTT + } fal_traffic_unit_t; + + typedef a_uint32_t fal_queue_t; + +#define FAL_SVL_FID 0xffff + + + /** + @brief This enum defines packets transmitted out vlan tagged mode. + */ + typedef enum + { + FAL_EG_UNMODIFIED = 0, /**< egress transmit packets unmodified */ + FAL_EG_UNTAGGED, /**< egress transmit packets without vlan tag*/ + FAL_EG_TAGGED, /**< egress transmit packets with vlan tag */ + FAL_EG_HYBRID, /**< egress transmit packets in hybrid tag mode */ + FAL_EG_UNTOUCHED, + FAL_EG_MODE_BUTT + } fal_pt_1q_egmode_t; + +#define FAL_NEXT_ENTRY_FIRST_ID 0xffffffff + + typedef struct{ + a_uint32_t reg_count; + a_uint32_t reg_base; + a_uint32_t reg_end; + a_uint32_t reg_value[256]; + a_int8_t reg_name[32]; + }fal_reg_dump_t; + + typedef struct{ + a_uint32_t reg_count; + a_uint32_t reg_addr[32]; + a_uint32_t reg_value[32]; + a_int8_t reg_name[32]; + }fal_debug_reg_dump_t; + + typedef struct{ + a_uint32_t phy_count; + a_uint32_t phy_base; + a_uint32_t phy_end; + a_uint16_t phy_value[256]; + a_int8_t phy_name[32]; + }fal_phy_dump_t; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_TYPE_H_ */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_uk_if.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_uk_if.h new file mode 100755 index 000000000..18a8bd761 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_uk_if.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014,2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#ifndef _FAL_UK_IF_H_ +#define _FAL_UK_IF_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" +#include "fal_type.h" +#include "ssdk_init.h" + + sw_error_t + sw_uk_exec(a_uint32_t api_id, ...); + + sw_error_t + ssdk_init(a_uint32_t dev_id, ssdk_init_cfg * cfg); + + sw_error_t + ssdk_cleanup(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_UK_IF_H_ */ + + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_vlan.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_vlan.h new file mode 100755 index 000000000..a1397a592 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_vlan.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/** + * @defgroup fal_vlan FAL_VLAN + * @{ + */ +#ifndef _FAL_VLAN_H +#define _FAL_VLAN_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "common/sw.h" +#include "fal/fal_type.h" + + /** + @brief This structure defines vlan entry. + */ + typedef struct + { + a_uint16_t vid; /**< vlan entry id */ + a_uint16_t fid; /**< filter data base id*/ + fal_pbmp_t mem_ports; /**< member port bit map */ + fal_pbmp_t tagged_ports; /**< bit map of tagged infomation for member port*/ + fal_pbmp_t untagged_ports; /**< bit map of untagged infomation for member port*/ + fal_pbmp_t unmodify_ports;/**< bit map of unmodified infomation for member port*/ + fal_pbmp_t u_ports; + a_bool_t learn_dis; /**< disable address learning*/ + a_bool_t vid_pri_en; /**< enable 802.1p*/ + a_uint8_t vid_pri; /**< vlaue of 802.1p when enable vid_pri_en*/ + } fal_vlan_t; + + + sw_error_t + fal_vlan_entry_append(a_uint32_t dev_id, fal_vlan_t * vlan_entry); + + + + sw_error_t + fal_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id); + + + + sw_error_t + fal_vlan_next(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan); + + + + sw_error_t + fal_vlan_find(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan); + + + + sw_error_t + fal_vlan_member_update(a_uint32_t dev_id, a_uint32_t vlan_id, + fal_pbmp_t member, fal_pbmp_t u_member); + + + + sw_error_t + fal_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id); + + + + sw_error_t + fal_vlan_reset(a_uint32_t dev_id); + + + sw_error_t + fal_vlan_flush(a_uint32_t dev_id); + + + sw_error_t + fal_vlan_init(a_uint32_t dev_id); + + + sw_error_t + fal_vlan_cleanup(void); + + + sw_error_t + fal_vlan_fid_set(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t fid); + + + sw_error_t + fal_vlan_fid_get(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t * fid); + + + sw_error_t + fal_vlan_member_add(a_uint32_t dev_id, a_uint32_t vlan_id, + fal_port_t port_id, fal_pt_1q_egmode_t port_info); + + + sw_error_t + fal_vlan_member_del(a_uint32_t dev_id, a_uint32_t vlan_id, fal_port_t port_id); + + + sw_error_t + fal_vlan_learning_state_set(a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t enable); + + + sw_error_t + fal_vlan_learning_state_get(a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t * enable); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _FAL_VLAN_H */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_vsi.h b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_vsi.h new file mode 100755 index 000000000..c6543be6f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/fal/fal_vsi.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/** + * @defgroup fal_stp FAL_VSI + * @{ + */ +#ifndef _FAL_VSI_H_ +#define _FAL_VSI_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "common/sw.h" +#include "fal/fal_type.h" + +#define FAL_VSI_INVALID 0xffff +#define FAL_VLAN_INVALID 0xffff + +typedef struct{ + a_uint32_t lrn_en; /*0: disable new address learn, 1: enable new address learn*/ + fal_fwd_cmd_t action;/*0:forward, 1:drop, 2: copy to CPU, 3: redirect to CPU*/ +}fal_vsi_newaddr_lrn_t; + +typedef struct{ + a_uint32_t stamove_en;/*0:disable station move, 1: enable station move*/ + fal_fwd_cmd_t action;/*0:forward, 1:drop, 2: copy to CPU, 3: redirect to CPU*/ +}fal_vsi_stamove_t; + +typedef struct{ + a_uint32_t member_ports;/*VSI member ports for known unicast and multicast*/ + a_uint32_t uuc_ports;/*VSI member ports for unknown unicast*/ + a_uint32_t umc_ports;/*VSI member ports for unknown multicast*/ + a_uint32_t bc_ports;/*VSI member ports for broadcast*/ +}fal_vsi_member_t; + +typedef struct +{ + a_uint32_t rx_packet_counter; + a_uint64_t rx_byte_counter; + a_uint32_t tx_packet_counter; + a_uint64_t tx_byte_counter; + a_uint32_t fwd_packet_counter; + a_uint64_t fwd_byte_counter; + a_uint32_t drop_packet_counter; + a_uint64_t drop_byte_counter; +}fal_vsi_counter_t; + + +enum{ + FUNC_PORT_VLAN_VSI_SET, + FUNC_PORT_VLAN_VSI_GET, + FUNC_PORT_VSI_SET, + FUNC_PORT_VSI_GET, + FUNC_VSI_STAMOVE_SET, + FUNC_VSI_STAMOVE_GET, + FUNC_VSI_NEWADDR_LRN_SET, + FUNC_VSI_NEWADDR_LRN_GET, + FUNC_VSI_MEMBER_SET, + FUNC_VSI_MEMBER_GET, + FUNC_VSI_COUNTER_GET, + FUNC_VSI_COUNTER_CLEANUP, +}; + +sw_error_t +fal_vsi_alloc(a_uint32_t dev_id, a_uint32_t *vsi); + +sw_error_t +fal_vsi_free(a_uint32_t dev_id, a_uint32_t vsi); + +sw_error_t +fal_port_vsi_set(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t vsi_id); + +sw_error_t +fal_port_vsi_get(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t *vsi_id); + +sw_error_t +fal_port_vlan_vsi_set(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t stag_vid, a_uint32_t ctag_vid, a_uint32_t vsi_id); + +sw_error_t +fal_port_vlan_vsi_get(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t stag_vid, a_uint32_t ctag_vid, a_uint32_t *vsi_id); + +sw_error_t +fal_vsi_tbl_dump(a_uint32_t dev_id); + +sw_error_t +fal_vsi_newaddr_lrn_set(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_newaddr_lrn_t *newaddr_lrn); + +sw_error_t +fal_vsi_newaddr_lrn_get(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_newaddr_lrn_t *newaddr_lrn); + +sw_error_t +fal_vsi_stamove_set(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_stamove_t *stamove); + +sw_error_t +fal_vsi_stamove_get(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_stamove_t *stamove); + +sw_error_t +fal_vsi_member_set(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_member_t *vsi_member); + +sw_error_t +fal_vsi_member_get(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_member_t *vsi_member); + +sw_error_t +fal_vsi_counter_get(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_counter_t *counter); + +sw_error_t +fal_vsi_counter_cleanup(a_uint32_t dev_id, a_uint32_t vsi_id); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _FAL_VSI_H_ */ + +/** + * @} + */ + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/init/ssdk_init.h b/feeds/ipq807x/qca-ssdk-shell/src/include/init/ssdk_init.h new file mode 100755 index 000000000..de0e27482 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/init/ssdk_init.h @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2014, 2017-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/*qca808x_start*/ +#ifndef _SSDK_INIT_H_ +#define _SSDK_INIT_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" +/*qca808x_end*/ +#include "fal_led.h" + +/*qca808x_start*/ + typedef enum { + HSL_MDIO = 1, + HSL_HEADER, + } + hsl_access_mode; + + typedef enum + { + HSL_NO_CPU = 0, + HSL_CPU_1, + HSL_CPU_2, + HSL_CPU_1_PLUS, + } hsl_init_mode; + typedef sw_error_t + (*mdio_reg_set) (a_uint32_t dev_id, a_uint32_t phy_addr, a_uint32_t reg, + a_uint16_t data); + + typedef sw_error_t + (*mdio_reg_get) (a_uint32_t dev_id, a_uint32_t phy_addr, a_uint32_t reg, + a_uint16_t * data); + + typedef sw_error_t + (*i2c_reg_set) (a_uint32_t dev_id, a_uint32_t phy_addr, a_uint32_t reg, + a_uint16_t data); + + typedef sw_error_t + (*i2c_reg_get) (a_uint32_t dev_id, a_uint32_t phy_addr, a_uint32_t reg, + a_uint16_t * data); +/*qca808x_end*/ + typedef sw_error_t + (*hdr_reg_set) (a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t *reg_data, a_uint32_t len); + + typedef sw_error_t + (*hdr_reg_get) (a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t *reg_data, a_uint32_t len); + typedef sw_error_t + (*psgmii_reg_set) (a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t *reg_data, a_uint32_t len); + + typedef sw_error_t + (*psgmii_reg_get) (a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t *reg_data, a_uint32_t len); + + typedef sw_error_t + (*uniphy_reg_set) (a_uint32_t dev_id, a_uint32_t index, a_uint32_t reg_addr, a_uint8_t *reg_data, a_uint32_t len); + + typedef sw_error_t + (*uniphy_reg_get) (a_uint32_t dev_id, a_uint32_t index, a_uint32_t reg_addr, a_uint8_t *reg_data, a_uint32_t len); + + typedef void (*mii_reg_set)(a_uint32_t reg, a_uint32_t val); + + typedef a_uint32_t (*mii_reg_get)(a_uint32_t reg); +/*qca808x_start*/ + typedef struct + { + mdio_reg_set mdio_set; + mdio_reg_get mdio_get; +/*qca808x_end*/ + hdr_reg_set header_reg_set; + hdr_reg_get header_reg_get; + psgmii_reg_set psgmii_reg_set; + psgmii_reg_get psgmii_reg_get; + uniphy_reg_set uniphy_reg_set; + uniphy_reg_get uniphy_reg_get; + mii_reg_set mii_reg_set; + mii_reg_get mii_reg_get; +/*qca808x_start*/ + i2c_reg_set i2c_set; + i2c_reg_get i2c_get; + } hsl_reg_func; +/*qca808x_end*/ + + typedef struct + { + a_bool_t mac0_rgmii; + a_bool_t mac5_rgmii; + a_bool_t rx_delay_s0; + a_bool_t rx_delay_s1; + a_bool_t tx_delay_s0; + a_bool_t tx_delay_s1; + a_bool_t rgmii_rxclk_delay; + a_bool_t rgmii_txclk_delay; + a_bool_t phy4_rx_delay; + a_bool_t phy4_tx_delay; + } garuda_init_spec_cfg; +/*qca808x_start*/ + typedef enum + { + CHIP_UNSPECIFIED = 0, + CHIP_ATHENA, + CHIP_GARUDA, + CHIP_SHIVA, + CHIP_HORUS, + CHIP_ISIS, + CHIP_ISISC, + CHIP_DESS, + CHIP_HPPE, + } ssdk_chip_type; +/*qca808x_end*/ + typedef struct + { + a_uint32_t cpu_bmp; + a_uint32_t lan_bmp; + a_uint32_t wan_bmp; + a_uint32_t inner_bmp; + } ssdk_port_cfg; + + typedef struct + { + a_uint32_t led_num; + a_uint32_t led_source_id; + led_ctrl_pattern_t led_pattern; + + } led_source_cfg_t; +/*qca808x_start*/ +typedef struct +{ + hsl_init_mode cpu_mode; + hsl_access_mode reg_mode; + hsl_reg_func reg_func; + + ssdk_chip_type chip_type; + a_uint32_t chip_revision; + /* os specific parameter */ + /* when uk_if based on netlink, it's netlink protocol type*/ + /* when uk_if based on ioctl, it's minor device number, major number + is always 10(misc device) */ + a_uint32_t nl_prot; + /* chip specific parameter */ + void * chip_spec_cfg; +/*qca808x_end*/ + /* port cfg */ + ssdk_port_cfg port_cfg; + a_uint32_t mac_mode; + a_uint32_t led_source_num; + led_source_cfg_t led_source_cfg[15]; +/*qca808x_start*/ + a_uint32_t phy_id; + a_uint32_t mac_mode1; + a_uint32_t mac_mode2; +} ssdk_init_cfg; +/*qca808x_end*/ +#if defined ATHENA +#define def_init_cfg {.reg_mode = HSL_MDIO, .cpu_mode = HSL_CPU_2}; +#elif defined GARUDA + +#define def_init_cfg_cpu2 {.reg_mode = HSL_MDIO, .cpu_mode = HSL_CPU_2,}; + +#define def_init_spec_cfg_cpu2 {.mac0_rgmii = A_TRUE, .mac5_rgmii = A_TRUE, \ + .rx_delay_s0 = A_FALSE, .rx_delay_s1 = A_FALSE, \ + .tx_delay_s0 = A_TRUE, .tx_delay_s1 = A_FALSE,\ + .rgmii_rxclk_delay = A_TRUE, .rgmii_txclk_delay = A_TRUE,\ + .phy4_rx_delay = A_TRUE, .phy4_tx_delay = A_TRUE,} + +#define def_init_cfg_cpu1 {.reg_mode = HSL_MDIO, .cpu_mode = HSL_CPU_1,}; + +#define def_init_spec_cfg_cpu1 {.mac0_rgmii = A_TRUE, .mac5_rgmii = A_FALSE, \ + .rx_delay_s0 = A_FALSE, .rx_delay_s1 = A_FALSE, \ + .tx_delay_s0 = A_TRUE, .tx_delay_s1 = A_FALSE,\ + .rgmii_rxclk_delay = A_TRUE, .rgmii_txclk_delay = A_TRUE, \ + .phy4_rx_delay = A_TRUE, .phy4_tx_delay = A_TRUE,} + +#define def_init_cfg_cpu1plus {.reg_mode = HSL_MDIO, .cpu_mode = HSL_CPU_1_PLUS,}; + +#define def_init_spec_cfg_cpu1plus {.mac0_rgmii = A_TRUE, .mac5_rgmii = A_FALSE, \ + .rx_delay_s0 = A_FALSE, .rx_delay_s1 = A_FALSE, \ + .tx_delay_s0 = A_FALSE, .tx_delay_s1 = A_FALSE,\ + .rgmii_rxclk_delay = A_TRUE, .rgmii_txclk_delay = A_TRUE, \ + .phy4_rx_delay = A_TRUE, .phy4_tx_delay = A_TRUE,} + +#define def_init_cfg_nocpu {.reg_mode = HSL_MDIO, .cpu_mode = HSL_NO_CPU,}; + +#define def_init_spec_cfg_nocpu { .mac0_rgmii = A_FALSE, .mac5_rgmii = A_FALSE, \ + .rx_delay_s0 = A_FALSE, .rx_delay_s1 = A_FALSE, \ + .tx_delay_s0 = A_FALSE, .tx_delay_s1 = A_FALSE,\ + .rgmii_rxclk_delay = A_TRUE, .rgmii_txclk_delay = A_TRUE, \ + .phy4_rx_delay = A_TRUE, .phy4_tx_delay = A_TRUE,} + +#define def_init_cfg_cpu1_gmii {.reg_mode = HSL_MDIO, .cpu_mode = HSL_CPU_1,}; + +#define def_init_spec_cfg_cpu1_gmii {.mac0_rgmii = A_FALSE, .mac5_rgmii = A_FALSE, \ + .rx_delay_s0 = A_FALSE, .rx_delay_s1 = A_FALSE, \ + .tx_delay_s0 = A_TRUE, .tx_delay_s1 = A_FALSE,\ + .rgmii_rxclk_delay = A_TRUE, .rgmii_txclk_delay = A_TRUE, \ + .phy4_rx_delay = A_TRUE, .phy4_tx_delay = A_TRUE,} + +#define def_init_cfg def_init_cfg_cpu2 +#define def_init_spec_cfg def_init_spec_cfg_cpu2 + +#elif defined SHIVA +#define def_init_cfg {.reg_mode = HSL_MDIO, .cpu_mode = HSL_CPU_2}; +#elif defined HORUS +#define def_init_cfg {.reg_mode = HSL_MDIO, .cpu_mode = HSL_CPU_2}; +#elif defined ISIS +#define def_init_cfg {.reg_mode = HSL_MDIO, .cpu_mode = HSL_CPU_2}; +#elif defined ISISC +/*qca808x_start*/ +#define def_init_cfg {.reg_mode = HSL_MDIO, .cpu_mode = HSL_CPU_2}; +/*qca808x_end*/ +#endif + typedef struct + { + a_bool_t in_acl; + a_bool_t in_fdb; + a_bool_t in_igmp; + a_bool_t in_leaky; + a_bool_t in_led; + a_bool_t in_mib; + a_bool_t in_mirror; + a_bool_t in_misc; + a_bool_t in_portcontrol; + a_bool_t in_portvlan; + a_bool_t in_qos; + a_bool_t in_rate; + a_bool_t in_stp; + a_bool_t in_vlan; + a_bool_t in_reduced_acl; + a_bool_t in_ip; + a_bool_t in_nat; + a_bool_t in_cosmap; + a_bool_t in_sec; + a_bool_t in_trunk; + a_bool_t in_nathelper; + a_bool_t in_interfacectrl; + } ssdk_features; +/*qca808x_start*/ +#define CFG_STR_SIZE 20 + typedef struct + { + a_uint8_t build_ver[CFG_STR_SIZE]; + a_uint8_t build_date[CFG_STR_SIZE]; + + a_uint8_t chip_type[CFG_STR_SIZE]; //GARUDA + a_uint8_t cpu_type[CFG_STR_SIZE]; //mips + a_uint8_t os_info[CFG_STR_SIZE]; //OS=linux OS_VER=2_6 + + a_bool_t fal_mod; + a_bool_t kernel_mode; + a_bool_t uk_if; +/*qca808x_end*/ + ssdk_features features; +/*qca808x_start*/ + ssdk_init_cfg init_cfg; + } ssdk_cfg_t; + sw_error_t + ssdk_init(a_uint32_t dev_id, ssdk_init_cfg *cfg); +/*qca808x_end*/ + sw_error_t + ssdk_hsl_access_mode_set(a_uint32_t dev_id, hsl_access_mode reg_mode); +/*qca808x_start*/ +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SSDK_INIT_H */ +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/init/ssdk_plat.h b/feeds/ipq807x/qca-ssdk-shell/src/include/init/ssdk_plat.h new file mode 100755 index 000000000..7cbeaa8b3 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/init/ssdk_plat.h @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __SSDK_PLAT_H +#define __SSDK_PLAT_H + +#ifndef BIT +#define BIT(_n) (1UL << (_n)) +#endif + + +#ifndef BITS +#define BITS(_s, _n) (((1UL << (_n)) - 1) << _s) +#endif + +/* Atheros specific MII registers */ +#define QCA_MII_MMD_ADDR 0x0d +#define QCA_MII_MMD_DATA 0x0e +#define QCA_MII_DBG_ADDR 0x1d +#define QCA_MII_DBG_DATA 0x1e + +#define AR8327_REG_CTRL 0x0000 +#define AR8327_CTRL_REVISION BITS(0, 8) +#define AR8327_CTRL_REVISION_S 0 +#define AR8327_CTRL_VERSION BITS(8, 8) +#define AR8327_CTRL_VERSION_S 8 +#define AR8327_CTRL_RESET BIT(31) + +#define AR8327_REG_LED_CTRL_0 0x50 +#define AR8327_REG_LED_CTRL_1 0x54 +#define AR8327_REG_LED_CTRL_2 0x58 +#define AR8327_REG_LED_CTRL_3 0x5c + +#define AR8327_REG_PORT_STATUS(_i) (0x07c + (_i) * 4) + +#define AR8327_PORT_STATUS_SPEED BITS(0,2) +#define AR8327_PORT_STATUS_SPEED_S 0 +#define AR8327_PORT_STATUS_TXMAC BIT(2) +#define AR8327_PORT_STATUS_RXMAC BIT(3) +#define AR8327_PORT_STATUS_TXFLOW BIT(4) +#define AR8327_PORT_STATUS_RXFLOW BIT(5) +#define AR8327_PORT_STATUS_DUPLEX BIT(6) +#define AR8327_PORT_STATUS_LINK_UP BIT(8) +#define AR8327_PORT_STATUS_LINK_AUTO BIT(9) +#define AR8327_PORT_STATUS_LINK_PAUSE BIT(10) + +#define AR8327_REG_PAD0_CTRL 0x4 +#define AR8327_REG_PAD5_CTRL 0x8 +#define AR8327_REG_PAD6_CTRL 0xc +#define AR8327_PAD_CTRL_MAC_MII_RXCLK_SEL BIT(0) +#define AR8327_PAD_CTRL_MAC_MII_TXCLK_SEL BIT(1) +#define AR8327_PAD_CTRL_MAC_MII_EN BIT(2) +#define AR8327_PAD_CTRL_MAC_GMII_RXCLK_SEL BIT(4) +#define AR8327_PAD_CTRL_MAC_GMII_TXCLK_SEL BIT(5) +#define AR8327_PAD_CTRL_MAC_GMII_EN BIT(6) +#define AR8327_PAD_CTRL_SGMII_EN BIT(7) +#define AR8327_PAD_CTRL_PHY_MII_RXCLK_SEL BIT(8) +#define AR8327_PAD_CTRL_PHY_MII_TXCLK_SEL BIT(9) +#define AR8327_PAD_CTRL_PHY_MII_EN BIT(10) +#define AR8327_PAD_CTRL_PHY_GMII_PIPE_RXCLK_SEL BIT(11) +#define AR8327_PAD_CTRL_PHY_GMII_RXCLK_SEL BIT(12) +#define AR8327_PAD_CTRL_PHY_GMII_TXCLK_SEL BIT(13) +#define AR8327_PAD_CTRL_PHY_GMII_EN BIT(14) +#define AR8327_PAD_CTRL_PHYX_GMII_EN BIT(16) +#define AR8327_PAD_CTRL_PHYX_RGMII_EN BIT(17) +#define AR8327_PAD_CTRL_PHYX_MII_EN BIT(18) +#define AR8327_PAD_CTRL_RGMII_RXCLK_DELAY_SEL BITS(20, 2) +#define AR8327_PAD_CTRL_RGMII_RXCLK_DELAY_SEL_S 20 +#define AR8327_PAD_CTRL_RGMII_TXCLK_DELAY_SEL BITS(22, 2) +#define AR8327_PAD_CTRL_RGMII_TXCLK_DELAY_SEL_S 22 +#define AR8327_PAD_CTRL_RGMII_RXCLK_DELAY_EN BIT(24) +#define AR8327_PAD_CTRL_RGMII_TXCLK_DELAY_EN BIT(25) +#define AR8327_PAD_CTRL_RGMII_EN BIT(26) + +#define AR8327_REG_POS 0x10 +#define AR8327_POS_POWER_ON_SEL BIT(31) +#define AR8327_POS_LED_OPEN_EN BIT(24) +#define AR8327_POS_SERDES_AEN BIT(7) + +#define AR8327_REG_PAD_SGMII_CTRL 0xe0 +#define AR8327_PAD_SGMII_CTRL_MODE_CTRL BITS(22, 2) +#define AR8327_PAD_SGMII_CTRL_MODE_CTRL_S 22 +#define AR8327_PAD_SGMII_CTRL_EN_SD BIT(4) +#define AR8327_PAD_SGMII_CTRL_EN_TX BIT(3) +#define AR8327_PAD_SGMII_CTRL_EN_RX BIT(2) +#define AR8327_PAD_SGMII_CTRL_EN_PLL BIT(1) +#define AR8327_PAD_SGMII_CTRL_EN_LCKDT BIT(0) + +#define AR8327_REG_PAD_MAC_PWR_SEL 0x0e4 +#define AR8327_PAD_MAC_PWR_RGMII0_1_8V BIT(19) +#define AR8327_PAD_MAC_PWR_RGMII1_1_8V BIT(18) + +#define AR8327_NUM_PHYS 5 +#define AR8327_PORT_CPU 0 +#define AR8327_NUM_PORTS 8 +#define AR8327_MAX_VLANS 128 + +enum { + AR8327_PORT_SPEED_10M = 0, + AR8327_PORT_SPEED_100M = 1, + AR8327_PORT_SPEED_1000M = 2, + AR8327_PORT_SPEED_NONE = 3, +}; + +enum { + QCA_VER_AR8216 = 0x01, + QCA_VER_AR8236 = 0x03, + QCA_VER_AR8316 = 0x10, + QCA_VER_AR8327 = 0x12, + QCA_VER_AR8337 = 0x13 +}; + +/*poll mib per 2secs*/ +#define QCA_PHY_MIB_WORK_DELAY 20000 +#define QCA_MIB_ITEM_NUMBER 41 + +struct qca_phy_priv { + struct phy_device *phy; + struct switch_dev sw_dev; + a_uint8_t version; + a_uint8_t revision; + a_uint32_t (*mii_read)(a_uint32_t reg); + void (*mii_write)(a_uint32_t reg, a_uint32_t val); + void (*phy_dbg_write)(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint16_t dbg_addr, a_uint16_t dbg_data); + void (*phy_mmd_write)(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint16_t addr, a_uint16_t data); + void (*phy_write)(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t data); + + bool init; + struct mutex reg_mutex; + struct mutex mib_lock; + struct delayed_work mib_dwork; + u64 *mib_counters; + /* dump buf */ + a_uint8_t buf[2048]; + + /* VLAN database */ + bool vlan; /* True: 1q vlan mode, False: port vlan mode */ + a_uint16_t vlan_id[AR8327_MAX_VLANS]; + a_uint8_t vlan_table[AR8327_MAX_VLANS]; + a_uint8_t vlan_tagged; + a_uint16_t pvid[AR8327_NUM_PORTS]; + +}; + + +#define qca_phy_priv_get(_dev) \ + container_of(_dev, struct qca_phy_priv, sw_dev) + +static int +miibus_get(void); +uint32_t +qca_ar8216_mii_read(int reg); +void +qca_ar8216_mii_write(int reg, uint32_t val); +static sw_error_t +qca_ar8327_phy_write(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t data); +static void +qca_ar8327_mmd_write(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint16_t addr, a_uint16_t data); +static void +qca_ar8327_phy_dbg_write(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint16_t dbg_addr, a_uint16_t dbg_data); +#endif diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/ref/ref_api.h b/feeds/ipq807x/qca-ssdk-shell/src/include/ref/ref_api.h new file mode 100755 index 000000000..ec7b557b1 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/ref/ref_api.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _REF_API_H_ +#define _REF_API_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef IN_VLAN +#define REF_VLAN_API \ + SW_API_DEF(SW_API_LAN_WAN_CFG_SET, qca_lan_wan_cfg_set), \ + SW_API_DEF(SW_API_LAN_WAN_CFG_GET, qca_lan_wan_cfg_get), + +#define REF_VLAN_API_PARAM \ + SW_API_DESC(SW_API_LAN_WAN_CFG_SET) \ + SW_API_DESC(SW_API_LAN_WAN_CFG_GET) + +#else +#define REF_VLAN_API +#define REF_VLAN_API_PARAM +#endif + +#define SSDK_REF_API \ + REF_VLAN_API + +#define SSDK_REF_PARAM \ + REF_VLAN_API_PARAM + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _REF_API_H_ */ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/ref/ref_vlan.h b/feeds/ipq807x/qca-ssdk-shell/src/include/ref/ref_vlan.h new file mode 100755 index 000000000..d8e124ba5 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/ref/ref_vlan.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/** + * @defgroup ref_vlan REF_VLAN + * @{ + */ +#ifndef _REF_VLAN_H +#define _REF_VLAN_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" +#include "fal_type.h" + +typedef struct { + fal_port_t port_id; /* port id */ + a_uint32_t vid; /* vlan id */ + a_bool_t is_wan_port; /* belong to wan port */ + a_bool_t valid; /* valid or not */ +} qca_lan_wan_port_info; + +typedef struct { + a_bool_t lan_only_mode; + qca_lan_wan_port_info v_port_info[SW_MAX_NR_PORT]; +} qca_lan_wan_cfg_t; + +sw_error_t +qca_lan_wan_cfg_set(a_uint32_t dev_id, qca_lan_wan_cfg_t *lan_wan_cfg); + +sw_error_t +qca_lan_wan_cfg_get(a_uint32_t dev_id, qca_lan_wan_cfg_t *lan_wan_cfg); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _REF_VLAN_H */ +/** + * @} + */ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/aos_lock.h b/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/aos_lock.h new file mode 100755 index 000000000..d09f012f4 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/aos_lock.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _AOS_LOCK_H +#define _AOS_LOCK_H + + +#ifdef KERNEL_MODULE +#include "sal/os/linux/aos_lock_pvt.h" +#else +#include "sal/os/linux_user/aos_lock_pvt.h" +#endif + + +typedef aos_lock_pvt_t aos_lock_t; + + +#define aos_lock_init(lock) __aos_lock_init(lock) + + +#define aos_lock(lock) __aos_lock(lock) + + +#define aos_unlock(lock) __aos_unlock(lock) + + +#define aos_irq_save(flags) __aos_irq_save(flags) + + +#define aos_irq_restore(flags) __aos_irq_restore(flags) + + +#define aos_default_unlock __aos_default_unlock + + +#endif diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/aos_mem.h b/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/aos_mem.h new file mode 100755 index 000000000..0006bbc52 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/aos_mem.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2014,2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _AOS_MEM_H +#define _AOS_MEM_H + +#include "aos_types.h" +#ifdef KERNEL_MODULE +#include "aos_mem_pvt.h" +#else +#include "aos_mem_pvt.h" +#endif + +/** + * @g aos_mem mem + * @{ + * + * @ig shim_ext + */ + +/** + * @brief Allocate a memory buffer. Note it's a non-blocking call. + * This call can block. + * + * @param[in] size buffer size + * + * @return Buffer pointer or NULL if there's not enough memory. + */ +static inline void * +aos_mem_alloc(aos_size_t size) +{ + return __aos_mem_alloc(size); +} + +/** + * @brief Free malloc'ed buffer + * + * @param[in] buf buffer pointer allocated by aos_alloc() + * @param[in] size buffer size + */ +static inline void +aos_mem_free(void *buf) +{ + __aos_mem_free(buf); +} + +/** + * @brief Move a memory buffer + * + * @param[in] dst destination address + * @param[in] src source address + * @param[in] size buffer size + */ +static inline void +aos_mem_copy(void *dst, void *src, aos_size_t size) +{ + __aos_mem_copy(dst, src, size); +} + +/** + * @brief Fill a memory buffer + * + * @param[in] buf buffer to be filled + * @param[in] b byte to fill + * @param[in] size buffer size + */ +static inline void +aos_mem_set(void *buf, a_uint8_t b, aos_size_t size) +{ + __aos_mem_set(buf, b, size); +} + +/** + * @brief Zero a memory buffer + * + * @param[in] buf buffer to be zeroed + * @param[in] size buffer size + */ +static inline void +aos_mem_zero(void *buf, aos_size_t size) +{ + __aos_mem_zero(buf, size); +} + +/** + * @brief Compare two memory buffers + * + * @param[in] buf1 first buffer + * @param[in] buf2 second buffer + * @param[in] size buffer size + * + * @retval 0 equal + * @retval 1 not equal + */ +static inline int +aos_mem_cmp(void *buf1, void *buf2, aos_size_t size) +{ + return __aos_mem_cmp(buf1, buf2, size); +} + +/** + * @} + */ + +#endif diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/aos_timer.h b/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/aos_timer.h new file mode 100755 index 000000000..81aa0bf07 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/aos_timer.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +#ifndef _AOS_TIMER_H +#define _AOS_TIMER_H + +#include "sal/os/aos_types.h" +#ifdef KERNEL_MODULE +#include "sal/os/linux/aos_timer_pvt.h" +#else +#include "sal/os/linux_user/aos_timer_pvt.h" +#endif + + +typedef __aos_timer_t aos_timer_t; + + +/* + * Delay in microseconds + */ +static inline void +aos_udelay(int usecs) +{ + return __aos_udelay(usecs); +} + +/* + * Delay in milliseconds. + */ +static inline void +aos_mdelay(int msecs) +{ + return __aos_mdelay(msecs); +} + + +#endif + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/aos_types.h b/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/aos_types.h new file mode 100755 index 000000000..a80e5d057 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/aos_types.h @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2014,2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _AOS_TYPES_H +#define _AOS_TYPES_H + +#ifdef KERNEL_MODULE +#include "aos_types_pvt.h" +#else +#include "aos_types_pvt.h" +#endif + +#ifndef NULL +#define NULL 0 +#endif + +/** + * @g aos_types types + * @{ + * + * @ig shim_ext + */ +/* + *@ basic data types. + */ +typedef enum +{ + A_FALSE, + A_TRUE +} a_bool_t; + +typedef __a_uint8_t a_uint8_t; +typedef __a_int8_t a_int8_t; +typedef __a_uint16_t a_uint16_t; +typedef __a_int16_t a_int16_t; +typedef __a_uint32_t a_uint32_t; +typedef __a_int32_t a_int32_t; +typedef __a_uint64_t a_uint64_t; +typedef __a_int64_t a_int64_t; +typedef unsigned long a_ulong_t; +typedef char a_char_t; + +typedef void * acore_t; + +/** + * @brief Platform/bus generic handle. Used for bus specific functions. + */ +typedef __aos_device_t aos_device_t; + +/** + * @brief size of an object + */ +typedef __aos_size_t aos_size_t; + +/** + * @brief Generic status to be used by acore. + */ +typedef enum +{ + A_STATUS_OK, + A_STATUS_FAILED, + A_STATUS_ENOENT, + A_STATUS_ENOMEM, + A_STATUS_EINVAL, + A_STATUS_EINPROGRESS, + A_STATUS_ENOTSUPP, + A_STATUS_EBUSY, +} a_status_t; + +/* + * An ecore needs to provide a table of all pci device/vendor id's it + * supports + * + * This table should be terminated by a NULL entry , i.e. {0} + */ +typedef struct +{ + a_uint32_t vendor; + a_uint32_t device; + a_uint32_t subvendor; + a_uint32_t subdevice; +} aos_pci_dev_id_t; + +#define AOS_PCI_ANY_ID (~0) + +/* + * Typically core's can use this macro to create a table of various device + * ID's + */ +#define AOS_PCI_DEVICE(_vendor, _device) \ + (_vendor), (_device), AOS_PCI_ANY_ID, AOS_PCI_ANY_ID + + +typedef __aos_iomem_t aos_iomem_t; +/* + * These define the hw resources the OS has allocated for the device + * Note that start defines a mapped area. + */ +typedef enum +{ + AOS_RESOURCE_TYPE_MEM, + AOS_RESOURCE_TYPE_IO, +} aos_resource_type_t; + +typedef struct +{ + a_uint32_t start; + a_uint32_t end; + aos_resource_type_t type; +} aos_resource_t; + +#define AOS_DEV_ID_TABLE_MAX 256 + +typedef union +{ + aos_pci_dev_id_t *pci; + void *raw; +} aos_bus_reg_data_t; + +typedef void *aos_attach_data_t; + +#define AOS_REGIONS_MAX 5 + +typedef enum +{ + AOS_BUS_TYPE_PCI = 1, + AOS_BUS_TYPE_GENERIC, +} aos_bus_type_t; + +typedef enum +{ + AOS_IRQ_NONE, + AOS_IRQ_HANDLED, +} aos_irq_resp_t; + +typedef enum +{ + AOS_DMA_MASK_32BIT, + AOS_DMA_MASK_64BIT, +} aos_dma_mask_t; + + +/** + * @brief DMA directions + */ +typedef enum +{ + AOS_DMA_TO_DEVICE = 0, /**< Data is transfered from device to memory */ + AOS_DMA_FROM_DEVICE, /**< Data is transfered from memory to device */ +} aos_dma_dir_t; + +/* + * Protoypes shared between public and private headers + */ + + +/* + * work queue(kernel thread) function callback + */ +typedef void (*aos_work_func_t)(void *); + +/** + * @brief Prototype of the critical region function that is to be + * executed with spinlock held and interrupt disalbed + */ +typedef a_bool_t (*aos_irqlocked_func_t)(void *); + +/** + * @brief Prototype of timer function + */ +typedef void (*aos_timer_func_t)(void *); + +#endif diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/linux_user/aos_lock_pvt.h b/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/linux_user/aos_lock_pvt.h new file mode 100755 index 000000000..a8894761f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/linux_user/aos_lock_pvt.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _AOS_LOCK_PVT_H +#define _AOS_LOCK_PVT_H + +#include +#include "sal/os/aos_types.h" + + +typedef pthread_mutex_t aos_lock_pvt_t; + + +#define __aos_lock_init(lock) \ + pthread_mutex_init(lock, NULL); \ + pthread_mutexattr_setpshared(lock, PTHREAD_PROCESS_SHARED) + + +#define __aos_lock(lock) pthread_mutex_lock(lock) + + +#define __aos_unlock(lock) pthread_mutex_unlock(lock) + + +#define __aos_irq_save(flags) + + +#define __aos_irq_restore(flags) + + +#define __aos_default_unlock PTHREAD_MUTEX_INITIALIZER + + +#endif /*_AOS_LOCK_PVT_H*/ + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/linux_user/aos_mem_pvt.h b/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/linux_user/aos_mem_pvt.h new file mode 100755 index 000000000..281e65dab --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/linux_user/aos_mem_pvt.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _AOS_MEM_PVT_H +#define _AOS_MEM_PVT_H + +#include +#include + +static inline void *__aos_mem_alloc(aos_size_t size) +{ + return (malloc(size)); +} + +static inline void __aos_mem_free(void *buf) +{ + free(buf); +} + +/* move a memory buffer */ +static inline void +__aos_mem_copy(void *dst, void *src, aos_size_t size) +{ + memcpy(dst, src, size); +} + +/* set a memory buffer */ +static inline void +__aos_mem_set(void *buf, a_uint8_t b, aos_size_t size) +{ + memset(buf, b, size); +} + +/* zero a memory buffer */ +static inline void +__aos_mem_zero(void *buf, aos_size_t size) +{ + memset(buf, 0, size); +} + +/* compare two memory buffers */ +static inline int +__aos_mem_cmp(void *buf1, void *buf2, aos_size_t size) +{ + return (memcmp(buf1, buf2, size) == 0) ? 0 : 1; +} + + + +#endif /*_AOS_MEM_PVT_H*/ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/linux_user/aos_timer_pvt.h b/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/linux_user/aos_timer_pvt.h new file mode 100755 index 000000000..58055eb71 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/linux_user/aos_timer_pvt.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _AOS_TIMER_PVT_H +#define _AOS_TIMER_PVT_H + +#include + +typedef int __aos_timer_t; + +static inline void +__aos_udelay(int usecs) +{ + usleep(usecs); + return; +} + +static inline void +__aos_mdelay(int msecs) +{ + usleep(1000*msecs); + return; +} + +#endif /*_AOS_TIMER_PVT_H*/ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/linux_user/aos_types_pvt.h b/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/linux_user/aos_types_pvt.h new file mode 100755 index 000000000..fc71a871f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/sal/os/linux_user/aos_types_pvt.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _AOS_PVTTYPES_H +#define _AOS_PVTTYPES_H + +#include +#include +/* + * Private definitions of general data types + */ + +typedef void* __aos_device_t; +typedef int __aos_size_t; +typedef int __aos_iomem_t; + +typedef __u8 __a_uint8_t; +typedef __s8 __a_int8_t; +typedef __u16 __a_uint16_t; +typedef __s16 __a_int16_t; +typedef __u32 __a_uint32_t; +typedef __s32 __a_int32_t; +typedef __u64 __a_uint64_t; +typedef __s64 __a_int64_t; + + +#define aos_printk printf + + +#endif diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/sal/sd/linux/uk_interface/sw_api_us.h b/feeds/ipq807x/qca-ssdk-shell/src/include/sal/sd/linux/uk_interface/sw_api_us.h new file mode 100755 index 000000000..d589d59fd --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/sal/sd/linux/uk_interface/sw_api_us.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014, 2017-2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#ifndef _SW_API_US_H +#define _SW_API_US_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "sw.h" + + sw_error_t sw_uk_init(a_uint32_t nl_prot); + + sw_error_t sw_uk_cleanup(void); + + sw_error_t sw_uk_if(unsigned long arg_val[SW_MAX_API_PARAM]); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SW_API_INTERFACE_H */ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/sal/sd/sd.h b/feeds/ipq807x/qca-ssdk-shell/src/include/sal/sd/sd.h new file mode 100755 index 000000000..7187f482a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/sal/sd/sd.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#ifndef _SD_H_ +#define _SD_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + sw_error_t + sd_reg_mdio_set(a_uint32_t dev_id, a_uint32_t phy, a_uint32_t reg, + a_uint16_t data); + + sw_error_t + sd_reg_mdio_get(a_uint32_t dev_id, a_uint32_t phy, a_uint32_t reg, + a_uint16_t * data); + + sw_error_t + sd_reg_hdr_set(a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint8_t * reg_data, a_uint32_t len); + + sw_error_t + sd_reg_hdr_get(a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint8_t * reg_data, a_uint32_t len); + sw_error_t + sd_reg_uniphy_set(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t reg_addr, a_uint8_t * reg_data, a_uint32_t len); + + sw_error_t + sd_reg_uniphy_get(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t reg_addr, a_uint8_t * reg_data, a_uint32_t len); + + void + sd_reg_mii_set(a_uint32_t reg, a_uint32_t val); + + a_uint32_t + sd_reg_mii_get(a_uint32_t reg); + + sw_error_t sd_init(a_uint32_t dev_id, ssdk_init_cfg * cfg); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _SD_H_ */ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/shell/shell.h b/feeds/ipq807x/qca-ssdk-shell/src/include/shell/shell.h new file mode 100755 index 000000000..1575e1b9b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/shell/shell.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _SW_SHELL_H +#define _SW_SHELL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sw.h" +#include "sw_api.h" +#include "ssdk_init.h" + + extern a_ulong_t *ioctl_buf; + extern ssdk_init_cfg init_cfg; + extern ssdk_cfg_t ssdk_cfg; + +#define IOCTL_BUF_SIZE 2048 +#define CMDSTR_BUF_SIZE 1024 +#define CMDSTR_ARGS_MAX 128 +#define dprintf cmd_print + extern sw_error_t cmd_exec_api(a_ulong_t *arg_val); + extern void cmd_print(char *fmt, ...); + void cmd_print_error(sw_error_t rtn); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SW_SHELL_H */ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/shell/shell_config.h b/feeds/ipq807x/qca-ssdk-shell/src/include/shell/shell_config.h new file mode 100755 index 000000000..8ddab7b68 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/shell/shell_config.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _SHELL_CONFIG_H_ +#define _SHELL_CONFIG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sw.h" +#include "sw_ioctl.h" +#include "sw_api.h" + +#define SW_CMD_SET_DEVID (SW_API_MAX + 1) +#define SW_CMD_VLAN_SHOW (SW_API_MAX + 2) +#define SW_CMD_FDB_SHOW (SW_API_MAX + 3) +#define SW_CMD_RESV_FDB_SHOW (SW_API_MAX + 4) +#define SW_CMD_HOST_SHOW (SW_API_MAX + 5) +#define SW_CMD_NAT_SHOW (SW_API_MAX + 6) +#define SW_CMD_NAPT_SHOW (SW_API_MAX + 7) +#define SW_CMD_INTFMAC_SHOW (SW_API_MAX + 8) +#define SW_CMD_PUBADDR_SHOW (SW_API_MAX + 9) +#define SW_CMD_FLOW_SHOW (SW_API_MAX + 10) +#define SW_CMD_HOST_IPV4_SHOW (SW_API_MAX + 11) +#define SW_CMD_HOST_IPV6_SHOW (SW_API_MAX + 12) +#define SW_CMD_HOST_IPV4M_SHOW (SW_API_MAX + 13) +#define SW_CMD_HOST_IPV6M_SHOW (SW_API_MAX + 14) +#define SW_CMD_CTRLPKT_SHOW (SW_API_MAX + 15) +#define SW_CMD_FLOW_IPV43T_SHOW (SW_API_MAX + 16) +#define SW_CMD_FLOW_IPV63T_SHOW (SW_API_MAX + 17) +#define SW_CMD_FLOW_IPV45T_SHOW (SW_API_MAX + 18) +#define SW_CMD_FLOW_IPV65T_SHOW (SW_API_MAX + 19) +#define SW_CMD_PT_VLAN_TRANS_ADV_SHOW (SW_API_MAX + 20) +#define SW_CMD_MAX (SW_API_MAX + 21) + +#define MAX_SUB_CMD_DES_NUM 120 + +#define SW_API_INVALID 0 + + struct sub_cmd_des_t + { + char *sub_name; + char *sub_act; + char *sub_memo; + char *sub_usage; + int sub_api; + sw_error_t (*sub_func) (); + }; + struct cmd_des_t + { + char *name; + char *memo; + struct sub_cmd_des_t sub_cmd_des[MAX_SUB_CMD_DES_NUM]; + }; + extern struct cmd_des_t gcmd_des[]; + +#define GCMD_DES gcmd_des + +#define GCMD_NAME(cmd_nr) GCMD_DES[cmd_nr].name +#define GCMD_MEMO(cmd_nr) GCMD_DES[cmd_nr].memo + +#define GCMD_SUB_NAME(cmd_nr, sub_cmd_nr) GCMD_DES[cmd_nr].sub_cmd_des[sub_cmd_nr].sub_name +#define GCMD_SUB_ACT(cmd_nr, sub_cmd_nr) GCMD_DES[cmd_nr].sub_cmd_des[sub_cmd_nr].sub_act +#define GCMD_SUB_MEMO(cmd_nr, sub_cmd_nr) GCMD_DES[cmd_nr].sub_cmd_des[sub_cmd_nr].sub_memo +#define GCMD_SUB_USAGE(cmd_nr, sub_cmd_nr) GCMD_DES[cmd_nr].sub_cmd_des[sub_cmd_nr].sub_usage +#define GCMD_SUB_API(cmd_nr, sub_cmd_nr) GCMD_DES[cmd_nr].sub_cmd_des[sub_cmd_nr].sub_api +#define GCMD_SUB_FUNC(cmd_nr, sub_cmd_nr) GCMD_DES[cmd_nr].sub_cmd_des[sub_cmd_nr].sub_func + +#define GCMD_DESC_VALID(cmd_nr) GCMD_NAME(cmd_nr) +#define GCMD_SUB_DESC_VALID(cmd_nr, sub_cmd_nr) GCMD_SUB_API(cmd_nr, sub_cmd_nr) + + +#define GCMD_DESC_NO_MATCH 0xffffffff + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SHELL_CONFIG_H_ */ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/shell/shell_io.h b/feeds/ipq807x/qca-ssdk-shell/src/include/shell/shell_io.h new file mode 100755 index 000000000..2121db881 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/shell/shell_io.h @@ -0,0 +1,1039 @@ +/* + * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/*qca808x_start*/ +#ifndef _SHELL_IO_H +#define _SHELL_IO_H + +#include "sw.h" +#include "sw_api.h" +#include "fal.h" +/*qca808x_end*/ +#include "ref_vlan.h" + +/*qca808x_start*/ +#define SW_TYPE_DEF(type, parser, show) {type, parser, show} +typedef struct +{ + sw_data_type_e data_type; + sw_error_t(*param_check) (); + void (*show_func) (); +} sw_data_type_t; + +void set_talk_mode(int mode); +int get_talk_mode(void); +void set_full_cmdstrp(char **cmdstrp); +int +get_jump(void); +sw_data_type_t * cmd_data_type_find(sw_data_type_e type); +void cmd_strtol(char *str, a_uint32_t * arg_val); + +sw_error_t __cmd_data_check_complex(char *info, char *defval, char *usage, + sw_error_t(*chk_func)(), void *arg_val, + a_uint32_t size); + +sw_error_t cmd_data_check_portid(char *cmdstr, fal_port_t * val, a_uint32_t size); + +sw_error_t cmd_data_check_portmap(char *cmdstr, fal_pbmp_t * val, a_uint32_t size); +sw_error_t cmd_data_check_confirm(char *cmdstr, a_bool_t def, a_bool_t * val, a_uint32_t size); + +sw_error_t cmd_data_check_uint64(char *cmd_str, a_uint64_t * arg_val, + a_uint32_t size); +sw_error_t cmd_data_check_uint32(char *cmd_str, a_uint32_t * arg_val, + a_uint32_t size); +sw_error_t cmd_data_check_uint16(char *cmd_str, a_uint32_t * arg_val, + a_uint32_t size); +sw_error_t cmd_data_check_uint8(char *cmd_str, a_uint32_t * arg_val, + a_uint32_t size); +sw_error_t cmd_data_check_enable(char *cmd_str, a_uint32_t * arg_val, + a_uint32_t size); +sw_error_t cmd_data_check_pbmp(char *cmd_str, a_uint32_t * arg_val, + a_uint32_t size); +sw_error_t cmd_data_check_duplex(char *cmd_str, a_uint32_t * arg_val, + a_uint32_t size); +sw_error_t cmd_data_check_speed(char *cmd_str, a_uint32_t * arg_val, + a_uint32_t size); +/*qca808x_end*/ +sw_error_t cmd_data_check_1qmode(char *cmd_str, a_uint32_t * arg_val, + a_uint32_t size); +sw_error_t cmd_data_check_egmode(char *cmd_str, a_uint32_t * arg_val, + a_uint32_t size); +/*qca808x_start*/ +sw_error_t cmd_data_check_capable(char *cmd_str, a_uint32_t * arg_val, + a_uint32_t size); +/*qca808x_end*/ +sw_error_t cmd_data_check_fdbentry(char *cmdstr, void *val, a_uint32_t size); +sw_error_t cmd_data_check_maclimit_ctrl(char *cmdstr, void *val, a_uint32_t size); +/*qca808x_start*/ +sw_error_t cmd_data_check_macaddr(char *cmdstr, void *val, a_uint32_t size); + +void cmd_data_print_uint64(a_uint8_t * param_name, a_uint64_t * buf, + a_uint32_t size); +void cmd_data_print_uint32(a_char_t * param_name, a_uint32_t * buf, + a_uint32_t size); +void cmd_data_print_uint16(a_char_t * param_name, a_uint32_t * buf, + a_uint32_t size); +void cmd_data_print_uint8(a_uint8_t * param_name, a_uint32_t * buf, + a_uint32_t size); +void cmd_data_print_enable(a_char_t * param_name, a_uint32_t * buf, + a_uint32_t size); +void cmd_data_print_pbmp(a_uint8_t * param_name, a_uint32_t * buf, + a_uint32_t size); +void cmd_data_print_duplex(a_uint8_t * param_name, a_uint32_t * buf, + a_uint32_t size); +void cmd_data_print_speed(a_uint8_t * param_name, a_uint32_t * buf, + a_uint32_t size); +/*qca808x_end*/ +sw_error_t cmd_data_check_vlan(char *cmdstr, fal_vlan_t * val, a_uint32_t size); +void cmd_data_print_vlan(a_uint8_t * param_name, a_uint32_t * buf, + a_uint32_t size); +sw_error_t cmd_data_check_lan_wan_cfg(char *cmd_str, void *arg_val, a_uint32_t size); + +void cmd_data_print_lan_wan_cfg(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size); + +void cmd_data_print_mib(a_uint8_t * param_name, a_uint32_t * buf, + a_uint32_t size); +void cmd_data_print_mib_cntr(a_uint8_t * param_name, a_uint64_t * buf, + a_uint32_t size); +void cmd_data_print_xgmib(a_uint8_t * param_name, a_uint64_t * buf, + a_uint64_t size); +void cmd_data_print_1qmode(a_uint8_t * param_name, a_uint32_t * buf, + a_uint32_t size); +void cmd_data_print_egmode(a_char_t * param_name, a_uint32_t * buf, + a_uint32_t size); +/*qca808x_start*/ +void cmd_data_print_capable(a_uint8_t * param_name, a_uint32_t * buf, + a_uint32_t size); +/*qca808x_end*/ +void cmd_data_print_maclimit_ctrl(a_uint8_t * param_name, a_uint32_t * buf, + a_uint32_t size); +/*qca808x_start*/ +void cmd_data_print_macaddr(a_char_t * param_name, a_uint32_t * buf, + a_uint32_t size); +/*qca808x_end*/ +sw_error_t cmd_data_check_qos_sch(char *cmdstr, fal_sch_mode_t * val, + a_uint32_t size); +void cmd_data_print_qos_sch(a_uint8_t * param_name, a_uint32_t * buf, + a_uint32_t size); +sw_error_t cmd_data_check_qos_pt(char *cmdstr, fal_qos_mode_t * val, + a_uint32_t size); +void cmd_data_print_qos_pt(a_uint8_t * param_name, a_uint32_t * buf, + a_uint32_t size); +sw_error_t cmd_data_check_storm(char *cmdstr, fal_storm_type_t * val, + a_uint32_t size); +void cmd_data_print_storm(a_uint8_t * param_name, a_uint32_t * buf, + a_uint32_t size); +sw_error_t cmd_data_check_stp_state(char *cmdstr, fal_stp_state_t * val, + a_uint32_t size); +void cmd_data_print_stp_state(a_uint8_t * param_name, a_uint32_t * buf, + a_uint32_t size); +sw_error_t cmd_data_check_leaky(char *cmdstr, fal_leaky_ctrl_mode_t * val, + a_uint32_t size); +void cmd_data_print_leaky(a_uint8_t * param_name, a_uint32_t * buf, + a_uint32_t size); + +sw_error_t cmd_data_check_uinta(char *cmdstr, a_uint32_t * val, + a_uint32_t size); +void cmd_data_print_uinta(a_uint8_t * param_name, a_uint32_t * buf, + a_uint32_t size); +sw_error_t cmd_data_check_maccmd(char *cmdstr, fal_fwd_cmd_t * val, + a_uint32_t size); +void cmd_data_print_maccmd(a_char_t * param_name, a_uint32_t * buf, + a_uint32_t size); +sw_error_t cmd_data_check_flowcmd(char *cmdstr, fal_default_flow_cmd_t * val, + a_uint32_t size); +void cmd_data_print_flowcmd(a_char_t *param_name, a_uint32_t * buf, + a_uint32_t size); +sw_error_t cmd_data_check_flowtype(char *cmdstr, fal_flow_type_t * val, + a_uint32_t size); +void cmd_data_print_flowtype(a_char_t *param_name, a_uint32_t * buf, + a_uint32_t size); +sw_error_t cmd_data_check_aclrule(char *info, void *val, a_uint32_t size); + +void cmd_data_print_aclrule(a_char_t * param_name, a_uint32_t * buf, + a_uint32_t size); + +sw_error_t +cmd_data_check_ledpattern(char *info, void * val, a_uint32_t size); + +void +cmd_data_print_ledpattern(a_uint8_t * param_name, a_uint32_t * buf, + a_uint32_t size); + +sw_error_t +cmd_data_check_mirr_analy_cfg(char *info, void *val, a_uint32_t size); +void +cmd_data_print_mirr_analy_cfg(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); +sw_error_t +cmd_data_check_mirr_direction(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); +void +cmd_data_print_mirr_direction(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); +sw_error_t +cmd_data_check_invlan_mode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); +void +cmd_data_print_invlan_mode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); +sw_error_t +cmd_data_check_vlan_propagation(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); +void +cmd_data_print_vlan_propagation(a_char_t * param_name, a_uint32_t * buf, a_uint32_t size); +sw_error_t +cmd_data_check_vlan_translation(char *info, fal_vlan_trans_entry_t *val, a_uint32_t size); +void +cmd_data_print_vlan_translation(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); +sw_error_t +cmd_data_check_qinq_mode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); +void +cmd_data_print_qinq_mode(a_char_t * param_name, a_uint32_t * buf, a_uint32_t size); +sw_error_t +cmd_data_check_qinq_role(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); +void +cmd_data_print_qinq_role(a_char_t * param_name, a_uint32_t * buf, a_uint32_t size); +/*qca808x_start*/ +void +cmd_data_print_cable_status(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); +void +cmd_data_print_cable_len(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); +void +cmd_data_print_ssdk_cfg(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); +/*qca808x_end*/ +sw_error_t +cmd_data_check_hdrmode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); + +void +cmd_data_print_hdrmode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_fdboperation(char *cmd_str, void * val, a_uint32_t size); + +sw_error_t +cmd_data_check_pppoe(char *cmd_str, void * val, a_uint32_t size); + +sw_error_t +cmd_data_check_pppoe_less(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_pppoe(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_udf_type(char *cmdstr, fal_acl_udf_type_t * arg_val, a_uint32_t size); + +void +cmd_data_print_udf_type(a_char_t * param_name, a_uint32_t * buf, + a_uint32_t size); + +sw_error_t +cmd_data_check_udf_pkt_type(a_char_t *cmdstr, fal_acl_udf_pkt_type_t * arg_val, a_uint32_t size); + +void +cmd_data_print_udf_pkt_type(a_char_t * param_name, a_uint32_t * buf, + a_uint32_t size); + +sw_error_t +cmd_data_check_host_entry(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_host_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_arp_learn_mode(char *cmd_str, fal_arp_learn_mode_t * arg_val, + a_uint32_t size); + +void +cmd_data_print_arp_learn_mode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ip_guard_mode(char *cmd_str, fal_source_guard_mode_t * arg_val, a_uint32_t size); + +void +cmd_data_print_ip_guard_mode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_nat_entry(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_nat_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_napt_entry(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_napt_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_flow_entry(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_flow_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_napt_mode(char *cmd_str, fal_napt_mode_t * arg_val, a_uint32_t size); + +void +cmd_data_print_napt_mode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_intf_mac_entry(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_intf_mac_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ip4addr(char *cmdstr, void * val, a_uint32_t size); + +void +cmd_data_print_ip4addr(a_char_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ip6addr(char *cmdstr, void * val, a_uint32_t size); + +void +cmd_data_print_ip6addr(a_char_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_pub_addr_entry(char *cmd_str, void * val, a_uint32_t size); + + +void +cmd_data_print_pub_addr_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + + +sw_error_t +cmd_data_check_egress_shaper(char *cmd_str, void * val, a_uint32_t size); + + +void +cmd_data_print_egress_shaper(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + + +sw_error_t +cmd_data_check_acl_policer(char *cmd_str, void * val, a_uint32_t size); + + +void +cmd_data_print_acl_policer(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + + +sw_error_t +cmd_data_check_port_policer(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_port_policer(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_mac_config(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_mac_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); +sw_error_t +cmd_data_check_phy_config(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_phy_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +void cmd_data_print_fdbentry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_fdb_smode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); + +void +cmd_data_print_fdb_smode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +void +cmd_data_print_fdb_ctrl_mode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); +sw_error_t +cmd_data_check_fx100_config(char *cmd_str, void * arg_val, a_uint32_t size); + +void +cmd_data_print_fx100_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_multi(char *info, void *val, a_uint32_t size); +void +cmd_data_print_multi(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_sec_mac(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); + +sw_error_t +cmd_data_check_sec_ip(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); + +sw_error_t +cmd_data_check_sec_ip4(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); + +sw_error_t +cmd_data_check_sec_ip6(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); + +sw_error_t +cmd_data_check_sec_tcp(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); + +sw_error_t +cmd_data_check_sec_udp(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); + +sw_error_t +cmd_data_check_sec_icmp4(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); + +sw_error_t +cmd_data_check_sec_icmp6(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); + +sw_error_t +cmd_data_check_remark_entry(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_remark_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_default_route_entry(char *cmd_str, void * val, a_uint32_t size); + +sw_error_t +cmd_data_check_u_qmap(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_default_route_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_host_route_entry(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_host_route_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_arp_sg(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_arp_sg(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_intf(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_intf(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_flow_age(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_flow_age(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_flow_ctrl(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_flow_ctrl(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ac_static_thresh(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_ac_static_thresh(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ac_dynamic_thresh(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_ac_dynamic_thresh(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ac_group_buff(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_ac_group_buff(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ac_ctrl(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_ac_ctrl(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ac_obj(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_ac_obj(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_vsi_intf(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_vsi_intf(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ip_pub(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_ip_pub(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ip_mcmode(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_ip_mcmode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ip_portmac(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_ip_portmac(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ip_sg(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_ip_sg(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_nexthop(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_nexthop(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_network_route(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_network_route(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ip_wcmp_entry(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_ip_wcmp_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ip4_rfs_entry(char *cmd_str, void * val, a_uint32_t size); +sw_error_t +cmd_data_check_ip6_rfs_entry(char *cmd_str, void * val, a_uint32_t size); +sw_error_t +cmd_data_check_flow_age_entry(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_flow_age_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); +sw_error_t +cmd_data_check_flow_ctrl_entry(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_flow_ctrl_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_flow(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_flow(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_flow_host(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_flow_host(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ip_global(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_ip_global(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_flow_global(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_flow_global(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_l3_parser(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_l3_parser(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_l4_parser(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_l4_parser(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_exp_ctrl(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_exp_ctrl(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_port_group(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_port_group(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_port_pri(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_port_pri(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_port_remark(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_port_remark(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_cosmap(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_cosmap(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_queue_scheduler(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_queue_scheduler(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ring_queue(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_ring_queue(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_bm_static_thresh(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_bm_static_thresh(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +void +cmd_data_print_queue_cnt(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_bm_dynamic_thresh(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_bm_dynamic_thresh(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +void +cmd_data_print_bm_port_counter(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_flow_cookie(char *cmd_str, void * val, a_uint32_t size); + +sw_error_t +cmd_data_check_fdb_rfs(char *cmd_str, void * val, a_uint32_t size); +sw_error_t +cmd_data_check_flow_rfs(char *cmd_str, void * val, a_uint32_t size); +/*qca808x_start*/ +sw_error_t +cmd_data_check_crossover_mode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); + +sw_error_t +cmd_data_check_crossover_status(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); +/*qca808x_end*/ +sw_error_t +cmd_data_check_prefer_medium(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); + +sw_error_t +cmd_data_check_fiber_mode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); +/*qca808x_start*/ +sw_error_t +cmd_data_check_interface_mode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); +/*qca808x_end*/ +sw_error_t +cmd_data_check_port_eee_config(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_port_eee_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); +sw_error_t +cmd_data_check_src_filter_config(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); + +void +cmd_data_print_src_filter_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_switch_port_loopback_config(char *cmd_str, void * val, + a_uint32_t size); +void +cmd_data_print_switch_port_loopback_config(a_uint8_t * param_name, + a_uint32_t * buf, a_uint32_t size); +sw_error_t +cmd_data_check_newadr_lrn(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_newaddr_lrn_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_stamove(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_stamove_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_vsi_member(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_vsi_member_entry(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +void +cmd_data_print_vsi_counter(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_mtu_entry(char *cmd_str, void * val, a_uint32_t size); + +sw_error_t +cmd_data_check_mru_entry(char *cmd_str, void * val, a_uint32_t size); +/*qca808x_start*/ +void +cmd_data_print_crossover_mode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +void +cmd_data_print_crossover_status(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); +/*qca808x_end*/ + +void +cmd_data_print_prefer_medium(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +void +cmd_data_print_fiber_mode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); +/*qca808x_start*/ + +void +cmd_data_print_interface_mode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +void +cmd_data_print_counter_info(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +void +cmd_data_print_register_info(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +void +cmd_data_print_phy_register_info(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +void +cmd_data_print_debug_register_info(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); +/*qca808x_end*/ + +void +cmd_data_print_mtu_info(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +void +cmd_data_print_mru_info(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_global_qinqmode(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_global_qinqmode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_port_qinqmode(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_port_qinqmode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_tpid(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_tpid(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ingress_filter(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_ingress_filter(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_port_default_vid_en(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_port_default_vid_en(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_port_vlan_tag(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_port_vlan_tag(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_port_vlan_direction(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); + +void +cmd_data_print_port_vlan_direction(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_port_vlan_translation_adv_rule(char *info, fal_vlan_trans_adv_rule_t *val, a_uint32_t size); + +void +cmd_data_print_port_vlan_translation_adv_rule(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_port_vlan_translation_adv_action(char *info, fal_vlan_trans_adv_action_t *val, a_uint32_t size); + +void +cmd_data_print_port_vlan_translation_adv_action(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +void +cmd_data_print_port_vlan_counter(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_tag_propagation(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_tag_propagation(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_egress_vsi_tag(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_egress_vsi_tag(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_egress_mode(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_egress_mode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ctrlpkt_profile(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_ctrlpkt_profile(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_servcode_config(char *info, fal_servcode_config_t *val, a_uint32_t size); + +void +cmd_data_print_servcode_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_rss_hash_mode(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); + +sw_error_t +cmd_data_check_rss_hash_config(char *info, fal_rss_hash_config_t *val, a_uint32_t size); + +void +cmd_data_print_rss_hash_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_port_policer_config(char *cmd_str, void * val, a_uint32_t size); + +sw_error_t +cmd_data_check_policer_cmd_config(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_port_policer_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +void +cmd_data_print_policer_cmd_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_acl_policer_config(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_acl_policer_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +void +cmd_data_print_policer_counter_infor(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +void +cmd_data_print_policer_global_counter_infor(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +void +cmd_data_print_port_scheduler_resource(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_port_shaper_token_config(char *cmd_str, void * val, a_uint32_t size); + +sw_error_t +cmd_data_check_shaper_token_config(char *cmd_str, void * val, a_uint32_t size); + +sw_error_t +cmd_data_check_port_shaper_config(char *cmd_str, void * val, a_uint32_t size); + +sw_error_t +cmd_data_check_shaper_config(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_port_shaper_token_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +void +cmd_data_print_shaper_token_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +void +cmd_data_print_port_shaper_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +void +cmd_data_print_shaper_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_module(char *cmd_str, a_uint32_t * arg_val, a_uint32_t size); + +void +cmd_data_print_module(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_func_ctrl(char *cmd_str, void * val, a_uint32_t size); + +void +cmd_data_print_func_ctrl(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +void +cmd_data_print_module_func_ctrl(a_uint32_t module, fal_func_ctrl_t *p); + +sw_error_t +cmd_data_check_debug_port_counter_status(char *info, fal_counter_en_t *val, a_uint32_t size); + +void +cmd_data_print_debug_port_counter_status(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ptp_config(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_ptp_config(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ptp_reference_clock(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_ptp_reference_clock(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ptp_rx_timestamp_mode(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_ptp_rx_timestamp_mode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ptp_direction(char *info, void *val, a_uint32_t size); + +sw_error_t +cmd_data_check_ptp_pkt_info(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_ptp_pkt_info(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ptp_time(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_ptp_time(a_char_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ptp_grandmaster_mode(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_ptp_grandmaster_mode(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ptp_security(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_ptp_security(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ptp_pps_sig_ctrl(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_ptp_pps_sig_ctrl(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ptp_asym_correction(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_ptp_asym_correction(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ptp_waveform(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_ptp_waveform(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ptp_tod_uart(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_ptp_tod_uart(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ptp_enhanced_timestamp_engine(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_ptp_enhanced_timestamp_engine(a_uint8_t * param_name, a_uint32_t * buf, + a_uint32_t size); + +sw_error_t +cmd_data_check_ptp_trigger(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_ptp_trigger(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ptp_capture(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_ptp_capture(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_ptp_interrupt(char *info, void *val, a_uint32_t size); + +void +cmd_data_print_ptp_interrupt(a_uint8_t * param_name, a_uint32_t * buf, a_uint32_t size); + +sw_error_t +cmd_data_check_sfp_ccode_type(char *cmdstr, fal_sfp_cc_type_t *arg_val, a_uint32_t size); + +sw_error_t +cmd_data_check_sfp_data(char *cmd_str, void *arg_val, a_uint32_t size); + +void +cmd_data_print_sfp_data(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size); + +void +cmd_data_print_sfp_dev_type(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size); + +void +cmd_data_print_sfp_transc_code(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size); + +void +cmd_data_print_sfp_rate_encode(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size); + +void +cmd_data_print_sfp_link_length(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size); + +void +cmd_data_print_sfp_vendor_info(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size); + +void +cmd_data_print_sfp_laser_wavelength(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size); + +void +cmd_data_print_sfp_option(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size); + +void +cmd_data_print_sfp_ctrl_rate(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size); + +void +cmd_data_print_sfp_enhanced_cfg(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size); + +void +cmd_data_print_sfp_diag_threshold(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size); + +void +cmd_data_print_sfp_diag_cal_const(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size); + +void +cmd_data_print_sfp_diag_realtime(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size); + +void +cmd_data_print_sfp_ctrl_status(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size); + +void +cmd_data_print_sfp_alarm_warn_flag(a_uint8_t *param_name, a_ulong_t *buf, a_uint32_t size); +/*qca808x_start*/ +#endif +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/shell/shell_lib.h b/feeds/ipq807x/qca-ssdk-shell/src/include/shell/shell_lib.h new file mode 100755 index 000000000..a6f824a97 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/shell/shell_lib.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _SW_SHELL_LIB_H +#define _SW_SHELL_LIB_H + +#ifdef __cplusplus +extern "C" { +#endif + + int next_cmd(char *out_cmd); + ssize_t getline(char **lineptr, size_t *n, FILE *stream); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _SW_SHELL_LIB_H */ + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/include/shell/shell_sw.h b/feeds/ipq807x/qca-ssdk-shell/src/include/shell/shell_sw.h new file mode 100755 index 000000000..6eaa9caef --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/include/shell/shell_sw.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2014, 2017-2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/*qca808x_start*/ +#ifndef _SHELL_SW_H_ +#define _SHELL_SW_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sw.h" + + int get_devid(void); + int set_devid(int dev_id); + sw_error_t cmd_set_devid(a_ulong_t *arg_val); +/*qca808x_end*/ + sw_error_t cmd_show_fdb(a_ulong_t *arg_val); + sw_error_t cmd_show_vlan(a_ulong_t *arg_val); + sw_error_t cmd_show_resv_fdb(a_ulong_t *arg_val); + sw_error_t cmd_show_host(a_ulong_t *arg_val); + sw_error_t cmd_show_host_ipv4(a_ulong_t *arg_val); + sw_error_t cmd_show_host_ipv6(a_ulong_t *arg_val); + sw_error_t cmd_show_host_ipv4M(a_ulong_t *arg_val); + sw_error_t cmd_show_host_ipv6M(a_ulong_t *arg_val); + sw_error_t cmd_show_flow_ipv4_3tuple(a_ulong_t *arg_val); + sw_error_t cmd_show_flow_ipv4_5tuple(a_ulong_t *arg_val); + sw_error_t cmd_show_flow_ipv6_3tuple(a_ulong_t *arg_val); + sw_error_t cmd_show_flow_ipv6_5tuple(a_ulong_t *arg_val); + sw_error_t cmd_show_nat(a_ulong_t *arg_val); + sw_error_t cmd_show_napt(a_ulong_t *arg_val); + sw_error_t cmd_show_intfmac(a_ulong_t *arg_val); + sw_error_t cmd_show_pubaddr(a_ulong_t *arg_val); + sw_error_t cmd_show_flow(a_ulong_t *arg_val); + sw_error_t cmd_show_ctrlpkt(a_ulong_t *arg_val); + sw_error_t cmd_show_ptvlan_entry(a_ulong_t *arg_val); +/*qca808x_start*/ +#ifdef __cplusplus +} +#endif /* __cplusplus */ +/*qca808x_start*/ + +#endif /* _SHELL_SW_H_ */ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/make/components.mk b/feeds/ipq807x/qca-ssdk-shell/src/make/components.mk new file mode 100755 index 000000000..71f9fb86e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/make/components.mk @@ -0,0 +1,36 @@ + +ifeq (linux, $(OS)) + ifeq (KSLIB, $(MODULE_TYPE)) + ifeq (TRUE, $(KERNEL_MODE)) + COMPONENTS = HSL SAL INIT UTIL REF + ifeq (TRUE, $(FAL)) + COMPONENTS += FAL + endif + else + COMPONENTS = HSL SAL INIT REF + endif + + ifeq (TRUE, $(UK_IF)) + COMPONENTS += API + endif + endif + + ifeq (USLIB, $(MODULE_TYPE)) + ifneq (TRUE, $(KERNEL_MODE)) + COMPONENTS = HSL SAL INIT UTIL REF + ifeq (TRUE, $(FAL)) + COMPONENTS += FAL + endif + else + COMPONENTS = UK_IF SAL REF + endif + + ifeq (TRUE, $(UK_IF)) + COMPONENTS += API + endif + endif + + ifeq (SHELL, $(MODULE_TYPE)) + COMPONENTS = SHELL + endif +endif diff --git a/feeds/ipq807x/qca-ssdk-shell/src/make/config.mk b/feeds/ipq807x/qca-ssdk-shell/src/make/config.mk new file mode 100755 index 000000000..027c9bba3 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/make/config.mk @@ -0,0 +1,91 @@ + +include $(PRJ_PATH)/config + +ifndef SYS_PATH + $(error SYS_PATH isn't defined!) +endif + +ifndef TOOL_PATH + $(error TOOL_PATH isn't defined!) +endif + +#define cpu type such as PPC MIPS ARM X86 +ifndef CPU + CPU=mips +endif + +#define os type such as linux netbsd vxworks +ifndef OS + OS=linux +endif + +ifndef OS_VER + OS_VER=2_6 +endif + +#support chip type such as ATHENA GARUDA +ifndef CHIP_TYPE + SUPPORT_CHIP = GARUDA +else + ifeq (GARUDA, $(CHIP_TYPE)) + SUPPORT_CHIP = GARUDA + endif + + ifeq (ATHENA, $(CHIP_TYPE)) + SUPPORT_CHIP = ATHENA + endif + + ifeq (SHIVA, $(CHIP_TYPE)) + SUPPORT_CHIP = SHIVA + endif + + ifeq (HORUS, $(CHIP_TYPE)) + SUPPORT_CHIP = HORUS + endif + + ifeq (ISIS, $(CHIP_TYPE)) + SUPPORT_CHIP = ISIS + endif + + ifeq (ISISC, $(CHIP_TYPE)) + SUPPORT_CHIP = ISISC + endif + + ifeq (ALL_CHIP, $(CHIP_TYPE)) + ifneq (TRUE, $(FAL)) + $(error FAL must be TRUE when CHIP_TYPE is defined as ALL_CHIP!) + endif + SUPPORT_CHIP = GARUDA SHIVA HORUS ISIS ISISC + endif + + ifndef SUPPORT_CHIP + $(error defined CHIP_TYPE isn't supported!) + endif +endif + +#define compile tool prefix +ifndef TOOLPREFIX + TOOLPREFIX=$(CPU)-$(OS)-uclibc- +endif + +DEBUG_ON=FALSE +OPT_FLAG= +LD_FLAG= + +SHELLOBJ=ssdk_sh +US_MOD=ssdk_us +KS_MOD=ssdk_ks + +ifeq (TRUE, $(KERNEL_MODE)) + RUNMODE=km +else + RUNMODE=um +endif + +BLD_DIR=$(PRJ_PATH)/build/$(OS) +BIN_DIR=$(PRJ_PATH)/build/bin + +VER=2.0.0 +BUILD_NUMBER=$(shell cat $(PRJ_PATH)/make/.build_number) +VERSION=$(VER) +BUILD_DATE=$(shell date -u +%F-%T) diff --git a/feeds/ipq807x/qca-ssdk-shell/src/make/defs.mk b/feeds/ipq807x/qca-ssdk-shell/src/make/defs.mk new file mode 100755 index 000000000..7d1c75bb9 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/make/defs.mk @@ -0,0 +1,28 @@ +DST_DIR=$(BLD_DIR)/$(MODULE_TYPE) + +SUB_DIR=$(patsubst %/, %, $(dir $(wildcard ./*/Makefile))) + +ifeq (,$(findstring $(LIB), $(COMPONENTS))) + SRC_LIST= +endif + +SRC_FILE=$(addprefix $(PRJ_PATH)/$(LOC_DIR)/, $(SRC_LIST)) + +OBJ_LIST=$(SRC_LIST:.c=.o) +OBJ_FILE=$(addprefix $(DST_DIR)/, $(OBJ_LIST)) + +DEP_LIST=$(SRC_LIST:.c=.d) +DEP_FILE=$(addprefix $(DST_DIR)/, $(DEP_LIST)) + +vpath %.c $(PRJ_PATH)/$(LOC_DIR) +vpath %.c $(PRJ_PATH)/app/nathelper/linux +vpath %.c $(PRJ_PATH)/app/nathelper/linux/lib +vpath %.o $(DST_DIR) +vpath %.d $(DST_DIR) + +DEP_LOOP=$(foreach i, $(SUB_DIR), $(MAKE) -C $(i) dep || exit 1;) +OBJ_LOOP=$(foreach i, $(SUB_DIR), $(MAKE) -C $(i) obj || exit 1;) +CLEAN_LOOP=$(foreach i, $(SUB_DIR), $(MAKE) -C $(i) clean;) +CLEAN_OBJ_LOOP=$(foreach i, $(SUB_DIR), $(MAKE) -C $(i) clean_o;) +CLEAN_DEP_LOOP=$(foreach i, $(SUB_DIR), $(MAKE) -C $(i) clean_d;) + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/make/linux_opt.mk b/feeds/ipq807x/qca-ssdk-shell/src/make/linux_opt.mk new file mode 100755 index 000000000..e9a98079b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/make/linux_opt.mk @@ -0,0 +1,328 @@ +ifeq (TRUE, $(IN_ACL)) + MODULE_CFLAG += -DIN_ACL +endif + +ifeq (TRUE, $(IN_FDB)) + MODULE_CFLAG += -DIN_FDB +endif + +ifeq (TRUE, $(IN_IGMP)) + MODULE_CFLAG += -DIN_IGMP +endif + +ifeq (TRUE, $(IN_LEAKY)) + MODULE_CFLAG += -DIN_LEAKY +endif + +ifeq (TRUE, $(IN_LED)) + MODULE_CFLAG += -DIN_LED +endif + +ifeq (TRUE, $(IN_MIB)) + MODULE_CFLAG += -DIN_MIB +endif + +ifeq (TRUE, $(IN_MIRROR)) + MODULE_CFLAG += -DIN_MIRROR +endif + +ifeq (TRUE, $(IN_MISC)) + MODULE_CFLAG += -DIN_MISC +endif + +ifeq (TRUE, $(IN_PORTCONTROL)) + MODULE_CFLAG += -DIN_PORTCONTROL +endif + +ifeq (TRUE, $(IN_PORTVLAN)) + MODULE_CFLAG += -DIN_PORTVLAN +endif + +ifeq (TRUE, $(IN_QOS)) + MODULE_CFLAG += -DIN_QOS +endif + +ifeq (TRUE, $(IN_RATE)) + MODULE_CFLAG += -DIN_RATE +endif + +ifeq (TRUE, $(IN_STP)) + MODULE_CFLAG += -DIN_STP +endif + +ifeq (TRUE, $(IN_VLAN)) + MODULE_CFLAG += -DIN_VLAN +endif + +ifeq (TRUE, $(IN_REDUCED_ACL)) + MODULE_CFLAG += -DIN_REDUCED_ACL +endif + +ifeq (TRUE, $(IN_COSMAP)) + MODULE_CFLAG += -DIN_COSMAP +endif + +ifeq (TRUE, $(IN_IP)) + MODULE_CFLAG += -DIN_IP +endif + +ifeq (TRUE, $(IN_NAT)) + MODULE_CFLAG += -DIN_NAT +endif + +ifeq (TRUE, $(IN_TRUNK)) + MODULE_CFLAG += -DIN_TRUNK +endif + +ifeq (TRUE, $(IN_SEC)) + MODULE_CFLAG += -DIN_SEC +endif + +ifeq (TRUE, $(IN_QM)) + MODULE_CFLAG += -DIN_QM +endif + +ifeq (TRUE, $(IN_BM)) + MODULE_CFLAG += -DIN_BM +endif + +ifeq (TRUE, $(IN_FLOW)) + MODULE_CFLAG += -DIN_FLOW +endif + +ifeq (TRUE, $(IN_NAT_HELPER)) + MODULE_CFLAG += -DIN_NAT_HELPER +endif + +ifeq (TRUE, $(IN_INTERFACECONTROL)) + MODULE_CFLAG += -DIN_INTERFACECONTROL +endif + +ifeq (TRUE, $(IN_CTRLPKT)) + MODULE_CFLAG += -DIN_CTRLPKT +endif + +ifeq (TRUE, $(IN_SERVCODE)) + MODULE_CFLAG += -DIN_SERVCODE +endif + +ifeq (TRUE, $(IN_RSS_HASH)) + MODULE_CFLAG += -DIN_RSS_HASH +endif + +ifeq (TRUE, $(IN_MACBLOCK)) + MODULE_CFLAG += -DIN_MACBLOCK +endif + +ifeq (TRUE, $(IN_VSI)) + MODULE_CFLAG += -DIN_VSI +endif + +ifeq (TRUE, $(IN_POLICER)) + MODULE_CFLAG += -DIN_POLICER +endif + +ifeq (TRUE, $(IN_SHAPER)) + MODULE_CFLAG += -DIN_SHAPER +endif + +ifeq (TRUE, $(IN_PTP)) + MODULE_CFLAG += -DIN_PTP +endif + +ifeq (TRUE, $(IN_SFP)) + MODULE_CFLAG += -DIN_SFP +endif + +ifeq (TRUE, $(IN_PPPOE)) + MODULE_CFLAG += -DIN_PPPOE +endif + +ifneq (TRUE, $(FAL)) + MODULE_CFLAG += -DHSL_STANDALONG +endif + +ifeq (TRUE, $(UK_IF)) + MODULE_CFLAG += -DUK_IF +endif + +#ifdef UK_NL_PROT + MODULE_CFLAG += -DUK_NL_PROT=$(UK_NL_PROT) +#endif + +#ifdef UK_MINOR_DEV + MODULE_CFLAG += -DUK_MINOR_DEV=$(UK_MINOR_DEV) +#endif + +ifeq (TRUE, $(API_LOCK)) + MODULE_CFLAG += -DAPI_LOCK +endif + +ifeq (TRUE, $(REG_ACCESS_SPEEDUP)) + MODULE_CFLAG += -DREG_ACCESS_SPEEDUP +endif + +ifeq (TRUE, $(DEBUG_ON)) + MODULE_CFLAG += -g +endif + +MODULE_CFLAG += $(OPT_FLAG) -Wall -Werror -DVERSION=\"$(VERSION)\" -DBUILD_DATE=\"$(BUILD_DATE)\" -DCPU=\"$(CPU)\" -DOS=\"$(OS)\" + +MODULE_INC += -I$(PRJ_PATH)/include \ + -I$(PRJ_PATH)/include/common \ + -I$(PRJ_PATH)/include/api \ + -I$(PRJ_PATH)/include/fal \ + -I$(PRJ_PATH)/include/ref \ + -I$(PRJ_PATH)/include/hsl \ + -I$(PRJ_PATH)/include/hsl/phy \ + -I$(PRJ_PATH)/include/sal/os \ + -I$(PRJ_PATH)/include/sal/os/linux_user \ + -I$(PRJ_PATH)/include/sal/sd \ + -I$(PRJ_PATH)/include/sal/sd/linux/hydra_howl \ + -I$(PRJ_PATH)/include/sal/sd/linux/uk_interface \ + -I$(PRJ_PATH)/include/init + +ifneq (,$(findstring ATHENA, $(SUPPORT_CHIP))) + MODULE_INC += -I$(PRJ_PATH)/include/hsl/athena + MODULE_CFLAG += -DATHENA +endif + +ifneq (,$(findstring GARUDA, $(SUPPORT_CHIP))) + MODULE_INC += -I$(PRJ_PATH)/include/hsl/garuda + MODULE_CFLAG += -DGARUDA +endif + +ifneq (,$(findstring SHIVA, $(SUPPORT_CHIP))) + MODULE_INC += -I$(PRJ_PATH)/include/hsl/shiva + MODULE_CFLAG += -DSHIVA +endif + +ifneq (,$(findstring HORUS, $(SUPPORT_CHIP))) + MODULE_INC += -I$(PRJ_PATH)/include/hsl/horus + MODULE_CFLAG += -DHORUS +endif + +ifneq (,$(findstring ISIS, $(SUPPORT_CHIP))) + ifneq (ISISC, $(SUPPORT_CHIP)) + MODULE_INC += -I$(PRJ_PATH)/include/hsl/isis + MODULE_CFLAG += -DISIS + endif +endif + +ifneq (,$(findstring ISISC, $(SUPPORT_CHIP))) + MODULE_INC += -I$(PRJ_PATH)/include/hsl/isisc + MODULE_CFLAG += -DISISC +endif + +# check for GCC version +ifeq (4, $(GCC_VER)) + MODULE_CFLAG += -DGCCV4 +endif + +ifeq (KSLIB, $(MODULE_TYPE)) + + ifeq (3_4, $(OS_VER)) + MODULE_CFLAG += -DKVER34 + MODULE_CFLAG += -DKVER32 + MODULE_CFLAG += -DLNX26_22 + MODULE_INC += -I$(SYS_PATH) \ + -I$(SYS_PATH)/include \ + -I$(SYS_PATH)/source/include \ + -I$(SYS_PATH)/source/arch/arm/mach-msm/include \ + -I$(SYS_PATH)/source/arch/arm/include \ + -I$(SYS_PATH)/source/arch/arm/include/asm \ + -I$(SYS_PATH)/arch/arm/include/generated \ + -I$(SYS_PATH)/source/arch/arm/include/asm/mach \ + -I$(SYS_PATH)/usr/include + + endif + + ifeq (3_2, $(OS_VER)) + MODULE_CFLAG += -DKVER32 + MODULE_CFLAG += -DLNX26_22 + ifeq (mips, $(CPU)) + MODULE_INC += -I$(SYS_PATH) \ + -I$(SYS_PATH)/include \ + -I$(SYS_PATH)/arch/mips/include \ + -I$(SYS_PATH)/arch/mips/include/asm/mach-ar7240 \ + -I$(SYS_PATH)/arch/mips/include/asm/mach-generic \ + -I$(SYS_PATH)/arch/mips/include/asm/mach-ar7 \ + -I$(SYS_PATH)/usr/include + + #CPU_CFLAG = -G 0 -mno-abicalls -fno-pic -pipe -mabi=32 -march=mips32r2 + ifndef CPU_CFLAG + CPU_CFLAG = -Wstrict-prototypes -fomit-frame-pointer -G 0 -mno-abicalls -fno-strict-aliasing \ + -O2 -fno-pic -pipe -mabi=32 -march=mips32r2 -DMODULE -mlong-calls -DEXPORT_SYMTAB + endif + else + MODULE_INC += -I$(SYS_PATH) \ + -I$(SYS_PATH)/include \ + -I$(SYS_PATH)/arch/arm/include \ + -I$(SYS_PATH)/arch/arm/include/asm \ + -I$(SYS_PATH)/arch/arm/mach-fv16xx/include \ + -I$(SYS_PATH)/arch/arm/include/generated \ + -I$(SYS_PATH)/include/generated \ + -I$(SYS_PATH)/usr/include + endif + + + endif + + ifeq (2_6, $(OS_VER)) + MODULE_CFLAG += -DKVER26 + MODULE_CFLAG += -DLNX26_22 + ifeq (mips, $(CPU)) + MODULE_INC += -I$(SYS_PATH) \ + -I$(SYS_PATH)/include \ + -I$(SYS_PATH)/arch/mips/include \ + -I$(SYS_PATH)/arch/mips/include/asm/mach-ar7240 \ + -I$(SYS_PATH)/arch/mips/include/asm/mach-generic \ + -I$(SYS_PATH)/usr/include + + #CPU_CFLAG = -G 0 -mno-abicalls -fno-pic -pipe -mabi=32 -march=mips32r2 + ifndef CPU_CFLAG + CPU_CFLAG = -Wstrict-prototypes -fomit-frame-pointer -G 0 -mno-abicalls -fno-strict-aliasing \ + -O2 -fno-pic -pipe -mabi=32 -march=mips32r2 -DMODULE -mlong-calls -DEXPORT_SYMTAB + endif + else + MODULE_INC += -I$(SYS_PATH) \ + -I$(SYS_PATH)/include \ + -I$(SYS_PATH)/arch/arm/include \ + -I$(SYS_PATH)/arch/arm/include/asm \ + -I$(SYS_PATH)/arch/arm/mach-fv16xx/include \ + -I$(SYS_PATH)/arch/arm/include/generated \ + -I$(SYS_PATH)/include/generated \ + -I$(SYS_PATH)/usr/include + endif + + + endif + + MODULE_CFLAG += -D__KERNEL__ -DKERNEL_MODULE $(CPU_CFLAG) + + +endif + +ifeq (SHELL, $(MODULE_TYPE)) + MODULE_INC += -I$(PRJ_PATH)/include/shell + + ifeq (2_6, $(OS_VER)) + MODULE_CFLAG += -DKVER26 + else + MODULE_CFLAG += -DKVER24 + endif + + ifneq (TRUE, $(KERNEL_MODE)) + MODULE_CFLAG += -DUSER_MODE + endif + +endif + +ifneq (TRUE, $(KERNEL_MODE)) + ifneq (SHELL, $(MODULE_TYPE)) + MODULE_CFLAG += -DUSER_MODE + endif +endif + +EXTRA_CFLAGS += $(MODULE_INC) $(MODULE_CFLAG) -fpie +EXTRA_LDFLAGS += -pie diff --git a/feeds/ipq807x/qca-ssdk-shell/src/make/target.mk b/feeds/ipq807x/qca-ssdk-shell/src/make/target.mk new file mode 100755 index 000000000..ddb3bd12f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/make/target.mk @@ -0,0 +1,49 @@ + +include $(PRJ_PATH)/make/$(OS)_opt.mk + +include $(PRJ_PATH)/make/tools.mk + +obj: $(OBJ_LIST) + $(OBJ_LOOP) + +dep: build_dir $(DEP_LIST) + $(DEP_LOOP) + +$(OBJ_LIST): %.o : %.c %.d + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $(DST_DIR)/$@ + +$(DEP_LIST) : %.d : %.c + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -MM $< > $(DST_DIR)/$@.tmp + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $(DST_DIR)/$@.tmp > $(DST_DIR)/$@ + $(RM) -f $(DST_DIR)/$@.tmp; + +build_dir: $(DST_DIR) + +$(DST_DIR): + $(MKDIR) -p $(DST_DIR) + +.PHONY: clean +clean: clean_o clean_d + $(CLEAN_LOOP) + +.PHONY: clean_o +clean_o: clean_obj + $(CLEAN_OBJ_LOOP) + +.PHONY: clean_d +clean_d: clean_dep + $(CLEAN_DEP_LOOP) + +clean_obj: +ifneq (,$(word 1, $(OBJ_FILE))) + $(RM) -f $(OBJ_FILE) +endif + +clean_dep: +ifneq (,$(word 1, $(DEP_FILE))) + $(RM) -f $(DEP_FILE) +endif + +ifneq (,$(word 1, $(DEP_FILE))) + sinclude $(DEP_FILE) +endif diff --git a/feeds/ipq807x/qca-ssdk-shell/src/make/tools.mk b/feeds/ipq807x/qca-ssdk-shell/src/make/tools.mk new file mode 100755 index 000000000..6ed387298 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/make/tools.mk @@ -0,0 +1,12 @@ + +ifeq (linux, $(OS)) + CC=$(TOOL_PATH)/$(TOOLPREFIX)gcc + AR=$(TOOL_PATH)/$(TOOLPREFIX)ar + LD=$(TOOL_PATH)/$(TOOLPREFIX)ld + STRIP=$(TOOL_PATH)/$(TOOLPREFIX)strip + MAKE=make -S + CP=cp + MKDIR=mkdir + RM=rm + PERL=perl +endif diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/api/Makefile b/feeds/ipq807x/qca-ssdk-shell/src/src/api/Makefile new file mode 100755 index 000000000..25c788a90 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/api/Makefile @@ -0,0 +1,12 @@ +LOC_DIR=src/sal +LIB=API + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST=$(wildcard *.c) + +include $(PRJ_PATH)/make/components.mk +include $(PRJ_PATH)/make/defs.mk +include $(PRJ_PATH)/make/target.mk + +all: dep obj \ No newline at end of file diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/api/api_access.c b/feeds/ipq807x/qca-ssdk-shell/src/src/api/api_access.c new file mode 100755 index 000000000..3c7b334e5 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/api/api_access.c @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2014,2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/*qca808x_start*/ +#include "sw.h" +#include "fal.h" +/*qca808x_end*/ +#include "ref_vlan.h" +#if (defined(KERNEL_MODULE)) +#include "hsl.h" +#include "hsl_dev.h" +#if defined ATHENA +#include "fal_igmp.h" +#include "fal_leaky.h" +#include "athena_mib.h" +#include "athena_port_ctrl.h" +#include "athena_portvlan.h" +#include "athena_fdb.h" +#include "athena_vlan.h" +#include "athena_init.h" +#include "athena_reg_access.h" +#include "athena_reg.h" +#elif defined GARUDA +#include "garuda_mib.h" +#include "garuda_qos.h" +#include "garuda_rate.h" +#include "garuda_port_ctrl.h" +#include "garuda_portvlan.h" +#include "garuda_fdb.h" +#include "garuda_vlan.h" +#include "garuda_mirror.h" +#include "garuda_stp.h" +#include "garuda_misc.h" +#include "garuda_leaky.h" +#include "garuda_igmp.h" +#include "garuda_acl.h" +#include "garuda_led.h" +#include "garuda_init.h" +#include "garuda_reg_access.h" +#include "garuda_reg.h" +#elif defined SHIVA +#include "shiva_mib.h" +#include "shiva_qos.h" +#include "shiva_rate.h" +#include "shiva_port_ctrl.h" +#include "shiva_portvlan.h" +#include "shiva_fdb.h" +#include "shiva_vlan.h" +#include "shiva_mirror.h" +#include "shiva_stp.h" +#include "shiva_misc.h" +#include "shiva_leaky.h" +#include "shiva_igmp.h" +#include "shiva_acl.h" +#include "shiva_led.h" +#include "shiva_init.h" +#include "shiva_reg_access.h" +#include "shiva_reg.h" +#elif defined HORUS +#include "horus_mib.h" +#include "horus_qos.h" +#include "horus_rate.h" +#include "horus_port_ctrl.h" +#include "horus_portvlan.h" +#include "horus_fdb.h" +#include "horus_vlan.h" +#include "horus_mirror.h" +#include "horus_stp.h" +#include "horus_misc.h" +#include "horus_leaky.h" +#include "horus_igmp.h" +#include "horus_led.h" +#include "horus_init.h" +#include "horus_reg_access.h" +#include "horus_reg.h" +#elif defined ISIS +#include "isis_mib.h" +#include "isis_qos.h" +#include "isis_cosmap.h" +#include "isis_rate.h" +#include "isis_port_ctrl.h" +#include "isis_portvlan.h" +#include "isis_fdb.h" +#include "isis_vlan.h" +#include "isis_mirror.h" +#include "isis_stp.h" +#include "isis_misc.h" +#include "isis_leaky.h" +#include "isis_igmp.h" +#include "isis_acl.h" +#include "isis_led.h" +#include "isis_cosmap.h" +#include "isis_ip.h" +#include "isis_nat.h" +#include "isis_trunk.h" +#include "isis_sec.h" +#include "isis_interface_ctrl.h" +#include "isis_init.h" +#include "isis_reg_access.h" +#include "isis_reg.h" +#elif defined ISISC +#include "isisc_mib.h" +#include "isisc_qos.h" +#include "isisc_cosmap.h" +#include "isisc_rate.h" +#include "isisc_port_ctrl.h" +#include "isisc_portvlan.h" +#include "isisc_fdb.h" +#include "isisc_vlan.h" +#include "isisc_mirror.h" +#include "isisc_stp.h" +#include "isisc_misc.h" +#include "isisc_leaky.h" +#include "isisc_igmp.h" +#include "isisc_acl.h" +#include "isisc_led.h" +#include "isisc_cosmap.h" +#include "isisc_ip.h" +#include "isisc_nat.h" +#include "isisc_trunk.h" +#include "isisc_sec.h" +#include "isisc_interface_ctrl.h" +#include "isisc_init.h" +#include "isisc_reg_access.h" +#include "isisc_reg.h" +#endif +#endif +/*qca808x_start*/ +#include "sw_api.h" +#include "api_desc.h" +/*qca808x_end*/ +#if (((!defined(USER_MODE)) && defined(KERNEL_MODULE)) || (defined(USER_MODE) && (!defined(KERNEL_MODULE)))) +#ifdef HSL_STANDALONG +#if defined ATHENA +#include "athena_api.h" +#elif defined GARUDA +#include "garuda_api.h" +#elif defined SHIVA +#include "shiva_api.h" +#elif defined HORUS +#include "horus_api.h" +#elif defined ISIS +#include "isis_api.h" +#elif defined ISISC +#include "isisc_api.h" +#endif +#else +#include "ref_api.h" +#include "fal_api.h" +#endif +#elif (defined(USER_MODE)) +#if defined ATHENA +#include "athena_api.h" +#elif defined GARUDA +#include "garuda_api.h" +#elif defined SHIVA +#include "shiva_api.h" +#elif defined HORUS +#include "horus_api.h" +#elif defined ISIS +#include "isis_api.h" +#elif defined ISISC +#include "isisc_api.h" +#endif +#else +#include "ref_api.h" +/*qca808x_start*/ +#include "fal_api.h" +/*qca808x_end*/ +#endif +/*qca808x_start*/ +static sw_api_func_t sw_api_func[] = { +/*qca808x_end*/ + SSDK_REF_API +/*qca808x_start*/ + SSDK_API }; +static sw_api_param_t sw_api_param[] = { +/*qca808x_end*/ + SSDK_REF_PARAM +/*qca808x_start*/ + SSDK_PARAM }; + +sw_api_func_t * +sw_api_func_find(a_uint32_t api_id) +{ + a_uint32_t i = 0; + static a_uint32_t save = 0; + + if(api_id == sw_api_func[save].api_id) + return &sw_api_func[save]; + + do + { + if (api_id == sw_api_func[i].api_id) + { + save = i; + return &sw_api_func[i]; + } + + } + while (++i < (sizeof(sw_api_func)/sizeof(sw_api_func[0]))); + + return NULL; +} + +sw_api_param_t * +sw_api_param_find(a_uint32_t api_id) +{ + a_uint32_t i = 0; + static a_uint32_t save = 0; + + if(api_id == sw_api_param[save].api_id) + return &sw_api_param[save]; + + do + { + if (api_id == sw_api_param[i].api_id) + { + save = i; + return &sw_api_param[i]; + } + } + while (++i < (sizeof(sw_api_param)/sizeof(sw_api_param[0]))); + + return NULL; +} + +a_uint32_t +sw_api_param_nums(a_uint32_t api_id) +{ + a_uint32_t i = 0; + sw_api_param_t *p = NULL; + static sw_api_param_t *savep = NULL; + static a_uint32_t save = 0; + + p = sw_api_param_find(api_id); + if (!p) + { + return 0; + } + + if (p == savep) + { + return save; + } + + savep = p; + while (api_id == p->api_id) + { + p++; + i++; + } + + /*error*/ + if(i >= sizeof(sw_api_param)/sizeof(sw_api_param[0])) + { + savep = NULL; + save = 0; + return 0; + } + save = i; + + return i; +} + +sw_error_t +sw_api_get(sw_api_t *sw_api) +{ + if(!sw_api) + return SW_FAIL; + + if ((sw_api->api_fp = sw_api_func_find(sw_api->api_id)) == NULL) + return SW_NOT_SUPPORTED; + + if ((sw_api->api_pp = sw_api_param_find(sw_api->api_id)) == NULL) + return SW_NOT_SUPPORTED; + + if((sw_api->api_nr = sw_api_param_nums(sw_api->api_id)) == 0) + return SW_NOT_SUPPORTED; + + return SW_OK; +} +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/Makefile b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/Makefile new file mode 100755 index 000000000..34612d390 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/Makefile @@ -0,0 +1,141 @@ +LOC_DIR=src/fal_uk +LIB=UK_IF + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST=fal_init.c fal_uk_if.c fal_reg_access.c + +ifeq (TRUE, $(IN_ACL)) + SRC_LIST += fal_acl.c +endif + +ifeq (TRUE, $(IN_FDB)) + SRC_LIST += fal_fdb.c +endif + +ifeq (TRUE, $(IN_IGMP)) + SRC_LIST += fal_igmp.c +endif + +ifeq (TRUE, $(IN_LEAKY)) + SRC_LIST += fal_leaky.c +endif + +ifeq (TRUE, $(IN_LED)) + SRC_LIST += fal_led.c +endif + +ifeq (TRUE, $(IN_MIB)) + SRC_LIST += fal_mib.c +endif + +ifeq (TRUE, $(IN_MIRROR)) + SRC_LIST += fal_mirror.c +endif + +ifeq (TRUE, $(IN_MISC)) + SRC_LIST += fal_misc.c +endif + +ifeq (TRUE, $(IN_PORTCONTROL)) + SRC_LIST += fal_port_ctrl.c +endif + +ifeq (TRUE, $(IN_PORTVLAN)) + SRC_LIST += fal_portvlan.c +endif + +ifeq (TRUE, $(IN_QOS)) + SRC_LIST += fal_qos.c +endif + +ifeq (TRUE, $(IN_RATE)) + SRC_LIST += fal_rate.c +endif + +ifeq (TRUE, $(IN_STP)) + SRC_LIST += fal_stp.c +endif + +ifeq (TRUE, $(IN_VLAN)) + SRC_LIST += fal_vlan.c +endif + +ifeq (TRUE, $(IN_COSMAP)) + SRC_LIST += fal_cosmap.c +endif + +ifeq (TRUE, $(IN_IP)) + SRC_LIST += fal_ip.c +endif + +ifeq (TRUE, $(IN_NAT)) + SRC_LIST += fal_nat.c +endif + +ifeq (TRUE, $(IN_SEC)) + SRC_LIST += fal_sec.c +endif + +ifeq (TRUE, $(IN_TRUNK)) + SRC_LIST += fal_trunk.c +endif + +ifeq (TRUE, $(IN_INTERFACECONTROL)) + SRC_LIST += fal_interface_ctrl.c +endif + +ifeq (TRUE, $(IN_CTRLPKT)) + SRC_LIST += fal_ctrlpkt.c +endif + +ifeq (TRUE, $(IN_SERVCODE)) + SRC_LIST += fal_servcode.c +endif + +ifeq (TRUE, $(IN_RSS_HASH)) + SRC_LIST += fal_rss_hash.c +endif + +ifeq (TRUE, $(IN_VSI)) + SRC_LIST += fal_vsi.c +endif + +ifeq (TRUE, $(IN_QM)) + SRC_LIST += fal_qm.c +endif + + +ifeq (TRUE, $(IN_FLOW)) + SRC_LIST += fal_flow.c +endif + +ifeq (TRUE, $(IN_PPPOE)) + SRC_LIST += fal_pppoe.c +endif + +ifeq (TRUE, $(IN_BM)) + SRC_LIST += fal_bm.c +endif + +ifeq (TRUE, $(IN_SHAPER)) + SRC_LIST += fal_shaper.c +endif + +ifeq (TRUE, $(IN_POLICER)) + SRC_LIST += fal_policer.c +endif + +ifeq (TRUE, $(IN_PTP)) + SRC_LIST += fal_ptp.c +endif + +ifeq (TRUE, $(IN_SFP)) + SRC_LIST += fal_sfp.c +endif + +include $(PRJ_PATH)/make/components.mk +include $(PRJ_PATH)/make/defs.mk +include $(PRJ_PATH)/make/target.mk + +all: dep obj diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_acl.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_acl.c new file mode 100755 index 000000000..9f97bf300 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_acl.c @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2014, 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +#include "sw_ioctl.h" +#include "fal_acl.h" +#include "fal_uk_if.h" + +sw_error_t +fal_acl_list_creat(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t prio) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ACL_LIST_CREAT, dev_id, list_id, prio); + return rv; +} + +sw_error_t +fal_acl_list_destroy(a_uint32_t dev_id, a_uint32_t list_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ACL_LIST_DESTROY, dev_id, list_id); + return rv; +} + +sw_error_t +fal_acl_rule_add(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t rule_id, + a_uint32_t rule_nr, fal_acl_rule_t * rule) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ACL_RULE_ADD, dev_id, list_id, rule_id, + rule_nr, rule); + return rv; +} + +sw_error_t +fal_acl_rule_delete(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t rule_id, + a_uint32_t rule_nr) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ACL_RULE_DELETE, dev_id, list_id, rule_id, rule_nr); + return rv; +} + +sw_error_t +fal_acl_rule_query(a_uint32_t dev_id, a_uint32_t list_id, a_uint32_t rule_id, + fal_acl_rule_t * rule) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ACL_RULE_QUERY, dev_id, list_id, rule_id, rule); + return rv; +} + +sw_error_t +fal_acl_list_bind(a_uint32_t dev_id, a_uint32_t list_id, + fal_acl_direc_t direc, fal_acl_bind_obj_t obj_t, + a_uint32_t obj_idx) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ACL_LIST_BIND, dev_id, list_id, direc, obj_t, obj_idx); + return rv; +} + +sw_error_t +fal_acl_list_unbind(a_uint32_t dev_id, a_uint32_t list_id, + fal_acl_direc_t direc, fal_acl_bind_obj_t obj_t, + a_uint32_t obj_idx) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ACL_LIST_UNBIND, dev_id, list_id, direc, obj_t, obj_idx); + return rv; +} + +sw_error_t +fal_acl_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ACL_STATUS_SET, dev_id, enable); + return rv; +} + +sw_error_t +fal_acl_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ACL_STATUS_GET, dev_id, enable); + return rv; +} + +sw_error_t +fal_acl_list_dump(a_uint32_t dev_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ACL_LIST_DUMP, dev_id); + return rv; +} + +sw_error_t +fal_acl_rule_dump(a_uint32_t dev_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ACL_RULE_DUMP, dev_id); + return rv; +} + +sw_error_t +fal_acl_port_udf_profile_set(a_uint32_t dev_id, fal_port_t port_id, + fal_acl_udf_type_t udf_type, a_uint32_t offset, a_uint32_t length) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ACL_PT_UDF_PROFILE_SET, dev_id, port_id, udf_type, offset, length); + return rv; +} + +sw_error_t +fal_acl_port_udf_profile_get(a_uint32_t dev_id, fal_port_t port_id, + fal_acl_udf_type_t udf_type, a_uint32_t * offset, a_uint32_t * length) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ACL_PT_UDF_PROFILE_GET, dev_id, port_id, + udf_type, offset, length); + return rv; +} + +sw_error_t +fal_acl_rule_active(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, a_uint32_t rule_nr) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ACL_RULE_ACTIVE, dev_id, list_id, rule_id, rule_nr); + return rv; +} + +sw_error_t +fal_acl_rule_deactive(a_uint32_t dev_id, a_uint32_t list_id, + a_uint32_t rule_id, a_uint32_t rule_nr) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ACL_RULE_DEACTIVE, dev_id, list_id, rule_id, rule_nr); + return rv; +} + +sw_error_t +fal_acl_rule_src_filter_sts_set(a_uint32_t dev_id, + a_uint32_t rule_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ACL_RULE_SRC_FILTER_STS_SET, dev_id, rule_id, enable); + return rv; +} + +sw_error_t +fal_acl_rule_src_filter_sts_get(a_uint32_t dev_id, + a_uint32_t rule_id, a_bool_t* enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ACL_RULE_SRC_FILTER_STS_GET, dev_id, rule_id, enable); + return rv; +} + +sw_error_t +fal_acl_udf_profile_set(a_uint32_t dev_id, fal_acl_udf_pkt_type_t pkt_type, + a_uint32_t udf_idx, fal_acl_udf_type_t udf_type, a_uint32_t offset) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ACL_UDF_SET, dev_id, pkt_type, udf_idx, udf_type, offset); + return rv; +} + +sw_error_t +fal_acl_udf_profile_get(a_uint32_t dev_id, fal_acl_udf_pkt_type_t pkt_type, + a_uint32_t udf_idx, fal_acl_udf_type_t *udf_type, a_uint32_t *offset) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ACL_UDF_GET, dev_id, pkt_type, udf_idx, udf_type, offset); + return rv; +} + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_bm.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_bm.c new file mode 100755 index 000000000..c822a867b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_bm.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_bm.h" +#include "fal_uk_if.h" + +sw_error_t +fal_port_bufgroup_map_get(a_uint32_t dev_id, fal_port_t port, + a_uint8_t *group) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_BM_PORTGROUP_MAP_GET, dev_id, port, group); + return rv; +} + +sw_error_t +fal_port_bufgroup_map_set(a_uint32_t dev_id, fal_port_t port, + a_uint8_t group) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_BM_PORTGROUP_MAP_SET, dev_id, port, group); + return rv; +} + +sw_error_t +fal_bm_port_reserved_buffer_get(a_uint32_t dev_id, fal_port_t port, + a_uint16_t *prealloc_buff, a_uint16_t *react_buff) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_BM_PORT_RSVBUFFER_GET, dev_id, port, + prealloc_buff, react_buff); + return rv; +} + +sw_error_t +fal_bm_port_reserved_buffer_set(a_uint32_t dev_id, fal_port_t port, + a_uint16_t prealloc_buff, a_uint16_t react_buff) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_BM_PORT_RSVBUFFER_SET, dev_id, port, + prealloc_buff, react_buff); + return rv; +} + +sw_error_t +fal_bm_bufgroup_buffer_get(a_uint32_t dev_id, a_uint8_t group, + a_uint16_t *buff_num) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_BM_GROUP_BUFFER_GET, dev_id, group, + buff_num); + return rv; +} + +sw_error_t +fal_bm_bufgroup_buffer_set(a_uint32_t dev_id, a_uint8_t group, + a_uint16_t buff_num) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_BM_GROUP_BUFFER_SET, dev_id, group, + buff_num); + return rv; +} + +sw_error_t +fal_bm_port_dynamic_thresh_get(a_uint32_t dev_id, fal_port_t port, + fal_bm_dynamic_cfg_t *cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_BM_DYNAMIC_THRESH_GET, dev_id, port, + cfg); + return rv; +} + +sw_error_t +fal_bm_port_dynamic_thresh_set(a_uint32_t dev_id, fal_port_t port, + fal_bm_dynamic_cfg_t *cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_BM_DYNAMIC_THRESH_SET, dev_id, port, + cfg); + return rv; +} + +sw_error_t +fal_port_bm_ctrl_get(a_uint32_t dev_id, fal_port_t port, a_bool_t *enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_BM_CTRL_GET, dev_id, port, + enable); + return rv; +} + +sw_error_t +fal_port_bm_ctrl_set(a_uint32_t dev_id, fal_port_t port, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_BM_CTRL_SET, dev_id, port, + enable); + return rv; +} + +sw_error_t +fal_bm_port_static_thresh_get(a_uint32_t dev_id, fal_port_t port, + fal_bm_static_cfg_t *cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_BM_STATIC_THRESH_GET, dev_id, port, + cfg); + return rv; +} + +sw_error_t +fal_bm_port_static_thresh_set(a_uint32_t dev_id, fal_port_t port, + fal_bm_static_cfg_t *cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_BM_STATIC_THRESH_SET, dev_id, port, + cfg); + return rv; +} + +sw_error_t +fal_bm_port_counter_get(a_uint32_t dev_id, fal_port_t port, + fal_bm_port_counter_t *counter) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_BM_PORT_COUNTER_GET, dev_id, port, + counter); + return rv; +} + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_cosmap.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_cosmap.c new file mode 100755 index 000000000..9b086884a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_cosmap.c @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_cosmap.h" +#include "fal_uk_if.h" + + +sw_error_t +fal_cosmap_dscp_to_pri_set(a_uint32_t dev_id, a_uint32_t dscp, a_uint32_t pri) +{ + sw_error_t rv; + + rv= sw_uk_exec(SW_API_COSMAP_DSCP_TO_PRI_SET, dev_id, dscp, pri); + return rv; +} + +sw_error_t +fal_cosmap_dscp_to_pri_get(a_uint32_t dev_id, a_uint32_t dscp, a_uint32_t * pri) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_COSMAP_DSCP_TO_PRI_GET, dev_id, dscp, pri); + return rv; +} + +sw_error_t +fal_cosmap_dscp_to_dp_set(a_uint32_t dev_id, a_uint32_t dscp, a_uint32_t dp) +{ + sw_error_t rv; + + rv= sw_uk_exec(SW_API_COSMAP_DSCP_TO_DP_SET, dev_id, dscp, dp); + return rv; +} + +sw_error_t +fal_cosmap_dscp_to_dp_get(a_uint32_t dev_id, a_uint32_t dscp, a_uint32_t * dp) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_COSMAP_DSCP_TO_DP_GET, dev_id, dscp, dp); + return rv; +} + +sw_error_t +fal_cosmap_up_to_pri_set(a_uint32_t dev_id, a_uint32_t up, a_uint32_t pri) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_COSMAP_UP_TO_PRI_SET, dev_id, up, pri); + return rv; +} + +sw_error_t +fal_cosmap_up_to_pri_get(a_uint32_t dev_id, a_uint32_t up, a_uint32_t * pri) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_COSMAP_UP_TO_PRI_GET, dev_id, up, pri); + return rv; +} + +sw_error_t +fal_cosmap_up_to_dp_set(a_uint32_t dev_id, a_uint32_t up, a_uint32_t dp) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_COSMAP_UP_TO_DP_SET, dev_id, up, dp); + return rv; +} + +sw_error_t +fal_cosmap_up_to_dp_get(a_uint32_t dev_id, a_uint32_t up, a_uint32_t * dp) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_COSMAP_UP_TO_DP_GET, dev_id, up, dp); + return rv; +} + +sw_error_t +fal_cosmap_pri_to_queue_set(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_COSMAP_PRI_TO_QU_SET, dev_id, pri, queue); + return rv; +} + +sw_error_t +fal_cosmap_pri_to_queue_get(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_COSMAP_PRI_TO_QU_GET, dev_id, pri, queue); + return rv; +} + +sw_error_t +fal_cosmap_pri_to_ehqueue_set(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t queue) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_COSMAP_PRI_TO_EHQU_SET, dev_id, pri, queue); + return rv; +} + +sw_error_t +fal_cosmap_pri_to_ehqueue_get(a_uint32_t dev_id, a_uint32_t pri, + a_uint32_t * queue) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_COSMAP_PRI_TO_EHQU_GET, dev_id, pri, queue); + return rv; +} + +sw_error_t +fal_cosmap_egress_remark_set(a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_COSMAP_EG_REMARK_SET, dev_id, tbl_id, tbl); + return rv; +} + +sw_error_t +fal_cosmap_egress_remark_get(a_uint32_t dev_id, a_uint32_t tbl_id, + fal_egress_remark_table_t * tbl) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_COSMAP_EG_REMARK_GET, dev_id, tbl_id, tbl); + return rv; +} + +sw_error_t +fal_cosmap_dscp_to_ehpri_set(a_uint32_t dev_id, a_uint32_t dscp, a_uint32_t pri) +{ + sw_error_t rv; + + rv= sw_uk_exec(SW_API_COSMAP_DSCP_TO_EHPRI_SET, dev_id, dscp, pri); + return rv; +} + +sw_error_t +fal_cosmap_dscp_to_ehpri_get(a_uint32_t dev_id, a_uint32_t dscp, a_uint32_t * pri) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_COSMAP_DSCP_TO_EHPRI_GET, dev_id, dscp, pri); + return rv; +} + +sw_error_t +fal_cosmap_dscp_to_ehdp_set(a_uint32_t dev_id, a_uint32_t dscp, a_uint32_t dp) +{ + sw_error_t rv; + + rv= sw_uk_exec(SW_API_COSMAP_DSCP_TO_EHDP_SET, dev_id, dscp, dp); + return rv; +} + +sw_error_t +fal_cosmap_dscp_to_ehdp_get(a_uint32_t dev_id, a_uint32_t dscp, a_uint32_t * dp) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_COSMAP_DSCP_TO_EHDP_GET, dev_id, dscp, dp); + return rv; +} + +sw_error_t +fal_cosmap_up_to_ehpri_set(a_uint32_t dev_id, a_uint32_t up, a_uint32_t pri) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_COSMAP_UP_TO_EHPRI_SET, dev_id, up, pri); + return rv; +} + +sw_error_t +fal_cosmap_up_to_ehpri_get(a_uint32_t dev_id, a_uint32_t up, a_uint32_t * pri) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_COSMAP_UP_TO_EHPRI_GET, dev_id, up, pri); + return rv; +} + +sw_error_t +fal_cosmap_up_to_ehdp_set(a_uint32_t dev_id, a_uint32_t up, a_uint32_t dp) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_COSMAP_UP_TO_EHDP_SET, dev_id, up, dp); + return rv; +} + +sw_error_t +fal_cosmap_up_to_ehdp_get(a_uint32_t dev_id, a_uint32_t up, a_uint32_t * dp) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_COSMAP_UP_TO_EHDP_GET, dev_id, up, dp); + return rv; +} \ No newline at end of file diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_ctrlpkt.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_ctrlpkt.c new file mode 100755 index 000000000..af661c9fe --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_ctrlpkt.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_ctrlpkt.h" +#include "fal_uk_if.h" + +sw_error_t +fal_mgmtctrl_ethtype_profile_set(a_uint32_t dev_id, a_uint32_t profile_id, a_uint32_t ethtype) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MGMTCTRL_ETHTYPE_PROFILE_SET, dev_id, profile_id, + (a_uint32_t) ethtype); + return rv; +} + +sw_error_t +fal_mgmtctrl_ethtype_profile_get(a_uint32_t dev_id, a_uint32_t profile_id, a_uint32_t * ethtype) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MGMTCTRL_ETHTYPE_PROFILE_GET, dev_id, profile_id, + ethtype); + return rv; +} + +sw_error_t +fal_mgmtctrl_rfdb_profile_set(a_uint32_t dev_id, a_uint32_t profile_id, fal_mac_addr_t *addr) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MGMTCTRL_RFDB_PROFILE_SET, dev_id, profile_id, + addr); + return rv; +} + +sw_error_t +fal_mgmtctrl_rfdb_profile_get(a_uint32_t dev_id, a_uint32_t profile_id, fal_mac_addr_t *addr) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MGMTCTRL_RFDB_PROFILE_GET, dev_id, profile_id, + addr); + return rv; +} + +sw_error_t +fal_mgmtctrl_ctrlpkt_profile_add(a_uint32_t dev_id, fal_ctrlpkt_profile_t *ctrlpkt) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MGMTCTRL_CTRLPKT_PROFILE_ADD, dev_id, ctrlpkt); + return rv; +} + +sw_error_t +fal_mgmtctrl_ctrlpkt_profile_del(a_uint32_t dev_id, fal_ctrlpkt_profile_t *ctrlpkt) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MGMTCTRL_CTRLPKT_PROFILE_DEL, dev_id, ctrlpkt); + return rv; +} + +sw_error_t +fal_mgmtctrl_ctrlpkt_profile_getfirst(a_uint32_t dev_id, fal_ctrlpkt_profile_t *ctrlpkt) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MGMTCTRL_CTRLPKT_PROFILE_GETFIRST, dev_id, ctrlpkt); + return rv; +} + +sw_error_t +fal_mgmtctrl_ctrlpkt_profile_getnext(a_uint32_t dev_id, fal_ctrlpkt_profile_t *ctrlpkt) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MGMTCTRL_CTRLPKT_PROFILE_GETNEXT, dev_id, ctrlpkt); + return rv; +} diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_fdb.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_fdb.c new file mode 100755 index 000000000..1f62e278b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_fdb.c @@ -0,0 +1,459 @@ +/* + * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_fdb.h" +#include "fal_uk_if.h" + +sw_error_t +fal_fdb_entry_add(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_ADD, dev_id, entry); + return rv; +} + +sw_error_t +fal_fdb_entry_flush(a_uint32_t dev_id, a_uint32_t flag) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_DELALL, dev_id, flag); + return rv; +} + +sw_error_t +fal_fdb_entry_del_byport(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t flag) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_DELPORT, dev_id, port_id, flag); + return rv; +} + +sw_error_t +fal_fdb_entry_del_bymac(a_uint32_t dev_id, const fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_DELMAC, dev_id, entry); + return rv; +} + +sw_error_t +fal_fdb_entry_getfirst(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_FIRST, dev_id, entry); + return rv; +} + +sw_error_t +fal_fdb_entry_getnext(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_NEXT, dev_id, entry); + return rv; +} + +sw_error_t +fal_fdb_entry_search(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_FIND, dev_id, entry); + return rv; +} + +sw_error_t +fal_fdb_port_learn_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_PT_LEARN_SET, dev_id, port_id, + (a_uint32_t) enable); + return rv; +} + +sw_error_t +fal_fdb_port_learn_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_PT_LEARN_GET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_fdb_port_learning_ctrl_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_PT_NEWADDR_LEARN_SET, dev_id, port_id, + enable, cmd); + return rv; +} + +sw_error_t +fal_fdb_port_learning_ctrl_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable, fal_fwd_cmd_t *cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_PT_NEWADDR_LEARN_GET, dev_id, port_id, + enable, cmd); + return rv; +} + +sw_error_t +fal_fdb_port_stamove_ctrl_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_PT_STAMOVE_SET, dev_id, port_id, + enable, cmd); + return rv; +} + +sw_error_t +fal_fdb_port_stamove_ctrl_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable, fal_fwd_cmd_t *cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_PT_STAMOVE_GET, dev_id, port_id, + enable, cmd); + return rv; +} + +sw_error_t +fal_fdb_aging_ctrl_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_AGE_CTRL_SET, dev_id, (a_uint32_t) enable); + return rv; +} + +sw_error_t +fal_fdb_aging_ctrl_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_AGE_CTRL_GET, dev_id, enable); + return rv; +} + +sw_error_t +fal_fdb_learning_ctrl_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_LEARN_CTRL_SET, dev_id, (a_uint32_t) enable); + return rv; +} + +sw_error_t +fal_fdb_learning_ctrl_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_LEARN_CTRL_GET, dev_id, enable); + return rv; +} + +sw_error_t +fal_fdb_vlan_ivl_svl_set(a_uint32_t dev_id, fal_fdb_smode smode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_VLAN_IVL_SVL_SET, dev_id, (a_uint32_t) smode); + return rv; +} + +sw_error_t +fal_fdb_vlan_ivl_svl_get(a_uint32_t dev_id, fal_fdb_smode* smode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_VLAN_IVL_SVL_GET, dev_id, smode); + return rv; +} + +sw_error_t +fal_fdb_aging_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_AGE_TIME_SET, dev_id, time); + return rv; +} + +sw_error_t +fal_fdb_aging_time_get(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_AGE_TIME_GET, dev_id, time); + return rv; +} + +sw_error_t +fal_fdb_entry_getnext_byindex(a_uint32_t dev_id, a_uint32_t * iterator, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_ITERATE, dev_id, iterator, entry); + return rv; +} + +sw_error_t +fal_fdb_entry_extend_getnext(a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_EXTEND_NEXT, dev_id, option, entry); + return rv; +} + +sw_error_t +fal_fdb_entry_extend_getfirst(a_uint32_t dev_id, fal_fdb_op_t * option, + fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_EXTEND_FIRST, dev_id, option, entry); + return rv; +} + +sw_error_t +fal_fdb_entry_update_byport(a_uint32_t dev_id, fal_port_t old_port, fal_port_t new_port, + a_uint32_t fid, fal_fdb_op_t * option) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_TRANSFER, dev_id, old_port, new_port, fid, option); + return rv; +} + +sw_error_t +fal_fdb_port_learned_mac_counter_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * cnt) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_FDB_LEARN_COUNTER_GET, dev_id, port_id, cnt); + return rv; +} + +sw_error_t +fal_port_fdb_learn_limit_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, a_uint32_t cnt) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_FDB_LEARN_LIMIT_SET, dev_id, port_id, enable, cnt); + return rv; +} + +sw_error_t +fal_port_fdb_learn_limit_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable, a_uint32_t * cnt) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_FDB_LEARN_LIMIT_GET, dev_id, port_id, enable, cnt); + return rv; +} + +sw_error_t +fal_port_fdb_learn_exceed_cmd_set(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_FDB_LEARN_EXCEED_CMD_SET, dev_id, port_id, (a_uint32_t)cmd); + return rv; +} + +sw_error_t +fal_port_fdb_learn_exceed_cmd_get(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_FDB_LEARN_EXCEED_CMD_GET, dev_id, port_id, cmd); + return rv; +} + +sw_error_t +fal_fdb_learn_limit_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t cnt) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_LEARN_LIMIT_SET, dev_id, enable, cnt); + return rv; +} + +sw_error_t +fal_fdb_learn_limit_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * cnt) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_LEARN_LIMIT_GET, dev_id, enable, cnt); + return rv; +} + +sw_error_t +fal_fdb_learn_exceed_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_LEARN_EXCEED_CMD_SET, dev_id, (a_uint32_t)cmd); + return rv; +} + +sw_error_t +fal_fdb_learn_exceed_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_LEARN_EXCEED_CMD_GET, dev_id, cmd); + return rv; +} + +sw_error_t +fal_fdb_resv_add(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_RESV_ADD, dev_id, entry); + return rv; +} + +sw_error_t +fal_fdb_resv_del(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_RESV_DEL, dev_id, entry); + return rv; +} + +sw_error_t +fal_fdb_resv_find(a_uint32_t dev_id, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_RESV_FIND, dev_id, entry); + return rv; +} + +sw_error_t +fal_fdb_resv_iterate(a_uint32_t dev_id, a_uint32_t * iterator, fal_fdb_entry_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_RESV_ITERATE, dev_id, iterator, entry); + return rv; +} + +sw_error_t +fal_fdb_port_learn_static_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_PT_LEARN_STATIC_SET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_fdb_port_learn_static_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_PT_LEARN_STATIC_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_fdb_port_add(a_uint32_t dev_id, a_uint32_t fid, fal_mac_addr_t * addr, fal_port_t port_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_PORT_ADD, dev_id, fid, addr, port_id); + return rv; +} + +sw_error_t +fal_fdb_port_del(a_uint32_t dev_id, a_uint32_t fid, fal_mac_addr_t * addr, fal_port_t port_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_PORT_DEL, dev_id, fid, addr, port_id); + return rv; +} + +sw_error_t +fal_fdb_rfs_set(a_uint32_t dev_id, fal_fdb_rfs_t *rfs) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_RFS_SET, dev_id, rfs); + return rv; +} + +sw_error_t +fal_fdb_rfs_del(a_uint32_t dev_id, fal_fdb_rfs_t *rfs) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_RFS_DEL, dev_id, rfs); + return rv; +} + +sw_error_t +fal_fdb_port_maclimit_ctrl_set(a_uint32_t dev_id, fal_port_t port_id, fal_maclimit_ctrl_t * maclimit_ctrl) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_PT_MACLIMIT_CTRL_SET, dev_id, port_id, maclimit_ctrl); + return rv; +} + +sw_error_t +fal_fdb_port_maclimit_ctrl_get(a_uint32_t dev_id, fal_port_t port_id, fal_maclimit_ctrl_t * maclimit_ctrl) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_PT_MACLIMIT_CTRL_GET, dev_id, port_id, maclimit_ctrl); + return rv; +} + +sw_error_t +fal_fdb_entry_del_byfid(a_uint32_t dev_id, a_uint16_t fid, a_uint32_t flag) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FDB_DEL_BY_FID, dev_id, fid, flag); + return rv; +} + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_flow.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_flow.c new file mode 100755 index 000000000..8276c0eae --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_flow.c @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_flow.h" +#include "fal_uk_if.h" + + +sw_error_t +fal_flow_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_STATUS_SET, dev_id, (a_uint32_t) enable); + return rv; +} + +sw_error_t +fal_flow_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_STATUS_GET, dev_id, enable); + return rv; +} + +sw_error_t +fal_flow_age_timer_set(a_uint32_t dev_id, fal_flow_age_timer_t *age_timer) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_AGE_TIMER_SET, dev_id, age_timer); + return rv; +} + +sw_error_t +fal_flow_age_timer_get(a_uint32_t dev_id, fal_flow_age_timer_t *age_timer) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_AGE_TIMER_GET, dev_id, age_timer); + return rv; +} + +sw_error_t +fal_flow_mgmt_set( + a_uint32_t dev_id, + fal_flow_pkt_type_t type, + fal_flow_direction_t dir, + fal_flow_mgmt_t *mgmt) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_CTRL_SET, dev_id, type, dir, mgmt); + return rv; +} + +sw_error_t +fal_flow_mgmt_get( + a_uint32_t dev_id, + fal_flow_pkt_type_t type, + fal_flow_direction_t dir, + fal_flow_mgmt_t *mgmt) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_CTRL_GET, dev_id, type, dir, mgmt); + return rv; +} + +sw_error_t +fal_flow_entry_add( + a_uint32_t dev_id, + a_uint32_t add_mode, /*index or hash*/ + fal_flow_entry_t *flow_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_ENTRY_ADD, dev_id, add_mode, flow_entry); + return rv; +} + +sw_error_t +fal_flow_entry_del( + a_uint32_t dev_id, + a_uint32_t del_mode, + fal_flow_entry_t *flow_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_ENTRY_DEL, dev_id, del_mode, flow_entry); + return rv; +} + +sw_error_t +fal_flow_entry_next( + a_uint32_t dev_id, + a_uint32_t next_mode, + fal_flow_entry_t *flow_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOWENTRY_NEXT, dev_id, next_mode, flow_entry); + return rv; +} + +sw_error_t +fal_flow_entry_get( + a_uint32_t dev_id, + a_uint32_t get_mode, + fal_flow_entry_t *flow_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_ENTRY_GET, dev_id, get_mode, flow_entry); + return rv; +} + +sw_error_t +fal_flow_global_cfg_get( + a_uint32_t dev_id, + fal_flow_global_cfg_t *cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_GLOBAL_CFG_GET, dev_id, cfg); + return rv; +} + +sw_error_t +fal_flow_global_cfg_set( + a_uint32_t dev_id, + fal_flow_global_cfg_t *cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_GLOBAL_CFG_SET, dev_id, cfg); + return rv; +} + +sw_error_t +fal_flow_host_add( + a_uint32_t dev_id, + a_uint32_t add_mode, /*index or hash*/ + fal_flow_host_entry_t *flow_host_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_HOST_ADD, dev_id, add_mode, flow_host_entry); + return rv; +} + +sw_error_t +fal_flow_host_del( + a_uint32_t dev_id, + a_uint32_t del_mode, + fal_flow_host_entry_t *flow_host_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_HOST_DEL, dev_id, del_mode, flow_host_entry); + return rv; +} + +sw_error_t +fal_flow_host_get( + a_uint32_t dev_id, + a_uint32_t get_mode, + fal_flow_host_entry_t *flow_host_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_HOST_GET, dev_id, get_mode, flow_host_entry); + return rv; +} + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_igmp.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_igmp.c new file mode 100755 index 000000000..b0728fd97 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_igmp.c @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_igmp.h" +#include "fal_uk_if.h" + +sw_error_t +fal_port_igmps_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_IGMPS_MODE_SET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_igmps_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_IGMPS_MODE_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_igmp_mld_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IGMP_MLD_CMD_SET, dev_id, cmd); + return rv; +} + +sw_error_t +fal_igmp_mld_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IGMP_MLD_CMD_GET, dev_id, cmd); + return rv; +} + +sw_error_t +fal_port_igmp_mld_join_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IGMP_PT_JOIN_SET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_igmp_mld_join_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IGMP_PT_JOIN_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_igmp_mld_leave_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IGMP_PT_LEAVE_SET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_igmp_mld_leave_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IGMP_PT_LEAVE_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_igmp_mld_rp_set(a_uint32_t dev_id, fal_pbmp_t pts) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IGMP_RP_SET, dev_id, pts); + return rv; +} + +sw_error_t +fal_igmp_mld_rp_get(a_uint32_t dev_id, fal_pbmp_t * pts) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IGMP_RP_GET, dev_id, pts); + return rv; +} + +sw_error_t +fal_igmp_mld_entry_creat_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IGMP_ENTRY_CREAT_SET, dev_id, enable); + return rv; +} + +sw_error_t +fal_igmp_mld_entry_creat_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IGMP_ENTRY_CREAT_GET, dev_id, enable); + return rv; +} + +sw_error_t +fal_igmp_mld_entry_static_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IGMP_ENTRY_STATIC_SET, dev_id, enable); + return rv; +} + +sw_error_t +fal_igmp_mld_entry_static_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IGMP_ENTRY_STATIC_GET, dev_id, enable); + return rv; +} + +sw_error_t +fal_igmp_mld_entry_leaky_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IGMP_ENTRY_LEAKY_SET, dev_id, enable); + return rv; +} + +sw_error_t +fal_igmp_mld_entry_leaky_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IGMP_ENTRY_LEAKY_GET, dev_id, enable); + return rv; +} + +sw_error_t +fal_igmp_mld_entry_v3_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IGMP_ENTRY_V3_SET, dev_id, enable); + return rv; +} + +sw_error_t +fal_igmp_mld_entry_v3_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IGMP_ENTRY_V3_GET, dev_id, enable); + return rv; +} + +sw_error_t +fal_igmp_mld_entry_queue_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t queue) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IGMP_ENTRY_QUEUE_SET, dev_id, enable, queue); + return rv; +} + +sw_error_t +fal_igmp_mld_entry_queue_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * queue) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IGMP_ENTRY_QUEUE_GET, dev_id, enable, queue); + return rv; +} + +sw_error_t +fal_port_igmp_mld_learn_limit_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, a_uint32_t cnt) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_IGMP_LEARN_LIMIT_SET, dev_id, port_id, enable, cnt); + return rv; +} + +sw_error_t +fal_port_igmp_mld_learn_limit_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable, a_uint32_t * cnt) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_IGMP_LEARN_LIMIT_GET, dev_id, port_id, enable, cnt); + return rv; +} + +sw_error_t +fal_port_igmp_mld_learn_exceed_cmd_set(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_IGMP_LEARN_EXCEED_CMD_SET, dev_id, port_id, cmd); + return rv; +} + +sw_error_t +fal_port_igmp_mld_learn_exceed_cmd_get(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_IGMP_LEARN_EXCEED_CMD_GET, dev_id, port_id, cmd); + return rv; +} + +sw_error_t +fal_igmp_sg_entry_set(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IGMP_SG_ENTRY_SET, dev_id, entry); + return rv; +} + +sw_error_t +fal_igmp_sg_entry_clear(a_uint32_t dev_id, fal_igmp_sg_entry_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IGMP_SG_ENTRY_CLEAR, dev_id, entry); + return rv; +} + +sw_error_t +fal_igmp_sg_entry_show(a_uint32_t dev_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IGMP_SG_ENTRY_SHOW, dev_id); + return rv; +} + +sw_error_t +fal_igmp_sg_entry_query(a_uint32_t dev_id, fal_igmp_sg_info_t * info) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IGMP_SG_ENTRY_QUERY, dev_id, info); + return rv; +} + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_init.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_init.c new file mode 100755 index 000000000..0654a9c94 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_init.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2014, 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/*qca808x_start*/ +#include "sw.h" +#include "sw_ioctl.h" +#include "ssdk_init.h" +#include "fal_init.h" +#include "fal_uk_if.h" +/*qca808x_end*/ +sw_error_t +fal_reset(a_uint32_t dev_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SWITCH_RESET, dev_id); + return rv; +} +/*qca808x_start*/ +sw_error_t +fal_ssdk_cfg(a_uint32_t dev_id, ssdk_cfg_t *ssdk_cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SSDK_CFG, dev_id, ssdk_cfg); + return rv; +} +/*qca808x_end*/ +sw_error_t +fal_module_func_ctrl_set(a_uint32_t dev_id, a_uint32_t module, fal_func_ctrl_t *func_ctrl) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MODULE_FUNC_CTRL_SET, dev_id, module, func_ctrl); + return rv; +} + +sw_error_t +fal_module_func_ctrl_get(a_uint32_t dev_id, a_uint32_t module, fal_func_ctrl_t *func_ctrl) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MODULE_FUNC_CTRL_GET, dev_id, module, func_ctrl); + return rv; +} + + + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_interface_ctrl.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_interface_ctrl.c new file mode 100755 index 000000000..ef26a72c6 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_interface_ctrl.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_interface_ctrl.h" +#include "fal_uk_if.h" + +sw_error_t +fal_port_3az_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PORT_3AZ_STATUS_SET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_3az_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PORT_3AZ_STATUS_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_interface_mac_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_mac_config_t * config) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MAC_MODE_SET, dev_id, port_id, config); + return rv; +} + +sw_error_t +fal_interface_mac_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_mac_config_t * config) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MAC_MODE_GET, dev_id, port_id, config); + return rv; +} + +sw_error_t +fal_interface_phy_mode_set(a_uint32_t dev_id, a_uint32_t phy_id, fal_phy_config_t * config) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PHY_MODE_SET, dev_id, phy_id, config); + return rv; +} + +sw_error_t +fal_interface_phy_mode_get(a_uint32_t dev_id, a_uint32_t phy_id, fal_phy_config_t * config) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PHY_MODE_GET, dev_id, phy_id, config); + return rv; +} + +sw_error_t +fal_interface_fx100_ctrl_set(a_uint32_t dev_id, fal_fx100_ctrl_config_t * config) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FX100_CTRL_SET, dev_id, config); + return rv; +} + +sw_error_t +fal_interface_fx100_ctrl_get(a_uint32_t dev_id, fal_fx100_ctrl_config_t * config) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FX100_CTRL_GET, dev_id, config); + return rv; +} + +sw_error_t +fal_interface_fx100_status_get(a_uint32_t dev_id, a_uint32_t *status) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FX100_STATUS_GET, dev_id, status); + return rv; +} + +sw_error_t +fal_interface_mac06_exch_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MAC06_EXCH_SET, dev_id, enable); + return rv; +} + +sw_error_t +fal_interface_mac06_exch_get(a_uint32_t dev_id, a_bool_t* enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MAC06_EXCH_GET, dev_id, enable); + return rv; +} diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_ip.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_ip.c new file mode 100755 index 000000000..59f9cd6eb --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_ip.c @@ -0,0 +1,728 @@ +/* + * Copyright (c) 2014, 2015, 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_ip.h" +#include "fal_uk_if.h" + + +sw_error_t +fal_ip_host_add(a_uint32_t dev_id, fal_host_entry_t * host_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_HOST_ADD, dev_id, host_entry); + return rv; +} + +sw_error_t +fal_ip_host_del(a_uint32_t dev_id, a_uint32_t del_mode, fal_host_entry_t * host_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_HOST_DEL, dev_id, del_mode, host_entry); + return rv; +} + +sw_error_t +fal_ip_host_get(a_uint32_t dev_id, a_uint32_t get_mode, fal_host_entry_t * host_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_HOST_GET, dev_id, get_mode, host_entry); + return rv; +} + +sw_error_t +fal_ip_host_next(a_uint32_t dev_id, a_uint32_t next_mode, fal_host_entry_t * host_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_HOST_NEXT, dev_id, next_mode, host_entry); + return rv; +} + +sw_error_t +fal_ip_host_counter_bind(a_uint32_t dev_id, a_uint32_t entry_id, a_uint32_t cnt_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_HOST_COUNTER_BIND, dev_id, entry_id, cnt_id, (a_uint32_t) enable); + return rv; +} + +sw_error_t +fal_ip_host_pppoe_bind(a_uint32_t dev_id, a_uint32_t entry_id, a_uint32_t pppoe_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_HOST_PPPOE_BIND, dev_id, entry_id, pppoe_id, (a_uint32_t) enable); + return rv; +} + +sw_error_t +fal_ip_pt_arp_learn_set(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t flags) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_PT_ARP_LEARN_SET, dev_id, port_id, flags); + return rv; +} + +sw_error_t +fal_ip_pt_arp_learn_get(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t * flags) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_PT_ARP_LEARN_GET, dev_id, port_id, flags); + return rv; +} + +sw_error_t +fal_ip_arp_learn_set(a_uint32_t dev_id, fal_arp_learn_mode_t mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_ARP_LEARN_SET, dev_id, (a_uint32_t)mode); + return rv; +} + +sw_error_t +fal_ip_arp_learn_get(a_uint32_t dev_id, fal_arp_learn_mode_t * mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_ARP_LEARN_GET, dev_id, mode); + return rv; +} + +sw_error_t +fal_ip_source_guard_set(a_uint32_t dev_id, fal_port_t port_id, fal_source_guard_mode_t mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_SOURCE_GUARD_SET, dev_id, port_id, (a_uint32_t)mode); + return rv; +} + +sw_error_t +fal_ip_source_guard_get(a_uint32_t dev_id, fal_port_t port_id, fal_source_guard_mode_t * mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_SOURCE_GUARD_GET, dev_id, port_id, mode); + return rv; +} + +sw_error_t +fal_ip_arp_guard_set(a_uint32_t dev_id, fal_port_t port_id, fal_source_guard_mode_t mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_ARP_GUARD_SET, dev_id, port_id, (a_uint32_t)mode); + return rv; +} + +sw_error_t +fal_ip_arp_guard_get(a_uint32_t dev_id, fal_port_t port_id, fal_source_guard_mode_t * mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_ARP_GUARD_GET, dev_id, port_id, mode); + return rv; +} + +sw_error_t +fal_ip_route_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_ROUTE_STATUS_SET, dev_id, (a_uint32_t) enable); + return rv; +} + +sw_error_t +fal_ip_route_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_ROUTE_STATUS_GET, dev_id, enable); + return rv; +} + +sw_error_t +fal_ip_intf_entry_add(a_uint32_t dev_id, fal_intf_mac_entry_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_INTF_ENTRY_ADD, dev_id, entry); + return rv; +} + +sw_error_t +fal_ip_intf_entry_del(a_uint32_t dev_id, a_uint32_t del_mode, fal_intf_mac_entry_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_INTF_ENTRY_DEL, dev_id, del_mode, entry); + return rv; +} + +sw_error_t +fal_ip_intf_entry_next(a_uint32_t dev_id, a_uint32_t next_mode, fal_intf_mac_entry_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_INTF_ENTRY_NEXT, dev_id, next_mode, entry); + return rv; +} + +sw_error_t +fal_ip_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_UNK_SOURCE_CMD_SET, dev_id, (a_uint32_t) cmd); + return rv; +} + +sw_error_t +fal_ip_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_UNK_SOURCE_CMD_GET, dev_id, cmd); + return rv; +} + +sw_error_t +fal_arp_unk_source_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ARP_UNK_SOURCE_CMD_SET, dev_id, (a_uint32_t) cmd); + return rv; +} + +sw_error_t +fal_arp_unk_source_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ARP_UNK_SOURCE_CMD_GET, dev_id, cmd); + return rv; +} + +sw_error_t +fal_ip_age_time_set(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_AGE_TIME_SET, dev_id, time); + return rv; +} + +sw_error_t +fal_ip_age_time_get(a_uint32_t dev_id, a_uint32_t * time) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_AGE_TIME_GET, dev_id, time); + return rv; +} + +sw_error_t +fal_ip_wcmp_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_WCMP_HASH_MODE_SET, dev_id, hash_mode); + return rv; +} + +sw_error_t +fal_ip_wcmp_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_WCMP_HASH_MODE_GET, dev_id, hash_mode); + return rv; +} + +sw_error_t +fal_ip_vrf_base_addr_set(a_uint32_t dev_id, a_uint32_t vrf_id, fal_ip4_addr_t addr) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_VRF_BASE_ADDR_SET, dev_id, vrf_id, addr); + return rv; +} + +sw_error_t +fal_ip_vrf_base_addr_get(a_uint32_t dev_id, a_uint32_t vrf_id, fal_ip4_addr_t * addr) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_VRF_BASE_ADDR_GET, dev_id, vrf_id, addr); + return rv; +} + +sw_error_t +fal_ip_vrf_base_mask_set(a_uint32_t dev_id, a_uint32_t vrf_id, fal_ip4_addr_t addr) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_VRF_BASE_MASK_SET, dev_id, vrf_id, addr); + return rv; +} + +sw_error_t +fal_ip_vrf_base_mask_get(a_uint32_t dev_id, a_uint32_t vrf_id, fal_ip4_addr_t * addr) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_VRF_BASE_MASK_GET, dev_id, vrf_id, addr); + return rv; +} + +sw_error_t +fal_ip_default_route_set(a_uint32_t dev_id, a_uint32_t droute_id, + fal_default_route_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_DEFAULT_ROUTE_SET, dev_id, droute_id, entry); + return rv; +} + +sw_error_t +fal_ip_default_route_get(a_uint32_t dev_id, a_uint32_t droute_id, + fal_default_route_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_DEFAULT_ROUTE_GET, dev_id, droute_id, entry); + return rv; +} + +sw_error_t +fal_ip_host_route_set(a_uint32_t dev_id, a_uint32_t hroute_id, + fal_host_route_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_HOST_ROUTE_SET, dev_id, hroute_id, entry); + return rv; +} + +sw_error_t +fal_ip_host_route_get(a_uint32_t dev_id, a_uint32_t hroute_id, + fal_host_route_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_HOST_ROUTE_GET, dev_id, hroute_id, entry); + return rv; +} + +sw_error_t +fal_ip_wcmp_entry_set(a_uint32_t dev_id, a_uint32_t wcmp_id, + fal_ip_wcmp_t * wcmp) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_WCMP_ENTRY_SET, dev_id, wcmp_id, wcmp); + return rv; +} + + +sw_error_t +fal_ip_wcmp_entry_get(a_uint32_t dev_id, a_uint32_t wcmp_id, + fal_ip_wcmp_t * wcmp) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_WCMP_ENTRY_GET, dev_id, wcmp_id, wcmp); + return rv; +} + +sw_error_t +fal_ip_rfs_ip4_rule_set(a_uint32_t dev_id, + fal_ip4_rfs_t * rfs) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_RFS_IP4_SET, dev_id, rfs); + return rv; +} + +sw_error_t +fal_ip_rfs_ip6_rule_set(a_uint32_t dev_id, + fal_ip6_rfs_t * rfs) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_RFS_IP6_SET, dev_id, rfs); + return rv; +} + +sw_error_t +fal_ip_rfs_ip4_rule_del(a_uint32_t dev_id, + fal_ip4_rfs_t * rfs) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_RFS_IP4_DEL, dev_id, rfs); + return rv; +} + +sw_error_t +fal_ip_rfs_ip6_rule_del(a_uint32_t dev_id, + fal_ip6_rfs_t * rfs) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_RFS_IP6_DEL, dev_id, rfs); + return rv; +} + +sw_error_t +fal_default_flow_cmd_set(a_uint32_t dev_id, a_uint32_t vrf_id, + fal_flow_type_t type, fal_default_flow_cmd_t cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_DEFAULT_FLOW_CMD_SET, dev_id, vrf_id, type, (a_uint32_t) cmd); + return rv; +} + +sw_error_t +fal_default_flow_cmd_get(a_uint32_t dev_id, a_uint32_t vrf_id, + fal_flow_type_t type, fal_default_flow_cmd_t * cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_DEFAULT_FLOW_CMD_GET, dev_id, vrf_id, type, cmd); + return rv; +} + +sw_error_t +fal_default_rt_flow_cmd_set(a_uint32_t dev_id, a_uint32_t vrf_id, + fal_flow_type_t type, fal_default_flow_cmd_t cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_DEFAULT_RT_FLOW_CMD_SET, dev_id, vrf_id, type, (a_uint32_t) cmd); + return rv; +} + +sw_error_t +fal_default_rt_flow_cmd_get(a_uint32_t dev_id, a_uint32_t vrf_id, + fal_flow_type_t type, fal_default_flow_cmd_t * cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_DEFAULT_RT_FLOW_CMD_GET, dev_id, vrf_id, type, cmd); + return rv; +} + +sw_error_t +fal_ip_vsi_arp_sg_cfg_set(a_uint32_t dev_id, a_uint32_t vsi, + fal_arp_sg_cfg_t *arp_sg_cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_VIS_ARP_SG_CFG_SET, dev_id, vsi, arp_sg_cfg); + return rv; +} + +sw_error_t +fal_ip_vsi_arp_sg_cfg_get(a_uint32_t dev_id, a_uint32_t vsi, + fal_arp_sg_cfg_t *arp_sg_cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_VIS_ARP_SG_CFG_GET, dev_id, vsi, arp_sg_cfg); + return rv; +} + +sw_error_t +fal_ip_network_route_add(a_uint32_t dev_id, + a_uint32_t index, + fal_network_route_entry_t *entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_NETWORK_ROUTE_ADD, dev_id, index, entry); + return rv; +} + +sw_error_t +fal_ip_network_route_get(a_uint32_t dev_id, + a_uint32_t index, a_uint8_t type, + fal_network_route_entry_t *entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_NETWORK_ROUTE_GET, dev_id, index, type, entry); + return rv; +} + +sw_error_t +fal_ip_intf_set( + a_uint32_t dev_id, + a_uint32_t index, + fal_intf_entry_t *entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_INTF_SET, dev_id, index, entry); + return rv; +} + +sw_error_t +fal_ip_intf_get( + a_uint32_t dev_id, + a_uint32_t index, + fal_intf_entry_t *entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_INTF_GET, dev_id, index, entry); + return rv; +} + +sw_error_t +fal_ip_vsi_intf_set(a_uint32_t dev_id, a_uint32_t vsi, fal_intf_id_t *id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_VSI_INTF_SET, dev_id, vsi, id); + return rv; +} + +sw_error_t +fal_ip_vsi_intf_get(a_uint32_t dev_id, a_uint32_t vsi, fal_intf_id_t *id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_VSI_INTF_GET, dev_id, vsi, id); + return rv; +} + +sw_error_t +fal_ip_port_intf_set(a_uint32_t dev_id, fal_port_t port_id, fal_intf_id_t *id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_PORT_INTF_SET, dev_id, port_id, id); + return rv; +} + +sw_error_t +fal_ip_port_intf_get(a_uint32_t dev_id, fal_port_t port_id, fal_intf_id_t *id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_PORT_INTF_GET, dev_id, port_id, id); + return rv; +} + +sw_error_t +fal_ip_nexthop_set(a_uint32_t dev_id, a_uint32_t index, + fal_ip_nexthop_t *entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_NEXTHOP_SET, dev_id, index, entry); + return rv; +} + +sw_error_t +fal_ip_nexthop_get(a_uint32_t dev_id, a_uint32_t index, + fal_ip_nexthop_t *entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_NEXTHOP_GET, dev_id, index, entry); + return rv; +} + +sw_error_t +fal_ip_port_sg_cfg_set(a_uint32_t dev_id, fal_port_t port_id, + fal_sg_cfg_t *sg_cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_PORT_SG_SET, dev_id, port_id, sg_cfg); + return rv; +} + +sw_error_t +fal_ip_port_sg_cfg_get(a_uint32_t dev_id, fal_port_t port_id, + fal_sg_cfg_t *sg_cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_PORT_SG_GET, dev_id, port_id, sg_cfg); + return rv; +} + +sw_error_t +fal_ip_vsi_sg_cfg_get(a_uint32_t dev_id, a_uint32_t vsi, + fal_sg_cfg_t *sg_cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_VSI_SG_GET, dev_id, vsi, sg_cfg); + return rv; +} + +sw_error_t +fal_ip_vsi_sg_cfg_set(a_uint32_t dev_id, a_uint32_t vsi, + fal_sg_cfg_t *sg_cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_VSI_SG_SET, dev_id, vsi, sg_cfg); + return rv; +} + +sw_error_t +fal_ip_pub_addr_set(a_uint32_t dev_id, a_uint32_t index, + fal_ip_pub_addr_t *entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_PUB_IP_SET, dev_id, index, entry); + return rv; +} + +sw_error_t +fal_ip_network_route_del(a_uint32_t dev_id, a_uint32_t index, a_uint8_t type) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_NETWORK_ROUTE_DEL, dev_id, index, type); + return rv; +} + +sw_error_t +fal_ip_pub_addr_get(a_uint32_t dev_id, a_uint32_t index, fal_ip_pub_addr_t *entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_PUB_IP_GET, dev_id, index, entry); + return rv; +} + +sw_error_t + fal_ip_port_macaddr_set(a_uint32_t dev_id, fal_port_t port_id, + fal_macaddr_entry_t *macaddr) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_PORT_MAC_SET, dev_id, port_id, macaddr); + return rv; +} + +sw_error_t +fal_ip_port_macaddr_get(a_uint32_t dev_id, fal_port_t port_id, + fal_macaddr_entry_t *macaddr) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_PORT_MAC_GET, dev_id, port_id, macaddr); + return rv; +} + +sw_error_t +fal_ip_route_mismatch_action_set(a_uint32_t dev_id, fal_fwd_cmd_t action) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_ROUTE_MISS_SET, dev_id, (a_uint32_t)action); + return rv; +} + +sw_error_t +fal_ip_route_mismatch_action_get(a_uint32_t dev_id, fal_fwd_cmd_t *action) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_ROUTE_MISS_GET, dev_id, action); + return rv; +} + +sw_error_t +fal_ip_port_arp_sg_cfg_set(a_uint32_t dev_id, fal_port_t port_id, + fal_arp_sg_cfg_t *arp_sg_cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_PORT_ARP_SG_SET, dev_id, port_id, arp_sg_cfg); + return rv; +} + +sw_error_t +fal_ip_port_arp_sg_cfg_get(a_uint32_t dev_id, fal_port_t port_id, + fal_arp_sg_cfg_t *arp_sg_cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_PORT_ARP_SG_GET, dev_id, port_id, arp_sg_cfg); + return rv; +} + +sw_error_t +fal_ip_vsi_mc_mode_set(a_uint32_t dev_id, a_uint32_t vsi, + fal_mc_mode_cfg_t *cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_VSI_MC_MODE_SET, dev_id, vsi, cfg); + return rv; +} + +sw_error_t +fal_ip_vsi_mc_mode_get(a_uint32_t dev_id, a_uint32_t vsi, + fal_mc_mode_cfg_t *cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_IP_VSI_MC_MODE_GET, dev_id, vsi, cfg); + return rv; +} + +sw_error_t +fal_ip_global_ctrl_get(a_uint32_t dev_id, fal_ip_global_cfg_t *cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_GLOBAL_CTRL_GET, dev_id, cfg); + return rv; +} + +sw_error_t +fal_ip_global_ctrl_set(a_uint32_t dev_id, fal_ip_global_cfg_t *cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_GLOBAL_CTRL_SET, dev_id, cfg); + return rv; +} + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_leaky.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_leaky.c new file mode 100755 index 000000000..917fd4497 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_leaky.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_leaky.h" +#include "fal_uk_if.h" + +sw_error_t +fal_uc_leaky_mode_set(a_uint32_t dev_id, fal_leaky_ctrl_mode_t ctrl_mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_UC_LEAKY_MODE_SET, dev_id, ctrl_mode); + return rv; +} + +sw_error_t +fal_uc_leaky_mode_get(a_uint32_t dev_id, fal_leaky_ctrl_mode_t * ctrl_mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_UC_LEAKY_MODE_GET, dev_id, ctrl_mode); + return rv; +} + +sw_error_t +fal_mc_leaky_mode_set(a_uint32_t dev_id, fal_leaky_ctrl_mode_t ctrl_mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MC_LEAKY_MODE_SET, dev_id, ctrl_mode); + return rv; +} + +sw_error_t +fal_mc_leaky_mode_get(a_uint32_t dev_id, fal_leaky_ctrl_mode_t * ctrl_mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MC_LEAKY_MODE_GET, dev_id, ctrl_mode); + return rv; +} + +sw_error_t +fal_port_arp_leaky_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ARP_LEAKY_MODE_SET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_arp_leaky_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ARP_LEAKY_MODE_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_uc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_UC_LEAKY_MODE_SET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_uc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_UC_LEAKY_MODE_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_mc_leaky_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_MC_LEAKY_MODE_SET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_mc_leaky_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_MC_LEAKY_MODE_GET, dev_id, port_id, enable); + return rv; +} diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_led.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_led.c new file mode 100755 index 000000000..996ea2a90 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_led.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_led.h" +#include "fal_uk_if.h" + + +sw_error_t +fal_led_ctrl_pattern_set(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_LED_PATTERN_SET, dev_id, group, + id, pattern); + return rv; +} + +sw_error_t +fal_led_ctrl_pattern_get(a_uint32_t dev_id, led_pattern_group_t group, + led_pattern_id_t id, led_ctrl_pattern_t * pattern) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_LED_PATTERN_GET, dev_id, group, + id, pattern); + return rv; +} diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_mib.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_mib.c new file mode 100755 index 000000000..aa24b7413 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_mib.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_mib.h" +#include "fal_uk_if.h" + +sw_error_t +fal_get_mib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_info_t * mib_Info) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_MIB_GET, dev_id, port_id, mib_Info); + return rv; +} + +sw_error_t +fal_get_xgmib_info(a_uint32_t dev_id, fal_port_t port_id, + fal_xgmib_info_t * mib_Info) +{ + sw_error_t rv; + rv = sw_uk_exec(SW_API_PT_XGMIB_GET, dev_id, port_id, mib_Info); + return rv; +} +sw_error_t +fal_mib_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MIB_STATUS_SET, dev_id, (a_uint32_t)enable); + return rv; +} + +sw_error_t +fal_mib_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MIB_STATUS_GET, dev_id, enable); + return rv; +} + +sw_error_t +fal_mib_port_flush_counters(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_MIB_FLUSH_COUNTERS, dev_id, port_id); + return rv; +} + +sw_error_t +fal_mib_cpukeep_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MIB_CPU_KEEP_SET, dev_id, (a_uint32_t)enable); + return rv; +} + +sw_error_t +fal_mib_cpukeep_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MIB_CPU_KEEP_GET, dev_id, enable); + return rv; +} + +sw_error_t +fal_mib_counter_get(a_uint32_t dev_id, fal_port_t port_id, + fal_mib_counter_t * mib_Info) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_MIB_COUNTER_GET, dev_id, port_id, mib_Info); + return rv; +} diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_mirror.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_mirror.c new file mode 100755 index 000000000..32b03a52a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_mirror.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2014, 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_mirror.h" +#include "fal_uk_if.h" + +sw_error_t +fal_mirr_analysis_port_set(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MIRROR_ANALY_PT_SET, dev_id, port_id); + return rv; +} + +sw_error_t +fal_mirr_analysis_port_get(a_uint32_t dev_id, fal_port_t * port_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MIRROR_ANALY_PT_GET, dev_id, + port_id); + return rv; +} + +sw_error_t +fal_mirr_port_in_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MIRROR_IN_PT_SET, dev_id, port_id, + (a_uint32_t) enable); + return rv; +} + +sw_error_t +fal_mirr_port_in_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MIRROR_IN_PT_GET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_mirr_port_eg_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MIRROR_EG_PT_SET, dev_id, port_id, + (a_uint32_t) enable); + return rv; +} + +sw_error_t +fal_mirr_port_eg_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MIRROR_EG_PT_GET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_mirr_analysis_config_set(a_uint32_t dev_id, fal_mirr_direction_t direction, fal_mirr_analysis_config_t * config) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MIRROR_ANALYSIS_CONFIG_SET, dev_id, direction, config); + return rv; +} + +sw_error_t +fal_mirr_analysis_config_get(a_uint32_t dev_id, fal_mirr_direction_t direction, fal_mirr_analysis_config_t * config) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MIRROR_ANALYSIS_CONFIG_GET, dev_id, direction, config); + return rv; +} + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_misc.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_misc.c new file mode 100755 index 000000000..de7d21148 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_misc.c @@ -0,0 +1,500 @@ +/* + * Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_misc.h" +#include "fal_uk_if.h" + +sw_error_t +fal_arp_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ARP_STATUS_SET, dev_id, enable); + return rv; +} + +sw_error_t +fal_arp_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ARP_STATUS_GET, dev_id, enable); + return rv; +} + +sw_error_t +fal_frame_max_size_set(a_uint32_t dev_id, a_uint32_t size) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FRAME_MAX_SIZE_SET, dev_id, size); + return rv; +} + +sw_error_t +fal_frame_max_size_get(a_uint32_t dev_id, a_uint32_t * size) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FRAME_MAX_SIZE_GET, dev_id, size); + return rv; +} + +sw_error_t +fal_port_unk_sa_cmd_set(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_UNK_SA_CMD_SET, dev_id, port_id, + cmd); + return rv; +} + +sw_error_t +fal_port_unk_sa_cmd_get(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_UNK_SA_CMD_GET, dev_id, port_id, + cmd); + return rv; +} + +sw_error_t +fal_port_unk_uc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_UNK_UC_FILTER_SET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_port_unk_uc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_UNK_UC_FILTER_GET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_port_unk_mc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_UNK_MC_FILTER_SET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_port_unk_mc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_UNK_MC_FILTER_GET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_port_bc_filter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_BC_FILTER_SET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_port_bc_filter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_BC_FILTER_GET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_cpu_port_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_CPU_PORT_STATUS_SET, dev_id, enable); + return rv; +} + +sw_error_t +fal_cpu_port_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_CPU_PORT_STATUS_GET, dev_id, enable); + return rv; +} + +sw_error_t +fal_bc_to_cpu_port_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_BC_TO_CPU_PORT_SET, dev_id, enable); + return rv; +} + +sw_error_t +fal_bc_to_cpu_port_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_BC_TO_CPU_PORT_GET, dev_id, enable); + return rv; +} + +sw_error_t +fal_port_dhcp_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_DHCP_SET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_dhcp_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_DHCP_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_arp_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ARP_CMD_SET, dev_id, cmd); + return rv; +} + +sw_error_t +fal_arp_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_ARP_CMD_GET, dev_id, cmd); + return rv; +} + +sw_error_t +fal_eapol_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_EAPOL_CMD_SET, dev_id, cmd); + return rv; +} + +sw_error_t +fal_eapol_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_EAPOL_CMD_GET, dev_id, cmd); + return rv; +} + +sw_error_t +fal_eapol_status_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_EAPOL_STATUS_SET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_eapol_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_EAPOL_STATUS_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_ripv1_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RIPV1_STATUS_SET, dev_id, enable); + return rv; +} + +sw_error_t +fal_ripv1_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RIPV1_STATUS_GET, dev_id, enable); + return rv; +} + + +sw_error_t +fal_port_arp_req_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_ARP_REQ_STATUS_SET, dev_id, port_id, enable); + return rv; +} + + +sw_error_t +fal_port_arp_req_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_ARP_REQ_STATUS_GET, dev_id, port_id, enable); + return rv; +} + + +sw_error_t +fal_port_arp_ack_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_ARP_ACK_STATUS_SET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_arp_ack_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t *enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_ARP_ACK_STATUS_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_intr_mask_set(a_uint32_t dev_id, a_uint32_t intr_mask) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_INTR_MASK_SET, dev_id, intr_mask); + return rv; +} + +sw_error_t +fal_intr_mask_get(a_uint32_t dev_id, a_uint32_t * intr_mask) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_INTR_MASK_GET, dev_id, intr_mask); + return rv; +} + +sw_error_t +fal_intr_status_get(a_uint32_t dev_id, a_uint32_t * intr_status) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_INTR_STATUS_GET, dev_id, intr_status); + return rv; +} + +sw_error_t +fal_intr_status_clear(a_uint32_t dev_id, a_uint32_t intr_status) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_INTR_STATUS_CLEAR, dev_id, intr_status); + return rv; +} + +sw_error_t +fal_intr_port_link_mask_set(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t intr_mask) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_INTR_PORT_LINK_MASK_SET, dev_id, port_id, intr_mask); + return rv; +} + +sw_error_t +fal_intr_port_link_mask_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_INTR_PORT_LINK_MASK_GET, dev_id, port_id, intr_mask); + return rv; +} + +sw_error_t +fal_intr_port_link_status_get(a_uint32_t dev_id, a_uint32_t port_id, a_uint32_t * intr_mask) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_INTR_PORT_LINK_STATUS_GET, dev_id, port_id, intr_mask); + return rv; +} + +sw_error_t +fal_intr_mask_mac_linkchg_set(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_INTR_MASK_MAC_LINKCHG_SET, dev_id, port_id, enable); + return rv; +} + + +sw_error_t +fal_intr_mask_mac_linkchg_get(a_uint32_t dev_id, a_uint32_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_INTR_MASK_MAC_LINKCHG_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_intr_status_mac_linkchg_get(a_uint32_t dev_id, fal_pbmp_t *port_bitmap) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_INTR_STATUS_MAC_LINKCHG_GET, dev_id, port_bitmap); + return rv; +} + +sw_error_t +fal_cpu_vid_en_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_CPU_VID_EN_SET, dev_id, enable); + return rv; +} + +sw_error_t +fal_cpu_vid_en_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_CPU_VID_EN_GET, dev_id, enable); + return rv; +} + +sw_error_t +fal_intr_status_mac_linkchg_clear(a_uint32_t dev_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_INTR_STATUS_MAC_LINKCHG_CLEAR, dev_id); + return rv; +} + +sw_error_t +fal_global_macaddr_set(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_GLOBAL_MACADDR_SET, dev_id, addr); + return rv; +} + +sw_error_t +fal_global_macaddr_get(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_GLOBAL_MACADDR_GET, dev_id, addr); + return rv; +} + +sw_error_t +fal_lldp_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_LLDP_STATUS_SET, dev_id, enable); + return rv; +} + +sw_error_t +fal_lldp_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_LLDP_STATUS_GET, dev_id, enable); + return rv; +} + + +sw_error_t +fal_frame_crc_reserve_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FRAME_CRC_RESERVE_SET, dev_id, enable); + return rv; +} + +sw_error_t +fal_frame_crc_reserve_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FRAME_CRC_RESERVE_GET, dev_id, enable); + return rv; +} + +sw_error_t +fal_debug_port_counter_enable(a_uint32_t dev_id, fal_port_t port_id, fal_counter_en_t * cnt_en) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_DEBUG_PORT_COUNTER_ENABLE, dev_id, port_id, cnt_en); + return rv; +} + +sw_error_t +fal_debug_port_counter_status_get(a_uint32_t dev_id, fal_port_t port_id, fal_counter_en_t * cnt_en) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_DEBUG_PORT_COUNTER_STATUS_GET, dev_id, port_id, cnt_en); + return rv; +} diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_nat.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_nat.c new file mode 100755 index 000000000..ec5d0586b --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_nat.c @@ -0,0 +1,360 @@ +/* + * Copyright (c) 2014, 2015, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_nat.h" +#include "fal_uk_if.h" + +sw_error_t +fal_nat_add(a_uint32_t dev_id, fal_nat_entry_t * nat_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NAT_ADD, dev_id, nat_entry); + return rv; +} + + +sw_error_t +fal_nat_del(a_uint32_t dev_id, a_uint32_t del_mode, fal_nat_entry_t * nat_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NAT_DEL, dev_id, del_mode, nat_entry); + return rv; +} + + +sw_error_t +fal_nat_get(a_uint32_t dev_id, a_uint32_t get_mode, fal_nat_entry_t * nat_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NAT_GET, dev_id, get_mode, nat_entry); + return rv; +} + +sw_error_t +fal_nat_next(a_uint32_t dev_id, a_uint32_t next_mode, fal_nat_entry_t * nat_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NAT_NEXT, dev_id, next_mode, nat_entry); + return rv; +} + +sw_error_t +fal_nat_counter_bind(a_uint32_t dev_id, a_uint32_t entry_id, a_uint32_t cnt_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NAT_COUNTER_BIND, dev_id, entry_id, cnt_id, enable); + return rv; +} + + +sw_error_t +fal_napt_add(a_uint32_t dev_id, fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NAPT_ADD, dev_id, napt_entry); + return rv; +} + +sw_error_t +fal_napt_del(a_uint32_t dev_id, a_uint32_t del_mode, fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NAPT_DEL, dev_id, del_mode, napt_entry); + return rv; +} + +sw_error_t +fal_napt_get(a_uint32_t dev_id, a_uint32_t get_mode, fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NAPT_GET, dev_id, get_mode, napt_entry); + return rv; +} + +sw_error_t +fal_napt_next(a_uint32_t dev_id, a_uint32_t next_mode, fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NAPT_NEXT, dev_id, next_mode, napt_entry); + return rv; +} + +sw_error_t +fal_napt_counter_bind(a_uint32_t dev_id, a_uint32_t entry_id, a_uint32_t cnt_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NAPT_COUNTER_BIND, dev_id, entry_id, cnt_id, enable); + return rv; +} + +sw_error_t +fal_flow_add(a_uint32_t dev_id, fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_ADD, dev_id, napt_entry); + return rv; +} + +sw_error_t +fal_flow_del(a_uint32_t dev_id, a_uint32_t del_mode, fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_DEL, dev_id, del_mode, napt_entry); + return rv; +} + +sw_error_t +fal_flow_get(a_uint32_t dev_id, a_uint32_t get_mode, fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_GET, dev_id, get_mode, napt_entry); + return rv; +} + +sw_error_t +fal_flow_next(a_uint32_t dev_id, a_uint32_t next_mode, fal_napt_entry_t * napt_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_NEXT, dev_id, next_mode, napt_entry); + return rv; +} + +sw_error_t +fal_flow_counter_bind(a_uint32_t dev_id, a_uint32_t entry_id, a_uint32_t cnt_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_COUNTER_BIND, dev_id, entry_id, cnt_id, enable); + return rv; +} + +sw_error_t +fal_nat_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NAT_STATUS_SET, dev_id, enable); + return rv; +} + +sw_error_t +fal_nat_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NAT_STATUS_GET, dev_id, enable); + return rv; +} + +sw_error_t +fal_nat_hash_mode_set(a_uint32_t dev_id, a_uint32_t mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NAT_HASH_MODE_SET, dev_id, mode); + return rv; +} + +sw_error_t +fal_nat_hash_mode_get(a_uint32_t dev_id, a_uint32_t * mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NAT_HASH_MODE_GET, dev_id, mode); + return rv; +} + +sw_error_t +fal_napt_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NAPT_STATUS_SET, dev_id, enable); + return rv; +} + +sw_error_t +fal_napt_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NAPT_STATUS_GET, dev_id, enable); + return rv; +} + +sw_error_t +fal_napt_mode_set(a_uint32_t dev_id, fal_napt_mode_t mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NAPT_MODE_SET, dev_id, mode); + return rv; +} + +sw_error_t +fal_napt_mode_get(a_uint32_t dev_id, fal_napt_mode_t * mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NAPT_MODE_GET, dev_id, mode); + return rv; +} + +sw_error_t +fal_nat_prv_base_addr_set(a_uint32_t dev_id, fal_ip4_addr_t addr) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PRV_BASE_ADDR_SET, dev_id, addr); + return rv; +} + +sw_error_t +fal_nat_prv_base_addr_get(a_uint32_t dev_id, fal_ip4_addr_t * addr) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PRV_BASE_ADDR_GET, dev_id, addr); + return rv; +} + +sw_error_t +fal_nat_prv_base_mask_set(a_uint32_t dev_id, fal_ip4_addr_t addr) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PRV_BASE_MASK_SET, dev_id, addr); + return rv; +} + +sw_error_t +fal_nat_prv_base_mask_get(a_uint32_t dev_id, fal_ip4_addr_t * addr) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PRV_BASE_MASK_GET, dev_id, addr); + return rv; +} + +sw_error_t +fal_nat_prv_addr_mode_set(a_uint32_t dev_id, a_bool_t map_en) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PRV_ADDR_MODE_SET, dev_id, map_en); + return rv; +} + +sw_error_t +fal_nat_prv_addr_mode_get(a_uint32_t dev_id, a_bool_t * map_en) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PRV_ADDR_MODE_GET, dev_id, map_en); + return rv; +} + +sw_error_t +fal_nat_pub_addr_add(a_uint32_t dev_id, fal_nat_pub_addr_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PUB_ADDR_ENTRY_ADD, dev_id, entry); + return rv; +} + +sw_error_t +fal_nat_pub_addr_del(a_uint32_t dev_id, a_uint32_t del_mode, fal_nat_pub_addr_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PUB_ADDR_ENTRY_DEL, dev_id, del_mode, entry); + return rv; +} + +sw_error_t +fal_nat_pub_addr_next(a_uint32_t dev_id, a_uint32_t next_mode, fal_nat_pub_addr_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PUB_ADDR_ENTRY_NEXT, dev_id, next_mode, entry); + return rv; +} + +sw_error_t +fal_nat_unk_session_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NAT_UNK_SESSION_CMD_SET, dev_id, cmd); + return rv; +} + +sw_error_t +fal_nat_unk_session_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NAT_UNK_SESSION_CMD_GET, dev_id, cmd); + return rv; +} + +sw_error_t +fal_nat_global_set(a_uint32_t dev_id, a_bool_t enable, + a_bool_t sync_cnt_enable, a_uint32_t portbmp) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NAT_GLOBAL_SET, dev_id, enable, + sync_cnt_enable, portbmp); + return rv; +} + +sw_error_t +fal_flow_cookie_set(a_uint32_t dev_id, fal_flow_cookie_t * flow_cookie) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_COOKIE_SET, dev_id, flow_cookie); + return rv; +} + +sw_error_t +fal_flow_rfs_set(a_uint32_t dev_id, a_uint8_t action, fal_flow_rfs_t * rfs) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_RFS_SET, dev_id, action, rfs); + return rv; +} + + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_policer.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_policer.c new file mode 100755 index 000000000..3897562ad --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_policer.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_policer.h" +#include "fal_uk_if.h" + + +sw_error_t +fal_policer_timeslot_set(a_uint32_t dev_id, a_uint32_t timeslot) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_POLICER_TIMESLOT_SET, dev_id, timeslot); + return rv; +} + +sw_error_t +fal_policer_timeslot_get(a_uint32_t dev_id, a_uint32_t *timeslot) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_POLICER_TIMESLOT_GET, dev_id, timeslot); + return rv; +} + +sw_error_t +fal_port_policer_counter_get(a_uint32_t dev_id, fal_port_t port_id, + fal_policer_counter_t *counter) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_POLICER_PORT_COUNTER_GET, dev_id, port_id, + counter); + return rv; +} + +sw_error_t +fal_acl_policer_counter_get(a_uint32_t dev_id, a_uint32_t index, + fal_policer_counter_t *counter) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_POLICER_ACL_COUNTER_GET, dev_id, index, + counter); + return rv; +} + +sw_error_t +fal_port_policer_compensation_byte_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t length) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_POLICER_COMPENSATION_SET, dev_id, port_id, length); + return rv; +} + +sw_error_t +fal_port_policer_compensation_byte_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *length) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_POLICER_COMPENSATION_GET, dev_id, port_id, + length); + return rv; +} + +sw_error_t +fal_port_policer_entry_set(a_uint32_t dev_id, fal_port_t port_id, + fal_policer_config_t *policer, fal_policer_action_t *action) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_POLICER_PORT_ENTRY_SET, dev_id, port_id, + policer, action); + return rv; +} + +sw_error_t +fal_port_policer_entry_get(a_uint32_t dev_id, fal_port_t port_id, + fal_policer_config_t *policer, fal_policer_action_t *action) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_POLICER_PORT_ENTRY_GET, dev_id, port_id, + policer, action); + return rv; +} + +sw_error_t +fal_acl_policer_entry_set(a_uint32_t dev_id, a_uint32_t index, + fal_policer_config_t *policer, fal_policer_action_t *action) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_POLICER_ACL_ENTRY_SET, dev_id, index, + policer, action); + return rv; +} + +sw_error_t +fal_acl_policer_entry_get(a_uint32_t dev_id, a_uint32_t index, + fal_policer_config_t *policer, fal_policer_action_t *action) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_POLICER_ACL_ENTRY_GET, dev_id, index, + policer, action); + return rv; +} + +sw_error_t +fal_policer_global_counter_get(a_uint32_t dev_id,fal_policer_global_counter_t *counter) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_POLICER_GLOBAL_COUNTER_GET, dev_id, + counter); + return rv; +} + + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_port_ctrl.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_port_ctrl.c new file mode 100755 index 000000000..018b38535 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_port_ctrl.c @@ -0,0 +1,956 @@ +/* + * Copyright (c) 2014,2016-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +/*qca808x_start*/ +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_port_ctrl.h" +#include "fal_uk_if.h" + +sw_error_t +fal_port_duplex_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t duplex) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_DUPLEX_SET, dev_id, port_id, + duplex); + return rv; +} + +sw_error_t +fal_port_duplex_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_duplex_t * pduplex) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_DUPLEX_GET, dev_id, port_id, pduplex); + return rv; +} + +sw_error_t +fal_port_speed_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t speed) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_SPEED_SET, dev_id, port_id, + speed); + return rv; +} + +sw_error_t +fal_port_speed_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_speed_t * pspeed) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_SPEED_GET, dev_id, port_id, pspeed); + return rv; +} + +sw_error_t +fal_port_autoneg_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * status) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_AN_GET, dev_id, port_id, status); + return rv; +} + +sw_error_t +fal_port_autoneg_enable(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_AN_ENABLE, dev_id, port_id); + return rv; +} + +sw_error_t +fal_port_autoneg_restart(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_AN_RESTART, dev_id, port_id); + return rv; +} + +sw_error_t +fal_port_autoneg_adv_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t autoadv) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_AN_ADV_SET, dev_id, port_id, autoadv); + return rv; +} + +sw_error_t +fal_port_autoneg_adv_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * autoadv) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_AN_ADV_GET, dev_id, port_id, autoadv); + return rv; +} +/*qca808x_end*/ +sw_error_t +fal_port_hdr_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_HDR_SET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_hdr_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_HDR_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_flowctrl_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_FLOWCTRL_SET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_port_flowctrl_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_FLOWCTRL_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_flowctrl_forcemode_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_FLOWCTRL_MODE_SET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_port_flowctrl_forcemode_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_FLOWCTRL_MODE_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_powersave_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_POWERSAVE_SET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_port_powersave_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_POWERSAVE_GET, dev_id, port_id, enable); + return rv; +} +/*qca808x_start*/ +sw_error_t +fal_port_hibernate_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_HIBERNATE_SET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_port_hibernate_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_HIBERNATE_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_cdt(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t mdi_pair, + a_uint32_t *cable_status, a_uint32_t *cable_len) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_CDT, dev_id, port_id, mdi_pair, + cable_status, cable_len); + return rv; +} +/*qca808x_end*/ +sw_error_t +fal_port_rxhdr_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_RXHDR_SET, dev_id, port_id, mode); + return rv; +} + +sw_error_t +fal_port_rxhdr_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t * mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_RXHDR_GET, dev_id, port_id, mode); + return rv; +} + +sw_error_t +fal_port_txhdr_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_TXHDR_SET, dev_id, port_id, mode); + return rv; +} + +sw_error_t +fal_port_txhdr_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_header_mode_t * mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_TXHDR_GET, dev_id, port_id, mode); + return rv; +} + +sw_error_t +fal_header_type_set(a_uint32_t dev_id, a_bool_t enable, a_uint32_t type) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_HEADER_TYPE_SET, dev_id, enable, type); + return rv; +} + +sw_error_t +fal_header_type_get(a_uint32_t dev_id, a_bool_t * enable, a_uint32_t * type) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_HEADER_TYPE_GET, dev_id, enable, type); + return rv; +} + +sw_error_t +fal_port_txmac_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_TXMAC_STATUS_SET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_txmac_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_TXMAC_STATUS_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_rxmac_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RXMAC_STATUS_SET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_rxmac_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RXMAC_STATUS_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_txfc_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_TXFC_STATUS_SET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_txfc_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_TXFC_STATUS_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_rxfc_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RXFC_STATUS_SET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_rxfc_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RXFC_STATUS_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_bp_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_BP_STATUS_SET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_bp_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_BP_STATUS_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_link_forcemode_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_LINK_MODE_SET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_link_forcemode_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_LINK_MODE_GET, dev_id, port_id, enable); + return rv; +} +/*qca808x_start*/ +sw_error_t +fal_port_link_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * status) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_LINK_STATUS_GET, dev_id, port_id, status); + return rv; +} +/*qca808x_end*/ +sw_error_t +fal_ports_link_status_get(a_uint32_t dev_id, a_uint32_t * status) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTS_LINK_STATUS_GET, dev_id, status); + return rv; +} + +sw_error_t +fal_port_mac_loopback_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_MAC_LOOPBACK_SET, dev_id, port_id, enable); + return rv; +} + + +sw_error_t +fal_port_mac_loopback_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_MAC_LOOPBACK_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_congestion_drop_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t queue_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_CONGESTION_DROP_SET, dev_id, port_id, queue_id, enable); + return rv; +} + + +sw_error_t +fal_port_congestion_drop_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t queue_id, a_bool_t *enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_CONGESTION_DROP_GET, dev_id, port_id, queue_id, enable); + return rv; +} + +sw_error_t +fal_ring_flow_ctrl_thres_set(a_uint32_t dev_id, a_uint32_t ring_id, + a_uint8_t on_thres, a_uint8_t off_thres) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_RING_FLOW_CTRL_THRES_SET, dev_id, ring_id, on_thres, off_thres); + return rv; +} + + +sw_error_t +fal_ring_flow_ctrl_thres_get(a_uint32_t dev_id, a_uint32_t ring_id, + a_uint8_t *on_thres, a_uint8_t *off_thres) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_RING_FLOW_CTRL_THRES_GET, dev_id, ring_id, on_thres, off_thres); + return rv; +} +/*qca808x_start*/ +sw_error_t +fal_port_8023az_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_8023AZ_SET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_port_8023az_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_8023AZ_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_mdix_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_mode_t mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_MDIX_SET, dev_id, port_id, mode); + return rv; +} + +sw_error_t +fal_port_mdix_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_mode_t * mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_MDIX_GET, dev_id, port_id, mode); + return rv; +} + +sw_error_t +fal_port_mdix_status_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_mdix_status_t * mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_MDIX_STATUS_GET, dev_id, port_id, mode); + return rv; +} +/*qca808x_end*/ +sw_error_t +fal_port_combo_prefer_medium_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_medium_t medium) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_COMBO_PREFER_MEDIUM_SET, dev_id, port_id, medium); + return rv; +} + +sw_error_t +fal_port_combo_prefer_medium_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_medium_t * medium) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_COMBO_PREFER_MEDIUM_GET, dev_id, port_id, medium); + return rv; +} + +sw_error_t +fal_port_combo_medium_status_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_medium_t * medium) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_COMBO_MEDIUM_STATUS_GET, dev_id, port_id, medium); + return rv; +} + +sw_error_t +fal_port_combo_fiber_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_fiber_mode_t mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_COMBO_FIBER_MODE_SET, dev_id, port_id, mode); + return rv; +} + +sw_error_t +fal_port_combo_fiber_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_fiber_mode_t * mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_COMBO_FIBER_MODE_GET, dev_id, port_id, mode); + return rv; +} +/*qca808x_start*/ +sw_error_t +fal_port_local_loopback_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_LOCAL_LOOPBACK_SET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_port_local_loopback_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_LOCAL_LOOPBACK_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_remote_loopback_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_REMOTE_LOOPBACK_SET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_port_remote_loopback_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_REMOTE_LOOPBACK_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_reset(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_RESET, dev_id, port_id); + return rv; +} + +sw_error_t +fal_port_power_off(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_POWER_OFF, dev_id, port_id); + return rv; +} + +sw_error_t +fal_port_power_on(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_POWER_ON, dev_id, port_id); + return rv; +} + + sw_error_t + fal_port_magic_frame_mac_set (a_uint32_t dev_id, fal_port_t port_id, + fal_mac_addr_t * mac) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_MAGIC_FRAME_MAC_SET, dev_id, port_id, mac); + return rv; + +} + + sw_error_t + fal_port_magic_frame_mac_get (a_uint32_t dev_id, fal_port_t port_id, + fal_mac_addr_t * mac) +{ + + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_MAGIC_FRAME_MAC_GET, dev_id, port_id, mac); + return rv; + + +} + sw_error_t + fal_port_phy_id_get (a_uint32_t dev_id, fal_port_t port_id, + a_uint16_t * org_id, a_uint16_t * rev_id) + { + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_PHY_ID_GET, dev_id, port_id, org_id, rev_id); + return rv; + } + sw_error_t + fal_port_wol_status_set (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_WOL_STATUS_SET, dev_id, port_id, enable); + return rv; + + } + sw_error_t + fal_port_wol_status_get (a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) + + { + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_WOL_STATUS_GET, dev_id, port_id,enable); + return rv; + } + /*qca808x_end*/ +sw_error_t +fal_port_interface_mode_set (a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t mode) +{ + sw_error_t rv; + rv = sw_uk_exec(SW_API_PT_INTERFACE_MODE_SET, dev_id, port_id, mode); + return rv; +} + +sw_error_t +fal_port_interface_mode_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t * mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_INTERFACE_MODE_GET, dev_id, port_id, mode); + return rv; +} + +sw_error_t +fal_port_interface_mode_apply (a_uint32_t dev_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_INTERFACE_MODE_APPLY, dev_id); + return rv; +} +/*qca808x_start*/ +sw_error_t +fal_port_interface_mode_status_get (a_uint32_t dev_id, fal_port_t port_id, + fal_port_interface_mode_t * mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_INTERFACE_MODE_STATUS_GET, dev_id, port_id, mode); + return rv; +} + +sw_error_t +fal_debug_phycounter_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_DEBUG_PHYCOUNTER_SET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_debug_phycounter_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_DEBUG_PHYCOUNTER_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_debug_phycounter_show(a_uint32_t dev_id, fal_port_t port_id, + fal_port_counter_info_t * port_counter_info) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_DEBUG_PHYCOUNTER_SHOW, dev_id, port_id, port_counter_info); + return rv; +} +/*qca808x_end*/ +sw_error_t +fal_port_mtu_set(a_uint32_t dev_id, fal_port_t port_id, + fal_mtu_ctrl_t *ctrl) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_MTU_SET, dev_id, port_id, ctrl); + return rv; +} + +sw_error_t +fal_port_mtu_get(a_uint32_t dev_id, fal_port_t port_id, + fal_mtu_ctrl_t *ctrl) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_MTU_GET, dev_id, port_id, ctrl); + return rv; +} + +sw_error_t +fal_port_mru_set(a_uint32_t dev_id, fal_port_t port_id, + fal_mru_ctrl_t *ctrl) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_MRU_SET, dev_id, port_id, ctrl); + return rv; +} + +sw_error_t +fal_port_mru_get(a_uint32_t dev_id, fal_port_t port_id, + fal_mru_ctrl_t *ctrl) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_MRU_GET, dev_id, port_id, ctrl); + return rv; +} + +sw_error_t +fal_port_source_filter_enable(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_SOURCE_FILTER_SET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_port_source_filter_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_SOURCE_FILTER_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_max_frame_size_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t max_frame) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_FRAME_MAX_SIZE_SET, dev_id, port_id, + max_frame); + return rv; +} + +sw_error_t +fal_port_max_frame_size_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t* max_frame) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_FRAME_MAX_SIZE_GET, dev_id, port_id, max_frame); + return rv; +} +sw_error_t +fal_port_interface_3az_status_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_INTERFACE_3AZ_STATUS_SET, dev_id, port_id, enable); + + return rv; +} +sw_error_t +fal_port_interface_3az_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_INTERFACE_3AZ_STATUS_GET, dev_id, port_id, enable); + + return rv; + + return rv; +} +sw_error_t +fal_port_promisc_mode_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_PROMISC_MODE_SET, dev_id, port_id, enable); + + return rv; +} + +sw_error_t +fal_port_promisc_mode_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t *enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_PROMISC_MODE_GET, dev_id, port_id, enable); + + return rv; +} +sw_error_t +fal_port_interface_eee_cfg_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_eee_cfg_t *port_eee_cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_INTERFACE_EEE_CFG_SET, dev_id, port_id, port_eee_cfg); + + return rv; +} +sw_error_t +fal_port_interface_eee_cfg_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_eee_cfg_t *port_eee_cfg) + +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_INTERFACE_EEE_CFG_GET, dev_id, port_id, port_eee_cfg); + + return rv; +} + +sw_error_t +fal_port_source_filter_config_set(a_uint32_t dev_id, + fal_port_t port_id, fal_src_filter_config_t *src_filter_config) + +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_SOURCE_FILTER_CONFIG_SET, dev_id, port_id, + src_filter_config); + + return rv; +} + +sw_error_t +fal_port_source_filter_config_get(a_uint32_t dev_id, + fal_port_t port_id, fal_src_filter_config_t *src_filter_config) + +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_SOURCE_FILTER_CONFIG_GET, dev_id, port_id, + src_filter_config); + + return rv; +} + +sw_error_t +fal_switch_port_loopback_set(a_uint32_t dev_id, fal_port_t port_id, + fal_loopback_config_t *loopback_cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_SWITCH_PORT_LOOPBACK_SET, dev_id, + port_id, loopback_cfg); + + return rv; +} +sw_error_t +fal_switch_port_loopback_get(a_uint32_t dev_id, fal_port_t port_id, + fal_loopback_config_t *loopback_cfg) + +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_SWITCH_PORT_LOOPBACK_GET, dev_id, port_id, + loopback_cfg); + + return rv; +} + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_portvlan.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_portvlan.c new file mode 100755 index 000000000..8aeea7225 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_portvlan.c @@ -0,0 +1,754 @@ +/* + * Copyright (c) 2014, 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_portvlan.h" +#include "fal_uk_if.h" + +sw_error_t +fal_port_1qmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t port_1qmode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_ING_MODE_SET, dev_id, port_id, + (a_uint32_t) port_1qmode); + return rv; +} + +sw_error_t +fal_port_1qmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1qmode_t * pport_1qmode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_ING_MODE_GET, dev_id, port_id, + pport_1qmode); + return rv; +} + +sw_error_t +fal_port_egvlanmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t port_egvlanmode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_EG_MODE_SET, dev_id, port_id, + (a_uint32_t) port_egvlanmode); + return rv; +} + +sw_error_t +fal_port_egvlanmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_1q_egmode_t * pport_egvlanmode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_EG_MODE_GET, dev_id, port_id, + pport_egvlanmode); + return rv; +} + +sw_error_t +fal_portvlan_member_add(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VLAN_MEM_ADD, dev_id, port_id, + (a_uint32_t) mem_port_id); + return rv; +} + +sw_error_t +fal_portvlan_member_del(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t mem_port_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VLAN_MEM_DEL, dev_id, port_id, + (a_uint32_t) mem_port_id); + return rv; +} + +sw_error_t +fal_portvlan_member_update(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t mem_port_map) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VLAN_MEM_UPDATE, dev_id, port_id, + (a_uint32_t) mem_port_map); + return rv; +} + +sw_error_t +fal_portvlan_member_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pbmp_t * mem_port_map) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VLAN_MEM_GET, dev_id, port_id, + mem_port_map); + return rv; +} + +sw_error_t +fal_port_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t vid) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_DEF_VID_SET, dev_id, port_id, + vid); + return rv; +} + +sw_error_t +fal_port_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_DEF_VID_GET, dev_id, port_id, + vid); + return rv; +} + +sw_error_t +fal_port_force_default_vid_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_FORCE_DEF_VID_SET, dev_id, port_id, + (a_uint32_t) enable); + return rv; +} + +sw_error_t +fal_port_force_default_vid_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_FORCE_DEF_VID_GET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_port_force_portvlan_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_FORCE_PORTVLAN_SET, dev_id, port_id, + (a_uint32_t) enable); + return rv; +} + +sw_error_t +fal_port_force_portvlan_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_FORCE_PORTVLAN_GET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_port_nestvlan_set(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_NESTVLAN_SET, dev_id, port_id, + (a_uint32_t) enable); + return rv; +} + +sw_error_t +fal_port_nestvlan_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_NESTVLAN_GET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_nestvlan_tpid_set(a_uint32_t dev_id, a_uint32_t tpid) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NESTVLAN_TPID_SET, dev_id, tpid); + return rv; +} + +sw_error_t +fal_nestvlan_tpid_get(a_uint32_t dev_id, a_uint32_t * tpid) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NESTVLAN_TPID_GET, dev_id, tpid); + return rv; +} + +sw_error_t +fal_port_invlan_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_IN_VLAN_MODE_SET, dev_id, port_id, (a_uint32_t) mode); + return rv; +} + +sw_error_t +fal_port_invlan_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_pt_invlan_mode_t * mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_IN_VLAN_MODE_GET, dev_id, port_id, mode); + return rv; +} + +sw_error_t +fal_port_tls_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_TLS_SET, dev_id, port_id, (a_uint32_t) enable); + return rv; +} + +sw_error_t +fal_port_tls_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_TLS_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_pri_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_PRI_PROPAGATION_SET, dev_id, port_id, (a_uint32_t) enable); + return rv; +} + +sw_error_t +fal_port_pri_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_PRI_PROPAGATION_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_default_svid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_DEF_SVID_SET, dev_id, port_id, vid); + return rv; +} + +sw_error_t +fal_port_default_svid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_DEF_SVID_GET, dev_id, port_id, vid); + return rv; +} + +sw_error_t +fal_port_default_cvid_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vid) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_DEF_CVID_SET, dev_id, port_id, vid); + return rv; +} + +sw_error_t +fal_port_default_cvid_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vid) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_DEF_CVID_GET, dev_id, port_id, vid); + return rv; +} + +sw_error_t +fal_port_vlan_propagation_set(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VLAN_PROPAGATION_SET, dev_id, port_id, (a_uint32_t)mode); + return rv; +} + +sw_error_t +fal_port_vlan_propagation_get(a_uint32_t dev_id, fal_port_t port_id, + fal_vlan_propagation_mode_t * mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VLAN_PROPAGATION_GET, dev_id, port_id, mode); + return rv; +} + +sw_error_t +fal_port_vlan_trans_add(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VLAN_TRANS_ADD, dev_id, port_id, entry); + return rv; +} + +sw_error_t +fal_port_vlan_trans_del(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VLAN_TRANS_DEL, dev_id, port_id, entry); + return rv; +} + +sw_error_t +fal_port_vlan_trans_get(a_uint32_t dev_id, fal_port_t port_id, fal_vlan_trans_entry_t *entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VLAN_TRANS_GET, dev_id, port_id, entry); + return rv; +} + +sw_error_t +fal_qinq_mode_set(a_uint32_t dev_id, fal_qinq_mode_t mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QINQ_MODE_SET, dev_id, (a_uint32_t)mode); + return rv; +} + +sw_error_t +fal_qinq_mode_get(a_uint32_t dev_id, fal_qinq_mode_t * mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QINQ_MODE_GET, dev_id, mode); + return rv; +} + +sw_error_t +fal_port_qinq_role_set(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t role) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_QINQ_ROLE_SET, dev_id, port_id, (a_uint32_t)role); + return rv; +} + +sw_error_t +fal_port_qinq_role_get(a_uint32_t dev_id, fal_port_t port_id, fal_qinq_port_role_t * role) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_QINQ_ROLE_GET, dev_id, port_id, role); + return rv; +} + +sw_error_t +fal_port_vlan_trans_iterate(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * iterator, fal_vlan_trans_entry_t * entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VLAN_TRANS_ITERATE, dev_id, port_id, + iterator,entry); + return rv; +} + +sw_error_t +fal_port_mac_vlan_xlt_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_MAC_VLAN_XLT_SET, dev_id, port_id, (a_uint32_t)enable); + return rv; +} + +sw_error_t +fal_port_mac_vlan_xlt_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_MAC_VLAN_XLT_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_netisolate_set(a_uint32_t dev_id, a_uint32_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NETISOLATE_SET, dev_id, enable); + return rv; +} + +sw_error_t +fal_netisolate_get(a_uint32_t dev_id, a_uint32_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_NETISOLATE_GET, dev_id, enable); + return rv; +} + +sw_error_t +fal_eg_trans_filter_bypass_en_set(a_uint32_t dev_id, a_uint32_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_EG_FLTR_BYPASS_EN_SET, dev_id, enable); + return rv; +} + +sw_error_t +fal_eg_trans_filter_bypass_en_get(a_uint32_t dev_id, a_uint32_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_EG_FLTR_BYPASS_EN_GET, dev_id, enable); + return rv; +} + +sw_error_t +fal_port_vrf_id_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t vrf_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VRF_ID_SET, dev_id, port_id, vrf_id); + return rv; +} + +sw_error_t +fal_port_vrf_id_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * vrf_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VRF_ID_GET, dev_id, port_id, vrf_id); + return rv; +} + +sw_error_t +fal_global_qinq_mode_set(a_uint32_t dev_id, fal_global_qinq_mode_t *mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_GLOBAL_QINQ_MODE_SET, dev_id, mode); + return rv; +} + +sw_error_t +fal_global_qinq_mode_get(a_uint32_t dev_id, fal_global_qinq_mode_t *mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_GLOBAL_QINQ_MODE_GET, dev_id, mode); + return rv; +} + +sw_error_t +fal_port_qinq_mode_set(a_uint32_t dev_id, fal_port_t port_id, fal_port_qinq_role_t *mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PORT_QINQ_MODE_SET, dev_id, port_id, mode); + return rv; +} + +sw_error_t +fal_port_qinq_mode_get(a_uint32_t dev_id, fal_port_t port_id, fal_port_qinq_role_t *mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PORT_QINQ_MODE_GET, dev_id, port_id, mode); + return rv; +} + +sw_error_t +fal_ingress_tpid_set(a_uint32_t dev_id, fal_tpid_t *tpid) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_TPID_SET, dev_id, tpid); + return rv; +} + +sw_error_t +fal_ingress_tpid_get(a_uint32_t dev_id, fal_tpid_t *tpid) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_TPID_GET, dev_id, tpid); + return rv; +} + +sw_error_t +fal_egress_tpid_set(a_uint32_t dev_id, fal_tpid_t *tpid) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_EGRESS_TPID_SET, dev_id, tpid); + return rv; +} + +sw_error_t +fal_egress_tpid_get(a_uint32_t dev_id, fal_tpid_t *tpid) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_EGRESS_TPID_GET, dev_id, tpid); + return rv; +} + +sw_error_t +fal_port_ingress_vlan_filter_set(a_uint32_t dev_id, fal_port_t port_id, fal_ingress_vlan_filter_t *filter) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_INGRESS_VLAN_FILTER_SET, dev_id, port_id, filter); + return rv; +} + +sw_error_t +fal_port_ingress_vlan_filter_get(a_uint32_t dev_id, fal_port_t port_id, fal_ingress_vlan_filter_t *filter) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_INGRESS_VLAN_FILTER_GET, dev_id, port_id, filter); + return rv; +} + +sw_error_t +fal_port_default_vlantag_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_vlan_direction_t direction, fal_port_default_vid_enable_t *default_vid_en, + fal_port_vlan_tag_t *default_tag) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_DEFAULT_VLANTAG_SET, dev_id, port_id, (a_uint32_t) direction, + default_vid_en, default_tag); + return rv; +} + +sw_error_t +fal_port_default_vlantag_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_vlan_direction_t direction, fal_port_default_vid_enable_t *default_vid_en, + fal_port_vlan_tag_t *default_tag) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_DEFAULT_VLANTAG_GET, dev_id, port_id, (a_uint32_t) direction, + default_vid_en, default_tag); + return rv; +} + +sw_error_t +fal_port_tag_propagation_set(a_uint32_t dev_id, fal_port_t port_id, fal_port_vlan_direction_t direction, + fal_vlantag_propagation_t *prop) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_TAG_PROPAGATION_SET, dev_id, port_id, (a_uint32_t) direction, prop); + return rv; +} + +sw_error_t +fal_port_tag_propagation_get(a_uint32_t dev_id, fal_port_t port_id, fal_port_vlan_direction_t direction, + fal_vlantag_propagation_t *prop) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_TAG_PROPAGATION_GET, dev_id, port_id, (a_uint32_t) direction, prop); + return rv; +} + +sw_error_t +fal_port_vlan_xlt_miss_cmd_set(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VLAN_XLT_MISS_CMD_SET, dev_id, port_id, (a_uint32_t) cmd); + return rv; +} + +sw_error_t +fal_port_vlan_xlt_miss_cmd_get(a_uint32_t dev_id, fal_port_t port_id, + fal_fwd_cmd_t *cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VLAN_XLT_MISS_CMD_GET, dev_id, port_id, cmd); + return rv; +} + +sw_error_t +fal_port_vlantag_egmode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_vlantag_egress_mode_t *port_egvlanmode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VLANTAG_EGMODE_SET, dev_id, port_id, port_egvlanmode); + return rv; +} + +sw_error_t +fal_port_vlantag_egmode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_vlantag_egress_mode_t *port_egvlanmode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VLANTAG_EGMODE_GET, dev_id, port_id, port_egvlanmode); + return rv; +} + +sw_error_t +fal_port_vsi_egmode_set(a_uint32_t dev_id, a_uint32_t vsi, a_uint32_t port_id, fal_pt_1q_egmode_t egmode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VSI_EGMODE_SET, dev_id, vsi, port_id, (a_uint32_t) egmode); + return rv; +} + +sw_error_t +fal_port_vsi_egmode_get(a_uint32_t dev_id, a_uint32_t vsi, a_uint32_t port_id, fal_pt_1q_egmode_t * egmode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VSI_EGMODE_GET, dev_id, vsi, port_id, egmode); + return rv; +} + +sw_error_t +fal_port_vlantag_vsi_egmode_enable(a_uint32_t dev_id, fal_port_t port_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VLANTAG_VSI_EGMODE_EN_SET, dev_id, port_id, (a_uint32_t) enable); + return rv; +} + +sw_error_t +fal_port_vlantag_vsi_egmode_status_get(a_uint32_t dev_id, fal_port_t port_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VLANTAG_VSI_EGMODE_EN_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_port_vlan_trans_adv_add(a_uint32_t dev_id, fal_port_t port_id, fal_port_vlan_direction_t direction, + fal_vlan_trans_adv_rule_t * rule, fal_vlan_trans_adv_action_t * action) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VLAN_TRANS_ADV_ADD, dev_id, port_id, (a_uint32_t) direction, + rule, action); + return rv; +} + +sw_error_t +fal_port_vlan_trans_adv_del(a_uint32_t dev_id, fal_port_t port_id, fal_port_vlan_direction_t direction, + fal_vlan_trans_adv_rule_t * rule, fal_vlan_trans_adv_action_t * action) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VLAN_TRANS_ADV_DEL, dev_id, port_id, (a_uint32_t) direction, + rule, action); + return rv; +} + +sw_error_t +fal_port_vlan_trans_adv_getfirst(a_uint32_t dev_id, fal_port_t port_id, fal_port_vlan_direction_t direction, + fal_vlan_trans_adv_rule_t * rule, fal_vlan_trans_adv_action_t * action) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VLAN_TRANS_ADV_GETFIRST, dev_id, port_id, (a_uint32_t) direction, + rule, action); + return rv; +} + +sw_error_t +fal_port_vlan_trans_adv_getnext(a_uint32_t dev_id, fal_port_t port_id, fal_port_vlan_direction_t direction, + fal_vlan_trans_adv_rule_t * rule, fal_vlan_trans_adv_action_t * action) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VLAN_TRANS_ADV_GETNEXT, dev_id, port_id, (a_uint32_t) direction, + rule, action); + return rv; +} + +sw_error_t +fal_port_vlan_counter_get(a_uint32_t dev_id, a_uint32_t cnt_index, fal_port_vlan_counter_t * counter) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VLAN_COUNTER_GET, dev_id, cnt_index, counter); + return rv; +} + +sw_error_t +fal_port_vlan_counter_cleanup(a_uint32_t dev_id, a_uint32_t cnt_index) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PT_VLAN_COUNTER_CLEANUP, dev_id, cnt_index); + return rv; +} + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_pppoe.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_pppoe.c new file mode 100755 index 000000000..4c7817c33 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_pppoe.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_pppoe.h" +#include "fal_uk_if.h" + +sw_error_t +fal_pppoe_cmd_set(a_uint32_t dev_id, fal_fwd_cmd_t cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PPPOE_CMD_SET, dev_id, (a_uint32_t) cmd); + return rv; +} + +sw_error_t +fal_pppoe_cmd_get(a_uint32_t dev_id, fal_fwd_cmd_t * cmd) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PPPOE_CMD_GET, dev_id, cmd); + return rv; +} + +sw_error_t +fal_pppoe_status_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PPPOE_STATUS_SET, dev_id, (a_uint32_t) enable); + return rv; +} + +sw_error_t +fal_pppoe_status_get(a_uint32_t dev_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PPPOE_STATUS_GET, dev_id, enable); + return rv; +} + +sw_error_t +fal_pppoe_session_add(a_uint32_t dev_id, a_uint32_t session_id, a_bool_t strip_hdr) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PPPOE_SESSION_ADD, dev_id, session_id, (a_uint32_t)strip_hdr); + return rv; +} + +sw_error_t +fal_pppoe_session_del(a_uint32_t dev_id, a_uint32_t session_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PPPOE_SESSION_DEL, dev_id, session_id); + return rv; +} + +sw_error_t +fal_pppoe_session_get(a_uint32_t dev_id, a_uint32_t session_id, a_bool_t * strip_hdr) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PPPOE_SESSION_GET, dev_id, session_id, strip_hdr); + return rv; +} + +sw_error_t +fal_pppoe_session_table_add(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PPPOE_SESSION_TABLE_ADD, dev_id, session_tbl); + return rv; +} + +sw_error_t +fal_pppoe_session_table_del(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PPPOE_SESSION_TABLE_DEL, dev_id, session_tbl); + return rv; +} + +sw_error_t +fal_pppoe_session_table_get(a_uint32_t dev_id, fal_pppoe_session_t * session_tbl) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PPPOE_SESSION_TABLE_GET, dev_id, session_tbl); + return rv; +} + +sw_error_t +fal_pppoe_session_id_set(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PPPOE_SESSION_ID_SET, dev_id, index, id); + return rv; +} + +sw_error_t +fal_pppoe_session_id_get(a_uint32_t dev_id, a_uint32_t index, + a_uint32_t * id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PPPOE_SESSION_ID_GET, dev_id, index, id); + return rv; +} + +sw_error_t +fal_rtd_pppoe_en_set(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RTD_PPPOE_EN_SET, dev_id, (a_uint32_t) enable); + return rv; +} + +sw_error_t +fal_rtd_pppoe_en_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RTD_PPPOE_EN_GET, dev_id, enable); + return rv; +} + +sw_error_t +fal_pppoe_l3intf_enable(a_uint32_t dev_id, a_uint32_t l3_if, a_uint32_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PPPOE_EN_SET, dev_id, l3_if, (a_uint32_t) enable); + return rv; +} + +sw_error_t +fal_pppoe_l3intf_status_get(a_uint32_t dev_id, a_uint32_t l3_if, a_uint32_t *enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PPPOE_EN_GET, dev_id, l3_if, enable); + return rv; +} + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_ptp.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_ptp.c new file mode 100755 index 000000000..4ad27e5c8 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_ptp.c @@ -0,0 +1,497 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_ptp.h" +#include "fal_uk_if.h" + +sw_error_t +fal_ptp_config_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_config_t *config) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_CONFIG_SET, dev_id, port_id, + config); + return rv; +} + +sw_error_t +fal_ptp_config_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_config_t *config) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_CONFIG_GET, dev_id, port_id, + config); + return rv; +} + +sw_error_t +fal_ptp_reference_clock_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_reference_clock_t ref_clock) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_REFERENCE_CLOCK_SET, dev_id, port_id, + ref_clock); + return rv; +} + +sw_error_t +fal_ptp_reference_clock_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_reference_clock_t *ref_clock) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_REFERENCE_CLOCK_GET, dev_id, port_id, + ref_clock); + return rv; +} + +sw_error_t +fal_ptp_rx_timestamp_mode_set(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_rx_timestamp_mode_t ts_mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_RX_TIMESTAMP_MODE_SET, dev_id, port_id, + ts_mode); + return rv; +} + +sw_error_t +fal_ptp_rx_timestamp_mode_get(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_rx_timestamp_mode_t *ts_mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_RX_TIMESTAMP_MODE_GET, dev_id, port_id, + ts_mode); + return rv; +} + +sw_error_t +fal_ptp_timestamp_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_direction_t direction, + fal_ptp_pkt_info_t *pkt_info, + fal_ptp_time_t *time) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_TIMESTAMP_GET, dev_id, port_id, + direction, pkt_info, time); + return rv; +} + +sw_error_t +fal_ptp_pkt_timestamp_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_time_t *time) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_PKT_TIMESTAMP_SET, dev_id, port_id, + time); + return rv; +} + +sw_error_t +fal_ptp_pkt_timestamp_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_time_t *time) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_PKT_TIMESTAMP_GET, dev_id, port_id, + time); + return rv; +} + +sw_error_t +fal_ptp_grandmaster_mode_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_grandmaster_mode_t *gm_mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_GRANDMASTER_MODE_SET, dev_id, port_id, + gm_mode); + return rv; +} + +sw_error_t +fal_ptp_grandmaster_mode_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_grandmaster_mode_t *gm_mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_GRANDMASTER_MODE_GET, dev_id, port_id, + gm_mode); + return rv; +} + +sw_error_t +fal_ptp_rtc_time_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_time_t *time) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_RTC_TIME_GET, dev_id, port_id, + time); + return rv; +} + +sw_error_t +fal_ptp_rtc_time_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_time_t *time) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_RTC_TIME_SET, dev_id, port_id, + time); + return rv; +} + +sw_error_t +fal_ptp_rtc_time_clear(a_uint32_t dev_id, a_uint32_t port_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_RTC_TIME_CLEAR, dev_id, port_id); + return rv; +} + +sw_error_t +fal_ptp_rtc_adjtime_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_time_t *time) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_RTC_ADJTIME_SET, dev_id, port_id, + time); + return rv; +} + +sw_error_t +fal_ptp_rtc_adjfreq_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_time_t *time) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_RTC_ADJFREQ_SET, dev_id, port_id, + time); + return rv; +} + +sw_error_t +fal_ptp_rtc_adjfreq_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_time_t *time) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_RTC_ADJFREQ_GET, dev_id, port_id, + time); + return rv; +} + +sw_error_t +fal_ptp_link_delay_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_time_t *time) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_LINK_DELAY_SET, dev_id, port_id, + time); + return rv; +} + +sw_error_t +fal_ptp_link_delay_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_time_t *time) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_LINK_DELAY_GET, dev_id, port_id, + time); + return rv; +} + +sw_error_t +fal_ptp_security_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_security_t *sec) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_SECURITY_SET, dev_id, port_id, + sec); + return rv; +} + +sw_error_t +fal_ptp_security_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_security_t *sec) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_SECURITY_GET, dev_id, port_id, + sec); + return rv; +} + +sw_error_t +fal_ptp_pps_signal_control_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_pps_signal_control_t *sig_control) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_PPS_SIGNAL_CONTROL_SET, dev_id, port_id, + sig_control); + return rv; +} + +sw_error_t +fal_ptp_pps_signal_control_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_pps_signal_control_t *sig_control) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_PPS_SIGNAL_CONTROL_GET, dev_id, port_id, + sig_control); + return rv; +} + +sw_error_t +fal_ptp_rx_crc_recalc_enable(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t status) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_RX_CRC_RECALC_SET, dev_id, port_id, + status); + return rv; +} + +sw_error_t +fal_ptp_rx_crc_recalc_status_get(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t *status) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_RX_CRC_RECALC_GET, dev_id, port_id, + status); + return rv; +} + +sw_error_t +fal_ptp_asym_correction_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_asym_correction_t *asym_cf) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_ASYM_CORRECTION_SET, dev_id, port_id, + asym_cf); + return rv; +} + +sw_error_t +fal_ptp_asym_correction_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_asym_correction_t* asym_cf) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_ASYM_CORRECTION_GET, dev_id, port_id, + asym_cf); + return rv; +} + +sw_error_t +fal_ptp_output_waveform_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_output_waveform_t *waveform) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_OUTPUT_WAVEFORM_SET, dev_id, port_id, + waveform); + return rv; +} + +sw_error_t +fal_ptp_output_waveform_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_output_waveform_t *waveform) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_OUTPUT_WAVEFORM_GET, dev_id, port_id, + waveform); + return rv; +} + +sw_error_t +fal_ptp_rtc_time_snapshot_enable(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t status) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_RTC_TIME_SNAPSHOT_SET, dev_id, port_id, + status); + return rv; +} + +sw_error_t +fal_ptp_rtc_time_snapshot_status_get(a_uint32_t dev_id, a_uint32_t port_id, + a_bool_t *status) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_RTC_TIME_SNAPSHOT_GET, dev_id, port_id, + status); + return rv; +} + +sw_error_t +fal_ptp_increment_sync_from_clock_enable(a_uint32_t dev_id, + a_uint32_t port_id, a_bool_t status) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_INCREMENT_SYNC_FROM_CLOCK_SET, dev_id, port_id, + status); + return rv; +} + +sw_error_t +fal_ptp_increment_sync_from_clock_status_get(a_uint32_t dev_id, + a_uint32_t port_id, a_bool_t *status) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_INCREMENT_SYNC_FROM_CLOCK_GET, dev_id, port_id, + status); + return rv; +} + +sw_error_t +fal_ptp_tod_uart_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_tod_uart_t *tod_uart) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_TOD_UART_SET, dev_id, port_id, + tod_uart); + return rv; +} + +sw_error_t +fal_ptp_tod_uart_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_tod_uart_t *tod_uart) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_TOD_UART_GET, dev_id, port_id, + tod_uart); + return rv; +} + +sw_error_t +fal_ptp_enhanced_timestamp_engine_set(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_direction_t direction, + fal_ptp_enhanced_ts_engine_t *ts_engine) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_ENHANCED_TIMESTAMP_ENGINE_SET, dev_id, port_id, + direction, ts_engine); + return rv; +} + +sw_error_t +fal_ptp_enhanced_timestamp_engine_get(a_uint32_t dev_id, + a_uint32_t port_id, fal_ptp_direction_t direction, + fal_ptp_enhanced_ts_engine_t *ts_engine) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_ENHANCED_TIMESTAMP_ENGINE_GET, dev_id, port_id, + direction, ts_engine); + return rv; +} + +sw_error_t +fal_ptp_trigger_set(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t trigger_id, fal_ptp_trigger_t *triger) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_TRIGGER_SET, dev_id, port_id, + trigger_id, triger); + return rv; +} + +sw_error_t +fal_ptp_trigger_get(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t trigger_id, fal_ptp_trigger_t *triger) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_TRIGGER_GET, dev_id, port_id, + trigger_id, triger); + return rv; +} + +sw_error_t +fal_ptp_capture_set(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t capture_id, fal_ptp_capture_t *capture) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_CAPTURE_SET, dev_id, port_id, + capture_id, capture); + return rv; +} + +sw_error_t +fal_ptp_capture_get(a_uint32_t dev_id, a_uint32_t port_id, + a_uint32_t capture_id, fal_ptp_capture_t *capture) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_CAPTURE_GET, dev_id, port_id, + capture_id, capture); + return rv; +} + +sw_error_t +fal_ptp_interrupt_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_interrupt_t *interrupt) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_INTERRUPT_SET, dev_id, port_id, + interrupt); + return rv; +} + +sw_error_t +fal_ptp_interrupt_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_ptp_interrupt_t *interrupt) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PTP_INTERRUPT_GET, dev_id, port_id, + interrupt); + return rv; +} + + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_qm.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_qm.c new file mode 100755 index 000000000..09b8c341e --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_qm.c @@ -0,0 +1,404 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_qm.h" +#include "fal_uk_if.h" + +sw_error_t +fal_ac_ctrl_set( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + fal_ac_ctrl_t *cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_AC_CTRL_SET, dev_id, obj, cfg); + return rv; +} + +sw_error_t +fal_ac_ctrl_get( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + fal_ac_ctrl_t *cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_AC_CTRL_GET, dev_id, obj, cfg); + return rv; +} + +sw_error_t +fal_ac_prealloc_buffer_set( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + a_uint16_t num) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_AC_PRE_BUFFER_SET, dev_id, obj, num); + return rv; +} + +sw_error_t +fal_ac_prealloc_buffer_get( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + a_uint16_t *num) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_AC_PRE_BUFFER_GET, dev_id, obj, num); + return rv; +} + +sw_error_t +fal_ac_queue_group_set( + a_uint32_t dev_id, + a_uint32_t queue_id, + a_uint8_t group_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QUEUE_GROUP_SET, dev_id, queue_id, group_id); + return rv; +} + +sw_error_t +fal_ac_queue_group_get( + a_uint32_t dev_id, + a_uint32_t queue_id, + a_uint8_t *group_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QUEUE_GROUP_GET, dev_id, queue_id, group_id); + return rv; +} + +sw_error_t +fal_ac_static_threshold_set( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + fal_ac_static_threshold_t *cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_STATIC_THRESH_SET, dev_id, obj, cfg); + return rv; +} + +sw_error_t +fal_ac_static_threshold_get( + a_uint32_t dev_id, + fal_ac_obj_t *obj, + fal_ac_static_threshold_t *cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_STATIC_THRESH_GET, dev_id, obj, cfg); + return rv; +} + +sw_error_t +fal_ac_dynamic_threshold_set( + a_uint32_t dev_id, + a_uint32_t queue_id, + fal_ac_dynamic_threshold_t *cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_DYNAMIC_THRESH_SET, dev_id, queue_id, cfg); + return rv; +} + +sw_error_t +fal_ac_dynamic_threshold_get( + a_uint32_t dev_id, + a_uint32_t queue_id, + fal_ac_dynamic_threshold_t *cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_DYNAMIC_THRESH_GET, dev_id, queue_id, cfg); + return rv; +} + +sw_error_t +fal_ac_group_buffer_set( + a_uint32_t dev_id, + a_uint8_t group_id, + fal_ac_group_buffer_t *cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_GOURP_BUFFER_SET, dev_id, group_id, cfg); + return rv; +} + +sw_error_t +fal_ac_group_buffer_get( + a_uint32_t dev_id, + a_uint8_t group_id, + fal_ac_group_buffer_t *cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_GOURP_BUFFER_GET, dev_id, group_id, cfg); + return rv; +} + +sw_error_t +fal_ucast_queue_base_profile_set( + a_uint32_t dev_id, + fal_ucast_queue_dest_t *queue_dest, + a_uint32_t queue_base, a_uint8_t profile) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_UCAST_QUEUE_BASE_PROFILE_SET, dev_id, queue_dest, queue_base, profile); + return rv; +} + +sw_error_t +fal_ucast_queue_base_profile_get( + a_uint32_t dev_id, + fal_ucast_queue_dest_t *queue_dest, + a_uint32_t *queue_base, a_uint8_t *profile) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_UCAST_QUEUE_BASE_PROFILE_GET, dev_id, queue_dest, queue_base, profile); + return rv; +} + +sw_error_t +fal_ucast_priority_class_set( + a_uint32_t dev_id, + a_uint8_t profile, + a_uint8_t priority, + a_uint8_t class) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_UCAST_PRIORITY_CLASS_SET, dev_id, profile, priority, class); + return rv; +} + +sw_error_t +fal_ucast_priority_class_get( + a_uint32_t dev_id, + a_uint8_t profile, + a_uint8_t priority, + a_uint8_t *class) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_UCAST_PRIORITY_CLASS_GET, dev_id, profile, priority, class); + return rv; +} + +sw_error_t +fal_ucast_hash_map_set( + a_uint32_t dev_id, + a_uint8_t profile, + a_uint8_t rss_hash, + a_int8_t queue_hash) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_UCAST_HASH_MAP_SET, dev_id, profile, rss_hash, queue_hash); + return rv; +} + +sw_error_t +fal_ucast_hash_map_get( + a_uint32_t dev_id, + a_uint8_t profile, + a_uint8_t rss_hash, + a_int8_t *queue_hash) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_UCAST_HASH_MAP_GET, dev_id, profile, rss_hash, queue_hash); + return rv; +} + +sw_error_t +fal_mcast_cpu_code_class_set( + a_uint32_t dev_id, + a_uint8_t cpu_code, + a_uint8_t queue_class) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MCAST_CPUCODE_CLASS_SET, dev_id, cpu_code, queue_class); + return rv; +} + +sw_error_t +fal_mcast_cpu_code_class_get( + a_uint32_t dev_id, + a_uint8_t cpu_code, + a_uint8_t *queue_class) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MCAST_CPUCODE_CLASS_GET, dev_id, cpu_code, queue_class); + return rv; +} + +sw_error_t +fal_port_mcast_priority_class_set( + a_uint32_t dev_id, + fal_port_t port, + a_uint8_t priority, + a_uint8_t queue_class) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MCAST_PRIORITY_CLASS_SET, dev_id, port, priority, queue_class); + return rv; +} + +sw_error_t +fal_port_mcast_priority_class_get( + a_uint32_t dev_id, + fal_port_t port, + a_uint8_t priority, + a_uint8_t *queue_class) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_MCAST_PRIORITY_CLASS_GET, dev_id, port, priority, queue_class); + return rv; +} + +sw_error_t +fal_queue_flush( + a_uint32_t dev_id, + fal_port_t port, + a_uint16_t queue_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QUEUE_FLUSH, dev_id, port, queue_id); + return rv; +} + +sw_error_t +fal_ucast_default_hash_set( + a_uint32_t dev_id, + a_uint8_t hash_value) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_UCAST_DFLT_HASH_MAP_SET, dev_id, hash_value); + return rv; +} + +sw_error_t +fal_ucast_default_hash_get( + a_uint32_t dev_id, + a_uint8_t *hash_value) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_UCAST_DFLT_HASH_MAP_GET, dev_id, hash_value); + return rv; +} + +sw_error_t +fal_queue_counter_ctrl_set(a_uint32_t dev_id, a_bool_t cnt_en) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QUEUE_CNT_CTRL_SET, dev_id, cnt_en); + return rv; +} + +sw_error_t +fal_queue_counter_ctrl_get(a_uint32_t dev_id, a_bool_t *cnt_en) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QUEUE_CNT_CTRL_GET, dev_id, cnt_en); + return rv; +} + +sw_error_t +fal_queue_counter_get( + a_uint32_t dev_id, + a_uint32_t queue_id, + fal_queue_stats_t *info) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QUEUE_CNT_GET, dev_id, queue_id, info); + return rv; +} + +sw_error_t +fal_queue_counter_cleanup(a_uint32_t dev_id, a_uint32_t queue_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QUEUE_CNT_CLEANUP, dev_id, queue_id); + return rv; +} + +sw_error_t +fal_qm_enqueue_ctrl_set(a_uint32_t dev_id, a_uint32_t queue_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QM_ENQUEUE_CTRL_SET, dev_id, queue_id, enable); + return rv; +} + +sw_error_t +fal_qm_enqueue_ctrl_get(a_uint32_t dev_id, a_uint32_t queue_id, a_bool_t *enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QM_ENQUEUE_CTRL_GET, dev_id, queue_id, enable); + return rv; +} + +sw_error_t +fal_qm_port_source_profile_set( + a_uint32_t dev_id, fal_port_t port, + a_uint32_t src_profile) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QM_SOURCE_PROFILE_SET, dev_id, port, src_profile); + return rv; +} + +sw_error_t +fal_qm_port_source_profile_get( + a_uint32_t dev_id, fal_port_t port, + a_uint32_t *src_profile) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QM_SOURCE_PROFILE_GET, dev_id, port, src_profile); + return rv; +} + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_qos.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_qos.c new file mode 100644 index 000000000..e48faa3c9 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_qos.c @@ -0,0 +1,612 @@ +/* + * Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_qos.h" +#include "fal_uk_if.h" + +sw_error_t +fal_qos_sch_mode_set(a_uint32_t dev_id, + fal_sch_mode_t mode, const a_uint32_t weight[]) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_SCH_MODE_SET, dev_id, mode, + weight); + return rv; +} + +sw_error_t +fal_qos_sch_mode_get(a_uint32_t dev_id, + fal_sch_mode_t * mode, a_uint32_t weight[]) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_SCH_MODE_GET, dev_id, mode, + weight); + return rv; +} + +sw_error_t +fal_qos_queue_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_QU_TX_BUF_ST_SET, dev_id, port_id, + (a_uint32_t) enable); + return rv; +} + +sw_error_t +fal_qos_queue_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_QU_TX_BUF_ST_GET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_qos_queue_tx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + fal_queue_t queue_id, a_uint32_t * number) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_QU_TX_BUF_NR_SET, dev_id, port_id, queue_id, + number); + return rv; +} + +sw_error_t +fal_qos_queue_tx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + fal_queue_t queue_id, a_uint32_t * number) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_QU_TX_BUF_NR_GET, dev_id, port_id, queue_id, + number); + return rv; +} + +sw_error_t +fal_qos_port_tx_buf_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PT_TX_BUF_ST_SET, dev_id, port_id, + (a_uint32_t) enable); + return rv; +} + +sw_error_t +fal_qos_port_tx_buf_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PT_TX_BUF_ST_GET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_qos_port_red_en_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PT_RED_EN_SET, dev_id, port_id, + (a_uint32_t) enable); + return rv; +} + +sw_error_t +fal_qos_port_red_en_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PT_RED_EN_GET, dev_id, port_id, + enable); + return rv; +} + +sw_error_t +fal_qos_port_tx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PT_TX_BUF_NR_SET, dev_id, port_id, + number); + return rv; +} + +sw_error_t +fal_qos_port_tx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PT_TX_BUF_NR_GET, dev_id, port_id, + number); + return rv; +} + +sw_error_t +fal_qos_port_rx_buf_nr_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PT_RX_BUF_NR_SET, dev_id, port_id, + number); + return rv; +} + +sw_error_t +fal_qos_port_rx_buf_nr_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * number) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PT_RX_BUF_NR_GET, dev_id, port_id, + number); + return rv; +} + +sw_error_t +fal_cosmap_up_queue_set(a_uint32_t dev_id, a_uint32_t up, fal_queue_t queue) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_COSMAP_UP_QU_SET, dev_id, up, + (a_uint32_t) queue); + return rv; +} + +sw_error_t +fal_cosmap_up_queue_get(a_uint32_t dev_id, a_uint32_t up, + fal_queue_t * queue) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_COSMAP_UP_QU_GET, dev_id, up, + queue); + return rv; +} + +sw_error_t +fal_cosmap_dscp_queue_set(a_uint32_t dev_id, a_uint32_t dscp, fal_queue_t queue) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_COSMAP_DSCP_QU_SET, dev_id, dscp, + (a_uint32_t) queue); + return rv; +} + +sw_error_t +fal_cosmap_dscp_queue_get(a_uint32_t dev_id, a_uint32_t dscp, + fal_queue_t * queue) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_COSMAP_DSCP_QU_GET, dev_id, dscp, + queue); + return rv; +} + +sw_error_t +fal_qos_port_mode_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PT_MODE_SET, dev_id, port_id, mode, + (a_uint32_t) enable); + return rv; +} + +sw_error_t +fal_qos_port_mode_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PT_MODE_GET, dev_id, port_id, mode, + enable); + return rv; +} + +sw_error_t +fal_qos_port_mode_pri_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_uint32_t pri) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PT_MODE_PRI_SET, dev_id, port_id, mode, pri); + return rv; +} + +sw_error_t +fal_qos_port_mode_pri_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_mode_t mode, a_uint32_t * pri) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PT_MODE_PRI_GET, dev_id, port_id, mode, + pri); + return rv; +} + +sw_error_t +fal_qos_port_default_up_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t up) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PORT_DEF_UP_SET, dev_id, port_id, up); + return rv; +} + +sw_error_t +fal_qos_port_default_up_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * up) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PORT_DEF_UP_GET, dev_id, port_id, up); + return rv; +} + +sw_error_t +fal_qos_port_sch_mode_set(a_uint32_t dev_id, a_uint32_t port_id, + fal_sch_mode_t mode, const a_uint32_t weight[]) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PORT_SCH_MODE_SET, dev_id, port_id, mode, + weight); + return rv; +} + +sw_error_t +fal_qos_port_sch_mode_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sch_mode_t * mode, a_uint32_t weight[]) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PORT_SCH_MODE_GET, dev_id, port_id, mode, + weight); + return rv; +} + +sw_error_t +fal_qos_port_default_spri_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t spri) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PT_DEF_SPRI_SET, dev_id, port_id, spri); + return rv; +} + +sw_error_t +fal_qos_port_default_spri_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * spri) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PT_DEF_SPRI_GET, dev_id, port_id, spri); + return rv; +} + +sw_error_t +fal_qos_port_default_cpri_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t cpri) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PT_DEF_CPRI_SET, dev_id, port_id, cpri); + return rv; +} + +sw_error_t +fal_qos_port_default_cpri_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * cpri) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PT_DEF_CPRI_GET, dev_id, port_id, cpri); + return rv; +} + +sw_error_t +fal_qos_port_force_spri_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PT_FORCE_SPRI_ST_SET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_qos_port_force_spri_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable) +{ + sw_error_t rv; + rv = sw_uk_exec(SW_API_QOS_PT_FORCE_SPRI_ST_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_qos_port_force_cpri_status_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PT_FORCE_CPRI_ST_SET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_qos_port_force_cpri_status_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PT_FORCE_CPRI_ST_GET, dev_id, port_id, enable); + return rv; +} + +sw_error_t +fal_qos_queue_remark_table_set(a_uint32_t dev_id, fal_port_t port_id, + fal_queue_t queue_id, a_uint32_t tbl_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_QUEUE_REMARK_SET, dev_id, port_id, queue_id, tbl_id, enable); + return rv; +} + + +sw_error_t +fal_qos_queue_remark_table_get(a_uint32_t dev_id, fal_port_t port_id, + fal_queue_t queue_id, a_uint32_t * tbl_id, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_QUEUE_REMARK_GET, dev_id, port_id, queue_id, tbl_id, enable); + return rv; +} + +sw_error_t +fal_qos_port_group_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_group_t *group) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PORT_GROUP_SET, dev_id, port_id, group); + return rv; +} + +sw_error_t +fal_qos_port_group_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_group_t *group) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PORT_GROUP_GET, dev_id, port_id, group); + return rv; +} + +sw_error_t +fal_qos_port_pri_precedence_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_pri_precedence_t *pri) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PORT_PRI_SET, dev_id, port_id, pri); + return rv; +} + +sw_error_t +fal_qos_port_pri_precedence_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_pri_precedence_t *pri) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PORT_PRI_GET, dev_id, port_id, pri); + return rv; +} + +sw_error_t +fal_qos_port_remark_set(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_remark_enable_t *remark) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PORT_REMARK_SET, dev_id, port_id, remark); + return rv; +} + +sw_error_t +fal_qos_port_remark_get(a_uint32_t dev_id, fal_port_t port_id, + fal_qos_remark_enable_t *remark) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PORT_REMARK_GET, dev_id, port_id, remark); + return rv; +} + +sw_error_t +fal_qos_cosmap_pcp_set(a_uint32_t dev_id, a_uint8_t group_id, + a_uint8_t pcp, fal_qos_cosmap_t *cosmap) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PCP_MAP_SET, dev_id, group_id, pcp, cosmap); + return rv; +} + +sw_error_t +fal_qos_cosmap_pcp_get(a_uint32_t dev_id, a_uint8_t group_id, + a_uint8_t pcp, fal_qos_cosmap_t *cosmap) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PCP_MAP_GET, dev_id, group_id, pcp, cosmap); + return rv; +} + +sw_error_t +fal_qos_cosmap_flow_set(a_uint32_t dev_id, a_uint8_t group_id, + a_uint16_t flow, fal_qos_cosmap_t *cosmap) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_FLOW_MAP_SET, dev_id, group_id, flow, cosmap); + return rv; +} + +sw_error_t +fal_qos_cosmap_flow_get(a_uint32_t dev_id, a_uint8_t group_id, + a_uint16_t flow, fal_qos_cosmap_t *cosmap) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_FLOW_MAP_GET, dev_id, group_id, flow, cosmap); + return rv; +} + +sw_error_t +fal_qos_cosmap_dscp_set(a_uint32_t dev_id, a_uint8_t group_id, + a_uint8_t dscp, fal_qos_cosmap_t *cosmap) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_DSCP_MAP_SET, dev_id, group_id, dscp, cosmap); + return rv; +} + +sw_error_t +fal_qos_cosmap_dscp_get(a_uint32_t dev_id, a_uint8_t group_id, + a_uint8_t dscp, fal_qos_cosmap_t *cosmap) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_DSCP_MAP_GET, dev_id, group_id, dscp, cosmap); + return rv; +} + +sw_error_t +fal_queue_scheduler_set(a_uint32_t dev_id, a_uint32_t node_id, + fal_queue_scheduler_level_t level, fal_port_t port_id, + fal_qos_scheduler_cfg_t *scheduler_cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_QUEUE_SCHEDULER_SET, dev_id, node_id, level, port_id, scheduler_cfg); + return rv; +} + +sw_error_t +fal_queue_scheduler_get(a_uint32_t dev_id, a_uint32_t node_id, + fal_queue_scheduler_level_t level, fal_port_t *port_id, + fal_qos_scheduler_cfg_t *scheduler_cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_QUEUE_SCHEDULER_GET, dev_id, node_id, level, port_id, scheduler_cfg); + return rv; +} + +sw_error_t +fal_edma_ring_queue_map_set(a_uint32_t dev_id, + a_uint32_t ring_id, fal_queue_bmp_t *queue_bmp) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_RING_QUEUE_MAP_SET, dev_id, ring_id, queue_bmp); + return rv; +} + +sw_error_t +fal_edma_ring_queue_map_get(a_uint32_t dev_id, + a_uint32_t ring_id, fal_queue_bmp_t *queue_bmp) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_RING_QUEUE_MAP_GET, dev_id, ring_id, queue_bmp); + return rv; +} + +sw_error_t +fal_port_queues_get(a_uint32_t dev_id, + fal_port_t port_id, fal_queue_bmp_t *queue_bmp) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PORT_QUEUES_GET, dev_id, port_id, queue_bmp); + return rv; +} + +sw_error_t +fal_scheduler_dequeue_ctrl_set(a_uint32_t dev_id, a_uint32_t queue_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_SCHEDULER_DEQUEU_CTRL_SET, dev_id, queue_id, enable); + return rv; +} + +sw_error_t +fal_scheduler_dequeue_ctrl_get(a_uint32_t dev_id, a_uint32_t queue_id, a_bool_t *enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_SCHEDULER_DEQUEU_CTRL_GET, dev_id, queue_id, enable); + return rv; +} + +sw_error_t +fal_port_scheduler_cfg_reset(a_uint32_t dev_id, fal_port_t port_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PORT_SCHEDULER_CFG_RESET, dev_id, port_id); + return rv; +} + +sw_error_t +fal_port_scheduler_resource_get( + a_uint32_t dev_id, + fal_port_t port_id, + fal_portscheduler_resource_t *cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QOS_PORT_SCHEDULER_RESOURCE_GET, dev_id, port_id, cfg); + return rv; +} \ No newline at end of file diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_rate.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_rate.c new file mode 100755 index 000000000..f53ea1bbf --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_rate.c @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_rate.h" +#include "fal_uk_if.h" + +sw_error_t +fal_rate_queue_egrl_set(a_uint32_t dev_id, fal_port_t port_id, + fal_queue_t queue_id, a_uint32_t * speed, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RATE_QU_EGRL_SET, dev_id, port_id, queue_id, + speed, enable); + return rv; +} + +sw_error_t +fal_rate_queue_egrl_get(a_uint32_t dev_id, fal_port_t port_id, + fal_queue_t queue_id, a_uint32_t * speed, + a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RATE_QU_EGRL_GET, dev_id, port_id, queue_id, + speed, enable); + return rv; +} + +sw_error_t +fal_rate_port_egrl_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * speed, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RATE_PT_EGRL_SET, dev_id, port_id, + speed, enable); + return rv; +} + +sw_error_t +fal_rate_port_egrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * speed, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RATE_PT_EGRL_GET, dev_id, port_id, + speed, enable); + return rv; +} + +sw_error_t +fal_rate_port_inrl_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * speed, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RATE_PT_INRL_SET, dev_id, port_id, + speed, enable); + return rv; +} + +sw_error_t +fal_rate_port_inrl_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * speed, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RATE_PT_INRL_GET, dev_id, port_id, + speed, enable); + return rv; +} + +sw_error_t +fal_storm_ctrl_frame_set(a_uint32_t dev_id, fal_port_t port_id, + fal_storm_type_t frame_type, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_STORM_CTRL_FRAME_SET, dev_id, port_id, + frame_type, enable); + return rv; +} + +sw_error_t +fal_storm_ctrl_frame_get(a_uint32_t dev_id, fal_port_t port_id, + fal_storm_type_t frame_type, a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_STORM_CTRL_FRAME_GET, dev_id, port_id, + frame_type, enable); + return rv; +} + +sw_error_t +fal_storm_ctrl_rate_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_STORM_CTRL_RATE_SET, dev_id, port_id, + rate); + return rv; +} + +sw_error_t +fal_storm_ctrl_rate_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t * rate) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_STORM_CTRL_RATE_GET, dev_id, port_id, + rate); + return rv; +} + +sw_error_t +fal_rate_port_policer_set(a_uint32_t dev_id, fal_port_t port_id, + fal_port_policer_t * policer) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RATE_PORT_POLICER_SET, dev_id, port_id, + policer); + return rv; +} + +sw_error_t +fal_rate_port_policer_get(a_uint32_t dev_id, fal_port_t port_id, + fal_port_policer_t * policer) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RATE_PORT_POLICER_GET, dev_id, port_id, + policer); + return rv; +} + +sw_error_t +fal_rate_port_shaper_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable, fal_egress_shaper_t * shaper) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RATE_PORT_SHAPER_SET, dev_id, port_id, + enable, shaper); + return rv; +} + +sw_error_t +fal_rate_port_shaper_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t * enable, fal_egress_shaper_t * shaper) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RATE_PORT_SHAPER_GET, dev_id, port_id, + enable, shaper); + return rv; +} + +sw_error_t +fal_rate_queue_shaper_set(a_uint32_t dev_id, fal_port_t port_id, + fal_queue_t queue_id, a_bool_t enable, + fal_egress_shaper_t * shaper) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RATE_QUEUE_SHAPER_SET, dev_id, port_id, queue_id, + enable, shaper); + return rv; +} + +sw_error_t +fal_rate_queue_shaper_get(a_uint32_t dev_id, fal_port_t port_id, + fal_queue_t queue_id, a_bool_t * enable, + fal_egress_shaper_t * shaper) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RATE_QUEUE_SHAPER_GET, dev_id, port_id, queue_id, + enable, shaper); + return rv; +} + +sw_error_t +fal_rate_acl_policer_set(a_uint32_t dev_id, a_uint32_t policer_id, + fal_acl_policer_t * policer) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RATE_ACL_POLICER_SET, dev_id, policer_id, policer); + return rv; +} + +sw_error_t +fal_rate_acl_policer_get(a_uint32_t dev_id, a_uint32_t policer_id, + fal_acl_policer_t * policer) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RATE_ACL_POLICER_GET, dev_id, policer_id, policer); + return rv; +} + +sw_error_t +fal_rate_port_add_rate_byte_set(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t number) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RATE_PT_ADDRATEBYTE_SET, dev_id, port_id, number); + return rv; +} + +sw_error_t +fal_rate_port_add_rate_byte_get(a_uint32_t dev_id, fal_port_t port_id, + a_uint32_t *number) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RATE_PT_ADDRATEBYTE_GET, dev_id, port_id, number); + return rv; +} + +sw_error_t +fal_rate_port_gol_flow_en_set(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RATE_PT_GOL_FLOW_EN_SET, dev_id, port_id, enable); + return rv; +} + + +sw_error_t +fal_rate_port_gol_flow_en_get(a_uint32_t dev_id, fal_port_t port_id, + a_bool_t* enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RATE_PT_GOL_FLOW_EN_GET, dev_id, port_id, enable); + return rv; +} + + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_reg_access.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_reg_access.c new file mode 100755 index 000000000..6825836b5 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_reg_access.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2014, 2017-2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/*qca808x_start*/ +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_reg_access.h" +#include "fal_uk_if.h" + +sw_error_t +fal_phy_get(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t * value) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PHY_GET, dev_id, phy_addr, reg, value); + return rv; +} + +sw_error_t +fal_phy_set(a_uint32_t dev_id, a_uint32_t phy_addr, + a_uint32_t reg, a_uint16_t value) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PHY_SET, dev_id, phy_addr, reg, value); + return rv; +} +/*qca808x_end*/ +sw_error_t +fal_reg_get(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_REG_GET, dev_id, reg_addr, value, value_len); + return rv; +} + +sw_error_t +fal_reg_set(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_REG_SET, dev_id, reg_addr, value, value_len); + return rv; +} + +sw_error_t +fal_psgmii_reg_get(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PSGMII_REG_GET, dev_id, reg_addr, value, value_len); + return rv; +} + +sw_error_t +fal_psgmii_reg_set(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t value[], + a_uint32_t value_len) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PSGMII_REG_SET, dev_id, reg_addr, value, value_len); + return rv; +} + +sw_error_t +fal_reg_field_get(a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint32_t bit_offset, a_uint32_t field_len, + a_uint8_t value[], a_uint32_t value_len) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_REG_FIELD_GET, dev_id, reg_addr, bit_offset, field_len, value, value_len); + return rv; +} + + +sw_error_t +fal_reg_field_set(a_uint32_t dev_id, a_uint32_t reg_addr, + a_uint32_t bit_offset, a_uint32_t field_len, + const a_uint8_t value[], a_uint32_t value_len) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_REG_FIELD_SET, dev_id, reg_addr, bit_offset, field_len, value, value_len); + return rv; +} + +sw_error_t +fal_reg_dump(a_uint32_t dev_id, a_uint32_t reg_idx,fal_reg_dump_t *reg_dump) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_REG_DUMP, dev_id, reg_idx, reg_dump); + return rv; +} + + +sw_error_t +fal_dbg_reg_dump(a_uint32_t dev_id,fal_reg_dump_t *reg_dump) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_DBG_REG_DUMP, dev_id, reg_dump); + return rv; +} + +sw_error_t +fal_debug_psgmii_self_test(a_uint32_t dev_id, a_bool_t enable, + a_uint32_t times, a_uint32_t * result) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_DBG_PSGMII_SELF_TEST, dev_id, enable, times, result); + return rv; +} +sw_error_t +fal_phy_dump(a_uint32_t dev_id, a_uint32_t phy_addr, a_uint32_t reg_idx,fal_phy_dump_t *phy_dump) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PHY_DUMP, dev_id, phy_addr, reg_idx, phy_dump); + return rv; +} + +sw_error_t +fal_uniphy_reg_get(a_uint32_t dev_id, a_uint32_t index, a_uint32_t reg_addr, + a_uint8_t value[], a_uint32_t value_len) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_UNIPHY_REG_GET, dev_id, index, reg_addr, value, value_len); + return rv; +} + +sw_error_t +fal_uniphy_reg_set(a_uint32_t dev_id, a_uint32_t index, a_uint32_t reg_addr, + a_uint8_t value[], a_uint32_t value_len) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_UNIPHY_REG_SET, dev_id, index, reg_addr, value, value_len); + return rv; +} diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_rss_hash.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_rss_hash.c new file mode 100755 index 000000000..28b67b5a3 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_rss_hash.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_rss_hash.h" +#include "fal_uk_if.h" + +sw_error_t +fal_rss_hash_config_set(a_uint32_t dev_id, fal_rss_hash_mode_t mode, fal_rss_hash_config_t * config) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RSS_HASH_CONFIG_SET, dev_id, mode, + config); + return rv; +} + +sw_error_t +fal_rss_hash_config_get(a_uint32_t dev_id, fal_rss_hash_mode_t mode, fal_rss_hash_config_t * config) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_RSS_HASH_CONFIG_GET, dev_id, mode, + config); + return rv; +} + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_sec.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_sec.c new file mode 100755 index 000000000..60627a40d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_sec.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_sec.h" +#include "fal_uk_if.h" + +sw_error_t +fal_sec_norm_item_set(a_uint32_t dev_id, fal_norm_item_t item, void * value) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SEC_NORM_SET, dev_id, item, value); + return rv; +} + +sw_error_t +fal_sec_norm_item_get(a_uint32_t dev_id, fal_norm_item_t item, void * value) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SEC_NORM_GET, dev_id, item, value); + return rv; +} + +sw_error_t +fal_sec_l3_excep_ctrl_set(a_uint32_t dev_id, a_uint32_t excep_type, fal_l3_excep_ctrl_t *ctrl) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SEC_EXP_CTRL_SET, dev_id, excep_type, ctrl); + return rv; +} + +sw_error_t +fal_sec_l3_excep_ctrl_get(a_uint32_t dev_id, a_uint32_t excep_type, fal_l3_excep_ctrl_t *ctrl) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SEC_EXP_CTRL_GET, dev_id, excep_type, ctrl); + return rv; +} + +sw_error_t +fal_sec_l4_excep_parser_ctrl_get(a_uint32_t dev_id, fal_l4_excep_parser_ctrl *ctrl) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SEC_L4_PARSER_CTRL_GET, dev_id, ctrl); + return rv; +} + +sw_error_t +fal_sec_l4_excep_parser_ctrl_set(a_uint32_t dev_id, fal_l4_excep_parser_ctrl *ctrl) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SEC_L4_PARSER_CTRL_SET, dev_id, ctrl); + return rv; +} + +sw_error_t +fal_sec_l3_excep_parser_ctrl_set(a_uint32_t dev_id, fal_l3_excep_parser_ctrl *ctrl) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SEC_L3_PARSER_CTRL_SET, dev_id, ctrl); + return rv; +} + +sw_error_t +fal_sec_l3_excep_parser_ctrl_get(a_uint32_t dev_id, fal_l3_excep_parser_ctrl *ctrl) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SEC_L3_PARSER_CTRL_GET, dev_id, ctrl); + return rv; +} + + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_servcode.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_servcode.c new file mode 100755 index 000000000..5bc9194ea --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_servcode.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_servcode.h" +#include "fal_uk_if.h" + +sw_error_t fal_servcode_config_set(a_uint32_t dev_id, a_uint32_t servcode_index, + fal_servcode_config_t *entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SERVCODE_CONFIG_SET, dev_id, servcode_index, + entry); + return rv; +} + +sw_error_t fal_servcode_config_get(a_uint32_t dev_id, a_uint32_t servcode_index, + fal_servcode_config_t *entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SERVCODE_CONFIG_GET, dev_id, servcode_index, + entry); + return rv; +} + +sw_error_t fal_servcode_loopcheck_en(a_uint32_t dev_id, a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SERVCODE_LOOPCHECK_EN, dev_id, (a_uint32_t) enable); + return rv; +} + +sw_error_t fal_servcode_loopcheck_status_get(a_uint32_t dev_id, a_bool_t *enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SERVCODE_LOOPCHECK_STATUS_GET, dev_id, enable); + return rv; +} + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_sfp.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_sfp.c new file mode 100755 index 000000000..9b320c040 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_sfp.c @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_sfp.h" +#include "fal_uk_if.h" + +sw_error_t +fal_sfp_eeprom_data_get(a_uint32_t dev_id, a_uint32_t port_id, fal_sfp_data_t *entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SFP_DATA_GET, dev_id, port_id, entry); + return rv; +} + +sw_error_t +fal_sfp_eeprom_data_set(a_uint32_t dev_id, a_uint32_t port_id, fal_sfp_data_t *entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SFP_DATA_SET, dev_id, port_id, entry); + + return rv; +} + +sw_error_t +fal_sfp_device_type_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sfp_dev_type_t *sfp_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SFP_DEV_TYPE_GET, dev_id, port_id, + sfp_id); + return rv; +} + +sw_error_t +fal_sfp_transceiver_code_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sfp_transc_code_t *transc_code) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SFP_TRANSC_CODE_GET, dev_id, port_id, + transc_code); + return rv; +} + +sw_error_t +fal_sfp_rate_encode_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sfp_rate_encode_t *encode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SFP_RATE_ENCODE_GET, dev_id, port_id, + encode); + return rv; +} + +sw_error_t +fal_sfp_link_length_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sfp_link_length_t *link_len) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SFP_LINK_LENGTH_GET, dev_id, port_id, + link_len); + return rv; +} + +sw_error_t +fal_sfp_vendor_info_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sfp_vendor_info_t *vender_info) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SFP_VENDOR_INFO_GET, dev_id, port_id, + vender_info); + return rv; +} + +sw_error_t +fal_sfp_laser_wavelength_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sfp_laser_wavelength_t *laser_wavelen) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SFP_LASER_WAVELENGTH_GET, dev_id, port_id, + laser_wavelen); + return rv; +} + +sw_error_t +fal_sfp_option_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sfp_option_t *option) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SFP_OPTION_GET, dev_id, port_id, + option); + return rv; +} + +sw_error_t +fal_sfp_ctrl_rate_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sfp_rate_t *rate_limit) + +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SFP_CTRL_RATE_GET, dev_id, port_id, + rate_limit); + return rv; +} +sw_error_t +fal_sfp_enhanced_cfg_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sfp_enhanced_cfg_t *enhanced_feature) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SFP_ENHANCED_CFG_GET, dev_id, port_id, + enhanced_feature); + return rv; +} + +sw_error_t +fal_sfp_diag_internal_threshold_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sfp_internal_threshold_t *threshold) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SFP_DIAG_THRESHOLD_GET, dev_id, port_id, + threshold); + return rv; +} + +sw_error_t +fal_sfp_diag_extenal_calibration_const_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sfp_cal_const_t *cal_const) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SFP_DIAG_CAL_CONST_GET, dev_id, port_id, + cal_const); + return rv; +} + +sw_error_t +fal_sfp_diag_realtime_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sfp_realtime_diag_t *real_diag) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SFP_DIAG_REALTIME_GET, dev_id, port_id, + real_diag); + return rv; +} + +sw_error_t +fal_sfp_diag_ctrl_status_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sfp_ctrl_status_t *ctrl_status) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SFP_DIAG_CTRL_STATUS_GET, dev_id, port_id, + ctrl_status); + return rv; +} + +sw_error_t +fal_sfp_diag_alarm_warning_flag_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sfp_alarm_warn_flag_t *alarm_warn_flag) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SFP_DIAG_ALARM_WARN_FLAG_GET, dev_id, port_id, + alarm_warn_flag); + return rv; +} + +sw_error_t +fal_sfp_checkcode_get(a_uint32_t dev_id, a_uint32_t port_id, + fal_sfp_cc_type_t cc_type, a_uint8_t *ccode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SFP_CHECKCODE_GET, dev_id, port_id, (a_ulong_t)cc_type, + ccode); + return rv; +} diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_shaper.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_shaper.c new file mode 100755 index 000000000..e579307fe --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_shaper.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_shaper.h" +#include "fal_uk_if.h" + + +sw_error_t +fal_port_shaper_timeslot_set(a_uint32_t dev_id, a_uint32_t timeslot) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PORT_SHAPER_TIMESLOT_SET, dev_id, timeslot); + return rv; +} + +sw_error_t +fal_port_shaper_timeslot_get(a_uint32_t dev_id, a_uint32_t *timeslot) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PORT_SHAPER_TIMESLOT_GET, dev_id, timeslot); + return rv; +} + +sw_error_t +fal_flow_shaper_timeslot_set(a_uint32_t dev_id, a_uint32_t timeslot) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_SHAPER_TIMESLOT_SET, dev_id, timeslot); + return rv; +} + +sw_error_t +fal_flow_shaper_timeslot_get(a_uint32_t dev_id, a_uint32_t *timeslot) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_SHAPER_TIMESLOT_GET, dev_id, timeslot); + return rv; +} + +sw_error_t +fal_queue_shaper_timeslot_set(a_uint32_t dev_id, a_uint32_t timeslot) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QUEUE_SHAPER_TIMESLOT_SET, dev_id, timeslot); + return rv; +} + +sw_error_t +fal_queue_shaper_timeslot_get(a_uint32_t dev_id, a_uint32_t *timeslot) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QUEUE_SHAPER_TIMESLOT_GET, dev_id, timeslot); + return rv; +} + +sw_error_t +fal_port_shaper_token_number_set(a_uint32_t dev_id, fal_port_t port_id, + fal_shaper_token_number_t * token_number) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PORT_SHAPER_TOKEN_NUMBER_SET, dev_id, port_id, + token_number); + return rv; +} + +sw_error_t +fal_port_shaper_token_number_get(a_uint32_t dev_id, fal_port_t port_id, + fal_shaper_token_number_t * token_number) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PORT_SHAPER_TOKEN_NUMBER_GET, dev_id, port_id, + token_number); + return rv; +} + +sw_error_t +fal_flow_shaper_token_number_set(a_uint32_t dev_id, a_uint32_t flow_id, + fal_shaper_token_number_t * token_number) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_SHAPER_TOKEN_NUMBER_SET, dev_id, flow_id, + token_number); + return rv; +} + +sw_error_t +fal_flow_shaper_token_number_get(a_uint32_t dev_id, a_uint32_t flow_id, + fal_shaper_token_number_t * token_number) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_SHAPER_TOKEN_NUMBER_GET, dev_id, flow_id, + token_number); + return rv; +} + +sw_error_t +fal_queue_shaper_token_number_set(a_uint32_t dev_id, a_uint32_t queue_id, + fal_shaper_token_number_t * token_number) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QUEUE_SHAPER_TOKEN_NUMBER_SET, dev_id, queue_id, + token_number); + return rv; +} + +sw_error_t +fal_queue_shaper_token_number_get(a_uint32_t dev_id, a_uint32_t queue_id, + fal_shaper_token_number_t * token_number) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QUEUE_SHAPER_TOKEN_NUMBER_GET, dev_id, queue_id, + token_number); + return rv; +} + +sw_error_t +fal_port_shaper_set(a_uint32_t dev_id, fal_port_t port_id, fal_shaper_config_t * shaper) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PORT_SHAPER_SET, dev_id, port_id, + shaper); + return rv; +} + +sw_error_t +fal_port_shaper_get(a_uint32_t dev_id, fal_port_t port_id, fal_shaper_config_t * shaper) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PORT_SHAPER_GET, dev_id, port_id, + shaper); + return rv; +} + +sw_error_t +fal_flow_shaper_set(a_uint32_t dev_id, a_uint32_t flow_id, fal_shaper_config_t * shaper) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_SHAPER_SET, dev_id, flow_id, + shaper); + return rv; +} + +sw_error_t +fal_flow_shaper_get(a_uint32_t dev_id, a_uint32_t flow_id, fal_shaper_config_t * shaper) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_FLOW_SHAPER_GET, dev_id, flow_id, + shaper); + return rv; +} + +sw_error_t +fal_queue_shaper_set(a_uint32_t dev_id, a_uint32_t queue_id, fal_shaper_config_t * shaper) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QUEUE_SHAPER_SET, dev_id, queue_id, + shaper); + return rv; +} + +sw_error_t +fal_queue_shaper_get(a_uint32_t dev_id, a_uint32_t queue_id, fal_shaper_config_t * shaper) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_QUEUE_SHAPER_GET, dev_id, queue_id, + shaper); + return rv; +} + +sw_error_t +fal_shaper_ipg_preamble_length_set(a_uint32_t dev_id, a_uint32_t ipg_pre_length) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SHAPER_IPG_PRE_SET, dev_id, ipg_pre_length); + return rv; +} + +sw_error_t +fal_shaper_ipg_preamble_length_get(a_uint32_t dev_id, a_uint32_t *ipg_pre_length) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_SHAPER_IPG_PRE_GET, dev_id, ipg_pre_length); + return rv; +} + + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_stp.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_stp.c new file mode 100755 index 000000000..dce40792a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_stp.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014, 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_stp.h" +#include "fal_uk_if.h" + +sw_error_t +fal_stp_port_state_set(a_uint32_t dev_id, a_uint32_t st_id, + fal_port_t port_id, fal_stp_state_t state) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_STP_PT_STATE_SET, dev_id, st_id, port_id, + (a_uint32_t) state); + return rv; +} + +sw_error_t +fal_stp_port_state_get(a_uint32_t dev_id, a_uint32_t st_id, + fal_port_t port_id, fal_stp_state_t * state) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_STP_PT_STATE_GET, dev_id, st_id, port_id, + state); + return rv; +} diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_trunk.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_trunk.c new file mode 100755 index 000000000..d509d41f8 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_trunk.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2014, 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_trunk.h" +#include "fal_uk_if.h" + + +sw_error_t +fal_trunk_group_set(a_uint32_t dev_id, a_uint32_t trunk_id, + a_bool_t enable, fal_pbmp_t member) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_TRUNK_GROUP_SET, dev_id, trunk_id, enable, + (a_uint32_t) member); + return rv; +} + +sw_error_t +fal_trunk_group_get(a_uint32_t dev_id, a_uint32_t trunk_id, + a_bool_t * enable, fal_pbmp_t * member) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_TRUNK_GROUP_GET, dev_id, trunk_id, enable, + member); + return rv; +} + +sw_error_t +fal_trunk_hash_mode_set(a_uint32_t dev_id, a_uint32_t hash_mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_TRUNK_HASH_SET, dev_id, hash_mode); + return rv; +} + +sw_error_t +fal_trunk_hash_mode_get(a_uint32_t dev_id, a_uint32_t * hash_mode) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_TRUNK_HASH_GET, dev_id, hash_mode); + return rv; +} + +sw_error_t +fal_trunk_manipulate_sa_set(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_TRUNK_MAN_SA_SET, dev_id, addr); + return rv; +} + +sw_error_t +fal_trunk_manipulate_sa_get(a_uint32_t dev_id, fal_mac_addr_t * addr) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_TRUNK_MAN_SA_GET, dev_id, addr); + return rv; +} + +sw_error_t +fal_trunk_failover_enable(a_uint32_t dev_id, a_bool_t failover) + +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_TRUNK_FAILOVER_EN_SET, dev_id, failover); + return rv; +} + +sw_error_t +fal_trunk_failover_status_get(a_uint32_t dev_id, a_bool_t *failover) + +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_TRUNK_FAILOVER_EN_GET, dev_id, failover); + return rv; +} + + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_uk_if.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_uk_if.c new file mode 100755 index 000000000..891ef938d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_uk_if.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +#include +#include "sw.h" +#include "ssdk_init.h" +#include "sw_api.h" +#include "sw_api_us.h" +#include "api_access.h" + +sw_error_t +sw_uk_exec(a_uint32_t api_id, ...) +{ + unsigned long value[SW_MAX_API_PARAM] = { 0 }; + unsigned long rtn = SW_OK, i; + va_list arg_ptr; + a_uint32_t nr_param = 0; + + if((nr_param = sw_api_param_nums(api_id)) == 0) + { + return SW_NOT_SUPPORTED; + } + + value[0] = (unsigned long)api_id; + value[1] = (unsigned long)&rtn; + + va_start(arg_ptr, api_id); + for (i = 0; i < nr_param; i++) + { + value[i + 2] = va_arg(arg_ptr, unsigned long); + } + va_end(arg_ptr); + sw_uk_if(value); + + return rtn; +} + +sw_error_t +ssdk_init(a_uint32_t dev_id, ssdk_init_cfg * cfg) +{ + sw_error_t rv; + + rv = sw_uk_init(cfg->nl_prot); + return rv; +} + +sw_error_t +ssdk_cleanup(void) +{ + sw_error_t rv; + + rv = sw_uk_cleanup(); + return rv; +} + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_vlan.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_vlan.c new file mode 100755 index 000000000..eef60b186 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_vlan.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + +#include "sw.h" +#include "sw_ioctl.h" +#include "fal_vlan.h" +#include "fal_uk_if.h" + +sw_error_t +fal_vlan_entry_append(a_uint32_t dev_id, fal_vlan_t * vlan_entry) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VLAN_APPEND, dev_id, vlan_entry); + return rv; +} + + +sw_error_t +fal_vlan_create(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VLAN_ADD, dev_id, vlan_id); + return rv; +} + +sw_error_t +fal_vlan_next(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VLAN_NEXT, dev_id, vlan_id, p_vlan); + return rv; +} + +sw_error_t +fal_vlan_find(a_uint32_t dev_id, a_uint32_t vlan_id, fal_vlan_t * p_vlan) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VLAN_FIND, dev_id, vlan_id, p_vlan); + return rv; +} + +sw_error_t +fal_vlan_member_update(a_uint32_t dev_id, a_uint32_t vlan_id, + fal_pbmp_t member, fal_pbmp_t u_member) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VLAN_MEM_UPDATE, dev_id, vlan_id, member, + u_member); + return rv; +} + +sw_error_t +fal_vlan_delete(a_uint32_t dev_id, a_uint32_t vlan_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VLAN_DEL, dev_id, vlan_id); + return rv; +} + +sw_error_t +fal_vlan_flush(a_uint32_t dev_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VLAN_FLUSH, dev_id); + return rv; +} + +sw_error_t +fal_vlan_fid_set(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t fid) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VLAN_FID_SET, dev_id, vlan_id, fid); + return rv; +} + +sw_error_t +fal_vlan_fid_get(a_uint32_t dev_id, a_uint32_t vlan_id, a_uint32_t * fid) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VLAN_FID_GET, dev_id, vlan_id, fid); + return rv; +} + +sw_error_t +fal_vlan_member_add(a_uint32_t dev_id, a_uint32_t vlan_id, + fal_port_t port_id, fal_pt_1q_egmode_t port_info) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VLAN_MEMBER_ADD, dev_id, vlan_id, port_id, port_info); + return rv; +} + +sw_error_t +fal_vlan_member_del(a_uint32_t dev_id, a_uint32_t vlan_id, fal_port_t port_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VLAN_MEMBER_DEL, dev_id, vlan_id, port_id); + return rv; +} + +sw_error_t +fal_vlan_learning_state_set(a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VLAN_LEARN_STATE_SET, dev_id, vlan_id, enable); + return rv; +} + +sw_error_t +fal_vlan_learning_state_get(a_uint32_t dev_id, a_uint32_t vlan_id, + a_bool_t * enable) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VLAN_LEARN_STATE_GET, dev_id, vlan_id, enable); + return rv; +} + + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_vsi.c b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_vsi.c new file mode 100755 index 000000000..ddfe8c623 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/fal_uk/fal_vsi.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "sw_ioctl.h" +#include "fal_vsi.h" +#include "fal_uk_if.h" + +sw_error_t +fal_port_vsi_get(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t *vsi_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PORT_VSI_GET, dev_id, port_id, vsi_id); + return rv; +} + +sw_error_t +fal_port_vlan_vsi_set(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t stag_vid, a_uint32_t ctag_vid, a_uint32_t vsi_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PORT_VLAN_VSI_SET, dev_id, port_id, stag_vid, ctag_vid, vsi_id); + return rv; +} + +sw_error_t +fal_vsi_free(a_uint32_t dev_id, a_uint32_t vsi) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VSI_FREE, dev_id, vsi); + return rv; +} + +sw_error_t +fal_port_vlan_vsi_get(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t stag_vid, a_uint32_t ctag_vid, a_uint32_t *vsi_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PORT_VLAN_VSI_GET, dev_id, port_id, stag_vid, ctag_vid, vsi_id); + return rv; +} + +sw_error_t +fal_port_vsi_set(a_uint32_t dev_id, fal_port_t port_id, a_uint32_t vsi_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_PORT_VSI_SET, dev_id, port_id, vsi_id); + return rv; +} + +sw_error_t +fal_vsi_alloc(a_uint32_t dev_id, a_uint32_t *vsi) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VSI_ALLOC, dev_id, vsi); + return rv; +} + +sw_error_t +fal_vsi_tbl_dump(a_uint32_t dev_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VSI_TBL_DUMP, dev_id); + return rv; +} + +sw_error_t +fal_vsi_stamove_set(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_stamove_t *stamove) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VSI_STAMOVE_SET, dev_id, vsi_id, stamove); + return rv; +} +sw_error_t +fal_vsi_stamove_get(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_stamove_t *stamove) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VSI_STAMOVE_GET, dev_id, vsi_id, stamove); + return rv; +} +sw_error_t +fal_vsi_newaddr_lrn_get(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_newaddr_lrn_t *newaddr_lrn) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VSI_NEWADDR_LRN_GET, dev_id, vsi_id, newaddr_lrn); + return rv; +} +sw_error_t +fal_vsi_newaddr_lrn_set(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_newaddr_lrn_t *newaddr_lrn) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VSI_NEWADDR_LRN_SET, dev_id, vsi_id, newaddr_lrn); + return rv; +} +sw_error_t +fal_vsi_member_get(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_member_t *vsi_member) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VSI_MEMBER_GET, dev_id, vsi_id, vsi_member); + return rv; +} +sw_error_t +fal_vsi_member_set(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_member_t *vsi_member) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VSI_MEMBER_SET, dev_id, vsi_id, vsi_member); + return rv; +} + +sw_error_t +fal_vsi_counter_get(a_uint32_t dev_id, a_uint32_t vsi_id, fal_vsi_counter_t *counter) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VSI_COUNTER_GET, dev_id, vsi_id, counter); + return rv; +} + +sw_error_t +fal_vsi_counter_cleanup(a_uint32_t dev_id, a_uint32_t vsi_id) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_VSI_COUNTER_CLEANUP, dev_id, vsi_id); + return rv; +} + + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/ref/Makefile b/feeds/ipq807x/qca-ssdk-shell/src/src/ref/Makefile new file mode 100755 index 000000000..f92ae6c45 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/ref/Makefile @@ -0,0 +1,16 @@ +LOC_DIR=src/ref +LIB=REF + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST= + +ifeq (TRUE, $(IN_VLAN)) + SRC_LIST += ref_vlan.c +endif + +include $(PRJ_PATH)/make/components.mk +include $(PRJ_PATH)/make/defs.mk +include $(PRJ_PATH)/make/target.mk + +all: dep obj diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/ref/ref_vlan.c b/feeds/ipq807x/qca-ssdk-shell/src/src/ref/ref_vlan.c new file mode 100755 index 000000000..d1af39455 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/ref/ref_vlan.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "sw.h" +#include "sw_ioctl.h" +#include "ref_vlan.h" +#include "fal_uk_if.h" + +sw_error_t +qca_lan_wan_cfg_set(a_uint32_t dev_id, qca_lan_wan_cfg_t *lan_wan_cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_LAN_WAN_CFG_SET, dev_id, lan_wan_cfg); + return rv; +} + +sw_error_t +qca_lan_wan_cfg_get(a_uint32_t dev_id, qca_lan_wan_cfg_t *lan_wan_cfg) +{ + sw_error_t rv; + + rv = sw_uk_exec(SW_API_LAN_WAN_CFG_GET, dev_id, lan_wan_cfg); + return rv; +} diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/sal/Makefile b/feeds/ipq807x/qca-ssdk-shell/src/src/sal/Makefile new file mode 100755 index 000000000..805ae0f63 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/sal/Makefile @@ -0,0 +1,12 @@ +LOC_DIR=src/sal +LIB=SAL + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST=$(wildcard *.c) + +include $(PRJ_PATH)/make/components.mk +include $(PRJ_PATH)/make/defs.mk +include $(PRJ_PATH)/make/target.mk + +all: dep obj diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/Makefile b/feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/Makefile new file mode 100755 index 000000000..74c50e2eb --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/Makefile @@ -0,0 +1,12 @@ +LOC_DIR=src/sal/sd +LIB=SAL + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST=$(wildcard *.c) + +include $(PRJ_PATH)/make/components.mk +include $(PRJ_PATH)/make/defs.mk +include $(PRJ_PATH)/make/target.mk + +all: dep obj \ No newline at end of file diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/linux/Makefile b/feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/linux/Makefile new file mode 100755 index 000000000..a038efc6d --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/linux/Makefile @@ -0,0 +1,12 @@ +LOC_DIR=src/sal/sd/linux +LIB=SAL + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST=$(wildcard *.c) + +include $(PRJ_PATH)/make/components.mk +include $(PRJ_PATH)/make/defs.mk +include $(PRJ_PATH)/make/target.mk + +all: dep obj \ No newline at end of file diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/linux/uk_interface/Makefile b/feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/linux/uk_interface/Makefile new file mode 100755 index 000000000..a4bac32fe --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/linux/uk_interface/Makefile @@ -0,0 +1,34 @@ +LOC_DIR=src/sal/sd/linux/uk_interface +LIB=SAL + +include $(PRJ_PATH)/make/config.mk + +SRC_LIST= + +ifeq (TRUE, $(UK_IF)) +ifeq (KSLIB, $(MODULE_TYPE)) + ifeq (TRUE, $(UK_NETLINK)) + SRC_LIST=sw_api_ks_netlink.c + endif + + ifeq (TRUE, $(UK_IOCTL)) + SRC_LIST=sw_api_ks_ioctl.c + endif +endif + +ifeq (USLIB, $(MODULE_TYPE)) + ifeq (TRUE, $(UK_NETLINK)) + SRC_LIST=sw_api_us_netlink.c + endif + + ifeq (TRUE, $(UK_IOCTL)) + SRC_LIST=sw_api_us_ioctl.c + endif +endif +endif + +include $(PRJ_PATH)/make/components.mk +include $(PRJ_PATH)/make/defs.mk +include $(PRJ_PATH)/make/target.mk + +all: dep obj \ No newline at end of file diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/linux/uk_interface/sw_api_us_ioctl.c b/feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/linux/uk_interface/sw_api_us_ioctl.c new file mode 100755 index 000000000..6e977726f --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/linux/uk_interface/sw_api_us_ioctl.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2014, 2017-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "sw.h" +#include "sw_api.h" +#include "sw_api_us.h" + +#define MISC_CHR_DEV 10 +static int glb_socket_fd = 0; + +sw_error_t +sw_uk_if(unsigned long arg_val[SW_MAX_API_PARAM]) +{ + ioctl(glb_socket_fd, SIOCDEVPRIVATE, arg_val); + return SW_OK; +} + +#ifndef SHELL_DEV +#define SHELL_DEV "/dev/switch_ssdk" +#endif +#define MISC_DEV "/proc/misc" + +static int sw_device_minor_get(a_uint32_t *device_minor) +{ + char buf[200] = {0}; + FILE *fp; + char *p; + + fp = fopen(MISC_DEV, "r"); + if (!fp) { + printf("failed to open %s\n", MISC_DEV); + return -1; + } + fseek(fp, 0, SEEK_SET); + while (fgets(buf, 200, fp) != NULL) { + p = strstr(buf, "switch_ssdk"); + if (p) { + sscanf(buf,"%d",device_minor); + fclose(fp); + return 0; + } + } + + fclose(fp); + return -1; +} + +static void sw_device_check(void) +{ + struct stat buf; + a_uint32_t file_minor; + a_uint32_t device_minor; + int rv; + + memset(&buf, 0, sizeof(buf)); + + if (stat( SHELL_DEV, &buf) < 0) { + printf("failed to stat!\n"); + return; + } + if (S_ISCHR(buf.st_mode)) { + file_minor = minor(buf.st_rdev); + rv = sw_device_minor_get(&device_minor); + if (!rv) { + if (device_minor != file_minor) + printf("device:%x file:%x mismatch!\n", + device_minor, file_minor); + else + printf("device:%x file:%x match!\n", + device_minor, file_minor); + } + } + +} + + +sw_error_t +sw_uk_init(a_uint32_t nl_prot) +{ + if (!glb_socket_fd) + { + /* even mknod fail we not quit, perhaps the device node exist already */ +#if defined UK_MINOR_DEV + mknod(SHELL_DEV, S_IFCHR, makedev(MISC_CHR_DEV, UK_MINOR_DEV)); +#else + mknod(SHELL_DEV, S_IFCHR, makedev(MISC_CHR_DEV, nl_prot)); +#endif + if ((glb_socket_fd = open(SHELL_DEV, O_RDWR)) < 0) + { + sw_device_check(); + return SW_INIT_ERROR; + } + } + + return SW_OK; +} + +sw_error_t +sw_uk_cleanup(void) +{ + close(glb_socket_fd); + glb_socket_fd = 0; +#if 0 + remove("/dev/switch_ssdk"); +#endif + return SW_OK; +} + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/linux/uk_interface/sw_api_us_netlink.c b/feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/linux/uk_interface/sw_api_us_netlink.c new file mode 100755 index 000000000..d3a448000 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/linux/uk_interface/sw_api_us_netlink.c @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include "sw.h" +#include "sw_api.h" +#include "sw_api_us.h" + +#define SSDK_SOCK_SEND_TRY_NUM 1000 +#define SSDK_SOCK_RCV_TRY_NUM 1000 +#define SSDK_SOCK_FD_NUM 16 +typedef struct +{ + a_uint32_t ssdk_sock_pid; + a_int32_t ssdk_sock_fd; +} ssdk_sock_t; +ssdk_sock_t ssdk_sock[SSDK_SOCK_FD_NUM]; + +static a_uint32_t ssdk_sock_prot = 0; +static struct nlmsghdr *nl_hdr = NULL; +#if defined(API_LOCK) +static aos_lock_t ssdk_sock_lock; +#define SOCK_LOCKER_INIT aos_lock_init(&ssdk_sock_lock) +#define SOCK_LOCKER_LOCK aos_lock(&ssdk_sock_lock) +#define SOCK_LOCKER_UNLOCK aos_unlock(&ssdk_sock_lock) +#else +#define SOCK_LOCKER_INIT +#define SOCK_LOCKER_LOCK +#define SOCK_LOCKER_UNLOCK +#endif + +static ssdk_sock_t * +ssdk_sock_alloc(a_uint32_t pid) +{ + a_uint32_t i; + + for (i = 0; i < SSDK_SOCK_FD_NUM; i++) + { + if (!ssdk_sock[i].ssdk_sock_pid) + { + return &ssdk_sock[i]; + } + else + { + if (0 != kill(ssdk_sock[i].ssdk_sock_pid, 0)) + { + return &ssdk_sock[i]; + } + } + } + + return NULL; +} + +static ssdk_sock_t * +ssdk_sock_find(a_uint32_t pid) +{ + a_uint32_t i; + + for (i = 0; i < SSDK_SOCK_FD_NUM; i++) + { + if (ssdk_sock[i].ssdk_sock_pid == pid) + { + return &ssdk_sock[i]; + } + } + + return NULL; +} + +sw_error_t +sw_uk_if(a_uint32_t arg_val[SW_MAX_API_PARAM]) +{ + struct sockaddr_nl src_addr; + struct sockaddr_nl dest_addr; + struct msghdr msg; + struct iovec iov; + struct nlmsghdr *nlh; + ssdk_sock_t * sock; + a_int32_t sock_fd; + a_uint32_t curr_pid; + sw_error_t rv = SW_OK; + a_uint32_t i, j, flag; + + curr_pid = getpid(); + + SOCK_LOCKER_LOCK; + sock = ssdk_sock_find(curr_pid); + if (!sock) + { + sock = ssdk_sock_alloc(curr_pid); + if (!sock) + { + SW_OUT_ON_ERROR(SW_NO_RESOURCE); + } + + sock_fd = socket(PF_NETLINK, SOCK_RAW, ssdk_sock_prot); + aos_mem_set(&src_addr, 0, sizeof(src_addr)); + src_addr.nl_family = AF_NETLINK; + src_addr.nl_pid = curr_pid; + src_addr.nl_groups = 0; + bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr)); + + sock->ssdk_sock_fd = sock_fd; + sock->ssdk_sock_pid = curr_pid; + } + else + { + sock_fd = sock->ssdk_sock_fd; + } + + aos_mem_set(&dest_addr, 0, sizeof(dest_addr)); + dest_addr.nl_family = AF_NETLINK; + dest_addr.nl_pid = 0; + dest_addr.nl_groups = 0; + + nlh = nl_hdr; + aos_mem_set(nlh, 0, NLMSG_SPACE(SW_MAX_PAYLOAD)); + nlh->nlmsg_len = NLMSG_SPACE(SW_MAX_PAYLOAD); + nlh->nlmsg_pid = curr_pid; + nlh->nlmsg_flags = 0; + aos_mem_copy(NLMSG_DATA(nlh), arg_val, SW_MAX_PAYLOAD); + + iov.iov_base = (void *)nlh; + iov.iov_len = nlh->nlmsg_len; + + aos_mem_set(&msg, 0, sizeof(msg)); + msg.msg_name = (void *)&dest_addr; + msg.msg_namelen = sizeof(dest_addr); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + for (i = 0; i < SSDK_SOCK_SEND_TRY_NUM; i++) + { + if (0 < sendmsg(sock_fd, &msg, MSG_DONTWAIT)) + { + break; + } + } + + if (SSDK_SOCK_SEND_TRY_NUM <= i) + { + SW_OUT_ON_ERROR(SW_TIMEOUT); + } + + flag = 0; + aos_mem_set(nlh, 0, NLMSG_SPACE(SW_MAX_PAYLOAD)); + for (i = 0; i < SSDK_SOCK_RCV_TRY_NUM; i++) + { + for (j = 0; j < 1000; j++) + { + if (0 < recvmsg(sock_fd, &msg, MSG_DONTWAIT)) + { + flag = 1; + break; + } + } + + if (flag) + { + break; + } + else + { + aos_mdelay(10); + } + } + + if (SSDK_SOCK_RCV_TRY_NUM <= i) + { + SW_OUT_ON_ERROR(SW_TIMEOUT); + } + +out: + SOCK_LOCKER_UNLOCK; + return rv; +} + +sw_error_t +sw_uk_init(a_uint32_t nl_prot) +{ + if (!nl_hdr) + { + nl_hdr = (struct nlmsghdr *)aos_mem_alloc(NLMSG_SPACE(SW_MAX_PAYLOAD)); + } + + if (!nl_hdr) + { + return SW_NO_RESOURCE; + } + +#if defined UK_NL_PROT + ssdk_sock_prot = UK_NL_PROT; +#else + ssdk_sock_prot = nl_prot; +#endif + SOCK_LOCKER_INIT; + aos_mem_zero(ssdk_sock, sizeof(ssdk_sock_t) * SSDK_SOCK_FD_NUM); + return SW_OK; +} + +sw_error_t +sw_uk_cleanup(void) +{ + aos_mem_zero(ssdk_sock, sizeof(ssdk_sock_t) * SSDK_SOCK_FD_NUM); + + if (nl_hdr) + { + aos_mem_free(nl_hdr); + nl_hdr = NULL; + } + + return SW_OK; +} + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/sd.c b/feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/sd.c new file mode 100755 index 000000000..9b7037c95 --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/sal/sd/sd.c @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +#include "sw.h" +#include "ssdk_init.h" +#include "sd.h" +#include "sw_api.h" +#if ((!defined(KERNEL_MODULE)) && defined(UK_IF)) +#include "sw_api_us.h" +#endif + +mdio_reg_set ssdk_mdio_set = NULL; +mdio_reg_get ssdk_mdio_get = NULL; +hdr_reg_set ssdk_hdr_reg_set = NULL; +hdr_reg_get ssdk_hdr_reg_get = NULL; +uniphy_reg_set ssdk_uniphy_reg_set = NULL; +uniphy_reg_get ssdk_uniphy_reg_get = NULL; +mii_reg_set ssdk_mii_reg_set = NULL; +mii_reg_get ssdk_mii_reg_get = NULL; + +sw_error_t +sd_reg_mdio_set(a_uint32_t dev_id, a_uint32_t phy, a_uint32_t reg, + a_uint16_t data) +{ + sw_error_t rv = SW_OK; + + if (NULL != ssdk_mdio_set) + { + rv = ssdk_mdio_set(dev_id, phy, reg, data); + } + else + { + return SW_NOT_SUPPORTED; + } + + return rv; +} + +sw_error_t +sd_reg_mdio_get(a_uint32_t dev_id, a_uint32_t phy, a_uint32_t reg, a_uint16_t * data) +{ + sw_error_t rv = SW_OK; + + if (NULL != ssdk_mdio_get) + { + rv = ssdk_mdio_get(dev_id, phy, reg, data); + } + else + { + return SW_NOT_SUPPORTED; + } + + return rv; +} + +sw_error_t +sd_reg_hdr_set(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t * reg_data, a_uint32_t len) +{ + sw_error_t rv; + + if (NULL != ssdk_hdr_reg_set) + { + rv = ssdk_hdr_reg_set(dev_id, reg_addr, reg_data, len); + } + else + { + return SW_NOT_SUPPORTED; + } + + return rv; +} + +sw_error_t +sd_reg_hdr_get(a_uint32_t dev_id, a_uint32_t reg_addr, a_uint8_t * reg_data, a_uint32_t len) +{ + sw_error_t rv; + + if (NULL != ssdk_hdr_reg_get) + { + rv = ssdk_hdr_reg_get(dev_id, reg_addr, reg_data, len); + } + else + { + return SW_NOT_SUPPORTED; + } + + return rv; +} + +sw_error_t +sd_reg_uniphy_set(a_uint32_t dev_id, a_uint32_t index, a_uint32_t reg_addr, + a_uint8_t * reg_data, a_uint32_t len) +{ + sw_error_t rv; + + if (NULL != ssdk_uniphy_reg_set) + { + rv = ssdk_uniphy_reg_set(dev_id, index, reg_addr, reg_data, len); + } + else + { + return SW_NOT_SUPPORTED; + } + + return rv; +} + +sw_error_t +sd_reg_uniphy_get(a_uint32_t dev_id, a_uint32_t index, a_uint32_t reg_addr, + a_uint8_t * reg_data, a_uint32_t len) +{ + sw_error_t rv; + + if (NULL != ssdk_uniphy_reg_get) + { + rv = ssdk_uniphy_reg_get(dev_id, index, reg_addr, reg_data, len); + } + else + { + return SW_NOT_SUPPORTED; + } + + return rv; +} + +void +sd_reg_mii_set(a_uint32_t reg, a_uint32_t val) +{ + if (NULL != ssdk_mii_reg_set) + { + ssdk_mii_reg_set(reg, val); + } +} + +a_uint32_t +sd_reg_mii_get(a_uint32_t reg) +{ + a_uint32_t value = 0; + + if (NULL != ssdk_mii_reg_get) + { + value = ssdk_mii_reg_get(reg); + } + + return value; +} + +sw_error_t +sd_init(a_uint32_t dev_id, ssdk_init_cfg * cfg) +{ + if (NULL != cfg->reg_func.mdio_set) + { + ssdk_mdio_set = cfg->reg_func.mdio_set; + } + + if (NULL != cfg->reg_func.mdio_get) + { + ssdk_mdio_get = cfg->reg_func.mdio_get; + } + + if (NULL != cfg->reg_func.header_reg_set) + { + ssdk_hdr_reg_set = cfg->reg_func.header_reg_set; + } + + if (NULL != cfg->reg_func.header_reg_get) + { + ssdk_hdr_reg_get = cfg->reg_func.header_reg_get; + } + if (NULL != cfg->reg_func.uniphy_reg_set) + { + ssdk_uniphy_reg_set = cfg->reg_func.uniphy_reg_set; + } + + if (NULL != cfg->reg_func.uniphy_reg_get) + { + ssdk_uniphy_reg_get = cfg->reg_func.uniphy_reg_get; + } + + if (NULL != cfg->reg_func.mii_reg_set) + { + ssdk_mii_reg_set = cfg->reg_func.mii_reg_set; + } + + if (NULL != cfg->reg_func.mii_reg_get) + { + ssdk_mii_reg_get = cfg->reg_func.mii_reg_get; + } + + return SW_OK; +} + diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/shell/Makefile b/feeds/ipq807x/qca-ssdk-shell/src/src/shell/Makefile new file mode 100755 index 000000000..668a48a4a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/shell/Makefile @@ -0,0 +1,24 @@ +LOC_DIR=src/shell +LIB=SHELL + +include $(PRJ_PATH)/make/config.mk +include $(PRJ_PATH)/make/components.mk + +SRC_LIST=$(wildcard *.c) +ifeq (,$(findstring SHELL, $(COMPONENTS))) +all: dep obj +else +all: dep obj lib +endif + +include $(PRJ_PATH)/make/defs.mk +include $(PRJ_PATH)/make/target.mk + +ifeq (TRUE, $(API_LOCK)) + PT_LIB=-lpthread +else + PT_LIB= +endif + +lib: + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(LDFLAGS) $(EXTRA_LDFLAGS) $(OBJ_FILE) $(BIN_DIR)/$(US_MOD)_$(RUNMODE).a -o $(DST_DIR)/$(SHELLOBJ) $(PT_LIB) diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/shell/shell.c b/feeds/ipq807x/qca-ssdk-shell/src/src/shell/shell.c new file mode 100755 index 000000000..fe583ba0c --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/shell/shell.c @@ -0,0 +1,858 @@ +/* + * Copyright (c) 2014, 2017-2018, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/*qca808x_start*/ +#include +#include +#include +#include "shell.h" +#include "shell_io.h" +#include "shell_sw.h" +#include "shell_lib.h" +#include "shell_config.h" +#include "api_access.h" +#include "fal_uk_if.h" + +a_ulong_t *ioctl_buf = NULL; +ssdk_init_cfg init_cfg = def_init_cfg; +ssdk_cfg_t ssdk_cfg; +static a_uint32_t flag = 0; + +static a_ulong_t *ioctl_argp; +static FILE * out_fd; +char dev_id_path[] = "/sys/ssdk/dev_id"; +#ifndef SSDK_STR +#define SSDK_STR "SSDK" +#endif +static char *err_info[] = +{ + "Operation succeeded", /*SW_OK*/ + "Operation failed", /*SW_FAIL*/ + "Illegal value ", /*SW_BAD_VALUE*/ + "Value is out of range ", /*SW_OUT_OF_RANGE*/ + "Illegal parameter(s) ", /*SW_BAD_PARAM*/ + "Illegal pointer value ", /*SW_BAD_PTR*/ + "Wrong length", /*SW_BAD_LEN*/ + "Wrong state of state machine ", /*SW_BAD_STATE*/ + "Read operation failed ", /*SW_READ_ERROR*/ + "Write operation failed ", /*SW_WRITE_ERROR*/ + "Fail in creating an entry ", /*SW_CREATE_ERROR*/ + "Fail in deleteing an entry ", /*SW_DELETE_ERROR*/ + "Entry not found ", /*SW_NOT_FOUND*/ + "The parameter(s) is the same ", /*SW_NO_CHANGE*/ + "No more entry found ", /*SW_NO_MORE*/ + "No such entry ", /*SW_NO_SUCH*/ + "Tried to create existing entry ", /*SW_ALREADY_EXIST*/ + "Table is full ", /*SW_FULL*/ + "Table is empty ", /*SW_EMPTY*/ + "This request is not support ", /*SW_NOT_SUPPORTED*/ + "This request is not implemented", /*SW_NOT_IMPLEMENTED*/ + "The item is not initialized ", /*SW_NOT_INITIALIZED*/ + "Operation is still running", /*SW_BUSY*/ + "Operation Time Out ", /*SW_TIMEOUT*/ + "Operation is disabled ", /*SW_DISABLE*/ + "Resource not available (memory ...)", /*SW_NO_RESOURCE*/ + "Error occured while INIT process", /*SW_INIT_ERROR*/ + "The other side is not ready yet", /*SW_NOT_READY */ + "Cpu memory allocation failed. ", /*SW_OUT_OF_MEM */ + "Operation has been aborted. ", /*SW_ABORTED*/ +} ; + +void +cmd_print_error(sw_error_t rtn) +{ + dprintf("\n%s\n\n", err_info[abs(rtn)]); +} + +void +cmd_print(char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + if(out_fd) + vfprintf(out_fd, fmt, args); + else + vfprintf(stdout, fmt, args); + va_end(args); +} + +static sw_error_t +cmd_input_parser(a_ulong_t *arg_val, a_uint32_t arg_index, sw_api_param_t *pp) +{ + a_int16_t i; + a_ulong_t *pbuf; + a_uint16_t rtn_size = 1; + sw_api_param_t *pptmp = pp; + + pbuf = ioctl_buf + rtn_size; /*reserve for return value */ + + for (i = 0; i < arg_index; i++) + { + pptmp = pp + i; + if (pptmp->param_type & SW_PARAM_PTR) + { + pbuf += (pptmp->data_size + 3) / 4; + } + } + if ((pbuf - ioctl_buf + (pptmp->data_size + 3) / 4) > (IOCTL_BUF_SIZE/4)) + { + return SW_NO_RESOURCE; + } + + *arg_val = (a_ulong_t) pbuf; + + return SW_OK; +} + +static sw_error_t +cmd_api_func(sw_api_func_t *fp, a_uint32_t nr_param, a_ulong_t * args) +{ + a_ulong_t *p = &args[2]; + sw_error_t rv; + sw_error_t(*func) (); + + func = fp->func; + + switch (nr_param) + { + case 0: + rv = (func) (); + break; + case 1: + rv = (func) (p[0]); + break; + case 2: + rv = (func) (p[0], p[1]); + break; + case 3: + rv = (func) (p[0], p[1], p[2]); + break; + case 4: + rv = (func) (p[0], p[1], p[2], p[3]); + break; + case 5: + rv = (func) (p[0], p[1], p[2], p[3], p[4]); + break; + case 6: + rv = (func) (p[0], p[1], p[2], p[3], p[4], p[5]); + break; + case 7: + rv = (func) (p[0], p[1], p[2], p[3], p[4], p[5], p[6]); + break; + case 8: + rv = (func) (p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); + break; + case 9: + rv = (func) (p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]); + break; + case 10: + rv = (func) (p[0], p[1], p[2], p[3], p[4], p[5], + p[6], p[7], p[8], p[9]); + break; + default: + rv = SW_OUT_OF_RANGE; + } + + *(a_ulong_t *) args[1] = rv; + + return rv; +} + +static sw_error_t +cmd_api_output(sw_api_param_t *pp, a_uint32_t nr_param, a_ulong_t * args) +{ + a_uint16_t i; + a_ulong_t *pbuf; + a_uint16_t rtn_size = 1; + sw_error_t rtn = (sw_error_t) (*ioctl_buf); + sw_api_param_t *pptmp = NULL; + + if (rtn != SW_OK) + { + cmd_print_error(rtn); + return rtn; + } + + pbuf = ioctl_buf + rtn_size; + for (i = 0; i < nr_param; i++) + { + pptmp = pp + i; + if (pptmp->param_type & SW_PARAM_PTR) + { + + if (pptmp->param_type & SW_PARAM_OUT) + { + + sw_data_type_t *data_type; + if (!(data_type = cmd_data_type_find(pptmp->data_type))) + return SW_NO_SUCH; + + if (data_type->show_func) + { + data_type->show_func(pptmp->param_name, pbuf, pptmp->data_size); +/*qca808x_end*/ + if(strcmp((a_char_t *)pptmp->param_name, "Function bitmap") == 0) + { + cmd_data_print_module_func_ctrl(args[3], (fal_func_ctrl_t *)pbuf); + } +/*qca808x_start*/ + } + else + { + dprintf("\n Error, not define output print function!"); + } + } + + if ((pbuf - ioctl_buf + + (pptmp->data_size + 3) / 4) > (IOCTL_BUF_SIZE/4)) + return SW_NO_RESOURCE; + + pbuf += (pptmp->data_size + 3) / 4; + + } + } + return SW_OK; +} + +void +cmd_strtol(char *str, a_uint32_t * arg_val) +{ + if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) + sscanf(str, "%x", arg_val); + else + sscanf(str, "%d", arg_val); +} + +static sw_error_t +cmd_parse_api(char **cmd_str, a_ulong_t * arg_val) +{ + char *tmp_str; + a_uint32_t arg_index, arg_start = 2, reserve_index = 1; /*reserve for dev_id */ + a_uint32_t last_param_in = 0; + a_ulong_t *temp; + void *pentry; + sw_api_param_t *pptmp = NULL; + sw_api_t sw_api; + a_uint32_t ignorecnt = 0, jump = 0; + sw_api.api_id = arg_val[0]; + SW_RTN_ON_ERROR(sw_api_get(&sw_api)); + + /*set device id */ + arg_val[arg_start] = get_devid(); + + for (arg_index = reserve_index; arg_index < sw_api.api_nr; arg_index++) + { + tmp_str = NULL; + pptmp = sw_api.api_pp + arg_index; + + if (!(pptmp->param_type & SW_PARAM_IN)) + { + ignorecnt++; + } + + if (pptmp->param_type & SW_PARAM_IN) + { + tmp_str = cmd_str[arg_index - reserve_index - ignorecnt + jump]; + last_param_in = arg_index; + if((pptmp->api_id == 314) && last_param_in == 2) last_param_in = 4;//SW_API_FDB_EXTEND_NEXT wr + if((pptmp->api_id == 327) && last_param_in == 2) last_param_in = 4;//SW_API_FDB_EXTEND_FIRST wr + } + temp = &arg_val[arg_start + arg_index]; + + sw_data_type_t *data_type; + if (!(data_type = cmd_data_type_find(pptmp->data_type))) + return SW_NO_SUCH; + + pentry = temp; + if (pptmp->param_type & SW_PARAM_PTR) + { + if (cmd_input_parser(temp, arg_index, sw_api.api_pp) != SW_OK) + return SW_NO_RESOURCE; + + pentry = (void *) *temp; + } + + if (pptmp->param_type & SW_PARAM_IN) + { +#if 1 + if(pptmp->param_type & SW_PARAM_PTR) //quiet mode + { + if(!get_talk_mode()) + set_full_cmdstrp((char **)(cmd_str + (last_param_in - reserve_index) + jump)); + } +#endif + /*check and convert input param */ + if (data_type->param_check != NULL) + { + if (data_type->param_check(tmp_str, pentry, pptmp->data_size) != SW_OK) + return SW_BAD_PARAM; + if(!get_talk_mode() && (pptmp->param_type & SW_PARAM_PTR)) { + if (get_jump()) + jump += get_jump() -1; + } + + } + } + } + + /*superfluous args */ + /* + if(cmd_str[last_param_in] != NULL) + return SW_BAD_PARAM; + */ + + return SW_OK; +} + +static sw_error_t +cmd_parse_sw(char **cmd_str, a_ulong_t * arg_val) +{ + char *tmp_str; + a_uint32_t arg_index = 0, tmp = 0; + a_uint32_t api_id = arg_val[0]; + + tmp_str = cmd_str[arg_index]; + while (tmp_str) + { + arg_index++; + cmd_strtol(tmp_str, &tmp); + arg_val[arg_index] = tmp; + tmp_str = cmd_str[arg_index]; + } + + /*args number check */ + if ( (arg_index == 0 && ( api_id == SW_CMD_VLAN_SHOW || + api_id == SW_CMD_FDB_SHOW || + api_id == SW_CMD_RESV_FDB_SHOW || + api_id == SW_CMD_HOST_SHOW || + api_id == SW_CMD_HOST_IPV4_SHOW || + api_id == SW_CMD_HOST_IPV6_SHOW || + api_id == SW_CMD_HOST_IPV4M_SHOW || + api_id == SW_CMD_HOST_IPV6M_SHOW || + api_id == SW_CMD_FLOW_IPV43T_SHOW || + api_id == SW_CMD_FLOW_IPV63T_SHOW || + api_id == SW_CMD_FLOW_IPV45T_SHOW || + api_id == SW_CMD_FLOW_IPV65T_SHOW || + api_id == SW_CMD_NAT_SHOW || + api_id == SW_CMD_NAPT_SHOW || + api_id == SW_CMD_FLOW_SHOW || + api_id == SW_CMD_CTRLPKT_SHOW || + api_id == SW_CMD_INTFMAC_SHOW || + api_id == SW_CMD_PUBADDR_SHOW )) || + ( arg_index == 1 && api_id == SW_CMD_SET_DEVID) || + ( arg_index == 2 && api_id == SW_CMD_PT_VLAN_TRANS_ADV_SHOW) ) + return SW_OK; + + return SW_BAD_PARAM; +} + +/*user command api*/ +sw_error_t +cmd_exec_api(a_ulong_t *arg_val) +{ + sw_error_t rv; + sw_api_t sw_api; + + sw_api.api_id = arg_val[0]; + SW_RTN_ON_ERROR(sw_api_get(&sw_api)); + + /*save cmd return value */ + arg_val[1] = (a_ulong_t) ioctl_buf; + /*save set device id */ + arg_val[2] = get_devid(); + + rv = cmd_api_func(sw_api.api_fp, sw_api.api_nr, arg_val); + SW_RTN_ON_ERROR(rv); + + rv = cmd_api_output(sw_api.api_pp, sw_api.api_nr, arg_val); + SW_RTN_ON_ERROR(rv); + + return rv; +} + + +void +cmd_print_usage (int cmd_index, int cmd_index_sub) +{ + if(GCMD_NAME(cmd_index)) + dprintf("usage: %s", GCMD_NAME(cmd_index)); + + if (GCMD_SUB_NAME(cmd_index, cmd_index_sub)) + dprintf(" %s", GCMD_SUB_NAME(cmd_index, cmd_index_sub)); + + if(GCMD_SUB_ACT(cmd_index, cmd_index_sub) && GCMD_SUB_USAGE(cmd_index, cmd_index_sub)) + dprintf(" %s %s\n\n", GCMD_SUB_ACT(cmd_index, cmd_index_sub), + GCMD_SUB_USAGE(cmd_index, cmd_index_sub)); +} +/* + main function + input args: + arg_val[0] = cmd_num + arg_val[1] = rtn_code + arg_val[2] = dev_id + arg_val[3] = dbg_cmd_num or other +*/ + +/*command string lookup*/ +a_uint32_t +cmd_lookup(char **cmd_str, int *cmd_index, int *cmd_index_sub) +{ + a_uint32_t no, sub_no; + a_uint32_t cmd_deepth = 0; + + *cmd_index = GCMD_DESC_NO_MATCH; + *cmd_index_sub = GCMD_DESC_NO_MATCH; + + if (cmd_str[0] == NULL) + return cmd_deepth; + + for (no = 0; GCMD_DESC_VALID(no); no++) + { + if (strcasecmp(cmd_str[0], GCMD_NAME(no))) + continue; + + for (sub_no = 0; GCMD_SUB_DESC_VALID(no, sub_no); sub_no++) + { + if (cmd_str[1] != NULL && cmd_str[2] != NULL) + { + + if (GCMD_SUB_NAME(no, sub_no) && GCMD_SUB_ACT(no, sub_no) + && !strcasecmp(cmd_str[1], GCMD_SUB_NAME(no, sub_no)) + && !strcasecmp(cmd_str[2], GCMD_SUB_ACT(no, sub_no))) + { + *cmd_index = no; + *cmd_index_sub = sub_no; + cmd_deepth = 3; + return cmd_deepth; + } + + else if (!GCMD_SUB_NAME(no, sub_no) && GCMD_SUB_ACT(no, sub_no) + && !strcasecmp(cmd_str[1], GCMD_SUB_ACT(no, sub_no))) + { + *cmd_index = no; + *cmd_index_sub = sub_no; + cmd_deepth = 2; + return cmd_deepth; + } + } + else if (cmd_str[1] != NULL && cmd_str[2] == NULL) + { + + if (!GCMD_SUB_NAME(no, sub_no) && GCMD_SUB_ACT(no, sub_no) + && !strcasecmp(cmd_str[1], GCMD_SUB_ACT(no, sub_no))) + { + *cmd_index = no; + *cmd_index_sub = sub_no; + cmd_deepth = 2; + return cmd_deepth; + } + } + } + } + + return cmd_deepth; +} + +static a_ulong_t * +cmd_parse(char *cmd_str, int *cmd_index, int *cmd_index_sub) +{ + int cmd_nr = 0; + a_ulong_t *arg_val = ioctl_argp; + char *tmp_str[CMDSTR_ARGS_MAX], *str_save; + + if (cmd_str == NULL) + return NULL; + + memset(arg_val, 0, CMDSTR_ARGS_MAX * sizeof (a_ulong_t)); + + /* split string into array */ + if ((tmp_str[cmd_nr] = (void *) strtok_r(cmd_str, " ", &str_save)) == NULL) + return NULL; + + /*handle help */ + if (!strcasecmp(tmp_str[cmd_nr], "help")) + { + dprintf("input ? get help\n\n"); + return NULL; + } + + while (tmp_str[cmd_nr]) + { + if (++cmd_nr == 3) + break; + tmp_str[cmd_nr] = (void *) strtok_r(NULL, " ", &str_save); + } + + /*commond string lookup */ + int cmd_depth = cmd_lookup(tmp_str, cmd_index, cmd_index_sub); + + if (*cmd_index == GCMD_DESC_NO_MATCH || *cmd_index_sub == GCMD_DESC_NO_MATCH) + { + dprintf("invalid or incomplete command.\n\n"); + return NULL; + } + + /*parse param */ + cmd_nr = 0; + if (cmd_depth == 2) + { + tmp_str[cmd_nr] = tmp_str[2]; + cmd_nr++; + } + + tmp_str[cmd_nr] = (void *) strtok_r(NULL, " ", &str_save); + while (tmp_str[cmd_nr]) + { + if (++cmd_nr == CMDSTR_ARGS_MAX) + break; + tmp_str[cmd_nr] = (void *) strtok_r(NULL, " ", &str_save); + } + + arg_val[0] = GCMD_SUB_API(*cmd_index, *cmd_index_sub); + arg_val[1] = (a_ulong_t) ioctl_buf; + + int rtn_code; + if (arg_val[0] < SW_API_MAX) + { + /*api command parse */ + rtn_code = cmd_parse_api(tmp_str, arg_val); + + } + else if (arg_val[0] > SW_API_MAX) + { + /*user command parse */ + rtn_code = cmd_parse_sw(tmp_str, arg_val); + + } + else + { + rtn_code = SW_BAD_PARAM; + } + + if(rtn_code != SW_OK) + { + cmd_print_error(rtn_code); + + if(rtn_code == SW_BAD_PARAM) + cmd_print_usage(*cmd_index, *cmd_index_sub); + + return NULL; + } + + return arg_val; +} + +static int +cmd_exec(a_ulong_t *arg_val, int cmd_index, int cmd_index_sub) +{ + a_uint32_t api_id = arg_val[0]; + sw_error_t rtn = SW_OK; + + if( api_id < SW_API_MAX ) + { + rtn = cmd_exec_api(arg_val); + + } + else if ((api_id > SW_API_MAX ) && (api_id < SW_CMD_MAX)) + { + if (GCMD_SUB_FUNC(cmd_index, cmd_index_sub)) + rtn = GCMD_SUB_FUNC(cmd_index, cmd_index_sub)(arg_val); + } + else + { + rtn = SW_BAD_PARAM; + } + + if(rtn != SW_OK) + cmd_print_error(rtn); + else + dprintf("\noperation done.\n\n"); + + return 0; +} + +static sw_error_t +cmd_socket_init(int dev_id) +{ + sw_error_t rv; + + init_cfg.cpu_mode = HSL_CPU_1; + init_cfg.reg_mode = HSL_MDIO; +#if defined UK_MINOR_DEV + init_cfg.nl_prot = UK_MINOR_DEV; +#else + init_cfg.nl_prot = 30; +#endif + init_cfg.chip_type=CHIP_UNSPECIFIED; +/*qca808x_end*/ + init_cfg.reg_func.mdio_set = NULL; + init_cfg.reg_func.mdio_get = NULL; +/*qca808x_start*/ + rv = ssdk_init(dev_id, &init_cfg); + if (SW_OK == rv) + { + dprintf("\n %s Init OK!", SSDK_STR); + } + else + { + dprintf("\n %s Init Fail! RV[%d]", SSDK_STR, rv); + } + + if (flag == 0) + { + aos_mem_set(&ssdk_cfg, 0 ,sizeof(ssdk_cfg_t)); + rv = sw_uk_exec(SW_API_SSDK_CFG, dev_id, &ssdk_cfg); + flag = 1; + } + return rv; +} + +static sw_error_t +cmd_init(void) +{ + ioctl_buf = (a_ulong_t *) malloc(IOCTL_BUF_SIZE); + ioctl_argp = (a_ulong_t *) malloc(CMDSTR_ARGS_MAX * sizeof (a_ulong_t)); + FILE *dev_id_fd = NULL; + int dev_id_value = 0; + if((dev_id_fd = fopen(dev_id_path, "r")) != NULL) + { + fscanf(dev_id_fd, "%d", &dev_id_value); + } + + set_devid(dev_id_value); + cmd_socket_init(dev_id_value); + + return SW_OK; +} + +static sw_error_t +cmd_exit(void) +{ + free(ioctl_buf); + free(ioctl_argp); + ssdk_cleanup(); + flag = 0; + return SW_OK; +} + +static sw_error_t +cmd_run_one(char *cmd_str) +{ + a_ulong_t *arg_list; + int cmd_index = 0, cmd_index_sub = 0; + + if ((arg_list = cmd_parse(cmd_str, &cmd_index, &cmd_index_sub)) != NULL) + { + cmd_exec(arg_list, cmd_index, cmd_index_sub); + } + + return SW_OK; +} + +int +cmd_is_batch(const char *cmd_str) +{ + char batch_cmd[] = "run"; + + if(!strncmp(cmd_str, batch_cmd, strlen(batch_cmd))) + return 1; + return 0; +} + +static void +cmd_batch_help(void) +{ + dprintf("usage:run \n"); +} + +static sw_error_t +cmd_run_batch (char *cmd_str) +{ + FILE *in_fd = NULL; + char * line = NULL, *str_save; + char *tmp_str[3]; + + if (cmd_str == NULL) + return SW_BAD_PARAM; + + /*usage: run cmd result*/ + if((tmp_str[0] = (void *) strtok_r(cmd_str, " ", &str_save)) == NULL) + return SW_BAD_PARAM; + + /*check again*/ + if(!cmd_is_batch(tmp_str[0])) + return SW_BAD_PARAM; + + if((tmp_str[1] = (void *) strtok_r(NULL, " ", &str_save))== NULL) + return SW_BAD_PARAM; + if((tmp_str[2] = (void *) strtok_r(NULL, " ", &str_save))== NULL) + return SW_BAD_PARAM; + + if((in_fd = fopen(tmp_str[1], "r")) == NULL) + { + dprintf("can't open cmd file %s\n", tmp_str[1]); + return SW_FAIL; + } + if((out_fd = fopen(tmp_str[2], "w+")) == NULL) + { + dprintf("can't open result file %s\n", tmp_str[2]); + return SW_FAIL; + } + + size_t len = 0; + ssize_t read; + + set_talk_mode(0); + while ((read = getline(&line, &len, in_fd)) != -1) + { + //dprintf("(%d)%s",read, line); + if (read <= 1 ) + { + continue; + } + + if (line[strlen(line)-1] == '\n') + { + line[strlen(line)-1] = '\0'; + } + + if (!strncmp(line, "echo", 4)) + { + dprintf("%s\n", line+strlen("echo ")); + continue; + } + else + { + dprintf("%s\n", line); + } + cmd_run_one(line); + } + set_talk_mode(1); + + if (line) free(line); + + fclose(out_fd); + fclose(in_fd); + out_fd = 0; + in_fd =0; + + return SW_OK; + +} + +static sw_error_t +cmd_args(char *cmd_str, int argc, const char *argv[]) +{ + /*quiet mode*/ + set_talk_mode(0); + + if(cmd_is_batch(argv[1])) + { + if(argc != 4) + { + cmd_batch_help(); + return SW_FAIL; + } + + snprintf(cmd_str, CMDSTR_BUF_SIZE, "%s %s %s", argv[1], argv[2], argv[3]); + cmd_run_batch(cmd_str); + + } + else + { + int argi; + for(argi = 1; argi < argc; argi++) + { + strlcat(cmd_str, argv[argi], CMDSTR_BUF_SIZE); + strlcat(cmd_str, " ", CMDSTR_BUF_SIZE); + } + cmd_run_one(cmd_str); + } + + return SW_OK; +} + +int +cmd_is_exit(char *cmd_str) +{ + if ((!strcasecmp(cmd_str, "q")) || (!strcasecmp(cmd_str, "quit"))) + { + return 1; + } + return 0; +} + +void cmd_welcome() +{ + char *ver = "", *date = ""; +#ifdef VERSION + ver = VERSION; +#endif + +#ifdef BUILD_DATE + date = BUILD_DATE; +#endif + dprintf("\n Welcome to %s Shell version: %s, at %s.\n", SSDK_STR, ver, date); +} + +/* Dummy function to avoid linker complaints */ +void __aeabi_unwind_cpp_pr0(void) +{ +}; +void __aeabi_unwind_cpp_pr1(void) +{ +}; + +int +main(int argc, const char *argv[]) +{ + char cmd_str[CMDSTR_BUF_SIZE]; + cmd_init(); + + if(argc > 1) + { + memset(cmd_str, 0, sizeof(cmd_str)); + cmd_args(cmd_str, argc, argv); + cmd_exit(); + return 0; + } + + cmd_welcome(); + + /*main loop*/ + while (1) + { + memset(cmd_str, 0, sizeof(cmd_str)); + + if(next_cmd(cmd_str) == 0)/*loop through if '\n'*/ + continue; + + if (cmd_is_exit(cmd_str)) + break; + + if(cmd_is_batch(cmd_str)) + { + if(cmd_run_batch(cmd_str)!= SW_OK) + cmd_batch_help(); + } + else + { + cmd_run_one(cmd_str); + } + } + + cmd_exit(); + return 0; +} +/*qca808x_end*/ diff --git a/feeds/ipq807x/qca-ssdk-shell/src/src/shell/shell_config.c b/feeds/ipq807x/qca-ssdk-shell/src/src/shell/shell_config.c new file mode 100755 index 000000000..e123f9b4a --- /dev/null +++ b/feeds/ipq807x/qca-ssdk-shell/src/src/shell/shell_config.c @@ -0,0 +1,1451 @@ +/* + * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all copies. + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/*qca808x_start*/ +#include "shell_config.h" +#include "shell_sw.h" + + +/*cmdline tree descript*/ +struct cmd_des_t gcmd_des[] = +{ + /*port ctrl*/ +/*qca808x_end*/ +#ifdef IN_PORTCONTROL +/*qca808x_start*/ + { + "port", "config port control", + { + {"duplex", "get", "get duplex mode of a port", "" , SW_API_PT_DUPLEX_GET, + NULL}, + {"duplex", "set", "set duplex mode of a port", " ", + SW_API_PT_DUPLEX_SET, NULL}, + {"speed", "get", "get speed mode of a port", "", SW_API_PT_SPEED_GET, + NULL}, + {"speed", "set", "set speed mode of a port", + " <10|100|1000|2500|5000|10000>", SW_API_PT_SPEED_SET, NULL}, + {"autoAdv", "get", "get auto-negotiation advertisement of a port", "", + SW_API_PT_AN_ADV_GET, NULL}, + {"autoAdv", "set", "set auto-negotiation advertisement of a port", + " ", SW_API_PT_AN_ADV_SET, NULL}, + {"autoNeg", "get", "get auto-negotiation status of a port", "", + SW_API_PT_AN_GET, NULL}, + {"autoNeg", "enable", "enable auto-negotiation of a port", "", + SW_API_PT_AN_ENABLE, NULL}, + {"autoNeg", "restart", "restart auto-negotiation process of a port", "", + SW_API_PT_AN_RESTART, NULL}, +/*qca808x_end*/ + {"header", "set", "set atheros header/tag status of a port", + " ", SW_API_PT_HDR_SET, NULL}, + {"header", "get", "get atheros header/tag status of a port", "", + SW_API_PT_HDR_GET, NULL}, + {"txhdr", "set", "set tx frame atheros header/tag status of a port", + " ", SW_API_PT_TXHDR_SET, NULL}, + {"txhdr", "get", "get tx frame atheros header/tag status of a port", "", + SW_API_PT_TXHDR_GET, NULL}, + {"rxhdr", "set", "set rx frame atheros header/tag status of a port", + " ", SW_API_PT_RXHDR_SET, NULL}, + {"rxhdr", "get", "get rx frame atheros header/tag status of a port", "", + SW_API_PT_RXHDR_GET, NULL}, + {"hdrtype", "set", "set atheros header/tag type", + " ", SW_API_HEADER_TYPE_SET, NULL}, + {"hdrtype", "get", "get atheros header/tag type", "", + SW_API_HEADER_TYPE_GET, NULL}, + {"flowCtrl", "set", "set flow control status of a port", + " ", SW_API_PT_FLOWCTRL_SET, NULL}, + {"flowCtrl", "get", "get flow control status of a port", "", + SW_API_PT_FLOWCTRL_GET, NULL}, + {"flowCtrlforcemode", "set", "set flow control force mode of a port", + " ", SW_API_PT_FLOWCTRL_MODE_SET, NULL}, + {"flowCtrlforcemode", "get", "get flow control force mode of a port", + "", SW_API_PT_FLOWCTRL_MODE_GET, NULL}, + {"powersave", "set", "set powersave status of a port", + " ", SW_API_PT_POWERSAVE_SET, NULL}, + {"powersave", "get", "get powersave status of a port", "", + SW_API_PT_POWERSAVE_GET, NULL}, +/*qca808x_start*/ + {"hibernate", "set", "set hibernate status of a port", + " ", SW_API_PT_HIBERNATE_SET, NULL}, + {"hibernate", "get", "get hibernate status of a port", "", + SW_API_PT_HIBERNATE_GET, NULL}, + {"cdt", "run", "run cable diagnostic test of a port", + " ", SW_API_PT_CDT, NULL}, +/*qca808x_end*/ + {"txmacstatus", "set", "set txmac status of a port", + " ", SW_API_TXMAC_STATUS_SET, NULL}, + {"txmacstatus", "get", "get txmac status of a port", "", + SW_API_TXMAC_STATUS_GET, NULL}, + {"rxmacstatus", "set", "set rxmac status of a port", " ", + SW_API_RXMAC_STATUS_SET, NULL}, + {"rxmacstatus", "get", "get rxmac status of a port", "", + SW_API_RXMAC_STATUS_GET, NULL}, + {"txfcstatus", "set", "set tx flow control status of a port", + " ", SW_API_TXFC_STATUS_SET, NULL}, + {"txfcstatus", "get", "get tx flow control status of a port", "", + SW_API_TXFC_STATUS_GET, NULL}, + {"rxfcstatus", "set", "set rx flow control status of a port", + " ", SW_API_RXFC_STATUS_SET, NULL}, + {"rxfcstatus", "get", "get rx flow control status of a port", "", + SW_API_RXFC_STATUS_GET, NULL}, + {"bpstatus", "set", "set back pressure status of a port", + " ", SW_API_BP_STATUS_SET, NULL}, + {"bpstatus", "get", "get back pressure status of a port", "", + SW_API_BP_STATUS_GET, NULL}, + {"linkforcemode", "set", "set link force mode of a port", + " ", SW_API_PT_LINK_MODE_SET, NULL}, + {"linkforcemode", "get", "get link force mode of a port", "", + SW_API_PT_LINK_MODE_GET, NULL}, +/*qca808x_start*/ + {"linkstatus", "get", "get link status of a port", "", + SW_API_PT_LINK_STATUS_GET, NULL}, +/*qca808x_end*/ + {"macLoopback", "set", "set mac level loop back mode of port", + " ", SW_API_PT_MAC_LOOPBACK_SET, NULL}, + {"macLoopback", "get", "get mac level loop back mode of port", "", + SW_API_PT_MAC_LOOPBACK_GET, NULL}, + {"ptslinkstatus", "get", "get link status of all ports", "", + SW_API_PTS_LINK_STATUS_GET, NULL}, + {"congedrop", "set", "set congestion drop of port queue", + " ", SW_API_PT_CONGESTION_DROP_SET, + NULL}, + {"congedrop", "get", "get congestion drop of port queue", + " ", SW_API_PT_CONGESTION_DROP_GET, NULL}, + {"ringfcthres", "set", "set ring flow ctrl of ring", + " ", SW_API_PT_RING_FLOW_CTRL_THRES_SET, + NULL}, + {"ringfcthres", "get", "get ring flow ctrl of ring", "", + SW_API_PT_RING_FLOW_CTRL_THRES_GET, NULL}, +/*qca808x_start*/ + {"Ieee8023az", "set", "set 8023az status of a port", " ", + SW_API_PT_8023AZ_SET, NULL}, + {"Ieee8023az", "get", "get 8023az status of a port", "", + SW_API_PT_8023AZ_GET, NULL}, + {"crossover", "set", "set crossover mode of a port", " ", + SW_API_PT_MDIX_SET, NULL}, + {"crossover", "get", "get crossover mode of a port", "", + SW_API_PT_MDIX_GET, NULL}, + {"crossover", "status", "get current crossover status of a port", "", + SW_API_PT_MDIX_STATUS_GET, NULL}, +/*qca808x_end*/ + {"preferMedium", "set", "set prefer medium of a combo port", + " ", SW_API_PT_COMBO_PREFER_MEDIUM_SET, NULL}, + {"preferMedium", "get", "get prefer medium of a combo port", "", + SW_API_PT_COMBO_PREFER_MEDIUM_GET, NULL}, + {"mediumType", "get", "get current medium status of a combo port", "", + SW_API_PT_COMBO_MEDIUM_STATUS_GET, NULL}, + {"fiberMode", "set", "set fiber mode of a combo fiber port", + " <100fx|1000bx |10g_r>", SW_API_PT_COMBO_FIBER_MODE_SET, NULL}, + {"fiberMode", "get", "get fiber mode of a combo fiber port", "", + SW_API_PT_COMBO_FIBER_MODE_GET, NULL}, +/*qca808x_start*/ + {"localLoopback", "set", "set local loopback of a port", + " ", SW_API_PT_LOCAL_LOOPBACK_SET, NULL}, + {"localLoopback", "get", "get local loopback of a port", "", + SW_API_PT_LOCAL_LOOPBACK_GET, NULL}, + {"remoteLoopback", "set", "set remote loopback of a port", + " ", SW_API_PT_REMOTE_LOOPBACK_SET, NULL}, + {"remoteLoopback", "get", "get remote loopback of a port", "", + SW_API_PT_REMOTE_LOOPBACK_GET, NULL}, + {"reset", "set", "reset phy of a port", "", SW_API_PT_RESET, NULL}, + {"poweroff", "set", "power off phy of a port", "", + SW_API_PT_POWER_OFF, NULL}, + {"poweron", "set", "power on phy of a port", "", SW_API_PT_POWER_ON, NULL}, + {"magicFrameMac", "set", "set magic frame mac address of a port", + " ", SW_API_PT_MAGIC_FRAME_MAC_SET, NULL}, + {"magicFrameMac", "get", "get magic frame mac address of a port", "", + SW_API_PT_MAGIC_FRAME_MAC_GET, NULL}, + {"phyId", "get", "get phy id of a port", "", SW_API_PT_PHY_ID_GET, NULL}, + {"wolstatus", "set", "set wol status of a port", " ", + SW_API_PT_WOL_STATUS_SET, NULL}, + {"wolstatus", "get", "get wol status of a port", "", + SW_API_PT_WOL_STATUS_GET, NULL}, +/*qca808x_end*/ + {"interfaceMode", "set", "set interface mode of phy", " ",\ + SW_API_PT_INTERFACE_MODE_SET, NULL}, + {"interfaceMode", "get", "get interface mode of phy", "", + SW_API_PT_INTERFACE_MODE_GET, NULL}, + {"interfaceMode", "apply", "apply interface mode","", + SW_API_PT_INTERFACE_MODE_APPLY, NULL}, +/*qca808x_start*/ + {"interfaceMode", "status", "get current interface mode of phy", "", + SW_API_PT_INTERFACE_MODE_STATUS_GET, NULL}, +/*qca808x_end*/ + {"interface3az", "set", "set interface and phy 3az info", + " ", SW_API_PT_INTERFACE_3AZ_STATUS_SET, NULL}, + {"interface3az", "get", "get interface and phy 3az info", "", + SW_API_PT_INTERFACE_3AZ_STATUS_GET, NULL}, + {"promiscmode", "set", "set port promisc mode", " ", + SW_API_PT_PROMISC_MODE_SET, NULL}, + {"promiscmode", "get", "get port promisc mode", "", + SW_API_PT_PROMISC_MODE_GET, NULL}, + {"mtu", "set", "set port mtu value", "", SW_API_PT_MTU_SET, NULL}, + {"mtu", "get", "get port mtu value", "", SW_API_PT_MTU_GET, NULL}, + {"mru", "set", "set port mru value", "", SW_API_PT_MRU_SET, NULL}, + {"mru", "get", "get port mru value", "", SW_API_PT_MRU_GET, NULL}, + {"srcfilter", "set", "set port source filter bypass", " ", + SW_API_PT_SOURCE_FILTER_SET, NULL}, + {"srcfilter", "get", "get port source filter bypass", "", + SW_API_PT_SOURCE_FILTER_GET, NULL}, + {"frameMaxSize", "get", "get port frame max size", "", + SW_API_PT_FRAME_MAX_SIZE_GET}, + {"frameMaxSize", "set", "set port frame max size", " ", + SW_API_PT_FRAME_MAX_SIZE_SET}, + {"eeecfg", "set", "set interface eee info", "", + SW_API_PT_INTERFACE_EEE_CFG_SET, NULL}, + {"eeecfg", "get", "get interface eee info", "", + SW_API_PT_INTERFACE_EEE_CFG_GET, NULL}, + {"srcfiltercfg", "set", "set port source filter configure", "", + SW_API_PT_SOURCE_FILTER_CONFIG_SET, NULL}, + {"srcfiltercfg", "get", "get port source filter configure", "", + SW_API_PT_SOURCE_FILTER_CONFIG_GET, NULL}, + {"switchportloopback", "set", "set switch port loopback", "", + SW_API_PT_SWITCH_PORT_LOOPBACK_SET, NULL}, + {"switchportloopback", "get", "get switch port loopback", "", + SW_API_PT_SWITCH_PORT_LOOPBACK_GET, NULL}, +/*qca808x_start*/ + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL},/*end of desc*/ + }, + }, +/*qca808x_end*/ +#endif + + /*vlan*/ +#ifdef IN_VLAN + { + "vlan", "config VLAN table", + { + {"entry", "create", "create a VLAN entry", "", SW_API_VLAN_ADD, NULL}, + {"entry", "del", "delete a VLAN entryn", "", SW_API_VLAN_DEL, NULL}, + {"entry", "update", "update port member of a VLAN entry", + " <0>", SW_API_VLAN_MEM_UPDATE, NULL}, + {"entry", "find", "find a VLAN entry by VLAN id", "", SW_API_VLAN_FIND, NULL}, + {"entry", "next", "find next VLAN entry by VLAN id", + "",SW_API_VLAN_NEXT, NULL}, + {"entry", "append", "append a VLAN entry", "", SW_API_VLAN_APPEND, NULL}, + {"entry", "flush", "flush all VLAN entries", "",SW_API_VLAN_FLUSH, NULL}, + {"entry", "show", "show whole VLAN entries", "", SW_CMD_VLAN_SHOW, cmd_show_vlan}, + {"fid", "set", "set VLAN entry fid", " ",SW_API_VLAN_FID_SET, NULL}, + {"fid", "get", "get VLAN entry fid", "",SW_API_VLAN_FID_GET, NULL}, + {"member", "add", "add VLAN entry member", + " ", + SW_API_VLAN_MEMBER_ADD, NULL}, + {"member", "del", "del VLAN entry member", + " ", SW_API_VLAN_MEMBER_DEL, NULL}, + {"learnsts", "set", "set VLAN entry learn status", + " ", SW_API_VLAN_LEARN_STATE_SET, NULL}, + {"learnsts", "get", "get VLAN entry learn status", + "", SW_API_VLAN_LEARN_STATE_GET, NULL}, + {"lan_wan_cfg", "set", "set lan & wan configuration", + "", SW_API_LAN_WAN_CFG_SET, NULL}, + {"lan_wan_cfg", "get", "get lan & wan configuration", + "", SW_API_LAN_WAN_CFG_GET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + + /*portvlan*/ +#ifdef IN_PORTVLAN + { + "portVlan", "config port base VLAN", + { + {"ingress", "get", "get ingress VLAN mode of a port", + "", SW_API_PT_ING_MODE_GET, NULL}, + {"ingress", "set", "set ingress VLAN mode of a port", + " ", SW_API_PT_ING_MODE_SET, NULL}, + {"egress", "get", "get egress VLAN mode of a port", + "", SW_API_PT_EG_MODE_GET, NULL}, + {"egress", "set", "set egress VLAN mode of a port", + " ", + SW_API_PT_EG_MODE_SET, NULL}, + {"member", "add", "add a member to the port based VLAN of a port", + " ", SW_API_PT_VLAN_MEM_ADD, NULL}, + {"member", "del", "delete a member from the port based VLAN of a port", + " ", SW_API_PT_VLAN_MEM_DEL, NULL}, + {"member", "update", "update members of the port based VLAN of a port", + " ", SW_API_PT_VLAN_MEM_UPDATE, NULL}, + {"member", "get", "get members of the port based VLAN of a port", + "", SW_API_PT_VLAN_MEM_GET, NULL}, + {"defaultVid", "get", "get default VLAN id of a port", + "", SW_API_PT_DEF_VID_GET, NULL}, + {"defaultVid", "set", "set default VLAN id of a port", + " ", SW_API_PT_DEF_VID_SET, NULL}, + {"forceVid", "set", "set VLAN id enforcement status of a port", + " ", SW_API_PT_FORCE_DEF_VID_SET, NULL}, + {"forceVid", "get", "get VLAN id enforcement status of a port", + "", SW_API_PT_FORCE_DEF_VID_GET, NULL}, + {"forceMode", "set", "set port based VLAN enforcement status of a port", + " ", SW_API_PT_FORCE_PORTVLAN_SET, NULL}, + {"forceMode", "get", "get port based VLAN enforcement status of a port", + "", SW_API_PT_FORCE_PORTVLAN_GET, NULL}, + {"nestVlan", "set", "set nest VLAN status of a port", + " ", SW_API_PT_NESTVLAN_SET, NULL}, + {"nestVlan", "get", "get nest VLAN status of a port", + "", SW_API_PT_NESTVLAN_GET, NULL}, + {"sVlanTPID", "set", "set service VLAN tpid", + "", SW_API_NESTVLAN_TPID_SET, NULL}, + {"sVlanTPID", "get", "get service VLAN tpid", + "", SW_API_NESTVLAN_TPID_GET, NULL}, + /*shiva*/ + {"invlan", "set", "set port invlan mode", + " ", + SW_API_PT_IN_VLAN_MODE_SET, NULL}, + {"invlan", "get", "get port invlan mode", + "", SW_API_PT_IN_VLAN_MODE_GET, NULL}, + {"tlsMode", "set", "set TLS mode", + " ", SW_API_PT_TLS_SET, NULL}, + {"tlsMode", "get", "get TLS mode", + "", SW_API_PT_TLS_GET, NULL}, + {"priPropagation", "set", "set priority propagation", + " ", SW_API_PT_PRI_PROPAGATION_SET, NULL}, + {"priPropagation", "get", "get priority propagation", + "", SW_API_PT_PRI_PROPAGATION_GET, NULL}, + {"defaultSVid", "set", "set default SVID", + " ", SW_API_PT_DEF_SVID_SET, NULL}, + {"defaultSVid", "get", "get default SVID", + "", SW_API_PT_DEF_SVID_GET, NULL}, + {"defaultCVid", "set", "set default CVID", + " ", SW_API_PT_DEF_CVID_SET, NULL}, + {"defaultCVid", "get", "get default CVID", + "", SW_API_PT_DEF_CVID_GET, NULL}, + {"vlanPropagation", "set", "set vlan propagation", + " ", SW_API_PT_VLAN_PROPAGATION_SET, NULL}, + {"vlanPropagation", "get", "get vlan propagation", + "", SW_API_PT_VLAN_PROPAGATION_GET, NULL}, + {"translation", "add", "add vlan translation", + "", SW_API_PT_VLAN_TRANS_ADD, NULL}, + {"translation", "del", "del vlan translation", + "", SW_API_PT_VLAN_TRANS_DEL, NULL}, + {"translation", "get", "get vlan translation", + "", SW_API_PT_VLAN_TRANS_GET, NULL}, + {"translation", "iterate", "iterate vlan translation tables", + " ", SW_API_PT_VLAN_TRANS_ITERATE, NULL}, + {"qinqMode", "set", "set qinq mode", + "", SW_API_QINQ_MODE_SET, NULL}, + {"qinqMode", "get", "get qinq mode", + "", SW_API_QINQ_MODE_GET, NULL}, + {"qinqRole", "set", "set qinq role", + " ", SW_API_PT_QINQ_ROLE_SET, NULL}, + {"qinqRole", "get", "get qinq role", + "", SW_API_PT_QINQ_ROLE_GET, NULL}, + {"macvlanxlt", "set", "set mac vlan xlt status", + " ", SW_API_PT_MAC_VLAN_XLT_SET, NULL}, + {"macvlanxlt", "get", "set mac vlan xlt status", + "", SW_API_PT_MAC_VLAN_XLT_GET, NULL}, + {"netiso", "set", "enable public/private net isolate", + "", SW_API_NETISOLATE_SET, NULL}, + {"netiso", "get", "get public/private net isolate status", + "", SW_API_NETISOLATE_GET, NULL}, + {"egbypass", "set", "enable egress translation filter bypass", + "", SW_API_EG_FLTR_BYPASS_EN_SET, NULL}, + {"egbypass", "get", "get the status of egress translation filter bypass", + "", SW_API_EG_FLTR_BYPASS_EN_GET, NULL}, + {"ptvrfid", "set", "set port VRF ID", + " ", SW_API_PT_VRF_ID_SET, NULL}, + {"ptvrfid", "get", "get port VRF ID", + "", SW_API_PT_VRF_ID_GET, NULL}, + {"globalqinqmode", "set", "set global qinq mode", + "", SW_API_GLOBAL_QINQ_MODE_SET, NULL}, + {"globalqinqmode", "get", "get global qinq mode", + "", SW_API_GLOBAL_QINQ_MODE_GET, NULL}, + {"ptqinqmode", "set", "set port qinq mode", + "", SW_API_PORT_QINQ_MODE_SET, NULL}, + {"ptqinqmode", "get", "get port qinq mode", + "", SW_API_PORT_QINQ_MODE_GET, NULL}, + {"intpid", "set", "set ingress tpid", "", SW_API_TPID_SET, NULL}, + {"intpid", "get", "get ingress tpid", "", SW_API_TPID_GET, NULL}, + {"egtpid", "set", "set egress tpid", "", SW_API_EGRESS_TPID_SET, NULL}, + {"egtpid", "get", "get egress tpid", "", SW_API_EGRESS_TPID_GET, NULL}, + {"ingressfilter", "set", "set port ingress filter", + "", SW_API_PT_INGRESS_VLAN_FILTER_SET, NULL}, + {"ingressfilter", "get", "get port ingress filter", + "", SW_API_PT_INGRESS_VLAN_FILTER_GET, NULL}, + {"defaultvlantag", "set", "set port default vlan tag", + " ", SW_API_PT_DEFAULT_VLANTAG_SET, NULL}, + {"defaultvlantag", "get", "get port default vlan tag", + " ", SW_API_PT_DEFAULT_VLANTAG_GET, NULL}, + {"tagpropagation", "set", "set port tag propagation", + " ", SW_API_PT_TAG_PROPAGATION_SET, NULL}, + {"tagpropagation", "get", "get port tag propagation", + " ", SW_API_PT_TAG_PROPAGATION_GET, NULL}, + {"egmode", "set", "set port egress vlan mode", + "", SW_API_PT_VLANTAG_EGMODE_SET, NULL}, + {"egmode", "get", "get port egress vlan mode", + "", SW_API_PT_VLANTAG_EGMODE_GET, NULL}, + {"translationmissaction", "set", "set port xlt miss command", + " ", + SW_API_PT_VLAN_XLT_MISS_CMD_SET, NULL}, + {"translationmissaction", "get", "get port xlt miss command", + "", SW_API_PT_VLAN_XLT_MISS_CMD_GET, NULL}, + {"vsiegmode", "set", "set a vsi port egress tag", + " ", + SW_API_PT_VSI_EGMODE_SET, NULL}, + {"vsiegmode", "get", "get a vsi port egress tag", + " ", SW_API_PT_VSI_EGMODE_GET, NULL}, + {"vsiegmodeen", "set", "set port vlan tag vsi egress mode enable or not", + " ", SW_API_PT_VLANTAG_VSI_EGMODE_EN_SET, NULL}, + {"vsiegmodeen", "get", "get port vlan tag vsi egress mode enable or not", + "", SW_API_PT_VLANTAG_VSI_EGMODE_EN_GET, NULL}, + {"translationAdv", "add", "add a vlan translation entry based on port and direction", + " ", SW_API_PT_VLAN_TRANS_ADV_ADD, NULL}, + {"translationAdv", "del", "del a vlan translation entry based on port and direction", + " ", SW_API_PT_VLAN_TRANS_ADV_DEL, NULL}, + {"translationAdv", "getfirst", "get first vlan entry based on port and direction", + " ", SW_API_PT_VLAN_TRANS_ADV_GETFIRST, NULL}, + {"translationAdv", "getnext", "get next vlan entry based on port and direction", + " ", SW_API_PT_VLAN_TRANS_ADV_GETNEXT, NULL}, + {"translationAdv", "show", "get all vlan entries based on port and direction", + " <1:ingress|2:egress>", + SW_CMD_PT_VLAN_TRANS_ADV_SHOW, cmd_show_ptvlan_entry}, + {"counter", "set", "clean up port vlan counter", + "", SW_API_PT_VLAN_COUNTER_CLEANUP, NULL}, + {"counter", "get", "get port vlan counter", + "", SW_API_PT_VLAN_COUNTER_GET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + + /*fdb*/ +#ifdef IN_FDB + { + "fdb", "config FDB table", + { + {"entry", "add", "add a FDB entry", "", SW_API_FDB_ADD, NULL}, + {"entry", "del", "delete a FDB entry", "", SW_API_FDB_DELMAC, NULL}, + {"entry", "flush", "flush all FDB entries", "<0:dynamic only|1:dynamic and static>", SW_API_FDB_DELALL, NULL}, + {"entry", "show", "show whole FDB entries", "", SW_CMD_FDB_SHOW, cmd_show_fdb}, + {"entry", "find", "find a FDB entry", "", SW_API_FDB_FIND, NULL}, + {"entry", "iterate", "iterate all FDB entries", "", SW_API_FDB_ITERATE, NULL}, + {"entry", "extendnext", "find next FDB entry in extend mode", "", SW_API_FDB_EXTEND_NEXT, NULL}, + {"entry", "extendfirst", "find first FDB entry in extend mode", "", SW_API_FDB_EXTEND_FIRST, NULL}, + {"entry", "transfer", "transfer port info in FDB entry", " ", SW_API_FDB_TRANSFER, NULL}, + {"portEntry", "flush", "flush all FDB entries by a port", " <0:dynamic only|1:dynamic and static>", SW_API_FDB_DELPORT, NULL}, + {"firstEntry", "find", "find the first FDB entry", "", SW_API_FDB_FIRST, NULL}, + {"nextEntry", "find", "find next FDB entry", "", SW_API_FDB_NEXT, NULL}, + {"portLearn", "set", "set FDB entry learning status of a port", " ", SW_API_FDB_PT_LEARN_SET, NULL}, + {"portLearn", "get", "get FDB entry learning status of a port", "", SW_API_FDB_PT_LEARN_GET, NULL}, + {"ptLearnCtrl", "set", "set new address learning and forward", " ", SW_API_FDB_PT_NEWADDR_LEARN_SET, NULL}, + {"ptLearnCtrl", "get", "get new address learning and forward", "", SW_API_FDB_PT_NEWADDR_LEARN_GET, NULL}, + {"ptStationMove", "set", "set station move learning and forward", " ", SW_API_FDB_PT_STAMOVE_SET, NULL}, + {"ptStationMove", "get", "get station move learning and forward", "", SW_API_FDB_PT_STAMOVE_GET, NULL}, + {"ageCtrl", "set", "set FDB entry aging status", "", SW_API_FDB_AGE_CTRL_SET, NULL}, + {"ageCtrl", "get", "get FDB entry aging status", "", SW_API_FDB_AGE_CTRL_GET, NULL}, + {"learnCtrl", "set", "set FDB entry learn status", "", SW_API_FDB_LEARN_CTRL_SET, NULL}, + {"learnCtrl", "get", "get FDB entry learn status", "", SW_API_FDB_LEARN_CTRL_GET, NULL}, + {"vlansmode", "set", "set FDB vlan search mode", "", SW_API_FDB_VLAN_IVL_SVL_SET, NULL}, + {"vlansmode", "get", "get FDB vlan search mode", "", SW_API_FDB_VLAN_IVL_SVL_GET, NULL}, + {"ageTime", "set", "set FDB entry aging time", "", SW_API_FDB_AGE_TIME_SET, NULL}, + {"ageTime", "get", "get FDB entry aging time", "", SW_API_FDB_AGE_TIME_GET, NULL}, + {"ptlearncounter", "get", "get port FDB entry learn counter", "", SW_API_PT_FDB_LEARN_COUNTER_GET, NULL}, + {"ptlearnlimit", "set", "set port FDB entry learn limit", " ", SW_API_PT_FDB_LEARN_LIMIT_SET, NULL}, + {"ptlearnlimit", "get", "get port FDB entry learn limit", "", SW_API_PT_FDB_LEARN_LIMIT_GET, NULL}, + {"ptlearnexceedcmd", "set", "set port forwarding cmd when exceed learn limit", " ", SW_API_PT_FDB_LEARN_EXCEED_CMD_SET, NULL}, + {"ptlearnexceedcmd", "get", "get port forwarding cmd when exceed learn limit", "", SW_API_PT_FDB_LEARN_EXCEED_CMD_GET, NULL}, + {"learnlimit", "set", "set FDB entry learn limit", " ", SW_API_FDB_LEARN_LIMIT_SET, NULL}, + {"learnlimit", "get", "get FDB entry learn limit", "", SW_API_FDB_LEARN_LIMIT_GET, NULL}, + {"learnexceedcmd", "set", "set forwarding cmd when exceed learn limit", "", SW_API_FDB_LEARN_EXCEED_CMD_SET, NULL}, + {"learnexceedcmd", "get", "get forwarding cmd when exceed learn limit", "", SW_API_FDB_LEARN_EXCEED_CMD_GET, NULL}, + {"resventry", "add", "add a reserve FDB entry", "", SW_API_FDB_RESV_ADD, NULL}, + {"resventry", "del", "delete reserve a FDB entry", "", SW_API_FDB_RESV_DEL, NULL}, + {"resventry", "find", "find a reserve FDB entry", "", SW_API_FDB_RESV_FIND, NULL}, + {"resventry", "iterate", "iterate all reserve FDB entries", "", SW_API_FDB_RESV_ITERATE, NULL}, + {"resventry", "show", "show whole resv FDB entries", "", SW_CMD_RESV_FDB_SHOW, cmd_show_resv_fdb}, + {"ptLearnstatic", "set", "set FDB entry learning static status of a port", " ", SW_API_FDB_PT_LEARN_STATIC_SET, NULL}, + {"ptLearnStatic", "get", "get FDB entry learning static status of a port", "", SW_API_FDB_PT_LEARN_STATIC_GET, NULL}, + {"port", "add", "add one port to a FDB entry", " ", SW_API_FDB_PORT_ADD, NULL}, + {"port", "del", "del one port from a FDB entry", " ", SW_API_FDB_PORT_DEL, NULL}, + {"fdbrfs", "set", "add a FDB rfs", "", SW_API_FDB_RFS_SET, NULL}, + {"fdbrfs", "del", "delete a FDB rfs", "", SW_API_FDB_RFS_DEL, NULL}, + {"ptmaclimitctrl", "set", "set port maclimit ctrl", "", SW_API_FDB_PT_MACLIMIT_CTRL_SET, NULL}, + {"ptmaclimitctrl", "get", "get port maclimit ctrl", "", SW_API_FDB_PT_MACLIMIT_CTRL_GET, NULL}, + {"fidEntry", "flush", "flush all FDB entries by a fid", " <0:dynamic only|1:dynamic and static>", SW_API_FDB_DEL_BY_FID, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + + /*acl*/ +#ifdef IN_ACL + { + "acl", "config ACL", + { + {"list", "create", "create an ACL list", " ", SW_API_ACL_LIST_CREAT, NULL}, + {"list", "destroy", "destroy an ACL list", "", SW_API_ACL_LIST_DESTROY, NULL}, + {"list", "bind", "bind an ACL list to a port", " <0-0:direction> <0-0:objtype> ", SW_API_ACL_LIST_BIND, NULL}, + {"list", "unbind", "unbind an ACL list from a port", " <0-0:direction> <0-0:objtype> ", SW_API_ACL_LIST_UNBIND, NULL}, + {"rule", "add", "add ACL rules to an ACL list", " ", SW_API_ACL_RULE_ADD, NULL}, + {"rule", "del", "delete ACL rules from an ACL list", " ", SW_API_ACL_RULE_DELETE, NULL}, + {"rule", "query", "query a ACL rule", " ", SW_API_ACL_RULE_QUERY, NULL}, + {"rule", "active", "active ACL rules in an ACL list", " ", SW_API_ACL_RULE_ACTIVE, NULL}, + {"rule", "deactive", "deactive ACL rules in an ACL list", " ", SW_API_ACL_RULE_DEACTIVE, NULL}, + {"srcfiltersts", "set", "set status of ACL rules source filter", " ", SW_API_ACL_RULE_SRC_FILTER_STS_SET, NULL}, + {"srcfiltersts", "get", "get status of ACL rules source filter", "", SW_API_ACL_RULE_SRC_FILTER_STS_GET, NULL}, + {"status", "set", "set status of ACL engine", "", SW_API_ACL_STATUS_SET, NULL}, + {"status", "get", "get status of ACL engine", "", SW_API_ACL_STATUS_GET, NULL}, + {"udfprofile", "set", "set port udf profile", " ", SW_API_ACL_PT_UDF_PROFILE_SET, NULL}, + {"udfprofile", "get", "get port udf profile", " ", SW_API_ACL_PT_UDF_PROFILE_GET, NULL}, + {"udf", "set", "set udf", " <0-3> ", SW_API_ACL_UDF_SET, NULL}, + {"udf", "get", "get udf", " <0-3>", SW_API_ACL_UDF_GET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + + /*qos*/ +#ifdef IN_QOS + { + "qos", "config Qos", + { + {"schMode", "set", "set traffic scheduling mode", " ", SW_API_QOS_SCH_MODE_SET, NULL}, + {"schMode", "get", "get traffic scheduling mode", "", SW_API_QOS_SCH_MODE_GET, NULL}, + {"qTxBufSts", "set", "set queue tx buffer counting status of a port", " ", SW_API_QOS_QU_TX_BUF_ST_SET, NULL}, + {"qTxBufSts", "get", "get queue tx buffer counting status of a port", "", SW_API_QOS_QU_TX_BUF_ST_GET, NULL}, + {"qTxBufNr", "set", "set queue tx buffer number", " ", SW_API_QOS_QU_TX_BUF_NR_SET, NULL}, + {"qTxBufNr", "get", "get queue tx buffer number", " ", SW_API_QOS_QU_TX_BUF_NR_GET, NULL}, + {"ptTxBufSts", "set", "set port tx buffer counting status of a port", " ", SW_API_QOS_PT_TX_BUF_ST_SET, NULL}, + {"ptTxBufSts", "get", "get port tx buffer counting status of a port", "", SW_API_QOS_PT_TX_BUF_ST_GET, NULL}, + {"ptRedEn", "set", "set status of port wred of a port", " ", SW_API_QOS_PT_RED_EN_SET, NULL}, + {"ptRedEn", "get", "get status of port wred of a port", "", SW_API_QOS_PT_RED_EN_GET, NULL}, + {"ptTxBufNr", "set", "set port tx buffer number", " ", SW_API_QOS_PT_TX_BUF_NR_SET, NULL}, + {"ptTxBufNr", "get", "get port tx buffer number", "", SW_API_QOS_PT_TX_BUF_NR_GET, NULL}, + {"ptRxBufNr", "set", "set port rx buffer number", " ", SW_API_QOS_PT_RX_BUF_NR_SET, NULL}, + {"ptRxBufNr", "get", "get port rx buffer number", "", SW_API_QOS_PT_RX_BUF_NR_GET, NULL}, + {"up2q", "set", "set user priority to queue mapping", " ", SW_API_COSMAP_UP_QU_SET, NULL}, + {"up2q", "get", "get user priority to queue mapping", "", SW_API_COSMAP_UP_QU_GET, NULL}, + {"dscp2q", "set", "set dscp to queue mapping", " ", SW_API_COSMAP_DSCP_QU_SET, NULL}, + {"dscp2q", "get", "get dscp to queue mapping", "", SW_API_COSMAP_DSCP_QU_GET, NULL}, + {"ptMode", "set", "set Qos mode of a port", " ", SW_API_QOS_PT_MODE_SET, NULL}, + {"ptMode", "get", "get Qos mode of a port", " ", SW_API_QOS_PT_MODE_GET, NULL}, + {"ptModePri", "set", "set the priority of Qos modes of a port", " ", SW_API_QOS_PT_MODE_PRI_SET, NULL}, + {"ptModePri", "get", "get the priority of Qos modes of a port", " ", SW_API_QOS_PT_MODE_PRI_GET, NULL}, + {"ptDefaultUp", "set", "set default user priority for received frames of a port", " ", SW_API_QOS_PORT_DEF_UP_SET, NULL}, + {"ptDefaultUp", "get", "get default user priority for received frames of a port", "", SW_API_QOS_PORT_DEF_UP_GET, NULL}, + {"ptschMode", "set", "set port traffic scheduling mode", " ", SW_API_QOS_PORT_SCH_MODE_SET, NULL}, + {"ptschMode", "get", "get port traffic scheduling mode", "", SW_API_QOS_PORT_SCH_MODE_GET, NULL}, + {"ptDefaultSpri", "set", "set default stag priority for received frames of a port", " ", SW_API_QOS_PT_DEF_SPRI_SET, NULL}, + {"ptDefaultSpri", "get", "get default stag priority for received frames of a port", "", SW_API_QOS_PT_DEF_SPRI_GET, NULL}, + {"ptDefaultCpri", "set", "set default ctag priority for received frames of a port", " ", SW_API_QOS_PT_DEF_CPRI_SET, NULL}, + {"ptDefaultCpri", "get", "get default ctag priority for received frames of a port", "", SW_API_QOS_PT_DEF_CPRI_GET, NULL}, + {"ptFSpriSts", "set", "set port force Stag priority status for received frames of a port", " ", SW_API_QOS_PT_FORCE_SPRI_ST_SET, NULL}, + {"ptFSpriSts", "get", "get port force Stag priority status for received frames of a port", "", SW_API_QOS_PT_FORCE_SPRI_ST_GET, NULL}, + {"ptFCpriSts", "set", "set port force Ctag priority status for received frames of a port", " ", SW_API_QOS_PT_FORCE_CPRI_ST_SET, NULL}, + {"ptFCpriSts", "get", "get port force Ctag priority status for received frames of a port", "", SW_API_QOS_PT_FORCE_CPRI_ST_GET, NULL}, + {"ptQuRemark", "set", "set egress queue based remark", " ", SW_API_QOS_QUEUE_REMARK_SET, NULL}, + {"ptQuRemark", "get", "get egress queue based remark", " ", SW_API_QOS_QUEUE_REMARK_GET, NULL}, + {"ptgroup", "set", "set port group", " ", SW_API_QOS_PORT_GROUP_SET, NULL}, + {"ptgroup", "get", "get port group", "", SW_API_QOS_PORT_GROUP_GET, NULL}, + {"ptpriprece", "set", "set port priority precedence", "", SW_API_QOS_PORT_PRI_SET, NULL}, + {"ptPriprece", "get", "get port priority precedence", "", SW_API_QOS_PORT_PRI_GET, NULL}, + {"ptremark", "set", "set port remark", " ", SW_API_QOS_PORT_REMARK_SET, NULL}, + {"ptremark", "get", "get port remark", "", SW_API_QOS_PORT_REMARK_GET, NULL}, + {"pcpmap", "set", "set pcp map", " ", SW_API_QOS_PCP_MAP_SET, NULL}, + {"pcpmap", "get", "get pcp map", " ", SW_API_QOS_PCP_MAP_GET, NULL}, + {"flowmap", "set", "set flow map", " ", SW_API_QOS_FLOW_MAP_SET, NULL}, + {"flowmap", "get", "get flow map", " ", SW_API_QOS_FLOW_MAP_GET, NULL}, + {"dscpmap", "set", "set dscp map", " ", SW_API_QOS_DSCP_MAP_SET, NULL}, + {"dscpmap", "get", "get dscp map", " ", SW_API_QOS_DSCP_MAP_GET, NULL}, + {"qscheduler", "set", "set queue scheduler", " ", SW_API_QOS_QUEUE_SCHEDULER_SET, NULL}, + {"qscheduler", "get", "get queue scheduler", " ", SW_API_QOS_QUEUE_SCHEDULER_GET, NULL}, + {"ringqueue", "set", "set ring queue map", " ", SW_API_QOS_RING_QUEUE_MAP_SET, NULL}, + {"ringqueue", "get", "get ring queue map", "", SW_API_QOS_RING_QUEUE_MAP_GET, NULL}, + {"portqueues", "get", "get queues belong to port", "", SW_API_QOS_PORT_QUEUES_GET, NULL}, + {"dequeue", "get", "dequeue control get", "", SW_API_QOS_SCHEDULER_DEQUEU_CTRL_GET, NULL}, + {"dequeue", "set", "dequeue control set", " ", SW_API_QOS_SCHEDULER_DEQUEU_CTRL_SET, NULL}, + {"portscheduler", "reset", "reset queue scheduler config", "", SW_API_QOS_PORT_SCHEDULER_CFG_RESET, NULL}, + {"schedulerresource", "get", "get port scheduler resource", "", SW_API_QOS_PORT_SCHEDULER_RESOURCE_GET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + + /*igmp*/ +#ifdef IN_IGMP + { + "igmp", "config IGMP/MLD", + { + {"mode", "set", "set IGMP/MLD snooping status of a port", " ", SW_API_PT_IGMPS_MODE_SET, NULL}, + {"mode", "get", "get port IGMP/MLD snooping status", "", SW_API_PT_IGMPS_MODE_GET, NULL}, + {"cmd", "set", "set IGMP/MLD frames forwarding command", "", SW_API_IGMP_MLD_CMD_SET, NULL}, + {"cmd", "get", "get IGMP/MLD frames forwarding command", "", SW_API_IGMP_MLD_CMD_GET, NULL}, + {"portJoin", "set", "set IGMP/MLD hardware joining status", " ", SW_API_IGMP_PT_JOIN_SET, NULL}, + {"portJoin", "get", "get IGMP/MLD hardware joining status", "", SW_API_IGMP_PT_JOIN_GET, NULL}, + {"portLeave", "set", "set IGMP/MLD hardware leaving status", " ", SW_API_IGMP_PT_LEAVE_SET, NULL}, + {"portLeave", "get", "get IGMP/MLD hardware leaving status", "", SW_API_IGMP_PT_LEAVE_GET, NULL}, + {"rp", "set", "set IGMP/MLD router ports", "", SW_API_IGMP_RP_SET, NULL}, + {"rp", "get", "get IGMP/MLD router ports", "", SW_API_IGMP_RP_GET, NULL}, + {"createStatus", "set", "set IGMP/MLD ability for creating entry", "", SW_API_IGMP_ENTRY_CREAT_SET, NULL}, + {"createStatus", "get", "get IGMP/MLD ability for creating entry", "", SW_API_IGMP_ENTRY_CREAT_GET, NULL}, + {"static", "set", "set IGMP/MLD static status for creating entry", "", SW_API_IGMP_ENTRY_STATIC_SET, NULL}, + {"static", "get", "get IGMP/MLD static status for creating entry", "", SW_API_IGMP_ENTRY_STATIC_GET, NULL}, + {"leaky", "set", "set IGMP/MLD leaky status for creating entry", "", SW_API_IGMP_ENTRY_LEAKY_SET, NULL}, + {"leaky", "get", "get IGMP/MLD leaky status for creating entry", "", SW_API_IGMP_ENTRY_LEAKY_GET, NULL}, + {"version3", "set", "set IGMP v3/MLD v2 status for creating entry", "", SW_API_IGMP_ENTRY_V3_SET, NULL}, + {"version3", "get", "get IGMP v3/MLD v2 status for creating entry", "", SW_API_IGMP_ENTRY_V3_GET, NULL}, + {"queue", "set", "set IGMP/MLD queue status for creating entry", " ", SW_API_IGMP_ENTRY_QUEUE_SET, NULL}, + {"queue", "get", "get IGMP/MLD queue status for creating entry", "", SW_API_IGMP_ENTRY_QUEUE_GET, NULL}, + {"ptlearnlimit", "set", "set port Multicast entry learn limit", " ", SW_API_PT_IGMP_LEARN_LIMIT_SET, NULL}, + {"ptlearnlimit", "get", "get port Multicast entry learn limit", "", SW_API_PT_IGMP_LEARN_LIMIT_GET, NULL}, + {"ptlearnexceedcmd", "set", "set port forwarding cmd when exceed multicast learn limit", " ", SW_API_PT_IGMP_LEARN_EXCEED_CMD_SET, NULL}, + {"ptlearnexceedcmd", "get", "get port forwarding cmd when exceed multicast learn limit", "", SW_API_PT_IGMP_LEARN_EXCEED_CMD_GET, NULL}, + {"multi", "set", "set igmp/mld entry", "", SW_API_IGMP_SG_ENTRY_SET, NULL}, + {"multi", "clear", "clear igmp/mld entry", "", SW_API_IGMP_SG_ENTRY_CLEAR, NULL}, + {"multi", "show", "show all igmp/mld entry", "", SW_API_IGMP_SG_ENTRY_SHOW, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + + /*leaky*/ +#ifdef IN_LEAKY + { + "leaky", "config leaky", + { + {"ucMode", "set", "set unicast packets leaky mode", "", SW_API_UC_LEAKY_MODE_SET, NULL}, + {"ucMode", "get", "get unicast packets leaky mode", "", SW_API_UC_LEAKY_MODE_GET, NULL}, + {"mcMode", "set", "set multicast packets leaky mode", "", SW_API_MC_LEAKY_MODE_SET, NULL}, + {"mcMode", "get", "get multicast packets leaky mode", "", SW_API_MC_LEAKY_MODE_GET, NULL}, + {"arpMode", "set", "set arp packets leaky mode", " ", SW_API_ARP_LEAKY_MODE_SET, NULL}, + {"arpMode", "get", "get arp packets leaky mode", "", SW_API_ARP_LEAKY_MODE_GET, NULL}, + {"ptUcMode", "set", "set unicast packets leaky status of a port", " ", SW_API_PT_UC_LEAKY_MODE_SET, NULL}, + {"ptUcMode", "get", "get unicast packets leaky status of a port", "", SW_API_PT_UC_LEAKY_MODE_GET, NULL}, + {"ptMcMode", "set", "set multicast packets leaky status of a port", " ", SW_API_PT_MC_LEAKY_MODE_SET, NULL}, + {"ptMcMode", "get", "get multicast packets leaky status of a port", "", SW_API_PT_MC_LEAKY_MODE_GET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + + /*mirror*/ +#ifdef IN_MIRROR + { + "mirror", "config mirror", + { + {"analyPt", "set", "set mirror analysis port", "", SW_API_MIRROR_ANALY_PT_SET, NULL}, + {"analyPt", "get", "get mirror analysis port", "", SW_API_MIRROR_ANALY_PT_GET, NULL}, + {"ptIngress", "set", "set ingress mirror status of a port", " ", SW_API_MIRROR_IN_PT_SET, NULL}, + {"ptIngress", "get", "get ingress mirror status of a port", "", SW_API_MIRROR_IN_PT_GET, NULL}, + {"ptEgress", "set", "set egress mirror status of a port", " ", SW_API_MIRROR_EG_PT_SET, NULL}, + {"ptEgress", "get", "get egress mirror status of a port", "", SW_API_MIRROR_EG_PT_GET, NULL}, + {"analyCfg", "set", "set analysis configure", "", SW_API_MIRROR_ANALYSIS_CONFIG_SET, NULL}, + {"analyCfg", "get", "get analysis configure", "", SW_API_MIRROR_ANALYSIS_CONFIG_GET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + + /*rate*/ +#ifdef IN_RATE + { + "rate", "config rate limit", + { + {"qEgress", "set", "set egress rate limit of a queue", " ", SW_API_RATE_QU_EGRL_SET, NULL}, + {"qEgress", "get", "get egress rate limit of a queue", " ", SW_API_RATE_QU_EGRL_GET, NULL}, + {"ptEgress", "set", "set egress rate limit of a port", " ", SW_API_RATE_PT_EGRL_SET, NULL}, + {"ptEgress", "get", "get egress rate limit of a port", "", SW_API_RATE_PT_EGRL_GET, NULL}, + {"ptIngress", "set", "set ingress rate limit of a port", " ", SW_API_RATE_PT_INRL_SET, NULL}, + {"ptIngress", "get", "get ingress rate limit of a port", "", SW_API_RATE_PT_INRL_GET, NULL}, + {"stormCtrl", "set", "set storm control status of a particular frame type", " ", SW_API_STORM_CTRL_FRAME_SET, NULL}, + {"stormCtrl", "get", "get storm control status of a particular frame type", " ", SW_API_STORM_CTRL_FRAME_GET, NULL}, + {"stormCtrlRate", "set", "set storm ctrl rate", " ", SW_API_STORM_CTRL_RATE_SET, NULL}, + {"stormCtrlRate", "get", "get storm ctrl rate", "", SW_API_STORM_CTRL_RATE_GET, NULL}, + {"portpolicer", "set", "set port policer", "", SW_API_RATE_PORT_POLICER_SET, NULL}, + {"portpolicer", "get", "get port policer", "", SW_API_RATE_PORT_POLICER_GET, NULL}, + {"portshaper", "set", "set port egress shaper", " ", SW_API_RATE_PORT_SHAPER_SET, NULL}, + {"portshaper", "get", "get port egress shaper", "", SW_API_RATE_PORT_SHAPER_GET, NULL}, + {"queueshaper", "set", "set queue egress shaper", " ", SW_API_RATE_QUEUE_SHAPER_SET, NULL}, + {"queueshaper", "get", "get queue egress shaper", " ", SW_API_RATE_QUEUE_SHAPER_GET, NULL}, + {"aclpolicer", "set", "set acl policer", "", SW_API_RATE_ACL_POLICER_SET, NULL}, + {"aclpolicer", "get", "get acl policer", "", SW_API_RATE_ACL_POLICER_GET, NULL}, + {"ptAddRateByte", "set", "set add_rate_byte when cal rate ", " ", SW_API_RATE_PT_ADDRATEBYTE_SET, NULL}, + {"ptAddRateByte", "get", "get add_rate_byte when cal rate ", "", SW_API_RATE_PT_ADDRATEBYTE_GET, NULL}, + {"ptgolflowen", "set", "set status of port globle flow control", " ", SW_API_RATE_PT_GOL_FLOW_EN_SET, NULL}, + {"ptgolflowen", "get", "get status of port globle flow control", "", SW_API_RATE_PT_GOL_FLOW_EN_GET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + +#ifdef IN_SEC + { + "sec", "config security", + { + {"mac", "set", "set MAC layer related security", " ", SW_API_SEC_MAC_SET, NULL}, + {"mac", "get", "get MAC layer related security", "", SW_API_SEC_MAC_GET, NULL}, + {"ip", "set", "set IP layer related security", " ", SW_API_SEC_IP_SET, NULL}, + {"ip", "get", "get IP layer related security", "", SW_API_SEC_IP_GET, NULL}, + {"ip4", "set", "set IP4 related security", " ", SW_API_SEC_IP4_SET, NULL}, + {"ip4", "get", "get IP4 related security", "", SW_API_SEC_IP4_GET, NULL}, + {"ip6", "set", "set IP6 related security", " ", SW_API_SEC_IP6_SET, NULL}, + {"ip6", "get", "get IP6 related security", "", SW_API_SEC_IP6_GET, NULL}, + {"tcp", "set", "set TCP related security", " ", SW_API_SEC_TCP_SET, NULL}, + {"tcp", "get", "get TCP related security", "", SW_API_SEC_TCP_GET, NULL}, + {"udp", "set", "set UDP related security", " ", SW_API_SEC_UDP_SET, NULL}, + {"udp", "get", "get UDP related security", "", SW_API_SEC_UDP_GET, NULL}, + {"icmp4", "set", "set ICMP4 related security", " ", SW_API_SEC_ICMP4_SET, NULL}, + {"icmp4", "get", "get ICMP4 related security", "", SW_API_SEC_ICMP4_GET, NULL}, + {"icmp6", "set", "set ICMP6 related security", " ", SW_API_SEC_ICMP6_SET, NULL}, + {"icmp6", "get", "get ICMP6 related security", "", SW_API_SEC_ICMP6_GET, NULL}, + {"l3parser", "get", "get l3 parser ctrl", " ", SW_API_SEC_L3_PARSER_CTRL_GET, NULL}, + {"l3parser", "set", "set l3 parser ctrl", " ", SW_API_SEC_L3_PARSER_CTRL_SET, NULL}, + {"l4parser", "get", "get l4 parser ctrl", " ", SW_API_SEC_L4_PARSER_CTRL_GET, NULL}, + {"l4parser", "set", "set l4 parser ctrl", " ", SW_API_SEC_L4_PARSER_CTRL_SET, NULL}, + {"expctrl", "get", "get l3 exp ctrl", "", SW_API_SEC_EXP_CTRL_GET, NULL}, + {"expctrl", "set", "set l3 exp ctrl", "", SW_API_SEC_EXP_CTRL_SET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + + /*stp*/ +#ifdef IN_STP + { + "stp", "config STP", + { + {"portState", "set", "set STP state of a port", " ", SW_API_STP_PT_STATE_SET, NULL}, + {"portState", "get", "get STP state of a port", " ", SW_API_STP_PT_STATE_GET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + + /*mib*/ +#ifdef IN_MIB + { + "mib", "show MIB statistics information", + { + {"statistics", "get", "get statistics information of a port", "", SW_API_PT_MIB_GET, NULL}, + {"status", "set", "set mib status", "", SW_API_MIB_STATUS_SET, NULL}, + {"status", "get", "get mib status", "", SW_API_MIB_STATUS_GET, NULL}, + {"counters", "flush", "flush counters of a port", "", SW_API_PT_MIB_FLUSH_COUNTERS, NULL}, + {"cpuKeep", "set", "set cpu keep bit", "", SW_API_MIB_CPU_KEEP_SET, NULL}, + {"cpuKeep", "get", "get cpu keep bit", "", SW_API_MIB_CPU_KEEP_GET, NULL}, + {"xgstatistics","get", "get statistics information of a xg_port", "",SW_API_PT_XGMIB_GET}, + {"counter", "get", "get counter information of a port", "", SW_API_PT_MIB_COUNTER_GET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + + /* led */ +#ifdef IN_LED + { + "led", "set/get led control pattern", + { + {"ctrlpattern", "set", "set led control pattern", " ", SW_API_LED_PATTERN_SET, NULL}, + {"ctrlpattern", "get", "get led control pattern", " ", SW_API_LED_PATTERN_GET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + + /* cosmap */ +#ifdef IN_COSMAP + { + "cosmap", "set/get cosmap table", + { + {"dscp2pri", "set", "set dscp to priority map table", " ", SW_API_COSMAP_DSCP_TO_PRI_SET, NULL}, + {"dscp2pri", "get", "get dscp to priority map table", "", SW_API_COSMAP_DSCP_TO_PRI_GET, NULL}, + {"dscp2dp", "set", "set dscp to dp map table", " ", SW_API_COSMAP_DSCP_TO_DP_SET, NULL}, + {"dscp2dp", "get", "get dscp to dp map table", "", SW_API_COSMAP_DSCP_TO_DP_GET, NULL}, + {"up2pri", "set", "set dot1p to priority map table", " ", SW_API_COSMAP_UP_TO_PRI_SET, NULL}, + {"up2pri", "get", "get dot1p to priority map table", "", SW_API_COSMAP_UP_TO_PRI_GET, NULL}, + {"up2dp", "set", "set dot1p to dp map table", " ", SW_API_COSMAP_UP_TO_DP_SET, NULL}, + {"up2dp", "get", "get dot1p to dp map table", "", SW_API_COSMAP_UP_TO_DP_GET, NULL}, + {"dscp2ehpri", "set", "set dscp to priority map table for WAN port", " ", SW_API_COSMAP_DSCP_TO_EHPRI_SET, NULL}, + {"dscp2ehpri", "get", "get dscp to priority map table for WAN port", "", SW_API_COSMAP_DSCP_TO_EHPRI_GET, NULL}, + {"dscp2ehdp", "set", "set dscp to dp map table for WAN port", " ", SW_API_COSMAP_DSCP_TO_EHDP_SET, NULL}, + {"dscp2ehdp", "get", "get dscp to dp map table for WAN port", "", SW_API_COSMAP_DSCP_TO_EHDP_GET, NULL}, + {"up2ehpri", "set", "set dot1p to priority map table for WAN port", " ", SW_API_COSMAP_UP_TO_EHPRI_SET, NULL}, + {"up2ehpri", "get", "get dot1p to priority map table for WAN port", "", SW_API_COSMAP_UP_TO_EHPRI_GET, NULL}, + {"up2ehdp", "set", "set dot1p to dp map table for WAN port", " ", SW_API_COSMAP_UP_TO_EHDP_SET, NULL}, + {"up2ehdp", "get", "get dot1p to dp map table for WAN port", "", SW_API_COSMAP_UP_TO_EHDP_GET, NULL}, + {"pri2q", "set", "set priority to queue mapping", " ", SW_API_COSMAP_PRI_TO_QU_SET, NULL}, + {"pri2q", "get", "get priority to queue mapping", "", SW_API_COSMAP_PRI_TO_QU_GET, NULL}, + {"pri2ehq", "set", "set priority to enhanced queue mapping", " ", SW_API_COSMAP_PRI_TO_EHQU_SET, NULL}, + {"pri2ehq", "get", "get priority to enhanced queue mapping", "", SW_API_COSMAP_PRI_TO_EHQU_GET, NULL}, + {"egRemark", "set", "set egress remark table", "", SW_API_COSMAP_EG_REMARK_SET, NULL}, + {"egRemark", "get", "get egress remark table", "", SW_API_COSMAP_EG_REMARK_GET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + + /*misc*/ +#ifdef IN_MISC + { + "misc", "config miscellaneous", + { + {"arp", "set", "set arp packets hardware identification status", "", SW_API_ARP_STATUS_SET, NULL}, + {"arp", "get", "get arp packets hardware identification status", "", SW_API_ARP_STATUS_GET, NULL}, + {"frameMaxSize", "set", "set the maximal received frame size of the device", "", SW_API_FRAME_MAX_SIZE_SET, NULL}, + {"frameMaxSize", "get", "get the maximal received frame size of the device", "", SW_API_FRAME_MAX_SIZE_GET, NULL}, + {"ptUnkSaCmd", "set", "set forwarding command for frames with unknown source address", " ", SW_API_PT_UNK_SA_CMD_SET, NULL}, + {"ptUnkSaCmd", "get", "get forwarding command for frames with unknown source address", "", SW_API_PT_UNK_SA_CMD_GET, NULL}, + {"ptUnkUcFilter", "set", "set flooding status of unknown unicast frames", " ", SW_API_PT_UNK_UC_FILTER_SET, NULL}, + {"ptUnkUcFilter", "get", "get flooding status of unknown unicast frames", "", SW_API_PT_UNK_UC_FILTER_GET, NULL}, + {"ptUnkMcFilter", "set", "set flooding status of unknown multicast frames", " ", SW_API_PT_UNK_MC_FILTER_SET, NULL}, + {"ptUnkMcFilter", "get", "get flooding status of unknown multicast frames", "", SW_API_PT_UNK_MC_FILTER_GET, NULL}, + {"ptBcFilter", "set", "set flooding status of broadcast frames", " ", SW_API_PT_BC_FILTER_SET, NULL}, + {"ptBcFilter", "get", "get flooding status of broadcast frames", "", SW_API_PT_BC_FILTER_GET, NULL}, + {"cpuPort", "set", "set cpu port status", "", SW_API_CPU_PORT_STATUS_SET, NULL}, + {"cpuPort", "get", "get cpu port status", "", SW_API_CPU_PORT_STATUS_GET, NULL}, + {"bctoCpu", "set", "set broadcast frames to Cpu port status", "", SW_API_BC_TO_CPU_PORT_SET, NULL}, + {"bctoCpu", "get", "get broadcast frames to Cpu port status", "", SW_API_BC_TO_CPU_PORT_GET, NULL}, + {"PppoeCmd", "set", "set pppoe frames forwarding command", "", SW_API_PPPOE_CMD_SET, NULL}, + {"PppoeCmd", "get", "get pppoe frames forwarding command", "", SW_API_PPPOE_CMD_GET, NULL}, + {"Pppoe", "set", "set pppoe frames hardware identification status", "", SW_API_PPPOE_STATUS_SET, NULL}, + {"Pppoe", "get", "get pppoe frames hardware identification status", "", SW_API_PPPOE_STATUS_GET, NULL}, + {"ptDhcp", "set", "set dhcp frames hardware identification status", " ", SW_API_PT_DHCP_SET, NULL}, + {"ptDhcp", "get", "get dhcp frames hardware identification status", "", SW_API_PT_DHCP_GET, NULL}, + {"arpcmd", "set", "set arp packets forwarding command", "", SW_API_ARP_CMD_SET, NULL}, + {"arpcmd", "get", "get arp packets forwarding command", "", SW_API_ARP_CMD_GET, NULL}, + {"eapolcmd", "set", "set eapol packets forwarding command", "", SW_API_EAPOL_CMD_SET, NULL}, + {"eapolcmd", "get", "get eapol packets forwarding command", "", SW_API_EAPOL_CMD_GET, NULL}, + {"pppoesession", "add", "add a pppoe session entry", " ", SW_API_PPPOE_SESSION_ADD, NULL}, + {"pppoesession", "del", "del a pppoe session entry", "", SW_API_PPPOE_SESSION_DEL, NULL}, + {"pppoesession", "get", "get a pppoe session entry", "", SW_API_PPPOE_SESSION_GET, NULL}, + {"eapolstatus", "set", "set eapol frames hardware identification status", " ", SW_API_EAPOL_STATUS_SET, NULL}, + {"eapolstatus", "get", "get eapol frames hardware identification status", "", SW_API_EAPOL_STATUS_GET, NULL}, + {"rip", "set", "set rip packets hardware identification status", "", SW_API_RIPV1_STATUS_SET, NULL}, + {"rip", "get", "get rip packets hardware identification status", "", SW_API_RIPV1_STATUS_GET, NULL}, + {"ptarpreq", "set", "set arp request packets hardware identification status", " ", SW_API_PT_ARP_REQ_STATUS_SET, NULL}, + {"ptarpreq", "get", "get arp request packets hardware identification status", "", SW_API_PT_ARP_REQ_STATUS_GET, NULL}, + {"ptarpack", "set", "set arp ack packets hardware identification status", " ", SW_API_PT_ARP_ACK_STATUS_SET, NULL}, + {"ptarpack", "get", "get arp ack packets hardware identification status", "", SW_API_PT_ARP_ACK_STATUS_GET, NULL}, + {"extendpppoe", "add", "add a pppoe session entry", "", SW_API_PPPOE_SESSION_TABLE_ADD, NULL}, + {"extendpppoe", "del", "del a pppoe session entry", "", SW_API_PPPOE_SESSION_TABLE_DEL, NULL}, + {"extendpppoe", "get", "get a pppoe session entry", "", SW_API_PPPOE_SESSION_TABLE_GET, NULL}, + {"pppoeid", "set", "set a pppoe session id entry", " ", SW_API_PPPOE_SESSION_ID_SET, NULL}, + {"pppoeid", "get", "get a pppoe session id entry", "", SW_API_PPPOE_SESSION_ID_GET, NULL}, + {"intrmask", "set", "set switch interrupt mask", "", SW_API_INTR_MASK_SET, NULL}, + {"intrmask", "get", "get switch interrupt mask", "", SW_API_INTR_MASK_GET, NULL}, + {"intrstatus", "get", "get switch interrupt status", "", SW_API_INTR_STATUS_GET, NULL}, + {"intrstatus", "clear", "clear switch interrupt status", "", SW_API_INTR_STATUS_CLEAR, NULL}, + {"intrportlinkmask", "set", "set link interrupt mask of a port", " ", SW_API_INTR_PORT_LINK_MASK_SET, NULL}, + {"intrportlinkmask", "get", "get link interrupt mask of a port", "", SW_API_INTR_PORT_LINK_MASK_GET, NULL}, + {"intrportlinkstatus", "get", "get link interrupt status of a port", "", SW_API_INTR_PORT_LINK_STATUS_GET, NULL}, + {"intrmaskmaclinkchg", "set", "set switch interrupt mask for mac link change", " ", SW_API_INTR_MASK_MAC_LINKCHG_SET, NULL}, + {"intrmaskmaclinkchg", "get", "get switch interrupt mask for mac link change", "", SW_API_INTR_MASK_MAC_LINKCHG_GET, NULL}, + {"intrstatusmaclinkchg", "get", "get switch interrupt status for mac link change", "", SW_API_INTR_STATUS_MAC_LINKCHG_GET, NULL}, + {"intrstatusmaclinkchg", "clear", "clear switch interrupt status for mac link change", "", SW_API_INTR_STATUS_MAC_LINKCHG_CLEAR, NULL}, + {"cpuVid", "set", "set to_cpu vid status", "", SW_API_CPU_VID_EN_SET, NULL}, + {"cpuVid", "get", "get to_cpu vid status", "", SW_API_CPU_VID_EN_GET, NULL}, + {"rtdPppoe", "set", "set RM_RTD_PPPOE_EN status", "", SW_API_RTD_PPPOE_EN_SET, NULL}, + {"rtdPppoe", "get", "get RM_RTD_PPPOE_EN status", "", SW_API_RTD_PPPOE_EN_GET, NULL}, + {"pppoeen", "set", "set a l3 interface pppoe status", " ", SW_API_PPPOE_EN_SET, NULL}, + {"pppoeen", "get", "get a l3 interface pppoe status", "", SW_API_PPPOE_EN_GET, NULL}, + {"glomacaddr", "set", "set global macaddr", "", SW_API_GLOBAL_MACADDR_SET, NULL}, + {"glomacaddr", "get", "get global macaddr", "", SW_API_GLOBAL_MACADDR_GET, NULL}, + {"lldp", "set", "set lldp frames hardware identification status", "", SW_API_LLDP_STATUS_SET, NULL}, + {"lldp", "get", "get lldp frames hardware identification status", "", SW_API_LLDP_STATUS_GET, NULL}, + {"framecrc", "set", "set frame crc reserve enable", "", SW_API_FRAME_CRC_RESERVE_SET, NULL}, + {"framecrc", "get", "get frame crc reserve enable", "", SW_API_FRAME_CRC_RESERVE_GET, NULL}, + {NULL, NULL, NULL, NULL, SW_API_INVALID, NULL}/*end of desc*/ + }, + }, +#endif + + /* IP */ +#ifdef IN_IP + { + "ip", "config ip", + { + {"hostentry", "add", "add host entry", "", SW_API_IP_HOST_ADD, NULL}, + {"hostentry", "del", "del host entry", "", SW_API_IP_HOST_DEL, NULL}, + {"hostentry", "get", "get host entry", "", SW_API_IP_HOST_GET, NULL}, + {"hostentry", "next", "next host entry", "", SW_API_IP_HOST_NEXT, NULL}, + {"hostentry", "show", "show whole host entries", "", SW_CMD_HOST_SHOW, cmd_show_host}, + {"hostipv4entry", "show", "show whole ipv4U host entries", "", SW_CMD_HOST_IPV4_SHOW, cmd_show_host_ipv4}, + {"hostipv6entry", "show", "show whole ipv6u host entries", "", SW_CMD_HOST_IPV6_SHOW, cmd_show_host_ipv6}, + {"hostipv4Mentry", "show", "show whole ipv4M host entries", "", SW_CMD_HOST_IPV4M_SHOW, cmd_show_host_ipv4M}, + {"hostipv6Mentry", "show", "show whole ipv6M host entries", "", SW_CMD_HOST_IPV6M_SHOW, cmd_show_host_ipv6M}, + {"hostentry", "bindcnt", "bind counter to host entry", " ", SW_API_IP_HOST_COUNTER_BIND, NULL}, + {"hostentry", "bindpppoe", "bind pppoe to host entry", " ", SW_API_IP_HOST_PPPOE_BIND, NULL}, + {"ptarplearn", "set", "set port arp learn flag, bit0 req bit1 ack", " ", SW_API_IP_PT_ARP_LEARN_SET, NULL}, + {"ptarplearn", "get", "get port arp learn flag, bit0 req bit1 ack", "", SW_API_IP_PT_ARP_LEARN_GET, NULL}, + {"arplearn", "set", "set arp learn mode", "", SW_API_IP_ARP_LEARN_SET, NULL}, + {"arplearn", "get", "get arp learn mode", "", SW_API_IP_ARP_LEARN_GET, NULL}, + {"ptipsrcguard", "set", "set ip source guard mode", " ", SW_API_IP_SOURCE_GUARD_SET, NULL}, + {"ptipsrcguard", "get", "get ip source guard mode", "", SW_API_IP_SOURCE_GUARD_GET, NULL}, + {"ptarpsrcguard", "set", "set arp source guard mode", " ", SW_API_IP_ARP_GUARD_SET, NULL}, + {"ptarpsrcguard", "get", "get arp source guard mode", "", SW_API_IP_ARP_GUARD_GET, NULL}, + {"routestatus", "set", "set ip route status", "", SW_API_IP_ROUTE_STATUS_SET, NULL}, + {"routestatus", "get", "get ip route status", "", SW_API_IP_ROUTE_STATUS_GET, NULL}, + {"intfentry", "add", "add interface mac address", "", SW_API_IP_INTF_ENTRY_ADD, NULL}, + {"intfentry", "del", "del interface mac address", "", SW_API_IP_INTF_ENTRY_DEL, NULL}, + {"intfentry", "show", "show whole interface mac entries", "", SW_CMD_INTFMAC_SHOW, cmd_show_intfmac}, + {"ipunksrc", "set", "set ip unkown source command", "", SW_API_IP_UNK_SOURCE_CMD_SET, NULL}, + {"ipunksrc", "get", "get ip unkown source command", "", SW_API_IP_UNK_SOURCE_CMD_GET, NULL}, + {"arpunksrc", "set", "set arp unkown source command", "", SW_API_ARP_UNK_SOURCE_CMD_SET, NULL}, + {"arpunksrc", "get", "get arp unkown source command", "", SW_API_ARP_UNK_SOURCE_CMD_GET, NULL}, + {"ipagetime", "set", "set dynamic ip entry age time", "